Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 18 Sep 2009 16:18:52 +0000 (09:18 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 18 Sep 2009 16:18:52 +0000 (09:18 -0700)
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs-2.6:
  ext3: Flush disk caches on fsync when needed
  ext3: Add locking to ext3_do_update_inode
  ext3: Fix possible deadlock between ext3_truncate() and ext3_get_blocks()
  jbd: Annotate transaction start also for journal_restart()
  jbd: Journal block numbers can ever be only 32-bit use unsigned int for them
  ext3: Update MAINTAINERS for ext3 and JBD
  JBD: round commit timer up to avoid uncommitted transaction

732 files changed:
Documentation/cpu-freq/user-guide.txt
Documentation/dontdiff
Documentation/feature-removal-schedule.txt
Documentation/hwmon/pcf8591
Documentation/hwmon/tmp421 [new file with mode: 0644]
Documentation/kernel-parameters.txt
Documentation/trace/events.txt
Documentation/trace/ftrace-design.txt [new file with mode: 0644]
Documentation/trace/ftrace.txt
MAINTAINERS
arch/Kconfig
arch/arm/plat-omap/common.c
arch/blackfin/Kconfig
arch/blackfin/Kconfig.debug
arch/blackfin/configs/BF518F-EZBRD_defconfig
arch/blackfin/configs/BF526-EZBRD_defconfig
arch/blackfin/configs/BF527-EZKIT_defconfig
arch/blackfin/configs/BF548-EZKIT_defconfig
arch/blackfin/include/asm/bfin-global.h
arch/blackfin/include/asm/bfin5xx_spi.h
arch/blackfin/include/asm/cplb.h
arch/blackfin/include/asm/early_printk.h
arch/blackfin/include/asm/elf.h
arch/blackfin/include/asm/entry.h
arch/blackfin/include/asm/ftrace.h
arch/blackfin/include/asm/ipipe.h
arch/blackfin/include/asm/irq_handler.h
arch/blackfin/include/asm/mmu_context.h
arch/blackfin/include/asm/pda.h
arch/blackfin/kernel/Makefile
arch/blackfin/kernel/asm-offsets.c
arch/blackfin/kernel/bfin_dma_5xx.c
arch/blackfin/kernel/bfin_gpio.c
arch/blackfin/kernel/cplb-mpu/Makefile
arch/blackfin/kernel/cplb-mpu/cacheinit.c [deleted file]
arch/blackfin/kernel/cplb-mpu/cplbmgr.c
arch/blackfin/kernel/cplb-nompu/Makefile
arch/blackfin/kernel/cplb-nompu/cacheinit.c [deleted file]
arch/blackfin/kernel/cplb-nompu/cplbinit.c
arch/blackfin/kernel/cplb-nompu/cplbmgr.c
arch/blackfin/kernel/early_printk.c
arch/blackfin/kernel/entry.S
arch/blackfin/kernel/ftrace-entry.S
arch/blackfin/kernel/ftrace.c
arch/blackfin/kernel/ipipe.c
arch/blackfin/kernel/kgdb_test.c
arch/blackfin/kernel/module.c
arch/blackfin/kernel/process.c
arch/blackfin/kernel/ptrace.c
arch/blackfin/kernel/setup.c
arch/blackfin/kernel/shadow_console.c [new file with mode: 0644]
arch/blackfin/kernel/time-ts.c
arch/blackfin/kernel/traps.c
arch/blackfin/kernel/vmlinux.lds.S
arch/blackfin/lib/ins.S
arch/blackfin/mach-bf518/boards/ezbrd.c
arch/blackfin/mach-bf518/include/mach/anomaly.h
arch/blackfin/mach-bf518/include/mach/blackfin.h
arch/blackfin/mach-bf527/boards/cm_bf527.c
arch/blackfin/mach-bf527/boards/ezbrd.c
arch/blackfin/mach-bf527/boards/ezkit.c
arch/blackfin/mach-bf527/include/mach/anomaly.h
arch/blackfin/mach-bf527/include/mach/blackfin.h
arch/blackfin/mach-bf533/boards/H8606.c
arch/blackfin/mach-bf533/boards/blackstamp.c
arch/blackfin/mach-bf533/boards/cm_bf533.c
arch/blackfin/mach-bf533/boards/ezkit.c
arch/blackfin/mach-bf533/boards/stamp.c
arch/blackfin/mach-bf533/dma.c
arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
arch/blackfin/mach-bf533/include/mach/blackfin.h
arch/blackfin/mach-bf537/boards/Kconfig
arch/blackfin/mach-bf537/boards/Makefile
arch/blackfin/mach-bf537/boards/cm_bf537.c [deleted file]
arch/blackfin/mach-bf537/boards/cm_bf537e.c [new file with mode: 0644]
arch/blackfin/mach-bf537/boards/cm_bf537u.c [new file with mode: 0644]
arch/blackfin/mach-bf537/boards/pnav10.c
arch/blackfin/mach-bf537/boards/stamp.c
arch/blackfin/mach-bf537/boards/tcm_bf537.c
arch/blackfin/mach-bf537/dma.c
arch/blackfin/mach-bf537/include/mach/anomaly.h
arch/blackfin/mach-bf537/include/mach/blackfin.h
arch/blackfin/mach-bf538/boards/ezkit.c
arch/blackfin/mach-bf538/include/mach/anomaly.h
arch/blackfin/mach-bf538/include/mach/blackfin.h
arch/blackfin/mach-bf538/include/mach/cdefBF538.h
arch/blackfin/mach-bf548/boards/cm_bf548.c
arch/blackfin/mach-bf548/boards/ezkit.c
arch/blackfin/mach-bf548/dma.c
arch/blackfin/mach-bf548/include/mach/anomaly.h
arch/blackfin/mach-bf548/include/mach/blackfin.h
arch/blackfin/mach-bf561/boards/cm_bf561.c
arch/blackfin/mach-bf561/boards/ezkit.c
arch/blackfin/mach-bf561/include/mach/anomaly.h
arch/blackfin/mach-bf561/secondary.S
arch/blackfin/mach-common/Makefile
arch/blackfin/mach-common/cache-c.c
arch/blackfin/mach-common/entry.S
arch/blackfin/mach-common/head.S
arch/blackfin/mach-common/interrupt.S
arch/blackfin/mach-common/ints-priority.c
arch/blackfin/mach-common/lock.S [deleted file]
arch/blackfin/mach-common/pm.c
arch/blackfin/mm/init.c
arch/blackfin/mm/isram-driver.c
arch/blackfin/mm/sram-alloc.c
arch/ia64/include/asm/topology.h
arch/ia64/kernel/head.S
arch/ia64/kernel/head.h [deleted file]
arch/m68k/include/asm/checksum.h
arch/m68k/include/asm/checksum_mm.h [deleted file]
arch/m68k/include/asm/checksum_no.h [deleted file]
arch/m68k/include/asm/dma.h
arch/m68k/include/asm/dma_mm.h [deleted file]
arch/m68k/include/asm/dma_no.h [deleted file]
arch/m68k/include/asm/elia.h [deleted file]
arch/m68k/include/asm/gpio.h [new file with mode: 0644]
arch/m68k/include/asm/hardirq_no.h
arch/m68k/include/asm/io_no.h
arch/m68k/include/asm/irq.h
arch/m68k/include/asm/irq_mm.h [deleted file]
arch/m68k/include/asm/irq_no.h [deleted file]
arch/m68k/include/asm/m5206sim.h
arch/m68k/include/asm/m520xsim.h
arch/m68k/include/asm/m523xsim.h
arch/m68k/include/asm/m5249sim.h
arch/m68k/include/asm/m5272sim.h
arch/m68k/include/asm/m527xsim.h
arch/m68k/include/asm/m528xsim.h
arch/m68k/include/asm/m5307sim.h
arch/m68k/include/asm/m532xsim.h
arch/m68k/include/asm/m5407sim.h
arch/m68k/include/asm/mcfgpio.h [new file with mode: 0644]
arch/m68k/include/asm/mcfintc.h [new file with mode: 0644]
arch/m68k/include/asm/mcfne.h
arch/m68k/include/asm/mcfsim.h
arch/m68k/include/asm/mcfsmc.h
arch/m68k/include/asm/nettel.h
arch/m68k/include/asm/page_no.h
arch/m68k/include/asm/pinmux.h [new file with mode: 0644]
arch/m68k/include/asm/processor.h
arch/m68k/include/asm/processor_mm.h [deleted file]
arch/m68k/include/asm/processor_no.h [deleted file]
arch/m68k/include/asm/timex.h
arch/m68knommu/Kconfig
arch/m68knommu/kernel/irq.c
arch/m68knommu/kernel/time.c
arch/m68knommu/lib/checksum.c
arch/m68knommu/platform/5206/Makefile
arch/m68knommu/platform/5206/config.c
arch/m68knommu/platform/5206/gpio.c [new file with mode: 0644]
arch/m68knommu/platform/5206e/Makefile
arch/m68knommu/platform/5206e/config.c
arch/m68knommu/platform/5206e/gpio.c [new file with mode: 0644]
arch/m68knommu/platform/520x/Makefile
arch/m68knommu/platform/520x/config.c
arch/m68knommu/platform/520x/gpio.c [new file with mode: 0644]
arch/m68knommu/platform/523x/Makefile
arch/m68knommu/platform/523x/config.c
arch/m68knommu/platform/523x/gpio.c [new file with mode: 0644]
arch/m68knommu/platform/5249/Makefile
arch/m68knommu/platform/5249/config.c
arch/m68knommu/platform/5249/gpio.c [new file with mode: 0644]
arch/m68knommu/platform/5249/intc2.c [new file with mode: 0644]
arch/m68knommu/platform/5272/Makefile
arch/m68knommu/platform/5272/config.c
arch/m68knommu/platform/5272/gpio.c [new file with mode: 0644]
arch/m68knommu/platform/5272/intc.c [new file with mode: 0644]
arch/m68knommu/platform/527x/Makefile
arch/m68knommu/platform/527x/config.c
arch/m68knommu/platform/527x/gpio.c [new file with mode: 0644]
arch/m68knommu/platform/528x/Makefile
arch/m68knommu/platform/528x/config.c
arch/m68knommu/platform/528x/gpio.c [new file with mode: 0644]
arch/m68knommu/platform/5307/Makefile
arch/m68knommu/platform/5307/config.c
arch/m68knommu/platform/5307/gpio.c [new file with mode: 0644]
arch/m68knommu/platform/532x/Makefile
arch/m68knommu/platform/532x/config.c
arch/m68knommu/platform/532x/gpio.c [new file with mode: 0644]
arch/m68knommu/platform/5407/Makefile
arch/m68knommu/platform/5407/config.c
arch/m68knommu/platform/5407/gpio.c [new file with mode: 0644]
arch/m68knommu/platform/68328/ints.c
arch/m68knommu/platform/68360/ints.c
arch/m68knommu/platform/coldfire/Makefile
arch/m68knommu/platform/coldfire/gpio.c [new file with mode: 0644]
arch/m68knommu/platform/coldfire/intc-2.c [new file with mode: 0644]
arch/m68knommu/platform/coldfire/intc-simr.c [new file with mode: 0644]
arch/m68knommu/platform/coldfire/intc.c [new file with mode: 0644]
arch/m68knommu/platform/coldfire/pinmux.c [new file with mode: 0644]
arch/m68knommu/platform/coldfire/pit.c
arch/m68knommu/platform/coldfire/timers.c
arch/m68knommu/platform/coldfire/vectors.c
arch/mips/Kconfig
arch/mips/Makefile
arch/mips/alchemy/common/setup.c
arch/mips/alchemy/common/time.c
arch/mips/ar7/platform.c
arch/mips/bcm63xx/Kconfig [new file with mode: 0644]
arch/mips/bcm63xx/Makefile [new file with mode: 0644]
arch/mips/bcm63xx/boards/Kconfig [new file with mode: 0644]
arch/mips/bcm63xx/boards/Makefile [new file with mode: 0644]
arch/mips/bcm63xx/boards/board_bcm963xx.c [new file with mode: 0644]
arch/mips/bcm63xx/clk.c [new file with mode: 0644]
arch/mips/bcm63xx/cpu.c [new file with mode: 0644]
arch/mips/bcm63xx/cs.c [new file with mode: 0644]
arch/mips/bcm63xx/dev-dsp.c [new file with mode: 0644]
arch/mips/bcm63xx/dev-enet.c [new file with mode: 0644]
arch/mips/bcm63xx/early_printk.c [new file with mode: 0644]
arch/mips/bcm63xx/gpio.c [new file with mode: 0644]
arch/mips/bcm63xx/irq.c [new file with mode: 0644]
arch/mips/bcm63xx/prom.c [new file with mode: 0644]
arch/mips/bcm63xx/setup.c [new file with mode: 0644]
arch/mips/bcm63xx/timer.c [new file with mode: 0644]
arch/mips/boot/elf2ecoff.c
arch/mips/cavium-octeon/Makefile
arch/mips/cavium-octeon/octeon-platform.c [new file with mode: 0644]
arch/mips/cavium-octeon/setup.c
arch/mips/configs/ar7_defconfig
arch/mips/configs/bcm47xx_defconfig
arch/mips/configs/bcm63xx_defconfig [new file with mode: 0644]
arch/mips/configs/bigsur_defconfig
arch/mips/configs/cobalt_defconfig
arch/mips/configs/db1000_defconfig
arch/mips/configs/db1100_defconfig
arch/mips/configs/db1200_defconfig
arch/mips/configs/db1500_defconfig
arch/mips/configs/db1550_defconfig
arch/mips/configs/excite_defconfig
arch/mips/configs/fulong_defconfig [deleted file]
arch/mips/configs/fuloong2e_defconfig [new file with mode: 0644]
arch/mips/configs/ip22_defconfig
arch/mips/configs/ip27_defconfig
arch/mips/configs/ip28_defconfig
arch/mips/configs/ip32_defconfig
arch/mips/configs/jazz_defconfig
arch/mips/configs/lasat_defconfig
arch/mips/configs/malta_defconfig
arch/mips/configs/markeins_defconfig
arch/mips/configs/mipssim_defconfig
arch/mips/configs/msp71xx_defconfig
arch/mips/configs/mtx1_defconfig
arch/mips/configs/pb1100_defconfig
arch/mips/configs/pb1500_defconfig
arch/mips/configs/pb1550_defconfig
arch/mips/configs/pnx8335-stb225_defconfig
arch/mips/configs/pnx8550-jbs_defconfig
arch/mips/configs/pnx8550-stb810_defconfig
arch/mips/configs/rb532_defconfig
arch/mips/configs/rbtx49xx_defconfig
arch/mips/configs/rm200_defconfig
arch/mips/configs/sb1250-swarm_defconfig
arch/mips/configs/wrppmc_defconfig
arch/mips/configs/yosemite_defconfig
arch/mips/dec/prom/memory.c
arch/mips/dec/time.c
arch/mips/emma/markeins/setup.c
arch/mips/fw/arc/Makefile
arch/mips/fw/cfe/cfe_api.c
arch/mips/include/asm/atomic.h
arch/mips/include/asm/bitops.h
arch/mips/include/asm/bootinfo.h
arch/mips/include/asm/cmpxchg.h
arch/mips/include/asm/cpu-features.h
arch/mips/include/asm/cpu.h
arch/mips/include/asm/delay.h
arch/mips/include/asm/fixmap.h
arch/mips/include/asm/hardirq.h
arch/mips/include/asm/lasat/lasat.h
arch/mips/include/asm/local.h
arch/mips/include/asm/mach-au1x00/gpio-au1000.h
arch/mips/include/asm/mach-bcm63xx/bcm63xx_board.h [new file with mode: 0644]
arch/mips/include/asm/mach-bcm63xx/bcm63xx_clk.h [new file with mode: 0644]
arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h [new file with mode: 0644]
arch/mips/include/asm/mach-bcm63xx/bcm63xx_cs.h [new file with mode: 0644]
arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_dsp.h [new file with mode: 0644]
arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h [new file with mode: 0644]
arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_pci.h [new file with mode: 0644]
arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h [new file with mode: 0644]
arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h [new file with mode: 0644]
arch/mips/include/asm/mach-bcm63xx/bcm63xx_irq.h [new file with mode: 0644]
arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h [new file with mode: 0644]
arch/mips/include/asm/mach-bcm63xx/bcm63xx_timer.h [new file with mode: 0644]
arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h [new file with mode: 0644]
arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h [new file with mode: 0644]
arch/mips/include/asm/mach-bcm63xx/gpio.h [new file with mode: 0644]
arch/mips/include/asm/mach-bcm63xx/war.h [new file with mode: 0644]
arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
arch/mips/include/asm/mach-ip27/topology.h
arch/mips/include/asm/mach-lemote/cpu-feature-overrides.h [deleted file]
arch/mips/include/asm/mach-lemote/dma-coherence.h [deleted file]
arch/mips/include/asm/mach-lemote/mc146818rtc.h [deleted file]
arch/mips/include/asm/mach-lemote/pci.h [deleted file]
arch/mips/include/asm/mach-lemote/war.h [deleted file]
arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h [new file with mode: 0644]
arch/mips/include/asm/mach-loongson/dma-coherence.h [new file with mode: 0644]
arch/mips/include/asm/mach-loongson/loongson.h [new file with mode: 0644]
arch/mips/include/asm/mach-loongson/machine.h [new file with mode: 0644]
arch/mips/include/asm/mach-loongson/mc146818rtc.h [new file with mode: 0644]
arch/mips/include/asm/mach-loongson/mem.h [new file with mode: 0644]
arch/mips/include/asm/mach-loongson/pci.h [new file with mode: 0644]
arch/mips/include/asm/mach-loongson/war.h [new file with mode: 0644]
arch/mips/include/asm/mach-malta/cpu-feature-overrides.h
arch/mips/include/asm/mips-boards/bonito64.h
arch/mips/include/asm/mips-boards/generic.h
arch/mips/include/asm/octeon/cvmx-rnm-defs.h [new file with mode: 0644]
arch/mips/include/asm/octeon/cvmx.h
arch/mips/include/asm/page.h
arch/mips/include/asm/pgtable-64.h
arch/mips/include/asm/system.h
arch/mips/kernel/asm-offsets.c
arch/mips/kernel/cpu-bugs64.c
arch/mips/kernel/cpu-probe.c
arch/mips/kernel/kspd.c
arch/mips/kernel/mips-mt-fpaff.c
arch/mips/kernel/mips-mt.c
arch/mips/kernel/octeon_switch.S
arch/mips/kernel/r2300_switch.S
arch/mips/kernel/r4k_switch.S
arch/mips/kernel/rtlx.c
arch/mips/kernel/scall32-o32.S
arch/mips/kernel/scall64-64.S
arch/mips/kernel/setup.c
arch/mips/kernel/smp.c
arch/mips/kernel/smtc.c
arch/mips/kernel/syscall.c
arch/mips/kernel/traps.c
arch/mips/kernel/vmlinux.lds.S
arch/mips/kernel/vpe.c
arch/mips/lasat/ds1603.c
arch/mips/lasat/sysctl.c
arch/mips/lemote/lm2e/Makefile [deleted file]
arch/mips/lemote/lm2e/bonito-irq.c [deleted file]
arch/mips/lemote/lm2e/dbg_io.c [deleted file]
arch/mips/lemote/lm2e/irq.c [deleted file]
arch/mips/lemote/lm2e/mem.c [deleted file]
arch/mips/lemote/lm2e/pci.c [deleted file]
arch/mips/lemote/lm2e/prom.c [deleted file]
arch/mips/lemote/lm2e/reset.c [deleted file]
arch/mips/lemote/lm2e/setup.c [deleted file]
arch/mips/loongson/Kconfig [new file with mode: 0644]
arch/mips/loongson/Makefile [new file with mode: 0644]
arch/mips/loongson/common/Makefile [new file with mode: 0644]
arch/mips/loongson/common/bonito-irq.c [new file with mode: 0644]
arch/mips/loongson/common/cmdline.c [new file with mode: 0644]
arch/mips/loongson/common/early_printk.c [new file with mode: 0644]
arch/mips/loongson/common/env.c [new file with mode: 0644]
arch/mips/loongson/common/init.c [new file with mode: 0644]
arch/mips/loongson/common/irq.c [new file with mode: 0644]
arch/mips/loongson/common/machtype.c [new file with mode: 0644]
arch/mips/loongson/common/mem.c [new file with mode: 0644]
arch/mips/loongson/common/pci.c [new file with mode: 0644]
arch/mips/loongson/common/reset.c [new file with mode: 0644]
arch/mips/loongson/common/setup.c [new file with mode: 0644]
arch/mips/loongson/common/time.c [new file with mode: 0644]
arch/mips/loongson/fuloong-2e/Makefile [new file with mode: 0644]
arch/mips/loongson/fuloong-2e/irq.c [new file with mode: 0644]
arch/mips/loongson/fuloong-2e/reset.c [new file with mode: 0644]
arch/mips/mipssim/sim_setup.c
arch/mips/mm/fault.c
arch/mips/mm/init.c
arch/mips/mm/pgtable-64.c
arch/mips/mm/tlb-r4k.c
arch/mips/mm/tlbex.c
arch/mips/mti-malta/malta-init.c
arch/mips/mti-malta/malta-reset.c
arch/mips/mti-malta/malta-setup.c
arch/mips/mti-malta/malta-time.c
arch/mips/nxp/pnx833x/stb22x/board.c
arch/mips/nxp/pnx8550/common/proc.c
arch/mips/oprofile/Makefile
arch/mips/oprofile/common.c
arch/mips/oprofile/op_model_loongson2.c [new file with mode: 0644]
arch/mips/pci/Makefile
arch/mips/pci/fixup-bcm63xx.c [new file with mode: 0644]
arch/mips/pci/fixup-fuloong2e.c [new file with mode: 0644]
arch/mips/pci/fixup-lm2e.c [deleted file]
arch/mips/pci/ops-bcm63xx.c [new file with mode: 0644]
arch/mips/pci/ops-bonito64.c
arch/mips/pci/pci-bcm1480.c
arch/mips/pci/pci-bcm1480ht.c
arch/mips/pci/pci-bcm63xx.c [new file with mode: 0644]
arch/mips/pci/pci-bcm63xx.h [new file with mode: 0644]
arch/mips/pci/pci-sb1250.c
arch/mips/pci/pci.c
arch/mips/pmc-sierra/yosemite/setup.c
arch/mips/power/hibernate.S
arch/mips/sgi-ip22/Makefile
arch/mips/sibyte/swarm/setup.c
arch/mips/sni/time.c
arch/mips/txx9/generic/pci.c
arch/mips/txx9/generic/setup.c
arch/powerpc/include/asm/topology.h
arch/powerpc/kernel/time.c
arch/s390/kernel/time.c
arch/sh/include/asm/topology.h
arch/sh/kernel/time.c
arch/sparc/configs/sparc32_defconfig
arch/sparc/configs/sparc64_defconfig
arch/sparc/include/asm/topology_64.h
arch/sparc/kernel/setup_32.c
arch/sparc/kernel/setup_64.c
arch/x86/Kconfig
arch/x86/include/asm/cpufeature.h
arch/x86/include/asm/elf.h
arch/x86/include/asm/entry_arch.h
arch/x86/include/asm/mce.h
arch/x86/include/asm/msr-index.h
arch/x86/include/asm/nops.h
arch/x86/include/asm/processor.h
arch/x86/include/asm/topology.h
arch/x86/include/asm/vgtod.h
arch/x86/kernel/apic/nmi.c
arch/x86/kernel/cpu/Makefile
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
arch/x86/kernel/cpu/cpufreq/powernow-k8.c
arch/x86/kernel/cpu/intel.c
arch/x86/kernel/cpu/mcheck/Makefile
arch/x86/kernel/cpu/mcheck/k7.c [deleted file]
arch/x86/kernel/cpu/mcheck/mce-inject.c
arch/x86/kernel/cpu/mcheck/mce-internal.h
arch/x86/kernel/cpu/mcheck/mce-severity.c
arch/x86/kernel/cpu/mcheck/mce.c
arch/x86/kernel/cpu/mcheck/mce_intel.c
arch/x86/kernel/cpu/mcheck/non-fatal.c [deleted file]
arch/x86/kernel/cpu/mcheck/p4.c [deleted file]
arch/x86/kernel/cpu/mcheck/p6.c [deleted file]
arch/x86/kernel/cpu/mcheck/therm_throt.c
arch/x86/kernel/cpu/sched.c [new file with mode: 0644]
arch/x86/kernel/entry_64.S
arch/x86/kernel/i8253.c
arch/x86/kernel/irq.c
arch/x86/kernel/irqinit.c
arch/x86/kernel/rtc.c
arch/x86/kernel/signal.c
arch/x86/kernel/tsc.c
arch/x86/kernel/vsyscall_64.c
arch/x86/mm/mmap.c
arch/x86/mm/pat.c
arch/x86/vdso/vclock_gettime.c
arch/xtensa/kernel/time.c
drivers/ata/Kconfig
drivers/ata/Makefile
drivers/ata/ahci.c
drivers/ata/libata-core.c
drivers/ata/pata_amd.c
drivers/ata/pata_atp867x.c [new file with mode: 0644]
drivers/ata/sata_promise.c
drivers/char/hw_random/Kconfig
drivers/char/hw_random/Makefile
drivers/char/hw_random/octeon-rng.c [new file with mode: 0644]
drivers/char/pty.c
drivers/char/vt.c
drivers/cpufreq/cpufreq.c
drivers/cpufreq/cpufreq_ondemand.c
drivers/edac/Kconfig
drivers/edac/amd64_edac.c
drivers/edac/edac_mce_amd.c
drivers/hwmon/Kconfig
drivers/hwmon/Makefile
drivers/hwmon/abituguru.c
drivers/hwmon/abituguru3.c
drivers/hwmon/applesmc.c
drivers/hwmon/dme1737.c
drivers/hwmon/f71805f.c
drivers/hwmon/hdaps.c
drivers/hwmon/hwmon-vid.c
drivers/hwmon/it87.c
drivers/hwmon/lm78.c
drivers/hwmon/lm85.c
drivers/hwmon/pc87360.c
drivers/hwmon/pc87427.c
drivers/hwmon/sis5595.c
drivers/hwmon/smsc47b397.c
drivers/hwmon/smsc47m1.c
drivers/hwmon/tmp421.c [new file with mode: 0644]
drivers/hwmon/via686a.c
drivers/hwmon/vt1211.c
drivers/hwmon/vt8231.c
drivers/hwmon/w83627ehf.c
drivers/hwmon/w83627hf.c
drivers/hwmon/w83781d.c
drivers/net/Kconfig
drivers/net/Makefile
drivers/net/atl1e/atl1e.h
drivers/net/atl1e/atl1e_main.c
drivers/net/b44.c
drivers/net/bcm63xx_enet.c [new file with mode: 0644]
drivers/net/bcm63xx_enet.h [new file with mode: 0644]
drivers/net/benet/be.h
drivers/net/benet/be_cmds.c
drivers/net/benet/be_cmds.h
drivers/net/benet/be_main.c
drivers/net/bonding/bond_main.c
drivers/net/can/vcan.c
drivers/net/fec.c
drivers/net/igb/e1000_82575.c
drivers/net/igb/e1000_82575.h
drivers/net/igb/e1000_defines.h
drivers/net/igb/e1000_phy.c
drivers/net/igb/igb_main.c
drivers/net/ixgbe/ixgbe_82598.c
drivers/net/ixgbe/ixgbe_82599.c
drivers/net/ixgbe/ixgbe_main.c
drivers/net/ixgbe/ixgbe_type.h
drivers/net/mlx4/catas.c
drivers/net/pcmcia/pcnet_cs.c
drivers/net/pppol2tp.c
drivers/net/sky2.c
drivers/net/smc91x.h
drivers/net/usb/cdc-phonet.c
drivers/net/wireless/Kconfig
drivers/net/wireless/ath/ath9k/ani.c
drivers/net/wireless/b43/main.c
drivers/net/wireless/hostap/hostap_main.c
drivers/net/wireless/iwlwifi/iwl-4965.c
drivers/net/wireless/iwlwifi/iwl-agn-rs.c
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-power.c
drivers/net/wireless/iwlwifi/iwl-rx.c
drivers/net/wireless/iwlwifi/iwl3945-base.c
drivers/net/wireless/p54/p54usb.c
drivers/net/wireless/wl12xx/wl1271_main.c
drivers/serial/serial_cs.c
drivers/ssb/pci.c
drivers/ssb/sdio.c
drivers/staging/octeon/cvmx-mdio.h
drivers/uwb/hwa-rc.c
drivers/uwb/lc-rc.c
drivers/uwb/reset.c
drivers/uwb/umc-bus.c
drivers/uwb/uwbd.c
drivers/uwb/whc-rc.c
drivers/video/console/.gitignore [deleted file]
drivers/video/console/Kconfig
drivers/video/console/Makefile
drivers/video/console/prom.uni [deleted file]
drivers/video/console/promcon.c [deleted file]
firmware/Makefile
firmware/WHENCE
firmware/cis/MT5634ZLX.cis.ihex [new file with mode: 0644]
firmware/cis/PCMLM28.cis.ihex [new file with mode: 0644]
firmware/cis/RS-COM-2P.cis.ihex [new file with mode: 0644]
fs/xfs/linux-2.6/xfs_aops.c
fs/xfs/linux-2.6/xfs_file.c
fs/xfs/linux-2.6/xfs_iops.c
fs/xfs/linux-2.6/xfs_lrw.c
fs/xfs/linux-2.6/xfs_stats.c
fs/xfs/linux-2.6/xfs_super.c
fs/xfs/linux-2.6/xfs_sync.c
fs/xfs/linux-2.6/xfs_sync.h
fs/xfs/quota/xfs_qm_stats.c
fs/xfs/xfs_ag.h
fs/xfs/xfs_bmap.c
fs/xfs/xfs_bmap.h
fs/xfs/xfs_bmap_btree.c
fs/xfs/xfs_bmap_btree.h
fs/xfs/xfs_btree.c
fs/xfs/xfs_btree.h
fs/xfs/xfs_ialloc.c
fs/xfs/xfs_ialloc.h
fs/xfs/xfs_iget.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_inode.h
fs/xfs/xfs_inode_item.c
fs/xfs/xfs_inode_item.h
fs/xfs/xfs_inum.h
fs/xfs/xfs_itable.c
fs/xfs/xfs_itable.h
fs/xfs/xfs_log_priv.h
fs/xfs/xfs_log_recover.c
fs/xfs/xfs_mount.c
fs/xfs/xfs_mount.h
fs/xfs/xfs_mru_cache.c
fs/xfs/xfs_mru_cache.h
fs/xfs/xfs_rw.c
fs/xfs/xfs_rw.h
fs/xfs/xfs_trans.h
fs/xfs/xfs_trans_buf.c
fs/xfs/xfs_trans_inode.c
fs/xfs/xfs_vnodeops.c
include/asm-generic/vmlinux.lds.h
include/keys/rxrpc-type.h
include/linux/clocksource.h
include/linux/cpufreq.h
include/linux/ftrace_event.h
include/linux/hrtimer.h
include/linux/igmp.h
include/linux/kprobes.h
include/linux/net.h
include/linux/netdevice.h
include/linux/netlink.h
include/linux/notifier.h
include/linux/pci_ids.h
include/linux/rxrpc.h
include/linux/sched.h
include/linux/time.h
include/linux/timer.h
include/linux/topology.h
include/linux/uwb.h
include/linux/wait.h
include/net/addrconf.h
include/net/protocol.h
include/net/sch_generic.h
include/net/tcp.h
include/trace/events/block.h
include/trace/events/irq.h
include/trace/ftrace.h
kernel/hrtimer.c
kernel/posix-timers.c
kernel/sched.c
kernel/sched_debug.c
kernel/sched_fair.c
kernel/sched_features.h
kernel/sched_idletask.c
kernel/sched_rt.c
kernel/softirq.c
kernel/time.c
kernel/time/clocksource.c
kernel/time/jiffies.c
kernel/time/ntp.c
kernel/time/timekeeping.c
kernel/timer.c
kernel/trace/Kconfig
kernel/trace/ftrace.c
kernel/trace/ring_buffer.c
kernel/trace/trace.c
kernel/trace/trace.h
kernel/trace/trace_boot.c
kernel/trace/trace_clock.c
kernel/trace/trace_entries.h [new file with mode: 0644]
kernel/trace/trace_event_profile.c
kernel/trace/trace_event_types.h [deleted file]
kernel/trace/trace_events.c
kernel/trace/trace_events_filter.c
kernel/trace/trace_export.c
kernel/trace/trace_functions.c
kernel/trace/trace_functions_graph.c
kernel/trace/trace_irqsoff.c
kernel/trace/trace_mmiotrace.c
kernel/trace/trace_output.c
kernel/trace/trace_output.h
kernel/trace/trace_sched_wakeup.c
lib/vsprintf.c
net/appletalk/ddp.c
net/can/af_can.c
net/core/dev.c
net/dccp/ccids/Kconfig
net/dccp/ccids/ccid2.c
net/dccp/ccids/ccid2.h
net/dccp/ccids/ccid3.c
net/dccp/ccids/ccid3.h
net/dccp/ccids/lib/loss_interval.c
net/dccp/ccids/lib/loss_interval.h
net/dccp/ccids/lib/packet_history.c
net/dccp/ccids/lib/packet_history.h
net/dccp/ccids/lib/tfrc.h
net/dccp/ccids/lib/tfrc_equation.c
net/dccp/ipv4.c
net/dccp/ipv6.c
net/ieee802154/dgram.c
net/ieee802154/netlink.c
net/ieee802154/raw.c
net/ipv4/af_inet.c
net/ipv4/ah4.c
net/ipv4/devinet.c
net/ipv4/esp4.c
net/ipv4/icmp.c
net/ipv4/igmp.c
net/ipv4/ip_gre.c
net/ipv4/ip_input.c
net/ipv4/ipcomp.c
net/ipv4/ipmr.c
net/ipv4/protocol.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_minisocks.c
net/ipv4/tunnel4.c
net/ipv4/udplite.c
net/ipv6/addrconf.c
net/ipv6/af_inet6.c
net/ipv6/ah6.c
net/ipv6/esp6.c
net/ipv6/exthdrs.c
net/ipv6/icmp.c
net/ipv6/ip6_input.c
net/ipv6/ip6mr.c
net/ipv6/ipcomp6.c
net/ipv6/mcast.c
net/ipv6/protocol.c
net/ipv6/reassembly.c
net/ipv6/route.c
net/ipv6/tcp_ipv6.c
net/ipv6/tunnel6.c
net/ipv6/udp.c
net/ipv6/udplite.c
net/iucv/af_iucv.c
net/iucv/iucv.c
net/mac80211/rc80211_minstrel.c
net/netlink/af_netlink.c
net/netlink/genetlink.c
net/phonet/pn_dev.c
net/rds/af_rds.c
net/rose/af_rose.c
net/rxrpc/ar-ack.c
net/rxrpc/ar-internal.h
net/rxrpc/ar-key.c
net/rxrpc/ar-security.c
net/rxrpc/rxkad.c
net/sched/sch_api.c
net/sched/sch_drr.c
net/sched/sch_mq.c
net/sched/sch_multiq.c
net/sched/sch_prio.c
net/sctp/ipv6.c
net/sctp/protocol.c
net/socket.c
net/wireless/scan.c
net/wireless/sme.c
scripts/Makefile
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/soc/codecs/ad1836.c
sound/soc/codecs/ad1938.c
sound/soc/codecs/wm8974.c
sound/soc/fsl/mpc5200_dma.c
sound/soc/s3c24xx/s3c-i2s-v2.c
sound/soc/soc-dapm.c

index 5d5f5fadd1c2c3d278b791735aed625fa39b82f9..2a5b850847c024e676395320f534c1982c8ae33a 100644 (file)
@@ -176,7 +176,9 @@ scaling_governor,           and by "echoing" the name of another
                                work on some specific architectures or
                                processors.
 
-cpuinfo_cur_freq :             Current speed of the CPU, in KHz.
+cpuinfo_cur_freq :             Current frequency of the CPU as obtained from
+                               the hardware, in KHz. This is the frequency
+                               the CPU actually runs at.
 
 scaling_available_frequencies : List of available frequencies, in KHz.
 
@@ -196,7 +198,10 @@ related_cpus :                     List of CPUs that need some sort of frequency
 
 scaling_driver :               Hardware driver for cpufreq.
 
-scaling_cur_freq :             Current frequency of the CPU, in KHz.
+scaling_cur_freq :             Current frequency of the CPU as determined by
+                               the governor and cpufreq core, in KHz. This is
+                               the frequency the kernel thinks the CPU runs
+                               at.
 
 If you have selected the "userspace" governor which allows you to
 set the CPU operating frequency to a specific value, you can read out
index 88519daab6e9b8d9eb6e551caa70d2e0d773c3f5..e1efc400bed66095629a46c2229b5bf863434315 100644 (file)
@@ -152,7 +152,6 @@ piggy.gz
 piggyback
 pnmtologo
 ppc_defs.h*
-promcon_tbl.c
 pss_boot.h
 qconf
 raid6altivec*.c
index 503d21216d58195ece5d6892e8fa871cac9f7a18..fa75220f8d34e602d166cecfffe0a7036fc2cb64 100644 (file)
@@ -428,16 +428,6 @@ Who:       Johannes Berg <johannes@sipsolutions.net>
 
 ----------------------------
 
-What:  CONFIG_X86_OLD_MCE
-When:  2.6.32
-Why:   Remove the old legacy 32bit machine check code. This has been
-       superseded by the newer machine check code from the 64bit port,
-       but the old version has been kept around for easier testing. Note this
-       doesn't impact the old P5 and WinChip machine check handlers.
-Who:   Andi Kleen <andi@firstfloor.org>
-
-----------------------------
-
 What:  lock_policy_rwsem_* and unlock_policy_rwsem_* will not be
        exported interface anymore.
 When:  2.6.33
index 5628fcf4207f787fa3ab33fc07c377f4e1c8e196..e76a7892f68ed5e15b52eff2f76981c3c3d63bfc 100644 (file)
@@ -2,11 +2,11 @@ Kernel driver pcf8591
 =====================
 
 Supported chips:
-  * Philips PCF8591
+  * Philips/NXP PCF8591
     Prefix: 'pcf8591'
     Addresses scanned: I2C 0x48 - 0x4f
-    Datasheet: Publicly available at the Philips Semiconductor website
-               http://www.semiconductors.philips.com/pip/PCF8591P.html
+    Datasheet: Publicly available at the NXP website
+               http://www.nxp.com/pip/PCF8591_6.html
 
 Authors:
         Aurelien Jarno <aurelien@aurel32.net>
@@ -16,9 +16,10 @@ Authors:
 
 Description
 -----------
+
 The PCF8591 is an 8-bit A/D and D/A converter (4 analog inputs and one
-analog output) for the I2C bus produced by Philips Semiconductors. It
-is designed to provide a byte I2C interface to up to 4 separate devices.
+analog output) for the I2C bus produced by Philips Semiconductors (now NXP).
+It is designed to provide a byte I2C interface to up to 4 separate devices.
 
 The PCF8591 has 4 analog inputs programmable as single-ended or
 differential inputs :
@@ -58,8 +59,8 @@ Accessing PCF8591 via /sys interface
 -------------------------------------
 
 ! Be careful !
-The PCF8591 is plainly impossible to detect ! Stupid chip.
-So every chip with address in the interval [48..4f] is
+The PCF8591 is plainly impossible to detect! Stupid chip.
+So every chip with address in the interval [0x48..0x4f] is
 detected as PCF8591. If you have other chips in this address
 range, the workaround is to load this module after the one
 for your others chips.
@@ -67,19 +68,20 @@ for your others chips.
 On detection (i.e. insmod, modprobe et al.), directories are being
 created for each detected PCF8591:
 
-/sys/bus/devices/<0>-<1>/
+/sys/bus/i2c/devices/<0>-<1>/
 where <0> is the bus the chip was detected on (e. g. i2c-0)
 and <1> the chip address ([48..4f])
 
 Inside these directories, there are such files:
-in0, in1, in2, in3, out0_enable, out0_output, name
+in0_input, in1_input, in2_input, in3_input, out0_enable, out0_output, name
 
 Name contains chip name.
 
-The in0, in1, in2 and in3 files are RO. Reading gives the value of the
-corresponding channel. Depending on the current analog inputs configuration,
-files in2 and/or in3 do not exist. Values range are from 0 to 255 for single
-ended inputs and -128 to +127 for differential inputs (8-bit ADC).
+The in0_input, in1_input, in2_input and in3_input files are RO. Reading gives
+the value of the corresponding channel. Depending on the current analog inputs
+configuration, files in2_input and in3_input may not exist. Values range
+from 0 to 255 for single ended inputs and -128 to +127 for differential inputs
+(8-bit ADC).
 
 The out0_enable file is RW. Reading gives "1" for analog output enabled and
 "0" for analog output disabled. Writing accepts "0" and "1" accordingly.
diff --git a/Documentation/hwmon/tmp421 b/Documentation/hwmon/tmp421
new file mode 100644 (file)
index 0000000..0cf07f8
--- /dev/null
@@ -0,0 +1,36 @@
+Kernel driver tmp421
+====================
+
+Supported chips:
+  * Texas Instruments TMP421
+    Prefix: 'tmp421'
+    Addresses scanned: I2C 0x2a, 0x4c, 0x4d, 0x4e and 0x4f
+    Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
+  * Texas Instruments TMP422
+    Prefix: 'tmp422'
+    Addresses scanned: I2C 0x2a, 0x4c, 0x4d, 0x4e and 0x4f
+    Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
+  * Texas Instruments TMP423
+    Prefix: 'tmp423'
+    Addresses scanned: I2C 0x2a, 0x4c, 0x4d, 0x4e and 0x4f
+    Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
+
+Authors:
+       Andre Prendel <andre.prendel@gmx.de>
+
+Description
+-----------
+
+This driver implements support for Texas Instruments TMP421, TMP422
+and TMP423 temperature sensor chips. These chips implement one local
+and up to one (TMP421), up to two (TMP422) or up to three (TMP423)
+remote sensors. Temperature is measured in degrees Celsius. The chips
+are wired over I2C/SMBus and specified over a temperature range of -40
+to +125 degrees Celsius. Resolution for both the local and remote
+channels is 0.0625 degree C.
+
+The chips support only temperature measurement. The driver exports
+the temperature values via the following sysfs files:
+
+temp[1-4]_input
+temp[2-4]_fault
index 4c12a290bee52a00186e4a4e4c4d726996320d8e..f45d0d8e71d8a6128b1af3cebf96ab4f79e62821 100644 (file)
@@ -1286,6 +1286,10 @@ and is between 256 and 4096 characters. It is defined in the file
                        (machvec) in a generic kernel.
                        Example: machvec=hpzx1_swiotlb
 
+       machtype=       [Loongson] Share the same kernel image file between different
+                        yeeloong laptop.
+                       Example: machtype=lemote-yeeloong-2f-7inch
+
        max_addr=nn[KMG]        [KNL,BOOT,ia64] All physical memory greater
                        than or equal to this physical address is ignored.
 
index 90e8b3383ba247c67cfd5040f7a7874182d2ee60..78c45a87be57a3c0d8df08664adce439df47586d 100644 (file)
@@ -1,7 +1,7 @@
                             Event Tracing
 
                Documentation written by Theodore Ts'o
-                       Updated by Li Zefan
+               Updated by Li Zefan and Tom Zanussi
 
 1. Introduction
 ===============
@@ -97,3 +97,185 @@ The format of this boot option is the same as described in section 2.1.
 
 See The example provided in samples/trace_events
 
+4. Event formats
+================
+
+Each trace event has a 'format' file associated with it that contains
+a description of each field in a logged event.  This information can
+be used to parse the binary trace stream, and is also the place to
+find the field names that can be used in event filters (see section 5).
+
+It also displays the format string that will be used to print the
+event in text mode, along with the event name and ID used for
+profiling.
+
+Every event has a set of 'common' fields associated with it; these are
+the fields prefixed with 'common_'.  The other fields vary between
+events and correspond to the fields defined in the TRACE_EVENT
+definition for that event.
+
+Each field in the format has the form:
+
+     field:field-type field-name; offset:N; size:N;
+
+where offset is the offset of the field in the trace record and size
+is the size of the data item, in bytes.
+
+For example, here's the information displayed for the 'sched_wakeup'
+event:
+
+# cat /debug/tracing/events/sched/sched_wakeup/format
+
+name: sched_wakeup
+ID: 60
+format:
+       field:unsigned short common_type;       offset:0;       size:2;
+       field:unsigned char common_flags;       offset:2;       size:1;
+       field:unsigned char common_preempt_count;       offset:3;       size:1;
+       field:int common_pid;   offset:4;       size:4;
+       field:int common_tgid;  offset:8;       size:4;
+
+       field:char comm[TASK_COMM_LEN]; offset:12;      size:16;
+       field:pid_t pid;        offset:28;      size:4;
+       field:int prio; offset:32;      size:4;
+       field:int success;      offset:36;      size:4;
+       field:int cpu;  offset:40;      size:4;
+
+print fmt: "task %s:%d [%d] success=%d [%03d]", REC->comm, REC->pid,
+          REC->prio, REC->success, REC->cpu
+
+This event contains 10 fields, the first 5 common and the remaining 5
+event-specific.  All the fields for this event are numeric, except for
+'comm' which is a string, a distinction important for event filtering.
+
+5. Event filtering
+==================
+
+Trace events can be filtered in the kernel by associating boolean
+'filter expressions' with them.  As soon as an event is logged into
+the trace buffer, its fields are checked against the filter expression
+associated with that event type.  An event with field values that
+'match' the filter will appear in the trace output, and an event whose
+values don't match will be discarded.  An event with no filter
+associated with it matches everything, and is the default when no
+filter has been set for an event.
+
+5.1 Expression syntax
+---------------------
+
+A filter expression consists of one or more 'predicates' that can be
+combined using the logical operators '&&' and '||'.  A predicate is
+simply a clause that compares the value of a field contained within a
+logged event with a constant value and returns either 0 or 1 depending
+on whether the field value matched (1) or didn't match (0):
+
+         field-name relational-operator value
+
+Parentheses can be used to provide arbitrary logical groupings and
+double-quotes can be used to prevent the shell from interpreting
+operators as shell metacharacters.
+
+The field-names available for use in filters can be found in the
+'format' files for trace events (see section 4).
+
+The relational-operators depend on the type of the field being tested:
+
+The operators available for numeric fields are:
+
+==, !=, <, <=, >, >=
+
+And for string fields they are:
+
+==, !=
+
+Currently, only exact string matches are supported.
+
+Currently, the maximum number of predicates in a filter is 16.
+
+5.2 Setting filters
+-------------------
+
+A filter for an individual event is set by writing a filter expression
+to the 'filter' file for the given event.
+
+For example:
+
+# cd /debug/tracing/events/sched/sched_wakeup
+# echo "common_preempt_count > 4" > filter
+
+A slightly more involved example:
+
+# cd /debug/tracing/events/sched/sched_signal_send
+# echo "((sig >= 10 && sig < 15) || sig == 17) && comm != bash" > filter
+
+If there is an error in the expression, you'll get an 'Invalid
+argument' error when setting it, and the erroneous string along with
+an error message can be seen by looking at the filter e.g.:
+
+# cd /debug/tracing/events/sched/sched_signal_send
+# echo "((sig >= 10 && sig < 15) || dsig == 17) && comm != bash" > filter
+-bash: echo: write error: Invalid argument
+# cat filter
+((sig >= 10 && sig < 15) || dsig == 17) && comm != bash
+^
+parse_error: Field not found
+
+Currently the caret ('^') for an error always appears at the beginning of
+the filter string; the error message should still be useful though
+even without more accurate position info.
+
+5.3 Clearing filters
+--------------------
+
+To clear the filter for an event, write a '0' to the event's filter
+file.
+
+To clear the filters for all events in a subsystem, write a '0' to the
+subsystem's filter file.
+
+5.3 Subsystem filters
+---------------------
+
+For convenience, filters for every event in a subsystem can be set or
+cleared as a group by writing a filter expression into the filter file
+at the root of the subsytem.  Note however, that if a filter for any
+event within the subsystem lacks a field specified in the subsystem
+filter, or if the filter can't be applied for any other reason, the
+filter for that event will retain its previous setting.  This can
+result in an unintended mixture of filters which could lead to
+confusing (to the user who might think different filters are in
+effect) trace output.  Only filters that reference just the common
+fields can be guaranteed to propagate successfully to all events.
+
+Here are a few subsystem filter examples that also illustrate the
+above points:
+
+Clear the filters on all events in the sched subsytem:
+
+# cd /sys/kernel/debug/tracing/events/sched
+# echo 0 > filter
+# cat sched_switch/filter
+none
+# cat sched_wakeup/filter
+none
+
+Set a filter using only common fields for all events in the sched
+subsytem (all events end up with the same filter):
+
+# cd /sys/kernel/debug/tracing/events/sched
+# echo common_pid == 0 > filter
+# cat sched_switch/filter
+common_pid == 0
+# cat sched_wakeup/filter
+common_pid == 0
+
+Attempt to set a filter using a non-common field for all events in the
+sched subsytem (all events but those that have a prev_pid field retain
+their old filters):
+
+# cd /sys/kernel/debug/tracing/events/sched
+# echo prev_pid == 0 > filter
+# cat sched_switch/filter
+prev_pid == 0
+# cat sched_wakeup/filter
+common_pid == 0
diff --git a/Documentation/trace/ftrace-design.txt b/Documentation/trace/ftrace-design.txt
new file mode 100644 (file)
index 0000000..7003e10
--- /dev/null
@@ -0,0 +1,233 @@
+               function tracer guts
+               ====================
+
+Introduction
+------------
+
+Here we will cover the architecture pieces that the common function tracing
+code relies on for proper functioning.  Things are broken down into increasing
+complexity so that you can start simple and at least get basic functionality.
+
+Note that this focuses on architecture implementation details only.  If you
+want more explanation of a feature in terms of common code, review the common
+ftrace.txt file.
+
+
+Prerequisites
+-------------
+
+Ftrace relies on these features being implemented:
+ STACKTRACE_SUPPORT - implement save_stack_trace()
+ TRACE_IRQFLAGS_SUPPORT - implement include/asm/irqflags.h
+
+
+HAVE_FUNCTION_TRACER
+--------------------
+
+You will need to implement the mcount and the ftrace_stub functions.
+
+The exact mcount symbol name will depend on your toolchain.  Some call it
+"mcount", "_mcount", or even "__mcount".  You can probably figure it out by
+running something like:
+       $ echo 'main(){}' | gcc -x c -S -o - - -pg | grep mcount
+               call    mcount
+We'll make the assumption below that the symbol is "mcount" just to keep things
+nice and simple in the examples.
+
+Keep in mind that the ABI that is in effect inside of the mcount function is
+*highly* architecture/toolchain specific.  We cannot help you in this regard,
+sorry.  Dig up some old documentation and/or find someone more familiar than
+you to bang ideas off of.  Typically, register usage (argument/scratch/etc...)
+is a major issue at this point, especially in relation to the location of the
+mcount call (before/after function prologue).  You might also want to look at
+how glibc has implemented the mcount function for your architecture.  It might
+be (semi-)relevant.
+
+The mcount function should check the function pointer ftrace_trace_function
+to see if it is set to ftrace_stub.  If it is, there is nothing for you to do,
+so return immediately.  If it isn't, then call that function in the same way
+the mcount function normally calls __mcount_internal -- the first argument is
+the "frompc" while the second argument is the "selfpc" (adjusted to remove the
+size of the mcount call that is embedded in the function).
+
+For example, if the function foo() calls bar(), when the bar() function calls
+mcount(), the arguments mcount() will pass to the tracer are:
+       "frompc" - the address bar() will use to return to foo()
+       "selfpc" - the address bar() (with _mcount() size adjustment)
+
+Also keep in mind that this mcount function will be called *a lot*, so
+optimizing for the default case of no tracer will help the smooth running of
+your system when tracing is disabled.  So the start of the mcount function is
+typically the bare min with checking things before returning.  That also means
+the code flow should usually kept linear (i.e. no branching in the nop case).
+This is of course an optimization and not a hard requirement.
+
+Here is some pseudo code that should help (these functions should actually be
+implemented in assembly):
+
+void ftrace_stub(void)
+{
+       return;
+}
+
+void mcount(void)
+{
+       /* save any bare state needed in order to do initial checking */
+
+       extern void (*ftrace_trace_function)(unsigned long, unsigned long);
+       if (ftrace_trace_function != ftrace_stub)
+               goto do_trace;
+
+       /* restore any bare state */
+
+       return;
+
+do_trace:
+
+       /* save all state needed by the ABI (see paragraph above) */
+
+       unsigned long frompc = ...;
+       unsigned long selfpc = <return address> - MCOUNT_INSN_SIZE;
+       ftrace_trace_function(frompc, selfpc);
+
+       /* restore all state needed by the ABI */
+}
+
+Don't forget to export mcount for modules !
+extern void mcount(void);
+EXPORT_SYMBOL(mcount);
+
+
+HAVE_FUNCTION_TRACE_MCOUNT_TEST
+-------------------------------
+
+This is an optional optimization for the normal case when tracing is turned off
+in the system.  If you do not enable this Kconfig option, the common ftrace
+code will take care of doing the checking for you.
+
+To support this feature, you only need to check the function_trace_stop
+variable in the mcount function.  If it is non-zero, there is no tracing to be
+done at all, so you can return.
+
+This additional pseudo code would simply be:
+void mcount(void)
+{
+       /* save any bare state needed in order to do initial checking */
+
++      if (function_trace_stop)
++              return;
+
+       extern void (*ftrace_trace_function)(unsigned long, unsigned long);
+       if (ftrace_trace_function != ftrace_stub)
+...
+
+
+HAVE_FUNCTION_GRAPH_TRACER
+--------------------------
+
+Deep breath ... time to do some real work.  Here you will need to update the
+mcount function to check ftrace graph function pointers, as well as implement
+some functions to save (hijack) and restore the return address.
+
+The mcount function should check the function pointers ftrace_graph_return
+(compare to ftrace_stub) and ftrace_graph_entry (compare to
+ftrace_graph_entry_stub).  If either of those are not set to the relevant stub
+function, call the arch-specific function ftrace_graph_caller which in turn
+calls the arch-specific function prepare_ftrace_return.  Neither of these
+function names are strictly required, but you should use them anyways to stay
+consistent across the architecture ports -- easier to compare & contrast
+things.
+
+The arguments to prepare_ftrace_return are slightly different than what are
+passed to ftrace_trace_function.  The second argument "selfpc" is the same,
+but the first argument should be a pointer to the "frompc".  Typically this is
+located on the stack.  This allows the function to hijack the return address
+temporarily to have it point to the arch-specific function return_to_handler.
+That function will simply call the common ftrace_return_to_handler function and
+that will return the original return address with which, you can return to the
+original call site.
+
+Here is the updated mcount pseudo code:
+void mcount(void)
+{
+...
+       if (ftrace_trace_function != ftrace_stub)
+               goto do_trace;
+
++#ifdef CONFIG_FUNCTION_GRAPH_TRACER
++      extern void (*ftrace_graph_return)(...);
++      extern void (*ftrace_graph_entry)(...);
++      if (ftrace_graph_return != ftrace_stub ||
++          ftrace_graph_entry != ftrace_graph_entry_stub)
++              ftrace_graph_caller();
++#endif
+
+       /* restore any bare state */
+...
+
+Here is the pseudo code for the new ftrace_graph_caller assembly function:
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+void ftrace_graph_caller(void)
+{
+       /* save all state needed by the ABI */
+
+       unsigned long *frompc = &...;
+       unsigned long selfpc = <return address> - MCOUNT_INSN_SIZE;
+       prepare_ftrace_return(frompc, selfpc);
+
+       /* restore all state needed by the ABI */
+}
+#endif
+
+For information on how to implement prepare_ftrace_return(), simply look at
+the x86 version.  The only architecture-specific piece in it is the setup of
+the fault recovery table (the asm(...) code).  The rest should be the same
+across architectures.
+
+Here is the pseudo code for the new return_to_handler assembly function.  Note
+that the ABI that applies here is different from what applies to the mcount
+code.  Since you are returning from a function (after the epilogue), you might
+be able to skimp on things saved/restored (usually just registers used to pass
+return values).
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+void return_to_handler(void)
+{
+       /* save all state needed by the ABI (see paragraph above) */
+
+       void (*original_return_point)(void) = ftrace_return_to_handler();
+
+       /* restore all state needed by the ABI */
+
+       /* this is usually either a return or a jump */
+       original_return_point();
+}
+#endif
+
+
+HAVE_FTRACE_NMI_ENTER
+---------------------
+
+If you can't trace NMI functions, then skip this option.
+
+<details to be filled>
+
+
+HAVE_FTRACE_SYSCALLS
+---------------------
+
+<details to be filled>
+
+
+HAVE_FTRACE_MCOUNT_RECORD
+-------------------------
+
+See scripts/recordmcount.pl for more info.
+
+<details to be filled>
+
+
+HAVE_DYNAMIC_FTRACE
+---------------------
+
+<details to be filled>
index 355d0f1f8c501ebf244f71fd45a777e7ee26649c..1b6292bbdd6dac91655057367681e1c733bf2a73 100644 (file)
@@ -26,6 +26,12 @@ disabled, and more (ftrace allows for tracer plugins, which
 means that the list of tracers can always grow).
 
 
+Implementation Details
+----------------------
+
+See ftrace-design.txt for details for arch porters and such.
+
+
 The File System
 ---------------
 
index 424beb672affb0bf83fbf7c9fbcacf9784447673..def1c5da787fc5ba6830a44e8a9038db764fd132 100644 (file)
@@ -931,6 +931,12 @@ W: http://wireless.kernel.org/en/users/Drivers/ar9170
 S:     Maintained
 F:     drivers/net/wireless/ath/ar9170/
 
+ATK0110 HWMON DRIVER
+M:     Luca Tettamanti <kronos.it@gmail.com>
+L:     lm-sensors@lm-sensors.org
+S:     Maintained
+F:     drivers/hwmon/asus_atk0110.c
+
 ATI_REMOTE2 DRIVER
 M:     Ville Syrjala <syrjala@sci.fi>
 S:     Maintained
@@ -2151,13 +2157,16 @@ F:      Documentation/filesystems/caching/
 F:     fs/fscache/
 F:     include/linux/fscache*.h
 
-FTRACE
+TRACING
 M:     Steven Rostedt <rostedt@goodmis.org>
+M:     Frederic Weisbecker <fweisbec@gmail.com>
+M:     Ingo Molnar <mingo@redhat.com>
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git tracing/core
 S:     Maintained
 F:     Documentation/trace/ftrace.txt
 F:     arch/*/*/*/ftrace.h
 F:     arch/*/kernel/ftrace.c
-F:     include/*/ftrace.h
+F:     include/*/ftrace.h include/trace/ include/linux/trace*.h
 F:     kernel/trace/
 
 FUJITSU FR-V (FRV) PORT
@@ -5700,7 +5709,7 @@ F:        include/xen/
 
 XFS FILESYSTEM
 P:     Silicon Graphics Inc
-M:     Felix Blyakher <felixb@sgi.com>
+M:     Alex Elder <aelder@sgi.com>
 M:     xfs-masters@oss.sgi.com
 L:     xfs@oss.sgi.com
 W:     http://oss.sgi.com/projects/xfs
index beea3ccebb5e4014ea3c9556824a2d54c0423dfa..7f418bbc261a0f825ab6072f935f1f974a2f746c 100644 (file)
@@ -9,6 +9,7 @@ config OPROFILE
        depends on TRACING_SUPPORT
        select TRACING
        select RING_BUFFER
+       select RING_BUFFER_ALLOW_SWAP
        help
          OProfile is a profiling system capable of profiling the
          whole system, include the kernel, kernel modules, libraries,
index ebcf006406f96568ecc809afd158f169bb6e5147..95587b6c02590071c31402d171642c7774b74ebd 100644 (file)
@@ -253,11 +253,8 @@ static struct clocksource clocksource_32k = {
  */
 unsigned long long sched_clock(void)
 {
-       unsigned long long ret;
-
-       ret = (unsigned long long)clocksource_32k.read(&clocksource_32k);
-       ret = (ret * clocksource_32k.mult_orig) >> clocksource_32k.shift;
-       return ret;
+       return clocksource_cyc2ns(clocksource_32k.read(&clocksource_32k),
+                                 clocksource_32k.mult, clocksource_32k.shift);
 }
 
 static int __init omap_init_clocksource_32k(void)
index 7faa2f554ab19e51a96c39c15799c899c069bf08..9a01d445eca8ed505570495e2f7d5b2fd46f021a 100644 (file)
@@ -342,8 +342,9 @@ config MEM_MT48LC64M4A2FB_7E
 config MEM_MT48LC16M16A2TG_75
        bool
        depends on (BFIN533_EZKIT || BFIN561_EZKIT \
-               || BFIN533_BLUETECHNIX_CM || BFIN537_BLUETECHNIX_CM \
-               || H8606_HVSISTEMAS || BFIN527_BLUETECHNIX_CM)
+               || BFIN533_BLUETECHNIX_CM || BFIN537_BLUETECHNIX_CM_E \
+               || BFIN537_BLUETECHNIX_CM_U || H8606_HVSISTEMAS \
+               || BFIN527_BLUETECHNIX_CM)
        default y
 
 config MEM_MT48LC32M8A2_75
@@ -459,7 +460,7 @@ config VCO_MULT
        default "45" if BFIN533_STAMP
        default "20" if (BFIN537_STAMP || BFIN527_EZKIT || BFIN548_EZKIT || BFIN548_BLUETECHNIX_CM || BFIN538_EZKIT)
        default "22" if BFIN533_BLUETECHNIX_CM
-       default "20" if (BFIN537_BLUETECHNIX_CM || BFIN527_BLUETECHNIX_CM || BFIN561_BLUETECHNIX_CM)
+       default "20" if (BFIN537_BLUETECHNIX_CM_E || BFIN537_BLUETECHNIX_CM_U || BFIN527_BLUETECHNIX_CM || BFIN561_BLUETECHNIX_CM)
        default "20" if BFIN561_EZKIT
        default "16" if (H8606_HVSISTEMAS || BLACKSTAMP || BFIN526_EZBRD || BFIN518F_EZBRD)
        help
@@ -574,8 +575,8 @@ config MAX_VCO_HZ
        default 400000000 if BF514
        default 400000000 if BF516
        default 400000000 if BF518
-       default 600000000 if BF522
-       default 400000000 if BF523
+       default 400000000 if BF522
+       default 600000000 if BF523
        default 400000000 if BF524
        default 600000000 if BF525
        default 400000000 if BF526
@@ -647,7 +648,7 @@ config CYCLES_CLOCKSOURCE
          writing the registers will most likely crash the kernel.
 
 config GPTMR0_CLOCKSOURCE
-       bool "Use GPTimer0 as a clocksource (higher rating)"
+       bool "Use GPTimer0 as a clocksource"
        select BFIN_GPTIMERS
        depends on GENERIC_CLOCKEVENTS
        depends on !TICKSOURCE_GPTMR0
@@ -917,10 +918,6 @@ comment "Cache Support"
 config BFIN_ICACHE
        bool "Enable ICACHE"
        default y
-config BFIN_ICACHE_LOCK
-       bool "Enable Instruction Cache Locking"
-       depends on BFIN_ICACHE
-       default n
 config BFIN_EXTMEM_ICACHEABLE
        bool "Enable ICACHE for external memory"
        depends on BFIN_ICACHE
@@ -987,7 +984,7 @@ endchoice
 config BFIN_L2_DCACHEABLE
        bool "Enable DCACHE for L2 SRAM"
        depends on BFIN_DCACHE
-       depends on BF54x || BF561
+       depends on (BF54x || BF561) && !SMP
        default n
 choice
        prompt "L2 SRAM DCACHE policy"
@@ -995,11 +992,9 @@ choice
        default BFIN_L2_WRITEBACK
 config BFIN_L2_WRITEBACK
        bool "Write back"
-       depends on !SMP
 
 config BFIN_L2_WRITETHROUGH
        bool "Write through"
-       depends on !SMP
 endchoice
 
 
@@ -1154,11 +1149,12 @@ source "fs/Kconfig.binfmt"
 endmenu
 
 menu "Power management options"
+       depends on !SMP
+
 source "kernel/power/Kconfig"
 
 config ARCH_SUSPEND_POSSIBLE
        def_bool y
-       depends on !SMP
 
 choice
        prompt "Standby Power Saving Mode"
@@ -1246,6 +1242,7 @@ config PM_BFIN_WAKE_GP
 endmenu
 
 menu "CPU Frequency scaling"
+       depends on !SMP
 
 source "drivers/cpufreq/Kconfig"
 
index 1fc4981d486f1371ebbf230ead0eeafaba6fe6b2..87f195ee2e06234e50399566b25243e8ca821bda 100644 (file)
@@ -252,4 +252,10 @@ config ACCESS_CHECK
 
          Say N here to disable that check to improve the performance.
 
+config BFIN_ISRAM_SELF_TEST
+       bool "isram boot self tests"
+       default n
+       help
+         Run some self tests of the isram driver code at boot.
+
 endmenu
index dcfb4889559a003d7a51639c2a6ad0ab9806dbef..9905b26009e52514e83bcfe874fa3ae59d7067f7 100644 (file)
@@ -358,9 +358,9 @@ CONFIG_C_AMBEN_ALL=y
 # EBIU_AMBCTL Control
 #
 CONFIG_BANK_0=0x7BB0
-CONFIG_BANK_1=0x5554
+CONFIG_BANK_1=0x7BB0
 CONFIG_BANK_2=0x7BB0
-CONFIG_BANK_3=0xFFC0
+CONFIG_BANK_3=0x99B2
 
 #
 # Bus options (PCI, PCMCIA, EISA, MCA, ISA)
index 48a3a7a9099c3e380a52a6eeb2b8f19ebda7ee07..9dc682088023c1124eca01ef24d935b30c9f83b2 100644 (file)
@@ -359,9 +359,9 @@ CONFIG_C_AMBEN_ALL=y
 # EBIU_AMBCTL Control
 #
 CONFIG_BANK_0=0x7BB0
-CONFIG_BANK_1=0x5554
+CONFIG_BANK_1=0x7BB0
 CONFIG_BANK_2=0x7BB0
-CONFIG_BANK_3=0xFFC0
+CONFIG_BANK_3=0x99B2
 
 #
 # Bus options (PCI, PCMCIA, EISA, MCA, ISA)
index dd8352791dafd67bfea507e6a4f67c65ff6cb5db..77e35d4baf535405aef306cd5c46262703457a88 100644 (file)
@@ -363,9 +363,9 @@ CONFIG_C_AMBEN_ALL=y
 # EBIU_AMBCTL Control
 #
 CONFIG_BANK_0=0x7BB0
-CONFIG_BANK_1=0x5554
+CONFIG_BANK_1=0x7BB0
 CONFIG_BANK_2=0x7BB0
-CONFIG_BANK_3=0xFFC0
+CONFIG_BANK_3=0x99B2
 
 #
 # Bus options (PCI, PCMCIA, EISA, MCA, ISA)
index b3d3cab81cfe5f2d5a100247534a6cf511486ecf..f773ad1155d4b5e06628fa170ccb0747ecff33ed 100644 (file)
@@ -400,7 +400,7 @@ CONFIG_C_AMBEN_ALL=y
 # EBIU_AMBCTL Control
 #
 CONFIG_BANK_0=0x7BB0
-CONFIG_BANK_1=0x5554
+CONFIG_BANK_1=0x7BB0
 CONFIG_BANK_2=0x7BB0
 CONFIG_BANK_3=0x99B2
 CONFIG_EBIU_MBSCTLVAL=0x0
index e39277ea43e8bfd38e4daacd8792526762ae284e..aef0594e7865556a89af0d82e3dd754022c82e10 100644 (file)
@@ -66,7 +66,6 @@ extern void program_IAR(void);
 
 extern asmlinkage void lower_to_irq14(void);
 extern asmlinkage void bfin_return_from_exception(void);
-extern asmlinkage void evt14_softirq(void);
 extern asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs);
 extern int bfin_internal_set_wake(unsigned int irq, unsigned int state);
 
@@ -100,11 +99,6 @@ extern unsigned long bfin_sic_iwr[];
 extern unsigned vr_wakeup;
 extern u16 _bfin_swrst; /* shadow for Software Reset Register (SWRST) */
 
-#ifdef CONFIG_BFIN_ICACHE_LOCK
-extern void cache_grab_lock(int way);
-extern void bfin_cache_lock(int way);
-#endif
-
 #endif
 
 #endif                         /* _BLACKFIN_H_ */
index aaeb4df10d578c6128aa6ef13a6ffb41b91e6a25..c281c6328276188665a6f32563c09ad1c99c536c 100644 (file)
@@ -127,6 +127,7 @@ struct bfin5xx_spi_chip {
        u32 cs_gpio;
        /* Value to send if no TX value is supplied, usually 0x0 or 0xFFFF */
        u16 idle_tx_val;
+       u8 pio_interrupt; /* Enable spi data irq */
 };
 
 #endif /* _SPI_CHANNEL_H_ */
index c5dacf8f8cf9d88dd824375a2066bdb45e0c3967..d18d16837a6d6086667d6b31f03b196b6ffb41c7 100644 (file)
 #define FAULT_USERSUPV  (1 << 17)
 #define FAULT_CPLBBITS  0x0000ffff
 
-#endif                         /* _CPLB_H */
+#ifndef __ASSEMBLY__
+
+static inline void _disable_cplb(u32 mmr, u32 mask)
+{
+       u32 ctrl = bfin_read32(mmr) & ~mask;
+       /* CSYNC to ensure load store ordering */
+       __builtin_bfin_csync();
+       bfin_write32(mmr, ctrl);
+       __builtin_bfin_ssync();
+}
+static inline void disable_cplb(u32 mmr, u32 mask)
+{
+       u32 ctrl = bfin_read32(mmr) & ~mask;
+       CSYNC();
+       bfin_write32(mmr, ctrl);
+       SSYNC();
+}
+#define _disable_dcplb() _disable_cplb(DMEM_CONTROL, ENDCPLB)
+#define  disable_dcplb()  disable_cplb(DMEM_CONTROL, ENDCPLB)
+#define _disable_icplb() _disable_cplb(IMEM_CONTROL, ENICPLB)
+#define  disable_icplb()  disable_cplb(IMEM_CONTROL, ENICPLB)
+
+static inline void _enable_cplb(u32 mmr, u32 mask)
+{
+       u32 ctrl = bfin_read32(mmr) | mask;
+       /* CSYNC to ensure load store ordering */
+       __builtin_bfin_csync();
+       bfin_write32(mmr, ctrl);
+       __builtin_bfin_ssync();
+}
+static inline void enable_cplb(u32 mmr, u32 mask)
+{
+       u32 ctrl = bfin_read32(mmr) | mask;
+       CSYNC();
+       bfin_write32(mmr, ctrl);
+       SSYNC();
+}
+#define _enable_dcplb()  _enable_cplb(DMEM_CONTROL, ENDCPLB)
+#define  enable_dcplb()   enable_cplb(DMEM_CONTROL, ENDCPLB)
+#define _enable_icplb()  _enable_cplb(IMEM_CONTROL, ENICPLB)
+#define  enable_icplb()   enable_cplb(IMEM_CONTROL, ENICPLB)
+
+#endif         /* __ASSEMBLY__ */
+
+#endif         /* _CPLB_H */
index 110f1c1f845c8a1802a04a5f3b8ce4a75542de08..53a762b6fcd2a586a3840e0d322f8063ae9b042c 100644 (file)
  * GNU General Public License for more details.
  */
 
+
+#ifndef __ASM_EARLY_PRINTK_H__
+#define __ASM_EARLY_PRINTK_H__
+
 #ifdef CONFIG_EARLY_PRINTK
+/* For those that don't include it already */
+#include <linux/console.h>
+
 extern int setup_early_printk(char *);
+extern void enable_shadow_console(void);
+extern int shadow_console_enabled(void);
+extern void mark_shadow_error(void);
+extern void early_shadow_reg(unsigned long reg, unsigned int n);
+extern void early_shadow_write(struct console *con, const char *s,
+       unsigned int n) __attribute__((nonnull(2)));
+#define early_shadow_puts(str) early_shadow_write(NULL, str, strlen(str))
+#define early_shadow_stamp() \
+       do { \
+               early_shadow_puts(__FILE__ " : " __stringify(__LINE__) " ["); \
+               early_shadow_puts(__func__); \
+               early_shadow_puts("]\n"); \
+       } while (0)
 #else
 #define setup_early_printk(fmt) do { } while (0)
+#define enable_shadow_console(fmt)  do { } while (0)
+#define early_shadow_stamp() do { } while (0)
 #endif /* CONFIG_EARLY_PRINTK */
+
+#endif /* __ASM_EARLY_PRINTK_H__ */
index 5a87baf0659d05c370d66e63c42f279f297731f3..c823e8ebbfa1973855103ab291e190cadc874f2b 100644 (file)
@@ -23,7 +23,7 @@ typedef unsigned long elf_greg_t;
 #define ELF_NGREG 40 /* (sizeof(struct user_regs_struct) / sizeof(elf_greg_t)) */
 typedef elf_greg_t elf_gregset_t[ELF_NGREG];
 
-typedef struct user_bfinfp_struct elf_fpregset_t;
+typedef struct { } elf_fpregset_t;
 /*
  * This is used to ensure we don't load something for the wrong architecture.
  */
index ec58efc130e677cb5b688b691715e0d4d0a5761c..55b808fced7132185f91c04810aeb113369d83ac 100644 (file)
 # define LOAD_IPIPE_IPEND
 #endif
 
+/*
+ * Workaround for anomalies 05000283 and 05000315
+ */
+#if ANOMALY_05000283 || ANOMALY_05000315
+# define ANOMALY_283_315_WORKAROUND(preg, dreg)                \
+       cc = dreg == dreg;                              \
+       preg.h = HI(CHIPID);                            \
+       preg.l = LO(CHIPID);                            \
+       if cc jump 1f;                                  \
+       dreg.l = W[preg];                               \
+1:
+#else
+# define ANOMALY_283_315_WORKAROUND(preg, dreg)
+#endif /* ANOMALY_05000283 || ANOMALY_05000315 */
+
 #ifndef CONFIG_EXACT_HWERR
 /* As a debugging aid - we save IPEND when DEBUG_KERNEL is on,
  * otherwise it is a waste of cycles.
  * As you can see by the code - we actually need to do two SSYNCS - one to
  * make sure the read/writes complete, and another to make sure the hardware
  * error is recognized by the core.
+ *
+ * The extra nop before the SSYNC is to make sure we work around 05000244,
+ * since the 283/315 workaround includes a branch to the end
  */
 #define INTERRUPT_ENTRY(N)                                             \
-    SSYNC;                                                             \
-    SSYNC;                                                             \
     [--sp] = SYSCFG;                                                   \
     [--sp] = P0;       /*orig_p0*/                                     \
     [--sp] = R0;       /*orig_r0*/                                     \
     [--sp] = (R7:0,P5:0);                                              \
     R1 = ASTAT;                                                                \
+    ANOMALY_283_315_WORKAROUND(p0, r0)                                 \
     P0.L = LO(ILAT);                                                   \
     P0.H = HI(ILAT);                                                   \
+    NOP;                                                               \
+    SSYNC;                                                             \
+    SSYNC;                                                             \
     R0 = [P0];                                                         \
     CC = BITTST(R0, EVT_IVHW_P);                                       \
     IF CC JUMP 1f;                                                     \
     RTI;
 
 #define TIMER_INTERRUPT_ENTRY(N)                                       \
-    SSYNC;                                                             \
-    SSYNC;                                                             \
     [--sp] = SYSCFG;                                                   \
     [--sp] = P0;       /*orig_p0*/                                     \
     [--sp] = R0;       /*orig_r0*/                                     \
     [--sp] = (R7:0,P5:0);                                              \
     R1 = ASTAT;                                                                \
+    ANOMALY_283_315_WORKAROUND(p0, r0)                                 \
     P0.L = LO(ILAT);                                                   \
     P0.H = HI(ILAT);                                                   \
+    NOP;                                                               \
+    SSYNC;                                                             \
+    SSYNC;                                                             \
     R0 = [P0];                                                         \
     CC = BITTST(R0, EVT_IVHW_P);                                       \
     IF CC JUMP 1f;                                                     \
index 8643680f0f786cf53bf94a40f6d4241a511565ec..90c9b400ba6d5e19872cd50e71c2fa51ea4ab11b 100644 (file)
@@ -8,6 +8,6 @@
 #ifndef __ASM_BFIN_FTRACE_H__
 #define __ASM_BFIN_FTRACE_H__
 
-#define MCOUNT_INSN_SIZE       8 /* sizeof mcount call: LINK + CALL */
+#define MCOUNT_INSN_SIZE       6 /* sizeof "[++sp] = rets; call __mcount;" */
 
 #endif
index 87ba9ad399cbd1100e0b57223dad80f1495e6a95..4617ba66278ffadb2ceb1f3cb524eaaa804cbf49 100644 (file)
@@ -145,10 +145,6 @@ void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs);
 
 int __ipipe_get_irq_priority(unsigned irq);
 
-void __ipipe_stall_root_raw(void);
-
-void __ipipe_unstall_root_raw(void);
-
 void __ipipe_serial_debug(const char *fmt, ...);
 
 asmlinkage void __ipipe_call_irqtail(unsigned long addr);
@@ -234,9 +230,6 @@ int ipipe_start_irq_thread(unsigned irq, struct irq_desc *desc);
 #define task_hijacked(p)               0
 #define ipipe_trap_notify(t, r)        0
 
-#define __ipipe_stall_root_raw()       do { } while (0)
-#define __ipipe_unstall_root_raw()     do { } while (0)
-
 #define ipipe_init_irq_threads()               do { } while (0)
 #define ipipe_start_irq_thread(irq, desc)      0
 
index 139b5208f9d8506a1c691345f05519e6c2a33109..7d9e2d3bbede79980b38724e1d887c814137a20d 100644 (file)
@@ -17,6 +17,7 @@ asmlinkage void evt_evt10(void);
 asmlinkage void evt_evt11(void);
 asmlinkage void evt_evt12(void);
 asmlinkage void evt_evt13(void);
+asmlinkage void evt_evt14(void);
 asmlinkage void evt_soft_int1(void);
 asmlinkage void evt_system_call(void);
 asmlinkage void init_exception_buff(void);
index 944e29faae48f4ba389450afe0d07e66a94b3cb5..040410bb07e1e5ac82c31095eebff76e31bc018d 100644 (file)
@@ -127,17 +127,17 @@ static inline void protect_page(struct mm_struct *mm, unsigned long addr,
        unsigned long idx = page >> 5;
        unsigned long bit = 1 << (page & 31);
 
-       if (flags & VM_MAYREAD)
+       if (flags & VM_READ)
                mask[idx] |= bit;
        else
                mask[idx] &= ~bit;
        mask += page_mask_nelts;
-       if (flags & VM_MAYWRITE)
+       if (flags & VM_WRITE)
                mask[idx] |= bit;
        else
                mask[idx] &= ~bit;
        mask += page_mask_nelts;
-       if (flags & VM_MAYEXEC)
+       if (flags & VM_EXEC)
                mask[idx] |= bit;
        else
                mask[idx] &= ~bit;
index b42555c1431cb5683605af10918389d151aeb708..a6f95695731d99ebda1cb14e5823f362f53b5d26 100644 (file)
@@ -50,6 +50,7 @@ struct blackfin_pda {                 /* Per-processor Data Area */
        unsigned long ex_optr;
        unsigned long ex_buf[4];
        unsigned long ex_imask;         /* Saved imask from exception */
+       unsigned long ex_ipend;         /* Saved IPEND from exception */
        unsigned long *ex_stack;        /* Exception stack space */
 
 #ifdef ANOMALY_05000261
@@ -60,6 +61,12 @@ struct blackfin_pda {                        /* Per-processor Data Area */
        unsigned long retx;
        unsigned long seqstat;
        unsigned int __nmi_count;       /* number of times NMI asserted on this CPU */
+#ifdef CONFIG_DEBUG_DOUBLEFAULT
+       unsigned long dcplb_doublefault_addr;
+       unsigned long icplb_doublefault_addr;
+       unsigned long retx_doublefault;
+       unsigned long seqstat_doublefault;
+#endif
 };
 
 extern struct blackfin_pda cpu_pda[];
index 141d9281e4b060be59ca1d4748aaa4fe683a0415..a8ddbc8ed5af6d430ce5da0bf42ec2cf6ddfb531 100644 (file)
@@ -26,6 +26,7 @@ obj-$(CONFIG_MODULES)                += module.o
 obj-$(CONFIG_KGDB)                   += kgdb.o
 obj-$(CONFIG_KGDB_TESTS)             += kgdb_test.o
 obj-$(CONFIG_EARLY_PRINTK)           += early_printk.o
+obj-$(CONFIG_EARLY_PRINTK)           += shadow_console.o
 obj-$(CONFIG_STACKTRACE)             += stacktrace.o
 
 # the kgdb test puts code into L2 and without linker
index b5df9459d6d506b255bd3d07bb13d8f6e15178ee..f05d1b99b0ef4a7f2c3c29671f7b0b22a38fe3c2 100644 (file)
@@ -145,6 +145,7 @@ int main(void)
        DEFINE(PDA_EXBUF, offsetof(struct blackfin_pda, ex_buf));
        DEFINE(PDA_EXIMASK, offsetof(struct blackfin_pda, ex_imask));
        DEFINE(PDA_EXSTACK, offsetof(struct blackfin_pda, ex_stack));
+       DEFINE(PDA_EXIPEND, offsetof(struct blackfin_pda, ex_ipend));
 #ifdef ANOMALY_05000261
        DEFINE(PDA_LFRETX, offsetof(struct blackfin_pda, last_cplb_fault_retx));
 #endif
@@ -152,6 +153,12 @@ int main(void)
        DEFINE(PDA_ICPLB, offsetof(struct blackfin_pda, icplb_fault_addr));
        DEFINE(PDA_RETX, offsetof(struct blackfin_pda, retx));
        DEFINE(PDA_SEQSTAT, offsetof(struct blackfin_pda, seqstat));
+#ifdef CONFIG_DEBUG_DOUBLEFAULT
+       DEFINE(PDA_DF_DCPLB, offsetof(struct blackfin_pda, dcplb_doublefault_addr));
+       DEFINE(PDA_DF_ICPLB, offsetof(struct blackfin_pda, icplb_doublefault_addr));
+       DEFINE(PDA_DF_SEQSTAT, offsetof(struct blackfin_pda, seqstat_doublefault));
+       DEFINE(PDA_DF_RETX, offsetof(struct blackfin_pda, retx_doublefault));
+#endif
 #ifdef CONFIG_SMP
        /* Inter-core lock (in L2 SRAM) */
        DEFINE(SIZEOF_CORELOCK, sizeof(struct corelock_slot));
index 9f9b82816652d6bddc4c67199699d9ba22647e1f..384868dedac3771c2de63a42829129706e88f39b 100644 (file)
@@ -19,6 +19,7 @@
 #include <asm/cacheflush.h>
 #include <asm/dma.h>
 #include <asm/uaccess.h>
+#include <asm/early_printk.h>
 
 /*
  * To make sure we work around 05000119 - we always check DMA_DONE bit,
@@ -146,8 +147,8 @@ EXPORT_SYMBOL(request_dma);
 
 int set_dma_callback(unsigned int channel, irq_handler_t callback, void *data)
 {
-       BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
-              && channel < MAX_DMA_CHANNELS));
+       BUG_ON(channel >= MAX_DMA_CHANNELS ||
+                       dma_ch[channel].chan_status == DMA_CHANNEL_FREE);
 
        if (callback != NULL) {
                int ret;
@@ -181,8 +182,8 @@ static void clear_dma_buffer(unsigned int channel)
 void free_dma(unsigned int channel)
 {
        pr_debug("freedma() : BEGIN \n");
-       BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
-              && channel < MAX_DMA_CHANNELS));
+       BUG_ON(channel >= MAX_DMA_CHANNELS ||
+                       dma_ch[channel].chan_status == DMA_CHANNEL_FREE);
 
        /* Halt the DMA */
        disable_dma(channel);
@@ -236,6 +237,7 @@ void blackfin_dma_resume(void)
  */
 void __init blackfin_dma_early_init(void)
 {
+       early_shadow_stamp();
        bfin_write_MDMA_S0_CONFIG(0);
        bfin_write_MDMA_S1_CONFIG(0);
 }
@@ -246,6 +248,8 @@ void __init early_dma_memcpy(void *pdst, const void *psrc, size_t size)
        unsigned long src = (unsigned long)psrc;
        struct dma_register *dst_ch, *src_ch;
 
+       early_shadow_stamp();
+
        /* We assume that everything is 4 byte aligned, so include
         * a basic sanity check
         */
@@ -300,6 +304,8 @@ void __init early_dma_memcpy(void *pdst, const void *psrc, size_t size)
 
 void __init early_dma_memcpy_done(void)
 {
+       early_shadow_stamp();
+
        while ((bfin_read_MDMA_S0_CONFIG() && !(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)) ||
               (bfin_read_MDMA_S1_CONFIG() && !(bfin_read_MDMA_D1_IRQ_STATUS() & DMA_DONE)))
                continue;
index 6b94462713710b612f3fb82e351b92d5e5bdb46a..fc4681c0170e5d43211ab183967b2c6c87af3cec 100644 (file)
@@ -722,7 +722,6 @@ void bfin_gpio_pm_hibernate_suspend(void)
                gpio_bank_saved[bank].fer = gpio_array[bank]->port_fer;
                gpio_bank_saved[bank].mux = gpio_array[bank]->port_mux;
                gpio_bank_saved[bank].data = gpio_array[bank]->data;
-               gpio_bank_saved[bank].data = gpio_array[bank]->data;
                gpio_bank_saved[bank].inen = gpio_array[bank]->inen;
                gpio_bank_saved[bank].dir = gpio_array[bank]->dir_set;
        }
index 7d70d3bf3212d0a905ed980ce377fe892adf0059..394d0b1b28fe318db1399f3019ae27ccde2da2e5 100644 (file)
@@ -2,7 +2,7 @@
 # arch/blackfin/kernel/cplb-nompu/Makefile
 #
 
-obj-y := cplbinit.o cacheinit.o cplbmgr.o
+obj-y := cplbinit.o cplbmgr.o
 
 CFLAGS_cplbmgr.o := -ffixed-I0 -ffixed-I1 -ffixed-I2 -ffixed-I3 \
                    -ffixed-L0 -ffixed-L1 -ffixed-L2 -ffixed-L3 \
diff --git a/arch/blackfin/kernel/cplb-mpu/cacheinit.c b/arch/blackfin/kernel/cplb-mpu/cacheinit.c
deleted file mode 100644 (file)
index d5a86c3..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- *               Copyright 2004-2007 Analog Devices Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <linux/cpu.h>
-
-#include <asm/cacheflush.h>
-#include <asm/blackfin.h>
-#include <asm/cplb.h>
-#include <asm/cplbinit.h>
-
-#if defined(CONFIG_BFIN_ICACHE)
-void __cpuinit bfin_icache_init(struct cplb_entry *icplb_tbl)
-{
-       unsigned long ctrl;
-       int i;
-
-       SSYNC();
-       for (i = 0; i < MAX_CPLBS; i++) {
-               bfin_write32(ICPLB_ADDR0 + i * 4, icplb_tbl[i].addr);
-               bfin_write32(ICPLB_DATA0 + i * 4, icplb_tbl[i].data);
-       }
-       ctrl = bfin_read_IMEM_CONTROL();
-       ctrl |= IMC | ENICPLB;
-       bfin_write_IMEM_CONTROL(ctrl);
-       SSYNC();
-}
-#endif
-
-#if defined(CONFIG_BFIN_DCACHE)
-void __cpuinit bfin_dcache_init(struct cplb_entry *dcplb_tbl)
-{
-       unsigned long ctrl;
-       int i;
-
-       SSYNC();
-       for (i = 0; i < MAX_CPLBS; i++) {
-               bfin_write32(DCPLB_ADDR0 + i * 4, dcplb_tbl[i].addr);
-               bfin_write32(DCPLB_DATA0 + i * 4, dcplb_tbl[i].data);
-       }
-
-       ctrl = bfin_read_DMEM_CONTROL();
-
-       /*
-        *  Anomaly notes:
-        *  05000287 - We implement workaround #2 - Change the DMEM_CONTROL
-        *  register, so that the port preferences for DAG0 and DAG1 are set
-        *  to port B
-        */
-       ctrl |= DMEM_CNTR | PORT_PREF0 | (ANOMALY_05000287 ? PORT_PREF1 : 0);
-       bfin_write_DMEM_CONTROL(ctrl);
-       SSYNC();
-}
-#endif
index bcdfe9b0b71f0a32ac31d40b2deb2f61590dee62..8e1e9e9e9632680dc5c2e4b3a1dc9da8a54f28ae 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <asm/blackfin.h>
 #include <asm/cacheflush.h>
+#include <asm/cplb.h>
 #include <asm/cplbinit.h>
 #include <asm/mmu_context.h>
 
@@ -41,46 +42,6 @@ int nr_dcplb_miss[NR_CPUS], nr_icplb_miss[NR_CPUS];
 int nr_icplb_supv_miss[NR_CPUS], nr_dcplb_prot[NR_CPUS];
 int nr_cplb_flush[NR_CPUS];
 
-static inline void disable_dcplb(void)
-{
-       unsigned long ctrl;
-       SSYNC();
-       ctrl = bfin_read_DMEM_CONTROL();
-       ctrl &= ~ENDCPLB;
-       bfin_write_DMEM_CONTROL(ctrl);
-       SSYNC();
-}
-
-static inline void enable_dcplb(void)
-{
-       unsigned long ctrl;
-       SSYNC();
-       ctrl = bfin_read_DMEM_CONTROL();
-       ctrl |= ENDCPLB;
-       bfin_write_DMEM_CONTROL(ctrl);
-       SSYNC();
-}
-
-static inline void disable_icplb(void)
-{
-       unsigned long ctrl;
-       SSYNC();
-       ctrl = bfin_read_IMEM_CONTROL();
-       ctrl &= ~ENICPLB;
-       bfin_write_IMEM_CONTROL(ctrl);
-       SSYNC();
-}
-
-static inline void enable_icplb(void)
-{
-       unsigned long ctrl;
-       SSYNC();
-       ctrl = bfin_read_IMEM_CONTROL();
-       ctrl |= ENICPLB;
-       bfin_write_IMEM_CONTROL(ctrl);
-       SSYNC();
-}
-
 /*
  * Given the contents of the status register, return the index of the
  * CPLB that caused the fault.
@@ -198,10 +159,10 @@ static noinline int dcplb_miss(unsigned int cpu)
        dcplb_tbl[cpu][idx].addr = addr;
        dcplb_tbl[cpu][idx].data = d_data;
 
-       disable_dcplb();
+       _disable_dcplb();
        bfin_write32(DCPLB_DATA0 + idx * 4, d_data);
        bfin_write32(DCPLB_ADDR0 + idx * 4, addr);
-       enable_dcplb();
+       _enable_dcplb();
 
        return 0;
 }
@@ -288,10 +249,10 @@ static noinline int icplb_miss(unsigned int cpu)
        icplb_tbl[cpu][idx].addr = addr;
        icplb_tbl[cpu][idx].data = i_data;
 
-       disable_icplb();
+       _disable_icplb();
        bfin_write32(ICPLB_DATA0 + idx * 4, i_data);
        bfin_write32(ICPLB_ADDR0 + idx * 4, addr);
-       enable_icplb();
+       _enable_icplb();
 
        return 0;
 }
@@ -319,7 +280,7 @@ static noinline int dcplb_protection_fault(unsigned int cpu)
 int cplb_hdr(int seqstat, struct pt_regs *regs)
 {
        int cause = seqstat & 0x3f;
-       unsigned int cpu = smp_processor_id();
+       unsigned int cpu = raw_smp_processor_id();
        switch (cause) {
        case 0x23:
                return dcplb_protection_fault(cpu);
@@ -340,19 +301,19 @@ void flush_switched_cplbs(unsigned int cpu)
        nr_cplb_flush[cpu]++;
 
        local_irq_save_hw(flags);
-       disable_icplb();
+       _disable_icplb();
        for (i = first_switched_icplb; i < MAX_CPLBS; i++) {
                icplb_tbl[cpu][i].data = 0;
                bfin_write32(ICPLB_DATA0 + i * 4, 0);
        }
-       enable_icplb();
+       _enable_icplb();
 
-       disable_dcplb();
+       _disable_dcplb();
        for (i = first_switched_dcplb; i < MAX_CPLBS; i++) {
                dcplb_tbl[cpu][i].data = 0;
                bfin_write32(DCPLB_DATA0 + i * 4, 0);
        }
-       enable_dcplb();
+       _enable_dcplb();
        local_irq_restore_hw(flags);
 
 }
@@ -385,7 +346,7 @@ void set_mask_dcplbs(unsigned long *masks, unsigned int cpu)
 #endif
        }
 
-       disable_dcplb();
+       _disable_dcplb();
        for (i = first_mask_dcplb; i < first_switched_dcplb; i++) {
                dcplb_tbl[cpu][i].addr = addr;
                dcplb_tbl[cpu][i].data = d_data;
@@ -393,6 +354,6 @@ void set_mask_dcplbs(unsigned long *masks, unsigned int cpu)
                bfin_write32(DCPLB_ADDR0 + i * 4, addr);
                addr += PAGE_SIZE;
        }
-       enable_dcplb();
+       _enable_dcplb();
        local_irq_restore_hw(flags);
 }
index 7d70d3bf3212d0a905ed980ce377fe892adf0059..394d0b1b28fe318db1399f3019ae27ccde2da2e5 100644 (file)
@@ -2,7 +2,7 @@
 # arch/blackfin/kernel/cplb-nompu/Makefile
 #
 
-obj-y := cplbinit.o cacheinit.o cplbmgr.o
+obj-y := cplbinit.o cplbmgr.o
 
 CFLAGS_cplbmgr.o := -ffixed-I0 -ffixed-I1 -ffixed-I2 -ffixed-I3 \
                    -ffixed-L0 -ffixed-L1 -ffixed-L2 -ffixed-L3 \
diff --git a/arch/blackfin/kernel/cplb-nompu/cacheinit.c b/arch/blackfin/kernel/cplb-nompu/cacheinit.c
deleted file mode 100644 (file)
index d5a86c3..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- *               Copyright 2004-2007 Analog Devices Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <linux/cpu.h>
-
-#include <asm/cacheflush.h>
-#include <asm/blackfin.h>
-#include <asm/cplb.h>
-#include <asm/cplbinit.h>
-
-#if defined(CONFIG_BFIN_ICACHE)
-void __cpuinit bfin_icache_init(struct cplb_entry *icplb_tbl)
-{
-       unsigned long ctrl;
-       int i;
-
-       SSYNC();
-       for (i = 0; i < MAX_CPLBS; i++) {
-               bfin_write32(ICPLB_ADDR0 + i * 4, icplb_tbl[i].addr);
-               bfin_write32(ICPLB_DATA0 + i * 4, icplb_tbl[i].data);
-       }
-       ctrl = bfin_read_IMEM_CONTROL();
-       ctrl |= IMC | ENICPLB;
-       bfin_write_IMEM_CONTROL(ctrl);
-       SSYNC();
-}
-#endif
-
-#if defined(CONFIG_BFIN_DCACHE)
-void __cpuinit bfin_dcache_init(struct cplb_entry *dcplb_tbl)
-{
-       unsigned long ctrl;
-       int i;
-
-       SSYNC();
-       for (i = 0; i < MAX_CPLBS; i++) {
-               bfin_write32(DCPLB_ADDR0 + i * 4, dcplb_tbl[i].addr);
-               bfin_write32(DCPLB_DATA0 + i * 4, dcplb_tbl[i].data);
-       }
-
-       ctrl = bfin_read_DMEM_CONTROL();
-
-       /*
-        *  Anomaly notes:
-        *  05000287 - We implement workaround #2 - Change the DMEM_CONTROL
-        *  register, so that the port preferences for DAG0 and DAG1 are set
-        *  to port B
-        */
-       ctrl |= DMEM_CNTR | PORT_PREF0 | (ANOMALY_05000287 ? PORT_PREF1 : 0);
-       bfin_write_DMEM_CONTROL(ctrl);
-       SSYNC();
-}
-#endif
index 685f160a5a369789671f948e2132d36fb5c2e29b..5d8ad503f82ab52ef69d29f4d980e2eb9ffac8b1 100644 (file)
@@ -36,7 +36,7 @@ int first_switched_icplb PDT_ATTR;
 int first_switched_dcplb PDT_ATTR;
 
 struct cplb_boundary dcplb_bounds[9] PDT_ATTR;
-struct cplb_boundary icplb_bounds[7] PDT_ATTR;
+struct cplb_boundary icplb_bounds[9] PDT_ATTR;
 
 int icplb_nr_bounds PDT_ATTR;
 int dcplb_nr_bounds PDT_ATTR;
@@ -167,14 +167,21 @@ void __init generate_cplb_tables_all(void)
                icplb_bounds[i_i++].data = (reserved_mem_icache_on ?
                                            SDRAM_IGENERIC : SDRAM_INON_CHBL);
        }
+       /* Addressing hole up to the async bank.  */
+       icplb_bounds[i_i].eaddr = ASYNC_BANK0_BASE;
+       icplb_bounds[i_i++].data = 0;
+       /* ASYNC banks.  */
+       icplb_bounds[i_i].eaddr = ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE;
+       icplb_bounds[i_i++].data = SDRAM_EBIU;
        /* Addressing hole up to BootROM.  */
        icplb_bounds[i_i].eaddr = BOOT_ROM_START;
        icplb_bounds[i_i++].data = 0;
        /* BootROM -- largest one should be less than 1 meg.  */
        icplb_bounds[i_i].eaddr = BOOT_ROM_START + (1 * 1024 * 1024);
        icplb_bounds[i_i++].data = SDRAM_IGENERIC;
+
        if (L2_LENGTH) {
-               /* Addressing hole up to L2 SRAM, including the async bank.  */
+               /* Addressing hole up to L2 SRAM.  */
                icplb_bounds[i_i].eaddr = L2_START;
                icplb_bounds[i_i++].data = 0;
                /* L2 SRAM.  */
index 12b030842fdbc1623c99997c60e67d534f168112..d9ea46c6e41a581087ca26f4ecc07c25eadc4c76 100644 (file)
@@ -48,36 +48,13 @@ int nr_cplb_flush[NR_CPUS], nr_dcplb_prot[NR_CPUS];
 #define MGR_ATTR
 #endif
 
-/*
- * We're in an exception handler.  The normal cli nop nop workaround
- * isn't going to do very much, as the only thing that can interrupt
- * us is an NMI, and the cli isn't going to stop that.
- */
-#define NOWA_SSYNC __asm__ __volatile__ ("ssync;")
-
-/* Anomaly handlers provide SSYNCs, so avoid extra if anomaly is present */
-#if ANOMALY_05000125
-
-#define bfin_write_DMEM_CONTROL_SSYNC(v)    bfin_write_DMEM_CONTROL(v)
-#define bfin_write_IMEM_CONTROL_SSYNC(v)    bfin_write_IMEM_CONTROL(v)
-
-#else
-
-#define bfin_write_DMEM_CONTROL_SSYNC(v) \
-    do { NOWA_SSYNC; bfin_write_DMEM_CONTROL(v); NOWA_SSYNC; } while (0)
-#define bfin_write_IMEM_CONTROL_SSYNC(v) \
-    do { NOWA_SSYNC; bfin_write_IMEM_CONTROL(v); NOWA_SSYNC; } while (0)
-
-#endif
-
 static inline void write_dcplb_data(int cpu, int idx, unsigned long data,
                                    unsigned long addr)
 {
-       unsigned long ctrl = bfin_read_DMEM_CONTROL();
-       bfin_write_DMEM_CONTROL_SSYNC(ctrl & ~ENDCPLB);
+       _disable_dcplb();
        bfin_write32(DCPLB_DATA0 + idx * 4, data);
        bfin_write32(DCPLB_ADDR0 + idx * 4, addr);
-       bfin_write_DMEM_CONTROL_SSYNC(ctrl);
+       _enable_dcplb();
 
 #ifdef CONFIG_CPLB_INFO
        dcplb_tbl[cpu][idx].addr = addr;
@@ -88,12 +65,10 @@ static inline void write_dcplb_data(int cpu, int idx, unsigned long data,
 static inline void write_icplb_data(int cpu, int idx, unsigned long data,
                                    unsigned long addr)
 {
-       unsigned long ctrl = bfin_read_IMEM_CONTROL();
-
-       bfin_write_IMEM_CONTROL_SSYNC(ctrl & ~ENICPLB);
+       _disable_icplb();
        bfin_write32(ICPLB_DATA0 + idx * 4, data);
        bfin_write32(ICPLB_ADDR0 + idx * 4, addr);
-       bfin_write_IMEM_CONTROL_SSYNC(ctrl);
+       _enable_icplb();
 
 #ifdef CONFIG_CPLB_INFO
        icplb_tbl[cpu][idx].addr = addr;
@@ -227,7 +202,7 @@ MGR_ATTR static int dcplb_miss(int cpu)
 MGR_ATTR int cplb_hdr(int seqstat, struct pt_regs *regs)
 {
        int cause = seqstat & 0x3f;
-       unsigned int cpu = smp_processor_id();
+       unsigned int cpu = raw_smp_processor_id();
        switch (cause) {
        case VEC_CPLB_I_M:
                return icplb_miss(cpu);
index 2ab56811841c6c6982e8cc00d1ca2724addc54d1..931c78b5ea1fc086ca43d1c03c62cc646e45bcf9 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/serial_core.h>
 #include <linux/console.h>
 #include <linux/string.h>
+#include <linux/reboot.h>
 #include <asm/blackfin.h>
 #include <asm/irq_handler.h>
 #include <asm/early_printk.h>
@@ -181,6 +182,22 @@ asmlinkage void __init init_early_exception_vectors(void)
        u32 evt;
        SSYNC();
 
+       /*
+        * This starts up the shadow buffer, incase anything crashes before
+        * setup arch
+        */
+       mark_shadow_error();
+       early_shadow_puts(linux_banner);
+       early_shadow_stamp();
+
+       if (CPUID != bfin_cpuid()) {
+               early_shadow_puts("Running on wrong machine type, expected");
+               early_shadow_reg(CPUID, 16);
+               early_shadow_puts(", but running on");
+               early_shadow_reg(bfin_cpuid(), 16);
+               early_shadow_puts("\n");
+       }
+
        /* cannot program in software:
         * evt0 - emulation (jtag)
         * evt1 - reset
@@ -199,6 +216,7 @@ asmlinkage void __init init_early_exception_vectors(void)
 
 }
 
+__attribute__((__noreturn__))
 asmlinkage void __init early_trap_c(struct pt_regs *fp, void *retaddr)
 {
        /* This can happen before the uart is initialized, so initialize
@@ -210,10 +228,58 @@ asmlinkage void __init early_trap_c(struct pt_regs *fp, void *retaddr)
        if (likely(early_console == NULL) && CPUID == bfin_cpuid())
                setup_early_printk(DEFAULT_EARLY_PORT);
 
-       printk(KERN_EMERG "Early panic\n");
-       dump_bfin_mem(fp);
-       show_regs(fp);
-       dump_bfin_trace_buffer();
+       if (!shadow_console_enabled()) {
+               /* crap - we crashed before setup_arch() */
+               early_shadow_puts("panic before setup_arch\n");
+               early_shadow_puts("IPEND:");
+               early_shadow_reg(fp->ipend, 16);
+               if (fp->seqstat & SEQSTAT_EXCAUSE) {
+                       early_shadow_puts("\nEXCAUSE:");
+                       early_shadow_reg(fp->seqstat & SEQSTAT_EXCAUSE, 8);
+               }
+               if (fp->seqstat & SEQSTAT_HWERRCAUSE) {
+                       early_shadow_puts("\nHWERRCAUSE:");
+                       early_shadow_reg(
+                               (fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14, 8);
+               }
+               early_shadow_puts("\nErr @");
+               if (fp->ipend & EVT_EVX)
+                       early_shadow_reg(fp->retx, 32);
+               else
+                       early_shadow_reg(fp->pc, 32);
+#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
+               early_shadow_puts("\nTrace:");
+               if (likely(bfin_read_TBUFSTAT() & TBUFCNT)) {
+                       while (bfin_read_TBUFSTAT() & TBUFCNT) {
+                               early_shadow_puts("\nT  :");
+                               early_shadow_reg(bfin_read_TBUF(), 32);
+                               early_shadow_puts("\n S :");
+                               early_shadow_reg(bfin_read_TBUF(), 32);
+                       }
+               }
+#endif
+               early_shadow_puts("\nUse bfin-elf-addr2line to determine "
+                       "function names\n");
+               /*
+                * We should panic(), but we can't - since panic calls printk,
+                * and printk uses memcpy.
+                * we want to reboot, but if the machine type is different,
+                * can't due to machine specific reboot sequences
+                */
+               if (CPUID == bfin_cpuid()) {
+                       early_shadow_puts("Trying to restart\n");
+                       machine_restart("");
+               }
+
+               early_shadow_puts("Halting, since it is not safe to restart\n");
+               while (1)
+                       asm volatile ("EMUEXCPT; IDLE;\n");
+
+       } else {
+               printk(KERN_EMERG "Early panic\n");
+               show_regs(fp);
+               dump_bfin_trace_buffer();
+       }
 
        panic("Died early");
 }
index a9cfba9946b5f8520d9366ad406357707a8b1c46..3f8769b7db54bc775a916d6829e515654b178706 100644 (file)
 
 ENTRY(_ret_from_fork)
 #ifdef CONFIG_IPIPE
-       [--sp] = reti;          /* IRQs on. */
-       SP += 4;
+       /*
+        * Hw IRQs are off on entry, and we don't want the scheduling tail
+        * code to starve high priority domains from interrupts while it
+        * runs. Therefore we first stall the root stage to have the
+        * virtual interrupt state reflect IMASK.
+        */
+       p0.l = ___ipipe_root_status;
+       p0.h = ___ipipe_root_status;
+       r4 = [p0];
+       bitset(r4, 0);
+       [p0] = r4;
+       /*
+        * Then we may enable hw IRQs, allowing preemption from high
+        * priority domains. schedule_tail() will do local_irq_enable()
+        * since Blackfin does not define __ARCH_WANT_UNLOCKED_CTXSW, so
+        * there is no need to unstall the root domain by ourselves
+        * afterwards.
+        */
+       p0.l = _bfin_irq_flags;
+       p0.h = _bfin_irq_flags;
+       r4 = [p0];
+       sti r4;
 #endif /* CONFIG_IPIPE */
        SP += -12;
        call _schedule_tail;
index 6980b7a0615d9422d1c7f808b7cea79d12f7126c..76dd4fbcd17a2e8f7adc45f76237e0c2a4d19538 100644 (file)
@@ -17,8 +17,8 @@
  * only one we can blow away.  With pointer registers, we have P0-P2.
  *
  * Upon entry, the RETS will point to the top of the current profiled
- * function.  And since GCC setup the frame for us, the previous function
- * will be waiting there.  mmmm pie.
+ * function.  And since GCC pushed the previous RETS for us, the previous
+ * function will be waiting there.  mmmm pie.
  */
 ENTRY(__mcount)
        /* save third function arg early so we can do testing below */
@@ -70,14 +70,14 @@ ENTRY(__mcount)
        /* setup the tracer function */
        p0 = r3;
 
-       /* tracer(ulong frompc, ulong selfpc):
-        *  frompc: the pc that did the call to ...
-        *  selfpc: ... this location
-        * the selfpc itself will need adjusting for the mcount call
+       /* function_trace_call(unsigned long ip, unsigned long parent_ip):
+        *  ip: this point was called by ...
+        *  parent_ip: ... this function
+        * the ip itself will need adjusting for the mcount call
         */
-       r1 = rets;
-       r0 = [fp + 4];
-       r1 += -MCOUNT_INSN_SIZE;
+       r0 = rets;
+       r1 = [sp + 16]; /* skip the 4 local regs on stack */
+       r0 += -MCOUNT_INSN_SIZE;
 
        /* call the tracer */
        call (p0);
@@ -106,9 +106,10 @@ ENTRY(_ftrace_graph_caller)
        [--sp] = r1;
        [--sp] = rets;
 
-       r0 = fp;
+       /* prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) */
+       r0 = sp;
        r1 = rets;
-       r0 += 4;
+       r0 += 16;       /* skip the 4 local regs on stack */
        r1 += -MCOUNT_INSN_SIZE;
        call _prepare_ftrace_return;
 
index 905bfc40a00b0875761c95b4226103cff6a5120a..f2c85ac6f2daf7dcfa47628a893b3993a15eeedc 100644 (file)
@@ -24,7 +24,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
        if (unlikely(atomic_read(&current->tracing_graph_pause)))
                return;
 
-       if (ftrace_push_return_trace(*parent, self_addr, &trace.depth) == -EBUSY)
+       if (ftrace_push_return_trace(*parent, self_addr, &trace.depth, 0) == -EBUSY)
                return;
 
        trace.func = self_addr;
index b8d22034b9a6ce8f829efa2dfd3f41afa42df16f..5d7382396dc02846d62b56506cb9088ae9ed66f6 100644 (file)
 #include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/kthread.h>
-#include <asm/unistd.h>
+#include <linux/unistd.h>
+#include <linux/io.h>
 #include <asm/system.h>
 #include <asm/atomic.h>
-#include <asm/io.h>
 
 DEFINE_PER_CPU(struct pt_regs, __ipipe_tick_regs);
 
@@ -90,6 +90,7 @@ void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs)
        struct ipipe_percpu_domain_data *p = ipipe_root_cpudom_ptr();
        struct ipipe_domain *this_domain, *next_domain;
        struct list_head *head, *pos;
+       struct ipipe_irqdesc *idesc;
        int m_ack, s = -1;
 
        /*
@@ -100,17 +101,20 @@ void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs)
         */
        m_ack = (regs == NULL || irq == IRQ_SYSTMR || irq == IRQ_CORETMR);
        this_domain = __ipipe_current_domain;
+       idesc = &this_domain->irqs[irq];
 
-       if (unlikely(test_bit(IPIPE_STICKY_FLAG, &this_domain->irqs[irq].control)))
+       if (unlikely(test_bit(IPIPE_STICKY_FLAG, &idesc->control)))
                head = &this_domain->p_link;
        else {
                head = __ipipe_pipeline.next;
                next_domain = list_entry(head, struct ipipe_domain, p_link);
-               if (likely(test_bit(IPIPE_WIRED_FLAG, &next_domain->irqs[irq].control))) {
-                       if (!m_ack && next_domain->irqs[irq].acknowledge != NULL)
-                               next_domain->irqs[irq].acknowledge(irq, irq_to_desc(irq));
+               idesc = &next_domain->irqs[irq];
+               if (likely(test_bit(IPIPE_WIRED_FLAG, &idesc->control))) {
+                       if (!m_ack && idesc->acknowledge != NULL)
+                               idesc->acknowledge(irq, irq_to_desc(irq));
                        if (test_bit(IPIPE_SYNCDEFER_FLAG, &p->status))
-                               s = __test_and_set_bit(IPIPE_STALL_FLAG, &p->status);
+                               s = __test_and_set_bit(IPIPE_STALL_FLAG,
+                                                      &p->status);
                        __ipipe_dispatch_wired(next_domain, irq);
                        goto out;
                }
@@ -121,14 +125,15 @@ void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs)
        pos = head;
        while (pos != &__ipipe_pipeline) {
                next_domain = list_entry(pos, struct ipipe_domain, p_link);
-               if (test_bit(IPIPE_HANDLE_FLAG, &next_domain->irqs[irq].control)) {
+               idesc = &next_domain->irqs[irq];
+               if (test_bit(IPIPE_HANDLE_FLAG, &idesc->control)) {
                        __ipipe_set_irq_pending(next_domain, irq);
-                       if (!m_ack && next_domain->irqs[irq].acknowledge != NULL) {
-                               next_domain->irqs[irq].acknowledge(irq, irq_to_desc(irq));
+                       if (!m_ack && idesc->acknowledge != NULL) {
+                               idesc->acknowledge(irq, irq_to_desc(irq));
                                m_ack = 1;
                        }
                }
-               if (!test_bit(IPIPE_PASS_FLAG, &next_domain->irqs[irq].control))
+               if (!test_bit(IPIPE_PASS_FLAG, &idesc->control))
                        break;
                pos = next_domain->p_link.next;
        }
@@ -159,11 +164,6 @@ out:
                __clear_bit(IPIPE_STALL_FLAG, &p->status);
 }
 
-int __ipipe_check_root(void)
-{
-       return ipipe_root_domain_p;
-}
-
 void __ipipe_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq)
 {
        struct irq_desc *desc = irq_to_desc(irq);
@@ -186,30 +186,6 @@ void __ipipe_disable_irqdesc(struct ipipe_domain *ipd, unsigned irq)
 }
 EXPORT_SYMBOL(__ipipe_disable_irqdesc);
 
-void __ipipe_stall_root_raw(void)
-{
-       /*
-        * This code is called by the ins{bwl} routines (see
-        * arch/blackfin/lib/ins.S), which are heavily used by the
-        * network stack. It masks all interrupts but those handled by
-        * non-root domains, so that we keep decent network transfer
-        * rates for Linux without inducing pathological jitter for
-        * the real-time domain.
-        */
-       __asm__ __volatile__ ("sti %0;" : : "d"(__ipipe_irq_lvmask));
-
-       __set_bit(IPIPE_STALL_FLAG,
-                 &ipipe_root_cpudom_var(status));
-}
-
-void __ipipe_unstall_root_raw(void)
-{
-       __clear_bit(IPIPE_STALL_FLAG,
-                   &ipipe_root_cpudom_var(status));
-
-       __asm__ __volatile__ ("sti %0;" : : "d"(bfin_irq_flags));
-}
-
 int __ipipe_syscall_root(struct pt_regs *regs)
 {
        struct ipipe_percpu_domain_data *p;
@@ -333,12 +309,29 @@ asmlinkage void __ipipe_sync_root(void)
 
 void ___ipipe_sync_pipeline(unsigned long syncmask)
 {
-       if (__ipipe_root_domain_p) {
-               if (test_bit(IPIPE_SYNCDEFER_FLAG, &ipipe_root_cpudom_var(status)))
-                       return;
-       }
+       if (__ipipe_root_domain_p &&
+           test_bit(IPIPE_SYNCDEFER_FLAG, &ipipe_root_cpudom_var(status)))
+               return;
 
        __ipipe_sync_stage(syncmask);
 }
 
-EXPORT_SYMBOL(show_stack);
+void __ipipe_disable_root_irqs_hw(void)
+{
+       /*
+        * This code is called by the ins{bwl} routines (see
+        * arch/blackfin/lib/ins.S), which are heavily used by the
+        * network stack. It masks all interrupts but those handled by
+        * non-root domains, so that we keep decent network transfer
+        * rates for Linux without inducing pathological jitter for
+        * the real-time domain.
+        */
+       bfin_sti(__ipipe_irq_lvmask);
+       __set_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status));
+}
+
+void __ipipe_enable_root_irqs_hw(void)
+{
+       __clear_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status));
+       bfin_sti(bfin_irq_flags);
+}
index dbcf3e45cb0baefef5136967e33744fef40b64fb..59fc42dc5d6a2e49f5014cbcada34fde53abed7f 100644 (file)
@@ -54,7 +54,7 @@ void kgdb_l2_test(void)
 
 int kgdb_test(char *name, int len, int count, int z)
 {
-       printk(KERN_DEBUG "kgdb name(%d): %s, %d, %d\n", len, name, count, z);
+       printk(KERN_ALERT "kgdb name(%d): %s, %d, %d\n", len, name, count, z);
        count = z;
        return count;
 }
index d5aee362668838f11d2f924ed47b05e34e4bb835..67fc7a56c865211cef10d339f0dc4fecac696336 100644 (file)
@@ -27,6 +27,7 @@
  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#define pr_fmt(fmt) "module %s: " fmt
 
 #include <linux/moduleloader.h>
 #include <linux/elf.h>
@@ -36,6 +37,7 @@
 #include <linux/kernel.h>
 #include <asm/dma.h>
 #include <asm/cacheflush.h>
+#include <asm/uaccess.h>
 
 void *module_alloc(unsigned long size)
 {
@@ -52,7 +54,7 @@ void module_free(struct module *mod, void *module_region)
 
 /* Transfer the section to the L1 memory */
 int
-module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
+module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
                          char *secstrings, struct module *mod)
 {
        /*
@@ -63,126 +65,119 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
         * NOTE: this breaks the semantic of mod->arch structure.
         */
        Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum;
-       void *dest = NULL;
+       void *dest;
 
        for (s = sechdrs; s < sechdrs_end; ++s) {
-               if ((strcmp(".l1.text", secstrings + s->sh_name) == 0) ||
-                   ((strcmp(".text", secstrings + s->sh_name) == 0) &&
-                    (hdr->e_flags & EF_BFIN_CODE_IN_L1) && (s->sh_size > 0))) {
+               const char *shname = secstrings + s->sh_name;
+
+               if (s->sh_size == 0)
+                       continue;
+
+               if (!strcmp(".l1.text", shname) ||
+                   (!strcmp(".text", shname) &&
+                    (hdr->e_flags & EF_BFIN_CODE_IN_L1))) {
+
                        dest = l1_inst_sram_alloc(s->sh_size);
                        mod->arch.text_l1 = dest;
                        if (dest == NULL) {
-                               printk(KERN_ERR
-                                      "module %s: L1 instruction memory allocation failed\n",
-                                      mod->name);
+                               pr_err("L1 inst memory allocation failed\n",
+                                       mod->name);
                                return -1;
                        }
                        dma_memcpy(dest, (void *)s->sh_addr, s->sh_size);
-                       s->sh_flags &= ~SHF_ALLOC;
-                       s->sh_addr = (unsigned long)dest;
-               }
-               if ((strcmp(".l1.data", secstrings + s->sh_name) == 0) ||
-                   ((strcmp(".data", secstrings + s->sh_name) == 0) &&
-                    (hdr->e_flags & EF_BFIN_DATA_IN_L1) && (s->sh_size > 0))) {
+
+               } else if (!strcmp(".l1.data", shname) ||
+                          (!strcmp(".data", shname) &&
+                           (hdr->e_flags & EF_BFIN_DATA_IN_L1))) {
+
                        dest = l1_data_sram_alloc(s->sh_size);
                        mod->arch.data_a_l1 = dest;
                        if (dest == NULL) {
-                               printk(KERN_ERR
-                                       "module %s: L1 data memory allocation failed\n",
+                               pr_err("L1 data memory allocation failed\n",
                                        mod->name);
                                return -1;
                        }
                        memcpy(dest, (void *)s->sh_addr, s->sh_size);
-                       s->sh_flags &= ~SHF_ALLOC;
-                       s->sh_addr = (unsigned long)dest;
-               }
-               if (strcmp(".l1.bss", secstrings + s->sh_name) == 0 ||
-                   ((strcmp(".bss", secstrings + s->sh_name) == 0) &&
-                    (hdr->e_flags & EF_BFIN_DATA_IN_L1) && (s->sh_size > 0))) {
-                       dest = l1_data_sram_alloc(s->sh_size);
+
+               } else if (!strcmp(".l1.bss", shname) ||
+                          (!strcmp(".bss", shname) &&
+                           (hdr->e_flags & EF_BFIN_DATA_IN_L1))) {
+
+                       dest = l1_data_sram_zalloc(s->sh_size);
                        mod->arch.bss_a_l1 = dest;
                        if (dest == NULL) {
-                               printk(KERN_ERR
-                                       "module %s: L1 data memory allocation failed\n",
+                               pr_err("L1 data memory allocation failed\n",
                                        mod->name);
                                return -1;
                        }
-                       memset(dest, 0, s->sh_size);
-                       s->sh_flags &= ~SHF_ALLOC;
-                       s->sh_addr = (unsigned long)dest;
-               }
-               if (strcmp(".l1.data.B", secstrings + s->sh_name) == 0) {
+
+               } else if (!strcmp(".l1.data.B", shname)) {
+
                        dest = l1_data_B_sram_alloc(s->sh_size);
                        mod->arch.data_b_l1 = dest;
                        if (dest == NULL) {
-                               printk(KERN_ERR
-                                       "module %s: L1 data memory allocation failed\n",
+                               pr_err("L1 data memory allocation failed\n",
                                        mod->name);
                                return -1;
                        }
                        memcpy(dest, (void *)s->sh_addr, s->sh_size);
-                       s->sh_flags &= ~SHF_ALLOC;
-                       s->sh_addr = (unsigned long)dest;
-               }
-               if (strcmp(".l1.bss.B", secstrings + s->sh_name) == 0) {
+
+               } else if (!strcmp(".l1.bss.B", shname)) {
+
                        dest = l1_data_B_sram_alloc(s->sh_size);
                        mod->arch.bss_b_l1 = dest;
                        if (dest == NULL) {
-                               printk(KERN_ERR
-                                       "module %s: L1 data memory allocation failed\n",
+                               pr_err("L1 data memory allocation failed\n",
                                        mod->name);
                                return -1;
                        }
                        memset(dest, 0, s->sh_size);
-                       s->sh_flags &= ~SHF_ALLOC;
-                       s->sh_addr = (unsigned long)dest;
-               }
-               if ((strcmp(".l2.text", secstrings + s->sh_name) == 0) ||
-                   ((strcmp(".text", secstrings + s->sh_name) == 0) &&
-                    (hdr->e_flags & EF_BFIN_CODE_IN_L2) && (s->sh_size > 0))) {
+
+               } else if (!strcmp(".l2.text", shname) ||
+                          (!strcmp(".text", shname) &&
+                           (hdr->e_flags & EF_BFIN_CODE_IN_L2))) {
+
                        dest = l2_sram_alloc(s->sh_size);
                        mod->arch.text_l2 = dest;
                        if (dest == NULL) {
-                               printk(KERN_ERR
-                                      "module %s: L2 SRAM allocation failed\n",
-                                      mod->name);
+                               pr_err("L2 SRAM allocation failed\n",
+                                       mod->name);
                                return -1;
                        }
                        memcpy(dest, (void *)s->sh_addr, s->sh_size);
-                       s->sh_flags &= ~SHF_ALLOC;
-                       s->sh_addr = (unsigned long)dest;
-               }
-               if ((strcmp(".l2.data", secstrings + s->sh_name) == 0) ||
-                   ((strcmp(".data", secstrings + s->sh_name) == 0) &&
-                    (hdr->e_flags & EF_BFIN_DATA_IN_L2) && (s->sh_size > 0))) {
+
+               } else if (!strcmp(".l2.data", shname) ||
+                          (!strcmp(".data", shname) &&
+                           (hdr->e_flags & EF_BFIN_DATA_IN_L2))) {
+
                        dest = l2_sram_alloc(s->sh_size);
                        mod->arch.data_l2 = dest;
                        if (dest == NULL) {
-                               printk(KERN_ERR
-                                       "module %s: L2 SRAM allocation failed\n",
+                               pr_err("L2 SRAM allocation failed\n",
                                        mod->name);
                                return -1;
                        }
                        memcpy(dest, (void *)s->sh_addr, s->sh_size);
-                       s->sh_flags &= ~SHF_ALLOC;
-                       s->sh_addr = (unsigned long)dest;
-               }
-               if (strcmp(".l2.bss", secstrings + s->sh_name) == 0 ||
-                   ((strcmp(".bss", secstrings + s->sh_name) == 0) &&
-                    (hdr->e_flags & EF_BFIN_DATA_IN_L2) && (s->sh_size > 0))) {
-                       dest = l2_sram_alloc(s->sh_size);
+
+               } else if (!strcmp(".l2.bss", shname) ||
+                          (!strcmp(".bss", shname) &&
+                           (hdr->e_flags & EF_BFIN_DATA_IN_L2))) {
+
+                       dest = l2_sram_zalloc(s->sh_size);
                        mod->arch.bss_l2 = dest;
                        if (dest == NULL) {
-                               printk(KERN_ERR
-                                       "module %s: L2 SRAM allocation failed\n",
+                               pr_err("L2 SRAM allocation failed\n",
                                        mod->name);
                                return -1;
                        }
-                       memset(dest, 0, s->sh_size);
-                       s->sh_flags &= ~SHF_ALLOC;
-                       s->sh_addr = (unsigned long)dest;
-               }
+
+               } else
+                       continue;
+
+               s->sh_flags &= ~SHF_ALLOC;
+               s->sh_addr = (unsigned long)dest;
        }
+
        return 0;
 }
 
@@ -190,7 +185,7 @@ int
 apply_relocate(Elf_Shdr * sechdrs, const char *strtab,
               unsigned int symindex, unsigned int relsec, struct module *me)
 {
-       printk(KERN_ERR "module %s: .rel unsupported\n", me->name);
+       pr_err(".rel unsupported\n", me->name);
        return -ENOEXEC;
 }
 
@@ -205,109 +200,86 @@ apply_relocate(Elf_Shdr * sechdrs, const char *strtab,
 /*            gas does not generate it.                                  */
 /*************************************************************************/
 int
-apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab,
+apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
                   unsigned int symindex, unsigned int relsec,
                   struct module *mod)
 {
        unsigned int i;
-       unsigned short tmp;
        Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
        Elf32_Sym *sym;
-       uint32_t *location32;
-       uint16_t *location16;
-       uint32_t value;
+       unsigned long location, value, size;
+
+       pr_debug("applying relocate section %u to %u\n", mod->name,
+               relsec, sechdrs[relsec].sh_info);
 
-       pr_debug("Applying relocate section %u to %u\n", relsec,
-              sechdrs[relsec].sh_info);
        for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
                /* This is where to make the change */
-               location16 =
-                   (uint16_t *) (sechdrs[sechdrs[relsec].sh_info].sh_addr +
-                                 rel[i].r_offset);
-               location32 = (uint32_t *) location16;
+               location = sechdrs[sechdrs[relsec].sh_info].sh_addr +
+                          rel[i].r_offset;
+
                /* This is the symbol it is referring to. Note that all
                   undefined symbols have been resolved. */
                sym = (Elf32_Sym *) sechdrs[symindex].sh_addr
                    + ELF32_R_SYM(rel[i].r_info);
                value = sym->st_value;
                value += rel[i].r_addend;
-               pr_debug("location is %x, value is %x type is %d \n",
-                        (unsigned int) location32, value,
-                        ELF32_R_TYPE(rel[i].r_info));
+
 #ifdef CONFIG_SMP
-               if ((unsigned long)location16 >= COREB_L1_DATA_A_START) {
-                       printk(KERN_ERR "module %s: cannot relocate in L1: %u (SMP kernel)",
-                                      mod->name, ELF32_R_TYPE(rel[i].r_info));
+               if (location >= COREB_L1_DATA_A_START) {
+                       pr_err("cannot relocate in L1: %u (SMP kernel)",
+                               mod->name, ELF32_R_TYPE(rel[i].r_info));
                        return -ENOEXEC;
                }
 #endif
+
+               pr_debug("location is %lx, value is %lx type is %d\n",
+                       mod->name, location, value, ELF32_R_TYPE(rel[i].r_info));
+
                switch (ELF32_R_TYPE(rel[i].r_info)) {
 
+               case R_BFIN_HUIMM16:
+                       value >>= 16;
+               case R_BFIN_LUIMM16:
+               case R_BFIN_RIMM16:
+                       size = 2;
+                       break;
+               case R_BFIN_BYTE4_DATA:
+                       size = 4;
+                       break;
+
                case R_BFIN_PCREL24:
                case R_BFIN_PCREL24_JUMP_L:
-                       /* Add the value, subtract its postition */
-                       location16 =
-                           (uint16_t *) (sechdrs[sechdrs[relsec].sh_info].
-                                         sh_addr + rel[i].r_offset - 2);
-                       location32 = (uint32_t *) location16;
-                       value -= (uint32_t) location32;
-                       value >>= 1;
-                       if ((value & 0xFF000000) != 0 &&
-                           (value & 0xFF000000) != 0xFF000000) {
-                               printk(KERN_ERR "module %s: relocation overflow\n",
-                                      mod->name);
-                               return -ENOEXEC;
-                       }
-                       pr_debug("value is %x, before %x-%x after %x-%x\n", value,
-                              *location16, *(location16 + 1),
-                              (*location16 & 0xff00) | (value >> 16 & 0x00ff),
-                              value & 0xffff);
-                       *location16 =
-                           (*location16 & 0xff00) | (value >> 16 & 0x00ff);
-                       *(location16 + 1) = value & 0xffff;
-                       break;
                case R_BFIN_PCREL12_JUMP:
                case R_BFIN_PCREL12_JUMP_S:
-                       value -= (uint32_t) location32;
-                       value >>= 1;
-                       *location16 = (value & 0xfff);
-                       break;
                case R_BFIN_PCREL10:
-                       value -= (uint32_t) location32;
-                       value >>= 1;
-                       *location16 = (value & 0x3ff);
-                       break;
-               case R_BFIN_LUIMM16:
-                       pr_debug("before %x after %x\n", *location16,
-                                      (value & 0xffff));
-                       tmp = (value & 0xffff);
-                       if ((unsigned long)location16 >= L1_CODE_START) {
-                               dma_memcpy(location16, &tmp, 2);
-                       } else
-                               *location16 = tmp;
-                       break;
-               case R_BFIN_HUIMM16:
-                       pr_debug("before %x after %x\n", *location16,
-                                      ((value >> 16) & 0xffff));
-                       tmp = ((value >> 16) & 0xffff);
-                       if ((unsigned long)location16 >= L1_CODE_START) {
-                               dma_memcpy(location16, &tmp, 2);
-                       } else
-                               *location16 = tmp;
+                       pr_err("unsupported relocation: %u (no -mlong-calls?)\n",
+                               mod->name, ELF32_R_TYPE(rel[i].r_info));
+                       return -ENOEXEC;
+
+               default:
+                       pr_err("unknown relocation: %u\n", mod->name,
+                               ELF32_R_TYPE(rel[i].r_info));
+                       return -ENOEXEC;
+               }
+
+               switch (bfin_mem_access_type(location, size)) {
+               case BFIN_MEM_ACCESS_CORE:
+               case BFIN_MEM_ACCESS_CORE_ONLY:
+                       memcpy((void *)location, &value, size);
                        break;
-               case R_BFIN_RIMM16:
-                       *location16 = (value & 0xffff);
+               case BFIN_MEM_ACCESS_DMA:
+                       dma_memcpy((void *)location, &value, size);
                        break;
-               case R_BFIN_BYTE4_DATA:
-                       pr_debug("before %x after %x\n", *location32, value);
-                       *location32 = value;
+               case BFIN_MEM_ACCESS_ITEST:
+                       isram_memcpy((void *)location, &value, size);
                        break;
                default:
-                       printk(KERN_ERR "module %s: Unknown relocation: %u\n",
-                              mod->name, ELF32_R_TYPE(rel[i].r_info));
+                       pr_err("invalid relocation for %#lx\n",
+                               mod->name, location);
                        return -ENOEXEC;
                }
        }
+
        return 0;
 }
 
@@ -332,22 +304,28 @@ module_finalize(const Elf_Ehdr * hdr,
        for (i = 1; i < hdr->e_shnum; i++) {
                const char *strtab = (char *)sechdrs[strindex].sh_addr;
                unsigned int info = sechdrs[i].sh_info;
+               const char *shname = secstrings + sechdrs[i].sh_name;
 
                /* Not a valid relocation section? */
                if (info >= hdr->e_shnum)
                        continue;
 
-               if ((sechdrs[i].sh_type == SHT_RELA) &&
-                   ((strcmp(".rela.l2.text", secstrings + sechdrs[i].sh_name) == 0) ||
-                   (strcmp(".rela.l1.text", secstrings + sechdrs[i].sh_name) == 0) ||
-                   ((strcmp(".rela.text", secstrings + sechdrs[i].sh_name) == 0) &&
-                       (hdr->e_flags & (EF_BFIN_CODE_IN_L1|EF_BFIN_CODE_IN_L2))))) {
+               /* Only support RELA relocation types */
+               if (sechdrs[i].sh_type != SHT_RELA)
+                       continue;
+
+               if (!strcmp(".rela.l2.text", shname) ||
+                   !strcmp(".rela.l1.text", shname) ||
+                   (!strcmp(".rela.text", shname) &&
+                        (hdr->e_flags & (EF_BFIN_CODE_IN_L1 | EF_BFIN_CODE_IN_L2)))) {
+
                        err = apply_relocate_add((Elf_Shdr *) sechdrs, strtab,
                                           symindex, i, mod);
                        if (err < 0)
                                return -ENOEXEC;
                }
        }
+
        return 0;
 }
 
index 9da36bab7ccb10194a3cde2c40628f4e52aeeccb..f5b286189647ff0f3fcd68ab1abe0d7e79fdc52c 100644 (file)
@@ -282,25 +282,19 @@ void finish_atomic_sections (struct pt_regs *regs)
 {
        int __user *up0 = (int __user *)regs->p0;
 
-       if (regs->pc < ATOMIC_SEQS_START || regs->pc >= ATOMIC_SEQS_END)
-               return;
-
        switch (regs->pc) {
        case ATOMIC_XCHG32 + 2:
                put_user(regs->r1, up0);
-               regs->pc += 2;
+               regs->pc = ATOMIC_XCHG32 + 4;
                break;
 
        case ATOMIC_CAS32 + 2:
        case ATOMIC_CAS32 + 4:
                if (regs->r0 == regs->r1)
+       case ATOMIC_CAS32 + 6:
                        put_user(regs->r2, up0);
                regs->pc = ATOMIC_CAS32 + 8;
                break;
-       case ATOMIC_CAS32 + 6:
-               put_user(regs->r2, up0);
-               regs->pc += 2;
-               break;
 
        case ATOMIC_ADD32 + 2:
                regs->r0 = regs->r1 + regs->r0;
index 6a387eec6b65e5baa3bcfb247e037748bea6f587..30f4828277ad8782ab8a909c7d98e5f6770bdfb4 100644 (file)
@@ -206,6 +206,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
        int ret;
        unsigned long __user *datap = (unsigned long __user *)data;
+       void *paddr = (void *)addr;
 
        switch (request) {
                /* when I and D space are separate, these will need to be fixed. */
@@ -215,42 +216,49 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
        case PTRACE_PEEKTEXT:   /* read word at location addr. */
                {
                        unsigned long tmp = 0;
-                       int copied;
+                       int copied = 0, to_copy = sizeof(tmp);
 
                        ret = -EIO;
-                       pr_debug("ptrace: PEEKTEXT at addr 0x%08lx + %ld\n", addr, sizeof(data));
-                       if (is_user_addr_valid(child, addr, sizeof(tmp)) < 0)
+                       pr_debug("ptrace: PEEKTEXT at addr 0x%08lx + %i\n", addr, to_copy);
+                       if (is_user_addr_valid(child, addr, to_copy) < 0)
                                break;
                        pr_debug("ptrace: user address is valid\n");
 
-                       if (L1_CODE_LENGTH != 0 && addr >= get_l1_code_start()
-                           && addr + sizeof(tmp) <= get_l1_code_start() + L1_CODE_LENGTH) {
-                               safe_dma_memcpy (&tmp, (const void *)(addr), sizeof(tmp));
-                               copied = sizeof(tmp);
-
-                       } else if (L1_DATA_A_LENGTH != 0 && addr >= L1_DATA_A_START
-                           && addr + sizeof(tmp) <= L1_DATA_A_START + L1_DATA_A_LENGTH) {
-                               memcpy(&tmp, (const void *)(addr), sizeof(tmp));
-                               copied = sizeof(tmp);
-
-                       } else if (L1_DATA_B_LENGTH != 0 && addr >= L1_DATA_B_START
-                           && addr + sizeof(tmp) <= L1_DATA_B_START + L1_DATA_B_LENGTH) {
-                               memcpy(&tmp, (const void *)(addr), sizeof(tmp));
-                               copied = sizeof(tmp);
-
-                       } else if (addr >= FIXED_CODE_START
-                           && addr + sizeof(tmp) <= FIXED_CODE_END) {
-                               copy_from_user_page(0, 0, 0, &tmp, (const void *)(addr), sizeof(tmp));
-                               copied = sizeof(tmp);
-
-                       } else
+                       switch (bfin_mem_access_type(addr, to_copy)) {
+                       case BFIN_MEM_ACCESS_CORE:
+                       case BFIN_MEM_ACCESS_CORE_ONLY:
                                copied = access_process_vm(child, addr, &tmp,
-                                                          sizeof(tmp), 0);
+                                                          to_copy, 0);
+                               if (copied)
+                                       break;
+
+                               /* hrm, why didn't that work ... maybe no mapping */
+                               if (addr >= FIXED_CODE_START &&
+                                   addr + to_copy <= FIXED_CODE_END) {
+                                       copy_from_user_page(0, 0, 0, &tmp, paddr, to_copy);
+                                       copied = to_copy;
+                               } else if (addr >= BOOT_ROM_START) {
+                                       memcpy(&tmp, paddr, to_copy);
+                                       copied = to_copy;
+                               }
 
-                       pr_debug("ptrace: copied size %d [0x%08lx]\n", copied, tmp);
-                       if (copied != sizeof(tmp))
                                break;
-                       ret = put_user(tmp, datap);
+                       case BFIN_MEM_ACCESS_DMA:
+                               if (safe_dma_memcpy(&tmp, paddr, to_copy))
+                                       copied = to_copy;
+                               break;
+                       case BFIN_MEM_ACCESS_ITEST:
+                               if (isram_memcpy(&tmp, paddr, to_copy))
+                                       copied = to_copy;
+                               break;
+                       default:
+                               copied = 0;
+                               break;
+                       }
+
+                       pr_debug("ptrace: copied size %d [0x%08lx]\n", copied, tmp);
+                       if (copied == to_copy)
+                               ret = put_user(tmp, datap);
                        break;
                }
 
@@ -277,9 +285,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                                tmp = child->mm->start_data;
 #ifdef CONFIG_BINFMT_ELF_FDPIC
                        } else if (addr == (sizeof(struct pt_regs) + 12)) {
-                               tmp = child->mm->context.exec_fdpic_loadmap;
+                               goto case_PTRACE_GETFDPIC_EXEC;
                        } else if (addr == (sizeof(struct pt_regs) + 16)) {
-                               tmp = child->mm->context.interp_fdpic_loadmap;
+                               goto case_PTRACE_GETFDPIC_INTERP;
 #endif
                        } else {
                                tmp = get_reg(child, addr);
@@ -288,49 +296,78 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                        break;
                }
 
+#ifdef CONFIG_BINFMT_ELF_FDPIC
+       case PTRACE_GETFDPIC: {
+               unsigned long tmp = 0;
+
+               switch (addr) {
+               case_PTRACE_GETFDPIC_EXEC:
+               case PTRACE_GETFDPIC_EXEC:
+                       tmp = child->mm->context.exec_fdpic_loadmap;
+                       break;
+               case_PTRACE_GETFDPIC_INTERP:
+               case PTRACE_GETFDPIC_INTERP:
+                       tmp = child->mm->context.interp_fdpic_loadmap;
+                       break;
+               default:
+                       break;
+               }
+
+               ret = put_user(tmp, datap);
+               break;
+       }
+#endif
+
                /* when I and D space are separate, this will have to be fixed. */
        case PTRACE_POKEDATA:
                pr_debug("ptrace: PTRACE_PEEKDATA\n");
                /* fall through */
        case PTRACE_POKETEXT:   /* write the word at location addr. */
                {
-                       int copied;
+                       int copied = 0, to_copy = sizeof(data);
 
                        ret = -EIO;
-                       pr_debug("ptrace: POKETEXT at addr 0x%08lx + %ld bytes %lx\n",
-                                addr, sizeof(data), data);
-                       if (is_user_addr_valid(child, addr, sizeof(data)) < 0)
+                       pr_debug("ptrace: POKETEXT at addr 0x%08lx + %i bytes %lx\n",
+                                addr, to_copy, data);
+                       if (is_user_addr_valid(child, addr, to_copy) < 0)
                                break;
                        pr_debug("ptrace: user address is valid\n");
 
-                       if (L1_CODE_LENGTH != 0 && addr >= get_l1_code_start()
-                           && addr + sizeof(data) <= get_l1_code_start() + L1_CODE_LENGTH) {
-                               safe_dma_memcpy ((void *)(addr), &data, sizeof(data));
-                               copied = sizeof(data);
-
-                       } else if (L1_DATA_A_LENGTH != 0 && addr >= L1_DATA_A_START
-                           && addr + sizeof(data) <= L1_DATA_A_START + L1_DATA_A_LENGTH) {
-                               memcpy((void *)(addr), &data, sizeof(data));
-                               copied = sizeof(data);
-
-                       } else if (L1_DATA_B_LENGTH != 0 && addr >= L1_DATA_B_START
-                           && addr + sizeof(data) <= L1_DATA_B_START + L1_DATA_B_LENGTH) {
-                               memcpy((void *)(addr), &data, sizeof(data));
-                               copied = sizeof(data);
-
-                       } else if (addr >= FIXED_CODE_START
-                           && addr + sizeof(data) <= FIXED_CODE_END) {
-                               copy_to_user_page(0, 0, 0, (void *)(addr), &data, sizeof(data));
-                               copied = sizeof(data);
-
-                       } else
+                       switch (bfin_mem_access_type(addr, to_copy)) {
+                       case BFIN_MEM_ACCESS_CORE:
+                       case BFIN_MEM_ACCESS_CORE_ONLY:
                                copied = access_process_vm(child, addr, &data,
-                                                          sizeof(data), 1);
+                                                          to_copy, 0);
+                               if (copied)
+                                       break;
+
+                               /* hrm, why didn't that work ... maybe no mapping */
+                               if (addr >= FIXED_CODE_START &&
+                                   addr + to_copy <= FIXED_CODE_END) {
+                                       copy_to_user_page(0, 0, 0, paddr, &data, to_copy);
+                                       copied = to_copy;
+                               } else if (addr >= BOOT_ROM_START) {
+                                       memcpy(paddr, &data, to_copy);
+                                       copied = to_copy;
+                               }
 
-                       pr_debug("ptrace: copied size %d\n", copied);
-                       if (copied != sizeof(data))
                                break;
-                       ret = 0;
+                       case BFIN_MEM_ACCESS_DMA:
+                               if (safe_dma_memcpy(paddr, &data, to_copy))
+                                       copied = to_copy;
+                               break;
+                       case BFIN_MEM_ACCESS_ITEST:
+                               if (isram_memcpy(paddr, &data, to_copy))
+                                       copied = to_copy;
+                               break;
+                       default:
+                               copied = 0;
+                               break;
+                       }
+
+                       pr_debug("ptrace: copied size %d\n", copied);
+                       if (copied == to_copy)
+                               ret = 0;
                        break;
                }
 
index 6225edae488edeb713db588487fe709d839572eb..369535b61ed1a3fc9bf844aab7d53fe2242ae0c8 100644 (file)
@@ -112,7 +112,7 @@ void __cpuinit bfin_setup_caches(unsigned int cpu)
        /*
         * In cache coherence emulation mode, we need to have the
         * D-cache enabled before running any atomic operation which
-        * might invove cache invalidation (i.e. spinlock, rwlock).
+        * might involve cache invalidation (i.e. spinlock, rwlock).
         * So printk's are deferred until then.
         */
 #ifdef CONFIG_BFIN_ICACHE
@@ -187,6 +187,8 @@ void __init bfin_relocate_l1_mem(void)
        unsigned long l1_data_b_length;
        unsigned long l2_length;
 
+       early_shadow_stamp();
+
        /*
         * due to the ALIGN(4) in the arch/blackfin/kernel/vmlinux.lds.S
         * we know that everything about l1 text/data is nice and aligned,
@@ -511,6 +513,7 @@ static __init void memory_setup(void)
 #ifdef CONFIG_MTD_UCLINUX
        unsigned long mtd_phys = 0;
 #endif
+       unsigned long max_mem;
 
        _rambase = (unsigned long)_stext;
        _ramstart = (unsigned long)_end;
@@ -520,7 +523,22 @@ static __init void memory_setup(void)
                panic("DMA region exceeds memory limit: %lu.",
                        _ramend - _ramstart);
        }
-       memory_end = _ramend - DMA_UNCACHED_REGION;
+       max_mem = memory_end = _ramend - DMA_UNCACHED_REGION;
+
+#if (defined(CONFIG_BFIN_EXTMEM_ICACHEABLE) && ANOMALY_05000263)
+       /* Due to a Hardware Anomaly we need to limit the size of usable
+        * instruction memory to max 60MB, 56 if HUNT_FOR_ZERO is on
+        * 05000263 - Hardware loop corrupted when taking an ICPLB exception
+        */
+# if (defined(CONFIG_DEBUG_HUNT_FOR_ZERO))
+       if (max_mem >= 56 * 1024 * 1024)
+               max_mem = 56 * 1024 * 1024;
+# else
+       if (max_mem >= 60 * 1024 * 1024)
+               max_mem = 60 * 1024 * 1024;
+# endif                                /* CONFIG_DEBUG_HUNT_FOR_ZERO */
+#endif                         /* ANOMALY_05000263 */
+
 
 #ifdef CONFIG_MPU
        /* Round up to multiple of 4MB */
@@ -549,22 +567,16 @@ static __init void memory_setup(void)
 
 # if defined(CONFIG_ROMFS_FS)
        if (((unsigned long *)mtd_phys)[0] == ROMSB_WORD0
-           && ((unsigned long *)mtd_phys)[1] == ROMSB_WORD1)
+           && ((unsigned long *)mtd_phys)[1] == ROMSB_WORD1) {
                mtd_size =
                    PAGE_ALIGN(be32_to_cpu(((unsigned long *)mtd_phys)[2]));
-#  if (defined(CONFIG_BFIN_EXTMEM_ICACHEABLE) && ANOMALY_05000263)
-       /* Due to a Hardware Anomaly we need to limit the size of usable
-        * instruction memory to max 60MB, 56 if HUNT_FOR_ZERO is on
-        * 05000263 - Hardware loop corrupted when taking an ICPLB exception
-        */
-#   if (defined(CONFIG_DEBUG_HUNT_FOR_ZERO))
-       if (memory_end >= 56 * 1024 * 1024)
-               memory_end = 56 * 1024 * 1024;
-#   else
-       if (memory_end >= 60 * 1024 * 1024)
-               memory_end = 60 * 1024 * 1024;
-#   endif                              /* CONFIG_DEBUG_HUNT_FOR_ZERO */
-#  endif                               /* ANOMALY_05000263 */
+
+               /* ROM_FS is XIP, so if we found it, we need to limit memory */
+               if (memory_end > max_mem) {
+                       pr_info("Limiting kernel memory to %liMB due to anomaly 05000263\n", max_mem >> 20);
+                       memory_end = max_mem;
+               }
+       }
 # endif                                /* CONFIG_ROMFS_FS */
 
        /* Since the default MTD_UCLINUX has no magic number, we just blindly
@@ -586,20 +598,14 @@ static __init void memory_setup(void)
        }
 #endif                         /* CONFIG_MTD_UCLINUX */
 
-#if (defined(CONFIG_BFIN_EXTMEM_ICACHEABLE) && ANOMALY_05000263)
-       /* Due to a Hardware Anomaly we need to limit the size of usable
-        * instruction memory to max 60MB, 56 if HUNT_FOR_ZERO is on
-        * 05000263 - Hardware loop corrupted when taking an ICPLB exception
+       /* We need lo limit memory, since everything could have a text section
+        * of userspace in it, and expose anomaly 05000263. If the anomaly
+        * doesn't exist, or we don't need to - then dont.
         */
-#if (defined(CONFIG_DEBUG_HUNT_FOR_ZERO))
-       if (memory_end >= 56 * 1024 * 1024)
-               memory_end = 56 * 1024 * 1024;
-#else
-       if (memory_end >= 60 * 1024 * 1024)
-               memory_end = 60 * 1024 * 1024;
-#endif                         /* CONFIG_DEBUG_HUNT_FOR_ZERO */
-       printk(KERN_NOTICE "Warning: limiting memory to %liMB due to hardware anomaly 05000263\n", memory_end >> 20);
-#endif                         /* ANOMALY_05000263 */
+       if (memory_end > max_mem) {
+               pr_info("Limiting kernel memory to %liMB due to anomaly 05000263\n", max_mem >> 20);
+               memory_end = max_mem;
+       }
 
 #ifdef CONFIG_MPU
        page_mask_nelts = ((_ramend >> PAGE_SHIFT) + 31) / 32;
@@ -693,7 +699,7 @@ static __init void setup_bootmem_allocator(void)
        sanitize_memmap(bfin_memmap.map, &bfin_memmap.nr_map);
        print_memory_map("boot memmap");
 
-       /* intialize globals in linux/bootmem.h */
+       /* initialize globals in linux/bootmem.h */
        find_min_max_pfn();
        /* pfn of the last usable page frame */
        if (max_pfn > memory_end >> PAGE_SHIFT)
@@ -806,6 +812,8 @@ void __init setup_arch(char **cmdline_p)
 {
        unsigned long sclk, cclk;
 
+       enable_shadow_console();
+
        /* Check to make sure we are running on the right processor */
        if (unlikely(CPUID != bfin_cpuid()))
                printk(KERN_ERR "ERROR: Not running on ADSP-%s: unknown CPUID 0x%04x Rev 0.%d\n",
@@ -1230,57 +1238,6 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 #ifdef __ARCH_SYNC_CORE_ICACHE
        seq_printf(m, "SMP Icache Flushes\t: %lu\n\n", cpudata->icache_invld_count);
 #endif
-#ifdef CONFIG_BFIN_ICACHE_LOCK
-       switch ((cpudata->imemctl >> 3) & WAYALL_L) {
-       case WAY0_L:
-               seq_printf(m, "Way0 Locked-Down\n");
-               break;
-       case WAY1_L:
-               seq_printf(m, "Way1 Locked-Down\n");
-               break;
-       case WAY01_L:
-               seq_printf(m, "Way0,Way1 Locked-Down\n");
-               break;
-       case WAY2_L:
-               seq_printf(m, "Way2 Locked-Down\n");
-               break;
-       case WAY02_L:
-               seq_printf(m, "Way0,Way2 Locked-Down\n");
-               break;
-       case WAY12_L:
-               seq_printf(m, "Way1,Way2 Locked-Down\n");
-               break;
-       case WAY012_L:
-               seq_printf(m, "Way0,Way1 & Way2 Locked-Down\n");
-               break;
-       case WAY3_L:
-               seq_printf(m, "Way3 Locked-Down\n");
-               break;
-       case WAY03_L:
-               seq_printf(m, "Way0,Way3 Locked-Down\n");
-               break;
-       case WAY13_L:
-               seq_printf(m, "Way1,Way3 Locked-Down\n");
-               break;
-       case WAY013_L:
-               seq_printf(m, "Way 0,Way1,Way3 Locked-Down\n");
-               break;
-       case WAY32_L:
-               seq_printf(m, "Way3,Way2 Locked-Down\n");
-               break;
-       case WAY320_L:
-               seq_printf(m, "Way3,Way2,Way0 Locked-Down\n");
-               break;
-       case WAY321_L:
-               seq_printf(m, "Way3,Way2,Way1 Locked-Down\n");
-               break;
-       case WAYALL_L:
-               seq_printf(m, "All Ways are locked\n");
-               break;
-       default:
-               seq_printf(m, "No Ways are locked\n");
-       }
-#endif
 
        if (cpu_num != num_possible_cpus() - 1)
                return 0;
@@ -1346,6 +1303,7 @@ const struct seq_operations cpuinfo_op = {
 
 void __init cmdline_init(const char *r0)
 {
+       early_shadow_stamp();
        if (r0)
                strncpy(command_line, r0, COMMAND_LINE_SIZE);
 }
diff --git a/arch/blackfin/kernel/shadow_console.c b/arch/blackfin/kernel/shadow_console.c
new file mode 100644 (file)
index 0000000..8b8c710
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * manage a small early shadow of the log buffer which we can pass between the
+ * bootloader so early crash messages are communicated properly and easily
+ *
+ * Copyright 2009 Analog Devices Inc.
+ *
+ * Enter bugs at http://blackfin.uclinux.org/
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/string.h>
+#include <asm/blackfin.h>
+#include <asm/irq_handler.h>
+#include <asm/early_printk.h>
+
+#define SHADOW_CONSOLE_START           (0x500)
+#define SHADOW_CONSOLE_END             (0x1000)
+#define SHADOW_CONSOLE_MAGIC_LOC       (0x4F0)
+#define SHADOW_CONSOLE_MAGIC           (0xDEADBEEF)
+
+static __initdata char *shadow_console_buffer = (char *)SHADOW_CONSOLE_START;
+
+__init void early_shadow_write(struct console *con, const char *s,
+                               unsigned int n)
+{
+       unsigned int i;
+       /*
+        * save 2 bytes for the double null at the end
+        * once we fail on a long line, make sure we don't write a short line afterwards
+        */
+       if ((shadow_console_buffer + n) <= (char *)(SHADOW_CONSOLE_END - 2)) {
+               /* can't use memcpy - it may not be relocated yet */
+               for (i = 0; i <= n; i++)
+                       shadow_console_buffer[i] = s[i];
+               shadow_console_buffer += n;
+               shadow_console_buffer[0] = 0;
+               shadow_console_buffer[1] = 0;
+       } else
+               shadow_console_buffer = (char *)SHADOW_CONSOLE_END;
+}
+
+static __initdata struct console early_shadow_console = {
+       .name = "early_shadow",
+       .write = early_shadow_write,
+       .flags = CON_BOOT | CON_PRINTBUFFER,
+       .index = -1,
+       .device = 0,
+};
+
+__init int shadow_console_enabled(void)
+{
+       return early_shadow_console.flags & CON_ENABLED;
+}
+
+__init void mark_shadow_error(void)
+{
+       int *loc = (int *)SHADOW_CONSOLE_MAGIC_LOC;
+       loc[0] = SHADOW_CONSOLE_MAGIC;
+       loc[1] = SHADOW_CONSOLE_START;
+}
+
+__init void enable_shadow_console(void)
+{
+       if (!shadow_console_enabled()) {
+               register_console(&early_shadow_console);
+               /* for now, assume things are going to fail */
+               mark_shadow_error();
+       }
+}
+
+static __init int disable_shadow_console(void)
+{
+       /*
+        * by the time pure_initcall runs, the standard console is enabled,
+        * and the early_console is off, so unset the magic numbers
+        * unregistering the console is taken care of in common code (See
+        * ./kernel/printk:disable_boot_consoles() )
+        */
+       int *loc = (int *)SHADOW_CONSOLE_MAGIC_LOC;
+
+       loc[0] = 0;
+
+       return 0;
+}
+pure_initcall(disable_shadow_console);
+
+/*
+ * since we can't use printk, dump numbers (as hex), n = # bits
+ */
+__init void early_shadow_reg(unsigned long reg, unsigned int n)
+{
+       /*
+        * can't use any "normal" kernel features, since thay
+        * may not be relocated to their execute address yet
+        */
+       int i;
+       char ascii[11] = " 0x";
+
+       n = n / 4;
+       reg = reg << ((8 - n) * 4);
+       n += 3;
+
+       for (i = 3; i <= n ; i++) {
+               ascii[i] = hex_asc_lo(reg >> 28);
+               reg <<= 4;
+       }
+       early_shadow_write(NULL, ascii, n);
+
+}
index 0791eba40d9fdc479509682c990099299912f85a..f9715764383ed145d23b2a0caa1bbdd00fdfba58 100644 (file)
@@ -66,7 +66,7 @@ static cycle_t bfin_read_cycles(struct clocksource *cs)
 
 static struct clocksource bfin_cs_cycles = {
        .name           = "bfin_cs_cycles",
-       .rating         = 350,
+       .rating         = 400,
        .read           = bfin_read_cycles,
        .mask           = CLOCKSOURCE_MASK(64),
        .shift          = 22,
@@ -115,7 +115,7 @@ static cycle_t bfin_read_gptimer0(void)
 
 static struct clocksource bfin_cs_gptimer0 = {
        .name           = "bfin_cs_gptimer0",
-       .rating         = 400,
+       .rating         = 350,
        .read           = bfin_read_gptimer0,
        .mask           = CLOCKSOURCE_MASK(32),
        .shift          = 22,
index bf2b2d1f8ae5f35ecd64b68abbbc324f444fa421..56464cb8edf3105e9a105a9e823eb22b3fead290 100644 (file)
@@ -100,7 +100,11 @@ static void decode_address(char *buf, unsigned long address)
        char *modname;
        char *delim = ":";
        char namebuf[128];
+#endif
+
+       buf += sprintf(buf, "<0x%08lx> ", address);
 
+#ifdef CONFIG_KALLSYMS
        /* look up the address and see if we are in kernel space */
        symname = kallsyms_lookup(address, &symsize, &offset, &modname, namebuf);
 
@@ -108,23 +112,33 @@ static void decode_address(char *buf, unsigned long address)
                /* yeah! kernel space! */
                if (!modname)
                        modname = delim = "";
-               sprintf(buf, "<0x%p> { %s%s%s%s + 0x%lx }",
-                             (void *)address, delim, modname, delim, symname,
-                             (unsigned long)offset);
+               sprintf(buf, "{ %s%s%s%s + 0x%lx }",
+                       delim, modname, delim, symname,
+                       (unsigned long)offset);
                return;
-
        }
 #endif
 
-       /* Problem in fixed code section? */
        if (address >= FIXED_CODE_START && address < FIXED_CODE_END) {
-               sprintf(buf, "<0x%p> /* Maybe fixed code section */", (void *)address);
+               /* Problem in fixed code section? */
+               strcat(buf, "/* Maybe fixed code section */");
+               return;
+
+       } else if (address < CONFIG_BOOT_LOAD) {
+               /* Problem somewhere before the kernel start address */
+               strcat(buf, "/* Maybe null pointer? */");
+               return;
+
+       } else if (address >= COREMMR_BASE) {
+               strcat(buf, "/* core mmrs */");
                return;
-       }
 
-       /* Problem somewhere before the kernel start address */
-       if (address < CONFIG_BOOT_LOAD) {
-               sprintf(buf, "<0x%p> /* Maybe null pointer? */", (void *)address);
+       } else if (address >= SYSMMR_BASE) {
+               strcat(buf, "/* system mmrs */");
+               return;
+
+       } else if (address >= L1_ROM_START && address < L1_ROM_START + L1_ROM_LENGTH) {
+               strcat(buf, "/* on-chip L1 ROM */");
                return;
        }
 
@@ -172,18 +186,16 @@ static void decode_address(char *buf, unsigned long address)
                                                offset = (address - vma->vm_start) +
                                                         (vma->vm_pgoff << PAGE_SHIFT);
 
-                                       sprintf(buf, "<0x%p> [ %s + 0x%lx ]",
-                                               (void *)address, name, offset);
+                                       sprintf(buf, "[ %s + 0x%lx ]", name, offset);
                                } else
-                                       sprintf(buf, "<0x%p> [ %s vma:0x%lx-0x%lx]",
-                                               (void *)address, name,
-                                               vma->vm_start, vma->vm_end);
+                                       sprintf(buf, "[ %s vma:0x%lx-0x%lx]",
+                                               name, vma->vm_start, vma->vm_end);
 
                                if (!in_atomic)
                                        mmput(mm);
 
-                               if (!strlen(buf))
-                                       sprintf(buf, "<0x%p> [ %s ] dynamic memory", (void *)address, name);
+                               if (buf[0] == '\0')
+                                       sprintf(buf, "[ %s ] dynamic memory", name);
 
                                goto done;
                        }
@@ -193,7 +205,7 @@ static void decode_address(char *buf, unsigned long address)
        }
 
        /* we were unable to find this address anywhere */
-       sprintf(buf, "<0x%p> /* kernel dynamic memory */", (void *)address);
+       sprintf(buf, "/* kernel dynamic memory */");
 
 done:
        write_unlock_irqrestore(&tasklist_lock, flags);
@@ -215,14 +227,14 @@ asmlinkage void double_fault_c(struct pt_regs *fp)
        printk(KERN_EMERG "Double Fault\n");
 #ifdef CONFIG_DEBUG_DOUBLEFAULT_PRINT
        if (((long)fp->seqstat &  SEQSTAT_EXCAUSE) == VEC_UNCOV) {
-               unsigned int cpu = smp_processor_id();
+               unsigned int cpu = raw_smp_processor_id();
                char buf[150];
-               decode_address(buf, cpu_pda[cpu].retx);
+               decode_address(buf, cpu_pda[cpu].retx_doublefault);
                printk(KERN_EMERG "While handling exception (EXCAUSE = 0x%x) at %s:\n",
-                       (unsigned int)cpu_pda[cpu].seqstat & SEQSTAT_EXCAUSE, buf);
-               decode_address(buf, cpu_pda[cpu].dcplb_fault_addr);
+                       (unsigned int)cpu_pda[cpu].seqstat_doublefault & SEQSTAT_EXCAUSE, buf);
+               decode_address(buf, cpu_pda[cpu].dcplb_doublefault_addr);
                printk(KERN_NOTICE "   DCPLB_FAULT_ADDR: %s\n", buf);
-               decode_address(buf, cpu_pda[cpu].icplb_fault_addr);
+               decode_address(buf, cpu_pda[cpu].icplb_doublefault_addr);
                printk(KERN_NOTICE "   ICPLB_FAULT_ADDR: %s\n", buf);
 
                decode_address(buf, fp->retx);
@@ -245,13 +257,13 @@ static int kernel_mode_regs(struct pt_regs *regs)
        return regs->ipend & 0xffc0;
 }
 
-asmlinkage void trap_c(struct pt_regs *fp)
+asmlinkage notrace void trap_c(struct pt_regs *fp)
 {
 #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
        int j;
 #endif
 #ifdef CONFIG_DEBUG_HUNT_FOR_ZERO
-       unsigned int cpu = smp_processor_id();
+       unsigned int cpu = raw_smp_processor_id();
 #endif
        const char *strerror = NULL;
        int sig = 0;
@@ -267,11 +279,6 @@ asmlinkage void trap_c(struct pt_regs *fp)
         * double faults if the stack has become corrupt
         */
 
-#ifndef CONFIG_KGDB
-       /* IPEND is skipped if KGDB isn't enabled (see entry code) */
-       fp->ipend = bfin_read_IPEND();
-#endif
-
        /* trap_c() will be called for exceptions. During exceptions
         * processing, the pc value should be set with retx value.
         * With this change we can cleanup some code in signal.c- TODO
@@ -404,7 +411,7 @@ asmlinkage void trap_c(struct pt_regs *fp)
        /* 0x23 - Data CPLB protection violation, handled here */
        case VEC_CPLB_VL:
                info.si_code = ILL_CPLB_VI;
-               sig = SIGBUS;
+               sig = SIGSEGV;
                strerror = KERN_NOTICE EXC_0x23(KERN_NOTICE);
                CHK_DEBUGGER_TRAP_MAYBE();
                break;
@@ -904,7 +911,7 @@ void show_stack(struct task_struct *task, unsigned long *stack)
                frame_no = 0;
 
                for (addr = (unsigned int *)((unsigned int)stack & ~0xF), i = 0;
-                    addr <= endstack; addr++, i++) {
+                    addr < endstack; addr++, i++) {
 
                        ret_addr = 0;
                        if (!j && i % 8 == 0)
@@ -949,6 +956,7 @@ void show_stack(struct task_struct *task, unsigned long *stack)
        }
 #endif
 }
+EXPORT_SYMBOL(show_stack);
 
 void dump_stack(void)
 {
@@ -1090,7 +1098,7 @@ void show_regs(struct pt_regs *fp)
        struct irqaction *action;
        unsigned int i;
        unsigned long flags = 0;
-       unsigned int cpu = smp_processor_id();
+       unsigned int cpu = raw_smp_processor_id();
        unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic();
 
        verbose_printk(KERN_NOTICE "\n");
@@ -1116,10 +1124,16 @@ void show_regs(struct pt_regs *fp)
 
        verbose_printk(KERN_NOTICE "%s", linux_banner);
 
-       verbose_printk(KERN_NOTICE "\nSEQUENCER STATUS:\t\t%s\n",
-                      print_tainted());
-       verbose_printk(KERN_NOTICE " SEQSTAT: %08lx  IPEND: %04lx  SYSCFG: %04lx\n",
-                      (long)fp->seqstat, fp->ipend, fp->syscfg);
+       verbose_printk(KERN_NOTICE "\nSEQUENCER STATUS:\t\t%s\n", print_tainted());
+       verbose_printk(KERN_NOTICE " SEQSTAT: %08lx  IPEND: %04lx  IMASK: %04lx  SYSCFG: %04lx\n",
+               (long)fp->seqstat, fp->ipend, cpu_pda[raw_smp_processor_id()].ex_imask, fp->syscfg);
+       if (fp->ipend & EVT_IRPTEN)
+               verbose_printk(KERN_NOTICE "  Global Interrupts Disabled (IPEND[4])\n");
+       if (!(cpu_pda[raw_smp_processor_id()].ex_imask & (EVT_IVG13 | EVT_IVG12 | EVT_IVG11 |
+                       EVT_IVG10 | EVT_IVG9 | EVT_IVG8 | EVT_IVG7 | EVT_IVTMR)))
+               verbose_printk(KERN_NOTICE "  Peripheral interrupts masked off\n");
+       if (!(cpu_pda[raw_smp_processor_id()].ex_imask & (EVT_IVG15 | EVT_IVG14)))
+               verbose_printk(KERN_NOTICE "  Kernel interrupts masked off\n");
        if ((fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) {
                verbose_printk(KERN_NOTICE "  HWERRCAUSE: 0x%lx\n",
                        (fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14);
index d7ffe299b979340de6264310434913ead137c775..21ac7c26079e732040c09c979525bcb51a941897 100644 (file)
@@ -221,7 +221,7 @@ SECTIONS
                . = ALIGN(4);
                __ebss_l1 = .;
        }
-       ASSERT (SIZEOF(.data_a_l1) <= L1_DATA_A_LENGTH, "L1 data A overflow!")
+       ASSERT (SIZEOF(.data_l1) <= L1_DATA_A_LENGTH, "L1 data A overflow!")
 
        .data_b_l1 L1_DATA_B_START : AT(LOADADDR(.data_l1) + SIZEOF(.data_l1))
        {
@@ -262,7 +262,7 @@ SECTIONS
                . = ALIGN(4);
                __ebss_l2 = .;
        }
-       ASSERT (SIZEOF(.text_data_l1) <= L2_LENGTH, "L2 overflow!")
+       ASSERT (SIZEOF(.text_data_l2) <= L2_LENGTH, "L2 overflow!")
 
        /* Force trailing alignment of our init section so that when we
         * free our init memory, we don't leave behind a partial page.
index 1863a6ba507c5426b07d02cacd4b105f676dffe1..3edbd8db6598cacfa6bc6d6a4bf642338d4c613c 100644 (file)
@@ -16,7 +16,7 @@
        [--sp] = rets; \
        [--sp] = (P5:0); \
        sp += -12; \
-       call ___ipipe_stall_root_raw; \
+       call ___ipipe_disable_root_irqs_hw; \
        sp += 12; \
        (P5:0) = [sp++];
 # define CLI_INNER_NOP
@@ -28,7 +28,7 @@
 #ifdef CONFIG_IPIPE
 # define DO_STI \
        sp += -12; \
-       call ___ipipe_unstall_root_raw; \
+       call ___ipipe_enable_root_irqs_hw; \
        sp += 12; \
 2:     rets = [sp++];
 #else
index 809be268e42d4fcdf20ea802bb35bb1d87677559..03e4a9941f019a3abdcbb5aefcaa7e9e1b878fa7 100644 (file)
@@ -199,15 +199,6 @@ static struct bfin5xx_spi_chip mmc_spi_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_PBX)
-static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
-       .ctl_reg        = 0x4, /* send zero */
-       .enable_dma     = 0,
-       .bits_per_word  = 8,
-       .cs_change_per_word = 1,
-};
-#endif
-
 #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
 static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
        .enable_dma = 0,
@@ -296,24 +287,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
                .mode = SPI_MODE_3,
        },
 #endif
-#if defined(CONFIG_PBX)
-       {
-               .modalias = "fxs-spi",
-               .max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 0,
-               .chip_select = 8 - CONFIG_J11_JUMPER,
-               .controller_data = &spi_si3xxx_chip_info,
-               .mode = SPI_MODE_3,
-       },
-       {
-               .modalias = "fxo-spi",
-               .max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 0,
-               .chip_select = 8 - CONFIG_J19_JUMPER,
-               .controller_data = &spi_si3xxx_chip_info,
-               .mode = SPI_MODE_3,
-       },
-#endif
 #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
        {
                .modalias               = "ad7877",
@@ -539,7 +512,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
                I2C_BOARD_INFO("pcf8574_lcd", 0x22),
        },
 #endif
-#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE)
+#if defined(CONFIG_INPUT_PCF8574) || defined(CONFIG_INPUT_PCF8574_MODULE)
        {
                I2C_BOARD_INFO("pcf8574_keypad", 0x27),
                .irq = IRQ_PF8,
index 753ed810e1c61f8bc0b63d6a117c82504f3fbd9e..e9c65390edd1852bdf4b691542e34e3687a29a95 100644 (file)
 #define ANOMALY_05000386 (0)
 #define ANOMALY_05000389 (0)
 #define ANOMALY_05000400 (0)
+#define ANOMALY_05000402 (0)
 #define ANOMALY_05000412 (0)
 #define ANOMALY_05000432 (0)
 #define ANOMALY_05000447 (0)
index e8e14c2769edbb24d54db9933e5e451a6729771f..83421d3931482e2d3da1c4ed333107a76e566f77 100644 (file)
 #endif
 #endif
 
-/* UART_IIR Register */
-#define STATUS(x)      ((x << 1) & 0x06)
-#define STATUS_P1      0x02
-#define STATUS_P0      0x01
-
 #define BFIN_UART_NR_PORTS     2
 
 #define OFFSET_THR              0x00   /* Transmit Holding register            */
 #define OFFSET_SCR              0x1C   /* SCR Scratch Register                 */
 #define OFFSET_GCTL             0x24   /* Global Control Register              */
 
-/* DPMC*/
-#define bfin_read_STOPCK_OFF() bfin_read_STOPCK()
-#define bfin_write_STOPCK_OFF(val) bfin_write_STOPCK(val)
-#define STOPCK_OFF STOPCK
-
 /* PLL_DIV Masks                                                                                                       */
 #define CCLK_DIV1 CSEL_DIV1    /*          CCLK = VCO / 1                                  */
 #define CCLK_DIV2 CSEL_DIV2    /*          CCLK = VCO / 2                                  */
index b09484f538f41abdf1ebf69ebd48acb7fe61f9c4..08a3f01c98865f15e43bf97bc97bd6d2bc55ffd5 100644 (file)
@@ -151,46 +151,6 @@ static struct platform_device musb_device = {
 };
 #endif
 
-#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
-static struct mtd_partition ezkit_partitions[] = {
-       {
-               .name       = "bootloader(nor)",
-               .size       = 0x40000,
-               .offset     = 0,
-       }, {
-               .name       = "linux kernel(nor)",
-               .size       = 0x1C0000,
-               .offset     = MTDPART_OFS_APPEND,
-       }, {
-               .name       = "file system(nor)",
-               .size       = MTDPART_SIZ_FULL,
-               .offset     = MTDPART_OFS_APPEND,
-       }
-};
-
-static struct physmap_flash_data ezkit_flash_data = {
-       .width      = 2,
-       .parts      = ezkit_partitions,
-       .nr_parts   = ARRAY_SIZE(ezkit_partitions),
-};
-
-static struct resource ezkit_flash_resource = {
-       .start = 0x20000000,
-       .end   = 0x201fffff,
-       .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device ezkit_flash_device = {
-       .name          = "physmap-flash",
-       .id            = 0,
-       .dev = {
-               .platform_data = &ezkit_flash_data,
-       },
-       .num_resources = 1,
-       .resource      = &ezkit_flash_resource,
-};
-#endif
-
 #if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE)
 static struct mtd_partition partition_info[] = {
        {
@@ -275,6 +235,14 @@ static struct platform_device rtc_device = {
 #endif
 
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+#include <linux/smc91x.h>
+
+static struct smc91x_platdata smc91x_info = {
+       .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+       .leda = RPC_LED_100_10,
+       .ledb = RPC_LED_TX_RX,
+};
+
 static struct resource smc91x_resources[] = {
        {
                .name = "smc91x-regs",
@@ -293,6 +261,9 @@ static struct platform_device smc91x_device = {
        .id = 0,
        .num_resources = ARRAY_SIZE(smc91x_resources),
        .resource = smc91x_resources,
+       .dev    = {
+               .platform_data  = &smc91x_info,
+       },
 };
 #endif
 
@@ -300,10 +271,15 @@ static struct platform_device smc91x_device = {
 static struct resource dm9000_resources[] = {
        [0] = {
                .start  = 0x203FB800,
-               .end    = 0x203FB800 + 8,
+               .end    = 0x203FB800 + 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
+               .start  = 0x203FB804,
+               .end    = 0x203FB804 + 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [2] = {
                .start  = IRQ_PF9,
                .end    = IRQ_PF9,
                .flags  = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE),
@@ -479,13 +455,6 @@ static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
-static struct bfin5xx_spi_chip ad9960_spi_chip_info = {
-       .enable_dma = 0,
-       .bits_per_word = 16,
-};
-#endif
-
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
 static struct bfin5xx_spi_chip  mmc_spi_chip_info = {
        .enable_dma = 0,
@@ -493,15 +462,6 @@ static struct bfin5xx_spi_chip  mmc_spi_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_PBX)
-static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
-       .ctl_reg        = 0x4, /* send zero */
-       .enable_dma     = 0,
-       .bits_per_word  = 8,
-       .cs_change_per_word = 1,
-};
-#endif
-
 #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
 static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
        .enable_dma = 0,
@@ -568,22 +528,13 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 #if defined(CONFIG_SND_BLACKFIN_AD1836) \
        || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
        {
-               .modalias = "ad1836-spi",
+               .modalias = "ad1836",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
                .bus_num = 0,
                .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
                .controller_data = &ad1836_spi_chip_info,
        },
 #endif
-#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
-       {
-               .modalias = "ad9960-spi",
-               .max_speed_hz = 10000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 0,
-               .chip_select = 1,
-               .controller_data = &ad9960_spi_chip_info,
-       },
-#endif
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
        {
                .modalias = "mmc_spi",
@@ -594,24 +545,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
                .mode = SPI_MODE_3,
        },
 #endif
-#if defined(CONFIG_PBX)
-       {
-               .modalias = "fxs-spi",
-               .max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 0,
-               .chip_select = 8 - CONFIG_J11_JUMPER,
-               .controller_data = &spi_si3xxx_chip_info,
-               .mode = SPI_MODE_3,
-       },
-       {
-               .modalias = "fxo-spi",
-               .max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 0,
-               .chip_select = 8 - CONFIG_J19_JUMPER,
-               .controller_data = &spi_si3xxx_chip_info,
-               .mode = SPI_MODE_3,
-       },
-#endif
 #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
        {
                .modalias               = "ad7877",
@@ -689,6 +622,55 @@ static struct platform_device bfin_fb_adv7393_device = {
 };
 #endif
 
+#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
+static struct mtd_partition cm_partitions[] = {
+       {
+               .name   = "bootloader(nor)",
+               .size   = 0x40000,
+               .offset = 0,
+       }, {
+               .name   = "linux kernel(nor)",
+               .size   = 0x100000,
+               .offset = MTDPART_OFS_APPEND,
+       }, {
+               .name   = "file system(nor)",
+               .size   = MTDPART_SIZ_FULL,
+               .offset = MTDPART_OFS_APPEND,
+       }
+};
+
+static struct physmap_flash_data cm_flash_data = {
+       .width    = 2,
+       .parts    = cm_partitions,
+       .nr_parts = ARRAY_SIZE(cm_partitions),
+};
+
+static unsigned cm_flash_gpios[] = { GPIO_PH9, GPIO_PG11 };
+
+static struct resource cm_flash_resource[] = {
+       {
+               .name  = "cfi_probe",
+               .start = 0x20000000,
+               .end   = 0x201fffff,
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = (unsigned long)cm_flash_gpios,
+               .end   = ARRAY_SIZE(cm_flash_gpios),
+               .flags = IORESOURCE_IRQ,
+       }
+};
+
+static struct platform_device cm_flash_device = {
+       .name          = "gpio-addr-flash",
+       .id            = 0,
+       .dev = {
+               .platform_data = &cm_flash_data,
+       },
+       .num_resources = ARRAY_SIZE(cm_flash_resource),
+       .resource      = cm_flash_resource,
+};
+#endif
+
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
 static struct resource bfin_uart_resources[] = {
 #ifdef CONFIG_SERIAL_BFIN_UART0
@@ -796,13 +778,11 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 #if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE)
        {
                I2C_BOARD_INFO("pcf8574_lcd", 0x22),
-               .type = "pcf8574_lcd",
        },
 #endif
-#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE)
+#if defined(CONFIG_INPUT_PCF8574) || defined(CONFIG_INPUT_PCF8574_MODULE)
        {
                I2C_BOARD_INFO("pcf8574_keypad", 0x27),
-               .type = "pcf8574_keypad",
                .irq = IRQ_PF8,
        },
 #endif
@@ -876,7 +856,7 @@ static struct platform_device bfin_dpmc = {
        },
 };
 
-static struct platform_device *stamp_devices[] __initdata = {
+static struct platform_device *cmbf527_devices[] __initdata = {
 
        &bfin_dpmc,
 
@@ -959,8 +939,8 @@ static struct platform_device *stamp_devices[] __initdata = {
        &bfin_device_gpiokeys,
 #endif
 
-#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
-       &ezkit_flash_device,
+#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
+       &cm_flash_device,
 #endif
 
        &bfin_gpios_device,
@@ -971,7 +951,7 @@ static int __init cm_init(void)
        printk(KERN_INFO "%s(): registering device resources\n", __func__);
        i2c_register_board_info(0, bfin_i2c_board_info,
                                ARRAY_SIZE(bfin_i2c_board_info));
-       platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
+       platform_add_devices(cmbf527_devices, ARRAY_SIZE(cmbf527_devices));
        spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
        return 0;
 }
index 2ad68cd10ae674af6b7d693afb98f7cbcdc79320..68b4c804364c043b2e81273a6315f3b4091f70c7 100644 (file)
@@ -263,15 +263,6 @@ static struct bfin5xx_spi_chip mmc_spi_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_PBX)
-static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
-       .ctl_reg        = 0x4, /* send zero */
-       .enable_dma     = 0,
-       .bits_per_word  = 8,
-       .cs_change_per_word = 1,
-};
-#endif
-
 #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
 static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
        .enable_dma = 0,
@@ -376,24 +367,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
                .mode = SPI_MODE_3,
        },
 #endif
-#if defined(CONFIG_PBX)
-       {
-               .modalias = "fxs-spi",
-               .max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 0,
-               .chip_select = 8 - CONFIG_J11_JUMPER,
-               .controller_data = &spi_si3xxx_chip_info,
-               .mode = SPI_MODE_3,
-       },
-       {
-               .modalias = "fxo-spi",
-               .max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 0,
-               .chip_select = 8 - CONFIG_J19_JUMPER,
-               .controller_data = &spi_si3xxx_chip_info,
-               .mode = SPI_MODE_3,
-       },
-#endif
 #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
        {
                .modalias               = "ad7877",
@@ -596,7 +569,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
                I2C_BOARD_INFO("pcf8574_lcd", 0x22),
        },
 #endif
-#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE)
+#if defined(CONFIG_INPUT_PCF8574) || defined(CONFIG_INPUT_PCF8574_MODULE)
        {
                I2C_BOARD_INFO("pcf8574_keypad", 0x27),
                .irq = IRQ_PF8,
index 75e563d3f9d4f0f49aa87921a11781e8fbcbd01b..2849b09abe995387cf279e1c30a4dd4095e804b9 100644 (file)
@@ -292,6 +292,14 @@ static struct platform_device rtc_device = {
 #endif
 
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+#include <linux/smc91x.h>
+
+static struct smc91x_platdata smc91x_info = {
+       .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+       .leda = RPC_LED_100_10,
+       .ledb = RPC_LED_TX_RX,
+};
+
 static struct resource smc91x_resources[] = {
        {
                .name = "smc91x-regs",
@@ -310,6 +318,9 @@ static struct platform_device smc91x_device = {
        .id = 0,
        .num_resources = ARRAY_SIZE(smc91x_resources),
        .resource = smc91x_resources,
+       .dev    = {
+               .platform_data  = &smc91x_info,
+       },
 };
 #endif
 
@@ -501,13 +512,6 @@ static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
-static struct bfin5xx_spi_chip ad9960_spi_chip_info = {
-       .enable_dma = 0,
-       .bits_per_word = 16,
-};
-#endif
-
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
 static struct bfin5xx_spi_chip  mmc_spi_chip_info = {
        .enable_dma = 0,
@@ -515,15 +519,6 @@ static struct bfin5xx_spi_chip  mmc_spi_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_PBX)
-static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
-       .ctl_reg        = 0x4, /* send zero */
-       .enable_dma     = 0,
-       .bits_per_word  = 8,
-       .cs_change_per_word = 1,
-};
-#endif
-
 #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
 static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
        .enable_dma = 0,
@@ -614,22 +609,13 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 #if defined(CONFIG_SND_BLACKFIN_AD1836) \
        || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
        {
-               .modalias = "ad1836-spi",
+               .modalias = "ad1836",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
                .bus_num = 0,
                .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
                .controller_data = &ad1836_spi_chip_info,
        },
 #endif
-#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
-       {
-               .modalias = "ad9960-spi",
-               .max_speed_hz = 10000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 0,
-               .chip_select = 1,
-               .controller_data = &ad9960_spi_chip_info,
-       },
-#endif
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
        {
                .modalias = "mmc_spi",
@@ -641,24 +627,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        },
 #endif
 
-#if defined(CONFIG_PBX)
-       {
-               .modalias = "fxs-spi",
-               .max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 0,
-               .chip_select = 8 - CONFIG_J11_JUMPER,
-               .controller_data = &spi_si3xxx_chip_info,
-               .mode = SPI_MODE_3,
-       },
-       {
-               .modalias = "fxo-spi",
-               .max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 0,
-               .chip_select = 8 - CONFIG_J19_JUMPER,
-               .controller_data = &spi_si3xxx_chip_info,
-               .mode = SPI_MODE_3,
-       },
-#endif
 #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
        {
                .modalias               = "ad7877",
@@ -863,7 +831,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
                I2C_BOARD_INFO("pcf8574_lcd", 0x22),
        },
 #endif
-#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE)
+#if defined(CONFIG_INPUT_PCF8574) || defined(CONFIG_INPUT_PCF8574_MODULE)
        {
                I2C_BOARD_INFO("pcf8574_keypad", 0x27),
                .irq = IRQ_PF8,
index c438ca89d8c9047c71669ffd652d67a92f135eb1..3f9052687fa8065c871d00e268c34c45f85a7f31 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 /* This file should be up to date with:
- *  - Revision C, 03/13/2009; ADSP-BF526 Blackfin Processor Anomaly List
+ *  - Revision D, 08/14/2009; ADSP-BF526 Blackfin Processor Anomaly List
  *  - Revision F, 03/03/2009; ADSP-BF527 Blackfin Processor Anomaly List
  */
 
 #define ANOMALY_05000443 (1)
 /* The WURESET Bit in the SYSCR Register is not Functional */
 #define ANOMALY_05000445 (1)
-/* USB DMA Short Packet Data Corruption */
+/* USB DMA Mode 1 Short Packet Data Corruption */
 #define ANOMALY_05000450 (1)
 /* BCODE_QUICKBOOT, BCODE_ALLBOOT, and BCODE_FULLBOOT Settings in SYSCR Register Not Functional */
 #define ANOMALY_05000451 (1)
 #define ANOMALY_05000456 (1)
 /* Host DMA Port Responds to Certain Bus Activity Without HOST_CE Assertion */
 #define ANOMALY_05000457 (1)
+/* USB DMA Mode 1 Failure When Multiple USB DMA Channels Are Concurrently Enabled */
+#define ANOMALY_05000460 (1)
 /* False Hardware Error when RETI Points to Invalid Memory */
 #define ANOMALY_05000461 (1)
+/* Synchronization Problem at Startup May Cause SPORT Transmit Channels to Misalign */
+#define ANOMALY_05000462 (1)
 /* USB Rx DMA hang */
 #define ANOMALY_05000465 (1)
+/* TxPktRdy Bit Not Set for Transmit Endpoint When Core and DMA Access USB Endpoint FIFOs Simultaneously */
+#define ANOMALY_05000466 (1)
 /* Possible RX data corruption when control & data EP FIFOs are accessed via the core */
 #define ANOMALY_05000467 (1)
+/* PLL Latches Incorrect Settings During Reset */
+#define ANOMALY_05000469 (1)
 
 /* Anomalies that don't exist on this proc */
 #define ANOMALY_05000099 (0)
 #define ANOMALY_05000362 (1)
 #define ANOMALY_05000363 (0)
 #define ANOMALY_05000400 (0)
+#define ANOMALY_05000402 (0)
 #define ANOMALY_05000412 (0)
 #define ANOMALY_05000447 (0)
 #define ANOMALY_05000448 (0)
index 03665a8e16be73e676b392b164aed4abcfe067dc..ea9cb0fef8bcd677a881d3dc4ba329870979857e 100644 (file)
 #endif
 #endif
 
-/* UART_IIR Register */
-#define STATUS(x)      ((x << 1) & 0x06)
-#define STATUS_P1      0x02
-#define STATUS_P0      0x01
-
 #define BFIN_UART_NR_PORTS     2
 
 #define OFFSET_THR              0x00   /* Transmit Holding register            */
 #define OFFSET_SCR              0x1C   /* SCR Scratch Register                 */
 #define OFFSET_GCTL             0x24   /* Global Control Register              */
 
-/* DPMC*/
-#define bfin_read_STOPCK_OFF() bfin_read_STOPCK()
-#define bfin_write_STOPCK_OFF(val) bfin_write_STOPCK(val)
-#define STOPCK_OFF STOPCK
-
 /* PLL_DIV Masks                                                                                                       */
 #define CCLK_DIV1 CSEL_DIV1    /*          CCLK = VCO / 1                                  */
 #define CCLK_DIV2 CSEL_DIV2    /*          CCLK = VCO / 2                                  */
index 38cf8ffd6d74ac68a14d723f739ecf78aa92b60d..6c2b47fe4fe4254339a5cb0ec64bd488c8a87778 100644 (file)
@@ -88,6 +88,14 @@ static struct platform_device dm9000_device = {
 #endif
 
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+#include <linux/smc91x.h>
+
+static struct smc91x_platdata smc91x_info = {
+       .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+       .leda = RPC_LED_100_10,
+       .ledb = RPC_LED_TX_RX,
+};
+
 static struct resource smc91x_resources[] = {
        {
                .name = "smc91x-regs",
@@ -110,6 +118,9 @@ static struct platform_device smc91x_device = {
        .id = 0,
        .num_resources = ARRAY_SIZE(smc91x_resources),
        .resource = smc91x_resources,
+       .dev    = {
+               .platform_data  = &smc91x_info,
+       },
 };
 #endif
 
@@ -190,15 +201,6 @@ static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_PBX)
-static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
-       .ctl_reg        = 0x1c04,
-       .enable_dma     = 0,
-       .bits_per_word  = 8,
-       .cs_change_per_word = 1,
-};
-#endif
-
 /* Notice: for blackfin, the speed_hz is the value of register
  * SPI_BAUD, not the real baudrate */
 static struct spi_board_info bfin_spi_board_info[] __initdata = {
@@ -229,7 +231,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 
 #if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
        {
-               .modalias = "ad1836-spi",
+               .modalias = "ad1836",
                .max_speed_hz = 16,
                .bus_num = 1,
                .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
@@ -237,23 +239,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        },
 #endif
 
-#if defined(CONFIG_PBX)
-       {
-               .modalias        = "fxs-spi",
-               .max_speed_hz    = 4,
-               .bus_num         = 1,
-               .chip_select     = 3,
-               .controller_data = &spi_si3xxx_chip_info,
-       },
-
-       {
-               .modalias        = "fxo-spi",
-               .max_speed_hz    = 4,
-               .bus_num         = 1,
-               .chip_select     = 2,
-               .controller_data = &spi_si3xxx_chip_info,
-       },
-#endif
 };
 
 /* SPI (0) */
index 9ecdc361fa6d56f299555fa28fb7b04298c81211..8208d67e2c9766cf3c496b41dd09bab7d99f2016 100644 (file)
@@ -48,6 +48,14 @@ static struct platform_device rtc_device = {
  *  Driver needs to know address, irq and flag pin.
  */
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+#include <linux/smc91x.h>
+
+static struct smc91x_platdata smc91x_info = {
+       .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+       .leda = RPC_LED_100_10,
+       .ledb = RPC_LED_TX_RX,
+};
+
 static struct resource smc91x_resources[] = {
        {
                .name = "smc91x-regs",
@@ -66,6 +74,9 @@ static struct platform_device smc91x_device = {
        .id = 0,
        .num_resources = ARRAY_SIZE(smc91x_resources),
        .resource = smc91x_resources,
+       .dev    = {
+               .platform_data  = &smc91x_info,
+       },
 };
 #endif
 
index 1443e92d8b6241e56138fc08a82e5c5b28eb6c24..7443b26c80c5df17eaf7e4c20cd45a3ca3acb790 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
+#include <linux/spi/mmc_spi.h>
 #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
 #include <linux/usb/isp1362.h>
 #endif
@@ -130,7 +132,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 
 #if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
        {
-               .modalias = "ad1836-spi",
+               .modalias = "ad1836",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
                .bus_num = 0,
                .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
@@ -141,9 +143,9 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
        {
                .modalias = "mmc_spi",
-               .max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
+               .max_speed_hz = 20000000,     /* max spi clock (SCK) speed in HZ */
                .bus_num = 0,
-               .chip_select = 5,
+               .chip_select = 1,
                .controller_data = &mmc_spi_chip_info,
                .mode = SPI_MODE_3,
        },
@@ -195,6 +197,14 @@ static struct platform_device rtc_device = {
 #endif
 
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+#include <linux/smc91x.h>
+
+static struct smc91x_platdata smc91x_info = {
+       .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+       .leda = RPC_LED_100_10,
+       .ledb = RPC_LED_TX_RX,
+};
+
 static struct resource smc91x_resources[] = {
        {
                .start = 0x20200300,
@@ -211,6 +221,43 @@ static struct platform_device smc91x_device = {
        .id = 0,
        .num_resources = ARRAY_SIZE(smc91x_resources),
        .resource = smc91x_resources,
+       .dev    = {
+               .platform_data  = &smc91x_info,
+       },
+};
+#endif
+
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+#include <linux/smsc911x.h>
+
+static struct resource smsc911x_resources[] = {
+       {
+               .name = "smsc911x-memory",
+               .start = 0x20308000,
+               .end = 0x20308000 + 0xFF,
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = IRQ_PF8,
+               .end = IRQ_PF8,
+               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+       },
+};
+
+static struct smsc911x_platform_config smsc911x_config = {
+       .flags = SMSC911X_USE_16BIT,
+       .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+       .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+       .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+static struct platform_device smsc911x_device = {
+       .name = "smsc911x",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(smsc911x_resources),
+       .resource = smsc911x_resources,
+       .dev = {
+               .platform_data = &smsc911x_config,
+       },
 };
 #endif
 
@@ -324,6 +371,68 @@ static struct platform_device isp1362_hcd_device = {
 };
 #endif
 
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+static struct resource net2272_bfin_resources[] = {
+       {
+               .start = 0x20300000,
+               .end = 0x20300000 + 0x100,
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = IRQ_PF6,
+               .end = IRQ_PF6,
+               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+       },
+};
+
+static struct platform_device net2272_bfin_device = {
+       .name = "net2272",
+       .id = -1,
+       .num_resources = ARRAY_SIZE(net2272_bfin_resources),
+       .resource = net2272_bfin_resources,
+};
+#endif
+
+
+
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct mtd_partition para_partitions[] = {
+       {
+               .name       = "bootloader(nor)",
+               .size       = 0x40000,
+               .offset     = 0,
+       }, {
+               .name       = "linux+rootfs(nor)",
+               .size       = MTDPART_SIZ_FULL,
+               .offset     = MTDPART_OFS_APPEND,
+       },
+};
+
+static struct physmap_flash_data para_flash_data = {
+       .width      = 2,
+       .parts      = para_partitions,
+       .nr_parts   = ARRAY_SIZE(para_partitions),
+};
+
+static struct resource para_flash_resource = {
+       .start = 0x20000000,
+       .end   = 0x201fffff,
+       .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device para_flash_device = {
+       .name          = "physmap-flash",
+       .id            = 0,
+       .dev = {
+               .platform_data = &para_flash_data,
+       },
+       .num_resources = 1,
+       .resource      = &para_flash_resource,
+};
+#endif
+
+
+
 static const unsigned int cclk_vlev_datasheet[] =
 {
        VRPAIR(VLEV_085, 250000000),
@@ -382,10 +491,22 @@ static struct platform_device *cm_bf533_devices[] __initdata = {
        &smc91x_device,
 #endif
 
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+       &smsc911x_device,
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+       &net2272_bfin_device,
+#endif
+
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
        &bfin_spi0_device,
 #endif
 
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+       &para_flash_device,
+#endif
+
        &bfin_gpios_device,
 };
 
index 4e3e511bf14646fdc3c32075cd91407d87777a2a..fd518e383b79ea8b3aa3657c39c154fec757c02a 100644 (file)
@@ -67,6 +67,14 @@ static struct platform_device bfin_fb_adv7393_device = {
  *  Driver needs to know address, irq and flag pin.
  */
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+#include <linux/smc91x.h>
+
+static struct smc91x_platdata smc91x_info = {
+       .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+       .leda = RPC_LED_100_10,
+       .ledb = RPC_LED_TX_RX,
+};
+
 static struct resource smc91x_resources[] = {
        {
                .name = "smc91x-regs",
@@ -84,6 +92,9 @@ static struct platform_device smc91x_device = {
        .id = 0,
        .num_resources = ARRAY_SIZE(smc91x_resources),
        .resource = smc91x_resources,
+       .dev    = {
+               .platform_data  = &smc91x_info,
+       },
 };
 #endif
 
@@ -263,7 +274,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 
 #if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
        {
-               .modalias = "ad1836-spi",
+               .modalias = "ad1836",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
                .bus_num = 0,
                .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
index 3d743ccaff6ab8d4b543b091f72833b8c8f73a21..729fd7c263360be6bd10a3dc80333cc64e223095 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/mtd/physmap.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
+#include <linux/spi/mmc_spi.h>
 #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
 #include <linux/usb/isp1362.h>
 #endif
@@ -62,6 +63,14 @@ static struct platform_device rtc_device = {
  *  Driver needs to know address, irq and flag pin.
  */
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+#include <linux/smc91x.h>
+
+static struct smc91x_platdata smc91x_info = {
+       .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+       .leda = RPC_LED_100_10,
+       .ledb = RPC_LED_TX_RX,
+};
+
 static struct resource smc91x_resources[] = {
        {
                .name = "smc91x-regs",
@@ -80,6 +89,9 @@ static struct platform_device smc91x_device = {
        .id = 0,
        .num_resources = ARRAY_SIZE(smc91x_resources),
        .resource = smc91x_resources,
+       .dev    = {
+               .platform_data  = &smc91x_info,
+       },
 };
 #endif
 
@@ -207,19 +219,38 @@ static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_PBX)
-static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
-       .ctl_reg        = 0x4, /* send zero */
-       .enable_dma     = 0,
-       .bits_per_word  = 8,
-       .cs_change_per_word = 1,
+#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
+static struct bfin5xx_spi_chip spidev_chip_info = {
+       .enable_dma = 0,
+       .bits_per_word = 8,
 };
 #endif
 
-#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
-static struct bfin5xx_spi_chip spidev_chip_info = {
+#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
+#define MMC_SPI_CARD_DETECT_INT IRQ_PF5
+static int bfin_mmc_spi_init(struct device *dev,
+       irqreturn_t (*detect_int)(int, void *), void *data)
+{
+       return request_irq(MMC_SPI_CARD_DETECT_INT, detect_int,
+               IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+               "mmc-spi-detect", data);
+}
+
+static void bfin_mmc_spi_exit(struct device *dev, void *data)
+{
+       free_irq(MMC_SPI_CARD_DETECT_INT, data);
+}
+
+static struct mmc_spi_platform_data bfin_mmc_spi_pdata = {
+       .init = bfin_mmc_spi_init,
+       .exit = bfin_mmc_spi_exit,
+       .detect_delay = 100, /* msecs */
+};
+
+static struct bfin5xx_spi_chip  mmc_spi_chip_info = {
        .enable_dma = 0,
        .bits_per_word = 8,
+       .pio_interrupt = 0,
 };
 #endif
 
@@ -250,33 +281,14 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 
 #if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
        {
-               .modalias = "ad1836-spi",
-               .max_speed_hz = 31250000,     /* max spi clock (SCK) speed in HZ */
+               .modalias = "ad1836",
+               .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
                .bus_num = 0,
                .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
                .controller_data = &ad1836_spi_chip_info,
        },
 #endif
 
-#if defined(CONFIG_PBX)
-       {
-               .modalias = "fxs-spi",
-               .max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 0,
-               .chip_select = 8 - CONFIG_J11_JUMPER,
-               .controller_data = &spi_si3xxx_chip_info,
-               .mode = SPI_MODE_3,
-       },
-       {
-               .modalias = "fxo-spi",
-               .max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 0,
-               .chip_select = 8 - CONFIG_J19_JUMPER,
-               .controller_data = &spi_si3xxx_chip_info,
-               .mode = SPI_MODE_3,
-       },
-#endif
-
 #if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
        {
                .modalias = "spidev",
@@ -286,6 +298,17 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
                .controller_data = &spidev_chip_info,
        },
 #endif
+#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
+       {
+               .modalias = "mmc_spi",
+               .max_speed_hz = 20000000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0,
+               .chip_select = 4,
+               .platform_data = &bfin_mmc_spi_pdata,
+               .controller_data = &mmc_spi_chip_info,
+               .mode = SPI_MODE_3,
+       },
+#endif
 };
 
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
@@ -458,7 +481,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
                I2C_BOARD_INFO("pcf8574_lcd", 0x22),
        },
 #endif
-#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE)
+#if defined(CONFIG_INPUT_PCF8574) || defined(CONFIG_INPUT_PCF8574_MODULE)
        {
                I2C_BOARD_INFO("pcf8574_keypad", 0x27),
                .irq = 39,
index 0a6eb8f24d98f62d866d4483e5ce0d17dfe777cd..7a443c37fb9fd8d6297a280813bfbb1cdc84d677 100644 (file)
@@ -76,12 +76,12 @@ int channel2irq(unsigned int channel)
                ret_irq = IRQ_SPI;
                break;
 
-       case CH_UART_RX:
-               ret_irq = IRQ_UART_RX;
+       case CH_UART0_RX:
+               ret_irq = IRQ_UART0_RX;
                break;
 
-       case CH_UART_TX:
-               ret_irq = IRQ_UART_TX;
+       case CH_UART0_TX:
+               ret_irq = IRQ_UART0_TX;
                break;
 
        case CH_MEM_STREAM0_SRC:
index 4062e24e759bbc83eb51dedf8386fb7dcc9792bd..6965b4088c44a5d09bec394dadc286320be60303 100644 (file)
@@ -131,11 +131,11 @@ struct bfin_serial_res {
 struct bfin_serial_res bfin_serial_resource[] = {
        {
        0xFFC00400,
-       IRQ_UART_RX,
-       IRQ_UART_ERROR,
+       IRQ_UART0_RX,
+       IRQ_UART0_ERROR,
 #ifdef CONFIG_SERIAL_BFIN_DMA
-       CH_UART_TX,
-       CH_UART_RX,
+       CH_UART0_TX,
+       CH_UART0_RX,
 #endif
 #ifdef CONFIG_SERIAL_BFIN_CTSRTS
        CONFIG_UART0_CTS_PIN,
index 39aa175f19f585c6e8dd75fd8f569544dd58d64d..499e897a4f4f17fc0186cb5a7fb6c541bc99651b 100644 (file)
 
 #define BFIN_UART_NR_PORTS      1
 
-#define CH_UART_RX CH_UART0_RX
-#define CH_UART_TX CH_UART0_TX
-
-#define IRQ_UART_ERROR IRQ_UART0_ERROR
-#define IRQ_UART_RX    IRQ_UART0_RX
-#define IRQ_UART_TX    IRQ_UART0_TX
-
 #define OFFSET_THR              0x00   /* Transmit Holding register            */
 #define OFFSET_RBR              0x00   /* Receive Buffer register              */
 #define OFFSET_DLL              0x00   /* Divisor Latch (Low-Byte)             */
index 77c59da87e85d93f2d62478fff1f6a9cef4c19df..44132fda63bec3562056d25550e4c5caf0ffea1e 100644 (file)
@@ -9,11 +9,17 @@ config BFIN537_STAMP
        help
          BF537-STAMP board support.
 
-config BFIN537_BLUETECHNIX_CM
-       bool "Bluetechnix CM-BF537"
+config BFIN537_BLUETECHNIX_CM_E
+       bool "Bluetechnix CM-BF537E"
        depends on (BF537)
        help
-         CM-BF537 support for EVAL- and DEV-Board.
+         CM-BF537E support for EVAL- and DEV-Board.
+
+config BFIN537_BLUETECHNIX_CM_U
+       bool "Bluetechnix CM-BF537U"
+       depends on (BF537)
+       help
+         CM-BF537U support for EVAL- and DEV-Board.
 
 config BFIN537_BLUETECHNIX_TCM
        bool "Bluetechnix TCM-BF537"
index 68b98a7af6a618dc642b9413ec0b7c613798bf84..7e6aa4e5b205f367b3ba30b50e11fe4d38c201e2 100644 (file)
@@ -3,7 +3,8 @@
 #
 
 obj-$(CONFIG_BFIN537_STAMP)            += stamp.o
-obj-$(CONFIG_BFIN537_BLUETECHNIX_CM)   += cm_bf537.o
+obj-$(CONFIG_BFIN537_BLUETECHNIX_CM_E) += cm_bf537e.o
+obj-$(CONFIG_BFIN537_BLUETECHNIX_CM_U) += cm_bf537u.o
 obj-$(CONFIG_BFIN537_BLUETECHNIX_TCM)  += tcm_bf537.o
 obj-$(CONFIG_PNAV10)                   += pnav10.o
 obj-$(CONFIG_CAMSIG_MINOTAUR)          += minotaur.o
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537.c b/arch/blackfin/mach-bf537/boards/cm_bf537.c
deleted file mode 100644 (file)
index 2a87d1c..0000000
+++ /dev/null
@@ -1,638 +0,0 @@
-/*
- * File:         arch/blackfin/mach-bf537/boards/cm_bf537.c
- * Based on:     arch/blackfin/mach-bf533/boards/ezkit.c
- * Author:       Aidan Williams <aidan@nicta.com.au>
- *
- * Created:      2005
- * Description:  Board description file
- *
- * Modified:
- *               Copyright 2005 National ICT Australia (NICTA)
- *               Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <linux/device.h>
-#include <linux/etherdevice.h>
-#include <linux/platform_device.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/physmap.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/flash.h>
-#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
-#include <linux/usb/isp1362.h>
-#endif
-#include <linux/ata_platform.h>
-#include <linux/irq.h>
-#include <asm/dma.h>
-#include <asm/bfin5xx_spi.h>
-#include <asm/portmux.h>
-#include <asm/dpmc.h>
-
-/*
- * Name the Board for the /proc/cpuinfo
- */
-const char bfin_board_name[] = "Bluetechnix CM BF537";
-
-#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
-/* all SPI peripherals info goes here */
-
-#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
-static struct mtd_partition bfin_spi_flash_partitions[] = {
-       {
-               .name = "bootloader(spi)",
-               .size = 0x00020000,
-               .offset = 0,
-               .mask_flags = MTD_CAP_ROM
-       }, {
-               .name = "linux kernel(spi)",
-               .size = 0xe0000,
-               .offset = 0x20000
-       }, {
-               .name = "file system(spi)",
-               .size = 0x700000,
-               .offset = 0x00100000,
-       }
-};
-
-static struct flash_platform_data bfin_spi_flash_data = {
-       .name = "m25p80",
-       .parts = bfin_spi_flash_partitions,
-       .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
-       .type = "m25p64",
-};
-
-/* SPI flash chip (m25p64) */
-static struct bfin5xx_spi_chip spi_flash_chip_info = {
-       .enable_dma = 0,         /* use dma transfer with this chip*/
-       .bits_per_word = 8,
-};
-#endif
-
-#if defined(CONFIG_BFIN_SPI_ADC) || defined(CONFIG_BFIN_SPI_ADC_MODULE)
-/* SPI ADC chip */
-static struct bfin5xx_spi_chip spi_adc_chip_info = {
-       .enable_dma = 1,         /* use dma transfer with this chip*/
-       .bits_per_word = 16,
-};
-#endif
-
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
-static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
-       .enable_dma = 0,
-       .bits_per_word = 16,
-};
-#endif
-
-#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
-static struct bfin5xx_spi_chip ad9960_spi_chip_info = {
-       .enable_dma = 0,
-       .bits_per_word = 16,
-};
-#endif
-
-#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
-static struct bfin5xx_spi_chip  mmc_spi_chip_info = {
-       .enable_dma = 0,
-       .bits_per_word = 8,
-};
-#endif
-
-static struct spi_board_info bfin_spi_board_info[] __initdata = {
-#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
-       {
-               /* the modalias must be the same as spi device driver name */
-               .modalias = "m25p80", /* Name of spi_driver for this device */
-               .max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 0, /* Framework bus number */
-               .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/
-               .platform_data = &bfin_spi_flash_data,
-               .controller_data = &spi_flash_chip_info,
-               .mode = SPI_MODE_3,
-       },
-#endif
-
-#if defined(CONFIG_BFIN_SPI_ADC) || defined(CONFIG_BFIN_SPI_ADC_MODULE)
-       {
-               .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
-               .max_speed_hz = 6250000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 0, /* Framework bus number */
-               .chip_select = 1, /* Framework chip select. */
-               .platform_data = NULL, /* No spi_driver specific config */
-               .controller_data = &spi_adc_chip_info,
-       },
-#endif
-
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
-       {
-               .modalias = "ad1836-spi",
-               .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 0,
-               .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
-               .controller_data = &ad1836_spi_chip_info,
-       },
-#endif
-
-#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
-       {
-               .modalias = "ad9960-spi",
-               .max_speed_hz = 10000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 0,
-               .chip_select = 1,
-               .controller_data = &ad9960_spi_chip_info,
-       },
-#endif
-
-#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
-       {
-               .modalias = "mmc_spi",
-               .max_speed_hz = 20000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 0,
-               .chip_select = 1,
-               .controller_data = &mmc_spi_chip_info,
-               .mode = SPI_MODE_3,
-       },
-#endif
-};
-
-/* SPI (0) */
-static struct resource bfin_spi0_resource[] = {
-       [0] = {
-               .start = SPI0_REGBASE,
-               .end   = SPI0_REGBASE + 0xFF,
-               .flags = IORESOURCE_MEM,
-               },
-       [1] = {
-               .start = CH_SPI,
-               .end   = CH_SPI,
-               .flags = IORESOURCE_DMA,
-       },
-       [2] = {
-               .start = IRQ_SPI,
-               .end   = IRQ_SPI,
-               .flags = IORESOURCE_IRQ,
-       },
-};
-
-/* SPI controller data */
-static struct bfin5xx_spi_master bfin_spi0_info = {
-       .num_chipselect = 8,
-       .enable_dma = 1,  /* master has the ability to do dma transfer */
-       .pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0},
-};
-
-static struct platform_device bfin_spi0_device = {
-       .name = "bfin-spi",
-       .id = 0, /* Bus number */
-       .num_resources = ARRAY_SIZE(bfin_spi0_resource),
-       .resource = bfin_spi0_resource,
-       .dev = {
-               .platform_data = &bfin_spi0_info, /* Passed to driver */
-       },
-};
-#endif  /* spi master and devices */
-
-#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
-static struct platform_device rtc_device = {
-       .name = "rtc-bfin",
-       .id   = -1,
-};
-#endif
-
-#if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE)
-static struct platform_device hitachi_fb_device = {
-       .name = "hitachi-tx09",
-};
-#endif
-
-#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
-static struct resource smc91x_resources[] = {
-       {
-               .start = 0x20200300,
-               .end = 0x20200300 + 16,
-               .flags = IORESOURCE_MEM,
-       }, {
-               .start = IRQ_PF14,
-               .end = IRQ_PF14,
-               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-               },
-};
-
-static struct platform_device smc91x_device = {
-       .name = "smc91x",
-       .id = 0,
-       .num_resources = ARRAY_SIZE(smc91x_resources),
-       .resource = smc91x_resources,
-};
-#endif
-
-#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
-static struct resource isp1362_hcd_resources[] = {
-       {
-               .start = 0x20308000,
-               .end = 0x20308000,
-               .flags = IORESOURCE_MEM,
-       }, {
-               .start = 0x20308004,
-               .end = 0x20308004,
-               .flags = IORESOURCE_MEM,
-       }, {
-               .start = IRQ_PG15,
-               .end = IRQ_PG15,
-               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-       },
-};
-
-static struct isp1362_platform_data isp1362_priv = {
-       .sel15Kres = 1,
-       .clknotstop = 0,
-       .oc_enable = 0,
-       .int_act_high = 0,
-       .int_edge_triggered = 0,
-       .remote_wakeup_connected = 0,
-       .no_power_switching = 1,
-       .power_switching_mode = 0,
-};
-
-static struct platform_device isp1362_hcd_device = {
-       .name = "isp1362-hcd",
-       .id = 0,
-       .dev = {
-               .platform_data = &isp1362_priv,
-       },
-       .num_resources = ARRAY_SIZE(isp1362_hcd_resources),
-       .resource = isp1362_hcd_resources,
-};
-#endif
-
-#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
-static struct resource net2272_bfin_resources[] = {
-       {
-               .start = 0x20200000,
-               .end = 0x20200000 + 0x100,
-               .flags = IORESOURCE_MEM,
-       }, {
-               .start = IRQ_PH14,
-               .end = IRQ_PH14,
-               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-       },
-};
-
-static struct platform_device net2272_bfin_device = {
-       .name = "net2272",
-       .id = -1,
-       .num_resources = ARRAY_SIZE(net2272_bfin_resources),
-       .resource = net2272_bfin_resources,
-};
-#endif
-
-static struct resource bfin_gpios_resources = {
-       .start = 0,
-       .end   = MAX_BLACKFIN_GPIOS - 1,
-       .flags = IORESOURCE_IRQ,
-};
-
-static struct platform_device bfin_gpios_device = {
-       .name = "simple-gpio",
-       .id = -1,
-       .num_resources = 1,
-       .resource = &bfin_gpios_resources,
-};
-
-#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
-static struct mtd_partition cm_partitions[] = {
-       {
-               .name   = "bootloader(nor)",
-               .size   = 0x40000,
-               .offset = 0,
-       }, {
-               .name   = "linux kernel(nor)",
-               .size   = 0xE0000,
-               .offset = MTDPART_OFS_APPEND,
-       }, {
-               .name   = "file system(nor)",
-               .size   = MTDPART_SIZ_FULL,
-               .offset = MTDPART_OFS_APPEND,
-       }
-};
-
-static struct physmap_flash_data cm_flash_data = {
-       .width    = 2,
-       .parts    = cm_partitions,
-       .nr_parts = ARRAY_SIZE(cm_partitions),
-};
-
-static unsigned cm_flash_gpios[] = { GPIO_PF4 };
-
-static struct resource cm_flash_resource[] = {
-       {
-               .name  = "cfi_probe",
-               .start = 0x20000000,
-               .end   = 0x201fffff,
-               .flags = IORESOURCE_MEM,
-       }, {
-               .start = (unsigned long)cm_flash_gpios,
-               .end   = ARRAY_SIZE(cm_flash_gpios),
-               .flags = IORESOURCE_IRQ,
-       }
-};
-
-static struct platform_device cm_flash_device = {
-       .name          = "gpio-addr-flash",
-       .id            = 0,
-       .dev = {
-               .platform_data = &cm_flash_data,
-       },
-       .num_resources = ARRAY_SIZE(cm_flash_resource),
-       .resource      = cm_flash_resource,
-};
-#endif
-
-#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
-       {
-               .start = 0xFFC00400,
-               .end = 0xFFC004FF,
-               .flags = IORESOURCE_MEM,
-       }, {
-               .start = 0xFFC02000,
-               .end = 0xFFC020FF,
-               .flags = IORESOURCE_MEM,
-       },
-};
-
-static struct platform_device bfin_uart_device = {
-       .name = "bfin-uart",
-       .id = 1,
-       .num_resources = ARRAY_SIZE(bfin_uart_resources),
-       .resource = bfin_uart_resources,
-};
-#endif
-
-#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
-#ifdef CONFIG_BFIN_SIR0
-static struct resource bfin_sir0_resources[] = {
-       {
-               .start = 0xFFC00400,
-               .end = 0xFFC004FF,
-               .flags = IORESOURCE_MEM,
-       },
-       {
-               .start = IRQ_UART0_RX,
-               .end = IRQ_UART0_RX+1,
-               .flags = IORESOURCE_IRQ,
-       },
-       {
-               .start = CH_UART0_RX,
-               .end = CH_UART0_RX+1,
-               .flags = IORESOURCE_DMA,
-       },
-};
-static struct platform_device bfin_sir0_device = {
-       .name = "bfin_sir",
-       .id = 0,
-       .num_resources = ARRAY_SIZE(bfin_sir0_resources),
-       .resource = bfin_sir0_resources,
-};
-#endif
-#ifdef CONFIG_BFIN_SIR1
-static struct resource bfin_sir1_resources[] = {
-       {
-               .start = 0xFFC02000,
-               .end = 0xFFC020FF,
-               .flags = IORESOURCE_MEM,
-       },
-       {
-               .start = IRQ_UART1_RX,
-               .end = IRQ_UART1_RX+1,
-               .flags = IORESOURCE_IRQ,
-       },
-       {
-               .start = CH_UART1_RX,
-               .end = CH_UART1_RX+1,
-               .flags = IORESOURCE_DMA,
-       },
-};
-static struct platform_device bfin_sir1_device = {
-       .name = "bfin_sir",
-       .id = 1,
-       .num_resources = ARRAY_SIZE(bfin_sir1_resources),
-       .resource = bfin_sir1_resources,
-};
-#endif
-#endif
-
-#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
-static struct resource bfin_twi0_resource[] = {
-       [0] = {
-               .start = TWI0_REGBASE,
-               .end   = TWI0_REGBASE,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_TWI,
-               .end   = IRQ_TWI,
-               .flags = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device i2c_bfin_twi_device = {
-       .name = "i2c-bfin-twi",
-       .id = 0,
-       .num_resources = ARRAY_SIZE(bfin_twi0_resource),
-       .resource = bfin_twi0_resource,
-};
-#endif
-
-#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
-static struct platform_device bfin_sport0_uart_device = {
-       .name = "bfin-sport-uart",
-       .id = 0,
-};
-
-static struct platform_device bfin_sport1_uart_device = {
-       .name = "bfin-sport-uart",
-       .id = 1,
-};
-#endif
-
-#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
-static struct platform_device bfin_mii_bus = {
-       .name = "bfin_mii_bus",
-};
-
-static struct platform_device bfin_mac_device = {
-       .name = "bfin_mac",
-       .dev.platform_data = &bfin_mii_bus,
-};
-#endif
-
-#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
-#define PATA_INT       IRQ_PF14
-
-static struct pata_platform_info bfin_pata_platform_data = {
-       .ioport_shift = 2,
-       .irq_type = IRQF_TRIGGER_HIGH | IRQF_DISABLED,
-};
-
-static struct resource bfin_pata_resources[] = {
-       {
-               .start = 0x2030C000,
-               .end = 0x2030C01F,
-               .flags = IORESOURCE_MEM,
-       },
-       {
-               .start = 0x2030D018,
-               .end = 0x2030D01B,
-               .flags = IORESOURCE_MEM,
-       },
-       {
-               .start = PATA_INT,
-               .end = PATA_INT,
-               .flags = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device bfin_pata_device = {
-       .name = "pata_platform",
-       .id = -1,
-       .num_resources = ARRAY_SIZE(bfin_pata_resources),
-       .resource = bfin_pata_resources,
-       .dev = {
-               .platform_data = &bfin_pata_platform_data,
-       }
-};
-#endif
-
-static const unsigned int cclk_vlev_datasheet[] =
-{
-       VRPAIR(VLEV_085, 250000000),
-       VRPAIR(VLEV_090, 376000000),
-       VRPAIR(VLEV_095, 426000000),
-       VRPAIR(VLEV_100, 426000000),
-       VRPAIR(VLEV_105, 476000000),
-       VRPAIR(VLEV_110, 476000000),
-       VRPAIR(VLEV_115, 476000000),
-       VRPAIR(VLEV_120, 500000000),
-       VRPAIR(VLEV_125, 533000000),
-       VRPAIR(VLEV_130, 600000000),
-};
-
-static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
-       .tuple_tab = cclk_vlev_datasheet,
-       .tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
-       .vr_settling_time = 25 /* us */,
-};
-
-static struct platform_device bfin_dpmc = {
-       .name = "bfin dpmc",
-       .dev = {
-               .platform_data = &bfin_dmpc_vreg_data,
-       },
-};
-
-static struct platform_device *cm_bf537_devices[] __initdata = {
-
-       &bfin_dpmc,
-
-#if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE)
-       &hitachi_fb_device,
-#endif
-
-#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
-       &rtc_device,
-#endif
-
-#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-       &bfin_uart_device,
-#endif
-
-#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
-#ifdef CONFIG_BFIN_SIR0
-       &bfin_sir0_device,
-#endif
-#ifdef CONFIG_BFIN_SIR1
-       &bfin_sir1_device,
-#endif
-#endif
-
-#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
-       &i2c_bfin_twi_device,
-#endif
-
-#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
-       &bfin_sport0_uart_device,
-       &bfin_sport1_uart_device,
-#endif
-
-#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
-       &isp1362_hcd_device,
-#endif
-
-#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
-       &smc91x_device,
-#endif
-
-#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
-       &bfin_mii_bus,
-       &bfin_mac_device,
-#endif
-
-#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
-       &net2272_bfin_device,
-#endif
-
-#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
-       &bfin_spi0_device,
-#endif
-
-#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
-       &bfin_pata_device,
-#endif
-
-#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
-       &cm_flash_device,
-#endif
-
-       &bfin_gpios_device,
-};
-
-static int __init cm_bf537_init(void)
-{
-       printk(KERN_INFO "%s(): registering device resources\n", __func__);
-       platform_add_devices(cm_bf537_devices, ARRAY_SIZE(cm_bf537_devices));
-#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
-       spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
-#endif
-
-#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
-       irq_desc[PATA_INT].status |= IRQ_NOAUTOEN;
-#endif
-       return 0;
-}
-
-arch_initcall(cm_bf537_init);
-
-void bfin_get_ether_addr(char *addr)
-{
-       random_ether_addr(addr);
-       printk(KERN_WARNING "%s:%s: Setting Ethernet MAC to a random one\n", __FILE__, __func__);
-}
-EXPORT_SYMBOL(bfin_get_ether_addr);
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537e.c b/arch/blackfin/mach-bf537/boards/cm_bf537e.c
new file mode 100644 (file)
index 0000000..87acb7d
--- /dev/null
@@ -0,0 +1,727 @@
+/*
+ * File:         arch/blackfin/mach-bf537/boards/cm_bf537.c
+ * Based on:     arch/blackfin/mach-bf533/boards/ezkit.c
+ * Author:       Aidan Williams <aidan@nicta.com.au>
+ *
+ * Created:      2005
+ * Description:  Board description file
+ *
+ * Modified:
+ *               Copyright 2005 National ICT Australia (NICTA)
+ *               Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/device.h>
+#include <linux/etherdevice.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+#include <linux/usb/isp1362.h>
+#endif
+#include <linux/ata_platform.h>
+#include <linux/irq.h>
+#include <asm/dma.h>
+#include <asm/bfin5xx_spi.h>
+#include <asm/portmux.h>
+#include <asm/dpmc.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+const char bfin_board_name[] = "Bluetechnix CM BF537E";
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+/* all SPI peripherals info goes here */
+
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition bfin_spi_flash_partitions[] = {
+       {
+               .name = "bootloader(spi)",
+               .size = 0x00020000,
+               .offset = 0,
+               .mask_flags = MTD_CAP_ROM
+       }, {
+               .name = "linux kernel(spi)",
+               .size = 0xe0000,
+               .offset = 0x20000
+       }, {
+               .name = "file system(spi)",
+               .size = 0x700000,
+               .offset = 0x00100000,
+       }
+};
+
+static struct flash_platform_data bfin_spi_flash_data = {
+       .name = "m25p80",
+       .parts = bfin_spi_flash_partitions,
+       .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
+       .type = "m25p64",
+};
+
+/* SPI flash chip (m25p64) */
+static struct bfin5xx_spi_chip spi_flash_chip_info = {
+       .enable_dma = 0,         /* use dma transfer with this chip*/
+       .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_BFIN_SPI_ADC) || defined(CONFIG_BFIN_SPI_ADC_MODULE)
+/* SPI ADC chip */
+static struct bfin5xx_spi_chip spi_adc_chip_info = {
+       .enable_dma = 1,         /* use dma transfer with this chip*/
+       .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
+       .enable_dma = 0,
+       .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
+static struct bfin5xx_spi_chip  mmc_spi_chip_info = {
+       .enable_dma = 0,
+       .bits_per_word = 8,
+};
+#endif
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+       {
+               /* the modalias must be the same as spi device driver name */
+               .modalias = "m25p80", /* Name of spi_driver for this device */
+               .max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0, /* Framework bus number */
+               .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/
+               .platform_data = &bfin_spi_flash_data,
+               .controller_data = &spi_flash_chip_info,
+               .mode = SPI_MODE_3,
+       },
+#endif
+
+#if defined(CONFIG_BFIN_SPI_ADC) || defined(CONFIG_BFIN_SPI_ADC_MODULE)
+       {
+               .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
+               .max_speed_hz = 6250000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0, /* Framework bus number */
+               .chip_select = 1, /* Framework chip select. */
+               .platform_data = NULL, /* No spi_driver specific config */
+               .controller_data = &spi_adc_chip_info,
+       },
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+       {
+               .modalias = "ad1836",
+               .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0,
+               .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+               .controller_data = &ad1836_spi_chip_info,
+       },
+#endif
+
+#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
+       {
+               .modalias = "mmc_spi",
+               .max_speed_hz = 20000000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0,
+               .chip_select = 1,
+               .controller_data = &mmc_spi_chip_info,
+               .mode = SPI_MODE_3,
+       },
+#endif
+};
+
+/* SPI (0) */
+static struct resource bfin_spi0_resource[] = {
+       [0] = {
+               .start = SPI0_REGBASE,
+               .end   = SPI0_REGBASE + 0xFF,
+               .flags = IORESOURCE_MEM,
+               },
+       [1] = {
+               .start = CH_SPI,
+               .end   = CH_SPI,
+               .flags = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start = IRQ_SPI,
+               .end   = IRQ_SPI,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+/* SPI controller data */
+static struct bfin5xx_spi_master bfin_spi0_info = {
+       .num_chipselect = 8,
+       .enable_dma = 1,  /* master has the ability to do dma transfer */
+       .pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0},
+};
+
+static struct platform_device bfin_spi0_device = {
+       .name = "bfin-spi",
+       .id = 0, /* Bus number */
+       .num_resources = ARRAY_SIZE(bfin_spi0_resource),
+       .resource = bfin_spi0_resource,
+       .dev = {
+               .platform_data = &bfin_spi0_info, /* Passed to driver */
+       },
+};
+#endif  /* spi master and devices */
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+static struct platform_device rtc_device = {
+       .name = "rtc-bfin",
+       .id   = -1,
+};
+#endif
+
+#if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE)
+static struct platform_device hitachi_fb_device = {
+       .name = "hitachi-tx09",
+};
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+#include <linux/smc91x.h>
+
+static struct smc91x_platdata smc91x_info = {
+       .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+       .leda = RPC_LED_100_10,
+       .ledb = RPC_LED_TX_RX,
+};
+
+static struct resource smc91x_resources[] = {
+       {
+               .start = 0x20200300,
+               .end = 0x20200300 + 16,
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = IRQ_PF14,
+               .end = IRQ_PF14,
+               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+               },
+};
+
+static struct platform_device smc91x_device = {
+       .name = "smc91x",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(smc91x_resources),
+       .resource = smc91x_resources,
+       .dev    = {
+               .platform_data  = &smc91x_info,
+       },
+};
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+static struct resource isp1362_hcd_resources[] = {
+       {
+               .start = 0x20308000,
+               .end = 0x20308000,
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = 0x20308004,
+               .end = 0x20308004,
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = IRQ_PG15,
+               .end = IRQ_PG15,
+               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+       },
+};
+
+static struct isp1362_platform_data isp1362_priv = {
+       .sel15Kres = 1,
+       .clknotstop = 0,
+       .oc_enable = 0,
+       .int_act_high = 0,
+       .int_edge_triggered = 0,
+       .remote_wakeup_connected = 0,
+       .no_power_switching = 1,
+       .power_switching_mode = 0,
+};
+
+static struct platform_device isp1362_hcd_device = {
+       .name = "isp1362-hcd",
+       .id = 0,
+       .dev = {
+               .platform_data = &isp1362_priv,
+       },
+       .num_resources = ARRAY_SIZE(isp1362_hcd_resources),
+       .resource = isp1362_hcd_resources,
+};
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+static struct resource net2272_bfin_resources[] = {
+       {
+               .start = 0x20300000,
+               .end = 0x20300000 + 0x100,
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = IRQ_PG13,
+               .end = IRQ_PG13,
+               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+       },
+};
+
+static struct platform_device net2272_bfin_device = {
+       .name = "net2272",
+       .id = -1,
+       .num_resources = ARRAY_SIZE(net2272_bfin_resources),
+       .resource = net2272_bfin_resources,
+};
+#endif
+
+static struct resource bfin_gpios_resources = {
+       .start = 0,
+       .end   = MAX_BLACKFIN_GPIOS - 1,
+       .flags = IORESOURCE_IRQ,
+};
+
+static struct platform_device bfin_gpios_device = {
+       .name = "simple-gpio",
+       .id = -1,
+       .num_resources = 1,
+       .resource = &bfin_gpios_resources,
+};
+
+#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
+static struct mtd_partition cm_partitions[] = {
+       {
+               .name   = "bootloader(nor)",
+               .size   = 0x40000,
+               .offset = 0,
+       }, {
+               .name   = "linux kernel(nor)",
+               .size   = 0x100000,
+               .offset = MTDPART_OFS_APPEND,
+       }, {
+               .name   = "file system(nor)",
+               .size   = MTDPART_SIZ_FULL,
+               .offset = MTDPART_OFS_APPEND,
+       }
+};
+
+static struct physmap_flash_data cm_flash_data = {
+       .width    = 2,
+       .parts    = cm_partitions,
+       .nr_parts = ARRAY_SIZE(cm_partitions),
+};
+
+static unsigned cm_flash_gpios[] = { GPIO_PF4 };
+
+static struct resource cm_flash_resource[] = {
+       {
+               .name  = "cfi_probe",
+               .start = 0x20000000,
+               .end   = 0x201fffff,
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = (unsigned long)cm_flash_gpios,
+               .end   = ARRAY_SIZE(cm_flash_gpios),
+               .flags = IORESOURCE_IRQ,
+       }
+};
+
+static struct platform_device cm_flash_device = {
+       .name          = "gpio-addr-flash",
+       .id            = 0,
+       .dev = {
+               .platform_data = &cm_flash_data,
+       },
+       .num_resources = ARRAY_SIZE(cm_flash_resource),
+       .resource      = cm_flash_resource,
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
+       {
+               .start = 0xFFC00400,
+               .end = 0xFFC004FF,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_UART0_RX,
+               .end = IRQ_UART0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART0_ERROR,
+               .end = IRQ_UART0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART0_TX,
+               .end = CH_UART0_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART0_RX,
+               .end = CH_UART0_RX,
+               .flags = IORESOURCE_DMA,
+       },
+#ifdef CONFIG_BFIN_UART0_CTSRTS
+       {
+               /*
+                * Refer to arch/blackfin/mach-xxx/include/mach/gpio.h for the GPIO map.
+                */
+               .start = -1,
+               .end = -1,
+               .flags = IORESOURCE_IO,
+       },
+       {
+               /*
+                * Refer to arch/blackfin/mach-xxx/include/mach/gpio.h for the GPIO map.
+                */
+               .start = -1,
+               .end = -1,
+               .flags = IORESOURCE_IO,
+       },
+#endif
+};
+
+static struct platform_device bfin_uart0_device = {
+       .name = "bfin-uart",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+       .resource = bfin_uart0_resources,
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
+       {
+               .start = 0xFFC02000,
+               .end = 0xFFC020FF,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_UART1_RX,
+               .end = IRQ_UART1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART1_ERROR,
+               .end = IRQ_UART1_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART1_TX,
+               .end = CH_UART1_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART1_RX,
+               .end = CH_UART1_RX,
+               .flags = IORESOURCE_DMA,
+       },
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+       {
+               /*
+                * Refer to arch/blackfin/mach-xxx/include/mach/gpio.h for the GPIO map.
+                */
+               .start = -1,
+               .end = -1,
+               .flags = IORESOURCE_IO,
+       },
+       {
+               /*
+                * Refer to arch/blackfin/mach-xxx/include/mach/gpio.h for the GPIO map.
+                */
+               .start = -1,
+               .end = -1,
+               .flags = IORESOURCE_IO,
+       },
+#endif
+};
+
+static struct platform_device bfin_uart1_device = {
+       .name = "bfin-uart",
+       .id = 1,
+       .num_resources = ARRAY_SIZE(bfin_uart1_resources),
+       .resource = bfin_uart1_resources,
+};
+#endif
+#endif
+
+#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
+#ifdef CONFIG_BFIN_SIR0
+static struct resource bfin_sir0_resources[] = {
+       {
+               .start = 0xFFC00400,
+               .end = 0xFFC004FF,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_UART0_RX,
+               .end = IRQ_UART0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART0_RX,
+               .end = CH_UART0_RX+1,
+               .flags = IORESOURCE_DMA,
+       },
+};
+static struct platform_device bfin_sir0_device = {
+       .name = "bfin_sir",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_sir0_resources),
+       .resource = bfin_sir0_resources,
+};
+#endif
+#ifdef CONFIG_BFIN_SIR1
+static struct resource bfin_sir1_resources[] = {
+       {
+               .start = 0xFFC02000,
+               .end = 0xFFC020FF,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_UART1_RX,
+               .end = IRQ_UART1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART1_RX,
+               .end = CH_UART1_RX+1,
+               .flags = IORESOURCE_DMA,
+       },
+};
+static struct platform_device bfin_sir1_device = {
+       .name = "bfin_sir",
+       .id = 1,
+       .num_resources = ARRAY_SIZE(bfin_sir1_resources),
+       .resource = bfin_sir1_resources,
+};
+#endif
+#endif
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+static struct resource bfin_twi0_resource[] = {
+       [0] = {
+               .start = TWI0_REGBASE,
+               .end   = TWI0_REGBASE,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_TWI,
+               .end   = IRQ_TWI,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device i2c_bfin_twi_device = {
+       .name = "i2c-bfin-twi",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_twi0_resource),
+       .resource = bfin_twi0_resource,
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+static struct platform_device bfin_sport0_uart_device = {
+       .name = "bfin-sport-uart",
+       .id = 0,
+};
+
+static struct platform_device bfin_sport1_uart_device = {
+       .name = "bfin-sport-uart",
+       .id = 1,
+};
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static struct platform_device bfin_mii_bus = {
+       .name = "bfin_mii_bus",
+};
+
+static struct platform_device bfin_mac_device = {
+       .name = "bfin_mac",
+       .dev.platform_data = &bfin_mii_bus,
+};
+#endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+#define PATA_INT       IRQ_PF14
+
+static struct pata_platform_info bfin_pata_platform_data = {
+       .ioport_shift = 2,
+       .irq_type = IRQF_TRIGGER_HIGH | IRQF_DISABLED,
+};
+
+static struct resource bfin_pata_resources[] = {
+       {
+               .start = 0x2030C000,
+               .end = 0x2030C01F,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = 0x2030D018,
+               .end = 0x2030D01B,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = PATA_INT,
+               .end = PATA_INT,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bfin_pata_device = {
+       .name = "pata_platform",
+       .id = -1,
+       .num_resources = ARRAY_SIZE(bfin_pata_resources),
+       .resource = bfin_pata_resources,
+       .dev = {
+               .platform_data = &bfin_pata_platform_data,
+       }
+};
+#endif
+
+static const unsigned int cclk_vlev_datasheet[] =
+{
+       VRPAIR(VLEV_085, 250000000),
+       VRPAIR(VLEV_090, 376000000),
+       VRPAIR(VLEV_095, 426000000),
+       VRPAIR(VLEV_100, 426000000),
+       VRPAIR(VLEV_105, 476000000),
+       VRPAIR(VLEV_110, 476000000),
+       VRPAIR(VLEV_115, 476000000),
+       VRPAIR(VLEV_120, 500000000),
+       VRPAIR(VLEV_125, 533000000),
+       VRPAIR(VLEV_130, 600000000),
+};
+
+static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
+       .tuple_tab = cclk_vlev_datasheet,
+       .tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
+       .vr_settling_time = 25 /* us */,
+};
+
+static struct platform_device bfin_dpmc = {
+       .name = "bfin dpmc",
+       .dev = {
+               .platform_data = &bfin_dmpc_vreg_data,
+       },
+};
+
+static struct platform_device *cm_bf537e_devices[] __initdata = {
+
+       &bfin_dpmc,
+
+#if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE)
+       &hitachi_fb_device,
+#endif
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+       &rtc_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       &bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
+#ifdef CONFIG_BFIN_SIR0
+       &bfin_sir0_device,
+#endif
+#ifdef CONFIG_BFIN_SIR1
+       &bfin_sir1_device,
+#endif
+#endif
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+       &i2c_bfin_twi_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+       &bfin_sport0_uart_device,
+       &bfin_sport1_uart_device,
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+       &isp1362_hcd_device,
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+       &smc91x_device,
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+       &bfin_mii_bus,
+       &bfin_mac_device,
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+       &net2272_bfin_device,
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+       &bfin_spi0_device,
+#endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+       &bfin_pata_device,
+#endif
+
+#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
+       &cm_flash_device,
+#endif
+
+       &bfin_gpios_device,
+};
+
+static int __init cm_bf537e_init(void)
+{
+       printk(KERN_INFO "%s(): registering device resources\n", __func__);
+       platform_add_devices(cm_bf537e_devices, ARRAY_SIZE(cm_bf537e_devices));
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+       spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
+#endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+       irq_desc[PATA_INT].status |= IRQ_NOAUTOEN;
+#endif
+       return 0;
+}
+
+arch_initcall(cm_bf537e_init);
+
+void bfin_get_ether_addr(char *addr)
+{
+       random_ether_addr(addr);
+       printk(KERN_WARNING "%s:%s: Setting Ethernet MAC to a random one\n", __FILE__, __func__);
+}
+EXPORT_SYMBOL(bfin_get_ether_addr);
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537u.c b/arch/blackfin/mach-bf537/boards/cm_bf537u.c
new file mode 100644 (file)
index 0000000..8219dc3
--- /dev/null
@@ -0,0 +1,633 @@
+/*
+ * File:         arch/blackfin/mach-bf537/boards/cm_bf537u.c
+ * Based on:     arch/blackfin/mach-bf533/boards/ezkit.c
+ * Author:       Aidan Williams <aidan@nicta.com.au>
+ *
+ * Created:      2005
+ * Description:  Board description file
+ *
+ * Modified:
+ *               Copyright 2005 National ICT Australia (NICTA)
+ *               Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/device.h>
+#include <linux/etherdevice.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+#include <linux/usb/isp1362.h>
+#endif
+#include <linux/ata_platform.h>
+#include <linux/irq.h>
+#include <asm/dma.h>
+#include <asm/bfin5xx_spi.h>
+#include <asm/portmux.h>
+#include <asm/dpmc.h>
+#include <linux/spi/mmc_spi.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+const char bfin_board_name[] = "Bluetechnix CM BF537U";
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+/* all SPI peripherals info goes here */
+
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition bfin_spi_flash_partitions[] = {
+       {
+               .name = "bootloader(spi)",
+               .size = 0x00020000,
+               .offset = 0,
+               .mask_flags = MTD_CAP_ROM
+       }, {
+               .name = "linux kernel(spi)",
+               .size = 0xe0000,
+               .offset = 0x20000
+       }, {
+               .name = "file system(spi)",
+               .size = 0x700000,
+               .offset = 0x00100000,
+       }
+};
+
+static struct flash_platform_data bfin_spi_flash_data = {
+       .name = "m25p80",
+       .parts = bfin_spi_flash_partitions,
+       .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
+       .type = "m25p64",
+};
+
+/* SPI flash chip (m25p64) */
+static struct bfin5xx_spi_chip spi_flash_chip_info = {
+       .enable_dma = 0,         /* use dma transfer with this chip*/
+       .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_BFIN_SPI_ADC) || defined(CONFIG_BFIN_SPI_ADC_MODULE)
+/* SPI ADC chip */
+static struct bfin5xx_spi_chip spi_adc_chip_info = {
+       .enable_dma = 1,         /* use dma transfer with this chip*/
+       .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
+       .enable_dma = 0,
+       .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
+static struct bfin5xx_spi_chip  mmc_spi_chip_info = {
+       .enable_dma = 0,
+       .bits_per_word = 8,
+};
+#endif
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+       {
+               /* the modalias must be the same as spi device driver name */
+               .modalias = "m25p80", /* Name of spi_driver for this device */
+               .max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0, /* Framework bus number */
+               .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/
+               .platform_data = &bfin_spi_flash_data,
+               .controller_data = &spi_flash_chip_info,
+               .mode = SPI_MODE_3,
+       },
+#endif
+
+#if defined(CONFIG_BFIN_SPI_ADC) || defined(CONFIG_BFIN_SPI_ADC_MODULE)
+       {
+               .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
+               .max_speed_hz = 6250000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0, /* Framework bus number */
+               .chip_select = 1, /* Framework chip select. */
+               .platform_data = NULL, /* No spi_driver specific config */
+               .controller_data = &spi_adc_chip_info,
+       },
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+       {
+               .modalias = "ad1836",
+               .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0,
+               .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+               .controller_data = &ad1836_spi_chip_info,
+       },
+#endif
+
+#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
+       {
+               .modalias = "mmc_spi",
+               .max_speed_hz = 20000000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0,
+               .chip_select = 1,
+               .controller_data = &mmc_spi_chip_info,
+               .mode = SPI_MODE_3,
+       },
+#endif
+};
+
+/* SPI (0) */
+static struct resource bfin_spi0_resource[] = {
+       [0] = {
+               .start = SPI0_REGBASE,
+               .end   = SPI0_REGBASE + 0xFF,
+               .flags = IORESOURCE_MEM,
+               },
+       [1] = {
+               .start = CH_SPI,
+               .end   = CH_SPI,
+               .flags = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start = IRQ_SPI,
+               .end   = IRQ_SPI,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+/* SPI controller data */
+static struct bfin5xx_spi_master bfin_spi0_info = {
+       .num_chipselect = 8,
+       .enable_dma = 1,  /* master has the ability to do dma transfer */
+       .pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0},
+};
+
+static struct platform_device bfin_spi0_device = {
+       .name = "bfin-spi",
+       .id = 0, /* Bus number */
+       .num_resources = ARRAY_SIZE(bfin_spi0_resource),
+       .resource = bfin_spi0_resource,
+       .dev = {
+               .platform_data = &bfin_spi0_info, /* Passed to driver */
+       },
+};
+#endif  /* spi master and devices */
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+static struct platform_device rtc_device = {
+       .name = "rtc-bfin",
+       .id   = -1,
+};
+#endif
+
+#if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE)
+static struct platform_device hitachi_fb_device = {
+       .name = "hitachi-tx09",
+};
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+#include <linux/smc91x.h>
+
+static struct smc91x_platdata smc91x_info = {
+       .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+       .leda = RPC_LED_100_10,
+       .ledb = RPC_LED_TX_RX,
+};
+
+static struct resource smc91x_resources[] = {
+       {
+               .start = 0x20200300,
+               .end = 0x20200300 + 16,
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = IRQ_PF14,
+               .end = IRQ_PF14,
+               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+               },
+};
+
+static struct platform_device smc91x_device = {
+       .name = "smc91x",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(smc91x_resources),
+       .resource = smc91x_resources,
+       .dev    = {
+               .platform_data  = &smc91x_info,
+       },
+};
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+static struct resource isp1362_hcd_resources[] = {
+       {
+               .start = 0x20308000,
+               .end = 0x20308000,
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = 0x20308004,
+               .end = 0x20308004,
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = IRQ_PG15,
+               .end = IRQ_PG15,
+               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+       },
+};
+
+static struct isp1362_platform_data isp1362_priv = {
+       .sel15Kres = 1,
+       .clknotstop = 0,
+       .oc_enable = 0,
+       .int_act_high = 0,
+       .int_edge_triggered = 0,
+       .remote_wakeup_connected = 0,
+       .no_power_switching = 1,
+       .power_switching_mode = 0,
+};
+
+static struct platform_device isp1362_hcd_device = {
+       .name = "isp1362-hcd",
+       .id = 0,
+       .dev = {
+               .platform_data = &isp1362_priv,
+       },
+       .num_resources = ARRAY_SIZE(isp1362_hcd_resources),
+       .resource = isp1362_hcd_resources,
+};
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+static struct resource net2272_bfin_resources[] = {
+       {
+               .start = 0x20200000,
+               .end = 0x20200000 + 0x100,
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = IRQ_PH14,
+               .end = IRQ_PH14,
+               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+       },
+};
+
+static struct platform_device net2272_bfin_device = {
+       .name = "net2272",
+       .id = -1,
+       .num_resources = ARRAY_SIZE(net2272_bfin_resources),
+       .resource = net2272_bfin_resources,
+};
+#endif
+
+static struct resource bfin_gpios_resources = {
+       .start = 0,
+       .end   = MAX_BLACKFIN_GPIOS - 1,
+       .flags = IORESOURCE_IRQ,
+};
+
+static struct platform_device bfin_gpios_device = {
+       .name = "simple-gpio",
+       .id = -1,
+       .num_resources = 1,
+       .resource = &bfin_gpios_resources,
+};
+
+#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
+static struct mtd_partition cm_partitions[] = {
+       {
+               .name   = "bootloader(nor)",
+               .size   = 0x40000,
+               .offset = 0,
+       }, {
+               .name   = "linux kernel(nor)",
+               .size   = 0x100000,
+               .offset = MTDPART_OFS_APPEND,
+       }, {
+               .name   = "file system(nor)",
+               .size   = MTDPART_SIZ_FULL,
+               .offset = MTDPART_OFS_APPEND,
+       }
+};
+
+static struct physmap_flash_data cm_flash_data = {
+       .width    = 2,
+       .parts    = cm_partitions,
+       .nr_parts = ARRAY_SIZE(cm_partitions),
+};
+
+static unsigned cm_flash_gpios[] = { GPIO_PH0 };
+
+static struct resource cm_flash_resource[] = {
+       {
+               .name  = "cfi_probe",
+               .start = 0x20000000,
+               .end   = 0x201fffff,
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = (unsigned long)cm_flash_gpios,
+               .end   = ARRAY_SIZE(cm_flash_gpios),
+               .flags = IORESOURCE_IRQ,
+       }
+};
+
+static struct platform_device cm_flash_device = {
+       .name          = "gpio-addr-flash",
+       .id            = 0,
+       .dev = {
+               .platform_data = &cm_flash_data,
+       },
+       .num_resources = ARRAY_SIZE(cm_flash_resource),
+       .resource      = cm_flash_resource,
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+static struct resource bfin_uart_resources[] = {
+       {
+               .start = 0xFFC00400,
+               .end = 0xFFC004FF,
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = 0xFFC02000,
+               .end = 0xFFC020FF,
+               .flags = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device bfin_uart_device = {
+       .name = "bfin-uart",
+       .id = 1,
+       .num_resources = ARRAY_SIZE(bfin_uart_resources),
+       .resource = bfin_uart_resources,
+};
+#endif
+
+#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
+#ifdef CONFIG_BFIN_SIR0
+static struct resource bfin_sir0_resources[] = {
+       {
+               .start = 0xFFC00400,
+               .end = 0xFFC004FF,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_UART0_RX,
+               .end = IRQ_UART0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART0_RX,
+               .end = CH_UART0_RX+1,
+               .flags = IORESOURCE_DMA,
+       },
+};
+static struct platform_device bfin_sir0_device = {
+       .name = "bfin_sir",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_sir0_resources),
+       .resource = bfin_sir0_resources,
+};
+#endif
+#ifdef CONFIG_BFIN_SIR1
+static struct resource bfin_sir1_resources[] = {
+       {
+               .start = 0xFFC02000,
+               .end = 0xFFC020FF,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_UART1_RX,
+               .end = IRQ_UART1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART1_RX,
+               .end = CH_UART1_RX+1,
+               .flags = IORESOURCE_DMA,
+       },
+};
+static struct platform_device bfin_sir1_device = {
+       .name = "bfin_sir",
+       .id = 1,
+       .num_resources = ARRAY_SIZE(bfin_sir1_resources),
+       .resource = bfin_sir1_resources,
+};
+#endif
+#endif
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+static struct resource bfin_twi0_resource[] = {
+       [0] = {
+               .start = TWI0_REGBASE,
+               .end   = TWI0_REGBASE,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_TWI,
+               .end   = IRQ_TWI,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device i2c_bfin_twi_device = {
+       .name = "i2c-bfin-twi",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_twi0_resource),
+       .resource = bfin_twi0_resource,
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+static struct platform_device bfin_sport0_uart_device = {
+       .name = "bfin-sport-uart",
+       .id = 0,
+};
+
+static struct platform_device bfin_sport1_uart_device = {
+       .name = "bfin-sport-uart",
+       .id = 1,
+};
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static struct platform_device bfin_mii_bus = {
+       .name = "bfin_mii_bus",
+};
+
+static struct platform_device bfin_mac_device = {
+       .name = "bfin_mac",
+       .dev.platform_data = &bfin_mii_bus,
+};
+#endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+#define PATA_INT       IRQ_PF14
+
+static struct pata_platform_info bfin_pata_platform_data = {
+       .ioport_shift = 2,
+       .irq_type = IRQF_TRIGGER_HIGH | IRQF_DISABLED,
+};
+
+static struct resource bfin_pata_resources[] = {
+       {
+               .start = 0x2030C000,
+               .end = 0x2030C01F,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = 0x2030D018,
+               .end = 0x2030D01B,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = PATA_INT,
+               .end = PATA_INT,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bfin_pata_device = {
+       .name = "pata_platform",
+       .id = -1,
+       .num_resources = ARRAY_SIZE(bfin_pata_resources),
+       .resource = bfin_pata_resources,
+       .dev = {
+               .platform_data = &bfin_pata_platform_data,
+       }
+};
+#endif
+
+static const unsigned int cclk_vlev_datasheet[] =
+{
+       VRPAIR(VLEV_085, 250000000),
+       VRPAIR(VLEV_090, 376000000),
+       VRPAIR(VLEV_095, 426000000),
+       VRPAIR(VLEV_100, 426000000),
+       VRPAIR(VLEV_105, 476000000),
+       VRPAIR(VLEV_110, 476000000),
+       VRPAIR(VLEV_115, 476000000),
+       VRPAIR(VLEV_120, 500000000),
+       VRPAIR(VLEV_125, 533000000),
+       VRPAIR(VLEV_130, 600000000),
+};
+
+static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
+       .tuple_tab = cclk_vlev_datasheet,
+       .tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
+       .vr_settling_time = 25 /* us */,
+};
+
+static struct platform_device bfin_dpmc = {
+       .name = "bfin dpmc",
+       .dev = {
+               .platform_data = &bfin_dmpc_vreg_data,
+       },
+};
+
+static struct platform_device *cm_bf537u_devices[] __initdata = {
+
+       &bfin_dpmc,
+
+#if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE)
+       &hitachi_fb_device,
+#endif
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+       &rtc_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+       &bfin_uart_device,
+#endif
+
+#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
+#ifdef CONFIG_BFIN_SIR0
+       &bfin_sir0_device,
+#endif
+#ifdef CONFIG_BFIN_SIR1
+       &bfin_sir1_device,
+#endif
+#endif
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+       &i2c_bfin_twi_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+       &bfin_sport0_uart_device,
+       &bfin_sport1_uart_device,
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+       &isp1362_hcd_device,
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+       &smc91x_device,
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+       &bfin_mii_bus,
+       &bfin_mac_device,
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+       &net2272_bfin_device,
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+       &bfin_spi0_device,
+#endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+       &bfin_pata_device,
+#endif
+
+#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
+       &cm_flash_device,
+#endif
+
+       &bfin_gpios_device,
+};
+
+static int __init cm_bf537u_init(void)
+{
+       printk(KERN_INFO "%s(): registering device resources\n", __func__);
+       platform_add_devices(cm_bf537u_devices, ARRAY_SIZE(cm_bf537u_devices));
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+       spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
+#endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+       irq_desc[PATA_INT].status |= IRQ_NOAUTOEN;
+#endif
+       return 0;
+}
+
+arch_initcall(cm_bf537u_init);
+
+void bfin_get_ether_addr(char *addr)
+{
+       random_ether_addr(addr);
+       printk(KERN_WARNING "%s:%s: Setting Ethernet MAC to a random one\n", __FILE__, __func__);
+}
+EXPORT_SYMBOL(bfin_get_ether_addr);
index 838240f151f5b79dc26e88152e9b7cc54fd9bde7..10b35b838bac659db57f841a0043101994523960 100644 (file)
@@ -92,6 +92,14 @@ static struct platform_device rtc_device = {
 #endif
 
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+#include <linux/smc91x.h>
+
+static struct smc91x_platdata smc91x_info = {
+       .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+       .leda = RPC_LED_100_10,
+       .ledb = RPC_LED_TX_RX,
+};
+
 static struct resource smc91x_resources[] = {
        {
                .name = "smc91x-regs",
@@ -110,6 +118,9 @@ static struct platform_device smc91x_device = {
        .id = 0,
        .num_resources = ARRAY_SIZE(smc91x_resources),
        .resource = smc91x_resources,
+       .dev    = {
+               .platform_data  = &smc91x_info,
+       },
 };
 #endif
 
@@ -282,13 +293,6 @@ static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
-static struct bfin5xx_spi_chip ad9960_spi_chip_info = {
-       .enable_dma = 0,
-       .bits_per_word = 16,
-};
-#endif
-
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
 static struct bfin5xx_spi_chip mmc_spi_chip_info = {
        .enable_dma = 0,
@@ -348,22 +352,13 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 #if defined(CONFIG_SND_BLACKFIN_AD1836) \
        || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
        {
-               .modalias = "ad1836-spi",
+               .modalias = "ad1836",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
                .bus_num = 0,
                .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
                .controller_data = &ad1836_spi_chip_info,
        },
 #endif
-#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
-       {
-               .modalias = "ad9960-spi",
-               .max_speed_hz = 10000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 0,
-               .chip_select = 1,
-               .controller_data = &ad9960_spi_chip_info,
-       },
-#endif
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
        {
                .modalias = "mmc_spi",
index bd656907b8c01588983d0f4e3c1cf267679d0c5c..9db6b40743e0ff052ffc2d6b124058332180b6da 100644 (file)
@@ -171,6 +171,14 @@ static struct platform_device rtc_device = {
 #endif
 
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+#include <linux/smc91x.h>
+
+static struct smc91x_platdata smc91x_info = {
+       .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+       .leda = RPC_LED_100_10,
+       .ledb = RPC_LED_TX_RX,
+};
+
 static struct resource smc91x_resources[] = {
        {
                .name = "smc91x-regs",
@@ -189,6 +197,9 @@ static struct platform_device smc91x_device = {
        .id = 0,
        .num_resources = ARRAY_SIZE(smc91x_resources),
        .resource = smc91x_resources,
+       .dev    = {
+               .platform_data  = &smc91x_info,
+       },
 };
 #endif
 
@@ -196,10 +207,15 @@ static struct platform_device smc91x_device = {
 static struct resource dm9000_resources[] = {
        [0] = {
                .start  = 0x203FB800,
-               .end    = 0x203FB800 + 8,
+               .end    = 0x203FB800 + 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
+               .start  = 0x203FB804,
+               .end    = 0x203FB804 + 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [2] = {
                .start  = IRQ_PF9,
                .end    = IRQ_PF9,
                .flags  = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE),
@@ -516,19 +532,135 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
-       || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
+       || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
        .enable_dma = 0,
        .bits_per_word = 16,
 };
 #endif
 
-#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
-static struct bfin5xx_spi_chip ad9960_spi_chip_info = {
+#if defined(CONFIG_SND_BF5XX_SOC_AD1938) \
+       || defined(CONFIG_SND_BF5XX_SOC_AD1938_MODULE)
+static struct bfin5xx_spi_chip ad1938_spi_chip_info = {
+       .enable_dma = 0,
+       .bits_per_word = 8,
+       .cs_gpio = GPIO_PF5,
+};
+#endif
+
+#if defined(CONFIG_INPUT_EVAL_AD7147EBZ)
+#include <linux/input.h>
+#include <linux/input/ad714x.h>
+static struct bfin5xx_spi_chip ad7147_spi_chip_info = {
        .enable_dma = 0,
        .bits_per_word = 16,
 };
+
+static struct ad714x_slider_plat slider_plat[] = {
+       {
+               .start_stage = 0,
+               .end_stage = 7,
+               .max_coord = 128,
+       },
+};
+
+static struct ad714x_button_plat button_plat[] = {
+       {
+               .keycode = BTN_FORWARD,
+               .l_mask = 0,
+               .h_mask = 0x600,
+       },
+       {
+               .keycode = BTN_LEFT,
+               .l_mask = 0,
+               .h_mask = 0x500,
+       },
+       {
+               .keycode = BTN_MIDDLE,
+               .l_mask = 0,
+               .h_mask = 0x800,
+       },
+       {
+               .keycode = BTN_RIGHT,
+               .l_mask = 0x100,
+               .h_mask = 0x400,
+       },
+       {
+               .keycode = BTN_BACK,
+               .l_mask = 0x200,
+               .h_mask = 0x400,
+       },
+};
+static struct ad714x_platform_data ad7147_platfrom_data = {
+       .slider_num = 1,
+       .button_num = 5,
+       .slider = slider_plat,
+       .button = button_plat,
+       .stage_cfg_reg =  {
+               {0xFBFF, 0x1FFF, 0, 0x2626, 1600, 1600, 1600, 1600},
+               {0xEFFF, 0x1FFF, 0, 0x2626, 1650, 1650, 1650, 1650},
+               {0xFFFF, 0x1FFE, 0, 0x2626, 1650, 1650, 1650, 1650},
+               {0xFFFF, 0x1FFB, 0, 0x2626, 1650, 1650, 1650, 1650},
+               {0xFFFF, 0x1FEF, 0, 0x2626, 1650, 1650, 1650, 1650},
+               {0xFFFF, 0x1FBF, 0, 0x2626, 1650, 1650, 1650, 1650},
+               {0xFFFF, 0x1EFF, 0, 0x2626, 1650, 1650, 1650, 1650},
+               {0xFFFF, 0x1BFF, 0, 0x2626, 1600, 1600, 1600, 1600},
+               {0xFF7B, 0x3FFF, 0x506,  0x2626, 1100, 1100, 1150, 1150},
+               {0xFDFE, 0x3FFF, 0x606,  0x2626, 1100, 1100, 1150, 1150},
+               {0xFEBA, 0x1FFF, 0x1400, 0x2626, 1200, 1200, 1300, 1300},
+               {0xFFEF, 0x1FFF, 0x0,    0x2626, 1100, 1100, 1150, 1150},
+       },
+       .sys_cfg_reg = {0x2B2, 0x0, 0x3233, 0x819, 0x832, 0xCFF, 0xCFF, 0x0},
+};
+#endif
+
+#if defined(CONFIG_INPUT_EVAL_AD7142EB)
+#include <linux/input.h>
+#include <linux/input/ad714x.h>
+static struct ad714x_button_plat button_plat[] = {
+       {
+               .keycode = BTN_1,
+               .l_mask = 0,
+               .h_mask = 0x1,
+       },
+       {
+               .keycode = BTN_2,
+               .l_mask = 0,
+               .h_mask = 0x2,
+       },
+       {
+               .keycode = BTN_3,
+               .l_mask = 0,
+               .h_mask = 0x4,
+       },
+       {
+               .keycode = BTN_4,
+               .l_mask = 0x0,
+               .h_mask = 0x8,
+       },
+};
+static struct ad714x_platform_data ad7142_platfrom_data = {
+       .button_num = 4,
+       .button = button_plat,
+       .stage_cfg_reg =  {
+               /* fixme: figure out right setting for all comoponent according
+                * to hardware feature of EVAL-AD7142EB board */
+               {0xE7FF, 0x3FFF, 0x0005, 0x2626, 0x01F4, 0x01F4, 0x028A, 0x028A},
+               {0xFDBF, 0x3FFF, 0x0001, 0x2626, 0x01F4, 0x01F4, 0x028A, 0x028A},
+               {0xFFFF, 0x2DFF, 0x0001, 0x2626, 0x01F4, 0x01F4, 0x028A, 0x028A},
+               {0xFFFF, 0x37BF, 0x0001, 0x2626, 0x01F4, 0x01F4, 0x028A, 0x028A},
+               {0xFFFF, 0x3FFF, 0x0000, 0x0606, 0x01F4, 0x01F4, 0x0320, 0x0320},
+               {0xFFFF, 0x3FFF, 0x0000, 0x0606, 0x01F4, 0x01F4, 0x0320, 0x0320},
+               {0xFFFF, 0x3FFF, 0x0000, 0x0606, 0x01F4, 0x01F4, 0x0320, 0x0320},
+               {0xFFFF, 0x3FFF, 0x0000, 0x0606, 0x01F4, 0x01F4, 0x0320, 0x0320},
+               {0xFFFF, 0x3FFF, 0x0000, 0x0606, 0x01F4, 0x01F4, 0x0320, 0x0320},
+               {0xFFFF, 0x3FFF, 0x0000, 0x0606, 0x01F4, 0x01F4, 0x0320, 0x0320},
+               {0xFFFF, 0x3FFF, 0x0000, 0x0606, 0x01F4, 0x01F4, 0x0320, 0x0320},
+               {0xFFFF, 0x3FFF, 0x0000, 0x0606, 0x01F4, 0x01F4, 0x0320, 0x0320},
+       },
+       .sys_cfg_reg = {0x0B2, 0x0, 0x690, 0x664, 0x290F, 0xF, 0xF, 0x0},
+};
 #endif
 
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
@@ -555,15 +687,7 @@ static struct mmc_spi_platform_data bfin_mmc_spi_pdata = {
 static struct bfin5xx_spi_chip  mmc_spi_chip_info = {
        .enable_dma = 0,
        .bits_per_word = 8,
-};
-#endif
-
-#if defined(CONFIG_PBX)
-static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
-       .ctl_reg        = 0x4, /* send zero */
-       .enable_dma     = 0,
-       .bits_per_word  = 8,
-       .cs_change_per_word = 1,
+       .pio_interrupt = 0,
 };
 #endif
 
@@ -743,25 +867,42 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        },
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
-       || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
+       || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
        {
-               .modalias = "ad1836-spi",
+               .modalias = "ad1836",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
                .bus_num = 0,
-               .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+               .chip_select = 4,/* CONFIG_SND_BLACKFIN_SPI_PFBIT */
                .controller_data = &ad1836_spi_chip_info,
+               .mode = SPI_MODE_3,
        },
 #endif
-#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
+
+#if defined(CONFIG_SND_BF5XX_SOC_AD1938) || defined(CONFIG_SND_BF5XX_SOC_AD1938_MODULE)
        {
-               .modalias = "ad9960-spi",
-               .max_speed_hz = 10000000,     /* max spi clock (SCK) speed in HZ */
+               .modalias = "ad1938",
+               .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
                .bus_num = 0,
-               .chip_select = 1,
-               .controller_data = &ad9960_spi_chip_info,
+               .chip_select = 0,/* CONFIG_SND_BLACKFIN_SPI_PFBIT */
+               .controller_data = &ad1938_spi_chip_info,
+               .mode = SPI_MODE_3,
        },
 #endif
+
+#if defined(CONFIG_INPUT_EVAL_AD7147EBZ)
+       {
+               .modalias = "ad714x_captouch",
+               .max_speed_hz = 1000000,     /* max spi clock (SCK) speed in HZ */
+               .irq = IRQ_PF4,
+               .bus_num = 0,
+               .chip_select = 5,
+               .mode = SPI_MODE_3,
+               .platform_data = &ad7147_platfrom_data,
+               .controller_data = &ad7147_spi_chip_info,
+       },
+#endif
+
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
        {
                .modalias = "mmc_spi",
@@ -773,24 +914,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
                .mode = SPI_MODE_3,
        },
 #endif
-#if defined(CONFIG_PBX)
-       {
-               .modalias = "fxs-spi",
-               .max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 0,
-               .chip_select = 8 - CONFIG_J11_JUMPER,
-               .controller_data = &spi_si3xxx_chip_info,
-               .mode = SPI_MODE_3,
-       },
-       {
-               .modalias = "fxo-spi",
-               .max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 0,
-               .chip_select = 8 - CONFIG_J19_JUMPER,
-               .controller_data = &spi_si3xxx_chip_info,
-               .mode = SPI_MODE_3,
-       },
-#endif
 #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
        {
                .modalias               = "ad7877",
@@ -864,6 +987,11 @@ static struct resource bfin_spi0_resource[] = {
        [1] = {
                .start = CH_SPI,
                .end   = CH_SPI,
+               .flags = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start = IRQ_SPI,
+               .end   = IRQ_SPI,
                .flags = IORESOURCE_IRQ,
        },
 };
@@ -1089,7 +1217,7 @@ static struct platform_device i2c_bfin_twi_device = {
 
 #if defined(CONFIG_KEYBOARD_ADP5588) || defined(CONFIG_KEYBOARD_ADP5588_MODULE)
 #include <linux/input.h>
-#include <linux/i2c/adp5588_keys.h>
+#include <linux/i2c/adp5588.h>
 static const unsigned short adp5588_keymap[ADP5588_KEYMAPSIZE] = {
        [0]      = KEY_GRAVE,
        [1]      = KEY_1,
@@ -1309,11 +1437,20 @@ static struct adp5520_platform_data adp5520_pdev_data = {
 
 #endif
 
+#if defined(CONFIG_GPIO_ADP5588) || defined(CONFIG_GPIO_ADP5588_MODULE)
+#include <linux/i2c/adp5588.h>
+static struct adp5588_gpio_platfrom_data adp5588_gpio_data = {
+       .gpio_start = 50,
+       .pullup_dis_mask = 0,
+};
+#endif
+
 static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
-#if defined(CONFIG_JOYSTICK_AD7142) || defined(CONFIG_JOYSTICK_AD7142_MODULE)
+#if defined(CONFIG_INPUT_EVAL_AD7142EB)
        {
-               I2C_BOARD_INFO("ad7142_joystick", 0x2C),
+               I2C_BOARD_INFO("ad7142_captouch", 0x2C),
                .irq = IRQ_PG5,
+               .platform_data = (void *)&ad7142_platfrom_data,
        },
 #endif
 #if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE)
@@ -1321,7 +1458,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
                I2C_BOARD_INFO("pcf8574_lcd", 0x22),
        },
 #endif
-#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE)
+#if defined(CONFIG_INPUT_PCF8574) || defined(CONFIG_INPUT_PCF8574_MODULE)
        {
                I2C_BOARD_INFO("pcf8574_keypad", 0x27),
                .irq = IRQ_PG6,
@@ -1355,6 +1492,12 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
                .platform_data = (void *)&adxl34x_info,
        },
 #endif
+#if defined(CONFIG_GPIO_ADP5588) || defined(CONFIG_GPIO_ADP5588_MODULE)
+       {
+               I2C_BOARD_INFO("adp5588-gpio", 0x34),
+               .platform_data = (void *)&adp5588_gpio_data,
+       },
+#endif
 };
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
@@ -1456,6 +1599,13 @@ static struct platform_device bfin_dpmc = {
        },
 };
 
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+static struct platform_device bfin_tdm = {
+       .name = "bfin-tdm",
+       /* TODO: add platform data here */
+};
+#endif
+
 static struct platform_device *stamp_devices[] __initdata = {
 
        &bfin_dpmc,
@@ -1561,6 +1711,10 @@ static struct platform_device *stamp_devices[] __initdata = {
 #if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
        &stamp_flash_device,
 #endif
+
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+       &bfin_tdm,
+#endif
 };
 
 static int __init stamp_init(void)
@@ -1572,11 +1726,6 @@ static int __init stamp_init(void)
        platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
        spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
 
-#if (defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)) \
-        && defined(PATA_INT)
-       irq_desc[PATA_INT].status |= IRQ_NOAUTOEN;
-#endif
-
        return 0;
 }
 
index e523e6e610d0b04f98b45aa4f049ea36f78053ac..61353f7bcb9e006c8c25f2a4504b125ed8a1d92e 100644 (file)
@@ -45,6 +45,7 @@
 #include <asm/bfin5xx_spi.h>
 #include <asm/portmux.h>
 #include <asm/dpmc.h>
+#include <linux/spi/mmc_spi.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
@@ -101,13 +102,6 @@ static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
-static struct bfin5xx_spi_chip ad9960_spi_chip_info = {
-       .enable_dma = 0,
-       .bits_per_word = 16,
-};
-#endif
-
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
 static struct bfin5xx_spi_chip mmc_spi_chip_info = {
        .enable_dma = 0,
@@ -142,7 +136,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 
 #if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
        {
-               .modalias = "ad1836-spi",
+               .modalias = "ad1836",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
                .bus_num = 0,
                .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
@@ -150,22 +144,12 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        },
 #endif
 
-#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
-       {
-               .modalias = "ad9960-spi",
-               .max_speed_hz = 10000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 0,
-               .chip_select = 1,
-               .controller_data = &ad9960_spi_chip_info,
-       },
-#endif
-
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
        {
                .modalias = "mmc_spi",
                .max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
                .bus_num = 0,
-               .chip_select = 5,
+               .chip_select = 1,
                .controller_data = &mmc_spi_chip_info,
                .mode = SPI_MODE_3,
        },
@@ -223,6 +207,14 @@ static struct platform_device hitachi_fb_device = {
 #endif
 
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+#include <linux/smc91x.h>
+
+static struct smc91x_platdata smc91x_info = {
+       .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+       .leda = RPC_LED_100_10,
+       .ledb = RPC_LED_TX_RX,
+};
+
 static struct resource smc91x_resources[] = {
        {
                .start = 0x20200300,
@@ -240,6 +232,9 @@ static struct platform_device smc91x_device = {
        .id = 0,
        .num_resources = ARRAY_SIZE(smc91x_resources),
        .resource = smc91x_resources,
+       .dev    = {
+               .platform_data  = &smc91x_info,
+       },
 };
 #endif
 
@@ -285,12 +280,12 @@ static struct platform_device isp1362_hcd_device = {
 #if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
 static struct resource net2272_bfin_resources[] = {
        {
-               .start = 0x20200000,
-               .end = 0x20200000 + 0x100,
+               .start = 0x20300000,
+               .end = 0x20300000 + 0x100,
                .flags = IORESOURCE_MEM,
        }, {
-               .start = IRQ_PH14,
-               .end = IRQ_PH14,
+               .start = IRQ_PG13,
+               .end = IRQ_PG13,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
        },
 };
@@ -324,7 +319,7 @@ static struct mtd_partition cm_partitions[] = {
                .offset = 0,
        }, {
                .name   = "linux kernel(nor)",
-               .size   = 0xE0000,
+               .size   = 0x100000,
                .offset = MTDPART_OFS_APPEND,
        }, {
                .name   = "file system(nor)",
index 81185051de91eeeb788662432e9173385511fe1b..d23fc0edf2b956cca2e15f63cb7e832f55c0dee0 100644 (file)
@@ -96,12 +96,12 @@ int channel2irq(unsigned int channel)
                ret_irq = IRQ_SPI;
                break;
 
-       case CH_UART_RX:
-               ret_irq = IRQ_UART_RX;
+       case CH_UART0_RX:
+               ret_irq = IRQ_UART0_RX;
                break;
 
-       case CH_UART_TX:
-               ret_irq = IRQ_UART_TX;
+       case CH_UART0_TX:
+               ret_irq = IRQ_UART0_TX;
                break;
 
        case CH_MEM_STREAM0_SRC:
index e66aa131f517d66ec5fe17588bf71d5f8c1cb7ef..f091ad2d8ea8dd23001bd598027e34aeb97b3598 100644 (file)
 /* Possible RETS Register Corruption when Subroutine Is under 5 Cycles in Duration */
 #define ANOMALY_05000371 (1)
 /* SSYNC Stalls Processor when Executed from Non-Cacheable Memory */
-#define ANOMALY_05000402 (__SILICON_REVISION__ >= 5)
+#define ANOMALY_05000402 (__SILICON_REVISION__ == 2)
 /* Level-Sensitive External GPIO Wakeups May Cause Indefinite Stall */
 #define ANOMALY_05000403 (1)
 /* Speculative Fetches Can Cause Undesired External FIFO Operations */
index f5e5015ad8317e13d1131164988ad0b2f443e005..9ee8834c8f1ad5aea3ab88b908eec58064c54370 100644 (file)
 #if !defined(__ASSEMBLY__)
 #include "cdefBF534.h"
 
-/* UART 0*/
-#define bfin_read_UART_THR() bfin_read_UART0_THR()
-#define bfin_write_UART_THR(val) bfin_write_UART0_THR(val)
-#define bfin_read_UART_RBR() bfin_read_UART0_RBR()
-#define bfin_write_UART_RBR(val) bfin_write_UART0_RBR(val)
-#define bfin_read_UART_DLL() bfin_read_UART0_DLL()
-#define bfin_write_UART_DLL(val) bfin_write_UART0_DLL(val)
-#define bfin_read_UART_IER() bfin_read_UART0_IER()
-#define bfin_write_UART_IER(val) bfin_write_UART0_IER(val)
-#define bfin_read_UART_DLH() bfin_read_UART0_DLH()
-#define bfin_write_UART_DLH(val) bfin_write_UART0_DLH(val)
-#define bfin_read_UART_IIR() bfin_read_UART0_IIR()
-#define bfin_write_UART_IIR(val) bfin_write_UART0_IIR(val)
-#define bfin_read_UART_LCR() bfin_read_UART0_LCR()
-#define bfin_write_UART_LCR(val) bfin_write_UART0_LCR(val)
-#define bfin_read_UART_MCR() bfin_read_UART0_MCR()
-#define bfin_write_UART_MCR(val) bfin_write_UART0_MCR(val)
-#define bfin_read_UART_LSR() bfin_read_UART0_LSR()
-#define bfin_write_UART_LSR(val) bfin_write_UART0_LSR(val)
-#define bfin_read_UART_SCR() bfin_read_UART0_SCR()
-#define bfin_write_UART_SCR(val) bfin_write_UART0_SCR(val)
-#define bfin_read_UART_GCTL() bfin_read_UART0_GCTL()
-#define bfin_write_UART_GCTL(val) bfin_write_UART0_GCTL(val)
-
 #if defined(CONFIG_BF537) || defined(CONFIG_BF536)
 #include "cdefBF537.h"
 #endif
 #endif
 
-/* MAP used DEFINES from BF533 to BF537 - so we don't need to change them in the driver, kernel, etc. */
-
-/* UART_IIR Register */
-#define STATUS(x)      ((x << 1) & 0x06)
-#define STATUS_P1      0x02
-#define STATUS_P0      0x01
-
-/* DMA Channel */
-#define bfin_read_CH_UART_RX() bfin_read_CH_UART0_RX()
-#define bfin_write_CH_UART_RX(val) bfin_write_CH_UART0_RX(val)
-#define CH_UART_RX CH_UART0_RX
-#define bfin_read_CH_UART_TX() bfin_read_CH_UART0_TX()
-#define bfin_write_CH_UART_TX(val) bfin_write_CH_UART0_TX(val)
-#define CH_UART_TX CH_UART0_TX
-
-/* System Interrupt Controller */
-#define bfin_read_IRQ_UART_RX() bfin_read_IRQ_UART0_RX()
-#define bfin_write_IRQ_UART_RX(val) bfin_write_IRQ_UART0_RX(val)
-#define IRQ_UART_RX IRQ_UART0_RX
-#define bfin_read_IRQ_UART_TX() bfin_read_IRQ_UART0_TX()
-#define bfin_write_IRQ_UART_TX(val) bfin_write_IRQ_UART0_TX(val)
-#define        IRQ_UART_TX IRQ_UART0_TX
-#define bfin_read_IRQ_UART_ERROR() bfin_read_IRQ_UART0_ERROR()
-#define bfin_write_IRQ_UART_ERROR(val) bfin_write_IRQ_UART0_ERROR(val)
-#define        IRQ_UART_ERROR IRQ_UART0_ERROR
-
-/* MMR Registers*/
-#define bfin_read_UART_THR() bfin_read_UART0_THR()
-#define bfin_write_UART_THR(val) bfin_write_UART0_THR(val)
-#define BFIN_UART_THR UART0_THR
-#define bfin_read_UART_RBR() bfin_read_UART0_RBR()
-#define bfin_write_UART_RBR(val) bfin_write_UART0_RBR(val)
-#define BFIN_UART_RBR UART0_RBR
-#define bfin_read_UART_DLL() bfin_read_UART0_DLL()
-#define bfin_write_UART_DLL(val) bfin_write_UART0_DLL(val)
-#define BFIN_UART_DLL UART0_DLL
-#define bfin_read_UART_IER() bfin_read_UART0_IER()
-#define bfin_write_UART_IER(val) bfin_write_UART0_IER(val)
-#define BFIN_UART_IER UART0_IER
-#define bfin_read_UART_DLH() bfin_read_UART0_DLH()
-#define bfin_write_UART_DLH(val) bfin_write_UART0_DLH(val)
-#define BFIN_UART_DLH UART0_DLH
-#define bfin_read_UART_IIR() bfin_read_UART0_IIR()
-#define bfin_write_UART_IIR(val) bfin_write_UART0_IIR(val)
-#define BFIN_UART_IIR UART0_IIR
-#define bfin_read_UART_LCR() bfin_read_UART0_LCR()
-#define bfin_write_UART_LCR(val) bfin_write_UART0_LCR(val)
-#define BFIN_UART_LCR UART0_LCR
-#define bfin_read_UART_MCR() bfin_read_UART0_MCR()
-#define bfin_write_UART_MCR(val) bfin_write_UART0_MCR(val)
-#define BFIN_UART_MCR UART0_MCR
-#define bfin_read_UART_LSR() bfin_read_UART0_LSR()
-#define bfin_write_UART_LSR(val) bfin_write_UART0_LSR(val)
-#define BFIN_UART_LSR UART0_LSR
-#define bfin_read_UART_SCR() bfin_read_UART0_SCR()
-#define bfin_write_UART_SCR(val) bfin_write_UART0_SCR(val)
-#define BFIN_UART_SCR  UART0_SCR
-#define bfin_read_UART_GCTL() bfin_read_UART0_GCTL()
-#define bfin_write_UART_GCTL(val) bfin_write_UART0_GCTL(val)
-#define BFIN_UART_GCTL UART0_GCTL
-
 #define BFIN_UART_NR_PORTS     2
 
 #define OFFSET_THR              0x00   /* Transmit Holding register            */
 #define OFFSET_SCR              0x1C   /* SCR Scratch Register                 */
 #define OFFSET_GCTL             0x24   /* Global Control Register              */
 
-/* DPMC*/
-#define bfin_read_STOPCK_OFF() bfin_read_STOPCK()
-#define bfin_write_STOPCK_OFF(val) bfin_write_STOPCK(val)
-#define STOPCK_OFF STOPCK
-
 /* PLL_DIV Masks                                                                                                       */
 #define CCLK_DIV1 CSEL_DIV1    /*          CCLK = VCO / 1                                  */
 #define CCLK_DIV2 CSEL_DIV2    /*          CCLK = VCO / 2                                  */
index 57695b4c3c0964c60413da1b7c55e889059282ae..f2ac3b0ebf2467bda9532e1ee3085308f183dfd8 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
+#include <linux/mtd/physmap.h>
 #include <linux/mtd/partitions.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
@@ -177,6 +178,14 @@ static struct platform_device bfin_sir2_device = {
  *  Driver needs to know address, irq and flag pin.
  */
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+#include <linux/smc91x.h>
+
+static struct smc91x_platdata smc91x_info = {
+       .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+       .leda = RPC_LED_100_10,
+       .ledb = RPC_LED_TX_RX,
+};
+
 static struct resource smc91x_resources[] = {
        {
                .name = "smc91x-regs",
@@ -194,6 +203,9 @@ static struct platform_device smc91x_device = {
        .id = 0,
        .num_resources = ARRAY_SIZE(smc91x_resources),
        .resource = smc91x_resources,
+       .dev    = {
+               .platform_data  = &smc91x_info,
+       },
 };
 #endif
 
@@ -390,6 +402,11 @@ static struct resource bfin_spi2_resource[] = {
        [1] = {
                .start = CH_SPI2,
                .end   = CH_SPI2,
+               .flags = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start = IRQ_SPI2,
+               .end   = IRQ_SPI2,
                .flags = IORESOURCE_IRQ,
        }
 };
@@ -550,6 +567,50 @@ static struct platform_device bfin_dpmc = {
        },
 };
 
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct mtd_partition ezkit_partitions[] = {
+       {
+               .name       = "bootloader(nor)",
+               .size       = 0x40000,
+               .offset     = 0,
+       }, {
+               .name       = "linux kernel(nor)",
+               .size       = 0x180000,
+               .offset     = MTDPART_OFS_APPEND,
+       }, {
+               .name       = "file system(nor)",
+               .size       = MTDPART_SIZ_FULL,
+               .offset     = MTDPART_OFS_APPEND,
+       }
+};
+
+static struct physmap_flash_data ezkit_flash_data = {
+       .width      = 2,
+       .parts      = ezkit_partitions,
+       .nr_parts   = ARRAY_SIZE(ezkit_partitions),
+};
+
+static struct resource ezkit_flash_resource = {
+       .start = 0x20000000,
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+       .end   = 0x202fffff,
+#else
+       .end   = 0x203fffff,
+#endif
+       .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device ezkit_flash_device = {
+       .name          = "physmap-flash",
+       .id            = 0,
+       .dev = {
+               .platform_data = &ezkit_flash_data,
+       },
+       .num_resources = 1,
+       .resource      = &ezkit_flash_resource,
+};
+#endif
+
 static struct platform_device *cm_bf538_devices[] __initdata = {
 
        &bfin_dpmc,
@@ -598,6 +659,10 @@ static struct platform_device *cm_bf538_devices[] __initdata = {
 #endif
 
        &bfin_gpios_device,
+
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+       &ezkit_flash_device,
+#endif
 };
 
 static int __init ezkit_init(void)
index 451cf8a82a42b0e1edbb3525232cf485587158af..26b76083e14c084fb2cd48622573ffeb70566b29 100644 (file)
 /* GPIO Pins PC1 and PC4 Can Function as Normal Outputs */
 #define ANOMALY_05000375 (__SILICON_REVISION__ < 4)
 /* SSYNC Stalls Processor when Executed from Non-Cacheable Memory */
-#define ANOMALY_05000402 (__SILICON_REVISION__ < 4)
+#define ANOMALY_05000402 (__SILICON_REVISION__ == 3)
 /* Level-Sensitive External GPIO Wakeups May Cause Indefinite Stall */
 #define ANOMALY_05000403 (1)
 /* Speculative Fetches Can Cause Undesired External FIFO Operations */
index 9496196ac1647036299407d88e9b7896d69a09d8..5ecee1690957476ad01610c6435253da3146cb60 100644 (file)
 #endif
 #endif
 
-/* UART_IIR Register */
-#define STATUS(x)      ((x << 1) & 0x06)
-#define STATUS_P1      0x02
-#define STATUS_P0      0x01
-
 #define BFIN_UART_NR_PORTS     3
 
 #define OFFSET_THR              0x00   /* Transmit Holding register            */
 #define OFFSET_SCR              0x1C   /* SCR Scratch Register                 */
 #define OFFSET_GCTL             0x24   /* Global Control Register              */
 
-/* DPMC*/
-#define bfin_read_STOPCK_OFF() bfin_read_STOPCK()
-#define bfin_write_STOPCK_OFF(val) bfin_write_STOPCK(val)
-#define STOPCK_OFF STOPCK
-
 /* PLL_DIV Masks                                                                                                       */
 #define CCLK_DIV1 CSEL_DIV1    /*          CCLK = VCO / 1                                  */
 #define CCLK_DIV2 CSEL_DIV2    /*          CCLK = VCO / 2                                  */
index 99ca3f4305e2fd233a86a4cf34e5e9a89492d610..1de67515dc9d3ef7f4fc8b89e9fe290d4d9dfa43 100644 (file)
 #define bfin_write_PPI_CONTROL(val)    bfin_write16(PPI_CONTROL, val)
 #define bfin_read_PPI_STATUS()         bfin_read16(PPI_STATUS)
 #define bfin_write_PPI_STATUS(val)     bfin_write16(PPI_STATUS, val)
+#define bfin_clear_PPI_STATUS()        bfin_read_PPI_STATUS()
 #define bfin_read_PPI_DELAY()          bfin_read16(PPI_DELAY)
 #define bfin_write_PPI_DELAY(val)      bfin_write16(PPI_DELAY, val)
 #define bfin_read_PPI_COUNT()          bfin_read16(PPI_COUNT)
index f5a3c30a41bd299d5c1899b4e18564309deab658..e565aae11d724e79518cbe45233129f1da227ae4 100644 (file)
@@ -291,6 +291,8 @@ static struct platform_device bfin_sir3_device = {
 #endif
 
 #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+#include <linux/smsc911x.h>
+
 static struct resource smsc911x_resources[] = {
        {
                .name = "smsc911x-memory",
@@ -304,11 +306,22 @@ static struct resource smsc911x_resources[] = {
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
        },
 };
+
+static struct smsc911x_platform_config smsc911x_config = {
+       .flags = SMSC911X_USE_16BIT,
+       .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+       .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+       .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
 static struct platform_device smsc911x_device = {
        .name = "smsc911x",
        .id = 0,
        .num_resources = ARRAY_SIZE(smsc911x_resources),
        .resource = smsc911x_resources,
+       .dev = {
+               .platform_data = &smsc911x_config,
+       },
 };
 #endif
 
@@ -473,7 +486,7 @@ static struct mtd_partition para_partitions[] = {
                .offset     = 0,
        }, {
                .name       = "linux kernel(nor)",
-               .size       = 0x400000,
+               .size       = 0x100000,
                .offset     = MTDPART_OFS_APPEND,
        }, {
                .name       = "file system(nor)",
@@ -642,7 +655,7 @@ static struct resource bfin_spi1_resource[] = {
 
 /* SPI controller data */
 static struct bfin5xx_spi_master bf54x_spi_master_info0 = {
-       .num_chipselect = 8,
+       .num_chipselect = 3,
        .enable_dma = 1,  /* master has the ability to do dma transfer */
        .pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0},
 };
@@ -658,7 +671,7 @@ static struct platform_device bf54x_spi_master0 = {
 };
 
 static struct bfin5xx_spi_master bf54x_spi_master_info1 = {
-       .num_chipselect = 8,
+       .num_chipselect = 3,
        .enable_dma = 1,  /* master has the ability to do dma transfer */
        .pin_req = {P_SPI1_SCK, P_SPI1_MISO, P_SPI1_MOSI, 0},
 };
index dc0dd9b2bcef46383369795cda3a3a19264e2fe4..c66f3801274f543a9e004b7a756f847061b131c4 100644 (file)
@@ -99,8 +99,8 @@ static struct platform_device bfin_isp1760_device = {
 #include <mach/bf54x-lq043.h>
 
 static struct bfin_bf54xfb_mach_info bf54x_lq043_data = {
-       .width =        480,
-       .height =       272,
+       .width =        95,
+       .height =       54,
        .xres =         {480, 480, 480},
        .yres =         {272, 272, 272},
        .bpp =          {24, 24, 24},
@@ -702,7 +702,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 #if defined(CONFIG_SND_BLACKFIN_AD1836) \
        || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
        {
-               .modalias = "ad1836-spi",
+               .modalias = "ad1836",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
                .bus_num = 1,
                .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
@@ -783,7 +783,7 @@ static struct resource bfin_spi1_resource[] = {
 
 /* SPI controller data */
 static struct bfin5xx_spi_master bf54x_spi_master_info0 = {
-       .num_chipselect = 8,
+       .num_chipselect = 3,
        .enable_dma = 1,  /* master has the ability to do dma transfer */
        .pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0},
 };
@@ -799,7 +799,7 @@ static struct platform_device bf54x_spi_master0 = {
 };
 
 static struct bfin5xx_spi_master bf54x_spi_master_info1 = {
-       .num_chipselect = 8,
+       .num_chipselect = 3,
        .enable_dma = 1,  /* master has the ability to do dma transfer */
        .pin_req = {P_SPI1_SCK, P_SPI1_MISO, P_SPI1_MOSI, 0},
 };
@@ -869,7 +869,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info1[] = {
                I2C_BOARD_INFO("pcf8574_lcd", 0x22),
        },
 #endif
-#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE)
+#if defined(CONFIG_INPUT_PCF8574) || defined(CONFIG_INPUT_PCF8574_MODULE)
        {
                I2C_BOARD_INFO("pcf8574_keypad", 0x27),
                .irq = 212,
index 535980652bf6acc3f7182e6a019929b96c3a4245..d9239bc05dd4a945b1a0ea6048cfff2ecdc510f7 100644 (file)
@@ -91,16 +91,16 @@ int channel2irq(unsigned int channel)
                ret_irq = IRQ_SPI1;
                break;
        case CH_UART0_RX:
-               ret_irq = IRQ_UART_RX;
+               ret_irq = IRQ_UART0_RX;
                break;
        case CH_UART0_TX:
-               ret_irq = IRQ_UART_TX;
+               ret_irq = IRQ_UART0_TX;
                break;
        case CH_UART1_RX:
-               ret_irq = IRQ_UART_RX;
+               ret_irq = IRQ_UART1_RX;
                break;
        case CH_UART1_TX:
-               ret_irq = IRQ_UART_TX;
+               ret_irq = IRQ_UART1_TX;
                break;
        case CH_EPPI0:
                ret_irq = IRQ_EPPI0;
index cd040fe0bc5c10e47b38f6fbd1882d5f3dbdad34..52b116ae522a57fc153515055ed7389ac784d18f 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 /* This file should be up to date with:
- *  - Revision H, 01/16/2009; ADSP-BF542/BF544/BF547/BF548/BF549 Blackfin Processor Anomaly List
+ *  - Revision I, 07/23/2009; ADSP-BF542/BF544/BF547/BF548/BF549 Blackfin Processor Anomaly List
  */
 
 #ifndef _MACH_ANOMALY_H_
 #define ANOMALY_05000430 (__SILICON_REVISION__ >= 2)
 /* Incorrect Use of Stack in Lockbox Firmware During Authentication */
 #define ANOMALY_05000431 (__SILICON_REVISION__ < 3)
+/* SW Breakpoints Ignored Upon Return From Lockbox Authentication */
+#define ANOMALY_05000434 (1)
 /* OTP Write Accesses Not Supported */
 #define ANOMALY_05000442 (__SILICON_REVISION__ < 1)
 /* IFLUSH Instruction at End of Hardware Loop Causes Infinite Stall */
 #define ANOMALY_05000449 (__SILICON_REVISION__ == 1)
 /* USB DMA Mode 1 Short Packet Data Corruption */
 #define ANOMALY_05000450 (1)
+/* Incorrect Default Hysteresis Setting for RESET, NMI, and BMODE Signals */
+#define ANOMALY_05000452 (__SILICON_REVISION__ < 1)
 /* USB Receive Interrupt Is Not Generated in DMA Mode 1 */
-#define ANOMALY_05000456 (__SILICON_REVISION__ < 3)
+#define ANOMALY_05000456 (1)
+/* Host DMA Port Responds to Certain Bus Activity Without HOST_CE Assertion */
+#define ANOMALY_05000457 (1)
+/* USB DMA Mode 1 Failure When Multiple USB DMA Channels Are Concurrently Enabled */
+#define ANOMALY_05000460 (1)
 /* False Hardware Error when RETI Points to Invalid Memory */
 #define ANOMALY_05000461 (1)
+/* Synchronization Problem at Startup May Cause SPORT Transmit Channels to Misalign */
+#define ANOMALY_05000462 (1)
+/* USB DMA RX Data Corruption */
+#define ANOMALY_05000463 (1)
+/* USB TX DMA Hang */
+#define ANOMALY_05000464 (1)
 /* USB Rx DMA hang */
 #define ANOMALY_05000465 (1)
+/* TxPktRdy Bit Not Set for Transmit Endpoint When Core and DMA Access USB Endpoint FIFOs Simultaneously */
+#define ANOMALY_05000466 (1)
 /* Possible RX data corruption when control & data EP FIFOs are accessed via the core */
 #define ANOMALY_05000467 (1)
 
 #define ANOMALY_05000364 (0)
 #define ANOMALY_05000380 (0)
 #define ANOMALY_05000400 (0)
+#define ANOMALY_05000402 (0)
 #define ANOMALY_05000412 (0)
 #define ANOMALY_05000432 (0)
 #define ANOMALY_05000435 (0)
index 6b97396d817f28f5f5c5842a6867e833f497d929..318667b2f036a021d364ffe1c97225449202cb20 100644 (file)
 #include "cdefBF549.h"
 #endif
 
-/* UART 1*/
-#define bfin_read_UART_THR()           bfin_read_UART1_THR()
-#define bfin_write_UART_THR(val)       bfin_write_UART1_THR(val)
-#define bfin_read_UART_RBR()           bfin_read_UART1_RBR()
-#define bfin_write_UART_RBR(val)       bfin_write_UART1_RBR(val)
-#define bfin_read_UART_DLL()           bfin_read_UART1_DLL()
-#define bfin_write_UART_DLL(val)       bfin_write_UART1_DLL(val)
-#define bfin_read_UART_IER()           bfin_read_UART1_IER()
-#define bfin_write_UART_IER(val)       bfin_write_UART1_IER(val)
-#define bfin_read_UART_DLH()           bfin_read_UART1_DLH()
-#define bfin_write_UART_DLH(val)       bfin_write_UART1_DLH(val)
-#define bfin_read_UART_IIR()           bfin_read_UART1_IIR()
-#define bfin_write_UART_IIR(val)       bfin_write_UART1_IIR(val)
-#define bfin_read_UART_LCR()           bfin_read_UART1_LCR()
-#define bfin_write_UART_LCR(val)       bfin_write_UART1_LCR(val)
-#define bfin_read_UART_MCR()           bfin_read_UART1_MCR()
-#define bfin_write_UART_MCR(val)       bfin_write_UART1_MCR(val)
-#define bfin_read_UART_LSR()           bfin_read_UART1_LSR()
-#define bfin_write_UART_LSR(val)       bfin_write_UART1_LSR(val)
-#define bfin_read_UART_SCR()           bfin_read_UART1_SCR()
-#define bfin_write_UART_SCR(val)       bfin_write_UART1_SCR(val)
-#define bfin_read_UART_GCTL()          bfin_read_UART1_GCTL()
-#define bfin_write_UART_GCTL(val)      bfin_write_UART1_GCTL(val)
-
 #endif
 
-/* MAP used DEFINES from BF533 to BF54x - so we don't need to change 
- * them in the driver, kernel, etc. */
-
-/* UART_IIR Register */
-#define STATUS(x)      ((x << 1) & 0x06)
-#define STATUS_P1      0x02
-#define STATUS_P0      0x01
-
-/* UART 0*/
-
-/* DMA Channel */
-#define bfin_read_CH_UART_RX()         bfin_read_CH_UART1_RX()
-#define bfin_write_CH_UART_RX(val)     bfin_write_CH_UART1_RX(val)
-#define bfin_read_CH_UART_TX()         bfin_read_CH_UART1_TX()
-#define bfin_write_CH_UART_TX(val)     bfin_write_CH_UART1_TX(val)
-#define CH_UART_RX                     CH_UART1_RX
-#define CH_UART_TX                     CH_UART1_TX
-
-/* System Interrupt Controller */
-#define bfin_read_IRQ_UART_RX()                bfin_read_IRQ_UART1_RX()
-#define bfin_write_IRQ_UART_RX(val)    bfin_write_IRQ_UART1_RX(val)
-#define bfin_read_IRQ_UART_TX()                bfin_read_IRQ_UART1_TX()
-#define bfin_write_IRQ_UART_TX(val)    bfin_write_IRQ_UART1_TX(val)
-#define bfin_read_IRQ_UART_ERROR()     bfin_read_IRQ_UART1_ERROR()
-#define bfin_write_IRQ_UART_ERROR(val) bfin_write_IRQ_UART1_ERROR(val)
-#define IRQ_UART_RX                    IRQ_UART1_RX
-#define        IRQ_UART_TX                     IRQ_UART1_TX
-#define        IRQ_UART_ERROR                  IRQ_UART1_ERROR
-
-/* MMR Registers*/
-#define bfin_read_UART_THR()           bfin_read_UART1_THR()
-#define bfin_write_UART_THR(val)       bfin_write_UART1_THR(val)
-#define bfin_read_UART_RBR()           bfin_read_UART1_RBR()
-#define bfin_write_UART_RBR(val)       bfin_write_UART1_RBR(val)
-#define bfin_read_UART_DLL()           bfin_read_UART1_DLL()
-#define bfin_write_UART_DLL(val)       bfin_write_UART1_DLL(val)
-#define bfin_read_UART_IER()           bfin_read_UART1_IER()
-#define bfin_write_UART_IER(val)       bfin_write_UART1_IER(val)
-#define bfin_read_UART_DLH()           bfin_read_UART1_DLH()
-#define bfin_write_UART_DLH(val)       bfin_write_UART1_DLH(val)
-#define bfin_read_UART_IIR()           bfin_read_UART1_IIR()
-#define bfin_write_UART_IIR(val)       bfin_write_UART1_IIR(val)
-#define bfin_read_UART_LCR()           bfin_read_UART1_LCR()
-#define bfin_write_UART_LCR(val)       bfin_write_UART1_LCR(val)
-#define bfin_read_UART_MCR()           bfin_read_UART1_MCR()
-#define bfin_write_UART_MCR(val)       bfin_write_UART1_MCR(val)
-#define bfin_read_UART_LSR()           bfin_read_UART1_LSR()
-#define bfin_write_UART_LSR(val)       bfin_write_UART1_LSR(val)
-#define bfin_read_UART_SCR()           bfin_read_UART1_SCR()
-#define bfin_write_UART_SCR(val)       bfin_write_UART1_SCR(val)
-#define bfin_read_UART_GCTL()          bfin_read_UART1_GCTL()
-#define bfin_write_UART_GCTL(val)      bfin_write_UART1_GCTL(val)
-
-#define BFIN_UART_THR                  UART1_THR
-#define BFIN_UART_RBR                  UART1_RBR
-#define BFIN_UART_DLL                  UART1_DLL
-#define BFIN_UART_IER                  UART1_IER
-#define BFIN_UART_DLH                  UART1_DLH
-#define BFIN_UART_IIR                  UART1_IIR
-#define BFIN_UART_LCR                  UART1_LCR
-#define BFIN_UART_MCR                  UART1_MCR
-#define BFIN_UART_LSR                  UART1_LSR
-#define BFIN_UART_SCR                  UART1_SCR
-#define BFIN_UART_GCTL                 UART1_GCTL
-
 #define BFIN_UART_NR_PORTS     4
 
 #define OFFSET_DLL              0x00   /* Divisor Latch (Low-Byte)             */
index 0c9d72c5f5babdef3fab2e5cdb9e87eced038b04..6577ecfcf11ebc5476270aaf11ac6f72bec9fe0c 100644 (file)
@@ -42,6 +42,7 @@
 #include <asm/bfin5xx_spi.h>
 #include <asm/portmux.h>
 #include <asm/dpmc.h>
+#include <linux/mtd/physmap.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
@@ -98,13 +99,6 @@ static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
-static struct bfin5xx_spi_chip ad9960_spi_chip_info = {
-       .enable_dma = 0,
-       .bits_per_word = 16,
-};
-#endif
-
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
 static struct bfin5xx_spi_chip mmc_spi_chip_info = {
        .enable_dma = 0,
@@ -139,28 +133,19 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 
 #if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
        {
-               .modalias = "ad1836-spi",
+               .modalias = "ad1836",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
                .bus_num = 0,
                .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
                .controller_data = &ad1836_spi_chip_info,
        },
 #endif
-#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
-       {
-               .modalias = "ad9960-spi",
-               .max_speed_hz = 10000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 0,
-               .chip_select = 1,
-               .controller_data = &ad9960_spi_chip_info,
-       },
-#endif
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
        {
                .modalias = "mmc_spi",
-               .max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
+               .max_speed_hz = 20000000,     /* max spi clock (SCK) speed in HZ */
                .bus_num = 0,
-               .chip_select = 5,
+               .chip_select = 1,
                .controller_data = &mmc_spi_chip_info,
                .mode = SPI_MODE_3,
        },
@@ -213,6 +198,13 @@ static struct platform_device hitachi_fb_device = {
 
 
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+#include <linux/smc91x.h>
+
+static struct smc91x_platdata smc91x_info = {
+       .flags = SMC91X_USE_32BIT | SMC91X_NOWAIT,
+       .leda = RPC_LED_100_10,
+       .ledb = RPC_LED_TX_RX,
+};
 
 static struct resource smc91x_resources[] = {
        {
@@ -231,6 +223,65 @@ static struct platform_device smc91x_device = {
        .id = 0,
        .num_resources = ARRAY_SIZE(smc91x_resources),
        .resource = smc91x_resources,
+       .dev    = {
+               .platform_data  = &smc91x_info,
+       },
+};
+#endif
+
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+#include <linux/smsc911x.h>
+
+static struct resource smsc911x_resources[] = {
+       {
+               .name = "smsc911x-memory",
+               .start = 0x24008000,
+               .end = 0x24008000 + 0xFF,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_PF43,
+               .end = IRQ_PF43,
+               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+       },
+};
+
+static struct smsc911x_platform_config smsc911x_config = {
+       .flags = SMSC911X_USE_16BIT,
+       .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+       .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+       .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+static struct platform_device smsc911x_device = {
+       .name = "smsc911x",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(smsc911x_resources),
+       .resource = smsc911x_resources,
+       .dev = {
+               .platform_data = &smsc911x_config,
+       },
+};
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+static struct resource net2272_bfin_resources[] = {
+       {
+               .start = 0x24000000,
+               .end = 0x24000000 + 0x100,
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = IRQ_PF45,
+               .end = IRQ_PF45,
+               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+       },
+};
+
+static struct platform_device net2272_bfin_device = {
+       .name = "net2272",
+       .id = -1,
+       .num_resources = ARRAY_SIZE(net2272_bfin_resources),
+       .resource = net2272_bfin_resources,
 };
 #endif
 
@@ -369,6 +420,46 @@ static struct platform_device bfin_pata_device = {
 };
 #endif
 
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct mtd_partition para_partitions[] = {
+       {
+               .name       = "bootloader(nor)",
+               .size       = 0x40000,
+               .offset     = 0,
+       }, {
+               .name       = "linux kernel(nor)",
+               .size       = 0x100000,
+               .offset     = MTDPART_OFS_APPEND,
+       }, {
+               .name       = "file system(nor)",
+               .size       = MTDPART_SIZ_FULL,
+               .offset     = MTDPART_OFS_APPEND,
+       }
+};
+
+static struct physmap_flash_data para_flash_data = {
+       .width      = 2,
+       .parts      = para_partitions,
+       .nr_parts   = ARRAY_SIZE(para_partitions),
+};
+
+static struct resource para_flash_resource = {
+       .start = 0x20000000,
+       .end   = 0x207fffff,
+       .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device para_flash_device = {
+       .name          = "physmap-flash",
+       .id            = 0,
+       .dev = {
+               .platform_data = &para_flash_data,
+       },
+       .num_resources = 1,
+       .resource      = &para_flash_resource,
+};
+#endif
+
 static const unsigned int cclk_vlev_datasheet[] =
 {
        VRPAIR(VLEV_085, 250000000),
@@ -422,6 +513,14 @@ static struct platform_device *cm_bf561_devices[] __initdata = {
        &smc91x_device,
 #endif
 
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+       &smsc911x_device,
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+       &net2272_bfin_device,
+#endif
+
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
        &bfin_spi0_device,
 #endif
@@ -430,6 +529,10 @@ static struct platform_device *cm_bf561_devices[] __initdata = {
        &bfin_pata_device,
 #endif
 
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+       &para_flash_device,
+#endif
+
        &bfin_gpios_device,
 };
 
index 4df904f9e90aebc498a5e3447b767a6ec73cbd75..caed96bb957e26db1ecbbe86d54a9e968cec0f07 100644 (file)
@@ -147,6 +147,14 @@ static struct platform_device net2272_bfin_device = {
  *  Driver needs to know address, irq and flag pin.
  */
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+#include <linux/smc91x.h>
+
+static struct smc91x_platdata smc91x_info = {
+       .flags = SMC91X_USE_32BIT | SMC91X_NOWAIT,
+       .leda = RPC_LED_100_10,
+       .ledb = RPC_LED_TX_RX,
+};
+
 static struct resource smc91x_resources[] = {
        {
                .name = "smc91x-regs",
@@ -166,6 +174,9 @@ static struct platform_device smc91x_device = {
        .id = 0,
        .num_resources = ARRAY_SIZE(smc91x_resources),
        .resource = smc91x_resources,
+       .dev    = {
+               .platform_data  = &smc91x_info,
+       },
 };
 #endif
 
@@ -334,7 +345,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 #if defined(CONFIG_SND_BLACKFIN_AD1836) \
        || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
        {
-               .modalias = "ad1836-spi",
+               .modalias = "ad1836",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
                .bus_num = 0,
                .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
index a5312b2d267e25117d53a6875f0ffcc0c75c4e9c..70da495c96652e1c407d8ecb49e5607b389cec6a 100644 (file)
 #define ANOMALY_05000366 (1)
 /* Possible RETS Register Corruption when Subroutine Is under 5 Cycles in Duration */
 #define ANOMALY_05000371 (1)
+/* SSYNC Stalls Processor when Executed from Non-Cacheable Memory */
+#define ANOMALY_05000402 (__SILICON_REVISION__ == 4)
 /* Level-Sensitive External GPIO Wakeups May Cause Indefinite Stall */
 #define ANOMALY_05000403 (1)
 /* TESTSET Instruction Causes Data Corruption with Writeback Data Cache Enabled */
index 35280f06b7b6b0387d475c7921065606e9be4b6a..f72a6af20c4fc21b05625b14b10661cbcf4eacb0 100644 (file)
@@ -85,16 +85,10 @@ ENTRY(_coreb_trampoline_start)
        R0 = ~ENICPLB;
        R0 = R0 & R1;
 
-       /* Anomaly 05000125 */
-#ifdef ANOMALY_05000125
-       CLI R2;
-       SSYNC;
-#endif
+       /* Disabling of CPLBs should be proceeded by a CSYNC */
+       CSYNC;
        [p0] = R0;
        SSYNC;
-#ifdef ANOMALY_05000125
-       STI R2;
-#endif
 
        /* Turn off the dcache */
        p0.l = LO(DMEM_CONTROL);
@@ -103,16 +97,10 @@ ENTRY(_coreb_trampoline_start)
        R0 = ~ENDCPLB;
        R0 = R0 & R1;
 
-       /* Anomaly 05000125 */
-#ifdef ANOMALY_05000125
-       CLI R2;
-       SSYNC;
-#endif
+       /* Disabling of CPLBs should be proceeded by a CSYNC */
+       CSYNC;
        [p0] = R0;
        SSYNC;
-#ifdef ANOMALY_05000125
-       STI R2;
-#endif
 
        /* in case of double faults, save a few things */
        p0.l = _init_retx_coreb;
@@ -126,22 +114,22 @@ ENTRY(_coreb_trampoline_start)
         * below
         */
        GET_PDA(p0, r0);
-       r7 = [p0 + PDA_RETX];
+       r7 = [p0 + PDA_DF_RETX];
        p1.l = _init_saved_retx_coreb;
        p1.h = _init_saved_retx_coreb;
        [p1] = r7;
 
-       r7 = [p0 + PDA_DCPLB];
+       r7 = [p0 + PDA_DF_DCPLB];
        p1.l = _init_saved_dcplb_fault_addr_coreb;
        p1.h = _init_saved_dcplb_fault_addr_coreb;
        [p1] = r7;
 
-       r7 = [p0 + PDA_ICPLB];
+       r7 = [p0 + PDA_DF_ICPLB];
        p1.l = _init_saved_icplb_fault_addr_coreb;
        p1.h = _init_saved_icplb_fault_addr_coreb;
        [p1] = r7;
 
-       r7 = [p0 + PDA_SEQSTAT];
+       r7 = [p0 + PDA_DF_SEQSTAT];
        p1.l = _init_saved_seqstat_coreb;
        p1.h = _init_saved_seqstat_coreb;
        [p1] = r7;
index dd8b2dc97f56100e02f2d2c38137545f02aa71eb..814cb483853bba6ea743285e65bbcabb161dd554 100644 (file)
@@ -6,7 +6,6 @@ obj-y := \
        cache.o cache-c.o entry.o head.o \
        interrupt.o arch_checks.o ints-priority.o
 
-obj-$(CONFIG_BFIN_ICACHE_LOCK) += lock.o
 obj-$(CONFIG_PM)          += pm.o dpmc_modes.o
 obj-$(CONFIG_CPU_FREQ)    += cpufreq.o
 obj-$(CONFIG_CPU_VOLTAGE) += dpmc.o
index b59ce3cb380718a5030e9ce99e154ad5e9bd54db..4ebbd78db3a4e8cff1a3c265a79afd62f387c1c8 100644 (file)
@@ -1,14 +1,16 @@
 /*
  * Blackfin cache control code (simpler control-style functions)
  *
- * Copyright 2004-2008 Analog Devices Inc.
+ * Copyright 2004-2009 Analog Devices Inc.
  *
  * Enter bugs at http://blackfin.uclinux.org/
  *
  * Licensed under the GPL-2 or later.
  */
 
+#include <linux/init.h>
 #include <asm/blackfin.h>
+#include <asm/cplbinit.h>
 
 /* Invalidate the Entire Data cache by
  * clearing DMC[1:0] bits
@@ -34,3 +36,43 @@ void blackfin_invalidate_entire_icache(void)
        SSYNC();
 }
 
+#if defined(CONFIG_BFIN_ICACHE) || defined(CONFIG_BFIN_DCACHE)
+
+static void
+bfin_cache_init(struct cplb_entry *cplb_tbl, unsigned long cplb_addr,
+                unsigned long cplb_data, unsigned long mem_control,
+                unsigned long mem_mask)
+{
+       int i;
+
+       for (i = 0; i < MAX_CPLBS; i++) {
+               bfin_write32(cplb_addr + i * 4, cplb_tbl[i].addr);
+               bfin_write32(cplb_data + i * 4, cplb_tbl[i].data);
+       }
+
+       _enable_cplb(mem_control, mem_mask);
+}
+
+#ifdef CONFIG_BFIN_ICACHE
+void __cpuinit bfin_icache_init(struct cplb_entry *icplb_tbl)
+{
+       bfin_cache_init(icplb_tbl, ICPLB_ADDR0, ICPLB_DATA0, IMEM_CONTROL,
+               (IMC | ENICPLB));
+}
+#endif
+
+#ifdef CONFIG_BFIN_DCACHE
+void __cpuinit bfin_dcache_init(struct cplb_entry *dcplb_tbl)
+{
+       /*
+        *  Anomaly notes:
+        *  05000287 - We implement workaround #2 - Change the DMEM_CONTROL
+        *  register, so that the port preferences for DAG0 and DAG1 are set
+        *  to port B
+        */
+       bfin_cache_init(dcplb_tbl, DCPLB_ADDR0, DCPLB_DATA0, DMEM_CONTROL,
+               (DMEM_CNTR | PORT_PREF0 | (ANOMALY_05000287 ? PORT_PREF1 : 0)));
+}
+#endif
+
+#endif
index fb1795d5be2af2e9765f31c1c40fafd90257580e..01af24cde362210f763aca00f0b5d3113bf6370c 100644 (file)
@@ -301,27 +301,31 @@ ENTRY(_ex_replaceable)
        nop;
 
 ENTRY(_ex_trap_c)
+       /* The only thing that has been saved in this context is
+        * (R7:6,P5:4), ASTAT & SP - don't use anything else
+        */
+
+       GET_PDA(p5, r6);
+
        /* Make sure we are not in a double fault */
        p4.l = lo(IPEND);
        p4.h = hi(IPEND);
        r7 = [p4];
        CC = BITTST (r7, 5);
        if CC jump _double_fault;
+       [p5 + PDA_EXIPEND] = r7;
 
        /* Call C code (trap_c) to handle the exception, which most
         * likely involves sending a signal to the current process.
         * To avoid double faults, lower our priority to IRQ5 first.
         */
-       P5.h = _exception_to_level5;
-       P5.l = _exception_to_level5;
+       r7.h = _exception_to_level5;
+       r7.l = _exception_to_level5;
        p4.l = lo(EVT5);
        p4.h = hi(EVT5);
-       [p4] = p5;
+       [p4] = r7;
        csync;
 
-       GET_PDA(p5, r6);
-#ifndef CONFIG_DEBUG_DOUBLEFAULT
-
        /*
         * Save these registers, as they are only valid in exception context
         *  (where we are now - as soon as we defer to IRQ5, they can change)
@@ -341,7 +345,10 @@ ENTRY(_ex_trap_c)
 
        r6 = retx;
        [p5 + PDA_RETX] = r6;
-#endif
+
+       r6 = SEQSTAT;
+       [p5 + PDA_SEQSTAT] = r6;
+
        /* Save the state of single stepping */
        r6 = SYSCFG;
        [p5 + PDA_SYSCFG] = r6;
@@ -349,8 +356,7 @@ ENTRY(_ex_trap_c)
        BITCLR(r6, SYSCFG_SSSTEP_P);
        SYSCFG = r6;
 
-       /* Disable all interrupts, but make sure level 5 is enabled so
-        * we can switch to that level.  Save the old mask.  */
+       /* Save the current IMASK, since we change in order to jump to level 5 */
        cli r6;
        [p5 + PDA_EXIMASK] = r6;
 
@@ -358,9 +364,21 @@ ENTRY(_ex_trap_c)
        p4.h = hi(SAFE_USER_INSTRUCTION);
        retx = p4;
 
+       /* Disable all interrupts, but make sure level 5 is enabled so
+        * we can switch to that level.
+        */
        r6 = 0x3f;
        sti r6;
 
+       /* In case interrupts are disabled IPEND[4] (global interrupt disable bit)
+        * clear it (re-enabling interrupts again) by the special sequence of pushing
+        * RETI onto the stack.  This way we can lower ourselves to IVG5 even if the
+        * exception was taken after the interrupt handler was called but before it
+        * got a chance to enable global interrupts itself.
+        */
+       [--sp] = reti;
+       sp += 4;
+
        raise 5;
        jump.s _bfin_return_from_exception;
 ENDPROC(_ex_trap_c)
@@ -379,8 +397,7 @@ ENTRY(_double_fault)
 
        R5 = [P4];              /* Control Register*/
        BITCLR(R5,ENICPLB_P);
-       SSYNC;          /* SSYNC required before writing to IMEM_CONTROL. */
-       .align 8;
+       CSYNC;          /* Disabling of CPLBs should be proceeded by a CSYNC */
        [P4] = R5;
        SSYNC;
 
@@ -388,8 +405,7 @@ ENTRY(_double_fault)
        P4.H = HI(DMEM_CONTROL);
        R5 = [P4];
        BITCLR(R5,ENDCPLB_P);
-       SSYNC;          /* SSYNC required before writing to DMEM_CONTROL. */
-       .align 8;
+       CSYNC;          /* Disabling of CPLBs should be proceeded by a CSYNC */
        [P4] = R5;
        SSYNC;
 
@@ -420,47 +436,55 @@ ENDPROC(_double_fault)
 ENTRY(_exception_to_level5)
        SAVE_ALL_SYS
 
-       GET_PDA(p4, r7);        /* Fetch current PDA */
-       r6 = [p4 + PDA_RETX];
+       GET_PDA(p5, r7);        /* Fetch current PDA */
+       r6 = [p5 + PDA_RETX];
        [sp + PT_PC] = r6;
 
-       r6 = [p4 + PDA_SYSCFG];
+       r6 = [p5 + PDA_SYSCFG];
        [sp + PT_SYSCFG] = r6;
 
-       /* Restore interrupt mask.  We haven't pushed RETI, so this
-        * doesn't enable interrupts until we return from this handler.  */
-       r6 = [p4 + PDA_EXIMASK];
-       sti r6;
+       r6 = [p5 + PDA_SEQSTAT]; /* Read back seqstat */
+       [sp + PT_SEQSTAT] = r6;
 
        /* Restore the hardware error vector.  */
-       P5.h = _evt_ivhw;
-       P5.l = _evt_ivhw;
+       r7.h = _evt_ivhw;
+       r7.l = _evt_ivhw;
        p4.l = lo(EVT5);
        p4.h = hi(EVT5);
-       [p4] = p5;
+       [p4] = r7;
        csync;
 
-       p2.l = lo(IPEND);
-       p2.h = hi(IPEND);
-       csync;
-       r0 = [p2];              /* Read current IPEND */
-       [sp + PT_IPEND] = r0;   /* Store IPEND */
+#ifdef CONFIG_DEBUG_DOUBLEFAULT
+       /* Now that we have the hardware error vector programmed properly
+        * we can re-enable interrupts (IPEND[4]), so if the _trap_c causes
+        * another hardware error, we can catch it (self-nesting).
+        */
+       [--sp] = reti;
+       sp += 4;
+#endif
+
+       r7 = [p5 + PDA_EXIPEND] /* Read the IPEND from the Exception state */
+       [sp + PT_IPEND] = r7;   /* Store IPEND onto the stack */
 
        r0 = sp;        /* stack frame pt_regs pointer argument ==> r0 */
        SP += -12;
        call _trap_c;
        SP += 12;
 
-#ifdef CONFIG_DEBUG_DOUBLEFAULT
-       /* Grab ILAT */
-       p2.l = lo(ILAT);
-       p2.h = hi(ILAT);
-       r0 = [p2];
-       r1 = 0x20;  /* Did I just cause anther HW error? */
-       r0 = r0 & r1;
-       CC = R0 == R1;
-       if CC JUMP _double_fault;
-#endif
+       /* If interrupts were off during the exception (IPEND[4] = 1), turn them off
+        * before we return.
+        */
+       CC = BITTST(r7, EVT_IRPTEN_P)
+       if !CC jump 1f;
+       /* this will load a random value into the reti register - but that is OK,
+        * since we do restore it to the correct value in the 'RESTORE_ALL_SYS' macro
+        */
+       sp += -4;
+       reti = [sp++];
+1:
+       /* restore the interrupt mask (IMASK) */
+       r6 = [p5 + PDA_EXIMASK];
+       sti r6;
 
        call _ret_from_exception;
        RESTORE_ALL_SYS
@@ -474,7 +498,7 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/
         */
        EX_SCRATCH_REG = sp;
        GET_PDA_SAFE(sp);
-       sp = [sp + PDA_EXSTACK]
+       sp = [sp + PDA_EXSTACK];
        /* Try to deal with syscalls quickly.  */
        [--sp] = ASTAT;
        [--sp] = (R7:6,P5:4);
@@ -489,14 +513,7 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/
        ssync;
 #endif
 
-#if ANOMALY_05000283 || ANOMALY_05000315
-       cc = r7 == r7;
-       p5.h = HI(CHIPID);
-       p5.l = LO(CHIPID);
-       if cc jump 1f;
-       r7.l = W[p5];
-1:
-#endif
+       ANOMALY_283_315_WORKAROUND(p5, r7)
 
 #ifdef CONFIG_DEBUG_DOUBLEFAULT
        /*
@@ -510,18 +527,18 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/
        p4.l = lo(DCPLB_FAULT_ADDR);
        p4.h = hi(DCPLB_FAULT_ADDR);
        r7 = [p4];
-       [p5 + PDA_DCPLB] = r7;
+       [p5 + PDA_DF_DCPLB] = r7;
 
        p4.l = lo(ICPLB_FAULT_ADDR);
        p4.h = hi(ICPLB_FAULT_ADDR);
        r7 = [p4];
-       [p5 + PDA_ICPLB] = r7;
+       [p5 + PDA_DF_ICPLB] = r7;
 
-       r6 = retx;
-       [p5 + PDA_RETX] = r6;
+       r7 = retx;
+       [p5 + PDA_DF_RETX] = r7;
 
        r7 = SEQSTAT;           /* reason code is in bit 5:0 */
-       [p5 + PDA_SEQSTAT] = r7;
+       [p5 + PDA_DF_SEQSTAT] = r7;
 #else
        r7 = SEQSTAT;           /* reason code is in bit 5:0 */
 #endif
@@ -686,8 +703,14 @@ ENTRY(_system_call)
 #ifdef CONFIG_IPIPE
        cc = BITTST(r7, TIF_IRQ_SYNC);
        if !cc jump .Lsyscall_no_irqsync;
+       /*
+        * Clear IPEND[4] manually to undo what resume_userspace_1 just did;
+        * we need this so that high priority domain interrupts may still
+        * preempt the current domain while the pipeline log is being played
+        * back.
+        */
        [--sp] = reti;
-       r0 = [sp++];
+       SP += 4; /* don't merge with next insn to keep the pattern obvious */
        SP += -12;
        call ___ipipe_sync_root;
        SP += 12;
@@ -699,7 +722,7 @@ ENTRY(_system_call)
 
        /* Reenable interrupts.  */
        [--sp] = reti;
-       r0 = [sp++];
+       sp += 4;
 
        SP += -12;
        call _schedule;
@@ -715,7 +738,7 @@ ENTRY(_system_call)
 .Lsyscall_do_signals:
        /* Reenable interrupts.  */
        [--sp] = reti;
-       r0 = [sp++];
+       sp += 4;
 
        r0 = sp;
        SP += -12;
@@ -725,10 +748,6 @@ ENTRY(_system_call)
 .Lsyscall_really_exit:
        r5 = [sp + PT_RESERVED];
        rets = r5;
-#ifdef CONFIG_IPIPE
-       [--sp] = reti;
-       r5 = [sp++];
-#endif /* CONFIG_IPIPE */
        rts;
 ENDPROC(_system_call)
 
@@ -816,13 +835,13 @@ ENDPROC(_resume)
 
 ENTRY(_ret_from_exception)
 #ifdef CONFIG_IPIPE
-       [--sp] = rets;
-       SP += -12;
-       call ___ipipe_check_root
-       SP += 12
-       rets = [sp++];
-       cc = r0 == 0;
-       if cc jump 4f;                /* not on behalf of Linux, get out */
+       p2.l = _per_cpu__ipipe_percpu_domain;
+       p2.h = _per_cpu__ipipe_percpu_domain;
+       r0.l = _ipipe_root;
+       r0.h = _ipipe_root;
+       r2 = [p2];
+       cc = r0 == r2;
+       if !cc jump 4f;  /* not on behalf of the root domain, get out */
 #endif /* CONFIG_IPIPE */
        p2.l = lo(IPEND);
        p2.h = hi(IPEND);
@@ -882,14 +901,9 @@ ENDPROC(_ret_from_exception)
 
 #ifdef CONFIG_IPIPE
 
-_sync_root_irqs:
-       [--sp] = reti;          /* Reenable interrupts */
-       r0 = [sp++];
-       jump.l ___ipipe_sync_root
-
 _resume_kernel_from_int:
-       r0.l = _sync_root_irqs
-       r0.h = _sync_root_irqs
+       r0.l = ___ipipe_sync_root;
+       r0.h = ___ipipe_sync_root;
        [--sp] = rets;
        [--sp] = ( r7:4, p5:3 );
        SP += -12;
@@ -953,10 +967,10 @@ ENTRY(_lower_to_irq14)
 #endif
 
 #ifdef CONFIG_DEBUG_HWERR
-       /* enable irq14 & hwerr interrupt, until we transition to _evt14_softirq */
+       /* enable irq14 & hwerr interrupt, until we transition to _evt_evt14 */
        r0 = (EVT_IVG14 | EVT_IVHW | EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU);
 #else
-       /* Only enable irq14 interrupt, until we transition to _evt14_softirq */
+       /* Only enable irq14 interrupt, until we transition to _evt_evt14 */
        r0 = (EVT_IVG14 | EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU);
 #endif
        sti r0;
@@ -964,7 +978,7 @@ ENTRY(_lower_to_irq14)
        rti;
 ENDPROC(_lower_to_irq14)
 
-ENTRY(_evt14_softirq)
+ENTRY(_evt_evt14)
 #ifdef CONFIG_DEBUG_HWERR
        r0 = (EVT_IVHW | EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU);
        sti r0;
@@ -974,7 +988,7 @@ ENTRY(_evt14_softirq)
        [--sp] = RETI;
        SP += 4;
        rts;
-ENDPROC(_evt14_softirq)
+ENDPROC(_evt_evt14)
 
 ENTRY(_schedule_and_signal_from_int)
        /* To end up here, vector 15 was changed - so we have to change it
@@ -1004,6 +1018,12 @@ ENTRY(_schedule_and_signal_from_int)
 #endif
        sti r0;
 
+       /* finish the userspace "atomic" functions for it */
+       r1 = FIXED_CODE_END;
+       r2 = [sp + PT_PC];
+       cc = r1 <= r2;
+       if cc jump .Lresume_userspace (bp);
+
        r0 = sp;
        sp += -12;
        call _finish_atomic_sections;
@@ -1107,14 +1127,7 @@ ENTRY(_early_trap)
        SAVE_ALL_SYS
        trace_buffer_stop(p0,r0);
 
-#if ANOMALY_05000283 || ANOMALY_05000315
-       cc = r5 == r5;
-       p4.h = HI(CHIPID);
-       p4.l = LO(CHIPID);
-       if cc jump 1f;
-       r5.l = W[p4];
-1:
-#endif
+       ANOMALY_283_315_WORKAROUND(p4, r5)
 
        /* Turn caches off, to ensure we don't get double exceptions */
 
@@ -1123,9 +1136,7 @@ ENTRY(_early_trap)
 
        R5 = [P4];              /* Control Register*/
        BITCLR(R5,ENICPLB_P);
-       CLI R1;
-       SSYNC;          /* SSYNC required before writing to IMEM_CONTROL. */
-       .align 8;
+       CSYNC;          /* Disabling of CPLBs should be proceeded by a CSYNC */
        [P4] = R5;
        SSYNC;
 
@@ -1133,11 +1144,9 @@ ENTRY(_early_trap)
        P4.H = HI(DMEM_CONTROL);
        R5 = [P4];
        BITCLR(R5,ENDCPLB_P);
-       SSYNC;          /* SSYNC required before writing to DMEM_CONTROL. */
-       .align 8;
+       CSYNC;          /* Disabling of CPLBs should be proceeded by a CSYNC */
        [P4] = R5;
        SSYNC;
-       STI R1;
 
        r0 = sp;        /* stack frame pt_regs pointer argument ==> r0 */
        r1 = RETX;
index f826f6b9f917e168e31ef84604549424745015c7..9c79dfea2a53b42e94286b0bf52a0b947c29452d 100644 (file)
@@ -124,22 +124,22 @@ ENTRY(__start)
         * below
         */
        GET_PDA(p0, r0);
-       r6 = [p0 + PDA_RETX];
+       r6 = [p0 + PDA_DF_RETX];
        p1.l = _init_saved_retx;
        p1.h = _init_saved_retx;
        [p1] = r6;
 
-       r6 = [p0 + PDA_DCPLB];
+       r6 = [p0 + PDA_DF_DCPLB];
        p1.l = _init_saved_dcplb_fault_addr;
        p1.h = _init_saved_dcplb_fault_addr;
        [p1] = r6;
 
-       r6 = [p0 + PDA_ICPLB];
+       r6 = [p0 + PDA_DF_ICPLB];
        p1.l = _init_saved_icplb_fault_addr;
        p1.h = _init_saved_icplb_fault_addr;
        [p1] = r6;
 
-       r6 = [p0 + PDA_SEQSTAT];
+       r6 = [p0 + PDA_DF_SEQSTAT];
        p1.l = _init_saved_seqstat;
        p1.h = _init_saved_seqstat;
        [p1] = r6;
@@ -153,6 +153,8 @@ ENTRY(__start)
 
 #ifdef CONFIG_EARLY_PRINTK
        call _init_early_exception_vectors;
+       r0 = (EVT_IVHW | EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU);
+       sti r0;
 #endif
 
        r0 = 0 (x);
@@ -212,12 +214,21 @@ ENTRY(__start)
        [p0] = p1;
        csync;
 
+#ifdef CONFIG_EARLY_PRINTK
+       r0 = (EVT_IVG15 | EVT_IVHW | EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU) (z);
+#else
        r0 = EVT_IVG15 (z);
+#endif
        sti r0;
 
        raise 15;
+#ifdef CONFIG_EARLY_PRINTK
+       p0.l = _early_trap;
+       p0.h = _early_trap;
+#else
        p0.l = .LWAIT_HERE;
        p0.h = .LWAIT_HERE;
+#endif
        reti = p0;
 #if ANOMALY_05000281
        nop; nop; nop;
index 9c46680186e4de2cab991257451d2f96c50e3dde..82d417ef4b5bc2933a75f5863ba1c68d36c14dc4 100644 (file)
@@ -119,14 +119,8 @@ __common_int_entry:
        fp = 0;
 #endif
 
-#if ANOMALY_05000283 || ANOMALY_05000315
-       cc = r7 == r7;
-       p5.h = HI(CHIPID);
-       p5.l = LO(CHIPID);
-       if cc jump 1f;
-       r7.l = W[p5];
-1:
-#endif
+       ANOMALY_283_315_WORKAROUND(p5, r7)
+
        r1 =  sp;
        SP += -12;
 #ifdef CONFIG_IPIPE
@@ -158,14 +152,7 @@ ENTRY(_evt_ivhw)
        fp = 0;
 #endif
 
-#if ANOMALY_05000283 || ANOMALY_05000315
-       cc = r7 == r7;
-       p5.h = HI(CHIPID);
-       p5.l = LO(CHIPID);
-       if cc jump 1f;
-       r7.l = W[p5];
-1:
-#endif
+       ANOMALY_283_315_WORKAROUND(p5, r7)
 
        /* Handle all stacked hardware errors
         * To make sure we don't hang forever, only do it 10 times
@@ -261,6 +248,31 @@ ENTRY(_evt_system_call)
 ENDPROC(_evt_system_call)
 
 #ifdef CONFIG_IPIPE
+/*
+ * __ipipe_call_irqtail: lowers the current priority level to EVT15
+ * before running a user-defined routine, then raises the priority
+ * level to EVT14 to prepare the caller for a normal interrupt
+ * return through RTI.
+ *
+ * We currently use this facility in two occasions:
+ *
+ * - to branch to __ipipe_irq_tail_hook as requested by a high
+ *   priority domain after the pipeline delivered an interrupt,
+ *   e.g. such as Xenomai, in order to start its rescheduling
+ *   procedure, since we may not switch tasks when IRQ levels are
+ *   nested on the Blackfin, so we have to fake an interrupt return
+ *   so that we may reschedule immediately.
+ *
+ * - to branch to sync_root_irqs, in order to play any interrupt
+ *   pending for the root domain (i.e. the Linux kernel). This lowers
+ *   the core priority level enough so that Linux IRQ handlers may
+ *   never delay interrupts handled by high priority domains; we defer
+ *   those handlers until this point instead. This is a substitute
+ *   to using a threaded interrupt model for the Linux kernel.
+ *
+ * r0: address of user-defined routine
+ * context: caller must have preempted EVT15, hw interrupts must be off.
+ */
 ENTRY(___ipipe_call_irqtail)
        p0 = r0;
        r0.l = 1f;
@@ -276,33 +288,19 @@ ENTRY(___ipipe_call_irqtail)
        ( r7:4, p5:3 ) = [sp++];
        rets = [sp++];
 
-       [--sp] = reti;
-       reti = [sp++];          /* IRQs are off. */
-       r0.h = 3f;
-       r0.l = 3f;
-       p0.l = lo(EVT14);
-       p0.h = hi(EVT14);
-       [p0] = r0;
-       csync;
-       r0 = 0x401f (z);
+#ifdef CONFIG_DEBUG_HWERR
+       /* enable irq14 & hwerr interrupt, until we transition to _evt_evt14 */
+       r0 = (EVT_IVG14 | EVT_IVHW | \
+               EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU);
+#else
+       /* Only enable irq14 interrupt, until we transition to _evt_evt14 */
+       r0 = (EVT_IVG14 | \
+               EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU);
+#endif
        sti r0;
-       raise 14;
-       [--sp] = reti;          /* IRQs on. */
+       raise 14;               /* Branches to _evt_evt14 */
 2:
        jump 2b;                /* Likely paranoid. */
-3:
-       sp += 4;                /* Discard saved RETI */
-       r0.h = _evt14_softirq;
-       r0.l = _evt14_softirq;
-       p0.l = lo(EVT14);
-       p0.h = hi(EVT14);
-       [p0] = r0;
-       csync;
-       p0.l = _bfin_irq_flags;
-       p0.h = _bfin_irq_flags;
-       r0 = [p0];
-       sti r0;
-       rts;
 ENDPROC(___ipipe_call_irqtail)
 
 #endif /* CONFIG_IPIPE */
index b42150190d0e39812377e9d2a4cea6a9025625ed..6ffda78aaf9d57383dcaa1747f7c888d3ea0ab5f 100644 (file)
@@ -967,7 +967,7 @@ void __cpuinit init_exception_vectors(void)
        bfin_write_EVT11(evt_evt11);
        bfin_write_EVT12(evt_evt12);
        bfin_write_EVT13(evt_evt13);
-       bfin_write_EVT14(evt14_softirq);
+       bfin_write_EVT14(evt_evt14);
        bfin_write_EVT15(evt_system_call);
        CSYNC();
 }
@@ -1052,18 +1052,26 @@ int __init init_arch_irq(void)
                        set_irq_chained_handler(irq, bfin_demux_error_irq);
                        break;
 #endif
+
 #ifdef CONFIG_SMP
+#ifdef CONFIG_TICKSOURCE_GPTMR0
+               case IRQ_TIMER0:
+#endif
+#ifdef CONFIG_TICKSOURCE_CORETMR
+               case IRQ_CORETMR:
+#endif
                case IRQ_SUPPLE_0:
                case IRQ_SUPPLE_1:
                        set_irq_handler(irq, handle_percpu_irq);
                        break;
 #endif
+
 #ifdef CONFIG_IPIPE
 #ifndef CONFIG_TICKSOURCE_CORETMR
                case IRQ_TIMER0:
                        set_irq_handler(irq, handle_simple_irq);
                        break;
-#endif /* !CONFIG_TICKSOURCE_CORETMR */
+#endif
                case IRQ_CORETMR:
                        set_irq_handler(irq, handle_simple_irq);
                        break;
@@ -1071,15 +1079,10 @@ int __init init_arch_irq(void)
                        set_irq_handler(irq, handle_level_irq);
                        break;
 #else /* !CONFIG_IPIPE */
-#ifdef CONFIG_TICKSOURCE_GPTMR0
-               case IRQ_TIMER0:
-                       set_irq_handler(irq, handle_percpu_irq);
-                       break;
-#endif /* CONFIG_TICKSOURCE_GPTMR0 */
                default:
                        set_irq_handler(irq, handle_simple_irq);
                        break;
-#endif /* !CONFIG_IPIPE */
+#endif /* !CONFIG_IPIPE */
                }
        }
 
diff --git a/arch/blackfin/mach-common/lock.S b/arch/blackfin/mach-common/lock.S
deleted file mode 100644 (file)
index 6c5f5f0..0000000
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * File:         arch/blackfin/mach-common/lock.S
- * Based on:
- * Author:       LG Soft India
- *
- * Created:      ?
- * Description:  kernel locks
- *
- * Modified:
- *               Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <linux/linkage.h>
-#include <asm/blackfin.h>
-
-.text
-
-/* When you come here, it is assumed that
- * R0 - Which way to be locked
- */
-
-ENTRY(_cache_grab_lock)
-
-       [--SP]=( R7:0,P5:0 );
-
-       P1.H = HI(IMEM_CONTROL);
-       P1.L = LO(IMEM_CONTROL);
-       P5.H = HI(ICPLB_ADDR0);
-       P5.L = LO(ICPLB_ADDR0);
-       P4.H = HI(ICPLB_DATA0);
-       P4.L = LO(ICPLB_DATA0);
-       R7 = R0;
-
-       /* If the code of interest already resides in the cache
-        * invalidate the entire cache itself.
-        * invalidate_entire_icache;
-        */
-
-       SP += -12;
-       [--SP] = RETS;
-       CALL _invalidate_entire_icache;
-       RETS = [SP++];
-       SP += 12;
-
-       /* Disable the Interrupts*/
-
-       CLI R3;
-
-.LLOCK_WAY:
-
-       /* Way0 - 0xFFA133E0
-        * Way1 - 0xFFA137E0
-        * Way2 - 0xFFA13BE0    Total Way Size = 4K
-        * Way3 - 0xFFA13FE0
-        */
-
-       /* Procedure Ex. -Set the locks for other ways by setting ILOC[3:1]
-        * Only Way0 of the instruction cache can now be
-        * replaced by a new code
-        */
-
-       R5 = R7;
-       CC = BITTST(R7,0);
-       IF CC JUMP .LCLEAR1;
-       R7 = 0;
-       BITSET(R7,0);
-       JUMP .LDONE1;
-
-.LCLEAR1:
-       R7 = 0;
-       BITCLR(R7,0);
-.LDONE1:       R4 = R7 << 3;
-       R7 = [P1];
-       R7 = R7 | R4;
-       SSYNC;          /* SSYNC required writing to IMEM_CONTROL. */
-       .align 8;
-       [P1] = R7;
-       SSYNC;
-
-       R7 = R5;
-       CC = BITTST(R7,1);
-       IF CC JUMP .LCLEAR2;
-       R7 = 0;
-       BITSET(R7,1);
-       JUMP .LDONE2;
-
-.LCLEAR2:
-       R7 = 0;
-       BITCLR(R7,1);
-.LDONE2:       R4 = R7 << 3;
-       R7 = [P1];
-       R7 = R7 | R4;
-       SSYNC;          /* SSYNC required writing to IMEM_CONTROL. */
-       .align 8;
-       [P1] = R7;
-       SSYNC;
-
-       R7 = R5;
-       CC = BITTST(R7,2);
-       IF CC JUMP .LCLEAR3;
-       R7 = 0;
-       BITSET(R7,2);
-       JUMP .LDONE3;
-.LCLEAR3:
-       R7 = 0;
-       BITCLR(R7,2);
-.LDONE3:       R4 = R7 << 3;
-       R7 = [P1];
-       R7 = R7 | R4;
-       SSYNC;          /* SSYNC required writing to IMEM_CONTROL. */
-       .align 8;
-       [P1] = R7;
-       SSYNC;
-
-
-       R7 = R5;
-       CC = BITTST(R7,3);
-       IF CC JUMP .LCLEAR4;
-       R7 = 0;
-       BITSET(R7,3);
-       JUMP .LDONE4;
-.LCLEAR4:
-       R7 = 0;
-       BITCLR(R7,3);
-.LDONE4:       R4 = R7 << 3;
-       R7 = [P1];
-       R7 = R7 | R4;
-       SSYNC;          /* SSYNC required writing to IMEM_CONTROL. */
-       .align 8;
-       [P1] = R7;
-       SSYNC;
-
-       STI R3;
-
-       ( R7:0,P5:0 ) = [SP++];
-
-       RTS;
-ENDPROC(_cache_grab_lock)
-
-/* After the execution of critical code, the code is now locked into
- * the cache way. Now we need to set ILOC.
- *
- * R0 - Which way to be locked
- */
-
-ENTRY(_bfin_cache_lock)
-
-       [--SP]=( R7:0,P5:0 );
-
-       P1.H = HI(IMEM_CONTROL);
-       P1.L = LO(IMEM_CONTROL);
-
-       /* Disable the Interrupts*/
-       CLI R3;
-
-       R7 = [P1];
-       R2 = ~(0x78) (X);       /* mask out ILOC */
-       R7 = R7 & R2;
-       R0 = R0 << 3;
-       R7 = R0 | R7;
-       SSYNC;          /* SSYNC required writing to IMEM_CONTROL. */
-       .align 8;
-       [P1] = R7;
-       SSYNC;
-       /* Renable the Interrupts */
-       STI R3;
-
-       ( R7:0,P5:0 ) = [SP++];
-       RTS;
-ENDPROC(_bfin_cache_lock)
-
-/* Invalidate the Entire Instruction cache by
- * disabling IMC bit
- */
-ENTRY(_invalidate_entire_icache)
-       [--SP] = ( R7:5);
-
-       P0.L = LO(IMEM_CONTROL);
-       P0.H = HI(IMEM_CONTROL);
-       R7 = [P0];
-
-       /* Clear the IMC bit , All valid bits in the instruction
-        * cache are set to the invalid state
-        */
-       BITCLR(R7,IMC_P);
-       CLI R6;
-       SSYNC;          /* SSYNC required before invalidating cache. */
-       .align 8;
-       [P0] = R7;
-       SSYNC;
-       STI R6;
-
-       /* Configures the instruction cache agian */
-       R6 = (IMC | ENICPLB);
-       R7 = R7 | R6;
-
-       CLI R6;
-       SSYNC;          /* SSYNC required before writing to IMEM_CONTROL. */
-       .align 8;
-       [P0] = R7;
-       SSYNC;
-       STI R6;
-
-       ( R7:5) = [SP++];
-       RTS;
-ENDPROC(_invalidate_entire_icache)
index 9e7e27b7fc8d3fbc5c1aca0b2ea84a9e774b0941..0e3d4ff9d8b677ff22ac28dbc9725579b5f13c69 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/io.h>
 #include <linux/irq.h>
 
+#include <asm/cplb.h>
 #include <asm/gpio.h>
 #include <asm/dma.h>
 #include <asm/dpmc.h>
@@ -170,58 +171,6 @@ static void flushinv_all_dcache(void)
 }
 #endif
 
-static inline void dcache_disable(void)
-{
-#ifdef CONFIG_BFIN_DCACHE
-       unsigned long ctrl;
-
-#if defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK)
-       flushinv_all_dcache();
-#endif
-       SSYNC();
-       ctrl = bfin_read_DMEM_CONTROL();
-       ctrl &= ~ENDCPLB;
-       bfin_write_DMEM_CONTROL(ctrl);
-       SSYNC();
-#endif
-}
-
-static inline void dcache_enable(void)
-{
-#ifdef CONFIG_BFIN_DCACHE
-       unsigned long ctrl;
-       SSYNC();
-       ctrl = bfin_read_DMEM_CONTROL();
-       ctrl |= ENDCPLB;
-       bfin_write_DMEM_CONTROL(ctrl);
-       SSYNC();
-#endif
-}
-
-static inline void icache_disable(void)
-{
-#ifdef CONFIG_BFIN_ICACHE
-       unsigned long ctrl;
-       SSYNC();
-       ctrl = bfin_read_IMEM_CONTROL();
-       ctrl &= ~ENICPLB;
-       bfin_write_IMEM_CONTROL(ctrl);
-       SSYNC();
-#endif
-}
-
-static inline void icache_enable(void)
-{
-#ifdef CONFIG_BFIN_ICACHE
-       unsigned long ctrl;
-       SSYNC();
-       ctrl = bfin_read_IMEM_CONTROL();
-       ctrl |= ENICPLB;
-       bfin_write_IMEM_CONTROL(ctrl);
-       SSYNC();
-#endif
-}
-
 int bfin_pm_suspend_mem_enter(void)
 {
        unsigned long flags;
@@ -258,16 +207,19 @@ int bfin_pm_suspend_mem_enter(void)
 
        bfin_gpio_pm_hibernate_suspend();
 
-       dcache_disable();
-       icache_disable();
+#if defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK)
+       flushinv_all_dcache();
+#endif
+       _disable_dcplb();
+       _disable_icplb();
        bf53x_suspend_l1_mem(memptr);
 
        do_hibernate(wakeup | vr_wakeup);       /* Goodbye */
 
        bf53x_resume_l1_mem(memptr);
 
-       icache_enable();
-       dcache_enable();
+       _enable_icplb();
+       _enable_dcplb();
 
        bfin_gpio_pm_hibernate_restore();
        blackfin_dma_resume();
index 68bd0bd680cd19efa12d3ae806d3d355f272114b..b88ce7fda548c7e76303f842ad485fd173c7118c 100644 (file)
@@ -33,6 +33,7 @@
 #include <asm/bfin-global.h>
 #include <asm/pda.h>
 #include <asm/cplbinit.h>
+#include <asm/early_printk.h>
 #include "blackfin_sram.h"
 
 /*
@@ -113,6 +114,8 @@ asmlinkage void __init init_pda(void)
 {
        unsigned int cpu = raw_smp_processor_id();
 
+       early_shadow_stamp();
+
        /* Initialize the PDA fields holding references to other parts
           of the memory. The content of such memory is still
           undefined at the time of the call, we are only setting up
index c080e70f98b0c579eafbb7d07365daaa2f8d484c..beb1a608824c1f7c47225a493158477503b9ce76 100644 (file)
@@ -16,6 +16,8 @@
  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#define pr_fmt(fmt) "isram: " fmt
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -23,6 +25,7 @@
 #include <linux/sched.h>
 
 #include <asm/blackfin.h>
+#include <asm/dma.h>
 
 /*
  * IMPORTANT WARNING ABOUT THESE FUNCTIONS
@@ -50,10 +53,12 @@ static DEFINE_SPINLOCK(dtest_lock);
 #define IADDR2DTEST(x) \
        ({ unsigned long __addr = (unsigned long)(x); \
                (__addr & 0x47F8)        | /* address bits 14 & 10:3 */ \
+               (__addr & 0x8000) << 23  | /* Bank A/B               */ \
                (__addr & 0x0800) << 15  | /* address bit  11        */ \
-               (__addr  & 0x3000) << 4  | /* address bits 13:12     */ \
-               (__addr  & 0x8000) << 8  | /* address bit  15        */ \
-               (0x1000004);               /* isram access           */ \
+               (__addr & 0x3000) <<  4  | /* address bits 13:12     */ \
+               (__addr & 0x8000) <<  8  | /* address bit  15        */ \
+               (0x1000000)              | /* instruction access = 1 */ \
+               (0x4);                     /* data array = 1         */ \
        })
 
 /* Takes a pointer, and returns the offset (in bits) which things should be shifted */
@@ -70,7 +75,7 @@ static void isram_write(const void *addr, uint64_t data)
        if (addr >= (void *)(L1_CODE_START + L1_CODE_LENGTH))
                return;
 
-       cmd = IADDR2DTEST(addr) | 1;             /* write */
+       cmd = IADDR2DTEST(addr) | 2;             /* write */
 
        /*
         * Writes to DTEST_DATA[0:1] need to be atomic with write to DTEST_COMMAND
@@ -127,8 +132,7 @@ static bool isram_check_addr(const void *addr, size_t n)
            (addr < (void *)(L1_CODE_START + L1_CODE_LENGTH))) {
                if ((addr + n) > (void *)(L1_CODE_START + L1_CODE_LENGTH)) {
                        show_stack(NULL, NULL);
-                       printk(KERN_ERR "isram_memcpy: copy involving %p length "
-                                       "(%zu) too long\n", addr, n);
+                       pr_err("copy involving %p length (%zu) too long\n", addr, n);
                }
                return true;
        }
@@ -199,3 +203,209 @@ void *isram_memcpy(void *dest, const void *src, size_t n)
 }
 EXPORT_SYMBOL(isram_memcpy);
 
+#ifdef CONFIG_BFIN_ISRAM_SELF_TEST
+
+#define TEST_LEN 0x100
+
+static __init void hex_dump(unsigned char *buf, int len)
+{
+       while (len--)
+               pr_cont("%02x", *buf++);
+}
+
+static __init int isram_read_test(char *sdram, void *l1inst)
+{
+       int i, ret = 0;
+       uint64_t data1, data2;
+
+       pr_info("INFO: running isram_read tests\n");
+
+       /* setup some different data to play with */
+       for (i = 0; i < TEST_LEN; ++i)
+               sdram[i] = i;
+       dma_memcpy(l1inst, sdram, TEST_LEN);
+
+       /* make sure we can read the L1 inst */
+       for (i = 0; i < TEST_LEN; i += sizeof(uint64_t)) {
+               data1 = isram_read(l1inst + i);
+               memcpy(&data2, sdram + i, sizeof(data2));
+               if (memcmp(&data1, &data2, sizeof(uint64_t))) {
+                       pr_err("FAIL: isram_read(%p) returned %#llx but wanted %#llx\n",
+                               l1inst + i, data1, data2);
+                       ++ret;
+               }
+       }
+
+       return ret;
+}
+
+static __init int isram_write_test(char *sdram, void *l1inst)
+{
+       int i, ret = 0;
+       uint64_t data1, data2;
+
+       pr_info("INFO: running isram_write tests\n");
+
+       /* setup some different data to play with */
+       memset(sdram, 0, TEST_LEN * 2);
+       dma_memcpy(l1inst, sdram, TEST_LEN);
+       for (i = 0; i < TEST_LEN; ++i)
+               sdram[i] = i;
+
+       /* make sure we can write the L1 inst */
+       for (i = 0; i < TEST_LEN; i += sizeof(uint64_t)) {
+               memcpy(&data1, sdram + i, sizeof(data1));
+               isram_write(l1inst + i, data1);
+               data2 = isram_read(l1inst + i);
+               if (memcmp(&data1, &data2, sizeof(uint64_t))) {
+                       pr_err("FAIL: isram_write(%p, %#llx) != %#llx\n",
+                               l1inst + i, data1, data2);
+                       ++ret;
+               }
+       }
+
+       dma_memcpy(sdram + TEST_LEN, l1inst, TEST_LEN);
+       if (memcmp(sdram, sdram + TEST_LEN, TEST_LEN)) {
+               pr_err("FAIL: isram_write() did not work properly\n");
+               ++ret;
+       }
+
+       return ret;
+}
+
+static __init int
+_isram_memcpy_test(char pattern, void *sdram, void *l1inst, const char *smemcpy,
+                   void *(*fmemcpy)(void *, const void *, size_t))
+{
+       memset(sdram, pattern, TEST_LEN);
+       fmemcpy(l1inst, sdram, TEST_LEN);
+       fmemcpy(sdram + TEST_LEN, l1inst, TEST_LEN);
+       if (memcmp(sdram, sdram + TEST_LEN, TEST_LEN)) {
+               pr_err("FAIL: %s(%p <=> %p, %#x) failed (data is %#x)\n",
+                       smemcpy, l1inst, sdram, TEST_LEN, pattern);
+               return 1;
+       }
+       return 0;
+}
+#define _isram_memcpy_test(a, b, c, d) _isram_memcpy_test(a, b, c, #d, d)
+
+static __init int isram_memcpy_test(char *sdram, void *l1inst)
+{
+       int i, j, thisret, ret = 0;
+
+       /* check broad isram_memcpy() */
+       pr_info("INFO: running broad isram_memcpy tests\n");
+       for (i = 0xf; i >= 0; --i)
+               ret += _isram_memcpy_test(i, sdram, l1inst, isram_memcpy);
+
+       /* check read of small, unaligned, and hardware 64bit limits */
+       pr_info("INFO: running isram_memcpy (read) tests\n");
+
+       for (i = 0; i < TEST_LEN; ++i)
+               sdram[i] = i;
+       dma_memcpy(l1inst, sdram, TEST_LEN);
+
+       thisret = 0;
+       for (i = 0; i < TEST_LEN - 32; ++i) {
+               unsigned char cmp[32];
+               for (j = 1; j <= 32; ++j) {
+                       memset(cmp, 0, sizeof(cmp));
+                       isram_memcpy(cmp, l1inst + i, j);
+                       if (memcmp(cmp, sdram + i, j)) {
+                               pr_err("FAIL: %p:", l1inst + 1);
+                               hex_dump(cmp, j);
+                               pr_cont(" SDRAM:");
+                               hex_dump(sdram + i, j);
+                               pr_cont("\n");
+                               if (++thisret > 20) {
+                                       pr_err("FAIL: skipping remaining series\n");
+                                       i = TEST_LEN;
+                                       break;
+                               }
+                       }
+               }
+       }
+       ret += thisret;
+
+       /* check write of small, unaligned, and hardware 64bit limits */
+       pr_info("INFO: running isram_memcpy (write) tests\n");
+
+       memset(sdram + TEST_LEN, 0, TEST_LEN);
+       dma_memcpy(l1inst, sdram + TEST_LEN, TEST_LEN);
+
+       thisret = 0;
+       for (i = 0; i < TEST_LEN - 32; ++i) {
+               unsigned char cmp[32];
+               for (j = 1; j <= 32; ++j) {
+                       isram_memcpy(l1inst + i, sdram + i, j);
+                       dma_memcpy(cmp, l1inst + i, j);
+                       if (memcmp(cmp, sdram + i, j)) {
+                               pr_err("FAIL: %p:", l1inst + i);
+                               hex_dump(cmp, j);
+                               pr_cont(" SDRAM:");
+                               hex_dump(sdram + i, j);
+                               pr_cont("\n");
+                               if (++thisret > 20) {
+                                       pr_err("FAIL: skipping remaining series\n");
+                                       i = TEST_LEN;
+                                       break;
+                               }
+                       }
+               }
+       }
+       ret += thisret;
+
+       return ret;
+}
+
+static __init int isram_test_init(void)
+{
+       int ret;
+       char *sdram;
+       void *l1inst;
+
+       sdram = kmalloc(TEST_LEN * 2, GFP_KERNEL);
+       if (!sdram) {
+               pr_warning("SKIP: could not allocate sdram\n");
+               return 0;
+       }
+
+       l1inst = l1_inst_sram_alloc(TEST_LEN);
+       if (!l1inst) {
+               kfree(sdram);
+               pr_warning("SKIP: could not allocate L1 inst\n");
+               return 0;
+       }
+
+       /* sanity check initial L1 inst state */
+       ret = 1;
+       pr_info("INFO: running initial dma_memcpy checks\n");
+       if (_isram_memcpy_test(0xa, sdram, l1inst, dma_memcpy))
+               goto abort;
+       if (_isram_memcpy_test(0x5, sdram, l1inst, dma_memcpy))
+               goto abort;
+
+       ret = 0;
+       ret += isram_read_test(sdram, l1inst);
+       ret += isram_write_test(sdram, l1inst);
+       ret += isram_memcpy_test(sdram, l1inst);
+
+ abort:
+       sram_free(l1inst);
+       kfree(sdram);
+
+       if (ret)
+               return -EIO;
+
+       pr_info("PASS: all tests worked !\n");
+       return 0;
+}
+late_initcall(isram_test_init);
+
+static __exit void isram_test_exit(void)
+{
+       /* stub to allow unloading */
+}
+module_exit(isram_test_exit);
+
+#endif
index 99e4dbb1dfd12502becc3d2506f3d51a1076433d..eb63ab353e5a1efdd5a124eade0fb1b355de4490 100644 (file)
 #include <asm/mem_map.h>
 #include "blackfin_sram.h"
 
-static DEFINE_PER_CPU_SHARED_ALIGNED(spinlock_t, l1sram_lock);
-static DEFINE_PER_CPU_SHARED_ALIGNED(spinlock_t, l1_data_sram_lock);
-static DEFINE_PER_CPU_SHARED_ALIGNED(spinlock_t, l1_inst_sram_lock);
-static spinlock_t l2_sram_lock ____cacheline_aligned_in_smp;
-
 /* the data structure for L1 scratchpad and DATA SRAM */
 struct sram_piece {
        void *paddr;
@@ -55,6 +50,7 @@ struct sram_piece {
        struct sram_piece *next;
 };
 
+static DEFINE_PER_CPU_SHARED_ALIGNED(spinlock_t, l1sram_lock);
 static DEFINE_PER_CPU(struct sram_piece, free_l1_ssram_head);
 static DEFINE_PER_CPU(struct sram_piece, used_l1_ssram_head);
 
@@ -68,12 +64,18 @@ static DEFINE_PER_CPU(struct sram_piece, free_l1_data_B_sram_head);
 static DEFINE_PER_CPU(struct sram_piece, used_l1_data_B_sram_head);
 #endif
 
+#if L1_DATA_A_LENGTH || L1_DATA_B_LENGTH
+static DEFINE_PER_CPU_SHARED_ALIGNED(spinlock_t, l1_data_sram_lock);
+#endif
+
 #if L1_CODE_LENGTH != 0
+static DEFINE_PER_CPU_SHARED_ALIGNED(spinlock_t, l1_inst_sram_lock);
 static DEFINE_PER_CPU(struct sram_piece, free_l1_inst_sram_head);
 static DEFINE_PER_CPU(struct sram_piece, used_l1_inst_sram_head);
 #endif
 
 #if L2_LENGTH != 0
+static spinlock_t l2_sram_lock ____cacheline_aligned_in_smp;
 static struct sram_piece free_l2_sram_head, used_l2_sram_head;
 #endif
 
@@ -225,10 +227,10 @@ static void __init l2_sram_init(void)
        printk(KERN_INFO "Blackfin L2 SRAM: %d KB (%d KB free)\n",
                L2_LENGTH >> 10,
                free_l2_sram_head.next->size >> 10);
-#endif
 
        /* mutex initialize */
        spin_lock_init(&l2_sram_lock);
+#endif
 }
 
 static int __init bfin_sram_init(void)
@@ -416,18 +418,17 @@ EXPORT_SYMBOL(sram_free);
 
 void *l1_data_A_sram_alloc(size_t size)
 {
+#if L1_DATA_A_LENGTH != 0
        unsigned long flags;
-       void *addr = NULL;
+       void *addr;
        unsigned int cpu;
 
        cpu = get_cpu();
        /* add mutex operation */
        spin_lock_irqsave(&per_cpu(l1_data_sram_lock, cpu), flags);
 
-#if L1_DATA_A_LENGTH != 0
        addr = _sram_alloc(size, &per_cpu(free_l1_data_A_sram_head, cpu),
                        &per_cpu(used_l1_data_A_sram_head, cpu));
-#endif
 
        /* add mutex operation */
        spin_unlock_irqrestore(&per_cpu(l1_data_sram_lock, cpu), flags);
@@ -437,11 +438,15 @@ void *l1_data_A_sram_alloc(size_t size)
                 (long unsigned int)addr, size);
 
        return addr;
+#else
+       return NULL;
+#endif
 }
 EXPORT_SYMBOL(l1_data_A_sram_alloc);
 
 int l1_data_A_sram_free(const void *addr)
 {
+#if L1_DATA_A_LENGTH != 0
        unsigned long flags;
        int ret;
        unsigned int cpu;
@@ -450,18 +455,17 @@ int l1_data_A_sram_free(const void *addr)
        /* add mutex operation */
        spin_lock_irqsave(&per_cpu(l1_data_sram_lock, cpu), flags);
 
-#if L1_DATA_A_LENGTH != 0
        ret = _sram_free(addr, &per_cpu(free_l1_data_A_sram_head, cpu),
                        &per_cpu(used_l1_data_A_sram_head, cpu));
-#else
-       ret = -1;
-#endif
 
        /* add mutex operation */
        spin_unlock_irqrestore(&per_cpu(l1_data_sram_lock, cpu), flags);
        put_cpu();
 
        return ret;
+#else
+       return -1;
+#endif
 }
 EXPORT_SYMBOL(l1_data_A_sram_free);
 
index 7b4c8c70b2d18f7949372899ab056f41d913ed6b..d0141fbf51d0a893626f110814f1f646610750fc 100644 (file)
@@ -61,12 +61,13 @@ void build_cpu_to_node_map(void);
        .cache_nice_tries       = 2,                    \
        .busy_idx               = 2,                    \
        .idle_idx               = 1,                    \
-       .newidle_idx            = 2,                    \
-       .wake_idx               = 1,                    \
-       .forkexec_idx           = 1,                    \
+       .newidle_idx            = 0,                    \
+       .wake_idx               = 0,                    \
+       .forkexec_idx           = 0,                    \
        .flags                  = SD_LOAD_BALANCE       \
                                | SD_BALANCE_NEWIDLE    \
                                | SD_BALANCE_EXEC       \
+                               | SD_BALANCE_FORK       \
                                | SD_WAKE_AFFINE,       \
        .last_balance           = jiffies,              \
        .balance_interval       = 1,                    \
@@ -85,14 +86,14 @@ void build_cpu_to_node_map(void);
        .cache_nice_tries       = 2,                    \
        .busy_idx               = 3,                    \
        .idle_idx               = 2,                    \
-       .newidle_idx            = 2,                    \
-       .wake_idx               = 1,                    \
-       .forkexec_idx           = 1,                    \
+       .newidle_idx            = 0,                    \
+       .wake_idx               = 0,                    \
+       .forkexec_idx           = 0,                    \
        .flags                  = SD_LOAD_BALANCE       \
+                               | SD_BALANCE_NEWIDLE    \
                                | SD_BALANCE_EXEC       \
                                | SD_BALANCE_FORK       \
-                               | SD_SERIALIZE          \
-                               | SD_WAKE_BALANCE,      \
+                               | SD_SERIALIZE,         \
        .last_balance           = jiffies,              \
        .balance_interval       = 64,                   \
        .nr_balance_failed      = 0,                    \
index e6c5c3d5e1f8ef79fb623bc82b656e11c2c6c938..23f846de62d58ae6e60a9c445911419daa4ff17f 100644 (file)
@@ -34,7 +34,6 @@
 #include <asm/mca_asm.h>
 #include <linux/init.h>
 #include <linux/linkage.h>
-#include "head.h"
 
 #ifdef CONFIG_HOTPLUG_CPU
 #define SAL_PSR_BITS_TO_SET                            \
diff --git a/arch/ia64/kernel/head.h b/arch/ia64/kernel/head.h
deleted file mode 100644 (file)
index 2e2ac68..0000000
+++ /dev/null
@@ -1 +0,0 @@
-extern void console_print(const char *s);
index 1cf544767453365adcb6a6e7916470c8f7597aa8..ec514485c8b6557bc18804c8f53589d4ed6eaefe 100644 (file)
@@ -1,5 +1,170 @@
-#ifdef __uClinux__
-#include "checksum_no.h"
+#ifndef _M68K_CHECKSUM_H
+#define _M68K_CHECKSUM_H
+
+#include <linux/in6.h>
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+__wsum csum_partial(const void *buff, int len, __wsum sum);
+
+/*
+ * the same as csum_partial, but copies from src while it
+ * checksums
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
+extern __wsum csum_partial_copy_from_user(const void __user *src,
+                                               void *dst,
+                                               int len, __wsum sum,
+                                               int *csum_err);
+
+extern __wsum csum_partial_copy_nocheck(const void *src,
+                                             void *dst, int len,
+                                             __wsum sum);
+
+
+#ifdef CONFIG_COLDFIRE
+
+/*
+ *     The ColdFire cores don't support all the 68k instructions used
+ *     in the optimized checksum code below. So it reverts back to using
+ *     more standard C coded checksums. The fast checksum code is
+ *     significantly larger than the optimized version, so it is not
+ *     inlined here.
+ */
+__sum16 ip_fast_csum(const void *iph, unsigned int ihl);
+
+static inline __sum16 csum_fold(__wsum sum)
+{
+       unsigned int tmp = (__force u32)sum;
+
+       tmp = (tmp & 0xffff) + (tmp >> 16);
+       tmp = (tmp & 0xffff) + (tmp >> 16);
+
+       return (__force __sum16)~tmp;
+}
+
 #else
-#include "checksum_mm.h"
-#endif
+
+/*
+ *     This is a version of ip_fast_csum() optimized for IP headers,
+ *     which always checksum on 4 octet boundaries.
+ */
+static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
+{
+       unsigned int sum = 0;
+       unsigned long tmp;
+
+       __asm__ ("subqw #1,%2\n"
+                "1:\t"
+                "movel %1@+,%3\n\t"
+                "addxl %3,%0\n\t"
+                "dbra  %2,1b\n\t"
+                "movel %0,%3\n\t"
+                "swap  %3\n\t"
+                "addxw %3,%0\n\t"
+                "clrw  %3\n\t"
+                "addxw %3,%0\n\t"
+                : "=d" (sum), "=&a" (iph), "=&d" (ihl), "=&d" (tmp)
+                : "0" (sum), "1" (iph), "2" (ihl)
+                : "memory");
+       return (__force __sum16)~sum;
+}
+
+static inline __sum16 csum_fold(__wsum sum)
+{
+       unsigned int tmp = (__force u32)sum;
+
+       __asm__("swap %1\n\t"
+               "addw %1, %0\n\t"
+               "clrw %1\n\t"
+               "addxw %1, %0"
+               : "=&d" (sum), "=&d" (tmp)
+               : "0" (sum), "1" (tmp));
+
+       return (__force __sum16)~sum;
+}
+
+#endif /* CONFIG_COLDFIRE */
+
+static inline __wsum
+csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
+                 unsigned short proto, __wsum sum)
+{
+       __asm__ ("addl  %2,%0\n\t"
+                "addxl %3,%0\n\t"
+                "addxl %4,%0\n\t"
+                "clrl %1\n\t"
+                "addxl %1,%0"
+                : "=&d" (sum), "=d" (saddr)
+                : "g" (daddr), "1" (saddr), "d" (len + proto),
+                  "0" (sum));
+       return sum;
+}
+
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+static inline __sum16
+csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
+                 unsigned short proto, __wsum sum)
+{
+       return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+
+static inline __sum16 ip_compute_csum(const void *buff, int len)
+{
+       return csum_fold (csum_partial(buff, len, 0));
+}
+
+#define _HAVE_ARCH_IPV6_CSUM
+static __inline__ __sum16
+csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
+               __u32 len, unsigned short proto, __wsum sum)
+{
+       register unsigned long tmp;
+       __asm__("addl %2@,%0\n\t"
+               "movel %2@(4),%1\n\t"
+               "addxl %1,%0\n\t"
+               "movel %2@(8),%1\n\t"
+               "addxl %1,%0\n\t"
+               "movel %2@(12),%1\n\t"
+               "addxl %1,%0\n\t"
+               "movel %3@,%1\n\t"
+               "addxl %1,%0\n\t"
+               "movel %3@(4),%1\n\t"
+               "addxl %1,%0\n\t"
+               "movel %3@(8),%1\n\t"
+               "addxl %1,%0\n\t"
+               "movel %3@(12),%1\n\t"
+               "addxl %1,%0\n\t"
+               "addxl %4,%0\n\t"
+               "clrl %1\n\t"
+               "addxl %1,%0"
+               : "=&d" (sum), "=&d" (tmp)
+               : "a" (saddr), "a" (daddr), "d" (len + proto),
+                 "0" (sum));
+
+       return csum_fold(sum);
+}
+
+#endif /* _M68K_CHECKSUM_H */
diff --git a/arch/m68k/include/asm/checksum_mm.h b/arch/m68k/include/asm/checksum_mm.h
deleted file mode 100644 (file)
index 494f9ae..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-#ifndef _M68K_CHECKSUM_H
-#define _M68K_CHECKSUM_H
-
-#include <linux/in6.h>
-
-/*
- * computes the checksum of a memory block at buff, length len,
- * and adds in "sum" (32-bit)
- *
- * returns a 32-bit number suitable for feeding into itself
- * or csum_tcpudp_magic
- *
- * this function must be called with even lengths, except
- * for the last fragment, which may be odd
- *
- * it's best to have buff aligned on a 32-bit boundary
- */
-__wsum csum_partial(const void *buff, int len, __wsum sum);
-
-/*
- * the same as csum_partial, but copies from src while it
- * checksums
- *
- * here even more important to align src and dst on a 32-bit (or even
- * better 64-bit) boundary
- */
-
-extern __wsum csum_partial_copy_from_user(const void __user *src,
-                                               void *dst,
-                                               int len, __wsum sum,
-                                               int *csum_err);
-
-extern __wsum csum_partial_copy_nocheck(const void *src,
-                                             void *dst, int len,
-                                             __wsum sum);
-
-/*
- *     This is a version of ip_compute_csum() optimized for IP headers,
- *     which always checksum on 4 octet boundaries.
- *
- */
-static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
-{
-       unsigned int sum = 0;
-       unsigned long tmp;
-
-       __asm__ ("subqw #1,%2\n"
-                "1:\t"
-                "movel %1@+,%3\n\t"
-                "addxl %3,%0\n\t"
-                "dbra  %2,1b\n\t"
-                "movel %0,%3\n\t"
-                "swap  %3\n\t"
-                "addxw %3,%0\n\t"
-                "clrw  %3\n\t"
-                "addxw %3,%0\n\t"
-                : "=d" (sum), "=&a" (iph), "=&d" (ihl), "=&d" (tmp)
-                : "0" (sum), "1" (iph), "2" (ihl)
-                : "memory");
-       return (__force __sum16)~sum;
-}
-
-/*
- *     Fold a partial checksum
- */
-
-static inline __sum16 csum_fold(__wsum sum)
-{
-       unsigned int tmp = (__force u32)sum;
-       __asm__("swap %1\n\t"
-               "addw %1, %0\n\t"
-               "clrw %1\n\t"
-               "addxw %1, %0"
-               : "=&d" (sum), "=&d" (tmp)
-               : "0" (sum), "1" (tmp));
-       return (__force __sum16)~sum;
-}
-
-
-static inline __wsum
-csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
-                 unsigned short proto, __wsum sum)
-{
-       __asm__ ("addl  %2,%0\n\t"
-                "addxl %3,%0\n\t"
-                "addxl %4,%0\n\t"
-                "clrl %1\n\t"
-                "addxl %1,%0"
-                : "=&d" (sum), "=d" (saddr)
-                : "g" (daddr), "1" (saddr), "d" (len + proto),
-                  "0" (sum));
-       return sum;
-}
-
-
-/*
- * computes the checksum of the TCP/UDP pseudo-header
- * returns a 16-bit checksum, already complemented
- */
-static inline __sum16
-csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
-                 unsigned short proto, __wsum sum)
-{
-       return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
-}
-
-/*
- * this routine is used for miscellaneous IP-like checksums, mainly
- * in icmp.c
- */
-
-static inline __sum16 ip_compute_csum(const void *buff, int len)
-{
-       return csum_fold (csum_partial(buff, len, 0));
-}
-
-#define _HAVE_ARCH_IPV6_CSUM
-static __inline__ __sum16
-csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
-               __u32 len, unsigned short proto, __wsum sum)
-{
-       register unsigned long tmp;
-       __asm__("addl %2@,%0\n\t"
-               "movel %2@(4),%1\n\t"
-               "addxl %1,%0\n\t"
-               "movel %2@(8),%1\n\t"
-               "addxl %1,%0\n\t"
-               "movel %2@(12),%1\n\t"
-               "addxl %1,%0\n\t"
-               "movel %3@,%1\n\t"
-               "addxl %1,%0\n\t"
-               "movel %3@(4),%1\n\t"
-               "addxl %1,%0\n\t"
-               "movel %3@(8),%1\n\t"
-               "addxl %1,%0\n\t"
-               "movel %3@(12),%1\n\t"
-               "addxl %1,%0\n\t"
-               "addxl %4,%0\n\t"
-               "clrl %1\n\t"
-               "addxl %1,%0"
-               : "=&d" (sum), "=&d" (tmp)
-               : "a" (saddr), "a" (daddr), "d" (len + proto),
-                 "0" (sum));
-
-       return csum_fold(sum);
-}
-
-#endif /* _M68K_CHECKSUM_H */
diff --git a/arch/m68k/include/asm/checksum_no.h b/arch/m68k/include/asm/checksum_no.h
deleted file mode 100644 (file)
index 8188348..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-#ifndef _M68K_CHECKSUM_H
-#define _M68K_CHECKSUM_H
-
-#include <linux/in6.h>
-
-/*
- * computes the checksum of a memory block at buff, length len,
- * and adds in "sum" (32-bit)
- *
- * returns a 32-bit number suitable for feeding into itself
- * or csum_tcpudp_magic
- *
- * this function must be called with even lengths, except
- * for the last fragment, which may be odd
- *
- * it's best to have buff aligned on a 32-bit boundary
- */
-__wsum csum_partial(const void *buff, int len, __wsum sum);
-
-/*
- * the same as csum_partial, but copies from src while it
- * checksums
- *
- * here even more important to align src and dst on a 32-bit (or even
- * better 64-bit) boundary
- */
-
-__wsum csum_partial_copy_nocheck(const void *src, void *dst,
-       int len, __wsum sum);
-
-
-/*
- * the same as csum_partial_copy, but copies from user space.
- *
- * here even more important to align src and dst on a 32-bit (or even
- * better 64-bit) boundary
- */
-
-extern __wsum csum_partial_copy_from_user(const void __user *src,
-       void *dst, int len, __wsum sum, int *csum_err);
-
-__sum16 ip_fast_csum(const void *iph, unsigned int ihl);
-
-/*
- *     Fold a partial checksum
- */
-
-static inline __sum16 csum_fold(__wsum sum)
-{
-       unsigned int tmp = (__force u32)sum;
-#ifdef CONFIG_COLDFIRE
-       tmp = (tmp & 0xffff) + (tmp >> 16);
-       tmp = (tmp & 0xffff) + (tmp >> 16);
-       return (__force __sum16)~tmp;
-#else
-       __asm__("swap %1\n\t"
-               "addw %1, %0\n\t"
-               "clrw %1\n\t"
-               "addxw %1, %0"
-               : "=&d" (sum), "=&d" (tmp)
-               : "0" (sum), "1" (sum));
-       return (__force __sum16)~sum;
-#endif
-}
-
-
-/*
- * computes the checksum of the TCP/UDP pseudo-header
- * returns a 16-bit checksum, already complemented
- */
-
-static inline __wsum
-csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
-                 unsigned short proto, __wsum sum)
-{
-       __asm__ ("addl  %1,%0\n\t"
-                "addxl %4,%0\n\t"
-                "addxl %5,%0\n\t"
-                "clrl %1\n\t"
-                "addxl %1,%0"
-                : "=&d" (sum), "=&d" (saddr)
-                : "0" (daddr), "1" (saddr), "d" (len + proto),
-                  "d"(sum));
-       return sum;
-}
-
-static inline __sum16
-csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
-                 unsigned short proto, __wsum sum)
-{
-       return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
-}
-
-/*
- * this routine is used for miscellaneous IP-like checksums, mainly
- * in icmp.c
- */
-
-extern __sum16 ip_compute_csum(const void *buff, int len);
-
-#define _HAVE_ARCH_IPV6_CSUM
-static __inline__ __sum16
-csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
-               __u32 len, unsigned short proto, __wsum sum)
-{
-       register unsigned long tmp;
-       __asm__("addl %2@,%0\n\t"
-               "movel %2@(4),%1\n\t"
-               "addxl %1,%0\n\t"
-               "movel %2@(8),%1\n\t"
-               "addxl %1,%0\n\t"
-               "movel %2@(12),%1\n\t"
-               "addxl %1,%0\n\t"
-               "movel %3@,%1\n\t"
-               "addxl %1,%0\n\t"
-               "movel %3@(4),%1\n\t"
-               "addxl %1,%0\n\t"
-               "movel %3@(8),%1\n\t"
-               "addxl %1,%0\n\t"
-               "movel %3@(12),%1\n\t"
-               "addxl %1,%0\n\t"
-               "addxl %4,%0\n\t"
-               "clrl %1\n\t"
-               "addxl %1,%0"
-               : "=&d" (sum), "=&d" (tmp)
-               : "a" (saddr), "a" (daddr), "d" (len + proto),
-                 "0" (sum));
-
-       return csum_fold(sum);
-}
-
-#endif /* _M68K_CHECKSUM_H */
index b82e660cf1c28d7e9321433f9973ac7c22821c9d..6fbdfe8951042e6498d37df345d24ce7fb64cf5b 100644 (file)
@@ -1,5 +1,491 @@
-#ifdef __uClinux__
-#include "dma_no.h"
+#ifndef _M68K_DMA_H
+#define _M68K_DMA_H 1
+
+#ifdef CONFIG_COLDFIRE
+/*
+ * ColdFire DMA Model:
+ *   ColdFire DMA supports two forms of DMA: Single and Dual address. Single
+ * address mode emits a source address, and expects that the device will either
+ * pick up the data (DMA READ) or source data (DMA WRITE). This implies that
+ * the device will place data on the correct byte(s) of the data bus, as the
+ * memory transactions are always 32 bits. This implies that only 32 bit
+ * devices will find single mode transfers useful. Dual address DMA mode
+ * performs two cycles: source read and destination write. ColdFire will
+ * align the data so that the device will always get the correct bytes, thus
+ * is useful for 8 and 16 bit devices. This is the mode that is supported
+ * below.
+ *
+ * AUG/22/2000 : added support for 32-bit Dual-Address-Mode (K) 2000
+ *               Oliver Kamphenkel (O.Kamphenkel@tu-bs.de)
+ *
+ * AUG/25/2000 : addad support for 8, 16 and 32-bit Single-Address-Mode (K)2000
+ *               Oliver Kamphenkel (O.Kamphenkel@tu-bs.de)
+ *
+ * APR/18/2002 : added proper support for MCF5272 DMA controller.
+ *               Arthur Shipkowski (art@videon-central.com)
+ */
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfdma.h>
+
+/*
+ * Set number of channels of DMA on ColdFire for different implementations.
+ */
+#if defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) || \
+       defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
+#define MAX_M68K_DMA_CHANNELS 4
+#elif defined(CONFIG_M5272)
+#define MAX_M68K_DMA_CHANNELS 1
+#elif defined(CONFIG_M532x)
+#define MAX_M68K_DMA_CHANNELS 0
 #else
-#include "dma_mm.h"
+#define MAX_M68K_DMA_CHANNELS 2
 #endif
+
+extern unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS];
+extern unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
+
+#if !defined(CONFIG_M5272)
+#define DMA_MODE_WRITE_BIT  0x01  /* Memory/IO to IO/Memory select */
+#define DMA_MODE_WORD_BIT   0x02  /* 8 or 16 bit transfers */
+#define DMA_MODE_LONG_BIT   0x04  /* or 32 bit transfers */
+#define DMA_MODE_SINGLE_BIT 0x08  /* single-address-mode */
+
+/* I/O to memory, 8 bits, mode */
+#define DMA_MODE_READ              0
+/* memory to I/O, 8 bits, mode */
+#define DMA_MODE_WRITE             1
+/* I/O to memory, 16 bits, mode */
+#define DMA_MODE_READ_WORD          2
+/* memory to I/O, 16 bits, mode */
+#define DMA_MODE_WRITE_WORD         3
+/* I/O to memory, 32 bits, mode */
+#define DMA_MODE_READ_LONG          4
+/* memory to I/O, 32 bits, mode */
+#define DMA_MODE_WRITE_LONG         5
+/* I/O to memory, 8 bits, single-address-mode */
+#define DMA_MODE_READ_SINGLE        8
+/* memory to I/O, 8 bits, single-address-mode */
+#define DMA_MODE_WRITE_SINGLE       9
+/* I/O to memory, 16 bits, single-address-mode */
+#define DMA_MODE_READ_WORD_SINGLE  10
+/* memory to I/O, 16 bits, single-address-mode */
+#define DMA_MODE_WRITE_WORD_SINGLE 11
+/* I/O to memory, 32 bits, single-address-mode */
+#define DMA_MODE_READ_LONG_SINGLE  12
+/* memory to I/O, 32 bits, single-address-mode */
+#define DMA_MODE_WRITE_LONG_SINGLE 13
+
+#else /* CONFIG_M5272 is defined */
+
+/* Source static-address mode */
+#define DMA_MODE_SRC_SA_BIT 0x01
+/* Two bits to select between all four modes */
+#define DMA_MODE_SSIZE_MASK 0x06
+/* Offset to shift bits in */
+#define DMA_MODE_SSIZE_OFF  0x01
+/* Destination static-address mode */
+#define DMA_MODE_DES_SA_BIT 0x10
+/* Two bits to select between all four modes */
+#define DMA_MODE_DSIZE_MASK 0x60
+/* Offset to shift bits in */
+#define DMA_MODE_DSIZE_OFF  0x05
+/* Size modifiers */
+#define DMA_MODE_SIZE_LONG  0x00
+#define DMA_MODE_SIZE_BYTE  0x01
+#define DMA_MODE_SIZE_WORD  0x02
+#define DMA_MODE_SIZE_LINE  0x03
+
+/*
+ * Aliases to help speed quick ports; these may be suboptimal, however. They
+ * do not include the SINGLE mode modifiers since the MCF5272 does not have a
+ * mode where the device is in control of its addressing.
+ */
+
+/* I/O to memory, 8 bits, mode */
+#define DMA_MODE_READ                ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT)
+/* memory to I/O, 8 bits, mode */
+#define DMA_MODE_WRITE             ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT)
+/* I/O to memory, 16 bits, mode */
+#define DMA_MODE_READ_WORD             ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT)
+/* memory to I/O, 16 bits, mode */
+#define DMA_MODE_WRITE_WORD         ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT)
+/* I/O to memory, 32 bits, mode */
+#define DMA_MODE_READ_LONG             ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT)
+/* memory to I/O, 32 bits, mode */
+#define DMA_MODE_WRITE_LONG         ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT)
+
+#endif /* !defined(CONFIG_M5272) */
+
+#if !defined(CONFIG_M5272)
+/* enable/disable a specific DMA channel */
+static __inline__ void enable_dma(unsigned int dmanr)
+{
+  volatile unsigned short *dmawp;
+
+#ifdef DMA_DEBUG
+  printk("enable_dma(dmanr=%d)\n", dmanr);
+#endif
+
+  dmawp = (unsigned short *) dma_base_addr[dmanr];
+  dmawp[MCFDMA_DCR] |= MCFDMA_DCR_EEXT;
+}
+
+static __inline__ void disable_dma(unsigned int dmanr)
+{
+  volatile unsigned short *dmawp;
+  volatile unsigned char  *dmapb;
+
+#ifdef DMA_DEBUG
+  printk("disable_dma(dmanr=%d)\n", dmanr);
+#endif
+
+  dmawp = (unsigned short *) dma_base_addr[dmanr];
+  dmapb = (unsigned char *) dma_base_addr[dmanr];
+
+  /* Turn off external requests, and stop any DMA in progress */
+  dmawp[MCFDMA_DCR] &= ~MCFDMA_DCR_EEXT;
+  dmapb[MCFDMA_DSR] = MCFDMA_DSR_DONE;
+}
+
+/*
+ * Clear the 'DMA Pointer Flip Flop'.
+ * Write 0 for LSB/MSB, 1 for MSB/LSB access.
+ * Use this once to initialize the FF to a known state.
+ * After that, keep track of it. :-)
+ * --- In order to do that, the DMA routines below should ---
+ * --- only be used while interrupts are disabled! ---
+ *
+ * This is a NOP for ColdFire. Provide a stub for compatibility.
+ */
+static __inline__ void clear_dma_ff(unsigned int dmanr)
+{
+}
+
+/* set mode (above) for a specific DMA channel */
+static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
+{
+
+  volatile unsigned char  *dmabp;
+  volatile unsigned short *dmawp;
+
+#ifdef DMA_DEBUG
+  printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode);
+#endif
+
+  dmabp = (unsigned char *) dma_base_addr[dmanr];
+  dmawp = (unsigned short *) dma_base_addr[dmanr];
+
+  /* Clear config errors */
+  dmabp[MCFDMA_DSR] = MCFDMA_DSR_DONE;
+
+  /* Set command register */
+  dmawp[MCFDMA_DCR] =
+    MCFDMA_DCR_INT |         /* Enable completion irq */
+    MCFDMA_DCR_CS |          /* Force one xfer per request */
+    MCFDMA_DCR_AA |          /* Enable auto alignment */
+    /* single-address-mode */
+    ((mode & DMA_MODE_SINGLE_BIT) ? MCFDMA_DCR_SAA : 0) |
+    /* sets s_rw (-> r/w) high if Memory to I/0 */
+    ((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_S_RW : 0) |
+    /* Memory to I/O or I/O to Memory */
+    ((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_SINC : MCFDMA_DCR_DINC) |
+    /* 32 bit, 16 bit or 8 bit transfers */
+    ((mode & DMA_MODE_WORD_BIT)  ? MCFDMA_DCR_SSIZE_WORD :
+     ((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_SSIZE_LONG :
+                                   MCFDMA_DCR_SSIZE_BYTE)) |
+    ((mode & DMA_MODE_WORD_BIT)  ? MCFDMA_DCR_DSIZE_WORD :
+     ((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_DSIZE_LONG :
+                                   MCFDMA_DCR_DSIZE_BYTE));
+
+#ifdef DEBUG_DMA
+  printk("%s(%d): dmanr=%d DSR[%x]=%x DCR[%x]=%x\n", __FILE__, __LINE__,
+         dmanr, (int) &dmabp[MCFDMA_DSR], dmabp[MCFDMA_DSR],
+        (int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR]);
+#endif
+}
+
+/* Set transfer address for specific DMA channel */
+static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
+{
+  volatile unsigned short *dmawp;
+  volatile unsigned int   *dmalp;
+
+#ifdef DMA_DEBUG
+  printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a);
+#endif
+
+  dmawp = (unsigned short *) dma_base_addr[dmanr];
+  dmalp = (unsigned int *) dma_base_addr[dmanr];
+
+  /* Determine which address registers are used for memory/device accesses */
+  if (dmawp[MCFDMA_DCR] & MCFDMA_DCR_SINC) {
+    /* Source incrementing, must be memory */
+    dmalp[MCFDMA_SAR] = a;
+    /* Set dest address, must be device */
+    dmalp[MCFDMA_DAR] = dma_device_address[dmanr];
+  } else {
+    /* Destination incrementing, must be memory */
+    dmalp[MCFDMA_DAR] = a;
+    /* Set source address, must be device */
+    dmalp[MCFDMA_SAR] = dma_device_address[dmanr];
+  }
+
+#ifdef DEBUG_DMA
+  printk("%s(%d): dmanr=%d DCR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n",
+       __FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR],
+       (int) &dmalp[MCFDMA_SAR], dmalp[MCFDMA_SAR],
+       (int) &dmalp[MCFDMA_DAR], dmalp[MCFDMA_DAR]);
+#endif
+}
+
+/*
+ * Specific for Coldfire - sets device address.
+ * Should be called after the mode set call, and before set DMA address.
+ */
+static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a)
+{
+#ifdef DMA_DEBUG
+  printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a);
+#endif
+
+  dma_device_address[dmanr] = a;
+}
+
+/*
+ * NOTE 2: "count" represents _bytes_.
+ */
+static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
+{
+  volatile unsigned short *dmawp;
+
+#ifdef DMA_DEBUG
+  printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count);
+#endif
+
+  dmawp = (unsigned short *) dma_base_addr[dmanr];
+  dmawp[MCFDMA_BCR] = (unsigned short)count;
+}
+
+/*
+ * Get DMA residue count. After a DMA transfer, this
+ * should return zero. Reading this while a DMA transfer is
+ * still in progress will return unpredictable results.
+ * Otherwise, it returns the number of _bytes_ left to transfer.
+ */
+static __inline__ int get_dma_residue(unsigned int dmanr)
+{
+  volatile unsigned short *dmawp;
+  unsigned short count;
+
+#ifdef DMA_DEBUG
+  printk("get_dma_residue(dmanr=%d)\n", dmanr);
+#endif
+
+  dmawp = (unsigned short *) dma_base_addr[dmanr];
+  count = dmawp[MCFDMA_BCR];
+  return((int) count);
+}
+#else /* CONFIG_M5272 is defined */
+
+/*
+ * The MCF5272 DMA controller is very different than the controller defined above
+ * in terms of register mapping.  For instance, with the exception of the 16-bit
+ * interrupt register (IRQ#85, for reference), all of the registers are 32-bit.
+ *
+ * The big difference, however, is the lack of device-requested DMA.  All modes
+ * are dual address transfer, and there is no 'device' setup or direction bit.
+ * You can DMA between a device and memory, between memory and memory, or even between
+ * two devices directly, with any combination of incrementing and non-incrementing
+ * addresses you choose.  This puts a crimp in distinguishing between the 'device
+ * address' set up by set_dma_device_addr.
+ *
+ * Therefore, there are two options.  One is to use set_dma_addr and set_dma_device_addr,
+ * which will act exactly as above in -- it will look to see if the source is set to
+ * autoincrement, and if so it will make the source use the set_dma_addr value and the
+ * destination the set_dma_device_addr value.  Otherwise the source will be set to the
+ * set_dma_device_addr value and the destination will get the set_dma_addr value.
+ *
+ * The other is to use the provided set_dma_src_addr and set_dma_dest_addr functions
+ * and make it explicit.  Depending on what you're doing, one of these two should work
+ * for you, but don't mix them in the same transfer setup.
+ */
+
+/* enable/disable a specific DMA channel */
+static __inline__ void enable_dma(unsigned int dmanr)
+{
+  volatile unsigned int  *dmalp;
+
+#ifdef DMA_DEBUG
+  printk("enable_dma(dmanr=%d)\n", dmanr);
+#endif
+
+  dmalp = (unsigned int *) dma_base_addr[dmanr];
+  dmalp[MCFDMA_DMR] |= MCFDMA_DMR_EN;
+}
+
+static __inline__ void disable_dma(unsigned int dmanr)
+{
+  volatile unsigned int   *dmalp;
+
+#ifdef DMA_DEBUG
+  printk("disable_dma(dmanr=%d)\n", dmanr);
+#endif
+
+  dmalp = (unsigned int *) dma_base_addr[dmanr];
+
+  /* Turn off external requests, and stop any DMA in progress */
+  dmalp[MCFDMA_DMR] &= ~MCFDMA_DMR_EN;
+  dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET;
+}
+
+/*
+ * Clear the 'DMA Pointer Flip Flop'.
+ * Write 0 for LSB/MSB, 1 for MSB/LSB access.
+ * Use this once to initialize the FF to a known state.
+ * After that, keep track of it. :-)
+ * --- In order to do that, the DMA routines below should ---
+ * --- only be used while interrupts are disabled! ---
+ *
+ * This is a NOP for ColdFire. Provide a stub for compatibility.
+ */
+static __inline__ void clear_dma_ff(unsigned int dmanr)
+{
+}
+
+/* set mode (above) for a specific DMA channel */
+static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
+{
+
+  volatile unsigned int   *dmalp;
+  volatile unsigned short *dmawp;
+
+#ifdef DMA_DEBUG
+  printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode);
+#endif
+  dmalp = (unsigned int *) dma_base_addr[dmanr];
+  dmawp = (unsigned short *) dma_base_addr[dmanr];
+
+  /* Clear config errors */
+  dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET;
+
+  /* Set command register */
+  dmalp[MCFDMA_DMR] =
+    MCFDMA_DMR_RQM_DUAL |         /* Mandatory Request Mode setting */
+    MCFDMA_DMR_DSTT_SD  |         /* Set up addressing types; set to supervisor-data. */
+    MCFDMA_DMR_SRCT_SD  |         /* Set up addressing types; set to supervisor-data. */
+    /* source static-address-mode */
+    ((mode & DMA_MODE_SRC_SA_BIT) ? MCFDMA_DMR_SRCM_SA : MCFDMA_DMR_SRCM_IA) |
+    /* dest static-address-mode */
+    ((mode & DMA_MODE_DES_SA_BIT) ? MCFDMA_DMR_DSTM_SA : MCFDMA_DMR_DSTM_IA) |
+    /* burst, 32 bit, 16 bit or 8 bit transfers are separately configurable on the MCF5272 */
+    (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_DSTS_OFF) |
+    (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_SRCS_OFF);
+
+  dmawp[MCFDMA_DIR] |= MCFDMA_DIR_ASCEN;   /* Enable completion interrupts */
+
+#ifdef DEBUG_DMA
+  printk("%s(%d): dmanr=%d DMR[%x]=%x DIR[%x]=%x\n", __FILE__, __LINE__,
+         dmanr, (int) &dmalp[MCFDMA_DMR], dmabp[MCFDMA_DMR],
+        (int) &dmawp[MCFDMA_DIR], dmawp[MCFDMA_DIR]);
+#endif
+}
+
+/* Set transfer address for specific DMA channel */
+static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
+{
+  volatile unsigned int   *dmalp;
+
+#ifdef DMA_DEBUG
+  printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a);
+#endif
+
+  dmalp = (unsigned int *) dma_base_addr[dmanr];
+
+  /* Determine which address registers are used for memory/device accesses */
+  if (dmalp[MCFDMA_DMR] & MCFDMA_DMR_SRCM) {
+    /* Source incrementing, must be memory */
+    dmalp[MCFDMA_DSAR] = a;
+    /* Set dest address, must be device */
+    dmalp[MCFDMA_DDAR] = dma_device_address[dmanr];
+  } else {
+    /* Destination incrementing, must be memory */
+    dmalp[MCFDMA_DDAR] = a;
+    /* Set source address, must be device */
+    dmalp[MCFDMA_DSAR] = dma_device_address[dmanr];
+  }
+
+#ifdef DEBUG_DMA
+  printk("%s(%d): dmanr=%d DMR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n",
+       __FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DMR], dmawp[MCFDMA_DMR],
+       (int) &dmalp[MCFDMA_DSAR], dmalp[MCFDMA_DSAR],
+       (int) &dmalp[MCFDMA_DDAR], dmalp[MCFDMA_DDAR]);
+#endif
+}
+
+/*
+ * Specific for Coldfire - sets device address.
+ * Should be called after the mode set call, and before set DMA address.
+ */
+static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a)
+{
+#ifdef DMA_DEBUG
+  printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a);
+#endif
+
+  dma_device_address[dmanr] = a;
+}
+
+/*
+ * NOTE 2: "count" represents _bytes_.
+ *
+ * NOTE 3: While a 32-bit register, "count" is only a maximum 24-bit value.
+ */
+static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
+{
+  volatile unsigned int *dmalp;
+
+#ifdef DMA_DEBUG
+  printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count);
+#endif
+
+  dmalp = (unsigned int *) dma_base_addr[dmanr];
+  dmalp[MCFDMA_DBCR] = count;
+}
+
+/*
+ * Get DMA residue count. After a DMA transfer, this
+ * should return zero. Reading this while a DMA transfer is
+ * still in progress will return unpredictable results.
+ * Otherwise, it returns the number of _bytes_ left to transfer.
+ */
+static __inline__ int get_dma_residue(unsigned int dmanr)
+{
+  volatile unsigned int *dmalp;
+  unsigned int count;
+
+#ifdef DMA_DEBUG
+  printk("get_dma_residue(dmanr=%d)\n", dmanr);
+#endif
+
+  dmalp = (unsigned int *) dma_base_addr[dmanr];
+  count = dmalp[MCFDMA_DBCR];
+  return(count);
+}
+
+#endif /* !defined(CONFIG_M5272) */
+#endif /* CONFIG_COLDFIRE */
+
+/* it's useless on the m68k, but unfortunately needed by the new
+   bootmem allocator (but this should do it for this) */
+#define MAX_DMA_ADDRESS PAGE_OFFSET
+
+#define MAX_DMA_CHANNELS 8
+
+extern int request_dma(unsigned int dmanr, const char * device_id);    /* reserve a DMA channel */
+extern void free_dma(unsigned int dmanr);      /* release it again */
+
+#define isa_dma_bridge_buggy    (0)
+
+#endif /* _M68K_DMA_H */
diff --git a/arch/m68k/include/asm/dma_mm.h b/arch/m68k/include/asm/dma_mm.h
deleted file mode 100644 (file)
index 4240fbc..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef _M68K_DMA_H
-#define _M68K_DMA_H 1
-
-
-/* it's useless on the m68k, but unfortunately needed by the new
-   bootmem allocator (but this should do it for this) */
-#define MAX_DMA_ADDRESS PAGE_OFFSET
-
-#define MAX_DMA_CHANNELS 8
-
-extern int request_dma(unsigned int dmanr, const char * device_id);    /* reserve a DMA channel */
-extern void free_dma(unsigned int dmanr);      /* release it again */
-
-#define isa_dma_bridge_buggy    (0)
-
-#endif /* _M68K_DMA_H */
diff --git a/arch/m68k/include/asm/dma_no.h b/arch/m68k/include/asm/dma_no.h
deleted file mode 100644 (file)
index 939a020..0000000
+++ /dev/null
@@ -1,494 +0,0 @@
-#ifndef _M68K_DMA_H
-#define _M68K_DMA_H 1
-//#define      DMA_DEBUG       1
-
-
-#ifdef CONFIG_COLDFIRE
-/*
- * ColdFire DMA Model:
- *   ColdFire DMA supports two forms of DMA: Single and Dual address. Single
- * address mode emits a source address, and expects that the device will either
- * pick up the data (DMA READ) or source data (DMA WRITE). This implies that
- * the device will place data on the correct byte(s) of the data bus, as the
- * memory transactions are always 32 bits. This implies that only 32 bit
- * devices will find single mode transfers useful. Dual address DMA mode
- * performs two cycles: source read and destination write. ColdFire will
- * align the data so that the device will always get the correct bytes, thus
- * is useful for 8 and 16 bit devices. This is the mode that is supported
- * below.
- *
- * AUG/22/2000 : added support for 32-bit Dual-Address-Mode (K) 2000 
- *               Oliver Kamphenkel (O.Kamphenkel@tu-bs.de)
- *
- * AUG/25/2000 : addad support for 8, 16 and 32-bit Single-Address-Mode (K)2000
- *               Oliver Kamphenkel (O.Kamphenkel@tu-bs.de)
- *
- * APR/18/2002 : added proper support for MCF5272 DMA controller.
- *               Arthur Shipkowski (art@videon-central.com)
- */
-
-#include <asm/coldfire.h>
-#include <asm/mcfsim.h>
-#include <asm/mcfdma.h>
-
-/*
- * Set number of channels of DMA on ColdFire for different implementations.
- */
-#if defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) || \
-       defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
-#define MAX_M68K_DMA_CHANNELS 4
-#elif defined(CONFIG_M5272)
-#define MAX_M68K_DMA_CHANNELS 1
-#elif defined(CONFIG_M532x)
-#define MAX_M68K_DMA_CHANNELS 0
-#else
-#define MAX_M68K_DMA_CHANNELS 2
-#endif
-
-extern unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS];
-extern unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
-
-#if !defined(CONFIG_M5272)
-#define DMA_MODE_WRITE_BIT  0x01  /* Memory/IO to IO/Memory select */
-#define DMA_MODE_WORD_BIT   0x02  /* 8 or 16 bit transfers */
-#define DMA_MODE_LONG_BIT   0x04  /* or 32 bit transfers */
-#define DMA_MODE_SINGLE_BIT 0x08  /* single-address-mode */
-
-/* I/O to memory, 8 bits, mode */
-#define DMA_MODE_READ              0
-/* memory to I/O, 8 bits, mode */
-#define DMA_MODE_WRITE             1
-/* I/O to memory, 16 bits, mode */
-#define DMA_MODE_READ_WORD          2
-/* memory to I/O, 16 bits, mode */
-#define DMA_MODE_WRITE_WORD         3
-/* I/O to memory, 32 bits, mode */
-#define DMA_MODE_READ_LONG          4
-/* memory to I/O, 32 bits, mode */
-#define DMA_MODE_WRITE_LONG         5
-/* I/O to memory, 8 bits, single-address-mode */     
-#define DMA_MODE_READ_SINGLE        8
-/* memory to I/O, 8 bits, single-address-mode */
-#define DMA_MODE_WRITE_SINGLE       9
-/* I/O to memory, 16 bits, single-address-mode */
-#define DMA_MODE_READ_WORD_SINGLE  10
-/* memory to I/O, 16 bits, single-address-mode */
-#define DMA_MODE_WRITE_WORD_SINGLE 11
-/* I/O to memory, 32 bits, single-address-mode */
-#define DMA_MODE_READ_LONG_SINGLE  12
-/* memory to I/O, 32 bits, single-address-mode */
-#define DMA_MODE_WRITE_LONG_SINGLE 13
-
-#else /* CONFIG_M5272 is defined */
-
-/* Source static-address mode */
-#define DMA_MODE_SRC_SA_BIT 0x01  
-/* Two bits to select between all four modes */
-#define DMA_MODE_SSIZE_MASK 0x06 
-/* Offset to shift bits in */
-#define DMA_MODE_SSIZE_OFF  0x01  
-/* Destination static-address mode */
-#define DMA_MODE_DES_SA_BIT 0x10  
-/* Two bits to select between all four modes */
-#define DMA_MODE_DSIZE_MASK 0x60  
-/* Offset to shift bits in */
-#define DMA_MODE_DSIZE_OFF  0x05
-/* Size modifiers */
-#define DMA_MODE_SIZE_LONG  0x00
-#define DMA_MODE_SIZE_BYTE  0x01
-#define DMA_MODE_SIZE_WORD  0x02
-#define DMA_MODE_SIZE_LINE  0x03
-
-/* 
- * Aliases to help speed quick ports; these may be suboptimal, however. They
- * do not include the SINGLE mode modifiers since the MCF5272 does not have a
- * mode where the device is in control of its addressing.
- */
-
-/* I/O to memory, 8 bits, mode */
-#define DMA_MODE_READ                ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT)
-/* memory to I/O, 8 bits, mode */
-#define DMA_MODE_WRITE             ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT)
-/* I/O to memory, 16 bits, mode */
-#define DMA_MODE_READ_WORD             ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT)
-/* memory to I/O, 16 bits, mode */
-#define DMA_MODE_WRITE_WORD         ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT)
-/* I/O to memory, 32 bits, mode */
-#define DMA_MODE_READ_LONG             ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT)
-/* memory to I/O, 32 bits, mode */
-#define DMA_MODE_WRITE_LONG         ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT)
-
-#endif /* !defined(CONFIG_M5272) */
-
-#if !defined(CONFIG_M5272)
-/* enable/disable a specific DMA channel */
-static __inline__ void enable_dma(unsigned int dmanr)
-{
-  volatile unsigned short *dmawp;
-
-#ifdef DMA_DEBUG
-  printk("enable_dma(dmanr=%d)\n", dmanr);
-#endif
-
-  dmawp = (unsigned short *) dma_base_addr[dmanr];
-  dmawp[MCFDMA_DCR] |= MCFDMA_DCR_EEXT;
-}
-
-static __inline__ void disable_dma(unsigned int dmanr)
-{
-  volatile unsigned short *dmawp;
-  volatile unsigned char  *dmapb;
-
-#ifdef DMA_DEBUG
-  printk("disable_dma(dmanr=%d)\n", dmanr);
-#endif
-
-  dmawp = (unsigned short *) dma_base_addr[dmanr];
-  dmapb = (unsigned char *) dma_base_addr[dmanr];
-
-  /* Turn off external requests, and stop any DMA in progress */
-  dmawp[MCFDMA_DCR] &= ~MCFDMA_DCR_EEXT;
-  dmapb[MCFDMA_DSR] = MCFDMA_DSR_DONE;
-}
-
-/*
- * Clear the 'DMA Pointer Flip Flop'.
- * Write 0 for LSB/MSB, 1 for MSB/LSB access.
- * Use this once to initialize the FF to a known state.
- * After that, keep track of it. :-)
- * --- In order to do that, the DMA routines below should ---
- * --- only be used while interrupts are disabled! ---
- *
- * This is a NOP for ColdFire. Provide a stub for compatibility.
- */
-static __inline__ void clear_dma_ff(unsigned int dmanr)
-{
-}
-
-/* set mode (above) for a specific DMA channel */
-static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
-{
-
-  volatile unsigned char  *dmabp;
-  volatile unsigned short *dmawp;
-
-#ifdef DMA_DEBUG
-  printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode);
-#endif
-
-  dmabp = (unsigned char *) dma_base_addr[dmanr];
-  dmawp = (unsigned short *) dma_base_addr[dmanr];
-
-  // Clear config errors
-  dmabp[MCFDMA_DSR] = MCFDMA_DSR_DONE; 
-
-  // Set command register
-  dmawp[MCFDMA_DCR] =
-    MCFDMA_DCR_INT |         // Enable completion irq
-    MCFDMA_DCR_CS |          // Force one xfer per request
-    MCFDMA_DCR_AA |          // Enable auto alignment
-    // single-address-mode
-    ((mode & DMA_MODE_SINGLE_BIT) ? MCFDMA_DCR_SAA : 0) |
-    // sets s_rw (-> r/w) high if Memory to I/0
-    ((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_S_RW : 0) |
-    // Memory to I/O or I/O to Memory
-    ((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_SINC : MCFDMA_DCR_DINC) |
-    // 32 bit, 16 bit or 8 bit transfers
-    ((mode & DMA_MODE_WORD_BIT)  ? MCFDMA_DCR_SSIZE_WORD : 
-     ((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_SSIZE_LONG :
-                                   MCFDMA_DCR_SSIZE_BYTE)) |
-    ((mode & DMA_MODE_WORD_BIT)  ? MCFDMA_DCR_DSIZE_WORD :
-     ((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_DSIZE_LONG :
-                                   MCFDMA_DCR_DSIZE_BYTE));
-
-#ifdef DEBUG_DMA
-  printk("%s(%d): dmanr=%d DSR[%x]=%x DCR[%x]=%x\n", __FILE__, __LINE__,
-         dmanr, (int) &dmabp[MCFDMA_DSR], dmabp[MCFDMA_DSR],
-        (int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR]);
-#endif
-}
-
-/* Set transfer address for specific DMA channel */
-static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
-{
-  volatile unsigned short *dmawp;
-  volatile unsigned int   *dmalp;
-
-#ifdef DMA_DEBUG
-  printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a);
-#endif
-
-  dmawp = (unsigned short *) dma_base_addr[dmanr];
-  dmalp = (unsigned int *) dma_base_addr[dmanr];
-
-  // Determine which address registers are used for memory/device accesses
-  if (dmawp[MCFDMA_DCR] & MCFDMA_DCR_SINC) {
-    // Source incrementing, must be memory
-    dmalp[MCFDMA_SAR] = a;
-    // Set dest address, must be device
-    dmalp[MCFDMA_DAR] = dma_device_address[dmanr];
-  } else {
-    // Destination incrementing, must be memory
-    dmalp[MCFDMA_DAR] = a;
-    // Set source address, must be device
-    dmalp[MCFDMA_SAR] = dma_device_address[dmanr];
-  }
-
-#ifdef DEBUG_DMA
-  printk("%s(%d): dmanr=%d DCR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n",
-       __FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR],
-       (int) &dmalp[MCFDMA_SAR], dmalp[MCFDMA_SAR],
-       (int) &dmalp[MCFDMA_DAR], dmalp[MCFDMA_DAR]);
-#endif
-}
-
-/*
- * Specific for Coldfire - sets device address.
- * Should be called after the mode set call, and before set DMA address.
- */
-static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a)
-{
-#ifdef DMA_DEBUG
-  printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a);
-#endif
-
-  dma_device_address[dmanr] = a;
-}
-
-/*
- * NOTE 2: "count" represents _bytes_.
- */
-static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
-{
-  volatile unsigned short *dmawp;
-
-#ifdef DMA_DEBUG
-  printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count);
-#endif
-
-  dmawp = (unsigned short *) dma_base_addr[dmanr];
-  dmawp[MCFDMA_BCR] = (unsigned short)count;
-}
-
-/*
- * Get DMA residue count. After a DMA transfer, this
- * should return zero. Reading this while a DMA transfer is
- * still in progress will return unpredictable results.
- * Otherwise, it returns the number of _bytes_ left to transfer.
- */
-static __inline__ int get_dma_residue(unsigned int dmanr)
-{
-  volatile unsigned short *dmawp;
-  unsigned short count;
-
-#ifdef DMA_DEBUG
-  printk("get_dma_residue(dmanr=%d)\n", dmanr);
-#endif
-
-  dmawp = (unsigned short *) dma_base_addr[dmanr];
-  count = dmawp[MCFDMA_BCR];
-  return((int) count);
-}
-#else /* CONFIG_M5272 is defined */
-
-/*
- * The MCF5272 DMA controller is very different than the controller defined above
- * in terms of register mapping.  For instance, with the exception of the 16-bit 
- * interrupt register (IRQ#85, for reference), all of the registers are 32-bit.
- *
- * The big difference, however, is the lack of device-requested DMA.  All modes
- * are dual address transfer, and there is no 'device' setup or direction bit.
- * You can DMA between a device and memory, between memory and memory, or even between
- * two devices directly, with any combination of incrementing and non-incrementing
- * addresses you choose.  This puts a crimp in distinguishing between the 'device 
- * address' set up by set_dma_device_addr.
- *
- * Therefore, there are two options.  One is to use set_dma_addr and set_dma_device_addr,
- * which will act exactly as above in -- it will look to see if the source is set to
- * autoincrement, and if so it will make the source use the set_dma_addr value and the
- * destination the set_dma_device_addr value.  Otherwise the source will be set to the
- * set_dma_device_addr value and the destination will get the set_dma_addr value.
- *
- * The other is to use the provided set_dma_src_addr and set_dma_dest_addr functions
- * and make it explicit.  Depending on what you're doing, one of these two should work
- * for you, but don't mix them in the same transfer setup.
- */
-
-/* enable/disable a specific DMA channel */
-static __inline__ void enable_dma(unsigned int dmanr)
-{
-  volatile unsigned int  *dmalp;
-
-#ifdef DMA_DEBUG
-  printk("enable_dma(dmanr=%d)\n", dmanr);
-#endif
-
-  dmalp = (unsigned int *) dma_base_addr[dmanr];
-  dmalp[MCFDMA_DMR] |= MCFDMA_DMR_EN;
-}
-
-static __inline__ void disable_dma(unsigned int dmanr)
-{
-  volatile unsigned int   *dmalp;
-
-#ifdef DMA_DEBUG
-  printk("disable_dma(dmanr=%d)\n", dmanr);
-#endif
-
-  dmalp = (unsigned int *) dma_base_addr[dmanr];
-
-  /* Turn off external requests, and stop any DMA in progress */
-  dmalp[MCFDMA_DMR] &= ~MCFDMA_DMR_EN;
-  dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET;
-}
-
-/*
- * Clear the 'DMA Pointer Flip Flop'.
- * Write 0 for LSB/MSB, 1 for MSB/LSB access.
- * Use this once to initialize the FF to a known state.
- * After that, keep track of it. :-)
- * --- In order to do that, the DMA routines below should ---
- * --- only be used while interrupts are disabled! ---
- *
- * This is a NOP for ColdFire. Provide a stub for compatibility.
- */
-static __inline__ void clear_dma_ff(unsigned int dmanr)
-{
-}
-
-/* set mode (above) for a specific DMA channel */
-static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
-{
-
-  volatile unsigned int   *dmalp;
-  volatile unsigned short *dmawp;
-
-#ifdef DMA_DEBUG
-  printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode);
-#endif
-  dmalp = (unsigned int *) dma_base_addr[dmanr];
-  dmawp = (unsigned short *) dma_base_addr[dmanr];
-
-  // Clear config errors
-  dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET; 
-
-  // Set command register
-  dmalp[MCFDMA_DMR] =
-    MCFDMA_DMR_RQM_DUAL |         // Mandatory Request Mode setting
-    MCFDMA_DMR_DSTT_SD  |         // Set up addressing types; set to supervisor-data.
-    MCFDMA_DMR_SRCT_SD  |         // Set up addressing types; set to supervisor-data. 
-    // source static-address-mode
-    ((mode & DMA_MODE_SRC_SA_BIT) ? MCFDMA_DMR_SRCM_SA : MCFDMA_DMR_SRCM_IA) |
-    // dest static-address-mode
-    ((mode & DMA_MODE_DES_SA_BIT) ? MCFDMA_DMR_DSTM_SA : MCFDMA_DMR_DSTM_IA) |
-    // burst, 32 bit, 16 bit or 8 bit transfers are separately configurable on the MCF5272
-    (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_DSTS_OFF) |
-    (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_SRCS_OFF);
-    
-  dmawp[MCFDMA_DIR] |= MCFDMA_DIR_ASCEN;   /* Enable completion interrupts */
-  
-#ifdef DEBUG_DMA
-  printk("%s(%d): dmanr=%d DMR[%x]=%x DIR[%x]=%x\n", __FILE__, __LINE__,
-         dmanr, (int) &dmalp[MCFDMA_DMR], dmabp[MCFDMA_DMR],
-        (int) &dmawp[MCFDMA_DIR], dmawp[MCFDMA_DIR]);
-#endif
-}
-
-/* Set transfer address for specific DMA channel */
-static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
-{
-  volatile unsigned int   *dmalp;
-
-#ifdef DMA_DEBUG
-  printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a);
-#endif
-
-  dmalp = (unsigned int *) dma_base_addr[dmanr];
-
-  // Determine which address registers are used for memory/device accesses
-  if (dmalp[MCFDMA_DMR] & MCFDMA_DMR_SRCM) {
-    // Source incrementing, must be memory
-    dmalp[MCFDMA_DSAR] = a;
-    // Set dest address, must be device
-    dmalp[MCFDMA_DDAR] = dma_device_address[dmanr];
-  } else {
-    // Destination incrementing, must be memory
-    dmalp[MCFDMA_DDAR] = a;
-    // Set source address, must be device
-    dmalp[MCFDMA_DSAR] = dma_device_address[dmanr];
-  }
-
-#ifdef DEBUG_DMA
-  printk("%s(%d): dmanr=%d DMR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n",
-       __FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DMR], dmawp[MCFDMA_DMR],
-       (int) &dmalp[MCFDMA_DSAR], dmalp[MCFDMA_DSAR],
-       (int) &dmalp[MCFDMA_DDAR], dmalp[MCFDMA_DDAR]);
-#endif
-}
-
-/*
- * Specific for Coldfire - sets device address.
- * Should be called after the mode set call, and before set DMA address.
- */
-static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a)
-{
-#ifdef DMA_DEBUG
-  printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a);
-#endif
-
-  dma_device_address[dmanr] = a;
-}
-
-/*
- * NOTE 2: "count" represents _bytes_.
- *
- * NOTE 3: While a 32-bit register, "count" is only a maximum 24-bit value.
- */
-static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
-{
-  volatile unsigned int *dmalp;
-  
-#ifdef DMA_DEBUG
-  printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count);
-#endif
-
-  dmalp = (unsigned int *) dma_base_addr[dmanr];
-  dmalp[MCFDMA_DBCR] = count;
-}
-
-/*
- * Get DMA residue count. After a DMA transfer, this
- * should return zero. Reading this while a DMA transfer is
- * still in progress will return unpredictable results.
- * Otherwise, it returns the number of _bytes_ left to transfer.
- */
-static __inline__ int get_dma_residue(unsigned int dmanr)
-{
-  volatile unsigned int *dmalp;
-  unsigned int count;
-
-#ifdef DMA_DEBUG
-  printk("get_dma_residue(dmanr=%d)\n", dmanr);
-#endif
-
-  dmalp = (unsigned int *) dma_base_addr[dmanr];
-  count = dmalp[MCFDMA_DBCR];
-  return(count);
-}
-
-#endif /* !defined(CONFIG_M5272) */
-#endif /* CONFIG_COLDFIRE */
-#define MAX_DMA_CHANNELS 8
-
-/* Don't define MAX_DMA_ADDRESS; it's useless on the m68k/coldfire and any
-   occurrence should be flagged as an error.  */
-/* under 2.4 it is actually needed by the new bootmem allocator */
-#define MAX_DMA_ADDRESS PAGE_OFFSET
-
-/* These are in kernel/dma.c: */
-extern int request_dma(unsigned int dmanr, const char *device_id);     /* reserve a DMA channel */
-extern void free_dma(unsigned int dmanr);      /* release it again */
-#endif /* _M68K_DMA_H */
diff --git a/arch/m68k/include/asm/elia.h b/arch/m68k/include/asm/elia.h
deleted file mode 100644 (file)
index e037d4e..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/****************************************************************************/
-
-/*
- *     elia.h -- Lineo (formerly Moreton Bay) eLIA platform support.
- *
- *     (C) Copyright 1999-2000, Moreton Bay (www.moreton.com.au)
- *     (C) Copyright 1999-2000, Lineo (www.lineo.com)
- */
-
-/****************************************************************************/
-#ifndef        elia_h
-#define        elia_h
-/****************************************************************************/
-
-#include <asm/coldfire.h>
-
-#ifdef CONFIG_eLIA
-
-/*
- *     The serial port DTR and DCD lines are also on the Parallel I/O
- *     as well, so define those too.
- */
-
-#define        eLIA_DCD1               0x0001
-#define        eLIA_DCD0               0x0002
-#define        eLIA_DTR1               0x0004
-#define        eLIA_DTR0               0x0008
-
-#define        eLIA_PCIRESET           0x0020
-
-/*
- *     Kernel macros to set and unset the LEDs.
- */
-#ifndef __ASSEMBLY__
-extern unsigned short  ppdata;
-#endif /* __ASSEMBLY__ */
-
-#endif /* CONFIG_eLIA */
-
-/****************************************************************************/
-#endif /* elia_h */
diff --git a/arch/m68k/include/asm/gpio.h b/arch/m68k/include/asm/gpio.h
new file mode 100644 (file)
index 0000000..283214d
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * Coldfire generic GPIO support
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+*/
+
+#ifndef coldfire_gpio_h
+#define coldfire_gpio_h
+
+#include <linux/io.h>
+#include <asm-generic/gpio.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+
+/*
+ * The Freescale Coldfire family is quite varied in how they implement GPIO.
+ * Some parts have 8 bit ports, some have 16bit and some have 32bit; some have
+ * only one port, others have multiple ports; some have a single data latch
+ * for both input and output, others have a separate pin data register to read
+ * input; some require a read-modify-write access to change an output, others
+ * have set and clear registers for some of the outputs; Some have all the
+ * GPIOs in a single control area, others have some GPIOs implemented in
+ * different modules.
+ *
+ * This implementation attempts accomodate the differences while presenting
+ * a generic interface that will optimize to as few instructions as possible.
+ */
+#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \
+    defined(CONFIG_M520x) || defined(CONFIG_M523x) || \
+    defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x)
+
+/* These parts have GPIO organized by 8 bit ports */
+
+#define MCFGPIO_PORTTYPE               u8
+#define MCFGPIO_PORTSIZE               8
+#define mcfgpio_read(port)             __raw_readb(port)
+#define mcfgpio_write(data, port)      __raw_writeb(data, port)
+
+#elif defined(CONFIG_M5307) || defined(CONFIG_M5407) || defined(CONFIG_M5272)
+
+/* These parts have GPIO organized by 16 bit ports */
+
+#define MCFGPIO_PORTTYPE               u16
+#define MCFGPIO_PORTSIZE               16
+#define mcfgpio_read(port)             __raw_readw(port)
+#define mcfgpio_write(data, port)      __raw_writew(data, port)
+
+#elif defined(CONFIG_M5249)
+
+/* These parts have GPIO organized by 32 bit ports */
+
+#define MCFGPIO_PORTTYPE               u32
+#define MCFGPIO_PORTSIZE               32
+#define mcfgpio_read(port)             __raw_readl(port)
+#define mcfgpio_write(data, port)      __raw_writel(data, port)
+
+#endif
+
+#define mcfgpio_bit(gpio)              (1 << ((gpio) %  MCFGPIO_PORTSIZE))
+#define mcfgpio_port(gpio)             ((gpio) / MCFGPIO_PORTSIZE)
+
+#if defined(CONFIG_M520x) || defined(CONFIG_M523x) || \
+    defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x)
+/*
+ * These parts have an 'Edge' Port module (external interrupt/GPIO) which uses
+ * read-modify-write to change an output and a GPIO module which has separate
+ * set/clr registers to directly change outputs with a single write access.
+ */
+#if defined(CONFIG_M528x)
+/*
+ * The 528x also has GPIOs in other modules (GPT, QADC) which use
+ * read-modify-write as well as those controlled by the EPORT and GPIO modules.
+ */
+#define MCFGPIO_SCR_START              40
+#else
+#define MCFGPIO_SCR_START              8
+#endif
+
+#define MCFGPIO_SETR_PORT(gpio)                (MCFGPIO_SETR + \
+                                       mcfgpio_port(gpio - MCFGPIO_SCR_START))
+
+#define MCFGPIO_CLRR_PORT(gpio)                (MCFGPIO_CLRR + \
+                                       mcfgpio_port(gpio - MCFGPIO_SCR_START))
+#else
+
+#define MCFGPIO_SCR_START              MCFGPIO_PIN_MAX
+/* with MCFGPIO_SCR == MCFGPIO_PIN_MAX, these will be optimized away */
+#define MCFGPIO_SETR_PORT(gpio)                0
+#define MCFGPIO_CLRR_PORT(gpio)                0
+
+#endif
+/*
+ * Coldfire specific helper functions
+ */
+
+/* return the port pin data register for a gpio */
+static inline u32 __mcf_gpio_ppdr(unsigned gpio)
+{
+#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \
+    defined(CONFIG_M5307) || defined(CONFIG_M5407)
+       return MCFSIM_PADAT;
+#elif defined(CONFIG_M5272)
+       if (gpio < 16)
+               return MCFSIM_PADAT;
+       else if (gpio < 32)
+               return MCFSIM_PBDAT;
+       else
+               return MCFSIM_PCDAT;
+#elif defined(CONFIG_M5249)
+       if (gpio < 32)
+               return MCFSIM2_GPIOREAD;
+       else
+               return MCFSIM2_GPIO1READ;
+#elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \
+      defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x)
+       if (gpio < 8)
+               return MCFEPORT_EPPDR;
+#if defined(CONFIG_M528x)
+       else if (gpio < 16)
+               return MCFGPTA_GPTPORT;
+       else if (gpio < 24)
+               return MCFGPTB_GPTPORT;
+       else if (gpio < 32)
+               return MCFQADC_PORTQA;
+       else if (gpio < 40)
+               return MCFQADC_PORTQB;
+#endif
+       else
+               return MCFGPIO_PPDR + mcfgpio_port(gpio - MCFGPIO_SCR_START);
+#endif
+}
+
+/* return the port output data register for a gpio */
+static inline u32 __mcf_gpio_podr(unsigned gpio)
+{
+#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \
+    defined(CONFIG_M5307) || defined(CONFIG_M5407)
+       return MCFSIM_PADAT;
+#elif defined(CONFIG_M5272)
+       if (gpio < 16)
+               return MCFSIM_PADAT;
+       else if (gpio < 32)
+               return MCFSIM_PBDAT;
+       else
+               return MCFSIM_PCDAT;
+#elif defined(CONFIG_M5249)
+       if (gpio < 32)
+               return MCFSIM2_GPIOWRITE;
+       else
+               return MCFSIM2_GPIO1WRITE;
+#elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \
+      defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x)
+       if (gpio < 8)
+               return MCFEPORT_EPDR;
+#if defined(CONFIG_M528x)
+       else if (gpio < 16)
+               return MCFGPTA_GPTPORT;
+       else if (gpio < 24)
+               return MCFGPTB_GPTPORT;
+       else if (gpio < 32)
+               return MCFQADC_PORTQA;
+       else if (gpio < 40)
+               return MCFQADC_PORTQB;
+#endif
+       else
+               return MCFGPIO_PODR + mcfgpio_port(gpio - MCFGPIO_SCR_START);
+#endif
+}
+
+/*
+ * The Generic GPIO functions
+ *
+ * If the gpio is a compile time constant and is one of the Coldfire gpios,
+ * use the inline version, otherwise dispatch thru gpiolib.
+ */
+
+static inline int gpio_get_value(unsigned gpio)
+{
+       if (__builtin_constant_p(gpio) && gpio < MCFGPIO_PIN_MAX)
+               return mcfgpio_read(__mcf_gpio_ppdr(gpio)) & mcfgpio_bit(gpio);
+       else
+               return __gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+       if (__builtin_constant_p(gpio) && gpio < MCFGPIO_PIN_MAX) {
+               if (gpio < MCFGPIO_SCR_START) {
+                       unsigned long flags;
+                       MCFGPIO_PORTTYPE data;
+
+                       local_irq_save(flags);
+                       data = mcfgpio_read(__mcf_gpio_podr(gpio));
+                       if (value)
+                               data |= mcfgpio_bit(gpio);
+                       else
+                               data &= ~mcfgpio_bit(gpio);
+                       mcfgpio_write(data, __mcf_gpio_podr(gpio));
+                       local_irq_restore(flags);
+               } else {
+                       if (value)
+                               mcfgpio_write(mcfgpio_bit(gpio),
+                                               MCFGPIO_SETR_PORT(gpio));
+                       else
+                               mcfgpio_write(~mcfgpio_bit(gpio),
+                                               MCFGPIO_CLRR_PORT(gpio));
+               }
+       } else
+               __gpio_set_value(gpio, value);
+}
+
+static inline int gpio_to_irq(unsigned gpio)
+{
+       return (gpio < MCFGPIO_IRQ_MAX) ? gpio + MCFGPIO_IRQ_VECBASE : -EINVAL;
+}
+
+static inline int irq_to_gpio(unsigned irq)
+{
+       return (irq >= MCFGPIO_IRQ_VECBASE &&
+               irq < (MCFGPIO_IRQ_VECBASE + MCFGPIO_IRQ_MAX)) ?
+               irq - MCFGPIO_IRQ_VECBASE : -ENXIO;
+}
+
+static inline int gpio_cansleep(unsigned gpio)
+{
+       return gpio < MCFGPIO_PIN_MAX ? 0 : __gpio_cansleep(gpio);
+}
+
+#endif
index bfad28149a49dd4ee46d55f42b43a6a4dc64125c..b44b14be87d9daeab92cd65c41289fff7c92efbe 100644 (file)
@@ -1,16 +1,8 @@
 #ifndef __M68K_HARDIRQ_H
 #define __M68K_HARDIRQ_H
 
-#include <linux/cache.h>
-#include <linux/threads.h>
 #include <asm/irq.h>
 
-typedef struct {
-       unsigned int __softirq_pending;
-} ____cacheline_aligned irq_cpustat_t;
-
-#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
-
 #define HARDIRQ_BITS   8
 
 /*
@@ -22,6 +14,6 @@ typedef struct {
 # error HARDIRQ_BITS is too low!
 #endif
 
-void ack_bad_irq(unsigned int irq);
+#include <asm-generic/hardirq.h>
 
 #endif /* __M68K_HARDIRQ_H */
index 6adef1ee2082c72c4a740d19b091c2c5f19faeb1..7f57436ec18f4fd05d992a2695960fd65ce035d6 100644 (file)
@@ -134,7 +134,7 @@ static inline void io_insl(unsigned int addr, void *buf, int len)
 #define insw(a,b,l) io_insw(a,b,l)
 #define insl(a,b,l) io_insl(a,b,l)
 
-#define IO_SPACE_LIMIT 0xffff
+#define IO_SPACE_LIMIT 0xffffffff
 
 
 /* Values for nocacheflag and cmode */
index d031416595b2f21d1869158395b336dbf28c6255..907eff1edd2f58e848c5a983c2f8d4d085074da9 100644 (file)
@@ -1,5 +1,134 @@
-#ifdef __uClinux__
-#include "irq_no.h"
+#ifndef _M68K_IRQ_H_
+#define _M68K_IRQ_H_
+
+/*
+ * This should be the same as the max(NUM_X_SOURCES) for all the
+ * different m68k hosts compiled into the kernel.
+ * Currently the Atari has 72 and the Amiga 24, but if both are
+ * supported in the kernel it is better to make room for 72.
+ */
+#if defined(CONFIG_COLDFIRE)
+#define NR_IRQS 256
+#elif defined(CONFIG_VME) || defined(CONFIG_SUN3) || defined(CONFIG_SUN3X)
+#define NR_IRQS 200
+#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC)
+#define NR_IRQS 72
+#elif defined(CONFIG_Q40)
+#define NR_IRQS        43
+#elif defined(CONFIG_AMIGA) || !defined(CONFIG_MMU)
+#define NR_IRQS        32
+#elif defined(CONFIG_APOLLO)
+#define NR_IRQS        24
+#elif defined(CONFIG_HP300)
+#define NR_IRQS        8
 #else
-#include "irq_mm.h"
+#define NR_IRQS        0
 #endif
+
+#ifdef CONFIG_MMU
+
+#include <linux/linkage.h>
+#include <linux/hardirq.h>
+#include <linux/irqreturn.h>
+#include <linux/spinlock_types.h>
+
+/*
+ * The hardirq mask has to be large enough to have
+ * space for potentially all IRQ sources in the system
+ * nesting on a single CPU:
+ */
+#if (1 << HARDIRQ_BITS) < NR_IRQS
+# error HARDIRQ_BITS is too low!
+#endif
+
+/*
+ * Interrupt source definitions
+ * General interrupt sources are the level 1-7.
+ * Adding an interrupt service routine for one of these sources
+ * results in the addition of that routine to a chain of routines.
+ * Each one is called in succession.  Each individual interrupt
+ * service routine should determine if the device associated with
+ * that routine requires service.
+ */
+
+#define IRQ_SPURIOUS   0
+
+#define IRQ_AUTO_1     1       /* level 1 interrupt */
+#define IRQ_AUTO_2     2       /* level 2 interrupt */
+#define IRQ_AUTO_3     3       /* level 3 interrupt */
+#define IRQ_AUTO_4     4       /* level 4 interrupt */
+#define IRQ_AUTO_5     5       /* level 5 interrupt */
+#define IRQ_AUTO_6     6       /* level 6 interrupt */
+#define IRQ_AUTO_7     7       /* level 7 interrupt (non-maskable) */
+
+#define IRQ_USER       8
+
+extern unsigned int irq_canonicalize(unsigned int irq);
+
+struct pt_regs;
+
+/*
+ * various flags for request_irq() - the Amiga now uses the standard
+ * mechanism like all other architectures - IRQF_DISABLED and
+ * IRQF_SHARED are your friends.
+ */
+#ifndef MACH_AMIGA_ONLY
+#define IRQ_FLG_LOCK   (0x0001)        /* handler is not replaceable   */
+#define IRQ_FLG_REPLACE        (0x0002)        /* replace existing handler     */
+#define IRQ_FLG_FAST   (0x0004)
+#define IRQ_FLG_SLOW   (0x0008)
+#define IRQ_FLG_STD    (0x8000)        /* internally used              */
+#endif
+
+/*
+ * This structure is used to chain together the ISRs for a particular
+ * interrupt source (if it supports chaining).
+ */
+typedef struct irq_node {
+       irqreturn_t     (*handler)(int, void *);
+       void            *dev_id;
+       struct irq_node *next;
+       unsigned long   flags;
+       const char      *devname;
+} irq_node_t;
+
+/*
+ * This structure has only 4 elements for speed reasons
+ */
+struct irq_handler {
+       int             (*handler)(int, void *);
+       unsigned long   flags;
+       void            *dev_id;
+       const char      *devname;
+};
+
+struct irq_controller {
+       const char *name;
+       spinlock_t lock;
+       int (*startup)(unsigned int irq);
+       void (*shutdown)(unsigned int irq);
+       void (*enable)(unsigned int irq);
+       void (*disable)(unsigned int irq);
+};
+
+extern int m68k_irq_startup(unsigned int);
+extern void m68k_irq_shutdown(unsigned int);
+
+/*
+ * This function returns a new irq_node_t
+ */
+extern irq_node_t *new_irq_node(void);
+
+extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *));
+extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt,
+                                     void (*handler)(unsigned int, struct pt_regs *));
+extern void m68k_setup_irq_controller(struct irq_controller *, unsigned int, unsigned int);
+
+asmlinkage void m68k_handle_int(unsigned int);
+asmlinkage void __m68k_handle_int(unsigned int, struct pt_regs *);
+
+#else
+#define irq_canonicalize(irq)  (irq)
+#endif /* CONFIG_MMU */
+
+#endif /* _M68K_IRQ_H_ */
diff --git a/arch/m68k/include/asm/irq_mm.h b/arch/m68k/include/asm/irq_mm.h
deleted file mode 100644 (file)
index 0cab42c..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-#ifndef _M68K_IRQ_H_
-#define _M68K_IRQ_H_
-
-#include <linux/linkage.h>
-#include <linux/hardirq.h>
-#include <linux/irqreturn.h>
-#include <linux/spinlock_types.h>
-
-/*
- * This should be the same as the max(NUM_X_SOURCES) for all the
- * different m68k hosts compiled into the kernel.
- * Currently the Atari has 72 and the Amiga 24, but if both are
- * supported in the kernel it is better to make room for 72.
- */
-#if defined(CONFIG_VME) || defined(CONFIG_SUN3) || defined(CONFIG_SUN3X)
-#define NR_IRQS 200
-#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC)
-#define NR_IRQS 72
-#elif defined(CONFIG_Q40)
-#define NR_IRQS        43
-#elif defined(CONFIG_AMIGA)
-#define NR_IRQS        32
-#elif defined(CONFIG_APOLLO)
-#define NR_IRQS        24
-#elif defined(CONFIG_HP300)
-#define NR_IRQS        8
-#else
-#define NR_IRQS        0
-#endif
-
-/*
- * The hardirq mask has to be large enough to have
- * space for potentially all IRQ sources in the system
- * nesting on a single CPU:
- */
-#if (1 << HARDIRQ_BITS) < NR_IRQS
-# error HARDIRQ_BITS is too low!
-#endif
-
-/*
- * Interrupt source definitions
- * General interrupt sources are the level 1-7.
- * Adding an interrupt service routine for one of these sources
- * results in the addition of that routine to a chain of routines.
- * Each one is called in succession.  Each individual interrupt
- * service routine should determine if the device associated with
- * that routine requires service.
- */
-
-#define IRQ_SPURIOUS   0
-
-#define IRQ_AUTO_1     1       /* level 1 interrupt */
-#define IRQ_AUTO_2     2       /* level 2 interrupt */
-#define IRQ_AUTO_3     3       /* level 3 interrupt */
-#define IRQ_AUTO_4     4       /* level 4 interrupt */
-#define IRQ_AUTO_5     5       /* level 5 interrupt */
-#define IRQ_AUTO_6     6       /* level 6 interrupt */
-#define IRQ_AUTO_7     7       /* level 7 interrupt (non-maskable) */
-
-#define IRQ_USER       8
-
-extern unsigned int irq_canonicalize(unsigned int irq);
-
-struct pt_regs;
-
-/*
- * various flags for request_irq() - the Amiga now uses the standard
- * mechanism like all other architectures - IRQF_DISABLED and
- * IRQF_SHARED are your friends.
- */
-#ifndef MACH_AMIGA_ONLY
-#define IRQ_FLG_LOCK   (0x0001)        /* handler is not replaceable   */
-#define IRQ_FLG_REPLACE        (0x0002)        /* replace existing handler     */
-#define IRQ_FLG_FAST   (0x0004)
-#define IRQ_FLG_SLOW   (0x0008)
-#define IRQ_FLG_STD    (0x8000)        /* internally used              */
-#endif
-
-/*
- * This structure is used to chain together the ISRs for a particular
- * interrupt source (if it supports chaining).
- */
-typedef struct irq_node {
-       irqreturn_t     (*handler)(int, void *);
-       void            *dev_id;
-       struct irq_node *next;
-       unsigned long   flags;
-       const char      *devname;
-} irq_node_t;
-
-/*
- * This structure has only 4 elements for speed reasons
- */
-struct irq_handler {
-       int             (*handler)(int, void *);
-       unsigned long   flags;
-       void            *dev_id;
-       const char      *devname;
-};
-
-struct irq_controller {
-       const char *name;
-       spinlock_t lock;
-       int (*startup)(unsigned int irq);
-       void (*shutdown)(unsigned int irq);
-       void (*enable)(unsigned int irq);
-       void (*disable)(unsigned int irq);
-};
-
-extern int m68k_irq_startup(unsigned int);
-extern void m68k_irq_shutdown(unsigned int);
-
-/*
- * This function returns a new irq_node_t
- */
-extern irq_node_t *new_irq_node(void);
-
-extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *));
-extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt,
-                                     void (*handler)(unsigned int, struct pt_regs *));
-extern void m68k_setup_irq_controller(struct irq_controller *, unsigned int, unsigned int);
-
-asmlinkage void m68k_handle_int(unsigned int);
-asmlinkage void __m68k_handle_int(unsigned int, struct pt_regs *);
-
-#endif /* _M68K_IRQ_H_ */
diff --git a/arch/m68k/include/asm/irq_no.h b/arch/m68k/include/asm/irq_no.h
deleted file mode 100644 (file)
index 9373c31..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef _M68KNOMMU_IRQ_H_
-#define _M68KNOMMU_IRQ_H_
-
-#ifdef CONFIG_COLDFIRE
-/*
- * On the ColdFire we keep track of all vectors. That way drivers
- * can register whatever vector number they wish, and we can deal
- * with it.
- */
-#define        SYS_IRQS        256
-#define        NR_IRQS         SYS_IRQS
-
-#else
-
-/*
- * # of m68k interrupts
- */
-#define SYS_IRQS       8
-#define NR_IRQS                (24 + SYS_IRQS)
-
-#endif /* CONFIG_COLDFIRE */
-
-
-#define irq_canonicalize(irq)  (irq)
-
-#endif /* _M68KNOMMU_IRQ_H_ */
index 7e3594dea88b01af1c792e24dfb4922d5b540468..9c384e294af9b172e4e258226739aab9b82c3552 100644 (file)
 #define        MCFSIM_PAR              0xcb            /* Pin Assignment reg (r/w) */
 #endif
 
-#define        MCFSIM_PADDR            0x1c5           /* Parallel Direction (r/w) */
-#define        MCFSIM_PADAT            0x1c9           /* Parallel Port Value (r/w) */
+#define        MCFSIM_PADDR            (MCF_MBAR + 0x1c5)      /* Parallel Direction (r/w) */
+#define        MCFSIM_PADAT            (MCF_MBAR + 0x1c9)      /* Parallel Port Value (r/w) */
+
+/*
+ *     Define system peripheral IRQ usage.
+ */
+#define        MCF_IRQ_TIMER           30              /* Timer0, Level 6 */
+#define        MCF_IRQ_PROFILER        31              /* Timer1, Level 7 */
+
+/*
+ * Generic GPIO
+ */
+#define MCFGPIO_PIN_MAX                8
+#define MCFGPIO_IRQ_VECBASE    -1
+#define MCFGPIO_IRQ_MAX                -1
 
 /*
  *     Some symbol defines for the Parallel Port Pin Assignment Register
 #define        MCFSIM_DMA2ICR          MCFSIM_ICR15    /* DMA 2 ICR */
 #endif
 
-#if defined(CONFIG_M5206e)
-#define        MCFSIM_IMR_MASKALL      0xfffe          /* All SIM intr sources */
-#endif
-
-/*
- *     Macro to get and set IMR register. It is 16 bits on the 5206.
- */
-#define        mcf_getimr()            \
-       *((volatile unsigned short *) (MCF_MBAR + MCFSIM_IMR))
-
-#define        mcf_setimr(imr)         \
-       *((volatile unsigned short *) (MCF_MBAR + MCFSIM_IMR)) = (imr)
-
-#define        mcf_getipr()            \
-       *((volatile unsigned short *) (MCF_MBAR + MCFSIM_IPR))
-
 /****************************************************************************/
 #endif /* m5206sim_h */
index 83bbcfd6e8f2b9d17aaff1eb908ee568967eb268..ed2b69b96805b50cafc1c8d09e9b07c51f23d77d 100644 (file)
@@ -11,9 +11,8 @@
 #define m520xsim_h
 /****************************************************************************/
 
-
 /*
- *  Define the 5282 SIM register set addresses.
+ *  Define the 520x SIM register set addresses.
  */
 #define MCFICM_INTC0        0x48000     /* Base for Interrupt Ctrl 0 */
 #define MCFINTC_IPRH        0x00        /* Interrupt pending 32-63 */
 #define MCFINTC_IMRL        0x0c        /* Interrupt mask 1-31 */
 #define MCFINTC_INTFRCH     0x10        /* Interrupt force 32-63 */
 #define MCFINTC_INTFRCL     0x14        /* Interrupt force 1-31 */
+#define MCFINTC_SIMR        0x1c        /* Set interrupt mask 0-63 */
+#define MCFINTC_CIMR        0x1d        /* Clear interrupt mask 0-63 */
 #define MCFINTC_ICR0        0x40        /* Base ICR register */
 
+/*
+ *  The common interrupt controller code just wants to know the absolute
+ *  address to the SIMR and CIMR registers (not offsets into IPSBAR).
+ *  The 520x family only has a single INTC unit.
+ */
+#define MCFINTC0_SIMR       (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_SIMR)
+#define MCFINTC0_CIMR       (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_CIMR)
+#define        MCFINTC0_ICR0       (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0)
+#define MCFINTC1_SIMR       (0)
+#define MCFINTC1_CIMR       (0)
+#define        MCFINTC1_ICR0       (0)
+
 #define MCFINT_VECBASE      64
 #define MCFINT_UART0        26          /* Interrupt number for UART0 */
 #define MCFINT_UART1        27          /* Interrupt number for UART1 */
 #define MCFSIM_SDCS0        0x000a8110 /* SDRAM Chip Select 0 Configuration */
 #define MCFSIM_SDCS1        0x000a8114 /* SDRAM Chip Select 1 Configuration */
 
+#define MCFEPORT_EPDDR                 0xFC088002
+#define MCFEPORT_EPDR                  0xFC088004
+#define MCFEPORT_EPPDR                 0xFC088005
+
+#define MCFGPIO_PODR_BUSCTL            0xFC0A4000
+#define MCFGPIO_PODR_BE                        0xFC0A4001
+#define MCFGPIO_PODR_CS                        0xFC0A4002
+#define MCFGPIO_PODR_FECI2C            0xFC0A4003
+#define MCFGPIO_PODR_QSPI              0xFC0A4004
+#define MCFGPIO_PODR_TIMER             0xFC0A4005
+#define MCFGPIO_PODR_UART              0xFC0A4006
+#define MCFGPIO_PODR_FECH              0xFC0A4007
+#define MCFGPIO_PODR_FECL              0xFC0A4008
+
+#define MCFGPIO_PDDR_BUSCTL            0xFC0A400C
+#define MCFGPIO_PDDR_BE                        0xFC0A400D
+#define MCFGPIO_PDDR_CS                        0xFC0A400E
+#define MCFGPIO_PDDR_FECI2C            0xFC0A400F
+#define MCFGPIO_PDDR_QSPI              0xFC0A4010
+#define MCFGPIO_PDDR_TIMER             0xFC0A4011
+#define MCFGPIO_PDDR_UART              0xFC0A4012
+#define MCFGPIO_PDDR_FECH              0xFC0A4013
+#define MCFGPIO_PDDR_FECL              0xFC0A4014
+
+#define MCFGPIO_PPDSDR_BUSCTL          0xFC0A401A
+#define MCFGPIO_PPDSDR_BE              0xFC0A401B
+#define MCFGPIO_PPDSDR_CS              0xFC0A401C
+#define MCFGPIO_PPDSDR_FECI2C          0xFC0A401D
+#define MCFGPIO_PPDSDR_QSPI            0xFC0A401E
+#define MCFGPIO_PPDSDR_TIMER           0xFC0A401F
+#define MCFGPIO_PPDSDR_UART            0xFC0A4021
+#define MCFGPIO_PPDSDR_FECH            0xFC0A4021
+#define MCFGPIO_PPDSDR_FECL            0xFC0A4022
+
+#define MCFGPIO_PCLRR_BUSCTL           0xFC0A4024
+#define MCFGPIO_PCLRR_BE               0xFC0A4025
+#define MCFGPIO_PCLRR_CS               0xFC0A4026
+#define MCFGPIO_PCLRR_FECI2C           0xFC0A4027
+#define MCFGPIO_PCLRR_QSPI             0xFC0A4028
+#define MCFGPIO_PCLRR_TIMER            0xFC0A4029
+#define MCFGPIO_PCLRR_UART             0xFC0A402A
+#define MCFGPIO_PCLRR_FECH             0xFC0A402B
+#define MCFGPIO_PCLRR_FECL             0xFC0A402C
+/*
+ * Generic GPIO support
+ */
+#define MCFGPIO_PODR                   MCFGPIO_PODR_BUSCTL
+#define MCFGPIO_PDDR                   MCFGPIO_PDDR_BUSCTL
+#define MCFGPIO_PPDR                   MCFGPIO_PPDSDR_BUSCTL
+#define MCFGPIO_SETR                   MCFGPIO_PPDSDR_BUSCTL
+#define MCFGPIO_CLRR                   MCFGPIO_PCLRR_BUSCTL
+
+#define MCFGPIO_PIN_MAX                        80
+#define MCFGPIO_IRQ_MAX                        8
+#define MCFGPIO_IRQ_VECBASE            MCFINT_VECBASE
+/****************************************************************************/
 
 #define MCF_GPIO_PAR_UART                   (0xA4036)
 #define MCF_GPIO_PAR_FECI2C                 (0xA4033)
 #define MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2   (0x02)
 #define MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2   (0x04)
 
-#define ICR_INTRCONF           0x05
-#define MCFPIT_IMR             MCFINTC_IMRL
-#define MCFPIT_IMR_IBIT                (1 << MCFINT_PIT1)
-
 /*
  *  Reset Controll Unit.
  */
index 55183b5df1b8716bd500c12013cbae45c86b8e52..a34894cf8e6f3ec02ea35fd3098c39c5084675c8 100644 (file)
 #define        MCF_RCR_SWRESET         0x80            /* Software reset bit */
 #define        MCF_RCR_FRCSTOUT        0x40            /* Force external reset */
 
+#define MCFGPIO_PODR_ADDR      (MCF_IPSBAR + 0x100000)
+#define MCFGPIO_PODR_DATAH     (MCF_IPSBAR + 0x100001)
+#define MCFGPIO_PODR_DATAL     (MCF_IPSBAR + 0x100002)
+#define MCFGPIO_PODR_BUSCTL    (MCF_IPSBAR + 0x100003)
+#define MCFGPIO_PODR_BS                (MCF_IPSBAR + 0x100004)
+#define MCFGPIO_PODR_CS                (MCF_IPSBAR + 0x100005)
+#define MCFGPIO_PODR_SDRAM     (MCF_IPSBAR + 0x100006)
+#define MCFGPIO_PODR_FECI2C    (MCF_IPSBAR + 0x100007)
+#define MCFGPIO_PODR_UARTH     (MCF_IPSBAR + 0x100008)
+#define MCFGPIO_PODR_UARTL     (MCF_IPSBAR + 0x100009)
+#define MCFGPIO_PODR_QSPI      (MCF_IPSBAR + 0x10000A)
+#define MCFGPIO_PODR_TIMER     (MCF_IPSBAR + 0x10000B)
+#define MCFGPIO_PODR_ETPU      (MCF_IPSBAR + 0x10000C)
+
+#define MCFGPIO_PDDR_ADDR      (MCF_IPSBAR + 0x100010)
+#define MCFGPIO_PDDR_DATAH     (MCF_IPSBAR + 0x100011)
+#define MCFGPIO_PDDR_DATAL     (MCF_IPSBAR + 0x100012)
+#define MCFGPIO_PDDR_BUSCTL    (MCF_IPSBAR + 0x100013)
+#define MCFGPIO_PDDR_BS                (MCF_IPSBAR + 0x100014)
+#define MCFGPIO_PDDR_CS                (MCF_IPSBAR + 0x100015)
+#define MCFGPIO_PDDR_SDRAM     (MCF_IPSBAR + 0x100016)
+#define MCFGPIO_PDDR_FECI2C    (MCF_IPSBAR + 0x100017)
+#define MCFGPIO_PDDR_UARTH     (MCF_IPSBAR + 0x100018)
+#define MCFGPIO_PDDR_UARTL     (MCF_IPSBAR + 0x100019)
+#define MCFGPIO_PDDR_QSPI      (MCF_IPSBAR + 0x10001A)
+#define MCFGPIO_PDDR_TIMER     (MCF_IPSBAR + 0x10001B)
+#define MCFGPIO_PDDR_ETPU      (MCF_IPSBAR + 0x10001C)
+
+#define MCFGPIO_PPDSDR_ADDR    (MCF_IPSBAR + 0x100020)
+#define MCFGPIO_PPDSDR_DATAH   (MCF_IPSBAR + 0x100021)
+#define MCFGPIO_PPDSDR_DATAL   (MCF_IPSBAR + 0x100022)
+#define MCFGPIO_PPDSDR_BUSCTL  (MCF_IPSBAR + 0x100023)
+#define MCFGPIO_PPDSDR_BS      (MCF_IPSBAR + 0x100024)
+#define MCFGPIO_PPDSDR_CS      (MCF_IPSBAR + 0x100025)
+#define MCFGPIO_PPDSDR_SDRAM   (MCF_IPSBAR + 0x100026)
+#define MCFGPIO_PPDSDR_FECI2C  (MCF_IPSBAR + 0x100027)
+#define MCFGPIO_PPDSDR_UARTH   (MCF_IPSBAR + 0x100028)
+#define MCFGPIO_PPDSDR_UARTL   (MCF_IPSBAR + 0x100029)
+#define MCFGPIO_PPDSDR_QSPI    (MCF_IPSBAR + 0x10002A)
+#define MCFGPIO_PPDSDR_TIMER   (MCF_IPSBAR + 0x10002B)
+#define MCFGPIO_PPDSDR_ETPU    (MCF_IPSBAR + 0x10002C)
+
+#define MCFGPIO_PCLRR_ADDR     (MCF_IPSBAR + 0x100030)
+#define MCFGPIO_PCLRR_DATAH    (MCF_IPSBAR + 0x100031)
+#define MCFGPIO_PCLRR_DATAL    (MCF_IPSBAR + 0x100032)
+#define MCFGPIO_PCLRR_BUSCTL   (MCF_IPSBAR + 0x100033)
+#define MCFGPIO_PCLRR_BS       (MCF_IPSBAR + 0x100034)
+#define MCFGPIO_PCLRR_CS       (MCF_IPSBAR + 0x100035)
+#define MCFGPIO_PCLRR_SDRAM    (MCF_IPSBAR + 0x100036)
+#define MCFGPIO_PCLRR_FECI2C   (MCF_IPSBAR + 0x100037)
+#define MCFGPIO_PCLRR_UARTH    (MCF_IPSBAR + 0x100038)
+#define MCFGPIO_PCLRR_UARTL    (MCF_IPSBAR + 0x100039)
+#define MCFGPIO_PCLRR_QSPI     (MCF_IPSBAR + 0x10003A)
+#define MCFGPIO_PCLRR_TIMER    (MCF_IPSBAR + 0x10003B)
+#define MCFGPIO_PCLRR_ETPU     (MCF_IPSBAR + 0x10003C)
+
+/*
+ * EPort
+ */
+
+#define MCFEPORT_EPDDR         (MCF_IPSBAR + 0x130002)
+#define MCFEPORT_EPDR          (MCF_IPSBAR + 0x130004)
+#define MCFEPORT_EPPDR         (MCF_IPSBAR + 0x130005)
+
+/*
+ * Generic GPIO support
+ */
+#define MCFGPIO_PODR                   MCFGPIO_PODR_ADDR
+#define MCFGPIO_PDDR                   MCFGPIO_PDDR_ADDR
+#define MCFGPIO_PPDR                   MCFGPIO_PPDSDR_ADDR
+#define MCFGPIO_SETR                   MCFGPIO_PPDSDR_ADDR
+#define MCFGPIO_CLRR                   MCFGPIO_PCLRR_ADDR
+
+#define MCFGPIO_PIN_MAX                        107
+#define MCFGPIO_IRQ_MAX                        8
+#define MCFGPIO_IRQ_VECBASE            MCFINT_VECBASE
+
 /****************************************************************************/
 #endif /* m523xsim_h */
index 366eb8602d2fb124aee5eab7b59341e49b41cf41..14bce877ed8853e6744e90c6e9665e256d7b938d 100644 (file)
 #define        MCFSIM_DMA2ICR          MCFSIM_ICR8     /* DMA 2 ICR */
 #define        MCFSIM_DMA3ICR          MCFSIM_ICR9     /* DMA 3 ICR */
 
+/*
+ *     Define system peripheral IRQ usage.
+ */
+#define        MCF_IRQ_TIMER           30              /* Timer0, Level 6 */
+#define        MCF_IRQ_PROFILER        31              /* Timer1, Level 7 */
+
 /*
  *     General purpose IO registers (in MBAR2).
  */
-#define        MCFSIM2_GPIOREAD        0x0             /* GPIO read values */
-#define        MCFSIM2_GPIOWRITE       0x4             /* GPIO write values */
-#define        MCFSIM2_GPIOENABLE      0x8             /* GPIO enabled */
-#define        MCFSIM2_GPIOFUNC        0xc             /* GPIO function */
-#define        MCFSIM2_GPIO1READ       0xb0            /* GPIO1 read values */
-#define        MCFSIM2_GPIO1WRITE      0xb4            /* GPIO1 write values */
-#define        MCFSIM2_GPIO1ENABLE     0xb8            /* GPIO1 enabled */
-#define        MCFSIM2_GPIO1FUNC       0xbc            /* GPIO1 function */
+#define        MCFSIM2_GPIOREAD        (MCF_MBAR2 + 0x000)     /* GPIO read values */
+#define        MCFSIM2_GPIOWRITE       (MCF_MBAR2 + 0x004)     /* GPIO write values */
+#define        MCFSIM2_GPIOENABLE      (MCF_MBAR2 + 0x008)     /* GPIO enabled */
+#define        MCFSIM2_GPIOFUNC        (MCF_MBAR2 + 0x00C)     /* GPIO function */
+#define        MCFSIM2_GPIO1READ       (MCF_MBAR2 + 0x0B0)     /* GPIO1 read values */
+#define        MCFSIM2_GPIO1WRITE      (MCF_MBAR2 + 0x0B4)     /* GPIO1 write values */
+#define        MCFSIM2_GPIO1ENABLE     (MCF_MBAR2 + 0x0B8)     /* GPIO1 enabled */
+#define        MCFSIM2_GPIO1FUNC       (MCF_MBAR2 + 0x0BC)     /* GPIO1 function */
 
 #define        MCFSIM2_GPIOINTSTAT     0xc0            /* GPIO interrupt status */
 #define        MCFSIM2_GPIOINTCLEAR    0xc0            /* GPIO interrupt clear */
 #define        MCFSIM2_IDECONFIG1      0x18c           /* IDEconfig1 */
 #define        MCFSIM2_IDECONFIG2      0x190           /* IDEconfig2 */
 
-
 /*
- *     Macro to set IMR register. It is 32 bits on the 5249.
+ * Define the base interrupt for the second interrupt controller.
+ * We set it to 128, out of the way of the base interrupts, and plenty
+ * of room for its 64 interrupts.
  */
-#define        MCFSIM_IMR_MASKALL      0x7fffe         /* All SIM intr sources */
+#define        MCFINTC2_VECBASE        128
 
-#define        mcf_getimr()            \
-       *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR))
+#define        MCFINTC2_GPIOIRQ0       (MCFINTC2_VECBASE + 32)
+#define        MCFINTC2_GPIOIRQ1       (MCFINTC2_VECBASE + 33)
+#define        MCFINTC2_GPIOIRQ2       (MCFINTC2_VECBASE + 34)
+#define        MCFINTC2_GPIOIRQ3       (MCFINTC2_VECBASE + 35)
+#define        MCFINTC2_GPIOIRQ4       (MCFINTC2_VECBASE + 36)
+#define        MCFINTC2_GPIOIRQ5       (MCFINTC2_VECBASE + 37)
+#define        MCFINTC2_GPIOIRQ6       (MCFINTC2_VECBASE + 38)
+#define        MCFINTC2_GPIOIRQ7       (MCFINTC2_VECBASE + 39)
 
-#define        mcf_setimr(imr)         \
-       *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr);
-
-#define        mcf_getipr()            \
-       *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR))
+/*
+ * Generic GPIO support
+ */
+#define MCFGPIO_PIN_MAX                64
+#define MCFGPIO_IRQ_MAX                -1
+#define MCFGPIO_IRQ_VECBASE    -1
 
 /****************************************************************************/
 
        subql   #1,%a1                          /* get MBAR2 address in a1 */
 
        /*
-        *      Move secondary interrupts to base at 128.
+        *      Move secondary interrupts to their base (128).
         */
-       moveb   #0x80,%d0
+       moveb   #MCFINTC2_VECBASE,%d0
        moveb   %d0,0x16b(%a1)                  /* interrupt base register */
 
        /*
index 6217edc2113955f7f6d722baf6d704ec562ed194..df3332c2317de8ae95eff60752596b5e0b962793 100644 (file)
@@ -12,7 +12,6 @@
 #define        m5272sim_h
 /****************************************************************************/
 
-
 /*
  *     Define the 5272 SIM register set addresses.
  */
 #define        MCFSIM_DCMR1            0x5c            /* DRAM 1 Mask reg (r/w) */
 #define        MCFSIM_DCCR1            0x63            /* DRAM 1 Control reg (r/w) */
 
-#define        MCFSIM_PACNT            0x80            /* Port A Control (r/w) */
-#define        MCFSIM_PADDR            0x84            /* Port A Direction (r/w) */
-#define        MCFSIM_PADAT            0x86            /* Port A Data (r/w) */
-#define        MCFSIM_PBCNT            0x88            /* Port B Control (r/w) */
-#define        MCFSIM_PBDDR            0x8c            /* Port B Direction (r/w) */
-#define        MCFSIM_PBDAT            0x8e            /* Port B Data (r/w) */
-#define        MCFSIM_PCDDR            0x94            /* Port C Direction (r/w) */
-#define        MCFSIM_PCDAT            0x96            /* Port C Data (r/w) */
-#define        MCFSIM_PDCNT            0x98            /* Port D Control (r/w) */
+#define        MCFSIM_PACNT            (MCF_MBAR + 0x80) /* Port A Control (r/w) */
+#define        MCFSIM_PADDR            (MCF_MBAR + 0x84) /* Port A Direction (r/w) */
+#define        MCFSIM_PADAT            (MCF_MBAR + 0x86) /* Port A Data (r/w) */
+#define        MCFSIM_PBCNT            (MCF_MBAR + 0x88) /* Port B Control (r/w) */
+#define        MCFSIM_PBDDR            (MCF_MBAR + 0x8c) /* Port B Direction (r/w) */
+#define        MCFSIM_PBDAT            (MCF_MBAR + 0x8e) /* Port B Data (r/w) */
+#define        MCFSIM_PCDDR            (MCF_MBAR + 0x94) /* Port C Direction (r/w) */
+#define        MCFSIM_PCDAT            (MCF_MBAR + 0x96) /* Port C Data (r/w) */
+#define        MCFSIM_PDCNT            (MCF_MBAR + 0x98) /* Port D Control (r/w) */
+
+/*
+ *     Define system peripheral IRQ usage.
+ */
+#define        MCFINT_VECBASE          64              /* Base of interrupts */
+#define        MCF_IRQ_SPURIOUS        64              /* User Spurious */
+#define        MCF_IRQ_EINT1           65              /* External Interrupt 1 */
+#define        MCF_IRQ_EINT2           66              /* External Interrupt 2 */
+#define        MCF_IRQ_EINT3           67              /* External Interrupt 3 */
+#define        MCF_IRQ_EINT4           68              /* External Interrupt 4 */
+#define        MCF_IRQ_TIMER1          69              /* Timer 1 */
+#define        MCF_IRQ_TIMER2          70              /* Timer 2 */
+#define        MCF_IRQ_TIMER3          71              /* Timer 3 */
+#define        MCF_IRQ_TIMER4          72              /* Timer 4 */
+#define        MCF_IRQ_UART1           73              /* UART 1 */
+#define        MCF_IRQ_UART2           74              /* UART 2 */
+#define        MCF_IRQ_PLIP            75              /* PLIC 2Khz Periodic */
+#define        MCF_IRQ_PLIA            76              /* PLIC Asynchronous */
+#define        MCF_IRQ_USB0            77              /* USB Endpoint 0 */
+#define        MCF_IRQ_USB1            78              /* USB Endpoint 1 */
+#define        MCF_IRQ_USB2            79              /* USB Endpoint 2 */
+#define        MCF_IRQ_USB3            80              /* USB Endpoint 3 */
+#define        MCF_IRQ_USB4            81              /* USB Endpoint 4 */
+#define        MCF_IRQ_USB5            82              /* USB Endpoint 5 */
+#define        MCF_IRQ_USB6            83              /* USB Endpoint 6 */
+#define        MCF_IRQ_USB7            84              /* USB Endpoint 7 */
+#define        MCF_IRQ_DMA             85              /* DMA Controller */
+#define        MCF_IRQ_ERX             86              /* Ethernet Receiver */
+#define        MCF_IRQ_ETX             87              /* Ethernet Transmitter */
+#define        MCF_IRQ_ENTC            88              /* Ethernet Non-Time Critical */
+#define        MCF_IRQ_QSPI            89              /* Queued Serial Interface */
+#define        MCF_IRQ_EINT5           90              /* External Interrupt 5 */
+#define        MCF_IRQ_EINT6           91              /* External Interrupt 6 */
+#define        MCF_IRQ_SWTO            92              /* Software Watchdog */
+#define        MCFINT_VECMAX           95              /* Maxmum interrupt */
 
+#define        MCF_IRQ_TIMER           MCF_IRQ_TIMER1
+#define        MCF_IRQ_PROFILER        MCF_IRQ_TIMER2
 
+/*
+ * Generic GPIO support
+ */
+#define MCFGPIO_PIN_MAX                        48
+#define MCFGPIO_IRQ_MAX                        -1
+#define MCFGPIO_IRQ_VECBASE            -1
 /****************************************************************************/
 #endif /* m5272sim_h */
index 95f4f8ee8f7c4131dca96d35cf87ea082d6e110d..453356d72d80a4a1dad0608603e8bf3fd585695a 100644 (file)
 #define        MCFSIM_DMR1             0x5c            /* SDRAM address mask 1 */
 #endif
 
+
+#ifdef CONFIG_M5271
+#define MCFGPIO_PODR_ADDR      (MCF_IPSBAR + 0x100000)
+#define MCFGPIO_PODR_DATAH     (MCF_IPSBAR + 0x100001)
+#define MCFGPIO_PODR_DATAL     (MCF_IPSBAR + 0x100002)
+#define MCFGPIO_PODR_BUSCTL    (MCF_IPSBAR + 0x100003)
+#define MCFGPIO_PODR_BS                (MCF_IPSBAR + 0x100004)
+#define MCFGPIO_PODR_CS                (MCF_IPSBAR + 0x100005)
+#define MCFGPIO_PODR_SDRAM     (MCF_IPSBAR + 0x100006)
+#define MCFGPIO_PODR_FECI2C    (MCF_IPSBAR + 0x100007)
+#define MCFGPIO_PODR_UARTH     (MCF_IPSBAR + 0x100008)
+#define MCFGPIO_PODR_UARTL     (MCF_IPSBAR + 0x100009)
+#define MCFGPIO_PODR_QSPI      (MCF_IPSBAR + 0x10000A)
+#define MCFGPIO_PODR_TIMER     (MCF_IPSBAR + 0x10000B)
+
+#define MCFGPIO_PDDR_ADDR      (MCF_IPSBAR + 0x100010)
+#define MCFGPIO_PDDR_DATAH     (MCF_IPSBAR + 0x100011)
+#define MCFGPIO_PDDR_DATAL     (MCF_IPSBAR + 0x100012)
+#define MCFGPIO_PDDR_BUSCTL    (MCF_IPSBAR + 0x100013)
+#define MCFGPIO_PDDR_BS                (MCF_IPSBAR + 0x100014)
+#define MCFGPIO_PDDR_CS                (MCF_IPSBAR + 0x100015)
+#define MCFGPIO_PDDR_SDRAM     (MCF_IPSBAR + 0x100016)
+#define MCFGPIO_PDDR_FECI2C    (MCF_IPSBAR + 0x100017)
+#define MCFGPIO_PDDR_UARTH     (MCF_IPSBAR + 0x100018)
+#define MCFGPIO_PDDR_UARTL     (MCF_IPSBAR + 0x100019)
+#define MCFGPIO_PDDR_QSPI      (MCF_IPSBAR + 0x10001A)
+#define MCFGPIO_PDDR_TIMER     (MCF_IPSBAR + 0x10001B)
+
+#define MCFGPIO_PPDSDR_ADDR    (MCF_IPSBAR + 0x100020)
+#define MCFGPIO_PPDSDR_DATAH   (MCF_IPSBAR + 0x100021)
+#define MCFGPIO_PPDSDR_DATAL   (MCF_IPSBAR + 0x100022)
+#define MCFGPIO_PPDSDR_BUSCTL  (MCF_IPSBAR + 0x100023)
+#define MCFGPIO_PPDSDR_BS      (MCF_IPSBAR + 0x100024)
+#define MCFGPIO_PPDSDR_CS      (MCF_IPSBAR + 0x100025)
+#define MCFGPIO_PPDSDR_SDRAM   (MCF_IPSBAR + 0x100026)
+#define MCFGPIO_PPDSDR_FECI2C  (MCF_IPSBAR + 0x100027)
+#define MCFGPIO_PPDSDR_UARTH   (MCF_IPSBAR + 0x100028)
+#define MCFGPIO_PPDSDR_UARTL   (MCF_IPSBAR + 0x100029)
+#define MCFGPIO_PPDSDR_QSPI    (MCF_IPSBAR + 0x10002A)
+#define MCFGPIO_PPDSDR_TIMER   (MCF_IPSBAR + 0x10002B)
+
+#define MCFGPIO_PCLRR_ADDR     (MCF_IPSBAR + 0x100030)
+#define MCFGPIO_PCLRR_DATAH    (MCF_IPSBAR + 0x100031)
+#define MCFGPIO_PCLRR_DATAL    (MCF_IPSBAR + 0x100032)
+#define MCFGPIO_PCLRR_BUSCTL   (MCF_IPSBAR + 0x100033)
+#define MCFGPIO_PCLRR_BS       (MCF_IPSBAR + 0x100034)
+#define MCFGPIO_PCLRR_CS       (MCF_IPSBAR + 0x100035)
+#define MCFGPIO_PCLRR_SDRAM    (MCF_IPSBAR + 0x100036)
+#define MCFGPIO_PCLRR_FECI2C   (MCF_IPSBAR + 0x100037)
+#define MCFGPIO_PCLRR_UARTH    (MCF_IPSBAR + 0x100038)
+#define MCFGPIO_PCLRR_UARTL    (MCF_IPSBAR + 0x100039)
+#define MCFGPIO_PCLRR_QSPI     (MCF_IPSBAR + 0x10003A)
+#define MCFGPIO_PCLRR_TIMER    (MCF_IPSBAR + 0x10003B)
+
+/*
+ * Generic GPIO support
+ */
+#define MCFGPIO_PODR                   MCFGPIO_PODR_ADDR
+#define MCFGPIO_PDDR                   MCFGPIO_PDDR_ADDR
+#define MCFGPIO_PPDR                   MCFGPIO_PPDSDR_ADDR
+#define MCFGPIO_SETR                   MCFGPIO_PPDSDR_ADDR
+#define MCFGPIO_CLRR                   MCFGPIO_PCLRR_ADDR
+
+#define MCFGPIO_PIN_MAX                        100
+#define MCFGPIO_IRQ_MAX                        8
+#define MCFGPIO_IRQ_VECBASE            MCFINT_VECBASE
+#endif
+
+#ifdef CONFIG_M5275
+#define MCFGPIO_PODR_BUSCTL    (MCF_IPSBAR + 0x100004)
+#define MCFGPIO_PODR_ADDR      (MCF_IPSBAR + 0x100005)
+#define MCFGPIO_PODR_CS                (MCF_IPSBAR + 0x100008)
+#define MCFGPIO_PODR_FEC0H     (MCF_IPSBAR + 0x10000A)
+#define MCFGPIO_PODR_FEC0L     (MCF_IPSBAR + 0x10000B)
+#define MCFGPIO_PODR_FECI2C    (MCF_IPSBAR + 0x10000C)
+#define MCFGPIO_PODR_QSPI      (MCF_IPSBAR + 0x10000D)
+#define MCFGPIO_PODR_SDRAM     (MCF_IPSBAR + 0x10000E)
+#define MCFGPIO_PODR_TIMERH    (MCF_IPSBAR + 0x10000F)
+#define MCFGPIO_PODR_TIMERL    (MCF_IPSBAR + 0x100010)
+#define MCFGPIO_PODR_UARTL     (MCF_IPSBAR + 0x100011)
+#define MCFGPIO_PODR_FEC1H     (MCF_IPSBAR + 0x100012)
+#define MCFGPIO_PODR_FEC1L     (MCF_IPSBAR + 0x100013)
+#define MCFGPIO_PODR_BS                (MCF_IPSBAR + 0x100014)
+#define MCFGPIO_PODR_IRQ       (MCF_IPSBAR + 0x100015)
+#define MCFGPIO_PODR_USBH      (MCF_IPSBAR + 0x100016)
+#define MCFGPIO_PODR_USBL      (MCF_IPSBAR + 0x100017)
+#define MCFGPIO_PODR_UARTH     (MCF_IPSBAR + 0x100018)
+
+#define MCFGPIO_PDDR_BUSCTL    (MCF_IPSBAR + 0x100020)
+#define MCFGPIO_PDDR_ADDR      (MCF_IPSBAR + 0x100021)
+#define MCFGPIO_PDDR_CS                (MCF_IPSBAR + 0x100024)
+#define MCFGPIO_PDDR_FEC0H     (MCF_IPSBAR + 0x100026)
+#define MCFGPIO_PDDR_FEC0L     (MCF_IPSBAR + 0x100027)
+#define MCFGPIO_PDDR_FECI2C    (MCF_IPSBAR + 0x100028)
+#define MCFGPIO_PDDR_QSPI      (MCF_IPSBAR + 0x100029)
+#define MCFGPIO_PDDR_SDRAM     (MCF_IPSBAR + 0x10002A)
+#define MCFGPIO_PDDR_TIMERH    (MCF_IPSBAR + 0x10002B)
+#define MCFGPIO_PDDR_TIMERL    (MCF_IPSBAR + 0x10002C)
+#define MCFGPIO_PDDR_UARTL     (MCF_IPSBAR + 0x10002D)
+#define MCFGPIO_PDDR_FEC1H     (MCF_IPSBAR + 0x10002E)
+#define MCFGPIO_PDDR_FEC1L     (MCF_IPSBAR + 0x10002F)
+#define MCFGPIO_PDDR_BS                (MCF_IPSBAR + 0x100030)
+#define MCFGPIO_PDDR_IRQ       (MCF_IPSBAR + 0x100031)
+#define MCFGPIO_PDDR_USBH      (MCF_IPSBAR + 0x100032)
+#define MCFGPIO_PDDR_USBL      (MCF_IPSBAR + 0x100033)
+#define MCFGPIO_PDDR_UARTH     (MCF_IPSBAR + 0x100034)
+
+#define MCFGPIO_PPDSDR_BUSCTL  (MCF_IPSBAR + 0x10003C)
+#define MCFGPIO_PPDSDR_ADDR    (MCF_IPSBAR + 0x10003D)
+#define MCFGPIO_PPDSDR_CS      (MCF_IPSBAR + 0x100040)
+#define MCFGPIO_PPDSDR_FEC0H   (MCF_IPSBAR + 0x100042)
+#define MCFGPIO_PPDSDR_FEC0L   (MCF_IPSBAR + 0x100043)
+#define MCFGPIO_PPDSDR_FECI2C  (MCF_IPSBAR + 0x100044)
+#define MCFGPIO_PPDSDR_QSPI    (MCF_IPSBAR + 0x100045)
+#define MCFGPIO_PPDSDR_SDRAM   (MCF_IPSBAR + 0x100046)
+#define MCFGPIO_PPDSDR_TIMERH  (MCF_IPSBAR + 0x100047)
+#define MCFGPIO_PPDSDR_TIMERL  (MCF_IPSBAR + 0x100048)
+#define MCFGPIO_PPDSDR_UARTL   (MCF_IPSBAR + 0x100049)
+#define MCFGPIO_PPDSDR_FEC1H   (MCF_IPSBAR + 0x10004A)
+#define MCFGPIO_PPDSDR_FEC1L   (MCF_IPSBAR + 0x10004B)
+#define MCFGPIO_PPDSDR_BS      (MCF_IPSBAR + 0x10004C)
+#define MCFGPIO_PPDSDR_IRQ     (MCF_IPSBAR + 0x10004D)
+#define MCFGPIO_PPDSDR_USBH    (MCF_IPSBAR + 0x10004E)
+#define MCFGPIO_PPDSDR_USBL    (MCF_IPSBAR + 0x10004F)
+#define MCFGPIO_PPDSDR_UARTH   (MCF_IPSBAR + 0x100050)
+
+#define MCFGPIO_PCLRR_BUSCTL   (MCF_IPSBAR + 0x100058)
+#define MCFGPIO_PCLRR_ADDR     (MCF_IPSBAR + 0x100059)
+#define MCFGPIO_PCLRR_CS       (MCF_IPSBAR + 0x10005C)
+#define MCFGPIO_PCLRR_FEC0H    (MCF_IPSBAR + 0x10005E)
+#define MCFGPIO_PCLRR_FEC0L    (MCF_IPSBAR + 0x10005F)
+#define MCFGPIO_PCLRR_FECI2C   (MCF_IPSBAR + 0x100060)
+#define MCFGPIO_PCLRR_QSPI     (MCF_IPSBAR + 0x100061)
+#define MCFGPIO_PCLRR_SDRAM    (MCF_IPSBAR + 0x100062)
+#define MCFGPIO_PCLRR_TIMERH   (MCF_IPSBAR + 0x100063)
+#define MCFGPIO_PCLRR_TIMERL   (MCF_IPSBAR + 0x100064)
+#define MCFGPIO_PCLRR_UARTL    (MCF_IPSBAR + 0x100065)
+#define MCFGPIO_PCLRR_FEC1H    (MCF_IPSBAR + 0x100066)
+#define MCFGPIO_PCLRR_FEC1L    (MCF_IPSBAR + 0x100067)
+#define MCFGPIO_PCLRR_BS       (MCF_IPSBAR + 0x100068)
+#define MCFGPIO_PCLRR_IRQ      (MCF_IPSBAR + 0x100069)
+#define MCFGPIO_PCLRR_USBH     (MCF_IPSBAR + 0x10006A)
+#define MCFGPIO_PCLRR_USBL     (MCF_IPSBAR + 0x10006B)
+#define MCFGPIO_PCLRR_UARTH    (MCF_IPSBAR + 0x10006C)
+
+
+/*
+ * Generic GPIO support
+ */
+#define MCFGPIO_PODR                   MCFGPIO_PODR_BUSCTL
+#define MCFGPIO_PDDR                   MCFGPIO_PDDR_BUSCTL
+#define MCFGPIO_PPDR                   MCFGPIO_PPDSDR_BUSCTL
+#define MCFGPIO_SETR                   MCFGPIO_PPDSDR_BUSCTL
+#define MCFGPIO_CLRR                   MCFGPIO_PCLRR_BUSCTL
+
+#define MCFGPIO_PIN_MAX                        148
+#define MCFGPIO_IRQ_MAX                        8
+#define MCFGPIO_IRQ_VECBASE            MCFINT_VECBASE
+#endif
+
+/*
+ * EPort
+ */
+
+#define MCFEPORT_EPDDR         (MCF_IPSBAR + 0x130002)
+#define MCFEPORT_EPDR          (MCF_IPSBAR + 0x130004)
+#define MCFEPORT_EPPDR         (MCF_IPSBAR + 0x130005)
+
+
 /*
  *     GPIO pins setups to enable the UARTs.
  */
index d79c49f8134ab05583aa8ef91f88ca60b161d71c..e2ad1f42b65709e762621c06e53420c7e839e571 100644 (file)
 #define        MCFSIM_DACR1            0x50            /* SDRAM base address 1 */
 #define        MCFSIM_DMR1             0x54            /* SDRAM address mask 1 */
 
+/*
+ *     GPIO registers
+ */
+#define MCFGPIO_PORTA          (MCF_IPSBAR + 0x00100000)
+#define MCFGPIO_PORTB          (MCF_IPSBAR + 0x00100001)
+#define MCFGPIO_PORTC          (MCF_IPSBAR + 0x00100002)
+#define MCFGPIO_PORTD          (MCF_IPSBAR + 0x00100003)
+#define MCFGPIO_PORTE          (MCF_IPSBAR + 0x00100004)
+#define MCFGPIO_PORTF          (MCF_IPSBAR + 0x00100005)
+#define MCFGPIO_PORTG          (MCF_IPSBAR + 0x00100006)
+#define MCFGPIO_PORTH          (MCF_IPSBAR + 0x00100007)
+#define MCFGPIO_PORTJ          (MCF_IPSBAR + 0x00100008)
+#define MCFGPIO_PORTDD         (MCF_IPSBAR + 0x00100009)
+#define MCFGPIO_PORTEH         (MCF_IPSBAR + 0x0010000A)
+#define MCFGPIO_PORTEL         (MCF_IPSBAR + 0x0010000B)
+#define MCFGPIO_PORTAS         (MCF_IPSBAR + 0x0010000C)
+#define MCFGPIO_PORTQS         (MCF_IPSBAR + 0x0010000D)
+#define MCFGPIO_PORTSD         (MCF_IPSBAR + 0x0010000E)
+#define MCFGPIO_PORTTC         (MCF_IPSBAR + 0x0010000F)
+#define MCFGPIO_PORTTD         (MCF_IPSBAR + 0x00100010)
+#define MCFGPIO_PORTUA         (MCF_IPSBAR + 0x00100011)
+
+#define MCFGPIO_DDRA           (MCF_IPSBAR + 0x00100014)
+#define MCFGPIO_DDRB           (MCF_IPSBAR + 0x00100015)
+#define MCFGPIO_DDRC           (MCF_IPSBAR + 0x00100016)
+#define MCFGPIO_DDRD           (MCF_IPSBAR + 0x00100017)
+#define MCFGPIO_DDRE           (MCF_IPSBAR + 0x00100018)
+#define MCFGPIO_DDRF           (MCF_IPSBAR + 0x00100019)
+#define MCFGPIO_DDRG           (MCF_IPSBAR + 0x0010001A)
+#define MCFGPIO_DDRH           (MCF_IPSBAR + 0x0010001B)
+#define MCFGPIO_DDRJ           (MCF_IPSBAR + 0x0010001C)
+#define MCFGPIO_DDRDD          (MCF_IPSBAR + 0x0010001D)
+#define MCFGPIO_DDREH          (MCF_IPSBAR + 0x0010001E)
+#define MCFGPIO_DDREL          (MCF_IPSBAR + 0x0010001F)
+#define MCFGPIO_DDRAS          (MCF_IPSBAR + 0x00100020)
+#define MCFGPIO_DDRQS          (MCF_IPSBAR + 0x00100021)
+#define MCFGPIO_DDRSD          (MCF_IPSBAR + 0x00100022)
+#define MCFGPIO_DDRTC          (MCF_IPSBAR + 0x00100023)
+#define MCFGPIO_DDRTD          (MCF_IPSBAR + 0x00100024)
+#define MCFGPIO_DDRUA          (MCF_IPSBAR + 0x00100025)
+
+#define MCFGPIO_PORTAP         (MCF_IPSBAR + 0x00100028)
+#define MCFGPIO_PORTBP         (MCF_IPSBAR + 0x00100029)
+#define MCFGPIO_PORTCP         (MCF_IPSBAR + 0x0010002A)
+#define MCFGPIO_PORTDP         (MCF_IPSBAR + 0x0010002B)
+#define MCFGPIO_PORTEP         (MCF_IPSBAR + 0x0010002C)
+#define MCFGPIO_PORTFP         (MCF_IPSBAR + 0x0010002D)
+#define MCFGPIO_PORTGP         (MCF_IPSBAR + 0x0010002E)
+#define MCFGPIO_PORTHP         (MCF_IPSBAR + 0x0010002F)
+#define MCFGPIO_PORTJP         (MCF_IPSBAR + 0x00100030)
+#define MCFGPIO_PORTDDP                (MCF_IPSBAR + 0x00100031)
+#define MCFGPIO_PORTEHP                (MCF_IPSBAR + 0x00100032)
+#define MCFGPIO_PORTELP                (MCF_IPSBAR + 0x00100033)
+#define MCFGPIO_PORTASP                (MCF_IPSBAR + 0x00100034)
+#define MCFGPIO_PORTQSP                (MCF_IPSBAR + 0x00100035)
+#define MCFGPIO_PORTSDP                (MCF_IPSBAR + 0x00100036)
+#define MCFGPIO_PORTTCP                (MCF_IPSBAR + 0x00100037)
+#define MCFGPIO_PORTTDP                (MCF_IPSBAR + 0x00100038)
+#define MCFGPIO_PORTUAP                (MCF_IPSBAR + 0x00100039)
+
+#define MCFGPIO_SETA           (MCF_IPSBAR + 0x00100028)
+#define MCFGPIO_SETB           (MCF_IPSBAR + 0x00100029)
+#define MCFGPIO_SETC           (MCF_IPSBAR + 0x0010002A)
+#define MCFGPIO_SETD           (MCF_IPSBAR + 0x0010002B)
+#define MCFGPIO_SETE           (MCF_IPSBAR + 0x0010002C)
+#define MCFGPIO_SETF           (MCF_IPSBAR + 0x0010002D)
+#define MCFGPIO_SETG           (MCF_IPSBAR + 0x0010002E)
+#define MCFGPIO_SETH           (MCF_IPSBAR + 0x0010002F)
+#define MCFGPIO_SETJ           (MCF_IPSBAR + 0x00100030)
+#define MCFGPIO_SETDD          (MCF_IPSBAR + 0x00100031)
+#define MCFGPIO_SETEH          (MCF_IPSBAR + 0x00100032)
+#define MCFGPIO_SETEL          (MCF_IPSBAR + 0x00100033)
+#define MCFGPIO_SETAS          (MCF_IPSBAR + 0x00100034)
+#define MCFGPIO_SETQS          (MCF_IPSBAR + 0x00100035)
+#define MCFGPIO_SETSD          (MCF_IPSBAR + 0x00100036)
+#define MCFGPIO_SETTC          (MCF_IPSBAR + 0x00100037)
+#define MCFGPIO_SETTD          (MCF_IPSBAR + 0x00100038)
+#define MCFGPIO_SETUA          (MCF_IPSBAR + 0x00100039)
+
+#define MCFGPIO_CLRA           (MCF_IPSBAR + 0x0010003C)
+#define MCFGPIO_CLRB           (MCF_IPSBAR + 0x0010003D)
+#define MCFGPIO_CLRC           (MCF_IPSBAR + 0x0010003E)
+#define MCFGPIO_CLRD           (MCF_IPSBAR + 0x0010003F)
+#define MCFGPIO_CLRE           (MCF_IPSBAR + 0x00100040)
+#define MCFGPIO_CLRF           (MCF_IPSBAR + 0x00100041)
+#define MCFGPIO_CLRG           (MCF_IPSBAR + 0x00100042)
+#define MCFGPIO_CLRH           (MCF_IPSBAR + 0x00100043)
+#define MCFGPIO_CLRJ           (MCF_IPSBAR + 0x00100044)
+#define MCFGPIO_CLRDD          (MCF_IPSBAR + 0x00100045)
+#define MCFGPIO_CLREH          (MCF_IPSBAR + 0x00100046)
+#define MCFGPIO_CLREL          (MCF_IPSBAR + 0x00100047)
+#define MCFGPIO_CLRAS          (MCF_IPSBAR + 0x00100048)
+#define MCFGPIO_CLRQS          (MCF_IPSBAR + 0x00100049)
+#define MCFGPIO_CLRSD          (MCF_IPSBAR + 0x0010004A)
+#define MCFGPIO_CLRTC          (MCF_IPSBAR + 0x0010004B)
+#define MCFGPIO_CLRTD          (MCF_IPSBAR + 0x0010004C)
+#define MCFGPIO_CLRUA          (MCF_IPSBAR + 0x0010004D)
+
+#define MCFGPIO_PBCDPAR                (MCF_IPSBAR + 0x00100050)
+#define MCFGPIO_PFPAR          (MCF_IPSBAR + 0x00100051)
+#define MCFGPIO_PEPAR          (MCF_IPSBAR + 0x00100052)
+#define MCFGPIO_PJPAR          (MCF_IPSBAR + 0x00100054)
+#define MCFGPIO_PSDPAR         (MCF_IPSBAR + 0x00100055)
+#define MCFGPIO_PASPAR         (MCF_IPSBAR + 0x00100056)
+#define MCFGPIO_PEHLPAR                (MCF_IPSBAR + 0x00100058)
+#define MCFGPIO_PQSPAR         (MCF_IPSBAR + 0x00100059)
+#define MCFGPIO_PTCPAR         (MCF_IPSBAR + 0x0010005A)
+#define MCFGPIO_PTDPAR         (MCF_IPSBAR + 0x0010005B)
+#define MCFGPIO_PUAPAR         (MCF_IPSBAR + 0x0010005C)
+
+/*
+ *     Edge Port registers
+ */
+#define MCFEPORT_EPPAR         (MCF_IPSBAR + 0x00130000)
+#define MCFEPORT_EPDDR         (MCF_IPSBAR + 0x00130002)
+#define MCFEPORT_EPIER         (MCF_IPSBAR + 0x00130003)
+#define MCFEPORT_EPDR          (MCF_IPSBAR + 0x00130004)
+#define MCFEPORT_EPPDR         (MCF_IPSBAR + 0x00130005)
+#define MCFEPORT_EPFR          (MCF_IPSBAR + 0x00130006)
+
+/*
+ *     Queued ADC registers
+ */
+#define MCFQADC_PORTQA         (MCF_IPSBAR + 0x00190006)
+#define MCFQADC_PORTQB         (MCF_IPSBAR + 0x00190007)
+#define MCFQADC_DDRQA          (MCF_IPSBAR + 0x00190008)
+#define MCFQADC_DDRQB          (MCF_IPSBAR + 0x00190009)
+
+/*
+ *     General Purpose Timers registers
+ */
+#define MCFGPTA_GPTPORT                (MCF_IPSBAR + 0x001A001D)
+#define MCFGPTA_GPTDDR         (MCF_IPSBAR + 0x001A001E)
+#define MCFGPTB_GPTPORT                (MCF_IPSBAR + 0x001B001D)
+#define MCFGPTB_GPTDDR         (MCF_IPSBAR + 0x001B001E)
+/*
+ *
+ * definitions for generic gpio support
+ *
+ */
+#define MCFGPIO_PODR           MCFGPIO_PORTA   /* port output data */
+#define MCFGPIO_PDDR           MCFGPIO_DDRA    /* port data direction */
+#define MCFGPIO_PPDR           MCFGPIO_PORTAP  /* port pin data */
+#define MCFGPIO_SETR           MCFGPIO_SETA    /* set output */
+#define MCFGPIO_CLRR           MCFGPIO_CLRA    /* clr output */
+
+#define MCFGPIO_IRQ_MAX                8
+#define MCFGPIO_IRQ_VECBASE    MCFINT_VECBASE
+#define MCFGPIO_PIN_MAX                180
+
+
 /*
  *     Derek Cheung - 6 Feb 2005
  *             add I2C and QSPI register definition using Freescale's MCF5282
index 5886728409c07894522da014d95dd022958840e1..c6830e5b54ce0bdb0dae58f95b03505bc609321e 100644 (file)
 #define MCFSIM_DACR1           0x110           /* DRAM 1 Addr and Ctrl (r/w) */
 #define MCFSIM_DMR1            0x114           /* DRAM 1 Mask reg (r/w) */
 
-#define        MCFSIM_PADDR            0x244           /* Parallel Direction (r/w) */
-#define        MCFSIM_PADAT            0x248           /* Parallel Data (r/w) */
+#define        MCFSIM_PADDR            (MCF_MBAR + 0x244)
+#define        MCFSIM_PADAT            (MCF_MBAR + 0x248)
+
+/*
+ * Generic GPIO support
+ */
+#define MCFGPIO_PIN_MAX                        16
+#define MCFGPIO_IRQ_MAX                        -1
+#define MCFGPIO_IRQ_VECBASE            -1
 
 
 /* Definition offset address for CS2-7  -- old mask 5307 */
 #define        MCFSIM_DMA2ICR          MCFSIM_ICR8     /* DMA 2 ICR */
 #define        MCFSIM_DMA3ICR          MCFSIM_ICR9     /* DMA 3 ICR */
 
-#if defined(CONFIG_M5307)
-#define        MCFSIM_IMR_MASKALL      0x3fffe         /* All SIM intr sources */
-#endif
-
-/*
- *     Macro to set IMR register. It is 32 bits on the 5307.
- */
-#define        mcf_getimr()            \
-       *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR))
-
-#define        mcf_setimr(imr)         \
-       *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr);
-
-#define        mcf_getipr()            \
-       *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR))
-
 
 /*
  *     Some symbol defines for the Parallel Port Pin Assignment Register
 #define IRQ3_LEVEL6    0x40
 #define IRQ1_LEVEL2    0x20
 
+/*
+ *     Define system peripheral IRQ usage.
+ */
+#define        MCF_IRQ_TIMER           30              /* Timer0, Level 6 */
+#define        MCF_IRQ_PROFILER        31              /* Timer1, Level 7 */
 
 /*
  *     Define the Cache register flags.
index eb7fd444894748ccadc262093b09712ecebcfd77..36bf15aec9aebcfc6da77bc3f2f83e2907a5a805 100644 (file)
 #define        MCFSIM_DMA3ICR          MCFSIM_ICR9     /* DMA 3 ICR */
 
 
-#define        MCFSIM_IMR_MASKALL      0xFFFFFFFF      /* All SIM intr sources */
-
-#define MCFSIM_IMR_SIMR0       0xFC04801C
-#define MCFSIM_IMR_SIMR1       0xFC04C01C
-#define MCFSIM_IMR_CIMR0       0xFC04801D
-#define MCFSIM_IMR_CIMR1       0xFC04C01D
+#define        MCFINTC0_SIMR           0xFC04801C
+#define        MCFINTC0_CIMR           0xFC04801D
+#define        MCFINTC0_ICR0           0xFC048040
+#define        MCFINTC1_SIMR           0xFC04C01C
+#define        MCFINTC1_CIMR           0xFC04C01D
+#define        MCFINTC1_ICR0           0xFC04C040
 
 #define MCFSIM_ICR_TIMER1      (0xFC048040+32)
 #define MCFSIM_ICR_TIMER2      (0xFC048040+33)
 
-
 /*
- *     Macro to set IMR register. It is 32 bits on the 5307.
+ *     Define system peripheral IRQ usage.
  */
-#define        mcf_getimr()            \
-       *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR))
-
-#define        mcf_setimr(imr)         \
-       *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr);
-
-#define        mcf_getipr()            \
-       *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR))
-
-#define        mcf_getiprl()           \
-       *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPRL))
-
-#define        mcf_getiprh()           \
-       *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPRH))
-
-
-#define mcf_enable_irq0(irq)           \
-       *((volatile unsigned char*) (MCFSIM_IMR_CIMR0)) = (irq);
-
-#define mcf_enable_irq1(irq)           \
-       *((volatile unsigned char*) (MCFSIM_IMR_CIMR1)) = (irq);
-
-#define mcf_disable_irq0(irq)          \
-       *((volatile unsigned char*) (MCFSIM_IMR_SIMR0)) = (irq);
-
-#define mcf_disable_irq1(irq)          \
-       *((volatile unsigned char*) (MCFSIM_IMR_SIMR1)) = (irq);
+#define        MCF_IRQ_TIMER           (64 + 32)       /* Timer0 */
+#define        MCF_IRQ_PROFILER        (64 + 33)       /* Timer1 */
 
 /*
  *     Define the Cache register flags.
  *********************************************************************/
 
 /* Register read/write macros */
-#define MCF_GPIO_PODR_FECH             MCF_REG08(0xFC0A4000)
-#define MCF_GPIO_PODR_FECL             MCF_REG08(0xFC0A4001)
-#define MCF_GPIO_PODR_SSI              MCF_REG08(0xFC0A4002)
-#define MCF_GPIO_PODR_BUSCTL           MCF_REG08(0xFC0A4003)
-#define MCF_GPIO_PODR_BE               MCF_REG08(0xFC0A4004)
-#define MCF_GPIO_PODR_CS               MCF_REG08(0xFC0A4005)
-#define MCF_GPIO_PODR_PWM              MCF_REG08(0xFC0A4006)
-#define MCF_GPIO_PODR_FECI2C           MCF_REG08(0xFC0A4007)
-#define MCF_GPIO_PODR_UART             MCF_REG08(0xFC0A4009)
-#define MCF_GPIO_PODR_QSPI             MCF_REG08(0xFC0A400A)
-#define MCF_GPIO_PODR_TIMER            MCF_REG08(0xFC0A400B)
-#define MCF_GPIO_PODR_LCDDATAH         MCF_REG08(0xFC0A400D)
-#define MCF_GPIO_PODR_LCDDATAM         MCF_REG08(0xFC0A400E)
-#define MCF_GPIO_PODR_LCDDATAL         MCF_REG08(0xFC0A400F)
-#define MCF_GPIO_PODR_LCDCTLH          MCF_REG08(0xFC0A4010)
-#define MCF_GPIO_PODR_LCDCTLL          MCF_REG08(0xFC0A4011)
-#define MCF_GPIO_PDDR_FECH             MCF_REG08(0xFC0A4014)
-#define MCF_GPIO_PDDR_FECL             MCF_REG08(0xFC0A4015)
-#define MCF_GPIO_PDDR_SSI              MCF_REG08(0xFC0A4016)
-#define MCF_GPIO_PDDR_BUSCTL           MCF_REG08(0xFC0A4017)
-#define MCF_GPIO_PDDR_BE               MCF_REG08(0xFC0A4018)
-#define MCF_GPIO_PDDR_CS               MCF_REG08(0xFC0A4019)
-#define MCF_GPIO_PDDR_PWM              MCF_REG08(0xFC0A401A)
-#define MCF_GPIO_PDDR_FECI2C           MCF_REG08(0xFC0A401B)
-#define MCF_GPIO_PDDR_UART             MCF_REG08(0xFC0A401C)
-#define MCF_GPIO_PDDR_QSPI             MCF_REG08(0xFC0A401E)
-#define MCF_GPIO_PDDR_TIMER            MCF_REG08(0xFC0A401F)
-#define MCF_GPIO_PDDR_LCDDATAH         MCF_REG08(0xFC0A4021)
-#define MCF_GPIO_PDDR_LCDDATAM         MCF_REG08(0xFC0A4022)
-#define MCF_GPIO_PDDR_LCDDATAL         MCF_REG08(0xFC0A4023)
-#define MCF_GPIO_PDDR_LCDCTLH          MCF_REG08(0xFC0A4024)
-#define MCF_GPIO_PDDR_LCDCTLL          MCF_REG08(0xFC0A4025)
-#define MCF_GPIO_PPDSDR_FECH           MCF_REG08(0xFC0A4028)
-#define MCF_GPIO_PPDSDR_FECL           MCF_REG08(0xFC0A4029)
-#define MCF_GPIO_PPDSDR_SSI            MCF_REG08(0xFC0A402A)
-#define MCF_GPIO_PPDSDR_BUSCTL         MCF_REG08(0xFC0A402B)
-#define MCF_GPIO_PPDSDR_BE             MCF_REG08(0xFC0A402C)
-#define MCF_GPIO_PPDSDR_CS             MCF_REG08(0xFC0A402D)
-#define MCF_GPIO_PPDSDR_PWM            MCF_REG08(0xFC0A402E)
-#define MCF_GPIO_PPDSDR_FECI2C         MCF_REG08(0xFC0A402F)
-#define MCF_GPIO_PPDSDR_UART           MCF_REG08(0xFC0A4031)
-#define MCF_GPIO_PPDSDR_QSPI           MCF_REG08(0xFC0A4032)
-#define MCF_GPIO_PPDSDR_TIMER          MCF_REG08(0xFC0A4033)
-#define MCF_GPIO_PPDSDR_LCDDATAH       MCF_REG08(0xFC0A4035)
-#define MCF_GPIO_PPDSDR_LCDDATAM       MCF_REG08(0xFC0A4036)
-#define MCF_GPIO_PPDSDR_LCDDATAL       MCF_REG08(0xFC0A4037)
-#define MCF_GPIO_PPDSDR_LCDCTLH                MCF_REG08(0xFC0A4038)
-#define MCF_GPIO_PPDSDR_LCDCTLL                MCF_REG08(0xFC0A4039)
-#define MCF_GPIO_PCLRR_FECH            MCF_REG08(0xFC0A403C)
-#define MCF_GPIO_PCLRR_FECL            MCF_REG08(0xFC0A403D)
-#define MCF_GPIO_PCLRR_SSI             MCF_REG08(0xFC0A403E)
-#define MCF_GPIO_PCLRR_BUSCTL          MCF_REG08(0xFC0A403F)
-#define MCF_GPIO_PCLRR_BE              MCF_REG08(0xFC0A4040)
-#define MCF_GPIO_PCLRR_CS              MCF_REG08(0xFC0A4041)
-#define MCF_GPIO_PCLRR_PWM             MCF_REG08(0xFC0A4042)
-#define MCF_GPIO_PCLRR_FECI2C          MCF_REG08(0xFC0A4043)
-#define MCF_GPIO_PCLRR_UART            MCF_REG08(0xFC0A4045)
-#define MCF_GPIO_PCLRR_QSPI            MCF_REG08(0xFC0A4046)
-#define MCF_GPIO_PCLRR_TIMER           MCF_REG08(0xFC0A4047)
-#define MCF_GPIO_PCLRR_LCDDATAH                MCF_REG08(0xFC0A4049)
-#define MCF_GPIO_PCLRR_LCDDATAM                MCF_REG08(0xFC0A404A)
-#define MCF_GPIO_PCLRR_LCDDATAL                MCF_REG08(0xFC0A404B)
-#define MCF_GPIO_PCLRR_LCDCTLH         MCF_REG08(0xFC0A404C)
-#define MCF_GPIO_PCLRR_LCDCTLL         MCF_REG08(0xFC0A404D)
+#define MCFGPIO_PODR_FECH              (0xFC0A4000)
+#define MCFGPIO_PODR_FECL              (0xFC0A4001)
+#define MCFGPIO_PODR_SSI               (0xFC0A4002)
+#define MCFGPIO_PODR_BUSCTL            (0xFC0A4003)
+#define MCFGPIO_PODR_BE                        (0xFC0A4004)
+#define MCFGPIO_PODR_CS                        (0xFC0A4005)
+#define MCFGPIO_PODR_PWM               (0xFC0A4006)
+#define MCFGPIO_PODR_FECI2C            (0xFC0A4007)
+#define MCFGPIO_PODR_UART              (0xFC0A4009)
+#define MCFGPIO_PODR_QSPI              (0xFC0A400A)
+#define MCFGPIO_PODR_TIMER             (0xFC0A400B)
+#define MCFGPIO_PODR_LCDDATAH          (0xFC0A400D)
+#define MCFGPIO_PODR_LCDDATAM          (0xFC0A400E)
+#define MCFGPIO_PODR_LCDDATAL          (0xFC0A400F)
+#define MCFGPIO_PODR_LCDCTLH           (0xFC0A4010)
+#define MCFGPIO_PODR_LCDCTLL           (0xFC0A4011)
+#define MCFGPIO_PDDR_FECH              (0xFC0A4014)
+#define MCFGPIO_PDDR_FECL              (0xFC0A4015)
+#define MCFGPIO_PDDR_SSI               (0xFC0A4016)
+#define MCFGPIO_PDDR_BUSCTL            (0xFC0A4017)
+#define MCFGPIO_PDDR_BE                        (0xFC0A4018)
+#define MCFGPIO_PDDR_CS                        (0xFC0A4019)
+#define MCFGPIO_PDDR_PWM               (0xFC0A401A)
+#define MCFGPIO_PDDR_FECI2C            (0xFC0A401B)
+#define MCFGPIO_PDDR_UART              (0xFC0A401C)
+#define MCFGPIO_PDDR_QSPI              (0xFC0A401E)
+#define MCFGPIO_PDDR_TIMER             (0xFC0A401F)
+#define MCFGPIO_PDDR_LCDDATAH          (0xFC0A4021)
+#define MCFGPIO_PDDR_LCDDATAM          (0xFC0A4022)
+#define MCFGPIO_PDDR_LCDDATAL          (0xFC0A4023)
+#define MCFGPIO_PDDR_LCDCTLH           (0xFC0A4024)
+#define MCFGPIO_PDDR_LCDCTLL           (0xFC0A4025)
+#define MCFGPIO_PPDSDR_FECH            (0xFC0A4028)
+#define MCFGPIO_PPDSDR_FECL            (0xFC0A4029)
+#define MCFGPIO_PPDSDR_SSI             (0xFC0A402A)
+#define MCFGPIO_PPDSDR_BUSCTL          (0xFC0A402B)
+#define MCFGPIO_PPDSDR_BE              (0xFC0A402C)
+#define MCFGPIO_PPDSDR_CS              (0xFC0A402D)
+#define MCFGPIO_PPDSDR_PWM             (0xFC0A402E)
+#define MCFGPIO_PPDSDR_FECI2C          (0xFC0A402F)
+#define MCFGPIO_PPDSDR_UART            (0xFC0A4031)
+#define MCFGPIO_PPDSDR_QSPI            (0xFC0A4032)
+#define MCFGPIO_PPDSDR_TIMER           (0xFC0A4033)
+#define MCFGPIO_PPDSDR_LCDDATAH                (0xFC0A4035)
+#define MCFGPIO_PPDSDR_LCDDATAM                (0xFC0A4036)
+#define MCFGPIO_PPDSDR_LCDDATAL                (0xFC0A4037)
+#define MCFGPIO_PPDSDR_LCDCTLH         (0xFC0A4038)
+#define MCFGPIO_PPDSDR_LCDCTLL         (0xFC0A4039)
+#define MCFGPIO_PCLRR_FECH             (0xFC0A403C)
+#define MCFGPIO_PCLRR_FECL             (0xFC0A403D)
+#define MCFGPIO_PCLRR_SSI              (0xFC0A403E)
+#define MCFGPIO_PCLRR_BUSCTL           (0xFC0A403F)
+#define MCFGPIO_PCLRR_BE               (0xFC0A4040)
+#define MCFGPIO_PCLRR_CS               (0xFC0A4041)
+#define MCFGPIO_PCLRR_PWM              (0xFC0A4042)
+#define MCFGPIO_PCLRR_FECI2C           (0xFC0A4043)
+#define MCFGPIO_PCLRR_UART             (0xFC0A4045)
+#define MCFGPIO_PCLRR_QSPI             (0xFC0A4046)
+#define MCFGPIO_PCLRR_TIMER            (0xFC0A4047)
+#define MCFGPIO_PCLRR_LCDDATAH         (0xFC0A4049)
+#define MCFGPIO_PCLRR_LCDDATAM         (0xFC0A404A)
+#define MCFGPIO_PCLRR_LCDDATAL         (0xFC0A404B)
+#define MCFGPIO_PCLRR_LCDCTLH          (0xFC0A404C)
+#define MCFGPIO_PCLRR_LCDCTLL          (0xFC0A404D)
 #define MCF_GPIO_PAR_FEC               MCF_REG08(0xFC0A4050)
 #define MCF_GPIO_PAR_PWM               MCF_REG08(0xFC0A4051)
 #define MCF_GPIO_PAR_BUSCTL            MCF_REG08(0xFC0A4052)
 /* Bit definitions and macros for MCF_GPIO_DSCR_IRQ */
 #define MCF_GPIO_DSCR_IRQ_IRQ_DSE(x)               (((x)&0x03)<<0)
 
+/*
+ * Generic GPIO support
+ */
+#define MCFGPIO_PODR                   MCFGPIO_PODR_FECH
+#define MCFGPIO_PDDR                   MCFGPIO_PDDR_FECH
+#define MCFGPIO_PPDR                   MCFGPIO_PPDSDR_FECH
+#define MCFGPIO_SETR                   MCFGPIO_PPDSDR_FECH
+#define MCFGPIO_CLRR                   MCFGPIO_PCLRR_FECH
+
+#define MCFGPIO_PIN_MAX                        136
+#define MCFGPIO_IRQ_MAX                        8
+#define MCFGPIO_IRQ_VECBASE            MCFINT_VECBASE
+
+
 /*********************************************************************
  *
  * Interrupt Controller (INTC)
  *********************************************************************/
 
 /* Register read/write macros */
-#define MCF_EPORT_EPPAR                MCF_REG16(0xFC094000)
-#define MCF_EPORT_EPDDR                MCF_REG08(0xFC094002)
-#define MCF_EPORT_EPIER                MCF_REG08(0xFC094003)
-#define MCF_EPORT_EPDR                 MCF_REG08(0xFC094004)
-#define MCF_EPORT_EPPDR                MCF_REG08(0xFC094005)
-#define MCF_EPORT_EPFR                 MCF_REG08(0xFC094006)
+#define MCFEPORT_EPPAR                (0xFC094000)
+#define MCFEPORT_EPDDR                (0xFC094002)
+#define MCFEPORT_EPIER                (0xFC094003)
+#define MCFEPORT_EPDR                 (0xFC094004)
+#define MCFEPORT_EPPDR                (0xFC094005)
+#define MCFEPORT_EPFR                 (0xFC094006)
 
 /* Bit definitions and macros for MCF_EPORT_EPPAR */
 #define MCF_EPORT_EPPAR_EPPA1(x)       (((x)&0x0003)<<2)
index cc22c4a53005cc9a9e714889fd2869f3919a84e9..c399abbf953ce57f1d771dabad967de88e7022f4 100644 (file)
 #define MCFSIM_DACR1           0x110           /* DRAM 1 Addr and Ctrl (r/w) */
 #define MCFSIM_DMR1            0x114           /* DRAM 1 Mask reg (r/w) */
 
-#define        MCFSIM_PADDR            0x244           /* Parallel Direction (r/w) */
-#define        MCFSIM_PADAT            0x248           /* Parallel Data (r/w) */
+#define        MCFSIM_PADDR            (MCF_MBAR + 0x244)
+#define        MCFSIM_PADAT            (MCF_MBAR + 0x248)
 
+/*
+ * Generic GPIO support
+ */
+#define MCFGPIO_PIN_MAX                        16
+#define MCFGPIO_IRQ_MAX                        -1
+#define MCFGPIO_IRQ_VECBASE            -1
 
 /*
  *     Some symbol defines for the above...
 #define        MCFSIM_DMA2ICR          MCFSIM_ICR8     /* DMA 2 ICR */
 #define        MCFSIM_DMA3ICR          MCFSIM_ICR9     /* DMA 3 ICR */
 
-/*
- *     Macro to set IMR register. It is 32 bits on the 5407.
- */
-#define        mcf_getimr()            \
-       *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR))
-
-#define        mcf_setimr(imr)         \
-       *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr);
-
-#define        mcf_getipr()            \
-       *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR))
-
-
 /*
  *     Some symbol defines for the Parallel Port Pin Assignment Register
  */
 #define IRQ3_LEVEL6    0x40
 #define IRQ1_LEVEL2    0x20
 
+/*
+ *     Define system peripheral IRQ usage.
+ */
+#define        MCF_IRQ_TIMER           30              /* Timer0, Level 6 */
+#define        MCF_IRQ_PROFILER        31              /* Timer1, Level 7 */
 
 /*
  *     Define the Cache register flags.
diff --git a/arch/m68k/include/asm/mcfgpio.h b/arch/m68k/include/asm/mcfgpio.h
new file mode 100644 (file)
index 0000000..ee5e4cc
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Coldfire generic GPIO support.
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef mcfgpio_h
+#define mcfgpio_h
+
+#include <linux/io.h>
+#include <asm-generic/gpio.h>
+
+struct mcf_gpio_chip {
+       struct gpio_chip gpio_chip;
+       void __iomem *pddr;
+       void __iomem *podr;
+       void __iomem *ppdr;
+       void __iomem *setr;
+       void __iomem *clrr;
+       const u8 *gpio_to_pinmux;
+};
+
+int mcf_gpio_direction_input(struct gpio_chip *, unsigned);
+int mcf_gpio_get_value(struct gpio_chip *, unsigned);
+int mcf_gpio_direction_output(struct gpio_chip *, unsigned, int);
+void mcf_gpio_set_value(struct gpio_chip *, unsigned, int);
+void mcf_gpio_set_value_fast(struct gpio_chip *, unsigned, int);
+int mcf_gpio_request(struct gpio_chip *, unsigned);
+void mcf_gpio_free(struct gpio_chip *, unsigned);
+
+#endif
diff --git a/arch/m68k/include/asm/mcfintc.h b/arch/m68k/include/asm/mcfintc.h
new file mode 100644 (file)
index 0000000..4183320
--- /dev/null
@@ -0,0 +1,89 @@
+/****************************************************************************/
+
+/*
+ *     mcfintc.h -- support definitions for the simple ColdFire
+ *                  Interrupt Controller
+ *
+ *     (C) Copyright 2009,  Greg Ungerer <gerg@uclinux.org>
+ */
+
+/****************************************************************************/
+#ifndef        mcfintc_h
+#define        mcfintc_h
+/****************************************************************************/
+
+/*
+ * Most of the older ColdFire parts use the same simple interrupt
+ * controller. This is currently used on the 5206, 5206e, 5249, 5307
+ * and 5407 parts.
+ *
+ * The builtin peripherals are masked through dedicated bits in the
+ * Interrupt Mask register (IMR) - and this is not indexed (or in any way
+ * related to) the actual interrupt number they use. So knowing the IRQ
+ * number doesn't explicitly map to a certain internal device for
+ * interrupt control purposes.
+ */
+
+/*
+ * Bit definitions for the ICR family of registers.
+ */
+#define        MCFSIM_ICR_AUTOVEC      0x80            /* Auto-vectored intr */
+#define        MCFSIM_ICR_LEVEL0       0x00            /* Level 0 intr */
+#define        MCFSIM_ICR_LEVEL1       0x04            /* Level 1 intr */
+#define        MCFSIM_ICR_LEVEL2       0x08            /* Level 2 intr */
+#define        MCFSIM_ICR_LEVEL3       0x0c            /* Level 3 intr */
+#define        MCFSIM_ICR_LEVEL4       0x10            /* Level 4 intr */
+#define        MCFSIM_ICR_LEVEL5       0x14            /* Level 5 intr */
+#define        MCFSIM_ICR_LEVEL6       0x18            /* Level 6 intr */
+#define        MCFSIM_ICR_LEVEL7       0x1c            /* Level 7 intr */
+
+#define        MCFSIM_ICR_PRI0         0x00            /* Priority 0 intr */
+#define        MCFSIM_ICR_PRI1         0x01            /* Priority 1 intr */
+#define        MCFSIM_ICR_PRI2         0x02            /* Priority 2 intr */
+#define        MCFSIM_ICR_PRI3         0x03            /* Priority 3 intr */
+
+/*
+ * IMR bit position definitions. Not all ColdFire parts with this interrupt
+ * controller actually support all of these interrupt sources. But the bit
+ * numbers are the same in all cores.
+ */
+#define        MCFINTC_EINT1           1               /* External int #1 */
+#define        MCFINTC_EINT2           2               /* External int #2 */
+#define        MCFINTC_EINT3           3               /* External int #3 */
+#define        MCFINTC_EINT4           4               /* External int #4 */
+#define        MCFINTC_EINT5           5               /* External int #5 */
+#define        MCFINTC_EINT6           6               /* External int #6 */
+#define        MCFINTC_EINT7           7               /* External int #7 */
+#define        MCFINTC_SWT             8               /* Software Watchdog */
+#define        MCFINTC_TIMER1          9
+#define        MCFINTC_TIMER2          10
+#define        MCFINTC_I2C             11              /* I2C / MBUS */
+#define        MCFINTC_UART0           12
+#define        MCFINTC_UART1           13
+#define        MCFINTC_DMA0            14
+#define        MCFINTC_DMA1            15
+#define        MCFINTC_DMA2            16
+#define        MCFINTC_DMA3            17
+#define        MCFINTC_QSPI            18
+
+#ifndef __ASSEMBLER__
+
+/*
+ * There is no one-is-one correspondance between the interrupt number (irq)
+ * and the bit fields on the mask register. So we create a per-cpu type
+ * mapping of irq to mask bit. The CPU platform code needs to register
+ * its supported irq's at init time, using this function.
+ */
+extern unsigned char mcf_irq2imr[];
+static inline void mcf_mapirq2imr(int irq, int imr)
+{
+       mcf_irq2imr[irq] = imr;
+}
+
+void mcf_autovector(int irq);
+void mcf_setimr(int index);
+void mcf_clrimr(int index);
+#endif
+
+/****************************************************************************/
+#endif /* mcfintc_h */
index 431f63aadd0ea3fbec75748cdce78c65326ffb89..bf638be0958c524add643e22b30f7c2194acac01 100644 (file)
@@ -238,88 +238,5 @@ void ne2000_outsw(unsigned int addr, const void *vbuf, unsigned long len)
 #endif /* COLDFIRE_NE2000_FUNCS */
 #endif /* NE2000_OFFOFFSET */
 
-/****************************************************************************/
-
-#ifdef COLDFIRE_NE2000_FUNCS
-
-/*
- *     Lastly the interrupt set up code...
- *     Minor differences between the different board types.
- */
-
-#if defined(CONFIG_ARN5206)
-void ne2000_irqsetup(int irq)
-{
-       volatile unsigned char  *icrp;
-
-       icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_ICR4);
-       *icrp = MCFSIM_ICR_LEVEL4 | MCFSIM_ICR_PRI2;
-       mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT4);
-}
-#endif
-
-#if defined(CONFIG_M5206eC3)
-void ne2000_irqsetup(int irq)
-{
-       volatile unsigned char  *icrp;
-
-       icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_ICR4);
-       *icrp = MCFSIM_ICR_LEVEL4 | MCFSIM_ICR_PRI2 | MCFSIM_ICR_AUTOVEC;
-       mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT4);
-}
-#endif
-
-#if defined(CONFIG_M5206e) && defined(CONFIG_NETtel)
-void ne2000_irqsetup(int irq)
-{
-       mcf_autovector(irq);
-}
-#endif
-
-#if defined(CONFIG_M5272) && defined(CONFIG_NETtel)
-void ne2000_irqsetup(int irq)
-{
-       volatile unsigned long  *icrp;
-       volatile unsigned long  *pitr;
-
-       /* The NE2000 device uses external IRQ3 */
-       icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
-       *icrp = (*icrp & 0x77077777) | 0x00d00000;
-
-       pitr = (volatile unsigned long *) (MCF_MBAR + MCFSIM_PITR);
-       *pitr = *pitr | 0x20000000;
-}
-
-void ne2000_irqack(int irq)
-{
-       volatile unsigned long  *icrp;
-
-       /* The NE2000 device uses external IRQ3 */
-       icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
-       *icrp = (*icrp & 0x77777777) | 0x00800000;
-}
-#endif
-
-#if defined(CONFIG_M5307) || defined(CONFIG_M5407)
-#if defined(CONFIG_NETtel) || defined(CONFIG_SECUREEDGEMP3)
-
-void ne2000_irqsetup(int irq)
-{
-       mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT3);
-       mcf_autovector(irq);
-}
-
-#else
-
-void ne2000_irqsetup(int irq)
-{
-       mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT3);
-}
-
-#endif /* ! CONFIG_NETtel || CONFIG_SECUREEDGEMP3 */
-#endif /* CONFIG_M5307 || CONFIG_M5407 */
-
-#endif /* COLDFIRE_NE2000_FUNCS */
-
 /****************************************************************************/
 #endif /* mcfne_h */
index da3f2ceff3a4bd1b5abf5bfd0568d4cad91022b5..9c70a67bf85f7c90f12be85c9aaef73ac55dec17 100644 (file)
@@ -4,7 +4,7 @@
  *     mcfsim.h -- ColdFire System Integration Module support.
  *
  *     (C) Copyright 1999-2003, Greg Ungerer (gerg@snapgear.com)
- *     (C) Copyright 2000, Lineo Inc. (www.lineo.com) 
+ *     (C) Copyright 2000, Lineo Inc. (www.lineo.com)
  */
 
 /****************************************************************************/
 #define        mcfsim_h
 /****************************************************************************/
 
-
 /*
- *     Include 5204, 5206/e, 5235, 5249, 5270/5271, 5272, 5280/5282,
- *     5307 or 5407 specific addresses.
+ * Include the appropriate ColdFire CPU specific System Integration Module
+ * (SIM) definitions.
  */
 #if defined(CONFIG_M5206) || defined(CONFIG_M5206e)
 #include <asm/m5206sim.h>
+#include <asm/mcfintc.h>
 #elif defined(CONFIG_M520x)
 #include <asm/m520xsim.h>
 #elif defined(CONFIG_M523x)
 #include <asm/m523xsim.h>
+#include <asm/mcfintc.h>
 #elif defined(CONFIG_M5249)
 #include <asm/m5249sim.h>
+#include <asm/mcfintc.h>
 #elif defined(CONFIG_M527x)
 #include <asm/m527xsim.h>
 #elif defined(CONFIG_M5272)
 #include <asm/m528xsim.h>
 #elif defined(CONFIG_M5307)
 #include <asm/m5307sim.h>
+#include <asm/mcfintc.h>
 #elif defined(CONFIG_M532x)
 #include <asm/m532xsim.h>
 #elif defined(CONFIG_M5407)
 #include <asm/m5407sim.h>
+#include <asm/mcfintc.h>
 #endif
 
-
-/*
- *     Define the base address of the SIM within the MBAR address space.
- */
-#define        MCFSIM_BASE             0x0             /* Base address of SIM */
-
-
-/*
- *     Bit definitions for the ICR family of registers.
- */
-#define        MCFSIM_ICR_AUTOVEC      0x80            /* Auto-vectored intr */
-#define        MCFSIM_ICR_LEVEL0       0x00            /* Level 0 intr */
-#define        MCFSIM_ICR_LEVEL1       0x04            /* Level 1 intr */
-#define        MCFSIM_ICR_LEVEL2       0x08            /* Level 2 intr */
-#define        MCFSIM_ICR_LEVEL3       0x0c            /* Level 3 intr */
-#define        MCFSIM_ICR_LEVEL4       0x10            /* Level 4 intr */
-#define        MCFSIM_ICR_LEVEL5       0x14            /* Level 5 intr */
-#define        MCFSIM_ICR_LEVEL6       0x18            /* Level 6 intr */
-#define        MCFSIM_ICR_LEVEL7       0x1c            /* Level 7 intr */
-
-#define        MCFSIM_ICR_PRI0         0x00            /* Priority 0 intr */
-#define        MCFSIM_ICR_PRI1         0x01            /* Priority 1 intr */
-#define        MCFSIM_ICR_PRI2         0x02            /* Priority 2 intr */
-#define        MCFSIM_ICR_PRI3         0x03            /* Priority 3 intr */
-
-/*
- *     Bit definitions for the Interrupt Mask register (IMR).
- */
-#define        MCFSIM_IMR_EINT1        0x0002          /* External intr # 1 */
-#define        MCFSIM_IMR_EINT2        0x0004          /* External intr # 2 */
-#define        MCFSIM_IMR_EINT3        0x0008          /* External intr # 3 */
-#define        MCFSIM_IMR_EINT4        0x0010          /* External intr # 4 */
-#define        MCFSIM_IMR_EINT5        0x0020          /* External intr # 5 */
-#define        MCFSIM_IMR_EINT6        0x0040          /* External intr # 6 */
-#define        MCFSIM_IMR_EINT7        0x0080          /* External intr # 7 */
-
-#define        MCFSIM_IMR_SWD          0x0100          /* Software Watchdog intr */
-#define        MCFSIM_IMR_TIMER1       0x0200          /* TIMER 1 intr */
-#define        MCFSIM_IMR_TIMER2       0x0400          /* TIMER 2 intr */
-#define MCFSIM_IMR_MBUS                0x0800          /* MBUS intr    */
-#define        MCFSIM_IMR_UART1        0x1000          /* UART 1 intr */
-#define        MCFSIM_IMR_UART2        0x2000          /* UART 2 intr */
-
-#if defined(CONFIG_M5206e)
-#define        MCFSIM_IMR_DMA1         0x4000          /* DMA 1 intr */
-#define        MCFSIM_IMR_DMA2         0x8000          /* DMA 2 intr */
-#elif defined(CONFIG_M5249) || defined(CONFIG_M5307)
-#define        MCFSIM_IMR_DMA0         0x4000          /* DMA 0 intr */
-#define        MCFSIM_IMR_DMA1         0x8000          /* DMA 1 intr */
-#define        MCFSIM_IMR_DMA2         0x10000         /* DMA 2 intr */
-#define        MCFSIM_IMR_DMA3         0x20000         /* DMA 3 intr */
-#endif
-
-/*
- *     Mask for all of the SIM devices. Some parts have more or less
- *     SIM devices. This is a catchall for the sandard set.
- */
-#ifndef MCFSIM_IMR_MASKALL
-#define        MCFSIM_IMR_MASKALL      0x3ffe          /* All intr sources */
-#endif
-
-
-/*
- *     PIT interrupt settings, if not found in mXXXXsim.h file.
- */
-#ifndef        ICR_INTRCONF
-#define        ICR_INTRCONF            0x2b            /* PIT1 level 5, priority 3 */
-#endif
-#ifndef        MCFPIT_IMR
-#define        MCFPIT_IMR              MCFINTC_IMRH
-#endif
-#ifndef        MCFPIT_IMR_IBIT
-#define        MCFPIT_IMR_IBIT         (1 << (MCFINT_PIT1 - 32))
-#endif
-
-
-#ifndef __ASSEMBLY__
-/*
- *     Definition for the interrupt auto-vectoring support.
- */
-extern void    mcf_autovector(unsigned int vec);
-#endif /* __ASSEMBLY__ */
-
 /****************************************************************************/
 #endif /* mcfsim_h */
index 2d7a4dbd96832a735f2a1300c67aab7181826782..527bea5d678827a93d68068a5b1b1c378b71b73b 100644 (file)
@@ -167,15 +167,15 @@ void smc_remap(unsigned int ioaddr)
        static int              once = 0;
        extern unsigned short   ppdata;
        if (once++ == 0) {
-               *((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADDR)) = 0x00ec;
+               *((volatile unsigned short *)MCFSIM_PADDR) = 0x00ec;
                ppdata |= 0x0080;
-               *((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADAT)) = ppdata;
+               *((volatile unsigned short *)MCFSIM_PADAT) = ppdata;
                outw(0x0001, ioaddr + BANK_SELECT);
                outw(0x0001, ioaddr + BANK_SELECT);
                outw(0x0067, ioaddr + BASE);
 
                ppdata &= ~0x0080;
-               *((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADAT)) = ppdata;
+               *((volatile unsigned short *)MCFSIM_PADAT) = ppdata;
        }
        
        *((volatile unsigned short *)(MCF_MBAR+MCFSIM_CSCR3)) = 0x1180;
index 0299f6a2deeb62f548129f269a150218570b8789..4dec2d9fb99442e3752a21f6da4f9b25255f9024 100644 (file)
@@ -48,14 +48,14 @@ extern volatile unsigned short ppdata;
 static __inline__ unsigned int mcf_getppdata(void)
 {
        volatile unsigned short *pp;
-       pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
+       pp = (volatile unsigned short *) MCFSIM_PADAT;
        return((unsigned int) *pp);
 }
 
 static __inline__ void mcf_setppdata(unsigned int mask, unsigned int bits)
 {
        volatile unsigned short *pp;
-       pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
+       pp = (volatile unsigned short *) MCFSIM_PADAT;
        ppdata = (ppdata & ~mask) | bits;
        *pp = ppdata;
 }
index 9aa3f90f4855b85ade95e2977cf9422e397d32f6..1f31b060cc8da823b2fe065cfa2f0bf783447417 100644 (file)
@@ -1,10 +1,12 @@
 #ifndef _M68KNOMMU_PAGE_H
 #define _M68KNOMMU_PAGE_H
 
+#include <linux/const.h>
+
 /* PAGE_SHIFT determines the page size */
 
 #define PAGE_SHIFT     (12)
-#define PAGE_SIZE      (1UL << PAGE_SHIFT)
+#define PAGE_SIZE      (_AC(1,UL) << PAGE_SHIFT)
 #define PAGE_MASK      (~(PAGE_SIZE-1))
 
 #include <asm/setup.h>
diff --git a/arch/m68k/include/asm/pinmux.h b/arch/m68k/include/asm/pinmux.h
new file mode 100644 (file)
index 0000000..119ee68
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Coldfire generic GPIO pinmux support.
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef pinmux_h
+#define pinmux_h
+
+#define MCFPINMUX_NONE         -1
+
+extern int mcf_pinmux_request(unsigned, unsigned);
+extern void mcf_pinmux_release(unsigned, unsigned);
+
+static inline int mcf_pinmux_is_valid(unsigned pinmux)
+{
+       return pinmux != MCFPINMUX_NONE;
+}
+
+#endif
+
index fc3f2c22f2b89dfc4419c509304b6e699b04db01..74fd674b15ad9f88f712632789098e233f1a0f0f 100644 (file)
@@ -1,5 +1,170 @@
-#ifdef __uClinux__
-#include "processor_no.h"
+/*
+ * include/asm-m68k/processor.h
+ *
+ * Copyright (C) 1995 Hamish Macdonald
+ */
+
+#ifndef __ASM_M68K_PROCESSOR_H
+#define __ASM_M68K_PROCESSOR_H
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l;})
+
+#include <linux/thread_info.h>
+#include <asm/segment.h>
+#include <asm/fpu.h>
+#include <asm/ptrace.h>
+
+static inline unsigned long rdusp(void)
+{
+#ifdef CONFIG_COLDFIRE
+       extern unsigned int sw_usp;
+       return sw_usp;
 #else
-#include "processor_mm.h"
+       unsigned long usp;
+       __asm__ __volatile__("move %/usp,%0" : "=a" (usp));
+       return usp;
+#endif
+}
+
+static inline void wrusp(unsigned long usp)
+{
+#ifdef CONFIG_COLDFIRE
+       extern unsigned int sw_usp;
+       sw_usp = usp;
+#else
+       __asm__ __volatile__("move %0,%/usp" : : "a" (usp));
+#endif
+}
+
+/*
+ * User space process size: 3.75GB. This is hardcoded into a few places,
+ * so don't change it unless you know what you are doing.
+ */
+#ifndef CONFIG_SUN3
+#define TASK_SIZE      (0xF0000000UL)
+#else
+#define TASK_SIZE      (0x0E000000UL)
+#endif
+
+#ifdef __KERNEL__
+#define STACK_TOP      TASK_SIZE
+#define STACK_TOP_MAX  STACK_TOP
+#endif
+
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#ifdef CONFIG_MMU
+#ifndef CONFIG_SUN3
+#define TASK_UNMAPPED_BASE     0xC0000000UL
+#else
+#define TASK_UNMAPPED_BASE     0x0A000000UL
+#endif
+#define TASK_UNMAPPED_ALIGN(addr, off) PAGE_ALIGN(addr)
+#else
+#define TASK_UNMAPPED_BASE     0
+#endif
+
+struct thread_struct {
+       unsigned long  ksp;             /* kernel stack pointer */
+       unsigned long  usp;             /* user stack pointer */
+       unsigned short sr;              /* saved status register */
+       unsigned short fs;              /* saved fs (sfc, dfc) */
+       unsigned long  crp[2];          /* cpu root pointer */
+       unsigned long  esp0;            /* points to SR of stack frame */
+       unsigned long  faddr;           /* info about last fault */
+       int            signo, code;
+       unsigned long  fp[8*3];
+       unsigned long  fpcntl[3];       /* fp control regs */
+       unsigned char  fpstate[FPSTATESIZE];  /* floating point state */
+       struct thread_info info;
+};
+
+#define INIT_THREAD  {                                                 \
+       .ksp    = sizeof(init_stack) + (unsigned long) init_stack,      \
+       .sr     = PS_S,                                                 \
+       .fs     = __KERNEL_DS,                                          \
+       .info   = INIT_THREAD_INFO(init_task),                          \
+}
+
+#ifdef CONFIG_MMU
+/*
+ * Do necessary setup to start up a newly executed thread.
+ */
+static inline void start_thread(struct pt_regs * regs, unsigned long pc,
+                               unsigned long usp)
+{
+       /* reads from user space */
+       set_fs(USER_DS);
+
+       regs->pc = pc;
+       regs->sr &= ~0x2000;
+       wrusp(usp);
+}
+
+#else
+
+/*
+ * Coldfire stacks need to be re-aligned on trap exit, conventional
+ * 68k can handle this case cleanly.
+ */
+#ifdef CONFIG_COLDFIRE
+#define reformat(_regs)                do { (_regs)->format = 0x4; } while(0)
+#else
+#define reformat(_regs)                do { } while (0)
+#endif
+
+#define start_thread(_regs, _pc, _usp)                  \
+do {                                                    \
+       set_fs(USER_DS); /* reads from user space */    \
+       (_regs)->pc = (_pc);                            \
+       ((struct switch_stack *)(_regs))[-1].a6 = 0;    \
+       reformat(_regs);                                \
+       if (current->mm)                                \
+               (_regs)->d5 = current->mm->start_data;  \
+       (_regs)->sr &= ~0x2000;                         \
+       wrusp(_usp);                                    \
+} while(0)
+
+#endif
+
+/* Forward declaration, a strange C thing */
+struct task_struct;
+
+/* Free all resources held by a thread. */
+static inline void release_thread(struct task_struct *dead_task)
+{
+}
+
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk)   do { } while (0)
+
+extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+
+/*
+ * Free current thread data structures etc..
+ */
+static inline void exit_thread(void)
+{
+}
+
+extern unsigned long thread_saved_pc(struct task_struct *tsk);
+
+unsigned long get_wchan(struct task_struct *p);
+
+#define        KSTK_EIP(tsk)   \
+    ({                 \
+       unsigned long eip = 0;   \
+       if ((tsk)->thread.esp0 > PAGE_SIZE && \
+           (virt_addr_valid((tsk)->thread.esp0))) \
+             eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \
+       eip; })
+#define        KSTK_ESP(tsk)   ((tsk) == current ? rdusp() : (tsk)->thread.usp)
+
+#define cpu_relax()    barrier()
+
 #endif
diff --git a/arch/m68k/include/asm/processor_mm.h b/arch/m68k/include/asm/processor_mm.h
deleted file mode 100644 (file)
index 1f61ef5..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * include/asm-m68k/processor.h
- *
- * Copyright (C) 1995 Hamish Macdonald
- */
-
-#ifndef __ASM_M68K_PROCESSOR_H
-#define __ASM_M68K_PROCESSOR_H
-
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#define current_text_addr() ({ __label__ _l; _l: &&_l;})
-
-#include <linux/thread_info.h>
-#include <asm/segment.h>
-#include <asm/fpu.h>
-#include <asm/ptrace.h>
-
-static inline unsigned long rdusp(void)
-{
-       unsigned long usp;
-
-       __asm__ __volatile__("move %/usp,%0" : "=a" (usp));
-       return usp;
-}
-
-static inline void wrusp(unsigned long usp)
-{
-       __asm__ __volatile__("move %0,%/usp" : : "a" (usp));
-}
-
-/*
- * User space process size: 3.75GB. This is hardcoded into a few places,
- * so don't change it unless you know what you are doing.
- */
-#ifndef CONFIG_SUN3
-#define TASK_SIZE      (0xF0000000UL)
-#else
-#define TASK_SIZE      (0x0E000000UL)
-#endif
-
-#ifdef __KERNEL__
-#define STACK_TOP      TASK_SIZE
-#define STACK_TOP_MAX  STACK_TOP
-#endif
-
-/* This decides where the kernel will search for a free chunk of vm
- * space during mmap's.
- */
-#ifndef CONFIG_SUN3
-#define TASK_UNMAPPED_BASE     0xC0000000UL
-#else
-#define TASK_UNMAPPED_BASE     0x0A000000UL
-#endif
-#define TASK_UNMAPPED_ALIGN(addr, off) PAGE_ALIGN(addr)
-
-struct thread_struct {
-       unsigned long  ksp;             /* kernel stack pointer */
-       unsigned long  usp;             /* user stack pointer */
-       unsigned short sr;              /* saved status register */
-       unsigned short fs;              /* saved fs (sfc, dfc) */
-       unsigned long  crp[2];          /* cpu root pointer */
-       unsigned long  esp0;            /* points to SR of stack frame */
-       unsigned long  faddr;           /* info about last fault */
-       int            signo, code;
-       unsigned long  fp[8*3];
-       unsigned long  fpcntl[3];       /* fp control regs */
-       unsigned char  fpstate[FPSTATESIZE];  /* floating point state */
-       struct thread_info info;
-};
-
-#define INIT_THREAD  {                                                 \
-       .ksp    = sizeof(init_stack) + (unsigned long) init_stack,      \
-       .sr     = PS_S,                                                 \
-       .fs     = __KERNEL_DS,                                          \
-       .info   = INIT_THREAD_INFO(init_task),                          \
-}
-
-/*
- * Do necessary setup to start up a newly executed thread.
- */
-static inline void start_thread(struct pt_regs * regs, unsigned long pc,
-                               unsigned long usp)
-{
-       /* reads from user space */
-       set_fs(USER_DS);
-
-       regs->pc = pc;
-       regs->sr &= ~0x2000;
-       wrusp(usp);
-}
-
-/* Forward declaration, a strange C thing */
-struct task_struct;
-
-/* Free all resources held by a thread. */
-static inline void release_thread(struct task_struct *dead_task)
-{
-}
-
-/* Prepare to copy thread state - unlazy all lazy status */
-#define prepare_to_copy(tsk)   do { } while (0)
-
-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
-/*
- * Free current thread data structures etc..
- */
-static inline void exit_thread(void)
-{
-}
-
-extern unsigned long thread_saved_pc(struct task_struct *tsk);
-
-unsigned long get_wchan(struct task_struct *p);
-
-#define        KSTK_EIP(tsk)   \
-    ({                 \
-       unsigned long eip = 0;   \
-       if ((tsk)->thread.esp0 > PAGE_SIZE && \
-           (virt_addr_valid((tsk)->thread.esp0))) \
-             eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \
-       eip; })
-#define        KSTK_ESP(tsk)   ((tsk) == current ? rdusp() : (tsk)->thread.usp)
-
-#define cpu_relax()    barrier()
-
-#endif
diff --git a/arch/m68k/include/asm/processor_no.h b/arch/m68k/include/asm/processor_no.h
deleted file mode 100644 (file)
index 7a1e0ba..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * include/asm-m68knommu/processor.h
- *
- * Copyright (C) 1995 Hamish Macdonald
- */
-
-#ifndef __ASM_M68K_PROCESSOR_H
-#define __ASM_M68K_PROCESSOR_H
-
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#define current_text_addr() ({ __label__ _l; _l: &&_l;})
-
-#include <linux/compiler.h>
-#include <linux/threads.h>
-#include <asm/types.h>
-#include <asm/segment.h>
-#include <asm/fpu.h>
-#include <asm/ptrace.h>
-#include <asm/current.h>
-
-static inline unsigned long rdusp(void)
-{
-#ifdef CONFIG_COLDFIRE
-       extern unsigned int sw_usp;
-       return(sw_usp);
-#else
-       unsigned long usp;
-       __asm__ __volatile__("move %/usp,%0" : "=a" (usp));
-       return usp;
-#endif
-}
-
-static inline void wrusp(unsigned long usp)
-{
-#ifdef CONFIG_COLDFIRE
-       extern unsigned int sw_usp;
-       sw_usp = usp;
-#else
-       __asm__ __volatile__("move %0,%/usp" : : "a" (usp));
-#endif
-}
-
-/*
- * User space process size: 3.75GB. This is hardcoded into a few places,
- * so don't change it unless you know what you are doing.
- */
-#define TASK_SIZE      (0xF0000000UL)
-
-/*
- * This decides where the kernel will search for a free chunk of vm
- * space during mmap's. We won't be using it
- */
-#define TASK_UNMAPPED_BASE     0
-
-/* 
- * if you change this structure, you must change the code and offsets
- * in m68k/machasm.S
- */
-   
-struct thread_struct {
-       unsigned long  ksp;             /* kernel stack pointer */
-       unsigned long  usp;             /* user stack pointer */
-       unsigned short sr;              /* saved status register */
-       unsigned short fs;              /* saved fs (sfc, dfc) */
-       unsigned long  crp[2];          /* cpu root pointer */
-       unsigned long  esp0;            /* points to SR of stack frame */
-       unsigned long  fp[8*3];
-       unsigned long  fpcntl[3];       /* fp control regs */
-       unsigned char  fpstate[FPSTATESIZE];  /* floating point state */
-};
-
-#define INIT_THREAD  {                                                 \
-       .ksp    = sizeof(init_stack) + (unsigned long) init_stack,      \
-       .sr     = PS_S,                                                 \
-       .fs     = __KERNEL_DS,                                          \
-}
-
-/*
- * Coldfire stacks need to be re-aligned on trap exit, conventional
- * 68k can handle this case cleanly.
- */
-#if defined(CONFIG_COLDFIRE)
-#define        reformat(_regs)         do { (_regs)->format = 0x4; } while(0)
-#else
-#define        reformat(_regs)         do { } while (0)
-#endif
-
-/*
- * Do necessary setup to start up a newly executed thread.
- *
- * pass the data segment into user programs if it exists,
- * it can't hurt anything as far as I can tell
- */
-#define start_thread(_regs, _pc, _usp)                 \
-do {                                                   \
-       set_fs(USER_DS); /* reads from user space */    \
-       (_regs)->pc = (_pc);                            \
-       ((struct switch_stack *)(_regs))[-1].a6 = 0;    \
-       reformat(_regs);                                \
-       if (current->mm)                                \
-               (_regs)->d5 = current->mm->start_data;  \
-       (_regs)->sr &= ~0x2000;                         \
-       wrusp(_usp);                                    \
-} while(0)
-
-/* Forward declaration, a strange C thing */
-struct task_struct;
-
-/* Free all resources held by a thread. */
-static inline void release_thread(struct task_struct *dead_task)
-{
-}
-
-/* Prepare to copy thread state - unlazy all lazy status */
-#define prepare_to_copy(tsk)   do { } while (0)
-
-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
-/*
- * Free current thread data structures etc..
- */
-static inline void exit_thread(void)
-{
-}
-
-unsigned long thread_saved_pc(struct task_struct *tsk);
-unsigned long get_wchan(struct task_struct *p);
-
-#define        KSTK_EIP(tsk)   \
-    ({                 \
-       unsigned long eip = 0;   \
-       if ((tsk)->thread.esp0 > PAGE_SIZE && \
-           (virt_addr_valid((tsk)->thread.esp0))) \
-             eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \
-       eip; })
-#define        KSTK_ESP(tsk)   ((tsk) == current ? rdusp() : (tsk)->thread.usp)
-
-#define cpu_relax()    barrier()
-
-#endif
index b87f2f278f673feda6270d9bf36ce70fe6c126e1..6759dad954f61d9a3d40800f63cf95179c8129aa 100644 (file)
@@ -3,10 +3,23 @@
  *
  * m68k architecture timex specifications
  */
-#ifndef _ASMm68k_TIMEX_H
-#define _ASMm68k_TIMEX_H
+#ifndef _ASMm68K_TIMEX_H
+#define _ASMm68K_TIMEX_H
 
+#ifdef CONFIG_COLDFIRE
+/*
+ * CLOCK_TICK_RATE should give the underlying frequency of the tick timer
+ * to make ntp work best.  For Coldfires, that's the main clock.
+ */
+#include <asm/coldfire.h>
+#define CLOCK_TICK_RATE        MCF_CLK
+#else
+/*
+ * This default CLOCK_TICK_RATE is probably wrong for many 68k boards
+ * Users of those boards will need to check and modify accordingly
+ */
 #define CLOCK_TICK_RATE        1193180 /* Underlying HZ */
+#endif
 
 typedef unsigned long cycles_t;
 
index 534376299a99e2b47ebde39e17e619e723bf7461..e2201b90aa22a2dbbf136e65bb6821f65f934bb7 100644 (file)
@@ -47,6 +47,10 @@ config GENERIC_FIND_NEXT_BIT
        bool
        default y
 
+config GENERIC_GPIO
+       bool
+       default n
+
 config GENERIC_HWEIGHT
        bool
        default y
@@ -182,6 +186,8 @@ config M527x
 config COLDFIRE
        bool
        depends on (M5206 || M5206e || M520x || M523x || M5249 || M527x || M5272 || M528x || M5307 || M532x || M5407)
+       select GENERIC_GPIO
+       select ARCH_REQUIRE_GPIOLIB
        default y
 
 config CLOCK_SET
index 56e0f4c55a67bb32b9d9bdf4b147519de774f68d..c9cac36d44223fa48a5220d2eb920d557cef74e4 100644 (file)
@@ -29,32 +29,6 @@ asmlinkage void do_IRQ(int irq, struct pt_regs *regs)
        set_irq_regs(oldregs);
 }
 
-void ack_bad_irq(unsigned int irq)
-{
-       printk(KERN_ERR "IRQ: unexpected irq=%d\n", irq);
-}
-
-static struct irq_chip m_irq_chip = {
-       .name           = "M68K-INTC",
-       .enable         = enable_vector,
-       .disable        = disable_vector,
-       .ack            = ack_vector,
-};
-
-void __init init_IRQ(void)
-{
-       int irq;
-
-       init_vectors();
-
-       for (irq = 0; (irq < NR_IRQS); irq++) {
-               irq_desc[irq].status = IRQ_DISABLED;
-               irq_desc[irq].action = NULL;
-               irq_desc[irq].depth = 1;
-               irq_desc[irq].chip = &m_irq_chip;
-       }
-}
-
 int show_interrupts(struct seq_file *p, void *v)
 {
        struct irqaction *ap;
index d182b2f722110d098d5e380179b0618298e4b3b4..a90acf5b0cde1812263625843dc348c6ce717f86 100644 (file)
@@ -69,12 +69,13 @@ static unsigned long read_rtc_mmss(void)
        if ((year += 1900) < 1970)
                year += 100;
 
-       return  mktime(year, mon, day, hour, min, sec);;
+       return  mktime(year, mon, day, hour, min, sec);
 }
 
-unsigned long read_persistent_clock(void)
+void read_persistent_clock(struct timespec *ts)
 {
-       return read_rtc_mmss();
+       ts->tv_sec = read_rtc_mmss();
+       ts->tv_nsec = 0;
 }
 
 int update_persistent_clock(struct timespec now)
index 269d83bfbbe11d656ade7ab83db532869fd18ba0..eccf25d3d73ec3c5c1e84f3a7d9f9383eab157f5 100644 (file)
@@ -92,6 +92,7 @@ out:
        return result;
 }
 
+#ifdef CONFIG_COLDFIRE
 /*
  *     This is a version of ip_compute_csum() optimized for IP headers,
  *     which always checksum on 4 octet boundaries.
@@ -100,6 +101,7 @@ __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
 {
        return (__force __sum16)~do_csum(iph,ihl*4);
 }
+#endif
 
 /*
  * computes the checksum of a memory block at buff, length len,
@@ -126,15 +128,6 @@ __wsum csum_partial(const void *buff, int len, __wsum sum)
 
 EXPORT_SYMBOL(csum_partial);
 
-/*
- * this routine is used for miscellaneous IP-like checksums, mainly
- * in icmp.c
- */
-__sum16 ip_compute_csum(const void *buff, int len)
-{
-       return (__force __sum16)~do_csum(buff,len);
-}
-
 /*
  * copy from fs while checksumming, otherwise like csum_partial
  */
index a439d9ab3f272dc4326db108fb548def198d22b9..113c333900648dcc9edfaa974a63084e07844816 100644 (file)
@@ -14,5 +14,5 @@
 
 asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
-obj-y := config.o
+obj-y := config.o gpio.o
 
index f6f79874e9af7a33da56676167b403d85844434e..9c335465e66de1a0e9a4d4e59ae53c4369810d05 100644 (file)
@@ -49,11 +49,11 @@ static void __init m5206_uart_init_line(int line, int irq)
        if (line == 0) {
                writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
                writeb(irq, MCFUART_BASE1 + MCFUART_UIVR);
-               mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
+               mcf_mapirq2imr(irq, MCFINTC_UART0);
        } else if (line == 1) {
                writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
                writeb(irq, MCFUART_BASE2 + MCFUART_UIVR);
-               mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
+               mcf_mapirq2imr(irq, MCFINTC_UART1);
        }
 }
 
@@ -68,38 +68,19 @@ static void __init m5206_uarts_init(void)
 
 /***************************************************************************/
 
-void mcf_autovector(unsigned int vec)
+static void __init m5206_timers_init(void)
 {
-       volatile unsigned char  *mbar;
-       unsigned char           icr;
-
-       if ((vec >= 25) && (vec <= 31)) {
-               vec -= 25;
-               mbar = (volatile unsigned char *) MCF_MBAR;
-               icr = MCFSIM_ICR_AUTOVEC | (vec << 3);
-               *(mbar + MCFSIM_ICR1 + vec) = icr;
-               vec = 0x1 << (vec + 1);
-               mcf_setimr(mcf_getimr() & ~vec);
-       }
-}
-
-/***************************************************************************/
-
-void mcf_settimericr(unsigned int timer, unsigned int level)
-{
-       volatile unsigned char *icrp;
-       unsigned int icr, imr;
-
-       if (timer <= 2) {
-               switch (timer) {
-               case 2:  icr = MCFSIM_TIMER2ICR; imr = MCFSIM_IMR_TIMER2; break;
-               default: icr = MCFSIM_TIMER1ICR; imr = MCFSIM_IMR_TIMER1; break;
-               }
-
-               icrp = (volatile unsigned char *) (MCF_MBAR + icr);
-               *icrp = MCFSIM_ICR_AUTOVEC | (level << 2) | MCFSIM_ICR_PRI3;
-               mcf_setimr(mcf_getimr() & ~imr);
-       }
+       /* Timer1 is always used as system timer */
+       writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3,
+               MCF_MBAR + MCFSIM_TIMER1ICR);
+       mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1);
+
+#ifdef CONFIG_HIGHPROFILE
+       /* Timer2 is to be used as a high speed profile timer  */
+       writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3,
+               MCF_MBAR + MCFSIM_TIMER2ICR);
+       mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2);
+#endif
 }
 
 /***************************************************************************/
@@ -117,15 +98,20 @@ void m5206_cpu_reset(void)
 
 void __init config_BSP(char *commandp, int size)
 {
-       mcf_setimr(MCFSIM_IMR_MASKALL);
        mach_reset = m5206_cpu_reset;
+       m5206_timers_init();
+       m5206_uarts_init();
+
+       /* Only support the external interrupts on their primary level */
+       mcf_mapirq2imr(25, MCFINTC_EINT1);
+       mcf_mapirq2imr(28, MCFINTC_EINT4);
+       mcf_mapirq2imr(31, MCFINTC_EINT7);
 }
 
 /***************************************************************************/
 
 static int __init init_BSP(void)
 {
-       m5206_uarts_init();
        platform_add_devices(m5206_devices, ARRAY_SIZE(m5206_devices));
        return 0;
 }
diff --git a/arch/m68knommu/platform/5206/gpio.c b/arch/m68knommu/platform/5206/gpio.c
new file mode 100644 (file)
index 0000000..60f779c
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Coldfire generic GPIO support
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/init.h>
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfgpio.h>
+
+static struct mcf_gpio_chip mcf_gpio_chips[] = {
+       {
+               .gpio_chip                      = {
+                       .label                  = "PP",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFSIM_PADDR,
+               .podr                           = MCFSIM_PADAT,
+               .ppdr                           = MCFSIM_PADAT,
+       },
+};
+
+static int __init mcf_gpio_init(void)
+{
+       unsigned i = 0;
+       while (i < ARRAY_SIZE(mcf_gpio_chips))
+               (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
+       return 0;
+}
+
+core_initcall(mcf_gpio_init);
index a439d9ab3f272dc4326db108fb548def198d22b9..113c333900648dcc9edfaa974a63084e07844816 100644 (file)
@@ -14,5 +14,5 @@
 
 asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
-obj-y := config.o
+obj-y := config.o gpio.o
 
index 65887799db81271c044f043a05a2d2cbc619666f..0f41ba82a3b533d1ff6a3815f59916c6d3e5f77e 100644 (file)
@@ -15,6 +15,7 @@
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
+#include <asm/mcfuart.h>
 #include <asm/mcfdma.h>
 #include <asm/mcfuart.h>
 
@@ -49,11 +50,11 @@ static void __init m5206e_uart_init_line(int line, int irq)
        if (line == 0) {
                writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
                writeb(irq, MCFUART_BASE1 + MCFUART_UIVR);
-               mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
+               mcf_mapirq2imr(irq, MCFINTC_UART0);
        } else if (line == 1) {
                writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
                writeb(irq, MCFUART_BASE2 + MCFUART_UIVR);
-               mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
+               mcf_mapirq2imr(irq, MCFINTC_UART1);
        }
 }
 
@@ -68,38 +69,19 @@ static void __init m5206e_uarts_init(void)
 
 /***************************************************************************/
 
-void mcf_autovector(unsigned int vec)
-{
-       volatile unsigned char  *mbar;
-       unsigned char           icr;
-
-       if ((vec >= 25) && (vec <= 31)) {
-               vec -= 25;
-               mbar = (volatile unsigned char *) MCF_MBAR;
-               icr = MCFSIM_ICR_AUTOVEC | (vec << 3);
-               *(mbar + MCFSIM_ICR1 + vec) = icr;
-               vec = 0x1 << (vec + 1);
-               mcf_setimr(mcf_getimr() & ~vec);
-       }
-}
-
-/***************************************************************************/
-
-void mcf_settimericr(unsigned int timer, unsigned int level)
+static void __init m5206e_timers_init(void)
 {
-       volatile unsigned char *icrp;
-       unsigned int icr, imr;
-
-       if (timer <= 2) {
-               switch (timer) {
-               case 2:  icr = MCFSIM_TIMER2ICR; imr = MCFSIM_IMR_TIMER2; break;
-               default: icr = MCFSIM_TIMER1ICR; imr = MCFSIM_IMR_TIMER1; break;
-               }
-
-               icrp = (volatile unsigned char *) (MCF_MBAR + icr);
-               *icrp = MCFSIM_ICR_AUTOVEC | (level << 2) | MCFSIM_ICR_PRI3;
-               mcf_setimr(mcf_getimr() & ~imr);
-       }
+       /* Timer1 is always used as system timer */
+       writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3,
+               MCF_MBAR + MCFSIM_TIMER1ICR);
+       mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1);
+
+#ifdef CONFIG_HIGHPROFILE
+       /* Timer2 is to be used as a high speed profile timer  */
+       writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3,
+               MCF_MBAR + MCFSIM_TIMER2ICR);
+       mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2);
+#endif
 }
 
 /***************************************************************************/
@@ -117,8 +99,6 @@ void m5206e_cpu_reset(void)
 
 void __init config_BSP(char *commandp, int size)
 {
-       mcf_setimr(MCFSIM_IMR_MASKALL);
-
 #if defined(CONFIG_NETtel)
        /* Copy command line from FLASH to local buffer... */
        memcpy(commandp, (char *) 0xf0004000, size);
@@ -126,13 +106,19 @@ void __init config_BSP(char *commandp, int size)
 #endif /* CONFIG_NETtel */
 
        mach_reset = m5206e_cpu_reset;
+       m5206e_timers_init();
+       m5206e_uarts_init();
+
+       /* Only support the external interrupts on their primary level */
+       mcf_mapirq2imr(25, MCFINTC_EINT1);
+       mcf_mapirq2imr(28, MCFINTC_EINT4);
+       mcf_mapirq2imr(31, MCFINTC_EINT7);
 }
 
 /***************************************************************************/
 
 static int __init init_BSP(void)
 {
-       m5206e_uarts_init();
        platform_add_devices(m5206e_devices, ARRAY_SIZE(m5206e_devices));
        return 0;
 }
diff --git a/arch/m68knommu/platform/5206e/gpio.c b/arch/m68knommu/platform/5206e/gpio.c
new file mode 100644 (file)
index 0000000..60f779c
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Coldfire generic GPIO support
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/init.h>
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfgpio.h>
+
+static struct mcf_gpio_chip mcf_gpio_chips[] = {
+       {
+               .gpio_chip                      = {
+                       .label                  = "PP",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFSIM_PADDR,
+               .podr                           = MCFSIM_PADAT,
+               .ppdr                           = MCFSIM_PADAT,
+       },
+};
+
+static int __init mcf_gpio_init(void)
+{
+       unsigned i = 0;
+       while (i < ARRAY_SIZE(mcf_gpio_chips))
+               (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
+       return 0;
+}
+
+core_initcall(mcf_gpio_init);
index a50e76acc8fdc0796a158924c6eed108f20eef7d..435ab3483dc1dd9f89c4599ce6ba96b5994e8fa5 100644 (file)
@@ -14,4 +14,4 @@
 
 asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
-obj-y := config.o
+obj-y := config.o gpio.o
index 1c43a8aec69b90ddd892698301d3478c026bb98a..92614de42cd349b6656c6f557f82cc1263fb17d5 100644 (file)
@@ -81,20 +81,11 @@ static struct platform_device *m520x_devices[] __initdata = {
 
 /***************************************************************************/
 
-#define        INTC0   (MCF_MBAR + MCFICM_INTC0)
-
 static void __init m520x_uart_init_line(int line, int irq)
 {
-       u32 imr;
        u16 par;
        u8 par2;
 
-       writeb(0x03, INTC0 + MCFINTC_ICR0 + MCFINT_UART0 + line);
-
-       imr = readl(INTC0 + MCFINTC_IMRL);
-       imr &= ~((1 << (irq - MCFINT_VECBASE)) | 1);
-       writel(imr, INTC0 + MCFINTC_IMRL);
-
        switch (line) {
        case 0:
                par = readw(MCF_IPSBAR + MCF_GPIO_PAR_UART);
@@ -131,18 +122,8 @@ static void __init m520x_uarts_init(void)
 
 static void __init m520x_fec_init(void)
 {
-       u32 imr;
        u8 v;
 
-       /* Unmask FEC interrupts at ColdFire interrupt controller */
-       writeb(0x4, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 36);
-       writeb(0x4, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 40);
-       writeb(0x4, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 42);
-
-       imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
-       imr &= ~0x0001FFF0;
-       writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
-
        /* Set multi-function pins to ethernet mode */
        v = readb(MCF_IPSBAR + MCF_GPIO_PAR_FEC);
        writeb(v | 0xf0, MCF_IPSBAR + MCF_GPIO_PAR_FEC);
@@ -153,17 +134,6 @@ static void __init m520x_fec_init(void)
 
 /***************************************************************************/
 
-/*
- *  Program the vector to be an auto-vectored.
- */
-
-void mcf_autovector(unsigned int vec)
-{
-    /* Everything is auto-vectored on the 520x devices */
-}
-
-/***************************************************************************/
-
 static void m520x_cpu_reset(void)
 {
        local_irq_disable();
diff --git a/arch/m68knommu/platform/520x/gpio.c b/arch/m68knommu/platform/520x/gpio.c
new file mode 100644 (file)
index 0000000..15b5bb6
--- /dev/null
@@ -0,0 +1,211 @@
+/*
+ * Coldfire generic GPIO support
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/init.h>
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfgpio.h>
+
+static struct mcf_gpio_chip mcf_gpio_chips[] = {
+       {
+               .gpio_chip                      = {
+                       .label                  = "PIRQ",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFEPORT_EPDDR,
+               .podr                           = MCFEPORT_EPDR,
+               .ppdr                           = MCFEPORT_EPPDR,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "BUSCTL",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 8,
+                       .ngpio                  = 4,
+               },
+               .pddr                           = MCFGPIO_PDDR_BUSCTL,
+               .podr                           = MCFGPIO_PODR_BUSCTL,
+               .ppdr                           = MCFGPIO_PPDSDR_BUSCTL,
+               .setr                           = MCFGPIO_PPDSDR_BUSCTL,
+               .clrr                           = MCFGPIO_PCLRR_BUSCTL,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "BE",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 16,
+                       .ngpio                  = 4,
+               },
+               .pddr                           = MCFGPIO_PDDR_BE,
+               .podr                           = MCFGPIO_PODR_BE,
+               .ppdr                           = MCFGPIO_PPDSDR_BE,
+               .setr                           = MCFGPIO_PPDSDR_BE,
+               .clrr                           = MCFGPIO_PCLRR_BE,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "CS",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 25,
+                       .ngpio                  = 3,
+               },
+               .pddr                           = MCFGPIO_PDDR_CS,
+               .podr                           = MCFGPIO_PODR_CS,
+               .ppdr                           = MCFGPIO_PPDSDR_CS,
+               .setr                           = MCFGPIO_PPDSDR_CS,
+               .clrr                           = MCFGPIO_PCLRR_CS,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "FECI2C",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 32,
+                       .ngpio                  = 4,
+               },
+               .pddr                           = MCFGPIO_PDDR_FECI2C,
+               .podr                           = MCFGPIO_PODR_FECI2C,
+               .ppdr                           = MCFGPIO_PPDSDR_FECI2C,
+               .setr                           = MCFGPIO_PPDSDR_FECI2C,
+               .clrr                           = MCFGPIO_PCLRR_FECI2C,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "QSPI",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 40,
+                       .ngpio                  = 4,
+               },
+               .pddr                           = MCFGPIO_PDDR_QSPI,
+               .podr                           = MCFGPIO_PODR_QSPI,
+               .ppdr                           = MCFGPIO_PPDSDR_QSPI,
+               .setr                           = MCFGPIO_PPDSDR_QSPI,
+               .clrr                           = MCFGPIO_PCLRR_QSPI,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "TIMER",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 48,
+                       .ngpio                  = 4,
+               },
+               .pddr                           = MCFGPIO_PDDR_TIMER,
+               .podr                           = MCFGPIO_PODR_TIMER,
+               .ppdr                           = MCFGPIO_PPDSDR_TIMER,
+               .setr                           = MCFGPIO_PPDSDR_TIMER,
+               .clrr                           = MCFGPIO_PCLRR_TIMER,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "UART",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 56,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_PDDR_UART,
+               .podr                           = MCFGPIO_PODR_UART,
+               .ppdr                           = MCFGPIO_PPDSDR_UART,
+               .setr                           = MCFGPIO_PPDSDR_UART,
+               .clrr                           = MCFGPIO_PCLRR_UART,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "FECH",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 64,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_PDDR_FECH,
+               .podr                           = MCFGPIO_PODR_FECH,
+               .ppdr                           = MCFGPIO_PPDSDR_FECH,
+               .setr                           = MCFGPIO_PPDSDR_FECH,
+               .clrr                           = MCFGPIO_PCLRR_FECH,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "FECL",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 72,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_PDDR_FECL,
+               .podr                           = MCFGPIO_PODR_FECL,
+               .ppdr                           = MCFGPIO_PPDSDR_FECL,
+               .setr                           = MCFGPIO_PPDSDR_FECL,
+               .clrr                           = MCFGPIO_PCLRR_FECL,
+       },
+};
+
+static int __init mcf_gpio_init(void)
+{
+       unsigned i = 0;
+       while (i < ARRAY_SIZE(mcf_gpio_chips))
+               (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
+       return 0;
+}
+
+core_initcall(mcf_gpio_init);
index 5694d593f0297ceb6989f6e55f9b699f8f723be1..b8f9b45440c203bed369b4cd195a5d82ca70b874 100644 (file)
@@ -14,4 +14,4 @@
 
 asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
-obj-y := config.o
+obj-y := config.o gpio.o
index 961fefebca14ebcf3c6e5954b6fbebfe65ecd092..6ba84f2aa397cc639eff61ea38acb9f0e1be903b 100644 (file)
@@ -82,66 +82,20 @@ static struct platform_device *m523x_devices[] __initdata = {
 
 /***************************************************************************/
 
-#define        INTC0   (MCF_MBAR + MCFICM_INTC0)
-
-static void __init m523x_uart_init_line(int line, int irq)
-{
-       u32 imr;
-
-       if ((line < 0) || (line > 2))
-               return;
-
-       writeb(0x30+line, (INTC0 + MCFINTC_ICR0 + MCFINT_UART0 + line));
-
-       imr = readl(INTC0 + MCFINTC_IMRL);
-       imr &= ~((1 << (irq - MCFINT_VECBASE)) | 1);
-       writel(imr, INTC0 + MCFINTC_IMRL);
-}
-
-static void __init m523x_uarts_init(void)
-{
-       const int nrlines = ARRAY_SIZE(m523x_uart_platform);
-       int line;
-
-       for (line = 0; (line < nrlines); line++)
-               m523x_uart_init_line(line, m523x_uart_platform[line].irq);
-}
-
-/***************************************************************************/
-
 static void __init m523x_fec_init(void)
 {
-       u32 imr;
-
-       /* Unmask FEC interrupts at ColdFire interrupt controller */
-       writeb(0x28, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 23);
-       writeb(0x27, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 27);
-       writeb(0x26, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 29);
-
-       imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
-       imr &= ~0xf;
-       writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
-       imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
-       imr &= ~0xff800001;
-       writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
-}
-
-/***************************************************************************/
-
-void mcf_disableall(void)
-{
-       *((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff;
-       *((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL)) = 0xffffffff;
+       u16 par;
+       u8 v;
+
+       /* Set multi-function pins to ethernet use */
+       par = readw(MCF_IPSBAR + 0x100082);
+       writew(par | 0xf00, MCF_IPSBAR + 0x100082);
+       v = readb(MCF_IPSBAR + 0x100078);
+       writeb(v | 0xc0, MCF_IPSBAR + 0x100078);
 }
 
 /***************************************************************************/
 
-void mcf_autovector(unsigned int vec)
-{
-       /* Everything is auto-vectored on the 523x */
-}
-/***************************************************************************/
-
 static void m523x_cpu_reset(void)
 {
        local_irq_disable();
@@ -152,16 +106,14 @@ static void m523x_cpu_reset(void)
 
 void __init config_BSP(char *commandp, int size)
 {
-       mcf_disableall();
        mach_reset = m523x_cpu_reset;
-       m523x_uarts_init();
-       m523x_fec_init();
 }
 
 /***************************************************************************/
 
 static int __init init_BSP(void)
 {
+       m523x_fec_init();
        platform_add_devices(m523x_devices, ARRAY_SIZE(m523x_devices));
        return 0;
 }
diff --git a/arch/m68knommu/platform/523x/gpio.c b/arch/m68knommu/platform/523x/gpio.c
new file mode 100644 (file)
index 0000000..f02840d
--- /dev/null
@@ -0,0 +1,283 @@
+/*
+ * Coldfire generic GPIO support
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/init.h>
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfgpio.h>
+
+static struct mcf_gpio_chip mcf_gpio_chips[] = {
+       {
+               .gpio_chip                      = {
+                       .label                  = "PIRQ",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFEPORT_EPDDR,
+               .podr                           = MCFEPORT_EPDR,
+               .ppdr                           = MCFEPORT_EPPDR,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "ADDR",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 13,
+                       .ngpio                  = 3,
+               },
+               .pddr                           = MCFGPIO_PDDR_ADDR,
+               .podr                           = MCFGPIO_PODR_ADDR,
+               .ppdr                           = MCFGPIO_PPDSDR_ADDR,
+               .setr                           = MCFGPIO_PPDSDR_ADDR,
+               .clrr                           = MCFGPIO_PCLRR_ADDR,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "DATAH",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 16,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_PDDR_DATAH,
+               .podr                           = MCFGPIO_PODR_DATAH,
+               .ppdr                           = MCFGPIO_PPDSDR_DATAH,
+               .setr                           = MCFGPIO_PPDSDR_DATAH,
+               .clrr                           = MCFGPIO_PCLRR_DATAH,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "DATAL",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 24,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_PDDR_DATAL,
+               .podr                           = MCFGPIO_PODR_DATAL,
+               .ppdr                           = MCFGPIO_PPDSDR_DATAL,
+               .setr                           = MCFGPIO_PPDSDR_DATAL,
+               .clrr                           = MCFGPIO_PCLRR_DATAL,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "BUSCTL",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 32,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_PDDR_BUSCTL,
+               .podr                           = MCFGPIO_PODR_BUSCTL,
+               .ppdr                           = MCFGPIO_PPDSDR_BUSCTL,
+               .setr                           = MCFGPIO_PPDSDR_BUSCTL,
+               .clrr                           = MCFGPIO_PCLRR_BUSCTL,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "BS",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 40,
+                       .ngpio                  = 4,
+               },
+               .pddr                           = MCFGPIO_PDDR_BS,
+               .podr                           = MCFGPIO_PODR_BS,
+               .ppdr                           = MCFGPIO_PPDSDR_BS,
+               .setr                           = MCFGPIO_PPDSDR_BS,
+               .clrr                           = MCFGPIO_PCLRR_BS,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "CS",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 49,
+                       .ngpio                  = 7,
+               },
+               .pddr                           = MCFGPIO_PDDR_CS,
+               .podr                           = MCFGPIO_PODR_CS,
+               .ppdr                           = MCFGPIO_PPDSDR_CS,
+               .setr                           = MCFGPIO_PPDSDR_CS,
+               .clrr                           = MCFGPIO_PCLRR_CS,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "SDRAM",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 56,
+                       .ngpio                  = 6,
+               },
+               .pddr                           = MCFGPIO_PDDR_SDRAM,
+               .podr                           = MCFGPIO_PODR_SDRAM,
+               .ppdr                           = MCFGPIO_PPDSDR_SDRAM,
+               .setr                           = MCFGPIO_PPDSDR_SDRAM,
+               .clrr                           = MCFGPIO_PCLRR_SDRAM,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "FECI2C",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 64,
+                       .ngpio                  = 4,
+               },
+               .pddr                           = MCFGPIO_PDDR_FECI2C,
+               .podr                           = MCFGPIO_PODR_FECI2C,
+               .ppdr                           = MCFGPIO_PPDSDR_FECI2C,
+               .setr                           = MCFGPIO_PPDSDR_FECI2C,
+               .clrr                           = MCFGPIO_PCLRR_FECI2C,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "UARTH",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 72,
+                       .ngpio                  = 2,
+               },
+               .pddr                           = MCFGPIO_PDDR_UARTH,
+               .podr                           = MCFGPIO_PODR_UARTH,
+               .ppdr                           = MCFGPIO_PPDSDR_UARTH,
+               .setr                           = MCFGPIO_PPDSDR_UARTH,
+               .clrr                           = MCFGPIO_PCLRR_UARTH,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "UARTL",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 80,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_PDDR_UARTL,
+               .podr                           = MCFGPIO_PODR_UARTL,
+               .ppdr                           = MCFGPIO_PPDSDR_UARTL,
+               .setr                           = MCFGPIO_PPDSDR_UARTL,
+               .clrr                           = MCFGPIO_PCLRR_UARTL,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "QSPI",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 88,
+                       .ngpio                  = 5,
+               },
+               .pddr                           = MCFGPIO_PDDR_QSPI,
+               .podr                           = MCFGPIO_PODR_QSPI,
+               .ppdr                           = MCFGPIO_PPDSDR_QSPI,
+               .setr                           = MCFGPIO_PPDSDR_QSPI,
+               .clrr                           = MCFGPIO_PCLRR_QSPI,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "TIMER",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 96,
+                       .ngpio                  = 4,
+               },
+               .pddr                           = MCFGPIO_PDDR_TIMER,
+               .podr                           = MCFGPIO_PODR_TIMER,
+               .ppdr                           = MCFGPIO_PPDSDR_TIMER,
+               .setr                           = MCFGPIO_PPDSDR_TIMER,
+               .clrr                           = MCFGPIO_PCLRR_TIMER,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "ETPU",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 104,
+                       .ngpio                  = 3,
+               },
+               .pddr                           = MCFGPIO_PDDR_ETPU,
+               .podr                           = MCFGPIO_PODR_ETPU,
+               .ppdr                           = MCFGPIO_PPDSDR_ETPU,
+               .setr                           = MCFGPIO_PPDSDR_ETPU,
+               .clrr                           = MCFGPIO_PCLRR_ETPU,
+       },
+};
+
+static int __init mcf_gpio_init(void)
+{
+       unsigned i = 0;
+       while (i < ARRAY_SIZE(mcf_gpio_chips))
+               (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
+       return 0;
+}
+
+core_initcall(mcf_gpio_init);
index a439d9ab3f272dc4326db108fb548def198d22b9..f56225d1582fe559a81026e2f8bbb32408a19ee2 100644 (file)
@@ -14,5 +14,5 @@
 
 asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
-obj-y := config.o
+obj-y := config.o gpio.o intc2.o
 
index 93d998825925074addca47dee661c49dc8cec9be..646f5ba462fcb6675293f7c55a8ee6efb6e31fbf 100644 (file)
@@ -48,11 +48,11 @@ static void __init m5249_uart_init_line(int line, int irq)
        if (line == 0) {
                writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
                writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR);
-               mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
+               mcf_mapirq2imr(irq, MCFINTC_UART0);
        } else if (line == 1) {
                writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
                writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR);
-               mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
+               mcf_mapirq2imr(irq, MCFINTC_UART1);
        }
 }
 
@@ -65,38 +65,21 @@ static void __init m5249_uarts_init(void)
                m5249_uart_init_line(line, m5249_uart_platform[line].irq);
 }
 
-
 /***************************************************************************/
 
-void mcf_autovector(unsigned int vec)
+static void __init m5249_timers_init(void)
 {
-       volatile unsigned char  *mbar;
-
-       if ((vec >= 25) && (vec <= 31)) {
-               mbar = (volatile unsigned char *) MCF_MBAR;
-               vec = 0x1 << (vec - 24);
-               *(mbar + MCFSIM_AVR) |= vec;
-               mcf_setimr(mcf_getimr() & ~vec);
-       }
-}
-
-/***************************************************************************/
-
-void mcf_settimericr(unsigned int timer, unsigned int level)
-{
-       volatile unsigned char *icrp;
-       unsigned int icr, imr;
-
-       if (timer <= 2) {
-               switch (timer) {
-               case 2:  icr = MCFSIM_TIMER2ICR; imr = MCFSIM_IMR_TIMER2; break;
-               default: icr = MCFSIM_TIMER1ICR; imr = MCFSIM_IMR_TIMER1; break;
-               }
-
-               icrp = (volatile unsigned char *) (MCF_MBAR + icr);
-               *icrp = MCFSIM_ICR_AUTOVEC | (level << 2) | MCFSIM_ICR_PRI3;
-               mcf_setimr(mcf_getimr() & ~imr);
-       }
+       /* Timer1 is always used as system timer */
+       writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3,
+               MCF_MBAR + MCFSIM_TIMER1ICR);
+       mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1);
+
+#ifdef CONFIG_HIGHPROFILE
+       /* Timer2 is to be used as a high speed profile timer  */
+       writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3,
+               MCF_MBAR + MCFSIM_TIMER2ICR);
+       mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2);
+#endif
 }
 
 /***************************************************************************/
@@ -114,15 +97,15 @@ void m5249_cpu_reset(void)
 
 void __init config_BSP(char *commandp, int size)
 {
-       mcf_setimr(MCFSIM_IMR_MASKALL);
        mach_reset = m5249_cpu_reset;
+       m5249_timers_init();
+       m5249_uarts_init();
 }
 
 /***************************************************************************/
 
 static int __init init_BSP(void)
 {
-       m5249_uarts_init();
        platform_add_devices(m5249_devices, ARRAY_SIZE(m5249_devices));
        return 0;
 }
diff --git a/arch/m68knommu/platform/5249/gpio.c b/arch/m68knommu/platform/5249/gpio.c
new file mode 100644 (file)
index 0000000..c611eab
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Coldfire generic GPIO support
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/init.h>
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfgpio.h>
+
+static struct mcf_gpio_chip mcf_gpio_chips[] = {
+       {
+               .gpio_chip                      = {
+                       .label                  = "GPIO0",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value,
+                       .ngpio                  = 32,
+               },
+               .pddr                           = MCFSIM2_GPIOENABLE,
+               .podr                           = MCFSIM2_GPIOWRITE,
+               .ppdr                           = MCFSIM2_GPIOREAD,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "GPIO1",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value,
+                       .base                   = 32,
+                       .ngpio                  = 32,
+               },
+               .pddr                           = MCFSIM2_GPIO1ENABLE,
+               .podr                           = MCFSIM2_GPIO1WRITE,
+               .ppdr                           = MCFSIM2_GPIO1READ,
+       },
+};
+
+static int __init mcf_gpio_init(void)
+{
+       unsigned i = 0;
+       while (i < ARRAY_SIZE(mcf_gpio_chips))
+               (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
+       return 0;
+}
+
+core_initcall(mcf_gpio_init);
diff --git a/arch/m68knommu/platform/5249/intc2.c b/arch/m68knommu/platform/5249/intc2.c
new file mode 100644 (file)
index 0000000..d09d9da
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * intc2.c  -- support for the 2nd INTC controller of the 5249
+ *
+ * (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+
+static void intc2_irq_gpio_mask(unsigned int irq)
+{
+       u32 imr;
+       imr = readl(MCF_MBAR2 + MCFSIM2_GPIOINTENABLE);
+       imr &= ~(0x1 << (irq - MCFINTC2_GPIOIRQ0));
+       writel(imr, MCF_MBAR2 + MCFSIM2_GPIOINTENABLE);
+}
+
+static void intc2_irq_gpio_unmask(unsigned int irq)
+{
+       u32 imr;
+       imr = readl(MCF_MBAR2 + MCFSIM2_GPIOINTENABLE);
+       imr |= (0x1 << (irq - MCFINTC2_GPIOIRQ0));
+       writel(imr, MCF_MBAR2 + MCFSIM2_GPIOINTENABLE);
+}
+
+static void intc2_irq_gpio_ack(unsigned int irq)
+{
+       writel(0x1 << (irq - MCFINTC2_GPIOIRQ0), MCF_MBAR2 + MCFSIM2_GPIOINTCLEAR);
+}
+
+static struct irq_chip intc2_irq_gpio_chip = {
+       .name           = "CF-INTC2",
+       .mask           = intc2_irq_gpio_mask,
+       .unmask         = intc2_irq_gpio_unmask,
+       .ack            = intc2_irq_gpio_ack,
+};
+
+static int __init mcf_intc2_init(void)
+{
+       int irq;
+
+       /* GPIO interrupt sources */
+       for (irq = MCFINTC2_GPIOIRQ0; (irq <= MCFINTC2_GPIOIRQ7); irq++)
+               irq_desc[irq].chip = &intc2_irq_gpio_chip;
+
+       return 0;
+}
+
+arch_initcall(mcf_intc2_init);
index 26135d92b34dff2e2a1305eb232ef8cc654cbd2c..93673ef8e2c13de6355fe4c2a3979c22cb2e5f7d 100644 (file)
@@ -14,5 +14,5 @@
 
 asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
-obj-y := config.o
+obj-y := config.o gpio.o intc.o
 
index 5f95fcde05fd8a8a1e951b32594415bb27453154..59278c0887d04de431d46049924f920170328d6a 100644 (file)
 
 /***************************************************************************/
 
-extern unsigned int mcf_timervector;
-extern unsigned int mcf_profilevector;
-extern unsigned int mcf_timerlevel;
-
-/***************************************************************************/
-
 /*
  *     Some platforms need software versions of the GPIO data registers.
  */
@@ -37,11 +31,11 @@ unsigned char ledbank = 0xff;
 static struct mcf_platform_uart m5272_uart_platform[] = {
        {
                .mapbase        = MCF_MBAR + MCFUART_BASE1,
-               .irq            = 73,
+               .irq            = MCF_IRQ_UART1,
        },
        {
                .mapbase        = MCF_MBAR + MCFUART_BASE2,
-               .irq            = 74,
+               .irq            = MCF_IRQ_UART2,
        },
        { },
 };
@@ -59,18 +53,18 @@ static struct resource m5272_fec_resources[] = {
                .flags          = IORESOURCE_MEM,
        },
        {
-               .start          = 86,
-               .end            = 86,
+               .start          = MCF_IRQ_ERX,
+               .end            = MCF_IRQ_ERX,
                .flags          = IORESOURCE_IRQ,
        },
        {
-               .start          = 87,
-               .end            = 87,
+               .start          = MCF_IRQ_ETX,
+               .end            = MCF_IRQ_ETX,
                .flags          = IORESOURCE_IRQ,
        },
        {
-               .start          = 88,
-               .end            = 88,
+               .start          = MCF_IRQ_ENTC,
+               .end            = MCF_IRQ_ENTC,
                .flags          = IORESOURCE_IRQ,
        },
 };
@@ -94,9 +88,6 @@ static void __init m5272_uart_init_line(int line, int irq)
        u32 v;
 
        if ((line >= 0) && (line < 2)) {
-               v = (line) ? 0x0e000000 : 0xe0000000;
-               writel(v, MCF_MBAR + MCFSIM_ICR2);
-
                /* Enable the output lines for the serial ports */
                v = readl(MCF_MBAR + MCFSIM_PBCNT);
                v = (v & ~0x000000ff) | 0x00000055;
@@ -119,54 +110,6 @@ static void __init m5272_uarts_init(void)
 
 /***************************************************************************/
 
-static void __init m5272_fec_init(void)
-{
-       u32 imr;
-
-       /* Unmask FEC interrupts at ColdFire interrupt controller */
-       imr = readl(MCF_MBAR + MCFSIM_ICR3);
-       imr = (imr & ~0x00000fff) | 0x00000ddd;
-       writel(imr, MCF_MBAR + MCFSIM_ICR3);
-
-       imr = readl(MCF_MBAR + MCFSIM_ICR1);
-       imr = (imr & ~0x0f000000) | 0x0d000000;
-       writel(imr, MCF_MBAR + MCFSIM_ICR1);
-}
-
-/***************************************************************************/
-
-void mcf_disableall(void)
-{
-       volatile unsigned long  *icrp;
-
-       icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
-       icrp[0] = 0x88888888;
-       icrp[1] = 0x88888888;
-       icrp[2] = 0x88888888;
-       icrp[3] = 0x88888888;
-}
-
-/***************************************************************************/
-
-void mcf_autovector(unsigned int vec)
-{
-       /* Everything is auto-vectored on the 5272 */
-}
-
-/***************************************************************************/
-
-void mcf_settimericr(int timer, int level)
-{
-       volatile unsigned long *icrp;
-
-       if ((timer >= 1 ) && (timer <= 4)) {
-               icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
-               *icrp = (0x8 | level) << ((4 - timer) * 4);
-       }
-}
-
-/***************************************************************************/
-
 static void m5272_cpu_reset(void)
 {
        local_irq_disable();
@@ -190,8 +133,6 @@ void __init config_BSP(char *commandp, int size)
        *pivrp = 0x40;
 #endif
 
-       mcf_disableall();
-
 #if defined(CONFIG_NETtel) || defined(CONFIG_SCALES)
        /* Copy command line from FLASH to local buffer... */
        memcpy(commandp, (char *) 0xf0004000, size);
@@ -202,8 +143,6 @@ void __init config_BSP(char *commandp, int size)
        commandp[size-1] = 0;
 #endif
 
-       mcf_timervector = 69;
-       mcf_profilevector = 70;
        mach_reset = m5272_cpu_reset;
 }
 
@@ -212,7 +151,6 @@ void __init config_BSP(char *commandp, int size)
 static int __init init_BSP(void)
 {
        m5272_uarts_init();
-       m5272_fec_init();
        platform_add_devices(m5272_devices, ARRAY_SIZE(m5272_devices));
        return 0;
 }
diff --git a/arch/m68knommu/platform/5272/gpio.c b/arch/m68knommu/platform/5272/gpio.c
new file mode 100644 (file)
index 0000000..459db89
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Coldfire generic GPIO support
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/init.h>
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfgpio.h>
+
+static struct mcf_gpio_chip mcf_gpio_chips[] = {
+       {
+               .gpio_chip                      = {
+                       .label                  = "PA",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value,
+                       .ngpio                  = 16,
+               },
+               .pddr                           = MCFSIM_PADDR,
+               .podr                           = MCFSIM_PADAT,
+               .ppdr                           = MCFSIM_PADAT,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "PB",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value,
+                       .base                   = 16,
+                       .ngpio                  = 16,
+               },
+               .pddr                           = MCFSIM_PBDDR,
+               .podr                           = MCFSIM_PBDAT,
+               .ppdr                           = MCFSIM_PBDAT,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "PC",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value,
+                       .base                   = 32,
+                       .ngpio                  = 16,
+               },
+               .pddr                           = MCFSIM_PCDDR,
+               .podr                           = MCFSIM_PCDAT,
+               .ppdr                           = MCFSIM_PCDAT,
+       },
+};
+
+static int __init mcf_gpio_init(void)
+{
+       unsigned i = 0;
+       while (i < ARRAY_SIZE(mcf_gpio_chips))
+               (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
+       return 0;
+}
+
+core_initcall(mcf_gpio_init);
diff --git a/arch/m68knommu/platform/5272/intc.c b/arch/m68knommu/platform/5272/intc.c
new file mode 100644 (file)
index 0000000..7081e0a
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * intc.c  --  interrupt controller or ColdFire 5272 SoC
+ *
+ * (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/traps.h>
+
+/*
+ * The 5272 ColdFire interrupt controller is nothing like any other
+ * ColdFire interrupt controller - it truly is completely different.
+ * Given its age it is unlikely to be used on any other ColdFire CPU.
+ */
+
+/*
+ * The masking and priproty setting of interrupts on the 5272 is done
+ * via a set of 4 "Interrupt Controller Registers" (ICR). There is a
+ * loose mapping of vector number to register and internal bits, but
+ * a table is the easiest and quickest way to map them.
+ */
+struct irqmap {
+       unsigned char   icr;
+       unsigned char   index;
+       unsigned char   ack;
+};
+
+static struct irqmap intc_irqmap[MCFINT_VECMAX - MCFINT_VECBASE] = {
+       /*MCF_IRQ_SPURIOUS*/    { .icr = 0,           .index = 0,  .ack = 0, },
+       /*MCF_IRQ_EINT1*/       { .icr = MCFSIM_ICR1, .index = 28, .ack = 1, },
+       /*MCF_IRQ_EINT2*/       { .icr = MCFSIM_ICR1, .index = 24, .ack = 1, },
+       /*MCF_IRQ_EINT3*/       { .icr = MCFSIM_ICR1, .index = 20, .ack = 1, },
+       /*MCF_IRQ_EINT4*/       { .icr = MCFSIM_ICR1, .index = 16, .ack = 1, },
+       /*MCF_IRQ_TIMER1*/      { .icr = MCFSIM_ICR1, .index = 12, .ack = 0, },
+       /*MCF_IRQ_TIMER2*/      { .icr = MCFSIM_ICR1, .index = 8,  .ack = 0, },
+       /*MCF_IRQ_TIMER3*/      { .icr = MCFSIM_ICR1, .index = 4,  .ack = 0, },
+       /*MCF_IRQ_TIMER4*/      { .icr = MCFSIM_ICR1, .index = 0,  .ack = 0, },
+       /*MCF_IRQ_UART1*/       { .icr = MCFSIM_ICR2, .index = 28, .ack = 0, },
+       /*MCF_IRQ_UART2*/       { .icr = MCFSIM_ICR2, .index = 24, .ack = 0, },
+       /*MCF_IRQ_PLIP*/        { .icr = MCFSIM_ICR2, .index = 20, .ack = 0, },
+       /*MCF_IRQ_PLIA*/        { .icr = MCFSIM_ICR2, .index = 16, .ack = 0, },
+       /*MCF_IRQ_USB0*/        { .icr = MCFSIM_ICR2, .index = 12, .ack = 0, },
+       /*MCF_IRQ_USB1*/        { .icr = MCFSIM_ICR2, .index = 8,  .ack = 0, },
+       /*MCF_IRQ_USB2*/        { .icr = MCFSIM_ICR2, .index = 4,  .ack = 0, },
+       /*MCF_IRQ_USB3*/        { .icr = MCFSIM_ICR2, .index = 0,  .ack = 0, },
+       /*MCF_IRQ_USB4*/        { .icr = MCFSIM_ICR3, .index = 28, .ack = 0, },
+       /*MCF_IRQ_USB5*/        { .icr = MCFSIM_ICR3, .index = 24, .ack = 0, },
+       /*MCF_IRQ_USB6*/        { .icr = MCFSIM_ICR3, .index = 20, .ack = 0, },
+       /*MCF_IRQ_USB7*/        { .icr = MCFSIM_ICR3, .index = 16, .ack = 0, },
+       /*MCF_IRQ_DMA*/         { .icr = MCFSIM_ICR3, .index = 12, .ack = 0, },
+       /*MCF_IRQ_ERX*/         { .icr = MCFSIM_ICR3, .index = 8,  .ack = 0, },
+       /*MCF_IRQ_ETX*/         { .icr = MCFSIM_ICR3, .index = 4,  .ack = 0, },
+       /*MCF_IRQ_ENTC*/        { .icr = MCFSIM_ICR3, .index = 0,  .ack = 0, },
+       /*MCF_IRQ_QSPI*/        { .icr = MCFSIM_ICR4, .index = 28, .ack = 0, },
+       /*MCF_IRQ_EINT5*/       { .icr = MCFSIM_ICR4, .index = 24, .ack = 1, },
+       /*MCF_IRQ_EINT6*/       { .icr = MCFSIM_ICR4, .index = 20, .ack = 1, },
+       /*MCF_IRQ_SWTO*/        { .icr = MCFSIM_ICR4, .index = 16, .ack = 0, },
+};
+
+static void intc_irq_mask(unsigned int irq)
+{
+       if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) {
+               u32 v;
+               irq -= MCFINT_VECBASE;
+               v = 0x8 << intc_irqmap[irq].index;
+               writel(v, MCF_MBAR + intc_irqmap[irq].icr);
+       }
+}
+
+static void intc_irq_unmask(unsigned int irq)
+{
+       if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) {
+               u32 v;
+               irq -= MCFINT_VECBASE;
+               v = 0xd << intc_irqmap[irq].index;
+               writel(v, MCF_MBAR + intc_irqmap[irq].icr);
+       }
+}
+
+static void intc_irq_ack(unsigned int irq)
+{
+       /* Only external interrupts are acked */
+       if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) {
+               irq -= MCFINT_VECBASE;
+               if (intc_irqmap[irq].ack) {
+                       u32 v;
+                       v = 0xd << intc_irqmap[irq].index;
+                       writel(v, MCF_MBAR + intc_irqmap[irq].icr);
+               }
+       }
+}
+
+static int intc_irq_set_type(unsigned int irq, unsigned int type)
+{
+       /* We can set the edge type here for external interrupts */
+       return 0;
+}
+
+static struct irq_chip intc_irq_chip = {
+       .name           = "CF-INTC",
+       .mask           = intc_irq_mask,
+       .unmask         = intc_irq_unmask,
+       .ack            = intc_irq_ack,
+       .set_type       = intc_irq_set_type,
+};
+
+void __init init_IRQ(void)
+{
+       int irq;
+
+       init_vectors();
+
+       /* Mask all interrupt sources */
+       writel(0x88888888, MCF_MBAR + MCFSIM_ICR1);
+       writel(0x88888888, MCF_MBAR + MCFSIM_ICR2);
+       writel(0x88888888, MCF_MBAR + MCFSIM_ICR3);
+       writel(0x88888888, MCF_MBAR + MCFSIM_ICR4);
+
+       for (irq = 0; (irq < NR_IRQS); irq++) {
+               irq_desc[irq].status = IRQ_DISABLED;
+               irq_desc[irq].action = NULL;
+               irq_desc[irq].depth = 1;
+               irq_desc[irq].chip = &intc_irq_chip;
+               intc_irq_set_type(irq, 0);
+       }
+}
+
index 26135d92b34dff2e2a1305eb232ef8cc654cbd2c..3d90e6d92459bc0e4adcecffa84488032833ff8f 100644 (file)
@@ -14,5 +14,5 @@
 
 asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
-obj-y := config.o
+obj-y := config.o gpio.o
 
index f746439cfd3ef9db0080b0d85f9d4f803c8b8d61..fa51be172830a856fade06999c65d08276e5e8e6 100644 (file)
@@ -116,23 +116,13 @@ static struct platform_device *m527x_devices[] __initdata = {
 
 /***************************************************************************/
 
-#define        INTC0   (MCF_MBAR + MCFICM_INTC0)
-
 static void __init m527x_uart_init_line(int line, int irq)
 {
        u16 sepmask;
-       u32 imr;
 
        if ((line < 0) || (line > 2))
                return;
 
-       /* level 6, line based priority */
-       writeb(0x30+line, INTC0 + MCFINTC_ICR0 + MCFINT_UART0 + line);
-
-       imr = readl(INTC0 + MCFINTC_IMRL);
-       imr &= ~((1 << (irq - MCFINT_VECBASE)) | 1);
-       writel(imr, INTC0 + MCFINTC_IMRL);
-
        /*
         * External Pin Mask Setting & Enable External Pin for Interface
         */
@@ -157,32 +147,11 @@ static void __init m527x_uarts_init(void)
 
 /***************************************************************************/
 
-static void __init m527x_fec_irq_init(int nr)
-{
-       unsigned long base;
-       u32 imr;
-
-       base = MCF_IPSBAR + (nr ? MCFICM_INTC1 : MCFICM_INTC0);
-
-       writeb(0x28, base + MCFINTC_ICR0 + 23);
-       writeb(0x27, base + MCFINTC_ICR0 + 27);
-       writeb(0x26, base + MCFINTC_ICR0 + 29);
-
-       imr = readl(base + MCFINTC_IMRH);
-       imr &= ~0xf;
-       writel(imr, base + MCFINTC_IMRH);
-       imr = readl(base + MCFINTC_IMRL);
-       imr &= ~0xff800001;
-       writel(imr, base + MCFINTC_IMRL);
-}
-
 static void __init m527x_fec_init(void)
 {
        u16 par;
        u8 v;
 
-       m527x_fec_irq_init(0);
-
        /* Set multi-function pins to ethernet mode for fec0 */
 #if defined(CONFIG_M5271)
        v = readb(MCF_IPSBAR + 0x100047);
@@ -195,8 +164,6 @@ static void __init m527x_fec_init(void)
 #endif
 
 #ifdef CONFIG_FEC2
-       m527x_fec_irq_init(1);
-
        /* Set multi-function pins to ethernet mode for fec1 */
        par = readw(MCF_IPSBAR + 0x100082);
        writew(par | 0xa0, MCF_IPSBAR + 0x100082);
@@ -207,21 +174,6 @@ static void __init m527x_fec_init(void)
 
 /***************************************************************************/
 
-void mcf_disableall(void)
-{
-       *((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff;
-       *((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL)) = 0xffffffff;
-}
-
-/***************************************************************************/
-
-void mcf_autovector(unsigned int vec)
-{
-       /* Everything is auto-vectored on the 5272 */
-}
-
-/***************************************************************************/
-
 static void m527x_cpu_reset(void)
 {
        local_irq_disable();
@@ -232,7 +184,6 @@ static void m527x_cpu_reset(void)
 
 void __init config_BSP(char *commandp, int size)
 {
-       mcf_disableall();
        mach_reset = m527x_cpu_reset;
        m527x_uarts_init();
        m527x_fec_init();
diff --git a/arch/m68knommu/platform/527x/gpio.c b/arch/m68knommu/platform/527x/gpio.c
new file mode 100644 (file)
index 0000000..1028142
--- /dev/null
@@ -0,0 +1,607 @@
+/*
+ * Coldfire generic GPIO support
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/init.h>
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfgpio.h>
+
+static struct mcf_gpio_chip mcf_gpio_chips[] = {
+#if defined(CONFIG_M5271)
+       {
+               .gpio_chip                      = {
+                       .label                  = "PIRQ",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFEPORT_EPDDR,
+               .podr                           = MCFEPORT_EPDR,
+               .ppdr                           = MCFEPORT_EPPDR,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "ADDR",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 13,
+                       .ngpio                  = 3,
+               },
+               .pddr                           = MCFGPIO_PDDR_ADDR,
+               .podr                           = MCFGPIO_PODR_ADDR,
+               .ppdr                           = MCFGPIO_PPDSDR_ADDR,
+               .setr                           = MCFGPIO_PPDSDR_ADDR,
+               .clrr                           = MCFGPIO_PCLRR_ADDR,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "DATAH",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 16,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_PDDR_DATAH,
+               .podr                           = MCFGPIO_PODR_DATAH,
+               .ppdr                           = MCFGPIO_PPDSDR_DATAH,
+               .setr                           = MCFGPIO_PPDSDR_DATAH,
+               .clrr                           = MCFGPIO_PCLRR_DATAH,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "DATAL",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 24,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_PDDR_DATAL,
+               .podr                           = MCFGPIO_PODR_DATAL,
+               .ppdr                           = MCFGPIO_PPDSDR_DATAL,
+               .setr                           = MCFGPIO_PPDSDR_DATAL,
+               .clrr                           = MCFGPIO_PCLRR_DATAL,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "BUSCTL",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 32,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_PDDR_BUSCTL,
+               .podr                           = MCFGPIO_PODR_BUSCTL,
+               .ppdr                           = MCFGPIO_PPDSDR_BUSCTL,
+               .setr                           = MCFGPIO_PPDSDR_BUSCTL,
+               .clrr                           = MCFGPIO_PCLRR_BUSCTL,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "BS",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 40,
+                       .ngpio                  = 4,
+               },
+               .pddr                           = MCFGPIO_PDDR_BS,
+               .podr                           = MCFGPIO_PODR_BS,
+               .ppdr                           = MCFGPIO_PPDSDR_BS,
+               .setr                           = MCFGPIO_PPDSDR_BS,
+               .clrr                           = MCFGPIO_PCLRR_BS,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "CS",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 49,
+                       .ngpio                  = 7,
+               },
+               .pddr                           = MCFGPIO_PDDR_CS,
+               .podr                           = MCFGPIO_PODR_CS,
+               .ppdr                           = MCFGPIO_PPDSDR_CS,
+               .setr                           = MCFGPIO_PPDSDR_CS,
+               .clrr                           = MCFGPIO_PCLRR_CS,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "SDRAM",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 56,
+                       .ngpio                  = 6,
+               },
+               .pddr                           = MCFGPIO_PDDR_SDRAM,
+               .podr                           = MCFGPIO_PODR_SDRAM,
+               .ppdr                           = MCFGPIO_PPDSDR_SDRAM,
+               .setr                           = MCFGPIO_PPDSDR_SDRAM,
+               .clrr                           = MCFGPIO_PCLRR_SDRAM,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "FECI2C",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 64,
+                       .ngpio                  = 4,
+               },
+               .pddr                           = MCFGPIO_PDDR_FECI2C,
+               .podr                           = MCFGPIO_PODR_FECI2C,
+               .ppdr                           = MCFGPIO_PPDSDR_FECI2C,
+               .setr                           = MCFGPIO_PPDSDR_FECI2C,
+               .clrr                           = MCFGPIO_PCLRR_FECI2C,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "UARTH",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 72,
+                       .ngpio                  = 2,
+               },
+               .pddr                           = MCFGPIO_PDDR_UARTH,
+               .podr                           = MCFGPIO_PODR_UARTH,
+               .ppdr                           = MCFGPIO_PPDSDR_UARTH,
+               .setr                           = MCFGPIO_PPDSDR_UARTH,
+               .clrr                           = MCFGPIO_PCLRR_UARTH,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "UARTL",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 80,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_PDDR_UARTL,
+               .podr                           = MCFGPIO_PODR_UARTL,
+               .ppdr                           = MCFGPIO_PPDSDR_UARTL,
+               .setr                           = MCFGPIO_PPDSDR_UARTL,
+               .clrr                           = MCFGPIO_PCLRR_UARTL,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "QSPI",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 88,
+                       .ngpio                  = 5,
+               },
+               .pddr                           = MCFGPIO_PDDR_QSPI,
+               .podr                           = MCFGPIO_PODR_QSPI,
+               .ppdr                           = MCFGPIO_PPDSDR_QSPI,
+               .setr                           = MCFGPIO_PPDSDR_QSPI,
+               .clrr                           = MCFGPIO_PCLRR_QSPI,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "TIMER",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 96,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_PDDR_TIMER,
+               .podr                           = MCFGPIO_PODR_TIMER,
+               .ppdr                           = MCFGPIO_PPDSDR_TIMER,
+               .setr                           = MCFGPIO_PPDSDR_TIMER,
+               .clrr                           = MCFGPIO_PCLRR_TIMER,
+       },
+#elif defined(CONFIG_M5275)
+       {
+               .gpio_chip                      = {
+                       .label                  = "PIRQ",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFEPORT_EPDDR,
+               .podr                           = MCFEPORT_EPDR,
+               .ppdr                           = MCFEPORT_EPPDR,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "BUSCTL",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 8,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_PDDR_BUSCTL,
+               .podr                           = MCFGPIO_PODR_BUSCTL,
+               .ppdr                           = MCFGPIO_PPDSDR_BUSCTL,
+               .setr                           = MCFGPIO_PPDSDR_BUSCTL,
+               .clrr                           = MCFGPIO_PCLRR_BUSCTL,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "ADDR",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 21,
+                       .ngpio                  = 3,
+               },
+               .pddr                           = MCFGPIO_PDDR_ADDR,
+               .podr                           = MCFGPIO_PODR_ADDR,
+               .ppdr                           = MCFGPIO_PPDSDR_ADDR,
+               .setr                           = MCFGPIO_PPDSDR_ADDR,
+               .clrr                           = MCFGPIO_PCLRR_ADDR,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "CS",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 25,
+                       .ngpio                  = 7,
+               },
+               .pddr                           = MCFGPIO_PDDR_CS,
+               .podr                           = MCFGPIO_PODR_CS,
+               .ppdr                           = MCFGPIO_PPDSDR_CS,
+               .setr                           = MCFGPIO_PPDSDR_CS,
+               .clrr                           = MCFGPIO_PCLRR_CS,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "FEC0H",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 32,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_PDDR_FEC0H,
+               .podr                           = MCFGPIO_PODR_FEC0H,
+               .ppdr                           = MCFGPIO_PPDSDR_FEC0H,
+               .setr                           = MCFGPIO_PPDSDR_FEC0H,
+               .clrr                           = MCFGPIO_PCLRR_FEC0H,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "FEC0L",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 40,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_PDDR_FEC0L,
+               .podr                           = MCFGPIO_PODR_FEC0L,
+               .ppdr                           = MCFGPIO_PPDSDR_FEC0L,
+               .setr                           = MCFGPIO_PPDSDR_FEC0L,
+               .clrr                           = MCFGPIO_PCLRR_FEC0L,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "FECI2C",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 48,
+                       .ngpio                  = 6,
+               },
+               .pddr                           = MCFGPIO_PDDR_FECI2C,
+               .podr                           = MCFGPIO_PODR_FECI2C,
+               .ppdr                           = MCFGPIO_PPDSDR_FECI2C,
+               .setr                           = MCFGPIO_PPDSDR_FECI2C,
+               .clrr                           = MCFGPIO_PCLRR_FECI2C,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "QSPI",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 56,
+                       .ngpio                  = 7,
+               },
+               .pddr                           = MCFGPIO_PDDR_QSPI,
+               .podr                           = MCFGPIO_PODR_QSPI,
+               .ppdr                           = MCFGPIO_PPDSDR_QSPI,
+               .setr                           = MCFGPIO_PPDSDR_QSPI,
+               .clrr                           = MCFGPIO_PCLRR_QSPI,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "SDRAM",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 64,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_PDDR_SDRAM,
+               .podr                           = MCFGPIO_PODR_SDRAM,
+               .ppdr                           = MCFGPIO_PPDSDR_SDRAM,
+               .setr                           = MCFGPIO_PPDSDR_SDRAM,
+               .clrr                           = MCFGPIO_PCLRR_SDRAM,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "TIMERH",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 72,
+                       .ngpio                  = 4,
+               },
+               .pddr                           = MCFGPIO_PDDR_TIMERH,
+               .podr                           = MCFGPIO_PODR_TIMERH,
+               .ppdr                           = MCFGPIO_PPDSDR_TIMERH,
+               .setr                           = MCFGPIO_PPDSDR_TIMERH,
+               .clrr                           = MCFGPIO_PCLRR_TIMERH,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "TIMERL",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 80,
+                       .ngpio                  = 4,
+               },
+               .pddr                           = MCFGPIO_PDDR_TIMERL,
+               .podr                           = MCFGPIO_PODR_TIMERL,
+               .ppdr                           = MCFGPIO_PPDSDR_TIMERL,
+               .setr                           = MCFGPIO_PPDSDR_TIMERL,
+               .clrr                           = MCFGPIO_PCLRR_TIMERL,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "UARTL",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 88,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_PDDR_UARTL,
+               .podr                           = MCFGPIO_PODR_UARTL,
+               .ppdr                           = MCFGPIO_PPDSDR_UARTL,
+               .setr                           = MCFGPIO_PPDSDR_UARTL,
+               .clrr                           = MCFGPIO_PCLRR_UARTL,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "FEC1H",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 96,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_PDDR_FEC1H,
+               .podr                           = MCFGPIO_PODR_FEC1H,
+               .ppdr                           = MCFGPIO_PPDSDR_FEC1H,
+               .setr                           = MCFGPIO_PPDSDR_FEC1H,
+               .clrr                           = MCFGPIO_PCLRR_FEC1H,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "FEC1L",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 104,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_PDDR_FEC1L,
+               .podr                           = MCFGPIO_PODR_FEC1L,
+               .ppdr                           = MCFGPIO_PPDSDR_FEC1L,
+               .setr                           = MCFGPIO_PPDSDR_FEC1L,
+               .clrr                           = MCFGPIO_PCLRR_FEC1L,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "BS",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 114,
+                       .ngpio                  = 2,
+               },
+               .pddr                           = MCFGPIO_PDDR_BS,
+               .podr                           = MCFGPIO_PODR_BS,
+               .ppdr                           = MCFGPIO_PPDSDR_BS,
+               .setr                           = MCFGPIO_PPDSDR_BS,
+               .clrr                           = MCFGPIO_PCLRR_BS,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "IRQ",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 121,
+                       .ngpio                  = 7,
+               },
+               .pddr                           = MCFGPIO_PDDR_IRQ,
+               .podr                           = MCFGPIO_PODR_IRQ,
+               .ppdr                           = MCFGPIO_PPDSDR_IRQ,
+               .setr                           = MCFGPIO_PPDSDR_IRQ,
+               .clrr                           = MCFGPIO_PCLRR_IRQ,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "USBH",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 128,
+                       .ngpio                  = 1,
+               },
+               .pddr                           = MCFGPIO_PDDR_USBH,
+               .podr                           = MCFGPIO_PODR_USBH,
+               .ppdr                           = MCFGPIO_PPDSDR_USBH,
+               .setr                           = MCFGPIO_PPDSDR_USBH,
+               .clrr                           = MCFGPIO_PCLRR_USBH,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "USBL",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 136,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_PDDR_USBL,
+               .podr                           = MCFGPIO_PODR_USBL,
+               .ppdr                           = MCFGPIO_PPDSDR_USBL,
+               .setr                           = MCFGPIO_PPDSDR_USBL,
+               .clrr                           = MCFGPIO_PCLRR_USBL,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "UARTH",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 144,
+                       .ngpio                  = 4,
+               },
+               .pddr                           = MCFGPIO_PDDR_UARTH,
+               .podr                           = MCFGPIO_PODR_UARTH,
+               .ppdr                           = MCFGPIO_PPDSDR_UARTH,
+               .setr                           = MCFGPIO_PPDSDR_UARTH,
+               .clrr                           = MCFGPIO_PCLRR_UARTH,
+       },
+#endif
+};
+
+static int __init mcf_gpio_init(void)
+{
+       unsigned i = 0;
+       while (i < ARRAY_SIZE(mcf_gpio_chips))
+               (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
+       return 0;
+}
+
+core_initcall(mcf_gpio_init);
index 26135d92b34dff2e2a1305eb232ef8cc654cbd2c..3d90e6d92459bc0e4adcecffa84488032833ff8f 100644 (file)
@@ -14,5 +14,5 @@
 
 asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
-obj-y := config.o
+obj-y := config.o gpio.o
 
index a1d1a61c4fe667188fc1979df0630d7f5c7a547f..6e608d1836f1e5e69a5d8e9be2dc25add5301986 100644 (file)
@@ -3,8 +3,8 @@
 /*
  *     linux/arch/m68knommu/platform/528x/config.c
  *
- *     Sub-architcture dependant initialization code for the Motorola
- *     5280 and 5282 CPUs.
+ *     Sub-architcture dependant initialization code for the Freescale
+ *     5280, 5281 and 5282 CPUs.
  *
  *     Copyright (C) 1999-2003, Greg Ungerer (gerg@snapgear.com)
  *     Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com)
 #include <linux/kernel.h>
 #include <linux/param.h>
 #include <linux/init.h>
-#include <linux/interrupt.h>
 #include <linux/platform_device.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/flash.h>
 #include <linux/io.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
 #include <asm/mcfuart.h>
 
-#ifdef CONFIG_MTD_PARTITIONS
-#include <linux/mtd/partitions.h>
-#endif
-
 /***************************************************************************/
 
 static struct mcf_platform_uart m528x_uart_platform[] = {
@@ -91,23 +84,13 @@ static struct platform_device *m528x_devices[] __initdata = {
 
 /***************************************************************************/
 
-#define        INTC0   (MCF_MBAR + MCFICM_INTC0)
-
 static void __init m528x_uart_init_line(int line, int irq)
 {
        u8 port;
-       u32 imr;
 
        if ((line < 0) || (line > 2))
                return;
 
-       /* level 6, line based priority */
-       writeb(0x30+line, INTC0 + MCFINTC_ICR0 + MCFINT_UART0 + line);
-
-       imr = readl(INTC0 + MCFINTC_IMRL);
-       imr &= ~((1 << (irq - MCFINT_VECBASE)) | 1);
-       writel(imr, INTC0 + MCFINTC_IMRL);
-
        /* make sure PUAPAR is set for UART0 and UART1 */
        if (line < 2) {
                port = readb(MCF_MBAR + MCF5282_GPIO_PUAPAR);
@@ -129,21 +112,8 @@ static void __init m528x_uarts_init(void)
 
 static void __init m528x_fec_init(void)
 {
-       u32 imr;
        u16 v16;
 
-       /* Unmask FEC interrupts at ColdFire interrupt controller */
-       writeb(0x28, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 23);
-       writeb(0x27, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 27);
-       writeb(0x26, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 29);
-
-       imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
-       imr &= ~0xf;
-       writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
-       imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
-       imr &= ~0xff800001;
-       writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
-
        /* Set multi-function pins to ethernet mode for fec0 */
        v16 = readw(MCF_IPSBAR + 0x100056);
        writew(v16 | 0xf00, MCF_IPSBAR + 0x100056);
@@ -152,21 +122,6 @@ static void __init m528x_fec_init(void)
 
 /***************************************************************************/
 
-void mcf_disableall(void)
-{
-       *((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff;
-       *((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL)) = 0xffffffff;
-}
-
-/***************************************************************************/
-
-void mcf_autovector(unsigned int vec)
-{
-       /* Everything is auto-vectored on the 5272 */
-}
-
-/***************************************************************************/
-
 static void m528x_cpu_reset(void)
 {
        local_irq_disable();
@@ -204,8 +159,6 @@ void wildfiremod_halt(void)
 
 void __init config_BSP(char *commandp, int size)
 {
-       mcf_disableall();
-
 #ifdef CONFIG_WILDFIRE
        mach_halt = wildfire_halt;
 #endif
diff --git a/arch/m68knommu/platform/528x/gpio.c b/arch/m68knommu/platform/528x/gpio.c
new file mode 100644 (file)
index 0000000..ec59395
--- /dev/null
@@ -0,0 +1,438 @@
+/*
+ * Coldfire generic GPIO support
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/init.h>
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfgpio.h>
+
+static struct mcf_gpio_chip mcf_gpio_chips[] = {
+       {
+               .gpio_chip                      = {
+                       .label                  = "NQ",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value,
+                       .base                   = 1,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFEPORT_EPDDR,
+               .podr                           = MCFEPORT_EPDR,
+               .ppdr                           = MCFEPORT_EPPDR,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "TA",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 8,
+                       .ngpio                  = 4,
+               },
+               .pddr                           = MCFGPTA_GPTDDR,
+               .podr                           = MCFGPTA_GPTPORT,
+               .ppdr                           = MCFGPTB_GPTPORT,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "TB",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 16,
+                       .ngpio                  = 4,
+               },
+               .pddr                           = MCFGPTB_GPTDDR,
+               .podr                           = MCFGPTB_GPTPORT,
+               .ppdr                           = MCFGPTB_GPTPORT,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "QA",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 24,
+                       .ngpio                  = 4,
+               },
+               .pddr                           = MCFQADC_DDRQA,
+               .podr                           = MCFQADC_PORTQA,
+               .ppdr                           = MCFQADC_PORTQA,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "QB",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 32,
+                       .ngpio                  = 4,
+               },
+               .pddr                           = MCFQADC_DDRQB,
+               .podr                           = MCFQADC_PORTQB,
+               .ppdr                           = MCFQADC_PORTQB,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "A",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 40,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_DDRA,
+               .podr                           = MCFGPIO_PORTA,
+               .ppdr                           = MCFGPIO_PORTAP,
+               .setr                           = MCFGPIO_SETA,
+               .clrr                           = MCFGPIO_CLRA,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "B",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 48,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_DDRB,
+               .podr                           = MCFGPIO_PORTB,
+               .ppdr                           = MCFGPIO_PORTBP,
+               .setr                           = MCFGPIO_SETB,
+               .clrr                           = MCFGPIO_CLRB,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "C",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 56,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_DDRC,
+               .podr                           = MCFGPIO_PORTC,
+               .ppdr                           = MCFGPIO_PORTCP,
+               .setr                           = MCFGPIO_SETC,
+               .clrr                           = MCFGPIO_CLRC,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "D",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 64,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_DDRD,
+               .podr                           = MCFGPIO_PORTD,
+               .ppdr                           = MCFGPIO_PORTDP,
+               .setr                           = MCFGPIO_SETD,
+               .clrr                           = MCFGPIO_CLRD,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "E",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 72,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_DDRE,
+               .podr                           = MCFGPIO_PORTE,
+               .ppdr                           = MCFGPIO_PORTEP,
+               .setr                           = MCFGPIO_SETE,
+               .clrr                           = MCFGPIO_CLRE,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "F",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 80,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_DDRF,
+               .podr                           = MCFGPIO_PORTF,
+               .ppdr                           = MCFGPIO_PORTFP,
+               .setr                           = MCFGPIO_SETF,
+               .clrr                           = MCFGPIO_CLRF,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "G",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 88,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_DDRG,
+               .podr                           = MCFGPIO_PORTG,
+               .ppdr                           = MCFGPIO_PORTGP,
+               .setr                           = MCFGPIO_SETG,
+               .clrr                           = MCFGPIO_CLRG,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "H",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 96,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_DDRH,
+               .podr                           = MCFGPIO_PORTH,
+               .ppdr                           = MCFGPIO_PORTHP,
+               .setr                           = MCFGPIO_SETH,
+               .clrr                           = MCFGPIO_CLRH,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "J",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 104,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_DDRJ,
+               .podr                           = MCFGPIO_PORTJ,
+               .ppdr                           = MCFGPIO_PORTJP,
+               .setr                           = MCFGPIO_SETJ,
+               .clrr                           = MCFGPIO_CLRJ,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "DD",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 112,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_DDRDD,
+               .podr                           = MCFGPIO_PORTDD,
+               .ppdr                           = MCFGPIO_PORTDDP,
+               .setr                           = MCFGPIO_SETDD,
+               .clrr                           = MCFGPIO_CLRDD,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "EH",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 120,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_DDREH,
+               .podr                           = MCFGPIO_PORTEH,
+               .ppdr                           = MCFGPIO_PORTEHP,
+               .setr                           = MCFGPIO_SETEH,
+               .clrr                           = MCFGPIO_CLREH,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "EL",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 128,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_DDREL,
+               .podr                           = MCFGPIO_PORTEL,
+               .ppdr                           = MCFGPIO_PORTELP,
+               .setr                           = MCFGPIO_SETEL,
+               .clrr                           = MCFGPIO_CLREL,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "AS",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 136,
+                       .ngpio                  = 6,
+               },
+               .pddr                           = MCFGPIO_DDRAS,
+               .podr                           = MCFGPIO_PORTAS,
+               .ppdr                           = MCFGPIO_PORTASP,
+               .setr                           = MCFGPIO_SETAS,
+               .clrr                           = MCFGPIO_CLRAS,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "QS",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 144,
+                       .ngpio                  = 7,
+               },
+               .pddr                           = MCFGPIO_DDRQS,
+               .podr                           = MCFGPIO_PORTQS,
+               .ppdr                           = MCFGPIO_PORTQSP,
+               .setr                           = MCFGPIO_SETQS,
+               .clrr                           = MCFGPIO_CLRQS,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "SD",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 152,
+                       .ngpio                  = 6,
+               },
+               .pddr                           = MCFGPIO_DDRSD,
+               .podr                           = MCFGPIO_PORTSD,
+               .ppdr                           = MCFGPIO_PORTSDP,
+               .setr                           = MCFGPIO_SETSD,
+               .clrr                           = MCFGPIO_CLRSD,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "TC",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 160,
+                       .ngpio                  = 4,
+               },
+               .pddr                           = MCFGPIO_DDRTC,
+               .podr                           = MCFGPIO_PORTTC,
+               .ppdr                           = MCFGPIO_PORTTCP,
+               .setr                           = MCFGPIO_SETTC,
+               .clrr                           = MCFGPIO_CLRTC,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "TD",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 168,
+                       .ngpio                  = 4,
+               },
+               .pddr                           = MCFGPIO_DDRTD,
+               .podr                           = MCFGPIO_PORTTD,
+               .ppdr                           = MCFGPIO_PORTTDP,
+               .setr                           = MCFGPIO_SETTD,
+               .clrr                           = MCFGPIO_CLRTD,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "UA",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 176,
+                       .ngpio                  = 4,
+               },
+               .pddr                           = MCFGPIO_DDRUA,
+               .podr                           = MCFGPIO_PORTUA,
+               .ppdr                           = MCFGPIO_PORTUAP,
+               .setr                           = MCFGPIO_SETUA,
+               .clrr                           = MCFGPIO_CLRUA,
+       },
+};
+
+static int __init mcf_gpio_init(void)
+{
+       unsigned i = 0;
+       while (i < ARRAY_SIZE(mcf_gpio_chips))
+               (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
+       return 0;
+}
+
+core_initcall(mcf_gpio_init);
index cfd586860fd8aba5c48345b7adafcf5049b0a2ec..667db6598451e64ff9a2d0035e2d75b84c69ec2f 100644 (file)
@@ -14,5 +14,5 @@
 
 asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
-obj-y  += config.o
+obj-y  += config.o gpio.o
 
index 39da9e9ff674ef87a315a166f168fb979c250833..00900ac06a9c9e4cdb51780b5741447c940a5e6a 100644 (file)
 
 /***************************************************************************/
 
-extern unsigned int mcf_timervector;
-extern unsigned int mcf_profilevector;
-extern unsigned int mcf_timerlevel;
-
-/***************************************************************************/
-
 /*
  *     Some platforms need software versions of the GPIO data registers.
  */
@@ -64,11 +58,11 @@ static void __init m5307_uart_init_line(int line, int irq)
        if (line == 0) {
                writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
                writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR);
-               mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
+               mcf_mapirq2imr(irq, MCFINTC_UART0);
        } else if (line == 1) {
                writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
                writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR);
-               mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
+               mcf_mapirq2imr(irq, MCFINTC_UART1);
        }
 }
 
@@ -83,35 +77,19 @@ static void __init m5307_uarts_init(void)
 
 /***************************************************************************/
 
-void mcf_autovector(unsigned int vec)
-{
-       volatile unsigned char  *mbar;
-
-       if ((vec >= 25) && (vec <= 31)) {
-               mbar = (volatile unsigned char *) MCF_MBAR;
-               vec = 0x1 << (vec - 24);
-               *(mbar + MCFSIM_AVR) |= vec;
-               mcf_setimr(mcf_getimr() & ~vec);
-       }
-}
-
-/***************************************************************************/
-
-void mcf_settimericr(unsigned int timer, unsigned int level)
+static void __init m5307_timers_init(void)
 {
-       volatile unsigned char *icrp;
-       unsigned int icr, imr;
-
-       if (timer <= 2) {
-               switch (timer) {
-               case 2:  icr = MCFSIM_TIMER2ICR; imr = MCFSIM_IMR_TIMER2; break;
-               default: icr = MCFSIM_TIMER1ICR; imr = MCFSIM_IMR_TIMER1; break;
-               }
-
-               icrp = (volatile unsigned char *) (MCF_MBAR + icr);
-               *icrp = MCFSIM_ICR_AUTOVEC | (level << 2) | MCFSIM_ICR_PRI3;
-               mcf_setimr(mcf_getimr() & ~imr);
-       }
+       /* Timer1 is always used as system timer */
+       writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3,
+               MCF_MBAR + MCFSIM_TIMER1ICR);
+       mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1);
+
+#ifdef CONFIG_HIGHPROFILE
+       /* Timer2 is to be used as a high speed profile timer  */
+       writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3,
+               MCF_MBAR + MCFSIM_TIMER2ICR);
+       mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2);
+#endif
 }
 
 /***************************************************************************/
@@ -129,20 +107,22 @@ void m5307_cpu_reset(void)
 
 void __init config_BSP(char *commandp, int size)
 {
-       mcf_setimr(MCFSIM_IMR_MASKALL);
-
 #if defined(CONFIG_NETtel) || \
     defined(CONFIG_SECUREEDGEMP3) || defined(CONFIG_CLEOPATRA)
        /* Copy command line from FLASH to local buffer... */
        memcpy(commandp, (char *) 0xf0004000, size);
        commandp[size-1] = 0;
-       /* Different timer setup - to prevent device clash */
-       mcf_timervector = 30;
-       mcf_profilevector = 31;
-       mcf_timerlevel = 6;
 #endif
 
        mach_reset = m5307_cpu_reset;
+       m5307_timers_init();
+       m5307_uarts_init();
+
+       /* Only support the external interrupts on their primary level */
+       mcf_mapirq2imr(25, MCFINTC_EINT1);
+       mcf_mapirq2imr(27, MCFINTC_EINT3);
+       mcf_mapirq2imr(29, MCFINTC_EINT5);
+       mcf_mapirq2imr(31, MCFINTC_EINT7);
 
 #ifdef CONFIG_BDM_DISABLE
        /*
@@ -158,7 +138,6 @@ void __init config_BSP(char *commandp, int size)
 
 static int __init init_BSP(void)
 {
-       m5307_uarts_init();
        platform_add_devices(m5307_devices, ARRAY_SIZE(m5307_devices));
        return 0;
 }
diff --git a/arch/m68knommu/platform/5307/gpio.c b/arch/m68knommu/platform/5307/gpio.c
new file mode 100644 (file)
index 0000000..8da5880
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Coldfire generic GPIO support
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/init.h>
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfgpio.h>
+
+static struct mcf_gpio_chip mcf_gpio_chips[] = {
+       {
+               .gpio_chip                      = {
+                       .label                  = "PP",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value,
+                       .ngpio                  = 16,
+               },
+               .pddr                           = MCFSIM_PADDR,
+               .podr                           = MCFSIM_PADAT,
+               .ppdr                           = MCFSIM_PADAT,
+       },
+};
+
+static int __init mcf_gpio_init(void)
+{
+       unsigned i = 0;
+       while (i < ARRAY_SIZE(mcf_gpio_chips))
+               (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
+       return 0;
+}
+
+core_initcall(mcf_gpio_init);
index e431912f56281adc6b2a3c617d84d2aab0f40cda..4cc23245bcd1e1192236a06032d5f1fe62d20fef 100644 (file)
@@ -15,4 +15,4 @@
 asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
 #obj-y := config.o usb-mcf532x.o spi-mcf532x.o
-obj-y := config.o
+obj-y := config.o gpio.o
index cdb761971f7a7e8ca479766aeb2271d0688c52bf..d632948e64e53602d3714197852f441d3288cf78 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/kernel.h>
 #include <linux/param.h>
 #include <linux/init.h>
-#include <linux/interrupt.h>
 #include <linux/io.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 
 /***************************************************************************/
 
-extern unsigned int mcf_timervector;
-extern unsigned int mcf_profilevector;
-extern unsigned int mcf_timerlevel;
-
-/***************************************************************************/
-
 static struct mcf_platform_uart m532x_uart_platform[] = {
        {
                .mapbase        = MCFUART_BASE1,
@@ -88,6 +81,7 @@ static struct platform_device m532x_fec = {
        .num_resources          = ARRAY_SIZE(m532x_fec_resources),
        .resource               = m532x_fec_resources,
 };
+
 static struct platform_device *m532x_devices[] __initdata = {
        &m532x_uart,
        &m532x_fec,
@@ -98,18 +92,11 @@ static struct platform_device *m532x_devices[] __initdata = {
 static void __init m532x_uart_init_line(int line, int irq)
 {
        if (line == 0) {
-               MCF_INTC0_ICR26 = 0x3;
-               MCF_INTC0_CIMR = 26;
                /* GPIO initialization */
                MCF_GPIO_PAR_UART |= 0x000F;
        } else if (line == 1) {
-               MCF_INTC0_ICR27 = 0x3;
-               MCF_INTC0_CIMR = 27;
                /* GPIO initialization */
                MCF_GPIO_PAR_UART |= 0x0FF0;
-       } else if (line == 2) {
-               MCF_INTC0_ICR28 = 0x3;
-               MCF_INTC0_CIMR = 28;
        }
 }
 
@@ -125,14 +112,6 @@ static void __init m532x_uarts_init(void)
 
 static void __init m532x_fec_init(void)
 {
-       /* Unmask FEC interrupts at ColdFire interrupt controller */
-       MCF_INTC0_ICR36 = 0x2;
-       MCF_INTC0_ICR40 = 0x2;
-       MCF_INTC0_ICR42 = 0x2;
-
-       MCF_INTC0_IMRH &= ~(MCF_INTC_IMRH_INT_MASK36 |
-               MCF_INTC_IMRH_INT_MASK40 | MCF_INTC_IMRH_INT_MASK42);
-
        /* Set multi-function pins to ethernet mode for fec0 */
        MCF_GPIO_PAR_FECI2C |= (MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC |
                MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO);
@@ -142,26 +121,6 @@ static void __init m532x_fec_init(void)
 
 /***************************************************************************/
 
-void mcf_settimericr(unsigned int timer, unsigned int level)
-{
-       volatile unsigned char *icrp;
-       unsigned int icr;
-       unsigned char irq;
-
-       if (timer <= 2) {
-               switch (timer) {
-               case 2:  irq = 33; icr = MCFSIM_ICR_TIMER2; break;
-               default: irq = 32; icr = MCFSIM_ICR_TIMER1; break;
-               }
-               
-               icrp = (volatile unsigned char *) (icr);
-               *icrp = level;
-               mcf_enable_irq0(irq);
-       }
-}
-
-/***************************************************************************/
-
 static void m532x_cpu_reset(void)
 {
        local_irq_disable();
@@ -172,8 +131,6 @@ static void m532x_cpu_reset(void)
 
 void __init config_BSP(char *commandp, int size)
 {
-       mcf_setimr(MCFSIM_IMR_MASKALL);
-
 #if !defined(CONFIG_BOOTPARAM)
        /* Copy command line from FLASH to local buffer... */
        memcpy(commandp, (char *) 0x4000, 4);
@@ -185,10 +142,6 @@ void __init config_BSP(char *commandp, int size)
        }
 #endif
 
-       mcf_timervector = 64+32;
-       mcf_profilevector = 64+33;
-       mach_reset = m532x_cpu_reset;
-
 #ifdef CONFIG_BDM_DISABLE
        /*
         * Disable the BDM clocking.  This also turns off most of the rest of
@@ -438,8 +391,8 @@ void gpio_init(void)
        /* Initialize TIN3 as a GPIO output to enable the write
           half of the latch */
        MCF_GPIO_PAR_TIMER = 0x00;
-       MCF_GPIO_PDDR_TIMER = 0x08;
-       MCF_GPIO_PCLRR_TIMER = 0x0;
+       __raw_writeb(0x08, MCFGPIO_PDDR_TIMER);
+       __raw_writeb(0x00, MCFGPIO_PCLRR_TIMER);
 
 }
 
diff --git a/arch/m68knommu/platform/532x/gpio.c b/arch/m68knommu/platform/532x/gpio.c
new file mode 100644 (file)
index 0000000..184b773
--- /dev/null
@@ -0,0 +1,337 @@
+/*
+ * Coldfire generic GPIO support
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/init.h>
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfgpio.h>
+
+static struct mcf_gpio_chip mcf_gpio_chips[] = {
+       {
+               .gpio_chip                      = {
+                       .label                  = "PIRQ",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFEPORT_EPDDR,
+               .podr                           = MCFEPORT_EPDR,
+               .ppdr                           = MCFEPORT_EPPDR,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "FECH",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 8,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_PDDR_FECH,
+               .podr                           = MCFGPIO_PODR_FECH,
+               .ppdr                           = MCFGPIO_PPDSDR_FECH,
+               .setr                           = MCFGPIO_PPDSDR_FECH,
+               .clrr                           = MCFGPIO_PCLRR_FECH,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "FECL",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 16,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_PDDR_FECL,
+               .podr                           = MCFGPIO_PODR_FECL,
+               .ppdr                           = MCFGPIO_PPDSDR_FECL,
+               .setr                           = MCFGPIO_PPDSDR_FECL,
+               .clrr                           = MCFGPIO_PCLRR_FECL,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "SSI",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 24,
+                       .ngpio                  = 5,
+               },
+               .pddr                           = MCFGPIO_PDDR_SSI,
+               .podr                           = MCFGPIO_PODR_SSI,
+               .ppdr                           = MCFGPIO_PPDSDR_SSI,
+               .setr                           = MCFGPIO_PPDSDR_SSI,
+               .clrr                           = MCFGPIO_PCLRR_SSI,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "BUSCTL",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 32,
+                       .ngpio                  = 4,
+               },
+               .pddr                           = MCFGPIO_PDDR_BUSCTL,
+               .podr                           = MCFGPIO_PODR_BUSCTL,
+               .ppdr                           = MCFGPIO_PPDSDR_BUSCTL,
+               .setr                           = MCFGPIO_PPDSDR_BUSCTL,
+               .clrr                           = MCFGPIO_PCLRR_BUSCTL,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "BE",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 40,
+                       .ngpio                  = 4,
+               },
+               .pddr                           = MCFGPIO_PDDR_BE,
+               .podr                           = MCFGPIO_PODR_BE,
+               .ppdr                           = MCFGPIO_PPDSDR_BE,
+               .setr                           = MCFGPIO_PPDSDR_BE,
+               .clrr                           = MCFGPIO_PCLRR_BE,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "CS",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 49,
+                       .ngpio                  = 5,
+               },
+               .pddr                           = MCFGPIO_PDDR_CS,
+               .podr                           = MCFGPIO_PODR_CS,
+               .ppdr                           = MCFGPIO_PPDSDR_CS,
+               .setr                           = MCFGPIO_PPDSDR_CS,
+               .clrr                           = MCFGPIO_PCLRR_CS,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "PWM",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 58,
+                       .ngpio                  = 4,
+               },
+               .pddr                           = MCFGPIO_PDDR_PWM,
+               .podr                           = MCFGPIO_PODR_PWM,
+               .ppdr                           = MCFGPIO_PPDSDR_PWM,
+               .setr                           = MCFGPIO_PPDSDR_PWM,
+               .clrr                           = MCFGPIO_PCLRR_PWM,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "FECI2C",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 64,
+                       .ngpio                  = 4,
+               },
+               .pddr                           = MCFGPIO_PDDR_FECI2C,
+               .podr                           = MCFGPIO_PODR_FECI2C,
+               .ppdr                           = MCFGPIO_PPDSDR_FECI2C,
+               .setr                           = MCFGPIO_PPDSDR_FECI2C,
+               .clrr                           = MCFGPIO_PCLRR_FECI2C,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "UART",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 72,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_PDDR_UART,
+               .podr                           = MCFGPIO_PODR_UART,
+               .ppdr                           = MCFGPIO_PPDSDR_UART,
+               .setr                           = MCFGPIO_PPDSDR_UART,
+               .clrr                           = MCFGPIO_PCLRR_UART,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "QSPI",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 80,
+                       .ngpio                  = 6,
+               },
+               .pddr                           = MCFGPIO_PDDR_QSPI,
+               .podr                           = MCFGPIO_PODR_QSPI,
+               .ppdr                           = MCFGPIO_PPDSDR_QSPI,
+               .setr                           = MCFGPIO_PPDSDR_QSPI,
+               .clrr                           = MCFGPIO_PCLRR_QSPI,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "TIMER",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 88,
+                       .ngpio                  = 4,
+               },
+               .pddr                           = MCFGPIO_PDDR_TIMER,
+               .podr                           = MCFGPIO_PODR_TIMER,
+               .ppdr                           = MCFGPIO_PPDSDR_TIMER,
+               .setr                           = MCFGPIO_PPDSDR_TIMER,
+               .clrr                           = MCFGPIO_PCLRR_TIMER,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "LCDDATAH",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 96,
+                       .ngpio                  = 2,
+               },
+               .pddr                           = MCFGPIO_PDDR_LCDDATAH,
+               .podr                           = MCFGPIO_PODR_LCDDATAH,
+               .ppdr                           = MCFGPIO_PPDSDR_LCDDATAH,
+               .setr                           = MCFGPIO_PPDSDR_LCDDATAH,
+               .clrr                           = MCFGPIO_PCLRR_LCDDATAH,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "LCDDATAM",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 104,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_PDDR_LCDDATAM,
+               .podr                           = MCFGPIO_PODR_LCDDATAM,
+               .ppdr                           = MCFGPIO_PPDSDR_LCDDATAM,
+               .setr                           = MCFGPIO_PPDSDR_LCDDATAM,
+               .clrr                           = MCFGPIO_PCLRR_LCDDATAM,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "LCDDATAL",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 112,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_PDDR_LCDDATAL,
+               .podr                           = MCFGPIO_PODR_LCDDATAL,
+               .ppdr                           = MCFGPIO_PPDSDR_LCDDATAL,
+               .setr                           = MCFGPIO_PPDSDR_LCDDATAL,
+               .clrr                           = MCFGPIO_PCLRR_LCDDATAL,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "LCDCTLH",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 120,
+                       .ngpio                  = 1,
+               },
+               .pddr                           = MCFGPIO_PDDR_LCDCTLH,
+               .podr                           = MCFGPIO_PODR_LCDCTLH,
+               .ppdr                           = MCFGPIO_PPDSDR_LCDCTLH,
+               .setr                           = MCFGPIO_PPDSDR_LCDCTLH,
+               .clrr                           = MCFGPIO_PCLRR_LCDCTLH,
+       },
+       {
+               .gpio_chip                      = {
+                       .label                  = "LCDCTLL",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value_fast,
+                       .base                   = 128,
+                       .ngpio                  = 8,
+               },
+               .pddr                           = MCFGPIO_PDDR_LCDCTLL,
+               .podr                           = MCFGPIO_PODR_LCDCTLL,
+               .ppdr                           = MCFGPIO_PPDSDR_LCDCTLL,
+               .setr                           = MCFGPIO_PPDSDR_LCDCTLL,
+               .clrr                           = MCFGPIO_PCLRR_LCDCTLL,
+       },
+};
+
+static int __init mcf_gpio_init(void)
+{
+       unsigned i = 0;
+       while (i < ARRAY_SIZE(mcf_gpio_chips))
+               (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
+       return 0;
+}
+
+core_initcall(mcf_gpio_init);
index e6035e7a2d3fd6be81c18d23c74cc37135d53aae..dee62c5dbaa6890e4a7d51923907fab46fb2cb72 100644 (file)
@@ -14,5 +14,5 @@
 
 asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
-obj-y := config.o
+obj-y := config.o gpio.o
 
index b41d942bf8d07e3bf0079bc53a1e0432b41daa93..70ea789a400c7cfd0df53783b3dd61b539c05771 100644 (file)
 
 /***************************************************************************/
 
-extern unsigned int mcf_timervector;
-extern unsigned int mcf_profilevector;
-extern unsigned int mcf_timerlevel;
-
-/***************************************************************************/
-
 static struct mcf_platform_uart m5407_uart_platform[] = {
        {
                .mapbase        = MCF_MBAR + MCFUART_BASE1,
@@ -55,11 +49,11 @@ static void __init m5407_uart_init_line(int line, int irq)
        if (line == 0) {
                writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
                writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR);
-               mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
+               mcf_mapirq2imr(irq, MCFINTC_UART0);
        } else if (line == 1) {
                writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
                writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR);
-               mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
+               mcf_mapirq2imr(irq, MCFINTC_UART1);
        }
 }
 
@@ -74,35 +68,19 @@ static void __init m5407_uarts_init(void)
 
 /***************************************************************************/
 
-void mcf_autovector(unsigned int vec)
-{
-       volatile unsigned char  *mbar;
-
-       if ((vec >= 25) && (vec <= 31)) {
-               mbar = (volatile unsigned char *) MCF_MBAR;
-               vec = 0x1 << (vec - 24);
-               *(mbar + MCFSIM_AVR) |= vec;
-               mcf_setimr(mcf_getimr() & ~vec);
-       }
-}
-
-/***************************************************************************/
-
-void mcf_settimericr(unsigned int timer, unsigned int level)
+static void __init m5407_timers_init(void)
 {
-       volatile unsigned char *icrp;
-       unsigned int icr, imr;
-
-       if (timer <= 2) {
-               switch (timer) {
-               case 2:  icr = MCFSIM_TIMER2ICR; imr = MCFSIM_IMR_TIMER2; break;
-               default: icr = MCFSIM_TIMER1ICR; imr = MCFSIM_IMR_TIMER1; break;
-               }
-
-               icrp = (volatile unsigned char *) (MCF_MBAR + icr);
-               *icrp = MCFSIM_ICR_AUTOVEC | (level << 2) | MCFSIM_ICR_PRI3;
-               mcf_setimr(mcf_getimr() & ~imr);
-       }
+       /* Timer1 is always used as system timer */
+       writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3,
+               MCF_MBAR + MCFSIM_TIMER1ICR);
+       mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1);
+
+#ifdef CONFIG_HIGHPROFILE
+       /* Timer2 is to be used as a high speed profile timer  */
+       writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3,
+               MCF_MBAR + MCFSIM_TIMER2ICR);
+       mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2);
+#endif
 }
 
 /***************************************************************************/
@@ -120,23 +98,21 @@ void m5407_cpu_reset(void)
 
 void __init config_BSP(char *commandp, int size)
 {
-       mcf_setimr(MCFSIM_IMR_MASKALL);
-
-#if defined(CONFIG_CLEOPATRA)
-       /* Different timer setup - to prevent device clash */
-       mcf_timervector = 30;
-       mcf_profilevector = 31;
-       mcf_timerlevel = 6;
-#endif
-
        mach_reset = m5407_cpu_reset;
+       m5407_timers_init();
+       m5407_uarts_init();
+
+       /* Only support the external interrupts on their primary level */
+       mcf_mapirq2imr(25, MCFINTC_EINT1);
+       mcf_mapirq2imr(27, MCFINTC_EINT3);
+       mcf_mapirq2imr(29, MCFINTC_EINT5);
+       mcf_mapirq2imr(31, MCFINTC_EINT7);
 }
 
 /***************************************************************************/
 
 static int __init init_BSP(void)
 {
-       m5407_uarts_init();
        platform_add_devices(m5407_devices, ARRAY_SIZE(m5407_devices));
        return 0;
 }
diff --git a/arch/m68knommu/platform/5407/gpio.c b/arch/m68knommu/platform/5407/gpio.c
new file mode 100644 (file)
index 0000000..8da5880
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Coldfire generic GPIO support
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/init.h>
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfgpio.h>
+
+static struct mcf_gpio_chip mcf_gpio_chips[] = {
+       {
+               .gpio_chip                      = {
+                       .label                  = "PP",
+                       .request                = mcf_gpio_request,
+                       .free                   = mcf_gpio_free,
+                       .direction_input        = mcf_gpio_direction_input,
+                       .direction_output       = mcf_gpio_direction_output,
+                       .get                    = mcf_gpio_get_value,
+                       .set                    = mcf_gpio_set_value,
+                       .ngpio                  = 16,
+               },
+               .pddr                           = MCFSIM_PADDR,
+               .podr                           = MCFSIM_PADAT,
+               .ppdr                           = MCFSIM_PADAT,
+       },
+};
+
+static int __init mcf_gpio_init(void)
+{
+       unsigned i = 0;
+       while (i < ARRAY_SIZE(mcf_gpio_chips))
+               (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
+       return 0;
+}
+
+core_initcall(mcf_gpio_init);
index 72e56d554f4f700d5f5c42205eeb337734d7ae46..b91ee85d4b5dbf7de464a6ab46350025f5cf78fb 100644 (file)
@@ -73,34 +73,6 @@ extern e_vector *_ramvec;
 /* The number of spurious interrupts */
 volatile unsigned int num_spurious;
 
-/*
- * This function should be called during kernel startup to initialize
- * the machine vector table.
- */
-void __init init_vectors(void)
-{
-       int i;
-
-       /* set up the vectors */
-       for (i = 72; i < 256; ++i)
-               _ramvec[i] = (e_vector) bad_interrupt;
-
-       _ramvec[32] = system_call;
-
-       _ramvec[65] = (e_vector) inthandler1;
-       _ramvec[66] = (e_vector) inthandler2;
-       _ramvec[67] = (e_vector) inthandler3;
-       _ramvec[68] = (e_vector) inthandler4;
-       _ramvec[69] = (e_vector) inthandler5;
-       _ramvec[70] = (e_vector) inthandler6;
-       _ramvec[71] = (e_vector) inthandler7;
-       IVR = 0x40; /* Set DragonBall IVR (interrupt base) to 64 */
-
-       /* turn off all interrupts */
-       IMR = ~0;
-}
-
 /* The 68k family did not have a good way to determine the source
  * of interrupts until later in the family.  The EC000 core does
  * not provide the vector number on the stack, we vector everything
@@ -163,18 +135,54 @@ void process_int(int vec, struct pt_regs *fp)
        }
 }
 
-void enable_vector(unsigned int irq)
+static void intc_irq_unmask(unsigned int irq)
 {
        IMR &= ~(1<<irq);
 }
 
-void disable_vector(unsigned int irq)
+static void intc_irq_mask(unsigned int irq)
 {
        IMR |= (1<<irq);
 }
 
-void ack_vector(unsigned int irq)
+static struct irq_chip intc_irq_chip = {
+       .name           = "M68K-INTC",
+       .mask           = intc_irq_mask,
+       .unmask         = intc_irq_unmask,
+};
+
+/*
+ * This function should be called during kernel startup to initialize
+ * the machine vector table.
+ */
+void __init init_IRQ(void)
 {
-       /* Nothing needed */
+       int i;
+
+       /* set up the vectors */
+       for (i = 72; i < 256; ++i)
+               _ramvec[i] = (e_vector) bad_interrupt;
+
+       _ramvec[32] = system_call;
+
+       _ramvec[65] = (e_vector) inthandler1;
+       _ramvec[66] = (e_vector) inthandler2;
+       _ramvec[67] = (e_vector) inthandler3;
+       _ramvec[68] = (e_vector) inthandler4;
+       _ramvec[69] = (e_vector) inthandler5;
+       _ramvec[70] = (e_vector) inthandler6;
+       _ramvec[71] = (e_vector) inthandler7;
+
+       IVR = 0x40; /* Set DragonBall IVR (interrupt base) to 64 */
+
+       /* turn off all interrupts */
+       IMR = ~0;
+
+       for (i = 0; (i < NR_IRQS); i++) {
+               irq_desc[i].status = IRQ_DISABLED;
+               irq_desc[i].action = NULL;
+               irq_desc[i].depth = 1;
+               irq_desc[i].chip = &intc_irq_chip;
+       }
 }
 
index c36781157e097016fd2822c82dd300c1c08d62e5..1143f77caca4d32d7739bd11b9e7c2118c0f7170 100644 (file)
@@ -37,11 +37,33 @@ extern void *_ramvec[];
 /* The number of spurious interrupts */
 volatile unsigned int num_spurious;
 
+static void intc_irq_unmask(unsigned int irq)
+{
+       pquicc->intr_cimr |= (1 << irq);
+}
+
+static void intc_irq_mask(unsigned int irq)
+{
+       pquicc->intr_cimr &= ~(1 << irq);
+}
+
+static void intc_irq_ack(unsigned int irq)
+{
+       pquicc->intr_cisr = (1 << irq);
+}
+
+static struct irq_chip intc_irq_chip = {
+       .name           = "M68K-INTC",
+       .mask           = intc_irq_mask,
+       .unmask         = intc_irq_unmask,
+       .ack            = intc_irq_ack,
+};
+
 /*
  * This function should be called during kernel startup to initialize
  * the vector table.
  */
-void init_vectors(void)
+void init_IRQ(void)
 {
        int i;
        int vba = (CPM_VECTOR_BASE<<4);
@@ -109,20 +131,12 @@ void init_vectors(void)
 
        /* turn off all CPM interrupts */
        pquicc->intr_cimr = 0x00000000;
-}
-
-void enable_vector(unsigned int irq)
-{
-       pquicc->intr_cimr |= (1 << irq);
-}
 
-void disable_vector(unsigned int irq)
-{
-       pquicc->intr_cimr &= ~(1 << irq);
-}
-
-void ack_vector(unsigned int irq)
-{
-       pquicc->intr_cisr = (1 << irq);
+       for (i = 0; (i < NR_IRQS); i++) {
+               irq_desc[i].status = IRQ_DISABLED;
+               irq_desc[i].action = NULL;
+               irq_desc[i].depth = 1;
+               irq_desc[i].chip = &intc_irq_chip;
+       }
 }
 
index 1bcb9372353fe8496966ce50f7a67cf2d32f80db..f72a0e5d9996a9a5104ca1d81171c2a701252dd9 100644 (file)
 asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
 obj-$(CONFIG_COLDFIRE) += clk.o dma.o entry.o vectors.o
-obj-$(CONFIG_M5206)    += timers.o
-obj-$(CONFIG_M5206e)   += timers.o
-obj-$(CONFIG_M520x)    += pit.o
-obj-$(CONFIG_M523x)    += pit.o dma_timer.o
-obj-$(CONFIG_M5249)    += timers.o
-obj-$(CONFIG_M527x)    += pit.o
+obj-$(CONFIG_M5206)    += timers.o intc.o
+obj-$(CONFIG_M5206e)   += timers.o intc.o
+obj-$(CONFIG_M520x)    += pit.o intc-simr.o
+obj-$(CONFIG_M523x)    += pit.o dma_timer.o intc-2.o
+obj-$(CONFIG_M5249)    += timers.o intc.o
+obj-$(CONFIG_M527x)    += pit.o intc-2.o
 obj-$(CONFIG_M5272)    += timers.o
-obj-$(CONFIG_M528x)    += pit.o
-obj-$(CONFIG_M5307)    += timers.o
-obj-$(CONFIG_M532x)    += timers.o
-obj-$(CONFIG_M5407)    += timers.o
+obj-$(CONFIG_M528x)    += pit.o intc-2.o
+obj-$(CONFIG_M5307)    += timers.o intc.o
+obj-$(CONFIG_M532x)    += timers.o intc-simr.o
+obj-$(CONFIG_M5407)    += timers.o intc.o
 
+obj-y                  += pinmux.o gpio.o
 extra-y := head.o
diff --git a/arch/m68knommu/platform/coldfire/gpio.c b/arch/m68knommu/platform/coldfire/gpio.c
new file mode 100644 (file)
index 0000000..ff00457
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Coldfire generic GPIO support.
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/init.h>
+#include <linux/sysdev.h>
+
+#include <asm/gpio.h>
+#include <asm/pinmux.h>
+#include <asm/mcfgpio.h>
+
+#define MCF_CHIP(chip) container_of(chip, struct mcf_gpio_chip, gpio_chip)
+
+int mcf_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+       unsigned long flags;
+       MCFGPIO_PORTTYPE dir;
+       struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
+
+       local_irq_save(flags);
+       dir = mcfgpio_read(mcf_chip->pddr);
+       dir &= ~mcfgpio_bit(chip->base + offset);
+       mcfgpio_write(dir, mcf_chip->pddr);
+       local_irq_restore(flags);
+
+       return 0;
+}
+
+int mcf_gpio_get_value(struct gpio_chip *chip, unsigned offset)
+{
+       struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
+
+       return mcfgpio_read(mcf_chip->ppdr) & mcfgpio_bit(chip->base + offset);
+}
+
+int mcf_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
+               int value)
+{
+       unsigned long flags;
+       MCFGPIO_PORTTYPE data;
+       struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
+
+       local_irq_save(flags);
+       /* write the value to the output latch */
+       data = mcfgpio_read(mcf_chip->podr);
+       if (value)
+               data |= mcfgpio_bit(chip->base + offset);
+       else
+               data &= ~mcfgpio_bit(chip->base + offset);
+       mcfgpio_write(data, mcf_chip->podr);
+
+       /* now set the direction to output */
+       data = mcfgpio_read(mcf_chip->pddr);
+       data |= mcfgpio_bit(chip->base + offset);
+       mcfgpio_write(data, mcf_chip->pddr);
+       local_irq_restore(flags);
+
+       return 0;
+}
+
+void mcf_gpio_set_value(struct gpio_chip *chip, unsigned offset, int value)
+{
+       struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
+
+       unsigned long flags;
+       MCFGPIO_PORTTYPE data;
+
+       local_irq_save(flags);
+       data = mcfgpio_read(mcf_chip->podr);
+       if (value)
+               data |= mcfgpio_bit(chip->base + offset);
+       else
+               data &= ~mcfgpio_bit(chip->base + offset);
+       mcfgpio_write(data, mcf_chip->podr);
+       local_irq_restore(flags);
+}
+
+void mcf_gpio_set_value_fast(struct gpio_chip *chip, unsigned offset, int value)
+{
+       struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
+
+       if (value)
+               mcfgpio_write(mcfgpio_bit(chip->base + offset), mcf_chip->setr);
+       else
+               mcfgpio_write(~mcfgpio_bit(chip->base + offset), mcf_chip->clrr);
+}
+
+int mcf_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+       struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
+
+       return mcf_chip->gpio_to_pinmux ?
+               mcf_pinmux_request(mcf_chip->gpio_to_pinmux[offset], 0) : 0;
+}
+
+void mcf_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+       struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
+
+       mcf_gpio_direction_input(chip, offset);
+
+       if (mcf_chip->gpio_to_pinmux)
+               mcf_pinmux_release(mcf_chip->gpio_to_pinmux[offset], 0);
+}
+
+struct sysdev_class mcf_gpio_sysclass = {
+       .name   = "gpio",
+};
+
+static int __init mcf_gpio_sysinit(void)
+{
+       return sysdev_class_register(&mcf_gpio_sysclass);
+}
+
+core_initcall(mcf_gpio_sysinit);
diff --git a/arch/m68knommu/platform/coldfire/intc-2.c b/arch/m68knommu/platform/coldfire/intc-2.c
new file mode 100644 (file)
index 0000000..5598c8b
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * intc-1.c
+ *
+ * (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/traps.h>
+
+/*
+ *     Each vector needs a unique priority and level asscoiated with it.
+ *     We don't really care so much what they are, we don't rely on the
+ *     tranditional priority interrupt scheme of the m68k/ColdFire.
+ */
+static u8 intc_intpri = 0x36;
+
+static void intc_irq_mask(unsigned int irq)
+{
+       if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECBASE + 128)) {
+               unsigned long imraddr;
+               u32 val, imrbit;
+
+               irq -= MCFINT_VECBASE;
+               imraddr = MCF_IPSBAR;
+               imraddr += (irq & 0x40) ? MCFICM_INTC1 : MCFICM_INTC0;
+               imraddr += (irq & 0x20) ? MCFINTC_IMRH : MCFINTC_IMRL;
+               imrbit = 0x1 << (irq & 0x1f);
+
+               val = __raw_readl(imraddr);
+               __raw_writel(val | imrbit, imraddr);
+       }
+}
+
+static void intc_irq_unmask(unsigned int irq)
+{
+       if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECBASE + 128)) {
+               unsigned long intaddr, imraddr, icraddr;
+               u32 val, imrbit;
+
+               irq -= MCFINT_VECBASE;
+               intaddr = MCF_IPSBAR;
+               intaddr += (irq & 0x40) ? MCFICM_INTC1 : MCFICM_INTC0;
+               imraddr = intaddr + ((irq & 0x20) ? MCFINTC_IMRH : MCFINTC_IMRL);
+               icraddr = intaddr + MCFINTC_ICR0 + (irq & 0x3f);
+               imrbit = 0x1 << (irq & 0x1f);
+
+               /* Don't set the "maskall" bit! */
+               if ((irq & 0x20) == 0)
+                       imrbit |= 0x1;
+
+               if (__raw_readb(icraddr) == 0)
+                       __raw_writeb(intc_intpri--, icraddr);
+
+               val = __raw_readl(imraddr);
+               __raw_writel(val & ~imrbit, imraddr);
+       }
+}
+
+static struct irq_chip intc_irq_chip = {
+       .name           = "CF-INTC",
+       .mask           = intc_irq_mask,
+       .unmask         = intc_irq_unmask,
+};
+
+void __init init_IRQ(void)
+{
+       int irq;
+
+       init_vectors();
+
+       /* Mask all interrupt sources */
+       __raw_writel(0x1, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
+       __raw_writel(0x1, MCF_IPSBAR + MCFICM_INTC1 + MCFINTC_IMRL);
+
+       for (irq = 0; (irq < NR_IRQS); irq++) {
+               irq_desc[irq].status = IRQ_DISABLED;
+               irq_desc[irq].action = NULL;
+               irq_desc[irq].depth = 1;
+               irq_desc[irq].chip = &intc_irq_chip;
+       }
+}
+
diff --git a/arch/m68knommu/platform/coldfire/intc-simr.c b/arch/m68knommu/platform/coldfire/intc-simr.c
new file mode 100644 (file)
index 0000000..1b01e79
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * intc-simr.c
+ *
+ * (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/traps.h>
+
+static void intc_irq_mask(unsigned int irq)
+{
+       if (irq >= MCFINT_VECBASE) {
+               if (irq < MCFINT_VECBASE + 64)
+                       __raw_writeb(irq - MCFINT_VECBASE, MCFINTC0_SIMR);
+               else if ((irq < MCFINT_VECBASE + 128) && MCFINTC1_SIMR)
+                       __raw_writeb(irq - MCFINT_VECBASE - 64, MCFINTC1_SIMR);
+       }
+}
+
+static void intc_irq_unmask(unsigned int irq)
+{
+       if (irq >= MCFINT_VECBASE) {
+               if (irq < MCFINT_VECBASE + 64)
+                       __raw_writeb(irq - MCFINT_VECBASE, MCFINTC0_CIMR);
+               else if ((irq < MCFINT_VECBASE + 128) && MCFINTC1_CIMR)
+                       __raw_writeb(irq - MCFINT_VECBASE - 64, MCFINTC1_CIMR);
+       }
+}
+
+static int intc_irq_set_type(unsigned int irq, unsigned int type)
+{
+       if (irq >= MCFINT_VECBASE) {
+               if (irq < MCFINT_VECBASE + 64)
+                       __raw_writeb(5, MCFINTC0_ICR0 + irq - MCFINT_VECBASE);
+               else if ((irq < MCFINT_VECBASE) && MCFINTC1_ICR0)
+                       __raw_writeb(5, MCFINTC1_ICR0 + irq - MCFINT_VECBASE - 64);
+       }
+       return 0;
+}
+
+static struct irq_chip intc_irq_chip = {
+       .name           = "CF-INTC",
+       .mask           = intc_irq_mask,
+       .unmask         = intc_irq_unmask,
+       .set_type       = intc_irq_set_type,
+};
+
+void __init init_IRQ(void)
+{
+       int irq;
+
+       init_vectors();
+
+       /* Mask all interrupt sources */
+       __raw_writeb(0xff, MCFINTC0_SIMR);
+       if (MCFINTC1_SIMR)
+               __raw_writeb(0xff, MCFINTC1_SIMR);
+
+       for (irq = 0; (irq < NR_IRQS); irq++) {
+               irq_desc[irq].status = IRQ_DISABLED;
+               irq_desc[irq].action = NULL;
+               irq_desc[irq].depth = 1;
+               irq_desc[irq].chip = &intc_irq_chip;
+               intc_irq_set_type(irq, 0);
+       }
+}
+
diff --git a/arch/m68knommu/platform/coldfire/intc.c b/arch/m68knommu/platform/coldfire/intc.c
new file mode 100644 (file)
index 0000000..a4560c8
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * intc.c  -- support for the old ColdFire interrupt controller
+ *
+ * (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <asm/traps.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+
+/*
+ * The mapping of irq number to a mask register bit is not one-to-one.
+ * The irq numbers are either based on "level" of interrupt or fixed
+ * for an autovector-able interrupt. So we keep a local data structure
+ * that maps from irq to mask register. Not all interrupts will have
+ * an IMR bit.
+ */
+unsigned char mcf_irq2imr[NR_IRQS];
+
+/*
+ * Define the miniumun and maximum external interrupt numbers.
+ * This is also used as the "level" interrupt numbers.
+ */
+#define        EIRQ1   25
+#define        EIRQ7   31
+
+/*
+ * In the early version 2 core ColdFire parts the IMR register was 16 bits
+ * in size. Version 3 (and later version 2) core parts have a 32 bit
+ * sized IMR register. Provide some size independant methods to access the
+ * IMR register.
+ */
+#ifdef MCFSIM_IMR_IS_16BITS
+
+void mcf_setimr(int index)
+{
+       u16 imr;
+       imr = __raw_readw(MCF_MBAR + MCFSIM_IMR);
+       __raw_writew(imr | (0x1 << index), MCF_MBAR + MCFSIM_IMR);
+}
+
+void mcf_clrimr(int index)
+{
+       u16 imr;
+       imr = __raw_readw(MCF_MBAR + MCFSIM_IMR);
+       __raw_writew(imr & ~(0x1 << index), MCF_MBAR + MCFSIM_IMR);
+}
+
+void mcf_maskimr(unsigned int mask)
+{
+       u16 imr;
+       imr = __raw_readw(MCF_MBAR + MCFSIM_IMR);
+       imr |= mask;
+       __raw_writew(imr, MCF_MBAR + MCFSIM_IMR);
+}
+
+#else
+
+void mcf_setimr(int index)
+{
+       u32 imr;
+       imr = __raw_readl(MCF_MBAR + MCFSIM_IMR);
+       __raw_writel(imr | (0x1 << index), MCF_MBAR + MCFSIM_IMR);
+}
+
+void mcf_clrimr(int index)
+{
+       u32 imr;
+       imr = __raw_readl(MCF_MBAR + MCFSIM_IMR);
+       __raw_writel(imr & ~(0x1 << index), MCF_MBAR + MCFSIM_IMR);
+}
+
+void mcf_maskimr(unsigned int mask)
+{
+       u32 imr;
+       imr = __raw_readl(MCF_MBAR + MCFSIM_IMR);
+       imr |= mask;
+       __raw_writel(imr, MCF_MBAR + MCFSIM_IMR);
+}
+
+#endif
+
+/*
+ * Interrupts can be "vectored" on the ColdFire cores that support this old
+ * interrupt controller. That is, the device raising the interrupt can also
+ * supply the vector number to interrupt through. The AVR register of the
+ * interrupt controller enables or disables this for each external interrupt,
+ * so provide generic support for this. Setting this up is out-of-band for
+ * the interrupt system API's, and needs to be done by the driver that
+ * supports this device. Very few devices actually use this.
+ */
+void mcf_autovector(int irq)
+{
+#ifdef MCFSIM_AVR
+       if ((irq >= EIRQ1) && (irq <= EIRQ7)) {
+               u8 avec;
+               avec = __raw_readb(MCF_MBAR + MCFSIM_AVR);
+               avec |= (0x1 << (irq - EIRQ1 + 1));
+               __raw_writeb(avec, MCF_MBAR + MCFSIM_AVR);
+       }
+#endif
+}
+
+static void intc_irq_mask(unsigned int irq)
+{
+       if (mcf_irq2imr[irq])
+               mcf_setimr(mcf_irq2imr[irq]);
+}
+
+static void intc_irq_unmask(unsigned int irq)
+{
+       if (mcf_irq2imr[irq])
+               mcf_clrimr(mcf_irq2imr[irq]);
+}
+
+static int intc_irq_set_type(unsigned int irq, unsigned int type)
+{
+       return 0;
+}
+
+static struct irq_chip intc_irq_chip = {
+       .name           = "CF-INTC",
+       .mask           = intc_irq_mask,
+       .unmask         = intc_irq_unmask,
+       .set_type       = intc_irq_set_type,
+};
+
+void __init init_IRQ(void)
+{
+       int irq;
+
+       init_vectors();
+       mcf_maskimr(0xffffffff);
+
+       for (irq = 0; (irq < NR_IRQS); irq++) {
+               irq_desc[irq].status = IRQ_DISABLED;
+               irq_desc[irq].action = NULL;
+               irq_desc[irq].depth = 1;
+               irq_desc[irq].chip = &intc_irq_chip;
+               intc_irq_set_type(irq, 0);
+       }
+}
+
diff --git a/arch/m68knommu/platform/coldfire/pinmux.c b/arch/m68knommu/platform/coldfire/pinmux.c
new file mode 100644 (file)
index 0000000..8c62b82
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Coldfire generic GPIO pinmux support.
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.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; version 2 of the License.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT 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 <asm/pinmux.h>
+
+int mcf_pinmux_request(unsigned pinmux, unsigned func)
+{
+       return 0;
+}
+
+void mcf_pinmux_release(unsigned pinmux, unsigned func)
+{
+}
index 61b96211f8ffda0e2d8609e097c3248011d28cb9..d8720ee345100abe26a4fa181b109f6ae9f0e7af 100644 (file)
@@ -32,7 +32,6 @@
  */
 #define        FREQ    ((MCF_CLK / 2) / 64)
 #define        TA(a)   (MCF_IPSBAR + MCFPIT_BASE1 + (a))
-#define        INTC0   (MCF_IPSBAR + MCFICM_INTC0)
 #define PIT_CYCLES_PER_JIFFY (FREQ / HZ)
 
 static u32 pit_cnt;
@@ -154,8 +153,6 @@ static struct clocksource pit_clk = {
 
 void hw_timer_init(void)
 {
-       u32 imr;
-
        cf_pit_clockevent.cpumask = cpumask_of(smp_processor_id());
        cf_pit_clockevent.mult = div_sc(FREQ, NSEC_PER_SEC, 32);
        cf_pit_clockevent.max_delta_ns =
@@ -166,11 +163,6 @@ void hw_timer_init(void)
 
        setup_irq(MCFINT_VECBASE + MCFINT_PIT1, &pit_irq);
 
-       __raw_writeb(ICR_INTRCONF, INTC0 + MCFINTC_ICR0 + MCFINT_PIT1);
-       imr = __raw_readl(INTC0 + MCFPIT_IMR);
-       imr &= ~MCFPIT_IMR_IBIT;
-       __raw_writel(imr, INTC0 + MCFPIT_IMR);
-
        pit_clk.mult = clocksource_hz2mult(FREQ, pit_clk.shift);
        clocksource_register(&pit_clk);
 }
index 1ba8a3731653aa60d94d45fe32a5f349d046dbb4..2304d736c701e59b0cb3266780a195945eec84f6 100644 (file)
 #define        FREQ    (MCF_BUSCLK / 16)
 #define        TA(a)   (MCF_MBAR + MCFTIMER_BASE1 + (a))
 
-/*
- *     Default the timer and vector to use for ColdFire. Some ColdFire
- *     CPU's and some boards may want different. Their sub-architecture
- *     startup code (in config.c) can change these if they want.
- */
-unsigned int   mcf_timervector = 29;
-unsigned int   mcf_profilevector = 31;
-unsigned int   mcf_timerlevel = 5;
-
 /*
  *     These provide the underlying interrupt vector support.
  *     Unfortunately it is a little different on each ColdFire.
  */
-extern void mcf_settimericr(int timer, int level);
 void coldfire_profile_init(void);
 
 #if defined(CONFIG_M532x)
@@ -107,8 +97,6 @@ static struct clocksource mcftmr_clk = {
 
 void hw_timer_init(void)
 {
-       setup_irq(mcf_timervector, &mcftmr_timer_irq);
-
        __raw_writew(MCFTIMER_TMR_DISABLE, TA(MCFTIMER_TMR));
        mcftmr_cycles_per_jiffy = FREQ / HZ;
        /*
@@ -124,7 +112,7 @@ void hw_timer_init(void)
        mcftmr_clk.mult = clocksource_hz2mult(FREQ, mcftmr_clk.shift);
        clocksource_register(&mcftmr_clk);
 
-       mcf_settimericr(1, mcf_timerlevel);
+       setup_irq(MCF_IRQ_TIMER, &mcftmr_timer_irq);
 
 #ifdef CONFIG_HIGHPROFILE
        coldfire_profile_init();
@@ -171,8 +159,6 @@ void coldfire_profile_init(void)
        printk(KERN_INFO "PROFILE: lodging TIMER2 @ %dHz as profile timer\n",
               PROFILEHZ);
 
-       setup_irq(mcf_profilevector, &coldfire_profile_irq);
-
        /* Set up TIMER 2 as high speed profile clock */
        __raw_writew(MCFTIMER_TMR_DISABLE, PA(MCFTIMER_TMR));
 
@@ -180,7 +166,7 @@ void coldfire_profile_init(void)
        __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
                MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, PA(MCFTIMER_TMR));
 
-       mcf_settimericr(2, 7);
+       setup_irq(MCF_IRQ_PROFILER, &coldfire_profile_irq);
 }
 
 /***************************************************************************/
index bdca0297fa9a1f6fc261df8cd12c9f9d487ee25f..a21d3f870b7aaee20a77405aa3e26b29f268b58d 100644 (file)
@@ -1,7 +1,7 @@
 /***************************************************************************/
 
 /*
- *     linux/arch/m68knommu/platform/5307/vectors.c
+ *     linux/arch/m68knommu/platform/coldfire/vectors.c
  *
  *     Copyright (C) 1999-2007, Greg Ungerer <gerg@snapgear.com>
  */
@@ -15,7 +15,6 @@
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
-#include <asm/mcfdma.h>
 #include <asm/mcfwdebug.h>
 
 /***************************************************************************/
@@ -79,20 +78,3 @@ void __init init_vectors(void)
 }
 
 /***************************************************************************/
-
-void enable_vector(unsigned int irq)
-{
-       /* Currently no action on ColdFire */
-}
-
-void disable_vector(unsigned int irq)
-{
-       /* Currently no action on ColdFire */
-}
-
-void ack_vector(unsigned int irq)
-{
-       /* Currently no action on ColdFire */
-}
-
-/***************************************************************************/
index 3ca0fe1a91231441d9767fdcd56a9caafe203c83..705a7a9170f32bc5aec7cc30865d1ace7eb1edf7 100644 (file)
@@ -6,7 +6,7 @@ config MIPS
        select HAVE_ARCH_KGDB
        # Horrible source of confusion.  Die, die, die ...
        select EMBEDDED
-       select RTC_LIB
+       select RTC_LIB if !LEMOTE_FULOONG2E
 
 mainmenu "Linux/MIPS Kernel Configuration"
 
@@ -80,6 +80,21 @@ config BCM47XX
        help
         Support for BCM47XX based boards
 
+config BCM63XX
+       bool "Broadcom BCM63XX based boards"
+       select CEVT_R4K
+       select CSRC_R4K
+       select DMA_NONCOHERENT
+       select IRQ_CPU
+       select SYS_HAS_CPU_MIPS32_R1
+       select SYS_SUPPORTS_32BIT_KERNEL
+       select SYS_SUPPORTS_BIG_ENDIAN
+       select SYS_HAS_EARLY_PRINTK
+       select SWAP_IO_SPACE
+       select ARCH_REQUIRE_GPIOLIB
+       help
+        Support for BCM63XX based boards
+
 config MIPS_COBALT
        bool "Cobalt Server"
        select CEVT_R4K
@@ -174,30 +189,15 @@ config LASAT
        select SYS_SUPPORTS_64BIT_KERNEL if BROKEN
        select SYS_SUPPORTS_LITTLE_ENDIAN
 
-config LEMOTE_FULONG
-       bool "Lemote Fulong mini-PC"
-       select ARCH_SPARSEMEM_ENABLE
-       select CEVT_R4K
-       select CSRC_R4K
-       select SYS_HAS_CPU_LOONGSON2
-       select DMA_NONCOHERENT
-       select BOOT_ELF32
-       select BOARD_SCACHE
-       select HAVE_STD_PC_SERIAL_PORT
-       select HW_HAS_PCI
-       select I8259
-       select ISA
-       select IRQ_CPU
-       select SYS_SUPPORTS_32BIT_KERNEL
-       select SYS_SUPPORTS_64BIT_KERNEL
-       select SYS_SUPPORTS_LITTLE_ENDIAN
-       select SYS_SUPPORTS_HIGHMEM
-       select SYS_HAS_EARLY_PRINTK
-       select GENERIC_ISA_DMA_SUPPORT_BROKEN
-       select CPU_HAS_WB
+config MACH_LOONGSON
+       bool "Loongson family of machines"
        help
-         Lemote Fulong mini-PC board based on the Chinese Loongson-2E CPU and
-         an FPGA northbridge
+         This enables the support of Loongson family of machines.
+
+         Loongson is a family of general-purpose MIPS-compatible CPUs.
+         developed at Institute of Computing Technology (ICT),
+         Chinese Academy of Sciences (CAS) in the People's Republic
+         of China. The chief architect is Professor Weiwu Hu.
 
 config MIPS_MALTA
        bool "MIPS Malta board"
@@ -660,6 +660,7 @@ endchoice
 
 source "arch/mips/alchemy/Kconfig"
 source "arch/mips/basler/excite/Kconfig"
+source "arch/mips/bcm63xx/Kconfig"
 source "arch/mips/jazz/Kconfig"
 source "arch/mips/lasat/Kconfig"
 source "arch/mips/pmc-sierra/Kconfig"
@@ -668,6 +669,7 @@ source "arch/mips/sibyte/Kconfig"
 source "arch/mips/txx9/Kconfig"
 source "arch/mips/vr41xx/Kconfig"
 source "arch/mips/cavium-octeon/Kconfig"
+source "arch/mips/loongson/Kconfig"
 
 endmenu
 
@@ -1044,12 +1046,10 @@ choice
        prompt "CPU type"
        default CPU_R4X00
 
-config CPU_LOONGSON2
-       bool "Loongson 2"
-       depends on SYS_HAS_CPU_LOONGSON2
-       select CPU_SUPPORTS_32BIT_KERNEL
-       select CPU_SUPPORTS_64BIT_KERNEL
-       select CPU_SUPPORTS_HIGHMEM
+config CPU_LOONGSON2E
+       bool "Loongson 2E"
+       depends on SYS_HAS_CPU_LOONGSON2E
+       select CPU_LOONGSON2
        help
          The Loongson 2E processor implements the MIPS III instruction set
          with many extensions.
@@ -1057,7 +1057,6 @@ config CPU_LOONGSON2
 config CPU_MIPS32_R1
        bool "MIPS32 Release 1"
        depends on SYS_HAS_CPU_MIPS32_R1
-       select CPU_HAS_LLSC
        select CPU_HAS_PREFETCH
        select CPU_SUPPORTS_32BIT_KERNEL
        select CPU_SUPPORTS_HIGHMEM
@@ -1075,7 +1074,6 @@ config CPU_MIPS32_R1
 config CPU_MIPS32_R2
        bool "MIPS32 Release 2"
        depends on SYS_HAS_CPU_MIPS32_R2
-       select CPU_HAS_LLSC
        select CPU_HAS_PREFETCH
        select CPU_SUPPORTS_32BIT_KERNEL
        select CPU_SUPPORTS_HIGHMEM
@@ -1089,7 +1087,6 @@ config CPU_MIPS32_R2
 config CPU_MIPS64_R1
        bool "MIPS64 Release 1"
        depends on SYS_HAS_CPU_MIPS64_R1
-       select CPU_HAS_LLSC
        select CPU_HAS_PREFETCH
        select CPU_SUPPORTS_32BIT_KERNEL
        select CPU_SUPPORTS_64BIT_KERNEL
@@ -1109,7 +1106,6 @@ config CPU_MIPS64_R1
 config CPU_MIPS64_R2
        bool "MIPS64 Release 2"
        depends on SYS_HAS_CPU_MIPS64_R2
-       select CPU_HAS_LLSC
        select CPU_HAS_PREFETCH
        select CPU_SUPPORTS_32BIT_KERNEL
        select CPU_SUPPORTS_64BIT_KERNEL
@@ -1155,7 +1151,6 @@ config CPU_VR41XX
 config CPU_R4300
        bool "R4300"
        depends on SYS_HAS_CPU_R4300
-       select CPU_HAS_LLSC
        select CPU_SUPPORTS_32BIT_KERNEL
        select CPU_SUPPORTS_64BIT_KERNEL
        help
@@ -1164,7 +1159,6 @@ config CPU_R4300
 config CPU_R4X00
        bool "R4x00"
        depends on SYS_HAS_CPU_R4X00
-       select CPU_HAS_LLSC
        select CPU_SUPPORTS_32BIT_KERNEL
        select CPU_SUPPORTS_64BIT_KERNEL
        help
@@ -1174,7 +1168,6 @@ config CPU_R4X00
 config CPU_TX49XX
        bool "R49XX"
        depends on SYS_HAS_CPU_TX49XX
-       select CPU_HAS_LLSC
        select CPU_HAS_PREFETCH
        select CPU_SUPPORTS_32BIT_KERNEL
        select CPU_SUPPORTS_64BIT_KERNEL
@@ -1182,7 +1175,6 @@ config CPU_TX49XX
 config CPU_R5000
        bool "R5000"
        depends on SYS_HAS_CPU_R5000
-       select CPU_HAS_LLSC
        select CPU_SUPPORTS_32BIT_KERNEL
        select CPU_SUPPORTS_64BIT_KERNEL
        help
@@ -1191,14 +1183,12 @@ config CPU_R5000
 config CPU_R5432
        bool "R5432"
        depends on SYS_HAS_CPU_R5432
-       select CPU_HAS_LLSC
        select CPU_SUPPORTS_32BIT_KERNEL
        select CPU_SUPPORTS_64BIT_KERNEL
 
 config CPU_R5500
        bool "R5500"
        depends on SYS_HAS_CPU_R5500
-       select CPU_HAS_LLSC
        select CPU_SUPPORTS_32BIT_KERNEL
        select CPU_SUPPORTS_64BIT_KERNEL
        select CPU_SUPPORTS_HUGEPAGES
@@ -1209,7 +1199,6 @@ config CPU_R5500
 config CPU_R6000
        bool "R6000"
        depends on EXPERIMENTAL
-       select CPU_HAS_LLSC
        depends on SYS_HAS_CPU_R6000
        select CPU_SUPPORTS_32BIT_KERNEL
        help
@@ -1219,7 +1208,6 @@ config CPU_R6000
 config CPU_NEVADA
        bool "RM52xx"
        depends on SYS_HAS_CPU_NEVADA
-       select CPU_HAS_LLSC
        select CPU_SUPPORTS_32BIT_KERNEL
        select CPU_SUPPORTS_64BIT_KERNEL
        help
@@ -1229,7 +1217,6 @@ config CPU_R8000
        bool "R8000"
        depends on EXPERIMENTAL
        depends on SYS_HAS_CPU_R8000
-       select CPU_HAS_LLSC
        select CPU_HAS_PREFETCH
        select CPU_SUPPORTS_64BIT_KERNEL
        help
@@ -1239,7 +1226,6 @@ config CPU_R8000
 config CPU_R10000
        bool "R10000"
        depends on SYS_HAS_CPU_R10000
-       select CPU_HAS_LLSC
        select CPU_HAS_PREFETCH
        select CPU_SUPPORTS_32BIT_KERNEL
        select CPU_SUPPORTS_64BIT_KERNEL
@@ -1250,7 +1236,6 @@ config CPU_R10000
 config CPU_RM7000
        bool "RM7000"
        depends on SYS_HAS_CPU_RM7000
-       select CPU_HAS_LLSC
        select CPU_HAS_PREFETCH
        select CPU_SUPPORTS_32BIT_KERNEL
        select CPU_SUPPORTS_64BIT_KERNEL
@@ -1259,7 +1244,6 @@ config CPU_RM7000
 config CPU_RM9000
        bool "RM9000"
        depends on SYS_HAS_CPU_RM9000
-       select CPU_HAS_LLSC
        select CPU_HAS_PREFETCH
        select CPU_SUPPORTS_32BIT_KERNEL
        select CPU_SUPPORTS_64BIT_KERNEL
@@ -1269,7 +1253,6 @@ config CPU_RM9000
 config CPU_SB1
        bool "SB1"
        depends on SYS_HAS_CPU_SB1
-       select CPU_HAS_LLSC
        select CPU_SUPPORTS_32BIT_KERNEL
        select CPU_SUPPORTS_64BIT_KERNEL
        select CPU_SUPPORTS_HIGHMEM
@@ -1296,7 +1279,13 @@ config CPU_CAVIUM_OCTEON
 
 endchoice
 
-config SYS_HAS_CPU_LOONGSON2
+config CPU_LOONGSON2
+       bool
+       select CPU_SUPPORTS_32BIT_KERNEL
+       select CPU_SUPPORTS_64BIT_KERNEL
+       select CPU_SUPPORTS_HIGHMEM
+
+config SYS_HAS_CPU_LOONGSON2E
        bool
 
 config SYS_HAS_CPU_MIPS32_R1
@@ -1683,9 +1672,6 @@ config SB1_PASS_2_1_WORKAROUNDS
 config 64BIT_PHYS_ADDR
        bool
 
-config CPU_HAS_LLSC
-       bool
-
 config CPU_HAS_SMARTMIPS
        depends on SYS_SUPPORTS_SMARTMIPS
        bool "Support for the SmartMIPS ASE"
index 861da514a468a7cf84bdb0d32cd703921f7853e0..c825b14b4ed05427367a694194f5bc2a82a12d99 100644 (file)
@@ -120,7 +120,11 @@ cflags-$(CONFIG_CPU_R4300) += -march=r4300 -Wa,--trap
 cflags-$(CONFIG_CPU_VR41XX)    += -march=r4100 -Wa,--trap
 cflags-$(CONFIG_CPU_R4X00)     += -march=r4600 -Wa,--trap
 cflags-$(CONFIG_CPU_TX49XX)    += -march=r4600 -Wa,--trap
-cflags-$(CONFIG_CPU_LOONGSON2) += -march=r4600 -Wa,--trap
+# only gcc >= 4.4 have the loongson-specific support
+cflags-$(CONFIG_CPU_LOONGSON2) += -Wa,--trap
+cflags-$(CONFIG_CPU_LOONGSON2E) += \
+       $(call cc-option,-march=loongson2e,-march=r4600)
+
 cflags-$(CONFIG_CPU_MIPS32_R1) += $(call cc-option,-march=mips32,-mips32 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
                        -Wa,-mips32 -Wa,--trap
 cflags-$(CONFIG_CPU_MIPS32_R2) += $(call cc-option,-march=mips32r2,-mips32r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
@@ -314,11 +318,12 @@ cflags-$(CONFIG_WR_PPMC)          += -I$(srctree)/arch/mips/include/asm/mach-wrppmc
 load-$(CONFIG_WR_PPMC)         += 0xffffffff80100000
 
 #
-# lemote fulong mini-PC board
+# Loongson family
 #
-core-$(CONFIG_LEMOTE_FULONG) +=arch/mips/lemote/lm2e/
-load-$(CONFIG_LEMOTE_FULONG) +=0xffffffff80100000
-cflags-$(CONFIG_LEMOTE_FULONG) += -I$(srctree)/arch/mips/include/asm/mach-lemote
+core-$(CONFIG_MACH_LOONGSON) +=arch/mips/loongson/
+cflags-$(CONFIG_MACH_LOONGSON) += -I$(srctree)/arch/mips/include/asm/mach-loongson \
+                    -mno-branch-likely
+load-$(CONFIG_LEMOTE_FULOONG2E) +=0xffffffff80100000
 
 #
 # MIPS Malta board
@@ -559,6 +564,13 @@ core-$(CONFIG_BCM47XX)             += arch/mips/bcm47xx/
 cflags-$(CONFIG_BCM47XX)       += -I$(srctree)/arch/mips/include/asm/mach-bcm47xx
 load-$(CONFIG_BCM47XX)         := 0xffffffff80001000
 
+#
+# Broadcom BCM63XX boards
+#
+core-$(CONFIG_BCM63XX)         += arch/mips/bcm63xx/
+cflags-$(CONFIG_BCM63XX)       += -I$(srctree)/arch/mips/include/asm/mach-bcm63xx/
+load-$(CONFIG_BCM63XX)         := 0xffffffff80010000
+
 #
 # SNI RM
 #
index 3f036b3d400e3077da869ad20021378101f26811..6184baa56786703af2ef195cf9ee77318cace225 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <linux/init.h>
 #include <linux/ioport.h>
+#include <linux/jiffies.h>
 #include <linux/module.h>
 #include <linux/pm.h>
 
@@ -53,6 +54,9 @@ void __init plat_mem_setup(void)
        printk(KERN_INFO "(PRId %08x) @ %lu.%02lu MHz\n", read_c0_prid(),
               est_freq / 1000000, ((est_freq % 1000000) * 100) / 1000000);
 
+       /* this is faster than wasting cycles trying to approximate it */
+       preset_lpj = (est_freq >> 1) / HZ;
+
        _machine_restart = au1000_restart;
        _machine_halt = au1000_halt;
        pm_power_off = au1000_power_off;
index 33fbae79af5e6660f33fc404b0a1f5781829950e..f34ff86019424ba311f6ff36b79d43265df23772 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
 
+#include <asm/processor.h>
 #include <asm/time.h>
 #include <asm/mach-au1x00/au1000.h>
 
 /* 32kHz clock enabled and detected */
 #define CNTR_OK (SYS_CNTRL_E0 | SYS_CNTRL_32S)
 
-extern int allow_au1k_wait; /* default off for CP0 Counter */
-
 static cycle_t au1x_counter1_read(struct clocksource *cs)
 {
        return au_readl(SYS_RTCREAD);
@@ -153,13 +152,17 @@ void __init plat_time_init(void)
 
        printk(KERN_INFO "Alchemy clocksource installed\n");
 
-       /* can now use 'wait' */
-       allow_au1k_wait = 1;
        return;
 
 cntr_err:
-       /* counters unusable, use C0 counter */
+       /*
+        * MIPS kernel assigns 'au1k_wait' to 'cpu_wait' before this
+        * function is called.  Because the Alchemy counters are unusable
+        * the C0 timekeeping code is installed and use of the 'wait'
+        * instruction must be prohibited, which is done most easily by
+        * assigning NULL to cpu_wait.
+        */
+       cpu_wait = NULL;
        r4k_clockevent_init();
        init_r4k_clocksource();
-       allow_au1k_wait = 0;
 }
index cf50fa29b198462fc04d6fd667910a20504b9e77..e2278c04459d184625f58a9f939a205c08913d81 100644 (file)
@@ -417,6 +417,20 @@ static struct platform_device ar7_udc = {
        .num_resources = ARRAY_SIZE(usb_res),
 };
 
+static struct resource ar7_wdt_res = {
+       .name = "regs",
+       .start = -1, /* Filled at runtime */
+       .end = -1, /* Filled at runtime */
+       .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device ar7_wdt = {
+       .id = -1,
+       .name  = "ar7_wdt",
+       .resource = &ar7_wdt_res,
+       .num_resources = 1,
+};
+
 static inline unsigned char char2hex(char h)
 {
        switch (h) {
@@ -487,6 +501,7 @@ static void __init detect_leds(void)
 
 static int __init ar7_register_devices(void)
 {
+       u16 chip_id;
        int res;
 #ifdef CONFIG_SERIAL_8250
        static struct uart_port uart_port[2];
@@ -565,6 +580,23 @@ static int __init ar7_register_devices(void)
 
        res = platform_device_register(&ar7_udc);
 
+       chip_id = ar7_chip_id();
+       switch (chip_id) {
+       case AR7_CHIP_7100:
+       case AR7_CHIP_7200:
+               ar7_wdt_res.start = AR7_REGS_WDT;
+               break;
+       case AR7_CHIP_7300:
+               ar7_wdt_res.start = UR8_REGS_WDT;
+               break;
+       default:
+               break;
+       }
+
+       ar7_wdt_res.end = ar7_wdt_res.start + 0x20;
+
+       res = platform_device_register(&ar7_wdt);
+
        return res;
 }
 arch_initcall(ar7_register_devices);
diff --git a/arch/mips/bcm63xx/Kconfig b/arch/mips/bcm63xx/Kconfig
new file mode 100644 (file)
index 0000000..fb177d6
--- /dev/null
@@ -0,0 +1,25 @@
+menu "CPU support"
+       depends on BCM63XX
+
+config BCM63XX_CPU_6338
+       bool "support 6338 CPU"
+       select HW_HAS_PCI
+       select USB_ARCH_HAS_OHCI
+       select USB_OHCI_BIG_ENDIAN_DESC
+       select USB_OHCI_BIG_ENDIAN_MMIO
+
+config BCM63XX_CPU_6345
+       bool "support 6345 CPU"
+       select USB_OHCI_BIG_ENDIAN_DESC
+       select USB_OHCI_BIG_ENDIAN_MMIO
+
+config BCM63XX_CPU_6348
+       bool "support 6348 CPU"
+       select HW_HAS_PCI
+
+config BCM63XX_CPU_6358
+       bool "support 6358 CPU"
+       select HW_HAS_PCI
+endmenu
+
+source "arch/mips/bcm63xx/boards/Kconfig"
diff --git a/arch/mips/bcm63xx/Makefile b/arch/mips/bcm63xx/Makefile
new file mode 100644 (file)
index 0000000..aaa585c
--- /dev/null
@@ -0,0 +1,7 @@
+obj-y          += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \
+                  dev-dsp.o dev-enet.o
+obj-$(CONFIG_EARLY_PRINTK)     += early_printk.o
+
+obj-y          += boards/
+
+EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/bcm63xx/boards/Kconfig b/arch/mips/bcm63xx/boards/Kconfig
new file mode 100644 (file)
index 0000000..c6aed33
--- /dev/null
@@ -0,0 +1,11 @@
+choice
+       prompt "Board support"
+       depends on BCM63XX
+       default BOARD_BCM963XX
+
+config BOARD_BCM963XX
+       bool "Generic Broadcom 963xx boards"
+       select SSB
+       help
+
+endchoice
diff --git a/arch/mips/bcm63xx/boards/Makefile b/arch/mips/bcm63xx/boards/Makefile
new file mode 100644 (file)
index 0000000..e5cc86d
--- /dev/null
@@ -0,0 +1,3 @@
+obj-$(CONFIG_BOARD_BCM963XX)           += board_bcm963xx.o
+
+EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c
new file mode 100644 (file)
index 0000000..fd77f54
--- /dev/null
@@ -0,0 +1,837 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/ssb/ssb.h>
+#include <asm/addrspace.h>
+#include <bcm63xx_board.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_board.h>
+#include <bcm63xx_dev_pci.h>
+#include <bcm63xx_dev_enet.h>
+#include <bcm63xx_dev_dsp.h>
+#include <board_bcm963xx.h>
+
+#define PFX    "board_bcm963xx: "
+
+static struct bcm963xx_nvram nvram;
+static unsigned int mac_addr_used;
+static struct board_info board;
+
+/*
+ * known 6338 boards
+ */
+#ifdef CONFIG_BCM63XX_CPU_6338
+static struct board_info __initdata board_96338gw = {
+       .name                           = "96338GW",
+       .expected_cpu_id                = 0x6338,
+
+       .has_enet0                      = 1,
+       .enet0 = {
+               .force_speed_100        = 1,
+               .force_duplex_full      = 1,
+       },
+
+       .has_ohci0                      = 1,
+
+       .leds = {
+               {
+                       .name           = "adsl",
+                       .gpio           = 3,
+                       .active_low     = 1,
+               },
+               {
+                       .name           = "ses",
+                       .gpio           = 5,
+                       .active_low     = 1,
+               },
+               {
+                       .name           = "ppp-fail",
+                       .gpio           = 4,
+                       .active_low     = 1,
+               },
+               {
+                       .name           = "power",
+                       .gpio           = 0,
+                       .active_low     = 1,
+                       .default_trigger = "default-on",
+               },
+               {
+                       .name           = "stop",
+                       .gpio           = 1,
+                       .active_low     = 1,
+               }
+       },
+};
+
+static struct board_info __initdata board_96338w = {
+       .name                           = "96338W",
+       .expected_cpu_id                = 0x6338,
+
+       .has_enet0                      = 1,
+       .enet0 = {
+               .force_speed_100        = 1,
+               .force_duplex_full      = 1,
+       },
+
+       .leds = {
+               {
+                       .name           = "adsl",
+                       .gpio           = 3,
+                       .active_low     = 1,
+               },
+               {
+                       .name           = "ses",
+                       .gpio           = 5,
+                       .active_low     = 1,
+               },
+               {
+                       .name           = "ppp-fail",
+                       .gpio           = 4,
+                       .active_low     = 1,
+               },
+               {
+                       .name           = "power",
+                       .gpio           = 0,
+                       .active_low     = 1,
+                       .default_trigger = "default-on",
+               },
+               {
+                       .name           = "stop",
+                       .gpio           = 1,
+                       .active_low     = 1,
+               },
+       },
+};
+#endif
+
+/*
+ * known 6345 boards
+ */
+#ifdef CONFIG_BCM63XX_CPU_6345
+static struct board_info __initdata board_96345gw2 = {
+       .name                           = "96345GW2",
+       .expected_cpu_id                = 0x6345,
+};
+#endif
+
+/*
+ * known 6348 boards
+ */
+#ifdef CONFIG_BCM63XX_CPU_6348
+static struct board_info __initdata board_96348r = {
+       .name                           = "96348R",
+       .expected_cpu_id                = 0x6348,
+
+       .has_enet0                      = 1,
+       .has_pci                        = 1,
+
+       .enet0 = {
+               .has_phy                = 1,
+               .use_internal_phy       = 1,
+       },
+
+       .leds = {
+               {
+                       .name           = "adsl-fail",
+                       .gpio           = 2,
+                       .active_low     = 1,
+               },
+               {
+                       .name           = "ppp",
+                       .gpio           = 3,
+                       .active_low     = 1,
+               },
+               {
+                       .name           = "ppp-fail",
+                       .gpio           = 4,
+                       .active_low     = 1,
+               },
+               {
+                       .name           = "power",
+                       .gpio           = 0,
+                       .active_low     = 1,
+                       .default_trigger = "default-on",
+
+               },
+               {
+                       .name           = "stop",
+                       .gpio           = 1,
+                       .active_low     = 1,
+               },
+       },
+};
+
+static struct board_info __initdata board_96348gw_10 = {
+       .name                           = "96348GW-10",
+       .expected_cpu_id                = 0x6348,
+
+       .has_enet0                      = 1,
+       .has_enet1                      = 1,
+       .has_pci                        = 1,
+
+       .enet0 = {
+               .has_phy                = 1,
+               .use_internal_phy       = 1,
+       },
+       .enet1 = {
+               .force_speed_100        = 1,
+               .force_duplex_full      = 1,
+       },
+
+       .has_ohci0                      = 1,
+       .has_pccard                     = 1,
+       .has_ehci0                      = 1,
+
+       .has_dsp                        = 1,
+       .dsp = {
+               .gpio_rst               = 6,
+               .gpio_int               = 34,
+               .cs                     = 2,
+               .ext_irq                = 2,
+       },
+
+       .leds = {
+               {
+                       .name           = "adsl-fail",
+                       .gpio           = 2,
+                       .active_low     = 1,
+               },
+               {
+                       .name           = "ppp",
+                       .gpio           = 3,
+                       .active_low     = 1,
+               },
+               {
+                       .name           = "ppp-fail",
+                       .gpio           = 4,
+                       .active_low     = 1,
+               },
+               {
+                       .name           = "power",
+                       .gpio           = 0,
+                       .active_low     = 1,
+                       .default_trigger = "default-on",
+               },
+               {
+                       .name           = "stop",
+                       .gpio           = 1,
+                       .active_low     = 1,
+               },
+       },
+};
+
+static struct board_info __initdata board_96348gw_11 = {
+       .name                           = "96348GW-11",
+       .expected_cpu_id                = 0x6348,
+
+       .has_enet0                      = 1,
+       .has_enet1                      = 1,
+       .has_pci                        = 1,
+
+       .enet0 = {
+               .has_phy                = 1,
+               .use_internal_phy       = 1,
+       },
+
+       .enet1 = {
+               .force_speed_100        = 1,
+               .force_duplex_full      = 1,
+       },
+
+
+       .has_ohci0 = 1,
+       .has_pccard = 1,
+       .has_ehci0 = 1,
+
+       .leds = {
+               {
+                       .name           = "adsl-fail",
+                       .gpio           = 2,
+                       .active_low     = 1,
+               },
+               {
+                       .name           = "ppp",
+                       .gpio           = 3,
+                       .active_low     = 1,
+               },
+               {
+                       .name           = "ppp-fail",
+                       .gpio           = 4,
+                       .active_low     = 1,
+               },
+               {
+                       .name           = "power",
+                       .gpio           = 0,
+                       .active_low     = 1,
+                       .default_trigger = "default-on",
+               },
+               {
+                       .name           = "stop",
+                       .gpio           = 1,
+                       .active_low     = 1,
+               },
+       },
+};
+
+static struct board_info __initdata board_96348gw = {
+       .name                           = "96348GW",
+       .expected_cpu_id                = 0x6348,
+
+       .has_enet0                      = 1,
+       .has_enet1                      = 1,
+       .has_pci                        = 1,
+
+       .enet0 = {
+               .has_phy                = 1,
+               .use_internal_phy       = 1,
+       },
+       .enet1 = {
+               .force_speed_100        = 1,
+               .force_duplex_full      = 1,
+       },
+
+       .has_ohci0 = 1,
+
+       .has_dsp                        = 1,
+       .dsp = {
+               .gpio_rst               = 6,
+               .gpio_int               = 34,
+               .ext_irq                = 2,
+               .cs                     = 2,
+       },
+
+       .leds = {
+               {
+                       .name           = "adsl-fail",
+                       .gpio           = 2,
+                       .active_low     = 1,
+               },
+               {
+                       .name           = "ppp",
+                       .gpio           = 3,
+                       .active_low     = 1,
+               },
+               {
+                       .name           = "ppp-fail",
+                       .gpio           = 4,
+                       .active_low     = 1,
+               },
+               {
+                       .name           = "power",
+                       .gpio           = 0,
+                       .active_low     = 1,
+                       .default_trigger = "default-on",
+               },
+               {
+                       .name           = "stop",
+                       .gpio           = 1,
+                       .active_low     = 1,
+               },
+       },
+};
+
+static struct board_info __initdata board_FAST2404 = {
+        .name                           = "F@ST2404",
+        .expected_cpu_id                = 0x6348,
+
+        .has_enet0                      = 1,
+        .has_enet1                      = 1,
+        .has_pci                        = 1,
+
+        .enet0 = {
+                .has_phy                = 1,
+                .use_internal_phy       = 1,
+        },
+
+        .enet1 = {
+                .force_speed_100        = 1,
+                .force_duplex_full      = 1,
+        },
+
+
+        .has_ohci0 = 1,
+        .has_pccard = 1,
+        .has_ehci0 = 1,
+};
+
+static struct board_info __initdata board_DV201AMR = {
+       .name                           = "DV201AMR",
+       .expected_cpu_id                = 0x6348,
+
+       .has_pci                        = 1,
+       .has_ohci0                      = 1,
+
+       .has_enet0                      = 1,
+       .has_enet1                      = 1,
+       .enet0 = {
+               .has_phy                = 1,
+               .use_internal_phy       = 1,
+       },
+       .enet1 = {
+               .force_speed_100        = 1,
+               .force_duplex_full      = 1,
+       },
+};
+
+static struct board_info __initdata board_96348gw_a = {
+       .name                           = "96348GW-A",
+       .expected_cpu_id                = 0x6348,
+
+       .has_enet0                      = 1,
+       .has_enet1                      = 1,
+       .has_pci                        = 1,
+
+       .enet0 = {
+               .has_phy                = 1,
+               .use_internal_phy       = 1,
+       },
+       .enet1 = {
+               .force_speed_100        = 1,
+               .force_duplex_full      = 1,
+       },
+
+       .has_ohci0 = 1,
+};
+#endif
+
+/*
+ * known 6358 boards
+ */
+#ifdef CONFIG_BCM63XX_CPU_6358
+static struct board_info __initdata board_96358vw = {
+       .name                           = "96358VW",
+       .expected_cpu_id                = 0x6358,
+
+       .has_enet0                      = 1,
+       .has_enet1                      = 1,
+       .has_pci                        = 1,
+
+       .enet0 = {
+               .has_phy                = 1,
+               .use_internal_phy       = 1,
+       },
+
+       .enet1 = {
+               .force_speed_100        = 1,
+               .force_duplex_full      = 1,
+       },
+
+
+       .has_ohci0 = 1,
+       .has_pccard = 1,
+       .has_ehci0 = 1,
+
+       .leds = {
+               {
+                       .name           = "adsl-fail",
+                       .gpio           = 15,
+                       .active_low     = 1,
+               },
+               {
+                       .name           = "ppp",
+                       .gpio           = 22,
+                       .active_low     = 1,
+               },
+               {
+                       .name           = "ppp-fail",
+                       .gpio           = 23,
+                       .active_low     = 1,
+               },
+               {
+                       .name           = "power",
+                       .gpio           = 4,
+                       .default_trigger = "default-on",
+               },
+               {
+                       .name           = "stop",
+                       .gpio           = 5,
+               },
+       },
+};
+
+static struct board_info __initdata board_96358vw2 = {
+       .name                           = "96358VW2",
+       .expected_cpu_id                = 0x6358,
+
+       .has_enet0                      = 1,
+       .has_enet1                      = 1,
+       .has_pci                        = 1,
+
+       .enet0 = {
+               .has_phy                = 1,
+               .use_internal_phy       = 1,
+       },
+
+       .enet1 = {
+               .force_speed_100        = 1,
+               .force_duplex_full      = 1,
+       },
+
+
+       .has_ohci0 = 1,
+       .has_pccard = 1,
+       .has_ehci0 = 1,
+
+       .leds = {
+               {
+                       .name           = "adsl",
+                       .gpio           = 22,
+                       .active_low     = 1,
+               },
+               {
+                       .name           = "ppp-fail",
+                       .gpio           = 23,
+               },
+               {
+                       .name           = "power",
+                       .gpio           = 5,
+                       .active_low     = 1,
+                       .default_trigger = "default-on",
+               },
+               {
+                       .name           = "stop",
+                       .gpio           = 4,
+                       .active_low     = 1,
+               },
+       },
+};
+
+static struct board_info __initdata board_AGPFS0 = {
+       .name                           = "AGPF-S0",
+       .expected_cpu_id                = 0x6358,
+
+       .has_enet0                      = 1,
+       .has_enet1                      = 1,
+       .has_pci                        = 1,
+
+       .enet0 = {
+               .has_phy                = 1,
+               .use_internal_phy       = 1,
+       },
+
+       .enet1 = {
+               .force_speed_100        = 1,
+               .force_duplex_full      = 1,
+       },
+
+       .has_ohci0 = 1,
+       .has_ehci0 = 1,
+};
+#endif
+
+/*
+ * all boards
+ */
+static const struct board_info __initdata *bcm963xx_boards[] = {
+#ifdef CONFIG_BCM63XX_CPU_6338
+       &board_96338gw,
+       &board_96338w,
+#endif
+#ifdef CONFIG_BCM63XX_CPU_6345
+       &board_96345gw2,
+#endif
+#ifdef CONFIG_BCM63XX_CPU_6348
+       &board_96348r,
+       &board_96348gw,
+       &board_96348gw_10,
+       &board_96348gw_11,
+       &board_FAST2404,
+       &board_DV201AMR,
+       &board_96348gw_a,
+#endif
+
+#ifdef CONFIG_BCM63XX_CPU_6358
+       &board_96358vw,
+       &board_96358vw2,
+       &board_AGPFS0,
+#endif
+};
+
+/*
+ * early init callback, read nvram data from flash and checksum it
+ */
+void __init board_prom_init(void)
+{
+       unsigned int check_len, i;
+       u8 *boot_addr, *cfe, *p;
+       char cfe_version[32];
+       u32 val;
+
+       /* read base address of boot chip select (0)
+        * 6345 does not have MPI but boots from standard
+        * MIPS Flash address */
+       if (BCMCPU_IS_6345())
+               val = 0x1fc00000;
+       else {
+               val = bcm_mpi_readl(MPI_CSBASE_REG(0));
+               val &= MPI_CSBASE_BASE_MASK;
+       }
+       boot_addr = (u8 *)KSEG1ADDR(val);
+
+       /* dump cfe version */
+       cfe = boot_addr + BCM963XX_CFE_VERSION_OFFSET;
+       if (!memcmp(cfe, "cfe-v", 5))
+               snprintf(cfe_version, sizeof(cfe_version), "%u.%u.%u-%u.%u",
+                        cfe[5], cfe[6], cfe[7], cfe[8], cfe[9]);
+       else
+               strcpy(cfe_version, "unknown");
+       printk(KERN_INFO PFX "CFE version: %s\n", cfe_version);
+
+       /* extract nvram data */
+       memcpy(&nvram, boot_addr + BCM963XX_NVRAM_OFFSET, sizeof(nvram));
+
+       /* check checksum before using data */
+       if (nvram.version <= 4)
+               check_len = offsetof(struct bcm963xx_nvram, checksum_old);
+       else
+               check_len = sizeof(nvram);
+       val = 0;
+       p = (u8 *)&nvram;
+       while (check_len--)
+               val += *p;
+       if (val) {
+               printk(KERN_ERR PFX "invalid nvram checksum\n");
+               return;
+       }
+
+       /* find board by name */
+       for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) {
+               if (strncmp(nvram.name, bcm963xx_boards[i]->name,
+                           sizeof(nvram.name)))
+                       continue;
+               /* copy, board desc array is marked initdata */
+               memcpy(&board, bcm963xx_boards[i], sizeof(board));
+               break;
+       }
+
+       /* bail out if board is not found, will complain later */
+       if (!board.name[0]) {
+               char name[17];
+               memcpy(name, nvram.name, 16);
+               name[16] = 0;
+               printk(KERN_ERR PFX "unknown bcm963xx board: %s\n",
+                      name);
+               return;
+       }
+
+       /* setup pin multiplexing depending on board enabled device,
+        * this has to be done this early since PCI init is done
+        * inside arch_initcall */
+       val = 0;
+
+#ifdef CONFIG_PCI
+       if (board.has_pci) {
+               bcm63xx_pci_enabled = 1;
+               if (BCMCPU_IS_6348())
+                       val |= GPIO_MODE_6348_G2_PCI;
+       }
+#endif
+
+       if (board.has_pccard) {
+               if (BCMCPU_IS_6348())
+                       val |= GPIO_MODE_6348_G1_MII_PCCARD;
+       }
+
+       if (board.has_enet0 && !board.enet0.use_internal_phy) {
+               if (BCMCPU_IS_6348())
+                       val |= GPIO_MODE_6348_G3_EXT_MII |
+                               GPIO_MODE_6348_G0_EXT_MII;
+       }
+
+       if (board.has_enet1 && !board.enet1.use_internal_phy) {
+               if (BCMCPU_IS_6348())
+                       val |= GPIO_MODE_6348_G3_EXT_MII |
+                               GPIO_MODE_6348_G0_EXT_MII;
+       }
+
+       bcm_gpio_writel(val, GPIO_MODE_REG);
+}
+
+/*
+ * second stage init callback, good time to panic if we couldn't
+ * identify on which board we're running since early printk is working
+ */
+void __init board_setup(void)
+{
+       if (!board.name[0])
+               panic("unable to detect bcm963xx board");
+       printk(KERN_INFO PFX "board name: %s\n", board.name);
+
+       /* make sure we're running on expected cpu */
+       if (bcm63xx_get_cpu_id() != board.expected_cpu_id)
+               panic("unexpected CPU for bcm963xx board");
+}
+
+/*
+ * return board name for /proc/cpuinfo
+ */
+const char *board_get_name(void)
+{
+       return board.name;
+}
+
+/*
+ * register & return a new board mac address
+ */
+static int board_get_mac_address(u8 *mac)
+{
+       u8 *p;
+       int count;
+
+       if (mac_addr_used >= nvram.mac_addr_count) {
+               printk(KERN_ERR PFX "not enough mac address\n");
+               return -ENODEV;
+       }
+
+       memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
+       p = mac + ETH_ALEN - 1;
+       count = mac_addr_used;
+
+       while (count--) {
+               do {
+                       (*p)++;
+                       if (*p != 0)
+                               break;
+                       p--;
+               } while (p != mac);
+       }
+
+       if (p == mac) {
+               printk(KERN_ERR PFX "unable to fetch mac address\n");
+               return -ENODEV;
+       }
+
+       mac_addr_used++;
+       return 0;
+}
+
+static struct mtd_partition mtd_partitions[] = {
+       {
+               .name           = "cfe",
+               .offset         = 0x0,
+               .size           = 0x40000,
+       }
+};
+
+static struct physmap_flash_data flash_data = {
+       .width                  = 2,
+       .nr_parts               = ARRAY_SIZE(mtd_partitions),
+       .parts                  = mtd_partitions,
+};
+
+static struct resource mtd_resources[] = {
+       {
+               .start          = 0,    /* filled at runtime */
+               .end            = 0,    /* filled at runtime */
+               .flags          = IORESOURCE_MEM,
+       }
+};
+
+static struct platform_device mtd_dev = {
+       .name                   = "physmap-flash",
+       .resource               = mtd_resources,
+       .num_resources          = ARRAY_SIZE(mtd_resources),
+       .dev                    = {
+               .platform_data  = &flash_data,
+       },
+};
+
+/*
+ * Register a sane SPROMv2 to make the on-board
+ * bcm4318 WLAN work
+ */
+#ifdef CONFIG_SSB_PCIHOST
+static struct ssb_sprom bcm63xx_sprom = {
+       .revision               = 0x02,
+       .board_rev              = 0x17,
+       .country_code           = 0x0,
+       .ant_available_bg       = 0x3,
+       .pa0b0                  = 0x15ae,
+       .pa0b1                  = 0xfa85,
+       .pa0b2                  = 0xfe8d,
+       .pa1b0                  = 0xffff,
+       .pa1b1                  = 0xffff,
+       .pa1b2                  = 0xffff,
+       .gpio0                  = 0xff,
+       .gpio1                  = 0xff,
+       .gpio2                  = 0xff,
+       .gpio3                  = 0xff,
+       .maxpwr_bg              = 0x004c,
+       .itssi_bg               = 0x00,
+       .boardflags_lo          = 0x2848,
+       .boardflags_hi          = 0x0000,
+};
+#endif
+
+static struct gpio_led_platform_data bcm63xx_led_data;
+
+static struct platform_device bcm63xx_gpio_leds = {
+       .name                   = "leds-gpio",
+       .id                     = 0,
+       .dev.platform_data      = &bcm63xx_led_data,
+};
+
+/*
+ * third stage init callback, register all board devices.
+ */
+int __init board_register_devices(void)
+{
+       u32 val;
+
+       if (board.has_enet0 &&
+           !board_get_mac_address(board.enet0.mac_addr))
+               bcm63xx_enet_register(0, &board.enet0);
+
+       if (board.has_enet1 &&
+           !board_get_mac_address(board.enet1.mac_addr))
+               bcm63xx_enet_register(1, &board.enet1);
+
+       if (board.has_dsp)
+               bcm63xx_dsp_register(&board.dsp);
+
+       /* Generate MAC address for WLAN and
+        * register our SPROM */
+#ifdef CONFIG_SSB_PCIHOST
+       if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
+               memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
+               memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
+               if (ssb_arch_set_fallback_sprom(&bcm63xx_sprom) < 0)
+                       printk(KERN_ERR "failed to register fallback SPROM\n");
+       }
+#endif
+
+       /* read base address of boot chip select (0) */
+       if (BCMCPU_IS_6345())
+               val = 0x1fc00000;
+       else {
+               val = bcm_mpi_readl(MPI_CSBASE_REG(0));
+               val &= MPI_CSBASE_BASE_MASK;
+       }
+       mtd_resources[0].start = val;
+       mtd_resources[0].end = 0x1FFFFFFF;
+
+       platform_device_register(&mtd_dev);
+
+       bcm63xx_led_data.num_leds = ARRAY_SIZE(board.leds);
+       bcm63xx_led_data.leds = board.leds;
+
+       platform_device_register(&bcm63xx_gpio_leds);
+
+       return 0;
+}
+
diff --git a/arch/mips/bcm63xx/clk.c b/arch/mips/bcm63xx/clk.c
new file mode 100644 (file)
index 0000000..2c68ee9
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_clk.h>
+
+static DEFINE_MUTEX(clocks_mutex);
+
+
+static void clk_enable_unlocked(struct clk *clk)
+{
+       if (clk->set && (clk->usage++) == 0)
+               clk->set(clk, 1);
+}
+
+static void clk_disable_unlocked(struct clk *clk)
+{
+       if (clk->set && (--clk->usage) == 0)
+               clk->set(clk, 0);
+}
+
+static void bcm_hwclock_set(u32 mask, int enable)
+{
+       u32 reg;
+
+       reg = bcm_perf_readl(PERF_CKCTL_REG);
+       if (enable)
+               reg |= mask;
+       else
+               reg &= ~mask;
+       bcm_perf_writel(reg, PERF_CKCTL_REG);
+}
+
+/*
+ * Ethernet MAC "misc" clock: dma clocks and main clock on 6348
+ */
+static void enet_misc_set(struct clk *clk, int enable)
+{
+       u32 mask;
+
+       if (BCMCPU_IS_6338())
+               mask = CKCTL_6338_ENET_EN;
+       else if (BCMCPU_IS_6345())
+               mask = CKCTL_6345_ENET_EN;
+       else if (BCMCPU_IS_6348())
+               mask = CKCTL_6348_ENET_EN;
+       else
+               /* BCMCPU_IS_6358 */
+               mask = CKCTL_6358_EMUSB_EN;
+       bcm_hwclock_set(mask, enable);
+}
+
+static struct clk clk_enet_misc = {
+       .set    = enet_misc_set,
+};
+
+/*
+ * Ethernet MAC clocks: only revelant on 6358, silently enable misc
+ * clocks
+ */
+static void enetx_set(struct clk *clk, int enable)
+{
+       if (enable)
+               clk_enable_unlocked(&clk_enet_misc);
+       else
+               clk_disable_unlocked(&clk_enet_misc);
+
+       if (BCMCPU_IS_6358()) {
+               u32 mask;
+
+               if (clk->id == 0)
+                       mask = CKCTL_6358_ENET0_EN;
+               else
+                       mask = CKCTL_6358_ENET1_EN;
+               bcm_hwclock_set(mask, enable);
+       }
+}
+
+static struct clk clk_enet0 = {
+       .id     = 0,
+       .set    = enetx_set,
+};
+
+static struct clk clk_enet1 = {
+       .id     = 1,
+       .set    = enetx_set,
+};
+
+/*
+ * Ethernet PHY clock
+ */
+static void ephy_set(struct clk *clk, int enable)
+{
+       if (!BCMCPU_IS_6358())
+               return;
+       bcm_hwclock_set(CKCTL_6358_EPHY_EN, enable);
+}
+
+
+static struct clk clk_ephy = {
+       .set    = ephy_set,
+};
+
+/*
+ * PCM clock
+ */
+static void pcm_set(struct clk *clk, int enable)
+{
+       if (!BCMCPU_IS_6358())
+               return;
+       bcm_hwclock_set(CKCTL_6358_PCM_EN, enable);
+}
+
+static struct clk clk_pcm = {
+       .set    = pcm_set,
+};
+
+/*
+ * USB host clock
+ */
+static void usbh_set(struct clk *clk, int enable)
+{
+       if (!BCMCPU_IS_6348())
+               return;
+       bcm_hwclock_set(CKCTL_6348_USBH_EN, enable);
+}
+
+static struct clk clk_usbh = {
+       .set    = usbh_set,
+};
+
+/*
+ * SPI clock
+ */
+static void spi_set(struct clk *clk, int enable)
+{
+       u32 mask;
+
+       if (BCMCPU_IS_6338())
+               mask = CKCTL_6338_SPI_EN;
+       else if (BCMCPU_IS_6348())
+               mask = CKCTL_6348_SPI_EN;
+       else
+               /* BCMCPU_IS_6358 */
+               mask = CKCTL_6358_SPI_EN;
+       bcm_hwclock_set(mask, enable);
+}
+
+static struct clk clk_spi = {
+       .set    = spi_set,
+};
+
+/*
+ * Internal peripheral clock
+ */
+static struct clk clk_periph = {
+       .rate   = (50 * 1000 * 1000),
+};
+
+
+/*
+ * Linux clock API implementation
+ */
+int clk_enable(struct clk *clk)
+{
+       mutex_lock(&clocks_mutex);
+       clk_enable_unlocked(clk);
+       mutex_unlock(&clocks_mutex);
+       return 0;
+}
+
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+       mutex_lock(&clocks_mutex);
+       clk_disable_unlocked(clk);
+       mutex_unlock(&clocks_mutex);
+}
+
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+       return clk->rate;
+}
+
+EXPORT_SYMBOL(clk_get_rate);
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+       if (!strcmp(id, "enet0"))
+               return &clk_enet0;
+       if (!strcmp(id, "enet1"))
+               return &clk_enet1;
+       if (!strcmp(id, "ephy"))
+               return &clk_ephy;
+       if (!strcmp(id, "usbh"))
+               return &clk_usbh;
+       if (!strcmp(id, "spi"))
+               return &clk_spi;
+       if (!strcmp(id, "periph"))
+               return &clk_periph;
+       if (BCMCPU_IS_6358() && !strcmp(id, "pcm"))
+               return &clk_pcm;
+       return ERR_PTR(-ENOENT);
+}
+
+EXPORT_SYMBOL(clk_get);
+
+void clk_put(struct clk *clk)
+{
+}
+
+EXPORT_SYMBOL(clk_put);
diff --git a/arch/mips/bcm63xx/cpu.c b/arch/mips/bcm63xx/cpu.c
new file mode 100644 (file)
index 0000000..6dc43f0
--- /dev/null
@@ -0,0 +1,345 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ * Copyright (C) 2009 Florian Fainelli <florian@openwrt.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/cpu.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_irq.h>
+
+const unsigned long *bcm63xx_regs_base;
+EXPORT_SYMBOL(bcm63xx_regs_base);
+
+const int *bcm63xx_irqs;
+EXPORT_SYMBOL(bcm63xx_irqs);
+
+static u16 bcm63xx_cpu_id;
+static u16 bcm63xx_cpu_rev;
+static unsigned int bcm63xx_cpu_freq;
+static unsigned int bcm63xx_memory_size;
+
+/*
+ * 6338 register sets and irqs
+ */
+static const unsigned long bcm96338_regs_base[] = {
+       [RSET_DSL_LMEM]         = BCM_6338_DSL_LMEM_BASE,
+       [RSET_PERF]             = BCM_6338_PERF_BASE,
+       [RSET_TIMER]            = BCM_6338_TIMER_BASE,
+       [RSET_WDT]              = BCM_6338_WDT_BASE,
+       [RSET_UART0]            = BCM_6338_UART0_BASE,
+       [RSET_GPIO]             = BCM_6338_GPIO_BASE,
+       [RSET_SPI]              = BCM_6338_SPI_BASE,
+       [RSET_OHCI0]            = BCM_6338_OHCI0_BASE,
+       [RSET_OHCI_PRIV]        = BCM_6338_OHCI_PRIV_BASE,
+       [RSET_USBH_PRIV]        = BCM_6338_USBH_PRIV_BASE,
+       [RSET_UDC0]             = BCM_6338_UDC0_BASE,
+       [RSET_MPI]              = BCM_6338_MPI_BASE,
+       [RSET_PCMCIA]           = BCM_6338_PCMCIA_BASE,
+       [RSET_SDRAM]            = BCM_6338_SDRAM_BASE,
+       [RSET_DSL]              = BCM_6338_DSL_BASE,
+       [RSET_ENET0]            = BCM_6338_ENET0_BASE,
+       [RSET_ENET1]            = BCM_6338_ENET1_BASE,
+       [RSET_ENETDMA]          = BCM_6338_ENETDMA_BASE,
+       [RSET_MEMC]             = BCM_6338_MEMC_BASE,
+       [RSET_DDR]              = BCM_6338_DDR_BASE,
+};
+
+static const int bcm96338_irqs[] = {
+       [IRQ_TIMER]             = BCM_6338_TIMER_IRQ,
+       [IRQ_UART0]             = BCM_6338_UART0_IRQ,
+       [IRQ_DSL]               = BCM_6338_DSL_IRQ,
+       [IRQ_ENET0]             = BCM_6338_ENET0_IRQ,
+       [IRQ_ENET_PHY]          = BCM_6338_ENET_PHY_IRQ,
+       [IRQ_ENET0_RXDMA]       = BCM_6338_ENET0_RXDMA_IRQ,
+       [IRQ_ENET0_TXDMA]       = BCM_6338_ENET0_TXDMA_IRQ,
+};
+
+/*
+ * 6345 register sets and irqs
+ */
+static const unsigned long bcm96345_regs_base[] = {
+       [RSET_DSL_LMEM]         = BCM_6345_DSL_LMEM_BASE,
+       [RSET_PERF]             = BCM_6345_PERF_BASE,
+       [RSET_TIMER]            = BCM_6345_TIMER_BASE,
+       [RSET_WDT]              = BCM_6345_WDT_BASE,
+       [RSET_UART0]            = BCM_6345_UART0_BASE,
+       [RSET_GPIO]             = BCM_6345_GPIO_BASE,
+       [RSET_SPI]              = BCM_6345_SPI_BASE,
+       [RSET_UDC0]             = BCM_6345_UDC0_BASE,
+       [RSET_OHCI0]            = BCM_6345_OHCI0_BASE,
+       [RSET_OHCI_PRIV]        = BCM_6345_OHCI_PRIV_BASE,
+       [RSET_USBH_PRIV]        = BCM_6345_USBH_PRIV_BASE,
+       [RSET_MPI]              = BCM_6345_MPI_BASE,
+       [RSET_PCMCIA]           = BCM_6345_PCMCIA_BASE,
+       [RSET_DSL]              = BCM_6345_DSL_BASE,
+       [RSET_ENET0]            = BCM_6345_ENET0_BASE,
+       [RSET_ENET1]            = BCM_6345_ENET1_BASE,
+       [RSET_ENETDMA]          = BCM_6345_ENETDMA_BASE,
+       [RSET_EHCI0]            = BCM_6345_EHCI0_BASE,
+       [RSET_SDRAM]            = BCM_6345_SDRAM_BASE,
+       [RSET_MEMC]             = BCM_6345_MEMC_BASE,
+       [RSET_DDR]              = BCM_6345_DDR_BASE,
+};
+
+static const int bcm96345_irqs[] = {
+       [IRQ_TIMER]             = BCM_6345_TIMER_IRQ,
+       [IRQ_UART0]             = BCM_6345_UART0_IRQ,
+       [IRQ_DSL]               = BCM_6345_DSL_IRQ,
+       [IRQ_ENET0]             = BCM_6345_ENET0_IRQ,
+       [IRQ_ENET_PHY]          = BCM_6345_ENET_PHY_IRQ,
+       [IRQ_ENET0_RXDMA]       = BCM_6345_ENET0_RXDMA_IRQ,
+       [IRQ_ENET0_TXDMA]       = BCM_6345_ENET0_TXDMA_IRQ,
+};
+
+/*
+ * 6348 register sets and irqs
+ */
+static const unsigned long bcm96348_regs_base[] = {
+       [RSET_DSL_LMEM]         = BCM_6348_DSL_LMEM_BASE,
+       [RSET_PERF]             = BCM_6348_PERF_BASE,
+       [RSET_TIMER]            = BCM_6348_TIMER_BASE,
+       [RSET_WDT]              = BCM_6348_WDT_BASE,
+       [RSET_UART0]            = BCM_6348_UART0_BASE,
+       [RSET_GPIO]             = BCM_6348_GPIO_BASE,
+       [RSET_SPI]              = BCM_6348_SPI_BASE,
+       [RSET_OHCI0]            = BCM_6348_OHCI0_BASE,
+       [RSET_OHCI_PRIV]        = BCM_6348_OHCI_PRIV_BASE,
+       [RSET_USBH_PRIV]        = BCM_6348_USBH_PRIV_BASE,
+       [RSET_MPI]              = BCM_6348_MPI_BASE,
+       [RSET_PCMCIA]           = BCM_6348_PCMCIA_BASE,
+       [RSET_SDRAM]            = BCM_6348_SDRAM_BASE,
+       [RSET_DSL]              = BCM_6348_DSL_BASE,
+       [RSET_ENET0]            = BCM_6348_ENET0_BASE,
+       [RSET_ENET1]            = BCM_6348_ENET1_BASE,
+       [RSET_ENETDMA]          = BCM_6348_ENETDMA_BASE,
+       [RSET_MEMC]             = BCM_6348_MEMC_BASE,
+       [RSET_DDR]              = BCM_6348_DDR_BASE,
+};
+
+static const int bcm96348_irqs[] = {
+       [IRQ_TIMER]             = BCM_6348_TIMER_IRQ,
+       [IRQ_UART0]             = BCM_6348_UART0_IRQ,
+       [IRQ_DSL]               = BCM_6348_DSL_IRQ,
+       [IRQ_ENET0]             = BCM_6348_ENET0_IRQ,
+       [IRQ_ENET1]             = BCM_6348_ENET1_IRQ,
+       [IRQ_ENET_PHY]          = BCM_6348_ENET_PHY_IRQ,
+       [IRQ_OHCI0]             = BCM_6348_OHCI0_IRQ,
+       [IRQ_PCMCIA]            = BCM_6348_PCMCIA_IRQ,
+       [IRQ_ENET0_RXDMA]       = BCM_6348_ENET0_RXDMA_IRQ,
+       [IRQ_ENET0_TXDMA]       = BCM_6348_ENET0_TXDMA_IRQ,
+       [IRQ_ENET1_RXDMA]       = BCM_6348_ENET1_RXDMA_IRQ,
+       [IRQ_ENET1_TXDMA]       = BCM_6348_ENET1_TXDMA_IRQ,
+       [IRQ_PCI]               = BCM_6348_PCI_IRQ,
+};
+
+/*
+ * 6358 register sets and irqs
+ */
+static const unsigned long bcm96358_regs_base[] = {
+       [RSET_DSL_LMEM]         = BCM_6358_DSL_LMEM_BASE,
+       [RSET_PERF]             = BCM_6358_PERF_BASE,
+       [RSET_TIMER]            = BCM_6358_TIMER_BASE,
+       [RSET_WDT]              = BCM_6358_WDT_BASE,
+       [RSET_UART0]            = BCM_6358_UART0_BASE,
+       [RSET_GPIO]             = BCM_6358_GPIO_BASE,
+       [RSET_SPI]              = BCM_6358_SPI_BASE,
+       [RSET_OHCI0]            = BCM_6358_OHCI0_BASE,
+       [RSET_EHCI0]            = BCM_6358_EHCI0_BASE,
+       [RSET_OHCI_PRIV]        = BCM_6358_OHCI_PRIV_BASE,
+       [RSET_USBH_PRIV]        = BCM_6358_USBH_PRIV_BASE,
+       [RSET_MPI]              = BCM_6358_MPI_BASE,
+       [RSET_PCMCIA]           = BCM_6358_PCMCIA_BASE,
+       [RSET_SDRAM]            = BCM_6358_SDRAM_BASE,
+       [RSET_DSL]              = BCM_6358_DSL_BASE,
+       [RSET_ENET0]            = BCM_6358_ENET0_BASE,
+       [RSET_ENET1]            = BCM_6358_ENET1_BASE,
+       [RSET_ENETDMA]          = BCM_6358_ENETDMA_BASE,
+       [RSET_MEMC]             = BCM_6358_MEMC_BASE,
+       [RSET_DDR]              = BCM_6358_DDR_BASE,
+};
+
+static const int bcm96358_irqs[] = {
+       [IRQ_TIMER]             = BCM_6358_TIMER_IRQ,
+       [IRQ_UART0]             = BCM_6358_UART0_IRQ,
+       [IRQ_DSL]               = BCM_6358_DSL_IRQ,
+       [IRQ_ENET0]             = BCM_6358_ENET0_IRQ,
+       [IRQ_ENET1]             = BCM_6358_ENET1_IRQ,
+       [IRQ_ENET_PHY]          = BCM_6358_ENET_PHY_IRQ,
+       [IRQ_OHCI0]             = BCM_6358_OHCI0_IRQ,
+       [IRQ_EHCI0]             = BCM_6358_EHCI0_IRQ,
+       [IRQ_PCMCIA]            = BCM_6358_PCMCIA_IRQ,
+       [IRQ_ENET0_RXDMA]       = BCM_6358_ENET0_RXDMA_IRQ,
+       [IRQ_ENET0_TXDMA]       = BCM_6358_ENET0_TXDMA_IRQ,
+       [IRQ_ENET1_RXDMA]       = BCM_6358_ENET1_RXDMA_IRQ,
+       [IRQ_ENET1_TXDMA]       = BCM_6358_ENET1_TXDMA_IRQ,
+       [IRQ_PCI]               = BCM_6358_PCI_IRQ,
+};
+
+u16 __bcm63xx_get_cpu_id(void)
+{
+       return bcm63xx_cpu_id;
+}
+
+EXPORT_SYMBOL(__bcm63xx_get_cpu_id);
+
+u16 bcm63xx_get_cpu_rev(void)
+{
+       return bcm63xx_cpu_rev;
+}
+
+EXPORT_SYMBOL(bcm63xx_get_cpu_rev);
+
+unsigned int bcm63xx_get_cpu_freq(void)
+{
+       return bcm63xx_cpu_freq;
+}
+
+unsigned int bcm63xx_get_memory_size(void)
+{
+       return bcm63xx_memory_size;
+}
+
+static unsigned int detect_cpu_clock(void)
+{
+       unsigned int tmp, n1 = 0, n2 = 0, m1 = 0;
+
+       /* BCM6338 has a fixed 240 Mhz frequency */
+       if (BCMCPU_IS_6338())
+               return 240000000;
+
+       /* BCM6345 has a fixed 140Mhz frequency */
+       if (BCMCPU_IS_6345())
+               return 140000000;
+
+       /*
+        * frequency depends on PLL configuration:
+        */
+       if (BCMCPU_IS_6348()) {
+               /* 16MHz * (N1 + 1) * (N2 + 2) / (M1_CPU + 1) */
+               tmp = bcm_perf_readl(PERF_MIPSPLLCTL_REG);
+               n1 = (tmp & MIPSPLLCTL_N1_MASK) >> MIPSPLLCTL_N1_SHIFT;
+               n2 = (tmp & MIPSPLLCTL_N2_MASK) >> MIPSPLLCTL_N2_SHIFT;
+               m1 = (tmp & MIPSPLLCTL_M1CPU_MASK) >> MIPSPLLCTL_M1CPU_SHIFT;
+               n1 += 1;
+               n2 += 2;
+               m1 += 1;
+       }
+
+       if (BCMCPU_IS_6358()) {
+               /* 16MHz * N1 * N2 / M1_CPU */
+               tmp = bcm_ddr_readl(DDR_DMIPSPLLCFG_REG);
+               n1 = (tmp & DMIPSPLLCFG_N1_MASK) >> DMIPSPLLCFG_N1_SHIFT;
+               n2 = (tmp & DMIPSPLLCFG_N2_MASK) >> DMIPSPLLCFG_N2_SHIFT;
+               m1 = (tmp & DMIPSPLLCFG_M1_MASK) >> DMIPSPLLCFG_M1_SHIFT;
+       }
+
+       return (16 * 1000000 * n1 * n2) / m1;
+}
+
+/*
+ * attempt to detect the amount of memory installed
+ */
+static unsigned int detect_memory_size(void)
+{
+       unsigned int cols = 0, rows = 0, is_32bits = 0, banks = 0;
+       u32 val;
+
+       if (BCMCPU_IS_6345())
+               return (8 * 1024 * 1024);
+
+       if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) {
+               val = bcm_sdram_readl(SDRAM_CFG_REG);
+               rows = (val & SDRAM_CFG_ROW_MASK) >> SDRAM_CFG_ROW_SHIFT;
+               cols = (val & SDRAM_CFG_COL_MASK) >> SDRAM_CFG_COL_SHIFT;
+               is_32bits = (val & SDRAM_CFG_32B_MASK) ? 1 : 0;
+               banks = (val & SDRAM_CFG_BANK_MASK) ? 2 : 1;
+       }
+
+       if (BCMCPU_IS_6358()) {
+               val = bcm_memc_readl(MEMC_CFG_REG);
+               rows = (val & MEMC_CFG_ROW_MASK) >> MEMC_CFG_ROW_SHIFT;
+               cols = (val & MEMC_CFG_COL_MASK) >> MEMC_CFG_COL_SHIFT;
+               is_32bits = (val & MEMC_CFG_32B_MASK) ? 0 : 1;
+               banks = 2;
+       }
+
+       /* 0 => 11 address bits ... 2 => 13 address bits */
+       rows += 11;
+
+       /* 0 => 8 address bits ... 2 => 10 address bits */
+       cols += 8;
+
+       return 1 << (cols + rows + (is_32bits + 1) + banks);
+}
+
+void __init bcm63xx_cpu_init(void)
+{
+       unsigned int tmp, expected_cpu_id;
+       struct cpuinfo_mips *c = &current_cpu_data;
+
+       /* soc registers location depends on cpu type */
+       expected_cpu_id = 0;
+
+       switch (c->cputype) {
+       /*
+        * BCM6338 as the same PrId as BCM3302 see arch/mips/kernel/cpu-probe.c
+        */
+       case CPU_BCM3302:
+               expected_cpu_id = BCM6338_CPU_ID;
+               bcm63xx_regs_base = bcm96338_regs_base;
+               bcm63xx_irqs = bcm96338_irqs;
+               break;
+       case CPU_BCM6345:
+               expected_cpu_id = BCM6345_CPU_ID;
+               bcm63xx_regs_base = bcm96345_regs_base;
+               bcm63xx_irqs = bcm96345_irqs;
+               break;
+       case CPU_BCM6348:
+               expected_cpu_id = BCM6348_CPU_ID;
+               bcm63xx_regs_base = bcm96348_regs_base;
+               bcm63xx_irqs = bcm96348_irqs;
+               break;
+       case CPU_BCM6358:
+               expected_cpu_id = BCM6358_CPU_ID;
+               bcm63xx_regs_base = bcm96358_regs_base;
+               bcm63xx_irqs = bcm96358_irqs;
+               break;
+       }
+
+       /*
+        * really early to panic, but delaying panic would not help since we
+        * will never get any working console
+        */
+       if (!expected_cpu_id)
+               panic("unsupported Broadcom CPU");
+
+       /*
+        * bcm63xx_regs_base is set, we can access soc registers
+        */
+
+       /* double check CPU type */
+       tmp = bcm_perf_readl(PERF_REV_REG);
+       bcm63xx_cpu_id = (tmp & REV_CHIPID_MASK) >> REV_CHIPID_SHIFT;
+       bcm63xx_cpu_rev = (tmp & REV_REVID_MASK) >> REV_REVID_SHIFT;
+
+       if (bcm63xx_cpu_id != expected_cpu_id)
+               panic("bcm63xx CPU id mismatch");
+
+       bcm63xx_cpu_freq = detect_cpu_clock();
+       bcm63xx_memory_size = detect_memory_size();
+
+       printk(KERN_INFO "Detected Broadcom 0x%04x CPU revision %02x\n",
+              bcm63xx_cpu_id, bcm63xx_cpu_rev);
+       printk(KERN_INFO "CPU frequency is %u MHz\n",
+              bcm63xx_cpu_freq / 1000000);
+       printk(KERN_INFO "%uMB of RAM installed\n",
+              bcm63xx_memory_size >> 20);
+}
diff --git a/arch/mips/bcm63xx/cs.c b/arch/mips/bcm63xx/cs.c
new file mode 100644 (file)
index 0000000..50d8190
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/log2.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_cs.h>
+
+static DEFINE_SPINLOCK(bcm63xx_cs_lock);
+
+/*
+ * check if given chip select exists
+ */
+static int is_valid_cs(unsigned int cs)
+{
+       if (cs > 6)
+               return 0;
+       return 1;
+}
+
+/*
+ * Configure chipselect base address and size (bytes).
+ * Size must be a power of two between 8k and 256M.
+ */
+int bcm63xx_set_cs_base(unsigned int cs, u32 base, unsigned int size)
+{
+       unsigned long flags;
+       u32 val;
+
+       if (!is_valid_cs(cs))
+               return -EINVAL;
+
+       /* sanity check on size */
+       if (size != roundup_pow_of_two(size))
+               return -EINVAL;
+
+       if (size < 8 * 1024 || size > 256 * 1024 * 1024)
+               return -EINVAL;
+
+       val = (base & MPI_CSBASE_BASE_MASK);
+       /* 8k => 0 - 256M => 15 */
+       val |= (ilog2(size) - ilog2(8 * 1024)) << MPI_CSBASE_SIZE_SHIFT;
+
+       spin_lock_irqsave(&bcm63xx_cs_lock, flags);
+       bcm_mpi_writel(val, MPI_CSBASE_REG(cs));
+       spin_unlock_irqrestore(&bcm63xx_cs_lock, flags);
+
+       return 0;
+}
+
+EXPORT_SYMBOL(bcm63xx_set_cs_base);
+
+/*
+ * configure chipselect timing (ns)
+ */
+int bcm63xx_set_cs_timing(unsigned int cs, unsigned int wait,
+                          unsigned int setup, unsigned int hold)
+{
+       unsigned long flags;
+       u32 val;
+
+       if (!is_valid_cs(cs))
+               return -EINVAL;
+
+       spin_lock_irqsave(&bcm63xx_cs_lock, flags);
+       val = bcm_mpi_readl(MPI_CSCTL_REG(cs));
+       val &= ~(MPI_CSCTL_WAIT_MASK);
+       val &= ~(MPI_CSCTL_SETUP_MASK);
+       val &= ~(MPI_CSCTL_HOLD_MASK);
+       val |= wait << MPI_CSCTL_WAIT_SHIFT;
+       val |= setup << MPI_CSCTL_SETUP_SHIFT;
+       val |= hold << MPI_CSCTL_HOLD_SHIFT;
+       bcm_mpi_writel(val, MPI_CSCTL_REG(cs));
+       spin_unlock_irqrestore(&bcm63xx_cs_lock, flags);
+
+       return 0;
+}
+
+EXPORT_SYMBOL(bcm63xx_set_cs_timing);
+
+/*
+ * configure other chipselect parameter (data bus size, ...)
+ */
+int bcm63xx_set_cs_param(unsigned int cs, u32 params)
+{
+       unsigned long flags;
+       u32 val;
+
+       if (!is_valid_cs(cs))
+               return -EINVAL;
+
+       /* none of this fields apply to pcmcia */
+       if (cs == MPI_CS_PCMCIA_COMMON ||
+           cs == MPI_CS_PCMCIA_ATTR ||
+           cs == MPI_CS_PCMCIA_IO)
+               return -EINVAL;
+
+       spin_lock_irqsave(&bcm63xx_cs_lock, flags);
+       val = bcm_mpi_readl(MPI_CSCTL_REG(cs));
+       val &= ~(MPI_CSCTL_DATA16_MASK);
+       val &= ~(MPI_CSCTL_SYNCMODE_MASK);
+       val &= ~(MPI_CSCTL_TSIZE_MASK);
+       val &= ~(MPI_CSCTL_ENDIANSWAP_MASK);
+       val |= params;
+       bcm_mpi_writel(val, MPI_CSCTL_REG(cs));
+       spin_unlock_irqrestore(&bcm63xx_cs_lock, flags);
+
+       return 0;
+}
+
+EXPORT_SYMBOL(bcm63xx_set_cs_param);
+
+/*
+ * set cs status (enable/disable)
+ */
+int bcm63xx_set_cs_status(unsigned int cs, int enable)
+{
+       unsigned long flags;
+       u32 val;
+
+       if (!is_valid_cs(cs))
+               return -EINVAL;
+
+       spin_lock_irqsave(&bcm63xx_cs_lock, flags);
+       val = bcm_mpi_readl(MPI_CSCTL_REG(cs));
+       if (enable)
+               val |= MPI_CSCTL_ENABLE_MASK;
+       else
+               val &= ~MPI_CSCTL_ENABLE_MASK;
+       bcm_mpi_writel(val, MPI_CSCTL_REG(cs));
+       spin_unlock_irqrestore(&bcm63xx_cs_lock, flags);
+       return 0;
+}
+
+EXPORT_SYMBOL(bcm63xx_set_cs_status);
diff --git a/arch/mips/bcm63xx/dev-dsp.c b/arch/mips/bcm63xx/dev-dsp.c
new file mode 100644 (file)
index 0000000..da46d1d
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Broadcom BCM63xx VoIP DSP registration
+ *
+ * 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) 2009 Florian Fainelli <florian@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_dev_dsp.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_io.h>
+
+static struct resource voip_dsp_resources[] = {
+       {
+               .start          = -1, /* filled at runtime */
+               .end            = -1, /* filled at runtime */
+               .flags          = IORESOURCE_MEM,
+       },
+       {
+               .start          = -1, /* filled at runtime */
+               .flags          = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bcm63xx_voip_dsp_device = {
+       .name           = "bcm63xx-voip-dsp",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(voip_dsp_resources),
+       .resource       = voip_dsp_resources,
+};
+
+int __init bcm63xx_dsp_register(const struct bcm63xx_dsp_platform_data *pd)
+{
+       struct bcm63xx_dsp_platform_data *dpd;
+       u32 val;
+
+       /* Get the memory window */
+       val = bcm_mpi_readl(MPI_CSBASE_REG(pd->cs - 1));
+       val &= MPI_CSBASE_BASE_MASK;
+       voip_dsp_resources[0].start = val;
+       voip_dsp_resources[0].end = val + 0xFFFFFFF;
+       voip_dsp_resources[1].start = pd->ext_irq;
+
+       /* copy given platform data */
+       dpd = bcm63xx_voip_dsp_device.dev.platform_data;
+       memcpy(dpd, pd, sizeof (*pd));
+
+       return platform_device_register(&bcm63xx_voip_dsp_device);
+}
diff --git a/arch/mips/bcm63xx/dev-enet.c b/arch/mips/bcm63xx/dev-enet.c
new file mode 100644 (file)
index 0000000..9f544ba
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <bcm63xx_dev_enet.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_regs.h>
+
+static struct resource shared_res[] = {
+       {
+               .start          = -1, /* filled at runtime */
+               .end            = -1, /* filled at runtime */
+               .flags          = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device bcm63xx_enet_shared_device = {
+       .name           = "bcm63xx_enet_shared",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(shared_res),
+       .resource       = shared_res,
+};
+
+static int shared_device_registered;
+
+static struct resource enet0_res[] = {
+       {
+               .start          = -1, /* filled at runtime */
+               .end            = -1, /* filled at runtime */
+               .flags          = IORESOURCE_MEM,
+       },
+       {
+               .start          = -1, /* filled at runtime */
+               .flags          = IORESOURCE_IRQ,
+       },
+       {
+               .start          = -1, /* filled at runtime */
+               .flags          = IORESOURCE_IRQ,
+       },
+       {
+               .start          = -1, /* filled at runtime */
+               .flags          = IORESOURCE_IRQ,
+       },
+};
+
+static struct bcm63xx_enet_platform_data enet0_pd;
+
+static struct platform_device bcm63xx_enet0_device = {
+       .name           = "bcm63xx_enet",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(enet0_res),
+       .resource       = enet0_res,
+       .dev            = {
+               .platform_data = &enet0_pd,
+       },
+};
+
+static struct resource enet1_res[] = {
+       {
+               .start          = -1, /* filled at runtime */
+               .end            = -1, /* filled at runtime */
+               .flags          = IORESOURCE_MEM,
+       },
+       {
+               .start          = -1, /* filled at runtime */
+               .flags          = IORESOURCE_IRQ,
+       },
+       {
+               .start          = -1, /* filled at runtime */
+               .flags          = IORESOURCE_IRQ,
+       },
+       {
+               .start          = -1, /* filled at runtime */
+               .flags          = IORESOURCE_IRQ,
+       },
+};
+
+static struct bcm63xx_enet_platform_data enet1_pd;
+
+static struct platform_device bcm63xx_enet1_device = {
+       .name           = "bcm63xx_enet",
+       .id             = 1,
+       .num_resources  = ARRAY_SIZE(enet1_res),
+       .resource       = enet1_res,
+       .dev            = {
+               .platform_data = &enet1_pd,
+       },
+};
+
+int __init bcm63xx_enet_register(int unit,
+                                const struct bcm63xx_enet_platform_data *pd)
+{
+       struct platform_device *pdev;
+       struct bcm63xx_enet_platform_data *dpd;
+       int ret;
+
+       if (unit > 1)
+               return -ENODEV;
+
+       if (!shared_device_registered) {
+               shared_res[0].start = bcm63xx_regset_address(RSET_ENETDMA);
+               shared_res[0].end = shared_res[0].start;
+               if (BCMCPU_IS_6338())
+                       shared_res[0].end += (RSET_ENETDMA_SIZE / 2)  - 1;
+               else
+                       shared_res[0].end += (RSET_ENETDMA_SIZE)  - 1;
+
+               ret = platform_device_register(&bcm63xx_enet_shared_device);
+               if (ret)
+                       return ret;
+               shared_device_registered = 1;
+       }
+
+       if (unit == 0) {
+               enet0_res[0].start = bcm63xx_regset_address(RSET_ENET0);
+               enet0_res[0].end = enet0_res[0].start;
+               enet0_res[0].end += RSET_ENET_SIZE - 1;
+               enet0_res[1].start = bcm63xx_get_irq_number(IRQ_ENET0);
+               enet0_res[2].start = bcm63xx_get_irq_number(IRQ_ENET0_RXDMA);
+               enet0_res[3].start = bcm63xx_get_irq_number(IRQ_ENET0_TXDMA);
+               pdev = &bcm63xx_enet0_device;
+       } else {
+               enet1_res[0].start = bcm63xx_regset_address(RSET_ENET1);
+               enet1_res[0].end = enet1_res[0].start;
+               enet1_res[0].end += RSET_ENET_SIZE - 1;
+               enet1_res[1].start = bcm63xx_get_irq_number(IRQ_ENET1);
+               enet1_res[2].start = bcm63xx_get_irq_number(IRQ_ENET1_RXDMA);
+               enet1_res[3].start = bcm63xx_get_irq_number(IRQ_ENET1_TXDMA);
+               pdev = &bcm63xx_enet1_device;
+       }
+
+       /* copy given platform data */
+       dpd = pdev->dev.platform_data;
+       memcpy(dpd, pd, sizeof(*pd));
+
+       /* adjust them in case internal phy is used */
+       if (dpd->use_internal_phy) {
+
+               /* internal phy only exists for enet0 */
+               if (unit == 1)
+                       return -ENODEV;
+
+               dpd->phy_id = 1;
+               dpd->has_phy_interrupt = 1;
+               dpd->phy_interrupt = bcm63xx_get_irq_number(IRQ_ENET_PHY);
+       }
+
+       ret = platform_device_register(pdev);
+       if (ret)
+               return ret;
+       return 0;
+}
diff --git a/arch/mips/bcm63xx/early_printk.c b/arch/mips/bcm63xx/early_printk.c
new file mode 100644 (file)
index 0000000..bf353c9
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/init.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_regs.h>
+
+static void __init wait_xfered(void)
+{
+       unsigned int val;
+
+       /* wait for any previous char to be transmitted */
+       do {
+               val = bcm_uart0_readl(UART_IR_REG);
+               if (val & UART_IR_STAT(UART_IR_TXEMPTY))
+                       break;
+       } while (1);
+}
+
+void __init prom_putchar(char c)
+{
+       wait_xfered();
+       bcm_uart0_writel(c, UART_FIFO_REG);
+       wait_xfered();
+}
diff --git a/arch/mips/bcm63xx/gpio.c b/arch/mips/bcm63xx/gpio.c
new file mode 100644 (file)
index 0000000..87ca390
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_gpio.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_regs.h>
+
+static DEFINE_SPINLOCK(bcm63xx_gpio_lock);
+static u32 gpio_out_low, gpio_out_high;
+
+static void bcm63xx_gpio_set(struct gpio_chip *chip,
+                            unsigned gpio, int val)
+{
+       u32 reg;
+       u32 mask;
+       u32 *v;
+       unsigned long flags;
+
+       if (gpio >= chip->ngpio)
+               BUG();
+
+       if (gpio < 32) {
+               reg = GPIO_DATA_LO_REG;
+               mask = 1 << gpio;
+               v = &gpio_out_low;
+       } else {
+               reg = GPIO_DATA_HI_REG;
+               mask = 1 << (gpio - 32);
+               v = &gpio_out_high;
+       }
+
+       spin_lock_irqsave(&bcm63xx_gpio_lock, flags);
+       if (val)
+               *v |= mask;
+       else
+               *v &= ~mask;
+       bcm_gpio_writel(*v, reg);
+       spin_unlock_irqrestore(&bcm63xx_gpio_lock, flags);
+}
+
+static int bcm63xx_gpio_get(struct gpio_chip *chip, unsigned gpio)
+{
+       u32 reg;
+       u32 mask;
+
+       if (gpio >= chip->ngpio)
+               BUG();
+
+       if (gpio < 32) {
+               reg = GPIO_DATA_LO_REG;
+               mask = 1 << gpio;
+       } else {
+               reg = GPIO_DATA_HI_REG;
+               mask = 1 << (gpio - 32);
+       }
+
+       return !!(bcm_gpio_readl(reg) & mask);
+}
+
+static int bcm63xx_gpio_set_direction(struct gpio_chip *chip,
+                                     unsigned gpio, int dir)
+{
+       u32 reg;
+       u32 mask;
+       u32 tmp;
+       unsigned long flags;
+
+       if (gpio >= chip->ngpio)
+               BUG();
+
+       if (gpio < 32) {
+               reg = GPIO_CTL_LO_REG;
+               mask = 1 << gpio;
+       } else {
+               reg = GPIO_CTL_HI_REG;
+               mask = 1 << (gpio - 32);
+       }
+
+       spin_lock_irqsave(&bcm63xx_gpio_lock, flags);
+       tmp = bcm_gpio_readl(reg);
+       if (dir == GPIO_DIR_IN)
+               tmp &= ~mask;
+       else
+               tmp |= mask;
+       bcm_gpio_writel(tmp, reg);
+       spin_unlock_irqrestore(&bcm63xx_gpio_lock, flags);
+
+       return 0;
+}
+
+static int bcm63xx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
+{
+       return bcm63xx_gpio_set_direction(chip, gpio, GPIO_DIR_IN);
+}
+
+static int bcm63xx_gpio_direction_output(struct gpio_chip *chip,
+                                        unsigned gpio, int value)
+{
+       bcm63xx_gpio_set(chip, gpio, value);
+       return bcm63xx_gpio_set_direction(chip, gpio, GPIO_DIR_OUT);
+}
+
+
+static struct gpio_chip bcm63xx_gpio_chip = {
+       .label                  = "bcm63xx-gpio",
+       .direction_input        = bcm63xx_gpio_direction_input,
+       .direction_output       = bcm63xx_gpio_direction_output,
+       .get                    = bcm63xx_gpio_get,
+       .set                    = bcm63xx_gpio_set,
+       .base                   = 0,
+};
+
+int __init bcm63xx_gpio_init(void)
+{
+       bcm63xx_gpio_chip.ngpio = bcm63xx_gpio_count();
+       pr_info("registering %d GPIOs\n", bcm63xx_gpio_chip.ngpio);
+
+       return gpiochip_add(&bcm63xx_gpio_chip);
+}
+
+arch_initcall(bcm63xx_gpio_init);
diff --git a/arch/mips/bcm63xx/irq.c b/arch/mips/bcm63xx/irq.c
new file mode 100644 (file)
index 0000000..a0c5cd1
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ * Copyright (C) 2008 Nicolas Schichan <nschichan@freebox.fr>
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_irq.h>
+
+/*
+ * dispatch internal devices IRQ (uart, enet, watchdog, ...). do not
+ * prioritize any interrupt relatively to another. the static counter
+ * will resume the loop where it ended the last time we left this
+ * function.
+ */
+static void bcm63xx_irq_dispatch_internal(void)
+{
+       u32 pending;
+       static int i;
+
+       pending = bcm_perf_readl(PERF_IRQMASK_REG) &
+               bcm_perf_readl(PERF_IRQSTAT_REG);
+
+       if (!pending)
+               return ;
+
+       while (1) {
+               int to_call = i;
+
+               i = (i + 1) & 0x1f;
+               if (pending & (1 << to_call)) {
+                       do_IRQ(to_call + IRQ_INTERNAL_BASE);
+                       break;
+               }
+       }
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+       u32 cause;
+
+       do {
+               cause = read_c0_cause() & read_c0_status() & ST0_IM;
+
+               if (!cause)
+                       break;
+
+               if (cause & CAUSEF_IP7)
+                       do_IRQ(7);
+               if (cause & CAUSEF_IP2)
+                       bcm63xx_irq_dispatch_internal();
+               if (cause & CAUSEF_IP3)
+                       do_IRQ(IRQ_EXT_0);
+               if (cause & CAUSEF_IP4)
+                       do_IRQ(IRQ_EXT_1);
+               if (cause & CAUSEF_IP5)
+                       do_IRQ(IRQ_EXT_2);
+               if (cause & CAUSEF_IP6)
+                       do_IRQ(IRQ_EXT_3);
+       } while (1);
+}
+
+/*
+ * internal IRQs operations: only mask/unmask on PERF irq mask
+ * register.
+ */
+static inline void bcm63xx_internal_irq_mask(unsigned int irq)
+{
+       u32 mask;
+
+       irq -= IRQ_INTERNAL_BASE;
+       mask = bcm_perf_readl(PERF_IRQMASK_REG);
+       mask &= ~(1 << irq);
+       bcm_perf_writel(mask, PERF_IRQMASK_REG);
+}
+
+static void bcm63xx_internal_irq_unmask(unsigned int irq)
+{
+       u32 mask;
+
+       irq -= IRQ_INTERNAL_BASE;
+       mask = bcm_perf_readl(PERF_IRQMASK_REG);
+       mask |= (1 << irq);
+       bcm_perf_writel(mask, PERF_IRQMASK_REG);
+}
+
+static unsigned int bcm63xx_internal_irq_startup(unsigned int irq)
+{
+       bcm63xx_internal_irq_unmask(irq);
+       return 0;
+}
+
+/*
+ * external IRQs operations: mask/unmask and clear on PERF external
+ * irq control register.
+ */
+static void bcm63xx_external_irq_mask(unsigned int irq)
+{
+       u32 reg;
+
+       irq -= IRQ_EXT_BASE;
+       reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
+       reg &= ~EXTIRQ_CFG_MASK(irq);
+       bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
+}
+
+static void bcm63xx_external_irq_unmask(unsigned int irq)
+{
+       u32 reg;
+
+       irq -= IRQ_EXT_BASE;
+       reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
+       reg |= EXTIRQ_CFG_MASK(irq);
+       bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
+}
+
+static void bcm63xx_external_irq_clear(unsigned int irq)
+{
+       u32 reg;
+
+       irq -= IRQ_EXT_BASE;
+       reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
+       reg |= EXTIRQ_CFG_CLEAR(irq);
+       bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
+}
+
+static unsigned int bcm63xx_external_irq_startup(unsigned int irq)
+{
+       set_c0_status(0x100 << (irq - IRQ_MIPS_BASE));
+       irq_enable_hazard();
+       bcm63xx_external_irq_unmask(irq);
+       return 0;
+}
+
+static void bcm63xx_external_irq_shutdown(unsigned int irq)
+{
+       bcm63xx_external_irq_mask(irq);
+       clear_c0_status(0x100 << (irq - IRQ_MIPS_BASE));
+       irq_disable_hazard();
+}
+
+static int bcm63xx_external_irq_set_type(unsigned int irq,
+                                        unsigned int flow_type)
+{
+       u32 reg;
+       struct irq_desc *desc = irq_desc + irq;
+
+       irq -= IRQ_EXT_BASE;
+
+       flow_type &= IRQ_TYPE_SENSE_MASK;
+
+       if (flow_type == IRQ_TYPE_NONE)
+               flow_type = IRQ_TYPE_LEVEL_LOW;
+
+       reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
+       switch (flow_type) {
+       case IRQ_TYPE_EDGE_BOTH:
+               reg &= ~EXTIRQ_CFG_LEVELSENSE(irq);
+               reg |= EXTIRQ_CFG_BOTHEDGE(irq);
+               break;
+
+       case IRQ_TYPE_EDGE_RISING:
+               reg &= ~EXTIRQ_CFG_LEVELSENSE(irq);
+               reg |= EXTIRQ_CFG_SENSE(irq);
+               reg &= ~EXTIRQ_CFG_BOTHEDGE(irq);
+               break;
+
+       case IRQ_TYPE_EDGE_FALLING:
+               reg &= ~EXTIRQ_CFG_LEVELSENSE(irq);
+               reg &= ~EXTIRQ_CFG_SENSE(irq);
+               reg &= ~EXTIRQ_CFG_BOTHEDGE(irq);
+               break;
+
+       case IRQ_TYPE_LEVEL_HIGH:
+               reg |= EXTIRQ_CFG_LEVELSENSE(irq);
+               reg |= EXTIRQ_CFG_SENSE(irq);
+               break;
+
+       case IRQ_TYPE_LEVEL_LOW:
+               reg |= EXTIRQ_CFG_LEVELSENSE(irq);
+               reg &= ~EXTIRQ_CFG_SENSE(irq);
+               break;
+
+       default:
+               printk(KERN_ERR "bogus flow type combination given !\n");
+               return -EINVAL;
+       }
+       bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
+
+       if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))  {
+               desc->status |= IRQ_LEVEL;
+               desc->handle_irq = handle_level_irq;
+       } else {
+               desc->handle_irq = handle_edge_irq;
+       }
+
+       return 0;
+}
+
+static struct irq_chip bcm63xx_internal_irq_chip = {
+       .name           = "bcm63xx_ipic",
+       .startup        = bcm63xx_internal_irq_startup,
+       .shutdown       = bcm63xx_internal_irq_mask,
+
+       .mask           = bcm63xx_internal_irq_mask,
+       .mask_ack       = bcm63xx_internal_irq_mask,
+       .unmask         = bcm63xx_internal_irq_unmask,
+};
+
+static struct irq_chip bcm63xx_external_irq_chip = {
+       .name           = "bcm63xx_epic",
+       .startup        = bcm63xx_external_irq_startup,
+       .shutdown       = bcm63xx_external_irq_shutdown,
+
+       .ack            = bcm63xx_external_irq_clear,
+
+       .mask           = bcm63xx_external_irq_mask,
+       .unmask         = bcm63xx_external_irq_unmask,
+
+       .set_type       = bcm63xx_external_irq_set_type,
+};
+
+static struct irqaction cpu_ip2_cascade_action = {
+       .handler        = no_action,
+       .name           = "cascade_ip2",
+};
+
+void __init arch_init_irq(void)
+{
+       int i;
+
+       mips_cpu_irq_init();
+       for (i = IRQ_INTERNAL_BASE; i < NR_IRQS; ++i)
+               set_irq_chip_and_handler(i, &bcm63xx_internal_irq_chip,
+                                        handle_level_irq);
+
+       for (i = IRQ_EXT_BASE; i < IRQ_EXT_BASE + 4; ++i)
+               set_irq_chip_and_handler(i, &bcm63xx_external_irq_chip,
+                                        handle_edge_irq);
+
+       setup_irq(IRQ_MIPS_BASE + 2, &cpu_ip2_cascade_action);
+}
diff --git a/arch/mips/bcm63xx/prom.c b/arch/mips/bcm63xx/prom.c
new file mode 100644 (file)
index 0000000..fb284fb
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <asm/bootinfo.h>
+#include <bcm63xx_board.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_gpio.h>
+
+void __init prom_init(void)
+{
+       u32 reg, mask;
+
+       bcm63xx_cpu_init();
+
+       /* stop any running watchdog */
+       bcm_wdt_writel(WDT_STOP_1, WDT_CTL_REG);
+       bcm_wdt_writel(WDT_STOP_2, WDT_CTL_REG);
+
+       /* disable all hardware blocks clock for now */
+       if (BCMCPU_IS_6338())
+               mask = CKCTL_6338_ALL_SAFE_EN;
+       else if (BCMCPU_IS_6345())
+               mask = CKCTL_6345_ALL_SAFE_EN;
+       else if (BCMCPU_IS_6348())
+               mask = CKCTL_6348_ALL_SAFE_EN;
+       else
+               /* BCMCPU_IS_6358() */
+               mask = CKCTL_6358_ALL_SAFE_EN;
+
+       reg = bcm_perf_readl(PERF_CKCTL_REG);
+       reg &= ~mask;
+       bcm_perf_writel(reg, PERF_CKCTL_REG);
+
+       /* assign command line from kernel config */
+       strcpy(arcs_cmdline, CONFIG_CMDLINE);
+
+       /* register gpiochip */
+       bcm63xx_gpio_init();
+
+       /* do low level board init */
+       board_prom_init();
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
diff --git a/arch/mips/bcm63xx/setup.c b/arch/mips/bcm63xx/setup.c
new file mode 100644 (file)
index 0000000..b18a0ca
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/bootmem.h>
+#include <linux/ioport.h>
+#include <linux/pm.h>
+#include <asm/bootinfo.h>
+#include <asm/time.h>
+#include <asm/reboot.h>
+#include <asm/cacheflush.h>
+#include <bcm63xx_board.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_io.h>
+
+void bcm63xx_machine_halt(void)
+{
+       printk(KERN_INFO "System halted\n");
+       while (1)
+               ;
+}
+
+static void bcm6348_a1_reboot(void)
+{
+       u32 reg;
+
+       /* soft reset all blocks */
+       printk(KERN_INFO "soft-reseting all blocks ...\n");
+       reg = bcm_perf_readl(PERF_SOFTRESET_REG);
+       reg &= ~SOFTRESET_6348_ALL;
+       bcm_perf_writel(reg, PERF_SOFTRESET_REG);
+       mdelay(10);
+
+       reg = bcm_perf_readl(PERF_SOFTRESET_REG);
+       reg |= SOFTRESET_6348_ALL;
+       bcm_perf_writel(reg, PERF_SOFTRESET_REG);
+       mdelay(10);
+
+       /* Jump to the power on address. */
+       printk(KERN_INFO "jumping to reset vector.\n");
+       /* set high vectors (base at 0xbfc00000 */
+       set_c0_status(ST0_BEV | ST0_ERL);
+       /* run uncached in kseg0 */
+       change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+       __flush_cache_all();
+       /* remove all wired TLB entries */
+       write_c0_wired(0);
+       __asm__ __volatile__(
+               "jr\t%0"
+               :
+               : "r" (0xbfc00000));
+       while (1)
+               ;
+}
+
+void bcm63xx_machine_reboot(void)
+{
+       u32 reg;
+
+       /* mask and clear all external irq */
+       reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
+       reg &= ~EXTIRQ_CFG_MASK_ALL;
+       reg |= EXTIRQ_CFG_CLEAR_ALL;
+       bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
+
+       if (BCMCPU_IS_6348() && (bcm63xx_get_cpu_rev() == 0xa1))
+               bcm6348_a1_reboot();
+
+       printk(KERN_INFO "triggering watchdog soft-reset...\n");
+       bcm_perf_writel(SYS_PLL_SOFT_RESET, PERF_SYS_PLL_CTL_REG);
+       while (1)
+               ;
+}
+
+static void __bcm63xx_machine_reboot(char *p)
+{
+       bcm63xx_machine_reboot();
+}
+
+/*
+ * return system type in /proc/cpuinfo
+ */
+const char *get_system_type(void)
+{
+       static char buf[128];
+       snprintf(buf, sizeof(buf), "bcm63xx/%s (0x%04x/0x%04X)",
+                board_get_name(),
+                bcm63xx_get_cpu_id(), bcm63xx_get_cpu_rev());
+       return buf;
+}
+
+void __init plat_time_init(void)
+{
+       mips_hpt_frequency = bcm63xx_get_cpu_freq() / 2;
+}
+
+void __init plat_mem_setup(void)
+{
+       add_memory_region(0, bcm63xx_get_memory_size(), BOOT_MEM_RAM);
+
+       _machine_halt = bcm63xx_machine_halt;
+       _machine_restart = __bcm63xx_machine_reboot;
+       pm_power_off = bcm63xx_machine_halt;
+
+       set_io_port_base(0);
+       ioport_resource.start = 0;
+       ioport_resource.end = ~0;
+
+       board_setup();
+}
+
+int __init bcm63xx_register_devices(void)
+{
+       return board_register_devices();
+}
+
+arch_initcall(bcm63xx_register_devices);
diff --git a/arch/mips/bcm63xx/timer.c b/arch/mips/bcm63xx/timer.c
new file mode 100644 (file)
index 0000000..ba522bd
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/clk.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_timer.h>
+#include <bcm63xx_regs.h>
+
+static DEFINE_SPINLOCK(timer_reg_lock);
+static DEFINE_SPINLOCK(timer_data_lock);
+static struct clk *periph_clk;
+
+static struct timer_data {
+       void    (*cb)(void *);
+       void    *data;
+} timer_data[BCM63XX_TIMER_COUNT];
+
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
+{
+       u32 stat;
+       int i;
+
+       spin_lock(&timer_reg_lock);
+       stat = bcm_timer_readl(TIMER_IRQSTAT_REG);
+       bcm_timer_writel(stat, TIMER_IRQSTAT_REG);
+       spin_unlock(&timer_reg_lock);
+
+       for (i = 0; i < BCM63XX_TIMER_COUNT; i++) {
+               if (!(stat & TIMER_IRQSTAT_TIMER_CAUSE(i)))
+                       continue;
+
+               spin_lock(&timer_data_lock);
+               if (!timer_data[i].cb) {
+                       spin_unlock(&timer_data_lock);
+                       continue;
+               }
+
+               timer_data[i].cb(timer_data[i].data);
+               spin_unlock(&timer_data_lock);
+       }
+
+       return IRQ_HANDLED;
+}
+
+int bcm63xx_timer_enable(int id)
+{
+       u32 reg;
+       unsigned long flags;
+
+       if (id >= BCM63XX_TIMER_COUNT)
+               return -EINVAL;
+
+       spin_lock_irqsave(&timer_reg_lock, flags);
+
+       reg = bcm_timer_readl(TIMER_CTLx_REG(id));
+       reg |= TIMER_CTL_ENABLE_MASK;
+       bcm_timer_writel(reg, TIMER_CTLx_REG(id));
+
+       reg = bcm_timer_readl(TIMER_IRQSTAT_REG);
+       reg |= TIMER_IRQSTAT_TIMER_IR_EN(id);
+       bcm_timer_writel(reg, TIMER_IRQSTAT_REG);
+
+       spin_unlock_irqrestore(&timer_reg_lock, flags);
+       return 0;
+}
+
+EXPORT_SYMBOL(bcm63xx_timer_enable);
+
+int bcm63xx_timer_disable(int id)
+{
+       u32 reg;
+       unsigned long flags;
+
+       if (id >= BCM63XX_TIMER_COUNT)
+               return -EINVAL;
+
+       spin_lock_irqsave(&timer_reg_lock, flags);
+
+       reg = bcm_timer_readl(TIMER_CTLx_REG(id));
+       reg &= ~TIMER_CTL_ENABLE_MASK;
+       bcm_timer_writel(reg, TIMER_CTLx_REG(id));
+
+       reg = bcm_timer_readl(TIMER_IRQSTAT_REG);
+       reg &= ~TIMER_IRQSTAT_TIMER_IR_EN(id);
+       bcm_timer_writel(reg, TIMER_IRQSTAT_REG);
+
+       spin_unlock_irqrestore(&timer_reg_lock, flags);
+       return 0;
+}
+
+EXPORT_SYMBOL(bcm63xx_timer_disable);
+
+int bcm63xx_timer_register(int id, void (*callback)(void *data), void *data)
+{
+       unsigned long flags;
+       int ret;
+
+       if (id >= BCM63XX_TIMER_COUNT || !callback)
+               return -EINVAL;
+
+       ret = 0;
+       spin_lock_irqsave(&timer_data_lock, flags);
+       if (timer_data[id].cb) {
+               ret = -EBUSY;
+               goto out;
+       }
+
+       timer_data[id].cb = callback;
+       timer_data[id].data = data;
+
+out:
+       spin_unlock_irqrestore(&timer_data_lock, flags);
+       return ret;
+}
+
+EXPORT_SYMBOL(bcm63xx_timer_register);
+
+void bcm63xx_timer_unregister(int id)
+{
+       unsigned long flags;
+
+       if (id >= BCM63XX_TIMER_COUNT)
+               return;
+
+       spin_lock_irqsave(&timer_data_lock, flags);
+       timer_data[id].cb = NULL;
+       spin_unlock_irqrestore(&timer_data_lock, flags);
+}
+
+EXPORT_SYMBOL(bcm63xx_timer_unregister);
+
+unsigned int bcm63xx_timer_countdown(unsigned int countdown_us)
+{
+       return (clk_get_rate(periph_clk) / (1000 * 1000)) * countdown_us;
+}
+
+EXPORT_SYMBOL(bcm63xx_timer_countdown);
+
+int bcm63xx_timer_set(int id, int monotonic, unsigned int countdown_us)
+{
+       u32 reg, countdown;
+       unsigned long flags;
+
+       if (id >= BCM63XX_TIMER_COUNT)
+               return -EINVAL;
+
+       countdown = bcm63xx_timer_countdown(countdown_us);
+       if (countdown & ~TIMER_CTL_COUNTDOWN_MASK)
+               return -EINVAL;
+
+       spin_lock_irqsave(&timer_reg_lock, flags);
+       reg = bcm_timer_readl(TIMER_CTLx_REG(id));
+
+       if (monotonic)
+               reg &= ~TIMER_CTL_MONOTONIC_MASK;
+       else
+               reg |= TIMER_CTL_MONOTONIC_MASK;
+
+       reg &= ~TIMER_CTL_COUNTDOWN_MASK;
+       reg |= countdown;
+       bcm_timer_writel(reg, TIMER_CTLx_REG(id));
+
+       spin_unlock_irqrestore(&timer_reg_lock, flags);
+       return 0;
+}
+
+EXPORT_SYMBOL(bcm63xx_timer_set);
+
+int bcm63xx_timer_init(void)
+{
+       int ret, irq;
+       u32 reg;
+
+       reg = bcm_timer_readl(TIMER_IRQSTAT_REG);
+       reg &= ~TIMER_IRQSTAT_TIMER0_IR_EN;
+       reg &= ~TIMER_IRQSTAT_TIMER1_IR_EN;
+       reg &= ~TIMER_IRQSTAT_TIMER2_IR_EN;
+       bcm_timer_writel(reg, TIMER_IRQSTAT_REG);
+
+       periph_clk = clk_get(NULL, "periph");
+       if (IS_ERR(periph_clk))
+               return -ENODEV;
+
+       irq = bcm63xx_get_irq_number(IRQ_TIMER);
+       ret = request_irq(irq, timer_interrupt, 0, "bcm63xx_timer", NULL);
+       if (ret) {
+               printk(KERN_ERR "bcm63xx_timer: failed to register irq\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+arch_initcall(bcm63xx_timer_init);
index c5a7f308c4051127c9553bf5769b3d258b5a42e0..e19d906236af818be4df3bfe28bf76f0b9948710 100644 (file)
@@ -59,8 +59,8 @@ struct sect {
 };
 
 int *symTypeTable;
-int must_convert_endian = 0;
-int format_bigendian = 0;
+int must_convert_endian;
+int format_bigendian;
 
 static void copy(int out, int in, off_t offset, off_t size)
 {
index d6903c3f3d513c0cd0990138aaada2445d27562b..139436280520698e5d6d8221e1bd6d9c9e405a33 100644 (file)
@@ -6,10 +6,10 @@
 # License.  See the file "COPYING" in the main directory of this archive
 # for more details.
 #
-# Copyright (C) 2005-2008 Cavium Networks
+# Copyright (C) 2005-2009 Cavium Networks
 #
 
-obj-y := setup.o serial.o octeon-irq.o csrc-octeon.o
+obj-y := setup.o serial.o octeon-platform.o octeon-irq.o csrc-octeon.o
 obj-y += dma-octeon.o flash_setup.o
 obj-y += octeon-memcpy.o
 
diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c
new file mode 100644 (file)
index 0000000..be711dd
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * 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) 2004-2009 Cavium Networks
+ * Copyright (C) 2008 Wind River Systems
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-rnm-defs.h>
+
+static struct octeon_cf_data octeon_cf_data;
+
+static int __init octeon_cf_device_init(void)
+{
+       union cvmx_mio_boot_reg_cfgx mio_boot_reg_cfg;
+       unsigned long base_ptr, region_base, region_size;
+       struct platform_device *pd;
+       struct resource cf_resources[3];
+       unsigned int num_resources;
+       int i;
+       int ret = 0;
+
+       /* Setup octeon-cf platform device if present. */
+       base_ptr = 0;
+       if (octeon_bootinfo->major_version == 1
+               && octeon_bootinfo->minor_version >= 1) {
+               if (octeon_bootinfo->compact_flash_common_base_addr)
+                       base_ptr =
+                               octeon_bootinfo->compact_flash_common_base_addr;
+       } else {
+               base_ptr = 0x1d000800;
+       }
+
+       if (!base_ptr)
+               return ret;
+
+       /* Find CS0 region. */
+       for (i = 0; i < 8; i++) {
+               mio_boot_reg_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(i));
+               region_base = mio_boot_reg_cfg.s.base << 16;
+               region_size = (mio_boot_reg_cfg.s.size + 1) << 16;
+               if (mio_boot_reg_cfg.s.en && base_ptr >= region_base
+                   && base_ptr < region_base + region_size)
+                       break;
+       }
+       if (i >= 7) {
+               /* i and i + 1 are CS0 and CS1, both must be less than 8. */
+               goto out;
+       }
+       octeon_cf_data.base_region = i;
+       octeon_cf_data.is16bit = mio_boot_reg_cfg.s.width;
+       octeon_cf_data.base_region_bias = base_ptr - region_base;
+       memset(cf_resources, 0, sizeof(cf_resources));
+       num_resources = 0;
+       cf_resources[num_resources].flags       = IORESOURCE_MEM;
+       cf_resources[num_resources].start       = region_base;
+       cf_resources[num_resources].end = region_base + region_size - 1;
+       num_resources++;
+
+
+       if (!(base_ptr & 0xfffful)) {
+               /*
+                * Boot loader signals availability of DMA (true_ide
+                * mode) by setting low order bits of base_ptr to
+                * zero.
+                */
+
+               /* Asume that CS1 immediately follows. */
+               mio_boot_reg_cfg.u64 =
+                       cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(i + 1));
+               region_base = mio_boot_reg_cfg.s.base << 16;
+               region_size = (mio_boot_reg_cfg.s.size + 1) << 16;
+               if (!mio_boot_reg_cfg.s.en)
+                       goto out;
+
+               cf_resources[num_resources].flags       = IORESOURCE_MEM;
+               cf_resources[num_resources].start       = region_base;
+               cf_resources[num_resources].end = region_base + region_size - 1;
+               num_resources++;
+
+               octeon_cf_data.dma_engine = 0;
+               cf_resources[num_resources].flags       = IORESOURCE_IRQ;
+               cf_resources[num_resources].start       = OCTEON_IRQ_BOOTDMA;
+               cf_resources[num_resources].end = OCTEON_IRQ_BOOTDMA;
+               num_resources++;
+       } else {
+               octeon_cf_data.dma_engine = -1;
+       }
+
+       pd = platform_device_alloc("pata_octeon_cf", -1);
+       if (!pd) {
+               ret = -ENOMEM;
+               goto out;
+       }
+       pd->dev.platform_data = &octeon_cf_data;
+
+       ret = platform_device_add_resources(pd, cf_resources, num_resources);
+       if (ret)
+               goto fail;
+
+       ret = platform_device_add(pd);
+       if (ret)
+               goto fail;
+
+       return ret;
+fail:
+       platform_device_put(pd);
+out:
+       return ret;
+}
+device_initcall(octeon_cf_device_init);
+
+/* Octeon Random Number Generator.  */
+static int __init octeon_rng_device_init(void)
+{
+       struct platform_device *pd;
+       int ret = 0;
+
+       struct resource rng_resources[] = {
+               {
+                       .flags  = IORESOURCE_MEM,
+                       .start  = XKPHYS_TO_PHYS(CVMX_RNM_CTL_STATUS),
+                       .end    = XKPHYS_TO_PHYS(CVMX_RNM_CTL_STATUS) + 0xf
+               }, {
+                       .flags  = IORESOURCE_MEM,
+                       .start  = cvmx_build_io_address(8, 0),
+                       .end    = cvmx_build_io_address(8, 0) + 0x7
+               }
+       };
+
+       pd = platform_device_alloc("octeon_rng", -1);
+       if (!pd) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       ret = platform_device_add_resources(pd, rng_resources,
+                                           ARRAY_SIZE(rng_resources));
+       if (ret)
+               goto fail;
+
+       ret = platform_device_add(pd);
+       if (ret)
+               goto fail;
+
+       return ret;
+fail:
+       platform_device_put(pd);
+
+out:
+       return ret;
+}
+device_initcall(octeon_rng_device_init);
+
+MODULE_AUTHOR("David Daney <ddaney@caviumnetworks.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Platform driver for Octeon SOC");
index da559249cc2fae44161c5322ce7cfd61b3cac328..b321d3b168771592cf744c8be9efc9f91fe31623 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
-#include <linux/irq.h>
 #include <linux/serial.h>
 #include <linux/smp.h>
 #include <linux/types.h>
@@ -824,105 +823,3 @@ void prom_free_prom_memory(void)
           CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB option is set */
        octeon_hal_setup_reserved32();
 }
-
-static struct octeon_cf_data octeon_cf_data;
-
-static int __init octeon_cf_device_init(void)
-{
-       union cvmx_mio_boot_reg_cfgx mio_boot_reg_cfg;
-       unsigned long base_ptr, region_base, region_size;
-       struct platform_device *pd;
-       struct resource cf_resources[3];
-       unsigned int num_resources;
-       int i;
-       int ret = 0;
-
-       /* Setup octeon-cf platform device if present. */
-       base_ptr = 0;
-       if (octeon_bootinfo->major_version == 1
-               && octeon_bootinfo->minor_version >= 1) {
-               if (octeon_bootinfo->compact_flash_common_base_addr)
-                       base_ptr =
-                               octeon_bootinfo->compact_flash_common_base_addr;
-       } else {
-               base_ptr = 0x1d000800;
-       }
-
-       if (!base_ptr)
-               return ret;
-
-       /* Find CS0 region. */
-       for (i = 0; i < 8; i++) {
-               mio_boot_reg_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(i));
-               region_base = mio_boot_reg_cfg.s.base << 16;
-               region_size = (mio_boot_reg_cfg.s.size + 1) << 16;
-               if (mio_boot_reg_cfg.s.en && base_ptr >= region_base
-                   && base_ptr < region_base + region_size)
-                       break;
-       }
-       if (i >= 7) {
-               /* i and i + 1 are CS0 and CS1, both must be less than 8. */
-               goto out;
-       }
-       octeon_cf_data.base_region = i;
-       octeon_cf_data.is16bit = mio_boot_reg_cfg.s.width;
-       octeon_cf_data.base_region_bias = base_ptr - region_base;
-       memset(cf_resources, 0, sizeof(cf_resources));
-       num_resources = 0;
-       cf_resources[num_resources].flags       = IORESOURCE_MEM;
-       cf_resources[num_resources].start       = region_base;
-       cf_resources[num_resources].end = region_base + region_size - 1;
-       num_resources++;
-
-
-       if (!(base_ptr & 0xfffful)) {
-               /*
-                * Boot loader signals availability of DMA (true_ide
-                * mode) by setting low order bits of base_ptr to
-                * zero.
-                */
-
-               /* Asume that CS1 immediately follows. */
-               mio_boot_reg_cfg.u64 =
-                       cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(i + 1));
-               region_base = mio_boot_reg_cfg.s.base << 16;
-               region_size = (mio_boot_reg_cfg.s.size + 1) << 16;
-               if (!mio_boot_reg_cfg.s.en)
-                       goto out;
-
-               cf_resources[num_resources].flags       = IORESOURCE_MEM;
-               cf_resources[num_resources].start       = region_base;
-               cf_resources[num_resources].end = region_base + region_size - 1;
-               num_resources++;
-
-               octeon_cf_data.dma_engine = 0;
-               cf_resources[num_resources].flags       = IORESOURCE_IRQ;
-               cf_resources[num_resources].start       = OCTEON_IRQ_BOOTDMA;
-               cf_resources[num_resources].end = OCTEON_IRQ_BOOTDMA;
-               num_resources++;
-       } else {
-               octeon_cf_data.dma_engine = -1;
-       }
-
-       pd = platform_device_alloc("pata_octeon_cf", -1);
-       if (!pd) {
-               ret = -ENOMEM;
-               goto out;
-       }
-       pd->dev.platform_data = &octeon_cf_data;
-
-       ret = platform_device_add_resources(pd, cf_resources, num_resources);
-       if (ret)
-               goto fail;
-
-       ret = platform_device_add(pd);
-       if (ret)
-               goto fail;
-
-       return ret;
-fail:
-       platform_device_put(pd);
-out:
-       return ret;
-}
-device_initcall(octeon_cf_device_init);
index dad5b6769d746c4a2e6b09004c10b1b576dc62f1..35648302f7cc9f2b3a310e08f2a80d4e6c621dd7 100644 (file)
@@ -125,7 +125,6 @@ CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
index d8694332b3441d0a4bfd09e7bbab103db828e982..94b7d57f906d8c46bc6ea420b8bbaeb5c1df3eed 100644 (file)
@@ -111,7 +111,6 @@ CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/bcm63xx_defconfig b/arch/mips/configs/bcm63xx_defconfig
new file mode 100644 (file)
index 0000000..ea00c18
--- /dev/null
@@ -0,0 +1,972 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.30-rc6
+# Sun May 31 20:17:18 2009
+#
+CONFIG_MIPS=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_ALCHEMY is not set
+# CONFIG_BASLER_EXCITE is not set
+# CONFIG_BCM47XX is not set
+CONFIG_BCM63XX=y
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_LEMOTE_FULONG is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_NEC_MARKEINS is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_NXP_STB220 is not set
+# CONFIG_NXP_STB225 is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
+# CONFIG_PMC_MSP is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP28 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SNI_RM is not set
+# CONFIG_MACH_TX39XX is not set
+# CONFIG_MACH_TX49XX is not set
+# CONFIG_MIKROTIK_RB532 is not set
+# CONFIG_WR_PPMC is not set
+# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
+# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
+
+#
+# CPU support
+#
+CONFIG_BCM63XX_CPU_6348=y
+CONFIG_BCM63XX_CPU_6358=y
+CONFIG_BOARD_BCM963XX=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_SUPPORTS_OPROFILE=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_CEVT_R4K_LIB=y
+CONFIG_CEVT_R4K=y
+CONFIG_CSRC_R4K_LIB=y
+CONFIG_CSRC_R4K=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+# CONFIG_HOTPLUG_CPU is not set
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_GPIO=y
+CONFIG_CPU_BIG_ENDIAN=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_IRQ_CPU=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_LOONGSON2 is not set
+CONFIG_CPU_MIPS32_R1=y
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R5500 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_CAVIUM_OCTEON is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_HARDWARE_WATCHPOINTS=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_32KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_MIPS_MT_DISABLED=y
+# CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_48 is not set
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_128 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_256 is not set
+# CONFIG_HZ_1000 is not set
+# CONFIG_HZ_1024 is not set
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
+# CONFIG_SECCOMP is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+# CONFIG_SYSVIPC is not set
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+# 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 is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+# CONFIG_PCSPKR_PLATFORM is not set
+CONFIG_BASE_FULL=y
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_SHMEM is not set
+# CONFIG_AIO is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_PCI_QUIRKS=y
+# CONFIG_SLUB_DEBUG is not set
+CONFIG_COMPAT_BRK=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_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_FREEZER is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCI_LEGACY is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
+CONFIG_MMU=y
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+# CONFIG_YENTA is not set
+# CONFIG_PD6729 is not set
+# CONFIG_I82092 is not set
+CONFIG_PCMCIA_BCM63XX=y
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Power management options
+#
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_PM is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET 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 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 is not set
+# 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_NET_DSA 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_PHONET is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+# CONFIG_MTD_CHAR is not set
+# CONFIG_MTD_BLKDEVS is not set
+# 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 is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA 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=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# 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
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+# CONFIG_BLK_DEV 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_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=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=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_BCM63XX_PHY=y
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 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_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET 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_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_B44 is not set
+# CONFIG_ATL2 is not set
+CONFIG_BCM63XX_ENET=y
+# 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
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# 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_NET_PCMCIA 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 is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_SERIAL_BCM63XX=y
+CONFIG_SERIAL_BCM63XX_CONSOLE=y
+# CONFIG_UNIX98_PTYS is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+# CONFIG_IPWIRELESS 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_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+# CONFIG_GPIO_BT8XX is not set
+
+#
+# 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
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB=y
+CONFIG_SSB_SPROM=y
+CONFIG_SSB_PCIHOST_POSSIBLE=y
+CONFIG_SSB_PCIHOST=y
+# CONFIG_SSB_B43_PCI_BRIDGE is not set
+CONFIG_SSB_PCMCIAHOST_POSSIBLE=y
+# CONFIG_SSB_PCMCIAHOST is not set
+# CONFIG_SSB_SILENT is not set
+# CONFIG_SSB_DEBUG is not set
+CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
+# CONFIG_SSB_DRIVER_PCICORE is not set
+# CONFIG_SSB_DRIVER_MIPS 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
+# CONFIG_REGULATOR 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_DRM is not set
+# 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
+#
+# CONFIG_SOUND 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
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF 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_BIG_ENDIAN_MMIO=y
+# CONFIG_USB_OXU210HP_HCD 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_SSB is not set
+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
+# CONFIG_USB_WHCI_HCD is not set
+# CONFIG_USB_HWA_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
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 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_SEVSEG 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_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_VST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_UWB 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_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_FILE_LOCKING is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=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
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+# CONFIG_NETWORK_FILESYSTEMS 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
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_TRACING_SUPPORT=y
+
+#
+# Tracers
+#
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_CMDLINE="console=ttyS0,115200"
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
index d6d35b2e5fe877b303e90f498b326542aeed6a40..13d9eb4736c0af2bc152aaab8f12a91084e5681e 100644 (file)
@@ -129,7 +129,6 @@ CONFIG_PAGE_SIZE_4KB=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
index eb44b72254afe26088bc921e3f2331057a065f10..6c8cca8589ba2db188fe9af4c88c708a7d8ea75d 100644 (file)
@@ -112,7 +112,6 @@ CONFIG_PAGE_SIZE_4KB=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
index a279165e3a7d3899b9fae53a7323f4e3df3b3781..dbdf3bb1a34a1e508bf6a3892cf50874a0b425e7 100644 (file)
@@ -114,7 +114,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
index 8944d15caf13145866a136710597dab3c915b704..fa681447589861130a324dc9a93620e43a3513d8 100644 (file)
@@ -114,7 +114,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
index ab17973107fde80e44e217b696cbf73757297f62..d73f1de43b5dda4262b6e79bffb9f9a8f971fc12 100644 (file)
@@ -114,7 +114,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
index b65803f19352724866354ba61d5b53a54d1a17f2..ec3e028a5b2e0f17499f899b816b60126e362e6e 100644 (file)
@@ -116,7 +116,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
index a190ac07740b31dcdc935701ebc30d02c87f9bc4..7631dae51be99e0eb4e36b8ce70186df4929a437 100644 (file)
@@ -115,7 +115,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
index 4e465e94599179a79f53769789cc0b3830aa0a40..1995d43a2ed122a1836ad102f1cf145af38bd161 100644 (file)
@@ -118,7 +118,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/fulong_defconfig b/arch/mips/configs/fulong_defconfig
deleted file mode 100644 (file)
index 786a9bc..0000000
+++ /dev/null
@@ -1,1912 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc6
-# Fri Nov 28 17:53:48 2008
-#
-CONFIG_MIPS=y
-
-#
-# Machine selection
-#
-# CONFIG_MACH_ALCHEMY is not set
-# CONFIG_BASLER_EXCITE is not set
-# CONFIG_BCM47XX is not set
-# CONFIG_MIPS_COBALT is not set
-# CONFIG_MACH_DECSTATION is not set
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
-CONFIG_LEMOTE_FULONG=y
-# CONFIG_MIPS_MALTA is not set
-# CONFIG_MIPS_SIM is not set
-# CONFIG_MACH_EMMA is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_NXP_STB220 is not set
-# CONFIG_NXP_STB225 is not set
-# CONFIG_PNX8550_JBS is not set
-# CONFIG_PNX8550_STB810 is not set
-# CONFIG_PMC_MSP is not set
-# CONFIG_PMC_YOSEMITE is not set
-# CONFIG_SGI_IP22 is not set
-# CONFIG_SGI_IP27 is not set
-# CONFIG_SGI_IP28 is not set
-# CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_CRHINE is not set
-# CONFIG_SIBYTE_CARMEL is not set
-# CONFIG_SIBYTE_CRHONE is not set
-# CONFIG_SIBYTE_RHONE is not set
-# CONFIG_SIBYTE_SWARM is not set
-# CONFIG_SIBYTE_LITTLESUR is not set
-# CONFIG_SIBYTE_SENTOSA is not set
-# CONFIG_SIBYTE_BIGSUR is not set
-# CONFIG_SNI_RM is not set
-# CONFIG_MACH_TX39XX is not set
-# CONFIG_MACH_TX49XX is not set
-# CONFIG_MIKROTIK_RB532 is not set
-# CONFIG_WR_PPMC is not set
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
-CONFIG_ARCH_SUPPORTS_OPROFILE=y
-CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_TIME=y
-CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_CEVT_R4K=y
-CONFIG_CSRC_R4K=y
-CONFIG_DMA_NONCOHERENT=y
-CONFIG_DMA_NEED_PCI_MAP_STATE=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_SYS_HAS_EARLY_PRINTK=y
-# CONFIG_HOTPLUG_CPU is not set
-CONFIG_I8259=y
-# CONFIG_NO_IOPORT is not set
-CONFIG_GENERIC_ISA_DMA=y
-CONFIG_GENERIC_ISA_DMA_SUPPORT_BROKEN=y
-# CONFIG_CPU_BIG_ENDIAN is not set
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
-CONFIG_IRQ_CPU=y
-CONFIG_BOOT_ELF32=y
-CONFIG_MIPS_L1_CACHE_SHIFT=5
-CONFIG_HAVE_STD_PC_SERIAL_PORT=y
-
-#
-# CPU selection
-#
-CONFIG_CPU_LOONGSON2=y
-# CONFIG_CPU_MIPS32_R1 is not set
-# CONFIG_CPU_MIPS32_R2 is not set
-# CONFIG_CPU_MIPS64_R1 is not set
-# CONFIG_CPU_MIPS64_R2 is not set
-# CONFIG_CPU_R3000 is not set
-# CONFIG_CPU_TX39XX is not set
-# CONFIG_CPU_VR41XX is not set
-# CONFIG_CPU_R4300 is not set
-# CONFIG_CPU_R4X00 is not set
-# CONFIG_CPU_TX49XX is not set
-# CONFIG_CPU_R5000 is not set
-# CONFIG_CPU_R5432 is not set
-# CONFIG_CPU_R5500 is not set
-# CONFIG_CPU_R6000 is not set
-# CONFIG_CPU_NEVADA is not set
-# CONFIG_CPU_R8000 is not set
-# CONFIG_CPU_R10000 is not set
-# CONFIG_CPU_RM7000 is not set
-# CONFIG_CPU_RM9000 is not set
-# CONFIG_CPU_SB1 is not set
-CONFIG_SYS_HAS_CPU_LOONGSON2=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
-
-#
-# Kernel type
-#
-# CONFIG_32BIT is not set
-CONFIG_64BIT=y
-# CONFIG_PAGE_SIZE_4KB is not set
-# CONFIG_PAGE_SIZE_8KB is not set
-CONFIG_PAGE_SIZE_16KB=y
-# CONFIG_PAGE_SIZE_64KB is not set
-CONFIG_BOARD_SCACHE=y
-CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMP is not set
-# CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_WB=y
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_CPU_SUPPORTS_HIGHMEM=y
-CONFIG_SYS_SUPPORTS_HIGHMEM=y
-CONFIG_ARCH_FLATMEM_ENABLE=y
-CONFIG_ARCH_POPULATES_NODE_MAP=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=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=y
-CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4
-CONFIG_RESOURCES_64BIT=y
-CONFIG_PHYS_ADDR_T_64BIT=y
-CONFIG_ZONE_DMA_FLAG=0
-CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
-CONFIG_TICK_ONESHOT=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
-# CONFIG_HZ_48 is not set
-# CONFIG_HZ_100 is not set
-# CONFIG_HZ_128 is not set
-CONFIG_HZ_250=y
-# CONFIG_HZ_256 is not set
-# CONFIG_HZ_1000 is not set
-# CONFIG_HZ_1024 is not set
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_HZ=250
-# CONFIG_PREEMPT_NONE is not set
-CONFIG_PREEMPT_VOLUNTARY=y
-# CONFIG_PREEMPT is not set
-# CONFIG_KEXEC is not set
-CONFIG_SECCOMP=y
-CONFIG_LOCKDEP_SUPPORT=y
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-
-#
-# General setup
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-CONFIG_LOCALVERSION="lm32"
-# CONFIG_LOCALVERSION_AUTO is not set
-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 is not set
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-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=y
-# CONFIG_UTS_NS is not set
-# CONFIG_IPC_NS is not set
-CONFIG_USER_NS=y
-CONFIG_PID_NS=y
-# CONFIG_BLK_DEV_INITRD is not set
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
-CONFIG_EMBEDDED=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_HOTPLUG=y
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-# CONFIG_PCSPKR_PLATFORM 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_AIO=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_PCI_QUIRKS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
-# CONFIG_SLOB is not set
-CONFIG_PROFILING=y
-# CONFIG_MARKERS is not set
-CONFIG_OPROFILE=m
-CONFIG_HAVE_OPROFILE=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 is not set
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
-CONFIG_BLOCK=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
-CONFIG_BLK_DEV_BSG=y
-# CONFIG_BLK_DEV_INTEGRITY is not set
-CONFIG_BLOCK_COMPAT=y
-
-#
-# 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_FREEZER=y
-
-#
-# Bus options (PCI, PCMCIA, EISA, ISA, TC)
-#
-CONFIG_HW_HAS_PCI=y
-CONFIG_PCI=y
-CONFIG_PCI_DOMAINS=y
-# CONFIG_ARCH_SUPPORTS_MSI is not set
-CONFIG_PCI_LEGACY=y
-CONFIG_ISA=y
-CONFIG_MMU=y
-# CONFIG_PCCARD is not set
-# CONFIG_HOTPLUG_PCI is not set
-
-#
-# Executable file formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-# CONFIG_HAVE_AOUT is not set
-CONFIG_BINFMT_MISC=y
-CONFIG_MIPS32_COMPAT=y
-CONFIG_COMPAT=y
-CONFIG_SYSVIPC_COMPAT=y
-CONFIG_MIPS32_O32=y
-CONFIG_MIPS32_N32=y
-CONFIG_BINFMT_ELF32=y
-
-#
-# Power management options
-#
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_PM=y
-# CONFIG_PM_DEBUG is not set
-CONFIG_PM_SLEEP=y
-CONFIG_SUSPEND=y
-CONFIG_SUSPEND_FREEZER=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 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=y
-# CONFIG_IP_PNP_RARP is not set
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-CONFIG_NET_IPGRE_BROADCAST=y
-# CONFIG_IP_MROUTE 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 is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_BEET=y
-# CONFIG_INET_LRO is not set
-# CONFIG_INET_DIAG is not set
-# 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=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_NETFILTER_ADVANCED=y
-
-#
-# Core Netfilter Configuration
-#
-CONFIG_NETFILTER_NETLINK=m
-CONFIG_NETFILTER_NETLINK_QUEUE=m
-CONFIG_NETFILTER_NETLINK_LOG=m
-# CONFIG_NF_CONNTRACK is not set
-CONFIG_NETFILTER_XTABLES=m
-CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
-# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
-CONFIG_NETFILTER_XT_TARGET_MARK=m
-# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
-CONFIG_NETFILTER_XT_TARGET_RATEEST=m
-CONFIG_NETFILTER_XT_TARGET_TRACE=m
-# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
-CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
-CONFIG_NETFILTER_XT_MATCH_COMMENT=m
-CONFIG_NETFILTER_XT_MATCH_DCCP=m
-# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
-CONFIG_NETFILTER_XT_MATCH_ESP=m
-# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
-CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
-CONFIG_NETFILTER_XT_MATCH_LENGTH=m
-CONFIG_NETFILTER_XT_MATCH_LIMIT=m
-CONFIG_NETFILTER_XT_MATCH_MAC=m
-CONFIG_NETFILTER_XT_MATCH_MARK=m
-CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
-CONFIG_NETFILTER_XT_MATCH_OWNER=m
-# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
-CONFIG_NETFILTER_XT_MATCH_QUOTA=m
-CONFIG_NETFILTER_XT_MATCH_RATEEST=m
-CONFIG_NETFILTER_XT_MATCH_REALM=m
-CONFIG_NETFILTER_XT_MATCH_RECENT=m
-# CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT is not set
-CONFIG_NETFILTER_XT_MATCH_SCTP=m
-CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
-CONFIG_NETFILTER_XT_MATCH_STRING=m
-CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
-CONFIG_NETFILTER_XT_MATCH_TIME=m
-CONFIG_NETFILTER_XT_MATCH_U32=m
-# CONFIG_IP_VS is not set
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_NF_DEFRAG_IPV4 is not set
-CONFIG_IP_NF_QUEUE=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
-CONFIG_IP_NF_MATCH_AH=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_TTL=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=m
-CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-CONFIG_IP_NF_ARP_MANGLE=m
-# 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_NET_DSA 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
-CONFIG_NET_CLS_ROUTE=y
-
-#
-# 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_PHONET=m
-CONFIG_WIRELESS=y
-# CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_OLD_REGULATORY=y
-CONFIG_WIRELESS_EXT=y
-CONFIG_WIRELESS_EXT_SYSFS=y
-# CONFIG_MAC80211 is not set
-CONFIG_IEEE80211=m
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=m
-# CONFIG_IEEE80211_CRYPT_CCMP is not set
-# CONFIG_IEEE80211_CRYPT_TKIP is not set
-# CONFIG_RFKILL is not set
-CONFIG_NET_9P=m
-# CONFIG_NET_9P_DEBUG 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=m
-CONFIG_FIRMWARE_IN_KERNEL=y
-CONFIG_EXTRA_FIRMWARE=""
-# CONFIG_SYS_HYPERVISOR is not set
-# CONFIG_CONNECTOR is not set
-CONFIG_MTD=m
-# CONFIG_MTD_DEBUG is not set
-# CONFIG_MTD_CONCAT is not set
-# CONFIG_MTD_PARTITIONS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=m
-CONFIG_MTD_BLKDEVS=m
-CONFIG_MTD_BLOCK=m
-# 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=m
-CONFIG_MTD_JEDECPROBE=m
-CONFIG_MTD_GEN_PROBE=m
-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 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 is not set
-CONFIG_MTD_CFI_AMDSTD=m
-CONFIG_MTD_CFI_STAA=m
-CONFIG_MTD_CFI_UTIL=m
-# 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=m
-CONFIG_MTD_PHYSMAP_START=0x1fc00000
-CONFIG_MTD_PHYSMAP_LEN=0x80000
-CONFIG_MTD_PHYSMAP_BANKWIDTH=1
-# 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_PARPORT is not set
-# CONFIG_PNP is not set
-CONFIG_BLK_DEV=y
-# 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=m
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_SX8 is not set
-# CONFIG_BLK_DEV_UB is not set
-CONFIG_BLK_DEV_RAM=m
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-# 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=m
-# CONFIG_BLK_DEV_HD is not set
-# CONFIG_MISC_DEVICES is not set
-CONFIG_HAVE_IDE=y
-CONFIG_IDE=y
-
-#
-# Please see Documentation/ide/ide.txt for help/info on IDE drives
-#
-CONFIG_IDE_TIMINGS=y
-CONFIG_IDE_ATAPI=y
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_IDE_GD=y
-CONFIG_IDE_GD_ATA=y
-# CONFIG_IDE_GD_ATAPI is not set
-CONFIG_BLK_DEV_IDECD=y
-CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
-# CONFIG_BLK_DEV_IDETAPE is not set
-CONFIG_BLK_DEV_IDESCSI=y
-CONFIG_IDE_TASK_IOCTL=y
-CONFIG_IDE_PROC_FS=y
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-# CONFIG_BLK_DEV_PLATFORM is not set
-CONFIG_BLK_DEV_IDEDMA_SFF=y
-
-#
-# PCI IDE chipsets support
-#
-CONFIG_BLK_DEV_IDEPCI=y
-CONFIG_IDEPCI_PCIBUS_ORDER=y
-# CONFIG_BLK_DEV_OFFBOARD is not set
-CONFIG_BLK_DEV_GENERIC=y
-# CONFIG_BLK_DEV_OPTI621 is not set
-CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_AEC62XX is not set
-# CONFIG_BLK_DEV_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD74XX is not set
-# CONFIG_BLK_DEV_CMD64X is not set
-# CONFIG_BLK_DEV_TRIFLEX is not set
-# CONFIG_BLK_DEV_CS5520 is not set
-# CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_BLK_DEV_JMICRON is not set
-# CONFIG_BLK_DEV_SC1200 is not set
-# CONFIG_BLK_DEV_PIIX is not set
-# CONFIG_BLK_DEV_IT8213 is not set
-# CONFIG_BLK_DEV_IT821X is not set
-# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_PDC202XX_OLD is not set
-# CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_BLK_DEV_SVWKS is not set
-# CONFIG_BLK_DEV_SIIMAGE is not set
-# CONFIG_BLK_DEV_SLC90E66 is not set
-# CONFIG_BLK_DEV_TRM290 is not set
-CONFIG_BLK_DEV_VIA82CXXX=y
-# CONFIG_BLK_DEV_TC86C001 is not set
-
-#
-# Other IDE chipsets support
-#
-
-#
-# Note: most of these also require special kernel boot parameters
-#
-# CONFIG_BLK_DEV_4DRIVES is not set
-# CONFIG_BLK_DEV_ALI14XX is not set
-# CONFIG_BLK_DEV_DTC2278 is not set
-# CONFIG_BLK_DEV_HT6560B is not set
-# CONFIG_BLK_DEV_QD65XX is not set
-# CONFIG_BLK_DEV_UMC8672 is not set
-CONFIG_BLK_DEV_IDEDMA=y
-
-#
-# 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=y
-CONFIG_BLK_DEV_SR_VENDOR=y
-CONFIG_CHR_DEV_SG=y
-# CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-CONFIG_SCSI_CONSTANTS=y
-# 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_ATTRS is not set
-# CONFIG_SCSI_SAS_LIBSAS is not set
-# CONFIG_SCSI_SRP_ATTRS is not set
-# CONFIG_SCSI_LOWLEVEL is not set
-# CONFIG_SCSI_DH 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_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-CONFIG_MACVLAN=m
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-CONFIG_VETH=m
-# CONFIG_ARCNET is not set
-CONFIG_PHYLIB=m
-
-#
-# MII PHY device drivers
-#
-CONFIG_MARVELL_PHY=m
-CONFIG_DAVICOM_PHY=m
-CONFIG_QSEMI_PHY=m
-CONFIG_LXT_PHY=m
-CONFIG_CICADA_PHY=m
-# 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_MDIO_BITBANG is not set
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-# CONFIG_AX88796 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_VENDOR_SMC is not set
-# CONFIG_SMC91X is not set
-# CONFIG_DM9000 is not set
-# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_NET_TULIP is not set
-# CONFIG_AT1700 is not set
-# CONFIG_DEPCA is not set
-# CONFIG_HP100 is not set
-# CONFIG_NET_ISA is not set
-# CONFIG_IBM_NEW_EMAC_ZMII is not set
-# CONFIG_IBM_NEW_EMAC_RGMII is not set
-# CONFIG_IBM_NEW_EMAC_TAH is not set
-# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
-# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
-# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
-# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
-CONFIG_NET_PCI=y
-# CONFIG_PCNET32 is not set
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_AC3200 is not set
-# CONFIG_APRICOT is not set
-# CONFIG_B44 is not set
-# CONFIG_FORCEDETH is not set
-# CONFIG_CS89x0 is not set
-# CONFIG_TC35815 is not set
-# CONFIG_EEPRO100 is not set
-# CONFIG_E100 is not set
-# CONFIG_FEALNX is not set
-# CONFIG_NATSEMI is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_8139CP is not set
-CONFIG_8139TOO=y
-# CONFIG_8139TOO_PIO is not set
-# CONFIG_8139TOO_TUNE_TWISTER is not set
-# CONFIG_8139TOO_8129 is not set
-# CONFIG_8139_OLD_RX_RESET is not set
-# CONFIG_R6040 is not set
-# CONFIG_SIS900 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_SUNDANCE is not set
-# CONFIG_TLAN is not set
-# CONFIG_VIA_RHINE is not set
-# CONFIG_SC92031 is not set
-# CONFIG_ATL2 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_QLA3XXX is not set
-# CONFIG_ATL1 is not set
-# CONFIG_ATL1E is not set
-# CONFIG_JME is not set
-CONFIG_NETDEV_10000=y
-# CONFIG_CHELSIO_T1 is not set
-# CONFIG_CHELSIO_T3 is not set
-# CONFIG_ENIC is not set
-# CONFIG_IXGBE is not set
-# CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
-# CONFIG_MYRI10GE is not set
-# CONFIG_NETXEN_NIC is not set
-# CONFIG_NIU is not set
-# CONFIG_MLX4_EN is not set
-# CONFIG_MLX4_CORE is not set
-# CONFIG_TEHUTI is not set
-# CONFIG_BNX2X is not set
-# CONFIG_QLGE is not set
-# CONFIG_SFC is not set
-# CONFIG_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=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=m
-CONFIG_PPPOE=m
-CONFIG_PPPOL2TP=m
-CONFIG_SLIP=m
-CONFIG_SLIP_COMPRESSED=y
-CONFIG_SLHC=m
-CONFIG_SLIP_SMART=y
-CONFIG_SLIP_MODE_SLIP6=y
-CONFIG_NET_FC=y
-# 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=y
-# 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=y
-CONFIG_KEYBOARD_ATKBD=m
-# 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_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_ELANTECH is not set
-# CONFIG_MOUSE_PS2_TOUCHKIT is not set
-CONFIG_MOUSE_SERIAL=y
-# CONFIG_MOUSE_APPLETOUCH is not set
-# CONFIG_MOUSE_BCM5974 is not set
-# CONFIG_MOUSE_INPORT is not set
-# CONFIG_MOUSE_LOGIBM is not set
-# CONFIG_MOUSE_PC110PAD is not set
-# CONFIG_MOUSE_VSXXXAA 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_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 is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM 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=y
-# CONFIG_DTLK 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=m
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=m
-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=m
-
-#
-# I2C system bus drivers (mostly embedded / system-on-chip)
-#
-# 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_ELEKTOR is not set
-# CONFIG_I2C_PCA_ISA is not set
-# CONFIG_I2C_PCA_PLATFORM is not set
-# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_MAX6875 is not set
-# CONFIG_SENSORS_TSL2550 is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
-# CONFIG_SPI is not set
-# CONFIG_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
-CONFIG_SSB_POSSIBLE=y
-
-#
-# Sonics Silicon Backplane
-#
-# 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
-# CONFIG_MFD_WM8400 is not set
-# CONFIG_MFD_WM8350_I2C is not set
-# CONFIG_REGULATOR 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 is not set
-CONFIG_VIDEO_MEDIA=m
-
-#
-# Multimedia drivers
-#
-CONFIG_MEDIA_ATTACH=y
-CONFIG_MEDIA_TUNER=m
-CONFIG_MEDIA_TUNER_CUSTOMIZE=y
-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_MT2131=m
-CONFIG_MEDIA_TUNER_QT1010=m
-CONFIG_MEDIA_TUNER_XC2028=m
-CONFIG_MEDIA_TUNER_XC5000=m
-CONFIG_MEDIA_TUNER_MXL5005S=m
-CONFIG_MEDIA_TUNER_MXL5007T=m
-CONFIG_VIDEO_V4L2=m
-CONFIG_VIDEO_V4L1=m
-CONFIG_VIDEOBUF_GEN=m
-CONFIG_VIDEOBUF_VMALLOC=m
-CONFIG_VIDEOBUF_DMA_CONTIG=m
-CONFIG_VIDEO_CAPTURE_DRIVERS=y
-# CONFIG_VIDEO_ADV_DEBUG is not set
-# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
-CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
-# CONFIG_VIDEO_VIVI is not set
-# CONFIG_VIDEO_BT848 is not set
-# CONFIG_VIDEO_PMS 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_VIDEO_STRADIS is not set
-# CONFIG_VIDEO_SAA7134 is not set
-# CONFIG_VIDEO_MXB is not set
-# CONFIG_VIDEO_HEXIUM_ORION is not set
-# CONFIG_VIDEO_HEXIUM_GEMINI is not set
-# CONFIG_VIDEO_CX88 is not set
-# CONFIG_VIDEO_IVTV is not set
-# CONFIG_VIDEO_CAFE_CCIC is not set
-CONFIG_SOC_CAMERA=m
-CONFIG_SOC_CAMERA_MT9M001=m
-CONFIG_SOC_CAMERA_MT9M111=m
-CONFIG_SOC_CAMERA_MT9V022=m
-CONFIG_SOC_CAMERA_PLATFORM=m
-CONFIG_VIDEO_SH_MOBILE_CEU=m
-CONFIG_V4L_USB_DRIVERS=y
-CONFIG_USB_VIDEO_CLASS=m
-CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
-CONFIG_USB_GSPCA=m
-CONFIG_USB_M5602=m
-CONFIG_USB_GSPCA_CONEX=m
-CONFIG_USB_GSPCA_ETOMS=m
-CONFIG_USB_GSPCA_FINEPIX=m
-CONFIG_USB_GSPCA_MARS=m
-CONFIG_USB_GSPCA_OV519=m
-CONFIG_USB_GSPCA_PAC207=m
-CONFIG_USB_GSPCA_PAC7311=m
-CONFIG_USB_GSPCA_SONIXB=m
-CONFIG_USB_GSPCA_SONIXJ=m
-CONFIG_USB_GSPCA_SPCA500=m
-CONFIG_USB_GSPCA_SPCA501=m
-CONFIG_USB_GSPCA_SPCA505=m
-CONFIG_USB_GSPCA_SPCA506=m
-CONFIG_USB_GSPCA_SPCA508=m
-CONFIG_USB_GSPCA_SPCA561=m
-CONFIG_USB_GSPCA_STK014=m
-CONFIG_USB_GSPCA_SUNPLUS=m
-CONFIG_USB_GSPCA_T613=m
-CONFIG_USB_GSPCA_TV8532=m
-CONFIG_USB_GSPCA_VC032X=m
-CONFIG_USB_GSPCA_ZC3XX=m
-# CONFIG_VIDEO_PVRUSB2 is not set
-# CONFIG_VIDEO_EM28XX is not set
-# CONFIG_VIDEO_USBVISION is not set
-CONFIG_VIDEO_USBVIDEO=m
-CONFIG_USB_VICAM=m
-CONFIG_USB_IBMCAM=m
-CONFIG_USB_KONICAWC=m
-CONFIG_USB_QUICKCAM_MESSENGER=m
-CONFIG_USB_ET61X251=m
-# CONFIG_VIDEO_OVCAMCHIP is not set
-CONFIG_USB_OV511=m
-CONFIG_USB_SE401=m
-CONFIG_USB_SN9C102=m
-CONFIG_USB_STV680=m
-CONFIG_USB_ZC0301=m
-CONFIG_USB_PWC=m
-# CONFIG_USB_PWC_DEBUG is not set
-# CONFIG_USB_ZR364XX is not set
-CONFIG_USB_STKWEBCAM=m
-CONFIG_USB_S2255=m
-CONFIG_RADIO_ADAPTERS=y
-# CONFIG_RADIO_CADET is not set
-# CONFIG_RADIO_RTRACK is not set
-# CONFIG_RADIO_RTRACK2 is not set
-# CONFIG_RADIO_AZTECH is not set
-# CONFIG_RADIO_GEMTEK is not set
-# CONFIG_RADIO_GEMTEK_PCI is not set
-# CONFIG_RADIO_MAXIRADIO is not set
-# CONFIG_RADIO_MAESTRO is not set
-# CONFIG_RADIO_SF16FMI is not set
-# CONFIG_RADIO_SF16FMR2 is not set
-# CONFIG_RADIO_TERRATEC is not set
-# CONFIG_RADIO_TRUST is not set
-# CONFIG_RADIO_TYPHOON is not set
-# CONFIG_RADIO_ZOLTRIX is not set
-# CONFIG_USB_DSBR is not set
-CONFIG_USB_SI470X=m
-CONFIG_USB_MR800=m
-CONFIG_DAB=y
-# CONFIG_USB_DABUSB is not set
-
-#
-# Graphics support
-#
-# CONFIG_DRM is not set
-# CONFIG_VGASTATE is not set
-CONFIG_VIDEO_OUTPUT_CONTROL=m
-CONFIG_FB=y
-# CONFIG_FIRMWARE_EDID is not set
-# CONFIG_FB_DDC is not set
-# CONFIG_FB_BOOT_VESA_SUPPORT is not set
-CONFIG_FB_CFB_FILLRECT=y
-CONFIG_FB_CFB_COPYAREA=y
-CONFIG_FB_CFB_IMAGEBLIT=y
-# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
-# CONFIG_FB_SYS_FILLRECT is not set
-# CONFIG_FB_SYS_COPYAREA is not set
-# CONFIG_FB_SYS_IMAGEBLIT is not set
-# CONFIG_FB_FOREIGN_ENDIAN is not set
-# CONFIG_FB_SYS_FOPS is not set
-# CONFIG_FB_SVGALIB is not set
-# CONFIG_FB_MACMODES is not set
-CONFIG_FB_BACKLIGHT=y
-CONFIG_FB_MODE_HELPERS=y
-# CONFIG_FB_TILEBLITTING is not set
-
-#
-# Frame buffer hardware drivers
-#
-# CONFIG_FB_CIRRUS is not set
-# CONFIG_FB_PM2 is not set
-# CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_ASILIANT is not set
-# CONFIG_FB_IMSTT is not set
-# CONFIG_FB_S1D13XXX is not set
-# CONFIG_FB_NVIDIA is not set
-# CONFIG_FB_RIVA is not set
-# CONFIG_FB_MATROX is not set
-CONFIG_FB_RADEON=y
-# CONFIG_FB_RADEON_I2C is not set
-CONFIG_FB_RADEON_BACKLIGHT=y
-# CONFIG_FB_RADEON_DEBUG is not set
-# CONFIG_FB_ATY128 is not set
-# CONFIG_FB_ATY is not set
-# CONFIG_FB_S3 is not set
-# CONFIG_FB_SAVAGE is not set
-# CONFIG_FB_SIS is not set
-# CONFIG_FB_VIA is not set
-# CONFIG_FB_NEOMAGIC is not set
-# CONFIG_FB_KYRO is not set
-# CONFIG_FB_3DFX is not set
-# CONFIG_FB_VOODOO1 is not set
-# CONFIG_FB_VT8623 is not set
-# CONFIG_FB_TRIDENT is not set
-# CONFIG_FB_ARK is not set
-# CONFIG_FB_PM3 is not set
-# CONFIG_FB_CARMINE is not set
-# CONFIG_FB_VIRTUAL is not set
-# CONFIG_FB_METRONOME is not set
-# CONFIG_FB_MB862XX is not set
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-CONFIG_LCD_CLASS_DEVICE=m
-# CONFIG_LCD_ILI9320 is not set
-# CONFIG_LCD_PLATFORM is not set
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-# CONFIG_BACKLIGHT_CORGI is not set
-
-#
-# Display device support
-#
-# CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_MDA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
-# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
-# CONFIG_FONTS is not set
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
-# CONFIG_LOGO is not set
-CONFIG_SOUND=y
-CONFIG_SOUND_OSS_CORE=y
-CONFIG_SND=m
-CONFIG_SND_TIMER=m
-CONFIG_SND_PCM=m
-CONFIG_SND_RAWMIDI=m
-CONFIG_SND_SEQUENCER=m
-CONFIG_SND_SEQ_DUMMY=m
-CONFIG_SND_OSSEMUL=y
-CONFIG_SND_MIXER_OSS=m
-CONFIG_SND_PCM_OSS=m
-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 is not set
-# CONFIG_SND_DEBUG is not set
-CONFIG_SND_VMASTER=y
-CONFIG_SND_MPU401_UART=m
-CONFIG_SND_AC97_CODEC=m
-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_AC97_POWER_SAVE is not set
-CONFIG_SND_PCI=y
-# CONFIG_SND_AD1889 is not set
-# CONFIG_SND_ALS300 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_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 is not set
-# 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=m
-# 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_MIPS=y
-CONFIG_SND_USB=y
-# CONFIG_SND_USB_AUDIO 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=m
-CONFIG_HID_SUPPORT=y
-CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
-CONFIG_HIDRAW=y
-
-#
-# USB Input Devices
-#
-CONFIG_USB_HID=m
-CONFIG_HID_PID=y
-CONFIG_USB_HIDDEV=y
-
-#
-# USB HID Boot Protocol drivers
-#
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
-
-#
-# Special HID drivers
-#
-CONFIG_HID_COMPAT=y
-CONFIG_HID_A4TECH=m
-CONFIG_HID_APPLE=m
-CONFIG_HID_BELKIN=m
-CONFIG_HID_BRIGHT=m
-CONFIG_HID_CHERRY=m
-CONFIG_HID_CHICONY=m
-CONFIG_HID_CYPRESS=m
-CONFIG_HID_DELL=m
-CONFIG_HID_EZKEY=m
-CONFIG_HID_GYRATION=m
-CONFIG_HID_LOGITECH=m
-CONFIG_LOGITECH_FF=y
-CONFIG_LOGIRUMBLEPAD2_FF=y
-CONFIG_HID_MICROSOFT=m
-CONFIG_HID_MONTEREY=m
-CONFIG_HID_PANTHERLORD=m
-# CONFIG_PANTHERLORD_FF is not set
-CONFIG_HID_PETALYNX=m
-CONFIG_HID_SAMSUNG=m
-CONFIG_HID_SONY=m
-CONFIG_HID_SUNPLUS=m
-# CONFIG_THRUSTMASTER_FF is not set
-CONFIG_ZEROPLUS_FF=m
-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=y
-
-#
-# Miscellaneous USB options
-#
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_DEVICE_CLASS is not set
-# CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_SUSPEND is not set
-# CONFIG_USB_OTG is not set
-CONFIG_USB_OTG_WHITELIST=y
-# CONFIG_USB_OTG_BLACKLIST_HUB is not set
-# CONFIG_USB_MON is not set
-# CONFIG_USB_WUSB is not set
-CONFIG_USB_WUSB_CBAF=m
-# CONFIG_USB_WUSB_CBAF_DEBUG is not set
-
-#
-# USB Host Controller Drivers
-#
-CONFIG_USB_C67X00_HCD=m
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_ROOT_HUB_TT=y
-CONFIG_USB_EHCI_TT_NEWSCHED=y
-# CONFIG_USB_ISP116X_HCD is not set
-CONFIG_USB_ISP1760_HCD=m
-CONFIG_USB_OHCI_HCD=y
-# 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=m
-# CONFIG_USB_SL811_HCD is not set
-CONFIG_USB_R8A66597_HCD=m
-# CONFIG_USB_WHCI_HCD is not set
-# CONFIG_USB_HWA_HCD is not set
-
-#
-# USB Device Class drivers
-#
-CONFIG_USB_ACM=y
-CONFIG_USB_PRINTER=y
-CONFIG_USB_WDM=m
-CONFIG_USB_TMC=m
-
-#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD 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=y
-# CONFIG_USB_STORAGE_KARMA is not set
-CONFIG_USB_STORAGE_CYPRESS_ATACB=y
-CONFIG_USB_LIBUSUAL=y
-
-#
-# 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_SEVSEG=m
-# 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=m
-CONFIG_USB_VST=m
-# CONFIG_USB_GADGET is not set
-# CONFIG_UWB 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_RTC_LIB=y
-CONFIG_RTC_CLASS=m
-
-#
-# RTC interfaces
-#
-CONFIG_RTC_INTF_SYSFS=y
-CONFIG_RTC_INTF_PROC=y
-CONFIG_RTC_INTF_DEV=y
-CONFIG_RTC_INTF_DEV_UIE_EMUL=y
-# 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
-# CONFIG_RTC_DRV_RX8581 is not set
-
-#
-# SPI RTC drivers
-#
-
-#
-# Platform RTC drivers
-#
-CONFIG_RTC_DRV_CMOS=m
-# CONFIG_RTC_DRV_DS1286 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_M48T35 is not set
-# CONFIG_RTC_DRV_M48T59 is not set
-# CONFIG_RTC_DRV_BQ4802 is not set
-# CONFIG_RTC_DRV_V3020 is not set
-
-#
-# on-CPU RTC drivers
-#
-# CONFIG_DMADEVICES is not set
-CONFIG_UIO=m
-CONFIG_UIO_CIF=m
-# CONFIG_UIO_PDRV is not set
-# CONFIG_UIO_PDRV_GENIRQ is not set
-# CONFIG_UIO_SMX is not set
-# CONFIG_UIO_SERCOS3 is not set
-# CONFIG_STAGING is not set
-CONFIG_STAGING_EXCLUDE_BUILD=y
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-CONFIG_EXT2_FS_XIP=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_FS_XATTR is not set
-CONFIG_EXT4_FS=m
-CONFIG_EXT4DEV_COMPAT=y
-CONFIG_EXT4_FS_XATTR=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
-CONFIG_FS_XIP=y
-CONFIG_JBD=y
-CONFIG_JBD2=m
-CONFIG_FS_MBCACHE=m
-CONFIG_REISERFS_FS=m
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_REISERFS_FS_XATTR is not set
-# CONFIG_JFS_FS is not set
-CONFIG_FS_POSIX_ACL=y
-CONFIG_FILE_LOCKING=y
-# CONFIG_XFS_FS 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 is not set
-CONFIG_AUTOFS_FS=y
-CONFIG_AUTOFS4_FS=y
-CONFIG_FUSE_FS=y
-
-#
-# 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=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_FAT_DEFAULT_CODEPAGE=936
-CONFIG_FAT_DEFAULT_IOCHARSET="utf8"
-CONFIG_NTFS_FS=m
-# CONFIG_NTFS_DEBUG is not set
-CONFIG_NTFS_RW=y
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_PROC_SYSCTL=y
-CONFIG_PROC_PAGE_MONITOR=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-# CONFIG_TMPFS_POSIX_ACL is not set
-# CONFIG_HUGETLB_PAGE is not set
-# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_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_OMFS_FS=m
-# 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=m
-CONFIG_NFS_V3=y
-CONFIG_NFS_V3_ACL=y
-CONFIG_NFS_V4=y
-CONFIG_NFSD=m
-CONFIG_NFSD_V2_ACL=y
-CONFIG_NFSD_V3=y
-CONFIG_NFSD_V3_ACL=y
-CONFIG_NFSD_V4=y
-CONFIG_LOCKD=m
-CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=m
-CONFIG_NFS_ACL_SUPPORT=m
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=m
-CONFIG_SUNRPC_GSS=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
-CONFIG_RPCSEC_GSS_KRB5=m
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
-CONFIG_SMB_FS=m
-CONFIG_SMB_NLS_DEFAULT=y
-CONFIG_SMB_NLS_REMOTE="cp936"
-CONFIG_CIFS=m
-CONFIG_CIFS_STATS=y
-CONFIG_CIFS_STATS2=y
-CONFIG_CIFS_WEAK_PW_HASH=y
-CONFIG_CIFS_XATTR=y
-CONFIG_CIFS_POSIX=y
-CONFIG_CIFS_DEBUG2=y
-CONFIG_CIFS_EXPERIMENTAL=y
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-# CONFIG_9P_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="utf8"
-# 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=y
-# 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=y
-# CONFIG_DLM is not set
-
-#
-# Kernel hacking
-#
-CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-# CONFIG_PRINTK_TIME is not set
-CONFIG_ENABLE_WARN_DEPRECATED=y
-# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_FRAME_WARN=2048
-# 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 is not set
-# CONFIG_DEBUG_MEMORY_INIT is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
-
-#
-# Tracers
-#
-CONFIG_DYNAMIC_PRINTK_DEBUG=y
-# CONFIG_SAMPLES is not set
-CONFIG_HAVE_ARCH_KGDB=y
-CONFIG_CMDLINE=""
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-# CONFIG_SECURITYFS is not set
-CONFIG_SECURITY_FILE_CAPABILITIES=y
-CONFIG_CRYPTO=y
-
-#
-# Crypto core or helper
-#
-CONFIG_CRYPTO_FIPS=y
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_AEAD=y
-CONFIG_CRYPTO_BLKCIPHER=y
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_RNG=y
-CONFIG_CRYPTO_MANAGER=y
-CONFIG_CRYPTO_GF128MUL=m
-# CONFIG_CRYPTO_NULL is not set
-# CONFIG_CRYPTO_CRYPTD is not set
-CONFIG_CRYPTO_AUTHENC=m
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Authenticated Encryption with Associated Data
-#
-CONFIG_CRYPTO_CCM=m
-CONFIG_CRYPTO_GCM=m
-CONFIG_CRYPTO_SEQIV=m
-
-#
-# Block modes
-#
-CONFIG_CRYPTO_CBC=m
-CONFIG_CRYPTO_CTR=m
-CONFIG_CRYPTO_CTS=m
-CONFIG_CRYPTO_ECB=m
-# CONFIG_CRYPTO_LRW is not set
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_XTS=m
-
-#
-# 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=m
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-CONFIG_CRYPTO_RMD128=m
-CONFIG_CRYPTO_RMD160=m
-CONFIG_CRYPTO_RMD256=m
-CONFIG_CRYPTO_RMD320=m
-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=m
-# CONFIG_CRYPTO_ANUBIS is not set
-CONFIG_CRYPTO_ARC4=m
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-CONFIG_CRYPTO_DES=m
-# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_KHAZAD is not set
-CONFIG_CRYPTO_SALSA20=m
-CONFIG_CRYPTO_SEED=m
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-
-#
-# Compression
-#
-CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_LZO=m
-
-#
-# Random Number Generation
-#
-CONFIG_CRYPTO_ANSI_CPRNG=m
-# CONFIG_CRYPTO_HW is not set
-
-#
-# Library routines
-#
-CONFIG_BITREVERSE=y
-CONFIG_CRC_CCITT=y
-CONFIG_CRC16=m
-# CONFIG_CRC_T10DIF is not set
-CONFIG_CRC_ITU_T=m
-CONFIG_CRC32=y
-CONFIG_CRC7=m
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=m
-CONFIG_ZLIB_DEFLATE=m
-CONFIG_LZO_COMPRESS=m
-CONFIG_LZO_DECOMPRESS=m
-CONFIG_TEXTSEARCH=y
-CONFIG_TEXTSEARCH_KMP=m
-CONFIG_TEXTSEARCH_BM=m
-CONFIG_TEXTSEARCH_FSM=m
-CONFIG_PLIST=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
diff --git a/arch/mips/configs/fuloong2e_defconfig b/arch/mips/configs/fuloong2e_defconfig
new file mode 100644 (file)
index 0000000..0197f0d
--- /dev/null
@@ -0,0 +1,1819 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.31-rc1
+# Thu Jul  2 22:37:00 2009
+#
+CONFIG_MIPS=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_ALCHEMY is not set
+# CONFIG_AR7 is not set
+# CONFIG_BASLER_EXCITE is not set
+# CONFIG_BCM47XX is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+CONFIG_MACH_LOONGSON=y
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_NEC_MARKEINS is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_NXP_STB220 is not set
+# CONFIG_NXP_STB225 is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
+# CONFIG_PMC_MSP is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP28 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SNI_RM is not set
+# CONFIG_MACH_TX39XX is not set
+# CONFIG_MACH_TX49XX is not set
+# CONFIG_MIKROTIK_RB532 is not set
+# CONFIG_WR_PPMC is not set
+# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
+# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
+# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_LEMOTE_FULOONG2E=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_SUPPORTS_OPROFILE=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_CEVT_R4K_LIB=y
+CONFIG_CEVT_R4K=y
+CONFIG_CSRC_R4K_LIB=y
+CONFIG_CSRC_R4K=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+CONFIG_I8259=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_ISA_DMA_SUPPORT_BROKEN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_IRQ_CPU=y
+CONFIG_BOOT_ELF32=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+CONFIG_CPU_LOONGSON2E=y
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R5500 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_CAVIUM_OCTEON is not set
+CONFIG_CPU_LOONGSON2=y
+CONFIG_SYS_HAS_CPU_LOONGSON2E=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+# CONFIG_32BIT is not set
+CONFIG_64BIT=y
+# CONFIG_PAGE_SIZE_4KB is not set
+# CONFIG_PAGE_SIZE_8KB is not set
+CONFIG_PAGE_SIZE_16KB=y
+# CONFIG_PAGE_SIZE_32KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_BOARD_SCACHE=y
+CONFIG_MIPS_MT_DISABLED=y
+# CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
+CONFIG_CPU_HAS_WB=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_SYS_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_SPARSEMEM_STATIC=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_48 is not set
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_128 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_256 is not set
+# CONFIG_HZ_1000 is not set
+# CONFIG_HZ_1024 is not set
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_HZ=250
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
+CONFIG_SECCOMP=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION="-fuloong2e"
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+CONFIG_USER_NS=y
+CONFIG_PID_NS=y
+# CONFIG_NET_NS is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+# CONFIG_PCSPKR_PLATFORM is not set
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Performance Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
+CONFIG_MARKERS=y
+CONFIG_OPROFILE=m
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_SYSCALL_WRAPPERS=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
+CONFIG_BLOCK_COMPAT=y
+
+#
+# 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_FREEZER is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
+CONFIG_ISA=y
+CONFIG_MMU=y
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+CONFIG_BINFMT_MISC=y
+CONFIG_MIPS32_COMPAT=y
+CONFIG_COMPAT=y
+CONFIG_SYSVIPC_COMPAT=y
+CONFIG_MIPS32_O32=y
+CONFIG_MIPS32_N32=y
+CONFIG_BINFMT_ELF32=y
+
+#
+# Power management options
+#
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_SUSPEND is not set
+# CONFIG_HIBERNATION is not set
+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 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=y
+# CONFIG_IP_PNP_RARP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+# CONFIG_IP_MROUTE 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 is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# 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=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+# CONFIG_NF_CONNTRACK is not set
+# CONFIG_NETFILTER_TPROXY is not set
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+CONFIG_NETFILTER_XT_TARGET_HL=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_RATEEST=m
+CONFIG_NETFILTER_XT_TARGET_TRACE=m
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
+CONFIG_NETFILTER_XT_MATCH_HL=m
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_OWNER=m
+# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_RATEEST=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_RECENT=m
+# CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT is not set
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_TIME=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+# CONFIG_NETFILTER_XT_MATCH_OSF is not set
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_NF_DEFRAG_IPV4 is not set
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=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=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+# 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_NET_DSA 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_PHONET=m
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_OLD_REGULATORY=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+CONFIG_MAC80211_DEFAULT_PS_VALUE=0
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+CONFIG_NET_9P=m
+# CONFIG_NET_9P_DEBUG 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=m
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=m
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_PARTITIONS is not set
+# CONFIG_MTD_TESTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLKDEVS=m
+CONFIG_MTD_BLOCK=m
+# 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=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+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 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 is not set
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_CFI_UTIL=m
+# 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=m
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# 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
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+# CONFIG_PNP is not set
+CONFIG_BLK_DEV=y
+# 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=m
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=m
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# 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=m
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+CONFIG_IDE=y
+
+#
+# Please see Documentation/ide/ide.txt for help/info on IDE drives
+#
+CONFIG_IDE_XFER_MODE=y
+CONFIG_IDE_TIMINGS=y
+CONFIG_IDE_ATAPI=y
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_IDE_GD=y
+CONFIG_IDE_GD_ATA=y
+# CONFIG_IDE_GD_ATAPI is not set
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_IDE_TASK_IOCTL=y
+CONFIG_IDE_PROC_FS=y
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_PLATFORM is not set
+CONFIG_BLK_DEV_IDEDMA_SFF=y
+
+#
+# PCI IDE chipsets support
+#
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_PCIBUS_ORDER=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT8172 is not set
+# CONFIG_BLK_DEV_IT8213 is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_BLK_DEV_TC86C001 is not set
+
+#
+# Other IDE chipsets support
+#
+
+#
+# Note: most of these also require special kernel boot parameters
+#
+# CONFIG_BLK_DEV_4DRIVES is not set
+# CONFIG_BLK_DEV_ALI14XX is not set
+# CONFIG_BLK_DEV_DTC2278 is not set
+# CONFIG_BLK_DEV_HT6560B is not set
+# CONFIG_BLK_DEV_QD65XX is not set
+# CONFIG_BLK_DEV_UMC8672 is not set
+CONFIG_BLK_DEV_IDEDMA=y
+
+#
+# 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=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+# 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_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+CONFIG_MACVLAN=m
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+CONFIG_VETH=m
+# CONFIG_ARCNET is not set
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 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_VENDOR_SMC is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_DNET is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TC35815 is not set
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+CONFIG_8139TOO=y
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_R6040 is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SMSC9420 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_KS8842 is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_SC92031 is not set
+# CONFIG_ATL2 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_IGBVF 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_CNIC is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
+# CONFIG_JME is not set
+CONFIG_NETDEV_10000=y
+# CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3_DEPENDS=y
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_ENIC is not set
+# CONFIG_IXGBE is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+# CONFIG_NIU is not set
+# CONFIG_MLX4_EN is not set
+# CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
+# CONFIG_BNX2X is not set
+# CONFIG_QLGE is not set
+# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# 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=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=m
+CONFIG_PPPOE=m
+CONFIG_PPPOL2TP=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLHC=m
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+CONFIG_NET_FC=y
+# 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=y
+# 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=y
+CONFIG_KEYBOARD_ATKBD=y
+# 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_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_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+CONFIG_MOUSE_SERIAL=y
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_INPORT is not set
+# CONFIG_MOUSE_LOGIBM is not set
+# CONFIG_MOUSE_PC110PAD is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C 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_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 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+CONFIG_RTC=y
+# CONFIG_DTLK 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=m
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=m
+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=m
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# 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_ELEKTOR is not set
+# CONFIG_I2C_PCA_ISA is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 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
+
+#
+# PPS support
+#
+# CONFIG_PPS 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
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# 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
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+CONFIG_FB_BACKLIGHT=y
+CONFIG_FB_MODE_HELPERS=y
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+CONFIG_FB_RADEON=y
+# CONFIG_FB_RADEON_I2C is not set
+CONFIG_FB_RADEON_BACKLIGHT=y
+# CONFIG_FB_RADEON_DEBUG is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_VIA is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CARMINE is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=m
+# CONFIG_LCD_ILI9320 is not set
+# CONFIG_LCD_PLATFORM is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_GENERIC=y
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_LOGO is not set
+CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_RTCTIMER 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_VMASTER=y
+CONFIG_SND_RAWMIDI_SEQ=m
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_MPU401_UART=m
+CONFIG_SND_AC97_CODEC=m
+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_AC97_POWER_SAVE is not set
+CONFIG_SND_PCI=y
+# CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALS300 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_CTXFI 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_INDIGOIOX is not set
+# CONFIG_SND_INDIGODJX 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 is not set
+# CONFIG_SND_INTEL8X0M is not set
+# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_LX6464ES 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=m
+# 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_MIPS=y
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO 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=m
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+CONFIG_HIDRAW=y
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+CONFIG_HID_PID=y
+
+#
+# USB HID Boot Protocol drivers
+#
+CONFIG_USB_KBD=y
+CONFIG_USB_MOUSE=y
+
+#
+# Special HID drivers
+#
+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=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+CONFIG_USB_OTG_WHITELIST=y
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+CONFIG_USB_WUSB_CBAF=m
+# CONFIG_USB_WUSB_CBAF_DEBUG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_C67X00_HCD=m
+# CONFIG_USB_XHCI_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_ISP1760_HCD=m
+CONFIG_USB_OHCI_HCD=y
+# 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=m
+# CONFIG_USB_SL811_HCD is not set
+CONFIG_USB_R8A66597_HCD=m
+# CONFIG_USB_WHCI_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=y
+CONFIG_USB_PRINTER=y
+CONFIG_USB_WDM=m
+CONFIG_USB_TMC=m
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+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_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=y
+# CONFIG_USB_STORAGE_KARMA is not set
+CONFIG_USB_STORAGE_CYPRESS_ATACB=y
+CONFIG_USB_LIBUSUAL=y
+
+#
+# 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_SEVSEG=m
+# 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_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=m
+CONFIG_USB_VST=m
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_UWB 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_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+CONFIG_UIO=m
+CONFIG_UIO_CIF=m
+# CONFIG_UIO_PDRV is not set
+# CONFIG_UIO_PDRV_GENIRQ is not set
+# CONFIG_UIO_SMX is not set
+# CONFIG_UIO_AEC is not set
+# CONFIG_UIO_SERCOS3 is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT2_FS_XIP=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_EXT4_FS=m
+CONFIG_EXT4DEV_COMPAT=y
+CONFIG_EXT4_FS_XATTR=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_FS_XIP=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=m
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=m
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_REISERFS_FS_XATTR is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=y
+# CONFIG_CUSE is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE 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=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=936
+CONFIG_FAT_DEFAULT_IOCHARSET="utf8"
+CONFIG_NTFS_FS=m
+# CONFIG_NTFS_DEBUG is not set
+CONFIG_NTFS_RW=y
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+CONFIG_OMFS_FS=m
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_SMB_NLS_REMOTE="cp936"
+CONFIG_CIFS=m
+CONFIG_CIFS_STATS=y
+CONFIG_CIFS_STATS2=y
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+CONFIG_CIFS_DEBUG2=y
+CONFIG_CIFS_EXPERIMENTAL=y
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_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="utf8"
+# 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=y
+# 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=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=2048
+# 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_STACKTRACE=y
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_NOP_TRACER=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_SECURITY_FILE_CAPABILITIES=y
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_FIPS=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_GF128MUL=m
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+CONFIG_CRYPTO_CCM=m
+CONFIG_CRYPTO_GCM=m
+CONFIG_CRYPTO_SEQIV=m
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_CTR=m
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+
+#
+# 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=m
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
+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=m
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=m
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+CONFIG_CRYPTO_SALSA20=m
+CONFIG_CRYPTO_SEED=m
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=m
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
+# CONFIG_CRYPTO_HW is not set
+CONFIG_BINARY_PRINTF=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=m
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+CONFIG_CRC7=m
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_LZO_COMPRESS=m
+CONFIG_LZO_DECOMPRESS=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
index 1158228764175bd98dced751c530f25ee7a74332..f14d38ba6034ea897e71764071475dc7b7a88af6 100644 (file)
@@ -130,7 +130,6 @@ CONFIG_IP22_CPU_SCACHE=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
index 0208723adf28e287d98d59bcc9afe2876b2cb184..1fc73aa7b509c73df1e6133899c7be4d8f5b0c47 100644 (file)
@@ -105,7 +105,6 @@ CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
index 70a744e9a8c55027e6197898cffa7133da44ab74..539dccb0345d18610d8e5407e92a4e12471f6cd7 100644 (file)
@@ -123,7 +123,6 @@ CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
index de4c7a0a96ddde228e6b2806ea5f5a48a8758a4c..d934bdefb393b44efc0444f499909ffb651f1ffc 100644 (file)
@@ -118,7 +118,6 @@ CONFIG_RM7000_CPU_SCACHE=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
index bbacc35d804fdc761b96cdd9d78ef92044e450a8..d22df61833a8efd95369f797d46b09f552b58299 100644 (file)
@@ -119,7 +119,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
index bc9159fda72892dd40c38f858ad8e0cc6395ed45..044074db7e55a40255f45b2a3121869fa4316435 100644 (file)
@@ -108,7 +108,6 @@ CONFIG_R5000_CPU_SCACHE=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
index 1ecdd3b65dc7bc7f9e11c1e29aa09bc514a55da7..3f01870b4d655a2ac4789b19d5e4c50a2ed94814 100644 (file)
@@ -139,7 +139,6 @@ CONFIG_SYS_SUPPORTS_SCHED_SMT=y
 CONFIG_SYS_SUPPORTS_MULTITHREADING=y
 CONFIG_MIPS_MT_FPAFF=y
 # CONFIG_MIPS_VPE_LOADER is not set
-CONFIG_CPU_HAS_LLSC=y
 # CONFIG_CPU_HAS_SMARTMIPS is not set
 CONFIG_CPU_MIPSR2_IRQ_VI=y
 CONFIG_CPU_MIPSR2_IRQ_EI=y
index bad8901f8f3cff6dab343a76600005a4a0013efb..d001f7e8741805bb756a5b8f5bdc9e1a6983d5fa 100644 (file)
@@ -112,7 +112,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
index 2c0a6314e901a3aedb203cf0153bc37ab313f767..7358454deaa66b430a5cdd14f08d9a3bf2577dae 100644 (file)
@@ -115,7 +115,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 CONFIG_SYS_SUPPORTS_MULTITHREADING=y
 # CONFIG_MIPS_VPE_LOADER is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
index 84d6491b3d4148faa4ed9fd01eb998a22b9803cc..ecbc030b7b6ce47a00d8caeb85614ba6aab93807 100644 (file)
@@ -129,7 +129,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_SYS_SUPPORTS_MULTITHREADING=y
 # CONFIG_64BIT_PHYS_ADDR is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
index fadb351d249bbfdc2fc0291ba44b27b4ab2c5afe..9477f040796d0ef08eafcec8593022673e2c19cc 100644 (file)
@@ -116,7 +116,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
 CONFIG_64BIT_PHYS_ADDR=y
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
index 9e21e333a2fc66efaef996f0198718f8b46ed15c..be8091ef0a79042be99441ccc02a29db602931f7 100644 (file)
@@ -115,7 +115,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
index af67ed4f71ae8bf3ad06f44e4a829c84b53cb528..e74ba794c789103f5daf3b315cbe552834ab7965 100644 (file)
@@ -114,7 +114,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
index 7956f56cbf3ed0dd1a9ca825d4b3651ed5c15195..1d896fd830dad6530aa83fb3b3b6b0ee2141c7fa 100644 (file)
@@ -115,7 +115,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
index 2728caa6c2fb83d5a52f0c777f49e6cb6ea94ce3..fef4d31c20550133141d1723689d58384cdf2f62 100644 (file)
@@ -112,7 +112,6 @@ CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_MIPSR2_IRQ_VI=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
index 723bd5176a358a7a1993335c931223be403d2c18..e10c7116c3c20c353baf373103e84536a28e400c 100644 (file)
@@ -112,7 +112,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
index b5052fb42e9ef11475960579564c7268fbb1808e..5ed3c8dfa0a10dd383f9efefe04faab574a52d6d 100644 (file)
@@ -112,7 +112,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
index f28dc32974e5a8bfa7848103c3062fab755e9815..f40c3a04739d5e194716784e65c1a901eaad205c 100644 (file)
@@ -113,7 +113,6 @@ CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
index 1efe977497dd5c9d0b83235154e772c92baefd74..c69813b8488cd6fc52d50d9b569db508a40254e7 100644 (file)
@@ -142,7 +142,6 @@ CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
index 0f4da0325ea4da2ae38c96043be1968f45d0e556..e53b8d096cfce0acde91225ef5b981c11288d3cc 100644 (file)
@@ -124,7 +124,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
index a9acaa2f9da3e6bc31a81ab2a729c6955b5db523..7f38c0b956f312701428cc5e770edf423364e619 100644 (file)
@@ -133,7 +133,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
 CONFIG_SB1_PASS_2_WORKAROUNDS=y
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
index fc2c56731b98ae9ab5930165e6652a820c29700e..06acc7482e4c84e73212ff1bb4268bc614323f71 100644 (file)
@@ -120,7 +120,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
index ea8249c75b3f8e0ed37f4f3133dacdf5b3014fb0..69feaf88b5104403df21b44c071e4fe1394152bf 100644 (file)
@@ -115,7 +115,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
index 5a557e268f78440273ef6174c4b54ca40c104807..e95ff3054ff61f83bc56a0458142046655daba6c 100644 (file)
@@ -18,7 +18,7 @@
 #include <asm/sections.h>
 
 
-volatile unsigned long mem_err = 0;    /* So we know an error occurred */
+volatile unsigned long mem_err;                /* So we know an error occurred */
 
 /*
  * Probe memory in 4MB chunks, waiting for an error to tell us we've fallen
index 463136e6685ac80e70359a24f747cc9a221ad999..02f505f23c322654971c6bdca4aaf5241b4d9ab0 100644 (file)
@@ -18,7 +18,7 @@
 #include <asm/dec/ioasic.h>
 #include <asm/dec/machtype.h>
 
-unsigned long read_persistent_clock(void)
+void read_persistent_clock(struct timespec *ts)
 {
        unsigned int year, mon, day, hour, min, sec, real_year;
        unsigned long flags;
@@ -53,7 +53,8 @@ unsigned long read_persistent_clock(void)
 
        year += real_year - 72 + 2000;
 
-       return mktime(year, mon, day, hour, min, sec);
+       ts->tv_sec = mktime(year, mon, day, hour, min, sec);
+       ts->tv_nsec = 0;
 }
 
 /*
index 335dc8c1a1bb47826fecec2aee444ab017b5acb8..9b3f51e5f140219120c8cdfe2df85487d5bf7ab4 100644 (file)
@@ -32,7 +32,7 @@
 
 extern void markeins_led(const char *);
 
-static int bus_frequency = 0;
+static int bus_frequency;
 
 static void markeins_machine_restart(char *command)
 {
index 4f349ec1ea2da4bb200a1c296d16f27b54650935..e0aaad482b0ebc806e971101a4f701ff30d2848e 100644 (file)
@@ -8,3 +8,5 @@ lib-y                           += cmdline.o env.o file.o identify.o init.o \
 lib-$(CONFIG_ARC_MEMORY)       += memory.o
 lib-$(CONFIG_ARC_CONSOLE)      += arc_con.o
 lib-$(CONFIG_ARC_PROMLIB)      += promlib.o
+
+EXTRA_CFLAGS                   += -Werror
index 717db74f7c6ea786ab930fb66072084dacb6f510..d06dc5a6b8d398ec5e4f6947277af6f589d06376 100644 (file)
@@ -45,8 +45,8 @@ int cfe_iocb_dispatch(struct cfe_xiocb *xiocb);
  * passed in two registers each, and CFE expects one.
  */
 
-static int (*cfe_dispfunc) (intptr_t handle, intptr_t xiocb) = 0;
-static u64 cfe_handle = 0;
+static int (*cfe_dispfunc) (intptr_t handle, intptr_t xiocb);
+static u64 cfe_handle;
 
 int cfe_init(u64 handle, u64 ept)
 {
index eb7f01cfd1acb906e2dd1a4ffd02bbd4893bf9f8..dd75d673447e37147c438991829b70c15c7c721b 100644 (file)
@@ -49,7 +49,7 @@
  */
 static __inline__ void atomic_add(int i, atomic_t * v)
 {
-       if (cpu_has_llsc && R10000_LLSC_WAR) {
+       if (kernel_uses_llsc && R10000_LLSC_WAR) {
                int temp;
 
                __asm__ __volatile__(
@@ -61,7 +61,7 @@ static __inline__ void atomic_add(int i, atomic_t * v)
                "       .set    mips0                                   \n"
                : "=&r" (temp), "=m" (v->counter)
                : "Ir" (i), "m" (v->counter));
-       } else if (cpu_has_llsc) {
+       } else if (kernel_uses_llsc) {
                int temp;
 
                __asm__ __volatile__(
@@ -94,7 +94,7 @@ static __inline__ void atomic_add(int i, atomic_t * v)
  */
 static __inline__ void atomic_sub(int i, atomic_t * v)
 {
-       if (cpu_has_llsc && R10000_LLSC_WAR) {
+       if (kernel_uses_llsc && R10000_LLSC_WAR) {
                int temp;
 
                __asm__ __volatile__(
@@ -106,7 +106,7 @@ static __inline__ void atomic_sub(int i, atomic_t * v)
                "       .set    mips0                                   \n"
                : "=&r" (temp), "=m" (v->counter)
                : "Ir" (i), "m" (v->counter));
-       } else if (cpu_has_llsc) {
+       } else if (kernel_uses_llsc) {
                int temp;
 
                __asm__ __volatile__(
@@ -139,7 +139,7 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
 
        smp_llsc_mb();
 
-       if (cpu_has_llsc && R10000_LLSC_WAR) {
+       if (kernel_uses_llsc && R10000_LLSC_WAR) {
                int temp;
 
                __asm__ __volatile__(
@@ -153,7 +153,7 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
                : "=&r" (result), "=&r" (temp), "=m" (v->counter)
                : "Ir" (i), "m" (v->counter)
                : "memory");
-       } else if (cpu_has_llsc) {
+       } else if (kernel_uses_llsc) {
                int temp;
 
                __asm__ __volatile__(
@@ -191,7 +191,7 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
 
        smp_llsc_mb();
 
-       if (cpu_has_llsc && R10000_LLSC_WAR) {
+       if (kernel_uses_llsc && R10000_LLSC_WAR) {
                int temp;
 
                __asm__ __volatile__(
@@ -205,7 +205,7 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
                : "=&r" (result), "=&r" (temp), "=m" (v->counter)
                : "Ir" (i), "m" (v->counter)
                : "memory");
-       } else if (cpu_has_llsc) {
+       } else if (kernel_uses_llsc) {
                int temp;
 
                __asm__ __volatile__(
@@ -251,7 +251,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
 
        smp_llsc_mb();
 
-       if (cpu_has_llsc && R10000_LLSC_WAR) {
+       if (kernel_uses_llsc && R10000_LLSC_WAR) {
                int temp;
 
                __asm__ __volatile__(
@@ -269,7 +269,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
                : "=&r" (result), "=&r" (temp), "=m" (v->counter)
                : "Ir" (i), "m" (v->counter)
                : "memory");
-       } else if (cpu_has_llsc) {
+       } else if (kernel_uses_llsc) {
                int temp;
 
                __asm__ __volatile__(
@@ -428,7 +428,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
  */
 static __inline__ void atomic64_add(long i, atomic64_t * v)
 {
-       if (cpu_has_llsc && R10000_LLSC_WAR) {
+       if (kernel_uses_llsc && R10000_LLSC_WAR) {
                long temp;
 
                __asm__ __volatile__(
@@ -440,7 +440,7 @@ static __inline__ void atomic64_add(long i, atomic64_t * v)
                "       .set    mips0                                   \n"
                : "=&r" (temp), "=m" (v->counter)
                : "Ir" (i), "m" (v->counter));
-       } else if (cpu_has_llsc) {
+       } else if (kernel_uses_llsc) {
                long temp;
 
                __asm__ __volatile__(
@@ -473,7 +473,7 @@ static __inline__ void atomic64_add(long i, atomic64_t * v)
  */
 static __inline__ void atomic64_sub(long i, atomic64_t * v)
 {
-       if (cpu_has_llsc && R10000_LLSC_WAR) {
+       if (kernel_uses_llsc && R10000_LLSC_WAR) {
                long temp;
 
                __asm__ __volatile__(
@@ -485,7 +485,7 @@ static __inline__ void atomic64_sub(long i, atomic64_t * v)
                "       .set    mips0                                   \n"
                : "=&r" (temp), "=m" (v->counter)
                : "Ir" (i), "m" (v->counter));
-       } else if (cpu_has_llsc) {
+       } else if (kernel_uses_llsc) {
                long temp;
 
                __asm__ __volatile__(
@@ -518,7 +518,7 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
 
        smp_llsc_mb();
 
-       if (cpu_has_llsc && R10000_LLSC_WAR) {
+       if (kernel_uses_llsc && R10000_LLSC_WAR) {
                long temp;
 
                __asm__ __volatile__(
@@ -532,7 +532,7 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
                : "=&r" (result), "=&r" (temp), "=m" (v->counter)
                : "Ir" (i), "m" (v->counter)
                : "memory");
-       } else if (cpu_has_llsc) {
+       } else if (kernel_uses_llsc) {
                long temp;
 
                __asm__ __volatile__(
@@ -570,7 +570,7 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
 
        smp_llsc_mb();
 
-       if (cpu_has_llsc && R10000_LLSC_WAR) {
+       if (kernel_uses_llsc && R10000_LLSC_WAR) {
                long temp;
 
                __asm__ __volatile__(
@@ -584,7 +584,7 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
                : "=&r" (result), "=&r" (temp), "=m" (v->counter)
                : "Ir" (i), "m" (v->counter)
                : "memory");
-       } else if (cpu_has_llsc) {
+       } else if (kernel_uses_llsc) {
                long temp;
 
                __asm__ __volatile__(
@@ -630,7 +630,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
 
        smp_llsc_mb();
 
-       if (cpu_has_llsc && R10000_LLSC_WAR) {
+       if (kernel_uses_llsc && R10000_LLSC_WAR) {
                long temp;
 
                __asm__ __volatile__(
@@ -648,7 +648,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
                : "=&r" (result), "=&r" (temp), "=m" (v->counter)
                : "Ir" (i), "m" (v->counter)
                : "memory");
-       } else if (cpu_has_llsc) {
+       } else if (kernel_uses_llsc) {
                long temp;
 
                __asm__ __volatile__(
index b1e9e97a9c78a7835033c97b52d630a262d7924f..84a383806b2cd823d9acbb362df004ae27c15854 100644 (file)
@@ -61,7 +61,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
        unsigned short bit = nr & SZLONG_MASK;
        unsigned long temp;
 
-       if (cpu_has_llsc && R10000_LLSC_WAR) {
+       if (kernel_uses_llsc && R10000_LLSC_WAR) {
                __asm__ __volatile__(
                "       .set    mips3                                   \n"
                "1:     " __LL "%0, %1                  # set_bit       \n"
@@ -72,7 +72,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
                : "=&r" (temp), "=m" (*m)
                : "ir" (1UL << bit), "m" (*m));
 #ifdef CONFIG_CPU_MIPSR2
-       } else if (__builtin_constant_p(bit)) {
+       } else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
                __asm__ __volatile__(
                "1:     " __LL "%0, %1                  # set_bit       \n"
                "       " __INS "%0, %4, %2, 1                          \n"
@@ -84,7 +84,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
                : "=&r" (temp), "=m" (*m)
                : "ir" (bit), "m" (*m), "r" (~0));
 #endif /* CONFIG_CPU_MIPSR2 */
-       } else if (cpu_has_llsc) {
+       } else if (kernel_uses_llsc) {
                __asm__ __volatile__(
                "       .set    mips3                                   \n"
                "1:     " __LL "%0, %1                  # set_bit       \n"
@@ -126,7 +126,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
        unsigned short bit = nr & SZLONG_MASK;
        unsigned long temp;
 
-       if (cpu_has_llsc && R10000_LLSC_WAR) {
+       if (kernel_uses_llsc && R10000_LLSC_WAR) {
                __asm__ __volatile__(
                "       .set    mips3                                   \n"
                "1:     " __LL "%0, %1                  # clear_bit     \n"
@@ -137,7 +137,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
                : "=&r" (temp), "=m" (*m)
                : "ir" (~(1UL << bit)), "m" (*m));
 #ifdef CONFIG_CPU_MIPSR2
-       } else if (__builtin_constant_p(bit)) {
+       } else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
                __asm__ __volatile__(
                "1:     " __LL "%0, %1                  # clear_bit     \n"
                "       " __INS "%0, $0, %2, 1                          \n"
@@ -149,7 +149,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
                : "=&r" (temp), "=m" (*m)
                : "ir" (bit), "m" (*m));
 #endif /* CONFIG_CPU_MIPSR2 */
-       } else if (cpu_has_llsc) {
+       } else if (kernel_uses_llsc) {
                __asm__ __volatile__(
                "       .set    mips3                                   \n"
                "1:     " __LL "%0, %1                  # clear_bit     \n"
@@ -202,7 +202,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
 {
        unsigned short bit = nr & SZLONG_MASK;
 
-       if (cpu_has_llsc && R10000_LLSC_WAR) {
+       if (kernel_uses_llsc && R10000_LLSC_WAR) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
                unsigned long temp;
 
@@ -215,7 +215,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
                "       .set    mips0                           \n"
                : "=&r" (temp), "=m" (*m)
                : "ir" (1UL << bit), "m" (*m));
-       } else if (cpu_has_llsc) {
+       } else if (kernel_uses_llsc) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
                unsigned long temp;
 
@@ -260,7 +260,7 @@ static inline int test_and_set_bit(unsigned long nr,
 
        smp_llsc_mb();
 
-       if (cpu_has_llsc && R10000_LLSC_WAR) {
+       if (kernel_uses_llsc && R10000_LLSC_WAR) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
                unsigned long temp;
 
@@ -275,7 +275,7 @@ static inline int test_and_set_bit(unsigned long nr,
                : "=&r" (temp), "=m" (*m), "=&r" (res)
                : "r" (1UL << bit), "m" (*m)
                : "memory");
-       } else if (cpu_has_llsc) {
+       } else if (kernel_uses_llsc) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
                unsigned long temp;
 
@@ -328,7 +328,7 @@ static inline int test_and_set_bit_lock(unsigned long nr,
        unsigned short bit = nr & SZLONG_MASK;
        unsigned long res;
 
-       if (cpu_has_llsc && R10000_LLSC_WAR) {
+       if (kernel_uses_llsc && R10000_LLSC_WAR) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
                unsigned long temp;
 
@@ -343,7 +343,7 @@ static inline int test_and_set_bit_lock(unsigned long nr,
                : "=&r" (temp), "=m" (*m), "=&r" (res)
                : "r" (1UL << bit), "m" (*m)
                : "memory");
-       } else if (cpu_has_llsc) {
+       } else if (kernel_uses_llsc) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
                unsigned long temp;
 
@@ -397,7 +397,7 @@ static inline int test_and_clear_bit(unsigned long nr,
 
        smp_llsc_mb();
 
-       if (cpu_has_llsc && R10000_LLSC_WAR) {
+       if (kernel_uses_llsc && R10000_LLSC_WAR) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
                unsigned long temp;
 
@@ -414,7 +414,7 @@ static inline int test_and_clear_bit(unsigned long nr,
                : "r" (1UL << bit), "m" (*m)
                : "memory");
 #ifdef CONFIG_CPU_MIPSR2
-       } else if (__builtin_constant_p(nr)) {
+       } else if (kernel_uses_llsc && __builtin_constant_p(nr)) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
                unsigned long temp;
 
@@ -431,7 +431,7 @@ static inline int test_and_clear_bit(unsigned long nr,
                : "ir" (bit), "m" (*m)
                : "memory");
 #endif
-       } else if (cpu_has_llsc) {
+       } else if (kernel_uses_llsc) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
                unsigned long temp;
 
@@ -487,7 +487,7 @@ static inline int test_and_change_bit(unsigned long nr,
 
        smp_llsc_mb();
 
-       if (cpu_has_llsc && R10000_LLSC_WAR) {
+       if (kernel_uses_llsc && R10000_LLSC_WAR) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
                unsigned long temp;
 
@@ -502,7 +502,7 @@ static inline int test_and_change_bit(unsigned long nr,
                : "=&r" (temp), "=m" (*m), "=&r" (res)
                : "r" (1UL << bit), "m" (*m)
                : "memory");
-       } else if (cpu_has_llsc) {
+       } else if (kernel_uses_llsc) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
                unsigned long temp;
 
index 610fe3af7a038763639c982c87c1820bd8bff9a2..f5dfaf6a16064a0ff16785d0e18ee8107f54b60b 100644 (file)
@@ -7,6 +7,7 @@
  * Copyright (C) 1995, 1996 Andreas Busse
  * Copyright (C) 1995, 1996 Stoned Elipot
  * Copyright (C) 1995, 1996 Paul M. Antoine.
+ * Copyright (C) 2009       Zhang Le
  */
 #ifndef _ASM_BOOTINFO_H
 #define _ASM_BOOTINFO_H
 #define        MACH_MIKROTIK_RB532     0       /* Mikrotik RouterBoard 532     */
 #define MACH_MIKROTIK_RB532A   1       /* Mikrotik RouterBoard 532A    */
 
+/*
+ * Valid machtype for Loongson family
+ */
+#define MACH_LOONGSON_UNKNOWN  0
+#define MACH_LEMOTE_FL2E       1
+#define MACH_LEMOTE_FL2F       2
+#define MACH_LEMOTE_ML2F7      3
+#define MACH_LEMOTE_YL2F89     4
+#define MACH_DEXXON_GDIUM2F10  5
+#define MACH_LOONGSON_END      6
+
 #define CL_SIZE                        COMMAND_LINE_SIZE
 
 extern char *system_type;
index 4a812c3ceb90f3b4781a6ead62d018639a66c0f4..815a438a268da85962b1e0a59d6bc0b90e7eee9c 100644 (file)
@@ -16,7 +16,7 @@
 ({                                                                     \
        __typeof(*(m)) __ret;                                           \
                                                                        \
-       if (cpu_has_llsc && R10000_LLSC_WAR) {                          \
+       if (kernel_uses_llsc && R10000_LLSC_WAR) {                              \
                __asm__ __volatile__(                                   \
                "       .set    push                            \n"     \
                "       .set    noat                            \n"     \
@@ -33,7 +33,7 @@
                : "=&r" (__ret), "=R" (*m)                              \
                : "R" (*m), "Jr" (old), "Jr" (new)                      \
                : "memory");                                            \
-       } else if (cpu_has_llsc) {                                      \
+       } else if (kernel_uses_llsc) {                                  \
                __asm__ __volatile__(                                   \
                "       .set    push                            \n"     \
                "       .set    noat                            \n"     \
index 8ab1d12ba7f4abef4dae8c450b58d1ecc682f1a7..1f4df647c384723b179a7b0a8de8873a0fb8b9e8 100644 (file)
@@ -80,6 +80,9 @@
 #ifndef cpu_has_llsc
 #define cpu_has_llsc           (cpu_data[0].options & MIPS_CPU_LLSC)
 #endif
+#ifndef kernel_uses_llsc
+#define kernel_uses_llsc       cpu_has_llsc
+#endif
 #ifndef cpu_has_mips16
 #define cpu_has_mips16         (cpu_data[0].ases & MIPS_ASE_MIPS16)
 #endif
index 3bdc0e3d89ccd2f8edb707c0c1c5dc1702438620..4b96d1a36056e67fb038d06f17812236a790b6ab 100644 (file)
 
 #define PRID_IMP_BCM4710       0x4000
 #define PRID_IMP_BCM3302       0x9000
+#define PRID_IMP_BCM6338       0x9000
+#define PRID_IMP_BCM6345       0x8000
+#define PRID_IMP_BCM6348       0x9100
+#define PRID_IMP_BCM4350       0xA000
+#define PRID_REV_BCM6358       0x0010
+#define PRID_REV_BCM6368       0x0030
 
 /*
  * These are the PRID's for when 23:16 == PRID_COMP_CAVIUM
@@ -210,6 +216,7 @@ enum cpu_type_enum {
         */
        CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K,
        CPU_ALCHEMY, CPU_PR4450, CPU_BCM3302, CPU_BCM4710,
+       CPU_BCM6338, CPU_BCM6345, CPU_BCM6348, CPU_BCM6358,
 
        /*
         * MIPS64 class processors
index d2d8949be6b78800e6d60ba6cc6a07b9057138aa..e7cd78277c2314cee30aec8d078d2e9cd3a8e69e 100644 (file)
@@ -11,6 +11,8 @@
 #ifndef _ASM_DELAY_H
 #define _ASM_DELAY_H
 
+#include <linux/param.h>
+
 extern void __delay(unsigned int loops);
 extern void __ndelay(unsigned int ns);
 extern void __udelay(unsigned int us);
index 0f5caa1307f18f71d97e6057d32ae235401ca7d7..efeddc8db8b1ee15883aec8e23fa95c7e905217b 100644 (file)
@@ -67,11 +67,15 @@ enum fixed_addresses {
  * the start of the fixmap, and leave one page empty
  * at the top of mem..
  */
+#ifdef CONFIG_BCM63XX
+#define FIXADDR_TOP     ((unsigned long)(long)(int)0xff000000)
+#else
 #if defined(CONFIG_CPU_TX39XX) || defined(CONFIG_CPU_TX49XX)
 #define FIXADDR_TOP    ((unsigned long)(long)(int)(0xff000000 - 0x20000))
 #else
 #define FIXADDR_TOP    ((unsigned long)(long)(int)0xfffe0000)
 #endif
+#endif
 #define FIXADDR_SIZE   (__end_of_fixed_addresses << PAGE_SHIFT)
 #define FIXADDR_START  (FIXADDR_TOP - FIXADDR_SIZE)
 
index 90bf399e6dd9139357cf2ad63e5134b829d25f78..c977a86c2c652bb24f771296762540838f22b704 100644 (file)
 #ifndef _ASM_HARDIRQ_H
 #define _ASM_HARDIRQ_H
 
-#include <linux/threads.h>
-#include <linux/irq.h>
-
-typedef struct {
-       unsigned int __softirq_pending;
-} ____cacheline_aligned irq_cpustat_t;
-
-#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
-
 extern void ack_bad_irq(unsigned int irq);
+#define ack_bad_irq ack_bad_irq
+
+#include <asm-generic/hardirq.h>
 
 #endif /* _ASM_HARDIRQ_H */
index caeba1e302a29c8b477348931e33be6284c009b2..a1ada1c27c16c305ea92c889ae8e83b9742af021 100644 (file)
@@ -227,6 +227,7 @@ extern void lasat_write_eeprom_info(void);
  * It is used for the bit-banging rtc and eeprom drivers */
 
 #include <linux/delay.h>
+#include <linux/smp.h>
 
 /* calculating with the slowest board with 100 MHz clock */
 #define LASAT_100_DIVIDER 20
index f96fd59e084577a4e9cfafd83c4801cbf99ed10e..361f4f16c30c1bc82dbb2f55ff0ddab5a7ad455e 100644 (file)
@@ -29,7 +29,7 @@ static __inline__ long local_add_return(long i, local_t * l)
 {
        unsigned long result;
 
-       if (cpu_has_llsc && R10000_LLSC_WAR) {
+       if (kernel_uses_llsc && R10000_LLSC_WAR) {
                unsigned long temp;
 
                __asm__ __volatile__(
@@ -43,7 +43,7 @@ static __inline__ long local_add_return(long i, local_t * l)
                : "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
                : "Ir" (i), "m" (l->a.counter)
                : "memory");
-       } else if (cpu_has_llsc) {
+       } else if (kernel_uses_llsc) {
                unsigned long temp;
 
                __asm__ __volatile__(
@@ -74,7 +74,7 @@ static __inline__ long local_sub_return(long i, local_t * l)
 {
        unsigned long result;
 
-       if (cpu_has_llsc && R10000_LLSC_WAR) {
+       if (kernel_uses_llsc && R10000_LLSC_WAR) {
                unsigned long temp;
 
                __asm__ __volatile__(
@@ -88,7 +88,7 @@ static __inline__ long local_sub_return(long i, local_t * l)
                : "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
                : "Ir" (i), "m" (l->a.counter)
                : "memory");
-       } else if (cpu_has_llsc) {
+       } else if (kernel_uses_llsc) {
                unsigned long temp;
 
                __asm__ __volatile__(
index 127d4ed9f073b7ecb95a8acde70132f5051e363f..feea00148b5d5fd813956c0d39b73cb3b157fab0 100644 (file)
@@ -578,6 +578,15 @@ static inline int irq_to_gpio(int irq)
        return alchemy_irq_to_gpio(irq);
 }
 
+static inline int gpio_request(unsigned gpio, const char *label)
+{
+       return 0;
+}
+
+static inline void gpio_free(unsigned gpio)
+{
+}
+
 #endif /* !CONFIG_ALCHEMY_GPIO_INDIRECT */
 
 
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_board.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_board.h
new file mode 100644 (file)
index 0000000..fa3e7e6
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef BCM63XX_BOARD_H_
+#define BCM63XX_BOARD_H_
+
+const char *board_get_name(void);
+
+void board_prom_init(void);
+
+void board_setup(void);
+
+int board_register_devices(void);
+
+#endif /* ! BCM63XX_BOARD_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_clk.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_clk.h
new file mode 100644 (file)
index 0000000..8fcf8df
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef BCM63XX_CLK_H_
+#define BCM63XX_CLK_H_
+
+struct clk {
+       void            (*set)(struct clk *, int);
+       unsigned int    rate;
+       unsigned int    usage;
+       int             id;
+};
+
+#endif /* ! BCM63XX_CLK_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
new file mode 100644 (file)
index 0000000..b12c4ac
--- /dev/null
@@ -0,0 +1,538 @@
+#ifndef BCM63XX_CPU_H_
+#define BCM63XX_CPU_H_
+
+#include <linux/types.h>
+#include <linux/init.h>
+
+/*
+ * Macro to fetch bcm63xx cpu id and revision, should be optimized at
+ * compile time if only one CPU support is enabled (idea stolen from
+ * arm mach-types)
+ */
+#define BCM6338_CPU_ID         0x6338
+#define BCM6345_CPU_ID         0x6345
+#define BCM6348_CPU_ID         0x6348
+#define BCM6358_CPU_ID         0x6358
+
+void __init bcm63xx_cpu_init(void);
+u16 __bcm63xx_get_cpu_id(void);
+u16 bcm63xx_get_cpu_rev(void);
+unsigned int bcm63xx_get_cpu_freq(void);
+
+#ifdef CONFIG_BCM63XX_CPU_6338
+# ifdef bcm63xx_get_cpu_id
+#  undef bcm63xx_get_cpu_id
+#  define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id()
+#  define BCMCPU_RUNTIME_DETECT
+# else
+#  define bcm63xx_get_cpu_id() BCM6338_CPU_ID
+# endif
+# define BCMCPU_IS_6338()      (bcm63xx_get_cpu_id() == BCM6338_CPU_ID)
+#else
+# define BCMCPU_IS_6338()      (0)
+#endif
+
+#ifdef CONFIG_BCM63XX_CPU_6345
+# ifdef bcm63xx_get_cpu_id
+#  undef bcm63xx_get_cpu_id
+#  define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id()
+#  define BCMCPU_RUNTIME_DETECT
+# else
+#  define bcm63xx_get_cpu_id() BCM6345_CPU_ID
+# endif
+# define BCMCPU_IS_6345()      (bcm63xx_get_cpu_id() == BCM6345_CPU_ID)
+#else
+# define BCMCPU_IS_6345()      (0)
+#endif
+
+#ifdef CONFIG_BCM63XX_CPU_6348
+# ifdef bcm63xx_get_cpu_id
+#  undef bcm63xx_get_cpu_id
+#  define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id()
+#  define BCMCPU_RUNTIME_DETECT
+# else
+#  define bcm63xx_get_cpu_id() BCM6348_CPU_ID
+# endif
+# define BCMCPU_IS_6348()      (bcm63xx_get_cpu_id() == BCM6348_CPU_ID)
+#else
+# define BCMCPU_IS_6348()      (0)
+#endif
+
+#ifdef CONFIG_BCM63XX_CPU_6358
+# ifdef bcm63xx_get_cpu_id
+#  undef bcm63xx_get_cpu_id
+#  define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id()
+#  define BCMCPU_RUNTIME_DETECT
+# else
+#  define bcm63xx_get_cpu_id() BCM6358_CPU_ID
+# endif
+# define BCMCPU_IS_6358()      (bcm63xx_get_cpu_id() == BCM6358_CPU_ID)
+#else
+# define BCMCPU_IS_6358()      (0)
+#endif
+
+#ifndef bcm63xx_get_cpu_id
+#error "No CPU support configured"
+#endif
+
+/*
+ * While registers sets are (mostly) the same across 63xx CPU, base
+ * address of these sets do change.
+ */
+enum bcm63xx_regs_set {
+       RSET_DSL_LMEM = 0,
+       RSET_PERF,
+       RSET_TIMER,
+       RSET_WDT,
+       RSET_UART0,
+       RSET_GPIO,
+       RSET_SPI,
+       RSET_UDC0,
+       RSET_OHCI0,
+       RSET_OHCI_PRIV,
+       RSET_USBH_PRIV,
+       RSET_MPI,
+       RSET_PCMCIA,
+       RSET_DSL,
+       RSET_ENET0,
+       RSET_ENET1,
+       RSET_ENETDMA,
+       RSET_EHCI0,
+       RSET_SDRAM,
+       RSET_MEMC,
+       RSET_DDR,
+};
+
+#define RSET_DSL_LMEM_SIZE             (64 * 1024 * 4)
+#define RSET_DSL_SIZE                  4096
+#define RSET_WDT_SIZE                  12
+#define RSET_ENET_SIZE                 2048
+#define RSET_ENETDMA_SIZE              2048
+#define RSET_UART_SIZE                 24
+#define RSET_UDC_SIZE                  256
+#define RSET_OHCI_SIZE                 256
+#define RSET_EHCI_SIZE                 256
+#define RSET_PCMCIA_SIZE               12
+
+/*
+ * 6338 register sets base address
+ */
+#define BCM_6338_DSL_LMEM_BASE         (0xfff00000)
+#define BCM_6338_PERF_BASE             (0xfffe0000)
+#define BCM_6338_BB_BASE               (0xfffe0100)
+#define BCM_6338_TIMER_BASE            (0xfffe0200)
+#define BCM_6338_WDT_BASE              (0xfffe021c)
+#define BCM_6338_UART0_BASE            (0xfffe0300)
+#define BCM_6338_GPIO_BASE             (0xfffe0400)
+#define BCM_6338_SPI_BASE              (0xfffe0c00)
+#define BCM_6338_UDC0_BASE             (0xdeadbeef)
+#define BCM_6338_USBDMA_BASE           (0xfffe2400)
+#define BCM_6338_OHCI0_BASE            (0xdeadbeef)
+#define BCM_6338_OHCI_PRIV_BASE                (0xfffe3000)
+#define BCM_6338_USBH_PRIV_BASE                (0xdeadbeef)
+#define BCM_6338_MPI_BASE              (0xfffe3160)
+#define BCM_6338_PCMCIA_BASE           (0xdeadbeef)
+#define BCM_6338_SDRAM_REGS_BASE       (0xfffe3100)
+#define BCM_6338_DSL_BASE              (0xfffe1000)
+#define BCM_6338_SAR_BASE              (0xfffe2000)
+#define BCM_6338_UBUS_BASE             (0xdeadbeef)
+#define BCM_6338_ENET0_BASE            (0xfffe2800)
+#define BCM_6338_ENET1_BASE            (0xdeadbeef)
+#define BCM_6338_ENETDMA_BASE          (0xfffe2400)
+#define BCM_6338_EHCI0_BASE            (0xdeadbeef)
+#define BCM_6338_SDRAM_BASE            (0xfffe3100)
+#define BCM_6338_MEMC_BASE             (0xdeadbeef)
+#define BCM_6338_DDR_BASE              (0xdeadbeef)
+
+/*
+ * 6345 register sets base address
+ */
+#define BCM_6345_DSL_LMEM_BASE         (0xfff00000)
+#define BCM_6345_PERF_BASE             (0xfffe0000)
+#define BCM_6345_BB_BASE               (0xfffe0100)
+#define BCM_6345_TIMER_BASE            (0xfffe0200)
+#define BCM_6345_WDT_BASE              (0xfffe021c)
+#define BCM_6345_UART0_BASE            (0xfffe0300)
+#define BCM_6345_GPIO_BASE             (0xfffe0400)
+#define BCM_6345_SPI_BASE              (0xdeadbeef)
+#define BCM_6345_UDC0_BASE             (0xdeadbeef)
+#define BCM_6345_USBDMA_BASE           (0xfffe2800)
+#define BCM_6345_ENET0_BASE            (0xfffe1800)
+#define BCM_6345_ENETDMA_BASE          (0xfffe2800)
+#define BCM_6345_PCMCIA_BASE           (0xfffe2028)
+#define BCM_6345_MPI_BASE              (0xdeadbeef)
+#define BCM_6345_OHCI0_BASE            (0xfffe2100)
+#define BCM_6345_OHCI_PRIV_BASE                (0xfffe2200)
+#define BCM_6345_USBH_PRIV_BASE                (0xdeadbeef)
+#define BCM_6345_SDRAM_REGS_BASE       (0xfffe2300)
+#define BCM_6345_DSL_BASE              (0xdeadbeef)
+#define BCM_6345_SAR_BASE              (0xdeadbeef)
+#define BCM_6345_UBUS_BASE             (0xdeadbeef)
+#define BCM_6345_ENET1_BASE            (0xdeadbeef)
+#define BCM_6345_EHCI0_BASE            (0xdeadbeef)
+#define BCM_6345_SDRAM_BASE            (0xfffe2300)
+#define BCM_6345_MEMC_BASE             (0xdeadbeef)
+#define BCM_6345_DDR_BASE              (0xdeadbeef)
+
+/*
+ * 6348 register sets base address
+ */
+#define BCM_6348_DSL_LMEM_BASE         (0xfff00000)
+#define BCM_6348_PERF_BASE             (0xfffe0000)
+#define BCM_6348_TIMER_BASE            (0xfffe0200)
+#define BCM_6348_WDT_BASE              (0xfffe021c)
+#define BCM_6348_UART0_BASE            (0xfffe0300)
+#define BCM_6348_GPIO_BASE             (0xfffe0400)
+#define BCM_6348_SPI_BASE              (0xfffe0c00)
+#define BCM_6348_UDC0_BASE             (0xfffe1000)
+#define BCM_6348_OHCI0_BASE            (0xfffe1b00)
+#define BCM_6348_OHCI_PRIV_BASE                (0xfffe1c00)
+#define BCM_6348_USBH_PRIV_BASE                (0xdeadbeef)
+#define BCM_6348_MPI_BASE              (0xfffe2000)
+#define BCM_6348_PCMCIA_BASE           (0xfffe2054)
+#define BCM_6348_SDRAM_REGS_BASE       (0xfffe2300)
+#define BCM_6348_DSL_BASE              (0xfffe3000)
+#define BCM_6348_ENET0_BASE            (0xfffe6000)
+#define BCM_6348_ENET1_BASE            (0xfffe6800)
+#define BCM_6348_ENETDMA_BASE          (0xfffe7000)
+#define BCM_6348_EHCI0_BASE            (0xdeadbeef)
+#define BCM_6348_SDRAM_BASE            (0xfffe2300)
+#define BCM_6348_MEMC_BASE             (0xdeadbeef)
+#define BCM_6348_DDR_BASE              (0xdeadbeef)
+
+/*
+ * 6358 register sets base address
+ */
+#define BCM_6358_DSL_LMEM_BASE         (0xfff00000)
+#define BCM_6358_PERF_BASE             (0xfffe0000)
+#define BCM_6358_TIMER_BASE            (0xfffe0040)
+#define BCM_6358_WDT_BASE              (0xfffe005c)
+#define BCM_6358_UART0_BASE            (0xfffe0100)
+#define BCM_6358_GPIO_BASE             (0xfffe0080)
+#define BCM_6358_SPI_BASE              (0xdeadbeef)
+#define BCM_6358_UDC0_BASE             (0xfffe0800)
+#define BCM_6358_OHCI0_BASE            (0xfffe1400)
+#define BCM_6358_OHCI_PRIV_BASE                (0xdeadbeef)
+#define BCM_6358_USBH_PRIV_BASE                (0xfffe1500)
+#define BCM_6358_MPI_BASE              (0xfffe1000)
+#define BCM_6358_PCMCIA_BASE           (0xfffe1054)
+#define BCM_6358_SDRAM_REGS_BASE       (0xfffe2300)
+#define BCM_6358_DSL_BASE              (0xfffe3000)
+#define BCM_6358_ENET0_BASE            (0xfffe4000)
+#define BCM_6358_ENET1_BASE            (0xfffe4800)
+#define BCM_6358_ENETDMA_BASE          (0xfffe5000)
+#define BCM_6358_EHCI0_BASE            (0xfffe1300)
+#define BCM_6358_SDRAM_BASE            (0xdeadbeef)
+#define BCM_6358_MEMC_BASE             (0xfffe1200)
+#define BCM_6358_DDR_BASE              (0xfffe12a0)
+
+
+extern const unsigned long *bcm63xx_regs_base;
+
+static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
+{
+#ifdef BCMCPU_RUNTIME_DETECT
+       return bcm63xx_regs_base[set];
+#else
+#ifdef CONFIG_BCM63XX_CPU_6338
+       switch (set) {
+       case RSET_DSL_LMEM:
+               return BCM_6338_DSL_LMEM_BASE;
+       case RSET_PERF:
+               return BCM_6338_PERF_BASE;
+       case RSET_TIMER:
+               return BCM_6338_TIMER_BASE;
+       case RSET_WDT:
+               return BCM_6338_WDT_BASE;
+       case RSET_UART0:
+               return BCM_6338_UART0_BASE;
+       case RSET_GPIO:
+               return BCM_6338_GPIO_BASE;
+       case RSET_SPI:
+               return BCM_6338_SPI_BASE;
+       case RSET_UDC0:
+               return BCM_6338_UDC0_BASE;
+       case RSET_OHCI0:
+               return BCM_6338_OHCI0_BASE;
+       case RSET_OHCI_PRIV:
+               return BCM_6338_OHCI_PRIV_BASE;
+       case RSET_USBH_PRIV:
+               return BCM_6338_USBH_PRIV_BASE;
+       case RSET_MPI:
+               return BCM_6338_MPI_BASE;
+       case RSET_PCMCIA:
+               return BCM_6338_PCMCIA_BASE;
+       case RSET_DSL:
+               return BCM_6338_DSL_BASE;
+       case RSET_ENET0:
+               return BCM_6338_ENET0_BASE;
+       case RSET_ENET1:
+               return BCM_6338_ENET1_BASE;
+       case RSET_ENETDMA:
+               return BCM_6338_ENETDMA_BASE;
+       case RSET_EHCI0:
+               return BCM_6338_EHCI0_BASE;
+       case RSET_SDRAM:
+               return BCM_6338_SDRAM_BASE;
+       case RSET_MEMC:
+               return BCM_6338_MEMC_BASE;
+       case RSET_DDR:
+               return BCM_6338_DDR_BASE;
+       }
+#endif
+#ifdef CONFIG_BCM63XX_CPU_6345
+       switch (set) {
+       case RSET_DSL_LMEM:
+               return BCM_6345_DSL_LMEM_BASE;
+       case RSET_PERF:
+               return BCM_6345_PERF_BASE;
+       case RSET_TIMER:
+               return BCM_6345_TIMER_BASE;
+       case RSET_WDT:
+               return BCM_6345_WDT_BASE;
+       case RSET_UART0:
+               return BCM_6345_UART0_BASE;
+       case RSET_GPIO:
+               return BCM_6345_GPIO_BASE;
+       case RSET_SPI:
+               return BCM_6345_SPI_BASE;
+       case RSET_UDC0:
+               return BCM_6345_UDC0_BASE;
+       case RSET_OHCI0:
+               return BCM_6345_OHCI0_BASE;
+       case RSET_OHCI_PRIV:
+               return BCM_6345_OHCI_PRIV_BASE;
+       case RSET_USBH_PRIV:
+               return BCM_6345_USBH_PRIV_BASE;
+       case RSET_MPI:
+               return BCM_6345_MPI_BASE;
+       case RSET_PCMCIA:
+               return BCM_6345_PCMCIA_BASE;
+       case RSET_DSL:
+               return BCM_6345_DSL_BASE;
+       case RSET_ENET0:
+               return BCM_6345_ENET0_BASE;
+       case RSET_ENET1:
+               return BCM_6345_ENET1_BASE;
+       case RSET_ENETDMA:
+               return BCM_6345_ENETDMA_BASE;
+       case RSET_EHCI0:
+               return BCM_6345_EHCI0_BASE;
+       case RSET_SDRAM:
+               return BCM_6345_SDRAM_BASE;
+       case RSET_MEMC:
+               return BCM_6345_MEMC_BASE;
+       case RSET_DDR:
+               return BCM_6345_DDR_BASE;
+       }
+#endif
+#ifdef CONFIG_BCM63XX_CPU_6348
+       switch (set) {
+       case RSET_DSL_LMEM:
+               return BCM_6348_DSL_LMEM_BASE;
+       case RSET_PERF:
+               return BCM_6348_PERF_BASE;
+       case RSET_TIMER:
+               return BCM_6348_TIMER_BASE;
+       case RSET_WDT:
+               return BCM_6348_WDT_BASE;
+       case RSET_UART0:
+               return BCM_6348_UART0_BASE;
+       case RSET_GPIO:
+               return BCM_6348_GPIO_BASE;
+       case RSET_SPI:
+               return BCM_6348_SPI_BASE;
+       case RSET_UDC0:
+               return BCM_6348_UDC0_BASE;
+       case RSET_OHCI0:
+               return BCM_6348_OHCI0_BASE;
+       case RSET_OHCI_PRIV:
+               return BCM_6348_OHCI_PRIV_BASE;
+       case RSET_USBH_PRIV:
+               return BCM_6348_USBH_PRIV_BASE;
+       case RSET_MPI:
+               return BCM_6348_MPI_BASE;
+       case RSET_PCMCIA:
+               return BCM_6348_PCMCIA_BASE;
+       case RSET_DSL:
+               return BCM_6348_DSL_BASE;
+       case RSET_ENET0:
+               return BCM_6348_ENET0_BASE;
+       case RSET_ENET1:
+               return BCM_6348_ENET1_BASE;
+       case RSET_ENETDMA:
+               return BCM_6348_ENETDMA_BASE;
+       case RSET_EHCI0:
+               return BCM_6348_EHCI0_BASE;
+       case RSET_SDRAM:
+               return BCM_6348_SDRAM_BASE;
+       case RSET_MEMC:
+               return BCM_6348_MEMC_BASE;
+       case RSET_DDR:
+               return BCM_6348_DDR_BASE;
+       }
+#endif
+#ifdef CONFIG_BCM63XX_CPU_6358
+       switch (set) {
+       case RSET_DSL_LMEM:
+               return BCM_6358_DSL_LMEM_BASE;
+       case RSET_PERF:
+               return BCM_6358_PERF_BASE;
+       case RSET_TIMER:
+               return BCM_6358_TIMER_BASE;
+       case RSET_WDT:
+               return BCM_6358_WDT_BASE;
+       case RSET_UART0:
+               return BCM_6358_UART0_BASE;
+       case RSET_GPIO:
+               return BCM_6358_GPIO_BASE;
+       case RSET_SPI:
+               return BCM_6358_SPI_BASE;
+       case RSET_UDC0:
+               return BCM_6358_UDC0_BASE;
+       case RSET_OHCI0:
+               return BCM_6358_OHCI0_BASE;
+       case RSET_OHCI_PRIV:
+               return BCM_6358_OHCI_PRIV_BASE;
+       case RSET_USBH_PRIV:
+               return BCM_6358_USBH_PRIV_BASE;
+       case RSET_MPI:
+               return BCM_6358_MPI_BASE;
+       case RSET_PCMCIA:
+               return BCM_6358_PCMCIA_BASE;
+       case RSET_ENET0:
+               return BCM_6358_ENET0_BASE;
+       case RSET_ENET1:
+               return BCM_6358_ENET1_BASE;
+       case RSET_ENETDMA:
+               return BCM_6358_ENETDMA_BASE;
+       case RSET_DSL:
+               return BCM_6358_DSL_BASE;
+       case RSET_EHCI0:
+               return BCM_6358_EHCI0_BASE;
+       case RSET_SDRAM:
+               return BCM_6358_SDRAM_BASE;
+       case RSET_MEMC:
+               return BCM_6358_MEMC_BASE;
+       case RSET_DDR:
+               return BCM_6358_DDR_BASE;
+       }
+#endif
+#endif
+       /* unreached */
+       return 0;
+}
+
+/*
+ * IRQ number changes across CPU too
+ */
+enum bcm63xx_irq {
+       IRQ_TIMER = 0,
+       IRQ_UART0,
+       IRQ_DSL,
+       IRQ_ENET0,
+       IRQ_ENET1,
+       IRQ_ENET_PHY,
+       IRQ_OHCI0,
+       IRQ_EHCI0,
+       IRQ_PCMCIA0,
+       IRQ_ENET0_RXDMA,
+       IRQ_ENET0_TXDMA,
+       IRQ_ENET1_RXDMA,
+       IRQ_ENET1_TXDMA,
+       IRQ_PCI,
+       IRQ_PCMCIA,
+};
+
+/*
+ * 6338 irqs
+ */
+#define BCM_6338_TIMER_IRQ             (IRQ_INTERNAL_BASE + 0)
+#define BCM_6338_SPI_IRQ               (IRQ_INTERNAL_BASE + 1)
+#define BCM_6338_UART0_IRQ             (IRQ_INTERNAL_BASE + 2)
+#define BCM_6338_DG_IRQ                        (IRQ_INTERNAL_BASE + 4)
+#define BCM_6338_DSL_IRQ               (IRQ_INTERNAL_BASE + 5)
+#define BCM_6338_ATM_IRQ               (IRQ_INTERNAL_BASE + 6)
+#define BCM_6338_UDC0_IRQ              (IRQ_INTERNAL_BASE + 7)
+#define BCM_6338_ENET0_IRQ             (IRQ_INTERNAL_BASE + 8)
+#define BCM_6338_ENET_PHY_IRQ          (IRQ_INTERNAL_BASE + 9)
+#define BCM_6338_SDRAM_IRQ             (IRQ_INTERNAL_BASE + 10)
+#define BCM_6338_USB_CNTL_RX_DMA_IRQ   (IRQ_INTERNAL_BASE + 11)
+#define BCM_6338_USB_CNTL_TX_DMA_IRQ   (IRQ_INTERNAL_BASE + 12)
+#define BCM_6338_USB_BULK_RX_DMA_IRQ   (IRQ_INTERNAL_BASE + 13)
+#define BCM_6338_USB_BULK_TX_DMA_IRQ   (IRQ_INTERNAL_BASE + 14)
+#define BCM_6338_ENET0_RXDMA_IRQ       (IRQ_INTERNAL_BASE + 15)
+#define BCM_6338_ENET0_TXDMA_IRQ       (IRQ_INTERNAL_BASE + 16)
+#define BCM_6338_SDIO_IRQ              (IRQ_INTERNAL_BASE + 17)
+
+/*
+ * 6345 irqs
+ */
+#define BCM_6345_TIMER_IRQ             (IRQ_INTERNAL_BASE + 0)
+#define BCM_6345_UART0_IRQ             (IRQ_INTERNAL_BASE + 2)
+#define BCM_6345_DSL_IRQ               (IRQ_INTERNAL_BASE + 3)
+#define BCM_6345_ATM_IRQ               (IRQ_INTERNAL_BASE + 4)
+#define BCM_6345_USB_IRQ               (IRQ_INTERNAL_BASE + 5)
+#define BCM_6345_ENET0_IRQ             (IRQ_INTERNAL_BASE + 8)
+#define BCM_6345_ENET_PHY_IRQ          (IRQ_INTERNAL_BASE + 12)
+#define BCM_6345_ENET0_RXDMA_IRQ       (IRQ_INTERNAL_BASE + 13 + 1)
+#define BCM_6345_ENET0_TXDMA_IRQ       (IRQ_INTERNAL_BASE + 13 + 2)
+#define BCM_6345_EBI_RX_IRQ            (IRQ_INTERNAL_BASE + 13 + 5)
+#define BCM_6345_EBI_TX_IRQ            (IRQ_INTERNAL_BASE + 13 + 6)
+#define BCM_6345_RESERVED_RX_IRQ       (IRQ_INTERNAL_BASE + 13 + 9)
+#define BCM_6345_RESERVED_TX_IRQ       (IRQ_INTERNAL_BASE + 13 + 10)
+#define BCM_6345_USB_BULK_RX_DMA_IRQ   (IRQ_INTERNAL_BASE + 13 + 13)
+#define BCM_6345_USB_BULK_TX_DMA_IRQ   (IRQ_INTERNAL_BASE + 13 + 14)
+#define BCM_6345_USB_CNTL_RX_DMA_IRQ   (IRQ_INTERNAL_BASE + 13 + 15)
+#define BCM_6345_USB_CNTL_TX_DMA_IRQ   (IRQ_INTERNAL_BASE + 13 + 16)
+#define BCM_6345_USB_ISO_RX_DMA_IRQ    (IRQ_INTERNAL_BASE + 13 + 17)
+#define BCM_6345_USB_ISO_TX_DMA_IRQ    (IRQ_INTERNAL_BASE + 13 + 18)
+
+/*
+ * 6348 irqs
+ */
+#define BCM_6348_TIMER_IRQ             (IRQ_INTERNAL_BASE + 0)
+#define BCM_6348_UART0_IRQ             (IRQ_INTERNAL_BASE + 2)
+#define BCM_6348_DSL_IRQ               (IRQ_INTERNAL_BASE + 4)
+#define BCM_6348_ENET1_IRQ             (IRQ_INTERNAL_BASE + 7)
+#define BCM_6348_ENET0_IRQ             (IRQ_INTERNAL_BASE + 8)
+#define BCM_6348_ENET_PHY_IRQ          (IRQ_INTERNAL_BASE + 9)
+#define BCM_6348_OHCI0_IRQ             (IRQ_INTERNAL_BASE + 12)
+#define BCM_6348_ENET0_RXDMA_IRQ       (IRQ_INTERNAL_BASE + 20)
+#define BCM_6348_ENET0_TXDMA_IRQ       (IRQ_INTERNAL_BASE + 21)
+#define BCM_6348_ENET1_RXDMA_IRQ       (IRQ_INTERNAL_BASE + 22)
+#define BCM_6348_ENET1_TXDMA_IRQ       (IRQ_INTERNAL_BASE + 23)
+#define BCM_6348_PCMCIA_IRQ            (IRQ_INTERNAL_BASE + 24)
+#define BCM_6348_PCI_IRQ               (IRQ_INTERNAL_BASE + 24)
+
+/*
+ * 6358 irqs
+ */
+#define BCM_6358_TIMER_IRQ             (IRQ_INTERNAL_BASE + 0)
+#define BCM_6358_UART0_IRQ             (IRQ_INTERNAL_BASE + 2)
+#define BCM_6358_OHCI0_IRQ             (IRQ_INTERNAL_BASE + 5)
+#define BCM_6358_ENET1_IRQ             (IRQ_INTERNAL_BASE + 6)
+#define BCM_6358_ENET0_IRQ             (IRQ_INTERNAL_BASE + 8)
+#define BCM_6358_ENET_PHY_IRQ          (IRQ_INTERNAL_BASE + 9)
+#define BCM_6358_EHCI0_IRQ             (IRQ_INTERNAL_BASE + 10)
+#define BCM_6358_ENET0_RXDMA_IRQ       (IRQ_INTERNAL_BASE + 15)
+#define BCM_6358_ENET0_TXDMA_IRQ       (IRQ_INTERNAL_BASE + 16)
+#define BCM_6358_ENET1_RXDMA_IRQ       (IRQ_INTERNAL_BASE + 17)
+#define BCM_6358_ENET1_TXDMA_IRQ       (IRQ_INTERNAL_BASE + 18)
+#define BCM_6358_DSL_IRQ               (IRQ_INTERNAL_BASE + 29)
+#define BCM_6358_PCI_IRQ               (IRQ_INTERNAL_BASE + 31)
+#define BCM_6358_PCMCIA_IRQ            (IRQ_INTERNAL_BASE + 24)
+
+extern const int *bcm63xx_irqs;
+
+static inline int bcm63xx_get_irq_number(enum bcm63xx_irq irq)
+{
+       return bcm63xx_irqs[irq];
+}
+
+/*
+ * return installed memory size
+ */
+unsigned int bcm63xx_get_memory_size(void);
+
+#endif /* !BCM63XX_CPU_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cs.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cs.h
new file mode 100644 (file)
index 0000000..b1821c8
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef BCM63XX_CS_H
+#define BCM63XX_CS_H
+
+int bcm63xx_set_cs_base(unsigned int cs, u32 base, unsigned int size);
+int bcm63xx_set_cs_timing(unsigned int cs, unsigned int wait,
+                          unsigned int setup, unsigned int hold);
+int bcm63xx_set_cs_param(unsigned int cs, u32 flags);
+int bcm63xx_set_cs_status(unsigned int cs, int enable);
+
+#endif /* !BCM63XX_CS_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_dsp.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_dsp.h
new file mode 100644 (file)
index 0000000..b587d45
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef __BCM63XX_DSP_H
+#define __BCM63XX_DSP_H
+
+struct bcm63xx_dsp_platform_data {
+       unsigned gpio_rst;
+       unsigned gpio_int;
+       unsigned cs;
+       unsigned ext_irq;
+};
+
+int __init bcm63xx_dsp_register(const struct bcm63xx_dsp_platform_data *pd);
+
+#endif /* __BCM63XX_DSP_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h
new file mode 100644 (file)
index 0000000..d53f611
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef BCM63XX_DEV_ENET_H_
+#define BCM63XX_DEV_ENET_H_
+
+#include <linux/if_ether.h>
+#include <linux/init.h>
+
+/*
+ * on board ethernet platform data
+ */
+struct bcm63xx_enet_platform_data {
+       char mac_addr[ETH_ALEN];
+
+       int has_phy;
+
+       /* if has_phy, then set use_internal_phy */
+       int use_internal_phy;
+
+       /* or fill phy info to use an external one */
+       int phy_id;
+       int has_phy_interrupt;
+       int phy_interrupt;
+
+       /* if has_phy, use autonegociated pause parameters or force
+        * them */
+       int pause_auto;
+       int pause_rx;
+       int pause_tx;
+
+       /* if !has_phy, set desired forced speed/duplex */
+       int force_speed_100;
+       int force_duplex_full;
+
+       /* if !has_phy, set callback to perform mii device
+        * init/remove */
+       int (*mii_config)(struct net_device *dev, int probe,
+                         int (*mii_read)(struct net_device *dev,
+                                         int phy_id, int reg),
+                         void (*mii_write)(struct net_device *dev,
+                                           int phy_id, int reg, int val));
+};
+
+int __init bcm63xx_enet_register(int unit,
+                                const struct bcm63xx_enet_platform_data *pd);
+
+#endif /* ! BCM63XX_DEV_ENET_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_pci.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_pci.h
new file mode 100644 (file)
index 0000000..c549344
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef BCM63XX_DEV_PCI_H_
+#define BCM63XX_DEV_PCI_H_
+
+extern int bcm63xx_pci_enabled;
+
+#endif /* BCM63XX_DEV_PCI_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
new file mode 100644 (file)
index 0000000..76a0b72
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef BCM63XX_GPIO_H
+#define BCM63XX_GPIO_H
+
+#include <linux/init.h>
+
+int __init bcm63xx_gpio_init(void);
+
+static inline unsigned long bcm63xx_gpio_count(void)
+{
+       switch (bcm63xx_get_cpu_id()) {
+       case BCM6358_CPU_ID:
+               return 40;
+       case BCM6348_CPU_ID:
+       default:
+               return 37;
+       }
+}
+
+#define GPIO_DIR_OUT   0x0
+#define GPIO_DIR_IN    0x1
+
+#endif /* !BCM63XX_GPIO_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h
new file mode 100644 (file)
index 0000000..91180fa
--- /dev/null
@@ -0,0 +1,93 @@
+#ifndef BCM63XX_IO_H_
+#define BCM63XX_IO_H_
+
+#include "bcm63xx_cpu.h"
+
+/*
+ * Physical memory map, RAM is mapped at 0x0.
+ *
+ * Note that size MUST be a power of two.
+ */
+#define BCM_PCMCIA_COMMON_BASE_PA      (0x20000000)
+#define BCM_PCMCIA_COMMON_SIZE         (16 * 1024 * 1024)
+#define BCM_PCMCIA_COMMON_END_PA       (BCM_PCMCIA_COMMON_BASE_PA +    \
+                                        BCM_PCMCIA_COMMON_SIZE - 1)
+
+#define BCM_PCMCIA_ATTR_BASE_PA                (0x21000000)
+#define BCM_PCMCIA_ATTR_SIZE           (16 * 1024 * 1024)
+#define BCM_PCMCIA_ATTR_END_PA         (BCM_PCMCIA_ATTR_BASE_PA +      \
+                                        BCM_PCMCIA_ATTR_SIZE - 1)
+
+#define BCM_PCMCIA_IO_BASE_PA          (0x22000000)
+#define BCM_PCMCIA_IO_SIZE             (64 * 1024)
+#define BCM_PCMCIA_IO_END_PA           (BCM_PCMCIA_IO_BASE_PA +        \
+                                       BCM_PCMCIA_IO_SIZE - 1)
+
+#define BCM_PCI_MEM_BASE_PA            (0x30000000)
+#define BCM_PCI_MEM_SIZE               (128 * 1024 * 1024)
+#define BCM_PCI_MEM_END_PA             (BCM_PCI_MEM_BASE_PA +          \
+                                       BCM_PCI_MEM_SIZE - 1)
+
+#define BCM_PCI_IO_BASE_PA             (0x08000000)
+#define BCM_PCI_IO_SIZE                        (64 * 1024)
+#define BCM_PCI_IO_END_PA              (BCM_PCI_IO_BASE_PA +           \
+                                       BCM_PCI_IO_SIZE - 1)
+#define BCM_PCI_IO_HALF_PA             (BCM_PCI_IO_BASE_PA +           \
+                                       (BCM_PCI_IO_SIZE / 2) - 1)
+
+#define BCM_CB_MEM_BASE_PA             (0x38000000)
+#define BCM_CB_MEM_SIZE                        (128 * 1024 * 1024)
+#define BCM_CB_MEM_END_PA              (BCM_CB_MEM_BASE_PA +           \
+                                       BCM_CB_MEM_SIZE - 1)
+
+
+/*
+ * Internal registers are accessed through KSEG3
+ */
+#define BCM_REGS_VA(x) ((void __iomem *)(x))
+
+#define bcm_readb(a)   (*(volatile unsigned char *)    BCM_REGS_VA(a))
+#define bcm_readw(a)   (*(volatile unsigned short *)   BCM_REGS_VA(a))
+#define bcm_readl(a)   (*(volatile unsigned int *)     BCM_REGS_VA(a))
+#define bcm_writeb(v, a) (*(volatile unsigned char *) BCM_REGS_VA((a)) = (v))
+#define bcm_writew(v, a) (*(volatile unsigned short *) BCM_REGS_VA((a)) = (v))
+#define bcm_writel(v, a) (*(volatile unsigned int *) BCM_REGS_VA((a)) = (v))
+
+/*
+ * IO helpers to access register set for current CPU
+ */
+#define bcm_rset_readb(s, o)   bcm_readb(bcm63xx_regset_address(s) + (o))
+#define bcm_rset_readw(s, o)   bcm_readw(bcm63xx_regset_address(s) + (o))
+#define bcm_rset_readl(s, o)   bcm_readl(bcm63xx_regset_address(s) + (o))
+#define bcm_rset_writeb(s, v, o)       bcm_writeb((v), \
+                                       bcm63xx_regset_address(s) + (o))
+#define bcm_rset_writew(s, v, o)       bcm_writew((v), \
+                                       bcm63xx_regset_address(s) + (o))
+#define bcm_rset_writel(s, v, o)       bcm_writel((v), \
+                                       bcm63xx_regset_address(s) + (o))
+
+/*
+ * helpers for frequently used register sets
+ */
+#define bcm_perf_readl(o)      bcm_rset_readl(RSET_PERF, (o))
+#define bcm_perf_writel(v, o)  bcm_rset_writel(RSET_PERF, (v), (o))
+#define bcm_timer_readl(o)     bcm_rset_readl(RSET_TIMER, (o))
+#define bcm_timer_writel(v, o) bcm_rset_writel(RSET_TIMER, (v), (o))
+#define bcm_wdt_readl(o)       bcm_rset_readl(RSET_WDT, (o))
+#define bcm_wdt_writel(v, o)   bcm_rset_writel(RSET_WDT, (v), (o))
+#define bcm_gpio_readl(o)      bcm_rset_readl(RSET_GPIO, (o))
+#define bcm_gpio_writel(v, o)  bcm_rset_writel(RSET_GPIO, (v), (o))
+#define bcm_uart0_readl(o)     bcm_rset_readl(RSET_UART0, (o))
+#define bcm_uart0_writel(v, o) bcm_rset_writel(RSET_UART0, (v), (o))
+#define bcm_mpi_readl(o)       bcm_rset_readl(RSET_MPI, (o))
+#define bcm_mpi_writel(v, o)   bcm_rset_writel(RSET_MPI, (v), (o))
+#define bcm_pcmcia_readl(o)    bcm_rset_readl(RSET_PCMCIA, (o))
+#define bcm_pcmcia_writel(v, o)        bcm_rset_writel(RSET_PCMCIA, (v), (o))
+#define bcm_sdram_readl(o)     bcm_rset_readl(RSET_SDRAM, (o))
+#define bcm_sdram_writel(v, o) bcm_rset_writel(RSET_SDRAM, (v), (o))
+#define bcm_memc_readl(o)      bcm_rset_readl(RSET_MEMC, (o))
+#define bcm_memc_writel(v, o)  bcm_rset_writel(RSET_MEMC, (v), (o))
+#define bcm_ddr_readl(o)       bcm_rset_readl(RSET_DDR, (o))
+#define bcm_ddr_writel(v, o)   bcm_rset_writel(RSET_DDR, (v), (o))
+
+#endif /* ! BCM63XX_IO_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_irq.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_irq.h
new file mode 100644 (file)
index 0000000..5f95577
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef BCM63XX_IRQ_H_
+#define BCM63XX_IRQ_H_
+
+#include <bcm63xx_cpu.h>
+
+#define IRQ_MIPS_BASE                  0
+#define IRQ_INTERNAL_BASE              8
+
+#define IRQ_EXT_BASE                   (IRQ_MIPS_BASE + 3)
+#define IRQ_EXT_0                      (IRQ_EXT_BASE + 0)
+#define IRQ_EXT_1                      (IRQ_EXT_BASE + 1)
+#define IRQ_EXT_2                      (IRQ_EXT_BASE + 2)
+#define IRQ_EXT_3                      (IRQ_EXT_BASE + 3)
+
+#endif /* ! BCM63XX_IRQ_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
new file mode 100644 (file)
index 0000000..ed4ccec
--- /dev/null
@@ -0,0 +1,773 @@
+#ifndef BCM63XX_REGS_H_
+#define BCM63XX_REGS_H_
+
+/*************************************************************************
+ * _REG relative to RSET_PERF
+ *************************************************************************/
+
+/* Chip Identifier / Revision register */
+#define PERF_REV_REG                   0x0
+#define REV_CHIPID_SHIFT               16
+#define REV_CHIPID_MASK                        (0xffff << REV_CHIPID_SHIFT)
+#define REV_REVID_SHIFT                        0
+#define REV_REVID_MASK                 (0xffff << REV_REVID_SHIFT)
+
+/* Clock Control register */
+#define PERF_CKCTL_REG                 0x4
+
+#define CKCTL_6338_ADSLPHY_EN          (1 << 0)
+#define CKCTL_6338_MPI_EN              (1 << 1)
+#define CKCTL_6338_DRAM_EN             (1 << 2)
+#define CKCTL_6338_ENET_EN             (1 << 4)
+#define CKCTL_6338_USBS_EN             (1 << 4)
+#define CKCTL_6338_SAR_EN              (1 << 5)
+#define CKCTL_6338_SPI_EN              (1 << 9)
+
+#define CKCTL_6338_ALL_SAFE_EN         (CKCTL_6338_ADSLPHY_EN |        \
+                                       CKCTL_6338_MPI_EN |             \
+                                       CKCTL_6338_ENET_EN |            \
+                                       CKCTL_6338_SAR_EN |             \
+                                       CKCTL_6338_SPI_EN)
+
+#define CKCTL_6345_CPU_EN              (1 << 0)
+#define CKCTL_6345_BUS_EN              (1 << 1)
+#define CKCTL_6345_EBI_EN              (1 << 2)
+#define CKCTL_6345_UART_EN             (1 << 3)
+#define CKCTL_6345_ADSLPHY_EN          (1 << 4)
+#define CKCTL_6345_ENET_EN             (1 << 7)
+#define CKCTL_6345_USBH_EN             (1 << 8)
+
+#define CKCTL_6345_ALL_SAFE_EN         (CKCTL_6345_ENET_EN |   \
+                                       CKCTL_6345_USBH_EN |    \
+                                       CKCTL_6345_ADSLPHY_EN)
+
+#define CKCTL_6348_ADSLPHY_EN          (1 << 0)
+#define CKCTL_6348_MPI_EN              (1 << 1)
+#define CKCTL_6348_SDRAM_EN            (1 << 2)
+#define CKCTL_6348_M2M_EN              (1 << 3)
+#define CKCTL_6348_ENET_EN             (1 << 4)
+#define CKCTL_6348_SAR_EN              (1 << 5)
+#define CKCTL_6348_USBS_EN             (1 << 6)
+#define CKCTL_6348_USBH_EN             (1 << 8)
+#define CKCTL_6348_SPI_EN              (1 << 9)
+
+#define CKCTL_6348_ALL_SAFE_EN         (CKCTL_6348_ADSLPHY_EN |        \
+                                       CKCTL_6348_M2M_EN |             \
+                                       CKCTL_6348_ENET_EN |            \
+                                       CKCTL_6348_SAR_EN |             \
+                                       CKCTL_6348_USBS_EN |            \
+                                       CKCTL_6348_USBH_EN |            \
+                                       CKCTL_6348_SPI_EN)
+
+#define CKCTL_6358_ENET_EN             (1 << 4)
+#define CKCTL_6358_ADSLPHY_EN          (1 << 5)
+#define CKCTL_6358_PCM_EN              (1 << 8)
+#define CKCTL_6358_SPI_EN              (1 << 9)
+#define CKCTL_6358_USBS_EN             (1 << 10)
+#define CKCTL_6358_SAR_EN              (1 << 11)
+#define CKCTL_6358_EMUSB_EN            (1 << 17)
+#define CKCTL_6358_ENET0_EN            (1 << 18)
+#define CKCTL_6358_ENET1_EN            (1 << 19)
+#define CKCTL_6358_USBSU_EN            (1 << 20)
+#define CKCTL_6358_EPHY_EN             (1 << 21)
+
+#define CKCTL_6358_ALL_SAFE_EN         (CKCTL_6358_ENET_EN |           \
+                                       CKCTL_6358_ADSLPHY_EN |         \
+                                       CKCTL_6358_PCM_EN |             \
+                                       CKCTL_6358_SPI_EN |             \
+                                       CKCTL_6358_USBS_EN |            \
+                                       CKCTL_6358_SAR_EN |             \
+                                       CKCTL_6358_EMUSB_EN |           \
+                                       CKCTL_6358_ENET0_EN |           \
+                                       CKCTL_6358_ENET1_EN |           \
+                                       CKCTL_6358_USBSU_EN |           \
+                                       CKCTL_6358_EPHY_EN)
+
+/* System PLL Control register  */
+#define PERF_SYS_PLL_CTL_REG           0x8
+#define SYS_PLL_SOFT_RESET             0x1
+
+/* Interrupt Mask register */
+#define PERF_IRQMASK_REG               0xc
+#define PERF_IRQSTAT_REG               0x10
+
+/* Interrupt Status register */
+#define PERF_IRQSTAT_REG               0x10
+
+/* External Interrupt Configuration register */
+#define PERF_EXTIRQ_CFG_REG            0x14
+#define EXTIRQ_CFG_SENSE(x)            (1 << (x))
+#define EXTIRQ_CFG_STAT(x)             (1 << (x + 5))
+#define EXTIRQ_CFG_CLEAR(x)            (1 << (x + 10))
+#define EXTIRQ_CFG_MASK(x)             (1 << (x + 15))
+#define EXTIRQ_CFG_BOTHEDGE(x)         (1 << (x + 20))
+#define EXTIRQ_CFG_LEVELSENSE(x)       (1 << (x + 25))
+
+#define EXTIRQ_CFG_CLEAR_ALL           (0xf << 10)
+#define EXTIRQ_CFG_MASK_ALL            (0xf << 15)
+
+/* Soft Reset register */
+#define PERF_SOFTRESET_REG             0x28
+
+#define SOFTRESET_6338_SPI_MASK                (1 << 0)
+#define SOFTRESET_6338_ENET_MASK       (1 << 2)
+#define SOFTRESET_6338_USBH_MASK       (1 << 3)
+#define SOFTRESET_6338_USBS_MASK       (1 << 4)
+#define SOFTRESET_6338_ADSL_MASK       (1 << 5)
+#define SOFTRESET_6338_DMAMEM_MASK     (1 << 6)
+#define SOFTRESET_6338_SAR_MASK                (1 << 7)
+#define SOFTRESET_6338_ACLC_MASK       (1 << 8)
+#define SOFTRESET_6338_ADSLMIPSPLL_MASK        (1 << 10)
+#define SOFTRESET_6338_ALL      (SOFTRESET_6338_SPI_MASK |             \
+                                 SOFTRESET_6338_ENET_MASK |            \
+                                 SOFTRESET_6338_USBH_MASK |            \
+                                 SOFTRESET_6338_USBS_MASK |            \
+                                 SOFTRESET_6338_ADSL_MASK |            \
+                                 SOFTRESET_6338_DMAMEM_MASK |          \
+                                 SOFTRESET_6338_SAR_MASK |             \
+                                 SOFTRESET_6338_ACLC_MASK |            \
+                                 SOFTRESET_6338_ADSLMIPSPLL_MASK)
+
+#define SOFTRESET_6348_SPI_MASK                (1 << 0)
+#define SOFTRESET_6348_ENET_MASK       (1 << 2)
+#define SOFTRESET_6348_USBH_MASK       (1 << 3)
+#define SOFTRESET_6348_USBS_MASK       (1 << 4)
+#define SOFTRESET_6348_ADSL_MASK       (1 << 5)
+#define SOFTRESET_6348_DMAMEM_MASK     (1 << 6)
+#define SOFTRESET_6348_SAR_MASK                (1 << 7)
+#define SOFTRESET_6348_ACLC_MASK       (1 << 8)
+#define SOFTRESET_6348_ADSLMIPSPLL_MASK        (1 << 10)
+
+#define SOFTRESET_6348_ALL      (SOFTRESET_6348_SPI_MASK |             \
+                                 SOFTRESET_6348_ENET_MASK |            \
+                                 SOFTRESET_6348_USBH_MASK |            \
+                                 SOFTRESET_6348_USBS_MASK |            \
+                                 SOFTRESET_6348_ADSL_MASK |            \
+                                 SOFTRESET_6348_DMAMEM_MASK |          \
+                                 SOFTRESET_6348_SAR_MASK |             \
+                                 SOFTRESET_6348_ACLC_MASK |            \
+                                 SOFTRESET_6348_ADSLMIPSPLL_MASK)
+
+/* MIPS PLL control register */
+#define PERF_MIPSPLLCTL_REG            0x34
+#define MIPSPLLCTL_N1_SHIFT            20
+#define MIPSPLLCTL_N1_MASK             (0x7 << MIPSPLLCTL_N1_SHIFT)
+#define MIPSPLLCTL_N2_SHIFT            15
+#define MIPSPLLCTL_N2_MASK             (0x1f << MIPSPLLCTL_N2_SHIFT)
+#define MIPSPLLCTL_M1REF_SHIFT         12
+#define MIPSPLLCTL_M1REF_MASK          (0x7 << MIPSPLLCTL_M1REF_SHIFT)
+#define MIPSPLLCTL_M2REF_SHIFT         9
+#define MIPSPLLCTL_M2REF_MASK          (0x7 << MIPSPLLCTL_M2REF_SHIFT)
+#define MIPSPLLCTL_M1CPU_SHIFT         6
+#define MIPSPLLCTL_M1CPU_MASK          (0x7 << MIPSPLLCTL_M1CPU_SHIFT)
+#define MIPSPLLCTL_M1BUS_SHIFT         3
+#define MIPSPLLCTL_M1BUS_MASK          (0x7 << MIPSPLLCTL_M1BUS_SHIFT)
+#define MIPSPLLCTL_M2BUS_SHIFT         0
+#define MIPSPLLCTL_M2BUS_MASK          (0x7 << MIPSPLLCTL_M2BUS_SHIFT)
+
+/* ADSL PHY PLL Control register */
+#define PERF_ADSLPLLCTL_REG            0x38
+#define ADSLPLLCTL_N1_SHIFT            20
+#define ADSLPLLCTL_N1_MASK             (0x7 << ADSLPLLCTL_N1_SHIFT)
+#define ADSLPLLCTL_N2_SHIFT            15
+#define ADSLPLLCTL_N2_MASK             (0x1f << ADSLPLLCTL_N2_SHIFT)
+#define ADSLPLLCTL_M1REF_SHIFT         12
+#define ADSLPLLCTL_M1REF_MASK          (0x7 << ADSLPLLCTL_M1REF_SHIFT)
+#define ADSLPLLCTL_M2REF_SHIFT         9
+#define ADSLPLLCTL_M2REF_MASK          (0x7 << ADSLPLLCTL_M2REF_SHIFT)
+#define ADSLPLLCTL_M1CPU_SHIFT         6
+#define ADSLPLLCTL_M1CPU_MASK          (0x7 << ADSLPLLCTL_M1CPU_SHIFT)
+#define ADSLPLLCTL_M1BUS_SHIFT         3
+#define ADSLPLLCTL_M1BUS_MASK          (0x7 << ADSLPLLCTL_M1BUS_SHIFT)
+#define ADSLPLLCTL_M2BUS_SHIFT         0
+#define ADSLPLLCTL_M2BUS_MASK          (0x7 << ADSLPLLCTL_M2BUS_SHIFT)
+
+#define ADSLPLLCTL_VAL(n1, n2, m1ref, m2ref, m1cpu, m1bus, m2bus)      \
+                               (((n1) << ADSLPLLCTL_N1_SHIFT) |        \
+                               ((n2) << ADSLPLLCTL_N2_SHIFT) |         \
+                               ((m1ref) << ADSLPLLCTL_M1REF_SHIFT) |   \
+                               ((m2ref) << ADSLPLLCTL_M2REF_SHIFT) |   \
+                               ((m1cpu) << ADSLPLLCTL_M1CPU_SHIFT) |   \
+                               ((m1bus) << ADSLPLLCTL_M1BUS_SHIFT) |   \
+                               ((m2bus) << ADSLPLLCTL_M2BUS_SHIFT))
+
+
+/*************************************************************************
+ * _REG relative to RSET_TIMER
+ *************************************************************************/
+
+#define BCM63XX_TIMER_COUNT            4
+#define TIMER_T0_ID                    0
+#define TIMER_T1_ID                    1
+#define TIMER_T2_ID                    2
+#define TIMER_WDT_ID                   3
+
+/* Timer irqstat register */
+#define TIMER_IRQSTAT_REG              0
+#define TIMER_IRQSTAT_TIMER_CAUSE(x)   (1 << (x))
+#define TIMER_IRQSTAT_TIMER0_CAUSE     (1 << 0)
+#define TIMER_IRQSTAT_TIMER1_CAUSE     (1 << 1)
+#define TIMER_IRQSTAT_TIMER2_CAUSE     (1 << 2)
+#define TIMER_IRQSTAT_WDT_CAUSE                (1 << 3)
+#define TIMER_IRQSTAT_TIMER_IR_EN(x)   (1 << ((x) + 8))
+#define TIMER_IRQSTAT_TIMER0_IR_EN     (1 << 8)
+#define TIMER_IRQSTAT_TIMER1_IR_EN     (1 << 9)
+#define TIMER_IRQSTAT_TIMER2_IR_EN     (1 << 10)
+
+/* Timer control register */
+#define TIMER_CTLx_REG(x)              (0x4 + (x * 4))
+#define TIMER_CTL0_REG                 0x4
+#define TIMER_CTL1_REG                 0x8
+#define TIMER_CTL2_REG                 0xC
+#define TIMER_CTL_COUNTDOWN_MASK       (0x3fffffff)
+#define TIMER_CTL_MONOTONIC_MASK       (1 << 30)
+#define TIMER_CTL_ENABLE_MASK          (1 << 31)
+
+
+/*************************************************************************
+ * _REG relative to RSET_WDT
+ *************************************************************************/
+
+/* Watchdog default count register */
+#define WDT_DEFVAL_REG                 0x0
+
+/* Watchdog control register */
+#define WDT_CTL_REG                    0x4
+
+/* Watchdog control register constants */
+#define WDT_START_1                    (0xff00)
+#define WDT_START_2                    (0x00ff)
+#define WDT_STOP_1                     (0xee00)
+#define WDT_STOP_2                     (0x00ee)
+
+/* Watchdog reset length register */
+#define WDT_RSTLEN_REG                 0x8
+
+
+/*************************************************************************
+ * _REG relative to RSET_UARTx
+ *************************************************************************/
+
+/* UART Control Register */
+#define UART_CTL_REG                   0x0
+#define UART_CTL_RXTMOUTCNT_SHIFT      0
+#define UART_CTL_RXTMOUTCNT_MASK       (0x1f << UART_CTL_RXTMOUTCNT_SHIFT)
+#define UART_CTL_RSTTXDN_SHIFT         5
+#define UART_CTL_RSTTXDN_MASK          (1 << UART_CTL_RSTTXDN_SHIFT)
+#define UART_CTL_RSTRXFIFO_SHIFT               6
+#define UART_CTL_RSTRXFIFO_MASK                (1 << UART_CTL_RSTRXFIFO_SHIFT)
+#define UART_CTL_RSTTXFIFO_SHIFT               7
+#define UART_CTL_RSTTXFIFO_MASK                (1 << UART_CTL_RSTTXFIFO_SHIFT)
+#define UART_CTL_STOPBITS_SHIFT                8
+#define UART_CTL_STOPBITS_MASK         (0xf << UART_CTL_STOPBITS_SHIFT)
+#define UART_CTL_STOPBITS_1            (0x7 << UART_CTL_STOPBITS_SHIFT)
+#define UART_CTL_STOPBITS_2            (0xf << UART_CTL_STOPBITS_SHIFT)
+#define UART_CTL_BITSPERSYM_SHIFT      12
+#define UART_CTL_BITSPERSYM_MASK       (0x3 << UART_CTL_BITSPERSYM_SHIFT)
+#define UART_CTL_XMITBRK_SHIFT         14
+#define UART_CTL_XMITBRK_MASK          (1 << UART_CTL_XMITBRK_SHIFT)
+#define UART_CTL_RSVD_SHIFT            15
+#define UART_CTL_RSVD_MASK             (1 << UART_CTL_RSVD_SHIFT)
+#define UART_CTL_RXPAREVEN_SHIFT               16
+#define UART_CTL_RXPAREVEN_MASK                (1 << UART_CTL_RXPAREVEN_SHIFT)
+#define UART_CTL_RXPAREN_SHIFT         17
+#define UART_CTL_RXPAREN_MASK          (1 << UART_CTL_RXPAREN_SHIFT)
+#define UART_CTL_TXPAREVEN_SHIFT               18
+#define UART_CTL_TXPAREVEN_MASK                (1 << UART_CTL_TXPAREVEN_SHIFT)
+#define UART_CTL_TXPAREN_SHIFT         18
+#define UART_CTL_TXPAREN_MASK          (1 << UART_CTL_TXPAREN_SHIFT)
+#define UART_CTL_LOOPBACK_SHIFT                20
+#define UART_CTL_LOOPBACK_MASK         (1 << UART_CTL_LOOPBACK_SHIFT)
+#define UART_CTL_RXEN_SHIFT            21
+#define UART_CTL_RXEN_MASK             (1 << UART_CTL_RXEN_SHIFT)
+#define UART_CTL_TXEN_SHIFT            22
+#define UART_CTL_TXEN_MASK             (1 << UART_CTL_TXEN_SHIFT)
+#define UART_CTL_BRGEN_SHIFT           23
+#define UART_CTL_BRGEN_MASK            (1 << UART_CTL_BRGEN_SHIFT)
+
+/* UART Baudword register */
+#define UART_BAUD_REG                  0x4
+
+/* UART Misc Control register */
+#define UART_MCTL_REG                  0x8
+#define UART_MCTL_DTR_SHIFT            0
+#define UART_MCTL_DTR_MASK             (1 << UART_MCTL_DTR_SHIFT)
+#define UART_MCTL_RTS_SHIFT            1
+#define UART_MCTL_RTS_MASK             (1 << UART_MCTL_RTS_SHIFT)
+#define UART_MCTL_RXFIFOTHRESH_SHIFT   8
+#define UART_MCTL_RXFIFOTHRESH_MASK    (0xf << UART_MCTL_RXFIFOTHRESH_SHIFT)
+#define UART_MCTL_TXFIFOTHRESH_SHIFT   12
+#define UART_MCTL_TXFIFOTHRESH_MASK    (0xf << UART_MCTL_TXFIFOTHRESH_SHIFT)
+#define UART_MCTL_RXFIFOFILL_SHIFT     16
+#define UART_MCTL_RXFIFOFILL_MASK      (0x1f << UART_MCTL_RXFIFOFILL_SHIFT)
+#define UART_MCTL_TXFIFOFILL_SHIFT     24
+#define UART_MCTL_TXFIFOFILL_MASK      (0x1f << UART_MCTL_TXFIFOFILL_SHIFT)
+
+/* UART External Input Configuration register */
+#define UART_EXTINP_REG                        0xc
+#define UART_EXTINP_RI_SHIFT           0
+#define UART_EXTINP_RI_MASK            (1 << UART_EXTINP_RI_SHIFT)
+#define UART_EXTINP_CTS_SHIFT          1
+#define UART_EXTINP_CTS_MASK           (1 << UART_EXTINP_CTS_SHIFT)
+#define UART_EXTINP_DCD_SHIFT          2
+#define UART_EXTINP_DCD_MASK           (1 << UART_EXTINP_DCD_SHIFT)
+#define UART_EXTINP_DSR_SHIFT          3
+#define UART_EXTINP_DSR_MASK           (1 << UART_EXTINP_DSR_SHIFT)
+#define UART_EXTINP_IRSTAT(x)          (1 << (x + 4))
+#define UART_EXTINP_IRMASK(x)          (1 << (x + 8))
+#define UART_EXTINP_IR_RI              0
+#define UART_EXTINP_IR_CTS             1
+#define UART_EXTINP_IR_DCD             2
+#define UART_EXTINP_IR_DSR             3
+#define UART_EXTINP_RI_NOSENSE_SHIFT   16
+#define UART_EXTINP_RI_NOSENSE_MASK    (1 << UART_EXTINP_RI_NOSENSE_SHIFT)
+#define UART_EXTINP_CTS_NOSENSE_SHIFT  17
+#define UART_EXTINP_CTS_NOSENSE_MASK   (1 << UART_EXTINP_CTS_NOSENSE_SHIFT)
+#define UART_EXTINP_DCD_NOSENSE_SHIFT  18
+#define UART_EXTINP_DCD_NOSENSE_MASK   (1 << UART_EXTINP_DCD_NOSENSE_SHIFT)
+#define UART_EXTINP_DSR_NOSENSE_SHIFT  19
+#define UART_EXTINP_DSR_NOSENSE_MASK   (1 << UART_EXTINP_DSR_NOSENSE_SHIFT)
+
+/* UART Interrupt register */
+#define UART_IR_REG                    0x10
+#define UART_IR_MASK(x)                        (1 << (x + 16))
+#define UART_IR_STAT(x)                        (1 << (x))
+#define UART_IR_EXTIP                  0
+#define UART_IR_TXUNDER                        1
+#define UART_IR_TXOVER                 2
+#define UART_IR_TXTRESH                        3
+#define UART_IR_TXRDLATCH              4
+#define UART_IR_TXEMPTY                        5
+#define UART_IR_RXUNDER                        6
+#define UART_IR_RXOVER                 7
+#define UART_IR_RXTIMEOUT              8
+#define UART_IR_RXFULL                 9
+#define UART_IR_RXTHRESH               10
+#define UART_IR_RXNOTEMPTY             11
+#define UART_IR_RXFRAMEERR             12
+#define UART_IR_RXPARERR               13
+#define UART_IR_RXBRK                  14
+#define UART_IR_TXDONE                 15
+
+/* UART Fifo register */
+#define UART_FIFO_REG                  0x14
+#define UART_FIFO_VALID_SHIFT          0
+#define UART_FIFO_VALID_MASK           0xff
+#define UART_FIFO_FRAMEERR_SHIFT       8
+#define UART_FIFO_FRAMEERR_MASK                (1 << UART_FIFO_FRAMEERR_SHIFT)
+#define UART_FIFO_PARERR_SHIFT         9
+#define UART_FIFO_PARERR_MASK          (1 << UART_FIFO_PARERR_SHIFT)
+#define UART_FIFO_BRKDET_SHIFT         10
+#define UART_FIFO_BRKDET_MASK          (1 << UART_FIFO_BRKDET_SHIFT)
+#define UART_FIFO_ANYERR_MASK          (UART_FIFO_FRAMEERR_MASK |      \
+                                       UART_FIFO_PARERR_MASK |         \
+                                       UART_FIFO_BRKDET_MASK)
+
+
+/*************************************************************************
+ * _REG relative to RSET_GPIO
+ *************************************************************************/
+
+/* GPIO registers */
+#define GPIO_CTL_HI_REG                        0x0
+#define GPIO_CTL_LO_REG                        0x4
+#define GPIO_DATA_HI_REG               0x8
+#define GPIO_DATA_LO_REG               0xC
+
+/* GPIO mux registers and constants */
+#define GPIO_MODE_REG                  0x18
+
+#define GPIO_MODE_6348_G4_DIAG         0x00090000
+#define GPIO_MODE_6348_G4_UTOPIA       0x00080000
+#define GPIO_MODE_6348_G4_LEGACY_LED   0x00030000
+#define GPIO_MODE_6348_G4_MII_SNOOP    0x00020000
+#define GPIO_MODE_6348_G4_EXT_EPHY     0x00010000
+#define GPIO_MODE_6348_G3_DIAG         0x00009000
+#define GPIO_MODE_6348_G3_UTOPIA       0x00008000
+#define GPIO_MODE_6348_G3_EXT_MII      0x00007000
+#define GPIO_MODE_6348_G2_DIAG         0x00000900
+#define GPIO_MODE_6348_G2_PCI          0x00000500
+#define GPIO_MODE_6348_G1_DIAG         0x00000090
+#define GPIO_MODE_6348_G1_UTOPIA       0x00000080
+#define GPIO_MODE_6348_G1_SPI_UART     0x00000060
+#define GPIO_MODE_6348_G1_SPI_MASTER   0x00000060
+#define GPIO_MODE_6348_G1_MII_PCCARD   0x00000040
+#define GPIO_MODE_6348_G1_MII_SNOOP    0x00000020
+#define GPIO_MODE_6348_G1_EXT_EPHY     0x00000010
+#define GPIO_MODE_6348_G0_DIAG         0x00000009
+#define GPIO_MODE_6348_G0_EXT_MII      0x00000007
+
+#define GPIO_MODE_6358_EXTRACS         (1 << 5)
+#define GPIO_MODE_6358_UART1           (1 << 6)
+#define GPIO_MODE_6358_EXTRA_SPI_SS    (1 << 7)
+#define GPIO_MODE_6358_SERIAL_LED      (1 << 10)
+#define GPIO_MODE_6358_UTOPIA          (1 << 12)
+
+
+/*************************************************************************
+ * _REG relative to RSET_ENET
+ *************************************************************************/
+
+/* Receiver Configuration register */
+#define ENET_RXCFG_REG                 0x0
+#define ENET_RXCFG_ALLMCAST_SHIFT      1
+#define ENET_RXCFG_ALLMCAST_MASK       (1 << ENET_RXCFG_ALLMCAST_SHIFT)
+#define ENET_RXCFG_PROMISC_SHIFT       3
+#define ENET_RXCFG_PROMISC_MASK                (1 << ENET_RXCFG_PROMISC_SHIFT)
+#define ENET_RXCFG_LOOPBACK_SHIFT      4
+#define ENET_RXCFG_LOOPBACK_MASK       (1 << ENET_RXCFG_LOOPBACK_SHIFT)
+#define ENET_RXCFG_ENFLOW_SHIFT                5
+#define ENET_RXCFG_ENFLOW_MASK         (1 << ENET_RXCFG_ENFLOW_SHIFT)
+
+/* Receive Maximum Length register */
+#define ENET_RXMAXLEN_REG              0x4
+#define ENET_RXMAXLEN_SHIFT            0
+#define ENET_RXMAXLEN_MASK             (0x7ff << ENET_RXMAXLEN_SHIFT)
+
+/* Transmit Maximum Length register */
+#define ENET_TXMAXLEN_REG              0x8
+#define ENET_TXMAXLEN_SHIFT            0
+#define ENET_TXMAXLEN_MASK             (0x7ff << ENET_TXMAXLEN_SHIFT)
+
+/* MII Status/Control register */
+#define ENET_MIISC_REG                 0x10
+#define ENET_MIISC_MDCFREQDIV_SHIFT    0
+#define ENET_MIISC_MDCFREQDIV_MASK     (0x7f << ENET_MIISC_MDCFREQDIV_SHIFT)
+#define ENET_MIISC_PREAMBLEEN_SHIFT    7
+#define ENET_MIISC_PREAMBLEEN_MASK     (1 << ENET_MIISC_PREAMBLEEN_SHIFT)
+
+/* MII Data register */
+#define ENET_MIIDATA_REG               0x14
+#define ENET_MIIDATA_DATA_SHIFT                0
+#define ENET_MIIDATA_DATA_MASK         (0xffff << ENET_MIIDATA_DATA_SHIFT)
+#define ENET_MIIDATA_TA_SHIFT          16
+#define ENET_MIIDATA_TA_MASK           (0x3 << ENET_MIIDATA_TA_SHIFT)
+#define ENET_MIIDATA_REG_SHIFT         18
+#define ENET_MIIDATA_REG_MASK          (0x1f << ENET_MIIDATA_REG_SHIFT)
+#define ENET_MIIDATA_PHYID_SHIFT       23
+#define ENET_MIIDATA_PHYID_MASK                (0x1f << ENET_MIIDATA_PHYID_SHIFT)
+#define ENET_MIIDATA_OP_READ_MASK      (0x6 << 28)
+#define ENET_MIIDATA_OP_WRITE_MASK     (0x5 << 28)
+
+/* Ethernet Interrupt Mask register */
+#define ENET_IRMASK_REG                        0x18
+
+/* Ethernet Interrupt register */
+#define ENET_IR_REG                    0x1c
+#define ENET_IR_MII                    (1 << 0)
+#define ENET_IR_MIB                    (1 << 1)
+#define ENET_IR_FLOWC                  (1 << 2)
+
+/* Ethernet Control register */
+#define ENET_CTL_REG                   0x2c
+#define ENET_CTL_ENABLE_SHIFT          0
+#define ENET_CTL_ENABLE_MASK           (1 << ENET_CTL_ENABLE_SHIFT)
+#define ENET_CTL_DISABLE_SHIFT         1
+#define ENET_CTL_DISABLE_MASK          (1 << ENET_CTL_DISABLE_SHIFT)
+#define ENET_CTL_SRESET_SHIFT          2
+#define ENET_CTL_SRESET_MASK           (1 << ENET_CTL_SRESET_SHIFT)
+#define ENET_CTL_EPHYSEL_SHIFT         3
+#define ENET_CTL_EPHYSEL_MASK          (1 << ENET_CTL_EPHYSEL_SHIFT)
+
+/* Transmit Control register */
+#define ENET_TXCTL_REG                 0x30
+#define ENET_TXCTL_FD_SHIFT            0
+#define ENET_TXCTL_FD_MASK             (1 << ENET_TXCTL_FD_SHIFT)
+
+/* Transmit Watermask register */
+#define ENET_TXWMARK_REG               0x34
+#define ENET_TXWMARK_WM_SHIFT          0
+#define ENET_TXWMARK_WM_MASK           (0x3f << ENET_TXWMARK_WM_SHIFT)
+
+/* MIB Control register */
+#define ENET_MIBCTL_REG                        0x38
+#define ENET_MIBCTL_RDCLEAR_SHIFT      0
+#define ENET_MIBCTL_RDCLEAR_MASK       (1 << ENET_MIBCTL_RDCLEAR_SHIFT)
+
+/* Perfect Match Data Low register */
+#define ENET_PML_REG(x)                        (0x58 + (x) * 8)
+#define ENET_PMH_REG(x)                        (0x5c + (x) * 8)
+#define ENET_PMH_DATAVALID_SHIFT       16
+#define ENET_PMH_DATAVALID_MASK                (1 << ENET_PMH_DATAVALID_SHIFT)
+
+/* MIB register */
+#define ENET_MIB_REG(x)                        (0x200 + (x) * 4)
+#define ENET_MIB_REG_COUNT             55
+
+
+/*************************************************************************
+ * _REG relative to RSET_ENETDMA
+ *************************************************************************/
+
+/* Controller Configuration Register */
+#define ENETDMA_CFG_REG                        (0x0)
+#define ENETDMA_CFG_EN_SHIFT           0
+#define ENETDMA_CFG_EN_MASK            (1 << ENETDMA_CFG_EN_SHIFT)
+#define ENETDMA_CFG_FLOWCH_MASK(x)     (1 << ((x >> 1) + 1))
+
+/* Flow Control Descriptor Low Threshold register */
+#define ENETDMA_FLOWCL_REG(x)          (0x4 + (x) * 6)
+
+/* Flow Control Descriptor High Threshold register */
+#define ENETDMA_FLOWCH_REG(x)          (0x8 + (x) * 6)
+
+/* Flow Control Descriptor Buffer Alloca Threshold register */
+#define ENETDMA_BUFALLOC_REG(x)                (0xc + (x) * 6)
+#define ENETDMA_BUFALLOC_FORCE_SHIFT   31
+#define ENETDMA_BUFALLOC_FORCE_MASK    (1 << ENETDMA_BUFALLOC_FORCE_SHIFT)
+
+/* Channel Configuration register */
+#define ENETDMA_CHANCFG_REG(x)         (0x100 + (x) * 0x10)
+#define ENETDMA_CHANCFG_EN_SHIFT       0
+#define ENETDMA_CHANCFG_EN_MASK                (1 << ENETDMA_CHANCFG_EN_SHIFT)
+#define ENETDMA_CHANCFG_PKTHALT_SHIFT  1
+#define ENETDMA_CHANCFG_PKTHALT_MASK   (1 << ENETDMA_CHANCFG_PKTHALT_SHIFT)
+
+/* Interrupt Control/Status register */
+#define ENETDMA_IR_REG(x)              (0x104 + (x) * 0x10)
+#define ENETDMA_IR_BUFDONE_MASK                (1 << 0)
+#define ENETDMA_IR_PKTDONE_MASK                (1 << 1)
+#define ENETDMA_IR_NOTOWNER_MASK       (1 << 2)
+
+/* Interrupt Mask register */
+#define ENETDMA_IRMASK_REG(x)          (0x108 + (x) * 0x10)
+
+/* Maximum Burst Length */
+#define ENETDMA_MAXBURST_REG(x)                (0x10C + (x) * 0x10)
+
+/* Ring Start Address register */
+#define ENETDMA_RSTART_REG(x)          (0x200 + (x) * 0x10)
+
+/* State Ram Word 2 */
+#define ENETDMA_SRAM2_REG(x)           (0x204 + (x) * 0x10)
+
+/* State Ram Word 3 */
+#define ENETDMA_SRAM3_REG(x)           (0x208 + (x) * 0x10)
+
+/* State Ram Word 4 */
+#define ENETDMA_SRAM4_REG(x)           (0x20c + (x) * 0x10)
+
+
+/*************************************************************************
+ * _REG relative to RSET_OHCI_PRIV
+ *************************************************************************/
+
+#define OHCI_PRIV_REG                  0x0
+#define OHCI_PRIV_PORT1_HOST_SHIFT     0
+#define OHCI_PRIV_PORT1_HOST_MASK      (1 << OHCI_PRIV_PORT1_HOST_SHIFT)
+#define OHCI_PRIV_REG_SWAP_SHIFT       3
+#define OHCI_PRIV_REG_SWAP_MASK                (1 << OHCI_PRIV_REG_SWAP_SHIFT)
+
+
+/*************************************************************************
+ * _REG relative to RSET_USBH_PRIV
+ *************************************************************************/
+
+#define USBH_PRIV_SWAP_REG             0x0
+#define USBH_PRIV_SWAP_EHCI_ENDN_SHIFT 4
+#define USBH_PRIV_SWAP_EHCI_ENDN_MASK  (1 << USBH_PRIV_SWAP_EHCI_ENDN_SHIFT)
+#define USBH_PRIV_SWAP_EHCI_DATA_SHIFT 3
+#define USBH_PRIV_SWAP_EHCI_DATA_MASK  (1 << USBH_PRIV_SWAP_EHCI_DATA_SHIFT)
+#define USBH_PRIV_SWAP_OHCI_ENDN_SHIFT 1
+#define USBH_PRIV_SWAP_OHCI_ENDN_MASK  (1 << USBH_PRIV_SWAP_OHCI_ENDN_SHIFT)
+#define USBH_PRIV_SWAP_OHCI_DATA_SHIFT 0
+#define USBH_PRIV_SWAP_OHCI_DATA_MASK  (1 << USBH_PRIV_SWAP_OHCI_DATA_SHIFT)
+
+#define USBH_PRIV_TEST_REG             0x24
+
+
+/*************************************************************************
+ * _REG relative to RSET_MPI
+ *************************************************************************/
+
+/* well known (hard wired) chip select */
+#define MPI_CS_PCMCIA_COMMON           4
+#define MPI_CS_PCMCIA_ATTR             5
+#define MPI_CS_PCMCIA_IO               6
+
+/* Chip select base register */
+#define MPI_CSBASE_REG(x)              (0x0 + (x) * 8)
+#define MPI_CSBASE_BASE_SHIFT          13
+#define MPI_CSBASE_BASE_MASK           (0x1ffff << MPI_CSBASE_BASE_SHIFT)
+#define MPI_CSBASE_SIZE_SHIFT          0
+#define MPI_CSBASE_SIZE_MASK           (0xf << MPI_CSBASE_SIZE_SHIFT)
+
+#define MPI_CSBASE_SIZE_8K             0
+#define MPI_CSBASE_SIZE_16K            1
+#define MPI_CSBASE_SIZE_32K            2
+#define MPI_CSBASE_SIZE_64K            3
+#define MPI_CSBASE_SIZE_128K           4
+#define MPI_CSBASE_SIZE_256K           5
+#define MPI_CSBASE_SIZE_512K           6
+#define MPI_CSBASE_SIZE_1M             7
+#define MPI_CSBASE_SIZE_2M             8
+#define MPI_CSBASE_SIZE_4M             9
+#define MPI_CSBASE_SIZE_8M             10
+#define MPI_CSBASE_SIZE_16M            11
+#define MPI_CSBASE_SIZE_32M            12
+#define MPI_CSBASE_SIZE_64M            13
+#define MPI_CSBASE_SIZE_128M           14
+#define MPI_CSBASE_SIZE_256M           15
+
+/* Chip select control register */
+#define MPI_CSCTL_REG(x)               (0x4 + (x) * 8)
+#define MPI_CSCTL_ENABLE_MASK          (1 << 0)
+#define MPI_CSCTL_WAIT_SHIFT           1
+#define MPI_CSCTL_WAIT_MASK            (0x7 << MPI_CSCTL_WAIT_SHIFT)
+#define MPI_CSCTL_DATA16_MASK          (1 << 4)
+#define MPI_CSCTL_SYNCMODE_MASK                (1 << 7)
+#define MPI_CSCTL_TSIZE_MASK           (1 << 8)
+#define MPI_CSCTL_ENDIANSWAP_MASK      (1 << 10)
+#define MPI_CSCTL_SETUP_SHIFT          16
+#define MPI_CSCTL_SETUP_MASK           (0xf << MPI_CSCTL_SETUP_SHIFT)
+#define MPI_CSCTL_HOLD_SHIFT           20
+#define MPI_CSCTL_HOLD_MASK            (0xf << MPI_CSCTL_HOLD_SHIFT)
+
+/* PCI registers */
+#define MPI_SP0_RANGE_REG              0x100
+#define MPI_SP0_REMAP_REG              0x104
+#define MPI_SP0_REMAP_ENABLE_MASK      (1 << 0)
+#define MPI_SP1_RANGE_REG              0x10C
+#define MPI_SP1_REMAP_REG              0x110
+#define MPI_SP1_REMAP_ENABLE_MASK      (1 << 0)
+
+#define MPI_L2PCFG_REG                 0x11C
+#define MPI_L2PCFG_CFG_TYPE_SHIFT      0
+#define MPI_L2PCFG_CFG_TYPE_MASK       (0x3 << MPI_L2PCFG_CFG_TYPE_SHIFT)
+#define MPI_L2PCFG_REG_SHIFT           2
+#define MPI_L2PCFG_REG_MASK            (0x3f << MPI_L2PCFG_REG_SHIFT)
+#define MPI_L2PCFG_FUNC_SHIFT          8
+#define MPI_L2PCFG_FUNC_MASK           (0x7 << MPI_L2PCFG_FUNC_SHIFT)
+#define MPI_L2PCFG_DEVNUM_SHIFT                11
+#define MPI_L2PCFG_DEVNUM_MASK         (0x1f << MPI_L2PCFG_DEVNUM_SHIFT)
+#define MPI_L2PCFG_CFG_USEREG_MASK     (1 << 30)
+#define MPI_L2PCFG_CFG_SEL_MASK                (1 << 31)
+
+#define MPI_L2PMEMRANGE1_REG           0x120
+#define MPI_L2PMEMBASE1_REG            0x124
+#define MPI_L2PMEMREMAP1_REG           0x128
+#define MPI_L2PMEMRANGE2_REG           0x12C
+#define MPI_L2PMEMBASE2_REG            0x130
+#define MPI_L2PMEMREMAP2_REG           0x134
+#define MPI_L2PIORANGE_REG             0x138
+#define MPI_L2PIOBASE_REG              0x13C
+#define MPI_L2PIOREMAP_REG             0x140
+#define MPI_L2P_BASE_MASK              (0xffff8000)
+#define MPI_L2PREMAP_ENABLED_MASK      (1 << 0)
+#define MPI_L2PREMAP_IS_CARDBUS_MASK   (1 << 2)
+
+#define MPI_PCIMODESEL_REG             0x144
+#define MPI_PCIMODESEL_BAR1_NOSWAP_MASK        (1 << 0)
+#define MPI_PCIMODESEL_BAR2_NOSWAP_MASK        (1 << 1)
+#define MPI_PCIMODESEL_EXT_ARB_MASK    (1 << 2)
+#define MPI_PCIMODESEL_PREFETCH_SHIFT  4
+#define MPI_PCIMODESEL_PREFETCH_MASK   (0xf << MPI_PCIMODESEL_PREFETCH_SHIFT)
+
+#define MPI_LOCBUSCTL_REG              0x14C
+#define MPI_LOCBUSCTL_EN_PCI_GPIO_MASK (1 << 0)
+#define MPI_LOCBUSCTL_U2P_NOSWAP_MASK  (1 << 1)
+
+#define MPI_LOCINT_REG                 0x150
+#define MPI_LOCINT_MASK(x)             (1 << (x + 16))
+#define MPI_LOCINT_STAT(x)             (1 << (x))
+#define MPI_LOCINT_DIR_FAILED          6
+#define MPI_LOCINT_EXT_PCI_INT         7
+#define MPI_LOCINT_SERR                        8
+#define MPI_LOCINT_CSERR               9
+
+#define MPI_PCICFGCTL_REG              0x178
+#define MPI_PCICFGCTL_CFGADDR_SHIFT    2
+#define MPI_PCICFGCTL_CFGADDR_MASK     (0x1f << MPI_PCICFGCTL_CFGADDR_SHIFT)
+#define MPI_PCICFGCTL_WRITEEN_MASK     (1 << 7)
+
+#define MPI_PCICFGDATA_REG             0x17C
+
+/* PCI host bridge custom register */
+#define BCMPCI_REG_TIMERS              0x40
+#define REG_TIMER_TRDY_SHIFT           0
+#define REG_TIMER_TRDY_MASK            (0xff << REG_TIMER_TRDY_SHIFT)
+#define REG_TIMER_RETRY_SHIFT          8
+#define REG_TIMER_RETRY_MASK           (0xff << REG_TIMER_RETRY_SHIFT)
+
+
+/*************************************************************************
+ * _REG relative to RSET_PCMCIA
+ *************************************************************************/
+
+#define PCMCIA_C1_REG                  0x0
+#define PCMCIA_C1_CD1_MASK             (1 << 0)
+#define PCMCIA_C1_CD2_MASK             (1 << 1)
+#define PCMCIA_C1_VS1_MASK             (1 << 2)
+#define PCMCIA_C1_VS2_MASK             (1 << 3)
+#define PCMCIA_C1_VS1OE_MASK           (1 << 6)
+#define PCMCIA_C1_VS2OE_MASK           (1 << 7)
+#define PCMCIA_C1_CBIDSEL_SHIFT                (8)
+#define PCMCIA_C1_CBIDSEL_MASK         (0x1f << PCMCIA_C1_CBIDSEL_SHIFT)
+#define PCMCIA_C1_EN_PCMCIA_GPIO_MASK  (1 << 13)
+#define PCMCIA_C1_EN_PCMCIA_MASK       (1 << 14)
+#define PCMCIA_C1_EN_CARDBUS_MASK      (1 << 15)
+#define PCMCIA_C1_RESET_MASK           (1 << 18)
+
+#define PCMCIA_C2_REG                  0x8
+#define PCMCIA_C2_DATA16_MASK          (1 << 0)
+#define PCMCIA_C2_BYTESWAP_MASK                (1 << 1)
+#define PCMCIA_C2_RWCOUNT_SHIFT                2
+#define PCMCIA_C2_RWCOUNT_MASK         (0x3f << PCMCIA_C2_RWCOUNT_SHIFT)
+#define PCMCIA_C2_INACTIVE_SHIFT       8
+#define PCMCIA_C2_INACTIVE_MASK                (0x3f << PCMCIA_C2_INACTIVE_SHIFT)
+#define PCMCIA_C2_SETUP_SHIFT          16
+#define PCMCIA_C2_SETUP_MASK           (0x3f << PCMCIA_C2_SETUP_SHIFT)
+#define PCMCIA_C2_HOLD_SHIFT           24
+#define PCMCIA_C2_HOLD_MASK            (0x3f << PCMCIA_C2_HOLD_SHIFT)
+
+
+/*************************************************************************
+ * _REG relative to RSET_SDRAM
+ *************************************************************************/
+
+#define SDRAM_CFG_REG                  0x0
+#define SDRAM_CFG_ROW_SHIFT            4
+#define SDRAM_CFG_ROW_MASK             (0x3 << SDRAM_CFG_ROW_SHIFT)
+#define SDRAM_CFG_COL_SHIFT            6
+#define SDRAM_CFG_COL_MASK             (0x3 << SDRAM_CFG_COL_SHIFT)
+#define SDRAM_CFG_32B_SHIFT            10
+#define SDRAM_CFG_32B_MASK             (1 << SDRAM_CFG_32B_SHIFT)
+#define SDRAM_CFG_BANK_SHIFT           13
+#define SDRAM_CFG_BANK_MASK            (1 << SDRAM_CFG_BANK_SHIFT)
+
+#define SDRAM_PRIO_REG                 0x2C
+#define SDRAM_PRIO_MIPS_SHIFT          29
+#define SDRAM_PRIO_MIPS_MASK           (1 << SDRAM_PRIO_MIPS_SHIFT)
+#define SDRAM_PRIO_ADSL_SHIFT          30
+#define SDRAM_PRIO_ADSL_MASK           (1 << SDRAM_PRIO_ADSL_SHIFT)
+#define SDRAM_PRIO_EN_SHIFT            31
+#define SDRAM_PRIO_EN_MASK             (1 << SDRAM_PRIO_EN_SHIFT)
+
+
+/*************************************************************************
+ * _REG relative to RSET_MEMC
+ *************************************************************************/
+
+#define MEMC_CFG_REG                   0x4
+#define MEMC_CFG_32B_SHIFT             1
+#define MEMC_CFG_32B_MASK              (1 << MEMC_CFG_32B_SHIFT)
+#define MEMC_CFG_COL_SHIFT             3
+#define MEMC_CFG_COL_MASK              (0x3 << MEMC_CFG_COL_SHIFT)
+#define MEMC_CFG_ROW_SHIFT             6
+#define MEMC_CFG_ROW_MASK              (0x3 << MEMC_CFG_ROW_SHIFT)
+
+
+/*************************************************************************
+ * _REG relative to RSET_DDR
+ *************************************************************************/
+
+#define DDR_DMIPSPLLCFG_REG            0x18
+#define DMIPSPLLCFG_M1_SHIFT           0
+#define DMIPSPLLCFG_M1_MASK            (0xff << DMIPSPLLCFG_M1_SHIFT)
+#define DMIPSPLLCFG_N1_SHIFT           23
+#define DMIPSPLLCFG_N1_MASK            (0x3f << DMIPSPLLCFG_N1_SHIFT)
+#define DMIPSPLLCFG_N2_SHIFT           29
+#define DMIPSPLLCFG_N2_MASK            (0x7 << DMIPSPLLCFG_N2_SHIFT)
+
+#endif /* BCM63XX_REGS_H_ */
+
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_timer.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_timer.h
new file mode 100644 (file)
index 0000000..c0fce83
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef BCM63XX_TIMER_H_
+#define BCM63XX_TIMER_H_
+
+int bcm63xx_timer_register(int id, void (*callback)(void *data), void *data);
+void bcm63xx_timer_unregister(int id);
+int bcm63xx_timer_set(int id, int monotonic, unsigned int countdown_us);
+int bcm63xx_timer_enable(int id);
+int bcm63xx_timer_disable(int id);
+unsigned int bcm63xx_timer_countdown(unsigned int countdown_us);
+
+#endif /* !BCM63XX_TIMER_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
new file mode 100644 (file)
index 0000000..6479090
--- /dev/null
@@ -0,0 +1,60 @@
+#ifndef BOARD_BCM963XX_H_
+#define BOARD_BCM963XX_H_
+
+#include <linux/types.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <bcm63xx_dev_enet.h>
+#include <bcm63xx_dev_dsp.h>
+
+/*
+ * flash mapping
+ */
+#define BCM963XX_CFE_VERSION_OFFSET    0x570
+#define BCM963XX_NVRAM_OFFSET          0x580
+
+/*
+ * nvram structure
+ */
+struct bcm963xx_nvram {
+       u32     version;
+       u8      reserved1[256];
+       u8      name[16];
+       u32     main_tp_number;
+       u32     psi_size;
+       u32     mac_addr_count;
+       u8      mac_addr_base[6];
+       u8      reserved2[2];
+       u32     checksum_old;
+       u8      reserved3[720];
+       u32     checksum_high;
+};
+
+/*
+ * board definition
+ */
+struct board_info {
+       u8              name[16];
+       unsigned int    expected_cpu_id;
+
+       /* enabled feature/device */
+       unsigned int    has_enet0:1;
+       unsigned int    has_enet1:1;
+       unsigned int    has_pci:1;
+       unsigned int    has_pccard:1;
+       unsigned int    has_ohci0:1;
+       unsigned int    has_ehci0:1;
+       unsigned int    has_dsp:1;
+
+       /* ethernet config */
+       struct bcm63xx_enet_platform_data enet0;
+       struct bcm63xx_enet_platform_data enet1;
+
+       /* DSP config */
+       struct bcm63xx_dsp_platform_data dsp;
+
+       /* GPIO LEDs */
+       struct gpio_led leds[5];
+};
+
+#endif /* ! BOARD_BCM963XX_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h b/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h
new file mode 100644 (file)
index 0000000..71742ba
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef __ASM_MACH_BCM963XX_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_BCM963XX_CPU_FEATURE_OVERRIDES_H
+
+#include <bcm63xx_cpu.h>
+
+#define cpu_has_tlb                    1
+#define cpu_has_4kex                   1
+#define cpu_has_4k_cache               1
+#define cpu_has_fpu                    0
+#define cpu_has_32fpr                  0
+#define cpu_has_counter                        1
+#define cpu_has_watch                  0
+#define cpu_has_divec                  1
+#define cpu_has_vce                    0
+#define cpu_has_cache_cdex_p           0
+#define cpu_has_cache_cdex_s           0
+#define cpu_has_prefetch               1
+#define cpu_has_mcheck                 1
+#define cpu_has_ejtag                  1
+#define cpu_has_llsc                   1
+#define cpu_has_mips16                 0
+#define cpu_has_mdmx                   0
+#define cpu_has_mips3d                 0
+#define cpu_has_smartmips              0
+#define cpu_has_vtag_icache            0
+
+#if !defined(BCMCPU_RUNTIME_DETECT) && (defined(CONFIG_BCMCPU_IS_6348) || defined(CONFIG_CPU_IS_6338) || defined(CONFIG_CPU_IS_BCM6345))
+#define cpu_has_dc_aliases             0
+#endif
+
+#define cpu_has_ic_fills_f_dc          0
+#define cpu_has_pindexed_dcache                0
+
+#define cpu_has_mips32r1               1
+#define cpu_has_mips32r2               0
+#define cpu_has_mips64r1               0
+#define cpu_has_mips64r2               0
+
+#define cpu_has_dsp                    0
+#define cpu_has_mipsmt                 0
+#define cpu_has_userlocal              0
+
+#define cpu_has_nofpuex                        0
+#define cpu_has_64bits                 0
+#define cpu_has_64bit_zero_reg         0
+
+#define cpu_dcache_line_size()         16
+#define cpu_icache_line_size()         16
+#define cpu_scache_line_size()         0
+
+#endif /* __ASM_MACH_BCM963XX_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/gpio.h b/arch/mips/include/asm/mach-bcm63xx/gpio.h
new file mode 100644 (file)
index 0000000..7cda8c0
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef __ASM_MIPS_MACH_BCM63XX_GPIO_H
+#define __ASM_MIPS_MACH_BCM63XX_GPIO_H
+
+#include <bcm63xx_gpio.h>
+
+#define gpio_to_irq(gpio)      NULL
+
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+
+#define gpio_cansleep __gpio_cansleep
+
+#include <asm-generic/gpio.h>
+
+#endif /* __ASM_MIPS_MACH_BCM63XX_GPIO_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/war.h b/arch/mips/include/asm/mach-bcm63xx/war.h
new file mode 100644 (file)
index 0000000..8e3f3fd
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_BCM63XX_WAR_H
+#define __ASM_MIPS_MACH_BCM63XX_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR    0
+#define R4600_V1_HIT_CACHEOP_WAR       0
+#define R4600_V2_HIT_CACHEOP_WAR       0
+#define R5432_CP0_INTERRUPT_WAR                0
+#define BCM1250_M3_WAR                 0
+#define SIBYTE_1956_WAR                        0
+#define MIPS4K_ICACHE_REFILL_WAR       0
+#define MIPS_CACHE_SYNC_WAR            0
+#define TX49XX_ICACHE_INDEX_INV_WAR    0
+#define RM9000_CDEX_SMP_WAR            0
+#define ICACHE_REFILLS_WORKAROUND_WAR  0
+#define R10000_LLSC_WAR                        0
+#define MIPS34K_MISSED_ITLB_WAR                0
+
+#endif /* __ASM_MIPS_MACH_BCM63XX_WAR_H */
index 3d830756b13a4cf7b11fd5f51cb1c116e01675e3..425e708d4fb9726f1d48b5d0fa293044f074566b 100644 (file)
 #define cpu_has_cache_cdex_s   0
 #define cpu_has_prefetch       1
 
+#define cpu_has_llsc           1
 /*
- * We should disable LL/SC on non SMP systems as it is faster to
- * disable interrupts for atomic access than a LL/SC.  Unfortunatly we
- * cannot as this breaks asm/futex.h
+ * We Disable LL/SC on non SMP systems as it is faster to disable
+ * interrupts for atomic access than a LL/SC.
  */
-#define cpu_has_llsc           1
+#ifdef CONFIG_SMP
+# define kernel_uses_llsc      1
+#else
+# define kernel_uses_llsc      0
+#endif
 #define cpu_has_vtag_icache    1
 #define cpu_has_dc_aliases     0
 #define cpu_has_ic_fills_f_dc  0
index 07547231e078dd3ecd35a988b3cd73bfc30c3683..23059170700593ebad07907d109a8fa8639aeba4 100644 (file)
@@ -48,7 +48,6 @@ extern unsigned char __node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES];
        .cache_nice_tries       = 1,                    \
        .flags                  = SD_LOAD_BALANCE       \
                                | SD_BALANCE_EXEC       \
-                               | SD_WAKE_BALANCE,      \
        .last_balance           = jiffies,              \
        .balance_interval       = 1,                    \
        .nr_balance_failed      = 0,                    \
diff --git a/arch/mips/include/asm/mach-lemote/cpu-feature-overrides.h b/arch/mips/include/asm/mach-lemote/cpu-feature-overrides.h
deleted file mode 100644 (file)
index 550a10d..0000000
+++ /dev/null
@@ -1,59 +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) 2009 Wu Zhangjin <wuzj@lemote.com>
- * Copyright (C) 2009 Philippe Vachon <philippe@cowpig.ca>
- * Copyright (C) 2009 Zhang Le <r0bertz@gentoo.org>
- *
- * reference: /proc/cpuinfo,
- *     arch/mips/kernel/cpu-probe.c(cpu_probe_legacy),
- *     arch/mips/kernel/proc.c(show_cpuinfo),
- *      loongson2f user manual.
- */
-
-#ifndef __ASM_MACH_LEMOTE_CPU_FEATURE_OVERRIDES_H
-#define __ASM_MACH_LEMOTE_CPU_FEATURE_OVERRIDES_H
-
-#define cpu_dcache_line_size() 32
-#define cpu_icache_line_size() 32
-#define cpu_scache_line_size() 32
-
-
-#define cpu_has_32fpr          1
-#define cpu_has_3k_cache       0
-#define cpu_has_4k_cache       1
-#define cpu_has_4kex           1
-#define cpu_has_64bits         1
-#define cpu_has_cache_cdex_p   0
-#define cpu_has_cache_cdex_s   0
-#define cpu_has_counter                1
-#define cpu_has_dc_aliases     1
-#define cpu_has_divec          0
-#define cpu_has_dsp            0
-#define cpu_has_ejtag          0
-#define cpu_has_fpu            1
-#define cpu_has_ic_fills_f_dc  0
-#define cpu_has_inclusive_pcaches      1
-#define cpu_has_llsc           1
-#define cpu_has_mcheck         0
-#define cpu_has_mdmx           0
-#define cpu_has_mips16         0
-#define cpu_has_mips32r1       0
-#define cpu_has_mips32r2       0
-#define cpu_has_mips3d         0
-#define cpu_has_mips64r1       0
-#define cpu_has_mips64r2       0
-#define cpu_has_mipsmt         0
-#define cpu_has_prefetch       0
-#define cpu_has_smartmips      0
-#define cpu_has_tlb            1
-#define cpu_has_tx39_cache     0
-#define cpu_has_userlocal      0
-#define cpu_has_vce            0
-#define cpu_has_vtag_icache    0
-#define cpu_has_watch          1
-#define cpu_icache_snoops_remote_store 1
-
-#endif /* __ASM_MACH_LEMOTE_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-lemote/dma-coherence.h b/arch/mips/include/asm/mach-lemote/dma-coherence.h
deleted file mode 100644 (file)
index c8de5e7..0000000
+++ /dev/null
@@ -1,68 +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) 2006, 07  Ralf Baechle <ralf@linux-mips.org>
- * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
- * Author: Fuxin Zhang, zhangfx@lemote.com
- *
- */
-#ifndef __ASM_MACH_LEMOTE_DMA_COHERENCE_H
-#define __ASM_MACH_LEMOTE_DMA_COHERENCE_H
-
-struct device;
-
-static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
-                                         size_t size)
-{
-       return virt_to_phys(addr) | 0x80000000;
-}
-
-static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
-                                              struct page *page)
-{
-       return page_to_phys(page) | 0x80000000;
-}
-
-static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
-       dma_addr_t dma_addr)
-{
-       return dma_addr & 0x7fffffff;
-}
-
-static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
-       size_t size, enum dma_data_direction direction)
-{
-}
-
-static inline int plat_dma_supported(struct device *dev, u64 mask)
-{
-       /*
-        * we fall back to GFP_DMA when the mask isn't all 1s,
-        * so we can't guarantee allocations that must be
-        * within a tighter range than GFP_DMA..
-        */
-       if (mask < DMA_BIT_MASK(24))
-               return 0;
-
-       return 1;
-}
-
-static inline void plat_extra_sync_for_device(struct device *dev)
-{
-       return;
-}
-
-static inline int plat_dma_mapping_error(struct device *dev,
-                                        dma_addr_t dma_addr)
-{
-       return 0;
-}
-
-static inline int plat_device_is_coherent(struct device *dev)
-{
-       return 0;
-}
-
-#endif /* __ASM_MACH_LEMOTE_DMA_COHERENCE_H */
diff --git a/arch/mips/include/asm/mach-lemote/mc146818rtc.h b/arch/mips/include/asm/mach-lemote/mc146818rtc.h
deleted file mode 100644 (file)
index ed5147e..0000000
+++ /dev/null
@@ -1,36 +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, 07 by Ralf Baechle (ralf@linux-mips.org)
- *
- * RTC routines for PC style attached Dallas chip.
- */
-#ifndef __ASM_MACH_LEMOTE_MC146818RTC_H
-#define __ASM_MACH_LEMOTE_MC146818RTC_H
-
-#include <linux/io.h>
-
-#define RTC_PORT(x)    (0x70 + (x))
-#define RTC_IRQ                8
-
-static inline unsigned char CMOS_READ(unsigned long addr)
-{
-       outb_p(addr, RTC_PORT(0));
-       return inb_p(RTC_PORT(1));
-}
-
-static inline void CMOS_WRITE(unsigned char data, unsigned long addr)
-{
-       outb_p(addr, RTC_PORT(0));
-       outb_p(data, RTC_PORT(1));
-}
-
-#define RTC_ALWAYS_BCD 0
-
-#ifndef mc146818_decode_year
-#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1970)
-#endif
-
-#endif /* __ASM_MACH_LEMOTE_MC146818RTC_H */
diff --git a/arch/mips/include/asm/mach-lemote/pci.h b/arch/mips/include/asm/mach-lemote/pci.h
deleted file mode 100644 (file)
index ea6aa14..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2008 Zhang Le <r0bertz@gentoo.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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
- * 02139, USA.
- */
-
-#ifndef _LEMOTE_PCI_H_
-#define _LEMOTE_PCI_H_
-
-#define LOONGSON2E_PCI_MEM_START       0x14000000UL
-#define LOONGSON2E_PCI_MEM_END         0x1fffffffUL
-#define LOONGSON2E_PCI_IO_START                0x00004000UL
-#define LOONGSON2E_IO_PORT_BASE                0x1fd00000UL
-
-#endif /* !_LEMOTE_PCI_H_ */
diff --git a/arch/mips/include/asm/mach-lemote/war.h b/arch/mips/include/asm/mach-lemote/war.h
deleted file mode 100644 (file)
index 05f89e0..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
- */
-#ifndef __ASM_MIPS_MACH_LEMOTE_WAR_H
-#define __ASM_MIPS_MACH_LEMOTE_WAR_H
-
-#define R4600_V1_INDEX_ICACHEOP_WAR    0
-#define R4600_V1_HIT_CACHEOP_WAR       0
-#define R4600_V2_HIT_CACHEOP_WAR       0
-#define R5432_CP0_INTERRUPT_WAR                0
-#define BCM1250_M3_WAR                 0
-#define SIBYTE_1956_WAR                        0
-#define MIPS4K_ICACHE_REFILL_WAR       0
-#define MIPS_CACHE_SYNC_WAR            0
-#define TX49XX_ICACHE_INDEX_INV_WAR    0
-#define RM9000_CDEX_SMP_WAR            0
-#define ICACHE_REFILLS_WORKAROUND_WAR  0
-#define R10000_LLSC_WAR                        0
-#define MIPS34K_MISSED_ITLB_WAR                0
-
-#endif /* __ASM_MIPS_MACH_LEMOTE_WAR_H */
diff --git a/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h b/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h
new file mode 100644 (file)
index 0000000..ce5b6e2
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * 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) 2009 Wu Zhangjin <wuzj@lemote.com>
+ * Copyright (C) 2009 Philippe Vachon <philippe@cowpig.ca>
+ * Copyright (C) 2009 Zhang Le <r0bertz@gentoo.org>
+ *
+ * reference: /proc/cpuinfo,
+ *     arch/mips/kernel/cpu-probe.c(cpu_probe_legacy),
+ *     arch/mips/kernel/proc.c(show_cpuinfo),
+ *      loongson2f user manual.
+ */
+
+#ifndef __ASM_MACH_LOONGSON_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_LOONGSON_CPU_FEATURE_OVERRIDES_H
+
+#define cpu_dcache_line_size() 32
+#define cpu_icache_line_size() 32
+#define cpu_scache_line_size() 32
+
+
+#define cpu_has_32fpr          1
+#define cpu_has_3k_cache       0
+#define cpu_has_4k_cache       1
+#define cpu_has_4kex           1
+#define cpu_has_64bits         1
+#define cpu_has_cache_cdex_p   0
+#define cpu_has_cache_cdex_s   0
+#define cpu_has_counter                1
+#define cpu_has_dc_aliases     1
+#define cpu_has_divec          0
+#define cpu_has_dsp            0
+#define cpu_has_ejtag          0
+#define cpu_has_fpu            1
+#define cpu_has_ic_fills_f_dc  0
+#define cpu_has_inclusive_pcaches      1
+#define cpu_has_llsc           1
+#define cpu_has_mcheck         0
+#define cpu_has_mdmx           0
+#define cpu_has_mips16         0
+#define cpu_has_mips32r1       0
+#define cpu_has_mips32r2       0
+#define cpu_has_mips3d         0
+#define cpu_has_mips64r1       0
+#define cpu_has_mips64r2       0
+#define cpu_has_mipsmt         0
+#define cpu_has_prefetch       0
+#define cpu_has_smartmips      0
+#define cpu_has_tlb            1
+#define cpu_has_tx39_cache     0
+#define cpu_has_userlocal      0
+#define cpu_has_vce            0
+#define cpu_has_vtag_icache    0
+#define cpu_has_watch          1
+#define cpu_icache_snoops_remote_store 1
+
+#endif /* __ASM_MACH_LOONGSON_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-loongson/dma-coherence.h b/arch/mips/include/asm/mach-loongson/dma-coherence.h
new file mode 100644 (file)
index 0000000..71a6851
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * 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) 2006, 07  Ralf Baechle <ralf@linux-mips.org>
+ * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ */
+#ifndef __ASM_MACH_LOONGSON_DMA_COHERENCE_H
+#define __ASM_MACH_LOONGSON_DMA_COHERENCE_H
+
+struct device;
+
+static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
+                                         size_t size)
+{
+       return virt_to_phys(addr) | 0x80000000;
+}
+
+static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
+                                              struct page *page)
+{
+       return page_to_phys(page) | 0x80000000;
+}
+
+static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
+       dma_addr_t dma_addr)
+{
+       return dma_addr & 0x7fffffff;
+}
+
+static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
+       size_t size, enum dma_data_direction direction)
+{
+}
+
+static inline int plat_dma_supported(struct device *dev, u64 mask)
+{
+       /*
+        * we fall back to GFP_DMA when the mask isn't all 1s,
+        * so we can't guarantee allocations that must be
+        * within a tighter range than GFP_DMA..
+        */
+       if (mask < DMA_BIT_MASK(24))
+               return 0;
+
+       return 1;
+}
+
+static inline void plat_extra_sync_for_device(struct device *dev)
+{
+       return;
+}
+
+static inline int plat_dma_mapping_error(struct device *dev,
+                                        dma_addr_t dma_addr)
+{
+       return 0;
+}
+
+static inline int plat_device_is_coherent(struct device *dev)
+{
+       return 0;
+}
+
+#endif /* __ASM_MACH_LOONGSON_DMA_COHERENCE_H */
diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h
new file mode 100644 (file)
index 0000000..da70bcf
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology
+ * Author: Wu Zhangjin <wuzj@lemote.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.
+ *
+ */
+
+#ifndef __ASM_MACH_LOONGSON_LOONGSON_H
+#define __ASM_MACH_LOONGSON_LOONGSON_H
+
+#include <linux/io.h>
+#include <linux/init.h>
+
+/* there is an internal bonito64-compatiable northbridge in loongson2e/2f */
+#include <asm/mips-boards/bonito64.h>
+
+/* loongson internal northbridge initialization */
+extern void bonito_irq_init(void);
+
+/* machine-specific reboot/halt operation */
+extern void mach_prepare_reboot(void);
+extern void mach_prepare_shutdown(void);
+
+/* environment arguments from bootloader */
+extern unsigned long bus_clock, cpu_clock_freq;
+extern unsigned long memsize, highmemsize;
+
+/* loongson-specific command line, env and memory initialization */
+extern void __init prom_init_memory(void);
+extern void __init prom_init_cmdline(void);
+extern void __init prom_init_env(void);
+
+/* irq operation functions */
+extern void bonito_irqdispatch(void);
+extern void __init bonito_irq_init(void);
+extern void __init set_irq_trigger_mode(void);
+extern void __init mach_init_irq(void);
+extern void mach_irq_dispatch(unsigned int pending);
+
+/* PCI Configuration Registers */
+#define LOONGSON_PCI_ISR4C  BONITO_PCI_REG(0x4c)
+
+/* PCI_Hit*_Sel_* */
+
+#define LOONGSON_PCI_HIT0_SEL_L     BONITO(BONITO_REGBASE + 0x50)
+#define LOONGSON_PCI_HIT0_SEL_H     BONITO(BONITO_REGBASE + 0x54)
+#define LOONGSON_PCI_HIT1_SEL_L     BONITO(BONITO_REGBASE + 0x58)
+#define LOONGSON_PCI_HIT1_SEL_H     BONITO(BONITO_REGBASE + 0x5c)
+#define LOONGSON_PCI_HIT2_SEL_L     BONITO(BONITO_REGBASE + 0x60)
+#define LOONGSON_PCI_HIT2_SEL_H     BONITO(BONITO_REGBASE + 0x64)
+
+/* PXArb Config & Status */
+
+#define LOONGSON_PXARB_CFG      BONITO(BONITO_REGBASE + 0x68)
+#define LOONGSON_PXARB_STATUS       BONITO(BONITO_REGBASE + 0x6c)
+
+/* loongson2-specific perf counter IRQ */
+#define LOONGSON2_PERFCNT_IRQ   (MIPS_CPU_IRQ_BASE + 6)
+
+#endif /* __ASM_MACH_LOONGSON_LOONGSON_H */
diff --git a/arch/mips/include/asm/mach-loongson/machine.h b/arch/mips/include/asm/mach-loongson/machine.h
new file mode 100644 (file)
index 0000000..206ea20
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology
+ * Author: Wu Zhangjin <wuzj@lemote.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.
+ */
+
+#ifndef __ASM_MACH_LOONGSON_MACHINE_H
+#define __ASM_MACH_LOONGSON_MACHINE_H
+
+#ifdef CONFIG_LEMOTE_FULOONG2E
+
+#define LOONGSON_UART_BASE (BONITO_PCIIO_BASE + 0x3f8)
+
+#define LOONGSON_MACHTYPE MACH_LEMOTE_FL2E
+
+#endif
+
+#endif /* __ASM_MACH_LOONGSON_MACHINE_H */
diff --git a/arch/mips/include/asm/mach-loongson/mc146818rtc.h b/arch/mips/include/asm/mach-loongson/mc146818rtc.h
new file mode 100644 (file)
index 0000000..ed7fe97
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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, 07 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ * RTC routines for PC style attached Dallas chip.
+ */
+#ifndef __ASM_MACH_LOONGSON_MC146818RTC_H
+#define __ASM_MACH_LOONGSON_MC146818RTC_H
+
+#include <linux/io.h>
+
+#define RTC_PORT(x)    (0x70 + (x))
+#define RTC_IRQ                8
+
+static inline unsigned char CMOS_READ(unsigned long addr)
+{
+       outb_p(addr, RTC_PORT(0));
+       return inb_p(RTC_PORT(1));
+}
+
+static inline void CMOS_WRITE(unsigned char data, unsigned long addr)
+{
+       outb_p(addr, RTC_PORT(0));
+       outb_p(data, RTC_PORT(1));
+}
+
+#define RTC_ALWAYS_BCD 0
+
+#ifndef mc146818_decode_year
+#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1970)
+#endif
+
+#endif /* __ASM_MACH_LOONGSON_MC146818RTC_H */
diff --git a/arch/mips/include/asm/mach-loongson/mem.h b/arch/mips/include/asm/mach-loongson/mem.h
new file mode 100644 (file)
index 0000000..bd7b3cb
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology
+ * Author: Wu Zhangjin <wuzj@lemote.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.
+ */
+
+#ifndef __ASM_MACH_LOONGSON_MEM_H
+#define __ASM_MACH_LOONGSON_MEM_H
+
+/*
+ * On Lemote Loongson 2e
+ *
+ * the high memory space starts from 512M.
+ * the peripheral registers reside between 0x1000:0000 and 0x2000:0000.
+ */
+
+#ifdef CONFIG_LEMOTE_FULOONG2E
+
+#define LOONGSON_HIGHMEM_START  0x20000000
+
+#define LOONGSON_MMIO_MEM_START 0x10000000
+#define LOONGSON_MMIO_MEM_END   0x20000000
+
+#endif
+
+#endif /* __ASM_MACH_LOONGSON_MEM_H */
diff --git a/arch/mips/include/asm/mach-loongson/pci.h b/arch/mips/include/asm/mach-loongson/pci.h
new file mode 100644 (file)
index 0000000..f1663ca
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2008 Zhang Le <r0bertz@gentoo.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, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
+ * 02139, USA.
+ */
+
+#ifndef __ASM_MACH_LOONGSON_PCI_H_
+#define __ASM_MACH_LOONGSON_PCI_H_
+
+extern struct pci_ops bonito64_pci_ops;
+
+#ifdef CONFIG_LEMOTE_FULOONG2E
+
+/* this pci memory space is mapped by pcimap in pci.c */
+#define LOONGSON_PCI_MEM_START BONITO_PCILO1_BASE
+#define LOONGSON_PCI_MEM_END   (BONITO_PCILO1_BASE + 0x04000000 * 2)
+/* this is an offset from mips_io_port_base */
+#define LOONGSON_PCI_IO_START  0x00004000UL
+
+#endif
+
+#endif /* !__ASM_MACH_LOONGSON_PCI_H_ */
diff --git a/arch/mips/include/asm/mach-loongson/war.h b/arch/mips/include/asm/mach-loongson/war.h
new file mode 100644 (file)
index 0000000..4b971c3
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MACH_LOONGSON_WAR_H
+#define __ASM_MACH_LOONGSON_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR    0
+#define R4600_V1_HIT_CACHEOP_WAR       0
+#define R4600_V2_HIT_CACHEOP_WAR       0
+#define R5432_CP0_INTERRUPT_WAR                0
+#define BCM1250_M3_WAR                 0
+#define SIBYTE_1956_WAR                        0
+#define MIPS4K_ICACHE_REFILL_WAR       0
+#define MIPS_CACHE_SYNC_WAR            0
+#define TX49XX_ICACHE_INDEX_INV_WAR    0
+#define RM9000_CDEX_SMP_WAR            0
+#define ICACHE_REFILLS_WORKAROUND_WAR  0
+#define R10000_LLSC_WAR                        0
+#define MIPS34K_MISSED_ITLB_WAR                0
+
+#endif /* __ASM_MACH_LEMOTE_WAR_H */
index 7f3e3f9bd23a0cb8a37d40827d7d918d017aa2fd..2848cea42bce8f5e441a63c2546e7c93d0b98da5 100644 (file)
 /* #define cpu_has_prefetch    ? */
 #define cpu_has_mcheck         1
 /* #define cpu_has_ejtag       ? */
-#ifdef CONFIG_CPU_HAS_LLSC
 #define cpu_has_llsc           1
-#else
-#define cpu_has_llsc           0
-#endif
 /* #define cpu_has_vtag_icache ? */
 /* #define cpu_has_dc_aliases  ? */
 /* #define cpu_has_ic_fills_f_dc ? */
index a0f04bb99c99bc57602cdde0b62af5252c1207e2..a576ce044c3c7ca845dedd4975a8dfef40a3b259 100644 (file)
@@ -26,7 +26,7 @@
 /* offsets from base register */
 #define BONITO(x)      (x)
 
-#elif defined(CONFIG_LEMOTE_FULONG)
+#elif defined(CONFIG_LEMOTE_FULOONG2E)
 
 #define BONITO(x) (*(volatile u32 *)((char *)CKSEG1ADDR(BONITO_REG_BASE) + (x)))
 #define BONITO_IRQ_BASE   32
index c0da1a881e3da030170fa010189d35ca33e9324e..46c08563e5328419540341ab176831ea4e991b46 100644 (file)
@@ -87,8 +87,6 @@
 
 extern int mips_revision_sconid;
 
-extern void mips_reboot_setup(void);
-
 #ifdef CONFIG_PCI
 extern void mips_pcibios_init(void);
 #else
diff --git a/arch/mips/include/asm/octeon/cvmx-rnm-defs.h b/arch/mips/include/asm/octeon/cvmx-rnm-defs.h
new file mode 100644 (file)
index 0000000..4586958
--- /dev/null
@@ -0,0 +1,88 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_RNM_DEFS_H__
+#define __CVMX_RNM_DEFS_H__
+
+#include <linux/types.h>
+
+#define CVMX_RNM_BIST_STATUS \
+        CVMX_ADD_IO_SEG(0x0001180040000008ull)
+#define CVMX_RNM_CTL_STATUS \
+        CVMX_ADD_IO_SEG(0x0001180040000000ull)
+
+union cvmx_rnm_bist_status {
+       uint64_t u64;
+       struct cvmx_rnm_bist_status_s {
+               uint64_t reserved_2_63:62;
+               uint64_t rrc:1;
+               uint64_t mem:1;
+       } s;
+       struct cvmx_rnm_bist_status_s cn30xx;
+       struct cvmx_rnm_bist_status_s cn31xx;
+       struct cvmx_rnm_bist_status_s cn38xx;
+       struct cvmx_rnm_bist_status_s cn38xxp2;
+       struct cvmx_rnm_bist_status_s cn50xx;
+       struct cvmx_rnm_bist_status_s cn52xx;
+       struct cvmx_rnm_bist_status_s cn52xxp1;
+       struct cvmx_rnm_bist_status_s cn56xx;
+       struct cvmx_rnm_bist_status_s cn56xxp1;
+       struct cvmx_rnm_bist_status_s cn58xx;
+       struct cvmx_rnm_bist_status_s cn58xxp1;
+};
+
+union cvmx_rnm_ctl_status {
+       uint64_t u64;
+       struct cvmx_rnm_ctl_status_s {
+               uint64_t reserved_9_63:55;
+               uint64_t ent_sel:4;
+               uint64_t exp_ent:1;
+               uint64_t rng_rst:1;
+               uint64_t rnm_rst:1;
+               uint64_t rng_en:1;
+               uint64_t ent_en:1;
+       } s;
+       struct cvmx_rnm_ctl_status_cn30xx {
+               uint64_t reserved_4_63:60;
+               uint64_t rng_rst:1;
+               uint64_t rnm_rst:1;
+               uint64_t rng_en:1;
+               uint64_t ent_en:1;
+       } cn30xx;
+       struct cvmx_rnm_ctl_status_cn30xx cn31xx;
+       struct cvmx_rnm_ctl_status_cn30xx cn38xx;
+       struct cvmx_rnm_ctl_status_cn30xx cn38xxp2;
+       struct cvmx_rnm_ctl_status_s cn50xx;
+       struct cvmx_rnm_ctl_status_s cn52xx;
+       struct cvmx_rnm_ctl_status_s cn52xxp1;
+       struct cvmx_rnm_ctl_status_s cn56xx;
+       struct cvmx_rnm_ctl_status_s cn56xxp1;
+       struct cvmx_rnm_ctl_status_s cn58xx;
+       struct cvmx_rnm_ctl_status_s cn58xxp1;
+};
+
+#endif
index e31e3fe14f8a446a8d94758bb3c37f89bbdc91ad..9d9381e2e3d890c9e82a62cd56acfee2319fb306 100644 (file)
@@ -271,7 +271,7 @@ static inline void cvmx_write_csr(uint64_t csr_addr, uint64_t val)
         * what RSL read we do, so we choose CVMX_MIO_BOOT_BIST_STAT
         * because it is fast and harmless.
         */
-       if ((csr_addr >> 40) == (0x800118))
+       if (((csr_addr >> 40) & 0x7ffff) == (0x118))
                cvmx_read64(CVMX_MIO_BOOT_BIST_STAT);
 }
 
index 4320239cf4ef1c73e57ffba2288f9226dbbe8c2f..f266295cce51ba982f4396b892306ef1286eb979 100644 (file)
@@ -10,6 +10,7 @@
 #define _ASM_PAGE_H
 
 #include <spaces.h>
+#include <linux/const.h>
 
 /*
  * PAGE_SHIFT determines the page size
 #ifdef CONFIG_PAGE_SIZE_64KB
 #define PAGE_SHIFT     16
 #endif
-#define PAGE_SIZE      (1UL << PAGE_SHIFT)
+#define PAGE_SIZE      (_AC(1,UL) << PAGE_SHIFT)
 #define PAGE_MASK       (~((1 << PAGE_SHIFT) - 1))
 
 #ifdef CONFIG_HUGETLB_PAGE
 #define HPAGE_SHIFT    (PAGE_SHIFT + PAGE_SHIFT - 3)
-#define HPAGE_SIZE     ((1UL) << HPAGE_SHIFT)
+#define HPAGE_SIZE     (_AC(1,UL) << HPAGE_SHIFT)
 #define HPAGE_MASK     (~(HPAGE_SIZE - 1))
 #define HUGETLB_PAGE_ORDER     (HPAGE_SHIFT - PAGE_SHIFT)
 #endif /* CONFIG_HUGETLB_PAGE */
index 4ed9d1bba2ba7d10244bd6a7884651f0cbeea076..9cd508993956b325d71dd654255d1a2aa92a459f 100644 (file)
 
 #define VMALLOC_START          MAP_BASE
 #define VMALLOC_END    \
-       (VMALLOC_START + PTRS_PER_PGD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE)
+       (VMALLOC_START + \
+        PTRS_PER_PGD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE - (1UL << 32))
 #if defined(CONFIG_MODULES) && defined(KBUILD_64BIT_SYM32) && \
        VMALLOC_START != CKSSEG
 /* Load modules into 32bit-compatible segment. */
 #define MODULE_START   CKSSEG
 #define MODULE_END     (FIXADDR_START-2*PAGE_SIZE)
-extern pgd_t module_pg_dir[PTRS_PER_PGD];
 #endif
 
 #define pte_ERROR(e) \
@@ -188,12 +188,7 @@ static inline void pud_clear(pud_t *pudp)
 #define __pmd_offset(address)  pmd_index(address)
 
 /* to find an entry in a kernel page-table-directory */
-#ifdef MODULE_START
-#define pgd_offset_k(address) \
-       ((address) >= MODULE_START ? module_pg_dir : pgd_offset(&init_mm, 0UL))
-#else
-#define pgd_offset_k(address) pgd_offset(&init_mm, 0UL)
-#endif
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
 
 #define pgd_index(address)     (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
 #define pmd_index(address)     (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
index cd30f83235bb292360233737dd87a4ac343b0830..fcf5f98d90ccf6227906449d24b2cfb016a6e1ae 100644 (file)
@@ -32,6 +32,9 @@ extern asmlinkage void *resume(void *last, void *next, void *next_ti);
 
 struct task_struct;
 
+extern unsigned int ll_bit;
+extern struct task_struct *ll_task;
+
 #ifdef CONFIG_MIPS_MT_FPAFF
 
 /*
@@ -63,11 +66,18 @@ do {                                                                        \
 #define __mips_mt_fpaff_switch_to(prev) do { (void) (prev); } while (0)
 #endif
 
+#define __clear_software_ll_bit()                                      \
+do {                                                                   \
+       if (!__builtin_constant_p(cpu_has_llsc) || !cpu_has_llsc)       \
+               ll_bit = 0;                                             \
+} while (0)
+
 #define switch_to(prev, next, last)                                    \
 do {                                                                   \
        __mips_mt_fpaff_switch_to(prev);                                \
        if (cpu_has_dsp)                                                \
                __save_dsp(prev);                                       \
+       __clear_software_ll_bit();                                      \
        (last) = resume(prev, next, task_thread_info(next));            \
 } while (0)
 
@@ -84,7 +94,7 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
 {
        __u32 retval;
 
-       if (cpu_has_llsc && R10000_LLSC_WAR) {
+       if (kernel_uses_llsc && R10000_LLSC_WAR) {
                unsigned long dummy;
 
                __asm__ __volatile__(
@@ -99,7 +109,7 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
                : "=&r" (retval), "=m" (*m), "=&r" (dummy)
                : "R" (*m), "Jr" (val)
                : "memory");
-       } else if (cpu_has_llsc) {
+       } else if (kernel_uses_llsc) {
                unsigned long dummy;
 
                __asm__ __volatile__(
@@ -136,7 +146,7 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
 {
        __u64 retval;
 
-       if (cpu_has_llsc && R10000_LLSC_WAR) {
+       if (kernel_uses_llsc && R10000_LLSC_WAR) {
                unsigned long dummy;
 
                __asm__ __volatile__(
@@ -149,7 +159,7 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
                : "=&r" (retval), "=m" (*m), "=&r" (dummy)
                : "R" (*m), "Jr" (val)
                : "memory");
-       } else if (cpu_has_llsc) {
+       } else if (kernel_uses_llsc) {
                unsigned long dummy;
 
                __asm__ __volatile__(
index 8d006ec656771f3e8735987f7050b62cb5d4e1cd..2c1e1d02338b23fb935b504aba53cdad6cf6cd8e 100644 (file)
@@ -183,9 +183,6 @@ void output_mm_defines(void)
        OFFSET(MM_PGD, mm_struct, pgd);
        OFFSET(MM_CONTEXT, mm_struct, context);
        BLANK();
-       DEFINE(_PAGE_SIZE, PAGE_SIZE);
-       DEFINE(_PAGE_SHIFT, PAGE_SHIFT);
-       BLANK();
        DEFINE(_PGD_T_SIZE, sizeof(pgd_t));
        DEFINE(_PMD_T_SIZE, sizeof(pmd_t));
        DEFINE(_PTE_T_SIZE, sizeof(pte_t));
index 02b7713cf71c3a8db4c89c98f0b61d9b31316473..408d0a07b3a37d2bac6eef16cb669d738da3ff65 100644 (file)
@@ -167,7 +167,7 @@ static inline void check_mult_sh(void)
        panic(bug64hit, !R4000_WAR ? r4kwar : nowar);
 }
 
-static volatile int daddi_ov __cpuinitdata = 0;
+static volatile int daddi_ov __cpuinitdata;
 
 asmlinkage void __init do_daddi_ov(struct pt_regs *regs)
 {
index 1abe9905c9c1895ef220bc51f7f4ddf366b5cfad..f709657e4dcd104e3fccd3518658d4478122e484 100644 (file)
@@ -31,7 +31,7 @@
  * The wait instruction stops the pipeline and reduces the power consumption of
  * the CPU very much.
  */
-void (*cpu_wait)(void) = NULL;
+void (*cpu_wait)(void);
 
 static void r3081_wait(void)
 {
@@ -91,16 +91,13 @@ static void rm7k_wait_irqoff(void)
        local_irq_enable();
 }
 
-/* The Au1xxx wait is available only if using 32khz counter or
- * external timer source, but specifically not CP0 Counter. */
-int allow_au1k_wait;
-
+/*
+ * The Au1xxx wait is available only if using 32khz counter or
+ * external timer source, but specifically not CP0 Counter.
+ * alchemy/common/time.c may override cpu_wait!
+ */
 static void au1k_wait(void)
 {
-       if (!allow_au1k_wait)
-               return;
-
-       /* using the wait instruction makes CP0 counter unusable */
        __asm__("       .set    mips3                   \n"
                "       cache   0x14, 0(%0)             \n"
                "       cache   0x14, 32(%0)            \n"
@@ -115,7 +112,7 @@ static void au1k_wait(void)
                : : "r" (au1k_wait));
 }
 
-static int __initdata nowait = 0;
+static int __initdata nowait;
 
 static int __init wait_disable(char *s)
 {
@@ -159,6 +156,9 @@ void __init check_wait(void)
        case CPU_25KF:
        case CPU_PR4450:
        case CPU_BCM3302:
+       case CPU_BCM6338:
+       case CPU_BCM6348:
+       case CPU_BCM6358:
        case CPU_CAVIUM_OCTEON:
                cpu_wait = r4k_wait;
                break;
@@ -857,6 +857,7 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
        decode_configs(c);
        switch (c->processor_id & 0xff00) {
        case PRID_IMP_BCM3302:
+        /* same as PRID_IMP_BCM6338 */
                c->cputype = CPU_BCM3302;
                __cpu_name[cpu] = "Broadcom BCM3302";
                break;
@@ -864,6 +865,25 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
                c->cputype = CPU_BCM4710;
                __cpu_name[cpu] = "Broadcom BCM4710";
                break;
+       case PRID_IMP_BCM6345:
+               c->cputype = CPU_BCM6345;
+               __cpu_name[cpu] = "Broadcom BCM6345";
+               break;
+       case PRID_IMP_BCM6348:
+               c->cputype = CPU_BCM6348;
+               __cpu_name[cpu] = "Broadcom BCM6348";
+               break;
+       case PRID_IMP_BCM4350:
+               switch (c->processor_id & 0xf0) {
+               case PRID_REV_BCM6358:
+                       c->cputype = CPU_BCM6358;
+                       __cpu_name[cpu] = "Broadcom BCM6358";
+                       break;
+               default:
+                       c->cputype = CPU_UNKNOWN;
+                       break;
+               }
+               break;
        }
 }
 
index fd6e512240347aac0a17b848cd9e1b42657badaf..f2397f00db439df62acc67424ac781692371d8e6 100644 (file)
@@ -31,7 +31,7 @@
 #include <asm/rtlx.h>
 #include <asm/kspd.h>
 
-static struct workqueue_struct *workqueue = NULL;
+static struct workqueue_struct *workqueue;
 static struct work_struct work;
 
 extern unsigned long cpu_khz;
@@ -58,7 +58,7 @@ struct mtsp_syscall_generic {
 };
 
 static struct list_head kspd_notifylist;
-static int sp_stopping = 0;
+static int sp_stopping;
 
 /* these should match with those in the SDE kit */
 #define MTSP_SYSCALL_BASE      0
@@ -328,7 +328,7 @@ static void sp_cleanup(void)
        sys_chdir("/");
 }
 
-static int channel_open = 0;
+static int channel_open;
 
 /* the work handler */
 static void sp_work(struct work_struct *unused)
index 42461310b185c683b9738fda5af742a74718b5ae..cbc6182b0065805865ff2e1557b0f8bda1c4df2b 100644 (file)
@@ -18,7 +18,7 @@
 cpumask_t mt_fpu_cpumask;
 
 static int fpaff_threshold = -1;
-unsigned long mt_fpemul_threshold = 0;
+unsigned long mt_fpemul_threshold;
 
 /*
  * Replacement functions for the sys_sched_setaffinity() and
index d01665a453f5b0de7ccc52ea3d899609e92be86c..b2259e7cd829161b958464fdc375bf68c182b34f 100644 (file)
@@ -125,10 +125,10 @@ void mips_mt_regdump(unsigned long mvpctl)
        local_irq_restore(flags);
 }
 
-static int mt_opt_norps = 0;
+static int mt_opt_norps;
 static int mt_opt_rpsctl = -1;
 static int mt_opt_nblsu = -1;
-static int mt_opt_forceconfig7 = 0;
+static int mt_opt_forceconfig7;
 static int mt_opt_config7 = -1;
 
 static int __init rps_disable(char *s)
@@ -161,8 +161,8 @@ static int __init config7_set(char *str)
 __setup("config7=", config7_set);
 
 /* Experimental cache flush control parameters that should go away some day */
-int mt_protiflush = 0;
-int mt_protdflush = 0;
+int mt_protiflush;
+int mt_protdflush;
 int mt_n_iflushes = 1;
 int mt_n_dflushes = 1;
 
@@ -194,7 +194,7 @@ static int __init ndflush(char *s)
 }
 __setup("ndflush=", ndflush);
 
-static unsigned int itc_base = 0;
+static unsigned int itc_base;
 
 static int __init set_itc_base(char *str)
 {
index d52389672b06def47bd135992fecccd379f00ab3..3952b8323efac5d3017c86bc99a4b72434fe66d3 100644 (file)
@@ -36,9 +36,6 @@
        .align  7
        LEAF(resume)
        .set arch=octeon
-#ifndef CONFIG_CPU_HAS_LLSC
-       sw      zero, ll_bit
-#endif
        mfc0    t1, CP0_STATUS
        LONG_S  t1, THREAD_STATUS(a0)
        cpu_save_nonscratch a0
index 656bde2e11b14d37186b5d3ec850b5397a78167d..698414b7a253d21c0de4017a5198904e6c689fd1 100644 (file)
@@ -46,9 +46,6 @@
  *                     struct thread_info *next_ti) )
  */
 LEAF(resume)
-#ifndef CONFIG_CPU_HAS_LLSC
-       sw      zero, ll_bit
-#endif
        mfc0    t1, CP0_STATUS
        sw      t1, THREAD_STATUS(a0)
        cpu_save_nonscratch a0
index d9bfae53c43f92c5a400301bb02bfb3c05bfad92..8893ee1a2368c369ddd503514866597fe6aa4ac3 100644 (file)
@@ -45,9 +45,6 @@
  */
        .align  5
        LEAF(resume)
-#ifndef CONFIG_CPU_HAS_LLSC
-       sw      zero, ll_bit
-#endif
        mfc0    t1, CP0_STATUS
        LONG_S  t1, THREAD_STATUS(a0)
        cpu_save_nonscratch a0
index 4ce93aa7b37259f24299791a7a793230de5a79a6..a10ebfdc28ae91ad4a7241e95d7d6bcac9caadf4 100644 (file)
@@ -57,7 +57,7 @@ static struct chan_waitqueues {
 } channel_wqs[RTLX_CHANNELS];
 
 static struct vpe_notifications notify;
-static int sp_stopping = 0;
+static int sp_stopping;
 
 extern void *vpe_get_shared(int index);
 
index b57082123536f217726600918330e7e3e92abda9..7c2de4f091c471f78b8bfc3e8925c7b4f578cf58 100644 (file)
@@ -187,78 +187,6 @@ illegal_syscall:
        j       o32_syscall_exit
        END(handle_sys)
 
-       LEAF(mips_atomic_set)
-       andi    v0, a1, 3                       # must be word aligned
-       bnez    v0, bad_alignment
-
-       lw      v1, TI_ADDR_LIMIT($28)          # in legal address range?
-       addiu   a0, a1, 4
-       or      a0, a0, a1
-       and     a0, a0, v1
-       bltz    a0, bad_address
-
-#ifdef CONFIG_CPU_HAS_LLSC
-       /* Ok, this is the ll/sc case.  World is sane :-)  */
-1:     ll      v0, (a1)
-       move    a0, a2
-2:     sc      a0, (a1)
-#if R10000_LLSC_WAR
-       beqzl   a0, 1b
-#else
-       beqz    a0, 1b
-#endif
-
-       .section __ex_table,"a"
-       PTR     1b, bad_stack
-       PTR     2b, bad_stack
-       .previous
-#else
-       sw      a1, 16(sp)
-       sw      a2, 20(sp)
-
-       move    a0, sp
-       move    a2, a1
-       li      a1, 1
-       jal     do_page_fault
-
-       lw      a1, 16(sp)
-       lw      a2, 20(sp)
-
-       /*
-        * At this point the page should be readable and writable unless
-        * there was no more memory available.
-        */
-1:     lw      v0, (a1)
-2:     sw      a2, (a1)
-
-       .section __ex_table,"a"
-       PTR     1b, no_mem
-       PTR     2b, no_mem
-       .previous
-#endif
-
-       sw      zero, PT_R7(sp)         # success
-       sw      v0, PT_R2(sp)           # result
-
-       j       o32_syscall_exit        # continue like a normal syscall
-
-no_mem:        li      v0, -ENOMEM
-       jr      ra
-
-bad_address:
-       li      v0, -EFAULT
-       jr      ra
-
-bad_alignment:
-       li      v0, -EINVAL
-       jr      ra
-       END(mips_atomic_set)
-
-       LEAF(sys_sysmips)
-       beq     a0, MIPS_ATOMIC_SET, mips_atomic_set
-       j       _sys_sysmips
-       END(sys_sysmips)
-
        LEAF(sys_syscall)
        subu    t0, a0, __NR_O32_Linux  # check syscall number
        sltiu   v0, t0, __NR_O32_Linux_syscalls + 1
index 3d866f24e06442995b7c1c106e628b28e7c4fb18..b97b993846d657ef25f0a940a5302824535dd5cc 100644 (file)
@@ -124,78 +124,6 @@ illegal_syscall:
        j       n64_syscall_exit
        END(handle_sys64)
 
-       LEAF(mips_atomic_set)
-       andi    v0, a1, 3                       # must be word aligned
-       bnez    v0, bad_alignment
-
-       LONG_L  v1, TI_ADDR_LIMIT($28)          # in legal address range?
-       LONG_ADDIU      a0, a1, 4
-       or      a0, a0, a1
-       and     a0, a0, v1
-       bltz    a0, bad_address
-
-#ifdef CONFIG_CPU_HAS_LLSC
-       /* Ok, this is the ll/sc case.  World is sane :-)  */
-1:     ll      v0, (a1)
-       move    a0, a2
-2:     sc      a0, (a1)
-#if R10000_LLSC_WAR
-       beqzl   a0, 1b
-#else
-       beqz    a0, 1b
-#endif
-
-       .section __ex_table,"a"
-       PTR     1b, bad_stack
-       PTR     2b, bad_stack
-       .previous
-#else
-       sw      a1, 16(sp)
-       sw      a2, 20(sp)
-
-       move    a0, sp
-       move    a2, a1
-       li      a1, 1
-       jal     do_page_fault
-
-       lw      a1, 16(sp)
-       lw      a2, 20(sp)
-
-       /*
-        * At this point the page should be readable and writable unless
-        * there was no more memory available.
-        */
-1:     lw      v0, (a1)
-2:     sw      a2, (a1)
-
-       .section __ex_table,"a"
-       PTR     1b, no_mem
-       PTR     2b, no_mem
-       .previous
-#endif
-
-       sd      zero, PT_R7(sp)         # success
-       sd      v0, PT_R2(sp)           # result
-
-       j       n64_syscall_exit        # continue like a normal syscall
-
-no_mem:        li      v0, -ENOMEM
-       jr      ra
-
-bad_address:
-       li      v0, -EFAULT
-       jr      ra
-
-bad_alignment:
-       li      v0, -EINVAL
-       jr      ra
-       END(mips_atomic_set)
-
-       LEAF(sys_sysmips)
-       beq     a0, MIPS_ATOMIC_SET, mips_atomic_set
-       j       _sys_sysmips
-       END(sys_sysmips)
-
        .align  3
 sys_call_table:
        PTR     sys_read                        /* 5000 */
index 2950b97253b7348c02134a2317372e78ba61c703..2b290d70083ebc6548deafc96b0a706d4fa445e7 100644 (file)
@@ -441,7 +441,7 @@ static void __init bootmem_init(void)
  * initialization hook for anything else was introduced.
  */
 
-static int usermem __initdata = 0;
+static int usermem __initdata;
 
 static int __init early_parse_mem(char *p)
 {
index bc7d9b05e2f4e4d218f0b87c81ee98e9f708b34a..64668a93248be249a9e376db2f34af05874ccbae 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/cpumask.h>
 #include <linux/cpu.h>
 #include <linux/err.h>
+#include <linux/smp.h>
 
 #include <asm/atomic.h>
 #include <asm/cpu.h>
@@ -49,8 +50,6 @@ volatile cpumask_t cpu_callin_map;    /* Bitmask of started secondaries */
 int __cpu_number_map[NR_CPUS];         /* Map physical to logical */
 int __cpu_logical_map[NR_CPUS];                /* Map logical to physical */
 
-extern void cpu_idle(void);
-
 /* Number of TCs (or siblings in Intel speak) per CPU core */
 int smp_num_siblings = 1;
 EXPORT_SYMBOL(smp_num_siblings);
index c16bb6d6c25c64f1562ca85f7f6d5a8a7d450a37..1a466baf0edf0eccd6fa200454e63772f78da630 100644 (file)
@@ -95,14 +95,14 @@ void init_smtc_stats(void);
 
 /* Global SMTC Status */
 
-unsigned int smtc_status = 0;
+unsigned int smtc_status;
 
 /* Boot command line configuration overrides */
 
 static int vpe0limit;
-static int ipibuffers = 0;
-static int nostlb = 0;
-static int asidmask = 0;
+static int ipibuffers;
+static int nostlb;
+static int asidmask;
 unsigned long smtc_asid_mask = 0xff;
 
 static int __init vpe0tcs(char *str)
@@ -151,7 +151,7 @@ __setup("asidmask=", asidmask_set);
 
 #ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
 
-static int hang_trig = 0;
+static int hang_trig;
 
 static int __init hangtrig_enable(char *s)
 {
index 8cf3846440401b682b01cf26aaa93ba25699c68c..3fe1fcfa2e7301825427c8f44faf80efc2969ed2 100644 (file)
@@ -28,7 +28,9 @@
 #include <linux/compiler.h>
 #include <linux/module.h>
 #include <linux/ipc.h>
+#include <linux/uaccess.h>
 
+#include <asm/asm.h>
 #include <asm/branch.h>
 #include <asm/cachectl.h>
 #include <asm/cacheflush.h>
@@ -290,12 +292,116 @@ SYSCALL_DEFINE1(set_thread_area, unsigned long, addr)
        return 0;
 }
 
-asmlinkage int _sys_sysmips(long cmd, long arg1, long arg2, long arg3)
+static inline int mips_atomic_set(struct pt_regs *regs,
+       unsigned long addr, unsigned long new)
 {
+       unsigned long old, tmp;
+       unsigned int err;
+
+       if (unlikely(addr & 3))
+               return -EINVAL;
+
+       if (unlikely(!access_ok(VERIFY_WRITE, addr, 4)))
+               return -EINVAL;
+
+       if (cpu_has_llsc && R10000_LLSC_WAR) {
+               __asm__ __volatile__ (
+               "       li      %[err], 0                               \n"
+               "1:     ll      %[old], (%[addr])                       \n"
+               "       move    %[tmp], %[new]                          \n"
+               "2:     sc      %[tmp], (%[addr])                       \n"
+               "       beqzl   %[tmp], 1b                              \n"
+               "3:                                                     \n"
+               "       .section .fixup,\"ax\"                          \n"
+               "4:     li      %[err], %[efault]                       \n"
+               "       j       3b                                      \n"
+               "       .previous                                       \n"
+               "       .section __ex_table,\"a\"                       \n"
+               "       "STR(PTR)"      1b, 4b                          \n"
+               "       "STR(PTR)"      2b, 4b                          \n"
+               "       .previous                                       \n"
+               : [old] "=&r" (old),
+                 [err] "=&r" (err),
+                 [tmp] "=&r" (tmp)
+               : [addr] "r" (addr),
+                 [new] "r" (new),
+                 [efault] "i" (-EFAULT)
+               : "memory");
+       } else if (cpu_has_llsc) {
+               __asm__ __volatile__ (
+               "       li      %[err], 0                               \n"
+               "1:     ll      %[old], (%[addr])                       \n"
+               "       move    %[tmp], %[new]                          \n"
+               "2:     sc      %[tmp], (%[addr])                       \n"
+               "       bnez    %[tmp], 4f                              \n"
+               "3:                                                     \n"
+               "       .subsection 2                                   \n"
+               "4:     b       1b                                      \n"
+               "       .previous                                       \n"
+               "                                                       \n"
+               "       .section .fixup,\"ax\"                          \n"
+               "5:     li      %[err], %[efault]                       \n"
+               "       j       3b                                      \n"
+               "       .previous                                       \n"
+               "       .section __ex_table,\"a\"                       \n"
+               "       "STR(PTR)"      1b, 5b                          \n"
+               "       "STR(PTR)"      2b, 5b                          \n"
+               "       .previous                                       \n"
+               : [old] "=&r" (old),
+                 [err] "=&r" (err),
+                 [tmp] "=&r" (tmp)
+               : [addr] "r" (addr),
+                 [new] "r" (new),
+                 [efault] "i" (-EFAULT)
+               : "memory");
+       } else {
+               do {
+                       preempt_disable();
+                       ll_bit = 1;
+                       ll_task = current;
+                       preempt_enable();
+
+                       err = __get_user(old, (unsigned int *) addr);
+                       err |= __put_user(new, (unsigned int *) addr);
+                       if (err)
+                               break;
+                       rmb();
+               } while (!ll_bit);
+       }
+
+       if (unlikely(err))
+               return err;
+
+       regs->regs[2] = old;
+       regs->regs[7] = 0;      /* No error */
+
+       /*
+        * Don't let your children do this ...
+        */
+       __asm__ __volatile__(
+       "       move    $29, %0                                         \n"
+       "       j       syscall_exit                                    \n"
+       : /* no outputs */
+       : "r" (regs));
+
+       /* unreached.  Honestly.  */
+       while (1);
+}
+
+save_static_function(sys_sysmips);
+static int __used noinline
+_sys_sysmips(nabi_no_regargs struct pt_regs regs)
+{
+       long cmd, arg1, arg2, arg3;
+
+       cmd = regs.regs[4];
+       arg1 = regs.regs[5];
+       arg2 = regs.regs[6];
+       arg3 = regs.regs[7];
+
        switch (cmd) {
        case MIPS_ATOMIC_SET:
-               printk(KERN_CRIT "How did I get here?\n");
-               return -EINVAL;
+               return mips_atomic_set(&regs, arg1, arg2);
 
        case MIPS_FIXADE:
                if (arg1 & ~3)
index 08f1edf355e80c51362e4e35822e4a109a419acc..0a18b4c62afb3f2f5a849d182a0c41d022d5b607 100644 (file)
@@ -466,9 +466,8 @@ asmlinkage void do_be(struct pt_regs *regs)
  * The ll_bit is cleared by r*_switch.S
  */
 
-unsigned long ll_bit;
-
-static struct task_struct *ll_task = NULL;
+unsigned int ll_bit;
+struct task_struct *ll_task;
 
 static inline int simulate_ll(struct pt_regs *regs, unsigned int opcode)
 {
index 1474c18fb777d13c1d07f164f50ccef1304f156b..2769bed3d2afcb0af8b3ebb351ed39c5f5ba609a 100644 (file)
@@ -1,4 +1,5 @@
 #include <asm/asm-offsets.h>
+#include <asm/page.h>
 #include <asm-generic/vmlinux.lds.h>
 
 #undef mips
@@ -42,13 +43,7 @@ SECTIONS
        } :text = 0
        _etext = .;     /* End of text section */
 
-       /* Exception table */
-       . = ALIGN(16);
-       __ex_table : {
-               __start___ex_table = .;
-               *(__ex_table)
-               __stop___ex_table = .;
-       }
+       EXCEPTION_TABLE(16)
 
        /* Exception table for data bus errors */
        __dbe_table : {
@@ -65,20 +60,10 @@ SECTIONS
        /* writeable */
        .data : {       /* Data */
                . = . + DATAOFFSET;             /* for CONFIG_MAPPED_KERNEL */
-               /*
-                * This ALIGN is needed as a workaround for a bug a
-                * gcc bug upto 4.1 which limits the maximum alignment
-                * to at most 32kB and results in the following
-                * warning:
-                *
-                *  CC      arch/mips/kernel/init_task.o
-                * arch/mips/kernel/init_task.c:30: warning: alignment
-                * of â€˜init_thread_union’ is greater than maximum
-                * object file alignment.  Using 32768
-                */
-               . = ALIGN(_PAGE_SIZE);
-               *(.data.init_task)
 
+               INIT_TASK_DATA(PAGE_SIZE)
+               NOSAVE_DATA
+               CACHELINE_ALIGNED_DATA(1 << CONFIG_MIPS_L1_CACHE_SHIFT)
                DATA_DATA
                CONSTRUCTORS
        }
@@ -95,51 +80,13 @@ SECTIONS
        .sdata : {
                *(.sdata)
        }
-
-       . = ALIGN(_PAGE_SIZE);
-       .data_nosave : {
-               __nosave_begin = .;
-               *(.data.nosave)
-       }
-       . = ALIGN(_PAGE_SIZE);
-       __nosave_end = .;
-
-       . = ALIGN(1 << CONFIG_MIPS_L1_CACHE_SHIFT);
-       .data.cacheline_aligned : {
-               *(.data.cacheline_aligned)
-       }
        _edata =  .;                    /* End of data section */
 
        /* will be freed after init */
-       . = ALIGN(_PAGE_SIZE);          /* Init code and data */
+       . = ALIGN(PAGE_SIZE);           /* Init code and data */
        __init_begin = .;
-       .init.text : {
-               _sinittext = .;
-               INIT_TEXT
-               _einittext = .;
-       }
-       .init.data : {
-               INIT_DATA
-       }
-       . = ALIGN(16);
-       .init.setup : {
-               __setup_start = .;
-               *(.init.setup)
-               __setup_end = .;
-       }
-
-       .initcall.init : {
-               __initcall_start = .;
-               INITCALLS
-               __initcall_end = .;
-       }
-
-       .con_initcall.init : {
-               __con_initcall_start = .;
-               *(.con_initcall.init)
-               __con_initcall_end = .;
-       }
-       SECURITY_INIT
+       INIT_TEXT_SECTION(PAGE_SIZE)
+       INIT_DATA_SECTION(16)
 
        /* .exit.text is discarded at runtime, not link time, to deal with
         * references from .rodata
@@ -150,29 +97,13 @@ SECTIONS
        .exit.data : {
                EXIT_DATA
        }
-#if defined(CONFIG_BLK_DEV_INITRD)
-       . = ALIGN(_PAGE_SIZE);
-       .init.ramfs : {
-               __initramfs_start = .;
-               *(.init.ramfs)
-               __initramfs_end = .;
-       }
-#endif
-       PERCPU(_PAGE_SIZE)
-       . = ALIGN(_PAGE_SIZE);
+
+       PERCPU(PAGE_SIZE)
+       . = ALIGN(PAGE_SIZE);
        __init_end = .;
        /* freed after init ends here */
 
-       __bss_start = .;        /* BSS */
-       .sbss  : {
-               *(.sbss)
-               *(.scommon)
-       }
-       .bss : {
-               *(.bss)
-               *(COMMON)
-       }
-       __bss_stop = .;
+       BSS_SECTION(0, 0, 0)
 
        _end = . ;
 
index 9a1ab7e87fd4d00e1705f858654f841a4f198e6f..eb6c4c5b7fbe468176e74e47a71458a6afaa830f 100644 (file)
@@ -74,7 +74,7 @@ static const int minor = 1;   /* fixed for now  */
 
 #ifdef CONFIG_MIPS_APSP_KSPD
 static struct kspd_notifications kspd_events;
-static int kspd_events_reqd = 0;
+static int kspd_events_reqd;
 #endif
 
 /* grab the likely amount of memory we will need. */
index 52cb1436a12aff59908461f87f9ea114d44c1f63..c6fd96ff118df4477627befc5db24d602a2abd7c 100644 (file)
@@ -135,7 +135,7 @@ static void rtc_end_op(void)
        lasat_ndelay(1000);
 }
 
-unsigned long read_persistent_clock(void)
+void read_persistent_clock(struct timespec *ts)
 {
        unsigned long word;
        unsigned long flags;
@@ -147,7 +147,8 @@ unsigned long read_persistent_clock(void)
        rtc_end_op();
        spin_unlock_irqrestore(&rtc_lock, flags);
 
-       return word;
+       ts->tv_sec = word;
+       ts->tv_nsec = 0;
 }
 
 int rtc_mips_set_mmss(unsigned long time)
index 8f88886feb12e147167fa7bcf61a5961bd6430cf..3f04d4c406b75f397f8c568a730bbcdf118f33f2 100644 (file)
@@ -92,10 +92,12 @@ static int rtctmp;
 int proc_dolasatrtc(ctl_table *table, int write, struct file *filp,
                       void *buffer, size_t *lenp, loff_t *ppos)
 {
+       struct timespec ts;
        int r;
 
        if (!write) {
-               rtctmp = read_persistent_clock();
+               read_persistent_clock(&ts);
+               rtctmp = ts.tv_sec;
                /* check for time < 0 and set to 0 */
                if (rtctmp < 0)
                        rtctmp = 0;
@@ -134,9 +136,11 @@ int sysctl_lasat_rtc(ctl_table *table,
                    void *oldval, size_t *oldlenp,
                    void *newval, size_t newlen)
 {
+       struct timespec ts;
        int r;
 
-       rtctmp = read_persistent_clock();
+       read_persistent_clock(&ts);
+       rtctmp = ts.tv_sec;
        if (rtctmp < 0)
                rtctmp = 0;
        r = sysctl_intvec(table, oldval, oldlenp, newval, newlen);
diff --git a/arch/mips/lemote/lm2e/Makefile b/arch/mips/lemote/lm2e/Makefile
deleted file mode 100644 (file)
index d34671d..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-# Makefile for Lemote Fulong mini-PC board.
-#
-
-obj-y += setup.o prom.o reset.o irq.o pci.o bonito-irq.o dbg_io.o mem.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/lemote/lm2e/bonito-irq.c b/arch/mips/lemote/lm2e/bonito-irq.c
deleted file mode 100644 (file)
index 8fc3bce..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2001 MontaVista Software Inc.
- * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
- * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org)
- *
- * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
- * Author: Fuxin Zhang, zhangfx@lemote.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.
- *
- */
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-
-#include <asm/mips-boards/bonito64.h>
-
-
-static inline void bonito_irq_enable(unsigned int irq)
-{
-       BONITO_INTENSET = (1 << (irq - BONITO_IRQ_BASE));
-       mmiowb();
-}
-
-static inline void bonito_irq_disable(unsigned int irq)
-{
-       BONITO_INTENCLR = (1 << (irq - BONITO_IRQ_BASE));
-       mmiowb();
-}
-
-static struct irq_chip bonito_irq_type = {
-       .name   = "bonito_irq",
-       .ack    = bonito_irq_disable,
-       .mask   = bonito_irq_disable,
-       .mask_ack = bonito_irq_disable,
-       .unmask = bonito_irq_enable,
-};
-
-static struct irqaction dma_timeout_irqaction = {
-       .handler        = no_action,
-       .name           = "dma_timeout",
-};
-
-void bonito_irq_init(void)
-{
-       u32 i;
-
-       for (i = BONITO_IRQ_BASE; i < BONITO_IRQ_BASE + 32; i++) {
-               set_irq_chip_and_handler(i, &bonito_irq_type, handle_level_irq);
-       }
-
-       setup_irq(BONITO_IRQ_BASE + 10, &dma_timeout_irqaction);
-}
diff --git a/arch/mips/lemote/lm2e/dbg_io.c b/arch/mips/lemote/lm2e/dbg_io.c
deleted file mode 100644 (file)
index 6c95da3..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright 2001 MontaVista Software Inc.
- * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
- * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org)
- *
- * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
- * Author: Fuxin Zhang, zhangfx@lemote.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.
- *
- */
-
-#include <linux/io.h>
-#include <linux/init.h>
-#include <linux/types.h>
-
-#include <asm/serial.h>
-
-#define         UART16550_BAUD_2400             2400
-#define         UART16550_BAUD_4800             4800
-#define         UART16550_BAUD_9600             9600
-#define         UART16550_BAUD_19200            19200
-#define         UART16550_BAUD_38400            38400
-#define         UART16550_BAUD_57600            57600
-#define         UART16550_BAUD_115200           115200
-
-#define         UART16550_PARITY_NONE           0
-#define         UART16550_PARITY_ODD            0x08
-#define         UART16550_PARITY_EVEN           0x18
-#define         UART16550_PARITY_MARK           0x28
-#define         UART16550_PARITY_SPACE          0x38
-
-#define         UART16550_DATA_5BIT             0x0
-#define         UART16550_DATA_6BIT             0x1
-#define         UART16550_DATA_7BIT             0x2
-#define         UART16550_DATA_8BIT             0x3
-
-#define         UART16550_STOP_1BIT             0x0
-#define         UART16550_STOP_2BIT             0x4
-
-/* ----------------------------------------------------- */
-
-/* === CONFIG === */
-#ifdef CONFIG_64BIT
-#define         BASE                    (0xffffffffbfd003f8)
-#else
-#define         BASE                    (0xbfd003f8)
-#endif
-
-#define         MAX_BAUD                BASE_BAUD
-/* === END OF CONFIG === */
-
-#define         REG_OFFSET              1
-
-/* register offset */
-#define         OFS_RCV_BUFFER          0
-#define         OFS_TRANS_HOLD          0
-#define         OFS_SEND_BUFFER         0
-#define         OFS_INTR_ENABLE         (1*REG_OFFSET)
-#define         OFS_INTR_ID             (2*REG_OFFSET)
-#define         OFS_DATA_FORMAT         (3*REG_OFFSET)
-#define         OFS_LINE_CONTROL        (3*REG_OFFSET)
-#define         OFS_MODEM_CONTROL       (4*REG_OFFSET)
-#define         OFS_RS232_OUTPUT        (4*REG_OFFSET)
-#define         OFS_LINE_STATUS         (5*REG_OFFSET)
-#define         OFS_MODEM_STATUS        (6*REG_OFFSET)
-#define         OFS_RS232_INPUT         (6*REG_OFFSET)
-#define         OFS_SCRATCH_PAD         (7*REG_OFFSET)
-
-#define         OFS_DIVISOR_LSB         (0*REG_OFFSET)
-#define         OFS_DIVISOR_MSB         (1*REG_OFFSET)
-
-/* memory-mapped read/write of the port */
-#define         UART16550_READ(y)      readb((char *)BASE + (y))
-#define         UART16550_WRITE(y, z)  writeb(z, (char *)BASE + (y))
-
-void debugInit(u32 baud, u8 data, u8 parity, u8 stop)
-{
-       u32 divisor;
-
-       /* disable interrupts */
-       UART16550_WRITE(OFS_INTR_ENABLE, 0);
-
-       /* set up buad rate */
-       /* set DIAB bit */
-       UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
-
-       /* set divisor */
-       divisor = MAX_BAUD / baud;
-       UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
-       UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
-
-       /* clear DIAB bit */
-       UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
-
-       /* set data format */
-       UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
-}
-
-static int remoteDebugInitialized;
-
-u8 getDebugChar(void)
-{
-       if (!remoteDebugInitialized) {
-               remoteDebugInitialized = 1;
-               debugInit(UART16550_BAUD_115200,
-                         UART16550_DATA_8BIT,
-                         UART16550_PARITY_NONE, UART16550_STOP_1BIT);
-       }
-
-       while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0) ;
-       return UART16550_READ(OFS_RCV_BUFFER);
-}
-
-int putDebugChar(u8 byte)
-{
-       if (!remoteDebugInitialized) {
-               remoteDebugInitialized = 1;
-               /*
-                  debugInit(UART16550_BAUD_115200,
-                  UART16550_DATA_8BIT,
-                  UART16550_PARITY_NONE, UART16550_STOP_1BIT); */
-       }
-
-       while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0) ;
-       UART16550_WRITE(OFS_SEND_BUFFER, byte);
-       return 1;
-}
diff --git a/arch/mips/lemote/lm2e/irq.c b/arch/mips/lemote/lm2e/irq.c
deleted file mode 100644 (file)
index 1d0a09f..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
- * Author: Fuxin Zhang, zhangfx@lemote.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.
- *
- */
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-
-#include <asm/irq_cpu.h>
-#include <asm/i8259.h>
-#include <asm/mipsregs.h>
-#include <asm/mips-boards/bonito64.h>
-
-
-/*
- * the first level int-handler will jump here if it is a bonito irq
- */
-static void bonito_irqdispatch(void)
-{
-       u32 int_status;
-       int i;
-
-       /* workaround the IO dma problem: let cpu looping to allow DMA finish */
-       int_status = BONITO_INTISR;
-       if (int_status & (1 << 10)) {
-               while (int_status & (1 << 10)) {
-                       udelay(1);
-                       int_status = BONITO_INTISR;
-               }
-       }
-
-       /* Get pending sources, masked by current enables */
-       int_status = BONITO_INTISR & BONITO_INTEN;
-
-       if (int_status != 0) {
-               i = __ffs(int_status);
-               int_status &= ~(1 << i);
-               do_IRQ(BONITO_IRQ_BASE + i);
-       }
-}
-
-static void i8259_irqdispatch(void)
-{
-       int irq;
-
-       irq = i8259_irq();
-       if (irq >= 0) {
-               do_IRQ(irq);
-       } else {
-               spurious_interrupt();
-       }
-
-}
-
-asmlinkage void plat_irq_dispatch(void)
-{
-       unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
-
-       if (pending & CAUSEF_IP7) {
-               do_IRQ(MIPS_CPU_IRQ_BASE + 7);
-       } else if (pending & CAUSEF_IP5) {
-               i8259_irqdispatch();
-       } else if (pending & CAUSEF_IP2) {
-               bonito_irqdispatch();
-       } else {
-               spurious_interrupt();
-       }
-}
-
-static struct irqaction cascade_irqaction = {
-       .handler = no_action,
-       .name = "cascade",
-};
-
-void __init arch_init_irq(void)
-{
-       extern void bonito_irq_init(void);
-
-       /*
-        * Clear all of the interrupts while we change the able around a bit.
-        * int-handler is not on bootstrap
-        */
-       clear_c0_status(ST0_IM | ST0_BEV);
-       local_irq_disable();
-
-       /* most bonito irq should be level triggered */
-       BONITO_INTEDGE = BONITO_ICU_SYSTEMERR | BONITO_ICU_MASTERERR |
-               BONITO_ICU_RETRYERR | BONITO_ICU_MBOXES;
-       BONITO_INTSTEER = 0;
-
-       /*
-        * Mask out all interrupt by writing "1" to all bit position in
-        * the interrupt reset reg.
-        */
-       BONITO_INTENCLR = ~0;
-
-       /* init all controller
-        *   0-15         ------> i8259 interrupt
-        *   16-23        ------> mips cpu interrupt
-        *   32-63        ------> bonito irq
-        */
-
-       /* Sets the first-level interrupt dispatcher. */
-       mips_cpu_irq_init();
-       init_i8259_irqs();
-       bonito_irq_init();
-
-       /*
-       printk("GPIODATA=%x, GPIOIE=%x\n", BONITO_GPIODATA, BONITO_GPIOIE);
-       printk("INTEN=%x, INTSET=%x, INTCLR=%x, INTISR=%x\n",
-                       BONITO_INTEN, BONITO_INTENSET,
-                       BONITO_INTENCLR, BONITO_INTISR);
-       */
-
-       /* bonito irq at IP2 */
-       setup_irq(MIPS_CPU_IRQ_BASE + 2, &cascade_irqaction);
-       /* 8259 irq at IP5 */
-       setup_irq(MIPS_CPU_IRQ_BASE + 5, &cascade_irqaction);
-
-}
diff --git a/arch/mips/lemote/lm2e/mem.c b/arch/mips/lemote/lm2e/mem.c
deleted file mode 100644 (file)
index 16cd215..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * This 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/fs.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-
-/* override of arch/mips/mm/cache.c: __uncached_access */
-int __uncached_access(struct file *file, unsigned long addr)
-{
-       if (file->f_flags & O_SYNC)
-               return 1;
-
-       /*
-        * On the Lemote Loongson 2e system, the peripheral registers
-        * reside between 0x1000:0000 and 0x2000:0000.
-        */
-       return addr >= __pa(high_memory) ||
-               ((addr >= 0x10000000) && (addr < 0x20000000));
-}
diff --git a/arch/mips/lemote/lm2e/pci.c b/arch/mips/lemote/lm2e/pci.c
deleted file mode 100644 (file)
index 8be03a8..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * pci.c
- *
- * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
- * Author: Fuxin Zhang, zhangfx@lemote.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.
- *
- */
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <asm/mips-boards/bonito64.h>
-#include <asm/mach-lemote/pci.h>
-
-extern struct pci_ops bonito64_pci_ops;
-
-static struct resource loongson2e_pci_mem_resource = {
-       .name   = "LOONGSON2E PCI MEM",
-       .start  = LOONGSON2E_PCI_MEM_START,
-       .end    = LOONGSON2E_PCI_MEM_END,
-       .flags  = IORESOURCE_MEM,
-};
-
-static struct resource loongson2e_pci_io_resource = {
-       .name   = "LOONGSON2E PCI IO MEM",
-       .start  = LOONGSON2E_PCI_IO_START,
-       .end    = IO_SPACE_LIMIT,
-       .flags  = IORESOURCE_IO,
-};
-
-static struct pci_controller  loongson2e_pci_controller = {
-       .pci_ops        = &bonito64_pci_ops,
-       .io_resource    = &loongson2e_pci_io_resource,
-       .mem_resource   = &loongson2e_pci_mem_resource,
-       .mem_offset     = 0x00000000UL,
-       .io_offset      = 0x00000000UL,
-};
-
-static void __init ict_pcimap(void)
-{
-       /*
-        * local to PCI mapping: [256M,512M] -> [256M,512M]; differ from PMON
-        *
-        * CPU address space [256M,448M] is window for accessing pci space
-        * we set pcimap_lo[0,1,2] to map it to pci space [256M,448M]
-        * pcimap: bit18,pcimap_2; bit[17-12],lo2;bit[11-6],lo1;bit[5-0],lo0
-        */
-       /* 1,00 0110 ,0001 01,00 0000 */
-       BONITO_PCIMAP = 0x46140;
-
-       /* 1, 00 0010, 0000,01, 00 0000 */
-       /* BONITO_PCIMAP = 0x42040; */
-
-       /*
-        * PCI to local mapping: [2G,2G+256M] -> [0,256M]
-        */
-       BONITO_PCIBASE0 = 0x80000000;
-       BONITO_PCIBASE1 = 0x00800000;
-       BONITO_PCIBASE2 = 0x90000000;
-
-}
-
-static int __init pcibios_init(void)
-{
-       ict_pcimap();
-
-       loongson2e_pci_controller.io_map_base =
-           (unsigned long) ioremap(LOONGSON2E_IO_PORT_BASE,
-                                   loongson2e_pci_io_resource.end -
-                                   loongson2e_pci_io_resource.start + 1);
-
-       register_pci_controller(&loongson2e_pci_controller);
-
-       return 0;
-}
-
-arch_initcall(pcibios_init);
diff --git a/arch/mips/lemote/lm2e/prom.c b/arch/mips/lemote/lm2e/prom.c
deleted file mode 100644 (file)
index 7edc15d..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Based on Ocelot Linux port, which is
- * Copyright 2001 MontaVista Software Inc.
- * Author: jsun@mvista.com or jsun@junsun.net
- *
- * Copyright 2003 ICT CAS
- * Author: Michael Guo <guoyi@ict.ac.cn>
- *
- * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
- * Author: Fuxin Zhang, zhangfx@lemote.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/bootmem.h>
-#include <asm/bootinfo.h>
-
-extern unsigned long bus_clock;
-extern unsigned long cpu_clock_freq;
-extern unsigned int memsize, highmemsize;
-extern int putDebugChar(unsigned char byte);
-
-static int argc;
-/* pmon passes arguments in 32bit pointers */
-static int *arg;
-static int *env;
-
-const char *get_system_type(void)
-{
-       return "lemote-fulong";
-}
-
-void __init prom_init_cmdline(void)
-{
-       int i;
-       long l;
-
-       /* arg[0] is "g", the rest is boot parameters */
-       arcs_cmdline[0] = '\0';
-       for (i = 1; i < argc; i++) {
-               l = (long)arg[i];
-               if (strlen(arcs_cmdline) + strlen(((char *)l) + 1)
-                   >= sizeof(arcs_cmdline))
-                       break;
-               strcat(arcs_cmdline, ((char *)l));
-               strcat(arcs_cmdline, " ");
-       }
-}
-
-void __init prom_init(void)
-{
-       long l;
-       argc = fw_arg0;
-       arg = (int *)fw_arg1;
-       env = (int *)fw_arg2;
-
-       prom_init_cmdline();
-
-       if ((strstr(arcs_cmdline, "console=")) == NULL)
-               strcat(arcs_cmdline, " console=ttyS0,115200");
-       if ((strstr(arcs_cmdline, "root=")) == NULL)
-               strcat(arcs_cmdline, " root=/dev/hda1");
-
-#define parse_even_earlier(res, option, p)                             \
-do {                                                                   \
-       if (strncmp(option, (char *)p, strlen(option)) == 0)            \
-               res = simple_strtol((char *)p + strlen(option"="),      \
-                                   NULL, 10);                          \
-} while (0)
-
-       l = (long)*env;
-       while (l != 0) {
-               parse_even_earlier(bus_clock, "busclock", l);
-               parse_even_earlier(cpu_clock_freq, "cpuclock", l);
-               parse_even_earlier(memsize, "memsize", l);
-               parse_even_earlier(highmemsize, "highmemsize", l);
-               env++;
-               l = (long)*env;
-       }
-       if (memsize == 0)
-               memsize = 256;
-
-       pr_info("busclock=%ld, cpuclock=%ld,memsize=%d,highmemsize=%d\n",
-              bus_clock, cpu_clock_freq, memsize, highmemsize);
-}
-
-void __init prom_free_prom_memory(void)
-{
-}
-
-void prom_putchar(char c)
-{
-       putDebugChar(c);
-}
diff --git a/arch/mips/lemote/lm2e/reset.c b/arch/mips/lemote/lm2e/reset.c
deleted file mode 100644 (file)
index 099387a..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- *
- * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
- * Author: Fuxin Zhang, zhangfx@lemote.com
- */
-#include <linux/pm.h>
-
-#include <asm/reboot.h>
-
-static void loongson2e_restart(char *command)
-{
-#ifdef CONFIG_32BIT
-       *(unsigned long *)0xbfe00104 &= ~(1 << 2);
-       *(unsigned long *)0xbfe00104 |= (1 << 2);
-#else
-       *(unsigned long *)0xffffffffbfe00104 &= ~(1 << 2);
-       *(unsigned long *)0xffffffffbfe00104 |= (1 << 2);
-#endif
-       __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
-}
-
-static void loongson2e_halt(void)
-{
-       while (1) ;
-}
-
-static void loongson2e_power_off(void)
-{
-       loongson2e_halt();
-}
-
-void mips_reboot_setup(void)
-{
-       _machine_restart = loongson2e_restart;
-       _machine_halt = loongson2e_halt;
-       pm_power_off = loongson2e_power_off;
-}
diff --git a/arch/mips/lemote/lm2e/setup.c b/arch/mips/lemote/lm2e/setup.c
deleted file mode 100644 (file)
index ebd6cea..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- * setup.c - board dependent boot routines
- *
- * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
- * Author: Fuxin Zhang, zhangfx@lemote.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.
- *
- */
-#include <linux/bootmem.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-
-#include <asm/bootinfo.h>
-#include <asm/mc146818-time.h>
-#include <asm/time.h>
-#include <asm/wbflush.h>
-#include <asm/mach-lemote/pci.h>
-
-#ifdef CONFIG_VT
-#include <linux/console.h>
-#include <linux/screen_info.h>
-#endif
-
-extern void mips_reboot_setup(void);
-
-unsigned long cpu_clock_freq;
-unsigned long bus_clock;
-unsigned int memsize;
-unsigned int highmemsize = 0;
-
-void __init plat_time_init(void)
-{
-       /* setup mips r4k timer */
-       mips_hpt_frequency = cpu_clock_freq / 2;
-}
-
-unsigned long read_persistent_clock(void)
-{
-       return mc146818_get_cmos_time();
-}
-
-void (*__wbflush)(void);
-EXPORT_SYMBOL(__wbflush);
-
-static void wbflush_loongson2e(void)
-{
-       asm(".set\tpush\n\t"
-           ".set\tnoreorder\n\t"
-           ".set mips3\n\t"
-           "sync\n\t"
-           "nop\n\t"
-           ".set\tpop\n\t"
-           ".set mips0\n\t");
-}
-
-void __init plat_mem_setup(void)
-{
-       set_io_port_base((unsigned long)ioremap(LOONGSON2E_IO_PORT_BASE,
-                               IO_SPACE_LIMIT - LOONGSON2E_PCI_IO_START + 1));
-       mips_reboot_setup();
-
-       __wbflush = wbflush_loongson2e;
-
-       add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM);
-#ifdef CONFIG_64BIT
-       if (highmemsize > 0) {
-               add_memory_region(0x20000000, highmemsize << 20, BOOT_MEM_RAM);
-       }
-#endif
-
-#ifdef CONFIG_VT
-#if defined(CONFIG_VGA_CONSOLE)
-       conswitchp = &vga_con;
-
-       screen_info = (struct screen_info) {
-               0, 25,          /* orig-x, orig-y */
-                   0,          /* unused */
-                   0,          /* orig-video-page */
-                   0,          /* orig-video-mode */
-                   80,         /* orig-video-cols */
-                   0, 0, 0,    /* ega_ax, ega_bx, ega_cx */
-                   25,         /* orig-video-lines */
-                   VIDEO_TYPE_VGAC,    /* orig-video-isVGA */
-                   16          /* orig-video-points */
-       };
-#elif defined(CONFIG_DUMMY_CONSOLE)
-       conswitchp = &dummy_con;
-#endif
-#endif
-
-}
diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig
new file mode 100644 (file)
index 0000000..d450925
--- /dev/null
@@ -0,0 +1,31 @@
+choice
+    prompt "Machine Type"
+    depends on MACH_LOONGSON
+
+config LEMOTE_FULOONG2E
+    bool "Lemote Fuloong(2e) mini-PC"
+    select ARCH_SPARSEMEM_ENABLE
+    select CEVT_R4K
+    select CSRC_R4K
+    select SYS_HAS_CPU_LOONGSON2E
+    select DMA_NONCOHERENT
+    select BOOT_ELF32
+    select BOARD_SCACHE
+    select HW_HAS_PCI
+    select I8259
+    select ISA
+    select IRQ_CPU
+    select SYS_SUPPORTS_32BIT_KERNEL
+    select SYS_SUPPORTS_64BIT_KERNEL
+    select SYS_SUPPORTS_LITTLE_ENDIAN
+    select SYS_SUPPORTS_HIGHMEM
+    select SYS_HAS_EARLY_PRINTK
+    select GENERIC_HARDIRQS_NO__DO_IRQ
+    select GENERIC_ISA_DMA_SUPPORT_BROKEN
+    select CPU_HAS_WB
+    help
+      Lemote Fuloong(2e) mini-PC board based on the Chinese Loongson-2E CPU and
+      an FPGA northbridge
+
+      Lemote Fuloong(2e) mini PC have a VIA686B south bridge.
+endchoice
diff --git a/arch/mips/loongson/Makefile b/arch/mips/loongson/Makefile
new file mode 100644 (file)
index 0000000..39048c4
--- /dev/null
@@ -0,0 +1,11 @@
+#
+# Common code for all Loongson based systems
+#
+
+obj-$(CONFIG_MACH_LOONGSON) += common/
+
+#
+# Lemote Fuloong mini-PC (Loongson 2E-based)
+#
+
+obj-$(CONFIG_LEMOTE_FULOONG2E)  += fuloong-2e/
diff --git a/arch/mips/loongson/common/Makefile b/arch/mips/loongson/common/Makefile
new file mode 100644 (file)
index 0000000..656b3cc
--- /dev/null
@@ -0,0 +1,11 @@
+#
+# Makefile for loongson based machines.
+#
+
+obj-y += setup.o init.o cmdline.o env.o time.o reset.o irq.o \
+    pci.o bonito-irq.o mem.o machtype.o
+
+#
+# Early printk support
+#
+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
diff --git a/arch/mips/loongson/common/bonito-irq.c b/arch/mips/loongson/common/bonito-irq.c
new file mode 100644 (file)
index 0000000..3e31e7a
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org)
+ *
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.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/interrupt.h>
+
+#include <loongson.h>
+
+static inline void bonito_irq_enable(unsigned int irq)
+{
+       BONITO_INTENSET = (1 << (irq - BONITO_IRQ_BASE));
+       mmiowb();
+}
+
+static inline void bonito_irq_disable(unsigned int irq)
+{
+       BONITO_INTENCLR = (1 << (irq - BONITO_IRQ_BASE));
+       mmiowb();
+}
+
+static struct irq_chip bonito_irq_type = {
+       .name   = "bonito_irq",
+       .ack    = bonito_irq_disable,
+       .mask   = bonito_irq_disable,
+       .mask_ack = bonito_irq_disable,
+       .unmask = bonito_irq_enable,
+};
+
+static struct irqaction dma_timeout_irqaction = {
+       .handler        = no_action,
+       .name           = "dma_timeout",
+};
+
+void bonito_irq_init(void)
+{
+       u32 i;
+
+       for (i = BONITO_IRQ_BASE; i < BONITO_IRQ_BASE + 32; i++)
+               set_irq_chip_and_handler(i, &bonito_irq_type, handle_level_irq);
+
+       setup_irq(BONITO_IRQ_BASE + 10, &dma_timeout_irqaction);
+}
diff --git a/arch/mips/loongson/common/cmdline.c b/arch/mips/loongson/common/cmdline.c
new file mode 100644 (file)
index 0000000..75f1b24
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Based on Ocelot Linux port, which is
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * Copyright 2003 ICT CAS
+ * Author: Michael Guo <guoyi@ict.ac.cn>
+ *
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
+ * Author: Wu Zhangjin, wuzj@lemote.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 <asm/bootinfo.h>
+
+#include <loongson.h>
+
+int prom_argc;
+/* pmon passes arguments in 32bit pointers */
+int *_prom_argv;
+
+void __init prom_init_cmdline(void)
+{
+       int i;
+       long l;
+
+       /* firmware arguments are initialized in head.S */
+       prom_argc = fw_arg0;
+       _prom_argv = (int *)fw_arg1;
+
+       /* arg[0] is "g", the rest is boot parameters */
+       arcs_cmdline[0] = '\0';
+       for (i = 1; i < prom_argc; i++) {
+               l = (long)_prom_argv[i];
+               if (strlen(arcs_cmdline) + strlen(((char *)l) + 1)
+                   >= sizeof(arcs_cmdline))
+                       break;
+               strcat(arcs_cmdline, ((char *)l));
+               strcat(arcs_cmdline, " ");
+       }
+
+       if ((strstr(arcs_cmdline, "console=")) == NULL)
+               strcat(arcs_cmdline, " console=ttyS0,115200");
+       if ((strstr(arcs_cmdline, "root=")) == NULL)
+               strcat(arcs_cmdline, " root=/dev/hda1");
+}
diff --git a/arch/mips/loongson/common/early_printk.c b/arch/mips/loongson/common/early_printk.c
new file mode 100644 (file)
index 0000000..bc73edc
--- /dev/null
@@ -0,0 +1,38 @@
+/*  early printk support
+ *
+ *  Copyright (c) 2009 Philippe Vachon <philippe@cowpig.ca>
+ *  Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
+ *  Author: Wu Zhangjin, wuzj@lemote.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/serial_reg.h>
+
+#include <loongson.h>
+#include <machine.h>
+
+#define PORT(base, offset) (u8 *)(base + offset)
+
+static inline unsigned int serial_in(phys_addr_t base, int offset)
+{
+       return readb(PORT(base, offset));
+}
+
+static inline void serial_out(phys_addr_t base, int offset, int value)
+{
+       writeb(value, PORT(base, offset));
+}
+
+void prom_putchar(char c)
+{
+       phys_addr_t uart_base =
+               (phys_addr_t) ioremap_nocache(LOONGSON_UART_BASE, 8);
+
+       while ((serial_in(uart_base, UART_LSR) & UART_LSR_THRE) == 0)
+               ;
+
+       serial_out(uart_base, UART_TX, c);
+}
diff --git a/arch/mips/loongson/common/env.c b/arch/mips/loongson/common/env.c
new file mode 100644 (file)
index 0000000..b9ef503
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Based on Ocelot Linux port, which is
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * Copyright 2003 ICT CAS
+ * Author: Michael Guo <guoyi@ict.ac.cn>
+ *
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
+ * Author: Wu Zhangjin, wuzj@lemote.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 <asm/bootinfo.h>
+
+#include <loongson.h>
+
+unsigned long bus_clock, cpu_clock_freq;
+unsigned long memsize, highmemsize;
+
+/* pmon passes arguments in 32bit pointers */
+int *_prom_envp;
+
+#define parse_even_earlier(res, option, p)                             \
+do {                                                                   \
+       if (strncmp(option, (char *)p, strlen(option)) == 0)            \
+                       strict_strtol((char *)p + strlen(option"="),    \
+                                       10, &res);                      \
+} while (0)
+
+void __init prom_init_env(void)
+{
+       long l;
+
+       /* firmware arguments are initialized in head.S */
+       _prom_envp = (int *)fw_arg2;
+
+       l = (long)*_prom_envp;
+       while (l != 0) {
+               parse_even_earlier(bus_clock, "busclock", l);
+               parse_even_earlier(cpu_clock_freq, "cpuclock", l);
+               parse_even_earlier(memsize, "memsize", l);
+               parse_even_earlier(highmemsize, "highmemsize", l);
+               _prom_envp++;
+               l = (long)*_prom_envp;
+       }
+       if (memsize == 0)
+               memsize = 256;
+
+       pr_info("busclock=%ld, cpuclock=%ld, memsize=%ld, highmemsize=%ld\n",
+               bus_clock, cpu_clock_freq, memsize, highmemsize);
+}
diff --git a/arch/mips/loongson/common/init.c b/arch/mips/loongson/common/init.c
new file mode 100644 (file)
index 0000000..3abe927
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
+ * Author: Wu Zhangjin, wuzj@lemote.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/bootmem.h>
+
+#include <asm/bootinfo.h>
+
+#include <loongson.h>
+
+void __init prom_init(void)
+{
+    /* init base address of io space */
+       set_io_port_base((unsigned long)
+               ioremap(BONITO_PCIIO_BASE, BONITO_PCIIO_SIZE));
+
+       prom_init_cmdline();
+       prom_init_env();
+       prom_init_memory();
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
diff --git a/arch/mips/loongson/common/irq.c b/arch/mips/loongson/common/irq.c
new file mode 100644 (file)
index 0000000..f368c73
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.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/delay.h>
+#include <linux/interrupt.h>
+
+#include <loongson.h>
+/*
+ * the first level int-handler will jump here if it is a bonito irq
+ */
+void bonito_irqdispatch(void)
+{
+       u32 int_status;
+       int i;
+
+       /* workaround the IO dma problem: let cpu looping to allow DMA finish */
+       int_status = BONITO_INTISR;
+       if (int_status & (1 << 10)) {
+               while (int_status & (1 << 10)) {
+                       udelay(1);
+                       int_status = BONITO_INTISR;
+               }
+       }
+
+       /* Get pending sources, masked by current enables */
+       int_status = BONITO_INTISR & BONITO_INTEN;
+
+       if (int_status != 0) {
+               i = __ffs(int_status);
+               int_status &= ~(1 << i);
+               do_IRQ(BONITO_IRQ_BASE + i);
+       }
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+       unsigned int pending;
+
+       pending = read_c0_cause() & read_c0_status() & ST0_IM;
+
+       /* machine-specific plat_irq_dispatch */
+       mach_irq_dispatch(pending);
+}
+
+void __init arch_init_irq(void)
+{
+       /*
+        * Clear all of the interrupts while we change the able around a bit.
+        * int-handler is not on bootstrap
+        */
+       clear_c0_status(ST0_IM | ST0_BEV);
+       local_irq_disable();
+
+       /* setting irq trigger mode */
+       set_irq_trigger_mode();
+
+       /* no steer */
+       BONITO_INTSTEER = 0;
+
+       /*
+        * Mask out all interrupt by writing "1" to all bit position in
+        * the interrupt reset reg.
+        */
+       BONITO_INTENCLR = ~0;
+
+       /* machine specific irq init */
+       mach_init_irq();
+}
diff --git a/arch/mips/loongson/common/machtype.c b/arch/mips/loongson/common/machtype.c
new file mode 100644 (file)
index 0000000..7b34824
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
+ * Author: Wu Zhangjin, wuzj@lemote.com
+ *
+ * Copyright (c) 2009 Zhang Le <r0bertz@gentoo.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.
+ */
+#include <linux/errno.h>
+#include <asm/bootinfo.h>
+
+#include <loongson.h>
+#include <machine.h>
+
+static const char *system_types[] = {
+       [MACH_LOONGSON_UNKNOWN]         "unknown loongson machine",
+       [MACH_LEMOTE_FL2E]              "lemote-fuloong-2e-box",
+       [MACH_LEMOTE_FL2F]              "lemote-fuloong-2f-box",
+       [MACH_LEMOTE_ML2F7]             "lemote-mengloong-2f-7inches",
+       [MACH_LEMOTE_YL2F89]            "lemote-yeeloong-2f-8.9inches",
+       [MACH_DEXXON_GDIUM2F10]         "dexxon-gidum-2f-10inches",
+       [MACH_LOONGSON_END]             NULL,
+};
+
+const char *get_system_type(void)
+{
+       if (mips_machtype == MACH_UNKNOWN)
+               mips_machtype = LOONGSON_MACHTYPE;
+
+       return system_types[mips_machtype];
+}
+
+static __init int machtype_setup(char *str)
+{
+       int machtype = MACH_LEMOTE_FL2E;
+
+       if (!str)
+               return -EINVAL;
+
+       for (; system_types[machtype]; machtype++)
+               if (strstr(system_types[machtype], str)) {
+                       mips_machtype = machtype;
+                       break;
+               }
+       return 0;
+}
+__setup("machtype=", machtype_setup);
diff --git a/arch/mips/loongson/common/mem.c b/arch/mips/loongson/common/mem.c
new file mode 100644 (file)
index 0000000..7c92f79
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * This 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/fs.h>
+#include <linux/fcntl.h>
+#include <linux/mm.h>
+
+#include <asm/bootinfo.h>
+
+#include <loongson.h>
+#include <mem.h>
+
+void __init prom_init_memory(void)
+{
+    add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM);
+#ifdef CONFIG_64BIT
+    if (highmemsize > 0)
+       add_memory_region(LOONGSON_HIGHMEM_START,
+               highmemsize << 20, BOOT_MEM_RAM);
+#endif /* CONFIG_64BIT */
+}
+
+/* override of arch/mips/mm/cache.c: __uncached_access */
+int __uncached_access(struct file *file, unsigned long addr)
+{
+       if (file->f_flags & O_SYNC)
+               return 1;
+
+       return addr >= __pa(high_memory) ||
+               ((addr >= LOONGSON_MMIO_MEM_START) &&
+                (addr < LOONGSON_MMIO_MEM_END));
+}
diff --git a/arch/mips/loongson/common/pci.c b/arch/mips/loongson/common/pci.c
new file mode 100644 (file)
index 0000000..a3a4abf
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.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/pci.h>
+
+#include <pci.h>
+#include <loongson.h>
+
+static struct resource loongson_pci_mem_resource = {
+       .name   = "pci memory space",
+       .start  = LOONGSON_PCI_MEM_START,
+       .end    = LOONGSON_PCI_MEM_END,
+       .flags  = IORESOURCE_MEM,
+};
+
+static struct resource loongson_pci_io_resource = {
+       .name   = "pci io space",
+       .start  = LOONGSON_PCI_IO_START,
+       .end    = IO_SPACE_LIMIT,
+       .flags  = IORESOURCE_IO,
+};
+
+static struct pci_controller  loongson_pci_controller = {
+       .pci_ops        = &bonito64_pci_ops,
+       .io_resource    = &loongson_pci_io_resource,
+       .mem_resource   = &loongson_pci_mem_resource,
+       .mem_offset     = 0x00000000UL,
+       .io_offset      = 0x00000000UL,
+};
+
+static void __init setup_pcimap(void)
+{
+       /*
+        * local to PCI mapping for CPU accessing PCI space
+        * CPU address space [256M,448M] is window for accessing pci space
+        * we set pcimap_lo[0,1,2] to map it to pci space[0M,64M], [320M,448M]
+        *
+        * pcimap: PCI_MAP2  PCI_Mem_Lo2 PCI_Mem_Lo1 PCI_Mem_Lo0
+        *           [<2G]   [384M,448M] [320M,384M] [0M,64M]
+        */
+       BONITO_PCIMAP = BONITO_PCIMAP_PCIMAP_2 |
+               BONITO_PCIMAP_WIN(2, BONITO_PCILO2_BASE) |
+               BONITO_PCIMAP_WIN(1, BONITO_PCILO1_BASE) |
+               BONITO_PCIMAP_WIN(0, 0);
+
+       /*
+        * PCI-DMA to local mapping: [2G,2G+256M] -> [0M,256M]
+        */
+       BONITO_PCIBASE0 = 0x80000000ul;   /* base: 2G -> mmap: 0M */
+       /* size: 256M, burst transmission, pre-fetch enable, 64bit */
+       LOONGSON_PCI_HIT0_SEL_L = 0xc000000cul;
+       LOONGSON_PCI_HIT0_SEL_H = 0xfffffffful;
+       LOONGSON_PCI_HIT1_SEL_L = 0x00000006ul; /* set this BAR as invalid */
+       LOONGSON_PCI_HIT1_SEL_H = 0x00000000ul;
+       LOONGSON_PCI_HIT2_SEL_L = 0x00000006ul; /* set this BAR as invalid */
+       LOONGSON_PCI_HIT2_SEL_H = 0x00000000ul;
+
+       /* avoid deadlock of PCI reading/writing lock operation */
+       LOONGSON_PCI_ISR4C = 0xd2000001ul;
+
+       /* can not change gnt to break pci transfer when device's gnt not
+       deassert for some broken device */
+       LOONGSON_PXARB_CFG = 0x00fe0105ul;
+}
+
+static int __init pcibios_init(void)
+{
+       setup_pcimap();
+
+       loongson_pci_controller.io_map_base = mips_io_port_base;
+
+       register_pci_controller(&loongson_pci_controller);
+
+       return 0;
+}
+
+arch_initcall(pcibios_init);
diff --git a/arch/mips/loongson/common/reset.c b/arch/mips/loongson/common/reset.c
new file mode 100644 (file)
index 0000000..97e9182
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology
+ * Author: Zhangjin Wu, wuzj@lemote.com
+ */
+#include <linux/init.h>
+#include <linux/pm.h>
+
+#include <asm/reboot.h>
+
+#include <loongson.h>
+
+static void loongson_restart(char *command)
+{
+       /* do preparation for reboot */
+       mach_prepare_reboot();
+
+       /* reboot via jumping to boot base address */
+       ((void (*)(void))ioremap_nocache(BONITO_BOOT_BASE, 4)) ();
+}
+
+static void loongson_halt(void)
+{
+       mach_prepare_shutdown();
+       while (1)
+               ;
+}
+
+static int __init mips_reboot_setup(void)
+{
+       _machine_restart = loongson_restart;
+       _machine_halt = loongson_halt;
+       pm_power_off = loongson_halt;
+
+       return 0;
+}
+
+arch_initcall(mips_reboot_setup);
diff --git a/arch/mips/loongson/common/setup.c b/arch/mips/loongson/common/setup.c
new file mode 100644 (file)
index 0000000..4cd2aa9
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.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/module.h>
+
+#include <asm/wbflush.h>
+
+#include <loongson.h>
+
+#ifdef CONFIG_VT
+#include <linux/console.h>
+#include <linux/screen_info.h>
+#endif
+
+void (*__wbflush)(void);
+EXPORT_SYMBOL(__wbflush);
+
+static void wbflush_loongson(void)
+{
+       asm(".set\tpush\n\t"
+           ".set\tnoreorder\n\t"
+           ".set mips3\n\t"
+           "sync\n\t"
+           "nop\n\t"
+           ".set\tpop\n\t"
+           ".set mips0\n\t");
+}
+
+void __init plat_mem_setup(void)
+{
+       __wbflush = wbflush_loongson;
+
+#ifdef CONFIG_VT
+#if defined(CONFIG_VGA_CONSOLE)
+       conswitchp = &vga_con;
+
+       screen_info = (struct screen_info) {
+               0, 25,          /* orig-x, orig-y */
+                   0,          /* unused */
+                   0,          /* orig-video-page */
+                   0,          /* orig-video-mode */
+                   80,         /* orig-video-cols */
+                   0, 0, 0,    /* ega_ax, ega_bx, ega_cx */
+                   25,         /* orig-video-lines */
+                   VIDEO_TYPE_VGAC,    /* orig-video-isVGA */
+                   16          /* orig-video-points */
+       };
+#elif defined(CONFIG_DUMMY_CONSOLE)
+       conswitchp = &dummy_con;
+#endif
+#endif
+}
diff --git a/arch/mips/loongson/common/time.c b/arch/mips/loongson/common/time.c
new file mode 100644 (file)
index 0000000..0edbef3
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
+ * Author: Wu Zhangjin, wuzj@lemote.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 <asm/mc146818-time.h>
+#include <asm/time.h>
+
+#include <loongson.h>
+
+void __init plat_time_init(void)
+{
+       /* setup mips r4k timer */
+       mips_hpt_frequency = cpu_clock_freq / 2;
+}
+
+void read_persistent_clock(struct timespec *ts)
+{
+       ts->tv_sec = return mc146818_get_cmos_time();
+       ts->tv_nsec = 0;
+}
diff --git a/arch/mips/loongson/fuloong-2e/Makefile b/arch/mips/loongson/fuloong-2e/Makefile
new file mode 100644 (file)
index 0000000..3aba5fc
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# Makefile for Lemote Fuloong2e mini-PC board.
+#
+
+obj-y += irq.o reset.o
+
+EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/loongson/fuloong-2e/irq.c b/arch/mips/loongson/fuloong-2e/irq.c
new file mode 100644 (file)
index 0000000..7888cf6
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.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/interrupt.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/i8259.h>
+
+#include <loongson.h>
+
+static void i8259_irqdispatch(void)
+{
+       int irq;
+
+       irq = i8259_irq();
+       if (irq >= 0)
+               do_IRQ(irq);
+       else
+               spurious_interrupt();
+}
+
+asmlinkage void mach_irq_dispatch(unsigned int pending)
+{
+       if (pending & CAUSEF_IP7)
+               do_IRQ(MIPS_CPU_IRQ_BASE + 7);
+       else if (pending & CAUSEF_IP6) /* perf counter loverflow */
+               do_IRQ(LOONGSON2_PERFCNT_IRQ);
+       else if (pending & CAUSEF_IP5)
+               i8259_irqdispatch();
+       else if (pending & CAUSEF_IP2)
+               bonito_irqdispatch();
+       else
+               spurious_interrupt();
+}
+
+static struct irqaction cascade_irqaction = {
+       .handler = no_action,
+       .name = "cascade",
+};
+
+void __init set_irq_trigger_mode(void)
+{
+       /* most bonito irq should be level triggered */
+       BONITO_INTEDGE = BONITO_ICU_SYSTEMERR | BONITO_ICU_MASTERERR |
+           BONITO_ICU_RETRYERR | BONITO_ICU_MBOXES;
+}
+
+void __init mach_init_irq(void)
+{
+       /* init all controller
+        *   0-15         ------> i8259 interrupt
+        *   16-23        ------> mips cpu interrupt
+        *   32-63        ------> bonito irq
+        */
+
+       /* Sets the first-level interrupt dispatcher. */
+       mips_cpu_irq_init();
+       init_i8259_irqs();
+       bonito_irq_init();
+
+       /* bonito irq at IP2 */
+       setup_irq(MIPS_CPU_IRQ_BASE + 2, &cascade_irqaction);
+       /* 8259 irq at IP5 */
+       setup_irq(MIPS_CPU_IRQ_BASE + 5, &cascade_irqaction);
+}
diff --git a/arch/mips/loongson/fuloong-2e/reset.c b/arch/mips/loongson/fuloong-2e/reset.c
new file mode 100644 (file)
index 0000000..677fe18
--- /dev/null
@@ -0,0 +1,23 @@
+/* Board-specific reboot/shutdown routines
+ * Copyright (c) 2009 Philippe Vachon <philippe@cowpig.ca>
+ *
+ * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
+ * Author: Wu Zhangjin, wuzj@lemote.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 <loongson.h>
+
+void mach_prepare_reboot(void)
+{
+       BONITO_BONGENCFG &= ~(1 << 2);
+       BONITO_BONGENCFG |= (1 << 2);
+}
+
+void mach_prepare_shutdown(void)
+{
+}
index 7c7148ef26463f5d159ef7ceaf538ecceb8b0dde..2877675c5f0ddc11f23e98a73bcbea8a855d8348 100644 (file)
@@ -37,7 +37,7 @@
 
 
 static void __init serial_init(void);
-unsigned int _isbonito = 0;
+unsigned int _isbonito;
 
 const char *get_system_type(void)
 {
index f956ecbb81363af8a55b4d0179e7b3b9abc50ca8..e97a7a2fb2c0980346c75791fce09b4026ee334b 100644 (file)
@@ -58,11 +58,17 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
         * only copy the information from the master page table,
         * nothing more.
         */
+#ifdef CONFIG_64BIT
+# define VMALLOC_FAULT_TARGET no_context
+#else
+# define VMALLOC_FAULT_TARGET vmalloc_fault
+#endif
+
        if (unlikely(address >= VMALLOC_START && address <= VMALLOC_END))
-               goto vmalloc_fault;
+               goto VMALLOC_FAULT_TARGET;
 #ifdef MODULE_START
        if (unlikely(address >= MODULE_START && address < MODULE_END))
-               goto vmalloc_fault;
+               goto VMALLOC_FAULT_TARGET;
 #endif
 
        /*
@@ -203,6 +209,7 @@ do_sigbus:
        force_sig_info(SIGBUS, &info, tsk);
 
        return;
+#ifndef CONFIG_64BIT
 vmalloc_fault:
        {
                /*
@@ -241,4 +248,5 @@ vmalloc_fault:
                        goto no_context;
                return;
        }
+#endif
 }
index 0e820508ff23fd8bbfe8a4642c5f9acf1c3a9e73..38c79c55b060f3dcccfb4637f9eb33a44668b490 100644 (file)
@@ -475,9 +475,6 @@ unsigned long pgd_current[NR_CPUS];
  */
 pgd_t swapper_pg_dir[_PTRS_PER_PGD] __page_aligned(_PGD_ORDER);
 #ifdef CONFIG_64BIT
-#ifdef MODULE_START
-pgd_t module_pg_dir[PTRS_PER_PGD] __page_aligned(PGD_ORDER);
-#endif
 pmd_t invalid_pmd_table[PTRS_PER_PMD] __page_aligned(PMD_ORDER);
 #endif
 pte_t invalid_pte_table[PTRS_PER_PTE] __page_aligned(PTE_ORDER);
index e4b565aeb00807ec1c851c2ad665e1fb5b158255..1121019fa45652cb953dfd59014ee21b3fee430f 100644 (file)
@@ -59,9 +59,6 @@ void __init pagetable_init(void)
 
        /* Initialize the entire pgd.  */
        pgd_init((unsigned long)swapper_pg_dir);
-#ifdef MODULE_START
-       pgd_init((unsigned long)module_pg_dir);
-#endif
        pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table);
 
        pgd_base = swapper_pg_dir;
index cee502caf398403bef0365c7969b1ecfad6c8626..d73428b18b0a41da13e81c64021e62505200ff2d 100644 (file)
@@ -475,7 +475,7 @@ static void __cpuinit probe_tlb(unsigned long config)
        c->tlbsize = ((reg >> 25) & 0x3f) + 1;
 }
 
-static int __cpuinitdata ntlb = 0;
+static int __cpuinitdata ntlb;
 static int __init set_ntlb(char *str)
 {
        get_option(&str, &ntlb);
index 9a17bf8395df1c92be94a48a6820891623154fe6..bb1719a55d227dc595467aafd88173dc9507b937 100644 (file)
@@ -321,6 +321,10 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l,
        case CPU_BCM3302:
        case CPU_BCM4710:
        case CPU_LOONGSON2:
+       case CPU_BCM6338:
+       case CPU_BCM6345:
+       case CPU_BCM6348:
+       case CPU_BCM6358:
        case CPU_R5500:
                if (m4kc_tlbp_war())
                        uasm_i_nop(p);
@@ -499,11 +503,7 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
         * The vmalloc handling is not in the hotpath.
         */
        uasm_i_dmfc0(p, tmp, C0_BADVADDR);
-#ifdef MODULE_START
-       uasm_il_bltz(p, r, tmp, label_module_alloc);
-#else
        uasm_il_bltz(p, r, tmp, label_vmalloc);
-#endif
        /* No uasm_i_nop needed here, since the next insn doesn't touch TMP. */
 
 #ifdef CONFIG_SMP
@@ -556,52 +556,7 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
 {
        long swpd = (long)swapper_pg_dir;
 
-#ifdef MODULE_START
-       long modd = (long)module_pg_dir;
-
-       uasm_l_module_alloc(l, *p);
-       /*
-        * Assumption:
-        * VMALLOC_START >= 0xc000000000000000UL
-        * MODULE_START >= 0xe000000000000000UL
-        */
-       UASM_i_SLL(p, ptr, bvaddr, 2);
-       uasm_il_bgez(p, r, ptr, label_vmalloc);
-
-       if (uasm_in_compat_space_p(MODULE_START) &&
-           !uasm_rel_lo(MODULE_START)) {
-               uasm_i_lui(p, ptr, uasm_rel_hi(MODULE_START)); /* delay slot */
-       } else {
-               /* unlikely configuration */
-               uasm_i_nop(p); /* delay slot */
-               UASM_i_LA(p, ptr, MODULE_START);
-       }
-       uasm_i_dsubu(p, bvaddr, bvaddr, ptr);
-
-       if (uasm_in_compat_space_p(modd) && !uasm_rel_lo(modd)) {
-               uasm_il_b(p, r, label_vmalloc_done);
-               uasm_i_lui(p, ptr, uasm_rel_hi(modd));
-       } else {
-               UASM_i_LA_mostly(p, ptr, modd);
-               uasm_il_b(p, r, label_vmalloc_done);
-               if (uasm_in_compat_space_p(modd))
-                       uasm_i_addiu(p, ptr, ptr, uasm_rel_lo(modd));
-               else
-                       uasm_i_daddiu(p, ptr, ptr, uasm_rel_lo(modd));
-       }
-
        uasm_l_vmalloc(l, *p);
-       if (uasm_in_compat_space_p(MODULE_START) &&
-           !uasm_rel_lo(MODULE_START) &&
-           MODULE_START << 32 == VMALLOC_START)
-               uasm_i_dsll32(p, ptr, ptr, 0);  /* typical case */
-       else
-               UASM_i_LA(p, ptr, VMALLOC_START);
-#else
-       uasm_l_vmalloc(l, *p);
-       UASM_i_LA(p, ptr, VMALLOC_START);
-#endif
-       uasm_i_dsubu(p, bvaddr, bvaddr, ptr);
 
        if (uasm_in_compat_space_p(swpd) && !uasm_rel_lo(swpd)) {
                uasm_il_b(p, r, label_vmalloc_done);
index 27c807b67feaf4fc1a8f7e745462d8dd1bcc9624..f1b14c8a4a1c386baf66a23ecc2e01ebb970de9e 100644 (file)
@@ -47,7 +47,7 @@ int *_prom_argv, *_prom_envp;
  */
 #define prom_envp(index) ((char *)(long)_prom_envp[(index)])
 
-int init_debug = 0;
+int init_debug;
 
 static int mips_revision_corid;
 int mips_revision_sconid;
index f48d60e8429017b52352e8e0b59bc18faa0e9061..329420536241b5b70743d5ef7ce56c02a4087aa3 100644 (file)
@@ -22,6 +22,7 @@
  * Reset the MIPS boards.
  *
  */
+#include <linux/init.h>
 #include <linux/pm.h>
 
 #include <asm/io.h>
@@ -45,9 +46,13 @@ static void mips_machine_halt(void)
 }
 
 
-void mips_reboot_setup(void)
+static int __init mips_reboot_setup(void)
 {
        _machine_restart = mips_machine_restart;
        _machine_halt = mips_machine_halt;
        pm_power_off = mips_machine_halt;
+
+       return 0;
 }
+
+arch_initcall(mips_reboot_setup);
index dc78b8983eeb2688b0fbae098561b53a9885c028..b7f37d4982fab27b91213a83be7a178626b694cb 100644 (file)
@@ -218,7 +218,6 @@ void __init plat_mem_setup(void)
 #if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
        screen_info_setup();
 #endif
-       mips_reboot_setup();
 
        board_be_init = malta_be_init;
        board_be_handler = malta_be_handler;
index 0b97d47691fc92398b3ecb0fdee70bcd7df5d3d9..3c6f190aa61ce9fdb2a15c10b96c139ca167a4d0 100644 (file)
@@ -100,9 +100,10 @@ static unsigned int __init estimate_cpu_frequency(void)
        return count;
 }
 
-unsigned long read_persistent_clock(void)
+void read_persistent_clock(struct timespec *ts)
 {
-       return mc146818_get_cmos_time();
+       ts->tv_sec = mc146818_get_cmos_time();
+       ts->tv_nsec = 0;
 }
 
 static void __init plat_perf_setup(void)
index 90cc604bdadfd8de85bf5d99d5aa0cf37efdf98d..644eb7c3210ff4b794eb4e80c50dedaaba3eabc2 100644 (file)
@@ -39,7 +39,7 @@
 #define PNX8335_DEBUG7 0x441c
 
 int prom_argc;
-char **prom_argv = 0, **prom_envp = 0;
+char **prom_argv, **prom_envp;
 
 extern void prom_init_cmdline(void);
 extern char *prom_getenv(char *envname);
index acf1fa88944456119619e57d2813041e3eb04b20..af094cd1d85bf030341bb6742079fbac5a630d91 100644 (file)
@@ -69,9 +69,9 @@ static int pnx8550_registers_read(char* page, char** start, off_t offset, int co
         return len;
 }
 
-static struct proc_dir_entry* pnx8550_dir        = NULL;
-static struct proc_dir_entry* pnx8550_timers     = NULL;
-static struct proc_dir_entry* pnx8550_registers  = NULL;
+static struct proc_dir_entry* pnx8550_dir;
+static struct proc_dir_entry* pnx8550_timers;
+static struct proc_dir_entry* pnx8550_registers;
 
 static int pnx8550_proc_init( void )
 {
index bf3be6fcf7ff38343e3ed157c4722ed8a938b145..02cc65e52d11b47574b2940e5859a733f7d0fd85 100644 (file)
@@ -15,3 +15,4 @@ oprofile-$(CONFIG_CPU_MIPS64)         += op_model_mipsxx.o
 oprofile-$(CONFIG_CPU_R10000)          += op_model_mipsxx.o
 oprofile-$(CONFIG_CPU_SB1)             += op_model_mipsxx.o
 oprofile-$(CONFIG_CPU_RM9000)          += op_model_rm9000.o
+oprofile-$(CONFIG_CPU_LOONGSON2)       += op_model_loongson2.o
index 3bf3354547f656971827c523f041dd72ab05cfb7..7832ad257a14c7e2b9cfb12d96e8b7d23964a202 100644 (file)
@@ -16,6 +16,7 @@
 
 extern struct op_mips_model op_model_mipsxx_ops __attribute__((weak));
 extern struct op_mips_model op_model_rm9000_ops __attribute__((weak));
+extern struct op_mips_model op_model_loongson2_ops __attribute__((weak));
 
 static struct op_mips_model *model;
 
@@ -93,6 +94,9 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
        case CPU_RM9000:
                lmodel = &op_model_rm9000_ops;
                break;
+       case CPU_LOONGSON2:
+               lmodel = &op_model_loongson2_ops;
+               break;
        };
 
        if (!lmodel)
diff --git a/arch/mips/oprofile/op_model_loongson2.c b/arch/mips/oprofile/op_model_loongson2.c
new file mode 100644 (file)
index 0000000..655cb8d
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * Loongson2 performance counter driver for oprofile
+ *
+ * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
+ * Author: Yanhua <yanh@lemote.com>
+ * Author: Wu Zhangjin <wuzj@lemote.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+#include <linux/init.h>
+#include <linux/oprofile.h>
+#include <linux/interrupt.h>
+
+#include <loongson.h>                  /* LOONGSON2_PERFCNT_IRQ */
+#include "op_impl.h"
+
+/*
+ * a patch should be sent to oprofile with the loongson-specific support.
+ * otherwise, the oprofile tool will not recognize this and complain about
+ * "cpu_type 'unset' is not valid".
+ */
+#define LOONGSON2_CPU_TYPE     "mips/godson2"
+
+#define LOONGSON2_COUNTER1_EVENT(event)        ((event & 0x0f) << 5)
+#define LOONGSON2_COUNTER2_EVENT(event)        ((event & 0x0f) << 9)
+
+#define LOONGSON2_PERFCNT_EXL                  (1UL    <<  0)
+#define LOONGSON2_PERFCNT_KERNEL               (1UL    <<  1)
+#define LOONGSON2_PERFCNT_SUPERVISOR   (1UL    <<  2)
+#define LOONGSON2_PERFCNT_USER                 (1UL    <<  3)
+#define LOONGSON2_PERFCNT_INT_EN               (1UL    <<  4)
+#define LOONGSON2_PERFCNT_OVERFLOW             (1ULL   << 31)
+
+/* Loongson2 performance counter register */
+#define read_c0_perfctrl() __read_64bit_c0_register($24, 0)
+#define write_c0_perfctrl(val) __write_64bit_c0_register($24, 0, val)
+#define read_c0_perfcnt() __read_64bit_c0_register($25, 0)
+#define write_c0_perfcnt(val) __write_64bit_c0_register($25, 0, val)
+
+static struct loongson2_register_config {
+       unsigned int ctrl;
+       unsigned long long reset_counter1;
+       unsigned long long reset_counter2;
+       int cnt1_enalbed, cnt2_enalbed;
+} reg;
+
+DEFINE_SPINLOCK(sample_lock);
+
+static char *oprofid = "LoongsonPerf";
+static irqreturn_t loongson2_perfcount_handler(int irq, void *dev_id);
+/* Compute all of the registers in preparation for enabling profiling.  */
+
+static void loongson2_reg_setup(struct op_counter_config *cfg)
+{
+       unsigned int ctrl = 0;
+
+       reg.reset_counter1 = 0;
+       reg.reset_counter2 = 0;
+       /* Compute the performance counter ctrl word.  */
+       /* For now count kernel and user mode */
+       if (cfg[0].enabled) {
+               ctrl |= LOONGSON2_COUNTER1_EVENT(cfg[0].event);
+               reg.reset_counter1 = 0x80000000ULL - cfg[0].count;
+       }
+
+       if (cfg[1].enabled) {
+               ctrl |= LOONGSON2_COUNTER2_EVENT(cfg[1].event);
+               reg.reset_counter2 = (0x80000000ULL - cfg[1].count);
+       }
+
+       if (cfg[0].enabled || cfg[1].enabled) {
+               ctrl |= LOONGSON2_PERFCNT_EXL | LOONGSON2_PERFCNT_INT_EN;
+               if (cfg[0].kernel || cfg[1].kernel)
+                       ctrl |= LOONGSON2_PERFCNT_KERNEL;
+               if (cfg[0].user || cfg[1].user)
+                       ctrl |= LOONGSON2_PERFCNT_USER;
+       }
+
+       reg.ctrl = ctrl;
+
+       reg.cnt1_enalbed = cfg[0].enabled;
+       reg.cnt2_enalbed = cfg[1].enabled;
+
+}
+
+/* Program all of the registers in preparation for enabling profiling.  */
+
+static void loongson2_cpu_setup(void *args)
+{
+       uint64_t perfcount;
+
+       perfcount = (reg.reset_counter2 << 32) | reg.reset_counter1;
+       write_c0_perfcnt(perfcount);
+}
+
+static void loongson2_cpu_start(void *args)
+{
+       /* Start all counters on current CPU */
+       if (reg.cnt1_enalbed || reg.cnt2_enalbed)
+               write_c0_perfctrl(reg.ctrl);
+}
+
+static void loongson2_cpu_stop(void *args)
+{
+       /* Stop all counters on current CPU */
+       write_c0_perfctrl(0);
+       memset(&reg, 0, sizeof(reg));
+}
+
+static irqreturn_t loongson2_perfcount_handler(int irq, void *dev_id)
+{
+       uint64_t counter, counter1, counter2;
+       struct pt_regs *regs = get_irq_regs();
+       int enabled;
+       unsigned long flags;
+
+       /*
+        * LOONGSON2 defines two 32-bit performance counters.
+        * To avoid a race updating the registers we need to stop the counters
+        * while we're messing with
+        * them ...
+        */
+
+       /* Check whether the irq belongs to me */
+       enabled = reg.cnt1_enalbed | reg.cnt2_enalbed;
+       if (!enabled)
+               return IRQ_NONE;
+
+       counter = read_c0_perfcnt();
+       counter1 = counter & 0xffffffff;
+       counter2 = counter >> 32;
+
+       spin_lock_irqsave(&sample_lock, flags);
+
+       if (counter1 & LOONGSON2_PERFCNT_OVERFLOW) {
+               if (reg.cnt1_enalbed)
+                       oprofile_add_sample(regs, 0);
+               counter1 = reg.reset_counter1;
+       }
+       if (counter2 & LOONGSON2_PERFCNT_OVERFLOW) {
+               if (reg.cnt2_enalbed)
+                       oprofile_add_sample(regs, 1);
+               counter2 = reg.reset_counter2;
+       }
+
+       spin_unlock_irqrestore(&sample_lock, flags);
+
+       write_c0_perfcnt((counter2 << 32) | counter1);
+
+       return IRQ_HANDLED;
+}
+
+static int __init loongson2_init(void)
+{
+       return request_irq(LOONGSON2_PERFCNT_IRQ, loongson2_perfcount_handler,
+                          IRQF_SHARED, "Perfcounter", oprofid);
+}
+
+static void loongson2_exit(void)
+{
+       write_c0_perfctrl(0);
+       free_irq(LOONGSON2_PERFCNT_IRQ, oprofid);
+}
+
+struct op_mips_model op_model_loongson2_ops = {
+       .reg_setup = loongson2_reg_setup,
+       .cpu_setup = loongson2_cpu_setup,
+       .init = loongson2_init,
+       .exit = loongson2_exit,
+       .cpu_start = loongson2_cpu_start,
+       .cpu_stop = loongson2_cpu_stop,
+       .cpu_type = LOONGSON2_CPU_TYPE,
+       .num_counters = 2
+};
index 63d8a297c58da4f85abf378fa4da6e7e2c9ed5e6..91bfe73a7f602b348c6e2168e880e8448699293e 100644 (file)
@@ -16,6 +16,8 @@ obj-$(CONFIG_PCI_VR41XX)      += ops-vr41xx.o pci-vr41xx.o
 obj-$(CONFIG_NEC_MARKEINS)     += ops-emma2rh.o pci-emma2rh.o fixup-emma2rh.o
 obj-$(CONFIG_PCI_TX4927)       += ops-tx4927.o
 obj-$(CONFIG_BCM47XX)          += pci-bcm47xx.o
+obj-$(CONFIG_BCM63XX)          += pci-bcm63xx.o fixup-bcm63xx.o \
+                                       ops-bcm63xx.o
 
 #
 # These are still pretty much in the old state, watch, go blind.
@@ -26,7 +28,7 @@ obj-$(CONFIG_MIPS_COBALT)     += fixup-cobalt.o
 obj-$(CONFIG_SOC_AU1500)       += fixup-au1000.o ops-au1000.o
 obj-$(CONFIG_SOC_AU1550)       += fixup-au1000.o ops-au1000.o
 obj-$(CONFIG_SOC_PNX8550)      += fixup-pnx8550.o ops-pnx8550.o
-obj-$(CONFIG_LEMOTE_FULONG)    += fixup-lm2e.o ops-bonito64.o
+obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-bonito64.o
 obj-$(CONFIG_MIPS_MALTA)       += fixup-malta.o
 obj-$(CONFIG_PMC_MSP7120_GW)   += fixup-pmcmsp.o ops-pmcmsp.o
 obj-$(CONFIG_PMC_MSP7120_EVAL) += fixup-pmcmsp.o ops-pmcmsp.o
diff --git a/arch/mips/pci/fixup-bcm63xx.c b/arch/mips/pci/fixup-bcm63xx.c
new file mode 100644 (file)
index 0000000..3408630
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <bcm63xx_cpu.h>
+
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+       return bcm63xx_get_irq_number(IRQ_PCI);
+}
+
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+       return 0;
+}
diff --git a/arch/mips/pci/fixup-fuloong2e.c b/arch/mips/pci/fixup-fuloong2e.c
new file mode 100644 (file)
index 0000000..0c4c7a8
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2004 ICT CAS
+ * Author: Li xiaoyu, ICT CAS
+ *   lixy@ict.ac.cn
+ *
+ * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.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/pci.h>
+#include <asm/mips-boards/bonito64.h>
+
+/* South bridge slot number is set by the pci probe process */
+static u8 sb_slot = 5;
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+       int irq = 0;
+
+       if (slot == sb_slot) {
+               switch (PCI_FUNC(dev->devfn)) {
+               case 2:
+                       irq = 10;
+                       break;
+               case 3:
+                       irq = 11;
+                       break;
+               case 5:
+                       irq = 9;
+                       break;
+               }
+       } else {
+               irq = BONITO_IRQ_BASE + 25 + pin;
+       }
+       return irq;
+
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+       return 0;
+}
+
+static void __init loongson2e_nec_fixup(struct pci_dev *pdev)
+{
+       unsigned int val;
+
+       /* Configues port 1, 2, 3, 4 to be validate*/
+       pci_read_config_dword(pdev, 0xe0, &val);
+       pci_write_config_dword(pdev, 0xe0, (val & ~7) | 0x4);
+
+       /* System clock is 48-MHz Oscillator. */
+       pci_write_config_dword(pdev, 0xe4, 1 << 5);
+}
+
+static void __init loongson2e_686b_func0_fixup(struct pci_dev *pdev)
+{
+       unsigned char c;
+
+       sb_slot = PCI_SLOT(pdev->devfn);
+
+       printk(KERN_INFO "via686b fix: ISA bridge\n");
+
+       /*  Enable I/O Recovery time */
+       pci_write_config_byte(pdev, 0x40, 0x08);
+
+       /*  Enable ISA refresh */
+       pci_write_config_byte(pdev, 0x41, 0x01);
+
+       /*  disable ISA line buffer */
+       pci_write_config_byte(pdev, 0x45, 0x00);
+
+       /*  Gate INTR, and flush line buffer */
+       pci_write_config_byte(pdev, 0x46, 0xe0);
+
+       /*  Disable PCI Delay Transaction, Enable EISA ports 4D0/4D1. */
+       /* pci_write_config_byte(pdev, 0x47, 0x20); */
+
+       /*
+        *  enable PCI Delay Transaction, Enable EISA ports 4D0/4D1.
+        *  enable time-out timer
+        */
+       pci_write_config_byte(pdev, 0x47, 0xe6);
+
+       /*
+        * enable level trigger on pci irqs: 9,10,11,13
+        * important! without this PCI interrupts won't work
+        */
+       outb(0x2e, 0x4d1);
+
+       /*  512 K PCI Decode */
+       pci_write_config_byte(pdev, 0x48, 0x01);
+
+       /*  Wait for PGNT before grant to ISA Master/DMA */
+       pci_write_config_byte(pdev, 0x4a, 0x84);
+
+       /*
+        * Plug'n'Play
+        *
+        *  Parallel DRQ 3, Floppy DRQ 2 (default)
+        */
+       pci_write_config_byte(pdev, 0x50, 0x0e);
+
+       /*
+        * IRQ Routing for Floppy and Parallel port
+        *
+        *  IRQ 6 for floppy, IRQ 7 for parallel port
+        */
+       pci_write_config_byte(pdev, 0x51, 0x76);
+
+       /* IRQ Routing for serial ports (take IRQ 3 and 4) */
+       pci_write_config_byte(pdev, 0x52, 0x34);
+
+       /*  All IRQ's level triggered. */
+       pci_write_config_byte(pdev, 0x54, 0x00);
+
+       /* route PIRQA-D irq */
+       pci_write_config_byte(pdev, 0x55, 0x90);        /* bit 7-4, PIRQA */
+       pci_write_config_byte(pdev, 0x56, 0xba);        /* bit 7-4, PIRQC; */
+                                                       /* 3-0, PIRQB */
+       pci_write_config_byte(pdev, 0x57, 0xd0);        /* bit 7-4, PIRQD */
+
+       /* enable function 5/6, audio/modem */
+       pci_read_config_byte(pdev, 0x85, &c);
+       c &= ~(0x3 << 2);
+       pci_write_config_byte(pdev, 0x85, c);
+
+       printk(KERN_INFO"via686b fix: ISA bridge done\n");
+}
+
+static void __init loongson2e_686b_func1_fixup(struct pci_dev *pdev)
+{
+       printk(KERN_INFO"via686b fix: IDE\n");
+
+       /* Modify IDE controller setup */
+       pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 48);
+       pci_write_config_byte(pdev, PCI_COMMAND,
+                             PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+                             PCI_COMMAND_MASTER);
+       pci_write_config_byte(pdev, 0x40, 0x0b);
+       /* legacy mode */
+       pci_write_config_byte(pdev, 0x42, 0x09);
+
+#if 1/* play safe, otherwise we may see notebook's usb keyboard lockup */
+       /* disable read prefetch/write post buffers */
+       pci_write_config_byte(pdev, 0x41, 0x02);
+
+       /* use 3/4 as fifo thresh hold  */
+       pci_write_config_byte(pdev, 0x43, 0x0a);
+       pci_write_config_byte(pdev, 0x44, 0x00);
+
+       pci_write_config_byte(pdev, 0x45, 0x00);
+#else
+       pci_write_config_byte(pdev, 0x41, 0xc2);
+       pci_write_config_byte(pdev, 0x43, 0x35);
+       pci_write_config_byte(pdev, 0x44, 0x1c);
+
+       pci_write_config_byte(pdev, 0x45, 0x10);
+#endif
+
+       printk(KERN_INFO"via686b fix: IDE done\n");
+}
+
+static void __init loongson2e_686b_func2_fixup(struct pci_dev *pdev)
+{
+       /* irq routing */
+       pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 10);
+}
+
+static void __init loongson2e_686b_func3_fixup(struct pci_dev *pdev)
+{
+       /* irq routing */
+       pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 11);
+}
+
+static void __init loongson2e_686b_func5_fixup(struct pci_dev *pdev)
+{
+       unsigned int val;
+       unsigned char c;
+
+       /* enable IO */
+       pci_write_config_byte(pdev, PCI_COMMAND,
+                             PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+                             PCI_COMMAND_MASTER);
+       pci_read_config_dword(pdev, 0x4, &val);
+       pci_write_config_dword(pdev, 0x4, val | 1);
+
+       /* route ac97 IRQ */
+       pci_write_config_byte(pdev, 0x3c, 9);
+
+       pci_read_config_byte(pdev, 0x8, &c);
+
+       /* link control: enable link & SGD PCM output */
+       pci_write_config_byte(pdev, 0x41, 0xcc);
+
+       /* disable game port, FM, midi, sb, enable write to reg2c-2f */
+       pci_write_config_byte(pdev, 0x42, 0x20);
+
+       /* we are using Avance logic codec */
+       pci_write_config_word(pdev, 0x2c, 0x1005);
+       pci_write_config_word(pdev, 0x2e, 0x4710);
+       pci_read_config_dword(pdev, 0x2c, &val);
+
+       pci_write_config_byte(pdev, 0x42, 0x0);
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686,
+                        loongson2e_686b_func0_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1,
+                        loongson2e_686b_func1_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2,
+                        loongson2e_686b_func2_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3,
+                        loongson2e_686b_func3_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5,
+                        loongson2e_686b_func5_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB,
+                        loongson2e_nec_fixup);
diff --git a/arch/mips/pci/fixup-lm2e.c b/arch/mips/pci/fixup-lm2e.c
deleted file mode 100644 (file)
index e18ae4f..0000000
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * fixup-lm2e.c
- *
- * Copyright (C) 2004 ICT CAS
- * Author: Li xiaoyu, ICT CAS
- *   lixy@ict.ac.cn
- *
- * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
- * Author: Fuxin Zhang, zhangfx@lemote.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.
- *
- */
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <asm/mips-boards/bonito64.h>
-
-/* South bridge slot number is set by the pci probe process */
-static u8 sb_slot = 5;
-
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-       int irq = 0;
-
-       if (slot == sb_slot) {
-               switch (PCI_FUNC(dev->devfn)) {
-               case 2:
-                       irq = 10;
-                       break;
-               case 3:
-                       irq = 11;
-                       break;
-               case 5:
-                       irq = 9;
-                       break;
-               }
-       } else {
-               irq = BONITO_IRQ_BASE + 25 + pin;
-       }
-       return irq;
-
-}
-
-/* Do platform specific device initialization at pci_enable_device() time */
-int pcibios_plat_dev_init(struct pci_dev *dev)
-{
-       return 0;
-}
-
-static void __init loongson2e_nec_fixup(struct pci_dev *pdev)
-{
-       unsigned int val;
-
-       /* Configues port 1, 2, 3, 4 to be validate*/
-       pci_read_config_dword(pdev, 0xe0, &val);
-       pci_write_config_dword(pdev, 0xe0, (val & ~7) | 0x4);
-
-       /* System clock is 48-MHz Oscillator. */
-       pci_write_config_dword(pdev, 0xe4, 1 << 5);
-}
-
-static void __init loongson2e_686b_func0_fixup(struct pci_dev *pdev)
-{
-       unsigned char c;
-
-       sb_slot = PCI_SLOT(pdev->devfn);
-
-       printk(KERN_INFO "via686b fix: ISA bridge\n");
-
-       /*  Enable I/O Recovery time */
-       pci_write_config_byte(pdev, 0x40, 0x08);
-
-       /*  Enable ISA refresh */
-       pci_write_config_byte(pdev, 0x41, 0x01);
-
-       /*  disable ISA line buffer */
-       pci_write_config_byte(pdev, 0x45, 0x00);
-
-       /*  Gate INTR, and flush line buffer */
-       pci_write_config_byte(pdev, 0x46, 0xe0);
-
-       /*  Disable PCI Delay Transaction, Enable EISA ports 4D0/4D1. */
-       /* pci_write_config_byte(pdev, 0x47, 0x20); */
-
-       /*
-        *  enable PCI Delay Transaction, Enable EISA ports 4D0/4D1.
-        *  enable time-out timer
-        */
-       pci_write_config_byte(pdev, 0x47, 0xe6);
-
-       /*
-        * enable level trigger on pci irqs: 9,10,11,13
-        * important! without this PCI interrupts won't work
-        */
-       outb(0x2e, 0x4d1);
-
-       /*  512 K PCI Decode */
-       pci_write_config_byte(pdev, 0x48, 0x01);
-
-       /*  Wait for PGNT before grant to ISA Master/DMA */
-       pci_write_config_byte(pdev, 0x4a, 0x84);
-
-       /*
-        * Plug'n'Play
-        *
-        *  Parallel DRQ 3, Floppy DRQ 2 (default)
-        */
-       pci_write_config_byte(pdev, 0x50, 0x0e);
-
-       /*
-        * IRQ Routing for Floppy and Parallel port
-        *
-        *  IRQ 6 for floppy, IRQ 7 for parallel port
-        */
-       pci_write_config_byte(pdev, 0x51, 0x76);
-
-       /* IRQ Routing for serial ports (take IRQ 3 and 4) */
-       pci_write_config_byte(pdev, 0x52, 0x34);
-
-       /*  All IRQ's level triggered. */
-       pci_write_config_byte(pdev, 0x54, 0x00);
-
-       /* route PIRQA-D irq */
-       pci_write_config_byte(pdev, 0x55, 0x90);        /* bit 7-4, PIRQA */
-       pci_write_config_byte(pdev, 0x56, 0xba);        /* bit 7-4, PIRQC; */
-                                                       /* 3-0, PIRQB */
-       pci_write_config_byte(pdev, 0x57, 0xd0);        /* bit 7-4, PIRQD */
-
-       /* enable function 5/6, audio/modem */
-       pci_read_config_byte(pdev, 0x85, &c);
-       c &= ~(0x3 << 2);
-       pci_write_config_byte(pdev, 0x85, c);
-
-       printk(KERN_INFO"via686b fix: ISA bridge done\n");
-}
-
-static void __init loongson2e_686b_func1_fixup(struct pci_dev *pdev)
-{
-       printk(KERN_INFO"via686b fix: IDE\n");
-
-       /* Modify IDE controller setup */
-       pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 48);
-       pci_write_config_byte(pdev, PCI_COMMAND,
-                             PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
-                             PCI_COMMAND_MASTER);
-       pci_write_config_byte(pdev, 0x40, 0x0b);
-       /* legacy mode */
-       pci_write_config_byte(pdev, 0x42, 0x09);
-
-#if 1/* play safe, otherwise we may see notebook's usb keyboard lockup */
-       /* disable read prefetch/write post buffers */
-       pci_write_config_byte(pdev, 0x41, 0x02);
-
-       /* use 3/4 as fifo thresh hold  */
-       pci_write_config_byte(pdev, 0x43, 0x0a);
-       pci_write_config_byte(pdev, 0x44, 0x00);
-
-       pci_write_config_byte(pdev, 0x45, 0x00);
-#else
-       pci_write_config_byte(pdev, 0x41, 0xc2);
-       pci_write_config_byte(pdev, 0x43, 0x35);
-       pci_write_config_byte(pdev, 0x44, 0x1c);
-
-       pci_write_config_byte(pdev, 0x45, 0x10);
-#endif
-
-       printk(KERN_INFO"via686b fix: IDE done\n");
-}
-
-static void __init loongson2e_686b_func2_fixup(struct pci_dev *pdev)
-{
-       /* irq routing */
-       pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 10);
-}
-
-static void __init loongson2e_686b_func3_fixup(struct pci_dev *pdev)
-{
-       /* irq routing */
-       pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 11);
-}
-
-static void __init loongson2e_686b_func5_fixup(struct pci_dev *pdev)
-{
-       unsigned int val;
-       unsigned char c;
-
-       /* enable IO */
-       pci_write_config_byte(pdev, PCI_COMMAND,
-                             PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
-                             PCI_COMMAND_MASTER);
-       pci_read_config_dword(pdev, 0x4, &val);
-       pci_write_config_dword(pdev, 0x4, val | 1);
-
-       /* route ac97 IRQ */
-       pci_write_config_byte(pdev, 0x3c, 9);
-
-       pci_read_config_byte(pdev, 0x8, &c);
-
-       /* link control: enable link & SGD PCM output */
-       pci_write_config_byte(pdev, 0x41, 0xcc);
-
-       /* disable game port, FM, midi, sb, enable write to reg2c-2f */
-       pci_write_config_byte(pdev, 0x42, 0x20);
-
-       /* we are using Avance logic codec */
-       pci_write_config_word(pdev, 0x2c, 0x1005);
-       pci_write_config_word(pdev, 0x2e, 0x4710);
-       pci_read_config_dword(pdev, 0x2c, &val);
-
-       pci_write_config_byte(pdev, 0x42, 0x0);
-}
-
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686,
-                        loongson2e_686b_func0_fixup);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1,
-                        loongson2e_686b_func1_fixup);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2,
-                        loongson2e_686b_func2_fixup);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3,
-                        loongson2e_686b_func3_fixup);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5,
-                        loongson2e_686b_func5_fixup);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB,
-                        loongson2e_nec_fixup);
diff --git a/arch/mips/pci/ops-bcm63xx.c b/arch/mips/pci/ops-bcm63xx.c
new file mode 100644 (file)
index 0000000..822ae17
--- /dev/null
@@ -0,0 +1,467 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include "pci-bcm63xx.h"
+
+/*
+ * swizzle 32bits data to return only the needed part
+ */
+static int postprocess_read(u32 data, int where, unsigned int size)
+{
+       u32 ret;
+
+       ret = 0;
+       switch (size) {
+       case 1:
+               ret = (data >> ((where & 3) << 3)) & 0xff;
+               break;
+       case 2:
+               ret = (data >> ((where & 3) << 3)) & 0xffff;
+               break;
+       case 4:
+               ret = data;
+               break;
+       }
+       return ret;
+}
+
+static int preprocess_write(u32 orig_data, u32 val, int where,
+                           unsigned int size)
+{
+       u32 ret;
+
+       ret = 0;
+       switch (size) {
+       case 1:
+               ret = (orig_data & ~(0xff << ((where & 3) << 3))) |
+                       (val << ((where & 3) << 3));
+               break;
+       case 2:
+               ret = (orig_data & ~(0xffff << ((where & 3) << 3))) |
+                       (val << ((where & 3) << 3));
+               break;
+       case 4:
+               ret = val;
+               break;
+       }
+       return ret;
+}
+
+/*
+ * setup hardware for a configuration cycle with given parameters
+ */
+static int bcm63xx_setup_cfg_access(int type, unsigned int busn,
+                                   unsigned int devfn, int where)
+{
+       unsigned int slot, func, reg;
+       u32 val;
+
+       slot = PCI_SLOT(devfn);
+       func = PCI_FUNC(devfn);
+       reg = where >> 2;
+
+       /* sanity check */
+       if (slot > (MPI_L2PCFG_DEVNUM_MASK >> MPI_L2PCFG_DEVNUM_SHIFT))
+               return 1;
+
+       if (func > (MPI_L2PCFG_FUNC_MASK >> MPI_L2PCFG_FUNC_SHIFT))
+               return 1;
+
+       if (reg > (MPI_L2PCFG_REG_MASK >> MPI_L2PCFG_REG_SHIFT))
+               return 1;
+
+       /* ok, setup config access */
+       val = (reg << MPI_L2PCFG_REG_SHIFT);
+       val |= (func << MPI_L2PCFG_FUNC_SHIFT);
+       val |= (slot << MPI_L2PCFG_DEVNUM_SHIFT);
+       val |= MPI_L2PCFG_CFG_USEREG_MASK;
+       val |= MPI_L2PCFG_CFG_SEL_MASK;
+       /* type 0 cycle for local bus, type 1 cycle for anything else */
+       if (type != 0) {
+               /* FIXME: how to specify bus ??? */
+               val |= (1 << MPI_L2PCFG_CFG_TYPE_SHIFT);
+       }
+       bcm_mpi_writel(val, MPI_L2PCFG_REG);
+
+       return 0;
+}
+
+static int bcm63xx_do_cfg_read(int type, unsigned int busn,
+                               unsigned int devfn, int where, int size,
+                               u32 *val)
+{
+       u32 data;
+
+       /* two phase cycle, first we write address, then read data at
+        * another location, caller already has a spinlock so no need
+        * to add one here  */
+       if (bcm63xx_setup_cfg_access(type, busn, devfn, where))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+       iob();
+       data = le32_to_cpu(__raw_readl(pci_iospace_start));
+       /* restore IO space normal behaviour */
+       bcm_mpi_writel(0, MPI_L2PCFG_REG);
+
+       *val = postprocess_read(data, where, size);
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static int bcm63xx_do_cfg_write(int type, unsigned int busn,
+                                unsigned int devfn, int where, int size,
+                                u32 val)
+{
+       u32 data;
+
+       /* two phase cycle, first we write address, then write data to
+        * another location, caller already has a spinlock so no need
+        * to add one here  */
+       if (bcm63xx_setup_cfg_access(type, busn, devfn, where))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+       iob();
+
+       data = le32_to_cpu(__raw_readl(pci_iospace_start));
+       data = preprocess_write(data, val, where, size);
+
+       __raw_writel(cpu_to_le32(data), pci_iospace_start);
+       wmb();
+       /* no way to know the access is done, we have to wait */
+       udelay(500);
+       /* restore IO space normal behaviour */
+       bcm_mpi_writel(0, MPI_L2PCFG_REG);
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static int bcm63xx_pci_read(struct pci_bus *bus, unsigned int devfn,
+                            int where, int size, u32 *val)
+{
+       int type;
+
+       type = bus->parent ? 1 : 0;
+
+       if (type == 0 && PCI_SLOT(devfn) == CARDBUS_PCI_IDSEL)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       return bcm63xx_do_cfg_read(type, bus->number, devfn,
+                                   where, size, val);
+}
+
+static int bcm63xx_pci_write(struct pci_bus *bus, unsigned int devfn,
+                             int where, int size, u32 val)
+{
+       int type;
+
+       type = bus->parent ? 1 : 0;
+
+       if (type == 0 && PCI_SLOT(devfn) == CARDBUS_PCI_IDSEL)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       return bcm63xx_do_cfg_write(type, bus->number, devfn,
+                                    where, size, val);
+}
+
+struct pci_ops bcm63xx_pci_ops = {
+       .read   = bcm63xx_pci_read,
+       .write  = bcm63xx_pci_write
+};
+
+#ifdef CONFIG_CARDBUS
+/*
+ * emulate configuration read access on a cardbus bridge
+ */
+#define FAKE_CB_BRIDGE_SLOT    0x1e
+
+static int fake_cb_bridge_bus_number = -1;
+
+static struct {
+       u16 pci_command;
+       u8 cb_latency;
+       u8 subordinate_busn;
+       u8 cardbus_busn;
+       u8 pci_busn;
+       int bus_assigned;
+       u16 bridge_control;
+
+       u32 mem_base0;
+       u32 mem_limit0;
+       u32 mem_base1;
+       u32 mem_limit1;
+
+       u32 io_base0;
+       u32 io_limit0;
+       u32 io_base1;
+       u32 io_limit1;
+} fake_cb_bridge_regs;
+
+static int fake_cb_bridge_read(int where, int size, u32 *val)
+{
+       unsigned int reg;
+       u32 data;
+
+       data = 0;
+       reg = where >> 2;
+       switch (reg) {
+       case (PCI_VENDOR_ID >> 2):
+       case (PCI_CB_SUBSYSTEM_VENDOR_ID >> 2):
+               /* create dummy vendor/device id from our cpu id */
+               data = (bcm63xx_get_cpu_id() << 16) | PCI_VENDOR_ID_BROADCOM;
+               break;
+
+       case (PCI_COMMAND >> 2):
+               data = (PCI_STATUS_DEVSEL_SLOW << 16);
+               data |= fake_cb_bridge_regs.pci_command;
+               break;
+
+       case (PCI_CLASS_REVISION >> 2):
+               data = (PCI_CLASS_BRIDGE_CARDBUS << 16);
+               break;
+
+       case (PCI_CACHE_LINE_SIZE >> 2):
+               data = (PCI_HEADER_TYPE_CARDBUS << 16);
+               break;
+
+       case (PCI_INTERRUPT_LINE >> 2):
+               /* bridge control */
+               data = (fake_cb_bridge_regs.bridge_control << 16);
+               /* pin:intA line:0xff */
+               data |= (0x1 << 8) | 0xff;
+               break;
+
+       case (PCI_CB_PRIMARY_BUS >> 2):
+               data = (fake_cb_bridge_regs.cb_latency << 24);
+               data |= (fake_cb_bridge_regs.subordinate_busn << 16);
+               data |= (fake_cb_bridge_regs.cardbus_busn << 8);
+               data |= fake_cb_bridge_regs.pci_busn;
+               break;
+
+       case (PCI_CB_MEMORY_BASE_0 >> 2):
+               data = fake_cb_bridge_regs.mem_base0;
+               break;
+
+       case (PCI_CB_MEMORY_LIMIT_0 >> 2):
+               data = fake_cb_bridge_regs.mem_limit0;
+               break;
+
+       case (PCI_CB_MEMORY_BASE_1 >> 2):
+               data = fake_cb_bridge_regs.mem_base1;
+               break;
+
+       case (PCI_CB_MEMORY_LIMIT_1 >> 2):
+               data = fake_cb_bridge_regs.mem_limit1;
+               break;
+
+       case (PCI_CB_IO_BASE_0 >> 2):
+               /* | 1 for 32bits io support */
+               data = fake_cb_bridge_regs.io_base0 | 0x1;
+               break;
+
+       case (PCI_CB_IO_LIMIT_0 >> 2):
+               data = fake_cb_bridge_regs.io_limit0;
+               break;
+
+       case (PCI_CB_IO_BASE_1 >> 2):
+               /* | 1 for 32bits io support */
+               data = fake_cb_bridge_regs.io_base1 | 0x1;
+               break;
+
+       case (PCI_CB_IO_LIMIT_1 >> 2):
+               data = fake_cb_bridge_regs.io_limit1;
+               break;
+       }
+
+       *val = postprocess_read(data, where, size);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * emulate configuration write access on a cardbus bridge
+ */
+static int fake_cb_bridge_write(int where, int size, u32 val)
+{
+       unsigned int reg;
+       u32 data, tmp;
+       int ret;
+
+       ret = fake_cb_bridge_read((where & ~0x3), 4, &data);
+       if (ret != PCIBIOS_SUCCESSFUL)
+               return ret;
+
+       data = preprocess_write(data, val, where, size);
+
+       reg = where >> 2;
+       switch (reg) {
+       case (PCI_COMMAND >> 2):
+               fake_cb_bridge_regs.pci_command = (data & 0xffff);
+               break;
+
+       case (PCI_CB_PRIMARY_BUS >> 2):
+               fake_cb_bridge_regs.cb_latency = (data >> 24) & 0xff;
+               fake_cb_bridge_regs.subordinate_busn = (data >> 16) & 0xff;
+               fake_cb_bridge_regs.cardbus_busn = (data >> 8) & 0xff;
+               fake_cb_bridge_regs.pci_busn = data & 0xff;
+               if (fake_cb_bridge_regs.cardbus_busn)
+                       fake_cb_bridge_regs.bus_assigned = 1;
+               break;
+
+       case (PCI_INTERRUPT_LINE >> 2):
+               tmp = (data >> 16) & 0xffff;
+               /* disable memory prefetch support */
+               tmp &= ~PCI_CB_BRIDGE_CTL_PREFETCH_MEM0;
+               tmp &= ~PCI_CB_BRIDGE_CTL_PREFETCH_MEM1;
+               fake_cb_bridge_regs.bridge_control = tmp;
+               break;
+
+       case (PCI_CB_MEMORY_BASE_0 >> 2):
+               fake_cb_bridge_regs.mem_base0 = data;
+               break;
+
+       case (PCI_CB_MEMORY_LIMIT_0 >> 2):
+               fake_cb_bridge_regs.mem_limit0 = data;
+               break;
+
+       case (PCI_CB_MEMORY_BASE_1 >> 2):
+               fake_cb_bridge_regs.mem_base1 = data;
+               break;
+
+       case (PCI_CB_MEMORY_LIMIT_1 >> 2):
+               fake_cb_bridge_regs.mem_limit1 = data;
+               break;
+
+       case (PCI_CB_IO_BASE_0 >> 2):
+               fake_cb_bridge_regs.io_base0 = data;
+               break;
+
+       case (PCI_CB_IO_LIMIT_0 >> 2):
+               fake_cb_bridge_regs.io_limit0 = data;
+               break;
+
+       case (PCI_CB_IO_BASE_1 >> 2):
+               fake_cb_bridge_regs.io_base1 = data;
+               break;
+
+       case (PCI_CB_IO_LIMIT_1 >> 2):
+               fake_cb_bridge_regs.io_limit1 = data;
+               break;
+       }
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static int bcm63xx_cb_read(struct pci_bus *bus, unsigned int devfn,
+                          int where, int size, u32 *val)
+{
+       /* snoop access to slot 0x1e on root bus, we fake a cardbus
+        * bridge at this location */
+       if (!bus->parent && PCI_SLOT(devfn) == FAKE_CB_BRIDGE_SLOT) {
+               fake_cb_bridge_bus_number = bus->number;
+               return fake_cb_bridge_read(where, size, val);
+       }
+
+       /* a  configuration  cycle for  the  device  behind the  cardbus
+        * bridge is  actually done as a  type 0 cycle  on the primary
+        * bus. This means that only  one device can be on the cardbus
+        * bus */
+       if (fake_cb_bridge_regs.bus_assigned &&
+           bus->number == fake_cb_bridge_regs.cardbus_busn &&
+           PCI_SLOT(devfn) == 0)
+               return bcm63xx_do_cfg_read(0, 0,
+                                          PCI_DEVFN(CARDBUS_PCI_IDSEL, 0),
+                                          where, size, val);
+
+       return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+static int bcm63xx_cb_write(struct pci_bus *bus, unsigned int devfn,
+                           int where, int size, u32 val)
+{
+       if (!bus->parent && PCI_SLOT(devfn) == FAKE_CB_BRIDGE_SLOT) {
+               fake_cb_bridge_bus_number = bus->number;
+               return fake_cb_bridge_write(where, size, val);
+       }
+
+       if (fake_cb_bridge_regs.bus_assigned &&
+           bus->number == fake_cb_bridge_regs.cardbus_busn &&
+           PCI_SLOT(devfn) == 0)
+               return bcm63xx_do_cfg_write(0, 0,
+                                           PCI_DEVFN(CARDBUS_PCI_IDSEL, 0),
+                                           where, size, val);
+
+       return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+struct pci_ops bcm63xx_cb_ops = {
+       .read   = bcm63xx_cb_read,
+       .write   = bcm63xx_cb_write,
+};
+
+/*
+ * only one IO window, so it  cannot be shared by PCI and cardbus, use
+ * fixup to choose and detect unhandled configuration
+ */
+static void bcm63xx_fixup(struct pci_dev *dev)
+{
+       static int io_window = -1;
+       int i, found, new_io_window;
+       u32 val;
+
+       /* look for any io resource */
+       found = 0;
+       for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+               if (pci_resource_flags(dev, i) & IORESOURCE_IO) {
+                       found = 1;
+                       break;
+               }
+       }
+
+       if (!found)
+               return;
+
+       /* skip our fake bus with only cardbus bridge on it */
+       if (dev->bus->number == fake_cb_bridge_bus_number)
+               return;
+
+       /* find on which bus the device is */
+       if (fake_cb_bridge_regs.bus_assigned &&
+           dev->bus->number == fake_cb_bridge_regs.cardbus_busn &&
+           PCI_SLOT(dev->devfn) == 0)
+               new_io_window = 1;
+       else
+               new_io_window = 0;
+
+       if (new_io_window == io_window)
+               return;
+
+       if (io_window != -1) {
+               printk(KERN_ERR "bcm63xx: both PCI and cardbus devices "
+                      "need IO, which hardware cannot do\n");
+               return;
+       }
+
+       printk(KERN_INFO "bcm63xx: PCI IO window assigned to %s\n",
+              (new_io_window == 0) ? "PCI" : "cardbus");
+
+       val = bcm_mpi_readl(MPI_L2PIOREMAP_REG);
+       if (io_window)
+               val |= MPI_L2PREMAP_IS_CARDBUS_MASK;
+       else
+               val &= ~MPI_L2PREMAP_IS_CARDBUS_MASK;
+       bcm_mpi_writel(val, MPI_L2PIOREMAP_REG);
+
+       io_window = new_io_window;
+}
+
+DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, bcm63xx_fixup);
+#endif
index f742c51acf0d0506a18d3784ecbf87fec371a175..54e55e7a243128a783070aed91faa661e96940b3 100644 (file)
@@ -29,7 +29,7 @@
 #define PCI_ACCESS_READ  0
 #define PCI_ACCESS_WRITE 1
 
-#ifdef CONFIG_LEMOTE_FULONG
+#ifdef CONFIG_LEMOTE_FULOONG2E
 #define CFG_SPACE_REG(offset) (void *)CKSEG1ADDR(BONITO_PCICFG_BASE | (offset))
 #define ID_SEL_BEGIN 11
 #else
@@ -77,7 +77,7 @@ static int bonito64_pcibios_config_access(unsigned char access_type,
        addrp = CFG_SPACE_REG(addr & 0xffff);
        if (access_type == PCI_ACCESS_WRITE) {
                writel(cpu_to_le32(*data), addrp);
-#ifndef CONFIG_LEMOTE_FULONG
+#ifndef CONFIG_LEMOTE_FULOONG2E
                /* Wait till done */
                while (BONITO_PCIMSTAT & 0xF);
 #endif
index a9060c7718402a43d471004cf0b844eabf236c18..6f5e24c6ae67261188c76dcba648033307415e08 100644 (file)
@@ -57,7 +57,7 @@ static void *cfg_space;
 #define PCI_BUS_ENABLED        1
 #define PCI_DEVICE_MODE        2
 
-static int bcm1480_bus_status = 0;
+static int bcm1480_bus_status;
 
 #define PCI_BRIDGE_DEVICE  0
 
index f54f45412b0baf9d1d9a5e0789b24f18ce28ee23..50cc6e9e8240857f95021854345ea234653ce6a2 100644 (file)
@@ -56,7 +56,7 @@ static void *ht_cfg_space;
 #define PCI_BUS_ENABLED        1
 #define PCI_DEVICE_MODE        2
 
-static int bcm1480ht_bus_status = 0;
+static int bcm1480ht_bus_status;
 
 #define PCI_BRIDGE_DEVICE  0
 #define HT_BRIDGE_DEVICE   1
diff --git a/arch/mips/pci/pci-bcm63xx.c b/arch/mips/pci/pci-bcm63xx.c
new file mode 100644 (file)
index 0000000..82e0fde
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/bootinfo.h>
+
+#include "pci-bcm63xx.h"
+
+/*
+ * Allow PCI to be disabled at runtime depending on board nvram
+ * configuration
+ */
+int bcm63xx_pci_enabled;
+
+static struct resource bcm_pci_mem_resource = {
+       .name   = "bcm63xx PCI memory space",
+       .start  = BCM_PCI_MEM_BASE_PA,
+       .end    = BCM_PCI_MEM_END_PA,
+       .flags  = IORESOURCE_MEM
+};
+
+static struct resource bcm_pci_io_resource = {
+       .name   = "bcm63xx PCI IO space",
+       .start  = BCM_PCI_IO_BASE_PA,
+#ifdef CONFIG_CARDBUS
+       .end    = BCM_PCI_IO_HALF_PA,
+#else
+       .end    = BCM_PCI_IO_END_PA,
+#endif
+       .flags  = IORESOURCE_IO
+};
+
+struct pci_controller bcm63xx_controller = {
+       .pci_ops        = &bcm63xx_pci_ops,
+       .io_resource    = &bcm_pci_io_resource,
+       .mem_resource   = &bcm_pci_mem_resource,
+};
+
+/*
+ * We handle cardbus  via a fake Cardbus bridge,  memory and io spaces
+ * have to be  clearly separated from PCI one  since we have different
+ * memory decoder.
+ */
+#ifdef CONFIG_CARDBUS
+static struct resource bcm_cb_mem_resource = {
+       .name   = "bcm63xx Cardbus memory space",
+       .start  = BCM_CB_MEM_BASE_PA,
+       .end    = BCM_CB_MEM_END_PA,
+       .flags  = IORESOURCE_MEM
+};
+
+static struct resource bcm_cb_io_resource = {
+       .name   = "bcm63xx Cardbus IO space",
+       .start  = BCM_PCI_IO_HALF_PA + 1,
+       .end    = BCM_PCI_IO_END_PA,
+       .flags  = IORESOURCE_IO
+};
+
+struct pci_controller bcm63xx_cb_controller = {
+       .pci_ops        = &bcm63xx_cb_ops,
+       .io_resource    = &bcm_cb_io_resource,
+       .mem_resource   = &bcm_cb_mem_resource,
+};
+#endif
+
+static u32 bcm63xx_int_cfg_readl(u32 reg)
+{
+       u32 tmp;
+
+       tmp = reg & MPI_PCICFGCTL_CFGADDR_MASK;
+       tmp |= MPI_PCICFGCTL_WRITEEN_MASK;
+       bcm_mpi_writel(tmp, MPI_PCICFGCTL_REG);
+       iob();
+       return bcm_mpi_readl(MPI_PCICFGDATA_REG);
+}
+
+static void bcm63xx_int_cfg_writel(u32 val, u32 reg)
+{
+       u32 tmp;
+
+       tmp = reg & MPI_PCICFGCTL_CFGADDR_MASK;
+       tmp |=  MPI_PCICFGCTL_WRITEEN_MASK;
+       bcm_mpi_writel(tmp, MPI_PCICFGCTL_REG);
+       bcm_mpi_writel(val, MPI_PCICFGDATA_REG);
+}
+
+void __iomem *pci_iospace_start;
+
+static int __init bcm63xx_pci_init(void)
+{
+       unsigned int mem_size;
+       u32 val;
+
+       if (!BCMCPU_IS_6348() && !BCMCPU_IS_6358())
+               return -ENODEV;
+
+       if (!bcm63xx_pci_enabled)
+               return -ENODEV;
+
+       /*
+        * configuration  access are  done through  IO space,  remap 4
+        * first bytes to access it from CPU.
+        *
+        * this means that  no io access from CPU  should happen while
+        * we do a configuration cycle,  but there's no way we can add
+        * a spinlock for each io access, so this is currently kind of
+        * broken on SMP.
+        */
+       pci_iospace_start = ioremap_nocache(BCM_PCI_IO_BASE_PA, 4);
+       if (!pci_iospace_start)
+               return -ENOMEM;
+
+       /* setup local bus to PCI access (PCI memory) */
+       val = BCM_PCI_MEM_BASE_PA & MPI_L2P_BASE_MASK;
+       bcm_mpi_writel(val, MPI_L2PMEMBASE1_REG);
+       bcm_mpi_writel(~(BCM_PCI_MEM_SIZE - 1), MPI_L2PMEMRANGE1_REG);
+       bcm_mpi_writel(val | MPI_L2PREMAP_ENABLED_MASK, MPI_L2PMEMREMAP1_REG);
+
+       /* set Cardbus IDSEL (type 0 cfg access on primary bus for
+        * this IDSEL will be done on Cardbus instead) */
+       val = bcm_pcmcia_readl(PCMCIA_C1_REG);
+       val &= ~PCMCIA_C1_CBIDSEL_MASK;
+       val |= (CARDBUS_PCI_IDSEL << PCMCIA_C1_CBIDSEL_SHIFT);
+       bcm_pcmcia_writel(val, PCMCIA_C1_REG);
+
+#ifdef CONFIG_CARDBUS
+       /* setup local bus to PCI access (Cardbus memory) */
+       val = BCM_CB_MEM_BASE_PA & MPI_L2P_BASE_MASK;
+       bcm_mpi_writel(val, MPI_L2PMEMBASE2_REG);
+       bcm_mpi_writel(~(BCM_CB_MEM_SIZE - 1), MPI_L2PMEMRANGE2_REG);
+       val |= MPI_L2PREMAP_ENABLED_MASK | MPI_L2PREMAP_IS_CARDBUS_MASK;
+       bcm_mpi_writel(val, MPI_L2PMEMREMAP2_REG);
+#else
+       /* disable second access windows */
+       bcm_mpi_writel(0, MPI_L2PMEMREMAP2_REG);
+#endif
+
+       /* setup local bus  to PCI access (IO memory),  we have only 1
+        * IO window  for both PCI  and cardbus, but it  cannot handle
+        * both  at the  same time,  assume standard  PCI for  now, if
+        * cardbus card has  IO zone, PCI fixup will  change window to
+        * cardbus */
+       val = BCM_PCI_IO_BASE_PA & MPI_L2P_BASE_MASK;
+       bcm_mpi_writel(val, MPI_L2PIOBASE_REG);
+       bcm_mpi_writel(~(BCM_PCI_IO_SIZE - 1), MPI_L2PIORANGE_REG);
+       bcm_mpi_writel(val | MPI_L2PREMAP_ENABLED_MASK, MPI_L2PIOREMAP_REG);
+
+       /* enable PCI related GPIO pins */
+       bcm_mpi_writel(MPI_LOCBUSCTL_EN_PCI_GPIO_MASK, MPI_LOCBUSCTL_REG);
+
+       /* setup PCI to local bus access, used by PCI device to target
+        * local RAM while bus mastering */
+       bcm63xx_int_cfg_writel(0, PCI_BASE_ADDRESS_3);
+       if (BCMCPU_IS_6358())
+               val = MPI_SP0_REMAP_ENABLE_MASK;
+       else
+               val = 0;
+       bcm_mpi_writel(val, MPI_SP0_REMAP_REG);
+
+       bcm63xx_int_cfg_writel(0x0, PCI_BASE_ADDRESS_4);
+       bcm_mpi_writel(0, MPI_SP1_REMAP_REG);
+
+       mem_size = bcm63xx_get_memory_size();
+
+       /* 6348 before rev b0 exposes only 16 MB of RAM memory through
+        * PCI, throw a warning if we have more memory */
+       if (BCMCPU_IS_6348() && (bcm63xx_get_cpu_rev() & 0xf0) == 0xa0) {
+               if (mem_size > (16 * 1024 * 1024))
+                       printk(KERN_WARNING "bcm63xx: this CPU "
+                              "revision cannot handle more than 16MB "
+                              "of RAM for PCI bus mastering\n");
+       } else {
+               /* setup sp0 range to local RAM size */
+               bcm_mpi_writel(~(mem_size - 1), MPI_SP0_RANGE_REG);
+               bcm_mpi_writel(0, MPI_SP1_RANGE_REG);
+       }
+
+       /* change  host bridge  retry  counter to  infinite number  of
+        * retry,  needed for  some broadcom  wifi cards  with Silicon
+        * Backplane bus where access to srom seems very slow  */
+       val = bcm63xx_int_cfg_readl(BCMPCI_REG_TIMERS);
+       val &= ~REG_TIMER_RETRY_MASK;
+       bcm63xx_int_cfg_writel(val, BCMPCI_REG_TIMERS);
+
+       /* enable memory decoder and bus mastering */
+       val = bcm63xx_int_cfg_readl(PCI_COMMAND);
+       val |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+       bcm63xx_int_cfg_writel(val, PCI_COMMAND);
+
+       /* enable read prefetching & disable byte swapping for bus
+        * mastering transfers */
+       val = bcm_mpi_readl(MPI_PCIMODESEL_REG);
+       val &= ~MPI_PCIMODESEL_BAR1_NOSWAP_MASK;
+       val &= ~MPI_PCIMODESEL_BAR2_NOSWAP_MASK;
+       val &= ~MPI_PCIMODESEL_PREFETCH_MASK;
+       val |= (8 << MPI_PCIMODESEL_PREFETCH_SHIFT);
+       bcm_mpi_writel(val, MPI_PCIMODESEL_REG);
+
+       /* enable pci interrupt */
+       val = bcm_mpi_readl(MPI_LOCINT_REG);
+       val |= MPI_LOCINT_MASK(MPI_LOCINT_EXT_PCI_INT);
+       bcm_mpi_writel(val, MPI_LOCINT_REG);
+
+       register_pci_controller(&bcm63xx_controller);
+
+#ifdef CONFIG_CARDBUS
+       register_pci_controller(&bcm63xx_cb_controller);
+#endif
+
+       /* mark memory space used for IO mapping as reserved */
+       request_mem_region(BCM_PCI_IO_BASE_PA, BCM_PCI_IO_SIZE,
+                          "bcm63xx PCI IO space");
+       return 0;
+}
+
+arch_initcall(bcm63xx_pci_init);
diff --git a/arch/mips/pci/pci-bcm63xx.h b/arch/mips/pci/pci-bcm63xx.h
new file mode 100644 (file)
index 0000000..a6e594e
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef PCI_BCM63XX_H_
+#define PCI_BCM63XX_H_
+
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_dev_pci.h>
+
+/*
+ * Cardbus shares  the PCI bus, but has  no IDSEL, so a  special id is
+ * reserved for it.  If you have a standard PCI device at this id, you
+ * need to change the following definition.
+ */
+#define CARDBUS_PCI_IDSEL      0x8
+
+/*
+ * defined in ops-bcm63xx.c
+ */
+extern struct pci_ops bcm63xx_pci_ops;
+extern struct pci_ops bcm63xx_cb_ops;
+
+/*
+ * defined in pci-bcm63xx.c
+ */
+extern void __iomem *pci_iospace_start;
+
+#endif /* ! PCI_BCM63XX_H_ */
index bf639590b8b2bae79253d0c8e87b5d19fbafbd73..ada24e6f951f6b43bff15f9fb862aabb8294ab0c 100644 (file)
@@ -58,7 +58,7 @@ static void *cfg_space;
 #define LDT_BUS_ENABLED        2
 #define PCI_DEVICE_MODE        4
 
-static int sb1250_bus_status = 0;
+static int sb1250_bus_status;
 
 #define PCI_BRIDGE_DEVICE  0
 #define LDT_BRIDGE_DEVICE  1
index b0eb9e75c6829444c10815312f0e0a145cb331e9..9a11c22268914ab6ea87823e6e2a3667d54237e4 100644 (file)
@@ -31,8 +31,8 @@ unsigned int pci_probe = PCI_ASSIGN_ALL_BUSSES;
 
 static struct pci_controller *hose_head, **hose_tail = &hose_head;
 
-unsigned long PCIBIOS_MIN_IO   = 0x0000;
-unsigned long PCIBIOS_MIN_MEM  = 0;
+unsigned long PCIBIOS_MIN_IO;
+unsigned long PCIBIOS_MIN_MEM;
 
 static int pci_initialized;
 
index 2d3c0dca275d40fd75a1db2b0aba1b54d635f338..3498ac9c35af026a4f8205ccef17223b9024cdc9 100644 (file)
@@ -70,7 +70,7 @@ void __init bus_error_init(void)
 }
 
 
-unsigned long read_persistent_clock(void)
+void read_persistent_clock(struct timespec *ts)
 {
        unsigned int year, month, day, hour, min, sec;
        unsigned long flags;
@@ -92,7 +92,8 @@ unsigned long read_persistent_clock(void)
        m48t37_base->control = 0x00;
        spin_unlock_irqrestore(&rtc_lock, flags);
 
-       return mktime(year, month, day, hour, min, sec);
+       ts->tv_sec = mktime(year, month, day, hour, min, sec);
+       ts->tv_nsec = 0;
 }
 
 int rtc_mips_set_time(unsigned long tim)
index 4b8174b382d742f17e3dc846a67f1e707f26c432..0cf86fb32ec3d8531a6921d450e76ffbf011fefd 100644 (file)
@@ -8,6 +8,7 @@
  *         Wu Zhangjin <wuzj@lemote.com>
  */
 #include <asm/asm-offsets.h>
+#include <asm/page.h>
 #include <asm/regdef.h>
 #include <asm/asm.h>
 
@@ -34,7 +35,7 @@ LEAF(swsusp_arch_resume)
 0:
        PTR_L t1, PBE_ADDRESS(t0)   /* source */
        PTR_L t2, PBE_ORIG_ADDRESS(t0) /* destination */
-       PTR_ADDIU t3, t1, _PAGE_SIZE
+       PTR_ADDIU t3, t1, PAGE_SIZE
 1:
        REG_L t8, (t1)
        REG_S t8, (t2)
index ef1564e40c8d694962a5297eee087c602f14bbbc..416b18f9fa722152466c1bc1018cf73c1be42f39 100644 (file)
@@ -10,4 +10,4 @@ obj-$(CONFIG_SGI_IP22) += ip22-berr.o
 obj-$(CONFIG_SGI_IP28) += ip28-berr.o
 obj-$(CONFIG_EISA)     += ip22-eisa.o
 
-EXTRA_CFLAGS += -Werror
+EXTRA_CFLAGS += -Werror
index 672e45d495a9b9c8f72da8c9642b03a1b9d361db..623ffc933c4cf5d3e662a8e81d3cde2a72120fe0 100644 (file)
@@ -87,19 +87,26 @@ enum swarm_rtc_type {
 
 enum swarm_rtc_type swarm_rtc_type;
 
-unsigned long read_persistent_clock(void)
+void read_persistent_clock(struct timespec *ts)
 {
+       unsigned long sec;
+
        switch (swarm_rtc_type) {
        case RTC_XICOR:
-               return xicor_get_time();
+               sec = xicor_get_time();
+               break;
 
        case RTC_M4LT81:
-               return m41t81_get_time();
+               sec = m41t81_get_time();
+               break;
 
        case RTC_NONE:
        default:
-               return mktime(2000, 1, 1, 0, 0, 0);
+               sec = mktime(2000, 1, 1, 0, 0, 0);
+               break;
        }
+       ts->tv_sec = sec;
+       tv->tv_nsec = 0;
 }
 
 int rtc_mips_set_time(unsigned long sec)
index 0d9ec1a5c24aa679df38fa0faabdf5c1046d3b0d..62df6a598e0a6a33bfe45dc2817280aa068ce07d 100644 (file)
@@ -182,7 +182,8 @@ void __init plat_time_init(void)
        setup_pit_timer();
 }
 
-unsigned long read_persistent_clock(void)
+void read_persistent_clock(struct timespec *ts)
 {
-       return -1;
+       ts->tv_sec = -1;
+       ts->tv_nsec = 0;
 }
index 7b637a7c0e6694d7bbae5c3ec895093fb2f6491e..707cfa9c547d98ac63fa619a0f831fbc939dba98 100644 (file)
@@ -341,6 +341,15 @@ static void quirk_slc90e66_ide(struct pci_dev *dev)
 }
 #endif /* CONFIG_TOSHIBA_FPCIB0 */
 
+static void tc35815_fixup(struct pci_dev *dev)
+{
+       /* This device may have PM registers but not they are not suported. */
+       if (dev->pm_cap) {
+               dev_info(&dev->dev, "PM disabled\n");
+               dev->pm_cap = 0;
+       }
+}
+
 static void final_fixup(struct pci_dev *dev)
 {
        unsigned char bist;
@@ -374,6 +383,10 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1,
 DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1,
        quirk_slc90e66_ide);
 #endif
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_TOSHIBA_2,
+                       PCI_DEVICE_ID_TOSHIBA_TC35815_NWU, tc35815_fixup);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_TOSHIBA_2,
+                       PCI_DEVICE_ID_TOSHIBA_TC35815_TX4939, tc35815_fixup);
 DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, final_fixup);
 DECLARE_PCI_FIXUP_RESUME(PCI_ANY_ID, PCI_ANY_ID, final_fixup);
 
index a205e2ba8e7b4e65b442cc56349808f01d88f3f6..c860810722c0a1450a47a3268e9e520e97712efc 100644 (file)
@@ -782,7 +782,7 @@ void __init txx9_iocled_init(unsigned long baseaddr,
                return;
        iocled->mmioaddr = ioremap(baseaddr, 1);
        if (!iocled->mmioaddr)
-               return;
+               goto out_free;
        iocled->chip.get = txx9_iocled_get;
        iocled->chip.set = txx9_iocled_set;
        iocled->chip.direction_input = txx9_iocled_dir_in;
@@ -791,13 +791,13 @@ void __init txx9_iocled_init(unsigned long baseaddr,
        iocled->chip.base = basenum;
        iocled->chip.ngpio = num;
        if (gpiochip_add(&iocled->chip))
-               return;
+               goto out_unmap;
        if (basenum < 0)
                basenum = iocled->chip.base;
 
        pdev = platform_device_alloc("leds-gpio", basenum);
        if (!pdev)
-               return;
+               goto out_gpio;
        iocled->pdata.num_leds = num;
        iocled->pdata.leds = iocled->leds;
        for (i = 0; i < num; i++) {
@@ -812,7 +812,16 @@ void __init txx9_iocled_init(unsigned long baseaddr,
        }
        pdev->dev.platform_data = &iocled->pdata;
        if (platform_device_add(pdev))
-               platform_device_put(pdev);
+               goto out_pdev;
+       return;
+out_pdev:
+       platform_device_put(pdev);
+out_gpio:
+       gpio_remove(&iocled->chip);
+out_unmap:
+       iounmap(iocled->mmioaddr);
+out_free:
+       kfree(iocled);
 }
 #else /* CONFIG_LEDS_GPIO */
 void __init txx9_iocled_init(unsigned long baseaddr,
index 054a16d68082a852c460d96436e9f3b7bb3ce41c..394edcbcce711cbf8181b4dff00a7eed2bfc153e 100644 (file)
@@ -57,14 +57,13 @@ static inline int pcibus_to_node(struct pci_bus *bus)
        .cache_nice_tries       = 1,                    \
        .busy_idx               = 3,                    \
        .idle_idx               = 1,                    \
-       .newidle_idx            = 2,                    \
-       .wake_idx               = 1,                    \
+       .newidle_idx            = 0,                    \
+       .wake_idx               = 0,                    \
        .flags                  = SD_LOAD_BALANCE       \
                                | SD_BALANCE_EXEC       \
+                               | SD_BALANCE_FORK       \
                                | SD_BALANCE_NEWIDLE    \
-                               | SD_WAKE_IDLE          \
-                               | SD_SERIALIZE          \
-                               | SD_WAKE_BALANCE,      \
+                               | SD_SERIALIZE,         \
        .last_balance           = jiffies,              \
        .balance_interval       = 1,                    \
        .nr_balance_failed      = 0,                    \
index a180b4f9a4f64c6d4d5b79bb9384285d4802e462..465e498bcb33c4dfda75ca3c590f143ef9d51923 100644 (file)
@@ -774,11 +774,12 @@ int update_persistent_clock(struct timespec now)
        return ppc_md.set_rtc_time(&tm);
 }
 
-unsigned long read_persistent_clock(void)
+void read_persistent_clock(struct timespec *ts)
 {
        struct rtc_time tm;
        static int first = 1;
 
+       ts->tv_nsec = 0;
        /* XXX this is a litle fragile but will work okay in the short term */
        if (first) {
                first = 0;
@@ -786,14 +787,18 @@ unsigned long read_persistent_clock(void)
                        timezone_offset = ppc_md.time_init();
 
                /* get_boot_time() isn't guaranteed to be safe to call late */
-               if (ppc_md.get_boot_time)
-                       return ppc_md.get_boot_time() -timezone_offset;
+               if (ppc_md.get_boot_time) {
+                       ts->tv_sec = ppc_md.get_boot_time() - timezone_offset;
+                       return;
+               }
+       }
+       if (!ppc_md.get_rtc_time) {
+               ts->tv_sec = 0;
+               return;
        }
-       if (!ppc_md.get_rtc_time)
-               return 0;
        ppc_md.get_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);
+       ts->tv_sec = mktime(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
+                           tm.tm_hour, tm.tm_min, tm.tm_sec);
 }
 
 /* clocksource code */
index e3dc28b8075d64813abeda0bb98f8a981597310a..34162a0b2caa6483f397306cc3e21a457b83b051 100644 (file)
@@ -184,12 +184,14 @@ static void timing_alert_interrupt(__u16 code)
 static void etr_reset(void);
 static void stp_reset(void);
 
-unsigned long read_persistent_clock(void)
+void read_persistent_clock(struct timespec *ts)
 {
-       struct timespec ts;
+       tod_to_timeval(get_clock() - TOD_UNIX_EPOCH, ts);
+}
 
-       tod_to_timeval(get_clock() - TOD_UNIX_EPOCH, &ts);
-       return ts.tv_sec;
+void read_boot_clock(struct timespec *ts)
+{
+       tod_to_timeval(sched_clock_base_cc - TOD_UNIX_EPOCH, ts);
 }
 
 static cycle_t read_tod_clock(struct clocksource *cs)
@@ -207,6 +209,10 @@ static struct clocksource clocksource_tod = {
        .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
+struct clocksource * __init clocksource_default_clock(void)
+{
+       return &clocksource_tod;
+}
 
 void update_vsyscall(struct timespec *wall_time, struct clocksource *clock)
 {
@@ -244,10 +250,6 @@ void update_vsyscall_tz(void)
  */
 void __init time_init(void)
 {
-       struct timespec ts;
-       unsigned long flags;
-       cycle_t now;
-
        /* Reset time synchronization interfaces. */
        etr_reset();
        stp_reset();
@@ -263,26 +265,6 @@ void __init time_init(void)
        if (clocksource_register(&clocksource_tod) != 0)
                panic("Could not register TOD clock source");
 
-       /*
-        * The TOD clock is an accurate clock. The xtime should be
-        * initialized in a way that the difference between TOD and
-        * xtime is reasonably small. Too bad that timekeeping_init
-        * sets xtime.tv_nsec to zero. In addition the clock source
-        * change from the jiffies clock source to the TOD clock
-        * source add another error of up to 1/HZ second. The same
-        * function sets wall_to_monotonic to a value that is too
-        * small for /proc/uptime to be accurate.
-        * Reset xtime and wall_to_monotonic to sane values.
-        */
-       write_seqlock_irqsave(&xtime_lock, flags);
-       now = get_clock();
-       tod_to_timeval(now - TOD_UNIX_EPOCH, &xtime);
-       clocksource_tod.cycle_last = now;
-       clocksource_tod.raw_time = xtime;
-       tod_to_timeval(sched_clock_base_cc - TOD_UNIX_EPOCH, &ts);
-       set_normalized_timespec(&wall_to_monotonic, -ts.tv_sec, -ts.tv_nsec);
-       write_sequnlock_irqrestore(&xtime_lock, flags);
-
        /* Enable TOD clock interrupts on the boot cpu. */
        init_cpu_timer();
 
index b69ee850906d037e5bf24be4c19766729ede6825..f8c40cc65054656fc2d7a62d311d015ed45e3da8 100644 (file)
        .cache_nice_tries       = 2,                    \
        .busy_idx               = 3,                    \
        .idle_idx               = 2,                    \
-       .newidle_idx            = 2,                    \
-       .wake_idx               = 1,                    \
-       .forkexec_idx           = 1,                    \
+       .newidle_idx            = 0,                    \
+       .wake_idx               = 0,                    \
+       .forkexec_idx           = 0,                    \
        .flags                  = SD_LOAD_BALANCE       \
                                | SD_BALANCE_FORK       \
                                | SD_BALANCE_EXEC       \
-                               | SD_SERIALIZE          \
-                               | SD_WAKE_BALANCE,      \
+                               | SD_BALANCE_NEWIDLE    \
+                               | SD_SERIALIZE,         \
        .last_balance           = jiffies,              \
        .balance_interval       = 1,                    \
        .nr_balance_failed      = 0,                    \
index 9b352a1e3fb47af66009127566b2c25b79a66167..0e0e8581cf7a3d8f66125be3efdfb37d9c7bd56a 100644 (file)
@@ -39,11 +39,9 @@ void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time;
 int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time;
 
 #ifdef CONFIG_GENERIC_CMOS_UPDATE
-unsigned long read_persistent_clock(void)
+void read_persistent_clock(struct timespec *ts)
 {
-       struct timespec tv;
-       rtc_sh_get_time(&tv);
-       return tv.tv_sec;
+       rtc_sh_get_time(ts);
 }
 
 int update_persistent_clock(struct timespec now)
index a0f62a808edb91b4deafece2dcabf1f0efa9a838..983d59824a286d0cba34fa48ce078c7ab70eaa04 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc1
-# Tue Aug 18 23:45:52 2009
+# Linux kernel version: 2.6.31
+# Wed Sep 16 00:03:43 2009
 #
 # CONFIG_64BIT is not set
 CONFIG_SPARC=y
@@ -39,11 +39,12 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -87,10 +88,12 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_COUNTERS=y
 
 #
 # Performance Counters
 #
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 # CONFIG_STRIP_ASM_SYMS is not set
@@ -102,6 +105,8 @@ CONFIG_SLAB=y
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
 
 #
 # GCOV-based kernel profiling
@@ -169,6 +174,7 @@ CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_SUN_PM=y
 # CONFIG_SPARC_LED is not set
 CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SPARC_LEON is not set
 
 #
 # Bus options (PCI etc.)
@@ -259,6 +265,7 @@ CONFIG_IPV6_TUNNEL=m
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -288,6 +295,7 @@ CONFIG_NET_PKTGEN=m
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
 CONFIG_WIRELESS_OLD_REGULATORY=y
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
@@ -295,7 +303,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
 #
 # CFG80211 needs to be enabled for MAC80211
 #
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -426,6 +433,7 @@ CONFIG_SCSI_QLOGICPTI=m
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 CONFIG_SCSI_SUNESP=y
+# CONFIG_SCSI_PMCRAID is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_DH is not set
 # CONFIG_SCSI_OSD_INITIATOR is not set
@@ -524,12 +532,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_WLAN is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -569,11 +572,11 @@ CONFIG_INPUT_EVBUG=m
 #
 CONFIG_INPUT_KEYBOARD=y
 CONFIG_KEYBOARD_ATKBD=m
-CONFIG_KEYBOARD_SUNKBD=m
 # 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_SUNKBD=m
+# CONFIG_KEYBOARD_XTKBD is not set
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=m
 CONFIG_MOUSE_PS2_ALPS=y
@@ -581,6 +584,7 @@ CONFIG_MOUSE_PS2_LOGIPS2PP=y
 CONFIG_MOUSE_PS2_SYNAPTICS=y
 CONFIG_MOUSE_PS2_TRACKPOINT=y
 # CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
 # CONFIG_MOUSE_PS2_TOUCHKIT is not set
 CONFIG_MOUSE_SERIAL=m
 # CONFIG_MOUSE_APPLETOUCH is not set
@@ -708,12 +712,10 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Console display driver support
 #
-# CONFIG_PROM_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
 # CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
 # CONFIG_HID_PID is not set
 
@@ -814,6 +816,7 @@ CONFIG_FS_POSIX_ACL=y
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_FILE_LOCKING=y
 CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
@@ -877,7 +880,6 @@ CONFIG_ROMFS_BACKED_BY_BLOCK=y
 CONFIG_ROMFS_ON_BLOCK=y
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
@@ -984,14 +986,17 @@ CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
 # CONFIG_PAGE_POISONING is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_KGDB=y
@@ -1014,7 +1019,6 @@ CONFIG_CRYPTO=y
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD=y
@@ -1057,11 +1061,13 @@ CONFIG_CRYPTO_PCBC=m
 #
 CONFIG_CRYPTO_HMAC=y
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_GHASH is not set
 CONFIG_CRYPTO_MD4=y
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
index fdddf7a6f7252b12b40823ad55bc705f3c38a7fa..f80b881dfea77be89459b343c71fdeaa61a1ad68 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc1
-# Tue Aug 18 23:56:02 2009
+# Linux kernel version: 2.6.31
+# Tue Sep 15 17:06:03 2009
 #
 CONFIG_64BIT=y
 CONFIG_SPARC=y
@@ -19,7 +19,7 @@ CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_AUDIT_ARCH=y
 CONFIG_HAVE_SETUP_PER_CPU_AREA=y
-CONFIG_HAVE_DYNAMIC_PER_CPU_AREA=y
+CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_MMU=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
@@ -48,11 +48,12 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=64
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=18
 CONFIG_GROUP_SCHED=y
@@ -96,10 +97,13 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_COUNTERS=y
 
 #
 # Performance Counters
 #
+CONFIG_PERF_COUNTERS=y
+CONFIG_EVENT_PROFILE=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
@@ -119,7 +123,9 @@ CONFIG_KRETPROBES=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
 
 #
 # GCOV-based kernel profiling
@@ -317,6 +323,7 @@ CONFIG_IPV6_TUNNEL=m
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -349,6 +356,7 @@ CONFIG_NET_TCPPROBE=m
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
 CONFIG_WIRELESS_OLD_REGULATORY=y
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
@@ -356,7 +364,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
 #
 # CFG80211 needs to be enabled for MAC80211
 #
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -549,6 +556,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SUNESP is not set
+# CONFIG_SCSI_PMCRAID is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_DH is not set
 # CONFIG_SCSI_OSD_INITIATOR is not set
@@ -704,12 +712,7 @@ CONFIG_NIU=m
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_WLAN is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -768,11 +771,11 @@ CONFIG_INPUT_EVDEV=y
 #
 CONFIG_INPUT_KEYBOARD=y
 CONFIG_KEYBOARD_ATKBD=y
-CONFIG_KEYBOARD_SUNKBD=y
 CONFIG_KEYBOARD_LKKBD=m
-# CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
 # CONFIG_KEYBOARD_STOWAWAY is not set
+CONFIG_KEYBOARD_SUNKBD=y
+# CONFIG_KEYBOARD_XTKBD is not set
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
 CONFIG_MOUSE_PS2_ALPS=y
@@ -780,6 +783,7 @@ CONFIG_MOUSE_PS2_LOGIPS2PP=y
 CONFIG_MOUSE_PS2_SYNAPTICS=y
 CONFIG_MOUSE_PS2_TRACKPOINT=y
 # CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
 # CONFIG_MOUSE_PS2_TOUCHKIT is not set
 CONFIG_MOUSE_SERIAL=y
 # CONFIG_MOUSE_APPLETOUCH is not set
@@ -883,7 +887,6 @@ CONFIG_I2C_ALGOBIT=y
 #
 # I2C system bus drivers (mostly embedded / system-on-chip)
 #
-# CONFIG_I2C_DESIGNWARE is not set
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
 
@@ -1102,7 +1105,6 @@ CONFIG_FB_ATY_GX=y
 #
 # Console display driver support
 #
-# CONFIG_PROM_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
@@ -1124,6 +1126,7 @@ CONFIG_LOGO=y
 CONFIG_LOGO_SUN_CLUT224=y
 CONFIG_SOUND=m
 CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
 CONFIG_SND=m
 CONFIG_SND_TIMER=m
 CONFIG_SND_PCM=m
@@ -1232,7 +1235,6 @@ CONFIG_SND_SUN_CS4231=m
 CONFIG_AC97_BUS=m
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
 
 #
@@ -1256,6 +1258,7 @@ CONFIG_HID_DRAGONRISE=y
 CONFIG_HID_EZKEY=y
 CONFIG_HID_KYE=y
 CONFIG_HID_GYRATION=y
+CONFIG_HID_TWINHAN=y
 CONFIG_HID_KENSINGTON=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
@@ -1289,6 +1292,7 @@ CONFIG_USB=y
 #
 # 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
@@ -1379,6 +1383,7 @@ CONFIG_USB_STORAGE=m
 # 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_VST is not set
 # CONFIG_USB_GADGET is not set
@@ -1493,6 +1498,7 @@ CONFIG_FS_POSIX_ACL=y
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_FILE_LOCKING=y
 CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
@@ -1553,7 +1559,6 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 # CONFIG_NFS_FS is not set
 # CONFIG_NFSD is not set
@@ -1656,12 +1661,14 @@ CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_KPROBES_SANITY_TEST is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
@@ -1692,6 +1699,7 @@ CONFIG_BLK_DEV_IO_TRACE=y
 # CONFIG_FTRACE_STARTUP_TEST is not set
 # CONFIG_RING_BUFFER_BENCHMARK is not set
 # CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1716,7 +1724,6 @@ CONFIG_CRYPTO=y
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD=y
@@ -1759,11 +1766,13 @@ CONFIG_CRYPTO_XTS=m
 #
 CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_XCBC=y
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_GHASH is not set
 CONFIG_CRYPTO_MD4=y
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
index e5ea8d332421d1ad1441541c8e013d62d099e444..26cd25c0839977ae3ad1562d1806d9c52b42a5e9 100644 (file)
@@ -52,13 +52,12 @@ static inline int pcibus_to_node(struct pci_bus *pbus)
        .busy_idx               = 3,                    \
        .idle_idx               = 2,                    \
        .newidle_idx            = 0,                    \
-       .wake_idx               = 1,                    \
-       .forkexec_idx           = 1,                    \
+       .wake_idx               = 0,                    \
+       .forkexec_idx           = 0,                    \
        .flags                  = SD_LOAD_BALANCE       \
                                | SD_BALANCE_FORK       \
                                | SD_BALANCE_EXEC       \
-                               | SD_SERIALIZE          \
-                               | SD_WAKE_BALANCE,      \
+                               | SD_SERIALIZE,         \
        .last_balance           = jiffies,              \
        .balance_interval       = 1,                    \
 }
index 16a47ffe03c1fe163d90d2ec1318e61852d6c5db..9be2af55c5cd5f93bfc15895a07192b355d2bb08 100644 (file)
@@ -268,8 +268,6 @@ void __init setup_arch(char **cmdline_p)
 
 #ifdef CONFIG_DUMMY_CONSOLE
        conswitchp = &dummy_con;
-#elif defined(CONFIG_PROM_CONSOLE)
-       conswitchp = &prom_con;
 #endif
        boot_flags_init(*cmdline_p);
 
index f2bcfd2967d76e463d183873ce309b4c71e5ca42..21180339cb09dd2a9d054296703c4c6a10bf6578 100644 (file)
@@ -295,8 +295,6 @@ void __init setup_arch(char **cmdline_p)
 
 #ifdef CONFIG_DUMMY_CONSOLE
        conswitchp = &dummy_con;
-#elif defined(CONFIG_PROM_CONSOLE)
-       conswitchp = &prom_con;
 #endif
 
        idprom_init();
index e98e81a04971f1c953533982f6b127573e4058c1..e5deee2dfcfe601729033c0c06d5c92a6006a8e3 100644 (file)
@@ -783,41 +783,17 @@ config X86_REROUTE_FOR_BROKEN_BOOT_IRQS
          increased on these systems.
 
 config X86_MCE
-       bool "Machine Check Exception"
+       bool "Machine Check / overheating reporting"
        ---help---
-         Machine Check Exception support allows the processor to notify the
-         kernel if it detects a problem (e.g. overheating, component failure).
+         Machine Check support allows the processor to notify the
+         kernel if it detects a problem (e.g. overheating, data corruption).
          The action the kernel takes depends on the severity of the problem,
-         ranging from a warning message on the console, to halting the machine.
-         Your processor must be a Pentium or newer to support this - check the
-         flags in /proc/cpuinfo for mce.  Note that some older Pentium systems
-         have a design flaw which leads to false MCE events - hence MCE is
-         disabled on all P5 processors, unless explicitly enabled with "mce"
-         as a boot argument.  Similarly, if MCE is built in and creates a
-         problem on some new non-standard machine, you can boot with "nomce"
-         to disable it.  MCE support simply ignores non-MCE processors like
-         the 386 and 486, so nearly everyone can say Y here.
-
-config X86_OLD_MCE
-       depends on X86_32 && X86_MCE
-       bool "Use legacy machine check code (will go away)"
-       default n
-       select X86_ANCIENT_MCE
-       ---help---
-         Use the old i386 machine check code. This is merely intended for
-         testing in a transition period. Try this if you run into any machine
-         check related software problems, but report the problem to
-         linux-kernel.  When in doubt say no.
-
-config X86_NEW_MCE
-       depends on X86_MCE
-       bool
-       default y if (!X86_OLD_MCE && X86_32) || X86_64
+         ranging from warning messages to halting the machine.
 
 config X86_MCE_INTEL
        def_bool y
        prompt "Intel MCE features"
-       depends on X86_NEW_MCE && X86_LOCAL_APIC
+       depends on X86_MCE && X86_LOCAL_APIC
        ---help---
           Additional support for intel specific MCE features such as
           the thermal monitor.
@@ -825,14 +801,14 @@ config X86_MCE_INTEL
 config X86_MCE_AMD
        def_bool y
        prompt "AMD MCE features"
-       depends on X86_NEW_MCE && X86_LOCAL_APIC
+       depends on X86_MCE && X86_LOCAL_APIC
        ---help---
           Additional support for AMD specific MCE features such as
           the DRAM Error Threshold.
 
 config X86_ANCIENT_MCE
        def_bool n
-       depends on X86_32
+       depends on X86_32 && X86_MCE
        prompt "Support for old Pentium 5 / WinChip machine checks"
        ---help---
          Include support for machine check handling on old Pentium 5 or WinChip
@@ -845,36 +821,16 @@ config X86_MCE_THRESHOLD
        default y
 
 config X86_MCE_INJECT
-       depends on X86_NEW_MCE
+       depends on X86_MCE
        tristate "Machine check injector support"
        ---help---
          Provide support for injecting machine checks for testing purposes.
          If you don't know what a machine check is and you don't do kernel
          QA it is safe to say n.
 
-config X86_MCE_NONFATAL
-       tristate "Check for non-fatal errors on AMD Athlon/Duron / Intel Pentium 4"
-       depends on X86_OLD_MCE
-       ---help---
-         Enabling this feature starts a timer that triggers every 5 seconds which
-         will look at the machine check registers to see if anything happened.
-         Non-fatal problems automatically get corrected (but still logged).
-         Disable this if you don't want to see these messages.
-         Seeing the messages this option prints out may be indicative of dying
-         or out-of-spec (ie, overclocked) hardware.
-         This option only does something on certain CPUs.
-         (AMD Athlon/Duron and Intel Pentium 4)
-
-config X86_MCE_P4THERMAL
-       bool "check for P4 thermal throttling interrupt."
-       depends on X86_OLD_MCE && X86_MCE && (X86_UP_APIC || SMP)
-       ---help---
-         Enabling this feature will cause a message to be printed when the P4
-         enters thermal throttling.
-
 config X86_THERMAL_VECTOR
        def_bool y
-       depends on X86_MCE_P4THERMAL || X86_MCE_INTEL
+       depends on X86_MCE_INTEL
 
 config VM86
        bool "Enable VM86 support" if EMBEDDED
index 847fee6493a268f97c56db20cdbc56e7d24eadd8..9cfc88b97742c45492d814b1d30ae3b60139da90 100644 (file)
@@ -96,6 +96,7 @@
 #define X86_FEATURE_CLFLUSH_MONITOR (3*32+25) /* "" clflush reqd with monitor */
 #define X86_FEATURE_EXTD_APICID        (3*32+26) /* has extended APICID (8 bits) */
 #define X86_FEATURE_AMD_DCM     (3*32+27) /* multi-node processor */
+#define X86_FEATURE_APERFMPERF (3*32+28) /* APERFMPERF */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
 #define X86_FEATURE_XMM3       (4*32+ 0) /* "pni" SSE-3 */
index 83c1bc8d2e8a7ba071cdd591050bbd45e7cf678a..456a304b817266320ad59d6f6b49419ea4e1aa15 100644 (file)
@@ -299,6 +299,8 @@ do {                                                                        \
 
 #ifdef CONFIG_X86_32
 
+#define STACK_RND_MASK (0x7ff)
+
 #define VDSO_HIGH_BASE         (__fix_to_virt(FIX_VDSO))
 
 #define ARCH_DLINFO            ARCH_DLINFO_IA32(vdso_enabled)
index ff8cbfa07851a1b2ce121f70b84e4d4269331dfb..5e3f2044f0d3527191a16f98bf6234c5c1340cd6 100644 (file)
@@ -61,7 +61,7 @@ BUILD_INTERRUPT(thermal_interrupt,THERMAL_APIC_VECTOR)
 BUILD_INTERRUPT(threshold_interrupt,THRESHOLD_APIC_VECTOR)
 #endif
 
-#ifdef CONFIG_X86_NEW_MCE
+#ifdef CONFIG_X86_MCE
 BUILD_INTERRUPT(mce_self_interrupt,MCE_SELF_VECTOR)
 #endif
 
index 5cdd8d100ec9be96c1b8f627d7e428632c4980cf..b608a64c5814de6ca6b78ae050a301704fdadc0e 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 #define MCG_BANKCNT_MASK       0xff         /* Number of Banks */
-#define MCG_CTL_P              (1ULL<<8)    /* MCG_CAP register available */
+#define MCG_CTL_P              (1ULL<<8)    /* MCG_CTL register available */
 #define MCG_EXT_P              (1ULL<<9)    /* Extended registers available */
 #define MCG_CMCI_P             (1ULL<<10)   /* CMCI supported */
 #define MCG_EXT_CNT_MASK       0xff0000     /* Number of Extended registers */
 #define MCM_ADDR_MEM    3      /* memory address */
 #define MCM_ADDR_GENERIC 7     /* generic */
 
+#define MCJ_CTX_MASK           3
+#define MCJ_CTX(flags)         ((flags) & MCJ_CTX_MASK)
+#define MCJ_CTX_RANDOM         0    /* inject context: random */
+#define MCJ_CTX_PROCESS                1    /* inject context: process */
+#define MCJ_CTX_IRQ            2    /* inject context: IRQ */
+#define MCJ_NMI_BROADCAST      4    /* do NMI broadcasting */
+#define MCJ_EXCEPTION          8    /* raise as exception */
+
 /* Fields are zero when not available */
 struct mce {
        __u64 status;
@@ -48,8 +56,8 @@ struct mce {
        __u64 tsc;      /* cpu time stamp counter */
        __u64 time;     /* wall time_t when error was detected */
        __u8  cpuvendor;        /* cpu vendor as encoded in system.h */
-       __u8  pad1;
-       __u16 pad2;
+       __u8  inject_flags;     /* software inject flags */
+       __u16  pad;
        __u32 cpuid;    /* CPUID 1 EAX */
        __u8  cs;               /* code segment */
        __u8  bank;     /* machine check bank */
@@ -115,13 +123,6 @@ void mcheck_init(struct cpuinfo_x86 *c);
 static inline void mcheck_init(struct cpuinfo_x86 *c) {}
 #endif
 
-#ifdef CONFIG_X86_OLD_MCE
-extern int nr_mce_banks;
-void amd_mcheck_init(struct cpuinfo_x86 *c);
-void intel_p4_mcheck_init(struct cpuinfo_x86 *c);
-void intel_p6_mcheck_init(struct cpuinfo_x86 *c);
-#endif
-
 #ifdef CONFIG_X86_ANCIENT_MCE
 void intel_p5_mcheck_init(struct cpuinfo_x86 *c);
 void winchip_mcheck_init(struct cpuinfo_x86 *c);
@@ -137,10 +138,11 @@ void mce_log(struct mce *m);
 DECLARE_PER_CPU(struct sys_device, mce_dev);
 
 /*
- * To support more than 128 would need to escape the predefined
- * Linux defined extended banks first.
+ * Maximum banks number.
+ * This is the limit of the current register layout on
+ * Intel CPUs.
  */
-#define MAX_NR_BANKS (MCE_EXTENDED_BANK - 1)
+#define MAX_NR_BANKS 32
 
 #ifdef CONFIG_X86_MCE_INTEL
 extern int mce_cmci_disabled;
@@ -208,11 +210,7 @@ extern void (*threshold_cpu_callback)(unsigned long action, unsigned int cpu);
 
 void intel_init_thermal(struct cpuinfo_x86 *c);
 
-#ifdef CONFIG_X86_NEW_MCE
 void mce_log_therm_throt_event(__u64 status);
-#else
-static inline void mce_log_therm_throt_event(__u64 status) {}
-#endif
 
 #endif /* __KERNEL__ */
 #endif /* _ASM_X86_MCE_H */
index bd5549034a956101377100833bb3f7c9a2c560ec..4ffe09b2ad7511c3e50a1f4465923c2f522dd3d6 100644 (file)
 #define MSR_IA32_MC0_ADDR              0x00000402
 #define MSR_IA32_MC0_MISC              0x00000403
 
+#define MSR_IA32_MCx_CTL(x)            (MSR_IA32_MC0_CTL + 4*(x))
+#define MSR_IA32_MCx_STATUS(x)         (MSR_IA32_MC0_STATUS + 4*(x))
+#define MSR_IA32_MCx_ADDR(x)           (MSR_IA32_MC0_ADDR + 4*(x))
+#define MSR_IA32_MCx_MISC(x)           (MSR_IA32_MC0_MISC + 4*(x))
+
 /* These are consecutive and not in the normal 4er MCE bank block */
 #define MSR_IA32_MC0_CTL2              0x00000280
+#define MSR_IA32_MCx_CTL2(x)           (MSR_IA32_MC0_CTL2 + (x))
+
 #define CMCI_EN                        (1ULL << 30)
 #define CMCI_THRESHOLD_MASK            0xffffULL
 
 
 #define THERM_STATUS_PROCHOT           (1 << 0)
 
+#define MSR_THERM2_CTL                 0x0000019d
+
+#define MSR_THERM2_CTL_TM_SELECT       (1ULL << 16)
+
 #define MSR_IA32_MISC_ENABLE           0x000001a0
 
 /* MISC_ENABLE bits: architectural */
index ad2668ee1aa7af8cc6fa62fdede3e58b08966ab1..6d8723a766cc1dc67c4a92264d02083f7c2127ed 100644 (file)
@@ -65,6 +65,8 @@
    6: osp nopl 0x00(%eax,%eax,1)
    7: nopl 0x00000000(%eax)
    8: nopl 0x00000000(%eax,%eax,1)
+   Note: All the above are assumed to be a single instruction.
+       There is kernel code that depends on this.
 */
 #define P6_NOP1        GENERIC_NOP1
 #define P6_NOP2        ".byte 0x66,0x90\n"
index e08ea043e085c7a35882cf382dc218d17a97b00c..c3429e8b2424841af488615785a9d2d098580eb0 100644 (file)
@@ -27,6 +27,7 @@ struct mm_struct;
 #include <linux/cpumask.h>
 #include <linux/cache.h>
 #include <linux/threads.h>
+#include <linux/math64.h>
 #include <linux/init.h>
 
 /*
@@ -1020,4 +1021,35 @@ extern void start_thread(struct pt_regs *regs, unsigned long new_ip,
 extern int get_tsc_mode(unsigned long adr);
 extern int set_tsc_mode(unsigned int val);
 
+extern int amd_get_nb_id(int cpu);
+
+struct aperfmperf {
+       u64 aperf, mperf;
+};
+
+static inline void get_aperfmperf(struct aperfmperf *am)
+{
+       WARN_ON_ONCE(!boot_cpu_has(X86_FEATURE_APERFMPERF));
+
+       rdmsrl(MSR_IA32_APERF, am->aperf);
+       rdmsrl(MSR_IA32_MPERF, am->mperf);
+}
+
+#define APERFMPERF_SHIFT 10
+
+static inline
+unsigned long calc_aperfmperf_ratio(struct aperfmperf *old,
+                                   struct aperfmperf *new)
+{
+       u64 aperf = new->aperf - old->aperf;
+       u64 mperf = new->mperf - old->mperf;
+       unsigned long ratio = aperf;
+
+       mperf >>= APERFMPERF_SHIFT;
+       if (mperf)
+               ratio = div64_u64(aperf, mperf);
+
+       return ratio;
+}
+
 #endif /* _ASM_X86_PROCESSOR_H */
index 26d06e052a181073851197c2110ce8d61916d5be..6f0695d744bf1a44304862fe8898cf24ce815ece 100644 (file)
@@ -116,15 +116,11 @@ extern unsigned long node_remap_size[];
 
 # define SD_CACHE_NICE_TRIES   1
 # define SD_IDLE_IDX           1
-# define SD_NEWIDLE_IDX                2
-# define SD_FORKEXEC_IDX       0
 
 #else
 
 # define SD_CACHE_NICE_TRIES   2
 # define SD_IDLE_IDX           2
-# define SD_NEWIDLE_IDX                2
-# define SD_FORKEXEC_IDX       1
 
 #endif
 
@@ -137,22 +133,20 @@ extern unsigned long node_remap_size[];
        .cache_nice_tries       = SD_CACHE_NICE_TRIES,                  \
        .busy_idx               = 3,                                    \
        .idle_idx               = SD_IDLE_IDX,                          \
-       .newidle_idx            = SD_NEWIDLE_IDX,                       \
-       .wake_idx               = 1,                                    \
-       .forkexec_idx           = SD_FORKEXEC_IDX,                      \
+       .newidle_idx            = 0,                                    \
+       .wake_idx               = 0,                                    \
+       .forkexec_idx           = 0,                                    \
                                                                        \
        .flags                  = 1*SD_LOAD_BALANCE                     \
                                | 1*SD_BALANCE_NEWIDLE                  \
                                | 1*SD_BALANCE_EXEC                     \
                                | 1*SD_BALANCE_FORK                     \
-                               | 0*SD_WAKE_IDLE                        \
+                               | 0*SD_BALANCE_WAKE                     \
                                | 1*SD_WAKE_AFFINE                      \
-                               | 1*SD_WAKE_BALANCE                     \
                                | 0*SD_SHARE_CPUPOWER                   \
                                | 0*SD_POWERSAVINGS_BALANCE             \
                                | 0*SD_SHARE_PKG_RESOURCES              \
                                | 1*SD_SERIALIZE                        \
-                               | 1*SD_WAKE_IDLE_FAR                    \
                                | 0*SD_PREFER_SIBLING                   \
                                ,                                       \
        .last_balance           = jiffies,                              \
index dc27a69e5d2ab1754153afb9281d6023caa18cd4..3d61e204826f1da5b6cb747957818a0e7b2d3913 100644 (file)
@@ -21,6 +21,7 @@ struct vsyscall_gtod_data {
                u32     shift;
        } clock;
        struct timespec wall_to_monotonic;
+       struct timespec wall_time_coarse;
 };
 extern struct vsyscall_gtod_data __vsyscall_gtod_data
 __section_vsyscall_gtod_data;
index db7220220d0927bb2756f5effd6da5aa539cd8b5..cb66a22d98ad72a3ad9eae5fc5b606beb15bcb94 100644 (file)
@@ -66,7 +66,7 @@ static inline unsigned int get_nmi_count(int cpu)
 
 static inline int mce_in_progress(void)
 {
-#if defined(CONFIG_X86_NEW_MCE)
+#if defined(CONFIG_X86_MCE)
        return atomic_read(&mce_entry) > 0;
 #endif
        return 0;
index c1f253dac1552f63c0795a31ce5977b681b98592..8dd30638fe4457ea6810bcbfd5476462b29890f9 100644 (file)
@@ -13,7 +13,7 @@ CFLAGS_common.o               := $(nostackp)
 
 obj-y                  := intel_cacheinfo.o addon_cpuid_features.o
 obj-y                  += proc.o capflags.o powerflags.o common.o
-obj-y                  += vmware.o hypervisor.o
+obj-y                  += vmware.o hypervisor.o sched.o
 
 obj-$(CONFIG_X86_32)   += bugs.o cmpxchg.o
 obj-$(CONFIG_X86_64)   += bugs_64.o
index 22a47c82f3c022d3de0fb0b08397fc9ea0ba422c..f32fa71ccf976ec0551916a075b6cedc69f41ea7 100644 (file)
@@ -333,6 +333,16 @@ static void __cpuinit amd_detect_cmp(struct cpuinfo_x86 *c)
 #endif
 }
 
+int amd_get_nb_id(int cpu)
+{
+       int id = 0;
+#ifdef CONFIG_SMP
+       id = per_cpu(cpu_llc_id, cpu);
+#endif
+       return id;
+}
+EXPORT_SYMBOL_GPL(amd_get_nb_id);
+
 static void __cpuinit srat_detect_node(struct cpuinfo_x86 *c)
 {
 #if defined(CONFIG_NUMA) && defined(CONFIG_X86_64)
index ae9b503220cafa62e818afd4bfcf3b849a86c4b3..7bb676c533aa8258c0d075323b3031b7f6bd5951 100644 (file)
@@ -60,7 +60,6 @@ enum {
 };
 
 #define INTEL_MSR_RANGE                (0xffff)
-#define CPUID_6_ECX_APERFMPERF_CAPABILITY      (0x1)
 
 struct acpi_cpufreq_data {
        struct acpi_processor_performance *acpi_data;
@@ -71,11 +70,7 @@ struct acpi_cpufreq_data {
 
 static DEFINE_PER_CPU(struct acpi_cpufreq_data *, drv_data);
 
-struct acpi_msr_data {
-       u64 saved_aperf, saved_mperf;
-};
-
-static DEFINE_PER_CPU(struct acpi_msr_data, msr_data);
+static DEFINE_PER_CPU(struct aperfmperf, old_perf);
 
 DEFINE_TRACE(power_mark);
 
@@ -244,23 +239,12 @@ static u32 get_cur_val(const struct cpumask *mask)
        return cmd.val;
 }
 
-struct perf_pair {
-       union {
-               struct {
-                       u32 lo;
-                       u32 hi;
-               } split;
-               u64 whole;
-       } aperf, mperf;
-};
-
 /* Called via smp_call_function_single(), on the target CPU */
 static void read_measured_perf_ctrs(void *_cur)
 {
-       struct perf_pair *cur = _cur;
+       struct aperfmperf *am = _cur;
 
-       rdmsr(MSR_IA32_APERF, cur->aperf.split.lo, cur->aperf.split.hi);
-       rdmsr(MSR_IA32_MPERF, cur->mperf.split.lo, cur->mperf.split.hi);
+       get_aperfmperf(am);
 }
 
 /*
@@ -279,63 +263,17 @@ static void read_measured_perf_ctrs(void *_cur)
 static unsigned int get_measured_perf(struct cpufreq_policy *policy,
                                      unsigned int cpu)
 {
-       struct perf_pair readin, cur;
-       unsigned int perf_percent;
+       struct aperfmperf perf;
+       unsigned long ratio;
        unsigned int retval;
 
-       if (smp_call_function_single(cpu, read_measured_perf_ctrs, &readin, 1))
+       if (smp_call_function_single(cpu, read_measured_perf_ctrs, &perf, 1))
                return 0;
 
-       cur.aperf.whole = readin.aperf.whole -
-                               per_cpu(msr_data, cpu).saved_aperf;
-       cur.mperf.whole = readin.mperf.whole -
-                               per_cpu(msr_data, cpu).saved_mperf;
-       per_cpu(msr_data, cpu).saved_aperf = readin.aperf.whole;
-       per_cpu(msr_data, cpu).saved_mperf = readin.mperf.whole;
-
-#ifdef __i386__
-       /*
-        * We dont want to do 64 bit divide with 32 bit kernel
-        * Get an approximate value. Return failure in case we cannot get
-        * an approximate value.
-        */
-       if (unlikely(cur.aperf.split.hi || cur.mperf.split.hi)) {
-               int shift_count;
-               u32 h;
-
-               h = max_t(u32, cur.aperf.split.hi, cur.mperf.split.hi);
-               shift_count = fls(h);
-
-               cur.aperf.whole >>= shift_count;
-               cur.mperf.whole >>= shift_count;
-       }
-
-       if (((unsigned long)(-1) / 100) < cur.aperf.split.lo) {
-               int shift_count = 7;
-               cur.aperf.split.lo >>= shift_count;
-               cur.mperf.split.lo >>= shift_count;
-       }
-
-       if (cur.aperf.split.lo && cur.mperf.split.lo)
-               perf_percent = (cur.aperf.split.lo * 100) / cur.mperf.split.lo;
-       else
-               perf_percent = 0;
+       ratio = calc_aperfmperf_ratio(&per_cpu(old_perf, cpu), &perf);
+       per_cpu(old_perf, cpu) = perf;
 
-#else
-       if (unlikely(((unsigned long)(-1) / 100) < cur.aperf.whole)) {
-               int shift_count = 7;
-               cur.aperf.whole >>= shift_count;
-               cur.mperf.whole >>= shift_count;
-       }
-
-       if (cur.aperf.whole && cur.mperf.whole)
-               perf_percent = (cur.aperf.whole * 100) / cur.mperf.whole;
-       else
-               perf_percent = 0;
-
-#endif
-
-       retval = (policy->cpuinfo.max_freq * perf_percent) / 100;
+       retval = (policy->cpuinfo.max_freq * ratio) >> APERFMPERF_SHIFT;
 
        return retval;
 }
@@ -588,6 +526,21 @@ static const struct dmi_system_id sw_any_bug_dmi_table[] = {
        },
        { }
 };
+
+static int acpi_cpufreq_blacklist(struct cpuinfo_x86 *c)
+{
+       /* http://www.intel.com/Assets/PDF/specupdate/314554.pdf
+        * AL30: A Machine Check Exception (MCE) Occurring during an
+        * Enhanced Intel SpeedStep Technology Ratio Change May Cause
+        * Both Processor Cores to Lock Up when HT is enabled*/
+       if (c->x86_vendor == X86_VENDOR_INTEL) {
+               if ((c->x86 == 15) &&
+                   (c->x86_model == 6) &&
+                   (c->x86_mask == 8) && smt_capable())
+                       return -ENODEV;
+               }
+       return 0;
+}
 #endif
 
 static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
@@ -602,6 +555,12 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
 
        dprintk("acpi_cpufreq_cpu_init\n");
 
+#ifdef CONFIG_SMP
+       result = acpi_cpufreq_blacklist(c);
+       if (result)
+               return result;
+#endif
+
        data = kzalloc(sizeof(struct acpi_cpufreq_data), GFP_KERNEL);
        if (!data)
                return -ENOMEM;
@@ -731,12 +690,8 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
        acpi_processor_notify_smm(THIS_MODULE);
 
        /* Check for APERF/MPERF support in hardware */
-       if (c->x86_vendor == X86_VENDOR_INTEL && c->cpuid_level >= 6) {
-               unsigned int ecx;
-               ecx = cpuid_ecx(6);
-               if (ecx & CPUID_6_ECX_APERFMPERF_CAPABILITY)
-                       acpi_cpufreq_driver.getavg = get_measured_perf;
-       }
+       if (cpu_has(c, X86_FEATURE_APERFMPERF))
+               acpi_cpufreq_driver.getavg = get_measured_perf;
 
        dprintk("CPU%u - ACPI performance management activated.\n", cpu);
        for (i = 0; i < perf->state_count; i++)
index 2a50ef891000f3c114374c1a28bdbf4f26a36d67..6394aa5c7985b17ea0c18a9d9ae6859cd7b66585 100644 (file)
@@ -605,9 +605,10 @@ static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst,
        return 0;
 }
 
-static void invalidate_entry(struct powernow_k8_data *data, unsigned int entry)
+static void invalidate_entry(struct cpufreq_frequency_table *powernow_table,
+               unsigned int entry)
 {
-       data->powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID;
+       powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID;
 }
 
 static void print_basics(struct powernow_k8_data *data)
@@ -854,6 +855,10 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
                goto err_out;
        }
 
+       /* fill in data */
+       data->numps = data->acpi_data.state_count;
+       powernow_k8_acpi_pst_values(data, 0);
+
        if (cpu_family == CPU_HW_PSTATE)
                ret_val = fill_powernow_table_pstate(data, powernow_table);
        else
@@ -866,11 +871,8 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
        powernow_table[data->acpi_data.state_count].index = 0;
        data->powernow_table = powernow_table;
 
-       /* fill in data */
-       data->numps = data->acpi_data.state_count;
        if (cpumask_first(cpu_core_mask(data->cpu)) == data->cpu)
                print_basics(data);
-       powernow_k8_acpi_pst_values(data, 0);
 
        /* notify BIOS that we exist */
        acpi_processor_notify_smm(THIS_MODULE);
@@ -914,13 +916,13 @@ static int fill_powernow_table_pstate(struct powernow_k8_data *data,
                                        "bad value %d.\n", i, index);
                        printk(KERN_ERR PFX "Please report to BIOS "
                                        "manufacturer\n");
-                       invalidate_entry(data, i);
+                       invalidate_entry(powernow_table, i);
                        continue;
                }
                rdmsr(MSR_PSTATE_DEF_BASE + index, lo, hi);
                if (!(hi & HW_PSTATE_VALID_MASK)) {
                        dprintk("invalid pstate %d, ignoring\n", index);
-                       invalidate_entry(data, i);
+                       invalidate_entry(powernow_table, i);
                        continue;
                }
 
@@ -941,7 +943,6 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data,
                struct cpufreq_frequency_table *powernow_table)
 {
        int i;
-       int cntlofreq = 0;
 
        for (i = 0; i < data->acpi_data.state_count; i++) {
                u32 fid;
@@ -970,7 +971,7 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data,
                /* verify frequency is OK */
                if ((freq > (MAX_FREQ * 1000)) || (freq < (MIN_FREQ * 1000))) {
                        dprintk("invalid freq %u kHz, ignoring\n", freq);
-                       invalidate_entry(data, i);
+                       invalidate_entry(powernow_table, i);
                        continue;
                }
 
@@ -978,38 +979,17 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data,
                 * BIOSs are using "off" to indicate invalid */
                if (vid == VID_OFF) {
                        dprintk("invalid vid %u, ignoring\n", vid);
-                       invalidate_entry(data, i);
+                       invalidate_entry(powernow_table, i);
                        continue;
                }
 
-               /* verify only 1 entry from the lo frequency table */
-               if (fid < HI_FID_TABLE_BOTTOM) {
-                       if (cntlofreq) {
-                               /* if both entries are the same,
-                                * ignore this one ... */
-                               if ((freq != powernow_table[cntlofreq].frequency) ||
-                                   (index != powernow_table[cntlofreq].index)) {
-                                       printk(KERN_ERR PFX
-                                               "Too many lo freq table "
-                                               "entries\n");
-                                       return 1;
-                               }
-
-                               dprintk("double low frequency table entry, "
-                                               "ignoring it.\n");
-                               invalidate_entry(data, i);
-                               continue;
-                       } else
-                               cntlofreq = i;
-               }
-
                if (freq != (data->acpi_data.states[i].core_frequency * 1000)) {
                        printk(KERN_INFO PFX "invalid freq entries "
                                "%u kHz vs. %u kHz\n", freq,
                                (unsigned int)
                                (data->acpi_data.states[i].core_frequency
                                 * 1000));
-                       invalidate_entry(data, i);
+                       invalidate_entry(powernow_table, i);
                        continue;
                }
        }
index 80a722a071b51dd9da2b2297d825ac2c0237ba82..40e1835b35e881d3479baec9d0bfa7f7ba48da9a 100644 (file)
@@ -350,6 +350,12 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
                        set_cpu_cap(c, X86_FEATURE_ARCH_PERFMON);
        }
 
+       if (c->cpuid_level > 6) {
+               unsigned ecx = cpuid_ecx(6);
+               if (ecx & 0x01)
+                       set_cpu_cap(c, X86_FEATURE_APERFMPERF);
+       }
+
        if (cpu_has_xmm2)
                set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
        if (cpu_has_ds) {
index 188a1ca5ad2b10d7c7918bcb3c0b2fb13441b617..4ac6d48fe11bc66eb2d8283e83438b0947e5ae92 100644 (file)
@@ -1,11 +1,8 @@
-obj-y                          =  mce.o
+obj-y                          =  mce.o mce-severity.o
 
-obj-$(CONFIG_X86_NEW_MCE)      += mce-severity.o
-obj-$(CONFIG_X86_OLD_MCE)      += k7.o p4.o p6.o
 obj-$(CONFIG_X86_ANCIENT_MCE)  += winchip.o p5.o
 obj-$(CONFIG_X86_MCE_INTEL)    += mce_intel.o
 obj-$(CONFIG_X86_MCE_AMD)      += mce_amd.o
-obj-$(CONFIG_X86_MCE_NONFATAL) += non-fatal.o
 obj-$(CONFIG_X86_MCE_THRESHOLD) += threshold.o
 obj-$(CONFIG_X86_MCE_INJECT)   += mce-inject.o
 
diff --git a/arch/x86/kernel/cpu/mcheck/k7.c b/arch/x86/kernel/cpu/mcheck/k7.c
deleted file mode 100644 (file)
index b945d5d..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Athlon specific Machine Check Exception Reporting
- * (C) Copyright 2002 Dave Jones <davej@redhat.com>
- */
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/smp.h>
-
-#include <asm/processor.h>
-#include <asm/system.h>
-#include <asm/mce.h>
-#include <asm/msr.h>
-
-/* Machine Check Handler For AMD Athlon/Duron: */
-static void k7_machine_check(struct pt_regs *regs, long error_code)
-{
-       u32 alow, ahigh, high, low;
-       u32 mcgstl, mcgsth;
-       int recover = 1;
-       int i;
-
-       rdmsr(MSR_IA32_MCG_STATUS, mcgstl, mcgsth);
-       if (mcgstl & (1<<0))    /* Recoverable ? */
-               recover = 0;
-
-       printk(KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n",
-               smp_processor_id(), mcgsth, mcgstl);
-
-       for (i = 1; i < nr_mce_banks; i++) {
-               rdmsr(MSR_IA32_MC0_STATUS+i*4, low, high);
-               if (high & (1<<31)) {
-                       char misc[20];
-                       char addr[24];
-
-                       misc[0] = '\0';
-                       addr[0] = '\0';
-
-                       if (high & (1<<29))
-                               recover |= 1;
-                       if (high & (1<<25))
-                               recover |= 2;
-                       high &= ~(1<<31);
-
-                       if (high & (1<<27)) {
-                               rdmsr(MSR_IA32_MC0_MISC+i*4, alow, ahigh);
-                               snprintf(misc, 20, "[%08x%08x]", ahigh, alow);
-                       }
-                       if (high & (1<<26)) {
-                               rdmsr(MSR_IA32_MC0_ADDR+i*4, alow, ahigh);
-                               snprintf(addr, 24, " at %08x%08x", ahigh, alow);
-                       }
-
-                       printk(KERN_EMERG "CPU %d: Bank %d: %08x%08x%s%s\n",
-                               smp_processor_id(), i, high, low, misc, addr);
-
-                       /* Clear it: */
-                       wrmsr(MSR_IA32_MC0_STATUS+i*4, 0UL, 0UL);
-                       /* Serialize: */
-                       wmb();
-                       add_taint(TAINT_MACHINE_CHECK);
-               }
-       }
-
-       if (recover & 2)
-               panic("CPU context corrupt");
-       if (recover & 1)
-               panic("Unable to continue");
-
-       printk(KERN_EMERG "Attempting to continue.\n");
-
-       mcgstl &= ~(1<<2);
-       wrmsr(MSR_IA32_MCG_STATUS, mcgstl, mcgsth);
-}
-
-
-/* AMD K7 machine check is Intel like: */
-void amd_mcheck_init(struct cpuinfo_x86 *c)
-{
-       u32 l, h;
-       int i;
-
-       if (!cpu_has(c, X86_FEATURE_MCE))
-               return;
-
-       machine_check_vector = k7_machine_check;
-       /* Make sure the vector pointer is visible before we enable MCEs: */
-       wmb();
-
-       printk(KERN_INFO "Intel machine check architecture supported.\n");
-
-       rdmsr(MSR_IA32_MCG_CAP, l, h);
-       if (l & (1<<8)) /* Control register present ? */
-               wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);
-       nr_mce_banks = l & 0xff;
-
-       /*
-        * Clear status for MC index 0 separately, we don't touch CTL,
-        * as some K7 Athlons cause spurious MCEs when its enabled:
-        */
-       if (boot_cpu_data.x86 == 6) {
-               wrmsr(MSR_IA32_MC0_STATUS, 0x0, 0x0);
-               i = 1;
-       } else
-               i = 0;
-
-       for (; i < nr_mce_banks; i++) {
-               wrmsr(MSR_IA32_MC0_CTL+4*i, 0xffffffff, 0xffffffff);
-               wrmsr(MSR_IA32_MC0_STATUS+4*i, 0x0, 0x0);
-       }
-
-       set_in_cr4(X86_CR4_MCE);
-       printk(KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n",
-               smp_processor_id());
-}
index a3a235a53f091e01bfd509e0bfed353f232e7d83..7029f0e2acadef9bc0e6d93820cc4ab08bb09797 100644 (file)
 #include <linux/string.h>
 #include <linux/fs.h>
 #include <linux/smp.h>
+#include <linux/notifier.h>
+#include <linux/kdebug.h>
+#include <linux/cpu.h>
+#include <linux/sched.h>
 #include <asm/mce.h>
+#include <asm/apic.h>
 
 /* Update fake mce registers on current CPU. */
 static void inject_mce(struct mce *m)
@@ -39,44 +44,141 @@ static void inject_mce(struct mce *m)
        i->finished = 1;
 }
 
-struct delayed_mce {
-       struct timer_list timer;
-       struct mce m;
-};
+static void raise_poll(struct mce *m)
+{
+       unsigned long flags;
+       mce_banks_t b;
 
-/* Inject mce on current CPU */
-static void raise_mce(unsigned long data)
+       memset(&b, 0xff, sizeof(mce_banks_t));
+       local_irq_save(flags);
+       machine_check_poll(0, &b);
+       local_irq_restore(flags);
+       m->finished = 0;
+}
+
+static void raise_exception(struct mce *m, struct pt_regs *pregs)
 {
-       struct delayed_mce *dm = (struct delayed_mce *)data;
-       struct mce *m = &dm->m;
-       int cpu = m->extcpu;
+       struct pt_regs regs;
+       unsigned long flags;
 
-       inject_mce(m);
-       if (m->status & MCI_STATUS_UC) {
-               struct pt_regs regs;
+       if (!pregs) {
                memset(&regs, 0, sizeof(struct pt_regs));
                regs.ip = m->ip;
                regs.cs = m->cs;
+               pregs = &regs;
+       }
+       /* in mcheck exeception handler, irq will be disabled */
+       local_irq_save(flags);
+       do_machine_check(pregs, 0);
+       local_irq_restore(flags);
+       m->finished = 0;
+}
+
+static cpumask_t mce_inject_cpumask;
+
+static int mce_raise_notify(struct notifier_block *self,
+                           unsigned long val, void *data)
+{
+       struct die_args *args = (struct die_args *)data;
+       int cpu = smp_processor_id();
+       struct mce *m = &__get_cpu_var(injectm);
+       if (val != DIE_NMI_IPI || !cpu_isset(cpu, mce_inject_cpumask))
+               return NOTIFY_DONE;
+       cpu_clear(cpu, mce_inject_cpumask);
+       if (m->inject_flags & MCJ_EXCEPTION)
+               raise_exception(m, args->regs);
+       else if (m->status)
+               raise_poll(m);
+       return NOTIFY_STOP;
+}
+
+static struct notifier_block mce_raise_nb = {
+       .notifier_call = mce_raise_notify,
+       .priority = 1000,
+};
+
+/* Inject mce on current CPU */
+static int raise_local(struct mce *m)
+{
+       int context = MCJ_CTX(m->inject_flags);
+       int ret = 0;
+       int cpu = m->extcpu;
+
+       if (m->inject_flags & MCJ_EXCEPTION) {
                printk(KERN_INFO "Triggering MCE exception on CPU %d\n", cpu);
-               do_machine_check(&regs, 0);
+               switch (context) {
+               case MCJ_CTX_IRQ:
+                       /*
+                        * Could do more to fake interrupts like
+                        * calling irq_enter, but the necessary
+                        * machinery isn't exported currently.
+                        */
+                       /*FALL THROUGH*/
+               case MCJ_CTX_PROCESS:
+                       raise_exception(m, NULL);
+                       break;
+               default:
+                       printk(KERN_INFO "Invalid MCE context\n");
+                       ret = -EINVAL;
+               }
                printk(KERN_INFO "MCE exception done on CPU %d\n", cpu);
-       } else {
-               mce_banks_t b;
-               memset(&b, 0xff, sizeof(mce_banks_t));
+       } else if (m->status) {
                printk(KERN_INFO "Starting machine check poll CPU %d\n", cpu);
-               machine_check_poll(0, &b);
+               raise_poll(m);
                mce_notify_irq();
-               printk(KERN_INFO "Finished machine check poll on CPU %d\n",
-                      cpu);
-       }
-       kfree(dm);
+               printk(KERN_INFO "Machine check poll done on CPU %d\n", cpu);
+       } else
+               m->finished = 0;
+
+       return ret;
+}
+
+static void raise_mce(struct mce *m)
+{
+       int context = MCJ_CTX(m->inject_flags);
+
+       inject_mce(m);
+
+       if (context == MCJ_CTX_RANDOM)
+               return;
+
+#ifdef CONFIG_X86_LOCAL_APIC
+       if (m->inject_flags & MCJ_NMI_BROADCAST) {
+               unsigned long start;
+               int cpu;
+               get_online_cpus();
+               mce_inject_cpumask = cpu_online_map;
+               cpu_clear(get_cpu(), mce_inject_cpumask);
+               for_each_online_cpu(cpu) {
+                       struct mce *mcpu = &per_cpu(injectm, cpu);
+                       if (!mcpu->finished ||
+                           MCJ_CTX(mcpu->inject_flags) != MCJ_CTX_RANDOM)
+                               cpu_clear(cpu, mce_inject_cpumask);
+               }
+               if (!cpus_empty(mce_inject_cpumask))
+                       apic->send_IPI_mask(&mce_inject_cpumask, NMI_VECTOR);
+               start = jiffies;
+               while (!cpus_empty(mce_inject_cpumask)) {
+                       if (!time_before(jiffies, start + 2*HZ)) {
+                               printk(KERN_ERR
+                               "Timeout waiting for mce inject NMI %lx\n",
+                                       *cpus_addr(mce_inject_cpumask));
+                               break;
+                       }
+                       cpu_relax();
+               }
+               raise_local(m);
+               put_cpu();
+               put_online_cpus();
+       } else
+#endif
+               raise_local(m);
 }
 
 /* Error injection interface */
 static ssize_t mce_write(struct file *filp, const char __user *ubuf,
                         size_t usize, loff_t *off)
 {
-       struct delayed_mce *dm;
        struct mce m;
 
        if (!capable(CAP_SYS_ADMIN))
@@ -96,19 +198,12 @@ static ssize_t mce_write(struct file *filp, const char __user *ubuf,
        if (m.extcpu >= num_possible_cpus() || !cpu_online(m.extcpu))
                return -EINVAL;
 
-       dm = kmalloc(sizeof(struct delayed_mce), GFP_KERNEL);
-       if (!dm)
-               return -ENOMEM;
-
        /*
         * Need to give user space some time to set everything up,
         * so do it a jiffie or two later everywhere.
-        * Should we use a hrtimer here for better synchronization?
         */
-       memcpy(&dm->m, &m, sizeof(struct mce));
-       setup_timer(&dm->timer, raise_mce, (unsigned long)dm);
-       dm->timer.expires = jiffies + 2;
-       add_timer_on(&dm->timer, m.extcpu);
+       schedule_timeout(2);
+       raise_mce(&m);
        return usize;
 }
 
@@ -116,6 +211,7 @@ static int inject_init(void)
 {
        printk(KERN_INFO "Machine check injector initialized\n");
        mce_chrdev_ops.write = mce_write;
+       register_die_notifier(&mce_raise_nb);
        return 0;
 }
 
index 54dcb8ff12e504b76e10ebe4c845429c3232e9cd..32996f9fab670be274b925e7ec3a4bd52e8650c3 100644 (file)
@@ -1,3 +1,4 @@
+#include <linux/sysdev.h>
 #include <asm/mce.h>
 
 enum severity_level {
@@ -10,6 +11,20 @@ enum severity_level {
        MCE_PANIC_SEVERITY,
 };
 
+#define ATTR_LEN               16
+
+/* One object for each MCE bank, shared by all CPUs */
+struct mce_bank {
+       u64                     ctl;                    /* subevents to enable */
+       unsigned char init;                             /* initialise bank? */
+       struct sysdev_attribute attr;                   /* sysdev attribute */
+       char                    attrname[ATTR_LEN];     /* attribute name */
+};
+
 int mce_severity(struct mce *a, int tolerant, char **msg);
+struct dentry *mce_get_debugfs_dir(void);
 
 extern int mce_ser;
+
+extern struct mce_bank *mce_banks;
+
index ff0807f9705668861ed227ec2fff1b7fa9f919fe..8a85dd1b1aa1d515e76b1e1cd9fdb213b27a6bcd 100644 (file)
@@ -139,6 +139,7 @@ int mce_severity(struct mce *a, int tolerant, char **msg)
        }
 }
 
+#ifdef CONFIG_DEBUG_FS
 static void *s_start(struct seq_file *f, loff_t *pos)
 {
        if (*pos >= ARRAY_SIZE(severities))
@@ -197,7 +198,7 @@ static int __init severities_debugfs_init(void)
 {
        struct dentry *dmce = NULL, *fseverities_coverage = NULL;
 
-       dmce = debugfs_create_dir("mce", NULL);
+       dmce = mce_get_debugfs_dir();
        if (dmce == NULL)
                goto err_out;
        fseverities_coverage = debugfs_create_file("severities-coverage",
@@ -209,10 +210,7 @@ static int __init severities_debugfs_init(void)
        return 0;
 
 err_out:
-       if (fseverities_coverage)
-               debugfs_remove(fseverities_coverage);
-       if (dmce)
-               debugfs_remove(dmce);
        return -ENOMEM;
 }
 late_initcall(severities_debugfs_init);
+#endif
index fdd51b554355049298ed2474fc7e5f1468c558fc..2f5aab26320e120b3531247e7682b1221721f96e 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/smp.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
+#include <linux/debugfs.h>
 
 #include <asm/processor.h>
 #include <asm/hw_irq.h>
 
 #include "mce-internal.h"
 
-/* Handle unconfigured int18 (should never happen) */
-static void unexpected_machine_check(struct pt_regs *regs, long error_code)
-{
-       printk(KERN_ERR "CPU#%d: Unexpected int18 (Machine Check).\n",
-              smp_processor_id());
-}
-
-/* Call the installed machine check handler for this CPU setup. */
-void (*machine_check_vector)(struct pt_regs *, long error_code) =
-                                               unexpected_machine_check;
-
 int mce_disabled __read_mostly;
 
-#ifdef CONFIG_X86_NEW_MCE
-
 #define MISC_MCELOG_MINOR      227
 
 #define SPINUNIT 100   /* 100ns */
@@ -77,7 +65,6 @@ DEFINE_PER_CPU(unsigned, mce_exception_count);
  */
 static int                     tolerant                __read_mostly = 1;
 static int                     banks                   __read_mostly;
-static u64                     *bank                   __read_mostly;
 static int                     rip_msr                 __read_mostly;
 static int                     mce_bootlog             __read_mostly = -1;
 static int                     monarch_timeout         __read_mostly = -1;
@@ -87,13 +74,13 @@ int                         mce_cmci_disabled       __read_mostly;
 int                            mce_ignore_ce           __read_mostly;
 int                            mce_ser                 __read_mostly;
 
+struct mce_bank                *mce_banks              __read_mostly;
+
 /* User mode helper program triggered by machine check event */
 static unsigned long           mce_need_notify;
 static char                    mce_helper[128];
 static char                    *mce_helper_argv[2] = { mce_helper, NULL };
 
-static unsigned long           dont_init_banks;
-
 static DECLARE_WAIT_QUEUE_HEAD(mce_wait);
 static DEFINE_PER_CPU(struct mce, mces_seen);
 static int                     cpu_missing;
@@ -104,11 +91,6 @@ DEFINE_PER_CPU(mce_banks_t, mce_poll_banks) = {
        [0 ... BITS_TO_LONGS(MAX_NR_BANKS)-1] = ~0UL
 };
 
-static inline int skip_bank_init(int i)
-{
-       return i < BITS_PER_LONG && test_bit(i, &dont_init_banks);
-}
-
 static DEFINE_PER_CPU(struct work_struct, mce_work);
 
 /* Do initial initialization of a struct mce */
@@ -232,6 +214,9 @@ static void print_mce_tail(void)
 
 static atomic_t mce_paniced;
 
+static int fake_panic;
+static atomic_t mce_fake_paniced;
+
 /* Panic in progress. Enable interrupts and wait for final IPI */
 static void wait_for_panic(void)
 {
@@ -249,15 +234,21 @@ static void mce_panic(char *msg, struct mce *final, char *exp)
 {
        int i;
 
-       /*
-        * Make sure only one CPU runs in machine check panic
-        */
-       if (atomic_add_return(1, &mce_paniced) > 1)
-               wait_for_panic();
-       barrier();
+       if (!fake_panic) {
+               /*
+                * Make sure only one CPU runs in machine check panic
+                */
+               if (atomic_inc_return(&mce_paniced) > 1)
+                       wait_for_panic();
+               barrier();
 
-       bust_spinlocks(1);
-       console_verbose();
+               bust_spinlocks(1);
+               console_verbose();
+       } else {
+               /* Don't log too much for fake panic */
+               if (atomic_inc_return(&mce_fake_paniced) > 1)
+                       return;
+       }
        print_mce_head();
        /* First print corrected ones that are still unlogged */
        for (i = 0; i < MCE_LOG_LEN; i++) {
@@ -284,9 +275,12 @@ static void mce_panic(char *msg, struct mce *final, char *exp)
        print_mce_tail();
        if (exp)
                printk(KERN_EMERG "Machine check: %s\n", exp);
-       if (panic_timeout == 0)
-               panic_timeout = mce_panic_timeout;
-       panic(msg);
+       if (!fake_panic) {
+               if (panic_timeout == 0)
+                       panic_timeout = mce_panic_timeout;
+               panic(msg);
+       } else
+               printk(KERN_EMERG "Fake kernel panic: %s\n", msg);
 }
 
 /* Support code for software error injection */
@@ -296,11 +290,11 @@ static int msr_to_offset(u32 msr)
        unsigned bank = __get_cpu_var(injectm.bank);
        if (msr == rip_msr)
                return offsetof(struct mce, ip);
-       if (msr == MSR_IA32_MC0_STATUS + bank*4)
+       if (msr == MSR_IA32_MCx_STATUS(bank))
                return offsetof(struct mce, status);
-       if (msr == MSR_IA32_MC0_ADDR + bank*4)
+       if (msr == MSR_IA32_MCx_ADDR(bank))
                return offsetof(struct mce, addr);
-       if (msr == MSR_IA32_MC0_MISC + bank*4)
+       if (msr == MSR_IA32_MCx_MISC(bank))
                return offsetof(struct mce, misc);
        if (msr == MSR_IA32_MCG_STATUS)
                return offsetof(struct mce, mcgstatus);
@@ -505,7 +499,7 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
 
        m.mcgstatus = mce_rdmsrl(MSR_IA32_MCG_STATUS);
        for (i = 0; i < banks; i++) {
-               if (!bank[i] || !test_bit(i, *b))
+               if (!mce_banks[i].ctl || !test_bit(i, *b))
                        continue;
 
                m.misc = 0;
@@ -514,7 +508,7 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
                m.tsc = 0;
 
                barrier();
-               m.status = mce_rdmsrl(MSR_IA32_MC0_STATUS + i*4);
+               m.status = mce_rdmsrl(MSR_IA32_MCx_STATUS(i));
                if (!(m.status & MCI_STATUS_VAL))
                        continue;
 
@@ -529,9 +523,9 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
                        continue;
 
                if (m.status & MCI_STATUS_MISCV)
-                       m.misc = mce_rdmsrl(MSR_IA32_MC0_MISC + i*4);
+                       m.misc = mce_rdmsrl(MSR_IA32_MCx_MISC(i));
                if (m.status & MCI_STATUS_ADDRV)
-                       m.addr = mce_rdmsrl(MSR_IA32_MC0_ADDR + i*4);
+                       m.addr = mce_rdmsrl(MSR_IA32_MCx_ADDR(i));
 
                if (!(flags & MCP_TIMESTAMP))
                        m.tsc = 0;
@@ -547,7 +541,7 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
                /*
                 * Clear state for this bank.
                 */
-               mce_wrmsrl(MSR_IA32_MC0_STATUS+4*i, 0);
+               mce_wrmsrl(MSR_IA32_MCx_STATUS(i), 0);
        }
 
        /*
@@ -568,7 +562,7 @@ static int mce_no_way_out(struct mce *m, char **msg)
        int i;
 
        for (i = 0; i < banks; i++) {
-               m->status = mce_rdmsrl(MSR_IA32_MC0_STATUS + i*4);
+               m->status = mce_rdmsrl(MSR_IA32_MCx_STATUS(i));
                if (mce_severity(m, tolerant, msg) >= MCE_PANIC_SEVERITY)
                        return 1;
        }
@@ -628,7 +622,7 @@ out:
  * This way we prevent any potential data corruption in a unrecoverable case
  * and also makes sure always all CPU's errors are examined.
  *
- * Also this detects the case of an machine check event coming from outer
+ * Also this detects the case of a machine check event coming from outer
  * space (not detected by any CPUs) In this case some external agent wants
  * us to shut down, so panic too.
  *
@@ -681,7 +675,7 @@ static void mce_reign(void)
         * No machine check event found. Must be some external
         * source or one CPU is hung. Panic.
         */
-       if (!m && tolerant < 3)
+       if (global_worst <= MCE_KEEP_SEVERITY && tolerant < 3)
                mce_panic("Machine check from unknown source", NULL, NULL);
 
        /*
@@ -715,7 +709,7 @@ static int mce_start(int *no_way_out)
         * global_nwo should be updated before mce_callin
         */
        smp_wmb();
-       order = atomic_add_return(1, &mce_callin);
+       order = atomic_inc_return(&mce_callin);
 
        /*
         * Wait for everyone.
@@ -852,7 +846,7 @@ static void mce_clear_state(unsigned long *toclear)
 
        for (i = 0; i < banks; i++) {
                if (test_bit(i, toclear))
-                       mce_wrmsrl(MSR_IA32_MC0_STATUS+4*i, 0);
+                       mce_wrmsrl(MSR_IA32_MCx_STATUS(i), 0);
        }
 }
 
@@ -905,11 +899,11 @@ void do_machine_check(struct pt_regs *regs, long error_code)
        mce_setup(&m);
 
        m.mcgstatus = mce_rdmsrl(MSR_IA32_MCG_STATUS);
-       no_way_out = mce_no_way_out(&m, &msg);
-
        final = &__get_cpu_var(mces_seen);
        *final = m;
 
+       no_way_out = mce_no_way_out(&m, &msg);
+
        barrier();
 
        /*
@@ -926,14 +920,14 @@ void do_machine_check(struct pt_regs *regs, long error_code)
        order = mce_start(&no_way_out);
        for (i = 0; i < banks; i++) {
                __clear_bit(i, toclear);
-               if (!bank[i])
+               if (!mce_banks[i].ctl)
                        continue;
 
                m.misc = 0;
                m.addr = 0;
                m.bank = i;
 
-               m.status = mce_rdmsrl(MSR_IA32_MC0_STATUS + i*4);
+               m.status = mce_rdmsrl(MSR_IA32_MCx_STATUS(i));
                if ((m.status & MCI_STATUS_VAL) == 0)
                        continue;
 
@@ -974,9 +968,9 @@ void do_machine_check(struct pt_regs *regs, long error_code)
                        kill_it = 1;
 
                if (m.status & MCI_STATUS_MISCV)
-                       m.misc = mce_rdmsrl(MSR_IA32_MC0_MISC + i*4);
+                       m.misc = mce_rdmsrl(MSR_IA32_MCx_MISC(i));
                if (m.status & MCI_STATUS_ADDRV)
-                       m.addr = mce_rdmsrl(MSR_IA32_MC0_ADDR + i*4);
+                       m.addr = mce_rdmsrl(MSR_IA32_MCx_ADDR(i));
 
                /*
                 * Action optional error. Queue address for later processing.
@@ -1169,10 +1163,25 @@ int mce_notify_irq(void)
 }
 EXPORT_SYMBOL_GPL(mce_notify_irq);
 
+static int mce_banks_init(void)
+{
+       int i;
+
+       mce_banks = kzalloc(banks * sizeof(struct mce_bank), GFP_KERNEL);
+       if (!mce_banks)
+               return -ENOMEM;
+       for (i = 0; i < banks; i++) {
+               struct mce_bank *b = &mce_banks[i];
+               b->ctl = -1ULL;
+               b->init = 1;
+       }
+       return 0;
+}
+
 /*
  * Initialize Machine Checks for a CPU.
  */
-static int mce_cap_init(void)
+static int __cpuinit mce_cap_init(void)
 {
        unsigned b;
        u64 cap;
@@ -1192,11 +1201,10 @@ static int mce_cap_init(void)
        /* Don't support asymmetric configurations today */
        WARN_ON(banks != 0 && b != banks);
        banks = b;
-       if (!bank) {
-               bank = kmalloc(banks * sizeof(u64), GFP_KERNEL);
-               if (!bank)
-                       return -ENOMEM;
-               memset(bank, 0xff, banks * sizeof(u64));
+       if (!mce_banks) {
+               int err = mce_banks_init();
+               if (err)
+                       return err;
        }
 
        /* Use accurate RIP reporting if available. */
@@ -1228,15 +1236,16 @@ static void mce_init(void)
                wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);
 
        for (i = 0; i < banks; i++) {
-               if (skip_bank_init(i))
+               struct mce_bank *b = &mce_banks[i];
+               if (!b->init)
                        continue;
-               wrmsrl(MSR_IA32_MC0_CTL+4*i, bank[i]);
-               wrmsrl(MSR_IA32_MC0_STATUS+4*i, 0);
+               wrmsrl(MSR_IA32_MCx_CTL(i), b->ctl);
+               wrmsrl(MSR_IA32_MCx_STATUS(i), 0);
        }
 }
 
 /* Add per CPU specific workarounds here */
-static int mce_cpu_quirks(struct cpuinfo_x86 *c)
+static int __cpuinit mce_cpu_quirks(struct cpuinfo_x86 *c)
 {
        if (c->x86_vendor == X86_VENDOR_UNKNOWN) {
                pr_info("MCE: unknown CPU type - not enabling MCE support.\n");
@@ -1251,7 +1260,7 @@ static int mce_cpu_quirks(struct cpuinfo_x86 *c)
                         * trips off incorrectly with the IOMMU & 3ware
                         * & Cerberus:
                         */
-                       clear_bit(10, (unsigned long *)&bank[4]);
+                       clear_bit(10, (unsigned long *)&mce_banks[4].ctl);
                }
                if (c->x86 <= 17 && mce_bootlog < 0) {
                        /*
@@ -1265,7 +1274,7 @@ static int mce_cpu_quirks(struct cpuinfo_x86 *c)
                 * by default.
                 */
                 if (c->x86 == 6 && banks > 0)
-                       bank[0] = 0;
+                       mce_banks[0].ctl = 0;
        }
 
        if (c->x86_vendor == X86_VENDOR_INTEL) {
@@ -1278,8 +1287,8 @@ static int mce_cpu_quirks(struct cpuinfo_x86 *c)
                 * valid event later, merely don't write CTL0.
                 */
 
-               if (c->x86 == 6 && c->x86_model < 0x1A)
-                       __set_bit(0, &dont_init_banks);
+               if (c->x86 == 6 && c->x86_model < 0x1A && banks > 0)
+                       mce_banks[0].init = 0;
 
                /*
                 * All newer Intel systems support MCE broadcasting. Enable
@@ -1348,6 +1357,17 @@ static void mce_init_timer(void)
        add_timer_on(t, smp_processor_id());
 }
 
+/* Handle unconfigured int18 (should never happen) */
+static void unexpected_machine_check(struct pt_regs *regs, long error_code)
+{
+       printk(KERN_ERR "CPU#%d: Unexpected int18 (Machine Check).\n",
+              smp_processor_id());
+}
+
+/* Call the installed machine check handler for this CPU setup. */
+void (*machine_check_vector)(struct pt_regs *, long error_code) =
+                                               unexpected_machine_check;
+
 /*
  * Called for each booted CPU to set up machine checks.
  * Must be called with preempt off:
@@ -1561,8 +1581,10 @@ static struct miscdevice mce_log_device = {
  */
 static int __init mcheck_enable(char *str)
 {
-       if (*str == 0)
+       if (*str == 0) {
                enable_p5_mce();
+               return 1;
+       }
        if (*str == '=')
                str++;
        if (!strcmp(str, "off"))
@@ -1603,8 +1625,9 @@ static int mce_disable(void)
        int i;
 
        for (i = 0; i < banks; i++) {
-               if (!skip_bank_init(i))
-                       wrmsrl(MSR_IA32_MC0_CTL + i*4, 0);
+               struct mce_bank *b = &mce_banks[i];
+               if (b->init)
+                       wrmsrl(MSR_IA32_MCx_CTL(i), 0);
        }
        return 0;
 }
@@ -1679,14 +1702,15 @@ DEFINE_PER_CPU(struct sys_device, mce_dev);
 __cpuinitdata
 void (*threshold_cpu_callback)(unsigned long action, unsigned int cpu);
 
-static struct sysdev_attribute *bank_attrs;
+static inline struct mce_bank *attr_to_bank(struct sysdev_attribute *attr)
+{
+       return container_of(attr, struct mce_bank, attr);
+}
 
 static ssize_t show_bank(struct sys_device *s, struct sysdev_attribute *attr,
                         char *buf)
 {
-       u64 b = bank[attr - bank_attrs];
-
-       return sprintf(buf, "%llx\n", b);
+       return sprintf(buf, "%llx\n", attr_to_bank(attr)->ctl);
 }
 
 static ssize_t set_bank(struct sys_device *s, struct sysdev_attribute *attr,
@@ -1697,7 +1721,7 @@ static ssize_t set_bank(struct sys_device *s, struct sysdev_attribute *attr,
        if (strict_strtoull(buf, 0, &new) < 0)
                return -EINVAL;
 
-       bank[attr - bank_attrs] = new;
+       attr_to_bank(attr)->ctl = new;
        mce_restart();
 
        return size;
@@ -1839,7 +1863,7 @@ static __cpuinit int mce_create_device(unsigned int cpu)
        }
        for (j = 0; j < banks; j++) {
                err = sysdev_create_file(&per_cpu(mce_dev, cpu),
-                                       &bank_attrs[j]);
+                                       &mce_banks[j].attr);
                if (err)
                        goto error2;
        }
@@ -1848,10 +1872,10 @@ static __cpuinit int mce_create_device(unsigned int cpu)
        return 0;
 error2:
        while (--j >= 0)
-               sysdev_remove_file(&per_cpu(mce_dev, cpu), &bank_attrs[j]);
+               sysdev_remove_file(&per_cpu(mce_dev, cpu), &mce_banks[j].attr);
 error:
        while (--i >= 0)
-               sysdev_remove_file(&per_cpu(mce_dev, cpu), mce_attrs[i]);
+               sysdev_remove_file(&per_cpu(mce_dev, cpu), &mce_banks[i].attr);
 
        sysdev_unregister(&per_cpu(mce_dev, cpu));
 
@@ -1869,7 +1893,7 @@ static __cpuinit void mce_remove_device(unsigned int cpu)
                sysdev_remove_file(&per_cpu(mce_dev, cpu), mce_attrs[i]);
 
        for (i = 0; i < banks; i++)
-               sysdev_remove_file(&per_cpu(mce_dev, cpu), &bank_attrs[i]);
+               sysdev_remove_file(&per_cpu(mce_dev, cpu), &mce_banks[i].attr);
 
        sysdev_unregister(&per_cpu(mce_dev, cpu));
        cpumask_clear_cpu(cpu, mce_dev_initialized);
@@ -1886,8 +1910,9 @@ static void mce_disable_cpu(void *h)
        if (!(action & CPU_TASKS_FROZEN))
                cmci_clear();
        for (i = 0; i < banks; i++) {
-               if (!skip_bank_init(i))
-                       wrmsrl(MSR_IA32_MC0_CTL + i*4, 0);
+               struct mce_bank *b = &mce_banks[i];
+               if (b->init)
+                       wrmsrl(MSR_IA32_MCx_CTL(i), 0);
        }
 }
 
@@ -1902,8 +1927,9 @@ static void mce_reenable_cpu(void *h)
        if (!(action & CPU_TASKS_FROZEN))
                cmci_reenable();
        for (i = 0; i < banks; i++) {
-               if (!skip_bank_init(i))
-                       wrmsrl(MSR_IA32_MC0_CTL + i*4, bank[i]);
+               struct mce_bank *b = &mce_banks[i];
+               if (b->init)
+                       wrmsrl(MSR_IA32_MCx_CTL(i), b->ctl);
        }
 }
 
@@ -1951,35 +1977,21 @@ static struct notifier_block mce_cpu_notifier __cpuinitdata = {
        .notifier_call = mce_cpu_callback,
 };
 
-static __init int mce_init_banks(void)
+static __init void mce_init_banks(void)
 {
        int i;
 
-       bank_attrs = kzalloc(sizeof(struct sysdev_attribute) * banks,
-                               GFP_KERNEL);
-       if (!bank_attrs)
-               return -ENOMEM;
-
        for (i = 0; i < banks; i++) {
-               struct sysdev_attribute *a = &bank_attrs[i];
+               struct mce_bank *b = &mce_banks[i];
+               struct sysdev_attribute *a = &b->attr;
 
-               a->attr.name    = kasprintf(GFP_KERNEL, "bank%d", i);
-               if (!a->attr.name)
-                       goto nomem;
+               a->attr.name    = b->attrname;
+               snprintf(b->attrname, ATTR_LEN, "bank%d", i);
 
                a->attr.mode    = 0644;
                a->show         = show_bank;
                a->store        = set_bank;
        }
-       return 0;
-
-nomem:
-       while (--i >= 0)
-               kfree(bank_attrs[i].attr.name);
-       kfree(bank_attrs);
-       bank_attrs = NULL;
-
-       return -ENOMEM;
 }
 
 static __init int mce_init_device(void)
@@ -1992,9 +2004,7 @@ static __init int mce_init_device(void)
 
        zalloc_cpumask_var(&mce_dev_initialized, GFP_KERNEL);
 
-       err = mce_init_banks();
-       if (err)
-               return err;
+       mce_init_banks();
 
        err = sysdev_class_register(&mce_sysclass);
        if (err)
@@ -2014,57 +2024,65 @@ static __init int mce_init_device(void)
 
 device_initcall(mce_init_device);
 
-#else /* CONFIG_X86_OLD_MCE: */
-
-int nr_mce_banks;
-EXPORT_SYMBOL_GPL(nr_mce_banks);       /* non-fatal.o */
+/*
+ * Old style boot options parsing. Only for compatibility.
+ */
+static int __init mcheck_disable(char *str)
+{
+       mce_disabled = 1;
+       return 1;
+}
+__setup("nomce", mcheck_disable);
 
-/* This has to be run for each processor */
-void mcheck_init(struct cpuinfo_x86 *c)
+#ifdef CONFIG_DEBUG_FS
+struct dentry *mce_get_debugfs_dir(void)
 {
-       if (mce_disabled)
-               return;
+       static struct dentry *dmce;
 
-       switch (c->x86_vendor) {
-       case X86_VENDOR_AMD:
-               amd_mcheck_init(c);
-               break;
+       if (!dmce)
+               dmce = debugfs_create_dir("mce", NULL);
 
-       case X86_VENDOR_INTEL:
-               if (c->x86 == 5)
-                       intel_p5_mcheck_init(c);
-               if (c->x86 == 6)
-                       intel_p6_mcheck_init(c);
-               if (c->x86 == 15)
-                       intel_p4_mcheck_init(c);
-               break;
+       return dmce;
+}
 
-       case X86_VENDOR_CENTAUR:
-               if (c->x86 == 5)
-                       winchip_mcheck_init(c);
-               break;
+static void mce_reset(void)
+{
+       cpu_missing = 0;
+       atomic_set(&mce_fake_paniced, 0);
+       atomic_set(&mce_executing, 0);
+       atomic_set(&mce_callin, 0);
+       atomic_set(&global_nwo, 0);
+}
 
-       default:
-               break;
-       }
-       printk(KERN_INFO "mce: CPU supports %d MCE banks\n", nr_mce_banks);
+static int fake_panic_get(void *data, u64 *val)
+{
+       *val = fake_panic;
+       return 0;
 }
 
-static int __init mcheck_enable(char *str)
+static int fake_panic_set(void *data, u64 val)
 {
-       mce_p5_enabled = 1;
-       return 1;
+       mce_reset();
+       fake_panic = val;
+       return 0;
 }
-__setup("mce", mcheck_enable);
 
-#endif /* CONFIG_X86_OLD_MCE */
+DEFINE_SIMPLE_ATTRIBUTE(fake_panic_fops, fake_panic_get,
+                       fake_panic_set, "%llu\n");
 
-/*
- * Old style boot options parsing. Only for compatibility.
- */
-static int __init mcheck_disable(char *str)
+static int __init mce_debugfs_init(void)
 {
-       mce_disabled = 1;
-       return 1;
+       struct dentry *dmce, *ffake_panic;
+
+       dmce = mce_get_debugfs_dir();
+       if (!dmce)
+               return -ENOMEM;
+       ffake_panic = debugfs_create_file("fake_panic", 0444, dmce, NULL,
+                                         &fake_panic_fops);
+       if (!ffake_panic)
+               return -ENOMEM;
+
+       return 0;
 }
-__setup("nomce", mcheck_disable);
+late_initcall(mce_debugfs_init);
+#endif
index e1acec0f7a324e2b26ed02f8fbd1b01f72b2e7ab..889f665fe93d78322093505882e636feac5029ac 100644 (file)
@@ -90,7 +90,7 @@ static void cmci_discover(int banks, int boot)
                if (test_bit(i, owned))
                        continue;
 
-               rdmsrl(MSR_IA32_MC0_CTL2 + i, val);
+               rdmsrl(MSR_IA32_MCx_CTL2(i), val);
 
                /* Already owned by someone else? */
                if (val & CMCI_EN) {
@@ -101,8 +101,8 @@ static void cmci_discover(int banks, int boot)
                }
 
                val |= CMCI_EN | CMCI_THRESHOLD;
-               wrmsrl(MSR_IA32_MC0_CTL2 + i, val);
-               rdmsrl(MSR_IA32_MC0_CTL2 + i, val);
+               wrmsrl(MSR_IA32_MCx_CTL2(i), val);
+               rdmsrl(MSR_IA32_MCx_CTL2(i), val);
 
                /* Did the enable bit stick? -- the bank supports CMCI */
                if (val & CMCI_EN) {
@@ -152,9 +152,9 @@ void cmci_clear(void)
                if (!test_bit(i, __get_cpu_var(mce_banks_owned)))
                        continue;
                /* Disable CMCI */
-               rdmsrl(MSR_IA32_MC0_CTL2 + i, val);
+               rdmsrl(MSR_IA32_MCx_CTL2(i), val);
                val &= ~(CMCI_EN|CMCI_THRESHOLD_MASK);
-               wrmsrl(MSR_IA32_MC0_CTL2 + i, val);
+               wrmsrl(MSR_IA32_MCx_CTL2(i), val);
                __clear_bit(i, __get_cpu_var(mce_banks_owned));
        }
        spin_unlock_irqrestore(&cmci_discover_lock, flags);
diff --git a/arch/x86/kernel/cpu/mcheck/non-fatal.c b/arch/x86/kernel/cpu/mcheck/non-fatal.c
deleted file mode 100644 (file)
index f5f2d6f..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Non Fatal Machine Check Exception Reporting
- *
- * (C) Copyright 2002 Dave Jones. <davej@redhat.com>
- *
- * This file contains routines to check for non-fatal MCEs every 15s
- *
- */
-#include <linux/interrupt.h>
-#include <linux/workqueue.h>
-#include <linux/jiffies.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/smp.h>
-
-#include <asm/processor.h>
-#include <asm/system.h>
-#include <asm/mce.h>
-#include <asm/msr.h>
-
-static int             firstbank;
-
-#define MCE_RATE       (15*HZ) /* timer rate is 15s */
-
-static void mce_checkregs(void *info)
-{
-       u32 low, high;
-       int i;
-
-       for (i = firstbank; i < nr_mce_banks; i++) {
-               rdmsr(MSR_IA32_MC0_STATUS+i*4, low, high);
-
-               if (!(high & (1<<31)))
-                       continue;
-
-               printk(KERN_INFO "MCE: The hardware reports a non fatal, "
-                       "correctable incident occurred on CPU %d.\n",
-                               smp_processor_id());
-
-               printk(KERN_INFO "Bank %d: %08x%08x\n", i, high, low);
-
-               /*
-                * Scrub the error so we don't pick it up in MCE_RATE
-                * seconds time:
-                */
-               wrmsr(MSR_IA32_MC0_STATUS+i*4, 0UL, 0UL);
-
-               /* Serialize: */
-               wmb();
-               add_taint(TAINT_MACHINE_CHECK);
-       }
-}
-
-static void mce_work_fn(struct work_struct *work);
-static DECLARE_DELAYED_WORK(mce_work, mce_work_fn);
-
-static void mce_work_fn(struct work_struct *work)
-{
-       on_each_cpu(mce_checkregs, NULL, 1);
-       schedule_delayed_work(&mce_work, round_jiffies_relative(MCE_RATE));
-}
-
-static int __init init_nonfatal_mce_checker(void)
-{
-       struct cpuinfo_x86 *c = &boot_cpu_data;
-
-       /* Check for MCE support */
-       if (!cpu_has(c, X86_FEATURE_MCE))
-               return -ENODEV;
-
-       /* Check for PPro style MCA */
-       if (!cpu_has(c, X86_FEATURE_MCA))
-               return -ENODEV;
-
-       /* Some Athlons misbehave when we frob bank 0 */
-       if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
-                                               boot_cpu_data.x86 == 6)
-               firstbank = 1;
-       else
-               firstbank = 0;
-
-       /*
-        * Check for non-fatal errors every MCE_RATE s
-        */
-       schedule_delayed_work(&mce_work, round_jiffies_relative(MCE_RATE));
-       printk(KERN_INFO "Machine check exception polling timer started.\n");
-
-       return 0;
-}
-module_init(init_nonfatal_mce_checker);
-
-MODULE_LICENSE("GPL");
diff --git a/arch/x86/kernel/cpu/mcheck/p4.c b/arch/x86/kernel/cpu/mcheck/p4.c
deleted file mode 100644 (file)
index 4482aea..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * P4 specific Machine Check Exception Reporting
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/smp.h>
-
-#include <asm/processor.h>
-#include <asm/mce.h>
-#include <asm/msr.h>
-
-/* as supported by the P4/Xeon family */
-struct intel_mce_extended_msrs {
-       u32 eax;
-       u32 ebx;
-       u32 ecx;
-       u32 edx;
-       u32 esi;
-       u32 edi;
-       u32 ebp;
-       u32 esp;
-       u32 eflags;
-       u32 eip;
-       /* u32 *reserved[]; */
-};
-
-static int mce_num_extended_msrs;
-
-/* P4/Xeon Extended MCE MSR retrieval, return 0 if unsupported */
-static void intel_get_extended_msrs(struct intel_mce_extended_msrs *r)
-{
-       u32 h;
-
-       rdmsr(MSR_IA32_MCG_EAX, r->eax, h);
-       rdmsr(MSR_IA32_MCG_EBX, r->ebx, h);
-       rdmsr(MSR_IA32_MCG_ECX, r->ecx, h);
-       rdmsr(MSR_IA32_MCG_EDX, r->edx, h);
-       rdmsr(MSR_IA32_MCG_ESI, r->esi, h);
-       rdmsr(MSR_IA32_MCG_EDI, r->edi, h);
-       rdmsr(MSR_IA32_MCG_EBP, r->ebp, h);
-       rdmsr(MSR_IA32_MCG_ESP, r->esp, h);
-       rdmsr(MSR_IA32_MCG_EFLAGS, r->eflags, h);
-       rdmsr(MSR_IA32_MCG_EIP, r->eip, h);
-}
-
-static void intel_machine_check(struct pt_regs *regs, long error_code)
-{
-       u32 alow, ahigh, high, low;
-       u32 mcgstl, mcgsth;
-       int recover = 1;
-       int i;
-
-       rdmsr(MSR_IA32_MCG_STATUS, mcgstl, mcgsth);
-       if (mcgstl & (1<<0))    /* Recoverable ? */
-               recover = 0;
-
-       printk(KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n",
-               smp_processor_id(), mcgsth, mcgstl);
-
-       if (mce_num_extended_msrs > 0) {
-               struct intel_mce_extended_msrs dbg;
-
-               intel_get_extended_msrs(&dbg);
-
-               printk(KERN_DEBUG "CPU %d: EIP: %08x EFLAGS: %08x\n"
-                       "\teax: %08x ebx: %08x ecx: %08x edx: %08x\n"
-                       "\tesi: %08x edi: %08x ebp: %08x esp: %08x\n",
-                       smp_processor_id(), dbg.eip, dbg.eflags,
-                       dbg.eax, dbg.ebx, dbg.ecx, dbg.edx,
-                       dbg.esi, dbg.edi, dbg.ebp, dbg.esp);
-       }
-
-       for (i = 0; i < nr_mce_banks; i++) {
-               rdmsr(MSR_IA32_MC0_STATUS+i*4, low, high);
-               if (high & (1<<31)) {
-                       char misc[20];
-                       char addr[24];
-
-                       misc[0] = addr[0] = '\0';
-                       if (high & (1<<29))
-                               recover |= 1;
-                       if (high & (1<<25))
-                               recover |= 2;
-                       high &= ~(1<<31);
-                       if (high & (1<<27)) {
-                               rdmsr(MSR_IA32_MC0_MISC+i*4, alow, ahigh);
-                               snprintf(misc, 20, "[%08x%08x]", ahigh, alow);
-                       }
-                       if (high & (1<<26)) {
-                               rdmsr(MSR_IA32_MC0_ADDR+i*4, alow, ahigh);
-                               snprintf(addr, 24, " at %08x%08x", ahigh, alow);
-                       }
-                       printk(KERN_EMERG "CPU %d: Bank %d: %08x%08x%s%s\n",
-                               smp_processor_id(), i, high, low, misc, addr);
-               }
-       }
-
-       if (recover & 2)
-               panic("CPU context corrupt");
-       if (recover & 1)
-               panic("Unable to continue");
-
-       printk(KERN_EMERG "Attempting to continue.\n");
-
-       /*
-        * Do not clear the MSR_IA32_MCi_STATUS if the error is not
-        * recoverable/continuable.This will allow BIOS to look at the MSRs
-        * for errors if the OS could not log the error.
-        */
-       for (i = 0; i < nr_mce_banks; i++) {
-               u32 msr;
-               msr = MSR_IA32_MC0_STATUS+i*4;
-               rdmsr(msr, low, high);
-               if (high&(1<<31)) {
-                       /* Clear it */
-                       wrmsr(msr, 0UL, 0UL);
-                       /* Serialize */
-                       wmb();
-                       add_taint(TAINT_MACHINE_CHECK);
-               }
-       }
-       mcgstl &= ~(1<<2);
-       wrmsr(MSR_IA32_MCG_STATUS, mcgstl, mcgsth);
-}
-
-void intel_p4_mcheck_init(struct cpuinfo_x86 *c)
-{
-       u32 l, h;
-       int i;
-
-       machine_check_vector = intel_machine_check;
-       wmb();
-
-       printk(KERN_INFO "Intel machine check architecture supported.\n");
-       rdmsr(MSR_IA32_MCG_CAP, l, h);
-       if (l & (1<<8)) /* Control register present ? */
-               wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);
-       nr_mce_banks = l & 0xff;
-
-       for (i = 0; i < nr_mce_banks; i++) {
-               wrmsr(MSR_IA32_MC0_CTL+4*i, 0xffffffff, 0xffffffff);
-               wrmsr(MSR_IA32_MC0_STATUS+4*i, 0x0, 0x0);
-       }
-
-       set_in_cr4(X86_CR4_MCE);
-       printk(KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n",
-               smp_processor_id());
-
-       /* Check for P4/Xeon extended MCE MSRs */
-       rdmsr(MSR_IA32_MCG_CAP, l, h);
-       if (l & (1<<9)) {/* MCG_EXT_P */
-               mce_num_extended_msrs = (l >> 16) & 0xff;
-               printk(KERN_INFO "CPU%d: Intel P4/Xeon Extended MCE MSRs (%d)"
-                               " available\n",
-                       smp_processor_id(), mce_num_extended_msrs);
-
-#ifdef CONFIG_X86_MCE_P4THERMAL
-               /* Check for P4/Xeon Thermal monitor */
-               intel_init_thermal(c);
-#endif
-       }
-}
diff --git a/arch/x86/kernel/cpu/mcheck/p6.c b/arch/x86/kernel/cpu/mcheck/p6.c
deleted file mode 100644 (file)
index 01e4f81..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * P6 specific Machine Check Exception Reporting
- * (C) Copyright 2002 Alan Cox <alan@lxorguk.ukuu.org.uk>
- */
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/smp.h>
-
-#include <asm/processor.h>
-#include <asm/system.h>
-#include <asm/mce.h>
-#include <asm/msr.h>
-
-/* Machine Check Handler For PII/PIII */
-static void intel_machine_check(struct pt_regs *regs, long error_code)
-{
-       u32 alow, ahigh, high, low;
-       u32 mcgstl, mcgsth;
-       int recover = 1;
-       int i;
-
-       rdmsr(MSR_IA32_MCG_STATUS, mcgstl, mcgsth);
-       if (mcgstl & (1<<0))    /* Recoverable ? */
-               recover = 0;
-
-       printk(KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n",
-               smp_processor_id(), mcgsth, mcgstl);
-
-       for (i = 0; i < nr_mce_banks; i++) {
-               rdmsr(MSR_IA32_MC0_STATUS+i*4, low, high);
-               if (high & (1<<31)) {
-                       char misc[20];
-                       char addr[24];
-
-                       misc[0] = '\0';
-                       addr[0] = '\0';
-
-                       if (high & (1<<29))
-                               recover |= 1;
-                       if (high & (1<<25))
-                               recover |= 2;
-                       high &= ~(1<<31);
-
-                       if (high & (1<<27)) {
-                               rdmsr(MSR_IA32_MC0_MISC+i*4, alow, ahigh);
-                               snprintf(misc, 20, "[%08x%08x]", ahigh, alow);
-                       }
-                       if (high & (1<<26)) {
-                               rdmsr(MSR_IA32_MC0_ADDR+i*4, alow, ahigh);
-                               snprintf(addr, 24, " at %08x%08x", ahigh, alow);
-                       }
-
-                       printk(KERN_EMERG "CPU %d: Bank %d: %08x%08x%s%s\n",
-                               smp_processor_id(), i, high, low, misc, addr);
-               }
-       }
-
-       if (recover & 2)
-               panic("CPU context corrupt");
-       if (recover & 1)
-               panic("Unable to continue");
-
-       printk(KERN_EMERG "Attempting to continue.\n");
-       /*
-        * Do not clear the MSR_IA32_MCi_STATUS if the error is not
-        * recoverable/continuable.This will allow BIOS to look at the MSRs
-        * for errors if the OS could not log the error:
-        */
-       for (i = 0; i < nr_mce_banks; i++) {
-               unsigned int msr;
-
-               msr = MSR_IA32_MC0_STATUS+i*4;
-               rdmsr(msr, low, high);
-               if (high & (1<<31)) {
-                       /* Clear it: */
-                       wrmsr(msr, 0UL, 0UL);
-                       /* Serialize: */
-                       wmb();
-                       add_taint(TAINT_MACHINE_CHECK);
-               }
-       }
-       mcgstl &= ~(1<<2);
-       wrmsr(MSR_IA32_MCG_STATUS, mcgstl, mcgsth);
-}
-
-/* Set up machine check reporting for processors with Intel style MCE: */
-void intel_p6_mcheck_init(struct cpuinfo_x86 *c)
-{
-       u32 l, h;
-       int i;
-
-       /* Check for MCE support */
-       if (!cpu_has(c, X86_FEATURE_MCE))
-               return;
-
-       /* Check for PPro style MCA */
-       if (!cpu_has(c, X86_FEATURE_MCA))
-               return;
-
-       /* Ok machine check is available */
-       machine_check_vector = intel_machine_check;
-       /* Make sure the vector pointer is visible before we enable MCEs: */
-       wmb();
-
-       printk(KERN_INFO "Intel machine check architecture supported.\n");
-       rdmsr(MSR_IA32_MCG_CAP, l, h);
-       if (l & (1<<8)) /* Control register present ? */
-               wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);
-       nr_mce_banks = l & 0xff;
-
-       /*
-        * Following the example in IA-32 SDM Vol 3:
-        * - MC0_CTL should not be written
-        * - Status registers on all banks should be cleared on reset
-        */
-       for (i = 1; i < nr_mce_banks; i++)
-               wrmsr(MSR_IA32_MC0_CTL+4*i, 0xffffffff, 0xffffffff);
-
-       for (i = 0; i < nr_mce_banks; i++)
-               wrmsr(MSR_IA32_MC0_STATUS+4*i, 0x0, 0x0);
-
-       set_in_cr4(X86_CR4_MCE);
-       printk(KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n",
-               smp_processor_id());
-}
index 5957a93e5173f2e1e985b1a149a01f5905bb03db..63a56d147e4a67b55ceea258dfeb20c18b9d1ccf 100644 (file)
@@ -260,9 +260,6 @@ void intel_init_thermal(struct cpuinfo_x86 *c)
                return;
        }
 
-       if (cpu_has(c, X86_FEATURE_TM2) && (l & MSR_IA32_MISC_ENABLE_TM2))
-               tm2 = 1;
-
        /* Check whether a vector already exists */
        if (h & APIC_VECTOR_MASK) {
                printk(KERN_DEBUG
@@ -271,6 +268,16 @@ void intel_init_thermal(struct cpuinfo_x86 *c)
                return;
        }
 
+       /* early Pentium M models use different method for enabling TM2 */
+       if (cpu_has(c, X86_FEATURE_TM2)) {
+               if (c->x86 == 6 && (c->x86_model == 9 || c->x86_model == 13)) {
+                       rdmsr(MSR_THERM2_CTL, l, h);
+                       if (l & MSR_THERM2_CTL_TM_SELECT)
+                               tm2 = 1;
+               } else if (l & MSR_IA32_MISC_ENABLE_TM2)
+                       tm2 = 1;
+       }
+
        /* We'll mask the thermal vector in the lapic till we're ready: */
        h = THERMAL_APIC_VECTOR | APIC_DM_FIXED | APIC_LVT_MASKED;
        apic_write(APIC_LVTTHMR, h);
diff --git a/arch/x86/kernel/cpu/sched.c b/arch/x86/kernel/cpu/sched.c
new file mode 100644 (file)
index 0000000..a640ae5
--- /dev/null
@@ -0,0 +1,55 @@
+#include <linux/sched.h>
+#include <linux/math64.h>
+#include <linux/percpu.h>
+#include <linux/irqflags.h>
+
+#include <asm/cpufeature.h>
+#include <asm/processor.h>
+
+#ifdef CONFIG_SMP
+
+static DEFINE_PER_CPU(struct aperfmperf, old_perf_sched);
+
+static unsigned long scale_aperfmperf(void)
+{
+       struct aperfmperf val, *old = &__get_cpu_var(old_perf_sched);
+       unsigned long ratio, flags;
+
+       local_irq_save(flags);
+       get_aperfmperf(&val);
+       local_irq_restore(flags);
+
+       ratio = calc_aperfmperf_ratio(old, &val);
+       *old = val;
+
+       return ratio;
+}
+
+unsigned long arch_scale_freq_power(struct sched_domain *sd, int cpu)
+{
+       /*
+        * do aperf/mperf on the cpu level because it includes things
+        * like turbo mode, which are relevant to full cores.
+        */
+       if (boot_cpu_has(X86_FEATURE_APERFMPERF))
+               return scale_aperfmperf();
+
+       /*
+        * maybe have something cpufreq here
+        */
+
+       return default_scale_freq_power(sd, cpu);
+}
+
+unsigned long arch_scale_smt_power(struct sched_domain *sd, int cpu)
+{
+       /*
+        * aperf/mperf already includes the smt gain
+        */
+       if (boot_cpu_has(X86_FEATURE_APERFMPERF))
+               return SCHED_LOAD_SCALE;
+
+       return default_scale_smt_power(sd, cpu);
+}
+
+#endif
index c251be7451079ac9150033b5987f6259902328b0..d59fe323807ed5ebf521909574fe022302653456 100644 (file)
@@ -146,7 +146,7 @@ ENTRY(ftrace_graph_caller)
 END(ftrace_graph_caller)
 
 GLOBAL(return_to_handler)
-       subq  $80, %rsp
+       subq  $24, %rsp
 
        /* Save the return values */
        movq %rax, (%rsp)
@@ -155,10 +155,10 @@ GLOBAL(return_to_handler)
 
        call ftrace_return_to_handler
 
-       movq %rax, 72(%rsp)
+       movq %rax, 16(%rsp)
        movq 8(%rsp), %rdx
        movq (%rsp), %rax
-       addq $72, %rsp
+       addq $16, %rsp
        retq
 #endif
 
index 5cf36c053ac401a08a9e1ced6679e7f59c09d782..23c167925a5c078bcd387b6bce8e34f7a6dca694 100644 (file)
 DEFINE_SPINLOCK(i8253_lock);
 EXPORT_SYMBOL(i8253_lock);
 
-#ifdef CONFIG_X86_32
-static void pit_disable_clocksource(void);
-#else
-static inline void pit_disable_clocksource(void) { }
-#endif
-
 /*
  * HPET replaces the PIT, when enabled. So we need to know, which of
  * the two timers is used
@@ -57,12 +51,10 @@ static void init_pit_timer(enum clock_event_mode mode,
                        outb_pit(0, PIT_CH0);
                        outb_pit(0, PIT_CH0);
                }
-               pit_disable_clocksource();
                break;
 
        case CLOCK_EVT_MODE_ONESHOT:
                /* One shot setup */
-               pit_disable_clocksource();
                outb_pit(0x38, PIT_MODE);
                break;
 
@@ -200,17 +192,6 @@ static struct clocksource pit_cs = {
        .shift          = 20,
 };
 
-static void pit_disable_clocksource(void)
-{
-       /*
-        * Use mult to check whether it is registered or not
-        */
-       if (pit_cs.mult) {
-               clocksource_unregister(&pit_cs);
-               pit_cs.mult = 0;
-       }
-}
-
 static int __init init_pit_clocksource(void)
 {
         /*
index b0cdde6932f5ef094d74eae1a80e0e79877a1018..74656d1d4e30f8fa560391253bb6b541b74e2b08 100644 (file)
@@ -104,7 +104,7 @@ static int show_other_interrupts(struct seq_file *p, int prec)
        seq_printf(p, "  Threshold APIC interrupts\n");
 # endif
 #endif
-#ifdef CONFIG_X86_NEW_MCE
+#ifdef CONFIG_X86_MCE
        seq_printf(p, "%*s: ", prec, "MCE");
        for_each_online_cpu(j)
                seq_printf(p, "%10u ", per_cpu(mce_exception_count, j));
@@ -200,7 +200,7 @@ u64 arch_irq_stat_cpu(unsigned int cpu)
        sum += irq_stats(cpu)->irq_threshold_count;
 # endif
 #endif
-#ifdef CONFIG_X86_NEW_MCE
+#ifdef CONFIG_X86_MCE
        sum += per_cpu(mce_exception_count, cpu);
        sum += per_cpu(mce_poll_count, cpu);
 #endif
index 92b7703d3d58e6ad278e45d733fdcac1505772fa..ccf8ab54f31a17198f064d18d99a8f6cc571ce08 100644 (file)
@@ -190,7 +190,7 @@ static void __init apic_intr_init(void)
 #ifdef CONFIG_X86_MCE_THRESHOLD
        alloc_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt);
 #endif
-#if defined(CONFIG_X86_NEW_MCE) && defined(CONFIG_X86_LOCAL_APIC)
+#if defined(CONFIG_X86_MCE) && defined(CONFIG_X86_LOCAL_APIC)
        alloc_intr_gate(MCE_SELF_VECTOR, mce_self_interrupt);
 #endif
 
index 5d465b207e72c3bfae75b29f6d0e1dcb3365e6b4..bf67dcb4a44ce77d02a63eb3c00824f46c0b4a63 100644 (file)
@@ -178,7 +178,7 @@ static int set_rtc_mmss(unsigned long nowtime)
 }
 
 /* not static: needed by APM */
-unsigned long read_persistent_clock(void)
+void read_persistent_clock(struct timespec *ts)
 {
        unsigned long retval, flags;
 
@@ -186,7 +186,8 @@ unsigned long read_persistent_clock(void)
        retval = get_wallclock();
        spin_unlock_irqrestore(&rtc_lock, flags);
 
-       return retval;
+       ts->tv_sec = retval;
+       ts->tv_nsec = 0;
 }
 
 int update_persistent_clock(struct timespec now)
index 81e58238c4ce642ed54ea3ce63c265427e1d6984..6a44a76055adcb781572978d1e332a9923f7e2d6 100644 (file)
@@ -856,7 +856,7 @@ static void do_signal(struct pt_regs *regs)
 void
 do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
 {
-#ifdef CONFIG_X86_NEW_MCE
+#ifdef CONFIG_X86_MCE
        /* notify userspace of pending MCEs */
        if (thread_info_flags & _TIF_MCE_NOTIFY)
                mce_notify_process();
index 71f4368b357edf2a47fd035349bfbcd8c595e882..fc3672a303d6298ca994fc58a4e229ac770c5af3 100644 (file)
@@ -744,10 +744,16 @@ static cycle_t __vsyscall_fn vread_tsc(void)
 }
 #endif
 
+static void resume_tsc(void)
+{
+       clocksource_tsc.cycle_last = 0;
+}
+
 static struct clocksource clocksource_tsc = {
        .name                   = "tsc",
        .rating                 = 300,
        .read                   = read_tsc,
+       .resume                 = resume_tsc,
        .mask                   = CLOCKSOURCE_MASK(64),
        .shift                  = 22,
        .flags                  = CLOCK_SOURCE_IS_CONTINUOUS |
@@ -761,12 +767,14 @@ void mark_tsc_unstable(char *reason)
 {
        if (!tsc_unstable) {
                tsc_unstable = 1;
-               printk("Marking TSC unstable due to %s\n", reason);
+               printk(KERN_INFO "Marking TSC unstable due to %s\n", reason);
                /* Change only the rating, when not registered */
                if (clocksource_tsc.mult)
-                       clocksource_change_rating(&clocksource_tsc, 0);
-               else
+                       clocksource_mark_unstable(&clocksource_tsc);
+               else {
+                       clocksource_tsc.flags |= CLOCK_SOURCE_UNSTABLE;
                        clocksource_tsc.rating = 0;
+               }
        }
 }
 
index 25ee06a80aad3cd116292227826f9a32fa4b3f7a..cf53a78e2dcf1b6639dd569b3810da809e437e1b 100644 (file)
@@ -87,6 +87,7 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock)
        vsyscall_gtod_data.wall_time_sec = wall_time->tv_sec;
        vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec;
        vsyscall_gtod_data.wall_to_monotonic = wall_to_monotonic;
+       vsyscall_gtod_data.wall_time_coarse = __current_kernel_time();
        write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags);
 }
 
index 1658296005668d7cb1013751d45cac1e4a22b15d..c8191defc38a36f16ae60245a60f781229169d06 100644 (file)
 #include <linux/random.h>
 #include <linux/limits.h>
 #include <linux/sched.h>
+#include <asm/elf.h>
+
+static unsigned int stack_maxrandom_size(void)
+{
+       unsigned int max = 0;
+       if ((current->flags & PF_RANDOMIZE) &&
+               !(current->personality & ADDR_NO_RANDOMIZE)) {
+               max = ((-1U) & STACK_RND_MASK) << PAGE_SHIFT;
+       }
+
+       return max;
+}
+
 
 /*
  * Top of mmap area (just below the process stack).
  *
- * Leave an at least ~128 MB hole.
+ * Leave an at least ~128 MB hole with possible stack randomization.
  */
-#define MIN_GAP (128*1024*1024)
+#define MIN_GAP (128*1024*1024UL + stack_maxrandom_size())
 #define MAX_GAP (TASK_SIZE/6*5)
 
 /*
index d7ebc3a10f2f1aa96aa00913e4b3f2472149facc..7257cf3decf9455ccb52f8f06bd28bc84a7f57ec 100644 (file)
@@ -424,17 +424,9 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
 
        spin_lock(&memtype_lock);
 
-       entry = memtype_rb_search(&memtype_rbroot, new->start);
-       if (likely(entry != NULL)) {
-               /* To work correctly with list_for_each_entry_continue */
-               entry = list_entry(entry->nd.prev, struct memtype, nd);
-       } else {
-               entry = list_entry(&memtype_list, struct memtype, nd);
-       }
-
        /* Search for existing mapping that overlaps the current range */
        where = NULL;
-       list_for_each_entry_continue(entry, &memtype_list, nd) {
+       list_for_each_entry(entry, &memtype_list, nd) {
                if (end <= entry->start) {
                        where = entry->nd.prev;
                        break;
@@ -532,7 +524,7 @@ int free_memtype(u64 start, u64 end)
         * in sorted start address
         */
        saved_entry = entry;
-       list_for_each_entry(entry, &memtype_list, nd) {
+       list_for_each_entry_from(entry, &memtype_list, nd) {
                if (entry->start == start && entry->end == end) {
                        rb_erase(&entry->rb, &memtype_rbroot);
                        list_del(&entry->nd);
index 6a40b78b46aafae8273ad7ed12ebbfd44187733a..ee55754cc3c5ff378b76f2065a610b72e757f088 100644 (file)
@@ -86,14 +86,47 @@ notrace static noinline int do_monotonic(struct timespec *ts)
        return 0;
 }
 
+notrace static noinline int do_realtime_coarse(struct timespec *ts)
+{
+       unsigned long seq;
+       do {
+               seq = read_seqbegin(&gtod->lock);
+               ts->tv_sec = gtod->wall_time_coarse.tv_sec;
+               ts->tv_nsec = gtod->wall_time_coarse.tv_nsec;
+       } while (unlikely(read_seqretry(&gtod->lock, seq)));
+       return 0;
+}
+
+notrace static noinline int do_monotonic_coarse(struct timespec *ts)
+{
+       unsigned long seq, ns, secs;
+       do {
+               seq = read_seqbegin(&gtod->lock);
+               secs = gtod->wall_time_coarse.tv_sec;
+               ns = gtod->wall_time_coarse.tv_nsec;
+               secs += gtod->wall_to_monotonic.tv_sec;
+               ns += gtod->wall_to_monotonic.tv_nsec;
+       } while (unlikely(read_seqretry(&gtod->lock, seq)));
+       vset_normalized_timespec(ts, secs, ns);
+       return 0;
+}
+
 notrace int __vdso_clock_gettime(clockid_t clock, struct timespec *ts)
 {
-       if (likely(gtod->sysctl_enabled && gtod->clock.vread))
+       if (likely(gtod->sysctl_enabled))
                switch (clock) {
                case CLOCK_REALTIME:
-                       return do_realtime(ts);
+                       if (likely(gtod->clock.vread))
+                               return do_realtime(ts);
+                       break;
                case CLOCK_MONOTONIC:
-                       return do_monotonic(ts);
+                       if (likely(gtod->clock.vread))
+                               return do_monotonic(ts);
+                       break;
+               case CLOCK_REALTIME_COARSE:
+                       return do_realtime_coarse(ts);
+               case CLOCK_MONOTONIC_COARSE:
+                       return do_monotonic_coarse(ts);
                }
        return vdso_fallback_gettime(clock, ts);
 }
index 8848120d291bc7465d9a4fcdf2b07aee7ae9c394..19085ff0484a27df21142c14a3fcc5384b4497a6 100644 (file)
@@ -59,9 +59,8 @@ static struct irqaction timer_irqaction = {
 
 void __init time_init(void)
 {
-       xtime.tv_nsec = 0;
-       xtime.tv_sec = read_persistent_clock();
-
+       /* FIXME: xtime&wall_to_monotonic are set in timekeeping_init. */
+       read_persistent_clock(&xtime);
        set_normalized_timespec(&wall_to_monotonic,
                -xtime.tv_sec, -xtime.tv_nsec);
 
index ab2fa4eeb364b3e5d0f4278f294a78a8483ab4e6..f2df6e2a224c3f9bfbebc3bfc9550ceecf9d6894 100644 (file)
@@ -255,6 +255,15 @@ config PATA_ARTOP
 
          If unsure, say N.
 
+config PATA_ATP867X
+       tristate "ARTOP/Acard ATP867X PATA support"
+       depends on PCI
+       help
+         This option enables support for ARTOP/Acard ATP867X PATA
+         controllers.
+
+         If unsure, say N.
+
 config PATA_AT32
        tristate "Atmel AVR32 PATA support (Experimental)"
        depends on AVR32 && PLATFORM_AT32AP && EXPERIMENTAL
index 463eb52236aac076c4798b9492f96ead74da4736..01e126f343b3f87a578ce949f5be9f0443cae532 100644 (file)
@@ -22,6 +22,7 @@ obj-$(CONFIG_SATA_FSL)                += sata_fsl.o
 obj-$(CONFIG_PATA_ALI)         += pata_ali.o
 obj-$(CONFIG_PATA_AMD)         += pata_amd.o
 obj-$(CONFIG_PATA_ARTOP)       += pata_artop.o
+obj-$(CONFIG_PATA_ATP867X)     += pata_atp867x.o
 obj-$(CONFIG_PATA_AT32)                += pata_at32.o
 obj-$(CONFIG_PATA_ATIIXP)      += pata_atiixp.o
 obj-$(CONFIG_PATA_CMD640_PCI)  += pata_cmd640.o
index d4cd9c203314df43b960cbbef0e05211d535b8da..acd1162712b18920ff4a0c2a00d6b7e44c4fc3bd 100644 (file)
@@ -2930,8 +2930,8 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (ahci_sb600_32bit_only(pdev))
                hpriv->flags |= AHCI_HFLAG_32BIT_ONLY;
 
-       if (!(hpriv->flags & AHCI_HFLAG_NO_MSI))
-               pci_enable_msi(pdev);
+       if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev))
+               pci_intx(pdev, 1);
 
        /* save initial config */
        ahci_save_initial_config(pdev, hpriv);
index df31deac5c8224fce9e4e0571c4484d35d966966..0ddaf43d68c68dd89e2b36409487bf57b5f54686 100644 (file)
@@ -5024,8 +5024,6 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
                struct ata_device *dev = qc->dev;
                struct ata_eh_info *ehi = &dev->link->eh_info;
 
-               WARN_ON_ONCE(ap->pflags & ATA_PFLAG_FROZEN);
-
                if (unlikely(qc->err_mask))
                        qc->flags |= ATA_QCFLAG_FAILED;
 
@@ -5038,6 +5036,8 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
                        }
                }
 
+               WARN_ON_ONCE(ap->pflags & ATA_PFLAG_FROZEN);
+
                /* read result TF if requested */
                if (qc->flags & ATA_QCFLAG_RESULT_TF)
                        fill_result_tf(qc);
index 33a74f11171cc15dcc4037796e1eafdf3058be0f..567f3f72774efd2a821b2a7b24724dc3bdb38077 100644 (file)
@@ -307,6 +307,9 @@ static unsigned long nv_mode_filter(struct ata_device *dev,
                limit |= ATA_MASK_PIO;
        if (!(limit & (ATA_MASK_MWDMA | ATA_MASK_UDMA)))
                limit |= ATA_MASK_MWDMA | ATA_MASK_UDMA;
+       /* PIO4, MWDMA2, UDMA2 should always be supported regardless of
+          cable detection result */
+       limit |= ata_pack_xfermask(ATA_PIO4, ATA_MWDMA2, ATA_UDMA2);
 
        ata_port_printk(ap, KERN_DEBUG, "nv_mode_filter: 0x%lx&0x%lx->0x%lx, "
                        "BIOS=0x%lx (0x%x) ACPI=0x%lx%s\n",
diff --git a/drivers/ata/pata_atp867x.c b/drivers/ata/pata_atp867x.c
new file mode 100644 (file)
index 0000000..7990de9
--- /dev/null
@@ -0,0 +1,548 @@
+/*
+ * pata_atp867x.c - ARTOP 867X 64bit 4-channel UDMA133 ATA controller driver
+ *
+ *     (C) 2009 Google Inc. John(Jung-Ik) Lee <jilee@google.com>
+ *
+ * Per Atp867 data sheet rev 1.2, Acard.
+ * Based in part on early ide code from
+ *     2003-2004 by Eric Uhrhane, Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *
+ * TODO:
+ *   1. RAID features [comparison, XOR, striping, mirroring, etc.]
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <scsi/scsi_host.h>
+#include <linux/libata.h>
+
+#define        DRV_NAME        "pata_atp867x"
+#define        DRV_VERSION     "0.7.5"
+
+/*
+ * IO Registers
+ * Note that all runtime hot priv ports are cached in ap private_data
+ */
+
+enum {
+       ATP867X_IO_CHANNEL_OFFSET       = 0x10,
+
+       /*
+        * IO Register Bitfields
+        */
+
+       ATP867X_IO_PIOSPD_ACTIVE_SHIFT  = 4,
+       ATP867X_IO_PIOSPD_RECOVER_SHIFT = 0,
+
+       ATP867X_IO_DMAMODE_MSTR_SHIFT   = 0,
+       ATP867X_IO_DMAMODE_MSTR_MASK    = 0x07,
+       ATP867X_IO_DMAMODE_SLAVE_SHIFT  = 4,
+       ATP867X_IO_DMAMODE_SLAVE_MASK   = 0x70,
+
+       ATP867X_IO_DMAMODE_UDMA_6       = 0x07,
+       ATP867X_IO_DMAMODE_UDMA_5       = 0x06,
+       ATP867X_IO_DMAMODE_UDMA_4       = 0x05,
+       ATP867X_IO_DMAMODE_UDMA_3       = 0x04,
+       ATP867X_IO_DMAMODE_UDMA_2       = 0x03,
+       ATP867X_IO_DMAMODE_UDMA_1       = 0x02,
+       ATP867X_IO_DMAMODE_UDMA_0       = 0x01,
+       ATP867X_IO_DMAMODE_DISABLE      = 0x00,
+
+       ATP867X_IO_SYS_INFO_66MHZ       = 0x04,
+       ATP867X_IO_SYS_INFO_SLOW_UDMA5  = 0x02,
+       ATP867X_IO_SYS_MASK_RESERVED    = (~0xf1),
+
+       ATP867X_IO_PORTSPD_VAL          = 0x1143,
+       ATP867X_PREREAD_VAL             = 0x0200,
+
+       ATP867X_NUM_PORTS               = 4,
+       ATP867X_BAR_IOBASE              = 0,
+       ATP867X_BAR_ROMBASE             = 6,
+};
+
+#define ATP867X_IOBASE(ap)             ((ap)->host->iomap[0])
+#define ATP867X_SYS_INFO(ap)           (0x3F + ATP867X_IOBASE(ap))
+
+#define ATP867X_IO_PORTBASE(ap, port)  (0x00 + ATP867X_IOBASE(ap) + \
+                                       (port) * ATP867X_IO_CHANNEL_OFFSET)
+#define ATP867X_IO_DMABASE(ap, port)   (0x40 + \
+                                       ATP867X_IO_PORTBASE((ap), (port)))
+
+#define ATP867X_IO_STATUS(ap, port)    (0x07 + \
+                                       ATP867X_IO_PORTBASE((ap), (port)))
+#define ATP867X_IO_ALTSTATUS(ap, port) (0x0E + \
+                                       ATP867X_IO_PORTBASE((ap), (port)))
+
+/*
+ * hot priv ports
+ */
+#define ATP867X_IO_MSTRPIOSPD(ap, port)        (0x08 + \
+                                       ATP867X_IO_DMABASE((ap), (port)))
+#define ATP867X_IO_SLAVPIOSPD(ap, port)        (0x09 + \
+                                       ATP867X_IO_DMABASE((ap), (port)))
+#define ATP867X_IO_8BPIOSPD(ap, port)  (0x0A + \
+                                       ATP867X_IO_DMABASE((ap), (port)))
+#define ATP867X_IO_DMAMODE(ap, port)   (0x0B + \
+                                       ATP867X_IO_DMABASE((ap), (port)))
+
+#define ATP867X_IO_PORTSPD(ap, port)   (0x4A + \
+                                       ATP867X_IO_PORTBASE((ap), (port)))
+#define ATP867X_IO_PREREAD(ap, port)   (0x4C + \
+                                       ATP867X_IO_PORTBASE((ap), (port)))
+
+struct atp867x_priv {
+       void __iomem *dma_mode;
+       void __iomem *mstr_piospd;
+       void __iomem *slave_piospd;
+       void __iomem *eightb_piospd;
+       int             pci66mhz;
+};
+
+static inline u8 atp867x_speed_to_mode(u8 speed)
+{
+       return speed - XFER_UDMA_0 + 1;
+}
+
+static void atp867x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
+{
+       struct pci_dev *pdev    = to_pci_dev(ap->host->dev);
+       struct atp867x_priv *dp = ap->private_data;
+       u8 speed = adev->dma_mode;
+       u8 b;
+       u8 mode;
+
+       mode = atp867x_speed_to_mode(speed);
+
+       /*
+        * Doc 6.6.9: decrease the udma mode value by 1 for safer UDMA speed
+        * on 66MHz bus
+        *   rev-A: UDMA_1~4 (5, 6 no change)
+        *   rev-B: all UDMA modes
+        *   UDMA_0 stays not to disable UDMA
+        */
+       if (dp->pci66mhz && mode > ATP867X_IO_DMAMODE_UDMA_0  &&
+          (pdev->device == PCI_DEVICE_ID_ARTOP_ATP867B ||
+           mode < ATP867X_IO_DMAMODE_UDMA_5))
+               mode--;
+
+       b = ioread8(dp->dma_mode);
+       if (adev->devno & 1) {
+               b = (b & ~ATP867X_IO_DMAMODE_SLAVE_MASK) |
+                       (mode << ATP867X_IO_DMAMODE_SLAVE_SHIFT);
+       } else {
+               b = (b & ~ATP867X_IO_DMAMODE_MSTR_MASK) |
+                       (mode << ATP867X_IO_DMAMODE_MSTR_SHIFT);
+       }
+       iowrite8(b, dp->dma_mode);
+}
+
+static int atp867x_get_active_clocks_shifted(unsigned int clk)
+{
+       unsigned char clocks = clk;
+
+       switch (clocks) {
+       case 0:
+               clocks = 1;
+               break;
+       case 1 ... 7:
+               break;
+       case 8 ... 12:
+               clocks = 7;
+               break;
+       default:
+               printk(KERN_WARNING "ATP867X: active %dclk is invalid. "
+                       "Using default 8clk.\n", clk);
+               clocks = 0;     /* 8 clk */
+               break;
+       }
+       return clocks << ATP867X_IO_PIOSPD_ACTIVE_SHIFT;
+}
+
+static int atp867x_get_recover_clocks_shifted(unsigned int clk)
+{
+       unsigned char clocks = clk;
+
+       switch (clocks) {
+       case 0:
+               clocks = 1;
+               break;
+       case 1 ... 11:
+               break;
+       case 12:
+               clocks = 0;
+               break;
+       case 13: case 14:
+               --clocks;
+               break;
+       case 15:
+               break;
+       default:
+               printk(KERN_WARNING "ATP867X: recover %dclk is invalid. "
+                       "Using default 15clk.\n", clk);
+               clocks = 0;     /* 12 clk */
+               break;
+       }
+       return clocks << ATP867X_IO_PIOSPD_RECOVER_SHIFT;
+}
+
+static void atp867x_set_piomode(struct ata_port *ap, struct ata_device *adev)
+{
+       struct ata_device *peer = ata_dev_pair(adev);
+       struct atp867x_priv *dp = ap->private_data;
+       u8 speed = adev->pio_mode;
+       struct ata_timing t, p;
+       int T, UT;
+       u8 b;
+
+       T = 1000000000 / 33333;
+       UT = T / 4;
+
+       ata_timing_compute(adev, speed, &t, T, UT);
+       if (peer && peer->pio_mode) {
+               ata_timing_compute(peer, peer->pio_mode, &p, T, UT);
+               ata_timing_merge(&p, &t, &t, ATA_TIMING_8BIT);
+       }
+
+       b = ioread8(dp->dma_mode);
+       if (adev->devno & 1)
+               b = (b & ~ATP867X_IO_DMAMODE_SLAVE_MASK);
+       else
+               b = (b & ~ATP867X_IO_DMAMODE_MSTR_MASK);
+       iowrite8(b, dp->dma_mode);
+
+       b = atp867x_get_active_clocks_shifted(t.active) |
+               atp867x_get_recover_clocks_shifted(t.recover);
+       if (dp->pci66mhz)
+               b += 0x10;
+
+       if (adev->devno & 1)
+               iowrite8(b, dp->slave_piospd);
+       else
+               iowrite8(b, dp->mstr_piospd);
+
+       /*
+        * use the same value for comand timing as for PIO timimg
+        */
+       iowrite8(b, dp->eightb_piospd);
+}
+
+static int atp867x_cable_detect(struct ata_port *ap)
+{
+       return ATA_CBL_PATA40_SHORT;
+}
+
+static struct scsi_host_template atp867x_sht = {
+       ATA_BMDMA_SHT(DRV_NAME),
+};
+
+static struct ata_port_operations atp867x_ops = {
+       .inherits               = &ata_bmdma_port_ops,
+       .cable_detect           = atp867x_cable_detect,
+       .set_piomode            = atp867x_set_piomode,
+       .set_dmamode            = atp867x_set_dmamode,
+};
+
+
+#ifdef ATP867X_DEBUG
+static void atp867x_check_res(struct pci_dev *pdev)
+{
+       int i;
+       unsigned long start, len;
+
+       /* Check the PCI resources for this channel are enabled */
+       for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+               start = pci_resource_start(pdev, i);
+               len   = pci_resource_len(pdev, i);
+               printk(KERN_DEBUG "ATP867X: resource start:len=%lx:%lx\n",
+                       start, len);
+       }
+}
+
+static void atp867x_check_ports(struct ata_port *ap, int port)
+{
+       struct ata_ioports *ioaddr = &ap->ioaddr;
+       struct atp867x_priv *dp = ap->private_data;
+
+       printk(KERN_DEBUG "ATP867X: port[%d] addresses\n"
+               "  cmd_addr     =0x%llx, 0x%llx\n"
+               "  ctl_addr     =0x%llx, 0x%llx\n"
+               "  bmdma_addr   =0x%llx, 0x%llx\n"
+               "  data_addr    =0x%llx\n"
+               "  error_addr   =0x%llx\n"
+               "  feature_addr =0x%llx\n"
+               "  nsect_addr   =0x%llx\n"
+               "  lbal_addr    =0x%llx\n"
+               "  lbam_addr    =0x%llx\n"
+               "  lbah_addr    =0x%llx\n"
+               "  device_addr  =0x%llx\n"
+               "  status_addr  =0x%llx\n"
+               "  command_addr =0x%llx\n"
+               "  dp->dma_mode =0x%llx\n"
+               "  dp->mstr_piospd      =0x%llx\n"
+               "  dp->slave_piospd     =0x%llx\n"
+               "  dp->eightb_piospd    =0x%llx\n"
+               "  dp->pci66mhz         =0x%lx\n",
+               port,
+               (unsigned long long)ioaddr->cmd_addr,
+               (unsigned long long)ATP867X_IO_PORTBASE(ap, port),
+               (unsigned long long)ioaddr->ctl_addr,
+               (unsigned long long)ATP867X_IO_ALTSTATUS(ap, port),
+               (unsigned long long)ioaddr->bmdma_addr,
+               (unsigned long long)ATP867X_IO_DMABASE(ap, port),
+               (unsigned long long)ioaddr->data_addr,
+               (unsigned long long)ioaddr->error_addr,
+               (unsigned long long)ioaddr->feature_addr,
+               (unsigned long long)ioaddr->nsect_addr,
+               (unsigned long long)ioaddr->lbal_addr,
+               (unsigned long long)ioaddr->lbam_addr,
+               (unsigned long long)ioaddr->lbah_addr,
+               (unsigned long long)ioaddr->device_addr,
+               (unsigned long long)ioaddr->status_addr,
+               (unsigned long long)ioaddr->command_addr,
+               (unsigned long long)dp->dma_mode,
+               (unsigned long long)dp->mstr_piospd,
+               (unsigned long long)dp->slave_piospd,
+               (unsigned long long)dp->eightb_piospd,
+               (unsigned long)dp->pci66mhz);
+}
+#endif
+
+static int atp867x_set_priv(struct ata_port *ap)
+{
+       struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+       struct atp867x_priv *dp;
+       int port = ap->port_no;
+
+       dp = ap->private_data =
+               devm_kzalloc(&pdev->dev, sizeof(*dp), GFP_KERNEL);
+       if (dp == NULL)
+               return -ENOMEM;
+
+       dp->dma_mode     = ATP867X_IO_DMAMODE(ap, port);
+       dp->mstr_piospd  = ATP867X_IO_MSTRPIOSPD(ap, port);
+       dp->slave_piospd = ATP867X_IO_SLAVPIOSPD(ap, port);
+       dp->eightb_piospd = ATP867X_IO_8BPIOSPD(ap, port);
+
+       dp->pci66mhz =
+               ioread8(ATP867X_SYS_INFO(ap)) & ATP867X_IO_SYS_INFO_66MHZ;
+
+       return 0;
+}
+
+static void atp867x_fixup(struct ata_host *host)
+{
+       struct pci_dev *pdev = to_pci_dev(host->dev);
+       struct ata_port *ap = host->ports[0];
+       int i;
+       u8 v;
+
+       /*
+        * Broken BIOS might not set latency high enough
+        */
+       pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &v);
+       if (v < 0x80) {
+               v = 0x80;
+               pci_write_config_byte(pdev, PCI_LATENCY_TIMER, v);
+               printk(KERN_DEBUG "ATP867X: set latency timer of device %s"
+                       " to %d\n", pci_name(pdev), v);
+       }
+
+       /*
+        * init 8bit io ports speed(0aaarrrr) to 43h and
+        * init udma modes of master/slave to 0/0(11h)
+        */
+       for (i = 0; i < ATP867X_NUM_PORTS; i++)
+               iowrite16(ATP867X_IO_PORTSPD_VAL, ATP867X_IO_PORTSPD(ap, i));
+
+       /*
+        * init PreREAD counts
+        */
+       for (i = 0; i < ATP867X_NUM_PORTS; i++)
+               iowrite16(ATP867X_PREREAD_VAL, ATP867X_IO_PREREAD(ap, i));
+
+       v = ioread8(ATP867X_IOBASE(ap) + 0x28);
+       v &= 0xcf;      /* Enable INTA#: bit4=0 means enable */
+       v |= 0xc0;      /* Enable PCI burst, MRM & not immediate interrupts */
+       iowrite8(v, ATP867X_IOBASE(ap) + 0x28);
+
+       /*
+        * Turn off the over clocked udma5 mode, only for Rev-B
+        */
+       v = ioread8(ATP867X_SYS_INFO(ap));
+       v &= ATP867X_IO_SYS_MASK_RESERVED;
+       if (pdev->device == PCI_DEVICE_ID_ARTOP_ATP867B)
+               v |= ATP867X_IO_SYS_INFO_SLOW_UDMA5;
+       iowrite8(v, ATP867X_SYS_INFO(ap));
+}
+
+static int atp867x_ata_pci_sff_init_host(struct ata_host *host)
+{
+       struct device *gdev = host->dev;
+       struct pci_dev *pdev = to_pci_dev(gdev);
+       unsigned int mask = 0;
+       int i, rc;
+
+       /*
+        * do not map rombase
+        */
+       rc = pcim_iomap_regions(pdev, 1 << ATP867X_BAR_IOBASE, DRV_NAME);
+       if (rc == -EBUSY)
+               pcim_pin_device(pdev);
+       if (rc)
+               return rc;
+       host->iomap = pcim_iomap_table(pdev);
+
+#ifdef ATP867X_DEBUG
+       atp867x_check_res(pdev);
+
+       for (i = 0; i < PCI_ROM_RESOURCE; i++)
+               printk(KERN_DEBUG "ATP867X: iomap[%d]=0x%llx\n", i,
+                       (unsigned long long)(host->iomap[i]));
+#endif
+
+       /*
+        * request, iomap BARs and init port addresses accordingly
+        */
+       for (i = 0; i < host->n_ports; i++) {
+               struct ata_port *ap = host->ports[i];
+               struct ata_ioports *ioaddr = &ap->ioaddr;
+
+               ioaddr->cmd_addr = ATP867X_IO_PORTBASE(ap, i);
+               ioaddr->ctl_addr = ioaddr->altstatus_addr
+                                = ATP867X_IO_ALTSTATUS(ap, i);
+               ioaddr->bmdma_addr = ATP867X_IO_DMABASE(ap, i);
+
+               ata_sff_std_ports(ioaddr);
+               rc = atp867x_set_priv(ap);
+               if (rc)
+                       return rc;
+
+#ifdef ATP867X_DEBUG
+               atp867x_check_ports(ap, i);
+#endif
+               ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx",
+                       (unsigned long)ioaddr->cmd_addr,
+                       (unsigned long)ioaddr->ctl_addr);
+               ata_port_desc(ap, "bmdma 0x%lx",
+                       (unsigned long)ioaddr->bmdma_addr);
+
+               mask |= 1 << i;
+       }
+
+       if (!mask) {
+               dev_printk(KERN_ERR, gdev, "no available native port\n");
+               return -ENODEV;
+       }
+
+       atp867x_fixup(host);
+
+       rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
+       if (rc)
+               return rc;
+
+       rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
+       return rc;
+}
+
+static int atp867x_init_one(struct pci_dev *pdev,
+       const struct pci_device_id *id)
+{
+       static int printed_version;
+       static const struct ata_port_info info_867x = {
+               .flags          = ATA_FLAG_SLAVE_POSS,
+               .pio_mask       = ATA_PIO4,
+               .mwdma_mask     = ATA_MWDMA2,
+               .udma_mask      = ATA_UDMA6,
+               .port_ops       = &atp867x_ops,
+       };
+
+       struct ata_host *host;
+       const struct ata_port_info *ppi[] = { &info_867x, NULL };
+       int rc;
+
+       if (!printed_version++)
+               dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
+
+       rc = pcim_enable_device(pdev);
+       if (rc)
+               return rc;
+
+       printk(KERN_INFO "ATP867X: ATP867 ATA UDMA133 controller (rev %02X)",
+               pdev->device);
+
+       host = ata_host_alloc_pinfo(&pdev->dev, ppi, ATP867X_NUM_PORTS);
+       if (!host) {
+               dev_printk(KERN_ERR, &pdev->dev,
+                       "failed to allocate ATA host\n");
+               rc = -ENOMEM;
+               goto err_out;
+       }
+
+       rc = atp867x_ata_pci_sff_init_host(host);
+       if (rc) {
+               dev_printk(KERN_ERR, &pdev->dev, "failed to init host\n");
+               goto err_out;
+       }
+
+       pci_set_master(pdev);
+
+       rc = ata_host_activate(host, pdev->irq, ata_sff_interrupt,
+                               IRQF_SHARED, &atp867x_sht);
+       if (rc)
+               dev_printk(KERN_ERR, &pdev->dev, "failed to activate host\n");
+
+err_out:
+       return rc;
+}
+
+static struct pci_device_id atp867x_pci_tbl[] = {
+       { PCI_VDEVICE(ARTOP, PCI_DEVICE_ID_ARTOP_ATP867A),      0 },
+       { PCI_VDEVICE(ARTOP, PCI_DEVICE_ID_ARTOP_ATP867B),      0 },
+       { },
+};
+
+static struct pci_driver atp867x_driver = {
+       .name           = DRV_NAME,
+       .id_table       = atp867x_pci_tbl,
+       .probe          = atp867x_init_one,
+       .remove         = ata_pci_remove_one,
+};
+
+static int __init atp867x_init(void)
+{
+       return pci_register_driver(&atp867x_driver);
+}
+
+static void __exit atp867x_exit(void)
+{
+       pci_unregister_driver(&atp867x_driver);
+}
+
+MODULE_AUTHOR("John(Jung-Ik) Lee, Google Inc.");
+MODULE_DESCRIPTION("low level driver for Artop/Acard 867x ATA controller");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, atp867x_pci_tbl);
+MODULE_VERSION(DRV_VERSION);
+
+module_init(atp867x_init);
+module_exit(atp867x_exit);
index b1fd7d62071ab4a8616b9f27fa9c21d8f30c232e..07d8d00b4d344cb38740f9d6a60ed6478e2b2b67 100644 (file)
@@ -56,6 +56,7 @@ enum {
        /* host register offsets (from host->iomap[PDC_MMIO_BAR]) */
        PDC_INT_SEQMASK         = 0x40, /* Mask of asserted SEQ INTs */
        PDC_FLASH_CTL           = 0x44, /* Flash control register */
+       PDC_PCI_CTL             = 0x48, /* PCI control/status reg */
        PDC_SATA_PLUG_CSR       = 0x6C, /* SATA Plug control/status reg */
        PDC2_SATA_PLUG_CSR      = 0x60, /* SATAII Plug control/status reg */
        PDC_TBG_MODE            = 0x41C, /* TBG mode (not SATAII) */
@@ -75,7 +76,17 @@ enum {
        PDC_CTLSTAT             = 0x60, /* IDE control and status (per port) */
 
        /* per-port SATA register offsets (from ap->ioaddr.scr_addr) */
+       PDC_SATA_ERROR          = 0x04,
        PDC_PHYMODE4            = 0x14,
+       PDC_LINK_LAYER_ERRORS   = 0x6C,
+       PDC_FPDMA_CTLSTAT       = 0xD8,
+       PDC_INTERNAL_DEBUG_1    = 0xF8, /* also used for PATA */
+       PDC_INTERNAL_DEBUG_2    = 0xFC, /* also used for PATA */
+
+       /* PDC_FPDMA_CTLSTAT bit definitions */
+       PDC_FPDMA_CTLSTAT_RESET                 = 1 << 3,
+       PDC_FPDMA_CTLSTAT_DMASETUP_INT_FLAG     = 1 << 10,
+       PDC_FPDMA_CTLSTAT_SETDB_INT_FLAG        = 1 << 11,
 
        /* PDC_GLOBAL_CTL bit definitions */
        PDC_PH_ERR              = (1 <<  8), /* PCI error while loading packet */
@@ -195,9 +206,12 @@ static struct ata_port_operations pdc_sata_ops = {
        .hardreset              = pdc_sata_hardreset,
 };
 
-/* First-generation chips need a more restrictive ->check_atapi_dma op */
+/* First-generation chips need a more restrictive ->check_atapi_dma op,
+   and ->freeze/thaw that ignore the hotplug controls. */
 static struct ata_port_operations pdc_old_sata_ops = {
        .inherits               = &pdc_sata_ops,
+       .freeze                 = pdc_freeze,
+       .thaw                   = pdc_thaw,
        .check_atapi_dma        = pdc_old_sata_check_atapi_dma,
 };
 
@@ -356,12 +370,76 @@ static int pdc_sata_port_start(struct ata_port *ap)
        return 0;
 }
 
+static void pdc_fpdma_clear_interrupt_flag(struct ata_port *ap)
+{
+       void __iomem *sata_mmio = ap->ioaddr.scr_addr;
+       u32 tmp;
+
+       tmp = readl(sata_mmio + PDC_FPDMA_CTLSTAT);
+       tmp |= PDC_FPDMA_CTLSTAT_DMASETUP_INT_FLAG;
+       tmp |= PDC_FPDMA_CTLSTAT_SETDB_INT_FLAG;
+
+       /* It's not allowed to write to the entire FPDMA_CTLSTAT register
+          when NCQ is running. So do a byte-sized write to bits 10 and 11. */
+       writeb(tmp >> 8, sata_mmio + PDC_FPDMA_CTLSTAT + 1);
+       readb(sata_mmio + PDC_FPDMA_CTLSTAT + 1); /* flush */
+}
+
+static void pdc_fpdma_reset(struct ata_port *ap)
+{
+       void __iomem *sata_mmio = ap->ioaddr.scr_addr;
+       u8 tmp;
+
+       tmp = (u8)readl(sata_mmio + PDC_FPDMA_CTLSTAT);
+       tmp &= 0x7F;
+       tmp |= PDC_FPDMA_CTLSTAT_RESET;
+       writeb(tmp, sata_mmio + PDC_FPDMA_CTLSTAT);
+       readl(sata_mmio + PDC_FPDMA_CTLSTAT); /* flush */
+       udelay(100);
+       tmp &= ~PDC_FPDMA_CTLSTAT_RESET;
+       writeb(tmp, sata_mmio + PDC_FPDMA_CTLSTAT);
+       readl(sata_mmio + PDC_FPDMA_CTLSTAT); /* flush */
+
+       pdc_fpdma_clear_interrupt_flag(ap);
+}
+
+static void pdc_not_at_command_packet_phase(struct ata_port *ap)
+{
+       void __iomem *sata_mmio = ap->ioaddr.scr_addr;
+       unsigned int i;
+       u32 tmp;
+
+       /* check not at ASIC packet command phase */
+       for (i = 0; i < 100; ++i) {
+               writel(0, sata_mmio + PDC_INTERNAL_DEBUG_1);
+               tmp = readl(sata_mmio + PDC_INTERNAL_DEBUG_2);
+               if ((tmp & 0xF) != 1)
+                       break;
+               udelay(100);
+       }
+}
+
+static void pdc_clear_internal_debug_record_error_register(struct ata_port *ap)
+{
+       void __iomem *sata_mmio = ap->ioaddr.scr_addr;
+
+       writel(0xffffffff, sata_mmio + PDC_SATA_ERROR);
+       writel(0xffff0000, sata_mmio + PDC_LINK_LAYER_ERRORS);
+}
+
 static void pdc_reset_port(struct ata_port *ap)
 {
        void __iomem *ata_ctlstat_mmio = ap->ioaddr.cmd_addr + PDC_CTLSTAT;
        unsigned int i;
        u32 tmp;
 
+       if (ap->flags & PDC_FLAG_GEN_II)
+               pdc_not_at_command_packet_phase(ap);
+
+       tmp = readl(ata_ctlstat_mmio);
+       tmp |= PDC_RESET;
+       writel(tmp, ata_ctlstat_mmio);
+
        for (i = 11; i > 0; i--) {
                tmp = readl(ata_ctlstat_mmio);
                if (tmp & PDC_RESET)
@@ -376,6 +454,11 @@ static void pdc_reset_port(struct ata_port *ap)
        tmp &= ~PDC_RESET;
        writel(tmp, ata_ctlstat_mmio);
        readl(ata_ctlstat_mmio);        /* flush */
+
+       if (sata_scr_valid(&ap->link) && (ap->flags & PDC_FLAG_GEN_II)) {
+               pdc_fpdma_reset(ap);
+               pdc_clear_internal_debug_record_error_register(ap);
+       }
 }
 
 static int pdc_pata_cable_detect(struct ata_port *ap)
@@ -626,11 +709,6 @@ static unsigned int pdc_sata_ata_port_to_ata_no(const struct ata_port *ap)
        return pdc_port_no_to_ata_no(i, pdc_is_sataii_tx4(ap->flags));
 }
 
-static unsigned int pdc_sata_hotplug_offset(const struct ata_port *ap)
-{
-       return (ap->flags & PDC_FLAG_GEN_II) ? PDC2_SATA_PLUG_CSR : PDC_SATA_PLUG_CSR;
-}
-
 static void pdc_freeze(struct ata_port *ap)
 {
        void __iomem *ata_mmio = ap->ioaddr.cmd_addr;
@@ -647,7 +725,7 @@ static void pdc_sata_freeze(struct ata_port *ap)
 {
        struct ata_host *host = ap->host;
        void __iomem *host_mmio = host->iomap[PDC_MMIO_BAR];
-       unsigned int hotplug_offset = pdc_sata_hotplug_offset(ap);
+       unsigned int hotplug_offset = PDC2_SATA_PLUG_CSR;
        unsigned int ata_no = pdc_sata_ata_port_to_ata_no(ap);
        u32 hotplug_status;
 
@@ -685,7 +763,7 @@ static void pdc_sata_thaw(struct ata_port *ap)
 {
        struct ata_host *host = ap->host;
        void __iomem *host_mmio = host->iomap[PDC_MMIO_BAR];
-       unsigned int hotplug_offset = pdc_sata_hotplug_offset(ap);
+       unsigned int hotplug_offset = PDC2_SATA_PLUG_CSR;
        unsigned int ata_no = pdc_sata_ata_port_to_ata_no(ap);
        u32 hotplug_status;
 
@@ -708,11 +786,50 @@ static int pdc_pata_softreset(struct ata_link *link, unsigned int *class,
        return ata_sff_softreset(link, class, deadline);
 }
 
+static unsigned int pdc_ata_port_to_ata_no(const struct ata_port *ap)
+{
+       void __iomem *ata_mmio = ap->ioaddr.cmd_addr;
+       void __iomem *host_mmio = ap->host->iomap[PDC_MMIO_BAR];
+
+       /* ata_mmio == host_mmio + 0x200 + ata_no * 0x80 */
+       return (ata_mmio - host_mmio - 0x200) / 0x80;
+}
+
+static void pdc_hard_reset_port(struct ata_port *ap)
+{
+       void __iomem *host_mmio = ap->host->iomap[PDC_MMIO_BAR];
+       void __iomem *pcictl_b1_mmio = host_mmio + PDC_PCI_CTL + 1;
+       unsigned int ata_no = pdc_ata_port_to_ata_no(ap);
+       u8 tmp;
+
+       spin_lock(&ap->host->lock);
+
+       tmp = readb(pcictl_b1_mmio);
+       tmp &= ~(0x10 << ata_no);
+       writeb(tmp, pcictl_b1_mmio);
+       readb(pcictl_b1_mmio); /* flush */
+       udelay(100);
+       tmp |= (0x10 << ata_no);
+       writeb(tmp, pcictl_b1_mmio);
+       readb(pcictl_b1_mmio); /* flush */
+
+       spin_unlock(&ap->host->lock);
+}
+
 static int pdc_sata_hardreset(struct ata_link *link, unsigned int *class,
                              unsigned long deadline)
 {
+       if (link->ap->flags & PDC_FLAG_GEN_II)
+               pdc_not_at_command_packet_phase(link->ap);
+       /* hotplug IRQs should have been masked by pdc_sata_freeze() */
+       pdc_hard_reset_port(link->ap);
        pdc_reset_port(link->ap);
-       return sata_sff_hardreset(link, class, deadline);
+
+       /* sata_promise can't reliably acquire the first D2H Reg FIS
+        * after hardreset.  Do non-waiting hardreset and request
+        * follow-up SRST.
+        */
+       return sata_std_hardreset(link, class, deadline);
 }
 
 static void pdc_error_handler(struct ata_port *ap)
@@ -832,14 +949,14 @@ static irqreturn_t pdc_interrupt(int irq, void *dev_instance)
        spin_lock(&host->lock);
 
        /* read and clear hotplug flags for all ports */
-       if (host->ports[0]->flags & PDC_FLAG_GEN_II)
+       if (host->ports[0]->flags & PDC_FLAG_GEN_II) {
                hotplug_offset = PDC2_SATA_PLUG_CSR;
-       else
-               hotplug_offset = PDC_SATA_PLUG_CSR;
-       hotplug_status = readl(host_mmio + hotplug_offset);
-       if (hotplug_status & 0xff)
-               writel(hotplug_status | 0xff, host_mmio + hotplug_offset);
-       hotplug_status &= 0xff; /* clear uninteresting bits */
+               hotplug_status = readl(host_mmio + hotplug_offset);
+               if (hotplug_status & 0xff)
+                       writel(hotplug_status | 0xff, host_mmio + hotplug_offset);
+               hotplug_status &= 0xff; /* clear uninteresting bits */
+       } else
+               hotplug_status = 0;
 
        /* reading should also clear interrupts */
        mask = readl(host_mmio + PDC_INT_SEQMASK);
@@ -1034,9 +1151,11 @@ static void pdc_host_init(struct ata_host *host)
        tmp = readl(host_mmio + hotplug_offset);
        writel(tmp | 0xff, host_mmio + hotplug_offset);
 
-       /* unmask plug/unplug ints */
        tmp = readl(host_mmio + hotplug_offset);
-       writel(tmp & ~0xff0000, host_mmio + hotplug_offset);
+       if (is_gen2)    /* unmask plug/unplug ints */
+               writel(tmp & ~0xff0000, host_mmio + hotplug_offset);
+       else            /* mask plug/unplug ints */
+               writel(tmp | 0xff0000, host_mmio + hotplug_offset);
 
        /* don't initialise TBG or SLEW on 2nd generation chips */
        if (is_gen2)
index ce66a70184f7568d8023ca0b5243ae9d7053eb75..87060266ef91b9ba765a0c951e268119beddf6f4 100644 (file)
@@ -126,6 +126,19 @@ config HW_RANDOM_OMAP
 
          If unsure, say Y.
 
+config HW_RANDOM_OCTEON
+       tristate "Octeon Random Number Generator support"
+       depends on HW_RANDOM && CPU_CAVIUM_OCTEON
+       default HW_RANDOM
+       ---help---
+         This driver provides kernel-side support for the Random Number
+         Generator hardware found on Octeon processors.
+
+         To compile this driver as a module, choose M here: the
+         module will be called octeon-rng.
+
+         If unsure, say Y.
+
 config HW_RANDOM_PASEMI
        tristate "PA Semi HW Random Number Generator support"
        depends on HW_RANDOM && PPC_PASEMI
index 676828ba81238c72e20213595e8598cc6b9dd4b2..5eeb1303f0d01efeb98d62282fb07c41e233b936 100644 (file)
@@ -17,3 +17,4 @@ obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o
 obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o
 obj-$(CONFIG_HW_RANDOM_TX4939) += tx4939-rng.o
 obj-$(CONFIG_HW_RANDOM_MXC_RNGA) += mxc-rnga.o
+obj-$(CONFIG_HW_RANDOM_OCTEON) += octeon-rng.o
diff --git a/drivers/char/hw_random/octeon-rng.c b/drivers/char/hw_random/octeon-rng.c
new file mode 100644 (file)
index 0000000..54b0d9b
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * Hardware Random Number Generator support for Cavium Networks
+ * Octeon processor family.
+ *
+ * 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) 2009 Cavium Networks
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/hw_random.h>
+#include <linux/io.h>
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-rnm-defs.h>
+
+struct octeon_rng {
+       struct hwrng ops;
+       void __iomem *control_status;
+       void __iomem *result;
+};
+
+static int octeon_rng_init(struct hwrng *rng)
+{
+       union cvmx_rnm_ctl_status ctl;
+       struct octeon_rng *p = container_of(rng, struct octeon_rng, ops);
+
+       ctl.u64 = 0;
+       ctl.s.ent_en = 1; /* Enable the entropy source.  */
+       ctl.s.rng_en = 1; /* Enable the RNG hardware.  */
+       cvmx_write_csr((u64)p->control_status, ctl.u64);
+       return 0;
+}
+
+static void octeon_rng_cleanup(struct hwrng *rng)
+{
+       union cvmx_rnm_ctl_status ctl;
+       struct octeon_rng *p = container_of(rng, struct octeon_rng, ops);
+
+       ctl.u64 = 0;
+       /* Disable everything.  */
+       cvmx_write_csr((u64)p->control_status, ctl.u64);
+}
+
+static int octeon_rng_data_read(struct hwrng *rng, u32 *data)
+{
+       struct octeon_rng *p = container_of(rng, struct octeon_rng, ops);
+
+       *data = cvmx_read64_uint32((u64)p->result);
+       return sizeof(u32);
+}
+
+static int __devinit octeon_rng_probe(struct platform_device *pdev)
+{
+       struct resource *res_ports;
+       struct resource *res_result;
+       struct octeon_rng *rng;
+       int ret;
+       struct hwrng ops = {
+               .name = "octeon",
+               .init = octeon_rng_init,
+               .cleanup = octeon_rng_cleanup,
+               .data_read = octeon_rng_data_read
+       };
+
+       rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL);
+       if (!rng)
+               return -ENOMEM;
+
+       res_ports = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res_ports)
+               goto err_ports;
+
+       res_result = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+       if (!res_result)
+               goto err_ports;
+
+
+       rng->control_status = devm_ioremap_nocache(&pdev->dev,
+                                                  res_ports->start,
+                                                  sizeof(u64));
+       if (!rng->control_status)
+               goto err_ports;
+
+       rng->result = devm_ioremap_nocache(&pdev->dev,
+                                          res_result->start,
+                                          sizeof(u64));
+       if (!rng->result)
+               goto err_r;
+
+       rng->ops = ops;
+
+       dev_set_drvdata(&pdev->dev, &rng->ops);
+       ret = hwrng_register(&rng->ops);
+       if (ret)
+               goto err;
+
+       dev_info(&pdev->dev, "Octeon Random Number Generator\n");
+
+       return 0;
+err:
+       devm_iounmap(&pdev->dev, rng->control_status);
+err_r:
+       devm_iounmap(&pdev->dev, rng->result);
+err_ports:
+       devm_kfree(&pdev->dev, rng);
+       return -ENOENT;
+}
+
+static int __exit octeon_rng_remove(struct platform_device *pdev)
+{
+       struct hwrng *rng = dev_get_drvdata(&pdev->dev);
+
+       hwrng_unregister(rng);
+
+       return 0;
+}
+
+static struct platform_driver octeon_rng_driver = {
+       .driver = {
+               .name           = "octeon_rng",
+               .owner          = THIS_MODULE,
+       },
+       .probe          = octeon_rng_probe,
+       .remove         = __exit_p(octeon_rng_remove),
+};
+
+static int __init octeon_rng_mod_init(void)
+{
+       return platform_driver_register(&octeon_rng_driver);
+}
+
+static void __exit octeon_rng_mod_exit(void)
+{
+       platform_driver_unregister(&octeon_rng_driver);
+}
+
+module_init(octeon_rng_mod_init);
+module_exit(octeon_rng_mod_exit);
+
+MODULE_AUTHOR("David Daney");
+MODULE_LICENSE("GPL");
index b33d6688e9109a31bb27a6b297a73a8e69c5989d..53761cefa9154bb541d676b432550d61fc579efb 100644 (file)
@@ -120,8 +120,10 @@ static int pty_write(struct tty_struct *tty, const unsigned char *buf, int c)
                /* Stuff the data into the input queue of the other end */
                c = tty_insert_flip_string(to, buf, c);
                /* And shovel */
-               tty_flip_buffer_push(to);
-               tty_wakeup(tty);
+               if (c) {
+                       tty_flip_buffer_push(to);
+                       tty_wakeup(tty);
+               }
        }
        return c;
 }
index 404f4c1ee43145c5429f6639f0454e5a59818f3f..6aa88f50b0397a36be2720c4555a65d6b96fae2d 100644 (file)
@@ -2948,9 +2948,6 @@ int __init vty_init(const struct file_operations *console_fops)
                panic("Couldn't register console driver\n");
        kbd_init();
        console_map_init();
-#ifdef CONFIG_PROM_CONSOLE
-       prom_con_init();
-#endif
 #ifdef CONFIG_MDA_CONSOLE
        mda_console_init();
 #endif
index 2968ed6a9c4997003591a9ebc33546e19d6deb0b..3938c7817095d0747a44045b51cff3c680e6e78a 100644 (file)
@@ -61,6 +61,8 @@ static DEFINE_SPINLOCK(cpufreq_driver_lock);
  *   are concerned with are online after they get the lock.
  * - Governor routines that can be called in cpufreq hotplug path should not
  *   take this sem as top level hotplug notifier handler takes this.
+ * - Lock should not be held across
+ *     __cpufreq_governor(data, CPUFREQ_GOV_STOP);
  */
 static DEFINE_PER_CPU(int, policy_cpu);
 static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem);
@@ -686,6 +688,9 @@ static struct attribute *default_attrs[] = {
        NULL
 };
 
+struct kobject *cpufreq_global_kobject;
+EXPORT_SYMBOL(cpufreq_global_kobject);
+
 #define to_policy(k) container_of(k, struct cpufreq_policy, kobj)
 #define to_attr(a) container_of(a, struct freq_attr, attr)
 
@@ -756,92 +761,20 @@ static struct kobj_type ktype_cpufreq = {
        .release        = cpufreq_sysfs_release,
 };
 
-
-/**
- * cpufreq_add_dev - add a CPU device
- *
- * Adds the cpufreq interface for a CPU device.
- *
- * The Oracle says: try running cpufreq registration/unregistration concurrently
- * with with cpu hotplugging and all hell will break loose. Tried to clean this
- * mess up, but more thorough testing is needed. - Mathieu
+/*
+ * Returns:
+ *   Negative: Failure
+ *   0:        Success
+ *   Positive: When we have a managed CPU and the sysfs got symlinked
  */
-static int cpufreq_add_dev(struct sys_device *sys_dev)
+int cpufreq_add_dev_policy(unsigned int cpu, struct cpufreq_policy *policy,
+               struct sys_device *sys_dev)
 {
-       unsigned int cpu = sys_dev->id;
        int ret = 0;
-       struct cpufreq_policy new_policy;
-       struct cpufreq_policy *policy;
-       struct freq_attr **drv_attr;
-       struct sys_device *cpu_sys_dev;
+#ifdef CONFIG_SMP
        unsigned long flags;
        unsigned int j;
 
-       if (cpu_is_offline(cpu))
-               return 0;
-
-       cpufreq_debug_disable_ratelimit();
-       dprintk("adding CPU %u\n", cpu);
-
-#ifdef CONFIG_SMP
-       /* check whether a different CPU already registered this
-        * CPU because it is in the same boat. */
-       policy = cpufreq_cpu_get(cpu);
-       if (unlikely(policy)) {
-               cpufreq_cpu_put(policy);
-               cpufreq_debug_enable_ratelimit();
-               return 0;
-       }
-#endif
-
-       if (!try_module_get(cpufreq_driver->owner)) {
-               ret = -EINVAL;
-               goto module_out;
-       }
-
-       policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
-       if (!policy) {
-               ret = -ENOMEM;
-               goto nomem_out;
-       }
-       if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL)) {
-               ret = -ENOMEM;
-               goto err_free_policy;
-       }
-       if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL)) {
-               ret = -ENOMEM;
-               goto err_free_cpumask;
-       }
-
-       policy->cpu = cpu;
-       cpumask_copy(policy->cpus, cpumask_of(cpu));
-
-       /* Initially set CPU itself as the policy_cpu */
-       per_cpu(policy_cpu, cpu) = cpu;
-       ret = (lock_policy_rwsem_write(cpu) < 0);
-       WARN_ON(ret);
-
-       init_completion(&policy->kobj_unregister);
-       INIT_WORK(&policy->update, handle_update);
-
-       /* Set governor before ->init, so that driver could check it */
-       policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
-       /* call driver. From then on the cpufreq must be able
-        * to accept all calls to ->verify and ->setpolicy for this CPU
-        */
-       ret = cpufreq_driver->init(policy);
-       if (ret) {
-               dprintk("initialization failed\n");
-               goto err_unlock_policy;
-       }
-       policy->user_policy.min = policy->min;
-       policy->user_policy.max = policy->max;
-
-       blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
-                                    CPUFREQ_START, policy);
-
-#ifdef CONFIG_SMP
-
 #ifdef CONFIG_HOTPLUG_CPU
        if (per_cpu(cpufreq_cpu_governor, cpu)) {
                policy->governor = per_cpu(cpufreq_cpu_governor, cpu);
@@ -872,9 +805,8 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
                                /* Should not go through policy unlock path */
                                if (cpufreq_driver->exit)
                                        cpufreq_driver->exit(policy);
-                               ret = -EBUSY;
                                cpufreq_cpu_put(managed_policy);
-                               goto err_free_cpumask;
+                               return -EBUSY;
                        }
 
                        spin_lock_irqsave(&cpufreq_driver_lock, flags);
@@ -893,17 +825,62 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
                         * Call driver->exit() because only the cpu parent of
                         * the kobj needed to call init().
                         */
-                       goto out_driver_exit; /* call driver->exit() */
+                       if (cpufreq_driver->exit)
+                               cpufreq_driver->exit(policy);
+
+                       if (!ret)
+                               return 1;
+                       else
+                               return ret;
                }
        }
 #endif
-       memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
+       return ret;
+}
+
+
+/* symlink affected CPUs */
+int cpufreq_add_dev_symlink(unsigned int cpu, struct cpufreq_policy *policy)
+{
+       unsigned int j;
+       int ret = 0;
+
+       for_each_cpu(j, policy->cpus) {
+               struct cpufreq_policy *managed_policy;
+               struct sys_device *cpu_sys_dev;
+
+               if (j == cpu)
+                       continue;
+               if (!cpu_online(j))
+                       continue;
+
+               dprintk("CPU %u already managed, adding link\n", j);
+               managed_policy = cpufreq_cpu_get(cpu);
+               cpu_sys_dev = get_cpu_sysdev(j);
+               ret = sysfs_create_link(&cpu_sys_dev->kobj, &policy->kobj,
+                                       "cpufreq");
+               if (ret) {
+                       cpufreq_cpu_put(managed_policy);
+                       return ret;
+               }
+       }
+       return ret;
+}
+
+int cpufreq_add_dev_interface(unsigned int cpu, struct cpufreq_policy *policy,
+               struct sys_device *sys_dev)
+{
+       struct cpufreq_policy new_policy;
+       struct freq_attr **drv_attr;
+       unsigned long flags;
+       int ret = 0;
+       unsigned int j;
 
        /* prepare interface data */
-       ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, &sys_dev->kobj,
-                                  "cpufreq");
+       ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq,
+                                  &sys_dev->kobj, "cpufreq");
        if (ret)
-               goto out_driver_exit;
+               return ret;
 
        /* set up files for this cpu device */
        drv_attr = cpufreq_driver->attr;
@@ -926,35 +903,20 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
 
        spin_lock_irqsave(&cpufreq_driver_lock, flags);
        for_each_cpu(j, policy->cpus) {
-               if (!cpu_online(j))
-                       continue;
+       if (!cpu_online(j))
+               continue;
                per_cpu(cpufreq_cpu_data, j) = policy;
                per_cpu(policy_cpu, j) = policy->cpu;
        }
        spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
 
-       /* symlink affected CPUs */
-       for_each_cpu(j, policy->cpus) {
-               struct cpufreq_policy *managed_policy;
-
-               if (j == cpu)
-                       continue;
-               if (!cpu_online(j))
-                       continue;
-
-               dprintk("CPU %u already managed, adding link\n", j);
-               managed_policy = cpufreq_cpu_get(cpu);
-               cpu_sys_dev = get_cpu_sysdev(j);
-               ret = sysfs_create_link(&cpu_sys_dev->kobj, &policy->kobj,
-                                       "cpufreq");
-               if (ret) {
-                       cpufreq_cpu_put(managed_policy);
-                       goto err_out_unregister;
-               }
-       }
+       ret = cpufreq_add_dev_symlink(cpu, policy);
+       if (ret)
+               goto err_out_kobj_put;
 
-       policy->governor = NULL; /* to assure that the starting sequence is
-                                 * run in cpufreq_set_policy */
+       memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
+       /* assure that the starting sequence is run in __cpufreq_set_policy */
+       policy->governor = NULL;
 
        /* set default policy */
        ret = __cpufreq_set_policy(policy, &new_policy);
@@ -963,8 +925,107 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
 
        if (ret) {
                dprintk("setting policy failed\n");
-               goto err_out_unregister;
+               if (cpufreq_driver->exit)
+                       cpufreq_driver->exit(policy);
+       }
+       return ret;
+
+err_out_kobj_put:
+       kobject_put(&policy->kobj);
+       wait_for_completion(&policy->kobj_unregister);
+       return ret;
+}
+
+
+/**
+ * cpufreq_add_dev - add a CPU device
+ *
+ * Adds the cpufreq interface for a CPU device.
+ *
+ * The Oracle says: try running cpufreq registration/unregistration concurrently
+ * with with cpu hotplugging and all hell will break loose. Tried to clean this
+ * mess up, but more thorough testing is needed. - Mathieu
+ */
+static int cpufreq_add_dev(struct sys_device *sys_dev)
+{
+       unsigned int cpu = sys_dev->id;
+       int ret = 0;
+       struct cpufreq_policy *policy;
+       unsigned long flags;
+       unsigned int j;
+
+       if (cpu_is_offline(cpu))
+               return 0;
+
+       cpufreq_debug_disable_ratelimit();
+       dprintk("adding CPU %u\n", cpu);
+
+#ifdef CONFIG_SMP
+       /* check whether a different CPU already registered this
+        * CPU because it is in the same boat. */
+       policy = cpufreq_cpu_get(cpu);
+       if (unlikely(policy)) {
+               cpufreq_cpu_put(policy);
+               cpufreq_debug_enable_ratelimit();
+               return 0;
+       }
+#endif
+
+       if (!try_module_get(cpufreq_driver->owner)) {
+               ret = -EINVAL;
+               goto module_out;
+       }
+
+       ret = -ENOMEM;
+       policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
+       if (!policy)
+               goto nomem_out;
+
+       if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL))
+               goto err_free_policy;
+
+       if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL))
+               goto err_free_cpumask;
+
+       policy->cpu = cpu;
+       cpumask_copy(policy->cpus, cpumask_of(cpu));
+
+       /* Initially set CPU itself as the policy_cpu */
+       per_cpu(policy_cpu, cpu) = cpu;
+       ret = (lock_policy_rwsem_write(cpu) < 0);
+       WARN_ON(ret);
+
+       init_completion(&policy->kobj_unregister);
+       INIT_WORK(&policy->update, handle_update);
+
+       /* Set governor before ->init, so that driver could check it */
+       policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+       /* call driver. From then on the cpufreq must be able
+        * to accept all calls to ->verify and ->setpolicy for this CPU
+        */
+       ret = cpufreq_driver->init(policy);
+       if (ret) {
+               dprintk("initialization failed\n");
+               goto err_unlock_policy;
        }
+       policy->user_policy.min = policy->min;
+       policy->user_policy.max = policy->max;
+
+       blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
+                                    CPUFREQ_START, policy);
+
+       ret = cpufreq_add_dev_policy(cpu, policy, sys_dev);
+       if (ret) {
+               if (ret > 0)
+                       /* This is a managed cpu, symlink created,
+                          exit with 0 */
+                       ret = 0;
+               goto err_unlock_policy;
+       }
+
+       ret = cpufreq_add_dev_interface(cpu, policy, sys_dev);
+       if (ret)
+               goto err_out_unregister;
 
        unlock_policy_rwsem_write(cpu);
 
@@ -982,14 +1043,9 @@ err_out_unregister:
                per_cpu(cpufreq_cpu_data, j) = NULL;
        spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
 
-err_out_kobj_put:
        kobject_put(&policy->kobj);
        wait_for_completion(&policy->kobj_unregister);
 
-out_driver_exit:
-       if (cpufreq_driver->exit)
-               cpufreq_driver->exit(policy);
-
 err_unlock_policy:
        unlock_policy_rwsem_write(cpu);
 err_free_cpumask:
@@ -1653,8 +1709,17 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data,
                        dprintk("governor switch\n");
 
                        /* end old governor */
-                       if (data->governor)
+                       if (data->governor) {
+                               /*
+                                * Need to release the rwsem around governor
+                                * stop due to lock dependency between
+                                * cancel_delayed_work_sync and the read lock
+                                * taken in the delayed work handler.
+                                */
+                               unlock_policy_rwsem_write(data->cpu);
                                __cpufreq_governor(data, CPUFREQ_GOV_STOP);
+                               lock_policy_rwsem_write(data->cpu);
+                       }
 
                        /* start new governor */
                        data->governor = policy->governor;
@@ -1884,7 +1949,11 @@ static int __init cpufreq_core_init(void)
                per_cpu(policy_cpu, cpu) = -1;
                init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
        }
+
+       cpufreq_global_kobject = kobject_create_and_add("cpufreq",
+                                               &cpu_sysdev_class.kset.kobj);
+       BUG_ON(!cpufreq_global_kobject);
+
        return 0;
 }
-
 core_initcall(cpufreq_core_init);
index d7a528c80de87f3280b344d3ea9f09ed37b3b673..071699de50eef68a56e586224ccbe1d07e319011 100644 (file)
@@ -55,6 +55,18 @@ static unsigned int min_sampling_rate;
 #define TRANSITION_LATENCY_LIMIT               (10 * 1000 * 1000)
 
 static void do_dbs_timer(struct work_struct *work);
+static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
+                               unsigned int event);
+
+#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND
+static
+#endif
+struct cpufreq_governor cpufreq_gov_ondemand = {
+       .name                   = "ondemand",
+       .governor               = cpufreq_governor_dbs,
+       .max_transition_latency = TRANSITION_LATENCY_LIMIT,
+       .owner                  = THIS_MODULE,
+};
 
 /* Sampling types */
 enum {DBS_NORMAL_SAMPLE, DBS_SUB_SAMPLE};
@@ -207,20 +219,23 @@ static void ondemand_powersave_bias_init(void)
 }
 
 /************************** sysfs interface ************************/
-static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf)
+
+static ssize_t show_sampling_rate_max(struct kobject *kobj,
+                                     struct attribute *attr, char *buf)
 {
        printk_once(KERN_INFO "CPUFREQ: ondemand sampling_rate_max "
               "sysfs file is deprecated - used by: %s\n", current->comm);
        return sprintf(buf, "%u\n", -1U);
 }
 
-static ssize_t show_sampling_rate_min(struct cpufreq_policy *policy, char *buf)
+static ssize_t show_sampling_rate_min(struct kobject *kobj,
+                                     struct attribute *attr, char *buf)
 {
        return sprintf(buf, "%u\n", min_sampling_rate);
 }
 
 #define define_one_ro(_name)           \
-static struct freq_attr _name =                \
+static struct global_attr _name =      \
 __ATTR(_name, 0444, show_##_name, NULL)
 
 define_one_ro(sampling_rate_max);
@@ -229,7 +244,7 @@ define_one_ro(sampling_rate_min);
 /* cpufreq_ondemand Governor Tunables */
 #define show_one(file_name, object)                                    \
 static ssize_t show_##file_name                                                \
-(struct cpufreq_policy *unused, char *buf)                             \
+(struct kobject *kobj, struct attribute *attr, char *buf)              \
 {                                                                      \
        return sprintf(buf, "%u\n", dbs_tuners_ins.object);             \
 }
@@ -238,8 +253,38 @@ show_one(up_threshold, up_threshold);
 show_one(ignore_nice_load, ignore_nice);
 show_one(powersave_bias, powersave_bias);
 
-static ssize_t store_sampling_rate(struct cpufreq_policy *unused,
-               const char *buf, size_t count)
+/*** delete after deprecation time ***/
+
+#define DEPRECATION_MSG(file_name)                                     \
+       printk_once(KERN_INFO "CPUFREQ: Per core ondemand sysfs "       \
+                   "interface is deprecated - " #file_name "\n");
+
+#define show_one_old(file_name)                                                \
+static ssize_t show_##file_name##_old                                  \
+(struct cpufreq_policy *unused, char *buf)                             \
+{                                                                      \
+       printk_once(KERN_INFO "CPUFREQ: Per core ondemand sysfs "       \
+                   "interface is deprecated - " #file_name "\n");      \
+       return show_##file_name(NULL, NULL, buf);                       \
+}
+show_one_old(sampling_rate);
+show_one_old(up_threshold);
+show_one_old(ignore_nice_load);
+show_one_old(powersave_bias);
+show_one_old(sampling_rate_min);
+show_one_old(sampling_rate_max);
+
+#define define_one_ro_old(object, _name)       \
+static struct freq_attr object =               \
+__ATTR(_name, 0444, show_##_name##_old, NULL)
+
+define_one_ro_old(sampling_rate_min_old, sampling_rate_min);
+define_one_ro_old(sampling_rate_max_old, sampling_rate_max);
+
+/*** delete after deprecation time ***/
+
+static ssize_t store_sampling_rate(struct kobject *a, struct attribute *b,
+                                  const char *buf, size_t count)
 {
        unsigned int input;
        int ret;
@@ -254,8 +299,8 @@ static ssize_t store_sampling_rate(struct cpufreq_policy *unused,
        return count;
 }
 
-static ssize_t store_up_threshold(struct cpufreq_policy *unused,
-               const char *buf, size_t count)
+static ssize_t store_up_threshold(struct kobject *a, struct attribute *b,
+                                 const char *buf, size_t count)
 {
        unsigned int input;
        int ret;
@@ -273,8 +318,8 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused,
        return count;
 }
 
-static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
-               const char *buf, size_t count)
+static ssize_t store_ignore_nice_load(struct kobject *a, struct attribute *b,
+                                     const char *buf, size_t count)
 {
        unsigned int input;
        int ret;
@@ -310,8 +355,8 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
        return count;
 }
 
-static ssize_t store_powersave_bias(struct cpufreq_policy *unused,
-               const char *buf, size_t count)
+static ssize_t store_powersave_bias(struct kobject *a, struct attribute *b,
+                                   const char *buf, size_t count)
 {
        unsigned int input;
        int ret;
@@ -332,7 +377,7 @@ static ssize_t store_powersave_bias(struct cpufreq_policy *unused,
 }
 
 #define define_one_rw(_name) \
-static struct freq_attr _name = \
+static struct global_attr _name = \
 __ATTR(_name, 0644, show_##_name, store_##_name)
 
 define_one_rw(sampling_rate);
@@ -355,6 +400,47 @@ static struct attribute_group dbs_attr_group = {
        .name = "ondemand",
 };
 
+/*** delete after deprecation time ***/
+
+#define write_one_old(file_name)                                       \
+static ssize_t store_##file_name##_old                                 \
+(struct cpufreq_policy *unused, const char *buf, size_t count)         \
+{                                                                      \
+       printk_once(KERN_INFO "CPUFREQ: Per core ondemand sysfs "       \
+                  "interface is deprecated - " #file_name "\n");       \
+       return store_##file_name(NULL, NULL, buf, count);               \
+}
+write_one_old(sampling_rate);
+write_one_old(up_threshold);
+write_one_old(ignore_nice_load);
+write_one_old(powersave_bias);
+
+#define define_one_rw_old(object, _name)       \
+static struct freq_attr object =               \
+__ATTR(_name, 0644, show_##_name##_old, store_##_name##_old)
+
+define_one_rw_old(sampling_rate_old, sampling_rate);
+define_one_rw_old(up_threshold_old, up_threshold);
+define_one_rw_old(ignore_nice_load_old, ignore_nice_load);
+define_one_rw_old(powersave_bias_old, powersave_bias);
+
+static struct attribute *dbs_attributes_old[] = {
+       &sampling_rate_max_old.attr,
+       &sampling_rate_min_old.attr,
+       &sampling_rate_old.attr,
+       &up_threshold_old.attr,
+       &ignore_nice_load_old.attr,
+       &powersave_bias_old.attr,
+       NULL
+};
+
+static struct attribute_group dbs_attr_group_old = {
+       .attrs = dbs_attributes_old,
+       .name = "ondemand",
+};
+
+/*** delete after deprecation time ***/
+
 /************************** sysfs end ************************/
 
 static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
@@ -545,7 +631,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
 
                mutex_lock(&dbs_mutex);
 
-               rc = sysfs_create_group(&policy->kobj, &dbs_attr_group);
+               rc = sysfs_create_group(&policy->kobj, &dbs_attr_group_old);
                if (rc) {
                        mutex_unlock(&dbs_mutex);
                        return rc;
@@ -566,13 +652,20 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
                }
                this_dbs_info->cpu = cpu;
                ondemand_powersave_bias_init_cpu(cpu);
-               mutex_init(&this_dbs_info->timer_mutex);
                /*
                 * Start the timerschedule work, when this governor
                 * is used for first time
                 */
                if (dbs_enable == 1) {
                        unsigned int latency;
+
+                       rc = sysfs_create_group(cpufreq_global_kobject,
+                                               &dbs_attr_group);
+                       if (rc) {
+                               mutex_unlock(&dbs_mutex);
+                               return rc;
+                       }
+
                        /* policy latency is in nS. Convert it to uS first */
                        latency = policy->cpuinfo.transition_latency / 1000;
                        if (latency == 0)
@@ -586,6 +679,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
                }
                mutex_unlock(&dbs_mutex);
 
+               mutex_init(&this_dbs_info->timer_mutex);
                dbs_timer_init(this_dbs_info);
                break;
 
@@ -593,10 +687,13 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
                dbs_timer_exit(this_dbs_info);
 
                mutex_lock(&dbs_mutex);
-               sysfs_remove_group(&policy->kobj, &dbs_attr_group);
+               sysfs_remove_group(&policy->kobj, &dbs_attr_group_old);
                mutex_destroy(&this_dbs_info->timer_mutex);
                dbs_enable--;
                mutex_unlock(&dbs_mutex);
+               if (!dbs_enable)
+                       sysfs_remove_group(cpufreq_global_kobject,
+                                          &dbs_attr_group);
 
                break;
 
@@ -614,16 +711,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
        return 0;
 }
 
-#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND
-static
-#endif
-struct cpufreq_governor cpufreq_gov_ondemand = {
-       .name                   = "ondemand",
-       .governor               = cpufreq_governor_dbs,
-       .max_transition_latency = TRANSITION_LATENCY_LIMIT,
-       .owner                  = THIS_MODULE,
-};
-
 static int __init cpufreq_gov_dbs_init(void)
 {
        int err;
index 4339b1a879cdb3ea1c6c3f5a570902c9769ac464..a3ca18e2d7cfe76d285cb5aa728ff9a709def563 100644 (file)
@@ -59,7 +59,7 @@ config EDAC_MM_EDAC
 
 config EDAC_AMD64
        tristate "AMD64 (Opteron, Athlon64) K8, F10h, F11h"
-       depends on EDAC_MM_EDAC && K8_NB && X86_64 && PCI
+       depends on EDAC_MM_EDAC && K8_NB && X86_64 && PCI && CPU_SUP_AMD
        help
          Support for error detection and correction on the AMD 64
          Families of Memory Controllers (K8, F10h and F11h)
index 173dc4a8416616a97c004ebe48f2f8ef77ece31e..4e551e63b6dc5fffd25c80b53b61e66a646772bf 100644 (file)
@@ -1255,7 +1255,9 @@ static int k8_dbam_map_to_pages(struct amd64_pvt *pvt, int dram_map)
  */
 static int f10_early_channel_count(struct amd64_pvt *pvt)
 {
+       int dbams[] = { DBAM0, DBAM1 };
        int err = 0, channels = 0;
+       int i, j;
        u32 dbam;
 
        err = pci_read_config_dword(pvt->dram_f2_ctl, F10_DCLR_0, &pvt->dclr0);
@@ -1288,46 +1290,19 @@ static int f10_early_channel_count(struct amd64_pvt *pvt)
         * is more than just one DIMM present in unganged mode. Need to check
         * both controllers since DIMMs can be placed in either one.
         */
-       channels = 0;
-       err = pci_read_config_dword(pvt->dram_f2_ctl, DBAM0, &dbam);
-       if (err)
-               goto err_reg;
-
-       if (DBAM_DIMM(0, dbam) > 0)
-               channels++;
-       if (DBAM_DIMM(1, dbam) > 0)
-               channels++;
-       if (DBAM_DIMM(2, dbam) > 0)
-               channels++;
-       if (DBAM_DIMM(3, dbam) > 0)
-               channels++;
-
-       /* If more than 2 DIMMs are present, then we have 2 channels */
-       if (channels > 2)
-               channels = 2;
-       else if (channels == 0) {
-               /* No DIMMs on DCT0, so look at DCT1 */
-               err = pci_read_config_dword(pvt->dram_f2_ctl, DBAM1, &dbam);
+       for (i = 0; i < ARRAY_SIZE(dbams); i++) {
+               err = pci_read_config_dword(pvt->dram_f2_ctl, dbams[i], &dbam);
                if (err)
                        goto err_reg;
 
-               if (DBAM_DIMM(0, dbam) > 0)
-                       channels++;
-               if (DBAM_DIMM(1, dbam) > 0)
-                       channels++;
-               if (DBAM_DIMM(2, dbam) > 0)
-                       channels++;
-               if (DBAM_DIMM(3, dbam) > 0)
-                       channels++;
-
-               if (channels > 2)
-                       channels = 2;
+               for (j = 0; j < 4; j++) {
+                       if (DBAM_DIMM(j, dbam) > 0) {
+                               channels++;
+                               break;
+                       }
+               }
        }
 
-       /* If we found ALL 0 values, then assume just ONE DIMM-ONE Channel */
-       if (channels == 0)
-               channels = 1;
-
        debugf0("MCT channel count: %d\n", channels);
 
        return channels;
@@ -2766,30 +2741,53 @@ static void amd64_restore_ecc_error_reporting(struct amd64_pvt *pvt)
        wrmsr_on_cpus(cpumask, K8_MSR_MCGCTL, msrs);
 }
 
-static void check_mcg_ctl(void *ret)
+/* get all cores on this DCT */
+static void get_cpus_on_this_dct_cpumask(cpumask_t *mask, int nid)
 {
-       u64 msr_val = 0;
-       u8 nbe;
-
-       rdmsrl(MSR_IA32_MCG_CTL, msr_val);
-       nbe = msr_val & K8_MSR_MCGCTL_NBE;
-
-       debugf0("core: %u, MCG_CTL: 0x%llx, NB MSR is %s\n",
-               raw_smp_processor_id(), msr_val,
-               (nbe ? "enabled" : "disabled"));
+       int cpu;
 
-       if (!nbe)
-               *(int *)ret = 0;
+       for_each_online_cpu(cpu)
+               if (amd_get_nb_id(cpu) == nid)
+                       cpumask_set_cpu(cpu, mask);
 }
 
 /* check MCG_CTL on all the cpus on this node */
-static int amd64_mcg_ctl_enabled_on_cpus(const cpumask_t *mask)
+static bool amd64_nb_mce_bank_enabled_on_node(int nid)
 {
-       int ret = 1;
-       preempt_disable();
-       smp_call_function_many(mask, check_mcg_ctl, &ret, 1);
-       preempt_enable();
+       cpumask_t mask;
+       struct msr *msrs;
+       int cpu, nbe, idx = 0;
+       bool ret = false;
 
+       cpumask_clear(&mask);
+
+       get_cpus_on_this_dct_cpumask(&mask, nid);
+
+       msrs = kzalloc(sizeof(struct msr) * cpumask_weight(&mask), GFP_KERNEL);
+       if (!msrs) {
+               amd64_printk(KERN_WARNING, "%s: error allocating msrs\n",
+                             __func__);
+                return false;
+       }
+
+       rdmsr_on_cpus(&mask, MSR_IA32_MCG_CTL, msrs);
+
+       for_each_cpu(cpu, &mask) {
+               nbe = msrs[idx].l & K8_MSR_MCGCTL_NBE;
+
+               debugf0("core: %u, MCG_CTL: 0x%llx, NB MSR is %s\n",
+                       cpu, msrs[idx].q,
+                       (nbe ? "enabled" : "disabled"));
+
+               if (!nbe)
+                       goto out;
+
+               idx++;
+       }
+       ret = true;
+
+out:
+       kfree(msrs);
        return ret;
 }
 
@@ -2799,71 +2797,46 @@ static int amd64_mcg_ctl_enabled_on_cpus(const cpumask_t *mask)
  * the memory system completely. A command line option allows to force-enable
  * hardware ECC later in amd64_enable_ecc_error_reporting().
  */
+static const char *ecc_warning =
+       "WARNING: ECC is disabled by BIOS. Module will NOT be loaded.\n"
+       " Either Enable ECC in the BIOS, or set 'ecc_enable_override'.\n"
+       " Also, use of the override can cause unknown side effects.\n";
+
 static int amd64_check_ecc_enabled(struct amd64_pvt *pvt)
 {
        u32 value;
-       int err = 0, ret = 0;
+       int err = 0;
        u8 ecc_enabled = 0;
+       bool nb_mce_en = false;
 
        err = pci_read_config_dword(pvt->misc_f3_ctl, K8_NBCFG, &value);
        if (err)
                debugf0("Reading K8_NBCTL failed\n");
 
        ecc_enabled = !!(value & K8_NBCFG_ECC_ENABLE);
+       if (!ecc_enabled)
+               amd64_printk(KERN_WARNING, "This node reports that Memory ECC "
+                            "is currently disabled, set F3x%x[22] (%s).\n",
+                            K8_NBCFG, pci_name(pvt->misc_f3_ctl));
+       else
+               amd64_printk(KERN_INFO, "ECC is enabled by BIOS.\n");
 
-       ret = amd64_mcg_ctl_enabled_on_cpus(cpumask_of_node(pvt->mc_node_id));
-
-       debugf0("K8_NBCFG=0x%x,  DRAM ECC is %s\n", value,
-                       (value & K8_NBCFG_ECC_ENABLE ? "enabled" : "disabled"));
-
-       if (!ecc_enabled || !ret) {
-               if (!ecc_enabled) {
-                       amd64_printk(KERN_WARNING, "This node reports that "
-                                                  "Memory ECC is currently "
-                                                  "disabled.\n");
+       nb_mce_en = amd64_nb_mce_bank_enabled_on_node(pvt->mc_node_id);
+       if (!nb_mce_en)
+               amd64_printk(KERN_WARNING, "NB MCE bank disabled, set MSR "
+                            "0x%08x[4] on node %d to enable.\n",
+                            MSR_IA32_MCG_CTL, pvt->mc_node_id);
 
-                       amd64_printk(KERN_WARNING, "bit 0x%lx in register "
-                               "F3x%x of the MISC_CONTROL device (%s) "
-                               "should be enabled\n", K8_NBCFG_ECC_ENABLE,
-                               K8_NBCFG, pci_name(pvt->misc_f3_ctl));
-               }
-               if (!ret) {
-                       amd64_printk(KERN_WARNING, "bit 0x%016lx in MSR 0x%08x "
-                                       "of node %d should be enabled\n",
-                                       K8_MSR_MCGCTL_NBE, MSR_IA32_MCG_CTL,
-                                       pvt->mc_node_id);
-               }
+       if (!ecc_enabled || !nb_mce_en) {
                if (!ecc_enable_override) {
-                       amd64_printk(KERN_WARNING, "WARNING: ECC is NOT "
-                               "currently enabled by the BIOS. Module "
-                               "will NOT be loaded.\n"
-                               "    Either Enable ECC in the BIOS, "
-                               "or use the 'ecc_enable_override' "
-                               "parameter.\n"
-                               "    Might be a BIOS bug, if BIOS says "
-                               "ECC is enabled\n"
-                               "    Use of the override can cause "
-                               "unknown side effects.\n");
-                       ret = -ENODEV;
-               } else
-                       /*
-                        * enable further driver loading if ECC enable is
-                        * overridden.
-                        */
-                       ret = 0;
-       } else {
-               amd64_printk(KERN_INFO,
-                       "ECC is enabled by BIOS, Proceeding "
-                       "with EDAC module initialization\n");
-
-               /* Signal good ECC status */
-               ret = 0;
-
+                       amd64_printk(KERN_WARNING, "%s", ecc_warning);
+                       return -ENODEV;
+               }
+       } else
                /* CLEAR the override, since BIOS controlled it */
                ecc_enable_override = 0;
-       }
 
-       return ret;
+       return 0;
 }
 
 struct mcidev_sysfs_attribute sysfs_attrs[ARRAY_SIZE(amd64_dbg_attrs) +
index c8ca7136daccb1edf6d43967d95439942c4488da..0c21c370c9dd001c2da04e1c914c5248708f219e 100644 (file)
@@ -405,7 +405,7 @@ void decode_mce(struct mce *m)
                regs.nbsh  = (u32)(m->status >> 32);
                regs.nbeal = (u32) m->addr;
                regs.nbeah = (u32)(m->addr >> 32);
-               node       = per_cpu(cpu_llc_id, m->extcpu);
+               node       = amd_get_nb_id(m->extcpu);
 
                amd_decode_nb_mce(node, &regs, 1);
                break;
index 2e25b7a827d396d1357646066b711ad8550ea287..461abb1e273ad08b196c8a4bbdd2e3d059ff8fae 100644 (file)
@@ -28,6 +28,17 @@ config HWMON_VID
        tristate
        default n
 
+config HWMON_DEBUG_CHIP
+       bool "Hardware Monitoring Chip debugging messages"
+       default n
+       help
+         Say Y here if you want the I2C chip drivers to produce a bunch of
+         debug messages to the system log.  Select this if you are having
+         a problem with I2C support and want to see more of what is going
+         on.
+
+comment "Native drivers"
+
 config SENSORS_ABITUGURU
        tristate "Abit uGuru (rev 1 & 2)"
        depends on X86 && EXPERIMENTAL
@@ -248,18 +259,6 @@ config SENSORS_ASB100
          This driver can also be built as a module.  If so, the module
          will be called asb100.
 
-config SENSORS_ATK0110
-       tristate "ASUS ATK0110 ACPI hwmon"
-       depends on X86 && ACPI && EXPERIMENTAL
-       help
-         If you say yes here you get support for the ACPI hardware
-         monitoring interface found in many ASUS motherboards. This
-         driver will provide readings of fans, voltages and temperatures
-         through the system firmware.
-
-         This driver can also be built as a module. If so, the module
-         will be called asus_atk0110.
-
 config SENSORS_ATXP1
        tristate "Attansic ATXP1 VID controller"
        depends on I2C && EXPERIMENTAL
@@ -814,6 +813,16 @@ config SENSORS_TMP401
          This driver can also be built as a module.  If so, the module
          will be called tmp401.
 
+config SENSORS_TMP421
+       tristate "Texas Instruments TMP421 and compatible"
+       depends on I2C && EXPERIMENTAL
+       help
+         If you say yes here you get support for Texas Instruments TMP421,
+         TMP422 and TMP423 temperature sensor chips.
+
+         This driver can also be built as a module.  If so, the module
+         will be called tmp421.
+
 config SENSORS_VIA686A
        tristate "VIA686A"
        depends on PCI
@@ -964,34 +973,6 @@ config SENSORS_HDAPS
          Say Y here if you have an applicable laptop and want to experience
          the awesome power of hdaps.
 
-config SENSORS_LIS3LV02D
-       tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer"
-       depends on ACPI && INPUT
-       select INPUT_POLLDEV
-       select NEW_LEDS
-       select LEDS_CLASS
-       default n
-       help
-         This driver provides support for the LIS3LV02Dx accelerometer. In
-         particular, it can be found in a number of HP laptops, which have the
-         "Mobile Data Protection System 3D" or "3D DriveGuard" feature. On such
-         systems the driver should load automatically (via ACPI). The
-         accelerometer might also be found in other systems, connected via SPI
-         or I2C.  The accelerometer data is readable via
-         /sys/devices/platform/lis3lv02d.
-
-         This driver also provides an absolute input class device, allowing
-         the laptop to act as a pinball machine-esque joystick. On HP laptops,
-         if the led infrastructure is activated, support for a led indicating
-         disk protection will be provided as hp:red:hddprotection.
-
-         This driver can also be built as modules.  If so, the core module
-         will be called lis3lv02d and a specific module for HP laptops will be
-         called hp_accel.
-
-         Say Y here if you have an applicable laptop and want to experience
-         the awesome power of lis3lv02d.
-
 config SENSORS_LIS3_SPI
        tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer (SPI)"
        depends on !ACPI && SPI_MASTER && INPUT
@@ -1034,13 +1015,50 @@ config SENSORS_APPLESMC
          Say Y here if you have an applicable laptop and want to experience
          the awesome power of applesmc.
 
-config HWMON_DEBUG_CHIP
-       bool "Hardware Monitoring Chip debugging messages"
+if ACPI
+
+comment "ACPI drivers"
+
+config SENSORS_ATK0110
+       tristate "ASUS ATK0110"
+       depends on X86 && EXPERIMENTAL
+       help
+         If you say yes here you get support for the ACPI hardware
+         monitoring interface found in many ASUS motherboards. This
+         driver will provide readings of fans, voltages and temperatures
+         through the system firmware.
+
+         This driver can also be built as a module. If so, the module
+         will be called asus_atk0110.
+
+config SENSORS_LIS3LV02D
+       tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer"
+       depends on INPUT
+       select INPUT_POLLDEV
+       select NEW_LEDS
+       select LEDS_CLASS
        default n
        help
-         Say Y here if you want the I2C chip drivers to produce a bunch of
-         debug messages to the system log.  Select this if you are having
-         a problem with I2C support and want to see more of what is going
-         on.
+         This driver provides support for the LIS3LV02Dx accelerometer. In
+         particular, it can be found in a number of HP laptops, which have the
+         "Mobile Data Protection System 3D" or "3D DriveGuard" feature. On such
+         systems the driver should load automatically (via ACPI). The
+         accelerometer might also be found in other systems, connected via SPI
+         or I2C.  The accelerometer data is readable via
+         /sys/devices/platform/lis3lv02d.
+
+         This driver also provides an absolute input class device, allowing
+         the laptop to act as a pinball machine-esque joystick. On HP laptops,
+         if the led infrastructure is activated, support for a led indicating
+         disk protection will be provided as hp:red:hddprotection.
+
+         This driver can also be built as modules.  If so, the core module
+         will be called lis3lv02d and a specific module for HP laptops will be
+         called hp_accel.
+
+         Say Y here if you have an applicable laptop and want to experience
+         the awesome power of lis3lv02d.
+
+endif # ACPI
 
 endif # HWMON
index 7f239a247c336614f88f5ccaa77eb6d2ccc7cf33..2e547881bc0a34769755a91096f45a042d6c9764 100644 (file)
@@ -5,6 +5,10 @@
 obj-$(CONFIG_HWMON)            += hwmon.o
 obj-$(CONFIG_HWMON_VID)                += hwmon-vid.o
 
+# APCI drivers
+obj-$(CONFIG_SENSORS_ATK0110)  += asus_atk0110.o
+
+# Native drivers
 # asb100, then w83781d go first, as they can override other drivers' addresses.
 obj-$(CONFIG_SENSORS_ASB100)   += asb100.o
 obj-$(CONFIG_SENSORS_W83627HF) += w83627hf.o
@@ -29,10 +33,8 @@ obj-$(CONFIG_SENSORS_ADT7462)        += adt7462.o
 obj-$(CONFIG_SENSORS_ADT7470)  += adt7470.o
 obj-$(CONFIG_SENSORS_ADT7473)  += adt7473.o
 obj-$(CONFIG_SENSORS_ADT7475)  += adt7475.o
-
 obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o
 obj-$(CONFIG_SENSORS_AMS)      += ams/
-obj-$(CONFIG_SENSORS_ATK0110)  += asus_atk0110.o
 obj-$(CONFIG_SENSORS_ATXP1)    += atxp1.o
 obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o
 obj-$(CONFIG_SENSORS_DME1737)  += dme1737.o
@@ -84,6 +86,7 @@ obj-$(CONFIG_SENSORS_SMSC47M1)        += smsc47m1.o
 obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o
 obj-$(CONFIG_SENSORS_THMC50)   += thmc50.o
 obj-$(CONFIG_SENSORS_TMP401)   += tmp401.o
+obj-$(CONFIG_SENSORS_TMP421)   += tmp421.o
 obj-$(CONFIG_SENSORS_VIA686A)  += via686a.o
 obj-$(CONFIG_SENSORS_VT1211)   += vt1211.o
 obj-$(CONFIG_SENSORS_VT8231)   += vt8231.o
index 4dbdb81ea3b1bfffce5d016746409ef7a3fe7f1d..03694cc17a32e20e2d64b7f402b5fcaa9989e5fd 100644 (file)
@@ -32,7 +32,7 @@
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 #include <linux/dmi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 /* Banks */
 #define ABIT_UGURU_ALARM_BANK                  0x20 /* 1x 3 bytes */
index 7d3f15d32fdfee8c1829d0f985cbb46331e7fbfa..3cf28af614b55cd894e7318c73b5d21ec3a27e27 100644 (file)
@@ -34,7 +34,7 @@
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 #include <linux/dmi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 /* uGuru3 bank addresses */
 #define ABIT_UGURU3_SETTINGS_BANK              0x01
@@ -117,9 +117,12 @@ struct abituguru3_sensor_info {
        int offset;
 };
 
+/* Avoid use of flexible array members */
+#define ABIT_UGURU3_MAX_DMI_NAMES 2
+
 struct abituguru3_motherboard_info {
        u16 id;
-       const char *dmi_name;
+       const char *dmi_name[ABIT_UGURU3_MAX_DMI_NAMES + 1];
        /* + 1 -> end of sensors indicated by a sensor with name == NULL */
        struct abituguru3_sensor_info sensors[ABIT_UGURU3_MAX_NO_SENSORS + 1];
 };
@@ -164,7 +167,7 @@ struct abituguru3_data {
 
 /* Constants */
 static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
-       { 0x000C, NULL /* Unknown, need DMI string */, {
+       { 0x000C, { NULL } /* Unknown, need DMI string */, {
                { "CPU Core",            0, 0, 10, 1, 0 },
                { "DDR",                 1, 0, 10, 1, 0 },
                { "DDR VTT",             2, 0, 10, 1, 0 },
@@ -186,7 +189,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
                { "AUX1 Fan",           35, 2, 60, 1, 0 },
                { NULL, 0, 0, 0, 0, 0 } }
        },
-       { 0x000D, NULL /* Abit AW8, need DMI string */, {
+       { 0x000D, { NULL } /* Abit AW8, need DMI string */, {
                { "CPU Core",            0, 0, 10, 1, 0 },
                { "DDR",                 1, 0, 10, 1, 0 },
                { "DDR VTT",             2, 0, 10, 1, 0 },
@@ -215,7 +218,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
                { "AUX5 Fan",           39, 2, 60, 1, 0 },
                { NULL, 0, 0, 0, 0, 0 } }
        },
-       { 0x000E, NULL /* AL-8, need DMI string */, {
+       { 0x000E, { NULL } /* AL-8, need DMI string */, {
                { "CPU Core",            0, 0, 10, 1, 0 },
                { "DDR",                 1, 0, 10, 1, 0 },
                { "DDR VTT",             2, 0, 10, 1, 0 },
@@ -236,7 +239,8 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
                { "SYS Fan",            34, 2, 60, 1, 0 },
                { NULL, 0, 0, 0, 0, 0 } }
        },
-       { 0x000F, NULL /* Unknown, need DMI string */, {
+       { 0x000F, { NULL } /* Unknown, need DMI string */, {
+
                { "CPU Core",            0, 0, 10, 1, 0 },
                { "DDR",                 1, 0, 10, 1, 0 },
                { "DDR VTT",             2, 0, 10, 1, 0 },
@@ -257,7 +261,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
                { "SYS Fan",            34, 2, 60, 1, 0 },
                { NULL, 0, 0, 0, 0, 0 } }
        },
-       { 0x0010, NULL /* Abit NI8 SLI GR, need DMI string */, {
+       { 0x0010, { NULL } /* Abit NI8 SLI GR, need DMI string */, {
                { "CPU Core",            0, 0, 10, 1, 0 },
                { "DDR",                 1, 0, 10, 1, 0 },
                { "DDR VTT",             2, 0, 10, 1, 0 },
@@ -279,7 +283,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
                { "OTES1 Fan",          36, 2, 60, 1, 0 },
                { NULL, 0, 0, 0, 0, 0 } }
        },
-       { 0x0011, "AT8 32X", {
+       { 0x0011, { "AT8 32X", NULL }, {
                { "CPU Core",            0, 0, 10, 1, 0 },
                { "DDR",                 1, 0, 20, 1, 0 },
                { "DDR VTT",             2, 0, 10, 1, 0 },
@@ -306,7 +310,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
                { "AUX3 Fan",           37, 2, 60, 1, 0 },
                { NULL, 0, 0, 0, 0, 0 } }
        },
-       { 0x0012, NULL /* Abit AN8 32X, need DMI string */, {
+       { 0x0012, { NULL } /* Abit AN8 32X, need DMI string */, {
                { "CPU Core",            0, 0, 10, 1, 0 },
                { "DDR",                 1, 0, 20, 1, 0 },
                { "DDR VTT",             2, 0, 10, 1, 0 },
@@ -328,7 +332,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
                { "AUX1 Fan",           36, 2, 60, 1, 0 },
                { NULL, 0, 0, 0, 0, 0 } }
        },
-       { 0x0013, NULL /* Abit AW8D, need DMI string */, {
+       { 0x0013, { NULL } /* Abit AW8D, need DMI string */, {
                { "CPU Core",            0, 0, 10, 1, 0 },
                { "DDR",                 1, 0, 10, 1, 0 },
                { "DDR VTT",             2, 0, 10, 1, 0 },
@@ -357,7 +361,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
                { "AUX5 Fan",           39, 2, 60, 1, 0 },
                { NULL, 0, 0, 0, 0, 0 } }
        },
-       { 0x0014, "AB9", /* + AB9 Pro */ {
+       { 0x0014, { "AB9", "AB9 Pro", NULL }, {
                { "CPU Core",            0, 0, 10, 1, 0 },
                { "DDR",                 1, 0, 10, 1, 0 },
                { "DDR VTT",             2, 0, 10, 1, 0 },
@@ -378,7 +382,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
                { "SYS Fan",            34, 2, 60, 1, 0 },
                { NULL, 0, 0, 0, 0, 0 } }
        },
-       { 0x0015, NULL /* Unknown, need DMI string */, {
+       { 0x0015, { NULL } /* Unknown, need DMI string */, {
                { "CPU Core",            0, 0, 10, 1, 0 },
                { "DDR",                 1, 0, 20, 1, 0 },
                { "DDR VTT",             2, 0, 10, 1, 0 },
@@ -402,7 +406,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
                { "AUX3 Fan",           36, 2, 60, 1, 0 },
                { NULL, 0, 0, 0, 0, 0 } }
        },
-       { 0x0016, "AW9D-MAX", {
+       { 0x0016, { "AW9D-MAX", NULL }, {
                { "CPU Core",            0, 0, 10, 1, 0 },
                { "DDR2",                1, 0, 20, 1, 0 },
                { "DDR2 VTT",            2, 0, 10, 1, 0 },
@@ -430,7 +434,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
                { "OTES1 Fan",          38, 2, 60, 1, 0 },
                { NULL, 0, 0, 0, 0, 0 } }
        },
-       { 0x0017, NULL /* Unknown, need DMI string */, {
+       { 0x0017, { NULL } /* Unknown, need DMI string */, {
                { "CPU Core",            0, 0, 10, 1, 0 },
                { "DDR2",                1, 0, 20, 1, 0 },
                { "DDR2 VTT",            2, 0, 10, 1, 0 },
@@ -455,7 +459,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
                { "AUX3 FAN",           37, 2, 60, 1, 0 },
                { NULL, 0, 0, 0, 0, 0 } }
        },
-       { 0x0018, "AB9 QuadGT", {
+       { 0x0018, { "AB9 QuadGT", NULL }, {
                { "CPU Core",            0, 0, 10, 1, 0 },
                { "DDR2",                1, 0, 20, 1, 0 },
                { "DDR2 VTT",            2, 0, 10, 1, 0 },
@@ -482,7 +486,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
                { "AUX3 Fan",           36, 2, 60, 1, 0 },
                { NULL, 0, 0, 0, 0, 0 } }
        },
-       { 0x0019, "IN9 32X MAX", {
+       { 0x0019, { "IN9 32X MAX", NULL }, {
                { "CPU Core",            7, 0, 10, 1, 0 },
                { "DDR2",               13, 0, 20, 1, 0 },
                { "DDR2 VTT",           14, 0, 10, 1, 0 },
@@ -509,7 +513,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
                { "AUX3 FAN",           36, 2, 60, 1, 0 },
                { NULL, 0, 0, 0, 0, 0 } }
        },
-       { 0x001A, "IP35 Pro", {
+       { 0x001A, { "IP35 Pro", "IP35 Pro XE", NULL }, {
                { "CPU Core",            0, 0, 10, 1, 0 },
                { "DDR2",                1, 0, 20, 1, 0 },
                { "DDR2 VTT",            2, 0, 10, 1, 0 },
@@ -537,7 +541,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
                { "AUX4 Fan",           37, 2, 60, 1, 0 },
                { NULL, 0, 0, 0, 0, 0 } }
        },
-       { 0x001B, NULL /* Unknown, need DMI string */, {
+       { 0x001B, { NULL } /* Unknown, need DMI string */, {
                { "CPU Core",            0, 0, 10, 1, 0 },
                { "DDR3",                1, 0, 20, 1, 0 },
                { "DDR3 VTT",            2, 0, 10, 1, 0 },
@@ -564,7 +568,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
                { "AUX3 Fan",           36, 2, 60, 1, 0 },
                { NULL, 0, 0, 0, 0, 0 } }
        },
-       { 0x001C, "IX38 QuadGT", {
+       { 0x001C, { "IX38 QuadGT", NULL }, {
                { "CPU Core",            0, 0, 10, 1, 0 },
                { "DDR2",                1, 0, 20, 1, 0 },
                { "DDR2 VTT",            2, 0, 10, 1, 0 },
@@ -591,7 +595,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
                { "AUX3 Fan",           36, 2, 60, 1, 0 },
                { NULL, 0, 0, 0, 0, 0 } }
        },
-       { 0x0000, NULL, { { NULL, 0, 0, 0, 0, 0 } } }
+       { 0x0000, { NULL }, { { NULL, 0, 0, 0, 0, 0 } } }
 };
 
 
@@ -946,15 +950,6 @@ static int __devinit abituguru3_probe(struct platform_device *pdev)
        printk(KERN_INFO ABIT_UGURU3_NAME ": found Abit uGuru3, motherboard "
                "ID: %04X\n", (unsigned int)id);
 
-#ifdef CONFIG_DMI
-       if (!abituguru3_motherboards[i].dmi_name) {
-               printk(KERN_WARNING ABIT_UGURU3_NAME ": this motherboard was "
-                       "not detected using DMI. Please send the output of "
-                       "\"dmidecode\" to the abituguru3 maintainer "
-                       "(see MAINTAINERS)\n");
-       }
-#endif
-
        /* Fill the sysfs attr array */
        sysfs_attr_i = 0;
        sysfs_filename = data->sysfs_names;
@@ -1131,6 +1126,7 @@ static int __init abituguru3_dmi_detect(void)
 {
        const char *board_vendor, *board_name;
        int i, err = (force) ? 1 : -ENODEV;
+       const char *const *dmi_name;
        size_t sublen;
 
        board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
@@ -1151,17 +1147,17 @@ static int __init abituguru3_dmi_detect(void)
                sublen--;
 
        for (i = 0; abituguru3_motherboards[i].id; i++) {
-               const char *dmi_name = abituguru3_motherboards[i].dmi_name;
-               if (!dmi_name || strlen(dmi_name) != sublen)
-                       continue;
-               if (!strncasecmp(board_name, dmi_name, sublen))
-                       break;
+               dmi_name = abituguru3_motherboards[i].dmi_name;
+               for ( ; *dmi_name; dmi_name++) {
+                       if (strlen(*dmi_name) != sublen)
+                               continue;
+                       if (!strncasecmp(board_name, *dmi_name, sublen))
+                               return 0;
+               }
        }
 
-       if (!abituguru3_motherboards[i].id)
-               return 1;
-
-       return 0;
+       /* No match found */
+       return 1;
 }
 
 #else /* !CONFIG_DMI */
@@ -1221,6 +1217,13 @@ static int __init abituguru3_init(void)
                err = abituguru3_detect();
                if (err)
                        return err;
+
+#ifdef CONFIG_DMI
+               printk(KERN_WARNING ABIT_UGURU3_NAME ": this motherboard was "
+                       "not detected using DMI. Please send the output of "
+                       "\"dmidecode\" to the abituguru3 maintainer "
+                       "(see MAINTAINERS)\n");
+#endif
        }
 
        err = platform_driver_register(&abituguru3_driver);
index 678e34b01e524d9c20fbe99b8c5473e1135a40db..753b34885f9da3caaa71723e8f3fe3765058d4ed 100644 (file)
@@ -35,7 +35,7 @@
 #include <linux/dmi.h>
 #include <linux/mutex.h>
 #include <linux/hwmon-sysfs.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/leds.h>
 #include <linux/hwmon.h>
 #include <linux/workqueue.h>
index 3df202a9ad723737ef89e148f9f9ff25f6691b84..9814d51b3af42893b607a5106b2e4030b3b87ecf 100644 (file)
@@ -35,7 +35,7 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 /* ISA device, if found */
 static struct platform_device *pdev;
index 89987657925361fa108a762993286ac2ba6a8788..525a00bd70b1c457c25a831e3017bf8d7b1afba4 100644 (file)
@@ -40,7 +40,7 @@
 #include <linux/sysfs.h>
 #include <linux/ioport.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 static unsigned short force_id;
 module_param(force_id, ushort, 0);
index d3612a1f198135d1a719428fc5f77e417674e671..be2d131e405c669f405d0b963c5704feec4b014a 100644 (file)
@@ -35,8 +35,7 @@
 #include <linux/timer.h>
 #include <linux/dmi.h>
 #include <linux/jiffies.h>
-
-#include <asm/io.h>
+#include <linux/io.h>
 
 #define HDAPS_LOW_PORT         0x1600  /* first port used by hdaps */
 #define HDAPS_NR_PORTS         0x30    /* number of ports: 0x1600 - 0x162f */
index bfc296145bba359572b5ed7f8b8fa7da23ec0773..bf0862a803c0555f68342eabd5d3a37c5c5d46dd 100644 (file)
@@ -179,8 +179,14 @@ struct vrm_model {
 static struct vrm_model vrm_models[] = {
        {X86_VENDOR_AMD, 0x6, ANY, ANY, 90},            /* Athlon Duron etc */
        {X86_VENDOR_AMD, 0xF, 0x3F, ANY, 24},           /* Athlon 64, Opteron */
-       {X86_VENDOR_AMD, 0xF, ANY, ANY, 25},            /* NPT family 0Fh */
+       /* In theory, all NPT family 0Fh processors have 6 VID pins and should
+          thus use vrm 25, however in practice not all mainboards route the
+          6th VID pin because it is never needed. So we use the 5 VID pin
+          variant (vrm 24) for the models which exist today. */
+       {X86_VENDOR_AMD, 0xF, 0x7F, ANY, 24},           /* NPT family 0Fh */
+       {X86_VENDOR_AMD, 0xF, ANY, ANY, 25},            /* future fam. 0Fh */
        {X86_VENDOR_AMD, 0x10, ANY, ANY, 25},           /* NPT family 10h */
+
        {X86_VENDOR_INTEL, 0x6, 0x9, ANY, 13},          /* Pentium M (130 nm) */
        {X86_VENDOR_INTEL, 0x6, 0xB, ANY, 85},          /* Tualatin */
        {X86_VENDOR_INTEL, 0x6, 0xD, ANY, 13},          /* Pentium M (90 nm) */
@@ -191,12 +197,14 @@ static struct vrm_model vrm_models[] = {
        {X86_VENDOR_INTEL, 0xF, 0x1, ANY, 90},          /* P4 Willamette */
        {X86_VENDOR_INTEL, 0xF, 0x2, ANY, 90},          /* P4 Northwood */
        {X86_VENDOR_INTEL, 0xF, ANY, ANY, 100},         /* Prescott and above assume VRD 10 */
+
        {X86_VENDOR_CENTAUR, 0x6, 0x7, ANY, 85},        /* Eden ESP/Ezra */
        {X86_VENDOR_CENTAUR, 0x6, 0x8, 0x7, 85},        /* Ezra T */
        {X86_VENDOR_CENTAUR, 0x6, 0x9, 0x7, 85},        /* Nemiah */
        {X86_VENDOR_CENTAUR, 0x6, 0x9, ANY, 17},        /* C3-M, Eden-N */
        {X86_VENDOR_CENTAUR, 0x6, 0xA, 0x7, 0},         /* No information */
        {X86_VENDOR_CENTAUR, 0x6, 0xA, ANY, 13},        /* C7, Esther */
+
        {X86_VENDOR_UNKNOWN, ANY, ANY, ANY, 0}          /* stop here */
 };
 
index 9157247fed8e6062877c4428571bb75385e2227b..ffeb2a10e1a76c59f090e6d8082a7a089a96f502 100644 (file)
@@ -50,7 +50,7 @@
 #include <linux/string.h>
 #include <linux/dmi.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 #define DRVNAME "it87"
 
index a1787fdf5b9f7a94d2578de6e2e710a6da0f372a..f7e70163e016a215429aff63819172147cb2104a 100644 (file)
@@ -31,7 +31,7 @@
 #include <linux/hwmon-sysfs.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 /* ISA device, if found */
 static struct platform_device *pdev;
index b251d8674b41a1c45708c5ee6647a668b7d0cfbf..6c53d987de1088dc5f4a199b6a0c44236b220ac4 100644 (file)
@@ -75,6 +75,8 @@ I2C_CLIENT_INSMOD_7(lm85b, lm85c, adm1027, adt7463, adt7468, emc6d100,
 #define        LM85_VERSTEP_GENERIC2           0x70
 #define        LM85_VERSTEP_LM85C              0x60
 #define        LM85_VERSTEP_LM85B              0x62
+#define        LM85_VERSTEP_LM96000_1          0x68
+#define        LM85_VERSTEP_LM96000_2          0x69
 #define        LM85_VERSTEP_ADM1027            0x60
 #define        LM85_VERSTEP_ADT7463            0x62
 #define        LM85_VERSTEP_ADT7463C           0x6A
@@ -1133,6 +1135,26 @@ static void lm85_init_client(struct i2c_client *client)
                dev_warn(&client->dev, "Device is not ready\n");
 }
 
+static int lm85_is_fake(struct i2c_client *client)
+{
+       /*
+        * Differenciate between real LM96000 and Winbond WPCD377I. The latter
+        * emulate the former except that it has no hardware monitoring function
+        * so the readings are always 0.
+        */
+       int i;
+       u8 in_temp, fan;
+
+       for (i = 0; i < 8; i++) {
+               in_temp = i2c_smbus_read_byte_data(client, 0x20 + i);
+               fan = i2c_smbus_read_byte_data(client, 0x28 + i);
+               if (in_temp != 0x00 || fan != 0xff)
+                       return 0;
+       }
+
+       return 1;
+}
+
 /* Return 0 if detection is successful, -ENODEV otherwise */
 static int lm85_detect(struct i2c_client *client, int kind,
                       struct i2c_board_info *info)
@@ -1173,6 +1195,16 @@ static int lm85_detect(struct i2c_client *client, int kind,
                        case LM85_VERSTEP_LM85B:
                                kind = lm85b;
                                break;
+                       case LM85_VERSTEP_LM96000_1:
+                       case LM85_VERSTEP_LM96000_2:
+                               /* Check for Winbond WPCD377I */
+                               if (lm85_is_fake(client)) {
+                                       dev_dbg(&adapter->dev,
+                                               "Found Winbond WPCD377I, "
+                                               "ignoring\n");
+                                       return -ENODEV;
+                               }
+                               break;
                        }
                } else if (company == LM85_COMPANY_ANALOG_DEV) {
                        switch (verstep) {
index fb052fea374401cfdb7edd78c662f6cda33292b4..4a64b85d4ec955d383932fe25d5edb726981a650 100644 (file)
@@ -44,7 +44,7 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 static u8 devid;
 static struct platform_device *pdev;
index 3a8a0f7a7736dd48468ca3dfdd3cb839d046083e..3170b26d2443b76bfbd6b518153c7329d622280c 100644 (file)
@@ -33,7 +33,7 @@
 #include <linux/sysfs.h>
 #include <linux/ioport.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 static unsigned short force_id;
 module_param(force_id, ushort, 0);
@@ -435,7 +435,7 @@ static int __devinit pc87427_probe(struct platform_device *pdev)
        /* This will need to be revisited when we add support for
           temperature and voltage monitoring. */
        res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-       if (!request_region(res->start, res->end - res->start + 1, DRVNAME)) {
+       if (!request_region(res->start, resource_size(res), DRVNAME)) {
                err = -EBUSY;
                dev_err(&pdev->dev, "Failed to request region 0x%lx-0x%lx\n",
                        (unsigned long)res->start, (unsigned long)res->end);
@@ -475,7 +475,7 @@ exit_remove_files:
                sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]);
        }
 exit_release_region:
-       release_region(res->start, res->end - res->start + 1);
+       release_region(res->start, resource_size(res));
 exit_kfree:
        platform_set_drvdata(pdev, NULL);
        kfree(data);
@@ -500,7 +500,7 @@ static int __devexit pc87427_remove(struct platform_device *pdev)
        kfree(data);
 
        res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-       release_region(res->start, res->end - res->start + 1);
+       release_region(res->start, resource_size(res));
 
        return 0;
 }
index aa2e8318f167e83cb9b6a32a47c1db6899fe191f..12f2e708656059e3dc357c438ee5d0c405f2fd0f 100644 (file)
@@ -63,7 +63,7 @@
 #include <linux/mutex.h>
 #include <linux/sysfs.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 
 /* If force_addr is set to anything different from 0, we forcibly enable
index 6f6d52b4fb64520f67581682acb3d63995343805..f46d936c12da890745de4ce11811a767fed78490 100644 (file)
@@ -37,7 +37,7 @@
 #include <linux/init.h>
 #include <linux/mutex.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 static unsigned short force_id;
 module_param(force_id, ushort, 0);
index ba75bfcf14ceb9a0f4d550091d6804e6bf2da081..8ad50fdba00dbb4744227de6c5d2949b3090c143 100644 (file)
@@ -38,7 +38,7 @@
 #include <linux/mutex.h>
 #include <linux/sysfs.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 static unsigned short force_id;
 module_param(force_id, ushort, 0);
diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c
new file mode 100644 (file)
index 0000000..2092434
--- /dev/null
@@ -0,0 +1,347 @@
+/* tmp421.c
+ *
+ * Copyright (C) 2009 Andre Prendel <andre.prendel@gmx.de>
+ * Preliminary support by:
+ * Melvin Rook, Raymond Ng
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Driver for the Texas Instruments TMP421 SMBus temperature sensor IC.
+ * Supported models: TMP421, TMP422, TMP423
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/sysfs.h>
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = { 0x2a, 0x4c, 0x4d, 0x4e, 0x4f,
+                                      I2C_CLIENT_END };
+
+/* Insmod parameters */
+I2C_CLIENT_INSMOD_3(tmp421, tmp422, tmp423);
+
+/* The TMP421 registers */
+#define TMP421_CONFIG_REG_1                    0x09
+#define TMP421_CONVERSION_RATE_REG             0x0B
+#define TMP421_MANUFACTURER_ID_REG             0xFE
+#define TMP421_DEVICE_ID_REG                   0xFF
+
+static const u8 TMP421_TEMP_MSB[4]             = { 0x00, 0x01, 0x02, 0x03 };
+static const u8 TMP421_TEMP_LSB[4]             = { 0x10, 0x11, 0x12, 0x13 };
+
+/* Flags */
+#define TMP421_CONFIG_SHUTDOWN                 0x40
+#define TMP421_CONFIG_RANGE                    0x04
+
+/* Manufacturer / Device ID's */
+#define TMP421_MANUFACTURER_ID                 0x55
+#define TMP421_DEVICE_ID                       0x21
+#define TMP422_DEVICE_ID                       0x22
+#define TMP423_DEVICE_ID                       0x23
+
+static const struct i2c_device_id tmp421_id[] = {
+       { "tmp421", tmp421 },
+       { "tmp422", tmp422 },
+       { "tmp423", tmp423 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, tmp421_id);
+
+struct tmp421_data {
+       struct device *hwmon_dev;
+       struct mutex update_lock;
+       char valid;
+       unsigned long last_updated;
+       int kind;
+       u8 config;
+       s16 temp[4];
+};
+
+static int temp_from_s16(s16 reg)
+{
+       int temp = reg;
+
+       return (temp * 1000 + 128) / 256;
+}
+
+static int temp_from_u16(u16 reg)
+{
+       int temp = reg;
+
+       /* Add offset for extended temperature range. */
+       temp -= 64 * 256;
+
+       return (temp * 1000 + 128) / 256;
+}
+
+static struct tmp421_data *tmp421_update_device(struct device *dev)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct tmp421_data *data = i2c_get_clientdata(client);
+       int i;
+
+       mutex_lock(&data->update_lock);
+
+       if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
+               data->config = i2c_smbus_read_byte_data(client,
+                       TMP421_CONFIG_REG_1);
+
+               for (i = 0; i <= data->kind; i++) {
+                       data->temp[i] = i2c_smbus_read_byte_data(client,
+                               TMP421_TEMP_MSB[i]) << 8;
+                       data->temp[i] |= i2c_smbus_read_byte_data(client,
+                               TMP421_TEMP_LSB[i]);
+               }
+               data->last_updated = jiffies;
+               data->valid = 1;
+       }
+
+       mutex_unlock(&data->update_lock);
+
+       return data;
+}
+
+static ssize_t show_temp_value(struct device *dev,
+                              struct device_attribute *devattr, char *buf)
+{
+       int index = to_sensor_dev_attr(devattr)->index;
+       struct tmp421_data *data = tmp421_update_device(dev);
+       int temp;
+
+       mutex_lock(&data->update_lock);
+       if (data->config & TMP421_CONFIG_RANGE)
+               temp = temp_from_u16(data->temp[index]);
+       else
+               temp = temp_from_s16(data->temp[index]);
+       mutex_unlock(&data->update_lock);
+
+       return sprintf(buf, "%d\n", temp);
+}
+
+static ssize_t show_fault(struct device *dev,
+                         struct device_attribute *devattr, char *buf)
+{
+       int index = to_sensor_dev_attr(devattr)->index;
+       struct tmp421_data *data = tmp421_update_device(dev);
+
+       /*
+        * The OPEN bit signals a fault. This is bit 0 of the temperature
+        * register (low byte).
+        */
+       if (data->temp[index] & 0x01)
+               return sprintf(buf, "1\n");
+       else
+               return sprintf(buf, "0\n");
+}
+
+static mode_t tmp421_is_visible(struct kobject *kobj, struct attribute *a,
+                               int n)
+{
+       struct device *dev = container_of(kobj, struct device, kobj);
+       struct tmp421_data *data = dev_get_drvdata(dev);
+       struct device_attribute *devattr;
+       unsigned int index;
+
+       devattr = container_of(a, struct device_attribute, attr);
+       index = to_sensor_dev_attr(devattr)->index;
+
+       if (data->kind > index)
+               return a->mode;
+
+       return 0;
+}
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_value, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_value, NULL, 1);
+static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_fault, NULL, 1);
+static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp_value, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_fault, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp_value, NULL, 3);
+static SENSOR_DEVICE_ATTR(temp4_fault, S_IRUGO, show_fault, NULL, 3);
+
+static struct attribute *tmp421_attr[] = {
+       &sensor_dev_attr_temp1_input.dev_attr.attr,
+       &sensor_dev_attr_temp2_input.dev_attr.attr,
+       &sensor_dev_attr_temp2_fault.dev_attr.attr,
+       &sensor_dev_attr_temp3_input.dev_attr.attr,
+       &sensor_dev_attr_temp3_fault.dev_attr.attr,
+       &sensor_dev_attr_temp4_input.dev_attr.attr,
+       &sensor_dev_attr_temp4_fault.dev_attr.attr,
+       NULL
+};
+
+static const struct attribute_group tmp421_group = {
+       .attrs = tmp421_attr,
+       .is_visible = tmp421_is_visible,
+};
+
+static int tmp421_init_client(struct i2c_client *client)
+{
+       int config, config_orig;
+
+       /* Set the conversion rate to 2 Hz */
+       i2c_smbus_write_byte_data(client, TMP421_CONVERSION_RATE_REG, 0x05);
+
+       /* Start conversions (disable shutdown if necessary) */
+       config = i2c_smbus_read_byte_data(client, TMP421_CONFIG_REG_1);
+       if (config < 0) {
+               dev_err(&client->dev, "Could not read configuration"
+                        " register (%d)\n", config);
+               return -ENODEV;
+       }
+
+       config_orig = config;
+       config &= ~TMP421_CONFIG_SHUTDOWN;
+
+       if (config != config_orig) {
+               dev_info(&client->dev, "Enable monitoring chip\n");
+               i2c_smbus_write_byte_data(client, TMP421_CONFIG_REG_1, config);
+       }
+
+       return 0;
+}
+
+static int tmp421_detect(struct i2c_client *client, int kind,
+                        struct i2c_board_info *info)
+{
+       struct i2c_adapter *adapter = client->adapter;
+       const char *names[] = { "TMP421", "TMP422", "TMP423" };
+
+       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+               return -ENODEV;
+
+       if (kind <= 0) {
+               u8 reg;
+
+               reg = i2c_smbus_read_byte_data(client,
+                                              TMP421_MANUFACTURER_ID_REG);
+               if (reg != TMP421_MANUFACTURER_ID)
+                       return -ENODEV;
+
+               reg = i2c_smbus_read_byte_data(client,
+                                              TMP421_DEVICE_ID_REG);
+               switch (reg) {
+               case TMP421_DEVICE_ID:
+                       kind = tmp421;
+                       break;
+               case TMP422_DEVICE_ID:
+                       kind = tmp422;
+                       break;
+               case TMP423_DEVICE_ID:
+                       kind = tmp423;
+                       break;
+               default:
+                       return -ENODEV;
+               }
+       }
+       strlcpy(info->type, tmp421_id[kind - 1].name, I2C_NAME_SIZE);
+       dev_info(&adapter->dev, "Detected TI %s chip at 0x%02x\n",
+                names[kind - 1], client->addr);
+
+       return 0;
+}
+
+static int tmp421_probe(struct i2c_client *client,
+                       const struct i2c_device_id *id)
+{
+       struct tmp421_data *data;
+       int err;
+
+       data = kzalloc(sizeof(struct tmp421_data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       i2c_set_clientdata(client, data);
+       mutex_init(&data->update_lock);
+       data->kind = id->driver_data;
+
+       err = tmp421_init_client(client);
+       if (err)
+               goto exit_free;
+
+       err = sysfs_create_group(&client->dev.kobj, &tmp421_group);
+       if (err)
+               goto exit_free;
+
+       data->hwmon_dev = hwmon_device_register(&client->dev);
+       if (IS_ERR(data->hwmon_dev)) {
+               err = PTR_ERR(data->hwmon_dev);
+               data->hwmon_dev = NULL;
+               goto exit_remove;
+       }
+       return 0;
+
+exit_remove:
+       sysfs_remove_group(&client->dev.kobj, &tmp421_group);
+
+exit_free:
+       i2c_set_clientdata(client, NULL);
+       kfree(data);
+
+       return err;
+}
+
+static int tmp421_remove(struct i2c_client *client)
+{
+       struct tmp421_data *data = i2c_get_clientdata(client);
+
+       hwmon_device_unregister(data->hwmon_dev);
+       sysfs_remove_group(&client->dev.kobj, &tmp421_group);
+
+       i2c_set_clientdata(client, NULL);
+       kfree(data);
+
+       return 0;
+}
+
+static struct i2c_driver tmp421_driver = {
+       .class = I2C_CLASS_HWMON,
+       .driver = {
+               .name   = "tmp421",
+       },
+       .probe = tmp421_probe,
+       .remove = tmp421_remove,
+       .id_table = tmp421_id,
+       .detect = tmp421_detect,
+       .address_data = &addr_data,
+};
+
+static int __init tmp421_init(void)
+{
+       return i2c_add_driver(&tmp421_driver);
+}
+
+static void __exit tmp421_exit(void)
+{
+       i2c_del_driver(&tmp421_driver);
+}
+
+MODULE_AUTHOR("Andre Prendel <andre.prendel@gmx.de>");
+MODULE_DESCRIPTION("Texas Instruments TMP421/422/423 temperature sensor"
+                  " driver");
+MODULE_LICENSE("GPL");
+
+module_init(tmp421_init);
+module_exit(tmp421_exit);
index a022aedcaacbe58b8377f42c96469105582990c4..39e82a492f263114382e5c123bfc46b6ad5a1e6c 100644 (file)
@@ -42,7 +42,7 @@
 #include <linux/mutex.h>
 #include <linux/sysfs.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 
 /* If force_addr is set to anything different from 0, we forcibly enable
index 73f77a9b8b188fb15840beea34d5f2f07a8d8a4f..ae33bbb577c755b89759a319d3d88c81eff4048b 100644 (file)
@@ -33,7 +33,7 @@
 #include <linux/mutex.h>
 #include <linux/ioport.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 static int uch_config = -1;
 module_param(uch_config, int, 0);
@@ -1136,7 +1136,7 @@ static int __devinit vt1211_probe(struct platform_device *pdev)
        }
 
        res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-       if (!request_region(res->start, res->end - res->start + 1, DRVNAME)) {
+       if (!request_region(res->start, resource_size(res), DRVNAME)) {
                err = -EBUSY;
                dev_err(dev, "Failed to request region 0x%lx-0x%lx\n",
                        (unsigned long)res->start, (unsigned long)res->end);
@@ -1209,7 +1209,7 @@ EXIT_DEV_REMOVE:
        dev_err(dev, "Sysfs interface creation failed (%d)\n", err);
 EXIT_DEV_REMOVE_SILENT:
        vt1211_remove_sysfs(pdev);
-       release_region(res->start, res->end - res->start + 1);
+       release_region(res->start, resource_size(res));
 EXIT_KFREE:
        platform_set_drvdata(pdev, NULL);
        kfree(data);
@@ -1228,7 +1228,7 @@ static int __devexit vt1211_remove(struct platform_device *pdev)
        kfree(data);
 
        res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-       release_region(res->start, res->end - res->start + 1);
+       release_region(res->start, resource_size(res));
 
        return 0;
 }
index 9982b45fbb1488aa1160683ada5f92cac4c88f24..470a1226ba2b38bdd29721ee943ac373c093789a 100644 (file)
@@ -36,7 +36,7 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 static int force_addr;
 module_param(force_addr, int, 0);
index 0e9746913d2b718bafdd43dc38be46c8a931ab38..bb5e78748783b71c465bdcc14c478cdcc06cf9c9 100644 (file)
@@ -51,7 +51,7 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include "lm75.h"
 
 enum kinds { w83627ehf, w83627dhg, w83627dhg_p, w83667hg };
index 389150ba30d364ffd46ce1121684531f18297754..2be28ac4ede0d1d439daa60f8bf581f251cf66b9 100644 (file)
@@ -51,7 +51,7 @@
 #include <linux/mutex.h>
 #include <linux/ioport.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include "lm75.h"
 
 static struct platform_device *pdev;
index 0bdab959b7369335672f7cd09b01386a15054472..d27ed1bac002cd1c35c8c55b41be32253c5a9936 100644 (file)
@@ -48,7 +48,7 @@
 #ifdef CONFIG_ISA
 #include <linux/platform_device.h>
 #include <linux/ioport.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #endif
 
 #include "lm75.h"
index 507569a4f232a21d2d3668aa3b8f2219b826203b..ed5741b2e7010a4ba9e6d1f76dded430e03111a9 100644 (file)
@@ -1934,6 +1934,15 @@ config XILINX_EMACLITE
        help
          This driver supports the 10/100 Ethernet Lite from Xilinx.
 
+config BCM63XX_ENET
+       tristate "Broadcom 63xx internal mac support"
+       depends on BCM63XX
+       select MII
+       select PHYLIB
+       help
+         This driver supports the ethernet MACs in the Broadcom 63xx
+         MIPS chipset family (BCM63XX).
+
 source "drivers/net/fs_enet/Kconfig"
 
 endif # NET_ETHERNET
index 99ae6d7fe6a9c6df2f72360f1a887529feb1bbd9..ae8cd30f13d6548690acdf90b114e1190f6ab465 100644 (file)
@@ -137,6 +137,7 @@ obj-$(CONFIG_B44) += b44.o
 obj-$(CONFIG_FORCEDETH) += forcedeth.o
 obj-$(CONFIG_NE_H8300) += ne-h8300.o 8390.o
 obj-$(CONFIG_AX88796) += ax88796.o
+obj-$(CONFIG_BCM63XX_ENET) += bcm63xx_enet.o
 
 obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o
 obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o
index ba48220df16a394cb157c8e9eb373de0408004a9..490d3b38e0cbaf299c57a097d20b1911f0ff03a8 100644 (file)
@@ -377,10 +377,19 @@ struct atl1e_hw {
  */
 struct atl1e_tx_buffer {
        struct sk_buff *skb;
+       u16 flags;
+#define ATL1E_TX_PCIMAP_SINGLE         0x0001
+#define ATL1E_TX_PCIMAP_PAGE           0x0002
+#define ATL1E_TX_PCIMAP_TYPE_MASK      0x0003
        u16 length;
        dma_addr_t dma;
 };
 
+#define ATL1E_SET_PCIMAP_TYPE(tx_buff, type) do {              \
+       ((tx_buff)->flags) &= ~ATL1E_TX_PCIMAP_TYPE_MASK;       \
+       ((tx_buff)->flags) |= (type);                           \
+       } while (0)
+
 struct atl1e_rx_page {
        dma_addr_t      dma;    /* receive rage DMA address */
        u8              *addr;   /* receive rage virtual address */
index 69b830f4b68fc3f9d85779f095feff2cb1338478..955da733c2ad9957320aafa545351b771c40056a 100644 (file)
@@ -635,7 +635,11 @@ static void atl1e_clean_tx_ring(struct atl1e_adapter *adapter)
        for (index = 0; index < ring_count; index++) {
                tx_buffer = &tx_ring->tx_buffer[index];
                if (tx_buffer->dma) {
-                       pci_unmap_page(pdev, tx_buffer->dma,
+                       if (tx_buffer->flags & ATL1E_TX_PCIMAP_SINGLE)
+                               pci_unmap_single(pdev, tx_buffer->dma,
+                                       tx_buffer->length, PCI_DMA_TODEVICE);
+                       else if (tx_buffer->flags & ATL1E_TX_PCIMAP_PAGE)
+                               pci_unmap_page(pdev, tx_buffer->dma,
                                        tx_buffer->length, PCI_DMA_TODEVICE);
                        tx_buffer->dma = 0;
                }
@@ -1220,7 +1224,11 @@ static bool atl1e_clean_tx_irq(struct atl1e_adapter *adapter)
        while (next_to_clean != hw_next_to_clean) {
                tx_buffer = &tx_ring->tx_buffer[next_to_clean];
                if (tx_buffer->dma) {
-                       pci_unmap_page(adapter->pdev, tx_buffer->dma,
+                       if (tx_buffer->flags & ATL1E_TX_PCIMAP_SINGLE)
+                               pci_unmap_single(adapter->pdev, tx_buffer->dma,
+                                       tx_buffer->length, PCI_DMA_TODEVICE);
+                       else if (tx_buffer->flags & ATL1E_TX_PCIMAP_PAGE)
+                               pci_unmap_page(adapter->pdev, tx_buffer->dma,
                                        tx_buffer->length, PCI_DMA_TODEVICE);
                        tx_buffer->dma = 0;
                }
@@ -1741,6 +1749,7 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter,
                tx_buffer->length = map_len;
                tx_buffer->dma = pci_map_single(adapter->pdev,
                                        skb->data, hdr_len, PCI_DMA_TODEVICE);
+               ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_SINGLE);
                mapped_len += map_len;
                use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma);
                use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) |
@@ -1766,6 +1775,7 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter,
                tx_buffer->dma =
                        pci_map_single(adapter->pdev, skb->data + mapped_len,
                                        map_len, PCI_DMA_TODEVICE);
+               ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_SINGLE);
                mapped_len  += map_len;
                use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma);
                use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) |
@@ -1801,6 +1811,7 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter,
                                                (i * MAX_TX_BUF_LEN),
                                                tx_buffer->length,
                                                PCI_DMA_TODEVICE);
+                       ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_PAGE);
                        use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma);
                        use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) |
                                        ((cpu_to_le32(tx_buffer->length) &
index 0189dcd36f31b9c4fd778763c87e30e671df8059..e046943ef29dc6c9243bb84ad0c5ab5fcdde19bf 100644 (file)
@@ -847,23 +847,22 @@ static int b44_poll(struct napi_struct *napi, int budget)
 {
        struct b44 *bp = container_of(napi, struct b44, napi);
        int work_done;
+       unsigned long flags;
 
-       spin_lock_irq(&bp->lock);
+       spin_lock_irqsave(&bp->lock, flags);
 
        if (bp->istat & (ISTAT_TX | ISTAT_TO)) {
                /* spin_lock(&bp->tx_lock); */
                b44_tx(bp);
                /* spin_unlock(&bp->tx_lock); */
        }
-       spin_unlock_irq(&bp->lock);
+       spin_unlock_irqrestore(&bp->lock, flags);
 
        work_done = 0;
        if (bp->istat & ISTAT_RX)
                work_done += b44_rx(bp, budget);
 
        if (bp->istat & ISTAT_ERRORS) {
-               unsigned long flags;
-
                spin_lock_irqsave(&bp->lock, flags);
                b44_halt(bp);
                b44_init_rings(bp);
diff --git a/drivers/net/bcm63xx_enet.c b/drivers/net/bcm63xx_enet.c
new file mode 100644 (file)
index 0000000..09d2709
--- /dev/null
@@ -0,0 +1,1971 @@
+/*
+ * Driver for BCM963xx builtin Ethernet mac
+ *
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/etherdevice.h>
+#include <linux/delay.h>
+#include <linux/ethtool.h>
+#include <linux/crc32.h>
+#include <linux/err.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/if_vlan.h>
+
+#include <bcm63xx_dev_enet.h>
+#include "bcm63xx_enet.h"
+
+static char bcm_enet_driver_name[] = "bcm63xx_enet";
+static char bcm_enet_driver_version[] = "1.0";
+
+static int copybreak __read_mostly = 128;
+module_param(copybreak, int, 0);
+MODULE_PARM_DESC(copybreak, "Receive copy threshold");
+
+/* io memory shared between all devices */
+static void __iomem *bcm_enet_shared_base;
+
+/*
+ * io helpers to access mac registers
+ */
+static inline u32 enet_readl(struct bcm_enet_priv *priv, u32 off)
+{
+       return bcm_readl(priv->base + off);
+}
+
+static inline void enet_writel(struct bcm_enet_priv *priv,
+                              u32 val, u32 off)
+{
+       bcm_writel(val, priv->base + off);
+}
+
+/*
+ * io helpers to access shared registers
+ */
+static inline u32 enet_dma_readl(struct bcm_enet_priv *priv, u32 off)
+{
+       return bcm_readl(bcm_enet_shared_base + off);
+}
+
+static inline void enet_dma_writel(struct bcm_enet_priv *priv,
+                                      u32 val, u32 off)
+{
+       bcm_writel(val, bcm_enet_shared_base + off);
+}
+
+/*
+ * write given data into mii register and wait for transfer to end
+ * with timeout (average measured transfer time is 25us)
+ */
+static int do_mdio_op(struct bcm_enet_priv *priv, unsigned int data)
+{
+       int limit;
+
+       /* make sure mii interrupt status is cleared */
+       enet_writel(priv, ENET_IR_MII, ENET_IR_REG);
+
+       enet_writel(priv, data, ENET_MIIDATA_REG);
+       wmb();
+
+       /* busy wait on mii interrupt bit, with timeout */
+       limit = 1000;
+       do {
+               if (enet_readl(priv, ENET_IR_REG) & ENET_IR_MII)
+                       break;
+               udelay(1);
+       } while (limit-- >= 0);
+
+       return (limit < 0) ? 1 : 0;
+}
+
+/*
+ * MII internal read callback
+ */
+static int bcm_enet_mdio_read(struct bcm_enet_priv *priv, int mii_id,
+                             int regnum)
+{
+       u32 tmp, val;
+
+       tmp = regnum << ENET_MIIDATA_REG_SHIFT;
+       tmp |= 0x2 << ENET_MIIDATA_TA_SHIFT;
+       tmp |= mii_id << ENET_MIIDATA_PHYID_SHIFT;
+       tmp |= ENET_MIIDATA_OP_READ_MASK;
+
+       if (do_mdio_op(priv, tmp))
+               return -1;
+
+       val = enet_readl(priv, ENET_MIIDATA_REG);
+       val &= 0xffff;
+       return val;
+}
+
+/*
+ * MII internal write callback
+ */
+static int bcm_enet_mdio_write(struct bcm_enet_priv *priv, int mii_id,
+                              int regnum, u16 value)
+{
+       u32 tmp;
+
+       tmp = (value & 0xffff) << ENET_MIIDATA_DATA_SHIFT;
+       tmp |= 0x2 << ENET_MIIDATA_TA_SHIFT;
+       tmp |= regnum << ENET_MIIDATA_REG_SHIFT;
+       tmp |= mii_id << ENET_MIIDATA_PHYID_SHIFT;
+       tmp |= ENET_MIIDATA_OP_WRITE_MASK;
+
+       (void)do_mdio_op(priv, tmp);
+       return 0;
+}
+
+/*
+ * MII read callback from phylib
+ */
+static int bcm_enet_mdio_read_phylib(struct mii_bus *bus, int mii_id,
+                                    int regnum)
+{
+       return bcm_enet_mdio_read(bus->priv, mii_id, regnum);
+}
+
+/*
+ * MII write callback from phylib
+ */
+static int bcm_enet_mdio_write_phylib(struct mii_bus *bus, int mii_id,
+                                     int regnum, u16 value)
+{
+       return bcm_enet_mdio_write(bus->priv, mii_id, regnum, value);
+}
+
+/*
+ * MII read callback from mii core
+ */
+static int bcm_enet_mdio_read_mii(struct net_device *dev, int mii_id,
+                                 int regnum)
+{
+       return bcm_enet_mdio_read(netdev_priv(dev), mii_id, regnum);
+}
+
+/*
+ * MII write callback from mii core
+ */
+static void bcm_enet_mdio_write_mii(struct net_device *dev, int mii_id,
+                                   int regnum, int value)
+{
+       bcm_enet_mdio_write(netdev_priv(dev), mii_id, regnum, value);
+}
+
+/*
+ * refill rx queue
+ */
+static int bcm_enet_refill_rx(struct net_device *dev)
+{
+       struct bcm_enet_priv *priv;
+
+       priv = netdev_priv(dev);
+
+       while (priv->rx_desc_count < priv->rx_ring_size) {
+               struct bcm_enet_desc *desc;
+               struct sk_buff *skb;
+               dma_addr_t p;
+               int desc_idx;
+               u32 len_stat;
+
+               desc_idx = priv->rx_dirty_desc;
+               desc = &priv->rx_desc_cpu[desc_idx];
+
+               if (!priv->rx_skb[desc_idx]) {
+                       skb = netdev_alloc_skb(dev, priv->rx_skb_size);
+                       if (!skb)
+                               break;
+                       priv->rx_skb[desc_idx] = skb;
+
+                       p = dma_map_single(&priv->pdev->dev, skb->data,
+                                          priv->rx_skb_size,
+                                          DMA_FROM_DEVICE);
+                       desc->address = p;
+               }
+
+               len_stat = priv->rx_skb_size << DMADESC_LENGTH_SHIFT;
+               len_stat |= DMADESC_OWNER_MASK;
+               if (priv->rx_dirty_desc == priv->rx_ring_size - 1) {
+                       len_stat |= DMADESC_WRAP_MASK;
+                       priv->rx_dirty_desc = 0;
+               } else {
+                       priv->rx_dirty_desc++;
+               }
+               wmb();
+               desc->len_stat = len_stat;
+
+               priv->rx_desc_count++;
+
+               /* tell dma engine we allocated one buffer */
+               enet_dma_writel(priv, 1, ENETDMA_BUFALLOC_REG(priv->rx_chan));
+       }
+
+       /* If rx ring is still empty, set a timer to try allocating
+        * again at a later time. */
+       if (priv->rx_desc_count == 0 && netif_running(dev)) {
+               dev_warn(&priv->pdev->dev, "unable to refill rx ring\n");
+               priv->rx_timeout.expires = jiffies + HZ;
+               add_timer(&priv->rx_timeout);
+       }
+
+       return 0;
+}
+
+/*
+ * timer callback to defer refill rx queue in case we're OOM
+ */
+static void bcm_enet_refill_rx_timer(unsigned long data)
+{
+       struct net_device *dev;
+       struct bcm_enet_priv *priv;
+
+       dev = (struct net_device *)data;
+       priv = netdev_priv(dev);
+
+       spin_lock(&priv->rx_lock);
+       bcm_enet_refill_rx((struct net_device *)data);
+       spin_unlock(&priv->rx_lock);
+}
+
+/*
+ * extract packet from rx queue
+ */
+static int bcm_enet_receive_queue(struct net_device *dev, int budget)
+{
+       struct bcm_enet_priv *priv;
+       struct device *kdev;
+       int processed;
+
+       priv = netdev_priv(dev);
+       kdev = &priv->pdev->dev;
+       processed = 0;
+
+       /* don't scan ring further than number of refilled
+        * descriptor */
+       if (budget > priv->rx_desc_count)
+               budget = priv->rx_desc_count;
+
+       do {
+               struct bcm_enet_desc *desc;
+               struct sk_buff *skb;
+               int desc_idx;
+               u32 len_stat;
+               unsigned int len;
+
+               desc_idx = priv->rx_curr_desc;
+               desc = &priv->rx_desc_cpu[desc_idx];
+
+               /* make sure we actually read the descriptor status at
+                * each loop */
+               rmb();
+
+               len_stat = desc->len_stat;
+
+               /* break if dma ownership belongs to hw */
+               if (len_stat & DMADESC_OWNER_MASK)
+                       break;
+
+               processed++;
+               priv->rx_curr_desc++;
+               if (priv->rx_curr_desc == priv->rx_ring_size)
+                       priv->rx_curr_desc = 0;
+               priv->rx_desc_count--;
+
+               /* if the packet does not have start of packet _and_
+                * end of packet flag set, then just recycle it */
+               if ((len_stat & DMADESC_ESOP_MASK) != DMADESC_ESOP_MASK) {
+                       priv->stats.rx_dropped++;
+                       continue;
+               }
+
+               /* recycle packet if it's marked as bad */
+               if (unlikely(len_stat & DMADESC_ERR_MASK)) {
+                       priv->stats.rx_errors++;
+
+                       if (len_stat & DMADESC_OVSIZE_MASK)
+                               priv->stats.rx_length_errors++;
+                       if (len_stat & DMADESC_CRC_MASK)
+                               priv->stats.rx_crc_errors++;
+                       if (len_stat & DMADESC_UNDER_MASK)
+                               priv->stats.rx_frame_errors++;
+                       if (len_stat & DMADESC_OV_MASK)
+                               priv->stats.rx_fifo_errors++;
+                       continue;
+               }
+
+               /* valid packet */
+               skb = priv->rx_skb[desc_idx];
+               len = (len_stat & DMADESC_LENGTH_MASK) >> DMADESC_LENGTH_SHIFT;
+               /* don't include FCS */
+               len -= 4;
+
+               if (len < copybreak) {
+                       struct sk_buff *nskb;
+
+                       nskb = netdev_alloc_skb(dev, len + NET_IP_ALIGN);
+                       if (!nskb) {
+                               /* forget packet, just rearm desc */
+                               priv->stats.rx_dropped++;
+                               continue;
+                       }
+
+                       /* since we're copying the data, we can align
+                        * them properly */
+                       skb_reserve(nskb, NET_IP_ALIGN);
+                       dma_sync_single_for_cpu(kdev, desc->address,
+                                               len, DMA_FROM_DEVICE);
+                       memcpy(nskb->data, skb->data, len);
+                       dma_sync_single_for_device(kdev, desc->address,
+                                                  len, DMA_FROM_DEVICE);
+                       skb = nskb;
+               } else {
+                       dma_unmap_single(&priv->pdev->dev, desc->address,
+                                        priv->rx_skb_size, DMA_FROM_DEVICE);
+                       priv->rx_skb[desc_idx] = NULL;
+               }
+
+               skb_put(skb, len);
+               skb->dev = dev;
+               skb->protocol = eth_type_trans(skb, dev);
+               priv->stats.rx_packets++;
+               priv->stats.rx_bytes += len;
+               dev->last_rx = jiffies;
+               netif_receive_skb(skb);
+
+       } while (--budget > 0);
+
+       if (processed || !priv->rx_desc_count) {
+               bcm_enet_refill_rx(dev);
+
+               /* kick rx dma */
+               enet_dma_writel(priv, ENETDMA_CHANCFG_EN_MASK,
+                               ENETDMA_CHANCFG_REG(priv->rx_chan));
+       }
+
+       return processed;
+}
+
+
+/*
+ * try to or force reclaim of transmitted buffers
+ */
+static int bcm_enet_tx_reclaim(struct net_device *dev, int force)
+{
+       struct bcm_enet_priv *priv;
+       int released;
+
+       priv = netdev_priv(dev);
+       released = 0;
+
+       while (priv->tx_desc_count < priv->tx_ring_size) {
+               struct bcm_enet_desc *desc;
+               struct sk_buff *skb;
+
+               /* We run in a bh and fight against start_xmit, which
+                * is called with bh disabled  */
+               spin_lock(&priv->tx_lock);
+
+               desc = &priv->tx_desc_cpu[priv->tx_dirty_desc];
+
+               if (!force && (desc->len_stat & DMADESC_OWNER_MASK)) {
+                       spin_unlock(&priv->tx_lock);
+                       break;
+               }
+
+               /* ensure other field of the descriptor were not read
+                * before we checked ownership */
+               rmb();
+
+               skb = priv->tx_skb[priv->tx_dirty_desc];
+               priv->tx_skb[priv->tx_dirty_desc] = NULL;
+               dma_unmap_single(&priv->pdev->dev, desc->address, skb->len,
+                                DMA_TO_DEVICE);
+
+               priv->tx_dirty_desc++;
+               if (priv->tx_dirty_desc == priv->tx_ring_size)
+                       priv->tx_dirty_desc = 0;
+               priv->tx_desc_count++;
+
+               spin_unlock(&priv->tx_lock);
+
+               if (desc->len_stat & DMADESC_UNDER_MASK)
+                       priv->stats.tx_errors++;
+
+               dev_kfree_skb(skb);
+               released++;
+       }
+
+       if (netif_queue_stopped(dev) && released)
+               netif_wake_queue(dev);
+
+       return released;
+}
+
+/*
+ * poll func, called by network core
+ */
+static int bcm_enet_poll(struct napi_struct *napi, int budget)
+{
+       struct bcm_enet_priv *priv;
+       struct net_device *dev;
+       int tx_work_done, rx_work_done;
+
+       priv = container_of(napi, struct bcm_enet_priv, napi);
+       dev = priv->net_dev;
+
+       /* ack interrupts */
+       enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
+                       ENETDMA_IR_REG(priv->rx_chan));
+       enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
+                       ENETDMA_IR_REG(priv->tx_chan));
+
+       /* reclaim sent skb */
+       tx_work_done = bcm_enet_tx_reclaim(dev, 0);
+
+       spin_lock(&priv->rx_lock);
+       rx_work_done = bcm_enet_receive_queue(dev, budget);
+       spin_unlock(&priv->rx_lock);
+
+       if (rx_work_done >= budget || tx_work_done > 0) {
+               /* rx/tx queue is not yet empty/clean */
+               return rx_work_done;
+       }
+
+       /* no more packet in rx/tx queue, remove device from poll
+        * queue */
+       napi_complete(napi);
+
+       /* restore rx/tx interrupt */
+       enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
+                       ENETDMA_IRMASK_REG(priv->rx_chan));
+       enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
+                       ENETDMA_IRMASK_REG(priv->tx_chan));
+
+       return rx_work_done;
+}
+
+/*
+ * mac interrupt handler
+ */
+static irqreturn_t bcm_enet_isr_mac(int irq, void *dev_id)
+{
+       struct net_device *dev;
+       struct bcm_enet_priv *priv;
+       u32 stat;
+
+       dev = dev_id;
+       priv = netdev_priv(dev);
+
+       stat = enet_readl(priv, ENET_IR_REG);
+       if (!(stat & ENET_IR_MIB))
+               return IRQ_NONE;
+
+       /* clear & mask interrupt */
+       enet_writel(priv, ENET_IR_MIB, ENET_IR_REG);
+       enet_writel(priv, 0, ENET_IRMASK_REG);
+
+       /* read mib registers in workqueue */
+       schedule_work(&priv->mib_update_task);
+
+       return IRQ_HANDLED;
+}
+
+/*
+ * rx/tx dma interrupt handler
+ */
+static irqreturn_t bcm_enet_isr_dma(int irq, void *dev_id)
+{
+       struct net_device *dev;
+       struct bcm_enet_priv *priv;
+
+       dev = dev_id;
+       priv = netdev_priv(dev);
+
+       /* mask rx/tx interrupts */
+       enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->rx_chan));
+       enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan));
+
+       napi_schedule(&priv->napi);
+
+       return IRQ_HANDLED;
+}
+
+/*
+ * tx request callback
+ */
+static int bcm_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       struct bcm_enet_priv *priv;
+       struct bcm_enet_desc *desc;
+       u32 len_stat;
+       int ret;
+
+       priv = netdev_priv(dev);
+
+       /* lock against tx reclaim */
+       spin_lock(&priv->tx_lock);
+
+       /* make sure  the tx hw queue  is not full,  should not happen
+        * since we stop queue before it's the case */
+       if (unlikely(!priv->tx_desc_count)) {
+               netif_stop_queue(dev);
+               dev_err(&priv->pdev->dev, "xmit called with no tx desc "
+                       "available?\n");
+               ret = NETDEV_TX_BUSY;
+               goto out_unlock;
+       }
+
+       /* point to the next available desc */
+       desc = &priv->tx_desc_cpu[priv->tx_curr_desc];
+       priv->tx_skb[priv->tx_curr_desc] = skb;
+
+       /* fill descriptor */
+       desc->address = dma_map_single(&priv->pdev->dev, skb->data, skb->len,
+                                      DMA_TO_DEVICE);
+
+       len_stat = (skb->len << DMADESC_LENGTH_SHIFT) & DMADESC_LENGTH_MASK;
+       len_stat |= DMADESC_ESOP_MASK |
+               DMADESC_APPEND_CRC |
+               DMADESC_OWNER_MASK;
+
+       priv->tx_curr_desc++;
+       if (priv->tx_curr_desc == priv->tx_ring_size) {
+               priv->tx_curr_desc = 0;
+               len_stat |= DMADESC_WRAP_MASK;
+       }
+       priv->tx_desc_count--;
+
+       /* dma might be already polling, make sure we update desc
+        * fields in correct order */
+       wmb();
+       desc->len_stat = len_stat;
+       wmb();
+
+       /* kick tx dma */
+       enet_dma_writel(priv, ENETDMA_CHANCFG_EN_MASK,
+                       ENETDMA_CHANCFG_REG(priv->tx_chan));
+
+       /* stop queue if no more desc available */
+       if (!priv->tx_desc_count)
+               netif_stop_queue(dev);
+
+       priv->stats.tx_bytes += skb->len;
+       priv->stats.tx_packets++;
+       dev->trans_start = jiffies;
+       ret = NETDEV_TX_OK;
+
+out_unlock:
+       spin_unlock(&priv->tx_lock);
+       return ret;
+}
+
+/*
+ * Change the interface's mac address.
+ */
+static int bcm_enet_set_mac_address(struct net_device *dev, void *p)
+{
+       struct bcm_enet_priv *priv;
+       struct sockaddr *addr = p;
+       u32 val;
+
+       priv = netdev_priv(dev);
+       memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+
+       /* use perfect match register 0 to store my mac address */
+       val = (dev->dev_addr[2] << 24) | (dev->dev_addr[3] << 16) |
+               (dev->dev_addr[4] << 8) | dev->dev_addr[5];
+       enet_writel(priv, val, ENET_PML_REG(0));
+
+       val = (dev->dev_addr[0] << 8 | dev->dev_addr[1]);
+       val |= ENET_PMH_DATAVALID_MASK;
+       enet_writel(priv, val, ENET_PMH_REG(0));
+
+       return 0;
+}
+
+/*
+ * Change rx mode (promiscous/allmulti) and update multicast list
+ */
+static void bcm_enet_set_multicast_list(struct net_device *dev)
+{
+       struct bcm_enet_priv *priv;
+       struct dev_mc_list *mc_list;
+       u32 val;
+       int i;
+
+       priv = netdev_priv(dev);
+
+       val = enet_readl(priv, ENET_RXCFG_REG);
+
+       if (dev->flags & IFF_PROMISC)
+               val |= ENET_RXCFG_PROMISC_MASK;
+       else
+               val &= ~ENET_RXCFG_PROMISC_MASK;
+
+       /* only 3 perfect match registers left, first one is used for
+        * own mac address */
+       if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > 3)
+               val |= ENET_RXCFG_ALLMCAST_MASK;
+       else
+               val &= ~ENET_RXCFG_ALLMCAST_MASK;
+
+       /* no need to set perfect match registers if we catch all
+        * multicast */
+       if (val & ENET_RXCFG_ALLMCAST_MASK) {
+               enet_writel(priv, val, ENET_RXCFG_REG);
+               return;
+       }
+
+       for (i = 0, mc_list = dev->mc_list;
+            (mc_list != NULL) && (i < dev->mc_count) && (i < 3);
+            i++, mc_list = mc_list->next) {
+               u8 *dmi_addr;
+               u32 tmp;
+
+               /* filter non ethernet address */
+               if (mc_list->dmi_addrlen != 6)
+                       continue;
+
+               /* update perfect match registers */
+               dmi_addr = mc_list->dmi_addr;
+               tmp = (dmi_addr[2] << 24) | (dmi_addr[3] << 16) |
+                       (dmi_addr[4] << 8) | dmi_addr[5];
+               enet_writel(priv, tmp, ENET_PML_REG(i + 1));
+
+               tmp = (dmi_addr[0] << 8 | dmi_addr[1]);
+               tmp |= ENET_PMH_DATAVALID_MASK;
+               enet_writel(priv, tmp, ENET_PMH_REG(i + 1));
+       }
+
+       for (; i < 3; i++) {
+               enet_writel(priv, 0, ENET_PML_REG(i + 1));
+               enet_writel(priv, 0, ENET_PMH_REG(i + 1));
+       }
+
+       enet_writel(priv, val, ENET_RXCFG_REG);
+}
+
+/*
+ * set mac duplex parameters
+ */
+static void bcm_enet_set_duplex(struct bcm_enet_priv *priv, int fullduplex)
+{
+       u32 val;
+
+       val = enet_readl(priv, ENET_TXCTL_REG);
+       if (fullduplex)
+               val |= ENET_TXCTL_FD_MASK;
+       else
+               val &= ~ENET_TXCTL_FD_MASK;
+       enet_writel(priv, val, ENET_TXCTL_REG);
+}
+
+/*
+ * set mac flow control parameters
+ */
+static void bcm_enet_set_flow(struct bcm_enet_priv *priv, int rx_en, int tx_en)
+{
+       u32 val;
+
+       /* rx flow control (pause frame handling) */
+       val = enet_readl(priv, ENET_RXCFG_REG);
+       if (rx_en)
+               val |= ENET_RXCFG_ENFLOW_MASK;
+       else
+               val &= ~ENET_RXCFG_ENFLOW_MASK;
+       enet_writel(priv, val, ENET_RXCFG_REG);
+
+       /* tx flow control (pause frame generation) */
+       val = enet_dma_readl(priv, ENETDMA_CFG_REG);
+       if (tx_en)
+               val |= ENETDMA_CFG_FLOWCH_MASK(priv->rx_chan);
+       else
+               val &= ~ENETDMA_CFG_FLOWCH_MASK(priv->rx_chan);
+       enet_dma_writel(priv, val, ENETDMA_CFG_REG);
+}
+
+/*
+ * link changed callback (from phylib)
+ */
+static void bcm_enet_adjust_phy_link(struct net_device *dev)
+{
+       struct bcm_enet_priv *priv;
+       struct phy_device *phydev;
+       int status_changed;
+
+       priv = netdev_priv(dev);
+       phydev = priv->phydev;
+       status_changed = 0;
+
+       if (priv->old_link != phydev->link) {
+               status_changed = 1;
+               priv->old_link = phydev->link;
+       }
+
+       /* reflect duplex change in mac configuration */
+       if (phydev->link && phydev->duplex != priv->old_duplex) {
+               bcm_enet_set_duplex(priv,
+                                   (phydev->duplex == DUPLEX_FULL) ? 1 : 0);
+               status_changed = 1;
+               priv->old_duplex = phydev->duplex;
+       }
+
+       /* enable flow control if remote advertise it (trust phylib to
+        * check that duplex is full */
+       if (phydev->link && phydev->pause != priv->old_pause) {
+               int rx_pause_en, tx_pause_en;
+
+               if (phydev->pause) {
+                       /* pause was advertised by lpa and us */
+                       rx_pause_en = 1;
+                       tx_pause_en = 1;
+               } else if (!priv->pause_auto) {
+                       /* pause setting overrided by user */
+                       rx_pause_en = priv->pause_rx;
+                       tx_pause_en = priv->pause_tx;
+               } else {
+                       rx_pause_en = 0;
+                       tx_pause_en = 0;
+               }
+
+               bcm_enet_set_flow(priv, rx_pause_en, tx_pause_en);
+               status_changed = 1;
+               priv->old_pause = phydev->pause;
+       }
+
+       if (status_changed) {
+               pr_info("%s: link %s", dev->name, phydev->link ?
+                       "UP" : "DOWN");
+               if (phydev->link)
+                       pr_cont(" - %d/%s - flow control %s", phydev->speed,
+                              DUPLEX_FULL == phydev->duplex ? "full" : "half",
+                              phydev->pause == 1 ? "rx&tx" : "off");
+
+               pr_cont("\n");
+       }
+}
+
+/*
+ * link changed callback (if phylib is not used)
+ */
+static void bcm_enet_adjust_link(struct net_device *dev)
+{
+       struct bcm_enet_priv *priv;
+
+       priv = netdev_priv(dev);
+       bcm_enet_set_duplex(priv, priv->force_duplex_full);
+       bcm_enet_set_flow(priv, priv->pause_rx, priv->pause_tx);
+       netif_carrier_on(dev);
+
+       pr_info("%s: link forced UP - %d/%s - flow control %s/%s\n",
+               dev->name,
+               priv->force_speed_100 ? 100 : 10,
+               priv->force_duplex_full ? "full" : "half",
+               priv->pause_rx ? "rx" : "off",
+               priv->pause_tx ? "tx" : "off");
+}
+
+/*
+ * open callback, allocate dma rings & buffers and start rx operation
+ */
+static int bcm_enet_open(struct net_device *dev)
+{
+       struct bcm_enet_priv *priv;
+       struct sockaddr addr;
+       struct device *kdev;
+       struct phy_device *phydev;
+       int i, ret;
+       unsigned int size;
+       char phy_id[MII_BUS_ID_SIZE + 3];
+       void *p;
+       u32 val;
+
+       priv = netdev_priv(dev);
+       kdev = &priv->pdev->dev;
+
+       if (priv->has_phy) {
+               /* connect to PHY */
+               snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT,
+                        priv->mac_id ? "1" : "0", priv->phy_id);
+
+               phydev = phy_connect(dev, phy_id, &bcm_enet_adjust_phy_link, 0,
+                                    PHY_INTERFACE_MODE_MII);
+
+               if (IS_ERR(phydev)) {
+                       dev_err(kdev, "could not attach to PHY\n");
+                       return PTR_ERR(phydev);
+               }
+
+               /* mask with MAC supported features */
+               phydev->supported &= (SUPPORTED_10baseT_Half |
+                                     SUPPORTED_10baseT_Full |
+                                     SUPPORTED_100baseT_Half |
+                                     SUPPORTED_100baseT_Full |
+                                     SUPPORTED_Autoneg |
+                                     SUPPORTED_Pause |
+                                     SUPPORTED_MII);
+               phydev->advertising = phydev->supported;
+
+               if (priv->pause_auto && priv->pause_rx && priv->pause_tx)
+                       phydev->advertising |= SUPPORTED_Pause;
+               else
+                       phydev->advertising &= ~SUPPORTED_Pause;
+
+               dev_info(kdev, "attached PHY at address %d [%s]\n",
+                        phydev->addr, phydev->drv->name);
+
+               priv->old_link = 0;
+               priv->old_duplex = -1;
+               priv->old_pause = -1;
+               priv->phydev = phydev;
+       }
+
+       /* mask all interrupts and request them */
+       enet_writel(priv, 0, ENET_IRMASK_REG);
+       enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->rx_chan));
+       enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan));
+
+       ret = request_irq(dev->irq, bcm_enet_isr_mac, 0, dev->name, dev);
+       if (ret)
+               goto out_phy_disconnect;
+
+       ret = request_irq(priv->irq_rx, bcm_enet_isr_dma,
+                         IRQF_SAMPLE_RANDOM | IRQF_DISABLED, dev->name, dev);
+       if (ret)
+               goto out_freeirq;
+
+       ret = request_irq(priv->irq_tx, bcm_enet_isr_dma,
+                         IRQF_DISABLED, dev->name, dev);
+       if (ret)
+               goto out_freeirq_rx;
+
+       /* initialize perfect match registers */
+       for (i = 0; i < 4; i++) {
+               enet_writel(priv, 0, ENET_PML_REG(i));
+               enet_writel(priv, 0, ENET_PMH_REG(i));
+       }
+
+       /* write device mac address */
+       memcpy(addr.sa_data, dev->dev_addr, ETH_ALEN);
+       bcm_enet_set_mac_address(dev, &addr);
+
+       /* allocate rx dma ring */
+       size = priv->rx_ring_size * sizeof(struct bcm_enet_desc);
+       p = dma_alloc_coherent(kdev, size, &priv->rx_desc_dma, GFP_KERNEL);
+       if (!p) {
+               dev_err(kdev, "cannot allocate rx ring %u\n", size);
+               ret = -ENOMEM;
+               goto out_freeirq_tx;
+       }
+
+       memset(p, 0, size);
+       priv->rx_desc_alloc_size = size;
+       priv->rx_desc_cpu = p;
+
+       /* allocate tx dma ring */
+       size = priv->tx_ring_size * sizeof(struct bcm_enet_desc);
+       p = dma_alloc_coherent(kdev, size, &priv->tx_desc_dma, GFP_KERNEL);
+       if (!p) {
+               dev_err(kdev, "cannot allocate tx ring\n");
+               ret = -ENOMEM;
+               goto out_free_rx_ring;
+       }
+
+       memset(p, 0, size);
+       priv->tx_desc_alloc_size = size;
+       priv->tx_desc_cpu = p;
+
+       priv->tx_skb = kzalloc(sizeof(struct sk_buff *) * priv->tx_ring_size,
+                              GFP_KERNEL);
+       if (!priv->tx_skb) {
+               dev_err(kdev, "cannot allocate rx skb queue\n");
+               ret = -ENOMEM;
+               goto out_free_tx_ring;
+       }
+
+       priv->tx_desc_count = priv->tx_ring_size;
+       priv->tx_dirty_desc = 0;
+       priv->tx_curr_desc = 0;
+       spin_lock_init(&priv->tx_lock);
+
+       /* init & fill rx ring with skbs */
+       priv->rx_skb = kzalloc(sizeof(struct sk_buff *) * priv->rx_ring_size,
+                              GFP_KERNEL);
+       if (!priv->rx_skb) {
+               dev_err(kdev, "cannot allocate rx skb queue\n");
+               ret = -ENOMEM;
+               goto out_free_tx_skb;
+       }
+
+       priv->rx_desc_count = 0;
+       priv->rx_dirty_desc = 0;
+       priv->rx_curr_desc = 0;
+
+       /* initialize flow control buffer allocation */
+       enet_dma_writel(priv, ENETDMA_BUFALLOC_FORCE_MASK | 0,
+                       ENETDMA_BUFALLOC_REG(priv->rx_chan));
+
+       if (bcm_enet_refill_rx(dev)) {
+               dev_err(kdev, "cannot allocate rx skb queue\n");
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       /* write rx & tx ring addresses */
+       enet_dma_writel(priv, priv->rx_desc_dma,
+                       ENETDMA_RSTART_REG(priv->rx_chan));
+       enet_dma_writel(priv, priv->tx_desc_dma,
+                       ENETDMA_RSTART_REG(priv->tx_chan));
+
+       /* clear remaining state ram for rx & tx channel */
+       enet_dma_writel(priv, 0, ENETDMA_SRAM2_REG(priv->rx_chan));
+       enet_dma_writel(priv, 0, ENETDMA_SRAM2_REG(priv->tx_chan));
+       enet_dma_writel(priv, 0, ENETDMA_SRAM3_REG(priv->rx_chan));
+       enet_dma_writel(priv, 0, ENETDMA_SRAM3_REG(priv->tx_chan));
+       enet_dma_writel(priv, 0, ENETDMA_SRAM4_REG(priv->rx_chan));
+       enet_dma_writel(priv, 0, ENETDMA_SRAM4_REG(priv->tx_chan));
+
+       /* set max rx/tx length */
+       enet_writel(priv, priv->hw_mtu, ENET_RXMAXLEN_REG);
+       enet_writel(priv, priv->hw_mtu, ENET_TXMAXLEN_REG);
+
+       /* set dma maximum burst len */
+       enet_dma_writel(priv, BCMENET_DMA_MAXBURST,
+                       ENETDMA_MAXBURST_REG(priv->rx_chan));
+       enet_dma_writel(priv, BCMENET_DMA_MAXBURST,
+                       ENETDMA_MAXBURST_REG(priv->tx_chan));
+
+       /* set correct transmit fifo watermark */
+       enet_writel(priv, BCMENET_TX_FIFO_TRESH, ENET_TXWMARK_REG);
+
+       /* set flow control low/high threshold to 1/3 / 2/3 */
+       val = priv->rx_ring_size / 3;
+       enet_dma_writel(priv, val, ENETDMA_FLOWCL_REG(priv->rx_chan));
+       val = (priv->rx_ring_size * 2) / 3;
+       enet_dma_writel(priv, val, ENETDMA_FLOWCH_REG(priv->rx_chan));
+
+       /* all set, enable mac and interrupts, start dma engine and
+        * kick rx dma channel */
+       wmb();
+       enet_writel(priv, ENET_CTL_ENABLE_MASK, ENET_CTL_REG);
+       enet_dma_writel(priv, ENETDMA_CFG_EN_MASK, ENETDMA_CFG_REG);
+       enet_dma_writel(priv, ENETDMA_CHANCFG_EN_MASK,
+                       ENETDMA_CHANCFG_REG(priv->rx_chan));
+
+       /* watch "mib counters about to overflow" interrupt */
+       enet_writel(priv, ENET_IR_MIB, ENET_IR_REG);
+       enet_writel(priv, ENET_IR_MIB, ENET_IRMASK_REG);
+
+       /* watch "packet transferred" interrupt in rx and tx */
+       enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
+                       ENETDMA_IR_REG(priv->rx_chan));
+       enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
+                       ENETDMA_IR_REG(priv->tx_chan));
+
+       /* make sure we enable napi before rx interrupt  */
+       napi_enable(&priv->napi);
+
+       enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
+                       ENETDMA_IRMASK_REG(priv->rx_chan));
+       enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
+                       ENETDMA_IRMASK_REG(priv->tx_chan));
+
+       if (priv->has_phy)
+               phy_start(priv->phydev);
+       else
+               bcm_enet_adjust_link(dev);
+
+       netif_start_queue(dev);
+       return 0;
+
+out:
+       for (i = 0; i < priv->rx_ring_size; i++) {
+               struct bcm_enet_desc *desc;
+
+               if (!priv->rx_skb[i])
+                       continue;
+
+               desc = &priv->rx_desc_cpu[i];
+               dma_unmap_single(kdev, desc->address, priv->rx_skb_size,
+                                DMA_FROM_DEVICE);
+               kfree_skb(priv->rx_skb[i]);
+       }
+       kfree(priv->rx_skb);
+
+out_free_tx_skb:
+       kfree(priv->tx_skb);
+
+out_free_tx_ring:
+       dma_free_coherent(kdev, priv->tx_desc_alloc_size,
+                         priv->tx_desc_cpu, priv->tx_desc_dma);
+
+out_free_rx_ring:
+       dma_free_coherent(kdev, priv->rx_desc_alloc_size,
+                         priv->rx_desc_cpu, priv->rx_desc_dma);
+
+out_freeirq_tx:
+       free_irq(priv->irq_tx, dev);
+
+out_freeirq_rx:
+       free_irq(priv->irq_rx, dev);
+
+out_freeirq:
+       free_irq(dev->irq, dev);
+
+out_phy_disconnect:
+       phy_disconnect(priv->phydev);
+
+       return ret;
+}
+
+/*
+ * disable mac
+ */
+static void bcm_enet_disable_mac(struct bcm_enet_priv *priv)
+{
+       int limit;
+       u32 val;
+
+       val = enet_readl(priv, ENET_CTL_REG);
+       val |= ENET_CTL_DISABLE_MASK;
+       enet_writel(priv, val, ENET_CTL_REG);
+
+       limit = 1000;
+       do {
+               u32 val;
+
+               val = enet_readl(priv, ENET_CTL_REG);
+               if (!(val & ENET_CTL_DISABLE_MASK))
+                       break;
+               udelay(1);
+       } while (limit--);
+}
+
+/*
+ * disable dma in given channel
+ */
+static void bcm_enet_disable_dma(struct bcm_enet_priv *priv, int chan)
+{
+       int limit;
+
+       enet_dma_writel(priv, 0, ENETDMA_CHANCFG_REG(chan));
+
+       limit = 1000;
+       do {
+               u32 val;
+
+               val = enet_dma_readl(priv, ENETDMA_CHANCFG_REG(chan));
+               if (!(val & ENETDMA_CHANCFG_EN_MASK))
+                       break;
+               udelay(1);
+       } while (limit--);
+}
+
+/*
+ * stop callback
+ */
+static int bcm_enet_stop(struct net_device *dev)
+{
+       struct bcm_enet_priv *priv;
+       struct device *kdev;
+       int i;
+
+       priv = netdev_priv(dev);
+       kdev = &priv->pdev->dev;
+
+       netif_stop_queue(dev);
+       napi_disable(&priv->napi);
+       if (priv->has_phy)
+               phy_stop(priv->phydev);
+       del_timer_sync(&priv->rx_timeout);
+
+       /* mask all interrupts */
+       enet_writel(priv, 0, ENET_IRMASK_REG);
+       enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->rx_chan));
+       enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan));
+
+       /* make sure no mib update is scheduled */
+       flush_scheduled_work();
+
+       /* disable dma & mac */
+       bcm_enet_disable_dma(priv, priv->tx_chan);
+       bcm_enet_disable_dma(priv, priv->rx_chan);
+       bcm_enet_disable_mac(priv);
+
+       /* force reclaim of all tx buffers */
+       bcm_enet_tx_reclaim(dev, 1);
+
+       /* free the rx skb ring */
+       for (i = 0; i < priv->rx_ring_size; i++) {
+               struct bcm_enet_desc *desc;
+
+               if (!priv->rx_skb[i])
+                       continue;
+
+               desc = &priv->rx_desc_cpu[i];
+               dma_unmap_single(kdev, desc->address, priv->rx_skb_size,
+                                DMA_FROM_DEVICE);
+               kfree_skb(priv->rx_skb[i]);
+       }
+
+       /* free remaining allocated memory */
+       kfree(priv->rx_skb);
+       kfree(priv->tx_skb);
+       dma_free_coherent(kdev, priv->rx_desc_alloc_size,
+                         priv->rx_desc_cpu, priv->rx_desc_dma);
+       dma_free_coherent(kdev, priv->tx_desc_alloc_size,
+                         priv->tx_desc_cpu, priv->tx_desc_dma);
+       free_irq(priv->irq_tx, dev);
+       free_irq(priv->irq_rx, dev);
+       free_irq(dev->irq, dev);
+
+       /* release phy */
+       if (priv->has_phy) {
+               phy_disconnect(priv->phydev);
+               priv->phydev = NULL;
+       }
+
+       return 0;
+}
+
+/*
+ * core request to return device rx/tx stats
+ */
+static struct net_device_stats *bcm_enet_get_stats(struct net_device *dev)
+{
+       struct bcm_enet_priv *priv;
+
+       priv = netdev_priv(dev);
+       return &priv->stats;
+}
+
+/*
+ * ethtool callbacks
+ */
+struct bcm_enet_stats {
+       char stat_string[ETH_GSTRING_LEN];
+       int sizeof_stat;
+       int stat_offset;
+       int mib_reg;
+};
+
+#define GEN_STAT(m) sizeof(((struct bcm_enet_priv *)0)->m),            \
+                    offsetof(struct bcm_enet_priv, m)
+
+static const struct bcm_enet_stats bcm_enet_gstrings_stats[] = {
+       { "rx_packets", GEN_STAT(stats.rx_packets), -1 },
+       { "tx_packets", GEN_STAT(stats.tx_packets), -1 },
+       { "rx_bytes", GEN_STAT(stats.rx_bytes), -1 },
+       { "tx_bytes", GEN_STAT(stats.tx_bytes), -1 },
+       { "rx_errors", GEN_STAT(stats.rx_errors), -1 },
+       { "tx_errors", GEN_STAT(stats.tx_errors), -1 },
+       { "rx_dropped", GEN_STAT(stats.rx_dropped), -1 },
+       { "tx_dropped", GEN_STAT(stats.tx_dropped), -1 },
+
+       { "rx_good_octets", GEN_STAT(mib.rx_gd_octets), ETH_MIB_RX_GD_OCTETS},
+       { "rx_good_pkts", GEN_STAT(mib.rx_gd_pkts), ETH_MIB_RX_GD_PKTS },
+       { "rx_broadcast", GEN_STAT(mib.rx_brdcast), ETH_MIB_RX_BRDCAST },
+       { "rx_multicast", GEN_STAT(mib.rx_mult), ETH_MIB_RX_MULT },
+       { "rx_64_octets", GEN_STAT(mib.rx_64), ETH_MIB_RX_64 },
+       { "rx_65_127_oct", GEN_STAT(mib.rx_65_127), ETH_MIB_RX_65_127 },
+       { "rx_128_255_oct", GEN_STAT(mib.rx_128_255), ETH_MIB_RX_128_255 },
+       { "rx_256_511_oct", GEN_STAT(mib.rx_256_511), ETH_MIB_RX_256_511 },
+       { "rx_512_1023_oct", GEN_STAT(mib.rx_512_1023), ETH_MIB_RX_512_1023 },
+       { "rx_1024_max_oct", GEN_STAT(mib.rx_1024_max), ETH_MIB_RX_1024_MAX },
+       { "rx_jabber", GEN_STAT(mib.rx_jab), ETH_MIB_RX_JAB },
+       { "rx_oversize", GEN_STAT(mib.rx_ovr), ETH_MIB_RX_OVR },
+       { "rx_fragment", GEN_STAT(mib.rx_frag), ETH_MIB_RX_FRAG },
+       { "rx_dropped", GEN_STAT(mib.rx_drop), ETH_MIB_RX_DROP },
+       { "rx_crc_align", GEN_STAT(mib.rx_crc_align), ETH_MIB_RX_CRC_ALIGN },
+       { "rx_undersize", GEN_STAT(mib.rx_und), ETH_MIB_RX_UND },
+       { "rx_crc", GEN_STAT(mib.rx_crc), ETH_MIB_RX_CRC },
+       { "rx_align", GEN_STAT(mib.rx_align), ETH_MIB_RX_ALIGN },
+       { "rx_symbol_error", GEN_STAT(mib.rx_sym), ETH_MIB_RX_SYM },
+       { "rx_pause", GEN_STAT(mib.rx_pause), ETH_MIB_RX_PAUSE },
+       { "rx_control", GEN_STAT(mib.rx_cntrl), ETH_MIB_RX_CNTRL },
+
+       { "tx_good_octets", GEN_STAT(mib.tx_gd_octets), ETH_MIB_TX_GD_OCTETS },
+       { "tx_good_pkts", GEN_STAT(mib.tx_gd_pkts), ETH_MIB_TX_GD_PKTS },
+       { "tx_broadcast", GEN_STAT(mib.tx_brdcast), ETH_MIB_TX_BRDCAST },
+       { "tx_multicast", GEN_STAT(mib.tx_mult), ETH_MIB_TX_MULT },
+       { "tx_64_oct", GEN_STAT(mib.tx_64), ETH_MIB_TX_64 },
+       { "tx_65_127_oct", GEN_STAT(mib.tx_65_127), ETH_MIB_TX_65_127 },
+       { "tx_128_255_oct", GEN_STAT(mib.tx_128_255), ETH_MIB_TX_128_255 },
+       { "tx_256_511_oct", GEN_STAT(mib.tx_256_511), ETH_MIB_TX_256_511 },
+       { "tx_512_1023_oct", GEN_STAT(mib.tx_512_1023), ETH_MIB_TX_512_1023},
+       { "tx_1024_max_oct", GEN_STAT(mib.tx_1024_max), ETH_MIB_TX_1024_MAX },
+       { "tx_jabber", GEN_STAT(mib.tx_jab), ETH_MIB_TX_JAB },
+       { "tx_oversize", GEN_STAT(mib.tx_ovr), ETH_MIB_TX_OVR },
+       { "tx_fragment", GEN_STAT(mib.tx_frag), ETH_MIB_TX_FRAG },
+       { "tx_underrun", GEN_STAT(mib.tx_underrun), ETH_MIB_TX_UNDERRUN },
+       { "tx_collisions", GEN_STAT(mib.tx_col), ETH_MIB_TX_COL },
+       { "tx_single_collision", GEN_STAT(mib.tx_1_col), ETH_MIB_TX_1_COL },
+       { "tx_multiple_collision", GEN_STAT(mib.tx_m_col), ETH_MIB_TX_M_COL },
+       { "tx_excess_collision", GEN_STAT(mib.tx_ex_col), ETH_MIB_TX_EX_COL },
+       { "tx_late_collision", GEN_STAT(mib.tx_late), ETH_MIB_TX_LATE },
+       { "tx_deferred", GEN_STAT(mib.tx_def), ETH_MIB_TX_DEF },
+       { "tx_carrier_sense", GEN_STAT(mib.tx_crs), ETH_MIB_TX_CRS },
+       { "tx_pause", GEN_STAT(mib.tx_pause), ETH_MIB_TX_PAUSE },
+
+};
+
+#define BCM_ENET_STATS_LEN     \
+       (sizeof(bcm_enet_gstrings_stats) / sizeof(struct bcm_enet_stats))
+
+static const u32 unused_mib_regs[] = {
+       ETH_MIB_TX_ALL_OCTETS,
+       ETH_MIB_TX_ALL_PKTS,
+       ETH_MIB_RX_ALL_OCTETS,
+       ETH_MIB_RX_ALL_PKTS,
+};
+
+
+static void bcm_enet_get_drvinfo(struct net_device *netdev,
+                                struct ethtool_drvinfo *drvinfo)
+{
+       strncpy(drvinfo->driver, bcm_enet_driver_name, 32);
+       strncpy(drvinfo->version, bcm_enet_driver_version, 32);
+       strncpy(drvinfo->fw_version, "N/A", 32);
+       strncpy(drvinfo->bus_info, "bcm63xx", 32);
+       drvinfo->n_stats = BCM_ENET_STATS_LEN;
+}
+
+static int bcm_enet_get_stats_count(struct net_device *netdev)
+{
+       return BCM_ENET_STATS_LEN;
+}
+
+static void bcm_enet_get_strings(struct net_device *netdev,
+                                u32 stringset, u8 *data)
+{
+       int i;
+
+       switch (stringset) {
+       case ETH_SS_STATS:
+               for (i = 0; i < BCM_ENET_STATS_LEN; i++) {
+                       memcpy(data + i * ETH_GSTRING_LEN,
+                              bcm_enet_gstrings_stats[i].stat_string,
+                              ETH_GSTRING_LEN);
+               }
+               break;
+       }
+}
+
+static void update_mib_counters(struct bcm_enet_priv *priv)
+{
+       int i;
+
+       for (i = 0; i < BCM_ENET_STATS_LEN; i++) {
+               const struct bcm_enet_stats *s;
+               u32 val;
+               char *p;
+
+               s = &bcm_enet_gstrings_stats[i];
+               if (s->mib_reg == -1)
+                       continue;
+
+               val = enet_readl(priv, ENET_MIB_REG(s->mib_reg));
+               p = (char *)priv + s->stat_offset;
+
+               if (s->sizeof_stat == sizeof(u64))
+                       *(u64 *)p += val;
+               else
+                       *(u32 *)p += val;
+       }
+
+       /* also empty unused mib counters to make sure mib counter
+        * overflow interrupt is cleared */
+       for (i = 0; i < ARRAY_SIZE(unused_mib_regs); i++)
+               (void)enet_readl(priv, ENET_MIB_REG(unused_mib_regs[i]));
+}
+
+static void bcm_enet_update_mib_counters_defer(struct work_struct *t)
+{
+       struct bcm_enet_priv *priv;
+
+       priv = container_of(t, struct bcm_enet_priv, mib_update_task);
+       mutex_lock(&priv->mib_update_lock);
+       update_mib_counters(priv);
+       mutex_unlock(&priv->mib_update_lock);
+
+       /* reenable mib interrupt */
+       if (netif_running(priv->net_dev))
+               enet_writel(priv, ENET_IR_MIB, ENET_IRMASK_REG);
+}
+
+static void bcm_enet_get_ethtool_stats(struct net_device *netdev,
+                                      struct ethtool_stats *stats,
+                                      u64 *data)
+{
+       struct bcm_enet_priv *priv;
+       int i;
+
+       priv = netdev_priv(netdev);
+
+       mutex_lock(&priv->mib_update_lock);
+       update_mib_counters(priv);
+
+       for (i = 0; i < BCM_ENET_STATS_LEN; i++) {
+               const struct bcm_enet_stats *s;
+               char *p;
+
+               s = &bcm_enet_gstrings_stats[i];
+               p = (char *)priv + s->stat_offset;
+               data[i] = (s->sizeof_stat == sizeof(u64)) ?
+                       *(u64 *)p : *(u32 *)p;
+       }
+       mutex_unlock(&priv->mib_update_lock);
+}
+
+static int bcm_enet_get_settings(struct net_device *dev,
+                                struct ethtool_cmd *cmd)
+{
+       struct bcm_enet_priv *priv;
+
+       priv = netdev_priv(dev);
+
+       cmd->maxrxpkt = 0;
+       cmd->maxtxpkt = 0;
+
+       if (priv->has_phy) {
+               if (!priv->phydev)
+                       return -ENODEV;
+               return phy_ethtool_gset(priv->phydev, cmd);
+       } else {
+               cmd->autoneg = 0;
+               cmd->speed = (priv->force_speed_100) ? SPEED_100 : SPEED_10;
+               cmd->duplex = (priv->force_duplex_full) ?
+                       DUPLEX_FULL : DUPLEX_HALF;
+               cmd->supported = ADVERTISED_10baseT_Half  |
+                       ADVERTISED_10baseT_Full |
+                       ADVERTISED_100baseT_Half |
+                       ADVERTISED_100baseT_Full;
+               cmd->advertising = 0;
+               cmd->port = PORT_MII;
+               cmd->transceiver = XCVR_EXTERNAL;
+       }
+       return 0;
+}
+
+static int bcm_enet_set_settings(struct net_device *dev,
+                                struct ethtool_cmd *cmd)
+{
+       struct bcm_enet_priv *priv;
+
+       priv = netdev_priv(dev);
+       if (priv->has_phy) {
+               if (!priv->phydev)
+                       return -ENODEV;
+               return phy_ethtool_sset(priv->phydev, cmd);
+       } else {
+
+               if (cmd->autoneg ||
+                   (cmd->speed != SPEED_100 && cmd->speed != SPEED_10) ||
+                   cmd->port != PORT_MII)
+                       return -EINVAL;
+
+               priv->force_speed_100 = (cmd->speed == SPEED_100) ? 1 : 0;
+               priv->force_duplex_full = (cmd->duplex == DUPLEX_FULL) ? 1 : 0;
+
+               if (netif_running(dev))
+                       bcm_enet_adjust_link(dev);
+               return 0;
+       }
+}
+
+static void bcm_enet_get_ringparam(struct net_device *dev,
+                                  struct ethtool_ringparam *ering)
+{
+       struct bcm_enet_priv *priv;
+
+       priv = netdev_priv(dev);
+
+       /* rx/tx ring is actually only limited by memory */
+       ering->rx_max_pending = 8192;
+       ering->tx_max_pending = 8192;
+       ering->rx_mini_max_pending = 0;
+       ering->rx_jumbo_max_pending = 0;
+       ering->rx_pending = priv->rx_ring_size;
+       ering->tx_pending = priv->tx_ring_size;
+}
+
+static int bcm_enet_set_ringparam(struct net_device *dev,
+                                 struct ethtool_ringparam *ering)
+{
+       struct bcm_enet_priv *priv;
+       int was_running;
+
+       priv = netdev_priv(dev);
+
+       was_running = 0;
+       if (netif_running(dev)) {
+               bcm_enet_stop(dev);
+               was_running = 1;
+       }
+
+       priv->rx_ring_size = ering->rx_pending;
+       priv->tx_ring_size = ering->tx_pending;
+
+       if (was_running) {
+               int err;
+
+               err = bcm_enet_open(dev);
+               if (err)
+                       dev_close(dev);
+               else
+                       bcm_enet_set_multicast_list(dev);
+       }
+       return 0;
+}
+
+static void bcm_enet_get_pauseparam(struct net_device *dev,
+                                   struct ethtool_pauseparam *ecmd)
+{
+       struct bcm_enet_priv *priv;
+
+       priv = netdev_priv(dev);
+       ecmd->autoneg = priv->pause_auto;
+       ecmd->rx_pause = priv->pause_rx;
+       ecmd->tx_pause = priv->pause_tx;
+}
+
+static int bcm_enet_set_pauseparam(struct net_device *dev,
+                                  struct ethtool_pauseparam *ecmd)
+{
+       struct bcm_enet_priv *priv;
+
+       priv = netdev_priv(dev);
+
+       if (priv->has_phy) {
+               if (ecmd->autoneg && (ecmd->rx_pause != ecmd->tx_pause)) {
+                       /* asymetric pause mode not supported,
+                        * actually possible but integrated PHY has RO
+                        * asym_pause bit */
+                       return -EINVAL;
+               }
+       } else {
+               /* no pause autoneg on direct mii connection */
+               if (ecmd->autoneg)
+                       return -EINVAL;
+       }
+
+       priv->pause_auto = ecmd->autoneg;
+       priv->pause_rx = ecmd->rx_pause;
+       priv->pause_tx = ecmd->tx_pause;
+
+       return 0;
+}
+
+static struct ethtool_ops bcm_enet_ethtool_ops = {
+       .get_strings            = bcm_enet_get_strings,
+       .get_stats_count        = bcm_enet_get_stats_count,
+       .get_ethtool_stats      = bcm_enet_get_ethtool_stats,
+       .get_settings           = bcm_enet_get_settings,
+       .set_settings           = bcm_enet_set_settings,
+       .get_drvinfo            = bcm_enet_get_drvinfo,
+       .get_link               = ethtool_op_get_link,
+       .get_ringparam          = bcm_enet_get_ringparam,
+       .set_ringparam          = bcm_enet_set_ringparam,
+       .get_pauseparam         = bcm_enet_get_pauseparam,
+       .set_pauseparam         = bcm_enet_set_pauseparam,
+};
+
+static int bcm_enet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+       struct bcm_enet_priv *priv;
+
+       priv = netdev_priv(dev);
+       if (priv->has_phy) {
+               if (!priv->phydev)
+                       return -ENODEV;
+               return phy_mii_ioctl(priv->phydev, if_mii(rq), cmd);
+       } else {
+               struct mii_if_info mii;
+
+               mii.dev = dev;
+               mii.mdio_read = bcm_enet_mdio_read_mii;
+               mii.mdio_write = bcm_enet_mdio_write_mii;
+               mii.phy_id = 0;
+               mii.phy_id_mask = 0x3f;
+               mii.reg_num_mask = 0x1f;
+               return generic_mii_ioctl(&mii, if_mii(rq), cmd, NULL);
+       }
+}
+
+/*
+ * calculate actual hardware mtu
+ */
+static int compute_hw_mtu(struct bcm_enet_priv *priv, int mtu)
+{
+       int actual_mtu;
+
+       actual_mtu = mtu;
+
+       /* add ethernet header + vlan tag size */
+       actual_mtu += VLAN_ETH_HLEN;
+
+       if (actual_mtu < 64 || actual_mtu > BCMENET_MAX_MTU)
+               return -EINVAL;
+
+       /*
+        * setup maximum size before we get overflow mark in
+        * descriptor, note that this will not prevent reception of
+        * big frames, they will be split into multiple buffers
+        * anyway
+        */
+       priv->hw_mtu = actual_mtu;
+
+       /*
+        * align rx buffer size to dma burst len, account FCS since
+        * it's appended
+        */
+       priv->rx_skb_size = ALIGN(actual_mtu + ETH_FCS_LEN,
+                                 BCMENET_DMA_MAXBURST * 4);
+       return 0;
+}
+
+/*
+ * adjust mtu, can't be called while device is running
+ */
+static int bcm_enet_change_mtu(struct net_device *dev, int new_mtu)
+{
+       int ret;
+
+       if (netif_running(dev))
+               return -EBUSY;
+
+       ret = compute_hw_mtu(netdev_priv(dev), new_mtu);
+       if (ret)
+               return ret;
+       dev->mtu = new_mtu;
+       return 0;
+}
+
+/*
+ * preinit hardware to allow mii operation while device is down
+ */
+static void bcm_enet_hw_preinit(struct bcm_enet_priv *priv)
+{
+       u32 val;
+       int limit;
+
+       /* make sure mac is disabled */
+       bcm_enet_disable_mac(priv);
+
+       /* soft reset mac */
+       val = ENET_CTL_SRESET_MASK;
+       enet_writel(priv, val, ENET_CTL_REG);
+       wmb();
+
+       limit = 1000;
+       do {
+               val = enet_readl(priv, ENET_CTL_REG);
+               if (!(val & ENET_CTL_SRESET_MASK))
+                       break;
+               udelay(1);
+       } while (limit--);
+
+       /* select correct mii interface */
+       val = enet_readl(priv, ENET_CTL_REG);
+       if (priv->use_external_mii)
+               val |= ENET_CTL_EPHYSEL_MASK;
+       else
+               val &= ~ENET_CTL_EPHYSEL_MASK;
+       enet_writel(priv, val, ENET_CTL_REG);
+
+       /* turn on mdc clock */
+       enet_writel(priv, (0x1f << ENET_MIISC_MDCFREQDIV_SHIFT) |
+                   ENET_MIISC_PREAMBLEEN_MASK, ENET_MIISC_REG);
+
+       /* set mib counters to self-clear when read */
+       val = enet_readl(priv, ENET_MIBCTL_REG);
+       val |= ENET_MIBCTL_RDCLEAR_MASK;
+       enet_writel(priv, val, ENET_MIBCTL_REG);
+}
+
+static const struct net_device_ops bcm_enet_ops = {
+       .ndo_open               = bcm_enet_open,
+       .ndo_stop               = bcm_enet_stop,
+       .ndo_start_xmit         = bcm_enet_start_xmit,
+       .ndo_get_stats          = bcm_enet_get_stats,
+       .ndo_set_mac_address    = bcm_enet_set_mac_address,
+       .ndo_set_multicast_list = bcm_enet_set_multicast_list,
+       .ndo_do_ioctl           = bcm_enet_ioctl,
+       .ndo_change_mtu         = bcm_enet_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller = bcm_enet_netpoll,
+#endif
+};
+
+/*
+ * allocate netdevice, request register memory and register device.
+ */
+static int __devinit bcm_enet_probe(struct platform_device *pdev)
+{
+       struct bcm_enet_priv *priv;
+       struct net_device *dev;
+       struct bcm63xx_enet_platform_data *pd;
+       struct resource *res_mem, *res_irq, *res_irq_rx, *res_irq_tx;
+       struct mii_bus *bus;
+       const char *clk_name;
+       unsigned int iomem_size;
+       int i, ret;
+
+       /* stop if shared driver failed, assume driver->probe will be
+        * called in the same order we register devices (correct ?) */
+       if (!bcm_enet_shared_base)
+               return -ENODEV;
+
+       res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       res_irq_rx = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
+       res_irq_tx = platform_get_resource(pdev, IORESOURCE_IRQ, 2);
+       if (!res_mem || !res_irq || !res_irq_rx || !res_irq_tx)
+               return -ENODEV;
+
+       ret = 0;
+       dev = alloc_etherdev(sizeof(*priv));
+       if (!dev)
+               return -ENOMEM;
+       priv = netdev_priv(dev);
+       memset(priv, 0, sizeof(*priv));
+
+       ret = compute_hw_mtu(priv, dev->mtu);
+       if (ret)
+               goto out;
+
+       iomem_size = res_mem->end - res_mem->start + 1;
+       if (!request_mem_region(res_mem->start, iomem_size, "bcm63xx_enet")) {
+               ret = -EBUSY;
+               goto out;
+       }
+
+       priv->base = ioremap(res_mem->start, iomem_size);
+       if (priv->base == NULL) {
+               ret = -ENOMEM;
+               goto out_release_mem;
+       }
+       dev->irq = priv->irq = res_irq->start;
+       priv->irq_rx = res_irq_rx->start;
+       priv->irq_tx = res_irq_tx->start;
+       priv->mac_id = pdev->id;
+
+       /* get rx & tx dma channel id for this mac */
+       if (priv->mac_id == 0) {
+               priv->rx_chan = 0;
+               priv->tx_chan = 1;
+               clk_name = "enet0";
+       } else {
+               priv->rx_chan = 2;
+               priv->tx_chan = 3;
+               clk_name = "enet1";
+       }
+
+       priv->mac_clk = clk_get(&pdev->dev, clk_name);
+       if (IS_ERR(priv->mac_clk)) {
+               ret = PTR_ERR(priv->mac_clk);
+               goto out_unmap;
+       }
+       clk_enable(priv->mac_clk);
+
+       /* initialize default and fetch platform data */
+       priv->rx_ring_size = BCMENET_DEF_RX_DESC;
+       priv->tx_ring_size = BCMENET_DEF_TX_DESC;
+
+       pd = pdev->dev.platform_data;
+       if (pd) {
+               memcpy(dev->dev_addr, pd->mac_addr, ETH_ALEN);
+               priv->has_phy = pd->has_phy;
+               priv->phy_id = pd->phy_id;
+               priv->has_phy_interrupt = pd->has_phy_interrupt;
+               priv->phy_interrupt = pd->phy_interrupt;
+               priv->use_external_mii = !pd->use_internal_phy;
+               priv->pause_auto = pd->pause_auto;
+               priv->pause_rx = pd->pause_rx;
+               priv->pause_tx = pd->pause_tx;
+               priv->force_duplex_full = pd->force_duplex_full;
+               priv->force_speed_100 = pd->force_speed_100;
+       }
+
+       if (priv->mac_id == 0 && priv->has_phy && !priv->use_external_mii) {
+               /* using internal PHY, enable clock */
+               priv->phy_clk = clk_get(&pdev->dev, "ephy");
+               if (IS_ERR(priv->phy_clk)) {
+                       ret = PTR_ERR(priv->phy_clk);
+                       priv->phy_clk = NULL;
+                       goto out_put_clk_mac;
+               }
+               clk_enable(priv->phy_clk);
+       }
+
+       /* do minimal hardware init to be able to probe mii bus */
+       bcm_enet_hw_preinit(priv);
+
+       /* MII bus registration */
+       if (priv->has_phy) {
+
+               priv->mii_bus = mdiobus_alloc();
+               if (!priv->mii_bus) {
+                       ret = -ENOMEM;
+                       goto out_uninit_hw;
+               }
+
+               bus = priv->mii_bus;
+               bus->name = "bcm63xx_enet MII bus";
+               bus->parent = &pdev->dev;
+               bus->priv = priv;
+               bus->read = bcm_enet_mdio_read_phylib;
+               bus->write = bcm_enet_mdio_write_phylib;
+               sprintf(bus->id, "%d", priv->mac_id);
+
+               /* only probe bus where we think the PHY is, because
+                * the mdio read operation return 0 instead of 0xffff
+                * if a slave is not present on hw */
+               bus->phy_mask = ~(1 << priv->phy_id);
+
+               bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
+               if (!bus->irq) {
+                       ret = -ENOMEM;
+                       goto out_free_mdio;
+               }
+
+               if (priv->has_phy_interrupt)
+                       bus->irq[priv->phy_id] = priv->phy_interrupt;
+               else
+                       bus->irq[priv->phy_id] = PHY_POLL;
+
+               ret = mdiobus_register(bus);
+               if (ret) {
+                       dev_err(&pdev->dev, "unable to register mdio bus\n");
+                       goto out_free_mdio;
+               }
+       } else {
+
+               /* run platform code to initialize PHY device */
+               if (pd->mii_config &&
+                   pd->mii_config(dev, 1, bcm_enet_mdio_read_mii,
+                                  bcm_enet_mdio_write_mii)) {
+                       dev_err(&pdev->dev, "unable to configure mdio bus\n");
+                       goto out_uninit_hw;
+               }
+       }
+
+       spin_lock_init(&priv->rx_lock);
+
+       /* init rx timeout (used for oom) */
+       init_timer(&priv->rx_timeout);
+       priv->rx_timeout.function = bcm_enet_refill_rx_timer;
+       priv->rx_timeout.data = (unsigned long)dev;
+
+       /* init the mib update lock&work */
+       mutex_init(&priv->mib_update_lock);
+       INIT_WORK(&priv->mib_update_task, bcm_enet_update_mib_counters_defer);
+
+       /* zero mib counters */
+       for (i = 0; i < ENET_MIB_REG_COUNT; i++)
+               enet_writel(priv, 0, ENET_MIB_REG(i));
+
+       /* register netdevice */
+       dev->netdev_ops = &bcm_enet_ops;
+       netif_napi_add(dev, &priv->napi, bcm_enet_poll, 16);
+
+       SET_ETHTOOL_OPS(dev, &bcm_enet_ethtool_ops);
+       SET_NETDEV_DEV(dev, &pdev->dev);
+
+       ret = register_netdev(dev);
+       if (ret)
+               goto out_unregister_mdio;
+
+       netif_carrier_off(dev);
+       platform_set_drvdata(pdev, dev);
+       priv->pdev = pdev;
+       priv->net_dev = dev;
+
+       return 0;
+
+out_unregister_mdio:
+       if (priv->mii_bus) {
+               mdiobus_unregister(priv->mii_bus);
+               kfree(priv->mii_bus->irq);
+       }
+
+out_free_mdio:
+       if (priv->mii_bus)
+               mdiobus_free(priv->mii_bus);
+
+out_uninit_hw:
+       /* turn off mdc clock */
+       enet_writel(priv, 0, ENET_MIISC_REG);
+       if (priv->phy_clk) {
+               clk_disable(priv->phy_clk);
+               clk_put(priv->phy_clk);
+       }
+
+out_put_clk_mac:
+       clk_disable(priv->mac_clk);
+       clk_put(priv->mac_clk);
+
+out_unmap:
+       iounmap(priv->base);
+
+out_release_mem:
+       release_mem_region(res_mem->start, iomem_size);
+out:
+       free_netdev(dev);
+       return ret;
+}
+
+
+/*
+ * exit func, stops hardware and unregisters netdevice
+ */
+static int __devexit bcm_enet_remove(struct platform_device *pdev)
+{
+       struct bcm_enet_priv *priv;
+       struct net_device *dev;
+       struct resource *res;
+
+       /* stop netdevice */
+       dev = platform_get_drvdata(pdev);
+       priv = netdev_priv(dev);
+       unregister_netdev(dev);
+
+       /* turn off mdc clock */
+       enet_writel(priv, 0, ENET_MIISC_REG);
+
+       if (priv->has_phy) {
+               mdiobus_unregister(priv->mii_bus);
+               kfree(priv->mii_bus->irq);
+               mdiobus_free(priv->mii_bus);
+       } else {
+               struct bcm63xx_enet_platform_data *pd;
+
+               pd = pdev->dev.platform_data;
+               if (pd && pd->mii_config)
+                       pd->mii_config(dev, 0, bcm_enet_mdio_read_mii,
+                                      bcm_enet_mdio_write_mii);
+       }
+
+       /* release device resources */
+       iounmap(priv->base);
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       release_mem_region(res->start, res->end - res->start + 1);
+
+       /* disable hw block clocks */
+       if (priv->phy_clk) {
+               clk_disable(priv->phy_clk);
+               clk_put(priv->phy_clk);
+       }
+       clk_disable(priv->mac_clk);
+       clk_put(priv->mac_clk);
+
+       platform_set_drvdata(pdev, NULL);
+       free_netdev(dev);
+       return 0;
+}
+
+struct platform_driver bcm63xx_enet_driver = {
+       .probe  = bcm_enet_probe,
+       .remove = __devexit_p(bcm_enet_remove),
+       .driver = {
+               .name   = "bcm63xx_enet",
+               .owner  = THIS_MODULE,
+       },
+};
+
+/*
+ * reserve & remap memory space shared between all macs
+ */
+static int __devinit bcm_enet_shared_probe(struct platform_device *pdev)
+{
+       struct resource *res;
+       unsigned int iomem_size;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res)
+               return -ENODEV;
+
+       iomem_size = res->end - res->start + 1;
+       if (!request_mem_region(res->start, iomem_size, "bcm63xx_enet_dma"))
+               return -EBUSY;
+
+       bcm_enet_shared_base = ioremap(res->start, iomem_size);
+       if (!bcm_enet_shared_base) {
+               release_mem_region(res->start, iomem_size);
+               return -ENOMEM;
+       }
+       return 0;
+}
+
+static int __devexit bcm_enet_shared_remove(struct platform_device *pdev)
+{
+       struct resource *res;
+
+       iounmap(bcm_enet_shared_base);
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       release_mem_region(res->start, res->end - res->start + 1);
+       return 0;
+}
+
+/*
+ * this "shared" driver is needed because both macs share a single
+ * address space
+ */
+struct platform_driver bcm63xx_enet_shared_driver = {
+       .probe  = bcm_enet_shared_probe,
+       .remove = __devexit_p(bcm_enet_shared_remove),
+       .driver = {
+               .name   = "bcm63xx_enet_shared",
+               .owner  = THIS_MODULE,
+       },
+};
+
+/*
+ * entry point
+ */
+static int __init bcm_enet_init(void)
+{
+       int ret;
+
+       ret = platform_driver_register(&bcm63xx_enet_shared_driver);
+       if (ret)
+               return ret;
+
+       ret = platform_driver_register(&bcm63xx_enet_driver);
+       if (ret)
+               platform_driver_unregister(&bcm63xx_enet_shared_driver);
+
+       return ret;
+}
+
+static void __exit bcm_enet_exit(void)
+{
+       platform_driver_unregister(&bcm63xx_enet_driver);
+       platform_driver_unregister(&bcm63xx_enet_shared_driver);
+}
+
+
+module_init(bcm_enet_init);
+module_exit(bcm_enet_exit);
+
+MODULE_DESCRIPTION("BCM63xx internal ethernet mac driver");
+MODULE_AUTHOR("Maxime Bizon <mbizon@freebox.fr>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/bcm63xx_enet.h b/drivers/net/bcm63xx_enet.h
new file mode 100644 (file)
index 0000000..bd3684d
--- /dev/null
@@ -0,0 +1,303 @@
+#ifndef BCM63XX_ENET_H_
+#define BCM63XX_ENET_H_
+
+#include <linux/types.h>
+#include <linux/mii.h>
+#include <linux/mutex.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
+
+#include <bcm63xx_regs.h>
+#include <bcm63xx_irq.h>
+#include <bcm63xx_io.h>
+
+/* default number of descriptor */
+#define BCMENET_DEF_RX_DESC    64
+#define BCMENET_DEF_TX_DESC    32
+
+/* maximum burst len for dma (4 bytes unit) */
+#define BCMENET_DMA_MAXBURST   16
+
+/* tx transmit threshold (4 bytes unit), fifo is 256 bytes, the value
+ * must be low enough so that a DMA transfer of above burst length can
+ * not overflow the fifo  */
+#define BCMENET_TX_FIFO_TRESH  32
+
+/*
+ * hardware maximum rx/tx packet size including FCS, max mtu is
+ * actually 2047, but if we set max rx size register to 2047 we won't
+ * get overflow information if packet size is 2048 or above
+ */
+#define BCMENET_MAX_MTU                2046
+
+/*
+ * rx/tx dma descriptor
+ */
+struct bcm_enet_desc {
+       u32 len_stat;
+       u32 address;
+};
+
+#define DMADESC_LENGTH_SHIFT   16
+#define DMADESC_LENGTH_MASK    (0xfff << DMADESC_LENGTH_SHIFT)
+#define DMADESC_OWNER_MASK     (1 << 15)
+#define DMADESC_EOP_MASK       (1 << 14)
+#define DMADESC_SOP_MASK       (1 << 13)
+#define DMADESC_ESOP_MASK      (DMADESC_EOP_MASK | DMADESC_SOP_MASK)
+#define DMADESC_WRAP_MASK      (1 << 12)
+
+#define DMADESC_UNDER_MASK     (1 << 9)
+#define DMADESC_APPEND_CRC     (1 << 8)
+#define DMADESC_OVSIZE_MASK    (1 << 4)
+#define DMADESC_RXER_MASK      (1 << 2)
+#define DMADESC_CRC_MASK       (1 << 1)
+#define DMADESC_OV_MASK                (1 << 0)
+#define DMADESC_ERR_MASK       (DMADESC_UNDER_MASK | \
+                               DMADESC_OVSIZE_MASK | \
+                               DMADESC_RXER_MASK | \
+                               DMADESC_CRC_MASK | \
+                               DMADESC_OV_MASK)
+
+
+/*
+ * MIB Counters register definitions
+*/
+#define ETH_MIB_TX_GD_OCTETS                   0
+#define ETH_MIB_TX_GD_PKTS                     1
+#define ETH_MIB_TX_ALL_OCTETS                  2
+#define ETH_MIB_TX_ALL_PKTS                    3
+#define ETH_MIB_TX_BRDCAST                     4
+#define ETH_MIB_TX_MULT                                5
+#define ETH_MIB_TX_64                          6
+#define ETH_MIB_TX_65_127                      7
+#define ETH_MIB_TX_128_255                     8
+#define ETH_MIB_TX_256_511                     9
+#define ETH_MIB_TX_512_1023                    10
+#define ETH_MIB_TX_1024_MAX                    11
+#define ETH_MIB_TX_JAB                         12
+#define ETH_MIB_TX_OVR                         13
+#define ETH_MIB_TX_FRAG                                14
+#define ETH_MIB_TX_UNDERRUN                    15
+#define ETH_MIB_TX_COL                         16
+#define ETH_MIB_TX_1_COL                       17
+#define ETH_MIB_TX_M_COL                       18
+#define ETH_MIB_TX_EX_COL                      19
+#define ETH_MIB_TX_LATE                                20
+#define ETH_MIB_TX_DEF                         21
+#define ETH_MIB_TX_CRS                         22
+#define ETH_MIB_TX_PAUSE                       23
+
+#define ETH_MIB_RX_GD_OCTETS                   32
+#define ETH_MIB_RX_GD_PKTS                     33
+#define ETH_MIB_RX_ALL_OCTETS                  34
+#define ETH_MIB_RX_ALL_PKTS                    35
+#define ETH_MIB_RX_BRDCAST                     36
+#define ETH_MIB_RX_MULT                                37
+#define ETH_MIB_RX_64                          38
+#define ETH_MIB_RX_65_127                      39
+#define ETH_MIB_RX_128_255                     40
+#define ETH_MIB_RX_256_511                     41
+#define ETH_MIB_RX_512_1023                    42
+#define ETH_MIB_RX_1024_MAX                    43
+#define ETH_MIB_RX_JAB                         44
+#define ETH_MIB_RX_OVR                         45
+#define ETH_MIB_RX_FRAG                                46
+#define ETH_MIB_RX_DROP                                47
+#define ETH_MIB_RX_CRC_ALIGN                   48
+#define ETH_MIB_RX_UND                         49
+#define ETH_MIB_RX_CRC                         50
+#define ETH_MIB_RX_ALIGN                       51
+#define ETH_MIB_RX_SYM                         52
+#define ETH_MIB_RX_PAUSE                       53
+#define ETH_MIB_RX_CNTRL                       54
+
+
+struct bcm_enet_mib_counters {
+       u64 tx_gd_octets;
+       u32 tx_gd_pkts;
+       u32 tx_all_octets;
+       u32 tx_all_pkts;
+       u32 tx_brdcast;
+       u32 tx_mult;
+       u32 tx_64;
+       u32 tx_65_127;
+       u32 tx_128_255;
+       u32 tx_256_511;
+       u32 tx_512_1023;
+       u32 tx_1024_max;
+       u32 tx_jab;
+       u32 tx_ovr;
+       u32 tx_frag;
+       u32 tx_underrun;
+       u32 tx_col;
+       u32 tx_1_col;
+       u32 tx_m_col;
+       u32 tx_ex_col;
+       u32 tx_late;
+       u32 tx_def;
+       u32 tx_crs;
+       u32 tx_pause;
+       u64 rx_gd_octets;
+       u32 rx_gd_pkts;
+       u32 rx_all_octets;
+       u32 rx_all_pkts;
+       u32 rx_brdcast;
+       u32 rx_mult;
+       u32 rx_64;
+       u32 rx_65_127;
+       u32 rx_128_255;
+       u32 rx_256_511;
+       u32 rx_512_1023;
+       u32 rx_1024_max;
+       u32 rx_jab;
+       u32 rx_ovr;
+       u32 rx_frag;
+       u32 rx_drop;
+       u32 rx_crc_align;
+       u32 rx_und;
+       u32 rx_crc;
+       u32 rx_align;
+       u32 rx_sym;
+       u32 rx_pause;
+       u32 rx_cntrl;
+};
+
+
+struct bcm_enet_priv {
+
+       /* mac id (from platform device id) */
+       int mac_id;
+
+       /* base remapped address of device */
+       void __iomem *base;
+
+       /* mac irq, rx_dma irq, tx_dma irq */
+       int irq;
+       int irq_rx;
+       int irq_tx;
+
+       /* hw view of rx & tx dma ring */
+       dma_addr_t rx_desc_dma;
+       dma_addr_t tx_desc_dma;
+
+       /* allocated size (in bytes) for rx & tx dma ring */
+       unsigned int rx_desc_alloc_size;
+       unsigned int tx_desc_alloc_size;
+
+
+       struct napi_struct napi;
+
+       /* dma channel id for rx */
+       int rx_chan;
+
+       /* number of dma desc in rx ring */
+       int rx_ring_size;
+
+       /* cpu view of rx dma ring */
+       struct bcm_enet_desc *rx_desc_cpu;
+
+       /* current number of armed descriptor given to hardware for rx */
+       int rx_desc_count;
+
+       /* next rx descriptor to fetch from hardware */
+       int rx_curr_desc;
+
+       /* next dirty rx descriptor to refill */
+       int rx_dirty_desc;
+
+       /* size of allocated rx skbs */
+       unsigned int rx_skb_size;
+
+       /* list of skb given to hw for rx */
+       struct sk_buff **rx_skb;
+
+       /* used when rx skb allocation failed, so we defer rx queue
+        * refill */
+       struct timer_list rx_timeout;
+
+       /* lock rx_timeout against rx normal operation */
+       spinlock_t rx_lock;
+
+
+       /* dma channel id for tx */
+       int tx_chan;
+
+       /* number of dma desc in tx ring */
+       int tx_ring_size;
+
+       /* cpu view of rx dma ring */
+       struct bcm_enet_desc *tx_desc_cpu;
+
+       /* number of available descriptor for tx */
+       int tx_desc_count;
+
+       /* next tx descriptor avaiable */
+       int tx_curr_desc;
+
+       /* next dirty tx descriptor to reclaim */
+       int tx_dirty_desc;
+
+       /* list of skb given to hw for tx */
+       struct sk_buff **tx_skb;
+
+       /* lock used by tx reclaim and xmit */
+       spinlock_t tx_lock;
+
+
+       /* set if internal phy is ignored and external mii interface
+        * is selected */
+       int use_external_mii;
+
+       /* set if a phy is connected, phy address must be known,
+        * probing is not possible */
+       int has_phy;
+       int phy_id;
+
+       /* set if connected phy has an associated irq */
+       int has_phy_interrupt;
+       int phy_interrupt;
+
+       /* used when a phy is connected (phylib used) */
+       struct mii_bus *mii_bus;
+       struct phy_device *phydev;
+       int old_link;
+       int old_duplex;
+       int old_pause;
+
+       /* used when no phy is connected */
+       int force_speed_100;
+       int force_duplex_full;
+
+       /* pause parameters */
+       int pause_auto;
+       int pause_rx;
+       int pause_tx;
+
+       /* stats */
+       struct net_device_stats stats;
+       struct bcm_enet_mib_counters mib;
+
+       /* after mib interrupt, mib registers update is done in this
+        * work queue */
+       struct work_struct mib_update_task;
+
+       /* lock mib update between userspace request and workqueue */
+       struct mutex mib_update_lock;
+
+       /* mac clock */
+       struct clk *mac_clk;
+
+       /* phy clock if internal phy is used */
+       struct clk *phy_clk;
+
+       /* network device reference */
+       struct net_device *net_dev;
+
+       /* platform device reference */
+       struct platform_device *pdev;
+
+       /* maximum hardware transmit/receive size */
+       unsigned int hw_mtu;
+};
+
+#endif /* ! BCM63XX_ENET_H_ */
index 13b72ce870de62e5f09e7f0006225a83f8b948bf..684c6fe24c8d538daa5145c803ac3c66e717fec2 100644 (file)
@@ -362,5 +362,6 @@ static inline u8 is_udp_pkt(struct sk_buff *skb)
 extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm,
                u16 num_popped);
 extern void be_link_status_update(struct be_adapter *adapter, bool link_up);
+extern void netdev_stats_update(struct be_adapter *adapter);
 extern int be_load_fw(struct be_adapter *adapter, u8 *func);
 #endif                         /* BE_H */
index 1db092498309ca8a4fe840a2e6f7c5d4cdd2e30a..3dd76c4170bfc000657f4b65713b662d20c8de04 100644 (file)
@@ -59,15 +59,22 @@ static int be_mcc_compl_process(struct be_adapter *adapter,
 
        compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
                                CQE_STATUS_COMPL_MASK;
-       if (compl_status != MCC_STATUS_SUCCESS) {
+       if (compl_status == MCC_STATUS_SUCCESS) {
+               if (compl->tag0 == OPCODE_ETH_GET_STATISTICS) {
+                       struct be_cmd_resp_get_stats *resp =
+                                               adapter->stats.cmd.va;
+                       be_dws_le_to_cpu(&resp->hw_stats,
+                                               sizeof(resp->hw_stats));
+                       netdev_stats_update(adapter);
+               }
+       } else if (compl_status != MCC_STATUS_NOT_SUPPORTED) {
                extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
                                CQE_STATUS_EXTD_MASK;
                dev_warn(&adapter->pdev->dev,
                        "Error in cmd completion: status(compl/extd)=%d/%d\n",
                        compl_status, extd_status);
-               return -1;
        }
-       return 0;
+       return compl_status;
 }
 
 /* Link state evt is a string of bytes; no need for endian swapping */
@@ -97,10 +104,10 @@ static struct be_mcc_compl *be_mcc_compl_get(struct be_adapter *adapter)
        return NULL;
 }
 
-void be_process_mcc(struct be_adapter *adapter)
+int be_process_mcc(struct be_adapter *adapter)
 {
        struct be_mcc_compl *compl;
-       int num = 0;
+       int num = 0, status = 0;
 
        spin_lock_bh(&adapter->mcc_cq_lock);
        while ((compl = be_mcc_compl_get(adapter))) {
@@ -111,38 +118,47 @@ void be_process_mcc(struct be_adapter *adapter)
                        /* Interpret compl as a async link evt */
                        be_async_link_state_process(adapter,
                                (struct be_async_event_link_state *) compl);
-               } else {
-                       be_mcc_compl_process(adapter, compl);
-                       atomic_dec(&adapter->mcc_obj.q.used);
+               } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) {
+                               status = be_mcc_compl_process(adapter, compl);
+                               atomic_dec(&adapter->mcc_obj.q.used);
                }
                be_mcc_compl_use(compl);
                num++;
        }
+
        if (num)
                be_cq_notify(adapter, adapter->mcc_obj.cq.id, true, num);
+
        spin_unlock_bh(&adapter->mcc_cq_lock);
+       return status;
 }
 
 /* Wait till no more pending mcc requests are present */
-static void be_mcc_wait_compl(struct be_adapter *adapter)
+static int be_mcc_wait_compl(struct be_adapter *adapter)
 {
-#define mcc_timeout            50000 /* 5s timeout */
-       int i;
+#define mcc_timeout            120000 /* 12s timeout */
+       int i, status;
        for (i = 0; i < mcc_timeout; i++) {
-               be_process_mcc(adapter);
+               status = be_process_mcc(adapter);
+               if (status)
+                       return status;
+
                if (atomic_read(&adapter->mcc_obj.q.used) == 0)
                        break;
                udelay(100);
        }
-       if (i == mcc_timeout)
+       if (i == mcc_timeout) {
                dev_err(&adapter->pdev->dev, "mccq poll timed out\n");
+               return -1;
+       }
+       return 0;
 }
 
 /* Notify MCC requests and wait for completion */
-static void be_mcc_notify_wait(struct be_adapter *adapter)
+static int be_mcc_notify_wait(struct be_adapter *adapter)
 {
        be_mcc_notify(adapter);
-       be_mcc_wait_compl(adapter);
+       return be_mcc_wait_compl(adapter);
 }
 
 static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db)
@@ -173,7 +189,7 @@ static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db)
  * Insert the mailbox address into the doorbell in two steps
  * Polls on the mbox doorbell till a command completion (or a timeout) occurs
  */
-static int be_mbox_notify(struct be_adapter *adapter)
+static int be_mbox_notify_wait(struct be_adapter *adapter)
 {
        int status;
        u32 val = 0;
@@ -182,8 +198,6 @@ static int be_mbox_notify(struct be_adapter *adapter)
        struct be_mcc_mailbox *mbox = mbox_mem->va;
        struct be_mcc_compl *compl = &mbox->compl;
 
-       memset(compl, 0, sizeof(*compl));
-
        val |= MPU_MAILBOX_DB_HI_MASK;
        /* at bits 2 - 31 place mbox dma addr msb bits 34 - 63 */
        val |= (upper_32_bits(mbox_mem->dma) >> 2) << 2;
@@ -310,34 +324,40 @@ static u32 eq_delay_to_mult(u32 usec_delay)
        return multiplier;
 }
 
-static inline struct be_mcc_wrb *wrb_from_mbox(struct be_dma_mem *mbox_mem)
+static inline struct be_mcc_wrb *wrb_from_mbox(struct be_adapter *adapter)
 {
-       return &((struct be_mcc_mailbox *)(mbox_mem->va))->wrb;
+       struct be_dma_mem *mbox_mem = &adapter->mbox_mem;
+       struct be_mcc_wrb *wrb
+               = &((struct be_mcc_mailbox *)(mbox_mem->va))->wrb;
+       memset(wrb, 0, sizeof(*wrb));
+       return wrb;
 }
 
-static inline struct be_mcc_wrb *wrb_from_mcc(struct be_queue_info *mccq)
+static struct be_mcc_wrb *wrb_from_mccq(struct be_adapter *adapter)
 {
-       struct be_mcc_wrb *wrb = NULL;
-       if (atomic_read(&mccq->used) < mccq->len) {
-               wrb = queue_head_node(mccq);
-               queue_head_inc(mccq);
-               atomic_inc(&mccq->used);
-               memset(wrb, 0, sizeof(*wrb));
-       }
+       struct be_queue_info *mccq = &adapter->mcc_obj.q;
+       struct be_mcc_wrb *wrb;
+
+       BUG_ON(atomic_read(&mccq->used) >= mccq->len);
+       wrb = queue_head_node(mccq);
+       queue_head_inc(mccq);
+       atomic_inc(&mccq->used);
+       memset(wrb, 0, sizeof(*wrb));
        return wrb;
 }
 
 int be_cmd_eq_create(struct be_adapter *adapter,
                struct be_queue_info *eq, int eq_delay)
 {
-       struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
-       struct be_cmd_req_eq_create *req = embedded_payload(wrb);
-       struct be_cmd_resp_eq_create *resp = embedded_payload(wrb);
+       struct be_mcc_wrb *wrb;
+       struct be_cmd_req_eq_create *req;
        struct be_dma_mem *q_mem = &eq->dma_mem;
        int status;
 
        spin_lock(&adapter->mbox_lock);
-       memset(wrb, 0, sizeof(*wrb));
+
+       wrb = wrb_from_mbox(adapter);
+       req = embedded_payload(wrb);
 
        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
@@ -359,25 +379,29 @@ int be_cmd_eq_create(struct be_adapter *adapter,
 
        be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
 
-       status = be_mbox_notify(adapter);
+       status = be_mbox_notify_wait(adapter);
        if (!status) {
+               struct be_cmd_resp_eq_create *resp = embedded_payload(wrb);
                eq->id = le16_to_cpu(resp->eq_id);
                eq->created = true;
        }
+
        spin_unlock(&adapter->mbox_lock);
        return status;
 }
 
+/* Uses mbox */
 int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
                        u8 type, bool permanent, u32 if_handle)
 {
-       struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
-       struct be_cmd_req_mac_query *req = embedded_payload(wrb);
-       struct be_cmd_resp_mac_query *resp = embedded_payload(wrb);
+       struct be_mcc_wrb *wrb;
+       struct be_cmd_req_mac_query *req;
        int status;
 
        spin_lock(&adapter->mbox_lock);
-       memset(wrb, 0, sizeof(*wrb));
+
+       wrb = wrb_from_mbox(adapter);
+       req = embedded_payload(wrb);
 
        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
@@ -388,27 +412,32 @@ int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
        if (permanent) {
                req->permanent = 1;
        } else {
-               req->if_id = cpu_to_le16((u16)if_handle);
+               req->if_id = cpu_to_le16((u16) if_handle);
                req->permanent = 0;
        }
 
-       status = be_mbox_notify(adapter);
-       if (!status)
+       status = be_mbox_notify_wait(adapter);
+       if (!status) {
+               struct be_cmd_resp_mac_query *resp = embedded_payload(wrb);
                memcpy(mac_addr, resp->mac.addr, ETH_ALEN);
+       }
 
        spin_unlock(&adapter->mbox_lock);
        return status;
 }
 
+/* Uses synchronous MCCQ */
 int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr,
                u32 if_id, u32 *pmac_id)
 {
-       struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
-       struct be_cmd_req_pmac_add *req = embedded_payload(wrb);
+       struct be_mcc_wrb *wrb;
+       struct be_cmd_req_pmac_add *req;
        int status;
 
-       spin_lock(&adapter->mbox_lock);
-       memset(wrb, 0, sizeof(*wrb));
+       spin_lock_bh(&adapter->mcc_lock);
+
+       wrb = wrb_from_mccq(adapter);
+       req = embedded_payload(wrb);
 
        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
@@ -418,24 +447,27 @@ int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr,
        req->if_id = cpu_to_le32(if_id);
        memcpy(req->mac_address, mac_addr, ETH_ALEN);
 
-       status = be_mbox_notify(adapter);
+       status = be_mcc_notify_wait(adapter);
        if (!status) {
                struct be_cmd_resp_pmac_add *resp = embedded_payload(wrb);
                *pmac_id = le32_to_cpu(resp->pmac_id);
        }
 
-       spin_unlock(&adapter->mbox_lock);
+       spin_unlock_bh(&adapter->mcc_lock);
        return status;
 }
 
+/* Uses synchronous MCCQ */
 int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id)
 {
-       struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
-       struct be_cmd_req_pmac_del *req = embedded_payload(wrb);
+       struct be_mcc_wrb *wrb;
+       struct be_cmd_req_pmac_del *req;
        int status;
 
-       spin_lock(&adapter->mbox_lock);
-       memset(wrb, 0, sizeof(*wrb));
+       spin_lock_bh(&adapter->mcc_lock);
+
+       wrb = wrb_from_mccq(adapter);
+       req = embedded_payload(wrb);
 
        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
@@ -445,25 +477,29 @@ int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id)
        req->if_id = cpu_to_le32(if_id);
        req->pmac_id = cpu_to_le32(pmac_id);
 
-       status = be_mbox_notify(adapter);
-       spin_unlock(&adapter->mbox_lock);
+       status = be_mcc_notify_wait(adapter);
+
+       spin_unlock_bh(&adapter->mcc_lock);
 
        return status;
 }
 
+/* Uses Mbox */
 int be_cmd_cq_create(struct be_adapter *adapter,
                struct be_queue_info *cq, struct be_queue_info *eq,
                bool sol_evts, bool no_delay, int coalesce_wm)
 {
-       struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
-       struct be_cmd_req_cq_create *req = embedded_payload(wrb);
-       struct be_cmd_resp_cq_create *resp = embedded_payload(wrb);
+       struct be_mcc_wrb *wrb;
+       struct be_cmd_req_cq_create *req;
        struct be_dma_mem *q_mem = &cq->dma_mem;
-       void *ctxt = &req->context;
+       void *ctxt;
        int status;
 
        spin_lock(&adapter->mbox_lock);
-       memset(wrb, 0, sizeof(*wrb));
+
+       wrb = wrb_from_mbox(adapter);
+       req = embedded_payload(wrb);
+       ctxt = &req->context;
 
        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
@@ -486,11 +522,13 @@ int be_cmd_cq_create(struct be_adapter *adapter,
 
        be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
 
-       status = be_mbox_notify(adapter);
+       status = be_mbox_notify_wait(adapter);
        if (!status) {
+               struct be_cmd_resp_cq_create *resp = embedded_payload(wrb);
                cq->id = le16_to_cpu(resp->cq_id);
                cq->created = true;
        }
+
        spin_unlock(&adapter->mbox_lock);
 
        return status;
@@ -508,14 +546,17 @@ int be_cmd_mccq_create(struct be_adapter *adapter,
                        struct be_queue_info *mccq,
                        struct be_queue_info *cq)
 {
-       struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
-       struct be_cmd_req_mcc_create *req = embedded_payload(wrb);
+       struct be_mcc_wrb *wrb;
+       struct be_cmd_req_mcc_create *req;
        struct be_dma_mem *q_mem = &mccq->dma_mem;
-       void *ctxt = &req->context;
+       void *ctxt;
        int status;
 
        spin_lock(&adapter->mbox_lock);
-       memset(wrb, 0, sizeof(*wrb));
+
+       wrb = wrb_from_mbox(adapter);
+       req = embedded_payload(wrb);
+       ctxt = &req->context;
 
        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
@@ -534,7 +575,7 @@ int be_cmd_mccq_create(struct be_adapter *adapter,
 
        be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
 
-       status = be_mbox_notify(adapter);
+       status = be_mbox_notify_wait(adapter);
        if (!status) {
                struct be_cmd_resp_mcc_create *resp = embedded_payload(wrb);
                mccq->id = le16_to_cpu(resp->id);
@@ -549,15 +590,17 @@ int be_cmd_txq_create(struct be_adapter *adapter,
                        struct be_queue_info *txq,
                        struct be_queue_info *cq)
 {
-       struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
-       struct be_cmd_req_eth_tx_create *req = embedded_payload(wrb);
+       struct be_mcc_wrb *wrb;
+       struct be_cmd_req_eth_tx_create *req;
        struct be_dma_mem *q_mem = &txq->dma_mem;
-       void *ctxt = &req->context;
+       void *ctxt;
        int status;
-       u32 len_encoded;
 
        spin_lock(&adapter->mbox_lock);
-       memset(wrb, 0, sizeof(*wrb));
+
+       wrb = wrb_from_mbox(adapter);
+       req = embedded_payload(wrb);
+       ctxt = &req->context;
 
        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
@@ -568,10 +611,8 @@ int be_cmd_txq_create(struct be_adapter *adapter,
        req->ulp_num = BE_ULP1_NUM;
        req->type = BE_ETH_TX_RING_TYPE_STANDARD;
 
-       len_encoded = fls(txq->len); /* log2(len) + 1 */
-       if (len_encoded == 16)
-               len_encoded = 0;
-       AMAP_SET_BITS(struct amap_tx_context, tx_ring_size, ctxt, len_encoded);
+       AMAP_SET_BITS(struct amap_tx_context, tx_ring_size, ctxt,
+               be_encoded_q_len(txq->len));
        AMAP_SET_BITS(struct amap_tx_context, pci_func_id, ctxt,
                        be_pci_func(adapter));
        AMAP_SET_BITS(struct amap_tx_context, ctx_valid, ctxt, 1);
@@ -581,28 +622,32 @@ int be_cmd_txq_create(struct be_adapter *adapter,
 
        be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
 
-       status = be_mbox_notify(adapter);
+       status = be_mbox_notify_wait(adapter);
        if (!status) {
                struct be_cmd_resp_eth_tx_create *resp = embedded_payload(wrb);
                txq->id = le16_to_cpu(resp->cid);
                txq->created = true;
        }
+
        spin_unlock(&adapter->mbox_lock);
 
        return status;
 }
 
+/* Uses mbox */
 int be_cmd_rxq_create(struct be_adapter *adapter,
                struct be_queue_info *rxq, u16 cq_id, u16 frag_size,
                u16 max_frame_size, u32 if_id, u32 rss)
 {
-       struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
-       struct be_cmd_req_eth_rx_create *req = embedded_payload(wrb);
+       struct be_mcc_wrb *wrb;
+       struct be_cmd_req_eth_rx_create *req;
        struct be_dma_mem *q_mem = &rxq->dma_mem;
        int status;
 
        spin_lock(&adapter->mbox_lock);
-       memset(wrb, 0, sizeof(*wrb));
+
+       wrb = wrb_from_mbox(adapter);
+       req = embedded_payload(wrb);
 
        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
@@ -617,29 +662,34 @@ int be_cmd_rxq_create(struct be_adapter *adapter,
        req->max_frame_size = cpu_to_le16(max_frame_size);
        req->rss_queue = cpu_to_le32(rss);
 
-       status = be_mbox_notify(adapter);
+       status = be_mbox_notify_wait(adapter);
        if (!status) {
                struct be_cmd_resp_eth_rx_create *resp = embedded_payload(wrb);
                rxq->id = le16_to_cpu(resp->id);
                rxq->created = true;
        }
+
        spin_unlock(&adapter->mbox_lock);
 
        return status;
 }
 
-/* Generic destroyer function for all types of queues */
+/* Generic destroyer function for all types of queues
+ * Uses Mbox
+ */
 int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
                int queue_type)
 {
-       struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
-       struct be_cmd_req_q_destroy *req = embedded_payload(wrb);
+       struct be_mcc_wrb *wrb;
+       struct be_cmd_req_q_destroy *req;
        u8 subsys = 0, opcode = 0;
        int status;
 
        spin_lock(&adapter->mbox_lock);
 
-       memset(wrb, 0, sizeof(*wrb));
+       wrb = wrb_from_mbox(adapter);
+       req = embedded_payload(wrb);
+
        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
        switch (queue_type) {
@@ -669,23 +719,27 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
        be_cmd_hdr_prepare(&req->hdr, subsys, opcode, sizeof(*req));
        req->id = cpu_to_le16(q->id);
 
-       status = be_mbox_notify(adapter);
+       status = be_mbox_notify_wait(adapter);
 
        spin_unlock(&adapter->mbox_lock);
 
        return status;
 }
 
-/* Create an rx filtering policy configuration on an i/f */
+/* Create an rx filtering policy configuration on an i/f
+ * Uses mbox
+ */
 int be_cmd_if_create(struct be_adapter *adapter, u32 flags, u8 *mac,
                bool pmac_invalid, u32 *if_handle, u32 *pmac_id)
 {
-       struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
-       struct be_cmd_req_if_create *req = embedded_payload(wrb);
+       struct be_mcc_wrb *wrb;
+       struct be_cmd_req_if_create *req;
        int status;
 
        spin_lock(&adapter->mbox_lock);
-       memset(wrb, 0, sizeof(*wrb));
+
+       wrb = wrb_from_mbox(adapter);
+       req = embedded_payload(wrb);
 
        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
@@ -694,10 +748,11 @@ int be_cmd_if_create(struct be_adapter *adapter, u32 flags, u8 *mac,
 
        req->capability_flags = cpu_to_le32(flags);
        req->enable_flags = cpu_to_le32(flags);
+       req->pmac_invalid = pmac_invalid;
        if (!pmac_invalid)
                memcpy(req->mac_addr, mac, ETH_ALEN);
 
-       status = be_mbox_notify(adapter);
+       status = be_mbox_notify_wait(adapter);
        if (!status) {
                struct be_cmd_resp_if_create *resp = embedded_payload(wrb);
                *if_handle = le32_to_cpu(resp->interface_id);
@@ -709,14 +764,17 @@ int be_cmd_if_create(struct be_adapter *adapter, u32 flags, u8 *mac,
        return status;
 }
 
+/* Uses mbox */
 int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id)
 {
-       struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
-       struct be_cmd_req_if_destroy *req = embedded_payload(wrb);
+       struct be_mcc_wrb *wrb;
+       struct be_cmd_req_if_destroy *req;
        int status;
 
        spin_lock(&adapter->mbox_lock);
-       memset(wrb, 0, sizeof(*wrb));
+
+       wrb = wrb_from_mbox(adapter);
+       req = embedded_payload(wrb);
 
        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
@@ -724,7 +782,8 @@ int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id)
                OPCODE_COMMON_NTWK_INTERFACE_DESTROY, sizeof(*req));
 
        req->interface_id = cpu_to_le32(interface_id);
-       status = be_mbox_notify(adapter);
+
+       status = be_mbox_notify_wait(adapter);
 
        spin_unlock(&adapter->mbox_lock);
 
@@ -733,20 +792,22 @@ int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id)
 
 /* Get stats is a non embedded command: the request is not embedded inside
  * WRB but is a separate dma memory block
+ * Uses asynchronous MCC
  */
 int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd)
 {
-       struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
-       struct be_cmd_req_get_stats *req = nonemb_cmd->va;
-       struct be_sge *sge = nonembedded_sgl(wrb);
-       int status;
+       struct be_mcc_wrb *wrb;
+       struct be_cmd_req_get_stats *req;
+       struct be_sge *sge;
 
-       spin_lock(&adapter->mbox_lock);
-       memset(wrb, 0, sizeof(*wrb));
+       spin_lock_bh(&adapter->mcc_lock);
 
-       memset(req, 0, sizeof(*req));
+       wrb = wrb_from_mccq(adapter);
+       req = nonemb_cmd->va;
+       sge = nonembedded_sgl(wrb);
 
        be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
+       wrb->tag0 = OPCODE_ETH_GET_STATISTICS;
 
        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
                OPCODE_ETH_GET_STATISTICS, sizeof(*req));
@@ -754,59 +815,61 @@ int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd)
        sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
        sge->len = cpu_to_le32(nonemb_cmd->size);
 
-       status = be_mbox_notify(adapter);
-       if (!status) {
-               struct be_cmd_resp_get_stats *resp = nonemb_cmd->va;
-               be_dws_le_to_cpu(&resp->hw_stats, sizeof(resp->hw_stats));
-       }
+       be_mcc_notify(adapter);
 
-       spin_unlock(&adapter->mbox_lock);
-       return status;
+       spin_unlock_bh(&adapter->mcc_lock);
+       return 0;
 }
 
+/* Uses synchronous mcc */
 int be_cmd_link_status_query(struct be_adapter *adapter,
                        bool *link_up)
 {
-       struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
-       struct be_cmd_req_link_status *req = embedded_payload(wrb);
+       struct be_mcc_wrb *wrb;
+       struct be_cmd_req_link_status *req;
        int status;
 
-       spin_lock(&adapter->mbox_lock);
+       spin_lock_bh(&adapter->mcc_lock);
+
+       wrb = wrb_from_mccq(adapter);
+       req = embedded_payload(wrb);
 
        *link_up = false;
-       memset(wrb, 0, sizeof(*wrb));
 
        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
                OPCODE_COMMON_NTWK_LINK_STATUS_QUERY, sizeof(*req));
 
-       status = be_mbox_notify(adapter);
+       status = be_mcc_notify_wait(adapter);
        if (!status) {
                struct be_cmd_resp_link_status *resp = embedded_payload(wrb);
                if (resp->mac_speed != PHY_LINK_SPEED_ZERO)
                        *link_up = true;
        }
 
-       spin_unlock(&adapter->mbox_lock);
+       spin_unlock_bh(&adapter->mcc_lock);
        return status;
 }
 
+/* Uses Mbox */
 int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver)
 {
-       struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
-       struct be_cmd_req_get_fw_version *req = embedded_payload(wrb);
+       struct be_mcc_wrb *wrb;
+       struct be_cmd_req_get_fw_version *req;
        int status;
 
        spin_lock(&adapter->mbox_lock);
-       memset(wrb, 0, sizeof(*wrb));
+
+       wrb = wrb_from_mbox(adapter);
+       req = embedded_payload(wrb);
 
        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
                OPCODE_COMMON_GET_FW_VERSION, sizeof(*req));
 
-       status = be_mbox_notify(adapter);
+       status = be_mbox_notify_wait(adapter);
        if (!status) {
                struct be_cmd_resp_get_fw_version *resp = embedded_payload(wrb);
                strncpy(fw_ver, resp->firmware_version_string, FW_VER_LEN);
@@ -816,15 +879,18 @@ int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver)
        return status;
 }
 
-/* set the EQ delay interval of an EQ to specified value */
+/* set the EQ delay interval of an EQ to specified value
+ * Uses async mcc
+ */
 int be_cmd_modify_eqd(struct be_adapter *adapter, u32 eq_id, u32 eqd)
 {
-       struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
-       struct be_cmd_req_modify_eq_delay *req = embedded_payload(wrb);
-       int status;
+       struct be_mcc_wrb *wrb;
+       struct be_cmd_req_modify_eq_delay *req;
 
-       spin_lock(&adapter->mbox_lock);
-       memset(wrb, 0, sizeof(*wrb));
+       spin_lock_bh(&adapter->mcc_lock);
+
+       wrb = wrb_from_mccq(adapter);
+       req = embedded_payload(wrb);
 
        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
@@ -836,21 +902,24 @@ int be_cmd_modify_eqd(struct be_adapter *adapter, u32 eq_id, u32 eqd)
        req->delay[0].phase = 0;
        req->delay[0].delay_multiplier = cpu_to_le32(eqd);
 
-       status = be_mbox_notify(adapter);
+       be_mcc_notify(adapter);
 
-       spin_unlock(&adapter->mbox_lock);
-       return status;
+       spin_unlock_bh(&adapter->mcc_lock);
+       return 0;
 }
 
+/* Uses sycnhronous mcc */
 int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id, u16 *vtag_array,
                        u32 num, bool untagged, bool promiscuous)
 {
-       struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
-       struct be_cmd_req_vlan_config *req = embedded_payload(wrb);
+       struct be_mcc_wrb *wrb;
+       struct be_cmd_req_vlan_config *req;
        int status;
 
-       spin_lock(&adapter->mbox_lock);
-       memset(wrb, 0, sizeof(*wrb));
+       spin_lock_bh(&adapter->mcc_lock);
+
+       wrb = wrb_from_mccq(adapter);
+       req = embedded_payload(wrb);
 
        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
@@ -866,23 +935,24 @@ int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id, u16 *vtag_array,
                        req->num_vlan * sizeof(vtag_array[0]));
        }
 
-       status = be_mbox_notify(adapter);
+       status = be_mcc_notify_wait(adapter);
 
-       spin_unlock(&adapter->mbox_lock);
+       spin_unlock_bh(&adapter->mcc_lock);
        return status;
 }
 
-/* Use MCC for this command as it may be called in BH context */
+/* Uses MCC for this command as it may be called in BH context
+ * Uses synchronous mcc
+ */
 int be_cmd_promiscuous_config(struct be_adapter *adapter, u8 port_num, bool en)
 {
        struct be_mcc_wrb *wrb;
        struct be_cmd_req_promiscuous_config *req;
+       int status;
 
        spin_lock_bh(&adapter->mcc_lock);
 
-       wrb = wrb_from_mcc(&adapter->mcc_obj.q);
-       BUG_ON(!wrb);
-
+       wrb = wrb_from_mccq(adapter);
        req = embedded_payload(wrb);
 
        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -895,14 +965,14 @@ int be_cmd_promiscuous_config(struct be_adapter *adapter, u8 port_num, bool en)
        else
                req->port0_promiscuous = en;
 
-       be_mcc_notify_wait(adapter);
+       status = be_mcc_notify_wait(adapter);
 
        spin_unlock_bh(&adapter->mcc_lock);
-       return 0;
+       return status;
 }
 
 /*
- * Use MCC for this command as it may be called in BH context
+ * Uses MCC for this command as it may be called in BH context
  * (mc == NULL) => multicast promiscous
  */
 int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
@@ -914,9 +984,7 @@ int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
 
        spin_lock_bh(&adapter->mcc_lock);
 
-       wrb = wrb_from_mcc(&adapter->mcc_obj.q);
-       BUG_ON(!wrb);
-
+       wrb = wrb_from_mccq(adapter);
        req = embedded_payload(wrb);
 
        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -944,15 +1012,17 @@ int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
        return 0;
 }
 
+/* Uses synchrounous mcc */
 int be_cmd_set_flow_control(struct be_adapter *adapter, u32 tx_fc, u32 rx_fc)
 {
-       struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
-       struct be_cmd_req_set_flow_control *req = embedded_payload(wrb);
+       struct be_mcc_wrb *wrb;
+       struct be_cmd_req_set_flow_control *req;
        int status;
 
-       spin_lock(&adapter->mbox_lock);
+       spin_lock_bh(&adapter->mcc_lock);
 
-       memset(wrb, 0, sizeof(*wrb));
+       wrb = wrb_from_mccq(adapter);
+       req = embedded_payload(wrb);
 
        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
@@ -962,28 +1032,30 @@ int be_cmd_set_flow_control(struct be_adapter *adapter, u32 tx_fc, u32 rx_fc)
        req->tx_flow_control = cpu_to_le16((u16)tx_fc);
        req->rx_flow_control = cpu_to_le16((u16)rx_fc);
 
-       status = be_mbox_notify(adapter);
+       status = be_mcc_notify_wait(adapter);
 
-       spin_unlock(&adapter->mbox_lock);
+       spin_unlock_bh(&adapter->mcc_lock);
        return status;
 }
 
+/* Uses sycn mcc */
 int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc)
 {
-       struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
-       struct be_cmd_req_get_flow_control *req = embedded_payload(wrb);
+       struct be_mcc_wrb *wrb;
+       struct be_cmd_req_get_flow_control *req;
        int status;
 
-       spin_lock(&adapter->mbox_lock);
+       spin_lock_bh(&adapter->mcc_lock);
 
-       memset(wrb, 0, sizeof(*wrb));
+       wrb = wrb_from_mccq(adapter);
+       req = embedded_payload(wrb);
 
        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
                OPCODE_COMMON_GET_FLOW_CONTROL, sizeof(*req));
 
-       status = be_mbox_notify(adapter);
+       status = be_mcc_notify_wait(adapter);
        if (!status) {
                struct be_cmd_resp_get_flow_control *resp =
                                                embedded_payload(wrb);
@@ -991,26 +1063,28 @@ int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc)
                *rx_fc = le16_to_cpu(resp->rx_flow_control);
        }
 
-       spin_unlock(&adapter->mbox_lock);
+       spin_unlock_bh(&adapter->mcc_lock);
        return status;
 }
 
+/* Uses mbox */
 int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num)
 {
-       struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
-       struct be_cmd_req_query_fw_cfg *req = embedded_payload(wrb);
+       struct be_mcc_wrb *wrb;
+       struct be_cmd_req_query_fw_cfg *req;
        int status;
 
        spin_lock(&adapter->mbox_lock);
 
-       memset(wrb, 0, sizeof(*wrb));
+       wrb = wrb_from_mbox(adapter);
+       req = embedded_payload(wrb);
 
        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
                OPCODE_COMMON_QUERY_FIRMWARE_CONFIG, sizeof(*req));
 
-       status = be_mbox_notify(adapter);
+       status = be_mbox_notify_wait(adapter);
        if (!status) {
                struct be_cmd_resp_query_fw_cfg *resp = embedded_payload(wrb);
                *port_num = le32_to_cpu(resp->phys_port);
@@ -1020,22 +1094,24 @@ int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num)
        return status;
 }
 
+/* Uses mbox */
 int be_cmd_reset_function(struct be_adapter *adapter)
 {
-       struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
-       struct be_cmd_req_hdr *req = embedded_payload(wrb);
+       struct be_mcc_wrb *wrb;
+       struct be_cmd_req_hdr *req;
        int status;
 
        spin_lock(&adapter->mbox_lock);
 
-       memset(wrb, 0, sizeof(*wrb));
+       wrb = wrb_from_mbox(adapter);
+       req = embedded_payload(wrb);
 
        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
        be_cmd_hdr_prepare(req, CMD_SUBSYSTEM_COMMON,
                OPCODE_COMMON_FUNCTION_RESET, sizeof(*req));
 
-       status = be_mbox_notify(adapter);
+       status = be_mbox_notify_wait(adapter);
 
        spin_unlock(&adapter->mbox_lock);
        return status;
@@ -1044,13 +1120,17 @@ int be_cmd_reset_function(struct be_adapter *adapter)
 int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
                        u32 flash_type, u32 flash_opcode, u32 buf_size)
 {
-       struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
+       struct be_mcc_wrb *wrb;
        struct be_cmd_write_flashrom *req = cmd->va;
-       struct be_sge *sge = nonembedded_sgl(wrb);
+       struct be_sge *sge;
        int status;
 
-       spin_lock(&adapter->mbox_lock);
-       memset(wrb, 0, sizeof(*wrb));
+       spin_lock_bh(&adapter->mcc_lock);
+
+       wrb = wrb_from_mccq(adapter);
+       req = embedded_payload(wrb);
+       sge = nonembedded_sgl(wrb);
+
        be_wrb_hdr_prepare(wrb, cmd->size, false, 1);
 
        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
@@ -1063,8 +1143,8 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
        req->params.op_code = cpu_to_le32(flash_opcode);
        req->params.data_buf_size = cpu_to_le32(buf_size);
 
-       status = be_mbox_notify(adapter);
+       status = be_mcc_notify_wait(adapter);
 
-       spin_unlock(&adapter->mbox_lock);
+       spin_unlock_bh(&adapter->mcc_lock);
        return status;
 }
index fd7028e5b78ea73fa519089d30621348efe1c8d6..93e432f3d926f784ecf586375ceb1c0c54c76183 100644 (file)
@@ -61,7 +61,8 @@ enum {
 /* The command is completing because the queue was getting flushed */
        MCC_STATUS_QUEUE_FLUSHING = 0x4,
 /* The command is completing with a DMA error */
-       MCC_STATUS_DMA_FAILED = 0x5
+       MCC_STATUS_DMA_FAILED = 0x5,
+       MCC_STATUS_NOT_SUPPORTED = 0x66
 };
 
 #define CQE_STATUS_COMPL_MASK          0xFFFF
@@ -761,7 +762,7 @@ extern int be_cmd_get_flow_control(struct be_adapter *adapter,
                        u32 *tx_fc, u32 *rx_fc);
 extern int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num);
 extern int be_cmd_reset_function(struct be_adapter *adapter);
-extern void be_process_mcc(struct be_adapter *adapter);
+extern int be_process_mcc(struct be_adapter *adapter);
 extern int be_cmd_write_flashrom(struct be_adapter *adapter,
                        struct be_dma_mem *cmd, u32 flash_oper,
                        u32 flash_opcode, u32 buf_size);
index ce11bba2cb6764a99cf577977c3e8dd9ee3eb00d..409cf05959034737273f6b2cb8371a2347102059 100644 (file)
@@ -135,7 +135,7 @@ static int be_mac_addr_set(struct net_device *netdev, void *p)
        return status;
 }
 
-static void netdev_stats_update(struct be_adapter *adapter)
+void netdev_stats_update(struct be_adapter *adapter)
 {
        struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats.cmd.va);
        struct be_rxf_stats *rxf_stats = &hw_stats->rxf;
@@ -431,8 +431,7 @@ static int make_tx_wrbs(struct be_adapter *adapter,
 }
 
 static netdev_tx_t be_xmit(struct sk_buff *skb,
-                                struct net_device *netdev)
-
+                       struct net_device *netdev)
 {
        struct be_adapter *adapter = netdev_priv(netdev);
        struct be_tx_obj *tx_obj = &adapter->tx_obj;
@@ -490,11 +489,11 @@ static int be_change_mtu(struct net_device *netdev, int new_mtu)
  * program them in BE.  If more than BE_NUM_VLANS_SUPPORTED are configured,
  * set the BE in promiscuous VLAN mode.
  */
-static void be_vid_config(struct net_device *netdev)
+static int be_vid_config(struct be_adapter *adapter)
 {
-       struct be_adapter *adapter = netdev_priv(netdev);
        u16 vtag[BE_NUM_VLANS_SUPPORTED];
        u16 ntags = 0, i;
+       int status;
 
        if (adapter->num_vlans <= BE_NUM_VLANS_SUPPORTED)  {
                /* Construct VLAN Table to give to HW */
@@ -504,12 +503,13 @@ static void be_vid_config(struct net_device *netdev)
                                ntags++;
                        }
                }
-               be_cmd_vlan_config(adapter, adapter->if_handle,
-                       vtag, ntags, 1, 0);
+               status = be_cmd_vlan_config(adapter, adapter->if_handle,
+                                       vtag, ntags, 1, 0);
        } else {
-               be_cmd_vlan_config(adapter, adapter->if_handle,
-                       NULL, 0, 1, 1);
+               status = be_cmd_vlan_config(adapter, adapter->if_handle,
+                                       NULL, 0, 1, 1);
        }
+       return status;
 }
 
 static void be_vlan_register(struct net_device *netdev, struct vlan_group *grp)
@@ -532,7 +532,7 @@ static void be_vlan_add_vid(struct net_device *netdev, u16 vid)
        adapter->num_vlans++;
        adapter->vlan_tag[vid] = 1;
 
-       be_vid_config(netdev);
+       be_vid_config(adapter);
 }
 
 static void be_vlan_rem_vid(struct net_device *netdev, u16 vid)
@@ -543,7 +543,7 @@ static void be_vlan_rem_vid(struct net_device *netdev, u16 vid)
        adapter->vlan_tag[vid] = 0;
 
        vlan_group_set_device(adapter->vlan_grp, vid, NULL);
-       be_vid_config(netdev);
+       be_vid_config(adapter);
 }
 
 static void be_set_multicast_list(struct net_device *netdev)
@@ -1444,12 +1444,8 @@ static void be_worker(struct work_struct *work)
 {
        struct be_adapter *adapter =
                container_of(work, struct be_adapter, work.work);
-       int status;
 
-       /* Get Stats */
-       status = be_cmd_get_stats(adapter, &adapter->stats.cmd);
-       if (!status)
-               netdev_stats_update(adapter);
+       be_cmd_get_stats(adapter, &adapter->stats.cmd);
 
        /* Set EQ delay */
        be_rx_eqd_update(adapter);
@@ -1622,11 +1618,6 @@ static int be_setup(struct be_adapter *adapter)
        if (status != 0)
                goto do_none;
 
-       be_vid_config(netdev);
-
-       status = be_cmd_set_flow_control(adapter, true, true);
-       if (status != 0)
-               goto if_destroy;
 
        status = be_tx_queues_create(adapter);
        if (status != 0)
@@ -1640,8 +1631,17 @@ static int be_setup(struct be_adapter *adapter)
        if (status != 0)
                goto rx_qs_destroy;
 
+       status = be_vid_config(adapter);
+       if (status != 0)
+               goto mccqs_destroy;
+
+       status = be_cmd_set_flow_control(adapter, true, true);
+       if (status != 0)
+               goto mccqs_destroy;
        return 0;
 
+mccqs_destroy:
+       be_mcc_queues_destroy(adapter);
 rx_qs_destroy:
        be_rx_queues_destroy(adapter);
 tx_qs_destroy:
index a7e731f8a0da5450f609eb68ccdba5f3acfadec7..69c5b15e22daca1239e5d10bc6f00b767ae3ce4c 100644 (file)
@@ -1093,15 +1093,8 @@ static struct slave *bond_find_best_slave(struct bonding *bond)
                        return NULL; /* still no slave, return NULL */
        }
 
-       /*
-        * first try the primary link; if arping, a link must tx/rx
-        * traffic before it can be considered the curr_active_slave.
-        * also, we would skip slaves between the curr_active_slave
-        * and primary_slave that may be up and able to arp
-        */
        if ((bond->primary_slave) &&
-           (!bond->params.arp_interval) &&
-           (IS_UP(bond->primary_slave->dev))) {
+           bond->primary_slave->link == BOND_LINK_UP) {
                new_active = bond->primary_slave;
        }
 
@@ -1109,15 +1102,14 @@ static struct slave *bond_find_best_slave(struct bonding *bond)
        old_active = new_active;
 
        bond_for_each_slave_from(bond, new_active, i, old_active) {
-               if (IS_UP(new_active->dev)) {
-                       if (new_active->link == BOND_LINK_UP) {
-                               return new_active;
-                       } else if (new_active->link == BOND_LINK_BACK) {
-                               /* link up, but waiting for stabilization */
-                               if (new_active->delay < mintime) {
-                                       mintime = new_active->delay;
-                                       bestslave = new_active;
-                               }
+               if (new_active->link == BOND_LINK_UP) {
+                       return new_active;
+               } else if (new_active->link == BOND_LINK_BACK &&
+                          IS_UP(new_active->dev)) {
+                       /* link up, but waiting for stabilization */
+                       if (new_active->delay < mintime) {
+                               mintime = new_active->delay;
+                               bestslave = new_active;
                        }
                }
        }
@@ -1211,7 +1203,7 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
                        write_unlock_bh(&bond->curr_slave_lock);
                        read_unlock(&bond->lock);
 
-                       netdev_bonding_change(bond->dev);
+                       netdev_bonding_change(bond->dev, NETDEV_BONDING_FAILOVER);
 
                        read_lock(&bond->lock);
                        write_lock_bh(&bond->curr_slave_lock);
@@ -1469,14 +1461,17 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
         */
        if (bond->slave_cnt == 0) {
                if (bond_dev->type != slave_dev->type) {
-                       dev_close(bond_dev);
                        pr_debug("%s: change device type from %d to %d\n",
                                bond_dev->name, bond_dev->type, slave_dev->type);
+
+                       netdev_bonding_change(bond_dev, NETDEV_BONDING_OLDTYPE);
+
                        if (slave_dev->type != ARPHRD_ETHER)
                                bond_setup_by_slave(bond_dev, slave_dev);
                        else
                                ether_setup(bond_dev);
-                       dev_open(bond_dev);
+
+                       netdev_bonding_change(bond_dev, NETDEV_BONDING_NEWTYPE);
                }
        } else if (bond_dev->type != slave_dev->type) {
                pr_err(DRV_NAME ": %s ether type (%d) is different "
@@ -2929,18 +2924,6 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks)
                }
        }
 
-       read_lock(&bond->curr_slave_lock);
-
-       /*
-        * Trigger a commit if the primary option setting has changed.
-        */
-       if (bond->primary_slave &&
-           (bond->primary_slave != bond->curr_active_slave) &&
-           (bond->primary_slave->link == BOND_LINK_UP))
-               commit++;
-
-       read_unlock(&bond->curr_slave_lock);
-
        return commit;
 }
 
@@ -2961,90 +2944,58 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks)
                        continue;
 
                case BOND_LINK_UP:
-                       write_lock_bh(&bond->curr_slave_lock);
-
-                       if (!bond->curr_active_slave &&
-                           time_before_eq(jiffies, dev_trans_start(slave->dev) +
-                                          delta_in_ticks)) {
+                       if ((!bond->curr_active_slave &&
+                            time_before_eq(jiffies,
+                                           dev_trans_start(slave->dev) +
+                                           delta_in_ticks)) ||
+                           bond->curr_active_slave != slave) {
                                slave->link = BOND_LINK_UP;
-                               bond_change_active_slave(bond, slave);
                                bond->current_arp_slave = NULL;
 
                                pr_info(DRV_NAME
-                                      ": %s: %s is up and now the "
-                                      "active interface\n",
-                                      bond->dev->name, slave->dev->name);
-
-                       } else if (bond->curr_active_slave != slave) {
-                               /* this slave has just come up but we
-                                * already have a current slave; this can
-                                * also happen if bond_enslave adds a new
-                                * slave that is up while we are searching
-                                * for a new slave
-                                */
-                               slave->link = BOND_LINK_UP;
-                               bond_set_slave_inactive_flags(slave);
-                               bond->current_arp_slave = NULL;
+                                       ": %s: link status definitely "
+                                       "up for interface %s.\n",
+                                       bond->dev->name, slave->dev->name);
 
-                               pr_info(DRV_NAME
-                                      ": %s: backup interface %s is now up\n",
-                                      bond->dev->name, slave->dev->name);
-                       }
+                               if (!bond->curr_active_slave ||
+                                   (slave == bond->primary_slave))
+                                       goto do_failover;
 
-                       write_unlock_bh(&bond->curr_slave_lock);
+                       }
 
-                       break;
+                       continue;
 
                case BOND_LINK_DOWN:
                        if (slave->link_failure_count < UINT_MAX)
                                slave->link_failure_count++;
 
                        slave->link = BOND_LINK_DOWN;
+                       bond_set_slave_inactive_flags(slave);
 
-                       if (slave == bond->curr_active_slave) {
-                               pr_info(DRV_NAME
-                                      ": %s: link status down for active "
-                                      "interface %s, disabling it\n",
-                                      bond->dev->name, slave->dev->name);
-
-                               bond_set_slave_inactive_flags(slave);
-
-                               write_lock_bh(&bond->curr_slave_lock);
-
-                               bond_select_active_slave(bond);
-                               if (bond->curr_active_slave)
-                                       bond->curr_active_slave->jiffies =
-                                               jiffies;
-
-                               write_unlock_bh(&bond->curr_slave_lock);
+                       pr_info(DRV_NAME
+                               ": %s: link status definitely down for "
+                               "interface %s, disabling it\n",
+                               bond->dev->name, slave->dev->name);
 
+                       if (slave == bond->curr_active_slave) {
                                bond->current_arp_slave = NULL;
-
-                       } else if (slave->state == BOND_STATE_BACKUP) {
-                               pr_info(DRV_NAME
-                                      ": %s: backup interface %s is now down\n",
-                                      bond->dev->name, slave->dev->name);
-
-                               bond_set_slave_inactive_flags(slave);
+                               goto do_failover;
                        }
-                       break;
+
+                       continue;
 
                default:
                        pr_err(DRV_NAME
                               ": %s: impossible: new_link %d on slave %s\n",
                               bond->dev->name, slave->new_link,
                               slave->dev->name);
+                       continue;
                }
-       }
 
-       /*
-        * No race with changes to primary via sysfs, as we hold rtnl.
-        */
-       if (bond->primary_slave &&
-           (bond->primary_slave != bond->curr_active_slave) &&
-           (bond->primary_slave->link == BOND_LINK_UP)) {
+do_failover:
+               ASSERT_RTNL();
                write_lock_bh(&bond->curr_slave_lock);
-               bond_change_active_slave(bond, bond->primary_slave);
+               bond_select_active_slave(bond);
                write_unlock_bh(&bond->curr_slave_lock);
        }
 
index 6971f6cd37fa3be0395b360ab0e086f8c25a2ae7..80ac56313981983063340adb95150fe40d76bea9 100644 (file)
@@ -80,7 +80,7 @@ static void vcan_rx(struct sk_buff *skb, struct net_device *dev)
        skb->dev       = dev;
        skb->ip_summed = CHECKSUM_UNNECESSARY;
 
-       netif_rx(skb);
+       netif_rx_ni(skb);
 }
 
 static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev)
index b47201874d844aac439cac06aa6c111ca39e36e8..29234380e6c68b02369d9c30c8e87826fa2b088e 100644 (file)
@@ -1154,19 +1154,9 @@ static void __inline__ fec_request_mii_intr(struct net_device *dev)
                printk("FEC: Could not allocate fec(MII) IRQ(66)!\n");
 }
 
-static void __inline__ fec_disable_phy_intr(void)
+static void __inline__ fec_disable_phy_intr(struct net_device *dev)
 {
-       volatile unsigned long *icrp;
-       icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
-       *icrp = 0x08000000;
-}
-
-static void __inline__ fec_phy_ack_intr(void)
-{
-       volatile unsigned long *icrp;
-       /* Acknowledge the interrupt */
-       icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
-       *icrp = 0x0d000000;
+       free_irq(66, dev);
 }
 #endif
 
@@ -1398,7 +1388,7 @@ mii_discover_phy(uint mii_reg, struct net_device *dev)
                writel(0, fep->hwp + FEC_MII_SPEED);
                fep->phy_speed = 0;
 #ifdef HAVE_mii_link_interrupt
-               fec_disable_phy_intr();
+               fec_disable_phy_intr(dev);
 #endif
        }
 }
@@ -1411,8 +1401,6 @@ mii_link_interrupt(int irq, void * dev_id)
        struct  net_device *dev = dev_id;
        struct fec_enet_private *fep = netdev_priv(dev);
 
-       fec_phy_ack_intr();
-
        mii_do_cmd(dev, fep->phy->ack_int);
        mii_do_cmd(dev, phy_cmd_relink);  /* restart and display status */
 
index 6158c0f3b2051f4768649a3d09fed9ebc017bb30..f8f5772557cefa661d864d0e0dfa1fde6c467ac0 100644 (file)
@@ -49,11 +49,10 @@ static s32  igb_read_phy_reg_sgmii_82575(struct e1000_hw *, u32, u16 *);
 static s32  igb_reset_hw_82575(struct e1000_hw *);
 static s32  igb_set_d0_lplu_state_82575(struct e1000_hw *, bool);
 static s32  igb_setup_copper_link_82575(struct e1000_hw *);
-static s32  igb_setup_fiber_serdes_link_82575(struct e1000_hw *);
+static s32  igb_setup_serdes_link_82575(struct e1000_hw *);
 static s32  igb_write_phy_reg_sgmii_82575(struct e1000_hw *, u32, u16);
 static void igb_clear_hw_cntrs_82575(struct e1000_hw *);
 static s32  igb_acquire_swfw_sync_82575(struct e1000_hw *, u16);
-static void igb_configure_pcs_link_82575(struct e1000_hw *);
 static s32  igb_get_pcs_speed_and_duplex_82575(struct e1000_hw *, u16 *,
                                                 u16 *);
 static s32  igb_get_phy_id_82575(struct e1000_hw *);
@@ -105,16 +104,20 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
        dev_spec->sgmii_active = false;
 
        ctrl_ext = rd32(E1000_CTRL_EXT);
-       if ((ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK) ==
-           E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES) {
-               hw->phy.media_type = e1000_media_type_internal_serdes;
-               ctrl_ext |= E1000_CTRL_I2C_ENA;
-       } else if (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_SGMII) {
+       switch (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK) {
+       case E1000_CTRL_EXT_LINK_MODE_SGMII:
                dev_spec->sgmii_active = true;
                ctrl_ext |= E1000_CTRL_I2C_ENA;
-       } else {
+               break;
+       case E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES:
+               hw->phy.media_type = e1000_media_type_internal_serdes;
+               ctrl_ext |= E1000_CTRL_I2C_ENA;
+               break;
+       default:
                ctrl_ext &= ~E1000_CTRL_I2C_ENA;
+               break;
        }
+
        wr32(E1000_CTRL_EXT, ctrl_ext);
 
        /* Set mta register count */
@@ -134,7 +137,7 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
        mac->ops.setup_physical_interface =
                (hw->phy.media_type == e1000_media_type_copper)
                        ? igb_setup_copper_link_82575
-                       : igb_setup_fiber_serdes_link_82575;
+                       : igb_setup_serdes_link_82575;
 
        /* NVM initialization */
        eecd = rd32(E1000_EECD);
@@ -379,6 +382,7 @@ static s32 igb_get_phy_id_82575(struct e1000_hw *hw)
        struct e1000_phy_info *phy = &hw->phy;
        s32  ret_val = 0;
        u16 phy_id;
+       u32 ctrl_ext;
 
        /*
         * For SGMII PHYs, we try the list of possible addresses until
@@ -393,6 +397,12 @@ static s32 igb_get_phy_id_82575(struct e1000_hw *hw)
                goto out;
        }
 
+       /* Power on sgmii phy if it is disabled */
+       ctrl_ext = rd32(E1000_CTRL_EXT);
+       wr32(E1000_CTRL_EXT, ctrl_ext & ~E1000_CTRL_EXT_SDP3_DATA);
+       wrfl();
+       msleep(300);
+
        /*
         * The address field in the I2CCMD register is 3 bits and 0 is invalid.
         * Therefore, we need to test 1-7
@@ -418,9 +428,12 @@ static s32 igb_get_phy_id_82575(struct e1000_hw *hw)
                phy->addr = 0;
                ret_val = -E1000_ERR_PHY;
                goto out;
+       } else {
+               ret_val = igb_get_phy_id(hw);
        }
 
-       ret_val = igb_get_phy_id(hw);
+       /* restore previous sfp cage power state */
+       wr32(E1000_CTRL_EXT, ctrl_ext);
 
 out:
        return ret_val;
@@ -766,17 +779,18 @@ static s32 igb_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, u16 *speed,
 }
 
 /**
- *  igb_shutdown_fiber_serdes_link_82575 - Remove link during power down
+ *  igb_shutdown_serdes_link_82575 - Remove link during power down
  *  @hw: pointer to the HW structure
  *
  *  In the case of fiber serdes, shut down optics and PCS on driver unload
  *  when management pass thru is not enabled.
  **/
-void igb_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw)
+void igb_shutdown_serdes_link_82575(struct e1000_hw *hw)
 {
        u32 reg;
 
-       if (hw->phy.media_type != e1000_media_type_internal_serdes)
+       if (hw->phy.media_type != e1000_media_type_internal_serdes ||
+           igb_sgmii_active_82575(hw))
                return;
 
        /* if the management interface is not enabled, then power down */
@@ -788,7 +802,7 @@ void igb_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw)
 
                /* shutdown the laser */
                reg = rd32(E1000_CTRL_EXT);
-               reg |= E1000_CTRL_EXT_SDP7_DATA;
+               reg |= E1000_CTRL_EXT_SDP3_DATA;
                wr32(E1000_CTRL_EXT, reg);
 
                /* flush the write to verify completion */
@@ -927,6 +941,17 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
        ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
        wr32(E1000_CTRL, ctrl);
 
+       ret_val = igb_setup_serdes_link_82575(hw);
+       if (ret_val)
+               goto out;
+
+       if (igb_sgmii_active_82575(hw) && !hw->phy.reset_disable) {
+               ret_val = hw->phy.ops.reset(hw);
+               if (ret_val) {
+                       hw_dbg("Error resetting the PHY.\n");
+                       goto out;
+               }
+       }
        switch (hw->phy.type) {
        case e1000_phy_m88:
                ret_val = igb_copper_link_setup_m88(hw);
@@ -963,8 +988,6 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
                }
        }
 
-       igb_configure_pcs_link_82575(hw);
-
        /*
         * Check link status. Wait up to 100 microseconds for link to become
         * valid.
@@ -987,14 +1010,18 @@ out:
 }
 
 /**
- *  igb_setup_fiber_serdes_link_82575 - Setup link for fiber/serdes
+ *  igb_setup_serdes_link_82575 - Setup link for fiber/serdes
  *  @hw: pointer to the HW structure
  *
  *  Configures speed and duplex for fiber and serdes links.
  **/
-static s32 igb_setup_fiber_serdes_link_82575(struct e1000_hw *hw)
+static s32 igb_setup_serdes_link_82575(struct e1000_hw *hw)
 {
-       u32 reg;
+       u32 ctrl_reg, reg;
+
+       if ((hw->phy.media_type != e1000_media_type_internal_serdes) &&
+           !igb_sgmii_active_82575(hw))
+               return 0;
 
        /*
         * On the 82575, SerDes loopback mode persists until it is
@@ -1004,26 +1031,38 @@ static s32 igb_setup_fiber_serdes_link_82575(struct e1000_hw *hw)
         */
        wr32(E1000_SCTL, E1000_SCTL_DISABLE_SERDES_LOOPBACK);
 
-       /* Force link up, set 1gb, set both sw defined pins */
-       reg = rd32(E1000_CTRL);
-       reg |= E1000_CTRL_SLU |
-              E1000_CTRL_SPD_1000 |
-              E1000_CTRL_FRCSPD |
-              E1000_CTRL_SWDPIN0 |
-              E1000_CTRL_SWDPIN1;
-       wr32(E1000_CTRL, reg);
-
-       /* Power on phy for 82576 fiber adapters */
-       if (hw->mac.type == e1000_82576) {
-               reg = rd32(E1000_CTRL_EXT);
-               reg &= ~E1000_CTRL_EXT_SDP7_DATA;
-               wr32(E1000_CTRL_EXT, reg);
+       /* power on the sfp cage if present */
+       reg = rd32(E1000_CTRL_EXT);
+       reg &= ~E1000_CTRL_EXT_SDP3_DATA;
+       wr32(E1000_CTRL_EXT, reg);
+
+       ctrl_reg = rd32(E1000_CTRL);
+       ctrl_reg |= E1000_CTRL_SLU;
+
+       if (hw->mac.type == e1000_82575 || hw->mac.type == e1000_82576) {
+               /* set both sw defined pins */
+               ctrl_reg |= E1000_CTRL_SWDPIN0 | E1000_CTRL_SWDPIN1;
+
+               /* Set switch control to serdes energy detect */
+               reg = rd32(E1000_CONNSW);
+               reg |= E1000_CONNSW_ENRGSRC;
+               wr32(E1000_CONNSW, reg);
+       }
+
+       reg = rd32(E1000_PCS_LCTL);
+
+       if (igb_sgmii_active_82575(hw)) {
+               /* allow time for SFP cage to power up phy */
+               msleep(300);
+
+               /* AN time out should be disabled for SGMII mode */
+               reg &= ~(E1000_PCS_LCTL_AN_TIMEOUT);
+       } else {
+               ctrl_reg |= E1000_CTRL_SPD_1000 | E1000_CTRL_FRCSPD |
+                           E1000_CTRL_FD | E1000_CTRL_FRCDPX;
        }
 
-       /* Set switch control to serdes energy detect */
-       reg = rd32(E1000_CONNSW);
-       reg |= E1000_CONNSW_ENRGSRC;
-       wr32(E1000_CONNSW, reg);
+       wr32(E1000_CTRL, ctrl_reg);
 
        /*
         * New SerDes mode allows for forcing speed or autonegotiating speed
@@ -1031,12 +1070,21 @@ static s32 igb_setup_fiber_serdes_link_82575(struct e1000_hw *hw)
         * mode that will be compatible with older link partners and switches.
         * However, both are supported by the hardware and some drivers/tools.
         */
-       reg = rd32(E1000_PCS_LCTL);
 
        reg &= ~(E1000_PCS_LCTL_AN_ENABLE | E1000_PCS_LCTL_FLV_LINK_UP |
                E1000_PCS_LCTL_FSD | E1000_PCS_LCTL_FORCE_LINK);
 
-       if (hw->mac.autoneg) {
+       /*
+        * We force flow control to prevent the CTRL register values from being
+        * overwritten by the autonegotiated flow control values
+        */
+       reg |= E1000_PCS_LCTL_FORCE_FCTRL;
+
+       /*
+        * we always set sgmii to autoneg since it is the phy that will be
+        * forcing the link and the serdes is just a go-between
+        */
+       if (hw->mac.autoneg || igb_sgmii_active_82575(hw)) {
                /* Set PCS register for autoneg */
                reg |= E1000_PCS_LCTL_FSV_1000 |      /* Force 1000    */
                       E1000_PCS_LCTL_FDV_FULL |      /* SerDes Full duplex */
@@ -1053,75 +1101,12 @@ static s32 igb_setup_fiber_serdes_link_82575(struct e1000_hw *hw)
                hw_dbg("Configuring Forced Link; PCS_LCTL = 0x%08X\n", reg);
        }
 
-       if (hw->mac.type == e1000_82576) {
-               reg |= E1000_PCS_LCTL_FORCE_FCTRL;
-               igb_force_mac_fc(hw);
-       }
-
        wr32(E1000_PCS_LCTL, reg);
 
-       return 0;
-}
-
-/**
- *  igb_configure_pcs_link_82575 - Configure PCS link
- *  @hw: pointer to the HW structure
- *
- *  Configure the physical coding sub-layer (PCS) link.  The PCS link is
- *  only used on copper connections where the serialized gigabit media
- *  independent interface (sgmii) is being used.  Configures the link
- *  for auto-negotiation or forces speed/duplex.
- **/
-static void igb_configure_pcs_link_82575(struct e1000_hw *hw)
-{
-       struct e1000_mac_info *mac = &hw->mac;
-       u32 reg = 0;
-
-       if (hw->phy.media_type != e1000_media_type_copper ||
-           !(igb_sgmii_active_82575(hw)))
-               return;
-
-       /* For SGMII, we need to issue a PCS autoneg restart */
-       reg = rd32(E1000_PCS_LCTL);
-
-       /* AN time out should be disabled for SGMII mode */
-       reg &= ~(E1000_PCS_LCTL_AN_TIMEOUT);
-
-       if (mac->autoneg) {
-               /* Make sure forced speed and force link are not set */
-               reg &= ~(E1000_PCS_LCTL_FSD | E1000_PCS_LCTL_FORCE_LINK);
-
-               /*
-                * The PHY should be setup prior to calling this function.
-                * All we need to do is restart autoneg and enable autoneg.
-                */
-               reg |= E1000_PCS_LCTL_AN_RESTART | E1000_PCS_LCTL_AN_ENABLE;
-       } else {
-               /* Set PCS register for forced speed */
-
-               /* Turn off bits for full duplex, speed, and autoneg */
-               reg &= ~(E1000_PCS_LCTL_FSV_1000 |
-                        E1000_PCS_LCTL_FSV_100 |
-                        E1000_PCS_LCTL_FDV_FULL |
-                        E1000_PCS_LCTL_AN_ENABLE);
-
-               /* Check for duplex first */
-               if (mac->forced_speed_duplex & E1000_ALL_FULL_DUPLEX)
-                       reg |= E1000_PCS_LCTL_FDV_FULL;
-
-               /* Now set speed */
-               if (mac->forced_speed_duplex & E1000_ALL_100_SPEED)
-                       reg |= E1000_PCS_LCTL_FSV_100;
-
-               /* Force speed and force link */
-               reg |= E1000_PCS_LCTL_FSD |
-                      E1000_PCS_LCTL_FORCE_LINK |
-                      E1000_PCS_LCTL_FLV_LINK_UP;
+       if (!igb_sgmii_active_82575(hw))
+               igb_force_mac_fc(hw);
 
-               hw_dbg("Wrote 0x%08X to PCS_LCTL to configure forced link\n",
-                      reg);
-       }
-       wr32(E1000_PCS_LCTL, reg);
+       return 0;
 }
 
 /**
@@ -1248,7 +1233,8 @@ static void igb_clear_hw_cntrs_82575(struct e1000_hw *hw)
        temp = rd32(E1000_LENERRS);
 
        /* This register should not be read in copper configurations */
-       if (hw->phy.media_type == e1000_media_type_internal_serdes)
+       if (hw->phy.media_type == e1000_media_type_internal_serdes ||
+           igb_sgmii_active_82575(hw))
                temp = rd32(E1000_SCVPC);
 }
 
index 8a1e6597061f5463464078fd6a52c7f6c1cafe83..ebd146fd4e15dc975e05652134a36167b7ac94ee 100644 (file)
@@ -28,7 +28,7 @@
 #ifndef _E1000_82575_H_
 #define _E1000_82575_H_
 
-extern void igb_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw);
+extern void igb_shutdown_serdes_link_82575(struct e1000_hw *hw);
 extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw);
 
 #define ID_LED_DEFAULT_82575_SERDES ((ID_LED_DEF1_DEF2 << 12) | \
index c85829355d508c9917b84adedc4360b1af694f19..cb916833f303126beb0b35c4584ae91d0949be3c 100644 (file)
@@ -44,7 +44,7 @@
 #define E1000_WUFC_BC   0x00000010 /* Broadcast Wakeup Enable */
 
 /* Extended Device Control */
-#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Defineable Pin 7 */
+#define E1000_CTRL_EXT_SDP3_DATA 0x00000080 /* Value of SW Defineable Pin 3 */
 /* Physical Func Reset Done Indication */
 #define E1000_CTRL_EXT_PFRSTD    0x00004000
 #define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
index c1f4da630420f186dfbff445c65bd943b95a1738..ee460600e74b42d814722f949c659e08eb20752f 100644 (file)
@@ -1565,9 +1565,12 @@ out:
  **/
 s32 igb_phy_sw_reset(struct e1000_hw *hw)
 {
-       s32 ret_val;
+       s32 ret_val = 0;
        u16 phy_ctrl;
 
+       if (!(hw->phy.ops.read_reg))
+               goto out;
+
        ret_val = hw->phy.ops.read_reg(hw, PHY_CONTROL, &phy_ctrl);
        if (ret_val)
                goto out;
index 943186b78483f27d9f7fb6d761ea0f5f60158d07..d2639c4a086dfc0ed7f265c472b9df1c1edcb1db 100644 (file)
@@ -5320,7 +5320,7 @@ static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake)
 
        *enable_wake = wufc || adapter->en_mng_pt;
        if (!*enable_wake)
-               igb_shutdown_fiber_serdes_link_82575(hw);
+               igb_shutdown_serdes_link_82575(hw);
 
        /* Release control of h/w to f/w.  If f/w is AMT enabled, this
         * would have already happened in close and is redundant. */
index cb7f0c3c6e16ea40c2c1e2816d62635fb0cee305..56b12f3192f1d5b18d72b77bb03aab9807708b5f 100644 (file)
@@ -322,14 +322,16 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
                break;
        case IXGBE_DEV_ID_82598AF_DUAL_PORT:
        case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
-       case IXGBE_DEV_ID_82598EB_CX4:
-       case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
        case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
        case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
        case IXGBE_DEV_ID_82598EB_XF_LR:
        case IXGBE_DEV_ID_82598EB_SFP_LOM:
                media_type = ixgbe_media_type_fiber;
                break;
+       case IXGBE_DEV_ID_82598EB_CX4:
+       case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
+               media_type = ixgbe_media_type_cx4;
+               break;
        case IXGBE_DEV_ID_82598AT:
        case IXGBE_DEV_ID_82598AT2:
                media_type = ixgbe_media_type_copper;
index 61af47e75aa1c66670f284133a5351d99c69ad4b..2ec58dcdb82bf6fba6013599c7695eb76d0804bc 100644 (file)
@@ -337,6 +337,9 @@ static enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw)
        case IXGBE_DEV_ID_82599_SFP:
                media_type = ixgbe_media_type_fiber;
                break;
+       case IXGBE_DEV_ID_82599_CX4:
+               media_type = ixgbe_media_type_cx4;
+               break;
        default:
                media_type = ixgbe_media_type_unknown;
                break;
index 45bf8b9716e39b0172fc2ac883967437b22ce8e4..59ad9590e700c23b79a7a512c0818302408ae06a 100644 (file)
@@ -97,6 +97,8 @@ static struct pci_device_id ixgbe_pci_tbl[] = {
         board_82599 },
        {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP),
         board_82599 },
+       {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_CX4),
+        board_82599 },
 
        /* required last entry */
        {0, }
@@ -2055,6 +2057,8 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
 
                if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED)
                        rx_ring->flags |= IXGBE_RING_RX_PS_ENABLED;
+               else
+                       rx_ring->flags &= ~IXGBE_RING_RX_PS_ENABLED;
 
 #ifdef IXGBE_FCOE
                if (netdev->features & NETIF_F_FCOE_MTU) {
index 8ba90eec1dc9fe1b7da78628106e1e4c2dd3d5dd..8761d7899f7d0704440d4bb3766bc671e4043750 100644 (file)
@@ -49,6 +49,7 @@
 #define IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM      0x10E1
 #define IXGBE_DEV_ID_82598EB_XF_LR       0x10F4
 #define IXGBE_DEV_ID_82599_KX4           0x10F7
+#define IXGBE_DEV_ID_82599_CX4           0x10F9
 #define IXGBE_DEV_ID_82599_SFP           0x10FB
 #define IXGBE_DEV_ID_82599_XAUI_LOM      0x10FC
 
@@ -2143,6 +2144,7 @@ enum ixgbe_media_type {
        ixgbe_media_type_fiber,
        ixgbe_media_type_copper,
        ixgbe_media_type_backplane,
+       ixgbe_media_type_cx4,
        ixgbe_media_type_virtual
 };
 
index aa9674b7f19ce5f8f980da832f7e9e49746c2733..f599294fa8abbe0f7195fb8a7e6b539a60faf618 100644 (file)
@@ -96,12 +96,17 @@ static void catas_reset(struct work_struct *work)
        spin_unlock_irq(&catas_lock);
 
        list_for_each_entry_safe(priv, tmppriv, &tlist, catas_err.list) {
+               struct pci_dev *pdev = priv->dev.pdev;
+
                ret = mlx4_restart_one(priv->dev.pdev);
-               dev = &priv->dev;
+               /* 'priv' now is not valid */
                if (ret)
-                       mlx4_err(dev, "Reset failed (%d)\n", ret);
-               else
+                       printk(KERN_ERR "mlx4 %s: Reset failed (%d)\n",
+                               pci_name(pdev), ret);
+               else {
+                       dev  = pci_get_drvdata(pdev);
                        mlx4_dbg(dev, "Reset succeeded\n");
+               }
        }
 }
 
index 90a94d2158314341da9e915239d52452018cccfd..97db1c732342bac4229720951b4938e401a6a3f2 100644 (file)
@@ -1750,11 +1750,11 @@ static struct pcmcia_device_id pcnet_ids[] = {
        PCMCIA_DEVICE_PROD_ID2("EN-6200P2", 0xa996d078),
        /* too generic! */
        /* PCMCIA_DEVICE_PROD_ID12("PCMCIA", "10/100 Ethernet Card", 0x281f1c5d, 0x11b0ffc0), */
-       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "PCMLM28.cis"),
-       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "PCMLM28.cis"),
-       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "PCMLM28.cis"),
-       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "PCMLM28.cis"),
-       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "PCMLM28.cis"),
+       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "cis/PCMLM28.cis"),
+       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "cis/PCMLM28.cis"),
+       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"),
+       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "cis/PCMLM28.cis"),
+       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "cis/PCMLM28.cis"),
        PCMCIA_MFC_DEVICE_CIS_PROD_ID12(0, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "DP83903.cis"),
        PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "DP83903.cis"),
        PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "DP83903.cis"),
index e0f9219a0aea8b60927d3ec0ef6861d8b1880261..cc394d073755413c1bae92367c727f172b6d11e3 100644 (file)
@@ -229,7 +229,7 @@ static void pppol2tp_tunnel_free(struct pppol2tp_tunnel *tunnel);
 static atomic_t pppol2tp_tunnel_count;
 static atomic_t pppol2tp_session_count;
 static struct ppp_channel_ops pppol2tp_chan_ops = { pppol2tp_xmit , NULL };
-static struct proto_ops pppol2tp_ops;
+static const struct proto_ops pppol2tp_ops;
 
 /* per-net private data for this module */
 static int pppol2tp_net_id;
@@ -2574,7 +2574,7 @@ static const struct file_operations pppol2tp_proc_fops = {
  * Init and cleanup
  *****************************************************************************/
 
-static struct proto_ops pppol2tp_ops = {
+static const struct proto_ops pppol2tp_ops = {
        .family         = AF_PPPOX,
        .owner          = THIS_MODULE,
        .release        = pppol2tp_release,
index 00bc65a0aac9e609156cfde1cdd719acb6ca2916..4bb52e9cd371afc58db9e8620bf8a3182643f686 100644 (file)
@@ -65,8 +65,8 @@
 #define RX_DEF_PENDING         RX_MAX_PENDING
 
 /* This is the worst case number of transmit list elements for a single skb:
-   VLAN + TSO + CKSUM + Data + skb_frags * DMA */
-#define MAX_SKB_TX_LE  (4 + (sizeof(dma_addr_t)/sizeof(u32))*MAX_SKB_FRAGS)
+   VLAN:GSO + CKSUM + Data + skb_frags * DMA */
+#define MAX_SKB_TX_LE  (2 + (sizeof(dma_addr_t)/sizeof(u32))*(MAX_SKB_FRAGS+1))
 #define TX_MIN_PENDING         (MAX_SKB_TX_LE+1)
 #define TX_MAX_PENDING         4096
 #define TX_DEF_PENDING         127
@@ -1567,11 +1567,13 @@ static unsigned tx_le_req(const struct sk_buff *skb)
 {
        unsigned count;
 
-       count = sizeof(dma_addr_t) / sizeof(u32);
-       count += skb_shinfo(skb)->nr_frags * count;
+       count = (skb_shinfo(skb)->nr_frags + 1)
+               * (sizeof(dma_addr_t) / sizeof(u32));
 
        if (skb_is_gso(skb))
                ++count;
+       else if (sizeof(dma_addr_t) == sizeof(u32))
+               ++count;        /* possible vlan */
 
        if (skb->ip_summed == CHECKSUM_PARTIAL)
                ++count;
@@ -4548,16 +4550,18 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
        if (hw->ports > 1) {
                struct net_device *dev1;
 
+               err = -ENOMEM;
                dev1 = sky2_init_netdev(hw, 1, using_dac, wol_default);
-               if (!dev1)
-                       dev_warn(&pdev->dev, "allocation for second device failed\n");
-               else if ((err = register_netdev(dev1))) {
+               if (dev1 && (err = register_netdev(dev1)) == 0)
+                       sky2_show_addr(dev1);
+               else {
                        dev_warn(&pdev->dev,
                                 "register of second port failed (%d)\n", err);
                        hw->dev[1] = NULL;
-                       free_netdev(dev1);
-               } else
-                       sky2_show_addr(dev1);
+                       hw->ports = 1;
+                       if (dev1)
+                               free_netdev(dev1);
+               }
        }
 
        setup_timer(&hw->watchdog_timer, sky2_watchdog, (unsigned long) hw);
index 784b631cfa3cf9e4930886ffec6419c939e5012e..3911be7c0cba19b71181fbb9aa1bfd7b138d960b 100644 (file)
@@ -83,34 +83,6 @@ static inline void SMC_outw(u16 val, void __iomem *ioaddr, int reg)
        }
 }
 
-#elif defined(CONFIG_BLACKFIN)
-
-#define SMC_IRQ_FLAGS          IRQF_TRIGGER_HIGH
-#define RPC_LSA_DEFAULT                RPC_LED_100_10
-#define RPC_LSB_DEFAULT                RPC_LED_TX_RX
-
-#define SMC_CAN_USE_8BIT       0
-#define SMC_CAN_USE_16BIT      1
-# if defined(CONFIG_BF561)
-#define SMC_CAN_USE_32BIT      1
-# else
-#define SMC_CAN_USE_32BIT      0
-# endif
-#define SMC_IO_SHIFT           0
-#define SMC_NOWAIT             1
-#define SMC_USE_BFIN_DMA       0
-
-#define SMC_inw(a, r)          readw((a) + (r))
-#define SMC_outw(v, a, r)      writew(v, (a) + (r))
-#define SMC_insw(a, r, p, l)   readsw((a) + (r), p, l)
-#define SMC_outsw(a, r, p, l)  writesw((a) + (r), p, l)
-# if SMC_CAN_USE_32BIT
-#define SMC_inl(a, r)          readl((a) + (r))
-#define SMC_outl(v, a, r)      writel(v, (a) + (r))
-#define SMC_insl(a, r, p, l)   readsl((a) + (r), p, l)
-#define SMC_outsl(a, r, p, l)  writesl((a) + (r), p, l)
-# endif
-
 #elif defined(CONFIG_REDWOOD_5) || defined(CONFIG_REDWOOD_6)
 
 /* We can only do 16-bit reads and writes in the static memory space. */
index 97e54d9d03ce760bea2b7178b646c82a41d87c5c..33d5c579c5add542772afb6bf4327bdbb0ebc90b 100644 (file)
@@ -264,7 +264,6 @@ static int usbpn_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
        switch (cmd) {
        case SIOCPNGAUTOCONF:
                req->ifr_phonet_autoconf.device = PN_DEV_PC;
-               printk(KERN_CRIT"device is PN_DEV_PC\n");
                return 0;
        }
        return -ENOIOCTLCMD;
index ad89d23968dfa41f33cf3904a62bf3cb64404924..49ea9c92b7e6ea29e733ad2bac893660a074243a 100644 (file)
@@ -5,6 +5,7 @@
 menuconfig WLAN
        bool "Wireless LAN"
        depends on !S390
+       default y
        ---help---
          This section contains all the pre 802.11 and 802.11 wireless
          device drivers. For a complete list of drivers and documentation
index a7cbb07988cf3e00d90673163312c3fc1096481a..2b493742ef10c16b4a69cc96c06a3e3f3a9c6a2b 100644 (file)
@@ -327,7 +327,8 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
                                             aniState->firstepLevel + 1);
                return;
        } else {
-               if (conf->channel->band == IEEE80211_BAND_2GHZ) {
+               if ((conf->channel->band == IEEE80211_BAND_2GHZ) &&
+                   !conf_is_ht(conf)) {
                        if (!aniState->ofdmWeakSigDetectOff)
                                ath9k_hw_ani_control(ah,
                                     ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
@@ -369,7 +370,8 @@ static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah)
                        ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
                                             aniState->firstepLevel + 1);
        } else {
-               if (conf->channel->band == IEEE80211_BAND_2GHZ) {
+               if ((conf->channel->band == IEEE80211_BAND_2GHZ) &&
+                   !conf_is_ht(conf)) {
                        if (aniState->firstepLevel > 0)
                                ath9k_hw_ani_control(ah,
                                             ATH9K_ANI_FIRSTEP_LEVEL, 0);
index 7a9a3fa5542590f76d306f7f00be413cfb208486..e789792a36bc468f88d688f984c299a78927424c 100644 (file)
@@ -2289,11 +2289,7 @@ static int b43_upload_microcode(struct b43_wldev *dev)
                        err = -ENODEV;
                        goto error;
                }
-               msleep_interruptible(50);
-               if (signal_pending(current)) {
-                       err = -EINTR;
-                       goto error;
-               }
+               msleep(50);
        }
        b43_read32(dev, B43_MMIO_GEN_IRQ_REASON);       /* dummy read */
 
@@ -4287,6 +4283,8 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
        if (!dev->suspend_in_progress)
                b43_rng_init(wl);
 
+       ieee80211_wake_queues(dev->wl->hw);
+
        b43_set_status(dev, B43_STAT_INITIALIZED);
 
        if (!dev->suspend_in_progress)
index 6fe122f18c0dcd68f8de72db16cc3310338aaf2b..eb57d1ea361f73738ee22451e29e6b799a82db81 100644 (file)
@@ -875,15 +875,16 @@ void hostap_setup_dev(struct net_device *dev, local_info_t *local,
 
        switch(type) {
        case HOSTAP_INTERFACE_AP:
+               dev->tx_queue_len = 0;  /* use main radio device queue */
                dev->netdev_ops = &hostap_mgmt_netdev_ops;
                dev->type = ARPHRD_IEEE80211;
                dev->header_ops = &hostap_80211_ops;
                break;
        case HOSTAP_INTERFACE_MASTER:
-               dev->tx_queue_len = 0;  /* use main radio device queue */
                dev->netdev_ops = &hostap_master_ops;
                break;
        default:
+               dev->tx_queue_len = 0;  /* use main radio device queue */
                dev->netdev_ops = &hostap_netdev_ops;
        }
 
index 6a13bfbc9d988aaaacc98442c4c2e02547c0e400..ca61d3796cef644798a1d81e67e52c734f4854d7 100644 (file)
@@ -2346,6 +2346,7 @@ struct iwl_cfg iwl4965_agn_cfg = {
        .mod_params = &iwl4965_mod_params,
        .use_isr_legacy = true,
        .ht_greenfield_support = false,
+       .broken_powersave = true,
 };
 
 /* Module firmware */
index 40b207aa8fef44dae59c2a6e4117f5af978ba61a..346dc06fa7b77f79f5cdd986653e19b8d547bf56 100644 (file)
@@ -760,6 +760,7 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
        u16 high_low;
        u8 switch_to_legacy = 0;
        u8 is_green = lq_sta->is_green;
+       struct iwl_priv *priv = lq_sta->drv;
 
        /* check if we need to switch from HT to legacy rates.
         * assumption is that mandatory rates (1Mbps or 6Mbps)
@@ -773,7 +774,8 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
                        tbl->lq_type = LQ_G;
 
                if (num_of_ant(tbl->ant_type) > 1)
-                       tbl->ant_type = ANT_A;/*FIXME:RS*/
+                       tbl->ant_type =
+                               first_antenna(priv->hw_params.valid_tx_ant);
 
                tbl->is_ht40 = 0;
                tbl->is_SGI = 0;
@@ -883,6 +885,12 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
                mac_index &= RATE_MCS_CODE_MSK; /* Remove # of streams */
                if (mac_index >= (IWL_RATE_9M_INDEX - IWL_FIRST_OFDM_RATE))
                        mac_index++;
+               /*
+                * mac80211 HT index is always zero-indexed; we need to move
+                * HT OFDM rates after CCK rates in 2.4 GHz band
+                */
+               if (priv->band == IEEE80211_BAND_2GHZ)
+                       mac_index += IWL_FIRST_OFDM_RATE;
        }
 
        if ((mac_index < 0) ||
index acfd7b40afb8e3bf074098c3e172c571473a29d5..fd26c0dc9c544124b3bfb861519b058fdcb5e2c8 100644 (file)
@@ -1585,9 +1585,12 @@ int iwl_setup_mac(struct iwl_priv *priv)
        hw->flags = IEEE80211_HW_SIGNAL_DBM |
                    IEEE80211_HW_NOISE_DBM |
                    IEEE80211_HW_AMPDU_AGGREGATION |
-                   IEEE80211_HW_SPECTRUM_MGMT |
-                   IEEE80211_HW_SUPPORTS_PS |
-                   IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
+                   IEEE80211_HW_SPECTRUM_MGMT;
+
+       if (!priv->cfg->broken_powersave)
+               hw->flags |= IEEE80211_HW_SUPPORTS_PS |
+                            IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
+
        hw->wiphy->interface_modes =
                BIT(NL80211_IFTYPE_STATION) |
                BIT(NL80211_IFTYPE_ADHOC);
index c04d2a270819316edf341e89d943f1f3f5e59cac..7ff9ffb2b7026c2280e7623eaa77d95f4ad89e2d 100644 (file)
@@ -252,6 +252,7 @@ struct iwl_cfg {
        const u16 max_ll_items;
        const bool shadow_ram_support;
        const bool ht_greenfield_support;
+       const bool broken_powersave;
 };
 
 /***************************
index 4ec6a8307cc6bd35a067c4e26d681eadf3408a38..60be976afff8e49dd918d303f45e5fe6e9853759 100644 (file)
@@ -292,8 +292,9 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
        else
                dtimper = 1;
 
-       /* TT power setting overwrites everything */
-       if (tt->state >= IWL_TI_1)
+       if (priv->cfg->broken_powersave)
+               iwl_power_sleep_cam_cmd(priv, &cmd);
+       else if (tt->state >= IWL_TI_1)
                iwl_static_sleep_cmd(priv, &cmd, tt->tt_power_mode, dtimper);
        else if (!enabled)
                iwl_power_sleep_cam_cmd(priv, &cmd);
index 8150c5c3a16bf328e610ef5572a3dae2b579890c..b90adcb73b061d53dfe745112ce6c80e95e9cd1d 100644 (file)
@@ -239,26 +239,22 @@ void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority)
        struct iwl_rx_queue *rxq = &priv->rxq;
        struct list_head *element;
        struct iwl_rx_mem_buffer *rxb;
+       struct sk_buff *skb;
        unsigned long flags;
 
        while (1) {
                spin_lock_irqsave(&rxq->lock, flags);
-
                if (list_empty(&rxq->rx_used)) {
                        spin_unlock_irqrestore(&rxq->lock, flags);
                        return;
                }
-               element = rxq->rx_used.next;
-               rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
-               list_del(element);
-
                spin_unlock_irqrestore(&rxq->lock, flags);
 
                /* Alloc a new receive buffer */
-               rxb->skb = alloc_skb(priv->hw_params.rx_buf_size + 256,
+               skb = alloc_skb(priv->hw_params.rx_buf_size + 256,
                                                priority);
 
-               if (!rxb->skb) {
+               if (!skb) {
                        IWL_CRIT(priv, "Can not allocate SKB buffers\n");
                        /* We don't reschedule replenish work here -- we will
                         * call the restock method and if it still needs
@@ -266,6 +262,20 @@ void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority)
                        break;
                }
 
+               spin_lock_irqsave(&rxq->lock, flags);
+
+               if (list_empty(&rxq->rx_used)) {
+                       spin_unlock_irqrestore(&rxq->lock, flags);
+                       dev_kfree_skb_any(skb);
+                       return;
+               }
+               element = rxq->rx_used.next;
+               rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
+               list_del(element);
+
+               spin_unlock_irqrestore(&rxq->lock, flags);
+
+               rxb->skb = skb;
                /* Get physical address of RB/SKB */
                rxb->real_dma_addr = pci_map_single(
                                        priv->pci_dev,
index 2238c9f2018cdf345903115d70449cf7bd49c846..090966837f3cc1e6d37b9bd2117a47fdaa0b7c7b 100644 (file)
@@ -1134,6 +1134,7 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority)
        struct iwl_rx_queue *rxq = &priv->rxq;
        struct list_head *element;
        struct iwl_rx_mem_buffer *rxb;
+       struct sk_buff *skb;
        unsigned long flags;
 
        while (1) {
@@ -1143,17 +1144,11 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority)
                        spin_unlock_irqrestore(&rxq->lock, flags);
                        return;
                }
-
-               element = rxq->rx_used.next;
-               rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
-               list_del(element);
                spin_unlock_irqrestore(&rxq->lock, flags);
 
                /* Alloc a new receive buffer */
-               rxb->skb =
-                   alloc_skb(priv->hw_params.rx_buf_size,
-                               priority);
-               if (!rxb->skb) {
+               skb = alloc_skb(priv->hw_params.rx_buf_size, priority);
+               if (!skb) {
                        if (net_ratelimit())
                                IWL_CRIT(priv, ": Can not allocate SKB buffers\n");
                        /* We don't reschedule replenish work here -- we will
@@ -1162,6 +1157,19 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority)
                        break;
                }
 
+               spin_lock_irqsave(&rxq->lock, flags);
+               if (list_empty(&rxq->rx_used)) {
+                       spin_unlock_irqrestore(&rxq->lock, flags);
+                       dev_kfree_skb_any(skb);
+                       return;
+               }
+               element = rxq->rx_used.next;
+               rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
+               list_del(element);
+               spin_unlock_irqrestore(&rxq->lock, flags);
+
+               rxb->skb = skb;
+
                /* If radiotap head is required, reserve some headroom here.
                 * The physical head count is a variable rx_stats->phy_count.
                 * We reserve 4 bytes here. Plus these extra bytes, the
index e44460ff149cb4a4eddd82fc600af71fc63c3e90..17e199546eebca34e7089e93382739005e7241fc 100644 (file)
@@ -67,6 +67,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {
        {USB_DEVICE(0x0bf8, 0x1009)},   /* FUJITSU E-5400 USB D1700*/
        {USB_DEVICE(0x0cde, 0x0006)},   /* Medion MD40900 */
        {USB_DEVICE(0x0cde, 0x0008)},   /* Sagem XG703A */
+       {USB_DEVICE(0x0cde, 0x0015)},   /* Zcomax XG-705A */
        {USB_DEVICE(0x0d8e, 0x3762)},   /* DLink DWL-G120 Cohiba */
        {USB_DEVICE(0x124a, 0x4025)},   /* IOGear GWU513 (GW3887IK chip) */
        {USB_DEVICE(0x1260, 0xee22)},   /* SMC 2862W-G version 2 */
index d9169b47ac422fdfcd0eb6cc45088f97447fa56f..27298b19d5bd393592da7a165887ba21c0c97067 100644 (file)
@@ -644,11 +644,10 @@ static int wl1271_op_config_interface(struct ieee80211_hw *hw,
 {
        struct wl1271 *wl = hw->priv;
        struct sk_buff *beacon;
-       DECLARE_MAC_BUF(mac);
        int ret;
 
-       wl1271_debug(DEBUG_MAC80211, "mac80211 config_interface bssid %s",
-                    print_mac(mac, conf->bssid));
+       wl1271_debug(DEBUG_MAC80211, "mac80211 config_interface bssid %pM",
+                    conf->bssid);
        wl1271_dump_ascii(DEBUG_MAC80211, "ssid: ", conf->ssid,
                          conf->ssid_len);
 
index 79c9c5f5cdbae6995774d88b22fa61b370bc4eb3..ed4648b556c775a030f27a967fab4d543f26ea6a 100644 (file)
@@ -868,11 +868,11 @@ static struct pcmcia_device_id serial_ids[] = {
        PCMCIA_DEVICE_PROD_ID12("PCMCIA   ", "C336MX     ", 0x99bcafe9, 0xaa25bcab),
        PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "PCMCIA Dual RS-232 Serial Port Card", 0xc4420b35, 0x92abc92f),
        PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "Dual RS-232 Serial Port PC Card", 0xc4420b35, 0x031a380d),
-       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "PCMLM28.cis"),
-       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "PCMLM28.cis"),
-       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "PCMLM28.cis"),
-       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "PCMLM28.cis"),
-       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "PCMLM28.cis"),
+       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "cis/PCMLM28.cis"),
+       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "cis/PCMLM28.cis"),
+       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"),
+       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "cis/PCMLM28.cis"),
+       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "cis/PCMLM28.cis"),
        PCMCIA_MFC_DEVICE_CIS_PROD_ID12(1, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "DP83903.cis"),
        PCMCIA_MFC_DEVICE_CIS_PROD_ID4(1, "NSC MF LAN/Modem", 0x58fc6056, "DP83903.cis"),
        PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0556, "cis/3CCFEM556.cis"),
@@ -883,10 +883,10 @@ static struct pcmcia_device_id serial_ids[] = {
        PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0x0710, "SW_7xx_SER.cis"),  /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */
        PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "SW_555_SER.cis"),  /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */
        PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "SW_555_SER.cis"),  /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */
-       PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "MT5634ZLX.cis"),
+       PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "cis/MT5634ZLX.cis"),
        PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "COMpad4.cis"),
        PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "COMpad2.cis"),
-       PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "RS-COM-2P.cis"),
+       PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "cis/RS-COM-2P.cis"),
        PCMCIA_DEVICE_CIS_MANF_CARD(0x0013, 0x0000, "GLOBETROTTER.cis"),
        PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100  1.00.",0x19ca78af,0xf964f42b),
        PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100",0x19ca78af,0x71d98e83),
index f853d5600ca778fa447f0ee6acee1bf6c2d3899f..9e50896233aa969e5fa145bcf630dd0ba9055363 100644 (file)
@@ -600,6 +600,7 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out,
                        ssb_printk(KERN_WARNING PFX "Unsupported SPROM"
                                   "  revision %d detected. Will extract"
                                   " v1\n", out->revision);
+                       out->revision = 1;
                        sprom_extract_r123(out, in);
                }
        }
index 114051056b52ceb6bced555561aa4ae51a674ec6..65a6080cb02af83bc39083fa00da1d64cc3acf50 100644 (file)
@@ -21,7 +21,7 @@
 #include "ssb_private.h"
 
 /* Define the following to 1 to enable a printk on each coreswitch. */
-#define SSB_VERBOSE_SDIOCORESWITCH_DEBUG               1
+#define SSB_VERBOSE_SDIOCORESWITCH_DEBUG               0
 
 
 /* Hardware invariants CIS tuples */
@@ -333,7 +333,7 @@ static void ssb_sdio_block_read(struct ssb_device *dev, void *buffer,
                goto out;
 
 err_out:
-       dev_dbg(ssb_sdio_dev(bus), "%04X:%04X (width=%u, len=%u), error %d\n",
+       dev_dbg(ssb_sdio_dev(bus), "%04X:%04X (width=%u, len=%zu), error %d\n",
                bus->sdio_sbaddr >> 16, offset, reg_width, saved_count, error);
 out:
        sdio_release_host(bus->host_sdio);
@@ -440,7 +440,7 @@ static void ssb_sdio_block_write(struct ssb_device *dev, const void *buffer,
                goto out;
 
 err_out:
-       dev_dbg(ssb_sdio_dev(bus), "%04X:%04X (width=%u, len=%u), error %d\n",
+       dev_dbg(ssb_sdio_dev(bus), "%04X:%04X (width=%u, len=%zu), error %d\n",
                bus->sdio_sbaddr >> 16, offset, reg_width, saved_count, error);
 out:
        sdio_release_host(bus->host_sdio);
index c987a75a20cff2b78fb7d39ad8f903c41daeac42..f45dc49512f2ea04ddd4383a4cbb16c9500f1691 100644 (file)
@@ -421,7 +421,7 @@ static inline int cvmx_mdio_45_read(int bus_id, int phy_id, int device,
        do {
                cvmx_wait(1000);
                smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(bus_id));
-       } while (smi_rd.s.pending && timeout--);
+       } while (smi_rd.s.pending && --timeout);
 
        if (timeout <= 0) {
                cvmx_dprintf("cvmx_mdio_45_read: bus_id %d phy_id %2d "
index 9052bcb4f528d206437f9a3e3c4212b211938d12..e7eeb63fab23a11632a1b94176def00e28bc9d27 100644 (file)
@@ -887,8 +887,7 @@ static int hwarc_post_reset(struct usb_interface *iface)
        struct hwarc *hwarc = usb_get_intfdata(iface);
        struct uwb_rc *uwb_rc = hwarc->uwb_rc;
 
-       uwb_rc_post_reset(uwb_rc);
-       return 0;
+       return uwb_rc_post_reset(uwb_rc);
 }
 
 /** USB device ID's that we handle */
index 9cf21e6bb624e036b6f698bc975f7e66080ca16e..9611ef3b787a39c3de7b295c39d99a7e376a2afe 100644 (file)
@@ -288,8 +288,8 @@ error_sys_add:
 error_dev_add:
 error_rc_setup:
        rc->stop(rc);
-       uwbd_stop(rc);
 error_rc_start:
+       uwbd_stop(rc);
        return result;
 }
 EXPORT_SYMBOL_GPL(uwb_rc_add);
index 70f8050221ff5efe5d0e733541f2465e63b41ee0..7f0512e43d9dea10c5005e298ac0902c32ae0c70 100644 (file)
@@ -30,6 +30,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/err.h>
+#include <linux/delay.h>
 
 #include "uwb-internal.h"
 
@@ -323,13 +324,15 @@ int uwbd_msg_handle_reset(struct uwb_event *evt)
 
        dev_info(&rc->uwb_dev.dev, "resetting radio controller\n");
        ret = rc->reset(rc);
-       if (ret) {
+       if (ret < 0) {
                dev_err(&rc->uwb_dev.dev, "failed to reset hardware: %d\n", ret);
                goto error;
        }
        return 0;
 error:
-       /* Nothing can be done except try the reset again. */
+       /* Nothing can be done except try the reset again. Wait a bit
+          to avoid reset loops during probe() or remove(). */
+       msleep(1000);
        uwb_rc_reset_all(rc);
        return ret;
 }
@@ -368,22 +371,20 @@ void uwb_rc_pre_reset(struct uwb_rc *rc)
 }
 EXPORT_SYMBOL_GPL(uwb_rc_pre_reset);
 
-void uwb_rc_post_reset(struct uwb_rc *rc)
+int uwb_rc_post_reset(struct uwb_rc *rc)
 {
        int ret;
 
        ret = rc->start(rc);
        if (ret)
-               goto error;
+               goto out;
        ret = uwb_rc_mac_addr_set(rc, &rc->uwb_dev.mac_addr);
        if (ret)
-               goto error;
+               goto out;
        ret = uwb_rc_dev_addr_set(rc, &rc->uwb_dev.dev_addr);
        if (ret)
-               goto error;
-       return;
-error:
-       /* Nothing can be done except try the reset again. */
-       uwb_rc_reset_all(rc);
+               goto out;
+out:
+       return ret;
 }
 EXPORT_SYMBOL_GPL(uwb_rc_post_reset);
index 5ad36164c13b374ab26dbdd0e435dcf6f2a40483..cdd6c8efc9f8ccadef82a989f2269ffd17f01151 100644 (file)
@@ -66,7 +66,7 @@ int umc_controller_reset(struct umc_dev *umc)
                return -EAGAIN;
        ret = device_for_each_child(parent, parent, umc_bus_pre_reset_helper);
        if (ret >= 0)
-               device_for_each_child(parent, parent, umc_bus_post_reset_helper);
+               ret = device_for_each_child(parent, parent, umc_bus_post_reset_helper);
        up(&parent->sem);
 
        return ret;
index 57bd6bfef37e95cca10ec3c2133e7f19f7d7c28a..5a777d8624da3f791bc08c2228de6b256a6d3bdc 100644 (file)
@@ -187,12 +187,12 @@ int uwbd_event_handle_urc(struct uwb_event *evt)
        event = le16_to_cpu(evt->notif.rceb->wEvent);
        context = evt->notif.rceb->bEventContext;
 
-       if (type > ARRAY_SIZE(uwbd_urc_evt_type_handlers))
+       if (type >= ARRAY_SIZE(uwbd_urc_evt_type_handlers))
                goto out;
        type_table = &uwbd_urc_evt_type_handlers[type];
        if (type_table->uwbd_events == NULL)
                goto out;
-       if (event > type_table->size)
+       if (event >= type_table->size)
                goto out;
        handler = type_table->uwbd_events[event].handler;
        if (handler == NULL)
index 19a1dd1292125b644e4728e8f677f3510bff8281..1d9a6f54658ecf1383094edf3f98020d7247bccf 100644 (file)
@@ -443,8 +443,7 @@ static int whcrc_post_reset(struct umc_dev *umc)
        struct whcrc *whcrc = umc_get_drvdata(umc);
        struct uwb_rc *uwb_rc = whcrc->uwb_rc;
 
-       uwb_rc_post_reset(uwb_rc);
-       return 0;
+       return uwb_rc_post_reset(uwb_rc);
 }
 
 /* PCI device ID's that we handle [so it gets loaded] */
diff --git a/drivers/video/console/.gitignore b/drivers/video/console/.gitignore
deleted file mode 100644 (file)
index 0c258b4..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-# conmakehash generated file
-promcon_tbl.c
index 2f50a80b413e07910e64c49598284f9361810728..fc7d9bbb548c4637e329080d2ca6110bff86cd75 100644 (file)
@@ -67,16 +67,9 @@ config SGI_NEWPORT_CONSOLE
 
 #  bool 'IODC console' CONFIG_IODC_CONSOLE
 
-config PROM_CONSOLE
-       bool "PROM console"
-       depends on SPARC
-       help
-         Say Y to build a console driver for Sun machines that uses the
-         terminal emulation built into their console PROMS.
-
 config DUMMY_CONSOLE
        bool
-       depends on PROM_CONSOLE!=y || VGA_CONSOLE!=y || SGI_NEWPORT_CONSOLE!=y 
+       depends on VGA_CONSOLE!=y || SGI_NEWPORT_CONSOLE!=y 
        default y
 
 config DUMMY_CONSOLE_COLUMNS
index ac46cc3f6a2a1286586d51cc3bec3dce23ff0d19..a862e9173ebed67d67cac954a98eb70a9f94c346 100644 (file)
@@ -22,7 +22,6 @@ font-objs += $(font-objs-y)
 
 obj-$(CONFIG_DUMMY_CONSOLE)       += dummycon.o
 obj-$(CONFIG_SGI_NEWPORT_CONSOLE) += newport_con.o font.o
-obj-$(CONFIG_PROM_CONSOLE)        += promcon.o promcon_tbl.o
 obj-$(CONFIG_STI_CONSOLE)         += sticon.o sticore.o font.o
 obj-$(CONFIG_VGA_CONSOLE)         += vgacon.o
 obj-$(CONFIG_MDA_CONSOLE)         += mdacon.o
@@ -40,14 +39,3 @@ obj-$(CONFIG_FB_STI)              += sticore.o font.o
 ifeq ($(CONFIG_USB_SISUSBVGA_CON),y)
 obj-$(CONFIG_USB_SISUSBVGA)           += font.o
 endif
-
-# Targets that kbuild needs to know about
-targets := promcon_tbl.c
-
-quiet_cmd_conmakehash = CNMKHSH $@
-      cmd_conmakehash = scripts/conmakehash $< | \
-               sed -e '/\#include <[^>]*>/p' -e 's/types/init/' \
-               -e 's/dfont\(_uni.*\]\)/promfont\1 /' > $@
-
-$(obj)/promcon_tbl.c: $(src)/prom.uni
-       $(call cmd,conmakehash)
diff --git a/drivers/video/console/prom.uni b/drivers/video/console/prom.uni
deleted file mode 100644 (file)
index 58f9c04..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# Unicode mapping table for font in Sun PROM
-# 
-#
-0x20-0x7e      idem
-0xa0-0xff      idem
-#
-0x7c           U+2502
-0x2d           U+2500
-0x2b           U+250c U+2510 U+2514 U+2518 U+251c U+2524 U+252c U+2534 U+253c
-0xa4           U+fffd
diff --git a/drivers/video/console/promcon.c b/drivers/video/console/promcon.c
deleted file mode 100644 (file)
index ae02e4e..0000000
+++ /dev/null
@@ -1,598 +0,0 @@
-/* $Id: promcon.c,v 1.17 2000/07/26 23:02:52 davem Exp $
- * Console driver utilizing PROM sun terminal emulation
- *
- * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
- * Copyright (C) 1998  Jakub Jelinek  (jj@ultra.linux.cz)
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/console.h>
-#include <linux/vt_kern.h>
-#include <linux/selection.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/kd.h>
-
-#include <asm/oplib.h>
-#include <asm/uaccess.h>
-
-static short pw = 80 - 1, ph = 34 - 1;
-static short px, py;
-static unsigned long promcon_uni_pagedir[2];
-
-extern u8 promfont_unicount[];
-extern u16 promfont_unitable[];
-
-#define PROMCON_COLOR 0
-
-#if PROMCON_COLOR
-#define inverted(s)    ((((s) & 0x7700) == 0x0700) ? 0 : 1)
-#else
-#define inverted(s)    (((s) & 0x0800) ? 1 : 0)
-#endif
-
-static __inline__ void
-promcon_puts(char *buf, int cnt)
-{
-       prom_printf("%*.*s", cnt, cnt, buf);
-}
-
-static int
-promcon_start(struct vc_data *conp, char *b)
-{
-       unsigned short *s = (unsigned short *)
-                       (conp->vc_origin + py * conp->vc_size_row + (px << 1));
-       u16 cs;
-
-       cs = scr_readw(s);
-       if (px == pw) {
-               unsigned short *t = s - 1;
-               u16 ct = scr_readw(t);
-
-               if (inverted(cs) && inverted(ct))
-                       return sprintf(b, "\b\033[7m%c\b\033[@%c\033[m", cs,
-                                      ct);
-               else if (inverted(cs))
-                       return sprintf(b, "\b\033[7m%c\033[m\b\033[@%c", cs,
-                                      ct);
-               else if (inverted(ct))
-                       return sprintf(b, "\b%c\b\033[@\033[7m%c\033[m", cs,
-                                      ct);
-               else
-                       return sprintf(b, "\b%c\b\033[@%c", cs, ct);
-       }
-
-       if (inverted(cs))
-               return sprintf(b, "\033[7m%c\033[m\b", cs);
-       else
-               return sprintf(b, "%c\b", cs);
-}
-
-static int
-promcon_end(struct vc_data *conp, char *b)
-{
-       unsigned short *s = (unsigned short *)
-                       (conp->vc_origin + py * conp->vc_size_row + (px << 1));
-       char *p = b;
-       u16 cs;
-
-       b += sprintf(b, "\033[%d;%dH", py + 1, px + 1);
-
-       cs = scr_readw(s);
-       if (px == pw) {
-               unsigned short *t = s - 1;
-               u16 ct = scr_readw(t);
-
-               if (inverted(cs) && inverted(ct))
-                       b += sprintf(b, "\b%c\b\033[@\033[7m%c\033[m", cs, ct);
-               else if (inverted(cs))
-                       b += sprintf(b, "\b%c\b\033[@%c", cs, ct);
-               else if (inverted(ct))
-                       b += sprintf(b, "\b\033[7m%c\b\033[@%c\033[m", cs, ct);
-               else
-                       b += sprintf(b, "\b\033[7m%c\033[m\b\033[@%c", cs, ct);
-               return b - p;
-       }
-
-       if (inverted(cs))
-               b += sprintf(b, "%c\b", cs);
-       else
-               b += sprintf(b, "\033[7m%c\033[m\b", cs);
-       return b - p;
-}
-
-const char *promcon_startup(void)
-{
-       const char *display_desc = "PROM";
-       int node;
-       char buf[40];
-       
-       node = prom_getchild(prom_root_node);
-       node = prom_searchsiblings(node, "options");
-       if (prom_getproperty(node,  "screen-#columns", buf, 40) != -1) {
-               pw = simple_strtoul(buf, NULL, 0);
-               if (pw < 10 || pw > 256)
-                       pw = 80;
-               pw--;
-       }
-       if (prom_getproperty(node,  "screen-#rows", buf, 40) != -1) {
-               ph = simple_strtoul(buf, NULL, 0);
-               if (ph < 10 || ph > 256)
-                       ph = 34;
-               ph--;
-       }
-       promcon_puts("\033[H\033[J", 6);
-       return display_desc;
-}
-
-static void
-promcon_init_unimap(struct vc_data *conp)
-{
-       mm_segment_t old_fs = get_fs();
-       struct unipair *p, *p1;
-       u16 *q;
-       int i, j, k;
-       
-       p = kmalloc(256*sizeof(struct unipair), GFP_KERNEL);
-       if (!p) return;
-       
-       q = promfont_unitable;
-       p1 = p;
-       k = 0;
-       for (i = 0; i < 256; i++)
-               for (j = promfont_unicount[i]; j; j--) {
-                       p1->unicode = *q++;
-                       p1->fontpos = i;
-                       p1++;
-                       k++;
-               }
-       set_fs(KERNEL_DS);
-       con_clear_unimap(conp, NULL);
-       con_set_unimap(conp, k, p);
-       con_protect_unimap(conp, 1);
-       set_fs(old_fs);
-       kfree(p);
-}
-
-static void
-promcon_init(struct vc_data *conp, int init)
-{
-       unsigned long p;
-       
-       conp->vc_can_do_color = PROMCON_COLOR;
-       if (init) {
-               conp->vc_cols = pw + 1;
-               conp->vc_rows = ph + 1;
-       }
-       p = *conp->vc_uni_pagedir_loc;
-       if (conp->vc_uni_pagedir_loc == &conp->vc_uni_pagedir ||
-           !--conp->vc_uni_pagedir_loc[1])
-               con_free_unimap(conp);
-       conp->vc_uni_pagedir_loc = promcon_uni_pagedir;
-       promcon_uni_pagedir[1]++;
-       if (!promcon_uni_pagedir[0] && p) {
-               promcon_init_unimap(conp);
-       }
-       if (!init) {
-               if (conp->vc_cols != pw + 1 || conp->vc_rows != ph + 1)
-                       vc_resize(conp, pw + 1, ph + 1);
-       }
-}
-
-static void
-promcon_deinit(struct vc_data *conp)
-{
-       /* When closing the last console, reset video origin */
-       if (!--promcon_uni_pagedir[1])
-               con_free_unimap(conp);
-       conp->vc_uni_pagedir_loc = &conp->vc_uni_pagedir;
-       con_set_default_unimap(conp);
-}
-
-static int
-promcon_switch(struct vc_data *conp)
-{
-       return 1;
-}
-
-static unsigned short *
-promcon_repaint_line(unsigned short *s, unsigned char *buf, unsigned char **bp)
-{
-       int cnt = pw + 1;
-       int attr = -1;
-       unsigned char *b = *bp;
-
-       while (cnt--) {
-               u16 c = scr_readw(s);
-               if (attr != inverted(c)) {
-                       attr = inverted(c);
-                       if (attr) {
-                               strcpy (b, "\033[7m");
-                               b += 4;
-                       } else {
-                               strcpy (b, "\033[m");
-                               b += 3;
-                       }
-               }
-               *b++ = c;
-               s++;
-               if (b - buf >= 224) {
-                       promcon_puts(buf, b - buf);
-                       b = buf;
-               }
-       }
-       *bp = b;
-       return s;
-}
-
-static void
-promcon_putcs(struct vc_data *conp, const unsigned short *s,
-             int count, int y, int x)
-{
-       unsigned char buf[256], *b = buf;
-       unsigned short attr = scr_readw(s);
-       unsigned char save;
-       int i, last = 0;
-
-       if (console_blanked)
-               return;
-       
-       if (count <= 0)
-               return;
-
-       b += promcon_start(conp, b);
-
-       if (x + count >= pw + 1) {
-               if (count == 1) {
-                       x -= 1;
-                       save = scr_readw((unsigned short *)(conp->vc_origin
-                                                  + y * conp->vc_size_row
-                                                  + (x << 1)));
-
-                       if (px != x || py != y) {
-                               b += sprintf(b, "\033[%d;%dH", y + 1, x + 1);
-                               px = x;
-                               py = y;
-                       }
-
-                       if (inverted(attr))
-                               b += sprintf(b, "\033[7m%c\033[m", scr_readw(s++));
-                       else
-                               b += sprintf(b, "%c", scr_readw(s++));
-
-                       strcpy(b, "\b\033[@");
-                       b += 4;
-
-                       if (inverted(save))
-                               b += sprintf(b, "\033[7m%c\033[m", save);
-                       else
-                               b += sprintf(b, "%c", save);
-
-                       px++;
-
-                       b += promcon_end(conp, b);
-                       promcon_puts(buf, b - buf);
-                       return;
-               } else {
-                       last = 1;
-                       count = pw - x - 1;
-               }
-       }
-
-       if (inverted(attr)) {
-               strcpy(b, "\033[7m");
-               b += 4;
-       }
-
-       if (px != x || py != y) {
-               b += sprintf(b, "\033[%d;%dH", y + 1, x + 1);
-               px = x;
-               py = y;
-       }
-
-       for (i = 0; i < count; i++) {
-               if (b - buf >= 224) {
-                       promcon_puts(buf, b - buf);
-                       b = buf;
-               }
-               *b++ = scr_readw(s++);
-       }
-
-       px += count;
-
-       if (last) {
-               save = scr_readw(s++);
-               b += sprintf(b, "%c\b\033[@%c", scr_readw(s++), save);
-               px++;
-       }
-
-       if (inverted(attr)) {
-               strcpy(b, "\033[m");
-               b += 3;
-       }
-
-       b += promcon_end(conp, b);
-       promcon_puts(buf, b - buf);
-}
-
-static void
-promcon_putc(struct vc_data *conp, int c, int y, int x)
-{
-       unsigned short s;
-
-       if (console_blanked)
-               return;
-       
-       scr_writew(c, &s);
-       promcon_putcs(conp, &s, 1, y, x);
-}
-
-static void
-promcon_clear(struct vc_data *conp, int sy, int sx, int height, int width)
-{
-       unsigned char buf[256], *b = buf;
-       int i, j;
-
-       if (console_blanked)
-               return;
-       
-       b += promcon_start(conp, b);
-
-       if (!sx && width == pw + 1) {
-
-               if (!sy && height == ph + 1) {
-                       strcpy(b, "\033[H\033[J");
-                       b += 6;
-                       b += promcon_end(conp, b);
-                       promcon_puts(buf, b - buf);
-                       return;
-               } else if (sy + height == ph + 1) {
-                       b += sprintf(b, "\033[%dH\033[J", sy + 1);
-                       b += promcon_end(conp, b);
-                       promcon_puts(buf, b - buf);
-                       return;
-               }
-
-               b += sprintf(b, "\033[%dH", sy + 1);
-               for (i = 1; i < height; i++) {
-                       strcpy(b, "\033[K\n");
-                       b += 4;
-               }
-
-               strcpy(b, "\033[K");
-               b += 3;
-
-               b += promcon_end(conp, b);
-               promcon_puts(buf, b - buf);
-               return;
-
-       } else if (sx + width == pw + 1) {
-
-               b += sprintf(b, "\033[%d;%dH", sy + 1, sx + 1);
-               for (i = 1; i < height; i++) {
-                       strcpy(b, "\033[K\n");
-                       b += 4;
-               }
-
-               strcpy(b, "\033[K");
-               b += 3;
-
-               b += promcon_end(conp, b);
-               promcon_puts(buf, b - buf);
-               return;
-       }
-
-       for (i = sy + 1; i <= sy + height; i++) {
-               b += sprintf(b, "\033[%d;%dH", i, sx + 1);
-               for (j = 0; j < width; j++)
-                       *b++ = ' ';
-               if (b - buf + width >= 224) {
-                       promcon_puts(buf, b - buf);
-                       b = buf;
-               }
-       }
-
-       b += promcon_end(conp, b);
-       promcon_puts(buf, b - buf);
-}
-                        
-static void
-promcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
-             int height, int width)
-{
-       char buf[256], *b = buf;
-
-       if (console_blanked)
-               return;
-       
-       b += promcon_start(conp, b);
-       if (sy == dy && height == 1) {
-               if (dx > sx && dx + width == conp->vc_cols)
-                       b += sprintf(b, "\033[%d;%dH\033[%d@\033[%d;%dH",
-                                    sy + 1, sx + 1, dx - sx, py + 1, px + 1);
-               else if (dx < sx && sx + width == conp->vc_cols)
-                       b += sprintf(b, "\033[%d;%dH\033[%dP\033[%d;%dH",
-                                    dy + 1, dx + 1, sx - dx, py + 1, px + 1);
-
-               b += promcon_end(conp, b);
-               promcon_puts(buf, b - buf);
-               return;
-       }
-
-       /*
-        * FIXME: What to do here???
-        * Current console.c should not call it like that ever.
-        */
-       prom_printf("\033[7mFIXME: bmove not handled\033[m\n");
-}
-
-static void
-promcon_cursor(struct vc_data *conp, int mode)
-{
-       char buf[32], *b = buf;
-
-       switch (mode) {
-       case CM_ERASE:
-               break;
-
-       case CM_MOVE:
-       case CM_DRAW:
-               b += promcon_start(conp, b);
-               if (px != conp->vc_x || py != conp->vc_y) {
-                       px = conp->vc_x;
-                       py = conp->vc_y;
-                       b += sprintf(b, "\033[%d;%dH", py + 1, px + 1);
-               }
-               promcon_puts(buf, b - buf);
-               break;
-       }
-}
-
-static int
-promcon_blank(struct vc_data *conp, int blank, int mode_switch)
-{
-       if (blank) {
-               promcon_puts("\033[H\033[J\033[7m \033[m\b", 15);
-               return 0;
-       } else {
-               /* Let console.c redraw */
-               return 1;
-       }
-}
-
-static int
-promcon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
-{
-       unsigned char buf[256], *p = buf;
-       unsigned short *s;
-       int i;
-
-       if (console_blanked)
-               return 0;
-       
-       p += promcon_start(conp, p);
-
-       switch (dir) {
-       case SM_UP:
-               if (b == ph + 1) {
-                       p += sprintf(p, "\033[%dH\033[%dM", t + 1, count);
-                       px = 0;
-                       py = t;
-                       p += promcon_end(conp, p);
-                       promcon_puts(buf, p - buf);
-                       break;
-               }
-
-               s = (unsigned short *)(conp->vc_origin
-                                      + (t + count) * conp->vc_size_row);
-
-               p += sprintf(p, "\033[%dH", t + 1);
-
-               for (i = t; i < b - count; i++)
-                       s = promcon_repaint_line(s, buf, &p);
-
-               for (; i < b - 1; i++) {
-                       strcpy(p, "\033[K\n");
-                       p += 4;
-                       if (p - buf >= 224) {
-                               promcon_puts(buf, p - buf);
-                               p = buf;
-                       }
-               }
-
-               strcpy(p, "\033[K");
-               p += 3;
-
-               p += promcon_end(conp, p);
-               promcon_puts(buf, p - buf);
-               break;
-
-       case SM_DOWN:
-               if (b == ph + 1) {
-                       p += sprintf(p, "\033[%dH\033[%dL", t + 1, count);
-                       px = 0;
-                       py = t;
-                       p += promcon_end(conp, p);
-                       promcon_puts(buf, p - buf);
-                       break;
-               }
-
-               s = (unsigned short *)(conp->vc_origin + t * conp->vc_size_row);
-
-               p += sprintf(p, "\033[%dH", t + 1);
-
-               for (i = t; i < t + count; i++) {
-                       strcpy(p, "\033[K\n");
-                       p += 4;
-                       if (p - buf >= 224) {
-                               promcon_puts(buf, p - buf);
-                               p = buf;
-                       }
-               }
-
-               for (; i < b; i++)
-                       s = promcon_repaint_line(s, buf, &p);
-
-               p += promcon_end(conp, p);
-               promcon_puts(buf, p - buf);
-               break;
-       }
-
-       return 0;
-}
-
-#if !(PROMCON_COLOR)
-static u8 promcon_build_attr(struct vc_data *conp, u8 _color, u8 _intensity,
-    u8 _blink, u8 _underline, u8 _reverse, u8 _italic)
-{
-       return (_reverse) ? 0xf : 0x7;
-}
-#endif
-
-/*
- *  The console 'switch' structure for the VGA based console
- */
-
-static int promcon_dummy(void)
-{
-        return 0;
-}
-
-#define DUMMY (void *) promcon_dummy
-
-const struct consw prom_con = {
-       .owner =                THIS_MODULE,
-       .con_startup =          promcon_startup,
-       .con_init =             promcon_init,
-       .con_deinit =           promcon_deinit,
-       .con_clear =            promcon_clear,
-       .con_putc =             promcon_putc,
-       .con_putcs =            promcon_putcs,
-       .con_cursor =           promcon_cursor,
-       .con_scroll =           promcon_scroll,
-       .con_bmove =            promcon_bmove,
-       .con_switch =           promcon_switch,
-       .con_blank =            promcon_blank,
-       .con_set_palette =      DUMMY,
-       .con_scrolldelta =      DUMMY,
-#if !(PROMCON_COLOR)
-       .con_build_attr =       promcon_build_attr,
-#endif
-};
-
-void __init prom_con_init(void)
-{
-#ifdef CONFIG_DUMMY_CONSOLE
-       if (conswitchp == &dummy_con)
-               take_over_console(&prom_con, 0, MAX_NR_CONSOLES-1, 1);
-       else
-#endif
-       if (conswitchp == &prom_con)
-               promcon_init_unimap(vc_cons[fg_console].d);
-}
index 878329cf4825f0db87b42ad67db6b6286b9d7183..ffe2663d49f2f1e15b4133efe1133d9119c57f20 100644 (file)
@@ -51,9 +51,10 @@ fw-shipped-$(CONFIG_DVB_TTUSB_BUDGET) += ttusb-budget/dspbootcode.bin
 fw-shipped-$(CONFIG_E100) += e100/d101m_ucode.bin e100/d101s_ucode.bin \
                             e100/d102e_ucode.bin
 fw-shipped-$(CONFIG_MYRI_SBUS) += myricom/lanai.bin
-fw-shipped-$(CONFIG_PCMCIA_PCNET) += cis/LA-PCM.cis
+fw-shipped-$(CONFIG_PCMCIA_PCNET) += cis/LA-PCM.cis cis/PCMLM28.cis
 fw-shipped-$(CONFIG_PCMCIA_3C589) += cis/3CXEM556.cis
 fw-shipped-$(CONFIG_PCMCIA_3C574) += cis/3CCFEM556.cis
+fw-shipped-$(CONFIG_SERIAL_8250_CS) += cis/MT5634ZLX.cis cis/RS-COM-2P.cis
 fw-shipped-$(CONFIG_PCMCIA_SMC91C92) += ositech/Xilinx7OD.bin
 fw-shipped-$(CONFIG_SCSI_ADVANSYS) += advansys/mcode.bin advansys/38C1600.bin \
                                      advansys/3550.bin advansys/38C0800.bin
index d9e3a94cb4df6803c8c00e608d0b24c62ba4fe3b..82db5256a4e5b24a9f76e6f27bacecdc07245708 100644 (file)
@@ -596,6 +596,7 @@ Found in hex form in kernel source.
 Driver: PCMCIA_PCNET - NE2000 compatible PCMCIA adapter
 
 File: cis/LA-PCM.cis
+      cis/PCMLM28.cis
 
 Licence: GPL
 
@@ -623,6 +624,17 @@ Originally developed by the pcmcia-cs project
 
 --------------------------------------------------------------------------
 
+Driver: SERIAL_8250_CS - Serial PCMCIA adapter
+
+File: cis/MT5634ZLX.cis
+      cis/RS-COM-2P.cis
+
+Licence: GPL
+
+Originally developed by the pcmcia-cs project
+
+--------------------------------------------------------------------------
+
 Driver: PCMCIA_SMC91C92 - SMC 91Cxx PCMCIA
 
 File: ositech/Xilinx7OD.bin
diff --git a/firmware/cis/MT5634ZLX.cis.ihex b/firmware/cis/MT5634ZLX.cis.ihex
new file mode 100644 (file)
index 0000000..72500b9
--- /dev/null
@@ -0,0 +1,11 @@
+:100000000101FF152204014D756C74695465636824
+:100010000050434D4349412035364B2044617461C3
+:10002000466178000000FF20040002010021020266
+:10003000001A05012780FF671B0FCF418B01550177
+:10004000550155AA60F80307281B08970108AA6004
+:10005000F802071B089F0108AA60E803071B08A70E
+:0B0060000108AA60E802071400FF007E
+:00000001FF
+#
+# Replacement CIS for Multitech MT5634ZLX modems
+#
diff --git a/firmware/cis/PCMLM28.cis.ihex b/firmware/cis/PCMLM28.cis.ihex
new file mode 100644 (file)
index 0000000..ffdfe85
--- /dev/null
@@ -0,0 +1,18 @@
+:1000000001030000FF151504014C494E4B53595391
+:100010000050434D4C4D3238000000FF2004430196
+:10002000ABC0210200001A05012FF803031B10E4E6
+:1000300001190155E06100031FF8020730FFFF1BA3
+:100040000BA50108E06120031FF802071B0BA601A6
+:1000500008E06140031FF802071B0BA70108E061DD
+:1000600060031FF802071B0BA80108E06100031FD3
+:10007000E803071B0BA90108E06120031FE8030741
+:100080001B0BAA0108E06140031FE803071B0BAB31
+:100090000108E06160031FE803071B0BAC0108E0E7
+:1000A0006100031FE802071B0BAD0108E06120039C
+:1000B0001FE802071B0BAE0108E06140031FE802C6
+:1000C000071B0BAF0108E06160031FE80207140083
+:0200D000FF002F
+:00000001FF
+#
+# The on-card CIS says it is MFC-compliant, but it is not
+#
diff --git a/firmware/cis/RS-COM-2P.cis.ihex b/firmware/cis/RS-COM-2P.cis.ihex
new file mode 100644 (file)
index 0000000..0801ca5
--- /dev/null
@@ -0,0 +1,10 @@
+:1000000001030000FF1516040150434D4349410010
+:1000100052532D434F4D203250000000FF21020269
+:10002000011A0501030001011B0EC18118AA61E834
+:100030000307E8020730B89E1B0B820108AA615033
+:1000400002075802071B0B830108AA6160020768B8
+:0600500002071400FF008E
+:00000001FF
+#
+# Replacement CIS for dual-serial-port IO card
+#
index aecf2519db76345a206fb812c61f0598d85440fb..d5e5559e31db3774ba6f76e350302009ccf831eb 100644 (file)
@@ -216,7 +216,6 @@ xfs_setfilesize(
        if (ip->i_d.di_size < isize) {
                ip->i_d.di_size = isize;
                ip->i_update_core = 1;
-               ip->i_update_size = 1;
                xfs_mark_inode_dirty_sync(ip);
        }
 
index 0542fd50764945935bd6975bc8094a8df2348601..988d8f87bc0f80b8a23d18397bcbac8f3116647e 100644 (file)
@@ -172,12 +172,21 @@ xfs_file_release(
  */
 STATIC int
 xfs_file_fsync(
-       struct file     *filp,
-       struct dentry   *dentry,
-       int             datasync)
+       struct file             *file,
+       struct dentry           *dentry,
+       int                     datasync)
 {
-       xfs_iflags_clear(XFS_I(dentry->d_inode), XFS_ITRUNCATED);
-       return -xfs_fsync(XFS_I(dentry->d_inode));
+       struct inode            *inode = dentry->d_inode;
+       struct xfs_inode        *ip = XFS_I(inode);
+       int                     error;
+
+       /* capture size updates in I/O completion before writing the inode. */
+       error = filemap_fdatawait(inode->i_mapping);
+       if (error)
+               return error;
+
+       xfs_iflags_clear(ip, XFS_ITRUNCATED);
+       return -xfs_fsync(ip);
 }
 
 STATIC int
index 6c32f1d63d8c43966b9f319610008831f63178bb..da0159d99f82795cd28277138a1f3d5e06916b03 100644 (file)
@@ -43,7 +43,6 @@
 #include "xfs_error.h"
 #include "xfs_itable.h"
 #include "xfs_rw.h"
-#include "xfs_acl.h"
 #include "xfs_attr.h"
 #include "xfs_buf_item.h"
 #include "xfs_utils.h"
index fde63a3c4ecc40cc30b813d3ae9a3a64ffbc80c0..49e4a6aea73c3c85f7d388d56d4371867c930178 100644 (file)
@@ -812,19 +812,21 @@ write_retry:
 
        /* Handle various SYNC-type writes */
        if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) {
+               loff_t end = pos + ret - 1;
                int error2;
 
                xfs_iunlock(xip, iolock);
                if (need_i_mutex)
                        mutex_unlock(&inode->i_mutex);
-               error2 = filemap_write_and_wait_range(mapping, pos,
-                                                     pos + ret - 1);
+
+               error2 = filemap_write_and_wait_range(mapping, pos, end);
                if (!error)
                        error = error2;
                if (need_i_mutex)
                        mutex_lock(&inode->i_mutex);
                xfs_ilock(xip, iolock);
-               error2 = xfs_write_sync_logforce(mp, xip);
+
+               error2 = xfs_fsync(xip);
                if (!error)
                        error = error2;
        }
index c3526d445f6a281c095371d4f5d7bf83658f63d5..76fdc5861932f8ed5412b4345dbb59a1054f8f9c 100644 (file)
 
 DEFINE_PER_CPU(struct xfsstats, xfsstats);
 
-STATIC int
-xfs_read_xfsstats(
-       char            *buffer,
-       char            **start,
-       off_t           offset,
-       int             count,
-       int             *eof,
-       void            *data)
+static int xfs_stat_proc_show(struct seq_file *m, void *v)
 {
-       int             c, i, j, len, val;
+       int             c, i, j, val;
        __uint64_t      xs_xstrat_bytes = 0;
        __uint64_t      xs_write_bytes = 0;
        __uint64_t      xs_read_bytes = 0;
@@ -60,18 +53,18 @@ xfs_read_xfsstats(
        };
 
        /* Loop over all stats groups */
-       for (i=j=len = 0; i < ARRAY_SIZE(xstats); i++) {
-               len += sprintf(buffer + len, "%s", xstats[i].desc);
+       for (i=j = 0; i < ARRAY_SIZE(xstats); i++) {
+               seq_printf(m, "%s", xstats[i].desc);
                /* inner loop does each group */
                while (j < xstats[i].endpoint) {
                        val = 0;
                        /* sum over all cpus */
                        for_each_possible_cpu(c)
                                val += *(((__u32*)&per_cpu(xfsstats, c) + j));
-                       len += sprintf(buffer + len, " %u", val);
+                       seq_printf(m, " %u", val);
                        j++;
                }
-               buffer[len++] = '\n';
+               seq_putc(m, '\n');
        }
        /* extra precision counters */
        for_each_possible_cpu(i) {
@@ -80,36 +73,38 @@ xfs_read_xfsstats(
                xs_read_bytes += per_cpu(xfsstats, i).xs_read_bytes;
        }
 
-       len += sprintf(buffer + len, "xpc %Lu %Lu %Lu\n",
+       seq_printf(m, "xpc %Lu %Lu %Lu\n",
                        xs_xstrat_bytes, xs_write_bytes, xs_read_bytes);
-       len += sprintf(buffer + len, "debug %u\n",
+       seq_printf(m, "debug %u\n",
 #if defined(DEBUG)
                1);
 #else
                0);
 #endif
+       return 0;
+}
 
-       if (offset >= len) {
-               *start = buffer;
-               *eof = 1;
-               return 0;
-       }
-       *start = buffer + offset;
-       if ((len -= offset) > count)
-               return count;
-       *eof = 1;
-
-       return len;
+static int xfs_stat_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, xfs_stat_proc_show, NULL);
 }
 
+static const struct file_operations xfs_stat_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = xfs_stat_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
 int
 xfs_init_procfs(void)
 {
        if (!proc_mkdir("fs/xfs", NULL))
                goto out;
 
-       if (!create_proc_read_entry("fs/xfs/stat", 0, NULL,
-                       xfs_read_xfsstats, NULL))
+       if (!proc_create("fs/xfs/stat", 0, NULL,
+                        &xfs_stat_proc_fops))
                goto out_remove_entry;
        return 0;
 
index a220d36f789b3454c90fa0a4fe71924c4b186b62..5d7c60ac77b4967d262fbca08037993109c9c39b 100644 (file)
@@ -579,15 +579,19 @@ xfs_showargs(
        else if (mp->m_qflags & XFS_UQUOTA_ACCT)
                seq_puts(m, "," MNTOPT_UQUOTANOENF);
 
-       if (mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))
-               seq_puts(m, "," MNTOPT_PRJQUOTA);
-       else if (mp->m_qflags & XFS_PQUOTA_ACCT)
-               seq_puts(m, "," MNTOPT_PQUOTANOENF);
-
-       if (mp->m_qflags & (XFS_GQUOTA_ACCT|XFS_OQUOTA_ENFD))
-               seq_puts(m, "," MNTOPT_GRPQUOTA);
-       else if (mp->m_qflags & XFS_GQUOTA_ACCT)
-               seq_puts(m, "," MNTOPT_GQUOTANOENF);
+       /* Either project or group quotas can be active, not both */
+
+       if (mp->m_qflags & XFS_PQUOTA_ACCT) {
+               if (mp->m_qflags & XFS_OQUOTA_ENFD)
+                       seq_puts(m, "," MNTOPT_PRJQUOTA);
+               else
+                       seq_puts(m, "," MNTOPT_PQUOTANOENF);
+       } else if (mp->m_qflags & XFS_GQUOTA_ACCT) {
+               if (mp->m_qflags & XFS_OQUOTA_ENFD)
+                       seq_puts(m, "," MNTOPT_GRPQUOTA);
+               else
+                       seq_puts(m, "," MNTOPT_GQUOTANOENF);
+       }
 
        if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
                seq_puts(m, "," MNTOPT_NOQUOTA);
@@ -687,7 +691,7 @@ xfs_barrier_test(
        return error;
 }
 
-void
+STATIC void
 xfs_mountfs_check_barriers(xfs_mount_t *mp)
 {
        int error;
index 98ef624d9baf65a2bb3503d0fb6c599fdbdfd02f..320be6aea4924ed6fdcf4ac1e581c0c616d04c83 100644 (file)
@@ -749,21 +749,6 @@ __xfs_inode_clear_reclaim_tag(
                        XFS_INO_TO_AGINO(mp, ip->i_ino), XFS_ICI_RECLAIM_TAG);
 }
 
-void
-xfs_inode_clear_reclaim_tag(
-       xfs_inode_t     *ip)
-{
-       xfs_mount_t     *mp = ip->i_mount;
-       xfs_perag_t     *pag = xfs_get_perag(mp, ip->i_ino);
-
-       read_lock(&pag->pag_ici_lock);
-       spin_lock(&ip->i_flags_lock);
-       __xfs_inode_clear_reclaim_tag(mp, pag, ip);
-       spin_unlock(&ip->i_flags_lock);
-       read_unlock(&pag->pag_ici_lock);
-       xfs_put_perag(mp, pag);
-}
-
 STATIC int
 xfs_reclaim_inode_now(
        struct xfs_inode        *ip,
index 59120602588a370168282a3177a66c7a477bbb42..27920eb7a820cbe77b2e7799bf441a5da8dd0930 100644 (file)
@@ -49,7 +49,6 @@ int xfs_reclaim_inodes(struct xfs_mount *mp, int mode);
 
 void xfs_inode_set_reclaim_tag(struct xfs_inode *ip);
 void __xfs_inode_set_reclaim_tag(struct xfs_perag *pag, struct xfs_inode *ip);
-void xfs_inode_clear_reclaim_tag(struct xfs_inode *ip);
 void __xfs_inode_clear_reclaim_tag(struct xfs_mount *mp, struct xfs_perag *pag,
                                struct xfs_inode *ip);
 
index 21b08c0396a1d8b6e5ab292ebb7db903c97b155c..83e7ea3e25fadc9a93ea101357a4a893dc243cc0 100644 (file)
 
 struct xqmstats xqmstats;
 
-STATIC int
-xfs_qm_read_xfsquota(
-       char            *buffer,
-       char            **start,
-       off_t           offset,
-       int             count,
-       int             *eof,
-       void            *data)
+static int xqm_proc_show(struct seq_file *m, void *v)
 {
-       int             len;
-
        /* maximum; incore; ratio free to inuse; freelist */
-       len = sprintf(buffer, "%d\t%d\t%d\t%u\n",
+       seq_printf(m, "%d\t%d\t%d\t%u\n",
                        ndquot,
                        xfs_Gqm? atomic_read(&xfs_Gqm->qm_totaldquots) : 0,
                        xfs_Gqm? xfs_Gqm->qm_dqfree_ratio : 0,
                        xfs_Gqm? xfs_Gqm->qm_dqfreelist.qh_nelems : 0);
-
-       if (offset >= len) {
-               *start = buffer;
-               *eof = 1;
-               return 0;
-       }
-       *start = buffer + offset;
-       if ((len -= offset) > count)
-               return count;
-       *eof = 1;
-
-       return len;
+       return 0;
 }
 
-STATIC int
-xfs_qm_read_stats(
-       char            *buffer,
-       char            **start,
-       off_t           offset,
-       int             count,
-       int             *eof,
-       void            *data)
+static int xqm_proc_open(struct inode *inode, struct file *file)
 {
-       int             len;
+       return single_open(file, xqm_proc_show, NULL);
+}
+
+static const struct file_operations xqm_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = xqm_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
 
+static int xqmstat_proc_show(struct seq_file *m, void *v)
+{
        /* quota performance statistics */
-       len = sprintf(buffer, "qm %u %u %u %u %u %u %u %u\n",
+       seq_printf(m, "qm %u %u %u %u %u %u %u %u\n",
                        xqmstats.xs_qm_dqreclaims,
                        xqmstats.xs_qm_dqreclaim_misses,
                        xqmstats.xs_qm_dquot_dups,
@@ -100,25 +84,27 @@ xfs_qm_read_stats(
                        xqmstats.xs_qm_dqwants,
                        xqmstats.xs_qm_dqshake_reclaims,
                        xqmstats.xs_qm_dqinact_reclaims);
+       return 0;
+}
 
-       if (offset >= len) {
-               *start = buffer;
-               *eof = 1;
-               return 0;
-       }
-       *start = buffer + offset;
-       if ((len -= offset) > count)
-               return count;
-       *eof = 1;
-
-       return len;
+static int xqmstat_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, xqmstat_proc_show, NULL);
 }
 
+static const struct file_operations xqmstat_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = xqmstat_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
 void
 xfs_qm_init_procfs(void)
 {
-       create_proc_read_entry("fs/xfs/xqmstat", 0, NULL, xfs_qm_read_stats, NULL);
-       create_proc_read_entry("fs/xfs/xqm", 0, NULL, xfs_qm_read_xfsquota, NULL);
+       proc_create("fs/xfs/xqmstat", 0, NULL, &xqmstat_proc_fops);
+       proc_create("fs/xfs/xqm", 0, NULL, &xqm_proc_fops);
 }
 
 void
index f24b50b68d03a6b3d89027bff545d19d3296f85e..a5d54bf4931b583dfd3729d670cd0694e7b7c507 100644 (file)
@@ -198,6 +198,15 @@ typedef struct xfs_perag
        xfs_agino_t     pagi_count;     /* number of allocated inodes */
        int             pagb_count;     /* pagb slots in use */
        xfs_perag_busy_t *pagb_list;    /* unstable blocks */
+
+       /*
+        * Inode allocation search lookup optimisation.
+        * If the pagino matches, the search for new inodes
+        * doesn't need to search the near ones again straight away
+        */
+       xfs_agino_t     pagl_pagino;
+       xfs_agino_t     pagl_leftrec;
+       xfs_agino_t     pagl_rightrec;
 #ifdef __KERNEL__
        spinlock_t      pagb_lock;      /* lock for pagb_list */
 
index 8ee5b5a76a2aff78995fb5a86926a0c9b1546bbd..8971fb09d3879b49e82ffc5b9a3c2e3cb278431b 100644 (file)
@@ -3713,7 +3713,7 @@ done:
  * entry (null if none).  Else, *lastxp will be set to the index
  * of the found entry; *gotp will contain the entry.
  */
-xfs_bmbt_rec_host_t *                  /* pointer to found extent entry */
+STATIC xfs_bmbt_rec_host_t *           /* pointer to found extent entry */
 xfs_bmap_search_multi_extents(
        xfs_ifork_t     *ifp,           /* inode fork pointer */
        xfs_fileoff_t   bno,            /* block number searched for */
index 1b8ff9256bd0cba9515bc212c859a80c2335c157..56f62d2edc35b884ed26067436a791a75c9f0a52 100644 (file)
@@ -392,17 +392,6 @@ xfs_bmap_count_blocks(
        int                     whichfork,
        int                     *count);
 
-/*
- * Search the extent records for the entry containing block bno.
- * If bno lies in a hole, point to the next entry.  If bno lies
- * past eof, *eofp will be set, and *prevp will contain the last
- * entry (null if none).  Else, *lastxp will be set to the index
- * of the found entry; *gotp will contain the entry.
- */
-xfs_bmbt_rec_host_t *
-xfs_bmap_search_multi_extents(struct xfs_ifork *, xfs_fileoff_t, int *,
-                       xfs_extnum_t *, xfs_bmbt_irec_t *, xfs_bmbt_irec_t *);
-
 #endif /* __KERNEL__ */
 
 #endif /* __XFS_BMAP_H__ */
index 5c1ade06578edbdad83711f59974a46cdddb7a0e..eb7b702d0690f673e3b86d178379b8eeb511bb67 100644 (file)
@@ -202,16 +202,6 @@ xfs_bmbt_get_state(
                                ext_flag);
 }
 
-/* Endian flipping versions of the bmbt extraction functions */
-void
-xfs_bmbt_disk_get_all(
-       xfs_bmbt_rec_t  *r,
-       xfs_bmbt_irec_t *s)
-{
-       __xfs_bmbt_get_all(get_unaligned_be64(&r->l0),
-                               get_unaligned_be64(&r->l1), s);
-}
-
 /*
  * Extract the blockcount field from an on disk bmap extent record.
  */
@@ -816,6 +806,16 @@ xfs_bmbt_trace_key(
        *l1 = 0;
 }
 
+/* Endian flipping versions of the bmbt extraction functions */
+STATIC void
+xfs_bmbt_disk_get_all(
+       xfs_bmbt_rec_t  *r,
+       xfs_bmbt_irec_t *s)
+{
+       __xfs_bmbt_get_all(get_unaligned_be64(&r->l0),
+                               get_unaligned_be64(&r->l1), s);
+}
+
 STATIC void
 xfs_bmbt_trace_record(
        struct xfs_btree_cur    *cur,
index 0e8df007615e9967f8d4b828b5af0c6e5197d20d..5549d495947f4d3e9949c2c15fbc2982282ebe35 100644 (file)
@@ -220,7 +220,6 @@ extern xfs_fsblock_t xfs_bmbt_get_startblock(xfs_bmbt_rec_host_t *r);
 extern xfs_fileoff_t xfs_bmbt_get_startoff(xfs_bmbt_rec_host_t *r);
 extern xfs_exntst_t xfs_bmbt_get_state(xfs_bmbt_rec_host_t *r);
 
-extern void xfs_bmbt_disk_get_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s);
 extern xfs_filblks_t xfs_bmbt_disk_get_blockcount(xfs_bmbt_rec_t *r);
 extern xfs_fileoff_t xfs_bmbt_disk_get_startoff(xfs_bmbt_rec_t *r);
 
index 26717388acf5a250c0ec8b039e041dbe753c0b77..52b5f14d0c32ef4573074b4e5962d5055aaec643 100644 (file)
@@ -645,46 +645,6 @@ xfs_btree_read_bufl(
        return 0;
 }
 
-/*
- * Get a buffer for the block, return it read in.
- * Short-form addressing.
- */
-int                                    /* error */
-xfs_btree_read_bufs(
-       xfs_mount_t     *mp,            /* file system mount point */
-       xfs_trans_t     *tp,            /* transaction pointer */
-       xfs_agnumber_t  agno,           /* allocation group number */
-       xfs_agblock_t   agbno,          /* allocation group block number */
-       uint            lock,           /* lock flags for read_buf */
-       xfs_buf_t       **bpp,          /* buffer for agno/agbno */
-       int             refval)         /* ref count value for buffer */
-{
-       xfs_buf_t       *bp;            /* return value */
-       xfs_daddr_t     d;              /* real disk block address */
-       int             error;
-
-       ASSERT(agno != NULLAGNUMBER);
-       ASSERT(agbno != NULLAGBLOCK);
-       d = XFS_AGB_TO_DADDR(mp, agno, agbno);
-       if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d,
-                                       mp->m_bsize, lock, &bp))) {
-               return error;
-       }
-       ASSERT(!bp || !XFS_BUF_GETERROR(bp));
-       if (bp != NULL) {
-               switch (refval) {
-               case XFS_ALLOC_BTREE_REF:
-                       XFS_BUF_SET_VTYPE_REF(bp, B_FS_MAP, refval);
-                       break;
-               case XFS_INO_BTREE_REF:
-                       XFS_BUF_SET_VTYPE_REF(bp, B_FS_INOMAP, refval);
-                       break;
-               }
-       }
-       *bpp = bp;
-       return 0;
-}
-
 /*
  * Read-ahead the block, don't wait for it, don't return a buffer.
  * Long-form addressing.
@@ -2951,7 +2911,7 @@ error0:
  * inode we have to copy the single block it was pointing to into the
  * inode.
  */
-int
+STATIC int
 xfs_btree_kill_iroot(
        struct xfs_btree_cur    *cur)
 {
index 4f852b735b961a37bb43f431937b52cbe1166212..7fa07062bddac3fce4649c0942f2828d90943cde 100644 (file)
@@ -378,20 +378,6 @@ xfs_btree_read_bufl(
        struct xfs_buf          **bpp,  /* buffer for fsbno */
        int                     refval);/* ref count value for buffer */
 
-/*
- * Get a buffer for the block, return it read in.
- * Short-form addressing.
- */
-int                                    /* error */
-xfs_btree_read_bufs(
-       struct xfs_mount        *mp,    /* file system mount point */
-       struct xfs_trans        *tp,    /* transaction pointer */
-       xfs_agnumber_t          agno,   /* allocation group number */
-       xfs_agblock_t           agbno,  /* allocation group block number */
-       uint                    lock,   /* lock flags for read_buf */
-       struct xfs_buf          **bpp,  /* buffer for agno/agbno */
-       int                     refval);/* ref count value for buffer */
-
 /*
  * Read-ahead the block, don't wait for it, don't return a buffer.
  * Long-form addressing.
@@ -432,7 +418,6 @@ int xfs_btree_decrement(struct xfs_btree_cur *, int, int *);
 int xfs_btree_lookup(struct xfs_btree_cur *, xfs_lookup_t, int *);
 int xfs_btree_update(struct xfs_btree_cur *, union xfs_btree_rec *);
 int xfs_btree_new_iroot(struct xfs_btree_cur *, int *, int *);
-int xfs_btree_kill_iroot(struct xfs_btree_cur *);
 int xfs_btree_insert(struct xfs_btree_cur *, int *);
 int xfs_btree_delete(struct xfs_btree_cur *, int *);
 int xfs_btree_get_rec(struct xfs_btree_cur *, union xfs_btree_rec **, int *);
index 3120a3a5e20f90a07186e9258d3767f315678be5..ab64f3efb43b3a375bf690b7ade11726db94bdc2 100644 (file)
@@ -57,75 +57,35 @@ xfs_ialloc_cluster_alignment(
 }
 
 /*
- * Lookup the record equal to ino in the btree given by cur.
- */
-STATIC int                             /* error */
-xfs_inobt_lookup_eq(
-       struct xfs_btree_cur    *cur,   /* btree cursor */
-       xfs_agino_t             ino,    /* starting inode of chunk */
-       __int32_t               fcnt,   /* free inode count */
-       xfs_inofree_t           free,   /* free inode mask */
-       int                     *stat)  /* success/failure */
-{
-       cur->bc_rec.i.ir_startino = ino;
-       cur->bc_rec.i.ir_freecount = fcnt;
-       cur->bc_rec.i.ir_free = free;
-       return xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat);
-}
-
-/*
- * Lookup the first record greater than or equal to ino
- * in the btree given by cur.
+ * Lookup a record by ino in the btree given by cur.
  */
 int                                    /* error */
-xfs_inobt_lookup_ge(
+xfs_inobt_lookup(
        struct xfs_btree_cur    *cur,   /* btree cursor */
        xfs_agino_t             ino,    /* starting inode of chunk */
-       __int32_t               fcnt,   /* free inode count */
-       xfs_inofree_t           free,   /* free inode mask */
+       xfs_lookup_t            dir,    /* <=, >=, == */
        int                     *stat)  /* success/failure */
 {
        cur->bc_rec.i.ir_startino = ino;
-       cur->bc_rec.i.ir_freecount = fcnt;
-       cur->bc_rec.i.ir_free = free;
-       return xfs_btree_lookup(cur, XFS_LOOKUP_GE, stat);
+       cur->bc_rec.i.ir_freecount = 0;
+       cur->bc_rec.i.ir_free = 0;
+       return xfs_btree_lookup(cur, dir, stat);
 }
 
 /*
- * Lookup the first record less than or equal to ino
- * in the btree given by cur.
- */
-int                                    /* error */
-xfs_inobt_lookup_le(
-       struct xfs_btree_cur    *cur,   /* btree cursor */
-       xfs_agino_t             ino,    /* starting inode of chunk */
-       __int32_t               fcnt,   /* free inode count */
-       xfs_inofree_t           free,   /* free inode mask */
-       int                     *stat)  /* success/failure */
-{
-       cur->bc_rec.i.ir_startino = ino;
-       cur->bc_rec.i.ir_freecount = fcnt;
-       cur->bc_rec.i.ir_free = free;
-       return xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat);
-}
-
-/*
- * Update the record referred to by cur to the value given
- * by [ino, fcnt, free].
+ * Update the record referred to by cur to the value given.
  * This either works (return 0) or gets an EFSCORRUPTED error.
  */
 STATIC int                             /* error */
 xfs_inobt_update(
        struct xfs_btree_cur    *cur,   /* btree cursor */
-       xfs_agino_t             ino,    /* starting inode of chunk */
-       __int32_t               fcnt,   /* free inode count */
-       xfs_inofree_t           free)   /* free inode mask */
+       xfs_inobt_rec_incore_t  *irec)  /* btree record */
 {
        union xfs_btree_rec     rec;
 
-       rec.inobt.ir_startino = cpu_to_be32(ino);
-       rec.inobt.ir_freecount = cpu_to_be32(fcnt);
-       rec.inobt.ir_free = cpu_to_be64(free);
+       rec.inobt.ir_startino = cpu_to_be32(irec->ir_startino);
+       rec.inobt.ir_freecount = cpu_to_be32(irec->ir_freecount);
+       rec.inobt.ir_free = cpu_to_be64(irec->ir_free);
        return xfs_btree_update(cur, &rec);
 }
 
@@ -135,9 +95,7 @@ xfs_inobt_update(
 int                                    /* error */
 xfs_inobt_get_rec(
        struct xfs_btree_cur    *cur,   /* btree cursor */
-       xfs_agino_t             *ino,   /* output: starting inode of chunk */
-       __int32_t               *fcnt,  /* output: number of free inodes */
-       xfs_inofree_t           *free,  /* output: free inode mask */
+       xfs_inobt_rec_incore_t  *irec,  /* btree record */
        int                     *stat)  /* output: success/failure */
 {
        union xfs_btree_rec     *rec;
@@ -145,13 +103,135 @@ xfs_inobt_get_rec(
 
        error = xfs_btree_get_rec(cur, &rec, stat);
        if (!error && *stat == 1) {
-               *ino = be32_to_cpu(rec->inobt.ir_startino);
-               *fcnt = be32_to_cpu(rec->inobt.ir_freecount);
-               *free = be64_to_cpu(rec->inobt.ir_free);
+               irec->ir_startino = be32_to_cpu(rec->inobt.ir_startino);
+               irec->ir_freecount = be32_to_cpu(rec->inobt.ir_freecount);
+               irec->ir_free = be64_to_cpu(rec->inobt.ir_free);
        }
        return error;
 }
 
+/*
+ * Verify that the number of free inodes in the AGI is correct.
+ */
+#ifdef DEBUG
+STATIC int
+xfs_check_agi_freecount(
+       struct xfs_btree_cur    *cur,
+       struct xfs_agi          *agi)
+{
+       if (cur->bc_nlevels == 1) {
+               xfs_inobt_rec_incore_t rec;
+               int             freecount = 0;
+               int             error;
+               int             i;
+
+               error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i);
+               if (error)
+                       return error;
+
+               do {
+                       error = xfs_inobt_get_rec(cur, &rec, &i);
+                       if (error)
+                               return error;
+
+                       if (i) {
+                               freecount += rec.ir_freecount;
+                               error = xfs_btree_increment(cur, 0, &i);
+                               if (error)
+                                       return error;
+                       }
+               } while (i == 1);
+
+               if (!XFS_FORCED_SHUTDOWN(cur->bc_mp))
+                       ASSERT(freecount == be32_to_cpu(agi->agi_freecount));
+       }
+       return 0;
+}
+#else
+#define xfs_check_agi_freecount(cur, agi)      0
+#endif
+
+/*
+ * Initialise a new set of inodes.
+ */
+STATIC void
+xfs_ialloc_inode_init(
+       struct xfs_mount        *mp,
+       struct xfs_trans        *tp,
+       xfs_agnumber_t          agno,
+       xfs_agblock_t           agbno,
+       xfs_agblock_t           length,
+       unsigned int            gen)
+{
+       struct xfs_buf          *fbuf;
+       struct xfs_dinode       *free;
+       int                     blks_per_cluster, nbufs, ninodes;
+       int                     version;
+       int                     i, j;
+       xfs_daddr_t             d;
+
+       /*
+        * Loop over the new block(s), filling in the inodes.
+        * For small block sizes, manipulate the inodes in buffers
+        * which are multiples of the blocks size.
+        */
+       if (mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(mp)) {
+               blks_per_cluster = 1;
+               nbufs = length;
+               ninodes = mp->m_sb.sb_inopblock;
+       } else {
+               blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) /
+                                  mp->m_sb.sb_blocksize;
+               nbufs = length / blks_per_cluster;
+               ninodes = blks_per_cluster * mp->m_sb.sb_inopblock;
+       }
+
+       /*
+        * Figure out what version number to use in the inodes we create.
+        * If the superblock version has caught up to the one that supports
+        * the new inode format, then use the new inode version.  Otherwise
+        * use the old version so that old kernels will continue to be
+        * able to use the file system.
+        */
+       if (xfs_sb_version_hasnlink(&mp->m_sb))
+               version = 2;
+       else
+               version = 1;
+
+       for (j = 0; j < nbufs; j++) {
+               /*
+                * Get the block.
+                */
+               d = XFS_AGB_TO_DADDR(mp, agno, agbno + (j * blks_per_cluster));
+               fbuf = xfs_trans_get_buf(tp, mp->m_ddev_targp, d,
+                                        mp->m_bsize * blks_per_cluster,
+                                        XFS_BUF_LOCK);
+               ASSERT(fbuf);
+               ASSERT(!XFS_BUF_GETERROR(fbuf));
+
+               /*
+                * Initialize all inodes in this buffer and then log them.
+                *
+                * XXX: It would be much better if we had just one transaction
+                *      to log a whole cluster of inodes instead of all the
+                *      individual transactions causing a lot of log traffic.
+                */
+               xfs_biozero(fbuf, 0, ninodes << mp->m_sb.sb_inodelog);
+               for (i = 0; i < ninodes; i++) {
+                       int     ioffset = i << mp->m_sb.sb_inodelog;
+                       uint    isize = sizeof(struct xfs_dinode);
+
+                       free = xfs_make_iptr(mp, fbuf, i);
+                       free->di_magic = cpu_to_be16(XFS_DINODE_MAGIC);
+                       free->di_version = version;
+                       free->di_gen = cpu_to_be32(gen);
+                       free->di_next_unlinked = cpu_to_be32(NULLAGINO);
+                       xfs_trans_log_buf(tp, fbuf, ioffset, ioffset + isize - 1);
+               }
+               xfs_trans_inode_alloc_buf(tp, fbuf);
+       }
+}
+
 /*
  * Allocate new inodes in the allocation group specified by agbp.
  * Return 0 for success, else error code.
@@ -164,24 +244,15 @@ xfs_ialloc_ag_alloc(
 {
        xfs_agi_t       *agi;           /* allocation group header */
        xfs_alloc_arg_t args;           /* allocation argument structure */
-       int             blks_per_cluster;  /* fs blocks per inode cluster */
        xfs_btree_cur_t *cur;           /* inode btree cursor */
-       xfs_daddr_t     d;              /* disk addr of buffer */
        xfs_agnumber_t  agno;
        int             error;
-       xfs_buf_t       *fbuf;          /* new free inodes' buffer */
-       xfs_dinode_t    *free;          /* new free inode structure */
-       int             i;              /* inode counter */
-       int             j;              /* block counter */
-       int             nbufs;          /* num bufs of new inodes */
+       int             i;
        xfs_agino_t     newino;         /* new first inode's number */
        xfs_agino_t     newlen;         /* new number of inodes */
-       int             ninodes;        /* num inodes per buf */
        xfs_agino_t     thisino;        /* current inode number, for loop */
-       int             version;        /* inode version number to use */
        int             isaligned = 0;  /* inode allocation at stripe unit */
                                        /* boundary */
-       unsigned int    gen;
 
        args.tp = tp;
        args.mp = tp->t_mountp;
@@ -202,12 +273,12 @@ xfs_ialloc_ag_alloc(
         */
        agi = XFS_BUF_TO_AGI(agbp);
        newino = be32_to_cpu(agi->agi_newino);
+       agno = be32_to_cpu(agi->agi_seqno);
        args.agbno = XFS_AGINO_TO_AGBNO(args.mp, newino) +
                        XFS_IALLOC_BLOCKS(args.mp);
        if (likely(newino != NULLAGINO &&
                  (args.agbno < be32_to_cpu(agi->agi_length)))) {
-               args.fsbno = XFS_AGB_TO_FSB(args.mp,
-                               be32_to_cpu(agi->agi_seqno), args.agbno);
+               args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno);
                args.type = XFS_ALLOCTYPE_THIS_BNO;
                args.mod = args.total = args.wasdel = args.isfl =
                        args.userdata = args.minalignslop = 0;
@@ -258,8 +329,7 @@ xfs_ialloc_ag_alloc(
                 * For now, just allocate blocks up front.
                 */
                args.agbno = be32_to_cpu(agi->agi_root);
-               args.fsbno = XFS_AGB_TO_FSB(args.mp,
-                               be32_to_cpu(agi->agi_seqno), args.agbno);
+               args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno);
                /*
                 * Allocate a fixed-size extent of inodes.
                 */
@@ -282,8 +352,7 @@ xfs_ialloc_ag_alloc(
        if (isaligned && args.fsbno == NULLFSBLOCK) {
                args.type = XFS_ALLOCTYPE_NEAR_BNO;
                args.agbno = be32_to_cpu(agi->agi_root);
-               args.fsbno = XFS_AGB_TO_FSB(args.mp,
-                               be32_to_cpu(agi->agi_seqno), args.agbno);
+               args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno);
                args.alignment = xfs_ialloc_cluster_alignment(&args);
                if ((error = xfs_alloc_vextent(&args)))
                        return error;
@@ -294,85 +363,30 @@ xfs_ialloc_ag_alloc(
                return 0;
        }
        ASSERT(args.len == args.minlen);
-       /*
-        * Convert the results.
-        */
-       newino = XFS_OFFBNO_TO_AGINO(args.mp, args.agbno, 0);
-       /*
-        * Loop over the new block(s), filling in the inodes.
-        * For small block sizes, manipulate the inodes in buffers
-        * which are multiples of the blocks size.
-        */
-       if (args.mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(args.mp)) {
-               blks_per_cluster = 1;
-               nbufs = (int)args.len;
-               ninodes = args.mp->m_sb.sb_inopblock;
-       } else {
-               blks_per_cluster = XFS_INODE_CLUSTER_SIZE(args.mp) /
-                                  args.mp->m_sb.sb_blocksize;
-               nbufs = (int)args.len / blks_per_cluster;
-               ninodes = blks_per_cluster * args.mp->m_sb.sb_inopblock;
-       }
-       /*
-        * Figure out what version number to use in the inodes we create.
-        * If the superblock version has caught up to the one that supports
-        * the new inode format, then use the new inode version.  Otherwise
-        * use the old version so that old kernels will continue to be
-        * able to use the file system.
-        */
-       if (xfs_sb_version_hasnlink(&args.mp->m_sb))
-               version = 2;
-       else
-               version = 1;
 
        /*
+        * Stamp and write the inode buffers.
+        *
         * Seed the new inode cluster with a random generation number. This
         * prevents short-term reuse of generation numbers if a chunk is
         * freed and then immediately reallocated. We use random numbers
         * rather than a linear progression to prevent the next generation
         * number from being easily guessable.
         */
-       gen = random32();
-       for (j = 0; j < nbufs; j++) {
-               /*
-                * Get the block.
-                */
-               d = XFS_AGB_TO_DADDR(args.mp, be32_to_cpu(agi->agi_seqno),
-                                    args.agbno + (j * blks_per_cluster));
-               fbuf = xfs_trans_get_buf(tp, args.mp->m_ddev_targp, d,
-                                        args.mp->m_bsize * blks_per_cluster,
-                                        XFS_BUF_LOCK);
-               ASSERT(fbuf);
-               ASSERT(!XFS_BUF_GETERROR(fbuf));
+       xfs_ialloc_inode_init(args.mp, tp, agno, args.agbno, args.len,
+                             random32());
 
-               /*
-                * Initialize all inodes in this buffer and then log them.
-                *
-                * XXX: It would be much better if we had just one transaction to
-                *      log a whole cluster of inodes instead of all the individual
-                *      transactions causing a lot of log traffic.
-                */
-               xfs_biozero(fbuf, 0, ninodes << args.mp->m_sb.sb_inodelog);
-               for (i = 0; i < ninodes; i++) {
-                       int     ioffset = i << args.mp->m_sb.sb_inodelog;
-                       uint    isize = sizeof(struct xfs_dinode);
-
-                       free = xfs_make_iptr(args.mp, fbuf, i);
-                       free->di_magic = cpu_to_be16(XFS_DINODE_MAGIC);
-                       free->di_version = version;
-                       free->di_gen = cpu_to_be32(gen);
-                       free->di_next_unlinked = cpu_to_be32(NULLAGINO);
-                       xfs_trans_log_buf(tp, fbuf, ioffset, ioffset + isize - 1);
-               }
-               xfs_trans_inode_alloc_buf(tp, fbuf);
-       }
+       /*
+        * Convert the results.
+        */
+       newino = XFS_OFFBNO_TO_AGINO(args.mp, args.agbno, 0);
        be32_add_cpu(&agi->agi_count, newlen);
        be32_add_cpu(&agi->agi_freecount, newlen);
-       agno = be32_to_cpu(agi->agi_seqno);
        down_read(&args.mp->m_peraglock);
        args.mp->m_perag[agno].pagi_freecount += newlen;
        up_read(&args.mp->m_peraglock);
        agi->agi_newino = cpu_to_be32(newino);
+
        /*
         * Insert records describing the new inode chunk into the btree.
         */
@@ -380,13 +394,17 @@ xfs_ialloc_ag_alloc(
        for (thisino = newino;
             thisino < newino + newlen;
             thisino += XFS_INODES_PER_CHUNK) {
-               if ((error = xfs_inobt_lookup_eq(cur, thisino,
-                               XFS_INODES_PER_CHUNK, XFS_INOBT_ALL_FREE, &i))) {
+               cur->bc_rec.i.ir_startino = thisino;
+               cur->bc_rec.i.ir_freecount = XFS_INODES_PER_CHUNK;
+               cur->bc_rec.i.ir_free = XFS_INOBT_ALL_FREE;
+               error = xfs_btree_lookup(cur, XFS_LOOKUP_EQ, &i);
+               if (error) {
                        xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
                        return error;
                }
                ASSERT(i == 0);
-               if ((error = xfs_btree_insert(cur, &i))) {
+               error = xfs_btree_insert(cur, &i);
+               if (error) {
                        xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
                        return error;
                }
@@ -538,6 +556,62 @@ nextag:
        }
 }
 
+/*
+ * Try to retrieve the next record to the left/right from the current one.
+ */
+STATIC int
+xfs_ialloc_next_rec(
+       struct xfs_btree_cur    *cur,
+       xfs_inobt_rec_incore_t  *rec,
+       int                     *done,
+       int                     left)
+{
+       int                     error;
+       int                     i;
+
+       if (left)
+               error = xfs_btree_decrement(cur, 0, &i);
+       else
+               error = xfs_btree_increment(cur, 0, &i);
+
+       if (error)
+               return error;
+       *done = !i;
+       if (i) {
+               error = xfs_inobt_get_rec(cur, rec, &i);
+               if (error)
+                       return error;
+               XFS_WANT_CORRUPTED_RETURN(i == 1);
+       }
+
+       return 0;
+}
+
+STATIC int
+xfs_ialloc_get_rec(
+       struct xfs_btree_cur    *cur,
+       xfs_agino_t             agino,
+       xfs_inobt_rec_incore_t  *rec,
+       int                     *done,
+       int                     left)
+{
+       int                     error;
+       int                     i;
+
+       error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_EQ, &i);
+       if (error)
+               return error;
+       *done = !i;
+       if (i) {
+               error = xfs_inobt_get_rec(cur, rec, &i);
+               if (error)
+                       return error;
+               XFS_WANT_CORRUPTED_RETURN(i == 1);
+       }
+
+       return 0;
+}
+
 /*
  * Visible inode allocation functions.
  */
@@ -592,8 +666,8 @@ xfs_dialloc(
        int             j;              /* result code */
        xfs_mount_t     *mp;            /* file system mount structure */
        int             offset;         /* index of inode in chunk */
-       xfs_agino_t     pagino;         /* parent's a.g. relative inode # */
-       xfs_agnumber_t  pagno;          /* parent's allocation group number */
+       xfs_agino_t     pagino;         /* parent's AG relative inode # */
+       xfs_agnumber_t  pagno;          /* parent's AG number */
        xfs_inobt_rec_incore_t rec;     /* inode allocation record */
        xfs_agnumber_t  tagno;          /* testing allocation group number */
        xfs_btree_cur_t *tcur;          /* temp cursor */
@@ -716,6 +790,8 @@ nextag:
         */
        agno = tagno;
        *IO_agbp = NULL;
+
+ restart_pagno:
        cur = xfs_inobt_init_cursor(mp, tp, agbp, be32_to_cpu(agi->agi_seqno));
        /*
         * If pagino is 0 (this is the root inode allocation) use newino.
@@ -723,220 +799,199 @@ nextag:
         */
        if (!pagino)
                pagino = be32_to_cpu(agi->agi_newino);
-#ifdef DEBUG
-       if (cur->bc_nlevels == 1) {
-               int     freecount = 0;
 
-               if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i)))
-                       goto error0;
-               XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
-               do {
-                       if ((error = xfs_inobt_get_rec(cur, &rec.ir_startino,
-                                       &rec.ir_freecount, &rec.ir_free, &i)))
-                               goto error0;
-                       XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
-                       freecount += rec.ir_freecount;
-                       if ((error = xfs_btree_increment(cur, 0, &i)))
-                               goto error0;
-               } while (i == 1);
+       error = xfs_check_agi_freecount(cur, agi);
+       if (error)
+               goto error0;
 
-               ASSERT(freecount == be32_to_cpu(agi->agi_freecount) ||
-                      XFS_FORCED_SHUTDOWN(mp));
-       }
-#endif
        /*
-        * If in the same a.g. as the parent, try to get near the parent.
+        * If in the same AG as the parent, try to get near the parent.
         */
        if (pagno == agno) {
-               if ((error = xfs_inobt_lookup_le(cur, pagino, 0, 0, &i)))
+               xfs_perag_t     *pag = &mp->m_perag[agno];
+               int             doneleft;       /* done, to the left */
+               int             doneright;      /* done, to the right */
+               int             searchdistance = 10;
+
+               error = xfs_inobt_lookup(cur, pagino, XFS_LOOKUP_LE, &i);
+               if (error)
+                       goto error0;
+               XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
+
+               error = xfs_inobt_get_rec(cur, &rec, &j);
+               if (error)
                        goto error0;
-               if (i != 0 &&
-                   (error = xfs_inobt_get_rec(cur, &rec.ir_startino,
-                           &rec.ir_freecount, &rec.ir_free, &j)) == 0 &&
-                   j == 1 &&
-                   rec.ir_freecount > 0) {
+               XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
+
+               if (rec.ir_freecount > 0) {
                        /*
                         * Found a free inode in the same chunk
-                        * as parent, done.
+                        * as the parent, done.
                         */
+                       goto alloc_inode;
                }
+
+
+               /*
+                * In the same AG as parent, but parent's chunk is full.
+                */
+
+               /* duplicate the cursor, search left & right simultaneously */
+               error = xfs_btree_dup_cursor(cur, &tcur);
+               if (error)
+                       goto error0;
+
                /*
-                * In the same a.g. as parent, but parent's chunk is full.
+                * Skip to last blocks looked up if same parent inode.
                 */
-               else {
-                       int     doneleft;       /* done, to the left */
-                       int     doneright;      /* done, to the right */
+               if (pagino != NULLAGINO &&
+                   pag->pagl_pagino == pagino &&
+                   pag->pagl_leftrec != NULLAGINO &&
+                   pag->pagl_rightrec != NULLAGINO) {
+                       error = xfs_ialloc_get_rec(tcur, pag->pagl_leftrec,
+                                                  &trec, &doneleft, 1);
+                       if (error)
+                               goto error1;
 
+                       error = xfs_ialloc_get_rec(cur, pag->pagl_rightrec,
+                                                  &rec, &doneright, 0);
                        if (error)
-                               goto error0;
-                       ASSERT(i == 1);
-                       ASSERT(j == 1);
-                       /*
-                        * Duplicate the cursor, search left & right
-                        * simultaneously.
-                        */
-                       if ((error = xfs_btree_dup_cursor(cur, &tcur)))
-                               goto error0;
-                       /*
-                        * Search left with tcur, back up 1 record.
-                        */
-                       if ((error = xfs_btree_decrement(tcur, 0, &i)))
                                goto error1;
-                       doneleft = !i;
-                       if (!doneleft) {
-                               if ((error = xfs_inobt_get_rec(tcur,
-                                               &trec.ir_startino,
-                                               &trec.ir_freecount,
-                                               &trec.ir_free, &i)))
-                                       goto error1;
-                               XFS_WANT_CORRUPTED_GOTO(i == 1, error1);
-                       }
-                       /*
-                        * Search right with cur, go forward 1 record.
-                        */
-                       if ((error = xfs_btree_increment(cur, 0, &i)))
+               } else {
+                       /* search left with tcur, back up 1 record */
+                       error = xfs_ialloc_next_rec(tcur, &trec, &doneleft, 1);
+                       if (error)
                                goto error1;
-                       doneright = !i;
-                       if (!doneright) {
-                               if ((error = xfs_inobt_get_rec(cur,
-                                               &rec.ir_startino,
-                                               &rec.ir_freecount,
-                                               &rec.ir_free, &i)))
-                                       goto error1;
-                               XFS_WANT_CORRUPTED_GOTO(i == 1, error1);
-                       }
-                       /*
-                        * Loop until we find the closest inode chunk
-                        * with a free one.
-                        */
-                       while (!doneleft || !doneright) {
-                               int     useleft;  /* using left inode
-                                                    chunk this time */
 
+                       /* search right with cur, go forward 1 record. */
+                       error = xfs_ialloc_next_rec(cur, &rec, &doneright, 0);
+                       if (error)
+                               goto error1;
+               }
+
+               /*
+                * Loop until we find an inode chunk with a free inode.
+                */
+               while (!doneleft || !doneright) {
+                       int     useleft;  /* using left inode chunk this time */
+
+                       if (!--searchdistance) {
                                /*
-                                * Figure out which block is closer,
-                                * if both are valid.
-                                */
-                               if (!doneleft && !doneright)
-                                       useleft =
-                                               pagino -
-                                               (trec.ir_startino +
-                                                XFS_INODES_PER_CHUNK - 1) <
-                                                rec.ir_startino - pagino;
-                               else
-                                       useleft = !doneleft;
-                               /*
-                                * If checking the left, does it have
-                                * free inodes?
-                                */
-                               if (useleft && trec.ir_freecount) {
-                                       /*
-                                        * Yes, set it up as the chunk to use.
-                                        */
-                                       rec = trec;
-                                       xfs_btree_del_cursor(cur,
-                                               XFS_BTREE_NOERROR);
-                                       cur = tcur;
-                                       break;
-                               }
-                               /*
-                                * If checking the right, does it have
-                                * free inodes?
-                                */
-                               if (!useleft && rec.ir_freecount) {
-                                       /*
-                                        * Yes, it's already set up.
-                                        */
-                                       xfs_btree_del_cursor(tcur,
-                                               XFS_BTREE_NOERROR);
-                                       break;
-                               }
-                               /*
-                                * If used the left, get another one
-                                * further left.
-                                */
-                               if (useleft) {
-                                       if ((error = xfs_btree_decrement(tcur, 0,
-                                                       &i)))
-                                               goto error1;
-                                       doneleft = !i;
-                                       if (!doneleft) {
-                                               if ((error = xfs_inobt_get_rec(
-                                                           tcur,
-                                                           &trec.ir_startino,
-                                                           &trec.ir_freecount,
-                                                           &trec.ir_free, &i)))
-                                                       goto error1;
-                                               XFS_WANT_CORRUPTED_GOTO(i == 1,
-                                                       error1);
-                                       }
-                               }
-                               /*
-                                * If used the right, get another one
-                                * further right.
+                                * Not in range - save last search
+                                * location and allocate a new inode
                                 */
-                               else {
-                                       if ((error = xfs_btree_increment(cur, 0,
-                                                       &i)))
-                                               goto error1;
-                                       doneright = !i;
-                                       if (!doneright) {
-                                               if ((error = xfs_inobt_get_rec(
-                                                           cur,
-                                                           &rec.ir_startino,
-                                                           &rec.ir_freecount,
-                                                           &rec.ir_free, &i)))
-                                                       goto error1;
-                                               XFS_WANT_CORRUPTED_GOTO(i == 1,
-                                                       error1);
-                                       }
-                               }
+                               pag->pagl_leftrec = trec.ir_startino;
+                               pag->pagl_rightrec = rec.ir_startino;
+                               pag->pagl_pagino = pagino;
+                               goto newino;
+                       }
+
+                       /* figure out the closer block if both are valid. */
+                       if (!doneleft && !doneright) {
+                               useleft = pagino -
+                                (trec.ir_startino + XFS_INODES_PER_CHUNK - 1) <
+                                 rec.ir_startino - pagino;
+                       } else {
+                               useleft = !doneleft;
                        }
-                       ASSERT(!doneleft || !doneright);
+
+                       /* free inodes to the left? */
+                       if (useleft && trec.ir_freecount) {
+                               rec = trec;
+                               xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
+                               cur = tcur;
+
+                               pag->pagl_leftrec = trec.ir_startino;
+                               pag->pagl_rightrec = rec.ir_startino;
+                               pag->pagl_pagino = pagino;
+                               goto alloc_inode;
+                       }
+
+                       /* free inodes to the right? */
+                       if (!useleft && rec.ir_freecount) {
+                               xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
+
+                               pag->pagl_leftrec = trec.ir_startino;
+                               pag->pagl_rightrec = rec.ir_startino;
+                               pag->pagl_pagino = pagino;
+                               goto alloc_inode;
+                       }
+
+                       /* get next record to check */
+                       if (useleft) {
+                               error = xfs_ialloc_next_rec(tcur, &trec,
+                                                                &doneleft, 1);
+                       } else {
+                               error = xfs_ialloc_next_rec(cur, &rec,
+                                                                &doneright, 0);
+                       }
+                       if (error)
+                               goto error1;
                }
+
+               /*
+                * We've reached the end of the btree. because
+                * we are only searching a small chunk of the
+                * btree each search, there is obviously free
+                * inodes closer to the parent inode than we
+                * are now. restart the search again.
+                */
+               pag->pagl_pagino = NULLAGINO;
+               pag->pagl_leftrec = NULLAGINO;
+               pag->pagl_rightrec = NULLAGINO;
+               xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
+               xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
+               goto restart_pagno;
        }
+
        /*
-        * In a different a.g. from the parent.
+        * In a different AG from the parent.
         * See if the most recently allocated block has any free.
         */
-       else if (be32_to_cpu(agi->agi_newino) != NULLAGINO) {
-               if ((error = xfs_inobt_lookup_eq(cur,
-                               be32_to_cpu(agi->agi_newino), 0, 0, &i)))
+newino:
+       if (be32_to_cpu(agi->agi_newino) != NULLAGINO) {
+               error = xfs_inobt_lookup(cur, be32_to_cpu(agi->agi_newino),
+                                        XFS_LOOKUP_EQ, &i);
+               if (error)
                        goto error0;
-               if (i == 1 &&
-                   (error = xfs_inobt_get_rec(cur, &rec.ir_startino,
-                           &rec.ir_freecount, &rec.ir_free, &j)) == 0 &&
-                   j == 1 &&
-                   rec.ir_freecount > 0) {
-                       /*
-                        * The last chunk allocated in the group still has
-                        * a free inode.
-                        */
-               }
-               /*
-                * None left in the last group, search the whole a.g.
-                */
-               else {
+
+               if (i == 1) {
+                       error = xfs_inobt_get_rec(cur, &rec, &j);
                        if (error)
                                goto error0;
-                       if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i)))
-                               goto error0;
-                       ASSERT(i == 1);
-                       for (;;) {
-                               if ((error = xfs_inobt_get_rec(cur,
-                                               &rec.ir_startino,
-                                               &rec.ir_freecount, &rec.ir_free,
-                                               &i)))
-                                       goto error0;
-                               XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
-                               if (rec.ir_freecount > 0)
-                                       break;
-                               if ((error = xfs_btree_increment(cur, 0, &i)))
-                                       goto error0;
-                               XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
+
+                       if (j == 1 && rec.ir_freecount > 0) {
+                               /*
+                                * The last chunk allocated in the group
+                                * still has a free inode.
+                                */
+                               goto alloc_inode;
                        }
                }
        }
+
+       /*
+        * None left in the last group, search the whole AG
+        */
+       error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i);
+       if (error)
+               goto error0;
+       XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
+
+       for (;;) {
+               error = xfs_inobt_get_rec(cur, &rec, &i);
+               if (error)
+                       goto error0;
+               XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
+               if (rec.ir_freecount > 0)
+                       break;
+               error = xfs_btree_increment(cur, 0, &i);
+               if (error)
+                       goto error0;
+               XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
+       }
+
+alloc_inode:
        offset = xfs_ialloc_find_free(&rec.ir_free);
        ASSERT(offset >= 0);
        ASSERT(offset < XFS_INODES_PER_CHUNK);
@@ -945,33 +1000,19 @@ nextag:
        ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino + offset);
        rec.ir_free &= ~XFS_INOBT_MASK(offset);
        rec.ir_freecount--;
-       if ((error = xfs_inobt_update(cur, rec.ir_startino, rec.ir_freecount,
-                       rec.ir_free)))
+       error = xfs_inobt_update(cur, &rec);
+       if (error)
                goto error0;
        be32_add_cpu(&agi->agi_freecount, -1);
        xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
        down_read(&mp->m_peraglock);
        mp->m_perag[tagno].pagi_freecount--;
        up_read(&mp->m_peraglock);
-#ifdef DEBUG
-       if (cur->bc_nlevels == 1) {
-               int     freecount = 0;
 
-               if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i)))
-                       goto error0;
-               do {
-                       if ((error = xfs_inobt_get_rec(cur, &rec.ir_startino,
-                                       &rec.ir_freecount, &rec.ir_free, &i)))
-                               goto error0;
-                       XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
-                       freecount += rec.ir_freecount;
-                       if ((error = xfs_btree_increment(cur, 0, &i)))
-                               goto error0;
-               } while (i == 1);
-               ASSERT(freecount == be32_to_cpu(agi->agi_freecount) ||
-                      XFS_FORCED_SHUTDOWN(mp));
-       }
-#endif
+       error = xfs_check_agi_freecount(cur, agi);
+       if (error)
+               goto error0;
+
        xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
        xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -1);
        *inop = ino;
@@ -1062,38 +1103,23 @@ xfs_difree(
         * Initialize the cursor.
         */
        cur = xfs_inobt_init_cursor(mp, tp, agbp, agno);
-#ifdef DEBUG
-       if (cur->bc_nlevels == 1) {
-               int freecount = 0;
 
-               if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i)))
-                       goto error0;
-               do {
-                       if ((error = xfs_inobt_get_rec(cur, &rec.ir_startino,
-                                       &rec.ir_freecount, &rec.ir_free, &i)))
-                               goto error0;
-                       if (i) {
-                               freecount += rec.ir_freecount;
-                               if ((error = xfs_btree_increment(cur, 0, &i)))
-                                       goto error0;
-                       }
-               } while (i == 1);
-               ASSERT(freecount == be32_to_cpu(agi->agi_freecount) ||
-                      XFS_FORCED_SHUTDOWN(mp));
-       }
-#endif
+       error = xfs_check_agi_freecount(cur, agi);
+       if (error)
+               goto error0;
+
        /*
         * Look for the entry describing this inode.
         */
-       if ((error = xfs_inobt_lookup_le(cur, agino, 0, 0, &i))) {
+       if ((error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i))) {
                cmn_err(CE_WARN,
-                       "xfs_difree: xfs_inobt_lookup_le returned()  an error %d on %s.  Returning error.",
+                       "xfs_difree: xfs_inobt_lookup returned()  an error %d on %s.  Returning error.",
                        error, mp->m_fsname);
                goto error0;
        }
        XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
-       if ((error = xfs_inobt_get_rec(cur, &rec.ir_startino, &rec.ir_freecount,
-                       &rec.ir_free, &i))) {
+       error = xfs_inobt_get_rec(cur, &rec, &i);
+       if (error) {
                cmn_err(CE_WARN,
                        "xfs_difree: xfs_inobt_get_rec()  returned an error %d on %s.  Returning error.",
                        error, mp->m_fsname);
@@ -1148,12 +1174,14 @@ xfs_difree(
        } else {
                *delete = 0;
 
-               if ((error = xfs_inobt_update(cur, rec.ir_startino, rec.ir_freecount, rec.ir_free))) {
+               error = xfs_inobt_update(cur, &rec);
+               if (error) {
                        cmn_err(CE_WARN,
-                               "xfs_difree: xfs_inobt_update()  returned an error %d on %s.  Returning error.",
+       "xfs_difree: xfs_inobt_update returned an error %d on %s.",
                                error, mp->m_fsname);
                        goto error0;
                }
+
                /* 
                 * Change the inode free counts and log the ag/sb changes.
                 */
@@ -1165,28 +1193,10 @@ xfs_difree(
                xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, 1);
        }
 
-#ifdef DEBUG
-       if (cur->bc_nlevels == 1) {
-               int freecount = 0;
+       error = xfs_check_agi_freecount(cur, agi);
+       if (error)
+               goto error0;
 
-               if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i)))
-                       goto error0;
-               do {
-                       if ((error = xfs_inobt_get_rec(cur,
-                                       &rec.ir_startino,
-                                       &rec.ir_freecount,
-                                       &rec.ir_free, &i)))
-                               goto error0;
-                       if (i) {
-                               freecount += rec.ir_freecount;
-                               if ((error = xfs_btree_increment(cur, 0, &i)))
-                                       goto error0;
-                       }
-               } while (i == 1);
-               ASSERT(freecount == be32_to_cpu(agi->agi_freecount) ||
-                      XFS_FORCED_SHUTDOWN(mp));
-       }
-#endif
        xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
        return 0;
 
@@ -1297,9 +1307,7 @@ xfs_imap(
                chunk_agbno = agbno - offset_agbno;
        } else {
                xfs_btree_cur_t *cur;   /* inode btree cursor */
-               xfs_agino_t     chunk_agino; /* first agino in inode chunk */
-               __int32_t       chunk_cnt; /* count of free inodes in chunk */
-               xfs_inofree_t   chunk_free; /* mask of free inodes in chunk */
+               xfs_inobt_rec_incore_t chunk_rec;
                xfs_buf_t       *agbp;  /* agi buffer */
                int             i;      /* temp state */
 
@@ -1315,15 +1323,14 @@ xfs_imap(
                }
 
                cur = xfs_inobt_init_cursor(mp, tp, agbp, agno);
-               error = xfs_inobt_lookup_le(cur, agino, 0, 0, &i);
+               error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i);
                if (error) {
                        xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: "
-                                       "xfs_inobt_lookup_le() failed");
+                                       "xfs_inobt_lookup() failed");
                        goto error0;
                }
 
-               error = xfs_inobt_get_rec(cur, &chunk_agino, &chunk_cnt,
-                               &chunk_free, &i);
+               error = xfs_inobt_get_rec(cur, &chunk_rec, &i);
                if (error) {
                        xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: "
                                        "xfs_inobt_get_rec() failed");
@@ -1341,7 +1348,7 @@ xfs_imap(
                xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
                if (error)
                        return error;
-               chunk_agbno = XFS_AGINO_TO_AGBNO(mp, chunk_agino);
+               chunk_agbno = XFS_AGINO_TO_AGBNO(mp, chunk_rec.ir_startino);
                offset_agbno = agbno - chunk_agbno;
        }
 
index aeee8278f92c135088da71b66d7a18fdaf5658cb..bb5385475e1f904b74bf24ec533b2640e96b867e 100644 (file)
@@ -150,23 +150,15 @@ xfs_ialloc_pagi_init(
         xfs_agnumber_t  agno);         /* allocation group number */
 
 /*
- * Lookup the first record greater than or equal to ino
- * in the btree given by cur.
+ * Lookup a record by ino in the btree given by cur.
  */
-int xfs_inobt_lookup_ge(struct xfs_btree_cur *cur, xfs_agino_t ino,
-               __int32_t fcnt, xfs_inofree_t free, int *stat);
-
-/*
- * Lookup the first record less than or equal to ino
- * in the btree given by cur.
- */
-int xfs_inobt_lookup_le(struct xfs_btree_cur *cur, xfs_agino_t ino,
-               __int32_t fcnt, xfs_inofree_t free, int *stat);
+int xfs_inobt_lookup(struct xfs_btree_cur *cur, xfs_agino_t ino,
+               xfs_lookup_t dir, int *stat);
 
 /*
  * Get the data from the pointed-to record.
  */
-extern int xfs_inobt_get_rec(struct xfs_btree_cur *cur, xfs_agino_t *ino,
-                            __int32_t *fcnt, xfs_inofree_t *free, int *stat);
+extern int xfs_inobt_get_rec(struct xfs_btree_cur *cur,
+               xfs_inobt_rec_incore_t *rec, int *stat);
 
 #endif /* __XFS_IALLOC_H__ */
index ecbf8b4d2e2e4d0f8ae4506b64a4b787dc84e5db..80e526489be5d7ee3dc415ec592fe2807a879a01 100644 (file)
@@ -82,7 +82,6 @@ xfs_inode_alloc(
        memset(&ip->i_df, 0, sizeof(xfs_ifork_t));
        ip->i_flags = 0;
        ip->i_update_core = 0;
-       ip->i_update_size = 0;
        ip->i_delayed_blks = 0;
        memset(&ip->i_d, 0, sizeof(xfs_icdinode_t));
        ip->i_size = 0;
@@ -456,32 +455,6 @@ out_error_or_again:
        return error;
 }
 
-
-/*
- * Look for the inode corresponding to the given ino in the hash table.
- * If it is there and its i_transp pointer matches tp, return it.
- * Otherwise, return NULL.
- */
-xfs_inode_t *
-xfs_inode_incore(xfs_mount_t   *mp,
-                xfs_ino_t      ino,
-                xfs_trans_t    *tp)
-{
-       xfs_inode_t     *ip;
-       xfs_perag_t     *pag;
-
-       pag = xfs_get_perag(mp, ino);
-       read_lock(&pag->pag_ici_lock);
-       ip = radix_tree_lookup(&pag->pag_ici_root, XFS_INO_TO_AGINO(mp, ino));
-       read_unlock(&pag->pag_ici_lock);
-       xfs_put_perag(mp, pag);
-
-       /* the returned inode must match the transaction */
-       if (ip && (ip->i_transp != tp))
-               return NULL;
-       return ip;
-}
-
 /*
  * Decrement reference count of an inode structure and unlock it.
  *
index da428b3fe0f5777980ba58aef8c5e566334f318d..c1dc7ef5a1d853ea935fd954ad0cf4863e701cd4 100644 (file)
@@ -651,7 +651,7 @@ xfs_iformat_btree(
        return 0;
 }
 
-void
+STATIC void
 xfs_dinode_from_disk(
        xfs_icdinode_t          *to,
        xfs_dinode_t            *from)
@@ -1247,7 +1247,7 @@ xfs_isize_check(
  * In that case the pages will still be in memory, but the inode size
  * will never have been updated.
  */
-xfs_fsize_t
+STATIC xfs_fsize_t
 xfs_file_last_byte(
        xfs_inode_t     *ip)
 {
@@ -3837,7 +3837,7 @@ xfs_iext_inline_to_direct(
 /*
  * Resize an extent indirection array to new_size bytes.
  */
-void
+STATIC void
 xfs_iext_realloc_indirect(
        xfs_ifork_t     *ifp,           /* inode fork pointer */
        int             new_size)       /* new indirection array size */
@@ -3862,7 +3862,7 @@ xfs_iext_realloc_indirect(
 /*
  * Switch from indirection array to linear (direct) extent allocations.
  */
-void
+STATIC void
 xfs_iext_indirect_to_direct(
         xfs_ifork_t    *ifp)           /* inode fork pointer */
 {
index 65f24a3cc9922a174b8989c276691e01b1e56621..0b38b9a869ece2136bf798a5329d2a38b8bf98ea 100644 (file)
@@ -261,7 +261,6 @@ typedef struct xfs_inode {
        /* Miscellaneous state. */
        unsigned short          i_flags;        /* see defined flags below */
        unsigned char           i_update_core;  /* timestamps/size is dirty */
-       unsigned char           i_update_size;  /* di_size field is dirty */
        unsigned int            i_delayed_blks; /* count of delay alloc blks */
 
        xfs_icdinode_t          i_d;            /* most of ondisk inode */
@@ -468,8 +467,6 @@ static inline void xfs_ifunlock(xfs_inode_t *ip)
 /*
  * xfs_iget.c prototypes.
  */
-xfs_inode_t    *xfs_inode_incore(struct xfs_mount *, xfs_ino_t,
-                                 struct xfs_trans *);
 int            xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
                         uint, uint, xfs_inode_t **, xfs_daddr_t);
 void           xfs_iput(xfs_inode_t *, uint);
@@ -504,7 +501,6 @@ void                xfs_ipin(xfs_inode_t *);
 void           xfs_iunpin(xfs_inode_t *);
 int            xfs_iflush(xfs_inode_t *, uint);
 void           xfs_ichgtime(xfs_inode_t *, int);
-xfs_fsize_t    xfs_file_last_byte(xfs_inode_t *);
 void           xfs_lock_inodes(xfs_inode_t **, int, uint);
 void           xfs_lock_two_inodes(xfs_inode_t *, xfs_inode_t *, uint);
 
@@ -572,8 +568,6 @@ int         xfs_itobp(struct xfs_mount *, struct xfs_trans *,
                          struct xfs_buf **, uint);
 int            xfs_iread(struct xfs_mount *, struct xfs_trans *,
                          struct xfs_inode *, xfs_daddr_t, uint);
-void           xfs_dinode_from_disk(struct xfs_icdinode *,
-                                    struct xfs_dinode *);
 void           xfs_dinode_to_disk(struct xfs_dinode *,
                                   struct xfs_icdinode *);
 void           xfs_idestroy_fork(struct xfs_inode *, int);
@@ -592,8 +586,6 @@ void                xfs_iext_remove_inline(xfs_ifork_t *, xfs_extnum_t, int);
 void           xfs_iext_remove_direct(xfs_ifork_t *, xfs_extnum_t, int);
 void           xfs_iext_remove_indirect(xfs_ifork_t *, xfs_extnum_t, int);
 void           xfs_iext_realloc_direct(xfs_ifork_t *, int);
-void           xfs_iext_realloc_indirect(xfs_ifork_t *, int);
-void           xfs_iext_indirect_to_direct(xfs_ifork_t *);
 void           xfs_iext_direct_to_inline(xfs_ifork_t *, xfs_extnum_t);
 void           xfs_iext_inline_to_direct(xfs_ifork_t *, int);
 void           xfs_iext_destroy(xfs_ifork_t *);
index 977c4aec587eeb3ea316408a73f147082c14c5ba..47d5b663c37e44a2b3528413edba37ec43eba880 100644 (file)
@@ -262,14 +262,6 @@ xfs_inode_item_format(
                SYNCHRONIZE();
        }
 
-       /*
-        * We don't have to worry about re-ordering here because
-        * the update_size field is protected by the inode lock
-        * and we have that held in exclusive mode.
-        */
-       if (ip->i_update_size)
-               ip->i_update_size = 0;
-
        /*
         * Make sure to get the latest atime from the Linux inode.
         */
@@ -712,8 +704,6 @@ xfs_inode_item_unlock(
         * Clear out the fields of the inode log item particular
         * to the current transaction.
         */
-       iip->ili_ilock_recur = 0;
-       iip->ili_iolock_recur = 0;
        iip->ili_flags = 0;
 
        /*
index a52ac125f0556a61c81fd2f375056b735740113f..65bae4c9b8bf3ddb87abb525a38b81687e9932aa 100644 (file)
@@ -137,8 +137,6 @@ typedef struct xfs_inode_log_item {
        struct xfs_inode        *ili_inode;        /* inode ptr */
        xfs_lsn_t               ili_flush_lsn;     /* lsn at last flush */
        xfs_lsn_t               ili_last_lsn;      /* lsn at last transaction */
-       unsigned short          ili_ilock_recur;   /* lock recursion count */
-       unsigned short          ili_iolock_recur;  /* lock recursion count */
        unsigned short          ili_flags;         /* misc flags */
        unsigned short          ili_logged;        /* flushed logged data */
        unsigned int            ili_last_fields;   /* fields when flushed */
index 7a28191cb0decc919a0cde01243c1a0069897d3d..b8e4ee4e89a431904f9e9aa4e6576f7db35d7924 100644 (file)
@@ -72,7 +72,6 @@ struct xfs_mount;
 
 #if XFS_BIG_INUMS
 #define        XFS_MAXINUMBER          ((xfs_ino_t)((1ULL << 56) - 1ULL))
-#define        XFS_INO64_OFFSET        ((xfs_ino_t)(1ULL << 32))
 #else
 #define        XFS_MAXINUMBER          ((xfs_ino_t)((1ULL << 32) - 1ULL))
 #endif
index aeb2d2221c7ddb15b8e4efdae36ee94f40b7fbe3..b68f9107e26cce1e3eb7f4b08f272d493a9d8b06 100644 (file)
@@ -39,7 +39,7 @@
 #include "xfs_error.h"
 #include "xfs_btree.h"
 
-int
+STATIC int
 xfs_internal_inum(
        xfs_mount_t     *mp,
        xfs_ino_t       ino)
@@ -353,9 +353,6 @@ xfs_bulkstat(
        int                     end_of_ag; /* set if we've seen the ag end */
        int                     error;  /* error code */
        int                     fmterror;/* bulkstat formatter result */
-       __int32_t               gcnt;   /* current btree rec's count */
-       xfs_inofree_t           gfree;  /* current btree rec's free mask */
-       xfs_agino_t             gino;   /* current btree rec's start inode */
        int                     i;      /* loop index */
        int                     icount; /* count of inodes good in irbuf */
        size_t                  irbsize; /* size of irec buffer in bytes */
@@ -442,40 +439,43 @@ xfs_bulkstat(
                 * we need to get the remainder of the chunk we're in.
                 */
                if (agino > 0) {
+                       xfs_inobt_rec_incore_t r;
+
                        /*
                         * Lookup the inode chunk that this inode lives in.
                         */
-                       error = xfs_inobt_lookup_le(cur, agino, 0, 0, &tmp);
+                       error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE,
+                                                &tmp);
                        if (!error &&   /* no I/O error */
                            tmp &&      /* lookup succeeded */
                                        /* got the record, should always work */
-                           !(error = xfs_inobt_get_rec(cur, &gino, &gcnt,
-                                   &gfree, &i)) &&
+                           !(error = xfs_inobt_get_rec(cur, &r, &i)) &&
                            i == 1 &&
                                        /* this is the right chunk */
-                           agino < gino + XFS_INODES_PER_CHUNK &&
+                           agino < r.ir_startino + XFS_INODES_PER_CHUNK &&
                                        /* lastino was not last in chunk */
-                           (chunkidx = agino - gino + 1) <
+                           (chunkidx = agino - r.ir_startino + 1) <
                                    XFS_INODES_PER_CHUNK &&
                                        /* there are some left allocated */
                            xfs_inobt_maskn(chunkidx,
-                                   XFS_INODES_PER_CHUNK - chunkidx) & ~gfree) {
+                                   XFS_INODES_PER_CHUNK - chunkidx) &
+                                   ~r.ir_free) {
                                /*
                                 * Grab the chunk record.  Mark all the
                                 * uninteresting inodes (because they're
                                 * before our start point) free.
                                 */
                                for (i = 0; i < chunkidx; i++) {
-                                       if (XFS_INOBT_MASK(i) & ~gfree)
-                                               gcnt++;
+                                       if (XFS_INOBT_MASK(i) & ~r.ir_free)
+                                               r.ir_freecount++;
                                }
-                               gfree |= xfs_inobt_maskn(0, chunkidx);
-                               irbp->ir_startino = gino;
-                               irbp->ir_freecount = gcnt;
-                               irbp->ir_free = gfree;
+                               r.ir_free |= xfs_inobt_maskn(0, chunkidx);
+                               irbp->ir_startino = r.ir_startino;
+                               irbp->ir_freecount = r.ir_freecount;
+                               irbp->ir_free = r.ir_free;
                                irbp++;
-                               agino = gino + XFS_INODES_PER_CHUNK;
-                               icount = XFS_INODES_PER_CHUNK - gcnt;
+                               agino = r.ir_startino + XFS_INODES_PER_CHUNK;
+                               icount = XFS_INODES_PER_CHUNK - r.ir_freecount;
                        } else {
                                /*
                                 * If any of those tests failed, bump the
@@ -493,7 +493,7 @@ xfs_bulkstat(
                        /*
                         * Start of ag.  Lookup the first inode chunk.
                         */
-                       error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &tmp);
+                       error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &tmp);
                        icount = 0;
                }
                /*
@@ -501,6 +501,8 @@ xfs_bulkstat(
                 * until we run out of inodes or space in the buffer.
                 */
                while (irbp < irbufend && icount < ubcount) {
+                       xfs_inobt_rec_incore_t r;
+
                        /*
                         * Loop as long as we're unable to read the
                         * inode btree.
@@ -510,51 +512,55 @@ xfs_bulkstat(
                                if (XFS_AGINO_TO_AGBNO(mp, agino) >=
                                                be32_to_cpu(agi->agi_length))
                                        break;
-                               error = xfs_inobt_lookup_ge(cur, agino, 0, 0,
-                                                           &tmp);
+                               error = xfs_inobt_lookup(cur, agino,
+                                                        XFS_LOOKUP_GE, &tmp);
                                cond_resched();
                        }
                        /*
                         * If ran off the end of the ag either with an error,
                         * or the normal way, set end and stop collecting.
                         */
-                       if (error ||
-                           (error = xfs_inobt_get_rec(cur, &gino, &gcnt,
-                                   &gfree, &i)) ||
-                           i == 0) {
+                       if (error) {
                                end_of_ag = 1;
                                break;
                        }
+
+                       error = xfs_inobt_get_rec(cur, &r, &i);
+                       if (error || i == 0) {
+                               end_of_ag = 1;
+                               break;
+                       }
+
                        /*
                         * If this chunk has any allocated inodes, save it.
                         * Also start read-ahead now for this chunk.
                         */
-                       if (gcnt < XFS_INODES_PER_CHUNK) {
+                       if (r.ir_freecount < XFS_INODES_PER_CHUNK) {
                                /*
                                 * Loop over all clusters in the next chunk.
                                 * Do a readahead if there are any allocated
                                 * inodes in that cluster.
                                 */
-                               for (agbno = XFS_AGINO_TO_AGBNO(mp, gino),
-                                    chunkidx = 0;
+                               agbno = XFS_AGINO_TO_AGBNO(mp, r.ir_startino);
+                               for (chunkidx = 0;
                                     chunkidx < XFS_INODES_PER_CHUNK;
                                     chunkidx += nicluster,
                                     agbno += nbcluster) {
-                                       if (xfs_inobt_maskn(chunkidx,
-                                                           nicluster) & ~gfree)
+                                       if (xfs_inobt_maskn(chunkidx, nicluster)
+                                                       & ~r.ir_free)
                                                xfs_btree_reada_bufs(mp, agno,
                                                        agbno, nbcluster);
                                }
-                               irbp->ir_startino = gino;
-                               irbp->ir_freecount = gcnt;
-                               irbp->ir_free = gfree;
+                               irbp->ir_startino = r.ir_startino;
+                               irbp->ir_freecount = r.ir_freecount;
+                               irbp->ir_free = r.ir_free;
                                irbp++;
-                               icount += XFS_INODES_PER_CHUNK - gcnt;
+                               icount += XFS_INODES_PER_CHUNK - r.ir_freecount;
                        }
                        /*
                         * Set agino to after this chunk and bump the cursor.
                         */
-                       agino = gino + XFS_INODES_PER_CHUNK;
+                       agino = r.ir_startino + XFS_INODES_PER_CHUNK;
                        error = xfs_btree_increment(cur, 0, &tmp);
                        cond_resched();
                }
@@ -820,9 +826,7 @@ xfs_inumbers(
        int             bufidx;
        xfs_btree_cur_t *cur;
        int             error;
-       __int32_t       gcnt;
-       xfs_inofree_t   gfree;
-       xfs_agino_t     gino;
+       xfs_inobt_rec_incore_t r;
        int             i;
        xfs_ino_t       ino;
        int             left;
@@ -855,7 +859,8 @@ xfs_inumbers(
                                continue;
                        }
                        cur = xfs_inobt_init_cursor(mp, NULL, agbp, agno);
-                       error = xfs_inobt_lookup_ge(cur, agino, 0, 0, &tmp);
+                       error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_GE,
+                                                &tmp);
                        if (error) {
                                xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
                                cur = NULL;
@@ -870,9 +875,8 @@ xfs_inumbers(
                                continue;
                        }
                }
-               if ((error = xfs_inobt_get_rec(cur, &gino, &gcnt, &gfree,
-                       &i)) ||
-                   i == 0) {
+               error = xfs_inobt_get_rec(cur, &r, &i);
+               if (error || i == 0) {
                        xfs_buf_relse(agbp);
                        agbp = NULL;
                        xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
@@ -881,10 +885,12 @@ xfs_inumbers(
                        agino = 0;
                        continue;
                }
-               agino = gino + XFS_INODES_PER_CHUNK - 1;
-               buffer[bufidx].xi_startino = XFS_AGINO_TO_INO(mp, agno, gino);
-               buffer[bufidx].xi_alloccount = XFS_INODES_PER_CHUNK - gcnt;
-               buffer[bufidx].xi_allocmask = ~gfree;
+               agino = r.ir_startino + XFS_INODES_PER_CHUNK - 1;
+               buffer[bufidx].xi_startino =
+                       XFS_AGINO_TO_INO(mp, agno, r.ir_startino);
+               buffer[bufidx].xi_alloccount =
+                       XFS_INODES_PER_CHUNK - r.ir_freecount;
+               buffer[bufidx].xi_allocmask = ~r.ir_free;
                bufidx++;
                left--;
                if (bufidx == bcount) {
index 1fb04e7deb61298d13c4a55db385071b92c3b9a5..20792bf459468b84b6bb960d7328888a1ab35df8 100644 (file)
@@ -99,11 +99,6 @@ xfs_bulkstat_one(
        void                    *dibuff,
        int                     *stat);
 
-int
-xfs_internal_inum(
-       xfs_mount_t             *mp,
-       xfs_ino_t               ino);
-
 typedef int (*inumbers_fmt_pf)(
        void                    __user *ubuffer, /* buffer to write to */
        const xfs_inogrp_t      *buffer,        /* buffer to read from */
index bcad5f4c1fd1b3f0c31fc7c0bcb848c12aaa21ee..679c7c4926a2a6e3858366704fa4d1b93887807c 100644 (file)
@@ -451,8 +451,6 @@ extern int   xlog_find_tail(xlog_t  *log,
 extern int      xlog_recover(xlog_t *log);
 extern int      xlog_recover_finish(xlog_t *log);
 extern void     xlog_pack_data(xlog_t *log, xlog_in_core_t *iclog, int);
-extern void     xlog_recover_process_iunlinks(xlog_t *log);
-
 extern struct xfs_buf *xlog_get_bp(xlog_t *, int);
 extern void     xlog_put_bp(struct xfs_buf *);
 
index 47da2fb45377309728acbeb3b4351908d61d6bde..1099395d7d6c1cc5250adec130da128a1469ab64 100644 (file)
@@ -3263,7 +3263,7 @@ xlog_recover_process_one_iunlink(
  * freeing of the inode and its removal from the list must be
  * atomic.
  */
-void
+STATIC void
 xlog_recover_process_iunlinks(
        xlog_t          *log)
 {
index 5c6f092659c1cfb3f0edef669a197d10a955b34d..8b6c9e807efb7b8a47bf493563bd5d8dadde3f4f 100644 (file)
@@ -1568,7 +1568,7 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fields)
  *
  * The m_sb_lock must be held when this routine is called.
  */
-int
+STATIC int
 xfs_mod_incore_sb_unlocked(
        xfs_mount_t     *mp,
        xfs_sb_field_t  field,
index a5122382afde2c569897bac565118226a31e0ca5..a6c023bc0fb27191d895578fe910e052840a804a 100644 (file)
@@ -414,13 +414,10 @@ typedef struct xfs_mod_sb {
 
 extern int     xfs_log_sbcount(xfs_mount_t *, uint);
 extern int     xfs_mountfs(xfs_mount_t *mp);
-extern void    xfs_mountfs_check_barriers(xfs_mount_t *mp);
 
 extern void    xfs_unmountfs(xfs_mount_t *);
 extern int     xfs_unmountfs_writesb(xfs_mount_t *);
 extern int     xfs_mod_incore_sb(xfs_mount_t *, xfs_sb_field_t, int64_t, int);
-extern int     xfs_mod_incore_sb_unlocked(xfs_mount_t *, xfs_sb_field_t,
-                       int64_t, int);
 extern int     xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *,
                        uint, int);
 extern int     xfs_mount_log_sb(xfs_mount_t *, __int64_t);
index afee7eb243234824a44a8ad9b91fc23200fdc6ea..4b0613d99faa9f70533df36ff2c8834535181313 100644 (file)
@@ -563,35 +563,6 @@ xfs_mru_cache_lookup(
        return elem ? elem->value : NULL;
 }
 
-/*
- * To look up an element using its key, but leave its location in the internal
- * lists alone, call xfs_mru_cache_peek().  If the element isn't found, this
- * function returns NULL.
- *
- * See the comments above the declaration of the xfs_mru_cache_lookup() function
- * for important locking information pertaining to this call.
- */
-void *
-xfs_mru_cache_peek(
-       xfs_mru_cache_t *mru,
-       unsigned long   key)
-{
-       xfs_mru_cache_elem_t *elem;
-
-       ASSERT(mru && mru->lists);
-       if (!mru || !mru->lists)
-               return NULL;
-
-       spin_lock(&mru->lock);
-       elem = radix_tree_lookup(&mru->store, key);
-       if (!elem)
-               spin_unlock(&mru->lock);
-       else
-               __release(mru_lock); /* help sparse not be stupid */
-
-       return elem ? elem->value : NULL;
-}
-
 /*
  * To release the internal data structure spinlock after having performed an
  * xfs_mru_cache_lookup() or an xfs_mru_cache_peek(), call xfs_mru_cache_done()
index dd58ea1bbebefeb0a49116c1f52be41e4dc60e44..5d439f34b0c9bf68ee84e22f7535c0fc0aa4a57d 100644 (file)
@@ -49,7 +49,6 @@ int xfs_mru_cache_insert(struct xfs_mru_cache *mru, unsigned long key,
 void * xfs_mru_cache_remove(struct xfs_mru_cache *mru, unsigned long key);
 void xfs_mru_cache_delete(struct xfs_mru_cache *mru, unsigned long key);
 void *xfs_mru_cache_lookup(struct xfs_mru_cache *mru, unsigned long key);
-void *xfs_mru_cache_peek(struct xfs_mru_cache *mru, unsigned long key);
 void xfs_mru_cache_done(struct xfs_mru_cache *mru);
 
 #endif /* __XFS_MRU_CACHE_H__ */
index fea68615ed23bdd65d1953ec6d4d8907c57046f1..3f816ad7ff19e7f0a93458333ac7b98d3842d3ec 100644 (file)
@@ -87,90 +87,6 @@ xfs_write_clear_setuid(
        return 0;
 }
 
-/*
- * Handle logging requirements of various synchronous types of write.
- */
-int
-xfs_write_sync_logforce(
-       xfs_mount_t     *mp,
-       xfs_inode_t     *ip)
-{
-       int             error = 0;
-
-       /*
-        * If we're treating this as O_DSYNC and we have not updated the
-        * size, force the log.
-        */
-       if (!(mp->m_flags & XFS_MOUNT_OSYNCISOSYNC) &&
-           !(ip->i_update_size)) {
-               xfs_inode_log_item_t    *iip = ip->i_itemp;
-
-               /*
-                * If an allocation transaction occurred
-                * without extending the size, then we have to force
-                * the log up the proper point to ensure that the
-                * allocation is permanent.  We can't count on
-                * the fact that buffered writes lock out direct I/O
-                * writes - the direct I/O write could have extended
-                * the size nontransactionally, then finished before
-                * we started.  xfs_write_file will think that the file
-                * didn't grow but the update isn't safe unless the
-                * size change is logged.
-                *
-                * Force the log if we've committed a transaction
-                * against the inode or if someone else has and
-                * the commit record hasn't gone to disk (e.g.
-                * the inode is pinned).  This guarantees that
-                * all changes affecting the inode are permanent
-                * when we return.
-                */
-               if (iip && iip->ili_last_lsn) {
-                       error = _xfs_log_force(mp, iip->ili_last_lsn,
-                                       XFS_LOG_FORCE | XFS_LOG_SYNC, NULL);
-               } else if (xfs_ipincount(ip) > 0) {
-                       error = _xfs_log_force(mp, (xfs_lsn_t)0,
-                                       XFS_LOG_FORCE | XFS_LOG_SYNC, NULL);
-               }
-
-       } else {
-               xfs_trans_t     *tp;
-
-               /*
-                * O_SYNC or O_DSYNC _with_ a size update are handled
-                * the same way.
-                *
-                * If the write was synchronous then we need to make
-                * sure that the inode modification time is permanent.
-                * We'll have updated the timestamp above, so here
-                * we use a synchronous transaction to log the inode.
-                * It's not fast, but it's necessary.
-                *
-                * If this a dsync write and the size got changed
-                * non-transactionally, then we need to ensure that
-                * the size change gets logged in a synchronous
-                * transaction.
-                */
-               tp = xfs_trans_alloc(mp, XFS_TRANS_WRITE_SYNC);
-               if ((error = xfs_trans_reserve(tp, 0,
-                                               XFS_SWRITE_LOG_RES(mp),
-                                               0, 0, 0))) {
-                       /* Transaction reserve failed */
-                       xfs_trans_cancel(tp, 0);
-               } else {
-                       /* Transaction reserve successful */
-                       xfs_ilock(ip, XFS_ILOCK_EXCL);
-                       xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
-                       xfs_trans_ihold(tp, ip);
-                       xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-                       xfs_trans_set_sync(tp);
-                       error = xfs_trans_commit(tp, 0);
-                       xfs_iunlock(ip, XFS_ILOCK_EXCL);
-               }
-       }
-
-       return error;
-}
-
 /*
  * Force a shutdown of the filesystem instantly while keeping
  * the filesystem consistent. We don't do an unmount here; just shutdown
index f76c003ec55d25bef4c575b8ef518383e53c22bd..f5e4874c37d8ecfa55a77a1a1eeca31c7a6d27df 100644 (file)
@@ -68,7 +68,6 @@ xfs_get_extsz_hint(
  * Prototypes for functions in xfs_rw.c.
  */
 extern int xfs_write_clear_setuid(struct xfs_inode *ip);
-extern int xfs_write_sync_logforce(struct xfs_mount *mp, struct xfs_inode *ip);
 extern int xfs_bwrite(struct xfs_mount *mp, struct xfs_buf *bp);
 extern int xfs_bioerror(struct xfs_buf *bp);
 extern int xfs_bioerror_relse(struct xfs_buf *bp);
@@ -78,10 +77,4 @@ extern int xfs_read_buf(struct xfs_mount *mp, xfs_buftarg_t *btp,
 extern void xfs_ioerror_alert(char *func, struct xfs_mount *mp,
                                xfs_buf_t *bp, xfs_daddr_t blkno);
 
-/*
- * Prototypes for functions in xfs_vnodeops.c.
- */
-extern int xfs_free_eofblocks(struct xfs_mount *mp, struct xfs_inode *ip,
-                       int flags);
-
 #endif /* __XFS_RW_H__ */
index 775249a54f6f9dc06584e6fe69617c6afa524697..ed47fc77759c7cce24f98f283a717fae33fa9eea 100644 (file)
@@ -68,7 +68,7 @@ typedef struct xfs_trans_header {
 #define XFS_TRANS_GROWFS               14
 #define XFS_TRANS_STRAT_WRITE          15
 #define XFS_TRANS_DIOSTRAT             16
-#define        XFS_TRANS_WRITE_SYNC            17
+/* 17 was XFS_TRANS_WRITE_SYNC */
 #define        XFS_TRANS_WRITEID               18
 #define        XFS_TRANS_ADDAFORK              19
 #define        XFS_TRANS_ATTRINVAL             20
index 8ee2f8c8b0a61863c9686a7bbae9b4794616615f..218829e6a152dce6698dbb8a9a8466fda694d92d 100644 (file)
@@ -307,7 +307,7 @@ xfs_trans_read_buf(
                        return (flags & XFS_BUF_TRYLOCK) ?
                                        EAGAIN : XFS_ERROR(ENOMEM);
 
-               if ((bp != NULL) && (XFS_BUF_GETERROR(bp) != 0)) {
+               if (XFS_BUF_GETERROR(bp) != 0) {
                        xfs_ioerror_alert("xfs_trans_read_buf", mp,
                                          bp, blkno);
                        error = XFS_BUF_GETERROR(bp);
@@ -315,7 +315,7 @@ xfs_trans_read_buf(
                        return error;
                }
 #ifdef DEBUG
-               if (xfs_do_error && (bp != NULL)) {
+               if (xfs_do_error) {
                        if (xfs_error_target == target) {
                                if (((xfs_req_num++) % xfs_error_mod) == 0) {
                                        xfs_buf_relse(bp);
index 23d276af2e0c43c0fddb374462adcc9fd0ddc481..785ff101da0a66368a7c06587dd13b3c3eae2f70 100644 (file)
@@ -49,30 +49,7 @@ xfs_trans_inode_broot_debug(
 
 
 /*
- * Get and lock the inode for the caller if it is not already
- * locked within the given transaction.  If it is already locked
- * within the transaction, just increment its lock recursion count
- * and return a pointer to it.
- *
- * For an inode to be locked in a transaction, the inode lock, as
- * opposed to the io lock, must be taken exclusively.  This ensures
- * that the inode can be involved in only 1 transaction at a time.
- * Lock recursion is handled on the io lock, but only for lock modes
- * of equal or lesser strength.  That is, you can recur on the io lock
- * held EXCL with a SHARED request but not vice versa.  Also, if
- * the inode is already a part of the transaction then you cannot
- * go from not holding the io lock to having it EXCL or SHARED.
- *
- * Use the inode cache routine xfs_inode_incore() to find the inode
- * if it is already owned by this transaction.
- *
- * If we don't already own the inode, use xfs_iget() to get it.
- * Since the inode log item structure is embedded in the incore
- * inode structure and is initialized when the inode is brought
- * into memory, there is nothing to do with it here.
- *
- * If the given transaction pointer is NULL, just call xfs_iget().
- * This simplifies code which must handle both cases.
+ * Get an inode and join it to the transaction.
  */
 int
 xfs_trans_iget(
@@ -84,62 +61,11 @@ xfs_trans_iget(
        xfs_inode_t     **ipp)
 {
        int                     error;
-       xfs_inode_t             *ip;
-
-       /*
-        * If the transaction pointer is NULL, just call the normal
-        * xfs_iget().
-        */
-       if (tp == NULL)
-               return xfs_iget(mp, NULL, ino, flags, lock_flags, ipp, 0);
-
-       /*
-        * If we find the inode in core with this transaction
-        * pointer in its i_transp field, then we know we already
-        * have it locked.  In this case we just increment the lock
-        * recursion count and return the inode to the caller.
-        * Assert that the inode is already locked in the mode requested
-        * by the caller.  We cannot do lock promotions yet, so
-        * die if someone gets this wrong.
-        */
-       if ((ip = xfs_inode_incore(tp->t_mountp, ino, tp)) != NULL) {
-               /*
-                * Make sure that the inode lock is held EXCL and
-                * that the io lock is never upgraded when the inode
-                * is already a part of the transaction.
-                */
-               ASSERT(ip->i_itemp != NULL);
-               ASSERT(lock_flags & XFS_ILOCK_EXCL);
-               ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
-               ASSERT((!(lock_flags & XFS_IOLOCK_EXCL)) ||
-                      xfs_isilocked(ip, XFS_IOLOCK_EXCL));
-               ASSERT((!(lock_flags & XFS_IOLOCK_EXCL)) ||
-                      (ip->i_itemp->ili_flags & XFS_ILI_IOLOCKED_EXCL));
-               ASSERT((!(lock_flags & XFS_IOLOCK_SHARED)) ||
-                      xfs_isilocked(ip, XFS_IOLOCK_EXCL|XFS_IOLOCK_SHARED));
-               ASSERT((!(lock_flags & XFS_IOLOCK_SHARED)) ||
-                      (ip->i_itemp->ili_flags & XFS_ILI_IOLOCKED_ANY));
-
-               if (lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) {
-                       ip->i_itemp->ili_iolock_recur++;
-               }
-               if (lock_flags & XFS_ILOCK_EXCL) {
-                       ip->i_itemp->ili_ilock_recur++;
-               }
-               *ipp = ip;
-               return 0;
-       }
-
-       ASSERT(lock_flags & XFS_ILOCK_EXCL);
-       error = xfs_iget(tp->t_mountp, tp, ino, flags, lock_flags, &ip, 0);
-       if (error) {
-               return error;
-       }
-       ASSERT(ip != NULL);
 
-       xfs_trans_ijoin(tp, ip, lock_flags);
-       *ipp = ip;
-       return 0;
+       error = xfs_iget(mp, tp, ino, flags, lock_flags, ipp, 0);
+       if (!error && tp)
+               xfs_trans_ijoin(tp, *ipp, lock_flags);
+       return error;
 }
 
 /*
@@ -163,8 +89,6 @@ xfs_trans_ijoin(
                xfs_inode_item_init(ip, ip->i_mount);
        iip = ip->i_itemp;
        ASSERT(iip->ili_flags == 0);
-       ASSERT(iip->ili_ilock_recur == 0);
-       ASSERT(iip->ili_iolock_recur == 0);
 
        /*
         * Get a log_item_desc to point at the new item.
index 492d75bae2bf22f25ff52fac48953e9e95141a01..a434f287962d18588e0711110b8b758818b9ceee 100644 (file)
@@ -611,7 +611,7 @@ xfs_fsync(
        xfs_inode_t     *ip)
 {
        xfs_trans_t     *tp;
-       int             error;
+       int             error = 0;
        int             log_flushed = 0, changed = 1;
 
        xfs_itrace_entry(ip);
@@ -619,14 +619,9 @@ xfs_fsync(
        if (XFS_FORCED_SHUTDOWN(ip->i_mount))
                return XFS_ERROR(EIO);
 
-       /* capture size updates in I/O completion before writing the inode. */
-       error = xfs_wait_on_pages(ip, 0, -1);
-       if (error)
-               return XFS_ERROR(error);
-
        /*
         * We always need to make sure that the required inode state is safe on
-        * disk.  The vnode might be clean but we still might need to force the
+        * disk.  The inode might be clean but we still might need to force the
         * log because of committed transactions that haven't hit the disk yet.
         * Likewise, there could be unflushed non-transactional changes to the
         * inode core that have to go to disk and this requires us to issue
@@ -638,7 +633,7 @@ xfs_fsync(
         */
        xfs_ilock(ip, XFS_ILOCK_SHARED);
 
-       if (!(ip->i_update_size || ip->i_update_core)) {
+       if (!ip->i_update_core) {
                /*
                 * Timestamps/size haven't changed since last inode flush or
                 * inode transaction commit.  That means either nothing got
@@ -718,7 +713,7 @@ xfs_fsync(
  * when the link count isn't zero and by xfs_dm_punch_hole() when
  * punching a hole to EOF.
  */
-int
+STATIC int
 xfs_free_eofblocks(
        xfs_mount_t     *mp,
        xfs_inode_t     *ip,
@@ -1476,8 +1471,8 @@ xfs_create(
        if (error == ENOSPC) {
                /* flush outstanding delalloc blocks and retry */
                xfs_flush_inodes(dp);
-               error = xfs_trans_reserve(tp, resblks, XFS_CREATE_LOG_RES(mp), 0,
-                       XFS_TRANS_PERM_LOG_RES, XFS_CREATE_LOG_COUNT);
+               error = xfs_trans_reserve(tp, resblks, log_res, 0,
+                               XFS_TRANS_PERM_LOG_RES, log_count);
        }
        if (error == ENOSPC) {
                /* No space at all so try a "no-allocation" reservation */
index a43223af98b667c0e5af01ed90d4637fe001272e..29ca8f53ffbe203fc00960e495fb39c3f959fc51 100644 (file)
@@ -88,7 +88,8 @@
 #endif
 
 #ifdef CONFIG_FTRACE_MCOUNT_RECORD
-#define MCOUNT_REC()   VMLINUX_SYMBOL(__start_mcount_loc) = .; \
+#define MCOUNT_REC()   . = ALIGN(8);                           \
+                       VMLINUX_SYMBOL(__start_mcount_loc) = .; \
                        *(__mcount_loc)                         \
                        VMLINUX_SYMBOL(__stop_mcount_loc) = .;
 #else
        /* __*init sections */                                          \
        __init_rodata : AT(ADDR(__init_rodata) - LOAD_OFFSET) {         \
                *(.ref.rodata)                                          \
-               MCOUNT_REC()                                            \
                DEV_KEEP(init.rodata)                                   \
                DEV_KEEP(exit.rodata)                                   \
                CPU_KEEP(init.rodata)                                   \
        MEM_DISCARD(init.data)                                          \
        KERNEL_CTORS()                                                  \
        *(.init.rodata)                                                 \
+       MCOUNT_REC()                                                    \
        DEV_DISCARD(init.rodata)                                        \
        CPU_DISCARD(init.rodata)                                        \
        MEM_DISCARD(init.rodata)
index 7609365577f1b88df0322f17fd6cd5cfaddcdc3d..5cb86c307f5d791298ae0add65bcd1f98dd781fb 100644 (file)
@@ -21,4 +21,111 @@ extern struct key_type key_type_rxrpc;
 
 extern struct key *rxrpc_get_null_key(const char *);
 
+/*
+ * RxRPC key for Kerberos IV (type-2 security)
+ */
+struct rxkad_key {
+       u32     vice_id;
+       u32     start;                  /* time at which ticket starts */
+       u32     expiry;                 /* time at which ticket expires */
+       u32     kvno;                   /* key version number */
+       u8      primary_flag;           /* T if key for primary cell for this user */
+       u16     ticket_len;             /* length of ticket[] */
+       u8      session_key[8];         /* DES session key */
+       u8      ticket[0];              /* the encrypted ticket */
+};
+
+/*
+ * Kerberos 5 principal
+ *     name/name/name@realm
+ */
+struct krb5_principal {
+       u8      n_name_parts;           /* N of parts of the name part of the principal */
+       char    **name_parts;           /* parts of the name part of the principal */
+       char    *realm;                 /* parts of the realm part of the principal */
+};
+
+/*
+ * Kerberos 5 tagged data
+ */
+struct krb5_tagged_data {
+       /* for tag value, see /usr/include/krb5/krb5.h
+        * - KRB5_AUTHDATA_* for auth data
+        * - 
+        */
+       s32             tag;
+       u32             data_len;
+       u8              *data;
+};
+
+/*
+ * RxRPC key for Kerberos V (type-5 security)
+ */
+struct rxk5_key {
+       u64                     authtime;       /* time at which auth token generated */
+       u64                     starttime;      /* time at which auth token starts */
+       u64                     endtime;        /* time at which auth token expired */
+       u64                     renew_till;     /* time to which auth token can be renewed */
+       s32                     is_skey;        /* T if ticket is encrypted in another ticket's
+                                                * skey */
+       s32                     flags;          /* mask of TKT_FLG_* bits (krb5/krb5.h) */
+       struct krb5_principal   client;         /* client principal name */
+       struct krb5_principal   server;         /* server principal name */
+       u16                     ticket_len;     /* length of ticket */
+       u16                     ticket2_len;    /* length of second ticket */
+       u8                      n_authdata;     /* number of authorisation data elements */
+       u8                      n_addresses;    /* number of addresses */
+       struct krb5_tagged_data session;        /* session data; tag is enctype */
+       struct krb5_tagged_data *addresses;     /* addresses */
+       u8                      *ticket;        /* krb5 ticket */
+       u8                      *ticket2;       /* second krb5 ticket, if related to ticket (via
+                                                * DUPLICATE-SKEY or ENC-TKT-IN-SKEY) */
+       struct krb5_tagged_data *authdata;      /* authorisation data */
+};
+
+/*
+ * list of tokens attached to an rxrpc key
+ */
+struct rxrpc_key_token {
+       u16     security_index;         /* RxRPC header security index */
+       struct rxrpc_key_token *next;   /* the next token in the list */
+       union {
+               struct rxkad_key *kad;
+               struct rxk5_key *k5;
+       };
+};
+
+/*
+ * structure of raw payloads passed to add_key() or instantiate key
+ */
+struct rxrpc_key_data_v1 {
+       u32             kif_version;            /* 1 */
+       u16             security_index;
+       u16             ticket_length;
+       u32             expiry;                 /* time_t */
+       u32             kvno;
+       u8              session_key[8];
+       u8              ticket[0];
+};
+
+/*
+ * AF_RXRPC key payload derived from XDR format
+ * - based on openafs-1.4.10/src/auth/afs_token.xg
+ */
+#define AFSTOKEN_LENGTH_MAX            16384   /* max payload size */
+#define AFSTOKEN_STRING_MAX            256     /* max small string length */
+#define AFSTOKEN_DATA_MAX              64      /* max small data length */
+#define AFSTOKEN_CELL_MAX              64      /* max cellname length */
+#define AFSTOKEN_MAX                   8       /* max tokens per payload */
+#define AFSTOKEN_BDATALN_MAX           16384   /* max big data length */
+#define AFSTOKEN_RK_TIX_MAX            12000   /* max RxKAD ticket size */
+#define AFSTOKEN_GK_KEY_MAX            64      /* max GSSAPI key size */
+#define AFSTOKEN_GK_TOKEN_MAX          16384   /* max GSSAPI token size */
+#define AFSTOKEN_K5_COMPONENTS_MAX     16      /* max K5 components */
+#define AFSTOKEN_K5_NAME_MAX           128     /* max K5 name length */
+#define AFSTOKEN_K5_REALM_MAX          64      /* max K5 realm name length */
+#define AFSTOKEN_K5_TIX_MAX            16384   /* max K5 ticket size */
+#define AFSTOKEN_K5_ADDRESSES_MAX      16      /* max K5 addresses */
+#define AFSTOKEN_K5_AUTHDATA_MAX       16      /* max K5 pieces of auth data */
+
 #endif /* _KEYS_RXRPC_TYPE_H */
index 1219be4fb42e8f2a86e9e1268dfe7958fde8263c..83d2fbd81b93a056ab7a55c1a1323deb744ef75a 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/list.h>
 #include <linux/cache.h>
 #include <linux/timer.h>
+#include <linux/init.h>
 #include <asm/div64.h>
 #include <asm/io.h>
 
@@ -148,14 +149,11 @@ extern u64 timecounter_cyc2time(struct timecounter *tc,
  * @disable:           optional function to disable the clocksource
  * @mask:              bitmask for two's complement
  *                     subtraction of non 64 bit counters
- * @mult:              cycle to nanosecond multiplier (adjusted by NTP)
- * @mult_orig:         cycle to nanosecond multiplier (unadjusted by NTP)
+ * @mult:              cycle to nanosecond multiplier
  * @shift:             cycle to nanosecond divisor (power of two)
  * @flags:             flags describing special properties
  * @vread:             vsyscall based read
  * @resume:            resume function for the clocksource, if necessary
- * @cycle_interval:    Used internally by timekeeping core, please ignore.
- * @xtime_interval:    Used internally by timekeeping core, please ignore.
  */
 struct clocksource {
        /*
@@ -169,7 +167,6 @@ struct clocksource {
        void (*disable)(struct clocksource *cs);
        cycle_t mask;
        u32 mult;
-       u32 mult_orig;
        u32 shift;
        unsigned long flags;
        cycle_t (*vread)(void);
@@ -181,19 +178,12 @@ struct clocksource {
 #define CLKSRC_FSYS_MMIO_SET(mmio, addr)      do { } while (0)
 #endif
 
-       /* timekeeping specific data, ignore */
-       cycle_t cycle_interval;
-       u64     xtime_interval;
-       u32     raw_interval;
        /*
         * Second part is written at each timer interrupt
         * Keep it in a different cache line to dirty no
         * more than one cache line.
         */
        cycle_t cycle_last ____cacheline_aligned_in_smp;
-       u64 xtime_nsec;
-       s64 error;
-       struct timespec raw_time;
 
 #ifdef CONFIG_CLOCKSOURCE_WATCHDOG
        /* Watchdog related data, used by the framework */
@@ -202,8 +192,6 @@ struct clocksource {
 #endif
 };
 
-extern struct clocksource *clock;      /* current clocksource */
-
 /*
  * Clock source flags bits::
  */
@@ -212,6 +200,7 @@ extern struct clocksource *clock;   /* current clocksource */
 
 #define CLOCK_SOURCE_WATCHDOG                  0x10
 #define CLOCK_SOURCE_VALID_FOR_HRES            0x20
+#define CLOCK_SOURCE_UNSTABLE                  0x40
 
 /* simplify initialization of mask field */
 #define CLOCKSOURCE_MASK(bits) (cycle_t)((bits) < 64 ? ((1ULL<<(bits))-1) : -1)
@@ -268,108 +257,15 @@ static inline u32 clocksource_hz2mult(u32 hz, u32 shift_constant)
 }
 
 /**
- * clocksource_read: - Access the clocksource's current cycle value
- * @cs:                pointer to clocksource being read
- *
- * Uses the clocksource to return the current cycle_t value
- */
-static inline cycle_t clocksource_read(struct clocksource *cs)
-{
-       return cs->read(cs);
-}
-
-/**
- * clocksource_enable: - enable clocksource
- * @cs:                pointer to clocksource
- *
- * Enables the specified clocksource. The clocksource callback
- * function should start up the hardware and setup mult and field
- * members of struct clocksource to reflect hardware capabilities.
- */
-static inline int clocksource_enable(struct clocksource *cs)
-{
-       int ret = 0;
-
-       if (cs->enable)
-               ret = cs->enable(cs);
-
-       /*
-        * The frequency may have changed while the clocksource
-        * was disabled. If so the code in ->enable() must update
-        * the mult value to reflect the new frequency. Make sure
-        * mult_orig follows this change.
-        */
-       cs->mult_orig = cs->mult;
-
-       return ret;
-}
-
-/**
- * clocksource_disable: - disable clocksource
- * @cs:                pointer to clocksource
- *
- * Disables the specified clocksource. The clocksource callback
- * function should power down the now unused hardware block to
- * save power.
- */
-static inline void clocksource_disable(struct clocksource *cs)
-{
-       /*
-        * Save mult_orig in mult so clocksource_enable() can
-        * restore the value regardless if ->enable() updates
-        * the value of mult or not.
-        */
-       cs->mult = cs->mult_orig;
-
-       if (cs->disable)
-               cs->disable(cs);
-}
-
-/**
- * cyc2ns - converts clocksource cycles to nanoseconds
- * @cs:                Pointer to clocksource
- * @cycles:    Cycles
+ * clocksource_cyc2ns - converts clocksource cycles to nanoseconds
  *
- * Uses the clocksource and ntp ajdustment to convert cycle_ts to nanoseconds.
+ * Converts cycles to nanoseconds, using the given mult and shift.
  *
  * XXX - This could use some mult_lxl_ll() asm optimization
  */
-static inline s64 cyc2ns(struct clocksource *cs, cycle_t cycles)
-{
-       u64 ret = (u64)cycles;
-       ret = (ret * cs->mult) >> cs->shift;
-       return ret;
-}
-
-/**
- * clocksource_calculate_interval - Calculates a clocksource interval struct
- *
- * @c:         Pointer to clocksource.
- * @length_nsec: Desired interval length in nanoseconds.
- *
- * Calculates a fixed cycle/nsec interval for a given clocksource/adjustment
- * pair and interval request.
- *
- * Unless you're the timekeeping code, you should not be using this!
- */
-static inline void clocksource_calculate_interval(struct clocksource *c,
-                                                 unsigned long length_nsec)
+static inline s64 clocksource_cyc2ns(cycle_t cycles, u32 mult, u32 shift)
 {
-       u64 tmp;
-
-       /* Do the ns -> cycle conversion first, using original mult */
-       tmp = length_nsec;
-       tmp <<= c->shift;
-       tmp += c->mult_orig/2;
-       do_div(tmp, c->mult_orig);
-
-       c->cycle_interval = (cycle_t)tmp;
-       if (c->cycle_interval == 0)
-               c->cycle_interval = 1;
-
-       /* Go back from cycles -> shifted ns, this time use ntp adjused mult */
-       c->xtime_interval = (u64)c->cycle_interval * c->mult;
-       c->raw_interval = ((u64)c->cycle_interval * c->mult_orig) >> c->shift;
+       return ((u64) cycles * mult) >> shift;
 }
 
 
@@ -380,6 +276,8 @@ extern void clocksource_touch_watchdog(void);
 extern struct clocksource* clocksource_get_next(void);
 extern void clocksource_change_rating(struct clocksource *cs, int rating);
 extern void clocksource_resume(void);
+extern struct clocksource * __init __weak clocksource_default_clock(void);
+extern void clocksource_mark_unstable(struct clocksource *cs);
 
 #ifdef CONFIG_GENERIC_TIME_VSYSCALL
 extern void update_vsyscall(struct timespec *ts, struct clocksource *c);
@@ -394,4 +292,6 @@ static inline void update_vsyscall_tz(void)
 }
 #endif
 
+extern void timekeeping_notify(struct clocksource *clock);
+
 #endif /* _LINUX_CLOCKSOURCE_H */
index 161042746afcf0f3fdf67201b8007deaa54d0a61..44717eb47639211ec9196875fe20212c72d603c5 100644 (file)
@@ -65,6 +65,9 @@ static inline int cpufreq_unregister_notifier(struct notifier_block *nb,
 
 struct cpufreq_governor;
 
+/* /sys/devices/system/cpu/cpufreq: entry point for global variables */
+extern struct kobject *cpufreq_global_kobject;
+
 #define CPUFREQ_ETERNAL                        (-1)
 struct cpufreq_cpuinfo {
        unsigned int            max_freq;
@@ -274,6 +277,13 @@ struct freq_attr {
        ssize_t (*store)(struct cpufreq_policy *, const char *, size_t count);
 };
 
+struct global_attr {
+       struct attribute attr;
+       ssize_t (*show)(struct kobject *kobj,
+                       struct attribute *attr, char *buf);
+       ssize_t (*store)(struct kobject *a, struct attribute *b,
+                        const char *c, size_t count);
+};
 
 /*********************************************************************
  *                        CPUFREQ 2.6. INTERFACE                     *
index 23f7179bf74eb53d9def4ade7f1c2114d7b1017f..bd099ba82ccc5700353eb5c04a7ab967fb8b0482 100644 (file)
@@ -1,8 +1,8 @@
 #ifndef _LINUX_FTRACE_EVENT_H
 #define _LINUX_FTRACE_EVENT_H
 
-#include <linux/trace_seq.h>
 #include <linux/ring_buffer.h>
+#include <linux/trace_seq.h>
 #include <linux/percpu.h>
 
 struct trace_array;
@@ -34,7 +34,7 @@ struct trace_entry {
        unsigned char           flags;
        unsigned char           preempt_count;
        int                     pid;
-       int                     tgid;
+       int                     lock_depth;
 };
 
 #define FTRACE_MAX_EVENT                                               \
@@ -135,7 +135,7 @@ struct ftrace_event_call {
 };
 
 #define MAX_FILTER_PRED                32
-#define MAX_FILTER_STR_VAL     128
+#define MAX_FILTER_STR_VAL     256     /* Should handle KSYM_SYMBOL_LEN */
 
 extern void destroy_preds(struct ftrace_event_call *call);
 extern int filter_match_preds(struct ftrace_event_call *call, void *rec);
index 4759917adc71ae371da1cc3a45d46b22a55d4015..ff037f0b1b4e07a1ce5d9e5ca06efc8be147a00c 100644 (file)
@@ -91,7 +91,6 @@ enum hrtimer_restart {
  * @function:  timer expiry callback function
  * @base:      pointer to the timer base (per cpu and per clock)
  * @state:     state information (See bit values above)
- * @cb_entry:  list head to enqueue an expired timer into the callback list
  * @start_site:        timer statistics field to store the site where the timer
  *             was started
  * @start_comm: timer statistics field to store the name of the process which
@@ -108,7 +107,6 @@ struct hrtimer {
        enum hrtimer_restart            (*function)(struct hrtimer *);
        struct hrtimer_clock_base       *base;
        unsigned long                   state;
-       struct list_head                cb_entry;
 #ifdef CONFIG_TIMER_STATS
        int                             start_pid;
        void                            *start_site;
index 92fbd8cbd68fc87032a77b739b24d4f2d63f7084..fe158e0e20e6a5b7957d78925c9ed2a044f0f557 100644 (file)
@@ -233,6 +233,8 @@ extern void ip_mc_init_dev(struct in_device *);
 extern void ip_mc_destroy_dev(struct in_device *);
 extern void ip_mc_up(struct in_device *);
 extern void ip_mc_down(struct in_device *);
+extern void ip_mc_unmap(struct in_device *);
+extern void ip_mc_remap(struct in_device *);
 extern void ip_mc_dec_group(struct in_device *in_dev, __be32 addr);
 extern void ip_mc_inc_group(struct in_device *in_dev, __be32 addr);
 extern void ip_mc_rejoin_group(struct ip_mc_list *im);
index bcd9c07848bef0c4fa9eb8042add0ad59faeb374..3a46b7b7abb219c40bf39ce4d5f4e448da131212 100644 (file)
 #define KPROBE_HIT_SSDONE      0x00000008
 
 /* Attach to insert probes on any functions which should be ignored*/
-#define __kprobes      __attribute__((__section__(".kprobes.text"))) notrace
+#define __kprobes      __attribute__((__section__(".kprobes.text")))
 #else /* CONFIG_KPROBES */
 typedef int kprobe_opcode_t;
 struct arch_specific_insn {
        int dummy;
 };
-#define __kprobes      notrace
+#define __kprobes
 #endif /* CONFIG_KPROBES */
 
 struct kprobe;
index 4fc2ffd527f9386e613afe1e54a552268a491eb5..9040a10584f7fe0b11ae5012d42e3cf5bec9fcf2 100644 (file)
@@ -57,6 +57,7 @@ typedef enum {
 #include <linux/random.h>
 #include <linux/wait.h>
 #include <linux/fcntl.h>       /* For O_CLOEXEC and O_NONBLOCK */
+#include <linux/kmemcheck.h>
 
 struct poll_table_struct;
 struct pipe_inode_info;
@@ -127,7 +128,11 @@ enum sock_shutdown_cmd {
  */
 struct socket {
        socket_state            state;
+
+       kmemcheck_bitfield_begin(type);
        short                   type;
+       kmemcheck_bitfield_end(type);
+
        unsigned long           flags;
        /*
         * Please keep fasync_list & wait fields in the same cache line
index a9aa4b5917d792bc3d5e0a8d5e1cb9433ee19624..94958c109761287798f187e1c2bb96abf0b5693e 100644 (file)
@@ -1873,7 +1873,8 @@ extern void               __dev_addr_unsync(struct dev_addr_list **to, int *to_count, struct
 extern int             dev_set_promiscuity(struct net_device *dev, int inc);
 extern int             dev_set_allmulti(struct net_device *dev, int inc);
 extern void            netdev_state_change(struct net_device *dev);
-extern void            netdev_bonding_change(struct net_device *dev);
+extern void            netdev_bonding_change(struct net_device *dev,
+                                             unsigned long event);
 extern void            netdev_features_change(struct net_device *dev);
 /* Load a device via the kmod */
 extern void            dev_load(struct net *net, const char *name);
index 0fbecbbe8e9e950b39f0b45b916c960e39acd4c8..080f6ba9e73a35063a8b0b6ae8a797b6a9b107da 100644 (file)
@@ -176,12 +176,16 @@ struct netlink_skb_parms
 #define NETLINK_CREDS(skb)     (&NETLINK_CB((skb)).creds)
 
 
+extern void netlink_table_grab(void);
+extern void netlink_table_ungrab(void);
+
 extern struct sock *netlink_kernel_create(struct net *net,
                                          int unit,unsigned int groups,
                                          void (*input)(struct sk_buff *skb),
                                          struct mutex *cb_mutex,
                                          struct module *module);
 extern void netlink_kernel_release(struct sock *sk);
+extern int __netlink_change_ngroups(struct sock *sk, unsigned int groups);
 extern int netlink_change_ngroups(struct sock *sk, unsigned int groups);
 extern void netlink_clear_multicast_users(struct sock *sk, unsigned int group);
 extern void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err);
index 81bc252dc8ac35d9ed7fbe877308f52ae59eb623..44428d247dbe6e3b52e9b71798eff99735ae4319 100644 (file)
@@ -199,6 +199,8 @@ static inline int notifier_to_errno(int ret)
 #define NETDEV_FEAT_CHANGE     0x000B
 #define NETDEV_BONDING_FAILOVER 0x000C
 #define NETDEV_PRE_UP          0x000D
+#define NETDEV_BONDING_OLDTYPE  0x000E
+#define NETDEV_BONDING_NEWTYPE  0x000F
 
 #define SYS_DOWN       0x0001  /* Notify of system down */
 #define SYS_RESTART    SYS_DOWN
index 8975add8668fae419909ff830c6f1b7f02b71dd2..3b6b788fe2b532546f1ae77deae5dd49f8410cf6 100644 (file)
 #define PCI_DEVICE_ID_ARTOP_ATP860R    0x0007
 #define PCI_DEVICE_ID_ARTOP_ATP865     0x0008
 #define PCI_DEVICE_ID_ARTOP_ATP865R    0x0009
+#define PCI_DEVICE_ID_ARTOP_ATP867A    0x000A
+#define PCI_DEVICE_ID_ARTOP_ATP867B    0x000B
 #define PCI_DEVICE_ID_ARTOP_AEC7610    0x8002
 #define PCI_DEVICE_ID_ARTOP_AEC7612UW  0x8010
 #define PCI_DEVICE_ID_ARTOP_AEC7612U   0x8020
index f7b826b565c721bfbd823cc485bbfd41f787e332..a53915cd5581d7c7b9c21f334d3a01f093c0a1b4 100644 (file)
@@ -58,5 +58,12 @@ struct sockaddr_rxrpc {
 #define RXRPC_SECURITY_AUTH    1       /* authenticated packets */
 #define RXRPC_SECURITY_ENCRYPT 2       /* encrypted packets */
 
+/*
+ * RxRPC security indices
+ */
+#define RXRPC_SECURITY_NONE    0       /* no security protocol */
+#define RXRPC_SECURITY_RXKAD   2       /* kaserver or kerberos 4 */
+#define RXRPC_SECURITY_RXGK    4       /* gssapi-based */
+#define RXRPC_SECURITY_RXK5    5       /* kerberos 5 */
 
 #endif /* _LINUX_RXRPC_H */
index f3d74bd04d184955326430d6704741950f574aba..8af3d249170e07f2e03d131540a0bc7b0f00f962 100644 (file)
@@ -190,6 +190,7 @@ extern unsigned long long time_sync_thresh;
 /* in tsk->state again */
 #define TASK_DEAD              64
 #define TASK_WAKEKILL          128
+#define TASK_WAKING            256
 
 /* Convenience macros for the sake of set_task_state */
 #define TASK_KILLABLE          (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE)
@@ -802,14 +803,14 @@ enum cpu_idle_type {
 #define SD_BALANCE_NEWIDLE     0x0002  /* Balance when about to become idle */
 #define SD_BALANCE_EXEC                0x0004  /* Balance on exec */
 #define SD_BALANCE_FORK                0x0008  /* Balance on fork, clone */
-#define SD_WAKE_IDLE           0x0010  /* Wake to idle CPU on task wakeup */
+#define SD_BALANCE_WAKE                0x0010  /* Balance on wakeup */
 #define SD_WAKE_AFFINE         0x0020  /* Wake task to waking CPU */
-#define SD_WAKE_BALANCE                0x0040  /* Perform balancing at task wakeup */
+#define SD_PREFER_LOCAL                0x0040  /* Prefer to keep tasks local to this domain */
 #define SD_SHARE_CPUPOWER      0x0080  /* Domain members share cpu power */
 #define SD_POWERSAVINGS_BALANCE        0x0100  /* Balance for power savings */
 #define SD_SHARE_PKG_RESOURCES 0x0200  /* Domain members share cpu pkg resources */
 #define SD_SERIALIZE           0x0400  /* Only a single load balancing instance */
-#define SD_WAKE_IDLE_FAR       0x0800  /* Gain latency sacrificing cache hit */
+
 #define SD_PREFER_SIBLING      0x1000  /* Prefer to place tasks in a sibling domain */
 
 enum powersavings_balance_level {
@@ -991,6 +992,9 @@ static inline int test_sd_parent(struct sched_domain *sd, int flag)
        return 0;
 }
 
+unsigned long default_scale_freq_power(struct sched_domain *sd, int cpu);
+unsigned long default_scale_smt_power(struct sched_domain *sd, int cpu);
+
 #else /* CONFIG_SMP */
 
 struct sched_domain_attr;
@@ -1002,6 +1006,7 @@ partition_sched_domains(int ndoms_new, struct cpumask *doms_new,
 }
 #endif /* !CONFIG_SMP */
 
+
 struct io_context;                     /* See blkdev.h */
 
 
@@ -1019,6 +1024,12 @@ struct uts_namespace;
 struct rq;
 struct sched_domain;
 
+/*
+ * wake flags
+ */
+#define WF_SYNC                0x01            /* waker goes to sleep after wakup */
+#define WF_FORK                0x02            /* child wakeup after fork */
+
 struct sched_class {
        const struct sched_class *next;
 
@@ -1026,13 +1037,13 @@ struct sched_class {
        void (*dequeue_task) (struct rq *rq, struct task_struct *p, int sleep);
        void (*yield_task) (struct rq *rq);
 
-       void (*check_preempt_curr) (struct rq *rq, struct task_struct *p, int sync);
+       void (*check_preempt_curr) (struct rq *rq, struct task_struct *p, int flags);
 
        struct task_struct * (*pick_next_task) (struct rq *rq);
        void (*put_prev_task) (struct rq *rq, struct task_struct *p);
 
 #ifdef CONFIG_SMP
-       int  (*select_task_rq)(struct task_struct *p, int sync);
+       int  (*select_task_rq)(struct task_struct *p, int sd_flag, int flags);
 
        unsigned long (*load_balance) (struct rq *this_rq, int this_cpu,
                        struct rq *busiest, unsigned long max_load_move,
@@ -1102,6 +1113,8 @@ struct sched_entity {
        u64                     start_runtime;
        u64                     avg_wakeup;
 
+       u64                     avg_running;
+
 #ifdef CONFIG_SCHEDSTATS
        u64                     wait_start;
        u64                     wait_max;
index ea16c1a01d5188b3d9d39181d993d0c92508923b..56787c0933456c560bc98e860da4a989e8437f18 100644 (file)
@@ -75,7 +75,7 @@ extern unsigned long mktime(const unsigned int year, const unsigned int mon,
                            const unsigned int day, const unsigned int hour,
                            const unsigned int min, const unsigned int sec);
 
-extern void set_normalized_timespec(struct timespec *ts, time_t sec, long nsec);
+extern void set_normalized_timespec(struct timespec *ts, time_t sec, s64 nsec);
 extern struct timespec timespec_add_safe(const struct timespec lhs,
                                         const struct timespec rhs);
 
@@ -101,7 +101,8 @@ extern struct timespec xtime;
 extern struct timespec wall_to_monotonic;
 extern seqlock_t xtime_lock;
 
-extern unsigned long read_persistent_clock(void);
+extern void read_persistent_clock(struct timespec *ts);
+extern void read_boot_clock(struct timespec *ts);
 extern int update_persistent_clock(struct timespec now);
 extern int no_sync_cmos_clock __read_mostly;
 void timekeeping_init(void);
@@ -109,6 +110,8 @@ extern int timekeeping_suspended;
 
 unsigned long get_seconds(void);
 struct timespec current_kernel_time(void);
+struct timespec __current_kernel_time(void); /* does not hold xtime_lock */
+struct timespec get_monotonic_coarse(void);
 
 #define CURRENT_TIME           (current_kernel_time())
 #define CURRENT_TIME_SEC       ((struct timespec) { get_seconds(), 0 })
@@ -147,6 +150,7 @@ extern struct timespec timespec_trunc(struct timespec t, unsigned gran);
 extern int timekeeping_valid_for_hres(void);
 extern void update_wall_time(void);
 extern void update_xtime_cache(u64 nsec);
+extern void timekeeping_leap_insert(int leapsecond);
 
 struct tms;
 extern void do_sys_times(struct tms *);
@@ -241,6 +245,8 @@ struct itimerval {
 #define CLOCK_PROCESS_CPUTIME_ID       2
 #define CLOCK_THREAD_CPUTIME_ID                3
 #define CLOCK_MONOTONIC_RAW            4
+#define CLOCK_REALTIME_COARSE          5
+#define CLOCK_MONOTONIC_COARSE         6
 
 /*
  * The IDs of various hardware clocks:
index be62ec2ebea54fc0c9bd97f3b630882385fa2943..a2d1eb6cb3f087b92b9fa56584a30ba77ad7e145 100644 (file)
@@ -173,11 +173,6 @@ extern int mod_timer_pinned(struct timer_list *timer, unsigned long expires);
  */
 #define NEXT_TIMER_MAX_DELTA   ((1UL << 30) - 1)
 
-/*
- * Return when the next timer-wheel timeout occurs (in absolute jiffies),
- * locks the timer base:
- */
-extern unsigned long next_timer_interrupt(void);
 /*
  * Return when the next timer-wheel timeout occurs (in absolute jiffies),
  * locks the timer base and does the comparison against the given
index 85e8cf7d393c6e11bf509d73ca9b24bbfeef23bf..809b26c07090b11ea8966b4efd756e03aa7ef4cf 100644 (file)
@@ -95,14 +95,12 @@ int arch_update_cpu_topology(void);
                                | 1*SD_BALANCE_NEWIDLE                  \
                                | 1*SD_BALANCE_EXEC                     \
                                | 1*SD_BALANCE_FORK                     \
-                               | 0*SD_WAKE_IDLE                        \
+                               | 0*SD_BALANCE_WAKE                     \
                                | 1*SD_WAKE_AFFINE                      \
-                               | 1*SD_WAKE_BALANCE                     \
                                | 1*SD_SHARE_CPUPOWER                   \
                                | 0*SD_POWERSAVINGS_BALANCE             \
                                | 0*SD_SHARE_PKG_RESOURCES              \
                                | 0*SD_SERIALIZE                        \
-                               | 0*SD_WAKE_IDLE_FAR                    \
                                | 0*SD_PREFER_SIBLING                   \
                                ,                                       \
        .last_balance           = jiffies,                              \
@@ -122,20 +120,19 @@ int arch_update_cpu_topology(void);
        .imbalance_pct          = 125,                                  \
        .cache_nice_tries       = 1,                                    \
        .busy_idx               = 2,                                    \
-       .wake_idx               = 1,                                    \
-       .forkexec_idx           = 1,                                    \
+       .wake_idx               = 0,                                    \
+       .forkexec_idx           = 0,                                    \
                                                                        \
        .flags                  = 1*SD_LOAD_BALANCE                     \
                                | 1*SD_BALANCE_NEWIDLE                  \
                                | 1*SD_BALANCE_EXEC                     \
                                | 1*SD_BALANCE_FORK                     \
-                               | 1*SD_WAKE_IDLE                        \
+                               | 0*SD_BALANCE_WAKE                     \
                                | 1*SD_WAKE_AFFINE                      \
-                               | 1*SD_WAKE_BALANCE                     \
+                               | 1*SD_PREFER_LOCAL                     \
                                | 0*SD_SHARE_CPUPOWER                   \
                                | 1*SD_SHARE_PKG_RESOURCES              \
                                | 0*SD_SERIALIZE                        \
-                               | 0*SD_WAKE_IDLE_FAR                    \
                                | sd_balance_for_mc_power()             \
                                | sd_power_saving_flags()               \
                                ,                                       \
@@ -155,21 +152,20 @@ int arch_update_cpu_topology(void);
        .cache_nice_tries       = 1,                                    \
        .busy_idx               = 2,                                    \
        .idle_idx               = 1,                                    \
-       .newidle_idx            = 2,                                    \
-       .wake_idx               = 1,                                    \
-       .forkexec_idx           = 1,                                    \
+       .newidle_idx            = 0,                                    \
+       .wake_idx               = 0,                                    \
+       .forkexec_idx           = 0,                                    \
                                                                        \
        .flags                  = 1*SD_LOAD_BALANCE                     \
                                | 1*SD_BALANCE_NEWIDLE                  \
                                | 1*SD_BALANCE_EXEC                     \
                                | 1*SD_BALANCE_FORK                     \
-                               | 1*SD_WAKE_IDLE                        \
-                               | 0*SD_WAKE_AFFINE                      \
-                               | 1*SD_WAKE_BALANCE                     \
+                               | 0*SD_BALANCE_WAKE                     \
+                               | 1*SD_WAKE_AFFINE                      \
+                               | 1*SD_PREFER_LOCAL                     \
                                | 0*SD_SHARE_CPUPOWER                   \
                                | 0*SD_SHARE_PKG_RESOURCES              \
                                | 0*SD_SERIALIZE                        \
-                               | 0*SD_WAKE_IDLE_FAR                    \
                                | sd_balance_for_package_power()        \
                                | sd_power_saving_flags()               \
                                ,                                       \
@@ -191,14 +187,12 @@ int arch_update_cpu_topology(void);
                                | 1*SD_BALANCE_NEWIDLE                  \
                                | 0*SD_BALANCE_EXEC                     \
                                | 0*SD_BALANCE_FORK                     \
-                               | 0*SD_WAKE_IDLE                        \
-                               | 1*SD_WAKE_AFFINE                      \
-                               | 0*SD_WAKE_BALANCE                     \
+                               | 0*SD_BALANCE_WAKE                     \
+                               | 0*SD_WAKE_AFFINE                      \
                                | 0*SD_SHARE_CPUPOWER                   \
                                | 0*SD_POWERSAVINGS_BALANCE             \
                                | 0*SD_SHARE_PKG_RESOURCES              \
                                | 1*SD_SERIALIZE                        \
-                               | 1*SD_WAKE_IDLE_FAR                    \
                                | 0*SD_PREFER_SIBLING                   \
                                ,                                       \
        .last_balance           = jiffies,                              \
index c02128991ff7f8aaebb382cbbffaebe0f9f28d3a..7fc9746f22cd329065b1ae18f0ad3b9e46d9171f 100644 (file)
@@ -597,7 +597,7 @@ void uwb_rc_neh_grok(struct uwb_rc *, void *, size_t);
 void uwb_rc_neh_error(struct uwb_rc *, int);
 void uwb_rc_reset_all(struct uwb_rc *rc);
 void uwb_rc_pre_reset(struct uwb_rc *rc);
-void uwb_rc_post_reset(struct uwb_rc *rc);
+int uwb_rc_post_reset(struct uwb_rc *rc);
 
 /**
  * uwb_rsv_is_owner - is the owner of this reservation the RC?
index cf3c2f5dba51834215b137e5385b2654f220fc42..a48e16b77d5e2d94c1bb1bfb6b5efa56a82bd7af 100644 (file)
@@ -26,8 +26,8 @@
 #include <asm/current.h>
 
 typedef struct __wait_queue wait_queue_t;
-typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int sync, void *key);
-int default_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key);
+typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int flags, void *key);
+int default_wake_function(wait_queue_t *wait, unsigned mode, int flags, void *key);
 
 struct __wait_queue {
        unsigned int flags;
index 7b55ab215a649a3c62f6f860300198e0f1587e26..0f7c37825fc146ae6a8ceee0ce269af3b4ef65eb 100644 (file)
@@ -143,6 +143,8 @@ extern int __ipv6_dev_mc_dec(struct inet6_dev *idev, const struct in6_addr *addr
 extern int ipv6_dev_mc_dec(struct net_device *dev, const struct in6_addr *addr);
 extern void ipv6_mc_up(struct inet6_dev *idev);
 extern void ipv6_mc_down(struct inet6_dev *idev);
+extern void ipv6_mc_unmap(struct inet6_dev *idev);
+extern void ipv6_mc_remap(struct inet6_dev *idev);
 extern void ipv6_mc_init_dev(struct inet6_dev *idev);
 extern void ipv6_mc_destroy_dev(struct inet6_dev *idev);
 extern void addrconf_dad_failure(struct inet6_ifaddr *ifp);
index 1089d5aabd4990f8b028e6fb3c7db8f82195950d..60249e51b6691354f70e5ffe00137f39c7371a4e 100644 (file)
@@ -94,21 +94,20 @@ struct inet_protosw {
 #define INET_PROTOSW_PERMANENT 0x02  /* Permanent protocols are unremovable. */
 #define INET_PROTOSW_ICSK      0x04  /* Is this an inet_connection_sock? */
 
-extern struct net_protocol *inet_protocol_base;
-extern struct net_protocol *inet_protos[MAX_INET_PROTOS];
+extern const struct net_protocol *inet_protos[MAX_INET_PROTOS];
 
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-extern struct inet6_protocol *inet6_protos[MAX_INET_PROTOS];
+extern const struct inet6_protocol *inet6_protos[MAX_INET_PROTOS];
 #endif
 
-extern int     inet_add_protocol(struct net_protocol *prot, unsigned char num);
-extern int     inet_del_protocol(struct net_protocol *prot, unsigned char num);
+extern int     inet_add_protocol(const struct net_protocol *prot, unsigned char num);
+extern int     inet_del_protocol(const struct net_protocol *prot, unsigned char num);
 extern void    inet_register_protosw(struct inet_protosw *p);
 extern void    inet_unregister_protosw(struct inet_protosw *p);
 
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-extern int     inet6_add_protocol(struct inet6_protocol *prot, unsigned char num);
-extern int     inet6_del_protocol(struct inet6_protocol *prot, unsigned char num);
+extern int     inet6_add_protocol(const struct inet6_protocol *prot, unsigned char num);
+extern int     inet6_del_protocol(const struct inet6_protocol *prot, unsigned char num);
 extern int     inet6_register_protosw(struct inet_protosw *p);
 extern void    inet6_unregister_protosw(struct inet_protosw *p);
 #endif
index 88eb9de095de21006ed26fd84db96ca7f58c3b38..c33180dd42b4916e9cb6b73544b757b71755aecb 100644 (file)
@@ -81,7 +81,7 @@ struct Qdisc
 struct Qdisc_class_ops
 {
        /* Child qdisc manipulation */
-       unsigned int            (*select_queue)(struct Qdisc *, struct tcmsg *);
+       struct netdev_queue *   (*select_queue)(struct Qdisc *, struct tcmsg *);
        int                     (*graft)(struct Qdisc *, unsigned long cl,
                                        struct Qdisc *, struct Qdisc **);
        struct Qdisc *          (*leaf)(struct Qdisc *, unsigned long cl);
index b71a446d58f6c6a74b50ebb9d2ff5d1b8c55b13f..56b76027b85eeb4c7e4de930750e9584f6326489 100644 (file)
@@ -793,6 +793,13 @@ static inline unsigned int tcp_packets_in_flight(const struct tcp_sock *tp)
        return tp->packets_out - tcp_left_out(tp) + tp->retrans_out;
 }
 
+#define TCP_INFINITE_SSTHRESH  0x7fffffff
+
+static inline bool tcp_in_initial_slowstart(const struct tcp_sock *tp)
+{
+       return tp->snd_ssthresh >= TCP_INFINITE_SSTHRESH;
+}
+
 /* If cwnd > ssthresh, we may raise ssthresh to be half-way to cwnd.
  * The exception is rate halving phase, when cwnd is decreasing towards
  * ssthresh.
index 9a74b468a2291dd19e0ee3b8ad364943b3a8b4bb..d86af94691c2c4148711f29880187b0587409581 100644 (file)
@@ -171,6 +171,7 @@ TRACE_EVENT(block_rq_complete,
                  (unsigned long long)__entry->sector,
                  __entry->nr_sector, __entry->errors)
 );
+
 TRACE_EVENT(block_bio_bounce,
 
        TP_PROTO(struct request_queue *q, struct bio *bio),
@@ -186,7 +187,8 @@ TRACE_EVENT(block_bio_bounce,
        ),
 
        TP_fast_assign(
-               __entry->dev            = bio->bi_bdev->bd_dev;
+               __entry->dev            = bio->bi_bdev ?
+                                         bio->bi_bdev->bd_dev : 0;
                __entry->sector         = bio->bi_sector;
                __entry->nr_sector      = bio->bi_size >> 9;
                blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_size);
index 1cb0c3aa11e613659a0a87cc9c72ea4d14f69a3f..b89f9db4a404eaeb1800d2424eae5bd6e26387d4 100644 (file)
@@ -8,16 +8,17 @@
 #include <linux/interrupt.h>
 
 #define softirq_name(sirq) { sirq##_SOFTIRQ, #sirq }
-#define show_softirq_name(val)                 \
-       __print_symbolic(val,                   \
-                        softirq_name(HI),      \
-                        softirq_name(TIMER),   \
-                        softirq_name(NET_TX),  \
-                        softirq_name(NET_RX),  \
-                        softirq_name(BLOCK),   \
-                        softirq_name(TASKLET), \
-                        softirq_name(SCHED),   \
-                        softirq_name(HRTIMER), \
+#define show_softirq_name(val)                         \
+       __print_symbolic(val,                           \
+                        softirq_name(HI),              \
+                        softirq_name(TIMER),           \
+                        softirq_name(NET_TX),          \
+                        softirq_name(NET_RX),          \
+                        softirq_name(BLOCK),           \
+                        softirq_name(BLOCK_IOPOLL),    \
+                        softirq_name(TASKLET),         \
+                        softirq_name(SCHED),           \
+                        softirq_name(HRTIMER),         \
                         softirq_name(RCU))
 
 /**
index 308bafd93325c992bb43bab91726aacefd91db3c..72a3b437b8299eef59a0a30cfca73ab84d431d61 100644 (file)
@@ -239,9 +239,9 @@ ftrace_format_##call(struct ftrace_event_call *unused,                      \
 #undef __print_flags
 #define __print_flags(flag, delim, flag_array...)                      \
        ({                                                              \
-               static const struct trace_print_flags flags[] =         \
+               static const struct trace_print_flags __flags[] =       \
                        { flag_array, { -1, NULL }};                    \
-               ftrace_print_flags_seq(p, delim, flag, flags);          \
+               ftrace_print_flags_seq(p, delim, flag, __flags);        \
        })
 
 #undef __print_symbolic
@@ -254,7 +254,7 @@ ftrace_format_##call(struct ftrace_event_call *unused,                      \
 
 #undef TRACE_EVENT
 #define TRACE_EVENT(call, proto, args, tstruct, assign, print)         \
-enum print_line_t                                                      \
+static enum print_line_t                                               \
 ftrace_raw_output_##call(struct trace_iterator *iter, int flags)       \
 {                                                                      \
        struct trace_seq *s = &iter->seq;                               \
@@ -317,7 +317,7 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags)    \
 
 #undef TRACE_EVENT
 #define TRACE_EVENT(call, proto, args, tstruct, func, print)           \
-int                                                                    \
+static int                                                             \
 ftrace_define_fields_##call(struct ftrace_event_call *event_call)      \
 {                                                                      \
        struct ftrace_raw_##call field;                                 \
index 05071bf6a37b7848561d9a386141d4cefd1a4de9..c03f221fee44c1d8271066a4bcae76c4a211b242 100644 (file)
 
 #include <asm/uaccess.h>
 
-/**
- * ktime_get - get the monotonic time in ktime_t format
- *
- * returns the time in ktime_t format
- */
-ktime_t ktime_get(void)
-{
-       struct timespec now;
-
-       ktime_get_ts(&now);
-
-       return timespec_to_ktime(now);
-}
-EXPORT_SYMBOL_GPL(ktime_get);
-
-/**
- * ktime_get_real - get the real (wall-) time in ktime_t format
- *
- * returns the time in ktime_t format
- */
-ktime_t ktime_get_real(void)
-{
-       struct timespec now;
-
-       getnstimeofday(&now);
-
-       return timespec_to_ktime(now);
-}
-
-EXPORT_SYMBOL_GPL(ktime_get_real);
-
 /*
  * The timer bases:
  *
@@ -106,31 +75,6 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) =
        }
 };
 
-/**
- * ktime_get_ts - get the monotonic clock in timespec format
- * @ts:                pointer to timespec variable
- *
- * The function calculates the monotonic clock from the realtime
- * clock and the wall_to_monotonic offset and stores the result
- * in normalized timespec format in the variable pointed to by @ts.
- */
-void ktime_get_ts(struct timespec *ts)
-{
-       struct timespec tomono;
-       unsigned long seq;
-
-       do {
-               seq = read_seqbegin(&xtime_lock);
-               getnstimeofday(ts);
-               tomono = wall_to_monotonic;
-
-       } while (read_seqretry(&xtime_lock, seq));
-
-       set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec,
-                               ts->tv_nsec + tomono.tv_nsec);
-}
-EXPORT_SYMBOL_GPL(ktime_get_ts);
-
 /*
  * Get the coarse grained time at the softirq based on xtime and
  * wall_to_monotonic.
@@ -1155,7 +1099,6 @@ static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id,
                clock_id = CLOCK_MONOTONIC;
 
        timer->base = &cpu_base->clock_base[clock_id];
-       INIT_LIST_HEAD(&timer->cb_entry);
        hrtimer_init_timer_hres(timer);
 
 #ifdef CONFIG_TIMER_STATS
index d089d052c4a90f18bb908724e93806f86d0e11aa..495440779ce3b91c9927b98c61a83922b8578a31 100644 (file)
@@ -242,6 +242,25 @@ static int posix_get_monotonic_raw(clockid_t which_clock, struct timespec *tp)
        return 0;
 }
 
+
+static int posix_get_realtime_coarse(clockid_t which_clock, struct timespec *tp)
+{
+       *tp = current_kernel_time();
+       return 0;
+}
+
+static int posix_get_monotonic_coarse(clockid_t which_clock,
+                                               struct timespec *tp)
+{
+       *tp = get_monotonic_coarse();
+       return 0;
+}
+
+int posix_get_coarse_res(const clockid_t which_clock, struct timespec *tp)
+{
+       *tp = ktime_to_timespec(KTIME_LOW_RES);
+       return 0;
+}
 /*
  * Initialize everything, well, just everything in Posix clocks/timers ;)
  */
@@ -262,10 +281,26 @@ static __init int init_posix_timers(void)
                .timer_create = no_timer_create,
                .nsleep = no_nsleep,
        };
+       struct k_clock clock_realtime_coarse = {
+               .clock_getres = posix_get_coarse_res,
+               .clock_get = posix_get_realtime_coarse,
+               .clock_set = do_posix_clock_nosettime,
+               .timer_create = no_timer_create,
+               .nsleep = no_nsleep,
+       };
+       struct k_clock clock_monotonic_coarse = {
+               .clock_getres = posix_get_coarse_res,
+               .clock_get = posix_get_monotonic_coarse,
+               .clock_set = do_posix_clock_nosettime,
+               .timer_create = no_timer_create,
+               .nsleep = no_nsleep,
+       };
 
        register_posix_clock(CLOCK_REALTIME, &clock_realtime);
        register_posix_clock(CLOCK_MONOTONIC, &clock_monotonic);
        register_posix_clock(CLOCK_MONOTONIC_RAW, &clock_monotonic_raw);
+       register_posix_clock(CLOCK_REALTIME_COARSE, &clock_realtime_coarse);
+       register_posix_clock(CLOCK_MONOTONIC_COARSE, &clock_monotonic_coarse);
 
        posix_timers_cache = kmem_cache_create("posix_timers_cache",
                                        sizeof (struct k_itimer), 0, SLAB_PANIC,
index d9db3fb17573b8aaf8449ade1d168eb20f9ba4f6..faf4d463bbffb9a561beed93bd59282ea7c7092e 100644 (file)
  */
 #define RUNTIME_INF    ((u64)~0ULL)
 
-static void double_rq_lock(struct rq *rq1, struct rq *rq2);
-
 static inline int rt_policy(int policy)
 {
        if (unlikely(policy == SCHED_FIFO || policy == SCHED_RR))
@@ -378,13 +376,6 @@ static inline void set_task_rq(struct task_struct *p, unsigned int cpu)
 
 #else
 
-#ifdef CONFIG_SMP
-static int root_task_group_empty(void)
-{
-       return 1;
-}
-#endif
-
 static inline void set_task_rq(struct task_struct *p, unsigned int cpu) { }
 static inline struct task_group *task_group(struct task_struct *p)
 {
@@ -514,14 +505,6 @@ struct root_domain {
 #ifdef CONFIG_SMP
        struct cpupri cpupri;
 #endif
-#if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
-       /*
-        * Preferred wake up cpu nominated by sched_mc balance that will be
-        * used when most cpus are idle in the system indicating overall very
-        * low system utilisation. Triggered at POWERSAVINGS_BALANCE_WAKEUP(2)
-        */
-       unsigned int sched_mc_preferred_wakeup_cpu;
-#endif
 };
 
 /*
@@ -646,9 +629,10 @@ struct rq {
 
 static DEFINE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues);
 
-static inline void check_preempt_curr(struct rq *rq, struct task_struct *p, int sync)
+static inline
+void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags)
 {
-       rq->curr->sched_class->check_preempt_curr(rq, p, sync);
+       rq->curr->sched_class->check_preempt_curr(rq, p, flags);
 }
 
 static inline int cpu_of(struct rq *rq)
@@ -1509,8 +1493,65 @@ static int tg_nop(struct task_group *tg, void *data)
 #endif
 
 #ifdef CONFIG_SMP
-static unsigned long source_load(int cpu, int type);
-static unsigned long target_load(int cpu, int type);
+/* Used instead of source_load when we know the type == 0 */
+static unsigned long weighted_cpuload(const int cpu)
+{
+       return cpu_rq(cpu)->load.weight;
+}
+
+/*
+ * Return a low guess at the load of a migration-source cpu weighted
+ * according to the scheduling class and "nice" value.
+ *
+ * We want to under-estimate the load of migration sources, to
+ * balance conservatively.
+ */
+static unsigned long source_load(int cpu, int type)
+{
+       struct rq *rq = cpu_rq(cpu);
+       unsigned long total = weighted_cpuload(cpu);
+
+       if (type == 0 || !sched_feat(LB_BIAS))
+               return total;
+
+       return min(rq->cpu_load[type-1], total);
+}
+
+/*
+ * Return a high guess at the load of a migration-target cpu weighted
+ * according to the scheduling class and "nice" value.
+ */
+static unsigned long target_load(int cpu, int type)
+{
+       struct rq *rq = cpu_rq(cpu);
+       unsigned long total = weighted_cpuload(cpu);
+
+       if (type == 0 || !sched_feat(LB_BIAS))
+               return total;
+
+       return max(rq->cpu_load[type-1], total);
+}
+
+static struct sched_group *group_of(int cpu)
+{
+       struct sched_domain *sd = rcu_dereference(cpu_rq(cpu)->sd);
+
+       if (!sd)
+               return NULL;
+
+       return sd->groups;
+}
+
+static unsigned long power_of(int cpu)
+{
+       struct sched_group *group = group_of(cpu);
+
+       if (!group)
+               return SCHED_LOAD_SCALE;
+
+       return group->cpu_power;
+}
+
 static int task_hot(struct task_struct *p, u64 now, struct sched_domain *sd);
 
 static unsigned long cpu_avg_load_per_task(int cpu)
@@ -1695,6 +1736,8 @@ static inline void update_shares_locked(struct rq *rq, struct sched_domain *sd)
 
 #ifdef CONFIG_PREEMPT
 
+static void double_rq_lock(struct rq *rq1, struct rq *rq2);
+
 /*
  * fair double_lock_balance: Safely acquires both rq->locks in a fair
  * way at the expense of forcing extra atomic operations in all
@@ -1959,13 +2002,6 @@ static inline void check_class_changed(struct rq *rq, struct task_struct *p,
 }
 
 #ifdef CONFIG_SMP
-
-/* Used instead of source_load when we know the type == 0 */
-static unsigned long weighted_cpuload(const int cpu)
-{
-       return cpu_rq(cpu)->load.weight;
-}
-
 /*
  * Is this task likely cache-hot:
  */
@@ -2239,185 +2275,6 @@ void kick_process(struct task_struct *p)
        preempt_enable();
 }
 EXPORT_SYMBOL_GPL(kick_process);
-
-/*
- * Return a low guess at the load of a migration-source cpu weighted
- * according to the scheduling class and "nice" value.
- *
- * We want to under-estimate the load of migration sources, to
- * balance conservatively.
- */
-static unsigned long source_load(int cpu, int type)
-{
-       struct rq *rq = cpu_rq(cpu);
-       unsigned long total = weighted_cpuload(cpu);
-
-       if (type == 0 || !sched_feat(LB_BIAS))
-               return total;
-
-       return min(rq->cpu_load[type-1], total);
-}
-
-/*
- * Return a high guess at the load of a migration-target cpu weighted
- * according to the scheduling class and "nice" value.
- */
-static unsigned long target_load(int cpu, int type)
-{
-       struct rq *rq = cpu_rq(cpu);
-       unsigned long total = weighted_cpuload(cpu);
-
-       if (type == 0 || !sched_feat(LB_BIAS))
-               return total;
-
-       return max(rq->cpu_load[type-1], total);
-}
-
-/*
- * find_idlest_group finds and returns the least busy CPU group within the
- * domain.
- */
-static struct sched_group *
-find_idlest_group(struct sched_domain *sd, struct task_struct *p, int this_cpu)
-{
-       struct sched_group *idlest = NULL, *this = NULL, *group = sd->groups;
-       unsigned long min_load = ULONG_MAX, this_load = 0;
-       int load_idx = sd->forkexec_idx;
-       int imbalance = 100 + (sd->imbalance_pct-100)/2;
-
-       do {
-               unsigned long load, avg_load;
-               int local_group;
-               int i;
-
-               /* Skip over this group if it has no CPUs allowed */
-               if (!cpumask_intersects(sched_group_cpus(group),
-                                       &p->cpus_allowed))
-                       continue;
-
-               local_group = cpumask_test_cpu(this_cpu,
-                                              sched_group_cpus(group));
-
-               /* Tally up the load of all CPUs in the group */
-               avg_load = 0;
-
-               for_each_cpu(i, sched_group_cpus(group)) {
-                       /* Bias balancing toward cpus of our domain */
-                       if (local_group)
-                               load = source_load(i, load_idx);
-                       else
-                               load = target_load(i, load_idx);
-
-                       avg_load += load;
-               }
-
-               /* Adjust by relative CPU power of the group */
-               avg_load = (avg_load * SCHED_LOAD_SCALE) / group->cpu_power;
-
-               if (local_group) {
-                       this_load = avg_load;
-                       this = group;
-               } else if (avg_load < min_load) {
-                       min_load = avg_load;
-                       idlest = group;
-               }
-       } while (group = group->next, group != sd->groups);
-
-       if (!idlest || 100*this_load < imbalance*min_load)
-               return NULL;
-       return idlest;
-}
-
-/*
- * find_idlest_cpu - find the idlest cpu among the cpus in group.
- */
-static int
-find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu)
-{
-       unsigned long load, min_load = ULONG_MAX;
-       int idlest = -1;
-       int i;
-
-       /* Traverse only the allowed CPUs */
-       for_each_cpu_and(i, sched_group_cpus(group), &p->cpus_allowed) {
-               load = weighted_cpuload(i);
-
-               if (load < min_load || (load == min_load && i == this_cpu)) {
-                       min_load = load;
-                       idlest = i;
-               }
-       }
-
-       return idlest;
-}
-
-/*
- * sched_balance_self: balance the current task (running on cpu) in domains
- * that have the 'flag' flag set. In practice, this is SD_BALANCE_FORK and
- * SD_BALANCE_EXEC.
- *
- * Balance, ie. select the least loaded group.
- *
- * Returns the target CPU number, or the same CPU if no balancing is needed.
- *
- * preempt must be disabled.
- */
-static int sched_balance_self(int cpu, int flag)
-{
-       struct task_struct *t = current;
-       struct sched_domain *tmp, *sd = NULL;
-
-       for_each_domain(cpu, tmp) {
-               /*
-                * If power savings logic is enabled for a domain, stop there.
-                */
-               if (tmp->flags & SD_POWERSAVINGS_BALANCE)
-                       break;
-               if (tmp->flags & flag)
-                       sd = tmp;
-       }
-
-       if (sd)
-               update_shares(sd);
-
-       while (sd) {
-               struct sched_group *group;
-               int new_cpu, weight;
-
-               if (!(sd->flags & flag)) {
-                       sd = sd->child;
-                       continue;
-               }
-
-               group = find_idlest_group(sd, t, cpu);
-               if (!group) {
-                       sd = sd->child;
-                       continue;
-               }
-
-               new_cpu = find_idlest_cpu(group, t, cpu);
-               if (new_cpu == -1 || new_cpu == cpu) {
-                       /* Now try balancing at a lower domain level of cpu */
-                       sd = sd->child;
-                       continue;
-               }
-
-               /* Now try balancing at a lower domain level of new_cpu */
-               cpu = new_cpu;
-               weight = cpumask_weight(sched_domain_span(sd));
-               sd = NULL;
-               for_each_domain(cpu, tmp) {
-                       if (weight <= cpumask_weight(sched_domain_span(tmp)))
-                               break;
-                       if (tmp->flags & flag)
-                               sd = tmp;
-               }
-               /* while loop will break here if sd == NULL */
-       }
-
-       return cpu;
-}
-
 #endif /* CONFIG_SMP */
 
 /**
@@ -2455,37 +2312,22 @@ void task_oncpu_function_call(struct task_struct *p,
  *
  * returns failure only if the task is already active.
  */
-static int try_to_wake_up(struct task_struct *p, unsigned int state, int sync)
+static int try_to_wake_up(struct task_struct *p, unsigned int state,
+                         int wake_flags)
 {
        int cpu, orig_cpu, this_cpu, success = 0;
        unsigned long flags;
-       long old_state;
        struct rq *rq;
 
        if (!sched_feat(SYNC_WAKEUPS))
-               sync = 0;
-
-#ifdef CONFIG_SMP
-       if (sched_feat(LB_WAKEUP_UPDATE) && !root_task_group_empty()) {
-               struct sched_domain *sd;
+               wake_flags &= ~WF_SYNC;
 
-               this_cpu = raw_smp_processor_id();
-               cpu = task_cpu(p);
-
-               for_each_domain(this_cpu, sd) {
-                       if (cpumask_test_cpu(cpu, sched_domain_span(sd))) {
-                               update_shares(sd);
-                               break;
-                       }
-               }
-       }
-#endif
+       this_cpu = get_cpu();
 
        smp_wmb();
        rq = task_rq_lock(p, &flags);
        update_rq_clock(rq);
-       old_state = p->state;
-       if (!(old_state & state))
+       if (!(p->state & state))
                goto out;
 
        if (p->se.on_rq)
@@ -2493,27 +2335,29 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, int sync)
 
        cpu = task_cpu(p);
        orig_cpu = cpu;
-       this_cpu = smp_processor_id();
 
 #ifdef CONFIG_SMP
        if (unlikely(task_running(rq, p)))
                goto out_activate;
 
-       cpu = p->sched_class->select_task_rq(p, sync);
-       if (cpu != orig_cpu) {
+       /*
+        * In order to handle concurrent wakeups and release the rq->lock
+        * we put the task in TASK_WAKING state.
+        *
+        * First fix up the nr_uninterruptible count:
+        */
+       if (task_contributes_to_load(p))
+               rq->nr_uninterruptible--;
+       p->state = TASK_WAKING;
+       task_rq_unlock(rq, &flags);
+
+       cpu = p->sched_class->select_task_rq(p, SD_BALANCE_WAKE, wake_flags);
+       if (cpu != orig_cpu)
                set_task_cpu(p, cpu);
-               task_rq_unlock(rq, &flags);
-               /* might preempt at this point */
-               rq = task_rq_lock(p, &flags);
-               old_state = p->state;
-               if (!(old_state & state))
-                       goto out;
-               if (p->se.on_rq)
-                       goto out_running;
 
-               this_cpu = smp_processor_id();
-               cpu = task_cpu(p);
-       }
+       rq = task_rq_lock(p, &flags);
+       WARN_ON(p->state != TASK_WAKING);
+       cpu = task_cpu(p);
 
 #ifdef CONFIG_SCHEDSTATS
        schedstat_inc(rq, ttwu_count);
@@ -2533,7 +2377,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, int sync)
 out_activate:
 #endif /* CONFIG_SMP */
        schedstat_inc(p, se.nr_wakeups);
-       if (sync)
+       if (wake_flags & WF_SYNC)
                schedstat_inc(p, se.nr_wakeups_sync);
        if (orig_cpu != cpu)
                schedstat_inc(p, se.nr_wakeups_migrate);
@@ -2562,7 +2406,7 @@ out_activate:
 
 out_running:
        trace_sched_wakeup(rq, p, success);
-       check_preempt_curr(rq, p, sync);
+       check_preempt_curr(rq, p, wake_flags);
 
        p->state = TASK_RUNNING;
 #ifdef CONFIG_SMP
@@ -2571,6 +2415,7 @@ out_running:
 #endif
 out:
        task_rq_unlock(rq, &flags);
+       put_cpu();
 
        return success;
 }
@@ -2613,6 +2458,7 @@ static void __sched_fork(struct task_struct *p)
        p->se.avg_overlap               = 0;
        p->se.start_runtime             = 0;
        p->se.avg_wakeup                = sysctl_sched_wakeup_granularity;
+       p->se.avg_running               = 0;
 
 #ifdef CONFIG_SCHEDSTATS
        p->se.wait_start                        = 0;
@@ -2674,11 +2520,6 @@ void sched_fork(struct task_struct *p, int clone_flags)
 
        __sched_fork(p);
 
-#ifdef CONFIG_SMP
-       cpu = sched_balance_self(cpu, SD_BALANCE_FORK);
-#endif
-       set_task_cpu(p, cpu);
-
        /*
         * Make sure we do not leak PI boosting priority to the child.
         */
@@ -2709,6 +2550,11 @@ void sched_fork(struct task_struct *p, int clone_flags)
        if (!rt_prio(p->prio))
                p->sched_class = &fair_sched_class;
 
+#ifdef CONFIG_SMP
+       cpu = p->sched_class->select_task_rq(p, SD_BALANCE_FORK, 0);
+#endif
+       set_task_cpu(p, cpu);
+
 #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
        if (likely(sched_info_on()))
                memset(&p->sched_info, 0, sizeof(p->sched_info));
@@ -2754,7 +2600,7 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags)
                inc_nr_running(rq);
        }
        trace_sched_wakeup_new(rq, p, 1);
-       check_preempt_curr(rq, p, 0);
+       check_preempt_curr(rq, p, WF_FORK);
 #ifdef CONFIG_SMP
        if (p->sched_class->task_wake_up)
                p->sched_class->task_wake_up(rq, p);
@@ -3263,7 +3109,7 @@ out:
 void sched_exec(void)
 {
        int new_cpu, this_cpu = get_cpu();
-       new_cpu = sched_balance_self(this_cpu, SD_BALANCE_EXEC);
+       new_cpu = current->sched_class->select_task_rq(current, SD_BALANCE_EXEC, 0);
        put_cpu();
        if (new_cpu != this_cpu)
                sched_migrate_task(current, new_cpu);
@@ -3683,11 +3529,6 @@ static inline int check_power_save_busiest_group(struct sd_lb_stats *sds,
        *imbalance = sds->min_load_per_task;
        sds->busiest = sds->group_min;
 
-       if (sched_mc_power_savings >= POWERSAVINGS_BALANCE_WAKEUP) {
-               cpu_rq(this_cpu)->rd->sched_mc_preferred_wakeup_cpu =
-                       group_first_cpu(sds->group_leader);
-       }
-
        return 1;
 
 }
@@ -3711,7 +3552,18 @@ static inline int check_power_save_busiest_group(struct sd_lb_stats *sds,
 }
 #endif /* CONFIG_SCHED_MC || CONFIG_SCHED_SMT */
 
-unsigned long __weak arch_scale_smt_power(struct sched_domain *sd, int cpu)
+
+unsigned long default_scale_freq_power(struct sched_domain *sd, int cpu)
+{
+       return SCHED_LOAD_SCALE;
+}
+
+unsigned long __weak arch_scale_freq_power(struct sched_domain *sd, int cpu)
+{
+       return default_scale_freq_power(sd, cpu);
+}
+
+unsigned long default_scale_smt_power(struct sched_domain *sd, int cpu)
 {
        unsigned long weight = cpumask_weight(sched_domain_span(sd));
        unsigned long smt_gain = sd->smt_gain;
@@ -3721,6 +3573,11 @@ unsigned long __weak arch_scale_smt_power(struct sched_domain *sd, int cpu)
        return smt_gain;
 }
 
+unsigned long __weak arch_scale_smt_power(struct sched_domain *sd, int cpu)
+{
+       return default_scale_smt_power(sd, cpu);
+}
+
 unsigned long scale_rt_power(int cpu)
 {
        struct rq *rq = cpu_rq(cpu);
@@ -3745,10 +3602,19 @@ static void update_cpu_power(struct sched_domain *sd, int cpu)
        unsigned long power = SCHED_LOAD_SCALE;
        struct sched_group *sdg = sd->groups;
 
-       /* here we could scale based on cpufreq */
+       if (sched_feat(ARCH_POWER))
+               power *= arch_scale_freq_power(sd, cpu);
+       else
+               power *= default_scale_freq_power(sd, cpu);
+
+       power >>= SCHED_LOAD_SHIFT;
 
        if ((sd->flags & SD_SHARE_CPUPOWER) && weight > 1) {
-               power *= arch_scale_smt_power(sd, cpu);
+               if (sched_feat(ARCH_POWER))
+                       power *= arch_scale_smt_power(sd, cpu);
+               else
+                       power *= default_scale_smt_power(sd, cpu);
+
                power >>= SCHED_LOAD_SHIFT;
        }
 
@@ -4161,26 +4027,6 @@ ret:
        return NULL;
 }
 
-static struct sched_group *group_of(int cpu)
-{
-       struct sched_domain *sd = rcu_dereference(cpu_rq(cpu)->sd);
-
-       if (!sd)
-               return NULL;
-
-       return sd->groups;
-}
-
-static unsigned long power_of(int cpu)
-{
-       struct sched_group *group = group_of(cpu);
-
-       if (!group)
-               return SCHED_LOAD_SCALE;
-
-       return group->cpu_power;
-}
-
 /*
  * find_busiest_queue - find the busiest runqueue among the cpus in group.
  */
@@ -5465,14 +5311,13 @@ static inline void schedule_debug(struct task_struct *prev)
 #endif
 }
 
-static void put_prev_task(struct rq *rq, struct task_struct *prev)
+static void put_prev_task(struct rq *rq, struct task_struct *p)
 {
-       if (prev->state == TASK_RUNNING) {
-               u64 runtime = prev->se.sum_exec_runtime;
+       u64 runtime = p->se.sum_exec_runtime - p->se.prev_sum_exec_runtime;
 
-               runtime -= prev->se.prev_sum_exec_runtime;
-               runtime = min_t(u64, runtime, 2*sysctl_sched_migration_cost);
+       update_avg(&p->se.avg_running, runtime);
 
+       if (p->state == TASK_RUNNING) {
                /*
                 * In order to avoid avg_overlap growing stale when we are
                 * indeed overlapping and hence not getting put to sleep, grow
@@ -5482,9 +5327,12 @@ static void put_prev_task(struct rq *rq, struct task_struct *prev)
                 * correlates to the amount of cache footprint a task can
                 * build up.
                 */
-               update_avg(&prev->se.avg_overlap, runtime);
+               runtime = min_t(u64, runtime, 2*sysctl_sched_migration_cost);
+               update_avg(&p->se.avg_overlap, runtime);
+       } else {
+               update_avg(&p->se.avg_running, 0);
        }
-       prev->sched_class->put_prev_task(rq, prev);
+       p->sched_class->put_prev_task(rq, p);
 }
 
 /*
@@ -5716,10 +5564,10 @@ asmlinkage void __sched preempt_schedule_irq(void)
 
 #endif /* CONFIG_PREEMPT */
 
-int default_wake_function(wait_queue_t *curr, unsigned mode, int sync,
+int default_wake_function(wait_queue_t *curr, unsigned mode, int wake_flags,
                          void *key)
 {
-       return try_to_wake_up(curr->private, mode, sync);
+       return try_to_wake_up(curr->private, mode, wake_flags);
 }
 EXPORT_SYMBOL(default_wake_function);
 
@@ -5733,14 +5581,14 @@ EXPORT_SYMBOL(default_wake_function);
  * zero in this (rare) case, and we handle it by continuing to scan the queue.
  */
 static void __wake_up_common(wait_queue_head_t *q, unsigned int mode,
-                       int nr_exclusive, int sync, void *key)
+                       int nr_exclusive, int wake_flags, void *key)
 {
        wait_queue_t *curr, *next;
 
        list_for_each_entry_safe(curr, next, &q->task_list, task_list) {
                unsigned flags = curr->flags;
 
-               if (curr->func(curr, mode, sync, key) &&
+               if (curr->func(curr, mode, wake_flags, key) &&
                                (flags & WQ_FLAG_EXCLUSIVE) && !--nr_exclusive)
                        break;
        }
@@ -5801,16 +5649,16 @@ void __wake_up_sync_key(wait_queue_head_t *q, unsigned int mode,
                        int nr_exclusive, void *key)
 {
        unsigned long flags;
-       int sync = 1;
+       int wake_flags = WF_SYNC;
 
        if (unlikely(!q))
                return;
 
        if (unlikely(!nr_exclusive))
-               sync = 0;
+               wake_flags = 0;
 
        spin_lock_irqsave(&q->lock, flags);
-       __wake_up_common(q, mode, nr_exclusive, sync, key);
+       __wake_up_common(q, mode, nr_exclusive, wake_flags, key);
        spin_unlock_irqrestore(&q->lock, flags);
 }
 EXPORT_SYMBOL_GPL(__wake_up_sync_key);
@@ -8000,9 +7848,7 @@ static int sd_degenerate(struct sched_domain *sd)
        }
 
        /* Following flags don't use groups */
-       if (sd->flags & (SD_WAKE_IDLE |
-                        SD_WAKE_AFFINE |
-                        SD_WAKE_BALANCE))
+       if (sd->flags & (SD_WAKE_AFFINE))
                return 0;
 
        return 1;
@@ -8019,10 +7865,6 @@ sd_parent_degenerate(struct sched_domain *sd, struct sched_domain *parent)
        if (!cpumask_equal(sched_domain_span(sd), sched_domain_span(parent)))
                return 0;
 
-       /* Does parent contain flags not in child? */
-       /* WAKE_BALANCE is a subset of WAKE_AFFINE */
-       if (cflags & SD_WAKE_AFFINE)
-               pflags &= ~SD_WAKE_BALANCE;
        /* Flags needing groups don't count if only 1 group in parent */
        if (parent->groups == parent->groups->next) {
                pflags &= ~(SD_LOAD_BALANCE |
@@ -8708,10 +8550,10 @@ static void set_domain_attribute(struct sched_domain *sd,
                request = attr->relax_domain_level;
        if (request < sd->level) {
                /* turn off idle balance on this domain */
-               sd->flags &= ~(SD_WAKE_IDLE|SD_BALANCE_NEWIDLE);
+               sd->flags &= ~(SD_BALANCE_WAKE|SD_BALANCE_NEWIDLE);
        } else {
                /* turn on idle balance on this domain */
-               sd->flags |= (SD_WAKE_IDLE_FAR|SD_BALANCE_NEWIDLE);
+               sd->flags |= (SD_BALANCE_WAKE|SD_BALANCE_NEWIDLE);
        }
 }
 
index 5ddbd08912678dad0a20711657f182e299faa032..efb84409bc435dc3422eeb2cc820eb773855eb4d 100644 (file)
@@ -395,6 +395,7 @@ void proc_sched_show_task(struct task_struct *p, struct seq_file *m)
        PN(se.sum_exec_runtime);
        PN(se.avg_overlap);
        PN(se.avg_wakeup);
+       PN(se.avg_running);
 
        nr_switches = p->nvcsw + p->nivcsw;
 
index aa7f8412101658fc27e1487ded677acf695ac4d1..10d218ab69f2ba4eac39a2d07461c0b2b256de34 100644 (file)
@@ -711,7 +711,7 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)
 
        if (!initial) {
                /* sleeps upto a single latency don't count. */
-               if (sched_feat(NEW_FAIR_SLEEPERS)) {
+               if (sched_feat(FAIR_SLEEPERS)) {
                        unsigned long thresh = sysctl_sched_latency;
 
                        /*
@@ -725,6 +725,13 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)
                                         task_of(se)->policy != SCHED_IDLE))
                                thresh = calc_delta_fair(thresh, se);
 
+                       /*
+                        * Halve their sleep time's effect, to allow
+                        * for a gentler effect of sleepers:
+                        */
+                       if (sched_feat(GENTLE_FAIR_SLEEPERS))
+                               thresh >>= 1;
+
                        vruntime -= thresh;
                }
        }
@@ -757,10 +764,10 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int wakeup)
 
 static void __clear_buddies(struct cfs_rq *cfs_rq, struct sched_entity *se)
 {
-       if (cfs_rq->last == se)
+       if (!se || cfs_rq->last == se)
                cfs_rq->last = NULL;
 
-       if (cfs_rq->next == se)
+       if (!se || cfs_rq->next == se)
                cfs_rq->next = NULL;
 }
 
@@ -1062,83 +1069,6 @@ static void yield_task_fair(struct rq *rq)
        se->vruntime = rightmost->vruntime + 1;
 }
 
-/*
- * wake_idle() will wake a task on an idle cpu if task->cpu is
- * not idle and an idle cpu is available.  The span of cpus to
- * search starts with cpus closest then further out as needed,
- * so we always favor a closer, idle cpu.
- * Domains may include CPUs that are not usable for migration,
- * hence we need to mask them out (rq->rd->online)
- *
- * Returns the CPU we should wake onto.
- */
-#if defined(ARCH_HAS_SCHED_WAKE_IDLE)
-
-#define cpu_rd_active(cpu, rq) cpumask_test_cpu(cpu, rq->rd->online)
-
-static int wake_idle(int cpu, struct task_struct *p)
-{
-       struct sched_domain *sd;
-       int i;
-       unsigned int chosen_wakeup_cpu;
-       int this_cpu;
-       struct rq *task_rq = task_rq(p);
-
-       /*
-        * At POWERSAVINGS_BALANCE_WAKEUP level, if both this_cpu and prev_cpu
-        * are idle and this is not a kernel thread and this task's affinity
-        * allows it to be moved to preferred cpu, then just move!
-        */
-
-       this_cpu = smp_processor_id();
-       chosen_wakeup_cpu =
-               cpu_rq(this_cpu)->rd->sched_mc_preferred_wakeup_cpu;
-
-       if (sched_mc_power_savings >= POWERSAVINGS_BALANCE_WAKEUP &&
-               idle_cpu(cpu) && idle_cpu(this_cpu) &&
-               p->mm && !(p->flags & PF_KTHREAD) &&
-               cpu_isset(chosen_wakeup_cpu, p->cpus_allowed))
-               return chosen_wakeup_cpu;
-
-       /*
-        * If it is idle, then it is the best cpu to run this task.
-        *
-        * This cpu is also the best, if it has more than one task already.
-        * Siblings must be also busy(in most cases) as they didn't already
-        * pickup the extra load from this cpu and hence we need not check
-        * sibling runqueue info. This will avoid the checks and cache miss
-        * penalities associated with that.
-        */
-       if (idle_cpu(cpu) || cpu_rq(cpu)->cfs.nr_running > 1)
-               return cpu;
-
-       for_each_domain(cpu, sd) {
-               if ((sd->flags & SD_WAKE_IDLE)
-                   || ((sd->flags & SD_WAKE_IDLE_FAR)
-                       && !task_hot(p, task_rq->clock, sd))) {
-                       for_each_cpu_and(i, sched_domain_span(sd),
-                                        &p->cpus_allowed) {
-                               if (cpu_rd_active(i, task_rq) && idle_cpu(i)) {
-                                       if (i != task_cpu(p)) {
-                                               schedstat_inc(p,
-                                                      se.nr_wakeups_idle);
-                                       }
-                                       return i;
-                               }
-                       }
-               } else {
-                       break;
-               }
-       }
-       return cpu;
-}
-#else /* !ARCH_HAS_SCHED_WAKE_IDLE*/
-static inline int wake_idle(int cpu, struct task_struct *p)
-{
-       return cpu;
-}
-#endif
-
 #ifdef CONFIG_SMP
 
 #ifdef CONFIG_FAIR_GROUP_SCHED
@@ -1225,25 +1155,34 @@ static inline unsigned long effective_load(struct task_group *tg, int cpu,
 
 #endif
 
-static int
-wake_affine(struct sched_domain *this_sd, struct rq *this_rq,
-           struct task_struct *p, int prev_cpu, int this_cpu, int sync,
-           int idx, unsigned long load, unsigned long this_load,
-           unsigned int imbalance)
+static int wake_affine(struct sched_domain *sd, struct task_struct *p, int sync)
 {
-       struct task_struct *curr = this_rq->curr;
-       struct task_group *tg;
-       unsigned long tl = this_load;
+       struct task_struct *curr = current;
+       unsigned long this_load, load;
+       int idx, this_cpu, prev_cpu;
        unsigned long tl_per_task;
+       unsigned int imbalance;
+       struct task_group *tg;
        unsigned long weight;
        int balanced;
 
-       if (!(this_sd->flags & SD_WAKE_AFFINE) || !sched_feat(AFFINE_WAKEUPS))
-               return 0;
+       idx       = sd->wake_idx;
+       this_cpu  = smp_processor_id();
+       prev_cpu  = task_cpu(p);
+       load      = source_load(prev_cpu, idx);
+       this_load = target_load(this_cpu, idx);
 
-       if (sync && (curr->se.avg_overlap > sysctl_sched_migration_cost ||
-                       p->se.avg_overlap > sysctl_sched_migration_cost))
-               sync = 0;
+       if (sync) {
+              if (sched_feat(SYNC_LESS) &&
+                  (curr->se.avg_overlap > sysctl_sched_migration_cost ||
+                   p->se.avg_overlap > sysctl_sched_migration_cost))
+                      sync = 0;
+       } else {
+               if (sched_feat(SYNC_MORE) &&
+                   (curr->se.avg_overlap < sysctl_sched_migration_cost &&
+                    p->se.avg_overlap < sysctl_sched_migration_cost))
+                       sync = 1;
+       }
 
        /*
         * If sync wakeup then subtract the (maximum possible)
@@ -1254,24 +1193,26 @@ wake_affine(struct sched_domain *this_sd, struct rq *this_rq,
                tg = task_group(current);
                weight = current->se.load.weight;
 
-               tl += effective_load(tg, this_cpu, -weight, -weight);
+               this_load += effective_load(tg, this_cpu, -weight, -weight);
                load += effective_load(tg, prev_cpu, 0, -weight);
        }
 
        tg = task_group(p);
        weight = p->se.load.weight;
 
+       imbalance = 100 + (sd->imbalance_pct - 100) / 2;
+
        /*
         * In low-load situations, where prev_cpu is idle and this_cpu is idle
-        * due to the sync cause above having dropped tl to 0, we'll always have
-        * an imbalance, but there's really nothing you can do about that, so
-        * that's good too.
+        * due to the sync cause above having dropped this_load to 0, we'll
+        * always have an imbalance, but there's really nothing you can do
+        * about that, so that's good too.
         *
         * Otherwise check if either cpus are near enough in load to allow this
         * task to be woken on this_cpu.
         */
-       balanced = !tl ||
-               100*(tl + effective_load(tg, this_cpu, weight, weight)) <=
+       balanced = !this_load ||
+               100*(this_load + effective_load(tg, this_cpu, weight, weight)) <=
                imbalance*(load + effective_load(tg, prev_cpu, 0, weight));
 
        /*
@@ -1285,14 +1226,15 @@ wake_affine(struct sched_domain *this_sd, struct rq *this_rq,
        schedstat_inc(p, se.nr_wakeups_affine_attempts);
        tl_per_task = cpu_avg_load_per_task(this_cpu);
 
-       if (balanced || (tl <= load && tl + target_load(prev_cpu, idx) <=
-                       tl_per_task)) {
+       if (balanced ||
+           (this_load <= load &&
+            this_load + target_load(prev_cpu, idx) <= tl_per_task)) {
                /*
                 * This domain has SD_WAKE_AFFINE and
                 * p is cache cold in this domain, and
                 * there is no bad imbalance.
                 */
-               schedstat_inc(this_sd, ttwu_move_affine);
+               schedstat_inc(sd, ttwu_move_affine);
                schedstat_inc(p, se.nr_wakeups_affine);
 
                return 1;
@@ -1300,65 +1242,215 @@ wake_affine(struct sched_domain *this_sd, struct rq *this_rq,
        return 0;
 }
 
-static int select_task_rq_fair(struct task_struct *p, int sync)
+/*
+ * find_idlest_group finds and returns the least busy CPU group within the
+ * domain.
+ */
+static struct sched_group *
+find_idlest_group(struct sched_domain *sd, struct task_struct *p,
+                 int this_cpu, int load_idx)
 {
-       struct sched_domain *sd, *this_sd = NULL;
-       int prev_cpu, this_cpu, new_cpu;
-       unsigned long load, this_load;
-       struct rq *this_rq;
-       unsigned int imbalance;
-       int idx;
+       struct sched_group *idlest = NULL, *this = NULL, *group = sd->groups;
+       unsigned long min_load = ULONG_MAX, this_load = 0;
+       int imbalance = 100 + (sd->imbalance_pct-100)/2;
 
-       prev_cpu        = task_cpu(p);
-       this_cpu        = smp_processor_id();
-       this_rq         = cpu_rq(this_cpu);
-       new_cpu         = prev_cpu;
+       do {
+               unsigned long load, avg_load;
+               int local_group;
+               int i;
 
-       /*
-        * 'this_sd' is the first domain that both
-        * this_cpu and prev_cpu are present in:
-        */
-       for_each_domain(this_cpu, sd) {
-               if (cpumask_test_cpu(prev_cpu, sched_domain_span(sd))) {
-                       this_sd = sd;
-                       break;
+               /* Skip over this group if it has no CPUs allowed */
+               if (!cpumask_intersects(sched_group_cpus(group),
+                                       &p->cpus_allowed))
+                       continue;
+
+               local_group = cpumask_test_cpu(this_cpu,
+                                              sched_group_cpus(group));
+
+               /* Tally up the load of all CPUs in the group */
+               avg_load = 0;
+
+               for_each_cpu(i, sched_group_cpus(group)) {
+                       /* Bias balancing toward cpus of our domain */
+                       if (local_group)
+                               load = source_load(i, load_idx);
+                       else
+                               load = target_load(i, load_idx);
+
+                       avg_load += load;
+               }
+
+               /* Adjust by relative CPU power of the group */
+               avg_load = (avg_load * SCHED_LOAD_SCALE) / group->cpu_power;
+
+               if (local_group) {
+                       this_load = avg_load;
+                       this = group;
+               } else if (avg_load < min_load) {
+                       min_load = avg_load;
+                       idlest = group;
+               }
+       } while (group = group->next, group != sd->groups);
+
+       if (!idlest || 100*this_load < imbalance*min_load)
+               return NULL;
+       return idlest;
+}
+
+/*
+ * find_idlest_cpu - find the idlest cpu among the cpus in group.
+ */
+static int
+find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu)
+{
+       unsigned long load, min_load = ULONG_MAX;
+       int idlest = -1;
+       int i;
+
+       /* Traverse only the allowed CPUs */
+       for_each_cpu_and(i, sched_group_cpus(group), &p->cpus_allowed) {
+               load = weighted_cpuload(i);
+
+               if (load < min_load || (load == min_load && i == this_cpu)) {
+                       min_load = load;
+                       idlest = i;
                }
        }
 
-       if (unlikely(!cpumask_test_cpu(this_cpu, &p->cpus_allowed)))
-               goto out;
+       return idlest;
+}
 
-       /*
-        * Check for affine wakeup and passive balancing possibilities.
-        */
-       if (!this_sd)
+/*
+ * sched_balance_self: balance the current task (running on cpu) in domains
+ * that have the 'flag' flag set. In practice, this is SD_BALANCE_FORK and
+ * SD_BALANCE_EXEC.
+ *
+ * Balance, ie. select the least loaded group.
+ *
+ * Returns the target CPU number, or the same CPU if no balancing is needed.
+ *
+ * preempt must be disabled.
+ */
+static int select_task_rq_fair(struct task_struct *p, int sd_flag, int wake_flags)
+{
+       struct sched_domain *tmp, *affine_sd = NULL, *sd = NULL;
+       int cpu = smp_processor_id();
+       int prev_cpu = task_cpu(p);
+       int new_cpu = cpu;
+       int want_affine = 0;
+       int want_sd = 1;
+       int sync = wake_flags & WF_SYNC;
+
+       if (sd_flag & SD_BALANCE_WAKE) {
+               if (sched_feat(AFFINE_WAKEUPS))
+                       want_affine = 1;
+               new_cpu = prev_cpu;
+       }
+
+       rcu_read_lock();
+       for_each_domain(cpu, tmp) {
+               /*
+                * If power savings logic is enabled for a domain, see if we
+                * are not overloaded, if so, don't balance wider.
+                */
+               if (tmp->flags & (SD_POWERSAVINGS_BALANCE|SD_PREFER_LOCAL)) {
+                       unsigned long power = 0;
+                       unsigned long nr_running = 0;
+                       unsigned long capacity;
+                       int i;
+
+                       for_each_cpu(i, sched_domain_span(tmp)) {
+                               power += power_of(i);
+                               nr_running += cpu_rq(i)->cfs.nr_running;
+                       }
+
+                       capacity = DIV_ROUND_CLOSEST(power, SCHED_LOAD_SCALE);
+
+                       if (tmp->flags & SD_POWERSAVINGS_BALANCE)
+                               nr_running /= 2;
+
+                       if (nr_running < capacity)
+                               want_sd = 0;
+               }
+
+               if (want_affine && (tmp->flags & SD_WAKE_AFFINE) &&
+                   cpumask_test_cpu(prev_cpu, sched_domain_span(tmp))) {
+
+                       affine_sd = tmp;
+                       want_affine = 0;
+               }
+
+               if (!want_sd && !want_affine)
+                       break;
+
+               if (!(tmp->flags & sd_flag))
+                       continue;
+
+               if (want_sd)
+                       sd = tmp;
+       }
+
+       if (sched_feat(LB_SHARES_UPDATE)) {
+               /*
+                * Pick the largest domain to update shares over
+                */
+               tmp = sd;
+               if (affine_sd && (!tmp ||
+                                 cpumask_weight(sched_domain_span(affine_sd)) >
+                                 cpumask_weight(sched_domain_span(sd))))
+                       tmp = affine_sd;
+
+               if (tmp)
+                       update_shares(tmp);
+       }
+
+       if (affine_sd && wake_affine(affine_sd, p, sync)) {
+               new_cpu = cpu;
                goto out;
+       }
 
-       idx = this_sd->wake_idx;
+       while (sd) {
+               int load_idx = sd->forkexec_idx;
+               struct sched_group *group;
+               int weight;
 
-       imbalance = 100 + (this_sd->imbalance_pct - 100) / 2;
+               if (!(sd->flags & sd_flag)) {
+                       sd = sd->child;
+                       continue;
+               }
 
-       load = source_load(prev_cpu, idx);
-       this_load = target_load(this_cpu, idx);
+               if (sd_flag & SD_BALANCE_WAKE)
+                       load_idx = sd->wake_idx;
 
-       if (wake_affine(this_sd, this_rq, p, prev_cpu, this_cpu, sync, idx,
-                                    load, this_load, imbalance))
-               return this_cpu;
+               group = find_idlest_group(sd, p, cpu, load_idx);
+               if (!group) {
+                       sd = sd->child;
+                       continue;
+               }
 
-       /*
-        * Start passive balancing when half the imbalance_pct
-        * limit is reached.
-        */
-       if (this_sd->flags & SD_WAKE_BALANCE) {
-               if (imbalance*this_load <= 100*load) {
-                       schedstat_inc(this_sd, ttwu_move_balance);
-                       schedstat_inc(p, se.nr_wakeups_passive);
-                       return this_cpu;
+               new_cpu = find_idlest_cpu(group, p, cpu);
+               if (new_cpu == -1 || new_cpu == cpu) {
+                       /* Now try balancing at a lower domain level of cpu */
+                       sd = sd->child;
+                       continue;
                }
+
+               /* Now try balancing at a lower domain level of new_cpu */
+               cpu = new_cpu;
+               weight = cpumask_weight(sched_domain_span(sd));
+               sd = NULL;
+               for_each_domain(cpu, tmp) {
+                       if (weight <= cpumask_weight(sched_domain_span(tmp)))
+                               break;
+                       if (tmp->flags & sd_flag)
+                               sd = tmp;
+               }
+               /* while loop will break here if sd == NULL */
        }
 
 out:
-       return wake_idle(new_cpu, p);
+       rcu_read_unlock();
+       return new_cpu;
 }
 #endif /* CONFIG_SMP */
 
@@ -1471,11 +1563,12 @@ static void set_next_buddy(struct sched_entity *se)
 /*
  * Preempt the current task with a newly woken task if needed:
  */
-static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int sync)
+static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_flags)
 {
        struct task_struct *curr = rq->curr;
        struct sched_entity *se = &curr->se, *pse = &p->se;
        struct cfs_rq *cfs_rq = task_cfs_rq(curr);
+       int sync = wake_flags & WF_SYNC;
 
        update_curr(cfs_rq);
 
@@ -1501,7 +1594,8 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int sync)
         */
        if (sched_feat(LAST_BUDDY) && likely(se->on_rq && curr != rq->idle))
                set_last_buddy(se);
-       set_next_buddy(pse);
+       if (sched_feat(NEXT_BUDDY) && !(wake_flags & WF_FORK))
+               set_next_buddy(pse);
 
        /*
         * We can come here with TIF_NEED_RESCHED already set from new task
@@ -1523,16 +1617,25 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int sync)
                return;
        }
 
-       if (!sched_feat(WAKEUP_PREEMPT))
-               return;
-
-       if (sched_feat(WAKEUP_OVERLAP) && (sync ||
-                       (se->avg_overlap < sysctl_sched_migration_cost &&
-                        pse->avg_overlap < sysctl_sched_migration_cost))) {
+       if ((sched_feat(WAKEUP_SYNC) && sync) ||
+           (sched_feat(WAKEUP_OVERLAP) &&
+            (se->avg_overlap < sysctl_sched_migration_cost &&
+             pse->avg_overlap < sysctl_sched_migration_cost))) {
                resched_task(curr);
                return;
        }
 
+       if (sched_feat(WAKEUP_RUNNING)) {
+               if (pse->avg_running < se->avg_running) {
+                       set_next_buddy(pse);
+                       resched_task(curr);
+                       return;
+               }
+       }
+
+       if (!sched_feat(WAKEUP_PREEMPT))
+               return;
+
        find_matching_se(&se, &pse);
 
        BUG_ON(!pse);
@@ -1555,8 +1658,13 @@ static struct task_struct *pick_next_task_fair(struct rq *rq)
                /*
                 * If se was a buddy, clear it so that it will have to earn
                 * the favour again.
+                *
+                * If se was not a buddy, clear the buddies because neither
+                * was elegible to run, let them earn it again.
+                *
+                * IOW. unconditionally clear buddies.
                 */
-               __clear_buddies(cfs_rq, se);
+               __clear_buddies(cfs_rq, NULL);
                set_next_entity(cfs_rq, se);
                cfs_rq = group_cfs_rq(se);
        } while (cfs_rq);
index e2dc63a5815d5eb90975ce53efc283d5d5a70746..0d94083582c71c84c48cdbec175191bc39ee43a6 100644 (file)
-SCHED_FEAT(NEW_FAIR_SLEEPERS, 0)
+/*
+ * Disregards a certain amount of sleep time (sched_latency_ns) and
+ * considers the task to be running during that period. This gives it
+ * a service deficit on wakeup, allowing it to run sooner.
+ */
+SCHED_FEAT(FAIR_SLEEPERS, 1)
+
+/*
+ * Only give sleepers 50% of their service deficit. This allows
+ * them to run sooner, but does not allow tons of sleepers to
+ * rip the spread apart.
+ */
+SCHED_FEAT(GENTLE_FAIR_SLEEPERS, 1)
+
+/*
+ * By not normalizing the sleep time, heavy tasks get an effective
+ * longer period, and lighter task an effective shorter period they
+ * are considered running.
+ */
 SCHED_FEAT(NORMALIZED_SLEEPER, 0)
-SCHED_FEAT(ADAPTIVE_GRAN, 1)
-SCHED_FEAT(WAKEUP_PREEMPT, 1)
+
+/*
+ * Place new tasks ahead so that they do not starve already running
+ * tasks
+ */
 SCHED_FEAT(START_DEBIT, 1)
+
+/*
+ * Should wakeups try to preempt running tasks.
+ */
+SCHED_FEAT(WAKEUP_PREEMPT, 1)
+
+/*
+ * Compute wakeup_gran based on task behaviour, clipped to
+ *  [0, sched_wakeup_gran_ns]
+ */
+SCHED_FEAT(ADAPTIVE_GRAN, 1)
+
+/*
+ * When converting the wakeup granularity to virtual time, do it such
+ * that heavier tasks preempting a lighter task have an edge.
+ */
+SCHED_FEAT(ASYM_GRAN, 1)
+
+/*
+ * Always wakeup-preempt SYNC wakeups, see SYNC_WAKEUPS.
+ */
+SCHED_FEAT(WAKEUP_SYNC, 0)
+
+/*
+ * Wakeup preempt based on task behaviour. Tasks that do not overlap
+ * don't get preempted.
+ */
+SCHED_FEAT(WAKEUP_OVERLAP, 0)
+
+/*
+ * Wakeup preemption towards tasks that run short
+ */
+SCHED_FEAT(WAKEUP_RUNNING, 0)
+
+/*
+ * Use the SYNC wakeup hint, pipes and the likes use this to indicate
+ * the remote end is likely to consume the data we just wrote, and
+ * therefore has cache benefit from being placed on the same cpu, see
+ * also AFFINE_WAKEUPS.
+ */
+SCHED_FEAT(SYNC_WAKEUPS, 1)
+
+/*
+ * Based on load and program behaviour, see if it makes sense to place
+ * a newly woken task on the same cpu as the task that woke it --
+ * improve cache locality. Typically used with SYNC wakeups as
+ * generated by pipes and the like, see also SYNC_WAKEUPS.
+ */
 SCHED_FEAT(AFFINE_WAKEUPS, 1)
+
+/*
+ * Weaken SYNC hint based on overlap
+ */
+SCHED_FEAT(SYNC_LESS, 1)
+
+/*
+ * Add SYNC hint based on overlap
+ */
+SCHED_FEAT(SYNC_MORE, 0)
+
+/*
+ * Prefer to schedule the task we woke last (assuming it failed
+ * wakeup-preemption), since its likely going to consume data we
+ * touched, increases cache locality.
+ */
+SCHED_FEAT(NEXT_BUDDY, 0)
+
+/*
+ * Prefer to schedule the task that ran last (when we did
+ * wake-preempt) as that likely will touch the same data, increases
+ * cache locality.
+ */
+SCHED_FEAT(LAST_BUDDY, 1)
+
+/*
+ * Consider buddies to be cache hot, decreases the likelyness of a
+ * cache buddy being migrated away, increases cache locality.
+ */
 SCHED_FEAT(CACHE_HOT_BUDDY, 1)
-SCHED_FEAT(SYNC_WAKEUPS, 1)
+
+/*
+ * Use arch dependent cpu power functions
+ */
+SCHED_FEAT(ARCH_POWER, 0)
+
 SCHED_FEAT(HRTICK, 0)
 SCHED_FEAT(DOUBLE_TICK, 0)
-SCHED_FEAT(ASYM_GRAN, 1)
 SCHED_FEAT(LB_BIAS, 1)
-SCHED_FEAT(LB_WAKEUP_UPDATE, 1)
+SCHED_FEAT(LB_SHARES_UPDATE, 1)
 SCHED_FEAT(ASYM_EFF_LOAD, 1)
-SCHED_FEAT(WAKEUP_OVERLAP, 0)
-SCHED_FEAT(LAST_BUDDY, 1)
+
+/*
+ * Spin-wait on mutex acquisition when the mutex owner is running on
+ * another cpu -- assumes that when the owner is running, it will soon
+ * release the lock. Decreases scheduling overhead.
+ */
 SCHED_FEAT(OWNER_SPIN, 1)
index 499672c10cbd615141a362cafe804711bbcf1ff3..a8b448af004b4361402d8146af596e44898641ba 100644 (file)
@@ -6,7 +6,7 @@
  */
 
 #ifdef CONFIG_SMP
-static int select_task_rq_idle(struct task_struct *p, int sync)
+static int select_task_rq_idle(struct task_struct *p, int sd_flag, int flags)
 {
        return task_cpu(p); /* IDLE tasks as never migrated */
 }
@@ -14,7 +14,7 @@ static int select_task_rq_idle(struct task_struct *p, int sync)
 /*
  * Idle tasks are unconditionally rescheduled:
  */
-static void check_preempt_curr_idle(struct rq *rq, struct task_struct *p, int sync)
+static void check_preempt_curr_idle(struct rq *rq, struct task_struct *p, int flags)
 {
        resched_task(rq->idle);
 }
index 2eb4bd6a526cffebc236392a5bc71b9e1d4ed17d..13de7126a6abebca2e2c6bdaede88fcaadca25de 100644 (file)
@@ -938,10 +938,13 @@ static void yield_task_rt(struct rq *rq)
 #ifdef CONFIG_SMP
 static int find_lowest_rq(struct task_struct *task);
 
-static int select_task_rq_rt(struct task_struct *p, int sync)
+static int select_task_rq_rt(struct task_struct *p, int sd_flag, int flags)
 {
        struct rq *rq = task_rq(p);
 
+       if (sd_flag != SD_BALANCE_WAKE)
+               return smp_processor_id();
+
        /*
         * If the current task is an RT task, then
         * try to see if we can wake this RT task up on another
@@ -999,7 +1002,7 @@ static void check_preempt_equal_prio(struct rq *rq, struct task_struct *p)
 /*
  * Preempt the current task with a newly woken task if needed:
  */
-static void check_preempt_curr_rt(struct rq *rq, struct task_struct *p, int sync)
+static void check_preempt_curr_rt(struct rq *rq, struct task_struct *p, int flags)
 {
        if (p->prio < rq->curr->prio) {
                resched_task(rq->curr);
index 7db25067cd2dde3018d64bbeed9b085ee8d42d7b..f8749e5216e00c0b1a719a4aa945be8454ca67c0 100644 (file)
@@ -57,7 +57,7 @@ static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp
 static DEFINE_PER_CPU(struct task_struct *, ksoftirqd);
 
 char *softirq_to_name[NR_SOFTIRQS] = {
-       "HI", "TIMER", "NET_TX", "NET_RX", "BLOCK",
+       "HI", "TIMER", "NET_TX", "NET_RX", "BLOCK", "BLOCK_IOPOLL",
        "TASKLET", "SCHED", "HRTIMER",  "RCU"
 };
 
index 29511943871a15b2acf87cccf528513b07e57880..2e2e469a7fecea49ea9124eaedf5b025075d789e 100644 (file)
@@ -370,13 +370,20 @@ EXPORT_SYMBOL(mktime);
  *     0 <= tv_nsec < NSEC_PER_SEC
  * For negative values only the tv_sec field is negative !
  */
-void set_normalized_timespec(struct timespec *ts, time_t sec, long nsec)
+void set_normalized_timespec(struct timespec *ts, time_t sec, s64 nsec)
 {
        while (nsec >= NSEC_PER_SEC) {
+               /*
+                * The following asm() prevents the compiler from
+                * optimising this loop into a modulo operation. See
+                * also __iter_div_u64_rem() in include/linux/time.h
+                */
+               asm("" : "+rm"(nsec));
                nsec -= NSEC_PER_SEC;
                ++sec;
        }
        while (nsec < 0) {
+               asm("" : "+rm"(nsec));
                nsec += NSEC_PER_SEC;
                --sec;
        }
index 7466cb8112517b3bbc8869e4c2c91438ee74608c..09113347d3281c8de133e4223dec7afa806e41e5 100644 (file)
@@ -21,7 +21,6 @@
  *
  * TODO WishList:
  *   o Allow clocksource drivers to be unregistered
- *   o get rid of clocksource_jiffies extern
  */
 
 #include <linux/clocksource.h>
@@ -30,6 +29,7 @@
 #include <linux/module.h>
 #include <linux/sched.h> /* for spin_unlock_irq() using preempt_count() m68k */
 #include <linux/tick.h>
+#include <linux/kthread.h>
 
 void timecounter_init(struct timecounter *tc,
                      const struct cyclecounter *cc,
@@ -107,50 +107,35 @@ u64 timecounter_cyc2time(struct timecounter *tc,
 }
 EXPORT_SYMBOL(timecounter_cyc2time);
 
-/* XXX - Would like a better way for initializing curr_clocksource */
-extern struct clocksource clocksource_jiffies;
-
 /*[Clocksource internal variables]---------
  * curr_clocksource:
- *     currently selected clocksource. Initialized to clocksource_jiffies.
- * next_clocksource:
- *     pending next selected clocksource.
+ *     currently selected clocksource.
  * clocksource_list:
  *     linked list with the registered clocksources
- * clocksource_lock:
- *     protects manipulations to curr_clocksource and next_clocksource
- *     and the clocksource_list
+ * clocksource_mutex:
+ *     protects manipulations to curr_clocksource and the clocksource_list
  * override_name:
  *     Name of the user-specified clocksource.
  */
-static struct clocksource *curr_clocksource = &clocksource_jiffies;
-static struct clocksource *next_clocksource;
-static struct clocksource *clocksource_override;
+static struct clocksource *curr_clocksource;
 static LIST_HEAD(clocksource_list);
-static DEFINE_SPINLOCK(clocksource_lock);
+static DEFINE_MUTEX(clocksource_mutex);
 static char override_name[32];
 static int finished_booting;
 
-/* clocksource_done_booting - Called near the end of core bootup
- *
- * Hack to avoid lots of clocksource churn at boot time.
- * We use fs_initcall because we want this to start before
- * device_initcall but after subsys_initcall.
- */
-static int __init clocksource_done_booting(void)
-{
-       finished_booting = 1;
-       return 0;
-}
-fs_initcall(clocksource_done_booting);
-
 #ifdef CONFIG_CLOCKSOURCE_WATCHDOG
+static void clocksource_watchdog_work(struct work_struct *work);
+
 static LIST_HEAD(watchdog_list);
 static struct clocksource *watchdog;
 static struct timer_list watchdog_timer;
+static DECLARE_WORK(watchdog_work, clocksource_watchdog_work);
 static DEFINE_SPINLOCK(watchdog_lock);
 static cycle_t watchdog_last;
-static unsigned long watchdog_resumed;
+static int watchdog_running;
+
+static int clocksource_watchdog_kthread(void *data);
+static void __clocksource_change_rating(struct clocksource *cs, int rating);
 
 /*
  * Interval: 0.5sec Threshold: 0.0625s
@@ -158,135 +143,249 @@ static unsigned long watchdog_resumed;
 #define WATCHDOG_INTERVAL (HZ >> 1)
 #define WATCHDOG_THRESHOLD (NSEC_PER_SEC >> 4)
 
-static void clocksource_ratewd(struct clocksource *cs, int64_t delta)
+static void clocksource_watchdog_work(struct work_struct *work)
 {
-       if (delta > -WATCHDOG_THRESHOLD && delta < WATCHDOG_THRESHOLD)
-               return;
+       /*
+        * If kthread_run fails the next watchdog scan over the
+        * watchdog_list will find the unstable clock again.
+        */
+       kthread_run(clocksource_watchdog_kthread, NULL, "kwatchdog");
+}
 
+static void __clocksource_unstable(struct clocksource *cs)
+{
+       cs->flags &= ~(CLOCK_SOURCE_VALID_FOR_HRES | CLOCK_SOURCE_WATCHDOG);
+       cs->flags |= CLOCK_SOURCE_UNSTABLE;
+       if (finished_booting)
+               schedule_work(&watchdog_work);
+}
+
+static void clocksource_unstable(struct clocksource *cs, int64_t delta)
+{
        printk(KERN_WARNING "Clocksource %s unstable (delta = %Ld ns)\n",
               cs->name, delta);
-       cs->flags &= ~(CLOCK_SOURCE_VALID_FOR_HRES | CLOCK_SOURCE_WATCHDOG);
-       clocksource_change_rating(cs, 0);
-       list_del(&cs->wd_list);
+       __clocksource_unstable(cs);
+}
+
+/**
+ * clocksource_mark_unstable - mark clocksource unstable via watchdog
+ * @cs:                clocksource to be marked unstable
+ *
+ * This function is called instead of clocksource_change_rating from
+ * cpu hotplug code to avoid a deadlock between the clocksource mutex
+ * and the cpu hotplug mutex. It defers the update of the clocksource
+ * to the watchdog thread.
+ */
+void clocksource_mark_unstable(struct clocksource *cs)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&watchdog_lock, flags);
+       if (!(cs->flags & CLOCK_SOURCE_UNSTABLE)) {
+               if (list_empty(&cs->wd_list))
+                       list_add(&cs->wd_list, &watchdog_list);
+               __clocksource_unstable(cs);
+       }
+       spin_unlock_irqrestore(&watchdog_lock, flags);
 }
 
 static void clocksource_watchdog(unsigned long data)
 {
-       struct clocksource *cs, *tmp;
+       struct clocksource *cs;
        cycle_t csnow, wdnow;
        int64_t wd_nsec, cs_nsec;
-       int resumed;
+       int next_cpu;
 
        spin_lock(&watchdog_lock);
-
-       resumed = test_and_clear_bit(0, &watchdog_resumed);
+       if (!watchdog_running)
+               goto out;
 
        wdnow = watchdog->read(watchdog);
-       wd_nsec = cyc2ns(watchdog, (wdnow - watchdog_last) & watchdog->mask);
+       wd_nsec = clocksource_cyc2ns((wdnow - watchdog_last) & watchdog->mask,
+                                    watchdog->mult, watchdog->shift);
        watchdog_last = wdnow;
 
-       list_for_each_entry_safe(cs, tmp, &watchdog_list, wd_list) {
-               csnow = cs->read(cs);
+       list_for_each_entry(cs, &watchdog_list, wd_list) {
 
-               if (unlikely(resumed)) {
-                       cs->wd_last = csnow;
+               /* Clocksource already marked unstable? */
+               if (cs->flags & CLOCK_SOURCE_UNSTABLE) {
+                       if (finished_booting)
+                               schedule_work(&watchdog_work);
                        continue;
                }
 
-               /* Initialized ? */
+               csnow = cs->read(cs);
+
+               /* Clocksource initialized ? */
                if (!(cs->flags & CLOCK_SOURCE_WATCHDOG)) {
-                       if ((cs->flags & CLOCK_SOURCE_IS_CONTINUOUS) &&
-                           (watchdog->flags & CLOCK_SOURCE_IS_CONTINUOUS)) {
-                               cs->flags |= CLOCK_SOURCE_VALID_FOR_HRES;
-                               /*
-                                * We just marked the clocksource as
-                                * highres-capable, notify the rest of the
-                                * system as well so that we transition
-                                * into high-res mode:
-                                */
-                               tick_clock_notify();
-                       }
                        cs->flags |= CLOCK_SOURCE_WATCHDOG;
                        cs->wd_last = csnow;
-               } else {
-                       cs_nsec = cyc2ns(cs, (csnow - cs->wd_last) & cs->mask);
-                       cs->wd_last = csnow;
-                       /* Check the delta. Might remove from the list ! */
-                       clocksource_ratewd(cs, cs_nsec - wd_nsec);
+                       continue;
                }
-       }
 
-       if (!list_empty(&watchdog_list)) {
-               /*
-                * Cycle through CPUs to check if the CPUs stay
-                * synchronized to each other.
-                */
-               int next_cpu = cpumask_next(raw_smp_processor_id(),
-                                           cpu_online_mask);
+               /* Check the deviation from the watchdog clocksource. */
+               cs_nsec = clocksource_cyc2ns((csnow - cs->wd_last) &
+                                            cs->mask, cs->mult, cs->shift);
+               cs->wd_last = csnow;
+               if (abs(cs_nsec - wd_nsec) > WATCHDOG_THRESHOLD) {
+                       clocksource_unstable(cs, cs_nsec - wd_nsec);
+                       continue;
+               }
 
-               if (next_cpu >= nr_cpu_ids)
-                       next_cpu = cpumask_first(cpu_online_mask);
-               watchdog_timer.expires += WATCHDOG_INTERVAL;
-               add_timer_on(&watchdog_timer, next_cpu);
+               if (!(cs->flags & CLOCK_SOURCE_VALID_FOR_HRES) &&
+                   (cs->flags & CLOCK_SOURCE_IS_CONTINUOUS) &&
+                   (watchdog->flags & CLOCK_SOURCE_IS_CONTINUOUS)) {
+                       cs->flags |= CLOCK_SOURCE_VALID_FOR_HRES;
+                       /*
+                        * We just marked the clocksource as highres-capable,
+                        * notify the rest of the system as well so that we
+                        * transition into high-res mode:
+                        */
+                       tick_clock_notify();
+               }
        }
+
+       /*
+        * Cycle through CPUs to check if the CPUs stay synchronized
+        * to each other.
+        */
+       next_cpu = cpumask_next(raw_smp_processor_id(), cpu_online_mask);
+       if (next_cpu >= nr_cpu_ids)
+               next_cpu = cpumask_first(cpu_online_mask);
+       watchdog_timer.expires += WATCHDOG_INTERVAL;
+       add_timer_on(&watchdog_timer, next_cpu);
+out:
        spin_unlock(&watchdog_lock);
 }
+
+static inline void clocksource_start_watchdog(void)
+{
+       if (watchdog_running || !watchdog || list_empty(&watchdog_list))
+               return;
+       init_timer(&watchdog_timer);
+       watchdog_timer.function = clocksource_watchdog;
+       watchdog_last = watchdog->read(watchdog);
+       watchdog_timer.expires = jiffies + WATCHDOG_INTERVAL;
+       add_timer_on(&watchdog_timer, cpumask_first(cpu_online_mask));
+       watchdog_running = 1;
+}
+
+static inline void clocksource_stop_watchdog(void)
+{
+       if (!watchdog_running || (watchdog && !list_empty(&watchdog_list)))
+               return;
+       del_timer(&watchdog_timer);
+       watchdog_running = 0;
+}
+
+static inline void clocksource_reset_watchdog(void)
+{
+       struct clocksource *cs;
+
+       list_for_each_entry(cs, &watchdog_list, wd_list)
+               cs->flags &= ~CLOCK_SOURCE_WATCHDOG;
+}
+
 static void clocksource_resume_watchdog(void)
 {
-       set_bit(0, &watchdog_resumed);
+       unsigned long flags;
+
+       spin_lock_irqsave(&watchdog_lock, flags);
+       clocksource_reset_watchdog();
+       spin_unlock_irqrestore(&watchdog_lock, flags);
 }
 
-static void clocksource_check_watchdog(struct clocksource *cs)
+static void clocksource_enqueue_watchdog(struct clocksource *cs)
 {
-       struct clocksource *cse;
        unsigned long flags;
 
        spin_lock_irqsave(&watchdog_lock, flags);
        if (cs->flags & CLOCK_SOURCE_MUST_VERIFY) {
-               int started = !list_empty(&watchdog_list);
-
+               /* cs is a clocksource to be watched. */
                list_add(&cs->wd_list, &watchdog_list);
-               if (!started && watchdog) {
-                       watchdog_last = watchdog->read(watchdog);
-                       watchdog_timer.expires = jiffies + WATCHDOG_INTERVAL;
-                       add_timer_on(&watchdog_timer,
-                                    cpumask_first(cpu_online_mask));
-               }
+               cs->flags &= ~CLOCK_SOURCE_WATCHDOG;
        } else {
+               /* cs is a watchdog. */
                if (cs->flags & CLOCK_SOURCE_IS_CONTINUOUS)
                        cs->flags |= CLOCK_SOURCE_VALID_FOR_HRES;
-
+               /* Pick the best watchdog. */
                if (!watchdog || cs->rating > watchdog->rating) {
-                       if (watchdog)
-                               del_timer(&watchdog_timer);
                        watchdog = cs;
-                       init_timer(&watchdog_timer);
-                       watchdog_timer.function = clocksource_watchdog;
-
                        /* Reset watchdog cycles */
-                       list_for_each_entry(cse, &watchdog_list, wd_list)
-                               cse->flags &= ~CLOCK_SOURCE_WATCHDOG;
-                       /* Start if list is not empty */
-                       if (!list_empty(&watchdog_list)) {
-                               watchdog_last = watchdog->read(watchdog);
-                               watchdog_timer.expires =
-                                       jiffies + WATCHDOG_INTERVAL;
-                               add_timer_on(&watchdog_timer,
-                                            cpumask_first(cpu_online_mask));
-                       }
+                       clocksource_reset_watchdog();
+               }
+       }
+       /* Check if the watchdog timer needs to be started. */
+       clocksource_start_watchdog();
+       spin_unlock_irqrestore(&watchdog_lock, flags);
+}
+
+static void clocksource_dequeue_watchdog(struct clocksource *cs)
+{
+       struct clocksource *tmp;
+       unsigned long flags;
+
+       spin_lock_irqsave(&watchdog_lock, flags);
+       if (cs->flags & CLOCK_SOURCE_MUST_VERIFY) {
+               /* cs is a watched clocksource. */
+               list_del_init(&cs->wd_list);
+       } else if (cs == watchdog) {
+               /* Reset watchdog cycles */
+               clocksource_reset_watchdog();
+               /* Current watchdog is removed. Find an alternative. */
+               watchdog = NULL;
+               list_for_each_entry(tmp, &clocksource_list, list) {
+                       if (tmp == cs || tmp->flags & CLOCK_SOURCE_MUST_VERIFY)
+                               continue;
+                       if (!watchdog || tmp->rating > watchdog->rating)
+                               watchdog = tmp;
                }
        }
+       cs->flags &= ~CLOCK_SOURCE_WATCHDOG;
+       /* Check if the watchdog timer needs to be stopped. */
+       clocksource_stop_watchdog();
        spin_unlock_irqrestore(&watchdog_lock, flags);
 }
-#else
-static void clocksource_check_watchdog(struct clocksource *cs)
+
+static int clocksource_watchdog_kthread(void *data)
+{
+       struct clocksource *cs, *tmp;
+       unsigned long flags;
+       LIST_HEAD(unstable);
+
+       mutex_lock(&clocksource_mutex);
+       spin_lock_irqsave(&watchdog_lock, flags);
+       list_for_each_entry_safe(cs, tmp, &watchdog_list, wd_list)
+               if (cs->flags & CLOCK_SOURCE_UNSTABLE) {
+                       list_del_init(&cs->wd_list);
+                       list_add(&cs->wd_list, &unstable);
+               }
+       /* Check if the watchdog timer needs to be stopped. */
+       clocksource_stop_watchdog();
+       spin_unlock_irqrestore(&watchdog_lock, flags);
+
+       /* Needs to be done outside of watchdog lock */
+       list_for_each_entry_safe(cs, tmp, &unstable, wd_list) {
+               list_del_init(&cs->wd_list);
+               __clocksource_change_rating(cs, 0);
+       }
+       mutex_unlock(&clocksource_mutex);
+       return 0;
+}
+
+#else /* CONFIG_CLOCKSOURCE_WATCHDOG */
+
+static void clocksource_enqueue_watchdog(struct clocksource *cs)
 {
        if (cs->flags & CLOCK_SOURCE_IS_CONTINUOUS)
                cs->flags |= CLOCK_SOURCE_VALID_FOR_HRES;
 }
 
+static inline void clocksource_dequeue_watchdog(struct clocksource *cs) { }
 static inline void clocksource_resume_watchdog(void) { }
-#endif
+static inline int clocksource_watchdog_kthread(void *data) { return 0; }
+
+#endif /* CONFIG_CLOCKSOURCE_WATCHDOG */
 
 /**
  * clocksource_resume - resume the clocksource(s)
@@ -294,18 +393,16 @@ static inline void clocksource_resume_watchdog(void) { }
 void clocksource_resume(void)
 {
        struct clocksource *cs;
-       unsigned long flags;
 
-       spin_lock_irqsave(&clocksource_lock, flags);
+       mutex_lock(&clocksource_mutex);
 
-       list_for_each_entry(cs, &clocksource_list, list) {
+       list_for_each_entry(cs, &clocksource_list, list)
                if (cs->resume)
                        cs->resume();
-       }
 
        clocksource_resume_watchdog();
 
-       spin_unlock_irqrestore(&clocksource_lock, flags);
+       mutex_unlock(&clocksource_mutex);
 }
 
 /**
@@ -320,75 +417,94 @@ void clocksource_touch_watchdog(void)
        clocksource_resume_watchdog();
 }
 
+#ifdef CONFIG_GENERIC_TIME
+
 /**
- * clocksource_get_next - Returns the selected clocksource
+ * clocksource_select - Select the best clocksource available
+ *
+ * Private function. Must hold clocksource_mutex when called.
  *
+ * Select the clocksource with the best rating, or the clocksource,
+ * which is selected by userspace override.
  */
-struct clocksource *clocksource_get_next(void)
+static void clocksource_select(void)
 {
-       unsigned long flags;
+       struct clocksource *best, *cs;
 
-       spin_lock_irqsave(&clocksource_lock, flags);
-       if (next_clocksource && finished_booting) {
-               curr_clocksource = next_clocksource;
-               next_clocksource = NULL;
+       if (!finished_booting || list_empty(&clocksource_list))
+               return;
+       /* First clocksource on the list has the best rating. */
+       best = list_first_entry(&clocksource_list, struct clocksource, list);
+       /* Check for the override clocksource. */
+       list_for_each_entry(cs, &clocksource_list, list) {
+               if (strcmp(cs->name, override_name) != 0)
+                       continue;
+               /*
+                * Check to make sure we don't switch to a non-highres
+                * capable clocksource if the tick code is in oneshot
+                * mode (highres or nohz)
+                */
+               if (!(cs->flags & CLOCK_SOURCE_VALID_FOR_HRES) &&
+                   tick_oneshot_mode_active()) {
+                       /* Override clocksource cannot be used. */
+                       printk(KERN_WARNING "Override clocksource %s is not "
+                              "HRT compatible. Cannot switch while in "
+                              "HRT/NOHZ mode\n", cs->name);
+                       override_name[0] = 0;
+               } else
+                       /* Override clocksource can be used. */
+                       best = cs;
+               break;
+       }
+       if (curr_clocksource != best) {
+               printk(KERN_INFO "Switching to clocksource %s\n", best->name);
+               curr_clocksource = best;
+               timekeeping_notify(curr_clocksource);
        }
-       spin_unlock_irqrestore(&clocksource_lock, flags);
-
-       return curr_clocksource;
 }
 
-/**
- * select_clocksource - Selects the best registered clocksource.
- *
- * Private function. Must hold clocksource_lock when called.
+#else /* CONFIG_GENERIC_TIME */
+
+static inline void clocksource_select(void) { }
+
+#endif
+
+/*
+ * clocksource_done_booting - Called near the end of core bootup
  *
- * Select the clocksource with the best rating, or the clocksource,
- * which is selected by userspace override.
+ * Hack to avoid lots of clocksource churn at boot time.
+ * We use fs_initcall because we want this to start before
+ * device_initcall but after subsys_initcall.
  */
-static struct clocksource *select_clocksource(void)
+static int __init clocksource_done_booting(void)
 {
-       struct clocksource *next;
-
-       if (list_empty(&clocksource_list))
-               return NULL;
-
-       if (clocksource_override)
-               next = clocksource_override;
-       else
-               next = list_entry(clocksource_list.next, struct clocksource,
-                                 list);
+       finished_booting = 1;
 
-       if (next == curr_clocksource)
-               return NULL;
+       /*
+        * Run the watchdog first to eliminate unstable clock sources
+        */
+       clocksource_watchdog_kthread(NULL);
 
-       return next;
+       mutex_lock(&clocksource_mutex);
+       clocksource_select();
+       mutex_unlock(&clocksource_mutex);
+       return 0;
 }
+fs_initcall(clocksource_done_booting);
 
 /*
  * Enqueue the clocksource sorted by rating
  */
-static int clocksource_enqueue(struct clocksource *c)
+static void clocksource_enqueue(struct clocksource *cs)
 {
-       struct list_head *tmp, *entry = &clocksource_list;
+       struct list_head *entry = &clocksource_list;
+       struct clocksource *tmp;
 
-       list_for_each(tmp, &clocksource_list) {
-               struct clocksource *cs;
-
-               cs = list_entry(tmp, struct clocksource, list);
-               if (cs == c)
-                       return -EBUSY;
+       list_for_each_entry(tmp, &clocksource_list, list)
                /* Keep track of the place, where to insert */
-               if (cs->rating >= c->rating)
-                       entry = tmp;
-       }
-       list_add(&c->list, entry);
-
-       if (strlen(c->name) == strlen(override_name) &&
-           !strcmp(c->name, override_name))
-               clocksource_override = c;
-
-       return 0;
+               if (tmp->rating >= cs->rating)
+                       entry = &tmp->list;
+       list_add(&cs->list, entry);
 }
 
 /**
@@ -397,52 +513,48 @@ static int clocksource_enqueue(struct clocksource *c)
  *
  * Returns -EBUSY if registration fails, zero otherwise.
  */
-int clocksource_register(struct clocksource *c)
+int clocksource_register(struct clocksource *cs)
 {
-       unsigned long flags;
-       int ret;
-
-       spin_lock_irqsave(&clocksource_lock, flags);
-       ret = clocksource_enqueue(c);
-       if (!ret)
-               next_clocksource = select_clocksource();
-       spin_unlock_irqrestore(&clocksource_lock, flags);
-       if (!ret)
-               clocksource_check_watchdog(c);
-       return ret;
+       mutex_lock(&clocksource_mutex);
+       clocksource_enqueue(cs);
+       clocksource_select();
+       clocksource_enqueue_watchdog(cs);
+       mutex_unlock(&clocksource_mutex);
+       return 0;
 }
 EXPORT_SYMBOL(clocksource_register);
 
+static void __clocksource_change_rating(struct clocksource *cs, int rating)
+{
+       list_del(&cs->list);
+       cs->rating = rating;
+       clocksource_enqueue(cs);
+       clocksource_select();
+}
+
 /**
  * clocksource_change_rating - Change the rating of a registered clocksource
- *
  */
 void clocksource_change_rating(struct clocksource *cs, int rating)
 {
-       unsigned long flags;
-
-       spin_lock_irqsave(&clocksource_lock, flags);
-       list_del(&cs->list);
-       cs->rating = rating;
-       clocksource_enqueue(cs);
-       next_clocksource = select_clocksource();
-       spin_unlock_irqrestore(&clocksource_lock, flags);
+       mutex_lock(&clocksource_mutex);
+       __clocksource_change_rating(cs, rating);
+       mutex_unlock(&clocksource_mutex);
 }
+EXPORT_SYMBOL(clocksource_change_rating);
 
 /**
  * clocksource_unregister - remove a registered clocksource
  */
 void clocksource_unregister(struct clocksource *cs)
 {
-       unsigned long flags;
-
-       spin_lock_irqsave(&clocksource_lock, flags);
+       mutex_lock(&clocksource_mutex);
+       clocksource_dequeue_watchdog(cs);
        list_del(&cs->list);
-       if (clocksource_override == cs)
-               clocksource_override = NULL;
-       next_clocksource = select_clocksource();
-       spin_unlock_irqrestore(&clocksource_lock, flags);
+       clocksource_select();
+       mutex_unlock(&clocksource_mutex);
 }
+EXPORT_SYMBOL(clocksource_unregister);
 
 #ifdef CONFIG_SYSFS
 /**
@@ -458,9 +570,9 @@ sysfs_show_current_clocksources(struct sys_device *dev,
 {
        ssize_t count = 0;
 
-       spin_lock_irq(&clocksource_lock);
+       mutex_lock(&clocksource_mutex);
        count = snprintf(buf, PAGE_SIZE, "%s\n", curr_clocksource->name);
-       spin_unlock_irq(&clocksource_lock);
+       mutex_unlock(&clocksource_mutex);
 
        return count;
 }
@@ -478,9 +590,7 @@ static ssize_t sysfs_override_clocksource(struct sys_device *dev,
                                          struct sysdev_attribute *attr,
                                          const char *buf, size_t count)
 {
-       struct clocksource *ovr = NULL;
        size_t ret = count;
-       int len;
 
        /* strings from sysfs write are not 0 terminated! */
        if (count >= sizeof(override_name))
@@ -490,44 +600,14 @@ static ssize_t sysfs_override_clocksource(struct sys_device *dev,
        if (buf[count-1] == '\n')
                count--;
 
-       spin_lock_irq(&clocksource_lock);
+       mutex_lock(&clocksource_mutex);
 
        if (count > 0)
                memcpy(override_name, buf, count);
        override_name[count] = 0;
+       clocksource_select();
 
-       len = strlen(override_name);
-       if (len) {
-               struct clocksource *cs;
-
-               ovr = clocksource_override;
-               /* try to select it: */
-               list_for_each_entry(cs, &clocksource_list, list) {
-                       if (strlen(cs->name) == len &&
-                           !strcmp(cs->name, override_name))
-                               ovr = cs;
-               }
-       }
-
-       /*
-        * Check to make sure we don't switch to a non-highres capable
-        * clocksource if the tick code is in oneshot mode (highres or nohz)
-        */
-       if (tick_oneshot_mode_active() && ovr &&
-           !(ovr->flags & CLOCK_SOURCE_VALID_FOR_HRES)) {
-               printk(KERN_WARNING "%s clocksource is not HRT compatible. "
-                       "Cannot switch while in HRT/NOHZ mode\n", ovr->name);
-               ovr = NULL;
-               override_name[0] = 0;
-       }
-
-       /* Reselect, when the override name has changed */
-       if (ovr != clocksource_override) {
-               clocksource_override = ovr;
-               next_clocksource = select_clocksource();
-       }
-
-       spin_unlock_irq(&clocksource_lock);
+       mutex_unlock(&clocksource_mutex);
 
        return ret;
 }
@@ -547,7 +627,7 @@ sysfs_show_available_clocksources(struct sys_device *dev,
        struct clocksource *src;
        ssize_t count = 0;
 
-       spin_lock_irq(&clocksource_lock);
+       mutex_lock(&clocksource_mutex);
        list_for_each_entry(src, &clocksource_list, list) {
                /*
                 * Don't show non-HRES clocksource if the tick code is
@@ -559,7 +639,7 @@ sysfs_show_available_clocksources(struct sys_device *dev,
                                  max((ssize_t)PAGE_SIZE - count, (ssize_t)0),
                                  "%s ", src->name);
        }
-       spin_unlock_irq(&clocksource_lock);
+       mutex_unlock(&clocksource_mutex);
 
        count += snprintf(buf + count,
                          max((ssize_t)PAGE_SIZE - count, (ssize_t)0), "\n");
@@ -614,11 +694,10 @@ device_initcall(init_clocksource_sysfs);
  */
 static int __init boot_override_clocksource(char* str)
 {
-       unsigned long flags;
-       spin_lock_irqsave(&clocksource_lock, flags);
+       mutex_lock(&clocksource_mutex);
        if (str)
                strlcpy(override_name, str, sizeof(override_name));
-       spin_unlock_irqrestore(&clocksource_lock, flags);
+       mutex_unlock(&clocksource_mutex);
        return 1;
 }
 
index c3f6c30816e397c7245243c8913a6331c55f9de1..5404a84569094f3cef796e903ad6a4cb92a8b3e8 100644 (file)
@@ -61,7 +61,6 @@ struct clocksource clocksource_jiffies = {
        .read           = jiffies_read,
        .mask           = 0xffffffff, /*32bits*/
        .mult           = NSEC_PER_JIFFY << JIFFIES_SHIFT, /* details above */
-       .mult_orig      = NSEC_PER_JIFFY << JIFFIES_SHIFT,
        .shift          = JIFFIES_SHIFT,
 };
 
@@ -71,3 +70,8 @@ static int __init init_jiffies_clocksource(void)
 }
 
 core_initcall(init_jiffies_clocksource);
+
+struct clocksource * __init __weak clocksource_default_clock(void)
+{
+       return &clocksource_jiffies;
+}
index 7fc64375ff43350ce59cb3a1d0db220c57d79a46..4800f933910ea4ed8f0f2d8ad4d2f660eb4a3467 100644 (file)
@@ -194,8 +194,7 @@ static enum hrtimer_restart ntp_leap_second(struct hrtimer *timer)
        case TIME_OK:
                break;
        case TIME_INS:
-               xtime.tv_sec--;
-               wall_to_monotonic.tv_sec++;
+               timekeeping_leap_insert(-1);
                time_state = TIME_OOP;
                printk(KERN_NOTICE
                        "Clock: inserting leap second 23:59:60 UTC\n");
@@ -203,9 +202,8 @@ static enum hrtimer_restart ntp_leap_second(struct hrtimer *timer)
                res = HRTIMER_RESTART;
                break;
        case TIME_DEL:
-               xtime.tv_sec++;
+               timekeeping_leap_insert(1);
                time_tai--;
-               wall_to_monotonic.tv_sec--;
                time_state = TIME_WAIT;
                printk(KERN_NOTICE
                        "Clock: deleting leap second 23:59:59 UTC\n");
@@ -219,7 +217,6 @@ static enum hrtimer_restart ntp_leap_second(struct hrtimer *timer)
                        time_state = TIME_OK;
                break;
        }
-       update_vsyscall(&xtime, clock);
 
        write_sequnlock(&xtime_lock);
 
index e8c77d9c633acbffc4872b8d0c4b8a9929d399c2..fb0f46fa1ecd0fc09b656e2759ff990372faacb3 100644 (file)
 #include <linux/jiffies.h>
 #include <linux/time.h>
 #include <linux/tick.h>
+#include <linux/stop_machine.h>
+
+/* Structure holding internal timekeeping values. */
+struct timekeeper {
+       /* Current clocksource used for timekeeping. */
+       struct clocksource *clock;
+       /* The shift value of the current clocksource. */
+       int     shift;
+
+       /* Number of clock cycles in one NTP interval. */
+       cycle_t cycle_interval;
+       /* Number of clock shifted nano seconds in one NTP interval. */
+       u64     xtime_interval;
+       /* Raw nano seconds accumulated per NTP interval. */
+       u32     raw_interval;
+
+       /* Clock shifted nano seconds remainder not stored in xtime.tv_nsec. */
+       u64     xtime_nsec;
+       /* Difference between accumulated time and NTP time in ntp
+        * shifted nano seconds. */
+       s64     ntp_error;
+       /* Shift conversion between clock shifted nano seconds and
+        * ntp shifted nano seconds. */
+       int     ntp_error_shift;
+       /* NTP adjusted clock multiplier */
+       u32     mult;
+};
+
+struct timekeeper timekeeper;
+
+/**
+ * timekeeper_setup_internals - Set up internals to use clocksource clock.
+ *
+ * @clock:             Pointer to clocksource.
+ *
+ * Calculates a fixed cycle/nsec interval for a given clocksource/adjustment
+ * pair and interval request.
+ *
+ * Unless you're the timekeeping code, you should not be using this!
+ */
+static void timekeeper_setup_internals(struct clocksource *clock)
+{
+       cycle_t interval;
+       u64 tmp;
+
+       timekeeper.clock = clock;
+       clock->cycle_last = clock->read(clock);
 
+       /* Do the ns -> cycle conversion first, using original mult */
+       tmp = NTP_INTERVAL_LENGTH;
+       tmp <<= clock->shift;
+       tmp += clock->mult/2;
+       do_div(tmp, clock->mult);
+       if (tmp == 0)
+               tmp = 1;
+
+       interval = (cycle_t) tmp;
+       timekeeper.cycle_interval = interval;
+
+       /* Go back from cycles -> shifted ns */
+       timekeeper.xtime_interval = (u64) interval * clock->mult;
+       timekeeper.raw_interval =
+               ((u64) interval * clock->mult) >> clock->shift;
+
+       timekeeper.xtime_nsec = 0;
+       timekeeper.shift = clock->shift;
+
+       timekeeper.ntp_error = 0;
+       timekeeper.ntp_error_shift = NTP_SCALE_SHIFT - clock->shift;
+
+       /*
+        * The timekeeper keeps its own mult values for the currently
+        * active clocksource. These value will be adjusted via NTP
+        * to counteract clock drifting.
+        */
+       timekeeper.mult = clock->mult;
+}
+
+/* Timekeeper helper functions. */
+static inline s64 timekeeping_get_ns(void)
+{
+       cycle_t cycle_now, cycle_delta;
+       struct clocksource *clock;
+
+       /* read clocksource: */
+       clock = timekeeper.clock;
+       cycle_now = clock->read(clock);
+
+       /* calculate the delta since the last update_wall_time: */
+       cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;
+
+       /* return delta convert to nanoseconds using ntp adjusted mult. */
+       return clocksource_cyc2ns(cycle_delta, timekeeper.mult,
+                                 timekeeper.shift);
+}
+
+static inline s64 timekeeping_get_ns_raw(void)
+{
+       cycle_t cycle_now, cycle_delta;
+       struct clocksource *clock;
+
+       /* read clocksource: */
+       clock = timekeeper.clock;
+       cycle_now = clock->read(clock);
+
+       /* calculate the delta since the last update_wall_time: */
+       cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;
+
+       /* return delta convert to nanoseconds using ntp adjusted mult. */
+       return clocksource_cyc2ns(cycle_delta, clock->mult, clock->shift);
+}
 
 /*
  * This read-write spinlock protects us from races in SMP while
@@ -44,7 +154,12 @@ __cacheline_aligned_in_smp DEFINE_SEQLOCK(xtime_lock);
  */
 struct timespec xtime __attribute__ ((aligned (16)));
 struct timespec wall_to_monotonic __attribute__ ((aligned (16)));
-static unsigned long total_sleep_time;         /* seconds */
+static struct timespec total_sleep_time;
+
+/*
+ * The raw monotonic time for the CLOCK_MONOTONIC_RAW posix clock.
+ */
+struct timespec raw_time;
 
 /* flag for if timekeeping is suspended */
 int __read_mostly timekeeping_suspended;
@@ -56,35 +171,44 @@ void update_xtime_cache(u64 nsec)
        timespec_add_ns(&xtime_cache, nsec);
 }
 
-struct clocksource *clock;
-
+/* must hold xtime_lock */
+void timekeeping_leap_insert(int leapsecond)
+{
+       xtime.tv_sec += leapsecond;
+       wall_to_monotonic.tv_sec -= leapsecond;
+       update_vsyscall(&xtime, timekeeper.clock);
+}
 
 #ifdef CONFIG_GENERIC_TIME
+
 /**
- * clocksource_forward_now - update clock to the current time
+ * timekeeping_forward_now - update clock to the current time
  *
  * Forward the current clock to update its state since the last call to
  * update_wall_time(). This is useful before significant clock changes,
  * as it avoids having to deal with this time offset explicitly.
  */
-static void clocksource_forward_now(void)
+static void timekeeping_forward_now(void)
 {
        cycle_t cycle_now, cycle_delta;
+       struct clocksource *clock;
        s64 nsec;
 
-       cycle_now = clocksource_read(clock);
+       clock = timekeeper.clock;
+       cycle_now = clock->read(clock);
        cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;
        clock->cycle_last = cycle_now;
 
-       nsec = cyc2ns(clock, cycle_delta);
+       nsec = clocksource_cyc2ns(cycle_delta, timekeeper.mult,
+                                 timekeeper.shift);
 
        /* If arch requires, add in gettimeoffset() */
        nsec += arch_gettimeoffset();
 
        timespec_add_ns(&xtime, nsec);
 
-       nsec = ((s64)cycle_delta * clock->mult_orig) >> clock->shift;
-       clock->raw_time.tv_nsec += nsec;
+       nsec = clocksource_cyc2ns(cycle_delta, clock->mult, clock->shift);
+       timespec_add_ns(&raw_time, nsec);
 }
 
 /**
@@ -95,7 +219,6 @@ static void clocksource_forward_now(void)
  */
 void getnstimeofday(struct timespec *ts)
 {
-       cycle_t cycle_now, cycle_delta;
        unsigned long seq;
        s64 nsecs;
 
@@ -105,15 +228,7 @@ void getnstimeofday(struct timespec *ts)
                seq = read_seqbegin(&xtime_lock);
 
                *ts = xtime;
-
-               /* read clocksource: */
-               cycle_now = clocksource_read(clock);
-
-               /* calculate the delta since the last update_wall_time: */
-               cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;
-
-               /* convert to nanoseconds: */
-               nsecs = cyc2ns(clock, cycle_delta);
+               nsecs = timekeeping_get_ns();
 
                /* If arch requires, add in gettimeoffset() */
                nsecs += arch_gettimeoffset();
@@ -125,6 +240,57 @@ void getnstimeofday(struct timespec *ts)
 
 EXPORT_SYMBOL(getnstimeofday);
 
+ktime_t ktime_get(void)
+{
+       unsigned int seq;
+       s64 secs, nsecs;
+
+       WARN_ON(timekeeping_suspended);
+
+       do {
+               seq = read_seqbegin(&xtime_lock);
+               secs = xtime.tv_sec + wall_to_monotonic.tv_sec;
+               nsecs = xtime.tv_nsec + wall_to_monotonic.tv_nsec;
+               nsecs += timekeeping_get_ns();
+
+       } while (read_seqretry(&xtime_lock, seq));
+       /*
+        * Use ktime_set/ktime_add_ns to create a proper ktime on
+        * 32-bit architectures without CONFIG_KTIME_SCALAR.
+        */
+       return ktime_add_ns(ktime_set(secs, 0), nsecs);
+}
+EXPORT_SYMBOL_GPL(ktime_get);
+
+/**
+ * ktime_get_ts - get the monotonic clock in timespec format
+ * @ts:                pointer to timespec variable
+ *
+ * The function calculates the monotonic clock from the realtime
+ * clock and the wall_to_monotonic offset and stores the result
+ * in normalized timespec format in the variable pointed to by @ts.
+ */
+void ktime_get_ts(struct timespec *ts)
+{
+       struct timespec tomono;
+       unsigned int seq;
+       s64 nsecs;
+
+       WARN_ON(timekeeping_suspended);
+
+       do {
+               seq = read_seqbegin(&xtime_lock);
+               *ts = xtime;
+               tomono = wall_to_monotonic;
+               nsecs = timekeeping_get_ns();
+
+       } while (read_seqretry(&xtime_lock, seq));
+
+       set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec,
+                               ts->tv_nsec + tomono.tv_nsec + nsecs);
+}
+EXPORT_SYMBOL_GPL(ktime_get_ts);
+
 /**
  * do_gettimeofday - Returns the time of day in a timeval
  * @tv:                pointer to the timeval to be set
@@ -157,7 +323,7 @@ int do_settimeofday(struct timespec *tv)
 
        write_seqlock_irqsave(&xtime_lock, flags);
 
-       clocksource_forward_now();
+       timekeeping_forward_now();
 
        ts_delta.tv_sec = tv->tv_sec - xtime.tv_sec;
        ts_delta.tv_nsec = tv->tv_nsec - xtime.tv_nsec;
@@ -167,10 +333,10 @@ int do_settimeofday(struct timespec *tv)
 
        update_xtime_cache(0);
 
-       clock->error = 0;
+       timekeeper.ntp_error = 0;
        ntp_clear();
 
-       update_vsyscall(&xtime, clock);
+       update_vsyscall(&xtime, timekeeper.clock);
 
        write_sequnlock_irqrestore(&xtime_lock, flags);
 
@@ -187,44 +353,97 @@ EXPORT_SYMBOL(do_settimeofday);
  *
  * Accumulates current time interval and initializes new clocksource
  */
-static void change_clocksource(void)
+static int change_clocksource(void *data)
 {
        struct clocksource *new, *old;
 
-       new = clocksource_get_next();
+       new = (struct clocksource *) data;
+
+       timekeeping_forward_now();
+       if (!new->enable || new->enable(new) == 0) {
+               old = timekeeper.clock;
+               timekeeper_setup_internals(new);
+               if (old->disable)
+                       old->disable(old);
+       }
+       return 0;
+}
 
-       if (clock == new)
+/**
+ * timekeeping_notify - Install a new clock source
+ * @clock:             pointer to the clock source
+ *
+ * This function is called from clocksource.c after a new, better clock
+ * source has been registered. The caller holds the clocksource_mutex.
+ */
+void timekeeping_notify(struct clocksource *clock)
+{
+       if (timekeeper.clock == clock)
                return;
+       stop_machine(change_clocksource, clock, NULL);
+       tick_clock_notify();
+}
 
-       clocksource_forward_now();
+#else /* GENERIC_TIME */
 
-       if (clocksource_enable(new))
-               return;
+static inline void timekeeping_forward_now(void) { }
 
-       new->raw_time = clock->raw_time;
-       old = clock;
-       clock = new;
-       clocksource_disable(old);
+/**
+ * ktime_get - get the monotonic time in ktime_t format
+ *
+ * returns the time in ktime_t format
+ */
+ktime_t ktime_get(void)
+{
+       struct timespec now;
 
-       clock->cycle_last = 0;
-       clock->cycle_last = clocksource_read(clock);
-       clock->error = 0;
-       clock->xtime_nsec = 0;
-       clocksource_calculate_interval(clock, NTP_INTERVAL_LENGTH);
+       ktime_get_ts(&now);
 
-       tick_clock_notify();
+       return timespec_to_ktime(now);
+}
+EXPORT_SYMBOL_GPL(ktime_get);
 
-       /*
-        * We're holding xtime lock and waking up klogd would deadlock
-        * us on enqueue.  So no printing!
-       printk(KERN_INFO "Time: %s clocksource has been installed.\n",
-              clock->name);
-        */
+/**
+ * ktime_get_ts - get the monotonic clock in timespec format
+ * @ts:                pointer to timespec variable
+ *
+ * The function calculates the monotonic clock from the realtime
+ * clock and the wall_to_monotonic offset and stores the result
+ * in normalized timespec format in the variable pointed to by @ts.
+ */
+void ktime_get_ts(struct timespec *ts)
+{
+       struct timespec tomono;
+       unsigned long seq;
+
+       do {
+               seq = read_seqbegin(&xtime_lock);
+               getnstimeofday(ts);
+               tomono = wall_to_monotonic;
+
+       } while (read_seqretry(&xtime_lock, seq));
+
+       set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec,
+                               ts->tv_nsec + tomono.tv_nsec);
 }
-#else
-static inline void clocksource_forward_now(void) { }
-static inline void change_clocksource(void) { }
-#endif
+EXPORT_SYMBOL_GPL(ktime_get_ts);
+
+#endif /* !GENERIC_TIME */
+
+/**
+ * ktime_get_real - get the real (wall-) time in ktime_t format
+ *
+ * returns the time in ktime_t format
+ */
+ktime_t ktime_get_real(void)
+{
+       struct timespec now;
+
+       getnstimeofday(&now);
+
+       return timespec_to_ktime(now);
+}
+EXPORT_SYMBOL_GPL(ktime_get_real);
 
 /**
  * getrawmonotonic - Returns the raw monotonic time in a timespec
@@ -236,21 +455,11 @@ void getrawmonotonic(struct timespec *ts)
 {
        unsigned long seq;
        s64 nsecs;
-       cycle_t cycle_now, cycle_delta;
 
        do {
                seq = read_seqbegin(&xtime_lock);
-
-               /* read clocksource: */
-               cycle_now = clocksource_read(clock);
-
-               /* calculate the delta since the last update_wall_time: */
-               cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;
-
-               /* convert to nanoseconds: */
-               nsecs = ((s64)cycle_delta * clock->mult_orig) >> clock->shift;
-
-               *ts = clock->raw_time;
+               nsecs = timekeeping_get_ns_raw();
+               *ts = raw_time;
 
        } while (read_seqretry(&xtime_lock, seq));
 
@@ -270,7 +479,7 @@ int timekeeping_valid_for_hres(void)
        do {
                seq = read_seqbegin(&xtime_lock);
 
-               ret = clock->flags & CLOCK_SOURCE_VALID_FOR_HRES;
+               ret = timekeeper.clock->flags & CLOCK_SOURCE_VALID_FOR_HRES;
 
        } while (read_seqretry(&xtime_lock, seq));
 
@@ -278,17 +487,33 @@ int timekeeping_valid_for_hres(void)
 }
 
 /**
- * read_persistent_clock -  Return time in seconds from the persistent clock.
+ * read_persistent_clock -  Return time from the persistent clock.
  *
  * Weak dummy function for arches that do not yet support it.
- * Returns seconds from epoch using the battery backed persistent clock.
- * Returns zero if unsupported.
+ * Reads the time from the battery backed persistent clock.
+ * Returns a timespec with tv_sec=0 and tv_nsec=0 if unsupported.
  *
  *  XXX - Do be sure to remove it once all arches implement it.
  */
-unsigned long __attribute__((weak)) read_persistent_clock(void)
+void __attribute__((weak)) read_persistent_clock(struct timespec *ts)
 {
-       return 0;
+       ts->tv_sec = 0;
+       ts->tv_nsec = 0;
+}
+
+/**
+ * read_boot_clock -  Return time of the system start.
+ *
+ * Weak dummy function for arches that do not yet support it.
+ * Function to read the exact time the system has been started.
+ * Returns a timespec with tv_sec=0 and tv_nsec=0 if unsupported.
+ *
+ *  XXX - Do be sure to remove it once all arches implement it.
+ */
+void __attribute__((weak)) read_boot_clock(struct timespec *ts)
+{
+       ts->tv_sec = 0;
+       ts->tv_nsec = 0;
 }
 
 /*
@@ -296,29 +521,40 @@ unsigned long __attribute__((weak)) read_persistent_clock(void)
  */
 void __init timekeeping_init(void)
 {
+       struct clocksource *clock;
        unsigned long flags;
-       unsigned long sec = read_persistent_clock();
+       struct timespec now, boot;
+
+       read_persistent_clock(&now);
+       read_boot_clock(&boot);
 
        write_seqlock_irqsave(&xtime_lock, flags);
 
        ntp_init();
 
-       clock = clocksource_get_next();
-       clocksource_enable(clock);
-       clocksource_calculate_interval(clock, NTP_INTERVAL_LENGTH);
-       clock->cycle_last = clocksource_read(clock);
-
-       xtime.tv_sec = sec;
-       xtime.tv_nsec = 0;
+       clock = clocksource_default_clock();
+       if (clock->enable)
+               clock->enable(clock);
+       timekeeper_setup_internals(clock);
+
+       xtime.tv_sec = now.tv_sec;
+       xtime.tv_nsec = now.tv_nsec;
+       raw_time.tv_sec = 0;
+       raw_time.tv_nsec = 0;
+       if (boot.tv_sec == 0 && boot.tv_nsec == 0) {
+               boot.tv_sec = xtime.tv_sec;
+               boot.tv_nsec = xtime.tv_nsec;
+       }
        set_normalized_timespec(&wall_to_monotonic,
-               -xtime.tv_sec, -xtime.tv_nsec);
+                               -boot.tv_sec, -boot.tv_nsec);
        update_xtime_cache(0);
-       total_sleep_time = 0;
+       total_sleep_time.tv_sec = 0;
+       total_sleep_time.tv_nsec = 0;
        write_sequnlock_irqrestore(&xtime_lock, flags);
 }
 
 /* time in seconds when suspend began */
-static unsigned long timekeeping_suspend_time;
+static struct timespec timekeeping_suspend_time;
 
 /**
  * timekeeping_resume - Resumes the generic timekeeping subsystem.
@@ -331,24 +567,24 @@ static unsigned long timekeeping_suspend_time;
 static int timekeeping_resume(struct sys_device *dev)
 {
        unsigned long flags;
-       unsigned long now = read_persistent_clock();
+       struct timespec ts;
+
+       read_persistent_clock(&ts);
 
        clocksource_resume();
 
        write_seqlock_irqsave(&xtime_lock, flags);
 
-       if (now && (now > timekeeping_suspend_time)) {
-               unsigned long sleep_length = now - timekeeping_suspend_time;
-
-               xtime.tv_sec += sleep_length;
-               wall_to_monotonic.tv_sec -= sleep_length;
-               total_sleep_time += sleep_length;
+       if (timespec_compare(&ts, &timekeeping_suspend_time) > 0) {
+               ts = timespec_sub(ts, timekeeping_suspend_time);
+               xtime = timespec_add_safe(xtime, ts);
+               wall_to_monotonic = timespec_sub(wall_to_monotonic, ts);
+               total_sleep_time = timespec_add_safe(total_sleep_time, ts);
        }
        update_xtime_cache(0);
        /* re-base the last cycle value */
-       clock->cycle_last = 0;
-       clock->cycle_last = clocksource_read(clock);
-       clock->error = 0;
+       timekeeper.clock->cycle_last = timekeeper.clock->read(timekeeper.clock);
+       timekeeper.ntp_error = 0;
        timekeeping_suspended = 0;
        write_sequnlock_irqrestore(&xtime_lock, flags);
 
@@ -366,10 +602,10 @@ static int timekeeping_suspend(struct sys_device *dev, pm_message_t state)
 {
        unsigned long flags;
 
-       timekeeping_suspend_time = read_persistent_clock();
+       read_persistent_clock(&timekeeping_suspend_time);
 
        write_seqlock_irqsave(&xtime_lock, flags);
-       clocksource_forward_now();
+       timekeeping_forward_now();
        timekeeping_suspended = 1;
        write_sequnlock_irqrestore(&xtime_lock, flags);
 
@@ -404,7 +640,7 @@ device_initcall(timekeeping_init_device);
  * If the error is already larger, we look ahead even further
  * to compensate for late or lost adjustments.
  */
-static __always_inline int clocksource_bigadjust(s64 error, s64 *interval,
+static __always_inline int timekeeping_bigadjust(s64 error, s64 *interval,
                                                 s64 *offset)
 {
        s64 tick_error, i;
@@ -420,7 +656,7 @@ static __always_inline int clocksource_bigadjust(s64 error, s64 *interval,
         * here.  This is tuned so that an error of about 1 msec is adjusted
         * within about 1 sec (or 2^20 nsec in 2^SHIFT_HZ ticks).
         */
-       error2 = clock->error >> (NTP_SCALE_SHIFT + 22 - 2 * SHIFT_HZ);
+       error2 = timekeeper.ntp_error >> (NTP_SCALE_SHIFT + 22 - 2 * SHIFT_HZ);
        error2 = abs(error2);
        for (look_ahead = 0; error2 > 0; look_ahead++)
                error2 >>= 2;
@@ -429,8 +665,8 @@ static __always_inline int clocksource_bigadjust(s64 error, s64 *interval,
         * Now calculate the error in (1 << look_ahead) ticks, but first
         * remove the single look ahead already included in the error.
         */
-       tick_error = tick_length >> (NTP_SCALE_SHIFT - clock->shift + 1);
-       tick_error -= clock->xtime_interval >> 1;
+       tick_error = tick_length >> (timekeeper.ntp_error_shift + 1);
+       tick_error -= timekeeper.xtime_interval >> 1;
        error = ((error - tick_error) >> look_ahead) + tick_error;
 
        /* Finally calculate the adjustment shift value.  */
@@ -455,18 +691,18 @@ static __always_inline int clocksource_bigadjust(s64 error, s64 *interval,
  * this is optimized for the most common adjustments of -1,0,1,
  * for other values we can do a bit more work.
  */
-static void clocksource_adjust(s64 offset)
+static void timekeeping_adjust(s64 offset)
 {
-       s64 error, interval = clock->cycle_interval;
+       s64 error, interval = timekeeper.cycle_interval;
        int adj;
 
-       error = clock->error >> (NTP_SCALE_SHIFT - clock->shift - 1);
+       error = timekeeper.ntp_error >> (timekeeper.ntp_error_shift - 1);
        if (error > interval) {
                error >>= 2;
                if (likely(error <= interval))
                        adj = 1;
                else
-                       adj = clocksource_bigadjust(error, &interval, &offset);
+                       adj = timekeeping_bigadjust(error, &interval, &offset);
        } else if (error < -interval) {
                error >>= 2;
                if (likely(error >= -interval)) {
@@ -474,15 +710,15 @@ static void clocksource_adjust(s64 offset)
                        interval = -interval;
                        offset = -offset;
                } else
-                       adj = clocksource_bigadjust(error, &interval, &offset);
+                       adj = timekeeping_bigadjust(error, &interval, &offset);
        } else
                return;
 
-       clock->mult += adj;
-       clock->xtime_interval += interval;
-       clock->xtime_nsec -= offset;
-       clock->error -= (interval - offset) <<
-                       (NTP_SCALE_SHIFT - clock->shift);
+       timekeeper.mult += adj;
+       timekeeper.xtime_interval += interval;
+       timekeeper.xtime_nsec -= offset;
+       timekeeper.ntp_error -= (interval - offset) <<
+                               timekeeper.ntp_error_shift;
 }
 
 /**
@@ -492,53 +728,59 @@ static void clocksource_adjust(s64 offset)
  */
 void update_wall_time(void)
 {
+       struct clocksource *clock;
        cycle_t offset;
+       u64 nsecs;
 
        /* Make sure we're fully resumed: */
        if (unlikely(timekeeping_suspended))
                return;
 
+       clock = timekeeper.clock;
 #ifdef CONFIG_GENERIC_TIME
-       offset = (clocksource_read(clock) - clock->cycle_last) & clock->mask;
+       offset = (clock->read(clock) - clock->cycle_last) & clock->mask;
 #else
-       offset = clock->cycle_interval;
+       offset = timekeeper.cycle_interval;
 #endif
-       clock->xtime_nsec = (s64)xtime.tv_nsec << clock->shift;
+       timekeeper.xtime_nsec = (s64)xtime.tv_nsec << timekeeper.shift;
 
        /* normally this loop will run just once, however in the
         * case of lost or late ticks, it will accumulate correctly.
         */
-       while (offset >= clock->cycle_interval) {
+       while (offset >= timekeeper.cycle_interval) {
+               u64 nsecps = (u64)NSEC_PER_SEC << timekeeper.shift;
+
                /* accumulate one interval */
-               offset -= clock->cycle_interval;
-               clock->cycle_last += clock->cycle_interval;
+               offset -= timekeeper.cycle_interval;
+               clock->cycle_last += timekeeper.cycle_interval;
 
-               clock->xtime_nsec += clock->xtime_interval;
-               if (clock->xtime_nsec >= (u64)NSEC_PER_SEC << clock->shift) {
-                       clock->xtime_nsec -= (u64)NSEC_PER_SEC << clock->shift;
+               timekeeper.xtime_nsec += timekeeper.xtime_interval;
+               if (timekeeper.xtime_nsec >= nsecps) {
+                       timekeeper.xtime_nsec -= nsecps;
                        xtime.tv_sec++;
                        second_overflow();
                }
 
-               clock->raw_time.tv_nsec += clock->raw_interval;
-               if (clock->raw_time.tv_nsec >= NSEC_PER_SEC) {
-                       clock->raw_time.tv_nsec -= NSEC_PER_SEC;
-                       clock->raw_time.tv_sec++;
+               raw_time.tv_nsec += timekeeper.raw_interval;
+               if (raw_time.tv_nsec >= NSEC_PER_SEC) {
+                       raw_time.tv_nsec -= NSEC_PER_SEC;
+                       raw_time.tv_sec++;
                }
 
                /* accumulate error between NTP and clock interval */
-               clock->error += tick_length;
-               clock->error -= clock->xtime_interval << (NTP_SCALE_SHIFT - clock->shift);
+               timekeeper.ntp_error += tick_length;
+               timekeeper.ntp_error -= timekeeper.xtime_interval <<
+                                       timekeeper.ntp_error_shift;
        }
 
        /* correct the clock when NTP error is too big */
-       clocksource_adjust(offset);
+       timekeeping_adjust(offset);
 
        /*
         * Since in the loop above, we accumulate any amount of time
         * in xtime_nsec over a second into xtime.tv_sec, its possible for
         * xtime_nsec to be fairly small after the loop. Further, if we're
-        * slightly speeding the clocksource up in clocksource_adjust(),
+        * slightly speeding the clocksource up in timekeeping_adjust(),
         * its possible the required corrective factor to xtime_nsec could
         * cause it to underflow.
         *
@@ -550,24 +792,25 @@ void update_wall_time(void)
         * We'll correct this error next time through this function, when
         * xtime_nsec is not as small.
         */
-       if (unlikely((s64)clock->xtime_nsec < 0)) {
-               s64 neg = -(s64)clock->xtime_nsec;
-               clock->xtime_nsec = 0;
-               clock->error += neg << (NTP_SCALE_SHIFT - clock->shift);
+       if (unlikely((s64)timekeeper.xtime_nsec < 0)) {
+               s64 neg = -(s64)timekeeper.xtime_nsec;
+               timekeeper.xtime_nsec = 0;
+               timekeeper.ntp_error += neg << timekeeper.ntp_error_shift;
        }
 
        /* store full nanoseconds into xtime after rounding it up and
         * add the remainder to the error difference.
         */
-       xtime.tv_nsec = ((s64)clock->xtime_nsec >> clock->shift) + 1;
-       clock->xtime_nsec -= (s64)xtime.tv_nsec << clock->shift;
-       clock->error += clock->xtime_nsec << (NTP_SCALE_SHIFT - clock->shift);
+       xtime.tv_nsec = ((s64) timekeeper.xtime_nsec >> timekeeper.shift) + 1;
+       timekeeper.xtime_nsec -= (s64) xtime.tv_nsec << timekeeper.shift;
+       timekeeper.ntp_error += timekeeper.xtime_nsec <<
+                               timekeeper.ntp_error_shift;
 
-       update_xtime_cache(cyc2ns(clock, offset));
+       nsecs = clocksource_cyc2ns(offset, timekeeper.mult, timekeeper.shift);
+       update_xtime_cache(nsecs);
 
        /* check to see if there is a new clocksource to use */
-       change_clocksource();
-       update_vsyscall(&xtime, clock);
+       update_vsyscall(&xtime, timekeeper.clock);
 }
 
 /**
@@ -583,9 +826,12 @@ void update_wall_time(void)
  */
 void getboottime(struct timespec *ts)
 {
-       set_normalized_timespec(ts,
-               - (wall_to_monotonic.tv_sec + total_sleep_time),
-               - wall_to_monotonic.tv_nsec);
+       struct timespec boottime = {
+               .tv_sec = wall_to_monotonic.tv_sec + total_sleep_time.tv_sec,
+               .tv_nsec = wall_to_monotonic.tv_nsec + total_sleep_time.tv_nsec
+       };
+
+       set_normalized_timespec(ts, -boottime.tv_sec, -boottime.tv_nsec);
 }
 
 /**
@@ -594,7 +840,7 @@ void getboottime(struct timespec *ts)
  */
 void monotonic_to_bootbased(struct timespec *ts)
 {
-       ts->tv_sec += total_sleep_time;
+       *ts = timespec_add_safe(*ts, total_sleep_time);
 }
 
 unsigned long get_seconds(void)
@@ -603,6 +849,10 @@ unsigned long get_seconds(void)
 }
 EXPORT_SYMBOL(get_seconds);
 
+struct timespec __current_kernel_time(void)
+{
+       return xtime_cache;
+}
 
 struct timespec current_kernel_time(void)
 {
@@ -618,3 +868,20 @@ struct timespec current_kernel_time(void)
        return now;
 }
 EXPORT_SYMBOL(current_kernel_time);
+
+struct timespec get_monotonic_coarse(void)
+{
+       struct timespec now, mono;
+       unsigned long seq;
+
+       do {
+               seq = read_seqbegin(&xtime_lock);
+
+               now = xtime_cache;
+               mono = wall_to_monotonic;
+       } while (read_seqretry(&xtime_lock, seq));
+
+       set_normalized_timespec(&now, now.tv_sec + mono.tv_sec,
+                               now.tv_nsec + mono.tv_nsec);
+       return now;
+}
index a3d25f4150190a7afcd36a0e1bb9c17e7df793cd..bbb51074680e3ee961f1decd1cf7bd289d0596f4 100644 (file)
@@ -72,6 +72,7 @@ struct tvec_base {
        spinlock_t lock;
        struct timer_list *running_timer;
        unsigned long timer_jiffies;
+       unsigned long next_timer;
        struct tvec_root tv1;
        struct tvec tv2;
        struct tvec tv3;
@@ -622,6 +623,9 @@ __mod_timer(struct timer_list *timer, unsigned long expires,
 
        if (timer_pending(timer)) {
                detach_timer(timer, 0);
+               if (timer->expires == base->next_timer &&
+                   !tbase_get_deferrable(timer->base))
+                       base->next_timer = base->timer_jiffies;
                ret = 1;
        } else {
                if (pending_only)
@@ -663,6 +667,9 @@ __mod_timer(struct timer_list *timer, unsigned long expires,
        }
 
        timer->expires = expires;
+       if (time_before(timer->expires, base->next_timer) &&
+           !tbase_get_deferrable(timer->base))
+               base->next_timer = timer->expires;
        internal_add_timer(base, timer);
 
 out_unlock:
@@ -781,6 +788,9 @@ void add_timer_on(struct timer_list *timer, int cpu)
        spin_lock_irqsave(&base->lock, flags);
        timer_set_base(timer, base);
        debug_timer_activate(timer);
+       if (time_before(timer->expires, base->next_timer) &&
+           !tbase_get_deferrable(timer->base))
+               base->next_timer = timer->expires;
        internal_add_timer(base, timer);
        /*
         * Check whether the other CPU is idle and needs to be
@@ -817,6 +827,9 @@ int del_timer(struct timer_list *timer)
                base = lock_timer_base(timer, &flags);
                if (timer_pending(timer)) {
                        detach_timer(timer, 1);
+                       if (timer->expires == base->next_timer &&
+                           !tbase_get_deferrable(timer->base))
+                               base->next_timer = base->timer_jiffies;
                        ret = 1;
                }
                spin_unlock_irqrestore(&base->lock, flags);
@@ -850,6 +863,9 @@ int try_to_del_timer_sync(struct timer_list *timer)
        ret = 0;
        if (timer_pending(timer)) {
                detach_timer(timer, 1);
+               if (timer->expires == base->next_timer &&
+                   !tbase_get_deferrable(timer->base))
+                       base->next_timer = base->timer_jiffies;
                ret = 1;
        }
 out:
@@ -1007,8 +1023,8 @@ static inline void __run_timers(struct tvec_base *base)
 #ifdef CONFIG_NO_HZ
 /*
  * Find out when the next timer event is due to happen. This
- * is used on S/390 to stop all activity when a cpus is idle.
- * This functions needs to be called disabled.
+ * is used on S/390 to stop all activity when a CPU is idle.
+ * This function needs to be called with interrupts disabled.
  */
 static unsigned long __next_timer_interrupt(struct tvec_base *base)
 {
@@ -1134,7 +1150,9 @@ unsigned long get_next_timer_interrupt(unsigned long now)
        unsigned long expires;
 
        spin_lock(&base->lock);
-       expires = __next_timer_interrupt(base);
+       if (time_before_eq(base->next_timer, base->timer_jiffies))
+               base->next_timer = __next_timer_interrupt(base);
+       expires = base->next_timer;
        spin_unlock(&base->lock);
 
        if (time_before_eq(expires, now))
@@ -1522,6 +1540,7 @@ static int __cpuinit init_timers_cpu(int cpu)
                INIT_LIST_HEAD(base->tv1.vec + j);
 
        base->timer_jiffies = jiffies;
+       base->next_timer = base->timer_jiffies;
        return 0;
 }
 
@@ -1534,6 +1553,9 @@ static void migrate_timer_list(struct tvec_base *new_base, struct list_head *hea
                timer = list_first_entry(head, struct timer_list, entry);
                detach_timer(timer, 0);
                timer_set_base(timer, new_base);
+               if (time_before(timer->expires, new_base->next_timer) &&
+                   !tbase_get_deferrable(timer->base))
+                       new_base->next_timer = timer->expires;
                internal_add_timer(new_base, timer);
        }
 }
index 1ea0d1234f4a36cb2b0fcb6769ddef83def4d35e..e71634604400c6dd5bb9f7e0a019143ae9c7cc32 100644 (file)
@@ -11,12 +11,18 @@ config NOP_TRACER
 
 config HAVE_FTRACE_NMI_ENTER
        bool
+       help
+         See Documentation/trace/ftrace-implementation.txt
 
 config HAVE_FUNCTION_TRACER
        bool
+       help
+         See Documentation/trace/ftrace-implementation.txt
 
 config HAVE_FUNCTION_GRAPH_TRACER
        bool
+       help
+         See Documentation/trace/ftrace-implementation.txt
 
 config HAVE_FUNCTION_GRAPH_FP_TEST
        bool
@@ -28,21 +34,25 @@ config HAVE_FUNCTION_GRAPH_FP_TEST
 config HAVE_FUNCTION_TRACE_MCOUNT_TEST
        bool
        help
-        This gets selected when the arch tests the function_trace_stop
-        variable at the mcount call site. Otherwise, this variable
-        is tested by the called function.
+         See Documentation/trace/ftrace-implementation.txt
 
 config HAVE_DYNAMIC_FTRACE
        bool
+       help
+         See Documentation/trace/ftrace-implementation.txt
 
 config HAVE_FTRACE_MCOUNT_RECORD
        bool
+       help
+         See Documentation/trace/ftrace-implementation.txt
 
 config HAVE_HW_BRANCH_TRACER
        bool
 
 config HAVE_SYSCALL_TRACEPOINTS
        bool
+       help
+         See Documentation/trace/ftrace-implementation.txt
 
 config TRACER_MAX_TRACE
        bool
@@ -469,6 +479,18 @@ config FTRACE_STARTUP_TEST
          functioning properly. It will do tests on all the configured
          tracers of ftrace.
 
+config EVENT_TRACE_TEST_SYSCALLS
+       bool "Run selftest on syscall events"
+       depends on FTRACE_STARTUP_TEST
+       help
+        This option will also enable testing every syscall event.
+        It only enables the event and disables it and runs various loads
+        with the event enabled. This adds a bit more time for kernel boot
+        up since it runs this on every system call defined.
+
+        TBD - enable a way to actually call the syscalls as we test their
+              events
+
 config MMIOTRACE
        bool "Memory mapped IO tracing"
        depends on HAVE_MMIOTRACE_SUPPORT && PCI
index 8c804e24f96fcbb0c0674e84e0efd62b463071b4..cc615f84751ba1e282d8af7fb3d2ed5ac8b4eae0 100644 (file)
@@ -1323,11 +1323,10 @@ static int __init ftrace_dyn_table_alloc(unsigned long num_to_init)
 
 enum {
        FTRACE_ITER_FILTER      = (1 << 0),
-       FTRACE_ITER_CONT        = (1 << 1),
-       FTRACE_ITER_NOTRACE     = (1 << 2),
-       FTRACE_ITER_FAILURES    = (1 << 3),
-       FTRACE_ITER_PRINTALL    = (1 << 4),
-       FTRACE_ITER_HASH        = (1 << 5),
+       FTRACE_ITER_NOTRACE     = (1 << 1),
+       FTRACE_ITER_FAILURES    = (1 << 2),
+       FTRACE_ITER_PRINTALL    = (1 << 3),
+       FTRACE_ITER_HASH        = (1 << 4),
 };
 
 #define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */
@@ -1337,8 +1336,7 @@ struct ftrace_iterator {
        int                     hidx;
        int                     idx;
        unsigned                flags;
-       unsigned char           buffer[FTRACE_BUFF_MAX+1];
-       unsigned                buffer_idx;
+       struct trace_parser     parser;
 };
 
 static void *
@@ -1407,7 +1405,7 @@ static int t_hash_show(struct seq_file *m, void *v)
        if (rec->ops->print)
                return rec->ops->print(m, rec->ip, rec->ops, rec->data);
 
-       seq_printf(m, "%pf:%pf", (void *)rec->ip, (void *)rec->ops->func);
+       seq_printf(m, "%ps:%ps", (void *)rec->ip, (void *)rec->ops->func);
 
        if (rec->data)
                seq_printf(m, ":%p", rec->data);
@@ -1517,7 +1515,7 @@ static int t_show(struct seq_file *m, void *v)
        if (!rec)
                return 0;
 
-       seq_printf(m, "%pf\n", (void *)rec->ip);
+       seq_printf(m, "%ps\n", (void *)rec->ip);
 
        return 0;
 }
@@ -1604,6 +1602,11 @@ ftrace_regex_open(struct inode *inode, struct file *file, int enable)
        if (!iter)
                return -ENOMEM;
 
+       if (trace_parser_get_init(&iter->parser, FTRACE_BUFF_MAX)) {
+               kfree(iter);
+               return -ENOMEM;
+       }
+
        mutex_lock(&ftrace_regex_lock);
        if ((file->f_mode & FMODE_WRITE) &&
            (file->f_flags & O_TRUNC))
@@ -2059,9 +2062,9 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
        int i, len = 0;
        char *search;
 
-       if (glob && (strcmp(glob, "*") || !strlen(glob)))
+       if (glob && (strcmp(glob, "*") == 0 || !strlen(glob)))
                glob = NULL;
-       else {
+       else if (glob) {
                int not;
 
                type = ftrace_setup_glob(glob, strlen(glob), &search, &not);
@@ -2196,9 +2199,8 @@ ftrace_regex_write(struct file *file, const char __user *ubuf,
                   size_t cnt, loff_t *ppos, int enable)
 {
        struct ftrace_iterator *iter;
-       char ch;
-       size_t read = 0;
-       ssize_t ret;
+       struct trace_parser *parser;
+       ssize_t ret, read;
 
        if (!cnt || cnt < 0)
                return 0;
@@ -2211,72 +2213,23 @@ ftrace_regex_write(struct file *file, const char __user *ubuf,
        } else
                iter = file->private_data;
 
-       if (!*ppos) {
-               iter->flags &= ~FTRACE_ITER_CONT;
-               iter->buffer_idx = 0;
-       }
-
-       ret = get_user(ch, ubuf++);
-       if (ret)
-               goto out;
-       read++;
-       cnt--;
+       parser = &iter->parser;
+       read = trace_get_user(parser, ubuf, cnt, ppos);
 
-       /*
-        * If the parser haven't finished with the last write,
-        * continue reading the user input without skipping spaces.
-        */
-       if (!(iter->flags & FTRACE_ITER_CONT)) {
-               /* skip white space */
-               while (cnt && isspace(ch)) {
-                       ret = get_user(ch, ubuf++);
-                       if (ret)
-                               goto out;
-                       read++;
-                       cnt--;
-               }
-
-               /* only spaces were written */
-               if (isspace(ch)) {
-                       *ppos += read;
-                       ret = read;
-                       goto out;
-               }
-
-               iter->buffer_idx = 0;
-       }
-
-       while (cnt && !isspace(ch)) {
-               if (iter->buffer_idx < FTRACE_BUFF_MAX)
-                       iter->buffer[iter->buffer_idx++] = ch;
-               else {
-                       ret = -EINVAL;
-                       goto out;
-               }
-               ret = get_user(ch, ubuf++);
+       if (trace_parser_loaded(parser) &&
+           !trace_parser_cont(parser)) {
+               ret = ftrace_process_regex(parser->buffer,
+                                          parser->idx, enable);
                if (ret)
                        goto out;
-               read++;
-               cnt--;
-       }
 
-       if (isspace(ch)) {
-               iter->buffer[iter->buffer_idx] = 0;
-               ret = ftrace_process_regex(iter->buffer,
-                                          iter->buffer_idx, enable);
-               if (ret)
-                       goto out;
-               iter->buffer_idx = 0;
-       } else {
-               iter->flags |= FTRACE_ITER_CONT;
-               iter->buffer[iter->buffer_idx++] = ch;
+               trace_parser_clear(parser);
        }
 
-       *ppos += read;
        ret = read;
- out:
-       mutex_unlock(&ftrace_regex_lock);
 
+       mutex_unlock(&ftrace_regex_lock);
+out:
        return ret;
 }
 
@@ -2381,6 +2334,7 @@ ftrace_regex_release(struct inode *inode, struct file *file, int enable)
 {
        struct seq_file *m = (struct seq_file *)file->private_data;
        struct ftrace_iterator *iter;
+       struct trace_parser *parser;
 
        mutex_lock(&ftrace_regex_lock);
        if (file->f_mode & FMODE_READ) {
@@ -2390,9 +2344,10 @@ ftrace_regex_release(struct inode *inode, struct file *file, int enable)
        } else
                iter = file->private_data;
 
-       if (iter->buffer_idx) {
-               iter->buffer[iter->buffer_idx] = 0;
-               ftrace_match_records(iter->buffer, iter->buffer_idx, enable);
+       parser = &iter->parser;
+       if (trace_parser_loaded(parser)) {
+               parser->buffer[parser->idx] = 0;
+               ftrace_match_records(parser->buffer, parser->idx, enable);
        }
 
        mutex_lock(&ftrace_lock);
@@ -2400,7 +2355,9 @@ ftrace_regex_release(struct inode *inode, struct file *file, int enable)
                ftrace_run_update_code(FTRACE_ENABLE_CALLS);
        mutex_unlock(&ftrace_lock);
 
+       trace_parser_put(parser);
        kfree(iter);
+
        mutex_unlock(&ftrace_regex_lock);
        return 0;
 }
@@ -2499,7 +2456,7 @@ static int g_show(struct seq_file *m, void *v)
                return 0;
        }
 
-       seq_printf(m, "%pf\n", v);
+       seq_printf(m, "%ps\n", (void *)*ptr);
 
        return 0;
 }
@@ -2602,12 +2559,10 @@ static ssize_t
 ftrace_graph_write(struct file *file, const char __user *ubuf,
                   size_t cnt, loff_t *ppos)
 {
-       unsigned char buffer[FTRACE_BUFF_MAX+1];
+       struct trace_parser parser;
        unsigned long *array;
        size_t read = 0;
        ssize_t ret;
-       int index = 0;
-       char ch;
 
        if (!cnt || cnt < 0)
                return 0;
@@ -2625,51 +2580,26 @@ ftrace_graph_write(struct file *file, const char __user *ubuf,
        } else
                array = file->private_data;
 
-       ret = get_user(ch, ubuf++);
-       if (ret)
+       if (trace_parser_get_init(&parser, FTRACE_BUFF_MAX)) {
+               ret = -ENOMEM;
                goto out;
-       read++;
-       cnt--;
-
-       /* skip white space */
-       while (cnt && isspace(ch)) {
-               ret = get_user(ch, ubuf++);
-               if (ret)
-                       goto out;
-               read++;
-               cnt--;
        }
 
-       if (isspace(ch)) {
-               *ppos += read;
-               ret = read;
-               goto out;
-       }
+       read = trace_get_user(&parser, ubuf, cnt, ppos);
 
-       while (cnt && !isspace(ch)) {
-               if (index < FTRACE_BUFF_MAX)
-                       buffer[index++] = ch;
-               else {
-                       ret = -EINVAL;
-                       goto out;
-               }
-               ret = get_user(ch, ubuf++);
+       if (trace_parser_loaded((&parser))) {
+               parser.buffer[parser.idx] = 0;
+
+               /* we allow only one expression at a time */
+               ret = ftrace_set_func(array, &ftrace_graph_count,
+                                       parser.buffer);
                if (ret)
                        goto out;
-               read++;
-               cnt--;
        }
-       buffer[index] = 0;
-
-       /* we allow only one expression at a time */
-       ret = ftrace_set_func(array, &ftrace_graph_count, buffer);
-       if (ret)
-               goto out;
-
-       file->f_pos += read;
 
        ret = read;
  out:
+       trace_parser_put(&parser);
        mutex_unlock(&graph_lock);
 
        return ret;
index 454e74e718cfb77b4b2b0824acc93b0ce3f90aa8..6eef38923b07eb9473bbb38fca2ccb8f0643aebe 100644 (file)
@@ -701,8 +701,8 @@ static int rb_head_page_set(struct ring_buffer_per_cpu *cpu_buffer,
 
        val &= ~RB_FLAG_MASK;
 
-       ret = (unsigned long)cmpxchg(&list->next,
-                                    val | old_flag, val | new_flag);
+       ret = cmpxchg((unsigned long *)&list->next,
+                     val | old_flag, val | new_flag);
 
        /* check if the reader took the page */
        if ((ret & ~RB_FLAG_MASK) != val)
@@ -794,7 +794,7 @@ static int rb_head_page_replace(struct buffer_page *old,
        val = *ptr & ~RB_FLAG_MASK;
        val |= RB_PAGE_HEAD;
 
-       ret = cmpxchg(ptr, val, &new->list);
+       ret = cmpxchg(ptr, val, (unsigned long)&new->list);
 
        return ret == val;
 }
@@ -2997,15 +2997,12 @@ static void rb_advance_iter(struct ring_buffer_iter *iter)
 }
 
 static struct ring_buffer_event *
-rb_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts)
+rb_buffer_peek(struct ring_buffer_per_cpu *cpu_buffer, u64 *ts)
 {
-       struct ring_buffer_per_cpu *cpu_buffer;
        struct ring_buffer_event *event;
        struct buffer_page *reader;
        int nr_loops = 0;
 
-       cpu_buffer = buffer->buffers[cpu];
-
  again:
        /*
         * We repeat when a timestamp is encountered. It is possible
@@ -3049,7 +3046,7 @@ rb_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts)
        case RINGBUF_TYPE_DATA:
                if (ts) {
                        *ts = cpu_buffer->read_stamp + event->time_delta;
-                       ring_buffer_normalize_time_stamp(buffer,
+                       ring_buffer_normalize_time_stamp(cpu_buffer->buffer,
                                                         cpu_buffer->cpu, ts);
                }
                return event;
@@ -3168,7 +3165,7 @@ ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts)
        local_irq_save(flags);
        if (dolock)
                spin_lock(&cpu_buffer->reader_lock);
-       event = rb_buffer_peek(buffer, cpu, ts);
+       event = rb_buffer_peek(cpu_buffer, ts);
        if (event && event->type_len == RINGBUF_TYPE_PADDING)
                rb_advance_reader(cpu_buffer);
        if (dolock)
@@ -3237,7 +3234,7 @@ ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts)
        if (dolock)
                spin_lock(&cpu_buffer->reader_lock);
 
-       event = rb_buffer_peek(buffer, cpu, ts);
+       event = rb_buffer_peek(cpu_buffer, ts);
        if (event)
                rb_advance_reader(cpu_buffer);
 
index 5c75deeefe30e7b3c9c6b36c18caf15438f67683..fd52a19dd1725d0c28829b9096eced2e6af9adae 100644 (file)
@@ -339,6 +339,112 @@ static struct {
 
 int trace_clock_id;
 
+/*
+ * trace_parser_get_init - gets the buffer for trace parser
+ */
+int trace_parser_get_init(struct trace_parser *parser, int size)
+{
+       memset(parser, 0, sizeof(*parser));
+
+       parser->buffer = kmalloc(size, GFP_KERNEL);
+       if (!parser->buffer)
+               return 1;
+
+       parser->size = size;
+       return 0;
+}
+
+/*
+ * trace_parser_put - frees the buffer for trace parser
+ */
+void trace_parser_put(struct trace_parser *parser)
+{
+       kfree(parser->buffer);
+}
+
+/*
+ * trace_get_user - reads the user input string separated by  space
+ * (matched by isspace(ch))
+ *
+ * For each string found the 'struct trace_parser' is updated,
+ * and the function returns.
+ *
+ * Returns number of bytes read.
+ *
+ * See kernel/trace/trace.h for 'struct trace_parser' details.
+ */
+int trace_get_user(struct trace_parser *parser, const char __user *ubuf,
+       size_t cnt, loff_t *ppos)
+{
+       char ch;
+       size_t read = 0;
+       ssize_t ret;
+
+       if (!*ppos)
+               trace_parser_clear(parser);
+
+       ret = get_user(ch, ubuf++);
+       if (ret)
+               goto out;
+
+       read++;
+       cnt--;
+
+       /*
+        * The parser is not finished with the last write,
+        * continue reading the user input without skipping spaces.
+        */
+       if (!parser->cont) {
+               /* skip white space */
+               while (cnt && isspace(ch)) {
+                       ret = get_user(ch, ubuf++);
+                       if (ret)
+                               goto out;
+                       read++;
+                       cnt--;
+               }
+
+               /* only spaces were written */
+               if (isspace(ch)) {
+                       *ppos += read;
+                       ret = read;
+                       goto out;
+               }
+
+               parser->idx = 0;
+       }
+
+       /* read the non-space input */
+       while (cnt && !isspace(ch)) {
+               if (parser->idx < parser->size)
+                       parser->buffer[parser->idx++] = ch;
+               else {
+                       ret = -EINVAL;
+                       goto out;
+               }
+               ret = get_user(ch, ubuf++);
+               if (ret)
+                       goto out;
+               read++;
+               cnt--;
+       }
+
+       /* We either got finished input or we have to wait for another call. */
+       if (isspace(ch)) {
+               parser->buffer[parser->idx] = 0;
+               parser->cont = false;
+       } else {
+               parser->cont = true;
+               parser->buffer[parser->idx++] = ch;
+       }
+
+       *ppos += read;
+       ret = read;
+
+out:
+       return ret;
+}
+
 ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, size_t cnt)
 {
        int len;
@@ -719,6 +825,11 @@ static void trace_init_cmdlines(void)
        cmdline_idx = 0;
 }
 
+int is_tracing_stopped(void)
+{
+       return trace_stop_count;
+}
+
 /**
  * ftrace_off_permanent - disable all ftrace code permanently
  *
@@ -886,7 +997,7 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags,
 
        entry->preempt_count            = pc & 0xff;
        entry->pid                      = (tsk) ? tsk->pid : 0;
-       entry->tgid                     = (tsk) ? tsk->tgid : 0;
+       entry->lock_depth               = (tsk) ? tsk->lock_depth : 0;
        entry->flags =
 #ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT
                (irqs_disabled_flags(flags) ? TRACE_FLAG_IRQS_OFF : 0) |
@@ -1068,6 +1179,7 @@ ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, int pc)
                return;
        entry   = ring_buffer_event_data(event);
 
+       entry->tgid             = current->tgid;
        memset(&entry->caller, 0, sizeof(entry->caller));
 
        trace.nr_entries        = 0;
@@ -1094,6 +1206,7 @@ ftrace_trace_special(void *__tr,
                     unsigned long arg1, unsigned long arg2, unsigned long arg3,
                     int pc)
 {
+       struct ftrace_event_call *call = &event_special;
        struct ring_buffer_event *event;
        struct trace_array *tr = __tr;
        struct ring_buffer *buffer = tr->buffer;
@@ -1107,7 +1220,9 @@ ftrace_trace_special(void *__tr,
        entry->arg1                     = arg1;
        entry->arg2                     = arg2;
        entry->arg3                     = arg3;
-       trace_buffer_unlock_commit(buffer, event, 0, pc);
+
+       if (!filter_check_discard(call, entry, buffer, event))
+               trace_buffer_unlock_commit(buffer, event, 0, pc);
 }
 
 void
@@ -1530,10 +1645,10 @@ static void print_lat_help_header(struct seq_file *m)
        seq_puts(m, "#                | / _----=> need-resched    \n");
        seq_puts(m, "#                || / _---=> hardirq/softirq \n");
        seq_puts(m, "#                ||| / _--=> preempt-depth   \n");
-       seq_puts(m, "#                |||| /                      \n");
-       seq_puts(m, "#                |||||     delay             \n");
-       seq_puts(m, "#  cmd     pid   ||||| time  |   caller      \n");
-       seq_puts(m, "#     \\   /      |||||   \\   |   /           \n");
+       seq_puts(m, "#                |||| /_--=> lock-depth       \n");
+       seq_puts(m, "#                |||||/     delay             \n");
+       seq_puts(m, "#  cmd     pid   |||||| time  |   caller      \n");
+       seq_puts(m, "#     \\   /      ||||||   \\   |   /           \n");
 }
 
 static void print_func_help_header(struct seq_file *m)
index fa1dccb579d57c1ff241c317a24ba45b5a545483..86bcff94791ab9c721a4dc982132e746d8b2546c 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/clocksource.h>
 #include <linux/ring_buffer.h>
 #include <linux/mmiotrace.h>
+#include <linux/tracepoint.h>
 #include <linux/ftrace.h>
 #include <trace/boot.h>
 #include <linux/kmemtrace.h>
@@ -42,157 +43,54 @@ enum trace_type {
        __TRACE_LAST_TYPE,
 };
 
-/*
- * Function trace entry - function address and parent function addres:
- */
-struct ftrace_entry {
-       struct trace_entry      ent;
-       unsigned long           ip;
-       unsigned long           parent_ip;
-};
-
-/* Function call entry */
-struct ftrace_graph_ent_entry {
-       struct trace_entry              ent;
-       struct ftrace_graph_ent         graph_ent;
+enum kmemtrace_type_id {
+       KMEMTRACE_TYPE_KMALLOC = 0,     /* kmalloc() or kfree(). */
+       KMEMTRACE_TYPE_CACHE,           /* kmem_cache_*(). */
+       KMEMTRACE_TYPE_PAGES,           /* __get_free_pages() and friends. */
 };
 
-/* Function return entry */
-struct ftrace_graph_ret_entry {
-       struct trace_entry              ent;
-       struct ftrace_graph_ret         ret;
-};
 extern struct tracer boot_tracer;
 
-/*
- * Context switch trace entry - which task (and prio) we switched from/to:
- */
-struct ctx_switch_entry {
-       struct trace_entry      ent;
-       unsigned int            prev_pid;
-       unsigned char           prev_prio;
-       unsigned char           prev_state;
-       unsigned int            next_pid;
-       unsigned char           next_prio;
-       unsigned char           next_state;
-       unsigned int            next_cpu;
-};
-
-/*
- * Special (free-form) trace entry:
- */
-struct special_entry {
-       struct trace_entry      ent;
-       unsigned long           arg1;
-       unsigned long           arg2;
-       unsigned long           arg3;
-};
-
-/*
- * Stack-trace entry:
- */
-
-#define FTRACE_STACK_ENTRIES   8
-
-struct stack_entry {
-       struct trace_entry      ent;
-       unsigned long           caller[FTRACE_STACK_ENTRIES];
-};
-
-struct userstack_entry {
-       struct trace_entry      ent;
-       unsigned long           caller[FTRACE_STACK_ENTRIES];
-};
-
-/*
- * trace_printk entry:
- */
-struct bprint_entry {
-       struct trace_entry      ent;
-       unsigned long           ip;
-       const char              *fmt;
-       u32                     buf[];
-};
+#undef __field
+#define __field(type, item)            type    item;
 
-struct print_entry {
-       struct trace_entry      ent;
-       unsigned long           ip;
-       char                    buf[];
-};
+#undef __field_struct
+#define __field_struct(type, item)     __field(type, item)
 
-#define TRACE_OLD_SIZE         88
+#undef __field_desc
+#define __field_desc(type, container, item)
 
-struct trace_field_cont {
-       unsigned char           type;
-       /* Temporary till we get rid of this completely */
-       char                    buf[TRACE_OLD_SIZE - 1];
-};
+#undef __array
+#define __array(type, item, size)      type    item[size];
 
-struct trace_mmiotrace_rw {
-       struct trace_entry      ent;
-       struct mmiotrace_rw     rw;
-};
+#undef __array_desc
+#define __array_desc(type, container, item, size)
 
-struct trace_mmiotrace_map {
-       struct trace_entry      ent;
-       struct mmiotrace_map    map;
-};
+#undef __dynamic_array
+#define __dynamic_array(type, item)    type    item[];
 
-struct trace_boot_call {
-       struct trace_entry      ent;
-       struct boot_trace_call boot_call;
-};
+#undef F_STRUCT
+#define F_STRUCT(args...)              args
 
-struct trace_boot_ret {
-       struct trace_entry      ent;
-       struct boot_trace_ret boot_ret;
-};
-
-#define TRACE_FUNC_SIZE 30
-#define TRACE_FILE_SIZE 20
-struct trace_branch {
-       struct trace_entry      ent;
-       unsigned                line;
-       char                    func[TRACE_FUNC_SIZE+1];
-       char                    file[TRACE_FILE_SIZE+1];
-       char                    correct;
-};
-
-struct hw_branch_entry {
-       struct trace_entry      ent;
-       u64                     from;
-       u64                     to;
-};
-
-struct trace_power {
-       struct trace_entry      ent;
-       struct power_trace      state_data;
-};
+#undef FTRACE_ENTRY
+#define FTRACE_ENTRY(name, struct_name, id, tstruct, print)    \
+       struct struct_name {                                    \
+               struct trace_entry      ent;                    \
+               tstruct                                         \
+       }
 
-enum kmemtrace_type_id {
-       KMEMTRACE_TYPE_KMALLOC = 0,     /* kmalloc() or kfree(). */
-       KMEMTRACE_TYPE_CACHE,           /* kmem_cache_*(). */
-       KMEMTRACE_TYPE_PAGES,           /* __get_free_pages() and friends. */
-};
+#undef TP_ARGS
+#define TP_ARGS(args...)       args
 
-struct kmemtrace_alloc_entry {
-       struct trace_entry      ent;
-       enum kmemtrace_type_id type_id;
-       unsigned long call_site;
-       const void *ptr;
-       size_t bytes_req;
-       size_t bytes_alloc;
-       gfp_t gfp_flags;
-       int node;
-};
+#undef FTRACE_ENTRY_DUP
+#define FTRACE_ENTRY_DUP(name, name_struct, id, tstruct, printk)
 
-struct kmemtrace_free_entry {
-       struct trace_entry      ent;
-       enum kmemtrace_type_id type_id;
-       unsigned long call_site;
-       const void *ptr;
-};
+#include "trace_entries.h"
 
+/*
+ * syscalls are special, and need special handling, this is why
+ * they are not included in trace_entries.h
+ */
 struct syscall_trace_enter {
        struct trace_entry      ent;
        int                     nr;
@@ -205,13 +103,12 @@ struct syscall_trace_exit {
        unsigned long           ret;
 };
 
-
 /*
  * trace_flag_type is an enumeration that holds different
  * states when a trace occurs. These are:
  *  IRQS_OFF           - interrupts were disabled
  *  IRQS_NOSUPPORT     - arch does not support irqs_disabled_flags
- *  NEED_RESCED                - reschedule is requested
+ *  NEED_RESCHED       - reschedule is requested
  *  HARDIRQ            - inside an interrupt handler
  *  SOFTIRQ            - inside a softirq handler
  */
@@ -390,7 +287,6 @@ struct tracer {
        struct tracer           *next;
        int                     print_max;
        struct tracer_flags     *flags;
-       struct tracer_stat      *stats;
 };
 
 
@@ -469,6 +365,7 @@ void tracing_stop_sched_switch_record(void);
 void tracing_start_sched_switch_record(void);
 int register_tracer(struct tracer *type);
 void unregister_tracer(struct tracer *type);
+int is_tracing_stopped(void);
 
 extern unsigned long nsecs_to_usecs(unsigned long nsecs);
 
@@ -509,20 +406,6 @@ static inline void __trace_stack(struct trace_array *tr, unsigned long flags,
 
 extern cycle_t ftrace_now(int cpu);
 
-#ifdef CONFIG_CONTEXT_SWITCH_TRACER
-typedef void
-(*tracer_switch_func_t)(void *private,
-                       void *__rq,
-                       struct task_struct *prev,
-                       struct task_struct *next);
-
-struct tracer_switch_ops {
-       tracer_switch_func_t            func;
-       void                            *private;
-       struct tracer_switch_ops        *next;
-};
-#endif /* CONFIG_CONTEXT_SWITCH_TRACER */
-
 extern void trace_find_cmdline(int pid, char comm[]);
 
 #ifdef CONFIG_DYNAMIC_FTRACE
@@ -637,6 +520,41 @@ static inline int ftrace_trace_task(struct task_struct *task)
 }
 #endif
 
+/*
+ * struct trace_parser - servers for reading the user input separated by spaces
+ * @cont: set if the input is not complete - no final space char was found
+ * @buffer: holds the parsed user input
+ * @idx: user input lenght
+ * @size: buffer size
+ */
+struct trace_parser {
+       bool            cont;
+       char            *buffer;
+       unsigned        idx;
+       unsigned        size;
+};
+
+static inline bool trace_parser_loaded(struct trace_parser *parser)
+{
+       return (parser->idx != 0);
+}
+
+static inline bool trace_parser_cont(struct trace_parser *parser)
+{
+       return parser->cont;
+}
+
+static inline void trace_parser_clear(struct trace_parser *parser)
+{
+       parser->cont = false;
+       parser->idx = 0;
+}
+
+extern int trace_parser_get_init(struct trace_parser *parser, int size);
+extern void trace_parser_put(struct trace_parser *parser);
+extern int trace_get_user(struct trace_parser *parser, const char __user *ubuf,
+       size_t cnt, loff_t *ppos);
+
 /*
  * trace_iterator_flags is an enumeration that defines bit
  * positions into trace_flags that controls the output.
@@ -823,58 +741,18 @@ filter_check_discard(struct ftrace_event_call *call, void *rec,
        return 0;
 }
 
-#define DEFINE_COMPARISON_PRED(type)                                   \
-static int filter_pred_##type(struct filter_pred *pred, void *event,   \
-                             int val1, int val2)                       \
-{                                                                      \
-       type *addr = (type *)(event + pred->offset);                    \
-       type val = (type)pred->val;                                     \
-       int match = 0;                                                  \
-                                                                       \
-       switch (pred->op) {                                             \
-       case OP_LT:                                                     \
-               match = (*addr < val);                                  \
-               break;                                                  \
-       case OP_LE:                                                     \
-               match = (*addr <= val);                                 \
-               break;                                                  \
-       case OP_GT:                                                     \
-               match = (*addr > val);                                  \
-               break;                                                  \
-       case OP_GE:                                                     \
-               match = (*addr >= val);                                 \
-               break;                                                  \
-       default:                                                        \
-               break;                                                  \
-       }                                                               \
-                                                                       \
-       return match;                                                   \
-}
-
-#define DEFINE_EQUALITY_PRED(size)                                     \
-static int filter_pred_##size(struct filter_pred *pred, void *event,   \
-                             int val1, int val2)                       \
-{                                                                      \
-       u##size *addr = (u##size *)(event + pred->offset);              \
-       u##size val = (u##size)pred->val;                               \
-       int match;                                                      \
-                                                                       \
-       match = (val == *addr) ^ pred->not;                             \
-                                                                       \
-       return match;                                                   \
-}
-
 extern struct mutex event_mutex;
 extern struct list_head ftrace_events;
 
 extern const char *__start___trace_bprintk_fmt[];
 extern const char *__stop___trace_bprintk_fmt[];
 
-#undef TRACE_EVENT_FORMAT
-#define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt)     \
+#undef FTRACE_ENTRY
+#define FTRACE_ENTRY(call, struct_name, id, tstruct, print)            \
        extern struct ftrace_event_call event_##call;
-#undef TRACE_EVENT_FORMAT_NOFILTER
-#define TRACE_EVENT_FORMAT_NOFILTER(call, proto, args, fmt, tstruct, tpfmt)
-#include "trace_event_types.h"
+#undef FTRACE_ENTRY_DUP
+#define FTRACE_ENTRY_DUP(call, struct_name, id, tstruct, print)                \
+       FTRACE_ENTRY(call, struct_name, id, PARAMS(tstruct), PARAMS(print))
+#include "trace_entries.h"
 
 #endif /* _LINUX_KERNEL_TRACE_H */
index 19bfc75d467e34927593243341effcdab9c51747..c21d5f3956ad790f58a3672a94d5ba09243260fe 100644 (file)
@@ -129,6 +129,7 @@ struct tracer boot_tracer __read_mostly =
 
 void trace_boot_call(struct boot_trace_call *bt, initcall_t fn)
 {
+       struct ftrace_event_call *call = &event_boot_call;
        struct ring_buffer_event *event;
        struct ring_buffer *buffer;
        struct trace_boot_call *entry;
@@ -150,13 +151,15 @@ void trace_boot_call(struct boot_trace_call *bt, initcall_t fn)
                goto out;
        entry   = ring_buffer_event_data(event);
        entry->boot_call = *bt;
-       trace_buffer_unlock_commit(buffer, event, 0, 0);
+       if (!filter_check_discard(call, entry, buffer, event))
+               trace_buffer_unlock_commit(buffer, event, 0, 0);
  out:
        preempt_enable();
 }
 
 void trace_boot_ret(struct boot_trace_ret *bt, initcall_t fn)
 {
+       struct ftrace_event_call *call = &event_boot_ret;
        struct ring_buffer_event *event;
        struct ring_buffer *buffer;
        struct trace_boot_ret *entry;
@@ -175,7 +178,8 @@ void trace_boot_ret(struct boot_trace_ret *bt, initcall_t fn)
                goto out;
        entry   = ring_buffer_event_data(event);
        entry->boot_ret = *bt;
-       trace_buffer_unlock_commit(buffer, event, 0, 0);
+       if (!filter_check_discard(call, entry, buffer, event))
+               trace_buffer_unlock_commit(buffer, event, 0, 0);
  out:
        preempt_enable();
 }
index b588fd81f7f996792852e5035278736cdf9bec46..20c5f92e28a8864cc3ca188cc1205200a89b6c55 100644 (file)
@@ -66,10 +66,14 @@ u64 notrace trace_clock(void)
  * Used by plugins that need globally coherent timestamps.
  */
 
-static u64 prev_trace_clock_time;
-
-static raw_spinlock_t trace_clock_lock ____cacheline_aligned_in_smp =
-       (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
+/* keep prev_time and lock in the same cacheline. */
+static struct {
+       u64 prev_time;
+       raw_spinlock_t lock;
+} trace_clock_struct ____cacheline_aligned_in_smp =
+       {
+               .lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED,
+       };
 
 u64 notrace trace_clock_global(void)
 {
@@ -88,19 +92,19 @@ u64 notrace trace_clock_global(void)
        if (unlikely(in_nmi()))
                goto out;
 
-       __raw_spin_lock(&trace_clock_lock);
+       __raw_spin_lock(&trace_clock_struct.lock);
 
        /*
         * TODO: if this happens often then maybe we should reset
-        * my_scd->clock to prev_trace_clock_time+1, to make sure
+        * my_scd->clock to prev_time+1, to make sure
         * we start ticking with the local clock from now on?
         */
-       if ((s64)(now - prev_trace_clock_time) < 0)
-               now = prev_trace_clock_time + 1;
+       if ((s64)(now - trace_clock_struct.prev_time) < 0)
+               now = trace_clock_struct.prev_time + 1;
 
-       prev_trace_clock_time = now;
+       trace_clock_struct.prev_time = now;
 
-       __raw_spin_unlock(&trace_clock_lock);
+       __raw_spin_unlock(&trace_clock_struct.lock);
 
  out:
        raw_local_irq_restore(flags);
diff --git a/kernel/trace/trace_entries.h b/kernel/trace/trace_entries.h
new file mode 100644 (file)
index 0000000..a431748
--- /dev/null
@@ -0,0 +1,383 @@
+/*
+ * This file defines the trace event structures that go into the ring
+ * buffer directly. They are created via macros so that changes for them
+ * appear in the format file. Using macros will automate this process.
+ *
+ * The macro used to create a ftrace data structure is:
+ *
+ * FTRACE_ENTRY( name, struct_name, id, structure, print )
+ *
+ * @name: the name used the event name, as well as the name of
+ *   the directory that holds the format file.
+ *
+ * @struct_name: the name of the structure that is created.
+ *
+ * @id: The event identifier that is used to detect what event
+ *    this is from the ring buffer.
+ *
+ * @structure: the structure layout
+ *
+ *  - __field( type,   item    )
+ *       This is equivalent to declaring
+ *             type    item;
+ *       in the structure.
+ *  - __array( type,   item,   size    )
+ *       This is equivalent to declaring
+ *             type    item[size];
+ *       in the structure.
+ *
+ *   * for structures within structures, the format of the internal
+ *     structure is layed out. This allows the internal structure
+ *     to be deciphered for the format file. Although these macros
+ *     may become out of sync with the internal structure, they
+ *     will create a compile error if it happens. Since the
+ *     internel structures are just tracing helpers, this is not
+ *     an issue.
+ *
+ *     When an internal structure is used, it should use:
+ *
+ *     __field_struct( type,   item    )
+ *
+ *     instead of __field. This will prevent it from being shown in
+ *     the output file. The fields in the structure should use.
+ *
+ *     __field_desc(   type,   container,      item            )
+ *     __array_desc(   type,   container,      item,   len     )
+ *
+ *     type, item and len are the same as __field and __array, but
+ *     container is added. This is the name of the item in
+ *     __field_struct that this is describing.
+ *
+ *
+ * @print: the print format shown to users in the format file.
+ */
+
+/*
+ * Function trace entry - function address and parent function addres:
+ */
+FTRACE_ENTRY(function, ftrace_entry,
+
+       TRACE_FN,
+
+       F_STRUCT(
+               __field(        unsigned long,  ip              )
+               __field(        unsigned long,  parent_ip       )
+       ),
+
+       F_printk(" %lx <-- %lx", __entry->ip, __entry->parent_ip)
+);
+
+/* Function call entry */
+FTRACE_ENTRY(funcgraph_entry, ftrace_graph_ent_entry,
+
+       TRACE_GRAPH_ENT,
+
+       F_STRUCT(
+               __field_struct( struct ftrace_graph_ent,        graph_ent       )
+               __field_desc(   unsigned long,  graph_ent,      func            )
+               __field_desc(   int,            graph_ent,      depth           )
+       ),
+
+       F_printk("--> %lx (%d)", __entry->func, __entry->depth)
+);
+
+/* Function return entry */
+FTRACE_ENTRY(funcgraph_exit, ftrace_graph_ret_entry,
+
+       TRACE_GRAPH_RET,
+
+       F_STRUCT(
+               __field_struct( struct ftrace_graph_ret,        ret     )
+               __field_desc(   unsigned long,  ret,            func    )
+               __field_desc(   unsigned long long, ret,        calltime)
+               __field_desc(   unsigned long long, ret,        rettime )
+               __field_desc(   unsigned long,  ret,            overrun )
+               __field_desc(   int,            ret,            depth   )
+       ),
+
+       F_printk("<-- %lx (%d) (start: %llx  end: %llx) over: %d",
+                __entry->func, __entry->depth,
+                __entry->calltime, __entry->rettime,
+                __entry->depth)
+);
+
+/*
+ * Context switch trace entry - which task (and prio) we switched from/to:
+ *
+ * This is used for both wakeup and context switches. We only want
+ * to create one structure, but we need two outputs for it.
+ */
+#define FTRACE_CTX_FIELDS                                      \
+       __field(        unsigned int,   prev_pid        )       \
+       __field(        unsigned char,  prev_prio       )       \
+       __field(        unsigned char,  prev_state      )       \
+       __field(        unsigned int,   next_pid        )       \
+       __field(        unsigned char,  next_prio       )       \
+       __field(        unsigned char,  next_state      )       \
+       __field(        unsigned int,   next_cpu        )
+
+FTRACE_ENTRY(context_switch, ctx_switch_entry,
+
+       TRACE_CTX,
+
+       F_STRUCT(
+               FTRACE_CTX_FIELDS
+       ),
+
+       F_printk("%u:%u:%u  ==> %u:%u:%u [%03u]",
+                __entry->prev_pid, __entry->prev_prio, __entry->prev_state,
+                __entry->next_pid, __entry->next_prio, __entry->next_state,
+                __entry->next_cpu
+               )
+);
+
+/*
+ * FTRACE_ENTRY_DUP only creates the format file, it will not
+ *  create another structure.
+ */
+FTRACE_ENTRY_DUP(wakeup, ctx_switch_entry,
+
+       TRACE_WAKE,
+
+       F_STRUCT(
+               FTRACE_CTX_FIELDS
+       ),
+
+       F_printk("%u:%u:%u  ==+ %u:%u:%u [%03u]",
+                __entry->prev_pid, __entry->prev_prio, __entry->prev_state,
+                __entry->next_pid, __entry->next_prio, __entry->next_state,
+                __entry->next_cpu
+               )
+);
+
+/*
+ * Special (free-form) trace entry:
+ */
+FTRACE_ENTRY(special, special_entry,
+
+       TRACE_SPECIAL,
+
+       F_STRUCT(
+               __field(        unsigned long,  arg1    )
+               __field(        unsigned long,  arg2    )
+               __field(        unsigned long,  arg3    )
+       ),
+
+       F_printk("(%08lx) (%08lx) (%08lx)",
+                __entry->arg1, __entry->arg2, __entry->arg3)
+);
+
+/*
+ * Stack-trace entry:
+ */
+
+#define FTRACE_STACK_ENTRIES   8
+
+FTRACE_ENTRY(kernel_stack, stack_entry,
+
+       TRACE_STACK,
+
+       F_STRUCT(
+               __array(        unsigned long,  caller, FTRACE_STACK_ENTRIES    )
+       ),
+
+       F_printk("\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n"
+                "\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n",
+                __entry->caller[0], __entry->caller[1], __entry->caller[2],
+                __entry->caller[3], __entry->caller[4], __entry->caller[5],
+                __entry->caller[6], __entry->caller[7])
+);
+
+FTRACE_ENTRY(user_stack, userstack_entry,
+
+       TRACE_USER_STACK,
+
+       F_STRUCT(
+               __field(        unsigned int,   tgid    )
+               __array(        unsigned long,  caller, FTRACE_STACK_ENTRIES    )
+       ),
+
+       F_printk("\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n"
+                "\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n",
+                __entry->caller[0], __entry->caller[1], __entry->caller[2],
+                __entry->caller[3], __entry->caller[4], __entry->caller[5],
+                __entry->caller[6], __entry->caller[7])
+);
+
+/*
+ * trace_printk entry:
+ */
+FTRACE_ENTRY(bprint, bprint_entry,
+
+       TRACE_BPRINT,
+
+       F_STRUCT(
+               __field(        unsigned long,  ip      )
+               __field(        const char *,   fmt     )
+               __dynamic_array(        u32,    buf     )
+       ),
+
+       F_printk("%08lx fmt:%p",
+                __entry->ip, __entry->fmt)
+);
+
+FTRACE_ENTRY(print, print_entry,
+
+       TRACE_PRINT,
+
+       F_STRUCT(
+               __field(        unsigned long,  ip      )
+               __dynamic_array(        char,   buf     )
+       ),
+
+       F_printk("%08lx %s",
+                __entry->ip, __entry->buf)
+);
+
+FTRACE_ENTRY(mmiotrace_rw, trace_mmiotrace_rw,
+
+       TRACE_MMIO_RW,
+
+       F_STRUCT(
+               __field_struct( struct mmiotrace_rw,    rw      )
+               __field_desc(   resource_size_t, rw,    phys    )
+               __field_desc(   unsigned long,  rw,     value   )
+               __field_desc(   unsigned long,  rw,     pc      )
+               __field_desc(   int,            rw,     map_id  )
+               __field_desc(   unsigned char,  rw,     opcode  )
+               __field_desc(   unsigned char,  rw,     width   )
+       ),
+
+       F_printk("%lx %lx %lx %d %x %x",
+                (unsigned long)__entry->phys, __entry->value, __entry->pc,
+                __entry->map_id, __entry->opcode, __entry->width)
+);
+
+FTRACE_ENTRY(mmiotrace_map, trace_mmiotrace_map,
+
+       TRACE_MMIO_MAP,
+
+       F_STRUCT(
+               __field_struct( struct mmiotrace_map,   map     )
+               __field_desc(   resource_size_t, map,   phys    )
+               __field_desc(   unsigned long,  map,    virt    )
+               __field_desc(   unsigned long,  map,    len     )
+               __field_desc(   int,            map,    map_id  )
+               __field_desc(   unsigned char,  map,    opcode  )
+       ),
+
+       F_printk("%lx %lx %lx %d %x",
+                (unsigned long)__entry->phys, __entry->virt, __entry->len,
+                __entry->map_id, __entry->opcode)
+);
+
+FTRACE_ENTRY(boot_call, trace_boot_call,
+
+       TRACE_BOOT_CALL,
+
+       F_STRUCT(
+               __field_struct( struct boot_trace_call, boot_call       )
+               __field_desc(   pid_t,  boot_call,      caller          )
+               __array_desc(   char,   boot_call,      func,   KSYM_SYMBOL_LEN)
+       ),
+
+       F_printk("%d  %s", __entry->caller, __entry->func)
+);
+
+FTRACE_ENTRY(boot_ret, trace_boot_ret,
+
+       TRACE_BOOT_RET,
+
+       F_STRUCT(
+               __field_struct( struct boot_trace_ret,  boot_ret        )
+               __array_desc(   char,   boot_ret,       func,   KSYM_SYMBOL_LEN)
+               __field_desc(   int,    boot_ret,       result          )
+               __field_desc(   unsigned long, boot_ret, duration       )
+       ),
+
+       F_printk("%s %d %lx",
+                __entry->func, __entry->result, __entry->duration)
+);
+
+#define TRACE_FUNC_SIZE 30
+#define TRACE_FILE_SIZE 20
+
+FTRACE_ENTRY(branch, trace_branch,
+
+       TRACE_BRANCH,
+
+       F_STRUCT(
+               __field(        unsigned int,   line                            )
+               __array(        char,           func,   TRACE_FUNC_SIZE+1       )
+               __array(        char,           file,   TRACE_FILE_SIZE+1       )
+               __field(        char,           correct                         )
+       ),
+
+       F_printk("%u:%s:%s (%u)",
+                __entry->line,
+                __entry->func, __entry->file, __entry->correct)
+);
+
+FTRACE_ENTRY(hw_branch, hw_branch_entry,
+
+       TRACE_HW_BRANCHES,
+
+       F_STRUCT(
+               __field(        u64,    from    )
+               __field(        u64,    to      )
+       ),
+
+       F_printk("from: %llx to: %llx", __entry->from, __entry->to)
+);
+
+FTRACE_ENTRY(power, trace_power,
+
+       TRACE_POWER,
+
+       F_STRUCT(
+               __field_struct( struct power_trace,     state_data      )
+               __field_desc(   s64,    state_data,     stamp           )
+               __field_desc(   s64,    state_data,     end             )
+               __field_desc(   int,    state_data,     type            )
+               __field_desc(   int,    state_data,     state           )
+       ),
+
+       F_printk("%llx->%llx type:%u state:%u",
+                __entry->stamp, __entry->end,
+                __entry->type, __entry->state)
+);
+
+FTRACE_ENTRY(kmem_alloc, kmemtrace_alloc_entry,
+
+       TRACE_KMEM_ALLOC,
+
+       F_STRUCT(
+               __field(        enum kmemtrace_type_id, type_id         )
+               __field(        unsigned long,          call_site       )
+               __field(        const void *,           ptr             )
+               __field(        size_t,                 bytes_req       )
+               __field(        size_t,                 bytes_alloc     )
+               __field(        gfp_t,                  gfp_flags       )
+               __field(        int,                    node            )
+       ),
+
+       F_printk("type:%u call_site:%lx ptr:%p req:%zi alloc:%zi"
+                " flags:%x node:%d",
+                __entry->type_id, __entry->call_site, __entry->ptr,
+                __entry->bytes_req, __entry->bytes_alloc,
+                __entry->gfp_flags, __entry->node)
+);
+
+FTRACE_ENTRY(kmem_free, kmemtrace_free_entry,
+
+       TRACE_KMEM_FREE,
+
+       F_STRUCT(
+               __field(        enum kmemtrace_type_id, type_id         )
+               __field(        unsigned long,          call_site       )
+               __field(        const void *,           ptr             )
+       ),
+
+       F_printk("type:%u call_site:%lx ptr:%p",
+                __entry->type_id, __entry->call_site, __entry->ptr)
+);
index 11ba5bb4ed0a71f0c3da5e8a2ce73471456aec47..55a25c933d159d5a289265e604d608d96277e63c 100644 (file)
@@ -5,6 +5,7 @@
  *
  */
 
+#include <linux/module.h>
 #include "trace.h"
 
 int ftrace_profile_enable(int event_id)
@@ -14,7 +15,8 @@ int ftrace_profile_enable(int event_id)
 
        mutex_lock(&event_mutex);
        list_for_each_entry(event, &ftrace_events, list) {
-               if (event->id == event_id && event->profile_enable) {
+               if (event->id == event_id && event->profile_enable &&
+                   try_module_get(event->mod)) {
                        ret = event->profile_enable(event);
                        break;
                }
@@ -32,6 +34,7 @@ void ftrace_profile_disable(int event_id)
        list_for_each_entry(event, &ftrace_events, list) {
                if (event->id == event_id) {
                        event->profile_disable(event);
+                       module_put(event->mod);
                        break;
                }
        }
diff --git a/kernel/trace/trace_event_types.h b/kernel/trace/trace_event_types.h
deleted file mode 100644 (file)
index 6db005e..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-#undef TRACE_SYSTEM
-#define TRACE_SYSTEM   ftrace
-
-/*
- * We cheat and use the proto type field as the ID
- * and args as the entry type (minus 'struct')
- */
-TRACE_EVENT_FORMAT(function, TRACE_FN, ftrace_entry, ignore,
-       TRACE_STRUCT(
-               TRACE_FIELD(unsigned long, ip, ip)
-               TRACE_FIELD(unsigned long, parent_ip, parent_ip)
-       ),
-       TP_RAW_FMT(" %lx <-- %lx")
-);
-
-TRACE_EVENT_FORMAT(funcgraph_entry, TRACE_GRAPH_ENT,
-                  ftrace_graph_ent_entry, ignore,
-       TRACE_STRUCT(
-               TRACE_FIELD(unsigned long, graph_ent.func, func)
-               TRACE_FIELD(int, graph_ent.depth, depth)
-       ),
-       TP_RAW_FMT("--> %lx (%d)")
-);
-
-TRACE_EVENT_FORMAT(funcgraph_exit, TRACE_GRAPH_RET,
-                  ftrace_graph_ret_entry, ignore,
-       TRACE_STRUCT(
-               TRACE_FIELD(unsigned long, ret.func, func)
-               TRACE_FIELD(unsigned long long, ret.calltime, calltime)
-               TRACE_FIELD(unsigned long long, ret.rettime, rettime)
-               TRACE_FIELD(unsigned long, ret.overrun, overrun)
-               TRACE_FIELD(int, ret.depth, depth)
-       ),
-       TP_RAW_FMT("<-- %lx (%d)")
-);
-
-TRACE_EVENT_FORMAT(wakeup, TRACE_WAKE, ctx_switch_entry, ignore,
-       TRACE_STRUCT(
-               TRACE_FIELD(unsigned int, prev_pid, prev_pid)
-               TRACE_FIELD(unsigned char, prev_prio, prev_prio)
-               TRACE_FIELD(unsigned char, prev_state, prev_state)
-               TRACE_FIELD(unsigned int, next_pid, next_pid)
-               TRACE_FIELD(unsigned char, next_prio, next_prio)
-               TRACE_FIELD(unsigned char, next_state, next_state)
-               TRACE_FIELD(unsigned int, next_cpu, next_cpu)
-       ),
-       TP_RAW_FMT("%u:%u:%u  ==+ %u:%u:%u [%03u]")
-);
-
-TRACE_EVENT_FORMAT(context_switch, TRACE_CTX, ctx_switch_entry, ignore,
-       TRACE_STRUCT(
-               TRACE_FIELD(unsigned int, prev_pid, prev_pid)
-               TRACE_FIELD(unsigned char, prev_prio, prev_prio)
-               TRACE_FIELD(unsigned char, prev_state, prev_state)
-               TRACE_FIELD(unsigned int, next_pid, next_pid)
-               TRACE_FIELD(unsigned char, next_prio, next_prio)
-               TRACE_FIELD(unsigned char, next_state, next_state)
-               TRACE_FIELD(unsigned int, next_cpu, next_cpu)
-       ),
-       TP_RAW_FMT("%u:%u:%u  ==+ %u:%u:%u [%03u]")
-);
-
-TRACE_EVENT_FORMAT_NOFILTER(special, TRACE_SPECIAL, special_entry, ignore,
-       TRACE_STRUCT(
-               TRACE_FIELD(unsigned long, arg1, arg1)
-               TRACE_FIELD(unsigned long, arg2, arg2)
-               TRACE_FIELD(unsigned long, arg3, arg3)
-       ),
-       TP_RAW_FMT("(%08lx) (%08lx) (%08lx)")
-);
-
-/*
- * Stack-trace entry:
- */
-
-/* #define FTRACE_STACK_ENTRIES   8 */
-
-TRACE_EVENT_FORMAT(kernel_stack, TRACE_STACK, stack_entry, ignore,
-       TRACE_STRUCT(
-               TRACE_FIELD(unsigned long, caller[0], stack0)
-               TRACE_FIELD(unsigned long, caller[1], stack1)
-               TRACE_FIELD(unsigned long, caller[2], stack2)
-               TRACE_FIELD(unsigned long, caller[3], stack3)
-               TRACE_FIELD(unsigned long, caller[4], stack4)
-               TRACE_FIELD(unsigned long, caller[5], stack5)
-               TRACE_FIELD(unsigned long, caller[6], stack6)
-               TRACE_FIELD(unsigned long, caller[7], stack7)
-       ),
-       TP_RAW_FMT("\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n"
-                "\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n")
-);
-
-TRACE_EVENT_FORMAT(user_stack, TRACE_USER_STACK, userstack_entry, ignore,
-       TRACE_STRUCT(
-               TRACE_FIELD(unsigned long, caller[0], stack0)
-               TRACE_FIELD(unsigned long, caller[1], stack1)
-               TRACE_FIELD(unsigned long, caller[2], stack2)
-               TRACE_FIELD(unsigned long, caller[3], stack3)
-               TRACE_FIELD(unsigned long, caller[4], stack4)
-               TRACE_FIELD(unsigned long, caller[5], stack5)
-               TRACE_FIELD(unsigned long, caller[6], stack6)
-               TRACE_FIELD(unsigned long, caller[7], stack7)
-       ),
-       TP_RAW_FMT("\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n"
-                "\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n")
-);
-
-TRACE_EVENT_FORMAT(bprint, TRACE_BPRINT, bprint_entry, ignore,
-       TRACE_STRUCT(
-               TRACE_FIELD(unsigned long, ip, ip)
-               TRACE_FIELD(char *, fmt, fmt)
-               TRACE_FIELD_ZERO_CHAR(buf)
-       ),
-       TP_RAW_FMT("%08lx (%d) fmt:%p %s")
-);
-
-TRACE_EVENT_FORMAT(print, TRACE_PRINT, print_entry, ignore,
-       TRACE_STRUCT(
-               TRACE_FIELD(unsigned long, ip, ip)
-               TRACE_FIELD_ZERO_CHAR(buf)
-       ),
-       TP_RAW_FMT("%08lx (%d) fmt:%p %s")
-);
-
-TRACE_EVENT_FORMAT(branch, TRACE_BRANCH, trace_branch, ignore,
-       TRACE_STRUCT(
-               TRACE_FIELD(unsigned int, line, line)
-               TRACE_FIELD_SPECIAL(char func[TRACE_FUNC_SIZE+1], func,
-                                   TRACE_FUNC_SIZE+1, func)
-               TRACE_FIELD_SPECIAL(char file[TRACE_FUNC_SIZE+1], file,
-                                   TRACE_FUNC_SIZE+1, file)
-               TRACE_FIELD(char, correct, correct)
-       ),
-       TP_RAW_FMT("%u:%s:%s (%u)")
-);
-
-TRACE_EVENT_FORMAT(hw_branch, TRACE_HW_BRANCHES, hw_branch_entry, ignore,
-       TRACE_STRUCT(
-               TRACE_FIELD(u64, from, from)
-               TRACE_FIELD(u64, to, to)
-       ),
-       TP_RAW_FMT("from: %llx to: %llx")
-);
-
-TRACE_EVENT_FORMAT(power, TRACE_POWER, trace_power, ignore,
-       TRACE_STRUCT(
-               TRACE_FIELD_SIGN(ktime_t, state_data.stamp, stamp, 1)
-               TRACE_FIELD_SIGN(ktime_t, state_data.end, end, 1)
-               TRACE_FIELD(int, state_data.type, type)
-               TRACE_FIELD(int, state_data.state, state)
-       ),
-       TP_RAW_FMT("%llx->%llx type:%u state:%u")
-);
-
-TRACE_EVENT_FORMAT(kmem_alloc, TRACE_KMEM_ALLOC, kmemtrace_alloc_entry, ignore,
-       TRACE_STRUCT(
-               TRACE_FIELD(enum kmemtrace_type_id, type_id, type_id)
-               TRACE_FIELD(unsigned long, call_site, call_site)
-               TRACE_FIELD(const void *, ptr, ptr)
-               TRACE_FIELD(size_t, bytes_req, bytes_req)
-               TRACE_FIELD(size_t, bytes_alloc, bytes_alloc)
-               TRACE_FIELD(gfp_t, gfp_flags, gfp_flags)
-               TRACE_FIELD(int, node, node)
-       ),
-       TP_RAW_FMT("type:%u call_site:%lx ptr:%p req:%lu alloc:%lu"
-                " flags:%x node:%d")
-);
-
-TRACE_EVENT_FORMAT(kmem_free, TRACE_KMEM_FREE, kmemtrace_free_entry, ignore,
-       TRACE_STRUCT(
-               TRACE_FIELD(enum kmemtrace_type_id, type_id, type_id)
-               TRACE_FIELD(unsigned long, call_site, call_site)
-               TRACE_FIELD(const void *, ptr, ptr)
-       ),
-       TP_RAW_FMT("type:%u call_site:%lx ptr:%p")
-);
-
-#undef TRACE_SYSTEM
index 97e2c4d2e9ebdfeed72e8518a34e0e25f6b045d4..56c260b83a9cc8a4fa76a44a387cbc68691ae2ff 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "trace_output.h"
 
+#undef TRACE_SYSTEM
 #define TRACE_SYSTEM "TRACE_SYSTEM"
 
 DEFINE_MUTEX(event_mutex);
@@ -86,7 +87,7 @@ int trace_define_common_fields(struct ftrace_event_call *call)
        __common_field(unsigned char, flags);
        __common_field(unsigned char, preempt_count);
        __common_field(int, pid);
-       __common_field(int, tgid);
+       __common_field(int, lock_depth);
 
        return ret;
 }
@@ -230,11 +231,9 @@ static ssize_t
 ftrace_event_write(struct file *file, const char __user *ubuf,
                   size_t cnt, loff_t *ppos)
 {
+       struct trace_parser parser;
        size_t read = 0;
-       int i, set = 1;
        ssize_t ret;
-       char *buf;
-       char ch;
 
        if (!cnt || cnt < 0)
                return 0;
@@ -243,60 +242,28 @@ ftrace_event_write(struct file *file, const char __user *ubuf,
        if (ret < 0)
                return ret;
 
-       ret = get_user(ch, ubuf++);
-       if (ret)
-               return ret;
-       read++;
-       cnt--;
-
-       /* skip white space */
-       while (cnt && isspace(ch)) {
-               ret = get_user(ch, ubuf++);
-               if (ret)
-                       return ret;
-               read++;
-               cnt--;
-       }
-
-       /* Only white space found? */
-       if (isspace(ch)) {
-               file->f_pos += read;
-               ret = read;
-               return ret;
-       }
-
-       buf = kmalloc(EVENT_BUF_SIZE+1, GFP_KERNEL);
-       if (!buf)
+       if (trace_parser_get_init(&parser, EVENT_BUF_SIZE + 1))
                return -ENOMEM;
 
-       if (cnt > EVENT_BUF_SIZE)
-               cnt = EVENT_BUF_SIZE;
+       read = trace_get_user(&parser, ubuf, cnt, ppos);
+
+       if (trace_parser_loaded((&parser))) {
+               int set = 1;
 
-       i = 0;
-       while (cnt && !isspace(ch)) {
-               if (!i && ch == '!')
+               if (*parser.buffer == '!')
                        set = 0;
-               else
-                       buf[i++] = ch;
 
-               ret = get_user(ch, ubuf++);
+               parser.buffer[parser.idx] = 0;
+
+               ret = ftrace_set_clr_event(parser.buffer + !set, set);
                if (ret)
-                       goto out_free;
-               read++;
-               cnt--;
+                       goto out_put;
        }
-       buf[i] = 0;
-
-       file->f_pos += read;
-
-       ret = ftrace_set_clr_event(buf, set);
-       if (ret)
-               goto out_free;
 
        ret = read;
 
- out_free:
-       kfree(buf);
+ out_put:
+       trace_parser_put(&parser);
 
        return ret;
 }
@@ -578,7 +545,7 @@ static int trace_write_header(struct trace_seq *s)
                                FIELD(unsigned char, flags),
                                FIELD(unsigned char, preempt_count),
                                FIELD(int, pid),
-                               FIELD(int, tgid));
+                               FIELD(int, lock_depth));
 }
 
 static ssize_t
@@ -1187,7 +1154,7 @@ static int trace_module_notify(struct notifier_block *self,
 }
 #endif /* CONFIG_MODULES */
 
-struct notifier_block trace_module_nb = {
+static struct notifier_block trace_module_nb = {
        .notifier_call = trace_module_notify,
        .priority = 0,
 };
@@ -1359,6 +1326,18 @@ static __init void event_trace_self_tests(void)
                if (!call->regfunc)
                        continue;
 
+/*
+ * Testing syscall events here is pretty useless, but
+ * we still do it if configured. But this is time consuming.
+ * What we really need is a user thread to perform the
+ * syscalls as we test.
+ */
+#ifndef CONFIG_EVENT_TRACE_TEST_SYSCALLS
+               if (call->system &&
+                   strcmp(call->system, "syscalls") == 0)
+                       continue;
+#endif
+
                pr_info("Testing event %s: ", call->name);
 
                /*
index 93660fbbf6297dff7894453c32d1942e1840d286..23245785927f8dfb6810313db3fcc19f3aa0d8e6 100644 (file)
@@ -121,6 +121,47 @@ struct filter_parse_state {
        } operand;
 };
 
+#define DEFINE_COMPARISON_PRED(type)                                   \
+static int filter_pred_##type(struct filter_pred *pred, void *event,   \
+                             int val1, int val2)                       \
+{                                                                      \
+       type *addr = (type *)(event + pred->offset);                    \
+       type val = (type)pred->val;                                     \
+       int match = 0;                                                  \
+                                                                       \
+       switch (pred->op) {                                             \
+       case OP_LT:                                                     \
+               match = (*addr < val);                                  \
+               break;                                                  \
+       case OP_LE:                                                     \
+               match = (*addr <= val);                                 \
+               break;                                                  \
+       case OP_GT:                                                     \
+               match = (*addr > val);                                  \
+               break;                                                  \
+       case OP_GE:                                                     \
+               match = (*addr >= val);                                 \
+               break;                                                  \
+       default:                                                        \
+               break;                                                  \
+       }                                                               \
+                                                                       \
+       return match;                                                   \
+}
+
+#define DEFINE_EQUALITY_PRED(size)                                     \
+static int filter_pred_##size(struct filter_pred *pred, void *event,   \
+                             int val1, int val2)                       \
+{                                                                      \
+       u##size *addr = (u##size *)(event + pred->offset);              \
+       u##size val = (u##size)pred->val;                               \
+       int match;                                                      \
+                                                                       \
+       match = (val == *addr) ^ pred->not;                             \
+                                                                       \
+       return match;                                                   \
+}
+
 DEFINE_COMPARISON_PRED(s64);
 DEFINE_COMPARISON_PRED(u64);
 DEFINE_COMPARISON_PRED(s32);
index df1bf6e48bb9dc88b5c4704fec2aac8c95f8fa78..9753fcc61bc55b4577527f1ef8ef4853cba7406f 100644 (file)
 
 #include "trace_output.h"
 
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM   ftrace
 
-#undef TRACE_STRUCT
-#define TRACE_STRUCT(args...) args
+/* not needed for this file */
+#undef __field_struct
+#define __field_struct(type, item)
 
-extern void __bad_type_size(void);
+#undef __field
+#define __field(type, item)                            type item;
 
-#undef TRACE_FIELD
-#define TRACE_FIELD(type, item, assign)                                        \
-       if (sizeof(type) != sizeof(field.item))                         \
-               __bad_type_size();                                      \
+#undef __field_desc
+#define __field_desc(type, container, item)            type item;
+
+#undef __array
+#define __array(type, item, size)                      type item[size];
+
+#undef __array_desc
+#define __array_desc(type, container, item, size)      type item[size];
+
+#undef __dynamic_array
+#define __dynamic_array(type, item)                    type item[];
+
+#undef F_STRUCT
+#define F_STRUCT(args...)                              args
+
+#undef F_printk
+#define F_printk(fmt, args...) fmt, args
+
+#undef FTRACE_ENTRY
+#define FTRACE_ENTRY(name, struct_name, id, tstruct, print)    \
+struct ____ftrace_##name {                                     \
+       tstruct                                                 \
+};                                                             \
+static void __used ____ftrace_check_##name(void)               \
+{                                                              \
+       struct ____ftrace_##name *__entry = NULL;               \
+                                                               \
+       /* force cmpile-time check on F_printk() */             \
+       printk(print);                                          \
+}
+
+#undef FTRACE_ENTRY_DUP
+#define FTRACE_ENTRY_DUP(name, struct_name, id, tstruct, print)        \
+       FTRACE_ENTRY(name, struct_name, id, PARAMS(tstruct), PARAMS(print))
+
+#include "trace_entries.h"
+
+
+#undef __field
+#define __field(type, item)                                            \
        ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t"      \
-                              "offset:%u;\tsize:%u;\n",                \
-                              (unsigned int)offsetof(typeof(field), item), \
-                              (unsigned int)sizeof(field.item));       \
+                              "offset:%zu;\tsize:%zu;\n",              \
+                              offsetof(typeof(field), item),           \
+                              sizeof(field.item));                     \
        if (!ret)                                                       \
                return 0;
 
+#undef __field_desc
+#define __field_desc(type, container, item)                            \
+       ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t"      \
+                              "offset:%zu;\tsize:%zu;\n",              \
+                              offsetof(typeof(field), container.item), \
+                              sizeof(field.container.item));           \
+       if (!ret)                                                       \
+               return 0;
 
-#undef TRACE_FIELD_SPECIAL
-#define TRACE_FIELD_SPECIAL(type_item, item, len, cmd)                 \
-       ret = trace_seq_printf(s, "\tfield special:" #type_item ";\t"   \
-                              "offset:%u;\tsize:%u;\n",                \
-                              (unsigned int)offsetof(typeof(field), item), \
-                              (unsigned int)sizeof(field.item));       \
+#undef __array
+#define __array(type, item, len)                                       \
+       ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \
+                              "offset:%zu;\tsize:%zu;\n",              \
+                              offsetof(typeof(field), item),   \
+                              sizeof(field.item));             \
        if (!ret)                                                       \
                return 0;
 
-#undef TRACE_FIELD_ZERO_CHAR
-#define TRACE_FIELD_ZERO_CHAR(item)                                    \
-       ret = trace_seq_printf(s, "\tfield:char " #item ";\t"           \
-                              "offset:%u;\tsize:0;\n",                 \
-                              (unsigned int)offsetof(typeof(field), item)); \
+#undef __array_desc
+#define __array_desc(type, container, item, len)                       \
+       ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \
+                              "offset:%zu;\tsize:%zu;\n",              \
+                              offsetof(typeof(field), container.item), \
+                              sizeof(field.container.item));           \
        if (!ret)                                                       \
                return 0;
 
-#undef TRACE_FIELD_SIGN
-#define TRACE_FIELD_SIGN(type, item, assign, is_signed)        \
-       TRACE_FIELD(type, item, assign)
+#undef __dynamic_array
+#define __dynamic_array(type, item)                                    \
+       ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t"      \
+                              "offset:%zu;\tsize:0;\n",                \
+                              offsetof(typeof(field), item));          \
+       if (!ret)                                                       \
+               return 0;
 
-#undef TP_RAW_FMT
-#define TP_RAW_FMT(args...) args
+#undef F_printk
+#define F_printk(fmt, args...) "%s, %s\n", #fmt, __stringify(args)
 
-#undef TRACE_EVENT_FORMAT
-#define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt)     \
-static int                                                             \
-ftrace_format_##call(struct ftrace_event_call *unused,                 \
-                     struct trace_seq *s)                              \
-{                                                                      \
-       struct args field;                                              \
-       int ret;                                                        \
-                                                                       \
-       tstruct;                                                        \
-                                                                       \
-       trace_seq_printf(s, "\nprint fmt: \"%s\"\n", tpfmt);            \
-                                                                       \
-       return ret;                                                     \
-}
+#undef __entry
+#define __entry REC
 
-#undef TRACE_EVENT_FORMAT_NOFILTER
-#define TRACE_EVENT_FORMAT_NOFILTER(call, proto, args, fmt, tstruct,   \
-                                   tpfmt)                              \
+#undef FTRACE_ENTRY
+#define FTRACE_ENTRY(name, struct_name, id, tstruct, print)            \
 static int                                                             \
-ftrace_format_##call(struct ftrace_event_call *unused,                 \
-                     struct trace_seq *s)                              \
+ftrace_format_##name(struct ftrace_event_call *unused,                 \
+                    struct trace_seq *s)                               \
 {                                                                      \
-       struct args field;                                              \
-       int ret;                                                        \
+       struct struct_name field __attribute__((unused));               \
+       int ret = 0;                                                    \
                                                                        \
        tstruct;                                                        \
                                                                        \
-       trace_seq_printf(s, "\nprint fmt: \"%s\"\n", tpfmt);            \
+       trace_seq_printf(s, "\nprint fmt: " print);                     \
                                                                        \
        return ret;                                                     \
 }
 
-#include "trace_event_types.h"
-
-#undef TRACE_ZERO_CHAR
-#define TRACE_ZERO_CHAR(arg)
-
-#undef TRACE_FIELD
-#define TRACE_FIELD(type, item, assign)\
-       entry->item = assign;
-
-#undef TRACE_FIELD
-#define TRACE_FIELD(type, item, assign)\
-       entry->item = assign;
-
-#undef TRACE_FIELD_SIGN
-#define TRACE_FIELD_SIGN(type, item, assign, is_signed)        \
-       TRACE_FIELD(type, item, assign)
-
-#undef TP_CMD
-#define TP_CMD(cmd...) cmd
-
-#undef TRACE_ENTRY
-#define TRACE_ENTRY    entry
-
-#undef TRACE_FIELD_SPECIAL
-#define TRACE_FIELD_SPECIAL(type_item, item, len, cmd) \
-       cmd;
-
-#undef TRACE_EVENT_FORMAT
-#define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt)     \
-int ftrace_define_fields_##call(struct ftrace_event_call *event_call); \
-static int ftrace_raw_init_event_##call(void);                         \
-                                                                       \
-struct ftrace_event_call __used                                                \
-__attribute__((__aligned__(4)))                                                \
-__attribute__((section("_ftrace_events"))) event_##call = {            \
-       .name                   = #call,                                \
-       .id                     = proto,                                \
-       .system                 = __stringify(TRACE_SYSTEM),            \
-       .raw_init               = ftrace_raw_init_event_##call,         \
-       .show_format            = ftrace_format_##call,                 \
-       .define_fields          = ftrace_define_fields_##call,          \
-};                                                                     \
-static int ftrace_raw_init_event_##call(void)                          \
-{                                                                      \
-       INIT_LIST_HEAD(&event_##call.fields);                           \
-       return 0;                                                       \
-}                                                                      \
-
-#undef TRACE_EVENT_FORMAT_NOFILTER
-#define TRACE_EVENT_FORMAT_NOFILTER(call, proto, args, fmt, tstruct,   \
-                                   tpfmt)                              \
-                                                                       \
-struct ftrace_event_call __used                                                \
-__attribute__((__aligned__(4)))                                                \
-__attribute__((section("_ftrace_events"))) event_##call = {            \
-       .name                   = #call,                                \
-       .id                     = proto,                                \
-       .system                 = __stringify(TRACE_SYSTEM),            \
-       .show_format            = ftrace_format_##call,                 \
-};
+#include "trace_entries.h"
 
-#include "trace_event_types.h"
 
-#undef TRACE_FIELD
-#define TRACE_FIELD(type, item, assign)                                        \
+#undef __field
+#define __field(type, item)                                            \
        ret = trace_define_field(event_call, #type, #item,              \
                                 offsetof(typeof(field), item),         \
                                 sizeof(field.item),                    \
@@ -162,32 +141,45 @@ __attribute__((section("_ftrace_events"))) event_##call = {               \
        if (ret)                                                        \
                return ret;
 
-#undef TRACE_FIELD_SPECIAL
-#define TRACE_FIELD_SPECIAL(type, item, len, cmd)                      \
+#undef __field_desc
+#define __field_desc(type, container, item)    \
+       ret = trace_define_field(event_call, #type, #item,              \
+                                offsetof(typeof(field),                \
+                                         container.item),              \
+                                sizeof(field.container.item),          \
+                                is_signed_type(type), FILTER_OTHER);   \
+       if (ret)                                                        \
+               return ret;
+
+#undef __array
+#define __array(type, item, len)                                       \
+       BUILD_BUG_ON(len > MAX_FILTER_STR_VAL);                         \
        ret = trace_define_field(event_call, #type "[" #len "]", #item, \
                                 offsetof(typeof(field), item),         \
                                 sizeof(field.item), 0, FILTER_OTHER);  \
        if (ret)                                                        \
                return ret;
 
-#undef TRACE_FIELD_SIGN
-#define TRACE_FIELD_SIGN(type, item, assign, is_signed)                        \
-       ret = trace_define_field(event_call, #type, #item,              \
-                                offsetof(typeof(field), item),         \
-                                sizeof(field.item), is_signed,         \
+#undef __array_desc
+#define __array_desc(type, container, item, len)                       \
+       BUILD_BUG_ON(len > MAX_FILTER_STR_VAL);                         \
+       ret = trace_define_field(event_call, #type "[" #len "]", #item, \
+                                offsetof(typeof(field),                \
+                                         container.item),              \
+                                sizeof(field.container.item), 0,       \
                                 FILTER_OTHER);                         \
        if (ret)                                                        \
                return ret;
 
-#undef TRACE_FIELD_ZERO_CHAR
-#define TRACE_FIELD_ZERO_CHAR(item)
+#undef __dynamic_array
+#define __dynamic_array(type, item)
 
-#undef TRACE_EVENT_FORMAT
-#define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt)     \
+#undef FTRACE_ENTRY
+#define FTRACE_ENTRY(name, struct_name, id, tstruct, print)            \
 int                                                                    \
-ftrace_define_fields_##call(struct ftrace_event_call *event_call)      \
+ftrace_define_fields_##name(struct ftrace_event_call *event_call)      \
 {                                                                      \
-       struct args field;                                              \
+       struct struct_name field;                                       \
        int ret;                                                        \
                                                                        \
        ret = trace_define_common_fields(event_call);                   \
@@ -199,8 +191,42 @@ ftrace_define_fields_##call(struct ftrace_event_call *event_call)  \
        return ret;                                                     \
 }
 
-#undef TRACE_EVENT_FORMAT_NOFILTER
-#define TRACE_EVENT_FORMAT_NOFILTER(call, proto, args, fmt, tstruct,   \
-                                   tpfmt)
+#include "trace_entries.h"
+
+
+#undef __field
+#define __field(type, item)
+
+#undef __field_desc
+#define __field_desc(type, container, item)
+
+#undef __array
+#define __array(type, item, len)
+
+#undef __array_desc
+#define __array_desc(type, container, item, len)
+
+#undef __dynamic_array
+#define __dynamic_array(type, item)
+
+#undef FTRACE_ENTRY
+#define FTRACE_ENTRY(call, struct_name, type, tstruct, print)          \
+static int ftrace_raw_init_event_##call(void);                         \
+                                                                       \
+struct ftrace_event_call __used                                                \
+__attribute__((__aligned__(4)))                                                \
+__attribute__((section("_ftrace_events"))) event_##call = {            \
+       .name                   = #call,                                \
+       .id                     = type,                                 \
+       .system                 = __stringify(TRACE_SYSTEM),            \
+       .raw_init               = ftrace_raw_init_event_##call,         \
+       .show_format            = ftrace_format_##call,                 \
+       .define_fields          = ftrace_define_fields_##call,          \
+};                                                                     \
+static int ftrace_raw_init_event_##call(void)                          \
+{                                                                      \
+       INIT_LIST_HEAD(&event_##call.fields);                           \
+       return 0;                                                       \
+}                                                                      \
 
-#include "trace_event_types.h"
+#include "trace_entries.h"
index 5b01b94518fcf15cc36646b6d2b859ed64a072e6..b3f3776b0cd64002605f6c3d2f2dc9528f2b9932 100644 (file)
@@ -290,7 +290,7 @@ ftrace_trace_onoff_print(struct seq_file *m, unsigned long ip,
 {
        long count = (long)data;
 
-       seq_printf(m, "%pf:", (void *)ip);
+       seq_printf(m, "%ps:", (void *)ip);
 
        if (ops == &traceon_probe_ops)
                seq_printf(m, "traceon");
index b3749a2c3132b00bc0779c84c8b9096102fa52fc..45e6c01b2e4d96fc3eb9d4ef8b7a96bd7b60e30b 100644 (file)
@@ -124,7 +124,7 @@ ftrace_pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret,
        if (unlikely(current->ret_stack[index].fp != frame_pointer)) {
                ftrace_graph_stop();
                WARN(1, "Bad frame pointer: expected %lx, received %lx\n"
-                    "  from func %pF return to %lx\n",
+                    "  from func %ps return to %lx\n",
                     current->ret_stack[index].fp,
                     frame_pointer,
                     (void *)current->ret_stack[index].func,
@@ -364,6 +364,15 @@ print_graph_proc(struct trace_seq *s, pid_t pid)
 }
 
 
+static enum print_line_t
+print_graph_lat_fmt(struct trace_seq *s, struct trace_entry *entry)
+{
+       if (!trace_seq_putc(s, ' '))
+               return 0;
+
+       return trace_print_lat_fmt(s, entry);
+}
+
 /* If the pid changed since the last trace, output this event */
 static enum print_line_t
 verif_pid(struct trace_seq *s, pid_t pid, int cpu, struct fgraph_data *data)
@@ -521,6 +530,7 @@ print_graph_irq(struct trace_iterator *iter, unsigned long addr,
                if (ret == TRACE_TYPE_PARTIAL_LINE)
                        return TRACE_TYPE_PARTIAL_LINE;
        }
+
        /* Proc */
        if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) {
                ret = print_graph_proc(s, pid);
@@ -659,7 +669,7 @@ print_graph_entry_leaf(struct trace_iterator *iter,
                        return TRACE_TYPE_PARTIAL_LINE;
        }
 
-       ret = trace_seq_printf(s, "%pf();\n", (void *)call->func);
+       ret = trace_seq_printf(s, "%ps();\n", (void *)call->func);
        if (!ret)
                return TRACE_TYPE_PARTIAL_LINE;
 
@@ -702,7 +712,7 @@ print_graph_entry_nested(struct trace_iterator *iter,
                        return TRACE_TYPE_PARTIAL_LINE;
        }
 
-       ret = trace_seq_printf(s, "%pf() {\n", (void *)call->func);
+       ret = trace_seq_printf(s, "%ps() {\n", (void *)call->func);
        if (!ret)
                return TRACE_TYPE_PARTIAL_LINE;
 
@@ -758,6 +768,13 @@ print_graph_prologue(struct trace_iterator *iter, struct trace_seq *s,
                        return TRACE_TYPE_PARTIAL_LINE;
        }
 
+       /* Latency format */
+       if (trace_flags & TRACE_ITER_LATENCY_FMT) {
+               ret = print_graph_lat_fmt(s, ent);
+               if (ret == TRACE_TYPE_PARTIAL_LINE)
+                       return TRACE_TYPE_PARTIAL_LINE;
+       }
+
        return 0;
 }
 
@@ -952,28 +969,59 @@ print_graph_function(struct trace_iterator *iter)
        return TRACE_TYPE_HANDLED;
 }
 
+static void print_lat_header(struct seq_file *s)
+{
+       static const char spaces[] = "                " /* 16 spaces */
+               "    "                                  /* 4 spaces */
+               "                 ";                    /* 17 spaces */
+       int size = 0;
+
+       if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME)
+               size += 16;
+       if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU)
+               size += 4;
+       if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC)
+               size += 17;
+
+       seq_printf(s, "#%.*s  _-----=> irqs-off        \n", size, spaces);
+       seq_printf(s, "#%.*s / _----=> need-resched    \n", size, spaces);
+       seq_printf(s, "#%.*s| / _---=> hardirq/softirq \n", size, spaces);
+       seq_printf(s, "#%.*s|| / _--=> preempt-depth   \n", size, spaces);
+       seq_printf(s, "#%.*s||| / _-=> lock-depth      \n", size, spaces);
+       seq_printf(s, "#%.*s|||| /                     \n", size, spaces);
+}
+
 static void print_graph_headers(struct seq_file *s)
 {
+       int lat = trace_flags & TRACE_ITER_LATENCY_FMT;
+
+       if (lat)
+               print_lat_header(s);
+
        /* 1st line */
-       seq_printf(s, "# ");
+       seq_printf(s, "#");
        if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME)
                seq_printf(s, "     TIME       ");
        if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU)
-               seq_printf(s, "CPU");
+               seq_printf(s, " CPU");
        if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC)
-               seq_printf(s, "  TASK/PID      ");
+               seq_printf(s, "  TASK/PID       ");
+       if (lat)
+               seq_printf(s, "|||||");
        if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION)
                seq_printf(s, "  DURATION   ");
        seq_printf(s, "               FUNCTION CALLS\n");
 
        /* 2nd line */
-       seq_printf(s, "# ");
+       seq_printf(s, "#");
        if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME)
                seq_printf(s, "      |         ");
        if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU)
-               seq_printf(s, "|  ");
+               seq_printf(s, " |  ");
        if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC)
-               seq_printf(s, "  |    |        ");
+               seq_printf(s, "   |    |        ");
+       if (lat)
+               seq_printf(s, "|||||");
        if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION)
                seq_printf(s, "   |   |      ");
        seq_printf(s, "               |   |   |   |\n");
index 5555b75a0d128e8e5acf5f56454af8e4f52cb818..3aa7eaa2114ce2abc5ae411725c7cfaa71fb137a 100644 (file)
@@ -129,15 +129,10 @@ check_critical_timing(struct trace_array *tr,
                      unsigned long parent_ip,
                      int cpu)
 {
-       unsigned long latency, t0, t1;
        cycle_t T0, T1, delta;
        unsigned long flags;
        int pc;
 
-       /*
-        * usecs conversion is slow so we try to delay the conversion
-        * as long as possible:
-        */
        T0 = data->preempt_timestamp;
        T1 = ftrace_now(cpu);
        delta = T1-T0;
@@ -157,18 +152,15 @@ check_critical_timing(struct trace_array *tr,
 
        trace_function(tr, CALLER_ADDR0, parent_ip, flags, pc);
 
-       latency = nsecs_to_usecs(delta);
-
        if (data->critical_sequence != max_sequence)
                goto out_unlock;
 
-       tracing_max_latency = delta;
-       t0 = nsecs_to_usecs(T0);
-       t1 = nsecs_to_usecs(T1);
-
        data->critical_end = parent_ip;
 
-       update_max_tr_single(tr, current, cpu);
+       if (likely(!is_tracing_stopped())) {
+               tracing_max_latency = delta;
+               update_max_tr_single(tr, current, cpu);
+       }
 
        max_sequence++;
 
index c4c9bbda53d3a5753ac986d83f669fee4a4264f6..0acd834659ed9f9306165d40b81d34a563604095 100644 (file)
@@ -307,6 +307,7 @@ static void __trace_mmiotrace_rw(struct trace_array *tr,
                                struct trace_array_cpu *data,
                                struct mmiotrace_rw *rw)
 {
+       struct ftrace_event_call *call = &event_mmiotrace_rw;
        struct ring_buffer *buffer = tr->buffer;
        struct ring_buffer_event *event;
        struct trace_mmiotrace_rw *entry;
@@ -320,7 +321,9 @@ static void __trace_mmiotrace_rw(struct trace_array *tr,
        }
        entry   = ring_buffer_event_data(event);
        entry->rw                       = *rw;
-       trace_buffer_unlock_commit(buffer, event, 0, pc);
+
+       if (!filter_check_discard(call, entry, buffer, event))
+               trace_buffer_unlock_commit(buffer, event, 0, pc);
 }
 
 void mmio_trace_rw(struct mmiotrace_rw *rw)
@@ -334,6 +337,7 @@ static void __trace_mmiotrace_map(struct trace_array *tr,
                                struct trace_array_cpu *data,
                                struct mmiotrace_map *map)
 {
+       struct ftrace_event_call *call = &event_mmiotrace_map;
        struct ring_buffer *buffer = tr->buffer;
        struct ring_buffer_event *event;
        struct trace_mmiotrace_map *entry;
@@ -347,7 +351,9 @@ static void __trace_mmiotrace_map(struct trace_array *tr,
        }
        entry   = ring_buffer_event_data(event);
        entry->map                      = *map;
-       trace_buffer_unlock_commit(buffer, event, 0, pc);
+
+       if (!filter_check_discard(call, entry, buffer, event))
+               trace_buffer_unlock_commit(buffer, event, 0, pc);
 }
 
 void mmio_trace_mapping(struct mmiotrace_map *map)
index e0c2545622e8f7617b3e32bcb8c3df235aa3a929..f572f44c6e1ede0c13a42223c11520d74efa1f41 100644 (file)
@@ -407,7 +407,7 @@ seq_print_userip_objs(const struct userstack_entry *entry, struct trace_seq *s,
                 * since individual threads might have already quit!
                 */
                rcu_read_lock();
-               task = find_task_by_vpid(entry->ent.tgid);
+               task = find_task_by_vpid(entry->tgid);
                if (task)
                        mm = get_task_mm(task);
                rcu_read_unlock();
@@ -460,18 +460,23 @@ seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags)
        return ret;
 }
 
-static int
-lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
+/**
+ * trace_print_lat_fmt - print the irq, preempt and lockdep fields
+ * @s: trace seq struct to write to
+ * @entry: The trace entry field from the ring buffer
+ *
+ * Prints the generic fields of irqs off, in hard or softirq, preempt
+ * count and lock depth.
+ */
+int trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry)
 {
        int hardirq, softirq;
-       char comm[TASK_COMM_LEN];
+       int ret;
 
-       trace_find_cmdline(entry->pid, comm);
        hardirq = entry->flags & TRACE_FLAG_HARDIRQ;
        softirq = entry->flags & TRACE_FLAG_SOFTIRQ;
 
-       if (!trace_seq_printf(s, "%8.8s-%-5d %3d%c%c%c",
-                             comm, entry->pid, cpu,
+       if (!trace_seq_printf(s, "%c%c%c",
                              (entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
                                (entry->flags & TRACE_FLAG_IRQS_NOSUPPORT) ?
                                  'X' : '.',
@@ -481,9 +486,30 @@ lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
                                hardirq ? 'h' : softirq ? 's' : '.'))
                return 0;
 
+       if (entry->lock_depth < 0)
+               ret = trace_seq_putc(s, '.');
+       else
+               ret = trace_seq_printf(s, "%d", entry->lock_depth);
+       if (!ret)
+               return 0;
+
        if (entry->preempt_count)
                return trace_seq_printf(s, "%x", entry->preempt_count);
-       return trace_seq_puts(s, ".");
+       return trace_seq_putc(s, '.');
+}
+
+static int
+lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
+{
+       char comm[TASK_COMM_LEN];
+
+       trace_find_cmdline(entry->pid, comm);
+
+       if (!trace_seq_printf(s, "%8.8s-%-5d %3d",
+                             comm, entry->pid, cpu))
+               return 0;
+
+       return trace_print_lat_fmt(s, entry);
 }
 
 static unsigned long preempt_mark_thresh = 100;
index d38bec4a9c3081e52bca0dec51e04e94827cba67..9d91c72ba38b91c6aacc9011180eed5ef85fa2bd 100644 (file)
@@ -26,6 +26,8 @@ extern struct trace_event *ftrace_find_event(int type);
 
 extern enum print_line_t trace_nop_print(struct trace_iterator *iter,
                                         int flags);
+extern int
+trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry);
 
 /* used by module unregistering */
 extern int __unregister_ftrace_event(struct trace_event *event);
index ad69f105a7c6f1c4662889b9b8f752a9590dc700..26185d727676b0620496a9eb5a4832e9c3fdbd01 100644 (file)
@@ -24,6 +24,7 @@ static int __read_mostly      tracer_enabled;
 
 static struct task_struct      *wakeup_task;
 static int                     wakeup_cpu;
+static int                     wakeup_current_cpu;
 static unsigned                        wakeup_prio = -1;
 static int                     wakeup_rt;
 
@@ -56,33 +57,23 @@ wakeup_tracer_call(unsigned long ip, unsigned long parent_ip)
        resched = ftrace_preempt_disable();
 
        cpu = raw_smp_processor_id();
+       if (cpu != wakeup_current_cpu)
+               goto out_enable;
+
        data = tr->data[cpu];
        disabled = atomic_inc_return(&data->disabled);
        if (unlikely(disabled != 1))
                goto out;
 
        local_irq_save(flags);
-       __raw_spin_lock(&wakeup_lock);
-
-       if (unlikely(!wakeup_task))
-               goto unlock;
-
-       /*
-        * The task can't disappear because it needs to
-        * wake up first, and we have the wakeup_lock.
-        */
-       if (task_cpu(wakeup_task) != cpu)
-               goto unlock;
 
        trace_function(tr, ip, parent_ip, flags, pc);
 
- unlock:
-       __raw_spin_unlock(&wakeup_lock);
        local_irq_restore(flags);
 
  out:
        atomic_dec(&data->disabled);
-
+ out_enable:
        ftrace_preempt_enable(resched);
 }
 
@@ -107,11 +98,18 @@ static int report_latency(cycle_t delta)
        return 1;
 }
 
+static void probe_wakeup_migrate_task(struct task_struct *task, int cpu)
+{
+       if (task != wakeup_task)
+               return;
+
+       wakeup_current_cpu = cpu;
+}
+
 static void notrace
 probe_wakeup_sched_switch(struct rq *rq, struct task_struct *prev,
        struct task_struct *next)
 {
-       unsigned long latency = 0, t0 = 0, t1 = 0;
        struct trace_array_cpu *data;
        cycle_t T0, T1, delta;
        unsigned long flags;
@@ -157,10 +155,6 @@ probe_wakeup_sched_switch(struct rq *rq, struct task_struct *prev,
        trace_function(wakeup_trace, CALLER_ADDR0, CALLER_ADDR1, flags, pc);
        tracing_sched_switch_trace(wakeup_trace, prev, next, flags, pc);
 
-       /*
-        * usecs conversion is slow so we try to delay the conversion
-        * as long as possible:
-        */
        T0 = data->preempt_timestamp;
        T1 = ftrace_now(cpu);
        delta = T1-T0;
@@ -168,13 +162,10 @@ probe_wakeup_sched_switch(struct rq *rq, struct task_struct *prev,
        if (!report_latency(delta))
                goto out_unlock;
 
-       latency = nsecs_to_usecs(delta);
-
-       tracing_max_latency = delta;
-       t0 = nsecs_to_usecs(T0);
-       t1 = nsecs_to_usecs(T1);
-
-       update_max_tr(wakeup_trace, wakeup_task, wakeup_cpu);
+       if (likely(!is_tracing_stopped())) {
+               tracing_max_latency = delta;
+               update_max_tr(wakeup_trace, wakeup_task, wakeup_cpu);
+       }
 
 out_unlock:
        __wakeup_reset(wakeup_trace);
@@ -244,6 +235,7 @@ probe_wakeup(struct rq *rq, struct task_struct *p, int success)
        __wakeup_reset(wakeup_trace);
 
        wakeup_cpu = task_cpu(p);
+       wakeup_current_cpu = wakeup_cpu;
        wakeup_prio = p->prio;
 
        wakeup_task = p;
@@ -293,6 +285,13 @@ static void start_wakeup_tracer(struct trace_array *tr)
                goto fail_deprobe_wake_new;
        }
 
+       ret = register_trace_sched_migrate_task(probe_wakeup_migrate_task);
+       if (ret) {
+               pr_info("wakeup trace: Couldn't activate tracepoint"
+                       " probe to kernel_sched_migrate_task\n");
+               return;
+       }
+
        wakeup_reset(tr);
 
        /*
@@ -325,6 +324,7 @@ static void stop_wakeup_tracer(struct trace_array *tr)
        unregister_trace_sched_switch(probe_wakeup_sched_switch);
        unregister_trace_sched_wakeup_new(probe_wakeup);
        unregister_trace_sched_wakeup(probe_wakeup);
+       unregister_trace_sched_migrate_task(probe_wakeup_migrate_task);
 }
 
 static int __wakeup_tracer_init(struct trace_array *tr)
index cb8a112030bba9ba0522b56dca4d6c3bec2a8986..d320c1816a7bfb3719b82e3b6da4531b473cb94c 100644 (file)
@@ -581,7 +581,7 @@ static char *symbol_string(char *buf, char *end, void *ptr,
        unsigned long value = (unsigned long) ptr;
 #ifdef CONFIG_KALLSYMS
        char sym[KSYM_SYMBOL_LEN];
-       if (ext != 'f')
+       if (ext != 'f' && ext != 's')
                sprint_symbol(sym, value);
        else
                kallsyms_lookup(value, NULL, NULL, NULL, sym);
@@ -794,7 +794,8 @@ static char *ip4_addr_string(char *buf, char *end, const u8 *addr,
  *
  * - 'F' For symbolic function descriptor pointers with offset
  * - 'f' For simple symbolic function names without offset
- * - 'S' For symbolic direct pointers
+ * - 'S' For symbolic direct pointers with offset
+ * - 's' For symbolic direct pointers without offset
  * - 'R' For a struct resource pointer, it prints the range of
  *       addresses (not the name nor the flags)
  * - 'M' For a 6-byte MAC address, it prints the address in the
@@ -822,6 +823,7 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr,
        case 'F':
        case 'f':
                ptr = dereference_function_descriptor(ptr);
+       case 's':
                /* Fallthrough */
        case 'S':
                return symbol_string(buf, end, ptr, spec, *fmt);
@@ -1063,10 +1065,12 @@ qualifier:
  * @args: Arguments for the format string
  *
  * This function follows C99 vsnprintf, but has some extensions:
- * %pS output the name of a text symbol
+ * %pS output the name of a text symbol with offset
+ * %ps output the name of a text symbol without offset
  * %pF output the name of a function pointer with its offset
  * %pf output the name of a function pointer without its offset
  * %pR output the address range in a struct resource
+ * %n is ignored
  *
  * The return value is the number of characters which would
  * be generated for the given input, excluding the trailing
@@ -1522,11 +1526,7 @@ EXPORT_SYMBOL_GPL(vbin_printf);
  * a binary buffer that generated by vbin_printf.
  *
  * The format follows C99 vsnprintf, but has some extensions:
- * %pS output the name of a text symbol
- * %pF output the name of a function pointer with its offset
- * %pf output the name of a function pointer without its offset
- * %pR output the address range in a struct resource
- * %n is ignored
+ *  see vsnprintf comment for details.
  *
  * The return value is the number of characters which would
  * be generated for the given input, excluding the trailing
index 4a6ff2ba4d071f459c7f6da04bc991da5a606ac8..b1a4290996b511ebc644e86ab9b7aeb693e74db8 100644 (file)
@@ -1372,7 +1372,7 @@ static int atalk_route_packet(struct sk_buff *skb, struct net_device *dev,
 
        if (aarp_send_ddp(rt->dev, skb, &ta, NULL) == NET_XMIT_DROP)
                return NET_RX_DROP;
-       return NET_XMIT_SUCCESS;
+       return NET_RX_SUCCESS;
 free_it:
        kfree_skb(skb);
 drop:
index ef1c43a2ed564a4dbcecd92b35dbe4fc702b86b9..606832115674147be25d49bea7f12ce293b9bc2a 100644 (file)
@@ -199,6 +199,8 @@ static int can_create(struct net *net, struct socket *sock, int protocol)
  * @skb: pointer to socket buffer with CAN frame in data section
  * @loop: loopback for listeners on local CAN sockets (recommended default!)
  *
+ * Due to the loopback this routine must not be called from hardirq context.
+ *
  * Return:
  *  0 on success
  *  -ENETDOWN when the selected interface is down
@@ -278,7 +280,7 @@ int can_send(struct sk_buff *skb, int loop)
        }
 
        if (newskb)
-               netif_rx(newskb);
+               netif_rx_ni(newskb);
 
        /* update statistics */
        can_stats.tx_frames++;
index 84945470ab38cc073ff71eb8dac14ad653c9cad0..560c8c9c03ab3ccfef96bfd1eed5fc195c4b1a75 100644 (file)
@@ -1017,9 +1017,9 @@ void netdev_state_change(struct net_device *dev)
 }
 EXPORT_SYMBOL(netdev_state_change);
 
-void netdev_bonding_change(struct net_device *dev)
+void netdev_bonding_change(struct net_device *dev, unsigned long event)
 {
-       call_netdevice_notifiers(NETDEV_BONDING_FAILOVER, dev);
+       call_netdevice_notifiers(event, dev);
 }
 EXPORT_SYMBOL(netdev_bonding_change);
 
index 4b5db44970aa23c8e8032542d0f5d55ea6bed415..8408398cd44e814cece7b9ec92615b1c615d32bd 100644 (file)
@@ -66,9 +66,9 @@ config IP_DCCP_CCID3_RTO
            A value of 0 disables this feature by enforcing the value specified
            in RFC 3448. The following values have been suggested as bounds for
            experimental use:
-               * 16-20ms to match the typical multimedia inter-frame interval
-               * 100ms as a reasonable compromise [default]
-               * 1000ms corresponds to the lower TCP RTO bound (RFC 2988, 2.4)
+               * 16-20ms to match the typical multimedia inter-frame interval
+               * 100ms as a reasonable compromise [default]
+               * 1000ms corresponds to the lower TCP RTO bound (RFC 2988, 2.4)
 
            The default of 100ms is a compromise between a large value for
            efficient DCCP implementations, and a small value to avoid disrupting
index d235294ace23b640960999a8dd2be995d82f1193..e8cf99e880b0c765bf2c983b7118939f2c0977a5 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *  net/dccp/ccids/ccid2.c
- *
  *  Copyright (c) 2005, 2006 Andrea Bittau <a.bittau@cs.ucl.ac.uk>
  *
  *  Changes to meet Linux coding standards, and DCCP infrastructure fixes.
index 2c94ca0290107b1d464cb9938101969d4b135763..326ac90fb9091bb40871cbf12c763aeec2398eb8 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *  net/dccp/ccids/ccid2.h
- *
  *  Copyright (c) 2005 Andrea Bittau <a.bittau@cs.ucl.ac.uk>
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -40,14 +38,14 @@ struct ccid2_seq {
 #define CCID2_SEQBUF_LEN 1024
 #define CCID2_SEQBUF_MAX 128
 
-/** struct ccid2_hc_tx_sock - CCID2 TX half connection
- *
+/**
+ * struct ccid2_hc_tx_sock - CCID2 TX half connection
  * @ccid2hctx_{cwnd,ssthresh,pipe}: as per RFC 4341, section 5
  * @ccid2hctx_packets_acked - Ack counter for deriving cwnd growth (RFC 3465)
  * @ccid2hctx_lastrtt -time RTT was last measured
  * @ccid2hctx_rpseq - last consecutive seqno
  * @ccid2hctx_rpdupack - dupacks since rpseq
-*/
+ */
 struct ccid2_hc_tx_sock {
        u32                     ccid2hctx_cwnd;
        u32                     ccid2hctx_ssthresh;
index f596ce149c3c00a18ae4213d7f5c9e6d86bd1df6..34dcc798c457b4f11b058f43303f4af231361b2b 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *  net/dccp/ccids/ccid3.c
- *
  *  Copyright (c) 2007   The University of Aberdeen, Scotland, UK
  *  Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand.
  *  Copyright (c) 2005-7 Ian McDonald <ian.mcdonald@jandi.co.nz>
@@ -750,7 +748,8 @@ static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
        return 0;
 }
 
-/** ccid3_first_li  -  Implements [RFC 3448, 6.3.1]
+/**
+ * ccid3_first_li  -  Implements [RFC 5348, 6.3.1]
  *
  * Determine the length of the first loss interval via inverse lookup.
  * Assume that X_recv can be computed by the throughput equation
index 49ca32bd7e79d608592aaae0371545ff246ab013..e5a24414384634b0d0a38e8da57a987286c72801 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *  net/dccp/ccids/ccid3.h
- *
  *  Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand.
  *  Copyright (c) 2007   The University of Aberdeen, Scotland, UK
  *
@@ -75,8 +73,8 @@ enum ccid3_hc_tx_states {
        TFRC_SSTATE_TERM,
 };
 
-/** struct ccid3_hc_tx_sock - CCID3 sender half-connection socket
- *
+/**
+ * struct ccid3_hc_tx_sock - CCID3 sender half-connection socket
  * @ccid3hctx_x - Current sending rate in 64 * bytes per second
  * @ccid3hctx_x_recv - Receive rate    in 64 * bytes per second
  * @ccid3hctx_x_calc - Calculated rate in bytes per second
@@ -119,9 +117,9 @@ struct ccid3_hc_tx_sock {
 
 static inline struct ccid3_hc_tx_sock *ccid3_hc_tx_sk(const struct sock *sk)
 {
-    struct ccid3_hc_tx_sock *hctx = ccid_priv(dccp_sk(sk)->dccps_hc_tx_ccid);
-    BUG_ON(hctx == NULL);
-    return hctx;
+       struct ccid3_hc_tx_sock *hctx = ccid_priv(dccp_sk(sk)->dccps_hc_tx_ccid);
+       BUG_ON(hctx == NULL);
+       return hctx;
 }
 
 /* TFRC receiver states */
@@ -131,22 +129,22 @@ enum ccid3_hc_rx_states {
        TFRC_RSTATE_TERM    = 127,
 };
 
-/** struct ccid3_hc_rx_sock - CCID3 receiver half-connection socket
- *
- *  @ccid3hcrx_x_recv  -  Receiver estimate of send rate (RFC 3448 4.3)
- *  @ccid3hcrx_rtt  -  Receiver estimate of rtt (non-standard)
- *  @ccid3hcrx_p  -  Current loss event rate (RFC 3448 5.4)
- *  @ccid3hcrx_last_counter  -  Tracks window counter (RFC 4342, 8.1)
- *  @ccid3hcrx_state  -  Receiver state, one of %ccid3_hc_rx_states
- *  @ccid3hcrx_bytes_recv  -  Total sum of DCCP payload bytes
- *  @ccid3hcrx_x_recv  -  Receiver estimate of send rate (RFC 3448, sec. 4.3)
- *  @ccid3hcrx_rtt  -  Receiver estimate of RTT
- *  @ccid3hcrx_tstamp_last_feedback  -  Time at which last feedback was sent
- *  @ccid3hcrx_tstamp_last_ack  -  Time at which last feedback was sent
- *  @ccid3hcrx_hist  -  Packet history (loss detection + RTT sampling)
- *  @ccid3hcrx_li_hist  -  Loss Interval database
- *  @ccid3hcrx_s  -  Received packet size in bytes
- *  @ccid3hcrx_pinv  -  Inverse of Loss Event Rate (RFC 4342, sec. 8.5)
+/**
+ * struct ccid3_hc_rx_sock - CCID3 receiver half-connection socket
+ * @ccid3hcrx_x_recv  -  Receiver estimate of send rate (RFC 3448 4.3)
+ * @ccid3hcrx_rtt  -  Receiver estimate of rtt (non-standard)
+ * @ccid3hcrx_p  -  Current loss event rate (RFC 3448 5.4)
+ * @ccid3hcrx_last_counter  -  Tracks window counter (RFC 4342, 8.1)
+ * @ccid3hcrx_state  -  Receiver state, one of %ccid3_hc_rx_states
+ * @ccid3hcrx_bytes_recv  -  Total sum of DCCP payload bytes
+ * @ccid3hcrx_x_recv  -  Receiver estimate of send rate (RFC 3448, sec. 4.3)
+ * @ccid3hcrx_rtt  -  Receiver estimate of RTT
+ * @ccid3hcrx_tstamp_last_feedback  -  Time at which last feedback was sent
+ * @ccid3hcrx_tstamp_last_ack  -  Time at which last feedback was sent
+ * @ccid3hcrx_hist  -  Packet history (loss detection + RTT sampling)
+ * @ccid3hcrx_li_hist  -  Loss Interval database
+ * @ccid3hcrx_s  -  Received packet size in bytes
+ * @ccid3hcrx_pinv  -  Inverse of Loss Event Rate (RFC 4342, sec. 8.5)
  */
 struct ccid3_hc_rx_sock {
        u8                              ccid3hcrx_last_counter:4;
@@ -163,9 +161,9 @@ struct ccid3_hc_rx_sock {
 
 static inline struct ccid3_hc_rx_sock *ccid3_hc_rx_sk(const struct sock *sk)
 {
-    struct ccid3_hc_rx_sock *hcrx = ccid_priv(dccp_sk(sk)->dccps_hc_rx_ccid);
-    BUG_ON(hcrx == NULL);
-    return hcrx;
+       struct ccid3_hc_rx_sock *hcrx = ccid_priv(dccp_sk(sk)->dccps_hc_rx_ccid);
+       BUG_ON(hcrx == NULL);
+       return hcrx;
 }
 
 #endif /* _DCCP_CCID3_H_ */
index 4d1e401272646c88789c9c0beb537718b3260708..8fc3cbf79071fdc7dc904d154864b007f9768a42 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *  net/dccp/ccids/lib/loss_interval.c
- *
  *  Copyright (c) 2007   The University of Aberdeen, Scotland, UK
  *  Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand.
  *  Copyright (c) 2005-7 Ian McDonald <ian.mcdonald@jandi.co.nz>
@@ -21,7 +19,7 @@ static const int tfrc_lh_weights[NINTERVAL] = { 10, 10, 10, 10, 8, 6, 4, 2 };
 /* implements LIFO semantics on the array */
 static inline u8 LIH_INDEX(const u8 ctr)
 {
-       return (LIH_SIZE - 1 - (ctr % LIH_SIZE));
+       return LIH_SIZE - 1 - (ctr % LIH_SIZE);
 }
 
 /* the `counter' index always points at the next entry to be populated */
@@ -129,7 +127,8 @@ static inline u8 tfrc_lh_is_new_loss(struct tfrc_loss_interval *cur,
                (cur->li_is_closed || SUB16(new_loss->tfrchrx_ccval, cur->li_ccval) > 4);
 }
 
-/** tfrc_lh_interval_add  -  Insert new record into the Loss Interval database
+/**
+ * tfrc_lh_interval_add  -  Insert new record into the Loss Interval database
  * @lh:                   Loss Interval database
  * @rh:                   Receive history containing a fresh loss event
  * @calc_first_li: Caller-dependent routine to compute length of first interval
index 246018a3b269f7a714f121eeb18cedbf832fee20..d1d2f5383b7d3d7cec533be0d7b8d939ebe492dd 100644 (file)
@@ -1,8 +1,6 @@
 #ifndef _DCCP_LI_HIST_
 #define _DCCP_LI_HIST_
 /*
- *  net/dccp/ccids/lib/loss_interval.h
- *
  *  Copyright (c) 2007   The University of Aberdeen, Scotland, UK
  *  Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand.
  *  Copyright (c) 2005-7 Ian McDonald <ian.mcdonald@jandi.co.nz>
index b7785b3581ec2ee5a747ec3975d00496f6a42183..3a4f414e94a0051bf66429739680d3d5ee8fb432 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *  net/dccp/packet_history.c
- *
  *  Copyright (c) 2007   The University of Aberdeen, Scotland, UK
  *  Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand.
  *
@@ -128,7 +126,7 @@ u32 tfrc_tx_hist_rtt(struct tfrc_tx_hist_entry *head, const u64 seqno,
 
 
 /*
- *     Receiver History Routines
+ *     Receiver History Routines
  */
 static struct kmem_cache *tfrc_rx_hist_slab;
 
index 461cc91cce88aecee60a32c8ab496de770192ad5..7df6c52999999a4c76c99802d0dbcf54a8654211 100644 (file)
@@ -70,7 +70,6 @@ struct tfrc_rx_hist_entry {
 
 /**
  * tfrc_rx_hist  -  RX history structure for TFRC-based protocols
- *
  * @ring:              Packet history for RTT sampling and loss detection
  * @loss_count:                Number of entries in circular history
  * @loss_start:                Movable index (for loss detection)
index e9720b14327536192b72fa282d97fa439eeb0a99..01bb48e96c2ed0b6955c50ee348817e1415f61fd 100644 (file)
@@ -1,8 +1,6 @@
 #ifndef _TFRC_H_
 #define _TFRC_H_
 /*
- *  net/dccp/ccids/lib/tfrc.h
- *
  *  Copyright (c) 2007   The University of Aberdeen, Scotland, UK
  *  Copyright (c) 2005-6 The University of Waikato, Hamilton, New Zealand.
  *  Copyright (c) 2005-6 Ian McDonald <ian.mcdonald@jandi.co.nz>
@@ -32,7 +30,7 @@ extern int tfrc_debug;
 /* integer-arithmetic divisions of type (a * 1000000)/b */
 static inline u64 scaled_div(u64 a, u64 b)
 {
-       BUG_ON(b==0);
+       BUG_ON(b == 0);
        return div64_u64(a * 1000000, b);
 }
 
index c5d3a9e5a5a46ee59e5665087df31fcaeb0986ff..22ca1cf0eb5503fe6ed2db69172771f0e207b182 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *  net/dccp/ccids/lib/tfrc_equation.c
- *
  *  Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand.
  *  Copyright (c) 2005 Ian McDonald <ian.mcdonald@jandi.co.nz>
  *  Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
     }
 
   With the given configuration, we have, with M = TFRC_CALC_X_ARRSIZE-1,
-    lookup[0][0]  =  g(1000000/(M+1))           =  1000000 * f(0.2%)
-    lookup[M][0]  =  g(1000000)                         =  1000000 * f(100%)
-    lookup[0][1]  =  g(TFRC_SMALLEST_P)                  = 1000000 * f(0.01%)
-    lookup[M][1]  =  g(TFRC_CALC_X_SPLIT)       =  1000000 * f(5%)
+    lookup[0][0]  =  g(1000000/(M+1))          = 1000000 * f(0.2%)
+    lookup[M][0]  =  g(1000000)                        = 1000000 * f(100%)
+    lookup[0][1]  =  g(TFRC_SMALLEST_P)                = 1000000 * f(0.01%)
+    lookup[M][1]  =  g(TFRC_CALC_X_SPLIT)      = 1000000 * f(5%)
 
   In summary, the two columns represent f(p) for the following ranges:
     * The first column is for   0.002  <= p <= 1.0
@@ -610,11 +608,10 @@ static inline u32 tfrc_binsearch(u32 fval, u8 small)
 
 /**
  * tfrc_calc_x - Calculate the send rate as per section 3.1 of RFC3448
- *
- *  @s: packet size          in bytes
- *  @R: RTT                  scaled by 1000000   (i.e., microseconds)
- *  @p: loss ratio estimate  scaled by 1000000
- *  Returns X_calc           in bytes per second (not scaled).
+ * @s: packet size          in bytes
+ * @R: RTT                  scaled by 1000000   (i.e., microseconds)
+ * @p: loss ratio estimate  scaled by 1000000
+ * Returns X_calc           in bytes per second (not scaled).
  */
 u32 tfrc_calc_x(u16 s, u32 R, u32 p)
 {
@@ -630,17 +627,17 @@ u32 tfrc_calc_x(u16 s, u32 R, u32 p)
                return ~0U;
        }
 
-       if (p <= TFRC_CALC_X_SPLIT)             {     /* 0.0000 < p <= 0.05   */
+       if (p <= TFRC_CALC_X_SPLIT)             {     /* 0.0000 < p <= 0.05   */
                if (p < TFRC_SMALLEST_P) {            /* 0.0000 < p <  0.0001 */
                        DCCP_WARN("Value of p (%d) below resolution. "
                                  "Substituting %d\n", p, TFRC_SMALLEST_P);
                        index = 0;
-               } else                                /* 0.0001 <= p <= 0.05  */
+               } else                                /* 0.0001 <= p <= 0.05  */
                        index =  p/TFRC_SMALLEST_P - 1;
 
                f = tfrc_calc_x_lookup[index][1];
 
-       } else {                                      /* 0.05   <  p <= 1.00  */
+       } else {                                      /* 0.05   <  p <= 1.00  */
                index = p/(1000000/TFRC_CALC_X_ARRSIZE) - 1;
 
                f = tfrc_calc_x_lookup[index][0];
@@ -661,7 +658,6 @@ u32 tfrc_calc_x(u16 s, u32 R, u32 p)
 
 /**
  *  tfrc_calc_x_reverse_lookup  -  try to find p given f(p)
- *
  *  @fvalue: function value to match, scaled by 1000000
  *  Returns closest match for p, also scaled by 1000000
  */
index d01c00de1ad0b2487a86a918b9e4916c71308c58..7302e1498d46e1b89381bc6dc834335a59a892cc 100644 (file)
@@ -948,7 +948,7 @@ static struct proto dccp_v4_prot = {
 #endif
 };
 
-static struct net_protocol dccp_v4_protocol = {
+static const struct net_protocol dccp_v4_protocol = {
        .handler        = dccp_v4_rcv,
        .err_handler    = dccp_v4_err,
        .no_policy      = 1,
index 64f011cc44916f99f37f9ab8279f055870d19b3a..e48ca5d45658468176bb60c8cbb53a587feea72d 100644 (file)
@@ -1152,13 +1152,13 @@ static struct proto dccp_v6_prot = {
 #endif
 };
 
-static struct inet6_protocol dccp_v6_protocol = {
+static const struct inet6_protocol dccp_v6_protocol = {
        .handler        = dccp_v6_rcv,
        .err_handler    = dccp_v6_err,
        .flags          = INET6_PROTO_NOPOLICY | INET6_PROTO_FINAL,
 };
 
-static struct proto_ops inet6_dccp_ops = {
+static const struct proto_ops inet6_dccp_ops = {
        .family            = PF_INET6,
        .owner             = THIS_MODULE,
        .release           = inet6_release,
index 77ae6852b93d11b3e1c9e5ad4f143d1188d281c9..51593a48f2ddae396a97395239ca7f7c1aad5859 100644 (file)
@@ -414,7 +414,7 @@ static int dgram_getsockopt(struct sock *sk, int level, int optname,
 }
 
 static int dgram_setsockopt(struct sock *sk, int level, int optname,
-                   char __user *optval, int __user optlen)
+                   char __user *optval, int optlen)
 {
        struct dgram_sock *ro = dgram_sk(sk);
        int val;
index 2106ecbf0308eb3101291d6f6f8f807567952413..ca767bde17a455a2f426e57dc1e2dc1db471c4a4 100644 (file)
@@ -35,6 +35,7 @@
 #include <net/ieee802154_netdev.h>
 
 static unsigned int ieee802154_seq_num;
+static DEFINE_SPINLOCK(ieee802154_seq_lock);
 
 static struct genl_family ieee802154_coordinator_family = {
        .id             = GENL_ID_GENERATE,
@@ -57,12 +58,15 @@ static struct sk_buff *ieee802154_nl_create(int flags, u8 req)
 {
        void *hdr;
        struct sk_buff *msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
+       unsigned long f;
 
        if (!msg)
                return NULL;
 
+       spin_lock_irqsave(&ieee802154_seq_lock, f);
        hdr = genlmsg_put(msg, 0, ieee802154_seq_num++,
                        &ieee802154_coordinator_family, flags, req);
+       spin_unlock_irqrestore(&ieee802154_seq_lock, f);
        if (!hdr) {
                nlmsg_free(msg);
                return NULL;
index 4681501aae930928a76ecaaf02dbdc6cd68d892c..13198859982e64baf80b97463af6e0b70bc75a50 100644 (file)
@@ -244,7 +244,7 @@ static int raw_getsockopt(struct sock *sk, int level, int optname,
 }
 
 static int raw_setsockopt(struct sock *sk, int level, int optname,
-                   char __user *optval, int __user optlen)
+                   char __user *optval, int optlen)
 {
        return -EOPNOTSUPP;
 }
index 6c30a73f03f58e0c96f07e1292809b176c09f595..58c4b0f7c4aae333e5767e331b84bebbe4845bd0 100644 (file)
@@ -244,7 +244,7 @@ EXPORT_SYMBOL(build_ehash_secret);
 static inline int inet_netns_ok(struct net *net, int protocol)
 {
        int hash;
-       struct net_protocol *ipprot;
+       const struct net_protocol *ipprot;
 
        if (net_eq(net, &init_net))
                return 1;
@@ -1162,7 +1162,7 @@ EXPORT_SYMBOL(inet_sk_rebuild_header);
 static int inet_gso_send_check(struct sk_buff *skb)
 {
        struct iphdr *iph;
-       struct net_protocol *ops;
+       const struct net_protocol *ops;
        int proto;
        int ihl;
        int err = -EINVAL;
@@ -1198,7 +1198,7 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features)
 {
        struct sk_buff *segs = ERR_PTR(-EINVAL);
        struct iphdr *iph;
-       struct net_protocol *ops;
+       const struct net_protocol *ops;
        int proto;
        int ihl;
        int id;
@@ -1265,7 +1265,7 @@ out:
 static struct sk_buff **inet_gro_receive(struct sk_buff **head,
                                         struct sk_buff *skb)
 {
-       struct net_protocol *ops;
+       const struct net_protocol *ops;
        struct sk_buff **pp = NULL;
        struct sk_buff *p;
        struct iphdr *iph;
@@ -1342,7 +1342,7 @@ out:
 
 static int inet_gro_complete(struct sk_buff *skb)
 {
-       struct net_protocol *ops;
+       const struct net_protocol *ops;
        struct iphdr *iph = ip_hdr(skb);
        int proto = iph->protocol & (MAX_INET_PROTOS - 1);
        int err = -ENOSYS;
@@ -1427,13 +1427,13 @@ void snmp_mib_free(void *ptr[2])
 EXPORT_SYMBOL_GPL(snmp_mib_free);
 
 #ifdef CONFIG_IP_MULTICAST
-static struct net_protocol igmp_protocol = {
+static const struct net_protocol igmp_protocol = {
        .handler =      igmp_rcv,
        .netns_ok =     1,
 };
 #endif
 
-static struct net_protocol tcp_protocol = {
+static const struct net_protocol tcp_protocol = {
        .handler =      tcp_v4_rcv,
        .err_handler =  tcp_v4_err,
        .gso_send_check = tcp_v4_gso_send_check,
@@ -1444,7 +1444,7 @@ static struct net_protocol tcp_protocol = {
        .netns_ok =     1,
 };
 
-static struct net_protocol udp_protocol = {
+static const struct net_protocol udp_protocol = {
        .handler =      udp_rcv,
        .err_handler =  udp_err,
        .gso_send_check = udp4_ufo_send_check,
@@ -1453,7 +1453,7 @@ static struct net_protocol udp_protocol = {
        .netns_ok =     1,
 };
 
-static struct net_protocol icmp_protocol = {
+static const struct net_protocol icmp_protocol = {
        .handler =      icmp_rcv,
        .no_policy =    1,
        .netns_ok =     1,
index e878e494296ef948958bb0ff845a145742cb90ec..5c662703eb1e9cf917df97b41e024c52b946be38 100644 (file)
@@ -311,7 +311,7 @@ static const struct xfrm_type ah_type =
        .output         = ah_output
 };
 
-static struct net_protocol ah4_protocol = {
+static const struct net_protocol ah4_protocol = {
        .handler        =       xfrm4_rcv,
        .err_handler    =       ah4_err,
        .no_policy      =       1,
index 3863c3a4223f45f84167b9a50c708049822f1ce4..07336c6201f0dede9e93c75f811b64af7d8cc853 100644 (file)
@@ -1087,6 +1087,12 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
        case NETDEV_DOWN:
                ip_mc_down(in_dev);
                break;
+       case NETDEV_BONDING_OLDTYPE:
+               ip_mc_unmap(in_dev);
+               break;
+       case NETDEV_BONDING_NEWTYPE:
+               ip_mc_remap(in_dev);
+               break;
        case NETDEV_CHANGEMTU:
                if (inetdev_valid_mtu(dev->mtu))
                        break;
index 18bb383ea39354c52ceb593a78f462d839fba5e4..12f7287e902dcac7614cfb8375c1788e15e006cc 100644 (file)
@@ -615,7 +615,7 @@ static const struct xfrm_type esp_type =
        .output         = esp_output
 };
 
-static struct net_protocol esp4_protocol = {
+static const struct net_protocol esp4_protocol = {
        .handler        =       xfrm4_rcv,
        .err_handler    =       esp4_err,
        .no_policy      =       1,
index 97c410e8438895664a9abdbbf5670b26af01dffa..5bc13fe816d125780d1b5518560dda663817e80e 100644 (file)
@@ -655,7 +655,7 @@ static void icmp_unreach(struct sk_buff *skb)
        struct iphdr *iph;
        struct icmphdr *icmph;
        int hash, protocol;
-       struct net_protocol *ipprot;
+       const struct net_protocol *ipprot;
        u32 info = 0;
        struct net *net;
 
index 01b4284ed694fc86540da28253e159625acc0f5e..d41e5de79a822b658b8bde74c3d88f96524f2166 100644 (file)
@@ -1298,6 +1298,28 @@ void ip_mc_dec_group(struct in_device *in_dev, __be32 addr)
        }
 }
 
+/* Device changing type */
+
+void ip_mc_unmap(struct in_device *in_dev)
+{
+       struct ip_mc_list *i;
+
+       ASSERT_RTNL();
+
+       for (i = in_dev->mc_list; i; i = i->next)
+               igmp_group_dropped(i);
+}
+
+void ip_mc_remap(struct in_device *in_dev)
+{
+       struct ip_mc_list *i;
+
+       ASSERT_RTNL();
+
+       for (i = in_dev->mc_list; i; i = i->next)
+               igmp_group_added(i);
+}
+
 /* Device going down */
 
 void ip_mc_down(struct in_device *in_dev)
index 533afaadefd4a25a09b8fd511f43032a57a87238..d9645c94a0678fd76f64ffbbaf40f63184a7e878 100644 (file)
@@ -1288,7 +1288,7 @@ static void ipgre_fb_tunnel_init(struct net_device *dev)
 }
 
 
-static struct net_protocol ipgre_protocol = {
+static const struct net_protocol ipgre_protocol = {
        .handler        =       ipgre_rcv,
        .err_handler    =       ipgre_err,
        .netns_ok       =       1,
index db46b4b5b2b9429db018b1abcadaf26d92316048..6c98b43badf4e1d770a3f28df87e6674dd963c42 100644 (file)
@@ -202,7 +202,7 @@ static int ip_local_deliver_finish(struct sk_buff *skb)
        {
                int protocol = ip_hdr(skb)->protocol;
                int hash, raw;
-               struct net_protocol *ipprot;
+               const struct net_protocol *ipprot;
 
        resubmit:
                raw = raw_local_deliver(skb, protocol);
index 3262ce06294c314a85bfcb4d643e4d3ec020b4e4..38fbf04150ae7ec60ccafa1a4bd740995fb13427 100644 (file)
@@ -146,7 +146,7 @@ static const struct xfrm_type ipcomp_type = {
        .output         = ipcomp_output
 };
 
-static struct net_protocol ipcomp4_protocol = {
+static const struct net_protocol ipcomp4_protocol = {
        .handler        =       xfrm4_rcv,
        .err_handler    =       ipcomp4_err,
        .no_policy      =       1,
index 65d421cf5bc717754353f443a62aa856605f6347..c43ec2d51ce21dcb8666785f52bbd5417d868a0e 100644 (file)
@@ -99,10 +99,6 @@ static int ipmr_cache_report(struct net *net,
                             struct sk_buff *pkt, vifi_t vifi, int assert);
 static int ipmr_fill_mroute(struct sk_buff *skb, struct mfc_cache *c, struct rtmsg *rtm);
 
-#ifdef CONFIG_IP_PIMSM_V2
-static struct net_protocol pim_protocol;
-#endif
-
 static struct timer_list ipmr_expire_timer;
 
 /* Service routines creating virtual interfaces: DVMRP tunnels and PIMREG */
@@ -1945,7 +1941,7 @@ static const struct file_operations ipmr_mfc_fops = {
 #endif
 
 #ifdef CONFIG_IP_PIMSM_V2
-static struct net_protocol pim_protocol = {
+static const struct net_protocol pim_protocol = {
        .handler        =       pim_rcv,
        .netns_ok       =       1,
 };
index a2e5fc0a15e15eff1abdecba3d94c870fc2054ec..542f22fc98b3948f80ba1f30027106ddeb882047 100644 (file)
 #include <linux/spinlock.h>
 #include <net/protocol.h>
 
-struct net_protocol *inet_protos[MAX_INET_PROTOS] ____cacheline_aligned_in_smp;
+const struct net_protocol *inet_protos[MAX_INET_PROTOS] ____cacheline_aligned_in_smp;
 static DEFINE_SPINLOCK(inet_proto_lock);
 
 /*
  *     Add a protocol handler to the hash tables
  */
 
-int inet_add_protocol(struct net_protocol *prot, unsigned char protocol)
+int inet_add_protocol(const struct net_protocol *prot, unsigned char protocol)
 {
        int hash, ret;
 
@@ -57,7 +57,7 @@ int inet_add_protocol(struct net_protocol *prot, unsigned char protocol)
  *     Remove a protocol from the hash tables.
  */
 
-int inet_del_protocol(struct net_protocol *prot, unsigned char protocol)
+int inet_del_protocol(const struct net_protocol *prot, unsigned char protocol)
 {
        int hash, ret;
 
index edeea060db4466691f5206679e67b6bd77c28044..19a0612b8a207c3d92aba38e25ce8f01c5e73f72 100644 (file)
@@ -2012,7 +2012,7 @@ int tcp_disconnect(struct sock *sk, int flags)
        tp->snd_cwnd = 2;
        icsk->icsk_probes_out = 0;
        tp->packets_out = 0;
-       tp->snd_ssthresh = 0x7fffffff;
+       tp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
        tp->snd_cwnd_cnt = 0;
        tp->bytes_acked = 0;
        tcp_set_ca_state(sk, TCP_CA_Open);
index af6d6fa00db124f091df1559a31c0bb95d07b8ac..d86784be7ab3d0160122cdd42f071cffaae82351 100644 (file)
@@ -761,7 +761,7 @@ void tcp_update_metrics(struct sock *sk)
                        set_dst_metric_rtt(dst, RTAX_RTTVAR, var);
                }
 
-               if (tp->snd_ssthresh >= 0xFFFF) {
+               if (tcp_in_initial_slowstart(tp)) {
                        /* Slow start still did not finish. */
                        if (dst_metric(dst, RTAX_SSTHRESH) &&
                            !dst_metric_locked(dst, RTAX_SSTHRESH) &&
index 0543561da9992125fa2afe24312c78ddf6f88cbb..7cda24b53f610482dbee6de501334991aba030cb 100644 (file)
@@ -1808,7 +1808,7 @@ static int tcp_v4_init_sock(struct sock *sk)
        /* See draft-stevens-tcpca-spec-01 for discussion of the
         * initialization of these values.
         */
-       tp->snd_ssthresh = 0x7fffffff;  /* Infinity */
+       tp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
        tp->snd_cwnd_clamp = ~0;
        tp->mss_cache = 536;
 
@@ -2284,7 +2284,7 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len)
                jiffies_to_clock_t(icsk->icsk_ack.ato),
                (icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong,
                tp->snd_cwnd,
-               tp->snd_ssthresh >= 0xFFFF ? -1 : tp->snd_ssthresh,
+               tcp_in_initial_slowstart(tp) ? -1 : tp->snd_ssthresh,
                len);
 }
 
index e48c37d74d77a5fd7a4312d338c5a2020f40ddc9..624c3c9b3c2bbe33a37f53b105d041b08ce490ef 100644 (file)
@@ -363,7 +363,7 @@ void tcp_twsk_destructor(struct sock *sk)
 #ifdef CONFIG_TCP_MD5SIG
        struct tcp_timewait_sock *twsk = tcp_twsk(sk);
        if (twsk->tw_md5_keylen)
-               tcp_put_md5sig_pool();
+               tcp_free_md5sig_pool();
 #endif
 }
 
@@ -410,7 +410,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req,
                newtp->retrans_out = 0;
                newtp->sacked_out = 0;
                newtp->fackets_out = 0;
-               newtp->snd_ssthresh = 0x7fffffff;
+               newtp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
 
                /* So many TCP implementations out there (incorrectly) count the
                 * initial SYN frame in their delayed-ACK and congestion control
index cb1f0e83830b408871139ca9a809b5320ea809b7..3959e0ca456a09ce2457e120e2244358629ee428 100644 (file)
@@ -132,7 +132,7 @@ static void tunnel64_err(struct sk_buff *skb, u32 info)
 }
 #endif
 
-static struct net_protocol tunnel4_protocol = {
+static const struct net_protocol tunnel4_protocol = {
        .handler        =       tunnel4_rcv,
        .err_handler    =       tunnel4_err,
        .no_policy      =       1,
@@ -140,7 +140,7 @@ static struct net_protocol tunnel4_protocol = {
 };
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-static struct net_protocol tunnel64_protocol = {
+static const struct net_protocol tunnel64_protocol = {
        .handler        =       tunnel64_rcv,
        .err_handler    =       tunnel64_err,
        .no_policy      =       1,
index c784891cb7e57b3f037b26f858c714bfc9614a33..95248d7f75ec43f9952f78d24b3ff1beaaa3e331 100644 (file)
@@ -25,7 +25,7 @@ static void udplite_err(struct sk_buff *skb, u32 info)
        __udp4_lib_err(skb, info, &udplite_table);
 }
 
-static struct net_protocol udplite_protocol = {
+static const struct net_protocol udplite_protocol = {
        .handler        = udplite_rcv,
        .err_handler    = udplite_err,
        .no_policy      = 1,
index c9b369034a4006562343825f2e73381e4aaf39f8..55f486d89c88eeb1d3e1409cd115cf996c9a8b07 100644 (file)
@@ -137,6 +137,8 @@ static DEFINE_SPINLOCK(addrconf_verify_lock);
 static void addrconf_join_anycast(struct inet6_ifaddr *ifp);
 static void addrconf_leave_anycast(struct inet6_ifaddr *ifp);
 
+static void addrconf_bonding_change(struct net_device *dev,
+                                   unsigned long event);
 static int addrconf_ifdown(struct net_device *dev, int how);
 
 static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags);
@@ -1405,8 +1407,8 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp)
        struct inet6_dev *idev = ifp->idev;
 
        if (net_ratelimit())
-               printk(KERN_INFO "%s: IPv6 duplicate address detected!\n",
-                       ifp->idev->dev->name);
+               printk(KERN_INFO "%s: IPv6 duplicate address %pI6c detected!\n",
+                       ifp->idev->dev->name, &ifp->addr);
 
        if (idev->cnf.accept_dad > 1 && !idev->cnf.disable_ipv6) {
                struct in6_addr addr;
@@ -2582,6 +2584,10 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
                                return notifier_from_errno(err);
                }
                break;
+       case NETDEV_BONDING_OLDTYPE:
+       case NETDEV_BONDING_NEWTYPE:
+               addrconf_bonding_change(dev, event);
+               break;
        }
 
        return NOTIFY_OK;
@@ -2595,6 +2601,19 @@ static struct notifier_block ipv6_dev_notf = {
        .priority = 0
 };
 
+static void addrconf_bonding_change(struct net_device *dev, unsigned long event)
+{
+       struct inet6_dev *idev;
+       ASSERT_RTNL();
+
+       idev = __in6_dev_get(dev);
+
+       if (event == NETDEV_BONDING_NEWTYPE)
+               ipv6_mc_remap(idev);
+       else if (event == NETDEV_BONDING_OLDTYPE)
+               ipv6_mc_unmap(idev);
+}
+
 static int addrconf_ifdown(struct net_device *dev, int how)
 {
        struct inet6_dev *idev;
index a123a328aeb317e3ab0cfa5c4906f3240105a5eb..e127a32f9540fecfaee5de6332ca1be64ce6541f 100644 (file)
@@ -710,7 +710,7 @@ EXPORT_SYMBOL_GPL(ipv6_opt_accepted);
 
 static int ipv6_gso_pull_exthdrs(struct sk_buff *skb, int proto)
 {
-       struct inet6_protocol *ops = NULL;
+       const struct inet6_protocol *ops = NULL;
 
        for (;;) {
                struct ipv6_opt_hdr *opth;
@@ -745,7 +745,7 @@ static int ipv6_gso_pull_exthdrs(struct sk_buff *skb, int proto)
 static int ipv6_gso_send_check(struct sk_buff *skb)
 {
        struct ipv6hdr *ipv6h;
-       struct inet6_protocol *ops;
+       const struct inet6_protocol *ops;
        int err = -EINVAL;
 
        if (unlikely(!pskb_may_pull(skb, sizeof(*ipv6h))))
@@ -773,7 +773,7 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, int features)
 {
        struct sk_buff *segs = ERR_PTR(-EINVAL);
        struct ipv6hdr *ipv6h;
-       struct inet6_protocol *ops;
+       const struct inet6_protocol *ops;
        int proto;
        struct frag_hdr *fptr;
        unsigned int unfrag_ip6hlen;
@@ -840,7 +840,7 @@ struct ipv6_gro_cb {
 static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,
                                         struct sk_buff *skb)
 {
-       struct inet6_protocol *ops;
+       const struct inet6_protocol *ops;
        struct sk_buff **pp = NULL;
        struct sk_buff *p;
        struct ipv6hdr *iph;
@@ -926,7 +926,7 @@ out:
 
 static int ipv6_gro_complete(struct sk_buff *skb)
 {
-       struct inet6_protocol *ops;
+       const struct inet6_protocol *ops;
        struct ipv6hdr *iph = ipv6_hdr(skb);
        int err = -ENOSYS;
 
index 86f42a288c4bb487237ffa6da9944e20d0456efb..c1589e2f1dc9f57d975b94a4a086121ff6bdac92 100644 (file)
@@ -527,7 +527,7 @@ static const struct xfrm_type ah6_type =
        .hdr_offset     = xfrm6_find_1stfragopt,
 };
 
-static struct inet6_protocol ah6_protocol = {
+static const struct inet6_protocol ah6_protocol = {
        .handler        =       xfrm6_rcv,
        .err_handler    =       ah6_err,
        .flags          =       INET6_PROTO_NOPOLICY,
index 678bb95b1525716f2120db6abe3332a7c4e5edab..af597c73ebe9b6bc53f5ae0eb4c91a268a66e47d 100644 (file)
@@ -558,7 +558,7 @@ static const struct xfrm_type esp6_type =
        .hdr_offset     = xfrm6_find_1stfragopt,
 };
 
-static struct inet6_protocol esp6_protocol = {
+static const struct inet6_protocol esp6_protocol = {
        .handler        =       xfrm6_rcv,
        .err_handler    =       esp6_err,
        .flags          =       INET6_PROTO_NOPOLICY,
index 4aae658e55016999c25640c41d2624eb49884903..df159fffe4bca2c373bb1d78bf03959244019bd2 100644 (file)
@@ -500,17 +500,17 @@ unknown_rh:
        return -1;
 }
 
-static struct inet6_protocol rthdr_protocol = {
+static const struct inet6_protocol rthdr_protocol = {
        .handler        =       ipv6_rthdr_rcv,
        .flags          =       INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR,
 };
 
-static struct inet6_protocol destopt_protocol = {
+static const struct inet6_protocol destopt_protocol = {
        .handler        =       ipv6_destopt_rcv,
        .flags          =       INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR,
 };
 
-static struct inet6_protocol nodata_protocol = {
+static const struct inet6_protocol nodata_protocol = {
        .handler        =       dst_discard,
        .flags          =       INET6_PROTO_NOPOLICY,
 };
index e2325f6a05fbd4e9a0d154ca5ddcf6386296760e..f23ebbec0631792407f6ea82827a572027050401 100644 (file)
@@ -86,7 +86,7 @@ static inline struct sock *icmpv6_sk(struct net *net)
 
 static int icmpv6_rcv(struct sk_buff *skb);
 
-static struct inet6_protocol icmpv6_protocol = {
+static const struct inet6_protocol icmpv6_protocol = {
        .handler        =       icmpv6_rcv,
        .flags          =       INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
 };
@@ -583,7 +583,7 @@ out:
 
 static void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info)
 {
-       struct inet6_protocol *ipprot;
+       const struct inet6_protocol *ipprot;
        int inner_offset;
        int hash;
        u8 nexthdr;
index 2d9cbaa67edb7232f6c992e66b8ece1d6d6bafd7..237e2dba6e944772e27e908188d7531e03744b7d 100644 (file)
@@ -159,7 +159,7 @@ drop:
 
 static int ip6_input_finish(struct sk_buff *skb)
 {
-       struct inet6_protocol *ipprot;
+       const struct inet6_protocol *ipprot;
        unsigned int nhoff;
        int nexthdr, raw;
        u8 hash;
index 5c8d73730c75d68dcdb050a5607fa073e1e7e40b..3907510c2ce3e17f21fa9b2d5f151d18edb28f6e 100644 (file)
@@ -83,10 +83,6 @@ static int ip6mr_cache_report(struct net *net, struct sk_buff *pkt,
 static int ip6mr_fill_mroute(struct sk_buff *skb, struct mfc6_cache *c, struct rtmsg *rtm);
 static void mroute_clean_tables(struct net *net);
 
-#ifdef CONFIG_IPV6_PIMSM_V2
-static struct inet6_protocol pim6_protocol;
-#endif
-
 static struct timer_list ipmr_expire_timer;
 
 
@@ -410,7 +406,7 @@ static int pim6_rcv(struct sk_buff *skb)
        return 0;
 }
 
-static struct inet6_protocol pim6_protocol = {
+static const struct inet6_protocol pim6_protocol = {
        .handler        =       pim6_rcv,
 };
 
index 79c172f1ff012d6b7f577ea20febae037ec96dad..2f2a5ca2c8786599560f7328d64401f837ab5e38 100644 (file)
@@ -178,7 +178,7 @@ static const struct xfrm_type ipcomp6_type =
        .hdr_offset     = xfrm6_find_1stfragopt,
 };
 
-static struct inet6_protocol ipcomp6_protocol =
+static const struct inet6_protocol ipcomp6_protocol =
 {
        .handler        = xfrm6_rcv,
        .err_handler    = ipcomp6_err,
index 71c3dacec1ed008c7f291e4aef0b7e6d55fe1c5e..f9fcf690bd5d60781f7c9c1d9e152eafb6712367 100644 (file)
@@ -2249,6 +2249,25 @@ static void igmp6_timer_handler(unsigned long data)
        ma_put(ma);
 }
 
+/* Device changing type */
+
+void ipv6_mc_unmap(struct inet6_dev *idev)
+{
+       struct ifmcaddr6 *i;
+
+       /* Install multicast list, except for all-nodes (already installed) */
+
+       read_lock_bh(&idev->lock);
+       for (i = idev->mc_list; i; i = i->next)
+               igmp6_group_dropped(i);
+       read_unlock_bh(&idev->lock);
+}
+
+void ipv6_mc_remap(struct inet6_dev *idev)
+{
+       ipv6_mc_up(idev);
+}
+
 /* Device going down */
 
 void ipv6_mc_down(struct inet6_dev *idev)
index 568864f722ca5cb92a704c836463572dceaa4b32..1fa3468f0f323782413c1931258c61aa9130f450 100644 (file)
 #include <linux/spinlock.h>
 #include <net/protocol.h>
 
-struct inet6_protocol *inet6_protos[MAX_INET_PROTOS];
+const struct inet6_protocol *inet6_protos[MAX_INET_PROTOS];
 static DEFINE_SPINLOCK(inet6_proto_lock);
 
 
-int inet6_add_protocol(struct inet6_protocol *prot, unsigned char protocol)
+int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char protocol)
 {
        int ret, hash = protocol & (MAX_INET_PROTOS - 1);
 
@@ -53,7 +53,7 @@ EXPORT_SYMBOL(inet6_add_protocol);
  *     Remove a protocol from the hash tables.
  */
 
-int inet6_del_protocol(struct inet6_protocol *prot, unsigned char protocol)
+int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char protocol)
 {
        int ret, hash = protocol & (MAX_INET_PROTOS - 1);
 
index 2642a41a853518bc6405f6934554bdbaad58c875..da5bd0ed83df251a4a5340f382fc1639c2fa9a72 100644 (file)
@@ -627,7 +627,7 @@ fail_hdr:
        return -1;
 }
 
-static struct inet6_protocol frag_protocol =
+static const struct inet6_protocol frag_protocol =
 {
        .handler        =       ipv6_frag_rcv,
        .flags          =       INET6_PROTO_NOPOLICY,
index 9ccfef3455605d1c629c92aaa2f1346c556800a9..77aecbe8ff6caf261c04700d6bea889bb2221a7e 100644 (file)
@@ -481,7 +481,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
 
        pref = rinfo->route_pref;
        if (pref == ICMPV6_ROUTER_PREF_INVALID)
-               pref = ICMPV6_ROUTER_PREF_MEDIUM;
+               return -EINVAL;
 
        lifetime = addrconf_timeout_fixup(ntohl(rinfo->lifetime), HZ);
 
index 3aae0f217d611234a9673ea0fcc7671e46ec6aeb..21d100b68b190dd7d88510f6924713567e20bded 100644 (file)
@@ -1846,7 +1846,7 @@ static int tcp_v6_init_sock(struct sock *sk)
        /* See draft-stevens-tcpca-spec-01 for discussion of the
         * initialization of these values.
         */
-       tp->snd_ssthresh = 0x7fffffff;
+       tp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
        tp->snd_cwnd_clamp = ~0;
        tp->mss_cache = 536;
 
@@ -1969,7 +1969,8 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
                   jiffies_to_clock_t(icsk->icsk_rto),
                   jiffies_to_clock_t(icsk->icsk_ack.ato),
                   (icsk->icsk_ack.quick << 1 ) | icsk->icsk_ack.pingpong,
-                  tp->snd_cwnd, tp->snd_ssthresh>=0xFFFF?-1:tp->snd_ssthresh
+                  tp->snd_cwnd,
+                  tcp_in_initial_slowstart(tp) ? -1 : tp->snd_ssthresh
                   );
 }
 
@@ -2093,7 +2094,7 @@ struct proto tcpv6_prot = {
 #endif
 };
 
-static struct inet6_protocol tcpv6_protocol = {
+static const struct inet6_protocol tcpv6_protocol = {
        .handler        =       tcp_v6_rcv,
        .err_handler    =       tcp_v6_err,
        .gso_send_check =       tcp_v6_gso_send_check,
index 633ad789effc12d0000c9ec3bb2c76192bfcee6e..51e2832d13a661ee862b0ec0cd2e200bc2f5c7dd 100644 (file)
@@ -133,13 +133,13 @@ static void tunnel6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
                        break;
 }
 
-static struct inet6_protocol tunnel6_protocol = {
+static const struct inet6_protocol tunnel6_protocol = {
        .handler        = tunnel6_rcv,
        .err_handler    = tunnel6_err,
        .flags          = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
 };
 
-static struct inet6_protocol tunnel46_protocol = {
+static const struct inet6_protocol tunnel46_protocol = {
        .handler        = tunnel46_rcv,
        .err_handler    = tunnel6_err,
        .flags          = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
index 164040613c2e996760ba756e5db89dd0e4f912a5..b265b7047d3e3b9795c348c92306c3b2b2970255 100644 (file)
@@ -1172,7 +1172,7 @@ out:
        return segs;
 }
 
-static struct inet6_protocol udpv6_protocol = {
+static const struct inet6_protocol udpv6_protocol = {
        .handler        =       udpv6_rcv,
        .err_handler    =       udpv6_err,
        .gso_send_check =       udp6_ufo_send_check,
index 4818c48688f210b31932329204b9c47159c5e44c..d737a27ee010e13e397605154654b3a68dd304c9 100644 (file)
@@ -25,7 +25,7 @@ static void udplitev6_err(struct sk_buff *skb,
        __udp6_lib_err(skb, opt, type, code, offset, info, &udplite_table);
 }
 
-static struct inet6_protocol udplitev6_protocol = {
+static const struct inet6_protocol udplitev6_protocol = {
        .handler        =       udplitev6_rcv,
        .err_handler    =       udplitev6_err,
        .flags          =       INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
index 49c15b48408e5617a5405ba396f1f9b9e427dd5d..d985d163dcfc12590948cefcb5af50af3d08754e 100644 (file)
@@ -34,7 +34,7 @@
 
 static char iucv_userid[80];
 
-static struct proto_ops iucv_sock_ops;
+static const struct proto_ops iucv_sock_ops;
 
 static struct proto iucv_proto = {
        .name           = "AF_IUCV",
@@ -59,8 +59,8 @@ do {                                                                  \
        DEFINE_WAIT(__wait);                                            \
        long __timeo = timeo;                                           \
        ret = 0;                                                        \
+       prepare_to_wait(sk->sk_sleep, &__wait, TASK_INTERRUPTIBLE);     \
        while (!(condition)) {                                          \
-               prepare_to_wait(sk->sk_sleep, &__wait, TASK_INTERRUPTIBLE); \
                if (!__timeo) {                                         \
                        ret = -EAGAIN;                                  \
                        break;                                          \
@@ -361,10 +361,9 @@ static void iucv_sock_cleanup_listen(struct sock *parent)
        }
 
        parent->sk_state = IUCV_CLOSED;
-       sock_set_flag(parent, SOCK_ZAPPED);
 }
 
-/* Kill socket */
+/* Kill socket (only if zapped and orphaned) */
 static void iucv_sock_kill(struct sock *sk)
 {
        if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
@@ -426,17 +425,18 @@ static void iucv_sock_close(struct sock *sk)
 
                skb_queue_purge(&iucv->send_skb_q);
                skb_queue_purge(&iucv->backlog_skb_q);
-
-               sock_set_flag(sk, SOCK_ZAPPED);
                break;
 
        default:
                sock_set_flag(sk, SOCK_ZAPPED);
+               /* nothing to do here */
                break;
        }
 
+       /* mark socket for deletion by iucv_sock_kill() */
+       sock_set_flag(sk, SOCK_ZAPPED);
+
        release_sock(sk);
-       iucv_sock_kill(sk);
 }
 
 static void iucv_sock_init(struct sock *sk, struct sock *parent)
@@ -569,6 +569,7 @@ struct sock *iucv_accept_dequeue(struct sock *parent, struct socket *newsock)
 
                if (sk->sk_state == IUCV_CONNECTED ||
                    sk->sk_state == IUCV_SEVERED ||
+                   sk->sk_state == IUCV_DISCONN ||     /* due to PM restore */
                    !newsock) {
                        iucv_accept_unlink(sk);
                        if (newsock)
@@ -1035,6 +1036,10 @@ out:
        return err;
 }
 
+/* iucv_fragment_skb() - Fragment a single IUCV message into multiple skb's
+ *
+ * Locking: must be called with message_q.lock held
+ */
 static int iucv_fragment_skb(struct sock *sk, struct sk_buff *skb, int len)
 {
        int dataleft, size, copied = 0;
@@ -1069,6 +1074,10 @@ static int iucv_fragment_skb(struct sock *sk, struct sk_buff *skb, int len)
        return 0;
 }
 
+/* iucv_process_message() - Receive a single outstanding IUCV message
+ *
+ * Locking: must be called with message_q.lock held
+ */
 static void iucv_process_message(struct sock *sk, struct sk_buff *skb,
                                 struct iucv_path *path,
                                 struct iucv_message *msg)
@@ -1119,6 +1128,10 @@ static void iucv_process_message(struct sock *sk, struct sk_buff *skb,
                skb_queue_head(&iucv_sk(sk)->backlog_skb_q, skb);
 }
 
+/* iucv_process_message_q() - Process outstanding IUCV messages
+ *
+ * Locking: must be called with message_q.lock held
+ */
 static void iucv_process_message_q(struct sock *sk)
 {
        struct iucv_sock *iucv = iucv_sk(sk);
@@ -1209,6 +1222,7 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
                kfree_skb(skb);
 
                /* Queue backlog skbs */
+               spin_lock_bh(&iucv->message_q.lock);
                rskb = skb_dequeue(&iucv->backlog_skb_q);
                while (rskb) {
                        if (sock_queue_rcv_skb(sk, rskb)) {
@@ -1220,11 +1234,10 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
                        }
                }
                if (skb_queue_empty(&iucv->backlog_skb_q)) {
-                       spin_lock_bh(&iucv->message_q.lock);
                        if (!list_empty(&iucv->message_q.list))
                                iucv_process_message_q(sk);
-                       spin_unlock_bh(&iucv->message_q.lock);
                }
+               spin_unlock_bh(&iucv->message_q.lock);
        }
 
 done:
@@ -1682,7 +1695,7 @@ static void iucv_callback_shutdown(struct iucv_path *path, u8 ipuser[16])
        bh_unlock_sock(sk);
 }
 
-static struct proto_ops iucv_sock_ops = {
+static const struct proto_ops iucv_sock_ops = {
        .family         = PF_IUCV,
        .owner          = THIS_MODULE,
        .release        = iucv_sock_release,
index c833481d32e383439b98504e84a68250d4f9c98e..3973d0e61e56fefef8d0d775b728288061ad295c 100644 (file)
@@ -79,6 +79,14 @@ static int iucv_bus_match(struct device *dev, struct device_driver *drv)
        return 0;
 }
 
+enum iucv_pm_states {
+       IUCV_PM_INITIAL = 0,
+       IUCV_PM_FREEZING = 1,
+       IUCV_PM_THAWING = 2,
+       IUCV_PM_RESTORING = 3,
+};
+static enum iucv_pm_states iucv_pm_state;
+
 static int iucv_pm_prepare(struct device *);
 static void iucv_pm_complete(struct device *);
 static int iucv_pm_freeze(struct device *);
@@ -354,7 +362,7 @@ static int iucv_query_maxconn(void)
                "       srl     %0,28\n"
                : "=d" (ccode), "+d" (reg0), "+d" (reg1) : : "cc");
        if (ccode == 0)
-               iucv_max_pathid = reg0;
+               iucv_max_pathid = reg1;
        kfree(param);
        return ccode ? -EPERM : 0;
 }
@@ -856,7 +864,7 @@ int iucv_path_accept(struct iucv_path *path, struct iucv_handler *handler,
        int rc;
 
        local_bh_disable();
-       if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+       if (cpus_empty(iucv_buffer_cpumask)) {
                rc = -EIO;
                goto out;
        }
@@ -905,7 +913,7 @@ int iucv_path_connect(struct iucv_path *path, struct iucv_handler *handler,
 
        spin_lock_bh(&iucv_table_lock);
        iucv_cleanup_queue();
-       if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+       if (cpus_empty(iucv_buffer_cpumask)) {
                rc = -EIO;
                goto out;
        }
@@ -965,7 +973,7 @@ int iucv_path_quiesce(struct iucv_path *path, u8 userdata[16])
        int rc;
 
        local_bh_disable();
-       if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+       if (cpus_empty(iucv_buffer_cpumask)) {
                rc = -EIO;
                goto out;
        }
@@ -997,7 +1005,7 @@ int iucv_path_resume(struct iucv_path *path, u8 userdata[16])
        int rc;
 
        local_bh_disable();
-       if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+       if (cpus_empty(iucv_buffer_cpumask)) {
                rc = -EIO;
                goto out;
        }
@@ -1026,7 +1034,7 @@ int iucv_path_sever(struct iucv_path *path, u8 userdata[16])
        int rc;
 
        preempt_disable();
-       if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+       if (cpus_empty(iucv_buffer_cpumask)) {
                rc = -EIO;
                goto out;
        }
@@ -1060,7 +1068,7 @@ int iucv_message_purge(struct iucv_path *path, struct iucv_message *msg,
        int rc;
 
        local_bh_disable();
-       if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+       if (cpus_empty(iucv_buffer_cpumask)) {
                rc = -EIO;
                goto out;
        }
@@ -1152,7 +1160,7 @@ int __iucv_message_receive(struct iucv_path *path, struct iucv_message *msg,
        if (msg->flags & IUCV_IPRMDATA)
                return iucv_message_receive_iprmdata(path, msg, flags,
                                                     buffer, size, residual);
-       if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+       if (cpus_empty(iucv_buffer_cpumask)) {
                rc = -EIO;
                goto out;
        }
@@ -1225,7 +1233,7 @@ int iucv_message_reject(struct iucv_path *path, struct iucv_message *msg)
        int rc;
 
        local_bh_disable();
-       if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+       if (cpus_empty(iucv_buffer_cpumask)) {
                rc = -EIO;
                goto out;
        }
@@ -1264,7 +1272,7 @@ int iucv_message_reply(struct iucv_path *path, struct iucv_message *msg,
        int rc;
 
        local_bh_disable();
-       if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+       if (cpus_empty(iucv_buffer_cpumask)) {
                rc = -EIO;
                goto out;
        }
@@ -1314,7 +1322,7 @@ int __iucv_message_send(struct iucv_path *path, struct iucv_message *msg,
        union iucv_param *parm;
        int rc;
 
-       if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+       if (cpus_empty(iucv_buffer_cpumask)) {
                rc = -EIO;
                goto out;
        }
@@ -1401,7 +1409,7 @@ int iucv_message_send2way(struct iucv_path *path, struct iucv_message *msg,
        int rc;
 
        local_bh_disable();
-       if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+       if (cpus_empty(iucv_buffer_cpumask)) {
                rc = -EIO;
                goto out;
        }
@@ -1875,6 +1883,7 @@ static int iucv_pm_freeze(struct device *dev)
 #ifdef CONFIG_PM_DEBUG
        printk(KERN_WARNING "iucv_pm_freeze\n");
 #endif
+       iucv_pm_state = IUCV_PM_FREEZING;
        for_each_cpu_mask_nr(cpu, iucv_irq_cpumask)
                smp_call_function_single(cpu, iucv_block_cpu_almost, NULL, 1);
        if (dev->driver && dev->driver->pm && dev->driver->pm->freeze)
@@ -1899,6 +1908,7 @@ static int iucv_pm_thaw(struct device *dev)
 #ifdef CONFIG_PM_DEBUG
        printk(KERN_WARNING "iucv_pm_thaw\n");
 #endif
+       iucv_pm_state = IUCV_PM_THAWING;
        if (!iucv_path_table) {
                rc = iucv_enable();
                if (rc)
@@ -1933,6 +1943,10 @@ static int iucv_pm_restore(struct device *dev)
 #ifdef CONFIG_PM_DEBUG
        printk(KERN_WARNING "iucv_pm_restore %p\n", iucv_path_table);
 #endif
+       if ((iucv_pm_state != IUCV_PM_RESTORING) && iucv_path_table)
+               pr_warning("Suspending Linux did not completely close all IUCV "
+                       "connections\n");
+       iucv_pm_state = IUCV_PM_RESTORING;
        if (cpus_empty(iucv_irq_cpumask)) {
                rc = iucv_query_maxconn();
                rc = iucv_enable();
index 7c5142988bbb77f140d373e26414f9bd0dec31b7..6e5d68b4e427a232dfeebcfe98f666bb2618bb1c 100644 (file)
@@ -418,7 +418,7 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband,
 
                        /* contention window */
                        tx_time_single += t_slot + min(cw, mp->cw_max);
-                       cw = (cw + 1) << 1;
+                       cw = (cw << 1) | 1;
 
                        tx_time += tx_time_single;
                        tx_time_cts += tx_time_single + mi->sp_ack_dur;
index d0ff382c40ca96cfe66752379039218714c966a1..c5aab6a368ce250badd33ab0d30e858292f91521 100644 (file)
@@ -177,9 +177,11 @@ static void netlink_sock_destruct(struct sock *sk)
  * this, _but_ remember, it adds useless work on UP machines.
  */
 
-static void netlink_table_grab(void)
+void netlink_table_grab(void)
        __acquires(nl_table_lock)
 {
+       might_sleep();
+
        write_lock_irq(&nl_table_lock);
 
        if (atomic_read(&nl_table_users)) {
@@ -200,7 +202,7 @@ static void netlink_table_grab(void)
        }
 }
 
-static void netlink_table_ungrab(void)
+void netlink_table_ungrab(void)
        __releases(nl_table_lock)
 {
        write_unlock_irq(&nl_table_lock);
@@ -1549,37 +1551,21 @@ static void netlink_free_old_listeners(struct rcu_head *rcu_head)
        kfree(lrh->ptr);
 }
 
-/**
- * netlink_change_ngroups - change number of multicast groups
- *
- * This changes the number of multicast groups that are available
- * on a certain netlink family. Note that it is not possible to
- * change the number of groups to below 32. Also note that it does
- * not implicitly call netlink_clear_multicast_users() when the
- * number of groups is reduced.
- *
- * @sk: The kernel netlink socket, as returned by netlink_kernel_create().
- * @groups: The new number of groups.
- */
-int netlink_change_ngroups(struct sock *sk, unsigned int groups)
+int __netlink_change_ngroups(struct sock *sk, unsigned int groups)
 {
        unsigned long *listeners, *old = NULL;
        struct listeners_rcu_head *old_rcu_head;
        struct netlink_table *tbl = &nl_table[sk->sk_protocol];
-       int err = 0;
 
        if (groups < 32)
                groups = 32;
 
-       netlink_table_grab();
        if (NLGRPSZ(tbl->groups) < NLGRPSZ(groups)) {
                listeners = kzalloc(NLGRPSZ(groups) +
                                    sizeof(struct listeners_rcu_head),
                                    GFP_ATOMIC);
-               if (!listeners) {
-                       err = -ENOMEM;
-                       goto out_ungrab;
-               }
+               if (!listeners)
+                       return -ENOMEM;
                old = tbl->listeners;
                memcpy(listeners, old, NLGRPSZ(tbl->groups));
                rcu_assign_pointer(tbl->listeners, listeners);
@@ -1597,8 +1583,29 @@ int netlink_change_ngroups(struct sock *sk, unsigned int groups)
        }
        tbl->groups = groups;
 
- out_ungrab:
+       return 0;
+}
+
+/**
+ * netlink_change_ngroups - change number of multicast groups
+ *
+ * This changes the number of multicast groups that are available
+ * on a certain netlink family. Note that it is not possible to
+ * change the number of groups to below 32. Also note that it does
+ * not implicitly call netlink_clear_multicast_users() when the
+ * number of groups is reduced.
+ *
+ * @sk: The kernel netlink socket, as returned by netlink_kernel_create().
+ * @groups: The new number of groups.
+ */
+int netlink_change_ngroups(struct sock *sk, unsigned int groups)
+{
+       int err;
+
+       netlink_table_grab();
+       err = __netlink_change_ngroups(sk, groups);
        netlink_table_ungrab();
+
        return err;
 }
 
index 66f6ba0bab11932c9b1302a555f9bcefb52065dd..566941e03363fbdd7591ded5ed16b41f0a903c7c 100644 (file)
@@ -176,9 +176,10 @@ int genl_register_mc_group(struct genl_family *family,
        if (family->netnsok) {
                struct net *net;
 
+               netlink_table_grab();
                rcu_read_lock();
                for_each_net_rcu(net) {
-                       err = netlink_change_ngroups(net->genl_sock,
+                       err = __netlink_change_ngroups(net->genl_sock,
                                        mc_groups_longs * BITS_PER_LONG);
                        if (err) {
                                /*
@@ -188,10 +189,12 @@ int genl_register_mc_group(struct genl_family *family,
                                 * increased on some sockets which is ok.
                                 */
                                rcu_read_unlock();
+                               netlink_table_ungrab();
                                goto out;
                        }
                }
                rcu_read_unlock();
+               netlink_table_ungrab();
        } else {
                err = netlink_change_ngroups(init_net.genl_sock,
                                             mc_groups_longs * BITS_PER_LONG);
index 2f65dcaed2fb072056ee2b3a11a89fa7033dc903..5f42f30dd1682bdc2427e7b387390fe231ab305e 100644 (file)
@@ -209,7 +209,14 @@ static int phonet_device_autoconf(struct net_device *dev)
                                                SIOCPNGAUTOCONF);
        if (ret < 0)
                return ret;
-       return phonet_address_add(dev, req.ifr_phonet_autoconf.device);
+
+       ASSERT_RTNL();
+       ret = phonet_address_add(dev, req.ifr_phonet_autoconf.device);
+       if (ret)
+               return ret;
+       phonet_address_notify(RTM_NEWADDR, dev,
+                               req.ifr_phonet_autoconf.device);
+       return 0;
 }
 
 /* notify Phonet of device events */
index 108ed2e671c5599a413d028feb1591962c978004..6b58aeff4c7ab72b4072799b63e2f0dd8d466a5c 100644 (file)
@@ -359,7 +359,7 @@ static struct proto rds_proto = {
        .obj_size = sizeof(struct rds_sock),
 };
 
-static struct proto_ops rds_proto_ops = {
+static const struct proto_ops rds_proto_ops = {
        .family =       AF_RDS,
        .owner =        THIS_MODULE,
        .release =      rds_release,
index e5f478ca3d61574e01bc74bad58cfdc910a33b4a..1e166c9685aac9c479eb7720a28f7dff4ecaa6f2 100644 (file)
@@ -63,7 +63,7 @@ int sysctl_rose_window_size             = ROSE_DEFAULT_WINDOW_SIZE;
 static HLIST_HEAD(rose_list);
 static DEFINE_SPINLOCK(rose_list_lock);
 
-static struct proto_ops rose_proto_ops;
+static const struct proto_ops rose_proto_ops;
 
 ax25_address rose_callsign;
 
@@ -1515,7 +1515,7 @@ static struct net_proto_family rose_family_ops = {
        .owner          =       THIS_MODULE,
 };
 
-static struct proto_ops rose_proto_ops = {
+static const struct proto_ops rose_proto_ops = {
        .family         =       PF_ROSE,
        .owner          =       THIS_MODULE,
        .release        =       rose_release,
index c9f1f0a3a2ff4a520e3c7a002115e7e646c2cee4..b4a2209770311a4fdce0757c9857bbdd6fdf2f39 100644 (file)
@@ -40,7 +40,7 @@ static const s8 rxrpc_ack_priority[] = {
 /*
  * propose an ACK be sent
  */
-void __rxrpc_propose_ACK(struct rxrpc_call *call, uint8_t ack_reason,
+void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason,
                         __be32 serial, bool immediate)
 {
        unsigned long expiry;
@@ -120,7 +120,7 @@ cancel_timer:
 /*
  * propose an ACK be sent, locking the call structure
  */
-void rxrpc_propose_ACK(struct rxrpc_call *call, uint8_t ack_reason,
+void rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason,
                       __be32 serial, bool immediate)
 {
        s8 prior = rxrpc_ack_priority[ack_reason];
@@ -520,7 +520,7 @@ static void rxrpc_zap_tx_window(struct rxrpc_call *call)
        struct rxrpc_skb_priv *sp;
        struct sk_buff *skb;
        unsigned long _skb, *acks_window;
-       uint8_t winsz = call->acks_winsz;
+       u8 winsz = call->acks_winsz;
        int tail;
 
        acks_window = call->acks_window;
index 3e7318c1343cb886d3aacf4e70df5b50200349ab..7043b294bb67d6266621949aa20cd5e6fa7180c4 100644 (file)
@@ -229,7 +229,7 @@ struct rxrpc_conn_bundle {
        int                     debug_id;       /* debug ID for printks */
        unsigned short          num_conns;      /* number of connections in this bundle */
        __be16                  service_id;     /* service ID */
-       uint8_t                 security_ix;    /* security type */
+       u8                      security_ix;    /* security type */
 };
 
 /*
@@ -370,10 +370,10 @@ struct rxrpc_call {
        u8                      channel;        /* connection channel occupied by this call */
 
        /* transmission-phase ACK management */
-       uint8_t                 acks_head;      /* offset into window of first entry */
-       uint8_t                 acks_tail;      /* offset into window of last entry */
-       uint8_t                 acks_winsz;     /* size of un-ACK'd window */
-       uint8_t                 acks_unacked;   /* lowest unacked packet in last ACK received */
+       u8                      acks_head;      /* offset into window of first entry */
+       u8                      acks_tail;      /* offset into window of last entry */
+       u8                      acks_winsz;     /* size of un-ACK'd window */
+       u8                      acks_unacked;   /* lowest unacked packet in last ACK received */
        int                     acks_latest;    /* serial number of latest ACK received */
        rxrpc_seq_t             acks_hard;      /* highest definitively ACK'd msg seq */
        unsigned long           *acks_window;   /* sent packet window
@@ -388,7 +388,7 @@ struct rxrpc_call {
        rxrpc_seq_t             rx_first_oos;   /* first packet in rx_oos_queue (or 0) */
        rxrpc_seq_t             ackr_win_top;   /* top of ACK window (rx_data_eaten is bottom) */
        rxrpc_seq_net_t         ackr_prev_seq;  /* previous sequence number received */
-       uint8_t                 ackr_reason;    /* reason to ACK */
+       u8                      ackr_reason;    /* reason to ACK */
        __be32                  ackr_serial;    /* serial of packet being ACK'd */
        atomic_t                ackr_not_idle;  /* number of packets in Rx queue */
 
@@ -401,22 +401,6 @@ struct rxrpc_call {
        __be32                  call_id;        /* call ID on connection  */
 };
 
-/*
- * RxRPC key for Kerberos (type-2 security)
- */
-struct rxkad_key {
-       u16     security_index;         /* RxRPC header security index */
-       u16     ticket_len;             /* length of ticket[] */
-       u32     expiry;                 /* time at which expires */
-       u32     kvno;                   /* key version number */
-       u8      session_key[8];         /* DES session key */
-       u8      ticket[0];              /* the encrypted ticket */
-};
-
-struct rxrpc_key_payload {
-       struct rxkad_key k;
-};
-
 /*
  * locally abort an RxRPC call
  */
@@ -450,8 +434,8 @@ extern int rxrpc_reject_call(struct rxrpc_sock *);
 /*
  * ar-ack.c
  */
-extern void __rxrpc_propose_ACK(struct rxrpc_call *, uint8_t, __be32, bool);
-extern void rxrpc_propose_ACK(struct rxrpc_call *, uint8_t, __be32, bool);
+extern void __rxrpc_propose_ACK(struct rxrpc_call *, u8, __be32, bool);
+extern void rxrpc_propose_ACK(struct rxrpc_call *, u8, __be32, bool);
 extern void rxrpc_process_call(struct work_struct *);
 
 /*
index ad8c7a782da1f0daabcd7ff1f9076e1785ae0f23..74697b2004962059857c6b42e84a5490befce23d 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/skbuff.h>
 #include <linux/key-type.h>
 #include <linux/crypto.h>
+#include <linux/ctype.h>
 #include <net/sock.h>
 #include <net/af_rxrpc.h>
 #include <keys/rxrpc-type.h>
@@ -28,6 +29,7 @@ static int rxrpc_instantiate_s(struct key *, const void *, size_t);
 static void rxrpc_destroy(struct key *);
 static void rxrpc_destroy_s(struct key *);
 static void rxrpc_describe(const struct key *, struct seq_file *);
+static long rxrpc_read(const struct key *, char __user *, size_t);
 
 /*
  * rxrpc defined keys take an arbitrary string as the description and an
@@ -39,6 +41,7 @@ struct key_type key_type_rxrpc = {
        .match          = user_match,
        .destroy        = rxrpc_destroy,
        .describe       = rxrpc_describe,
+       .read           = rxrpc_read,
 };
 EXPORT_SYMBOL(key_type_rxrpc);
 
@@ -54,6 +57,595 @@ struct key_type key_type_rxrpc_s = {
        .describe       = rxrpc_describe,
 };
 
+/*
+ * parse an RxKAD type XDR format token
+ * - the caller guarantees we have at least 4 words
+ */
+static int rxrpc_instantiate_xdr_rxkad(struct key *key, const __be32 *xdr,
+                                      unsigned toklen)
+{
+       struct rxrpc_key_token *token, **pptoken;
+       size_t plen;
+       u32 tktlen;
+       int ret;
+
+       _enter(",{%x,%x,%x,%x},%u",
+              ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]),
+              toklen);
+
+       if (toklen <= 8 * 4)
+               return -EKEYREJECTED;
+       tktlen = ntohl(xdr[7]);
+       _debug("tktlen: %x", tktlen);
+       if (tktlen > AFSTOKEN_RK_TIX_MAX)
+               return -EKEYREJECTED;
+       if (8 * 4 + tktlen != toklen)
+               return -EKEYREJECTED;
+
+       plen = sizeof(*token) + sizeof(*token->kad) + tktlen;
+       ret = key_payload_reserve(key, key->datalen + plen);
+       if (ret < 0)
+               return ret;
+
+       plen -= sizeof(*token);
+       token = kmalloc(sizeof(*token), GFP_KERNEL);
+       if (!token)
+               return -ENOMEM;
+
+       token->kad = kmalloc(plen, GFP_KERNEL);
+       if (!token->kad) {
+               kfree(token);
+               return -ENOMEM;
+       }
+
+       token->security_index   = RXRPC_SECURITY_RXKAD;
+       token->kad->ticket_len  = tktlen;
+       token->kad->vice_id     = ntohl(xdr[0]);
+       token->kad->kvno        = ntohl(xdr[1]);
+       token->kad->start       = ntohl(xdr[4]);
+       token->kad->expiry      = ntohl(xdr[5]);
+       token->kad->primary_flag = ntohl(xdr[6]);
+       memcpy(&token->kad->session_key, &xdr[2], 8);
+       memcpy(&token->kad->ticket, &xdr[8], tktlen);
+
+       _debug("SCIX: %u", token->security_index);
+       _debug("TLEN: %u", token->kad->ticket_len);
+       _debug("EXPY: %x", token->kad->expiry);
+       _debug("KVNO: %u", token->kad->kvno);
+       _debug("PRIM: %u", token->kad->primary_flag);
+       _debug("SKEY: %02x%02x%02x%02x%02x%02x%02x%02x",
+              token->kad->session_key[0], token->kad->session_key[1],
+              token->kad->session_key[2], token->kad->session_key[3],
+              token->kad->session_key[4], token->kad->session_key[5],
+              token->kad->session_key[6], token->kad->session_key[7]);
+       if (token->kad->ticket_len >= 8)
+               _debug("TCKT: %02x%02x%02x%02x%02x%02x%02x%02x",
+                      token->kad->ticket[0], token->kad->ticket[1],
+                      token->kad->ticket[2], token->kad->ticket[3],
+                      token->kad->ticket[4], token->kad->ticket[5],
+                      token->kad->ticket[6], token->kad->ticket[7]);
+
+       /* count the number of tokens attached */
+       key->type_data.x[0]++;
+
+       /* attach the data */
+       for (pptoken = (struct rxrpc_key_token **)&key->payload.data;
+            *pptoken;
+            pptoken = &(*pptoken)->next)
+               continue;
+       *pptoken = token;
+       if (token->kad->expiry < key->expiry)
+               key->expiry = token->kad->expiry;
+
+       _leave(" = 0");
+       return 0;
+}
+
+static void rxrpc_free_krb5_principal(struct krb5_principal *princ)
+{
+       int loop;
+
+       if (princ->name_parts) {
+               for (loop = princ->n_name_parts - 1; loop >= 0; loop--)
+                       kfree(princ->name_parts[loop]);
+               kfree(princ->name_parts);
+       }
+       kfree(princ->realm);
+}
+
+static void rxrpc_free_krb5_tagged(struct krb5_tagged_data *td)
+{
+       kfree(td->data);
+}
+
+/*
+ * free up an RxK5 token
+ */
+static void rxrpc_rxk5_free(struct rxk5_key *rxk5)
+{
+       int loop;
+
+       rxrpc_free_krb5_principal(&rxk5->client);
+       rxrpc_free_krb5_principal(&rxk5->server);
+       rxrpc_free_krb5_tagged(&rxk5->session);
+
+       if (rxk5->addresses) {
+               for (loop = rxk5->n_addresses - 1; loop >= 0; loop--)
+                       rxrpc_free_krb5_tagged(&rxk5->addresses[loop]);
+               kfree(rxk5->addresses);
+       }
+       if (rxk5->authdata) {
+               for (loop = rxk5->n_authdata - 1; loop >= 0; loop--)
+                       rxrpc_free_krb5_tagged(&rxk5->authdata[loop]);
+               kfree(rxk5->authdata);
+       }
+
+       kfree(rxk5->ticket);
+       kfree(rxk5->ticket2);
+       kfree(rxk5);
+}
+
+/*
+ * extract a krb5 principal
+ */
+static int rxrpc_krb5_decode_principal(struct krb5_principal *princ,
+                                      const __be32 **_xdr,
+                                      unsigned *_toklen)
+{
+       const __be32 *xdr = *_xdr;
+       unsigned toklen = *_toklen, n_parts, loop, tmp;
+
+       /* there must be at least one name, and at least #names+1 length
+        * words */
+       if (toklen <= 12)
+               return -EINVAL;
+
+       _enter(",{%x,%x,%x},%u",
+              ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), toklen);
+
+       n_parts = ntohl(*xdr++);
+       toklen -= 4;
+       if (n_parts <= 0 || n_parts > AFSTOKEN_K5_COMPONENTS_MAX)
+               return -EINVAL;
+       princ->n_name_parts = n_parts;
+
+       if (toklen <= (n_parts + 1) * 4)
+               return -EINVAL;
+
+       princ->name_parts = kcalloc(sizeof(char *), n_parts, GFP_KERNEL);
+       if (!princ->name_parts)
+               return -ENOMEM;
+
+       for (loop = 0; loop < n_parts; loop++) {
+               if (toklen < 4)
+                       return -EINVAL;
+               tmp = ntohl(*xdr++);
+               toklen -= 4;
+               if (tmp <= 0 || tmp > AFSTOKEN_STRING_MAX)
+                       return -EINVAL;
+               if (tmp > toklen)
+                       return -EINVAL;
+               princ->name_parts[loop] = kmalloc(tmp + 1, GFP_KERNEL);
+               if (!princ->name_parts[loop])
+                       return -ENOMEM;
+               memcpy(princ->name_parts[loop], xdr, tmp);
+               princ->name_parts[loop][tmp] = 0;
+               tmp = (tmp + 3) & ~3;
+               toklen -= tmp;
+               xdr += tmp >> 2;
+       }
+
+       if (toklen < 4)
+               return -EINVAL;
+       tmp = ntohl(*xdr++);
+       toklen -= 4;
+       if (tmp <= 0 || tmp > AFSTOKEN_K5_REALM_MAX)
+               return -EINVAL;
+       if (tmp > toklen)
+               return -EINVAL;
+       princ->realm = kmalloc(tmp + 1, GFP_KERNEL);
+       if (!princ->realm)
+               return -ENOMEM;
+       memcpy(princ->realm, xdr, tmp);
+       princ->realm[tmp] = 0;
+       tmp = (tmp + 3) & ~3;
+       toklen -= tmp;
+       xdr += tmp >> 2;
+
+       _debug("%s/...@%s", princ->name_parts[0], princ->realm);
+
+       *_xdr = xdr;
+       *_toklen = toklen;
+       _leave(" = 0 [toklen=%u]", toklen);
+       return 0;
+}
+
+/*
+ * extract a piece of krb5 tagged data
+ */
+static int rxrpc_krb5_decode_tagged_data(struct krb5_tagged_data *td,
+                                        size_t max_data_size,
+                                        const __be32 **_xdr,
+                                        unsigned *_toklen)
+{
+       const __be32 *xdr = *_xdr;
+       unsigned toklen = *_toklen, len;
+
+       /* there must be at least one tag and one length word */
+       if (toklen <= 8)
+               return -EINVAL;
+
+       _enter(",%zu,{%x,%x},%u",
+              max_data_size, ntohl(xdr[0]), ntohl(xdr[1]), toklen);
+
+       td->tag = ntohl(*xdr++);
+       len = ntohl(*xdr++);
+       toklen -= 8;
+       if (len > max_data_size)
+               return -EINVAL;
+       td->data_len = len;
+
+       if (len > 0) {
+               td->data = kmalloc(len, GFP_KERNEL);
+               if (!td->data)
+                       return -ENOMEM;
+               memcpy(td->data, xdr, len);
+               len = (len + 3) & ~3;
+               toklen -= len;
+               xdr += len >> 2;
+       }
+
+       _debug("tag %x len %x", td->tag, td->data_len);
+
+       *_xdr = xdr;
+       *_toklen = toklen;
+       _leave(" = 0 [toklen=%u]", toklen);
+       return 0;
+}
+
+/*
+ * extract an array of tagged data
+ */
+static int rxrpc_krb5_decode_tagged_array(struct krb5_tagged_data **_td,
+                                         u8 *_n_elem,
+                                         u8 max_n_elem,
+                                         size_t max_elem_size,
+                                         const __be32 **_xdr,
+                                         unsigned *_toklen)
+{
+       struct krb5_tagged_data *td;
+       const __be32 *xdr = *_xdr;
+       unsigned toklen = *_toklen, n_elem, loop;
+       int ret;
+
+       /* there must be at least one count */
+       if (toklen < 4)
+               return -EINVAL;
+
+       _enter(",,%u,%zu,{%x},%u",
+              max_n_elem, max_elem_size, ntohl(xdr[0]), toklen);
+
+       n_elem = ntohl(*xdr++);
+       toklen -= 4;
+       if (n_elem < 0 || n_elem > max_n_elem)
+               return -EINVAL;
+       *_n_elem = n_elem;
+       if (n_elem > 0) {
+               if (toklen <= (n_elem + 1) * 4)
+                       return -EINVAL;
+
+               _debug("n_elem %d", n_elem);
+
+               td = kcalloc(sizeof(struct krb5_tagged_data), n_elem,
+                            GFP_KERNEL);
+               if (!td)
+                       return -ENOMEM;
+               *_td = td;
+
+               for (loop = 0; loop < n_elem; loop++) {
+                       ret = rxrpc_krb5_decode_tagged_data(&td[loop],
+                                                           max_elem_size,
+                                                           &xdr, &toklen);
+                       if (ret < 0)
+                               return ret;
+               }
+       }
+
+       *_xdr = xdr;
+       *_toklen = toklen;
+       _leave(" = 0 [toklen=%u]", toklen);
+       return 0;
+}
+
+/*
+ * extract a krb5 ticket
+ */
+static int rxrpc_krb5_decode_ticket(u8 **_ticket, u16 *_tktlen,
+                                   const __be32 **_xdr, unsigned *_toklen)
+{
+       const __be32 *xdr = *_xdr;
+       unsigned toklen = *_toklen, len;
+
+       /* there must be at least one length word */
+       if (toklen <= 4)
+               return -EINVAL;
+
+       _enter(",{%x},%u", ntohl(xdr[0]), toklen);
+
+       len = ntohl(*xdr++);
+       toklen -= 4;
+       if (len > AFSTOKEN_K5_TIX_MAX)
+               return -EINVAL;
+       *_tktlen = len;
+
+       _debug("ticket len %u", len);
+
+       if (len > 0) {
+               *_ticket = kmalloc(len, GFP_KERNEL);
+               if (!*_ticket)
+                       return -ENOMEM;
+               memcpy(*_ticket, xdr, len);
+               len = (len + 3) & ~3;
+               toklen -= len;
+               xdr += len >> 2;
+       }
+
+       *_xdr = xdr;
+       *_toklen = toklen;
+       _leave(" = 0 [toklen=%u]", toklen);
+       return 0;
+}
+
+/*
+ * parse an RxK5 type XDR format token
+ * - the caller guarantees we have at least 4 words
+ */
+static int rxrpc_instantiate_xdr_rxk5(struct key *key, const __be32 *xdr,
+                                     unsigned toklen)
+{
+       struct rxrpc_key_token *token, **pptoken;
+       struct rxk5_key *rxk5;
+       const __be32 *end_xdr = xdr + (toklen >> 2);
+       int ret;
+
+       _enter(",{%x,%x,%x,%x},%u",
+              ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]),
+              toklen);
+
+       /* reserve some payload space for this subkey - the length of the token
+        * is a reasonable approximation */
+       ret = key_payload_reserve(key, key->datalen + toklen);
+       if (ret < 0)
+               return ret;
+
+       token = kzalloc(sizeof(*token), GFP_KERNEL);
+       if (!token)
+               return -ENOMEM;
+
+       rxk5 = kzalloc(sizeof(*rxk5), GFP_KERNEL);
+       if (!rxk5) {
+               kfree(token);
+               return -ENOMEM;
+       }
+
+       token->security_index = RXRPC_SECURITY_RXK5;
+       token->k5 = rxk5;
+
+       /* extract the principals */
+       ret = rxrpc_krb5_decode_principal(&rxk5->client, &xdr, &toklen);
+       if (ret < 0)
+               goto error;
+       ret = rxrpc_krb5_decode_principal(&rxk5->server, &xdr, &toklen);
+       if (ret < 0)
+               goto error;
+
+       /* extract the session key and the encoding type (the tag field ->
+        * ENCTYPE_xxx) */
+       ret = rxrpc_krb5_decode_tagged_data(&rxk5->session, AFSTOKEN_DATA_MAX,
+                                           &xdr, &toklen);
+       if (ret < 0)
+               goto error;
+
+       if (toklen < 4 * 8 + 2 * 4)
+               goto inval;
+       rxk5->authtime  = be64_to_cpup((const __be64 *) xdr);
+       xdr += 2;
+       rxk5->starttime = be64_to_cpup((const __be64 *) xdr);
+       xdr += 2;
+       rxk5->endtime   = be64_to_cpup((const __be64 *) xdr);
+       xdr += 2;
+       rxk5->renew_till = be64_to_cpup((const __be64 *) xdr);
+       xdr += 2;
+       rxk5->is_skey = ntohl(*xdr++);
+       rxk5->flags = ntohl(*xdr++);
+       toklen -= 4 * 8 + 2 * 4;
+
+       _debug("times: a=%llx s=%llx e=%llx rt=%llx",
+              rxk5->authtime, rxk5->starttime, rxk5->endtime,
+              rxk5->renew_till);
+       _debug("is_skey=%x flags=%x", rxk5->is_skey, rxk5->flags);
+
+       /* extract the permitted client addresses */
+       ret = rxrpc_krb5_decode_tagged_array(&rxk5->addresses,
+                                            &rxk5->n_addresses,
+                                            AFSTOKEN_K5_ADDRESSES_MAX,
+                                            AFSTOKEN_DATA_MAX,
+                                            &xdr, &toklen);
+       if (ret < 0)
+               goto error;
+
+       ASSERTCMP((end_xdr - xdr) << 2, ==, toklen);
+
+       /* extract the tickets */
+       ret = rxrpc_krb5_decode_ticket(&rxk5->ticket, &rxk5->ticket_len,
+                                      &xdr, &toklen);
+       if (ret < 0)
+               goto error;
+       ret = rxrpc_krb5_decode_ticket(&rxk5->ticket2, &rxk5->ticket2_len,
+                                      &xdr, &toklen);
+       if (ret < 0)
+               goto error;
+
+       ASSERTCMP((end_xdr - xdr) << 2, ==, toklen);
+
+       /* extract the typed auth data */
+       ret = rxrpc_krb5_decode_tagged_array(&rxk5->authdata,
+                                            &rxk5->n_authdata,
+                                            AFSTOKEN_K5_AUTHDATA_MAX,
+                                            AFSTOKEN_BDATALN_MAX,
+                                            &xdr, &toklen);
+       if (ret < 0)
+               goto error;
+
+       ASSERTCMP((end_xdr - xdr) << 2, ==, toklen);
+
+       if (toklen != 0)
+               goto inval;
+
+       /* attach the payload to the key */
+       for (pptoken = (struct rxrpc_key_token **)&key->payload.data;
+            *pptoken;
+            pptoken = &(*pptoken)->next)
+               continue;
+       *pptoken = token;
+       if (token->kad->expiry < key->expiry)
+               key->expiry = token->kad->expiry;
+
+       _leave(" = 0");
+       return 0;
+
+inval:
+       ret = -EINVAL;
+error:
+       rxrpc_rxk5_free(rxk5);
+       kfree(token);
+       _leave(" = %d", ret);
+       return ret;
+}
+
+/*
+ * attempt to parse the data as the XDR format
+ * - the caller guarantees we have more than 7 words
+ */
+static int rxrpc_instantiate_xdr(struct key *key, const void *data, size_t datalen)
+{
+       const __be32 *xdr = data, *token;
+       const char *cp;
+       unsigned len, tmp, loop, ntoken, toklen, sec_ix;
+       int ret;
+
+       _enter(",{%x,%x,%x,%x},%zu",
+              ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]),
+              datalen);
+
+       if (datalen > AFSTOKEN_LENGTH_MAX)
+               goto not_xdr;
+
+       /* XDR is an array of __be32's */
+       if (datalen & 3)
+               goto not_xdr;
+
+       /* the flags should be 0 (the setpag bit must be handled by
+        * userspace) */
+       if (ntohl(*xdr++) != 0)
+               goto not_xdr;
+       datalen -= 4;
+
+       /* check the cell name */
+       len = ntohl(*xdr++);
+       if (len < 1 || len > AFSTOKEN_CELL_MAX)
+               goto not_xdr;
+       datalen -= 4;
+       tmp = (len + 3) & ~3;
+       if (tmp > datalen)
+               goto not_xdr;
+
+       cp = (const char *) xdr;
+       for (loop = 0; loop < len; loop++)
+               if (!isprint(cp[loop]))
+                       goto not_xdr;
+       if (len < tmp)
+               for (; loop < tmp; loop++)
+                       if (cp[loop])
+                               goto not_xdr;
+       _debug("cellname: [%u/%u] '%*.*s'",
+              len, tmp, len, len, (const char *) xdr);
+       datalen -= tmp;
+       xdr += tmp >> 2;
+
+       /* get the token count */
+       if (datalen < 12)
+               goto not_xdr;
+       ntoken = ntohl(*xdr++);
+       datalen -= 4;
+       _debug("ntoken: %x", ntoken);
+       if (ntoken < 1 || ntoken > AFSTOKEN_MAX)
+               goto not_xdr;
+
+       /* check each token wrapper */
+       token = xdr;
+       loop = ntoken;
+       do {
+               if (datalen < 8)
+                       goto not_xdr;
+               toklen = ntohl(*xdr++);
+               sec_ix = ntohl(*xdr);
+               datalen -= 4;
+               _debug("token: [%x/%zx] %x", toklen, datalen, sec_ix);
+               if (toklen < 20 || toklen > datalen)
+                       goto not_xdr;
+               datalen -= (toklen + 3) & ~3;
+               xdr += (toklen + 3) >> 2;
+
+       } while (--loop > 0);
+
+       _debug("remainder: %zu", datalen);
+       if (datalen != 0)
+               goto not_xdr;
+
+       /* okay: we're going to assume it's valid XDR format
+        * - we ignore the cellname, relying on the key to be correctly named
+        */
+       do {
+               xdr = token;
+               toklen = ntohl(*xdr++);
+               token = xdr + ((toklen + 3) >> 2);
+               sec_ix = ntohl(*xdr++);
+               toklen -= 4;
+
+               _debug("TOKEN type=%u [%p-%p]", sec_ix, xdr, token);
+
+               switch (sec_ix) {
+               case RXRPC_SECURITY_RXKAD:
+                       ret = rxrpc_instantiate_xdr_rxkad(key, xdr, toklen);
+                       if (ret != 0)
+                               goto error;
+                       break;
+
+               case RXRPC_SECURITY_RXK5:
+                       ret = rxrpc_instantiate_xdr_rxk5(key, xdr, toklen);
+                       if (ret != 0)
+                               goto error;
+                       break;
+
+               default:
+                       ret = -EPROTONOSUPPORT;
+                       goto error;
+               }
+
+       } while (--ntoken > 0);
+
+       _leave(" = 0");
+       return 0;
+
+not_xdr:
+       _leave(" = -EPROTO");
+       return -EPROTO;
+error:
+       _leave(" = %d", ret);
+       return ret;
+}
+
 /*
  * instantiate an rxrpc defined key
  * data should be of the form:
@@ -70,8 +662,8 @@ struct key_type key_type_rxrpc_s = {
  */
 static int rxrpc_instantiate(struct key *key, const void *data, size_t datalen)
 {
-       const struct rxkad_key *tsec;
-       struct rxrpc_key_payload *upayload;
+       const struct rxrpc_key_data_v1 *v1;
+       struct rxrpc_key_token *token, **pp;
        size_t plen;
        u32 kver;
        int ret;
@@ -82,6 +674,13 @@ static int rxrpc_instantiate(struct key *key, const void *data, size_t datalen)
        if (!data && datalen == 0)
                return 0;
 
+       /* determine if the XDR payload format is being used */
+       if (datalen > 7 * 4) {
+               ret = rxrpc_instantiate_xdr(key, data, datalen);
+               if (ret != -EPROTO)
+                       return ret;
+       }
+
        /* get the key interface version number */
        ret = -EINVAL;
        if (datalen <= 4 || !data)
@@ -98,53 +697,67 @@ static int rxrpc_instantiate(struct key *key, const void *data, size_t datalen)
 
        /* deal with a version 1 key */
        ret = -EINVAL;
-       if (datalen < sizeof(*tsec))
+       if (datalen < sizeof(*v1))
                goto error;
 
-       tsec = data;
-       if (datalen != sizeof(*tsec) + tsec->ticket_len)
+       v1 = data;
+       if (datalen != sizeof(*v1) + v1->ticket_length)
                goto error;
 
-       _debug("SCIX: %u", tsec->security_index);
-       _debug("TLEN: %u", tsec->ticket_len);
-       _debug("EXPY: %x", tsec->expiry);
-       _debug("KVNO: %u", tsec->kvno);
+       _debug("SCIX: %u", v1->security_index);
+       _debug("TLEN: %u", v1->ticket_length);
+       _debug("EXPY: %x", v1->expiry);
+       _debug("KVNO: %u", v1->kvno);
        _debug("SKEY: %02x%02x%02x%02x%02x%02x%02x%02x",
-              tsec->session_key[0], tsec->session_key[1],
-              tsec->session_key[2], tsec->session_key[3],
-              tsec->session_key[4], tsec->session_key[5],
-              tsec->session_key[6], tsec->session_key[7]);
-       if (tsec->ticket_len >= 8)
+              v1->session_key[0], v1->session_key[1],
+              v1->session_key[2], v1->session_key[3],
+              v1->session_key[4], v1->session_key[5],
+              v1->session_key[6], v1->session_key[7]);
+       if (v1->ticket_length >= 8)
                _debug("TCKT: %02x%02x%02x%02x%02x%02x%02x%02x",
-                      tsec->ticket[0], tsec->ticket[1],
-                      tsec->ticket[2], tsec->ticket[3],
-                      tsec->ticket[4], tsec->ticket[5],
-                      tsec->ticket[6], tsec->ticket[7]);
+                      v1->ticket[0], v1->ticket[1],
+                      v1->ticket[2], v1->ticket[3],
+                      v1->ticket[4], v1->ticket[5],
+                      v1->ticket[6], v1->ticket[7]);
 
        ret = -EPROTONOSUPPORT;
-       if (tsec->security_index != 2)
+       if (v1->security_index != RXRPC_SECURITY_RXKAD)
                goto error;
 
-       key->type_data.x[0] = tsec->security_index;
-
-       plen = sizeof(*upayload) + tsec->ticket_len;
-       ret = key_payload_reserve(key, plen);
+       plen = sizeof(*token->kad) + v1->ticket_length;
+       ret = key_payload_reserve(key, plen + sizeof(*token));
        if (ret < 0)
                goto error;
 
        ret = -ENOMEM;
-       upayload = kmalloc(plen, GFP_KERNEL);
-       if (!upayload)
+       token = kmalloc(sizeof(*token), GFP_KERNEL);
+       if (!token)
                goto error;
+       token->kad = kmalloc(plen, GFP_KERNEL);
+       if (!token->kad)
+               goto error_free;
+
+       token->security_index           = RXRPC_SECURITY_RXKAD;
+       token->kad->ticket_len          = v1->ticket_length;
+       token->kad->expiry              = v1->expiry;
+       token->kad->kvno                = v1->kvno;
+       memcpy(&token->kad->session_key, &v1->session_key, 8);
+       memcpy(&token->kad->ticket, v1->ticket, v1->ticket_length);
 
        /* attach the data */
-       memcpy(&upayload->k, tsec, sizeof(*tsec));
-       memcpy(&upayload->k.ticket, (void *)tsec + sizeof(*tsec),
-              tsec->ticket_len);
-       key->payload.data = upayload;
-       key->expiry = tsec->expiry;
+       key->type_data.x[0]++;
+
+       pp = (struct rxrpc_key_token **)&key->payload.data;
+       while (*pp)
+               pp = &(*pp)->next;
+       *pp = token;
+       if (token->kad->expiry < key->expiry)
+               key->expiry = token->kad->expiry;
+       token = NULL;
        ret = 0;
 
+error_free:
+       kfree(token);
 error:
        return ret;
 }
@@ -184,7 +797,26 @@ static int rxrpc_instantiate_s(struct key *key, const void *data,
  */
 static void rxrpc_destroy(struct key *key)
 {
-       kfree(key->payload.data);
+       struct rxrpc_key_token *token;
+
+       while ((token = key->payload.data)) {
+               key->payload.data = token->next;
+               switch (token->security_index) {
+               case RXRPC_SECURITY_RXKAD:
+                       kfree(token->kad);
+                       break;
+               case RXRPC_SECURITY_RXK5:
+                       if (token->k5)
+                               rxrpc_rxk5_free(token->k5);
+                       break;
+               default:
+                       printk(KERN_ERR "Unknown token type %x on rxrpc key\n",
+                              token->security_index);
+                       BUG();
+               }
+
+               kfree(token);
+       }
 }
 
 /*
@@ -293,7 +925,7 @@ int rxrpc_get_server_data_key(struct rxrpc_connection *conn,
 
        struct {
                u32 kver;
-               struct rxkad_key tsec;
+               struct rxrpc_key_data_v1 v1;
        } data;
 
        _enter("");
@@ -308,13 +940,12 @@ int rxrpc_get_server_data_key(struct rxrpc_connection *conn,
        _debug("key %d", key_serial(key));
 
        data.kver = 1;
-       data.tsec.security_index = 2;
-       data.tsec.ticket_len = 0;
-       data.tsec.expiry = expiry;
-       data.tsec.kvno = 0;
+       data.v1.security_index = RXRPC_SECURITY_RXKAD;
+       data.v1.ticket_length = 0;
+       data.v1.expiry = expiry;
+       data.v1.kvno = 0;
 
-       memcpy(&data.tsec.session_key, session_key,
-              sizeof(data.tsec.session_key));
+       memcpy(&data.v1.session_key, session_key, sizeof(data.v1.session_key));
 
        ret = key_instantiate_and_link(key, &data, sizeof(data), NULL, NULL);
        if (ret < 0)
@@ -360,3 +991,210 @@ struct key *rxrpc_get_null_key(const char *keyname)
        return key;
 }
 EXPORT_SYMBOL(rxrpc_get_null_key);
+
+/*
+ * read the contents of an rxrpc key
+ * - this returns the result in XDR form
+ */
+static long rxrpc_read(const struct key *key,
+                      char __user *buffer, size_t buflen)
+{
+       const struct rxrpc_key_token *token;
+       const struct krb5_principal *princ;
+       size_t size;
+       __be32 __user *xdr, *oldxdr;
+       u32 cnlen, toksize, ntoks, tok, zero;
+       u16 toksizes[AFSTOKEN_MAX];
+       int loop;
+
+       _enter("");
+
+       /* we don't know what form we should return non-AFS keys in */
+       if (memcmp(key->description, "afs@", 4) != 0)
+               return -EOPNOTSUPP;
+       cnlen = strlen(key->description + 4);
+
+#define RND(X) (((X) + 3) & ~3)
+
+       /* AFS keys we return in XDR form, so we need to work out the size of
+        * the XDR */
+       size = 2 * 4;   /* flags, cellname len */
+       size += RND(cnlen);     /* cellname */
+       size += 1 * 4;  /* token count */
+
+       ntoks = 0;
+       for (token = key->payload.data; token; token = token->next) {
+               toksize = 4;    /* sec index */
+
+               switch (token->security_index) {
+               case RXRPC_SECURITY_RXKAD:
+                       toksize += 8 * 4;       /* viceid, kvno, key*2, begin,
+                                                * end, primary, tktlen */
+                       toksize += RND(token->kad->ticket_len);
+                       break;
+
+               case RXRPC_SECURITY_RXK5:
+                       princ = &token->k5->client;
+                       toksize += 4 + princ->n_name_parts * 4;
+                       for (loop = 0; loop < princ->n_name_parts; loop++)
+                               toksize += RND(strlen(princ->name_parts[loop]));
+                       toksize += 4 + RND(strlen(princ->realm));
+
+                       princ = &token->k5->server;
+                       toksize += 4 + princ->n_name_parts * 4;
+                       for (loop = 0; loop < princ->n_name_parts; loop++)
+                               toksize += RND(strlen(princ->name_parts[loop]));
+                       toksize += 4 + RND(strlen(princ->realm));
+
+                       toksize += 8 + RND(token->k5->session.data_len);
+
+                       toksize += 4 * 8 + 2 * 4;
+
+                       toksize += 4 + token->k5->n_addresses * 8;
+                       for (loop = 0; loop < token->k5->n_addresses; loop++)
+                               toksize += RND(token->k5->addresses[loop].data_len);
+
+                       toksize += 4 + RND(token->k5->ticket_len);
+                       toksize += 4 + RND(token->k5->ticket2_len);
+
+                       toksize += 4 + token->k5->n_authdata * 8;
+                       for (loop = 0; loop < token->k5->n_authdata; loop++)
+                               toksize += RND(token->k5->authdata[loop].data_len);
+                       break;
+
+               default: /* we have a ticket we can't encode */
+                       BUG();
+                       continue;
+               }
+
+               _debug("token[%u]: toksize=%u", ntoks, toksize);
+               ASSERTCMP(toksize, <=, AFSTOKEN_LENGTH_MAX);
+
+               toksizes[ntoks++] = toksize;
+               size += toksize + 4; /* each token has a length word */
+       }
+
+#undef RND
+
+       if (!buffer || buflen < size)
+               return size;
+
+       xdr = (__be32 __user *) buffer;
+       zero = 0;
+#define ENCODE(x)                              \
+       do {                                    \
+               __be32 y = htonl(x);            \
+               if (put_user(y, xdr++) < 0)     \
+                       goto fault;             \
+       } while(0)
+#define ENCODE_DATA(l, s)                                              \
+       do {                                                            \
+               u32 _l = (l);                                           \
+               ENCODE(l);                                              \
+               if (copy_to_user(xdr, (s), _l) != 0)                    \
+                       goto fault;                                     \
+               if (_l & 3 &&                                           \
+                   copy_to_user((u8 *)xdr + _l, &zero, 4 - (_l & 3)) != 0) \
+                       goto fault;                                     \
+               xdr += (_l + 3) >> 2;                                   \
+       } while(0)
+#define ENCODE64(x)                                    \
+       do {                                            \
+               __be64 y = cpu_to_be64(x);              \
+               if (copy_to_user(xdr, &y, 8) != 0)      \
+                       goto fault;                     \
+               xdr += 8 >> 2;                          \
+       } while(0)
+#define ENCODE_STR(s)                          \
+       do {                                    \
+               const char *_s = (s);           \
+               ENCODE_DATA(strlen(_s), _s);    \
+       } while(0)
+
+       ENCODE(0);                                      /* flags */
+       ENCODE_DATA(cnlen, key->description + 4);       /* cellname */
+       ENCODE(ntoks);
+
+       tok = 0;
+       for (token = key->payload.data; token; token = token->next) {
+               toksize = toksizes[tok++];
+               ENCODE(toksize);
+               oldxdr = xdr;
+               ENCODE(token->security_index);
+
+               switch (token->security_index) {
+               case RXRPC_SECURITY_RXKAD:
+                       ENCODE(token->kad->vice_id);
+                       ENCODE(token->kad->kvno);
+                       ENCODE_DATA(8, token->kad->session_key);
+                       ENCODE(token->kad->start);
+                       ENCODE(token->kad->expiry);
+                       ENCODE(token->kad->primary_flag);
+                       ENCODE_DATA(token->kad->ticket_len, token->kad->ticket);
+                       break;
+
+               case RXRPC_SECURITY_RXK5:
+                       princ = &token->k5->client;
+                       ENCODE(princ->n_name_parts);
+                       for (loop = 0; loop < princ->n_name_parts; loop++)
+                               ENCODE_STR(princ->name_parts[loop]);
+                       ENCODE_STR(princ->realm);
+
+                       princ = &token->k5->server;
+                       ENCODE(princ->n_name_parts);
+                       for (loop = 0; loop < princ->n_name_parts; loop++)
+                               ENCODE_STR(princ->name_parts[loop]);
+                       ENCODE_STR(princ->realm);
+
+                       ENCODE(token->k5->session.tag);
+                       ENCODE_DATA(token->k5->session.data_len,
+                                   token->k5->session.data);
+
+                       ENCODE64(token->k5->authtime);
+                       ENCODE64(token->k5->starttime);
+                       ENCODE64(token->k5->endtime);
+                       ENCODE64(token->k5->renew_till);
+                       ENCODE(token->k5->is_skey);
+                       ENCODE(token->k5->flags);
+
+                       ENCODE(token->k5->n_addresses);
+                       for (loop = 0; loop < token->k5->n_addresses; loop++) {
+                               ENCODE(token->k5->addresses[loop].tag);
+                               ENCODE_DATA(token->k5->addresses[loop].data_len,
+                                           token->k5->addresses[loop].data);
+                       }
+
+                       ENCODE_DATA(token->k5->ticket_len, token->k5->ticket);
+                       ENCODE_DATA(token->k5->ticket2_len, token->k5->ticket2);
+
+                       ENCODE(token->k5->n_authdata);
+                       for (loop = 0; loop < token->k5->n_authdata; loop++) {
+                               ENCODE(token->k5->authdata[loop].tag);
+                               ENCODE_DATA(token->k5->authdata[loop].data_len,
+                                           token->k5->authdata[loop].data);
+                       }
+                       break;
+
+               default:
+                       BUG();
+                       break;
+               }
+
+               ASSERTCMP((unsigned long)xdr - (unsigned long)oldxdr, ==,
+                         toksize);
+       }
+
+#undef ENCODE_STR
+#undef ENCODE_DATA
+#undef ENCODE64
+#undef ENCODE
+
+       ASSERTCMP(tok, ==, ntoks);
+       ASSERTCMP((char __user *) xdr - buffer, ==, size);
+       _leave(" = %zu", size);
+       return size;
+
+fault:
+       _leave(" = -EFAULT");
+       return -EFAULT;
+}
index dc62920ee19ad5a430f5c6361bc01119f1746def..49b3cc31ee1f505b65bf21f6042e6727e2d2ed93 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/crypto.h>
 #include <net/sock.h>
 #include <net/af_rxrpc.h>
+#include <keys/rxrpc-type.h>
 #include "ar-internal.h"
 
 static LIST_HEAD(rxrpc_security_methods);
@@ -122,6 +123,7 @@ EXPORT_SYMBOL_GPL(rxrpc_unregister_security);
  */
 int rxrpc_init_client_conn_security(struct rxrpc_connection *conn)
 {
+       struct rxrpc_key_token *token;
        struct rxrpc_security *sec;
        struct key *key = conn->key;
        int ret;
@@ -135,7 +137,11 @@ int rxrpc_init_client_conn_security(struct rxrpc_connection *conn)
        if (ret < 0)
                return ret;
 
-       sec = rxrpc_security_lookup(key->type_data.x[0]);
+       if (!key->payload.data)
+               return -EKEYREJECTED;
+       token = key->payload.data;
+
+       sec = rxrpc_security_lookup(token->security_index);
        if (!sec)
                return -EKEYREJECTED;
        conn->security = sec;
index ef8f91030a150ff6cb4605c8229dd1955b3528e0..713ac593e2e96d5a21b43958ff3ebb67816a8a3c 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/ctype.h>
 #include <net/sock.h>
 #include <net/af_rxrpc.h>
+#include <keys/rxrpc-type.h>
 #define rxrpc_debug rxkad_debug
 #include "ar-internal.h"
 
@@ -42,7 +43,7 @@ struct rxkad_level2_hdr {
        __be32  checksum;       /* decrypted data checksum */
 };
 
-MODULE_DESCRIPTION("RxRPC network protocol type-2 security (Kerberos)");
+MODULE_DESCRIPTION("RxRPC network protocol type-2 security (Kerberos 4)");
 MODULE_AUTHOR("Red Hat, Inc.");
 MODULE_LICENSE("GPL");
 
@@ -59,14 +60,14 @@ static DEFINE_MUTEX(rxkad_ci_mutex);
  */
 static int rxkad_init_connection_security(struct rxrpc_connection *conn)
 {
-       struct rxrpc_key_payload *payload;
        struct crypto_blkcipher *ci;
+       struct rxrpc_key_token *token;
        int ret;
 
        _enter("{%d},{%x}", conn->debug_id, key_serial(conn->key));
 
-       payload = conn->key->payload.data;
-       conn->security_ix = payload->k.security_index;
+       token = conn->key->payload.data;
+       conn->security_ix = token->security_index;
 
        ci = crypto_alloc_blkcipher("pcbc(fcrypt)", 0, CRYPTO_ALG_ASYNC);
        if (IS_ERR(ci)) {
@@ -75,8 +76,8 @@ static int rxkad_init_connection_security(struct rxrpc_connection *conn)
                goto error;
        }
 
-       if (crypto_blkcipher_setkey(ci, payload->k.session_key,
-                                   sizeof(payload->k.session_key)) < 0)
+       if (crypto_blkcipher_setkey(ci, token->kad->session_key,
+                                   sizeof(token->kad->session_key)) < 0)
                BUG();
 
        switch (conn->security_level) {
@@ -110,7 +111,7 @@ error:
  */
 static void rxkad_prime_packet_security(struct rxrpc_connection *conn)
 {
-       struct rxrpc_key_payload *payload;
+       struct rxrpc_key_token *token;
        struct blkcipher_desc desc;
        struct scatterlist sg[2];
        struct rxrpc_crypt iv;
@@ -123,8 +124,8 @@ static void rxkad_prime_packet_security(struct rxrpc_connection *conn)
        if (!conn->key)
                return;
 
-       payload = conn->key->payload.data;
-       memcpy(&iv, payload->k.session_key, sizeof(iv));
+       token = conn->key->payload.data;
+       memcpy(&iv, token->kad->session_key, sizeof(iv));
 
        desc.tfm = conn->cipher;
        desc.info = iv.x;
@@ -197,7 +198,7 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call,
                                        u32 data_size,
                                        void *sechdr)
 {
-       const struct rxrpc_key_payload *payload;
+       const struct rxrpc_key_token *token;
        struct rxkad_level2_hdr rxkhdr
                __attribute__((aligned(8))); /* must be all on one page */
        struct rxrpc_skb_priv *sp;
@@ -219,8 +220,8 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call,
        rxkhdr.checksum = 0;
 
        /* encrypt from the session key */
-       payload = call->conn->key->payload.data;
-       memcpy(&iv, payload->k.session_key, sizeof(iv));
+       token = call->conn->key->payload.data;
+       memcpy(&iv, token->kad->session_key, sizeof(iv));
        desc.tfm = call->conn->cipher;
        desc.info = iv.x;
        desc.flags = 0;
@@ -400,7 +401,7 @@ static int rxkad_verify_packet_encrypt(const struct rxrpc_call *call,
                                       struct sk_buff *skb,
                                       u32 *_abort_code)
 {
-       const struct rxrpc_key_payload *payload;
+       const struct rxrpc_key_token *token;
        struct rxkad_level2_hdr sechdr;
        struct rxrpc_skb_priv *sp;
        struct blkcipher_desc desc;
@@ -431,8 +432,8 @@ static int rxkad_verify_packet_encrypt(const struct rxrpc_call *call,
        skb_to_sgvec(skb, sg, 0, skb->len);
 
        /* decrypt from the session key */
-       payload = call->conn->key->payload.data;
-       memcpy(&iv, payload->k.session_key, sizeof(iv));
+       token = call->conn->key->payload.data;
+       memcpy(&iv, token->kad->session_key, sizeof(iv));
        desc.tfm = call->conn->cipher;
        desc.info = iv.x;
        desc.flags = 0;
@@ -506,7 +507,7 @@ static int rxkad_verify_packet(const struct rxrpc_call *call,
        if (!call->conn->cipher)
                return 0;
 
-       if (sp->hdr.securityIndex != 2) {
+       if (sp->hdr.securityIndex != RXRPC_SECURITY_RXKAD) {
                *_abort_code = RXKADINCONSISTENCY;
                _leave(" = -EPROTO [not rxkad]");
                return -EPROTO;
@@ -737,7 +738,7 @@ static int rxkad_respond_to_challenge(struct rxrpc_connection *conn,
                                      struct sk_buff *skb,
                                      u32 *_abort_code)
 {
-       const struct rxrpc_key_payload *payload;
+       const struct rxrpc_key_token *token;
        struct rxkad_challenge challenge;
        struct rxkad_response resp
                __attribute__((aligned(8))); /* must be aligned for crypto */
@@ -778,7 +779,7 @@ static int rxkad_respond_to_challenge(struct rxrpc_connection *conn,
        if (conn->security_level < min_level)
                goto protocol_error;
 
-       payload = conn->key->payload.data;
+       token = conn->key->payload.data;
 
        /* build the response packet */
        memset(&resp, 0, sizeof(resp));
@@ -797,13 +798,13 @@ static int rxkad_respond_to_challenge(struct rxrpc_connection *conn,
                (conn->channels[3] ? conn->channels[3]->call_id : 0);
        resp.encrypted.inc_nonce = htonl(nonce + 1);
        resp.encrypted.level = htonl(conn->security_level);
-       resp.kvno = htonl(payload->k.kvno);
-       resp.ticket_len = htonl(payload->k.ticket_len);
+       resp.kvno = htonl(token->kad->kvno);
+       resp.ticket_len = htonl(token->kad->ticket_len);
 
        /* calculate the response checksum and then do the encryption */
        rxkad_calc_response_checksum(&resp);
-       rxkad_encrypt_response(conn, &resp, &payload->k);
-       return rxkad_send_response(conn, &sp->hdr, &resp, &payload->k);
+       rxkad_encrypt_response(conn, &resp, token->kad);
+       return rxkad_send_response(conn, &sp->hdr, &resp, token->kad);
 
 protocol_error:
        *_abort_code = abort_code;
@@ -1122,7 +1123,7 @@ static void rxkad_clear(struct rxrpc_connection *conn)
 static struct rxrpc_security rxkad = {
        .owner                          = THIS_MODULE,
        .name                           = "rxkad",
-       .security_index                 = RXKAD_VERSION,
+       .security_index                 = RXRPC_SECURITY_RXKAD,
        .init_connection_security       = rxkad_init_connection_security,
        .prime_packet_security          = rxkad_prime_packet_security,
        .secure_packet                  = rxkad_secure_packet,
index 692d9a41cd23e714f77eda461323962e11c3a7b8..903e4188b6ca1057426f8327f0bb1d69f00afb0b 100644 (file)
@@ -693,13 +693,18 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
                        if (new && i > 0)
                                atomic_inc(&new->refcnt);
 
-                       qdisc_destroy(old);
+                       if (!ingress)
+                               qdisc_destroy(old);
                }
 
-               notify_and_destroy(skb, n, classid, dev->qdisc, new);
-               if (new && !new->ops->attach)
-                       atomic_inc(&new->refcnt);
-               dev->qdisc = new ? : &noop_qdisc;
+               if (!ingress) {
+                       notify_and_destroy(skb, n, classid, dev->qdisc, new);
+                       if (new && !new->ops->attach)
+                               atomic_inc(&new->refcnt);
+                       dev->qdisc = new ? : &noop_qdisc;
+               } else {
+                       notify_and_destroy(skb, n, classid, old, new);
+               }
 
                if (dev->flags & IFF_UP)
                        dev_activate(dev);
@@ -804,7 +809,7 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
                        stab = qdisc_get_stab(tca[TCA_STAB]);
                        if (IS_ERR(stab)) {
                                err = PTR_ERR(stab);
-                               goto err_out3;
+                               goto err_out4;
                        }
                        sch->stab = stab;
                }
@@ -833,7 +838,6 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
                return sch;
        }
 err_out3:
-       qdisc_put_stab(sch->stab);
        dev_put(dev);
        kfree((char *) sch - sch->padded);
 err_out2:
@@ -847,6 +851,7 @@ err_out4:
         * Any broken qdiscs that would require a ops->reset() here?
         * The qdisc was never in action so it shouldn't be necessary.
         */
+       qdisc_put_stab(sch->stab);
        if (ops->destroy)
                ops->destroy(sch);
        goto err_out3;
@@ -1111,12 +1116,16 @@ create_n_graft:
                                 tcm->tcm_parent, tcm->tcm_parent,
                                 tca, &err);
        else {
-               unsigned int ntx = 0;
+               struct netdev_queue *dev_queue;
 
                if (p && p->ops->cl_ops && p->ops->cl_ops->select_queue)
-                       ntx = p->ops->cl_ops->select_queue(p, tcm);
+                       dev_queue = p->ops->cl_ops->select_queue(p, tcm);
+               else if (p)
+                       dev_queue = p->dev_queue;
+               else
+                       dev_queue = netdev_get_tx_queue(dev, 0);
 
-               q = qdisc_create(dev, netdev_get_tx_queue(dev, ntx), p,
+               q = qdisc_create(dev, dev_queue, p,
                                 tcm->tcm_parent, tcm->tcm_handle,
                                 tca, &err);
        }
index 12b2fb04b29b6d4d873e6fe28981dabd7de039b6..5a888af7e5daed2f46d3293a843de8182f3f6cc3 100644 (file)
@@ -274,8 +274,10 @@ static int drr_dump_class_stats(struct Qdisc *sch, unsigned long arg,
        struct tc_drr_stats xstats;
 
        memset(&xstats, 0, sizeof(xstats));
-       if (cl->qdisc->q.qlen)
+       if (cl->qdisc->q.qlen) {
                xstats.deficit = cl->deficit;
+               cl->qdisc->qstats.qlen = cl->qdisc->q.qlen;
+       }
 
        if (gnet_stats_copy_basic(d, &cl->bstats) < 0 ||
            gnet_stats_copy_rate_est(d, &cl->rate_est) < 0 ||
index dd5ee022f1f7c1d76b28b4fd76028880db6ecaa5..d1dea3d5dc929f1dc2051b2ed42f65168c88aa09 100644 (file)
@@ -125,13 +125,18 @@ static struct netdev_queue *mq_queue_get(struct Qdisc *sch, unsigned long cl)
        return netdev_get_tx_queue(dev, ntx);
 }
 
-static unsigned int mq_select_queue(struct Qdisc *sch, struct tcmsg *tcm)
+static struct netdev_queue *mq_select_queue(struct Qdisc *sch,
+                                           struct tcmsg *tcm)
 {
        unsigned int ntx = TC_H_MIN(tcm->tcm_parent);
+       struct netdev_queue *dev_queue = mq_queue_get(sch, ntx);
 
-       if (!mq_queue_get(sch, ntx))
-               return 0;
-       return ntx - 1;
+       if (!dev_queue) {
+               struct net_device *dev = qdisc_dev(sch);
+
+               return netdev_get_tx_queue(dev, 0);
+       }
+       return dev_queue;
 }
 
 static int mq_graft(struct Qdisc *sch, unsigned long cl, struct Qdisc *new,
@@ -188,6 +193,7 @@ static int mq_dump_class_stats(struct Qdisc *sch, unsigned long cl,
        struct netdev_queue *dev_queue = mq_queue_get(sch, cl);
 
        sch = dev_queue->qdisc_sleeping;
+       sch->qstats.qlen = sch->q.qlen;
        if (gnet_stats_copy_basic(d, &sch->bstats) < 0 ||
            gnet_stats_copy_queue(d, &sch->qstats) < 0)
                return -1;
index 069f81c972778cda6f26b4c276b6b1495f10da5b..7db2c88ce585f04a7361b87dec3aa2760d65f1f3 100644 (file)
@@ -359,6 +359,7 @@ static int multiq_dump_class_stats(struct Qdisc *sch, unsigned long cl,
        struct Qdisc *cl_q;
 
        cl_q = q->queues[cl - 1];
+       cl_q->qstats.qlen = cl_q->q.qlen;
        if (gnet_stats_copy_basic(d, &cl_q->bstats) < 0 ||
            gnet_stats_copy_queue(d, &cl_q->qstats) < 0)
                return -1;
index 0f73c412d04b6005091fc69b0fb068a3e94bb662..93285cecb246942b5640809d34e7d17d9ee1d63a 100644 (file)
@@ -322,6 +322,7 @@ static int prio_dump_class_stats(struct Qdisc *sch, unsigned long cl,
        struct Qdisc *cl_q;
 
        cl_q = q->queues[cl - 1];
+       cl_q->qstats.qlen = cl_q->q.qlen;
        if (gnet_stats_copy_basic(d, &cl_q->bstats) < 0 ||
            gnet_stats_copy_queue(d, &cl_q->qstats) < 0)
                return -1;
index 6a4b19094143653ab79a43de52d916fd8ed2a0f0..bb280e60e00a9f23c93ae1047ef1934af62ad81c 100644 (file)
@@ -949,7 +949,7 @@ static int sctp6_rcv(struct sk_buff *skb)
        return sctp_rcv(skb) ? -1 : 0;
 }
 
-static struct inet6_protocol sctpv6_protocol = {
+static const struct inet6_protocol sctpv6_protocol = {
        .handler      = sctp6_rcv,
        .err_handler  = sctp_v6_err,
        .flags        = INET6_PROTO_NOPOLICY | INET6_PROTO_FINAL,
index 60093be8385d68fa27ba002e6c84e51db437a2dd..c557f1fb1c66ac79647ff91cf80f72c59e0baf05 100644 (file)
@@ -924,7 +924,7 @@ static struct inet_protosw sctp_stream_protosw = {
 };
 
 /* Register with IP layer.  */
-static struct net_protocol sctp_protocol = {
+static const struct net_protocol sctp_protocol = {
        .handler     = sctp_rcv,
        .err_handler = sctp_v4_err,
        .no_policy   = 1,
index 6d47165590473daa4990bf69b0435d5c49b41302..2a022c00d85c509e2346a8afac33eaa63154439a 100644 (file)
@@ -489,6 +489,7 @@ static struct socket *sock_alloc(void)
 
        sock = SOCKET_I(inode);
 
+       kmemcheck_annotate_bitfield(sock, type);
        inode->i_mode = S_IFSOCK | S_IRWXUGO;
        inode->i_uid = current_fsuid();
        inode->i_gid = current_fsgid();
index 4c210c2debc6773e3b84b703a3ca3b5b3fd941b2..e5f92ee758f44226999112603a4f3d59a23f222f 100644 (file)
@@ -662,7 +662,7 @@ int cfg80211_wext_siwscan(struct net_device *dev,
                                int k;
                                int wiphy_freq = wiphy->bands[band]->channels[j].center_freq;
                                for (k = 0; k < wreq->num_channels; k++) {
-                                       int wext_freq = wreq->channel_list[k].m / 100000;
+                                       int wext_freq = cfg80211_wext_freq(wiphy, &wreq->channel_list[k]);
                                        if (wext_freq == wiphy_freq)
                                                goto wext_freq_found;
                                }
@@ -675,6 +675,11 @@ int cfg80211_wext_siwscan(struct net_device *dev,
                wext_freq_not_found: ;
                }
        }
+       /* No channels found? */
+       if (!i) {
+               err = -EINVAL;
+               goto out;
+       }
 
        /* Set real number of channels specified in creq->channels[] */
        creq->n_channels = i;
index 68307883ec87ad36145ce6f00e63eb2c9fcb64ed..7fae7eee65def0b24d17aa1046c37a496bcf04b6 100644 (file)
@@ -188,7 +188,7 @@ void cfg80211_conn_work(struct work_struct *work)
        rtnl_unlock();
 }
 
-static bool cfg80211_get_conn_bss(struct wireless_dev *wdev)
+static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev)
 {
        struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
        struct cfg80211_bss *bss;
@@ -205,7 +205,7 @@ static bool cfg80211_get_conn_bss(struct wireless_dev *wdev)
                               WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_PRIVACY,
                               capa);
        if (!bss)
-               return false;
+               return NULL;
 
        memcpy(wdev->conn->bssid, bss->bssid, ETH_ALEN);
        wdev->conn->params.bssid = wdev->conn->bssid;
@@ -213,14 +213,14 @@ static bool cfg80211_get_conn_bss(struct wireless_dev *wdev)
        wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
        schedule_work(&rdev->conn_work);
 
-       cfg80211_put_bss(bss);
-       return true;
+       return bss;
 }
 
 static void __cfg80211_sme_scan_done(struct net_device *dev)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+       struct cfg80211_bss *bss;
 
        ASSERT_WDEV_LOCK(wdev);
 
@@ -234,7 +234,10 @@ static void __cfg80211_sme_scan_done(struct net_device *dev)
            wdev->conn->state != CFG80211_CONN_SCAN_AGAIN)
                return;
 
-       if (!cfg80211_get_conn_bss(wdev)) {
+       bss = cfg80211_get_conn_bss(wdev);
+       if (bss) {
+               cfg80211_put_bss(bss);
+       } else {
                /* not found */
                if (wdev->conn->state == CFG80211_CONN_SCAN_AGAIN)
                        schedule_work(&rdev->conn_work);
@@ -670,6 +673,7 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev,
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        struct ieee80211_channel *chan;
+       struct cfg80211_bss *bss = NULL;
        int err;
 
        ASSERT_WDEV_LOCK(wdev);
@@ -760,7 +764,7 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev,
 
                /* don't care about result -- but fill bssid & channel */
                if (!wdev->conn->params.bssid || !wdev->conn->params.channel)
-                       cfg80211_get_conn_bss(wdev);
+                       bss = cfg80211_get_conn_bss(wdev);
 
                wdev->sme_state = CFG80211_SME_CONNECTING;
                wdev->connect_keys = connkeys;
@@ -770,10 +774,11 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev,
                        wdev->conn->prev_bssid_valid = true;
                }
 
-               /* we're good if we have both BSSID and channel */
-               if (wdev->conn->params.bssid && wdev->conn->params.channel) {
+               /* we're good if we have a matching bss struct */
+               if (bss) {
                        wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
                        err = cfg80211_conn_do_work(wdev);
+                       cfg80211_put_bss(bss);
                } else {
                        /* otherwise we'll need to scan for the AP first */
                        err = cfg80211_conn_scan(wdev);
index 9dd5b25a1d534d9e291deffb3b285a5c6fe4c286..842dbc2d5aeda0af27ce18af9914deea370dc329 100644 (file)
@@ -10,7 +10,6 @@
 hostprogs-$(CONFIG_KALLSYMS)     += kallsyms
 hostprogs-$(CONFIG_LOGO)         += pnmtologo
 hostprogs-$(CONFIG_VT)           += conmakehash
-hostprogs-$(CONFIG_PROM_CONSOLE) += conmakehash
 hostprogs-$(CONFIG_IKCONFIG)     += bin2c
 
 always         := $(hostprogs-y) $(hostprogs-m)
index 7ed47f66ddd1fe8a6f09f24b548536ff04fd8660..129605819560073d542de35b1b265d4cd0696ae0 100644 (file)
@@ -7927,8 +7927,9 @@ static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
 
 static struct snd_kcontrol_new alc883_targa_mixer[] = {
        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
        HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
@@ -7947,8 +7948,9 @@ static struct snd_kcontrol_new alc883_targa_mixer[] = {
 
 static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
        HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -7960,6 +7962,15 @@ static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
        { } /* end */
 };
 
+static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
+       HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+       HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
+       HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+       { } /* end */
+};
+
 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
@@ -9167,7 +9178,8 @@ static struct alc_config_preset alc882_presets[] = {
                .init_hook = alc882_targa_automute,
        },
        [ALC883_TARGA_8ch_DIG] = {
-               .mixers = { alc883_base_mixer, alc883_chmode_mixer },
+               .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
+                           alc883_chmode_mixer },
                .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
                                alc883_targa_verbs },
                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
@@ -13370,7 +13382,8 @@ static const char *alc269_models[ALC269_MODEL_LAST] = {
        [ALC269_ASUS_EEEPC_P703]        = "eeepc-p703",
        [ALC269_ASUS_EEEPC_P901]        = "eeepc-p901",
        [ALC269_FUJITSU]                = "fujitsu",
-       [ALC269_LIFEBOOK]               = "lifebook"
+       [ALC269_LIFEBOOK]               = "lifebook",
+       [ALC269_AUTO]                   = "auto",
 };
 
 static struct snd_pci_quirk alc269_cfg_tbl[] = {
index e31e53dc6962335458639d33cf5adda136dcd3a1..826137ec3002021dba56de29169f01740b3008e1 100644 (file)
@@ -864,10 +864,6 @@ static struct hda_verb stac92hd73xx_core_init[] = {
 };
 
 static struct hda_verb stac92hd83xxx_core_init[] = {
-       { 0xa, AC_VERB_SET_CONNECT_SEL, 0x1},
-       { 0xb, AC_VERB_SET_CONNECT_SEL, 0x1},
-       { 0xd, AC_VERB_SET_CONNECT_SEL, 0x0},
-
        /* power state controls amps */
        { 0x01, AC_VERB_SET_EAPD, 1 << 2},
        {}
@@ -1590,8 +1586,8 @@ static unsigned int ref92hd83xxx_pin_configs[10] = {
 };
 
 static unsigned int dell_s14_pin_configs[10] = {
-       0x02214030, 0x02211010, 0x02a19020, 0x01014050,
-       0x40f000f0, 0x01819040, 0x40f000f0, 0x90a60160,
+       0x0221403f, 0x0221101f, 0x02a19020, 0x90170110,
+       0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a60160,
        0x40f000f0, 0x40f000f0,
 };
 
@@ -1690,6 +1686,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
                      "HP mini 1000", STAC_HP_M4),
        SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361b,
                      "HP HDX", STAC_HP_HDX),  /* HDX16 */
+       SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3620,
+                     "HP dv6", STAC_HP_DV5),
        SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010,
                      "HP", STAC_HP_DV5),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233,
@@ -4166,7 +4164,10 @@ static int stac92xx_init(struct hda_codec *codec)
                stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0],
                                AC_PINCTL_OUT_EN);
                /* fake event to set up pins */
-               stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0]);
+               if (cfg->hp_pins[0])
+                       stac_issue_unsol_event(codec, cfg->hp_pins[0]);
+               else if (cfg->line_out_pins[0])
+                       stac_issue_unsol_event(codec, cfg->line_out_pins[0]);
        } else {
                stac92xx_auto_init_multi_out(codec);
                stac92xx_auto_init_hp_out(codec);
@@ -4688,8 +4689,13 @@ static int stac92xx_resume(struct hda_codec *codec)
        snd_hda_codec_resume_amp(codec);
        snd_hda_codec_resume_cache(codec);
        /* fake event to set up pins again to override cached values */
-       if (spec->hp_detect)
-               stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0]);
+       if (spec->hp_detect) {
+               if (spec->autocfg.hp_pins[0])
+                       stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0]);
+               else if (spec->autocfg.line_out_pins[0])
+                       stac_issue_unsol_event(codec,
+                                              spec->autocfg.line_out_pins[0]);
+       }
        return 0;
 }
 
@@ -5016,7 +5022,7 @@ again:
                spec->eapd_switch = 1;
                break;
        }
-       if (spec->board_config > STAC_92HD73XX_REF) {
+       if (spec->board_config != STAC_92HD73XX_REF) {
                /* GPIO0 High = Enable EAPD */
                spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
                spec->gpio_data = 0x01;
@@ -5066,7 +5072,6 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
 
        codec->spec = spec;
        codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs;
-       spec->mono_nid = 0x19;
        spec->digbeep_nid = 0x21;
        spec->mux_nids = stac92hd83xxx_mux_nids;
        spec->num_muxes = ARRAY_SIZE(stac92hd83xxx_mux_nids);
@@ -5242,7 +5247,7 @@ again:
                stac92xx_set_config_regs(codec,
                                stac92hd71bxx_brd_tbl[spec->board_config]);
 
-       if (spec->board_config > STAC_92HD71BXX_REF) {
+       if (spec->board_config != STAC_92HD71BXX_REF) {
                /* GPIO0 = EAPD */
                spec->gpio_mask = 0x01;
                spec->gpio_dir = 0x01;
@@ -5375,6 +5380,11 @@ again:
        case STAC_HP_DV5:
                snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010);
                stac92xx_auto_set_pinctl(codec, 0x0d, AC_PINCTL_OUT_EN);
+               /* HP dv6 gives the headphone pin as a line-out.  Thus we
+                * need to set hp_detect flag here to force to enable HP
+                * detection.
+                */
+               spec->hp_detect = 1;
                break;
        case STAC_HP_HDX:
                spec->num_dmics = 1;
@@ -5557,14 +5567,17 @@ static int patch_stac927x(struct hda_codec *codec)
        spec->dac_list = stac927x_dac_nids;
        spec->multiout.dac_nids = spec->dac_nids;
 
+       if (spec->board_config != STAC_D965_REF) {
+               /* GPIO0 High = Enable EAPD */
+               spec->eapd_mask = spec->gpio_mask = 0x01;
+               spec->gpio_dir = spec->gpio_data = 0x01;
+       }
+
        switch (spec->board_config) {
        case STAC_D965_3ST:
        case STAC_D965_5ST:
                /* GPIO0 High = Enable EAPD */
-               spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x01;
-               spec->gpio_data = 0x01;
                spec->num_dmics = 0;
-
                spec->init = d965_core_init;
                break;
        case STAC_DELL_BIOS:
@@ -5583,16 +5596,11 @@ static int patch_stac927x(struct hda_codec *codec)
                snd_hda_codec_set_pincfg(codec, 0x0e, 0x02a79130);
                /* fallthru */
        case STAC_DELL_3ST:
-               /* GPIO2 High = Enable EAPD */
-               spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x04;
-               spec->gpio_data = 0x04;
-               switch (codec->subsystem_id) {
-               case 0x1028022f:
-                       /* correct EAPD to be GPIO0 */
-                       spec->eapd_mask = spec->gpio_mask = 0x01;
-                       spec->gpio_dir = spec->gpio_data = 0x01;
-                       break;
-               };
+               if (codec->subsystem_id != 0x1028022f) {
+                       /* GPIO2 High = Enable EAPD */
+                       spec->eapd_mask = spec->gpio_mask = 0x04;
+                       spec->gpio_dir = spec->gpio_data = 0x04;
+               }
                spec->dmic_nids = stac927x_dmic_nids;
                spec->num_dmics = STAC927X_NUM_DMICS;
 
@@ -5601,14 +5609,9 @@ static int patch_stac927x(struct hda_codec *codec)
                spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids);
                break;
        default:
-               if (spec->board_config > STAC_D965_REF) {
-                       /* GPIO0 High = Enable EAPD */
-                       spec->eapd_mask = spec->gpio_mask = 0x01;
-                       spec->gpio_dir = spec->gpio_data = 0x01;
-               }
                spec->num_dmics = 0;
-
                spec->init = stac927x_core_init;
+               break;
        }
 
        spec->num_caps = STAC927X_NUM_CAPS;
index 3612bb92df9074f27b0739dd4ad7232cdad7e1f5..01343dc984fdfaf6c517fb86e0f0afb21cd9f108 100644 (file)
@@ -18,7 +18,6 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 #include <sound/core.h>
index e62b27701a4926adc04a7ecb3d43f76c27cd1cfd..9a049a1995a38372e2a2090cc82810af5245d59f 100644 (file)
@@ -28,7 +28,6 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 #include <sound/core.h>
index d8a013ab3177c2ea6a42bfa910e0e7d2bd620461..98d663afc97d290e9d954eb08d37e007b16fbfae 100644 (file)
@@ -12,7 +12,6 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/delay.h>
index 9ff62e3a9b1d1c49a2938c3085f7182d18d8ea44..6096d22283e6e5043386724cf11caf54b597f536 100644 (file)
@@ -447,6 +447,7 @@ int mpc5200_audio_dma_create(struct of_device *op)
        int size, irq, rc;
        const __be32 *prop;
        void __iomem *regs;
+       int ret;
 
        /* Fetch the registers and IRQ of the PSC */
        irq = irq_of_parse_and_map(op->node, 0);
@@ -463,14 +464,16 @@ int mpc5200_audio_dma_create(struct of_device *op)
        /* Allocate and initialize the driver private data */
        psc_dma = kzalloc(sizeof *psc_dma, GFP_KERNEL);
        if (!psc_dma) {
-               iounmap(regs);
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto out_unmap;
        }
 
        /* Get the PSC ID */
        prop = of_get_property(op->node, "cell-index", &size);
-       if (!prop || size < sizeof *prop)
-               return -ENODEV;
+       if (!prop || size < sizeof *prop) {
+               ret = -ENODEV;
+               goto out_free;
+       }
 
        spin_lock_init(&psc_dma->lock);
        mutex_init(&psc_dma->mutex);
@@ -493,9 +496,8 @@ int mpc5200_audio_dma_create(struct of_device *op)
        if (!psc_dma->capture.bcom_task ||
            !psc_dma->playback.bcom_task) {
                dev_err(&op->dev, "Could not allocate bestcomm tasks\n");
-               iounmap(regs);
-               kfree(psc_dma);
-               return -ENODEV;
+               ret = -ENODEV;
+               goto out_free;
        }
 
        /* Disable all interrupts and reset the PSC */
@@ -537,12 +539,8 @@ int mpc5200_audio_dma_create(struct of_device *op)
                          &psc_dma_bcom_irq_tx, IRQF_SHARED,
                          "psc-dma-playback", &psc_dma->playback);
        if (rc) {
-               free_irq(psc_dma->irq, psc_dma);
-               free_irq(psc_dma->capture.irq,
-                        &psc_dma->capture);
-               free_irq(psc_dma->playback.irq,
-                        &psc_dma->playback);
-               return -ENODEV;
+               ret = -ENODEV;
+               goto out_irq;
        }
 
        /* Save what we've done so it can be found again later */
@@ -550,6 +548,15 @@ int mpc5200_audio_dma_create(struct of_device *op)
 
        /* Tell the ASoC OF helpers about it */
        return snd_soc_register_platform(&mpc5200_audio_dma_platform);
+out_irq:
+       free_irq(psc_dma->irq, psc_dma);
+       free_irq(psc_dma->capture.irq, &psc_dma->capture);
+       free_irq(psc_dma->playback.irq, &psc_dma->playback);
+out_free:
+       kfree(psc_dma);
+out_unmap:
+       iounmap(regs);
+       return ret;
 }
 EXPORT_SYMBOL_GPL(mpc5200_audio_dma_create);
 
index aa7af0b8d421e121996332cc71bcafb1b11eaf35..9bc4aa35caab477f918f6f574fadb8ffbf75f319 100644 (file)
@@ -230,6 +230,8 @@ static void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on)
        pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic);
 }
 
+#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
+
 /*
  * Wait for the LR signal to allow synchronisation to the L/R clock
  * from the codec. May only be needed for slave mode.
@@ -237,19 +239,21 @@ static void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on)
 static int s3c2412_snd_lrsync(struct s3c_i2sv2_info *i2s)
 {
        u32 iiscon;
-       unsigned long timeout = jiffies + msecs_to_jiffies(5);
+       unsigned long loops = msecs_to_loops(5);
 
        pr_debug("Entered %s\n", __func__);
 
-       while (1) {
+       while (--loops) {
                iiscon = readl(i2s->regs + S3C2412_IISCON);
                if (iiscon & S3C2412_IISCON_LRINDEX)
                        break;
 
-               if (timeout < jiffies) {
-                       printk(KERN_ERR "%s: timeout\n", __func__);
-                       return -ETIMEDOUT;
-               }
+               cpu_relax();
+       }
+
+       if (!loops) {
+               printk(KERN_ERR "%s: timeout\n", __func__);
+               return -ETIMEDOUT;
        }
 
        return 0;
index 0d8b08ef873170fa5162c26f0cf35b93c69100c1..f79711b9fa5b9c58de8c156b30ff0e613bf26664 100644 (file)
@@ -1131,9 +1131,10 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
        ret = snprintf(buf, PAGE_SIZE, "%s: %s  in %d out %d\n",
                       w->name, w->power ? "On" : "Off", in, out);
 
-       if (w->active && w->sname)
-               ret += snprintf(buf, PAGE_SIZE - ret, " stream %s active\n",
-                               w->sname);
+       if (w->sname)
+               ret += snprintf(buf + ret, PAGE_SIZE - ret, " stream %s %s\n",
+                               w->sname,
+                               w->active ? "active" : "inactive");
 
        list_for_each_entry(p, &w->sources, list_sink) {
                if (p->connect)
This page took 0.857262 seconds and 5 git commands to generate.