aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/RCU/torture.txt122
-rw-r--r--Documentation/cachetlb.txt9
-rw-r--r--Documentation/cpusets.txt2
-rw-r--r--Documentation/firmware_class/firmware_sample_driver.c1
-rw-r--r--Documentation/firmware_class/firmware_sample_firmware_class.c2
-rw-r--r--Documentation/i2c/writing-clients1
-rw-r--r--Documentation/kernel-parameters.txt2
-rw-r--r--Documentation/keys.txt22
-rw-r--r--Documentation/m68k/kernel-options.txt24
-rw-r--r--Documentation/mips/AU1xxx_IDE.README168
-rw-r--r--Documentation/networking/ip-sysctl.txt2
-rw-r--r--MAINTAINERS15
-rw-r--r--README4
-rw-r--r--arch/alpha/kernel/time.c4
-rw-r--r--arch/alpha/mm/numa.c3
-rw-r--r--arch/alpha/mm/remap.c6
-rw-r--r--arch/arm/Makefile14
-rw-r--r--arch/arm/boot/compressed/misc.c2
-rw-r--r--arch/arm/common/amba.c2
-rw-r--r--arch/arm/common/dmabounce.c165
-rw-r--r--arch/arm/common/scoop.c2
-rw-r--r--arch/arm/configs/ixdp2400_defconfig2
-rw-r--r--arch/arm/configs/ixdp2800_defconfig2
-rw-r--r--arch/arm/kernel/Makefile2
-rw-r--r--arch/arm/kernel/arthur.c1
-rw-r--r--arch/arm/kernel/asm-offsets.c1
-rw-r--r--arch/arm/kernel/entry-armv.S3
-rw-r--r--arch/arm/kernel/head.S57
-rw-r--r--arch/arm/kernel/ptrace.c2
-rw-r--r--arch/arm/kernel/signal.c96
-rw-r--r--arch/arm/kernel/time.c4
-rw-r--r--arch/arm/kernel/traps.c43
-rw-r--r--arch/arm/kernel/vmlinux.lds.S11
-rw-r--r--arch/arm/lib/ashldi3.S48
-rw-r--r--arch/arm/lib/ashldi3.c56
-rw-r--r--arch/arm/lib/ashrdi3.S48
-rw-r--r--arch/arm/lib/ashrdi3.c57
-rw-r--r--arch/arm/lib/gcclib.h22
-rw-r--r--arch/arm/lib/lshrdi3.S48
-rw-r--r--arch/arm/lib/lshrdi3.c56
-rw-r--r--arch/arm/lib/muldi3.S44
-rw-r--r--arch/arm/lib/muldi3.c72
-rw-r--r--arch/arm/lib/ucmpdi2.S35
-rw-r--r--arch/arm/lib/ucmpdi2.c49
-rw-r--r--arch/arm/mach-imx/generic.c2
-rw-r--r--arch/arm/mach-integrator/clock.c1
-rw-r--r--arch/arm/mach-integrator/integrator_ap.c1
-rw-r--r--arch/arm/mach-integrator/lm.c1
-rw-r--r--arch/arm/mach-iop3xx/iq31244-pci.c2
-rw-r--r--arch/arm/mach-iop3xx/iq80321-pci.c2
-rw-r--r--arch/arm/mach-iop3xx/iq80331-pci.c2
-rw-r--r--arch/arm/mach-iop3xx/iq80332-pci.c2
-rw-r--r--arch/arm/mach-pxa/corgi.c20
-rw-r--r--arch/arm/mach-pxa/generic.c1
-rw-r--r--arch/arm/mach-pxa/poodle.c21
-rw-r--r--arch/arm/mach-pxa/spitz.c19
-rw-r--r--arch/arm/mach-sa1100/generic.c3
-rw-r--r--arch/arm/mach-sa1100/jornada720.c64
-rw-r--r--arch/arm/mach-versatile/clock.c1
-rw-r--r--arch/arm/mm/consistent.c6
-rw-r--r--arch/arm/mm/copypage-v6.c16
-rw-r--r--arch/arm/mm/fault-armv.c7
-rw-r--r--arch/arm/mm/init.c30
-rw-r--r--arch/arm/mm/ioremap.c4
-rw-r--r--arch/arm/mm/mm-armv.c15
-rw-r--r--arch/arm/oprofile/backtrace.c46
-rw-r--r--arch/arm/plat-omap/clock.c1
-rw-r--r--arch/arm26/kernel/ptrace.c2
-rw-r--r--arch/arm26/kernel/time.c4
-rw-r--r--arch/arm26/mm/memc.c18
-rw-r--r--arch/cris/arch-v10/drivers/axisflashmap.c1
-rw-r--r--arch/cris/arch-v32/drivers/axisflashmap.c1
-rw-r--r--arch/cris/arch-v32/mm/tlb.c6
-rw-r--r--arch/cris/kernel/time.c5
-rw-r--r--arch/cris/mm/ioremap.c4
-rw-r--r--arch/frv/kernel/ptrace.c2
-rw-r--r--arch/frv/kernel/time.c4
-rw-r--r--arch/frv/mm/dma-alloc.c5
-rw-r--r--arch/frv/mm/pgalloc.c4
-rw-r--r--arch/h8300/kernel/ptrace.c2
-rw-r--r--arch/h8300/kernel/time.c4
-rw-r--r--arch/i386/Kconfig310
-rw-r--r--arch/i386/Kconfig.cpu309
-rw-r--r--arch/i386/Makefile31
-rw-r--r--arch/i386/Makefile.cpu41
-rw-r--r--arch/i386/kernel/apic.c82
-rw-r--r--arch/i386/kernel/apm.c40
-rw-r--r--arch/i386/kernel/cpu/common.c15
-rw-r--r--arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c1
-rw-r--r--arch/i386/kernel/cpu/cpufreq/p4-clockmod.c1
-rw-r--r--arch/i386/kernel/cpu/cpufreq/powernow-k8.c1
-rw-r--r--arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c1
-rw-r--r--arch/i386/kernel/cpu/intel_cacheinfo.c87
-rw-r--r--arch/i386/kernel/cpu/mcheck/p6.c11
-rw-r--r--arch/i386/kernel/cpu/mtrr/if.c119
-rw-r--r--arch/i386/kernel/cpu/proc.c2
-rw-r--r--arch/i386/kernel/crash.c7
-rw-r--r--arch/i386/kernel/i8259.c4
-rw-r--r--arch/i386/kernel/io_apic.c153
-rw-r--r--arch/i386/kernel/irq.c8
-rw-r--r--arch/i386/kernel/mpparse.c41
-rw-r--r--arch/i386/kernel/nmi.c39
-rw-r--r--arch/i386/kernel/ptrace.c2
-rw-r--r--arch/i386/kernel/reboot_fixups.c2
-rw-r--r--arch/i386/kernel/setup.c24
-rw-r--r--arch/i386/kernel/smpboot.c72
-rw-r--r--arch/i386/kernel/srat.c7
-rw-r--r--arch/i386/kernel/time.c16
-rw-r--r--arch/i386/kernel/time_hpet.c20
-rw-r--r--arch/i386/kernel/timers/timer_hpet.c17
-rw-r--r--arch/i386/kernel/timers/timer_tsc.c21
-rw-r--r--arch/i386/kernel/traps.c1
-rw-r--r--arch/i386/kernel/vm86.c17
-rw-r--r--arch/i386/mach-es7000/es7000.h11
-rw-r--r--arch/i386/mach-es7000/es7000plat.c11
-rw-r--r--arch/i386/mm/discontig.c4
-rw-r--r--arch/i386/mm/fault.c2
-rw-r--r--arch/i386/mm/init.c62
-rw-r--r--arch/i386/mm/ioremap.c4
-rw-r--r--arch/i386/mm/pgtable.c11
-rw-r--r--arch/i386/oprofile/backtrace.c38
-rw-r--r--arch/i386/pci/irq.c55
-rw-r--r--arch/i386/power/cpu.c12
-rw-r--r--arch/ia64/ia32/sys_ia32.c1
-rw-r--r--arch/ia64/kernel/cyclone.c1
-rw-r--r--arch/ia64/kernel/perfmon.c3
-rw-r--r--arch/ia64/kernel/time.c4
-rw-r--r--arch/ia64/mm/discontig.c7
-rw-r--r--arch/ia64/mm/fault.c34
-rw-r--r--arch/ia64/mm/init.c13
-rw-r--r--arch/ia64/mm/tlb.c2
-rw-r--r--arch/m32r/kernel/entry.S2
-rw-r--r--arch/m32r/kernel/io_m32700ut.c6
-rw-r--r--arch/m32r/kernel/io_mappi.c2
-rw-r--r--arch/m32r/kernel/io_mappi2.c11
-rw-r--r--arch/m32r/kernel/io_mappi3.c7
-rw-r--r--arch/m32r/kernel/io_oaks32r.c2
-rw-r--r--arch/m32r/kernel/io_opsput.c8
-rw-r--r--arch/m32r/kernel/io_usrv.c2
-rw-r--r--arch/m32r/kernel/ptrace.c2
-rw-r--r--arch/m32r/kernel/setup.c24
-rw-r--r--arch/m32r/kernel/time.c4
-rw-r--r--arch/m32r/lib/csum_partial_copy.c2
-rw-r--r--arch/m32r/mm/init.c9
-rw-r--r--arch/m32r/mm/ioremap.c4
-rw-r--r--arch/m68k/Kconfig24
-rw-r--r--arch/m68k/atari/stram.c918
-rw-r--r--arch/m68k/kernel/ptrace.c2
-rw-r--r--arch/m68k/kernel/time.c4
-rw-r--r--arch/m68k/mm/kmap.c2
-rw-r--r--arch/m68k/sun3x/dvma.c2
-rw-r--r--arch/m68knommu/kernel/ptrace.c2
-rw-r--r--arch/m68knommu/kernel/time.c4
-rw-r--r--arch/mips/Kconfig1510
-rw-r--r--arch/mips/Makefile118
-rw-r--r--arch/mips/arc/Makefile2
-rw-r--r--arch/mips/arc/identify.c5
-rw-r--r--arch/mips/au1000/common/Makefile2
-rw-r--r--arch/mips/au1000/common/au1xxx_irqmap.c32
-rw-r--r--arch/mips/au1000/common/cputable.c3
-rw-r--r--arch/mips/au1000/common/dbdma.c319
-rw-r--r--arch/mips/au1000/common/dma.c1
-rw-r--r--arch/mips/au1000/common/gpio.c119
-rw-r--r--arch/mips/au1000/common/irq.c105
-rw-r--r--arch/mips/au1000/common/platform.c249
-rw-r--r--arch/mips/au1000/common/power.c19
-rw-r--r--arch/mips/au1000/common/prom.c3
-rw-r--r--arch/mips/au1000/common/puts.c77
-rw-r--r--arch/mips/au1000/common/setup.c12
-rw-r--r--arch/mips/au1000/common/time.c26
-rw-r--r--arch/mips/au1000/common/usbdev.c12
-rw-r--r--arch/mips/au1000/csb250/init.c1
-rw-r--r--arch/mips/au1000/db1x00/irqmap.c32
-rw-r--r--arch/mips/au1000/db1x00/mirage_ts.c16
-rw-r--r--arch/mips/au1000/hydrogen3/init.c1
-rw-r--r--arch/mips/au1000/mtx-1/init.c1
-rw-r--r--arch/mips/au1000/mtx-1/irqmap.c11
-rw-r--r--arch/mips/au1000/pb1000/init.c1
-rw-r--r--arch/mips/au1000/pb1200/Makefile5
-rw-r--r--arch/mips/au1000/pb1200/board_setup.c193
-rw-r--r--arch/mips/au1000/pb1200/init.c69
-rw-r--r--arch/mips/au1000/pb1200/irqmap.c182
-rw-r--r--arch/mips/au1000/pb1500/irqmap.c5
-rw-r--r--arch/mips/au1000/pb1550/irqmap.c5
-rw-r--r--arch/mips/boot/Makefile4
-rw-r--r--arch/mips/cobalt/Makefile2
-rw-r--r--arch/mips/cobalt/int-handler.S4
-rw-r--r--arch/mips/cobalt/irq.c111
-rw-r--r--arch/mips/cobalt/promcon.c87
-rw-r--r--arch/mips/cobalt/reset.c59
-rw-r--r--arch/mips/cobalt/setup.c104
-rw-r--r--arch/mips/configs/atlas_defconfig660
-rw-r--r--arch/mips/configs/bigsur_defconfig881
-rw-r--r--arch/mips/configs/capcella_defconfig450
-rw-r--r--arch/mips/configs/cobalt_defconfig367
-rw-r--r--arch/mips/configs/db1000_defconfig498
-rw-r--r--arch/mips/configs/db1100_defconfig558
-rw-r--r--arch/mips/configs/db1200_defconfig987
-rw-r--r--arch/mips/configs/db1500_defconfig459
-rw-r--r--arch/mips/configs/db1550_defconfig441
-rw-r--r--arch/mips/configs/ddb5476_defconfig389
-rw-r--r--arch/mips/configs/ddb5477_defconfig377
-rw-r--r--arch/mips/configs/decstation_defconfig463
-rw-r--r--arch/mips/configs/e55_defconfig403
-rw-r--r--arch/mips/configs/ev64120_defconfig376
-rw-r--r--arch/mips/configs/ev96100_defconfig359
-rw-r--r--arch/mips/configs/ip22_defconfig479
-rw-r--r--arch/mips/configs/ip27_defconfig466
-rw-r--r--arch/mips/configs/ip32_defconfig390
-rw-r--r--arch/mips/configs/it8172_defconfig372
-rw-r--r--arch/mips/configs/ivr_defconfig376
-rw-r--r--arch/mips/configs/jaguar-atx_defconfig339
-rw-r--r--arch/mips/configs/jmr3927_defconfig388
-rw-r--r--arch/mips/configs/lasat200_defconfig378
-rw-r--r--arch/mips/configs/malta_defconfig724
-rw-r--r--arch/mips/configs/mipssim_defconfig775
-rw-r--r--arch/mips/configs/mpc30x_defconfig607
-rw-r--r--arch/mips/configs/ocelot_3_defconfig457
-rw-r--r--arch/mips/configs/ocelot_c_defconfig372
-rw-r--r--arch/mips/configs/ocelot_defconfig359
-rw-r--r--arch/mips/configs/ocelot_g_defconfig372
-rw-r--r--arch/mips/configs/pb1100_defconfig434
-rw-r--r--arch/mips/configs/pb1500_defconfig512
-rw-r--r--arch/mips/configs/pb1550_defconfig508
-rw-r--r--arch/mips/configs/pnx8550-jbs_defconfig1069
-rw-r--r--arch/mips/configs/pnx8550-v2pci_defconfig1251
-rw-r--r--arch/mips/configs/qemu_defconfig106
-rw-r--r--arch/mips/configs/rbhma4500_defconfig1259
-rw-r--r--arch/mips/configs/rm200_defconfig801
-rw-r--r--arch/mips/configs/sb1250-swarm_defconfig397
-rw-r--r--arch/mips/configs/sead_defconfig234
-rw-r--r--arch/mips/configs/tb0226_defconfig684
-rw-r--r--arch/mips/configs/tb0229_defconfig541
-rw-r--r--arch/mips/configs/tb0287_defconfig170
-rw-r--r--arch/mips/configs/workpad_defconfig416
-rw-r--r--arch/mips/configs/yosemite_defconfig346
-rw-r--r--arch/mips/ddb5xxx/Kconfig4
-rw-r--r--arch/mips/ddb5xxx/ddb5074/nile4_pic.c15
-rw-r--r--arch/mips/ddb5xxx/ddb5074/setup.c4
-rw-r--r--arch/mips/ddb5xxx/ddb5476/setup.c4
-rw-r--r--arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c15
-rw-r--r--arch/mips/ddb5xxx/ddb5477/irq_5477.c15
-rw-r--r--arch/mips/ddb5xxx/ddb5477/setup.c6
-rw-r--r--arch/mips/dec/Makefile4
-rw-r--r--arch/mips/dec/ecc-berr.c48
-rw-r--r--arch/mips/dec/int-handler.S18
-rw-r--r--arch/mips/dec/kn01-berr.c201
-rw-r--r--arch/mips/dec/kn02-irq.c13
-rw-r--r--arch/mips/dec/kn02xa-berr.c139
-rw-r--r--arch/mips/dec/prom/identify.c28
-rw-r--r--arch/mips/dec/prom/init.c16
-rw-r--r--arch/mips/dec/prom/memory.c14
-rw-r--r--arch/mips/dec/reset.c2
-rw-r--r--arch/mips/dec/setup.c57
-rw-r--r--arch/mips/defconfig479
-rw-r--r--arch/mips/galileo-boards/ev96100/setup.c4
-rw-r--r--arch/mips/gt64120/ev64120/Kconfig3
-rw-r--r--arch/mips/gt64120/ev64120/setup.c4
-rw-r--r--arch/mips/gt64120/momenco_ocelot/setup.c4
-rw-r--r--arch/mips/ite-boards/Kconfig8
-rw-r--r--arch/mips/ite-boards/generic/irq.c30
-rw-r--r--arch/mips/ite-boards/generic/it8172_setup.c4
-rw-r--r--arch/mips/jazz/Kconfig33
-rw-r--r--arch/mips/jazz/irq.c15
-rw-r--r--arch/mips/jazz/setup.c4
-rw-r--r--arch/mips/jmr3927/rbhma3100/irq.c14
-rw-r--r--arch/mips/jmr3927/rbhma3100/setup.c38
-rw-r--r--arch/mips/kernel/Makefile14
-rw-r--r--arch/mips/kernel/asm-offsets.c25
-rw-r--r--arch/mips/kernel/binfmt_elfn32.c4
-rw-r--r--arch/mips/kernel/binfmt_elfo32.c35
-rw-r--r--arch/mips/kernel/branch.c29
-rw-r--r--arch/mips/kernel/cpu-probe.c256
-rw-r--r--arch/mips/kernel/dma-no-isa.c28
-rw-r--r--arch/mips/kernel/entry.S54
-rw-r--r--arch/mips/kernel/gdb-low.S5
-rw-r--r--arch/mips/kernel/gdb-stub.c23
-rw-r--r--arch/mips/kernel/genex.S44
-rw-r--r--arch/mips/kernel/genrtc.c64
-rw-r--r--arch/mips/kernel/head.S70
-rw-r--r--arch/mips/kernel/i8259.c21
-rw-r--r--arch/mips/kernel/ioctl32.c6
-rw-r--r--arch/mips/kernel/irixelf.c254
-rw-r--r--arch/mips/kernel/irixinv.c7
-rw-r--r--arch/mips/kernel/irixioctl.c63
-rw-r--r--arch/mips/kernel/irixsig.c408
-rw-r--r--arch/mips/kernel/irq-msc01.c38
-rw-r--r--arch/mips/kernel/irq-mv6434x.c15
-rw-r--r--arch/mips/kernel/irq-rm7000.c14
-rw-r--r--arch/mips/kernel/irq-rm9000.c28
-rw-r--r--arch/mips/kernel/irq_cpu.c91
-rw-r--r--arch/mips/kernel/linux32.c164
-rw-r--r--arch/mips/kernel/module-elf32.c250
-rw-r--r--arch/mips/kernel/module-elf64.c274
-rw-r--r--arch/mips/kernel/module.c336
-rw-r--r--arch/mips/kernel/proc.c135
-rw-r--r--arch/mips/kernel/process.c213
-rw-r--r--arch/mips/kernel/ptrace.c244
-rw-r--r--arch/mips/kernel/ptrace32.c150
-rw-r--r--arch/mips/kernel/r4k_fpu.S5
-rw-r--r--arch/mips/kernel/rtlx.c341
-rw-r--r--arch/mips/kernel/scall32-o32.S13
-rw-r--r--arch/mips/kernel/scall64-64.S4
-rw-r--r--arch/mips/kernel/scall64-n32.S32
-rw-r--r--arch/mips/kernel/scall64-o32.S14
-rw-r--r--arch/mips/kernel/semaphore.c12
-rw-r--r--arch/mips/kernel/setup.c46
-rw-r--r--arch/mips/kernel/signal-common.h90
-rw-r--r--arch/mips/kernel/signal.c143
-rw-r--r--arch/mips/kernel/signal32.c114
-rw-r--r--arch/mips/kernel/signal_n32.c37
-rw-r--r--arch/mips/kernel/smp.c51
-rw-r--r--arch/mips/kernel/smp_mt.c366
-rw-r--r--arch/mips/kernel/syscall.c34
-rw-r--r--arch/mips/kernel/sysirix.c539
-rw-r--r--arch/mips/kernel/time.c16
-rw-r--r--arch/mips/kernel/traps.c499
-rw-r--r--arch/mips/kernel/unaligned.c10
-rw-r--r--arch/mips/kernel/vmlinux.lds.S13
-rw-r--r--arch/mips/kernel/vpe.c1296
-rw-r--r--arch/mips/lasat/Kconfig15
-rw-r--r--arch/mips/lasat/interrupt.c15
-rw-r--r--arch/mips/lasat/setup.c6
-rw-r--r--arch/mips/lib-32/dump_tlb.c106
-rw-r--r--arch/mips/lib-32/r3k_dump_tlb.c10
-rw-r--r--arch/mips/lib-64/dump_tlb.c10
-rw-r--r--arch/mips/lib/Makefile4
-rw-r--r--arch/mips/lib/csum_partial_copy.c8
-rw-r--r--arch/mips/lib/memcpy.S15
-rw-r--r--arch/mips/lib/uncached.c76
-rw-r--r--arch/mips/math-emu/cp1emu.c229
-rw-r--r--arch/mips/math-emu/dp_sqrt.c2
-rw-r--r--arch/mips/math-emu/dsemul.c17
-rw-r--r--arch/mips/math-emu/dsemul.h10
-rw-r--r--arch/mips/math-emu/ieee754.c16
-rw-r--r--arch/mips/math-emu/ieee754.h180
-rw-r--r--arch/mips/math-emu/kernel_linkage.c6
-rw-r--r--arch/mips/mips-boards/atlas/atlas_int.c15
-rw-r--r--arch/mips/mips-boards/atlas/atlas_setup.c8
-rw-r--r--arch/mips/mips-boards/generic/init.c91
-rw-r--r--arch/mips/mips-boards/generic/memory.c29
-rw-r--r--arch/mips/mips-boards/generic/mipsIRQ.S110
-rw-r--r--arch/mips/mips-boards/generic/pci.c167
-rw-r--r--arch/mips/mips-boards/generic/time.c88
-rw-r--r--arch/mips/mips-boards/malta/malta_int.c153
-rw-r--r--arch/mips/mips-boards/malta/malta_setup.c8
-rw-r--r--arch/mips/mips-boards/sead/sead_int.c12
-rw-r--r--arch/mips/mips-boards/sead/sead_setup.c2
-rw-r--r--arch/mips/mips-boards/sim/Makefile20
-rw-r--r--arch/mips/mips-boards/sim/cmdline.c59
-rw-r--r--arch/mips/mips-boards/sim/sim_IRQ.c148
-rw-r--r--arch/mips/mips-boards/sim/sim_cmdline.c33
-rw-r--r--arch/mips/mips-boards/sim/sim_int.c41
-rw-r--r--arch/mips/mips-boards/sim/sim_irq.S99
-rw-r--r--arch/mips/mips-boards/sim/sim_mem.c129
-rw-r--r--arch/mips/mips-boards/sim/sim_printf.c74
-rw-r--r--arch/mips/mips-boards/sim/sim_setup.c101
-rw-r--r--arch/mips/mips-boards/sim/sim_smp.c151
-rw-r--r--arch/mips/mips-boards/sim/sim_time.c215
-rw-r--r--arch/mips/mm/Makefile2
-rw-r--r--arch/mips/mm/c-r3k.c6
-rw-r--r--arch/mips/mm/c-r4k.c145
-rw-r--r--arch/mips/mm/c-sb1.c10
-rw-r--r--arch/mips/mm/c-tx39.c16
-rw-r--r--arch/mips/mm/cache.c106
-rw-r--r--arch/mips/mm/cerr-sb1.c54
-rw-r--r--arch/mips/mm/cex-sb1.S5
-rw-r--r--arch/mips/mm/dma-coherent.c2
-rw-r--r--arch/mips/mm/dma-noncoherent.c46
-rw-r--r--arch/mips/mm/fault.c17
-rw-r--r--arch/mips/mm/highmem.c19
-rw-r--r--arch/mips/mm/init.c34
-rw-r--r--arch/mips/mm/ioremap.c32
-rw-r--r--arch/mips/mm/pg-r4k.c21
-rw-r--r--arch/mips/mm/pg-sb1.c65
-rw-r--r--arch/mips/mm/pgtable-32.c36
-rw-r--r--arch/mips/mm/sc-rm7k.c39
-rw-r--r--arch/mips/mm/tlb-andes.c4
-rw-r--r--arch/mips/mm/tlb-r4k.c70
-rw-r--r--arch/mips/mm/tlb-sb1.c376
-rw-r--r--arch/mips/mm/tlbex.c245
-rw-r--r--arch/mips/momentum/Kconfig6
-rw-r--r--arch/mips/momentum/jaguar_atx/prom.c3
-rw-r--r--arch/mips/momentum/jaguar_atx/setup.c6
-rw-r--r--arch/mips/momentum/ocelot_3/prom.c3
-rw-r--r--arch/mips/momentum/ocelot_3/setup.c6
-rw-r--r--arch/mips/momentum/ocelot_c/cpci-irq.c15
-rw-r--r--arch/mips/momentum/ocelot_c/setup.c4
-rw-r--r--arch/mips/momentum/ocelot_c/uart-irq.c15
-rw-r--r--arch/mips/momentum/ocelot_g/setup.c6
-rw-r--r--arch/mips/oprofile/Kconfig2
-rw-r--r--arch/mips/oprofile/common.c28
-rw-r--r--arch/mips/oprofile/op_impl.h5
-rw-r--r--arch/mips/oprofile/op_model_mipsxx.c215
-rw-r--r--arch/mips/oprofile/op_model_rm9000.c3
-rw-r--r--arch/mips/pci/Makefile3
-rw-r--r--arch/mips/pci/fixup-atlas.c41
-rw-r--r--arch/mips/pci/fixup-au1000.c78
-rw-r--r--arch/mips/pci/fixup-cobalt.c55
-rw-r--r--arch/mips/pci/fixup-pnx8550.c57
-rw-r--r--arch/mips/pci/fixup-tx4938.c92
-rw-r--r--arch/mips/pci/ops-au1000.c14
-rw-r--r--arch/mips/pci/ops-bonito64.c14
-rw-r--r--arch/mips/pci/ops-gt64111.c10
-rw-r--r--arch/mips/pci/ops-gt64120.c10
-rw-r--r--arch/mips/pci/ops-msc.c31
-rw-r--r--arch/mips/pci/ops-nile4.c2
-rw-r--r--arch/mips/pci/ops-pnx8550.c284
-rw-r--r--arch/mips/pci/ops-tx4938.c198
-rw-r--r--arch/mips/pci/pci-bcm1480.c265
-rw-r--r--arch/mips/pci/pci-bcm1480ht.c224
-rw-r--r--arch/mips/pci/pci-ip27.c7
-rw-r--r--arch/mips/pci/pci-ip32.c4
-rw-r--r--arch/mips/pci/pci-lasat.c56
-rw-r--r--arch/mips/pci/pci.c19
-rw-r--r--arch/mips/philips/pnx8550/common/Kconfig1
-rw-r--r--arch/mips/philips/pnx8550/common/Makefile27
-rw-r--r--arch/mips/philips/pnx8550/common/gdb_hook.c109
-rw-r--r--arch/mips/philips/pnx8550/common/int.c293
-rw-r--r--arch/mips/philips/pnx8550/common/mipsIRQ.S76
-rw-r--r--arch/mips/philips/pnx8550/common/pci.c133
-rw-r--r--arch/mips/philips/pnx8550/common/platform.c135
-rw-r--r--arch/mips/philips/pnx8550/common/proc.c113
-rw-r--r--arch/mips/philips/pnx8550/common/prom.c138
-rw-r--r--arch/mips/philips/pnx8550/common/reset.c49
-rw-r--r--arch/mips/philips/pnx8550/common/setup.c149
-rw-r--r--arch/mips/philips/pnx8550/common/time.c105
-rw-r--r--arch/mips/philips/pnx8550/jbs/Makefile4
-rw-r--r--arch/mips/philips/pnx8550/jbs/board_setup.c65
-rw-r--r--arch/mips/philips/pnx8550/jbs/init.c57
-rw-r--r--arch/mips/philips/pnx8550/jbs/irqmap.c36
-rw-r--r--arch/mips/pmc-sierra/Kconfig3
-rw-r--r--arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h1
-rw-r--r--arch/mips/pmc-sierra/yosemite/ht-irq.c1
-rw-r--r--arch/mips/pmc-sierra/yosemite/ht.c1
-rw-r--r--arch/mips/pmc-sierra/yosemite/prom.c3
-rw-r--r--arch/mips/pmc-sierra/yosemite/setup.c6
-rw-r--r--arch/mips/pmc-sierra/yosemite/smp.c2
-rw-r--r--arch/mips/qemu/q-setup.c5
-rw-r--r--arch/mips/sgi-ip22/ip22-eisa.c148
-rw-r--r--arch/mips/sgi-ip22/ip22-setup.c6
-rw-r--r--arch/mips/sgi-ip27/Kconfig54
-rw-r--r--arch/mips/sgi-ip27/ip27-berr.c1
-rw-r--r--arch/mips/sgi-ip27/ip27-console.c4
-rw-r--r--arch/mips/sgi-ip27/ip27-init.c50
-rw-r--r--arch/mips/sgi-ip27/ip27-irq.c66
-rw-r--r--arch/mips/sgi-ip27/ip27-smp.c25
-rw-r--r--arch/mips/sgi-ip32/ip32-irq.c75
-rw-r--r--arch/mips/sgi-ip32/ip32-memory.c4
-rw-r--r--arch/mips/sgi-ip32/ip32-setup.c6
-rw-r--r--arch/mips/sibyte/Kconfig161
-rw-r--r--arch/mips/sibyte/bcm1480/Makefile5
-rw-r--r--arch/mips/sibyte/bcm1480/irq.c476
-rw-r--r--arch/mips/sibyte/bcm1480/irq_handler.S165
-rw-r--r--arch/mips/sibyte/bcm1480/setup.c136
-rw-r--r--arch/mips/sibyte/bcm1480/smp.c110
-rw-r--r--arch/mips/sibyte/bcm1480/time.c138
-rw-r--r--arch/mips/sibyte/cfe/smp.c14
-rw-r--r--arch/mips/sibyte/sb1250/bcm1250_tbprof.c154
-rw-r--r--arch/mips/sibyte/sb1250/bus_watcher.c2
-rw-r--r--arch/mips/sibyte/sb1250/irq.c121
-rw-r--r--arch/mips/sibyte/sb1250/setup.c4
-rw-r--r--arch/mips/sibyte/sb1250/smp.c18
-rw-r--r--arch/mips/sibyte/sb1250/time.c44
-rw-r--r--arch/mips/sibyte/swarm/rtc_m41t81.c47
-rw-r--r--arch/mips/sibyte/swarm/rtc_xicor1241.c42
-rw-r--r--arch/mips/sibyte/swarm/setup.c41
-rw-r--r--arch/mips/sibyte/swarm/time.c44
-rw-r--r--arch/mips/sni/irq.c15
-rw-r--r--arch/mips/sni/setup.c6
-rw-r--r--arch/mips/tx4927/Kconfig3
-rw-r--r--arch/mips/tx4927/common/tx4927_setup.c6
-rw-r--r--arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c23
-rw-r--r--arch/mips/tx4938/Kconfig24
-rw-r--r--arch/mips/tx4938/common/Makefile11
-rw-r--r--arch/mips/tx4938/common/dbgio.c50
-rw-r--r--arch/mips/tx4938/common/irq.c424
-rw-r--r--arch/mips/tx4938/common/irq_handler.S84
-rw-r--r--arch/mips/tx4938/common/prom.c129
-rw-r--r--arch/mips/tx4938/common/rtc_rx5c348.c202
-rw-r--r--arch/mips/tx4938/common/setup.c91
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/Makefile9
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/irq.c244
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/prom.c78
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/setup.c1035
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c219
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c159
-rw-r--r--arch/mips/vr41xx/Kconfig88
-rw-r--r--arch/mips/vr41xx/common/cmu.c2
-rw-r--r--arch/mips/vr41xx/common/init.c14
-rw-r--r--arch/mips/vr41xx/common/vrc4173.c4
-rw-r--r--arch/mips/vr41xx/nec-cmbvr4133/setup.c5
-rw-r--r--arch/parisc/kernel/cache.c24
-rw-r--r--arch/parisc/kernel/ioctl32.c5
-rw-r--r--arch/parisc/kernel/pci-dma.c2
-rw-r--r--arch/parisc/kernel/ptrace.c2
-rw-r--r--arch/parisc/kernel/time.c4
-rw-r--r--arch/parisc/mm/init.c3
-rw-r--r--arch/parisc/mm/ioremap.c6
-rw-r--r--arch/powerpc/Kconfig900
-rw-r--r--arch/powerpc/Kconfig.debug128
-rw-r--r--arch/powerpc/Makefile222
-rw-r--r--arch/powerpc/kernel/Makefile56
-rw-r--r--arch/powerpc/kernel/asm-offsets.c273
-rw-r--r--arch/powerpc/kernel/binfmt_elf32.c (renamed from arch/ppc64/kernel/binfmt_elf32.c)3
-rw-r--r--arch/powerpc/kernel/btext.c853
-rw-r--r--arch/powerpc/kernel/cputable.c (renamed from arch/ppc/kernel/cputable.c)797
-rw-r--r--arch/powerpc/kernel/entry_32.S1000
-rw-r--r--arch/powerpc/kernel/entry_64.S (renamed from arch/ppc64/kernel/entry.S)47
-rw-r--r--arch/powerpc/kernel/fpu.S (renamed from arch/ppc/kernel/fpu.S)105
-rw-r--r--arch/powerpc/kernel/head_32.S1381
-rw-r--r--arch/powerpc/kernel/head_44x.S782
-rw-r--r--arch/powerpc/kernel/head_4xx.S1022
-rw-r--r--arch/powerpc/kernel/head_64.S1957
-rw-r--r--arch/powerpc/kernel/head_8xx.S860
-rw-r--r--arch/powerpc/kernel/head_fsl_booke.S1063
-rw-r--r--arch/powerpc/kernel/idle_6xx.S233
-rw-r--r--arch/powerpc/kernel/idle_power4.S (renamed from arch/ppc64/kernel/idle_power4.S)9
-rw-r--r--arch/powerpc/kernel/init_task.c (renamed from arch/ppc64/kernel/init_task.c)0
-rw-r--r--arch/powerpc/kernel/lparmap.c (renamed from arch/ppc64/kernel/lparmap.c)0
-rw-r--r--arch/powerpc/kernel/misc_32.S1037
-rw-r--r--arch/powerpc/kernel/misc_64.S880
-rw-r--r--arch/powerpc/kernel/of_device.c (renamed from arch/ppc64/kernel/of_device.c)6
-rw-r--r--arch/powerpc/kernel/pmc.c (renamed from arch/ppc64/kernel/pmc.c)30
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c273
-rw-r--r--arch/powerpc/kernel/process.c (renamed from arch/ppc64/kernel/process.c)486
-rw-r--r--arch/powerpc/kernel/prom.c2170
-rw-r--r--arch/powerpc/kernel/prom_init.c2109
-rw-r--r--arch/powerpc/kernel/ptrace.c (renamed from arch/ppc/kernel/ptrace.c)172
-rw-r--r--arch/powerpc/kernel/ptrace32.c (renamed from arch/ppc64/kernel/ptrace32.c)9
-rw-r--r--arch/powerpc/kernel/rtas.c (renamed from arch/ppc64/kernel/rtas.c)254
-rw-r--r--arch/powerpc/kernel/semaphore.c135
-rw-r--r--arch/powerpc/kernel/setup-common.c410
-rw-r--r--arch/powerpc/kernel/setup_32.c372
-rw-r--r--arch/powerpc/kernel/setup_64.c (renamed from arch/ppc64/kernel/setup.c)352
-rw-r--r--arch/powerpc/kernel/signal_32.c (renamed from arch/ppc64/kernel/signal32.c)993
-rw-r--r--arch/powerpc/kernel/sys_ppc32.c (renamed from arch/ppc64/kernel/sys_ppc32.c)320
-rw-r--r--arch/powerpc/kernel/syscalls.c (renamed from arch/ppc64/kernel/syscalls.c)187
-rw-r--r--arch/powerpc/kernel/systbl.S321
-rw-r--r--arch/powerpc/kernel/time.c (renamed from arch/ppc64/kernel/time.c)574
-rw-r--r--arch/powerpc/kernel/traps.c1101
-rw-r--r--arch/powerpc/kernel/vecemu.c (renamed from arch/ppc/kernel/vecemu.c)0
-rw-r--r--arch/powerpc/kernel/vector.S (renamed from arch/ppc64/kernel/vector.S)71
-rw-r--r--arch/powerpc/kernel/vio.c (renamed from arch/ppc64/kernel/vio.c)14
-rw-r--r--arch/powerpc/kernel/vmlinux.lds.S279
-rw-r--r--arch/powerpc/lib/Makefile19
-rw-r--r--arch/powerpc/lib/checksum_32.S225
-rw-r--r--arch/powerpc/lib/checksum_64.S (renamed from arch/ppc64/lib/checksum.S)0
-rw-r--r--arch/powerpc/lib/copy_32.S543
-rw-r--r--arch/powerpc/lib/copypage_64.S (renamed from arch/ppc64/lib/copypage.S)0
-rw-r--r--arch/powerpc/lib/copyuser_64.S (renamed from arch/ppc64/lib/copyuser.S)0
-rw-r--r--arch/powerpc/lib/div64.S59
-rw-r--r--arch/powerpc/lib/e2a.c (renamed from arch/ppc64/lib/e2a.c)0
-rw-r--r--arch/powerpc/lib/locks.c (renamed from arch/ppc64/lib/locks.c)5
-rw-r--r--arch/powerpc/lib/mem_64.S119
-rw-r--r--arch/powerpc/lib/memcpy_64.S (renamed from arch/ppc64/lib/memcpy.S)0
-rw-r--r--arch/powerpc/lib/rheap.c693
-rw-r--r--arch/powerpc/lib/sstep.c (renamed from arch/ppc64/lib/sstep.c)17
-rw-r--r--arch/powerpc/lib/strcase.c (renamed from arch/ppc64/lib/strcase.c)8
-rw-r--r--arch/powerpc/lib/string.S198
-rw-r--r--arch/powerpc/lib/usercopy_64.c (renamed from arch/ppc64/lib/usercopy.c)0
-rw-r--r--arch/powerpc/mm/44x_mmu.c120
-rw-r--r--arch/powerpc/mm/4xx_mmu.c141
-rw-r--r--arch/powerpc/mm/Makefile21
-rw-r--r--arch/powerpc/mm/fault.c (renamed from arch/ppc64/mm/fault.c)104
-rw-r--r--arch/powerpc/mm/fsl_booke_mmu.c237
-rw-r--r--arch/powerpc/mm/hash_low_32.S618
-rw-r--r--arch/powerpc/mm/hash_low_64.S (renamed from arch/ppc64/mm/hash_low.S)2
-rw-r--r--arch/powerpc/mm/hash_native_64.c (renamed from arch/ppc64/mm/hash_native.c)13
-rw-r--r--arch/powerpc/mm/hash_utils_64.c (renamed from arch/ppc64/mm/hash_utils.c)61
-rw-r--r--arch/powerpc/mm/hugetlbpage.c (renamed from arch/ppc64/mm/hugetlbpage.c)0
-rw-r--r--arch/powerpc/mm/imalloc.c (renamed from arch/ppc64/mm/imalloc.c)5
-rw-r--r--arch/powerpc/mm/init_32.c254
-rw-r--r--arch/powerpc/mm/init_64.c223
-rw-r--r--arch/powerpc/mm/lmb.c (renamed from arch/ppc64/kernel/lmb.c)105
-rw-r--r--arch/powerpc/mm/mem.c564
-rw-r--r--arch/powerpc/mm/mmap.c (renamed from arch/ppc64/mm/mmap.c)0
-rw-r--r--arch/powerpc/mm/mmu_context_32.c86
-rw-r--r--arch/powerpc/mm/mmu_context_64.c63
-rw-r--r--arch/powerpc/mm/mmu_decl.h87
-rw-r--r--arch/powerpc/mm/numa.c (renamed from arch/ppc64/mm/numa.c)2
-rw-r--r--arch/powerpc/mm/pgtable_32.c467
-rw-r--r--arch/powerpc/mm/pgtable_64.c347
-rw-r--r--arch/powerpc/mm/ppc_mmu_32.c285
-rw-r--r--arch/powerpc/mm/slb.c (renamed from arch/ppc64/mm/slb.c)0
-rw-r--r--arch/powerpc/mm/slb_low.S (renamed from arch/ppc64/mm/slb_low.S)0
-rw-r--r--arch/powerpc/mm/stab.c (renamed from arch/ppc64/mm/stab.c)0
-rw-r--r--arch/powerpc/mm/tlb_32.c183
-rw-r--r--arch/powerpc/mm/tlb_64.c (renamed from arch/ppc64/mm/tlb.c)23
-rw-r--r--arch/powerpc/oprofile/Kconfig (renamed from arch/ppc/oprofile/Kconfig)0
-rw-r--r--arch/powerpc/oprofile/Makefile (renamed from arch/ppc/oprofile/Makefile)7
-rw-r--r--arch/powerpc/oprofile/common.c (renamed from arch/ppc64/oprofile/common.c)84
-rw-r--r--arch/powerpc/oprofile/op_model_fsl_booke.c (renamed from arch/ppc/oprofile/op_model_fsl_booke.c)7
-rw-r--r--arch/powerpc/oprofile/op_model_power4.c (renamed from arch/ppc64/oprofile/op_model_power4.c)2
-rw-r--r--arch/powerpc/oprofile/op_model_rs64.c (renamed from arch/ppc64/oprofile/op_model_rs64.c)2
-rw-r--r--arch/powerpc/platforms/4xx/Kconfig280
-rw-r--r--arch/powerpc/platforms/4xx/Makefile1
-rw-r--r--arch/powerpc/platforms/85xx/Kconfig86
-rw-r--r--arch/powerpc/platforms/85xx/Makefile1
-rw-r--r--arch/powerpc/platforms/8xx/Kconfig352
-rw-r--r--arch/powerpc/platforms/Makefile13
-rw-r--r--arch/powerpc/platforms/apus/Kconfig130
-rw-r--r--arch/powerpc/platforms/chrp/Makefile4
-rw-r--r--arch/powerpc/platforms/chrp/chrp.h12
-rw-r--r--arch/powerpc/platforms/chrp/nvram.c84
-rw-r--r--arch/powerpc/platforms/chrp/pci.c310
-rw-r--r--arch/powerpc/platforms/chrp/pegasos_eth.c213
-rw-r--r--arch/powerpc/platforms/chrp/setup.c522
-rw-r--r--arch/powerpc/platforms/chrp/smp.c122
-rw-r--r--arch/powerpc/platforms/chrp/time.c188
-rw-r--r--arch/powerpc/platforms/embedded6xx/Kconfig318
-rw-r--r--arch/powerpc/platforms/iseries/Kconfig31
-rw-r--r--arch/powerpc/platforms/iseries/Makefile9
-rw-r--r--arch/powerpc/platforms/iseries/call_hpt.h (renamed from include/asm-ppc64/iSeries/HvCallHpt.h)7
-rw-r--r--arch/powerpc/platforms/iseries/call_pci.h (renamed from include/asm-ppc64/iSeries/HvCallPci.h)249
-rw-r--r--arch/powerpc/platforms/iseries/call_sm.h (renamed from include/asm-ppc64/iSeries/HvCallSm.h)7
-rw-r--r--arch/powerpc/platforms/iseries/htab.c (renamed from arch/ppc64/kernel/iSeries_htab.c)47
-rw-r--r--arch/powerpc/platforms/iseries/hvcall.S (renamed from arch/ppc64/kernel/hvCall.S)22
-rw-r--r--arch/powerpc/platforms/iseries/hvlog.c (renamed from arch/ppc64/kernel/HvCall.c)1
-rw-r--r--arch/powerpc/platforms/iseries/hvlpconfig.c (renamed from arch/ppc64/kernel/HvLpConfig.c)1
-rw-r--r--arch/powerpc/platforms/iseries/iommu.c (renamed from arch/ppc64/kernel/iSeries_iommu.c)44
-rw-r--r--arch/powerpc/platforms/iseries/ipl_parms.h (renamed from include/asm-ppc64/iSeries/ItIplParmsReal.h)7
-rw-r--r--arch/powerpc/platforms/iseries/irq.c (renamed from arch/ppc64/kernel/iSeries_irq.c)17
-rw-r--r--arch/powerpc/platforms/iseries/irq.h (renamed from include/asm-ppc64/iSeries/iSeries_irq.h)6
-rw-r--r--arch/powerpc/platforms/iseries/ksyms.c27
-rw-r--r--arch/powerpc/platforms/iseries/lpardata.c (renamed from arch/ppc64/kernel/LparData.c)28
-rw-r--r--arch/powerpc/platforms/iseries/lpevents.c (renamed from arch/ppc64/kernel/ItLpQueue.c)77
-rw-r--r--arch/powerpc/platforms/iseries/main_store.h (renamed from include/asm-ppc64/iSeries/IoHriMainStore.h)7
-rw-r--r--arch/powerpc/platforms/iseries/mf.c (renamed from arch/ppc64/kernel/mf.c)98
-rw-r--r--arch/powerpc/platforms/iseries/misc.S55
-rw-r--r--arch/powerpc/platforms/iseries/pci.c (renamed from arch/ppc64/kernel/iSeries_pci.c)173
-rw-r--r--arch/powerpc/platforms/iseries/pci.h (renamed from include/asm-ppc64/iSeries/iSeries_pci.h)49
-rw-r--r--arch/powerpc/platforms/iseries/proc.c (renamed from arch/ppc64/kernel/iSeries_proc.c)15
-rw-r--r--arch/powerpc/platforms/iseries/processor_vpd.h (renamed from include/asm-ppc64/iSeries/IoHriProcessorVpd.h)7
-rw-r--r--arch/powerpc/platforms/iseries/release_data.h (renamed from include/asm-ppc64/iSeries/HvReleaseData.h)7
-rw-r--r--arch/powerpc/platforms/iseries/setup.c (renamed from arch/ppc64/kernel/iSeries_setup.c)495
-rw-r--r--arch/powerpc/platforms/iseries/setup.h (renamed from arch/ppc64/kernel/iSeries_setup.h)4
-rw-r--r--arch/powerpc/platforms/iseries/smp.c (renamed from arch/ppc64/kernel/iSeries_smp.c)46
-rw-r--r--arch/powerpc/platforms/iseries/spcomm_area.h (renamed from include/asm-ppc64/iSeries/ItSpCommArea.h)7
-rw-r--r--arch/powerpc/platforms/iseries/vio.c (renamed from arch/ppc64/kernel/iSeries_vio.c)1
-rw-r--r--arch/powerpc/platforms/iseries/viopath.c (renamed from arch/ppc64/kernel/viopath.c)3
-rw-r--r--arch/powerpc/platforms/iseries/vpd_areas.h (renamed from include/asm-ppc64/iSeries/ItVpdAreas.h)7
-rw-r--r--arch/powerpc/platforms/iseries/vpdinfo.c (renamed from arch/ppc64/kernel/iSeries_VpdInfo.c)21
-rw-r--r--arch/powerpc/platforms/maple/Makefile1
-rw-r--r--arch/powerpc/platforms/maple/maple.h12
-rw-r--r--arch/powerpc/platforms/maple/pci.c (renamed from arch/ppc64/kernel/maple_pci.c)7
-rw-r--r--arch/powerpc/platforms/maple/setup.c (renamed from arch/ppc64/kernel/maple_setup.c)13
-rw-r--r--arch/powerpc/platforms/maple/time.c (renamed from arch/ppc64/kernel/maple_time.c)9
-rw-r--r--arch/powerpc/platforms/powermac/Makefile8
-rw-r--r--arch/powerpc/platforms/powermac/backlight.c202
-rw-r--r--arch/powerpc/platforms/powermac/cache.S359
-rw-r--r--arch/powerpc/platforms/powermac/cpufreq.c726
-rw-r--r--arch/powerpc/platforms/powermac/feature.c3063
-rw-r--r--arch/powerpc/platforms/powermac/low_i2c.c (renamed from arch/ppc64/kernel/pmac_low_i2c.c)0
-rw-r--r--arch/powerpc/platforms/powermac/nvram.c (renamed from arch/ppc64/kernel/pmac_nvram.c)282
-rw-r--r--arch/powerpc/platforms/powermac/pci.c1170
-rw-r--r--arch/powerpc/platforms/powermac/pic.c678
-rw-r--r--arch/powerpc/platforms/powermac/pic.h11
-rw-r--r--arch/powerpc/platforms/powermac/pmac.h51
-rw-r--r--arch/powerpc/platforms/powermac/setup.c794
-rw-r--r--arch/powerpc/platforms/powermac/sleep.S396
-rw-r--r--arch/powerpc/platforms/powermac/smp.c865
-rw-r--r--arch/powerpc/platforms/powermac/time.c360
-rw-r--r--arch/powerpc/platforms/prep/Kconfig22
-rw-r--r--arch/powerpc/platforms/pseries/Kconfig42
-rw-r--r--arch/powerpc/platforms/pseries/Makefile5
-rw-r--r--arch/powerpc/platforms/pseries/hvCall.S (renamed from arch/ppc64/kernel/pSeries_hvCall.S)0
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c (renamed from arch/ppc64/kernel/pSeries_iommu.c)28
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c (renamed from arch/ppc64/kernel/pSeries_lpar.c)5
-rw-r--r--arch/powerpc/platforms/pseries/nvram.c (renamed from arch/ppc64/kernel/pSeries_nvram.c)0
-rw-r--r--arch/powerpc/platforms/pseries/pci.c (renamed from arch/ppc64/kernel/pSeries_pci.c)3
-rw-r--r--arch/powerpc/platforms/pseries/ras.c (renamed from arch/ppc64/kernel/ras.c)11
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c (renamed from arch/ppc64/kernel/pSeries_reconfig.c)0
-rw-r--r--arch/powerpc/platforms/pseries/rtas-fw.c138
-rw-r--r--arch/powerpc/platforms/pseries/rtas-fw.h3
-rw-r--r--arch/powerpc/platforms/pseries/setup.c (renamed from arch/ppc64/kernel/pSeries_setup.c)57
-rw-r--r--arch/powerpc/platforms/pseries/smp.c (renamed from arch/ppc64/kernel/pSeries_smp.c)52
-rw-r--r--arch/powerpc/platforms/pseries/vio.c (renamed from arch/ppc64/kernel/pSeries_vio.c)1
-rw-r--r--arch/powerpc/platforms/pseries/xics.c (renamed from arch/ppc64/kernel/xics.c)30
-rw-r--r--arch/powerpc/platforms/pseries/xics.h (renamed from include/asm-ppc64/xics.h)10
-rw-r--r--arch/powerpc/sysdev/Makefile7
-rw-r--r--arch/powerpc/sysdev/dcr.S (renamed from arch/ppc/syslib/dcr.S)0
-rw-r--r--arch/powerpc/sysdev/grackle.c64
-rw-r--r--arch/powerpc/sysdev/i8259.c (renamed from arch/ppc/syslib/i8259.c)65
-rw-r--r--arch/powerpc/sysdev/indirect_pci.c (renamed from arch/ppc/syslib/indirect_pci.c)0
-rw-r--r--arch/powerpc/sysdev/mpic.c (renamed from arch/ppc64/kernel/mpic.c)53
-rw-r--r--arch/powerpc/sysdev/u3_iommu.c (renamed from arch/ppc64/kernel/u3_iommu.c)50
-rw-r--r--arch/powerpc/xmon/Makefile11
-rw-r--r--arch/powerpc/xmon/ansidecl.h (renamed from arch/ppc64/xmon/ansidecl.h)0
-rw-r--r--arch/powerpc/xmon/nonstdio.h (renamed from arch/ppc64/xmon/nonstdio.h)0
-rw-r--r--arch/powerpc/xmon/ppc-dis.c (renamed from arch/ppc64/xmon/ppc-dis.c)0
-rw-r--r--arch/powerpc/xmon/ppc-opc.c (renamed from arch/ppc64/xmon/ppc-opc.c)0
-rw-r--r--arch/powerpc/xmon/ppc.h (renamed from arch/ppc64/xmon/ppc.h)0
-rw-r--r--arch/powerpc/xmon/setjmp.S135
-rw-r--r--arch/powerpc/xmon/start_32.c624
-rw-r--r--arch/powerpc/xmon/start_64.c (renamed from arch/ppc64/xmon/start.c)0
-rw-r--r--arch/powerpc/xmon/start_8xx.c287
-rw-r--r--arch/powerpc/xmon/subr_prf.c (renamed from arch/ppc64/xmon/subr_prf.c)11
-rw-r--r--arch/powerpc/xmon/xmon.c (renamed from arch/ppc64/xmon/xmon.c)399
-rw-r--r--arch/ppc/8xx_io/commproc.c20
-rw-r--r--arch/ppc/Kconfig40
-rw-r--r--arch/ppc/Makefile14
-rw-r--r--arch/ppc/boot/of1275/claim.c1
-rw-r--r--arch/ppc/boot/openfirmware/chrpmain.c2
-rw-r--r--arch/ppc/boot/openfirmware/coffmain.c2
-rw-r--r--arch/ppc/kernel/Makefile27
-rw-r--r--arch/ppc/kernel/align.c4
-rw-r--r--arch/ppc/kernel/asm-offsets.c3
-rw-r--r--arch/ppc/kernel/cpu_setup_6xx.S6
-rw-r--r--arch/ppc/kernel/cpu_setup_power4.S6
-rw-r--r--arch/ppc/kernel/dma-mapping.c6
-rw-r--r--arch/ppc/kernel/entry.S12
-rw-r--r--arch/ppc/kernel/head.S100
-rw-r--r--arch/ppc/kernel/head_44x.S32
-rw-r--r--arch/ppc/kernel/head_4xx.S68
-rw-r--r--arch/ppc/kernel/head_8xx.S42
-rw-r--r--arch/ppc/kernel/head_booke.h4
-rw-r--r--arch/ppc/kernel/head_fsl_booke.S47
-rw-r--r--arch/ppc/kernel/idle.c3
-rw-r--r--arch/ppc/kernel/irq.c1
-rw-r--r--arch/ppc/kernel/l2cr.S2
-rw-r--r--arch/ppc/kernel/misc.S235
-rw-r--r--arch/ppc/kernel/pci.c33
-rw-r--r--arch/ppc/kernel/perfmon.c96
-rw-r--r--arch/ppc/kernel/perfmon_fsl_booke.c2
-rw-r--r--arch/ppc/kernel/ppc_ksyms.c34
-rw-r--r--arch/ppc/kernel/process.c142
-rw-r--r--arch/ppc/kernel/setup.c39
-rw-r--r--arch/ppc/kernel/signal.c771
-rw-r--r--arch/ppc/kernel/smp.c22
-rw-r--r--arch/ppc/kernel/syscalls.c268
-rw-r--r--arch/ppc/kernel/time.c14
-rw-r--r--arch/ppc/kernel/traps.c42
-rw-r--r--arch/ppc/kernel/vector.S217
-rw-r--r--arch/ppc/kernel/vmlinux.lds.S26
-rw-r--r--arch/ppc/lib/string.S24
-rw-r--r--arch/ppc/math-emu/sfp-machine.h2
-rw-r--r--arch/ppc/mm/4xx_mmu.c4
-rw-r--r--arch/ppc/mm/init.c23
-rw-r--r--arch/ppc/mm/pgtable.c4
-rw-r--r--arch/ppc/oprofile/common.c161
-rw-r--r--arch/ppc/oprofile/op_impl.h45
-rw-r--r--arch/ppc/platforms/4xx/bamboo.c14
-rw-r--r--arch/ppc/platforms/4xx/ebony.c15
-rw-r--r--arch/ppc/platforms/4xx/luan.c13
-rw-r--r--arch/ppc/platforms/4xx/ocotea.c31
-rw-r--r--arch/ppc/platforms/83xx/mpc834x_sys.h1
-rw-r--r--arch/ppc/platforms/85xx/mpc8540_ads.c30
-rw-r--r--arch/ppc/platforms/85xx/mpc8560_ads.c25
-rw-r--r--arch/ppc/platforms/85xx/mpc85xx_ads_common.h1
-rw-r--r--arch/ppc/platforms/85xx/mpc85xx_cds_common.c39
-rw-r--r--arch/ppc/platforms/85xx/sbc8560.c22
-rw-r--r--arch/ppc/platforms/85xx/stx_gp3.c21
-rw-r--r--arch/ppc/platforms/85xx/stx_gp3.h1
-rw-r--r--arch/ppc/platforms/Makefile3
-rw-r--r--arch/ppc/platforms/chestnut.c1
-rw-r--r--arch/ppc/platforms/chrp_nvram.c83
-rw-r--r--arch/ppc/platforms/chrp_pci.c10
-rw-r--r--arch/ppc/platforms/chrp_pegasos_eth.c124
-rw-r--r--arch/ppc/platforms/chrp_setup.c33
-rw-r--r--arch/ppc/platforms/chrp_smp.c3
-rw-r--r--arch/ppc/platforms/chrp_time.c8
-rw-r--r--arch/ppc/platforms/ev64360.c1
-rw-r--r--arch/ppc/platforms/fads.h2
-rw-r--r--arch/ppc/platforms/gemini_setup.c4
-rw-r--r--arch/ppc/platforms/hdpu.c9
-rw-r--r--arch/ppc/platforms/katana.c3
-rw-r--r--arch/ppc/platforms/lite5200.c1
-rw-r--r--arch/ppc/platforms/lopec.c17
-rw-r--r--arch/ppc/platforms/mpc885ads.h2
-rw-r--r--arch/ppc/platforms/mvme5100.c6
-rw-r--r--arch/ppc/platforms/pal4_setup.c1
-rw-r--r--arch/ppc/platforms/pmac_backlight.c16
-rw-r--r--arch/ppc/platforms/pmac_cpufreq.c36
-rw-r--r--arch/ppc/platforms/pmac_feature.c176
-rw-r--r--arch/ppc/platforms/pmac_nvram.c42
-rw-r--r--arch/ppc/platforms/pmac_pci.c28
-rw-r--r--arch/ppc/platforms/pmac_pic.c27
-rw-r--r--arch/ppc/platforms/pmac_setup.c19
-rw-r--r--arch/ppc/platforms/pmac_sleep.S4
-rw-r--r--arch/ppc/platforms/pmac_smp.c11
-rw-r--r--arch/ppc/platforms/pmac_time.c8
-rw-r--r--arch/ppc/platforms/pplus.c17
-rw-r--r--arch/ppc/platforms/prep_pci.c64
-rw-r--r--arch/ppc/platforms/prep_setup.c70
-rw-r--r--arch/ppc/platforms/radstone_ppc7d.c15
-rw-r--r--arch/ppc/platforms/residual.c2
-rw-r--r--arch/ppc/platforms/sandpoint.c21
-rw-r--r--arch/ppc/syslib/Makefile57
-rw-r--r--arch/ppc/syslib/btext.c6
-rw-r--r--arch/ppc/syslib/gt64260_pic.c1
-rw-r--r--arch/ppc/syslib/ibm440gx_common.c6
-rw-r--r--arch/ppc/syslib/ibm44x_common.c37
-rw-r--r--arch/ppc/syslib/ibm44x_common.h3
-rw-r--r--arch/ppc/syslib/m8260_setup.c4
-rw-r--r--arch/ppc/syslib/m82xx_pci.c4
-rw-r--r--arch/ppc/syslib/m8xx_setup.c48
-rw-r--r--arch/ppc/syslib/m8xx_wdt.c14
-rw-r--r--arch/ppc/syslib/mpc52xx_pci.c3
-rw-r--r--arch/ppc/syslib/mpc83xx_devices.c1
-rw-r--r--arch/ppc/syslib/mpc85xx_devices.c17
-rw-r--r--arch/ppc/syslib/mpc85xx_sys.c44
-rw-r--r--arch/ppc/syslib/mpc8xx_sys.c4
-rw-r--r--arch/ppc/syslib/mv64360_pic.c1
-rw-r--r--arch/ppc/syslib/mv64x60.c2
-rw-r--r--arch/ppc/syslib/mv64x60_dbg.c1
-rw-r--r--arch/ppc/syslib/of_device.c276
-rw-r--r--arch/ppc/syslib/open_pic.c3
-rw-r--r--arch/ppc/syslib/open_pic2.c1
-rw-r--r--arch/ppc/syslib/ppc403_pic.c1
-rw-r--r--arch/ppc/syslib/ppc4xx_pic.c1
-rw-r--r--arch/ppc/syslib/ppc4xx_setup.c2
-rw-r--r--arch/ppc/syslib/ppc83xx_setup.c1
-rw-r--r--arch/ppc/syslib/ppc85xx_setup.c1
-rw-r--r--arch/ppc/syslib/ppc8xx_pic.c17
-rw-r--r--arch/ppc/syslib/ppc_sys.c3
-rw-r--r--arch/ppc/syslib/pq2_devices.c1
-rw-r--r--arch/ppc/syslib/prep_nvram.c13
-rw-r--r--arch/ppc/syslib/prom.c18
-rw-r--r--arch/ppc/syslib/xilinx_pic.c1
-rw-r--r--arch/ppc/xmon/start.c3
-rw-r--r--arch/ppc/xmon/xmon.c9
-rw-r--r--arch/ppc64/Kconfig33
-rw-r--r--arch/ppc64/Makefile18
-rw-r--r--arch/ppc64/boot/Makefile67
-rw-r--r--arch/ppc64/boot/crt0.S53
-rw-r--r--arch/ppc64/boot/install.sh2
-rw-r--r--arch/ppc64/boot/main.c268
-rw-r--r--arch/ppc64/boot/string.S4
-rw-r--r--arch/ppc64/boot/string.h1
-rw-r--r--arch/ppc64/boot/zImage.lds64
-rw-r--r--arch/ppc64/boot/zlib.c2195
-rw-r--r--arch/ppc64/boot/zlib.h432
-rw-r--r--arch/ppc64/defconfig4
-rw-r--r--arch/ppc64/kernel/HvLpEvent.c88
-rw-r--r--arch/ppc64/kernel/Makefile75
-rw-r--r--arch/ppc64/kernel/align.c4
-rw-r--r--arch/ppc64/kernel/asm-offsets.c3
-rw-r--r--arch/ppc64/kernel/bpa_iommu.c2
-rw-r--r--arch/ppc64/kernel/bpa_setup.c7
-rw-r--r--arch/ppc64/kernel/btext.c42
-rw-r--r--arch/ppc64/kernel/cputable.c308
-rw-r--r--arch/ppc64/kernel/eeh.c2
-rw-r--r--arch/ppc64/kernel/head.S290
-rw-r--r--arch/ppc64/kernel/hvcserver.c2
-rw-r--r--arch/ppc64/kernel/i8259.c177
-rw-r--r--arch/ppc64/kernel/i8259.h17
-rw-r--r--arch/ppc64/kernel/idle.c8
-rw-r--r--arch/ppc64/kernel/ioctl32.c4
-rw-r--r--arch/ppc64/kernel/kprobes.c1
-rw-r--r--arch/ppc64/kernel/misc.S662
-rw-r--r--arch/ppc64/kernel/pci.c46
-rw-r--r--arch/ppc64/kernel/pci_direct_iommu.c3
-rw-r--r--arch/ppc64/kernel/pci_dn.c3
-rw-r--r--arch/ppc64/kernel/pci_iommu.c21
-rw-r--r--arch/ppc64/kernel/pmac.h31
-rw-r--r--arch/ppc64/kernel/pmac_feature.c767
-rw-r--r--arch/ppc64/kernel/pmac_pci.c793
-rw-r--r--arch/ppc64/kernel/pmac_setup.c525
-rw-r--r--arch/ppc64/kernel/pmac_smp.c330
-rw-r--r--arch/ppc64/kernel/pmac_time.c195
-rw-r--r--arch/ppc64/kernel/ppc_ksyms.c20
-rw-r--r--arch/ppc64/kernel/prom.c7
-rw-r--r--arch/ppc64/kernel/prom_init.c1
-rw-r--r--arch/ppc64/kernel/ptrace.c363
-rw-r--r--arch/ppc64/kernel/rtas-proc.c1
-rw-r--r--arch/ppc64/kernel/rtas_pci.c9
-rw-r--r--arch/ppc64/kernel/rtc.c48
-rw-r--r--arch/ppc64/kernel/signal.c2
-rw-r--r--arch/ppc64/kernel/smp.c40
-rw-r--r--arch/ppc64/kernel/traps.c568
-rw-r--r--arch/ppc64/kernel/vdso.c12
-rw-r--r--arch/ppc64/kernel/vdso64/sigtramp.S1
-rw-r--r--arch/ppc64/kernel/vecemu.c346
-rw-r--r--arch/ppc64/kernel/vmlinux.lds.S17
-rw-r--r--arch/ppc64/lib/Makefile15
-rw-r--r--arch/ppc64/lib/string.S106
-rw-r--r--arch/ppc64/mm/Makefile11
-rw-r--r--arch/ppc64/mm/init.c869
-rw-r--r--arch/ppc64/oprofile/Kconfig23
-rw-r--r--arch/ppc64/oprofile/Makefile9
-rw-r--r--arch/ppc64/xmon/Makefile5
-rw-r--r--arch/ppc64/xmon/setjmp.S73
-rw-r--r--arch/s390/kernel/compat_ioctl.c9
-rw-r--r--arch/s390/kernel/head.S72
-rw-r--r--arch/s390/kernel/head64.S66
-rw-r--r--arch/s390/kernel/setup.c186
-rw-r--r--arch/s390/kernel/time.c4
-rw-r--r--arch/s390/kernel/vtime.c18
-rw-r--r--arch/s390/mm/ioremap.c4
-rw-r--r--arch/sh/drivers/dma/dma-sysfs.c1
-rw-r--r--arch/sh/kernel/cpufreq.c1
-rw-r--r--arch/sh/kernel/ptrace.c2
-rw-r--r--arch/sh/kernel/time.c4
-rw-r--r--arch/sh/mm/fault.c40
-rw-r--r--arch/sh/mm/hugetlbpage.c2
-rw-r--r--arch/sh/mm/ioremap.c4
-rw-r--r--arch/sh64/kernel/ptrace.c2
-rw-r--r--arch/sh64/kernel/time.c3
-rw-r--r--arch/sh64/mm/cache.c68
-rw-r--r--arch/sh64/mm/hugetlbpage.c188
-rw-r--r--arch/sh64/mm/ioremap.c4
-rw-r--r--arch/sparc/kernel/pcic.c4
-rw-r--r--arch/sparc/kernel/time.c4
-rw-r--r--arch/sparc/mm/generic.c7
-rw-r--r--arch/sparc64/kernel/binfmt_aout32.c1
-rw-r--r--arch/sparc64/kernel/ioctl32.c3
-rw-r--r--arch/sparc64/kernel/time.c4
-rw-r--r--arch/sparc64/mm/generic.c9
-rw-r--r--arch/sparc64/mm/tlb.c7
-rw-r--r--arch/um/Kconfig10
-rw-r--r--arch/um/Kconfig.x86_645
-rw-r--r--arch/um/Makefile-i38612
-rw-r--r--arch/um/include/sysdep-i386/syscalls.h1
-rw-r--r--arch/um/include/tlb.h1
-rw-r--r--arch/um/kernel/process_kern.c8
-rw-r--r--arch/um/kernel/skas/mmu.c4
-rw-r--r--arch/um/kernel/time_kern.c4
-rw-r--r--arch/um/kernel/tt/tlb.c36
-rw-r--r--arch/v850/kernel/ptrace.c2
-rw-r--r--arch/v850/kernel/time.c4
-rw-r--r--arch/x86_64/ia32/ia32_aout.c1
-rw-r--r--arch/x86_64/ia32/ia32_ioctl.c125
-rw-r--r--arch/x86_64/kernel/i8259.c8
-rw-r--r--arch/x86_64/kernel/setup.c2
-rw-r--r--arch/x86_64/kernel/suspend.c95
-rw-r--r--arch/x86_64/kernel/time.c32
-rw-r--r--arch/x86_64/mm/ioremap.c4
-rw-r--r--arch/xtensa/kernel/platform.c1
-rw-r--r--arch/xtensa/kernel/ptrace.c2
-rw-r--r--arch/xtensa/kernel/time.c3
-rw-r--r--crypto/api.c5
-rw-r--r--crypto/hmac.c19
-rw-r--r--crypto/tcrypt.c56
-rw-r--r--drivers/acorn/char/pcf8583.c80
-rw-r--r--drivers/acpi/acpi_memhotplug.c5
-rw-r--r--drivers/acpi/processor_idle.c1
-rw-r--r--drivers/acpi/sleep/main.c8
-rw-r--r--drivers/base/Makefile1
-rw-r--r--drivers/base/class.c1
-rw-r--r--drivers/base/cpu.c16
-rw-r--r--drivers/base/firmware_class.c69
-rw-r--r--drivers/base/init.c2
-rw-r--r--drivers/base/memory.c452
-rw-r--r--drivers/base/platform.c1
-rw-r--r--drivers/base/sys.c1
-rw-r--r--drivers/block/Kconfig.iosched28
-rw-r--r--drivers/block/as-iosched.c3
-rw-r--r--drivers/block/cciss_scsi.c10
-rw-r--r--drivers/block/cfq-iosched.c22
-rw-r--r--drivers/block/elevator.c50
-rw-r--r--drivers/block/paride/paride.c1
-rw-r--r--drivers/block/paride/pf.c4
-rw-r--r--drivers/block/paride/pg.c2
-rw-r--r--drivers/block/paride/pt.c1
-rw-r--r--drivers/block/viodasd.c9
-rw-r--r--drivers/cdrom/viocd.c9
-rw-r--r--drivers/char/Kconfig16
-rw-r--r--drivers/char/Makefile1
-rw-r--r--drivers/char/agp/Kconfig16
-rw-r--r--drivers/char/agp/ali-agp.c1
-rw-r--r--drivers/char/agp/amd64-agp.c1
-rw-r--r--drivers/char/agp/ati-agp.c2
-rw-r--r--drivers/char/agp/i460-agp.c2
-rw-r--r--drivers/char/agp/isoch.c1
-rw-r--r--drivers/char/agp/sworks-agp.c2
-rw-r--r--drivers/char/cyclades.c2
-rw-r--r--drivers/char/drm/drm_sysfs.c2
-rw-r--r--drivers/char/epca.c1
-rw-r--r--drivers/char/hangcheck-timer.c2
-rw-r--r--drivers/char/hpet.c168
-rw-r--r--drivers/char/hvc_vio.c2
-rw-r--r--drivers/char/hvcs.c5
-rw-r--r--drivers/char/lcd.c4
-rw-r--r--drivers/char/lcd.h2
-rw-r--r--drivers/char/mem.c4
-rw-r--r--drivers/char/mwave/3780i.c2
-rw-r--r--drivers/char/qtronix.c5
-rw-r--r--drivers/char/rocket.c10
-rw-r--r--drivers/char/ser_a2232.c2
-rw-r--r--drivers/char/specialix.c342
-rw-r--r--drivers/char/synclink.c1
-rw-r--r--drivers/char/synclinkmp.c1
-rw-r--r--drivers/char/tlclk.c896
-rw-r--r--drivers/char/tpm/tpm.c104
-rw-r--r--drivers/char/tpm/tpm.h11
-rw-r--r--drivers/char/tpm/tpm_atmel.c146
-rw-r--r--drivers/char/tpm/tpm_infineon.c179
-rw-r--r--drivers/char/tpm/tpm_nsc.c164
-rw-r--r--drivers/char/tty_io.c2
-rw-r--r--drivers/char/viotape.c9
-rw-r--r--drivers/char/vt_ioctl.c3
-rw-r--r--drivers/char/watchdog/cpu5wdt.c1
-rw-r--r--drivers/char/watchdog/mixcomwd.c2
-rw-r--r--drivers/char/watchdog/pcwd.c2
-rw-r--r--drivers/char/watchdog/pcwd_pci.c1
-rw-r--r--drivers/char/watchdog/sc520_wdt.c1
-rw-r--r--drivers/char/watchdog/softdog.c2
-rw-r--r--drivers/char/watchdog/wdt_pci.c1
-rw-r--r--drivers/cpufreq/cpufreq.c85
-rw-r--r--drivers/cpufreq/cpufreq_stats.c42
-rw-r--r--drivers/crypto/Kconfig2
-rw-r--r--drivers/firmware/Kconfig3
-rw-r--r--drivers/ide/Kconfig31
-rw-r--r--drivers/ide/ide-cd.c56
-rw-r--r--drivers/ide/ide-proc.c1
-rw-r--r--drivers/ide/mips/au1xxx-ide.c1250
-rw-r--r--drivers/ide/ppc/pmac.c80
-rw-r--r--drivers/infiniband/core/agent.h1
-rw-r--r--drivers/infiniband/core/cache.c1
-rw-r--r--drivers/infiniband/core/sa_query.c1
-rw-r--r--drivers/infiniband/hw/mthca/mthca_av.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_mad.c3
-rw-r--r--drivers/infiniband/hw/mthca/mthca_mcg.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_profile.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_qp.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_reset.c1
-rw-r--r--drivers/infiniband/hw/mthca/mthca_uar.c2
-rw-r--r--drivers/input/evdev.c4
-rw-r--r--drivers/input/gameport/gameport.c1
-rw-r--r--drivers/input/input.c2
-rw-r--r--drivers/input/joystick/a3d.c1
-rw-r--r--drivers/input/joystick/adi.c1
-rw-r--r--drivers/input/joystick/analog.c1
-rw-r--r--drivers/input/joystick/cobra.c1
-rw-r--r--drivers/input/joystick/gf2k.c1
-rw-r--r--drivers/input/joystick/grip.c1
-rw-r--r--drivers/input/joystick/grip_mp.c1
-rw-r--r--drivers/input/joystick/guillemot.c1
-rw-r--r--drivers/input/joystick/interact.c1
-rw-r--r--drivers/input/joystick/joydump.c1
-rw-r--r--drivers/input/joystick/sidewinder.c1
-rw-r--r--drivers/input/joystick/tmdc.c1
-rw-r--r--drivers/input/keyboard/amikbd.c2
-rw-r--r--drivers/input/keyboard/lkkbd.c2
-rw-r--r--drivers/input/misc/Kconfig2
-rw-r--r--drivers/input/misc/pcspkr.c2
-rw-r--r--drivers/input/misc/sparcspkr.c2
-rw-r--r--drivers/input/serio/hp_sdc_mlc.c1
-rw-r--r--drivers/isdn/capi/capifs.c1
-rw-r--r--drivers/isdn/hisax/hfc4s8s_l1.c10
-rw-r--r--drivers/macintosh/adbhid.c1
-rw-r--r--drivers/macintosh/ans-lcd.c10
-rw-r--r--drivers/macintosh/apm_emu.c8
-rw-r--r--drivers/macintosh/macio_asic.c2
-rw-r--r--drivers/macintosh/macio_sysfs.c26
-rw-r--r--drivers/macintosh/mediabay.c56
-rw-r--r--drivers/macintosh/smu.c4
-rw-r--r--drivers/macintosh/via-cuda.c1
-rw-r--r--drivers/macintosh/via-pmu.c142
-rw-r--r--drivers/macintosh/via-pmu68k.c15
-rw-r--r--drivers/mca/mca-device.c1
-rw-r--r--drivers/md/dm-crypt.c12
-rw-r--r--drivers/media/common/ir-common.c1
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.c1
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u.c4
-rw-r--r--drivers/media/dvb/dvb-usb/vp7045.c2
-rw-r--r--drivers/media/dvb/frontends/bcm3510.c3
-rw-r--r--drivers/media/dvb/frontends/dib3000mb.c2
-rw-r--r--drivers/media/dvb/frontends/dib3000mc.c2
-rw-r--r--drivers/media/dvb/frontends/dvb_dummy_fe.c2
-rw-r--r--drivers/media/dvb/frontends/lgdt330x.c2
-rw-r--r--drivers/media/dvb/frontends/mt312.c2
-rw-r--r--drivers/media/dvb/frontends/mt352.c2
-rw-r--r--drivers/media/dvb/frontends/nxt2002.c2
-rw-r--r--drivers/media/dvb/frontends/or51132.c2
-rw-r--r--drivers/media/dvb/frontends/or51211.c2
-rw-r--r--drivers/media/dvb/frontends/s5h1420.c2
-rw-r--r--drivers/media/dvb/frontends/sp8870.c2
-rw-r--r--drivers/media/dvb/frontends/sp887x.c2
-rw-r--r--drivers/media/dvb/frontends/stv0297.c2
-rw-r--r--drivers/media/dvb/frontends/stv0299.c1
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c4
-rw-r--r--drivers/media/dvb/frontends/tda8083.c1
-rw-r--r--drivers/media/radio/miropcm20-rds.c1
-rw-r--r--drivers/media/video/indycam.c10
-rw-r--r--drivers/media/video/saa7191.c14
-rw-r--r--drivers/media/video/vino.c7
-rw-r--r--drivers/message/i2o/debug.c2
-rw-r--r--drivers/message/i2o/device.c2
-rw-r--r--drivers/message/i2o/driver.c3
-rw-r--r--drivers/message/i2o/exec-osm.c4
-rw-r--r--drivers/message/i2o/iop.c1
-rw-r--r--drivers/mfd/ucb1x00-ts.c74
-rw-r--r--drivers/mmc/Kconfig9
-rw-r--r--drivers/mmc/Makefile1
-rw-r--r--drivers/mmc/au1xmmc.c1026
-rw-r--r--drivers/mmc/au1xmmc.h96
-rw-r--r--drivers/mmc/mmc_block.c10
-rw-r--r--drivers/mmc/pxamci.c1
-rw-r--r--drivers/mtd/chips/jedec.c1
-rw-r--r--drivers/mtd/devices/lart.c1
-rw-r--r--drivers/mtd/devices/phram.c1
-rw-r--r--drivers/mtd/maps/bast-flash.c3
-rw-r--r--drivers/mtd/maps/ceiva.c1
-rw-r--r--drivers/mtd/maps/dc21285.c1
-rw-r--r--drivers/mtd/maps/dilnetpc.c5
-rw-r--r--drivers/mtd/maps/epxa10db-flash.c5
-rw-r--r--drivers/mtd/maps/fortunet.c5
-rw-r--r--drivers/mtd/maps/ixp2000.c7
-rw-r--r--drivers/mtd/maps/ixp4xx.c8
-rw-r--r--drivers/mtd/maps/lubbock-flash.c3
-rw-r--r--drivers/mtd/maps/mainstone-flash.c3
-rw-r--r--drivers/mtd/maps/omap-toto-flash.c2
-rw-r--r--drivers/mtd/maps/omap_nor.c2
-rw-r--r--drivers/mtd/maps/pci.c1
-rw-r--r--drivers/mtd/maps/plat-ram.c2
-rw-r--r--drivers/mtd/maps/sa1100-flash.c66
-rw-r--r--drivers/mtd/maps/tqm8xxl.c4
-rw-r--r--drivers/mtd/mtdblock.c1
-rw-r--r--drivers/mtd/mtdchar.c1
-rw-r--r--drivers/mtd/mtdconcat.c2
-rw-r--r--drivers/mtd/nand/s3c2410.c1
-rw-r--r--drivers/net/Kconfig77
-rw-r--r--drivers/net/Makefile3
-rw-r--r--drivers/net/acenic.c6
-rw-r--r--[-rwxr-xr-x]drivers/net/amd8111e.c0
-rw-r--r--[-rwxr-xr-x]drivers/net/amd8111e.h0
-rw-r--r--drivers/net/au1000_eth.c6
-rw-r--r--drivers/net/b44.c28
-rw-r--r--drivers/net/bmac.c7
-rw-r--r--drivers/net/bnx2.c12
-rw-r--r--drivers/net/e1000/e1000_ethtool.c7
-rw-r--r--drivers/net/e1000/e1000_main.c9
-rw-r--r--drivers/net/eepro.c57
-rw-r--r--drivers/net/fs_enet/Kconfig20
-rw-r--r--drivers/net/fs_enet/Makefile10
-rw-r--r--drivers/net/fs_enet/fs_enet-main.c1226
-rw-r--r--drivers/net/fs_enet/fs_enet-mii.c507
-rw-r--r--drivers/net/fs_enet/fs_enet.h245
-rw-r--r--drivers/net/fs_enet/mac-fcc.c578
-rw-r--r--drivers/net/fs_enet/mac-fec.c653
-rw-r--r--drivers/net/fs_enet/mac-scc.c524
-rw-r--r--drivers/net/fs_enet/mii-bitbang.c405
-rw-r--r--drivers/net/fs_enet/mii-fixed.c92
-rw-r--r--drivers/net/hamradio/mkiss.c6
-rw-r--r--drivers/net/ibm_emac/Makefile13
-rw-r--r--drivers/net/ibm_emac/ibm_emac.h408
-rw-r--r--drivers/net/ibm_emac/ibm_emac_core.c3396
-rw-r--r--drivers/net/ibm_emac/ibm_emac_core.h313
-rw-r--r--drivers/net/ibm_emac/ibm_emac_debug.c363
-rw-r--r--drivers/net/ibm_emac/ibm_emac_debug.h63
-rw-r--r--drivers/net/ibm_emac/ibm_emac_mal.c674
-rw-r--r--drivers/net/ibm_emac/ibm_emac_mal.h332
-rw-r--r--drivers/net/ibm_emac/ibm_emac_phy.c335
-rw-r--r--drivers/net/ibm_emac/ibm_emac_phy.h105
-rw-r--r--drivers/net/ibm_emac/ibm_emac_rgmii.c201
-rw-r--r--drivers/net/ibm_emac/ibm_emac_rgmii.h60
-rw-r--r--drivers/net/ibm_emac/ibm_emac_tah.c111
-rw-r--r--drivers/net/ibm_emac/ibm_emac_tah.h96
-rw-r--r--drivers/net/ibm_emac/ibm_emac_zmii.c255
-rw-r--r--drivers/net/ibm_emac/ibm_emac_zmii.h104
-rw-r--r--drivers/net/ibmveth.c200
-rw-r--r--drivers/net/ibmveth.h23
-rw-r--r--drivers/net/irda/donauboe.c6
-rw-r--r--drivers/net/irda/irda-usb.c6
-rw-r--r--drivers/net/irda/irport.c3
-rw-r--r--drivers/net/irda/pxaficp_ir.c14
-rw-r--r--drivers/net/irda/sir_dev.c3
-rw-r--r--drivers/net/irda/smsc-ircc2.c129
-rw-r--r--drivers/net/irda/vlsi_ir.c3
-rw-r--r--drivers/net/iseries_veth.c18
-rw-r--r--drivers/net/mace.c7
-rw-r--r--drivers/net/mv643xx_eth.c3
-rw-r--r--drivers/net/ne2k-pci.c1
-rw-r--r--drivers/net/ni65.c9
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c6
-rw-r--r--drivers/net/rrunner.c6
-rw-r--r--drivers/net/s2io.c13
-rw-r--r--drivers/net/saa9730.c8
-rw-r--r--drivers/net/sis190.c2
-rw-r--r--drivers/net/sis900.c16
-rw-r--r--drivers/net/skfp/smt.c2
-rw-r--r--drivers/net/smc91x.c4
-rw-r--r--drivers/net/smc91x.h12
-rw-r--r--drivers/net/starfire.c4
-rw-r--r--drivers/net/sundance.c62
-rw-r--r--drivers/net/tg3.c91
-rw-r--r--drivers/net/tg3.h12
-rw-r--r--drivers/net/tulip/de2104x.c6
-rw-r--r--drivers/net/tulip/tulip_core.c6
-rw-r--r--drivers/net/via-velocity.c6
-rw-r--r--drivers/net/wireless/airo.c55
-rw-r--r--drivers/net/wireless/airo_cs.c4
-rw-r--r--drivers/net/wireless/atmel.c6
-rw-r--r--drivers/net/wireless/atmel_cs.c3
-rw-r--r--drivers/net/wireless/hermes.c38
-rw-r--r--drivers/net/wireless/hermes.h2
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c9
-rw-r--r--drivers/net/wireless/ipw2200.c4
-rw-r--r--drivers/net/wireless/orinoco.c13
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.c3
-rw-r--r--drivers/net/wireless/prism54/islpci_eth.c13
-rw-r--r--drivers/net/wireless/prism54/islpci_mgt.c2
-rw-r--r--drivers/net/wireless/prism54/oid_mgt.c9
-rw-r--r--drivers/net/wireless/strip.c38
-rw-r--r--drivers/pci/hotplug/cpcihp_generic.c1
-rw-r--r--drivers/pci/hotplug/cpcihp_zt5550.c1
-rw-r--r--drivers/pci/hotplug/fakephp.c2
-rw-r--r--drivers/pci/hotplug/ibmphp_core.c2
-rw-r--r--drivers/pci/hotplug/pciehp_pci.c2
-rw-r--r--drivers/pci/hotplug/pciehprm_nonacpi.c3
-rw-r--r--drivers/pci/hotplug/rpadlpar_core.c3
-rw-r--r--drivers/pci/hotplug/rpaphp_pci.c4
-rw-r--r--drivers/pci/hotplug/rpaphp_slot.c3
-rw-r--r--drivers/pci/hotplug/shpchp.h2
-rw-r--r--drivers/pci/hotplug/shpchprm_nonacpi.c2
-rw-r--r--drivers/pci/pci-driver.c2
-rw-r--r--drivers/pci/pci.c1
-rw-r--r--drivers/pci/pcie/portdrv_core.c2
-rw-r--r--drivers/pci/pcie/portdrv_pci.c1
-rw-r--r--drivers/pci/quirks.c4
-rw-r--r--drivers/pci/rom.c1
-rw-r--r--drivers/pcmcia/Kconfig10
-rw-r--r--drivers/pcmcia/Makefile4
-rw-r--r--drivers/pcmcia/au1000_db1x00.c21
-rw-r--r--drivers/pcmcia/au1000_generic.c8
-rw-r--r--drivers/pcmcia/au1000_generic.h4
-rw-r--r--drivers/pcmcia/m8xx_pcmcia.c1290
-rw-r--r--drivers/pcmcia/pxa2xx_sharpsl.c31
-rw-r--r--drivers/pcmcia/rsrc_nonstatic.c2
-rw-r--r--drivers/pcmcia/sa1100_generic.c7
-rw-r--r--drivers/pnp/manager.c2
-rw-r--r--drivers/pnp/pnpbios/rsparser.c2
-rw-r--r--drivers/s390/char/con3270.c7
-rw-r--r--drivers/s390/char/fs3270.c234
-rw-r--r--drivers/s390/char/raw3270.c100
-rw-r--r--drivers/s390/char/raw3270.h7
-rw-r--r--drivers/s390/char/tty3270.c27
-rw-r--r--drivers/s390/char/vmlogrdr.c2
-rw-r--r--drivers/s390/cio/cmf.c3
-rw-r--r--drivers/s390/cio/device.c20
-rw-r--r--drivers/s390/cio/device_fsm.c2
-rw-r--r--drivers/scsi/ahci.c55
-rw-r--r--drivers/scsi/arm/scsi.h6
-rw-r--r--drivers/scsi/ata_piix.c15
-rw-r--r--drivers/scsi/dec_esp.c2
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.c9
-rw-r--r--drivers/scsi/ide-scsi.c38
-rw-r--r--drivers/scsi/libata-core.c104
-rw-r--r--drivers/scsi/libata-scsi.c804
-rw-r--r--drivers/scsi/libata.h5
-rw-r--r--drivers/scsi/mesh.c2
-rw-r--r--drivers/scsi/pdc_adma.c46
-rw-r--r--drivers/scsi/sata_mv.c41
-rw-r--r--drivers/scsi/sata_nv.c3
-rw-r--r--drivers/scsi/sata_promise.c23
-rw-r--r--drivers/scsi/sata_qstor.c27
-rw-r--r--drivers/scsi/sata_sil.c7
-rw-r--r--drivers/scsi/sata_sil24.c76
-rw-r--r--drivers/scsi/sata_sis.c13
-rw-r--r--drivers/scsi/sata_svw.c25
-rw-r--r--drivers/scsi/sata_sx4.c13
-rw-r--r--drivers/scsi/sata_uli.c5
-rw-r--r--drivers/scsi/sata_via.c38
-rw-r--r--drivers/scsi/sata_vsc.c23
-rw-r--r--drivers/scsi/scsi_transport_fc.c1
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c3
-rw-r--r--drivers/scsi/sg.c17
-rw-r--r--drivers/scsi/st.c10
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_hipd.c3
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_hipd.h2
-rw-r--r--drivers/serial/ioc4_serial.c80
-rw-r--r--drivers/serial/mpsc.c2
-rw-r--r--drivers/serial/serial_core.c3
-rw-r--r--drivers/sh/superhyway/superhyway.c2
-rw-r--r--drivers/tc/tc.c89
-rw-r--r--drivers/tc/zs.c32
-rw-r--r--drivers/usb/host/ohci-omap.c2
-rw-r--r--drivers/usb/host/ohci-pci.c2
-rw-r--r--drivers/usb/host/ohci-pxa27x.c3
-rw-r--r--drivers/usb/input/pid.c2
-rw-r--r--drivers/usb/misc/idmouse.c16
-rw-r--r--drivers/usb/misc/usbtest.c7
-rw-r--r--drivers/video/Kconfig14
-rw-r--r--drivers/video/Makefile2
-rw-r--r--drivers/video/au1100fb.c971
-rw-r--r--drivers/video/au1100fb.h614
-rw-r--r--drivers/video/console/Kconfig2
-rw-r--r--drivers/video/console/newport_con.c1
-rw-r--r--drivers/video/console/vgacon.c2
-rw-r--r--drivers/video/fbmem.c2
-rw-r--r--drivers/video/gbefb.c20
-rw-r--r--drivers/w1/w1_family.c1
-rw-r--r--drivers/zorro/zorro-sysfs.c1
-rw-r--r--drivers/zorro/zorro.c2
-rw-r--r--fs/Kconfig2
-rw-r--r--fs/Kconfig.binfmt2
-rw-r--r--fs/afs/file.c4
-rw-r--r--fs/attr.c3
-rw-r--r--fs/binfmt_aout.c1
-rw-r--r--fs/binfmt_elf.c5
-rw-r--r--fs/binfmt_elf_fdpic.c7
-rw-r--r--fs/binfmt_flat.c1
-rw-r--r--fs/binfmt_som.c1
-rw-r--r--fs/buffer.c21
-rw-r--r--fs/compat.c1
-rw-r--r--fs/compat_ioctl.c4
-rw-r--r--fs/direct-io.c4
-rw-r--r--fs/dquot.c2
-rw-r--r--fs/exec.c56
-rw-r--r--fs/ext2/inode.c4
-rw-r--r--fs/ext3/balloc.c7
-rw-r--r--fs/ext3/bitmap.c2
-rw-r--r--fs/ext3/bitmap.h8
-rw-r--r--fs/ext3/ialloc.c3
-rw-r--r--fs/ext3/inode.c11
-rw-r--r--fs/ext3/namei.c2
-rw-r--r--fs/ext3/namei.h8
-rw-r--r--fs/ext3/resize.c10
-rw-r--r--fs/ext3/super.c4
-rw-r--r--fs/ext3/xattr.c8
-rw-r--r--fs/fat/dir.c230
-rw-r--r--fs/file_table.c14
-rw-r--r--fs/filesystems.c1
-rw-r--r--fs/fs-writeback.c28
-rw-r--r--fs/fuse/dev.c6
-rw-r--r--fs/fuse/dir.c5
-rw-r--r--fs/fuse/fuse_i.h12
-rw-r--r--fs/hugetlbfs/inode.c206
-rw-r--r--fs/inode.c1
-rw-r--r--fs/jffs2/background.c1
-rw-r--r--fs/jffs2/wbuf.c2
-rw-r--r--fs/jfs/jfs_metapage.c12
-rw-r--r--fs/msdos/namei.c14
-rw-r--r--fs/namei.c6
-rw-r--r--fs/nfs/inode.c2
-rw-r--r--fs/proc/array.c2
-rw-r--r--fs/proc/generic.c2
-rw-r--r--fs/proc/inode.c17
-rw-r--r--fs/proc/proc_misc.c8
-rw-r--r--fs/proc/task_mmu.c51
-rw-r--r--fs/reiserfs/super.c25
-rw-r--r--fs/reiserfs/xattr_acl.c3
-rw-r--r--fs/super.c2
-rw-r--r--fs/vfat/namei.c20
-rw-r--r--fs/xattr.c14
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.c7
-rw-r--r--include/asm-alpha/barrier.h2
-rw-r--r--include/asm-alpha/rwsem.h5
-rw-r--r--include/asm-alpha/semaphore.h3
-rw-r--r--include/asm-arm/arch-aaec2000/memory.h2
-rw-r--r--include/asm-arm/arch-cl7500/memory.h2
-rw-r--r--include/asm-arm/arch-clps711x/memory.h2
-rw-r--r--include/asm-arm/arch-ebsa110/memory.h2
-rw-r--r--include/asm-arm/arch-ebsa285/memory.h10
-rw-r--r--include/asm-arm/arch-epxa10db/memory.h2
-rw-r--r--include/asm-arm/arch-h720x/memory.h2
-rw-r--r--include/asm-arm/arch-imx/memory.h2
-rw-r--r--include/asm-arm/arch-integrator/memory.h4
-rw-r--r--include/asm-arm/arch-iop3xx/memory.h4
-rw-r--r--include/asm-arm/arch-ixp2000/ixdp2x01.h2
-rw-r--r--include/asm-arm/arch-ixp2000/memory.h2
-rw-r--r--include/asm-arm/arch-ixp2000/platform.h50
-rw-r--r--include/asm-arm/arch-ixp4xx/io.h6
-rw-r--r--include/asm-arm/arch-ixp4xx/ixp4xx-regs.h75
-rw-r--r--include/asm-arm/arch-ixp4xx/memory.h2
-rw-r--r--include/asm-arm/arch-l7200/memory.h2
-rw-r--r--include/asm-arm/arch-lh7a40x/memory.h2
-rw-r--r--include/asm-arm/arch-omap/memory.h6
-rw-r--r--include/asm-arm/arch-pxa/memory.h2
-rw-r--r--include/asm-arm/arch-rpc/memory.h2
-rw-r--r--include/asm-arm/arch-s3c2410/memory.h4
-rw-r--r--include/asm-arm/arch-sa1100/memory.h2
-rw-r--r--include/asm-arm/arch-shark/memory.h2
-rw-r--r--include/asm-arm/arch-versatile/memory.h2
-rw-r--r--include/asm-arm/mach/arch.h1
-rw-r--r--include/asm-arm/mach/flash.h2
-rw-r--r--include/asm-arm/mach/map.h4
-rw-r--r--include/asm-arm/memory.h25
-rw-r--r--include/asm-arm/pgtable.h3
-rw-r--r--include/asm-arm/semaphore.h2
-rw-r--r--include/asm-arm/tlb.h23
-rw-r--r--include/asm-arm/unistd.h1
-rw-r--r--include/asm-arm26/pgtable.h2
-rw-r--r--include/asm-arm26/semaphore.h3
-rw-r--r--include/asm-arm26/tlb.h47
-rw-r--r--include/asm-arm26/unistd.h1
-rw-r--r--include/asm-cris/semaphore.h3
-rw-r--r--include/asm-cris/unistd.h1
-rw-r--r--include/asm-frv/pgtable.h2
-rw-r--r--include/asm-frv/semaphore.h3
-rw-r--r--include/asm-generic/4level-fixup.h11
-rw-r--r--include/asm-generic/pgtable.h2
-rw-r--r--include/asm-generic/tlb.h23
-rw-r--r--include/asm-h8300/semaphore.h3
-rw-r--r--include/asm-h8300/unistd.h1
-rw-r--r--include/asm-i386/apic.h3
-rw-r--r--include/asm-i386/desc.h8
-rw-r--r--include/asm-i386/hw_irq.h1
-rw-r--r--include/asm-i386/mach-default/smpboot_hooks.h15
-rw-r--r--include/asm-i386/mach-es7000/mach_mpparse.h2
-rw-r--r--include/asm-i386/mach-visws/smpboot_hooks.h7
-rw-r--r--include/asm-i386/mmzone.h6
-rw-r--r--include/asm-i386/pgtable-2level.h5
-rw-r--r--include/asm-i386/pgtable-3level.h5
-rw-r--r--include/asm-i386/pgtable.h10
-rw-r--r--include/asm-i386/rwsem.h5
-rw-r--r--include/asm-i386/semaphore.h3
-rw-r--r--include/asm-i386/system.h33
-rw-r--r--include/asm-i386/unistd.h1
-rw-r--r--include/asm-ia64/pgtable.h3
-rw-r--r--include/asm-ia64/rwsem.h5
-rw-r--r--include/asm-ia64/semaphore.h2
-rw-r--r--include/asm-ia64/tlb.h19
-rw-r--r--include/asm-ia64/unistd.h2
-rw-r--r--include/asm-m32r/mmzone.h6
-rw-r--r--include/asm-m32r/pgtable.h2
-rw-r--r--include/asm-m32r/semaphore.h3
-rw-r--r--include/asm-m32r/thread_info.h2
-rw-r--r--include/asm-m32r/unistd.h1
-rw-r--r--include/asm-m68k/semaphore.h3
-rw-r--r--include/asm-m68k/sun3xflop.h2
-rw-r--r--include/asm-m68k/unistd.h1
-rw-r--r--include/asm-m68knommu/ide.h7
-rw-r--r--include/asm-m68knommu/semaphore.h3
-rw-r--r--include/asm-m68knommu/unistd.h1
-rw-r--r--include/asm-mips/abi.h25
-rw-r--r--include/asm-mips/addrspace.h90
-rw-r--r--include/asm-mips/asm.h4
-rw-r--r--include/asm-mips/atomic.h40
-rw-r--r--include/asm-mips/bitops.h209
-rw-r--r--include/asm-mips/bootinfo.h5
-rw-r--r--include/asm-mips/break.h1
-rw-r--r--include/asm-mips/bug.h11
-rw-r--r--include/asm-mips/bugs.h6
-rw-r--r--include/asm-mips/cache.h3
-rw-r--r--include/asm-mips/cacheflush.h31
-rw-r--r--include/asm-mips/checksum.h159
-rw-r--r--include/asm-mips/cobalt/cobalt.h52
-rw-r--r--include/asm-mips/cobalt/mach-gt64120.h1
-rw-r--r--include/asm-mips/compat.h12
-rw-r--r--include/asm-mips/cpu-features.h66
-rw-r--r--include/asm-mips/cpu-info.h2
-rw-r--r--include/asm-mips/cpu.h87
-rw-r--r--include/asm-mips/dec/ecc.h3
-rw-r--r--include/asm-mips/dec/ioasic_addrs.h3
-rw-r--r--include/asm-mips/dec/kn01.h34
-rw-r--r--include/asm-mips/dec/kn02.h33
-rw-r--r--include/asm-mips/dec/kn02xa.h46
-rw-r--r--include/asm-mips/dec/kn03.h13
-rw-r--r--include/asm-mips/dec/kn05.h76
-rw-r--r--include/asm-mips/dec/prom.h30
-rw-r--r--include/asm-mips/dec/system.h18
-rw-r--r--include/asm-mips/dec/tc.h10
-rw-r--r--include/asm-mips/delay.h8
-rw-r--r--include/asm-mips/dsp.h83
-rw-r--r--include/asm-mips/elf.h96
-rw-r--r--include/asm-mips/errno.h4
-rw-r--r--include/asm-mips/fcntl.h17
-rw-r--r--include/asm-mips/fixmap.h7
-rw-r--r--include/asm-mips/fpu.h9
-rw-r--r--include/asm-mips/fpu_emulator.h19
-rw-r--r--include/asm-mips/futex.h50
-rw-r--r--include/asm-mips/hazards.h58
-rw-r--r--include/asm-mips/highmem.h2
-rw-r--r--include/asm-mips/inst.h10
-rw-r--r--include/asm-mips/interrupt.h137
-rw-r--r--include/asm-mips/inventory.h8
-rw-r--r--include/asm-mips/io.h164
-rw-r--r--include/asm-mips/irq.h4
-rw-r--r--include/asm-mips/jmr3927/jmr3927.h14
-rw-r--r--include/asm-mips/mach-au1x00/au1000.h554
-rw-r--r--include/asm-mips/mach-au1x00/au1xxx.h44
-rw-r--r--include/asm-mips/mach-au1x00/au1xxx_dbdma.h128
-rw-r--r--include/asm-mips/mach-au1x00/au1xxx_gpio.h20
-rw-r--r--include/asm-mips/mach-au1x00/au1xxx_ide.h301
-rw-r--r--include/asm-mips/mach-au1x00/au1xxx_psc.h2
-rw-r--r--include/asm-mips/mach-au1x00/ioremap.h32
-rw-r--r--include/asm-mips/mach-db1x00/db1200.h224
-rw-r--r--include/asm-mips/mach-dec/mc146818rtc.h11
-rw-r--r--include/asm-mips/mach-generic/cpu-feature-overrides.h2
-rw-r--r--include/asm-mips/mach-generic/ide.h73
-rw-r--r--include/asm-mips/mach-generic/ioremap.h23
-rw-r--r--include/asm-mips/mach-generic/kernel-entry-init.h25
-rw-r--r--include/asm-mips/mach-generic/kmalloc.h13
-rw-r--r--include/asm-mips/mach-generic/spaces.h10
-rw-r--r--include/asm-mips/mach-ip22/cpu-feature-overrides.h8
-rw-r--r--include/asm-mips/mach-ip22/spaces.h2
-rw-r--r--include/asm-mips/mach-ip27/cpu-feature-overrides.h1
-rw-r--r--include/asm-mips/mach-ip27/kernel-entry-init.h52
-rw-r--r--include/asm-mips/mach-ip27/kmalloc.h8
-rw-r--r--include/asm-mips/mach-ip27/mmzone.h2
-rw-r--r--include/asm-mips/mach-ip27/spaces.h1
-rw-r--r--include/asm-mips/mach-ip27/topology.h3
-rw-r--r--include/asm-mips/mach-ip32/cpu-feature-overrides.h1
-rw-r--r--include/asm-mips/mach-ip32/kmalloc.h12
-rw-r--r--include/asm-mips/mach-ip32/spaces.h8
-rw-r--r--include/asm-mips/mach-ja/cpu-feature-overrides.h7
-rw-r--r--include/asm-mips/mach-mips/cpu-feature-overrides.h6
-rw-r--r--include/asm-mips/mach-mips/irq.h14
-rw-r--r--include/asm-mips/mach-ocelot3/cpu-feature-overrides.h7
-rw-r--r--include/asm-mips/mach-pb1x00/pb1200.h252
-rw-r--r--include/asm-mips/mach-pnx8550/cm.h43
-rw-r--r--include/asm-mips/mach-pnx8550/glb.h86
-rw-r--r--include/asm-mips/mach-pnx8550/int.h140
-rw-r--r--include/asm-mips/mach-pnx8550/kernel-entry-init.h262
-rw-r--r--include/asm-mips/mach-pnx8550/nand.h121
-rw-r--r--include/asm-mips/mach-pnx8550/pci.h185
-rw-r--r--include/asm-mips/mach-pnx8550/uart.h16
-rw-r--r--include/asm-mips/mach-pnx8550/usb.h32
-rw-r--r--include/asm-mips/mach-rm200/cpu-feature-overrides.h3
-rw-r--r--include/asm-mips/mach-sibyte/cpu-feature-overrides.h1
-rw-r--r--include/asm-mips/mach-sim/cpu-feature-overrides.h66
-rw-r--r--include/asm-mips/mach-yosemite/cpu-feature-overrides.h7
-rw-r--r--include/asm-mips/mips-boards/generic.h7
-rw-r--r--include/asm-mips/mips-boards/maltaint.h58
-rw-r--r--include/asm-mips/mips-boards/msc01_pci.h241
-rw-r--r--include/asm-mips/mips-boards/sim.h40
-rw-r--r--include/asm-mips/mips-boards/simint.h34
-rw-r--r--include/asm-mips/mipsmtregs.h391
-rw-r--r--include/asm-mips/mipsregs.h394
-rw-r--r--include/asm-mips/mmu_context.h4
-rw-r--r--include/asm-mips/mmzone.h1
-rw-r--r--include/asm-mips/module.h90
-rw-r--r--include/asm-mips/paccess.h8
-rw-r--r--include/asm-mips/page.h42
-rw-r--r--include/asm-mips/pci.h36
-rw-r--r--include/asm-mips/pgalloc.h19
-rw-r--r--include/asm-mips/pgtable-32.h53
-rw-r--r--include/asm-mips/pgtable-64.h71
-rw-r--r--include/asm-mips/pgtable-bits.h6
-rw-r--r--include/asm-mips/pgtable.h24
-rw-r--r--include/asm-mips/processor.h22
-rw-r--r--include/asm-mips/ptrace.h19
-rw-r--r--include/asm-mips/r4kcache.h72
-rw-r--r--include/asm-mips/rtc.h53
-rw-r--r--include/asm-mips/rtlx.h56
-rw-r--r--include/asm-mips/semaphore.h3
-rw-r--r--include/asm-mips/serial.h35
-rw-r--r--include/asm-mips/sibyte/bcm1480_int.h310
-rw-r--r--include/asm-mips/sibyte/bcm1480_l2c.h176
-rw-r--r--include/asm-mips/sibyte/bcm1480_mc.h962
-rw-r--r--include/asm-mips/sibyte/bcm1480_regs.h869
-rw-r--r--include/asm-mips/sibyte/bcm1480_scd.h436
-rw-r--r--include/asm-mips/sibyte/bigsur.h49
-rw-r--r--include/asm-mips/sibyte/board.h16
-rw-r--r--include/asm-mips/sibyte/sb1250.h13
-rw-r--r--include/asm-mips/sibyte/sb1250_defs.h33
-rw-r--r--include/asm-mips/sibyte/sb1250_dma.h70
-rw-r--r--include/asm-mips/sibyte/sb1250_genbus.h230
-rw-r--r--include/asm-mips/sibyte/sb1250_int.h8
-rw-r--r--include/asm-mips/sibyte/sb1250_l2c.h11
-rw-r--r--include/asm-mips/sibyte/sb1250_ldt.h2
-rw-r--r--include/asm-mips/sibyte/sb1250_mac.h35
-rw-r--r--include/asm-mips/sibyte/sb1250_mc.h6
-rw-r--r--include/asm-mips/sibyte/sb1250_regs.h35
-rw-r--r--include/asm-mips/sibyte/sb1250_scd.h102
-rw-r--r--include/asm-mips/sibyte/sb1250_smbus.h58
-rw-r--r--include/asm-mips/sibyte/sb1250_syncser.h2
-rw-r--r--include/asm-mips/sibyte/sb1250_uart.h13
-rw-r--r--include/asm-mips/sibyte/swarm.h2
-rw-r--r--include/asm-mips/sigcontext.h60
-rw-r--r--include/asm-mips/siginfo.h1
-rw-r--r--include/asm-mips/signal.h29
-rw-r--r--include/asm-mips/sn/sn0/arch.h5
-rw-r--r--include/asm-mips/socket.h5
-rw-r--r--include/asm-mips/spinlock.h26
-rw-r--r--include/asm-mips/stackframe.h29
-rw-r--r--include/asm-mips/system.h71
-rw-r--r--include/asm-mips/thread_info.h11
-rw-r--r--include/asm-mips/traps.h3
-rw-r--r--include/asm-mips/tx4938/rbtx4938.h207
-rw-r--r--include/asm-mips/tx4938/spi.h74
-rw-r--r--include/asm-mips/tx4938/tx4938.h706
-rw-r--r--include/asm-mips/tx4938/tx4938_mips.h54
-rw-r--r--include/asm-mips/uaccess.h158
-rw-r--r--include/asm-mips/unistd.h26
-rw-r--r--include/asm-mips/vga.h25
-rw-r--r--include/asm-mips/war.h14
-rw-r--r--include/asm-parisc/cacheflush.h35
-rw-r--r--include/asm-parisc/ide.h1
-rw-r--r--include/asm-parisc/mmzone.h6
-rw-r--r--include/asm-parisc/semaphore.h3
-rw-r--r--include/asm-parisc/tlbflush.h3
-rw-r--r--include/asm-parisc/unistd.h1
-rw-r--r--include/asm-powerpc/a.out.h (renamed from include/asm-ppc64/a.out.h)21
-rw-r--r--include/asm-powerpc/atomic.h (renamed from include/asm-ppc/atomic.h)45
-rw-r--r--include/asm-powerpc/auxvec.h (renamed from include/asm-ppc64/auxvec.h)8
-rw-r--r--include/asm-powerpc/backlight.h (renamed from include/asm-ppc/backlight.h)9
-rw-r--r--include/asm-powerpc/bug.h (renamed from include/asm-ppc64/bug.h)38
-rw-r--r--include/asm-powerpc/byteorder.h (renamed from include/asm-ppc64/byteorder.h)11
-rw-r--r--include/asm-powerpc/checksum.h (renamed from include/asm-ppc64/checksum.h)47
-rw-r--r--include/asm-powerpc/cputable.h427
-rw-r--r--include/asm-powerpc/dbdma.h (renamed from include/asm-ppc/dbdma.h)0
-rw-r--r--include/asm-powerpc/dma.h (renamed from include/asm-ppc/dma.h)91
-rw-r--r--include/asm-powerpc/elf.h (renamed from include/asm-ppc64/elf.h)96
-rw-r--r--include/asm-powerpc/firmware.h (renamed from include/asm-ppc64/firmware.h)10
-rw-r--r--include/asm-powerpc/grackle.h7
-rw-r--r--include/asm-powerpc/hardirq.h (renamed from include/asm-ppc/hardirq.h)14
-rw-r--r--include/asm-powerpc/heathrow.h (renamed from include/asm-ppc/heathrow.h)0
-rw-r--r--include/asm-powerpc/hw_irq.h (renamed from include/asm-ppc64/hw_irq.h)66
-rw-r--r--include/asm-powerpc/i8259.h12
-rw-r--r--include/asm-powerpc/iommu.h (renamed from include/asm-ppc64/iommu.h)41
-rw-r--r--include/asm-powerpc/irq.h (renamed from include/asm-ppc/irq.h)168
-rw-r--r--include/asm-powerpc/kdebug.h (renamed from include/asm-ppc64/kdebug.h)11
-rw-r--r--include/asm-powerpc/keylargo.h (renamed from include/asm-ppc/keylargo.h)0
-rw-r--r--include/asm-powerpc/kmap_types.h33
-rw-r--r--include/asm-powerpc/kprobes.h (renamed from include/asm-ppc64/kprobes.h)7
-rw-r--r--include/asm-powerpc/lmb.h (renamed from include/asm-ppc64/lmb.h)2
-rw-r--r--include/asm-powerpc/machdep.h (renamed from include/asm-ppc64/machdep.h)127
-rw-r--r--include/asm-powerpc/macio.h (renamed from include/asm-ppc/macio.h)0
-rw-r--r--include/asm-powerpc/mediabay.h (renamed from include/asm-ppc/mediabay.h)0
-rw-r--r--include/asm-powerpc/mpic.h (renamed from arch/ppc64/kernel/mpic.h)14
-rw-r--r--include/asm-powerpc/of_device.h (renamed from include/asm-ppc/of_device.h)7
-rw-r--r--include/asm-powerpc/ohare.h (renamed from include/asm-ppc/ohare.h)0
-rw-r--r--include/asm-powerpc/oprofile_impl.h (renamed from include/asm-ppc64/oprofile_impl.h)24
-rw-r--r--include/asm-powerpc/pSeries_reconfig.h (renamed from include/asm-ppc64/pSeries_reconfig.h)0
-rw-r--r--include/asm-powerpc/parport.h (renamed from include/asm-ppc/parport.h)6
-rw-r--r--include/asm-powerpc/pmac_feature.h (renamed from include/asm-ppc/pmac_feature.h)0
-rw-r--r--include/asm-powerpc/pmac_low_i2c.h (renamed from include/asm-ppc/pmac_low_i2c.h)0
-rw-r--r--include/asm-powerpc/pmc.h (renamed from include/asm-ppc64/pmc.h)21
-rw-r--r--include/asm-powerpc/posix_types.h (renamed from include/asm-ppc64/posix_types.h)40
-rw-r--r--include/asm-powerpc/ppc-pci.h (renamed from arch/ppc64/kernel/pci.h)6
-rw-r--r--include/asm-powerpc/ppc_asm.h (renamed from include/asm-ppc/ppc_asm.h)303
-rw-r--r--include/asm-powerpc/processor.h (renamed from include/asm-ppc/processor.h)190
-rw-r--r--include/asm-powerpc/prom.h219
-rw-r--r--include/asm-powerpc/reg.h (renamed from include/asm-ppc/reg.h)297
-rw-r--r--include/asm-powerpc/rtas.h (renamed from include/asm-ppc64/rtas.h)8
-rw-r--r--include/asm-powerpc/rtc.h78
-rw-r--r--include/asm-powerpc/rwsem.h (renamed from include/asm-ppc64/rwsem.h)23
-rw-r--r--include/asm-powerpc/scatterlist.h (renamed from include/asm-ppc64/scatterlist.h)24
-rw-r--r--include/asm-powerpc/seccomp.h (renamed from include/asm-ppc64/seccomp.h)11
-rw-r--r--include/asm-powerpc/sections.h (renamed from include/asm-ppc64/sections.h)21
-rw-r--r--include/asm-powerpc/semaphore.h (renamed from include/asm-ppc64/semaphore.h)9
-rw-r--r--include/asm-powerpc/smu.h (renamed from include/asm-ppc64/smu.h)0
-rw-r--r--include/asm-powerpc/spinlock_types.h (renamed from include/asm-ppc64/spinlock_types.h)4
-rw-r--r--include/asm-powerpc/sstep.h (renamed from include/asm-ppc64/sstep.h)4
-rw-r--r--include/asm-powerpc/statfs.h (renamed from include/asm-ppc64/statfs.h)19
-rw-r--r--include/asm-powerpc/synch.h51
-rw-r--r--include/asm-powerpc/system.h363
-rw-r--r--include/asm-powerpc/thread_info.h (renamed from include/asm-ppc64/thread_info.h)59
-rw-r--r--include/asm-powerpc/time.h226
-rw-r--r--include/asm-powerpc/types.h (renamed from include/asm-ppc64/types.h)37
-rw-r--r--include/asm-powerpc/uninorth.h (renamed from include/asm-ppc/uninorth.h)0
-rw-r--r--include/asm-powerpc/unistd.h (renamed from include/asm-ppc/unistd.h)92
-rw-r--r--include/asm-powerpc/vga.h (renamed from include/asm-ppc64/vga.h)20
-rw-r--r--include/asm-powerpc/vio.h (renamed from include/asm-ppc64/vio.h)22
-rw-r--r--include/asm-powerpc/xmon.h12
-rw-r--r--include/asm-ppc/a.out.h26
-rw-r--r--include/asm-ppc/auxvec.h14
-rw-r--r--include/asm-ppc/bug.h58
-rw-r--r--include/asm-ppc/byteorder.h76
-rw-r--r--include/asm-ppc/cache.h13
-rw-r--r--include/asm-ppc/checksum.h107
-rw-r--r--include/asm-ppc/cpm2.h3
-rw-r--r--include/asm-ppc/cputable.h129
-rw-r--r--include/asm-ppc/elf.h151
-rw-r--r--include/asm-ppc/hw_irq.h74
-rw-r--r--include/asm-ppc/i8259.h11
-rw-r--r--include/asm-ppc/io.h11
-rw-r--r--include/asm-ppc/kmap_types.h25
-rw-r--r--include/asm-ppc/machdep.h4
-rw-r--r--include/asm-ppc/mmu_context.h6
-rw-r--r--include/asm-ppc/mpc8260.h4
-rw-r--r--include/asm-ppc/mpc85xx.h3
-rw-r--r--include/asm-ppc/mpc8xx.h4
-rw-r--r--include/asm-ppc/open_pic.h3
-rw-r--r--include/asm-ppc/page.h18
-rw-r--r--include/asm-ppc/pci-bridge.h5
-rw-r--r--include/asm-ppc/pci.h6
-rw-r--r--include/asm-ppc/perfmon.h22
-rw-r--r--include/asm-ppc/pgtable.h2
-rw-r--r--include/asm-ppc/posix_types.h111
-rw-r--r--include/asm-ppc/ptrace.h2
-rw-r--r--include/asm-ppc/rwsem.h172
-rw-r--r--include/asm-ppc/scatterlist.h25
-rw-r--r--include/asm-ppc/seccomp.h10
-rw-r--r--include/asm-ppc/sections.h33
-rw-r--r--include/asm-ppc/semaphore.h111
-rw-r--r--include/asm-ppc/smp.h28
-rw-r--r--include/asm-ppc/spinlock.h8
-rw-r--r--include/asm-ppc/spinlock_types.h20
-rw-r--r--include/asm-ppc/statfs.h8
-rw-r--r--include/asm-ppc/system.h28
-rw-r--r--include/asm-ppc/thread_info.h107
-rw-r--r--include/asm-ppc/types.h69
-rw-r--r--include/asm-ppc/vga.h46
-rw-r--r--include/asm-ppc/xmon.h17
-rw-r--r--include/asm-ppc64/abs_addr.h7
-rw-r--r--include/asm-ppc64/atomic.h197
-rw-r--r--include/asm-ppc64/bitops.h2
-rw-r--r--include/asm-ppc64/bootinfo.h70
-rw-r--r--include/asm-ppc64/btext.h1
-rw-r--r--include/asm-ppc64/cputable.h167
-rw-r--r--include/asm-ppc64/dart.h59
-rw-r--r--include/asm-ppc64/dbdma.h2
-rw-r--r--include/asm-ppc64/dma.h329
-rw-r--r--include/asm-ppc64/futex.h2
-rw-r--r--include/asm-ppc64/hardirq.h27
-rw-r--r--include/asm-ppc64/io.h2
-rw-r--r--include/asm-ppc64/irq.h120
-rw-r--r--include/asm-ppc64/keylargo.h2
-rw-r--r--include/asm-ppc64/kmap_types.h23
-rw-r--r--include/asm-ppc64/macio.h2
-rw-r--r--include/asm-ppc64/memory.h61
-rw-r--r--include/asm-ppc64/mmu.h7
-rw-r--r--include/asm-ppc64/mmzone.h3
-rw-r--r--include/asm-ppc64/of_device.h2
-rw-r--r--include/asm-ppc64/page.h8
-rw-r--r--include/asm-ppc64/parport.h18
-rw-r--r--include/asm-ppc64/pci-bridge.h22
-rw-r--r--include/asm-ppc64/pci.h2
-rw-r--r--include/asm-ppc64/pgtable.h6
-rw-r--r--include/asm-ppc64/pmac_feature.h2
-rw-r--r--include/asm-ppc64/pmac_low_i2c.h2
-rw-r--r--include/asm-ppc64/ppc32.h14
-rw-r--r--include/asm-ppc64/ppc_asm.h242
-rw-r--r--include/asm-ppc64/processor.h558
-rw-r--r--include/asm-ppc64/prom.h4
-rw-r--r--include/asm-ppc64/smp.h1
-rw-r--r--include/asm-ppc64/system.h20
-rw-r--r--include/asm-ppc64/tce.h64
-rw-r--r--include/asm-ppc64/time.h124
-rw-r--r--include/asm-ppc64/tlbflush.h7
-rw-r--r--include/asm-ppc64/udbg.h3
-rw-r--r--include/asm-ppc64/uninorth.h2
-rw-r--r--include/asm-ppc64/unistd.h487
-rw-r--r--include/asm-s390/rwsem.h5
-rw-r--r--include/asm-s390/semaphore.h3
-rw-r--r--include/asm-s390/setup.h50
-rw-r--r--include/asm-s390/unistd.h1
-rw-r--r--include/asm-sh/pgtable.h2
-rw-r--r--include/asm-sh/rwsem.h5
-rw-r--r--include/asm-sh/semaphore.h3
-rw-r--r--include/asm-sh/unistd.h1
-rw-r--r--include/asm-sh64/pgtable.h3
-rw-r--r--include/asm-sh64/semaphore.h3
-rw-r--r--include/asm-sparc/floppy.h2
-rw-r--r--include/asm-sparc/pgtable.h2
-rw-r--r--include/asm-sparc/semaphore.h3
-rw-r--r--include/asm-sparc64/pgtable.h3
-rw-r--r--include/asm-sparc64/rwsem.h5
-rw-r--r--include/asm-sparc64/semaphore.h3
-rw-r--r--include/asm-sparc64/tlb.h29
-rw-r--r--include/asm-um/cache.h19
-rw-r--r--include/asm-um/linkage.h8
-rw-r--r--include/asm-um/pgtable.h2
-rw-r--r--include/asm-v850/semaphore.h3
-rw-r--r--include/asm-v850/unistd.h1
-rw-r--r--include/asm-x86_64/mtrr.h33
-rw-r--r--include/asm-x86_64/pgtable.h2
-rw-r--r--include/asm-x86_64/rwsem.h5
-rw-r--r--include/asm-x86_64/semaphore.h3
-rw-r--r--include/asm-x86_64/unistd.h2
-rw-r--r--include/asm-xtensa/semaphore.h3
-rw-r--r--include/keys/user-type.h47
-rw-r--r--include/linux/bitmap.h6
-rw-r--r--include/linux/buffer_head.h7
-rw-r--r--include/linux/cpu.h1
-rw-r--r--include/linux/cpufreq.h1
-rw-r--r--include/linux/cpumask.h20
-rw-r--r--include/linux/dmi.h2
-rw-r--r--include/linux/etherdevice.h16
-rw-r--r--include/linux/fs.h10
-rw-r--r--include/linux/fs_enet_pd.h136
-rw-r--r--include/linux/fsl_devices.h13
-rw-r--r--include/linux/fuse.h1
-rw-r--r--include/linux/gameport.h1
-rw-r--r--include/linux/hugetlb.h2
-rw-r--r--include/linux/i2c.h1
-rw-r--r--include/linux/i2o.h8
-rw-r--r--include/linux/ide.h2
-rw-r--r--include/linux/kernel.h2
-rw-r--r--include/linux/key-ui.h3
-rw-r--r--include/linux/key.h13
-rw-r--r--include/linux/kobj_map.h2
-rw-r--r--include/linux/kthread.h12
-rw-r--r--include/linux/libata.h30
-rw-r--r--include/linux/memory.h94
-rw-r--r--include/linux/memory_hotplug.h104
-rw-r--r--include/linux/mempolicy.h13
-rw-r--r--include/linux/mm.h150
-rw-r--r--include/linux/mmzone.h28
-rw-r--r--include/linux/module.h4
-rw-r--r--include/linux/msdos_fs.h11
-rw-r--r--include/linux/mtd/map.h3
-rw-r--r--include/linux/nodemask.h20
-rw-r--r--include/linux/pci_ids.h2
-rw-r--r--include/linux/pm.h1
-rw-r--r--include/linux/rcupdate.h1
-rw-r--r--include/linux/rmap.h4
-rw-r--r--include/linux/rwsem-spinlock.h5
-rw-r--r--include/linux/scatterlist.h17
-rw-r--r--include/linux/sched.h74
-rw-r--r--include/linux/security.h84
-rw-r--r--include/linux/serial.h1
-rw-r--r--include/linux/serial_core.h3
-rw-r--r--include/linux/serial_ip3106.h81
-rw-r--r--include/linux/signal.h1
-rw-r--r--include/linux/spinlock.h31
-rw-r--r--include/linux/suspend.h9
-rw-r--r--include/linux/syscalls.h1
-rw-r--r--include/linux/textsearch.h1
-rw-r--r--include/linux/timer.h17
-rw-r--r--include/linux/timex.h7
-rw-r--r--include/linux/vmalloc.h8
-rw-r--r--include/linux/zutil.h1
-rw-r--r--include/net/ax25.h3
-rw-r--r--include/net/netrom.h3
-rw-r--r--include/pcmcia/ss.h1
-rw-r--r--include/scsi/scsi.h3
-rw-r--r--include/scsi/scsi_cmnd.h1
-rw-r--r--include/scsi/scsi_transport_fc.h1
-rw-r--r--init/Kconfig4
-rw-r--r--init/main.c11
-rw-r--r--ipc/shm.c7
-rw-r--r--kernel/Makefile2
-rw-r--r--kernel/acct.c2
-rw-r--r--kernel/cpu.c1
-rw-r--r--kernel/cpuset.c466
-rw-r--r--kernel/exit.c34
-rw-r--r--kernel/fork.c31
-rw-r--r--kernel/futex.c6
-rw-r--r--kernel/irq/handle.c6
-rw-r--r--kernel/kallsyms.c1
-rw-r--r--kernel/kexec.c4
-rw-r--r--kernel/kmod.c6
-rw-r--r--kernel/kprobes.c1
-rw-r--r--kernel/kthread.c13
-rw-r--r--kernel/params.c1
-rw-r--r--kernel/posix-cpu-timers.c16
-rw-r--r--kernel/posix-timers.c19
-rw-r--r--kernel/power/Makefile2
-rw-r--r--kernel/power/disk.c22
-rw-r--r--kernel/power/main.c5
-rw-r--r--kernel/power/power.h17
-rw-r--r--kernel/power/snapshot.c435
-rw-r--r--kernel/power/swsusp.c569
-rw-r--r--kernel/printk.c78
-rw-r--r--kernel/ptrace.c7
-rw-r--r--kernel/rcupdate.c10
-rw-r--r--kernel/rcutorture.c492
-rw-r--r--kernel/sched.c3
-rw-r--r--kernel/signal.c150
-rw-r--r--kernel/time.c26
-rw-r--r--kernel/timer.c337
-rw-r--r--kernel/workqueue.c33
-rw-r--r--lib/Kconfig.debug27
-rw-r--r--lib/bitmap.c166
-rw-r--r--lib/extable.c3
-rw-r--r--lib/idr.c35
-rw-r--r--lib/kobject.c1
-rw-r--r--lib/smp_processor_id.c1
-rw-r--r--lib/sort.c1
-rw-r--r--lib/string.c125
-rw-r--r--lib/vsprintf.c1
-rw-r--r--lib/zlib_inflate/inflate.c1
-rw-r--r--mm/Kconfig21
-rw-r--r--mm/Makefile2
-rw-r--r--mm/bootmem.c1
-rw-r--r--mm/filemap.c16
-rw-r--r--mm/filemap_xip.c22
-rw-r--r--mm/fremap.c86
-rw-r--r--mm/hugetlb.c207
-rw-r--r--mm/madvise.c2
-rw-r--r--mm/memory.c993
-rw-r--r--mm/memory_hotplug.c138
-rw-r--r--mm/mempolicy.c457
-rw-r--r--mm/mmap.c128
-rw-r--r--mm/mprotect.c19
-rw-r--r--mm/mremap.c193
-rw-r--r--mm/msync.c78
-rw-r--r--mm/nommu.c18
-rw-r--r--mm/page_alloc.c207
-rw-r--r--mm/page_io.c6
-rw-r--r--mm/pdflush.c13
-rw-r--r--mm/rmap.c146
-rw-r--r--mm/shmem.c28
-rw-r--r--mm/slab.c5
-rw-r--r--mm/sparse.c99
-rw-r--r--mm/swap.c7
-rw-r--r--mm/swap_state.c11
-rw-r--r--mm/swapfile.c41
-rw-r--r--mm/thrash.c2
-rw-r--r--mm/tiny-shmem.c5
-rw-r--r--mm/truncate.c11
-rw-r--r--mm/vmalloc.c77
-rw-r--r--mm/vmscan.c6
-rw-r--r--net/bluetooth/hidp/Kconfig2
-rw-r--r--net/ethernet/eth.c17
-rw-r--r--net/ipv4/fib_frontend.c2
-rw-r--r--net/ipv4/netfilter/ipt_addrtype.c2
-rw-r--r--net/ipv6/addrconf.c10
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_crypto.c23
-rw-r--r--scripts/kconfig/Makefile9
-rw-r--r--scripts/kconfig/lkc.h8
-rw-r--r--scripts/kconfig/mconf.c3
-rw-r--r--security/dummy.c25
-rw-r--r--security/keys/key.c56
-rw-r--r--security/keys/keyctl.c13
-rw-r--r--security/keys/keyring.c21
-rw-r--r--security/keys/permission.c7
-rw-r--r--security/keys/process_keys.c9
-rw-r--r--security/keys/user_defined.c49
-rw-r--r--security/selinux/hooks.c78
-rw-r--r--security/selinux/netif.c3
-rw-r--r--security/selinux/selinuxfs.c50
-rw-r--r--security/selinux/ss/conditional.c12
-rw-r--r--security/selinux/ss/ebitmap.c9
-rw-r--r--security/selinux/ss/hashtab.c6
-rw-r--r--security/selinux/ss/policydb.c51
-rw-r--r--security/selinux/ss/services.c11
-rw-r--r--sound/core/pcm_native.c9
-rw-r--r--sound/oss/ac97_codec.c1
-rw-r--r--sound/oss/au1550_ac97.c1
-rw-r--r--sound/oss/awe_wave.c2
-rw-r--r--sound/oss/cs4232.c6
-rw-r--r--sound/oss/wavfront.c38
1909 files changed, 118753 insertions, 46248 deletions
diff --git a/Documentation/RCU/torture.txt b/Documentation/RCU/torture.txt
new file mode 100644
index 000000000000..e4c38152f7f7
--- /dev/null
+++ b/Documentation/RCU/torture.txt
@@ -0,0 +1,122 @@
+RCU Torture Test Operation
+
+
+CONFIG_RCU_TORTURE_TEST
+
+The CONFIG_RCU_TORTURE_TEST config option is available for all RCU
+implementations. It creates an rcutorture kernel module that can
+be loaded to run a torture test. The test periodically outputs
+status messages via printk(), which can be examined via the dmesg
+command (perhaps grepping for "rcutorture"). The test is started
+when the module is loaded, and stops when the module is unloaded.
+
+However, actually setting this config option to "y" results in the system
+running the test immediately upon boot, and ending only when the system
+is taken down. Normally, one will instead want to build the system
+with CONFIG_RCU_TORTURE_TEST=m and to use modprobe and rmmod to control
+the test, perhaps using a script similar to the one shown at the end of
+this document. Note that you will need CONFIG_MODULE_UNLOAD in order
+to be able to end the test.
+
+
+MODULE PARAMETERS
+
+This module has the following parameters:
+
+nreaders This is the number of RCU reading threads supported.
+ The default is twice the number of CPUs. Why twice?
+ To properly exercise RCU implementations with preemptible
+ read-side critical sections.
+
+stat_interval The number of seconds between output of torture
+ statistics (via printk()). Regardless of the interval,
+ statistics are printed when the module is unloaded.
+ Setting the interval to zero causes the statistics to
+ be printed -only- when the module is unloaded, and this
+ is the default.
+
+verbose Enable debug printk()s. Default is disabled.
+
+
+OUTPUT
+
+The statistics output is as follows:
+
+ rcutorture: --- Start of test: nreaders=16 stat_interval=0 verbose=0
+ rcutorture: rtc: 0000000000000000 ver: 1916 tfle: 0 rta: 1916 rtaf: 0 rtf: 1915
+ rcutorture: Reader Pipe: 1466408 9747 0 0 0 0 0 0 0 0 0
+ rcutorture: Reader Batch: 1464477 11678 0 0 0 0 0 0 0 0
+ rcutorture: Free-Block Circulation: 1915 1915 1915 1915 1915 1915 1915 1915 1915 1915 0
+ rcutorture: --- End of test
+
+The command "dmesg | grep rcutorture:" will extract this information on
+most systems. On more esoteric configurations, it may be necessary to
+use other commands to access the output of the printk()s used by
+the RCU torture test. The printk()s use KERN_ALERT, so they should
+be evident. ;-)
+
+The entries are as follows:
+
+o "ggp": The number of counter flips (or batches) since boot.
+
+o "rtc": The hexadecimal address of the structure currently visible
+ to readers.
+
+o "ver": The number of times since boot that the rcutw writer task
+ has changed the structure visible to readers.
+
+o "tfle": If non-zero, indicates that the "torture freelist"
+ containing structure to be placed into the "rtc" area is empty.
+ This condition is important, since it can fool you into thinking
+ that RCU is working when it is not. :-/
+
+o "rta": Number of structures allocated from the torture freelist.
+
+o "rtaf": Number of allocations from the torture freelist that have
+ failed due to the list being empty.
+
+o "rtf": Number of frees into the torture freelist.
+
+o "Reader Pipe": Histogram of "ages" of structures seen by readers.
+ If any entries past the first two are non-zero, RCU is broken.
+ And rcutorture prints the error flag string "!!!" to make sure
+ you notice. The age of a newly allocated structure is zero,
+ it becomes one when removed from reader visibility, and is
+ incremented once per grace period subsequently -- and is freed
+ after passing through (RCU_TORTURE_PIPE_LEN-2) grace periods.
+
+ The output displayed above was taken from a correctly working
+ RCU. If you want to see what it looks like when broken, break
+ it yourself. ;-)
+
+o "Reader Batch": Another histogram of "ages" of structures seen
+ by readers, but in terms of counter flips (or batches) rather
+ than in terms of grace periods. The legal number of non-zero
+ entries is again two. The reason for this separate view is
+ that it is easier to get the third entry to show up in the
+ "Reader Batch" list than in the "Reader Pipe" list.
+
+o "Free-Block Circulation": Shows the number of torture structures
+ that have reached a given point in the pipeline. The first element
+ should closely correspond to the number of structures allocated,
+ the second to the number that have been removed from reader view,
+ and all but the last remaining to the corresponding number of
+ passes through a grace period. The last entry should be zero,
+ as it is only incremented if a torture structure's counter
+ somehow gets incremented farther than it should.
+
+
+USAGE
+
+The following script may be used to torture RCU:
+
+ #!/bin/sh
+
+ modprobe rcutorture
+ sleep 100
+ rmmod rcutorture
+ dmesg | grep rcutorture:
+
+The output can be manually inspected for the error flag of "!!!".
+One could of course create a more elaborate script that automatically
+checked for such errors.
diff --git a/Documentation/cachetlb.txt b/Documentation/cachetlb.txt
index e132fb1163b0..7eb715e07eda 100644
--- a/Documentation/cachetlb.txt
+++ b/Documentation/cachetlb.txt
@@ -49,9 +49,6 @@ changes occur:
page table operations such as what happens during
fork, and exec.
- Platform developers note that generic code will always
- invoke this interface without mm->page_table_lock held.
-
3) void flush_tlb_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
@@ -72,9 +69,6 @@ changes occur:
call flush_tlb_page (see below) for each entry which may be
modified.
- Platform developers note that generic code will always
- invoke this interface with mm->page_table_lock held.
-
4) void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
This time we need to remove the PAGE_SIZE sized translation
@@ -93,9 +87,6 @@ changes occur:
This is used primarily during fault processing.
- Platform developers note that generic code will always
- invoke this interface with mm->page_table_lock held.
-
5) void flush_tlb_pgtables(struct mm_struct *mm,
unsigned long start, unsigned long end)
diff --git a/Documentation/cpusets.txt b/Documentation/cpusets.txt
index d17b7d2dd771..a09a8eb80665 100644
--- a/Documentation/cpusets.txt
+++ b/Documentation/cpusets.txt
@@ -94,7 +94,7 @@ the available CPU and Memory resources amongst the requesting tasks.
But larger systems, which benefit more from careful processor and
memory placement to reduce memory access times and contention,
and which typically represent a larger investment for the customer,
-can benefit from explictly placing jobs on properly sized subsets of
+can benefit from explicitly placing jobs on properly sized subsets of
the system.
This can be especially valuable on:
diff --git a/Documentation/firmware_class/firmware_sample_driver.c b/Documentation/firmware_class/firmware_sample_driver.c
index 4bef8c25172c..d3ad2c24490a 100644
--- a/Documentation/firmware_class/firmware_sample_driver.c
+++ b/Documentation/firmware_class/firmware_sample_driver.c
@@ -13,6 +13,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/device.h>
+#include <linux/string.h>
#include "linux/firmware.h"
diff --git a/Documentation/firmware_class/firmware_sample_firmware_class.c b/Documentation/firmware_class/firmware_sample_firmware_class.c
index 09eab2f1b373..57b956aecbc5 100644
--- a/Documentation/firmware_class/firmware_sample_firmware_class.c
+++ b/Documentation/firmware_class/firmware_sample_firmware_class.c
@@ -14,6 +14,8 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/timer.h>
+#include <linux/slab.h>
+#include <linux/string.h>
#include <linux/firmware.h>
diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients
index e94d9c6cc522..cff7b652588a 100644
--- a/Documentation/i2c/writing-clients
+++ b/Documentation/i2c/writing-clients
@@ -273,6 +273,7 @@ For now, you can ignore the `flags' parameter. It is there for future use.
if (is_isa) {
/* Discard immediately if this ISA range is already used */
+ /* FIXME: never use check_region(), only request_region() */
if (check_region(address,FOO_EXTENT))
goto ERROR0;
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 90766b75d1b7..5dffcfefc3c7 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1460,8 +1460,6 @@ running once the system is up.
stifb= [HW]
Format: bpp:<bpp1>[:<bpp2>[:<bpp3>...]]
- stram_swap= [HW,M68k]
-
swiotlb= [IA-64] Number of I/O TLB slabs
switches= [HW,M68k]
diff --git a/Documentation/keys.txt b/Documentation/keys.txt
index 4afe03a58c5b..31154882000a 100644
--- a/Documentation/keys.txt
+++ b/Documentation/keys.txt
@@ -196,7 +196,7 @@ KEY ACCESS PERMISSIONS
Keys have an owner user ID, a group access ID, and a permissions mask. The mask
has up to eight bits each for possessor, user, group and other access. Only
-five of each set of eight bits are defined. These permissions granted are:
+six of each set of eight bits are defined. These permissions granted are:
(*) View
@@ -224,6 +224,10 @@ five of each set of eight bits are defined. These permissions granted are:
keyring to a key, a process must have Write permission on the keyring and
Link permission on the key.
+ (*) Set Attribute
+
+ This permits a key's UID, GID and permissions mask to be changed.
+
For changing the ownership, group ID or permissions mask, being the owner of
the key or having the sysadmin capability is sufficient.
@@ -242,15 +246,15 @@ about the status of the key service:
this way:
SERIAL FLAGS USAGE EXPY PERM UID GID TYPE DESCRIPTION: SUMMARY
- 00000001 I----- 39 perm 1f1f0000 0 0 keyring _uid_ses.0: 1/4
- 00000002 I----- 2 perm 1f1f0000 0 0 keyring _uid.0: empty
- 00000007 I----- 1 perm 1f1f0000 0 0 keyring _pid.1: empty
- 0000018d I----- 1 perm 1f1f0000 0 0 keyring _pid.412: empty
- 000004d2 I--Q-- 1 perm 1f1f0000 32 -1 keyring _uid.32: 1/4
- 000004d3 I--Q-- 3 perm 1f1f0000 32 -1 keyring _uid_ses.32: empty
+ 00000001 I----- 39 perm 1f3f0000 0 0 keyring _uid_ses.0: 1/4
+ 00000002 I----- 2 perm 1f3f0000 0 0 keyring _uid.0: empty
+ 00000007 I----- 1 perm 1f3f0000 0 0 keyring _pid.1: empty
+ 0000018d I----- 1 perm 1f3f0000 0 0 keyring _pid.412: empty
+ 000004d2 I--Q-- 1 perm 1f3f0000 32 -1 keyring _uid.32: 1/4
+ 000004d3 I--Q-- 3 perm 1f3f0000 32 -1 keyring _uid_ses.32: empty
00000892 I--QU- 1 perm 1f000000 0 0 user metal:copper: 0
- 00000893 I--Q-N 1 35s 1f1f0000 0 0 user metal:silver: 0
- 00000894 I--Q-- 1 10h 001f0000 0 0 user metal:gold: 0
+ 00000893 I--Q-N 1 35s 1f3f0000 0 0 user metal:silver: 0
+ 00000894 I--Q-- 1 10h 003f0000 0 0 user metal:gold: 0
The flags are:
diff --git a/Documentation/m68k/kernel-options.txt b/Documentation/m68k/kernel-options.txt
index e191baad8308..d5d3f064f552 100644
--- a/Documentation/m68k/kernel-options.txt
+++ b/Documentation/m68k/kernel-options.txt
@@ -626,7 +626,7 @@ ignored (others aren't affected).
can be performed in optimal order. Not all SCSI devices support
tagged queuing (:-().
-4.6 switches=
+4.5 switches=
-------------
Syntax: switches=<list of switches>
@@ -661,28 +661,6 @@ correctly.
earlier initialization ("ov_"-less) takes precedence. But the
switching-off on reset still happens in this case.
-4.5) stram_swap=
-----------------
-
-Syntax: stram_swap=<do_swap>[,<max_swap>]
-
- This option is available only if the kernel has been compiled with
-CONFIG_STRAM_SWAP enabled. Normally, the kernel then determines
-dynamically whether to actually use ST-RAM as swap space. (Currently,
-the fraction of ST-RAM must be less or equal 1/3 of total memory to
-enable this swapping.) You can override the kernel's decision by
-specifying this option. 1 for <do_swap> means always enable the swap,
-even if you have less alternate RAM. 0 stands for never swap to
-ST-RAM, even if it's small enough compared to the rest of memory.
-
- If ST-RAM swapping is enabled, the kernel usually uses all free
-ST-RAM as swap "device". If the kernel resides in ST-RAM, the region
-allocated by it is obviously never used for swapping :-) You can also
-limit this amount by specifying the second parameter, <max_swap>, if
-you want to use parts of ST-RAM as normal system memory. <max_swap> is
-in kBytes and the number should be a multiple of 4 (otherwise: rounded
-down).
-
5) Options for Amiga Only:
==========================
diff --git a/Documentation/mips/AU1xxx_IDE.README b/Documentation/mips/AU1xxx_IDE.README
new file mode 100644
index 000000000000..a7e4c4ea3560
--- /dev/null
+++ b/Documentation/mips/AU1xxx_IDE.README
@@ -0,0 +1,168 @@
+README for MIPS AU1XXX IDE driver - Released 2005-07-15
+
+ABOUT
+-----
+This file describes the 'drivers/ide/mips/au1xxx-ide.c', related files and the
+services they provide.
+
+If you are short in patience and just want to know how to add your hard disc to
+the white or black list, go to the 'ADD NEW HARD DISC TO WHITE OR BLACK LIST'
+section.
+
+
+LICENSE
+-------
+
+Copyright (c) 2003-2005 AMD, Personal Connectivity Solutions
+
+This program is free software; you can redistribute 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.
+
+Note: for more information, please refer "AMD Alchemy Au1200/Au1550 IDE
+ Interface and Linux Device Driver" Application Note.
+
+
+FILES, CONFIGS AND COMPATABILITY
+--------------------------------
+
+Two files are introduced:
+
+ a) 'include/asm-mips/mach-au1x00/au1xxx_ide.h'
+ containes : struct _auide_hwif
+ struct drive_list_entry dma_white_list
+ struct drive_list_entry dma_black_list
+ timing parameters for PIO mode 0/1/2/3/4
+ timing parameters for MWDMA 0/1/2
+
+ b) 'drivers/ide/mips/au1xxx-ide.c'
+ contains the functionality of the AU1XXX IDE driver
+
+Four configs variables are introduced:
+
+ CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA - enable the PIO+DBDMA mode
+ CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA - enable the MWDMA mode
+ CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON - set Burstable FIFO in DBDMA
+ controler
+ CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ - maximum transfer size
+ per descriptor
+
+If MWDMA is enabled and the connected hard disc is not on the white list, the
+kernel switches to a "safe mwdma mode" at boot time. In this mode the IDE
+performance is substantial slower then in full speed mwdma. In this case
+please add your hard disc to the white list (follow instruction from 'ADD NEW
+HARD DISC TO WHITE OR BLACK LIST' section).
+
+
+SUPPORTED IDE MODES
+-------------------
+
+The AU1XXX IDE driver supported all PIO modes - PIO mode 0/1/2/3/4 - and all
+MWDMA modes - MWDMA 0/1/2 -. There is no support for SWDMA and UDMA mode.
+
+To change the PIO mode use the program hdparm with option -p, e.g.
+'hdparm -p0 [device]' for PIO mode 0. To enable the MWDMA mode use the option
+-X, e.g. 'hdparm -X32 [device]' for MWDMA mode 0.
+
+
+PERFORMANCE CONFIGURATIONS
+--------------------------
+
+If the used system doesn't need USB support enable the following kernel configs:
+
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_BLK_DEV_GENERIC=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+CONFIG_IDEDMA_PCI_AUTO=y
+CONFIG_BLK_DEV_IDE_AU1XXX=y
+CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA=y
+CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON=y
+CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ=128
+CONFIG_BLK_DEV_IDEDMA=y
+CONFIG_IDEDMA_AUTO=y
+
+If the used system need the USB support enable the following kernel configs for
+high IDE to USB throughput.
+
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_BLK_DEV_GENERIC=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+CONFIG_IDEDMA_PCI_AUTO=y
+CONFIG_BLK_DEV_IDE_AU1XXX=y
+CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA=y
+CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ=128
+CONFIG_BLK_DEV_IDEDMA=y
+CONFIG_IDEDMA_AUTO=y
+
+
+ADD NEW HARD DISC TO WHITE OR BLACK LIST
+----------------------------------------
+
+Step 1 : detect the model name of your hard disc
+
+ a) connect your hard disc to the AU1XXX
+
+ b) boot your kernel and get the hard disc model.
+
+ Example boot log:
+
+ --snipped--
+ Uniform Multi-Platform E-IDE driver Revision: 7.00alpha2
+ ide: Assuming 50MHz system bus speed for PIO modes; override with idebus=xx
+ Au1xxx IDE(builtin) configured for MWDMA2
+ Probing IDE interface ide0...
+ hda: Maxtor 6E040L0, ATA DISK drive
+ ide0 at 0xac800000-0xac800007,0xac8001c0 on irq 64
+ hda: max request size: 64KiB
+ hda: 80293248 sectors (41110 MB) w/2048KiB Cache, CHS=65535/16/63, (U)DMA
+ --snipped--
+
+ In this example 'Maxtor 6E040L0'.
+
+Step 2 : edit 'include/asm-mips/mach-au1x00/au1xxx_ide.h'
+
+ Add your hard disc to the dma_white_list or dma_black_list structur.
+
+Step 3 : Recompile the kernel
+
+ Enable MWDMA support in the kernel configuration. Recompile the kernel and
+ reboot.
+
+Step 4 : Tests
+
+ If you have add a hard disc to the white list, please run some stress tests
+ for verification.
+
+
+ACKNOWLEDGMENTS
+---------------
+
+These drivers wouldn't have been done without the base of kernel 2.4.x AU1XXX
+IDE driver from AMD.
+
+Additional input also from:
+Matthias Lenk <matthias.lenk@amd.com>
+
+Happy hacking!
+Enrico Walther <enrico.walther@amd.com>
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index b433c8a27e2d..65895bb51414 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -309,7 +309,7 @@ tcp_tso_win_divisor - INTEGER
can be consumed by a single TSO frame.
The setting of this parameter is a choice between burstiness and
building larger TSO frames.
- Default: 8
+ Default: 3
tcp_frto - BOOLEAN
Enables F-RTO, an enhanced recovery algorithm for TCP retransmission
diff --git a/MAINTAINERS b/MAINTAINERS
index 770155a01523..983f9e9aed61 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1643,7 +1643,7 @@ S: Maintained
MIPS
P: Ralf Baechle
M: ralf@linux-mips.org
-W: http://oss.sgi.com/mips/mips-howto.html
+W: http://www.linux-mips.org/
L: linux-mips@linux-mips.org
S: Maintained
@@ -1945,6 +1945,14 @@ M: george@mvista.com
L: netdev@vger.kernel.org
S: Supported
+POWERPC 4xx EMAC DRIVER
+P: Eugene Surovegin
+M: ebs@ebshome.net
+W: http://kernel.ebshome.net/emac/
+L: linuxppc-embedded@ozlabs.org
+L: netdev@vger.kernel.org
+S: Maintained
+
PNP SUPPORT
P: Adam Belay
M: ambx1@neo.rr.com
@@ -2278,6 +2286,11 @@ W: http://tpmdd.sourceforge.net
L: tpmdd-devel@lists.sourceforge.net
S: Maintained
+Telecom Clock Driver for MCPL0010
+P: Mark Gross
+M: mark.gross@intel.com
+S: Supported
+
TENSILICA XTENSA PORT (xtensa):
P: Chris Zankel
M: chris@zankel.net
diff --git a/README b/README
index d1edcc7adabe..4ee7dda88ba3 100644
--- a/README
+++ b/README
@@ -54,6 +54,10 @@ INSTALLING the kernel:
gzip -cd linux-2.6.XX.tar.gz | tar xvf -
+ or
+ bzip2 -dc linux-2.6.XX.tar.bz2 | tar xvf -
+
+
Replace "XX" with the version number of the latest kernel.
Do NOT use the /usr/src/linux area! This area has a (usually
diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c
index 67be50b7d80a..6b2921be1909 100644
--- a/arch/alpha/kernel/time.c
+++ b/arch/alpha/kernel/time.c
@@ -55,10 +55,6 @@
#include "proto.h"
#include "irq_impl.h"
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
extern unsigned long wall_jiffies; /* kernel/timer.c */
static int set_rtc_mmss(unsigned long);
diff --git a/arch/alpha/mm/numa.c b/arch/alpha/mm/numa.c
index c7481d59b6df..6d5251254f68 100644
--- a/arch/alpha/mm/numa.c
+++ b/arch/alpha/mm/numa.c
@@ -371,6 +371,8 @@ show_mem(void)
show_free_areas();
printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
for_each_online_node(nid) {
+ unsigned long flags;
+ pgdat_resize_lock(NODE_DATA(nid), &flags);
i = node_spanned_pages(nid);
while (i-- > 0) {
struct page *page = nid_page_nr(nid, i);
@@ -384,6 +386,7 @@ show_mem(void)
else
shared += page_count(page) - 1;
}
+ pgdat_resize_unlock(NODE_DATA(nid), &flags);
}
printk("%ld pages of RAM\n",total);
printk("%ld free pages\n",free);
diff --git a/arch/alpha/mm/remap.c b/arch/alpha/mm/remap.c
index 19817ad3d89b..a78356c3ead5 100644
--- a/arch/alpha/mm/remap.c
+++ b/arch/alpha/mm/remap.c
@@ -2,7 +2,6 @@
#include <asm/pgalloc.h>
#include <asm/cacheflush.h>
-/* called with the page_table_lock held */
static inline void
remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
unsigned long phys_addr, unsigned long flags)
@@ -31,7 +30,6 @@ remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
} while (address && (address < end));
}
-/* called with the page_table_lock held */
static inline int
remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
unsigned long phys_addr, unsigned long flags)
@@ -46,7 +44,7 @@ remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
if (address >= end)
BUG();
do {
- pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
+ pte_t * pte = pte_alloc_kernel(pmd, address);
if (!pte)
return -ENOMEM;
remap_area_pte(pte, address, end - address,
@@ -70,7 +68,6 @@ __alpha_remap_area_pages(unsigned long address, unsigned long phys_addr,
flush_cache_all();
if (address >= end)
BUG();
- spin_lock(&init_mm.page_table_lock);
do {
pmd_t *pmd;
pmd = pmd_alloc(&init_mm, dir, address);
@@ -84,7 +81,6 @@ __alpha_remap_area_pages(unsigned long address, unsigned long phys_addr,
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
} while (address && (address < end));
- spin_unlock(&init_mm.page_table_lock);
return error;
}
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 299bc0468702..64cf480b0b02 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -8,7 +8,7 @@
# Copyright (C) 1995-2001 by Russell King
LDFLAGS_vmlinux :=-p --no-undefined -X
-CPPFLAGS_vmlinux.lds = -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR)
+CPPFLAGS_vmlinux.lds = -DKERNEL_RAM_ADDR=$(TEXTADDR)
OBJCOPYFLAGS :=-O binary -R .note -R .comment -S
GZFLAGS :=-9
#CFLAGS +=-pipe
@@ -108,27 +108,19 @@ export CFLAGS_3c589_cs.o
endif
TEXTADDR := $(textaddr-y)
-ifeq ($(CONFIG_XIP_KERNEL),y)
- DATAADDR := $(TEXTADDR)
- xipaddr-$(CONFIG_ARCH_CO285) := 0x5f000000
- xipaddr-y ?= 0xbf000000
- # Replace phys addr with virt addr while keeping offset from base.
- TEXTADDR := $(shell echo $(CONFIG_XIP_PHYS_ADDR) $(xipaddr-y) | \
- awk --non-decimal-data '/[:xdigit:]/ \
- { printf("0x%x\n", and($$1, 0x000fffff) + $$2) }' )
-endif
ifeq ($(incdir-y),)
incdir-y := $(machine-y)
endif
INCDIR := arch-$(incdir-y)
+
ifneq ($(machine-y),)
MACHINE := arch/arm/mach-$(machine-y)/
else
MACHINE :=
endif
-export TEXTADDR DATAADDR GZFLAGS
+export TEXTADDR GZFLAGS
# Do we have FASTFPE?
FASTFPE :=arch/arm/fastfpe
diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c
index 23434b56786a..50f13eec6cd7 100644
--- a/arch/arm/boot/compressed/misc.c
+++ b/arch/arm/boot/compressed/misc.c
@@ -30,7 +30,7 @@ unsigned int __machine_arch_type;
#define putstr icedcc_putstr
#define putc icedcc_putc
-extern void idedcc_putc(int ch);
+extern void icedcc_putc(int ch);
static void
icedcc_putstr(const char *ptr)
diff --git a/arch/arm/common/amba.c b/arch/arm/common/amba.c
index c6beb751f2a9..e1013112c354 100644
--- a/arch/arm/common/amba.c
+++ b/arch/arm/common/amba.c
@@ -10,6 +10,8 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/irq.h>
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index cbf2165476b0..ad6c89a555bb 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -33,8 +33,8 @@
#include <asm/cacheflush.h>
#undef DEBUG
-
#undef STATS
+
#ifdef STATS
#define DO_STATS(X) do { X ; } while (0)
#else
@@ -52,26 +52,31 @@ struct safe_buffer {
int direction;
/* safe buffer info */
- struct dma_pool *pool;
+ struct dmabounce_pool *pool;
void *safe;
dma_addr_t safe_dma_addr;
};
+struct dmabounce_pool {
+ unsigned long size;
+ struct dma_pool *pool;
+#ifdef STATS
+ unsigned long allocs;
+#endif
+};
+
struct dmabounce_device_info {
struct list_head node;
struct device *dev;
- struct dma_pool *small_buffer_pool;
- struct dma_pool *large_buffer_pool;
struct list_head safe_buffers;
- unsigned long small_buffer_size, large_buffer_size;
#ifdef STATS
- unsigned long sbp_allocs;
- unsigned long lbp_allocs;
unsigned long total_allocs;
unsigned long map_op_count;
unsigned long bounce_count;
#endif
+ struct dmabounce_pool small;
+ struct dmabounce_pool large;
};
static LIST_HEAD(dmabounce_devs);
@@ -82,9 +87,9 @@ static void print_alloc_stats(struct dmabounce_device_info *device_info)
printk(KERN_INFO
"%s: dmabounce: sbp: %lu, lbp: %lu, other: %lu, total: %lu\n",
device_info->dev->bus_id,
- device_info->sbp_allocs, device_info->lbp_allocs,
- device_info->total_allocs - device_info->sbp_allocs -
- device_info->lbp_allocs,
+ device_info->small.allocs, device_info->large.allocs,
+ device_info->total_allocs - device_info->small.allocs -
+ device_info->large.allocs,
device_info->total_allocs);
}
#endif
@@ -106,18 +111,22 @@ find_dmabounce_dev(struct device *dev)
/* allocate a 'safe' buffer and keep track of it */
static inline struct safe_buffer *
alloc_safe_buffer(struct dmabounce_device_info *device_info, void *ptr,
- size_t size, enum dma_data_direction dir)
+ size_t size, enum dma_data_direction dir)
{
struct safe_buffer *buf;
- struct dma_pool *pool;
+ struct dmabounce_pool *pool;
struct device *dev = device_info->dev;
- void *safe;
- dma_addr_t safe_dma_addr;
dev_dbg(dev, "%s(ptr=%p, size=%d, dir=%d)\n",
__func__, ptr, size, dir);
- DO_STATS ( device_info->total_allocs++ );
+ if (size <= device_info->small.size) {
+ pool = &device_info->small;
+ } else if (size <= device_info->large.size) {
+ pool = &device_info->large;
+ } else {
+ pool = NULL;
+ }
buf = kmalloc(sizeof(struct safe_buffer), GFP_ATOMIC);
if (buf == NULL) {
@@ -125,41 +134,35 @@ alloc_safe_buffer(struct dmabounce_device_info *device_info, void *ptr,
return NULL;
}
- if (size <= device_info->small_buffer_size) {
- pool = device_info->small_buffer_pool;
- safe = dma_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr);
-
- DO_STATS ( device_info->sbp_allocs++ );
- } else if (size <= device_info->large_buffer_size) {
- pool = device_info->large_buffer_pool;
- safe = dma_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr);
+ buf->ptr = ptr;
+ buf->size = size;
+ buf->direction = dir;
+ buf->pool = pool;
- DO_STATS ( device_info->lbp_allocs++ );
+ if (pool) {
+ buf->safe = dma_pool_alloc(pool->pool, GFP_ATOMIC,
+ &buf->safe_dma_addr);
} else {
- pool = NULL;
- safe = dma_alloc_coherent(dev, size, &safe_dma_addr, GFP_ATOMIC);
+ buf->safe = dma_alloc_coherent(dev, size, &buf->safe_dma_addr,
+ GFP_ATOMIC);
}
- if (safe == NULL) {
- dev_warn(device_info->dev,
- "%s: could not alloc dma memory (size=%d)\n",
- __func__, size);
+ if (buf->safe == NULL) {
+ dev_warn(dev,
+ "%s: could not alloc dma memory (size=%d)\n",
+ __func__, size);
kfree(buf);
return NULL;
}
#ifdef STATS
+ if (pool)
+ pool->allocs++;
+ device_info->total_allocs++;
if (device_info->total_allocs % 1000 == 0)
print_alloc_stats(device_info);
#endif
- buf->ptr = ptr;
- buf->size = size;
- buf->direction = dir;
- buf->pool = pool;
- buf->safe = safe;
- buf->safe_dma_addr = safe_dma_addr;
-
list_add(&buf->node, &device_info->safe_buffers);
return buf;
@@ -186,7 +189,7 @@ free_safe_buffer(struct dmabounce_device_info *device_info, struct safe_buffer *
list_del(&buf->node);
if (buf->pool)
- dma_pool_free(buf->pool, buf->safe, buf->safe_dma_addr);
+ dma_pool_free(buf->pool->pool, buf->safe, buf->safe_dma_addr);
else
dma_free_coherent(device_info->dev, buf->size, buf->safe,
buf->safe_dma_addr);
@@ -197,12 +200,10 @@ free_safe_buffer(struct dmabounce_device_info *device_info, struct safe_buffer *
/* ************************************************** */
#ifdef STATS
-
static void print_map_stats(struct dmabounce_device_info *device_info)
{
- printk(KERN_INFO
- "%s: dmabounce: map_op_count=%lu, bounce_count=%lu\n",
- device_info->dev->bus_id,
+ dev_info(device_info->dev,
+ "dmabounce: map_op_count=%lu, bounce_count=%lu\n",
device_info->map_op_count, device_info->bounce_count);
}
#endif
@@ -258,13 +259,13 @@ map_single(struct device *dev, void *ptr, size_t size,
__func__, ptr, buf->safe, size);
memcpy(buf->safe, ptr, size);
}
- consistent_sync(buf->safe, size, dir);
+ ptr = buf->safe;
dma_addr = buf->safe_dma_addr;
- } else {
- consistent_sync(ptr, size, dir);
}
+ consistent_sync(ptr, size, dir);
+
return dma_addr;
}
@@ -278,7 +279,7 @@ unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
/*
* Trying to unmap an invalid mapping
*/
- if (dma_addr == ~0) {
+ if (dma_mapping_error(dma_addr)) {
dev_err(dev, "Trying to unmap invalid mapping\n");
return;
}
@@ -570,11 +571,25 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
local_irq_restore(flags);
}
+static int
+dmabounce_init_pool(struct dmabounce_pool *pool, struct device *dev, const char *name,
+ unsigned long size)
+{
+ pool->size = size;
+ DO_STATS(pool->allocs = 0);
+ pool->pool = dma_pool_create(name, dev, size,
+ 0 /* byte alignment */,
+ 0 /* no page-crossing issues */);
+
+ return pool->pool ? 0 : -ENOMEM;
+}
+
int
dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
unsigned long large_buffer_size)
{
struct dmabounce_device_info *device_info;
+ int ret;
device_info = kmalloc(sizeof(struct dmabounce_device_info), GFP_ATOMIC);
if (!device_info) {
@@ -584,45 +599,31 @@ dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
return -ENOMEM;
}
- device_info->small_buffer_pool =
- dma_pool_create("small_dmabounce_pool",
- dev,
- small_buffer_size,
- 0 /* byte alignment */,
- 0 /* no page-crossing issues */);
- if (!device_info->small_buffer_pool) {
- printk(KERN_ERR
- "dmabounce: could not allocate small DMA pool for %s\n",
- dev->bus_id);
- kfree(device_info);
- return -ENOMEM;
+ ret = dmabounce_init_pool(&device_info->small, dev,
+ "small_dmabounce_pool", small_buffer_size);
+ if (ret) {
+ dev_err(dev,
+ "dmabounce: could not allocate DMA pool for %ld byte objects\n",
+ small_buffer_size);
+ goto err_free;
}
if (large_buffer_size) {
- device_info->large_buffer_pool =
- dma_pool_create("large_dmabounce_pool",
- dev,
- large_buffer_size,
- 0 /* byte alignment */,
- 0 /* no page-crossing issues */);
- if (!device_info->large_buffer_pool) {
- printk(KERN_ERR
- "dmabounce: could not allocate large DMA pool for %s\n",
- dev->bus_id);
- dma_pool_destroy(device_info->small_buffer_pool);
-
- return -ENOMEM;
+ ret = dmabounce_init_pool(&device_info->large, dev,
+ "large_dmabounce_pool",
+ large_buffer_size);
+ if (ret) {
+ dev_err(dev,
+ "dmabounce: could not allocate DMA pool for %ld byte objects\n",
+ large_buffer_size);
+ goto err_destroy;
}
}
device_info->dev = dev;
- device_info->small_buffer_size = small_buffer_size;
- device_info->large_buffer_size = large_buffer_size;
INIT_LIST_HEAD(&device_info->safe_buffers);
#ifdef STATS
- device_info->sbp_allocs = 0;
- device_info->lbp_allocs = 0;
device_info->total_allocs = 0;
device_info->map_op_count = 0;
device_info->bounce_count = 0;
@@ -634,6 +635,12 @@ dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
dev->bus_id, dev->bus->name);
return 0;
+
+ err_destroy:
+ dma_pool_destroy(device_info->small.pool);
+ err_free:
+ kfree(device_info);
+ return ret;
}
void
@@ -655,10 +662,10 @@ dmabounce_unregister_dev(struct device *dev)
BUG();
}
- if (device_info->small_buffer_pool)
- dma_pool_destroy(device_info->small_buffer_pool);
- if (device_info->large_buffer_pool)
- dma_pool_destroy(device_info->large_buffer_pool);
+ if (device_info->small.pool)
+ dma_pool_destroy(device_info->small.pool);
+ if (device_info->large.pool)
+ dma_pool_destroy(device_info->large.pool);
#ifdef STATS
print_alloc_stats(device_info);
diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c
index 68b06d16f253..bb4eff614413 100644
--- a/arch/arm/common/scoop.c
+++ b/arch/arm/common/scoop.c
@@ -11,6 +11,8 @@
*
*/
+#include <linux/device.h>
+#include <linux/string.h>
#include <linux/platform_device.h>
#include <asm/io.h>
#include <asm/hardware/scoop.h>
diff --git a/arch/arm/configs/ixdp2400_defconfig b/arch/arm/configs/ixdp2400_defconfig
index 678720fa2e2e..ddeb9f99d662 100644
--- a/arch/arm/configs/ixdp2400_defconfig
+++ b/arch/arm/configs/ixdp2400_defconfig
@@ -559,7 +559,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_NR_UARTS=1
# CONFIG_SERIAL_8250_EXTENDED is not set
#
diff --git a/arch/arm/configs/ixdp2800_defconfig b/arch/arm/configs/ixdp2800_defconfig
index 261e2343903b..81d3a0606f95 100644
--- a/arch/arm/configs/ixdp2800_defconfig
+++ b/arch/arm/configs/ixdp2800_defconfig
@@ -559,7 +559,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_NR_UARTS=1
# CONFIG_SERIAL_8250_EXTENDED is not set
#
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 3e1b0327e4d7..c11169b5ed9a 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -2,7 +2,7 @@
# Makefile for the linux kernel.
#
-AFLAGS_head.o := -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR)
+AFLAGS_head.o := -DKERNEL_RAM_ADDR=$(TEXTADDR)
# Object file lists.
diff --git a/arch/arm/kernel/arthur.c b/arch/arm/kernel/arthur.c
index a418dad6692c..0ee2e9819631 100644
--- a/arch/arm/kernel/arthur.c
+++ b/arch/arm/kernel/arthur.c
@@ -18,6 +18,7 @@
#include <linux/stddef.h>
#include <linux/signal.h>
#include <linux/init.h>
+#include <linux/sched.h>
#include <asm/ptrace.h>
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index c1ff4d1f1bfd..04d3082a7b94 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -94,7 +94,6 @@ int main(void)
DEFINE(VM_EXEC, VM_EXEC);
BLANK();
DEFINE(PAGE_SZ, PAGE_SIZE);
- DEFINE(VIRT_OFFSET, PAGE_OFFSET);
BLANK();
DEFINE(SYS_ERROR0, 0x9f0000);
BLANK();
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 93b5e8e5292e..be439cab92c6 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -15,6 +15,7 @@
*/
#include <linux/config.h>
+#include <asm/memory.h>
#include <asm/glue.h>
#include <asm/vfpmacros.h>
#include <asm/hardware.h> /* should be moved into entry-macro.S */
@@ -310,7 +311,7 @@ __pabt_svc:
#if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
@ make sure our user space atomic helper is aborted
- cmp r2, #VIRT_OFFSET
+ cmp r2, #TASK_SIZE
bichs r3, r3, #PSR_Z_BIT
#endif
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 539626351348..8d8748407cbe 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -21,6 +21,7 @@
#include <asm/procinfo.h>
#include <asm/ptrace.h>
#include <asm/asm-offsets.h>
+#include <asm/memory.h>
#include <asm/thread_info.h>
#include <asm/system.h>
@@ -33,52 +34,28 @@
#define MACHINFO_PGOFFIO 12
#define MACHINFO_NAME 16
-#ifndef CONFIG_XIP_KERNEL
/*
- * We place the page tables 16K below TEXTADDR. Therefore, we must make sure
- * that TEXTADDR is correctly set. Currently, we expect the least significant
- * 16 bits to be 0x8000, but we could probably relax this restriction to
- * TEXTADDR >= PAGE_OFFSET + 0x4000
- *
- * Note that swapper_pg_dir is the virtual address of the page tables, and
- * pgtbl gives us a position-independent reference to these tables. We can
- * do this because stext == TEXTADDR
+ * swapper_pg_dir is the virtual address of the initial page table.
+ * We place the page tables 16K below KERNEL_RAM_ADDR. Therefore, we must
+ * make sure that KERNEL_RAM_ADDR is correctly set. Currently, we expect
+ * the least significant 16 bits to be 0x8000, but we could probably
+ * relax this restriction to KERNEL_RAM_ADDR >= PAGE_OFFSET + 0x4000.
*/
-#if (TEXTADDR & 0xffff) != 0x8000
-#error TEXTADDR must start at 0xXXXX8000
+#if (KERNEL_RAM_ADDR & 0xffff) != 0x8000
+#error KERNEL_RAM_ADDR must start at 0xXXXX8000
#endif
.globl swapper_pg_dir
- .equ swapper_pg_dir, TEXTADDR - 0x4000
+ .equ swapper_pg_dir, KERNEL_RAM_ADDR - 0x4000
- .macro pgtbl, rd, phys
- adr \rd, stext
- sub \rd, \rd, #0x4000
+ .macro pgtbl, rd
+ ldr \rd, =(__virt_to_phys(KERNEL_RAM_ADDR - 0x4000))
.endm
-#else
-/*
- * XIP Kernel:
- *
- * We place the page tables 16K below DATAADDR. Therefore, we must make sure
- * that DATAADDR is correctly set. Currently, we expect the least significant
- * 16 bits to be 0x8000, but we could probably relax this restriction to
- * DATAADDR >= PAGE_OFFSET + 0x4000
- *
- * Note that pgtbl is meant to return the physical address of swapper_pg_dir.
- * We can't make it relative to the kernel position in this case since
- * the kernel can physically be anywhere.
- */
-#if (DATAADDR & 0xffff) != 0x8000
-#error DATAADDR must start at 0xXXXX8000
-#endif
-
- .globl swapper_pg_dir
- .equ swapper_pg_dir, DATAADDR - 0x4000
- .macro pgtbl, rd, phys
- ldr \rd, =((DATAADDR - 0x4000) - VIRT_OFFSET)
- add \rd, \rd, \phys
- .endm
+#ifdef CONFIG_XIP_KERNEL
+#define TEXTADDR XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
+#else
+#define TEXTADDR KERNEL_RAM_ADDR
#endif
/*
@@ -279,7 +256,7 @@ __turn_mmu_on:
.type __create_page_tables, %function
__create_page_tables:
ldr r5, [r8, #MACHINFO_PHYSRAM] @ physram
- pgtbl r4, r5 @ page table address
+ pgtbl r4 @ page table address
/*
* Clear the 16K level 1 swapper page table
@@ -324,7 +301,7 @@ __create_page_tables:
/*
* Then map first 1MB of ram in case it contains our boot params.
*/
- add r0, r4, #VIRT_OFFSET >> 18
+ add r0, r4, #PAGE_OFFSET >> 18
orr r6, r5, r7
str r6, [r0]
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index cd99b83f14c2..9bd8609a2926 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -782,7 +782,7 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
return ret;
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
int ret;
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index a94d75fef598..a917e3dd3666 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -139,93 +139,33 @@ struct iwmmxt_sigframe {
unsigned long storage[0x98/4];
};
-static int page_present(struct mm_struct *mm, void __user *uptr, int wr)
-{
- unsigned long addr = (unsigned long)uptr;
- pgd_t *pgd = pgd_offset(mm, addr);
- if (pgd_present(*pgd)) {
- pmd_t *pmd = pmd_offset(pgd, addr);
- if (pmd_present(*pmd)) {
- pte_t *pte = pte_offset_map(pmd, addr);
- return (pte_present(*pte) && (!wr || pte_write(*pte)));
- }
- }
- return 0;
-}
-
-static int copy_locked(void __user *uptr, void *kptr, size_t size, int write,
- void (*copyfn)(void *, void __user *))
-{
- unsigned char v, __user *userptr = uptr;
- int err = 0;
-
- do {
- struct mm_struct *mm;
-
- if (write) {
- __put_user_error(0, userptr, err);
- __put_user_error(0, userptr + size - 1, err);
- } else {
- __get_user_error(v, userptr, err);
- __get_user_error(v, userptr + size - 1, err);
- }
-
- if (err)
- break;
-
- mm = current->mm;
- spin_lock(&mm->page_table_lock);
- if (page_present(mm, userptr, write) &&
- page_present(mm, userptr + size - 1, write)) {
- copyfn(kptr, uptr);
- } else
- err = 1;
- spin_unlock(&mm->page_table_lock);
- } while (err);
-
- return err;
-}
-
static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame)
{
- int err = 0;
+ char kbuf[sizeof(*frame) + 8];
+ struct iwmmxt_sigframe *kframe;
/* the iWMMXt context must be 64 bit aligned */
- WARN_ON((unsigned long)frame & 7);
-
- __put_user_error(IWMMXT_MAGIC0, &frame->magic0, err);
- __put_user_error(IWMMXT_MAGIC1, &frame->magic1, err);
-
- /*
- * iwmmxt_task_copy() doesn't check user permissions.
- * Let's do a dummy write on the upper boundary to ensure
- * access to user mem is OK all way up.
- */
- err |= copy_locked(&frame->storage, current_thread_info(),
- sizeof(frame->storage), 1, iwmmxt_task_copy);
- return err;
+ kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7);
+ kframe->magic0 = IWMMXT_MAGIC0;
+ kframe->magic1 = IWMMXT_MAGIC1;
+ iwmmxt_task_copy(current_thread_info(), &kframe->storage);
+ return __copy_to_user(frame, kframe, sizeof(*frame));
}
static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame)
{
- unsigned long magic0, magic1;
- int err = 0;
+ char kbuf[sizeof(*frame) + 8];
+ struct iwmmxt_sigframe *kframe;
- /* the iWMMXt context is 64 bit aligned */
- WARN_ON((unsigned long)frame & 7);
-
- /*
- * Validate iWMMXt context signature.
- * Also, iwmmxt_task_restore() doesn't check user permissions.
- * Let's do a dummy write on the upper boundary to ensure
- * access to user mem is OK all way up.
- */
- __get_user_error(magic0, &frame->magic0, err);
- __get_user_error(magic1, &frame->magic1, err);
- if (!err && magic0 == IWMMXT_MAGIC0 && magic1 == IWMMXT_MAGIC1)
- err = copy_locked(&frame->storage, current_thread_info(),
- sizeof(frame->storage), 0, iwmmxt_task_restore);
- return err;
+ /* the iWMMXt context must be 64 bit aligned */
+ kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7);
+ if (__copy_from_user(kframe, frame, sizeof(*frame)))
+ return -1;
+ if (kframe->magic0 != IWMMXT_MAGIC0 ||
+ kframe->magic1 != IWMMXT_MAGIC1)
+ return -1;
+ iwmmxt_task_restore(current_thread_info(), &kframe->storage);
+ return 0;
}
#endif
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index 69449a818dcc..fc4729106a32 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -36,10 +36,6 @@
#include <asm/thread_info.h>
#include <asm/mach/time.h>
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
/*
* Our system timer.
*/
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index baa09601a64e..45e9ea6cd2a5 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -198,25 +198,16 @@ void show_stack(struct task_struct *tsk, unsigned long *sp)
barrier();
}
-DEFINE_SPINLOCK(die_lock);
-
-/*
- * This function is protected against re-entrancy.
- */
-NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
+static void __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs)
{
- struct task_struct *tsk = current;
+ struct task_struct *tsk = thread->task;
static int die_counter;
- console_verbose();
- spin_lock_irq(&die_lock);
- bust_spinlocks(1);
-
printk("Internal error: %s: %x [#%d]\n", str, err, ++die_counter);
print_modules();
__show_regs(regs);
printk("Process %s (pid: %d, stack limit = 0x%p)\n",
- tsk->comm, tsk->pid, tsk->thread_info + 1);
+ tsk->comm, tsk->pid, thread + 1);
if (!user_mode(regs) || in_interrupt()) {
dump_mem("Stack: ", regs->ARM_sp,
@@ -224,7 +215,21 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
dump_backtrace(regs, tsk);
dump_instr(regs);
}
+}
+
+DEFINE_SPINLOCK(die_lock);
+
+/*
+ * This function is protected against re-entrancy.
+ */
+NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
+{
+ struct thread_info *thread = current_thread_info();
+ console_verbose();
+ spin_lock_irq(&die_lock);
+ bust_spinlocks(1);
+ __die(str, err, thread, regs);
bust_spinlocks(0);
spin_unlock_irq(&die_lock);
do_exit(SIGSEGV);
@@ -483,29 +488,33 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
unsigned long addr = regs->ARM_r2;
struct mm_struct *mm = current->mm;
pgd_t *pgd; pmd_t *pmd; pte_t *pte;
+ spinlock_t *ptl;
regs->ARM_cpsr &= ~PSR_C_BIT;
- spin_lock(&mm->page_table_lock);
+ down_read(&mm->mmap_sem);
pgd = pgd_offset(mm, addr);
if (!pgd_present(*pgd))
goto bad_access;
pmd = pmd_offset(pgd, addr);
if (!pmd_present(*pmd))
goto bad_access;
- pte = pte_offset_map(pmd, addr);
- if (!pte_present(*pte) || !pte_write(*pte))
+ pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
+ if (!pte_present(*pte) || !pte_write(*pte)) {
+ pte_unmap_unlock(pte, ptl);
goto bad_access;
+ }
val = *(unsigned long *)addr;
val -= regs->ARM_r0;
if (val == 0) {
*(unsigned long *)addr = regs->ARM_r1;
regs->ARM_cpsr |= PSR_C_BIT;
}
- spin_unlock(&mm->page_table_lock);
+ pte_unmap_unlock(pte, ptl);
+ up_read(&mm->mmap_sem);
return val;
bad_access:
- spin_unlock(&mm->page_table_lock);
+ up_read(&mm->mmap_sem);
/* simulate a write access fault */
do_DataAbort(addr, 15 + (1 << 11), regs);
return -1;
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 0d5db5279c5c..80c8e4c8cefa 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -6,14 +6,23 @@
#include <asm-generic/vmlinux.lds.h>
#include <linux/config.h>
#include <asm/thread_info.h>
+#include <asm/memory.h>
OUTPUT_ARCH(arm)
ENTRY(stext)
+
#ifndef __ARMEB__
jiffies = jiffies_64;
#else
jiffies = jiffies_64 + 4;
#endif
+
+#ifdef CONFIG_XIP_KERNEL
+#define TEXTADDR XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
+#else
+#define TEXTADDR KERNEL_RAM_ADDR
+#endif
+
SECTIONS
{
. = TEXTADDR;
@@ -95,7 +104,7 @@ SECTIONS
#ifdef CONFIG_XIP_KERNEL
__data_loc = ALIGN(4); /* location in binary */
- . = DATAADDR;
+ . = KERNEL_RAM_ADDR;
#else
. = ALIGN(THREAD_SIZE);
__data_loc = .;
diff --git a/arch/arm/lib/ashldi3.S b/arch/arm/lib/ashldi3.S
new file mode 100644
index 000000000000..561e20717b30
--- /dev/null
+++ b/arch/arm/lib/ashldi3.S
@@ -0,0 +1,48 @@
+/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005
+ Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING. If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
+
+
+#include <linux/linkage.h>
+
+#ifdef __ARMEB__
+#define al r1
+#define ah r0
+#else
+#define al r0
+#define ah r1
+#endif
+
+ENTRY(__ashldi3)
+
+ subs r3, r2, #32
+ rsb ip, r2, #32
+ movmi ah, ah, lsl r2
+ movpl ah, al, lsl r3
+ orrmi ah, ah, al, lsr ip
+ mov al, al, lsl r2
+ mov pc, lr
+
diff --git a/arch/arm/lib/ashldi3.c b/arch/arm/lib/ashldi3.c
deleted file mode 100644
index b62875cfd8f8..000000000000
--- a/arch/arm/lib/ashldi3.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/* More subroutines needed by GCC output code on some machines. */
-/* Compile this one with gcc. */
-/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-/* As a special exception, if you link this library with other files,
- some of which are compiled with GCC, to produce an executable,
- this library does not by itself cause the resulting executable
- to be covered by the GNU General Public License.
- This exception does not however invalidate any other reasons why
- the executable file might be covered by the GNU General Public License.
- */
-/* support functions required by the kernel. based on code from gcc-2.95.3 */
-/* I Molton 29/07/01 */
-
-#include "gcclib.h"
-
-s64 __ashldi3(s64 u, int b)
-{
- DIunion w;
- int bm;
- DIunion uu;
-
- if (b == 0)
- return u;
-
- uu.ll = u;
-
- bm = (sizeof(s32) * BITS_PER_UNIT) - b;
- if (bm <= 0) {
- w.s.low = 0;
- w.s.high = (u32) uu.s.low << -bm;
- } else {
- u32 carries = (u32) uu.s.low >> bm;
- w.s.low = (u32) uu.s.low << b;
- w.s.high = ((u32) uu.s.high << b) | carries;
- }
-
- return w.ll;
-}
diff --git a/arch/arm/lib/ashrdi3.S b/arch/arm/lib/ashrdi3.S
new file mode 100644
index 000000000000..86fb2a90c301
--- /dev/null
+++ b/arch/arm/lib/ashrdi3.S
@@ -0,0 +1,48 @@
+/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005
+ Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING. If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
+
+
+#include <linux/linkage.h>
+
+#ifdef __ARMEB__
+#define al r1
+#define ah r0
+#else
+#define al r0
+#define ah r1
+#endif
+
+ENTRY(__ashrdi3)
+
+ subs r3, r2, #32
+ rsb ip, r2, #32
+ movmi al, al, lsr r2
+ movpl al, ah, asr r3
+ orrmi al, al, ah, lsl ip
+ mov ah, ah, asr r2
+ mov pc, lr
+
diff --git a/arch/arm/lib/ashrdi3.c b/arch/arm/lib/ashrdi3.c
deleted file mode 100644
index 9a8600a7543f..000000000000
--- a/arch/arm/lib/ashrdi3.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/* More subroutines needed by GCC output code on some machines. */
-/* Compile this one with gcc. */
-/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-/* As a special exception, if you link this library with other files,
- some of which are compiled with GCC, to produce an executable,
- this library does not by itself cause the resulting executable
- to be covered by the GNU General Public License.
- This exception does not however invalidate any other reasons why
- the executable file might be covered by the GNU General Public License.
- */
-/* support functions required by the kernel. based on code from gcc-2.95.3 */
-/* I Molton 29/07/01 */
-
-#include "gcclib.h"
-
-s64 __ashrdi3(s64 u, int b)
-{
- DIunion w;
- int bm;
- DIunion uu;
-
- if (b == 0)
- return u;
-
- uu.ll = u;
-
- bm = (sizeof(s32) * BITS_PER_UNIT) - b;
- if (bm <= 0) {
- /* w.s.high = 1..1 or 0..0 */
- w.s.high = uu.s.high >> (sizeof(s32) * BITS_PER_UNIT - 1);
- w.s.low = uu.s.high >> -bm;
- } else {
- u32 carries = (u32) uu.s.high << bm;
- w.s.high = uu.s.high >> b;
- w.s.low = ((u32) uu.s.low >> b) | carries;
- }
-
- return w.ll;
-}
diff --git a/arch/arm/lib/gcclib.h b/arch/arm/lib/gcclib.h
deleted file mode 100644
index 8b6dcc656de7..000000000000
--- a/arch/arm/lib/gcclib.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* gcclib.h -- definitions for various functions 'borrowed' from gcc-2.95.3 */
-/* I Molton 29/07/01 */
-
-#include <linux/types.h>
-
-#define BITS_PER_UNIT 8
-#define SI_TYPE_SIZE (sizeof(s32) * BITS_PER_UNIT)
-
-#ifdef __ARMEB__
-struct DIstruct {
- s32 high, low;
-};
-#else
-struct DIstruct {
- s32 low, high;
-};
-#endif
-
-typedef union {
- struct DIstruct s;
- s64 ll;
-} DIunion;
diff --git a/arch/arm/lib/lshrdi3.S b/arch/arm/lib/lshrdi3.S
new file mode 100644
index 000000000000..46c2ed19ec95
--- /dev/null
+++ b/arch/arm/lib/lshrdi3.S
@@ -0,0 +1,48 @@
+/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005
+ Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING. If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
+
+
+#include <linux/linkage.h>
+
+#ifdef __ARMEB__
+#define al r1
+#define ah r0
+#else
+#define al r0
+#define ah r1
+#endif
+
+ENTRY(__lshrdi3)
+
+ subs r3, r2, #32
+ rsb ip, r2, #32
+ movmi al, al, lsr r2
+ movpl al, ah, lsr r3
+ orrmi al, al, ah, lsl ip
+ mov ah, ah, lsr r2
+ mov pc, lr
+
diff --git a/arch/arm/lib/lshrdi3.c b/arch/arm/lib/lshrdi3.c
deleted file mode 100644
index 3681f49d2b6e..000000000000
--- a/arch/arm/lib/lshrdi3.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/* More subroutines needed by GCC output code on some machines. */
-/* Compile this one with gcc. */
-/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-/* As a special exception, if you link this library with other files,
- some of which are compiled with GCC, to produce an executable,
- this library does not by itself cause the resulting executable
- to be covered by the GNU General Public License.
- This exception does not however invalidate any other reasons why
- the executable file might be covered by the GNU General Public License.
- */
-/* support functions required by the kernel. based on code from gcc-2.95.3 */
-/* I Molton 29/07/01 */
-
-#include "gcclib.h"
-
-s64 __lshrdi3(s64 u, int b)
-{
- DIunion w;
- int bm;
- DIunion uu;
-
- if (b == 0)
- return u;
-
- uu.ll = u;
-
- bm = (sizeof(s32) * BITS_PER_UNIT) - b;
- if (bm <= 0) {
- w.s.high = 0;
- w.s.low = (u32) uu.s.high >> -bm;
- } else {
- u32 carries = (u32) uu.s.high << bm;
- w.s.high = (u32) uu.s.high >> b;
- w.s.low = ((u32) uu.s.low >> b) | carries;
- }
-
- return w.ll;
-}
diff --git a/arch/arm/lib/muldi3.S b/arch/arm/lib/muldi3.S
new file mode 100644
index 000000000000..c7fbdf005319
--- /dev/null
+++ b/arch/arm/lib/muldi3.S
@@ -0,0 +1,44 @@
+/*
+ * linux/arch/arm/lib/muldi3.S
+ *
+ * Author: Nicolas Pitre
+ * Created: Oct 19, 2005
+ * Copyright: Monta Vista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+
+#ifdef __ARMEB__
+#define xh r0
+#define xl r1
+#define yh r2
+#define yl r3
+#else
+#define xl r0
+#define xh r1
+#define yl r2
+#define yh r3
+#endif
+
+ENTRY(__muldi3)
+
+ mul xh, yl, xh
+ mla xh, xl, yh, xh
+ mov ip, xl, asr #16
+ mov yh, yl, asr #16
+ bic xl, xl, ip, lsl #16
+ bic yl, yl, yh, lsl #16
+ mla xh, yh, ip, xh
+ mul yh, xl, yh
+ mul xl, yl, xl
+ mul ip, yl, ip
+ adds xl, xl, yh, lsl #16
+ adc xh, xh, yh, lsr #16
+ adds xl, xl, ip, lsl #16
+ adc xh, xh, ip, lsr #16
+ mov pc, lr
+
diff --git a/arch/arm/lib/muldi3.c b/arch/arm/lib/muldi3.c
deleted file mode 100644
index 0a3b93313f18..000000000000
--- a/arch/arm/lib/muldi3.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/* More subroutines needed by GCC output code on some machines. */
-/* Compile this one with gcc. */
-/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-/* As a special exception, if you link this library with other files,
- some of which are compiled with GCC, to produce an executable,
- this library does not by itself cause the resulting executable
- to be covered by the GNU General Public License.
- This exception does not however invalidate any other reasons why
- the executable file might be covered by the GNU General Public License.
- */
-/* support functions required by the kernel. based on code from gcc-2.95.3 */
-/* I Molton 29/07/01 */
-
-#include "gcclib.h"
-
-#define umul_ppmm(xh, xl, a, b) \
-{register u32 __t0, __t1, __t2; \
- __asm__ ("%@ Inlined umul_ppmm \n\
- mov %2, %5, lsr #16 \n\
- mov %0, %6, lsr #16 \n\
- bic %3, %5, %2, lsl #16 \n\
- bic %4, %6, %0, lsl #16 \n\
- mul %1, %3, %4 \n\
- mul %4, %2, %4 \n\
- mul %3, %0, %3 \n\
- mul %0, %2, %0 \n\
- adds %3, %4, %3 \n\
- addcs %0, %0, #65536 \n\
- adds %1, %1, %3, lsl #16 \n\
- adc %0, %0, %3, lsr #16" \
- : "=&r" ((u32) (xh)), \
- "=r" ((u32) (xl)), \
- "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \
- : "r" ((u32) (a)), \
- "r" ((u32) (b)));}
-
-#define __umulsidi3(u, v) \
- ({DIunion __w; \
- umul_ppmm (__w.s.high, __w.s.low, u, v); \
- __w.ll; })
-
-s64 __muldi3(s64 u, s64 v)
-{
- DIunion w;
- DIunion uu, vv;
-
- uu.ll = u, vv.ll = v;
-
- w.ll = __umulsidi3(uu.s.low, vv.s.low);
- w.s.high += ((u32) uu.s.low * (u32) vv.s.high
- + (u32) uu.s.high * (u32) vv.s.low);
-
- return w.ll;
-}
diff --git a/arch/arm/lib/ucmpdi2.S b/arch/arm/lib/ucmpdi2.S
new file mode 100644
index 000000000000..112630f93e5d
--- /dev/null
+++ b/arch/arm/lib/ucmpdi2.S
@@ -0,0 +1,35 @@
+/*
+ * linux/arch/arm/lib/ucmpdi2.S
+ *
+ * Author: Nicolas Pitre
+ * Created: Oct 19, 2005
+ * Copyright: Monta Vista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+
+#ifdef __ARMEB__
+#define xh r0
+#define xl r1
+#define yh r2
+#define yl r3
+#else
+#define xl r0
+#define xh r1
+#define yl r2
+#define yh r3
+#endif
+
+ENTRY(__ucmpdi2)
+
+ cmp xh, yh
+ cmpeq xl, yl
+ movlo r0, #0
+ moveq r0, #1
+ movhi r0, #2
+ mov pc, lr
+
diff --git a/arch/arm/lib/ucmpdi2.c b/arch/arm/lib/ucmpdi2.c
deleted file mode 100644
index 57f3f2df3850..000000000000
--- a/arch/arm/lib/ucmpdi2.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/* More subroutines needed by GCC output code on some machines. */
-/* Compile this one with gcc. */
-/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-/* As a special exception, if you link this library with other files,
- some of which are compiled with GCC, to produce an executable,
- this library does not by itself cause the resulting executable
- to be covered by the GNU General Public License.
- This exception does not however invalidate any other reasons why
- the executable file might be covered by the GNU General Public License.
- */
-/* support functions required by the kernel. based on code from gcc-2.95.3 */
-/* I Molton 29/07/01 */
-
-#include "gcclib.h"
-
-int __ucmpdi2(s64 a, s64 b)
-{
- DIunion au, bu;
-
- au.ll = a, bu.ll = b;
-
- if ((u32) au.s.high < (u32) bu.s.high)
- return 0;
- else if ((u32) au.s.high > (u32) bu.s.high)
- return 2;
- if ((u32) au.s.low < (u32) bu.s.low)
- return 0;
- else if ((u32) au.s.low > (u32) bu.s.low)
- return 2;
- return 1;
-}
diff --git a/arch/arm/mach-imx/generic.c b/arch/arm/mach-imx/generic.c
index 60e2361e98e8..37613ad68366 100644
--- a/arch/arm/mach-imx/generic.c
+++ b/arch/arm/mach-imx/generic.c
@@ -26,6 +26,8 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/string.h>
+
#include <asm/arch/imxfb.h>
#include <asm/hardware.h>
#include <asm/arch/imx-regs.h>
diff --git a/arch/arm/mach-integrator/clock.c b/arch/arm/mach-integrator/clock.c
index 56200594db3c..73c360685cad 100644
--- a/arch/arm/mach-integrator/clock.c
+++ b/arch/arm/mach-integrator/clock.c
@@ -13,6 +13,7 @@
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/err.h>
+#include <linux/string.h>
#include <asm/semaphore.h>
#include <asm/hardware/clock.h>
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 1f9061ca7ef4..4c0f7c65facf 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -30,6 +30,7 @@
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/setup.h>
+#include <asm/param.h> /* HZ */
#include <asm/mach-types.h>
#include <asm/hardware/amba.h>
#include <asm/hardware/amba_kmi.h>
diff --git a/arch/arm/mach-integrator/lm.c b/arch/arm/mach-integrator/lm.c
index c5f19d160598..5b41e3a724e1 100644
--- a/arch/arm/mach-integrator/lm.c
+++ b/arch/arm/mach-integrator/lm.c
@@ -10,6 +10,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
+#include <linux/slab.h>
#include <asm/arch/lm.h>
diff --git a/arch/arm/mach-iop3xx/iq31244-pci.c b/arch/arm/mach-iop3xx/iq31244-pci.c
index f997daa800bf..c6a973ba8fc6 100644
--- a/arch/arm/mach-iop3xx/iq31244-pci.c
+++ b/arch/arm/mach-iop3xx/iq31244-pci.c
@@ -14,6 +14,8 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <asm/hardware.h>
#include <asm/irq.h>
diff --git a/arch/arm/mach-iop3xx/iq80321-pci.c b/arch/arm/mach-iop3xx/iq80321-pci.c
index 79fea3d20b66..802f6d091b75 100644
--- a/arch/arm/mach-iop3xx/iq80321-pci.c
+++ b/arch/arm/mach-iop3xx/iq80321-pci.c
@@ -14,6 +14,8 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <asm/hardware.h>
#include <asm/irq.h>
diff --git a/arch/arm/mach-iop3xx/iq80331-pci.c b/arch/arm/mach-iop3xx/iq80331-pci.c
index f37a0e26b466..654e450a1311 100644
--- a/arch/arm/mach-iop3xx/iq80331-pci.c
+++ b/arch/arm/mach-iop3xx/iq80331-pci.c
@@ -13,6 +13,8 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <asm/hardware.h>
#include <asm/irq.h>
diff --git a/arch/arm/mach-iop3xx/iq80332-pci.c b/arch/arm/mach-iop3xx/iq80332-pci.c
index b9807aa2aade..65951ffe4631 100644
--- a/arch/arm/mach-iop3xx/iq80332-pci.c
+++ b/arch/arm/mach-iop3xx/iq80332-pci.c
@@ -13,6 +13,8 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <asm/hardware.h>
#include <asm/irq.h>
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 247147f29b93..eb5f6d744a4a 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -33,6 +33,7 @@
#include <asm/arch/pxa-regs.h>
#include <asm/arch/irq.h>
+#include <asm/arch/irda.h>
#include <asm/arch/mmc.h>
#include <asm/arch/udc.h>
#include <asm/arch/corgi.h>
@@ -224,6 +225,22 @@ static struct pxamci_platform_data corgi_mci_platform_data = {
};
+/*
+ * Irda
+ */
+static void corgi_irda_transceiver_mode(struct device *dev, int mode)
+{
+ if (mode & IR_OFF)
+ GPSR(CORGI_GPIO_IR_ON) = GPIO_bit(CORGI_GPIO_IR_ON);
+ else
+ GPCR(CORGI_GPIO_IR_ON) = GPIO_bit(CORGI_GPIO_IR_ON);
+}
+
+static struct pxaficp_platform_data corgi_ficp_platform_data = {
+ .transceiver_cap = IR_SIRMODE | IR_OFF,
+ .transceiver_mode = corgi_irda_transceiver_mode,
+};
+
/*
* USB Device Controller
@@ -269,10 +286,13 @@ static void __init corgi_init(void)
corgi_ssp_set_machinfo(&corgi_ssp_machinfo);
+ pxa_gpio_mode(CORGI_GPIO_IR_ON | GPIO_OUT);
pxa_gpio_mode(CORGI_GPIO_USB_PULLUP | GPIO_OUT);
pxa_gpio_mode(CORGI_GPIO_HSYNC | GPIO_IN);
+
pxa_set_udc_info(&udc_info);
pxa_set_mci_info(&corgi_mci_platform_data);
+ pxa_set_ficp_info(&corgi_ficp_platform_data);
scoop_num = 1;
scoop_devs = &corgi_pcmcia_scoop[0];
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index afd5063b0ebe..9b48a90aefce 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -23,6 +23,7 @@
#include <linux/platform_device.h>
#include <linux/ioport.h>
#include <linux/pm.h>
+#include <linux/string.h>
#include <asm/hardware.h>
#include <asm/irq.h>
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 86326307ab9f..ad6a13f95a62 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -32,6 +32,7 @@
#include <asm/arch/irq.h>
#include <asm/arch/mmc.h>
#include <asm/arch/udc.h>
+#include <asm/arch/irda.h>
#include <asm/arch/poodle.h>
#include <asm/arch/pxafb.h>
@@ -152,6 +153,24 @@ static struct pxamci_platform_data poodle_mci_platform_data = {
/*
+ * Irda
+ */
+static void poodle_irda_transceiver_mode(struct device *dev, int mode)
+{
+ if (mode & IR_OFF) {
+ GPSR(POODLE_GPIO_IR_ON) = GPIO_bit(POODLE_GPIO_IR_ON);
+ } else {
+ GPCR(POODLE_GPIO_IR_ON) = GPIO_bit(POODLE_GPIO_IR_ON);
+ }
+}
+
+static struct pxaficp_platform_data poodle_ficp_platform_data = {
+ .transceiver_cap = IR_SIRMODE | IR_OFF,
+ .transceiver_mode = poodle_irda_transceiver_mode,
+};
+
+
+/*
* USB Device Controller
*/
static void poodle_udc_command(int cmd)
@@ -244,8 +263,10 @@ static void __init poodle_init(void)
set_pxa_fb_info(&poodle_fb_info);
pxa_gpio_mode(POODLE_GPIO_USB_PULLUP | GPIO_OUT);
+ pxa_gpio_mode(POODLE_GPIO_IR_ON | GPIO_OUT);
pxa_set_udc_info(&udc_info);
pxa_set_mci_info(&poodle_mci_platform_data);
+ pxa_set_ficp_info(&poodle_ficp_platform_data);
scoop_num = 1;
scoop_devs = &poodle_pcmcia_scoop[0];
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 4182ddf330da..6c6878cd2207 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -34,6 +34,7 @@
#include <asm/arch/pxa-regs.h>
#include <asm/arch/irq.h>
+#include <asm/arch/irda.h>
#include <asm/arch/mmc.h>
#include <asm/arch/udc.h>
#include <asm/arch/pxafb.h>
@@ -277,6 +278,23 @@ static struct pxamci_platform_data spitz_mci_platform_data = {
/*
+ * Irda
+ */
+static void spitz_irda_transceiver_mode(struct device *dev, int mode)
+{
+ if (mode & IR_OFF)
+ set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_IR_ON);
+ else
+ reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_IR_ON);
+}
+
+static struct pxaficp_platform_data spitz_ficp_platform_data = {
+ .transceiver_cap = IR_SIRMODE | IR_OFF,
+ .transceiver_mode = spitz_irda_transceiver_mode,
+};
+
+
+/*
* Spitz PXA Framebuffer
*/
static struct pxafb_mach_info spitz_pxafb_info __initdata = {
@@ -326,6 +344,7 @@ static void __init common_init(void)
platform_add_devices(devices, ARRAY_SIZE(devices));
pxa_set_mci_info(&spitz_mci_platform_data);
+ pxa_set_ficp_info(&spitz_ficp_platform_data);
set_pxa_fb_parent(&spitzssp_device.dev);
set_pxa_fb_info(&spitz_pxafb_info);
}
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index 976380bde417..2abdc419e984 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -17,6 +17,7 @@
#include <linux/pm.h>
#include <linux/cpufreq.h>
#include <linux/ioport.h>
+#include <linux/sched.h> /* just for sched_clock() - funny that */
#include <linux/platform_device.h>
#include <asm/div64.h>
@@ -24,6 +25,7 @@
#include <asm/system.h>
#include <asm/pgtable.h>
#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
#include <asm/irq.h>
#include "generic.h"
@@ -284,6 +286,7 @@ static struct platform_device sa11x0mtd_device = {
void sa11x0_set_flash_data(struct flash_platform_data *flash,
struct resource *res, int nr)
{
+ flash->name = "sa1100";
sa11x0mtd_device.dev.platform_data = flash;
sa11x0mtd_device.resource = res;
sa11x0mtd_device.num_resources = nr;
diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c
index 9fb65cffa578..2f671cc3cb99 100644
--- a/arch/arm/mach-sa1100/jornada720.c
+++ b/arch/arm/mach-sa1100/jornada720.c
@@ -8,6 +8,8 @@
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/ioport.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
#include <asm/hardware.h>
#include <asm/hardware/sa1111.h>
@@ -16,6 +18,7 @@
#include <asm/setup.h>
#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
#include <asm/mach/map.h>
#include <asm/mach/serial_sa1100.h>
@@ -108,6 +111,66 @@ static void __init jornada720_map_io(void)
sa1100_register_uart(1, 1);
}
+static struct mtd_partition jornada720_partitions[] = {
+ {
+ .name = "JORNADA720 boot firmware",
+ .size = 0x00040000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }, {
+ .name = "JORNADA720 kernel",
+ .size = 0x000c0000,
+ .offset = 0x00040000,
+ }, {
+ .name = "JORNADA720 params",
+ .size = 0x00040000,
+ .offset = 0x00100000,
+ }, {
+ .name = "JORNADA720 initrd",
+ .size = 0x00100000,
+ .offset = 0x00140000,
+ }, {
+ .name = "JORNADA720 root cramfs",
+ .size = 0x00300000,
+ .offset = 0x00240000,
+ }, {
+ .name = "JORNADA720 usr cramfs",
+ .size = 0x00800000,
+ .offset = 0x00540000,
+ }, {
+ .name = "JORNADA720 usr local",
+ .size = 0, /* will expand to the end of the flash */
+ .offset = 0x00d00000,
+ }
+};
+
+static void jornada720_set_vpp(int vpp)
+{
+ if (vpp)
+ PPSR |= 0x80;
+ else
+ PPSR &= ~0x80;
+ PPDR |= 0x80;
+}
+
+static struct flash_platform_data jornada720_flash_data = {
+ .map_name = "cfi_probe",
+ .set_vpp = jornada720_set_vpp,
+ .parts = jornada720_partitions,
+ .nr_parts = ARRAY_SIZE(jornada720_partitions),
+};
+
+static struct resource jornada720_flash_resource = {
+ .start = SA1100_CS0_PHYS,
+ .end = SA1100_CS0_PHYS + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static void __init jornada720_mach_init(void)
+{
+ sa11x0_set_flash_data(&jornada720_flash_data, &jornada720_flash_resource, 1);
+}
+
MACHINE_START(JORNADA720, "HP Jornada 720")
/* Maintainer: Michael Gernoth <michael@gernoth.net> */
.phys_ram = 0xc0000000,
@@ -117,4 +180,5 @@ MACHINE_START(JORNADA720, "HP Jornada 720")
.map_io = jornada720_map_io,
.init_irq = sa1100_init_irq,
.timer = &sa1100_timer,
+ .init_machine = jornada720_mach_init,
MACHINE_END
diff --git a/arch/arm/mach-versatile/clock.c b/arch/arm/mach-versatile/clock.c
index 48025c2b9987..b96a2ea15d41 100644
--- a/arch/arm/mach-versatile/clock.c
+++ b/arch/arm/mach-versatile/clock.c
@@ -13,6 +13,7 @@
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/err.h>
+#include <linux/string.h>
#include <asm/semaphore.h>
#include <asm/hardware/clock.h>
diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c
index 82f4d5e27c54..47b0b767f080 100644
--- a/arch/arm/mm/consistent.c
+++ b/arch/arm/mm/consistent.c
@@ -397,8 +397,6 @@ static int __init consistent_init(void)
pte_t *pte;
int ret = 0;
- spin_lock(&init_mm.page_table_lock);
-
do {
pgd = pgd_offset(&init_mm, CONSISTENT_BASE);
pmd = pmd_alloc(&init_mm, pgd, CONSISTENT_BASE);
@@ -409,7 +407,7 @@ static int __init consistent_init(void)
}
WARN_ON(!pmd_none(*pmd));
- pte = pte_alloc_kernel(&init_mm, pmd, CONSISTENT_BASE);
+ pte = pte_alloc_kernel(pmd, CONSISTENT_BASE);
if (!pte) {
printk(KERN_ERR "%s: no pte tables\n", __func__);
ret = -ENOMEM;
@@ -419,8 +417,6 @@ static int __init consistent_init(void)
consistent_pte = pte;
} while (0);
- spin_unlock(&init_mm.page_table_lock);
-
return ret;
}
diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c
index 27d041574ea7..269ce6913ee9 100644
--- a/arch/arm/mm/copypage-v6.c
+++ b/arch/arm/mm/copypage-v6.c
@@ -22,9 +22,7 @@
#endif
#define from_address (0xffff8000)
-#define from_pgprot PAGE_KERNEL
#define to_address (0xffffc000)
-#define to_pgprot PAGE_KERNEL
#define TOP_PTE(x) pte_offset_kernel(top_pmd, x)
@@ -34,7 +32,7 @@ static DEFINE_SPINLOCK(v6_lock);
* Copy the user page. No aliasing to deal with so we can just
* attack the kernel's existing mapping of these pages.
*/
-void v6_copy_user_page_nonaliasing(void *kto, const void *kfrom, unsigned long vaddr)
+static void v6_copy_user_page_nonaliasing(void *kto, const void *kfrom, unsigned long vaddr)
{
copy_page(kto, kfrom);
}
@@ -43,7 +41,7 @@ void v6_copy_user_page_nonaliasing(void *kto, const void *kfrom, unsigned long v
* Clear the user page. No aliasing to deal with so we can just
* attack the kernel's existing mapping of this page.
*/
-void v6_clear_user_page_nonaliasing(void *kaddr, unsigned long vaddr)
+static void v6_clear_user_page_nonaliasing(void *kaddr, unsigned long vaddr)
{
clear_page(kaddr);
}
@@ -51,7 +49,7 @@ void v6_clear_user_page_nonaliasing(void *kaddr, unsigned long vaddr)
/*
* Copy the page, taking account of the cache colour.
*/
-void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vaddr)
+static void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vaddr)
{
unsigned int offset = CACHE_COLOUR(vaddr);
unsigned long from, to;
@@ -72,8 +70,8 @@ void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vadd
*/
spin_lock(&v6_lock);
- set_pte(TOP_PTE(from_address) + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, from_pgprot));
- set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, to_pgprot));
+ set_pte(TOP_PTE(from_address) + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, PAGE_KERNEL));
+ set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, PAGE_KERNEL));
from = from_address + (offset << PAGE_SHIFT);
to = to_address + (offset << PAGE_SHIFT);
@@ -91,7 +89,7 @@ void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vadd
* so remap the kernel page into the same cache colour as the user
* page.
*/
-void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr)
+static void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr)
{
unsigned int offset = CACHE_COLOUR(vaddr);
unsigned long to = to_address + (offset << PAGE_SHIFT);
@@ -112,7 +110,7 @@ void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr)
*/
spin_lock(&v6_lock);
- set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, to_pgprot));
+ set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, PAGE_KERNEL));
flush_tlb_kernel_page(to);
clear_page((void *)to);
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index be4ab3d73c91..7fc1b35a6746 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -26,6 +26,11 @@ static unsigned long shared_pte_mask = L_PTE_CACHEABLE;
/*
* We take the easy way out of this problem - we make the
* PTE uncacheable. However, we leave the write buffer on.
+ *
+ * Note that the pte lock held when calling update_mmu_cache must also
+ * guard the pte (somewhere else in the same mm) that we modify here.
+ * Therefore those configurations which might call adjust_pte (those
+ * without CONFIG_CPU_CACHE_VIPT) cannot support split page_table_lock.
*/
static int adjust_pte(struct vm_area_struct *vma, unsigned long address)
{
@@ -127,7 +132,7 @@ void __flush_dcache_page(struct address_space *mapping, struct page *page);
* 2. If we have multiple shared mappings of the same space in
* an object, we need to deal with the cache aliasing issues.
*
- * Note that the page_table_lock will be held.
+ * Note that the pte lock will be held.
*/
void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
{
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index f4496813615a..fd079ff1fc53 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -363,20 +363,16 @@ static void __init bootmem_init(struct meminfo *mi)
memcpy(&meminfo, mi, sizeof(meminfo));
-#ifdef CONFIG_XIP_KERNEL
-#error needs fixing
- p->pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & PMD_MASK);
- p->virtual = (unsigned long)&_stext & PMD_MASK;
- p->length = ((unsigned long)&_etext - p->virtual + ~PMD_MASK) & PMD_MASK;
- p->type = MT_ROM;
- p ++;
-#endif
-
/*
* Clear out all the mappings below the kernel image.
- * FIXME: what about XIP?
*/
- for (addr = 0; addr < PAGE_OFFSET; addr += PGDIR_SIZE)
+ for (addr = 0; addr < MODULE_START; addr += PGDIR_SIZE)
+ pmd_clear(pmd_off_k(addr));
+#ifdef CONFIG_XIP_KERNEL
+ /* The XIP kernel is mapped in the module area -- skip over it */
+ addr = ((unsigned long)&_etext + PGDIR_SIZE - 1) & PGDIR_MASK;
+#endif
+ for ( ; addr < PAGE_OFFSET; addr += PGDIR_SIZE)
pmd_clear(pmd_off_k(addr));
/*
@@ -436,6 +432,18 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
pmd_clear(pmd_off_k(addr));
/*
+ * Map the kernel if it is XIP.
+ * It is always first in the modulearea.
+ */
+#ifdef CONFIG_XIP_KERNEL
+ map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & PGDIR_MASK);
+ map.virtual = MODULE_START;
+ map.length = ((unsigned long)&_etext - map.virtual + ~PGDIR_MASK) & PGDIR_MASK;
+ map.type = MT_ROM;
+ create_mapping(&map);
+#endif
+
+ /*
* Map the cache flushing regions.
*/
#ifdef FLUSH_BASE
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 6fb1258df1b5..0f128c28fee4 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -75,7 +75,7 @@ remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
pgprot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_WRITE | flags);
do {
- pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
+ pte_t * pte = pte_alloc_kernel(pmd, address);
if (!pte)
return -ENOMEM;
remap_area_pte(pte, address, end - address, address + phys_addr, pgprot);
@@ -97,7 +97,6 @@ remap_area_pages(unsigned long start, unsigned long phys_addr,
phys_addr -= address;
dir = pgd_offset(&init_mm, address);
BUG_ON(address >= end);
- spin_lock(&init_mm.page_table_lock);
do {
pmd_t *pmd = pmd_alloc(&init_mm, dir, address);
if (!pmd) {
@@ -114,7 +113,6 @@ remap_area_pages(unsigned long start, unsigned long phys_addr,
dir++;
} while (address && (address < end));
- spin_unlock(&init_mm.page_table_lock);
flush_cache_vmap(start, end);
return err;
}
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index 61bc2fa0511e..1221fdde1769 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -180,11 +180,6 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
if (!vectors_high()) {
/*
- * This lock is here just to satisfy pmd_alloc and pte_lock
- */
- spin_lock(&mm->page_table_lock);
-
- /*
* On ARM, first page must always be allocated since it
* contains the machine vectors.
*/
@@ -201,23 +196,14 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
set_pte(new_pte, *init_pte);
pte_unmap_nested(init_pte);
pte_unmap(new_pte);
-
- spin_unlock(&mm->page_table_lock);
}
return new_pgd;
no_pte:
- spin_unlock(&mm->page_table_lock);
pmd_free(new_pmd);
- free_pages((unsigned long)new_pgd, 2);
- return NULL;
-
no_pmd:
- spin_unlock(&mm->page_table_lock);
free_pages((unsigned long)new_pgd, 2);
- return NULL;
-
no_pgd:
return NULL;
}
@@ -243,6 +229,7 @@ void free_pgd_slow(pgd_t *pgd)
pte = pmd_page(*pmd);
pmd_clear(pmd);
dec_page_state(nr_page_table_pages);
+ pte_lock_deinit(pte);
pte_free(pte);
pmd_free(pmd);
free:
diff --git a/arch/arm/oprofile/backtrace.c b/arch/arm/oprofile/backtrace.c
index df35c452a8bf..7c22c12618cc 100644
--- a/arch/arm/oprofile/backtrace.c
+++ b/arch/arm/oprofile/backtrace.c
@@ -49,42 +49,22 @@ static struct frame_tail* kernel_backtrace(struct frame_tail *tail)
static struct frame_tail* user_backtrace(struct frame_tail *tail)
{
- struct frame_tail buftail;
+ struct frame_tail buftail[2];
- /* hardware pte might not be valid due to dirty/accessed bit emulation
- * so we use copy_from_user and benefit from exception fixups */
- if (copy_from_user(&buftail, tail, sizeof(struct frame_tail)))
+ /* Also check accessibility of one struct frame_tail beyond */
+ if (!access_ok(VERIFY_READ, tail, sizeof(buftail)))
+ return NULL;
+ if (__copy_from_user_inatomic(buftail, tail, sizeof(buftail)))
return NULL;
- oprofile_add_trace(buftail.lr);
+ oprofile_add_trace(buftail[0].lr);
/* frame pointers should strictly progress back up the stack
* (towards higher addresses) */
- if (tail >= buftail.fp)
+ if (tail >= buftail[0].fp)
return NULL;
- return buftail.fp-1;
-}
-
-/* Compare two addresses and see if they're on the same page */
-#define CMP_ADDR_EQUAL(x,y,offset) ((((unsigned long) x) >> PAGE_SHIFT) \
- == ((((unsigned long) y) + offset) >> PAGE_SHIFT))
-
-/* check that the page(s) containing the frame tail are present */
-static int pages_present(struct frame_tail *tail)
-{
- struct mm_struct * mm = current->mm;
-
- if (!check_user_page_readable(mm, (unsigned long)tail))
- return 0;
-
- if (CMP_ADDR_EQUAL(tail, tail, 8))
- return 1;
-
- if (!check_user_page_readable(mm, ((unsigned long)tail) + 8))
- return 0;
-
- return 1;
+ return buftail[0].fp-1;
}
/*
@@ -118,7 +98,6 @@ static int valid_kernel_stack(struct frame_tail *tail, struct pt_regs *regs)
void arm_backtrace(struct pt_regs * const regs, unsigned int depth)
{
struct frame_tail *tail;
- unsigned long last_address = 0;
tail = ((struct frame_tail *) regs->ARM_fp) - 1;
@@ -132,13 +111,6 @@ void arm_backtrace(struct pt_regs * const regs, unsigned int depth)
return;
}
- while (depth-- && tail && !((unsigned long) tail & 3)) {
- if ((!CMP_ADDR_EQUAL(last_address, tail, 0)
- || !CMP_ADDR_EQUAL(last_address, tail, 8))
- && !pages_present(tail))
- return;
- last_address = (unsigned long) tail;
+ while (depth-- && tail && !((unsigned long) tail & 3))
tail = user_backtrace(tail);
- }
}
-
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index 52a58b2da288..a020fe16428f 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -13,6 +13,7 @@
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/err.h>
+#include <linux/string.h>
#include <asm/io.h>
#include <asm/semaphore.h>
diff --git a/arch/arm26/kernel/ptrace.c b/arch/arm26/kernel/ptrace.c
index 8a52124de0e1..cf7e977d18c8 100644
--- a/arch/arm26/kernel/ptrace.c
+++ b/arch/arm26/kernel/ptrace.c
@@ -665,7 +665,7 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
return ret;
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
int ret;
diff --git a/arch/arm26/kernel/time.c b/arch/arm26/kernel/time.c
index e66aedd02fad..335525339ad6 100644
--- a/arch/arm26/kernel/time.c
+++ b/arch/arm26/kernel/time.c
@@ -34,10 +34,6 @@
#include <asm/irq.h>
#include <asm/ioc.h>
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
extern unsigned long wall_jiffies;
/* this needs a better home */
diff --git a/arch/arm26/mm/memc.c b/arch/arm26/mm/memc.c
index 8e8a2bb2487d..34def6397c3c 100644
--- a/arch/arm26/mm/memc.c
+++ b/arch/arm26/mm/memc.c
@@ -79,12 +79,6 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
goto no_pgd;
/*
- * This lock is here just to satisfy pmd_alloc and pte_lock
- * FIXME: I bet we could avoid taking it pretty much altogether
- */
- spin_lock(&mm->page_table_lock);
-
- /*
* On ARM, first page must always be allocated since it contains
* the machine vectors.
*/
@@ -92,7 +86,7 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
if (!new_pmd)
goto no_pmd;
- new_pte = pte_alloc_kernel(mm, new_pmd, 0);
+ new_pte = pte_alloc_map(mm, new_pmd, 0);
if (!new_pte)
goto no_pte;
@@ -101,6 +95,7 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
init_pte = pte_offset(init_pmd, 0);
set_pte(new_pte, *init_pte);
+ pte_unmap(new_pte);
/*
* the page table entries are zeroed
@@ -112,23 +107,14 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR,
(PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t));
- spin_unlock(&mm->page_table_lock);
-
/* update MEMC tables */
cpu_memc_update_all(new_pgd);
return new_pgd;
no_pte:
- spin_unlock(&mm->page_table_lock);
pmd_free(new_pmd);
- free_pgd_slow(new_pgd);
- return NULL;
-
no_pmd:
- spin_unlock(&mm->page_table_lock);
free_pgd_slow(new_pgd);
- return NULL;
-
no_pgd:
return NULL;
}
diff --git a/arch/cris/arch-v10/drivers/axisflashmap.c b/arch/cris/arch-v10/drivers/axisflashmap.c
index 11ab3836aac6..56b038c8d482 100644
--- a/arch/cris/arch-v10/drivers/axisflashmap.c
+++ b/arch/cris/arch-v10/drivers/axisflashmap.c
@@ -140,6 +140,7 @@
#include <linux/kernel.h>
#include <linux/config.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/mtd/concat.h>
#include <linux/mtd/map.h>
diff --git a/arch/cris/arch-v32/drivers/axisflashmap.c b/arch/cris/arch-v32/drivers/axisflashmap.c
index 78ed52b1cdac..b679f983b90a 100644
--- a/arch/cris/arch-v32/drivers/axisflashmap.c
+++ b/arch/cris/arch-v32/drivers/axisflashmap.c
@@ -20,6 +20,7 @@
#include <linux/kernel.h>
#include <linux/config.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/mtd/concat.h>
#include <linux/mtd/map.h>
diff --git a/arch/cris/arch-v32/mm/tlb.c b/arch/cris/arch-v32/mm/tlb.c
index 8233406798d3..b08a28bb58ab 100644
--- a/arch/cris/arch-v32/mm/tlb.c
+++ b/arch/cris/arch-v32/mm/tlb.c
@@ -175,6 +175,8 @@ init_new_context(struct task_struct *tsk, struct mm_struct *mm)
return 0;
}
+static DEFINE_SPINLOCK(mmu_context_lock);
+
/* Called in schedule() just before actually doing the switch_to. */
void
switch_mm(struct mm_struct *prev, struct mm_struct *next,
@@ -183,10 +185,10 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
int cpu = smp_processor_id();
/* Make sure there is a MMU context. */
- spin_lock(&next->page_table_lock);
+ spin_lock(&mmu_context_lock);
get_mmu_context(next);
cpu_set(cpu, next->cpu_vm_mask);
- spin_unlock(&next->page_table_lock);
+ spin_unlock(&mmu_context_lock);
/*
* Remember the pgd for the fault handlers. Keep a seperate copy of it
diff --git a/arch/cris/kernel/time.c b/arch/cris/kernel/time.c
index a2d99b4aedcd..66ba8898db07 100644
--- a/arch/cris/kernel/time.c
+++ b/arch/cris/kernel/time.c
@@ -31,10 +31,7 @@
#include <linux/timex.h>
#include <linux/init.h>
#include <linux/profile.h>
-
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
+#include <linux/sched.h> /* just for sched_clock() - funny that */
int have_rtc; /* used to remember if we have an RTC or not */;
diff --git a/arch/cris/mm/ioremap.c b/arch/cris/mm/ioremap.c
index ebba11e270fa..a92ac9877582 100644
--- a/arch/cris/mm/ioremap.c
+++ b/arch/cris/mm/ioremap.c
@@ -52,7 +52,7 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned lo
if (address >= end)
BUG();
do {
- pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
+ pte_t * pte = pte_alloc_kernel(pmd, address);
if (!pte)
return -ENOMEM;
remap_area_pte(pte, address, end - address, address + phys_addr, prot);
@@ -74,7 +74,6 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr,
flush_cache_all();
if (address >= end)
BUG();
- spin_lock(&init_mm.page_table_lock);
do {
pud_t *pud;
pmd_t *pmd;
@@ -94,7 +93,6 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr,
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
} while (address && (address < end));
- spin_unlock(&init_mm.page_table_lock);
flush_tlb_all();
return error;
}
diff --git a/arch/frv/kernel/ptrace.c b/arch/frv/kernel/ptrace.c
index cbe03cba9f02..cb335a14a315 100644
--- a/arch/frv/kernel/ptrace.c
+++ b/arch/frv/kernel/ptrace.c
@@ -106,7 +106,7 @@ void ptrace_enable(struct task_struct *child)
child->thread.frame0->__status |= REG__STATUS_STEP;
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
unsigned long tmp;
diff --git a/arch/frv/kernel/time.c b/arch/frv/kernel/time.c
index 8d6558b00e44..2e9741227b73 100644
--- a/arch/frv/kernel/time.c
+++ b/arch/frv/kernel/time.c
@@ -34,9 +34,6 @@
extern unsigned long wall_jiffies;
-u64 jiffies_64 = INITIAL_JIFFIES;
-EXPORT_SYMBOL(jiffies_64);
-
unsigned long __nongprelbss __clkin_clock_speed_HZ;
unsigned long __nongprelbss __ext_bus_clock_speed_HZ;
unsigned long __nongprelbss __res_bus_clock_speed_HZ;
@@ -221,6 +218,7 @@ int do_settimeofday(struct timespec *tv)
clock_was_set();
return 0;
}
+EXPORT_SYMBOL(do_settimeofday);
/*
* Scheduler clock - returns current time in nanosec units.
diff --git a/arch/frv/mm/dma-alloc.c b/arch/frv/mm/dma-alloc.c
index cfc4f97490c6..342823aad758 100644
--- a/arch/frv/mm/dma-alloc.c
+++ b/arch/frv/mm/dma-alloc.c
@@ -55,21 +55,18 @@ static int map_page(unsigned long va, unsigned long pa, pgprot_t prot)
pte_t *pte;
int err = -ENOMEM;
- spin_lock(&init_mm.page_table_lock);
-
/* Use upper 10 bits of VA to index the first level map */
pge = pgd_offset_k(va);
pue = pud_offset(pge, va);
pme = pmd_offset(pue, va);
/* Use middle 10 bits of VA to index the second-level map */
- pte = pte_alloc_kernel(&init_mm, pme, va);
+ pte = pte_alloc_kernel(pme, va);
if (pte != 0) {
err = 0;
set_pte(pte, mk_pte_phys(pa & PAGE_MASK, prot));
}
- spin_unlock(&init_mm.page_table_lock);
return err;
}
diff --git a/arch/frv/mm/pgalloc.c b/arch/frv/mm/pgalloc.c
index 4eaec0f3525b..2c67dfe5a6b3 100644
--- a/arch/frv/mm/pgalloc.c
+++ b/arch/frv/mm/pgalloc.c
@@ -87,14 +87,14 @@ static inline void pgd_list_add(pgd_t *pgd)
if (pgd_list)
pgd_list->private = (unsigned long) &page->index;
pgd_list = page;
- page->private = (unsigned long) &pgd_list;
+ set_page_private(page, (unsigned long)&pgd_list);
}
static inline void pgd_list_del(pgd_t *pgd)
{
struct page *next, **pprev, *page = virt_to_page(pgd);
next = (struct page *) page->index;
- pprev = (struct page **) page->private;
+ pprev = (struct page **)page_private(page);
*pprev = next;
if (next)
next->private = (unsigned long) pprev;
diff --git a/arch/h8300/kernel/ptrace.c b/arch/h8300/kernel/ptrace.c
index 05c15e869777..a569fe4aa284 100644
--- a/arch/h8300/kernel/ptrace.c
+++ b/arch/h8300/kernel/ptrace.c
@@ -57,7 +57,7 @@ void ptrace_disable(struct task_struct *child)
h8300_disable_trace(child);
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
int ret;
diff --git a/arch/h8300/kernel/time.c b/arch/h8300/kernel/time.c
index af8c5d2057dd..688a5100604c 100644
--- a/arch/h8300/kernel/time.c
+++ b/arch/h8300/kernel/time.c
@@ -32,10 +32,6 @@
#define TICK_SIZE (tick_nsec / 1000)
-u64 jiffies_64;
-
-EXPORT_SYMBOL(jiffies_64);
-
/*
* timer_interrupt() needs to keep up the real-time clock,
* as well as call the "do_timer()" routine every clocktick
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index d2703cda61ea..5383e5e2d9b7 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -5,7 +5,7 @@
mainmenu "Linux Kernel Configuration"
-config X86
+config X86_32
bool
default y
help
@@ -18,6 +18,10 @@ config SEMAPHORE_SLEEPERS
bool
default y
+config X86
+ bool
+ default y
+
config MMU
bool
default y
@@ -151,304 +155,7 @@ config ES7000_CLUSTERED_APIC
default y
depends on SMP && X86_ES7000 && MPENTIUMIII
-if !X86_ELAN
-
-choice
- prompt "Processor family"
- default M686
-
-config M386
- bool "386"
- ---help---
- This is the processor type of your CPU. This information is used for
- optimizing purposes. In order to compile a kernel that can run on
- all x86 CPU types (albeit not optimally fast), you can specify
- "386" here.
-
- The kernel will not necessarily run on earlier architectures than
- the one you have chosen, e.g. a Pentium optimized kernel will run on
- a PPro, but not necessarily on a i486.
-
- Here are the settings recommended for greatest speed:
- - "386" for the AMD/Cyrix/Intel 386DX/DXL/SL/SLC/SX, Cyrix/TI
- 486DLC/DLC2, UMC 486SX-S and NexGen Nx586. Only "386" kernels
- will run on a 386 class machine.
- - "486" for the AMD/Cyrix/IBM/Intel 486DX/DX2/DX4 or
- SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or U5S.
- - "586" for generic Pentium CPUs lacking the TSC
- (time stamp counter) register.
- - "Pentium-Classic" for the Intel Pentium.
- - "Pentium-MMX" for the Intel Pentium MMX.
- - "Pentium-Pro" for the Intel Pentium Pro.
- - "Pentium-II" for the Intel Pentium II or pre-Coppermine Celeron.
- - "Pentium-III" for the Intel Pentium III or Coppermine Celeron.
- - "Pentium-4" for the Intel Pentium 4 or P4-based Celeron.
- - "K6" for the AMD K6, K6-II and K6-III (aka K6-3D).
- - "Athlon" for the AMD K7 family (Athlon/Duron/Thunderbird).
- - "Crusoe" for the Transmeta Crusoe series.
- - "Efficeon" for the Transmeta Efficeon series.
- - "Winchip-C6" for original IDT Winchip.
- - "Winchip-2" for IDT Winchip 2.
- - "Winchip-2A" for IDT Winchips with 3dNow! capabilities.
- - "GeodeGX1" for Geode GX1 (Cyrix MediaGX).
- - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3.
- - "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above).
-
- If you don't know what to do, choose "386".
-
-config M486
- bool "486"
- help
- Select this for a 486 series processor, either Intel or one of the
- compatible processors from AMD, Cyrix, IBM, or Intel. Includes DX,
- DX2, and DX4 variants; also SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or
- U5S.
-
-config M586
- bool "586/K5/5x86/6x86/6x86MX"
- help
- Select this for an 586 or 686 series processor such as the AMD K5,
- the Cyrix 5x86, 6x86 and 6x86MX. This choice does not
- assume the RDTSC (Read Time Stamp Counter) instruction.
-
-config M586TSC
- bool "Pentium-Classic"
- help
- Select this for a Pentium Classic processor with the RDTSC (Read
- Time Stamp Counter) instruction for benchmarking.
-
-config M586MMX
- bool "Pentium-MMX"
- help
- Select this for a Pentium with the MMX graphics/multimedia
- extended instructions.
-
-config M686
- bool "Pentium-Pro"
- help
- Select this for Intel Pentium Pro chips. This enables the use of
- Pentium Pro extended instructions, and disables the init-time guard
- against the f00f bug found in earlier Pentiums.
-
-config MPENTIUMII
- bool "Pentium-II/Celeron(pre-Coppermine)"
- help
- Select this for Intel chips based on the Pentium-II and
- pre-Coppermine Celeron core. This option enables an unaligned
- copy optimization, compiles the kernel with optimization flags
- tailored for the chip, and applies any applicable Pentium Pro
- optimizations.
-
-config MPENTIUMIII
- bool "Pentium-III/Celeron(Coppermine)/Pentium-III Xeon"
- help
- Select this for Intel chips based on the Pentium-III and
- Celeron-Coppermine core. This option enables use of some
- extended prefetch instructions in addition to the Pentium II
- extensions.
-
-config MPENTIUMM
- bool "Pentium M"
- help
- Select this for Intel Pentium M (not Pentium-4 M)
- notebook chips.
-
-config MPENTIUM4
- bool "Pentium-4/Celeron(P4-based)/Pentium-4 M/Xeon"
- help
- Select this for Intel Pentium 4 chips. This includes the
- Pentium 4, P4-based Celeron and Xeon, and Pentium-4 M
- (not Pentium M) chips. This option enables compile flags
- optimized for the chip, uses the correct cache shift, and
- applies any applicable Pentium III optimizations.
-
-config MK6
- bool "K6/K6-II/K6-III"
- help
- Select this for an AMD K6-family processor. Enables use of
- some extended instructions, and passes appropriate optimization
- flags to GCC.
-
-config MK7
- bool "Athlon/Duron/K7"
- help
- Select this for an AMD Athlon K7-family processor. Enables use of
- some extended instructions, and passes appropriate optimization
- flags to GCC.
-
-config MK8
- bool "Opteron/Athlon64/Hammer/K8"
- help
- Select this for an AMD Opteron or Athlon64 Hammer-family processor. Enables
- use of some extended instructions, and passes appropriate optimization
- flags to GCC.
-
-config MCRUSOE
- bool "Crusoe"
- help
- Select this for a Transmeta Crusoe processor. Treats the processor
- like a 586 with TSC, and sets some GCC optimization flags (like a
- Pentium Pro with no alignment requirements).
-
-config MEFFICEON
- bool "Efficeon"
- help
- Select this for a Transmeta Efficeon processor.
-
-config MWINCHIPC6
- bool "Winchip-C6"
- help
- Select this for an IDT Winchip C6 chip. Linux and GCC
- treat this chip as a 586TSC with some extended instructions
- and alignment requirements.
-
-config MWINCHIP2
- bool "Winchip-2"
- help
- Select this for an IDT Winchip-2. Linux and GCC
- treat this chip as a 586TSC with some extended instructions
- and alignment requirements.
-
-config MWINCHIP3D
- bool "Winchip-2A/Winchip-3"
- help
- Select this for an IDT Winchip-2A or 3. Linux and GCC
- treat this chip as a 586TSC with some extended instructions
- and alignment reqirements. Also enable out of order memory
- stores for this CPU, which can increase performance of some
- operations.
-
-config MGEODEGX1
- bool "GeodeGX1"
- help
- Select this for a Geode GX1 (Cyrix MediaGX) chip.
-
-config MCYRIXIII
- bool "CyrixIII/VIA-C3"
- help
- Select this for a Cyrix III or C3 chip. Presently Linux and GCC
- treat this chip as a generic 586. Whilst the CPU is 686 class,
- it lacks the cmov extension which gcc assumes is present when
- generating 686 code.
- Note that Nehemiah (Model 9) and above will not boot with this
- kernel due to them lacking the 3DNow! instructions used in earlier
- incarnations of the CPU.
-
-config MVIAC3_2
- bool "VIA C3-2 (Nehemiah)"
- help
- Select this for a VIA C3 "Nehemiah". Selecting this enables usage
- of SSE and tells gcc to treat the CPU as a 686.
- Note, this kernel will not boot on older (pre model 9) C3s.
-
-endchoice
-
-config X86_GENERIC
- bool "Generic x86 support"
- help
- Instead of just including optimizations for the selected
- x86 variant (e.g. PII, Crusoe or Athlon), include some more
- generic optimizations as well. This will make the kernel
- perform better on x86 CPUs other than that selected.
-
- This is really intended for distributors who need more
- generic optimizations.
-
-endif
-
-#
-# Define implied options from the CPU selection here
-#
-config X86_CMPXCHG
- bool
- depends on !M386
- default y
-
-config X86_XADD
- bool
- depends on !M386
- default y
-
-config X86_L1_CACHE_SHIFT
- int
- default "7" if MPENTIUM4 || X86_GENERIC
- default "4" if X86_ELAN || M486 || M386
- default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODEGX1
- default "6" if MK7 || MK8 || MPENTIUMM
-
-config RWSEM_GENERIC_SPINLOCK
- bool
- depends on M386
- default y
-
-config RWSEM_XCHGADD_ALGORITHM
- bool
- depends on !M386
- default y
-
-config GENERIC_CALIBRATE_DELAY
- bool
- default y
-
-config X86_PPRO_FENCE
- bool
- depends on M686 || M586MMX || M586TSC || M586 || M486 || M386 || MGEODEGX1
- default y
-
-config X86_F00F_BUG
- bool
- depends on M586MMX || M586TSC || M586 || M486 || M386
- default y
-
-config X86_WP_WORKS_OK
- bool
- depends on !M386
- default y
-
-config X86_INVLPG
- bool
- depends on !M386
- default y
-
-config X86_BSWAP
- bool
- depends on !M386
- default y
-
-config X86_POPAD_OK
- bool
- depends on !M386
- default y
-
-config X86_ALIGNMENT_16
- bool
- depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
- default y
-
-config X86_GOOD_APIC
- bool
- depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON
- default y
-
-config X86_INTEL_USERCOPY
- bool
- depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON
- default y
-
-config X86_USE_PPRO_CHECKSUM
- bool
- depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON
- default y
-
-config X86_USE_3DNOW
- bool
- depends on MCYRIXIII || MK7
- default y
-
-config X86_OOSTORE
- bool
- depends on (MWINCHIP3D || MWINCHIP2 || MWINCHIPC6) && MTRR
- default y
+source "arch/i386/Kconfig.cpu"
config HPET_TIMER
bool "HPET Timer Support"
@@ -561,11 +268,6 @@ config X86_VISWS_APIC
depends on X86_VISWS
default y
-config X86_TSC
- bool
- depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1) && !X86_NUMAQ
- default y
-
config X86_MCE
bool "Machine Check Exception"
depends on !X86_VOYAGER
diff --git a/arch/i386/Kconfig.cpu b/arch/i386/Kconfig.cpu
new file mode 100644
index 000000000000..53bbb3c008ee
--- /dev/null
+++ b/arch/i386/Kconfig.cpu
@@ -0,0 +1,309 @@
+# Put here option for CPU selection and depending optimization
+if !X86_ELAN
+
+choice
+ prompt "Processor family"
+ default M686
+
+config M386
+ bool "386"
+ ---help---
+ This is the processor type of your CPU. This information is used for
+ optimizing purposes. In order to compile a kernel that can run on
+ all x86 CPU types (albeit not optimally fast), you can specify
+ "386" here.
+
+ The kernel will not necessarily run on earlier architectures than
+ the one you have chosen, e.g. a Pentium optimized kernel will run on
+ a PPro, but not necessarily on a i486.
+
+ Here are the settings recommended for greatest speed:
+ - "386" for the AMD/Cyrix/Intel 386DX/DXL/SL/SLC/SX, Cyrix/TI
+ 486DLC/DLC2, UMC 486SX-S and NexGen Nx586. Only "386" kernels
+ will run on a 386 class machine.
+ - "486" for the AMD/Cyrix/IBM/Intel 486DX/DX2/DX4 or
+ SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or U5S.
+ - "586" for generic Pentium CPUs lacking the TSC
+ (time stamp counter) register.
+ - "Pentium-Classic" for the Intel Pentium.
+ - "Pentium-MMX" for the Intel Pentium MMX.
+ - "Pentium-Pro" for the Intel Pentium Pro.
+ - "Pentium-II" for the Intel Pentium II or pre-Coppermine Celeron.
+ - "Pentium-III" for the Intel Pentium III or Coppermine Celeron.
+ - "Pentium-4" for the Intel Pentium 4 or P4-based Celeron.
+ - "K6" for the AMD K6, K6-II and K6-III (aka K6-3D).
+ - "Athlon" for the AMD K7 family (Athlon/Duron/Thunderbird).
+ - "Crusoe" for the Transmeta Crusoe series.
+ - "Efficeon" for the Transmeta Efficeon series.
+ - "Winchip-C6" for original IDT Winchip.
+ - "Winchip-2" for IDT Winchip 2.
+ - "Winchip-2A" for IDT Winchips with 3dNow! capabilities.
+ - "GeodeGX1" for Geode GX1 (Cyrix MediaGX).
+ - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3.
+ - "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above).
+
+ If you don't know what to do, choose "386".
+
+config M486
+ bool "486"
+ help
+ Select this for a 486 series processor, either Intel or one of the
+ compatible processors from AMD, Cyrix, IBM, or Intel. Includes DX,
+ DX2, and DX4 variants; also SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or
+ U5S.
+
+config M586
+ bool "586/K5/5x86/6x86/6x86MX"
+ help
+ Select this for an 586 or 686 series processor such as the AMD K5,
+ the Cyrix 5x86, 6x86 and 6x86MX. This choice does not
+ assume the RDTSC (Read Time Stamp Counter) instruction.
+
+config M586TSC
+ bool "Pentium-Classic"
+ help
+ Select this for a Pentium Classic processor with the RDTSC (Read
+ Time Stamp Counter) instruction for benchmarking.
+
+config M586MMX
+ bool "Pentium-MMX"
+ help
+ Select this for a Pentium with the MMX graphics/multimedia
+ extended instructions.
+
+config M686
+ bool "Pentium-Pro"
+ help
+ Select this for Intel Pentium Pro chips. This enables the use of
+ Pentium Pro extended instructions, and disables the init-time guard
+ against the f00f bug found in earlier Pentiums.
+
+config MPENTIUMII
+ bool "Pentium-II/Celeron(pre-Coppermine)"
+ help
+ Select this for Intel chips based on the Pentium-II and
+ pre-Coppermine Celeron core. This option enables an unaligned
+ copy optimization, compiles the kernel with optimization flags
+ tailored for the chip, and applies any applicable Pentium Pro
+ optimizations.
+
+config MPENTIUMIII
+ bool "Pentium-III/Celeron(Coppermine)/Pentium-III Xeon"
+ help
+ Select this for Intel chips based on the Pentium-III and
+ Celeron-Coppermine core. This option enables use of some
+ extended prefetch instructions in addition to the Pentium II
+ extensions.
+
+config MPENTIUMM
+ bool "Pentium M"
+ help
+ Select this for Intel Pentium M (not Pentium-4 M)
+ notebook chips.
+
+config MPENTIUM4
+ bool "Pentium-4/Celeron(P4-based)/Pentium-4 M/Xeon"
+ help
+ Select this for Intel Pentium 4 chips. This includes the
+ Pentium 4, P4-based Celeron and Xeon, and Pentium-4 M
+ (not Pentium M) chips. This option enables compile flags
+ optimized for the chip, uses the correct cache shift, and
+ applies any applicable Pentium III optimizations.
+
+config MK6
+ bool "K6/K6-II/K6-III"
+ help
+ Select this for an AMD K6-family processor. Enables use of
+ some extended instructions, and passes appropriate optimization
+ flags to GCC.
+
+config MK7
+ bool "Athlon/Duron/K7"
+ help
+ Select this for an AMD Athlon K7-family processor. Enables use of
+ some extended instructions, and passes appropriate optimization
+ flags to GCC.
+
+config MK8
+ bool "Opteron/Athlon64/Hammer/K8"
+ help
+ Select this for an AMD Opteron or Athlon64 Hammer-family processor. Enables
+ use of some extended instructions, and passes appropriate optimization
+ flags to GCC.
+
+config MCRUSOE
+ bool "Crusoe"
+ help
+ Select this for a Transmeta Crusoe processor. Treats the processor
+ like a 586 with TSC, and sets some GCC optimization flags (like a
+ Pentium Pro with no alignment requirements).
+
+config MEFFICEON
+ bool "Efficeon"
+ help
+ Select this for a Transmeta Efficeon processor.
+
+config MWINCHIPC6
+ bool "Winchip-C6"
+ help
+ Select this for an IDT Winchip C6 chip. Linux and GCC
+ treat this chip as a 586TSC with some extended instructions
+ and alignment requirements.
+
+config MWINCHIP2
+ bool "Winchip-2"
+ help
+ Select this for an IDT Winchip-2. Linux and GCC
+ treat this chip as a 586TSC with some extended instructions
+ and alignment requirements.
+
+config MWINCHIP3D
+ bool "Winchip-2A/Winchip-3"
+ help
+ Select this for an IDT Winchip-2A or 3. Linux and GCC
+ treat this chip as a 586TSC with some extended instructions
+ and alignment reqirements. Also enable out of order memory
+ stores for this CPU, which can increase performance of some
+ operations.
+
+config MGEODEGX1
+ bool "GeodeGX1"
+ help
+ Select this for a Geode GX1 (Cyrix MediaGX) chip.
+
+config MCYRIXIII
+ bool "CyrixIII/VIA-C3"
+ help
+ Select this for a Cyrix III or C3 chip. Presently Linux and GCC
+ treat this chip as a generic 586. Whilst the CPU is 686 class,
+ it lacks the cmov extension which gcc assumes is present when
+ generating 686 code.
+ Note that Nehemiah (Model 9) and above will not boot with this
+ kernel due to them lacking the 3DNow! instructions used in earlier
+ incarnations of the CPU.
+
+config MVIAC3_2
+ bool "VIA C3-2 (Nehemiah)"
+ help
+ Select this for a VIA C3 "Nehemiah". Selecting this enables usage
+ of SSE and tells gcc to treat the CPU as a 686.
+ Note, this kernel will not boot on older (pre model 9) C3s.
+
+endchoice
+
+config X86_GENERIC
+ bool "Generic x86 support"
+ help
+ Instead of just including optimizations for the selected
+ x86 variant (e.g. PII, Crusoe or Athlon), include some more
+ generic optimizations as well. This will make the kernel
+ perform better on x86 CPUs other than that selected.
+
+ This is really intended for distributors who need more
+ generic optimizations.
+
+endif
+
+#
+# Define implied options from the CPU selection here
+#
+config X86_CMPXCHG
+ bool
+ depends on !M386
+ default y
+
+config X86_XADD
+ bool
+ depends on !M386
+ default y
+
+config X86_L1_CACHE_SHIFT
+ int
+ default "7" if MPENTIUM4 || X86_GENERIC
+ default "4" if X86_ELAN || M486 || M386
+ default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODEGX1
+ default "6" if MK7 || MK8 || MPENTIUMM
+
+config RWSEM_GENERIC_SPINLOCK
+ bool
+ depends on M386
+ default y
+
+config RWSEM_XCHGADD_ALGORITHM
+ bool
+ depends on !M386
+ default y
+
+config GENERIC_CALIBRATE_DELAY
+ bool
+ default y
+
+config X86_PPRO_FENCE
+ bool
+ depends on M686 || M586MMX || M586TSC || M586 || M486 || M386 || MGEODEGX1
+ default y
+
+config X86_F00F_BUG
+ bool
+ depends on M586MMX || M586TSC || M586 || M486 || M386
+ default y
+
+config X86_WP_WORKS_OK
+ bool
+ depends on !M386
+ default y
+
+config X86_INVLPG
+ bool
+ depends on !M386
+ default y
+
+config X86_BSWAP
+ bool
+ depends on !M386
+ default y
+
+config X86_POPAD_OK
+ bool
+ depends on !M386
+ default y
+
+config X86_CMPXCHG64
+ bool
+ depends on !M386 && !M486
+ default y
+
+config X86_ALIGNMENT_16
+ bool
+ depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
+ default y
+
+config X86_GOOD_APIC
+ bool
+ depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON
+ default y
+
+config X86_INTEL_USERCOPY
+ bool
+ depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON
+ default y
+
+config X86_USE_PPRO_CHECKSUM
+ bool
+ depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON
+ default y
+
+config X86_USE_3DNOW
+ bool
+ depends on MCYRIXIII || MK7
+ default y
+
+config X86_OOSTORE
+ bool
+ depends on (MWINCHIP3D || MWINCHIP2 || MWINCHIPC6) && MTRR
+ default y
+
+config X86_TSC
+ bool
+ depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1) && !X86_NUMAQ
+ default y
diff --git a/arch/i386/Makefile b/arch/i386/Makefile
index 09951990a622..d121ea18460f 100644
--- a/arch/i386/Makefile
+++ b/arch/i386/Makefile
@@ -34,35 +34,8 @@ CFLAGS += -pipe -msoft-float
# prevent gcc from keeping the stack 16 byte aligned
CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2)
-align := $(cc-option-align)
-cflags-$(CONFIG_M386) += -march=i386
-cflags-$(CONFIG_M486) += -march=i486
-cflags-$(CONFIG_M586) += -march=i586
-cflags-$(CONFIG_M586TSC) += -march=i586
-cflags-$(CONFIG_M586MMX) += $(call cc-option,-march=pentium-mmx,-march=i586)
-cflags-$(CONFIG_M686) += -march=i686
-cflags-$(CONFIG_MPENTIUMII) += -march=i686 $(call cc-option,-mtune=pentium2)
-cflags-$(CONFIG_MPENTIUMIII) += -march=i686 $(call cc-option,-mtune=pentium3)
-cflags-$(CONFIG_MPENTIUMM) += -march=i686 $(call cc-option,-mtune=pentium3)
-cflags-$(CONFIG_MPENTIUM4) += -march=i686 $(call cc-option,-mtune=pentium4)
-cflags-$(CONFIG_MK6) += -march=k6
-# Please note, that patches that add -march=athlon-xp and friends are pointless.
-# They make zero difference whatsosever to performance at this time.
-cflags-$(CONFIG_MK7) += $(call cc-option,-march=athlon,-march=i686 $(align)-functions=4)
-cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8,$(call cc-option,-march=athlon,-march=i686 $(align)-functions=4))
-cflags-$(CONFIG_MCRUSOE) += -march=i686 $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
-cflags-$(CONFIG_MEFFICEON) += -march=i686 $(call cc-option,-mtune=pentium3) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
-cflags-$(CONFIG_MWINCHIPC6) += $(call cc-option,-march=winchip-c6,-march=i586)
-cflags-$(CONFIG_MWINCHIP2) += $(call cc-option,-march=winchip2,-march=i586)
-cflags-$(CONFIG_MWINCHIP3D) += $(call cc-option,-march=winchip2,-march=i586)
-cflags-$(CONFIG_MCYRIXIII) += $(call cc-option,-march=c3,-march=i486) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
-cflags-$(CONFIG_MVIAC3_2) += $(call cc-option,-march=c3-2,-march=i686)
-
-# AMD Elan support
-cflags-$(CONFIG_X86_ELAN) += -march=i486
-
-# Geode GX1 support
-cflags-$(CONFIG_MGEODEGX1) += $(call cc-option,-march=pentium-mmx,-march=i486)
+# CPU-specific tuning. Anything which can be shared with UML should go here.
+include $(srctree)/arch/i386/Makefile.cpu
# -mregparm=3 works ok on gcc-3.0 and later
#
diff --git a/arch/i386/Makefile.cpu b/arch/i386/Makefile.cpu
new file mode 100644
index 000000000000..8e51456df23d
--- /dev/null
+++ b/arch/i386/Makefile.cpu
@@ -0,0 +1,41 @@
+# CPU tuning section - shared with UML.
+# Must change only cflags-y (or [yn]), not CFLAGS! That makes a difference for UML.
+
+#-mtune exists since gcc 3.4, and some -mcpu flavors didn't exist in gcc 2.95.
+HAS_MTUNE := $(call cc-option-yn, -mtune=i386)
+ifeq ($(HAS_MTUNE),y)
+tune = $(call cc-option,-mtune=$(1),)
+else
+tune = $(call cc-option,-mcpu=$(1),)
+endif
+
+align := $(cc-option-align)
+cflags-$(CONFIG_M386) += -march=i386
+cflags-$(CONFIG_M486) += -march=i486
+cflags-$(CONFIG_M586) += -march=i586
+cflags-$(CONFIG_M586TSC) += -march=i586
+cflags-$(CONFIG_M586MMX) += $(call cc-option,-march=pentium-mmx,-march=i586)
+cflags-$(CONFIG_M686) += -march=i686
+cflags-$(CONFIG_MPENTIUMII) += -march=i686 $(call tune,pentium2)
+cflags-$(CONFIG_MPENTIUMIII) += -march=i686 $(call tune,pentium3)
+cflags-$(CONFIG_MPENTIUMM) += -march=i686 $(call tune,pentium3)
+cflags-$(CONFIG_MPENTIUM4) += -march=i686 $(call tune,pentium4)
+cflags-$(CONFIG_MK6) += -march=k6
+# Please note, that patches that add -march=athlon-xp and friends are pointless.
+# They make zero difference whatsosever to performance at this time.
+cflags-$(CONFIG_MK7) += $(call cc-option,-march=athlon,-march=i686 $(align)-functions=4)
+cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8,$(call cc-option,-march=athlon,-march=i686 $(align)-functions=4))
+cflags-$(CONFIG_MCRUSOE) += -march=i686 $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
+cflags-$(CONFIG_MEFFICEON) += -march=i686 $(call tune,pentium3) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
+cflags-$(CONFIG_MWINCHIPC6) += $(call cc-option,-march=winchip-c6,-march=i586)
+cflags-$(CONFIG_MWINCHIP2) += $(call cc-option,-march=winchip2,-march=i586)
+cflags-$(CONFIG_MWINCHIP3D) += $(call cc-option,-march=winchip2,-march=i586)
+cflags-$(CONFIG_MCYRIXIII) += $(call cc-option,-march=c3,-march=i486) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
+cflags-$(CONFIG_MVIAC3_2) += $(call cc-option,-march=c3-2,-march=i686)
+
+# AMD Elan support
+cflags-$(CONFIG_X86_ELAN) += -march=i486
+
+# Geode GX1 support
+cflags-$(CONFIG_MGEODEGX1) += $(call cc-option,-march=pentium-mmx,-march=i486)
+
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index 5546ddebec33..9204be6eedb3 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -803,6 +803,7 @@ no_apic:
void __init init_apic_mappings(void)
{
+ unsigned int orig_apicid;
unsigned long apic_phys;
/*
@@ -824,8 +825,11 @@ void __init init_apic_mappings(void)
* Fetch the APIC ID of the BSP in case we have a
* default configuration (or the MP table is broken).
*/
- if (boot_cpu_physical_apicid == -1U)
- boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
+ orig_apicid = boot_cpu_physical_apicid;
+ boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
+ if ((orig_apicid != -1U) && (orig_apicid != boot_cpu_physical_apicid))
+ printk(KERN_WARNING "Boot APIC ID in local APIC unexpected (%d vs %d)",
+ orig_apicid, boot_cpu_physical_apicid);
#ifdef CONFIG_X86_IO_APIC
{
@@ -1046,10 +1050,11 @@ static unsigned int calibration_result;
void __init setup_boot_APIC_clock(void)
{
+ unsigned long flags;
apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n");
using_apic_timer = 1;
- local_irq_disable();
+ local_irq_save(flags);
calibration_result = calibrate_APIC_clock();
/*
@@ -1057,7 +1062,7 @@ void __init setup_boot_APIC_clock(void)
*/
setup_APIC_timer(calibration_result);
- local_irq_enable();
+ local_irq_restore(flags);
}
void __devinit setup_secondary_APIC_clock(void)
@@ -1254,40 +1259,81 @@ fastcall void smp_error_interrupt(struct pt_regs *regs)
}
/*
- * This initializes the IO-APIC and APIC hardware if this is
- * a UP kernel.
+ * This initializes the IO-APIC and APIC hardware.
*/
-int __init APIC_init_uniprocessor (void)
+int __init APIC_init(void)
{
- if (enable_local_apic < 0)
- clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
+ if (enable_local_apic < 0) {
+ printk(KERN_INFO "APIC disabled\n");
+ return -1;
+ }
- if (!smp_found_config && !cpu_has_apic)
+ /* See if we have a SMP configuration or have forced enabled
+ * the local apic.
+ */
+ if (!smp_found_config && !acpi_lapic && !cpu_has_apic) {
+ enable_local_apic = -1;
return -1;
+ }
/*
- * Complain if the BIOS pretends there is one.
+ * Complain if the BIOS pretends there is an apic.
+ * Then get out because we don't have an a local apic.
*/
if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
boot_cpu_physical_apicid);
+ printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
+ enable_local_apic = -1;
return -1;
}
verify_local_APIC();
+ /*
+ * Should not be necessary because the MP table should list the boot
+ * CPU too, but we do it for the sake of robustness anyway.
+ * Makes no sense to do this check in clustered apic mode, so skip it
+ */
+ if (!check_phys_apicid_present(boot_cpu_physical_apicid)) {
+ printk("weird, boot CPU (#%d) not listed by the BIOS.\n",
+ boot_cpu_physical_apicid);
+ physid_set(boot_cpu_physical_apicid, phys_cpu_present_map);
+ }
+
+ /*
+ * Switch from PIC to APIC mode.
+ */
connect_bsp_APIC();
+ setup_local_APIC();
- phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid);
+#ifdef CONFIG_X86_IO_APIC
+ /*
+ * Now start the IO-APICs
+ */
+ if (smp_found_config && !skip_ioapic_setup && nr_ioapics)
+ setup_IO_APIC();
+#endif
+ return 0;
+}
- setup_local_APIC();
+void __init APIC_late_time_init(void)
+{
+ /* Improve our loops per jiffy estimate */
+ loops_per_jiffy = ((1000 + HZ - 1)/HZ)*cpu_khz;
+ boot_cpu_data.loops_per_jiffy = loops_per_jiffy;
+ cpu_data[0].loops_per_jiffy = loops_per_jiffy;
+
+ /* setup_apic_nmi_watchdog doesn't work properly before cpu_khz is
+ * initialized. So redo it here to ensure the boot cpu is setup
+ * properly.
+ */
+ if (nmi_watchdog == NMI_LOCAL_APIC)
+ setup_apic_nmi_watchdog();
#ifdef CONFIG_X86_IO_APIC
- if (smp_found_config)
- if (!skip_ioapic_setup && nr_ioapics)
- setup_IO_APIC();
+ if (smp_found_config && !skip_ioapic_setup && nr_ioapics)
+ IO_APIC_late_time_init();
#endif
setup_boot_APIC_clock();
-
- return 0;
}
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index d7811c4e8b50..d2ef0c2aa93e 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -597,12 +597,14 @@ static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in,
cpumask_t cpus;
int cpu;
struct desc_struct save_desc_40;
+ struct desc_struct *gdt;
cpus = apm_save_cpus();
cpu = get_cpu();
- save_desc_40 = per_cpu(cpu_gdt_table, cpu)[0x40 / 8];
- per_cpu(cpu_gdt_table, cpu)[0x40 / 8] = bad_bios_desc;
+ gdt = get_cpu_gdt_table(cpu);
+ save_desc_40 = gdt[0x40 / 8];
+ gdt[0x40 / 8] = bad_bios_desc;
local_save_flags(flags);
APM_DO_CLI;
@@ -610,7 +612,7 @@ static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in,
apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
APM_DO_RESTORE_SEGS;
local_irq_restore(flags);
- per_cpu(cpu_gdt_table, cpu)[0x40 / 8] = save_desc_40;
+ gdt[0x40 / 8] = save_desc_40;
put_cpu();
apm_restore_cpus(cpus);
@@ -639,13 +641,14 @@ static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax)
cpumask_t cpus;
int cpu;
struct desc_struct save_desc_40;
-
+ struct desc_struct *gdt;
cpus = apm_save_cpus();
cpu = get_cpu();
- save_desc_40 = per_cpu(cpu_gdt_table, cpu)[0x40 / 8];
- per_cpu(cpu_gdt_table, cpu)[0x40 / 8] = bad_bios_desc;
+ gdt = get_cpu_gdt_table(cpu);
+ save_desc_40 = gdt[0x40 / 8];
+ gdt[0x40 / 8] = bad_bios_desc;
local_save_flags(flags);
APM_DO_CLI;
@@ -653,7 +656,7 @@ static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax)
error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
APM_DO_RESTORE_SEGS;
local_irq_restore(flags);
- __get_cpu_var(cpu_gdt_table)[0x40 / 8] = save_desc_40;
+ gdt[0x40 / 8] = save_desc_40;
put_cpu();
apm_restore_cpus(cpus);
return error;
@@ -2295,35 +2298,36 @@ static int __init apm_init(void)
apm_bios_entry.segment = APM_CS;
for (i = 0; i < NR_CPUS; i++) {
- set_base(per_cpu(cpu_gdt_table, i)[APM_CS >> 3],
+ struct desc_struct *gdt = get_cpu_gdt_table(i);
+ set_base(gdt[APM_CS >> 3],
__va((unsigned long)apm_info.bios.cseg << 4));
- set_base(per_cpu(cpu_gdt_table, i)[APM_CS_16 >> 3],
+ set_base(gdt[APM_CS_16 >> 3],
__va((unsigned long)apm_info.bios.cseg_16 << 4));
- set_base(per_cpu(cpu_gdt_table, i)[APM_DS >> 3],
+ set_base(gdt[APM_DS >> 3],
__va((unsigned long)apm_info.bios.dseg << 4));
#ifndef APM_RELAX_SEGMENTS
if (apm_info.bios.version == 0x100) {
#endif
/* For ASUS motherboard, Award BIOS rev 110 (and others?) */
- _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS >> 3], 64 * 1024 - 1);
+ _set_limit((char *)&gdt[APM_CS >> 3], 64 * 1024 - 1);
/* For some unknown machine. */
- _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS_16 >> 3], 64 * 1024 - 1);
+ _set_limit((char *)&gdt[APM_CS_16 >> 3], 64 * 1024 - 1);
/* For the DEC Hinote Ultra CT475 (and others?) */
- _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_DS >> 3], 64 * 1024 - 1);
+ _set_limit((char *)&gdt[APM_DS >> 3], 64 * 1024 - 1);
#ifndef APM_RELAX_SEGMENTS
} else {
- _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS >> 3],
+ _set_limit((char *)&gdt[APM_CS >> 3],
(apm_info.bios.cseg_len - 1) & 0xffff);
- _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS_16 >> 3],
+ _set_limit((char *)&gdt[APM_CS_16 >> 3],
(apm_info.bios.cseg_16_len - 1) & 0xffff);
- _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_DS >> 3],
+ _set_limit((char *)&gdt[APM_DS >> 3],
(apm_info.bios.dseg_len - 1) & 0xffff);
/* workaround for broken BIOSes */
if (apm_info.bios.cseg_len <= apm_info.bios.offset)
- _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS >> 3], 64 * 1024 -1);
+ _set_limit((char *)&gdt[APM_CS >> 3], 64 * 1024 -1);
if (apm_info.bios.dseg_len <= 0x40) { /* 0x40 * 4kB == 64kB */
/* for the BIOS that assumes granularity = 1 */
- per_cpu(cpu_gdt_table, i)[APM_DS >> 3].b |= 0x800000;
+ gdt[APM_DS >> 3].b |= 0x800000;
printk(KERN_NOTICE "apm: we set the granularity of dseg.\n");
}
}
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index 9ad43be9a01f..74145a33cb0f 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -573,6 +573,7 @@ void __devinit cpu_init(void)
int cpu = smp_processor_id();
struct tss_struct * t = &per_cpu(init_tss, cpu);
struct thread_struct *thread = &current->thread;
+ struct desc_struct *gdt = get_cpu_gdt_table(cpu);
__u32 stk16_off = (__u32)&per_cpu(cpu_16bit_stack, cpu);
if (cpu_test_and_set(cpu, cpu_initialized)) {
@@ -594,24 +595,16 @@ void __devinit cpu_init(void)
* Initialize the per-CPU GDT with the boot GDT,
* and set up the GDT descriptor:
*/
- memcpy(&per_cpu(cpu_gdt_table, cpu), cpu_gdt_table,
- GDT_SIZE);
+ memcpy(gdt, cpu_gdt_table, GDT_SIZE);
/* Set up GDT entry for 16bit stack */
- *(__u64 *)&(per_cpu(cpu_gdt_table, cpu)[GDT_ENTRY_ESPFIX_SS]) |=
+ *(__u64 *)(&gdt[GDT_ENTRY_ESPFIX_SS]) |=
((((__u64)stk16_off) << 16) & 0x000000ffffff0000ULL) |
((((__u64)stk16_off) << 32) & 0xff00000000000000ULL) |
(CPU_16BIT_STACK_SIZE - 1);
cpu_gdt_descr[cpu].size = GDT_SIZE - 1;
- cpu_gdt_descr[cpu].address =
- (unsigned long)&per_cpu(cpu_gdt_table, cpu);
-
- /*
- * Set up the per-thread TLS descriptor cache:
- */
- memcpy(thread->tls_array, &per_cpu(cpu_gdt_table, cpu),
- GDT_ENTRY_TLS_ENTRIES * 8);
+ cpu_gdt_descr[cpu].address = (unsigned long)gdt;
load_gdt(&cpu_gdt_descr[cpu]);
load_idt(&idt_descr);
diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
index 822c8ce9d1f1..caa9f7711343 100644
--- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -32,6 +32,7 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/compiler.h>
+#include <linux/sched.h> /* current */
#include <asm/io.h>
#include <asm/delay.h>
#include <asm/uaccess.h>
diff --git a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
index aa622d52c6e5..270f2188d68b 100644
--- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
+++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
@@ -28,6 +28,7 @@
#include <linux/cpufreq.h>
#include <linux/slab.h>
#include <linux/cpumask.h>
+#include <linux/sched.h> /* current / set_cpus_allowed() */
#include <asm/processor.h>
#include <asm/msr.h>
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
index 58ca98fdc2ca..2d5c9adba0cd 100644
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
@@ -32,6 +32,7 @@
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/cpumask.h>
+#include <linux/sched.h> /* for current / set_cpus_allowed() */
#include <asm/msr.h>
#include <asm/io.h>
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
index c397b6220430..1465974256c9 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
@@ -22,6 +22,7 @@
#include <linux/init.h>
#include <linux/cpufreq.h>
#include <linux/config.h>
+#include <linux/sched.h> /* current */
#include <linux/delay.h>
#include <linux/compiler.h>
diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c
index 9e0d5f83cb9f..4dc42a189ae5 100644
--- a/arch/i386/kernel/cpu/intel_cacheinfo.c
+++ b/arch/i386/kernel/cpu/intel_cacheinfo.c
@@ -3,6 +3,7 @@
*
* Changes:
* Venkatesh Pallipadi : Adding cache identification through cpuid(4)
+ * Ashok Raj <ashok.raj@intel.com>: Work with CPU hotplug infrastructure.
*/
#include <linux/init.h>
@@ -10,6 +11,7 @@
#include <linux/device.h>
#include <linux/compiler.h>
#include <linux/cpu.h>
+#include <linux/sched.h>
#include <asm/processor.h>
#include <asm/smp.h>
@@ -28,7 +30,7 @@ struct _cache_table
};
/* all the cache descriptor types we care about (no TLB or trace cache entries) */
-static struct _cache_table cache_table[] __devinitdata =
+static struct _cache_table cache_table[] __cpuinitdata =
{
{ 0x06, LVL_1_INST, 8 }, /* 4-way set assoc, 32 byte line size */
{ 0x08, LVL_1_INST, 16 }, /* 4-way set assoc, 32 byte line size */
@@ -117,10 +119,9 @@ struct _cpuid4_info {
cpumask_t shared_cpu_map;
};
-#define MAX_CACHE_LEAVES 4
static unsigned short num_cache_leaves;
-static int __devinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
+static int __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
{
unsigned int eax, ebx, ecx, edx;
union _cpuid4_leaf_eax cache_eax;
@@ -144,23 +145,18 @@ static int __init find_num_cache_leaves(void)
{
unsigned int eax, ebx, ecx, edx;
union _cpuid4_leaf_eax cache_eax;
- int i;
- int retval;
+ int i = -1;
- retval = MAX_CACHE_LEAVES;
- /* Do cpuid(4) loop to find out num_cache_leaves */
- for (i = 0; i < MAX_CACHE_LEAVES; i++) {
+ do {
+ ++i;
+ /* Do cpuid(4) loop to find out num_cache_leaves */
cpuid_count(4, i, &eax, &ebx, &ecx, &edx);
cache_eax.full = eax;
- if (cache_eax.split.type == CACHE_TYPE_NULL) {
- retval = i;
- break;
- }
- }
- return retval;
+ } while (cache_eax.split.type != CACHE_TYPE_NULL);
+ return i;
}
-unsigned int __devinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
+unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
{
unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
@@ -284,13 +280,7 @@ unsigned int __devinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
if ( l3 )
printk(KERN_INFO "CPU: L3 cache: %dK\n", l3);
- /*
- * This assumes the L3 cache is shared; it typically lives in
- * the northbridge. The L1 caches are included by the L2
- * cache, and so should not be included for the purpose of
- * SMP switching weights.
- */
- c->x86_cache_size = l2 ? l2 : (l1i+l1d);
+ c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d));
}
return l2;
@@ -301,7 +291,7 @@ static struct _cpuid4_info *cpuid4_info[NR_CPUS];
#define CPUID4_INFO_IDX(x,y) (&((cpuid4_info[x])[y]))
#ifdef CONFIG_SMP
-static void __devinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
+static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
{
struct _cpuid4_info *this_leaf;
unsigned long num_threads_sharing;
@@ -334,7 +324,7 @@ static void free_cache_attributes(unsigned int cpu)
cpuid4_info[cpu] = NULL;
}
-static int __devinit detect_cache_attributes(unsigned int cpu)
+static int __cpuinit detect_cache_attributes(unsigned int cpu)
{
struct _cpuid4_info *this_leaf;
unsigned long j;
@@ -511,7 +501,7 @@ static void cpuid4_cache_sysfs_exit(unsigned int cpu)
free_cache_attributes(cpu);
}
-static int __devinit cpuid4_cache_sysfs_init(unsigned int cpu)
+static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu)
{
if (num_cache_leaves == 0)
@@ -542,7 +532,7 @@ err_out:
}
/* Add/Remove cache interface for CPU device */
-static int __devinit cache_add_dev(struct sys_device * sys_dev)
+static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
{
unsigned int cpu = sys_dev->id;
unsigned long i, j;
@@ -579,7 +569,7 @@ static int __devinit cache_add_dev(struct sys_device * sys_dev)
return retval;
}
-static int __devexit cache_remove_dev(struct sys_device * sys_dev)
+static void __cpuexit cache_remove_dev(struct sys_device * sys_dev)
{
unsigned int cpu = sys_dev->id;
unsigned long i;
@@ -588,24 +578,49 @@ static int __devexit cache_remove_dev(struct sys_device * sys_dev)
kobject_unregister(&(INDEX_KOBJECT_PTR(cpu,i)->kobj));
kobject_unregister(cache_kobject[cpu]);
cpuid4_cache_sysfs_exit(cpu);
- return 0;
+ return;
+}
+
+static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb,
+ unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (unsigned long)hcpu;
+ struct sys_device *sys_dev;
+
+ sys_dev = get_cpu_sysdev(cpu);
+ switch (action) {
+ case CPU_ONLINE:
+ cache_add_dev(sys_dev);
+ break;
+ case CPU_DEAD:
+ cache_remove_dev(sys_dev);
+ break;
+ }
+ return NOTIFY_OK;
}
-static struct sysdev_driver cache_sysdev_driver = {
- .add = cache_add_dev,
- .remove = __devexit_p(cache_remove_dev),
+static struct notifier_block cacheinfo_cpu_notifier =
+{
+ .notifier_call = cacheinfo_cpu_callback,
};
-/* Register/Unregister the cpu_cache driver */
-static int __devinit cache_register_driver(void)
+static int __cpuinit cache_sysfs_init(void)
{
+ int i;
+
if (num_cache_leaves == 0)
return 0;
- return sysdev_driver_register(&cpu_sysdev_class,&cache_sysdev_driver);
+ register_cpu_notifier(&cacheinfo_cpu_notifier);
+
+ for_each_online_cpu(i) {
+ cacheinfo_cpu_callback(&cacheinfo_cpu_notifier, CPU_ONLINE,
+ (void *)(long)i);
+ }
+
+ return 0;
}
-device_initcall(cache_register_driver);
+device_initcall(cache_sysfs_init);
#endif
-
diff --git a/arch/i386/kernel/cpu/mcheck/p6.c b/arch/i386/kernel/cpu/mcheck/p6.c
index 3c035b8fa3d9..979b18bc95c1 100644
--- a/arch/i386/kernel/cpu/mcheck/p6.c
+++ b/arch/i386/kernel/cpu/mcheck/p6.c
@@ -102,11 +102,16 @@ void __devinit intel_p6_mcheck_init(struct cpuinfo_x86 *c)
wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);
nr_mce_banks = l & 0xff;
- /* Don't enable bank 0 on intel P6 cores, it goes bang quickly. */
- for (i=1; i<nr_mce_banks; i++) {
+ /*
+ * 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",
diff --git a/arch/i386/kernel/cpu/mtrr/if.c b/arch/i386/kernel/cpu/mtrr/if.c
index 1923e0aed26a..cf39e205d33c 100644
--- a/arch/i386/kernel/cpu/mtrr/if.c
+++ b/arch/i386/kernel/cpu/mtrr/if.c
@@ -149,60 +149,89 @@ mtrr_write(struct file *file, const char __user *buf, size_t len, loff_t * ppos)
return -EINVAL;
}
-static int
-mtrr_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long __arg)
+static long
+mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
{
- int err;
+ int err = 0;
mtrr_type type;
struct mtrr_sentry sentry;
struct mtrr_gentry gentry;
void __user *arg = (void __user *) __arg;
switch (cmd) {
+ case MTRRIOC_ADD_ENTRY:
+ case MTRRIOC_SET_ENTRY:
+ case MTRRIOC_DEL_ENTRY:
+ case MTRRIOC_KILL_ENTRY:
+ case MTRRIOC_ADD_PAGE_ENTRY:
+ case MTRRIOC_SET_PAGE_ENTRY:
+ case MTRRIOC_DEL_PAGE_ENTRY:
+ case MTRRIOC_KILL_PAGE_ENTRY:
+ if (copy_from_user(&sentry, arg, sizeof sentry))
+ return -EFAULT;
+ break;
+ case MTRRIOC_GET_ENTRY:
+ case MTRRIOC_GET_PAGE_ENTRY:
+ if (copy_from_user(&gentry, arg, sizeof gentry))
+ return -EFAULT;
+ break;
+#ifdef CONFIG_COMPAT
+ case MTRRIOC32_ADD_ENTRY:
+ case MTRRIOC32_SET_ENTRY:
+ case MTRRIOC32_DEL_ENTRY:
+ case MTRRIOC32_KILL_ENTRY:
+ case MTRRIOC32_ADD_PAGE_ENTRY:
+ case MTRRIOC32_SET_PAGE_ENTRY:
+ case MTRRIOC32_DEL_PAGE_ENTRY:
+ case MTRRIOC32_KILL_PAGE_ENTRY: {
+ struct mtrr_sentry32 __user *s32 = (struct mtrr_sentry32 __user *)__arg;
+ err = get_user(sentry.base, &s32->base);
+ err |= get_user(sentry.size, &s32->size);
+ err |= get_user(sentry.type, &s32->type);
+ if (err)
+ return err;
+ break;
+ }
+ case MTRRIOC32_GET_ENTRY:
+ case MTRRIOC32_GET_PAGE_ENTRY: {
+ struct mtrr_gentry32 __user *g32 = (struct mtrr_gentry32 __user *)__arg;
+ err = get_user(gentry.regnum, &g32->regnum);
+ err |= get_user(gentry.base, &g32->base);
+ err |= get_user(gentry.size, &g32->size);
+ err |= get_user(gentry.type, &g32->type);
+ if (err)
+ return err;
+ break;
+ }
+#endif
+ }
+
+ switch (cmd) {
default:
return -ENOTTY;
case MTRRIOC_ADD_ENTRY:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- if (copy_from_user(&sentry, arg, sizeof sentry))
- return -EFAULT;
err =
mtrr_file_add(sentry.base, sentry.size, sentry.type, 1,
file, 0);
- if (err < 0)
- return err;
break;
case MTRRIOC_SET_ENTRY:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- if (copy_from_user(&sentry, arg, sizeof sentry))
- return -EFAULT;
err = mtrr_add(sentry.base, sentry.size, sentry.type, 0);
- if (err < 0)
- return err;
break;
case MTRRIOC_DEL_ENTRY:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- if (copy_from_user(&sentry, arg, sizeof sentry))
- return -EFAULT;
err = mtrr_file_del(sentry.base, sentry.size, file, 0);
- if (err < 0)
- return err;
break;
case MTRRIOC_KILL_ENTRY:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- if (copy_from_user(&sentry, arg, sizeof sentry))
- return -EFAULT;
err = mtrr_del(-1, sentry.base, sentry.size);
- if (err < 0)
- return err;
break;
case MTRRIOC_GET_ENTRY:
- if (copy_from_user(&gentry, arg, sizeof gentry))
- return -EFAULT;
if (gentry.regnum >= num_var_ranges)
return -EINVAL;
mtrr_if->get(gentry.regnum, &gentry.base, &gentry.size, &type);
@@ -217,60 +246,59 @@ mtrr_ioctl(struct inode *inode, struct file *file,
gentry.type = type;
}
- if (copy_to_user(arg, &gentry, sizeof gentry))
- return -EFAULT;
break;
case MTRRIOC_ADD_PAGE_ENTRY:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- if (copy_from_user(&sentry, arg, sizeof sentry))
- return -EFAULT;
err =
mtrr_file_add(sentry.base, sentry.size, sentry.type, 1,
file, 1);
- if (err < 0)
- return err;
break;
case MTRRIOC_SET_PAGE_ENTRY:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- if (copy_from_user(&sentry, arg, sizeof sentry))
- return -EFAULT;
err = mtrr_add_page(sentry.base, sentry.size, sentry.type, 0);
- if (err < 0)
- return err;
break;
case MTRRIOC_DEL_PAGE_ENTRY:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- if (copy_from_user(&sentry, arg, sizeof sentry))
- return -EFAULT;
err = mtrr_file_del(sentry.base, sentry.size, file, 1);
- if (err < 0)
- return err;
break;
case MTRRIOC_KILL_PAGE_ENTRY:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- if (copy_from_user(&sentry, arg, sizeof sentry))
- return -EFAULT;
err = mtrr_del_page(-1, sentry.base, sentry.size);
- if (err < 0)
- return err;
break;
case MTRRIOC_GET_PAGE_ENTRY:
- if (copy_from_user(&gentry, arg, sizeof gentry))
- return -EFAULT;
if (gentry.regnum >= num_var_ranges)
return -EINVAL;
mtrr_if->get(gentry.regnum, &gentry.base, &gentry.size, &type);
gentry.type = type;
+ break;
+ }
+
+ if (err)
+ return err;
+ switch(cmd) {
+ case MTRRIOC_GET_ENTRY:
+ case MTRRIOC_GET_PAGE_ENTRY:
if (copy_to_user(arg, &gentry, sizeof gentry))
- return -EFAULT;
+ err = -EFAULT;
+ break;
+#ifdef CONFIG_COMPAT
+ case MTRRIOC32_GET_ENTRY:
+ case MTRRIOC32_GET_PAGE_ENTRY: {
+ struct mtrr_gentry32 __user *g32 = (struct mtrr_gentry32 __user *)__arg;
+ err = put_user(gentry.base, &g32->base);
+ err |= put_user(gentry.size, &g32->size);
+ err |= put_user(gentry.regnum, &g32->regnum);
+ err |= put_user(gentry.type, &g32->type);
break;
}
- return 0;
+#endif
+ }
+ return err;
}
static int
@@ -310,7 +338,8 @@ static struct file_operations mtrr_fops = {
.read = seq_read,
.llseek = seq_lseek,
.write = mtrr_write,
- .ioctl = mtrr_ioctl,
+ .unlocked_ioctl = mtrr_ioctl,
+ .compat_ioctl = mtrr_ioctl,
.release = mtrr_close,
};
diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c
index 8bd77d948a84..41b871ecf4b3 100644
--- a/arch/i386/kernel/cpu/proc.c
+++ b/arch/i386/kernel/cpu/proc.c
@@ -44,7 +44,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* Intel-defined (#2) */
- "pni", NULL, NULL, "monitor", "ds_cpl", NULL, NULL, "est",
+ "pni", NULL, NULL, "monitor", "ds_cpl", "vmx", NULL, "est",
"tm2", NULL, "cid", NULL, NULL, "cx16", "xtpr", NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
diff --git a/arch/i386/kernel/crash.c b/arch/i386/kernel/crash.c
index 0248e084017c..af809ccf5fbe 100644
--- a/arch/i386/kernel/crash.c
+++ b/arch/i386/kernel/crash.c
@@ -21,7 +21,6 @@
#include <asm/hardirq.h>
#include <asm/nmi.h>
#include <asm/hw_irq.h>
-#include <asm/apic.h>
#include <mach_ipi.h>
@@ -148,7 +147,6 @@ static int crash_nmi_callback(struct pt_regs *regs, int cpu)
regs = &fixed_regs;
}
crash_save_this_cpu(regs, cpu);
- disable_local_APIC();
atomic_dec(&waiting_for_crash_ipi);
/* Assume hlt works */
halt();
@@ -188,7 +186,6 @@ static void nmi_shootdown_cpus(void)
}
/* Leave the nmi callback set */
- disable_local_APIC();
}
#else
static void nmi_shootdown_cpus(void)
@@ -213,9 +210,5 @@ void machine_crash_shutdown(struct pt_regs *regs)
/* Make a note of crashing cpu. Will be used in NMI callback.*/
crashing_cpu = smp_processor_id();
nmi_shootdown_cpus();
- lapic_shutdown();
-#if defined(CONFIG_X86_IO_APIC)
- disable_IO_APIC();
-#endif
crash_save_self(regs);
}
diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c
index 323ef8ab3244..d86f24909284 100644
--- a/arch/i386/kernel/i8259.c
+++ b/arch/i386/kernel/i8259.c
@@ -435,4 +435,8 @@ void __init init_IRQ(void)
setup_irq(FPU_IRQ, &fpu_irq);
irq_ctx_init(smp_processor_id());
+
+#ifdef CONFIG_X86_LOCAL_APIC
+ APIC_init();
+#endif
}
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index fb3991e8229e..5a77c52b20a9 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -46,6 +46,9 @@
int (*ioapic_renumber_irq)(int ioapic, int irq);
atomic_t irq_mis_count;
+/* Where if anywhere is the i8259 connect in external int mode */
+static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
+
static DEFINE_SPINLOCK(ioapic_lock);
/*
@@ -738,7 +741,7 @@ static int find_irq_entry(int apic, int pin, int type)
/*
* Find the pin to which IRQ[irq] (ISA) is connected
*/
-static int find_isa_irq_pin(int irq, int type)
+static int __init find_isa_irq_pin(int irq, int type)
{
int i;
@@ -758,6 +761,33 @@ static int find_isa_irq_pin(int irq, int type)
return -1;
}
+static int __init find_isa_irq_apic(int irq, int type)
+{
+ int i;
+
+ for (i = 0; i < mp_irq_entries; i++) {
+ int lbus = mp_irqs[i].mpc_srcbus;
+
+ if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA ||
+ mp_bus_id_to_type[lbus] == MP_BUS_EISA ||
+ mp_bus_id_to_type[lbus] == MP_BUS_MCA ||
+ mp_bus_id_to_type[lbus] == MP_BUS_NEC98
+ ) &&
+ (mp_irqs[i].mpc_irqtype == type) &&
+ (mp_irqs[i].mpc_srcbusirq == irq))
+ break;
+ }
+ if (i < mp_irq_entries) {
+ int apic;
+ for(apic = 0; apic < nr_ioapics; apic++) {
+ if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic)
+ return apic;
+ }
+ }
+
+ return -1;
+}
+
/*
* Find a specific PCI IRQ entry.
* Not an __init, possibly needed by modules
@@ -1253,7 +1283,7 @@ static void __init setup_IO_APIC_irqs(void)
/*
* Set up the 8259A-master output pin:
*/
-static void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector)
+static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, int vector)
{
struct IO_APIC_route_entry entry;
unsigned long flags;
@@ -1287,8 +1317,8 @@ static void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector)
* Add it to the IO-APIC irq-routing table:
*/
spin_lock_irqsave(&ioapic_lock, flags);
- io_apic_write(0, 0x11+2*pin, *(((int *)&entry)+1));
- io_apic_write(0, 0x10+2*pin, *(((int *)&entry)+0));
+ io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1));
+ io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0));
spin_unlock_irqrestore(&ioapic_lock, flags);
enable_8259A_irq(0);
@@ -1595,7 +1625,8 @@ void /*__init*/ print_PIC(void)
static void __init enable_IO_APIC(void)
{
union IO_APIC_reg_01 reg_01;
- int i;
+ int i8259_apic, i8259_pin;
+ int i, apic;
unsigned long flags;
for (i = 0; i < PIN_MAP_SIZE; i++) {
@@ -1609,11 +1640,52 @@ static void __init enable_IO_APIC(void)
/*
* The number of IO-APIC IRQ registers (== #pins):
*/
- for (i = 0; i < nr_ioapics; i++) {
+ for (apic = 0; apic < nr_ioapics; apic++) {
spin_lock_irqsave(&ioapic_lock, flags);
- reg_01.raw = io_apic_read(i, 1);
+ reg_01.raw = io_apic_read(apic, 1);
spin_unlock_irqrestore(&ioapic_lock, flags);
- nr_ioapic_registers[i] = reg_01.bits.entries+1;
+ nr_ioapic_registers[apic] = reg_01.bits.entries+1;
+ }
+ for(apic = 0; apic < nr_ioapics; apic++) {
+ int pin;
+ /* See if any of the pins is in ExtINT mode */
+ for(pin = 0; pin < nr_ioapic_registers[i]; pin++) {
+ struct IO_APIC_route_entry entry;
+ spin_lock_irqsave(&ioapic_lock, flags);
+ *(((int *)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin);
+ *(((int *)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin);
+ spin_unlock_irqrestore(&ioapic_lock, flags);
+
+
+ /* If the interrupt line is enabled and in ExtInt mode
+ * I have found the pin where the i8259 is connected.
+ */
+ if ((entry.mask == 0) && (entry.delivery_mode == dest_ExtINT)) {
+ ioapic_i8259.apic = apic;
+ ioapic_i8259.pin = pin;
+ goto found_i8259;
+ }
+ }
+ }
+ found_i8259:
+ /* Look to see what if the MP table has reported the ExtINT */
+ /* If we could not find the appropriate pin by looking at the ioapic
+ * the i8259 probably is not connected the ioapic but give the
+ * mptable a chance anyway.
+ */
+ i8259_pin = find_isa_irq_pin(0, mp_ExtINT);
+ i8259_apic = find_isa_irq_apic(0, mp_ExtINT);
+ /* Trust the MP table if nothing is setup in the hardware */
+ if ((ioapic_i8259.pin == -1) && (i8259_pin >= 0)) {
+ printk(KERN_WARNING "ExtINT not setup in hardware but reported by MP table\n");
+ ioapic_i8259.pin = i8259_pin;
+ ioapic_i8259.apic = i8259_apic;
+ }
+ /* Complain if the MP table and the hardware disagree */
+ if (((ioapic_i8259.apic != i8259_apic) || (ioapic_i8259.pin != i8259_pin)) &&
+ (i8259_pin >= 0) && (ioapic_i8259.pin >= 0))
+ {
+ printk(KERN_WARNING "ExtINT in hardware and MP table differ\n");
}
/*
@@ -1627,7 +1699,6 @@ static void __init enable_IO_APIC(void)
*/
void disable_IO_APIC(void)
{
- int pin;
/*
* Clear the IO-APIC before rebooting:
*/
@@ -1638,8 +1709,7 @@ void disable_IO_APIC(void)
* Put that IOAPIC in virtual wire mode
* so legacy interrupts can be delivered.
*/
- pin = find_isa_irq_pin(0, mp_ExtINT);
- if (pin != -1) {
+ if (ioapic_i8259.pin != -1) {
struct IO_APIC_route_entry entry;
unsigned long flags;
@@ -1650,7 +1720,7 @@ void disable_IO_APIC(void)
entry.polarity = 0; /* High */
entry.delivery_status = 0;
entry.dest_mode = 0; /* Physical */
- entry.delivery_mode = 7; /* ExtInt */
+ entry.delivery_mode = dest_ExtINT; /* ExtInt */
entry.vector = 0;
entry.dest.physical.physical_dest = 0;
@@ -1659,11 +1729,13 @@ void disable_IO_APIC(void)
* Add it to the IO-APIC irq-routing table:
*/
spin_lock_irqsave(&ioapic_lock, flags);
- io_apic_write(0, 0x11+2*pin, *(((int *)&entry)+1));
- io_apic_write(0, 0x10+2*pin, *(((int *)&entry)+0));
+ io_apic_write(ioapic_i8259.apic, 0x11+2*ioapic_i8259.pin,
+ *(((int *)&entry)+1));
+ io_apic_write(ioapic_i8259.apic, 0x10+2*ioapic_i8259.pin,
+ *(((int *)&entry)+0));
spin_unlock_irqrestore(&ioapic_lock, flags);
}
- disconnect_bsp_APIC(pin != -1);
+ disconnect_bsp_APIC(ioapic_i8259.pin != -1);
}
/*
@@ -2113,20 +2185,21 @@ static void setup_nmi (void)
*/
static inline void unlock_ExtINT_logic(void)
{
- int pin, i;
+ int apic, pin, i;
struct IO_APIC_route_entry entry0, entry1;
unsigned char save_control, save_freq_select;
unsigned long flags;
- pin = find_isa_irq_pin(8, mp_INT);
+ pin = find_isa_irq_pin(8, mp_INT);
+ apic = find_isa_irq_apic(8, mp_INT);
if (pin == -1)
return;
spin_lock_irqsave(&ioapic_lock, flags);
- *(((int *)&entry0) + 1) = io_apic_read(0, 0x11 + 2 * pin);
- *(((int *)&entry0) + 0) = io_apic_read(0, 0x10 + 2 * pin);
+ *(((int *)&entry0) + 1) = io_apic_read(apic, 0x11 + 2 * pin);
+ *(((int *)&entry0) + 0) = io_apic_read(apic, 0x10 + 2 * pin);
spin_unlock_irqrestore(&ioapic_lock, flags);
- clear_IO_APIC_pin(0, pin);
+ clear_IO_APIC_pin(apic, pin);
memset(&entry1, 0, sizeof(entry1));
@@ -2139,8 +2212,8 @@ static inline void unlock_ExtINT_logic(void)
entry1.vector = 0;
spin_lock_irqsave(&ioapic_lock, flags);
- io_apic_write(0, 0x11 + 2 * pin, *(((int *)&entry1) + 1));
- io_apic_write(0, 0x10 + 2 * pin, *(((int *)&entry1) + 0));
+ io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry1) + 1));
+ io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry1) + 0));
spin_unlock_irqrestore(&ioapic_lock, flags);
save_control = CMOS_READ(RTC_CONTROL);
@@ -2158,11 +2231,11 @@ static inline void unlock_ExtINT_logic(void)
CMOS_WRITE(save_control, RTC_CONTROL);
CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
- clear_IO_APIC_pin(0, pin);
+ clear_IO_APIC_pin(apic, pin);
spin_lock_irqsave(&ioapic_lock, flags);
- io_apic_write(0, 0x11 + 2 * pin, *(((int *)&entry0) + 1));
- io_apic_write(0, 0x10 + 2 * pin, *(((int *)&entry0) + 0));
+ io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry0) + 1));
+ io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry0) + 0));
spin_unlock_irqrestore(&ioapic_lock, flags);
}
@@ -2174,7 +2247,7 @@ static inline void unlock_ExtINT_logic(void)
*/
static inline void check_timer(void)
{
- int pin1, pin2;
+ int apic1, pin1, apic2, pin2;
int vector;
/*
@@ -2196,10 +2269,13 @@ static inline void check_timer(void)
timer_ack = 1;
enable_8259A_irq(0);
- pin1 = find_isa_irq_pin(0, mp_INT);
- pin2 = find_isa_irq_pin(0, mp_ExtINT);
+ pin1 = find_isa_irq_pin(0, mp_INT);
+ apic1 = find_isa_irq_apic(0, mp_INT);
+ pin2 = ioapic_i8259.pin;
+ apic2 = ioapic_i8259.apic;
- printk(KERN_INFO "..TIMER: vector=0x%02X pin1=%d pin2=%d\n", vector, pin1, pin2);
+ printk(KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n",
+ vector, apic1, pin1, apic2, pin2);
if (pin1 != -1) {
/*
@@ -2216,8 +2292,9 @@ static inline void check_timer(void)
clear_IO_APIC_pin(0, pin1);
return;
}
- clear_IO_APIC_pin(0, pin1);
- printk(KERN_ERR "..MP-BIOS bug: 8254 timer not connected to IO-APIC\n");
+ clear_IO_APIC_pin(apic1, pin1);
+ printk(KERN_ERR "..MP-BIOS bug: 8254 timer not connected to "
+ "IO-APIC\n");
}
printk(KERN_INFO "...trying to set up timer (IRQ0) through the 8259A ... ");
@@ -2226,13 +2303,13 @@ static inline void check_timer(void)
/*
* legacy devices should be connected to IO APIC #0
*/
- setup_ExtINT_IRQ0_pin(pin2, vector);
+ setup_ExtINT_IRQ0_pin(apic2, pin2, vector);
if (timer_irq_works()) {
printk("works.\n");
if (pin1 != -1)
- replace_pin_at_irq(0, 0, pin1, 0, pin2);
+ replace_pin_at_irq(0, apic1, pin1, apic2, pin2);
else
- add_pin_to_irq(0, 0, pin2);
+ add_pin_to_irq(0, apic2, pin2);
if (nmi_watchdog == NMI_IO_APIC) {
setup_nmi();
}
@@ -2241,7 +2318,7 @@ static inline void check_timer(void)
/*
* Cleanup, just in case ...
*/
- clear_IO_APIC_pin(0, pin2);
+ clear_IO_APIC_pin(apic2, pin2);
}
printk(" failed.\n");
@@ -2310,11 +2387,15 @@ void __init setup_IO_APIC(void)
sync_Arb_IDs();
setup_IO_APIC_irqs();
init_IO_APIC_traps();
- check_timer();
if (!acpi_ioapic)
print_IO_APIC();
}
+void __init IO_APIC_late_time_init(void)
+{
+ check_timer();
+}
+
/*
* Called after all the initialization is done. If we didnt find any
* APIC bugs then we can allow the modify fast path
diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c
index ce66dcc26d90..1a201a932865 100644
--- a/arch/i386/kernel/irq.c
+++ b/arch/i386/kernel/irq.c
@@ -218,7 +218,7 @@ int show_interrupts(struct seq_file *p, void *v)
if (i == 0) {
seq_printf(p, " ");
- for_each_cpu(j)
+ for_each_online_cpu(j)
seq_printf(p, "CPU%d ",j);
seq_putc(p, '\n');
}
@@ -232,7 +232,7 @@ int show_interrupts(struct seq_file *p, void *v)
#ifndef CONFIG_SMP
seq_printf(p, "%10u ", kstat_irqs(i));
#else
- for_each_cpu(j)
+ for_each_online_cpu(j)
seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
#endif
seq_printf(p, " %14s", irq_desc[i].handler->typename);
@@ -246,12 +246,12 @@ skip:
spin_unlock_irqrestore(&irq_desc[i].lock, flags);
} else if (i == NR_IRQS) {
seq_printf(p, "NMI: ");
- for_each_cpu(j)
+ for_each_online_cpu(j)
seq_printf(p, "%10u ", nmi_count(j));
seq_putc(p, '\n');
#ifdef CONFIG_X86_LOCAL_APIC
seq_printf(p, "LOC: ");
- for_each_cpu(j)
+ for_each_online_cpu(j)
seq_printf(p, "%10u ",
per_cpu(irq_stat,j).apic_timer_irqs);
seq_putc(p, '\n');
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
index 27aabfceb67e..8f767d9aa45d 100644
--- a/arch/i386/kernel/mpparse.c
+++ b/arch/i386/kernel/mpparse.c
@@ -69,7 +69,7 @@ unsigned int def_to_bigsmp = 0;
/* Processor that is doing the boot up */
unsigned int boot_cpu_physical_apicid = -1U;
/* Internal processor count */
-static unsigned int __initdata num_processors;
+static unsigned int __devinitdata num_processors;
/* Bitmask of physically existing CPUs */
physid_mask_t phys_cpu_present_map;
@@ -119,7 +119,7 @@ static int MP_valid_apicid(int apicid, int version)
}
#endif
-static void __init MP_processor_info (struct mpc_config_processor *m)
+static void __devinit MP_processor_info (struct mpc_config_processor *m)
{
int ver, apicid;
physid_mask_t phys_cpu;
@@ -182,17 +182,6 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
boot_cpu_physical_apicid = m->mpc_apicid;
}
- if (num_processors >= NR_CPUS) {
- printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached."
- " Processor ignored.\n", NR_CPUS);
- return;
- }
-
- if (num_processors >= maxcpus) {
- printk(KERN_WARNING "WARNING: maxcpus limit of %i reached."
- " Processor ignored.\n", maxcpus);
- return;
- }
ver = m->mpc_apicver;
if (!MP_valid_apicid(apicid, ver)) {
@@ -201,11 +190,6 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
return;
}
- cpu_set(num_processors, cpu_possible_map);
- num_processors++;
- phys_cpu = apicid_to_cpu_present(apicid);
- physids_or(phys_cpu_present_map, phys_cpu_present_map, phys_cpu);
-
/*
* Validate version
*/
@@ -216,6 +200,25 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
ver = 0x10;
}
apic_version[m->mpc_apicid] = ver;
+
+ phys_cpu = apicid_to_cpu_present(apicid);
+ physids_or(phys_cpu_present_map, phys_cpu_present_map, phys_cpu);
+
+ if (num_processors >= NR_CPUS) {
+ printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached."
+ " Processor ignored.\n", NR_CPUS);
+ return;
+ }
+
+ if (num_processors >= maxcpus) {
+ printk(KERN_WARNING "WARNING: maxcpus limit of %i reached."
+ " Processor ignored.\n", maxcpus);
+ return;
+ }
+
+ cpu_set(num_processors, cpu_possible_map);
+ num_processors++;
+
if ((num_processors > 8) &&
APIC_XAPIC(ver) &&
(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL))
@@ -834,7 +837,7 @@ void __init mp_register_lapic_address (
}
-void __init mp_register_lapic (
+void __devinit mp_register_lapic (
u8 id,
u8 enabled)
{
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
index 72515b8a1b12..d661703ac1cb 100644
--- a/arch/i386/kernel/nmi.c
+++ b/arch/i386/kernel/nmi.c
@@ -100,16 +100,44 @@ int nmi_active;
(P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT| \
P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE)
+#ifdef CONFIG_SMP
+/* The performance counters used by NMI_LOCAL_APIC don't trigger when
+ * the CPU is idle. To make sure the NMI watchdog really ticks on all
+ * CPUs during the test make them busy.
+ */
+static __init void nmi_cpu_busy(void *data)
+{
+ volatile int *endflag = data;
+ local_irq_enable();
+ /* Intentionally don't use cpu_relax here. This is
+ to make sure that the performance counter really ticks,
+ even if there is a simulator or similar that catches the
+ pause instruction. On a real HT machine this is fine because
+ all other CPUs are busy with "useless" delay loops and don't
+ care if they get somewhat less cycles. */
+ while (*endflag == 0)
+ barrier();
+}
+#endif
+
static int __init check_nmi_watchdog(void)
{
- unsigned int prev_nmi_count[NR_CPUS];
+ volatile int endflag = 0;
+ unsigned int *prev_nmi_count;
int cpu;
if (nmi_watchdog == NMI_NONE)
return 0;
+ prev_nmi_count = kmalloc(NR_CPUS * sizeof(int), GFP_KERNEL);
+ if (!prev_nmi_count)
+ return -1;
+
printk(KERN_INFO "Testing NMI watchdog ... ");
+ if (nmi_watchdog == NMI_LOCAL_APIC)
+ smp_call_function(nmi_cpu_busy, (void *)&endflag, 0, 0);
+
for (cpu = 0; cpu < NR_CPUS; cpu++)
prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count;
local_irq_enable();
@@ -123,12 +151,18 @@ static int __init check_nmi_watchdog(void)
continue;
#endif
if (nmi_count(cpu) - prev_nmi_count[cpu] <= 5) {
- printk("CPU#%d: NMI appears to be stuck!\n", cpu);
+ endflag = 1;
+ printk("CPU#%d: NMI appears to be stuck (%d->%d)!\n",
+ cpu,
+ prev_nmi_count[cpu],
+ nmi_count(cpu));
nmi_active = 0;
lapic_nmi_owner &= ~LAPIC_NMI_WATCHDOG;
+ kfree(prev_nmi_count);
return -1;
}
}
+ endflag = 1;
printk("OK.\n");
/* now that we know it works we can reduce NMI frequency to
@@ -136,6 +170,7 @@ static int __init check_nmi_watchdog(void)
if (nmi_watchdog == NMI_LOCAL_APIC)
nmi_hz = 1;
+ kfree(prev_nmi_count);
return 0;
}
/* This needs to happen later in boot so counters are working */
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index 7b6368bf8974..efd11f09c996 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -354,7 +354,7 @@ ptrace_set_thread_area(struct task_struct *child,
return 0;
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
struct user * dummy = NULL;
diff --git a/arch/i386/kernel/reboot_fixups.c b/arch/i386/kernel/reboot_fixups.c
index 1b183b378c2c..c9b87330aeea 100644
--- a/arch/i386/kernel/reboot_fixups.c
+++ b/arch/i386/kernel/reboot_fixups.c
@@ -44,7 +44,7 @@ void mach_reboot_fixups(void)
for (i=0; i < (sizeof(fixups_table)/sizeof(fixups_table[0])); i++) {
cur = &(fixups_table[i]);
- dev = pci_get_device(cur->vendor, cur->device, 0);
+ dev = pci_get_device(cur->vendor, cur->device, NULL);
if (!dev)
continue;
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 9b8c8a19824d..b48ac635f3c1 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -389,14 +389,24 @@ static void __init limit_regions(unsigned long long size)
}
}
for (i = 0; i < e820.nr_map; i++) {
- if (e820.map[i].type == E820_RAM) {
- current_addr = e820.map[i].addr + e820.map[i].size;
- if (current_addr >= size) {
- e820.map[i].size -= current_addr-size;
- e820.nr_map = i + 1;
- return;
- }
+ current_addr = e820.map[i].addr + e820.map[i].size;
+ if (current_addr < size)
+ continue;
+
+ if (e820.map[i].type != E820_RAM)
+ continue;
+
+ if (e820.map[i].addr >= size) {
+ /*
+ * This region starts past the end of the
+ * requested size, skip it completely.
+ */
+ e820.nr_map = i;
+ } else {
+ e820.nr_map = i + 1;
+ e820.map[i].size -= current_addr - size;
}
+ return;
}
}
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 1fb26d0e30b6..5a2bbe0c4fff 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -87,7 +87,11 @@ EXPORT_SYMBOL(cpu_online_map);
cpumask_t cpu_callin_map;
cpumask_t cpu_callout_map;
EXPORT_SYMBOL(cpu_callout_map);
+#ifdef CONFIG_HOTPLUG_CPU
+cpumask_t cpu_possible_map = CPU_MASK_ALL;
+#else
cpumask_t cpu_possible_map;
+#endif
EXPORT_SYMBOL(cpu_possible_map);
static cpumask_t smp_commenced_mask;
@@ -1074,6 +1078,16 @@ void *xquad_portio;
EXPORT_SYMBOL(xquad_portio);
#endif
+/*
+ * Fall back to non SMP mode after errors.
+ *
+ */
+static __init void disable_smp(void)
+{
+ cpu_set(0, cpu_sibling_map[0]);
+ cpu_set(0, cpu_core_map[0]);
+}
+
static void __init smp_boot_cpus(unsigned int max_cpus)
{
int apicid, cpu, bit, kicked;
@@ -1086,7 +1100,6 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
printk("CPU%d: ", 0);
print_cpu_info(&cpu_data[0]);
- boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
boot_cpu_logical_apicid = logical_smp_processor_id();
x86_cpu_to_apicid[0] = boot_cpu_physical_apicid;
@@ -1098,68 +1111,27 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
cpus_clear(cpu_core_map[0]);
cpu_set(0, cpu_core_map[0]);
+ map_cpu_to_logical_apicid();
+
/*
* If we couldn't find an SMP configuration at boot time,
* get out of here now!
*/
if (!smp_found_config && !acpi_lapic) {
printk(KERN_NOTICE "SMP motherboard not detected.\n");
- smpboot_clear_io_apic_irqs();
- phys_cpu_present_map = physid_mask_of_physid(0);
- if (APIC_init_uniprocessor())
- printk(KERN_NOTICE "Local APIC not detected."
- " Using dummy APIC emulation.\n");
- map_cpu_to_logical_apicid();
- cpu_set(0, cpu_sibling_map[0]);
- cpu_set(0, cpu_core_map[0]);
+ disable_smp();
return;
}
/*
- * Should not be necessary because the MP table should list the boot
- * CPU too, but we do it for the sake of robustness anyway.
- * Makes no sense to do this check in clustered apic mode, so skip it
- */
- if (!check_phys_apicid_present(boot_cpu_physical_apicid)) {
- printk("weird, boot CPU (#%d) not listed by the BIOS.\n",
- boot_cpu_physical_apicid);
- physid_set(hard_smp_processor_id(), phys_cpu_present_map);
- }
-
- /*
- * If we couldn't find a local APIC, then get out of here now!
- */
- if (APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid]) && !cpu_has_apic) {
- printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
- boot_cpu_physical_apicid);
- printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
- smpboot_clear_io_apic_irqs();
- phys_cpu_present_map = physid_mask_of_physid(0);
- cpu_set(0, cpu_sibling_map[0]);
- cpu_set(0, cpu_core_map[0]);
- return;
- }
-
- verify_local_APIC();
-
- /*
* If SMP should be disabled, then really disable it!
*/
- if (!max_cpus) {
- smp_found_config = 0;
- printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
- smpboot_clear_io_apic_irqs();
- phys_cpu_present_map = physid_mask_of_physid(0);
- cpu_set(0, cpu_sibling_map[0]);
- cpu_set(0, cpu_core_map[0]);
+ if (!max_cpus || (enable_local_apic < 0)) {
+ printk(KERN_INFO "SMP mode deactivated.\n");
+ disable_smp();
return;
}
- connect_bsp_APIC();
- setup_local_APIC();
- map_cpu_to_logical_apicid();
-
-
setup_portio_remap();
/*
@@ -1240,10 +1212,6 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
cpu_set(0, cpu_sibling_map[0]);
cpu_set(0, cpu_core_map[0]);
- smpboot_setup_io_apic();
-
- setup_boot_APIC_clock();
-
/*
* Synchronize the TSC with the AP
*/
diff --git a/arch/i386/kernel/srat.c b/arch/i386/kernel/srat.c
index 516bf5653b02..8de658db8146 100644
--- a/arch/i386/kernel/srat.c
+++ b/arch/i386/kernel/srat.c
@@ -327,7 +327,12 @@ int __init get_memcfg_from_srat(void)
int tables = 0;
int i = 0;
- acpi_find_root_pointer(ACPI_PHYSICAL_ADDRESSING, rsdp_address);
+ if (ACPI_FAILURE(acpi_find_root_pointer(ACPI_PHYSICAL_ADDRESSING,
+ rsdp_address))) {
+ printk("%s: System description tables not found\n",
+ __FUNCTION__);
+ goto out_err;
+ }
if (rsdp_address->pointer_type == ACPI_PHYSICAL_POINTER) {
printk("%s: assigning address to rsdp\n", __FUNCTION__);
diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
index 2883a4d4f01f..07471bba2dc6 100644
--- a/arch/i386/kernel/time.c
+++ b/arch/i386/kernel/time.c
@@ -74,10 +74,6 @@ int pit_latch_buggy; /* extern */
#include "do_timer.h"
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
unsigned int cpu_khz; /* Detected as we calibrate the TSC */
EXPORT_SYMBOL(cpu_khz);
@@ -444,8 +440,8 @@ static int time_init_device(void)
device_initcall(time_init_device);
-#ifdef CONFIG_HPET_TIMER
extern void (*late_time_init)(void);
+#ifdef CONFIG_HPET_TIMER
/* Duplicate of time_init() below, with hpet_enable part added */
static void __init hpet_time_init(void)
{
@@ -462,6 +458,11 @@ static void __init hpet_time_init(void)
printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name);
time_init_hook();
+
+#ifdef CONFIG_X86_LOCAL_APIC
+ if (enable_local_apic >= 0)
+ APIC_late_time_init();
+#endif
}
#endif
@@ -486,4 +487,9 @@ void __init time_init(void)
printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name);
time_init_hook();
+
+#ifdef CONFIG_X86_LOCAL_APIC
+ if (enable_local_apic >= 0)
+ late_time_init = APIC_late_time_init;
+#endif
}
diff --git a/arch/i386/kernel/time_hpet.c b/arch/i386/kernel/time_hpet.c
index 658c0629ba6a..9caeaa315cd7 100644
--- a/arch/i386/kernel/time_hpet.c
+++ b/arch/i386/kernel/time_hpet.c
@@ -275,6 +275,7 @@ static unsigned long PIE_freq = DEFAULT_RTC_INT_FREQ;
static unsigned long PIE_count;
static unsigned long hpet_rtc_int_freq; /* RTC interrupt frequency */
+static unsigned int hpet_t1_cmp; /* cached comparator register */
/*
* Timer 1 for RTC, we do not use periodic interrupt feature,
@@ -306,10 +307,12 @@ int hpet_rtc_timer_init(void)
cnt = hpet_readl(HPET_COUNTER);
cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq);
hpet_writel(cnt, HPET_T1_CMP);
+ hpet_t1_cmp = cnt;
local_irq_restore(flags);
cfg = hpet_readl(HPET_T1_CFG);
- cfg |= HPET_TN_ENABLE | HPET_TN_SETVAL | HPET_TN_32BIT;
+ cfg &= ~HPET_TN_PERIODIC;
+ cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
hpet_writel(cfg, HPET_T1_CFG);
return 1;
@@ -319,8 +322,12 @@ static void hpet_rtc_timer_reinit(void)
{
unsigned int cfg, cnt;
- if (!(PIE_on | AIE_on | UIE_on))
+ if (unlikely(!(PIE_on | AIE_on | UIE_on))) {
+ cfg = hpet_readl(HPET_T1_CFG);
+ cfg &= ~HPET_TN_ENABLE;
+ hpet_writel(cfg, HPET_T1_CFG);
return;
+ }
if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ))
hpet_rtc_int_freq = PIE_freq;
@@ -328,15 +335,10 @@ static void hpet_rtc_timer_reinit(void)
hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;
/* It is more accurate to use the comparator value than current count.*/
- cnt = hpet_readl(HPET_T1_CMP);
+ cnt = hpet_t1_cmp;
cnt += hpet_tick*HZ/hpet_rtc_int_freq;
hpet_writel(cnt, HPET_T1_CMP);
-
- cfg = hpet_readl(HPET_T1_CFG);
- cfg |= HPET_TN_ENABLE | HPET_TN_SETVAL | HPET_TN_32BIT;
- hpet_writel(cfg, HPET_T1_CFG);
-
- return;
+ hpet_t1_cmp = cnt;
}
/*
diff --git a/arch/i386/kernel/timers/timer_hpet.c b/arch/i386/kernel/timers/timer_hpet.c
index d973a8b681fd..be242723c339 100644
--- a/arch/i386/kernel/timers/timer_hpet.c
+++ b/arch/i386/kernel/timers/timer_hpet.c
@@ -30,23 +30,28 @@ static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED;
* basic equation:
* ns = cycles / (freq / ns_per_sec)
* ns = cycles * (ns_per_sec / freq)
- * ns = cycles * (10^9 / (cpu_mhz * 10^6))
- * ns = cycles * (10^3 / cpu_mhz)
+ * ns = cycles * (10^9 / (cpu_khz * 10^3))
+ * ns = cycles * (10^6 / cpu_khz)
*
* Then we use scaling math (suggested by george@mvista.com) to get:
- * ns = cycles * (10^3 * SC / cpu_mhz) / SC
+ * ns = cycles * (10^6 * SC / cpu_khz) / SC
* ns = cycles * cyc2ns_scale / SC
*
* And since SC is a constant power of two, we can convert the div
* into a shift.
+ *
+ * We can use khz divisor instead of mhz to keep a better percision, since
+ * cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits.
+ * (mathieu.desnoyers@polymtl.ca)
+ *
* -johnstul@us.ibm.com "math is hard, lets go shopping!"
*/
static unsigned long cyc2ns_scale;
#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
-static inline void set_cyc2ns_scale(unsigned long cpu_mhz)
+static inline void set_cyc2ns_scale(unsigned long cpu_khz)
{
- cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz;
+ cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz;
}
static inline unsigned long long cycles_2_ns(unsigned long long cyc)
@@ -163,7 +168,7 @@ static int __init init_hpet(char* override)
printk("Detected %u.%03u MHz processor.\n",
cpu_khz / 1000, cpu_khz % 1000);
}
- set_cyc2ns_scale(cpu_khz/1000);
+ set_cyc2ns_scale(cpu_khz);
}
/* set this only when cpu_has_tsc */
timer_hpet.read_timer = read_timer_tsc;
diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c
index 6dd470cc9f72..d395e3b42485 100644
--- a/arch/i386/kernel/timers/timer_tsc.c
+++ b/arch/i386/kernel/timers/timer_tsc.c
@@ -49,23 +49,28 @@ static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED;
* basic equation:
* ns = cycles / (freq / ns_per_sec)
* ns = cycles * (ns_per_sec / freq)
- * ns = cycles * (10^9 / (cpu_mhz * 10^6))
- * ns = cycles * (10^3 / cpu_mhz)
+ * ns = cycles * (10^9 / (cpu_khz * 10^3))
+ * ns = cycles * (10^6 / cpu_khz)
*
* Then we use scaling math (suggested by george@mvista.com) to get:
- * ns = cycles * (10^3 * SC / cpu_mhz) / SC
+ * ns = cycles * (10^6 * SC / cpu_khz) / SC
* ns = cycles * cyc2ns_scale / SC
*
* And since SC is a constant power of two, we can convert the div
- * into a shift.
+ * into a shift.
+ *
+ * We can use khz divisor instead of mhz to keep a better percision, since
+ * cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits.
+ * (mathieu.desnoyers@polymtl.ca)
+ *
* -johnstul@us.ibm.com "math is hard, lets go shopping!"
*/
static unsigned long cyc2ns_scale;
#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
-static inline void set_cyc2ns_scale(unsigned long cpu_mhz)
+static inline void set_cyc2ns_scale(unsigned long cpu_khz)
{
- cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz;
+ cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz;
}
static inline unsigned long long cycles_2_ns(unsigned long long cyc)
@@ -286,7 +291,7 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
if (use_tsc) {
if (!(freq->flags & CPUFREQ_CONST_LOOPS)) {
fast_gettimeoffset_quotient = cpufreq_scale(fast_gettimeoffset_ref, freq->new, ref_freq);
- set_cyc2ns_scale(cpu_khz/1000);
+ set_cyc2ns_scale(cpu_khz);
}
}
#endif
@@ -536,7 +541,7 @@ static int __init init_tsc(char* override)
printk("Detected %u.%03u MHz processor.\n",
cpu_khz / 1000, cpu_khz % 1000);
}
- set_cyc2ns_scale(cpu_khz/1000);
+ set_cyc2ns_scale(cpu_khz);
return 0;
}
}
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 19e90bdd84ea..c34d1bfc5161 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -488,6 +488,7 @@ fastcall void __kprobes do_general_protection(struct pt_regs * regs,
tss->io_bitmap_max - thread->io_bitmap_max);
tss->io_bitmap_max = thread->io_bitmap_max;
tss->io_bitmap_base = IO_BITMAP_OFFSET;
+ tss->io_bitmap_owner = thread;
put_cpu();
return;
}
diff --git a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c
index 16b485009622..fc1993564f98 100644
--- a/arch/i386/kernel/vm86.c
+++ b/arch/i386/kernel/vm86.c
@@ -134,17 +134,16 @@ struct pt_regs * fastcall save_v86_state(struct kernel_vm86_regs * regs)
return ret;
}
-static void mark_screen_rdonly(struct task_struct * tsk)
+static void mark_screen_rdonly(struct mm_struct *mm)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
- pte_t *pte, *mapped;
+ pte_t *pte;
+ spinlock_t *ptl;
int i;
- preempt_disable();
- spin_lock(&tsk->mm->page_table_lock);
- pgd = pgd_offset(tsk->mm, 0xA0000);
+ pgd = pgd_offset(mm, 0xA0000);
if (pgd_none_or_clear_bad(pgd))
goto out;
pud = pud_offset(pgd, 0xA0000);
@@ -153,16 +152,14 @@ static void mark_screen_rdonly(struct task_struct * tsk)
pmd = pmd_offset(pud, 0xA0000);
if (pmd_none_or_clear_bad(pmd))
goto out;
- pte = mapped = pte_offset_map(pmd, 0xA0000);
+ pte = pte_offset_map_lock(mm, pmd, 0xA0000, &ptl);
for (i = 0; i < 32; i++) {
if (pte_present(*pte))
set_pte(pte, pte_wrprotect(*pte));
pte++;
}
- pte_unmap(mapped);
+ pte_unmap_unlock(pte, ptl);
out:
- spin_unlock(&tsk->mm->page_table_lock);
- preempt_enable();
flush_tlb();
}
@@ -306,7 +303,7 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk
tsk->thread.screen_bitmap = info->screen_bitmap;
if (info->flags & VM86_SCREEN_BITMAP)
- mark_screen_rdonly(tsk);
+ mark_screen_rdonly(tsk->mm);
__asm__ __volatile__(
"xorl %%eax,%%eax; movl %%eax,%%fs; movl %%eax,%%gs\n\t"
"movl %0,%%esp\n\t"
diff --git a/arch/i386/mach-es7000/es7000.h b/arch/i386/mach-es7000/es7000.h
index 898ed905e119..f1e3204f5dec 100644
--- a/arch/i386/mach-es7000/es7000.h
+++ b/arch/i386/mach-es7000/es7000.h
@@ -24,6 +24,15 @@
* http://www.unisys.com
*/
+/*
+ * ES7000 chipsets
+ */
+
+#define NON_UNISYS 0
+#define ES7000_CLASSIC 1
+#define ES7000_ZORRO 2
+
+
#define MIP_REG 1
#define MIP_PSAI_REG 4
@@ -106,6 +115,6 @@ struct mip_reg {
extern int parse_unisys_oem (char *oemptr);
extern int find_unisys_acpi_oem_table(unsigned long *oem_addr);
-extern void setup_unisys ();
+extern void setup_unisys(void);
extern int es7000_start_cpu(int cpu, unsigned long eip);
extern void es7000_sw_apic(void);
diff --git a/arch/i386/mach-es7000/es7000plat.c b/arch/i386/mach-es7000/es7000plat.c
index dc6660511b07..a9ab0644f403 100644
--- a/arch/i386/mach-es7000/es7000plat.c
+++ b/arch/i386/mach-es7000/es7000plat.c
@@ -62,6 +62,9 @@ static unsigned int base;
static int
es7000_rename_gsi(int ioapic, int gsi)
{
+ if (es7000_plat == ES7000_ZORRO)
+ return gsi;
+
if (!base) {
int i;
for (i = 0; i < nr_ioapics; i++)
@@ -76,7 +79,7 @@ es7000_rename_gsi(int ioapic, int gsi)
#endif /* (CONFIG_X86_IO_APIC) && (CONFIG_ACPI) */
void __init
-setup_unisys ()
+setup_unisys(void)
{
/*
* Determine the generation of the ES7000 currently running.
@@ -86,9 +89,9 @@ setup_unisys ()
*
*/
if (!(boot_cpu_data.x86 <= 15 && boot_cpu_data.x86_model <= 2))
- es7000_plat = 2;
+ es7000_plat = ES7000_ZORRO;
else
- es7000_plat = 1;
+ es7000_plat = ES7000_CLASSIC;
ioapic_renumber_irq = es7000_rename_gsi;
}
@@ -151,7 +154,7 @@ parse_unisys_oem (char *oemptr)
}
if (success < 2) {
- es7000_plat = 0;
+ es7000_plat = NON_UNISYS;
} else
setup_unisys();
return es7000_plat;
diff --git a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c
index 244d8ec66be2..c4af9638dbfa 100644
--- a/arch/i386/mm/discontig.c
+++ b/arch/i386/mm/discontig.c
@@ -98,7 +98,7 @@ unsigned long node_memmap_size_bytes(int nid, unsigned long start_pfn,
extern unsigned long find_max_low_pfn(void);
extern void find_max_pfn(void);
-extern void one_highpage_init(struct page *, int, int);
+extern void add_one_highpage_init(struct page *, int, int);
extern struct e820map e820;
extern unsigned long init_pg_tables_end;
@@ -427,7 +427,7 @@ void __init set_highmem_pages_init(int bad_ppro)
if (!pfn_valid(node_pfn))
continue;
page = pfn_to_page(node_pfn);
- one_highpage_init(page, node_pfn, bad_ppro);
+ add_one_highpage_init(page, node_pfn, bad_ppro);
}
}
totalram_pages += totalhigh_pages;
diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c
index 9edd4485b91e..cf572d9a3b6e 100644
--- a/arch/i386/mm/fault.c
+++ b/arch/i386/mm/fault.c
@@ -108,7 +108,7 @@ static inline unsigned long get_segment_eip(struct pt_regs *regs,
desc = (void *)desc + (seg & ~7);
} else {
/* Must disable preemption while reading the GDT. */
- desc = (u32 *)&per_cpu(cpu_gdt_table, get_cpu());
+ desc = (u32 *)get_cpu_gdt_table(get_cpu());
desc = (void *)desc + (seg & ~7);
}
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index 2ebaf75f732e..542d9298da5e 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -27,6 +27,7 @@
#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <linux/efi.h>
+#include <linux/memory_hotplug.h>
#include <asm/processor.h>
#include <asm/system.h>
@@ -266,17 +267,46 @@ static void __init permanent_kmaps_init(pgd_t *pgd_base)
pkmap_page_table = pte;
}
-void __init one_highpage_init(struct page *page, int pfn, int bad_ppro)
+void __devinit free_new_highpage(struct page *page)
+{
+ set_page_count(page, 1);
+ __free_page(page);
+ totalhigh_pages++;
+}
+
+void __init add_one_highpage_init(struct page *page, int pfn, int bad_ppro)
{
if (page_is_ram(pfn) && !(bad_ppro && page_kills_ppro(pfn))) {
ClearPageReserved(page);
- set_page_count(page, 1);
- __free_page(page);
- totalhigh_pages++;
+ free_new_highpage(page);
} else
SetPageReserved(page);
}
+static int add_one_highpage_hotplug(struct page *page, unsigned long pfn)
+{
+ free_new_highpage(page);
+ totalram_pages++;
+#ifdef CONFIG_FLATMEM
+ max_mapnr = max(pfn, max_mapnr);
+#endif
+ num_physpages++;
+ return 0;
+}
+
+/*
+ * Not currently handling the NUMA case.
+ * Assuming single node and all memory that
+ * has been added dynamically that would be
+ * onlined here is in HIGHMEM
+ */
+void online_page(struct page *page)
+{
+ ClearPageReserved(page);
+ add_one_highpage_hotplug(page, page_to_pfn(page));
+}
+
+
#ifdef CONFIG_NUMA
extern void set_highmem_pages_init(int);
#else
@@ -284,7 +314,7 @@ static void __init set_highmem_pages_init(int bad_ppro)
{
int pfn;
for (pfn = highstart_pfn; pfn < highend_pfn; pfn++)
- one_highpage_init(pfn_to_page(pfn), pfn, bad_ppro);
+ add_one_highpage_init(pfn_to_page(pfn), pfn, bad_ppro);
totalram_pages += totalhigh_pages;
}
#endif /* CONFIG_FLATMEM */
@@ -615,6 +645,28 @@ void __init mem_init(void)
#endif
}
+/*
+ * this is for the non-NUMA, single node SMP system case.
+ * Specifically, in the case of x86, we will always add
+ * memory to the highmem for now.
+ */
+#ifndef CONFIG_NEED_MULTIPLE_NODES
+int add_memory(u64 start, u64 size)
+{
+ struct pglist_data *pgdata = &contig_page_data;
+ struct zone *zone = pgdata->node_zones + MAX_NR_ZONES-1;
+ unsigned long start_pfn = start >> PAGE_SHIFT;
+ unsigned long nr_pages = size >> PAGE_SHIFT;
+
+ return __add_pages(zone, start_pfn, nr_pages);
+}
+
+int remove_memory(u64 start, u64 size)
+{
+ return -EINVAL;
+}
+#endif
+
kmem_cache_t *pgd_cache;
kmem_cache_t *pmd_cache;
diff --git a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c
index f379b8d67558..5d09de8d1c6b 100644
--- a/arch/i386/mm/ioremap.c
+++ b/arch/i386/mm/ioremap.c
@@ -28,7 +28,7 @@ static int ioremap_pte_range(pmd_t *pmd, unsigned long addr,
unsigned long pfn;
pfn = phys_addr >> PAGE_SHIFT;
- pte = pte_alloc_kernel(&init_mm, pmd, addr);
+ pte = pte_alloc_kernel(pmd, addr);
if (!pte)
return -ENOMEM;
do {
@@ -87,14 +87,12 @@ static int ioremap_page_range(unsigned long addr,
flush_cache_all();
phys_addr -= addr;
pgd = pgd_offset_k(addr);
- spin_lock(&init_mm.page_table_lock);
do {
next = pgd_addr_end(addr, end);
err = ioremap_pud_range(pgd, addr, next, phys_addr+addr, flags);
if (err)
break;
} while (pgd++, addr = next, addr != end);
- spin_unlock(&init_mm.page_table_lock);
flush_tlb_all();
return err;
}
diff --git a/arch/i386/mm/pgtable.c b/arch/i386/mm/pgtable.c
index dcdce2c6c532..9db3242103be 100644
--- a/arch/i386/mm/pgtable.c
+++ b/arch/i386/mm/pgtable.c
@@ -31,11 +31,13 @@ void show_mem(void)
pg_data_t *pgdat;
unsigned long i;
struct page_state ps;
+ unsigned long flags;
printk(KERN_INFO "Mem-info:\n");
show_free_areas();
printk(KERN_INFO "Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
for_each_pgdat(pgdat) {
+ pgdat_resize_lock(pgdat, &flags);
for (i = 0; i < pgdat->node_spanned_pages; ++i) {
page = pgdat_page_nr(pgdat, i);
total++;
@@ -48,6 +50,7 @@ void show_mem(void)
else if (page_count(page))
shared += page_count(page) - 1;
}
+ pgdat_resize_unlock(pgdat, &flags);
}
printk(KERN_INFO "%d pages of RAM\n", total);
printk(KERN_INFO "%d pages of HIGHMEM\n", highmem);
@@ -188,19 +191,19 @@ static inline void pgd_list_add(pgd_t *pgd)
struct page *page = virt_to_page(pgd);
page->index = (unsigned long)pgd_list;
if (pgd_list)
- pgd_list->private = (unsigned long)&page->index;
+ set_page_private(pgd_list, (unsigned long)&page->index);
pgd_list = page;
- page->private = (unsigned long)&pgd_list;
+ set_page_private(page, (unsigned long)&pgd_list);
}
static inline void pgd_list_del(pgd_t *pgd)
{
struct page *next, **pprev, *page = virt_to_page(pgd);
next = (struct page *)page->index;
- pprev = (struct page **)page->private;
+ pprev = (struct page **)page_private(page);
*pprev = next;
if (next)
- next->private = (unsigned long)pprev;
+ set_page_private(next, (unsigned long)pprev);
}
void pgd_ctor(void *pgd, kmem_cache_t *cache, unsigned long unused)
diff --git a/arch/i386/oprofile/backtrace.c b/arch/i386/oprofile/backtrace.c
index 65dfd2edb671..21654be3f73f 100644
--- a/arch/i386/oprofile/backtrace.c
+++ b/arch/i386/oprofile/backtrace.c
@@ -12,6 +12,7 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <asm/ptrace.h>
+#include <asm/uaccess.h>
struct frame_head {
struct frame_head * ebp;
@@ -21,26 +22,22 @@ struct frame_head {
static struct frame_head *
dump_backtrace(struct frame_head * head)
{
- oprofile_add_trace(head->ret);
+ struct frame_head bufhead[2];
- /* frame pointers should strictly progress back up the stack
- * (towards higher addresses) */
- if (head >= head->ebp)
+ /* Also check accessibility of one struct frame_head beyond */
+ if (!access_ok(VERIFY_READ, head, sizeof(bufhead)))
+ return NULL;
+ if (__copy_from_user_inatomic(bufhead, head, sizeof(bufhead)))
return NULL;
- return head->ebp;
-}
-
-/* check that the page(s) containing the frame head are present */
-static int pages_present(struct frame_head * head)
-{
- struct mm_struct * mm = current->mm;
+ oprofile_add_trace(bufhead[0].ret);
- /* FIXME: only necessary once per page */
- if (!check_user_page_readable(mm, (unsigned long)head))
- return 0;
+ /* frame pointers should strictly progress back up the stack
+ * (towards higher addresses) */
+ if (head >= bufhead[0].ebp)
+ return NULL;
- return check_user_page_readable(mm, (unsigned long)(head + 1));
+ return bufhead[0].ebp;
}
/*
@@ -97,15 +94,6 @@ x86_backtrace(struct pt_regs * const regs, unsigned int depth)
return;
}
-#ifdef CONFIG_SMP
- if (!spin_trylock(&current->mm->page_table_lock))
- return;
-#endif
-
- while (depth-- && head && pages_present(head))
+ while (depth-- && head)
head = dump_backtrace(head);
-
-#ifdef CONFIG_SMP
- spin_unlock(&current->mm->page_table_lock);
-#endif
}
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c
index cddafe33ff7c..19e6f4871d1e 100644
--- a/arch/i386/pci/irq.c
+++ b/arch/i386/pci/irq.c
@@ -547,31 +547,48 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route
return 0;
}
-static __init int via_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
+static __init int via_router_probe(struct irq_router *r,
+ struct pci_dev *router, u16 device)
{
/* FIXME: We should move some of the quirk fixup stuff here */
- if (router->device == PCI_DEVICE_ID_VIA_82C686 &&
- device == PCI_DEVICE_ID_VIA_82C586_0) {
- /* Asus k7m bios wrongly reports 82C686A as 586-compatible */
- device = PCI_DEVICE_ID_VIA_82C686;
+ /*
+ * work arounds for some buggy BIOSes
+ */
+ if (device == PCI_DEVICE_ID_VIA_82C586_0) {
+ switch(router->device) {
+ case PCI_DEVICE_ID_VIA_82C686:
+ /*
+ * Asus k7m bios wrongly reports 82C686A
+ * as 586-compatible
+ */
+ device = PCI_DEVICE_ID_VIA_82C686;
+ break;
+ case PCI_DEVICE_ID_VIA_8235:
+ /**
+ * Asus a7v-x bios wrongly reports 8235
+ * as 586-compatible
+ */
+ device = PCI_DEVICE_ID_VIA_8235;
+ break;
+ }
}
- switch(device)
- {
- case PCI_DEVICE_ID_VIA_82C586_0:
- r->name = "VIA";
- r->get = pirq_via586_get;
- r->set = pirq_via586_set;
- return 1;
- case PCI_DEVICE_ID_VIA_82C596:
- case PCI_DEVICE_ID_VIA_82C686:
- case PCI_DEVICE_ID_VIA_8231:
+ switch(device) {
+ case PCI_DEVICE_ID_VIA_82C586_0:
+ r->name = "VIA";
+ r->get = pirq_via586_get;
+ r->set = pirq_via586_set;
+ return 1;
+ case PCI_DEVICE_ID_VIA_82C596:
+ case PCI_DEVICE_ID_VIA_82C686:
+ case PCI_DEVICE_ID_VIA_8231:
+ case PCI_DEVICE_ID_VIA_8235:
/* FIXME: add new ones for 8233/5 */
- r->name = "VIA";
- r->get = pirq_via_get;
- r->set = pirq_via_set;
- return 1;
+ r->name = "VIA";
+ r->get = pirq_via_get;
+ r->set = pirq_via_set;
+ return 1;
}
return 0;
}
diff --git a/arch/i386/power/cpu.c b/arch/i386/power/cpu.c
index b27c5acc79d0..1f1572692e0b 100644
--- a/arch/i386/power/cpu.c
+++ b/arch/i386/power/cpu.c
@@ -51,16 +51,14 @@ void save_processor_state(void)
__save_processor_state(&saved_context);
}
-static void
-do_fpu_end(void)
+static void do_fpu_end(void)
{
- /* restore FPU regs if necessary */
- /* Do it out of line so that gcc does not move cr0 load to some stupid place */
- kernel_fpu_end();
- mxcsr_feature_mask_init();
+ /*
+ * Restore FPU regs if necessary.
+ */
+ kernel_fpu_end();
}
-
static void fix_processor_context(void)
{
int cpu = smp_processor_id();
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
index 3fa67ecebc83..dc282710421a 100644
--- a/arch/ia64/ia32/sys_ia32.c
+++ b/arch/ia64/ia32/sys_ia32.c
@@ -36,6 +36,7 @@
#include <linux/uio.h>
#include <linux/nfs_fs.h>
#include <linux/quota.h>
+#include <linux/syscalls.h>
#include <linux/sunrpc/svc.h>
#include <linux/nfsd/nfsd.h>
#include <linux/nfsd/cache.h>
diff --git a/arch/ia64/kernel/cyclone.c b/arch/ia64/kernel/cyclone.c
index 768c7e46957c..6ade3790ce07 100644
--- a/arch/ia64/kernel/cyclone.c
+++ b/arch/ia64/kernel/cyclone.c
@@ -2,6 +2,7 @@
#include <linux/smp.h>
#include <linux/time.h>
#include <linux/errno.h>
+#include <linux/timex.h>
#include <asm/io.h>
/* IBM Summit (EXA) Cyclone counter code*/
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index d71731ee5b61..f7dfc107cb7b 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -2352,7 +2352,8 @@ pfm_smpl_buffer_alloc(struct task_struct *task, pfm_context_t *ctx, unsigned lon
insert_vm_struct(mm, vma);
mm->total_vm += size >> PAGE_SHIFT;
- vm_stat_account(vma);
+ vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file,
+ vma_pages(vma));
up_write(&task->mm->mmap_sem);
/*
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index 8b8a5a45b621..5b7e736f3b49 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -32,10 +32,6 @@
extern unsigned long wall_jiffies;
-u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
#define TIME_KEEPER_ID 0 /* smp_processor_id() of time-keeper */
#ifdef CONFIG_IA64_DEBUG_IRQ
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
index a3788fb84809..a88cdb7232f8 100644
--- a/arch/ia64/mm/discontig.c
+++ b/arch/ia64/mm/discontig.c
@@ -555,9 +555,13 @@ void show_mem(void)
show_free_areas();
printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
for_each_pgdat(pgdat) {
- unsigned long present = pgdat->node_present_pages;
+ unsigned long present;
+ unsigned long flags;
int shared = 0, cached = 0, reserved = 0;
+
printk("Node ID: %d\n", pgdat->node_id);
+ pgdat_resize_lock(pgdat, &flags);
+ present = pgdat->node_present_pages;
for(i = 0; i < pgdat->node_spanned_pages; i++) {
struct page *page;
if (pfn_valid(pgdat->node_start_pfn + i))
@@ -571,6 +575,7 @@ void show_mem(void)
else if (page_count(page))
shared += page_count(page)-1;
}
+ pgdat_resize_unlock(pgdat, &flags);
total_present += present;
total_reserved += reserved;
total_cached += cached;
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
index 3c32af910d60..af7eb087dca7 100644
--- a/arch/ia64/mm/fault.c
+++ b/arch/ia64/mm/fault.c
@@ -20,32 +20,6 @@
extern void die (char *, struct pt_regs *, long);
/*
- * This routine is analogous to expand_stack() but instead grows the
- * register backing store (which grows towards higher addresses).
- * Since the register backing store is access sequentially, we
- * disallow growing the RBS by more than a page at a time. Note that
- * the VM_GROWSUP flag can be set on any VM area but that's fine
- * because the total process size is still limited by RLIMIT_STACK and
- * RLIMIT_AS.
- */
-static inline long
-expand_backing_store (struct vm_area_struct *vma, unsigned long address)
-{
- unsigned long grow;
-
- grow = PAGE_SIZE >> PAGE_SHIFT;
- if (address - vma->vm_start > current->signal->rlim[RLIMIT_STACK].rlim_cur
- || (((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) > current->signal->rlim[RLIMIT_AS].rlim_cur))
- return -ENOMEM;
- vma->vm_end += PAGE_SIZE;
- vma->vm_mm->total_vm += grow;
- if (vma->vm_flags & VM_LOCKED)
- vma->vm_mm->locked_vm += grow;
- __vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file, grow);
- return 0;
-}
-
-/*
* Return TRUE if ADDRESS points at a page in the kernel's mapped segment
* (inside region 5, on ia64) and that page is present.
*/
@@ -185,7 +159,13 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
if (REGION_NUMBER(address) != REGION_NUMBER(vma->vm_start)
|| REGION_OFFSET(address) >= RGN_MAP_LIMIT)
goto bad_area;
- if (expand_backing_store(vma, address))
+ /*
+ * Since the register backing store is accessed sequentially,
+ * we disallow growing it by more than a page at a time.
+ */
+ if (address > vma->vm_end + PAGE_SIZE - sizeof(long))
+ goto bad_area;
+ if (expand_upwards(vma, address))
goto bad_area;
}
goto good_area;
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index 98246acd4991..e3215ba64ffd 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -158,7 +158,7 @@ ia64_init_addr_space (void)
vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
vma->vm_end = vma->vm_start + PAGE_SIZE;
vma->vm_page_prot = protection_map[VM_DATA_DEFAULT_FLAGS & 0x7];
- vma->vm_flags = VM_DATA_DEFAULT_FLAGS | VM_GROWSUP;
+ vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
down_write(&current->mm->mmap_sem);
if (insert_vm_struct(current->mm, vma)) {
up_write(&current->mm->mmap_sem);
@@ -275,26 +275,21 @@ put_kernel_page (struct page *page, unsigned long address, pgprot_t pgprot)
pgd = pgd_offset_k(address); /* note: this is NOT pgd_offset()! */
- spin_lock(&init_mm.page_table_lock);
{
pud = pud_alloc(&init_mm, pgd, address);
if (!pud)
goto out;
-
pmd = pmd_alloc(&init_mm, pud, address);
if (!pmd)
goto out;
- pte = pte_alloc_map(&init_mm, pmd, address);
+ pte = pte_alloc_kernel(pmd, address);
if (!pte)
goto out;
- if (!pte_none(*pte)) {
- pte_unmap(pte);
+ if (!pte_none(*pte))
goto out;
- }
set_pte(pte, mk_pte(page, pgprot));
- pte_unmap(pte);
}
- out: spin_unlock(&init_mm.page_table_lock);
+ out:
/* no need for flush_tlb */
return page;
}
diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c
index c93e0f2b5fea..c79a9b96d02b 100644
--- a/arch/ia64/mm/tlb.c
+++ b/arch/ia64/mm/tlb.c
@@ -158,10 +158,12 @@ flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long
# ifdef CONFIG_SMP
platform_global_tlb_purge(mm, start, end, nbits);
# else
+ preempt_disable();
do {
ia64_ptcl(start, (nbits<<2));
start += (1UL << nbits);
} while (start < end);
+ preempt_enable();
# endif
ia64_srlz_i(); /* srlz.i implies srlz.d */
diff --git a/arch/m32r/kernel/entry.S b/arch/m32r/kernel/entry.S
index 85920fb8d08c..396c94218cc2 100644
--- a/arch/m32r/kernel/entry.S
+++ b/arch/m32r/kernel/entry.S
@@ -653,8 +653,6 @@ ENTRY(rie_handler)
SAVE_ALL
mvfc r0, bpc
ld r1, @r0
- seth r0, #0xa0f0
- st r1, @r0
ldi r1, #0x20 ; error_code
mv r0, sp ; pt_regs
bl do_rie_handler
diff --git a/arch/m32r/kernel/io_m32700ut.c b/arch/m32r/kernel/io_m32700ut.c
index e545b065f7e9..eda9f963c1eb 100644
--- a/arch/m32r/kernel/io_m32700ut.c
+++ b/arch/m32r/kernel/io_m32700ut.c
@@ -64,11 +64,11 @@ static inline void *__port2addr_ata(unsigned long port)
* from 0x10000000 to 0x13ffffff on physical address.
* The base address of LAN controller(LAN91C111) is 0x300.
*/
-#define LAN_IOSTART 0x300
-#define LAN_IOEND 0x320
+#define LAN_IOSTART 0xa0000300
+#define LAN_IOEND 0xa0000320
static inline void *_port2addr_ne(unsigned long port)
{
- return (void *)(port + NONCACHE_OFFSET + 0x10000000);
+ return (void *)(port + 0x10000000);
}
static inline void *_port2addr_usb(unsigned long port)
{
diff --git a/arch/m32r/kernel/io_mappi.c b/arch/m32r/kernel/io_mappi.c
index 78033165fb5c..3c3da042fbd1 100644
--- a/arch/m32r/kernel/io_mappi.c
+++ b/arch/m32r/kernel/io_mappi.c
@@ -31,7 +31,7 @@ extern void pcc_iowrite(int, unsigned long, void *, size_t, size_t, int);
static inline void *_port2addr(unsigned long port)
{
- return (void *)(port + NONCACHE_OFFSET);
+ return (void *)(port | (NONCACHE_OFFSET));
}
static inline void *_port2addr_ne(unsigned long port)
diff --git a/arch/m32r/kernel/io_mappi2.c b/arch/m32r/kernel/io_mappi2.c
index 5c03504bf653..df3c729cb3e0 100644
--- a/arch/m32r/kernel/io_mappi2.c
+++ b/arch/m32r/kernel/io_mappi2.c
@@ -33,12 +33,9 @@ extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int);
static inline void *_port2addr(unsigned long port)
{
- return (void *)(port + NONCACHE_OFFSET);
+ return (void *)(port | (NONCACHE_OFFSET));
}
-#define LAN_IOSTART 0x300
-#define LAN_IOEND 0x320
-
#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
static inline void *__port2addr_ata(unsigned long port)
{
@@ -59,15 +56,17 @@ static inline void *__port2addr_ata(unsigned long port)
}
#endif
+#define LAN_IOSTART 0xa0000300
+#define LAN_IOEND 0xa0000320
#ifdef CONFIG_CHIP_OPSP
static inline void *_port2addr_ne(unsigned long port)
{
- return (void *)(port + NONCACHE_OFFSET + 0x10000000);
+ return (void *)(port + 0x10000000);
}
#else
static inline void *_port2addr_ne(unsigned long port)
{
- return (void *)(port + NONCACHE_OFFSET + 0x04000000);
+ return (void *)(port + 0x04000000);
}
#endif
static inline void *_port2addr_usb(unsigned long port)
diff --git a/arch/m32r/kernel/io_mappi3.c b/arch/m32r/kernel/io_mappi3.c
index c80bde657854..6716ffea769a 100644
--- a/arch/m32r/kernel/io_mappi3.c
+++ b/arch/m32r/kernel/io_mappi3.c
@@ -36,9 +36,6 @@ static inline void *_port2addr(unsigned long port)
return (void *)(port + NONCACHE_OFFSET);
}
-#define LAN_IOSTART 0x300
-#define LAN_IOEND 0x320
-
#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
static inline void *__port2addr_ata(unsigned long port)
{
@@ -59,9 +56,11 @@ static inline void *__port2addr_ata(unsigned long port)
}
#endif
+#define LAN_IOSTART 0xa0000300
+#define LAN_IOEND 0xa0000320
static inline void *_port2addr_ne(unsigned long port)
{
- return (void *)(port + NONCACHE_OFFSET + 0x10000000);
+ return (void *)(port + 0x10000000);
}
static inline void *_port2addr_usb(unsigned long port)
diff --git a/arch/m32r/kernel/io_oaks32r.c b/arch/m32r/kernel/io_oaks32r.c
index 9997dddd24d7..8be323931e4a 100644
--- a/arch/m32r/kernel/io_oaks32r.c
+++ b/arch/m32r/kernel/io_oaks32r.c
@@ -16,7 +16,7 @@
static inline void *_port2addr(unsigned long port)
{
- return (void *)(port + NONCACHE_OFFSET);
+ return (void *)(port | (NONCACHE_OFFSET));
}
static inline void *_port2addr_ne(unsigned long port)
diff --git a/arch/m32r/kernel/io_opsput.c b/arch/m32r/kernel/io_opsput.c
index e34951e8156f..4793bd18e115 100644
--- a/arch/m32r/kernel/io_opsput.c
+++ b/arch/m32r/kernel/io_opsput.c
@@ -36,7 +36,7 @@ extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int);
static inline void *_port2addr(unsigned long port)
{
- return (void *)(port + NONCACHE_OFFSET);
+ return (void *)(port | (NONCACHE_OFFSET));
}
/*
@@ -44,11 +44,11 @@ static inline void *_port2addr(unsigned long port)
* from 0x10000000 to 0x13ffffff on physical address.
* The base address of LAN controller(LAN91C111) is 0x300.
*/
-#define LAN_IOSTART 0x300
-#define LAN_IOEND 0x320
+#define LAN_IOSTART 0xa0000300
+#define LAN_IOEND 0xa0000320
static inline void *_port2addr_ne(unsigned long port)
{
- return (void *)(port + NONCACHE_OFFSET + 0x10000000);
+ return (void *)(port + 0x10000000);
}
static inline void *_port2addr_usb(unsigned long port)
{
diff --git a/arch/m32r/kernel/io_usrv.c b/arch/m32r/kernel/io_usrv.c
index 9eb161dcc104..39a379af40bc 100644
--- a/arch/m32r/kernel/io_usrv.c
+++ b/arch/m32r/kernel/io_usrv.c
@@ -47,7 +47,7 @@ static inline void *_port2addr(unsigned long port)
else if (port >= UART1_IOSTART && port <= UART1_IOEND)
port = ((port - UART1_IOSTART) << 1) + UART1_REGSTART;
#endif /* CONFIG_SERIAL_8250 || CONFIG_SERIAL_8250_MODULE */
- return (void *)(port + NONCACHE_OFFSET);
+ return (void *)(port | (NONCACHE_OFFSET));
}
static inline void delay(void)
diff --git a/arch/m32r/kernel/ptrace.c b/arch/m32r/kernel/ptrace.c
index 124f7c1b775e..078d2a0e71c2 100644
--- a/arch/m32r/kernel/ptrace.c
+++ b/arch/m32r/kernel/ptrace.c
@@ -756,7 +756,7 @@ do_ptrace(long request, struct task_struct *child, long addr, long data)
return ret;
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
int ret;
diff --git a/arch/m32r/kernel/setup.c b/arch/m32r/kernel/setup.c
index ec5674727e7f..f722ec8eb021 100644
--- a/arch/m32r/kernel/setup.c
+++ b/arch/m32r/kernel/setup.c
@@ -305,19 +305,19 @@ static int show_cpuinfo(struct seq_file *m, void *v)
seq_printf(m, "processor\t: %ld\n", cpu);
-#ifdef CONFIG_CHIP_VDEC2
+#if defined(CONFIG_CHIP_VDEC2)
seq_printf(m, "cpu family\t: VDEC2\n"
"cache size\t: Unknown\n");
-#elif CONFIG_CHIP_M32700
+#elif defined(CONFIG_CHIP_M32700)
seq_printf(m,"cpu family\t: M32700\n"
"cache size\t: I-8KB/D-8KB\n");
-#elif CONFIG_CHIP_M32102
+#elif defined(CONFIG_CHIP_M32102)
seq_printf(m,"cpu family\t: M32102\n"
"cache size\t: I-8KB\n");
-#elif CONFIG_CHIP_OPSP
+#elif defined(CONFIG_CHIP_OPSP)
seq_printf(m,"cpu family\t: OPSP\n"
"cache size\t: I-8KB/D-8KB\n");
-#elif CONFIG_CHIP_MP
+#elif defined(CONFIG_CHIP_MP)
seq_printf(m, "cpu family\t: M32R-MP\n"
"cache size\t: I-xxKB/D-xxKB\n");
#else
@@ -326,19 +326,19 @@ static int show_cpuinfo(struct seq_file *m, void *v)
seq_printf(m, "bogomips\t: %lu.%02lu\n",
c->loops_per_jiffy/(500000/HZ),
(c->loops_per_jiffy/(5000/HZ)) % 100);
-#ifdef CONFIG_PLAT_MAPPI
+#if defined(CONFIG_PLAT_MAPPI)
seq_printf(m, "Machine\t\t: Mappi Evaluation board\n");
-#elif CONFIG_PLAT_MAPPI2
+#elif defined(CONFIG_PLAT_MAPPI2)
seq_printf(m, "Machine\t\t: Mappi-II Evaluation board\n");
-#elif CONFIG_PLAT_MAPPI3
+#elif defined(CONFIG_PLAT_MAPPI3)
seq_printf(m, "Machine\t\t: Mappi-III Evaluation board\n");
-#elif CONFIG_PLAT_M32700UT
+#elif defined(CONFIG_PLAT_M32700UT)
seq_printf(m, "Machine\t\t: M32700UT Evaluation board\n");
-#elif CONFIG_PLAT_OPSPUT
+#elif defined(CONFIG_PLAT_OPSPUT)
seq_printf(m, "Machine\t\t: OPSPUT Evaluation board\n");
-#elif CONFIG_PLAT_USRV
+#elif defined(CONFIG_PLAT_USRV)
seq_printf(m, "Machine\t\t: uServer\n");
-#elif CONFIG_PLAT_OAKS32R
+#elif defined(CONFIG_PLAT_OAKS32R)
seq_printf(m, "Machine\t\t: OAKS32R\n");
#else
seq_printf(m, "Machine\t\t: Unknown\n");
diff --git a/arch/m32r/kernel/time.c b/arch/m32r/kernel/time.c
index 539c562cd54d..2ebce2063fea 100644
--- a/arch/m32r/kernel/time.c
+++ b/arch/m32r/kernel/time.c
@@ -39,10 +39,6 @@ extern void send_IPI_allbutself(int, int);
extern void smp_local_timer_interrupt(struct pt_regs *);
#endif
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
extern unsigned long wall_jiffies;
#define TICK_SIZE (tick_nsec / 1000)
diff --git a/arch/m32r/lib/csum_partial_copy.c b/arch/m32r/lib/csum_partial_copy.c
index ddb16a83a8ce..3d5f06145854 100644
--- a/arch/m32r/lib/csum_partial_copy.c
+++ b/arch/m32r/lib/csum_partial_copy.c
@@ -18,10 +18,10 @@
#include <linux/module.h>
#include <linux/types.h>
+#include <linux/string.h>
#include <net/checksum.h>
#include <asm/byteorder.h>
-#include <asm/string.h>
#include <asm/uaccess.h>
/*
diff --git a/arch/m32r/mm/init.c b/arch/m32r/mm/init.c
index d9a40b1fe8ba..6facf15b04f3 100644
--- a/arch/m32r/mm/init.c
+++ b/arch/m32r/mm/init.c
@@ -48,6 +48,8 @@ void show_mem(void)
show_free_areas();
printk("Free swap: %6ldkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
for_each_pgdat(pgdat) {
+ unsigned long flags;
+ pgdat_resize_lock(pgdat, &flags);
for (i = 0; i < pgdat->node_spanned_pages; ++i) {
page = pgdat_page_nr(pgdat, i);
total++;
@@ -60,6 +62,7 @@ void show_mem(void)
else if (page_count(page))
shared += page_count(page) - 1;
}
+ pgdat_resize_unlock(pgdat, &flags);
}
printk("%d pages of RAM\n", total);
printk("%d pages of HIGHMEM\n",highmem);
@@ -150,10 +153,14 @@ int __init reservedpages_count(void)
int reservedpages, nid, i;
reservedpages = 0;
- for_each_online_node(nid)
+ for_each_online_node(nid) {
+ unsigned long flags;
+ pgdat_resize_lock(NODE_DATA(nid), &flags);
for (i = 0 ; i < MAX_LOW_PFN(nid) - START_PFN(nid) ; i++)
if (PageReserved(nid_page_nr(nid, i)))
reservedpages++;
+ pgdat_resize_unlock(NODE_DATA(nid), &flags);
+ }
return reservedpages;
}
diff --git a/arch/m32r/mm/ioremap.c b/arch/m32r/mm/ioremap.c
index 70c59055c19c..a151849a605e 100644
--- a/arch/m32r/mm/ioremap.c
+++ b/arch/m32r/mm/ioremap.c
@@ -67,7 +67,7 @@ remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
if (address >= end)
BUG();
do {
- pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
+ pte_t * pte = pte_alloc_kernel(pmd, address);
if (!pte)
return -ENOMEM;
remap_area_pte(pte, address, end - address, address + phys_addr, flags);
@@ -90,7 +90,6 @@ remap_area_pages(unsigned long address, unsigned long phys_addr,
flush_cache_all();
if (address >= end)
BUG();
- spin_lock(&init_mm.page_table_lock);
do {
pmd_t *pmd;
pmd = pmd_alloc(&init_mm, dir, address);
@@ -104,7 +103,6 @@ remap_area_pages(unsigned long address, unsigned long phys_addr,
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
} while (address && (address < end));
- spin_unlock(&init_mm.page_table_lock);
flush_tlb_all();
return error;
}
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index ba960bbc8e6d..1dd5d18b2201 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -388,33 +388,11 @@ config AMIGA_PCMCIA
Include support in the kernel for pcmcia on Amiga 1200 and Amiga
600. If you intend to use pcmcia cards say Y; otherwise say N.
-config STRAM_SWAP
- bool "Support for ST-RAM as swap space"
- depends on ATARI && BROKEN
- ---help---
- Some Atari 68k machines (including the 520STF and 1020STE) divide
- their addressable memory into ST and TT sections. The TT section
- (up to 512MB) is the main memory; the ST section (up to 4MB) is
- accessible to the built-in graphics board, runs slower, and is
- present mainly for backward compatibility with older machines.
-
- This enables support for using (parts of) ST-RAM as swap space,
- instead of as normal system memory. This can first enhance system
- performance if you have lots of alternate RAM (compared to the size
- of ST-RAM), because executable code always will reside in faster
- memory. ST-RAM will remain as ultra-fast swap space. On the other
- hand, it allows much improved dynamic allocations of ST-RAM buffers
- for device driver modules (e.g. floppy, ACSI, SLM printer, DMA
- sound). The probability that such allocations at module load time
- fail is drastically reduced.
-
config STRAM_PROC
bool "ST-RAM statistics in /proc"
depends on ATARI
help
- Say Y here to report ST-RAM usage statistics in /proc/stram. See
- the help for CONFIG_STRAM_SWAP for discussion of ST-RAM and its
- uses.
+ Say Y here to report ST-RAM usage statistics in /proc/stram.
config HEARTBEAT
bool "Use power LED as a heartbeat" if AMIGA || APOLLO || ATARI || MAC ||Q40
diff --git a/arch/m68k/atari/stram.c b/arch/m68k/atari/stram.c
index 5a3c106b40c8..22e0481a5f7b 100644
--- a/arch/m68k/atari/stram.c
+++ b/arch/m68k/atari/stram.c
@@ -15,11 +15,9 @@
#include <linux/kdev_t.h>
#include <linux/major.h>
#include <linux/init.h>
-#include <linux/swap.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/pagemap.h>
-#include <linux/shm.h>
#include <linux/bootmem.h>
#include <linux/mount.h>
#include <linux/blkdev.h>
@@ -33,8 +31,6 @@
#include <asm/io.h>
#include <asm/semaphore.h>
-#include <linux/swapops.h>
-
#undef DEBUG
#ifdef DEBUG
@@ -49,8 +45,7 @@
#include <linux/proc_fs.h>
#endif
-/* Pre-swapping comments:
- *
+/*
* ++roman:
*
* New version of ST-Ram buffer allocation. Instead of using the
@@ -75,76 +70,6 @@
*
*/
-/*
- * New Nov 1997: Use ST-RAM as swap space!
- *
- * In the past, there were often problems with modules that require ST-RAM
- * buffers. Such drivers have to use __get_dma_pages(), which unfortunately
- * often isn't very successful in allocating more than 1 page :-( [1] The net
- * result was that most of the time you couldn't insmod such modules (ataflop,
- * ACSI, SCSI on Falcon, Atari internal framebuffer, not to speak of acsi_slm,
- * which needs a 1 MB buffer... :-).
- *
- * To overcome this limitation, ST-RAM can now be turned into a very
- * high-speed swap space. If a request for an ST-RAM buffer comes, the kernel
- * now tries to unswap some pages on that swap device to make some free (and
- * contiguous) space. This works much better in comparison to
- * __get_dma_pages(), since used swap pages can be selectively freed by either
- * moving them to somewhere else in swap space, or by reading them back into
- * system memory. Ok, there operation of unswapping isn't really cheap (for
- * each page, one has to go through the page tables of all processes), but it
- * doesn't happen that often (only when allocation ST-RAM, i.e. when loading a
- * module that needs ST-RAM). But it at least makes it possible to load such
- * modules!
- *
- * It could also be that overall system performance increases a bit due to
- * ST-RAM swapping, since slow ST-RAM isn't used anymore for holding data or
- * executing code in. It's then just a (very fast, compared to disk) back
- * storage for not-so-often needed data. (But this effect must be compared
- * with the loss of total memory...) Don't know if the effect is already
- * visible on a TT, where the speed difference between ST- and TT-RAM isn't
- * that dramatic, but it should on machines where TT-RAM is really much faster
- * (e.g. Afterburner).
- *
- * [1]: __get_free_pages() does a fine job if you only want one page, but if
- * you want more (contiguous) pages, it can give you such a block only if
- * there's already a free one. The algorithm can't try to free buffers or swap
- * out something in order to make more free space, since all that page-freeing
- * mechanisms work "target-less", i.e. they just free something, but not in a
- * specific place. I.e., __get_free_pages() can't do anything to free
- * *adjacent* pages :-( This situation becomes even worse for DMA memory,
- * since the freeing algorithms are also blind to DMA capability of pages.
- */
-
-/* 1998-10-20: ++andreas
- unswap_by_move disabled because it does not handle swapped shm pages.
-*/
-
-/* 2000-05-01: ++andreas
- Integrated with bootmem. Remove all traces of unswap_by_move.
-*/
-
-#ifdef CONFIG_STRAM_SWAP
-#define ALIGN_IF_SWAP(x) PAGE_ALIGN(x)
-#else
-#define ALIGN_IF_SWAP(x) (x)
-#endif
-
-/* get index of swap page at address 'addr' */
-#define SWAP_NR(addr) (((addr) - swap_start) >> PAGE_SHIFT)
-
-/* get address of swap page #'nr' */
-#define SWAP_ADDR(nr) (swap_start + ((nr) << PAGE_SHIFT))
-
-/* get number of pages for 'n' bytes (already page-aligned) */
-#define N_PAGES(n) ((n) >> PAGE_SHIFT)
-
-/* The following two numbers define the maximum fraction of ST-RAM in total
- * memory, below that the kernel would automatically use ST-RAM as swap
- * space. This decision can be overridden with stram_swap= */
-#define MAX_STRAM_FRACTION_NOM 1
-#define MAX_STRAM_FRACTION_DENOM 3
-
/* Start and end (virtual) of ST-RAM */
static void *stram_start, *stram_end;
@@ -164,10 +89,9 @@ typedef struct stram_block {
} BLOCK;
/* values for flags field */
-#define BLOCK_FREE 0x01 /* free structure in the BLOCKs pool */
+#define BLOCK_FREE 0x01 /* free structure in the BLOCKs pool */
#define BLOCK_KMALLOCED 0x02 /* structure allocated by kmalloc() */
-#define BLOCK_GFP 0x08 /* block allocated with __get_dma_pages() */
-#define BLOCK_INSWAP 0x10 /* block allocated in swap space */
+#define BLOCK_GFP 0x08 /* block allocated with __get_dma_pages() */
/* list of allocated blocks */
static BLOCK *alloc_list;
@@ -179,60 +103,8 @@ static BLOCK *alloc_list;
#define N_STATIC_BLOCKS 20
static BLOCK static_blocks[N_STATIC_BLOCKS];
-#ifdef CONFIG_STRAM_SWAP
-/* max. number of bytes to use for swapping
- * 0 = no ST-RAM swapping
- * -1 = do swapping (to whole ST-RAM) if it's less than MAX_STRAM_FRACTION of
- * total memory
- */
-static int max_swap_size = -1;
-
-/* start and end of swapping area */
-static void *swap_start, *swap_end;
-
-/* The ST-RAM's swap info structure */
-static struct swap_info_struct *stram_swap_info;
-
-/* The ST-RAM's swap type */
-static int stram_swap_type;
-
-/* Semaphore for get_stram_region. */
-static DECLARE_MUTEX(stram_swap_sem);
-
-/* major and minor device number of the ST-RAM device; for the major, we use
- * the same as Amiga z2ram, which is really similar and impossible on Atari,
- * and for the minor a relatively odd number to avoid the user creating and
- * using that device. */
-#define STRAM_MAJOR Z2RAM_MAJOR
-#define STRAM_MINOR 13
-
-/* Some impossible pointer value */
-#define MAGIC_FILE_P (struct file *)0xffffdead
-
-#ifdef DO_PROC
-static unsigned stat_swap_read;
-static unsigned stat_swap_write;
-static unsigned stat_swap_force;
-#endif /* DO_PROC */
-
-#endif /* CONFIG_STRAM_SWAP */
-
/***************************** Prototypes *****************************/
-#ifdef CONFIG_STRAM_SWAP
-static int swap_init(void *start_mem, void *swap_data);
-static void *get_stram_region( unsigned long n_pages );
-static void free_stram_region( unsigned long offset, unsigned long n_pages
- );
-static int in_some_region(void *addr);
-static unsigned long find_free_region( unsigned long n_pages, unsigned long
- *total_free, unsigned long
- *region_free );
-static void do_stram_request(request_queue_t *);
-static int stram_open( struct inode *inode, struct file *filp );
-static int stram_release( struct inode *inode, struct file *filp );
-static void reserve_region(void *start, void *end);
-#endif
static BLOCK *add_region( void *addr, unsigned long size );
static BLOCK *find_region( void *addr );
static int remove_region( BLOCK *block );
@@ -279,84 +151,11 @@ void __init atari_stram_init(void)
*/
void __init atari_stram_reserve_pages(void *start_mem)
{
-#ifdef CONFIG_STRAM_SWAP
- /* if max_swap_size is negative (i.e. no stram_swap= option given),
- * determine at run time whether to use ST-RAM swapping */
- if (max_swap_size < 0)
- /* Use swapping if ST-RAM doesn't make up more than MAX_STRAM_FRACTION
- * of total memory. In that case, the max. size is set to 16 MB,
- * because ST-RAM can never be bigger than that.
- * Also, never use swapping on a Hades, there's no separate ST-RAM in
- * that machine. */
- max_swap_size =
- (!MACH_IS_HADES &&
- (N_PAGES(stram_end-stram_start)*MAX_STRAM_FRACTION_DENOM <=
- ((unsigned long)high_memory>>PAGE_SHIFT)*MAX_STRAM_FRACTION_NOM)) ? 16*1024*1024 : 0;
- DPRINTK( "atari_stram_reserve_pages: max_swap_size = %d\n", max_swap_size );
-#endif
-
/* always reserve first page of ST-RAM, the first 2 kB are
* supervisor-only! */
if (!kernel_in_stram)
reserve_bootmem (0, PAGE_SIZE);
-#ifdef CONFIG_STRAM_SWAP
- {
- void *swap_data;
-
- start_mem = (void *) PAGE_ALIGN ((unsigned long) start_mem);
- /* determine first page to use as swap: if the kernel is
- in TT-RAM, this is the first page of (usable) ST-RAM;
- otherwise just use the end of kernel data (= start_mem) */
- swap_start = !kernel_in_stram ? stram_start + PAGE_SIZE : start_mem;
- /* decrement by one page, rest of kernel assumes that first swap page
- * is always reserved and maybe doesn't handle swp_entry == 0
- * correctly */
- swap_start -= PAGE_SIZE;
- swap_end = stram_end;
- if (swap_end-swap_start > max_swap_size)
- swap_end = swap_start + max_swap_size;
- DPRINTK( "atari_stram_reserve_pages: swapping enabled; "
- "swap=%p-%p\n", swap_start, swap_end);
-
- /* reserve some amount of memory for maintainance of
- * swapping itself: one page for each 2048 (PAGE_SIZE/2)
- * swap pages. (2 bytes for each page) */
- swap_data = start_mem;
- start_mem += ((SWAP_NR(swap_end) + PAGE_SIZE/2 - 1)
- >> (PAGE_SHIFT-1)) << PAGE_SHIFT;
- /* correct swap_start if necessary */
- if (swap_start + PAGE_SIZE == swap_data)
- swap_start = start_mem - PAGE_SIZE;
-
- if (!swap_init( start_mem, swap_data )) {
- printk( KERN_ERR "ST-RAM swap space initialization failed\n" );
- max_swap_size = 0;
- return;
- }
- /* reserve region for swapping meta-data */
- reserve_region(swap_data, start_mem);
- /* reserve swapping area itself */
- reserve_region(swap_start + PAGE_SIZE, swap_end);
-
- /*
- * If the whole ST-RAM is used for swapping, there are no allocatable
- * dma pages left. But unfortunately, some shared parts of the kernel
- * (particularly the SCSI mid-level) call __get_dma_pages()
- * unconditionally :-( These calls then fail, and scsi.c even doesn't
- * check for NULL return values and just crashes. The quick fix for
- * this (instead of doing much clean up work in the SCSI code) is to
- * pretend all pages are DMA-able by setting mach_max_dma_address to
- * ULONG_MAX. This doesn't change any functionality so far, since
- * get_dma_pages() shouldn't be used on Atari anyway anymore (better
- * use atari_stram_alloc()), and the Atari SCSI drivers don't need DMA
- * memory. But unfortunately there's now no kind of warning (even not
- * a NULL return value) if you use get_dma_pages() nevertheless :-(
- * You just will get non-DMA-able memory...
- */
- mach_max_dma_address = 0xffffffff;
- }
-#endif
}
void atari_stram_mem_init_hook (void)
@@ -367,7 +166,6 @@ void atari_stram_mem_init_hook (void)
/*
* This is main public interface: somehow allocate a ST-RAM block
- * There are three strategies:
*
* - If we're before mem_init(), we have to make a static allocation. The
* region is taken in the kernel data area (if the kernel is in ST-RAM) or
@@ -375,14 +173,9 @@ void atari_stram_mem_init_hook (void)
* rsvd_stram_* region. The ST-RAM is somewhere in the middle of kernel
* address space in the latter case.
*
- * - If mem_init() already has been called and ST-RAM swapping is enabled,
- * try to get the memory from the (pseudo) swap-space, either free already
- * or by moving some other pages out of the swap.
- *
- * - If mem_init() already has been called, and ST-RAM swapping is not
- * enabled, the only possibility is to try with __get_dma_pages(). This has
- * the disadvantage that it's very hard to get more than 1 page, and it is
- * likely to fail :-(
+ * - If mem_init() already has been called, try with __get_dma_pages().
+ * This has the disadvantage that it's very hard to get more than 1 page,
+ * and it is likely to fail :-(
*
*/
void *atari_stram_alloc(long size, const char *owner)
@@ -393,27 +186,13 @@ void *atari_stram_alloc(long size, const char *owner)
DPRINTK("atari_stram_alloc(size=%08lx,owner=%s)\n", size, owner);
- size = ALIGN_IF_SWAP(size);
- DPRINTK( "atari_stram_alloc: rounded size = %08lx\n", size );
-#ifdef CONFIG_STRAM_SWAP
- if (max_swap_size) {
- /* If swapping is active: make some free space in the swap
- "device". */
- DPRINTK( "atari_stram_alloc: after mem_init, swapping ok, "
- "calling get_region\n" );
- addr = get_stram_region( N_PAGES(size) );
- flags = BLOCK_INSWAP;
- }
- else
-#endif
if (!mem_init_done)
return alloc_bootmem_low(size);
else {
- /* After mem_init() and no swapping: can only resort to
- * __get_dma_pages() */
+ /* After mem_init(): can only resort to __get_dma_pages() */
addr = (void *)__get_dma_pages(GFP_KERNEL, get_order(size));
flags = BLOCK_GFP;
- DPRINTK( "atari_stram_alloc: after mem_init, swapping off, "
+ DPRINTK( "atari_stram_alloc: after mem_init, "
"get_pages=%p\n", addr );
}
@@ -422,12 +201,7 @@ void *atari_stram_alloc(long size, const char *owner)
/* out of memory for BLOCK structure :-( */
DPRINTK( "atari_stram_alloc: out of mem for BLOCK -- "
"freeing again\n" );
-#ifdef CONFIG_STRAM_SWAP
- if (flags == BLOCK_INSWAP)
- free_stram_region( SWAP_NR(addr), N_PAGES(size) );
- else
-#endif
- free_pages((unsigned long)addr, get_order(size));
+ free_pages((unsigned long)addr, get_order(size));
return( NULL );
}
block->owner = owner;
@@ -451,25 +225,12 @@ void atari_stram_free( void *addr )
DPRINTK( "atari_stram_free: found block (%p): size=%08lx, owner=%s, "
"flags=%02x\n", block, block->size, block->owner, block->flags );
-#ifdef CONFIG_STRAM_SWAP
- if (!max_swap_size) {
-#endif
- if (block->flags & BLOCK_GFP) {
- DPRINTK("atari_stram_free: is kmalloced, order_size=%d\n",
- get_order(block->size));
- free_pages((unsigned long)addr, get_order(block->size));
- }
- else
- goto fail;
-#ifdef CONFIG_STRAM_SWAP
- }
- else if (block->flags & BLOCK_INSWAP) {
- DPRINTK( "atari_stram_free: is swap-alloced\n" );
- free_stram_region( SWAP_NR(block->start), N_PAGES(block->size) );
- }
- else
+ if (!(block->flags & BLOCK_GFP))
goto fail;
-#endif
+
+ DPRINTK("atari_stram_free: is kmalloced, order_size=%d\n",
+ get_order(block->size));
+ free_pages((unsigned long)addr, get_order(block->size));
remove_region( block );
return;
@@ -478,612 +239,6 @@ void atari_stram_free( void *addr )
"(called from %p)\n", addr, __builtin_return_address(0) );
}
-
-#ifdef CONFIG_STRAM_SWAP
-
-
-/* ------------------------------------------------------------------------ */
-/* Main Swapping Functions */
-/* ------------------------------------------------------------------------ */
-
-
-/*
- * Initialize ST-RAM swap device
- * (lots copied and modified from sys_swapon() in mm/swapfile.c)
- */
-static int __init swap_init(void *start_mem, void *swap_data)
-{
- static struct dentry fake_dentry;
- static struct vfsmount fake_vfsmnt;
- struct swap_info_struct *p;
- struct inode swap_inode;
- unsigned int type;
- void *addr;
- int i, j, k, prev;
-
- DPRINTK("swap_init(start_mem=%p, swap_data=%p)\n",
- start_mem, swap_data);
-
- /* need at least one page for swapping to (and this also isn't very
- * much... :-) */
- if (swap_end - swap_start < 2*PAGE_SIZE) {
- printk( KERN_WARNING "stram_swap_init: swap space too small\n" );
- return( 0 );
- }
-
- /* find free slot in swap_info */
- for( p = swap_info, type = 0; type < nr_swapfiles; type++, p++ )
- if (!(p->flags & SWP_USED))
- break;
- if (type >= MAX_SWAPFILES) {
- printk( KERN_WARNING "stram_swap_init: max. number of "
- "swap devices exhausted\n" );
- return( 0 );
- }
- if (type >= nr_swapfiles)
- nr_swapfiles = type+1;
-
- stram_swap_info = p;
- stram_swap_type = type;
-
- /* fake some dir cache entries to give us some name in /dev/swaps */
- fake_dentry.d_parent = &fake_dentry;
- fake_dentry.d_name.name = "stram (internal)";
- fake_dentry.d_name.len = 16;
- fake_vfsmnt.mnt_parent = &fake_vfsmnt;
-
- p->flags = SWP_USED;
- p->swap_file = &fake_dentry;
- p->swap_vfsmnt = &fake_vfsmnt;
- p->swap_map = swap_data;
- p->cluster_nr = 0;
- p->next = -1;
- p->prio = 0x7ff0; /* a rather high priority, but not the higest
- * to give the user a chance to override */
-
- /* call stram_open() directly, avoids at least the overhead in
- * constructing a dummy file structure... */
- swap_inode.i_rdev = MKDEV( STRAM_MAJOR, STRAM_MINOR );
- stram_open( &swap_inode, MAGIC_FILE_P );
- p->max = SWAP_NR(swap_end);
-
- /* initialize swap_map: set regions that are already allocated or belong
- * to kernel data space to SWAP_MAP_BAD, otherwise to free */
- j = 0; /* # of free pages */
- k = 0; /* # of already allocated pages (from pre-mem_init stram_alloc()) */
- p->lowest_bit = 0;
- p->highest_bit = 0;
- for( i = 1, addr = SWAP_ADDR(1); i < p->max;
- i++, addr += PAGE_SIZE ) {
- if (in_some_region( addr )) {
- p->swap_map[i] = SWAP_MAP_BAD;
- ++k;
- }
- else if (kernel_in_stram && addr < start_mem ) {
- p->swap_map[i] = SWAP_MAP_BAD;
- }
- else {
- p->swap_map[i] = 0;
- ++j;
- if (!p->lowest_bit) p->lowest_bit = i;
- p->highest_bit = i;
- }
- }
- /* first page always reserved (and doesn't really belong to swap space) */
- p->swap_map[0] = SWAP_MAP_BAD;
-
- /* now swapping to this device ok */
- p->pages = j + k;
- swap_list_lock();
- nr_swap_pages += j;
- p->flags = SWP_WRITEOK;
-
- /* insert swap space into swap_list */
- prev = -1;
- for (i = swap_list.head; i >= 0; i = swap_info[i].next) {
- if (p->prio >= swap_info[i].prio) {
- break;
- }
- prev = i;
- }
- p->next = i;
- if (prev < 0) {
- swap_list.head = swap_list.next = p - swap_info;
- } else {
- swap_info[prev].next = p - swap_info;
- }
- swap_list_unlock();
-
- printk( KERN_INFO "Using %dk (%d pages) of ST-RAM as swap space.\n",
- p->pages << 2, p->pages );
- return( 1 );
-}
-
-
-/*
- * The swap entry has been read in advance, and we return 1 to indicate
- * that the page has been used or is no longer needed.
- *
- * Always set the resulting pte to be nowrite (the same as COW pages
- * after one process has exited). We don't know just how many PTEs will
- * share this swap entry, so be cautious and let do_wp_page work out
- * what to do if a write is requested later.
- */
-static inline void unswap_pte(struct vm_area_struct * vma, unsigned long
- address, pte_t *dir, swp_entry_t entry,
- struct page *page)
-{
- pte_t pte = *dir;
-
- if (pte_none(pte))
- return;
- if (pte_present(pte)) {
- /* If this entry is swap-cached, then page must already
- hold the right address for any copies in physical
- memory */
- if (pte_page(pte) != page)
- return;
- /* We will be removing the swap cache in a moment, so... */
- set_pte(dir, pte_mkdirty(pte));
- return;
- }
- if (pte_val(pte) != entry.val)
- return;
-
- DPRINTK("unswap_pte: replacing entry %08lx by new page %p",
- entry.val, page);
- set_pte(dir, pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
- swap_free(entry);
- get_page(page);
- inc_mm_counter(vma->vm_mm, rss);
-}
-
-static inline void unswap_pmd(struct vm_area_struct * vma, pmd_t *dir,
- unsigned long address, unsigned long size,
- unsigned long offset, swp_entry_t entry,
- struct page *page)
-{
- pte_t * pte;
- unsigned long end;
-
- if (pmd_none(*dir))
- return;
- if (pmd_bad(*dir)) {
- pmd_ERROR(*dir);
- pmd_clear(dir);
- return;
- }
- pte = pte_offset_kernel(dir, address);
- offset += address & PMD_MASK;
- address &= ~PMD_MASK;
- end = address + size;
- if (end > PMD_SIZE)
- end = PMD_SIZE;
- do {
- unswap_pte(vma, offset+address-vma->vm_start, pte, entry, page);
- address += PAGE_SIZE;
- pte++;
- } while (address < end);
-}
-
-static inline void unswap_pgd(struct vm_area_struct * vma, pgd_t *dir,
- unsigned long address, unsigned long size,
- swp_entry_t entry, struct page *page)
-{
- pmd_t * pmd;
- unsigned long offset, end;
-
- if (pgd_none(*dir))
- return;
- if (pgd_bad(*dir)) {
- pgd_ERROR(*dir);
- pgd_clear(dir);
- return;
- }
- pmd = pmd_offset(dir, address);
- offset = address & PGDIR_MASK;
- address &= ~PGDIR_MASK;
- end = address + size;
- if (end > PGDIR_SIZE)
- end = PGDIR_SIZE;
- do {
- unswap_pmd(vma, pmd, address, end - address, offset, entry,
- page);
- address = (address + PMD_SIZE) & PMD_MASK;
- pmd++;
- } while (address < end);
-}
-
-static void unswap_vma(struct vm_area_struct * vma, pgd_t *pgdir,
- swp_entry_t entry, struct page *page)
-{
- unsigned long start = vma->vm_start, end = vma->vm_end;
-
- do {
- unswap_pgd(vma, pgdir, start, end - start, entry, page);
- start = (start + PGDIR_SIZE) & PGDIR_MASK;
- pgdir++;
- } while (start < end);
-}
-
-static void unswap_process(struct mm_struct * mm, swp_entry_t entry,
- struct page *page)
-{
- struct vm_area_struct* vma;
-
- /*
- * Go through process' page directory.
- */
- if (!mm)
- return;
- for (vma = mm->mmap; vma; vma = vma->vm_next) {
- pgd_t * pgd = pgd_offset(mm, vma->vm_start);
- unswap_vma(vma, pgd, entry, page);
- }
-}
-
-
-static int unswap_by_read(unsigned short *map, unsigned long max,
- unsigned long start, unsigned long n_pages)
-{
- struct task_struct *p;
- struct page *page;
- swp_entry_t entry;
- unsigned long i;
-
- DPRINTK( "unswapping %lu..%lu by reading in\n",
- start, start+n_pages-1 );
-
- for( i = start; i < start+n_pages; ++i ) {
- if (map[i] == SWAP_MAP_BAD) {
- printk( KERN_ERR "get_stram_region: page %lu already "
- "reserved??\n", i );
- continue;
- }
-
- if (map[i]) {
- entry = swp_entry(stram_swap_type, i);
- DPRINTK("unswap: map[i=%lu]=%u nr_swap=%ld\n",
- i, map[i], nr_swap_pages);
-
- swap_device_lock(stram_swap_info);
- map[i]++;
- swap_device_unlock(stram_swap_info);
- /* Get a page for the entry, using the existing
- swap cache page if there is one. Otherwise,
- get a clean page and read the swap into it. */
- page = read_swap_cache_async(entry, NULL, 0);
- if (!page) {
- swap_free(entry);
- return -ENOMEM;
- }
- read_lock(&tasklist_lock);
- for_each_process(p)
- unswap_process(p->mm, entry, page);
- read_unlock(&tasklist_lock);
- shmem_unuse(entry, page);
- /* Now get rid of the extra reference to the
- temporary page we've been using. */
- if (PageSwapCache(page))
- delete_from_swap_cache(page);
- __free_page(page);
- #ifdef DO_PROC
- stat_swap_force++;
- #endif
- }
-
- DPRINTK( "unswap: map[i=%lu]=%u nr_swap=%ld\n",
- i, map[i], nr_swap_pages );
- swap_list_lock();
- swap_device_lock(stram_swap_info);
- map[i] = SWAP_MAP_BAD;
- if (stram_swap_info->lowest_bit == i)
- stram_swap_info->lowest_bit++;
- if (stram_swap_info->highest_bit == i)
- stram_swap_info->highest_bit--;
- --nr_swap_pages;
- swap_device_unlock(stram_swap_info);
- swap_list_unlock();
- }
-
- return 0;
-}
-
-/*
- * reserve a region in ST-RAM swap space for an allocation
- */
-static void *get_stram_region( unsigned long n_pages )
-{
- unsigned short *map = stram_swap_info->swap_map;
- unsigned long max = stram_swap_info->max;
- unsigned long start, total_free, region_free;
- int err;
- void *ret = NULL;
-
- DPRINTK( "get_stram_region(n_pages=%lu)\n", n_pages );
-
- down(&stram_swap_sem);
-
- /* disallow writing to the swap device now */
- stram_swap_info->flags = SWP_USED;
-
- /* find a region of n_pages pages in the swap space including as much free
- * pages as possible (and excluding any already-reserved pages). */
- if (!(start = find_free_region( n_pages, &total_free, &region_free )))
- goto end;
- DPRINTK( "get_stram_region: region starts at %lu, has %lu free pages\n",
- start, region_free );
-
- err = unswap_by_read(map, max, start, n_pages);
- if (err)
- goto end;
-
- ret = SWAP_ADDR(start);
- end:
- /* allow using swap device again */
- stram_swap_info->flags = SWP_WRITEOK;
- up(&stram_swap_sem);
- DPRINTK( "get_stram_region: returning %p\n", ret );
- return( ret );
-}
-
-
-/*
- * free a reserved region in ST-RAM swap space
- */
-static void free_stram_region( unsigned long offset, unsigned long n_pages )
-{
- unsigned short *map = stram_swap_info->swap_map;
-
- DPRINTK( "free_stram_region(offset=%lu,n_pages=%lu)\n", offset, n_pages );
-
- if (offset < 1 || offset + n_pages > stram_swap_info->max) {
- printk( KERN_ERR "free_stram_region: Trying to free non-ST-RAM\n" );
- return;
- }
-
- swap_list_lock();
- swap_device_lock(stram_swap_info);
- /* un-reserve the freed pages */
- for( ; n_pages > 0; ++offset, --n_pages ) {
- if (map[offset] != SWAP_MAP_BAD)
- printk( KERN_ERR "free_stram_region: Swap page %lu was not "
- "reserved\n", offset );
- map[offset] = 0;
- }
-
- /* update swapping meta-data */
- if (offset < stram_swap_info->lowest_bit)
- stram_swap_info->lowest_bit = offset;
- if (offset+n_pages-1 > stram_swap_info->highest_bit)
- stram_swap_info->highest_bit = offset+n_pages-1;
- if (stram_swap_info->prio > swap_info[swap_list.next].prio)
- swap_list.next = swap_list.head;
- nr_swap_pages += n_pages;
- swap_device_unlock(stram_swap_info);
- swap_list_unlock();
-}
-
-
-/* ------------------------------------------------------------------------ */
-/* Utility Functions for Swapping */
-/* ------------------------------------------------------------------------ */
-
-
-/* is addr in some of the allocated regions? */
-static int in_some_region(void *addr)
-{
- BLOCK *p;
-
- for( p = alloc_list; p; p = p->next ) {
- if (p->start <= addr && addr < p->start + p->size)
- return( 1 );
- }
- return( 0 );
-}
-
-
-static unsigned long find_free_region(unsigned long n_pages,
- unsigned long *total_free,
- unsigned long *region_free)
-{
- unsigned short *map = stram_swap_info->swap_map;
- unsigned long max = stram_swap_info->max;
- unsigned long head, tail, max_start;
- long nfree, max_free;
-
- /* first scan the swap space for a suitable place for the allocation */
- head = 1;
- max_start = 0;
- max_free = -1;
- *total_free = 0;
-
- start_over:
- /* increment tail until final window size reached, and count free pages */
- nfree = 0;
- for( tail = head; tail-head < n_pages && tail < max; ++tail ) {
- if (map[tail] == SWAP_MAP_BAD) {
- head = tail+1;
- goto start_over;
- }
- if (!map[tail]) {
- ++nfree;
- ++*total_free;
- }
- }
- if (tail-head < n_pages)
- goto out;
- if (nfree > max_free) {
- max_start = head;
- max_free = nfree;
- if (max_free >= n_pages)
- /* don't need more free pages... :-) */
- goto out;
- }
-
- /* now shift the window and look for the area where as much pages as
- * possible are free */
- while( tail < max ) {
- nfree -= (map[head++] == 0);
- if (map[tail] == SWAP_MAP_BAD) {
- head = tail+1;
- goto start_over;
- }
- if (!map[tail]) {
- ++nfree;
- ++*total_free;
- }
- ++tail;
- if (nfree > max_free) {
- max_start = head;
- max_free = nfree;
- if (max_free >= n_pages)
- /* don't need more free pages... :-) */
- goto out;
- }
- }
-
- out:
- if (max_free < 0) {
- printk( KERN_NOTICE "get_stram_region: ST-RAM too full or fragmented "
- "-- can't allocate %lu pages\n", n_pages );
- return( 0 );
- }
-
- *region_free = max_free;
- return( max_start );
-}
-
-
-/* setup parameters from command line */
-void __init stram_swap_setup(char *str, int *ints)
-{
- if (ints[0] >= 1)
- max_swap_size = ((ints[1] < 0 ? 0 : ints[1]) * 1024) & PAGE_MASK;
-}
-
-
-/* ------------------------------------------------------------------------ */
-/* ST-RAM device */
-/* ------------------------------------------------------------------------ */
-
-static int refcnt;
-
-static void do_stram_request(request_queue_t *q)
-{
- struct request *req;
-
- while ((req = elv_next_request(q)) != NULL) {
- void *start = swap_start + (req->sector << 9);
- unsigned long len = req->current_nr_sectors << 9;
- if ((start + len) > swap_end) {
- printk( KERN_ERR "stram: bad access beyond end of device: "
- "block=%ld, count=%d\n",
- req->sector,
- req->current_nr_sectors );
- end_request(req, 0);
- continue;
- }
-
- if (req->cmd == READ) {
- memcpy(req->buffer, start, len);
-#ifdef DO_PROC
- stat_swap_read += N_PAGES(len);
-#endif
- }
- else {
- memcpy(start, req->buffer, len);
-#ifdef DO_PROC
- stat_swap_write += N_PAGES(len);
-#endif
- }
- end_request(req, 1);
- }
-}
-
-
-static int stram_open( struct inode *inode, struct file *filp )
-{
- if (filp != MAGIC_FILE_P) {
- printk( KERN_NOTICE "Only kernel can open ST-RAM device\n" );
- return( -EPERM );
- }
- if (refcnt)
- return( -EBUSY );
- ++refcnt;
- return( 0 );
-}
-
-static int stram_release( struct inode *inode, struct file *filp )
-{
- if (filp != MAGIC_FILE_P) {
- printk( KERN_NOTICE "Only kernel can close ST-RAM device\n" );
- return( -EPERM );
- }
- if (refcnt > 0)
- --refcnt;
- return( 0 );
-}
-
-
-static struct block_device_operations stram_fops = {
- .open = stram_open,
- .release = stram_release,
-};
-
-static struct gendisk *stram_disk;
-static struct request_queue *stram_queue;
-static DEFINE_SPINLOCK(stram_lock);
-
-int __init stram_device_init(void)
-{
- if (!MACH_IS_ATARI)
- /* no point in initializing this, I hope */
- return -ENXIO;
-
- if (!max_swap_size)
- /* swapping not enabled */
- return -ENXIO;
- stram_disk = alloc_disk(1);
- if (!stram_disk)
- return -ENOMEM;
-
- if (register_blkdev(STRAM_MAJOR, "stram")) {
- put_disk(stram_disk);
- return -ENXIO;
- }
-
- stram_queue = blk_init_queue(do_stram_request, &stram_lock);
- if (!stram_queue) {
- unregister_blkdev(STRAM_MAJOR, "stram");
- put_disk(stram_disk);
- return -ENOMEM;
- }
-
- stram_disk->major = STRAM_MAJOR;
- stram_disk->first_minor = STRAM_MINOR;
- stram_disk->fops = &stram_fops;
- stram_disk->queue = stram_queue;
- sprintf(stram_disk->disk_name, "stram");
- set_capacity(stram_disk, (swap_end - swap_start)/512);
- add_disk(stram_disk);
- return 0;
-}
-
-
-
-/* ------------------------------------------------------------------------ */
-/* Misc Utility Functions */
-/* ------------------------------------------------------------------------ */
-
-/* reserve a range of pages */
-static void reserve_region(void *start, void *end)
-{
- reserve_bootmem (virt_to_phys(start), end - start);
-}
-
-#endif /* CONFIG_STRAM_SWAP */
-
/* ------------------------------------------------------------------------ */
/* Region Management */
@@ -1173,50 +328,9 @@ int get_stram_list( char *buf )
{
int len = 0;
BLOCK *p;
-#ifdef CONFIG_STRAM_SWAP
- int i;
- unsigned short *map = stram_swap_info->swap_map;
- unsigned long max = stram_swap_info->max;
- unsigned free = 0, used = 0, rsvd = 0;
-#endif
-#ifdef CONFIG_STRAM_SWAP
- if (max_swap_size) {
- for( i = 1; i < max; ++i ) {
- if (!map[i])
- ++free;
- else if (map[i] == SWAP_MAP_BAD)
- ++rsvd;
- else
- ++used;
- }
- PRINT_PROC(
- "Total ST-RAM: %8u kB\n"
- "Total ST-RAM swap: %8lu kB\n"
- "Free swap: %8u kB\n"
- "Used swap: %8u kB\n"
- "Allocated swap: %8u kB\n"
- "Swap Reads: %8u\n"
- "Swap Writes: %8u\n"
- "Swap Forced Reads: %8u\n",
- (stram_end - stram_start) >> 10,
- (max-1) << (PAGE_SHIFT-10),
- free << (PAGE_SHIFT-10),
- used << (PAGE_SHIFT-10),
- rsvd << (PAGE_SHIFT-10),
- stat_swap_read,
- stat_swap_write,
- stat_swap_force );
- }
- else {
-#endif
- PRINT_PROC( "ST-RAM swapping disabled\n" );
- PRINT_PROC("Total ST-RAM: %8u kB\n",
+ PRINT_PROC("Total ST-RAM: %8u kB\n",
(stram_end - stram_start) >> 10);
-#ifdef CONFIG_STRAM_SWAP
- }
-#endif
-
PRINT_PROC( "Allocated regions:\n" );
for( p = alloc_list; p; p = p->next ) {
if (len + 50 >= PAGE_SIZE)
@@ -1227,8 +341,6 @@ int get_stram_list( char *buf )
p->owner);
if (p->flags & BLOCK_GFP)
PRINT_PROC( "page-alloced)\n" );
- else if (p->flags & BLOCK_INSWAP)
- PRINT_PROC( "in swap)\n" );
else
PRINT_PROC( "??)\n" );
}
diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c
index 8ed1b01a6a87..f7f1d2e5b90b 100644
--- a/arch/m68k/kernel/ptrace.c
+++ b/arch/m68k/kernel/ptrace.c
@@ -121,7 +121,7 @@ void ptrace_disable(struct task_struct *child)
child->thread.work.syscall_trace = 0;
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
unsigned long tmp;
diff --git a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c
index 4ec95e3cb874..98e4b1adfa29 100644
--- a/arch/m68k/kernel/time.c
+++ b/arch/m68k/kernel/time.c
@@ -27,10 +27,6 @@
#include <linux/timex.h>
#include <linux/profile.h>
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
static inline int set_rtc_mmss(unsigned long nowtime)
{
if (mach_set_clock_mmss)
diff --git a/arch/m68k/mm/kmap.c b/arch/m68k/mm/kmap.c
index 5dcb3fa35ea9..fe2383e36b06 100644
--- a/arch/m68k/mm/kmap.c
+++ b/arch/m68k/mm/kmap.c
@@ -201,7 +201,7 @@ void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
virtaddr += PTRTREESIZE;
size -= PTRTREESIZE;
} else {
- pte_dir = pte_alloc_kernel(&init_mm, pmd_dir, virtaddr);
+ pte_dir = pte_alloc_kernel(pmd_dir, virtaddr);
if (!pte_dir) {
printk("ioremap: no mem for pte_dir\n");
return NULL;
diff --git a/arch/m68k/sun3x/dvma.c b/arch/m68k/sun3x/dvma.c
index 32e55adfeb8e..117481e86305 100644
--- a/arch/m68k/sun3x/dvma.c
+++ b/arch/m68k/sun3x/dvma.c
@@ -116,7 +116,7 @@ inline int dvma_map_cpu(unsigned long kaddr,
pte_t *pte;
unsigned long end3;
- if((pte = pte_alloc_kernel(&init_mm, pmd, vaddr)) == NULL) {
+ if((pte = pte_alloc_kernel(pmd, vaddr)) == NULL) {
ret = -ENOMEM;
goto out;
}
diff --git a/arch/m68knommu/kernel/ptrace.c b/arch/m68knommu/kernel/ptrace.c
index 9724e1cd82e5..621d7b91ccfe 100644
--- a/arch/m68knommu/kernel/ptrace.c
+++ b/arch/m68knommu/kernel/ptrace.c
@@ -101,7 +101,7 @@ void ptrace_disable(struct task_struct *child)
put_reg(child, PT_SR, tmp);
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
int ret;
diff --git a/arch/m68knommu/kernel/time.c b/arch/m68knommu/kernel/time.c
index b17c1ecba966..b9d8abb45430 100644
--- a/arch/m68knommu/kernel/time.c
+++ b/arch/m68knommu/kernel/time.c
@@ -27,10 +27,6 @@
#define TICK_SIZE (tick_nsec / 1000)
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
extern unsigned long wall_jiffies;
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 4cd724c05700..0097a0d53b3b 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -4,216 +4,147 @@ config MIPS
# Horrible source of confusion. Die, die, die ...
select EMBEDDED
-# shouldn't it be per-subarchitecture?
-config ARCH_MAY_HAVE_PC_FDC
- bool
- default y
-
mainmenu "Linux/MIPS Kernel Configuration"
source "init/Kconfig"
-config SYS_SUPPORTS_32BIT_KERNEL
- bool
-config SYS_SUPPORTS_64BIT_KERNEL
- bool
-config CPU_SUPPORTS_32BIT_KERNEL
- bool
-config CPU_SUPPORTS_64BIT_KERNEL
- bool
-
-menu "Kernel type"
-
-choice
-
- prompt "Kernel code model"
- help
- You should only select this option if you have a workload that
- actually benefits from 64-bit processing or if your machine has
- large memory. You will only be presented a single option in this
- menu if your system does not support both 32-bit and 64-bit kernels.
-
-config 32BIT
- bool "32-bit kernel"
- depends on CPU_SUPPORTS_32BIT_KERNEL && SYS_SUPPORTS_32BIT_KERNEL
- select TRAD_SIGNALS
- help
- Select this option if you want to build a 32-bit kernel.
-
-config 64BIT
- bool "64-bit kernel"
- depends on CPU_SUPPORTS_64BIT_KERNEL && SYS_SUPPORTS_64BIT_KERNEL
- help
- Select this option if you want to build a 64-bit kernel.
-
-endchoice
-
-endmenu
-
menu "Machine selection"
-config MACH_JAZZ
- bool "Support for the Jazz family of machines"
- select ARC
- select ARC32
- select GENERIC_ISA_DMA
- select I8259
- select ISA
- select SYS_SUPPORTS_32BIT_KERNEL
- select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
- help
- This a family of machines based on the MIPS R4030 chipset which was
- used by several vendors to build RISC/os and Windows NT workstations.
- Members include the Acer PICA, MIPS Magnum 4000, MIPS Millenium and
- Olivetti M700-10 workstations.
+choice
+ prompt "System type"
+ default SGI_IP22
-config ACER_PICA_61
- bool "Support for Acer PICA 1 chipset (EXPERIMENTAL)"
- depends on MACH_JAZZ && EXPERIMENTAL
+config MIPS_MTX1
+ bool "Support for 4G Systems MTX-1 board"
select DMA_NONCOHERENT
- help
- This is a machine with a R4400 133/150 MHz CPU. To compile a Linux
- kernel that runs on these, say Y here. For details about Linux on
- the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
- <http://www.linux-mips.org/>.
+ select HW_HAS_PCI
+ select SOC_AU1500
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_LITTLE_ENDIAN
-config MIPS_MAGNUM_4000
- bool "Support for MIPS Magnum 4000"
- depends on MACH_JAZZ
+config MIPS_BOSPORUS
+ bool "AMD Alchemy Bosporus board"
+ select SOC_AU1500
select DMA_NONCOHERENT
- help
- This is a machine with a R4000 100 MHz CPU. To compile a Linux
- kernel that runs on these, say Y here. For details about Linux on
- the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
- <http://www.linux-mips.org/>.
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_LITTLE_ENDIAN
-config OLIVETTI_M700
- bool "Support for Olivetti M700-10"
- depends on MACH_JAZZ
+config MIPS_PB1000
+ bool "AMD Alchemy PB1000 board"
+ select SOC_AU1000
select DMA_NONCOHERENT
- help
- This is a machine with a R4000 100 MHz CPU. To compile a Linux
- kernel that runs on these, say Y here. For details about Linux on
- the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
- <http://www.linux-mips.org/>.
-
-config MACH_VR41XX
- bool "Support for NEC VR4100 series based machines"
- select SYS_SUPPORTS_32BIT_KERNEL
- select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+ select HW_HAS_PCI
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_LITTLE_ENDIAN
-config NEC_CMBVR4133
- bool "Support for NEC CMB-VR4133"
- depends on MACH_VR41XX
- select CPU_VR41XX
+config MIPS_PB1100
+ bool "AMD Alchemy PB1100 board"
+ select SOC_AU1100
select DMA_NONCOHERENT
- select IRQ_CPU
select HW_HAS_PCI
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_LITTLE_ENDIAN
-config ROCKHOPPER
- bool "Support for Rockhopper baseboard"
- depends on NEC_CMBVR4133
- select I8259
- select HAVE_STD_PC_SERIAL_PORT
+config MIPS_PB1500
+ bool "AMD Alchemy PB1500 board"
+ select SOC_AU1500
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_LITTLE_ENDIAN
-config CASIO_E55
- bool "Support for CASIO CASSIOPEIA E-10/15/55/65"
- depends on MACH_VR41XX
- select CPU_LITTLE_ENDIAN
+config MIPS_PB1550
+ bool "AMD Alchemy PB1550 board"
+ select SOC_AU1550
select DMA_NONCOHERENT
- select IRQ_CPU
- select ISA
+ select HW_HAS_PCI
+ select MIPS_DISABLE_OBSOLETE_IDE
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_LITTLE_ENDIAN
-config IBM_WORKPAD
- bool "Support for IBM WorkPad z50"
- depends on MACH_VR41XX
- select CPU_LITTLE_ENDIAN
+config MIPS_PB1200
+ bool "AMD Alchemy PB1200 board"
+ select SOC_AU1200
select DMA_NONCOHERENT
- select IRQ_CPU
- select ISA
+ select MIPS_DISABLE_OBSOLETE_IDE
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_LITTLE_ENDIAN
-config TANBAC_TB022X
- bool "Support for TANBAC VR4131 multichip module and TANBAC VR4131DIMM"
- depends on MACH_VR41XX
- select CPU_LITTLE_ENDIAN
+config MIPS_DB1000
+ bool "AMD Alchemy DB1000 board"
+ select SOC_AU1000
select DMA_NONCOHERENT
- select IRQ_CPU
select HW_HAS_PCI
- help
- The TANBAC VR4131 multichip module(TB0225) and
- the TANBAC VR4131DIMM(TB0229) are MIPS-based platforms
- manufactured by TANBAC.
- Please refer to <http://www.tanbac.co.jp/>
- about VR4131 multichip module and VR4131DIMM.
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_LITTLE_ENDIAN
-config TANBAC_TB0226
- bool "Support for TANBAC Mbase(TB0226)"
- depends on TANBAC_TB022X
- select GPIO_VR41XX
- help
- The TANBAC Mbase(TB0226) is a MIPS-based platform manufactured by TANBAC.
- Please refer to <http://www.tanbac.co.jp/> about Mbase.
-
-config TANBAC_TB0287
- bool "Support for TANBAC Mini-ITX DIMM base(TB0287)"
- depends on TANBAC_TB022X
- help
- The TANBAC Mini-ITX DIMM base(TB0287) is a MIPS-based platform manufactured by TANBAC.
- Please refer to <http://www.tanbac.co.jp/> about Mini-ITX DIMM base.
-
-config VICTOR_MPC30X
- bool "Support for Victor MP-C303/304"
- depends on MACH_VR41XX
- select CPU_LITTLE_ENDIAN
+config MIPS_DB1100
+ bool "AMD Alchemy DB1100 board"
+ select SOC_AU1100
select DMA_NONCOHERENT
- select IRQ_CPU
- select HW_HAS_PCI
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_LITTLE_ENDIAN
-config ZAO_CAPCELLA
- bool "Support for ZAO Networks Capcella"
- depends on MACH_VR41XX
- select CPU_LITTLE_ENDIAN
+config MIPS_DB1500
+ bool "AMD Alchemy DB1500 board"
+ select SOC_AU1500
select DMA_NONCOHERENT
- select IRQ_CPU
select HW_HAS_PCI
+ select MIPS_DISABLE_OBSOLETE_IDE
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
-config PCI_VR41XX
- bool "Add PCI control unit support of NEC VR4100 series"
- depends on MACH_VR41XX && HW_HAS_PCI
- default y
- select PCI
+config MIPS_DB1550
+ bool "AMD Alchemy DB1550 board"
+ select SOC_AU1550
+ select HW_HAS_PCI
+ select DMA_NONCOHERENT
+ select MIPS_DISABLE_OBSOLETE_IDE
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_LITTLE_ENDIAN
-config VRC4173
- tristate "Add NEC VRC4173 companion chip support"
- depends on MACH_VR41XX && PCI_VR41XX
- ---help---
- The NEC VRC4173 is a companion chip for NEC VR4122/VR4131.
+config MIPS_DB1200
+ bool "AMD Alchemy DB1200 board"
+ select SOC_AU1200
+ select DMA_COHERENT
+ select MIPS_DISABLE_OBSOLETE_IDE
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_LITTLE_ENDIAN
-config TOSHIBA_JMR3927
- bool "Support for Toshiba JMR-TX3927 board"
+config MIPS_MIRAGE
+ bool "AMD Alchemy Mirage board"
select DMA_NONCOHERENT
- select HW_HAS_PCI
- select SWAP_IO_SPACE
- select SYS_SUPPORTS_32BIT_KERNEL
+ select SOC_AU1500
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_LITTLE_ENDIAN
config MIPS_COBALT
bool "Support for Cobalt Server"
- depends on EXPERIMENTAL
select DMA_NONCOHERENT
select HW_HAS_PCI
select I8259
select IRQ_CPU
+ select MIPS_GT64111
+ select SYS_HAS_CPU_NEVADA
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
config MACH_DECSTATION
bool "Support for DECstations"
select BOOT_ELF32
select DMA_NONCOHERENT
+ select EARLY_PRINTK
select IRQ_CPU
+ select SYS_HAS_CPU_R3000
+ select SYS_HAS_CPU_R4X00
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
- ---help---
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ help
This enables support for DEC's MIPS based workstations. For details
see the Linux/MIPS FAQ on <http://www.linux-mips.org/> and the
DECstation porting pages on <http://decstation.unix-ag.org/>.
@@ -234,8 +165,10 @@ config MIPS_EV64120
select DMA_NONCOHERENT
select HW_HAS_PCI
select MIPS_GT64120
+ select SYS_HAS_CPU_R5000
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
help
This is an evaluation board based on the Galileo GT-64120
single-chip system controller that contains a MIPS R5000 compatible
@@ -243,10 +176,6 @@ config MIPS_EV64120
<http://www.marvell.com/>. Say Y here if you wish to build a
kernel for this platform.
-config EVB_PCI1
- bool "Enable Second PCI (PCI1)"
- depends on MIPS_EV64120
-
config MIPS_EV96100
bool "Support for Galileo EV96100 Evaluation board (EXPERIMENTAL)"
depends on EXPERIMENTAL
@@ -256,8 +185,11 @@ config MIPS_EV96100
select MIPS_GT96100
select RM7000_CPU_SCACHE
select SWAP_IO_SPACE
+ select SYS_HAS_CPU_R5000
+ select SYS_HAS_CPU_RM7000
select SYS_SUPPORTS_32BIT_KERNEL
- select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+ select SYS_SUPPORTS_BIG_ENDIAN
help
This is an evaluation board based on the Galileo GT-96100 LAN/WAN
communications controllers containing a MIPS R5000 compatible core
@@ -268,8 +200,11 @@ config MIPS_IVR
bool "Support for Globespan IVR board"
select DMA_NONCOHERENT
select HW_HAS_PCI
+ select ITE_BOARD_GEN
+ select SYS_HAS_CPU_NEVADA
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
help
This is an evaluation board built by Globespan to showcase thir
iVR (Internet Video Recorder) design. It utilizes a QED RM5231
@@ -277,37 +212,16 @@ config MIPS_IVR
located at <http://www.globespan.net/>. Say Y here if you wish to
build a kernel for this platform.
-config LASAT
- bool "Support for LASAT Networks platforms"
- select DMA_NONCOHERENT
- select HW_HAS_PCI
- select MIPS_GT64120
- select R5000_CPU_SCACHE
- select SYS_SUPPORTS_32BIT_KERNEL
- select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
-
-config PICVUE
- tristate "PICVUE LCD display driver"
- depends on LASAT
-
-config PICVUE_PROC
- tristate "PICVUE LCD display driver /proc interface"
- depends on PICVUE
-
-config DS1603
- bool "DS1603 RTC driver"
- depends on LASAT
-
-config LASAT_SYSCTL
- bool "LASAT sysctl interface"
- depends on LASAT
-
config MIPS_ITE8172
bool "Support for ITE 8172G board"
select DMA_NONCOHERENT
select HW_HAS_PCI
+ select ITE_BOARD_GEN
+ select SYS_HAS_CPU_R5432
+ select SYS_HAS_CPU_NEVADA
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
help
Ths is an evaluation board made by ITE <http://www.ite.com.tw/>
with ATX form factor that utilizes a MIPS R5000 to work with its
@@ -315,42 +229,86 @@ config MIPS_ITE8172
either a NEC Vr5432 or QED RM5231. Say Y here if you wish to build
a kernel for this platform.
-config IT8172_REVC
- bool "Support for older IT8172 (Rev C)"
- depends on MIPS_ITE8172
+config MACH_JAZZ
+ bool "Support for the Jazz family of machines"
+ select ARC
+ select ARC32
+ select ARCH_MAY_HAVE_PC_FDC
+ select GENERIC_ISA_DMA
+ select I8259
+ select ISA
+ select SYS_HAS_CPU_R4X00
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
help
- Say Y here to support the older, Revision C version of the Integrated
- Technology Express, Inc. ITE8172 SBC. Vendor page at
- <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the
- board at <http://www.mvista.com/partners/semiconductor/ite.html>.
+ This a family of machines based on the MIPS R4030 chipset which was
+ used by several vendors to build RISC/os and Windows NT workstations.
+ Members include the Acer PICA, MIPS Magnum 4000, MIPS Millenium and
+ Olivetti M700-10 workstations.
+
+config LASAT
+ bool "Support for LASAT Networks platforms"
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select MIPS_GT64120
+ select MIPS_NILE4
+ select R5000_CPU_SCACHE
+ select SYS_HAS_CPU_R5000
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
config MIPS_ATLAS
bool "Support for MIPS Atlas board"
select BOOT_ELF32
select DMA_NONCOHERENT
+ select IRQ_CPU
select HW_HAS_PCI
+ select MIPS_BOARDS_GEN
+ select MIPS_BONITO64
select MIPS_GT64120
+ select MIPS_MSC
+ select RM7000_CPU_SCACHE
select SWAP_IO_SPACE
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_HAS_CPU_MIPS64_R1
+ select SYS_HAS_CPU_NEVADA
+ select SYS_HAS_CPU_RM7000
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
help
- This enables support for the QED R5231-based MIPS Atlas evaluation
+ This enables support for the MIPS Technologies Atlas evaluation
board.
config MIPS_MALTA
bool "Support for MIPS Malta board"
+ select ARCH_MAY_HAVE_PC_FDC
select BOOT_ELF32
select HAVE_STD_PC_SERIAL_PORT
select DMA_NONCOHERENT
+ select IRQ_CPU
select GENERIC_ISA_DMA
select HW_HAS_PCI
select I8259
+ select MIPS_BOARDS_GEN
+ select MIPS_BONITO64
select MIPS_GT64120
+ select MIPS_MSC
select SWAP_IO_SPACE
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_HAS_CPU_MIPS64_R1
+ select SYS_HAS_CPU_NEVADA
+ select SYS_HAS_CPU_RM7000
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
help
- This enables support for the VR5000-based MIPS Malta evaluation
+ This enables support for the MIPS Technologies Malta evaluation
board.
config MIPS_SEAD
@@ -358,50 +316,64 @@ config MIPS_SEAD
depends on EXPERIMENTAL
select IRQ_CPU
select DMA_NONCOHERENT
+ select MIPS_BOARDS_GEN
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_HAS_CPU_MIPS64_R1
select SYS_SUPPORTS_32BIT_KERNEL
- select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ help
+ This enables support for the MIPS Technologies SEAD evaluation
+ board.
-config MOMENCO_OCELOT
- bool "Support for Momentum Ocelot board"
+config MIPS_SIM
+ bool 'Support for MIPS simulator (MIPSsim)'
select DMA_NONCOHERENT
- select HW_HAS_PCI
select IRQ_CPU
- select IRQ_CPU_RM7K
- select MIPS_GT64120
- select RM7000_CPU_SCACHE
- select SWAP_IO_SPACE
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_HAS_CPU_MIPS32_R2
select SYS_SUPPORTS_32BIT_KERNEL
- select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
help
- The Ocelot is a MIPS-based Single Board Computer (SBC) made by
- Momentum Computer <http://www.momenco.com/>.
+ This option enables support for MIPS Technologies MIPSsim software
+ emulator.
-config MOMENCO_OCELOT_G
- bool "Support for Momentum Ocelot-G board"
+config MOMENCO_JAGUAR_ATX
+ bool "Support for Momentum Jaguar board"
+ select BOOT_ELF32
select DMA_NONCOHERENT
select HW_HAS_PCI
select IRQ_CPU
select IRQ_CPU_RM7K
+ select IRQ_MV64340
+ select LIMITED_DMA
select PCI_MARVELL
select RM7000_CPU_SCACHE
select SWAP_IO_SPACE
+ select SYS_HAS_CPU_RM9000
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
help
- The Ocelot is a MIPS-based Single Board Computer (SBC) made by
+ The Jaguar ATX is a MIPS-based Single Board Computer (SBC) made by
Momentum Computer <http://www.momenco.com/>.
-config MOMENCO_OCELOT_C
- bool "Support for Momentum Ocelot-C board"
+config MOMENCO_OCELOT
+ bool "Support for Momentum Ocelot board"
select DMA_NONCOHERENT
select HW_HAS_PCI
select IRQ_CPU
- select IRQ_MV64340
- select PCI_MARVELL
+ select IRQ_CPU_RM7K
+ select MIPS_GT64120
select RM7000_CPU_SCACHE
select SWAP_IO_SPACE
+ select SYS_HAS_CPU_RM7000
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
help
The Ocelot is a MIPS-based Single Board Computer (SBC) made by
Momentum Computer <http://www.momenco.com/>.
@@ -417,80 +389,95 @@ config MOMENCO_OCELOT_3
select PCI_MARVELL
select RM7000_CPU_SCACHE
select SWAP_IO_SPACE
+ select SYS_HAS_CPU_RM9000
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
help
The Ocelot-3 is based off Discovery III System Controller and
PMC-Sierra Rm79000 core.
-config MOMENCO_JAGUAR_ATX
- bool "Support for Momentum Jaguar board"
- select BOOT_ELF32
+config MOMENCO_OCELOT_C
+ bool "Support for Momentum Ocelot-C board"
select DMA_NONCOHERENT
select HW_HAS_PCI
select IRQ_CPU
- select IRQ_CPU_RM7K
select IRQ_MV64340
- select LIMITED_DMA
select PCI_MARVELL
select RM7000_CPU_SCACHE
select SWAP_IO_SPACE
+ select SYS_HAS_CPU_RM7000
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
help
- The Jaguar ATX is a MIPS-based Single Board Computer (SBC) made by
+ The Ocelot is a MIPS-based Single Board Computer (SBC) made by
Momentum Computer <http://www.momenco.com/>.
-config JAGUAR_DMALOW
- bool "Low DMA Mode"
- depends on MOMENCO_JAGUAR_ATX
- help
- Select to Y if jump JP5 is set on your board, N otherwise. Normally
- the jumper is set, so if you feel unsafe, just say Y.
-
-config PMC_YOSEMITE
- bool "Support for PMC-Sierra Yosemite eval board"
- select DMA_COHERENT
+config MOMENCO_OCELOT_G
+ bool "Support for Momentum Ocelot-G board"
+ select DMA_NONCOHERENT
select HW_HAS_PCI
select IRQ_CPU
select IRQ_CPU_RM7K
- select IRQ_CPU_RM9K
+ select PCI_MARVELL
+ select RM7000_CPU_SCACHE
select SWAP_IO_SPACE
+ select SYS_HAS_CPU_RM7000
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
help
- Yosemite is an evaluation board for the RM9000x2 processor
- manufactured by PMC-Sierra
+ The Ocelot is a MIPS-based Single Board Computer (SBC) made by
+ Momentum Computer <http://www.momenco.com/>.
-config HYPERTRANSPORT
- bool "Hypertransport Support for PMC-Sierra Yosemite"
- depends on PMC_YOSEMITE
+config MIPS_XXS1500
+ bool "Support for MyCable XXS1500 board"
+ select DMA_NONCOHERENT
+ select SOC_AU1500
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config PNX8550_V2PCI
+ bool "Support for Philips PNX8550 based Viper2-PCI board"
+ select PNX8550
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config PNX8550_JBS
+ bool "Support for Philips PNX8550 based JBS board"
+ select PNX8550
+ select SYS_SUPPORTS_LITTLE_ENDIAN
config DDB5074
bool "Support for NEC DDB Vrc-5074 (EXPERIMENTAL)"
depends on EXPERIMENTAL
+ select DDB5XXX_COMMON
select DMA_NONCOHERENT
select HAVE_STD_PC_SERIAL_PORT
select HW_HAS_PCI
select IRQ_CPU
select I8259
select ISA
+ select SYS_HAS_CPU_R5000
select SYS_SUPPORTS_32BIT_KERNEL
- select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
help
This enables support for the VR5000-based NEC DDB Vrc-5074
evaluation board.
config DDB5476
bool "Support for NEC DDB Vrc-5476"
+ select DDB5XXX_COMMON
select DMA_NONCOHERENT
select HAVE_STD_PC_SERIAL_PORT
select HW_HAS_PCI
select IRQ_CPU
select I8259
select ISA
+ select SYS_HAS_CPU_R5432
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
help
This enables support for the R5432-based NEC DDB Vrc-5476
evaluation board.
@@ -501,12 +488,15 @@ config DDB5476
config DDB5477
bool "Support for NEC DDB Vrc-5477"
+ select DDB5XXX_COMMON
select DMA_NONCOHERENT
select HW_HAS_PCI
select I8259
select IRQ_CPU
+ select SYS_HAS_CPU_R5432
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
help
This enables support for the R5432-based NEC DDB Vrc-5477,
or Rockhopper/SolutionGear boards with R5432/R5500 CPUs.
@@ -514,10 +504,28 @@ config DDB5477
Features : kernel debugging, serial terminal, NFS root fs, on-board
ether port USB, AC97, PCI, etc.
-config DDB5477_BUS_FREQUENCY
- int "bus frequency (in kHZ, 0 for auto-detect)"
- depends on DDB5477
- default 0
+config MACH_VR41XX
+ bool "Support for NEC VR4100 series based machines"
+ select SYS_HAS_CPU_VR41XX
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+
+config PMC_YOSEMITE
+ bool "Support for PMC-Sierra Yosemite eval board"
+ select DMA_COHERENT
+ select HW_HAS_PCI
+ select IRQ_CPU
+ select IRQ_CPU_RM7K
+ select IRQ_CPU_RM9K
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_RM9000
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ help
+ Yosemite is an evaluation board for the RM9000x2 processor
+ manufactured by PMC-Sierra.
config QEMU
bool "Support for Qemu"
@@ -527,15 +535,16 @@ config QEMU
select I8259
select ISA
select SWAP_IO_SPACE
+ select SYS_HAS_CPU_MIPS32_R1
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
help
- Qemu is a software emulator which among other architectures also
- can simulate a MIPS32 4Kc system. This patch adds support for the
- system architecture that currently is being simulated by Qemu. It
- will eventually be removed again when Qemu has the capability to
- simulate actual MIPS hardware platforms. More information on Qemu
- can be found at http://www.linux-mips.org/wiki/Qemu.
+ Qemu is a software emulator which among other architectures also
+ can simulate a MIPS32 4Kc system. This patch adds support for the
+ system architecture that currently is being simulated by Qemu. It
+ will eventually be removed again when Qemu has the capability to
+ simulate actual MIPS hardware platforms. More information on Qemu
+ can be found at http://www.linux-mips.org/wiki/Qemu.
config SGI_IP22
bool "Support for SGI IP22 (Indy/Indigo2)"
@@ -543,11 +552,15 @@ config SGI_IP22
select ARC32
select BOOT_ELF32
select DMA_NONCOHERENT
+ select HW_HAS_EISA
select IP22_CPU_SCACHE
select IRQ_CPU
select SWAP_IO_SPACE
+ select SYS_HAS_CPU_R4X00
+ select SYS_HAS_CPU_R5000
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
help
This are the SGI Indy, Challenge S and Indigo2, as well as certain
OEM variants like the Tandem CMN B006S. To compile a Linux kernel
@@ -557,70 +570,18 @@ config SGI_IP27
bool "Support for SGI IP27 (Origin200/2000)"
select ARC
select ARC64
+ select BOOT_ELF64
select DMA_IP27
select HW_HAS_PCI
select PCI_DOMAINS
+ select SYS_HAS_CPU_R10000
select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
help
This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics
workstations. To compile a Linux kernel that runs on these, say Y
here.
-#config SGI_SN0_XXL
-# bool "IP27 XXL"
-# depends on SGI_IP27
-# This options adds support for userspace processes upto 16TB size.
-# Normally the limit is just .5TB.
-
-config SGI_SN0_N_MODE
- bool "IP27 N-Mode"
- depends on SGI_IP27
- help
- The nodes of Origin 200, Origin 2000 and Onyx 2 systems can be
- configured in either N-Modes which allows for more nodes or M-Mode
- which allows for more memory. Your system is most probably
- running in M-Mode, so you should say N here.
-
-config ARCH_DISCONTIGMEM_ENABLE
- bool
- default y if SGI_IP27
- help
- Say Y to upport efficient handling of discontiguous physical memory,
- for architectures which are either NUMA (Non-Uniform Memory Access)
- or have huge holes in the physical address space for other reasons.
- See <file:Documentation/vm/numa> for more.
-
-config NUMA
- bool "NUMA Support"
- depends on SGI_IP27
- help
- Say Y to compile the kernel to support NUMA (Non-Uniform Memory
- Access). This option is for configuring high-end multiprocessor
- server machines. If in doubt, say N.
-
-config MAPPED_KERNEL
- bool "Mapped kernel support"
- depends on SGI_IP27
- help
- Change the way a Linux kernel is loaded into memory on a MIPS64
- machine. This is required in order to support text replication and
- NUMA. If you need to understand it, read the source code.
-
-config REPLICATE_KTEXT
- bool "Kernel text replication support"
- depends on SGI_IP27
- help
- Say Y here to enable replicating the kernel text across multiple
- nodes in a NUMA cluster. This trades memory for speed.
-
-config REPLICATE_EXHANDLERS
- bool "Exception handler replication support"
- depends on SGI_IP27
- help
- Say Y here to enable replicating the kernel exception handlers
- across multiple nodes in a NUMA cluster. This trades memory for
- speed.
-
config SGI_IP32
bool "Support for SGI IP32 (O2) (EXPERIMENTAL)"
depends on EXPERIMENTAL
@@ -633,353 +594,152 @@ config SGI_IP32
select HW_HAS_PCI
select R5000_CPU_SCACHE
select RM7000_CPU_SCACHE
+ select SYS_HAS_CPU_R5000
+ select SYS_HAS_CPU_R10000 if BROKEN
+ select SYS_HAS_CPU_RM7000
select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
help
If you want this kernel to run on SGI O2 workstation, say Y here.
-config SOC_AU1X00
- bool "Support for AMD/Alchemy Au1X00 SOCs"
- select SYS_SUPPORTS_32BIT_KERNEL
-
-choice
- prompt "Au1X00 SOC Type"
- depends on SOC_AU1X00
- help
- Say Y here to enable support for one of three AMD/Alchemy
- SOCs. For additional documentation see www.amd.com.
-
-config SOC_AU1000
- bool "SOC_AU1000"
-config SOC_AU1100
- bool "SOC_AU1100"
-config SOC_AU1500
- bool "SOC_AU1500"
-config SOC_AU1550
- bool "SOC_AU1550"
-
-endchoice
-
-choice
- prompt "AMD/Alchemy Au1x00 board support"
- depends on SOC_AU1X00
- help
- These are evaluation boards built by AMD/Alchemy to
- showcase their Au1X00 Internet Edge Processors. The SOC design
- is based on the MIPS32 architecture running at 266/400/500MHz
- with many integrated peripherals. Further information can be
- found at their website, <http://www.amd.com/>. Say Y here if you
- wish to build a kernel for this platform.
-
-config MIPS_PB1000
- bool "PB1000 board"
- depends on SOC_AU1000
- select DMA_NONCOHERENT
- select HW_HAS_PCI
- select SWAP_IO_SPACE
-
-config MIPS_PB1100
- bool "PB1100 board"
- depends on SOC_AU1100
- select DMA_NONCOHERENT
- select HW_HAS_PCI
- select SWAP_IO_SPACE
-
-config MIPS_PB1500
- bool "PB1500 board"
- depends on SOC_AU1500
- select DMA_COHERENT
- select HW_HAS_PCI
-
-config MIPS_PB1550
- bool "PB1550 board"
- depends on SOC_AU1550
- select DMA_COHERENT
- select HW_HAS_PCI
- select MIPS_DISABLE_OBSOLETE_IDE
-
-config MIPS_DB1000
- bool "DB1000 board"
- depends on SOC_AU1000
- select DMA_NONCOHERENT
- select HW_HAS_PCI
-
-config MIPS_DB1100
- bool "DB1100 board"
- depends on SOC_AU1100
- select DMA_NONCOHERENT
-
-config MIPS_DB1500
- bool "DB1500 board"
- depends on SOC_AU1500
- select DMA_COHERENT
- select HW_HAS_PCI
- select MIPS_DISABLE_OBSOLETE_IDE
-
-config MIPS_DB1550
- bool "DB1550 board"
- depends on SOC_AU1550
- select HW_HAS_PCI
- select DMA_COHERENT
- select MIPS_DISABLE_OBSOLETE_IDE
-
-config MIPS_BOSPORUS
- bool "Bosporus board"
- depends on SOC_AU1500
- select DMA_NONCOHERENT
-
-config MIPS_MIRAGE
- bool "Mirage board"
- depends on SOC_AU1500
- select DMA_NONCOHERENT
-
-config MIPS_XXS1500
- bool "MyCable XXS1500 board"
- depends on SOC_AU1500
- select DMA_NONCOHERENT
-
-config MIPS_MTX1
- bool "4G Systems MTX-1 board"
- depends on SOC_AU1500
- select HW_HAS_PCI
- select DMA_NONCOHERENT
-
-endchoice
-
-config SIBYTE_SB1xxx_SOC
- bool "Support for Broadcom BCM1xxx SOCs (EXPERIMENTAL)"
- depends on EXPERIMENTAL
+config SIBYTE_BIGSUR
+ bool "Support for Sibyte BigSur"
select BOOT_ELF32
select DMA_COHERENT
+ select PCI_DOMAINS
+ select SIBYTE_BCM1x80
select SWAP_IO_SPACE
- select SYS_SUPPORTS_32BIT_KERNEL
- select SYS_SUPPORTS_64BIT_KERNEL
-
-choice
- prompt "BCM1xxx SOC-based board"
- depends on SIBYTE_SB1xxx_SOC
- default SIBYTE_SWARM
- help
- Enable support for boards based on the SiByte line of SOCs
- from Broadcom. There are configurations for the known
- evaluation boards, or you can choose "Other" and add your
- own board support code.
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
config SIBYTE_SWARM
- bool "BCM91250A-SWARM"
+ bool "Support for Sibyte BCM91250A-SWARM"
+ select BOOT_ELF32
+ select DMA_COHERENT
select SIBYTE_SB1250
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ select SYS_SUPPORTS_LITTLE_ENDIAN
config SIBYTE_SENTOSA
- bool "BCM91250E-Sentosa"
+ bool "Support for Sibyte BCM91250E-Sentosa"
+ depends on EXPERIMENTAL
+ select BOOT_ELF32
+ select DMA_COHERENT
select SIBYTE_SB1250
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
config SIBYTE_RHONE
- bool "BCM91125E-Rhone"
+ bool "Support for Sibyte BCM91125E-Rhone"
+ depends on EXPERIMENTAL
+ select BOOT_ELF32
+ select DMA_COHERENT
select SIBYTE_BCM1125H
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
config SIBYTE_CARMEL
- bool "BCM91120x-Carmel"
+ bool "Support for Sibyte BCM91120x-Carmel"
+ depends on EXPERIMENTAL
+ select BOOT_ELF32
+ select DMA_COHERENT
select SIBYTE_BCM1120
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
config SIBYTE_PTSWARM
- bool "BCM91250PT-PTSWARM"
+ bool "Support for Sibyte BCM91250PT-PTSWARM"
+ depends on EXPERIMENTAL
+ select BOOT_ELF32
+ select DMA_COHERENT
select SIBYTE_SB1250
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ select SYS_SUPPORTS_LITTLE_ENDIAN
config SIBYTE_LITTLESUR
- bool "BCM91250C2-LittleSur"
+ bool "Support for Sibyte BCM91250C2-LittleSur"
+ depends on EXPERIMENTAL
+ select BOOT_ELF32
+ select DMA_COHERENT
select SIBYTE_SB1250
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ select SYS_SUPPORTS_LITTLE_ENDIAN
config SIBYTE_CRHINE
- bool "BCM91120C-CRhine"
+ bool "Support for Sibyte BCM91120C-CRhine"
+ depends on EXPERIMENTAL
+ select BOOT_ELF32
+ select DMA_COHERENT
select SIBYTE_BCM1120
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
config SIBYTE_CRHONE
- bool "BCM91125C-CRhone"
- select SIBYTE_BCM1125
-
-config SIBYTE_UNKNOWN
- bool "Other"
-
-endchoice
-
-config SIBYTE_BOARD
- bool
- depends on SIBYTE_SB1xxx_SOC && !SIBYTE_UNKNOWN
- default y
-
-choice
- prompt "BCM1xxx SOC Type"
- depends on SIBYTE_UNKNOWN
- default SIBYTE_UNK_BCM1250
- help
- Since you haven't chosen a known evaluation board from
- Broadcom, you must explicitly pick the SOC this kernel is
- targetted for.
-
-config SIBYTE_UNK_BCM1250
- bool "BCM1250"
- select SIBYTE_SB1250
-
-config SIBYTE_UNK_BCM1120
- bool "BCM1120"
- select SIBYTE_BCM1120
-
-config SIBYTE_UNK_BCM1125
- bool "BCM1125"
+ bool "Support for Sibyte BCM91125C-CRhone"
+ depends on EXPERIMENTAL
+ select BOOT_ELF32
+ select DMA_COHERENT
select SIBYTE_BCM1125
-
-config SIBYTE_UNK_BCM1125H
- bool "BCM1125H"
- select SIBYTE_BCM1125H
-
-endchoice
-
-config SIBYTE_SB1250
- bool
- select HW_HAS_PCI
-
-config SIBYTE_BCM1120
- bool
- select SIBYTE_BCM112X
-
-config SIBYTE_BCM1125
- bool
- select HW_HAS_PCI
- select SIBYTE_BCM112X
-
-config SIBYTE_BCM1125H
- bool
- select HW_HAS_PCI
- select SIBYTE_BCM112X
-
-config SIBYTE_BCM112X
- bool
-
-choice
- prompt "SiByte SOC Stepping"
- depends on SIBYTE_SB1xxx_SOC
-
-config CPU_SB1_PASS_1
- bool "1250 Pass1"
- depends on SIBYTE_SB1250
- select CPU_HAS_PREFETCH
-
-config CPU_SB1_PASS_2_1250
- bool "1250 An"
- depends on SIBYTE_SB1250
- select CPU_SB1_PASS_2
- help
- Also called BCM1250 Pass 2
-
-config CPU_SB1_PASS_2_2
- bool "1250 Bn"
- depends on SIBYTE_SB1250
- select CPU_HAS_PREFETCH
- help
- Also called BCM1250 Pass 2.2
-
-config CPU_SB1_PASS_4
- bool "1250 Cn"
- depends on SIBYTE_SB1250
- select CPU_HAS_PREFETCH
- help
- Also called BCM1250 Pass 3
-
-config CPU_SB1_PASS_2_112x
- bool "112x Hybrid"
- depends on SIBYTE_BCM112X
- select CPU_SB1_PASS_2
-
-config CPU_SB1_PASS_3
- bool "112x An"
- depends on SIBYTE_BCM112X
- select CPU_HAS_PREFETCH
-
-endchoice
-
-config CPU_SB1_PASS_2
- bool
-
-config SIBYTE_HAS_LDT
- bool
- depends on PCI && (SIBYTE_SB1250 || SIBYTE_BCM1125H)
- default y
-
-config SIMULATION
- bool "Running under simulation"
- depends on SIBYTE_SB1xxx_SOC
- help
- Build a kernel suitable for running under the GDB simulator.
- Primarily adjusts the kernel's notion of time.
-
-config SIBYTE_CFE
- bool "Booting from CFE"
- depends on SIBYTE_SB1xxx_SOC
- help
- Make use of the CFE API for enumerating available memory,
- controlling secondary CPUs, and possibly console output.
-
-config SIBYTE_CFE_CONSOLE
- bool "Use firmware console"
- depends on SIBYTE_CFE
- help
- Use the CFE API's console write routines during boot. Other console
- options (VT console, sb1250 duart console, etc.) should not be
- configured.
-
-config SIBYTE_STANDALONE
- bool
- depends on SIBYTE_SB1xxx_SOC && !SIBYTE_CFE
- default y
-
-config SIBYTE_STANDALONE_RAM_SIZE
- int "Memory size (in megabytes)"
- depends on SIBYTE_STANDALONE
- default "32"
-
-config SIBYTE_BUS_WATCHER
- bool "Support for Bus Watcher statistics"
- depends on SIBYTE_SB1xxx_SOC
- help
- Handle and keep statistics on the bus error interrupts (COR_ECC,
- BAD_ECC, IO_BUS).
-
-config SIBYTE_BW_TRACE
- bool "Capture bus trace before bus error"
- depends on SIBYTE_BUS_WATCHER
- help
- Run a continuous bus trace, dumping the raw data as soon as
- a ZBbus error is detected. Cannot work if ZBbus profiling
- is turned on, and also will interfere with JTAG-based trace
- buffer activity. Raw buffer data is dumped to console, and
- must be processed off-line.
-
-config SIBYTE_SB1250_PROF
- bool "Support for SB1/SOC profiling - SB1/SCD perf counters"
- depends on SIBYTE_SB1xxx_SOC
-
-config SIBYTE_TBPROF
- bool "Support for ZBbus profiling"
- depends on SIBYTE_SB1xxx_SOC
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ select SYS_SUPPORTS_LITTLE_ENDIAN
config SNI_RM200_PCI
bool "Support for SNI RM200 PCI"
select ARC
select ARC32
+ select ARCH_MAY_HAVE_PC_FDC
select BOOT_ELF32
select DMA_NONCOHERENT
select GENERIC_ISA_DMA
select HAVE_STD_PC_SERIAL_PORT
+ select HW_HAS_EISA
select HW_HAS_PCI
select I8259
select ISA
+ select SYS_HAS_CPU_R4X00
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+ select SYS_SUPPORTS_BIG_ENDIAN if EXPERIMENTAL
+ select SYS_SUPPORTS_HIGHMEM
+ select SYS_SUPPORTS_LITTLE_ENDIAN
help
The SNI RM200 PCI was a MIPS-based platform manufactured by Siemens
Nixdorf Informationssysteme (SNI), parent company of Pyramid
Technology and now in turn merged with Fujitsu. Say Y here to
support this machine type.
+config TOSHIBA_JMR3927
+ bool "Support for Toshiba JMR-TX3927 board"
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select MIPS_TX3927
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_TX39XX
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select TOSHIBA_BOARDS
+
config TOSHIBA_RBTX4927
bool "Support for Toshiba TBTX49[23]7 board"
select DMA_NONCOHERENT
@@ -988,15 +748,51 @@ config TOSHIBA_RBTX4927
select I8259
select ISA
select SWAP_IO_SPACE
+ select SYS_HAS_CPU_TX49XX
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select TOSHIBA_BOARDS
help
This Toshiba board is based on the TX4927 processor. Say Y here to
support this machine type
-config TOSHIBA_FPCIB0
- bool "FPCIB0 Backplane Support"
- depends on TOSHIBA_RBTX4927
+config TOSHIBA_RBTX4938
+ bool "Support for Toshiba RBTX4938 board"
+ select HAVE_STD_PC_SERIAL_PORT
+ select DMA_NONCOHERENT
+ select GENERIC_ISA_DMA
+ select HAS_TXX9_SERIAL
+ select HW_HAS_PCI
+ select I8259
+ select ISA
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_TX49XX
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select TOSHIBA_BOARDS
+ help
+ This Toshiba board is based on the TX4938 processor. Say Y here to
+ support this machine type
+
+endchoice
+
+source "arch/mips/ddb5xxx/Kconfig"
+source "arch/mips/gt64120/ev64120/Kconfig"
+source "arch/mips/jazz/Kconfig"
+source "arch/mips/ite-boards/Kconfig"
+source "arch/mips/lasat/Kconfig"
+source "arch/mips/momentum/Kconfig"
+source "arch/mips/pmc-sierra/Kconfig"
+source "arch/mips/sgi-ip27/Kconfig"
+source "arch/mips/sibyte/Kconfig"
+source "arch/mips/tx4927/Kconfig"
+source "arch/mips/tx4938/Kconfig"
+source "arch/mips/vr41xx/Kconfig"
+source "arch/mips/philips/pnx8550/common/Kconfig"
+
+endmenu
config RWSEM_GENERIC_SPINLOCK
bool
@@ -1014,8 +810,9 @@ config GENERIC_CALIBRATE_DELAY
#
config ARC
bool
- depends on SNI_RM200_PCI || SGI_IP32 || SGI_IP27 || SGI_IP22 || MIPS_MAGNUM_4000 || OLIVETTI_M700 || ACER_PICA_61
- default y
+
+config ARCH_MAY_HAVE_PC_FDC
+ bool
config DMA_COHERENT
bool
@@ -1034,51 +831,65 @@ config DMA_NONCOHERENT
config DMA_NEED_PCI_MAP_STATE
bool
+config OWN_DMA
+ bool
+
config EARLY_PRINTK
bool
- depends on MACH_DECSTATION
- default y
config GENERIC_ISA_DMA
bool
- depends on SNI_RM200_PCI || MIPS_MAGNUM_4000 || OLIVETTI_M700 || ACER_PICA_61 || MIPS_MALTA
- default y
config I8259
bool
- depends on SNI_RM200_PCI || DDB5477 || DDB5476 || DDB5074 || MACH_JAZZ || MIPS_MALTA || MIPS_COBALT
- default y
config LIMITED_DMA
bool
select HIGHMEM
+ select SYS_SUPPORTS_HIGHMEM
config MIPS_BONITO64
bool
- depends on MIPS_ATLAS || MIPS_MALTA
- default y
config MIPS_MSC
bool
- depends on MIPS_ATLAS || MIPS_MALTA
- default y
config MIPS_NILE4
bool
- depends on LASAT
- default y
config MIPS_DISABLE_OBSOLETE_IDE
bool
-config CPU_LITTLE_ENDIAN
- bool "Generate little endian code"
- default y if ACER_PICA_61 || CASIO_E55 || DDB5074 || DDB5476 || DDB5477 || MACH_DECSTATION || IBM_WORKPAD || LASAT || MIPS_COBALT || MIPS_ITE8172 || MIPS_IVR || SOC_AU1X00 || OLIVETTI_M700 || SNI_RM200_PCI || VICTOR_MPC30X || ZAO_CAPCELLA
- default n if MIPS_EV64120 || MIPS_EV96100 || MOMENCO_OCELOT || MOMENCO_OCELOT_G || SGI_IP22 || SGI_IP27 || SGI_IP32 || TOSHIBA_JMR3927
+#
+# Endianess selection. Suffiently obscure so many users don't know what to
+# answer,so we try hard to limit the available choices. Also the use of a
+# choice statement should be more obvious to the user.
+#
+choice
+ prompt "Endianess selection"
help
Some MIPS machines can be configured for either little or big endian
- byte order. These modes require different kernels. Say Y if your
- machine is little endian, N if it's a big endian machine.
+ byte order. These modes require different kernels and a different
+ Linux distribution. In general there is one prefered byteorder for a
+ particular system but some systems are just as commonly used in the
+ one or the other endianess.
+
+config CPU_BIG_ENDIAN
+ bool "Big endian"
+ depends on SYS_SUPPORTS_BIG_ENDIAN
+
+config CPU_LITTLE_ENDIAN
+ bool "Little endian"
+ depends on SYS_SUPPORTS_LITTLE_ENDIAN
+ help
+
+endchoice
+
+config SYS_SUPPORTS_BIG_ENDIAN
+ bool
+
+config SYS_SUPPORTS_LITTLE_ENDIAN
+ bool
config IRQ_CPU
bool
@@ -1086,42 +897,69 @@ config IRQ_CPU
config IRQ_CPU_RM7K
bool
+config IRQ_CPU_RM9K
+ bool
+
config IRQ_MV64340
bool
config DDB5XXX_COMMON
bool
- depends on DDB5074 || DDB5476 || DDB5477
- default y
config MIPS_BOARDS_GEN
bool
- depends on MIPS_ATLAS || MIPS_MALTA || MIPS_SEAD
- default y
config MIPS_GT64111
bool
- depends on MIPS_COBALT
- default y
config MIPS_GT64120
bool
- depends on MIPS_EV64120 || MIPS_EV96100 || LASAT || MIPS_ATLAS || MIPS_MALTA || MOMENCO_OCELOT
- default y
config MIPS_TX3927
bool
- depends on TOSHIBA_JMR3927
select HAS_TXX9_SERIAL
- default y
config PCI_MARVELL
bool
config ITE_BOARD_GEN
bool
- depends on MIPS_IVR || MIPS_ITE8172
- default y
+
+config SOC_AU1000
+ bool
+ select SOC_AU1X00
+
+config SOC_AU1100
+ bool
+ select SOC_AU1X00
+
+config SOC_AU1500
+ bool
+ select SOC_AU1X00
+
+config SOC_AU1550
+ bool
+ select SOC_AU1X00
+
+config SOC_AU1200
+ bool
+ select SOC_AU1X00
+
+config SOC_AU1X00
+ bool
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_32BIT_KERNEL
+
+config PNX8550
+ bool
+ select SOC_PNX8550
+
+config SOC_PNX8550
+ bool
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select SYS_HAS_CPU_R4X00
+ select SYS_SUPPORTS_32BIT_KERNEL
config SWAP_IO_SPACE
bool
@@ -1148,6 +986,9 @@ config SYSCLK_100
endchoice
+config ARC32
+ bool
+
config AU1X00_USB_DEVICE
bool
depends on MIPS_PB1500 || MIPS_PB1100 || MIPS_PB1000
@@ -1155,11 +996,7 @@ config AU1X00_USB_DEVICE
config MIPS_GT96100
bool
- depends on MIPS_EV96100
- default y
- help
- Say Y here to support the Galileo Technology GT96100 communications
- controller card. There is a web page at <http://www.galileot.com/>.
+ select MIPS_GT64120
config IT8172_CIR
bool
@@ -1173,8 +1010,6 @@ config IT8712
config BOOT_ELF32
bool
- depends on MACH_DECSTATION || MIPS_ATLAS || MIPS_MALTA || MOMENCO_JAGUAR_ATX || MOMENCO_OCELOT_3 || SIBYTE_SB1xxx_SOC || SGI_IP32 || SGI_IP22 || SNI_RM200_PCI
- default y
config MIPS_L1_CACHE_SHIFT
int
@@ -1182,11 +1017,6 @@ config MIPS_L1_CACHE_SHIFT
default "7" if SGI_IP27
default "5"
-config ARC32
- bool
- depends on MACH_JAZZ || SNI_RM200_PCI || SGI_IP22 || SGI_IP32
- default y
-
config HAVE_STD_PC_SERIAL_PORT
bool
@@ -1206,30 +1036,12 @@ config ARC_PROMLIB
config ARC64
bool
- depends on SGI_IP27
- default y
config BOOT_ELF64
bool
- depends on SGI_IP27
- default y
-
-#config MAPPED_PCI_IO y
-# bool
-# depends on SGI_IP27
-# default y
-
-config QL_ISP_A64
- bool
- depends on SGI_IP27
- default y
config TOSHIBA_BOARDS
bool
- depends on TOSHIBA_JMR3927 || TOSHIBA_RBTX4927
- default y
-
-endmenu
menu "CPU selection"
@@ -1237,18 +1049,69 @@ choice
prompt "CPU type"
default CPU_R4X00
-config CPU_MIPS32
- bool "MIPS32"
+config CPU_MIPS32_R1
+ bool "MIPS32 Release 1"
+ depends on SYS_HAS_CPU_MIPS32_R1
+ select CPU_HAS_PREFETCH
select CPU_SUPPORTS_32BIT_KERNEL
+ help
+ Choose this option to build a kernel for release 1 or later of the
+ MIPS32 architecture. Most modern embedded systems with a 32-bit
+ MIPS processor are based on a MIPS32 processor. If you know the
+ specific type of processor in your system, choose those that one
+ otherwise CPU_MIPS32_R1 is a safe bet for any MIPS32 system.
+ Release 2 of the MIPS32 architecture is available since several
+ years so chances are you even have a MIPS32 Release 2 processor
+ in which case you should choose CPU_MIPS32_R2 instead for better
+ performance.
+
+config CPU_MIPS32_R2
+ bool "MIPS32 Release 2"
+ depends on SYS_HAS_CPU_MIPS32_R2
+ select CPU_HAS_PREFETCH
+ select CPU_SUPPORTS_32BIT_KERNEL
+ help
+ Choose this option to build a kernel for release 2 or later of the
+ MIPS32 architecture. Most modern embedded systems with a 32-bit
+ MIPS processor are based on a MIPS32 processor. If you know the
+ specific type of processor in your system, choose those that one
+ otherwise CPU_MIPS32_R1 is a safe bet for any MIPS32 system.
-config CPU_MIPS64
- bool "MIPS64"
+config CPU_MIPS64_R1
+ bool "MIPS64 Release 1"
+ depends on SYS_HAS_CPU_MIPS64_R1
+ select CPU_HAS_PREFETCH
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
+ help
+ Choose this option to build a kernel for release 1 or later of the
+ MIPS64 architecture. Many modern embedded systems with a 64-bit
+ MIPS processor are based on a MIPS64 processor. If you know the
+ specific type of processor in your system, choose those that one
+ otherwise CPU_MIPS64_R1 is a safe bet for any MIPS64 system.
+ Release 2 of the MIPS64 architecture is available since several
+ years so chances are you even have a MIPS64 Release 2 processor
+ in which case you should choose CPU_MIPS64_R2 instead for better
+ performance.
+
+config CPU_MIPS64_R2
+ bool "MIPS64 Release 2"
+ depends on SYS_HAS_CPU_MIPS64_R2
+ select CPU_HAS_PREFETCH
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ help
+ Choose this option to build a kernel for release 2 or later of the
+ MIPS64 architecture. Many modern embedded systems with a 64-bit
+ MIPS processor are based on a MIPS64 processor. If you know the
+ specific type of processor in your system, choose those that one
+ otherwise CPU_MIPS64_R1 is a safe bet for any MIPS64 system.
config CPU_R3000
bool "R3000"
+ depends on SYS_HAS_CPU_R3000
select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
help
Please make sure to pick the right CPU type. Linux/MIPS is not
designed to be generic, i.e. Kernels compiled for R3000 CPUs will
@@ -1259,20 +1122,23 @@ config CPU_R3000
config CPU_TX39XX
bool "R39XX"
+ depends on SYS_HAS_CPU_TX39XX
select CPU_SUPPORTS_32BIT_KERNEL
config CPU_VR41XX
bool "R41xx"
+ depends on SYS_HAS_CPU_VR41XX
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
help
- The options selects support for the NEC VR41xx series of processors.
+ The options selects support for the NEC VR4100 series of processors.
Only choose this option if you have one of these processors as a
kernel built with this option will not run on any other type of
processor or vice versa.
config CPU_R4300
bool "R4300"
+ depends on SYS_HAS_CPU_R4300
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
help
@@ -1280,6 +1146,7 @@ config CPU_R4300
config CPU_R4X00
bool "R4x00"
+ depends on SYS_HAS_CPU_R4X00
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
help
@@ -1288,11 +1155,13 @@ config CPU_R4X00
config CPU_TX49XX
bool "R49XX"
+ depends on SYS_HAS_CPU_TX49XX
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
config CPU_R5000
bool "R5000"
+ depends on SYS_HAS_CPU_R5000
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
help
@@ -1300,10 +1169,14 @@ config CPU_R5000
config CPU_R5432
bool "R5432"
+ depends on SYS_HAS_CPU_R5432
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
config CPU_R6000
bool "R6000"
depends on EXPERIMENTAL
+ depends on SYS_HAS_CPU_R6000
select CPU_SUPPORTS_32BIT_KERNEL
help
MIPS Technologies R6000 and R6000A series processors. Note these
@@ -1311,6 +1184,7 @@ config CPU_R6000
config CPU_NEVADA
bool "RM52xx"
+ depends on SYS_HAS_CPU_NEVADA
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
help
@@ -1319,6 +1193,8 @@ config CPU_NEVADA
config CPU_R8000
bool "R8000"
depends on EXPERIMENTAL
+ depends on SYS_HAS_CPU_R8000
+ select CPU_HAS_PREFETCH
select CPU_SUPPORTS_64BIT_KERNEL
help
MIPS Technologies R8000 processors. Note these processors are
@@ -1326,25 +1202,151 @@ config CPU_R8000
config CPU_R10000
bool "R10000"
+ depends on SYS_HAS_CPU_R10000
+ select CPU_HAS_PREFETCH
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
help
MIPS Technologies R10000-series processors.
config CPU_RM7000
bool "RM7000"
+ depends on SYS_HAS_CPU_RM7000
+ select CPU_HAS_PREFETCH
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
config CPU_RM9000
bool "RM9000"
+ depends on SYS_HAS_CPU_RM9000
+ select CPU_HAS_PREFETCH
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
config CPU_SB1
bool "SB1"
+ depends on SYS_HAS_CPU_SB1
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
+
+endchoice
+
+config SYS_HAS_CPU_MIPS32_R1
+ bool
+
+config SYS_HAS_CPU_MIPS32_R2
+ bool
+
+config SYS_HAS_CPU_MIPS64_R1
+ bool
+
+config SYS_HAS_CPU_MIPS64_R2
+ bool
+
+config SYS_HAS_CPU_R3000
+ bool
+
+config SYS_HAS_CPU_TX39XX
+ bool
+
+config SYS_HAS_CPU_VR41XX
+ bool
+
+config SYS_HAS_CPU_R4300
+ bool
+
+config SYS_HAS_CPU_R4X00
+ bool
+
+config SYS_HAS_CPU_TX49XX
+ bool
+
+config SYS_HAS_CPU_R5000
+ bool
+
+config SYS_HAS_CPU_R5432
+ bool
+
+config SYS_HAS_CPU_R6000
+ bool
+
+config SYS_HAS_CPU_NEVADA
+ bool
+
+config SYS_HAS_CPU_R8000
+ bool
+
+config SYS_HAS_CPU_R10000
+ bool
+
+config SYS_HAS_CPU_RM7000
+ bool
+
+config SYS_HAS_CPU_RM9000
+ bool
+
+config SYS_HAS_CPU_SB1
+ bool
+
+endmenu
+
+#
+# These two indicate any levelof the MIPS32 and MIPS64 architecture
+#
+config CPU_MIPS32
+ bool
+ default y if CPU_MIPS32_R1 || CPU_MIPS32_R2
+
+config CPU_MIPS64
+ bool
+ default y if CPU_MIPS64_R1 || CPU_MIPS64_R2
+
+#
+# These two indicate the revision of the architecture, either 32 bot 64 bit.
+#
+config CPU_MIPSR1
+ bool
+ default y if CPU_MIPS32_R1 || CPU_MIPS64_R1
+
+config CPU_MIPSR2
+ bool
+ default y if CPU_MIPS32_R2 || CPU_MIPS64_R2
+
+config SYS_SUPPORTS_32BIT_KERNEL
+ bool
+config SYS_SUPPORTS_64BIT_KERNEL
+ bool
+config CPU_SUPPORTS_32BIT_KERNEL
+ bool
+config CPU_SUPPORTS_64BIT_KERNEL
+ bool
+
+menu "Kernel type"
+
+choice
+
+ prompt "Kernel code model"
+ help
+ You should only select this option if you have a workload that
+ actually benefits from 64-bit processing or if your machine has
+ large memory. You will only be presented a single option in this
+ menu if your system does not support both 32-bit and 64-bit kernels.
+
+config 32BIT
+ bool "32-bit kernel"
+ depends on CPU_SUPPORTS_32BIT_KERNEL && SYS_SUPPORTS_32BIT_KERNEL
+ select TRAD_SIGNALS
+ help
+ Select this option if you want to build a 32-bit kernel.
+config 64BIT
+ bool "64-bit kernel"
+ depends on CPU_SUPPORTS_64BIT_KERNEL && SYS_SUPPORTS_64BIT_KERNEL
+ help
+ Select this option if you want to build a 64-bit kernel.
endchoice
@@ -1416,12 +1418,43 @@ config SIBYTE_DMA_PAGEOPS
SiByte Linux port. Seems to give a small performance benefit.
config CPU_HAS_PREFETCH
- bool "Enable prefetches" if CPU_SB1 && !CPU_SB1_PASS_2
- default y if CPU_MIPS32 || CPU_MIPS64 || CPU_RM7000 || CPU_RM9000 || CPU_R10000
+ bool
+
+config MIPS_MT
+ bool "Enable MIPS MT"
+
+choice
+ prompt "MIPS MT options"
+ depends on MIPS_MT
-config VTAG_ICACHE
- bool "Support for Virtual Tagged I-cache" if CPU_MIPS64 || CPU_MIPS32
- default y if CPU_SB1
+config MIPS_MT_SMP
+ bool "Use 1 TC on each available VPE for SMP"
+ select SMP
+
+config MIPS_VPE_LOADER
+ bool "VPE loader support."
+ depends on MIPS_MT
+ help
+ Includes a loader for loading an elf relocatable object
+ onto another VPE and running it.
+
+endchoice
+
+config MIPS_VPE_LOADER_TOM
+ bool "Load VPE program into memory hidden from linux"
+ depends on MIPS_VPE_LOADER
+ default y
+ help
+ The loader can use memory that is present but has been hidden from
+ Linux using the kernel command line option "mem=xxMB". It's up to
+ you to ensure the amount you put in the option and the space your
+ program requires is less or equal to the amount physically present.
+
+# this should possibly be in drivers/char, but it is rather cpu related. Hmmm
+config MIPS_VPE_APSP_API
+ bool "Enable support for AP/SP API (RTLX)"
+ depends on MIPS_VPE_LOADER
+ help
config SB1_PASS_1_WORKAROUNDS
bool
@@ -1440,7 +1473,7 @@ config SB1_PASS_2_1_WORKAROUNDS
config 64BIT_PHYS_ADDR
bool "Support for 64-bit physical address space"
- depends on (CPU_R4X00 || CPU_R5000 || CPU_RM7000 || CPU_RM9000 || CPU_R10000 || CPU_SB1 || CPU_MIPS32 || CPU_MIPS64) && 32BIT
+ depends on (CPU_R4X00 || CPU_R5000 || CPU_RM7000 || CPU_RM9000 || CPU_R10000 || CPU_SB1 || CPU_MIPS32_R1 || CPU_MIPS64_R1) && 32BIT
config CPU_ADVANCED
bool "Override CPU Options"
@@ -1463,7 +1496,7 @@ config CPU_HAS_LLSC
config CPU_HAS_LLDSCD
bool "lld/scd Instructions available" if CPU_ADVANCED
- default y if !CPU_ADVANCED && !CPU_R3000 && !CPU_VR41XX && !CPU_TX39XX && !CPU_MIPS32
+ default y if !CPU_ADVANCED && !CPU_R3000 && !CPU_VR41XX && !CPU_TX39XX && !CPU_MIPS32_R1
help
Say Y here if your CPU has the lld and scd instructions, the 64-bit
equivalents of ll and sc. Say Y here for better performance, N if
@@ -1477,12 +1510,52 @@ config CPU_HAS_WB
machines which require flushing of write buffers in software. Saying
Y is the safe option; N may result in kernel malfunction and crashes.
+menu "MIPSR2 Interrupt handling"
+ depends on CPU_MIPSR2 && CPU_ADVANCED
+
+config CPU_MIPSR2_IRQ_VI
+ bool "Vectored interrupt mode"
+ help
+ Vectored interrupt mode allowing faster dispatching of interrupts.
+ The board support code needs to be written to take advantage of this
+ mode. Compatibility code is included to allow the kernel to run on
+ a CPU that does not support vectored interrupts. It's safe to
+ say Y here.
+
+config CPU_MIPSR2_IRQ_EI
+ bool "External interrupt controller mode"
+ help
+ Extended interrupt mode takes advantage of an external interrupt
+ controller to allow fast dispatching from many possible interrupt
+ sources. Say N unless you know that external interrupt support is
+ required.
+
+config CPU_MIPSR2_SRS
+ bool "Make shadow set registers available for interrupt handlers"
+ depends on CPU_MIPSR2_IRQ_VI || CPU_MIPSR2_IRQ_EI
+ help
+ Allow the kernel to use shadow register sets for fast interrupts.
+ Interrupt handlers must be specially written to use shadow sets.
+ Say N unless you know that shadow register set upport is needed.
+endmenu
+
config CPU_HAS_SYNC
bool
depends on !CPU_R3000
default y
#
+# Use the generic interrupt handling code in kernel/irq/:
+#
+config GENERIC_HARDIRQS
+ bool
+ default y
+
+config GENERIC_IRQ_PROBE
+ bool
+ default y
+
+#
# - Highmem only makes sense for the 32-bit kernel.
# - The current highmem code will only work properly on physically indexed
# caches such as R3000, SB1, R7000 or those that look like they're virtually
@@ -1491,14 +1564,19 @@ config CPU_HAS_SYNC
# where it's known to be safe. This will not offer highmem on a few systems
# such as MIPS32 and MIPS64 CPUs which may have virtual and physically
# indexed CPUs but we're playing safe.
-# - We should not offer highmem for system of which we already know that they
-# don't have memory configurations that could gain from highmem support in
-# the kernel because they don't support configurations with RAM at physical
-# addresses > 0x20000000.
+# - We use SYS_SUPPORTS_HIGHMEM to offer highmem only for systems where we
+# know they might have memory configurations that could make use of highmem
+# support.
#
config HIGHMEM
bool "High Memory Support"
- depends on 32BIT && (CPU_R3000 || CPU_SB1 || CPU_R7000 || CPU_RM9000 || CPU_R10000) && !(MACH_DECSTATION || MOMENCO_JAGUAR_ATX)
+ depends on 32BIT && CPU_SUPPORTS_HIGHMEM && SYS_SUPPORTS_HIGHMEM
+
+config CPU_SUPPORTS_HIGHMEM
+ bool
+
+config SYS_SUPPORTS_HIGHMEM
+ bool
config ARCH_FLATMEM_ENABLE
def_bool y
@@ -1508,7 +1586,7 @@ source "mm/Kconfig"
config SMP
bool "Multi-Processing support"
- depends on CPU_RM9000 || (SIBYTE_SB1250 && !SIBYTE_STANDALONE) || SGI_IP27
+ depends on CPU_RM9000 || ((SIBYTE_BCM1x80 || SIBYTE_BCM1x55 || SIBYTE_SB1250) && !SIBYTE_STANDALONE) || SGI_IP27 || MIPS_MT_SMP
---help---
This enables support for systems with more than one CPU. If you have
a system with only one CPU, like most personal computers, say N. If
@@ -1543,14 +1621,7 @@ config NR_CPUS
This is purely to save memory - each supported CPU adds
approximately eight kilobytes to the kernel image.
-config PREEMPT
- bool "Preemptible Kernel"
- help
- This option reduces the latency of the kernel when reacting to
- real-time or interactive events by allowing a low priority process to
- be preempted even if it is in kernel mode executing a system call.
- This allows applications to run more reliably even when the system is
- under load.
+source "kernel/Kconfig.preempt"
config RTC_DS1742
bool "DS1742 BRAM/RTC support"
@@ -1566,14 +1637,16 @@ config MIPS_INSANE_LARGE
This will result in additional memory usage, so it is not
recommended for normal users.
+endmenu
+
config RWSEM_GENERIC_SPINLOCK
bool
default y
-endmenu
-
menu "Bus options (PCI, PCMCIA, EISA, ISA, TC)"
+config HW_HAS_EISA
+ bool
config HW_HAS_PCI
bool
@@ -1607,7 +1680,7 @@ config ISA
config EISA
bool "EISA support"
- depends on SGI_IP22 || SNI_RM200_PCI
+ depends on HW_HAS_EISA
select ISA
---help---
The Extended Industry Standard Architecture (EISA) bus was
@@ -1641,12 +1714,6 @@ config MMU
bool
default y
-config MCA
- bool
-
-config SBUS
- bool
-
source "drivers/pcmcia/Kconfig"
source "drivers/pci/hotplug/Kconfig"
@@ -1659,7 +1726,6 @@ source "fs/Kconfig.binfmt"
config TRAD_SIGNALS
bool
- default y if 32BIT
config BUILD_ELF64
bool "Use 64-bit ELF format for building"
@@ -1678,7 +1744,7 @@ config BUILD_ELF64
config BINFMT_IRIX
bool "Include IRIX binary compatibility"
- depends on !CPU_LITTLE_ENDIAN && 32BIT && BROKEN
+ depends on CPU_BIG_ENDIAN && 32BIT && BROKEN
config MIPS32_COMPAT
bool "Kernel support for Linux/MIPS 32-bit binary compatibility"
@@ -1718,9 +1784,26 @@ config BINFMT_ELF32
bool
default y if MIPS32_O32 || MIPS32_N32
+config SECCOMP
+ bool "Enable seccomp to safely compute untrusted bytecode"
+ depends on PROC_FS && BROKEN
+ default y
+ help
+ This kernel feature is useful for number crunching applications
+ that may need to compute untrusted bytecode during their
+ execution. By using pipes or other transports made available to
+ the process as file descriptors supporting the read/write
+ syscalls, it's possible to isolate those applications in
+ their own address space using seccomp. Once seccomp is
+ enabled via /proc/<pid>/seccomp, it cannot be disabled
+ and the task is only allowed to execute a few safe syscalls
+ defined by each seccomp mode.
+
+ If unsure, say Y. Only embedded should say N here.
+
config PM
bool "Power Management support (EXPERIMENTAL)"
- depends on EXPERIMENTAL && MACH_AU1X00
+ depends on EXPERIMENTAL && SOC_AU1X00
endmenu
@@ -1730,6 +1813,8 @@ source "drivers/Kconfig"
source "fs/Kconfig"
+source "arch/mips/oprofile/Kconfig"
+
source "arch/mips/Kconfig.debug"
source "security/Kconfig"
@@ -1737,18 +1822,3 @@ source "security/Kconfig"
source "crypto/Kconfig"
source "lib/Kconfig"
-
-#
-# Use the generic interrupt handling code in kernel/irq/:
-#
-config GENERIC_HARDIRQS
- bool
- default y
-
-config GENERIC_IRQ_PROBE
- bool
- default y
-
-config ISA_DMA_API
- bool
- default y
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 346e803f153b..02692027730a 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -52,6 +52,21 @@ ifdef CONFIG_CROSSCOMPILE
CROSS_COMPILE := $(tool-prefix)
endif
+CHECKFLAGS-y += -D__linux__ -D__mips__ \
+ -D_ABIO32=1 \
+ -D_ABIN32=2 \
+ -D_ABI64=3
+CHECKFLAGS-$(CONFIG_32BIT) += -D_MIPS_SIM=_ABIO32 \
+ -D_MIPS_SZLONG=32 \
+ -D__PTRDIFF_TYPE__=int
+CHECKFLAGS-$(CONFIG_64BIT) += -m64 -D_MIPS_SIM=_ABI64 \
+ -D_MIPS_SZLONG=64 \
+ -D__PTRDIFF_TYPE__="long int"
+CHECKFLAGS-$(CONFIG_CPU_BIG_ENDIAN) += -D__MIPSEB__
+CHECKFLAGS-$(CONFIG_CPU_LITTLE_ENDIAN) += -D__MIPSEL__
+
+CHECKFLAGS = $(CHECKFLAGS-y)
+
ifdef CONFIG_BUILD_ELF64
gas-abi = 64
ld-emul = $(64bit-emul)
@@ -79,9 +94,18 @@ endif
cflags-y += -I $(TOPDIR)/include/asm/gcc
cflags-y += -G 0 -mno-abicalls -fno-pic -pipe
cflags-y += $(call cc-option, -finline-limit=100000)
-LDFLAGS_vmlinux += -G 0 -static -n
+LDFLAGS_vmlinux += -G 0 -static -n -nostdlib
MODFLAGS += -mlong-calls
+#
+# We explicitly add the endianness specifier if needed, this allows
+# to compile kernels with a toolchain for the other endianness. We
+# carefully avoid to add it redundantly because gcc 3.3/3.4 complains
+# when fed the toolchain default!
+#
+cflags-$(CONFIG_CPU_BIG_ENDIAN) += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' && echo -EB)
+cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' || echo -EL)
+
cflags-$(CONFIG_SB1XXX_CORELIS) += -mno-sched-prolog -fno-omit-frame-pointer
#
@@ -167,14 +191,22 @@ cflags-$(CONFIG_CPU_TX49XX) += \
$(call set_gccflags,r4600,mips3,r4600,mips3,mips2) \
-Wa,--trap
-cflags-$(CONFIG_CPU_MIPS32) += \
+cflags-$(CONFIG_CPU_MIPS32_R1) += \
$(call set_gccflags,mips32,mips32,r4600,mips3,mips2) \
-Wa,--trap
-cflags-$(CONFIG_CPU_MIPS64) += \
+cflags-$(CONFIG_CPU_MIPS32_R2) += \
+ $(call set_gccflags,mips32r2,mips32r2,r4600,mips3,mips2) \
+ -Wa,--trap
+
+cflags-$(CONFIG_CPU_MIPS64_R1) += \
$(call set_gccflags,mips64,mips64,r4600,mips3,mips2) \
-Wa,--trap
+cflags-$(CONFIG_CPU_MIPS64_R2) += \
+ $(call set_gccflags,mips64r2,mips64r2,r4600,mips3,mips2) \
+ -Wa,--trap
+
cflags-$(CONFIG_CPU_R5000) += \
$(call set_gccflags,r5000,mips4,r5000,mips4,mips2) \
-Wa,--trap
@@ -196,6 +228,7 @@ cflags-$(CONFIG_CPU_RM9000) += \
$(call set_gccflags,rm9000,mips4,r5000,mips4,mips2) \
-Wa,--trap
+
cflags-$(CONFIG_CPU_SB1) += \
$(call set_gccflags,sb1,mips64,r5000,mips4,mips2) \
-Wa,--trap
@@ -266,6 +299,13 @@ cflags-$(CONFIG_MIPS_PB1550) += -Iinclude/asm-mips/mach-pb1x00
load-$(CONFIG_MIPS_PB1550) += 0xffffffff80100000
#
+# AMD Alchemy Pb1200 eval board
+#
+libs-$(CONFIG_MIPS_PB1200) += arch/mips/au1000/pb1200/
+cflags-$(CONFIG_MIPS_PB1200) += -Iinclude/asm-mips/mach-pb1x00
+load-$(CONFIG_MIPS_PB1200) += 0xffffffff80100000
+
+#
# AMD Alchemy Db1000 eval board
#
libs-$(CONFIG_MIPS_DB1000) += arch/mips/au1000/db1x00/
@@ -294,6 +334,13 @@ cflags-$(CONFIG_MIPS_DB1550) += -Iinclude/asm-mips/mach-db1x00
load-$(CONFIG_MIPS_DB1550) += 0xffffffff80100000
#
+# AMD Alchemy Db1200 eval board
+#
+libs-$(CONFIG_MIPS_DB1200) += arch/mips/au1000/pb1200/
+cflags-$(CONFIG_MIPS_DB1200) += -Iinclude/asm-mips/mach-db1x00
+load-$(CONFIG_MIPS_DB1200) += 0xffffffff80100000
+
+#
# AMD Alchemy Bosporus eval board
#
libs-$(CONFIG_MIPS_BOSPORUS) += arch/mips/au1000/db1x00/
@@ -323,6 +370,7 @@ load-$(CONFIG_MIPS_XXS1500) += 0xffffffff80100000
# Cobalt Server
#
core-$(CONFIG_MIPS_COBALT) += arch/mips/cobalt/
+cflags-$(CONFIG_MIPS_COBALT) += -Iinclude/asm-mips/cobalt
load-$(CONFIG_MIPS_COBALT) += 0xffffffff80080000
#
@@ -389,6 +437,13 @@ core-$(CONFIG_MIPS_SEAD) += arch/mips/mips-boards/sead/
load-$(CONFIG_MIPS_SEAD) += 0xffffffff80100000
#
+# MIPS SIM
+#
+core-$(CONFIG_MIPS_SIM) += arch/mips/mips-boards/sim/
+cflags-$(CONFIG_MIPS_SIM) += -Iinclude/asm-mips/mach-sim
+load-$(CONFIG_MIPS_SIM) += 0x80100000
+
+#
# Momentum Ocelot board
#
# The Ocelot setup.o must be linked early - it does the ioremap() for the
@@ -514,6 +569,19 @@ load-$(CONFIG_CASIO_E55) += 0xffffffff80004000
load-$(CONFIG_TANBAC_TB022X) += 0xffffffff80000000
#
+# Common Philips PNX8550
+#
+core-$(CONFIG_SOC_PNX8550) += arch/mips/philips/pnx8550/common/
+cflags-$(CONFIG_SOC_PNX8550) += -Iinclude/asm-mips/mach-pnx8550
+
+#
+# Philips PNX8550 JBS board
+#
+libs-$(CONFIG_PNX8550_JBS) += arch/mips/philips/pnx8550/jbs/
+#cflags-$(CONFIG_PNX8550_JBS) += -Iinclude/asm-mips/mach-pnx8550
+load-$(CONFIG_PNX8550_JBS) += 0xffffffff80060000
+
+#
# SGI IP22 (Indy/Indigo2)
#
# Set the load address to >= 0xffffffff88069000 if you want to leave space for
@@ -582,10 +650,20 @@ load-$(CONFIG_SGI_IP32) += 0xffffffff80004000
# removed (as happens, even if they have __initcall/module_init)
#
core-$(CONFIG_SIBYTE_BCM112X) += arch/mips/sibyte/sb1250/
-cflags-$(CONFIG_SIBYTE_BCM112X) += -Iinclude/asm-mips/mach-sibyte
+cflags-$(CONFIG_SIBYTE_BCM112X) += -Iinclude/asm-mips/mach-sibyte \
+ -DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1250_112x_ALL
core-$(CONFIG_SIBYTE_SB1250) += arch/mips/sibyte/sb1250/
-cflags-$(CONFIG_SIBYTE_SB1250) += -Iinclude/asm-mips/mach-sibyte
+cflags-$(CONFIG_SIBYTE_SB1250) += -Iinclude/asm-mips/mach-sibyte \
+ -DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1250_112x_ALL
+
+core-$(CONFIG_SIBYTE_BCM1x55) += arch/mips/sibyte/bcm1480/
+cflags-$(CONFIG_SIBYTE_BCM1x55) += -Iinclude/asm-mips/mach-sibyte \
+ -DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1480_ALL
+
+core-$(CONFIG_SIBYTE_BCM1x80) += arch/mips/sibyte/bcm1480/
+cflags-$(CONFIG_SIBYTE_BCM1x80) += -Iinclude/asm-mips/mach-sibyte \
+ -DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1480_ALL
#
# Sibyte BCM91120x (Carmel) board
@@ -593,6 +671,7 @@ cflags-$(CONFIG_SIBYTE_SB1250) += -Iinclude/asm-mips/mach-sibyte
# Sibyte BCM91125C (CRhone) board
# Sibyte BCM91125E (Rhone) board
# Sibyte SWARM board
+# Sibyte BCM91x80 (BigSur) board
#
libs-$(CONFIG_SIBYTE_CARMEL) += arch/mips/sibyte/swarm/
load-$(CONFIG_SIBYTE_CARMEL) := 0xffffffff80100000
@@ -606,6 +685,8 @@ libs-$(CONFIG_SIBYTE_SENTOSA) += arch/mips/sibyte/swarm/
load-$(CONFIG_SIBYTE_SENTOSA) := 0xffffffff80100000
libs-$(CONFIG_SIBYTE_SWARM) += arch/mips/sibyte/swarm/
load-$(CONFIG_SIBYTE_SWARM) := 0xffffffff80100000
+libs-$(CONFIG_SIBYTE_BIGSUR) += arch/mips/sibyte/swarm/
+load-$(CONFIG_SIBYTE_BIGSUR) := 0xffffffff80100000
#
# SNI RM200 PCI
@@ -629,6 +710,13 @@ core-$(CONFIG_TOSHIBA_RBTX4927) += arch/mips/tx4927/toshiba_rbtx4927/
core-$(CONFIG_TOSHIBA_RBTX4927) += arch/mips/tx4927/common/
load-$(CONFIG_TOSHIBA_RBTX4927) += 0xffffffff80020000
+#
+# Toshiba RBTX4938 board
+#
+core-$(CONFIG_TOSHIBA_RBTX4938) += arch/mips/tx4938/toshiba_rbtx4938/
+core-$(CONFIG_TOSHIBA_RBTX4938) += arch/mips/tx4938/common/
+load-$(CONFIG_TOSHIBA_RBTX4938) += 0xffffffff80100000
+
cflags-y += -Iinclude/asm-mips/mach-generic
drivers-$(CONFIG_PCI) += arch/mips/pci/
@@ -701,10 +789,29 @@ ifdef CONFIG_BOOT_ELF64
all: $(vmlinux-64)
endif
+ifdef CONFIG_MIPS_ATLAS
+all: vmlinux.srec
+endif
+
+ifdef CONFIG_MIPS_MALTA
+all: vmlinux.srec
+endif
+
+ifdef CONFIG_MIPS_SEAD
+all: vmlinux.srec
+endif
+
+ifdef CONFIG_QEMU
+all: vmlinux.bin
+endif
+
ifdef CONFIG_SNI_RM200_PCI
all: vmlinux.ecoff
endif
+vmlinux.bin: $(vmlinux-32)
+ +@$(call makeboot,$@)
+
vmlinux.ecoff vmlinux.rm200: $(vmlinux-32)
+@$(call makeboot,$@)
@@ -720,7 +827,6 @@ archclean:
@$(MAKE) $(clean)=arch/mips/boot
@$(MAKE) $(clean)=arch/mips/lasat
-
CLEAN_FILES += vmlinux.32 \
vmlinux.64 \
vmlinux.ecoff
diff --git a/arch/mips/arc/Makefile b/arch/mips/arc/Makefile
index e8424932e1a3..4f349ec1ea2d 100644
--- a/arch/mips/arc/Makefile
+++ b/arch/mips/arc/Makefile
@@ -3,7 +3,7 @@
#
lib-y += cmdline.o env.o file.o identify.o init.o \
- misc.o time.o tree.o
+ misc.o salone.o time.o tree.o
lib-$(CONFIG_ARC_MEMORY) += memory.o
lib-$(CONFIG_ARC_CONSOLE) += arc_con.o
diff --git a/arch/mips/arc/identify.c b/arch/mips/arc/identify.c
index 0dd7a345eb79..1bd6199e174a 100644
--- a/arch/mips/arc/identify.c
+++ b/arch/mips/arc/identify.c
@@ -44,6 +44,11 @@ static struct smatch mach_table[] = {
MACH_GROUP_SGI,
MACH_SGI_IP28,
PROM_FLAG_ARCS
+ }, { "SGI-IP30",
+ "SGI Octane",
+ MACH_GROUP_SGI,
+ MACH_SGI_IP30,
+ PROM_FLAG_ARCS
}, { "SGI-IP32",
"SGI O2",
MACH_GROUP_SGI,
diff --git a/arch/mips/au1000/common/Makefile b/arch/mips/au1000/common/Makefile
index 594b75e5e080..a1edfd1f643c 100644
--- a/arch/mips/au1000/common/Makefile
+++ b/arch/mips/au1000/common/Makefile
@@ -8,7 +8,7 @@
obj-y += prom.o int-handler.o irq.o puts.o time.o reset.o \
au1xxx_irqmap.o clocks.o platform.o power.o setup.o \
- sleeper.o cputable.o dma.o dbdma.o
+ sleeper.o cputable.o dma.o dbdma.o gpio.o
obj-$(CONFIG_AU1X00_USB_DEVICE) += usbdev.o
obj-$(CONFIG_KGDB) += dbg_io.o
diff --git a/arch/mips/au1000/common/au1xxx_irqmap.c b/arch/mips/au1000/common/au1xxx_irqmap.c
index 8a0f39f67c59..0b2c03c52319 100644
--- a/arch/mips/au1000/common/au1xxx_irqmap.c
+++ b/arch/mips/au1000/common/au1xxx_irqmap.c
@@ -173,14 +173,14 @@ au1xxx_irq_map_t au1xxx_ic0_map[] = {
{ AU1550_PSC1_INT, INTC_INT_HIGH_LEVEL, 0},
{ AU1550_PSC2_INT, INTC_INT_HIGH_LEVEL, 0},
{ AU1550_PSC3_INT, INTC_INT_HIGH_LEVEL, 0},
- { AU1550_TOY_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1550_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1550_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1550_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
- { AU1550_RTC_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1550_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1550_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1550_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
+ { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
+ { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+ { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+ { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
+ { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 },
+ { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+ { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+ { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1550_NAND_INT, INTC_INT_RISE_EDGE, 0},
{ AU1550_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1550_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
@@ -201,14 +201,14 @@ au1xxx_irq_map_t au1xxx_ic0_map[] = {
{ AU1200_PSC1_INT, INTC_INT_HIGH_LEVEL, 0},
{ AU1200_AES_INT, INTC_INT_HIGH_LEVEL, 0},
{ AU1200_CAMERA_INT, INTC_INT_HIGH_LEVEL, 0},
- { AU1200_TOY_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1200_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1200_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1200_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
- { AU1200_RTC_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1200_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1200_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1200_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
+ { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
+ { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+ { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+ { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
+ { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 },
+ { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+ { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+ { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1200_NAND_INT, INTC_INT_RISE_EDGE, 0},
{ AU1200_USB_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1200_LCD_INT, INTC_INT_HIGH_LEVEL, 0},
diff --git a/arch/mips/au1000/common/cputable.c b/arch/mips/au1000/common/cputable.c
index f5521dfccfd6..4dbde82c8215 100644
--- a/arch/mips/au1000/common/cputable.c
+++ b/arch/mips/au1000/common/cputable.c
@@ -37,7 +37,8 @@ struct cpu_spec cpu_specs[] = {
{ 0xffffffff, 0x02030203, "Au1100 BD", 0, 1 },
{ 0xffffffff, 0x02030204, "Au1100 BE", 0, 1 },
{ 0xffffffff, 0x03030200, "Au1550 AA", 0, 1 },
- { 0xffffffff, 0x04030200, "Au1200 AA", 0, 1 },
+ { 0xffffffff, 0x04030200, "Au1200 AB", 0, 0 },
+ { 0xffffffff, 0x04030201, "Au1200 AC", 0, 1 },
{ 0x00000000, 0x00000000, "Unknown Au1xxx", 1, 0 },
};
diff --git a/arch/mips/au1000/common/dbdma.c b/arch/mips/au1000/common/dbdma.c
index adfc3172aace..d00e8247d6c2 100644
--- a/arch/mips/au1000/common/dbdma.c
+++ b/arch/mips/au1000/common/dbdma.c
@@ -29,6 +29,7 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
+
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -38,10 +39,12 @@
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
+#include <linux/module.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h>
#include <asm/system.h>
+
#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
/*
@@ -61,37 +64,10 @@ static DEFINE_SPINLOCK(au1xxx_dbdma_spin_lock);
*/
#define ALIGN_ADDR(x, a) ((((u32)(x)) + (a-1)) & ~(a-1))
-static volatile dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE;
-static int dbdma_initialized;
+static dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE;
+static int dbdma_initialized=0;
static void au1xxx_dbdma_init(void);
-typedef struct dbdma_device_table {
- u32 dev_id;
- u32 dev_flags;
- u32 dev_tsize;
- u32 dev_devwidth;
- u32 dev_physaddr; /* If FIFO */
- u32 dev_intlevel;
- u32 dev_intpolarity;
-} dbdev_tab_t;
-
-typedef struct dbdma_chan_config {
- u32 chan_flags;
- u32 chan_index;
- dbdev_tab_t *chan_src;
- dbdev_tab_t *chan_dest;
- au1x_dma_chan_t *chan_ptr;
- au1x_ddma_desc_t *chan_desc_base;
- au1x_ddma_desc_t *get_ptr, *put_ptr, *cur_ptr;
- void *chan_callparam;
- void (*chan_callback)(int, void *, struct pt_regs *);
-} chan_tab_t;
-
-#define DEV_FLAGS_INUSE (1 << 0)
-#define DEV_FLAGS_ANYUSE (1 << 1)
-#define DEV_FLAGS_OUT (1 << 2)
-#define DEV_FLAGS_IN (1 << 3)
-
static dbdev_tab_t dbdev_tab[] = {
#ifdef CONFIG_SOC_AU1550
/* UARTS */
@@ -157,25 +133,25 @@ static dbdev_tab_t dbdev_tab[] = {
{ DSCR_CMD0_MAE_BOTH, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
{ DSCR_CMD0_LCD, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
- { DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
- { DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
- { DSCR_CMD0_SDMS_TX1, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
- { DSCR_CMD0_SDMS_RX1, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+ { DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 4, 8, 0x10600000, 0, 0 },
+ { DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 4, 8, 0x10600004, 0, 0 },
+ { DSCR_CMD0_SDMS_TX1, DEV_FLAGS_OUT, 4, 8, 0x10680000, 0, 0 },
+ { DSCR_CMD0_SDMS_RX1, DEV_FLAGS_IN, 4, 8, 0x10680004, 0, 0 },
- { DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
- { DSCR_CMD0_AES_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+ { DSCR_CMD0_AES_RX, DEV_FLAGS_IN , 4, 32, 0x10300008, 0, 0 },
+ { DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 4, 32, 0x10300004, 0, 0 },
- { DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 0, 0x11a0001c, 0, 0 },
- { DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 0, 0x11a0001c, 0, 0 },
+ { DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 16, 0x11a0001c, 0, 0 },
+ { DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 16, 0x11a0001c, 0, 0 },
{ DSCR_CMD0_PSC0_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
- { DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 0, 0x11b0001c, 0, 0 },
- { DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 0, 0x11b0001c, 0, 0 },
+ { DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 16, 0x11b0001c, 0, 0 },
+ { DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 16, 0x11b0001c, 0, 0 },
{ DSCR_CMD0_PSC1_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
- { DSCR_CMD0_CIM_RXA, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
- { DSCR_CMD0_CIM_RXB, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
- { DSCR_CMD0_CIM_RXC, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+ { DSCR_CMD0_CIM_RXA, DEV_FLAGS_IN, 0, 32, 0x14004020, 0, 0 },
+ { DSCR_CMD0_CIM_RXB, DEV_FLAGS_IN, 0, 32, 0x14004040, 0, 0 },
+ { DSCR_CMD0_CIM_RXC, DEV_FLAGS_IN, 0, 32, 0x14004060, 0, 0 },
{ DSCR_CMD0_CIM_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
{ DSCR_CMD0_NAND_FLASH, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
@@ -184,6 +160,24 @@ static dbdev_tab_t dbdev_tab[] = {
{ DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
{ DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+
+ /* Provide 16 user definable device types */
+ { 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0 },
};
#define DBDEV_TAB_SIZE (sizeof(dbdev_tab) / sizeof(dbdev_tab_t))
@@ -203,6 +197,36 @@ find_dbdev_id (u32 id)
return NULL;
}
+void * au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp)
+{
+ return phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+}
+EXPORT_SYMBOL(au1xxx_ddma_get_nextptr_virt);
+
+u32
+au1xxx_ddma_add_device(dbdev_tab_t *dev)
+{
+ u32 ret = 0;
+ dbdev_tab_t *p=NULL;
+ static u16 new_id=0x1000;
+
+ p = find_dbdev_id(0);
+ if ( NULL != p )
+ {
+ memcpy(p, dev, sizeof(dbdev_tab_t));
+ p->dev_id = DSCR_DEV2CUSTOM_ID(new_id,dev->dev_id);
+ ret = p->dev_id;
+ new_id++;
+#if 0
+ printk("add_device: id:%x flags:%x padd:%x\n",
+ p->dev_id, p->dev_flags, p->dev_physaddr );
+#endif
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(au1xxx_ddma_add_device);
+
/* Allocate a channel and return a non-zero descriptor if successful.
*/
u32
@@ -215,7 +239,7 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
int i;
dbdev_tab_t *stp, *dtp;
chan_tab_t *ctp;
- volatile au1x_dma_chan_t *cp;
+ au1x_dma_chan_t *cp;
/* We do the intialization on the first channel allocation.
* We have to wait because of the interrupt handler initialization
@@ -225,9 +249,6 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
au1xxx_dbdma_init();
dbdma_initialized = 1;
- if ((srcid > DSCR_NDEV_IDS) || (destid > DSCR_NDEV_IDS))
- return 0;
-
if ((stp = find_dbdev_id(srcid)) == NULL) return 0;
if ((dtp = find_dbdev_id(destid)) == NULL) return 0;
@@ -271,7 +292,6 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
*/
ctp = kmalloc(sizeof(chan_tab_t), GFP_KERNEL);
chan_tab_ptr[i] = ctp;
- ctp->chan_index = chan = i;
break;
}
}
@@ -279,10 +299,11 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
if (ctp != NULL) {
memset(ctp, 0, sizeof(chan_tab_t));
+ ctp->chan_index = chan = i;
dcp = DDMA_CHANNEL_BASE;
dcp += (0x0100 * chan);
ctp->chan_ptr = (au1x_dma_chan_t *)dcp;
- cp = (volatile au1x_dma_chan_t *)dcp;
+ cp = (au1x_dma_chan_t *)dcp;
ctp->chan_src = stp;
ctp->chan_dest = dtp;
ctp->chan_callback = callback;
@@ -299,6 +320,9 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
i |= DDMA_CFG_DED;
if (dtp->dev_intpolarity)
i |= DDMA_CFG_DP;
+ if ((stp->dev_flags & DEV_FLAGS_SYNC) ||
+ (dtp->dev_flags & DEV_FLAGS_SYNC))
+ i |= DDMA_CFG_SYNC;
cp->ddma_cfg = i;
au_sync();
@@ -309,14 +333,14 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
rv = (u32)(&chan_tab_ptr[chan]);
}
else {
- /* Release devices.
- */
+ /* Release devices */
stp->dev_flags &= ~DEV_FLAGS_INUSE;
dtp->dev_flags &= ~DEV_FLAGS_INUSE;
}
}
return rv;
}
+EXPORT_SYMBOL(au1xxx_dbdma_chan_alloc);
/* Set the device width if source or destination is a FIFO.
* Should be 8, 16, or 32 bits.
@@ -344,6 +368,7 @@ au1xxx_dbdma_set_devwidth(u32 chanid, int bits)
return rv;
}
+EXPORT_SYMBOL(au1xxx_dbdma_set_devwidth);
/* Allocate a descriptor ring, initializing as much as possible.
*/
@@ -370,7 +395,8 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
* and if we try that first we are likely to not waste larger
* slabs of memory.
*/
- desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t), GFP_KERNEL);
+ desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t),
+ GFP_KERNEL|GFP_DMA);
if (desc_base == 0)
return 0;
@@ -381,7 +407,7 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
kfree((const void *)desc_base);
i = entries * sizeof(au1x_ddma_desc_t);
i += (sizeof(au1x_ddma_desc_t) - 1);
- if ((desc_base = (u32)kmalloc(i, GFP_KERNEL)) == 0)
+ if ((desc_base = (u32)kmalloc(i, GFP_KERNEL|GFP_DMA)) == 0)
return 0;
desc_base = ALIGN_ADDR(desc_base, sizeof(au1x_ddma_desc_t));
@@ -403,7 +429,13 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
cmd0 |= DSCR_CMD0_SID(srcid);
cmd0 |= DSCR_CMD0_DID(destid);
cmd0 |= DSCR_CMD0_IE | DSCR_CMD0_CV;
- cmd0 |= DSCR_CMD0_ST(DSCR_CMD0_ST_CURRENT);
+ cmd0 |= DSCR_CMD0_ST(DSCR_CMD0_ST_NOCHANGE);
+
+ /* is it mem to mem transfer? */
+ if(((DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_THROTTLE) || (DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_ALWAYS)) &&
+ ((DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_THROTTLE) || (DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_ALWAYS))) {
+ cmd0 |= DSCR_CMD0_MEM;
+ }
switch (stp->dev_devwidth) {
case 8:
@@ -461,9 +493,14 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
/* If source input is fifo, set static address.
*/
if (stp->dev_flags & DEV_FLAGS_IN) {
- src0 = stp->dev_physaddr;
+ if ( stp->dev_flags & DEV_FLAGS_BURSTABLE )
+ src1 |= DSCR_SRC1_SAM(DSCR_xAM_BURST);
+ else
src1 |= DSCR_SRC1_SAM(DSCR_xAM_STATIC);
+
}
+ if (stp->dev_physaddr)
+ src0 = stp->dev_physaddr;
/* Set up dest1. For now, assume no stride and increment.
* A channel attribute update can change this later.
@@ -487,10 +524,18 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
/* If destination output is fifo, set static address.
*/
if (dtp->dev_flags & DEV_FLAGS_OUT) {
- dest0 = dtp->dev_physaddr;
+ if ( dtp->dev_flags & DEV_FLAGS_BURSTABLE )
+ dest1 |= DSCR_DEST1_DAM(DSCR_xAM_BURST);
+ else
dest1 |= DSCR_DEST1_DAM(DSCR_xAM_STATIC);
}
+ if (dtp->dev_physaddr)
+ dest0 = dtp->dev_physaddr;
+#if 0
+ printk("did:%x sid:%x cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n",
+ dtp->dev_id, stp->dev_id, cmd0, cmd1, src0, src1, dest0, dest1 );
+#endif
for (i=0; i<entries; i++) {
dp->dscr_cmd0 = cmd0;
dp->dscr_cmd1 = cmd1;
@@ -499,6 +544,8 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
dp->dscr_dest0 = dest0;
dp->dscr_dest1 = dest1;
dp->dscr_stat = 0;
+ dp->sw_context = 0;
+ dp->sw_status = 0;
dp->dscr_nxtptr = DSCR_NXTPTR(virt_to_phys(dp + 1));
dp++;
}
@@ -511,13 +558,14 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
return (u32)(ctp->chan_desc_base);
}
+EXPORT_SYMBOL(au1xxx_dbdma_ring_alloc);
/* Put a source buffer into the DMA ring.
* This updates the source pointer and byte count. Normally used
* for memory to fifo transfers.
*/
u32
-au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes)
+_au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags)
{
chan_tab_t *ctp;
au1x_ddma_desc_t *dp;
@@ -544,8 +592,24 @@ au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes)
*/
dp->dscr_source0 = virt_to_phys(buf);
dp->dscr_cmd1 = nbytes;
- dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */
- ctp->chan_ptr->ddma_dbell = 0xffffffff; /* Make it go */
+ /* Check flags */
+ if (flags & DDMA_FLAGS_IE)
+ dp->dscr_cmd0 |= DSCR_CMD0_IE;
+ if (flags & DDMA_FLAGS_NOIE)
+ dp->dscr_cmd0 &= ~DSCR_CMD0_IE;
+
+ /*
+ * There is an errata on the Au1200/Au1550 parts that could result
+ * in "stale" data being DMA'd. It has to do with the snoop logic on
+ * the dache eviction buffer. NONCOHERENT_IO is on by default for
+ * these parts. If it is fixedin the future, these dma_cache_inv will
+ * just be nothing more than empty macros. See io.h.
+ * */
+ dma_cache_wback_inv((unsigned long)buf, nbytes);
+ dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */
+ au_sync();
+ dma_cache_wback_inv((unsigned long)dp, sizeof(dp));
+ ctp->chan_ptr->ddma_dbell = 0;
/* Get next descriptor pointer.
*/
@@ -555,13 +619,14 @@ au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes)
*/
return nbytes;
}
+EXPORT_SYMBOL(_au1xxx_dbdma_put_source);
/* Put a destination buffer into the DMA ring.
* This updates the destination pointer and byte count. Normally used
* to place an empty buffer into the ring for fifo to memory transfers.
*/
u32
-au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes)
+_au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags)
{
chan_tab_t *ctp;
au1x_ddma_desc_t *dp;
@@ -583,11 +648,33 @@ au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes)
if (dp->dscr_cmd0 & DSCR_CMD0_V)
return 0;
- /* Load up buffer address and byte count.
- */
+ /* Load up buffer address and byte count */
+
+ /* Check flags */
+ if (flags & DDMA_FLAGS_IE)
+ dp->dscr_cmd0 |= DSCR_CMD0_IE;
+ if (flags & DDMA_FLAGS_NOIE)
+ dp->dscr_cmd0 &= ~DSCR_CMD0_IE;
+
dp->dscr_dest0 = virt_to_phys(buf);
dp->dscr_cmd1 = nbytes;
+#if 0
+ printk("cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n",
+ dp->dscr_cmd0, dp->dscr_cmd1, dp->dscr_source0,
+ dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1 );
+#endif
+ /*
+ * There is an errata on the Au1200/Au1550 parts that could result in
+ * "stale" data being DMA'd. It has to do with the snoop logic on the
+ * dache eviction buffer. NONCOHERENT_IO is on by default for these
+ * parts. If it is fixedin the future, these dma_cache_inv will just
+ * be nothing more than empty macros. See io.h.
+ * */
+ dma_cache_inv((unsigned long)buf,nbytes);
dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */
+ au_sync();
+ dma_cache_wback_inv((unsigned long)dp, sizeof(dp));
+ ctp->chan_ptr->ddma_dbell = 0;
/* Get next descriptor pointer.
*/
@@ -597,6 +684,7 @@ au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes)
*/
return nbytes;
}
+EXPORT_SYMBOL(_au1xxx_dbdma_put_dest);
/* Get a destination buffer into the DMA ring.
* Normally used to get a full buffer from the ring during fifo
@@ -646,7 +734,7 @@ void
au1xxx_dbdma_stop(u32 chanid)
{
chan_tab_t *ctp;
- volatile au1x_dma_chan_t *cp;
+ au1x_dma_chan_t *cp;
int halt_timeout = 0;
ctp = *((chan_tab_t **)chanid);
@@ -666,6 +754,7 @@ au1xxx_dbdma_stop(u32 chanid)
cp->ddma_stat |= (DDMA_STAT_DB | DDMA_STAT_V);
au_sync();
}
+EXPORT_SYMBOL(au1xxx_dbdma_stop);
/* Start using the current descriptor pointer. If the dbdma encounters
* a not valid descriptor, it will stop. In this case, we can just
@@ -675,17 +764,17 @@ void
au1xxx_dbdma_start(u32 chanid)
{
chan_tab_t *ctp;
- volatile au1x_dma_chan_t *cp;
+ au1x_dma_chan_t *cp;
ctp = *((chan_tab_t **)chanid);
-
cp = ctp->chan_ptr;
cp->ddma_desptr = virt_to_phys(ctp->cur_ptr);
cp->ddma_cfg |= DDMA_CFG_EN; /* Enable channel */
au_sync();
- cp->ddma_dbell = 0xffffffff; /* Make it go */
+ cp->ddma_dbell = 0;
au_sync();
}
+EXPORT_SYMBOL(au1xxx_dbdma_start);
void
au1xxx_dbdma_reset(u32 chanid)
@@ -704,15 +793,21 @@ au1xxx_dbdma_reset(u32 chanid)
do {
dp->dscr_cmd0 &= ~DSCR_CMD0_V;
+ /* reset our SW status -- this is used to determine
+ * if a descriptor is in use by upper level SW. Since
+ * posting can reset 'V' bit.
+ */
+ dp->sw_status = 0;
dp = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
} while (dp != ctp->chan_desc_base);
}
+EXPORT_SYMBOL(au1xxx_dbdma_reset);
u32
au1xxx_get_dma_residue(u32 chanid)
{
chan_tab_t *ctp;
- volatile au1x_dma_chan_t *cp;
+ au1x_dma_chan_t *cp;
u32 rv;
ctp = *((chan_tab_t **)chanid);
@@ -738,8 +833,7 @@ au1xxx_dbdma_chan_free(u32 chanid)
au1xxx_dbdma_stop(chanid);
- if (ctp->chan_desc_base != NULL)
- kfree(ctp->chan_desc_base);
+ kfree((void *)ctp->chan_desc_base);
stp->dev_flags &= ~DEV_FLAGS_INUSE;
dtp->dev_flags &= ~DEV_FLAGS_INUSE;
@@ -747,15 +841,16 @@ au1xxx_dbdma_chan_free(u32 chanid)
kfree(ctp);
}
+EXPORT_SYMBOL(au1xxx_dbdma_chan_free);
static irqreturn_t
dbdma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
- u32 intstat;
- u32 chan_index;
+ u32 intstat;
+ u32 chan_index;
chan_tab_t *ctp;
au1x_ddma_desc_t *dp;
- volatile au1x_dma_chan_t *cp;
+ au1x_dma_chan_t *cp;
intstat = dbdma_gptr->ddma_intstat;
au_sync();
@@ -774,19 +869,27 @@ dbdma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
(ctp->chan_callback)(irq, ctp->chan_callparam, regs);
ctp->cur_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
-
- return IRQ_HANDLED;
+ return IRQ_RETVAL(1);
}
-static void
-au1xxx_dbdma_init(void)
+static void au1xxx_dbdma_init(void)
{
+ int irq_nr;
+
dbdma_gptr->ddma_config = 0;
dbdma_gptr->ddma_throttle = 0;
dbdma_gptr->ddma_inten = 0xffff;
au_sync();
- if (request_irq(AU1550_DDMA_INT, dbdma_interrupt, SA_INTERRUPT,
+#if defined(CONFIG_SOC_AU1550)
+ irq_nr = AU1550_DDMA_INT;
+#elif defined(CONFIG_SOC_AU1200)
+ irq_nr = AU1200_DDMA_INT;
+#else
+ #error Unknown Au1x00 SOC
+#endif
+
+ if (request_irq(irq_nr, dbdma_interrupt, SA_INTERRUPT,
"Au1xxx dbdma", (void *)dbdma_gptr))
printk("Can't get 1550 dbdma irq");
}
@@ -797,7 +900,8 @@ au1xxx_dbdma_dump(u32 chanid)
chan_tab_t *ctp;
au1x_ddma_desc_t *dp;
dbdev_tab_t *stp, *dtp;
- volatile au1x_dma_chan_t *cp;
+ au1x_dma_chan_t *cp;
+ u32 i = 0;
ctp = *((chan_tab_t **)chanid);
stp = ctp->chan_src;
@@ -822,15 +926,64 @@ au1xxx_dbdma_dump(u32 chanid)
dp = ctp->chan_desc_base;
do {
- printk("dp %08x, cmd0 %08x, cmd1 %08x\n",
- (u32)dp, dp->dscr_cmd0, dp->dscr_cmd1);
- printk("src0 %08x, src1 %08x, dest0 %08x\n",
- dp->dscr_source0, dp->dscr_source1, dp->dscr_dest0);
- printk("dest1 %08x, stat %08x, nxtptr %08x\n",
- dp->dscr_dest1, dp->dscr_stat, dp->dscr_nxtptr);
+ printk("Dp[%d]= %08x, cmd0 %08x, cmd1 %08x\n",
+ i++, (u32)dp, dp->dscr_cmd0, dp->dscr_cmd1);
+ printk("src0 %08x, src1 %08x, dest0 %08x, dest1 %08x\n",
+ dp->dscr_source0, dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1);
+ printk("stat %08x, nxtptr %08x\n",
+ dp->dscr_stat, dp->dscr_nxtptr);
dp = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
} while (dp != ctp->chan_desc_base);
}
+/* Put a descriptor into the DMA ring.
+ * This updates the source/destination pointers and byte count.
+ */
+u32
+au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr )
+{
+ chan_tab_t *ctp;
+ au1x_ddma_desc_t *dp;
+ u32 nbytes=0;
+
+ /* I guess we could check this to be within the
+ * range of the table......
+ */
+ ctp = *((chan_tab_t **)chanid);
+
+ /* We should have multiple callers for a particular channel,
+ * an interrupt doesn't affect this pointer nor the descriptor,
+ * so no locking should be needed.
+ */
+ dp = ctp->put_ptr;
+
+ /* If the descriptor is valid, we are way ahead of the DMA
+ * engine, so just return an error condition.
+ */
+ if (dp->dscr_cmd0 & DSCR_CMD0_V)
+ return 0;
+
+ /* Load up buffer addresses and byte count.
+ */
+ dp->dscr_dest0 = dscr->dscr_dest0;
+ dp->dscr_source0 = dscr->dscr_source0;
+ dp->dscr_dest1 = dscr->dscr_dest1;
+ dp->dscr_source1 = dscr->dscr_source1;
+ dp->dscr_cmd1 = dscr->dscr_cmd1;
+ nbytes = dscr->dscr_cmd1;
+ /* Allow the caller to specifiy if an interrupt is generated */
+ dp->dscr_cmd0 &= ~DSCR_CMD0_IE;
+ dp->dscr_cmd0 |= dscr->dscr_cmd0 | DSCR_CMD0_V;
+ ctp->chan_ptr->ddma_dbell = 0;
+
+ /* Get next descriptor pointer.
+ */
+ ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+
+ /* return something not zero.
+ */
+ return nbytes;
+}
+
#endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */
diff --git a/arch/mips/au1000/common/dma.c b/arch/mips/au1000/common/dma.c
index 372c33f1353d..1905c6b104f2 100644
--- a/arch/mips/au1000/common/dma.c
+++ b/arch/mips/au1000/common/dma.c
@@ -39,7 +39,6 @@
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/module.h>
#include <asm/system.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1000_dma.h>
diff --git a/arch/mips/au1000/common/gpio.c b/arch/mips/au1000/common/gpio.c
new file mode 100644
index 000000000000..5f5915b83142
--- /dev/null
+++ b/arch/mips/au1000/common/gpio.c
@@ -0,0 +1,119 @@
+/*
+ * This program is free software; you can redistribute 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/config.h>
+#include <linux/module.h>
+#include <au1000.h>
+#include <au1xxx_gpio.h>
+
+#define gpio1 sys
+#if !defined(CONFIG_SOC_AU1000)
+static AU1X00_GPIO2 * const gpio2 = (AU1X00_GPIO2 *)GPIO2_BASE;
+
+#define GPIO2_OUTPUT_ENABLE_MASK 0x00010000
+
+int au1xxx_gpio2_read(int signal)
+{
+ signal -= 200;
+/* gpio2->dir &= ~(0x01 << signal); //Set GPIO to input */
+ return ((gpio2->pinstate >> signal) & 0x01);
+}
+
+void au1xxx_gpio2_write(int signal, int value)
+{
+ signal -= 200;
+
+ gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << signal) |
+ (value << signal);
+}
+
+void au1xxx_gpio2_tristate(int signal)
+{
+ signal -= 200;
+ gpio2->dir &= ~(0x01 << signal); /* Set GPIO to input */
+}
+#endif
+
+int au1xxx_gpio1_read(int signal)
+{
+/* gpio1->trioutclr |= (0x01 << signal); */
+ return ((gpio1->pinstaterd >> signal) & 0x01);
+}
+
+void au1xxx_gpio1_write(int signal, int value)
+{
+ if(value)
+ gpio1->outputset = (0x01 << signal);
+ else
+ gpio1->outputclr = (0x01 << signal); /* Output a Zero */
+}
+
+void au1xxx_gpio1_tristate(int signal)
+{
+ gpio1->trioutclr = (0x01 << signal); /* Tristate signal */
+}
+
+
+int au1xxx_gpio_read(int signal)
+{
+ if(signal >= 200)
+#if defined(CONFIG_SOC_AU1000)
+ return 0;
+#else
+ return au1xxx_gpio2_read(signal);
+#endif
+ else
+ return au1xxx_gpio1_read(signal);
+}
+
+void au1xxx_gpio_write(int signal, int value)
+{
+ if(signal >= 200)
+#if defined(CONFIG_SOC_AU1000)
+ ;
+#else
+ au1xxx_gpio2_write(signal, value);
+#endif
+ else
+ au1xxx_gpio1_write(signal, value);
+}
+
+void au1xxx_gpio_tristate(int signal)
+{
+ if(signal >= 200)
+#if defined(CONFIG_SOC_AU1000)
+ ;
+#else
+ au1xxx_gpio2_tristate(signal);
+#endif
+ else
+ au1xxx_gpio1_tristate(signal);
+}
+
+void au1xxx_gpio1_set_inputs(void)
+{
+ gpio1->pininputen = 0;
+}
+
+EXPORT_SYMBOL(au1xxx_gpio1_set_inputs);
+EXPORT_SYMBOL(au1xxx_gpio_tristate);
+EXPORT_SYMBOL(au1xxx_gpio_write);
+EXPORT_SYMBOL(au1xxx_gpio_read);
diff --git a/arch/mips/au1000/common/irq.c b/arch/mips/au1000/common/irq.c
index d1eb5a4a9a19..1339a0979f66 100644
--- a/arch/mips/au1000/common/irq.c
+++ b/arch/mips/au1000/common/irq.c
@@ -83,7 +83,7 @@ inline void local_disable_irq(unsigned int irq_nr);
void (*board_init_irq)(void);
#ifdef CONFIG_PM
-extern void counter0_irq(int irq, void *dev_id, struct pt_regs *regs);
+extern irqreturn_t counter0_irq(int irq, void *dev_id, struct pt_regs *regs);
#endif
static DEFINE_SPINLOCK(irq_lock);
@@ -253,52 +253,72 @@ void restore_local_and_enable(int controller, unsigned long mask)
static struct hw_interrupt_type rise_edge_irq_type = {
- "Au1000 Rise Edge",
- startup_irq,
- shutdown_irq,
- local_enable_irq,
- local_disable_irq,
- mask_and_ack_rise_edge_irq,
- end_irq,
- NULL
+ .typename = "Au1000 Rise Edge",
+ .startup = startup_irq,
+ .shutdown = shutdown_irq,
+ .enable = local_enable_irq,
+ .disable = local_disable_irq,
+ .ack = mask_and_ack_rise_edge_irq,
+ .end = end_irq,
};
static struct hw_interrupt_type fall_edge_irq_type = {
- "Au1000 Fall Edge",
- startup_irq,
- shutdown_irq,
- local_enable_irq,
- local_disable_irq,
- mask_and_ack_fall_edge_irq,
- end_irq,
- NULL
+ .typename = "Au1000 Fall Edge",
+ .startup = startup_irq,
+ .shutdown = shutdown_irq,
+ .enable = local_enable_irq,
+ .disable = local_disable_irq,
+ .ack = mask_and_ack_fall_edge_irq,
+ .end = end_irq,
};
static struct hw_interrupt_type either_edge_irq_type = {
- "Au1000 Rise or Fall Edge",
- startup_irq,
- shutdown_irq,
- local_enable_irq,
- local_disable_irq,
- mask_and_ack_either_edge_irq,
- end_irq,
- NULL
+ .typename = "Au1000 Rise or Fall Edge",
+ .startup = startup_irq,
+ .shutdown = shutdown_irq,
+ .enable = local_enable_irq,
+ .disable = local_disable_irq,
+ .ack = mask_and_ack_either_edge_irq,
+ .end = end_irq,
};
static struct hw_interrupt_type level_irq_type = {
- "Au1000 Level",
- startup_irq,
- shutdown_irq,
- local_enable_irq,
- local_disable_irq,
- mask_and_ack_level_irq,
- end_irq,
- NULL
+ .typename = "Au1000 Level",
+ .startup = startup_irq,
+ .shutdown = shutdown_irq,
+ .enable = local_enable_irq,
+ .disable = local_disable_irq,
+ .ack = mask_and_ack_level_irq,
+ .end = end_irq,
};
#ifdef CONFIG_PM
-void startup_match20_interrupt(void)
+void startup_match20_interrupt(irqreturn_t (*handler)(int, void *, struct pt_regs *))
{
+ struct irq_desc *desc = &irq_desc[AU1000_TOY_MATCH2_INT];
+
+ static struct irqaction action;
+ memset(&action, 0, sizeof(struct irqaction));
+
+ /* This is a big problem.... since we didn't use request_irq
+ * when kernel/irq.c calls probe_irq_xxx this interrupt will
+ * be probed for usage. This will end up disabling the device :(
+ * Give it a bogus "action" pointer -- this will keep it from
+ * getting auto-probed!
+ *
+ * By setting the status to match that of request_irq() we
+ * can avoid it. --cgray
+ */
+ action.dev_id = handler;
+ action.flags = SA_INTERRUPT;
+ cpus_clear(action.mask);
+ action.name = "Au1xxx TOY";
+ action.handler = handler;
+ action.next = NULL;
+
+ desc->action = &action;
+ desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS);
+
local_enable_irq(AU1000_TOY_MATCH2_INT);
}
#endif
@@ -426,7 +446,6 @@ void __init arch_init_irq(void)
extern int au1xxx_ic0_nr_irqs;
cp0_status = read_c0_status();
- memset(irq_desc, 0, sizeof(irq_desc));
set_except_vector(0, au1000_IRQ);
/* Initialize interrupt controllers to a safe state.
@@ -492,7 +511,7 @@ void intc0_req0_irqdispatch(struct pt_regs *regs)
intc0_req0 |= au_readl(IC0_REQ0INT);
if (!intc0_req0) return;
-
+#ifdef AU1000_USB_DEV_REQ_INT
/*
* Because of the tight timing of SETUP token to reply
* transactions, the USB devices-side packet complete
@@ -503,7 +522,7 @@ void intc0_req0_irqdispatch(struct pt_regs *regs)
do_IRQ(AU1000_USB_DEV_REQ_INT, regs);
return;
}
-
+#endif
irq = au_ffs(intc0_req0) - 1;
intc0_req0 &= ~(1<<irq);
do_IRQ(irq, regs);
@@ -521,17 +540,7 @@ void intc0_req1_irqdispatch(struct pt_regs *regs)
irq = au_ffs(intc0_req1) - 1;
intc0_req1 &= ~(1<<irq);
-#ifdef CONFIG_PM
- if (irq == AU1000_TOY_MATCH2_INT) {
- mask_and_ack_rise_edge_irq(irq);
- counter0_irq(irq, NULL, regs);
- local_enable_irq(irq);
- }
- else
-#endif
- {
- do_IRQ(irq, regs);
- }
+ do_IRQ(irq, regs);
}
diff --git a/arch/mips/au1000/common/platform.c b/arch/mips/au1000/common/platform.c
index 3c778d0f58a6..48d3f54f88f8 100644
--- a/arch/mips/au1000/common/platform.c
+++ b/arch/mips/au1000/common/platform.c
@@ -7,13 +7,16 @@
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
+#include <linux/config.h>
+#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/resource.h>
-#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/au1xxx.h>
+/* OHCI (USB full speed host controller) */
static struct resource au1xxx_usb_ohci_resources[] = {
[0] = {
.start = USB_OHCI_BASE,
@@ -41,8 +44,252 @@ static struct platform_device au1xxx_usb_ohci_device = {
.resource = au1xxx_usb_ohci_resources,
};
+/*** AU1100 LCD controller ***/
+
+#ifdef CONFIG_FB_AU1100
+static struct resource au1100_lcd_resources[] = {
+ [0] = {
+ .start = LCD_PHYS_ADDR,
+ .end = LCD_PHYS_ADDR + 0x800 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1100_LCD_INT,
+ .end = AU1100_LCD_INT,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 au1100_lcd_dmamask = ~(u32)0;
+
+static struct platform_device au1100_lcd_device = {
+ .name = "au1100-lcd",
+ .id = 0,
+ .dev = {
+ .dma_mask = &au1100_lcd_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(au1100_lcd_resources),
+ .resource = au1100_lcd_resources,
+};
+#endif
+
+#ifdef CONFIG_SOC_AU1200
+/* EHCI (USB high speed host controller) */
+static struct resource au1xxx_usb_ehci_resources[] = {
+ [0] = {
+ .start = USB_EHCI_BASE,
+ .end = USB_EHCI_BASE + USB_EHCI_LEN - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1000_USB_HOST_INT,
+ .end = AU1000_USB_HOST_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 ehci_dmamask = ~(u32)0;
+
+static struct platform_device au1xxx_usb_ehci_device = {
+ .name = "au1xxx-ehci",
+ .id = 0,
+ .dev = {
+ .dma_mask = &ehci_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(au1xxx_usb_ehci_resources),
+ .resource = au1xxx_usb_ehci_resources,
+};
+
+/* Au1200 UDC (USB gadget controller) */
+static struct resource au1xxx_usb_gdt_resources[] = {
+ [0] = {
+ .start = USB_UDC_BASE,
+ .end = USB_UDC_BASE + USB_UDC_LEN - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1200_USB_INT,
+ .end = AU1200_USB_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource au1xxx_mmc_resources[] = {
+ [0] = {
+ .start = SD0_PHYS_ADDR,
+ .end = SD0_PHYS_ADDR + 0x40,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = SD1_PHYS_ADDR,
+ .end = SD1_PHYS_ADDR + 0x40,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = AU1200_SD_INT,
+ .end = AU1200_SD_INT,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 udc_dmamask = ~(u32)0;
+
+static struct platform_device au1xxx_usb_gdt_device = {
+ .name = "au1xxx-udc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &udc_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(au1xxx_usb_gdt_resources),
+ .resource = au1xxx_usb_gdt_resources,
+};
+
+/* Au1200 UOC (USB OTG controller) */
+static struct resource au1xxx_usb_otg_resources[] = {
+ [0] = {
+ .start = USB_UOC_BASE,
+ .end = USB_UOC_BASE + USB_UOC_LEN - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1200_USB_INT,
+ .end = AU1200_USB_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 uoc_dmamask = ~(u32)0;
+
+static struct platform_device au1xxx_usb_otg_device = {
+ .name = "au1xxx-uoc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &uoc_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(au1xxx_usb_otg_resources),
+ .resource = au1xxx_usb_otg_resources,
+};
+
+static struct resource au1200_lcd_resources[] = {
+ [0] = {
+ .start = LCD_PHYS_ADDR,
+ .end = LCD_PHYS_ADDR + 0x800 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1200_LCD_INT,
+ .end = AU1200_LCD_INT,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct resource au1200_ide0_resources[] = {
+ [0] = {
+ .start = AU1XXX_ATA_PHYS_ADDR,
+ .end = AU1XXX_ATA_PHYS_ADDR + AU1XXX_ATA_PHYS_LEN,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1XXX_ATA_INT,
+ .end = AU1XXX_ATA_INT,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 au1200_lcd_dmamask = ~(u32)0;
+
+static struct platform_device au1200_lcd_device = {
+ .name = "au1200-lcd",
+ .id = 0,
+ .dev = {
+ .dma_mask = &au1200_lcd_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(au1200_lcd_resources),
+ .resource = au1200_lcd_resources,
+};
+
+
+static u64 ide0_dmamask = ~(u32)0;
+
+static struct platform_device au1200_ide0_device = {
+ .name = "au1200-ide",
+ .id = 0,
+ .dev = {
+ .dma_mask = &ide0_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(au1200_ide0_resources),
+ .resource = au1200_ide0_resources,
+};
+
+static u64 au1xxx_mmc_dmamask = ~(u32)0;
+
+static struct platform_device au1xxx_mmc_device = {
+ .name = "au1xxx-mmc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &au1xxx_mmc_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(au1xxx_mmc_resources),
+ .resource = au1xxx_mmc_resources,
+};
+#endif /* #ifdef CONFIG_SOC_AU1200 */
+
+static struct platform_device au1x00_pcmcia_device = {
+ .name = "au1x00-pcmcia",
+ .id = 0,
+};
+
+#ifdef CONFIG_MIPS_DB1200
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .name = "smc91x-regs",
+ .start = AU1XXX_SMC91111_PHYS_ADDR,
+ .end = AU1XXX_SMC91111_PHYS_ADDR + 0xfffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1XXX_SMC91111_IRQ,
+ .end = AU1XXX_SMC91111_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+
+#endif
+
static struct platform_device *au1xxx_platform_devices[] __initdata = {
&au1xxx_usb_ohci_device,
+ &au1x00_pcmcia_device,
+#ifdef CONFIG_FB_AU1100
+ &au1100_lcd_device,
+#endif
+#ifdef CONFIG_SOC_AU1200
+#if 0 /* fixme */
+ &au1xxx_usb_ehci_device,
+#endif
+ &au1xxx_usb_gdt_device,
+ &au1xxx_usb_otg_device,
+ &au1200_lcd_device,
+ &au1200_ide0_device,
+ &au1xxx_mmc_device,
+#endif
+#ifdef CONFIG_MIPS_DB1200
+ &smc91x_device,
+#endif
};
int au1xxx_platform_init(void)
diff --git a/arch/mips/au1000/common/power.c b/arch/mips/au1000/common/power.c
index c40daccbb5b1..f85093b8d54d 100644
--- a/arch/mips/au1000/common/power.c
+++ b/arch/mips/au1000/common/power.c
@@ -34,11 +34,13 @@
#include <linux/pm.h>
#include <linux/slab.h>
#include <linux/sysctl.h>
+#include <linux/jiffies.h>
#include <asm/string.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/system.h>
+#include <asm/cacheflush.h>
#include <asm/mach-au1x00/au1000.h>
#ifdef CONFIG_PM
@@ -50,7 +52,7 @@
# define DPRINTK(fmt, args...)
#endif
-static void calibrate_delay(void);
+static void au1000_calibrate_delay(void);
extern void set_au1x00_speed(unsigned int new_freq);
extern unsigned int get_au1x00_speed(void);
@@ -260,7 +262,7 @@ int au_sleep(void)
}
static int pm_do_sleep(ctl_table * ctl, int write, struct file *file,
- void *buffer, size_t * len)
+ void __user *buffer, size_t * len, loff_t *ppos)
{
int retval = 0;
#ifdef SLEEP_TEST_TIMEOUT
@@ -294,10 +296,9 @@ static int pm_do_sleep(ctl_table * ctl, int write, struct file *file,
}
static int pm_do_suspend(ctl_table * ctl, int write, struct file *file,
- void *buffer, size_t * len)
+ void __user *buffer, size_t * len, loff_t *ppos)
{
int retval = 0;
- void au1k_wait(void);
if (!write) {
*len = 0;
@@ -306,7 +307,7 @@ static int pm_do_suspend(ctl_table * ctl, int write, struct file *file,
if (retval)
return retval;
suspend_mode = 1;
- au1k_wait();
+
retval = pm_send_all(PM_RESUME, (void *) 0);
}
return retval;
@@ -314,7 +315,7 @@ static int pm_do_suspend(ctl_table * ctl, int write, struct file *file,
static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
- void *buffer, size_t * len)
+ void __user *buffer, size_t * len, loff_t *ppos)
{
int retval = 0, i;
unsigned long val, pll;
@@ -409,14 +410,14 @@ static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
/* We don't want _any_ interrupts other than
- * match20. Otherwise our calibrate_delay()
+ * match20. Otherwise our au1000_calibrate_delay()
* calculation will be off, potentially a lot.
*/
intc0_mask = save_local_and_disable(0);
intc1_mask = save_local_and_disable(1);
local_enable_irq(AU1000_TOY_MATCH2_INT);
spin_unlock_irqrestore(&pm_lock, flags);
- calibrate_delay();
+ au1000_calibrate_delay();
restore_local_and_enable(0, intc0_mask);
restore_local_and_enable(1, intc1_mask);
return retval;
@@ -456,7 +457,7 @@ __initcall(pm_init);
better than 1% */
#define LPS_PREC 8
-static void calibrate_delay(void)
+static void au1000_calibrate_delay(void)
{
unsigned long ticks, loopbit;
int lps_precision = LPS_PREC;
diff --git a/arch/mips/au1000/common/prom.c b/arch/mips/au1000/common/prom.c
index 22e5a85af4d5..9c171afd9a53 100644
--- a/arch/mips/au1000/common/prom.c
+++ b/arch/mips/au1000/common/prom.c
@@ -75,7 +75,8 @@ void prom_init_cmdline(void)
}
if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
--cp;
- *cp = '\0';
+ if (prom_argc > 1)
+ *cp = '\0';
}
diff --git a/arch/mips/au1000/common/puts.c b/arch/mips/au1000/common/puts.c
index c2ae4624b77b..2705829cd466 100644
--- a/arch/mips/au1000/common/puts.c
+++ b/arch/mips/au1000/common/puts.c
@@ -39,7 +39,6 @@
#define TIMEOUT 0xffffff
#define SLOW_DOWN
-static const char digits[16] = "0123456789abcdef";
static volatile unsigned long * const com1 = (unsigned long *)SERIAL_BASE;
@@ -54,7 +53,7 @@ static inline void slow_down(void)
#endif
void
-putch(const unsigned char c)
+prom_putchar(const unsigned char c)
{
unsigned char ch;
int i = 0;
@@ -69,77 +68,3 @@ putch(const unsigned char c)
} while (0 == (ch & TX_BUSY));
com1[SER_DATA] = c;
}
-
-void
-puts(unsigned char *cp)
-{
- unsigned char ch;
- int i = 0;
-
- while (*cp) {
- do {
- ch = com1[SER_CMD];
- slow_down();
- i++;
- if (i>TIMEOUT) {
- break;
- }
- } while (0 == (ch & TX_BUSY));
- com1[SER_DATA] = *cp++;
- }
- putch('\r');
- putch('\n');
-}
-
-void
-fputs(const char *cp)
-{
- unsigned char ch;
- int i = 0;
-
- while (*cp) {
-
- do {
- ch = com1[SER_CMD];
- slow_down();
- i++;
- if (i>TIMEOUT) {
- break;
- }
- } while (0 == (ch & TX_BUSY));
- com1[SER_DATA] = *cp++;
- }
-}
-
-
-void
-put64(uint64_t ul)
-{
- int cnt;
- unsigned ch;
-
- cnt = 16; /* 16 nibbles in a 64 bit long */
- putch('0');
- putch('x');
- do {
- cnt--;
- ch = (unsigned char)(ul >> cnt * 4) & 0x0F;
- putch(digits[ch]);
- } while (cnt > 0);
-}
-
-void
-put32(unsigned u)
-{
- int cnt;
- unsigned ch;
-
- cnt = 8; /* 8 nibbles in a 32 bit long */
- putch('0');
- putch('x');
- do {
- cnt--;
- ch = (unsigned char)(u >> cnt * 4) & 0x0F;
- putch(digits[ch]);
- } while (cnt > 0);
-}
diff --git a/arch/mips/au1000/common/setup.c b/arch/mips/au1000/common/setup.c
index eff89e109ce6..1ef15d5ef943 100644
--- a/arch/mips/au1000/common/setup.c
+++ b/arch/mips/au1000/common/setup.c
@@ -32,6 +32,7 @@
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
+#include <linux/module.h>
#include <asm/cpu.h>
#include <asm/bootinfo.h>
@@ -57,7 +58,7 @@ extern void au1xxx_time_init(void);
extern void au1xxx_timer_setup(struct irqaction *irq);
extern void set_cpuspec(void);
-static int __init au1x00_setup(void)
+void __init plat_setup(void)
{
struct cpu_spec *sp;
char *argptr;
@@ -106,8 +107,6 @@ static int __init au1x00_setup(void)
/*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/
#ifdef CONFIG_MIPS_HYDROGEN3
strcat(argptr, " video=au1100fb:panel:Hydrogen_3_NEC_panel_320x240,nohwcursor");
-#else
- strcat(argptr, " video=au1100fb:panel:s10,nohwcursor");
#endif
}
#endif
@@ -153,15 +152,11 @@ static int __init au1x00_setup(void)
au_sync();
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S);
au_writel(0, SYS_TOYTRIM);
-
- return 0;
}
-early_initcall(au1x00_setup);
-
#if defined(CONFIG_64BIT_PHYS_ADDR)
/* This routine should be valid for all Au1x based boards */
-phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
{
u32 start, end;
@@ -192,4 +187,5 @@ phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
/* default nop */
return phys_addr;
}
+EXPORT_SYMBOL(__fixup_bigphys_addr);
#endif
diff --git a/arch/mips/au1000/common/time.c b/arch/mips/au1000/common/time.c
index 57675b41480e..883d3f3d8c53 100644
--- a/arch/mips/au1000/common/time.c
+++ b/arch/mips/au1000/common/time.c
@@ -50,7 +50,6 @@
#include <linux/mc146818rtc.h>
#include <linux/timex.h>
-extern void startup_match20_interrupt(void);
extern void do_softirq(void);
extern volatile unsigned long wall_jiffies;
unsigned long missed_heart_beats = 0;
@@ -58,14 +57,17 @@ unsigned long missed_heart_beats = 0;
static unsigned long r4k_offset; /* Amount to increment compare reg each time */
static unsigned long r4k_cur; /* What counter should be at next timer irq */
int no_au1xxx_32khz;
-void (*au1k_wait_ptr)(void);
+extern int allow_au1k_wait; /* default off for CP0 Counter */
/* Cycle counter value at the previous timer interrupt.. */
static unsigned int timerhi = 0, timerlo = 0;
#ifdef CONFIG_PM
-#define MATCH20_INC 328
-extern void startup_match20_interrupt(void);
+#if HZ < 100 || HZ > 1000
+#error "unsupported HZ value! Must be in [100,1000]"
+#endif
+#define MATCH20_INC (328*100/HZ) /* magic number 328 is for HZ=100... */
+extern void startup_match20_interrupt(irqreturn_t (*handler)(int, void *, struct pt_regs *));
static unsigned long last_pc0, last_match20;
#endif
@@ -117,17 +119,16 @@ null:
}
#ifdef CONFIG_PM
-void counter0_irq(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t counter0_irq(int irq, void *dev_id, struct pt_regs *regs)
{
unsigned long pc0;
int time_elapsed;
static int jiffie_drift = 0;
- kstat.irqs[0][irq]++;
if (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20) {
/* should never happen! */
- printk(KERN_WARNING "counter 0 w status eror\n");
- return;
+ printk(KERN_WARNING "counter 0 w status error\n");
+ return IRQ_NONE;
}
pc0 = au_readl(SYS_TOYREAD);
@@ -164,6 +165,8 @@ void counter0_irq(int irq, void *dev_id, struct pt_regs *regs)
update_process_times(user_mode(regs));
#endif
}
+
+ return IRQ_HANDLED;
}
/* When we wakeup from sleep, we have to "catch up" on all of the
@@ -388,7 +391,6 @@ void au1xxx_timer_setup(struct irqaction *irq)
{
unsigned int est_freq;
extern unsigned long (*do_gettimeoffset)(void);
- extern void au1k_wait(void);
printk("calculating r4koff... ");
r4k_offset = cal_r4koff();
@@ -441,18 +443,18 @@ void au1xxx_timer_setup(struct irqaction *irq)
au_sync();
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
- /* setup match20 to interrupt once every 10ms */
+ /* setup match20 to interrupt once every HZ */
last_pc0 = last_match20 = au_readl(SYS_TOYREAD);
au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
au_sync();
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
- startup_match20_interrupt();
+ startup_match20_interrupt(counter0_irq);
do_gettimeoffset = do_fast_pm_gettimeoffset;
/* We can use the real 'wait' instruction.
*/
- au1k_wait_ptr = au1k_wait;
+ allow_au1k_wait = 1;
}
#else
diff --git a/arch/mips/au1000/common/usbdev.c b/arch/mips/au1000/common/usbdev.c
index 447a9a4612a8..0b21bed7ee55 100644
--- a/arch/mips/au1000/common/usbdev.c
+++ b/arch/mips/au1000/common/usbdev.c
@@ -1005,11 +1005,11 @@ process_ep0_receive (struct usb_dev* dev)
#endif
dev->ep0_stage = SETUP_STAGE;
break;
- }
+ }
spin_unlock(&ep0->lock);
- // we're done processing the packet, free it
- kfree(pkt);
+ // we're done processing the packet, free it
+ kfree(pkt);
}
@@ -1072,8 +1072,7 @@ dma_done_ep0_intr(int irq, void *dev_id, struct pt_regs *regs)
clear_dma_done1(ep0->indma);
pkt = send_packet_complete(ep0);
- if (pkt)
- kfree(pkt);
+ kfree(pkt);
}
/*
@@ -1302,8 +1301,7 @@ usbdev_exit(void)
endpoint_flush(ep);
}
- if (usbdev.full_conf_desc)
- kfree(usbdev.full_conf_desc);
+ kfree(usbdev.full_conf_desc);
}
int
diff --git a/arch/mips/au1000/csb250/init.c b/arch/mips/au1000/csb250/init.c
index bd99733abc0b..a4898b1bc66a 100644
--- a/arch/mips/au1000/csb250/init.c
+++ b/arch/mips/au1000/csb250/init.c
@@ -35,7 +35,6 @@
#include <asm/bootinfo.h>
#include <linux/string.h>
#include <linux/kernel.h>
-#include <linux/sched.h>
int prom_argc;
char **prom_argv, **prom_envp;
diff --git a/arch/mips/au1000/db1x00/irqmap.c b/arch/mips/au1000/db1x00/irqmap.c
index 8f6ef0dbe1f8..f63024a9893a 100644
--- a/arch/mips/au1000/db1x00/irqmap.c
+++ b/arch/mips/au1000/db1x00/irqmap.c
@@ -48,6 +48,38 @@
#include <asm/system.h>
#include <asm/mach-au1x00/au1000.h>
+#ifdef CONFIG_MIPS_DB1500
+char irq_tab_alchemy[][5] __initdata = {
+ [12] = { -1, INTA, INTX, INTX, INTX}, /* IDSEL 12 - HPT371 */
+ [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot */
+};
+#endif
+
+#ifdef CONFIG_MIPS_BOSPORUS
+char irq_tab_alchemy[][5] __initdata = {
+ [11] = { -1, INTA, INTB, INTX, INTX}, /* IDSEL 11 - miniPCI */
+ [12] = { -1, INTA, INTX, INTX, INTX}, /* IDSEL 12 - SN1741 */
+ [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot */
+};
+#endif
+
+#ifdef CONFIG_MIPS_MIRAGE
+char irq_tab_alchemy[][5] __initdata = {
+ [11] = { -1, INTD, INTX, INTX, INTX}, /* IDSEL 11 - SMI VGX */
+ [12] = { -1, INTX, INTX, INTC, INTX}, /* IDSEL 12 - PNX1300 */
+ [13] = { -1, INTA, INTB, INTX, INTX}, /* IDSEL 13 - miniPCI */
+};
+#endif
+
+#ifdef CONFIG_MIPS_DB1550
+char irq_tab_alchemy[][5] __initdata = {
+ [11] = { -1, INTC, INTX, INTX, INTX}, /* IDSEL 11 - on-board HPT371 */
+ [12] = { -1, INTB, INTC, INTD, INTA}, /* IDSEL 12 - PCI slot 2 (left) */
+ [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot 1 (right) */
+};
+#endif
+
+
au1xxx_irq_map_t au1xxx_irq_map[] = {
#ifndef CONFIG_MIPS_MIRAGE
diff --git a/arch/mips/au1000/db1x00/mirage_ts.c b/arch/mips/au1000/db1x00/mirage_ts.c
index ade35e432004..c29852c24b4f 100644
--- a/arch/mips/au1000/db1x00/mirage_ts.c
+++ b/arch/mips/au1000/db1x00/mirage_ts.c
@@ -102,15 +102,15 @@ static struct {
} mirage_ts_cal =
{
#if 0
- xscale: 84,
- xtrans: -157,
- yscale: 66,
- ytrans: -150,
+ .xscale = 84,
+ .xtrans = -157,
+ .yscale = 66,
+ .ytrans = -150,
#else
- xscale: 84,
- xtrans: -150,
- yscale: 66,
- ytrans: -146,
+ .xscale = 84,
+ .xtrans = -150,
+ .yscale = 66,
+ .ytrans = -146,
#endif
};
diff --git a/arch/mips/au1000/hydrogen3/init.c b/arch/mips/au1000/hydrogen3/init.c
index 8cc9879dd582..01ab28483959 100644
--- a/arch/mips/au1000/hydrogen3/init.c
+++ b/arch/mips/au1000/hydrogen3/init.c
@@ -37,7 +37,6 @@
#include <linux/config.h>
#include <linux/string.h>
#include <linux/kernel.h>
-#include <linux/sched.h>
int prom_argc;
char **prom_argv, **prom_envp;
diff --git a/arch/mips/au1000/mtx-1/init.c b/arch/mips/au1000/mtx-1/init.c
index 02e7dbcff727..88f2b6d97281 100644
--- a/arch/mips/au1000/mtx-1/init.c
+++ b/arch/mips/au1000/mtx-1/init.c
@@ -33,7 +33,6 @@
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/mm.h>
-#include <linux/sched.h>
#include <linux/bootmem.h>
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
diff --git a/arch/mips/au1000/mtx-1/irqmap.c b/arch/mips/au1000/mtx-1/irqmap.c
index ddcb9d089dc1..f9a0a8b9def2 100644
--- a/arch/mips/au1000/mtx-1/irqmap.c
+++ b/arch/mips/au1000/mtx-1/irqmap.c
@@ -47,6 +47,17 @@
#include <asm/system.h>
#include <asm/mach-au1x00/au1000.h>
+char irq_tab_alchemy[][5] __initdata = {
+ [0] = { -1, INTA, INTB, INTX, INTX}, /* IDSEL 00 - AdapterA-Slot0 (top) */
+ [1] = { -1, INTB, INTA, INTX, INTX}, /* IDSEL 01 - AdapterA-Slot1 (bottom) */
+ [2] = { -1, INTC, INTD, INTX, INTX}, /* IDSEL 02 - AdapterB-Slot0 (top) */
+ [3] = { -1, INTD, INTC, INTX, INTX}, /* IDSEL 03 - AdapterB-Slot1 (bottom) */
+ [4] = { -1, INTA, INTB, INTX, INTX}, /* IDSEL 04 - AdapterC-Slot0 (top) */
+ [5] = { -1, INTB, INTA, INTX, INTX}, /* IDSEL 05 - AdapterC-Slot1 (bottom) */
+ [6] = { -1, INTC, INTD, INTX, INTX}, /* IDSEL 06 - AdapterD-Slot0 (top) */
+ [7] = { -1, INTD, INTC, INTX, INTX}, /* IDSEL 07 - AdapterD-Slot1 (bottom) */
+};
+
au1xxx_irq_map_t au1xxx_irq_map[] = {
{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
{ AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
diff --git a/arch/mips/au1000/pb1000/init.c b/arch/mips/au1000/pb1000/init.c
index 34713c5df0d7..e9fa1bab81f3 100644
--- a/arch/mips/au1000/pb1000/init.c
+++ b/arch/mips/au1000/pb1000/init.c
@@ -65,5 +65,4 @@ void __init prom_init(void)
memsize = simple_strtol(memsize_str, NULL, 0);
}
add_memory_region(0, memsize, BOOT_MEM_RAM);
- return 0;
}
diff --git a/arch/mips/au1000/pb1200/Makefile b/arch/mips/au1000/pb1200/Makefile
new file mode 100644
index 000000000000..22b673cf55af
--- /dev/null
+++ b/arch/mips/au1000/pb1200/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the Alchemy Semiconductor PB1200 board.
+#
+
+lib-y := init.o board_setup.o irqmap.o
diff --git a/arch/mips/au1000/pb1200/board_setup.c b/arch/mips/au1000/pb1200/board_setup.c
new file mode 100644
index 000000000000..a45b17538ac9
--- /dev/null
+++ b/arch/mips/au1000/pb1200/board_setup.c
@@ -0,0 +1,193 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * Alchemy Pb1200/Db1200 board setup.
+ *
+ * This program is free software; you can redistribute 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/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/mc146818rtc.h>
+#include <linux/delay.h>
+
+#if defined(CONFIG_BLK_DEV_IDE_AU1XXX)
+#include <linux/ide.h>
+#endif
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/pgtable.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/au1xxx_dbdma.h>
+
+#ifdef CONFIG_MIPS_PB1200
+#include <asm/mach-pb1x00/pb1200.h>
+#endif
+
+#ifdef CONFIG_MIPS_DB1200
+#include <asm/mach-db1x00/db1200.h>
+#define PB1200_ETH_INT DB1200_ETH_INT
+#define PB1200_IDE_INT DB1200_IDE_INT
+#endif
+
+extern void _board_init_irq(void);
+extern void (*board_init_irq)(void);
+
+void board_reset (void)
+{
+ bcsr->resets = 0;
+ bcsr->system = 0;
+}
+
+void __init board_setup(void)
+{
+ char *argptr = NULL;
+ u32 pin_func;
+
+#if 0
+ /* Enable PSC1 SYNC for AC97. Normaly done in audio driver,
+ * but it is board specific code, so put it here.
+ */
+ pin_func = au_readl(SYS_PINFUNC);
+ au_sync();
+ pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
+ au_writel(pin_func, SYS_PINFUNC);
+
+ au_writel(0, (u32)bcsr|0x10); /* turn off pcmcia power */
+ au_sync();
+#endif
+
+#if defined(CONFIG_I2C_AU1550)
+ {
+ u32 freq0, clksrc;
+
+ /* Select SMBUS in CPLD */
+ bcsr->resets &= ~(BCSR_RESETS_PCS0MUX);
+
+ pin_func = au_readl(SYS_PINFUNC);
+ au_sync();
+ pin_func &= ~(3<<17 | 1<<4);
+ /* Set GPIOs correctly */
+ pin_func |= 2<<17;
+ au_writel(pin_func, SYS_PINFUNC);
+ au_sync();
+
+ /* The i2c driver depends on 50Mhz clock */
+ freq0 = au_readl(SYS_FREQCTRL0);
+ au_sync();
+ freq0 &= ~(SYS_FC_FRDIV1_MASK | SYS_FC_FS1 | SYS_FC_FE1);
+ freq0 |= (3<<SYS_FC_FRDIV1_BIT);
+ /* 396Mhz / (3+1)*2 == 49.5Mhz */
+ au_writel(freq0, SYS_FREQCTRL0);
+ au_sync();
+ freq0 |= SYS_FC_FE1;
+ au_writel(freq0, SYS_FREQCTRL0);
+ au_sync();
+
+ clksrc = au_readl(SYS_CLKSRC);
+ au_sync();
+ clksrc &= ~0x01f00000;
+ /* bit 22 is EXTCLK0 for PSC0 */
+ clksrc |= (0x3 << 22);
+ au_writel(clksrc, SYS_CLKSRC);
+ au_sync();
+ }
+#endif
+
+#ifdef CONFIG_FB_AU1200
+ argptr = prom_getcmdline();
+#ifdef CONFIG_MIPS_PB1200
+ strcat(argptr, " video=au1200fb:panel:bs");
+#endif
+#ifdef CONFIG_MIPS_DB1200
+ strcat(argptr, " video=au1200fb:panel:bs");
+#endif
+#endif
+
+ /* The Pb1200 development board uses external MUX for PSC0 to
+ support SMB/SPI. bcsr->resets bit 12: 0=SMB 1=SPI
+ */
+#if defined(CONFIG_AU1XXX_PSC_SPI) && defined(CONFIG_I2C_AU1550)
+ #error I2C and SPI are mutually exclusive. Both are physically connected to PSC0.\
+ Refer to Pb1200/Db1200 documentation.
+#elif defined( CONFIG_AU1XXX_PSC_SPI )
+ bcsr->resets |= BCSR_RESETS_PCS0MUX;
+ /*Hard Coding Value to enable Temp Sensors [bit 14] Value for SOC Au1200. Pls refer documentation*/
+ bcsr->resets =0x900f;
+#elif defined( CONFIG_I2C_AU1550 )
+ bcsr->resets &= (~BCSR_RESETS_PCS0MUX);
+#endif
+ au_sync();
+
+#ifdef CONFIG_MIPS_PB1200
+ printk("AMD Alchemy Pb1200 Board\n");
+#endif
+#ifdef CONFIG_MIPS_DB1200
+ printk("AMD Alchemy Db1200 Board\n");
+#endif
+
+ /* Setup Pb1200 External Interrupt Controller */
+ {
+ extern void (*board_init_irq)(void);
+ extern void _board_init_irq(void);
+ board_init_irq = _board_init_irq;
+ }
+}
+
+int
+board_au1200fb_panel (void)
+{
+ BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+ int p;
+
+ p = bcsr->switches;
+ p >>= 8;
+ p &= 0x0F;
+ return p;
+}
+
+int
+board_au1200fb_panel_init (void)
+{
+ /* Apply power */
+ BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+ bcsr->board |= (BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD | BCSR_BOARD_LCDBL);
+ /*printk("board_au1200fb_panel_init()\n"); */
+ return 0;
+}
+
+int
+board_au1200fb_panel_shutdown (void)
+{
+ /* Remove power */
+ BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+ bcsr->board &= ~(BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD | BCSR_BOARD_LCDBL);
+ /*printk("board_au1200fb_panel_shutdown()\n"); */
+ return 0;
+}
+
diff --git a/arch/mips/au1000/pb1200/init.c b/arch/mips/au1000/pb1200/init.c
new file mode 100644
index 000000000000..27f09e374e15
--- /dev/null
+++ b/arch/mips/au1000/pb1200/init.c
@@ -0,0 +1,69 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * PB1200 board setup
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * ppopov@mvista.com or source@mvista.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * 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/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+
+int prom_argc;
+char **prom_argv, **prom_envp;
+extern void __init prom_init_cmdline(void);
+extern char *prom_getenv(char *envname);
+
+const char *get_system_type(void)
+{
+ return "Alchemy Pb1200";
+}
+
+void __init prom_init(void)
+{
+ unsigned char *memsize_str;
+ unsigned long memsize;
+
+ prom_argc = (int) fw_arg0;
+ prom_argv = (char **) fw_arg1;
+ prom_envp = (char **) fw_arg2;
+
+ mips_machgroup = MACH_GROUP_ALCHEMY;
+ mips_machtype = MACH_PB1200;
+
+ prom_init_cmdline();
+ memsize_str = prom_getenv("memsize");
+ if (!memsize_str) {
+ memsize = 0x08000000;
+ } else {
+ memsize = simple_strtol(memsize_str, NULL, 0);
+ }
+ add_memory_region(0, memsize, BOOT_MEM_RAM);
+}
diff --git a/arch/mips/au1000/pb1200/irqmap.c b/arch/mips/au1000/pb1200/irqmap.c
new file mode 100644
index 000000000000..59e70e5cf325
--- /dev/null
+++ b/arch/mips/au1000/pb1200/irqmap.c
@@ -0,0 +1,182 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ * Au1xxx irq map table
+ *
+ * This program is free software; you can redistribute 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/config.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/delay.h>
+
+#include <asm/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/mach-au1x00/au1000.h>
+
+#ifdef CONFIG_MIPS_PB1200
+#include <asm/mach-pb1x00/pb1200.h>
+#endif
+
+#ifdef CONFIG_MIPS_DB1200
+#include <asm/mach-db1x00/db1200.h>
+#define PB1200_INT_BEGIN DB1200_INT_BEGIN
+#define PB1200_INT_END DB1200_INT_END
+#endif
+
+au1xxx_irq_map_t au1xxx_irq_map[] = {
+ { AU1000_GPIO_7, INTC_INT_LOW_LEVEL, 0 }, // This is exteranl interrupt cascade
+};
+
+int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t);
+
+/*
+ * Support for External interrupts on the PbAu1200 Development platform.
+ */
+static volatile int pb1200_cascade_en=0;
+
+irqreturn_t pb1200_cascade_handler( int irq, void *dev_id, struct pt_regs *regs)
+{
+ unsigned short bisr = bcsr->int_status;
+ int extirq_nr = 0;
+
+ /* Clear all the edge interrupts. This has no effect on level */
+ bcsr->int_status = bisr;
+ for( ; bisr; bisr &= (bisr-1) )
+ {
+ extirq_nr = (PB1200_INT_BEGIN-1) + au_ffs(bisr);
+ /* Ack and dispatch IRQ */
+ do_IRQ(extirq_nr,regs);
+ }
+ return IRQ_RETVAL(1);
+}
+
+inline void pb1200_enable_irq(unsigned int irq_nr)
+{
+ bcsr->intset_mask = 1<<(irq_nr - PB1200_INT_BEGIN);
+ bcsr->intset = 1<<(irq_nr - PB1200_INT_BEGIN);
+}
+
+inline void pb1200_disable_irq(unsigned int irq_nr)
+{
+ bcsr->intclr_mask = 1<<(irq_nr - PB1200_INT_BEGIN);
+ bcsr->intclr = 1<<(irq_nr - PB1200_INT_BEGIN);
+}
+
+static unsigned int pb1200_startup_irq( unsigned int irq_nr )
+{
+ if (++pb1200_cascade_en == 1)
+ {
+ request_irq(AU1000_GPIO_7, &pb1200_cascade_handler,
+ 0, "Pb1200 Cascade", (void *)&pb1200_cascade_handler );
+#ifdef CONFIG_MIPS_PB1200
+ /* We have a problem with CPLD rev3. Enable a workaround */
+ if( ((bcsr->whoami & BCSR_WHOAMI_CPLD)>>4) <= 3)
+ {
+ printk("\nWARNING!!!\n");
+ printk("\nWARNING!!!\n");
+ printk("\nWARNING!!!\n");
+ printk("\nWARNING!!!\n");
+ printk("\nWARNING!!!\n");
+ printk("\nWARNING!!!\n");
+ printk("Pb1200 must be at CPLD rev4. Please have Pb1200\n");
+ printk("updated to latest revision. This software will not\n");
+ printk("work on anything less than CPLD rev4\n");
+ printk("\nWARNING!!!\n");
+ printk("\nWARNING!!!\n");
+ printk("\nWARNING!!!\n");
+ printk("\nWARNING!!!\n");
+ printk("\nWARNING!!!\n");
+ printk("\nWARNING!!!\n");
+ while(1);
+ }
+#endif
+ }
+ pb1200_enable_irq(irq_nr);
+ return 0;
+}
+
+static void pb1200_shutdown_irq( unsigned int irq_nr )
+{
+ pb1200_disable_irq(irq_nr);
+ if (--pb1200_cascade_en == 0)
+ {
+ free_irq(AU1000_GPIO_7,&pb1200_cascade_handler );
+ }
+ return;
+}
+
+static inline void pb1200_mask_and_ack_irq(unsigned int irq_nr)
+{
+ pb1200_disable_irq( irq_nr );
+}
+
+static void pb1200_end_irq(unsigned int irq_nr)
+{
+ if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
+ pb1200_enable_irq(irq_nr);
+ }
+}
+
+static struct hw_interrupt_type external_irq_type =
+{
+#ifdef CONFIG_MIPS_PB1200
+ "Pb1200 Ext",
+#endif
+#ifdef CONFIG_MIPS_DB1200
+ "Db1200 Ext",
+#endif
+ pb1200_startup_irq,
+ pb1200_shutdown_irq,
+ pb1200_enable_irq,
+ pb1200_disable_irq,
+ pb1200_mask_and_ack_irq,
+ pb1200_end_irq,
+ NULL
+};
+
+void _board_init_irq(void)
+{
+ int irq_nr;
+
+ for (irq_nr = PB1200_INT_BEGIN; irq_nr <= PB1200_INT_END; irq_nr++)
+ {
+ irq_desc[irq_nr].handler = &external_irq_type;
+ pb1200_disable_irq(irq_nr);
+ }
+
+ /* GPIO_7 can not be hooked here, so it is hooked upon first
+ request of any source attached to the cascade */
+}
+
diff --git a/arch/mips/au1000/pb1500/irqmap.c b/arch/mips/au1000/pb1500/irqmap.c
index 476e25001681..8cb76c2edb5e 100644
--- a/arch/mips/au1000/pb1500/irqmap.c
+++ b/arch/mips/au1000/pb1500/irqmap.c
@@ -47,6 +47,11 @@
#include <asm/system.h>
#include <asm/mach-au1x00/au1000.h>
+char irq_tab_alchemy[][5] __initdata = {
+ [12] = { -1, INTA, INTX, INTX, INTX}, /* IDSEL 12 - HPT370 */
+ [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot */
+};
+
au1xxx_irq_map_t au1xxx_irq_map[] = {
{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
{ AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
diff --git a/arch/mips/au1000/pb1550/irqmap.c b/arch/mips/au1000/pb1550/irqmap.c
index 889d4949ee76..47c7a1c19f4b 100644
--- a/arch/mips/au1000/pb1550/irqmap.c
+++ b/arch/mips/au1000/pb1550/irqmap.c
@@ -47,6 +47,11 @@
#include <asm/system.h>
#include <asm/mach-au1x00/au1000.h>
+char irq_tab_alchemy[][5] __initdata = {
+ [12] = { -1, INTB, INTC, INTD, INTA}, /* IDSEL 12 - PCI slot 2 (left) */
+ [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot 1 (right) */
+};
+
au1xxx_irq_map_t au1xxx_irq_map[] = {
{ AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 },
{ AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 },
diff --git a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile
index efbeac326815..0dc84417bf49 100644
--- a/arch/mips/boot/Makefile
+++ b/arch/mips/boot/Makefile
@@ -33,6 +33,9 @@ vmlinux.ecoff: $(obj)/elf2ecoff $(VMLINUX)
$(obj)/elf2ecoff: $(obj)/elf2ecoff.c
$(HOSTCC) -o $@ $^
+vmlinux.bin: $(VMLINUX)
+ $(OBJCOPY) -O binary $(strip-flags) $(VMLINUX) $(obj)/vmlinux.bin
+
vmlinux.srec: $(VMLINUX)
$(OBJCOPY) -S -O srec $(strip-flags) $(VMLINUX) $(obj)/vmlinux.srec
@@ -45,5 +48,6 @@ archhelp:
clean-files += addinitrd \
elf2ecoff \
+ vmlinux.bin \
vmlinux.ecoff \
vmlinux.srec
diff --git a/arch/mips/cobalt/Makefile b/arch/mips/cobalt/Makefile
index a5e6554b2326..3b6b7579d1de 100644
--- a/arch/mips/cobalt/Makefile
+++ b/arch/mips/cobalt/Makefile
@@ -2,6 +2,6 @@
# Makefile for the Cobalt micro systems family specific parts of the kernel
#
-obj-y := irq.o int-handler.o reset.o setup.o promcon.o
+obj-y := irq.o int-handler.o reset.o setup.o
EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/cobalt/int-handler.S b/arch/mips/cobalt/int-handler.S
index 1a21dec1b3ca..f92608e8d84f 100644
--- a/arch/mips/cobalt/int-handler.S
+++ b/arch/mips/cobalt/int-handler.S
@@ -18,8 +18,8 @@
SAVE_ALL
CLI
- la ra, ret_from_irq
- move a1, sp
+ PTR_LA ra, ret_from_irq
+ move a0, sp
j cobalt_irq
END(cobalt_handle_int)
diff --git a/arch/mips/cobalt/irq.c b/arch/mips/cobalt/irq.c
index 6d2a81581397..0d90851f925e 100644
--- a/arch/mips/cobalt/irq.c
+++ b/arch/mips/cobalt/irq.c
@@ -10,6 +10,8 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
#include <asm/i8259.h>
#include <asm/irq_cpu.h>
@@ -25,8 +27,8 @@ extern void cobalt_handle_int(void);
* the CPU interrupt lines, and ones that come in on the via chip. The CPU
* mappings are:
*
- * 16, - Software interrupt 0 (unused) IE_SW0
- * 17 - Software interrupt 1 (unused) IE_SW0
+ * 16 - Software interrupt 0 (unused) IE_SW0
+ * 17 - Software interrupt 1 (unused) IE_SW1
* 18 - Galileo chip (timer) IE_IRQ0
* 19 - Tulip 0 + NCR SCSI IE_IRQ1
* 20 - Tulip 1 IE_IRQ2
@@ -42,61 +44,94 @@ extern void cobalt_handle_int(void);
* 15 - IDE1
*/
-asmlinkage void cobalt_irq(struct pt_regs *regs)
+static inline void galileo_irq(struct pt_regs *regs)
{
- unsigned int pending = read_c0_status() & read_c0_cause();
-
- if (pending & CAUSEF_IP2) { /* int 18 */
- unsigned long irq_src = GALILEO_INL(GT_INTRCAUSE_OFS);
-
- /* Check for timer irq ... */
- if (irq_src & GALILEO_T0EXP) {
- /* Clear the int line */
- GALILEO_OUTL(0, GT_INTRCAUSE_OFS);
- do_IRQ(COBALT_TIMER_IRQ, regs);
- }
- return;
- }
+ unsigned int mask, pending, devfn;
- if (pending & CAUSEF_IP6) { /* int 22 */
- int irq = i8259_irq();
+ mask = GALILEO_INL(GT_INTRMASK_OFS);
+ pending = GALILEO_INL(GT_INTRCAUSE_OFS) & mask;
- if (irq >= 0)
- do_IRQ(irq, regs);
- return;
- }
+ if (pending & GALILEO_INTR_T0EXP) {
- if (pending & CAUSEF_IP3) { /* int 19 */
- do_IRQ(COBALT_ETH0_IRQ, regs);
- return;
- }
+ GALILEO_OUTL(~GALILEO_INTR_T0EXP, GT_INTRCAUSE_OFS);
+ do_IRQ(COBALT_GALILEO_IRQ, regs);
- if (pending & CAUSEF_IP4) { /* int 20 */
- do_IRQ(COBALT_ETH1_IRQ, regs);
- return;
- }
+ } else if (pending & GALILEO_INTR_RETRY_CTR) {
- if (pending & CAUSEF_IP5) { /* int 21 */
- do_IRQ(COBALT_SERIAL_IRQ, regs);
- return;
- }
+ devfn = GALILEO_INL(GT_PCI0_CFGADDR_OFS) >> 8;
+ GALILEO_OUTL(~GALILEO_INTR_RETRY_CTR, GT_INTRCAUSE_OFS);
+ printk(KERN_WARNING "Galileo: PCI retry count exceeded (%02x.%u)\n",
+ PCI_SLOT(devfn), PCI_FUNC(devfn));
+
+ } else {
- if (pending & CAUSEF_IP7) { /* int 23 */
- do_IRQ(COBALT_QUBE_SLOT_IRQ, regs);
- return;
+ GALILEO_OUTL(mask & ~pending, GT_INTRMASK_OFS);
+ printk(KERN_WARNING "Galileo: masking unexpected interrupt %08x\n", pending);
}
}
+static inline void via_pic_irq(struct pt_regs *regs)
+{
+ int irq;
+
+ irq = i8259_irq();
+ if (irq >= 0)
+ do_IRQ(irq, regs);
+}
+
+asmlinkage void cobalt_irq(struct pt_regs *regs)
+{
+ unsigned pending;
+
+ pending = read_c0_status() & read_c0_cause();
+
+ if (pending & CAUSEF_IP2) /* COBALT_GALILEO_IRQ (18) */
+
+ galileo_irq(regs);
+
+ else if (pending & CAUSEF_IP6) /* COBALT_VIA_IRQ (22) */
+
+ via_pic_irq(regs);
+
+ else if (pending & CAUSEF_IP3) /* COBALT_ETH0_IRQ (19) */
+
+ do_IRQ(COBALT_CPU_IRQ + 3, regs);
+
+ else if (pending & CAUSEF_IP4) /* COBALT_ETH1_IRQ (20) */
+
+ do_IRQ(COBALT_CPU_IRQ + 4, regs);
+
+ else if (pending & CAUSEF_IP5) /* COBALT_SERIAL_IRQ (21) */
+
+ do_IRQ(COBALT_CPU_IRQ + 5, regs);
+
+ else if (pending & CAUSEF_IP7) /* IRQ 23 */
+
+ do_IRQ(COBALT_CPU_IRQ + 7, regs);
+}
+
+static struct irqaction irq_via = {
+ no_action, 0, { { 0, } }, "cascade", NULL, NULL
+};
+
void __init arch_init_irq(void)
{
+ /*
+ * Mask all Galileo interrupts. The Galileo
+ * handler is set in cobalt_timer_setup()
+ */
+ GALILEO_OUTL(0, GT_INTRMASK_OFS);
+
set_except_vector(0, cobalt_handle_int);
init_i8259_irqs(); /* 0 ... 15 */
- mips_cpu_irq_init(16); /* 16 ... 23 */
+ mips_cpu_irq_init(COBALT_CPU_IRQ); /* 16 ... 23 */
/*
* Mask all cpu interrupts
* (except IE4, we already masked those at VIA level)
*/
change_c0_status(ST0_IM, IE_IRQ4);
+
+ setup_irq(COBALT_VIA_IRQ, &irq_via);
}
diff --git a/arch/mips/cobalt/promcon.c b/arch/mips/cobalt/promcon.c
deleted file mode 100644
index f03df761e9f1..000000000000
--- a/arch/mips/cobalt/promcon.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * PROM console for Cobalt Raq2
- *
- * 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) 1995, 1996, 1997 by Ralf Baechle
- * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv)
- *
- */
-
-#include <linux/init.h>
-#include <linux/console.h>
-#include <linux/kdev_t.h>
-#include <linux/serial_reg.h>
-
-#include <asm/delay.h>
-#include <asm/serial.h>
-#include <asm/io.h>
-
-static unsigned long port = 0xc800000;
-
-static __inline__ void ns16550_cons_put_char(char ch, unsigned long ioaddr)
-{
- char lsr;
-
- do {
- lsr = inb(ioaddr + UART_LSR);
- } while ((lsr & (UART_LSR_TEMT | UART_LSR_THRE)) != (UART_LSR_TEMT | UART_LSR_THRE));
- outb(ch, ioaddr + UART_TX);
-}
-
-static __inline__ char ns16550_cons_get_char(unsigned long ioaddr)
-{
- while ((inb(ioaddr + UART_LSR) & UART_LSR_DR) == 0)
- udelay(1);
- return inb(ioaddr + UART_RX);
-}
-
-void ns16550_console_write(struct console *co, const char *s, unsigned count)
-{
- char lsr, ier;
- unsigned i;
-
- ier = inb(port + UART_IER);
- outb(0x00, port + UART_IER);
- for (i=0; i < count; i++, s++) {
-
- if(*s == '\n')
- ns16550_cons_put_char('\r', port);
- ns16550_cons_put_char(*s, port);
- }
-
- do {
- lsr = inb(port + UART_LSR);
- } while ((lsr & (UART_LSR_TEMT | UART_LSR_THRE)) != (UART_LSR_TEMT | UART_LSR_THRE));
-
- outb(ier, port + UART_IER);
-}
-
-char getDebugChar(void)
-{
- return ns16550_cons_get_char(port);
-}
-
-void putDebugChar(char kgdb_char)
-{
- ns16550_cons_put_char(kgdb_char, port);
-}
-
-static struct console ns16550_console = {
- .name = "prom",
- .setup = NULL,
- .write = ns16550_console_write,
- .flags = CON_PRINTBUFFER,
- .index = -1,
-};
-
-static int __init ns16550_setup_console(void)
-{
- register_console(&ns16550_console);
-
- return 0;
-}
-
-console_initcall(ns16550_setup_console);
diff --git a/arch/mips/cobalt/reset.c b/arch/mips/cobalt/reset.c
index 084c8e59f42c..805a0e88507b 100644
--- a/arch/mips/cobalt/reset.c
+++ b/arch/mips/cobalt/reset.c
@@ -16,48 +16,45 @@
#include <asm/reboot.h>
#include <asm/system.h>
#include <asm/mipsregs.h>
+#include <asm/cobalt/cobalt.h>
-void cobalt_machine_restart(char *command)
+void cobalt_machine_halt(void)
{
- *(volatile char *)0xbc000000 = 0x0f;
+ int state, last, diff;
+ unsigned long mark;
/*
- * Ouch, we're still alive ... This time we take the silver bullet ...
- * ... and find that we leave the hardware in a state in which the
- * kernel in the flush locks up somewhen during of after the PCI
- * detection stuff.
+ * turn off bar on Qube, flash power off LED on RaQ (0.5Hz)
+ *
+ * restart if ENTER and SELECT are pressed
*/
- set_c0_status(ST0_BEV | ST0_ERL);
- change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
- flush_cache_all();
- write_c0_wired(0);
- __asm__ __volatile__(
- "jr\t%0"
- :
- : "r" (0xbfc00000));
-}
-extern int led_state;
-#define kLED 0xBC000000
-#define LEDSet(x) (*(volatile unsigned char *) kLED) = (( unsigned char)x)
+ last = COBALT_KEY_PORT;
-void cobalt_machine_halt(void)
-{
- int mark;
+ for (state = 0;;) {
+
+ state ^= COBALT_LED_POWER_OFF;
+ COBALT_LED_PORT = state;
+
+ diff = COBALT_KEY_PORT ^ last;
+ last ^= diff;
- /* Blink our cute? little LED (number 3)... */
- while (1) {
- led_state = led_state | ( 1 << 3 );
- LEDSet(led_state);
- mark = jiffies;
- while (jiffies<(mark+HZ));
- led_state = led_state & ~( 1 << 3 );
- LEDSet(led_state);
- mark = jiffies;
- while (jiffies<(mark+HZ));
+ if((diff & (COBALT_KEY_ENTER | COBALT_KEY_SELECT)) && !(~last & (COBALT_KEY_ENTER | COBALT_KEY_SELECT)))
+ COBALT_LED_PORT = COBALT_LED_RESET;
+
+ for (mark = jiffies; jiffies - mark < HZ;)
+ ;
}
}
+void cobalt_machine_restart(char *command)
+{
+ COBALT_LED_PORT = COBALT_LED_RESET;
+
+ /* we should never get here */
+ cobalt_machine_halt();
+}
+
/*
* This triggers the luser mode device driver for the power switch ;-)
*/
diff --git a/arch/mips/cobalt/setup.c b/arch/mips/cobalt/setup.c
index 6b4737e425ed..d358a118fa31 100644
--- a/arch/mips/cobalt/setup.c
+++ b/arch/mips/cobalt/setup.c
@@ -13,6 +13,8 @@
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
#include <asm/bootinfo.h>
#include <asm/time.h>
@@ -21,6 +23,7 @@
#include <asm/processor.h>
#include <asm/reboot.h>
#include <asm/gt64120.h>
+#include <asm/serial.h>
#include <asm/cobalt/cobalt.h>
@@ -30,45 +33,44 @@ extern void cobalt_machine_power_off(void);
int cobalt_board_id;
-static char my_cmdline[CL_SIZE] = {
- "console=ttyS0,115200 "
-#ifdef CONFIG_IP_PNP
- "ip=on "
-#endif
-#ifdef CONFIG_ROOT_NFS
- "root=/dev/nfs "
-#else
- "root=/dev/hda1 "
-#endif
- };
-
const char *get_system_type(void)
{
+ switch (cobalt_board_id) {
+ case COBALT_BRD_ID_QUBE1:
+ return "Cobalt Qube";
+ case COBALT_BRD_ID_RAQ1:
+ return "Cobalt RaQ";
+ case COBALT_BRD_ID_QUBE2:
+ return "Cobalt Qube2";
+ case COBALT_BRD_ID_RAQ2:
+ return "Cobalt RaQ2";
+ }
return "MIPS Cobalt";
}
static void __init cobalt_timer_setup(struct irqaction *irq)
{
- /* Load timer value for 150 Hz */
- GALILEO_OUTL(500000, GT_TC0_OFS);
+ /* Load timer value for 1KHz (TCLK is 50MHz) */
+ GALILEO_OUTL(50*1000*1000 / 1000, GT_TC0_OFS);
- /* Register our timer interrupt */
- setup_irq(COBALT_TIMER_IRQ, irq);
+ /* Enable timer */
+ GALILEO_OUTL(GALILEO_ENTC0 | GALILEO_SELTC0, GT_TC_CONTROL_OFS);
- /* Enable timer ints */
- GALILEO_OUTL((GALILEO_ENTC0 | GALILEO_SELTC0), GT_TC_CONTROL_OFS);
- /* Unmask timer int */
- GALILEO_OUTL(0x100, GT_INTRMASK_OFS);
+ /* Register interrupt */
+ setup_irq(COBALT_GALILEO_IRQ, irq);
+
+ /* Enable interrupt */
+ GALILEO_OUTL(GALILEO_INTR_T0EXP | GALILEO_INL(GT_INTRMASK_OFS), GT_INTRMASK_OFS);
}
extern struct pci_ops gt64111_pci_ops;
static struct resource cobalt_mem_resource = {
- "GT64111 PCI MEM", GT64111_IO_BASE, 0xffffffffUL, IORESOURCE_MEM
+ "PCI memory", GT64111_MEM_BASE, GT64111_MEM_END, IORESOURCE_MEM
};
static struct resource cobalt_io_resource = {
- "GT64111 IO MEM", 0x00001000UL, 0x0fffffffUL, IORESOURCE_IO
+ "PCI I/O", 0x1000, 0xffff, IORESOURCE_IO
};
static struct resource cobalt_io_resources[] = {
@@ -86,11 +88,12 @@ static struct pci_controller cobalt_pci_controller = {
.mem_resource = &cobalt_mem_resource,
.mem_offset = 0,
.io_resource = &cobalt_io_resource,
- .io_offset = 0x00001000UL - GT64111_IO_BASE
+ .io_offset = 0 - GT64111_IO_BASE
};
-static void __init cobalt_setup(void)
+void __init plat_setup(void)
{
+ static struct uart_port uart;
unsigned int devfn = PCI_DEVFN(COBALT_PCICONF_VIA, 0);
int i;
@@ -100,7 +103,10 @@ static void __init cobalt_setup(void)
board_timer_setup = cobalt_timer_setup;
- set_io_port_base(KSEG1ADDR(GT64111_IO_BASE));
+ set_io_port_base(CKSEG1ADDR(GT64111_IO_BASE));
+
+ /* I/O port resource must include UART and LCD/buttons */
+ ioport_resource.end = 0x0fffffff;
/*
* This is a prom style console. We just poke at the
@@ -120,27 +126,61 @@ static void __init cobalt_setup(void)
cobalt_board_id >>= ((VIA_COBALT_BRD_ID_REG & 3) * 8);
cobalt_board_id = VIA_COBALT_BRD_REG_to_ID(cobalt_board_id);
+ printk("Cobalt board ID: %d\n", cobalt_board_id);
+
#ifdef CONFIG_PCI
register_pci_controller(&cobalt_pci_controller);
#endif
-}
-early_initcall(cobalt_setup);
+#ifdef CONFIG_SERIAL_8250
+ if (cobalt_board_id > COBALT_BRD_ID_RAQ1) {
+
+ uart.line = 0;
+ uart.type = PORT_UNKNOWN;
+ uart.uartclk = 18432000;
+ uart.irq = COBALT_SERIAL_IRQ;
+ uart.flags = STD_COM_FLAGS;
+ uart.iobase = 0xc800000;
+ uart.iotype = UPIO_PORT;
+
+ early_serial_setup(&uart);
+ }
+#endif
+}
/*
* Prom init. We read our one and only communication with the firmware.
- * Grab the amount of installed memory
+ * Grab the amount of installed memory.
+ * Better boot loaders (CoLo) pass a command line too :-)
*/
void __init prom_init(void)
{
- int argc = fw_arg0;
-
- strcpy(arcs_cmdline, my_cmdline);
+ int narg, indx, posn, nchr;
+ unsigned long memsz;
+ char **argv;
mips_machgroup = MACH_GROUP_COBALT;
- add_memory_region(0x0, argc & 0x7fffffff, BOOT_MEM_RAM);
+ memsz = fw_arg0 & 0x7fff0000;
+ narg = fw_arg0 & 0x0000ffff;
+
+ if (narg) {
+ arcs_cmdline[0] = '\0';
+ argv = (char **) fw_arg1;
+ posn = 0;
+ for (indx = 1; indx < narg; ++indx) {
+ nchr = strlen(argv[indx]);
+ if (posn + 1 + nchr + 1 > sizeof(arcs_cmdline))
+ break;
+ if (posn)
+ arcs_cmdline[posn++] = ' ';
+ strcpy(arcs_cmdline + posn, argv[indx]);
+ posn += nchr;
+ }
+ }
+
+ add_memory_region(0x0, memsz, BOOT_MEM_RAM);
}
unsigned long __init prom_free_prom_memory(void)
diff --git a/arch/mips/configs/atlas_defconfig b/arch/mips/configs/atlas_defconfig
index 3120a02b8670..132ec3dac63f 100644
--- a/arch/mips/configs/atlas_defconfig
+++ b/arch/mips/configs/atlas_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:00 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:13 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,42 +59,72 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
CONFIG_MIPS_ATLAS=y
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
CONFIG_MIPS_BONITO64=y
CONFIG_MIPS_MSC=y
-# CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_IRQ_CPU=y
CONFIG_MIPS_BOARDS_GEN=y
CONFIG_MIPS_GT64120=y
CONFIG_SWAP_IO_SPACE=y
@@ -101,8 +134,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS64 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
@@ -118,15 +153,46 @@ CONFIG_CPU_MIPS32=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_SYS_HAS_CPU_MIPS32_R2=y
+CONFIG_SYS_HAS_CPU_MIPS64_R1=y
+CONFIG_SYS_HAS_CPU_NEVADA=y
+CONFIG_SYS_HAS_CPU_RM7000=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=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_64KB is not set
+CONFIG_BOARD_SCACHE=y
+CONFIG_RM7000_CPU_SCACHE=y
CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
# CONFIG_64BIT_PHYS_ADDR is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -135,7 +201,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -144,10 +209,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -160,199 +221,7 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=y
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-CONFIG_BLK_DEV_UMEM=m
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_BLK_DEV_NBD=m
-# CONFIG_BLK_DEV_SX8 is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_ATA_OVER_ETH=m
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-CONFIG_BLK_DEV_IDECD=y
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-# CONFIG_BLK_DEV_IDEPCI is not set
-# CONFIG_IDE_ARM is not set
-# CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-CONFIG_SCSI=y
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=m
-CONFIG_CHR_DEV_OSST=m
-CONFIG_BLK_DEV_SR=m
-CONFIG_BLK_DEV_SR_VENDOR=y
-CONFIG_CHR_DEV_SG=m
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_LOGGING=y
-
-#
-# SCSI Transport Attributes
-#
-CONFIG_SCSI_SPI_ATTRS=y
-CONFIG_SCSI_FC_ATTRS=m
-CONFIG_SCSI_ISCSI_ATTRS=m
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_3W_9XXX is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_MEGARAID_NEWGEN is not set
-# CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-CONFIG_SCSI_SYM53C8XX_2=y
-CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
-CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
-CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
-# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=y
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_DC395x is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
-CONFIG_MD_LINEAR=m
-CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_RAID10=m
-CONFIG_MD_RAID5=m
-CONFIG_MD_RAID6=m
-CONFIG_MD_MULTIPATH=m
-CONFIG_MD_FAULTY=m
-CONFIG_BLK_DEV_DM=m
-CONFIG_DM_CRYPT=m
-CONFIG_DM_SNAPSHOT=m
-CONFIG_DM_MIRROR=m
-CONFIG_DM_ZERO=m
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-
-#
-# Networking support
+# Networking
#
CONFIG_NET=y
@@ -361,15 +230,20 @@ CONFIG_NET=y
#
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
CONFIG_NET_KEY=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_FWMARK=y
CONFIG_IP_ROUTE_MULTIPATH=y
+# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
@@ -387,8 +261,10 @@ CONFIG_INET_AH=m
CONFIG_INET_ESP=m
CONFIG_INET_IPCOMP=m
CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-CONFIG_IP_TCPDIAG_IPV6=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
#
# IP: Virtual Server Configuration
@@ -433,6 +309,9 @@ CONFIG_IPV6_TUNNEL=m
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
CONFIG_BRIDGE_NETFILTER=y
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
#
# IP: Netfilter Configuration
@@ -440,11 +319,15 @@ CONFIG_BRIDGE_NETFILTER=y
CONFIG_IP_NF_CONNTRACK=m
CONFIG_IP_NF_CT_ACCT=y
CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CONNTRACK_EVENTS=y
+CONFIG_IP_NF_CONNTRACK_NETLINK=m
CONFIG_IP_NF_CT_PROTO_SCTP=m
CONFIG_IP_NF_FTP=m
CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_NETBIOS_NS is not set
CONFIG_IP_NF_TFTP=m
CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_PPTP=m
CONFIG_IP_NF_QUEUE=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_LIMIT=m
@@ -469,9 +352,12 @@ CONFIG_IP_NF_MATCH_PHYSDEV=m
CONFIG_IP_NF_MATCH_ADDRTYPE=m
CONFIG_IP_NF_MATCH_REALM=m
CONFIG_IP_NF_MATCH_SCTP=m
+CONFIG_IP_NF_MATCH_DCCP=m
CONFIG_IP_NF_MATCH_COMMENT=m
CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_CONNBYTES=m
CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_MATCH_STRING=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_TARGET_LOG=m
@@ -488,12 +374,14 @@ CONFIG_IP_NF_NAT_IRC=m
CONFIG_IP_NF_NAT_FTP=m
CONFIG_IP_NF_NAT_TFTP=m
CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_NAT_PPTP=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_TOS=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_DSCP=m
CONFIG_IP_NF_TARGET_MARK=m
CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_TARGET_CONNMARK=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_RAW=m
@@ -503,7 +391,7 @@ CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
#
-# IPv6: Netfilter Configuration
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
#
CONFIG_IP6_NF_QUEUE=m
CONFIG_IP6_NF_IPTABLES=m
@@ -523,8 +411,10 @@ CONFIG_IP6_NF_MATCH_EUI64=m
CONFIG_IP6_NF_MATCH_PHYSDEV=m
CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_TARGET_REJECT=m
CONFIG_IP6_NF_MANGLE=m
CONFIG_IP6_NF_TARGET_MARK=m
+CONFIG_IP6_NF_TARGET_HL=m
CONFIG_IP6_NF_RAW=m
#
@@ -550,8 +440,11 @@ CONFIG_BRIDGE_EBT_REDIRECT=m
CONFIG_BRIDGE_EBT_SNAT=m
CONFIG_BRIDGE_EBT_LOG=m
CONFIG_BRIDGE_EBT_ULOG=m
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
#
# SCTP Configuration (EXPERIMENTAL)
@@ -579,10 +472,6 @@ CONFIG_IPDDP_DECAP=y
CONFIG_NET_DIVERT=y
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_CLK_JIFFIES=y
# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
@@ -602,6 +491,7 @@ CONFIG_NET_SCH_INGRESS=m
CONFIG_NET_QOS=y
CONFIG_NET_ESTIMATOR=y
CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
CONFIG_NET_CLS_TCINDEX=m
CONFIG_NET_CLS_ROUTE4=m
CONFIG_NET_CLS_ROUTE=y
@@ -612,6 +502,7 @@ CONFIG_NET_CLS_IND=y
# CONFIG_CLS_U32_MARK is not set
CONFIG_NET_CLS_RSVP=m
CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_EMATCH is not set
# CONFIG_NET_CLS_ACT is not set
CONFIG_NET_CLS_POLICE=y
@@ -619,17 +510,222 @@ CONFIG_NET_CLS_POLICE=y
# Network testing
#
# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# 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=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_IDEPCI is not set
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=y
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+CONFIG_SCSI_SYM53C8XX_2=y
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+CONFIG_SCSI_QLA2XXX=y
+# CONFIG_SCSI_QLA21XX is not set
+# CONFIG_SCSI_QLA22XX is not set
+# CONFIG_SCSI_QLA2300 is not set
+# CONFIG_SCSI_QLA2322 is not set
+# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID5=m
+CONFIG_MD_RAID6=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
CONFIG_NETDEVICES=y
CONFIG_DUMMY=m
CONFIG_BONDING=m
CONFIG_EQUALIZER=m
CONFIG_TUN=m
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -637,6 +733,21 @@ CONFIG_TUN=m
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -681,13 +792,17 @@ CONFIG_LAN_SAA9730=y
# 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_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -700,6 +815,8 @@ CONFIG_LAN_SAA9730=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# Wan interfaces
@@ -712,6 +829,8 @@ CONFIG_LAN_SAA9730=y
# CONFIG_NET_FC is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -741,19 +860,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-CONFIG_SERIO_RAW=y
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -766,6 +872,17 @@ CONFIG_MOUSE_SERIAL=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=y
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -786,6 +903,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
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
@@ -812,6 +930,11 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -822,10 +945,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -845,7 +978,6 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -855,13 +987,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -879,10 +1007,15 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -903,12 +1036,14 @@ CONFIG_JFS_SECURITY=y
# CONFIG_JFS_STATISTICS is not set
CONFIG_FS_POSIX_ACL=y
CONFIG_XFS_FS=m
-# CONFIG_XFS_RT is not set
-CONFIG_XFS_QUOTA=y
+CONFIG_XFS_EXPORT=y
+CONFIG_XFS_QUOTA=m
CONFIG_XFS_SECURITY=y
CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
CONFIG_MINIX_FS=m
CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
CONFIG_QUOTA=y
# CONFIG_QFMT_V1 is not set
CONFIG_QFMT_V2=y
@@ -916,6 +1051,7 @@ CONFIG_QUOTACTL=y
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=y
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -943,12 +1079,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -974,16 +1108,19 @@ CONFIG_UFS_FS=m
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
CONFIG_NFSD=y
CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
# CONFIG_NFSD_V4 is not set
# CONFIG_NFSD_TCP is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -992,6 +1129,7 @@ CONFIG_SUNRPC=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
@@ -1051,7 +1189,9 @@ CONFIG_NLS_UTF8=m
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -1073,6 +1213,7 @@ CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_DES=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_TWOFISH=m
@@ -1097,9 +1238,12 @@ CONFIG_CRYPTO_CRC32C=m
# Library routines
#
# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=m
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=m
CONFIG_ZLIB_DEFLATE=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig
new file mode 100644
index 000000000000..25e8a08e68be
--- /dev/null
+++ b/arch/mips/configs/bigsur_defconfig
@@ -0,0 +1,881 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:17 2005
+#
+CONFIG_MIPS=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+# CONFIG_CPUSETS is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Machine selection
+#
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+CONFIG_SIBYTE_BIGSUR=y
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+CONFIG_SIBYTE_BCM1x80=y
+CONFIG_SIBYTE_SB1xxx_SOC=y
+# CONFIG_CPU_SB1_PASS_1 is not set
+# CONFIG_CPU_SB1_PASS_2_1250 is not set
+# CONFIG_CPU_SB1_PASS_2_2 is not set
+# CONFIG_CPU_SB1_PASS_4 is not set
+# CONFIG_CPU_SB1_PASS_2_112x is not set
+# CONFIG_CPU_SB1_PASS_3 is not set
+# CONFIG_SIMULATION is not set
+# CONFIG_CONFIG_SB1_CEX_ALWAYS_FATAL is not set
+# CONFIG_CONFIG_SB1_CERR_STALL is not set
+CONFIG_SIBYTE_CFE=y
+# CONFIG_SIBYTE_CFE_CONSOLE is not set
+# CONFIG_SIBYTE_BUS_WATCHER is not set
+# CONFIG_SIBYTE_SB1250_PROF is not set
+# CONFIG_SIBYTE_TBPROF is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DMA_COHERENT=y
+CONFIG_CPU_BIG_ENDIAN=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_BOOT_ELF32=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# 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_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=y
+CONFIG_SYS_HAS_CPU_SB1=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=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+# CONFIG_SIBYTE_DMA_PAGEOPS is not set
+# CONFIG_MIPS_MT is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=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_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SMP=y
+CONFIG_NR_CPUS=4
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_PREEMPT_BKL is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_DEBUG=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_BUILD_ELF64=y
+CONFIG_MIPS32_COMPAT=y
+CONFIG_COMPAT=y
+CONFIG_MIPS32_O32=y
+# CONFIG_MIPS32_N32 is not set
+CONFIG_BINFMT_ELF32=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_IDETAPE=y
+CONFIG_BLK_DEV_IDEFLOPPY=y
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_IDEPCI is not set
+# CONFIG_BLK_DEV_IDE_SWARM is not set
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+CONFIG_NET_SB1250_MAC=y
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# 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_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_ROCKETPORT is not set
+# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+# CONFIG_SYNCLINKMP is not set
+# CONFIG_N_HDLC is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_STALDRV is not set
+CONFIG_SIBYTE_SB1250_DUART=y
+CONFIG_SIBYTE_SB1250_DUART_CONSOLE=y
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+CONFIG_I2C_ALGO_SIBYTE=y
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+CONFIG_I2C_SIBYTE=y
+# CONFIG_SCx200_ACB is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_SENSORS_DS1337=y
+CONFIG_SENSORS_DS1374=y
+CONFIG_SENSORS_EEPROM=y
+CONFIG_SENSORS_PCF8574=y
+CONFIG_SENSORS_PCA9539=y
+CONFIG_SENSORS_PCF8591=y
+CONFIG_SENSORS_RTC8564=y
+CONFIG_SENSORS_MAX6875=y
+CONFIG_I2C_DEBUG_CORE=y
+CONFIG_I2C_DEBUG_ALGO=y
+CONFIG_I2C_DEBUG_BUS=y
+CONFIG_I2C_DEBUG_CHIP=y
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB is not set
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# 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_SYSFS=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_KGDB is not set
+# CONFIG_SB1XXX_CORELIS is not set
+# CONFIG_RUNTIME_DEBUG is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_TEA=m
+# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig
index 158e7165f4e3..bfbaa08c47cb 100644
--- a/arch/mips/configs/capcella_defconfig
+++ b/arch/mips/configs/capcella_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:00 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:20 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,57 +59,86 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-CONFIG_MACH_VR41XX=y
-# CONFIG_NEC_CMBVR4133 is not set
-# CONFIG_CASIO_E55 is not set
-# CONFIG_IBM_WORKPAD is not set
-# CONFIG_TANBAC_TB0226 is not set
-# CONFIG_TANBAC_TB0229 is not set
-# CONFIG_VICTOR_MPC30X is not set
-CONFIG_ZAO_CAPCELLA=y
-CONFIG_PCI_VR41XX=y
-CONFIG_VRC4173=y
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+CONFIG_MACH_VR41XX=y
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_NEC_CMBVR4133 is not set
+# CONFIG_CASIO_E55 is not set
+# CONFIG_IBM_WORKPAD is not set
+# CONFIG_TANBAC_TB022X is not set
+# CONFIG_VICTOR_MPC30X is not set
+CONFIG_ZAO_CAPCELLA=y
+CONFIG_PCI_VR41XX=y
+# CONFIG_VRC4173 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# 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=y
@@ -122,12 +154,36 @@ CONFIG_CPU_VR41XX=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_VR41XX=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=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_64KB is not set
+# CONFIG_MIPS_MT is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -136,7 +192,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -145,10 +200,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -161,6 +212,81 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+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 is not set
+# CONFIG_NET_IPGRE is not set
+# 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_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -169,7 +295,12 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
@@ -188,7 +319,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -199,11 +329,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+# CONFIG_CDROM_PKTCDVD is not set
#
# IO Schedulers
@@ -244,6 +371,7 @@ CONFIG_IDE_GENERIC=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
#
@@ -254,6 +382,7 @@ CONFIG_IDE_GENERIC=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -266,79 +395,13 @@ CONFIG_IDE_GENERIC=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-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 is not set
-# CONFIG_NET_IPGRE is not set
-# 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_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
+# Network device support
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -346,10 +409,25 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
+CONFIG_MII=y
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
# CONFIG_NET_VENDOR_3COM is not set
@@ -359,7 +437,30 @@ CONFIG_NET_ETHERNET=y
#
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
-# CONFIG_NET_PCI 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_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS 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=y
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET 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_LAN_SAA9730 is not set
#
# Ethernet (1000 Mbit)
@@ -371,12 +472,17 @@ CONFIG_NET_ETHERNET=y
# 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_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -389,6 +495,8 @@ CONFIG_NET_ETHERNET=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# Wan interfaces
@@ -400,6 +508,8 @@ CONFIG_NET_ETHERNET=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -419,29 +529,13 @@ CONFIG_INPUT=y
#
# 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_MOUSEDEV is not set
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_TSDEV is not set
# CONFIG_INPUT_EVDEV is not set
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=m
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -451,6 +545,12 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -461,16 +561,16 @@ CONFIG_HW_CONSOLE=y
#
# Serial drivers
#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250 is not set
#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_VR41XX=y
+CONFIG_SERIAL_VR41XX_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -483,19 +583,7 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# Watchdog Cards
#
-CONFIG_WATCHDOG=y
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-
-#
-# Watchdog Device Drivers
-#
-# CONFIG_SOFT_WATCHDOG is not set
-
-#
-# PCI-based Watchdog Cards
-#
-# CONFIG_PCIPCWATCHDOG is not set
-# CONFIG_WDTPCI is not set
+# CONFIG_WATCHDOG is not set
# CONFIG_RTC is not set
# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
@@ -506,9 +594,15 @@ CONFIG_WATCHDOG=y
# Ftape, the floppy tape device driver
#
# CONFIG_DRM is not set
+CONFIG_GPIO_VR41XX=y
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -519,10 +613,20 @@ CONFIG_WATCHDOG=y
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -542,7 +646,6 @@ CONFIG_WATCHDOG=y
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -552,13 +655,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -576,21 +675,29 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=y
CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -611,12 +718,10 @@ CONFIG_AUTOFS4_FS=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -648,6 +753,7 @@ CONFIG_NFSD=y
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -656,6 +762,7 @@ CONFIG_SUNRPC=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
@@ -676,9 +783,11 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
+CONFIG_CMDLINE="mem=32M console=ttyVR0,38400"
#
# Security options
@@ -690,7 +799,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -700,7 +833,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
+CONFIG_CRC16=m
+CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig
index 4302c6f914f5..4b4d1ddb3d42 100644
--- a/arch/mips/configs/cobalt_defconfig
+++ b/arch/mips/configs/cobalt_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:00 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:23 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -50,41 +53,69 @@ CONFIG_CC_ALIGN_JUMPS=0
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
CONFIG_MIPS_COBALT=y
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
CONFIG_I8259=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_MIPS_GT64111=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
@@ -92,8 +123,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# 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
@@ -109,14 +142,38 @@ CONFIG_CPU_NEVADA=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_NEVADA=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=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_64KB is not set
+# CONFIG_MIPS_MT is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -125,7 +182,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -134,10 +190,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -150,6 +202,77 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=y
+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_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=y
+CONFIG_IEEE80211_CRYPT_CCMP=y
+CONFIG_IEEE80211_CRYPT_TKIP=y
+
+#
# Device Drivers
#
@@ -161,6 +284,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -177,7 +305,6 @@ CONFIG_FW_LOADER=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -189,7 +316,6 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=y
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -234,6 +360,7 @@ CONFIG_IDE_GENERIC=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=y
# CONFIG_SCSI is not set
#
@@ -244,6 +371,7 @@ CONFIG_IDE_GENERIC=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -256,75 +384,13 @@ CONFIG_IDE_GENERIC=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# 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_TUNNEL=y
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=y
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
+# Network device support
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -332,6 +398,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -357,12 +438,16 @@ CONFIG_NET_ETHERNET=y
# 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_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -375,6 +460,8 @@ CONFIG_NET_ETHERNET=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=y
#
# Wan interfaces
@@ -386,6 +473,8 @@ CONFIG_NET_ETHERNET=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -415,19 +504,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=y
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -437,6 +513,17 @@ CONFIG_SERIO_RAW=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=y
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -457,6 +544,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
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
@@ -483,6 +571,11 @@ CONFIG_COBALT_LCD=y
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -493,10 +586,20 @@ CONFIG_COBALT_LCD=y
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -516,7 +619,6 @@ CONFIG_COBALT_LCD=y
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -526,13 +628,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -550,12 +648,17 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
CONFIG_FS_MBCACHE=y
@@ -565,10 +668,12 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=y
#
# CD-ROM/DVD Filesystems
@@ -589,12 +694,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=y
#
# Miscellaneous filesystems
@@ -622,7 +725,7 @@ CONFIG_NFS_FS=y
# CONFIG_NFS_DIRECTIO is not set
# CONFIG_NFSD is not set
CONFIG_LOCKD=y
-# CONFIG_EXPORTFS is not set
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -631,6 +734,7 @@ CONFIG_SUNRPC=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
@@ -651,7 +755,9 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -665,7 +771,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -675,7 +805,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CRC16=y
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig
index 962fc14b58c2..6501144ec612 100644
--- a/arch/mips/configs/db1000_defconfig
+++ b/arch/mips/configs/db1000_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:01 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:26 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,63 +59,79 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+CONFIG_MIPS_DB1000=y
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-CONFIG_SOC_AU1X00=y
-CONFIG_SOC_AU1000=y
-# CONFIG_SOC_AU1100 is not set
-# CONFIG_SOC_AU1500 is not set
-# CONFIG_SOC_AU1550 is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-CONFIG_MIPS_DB1000=y
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_MIRAGE is not set
-# CONFIG_MIPS_XXS1500 is not set
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SOC_AU1000=y
+CONFIG_SOC_AU1X00=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS64 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
@@ -128,15 +147,39 @@ CONFIG_CPU_MIPS32=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 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
+
+#
+# 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_64KB is not set
CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
CONFIG_64BIT_PHYS_ADDR=y
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -152,6 +195,8 @@ CONFIG_MMU=y
CONFIG_PCCARD=m
# CONFIG_PCMCIA_DEBUG is not set
CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
#
# PC-card bridges
@@ -169,6 +214,100 @@ CONFIG_PCMCIA=m
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
CONFIG_TRAD_SIGNALS=y
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+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 is not set
+# CONFIG_NET_IPGRE is not set
+# 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_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_PPTP=m
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
#
# Device Drivers
@@ -179,12 +318,86 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
#
-# CONFIG_MTD is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_AMDSTD_RETRY=0
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_ALCHEMY=y
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD 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
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
#
# Parallel port support
@@ -198,14 +411,12 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -228,6 +439,7 @@ CONFIG_ATA_OVER_ETH=m
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
# CONFIG_SCSI is not set
#
@@ -238,6 +450,7 @@ CONFIG_ATA_OVER_ETH=m
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -248,94 +461,28 @@ CONFIG_ATA_OVER_ETH=m
#
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-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 is not set
-# CONFIG_NET_IPGRE is not set
-# 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_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# IP: Netfilter Configuration
+# Network device support
#
-# CONFIG_IP_NF_CONNTRACK is not set
-CONFIG_IP_NF_CONNTRACK_MARK=y
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
#
-# QoS and/or fair queueing
+# PHY device support
#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
#
-# Network testing
+# MII PHY device drivers
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
#
# Ethernet (10 or 100Mbit)
@@ -389,6 +536,8 @@ CONFIG_PPPOE=m
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -418,18 +567,6 @@ CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -439,6 +576,16 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -473,14 +620,14 @@ CONFIG_LEGACY_PTY_COUNT=256
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
-CONFIG_RTC=y
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
#
# PCMCIA character devices
@@ -489,6 +636,10 @@ CONFIG_SYNCLINK_CS=m
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -499,10 +650,20 @@ CONFIG_SYNCLINK_CS=m
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -522,7 +683,6 @@ CONFIG_SYNCLINK_CS=m
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -532,12 +692,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -552,7 +709,10 @@ CONFIG_DUMMY_CONSOLE=y
#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
#
# File systems
@@ -561,6 +721,7 @@ CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
@@ -579,10 +740,12 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -603,13 +766,10 @@ CONFIG_AUTOFS4_FS=m
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -621,6 +781,8 @@ CONFIG_RAMFS=y
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
CONFIG_CRAMFS=m
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
@@ -641,6 +803,7 @@ CONFIG_NFSD=m
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -650,6 +813,7 @@ CONFIG_SMB_FS=m
# 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
@@ -709,7 +873,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -725,26 +891,27 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
CONFIG_CRYPTO=y
CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=y
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-CONFIG_CRYPTO_TWOFISH=y
-# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
-# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
# CONFIG_CRYPTO_TEST is not set
@@ -756,9 +923,8 @@ CONFIG_CRYPTO_CRC32C=m
# Library routines
#
CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig
index 6a528d479d70..b8cd2cd923dd 100644
--- a/arch/mips/configs/db1100_defconfig
+++ b/arch/mips/configs/db1100_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:01 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:29 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,63 +59,79 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+CONFIG_MIPS_DB1100=y
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-CONFIG_SOC_AU1X00=y
-# CONFIG_SOC_AU1000 is not set
-CONFIG_SOC_AU1100=y
-# CONFIG_SOC_AU1500 is not set
-# CONFIG_SOC_AU1550 is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_DB1000 is not set
-CONFIG_MIPS_DB1100=y
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_MIRAGE is not set
-# CONFIG_MIPS_XXS1500 is not set
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SOC_AU1100=y
+CONFIG_SOC_AU1X00=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS64 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
@@ -128,15 +147,39 @@ CONFIG_CPU_MIPS32=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 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
+
+#
+# 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_64KB is not set
CONFIG_CPU_HAS_PREFETCH=y
-# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_MIPS_MT is not set
+CONFIG_64BIT_PHYS_ADDR=y
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -147,15 +190,7 @@ CONFIG_MMU=y
#
# PCCARD (PCMCIA/CardBus) support
#
-CONFIG_PCCARD=m
-# CONFIG_PCMCIA_DEBUG is not set
-CONFIG_PCMCIA=m
-
-#
-# PC-card bridges
-#
-# CONFIG_TCIC is not set
-# CONFIG_PCMCIA_AU1X00 is not set
+# CONFIG_PCCARD is not set
#
# PCI Hotplug Support
@@ -167,6 +202,100 @@ CONFIG_PCMCIA=m
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
CONFIG_TRAD_SIGNALS=y
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+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 is not set
+# CONFIG_NET_IPGRE is not set
+# 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_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_PPTP=m
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
#
# Device Drivers
@@ -180,9 +309,83 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
+
+#
# Memory Technology Devices (MTD)
#
-# CONFIG_MTD is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_AMDSTD_RETRY=0
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_ALCHEMY=y
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD 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
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
#
# Parallel port support
@@ -196,14 +399,12 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -226,6 +427,7 @@ CONFIG_ATA_OVER_ETH=m
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
# CONFIG_SCSI is not set
#
@@ -236,6 +438,7 @@ CONFIG_ATA_OVER_ETH=m
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -246,101 +449,35 @@ CONFIG_ATA_OVER_ETH=m
#
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-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 is not set
-# CONFIG_NET_IPGRE is not set
-# 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_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# IP: Netfilter Configuration
+# Network device support
#
-# CONFIG_IP_NF_CONNTRACK is not set
-CONFIG_IP_NF_CONNTRACK_MARK=y
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
#
-# QoS and/or fair queueing
+# PHY device support
#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
#
-# Network testing
+# MII PHY device drivers
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
CONFIG_MII=m
-# CONFIG_MIPS_AU1X00_ENET is not set
+CONFIG_MIPS_AU1X00_ENET=y
#
# Ethernet (1000 Mbit)
@@ -360,19 +497,6 @@ CONFIG_MII=m
# CONFIG_NET_RADIO is not set
#
-# PCMCIA network device support
-#
-CONFIG_NET_PCMCIA=y
-CONFIG_PCMCIA_3C589=m
-CONFIG_PCMCIA_3C574=m
-CONFIG_PCMCIA_FMVJ18X=m
-CONFIG_PCMCIA_PCNET=m
-CONFIG_PCMCIA_NMCLAN=m
-CONFIG_PCMCIA_SMC91C92=m
-CONFIG_PCMCIA_XIRC2PS=m
-CONFIG_PCMCIA_AXNET=m
-
-#
# Wan interfaces
#
# CONFIG_WAN is not set
@@ -387,6 +511,8 @@ CONFIG_PPPOE=m
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -416,18 +542,6 @@ CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-CONFIG_SERIO_LIBPS2=m
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -437,6 +551,16 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=m
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -454,7 +578,10 @@ CONFIG_HW_CONSOLE=y
#
# Non-8250 serial port support
#
-# CONFIG_SERIAL_AU1X00 is not set
+CONFIG_SERIAL_AU1X00=y
+CONFIG_SERIAL_AU1X00_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -468,20 +595,19 @@ CONFIG_LEGACY_PTY_COUNT=256
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
-CONFIG_RTC=y
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
#
-# PCMCIA character devices
+# TPM devices
#
-CONFIG_SYNCLINK_CS=m
-# CONFIG_RAW_DRIVER is not set
#
# I2C support
@@ -494,10 +620,20 @@ CONFIG_SYNCLINK_CS=m
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -510,13 +646,43 @@ CONFIG_SYNCLINK_CS=m
#
# Graphics support
#
-# CONFIG_FB is not set
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+CONFIG_FB_AU1100=y
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
#
# Console display driver support
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -527,12 +693,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -547,7 +710,10 @@ CONFIG_DUMMY_CONSOLE=y
#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
#
# File systems
@@ -556,6 +722,7 @@ CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
@@ -574,10 +741,12 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -598,13 +767,10 @@ CONFIG_AUTOFS4_FS=m
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -616,6 +782,8 @@ CONFIG_RAMFS=y
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
CONFIG_CRAMFS=m
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
@@ -636,6 +804,7 @@ CONFIG_NFSD=m
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -645,6 +814,7 @@ CONFIG_SMB_FS=m
# 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
@@ -704,7 +874,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -720,26 +892,27 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
CONFIG_CRYPTO=y
CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=y
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-CONFIG_CRYPTO_TWOFISH=y
-# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
-# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
# CONFIG_CRYPTO_TEST is not set
@@ -751,9 +924,8 @@ CONFIG_CRYPTO_CRC32C=m
# Library routines
#
CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig
new file mode 100644
index 000000000000..530b6c2d99f6
--- /dev/null
+++ b/arch/mips/configs/db1200_defconfig
@@ -0,0 +1,987 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:32 2005
+#
+CONFIG_MIPS=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+CONFIG_MIPS_DB1200=y
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DMA_COHERENT=y
+CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SOC_AU1200=y
+CONFIG_SOC_AU1X00=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+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_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_MIPS32_R1=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=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_64KB is not set
+CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
+CONFIG_64BIT_PHYS_ADDR=y
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+
+#
+# PC-card bridges
+#
+# CONFIG_TCIC is not set
+CONFIG_PCMCIA_AU1X00=m
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# 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_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_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_NETFILTER_NETLINK is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_PPTP=m
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+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
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_AMDSTD_RETRY=0
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_ALCHEMY=y
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD 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
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_AU1550 is not set
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_LBD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECS=m
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDE_AU1XXX=y
+CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA=y
+# CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA is not set
+# CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON is not set
+CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ=128
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+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 is not set
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+# 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
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_PCMCIA_AHA152X is not set
+# CONFIG_PCMCIA_FDOMAIN is not set
+# CONFIG_PCMCIA_NINJA_SCSI is not set
+# CONFIG_PCMCIA_QLOGIC is not set
+# CONFIG_PCMCIA_SYM53C500 is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+# CONFIG_MIPS_AU1X00_ENET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# PCMCIA network device support
+#
+# CONFIG_NET_PCMCIA is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=y
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_AU1X00_GPIO is not set
+# CONFIG_TS_AU1X00_ADS7846 is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_AU1X00=y
+CONFIG_SERIAL_AU1X00_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+CONFIG_FB_AU1200=y
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB is not set
+
+#
+# USB Gadget Support
+#
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA2XX is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_AU1X=y
+
+#
+# InfiniBand support
+#
+
+#
+# SN Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+CONFIG_JFS_FS=y
+# CONFIG_JFS_POSIX_ACL is not set
+# CONFIG_JFS_SECURITY is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=m
+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=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_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_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_CRAMFS=m
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=y
+# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE="mem=48M"
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig
index fed6f2fab48b..1c2784dee697 100644
--- a/arch/mips/configs/db1500_defconfig
+++ b/arch/mips/configs/db1500_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:01 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:36 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,63 +59,81 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+CONFIG_MIPS_DB1500=y
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-CONFIG_SOC_AU1X00=y
-# CONFIG_SOC_AU1000 is not set
-# CONFIG_SOC_AU1100 is not set
-CONFIG_SOC_AU1500=y
-# CONFIG_SOC_AU1550 is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-CONFIG_MIPS_DB1500=y
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_MIRAGE is not set
-# CONFIG_MIPS_XXS1500 is not set
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
-CONFIG_DMA_COHERENT=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SOC_AU1500=y
+CONFIG_SOC_AU1X00=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS64 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
@@ -128,15 +149,39 @@ CONFIG_CPU_MIPS32=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 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
+
+#
+# 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_64KB is not set
CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
CONFIG_64BIT_PHYS_ADDR=y
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -145,7 +190,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -154,6 +198,8 @@ CONFIG_MMU=y
CONFIG_PCCARD=m
# CONFIG_PCMCIA_DEBUG is not set
CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
CONFIG_CARDBUS=y
#
@@ -176,6 +222,100 @@ CONFIG_PCMCIA_AU1X00=m
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
CONFIG_TRAD_SIGNALS=y
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+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 is not set
+# CONFIG_NET_IPGRE is not set
+# 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_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_PPTP=m
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
#
# Device Drivers
@@ -186,15 +326,20 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
#
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
@@ -232,16 +377,14 @@ CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_XIP is not set
#
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_DB1X00=y
-CONFIG_MTD_DB1X00_BOOT=y
-CONFIG_MTD_DB1X00_USER=y
+CONFIG_MTD_ALCHEMY=y
+# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
@@ -277,7 +420,6 @@ CONFIG_MTD_DB1X00_USER=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -290,7 +432,6 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_UB is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -336,6 +477,7 @@ CONFIG_BLK_DEV_IDECS=m
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
# CONFIG_SCSI is not set
#
@@ -346,6 +488,7 @@ CONFIG_BLK_DEV_IDECS=m
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -358,94 +501,13 @@ CONFIG_BLK_DEV_IDECS=m
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-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 is not set
-# CONFIG_NET_IPGRE is not set
-# 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_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-
-#
-# IP: Virtual Server Configuration
+# Network device support
#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_IP_NF_CONNTRACK is not set
-CONFIG_IP_NF_CONNTRACK_MARK=y
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -453,6 +515,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -479,12 +556,16 @@ CONFIG_MIPS_AU1X00_ENET=y
# 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_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -497,6 +578,8 @@ CONFIG_MIPS_AU1X00_ENET=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# PCMCIA network device support
@@ -520,6 +603,8 @@ CONFIG_PPPOE=m
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -549,19 +634,6 @@ CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -571,6 +643,17 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
# CONFIG_VT is not set
@@ -590,6 +673,7 @@ CONFIG_SERIAL_AU1X00=y
CONFIG_SERIAL_AU1X00_CONSOLE=y
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
@@ -603,7 +687,8 @@ CONFIG_LEGACY_PTY_COUNT=256
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
-CONFIG_RTC=y
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
@@ -620,6 +705,11 @@ CONFIG_SYNCLINK_CS=m
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -630,10 +720,20 @@ CONFIG_SYNCLINK_CS=m
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -647,7 +747,6 @@ CONFIG_SYNCLINK_CS=m
# Graphics support
#
# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -680,7 +779,6 @@ CONFIG_SOUND_AU1000=y
# CONFIG_SOUND_MSNDCLAS is not set
# CONFIG_SOUND_MSNDPIN is not set
# CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_SOUND_OSS is not set
# CONFIG_SOUND_ALI5455 is not set
# CONFIG_SOUND_FORTE is not set
# CONFIG_SOUND_RME96XX is not set
@@ -689,6 +787,8 @@ CONFIG_SOUND_AU1000=y
#
# USB support
#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB=y
# CONFIG_USB_DEBUG is not set
@@ -699,23 +799,23 @@ CONFIG_USB=y
# CONFIG_USB_BANDWIDTH is not set
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_OTG is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
#
# USB Host Controller Drivers
#
# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_UHCI_HCD is not set
# CONFIG_USB_SL811_HCD is not set
#
# USB Device Class drivers
#
-# CONFIG_USB_AUDIO is not set
+# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
# CONFIG_USB_BLUETOOTH_TTY is not set
-# CONFIG_USB_MIDI is not set
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set
@@ -733,12 +833,17 @@ CONFIG_USB_HIDINPUT=y
# CONFIG_USB_HIDDEV is not set
# CONFIG_USB_AIPTEK is not set
# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
# CONFIG_USB_KBTAB is not set
# CONFIG_USB_POWERMATE is not set
# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
# CONFIG_USB_EGALAX is not set
+CONFIG_USB_YEALINK=m
# CONFIG_USB_XPAD is not set
# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
#
# USB Imaging devices
@@ -762,6 +867,7 @@ CONFIG_USB_HIDINPUT=y
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_RTL8150 is not set
# CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
#
# USB port drivers
@@ -786,9 +892,10 @@ CONFIG_USB_HIDINPUT=y
# CONFIG_USB_PHIDGETKIT is not set
# CONFIG_USB_PHIDGETSERVO is not set
# CONFIG_USB_IDMOUSE is not set
+CONFIG_USB_LD=m
#
-# USB ATM/DSL drivers
+# USB DSL modem support
#
#
@@ -807,12 +914,17 @@ CONFIG_USB_HIDINPUT=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
@@ -831,10 +943,12 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -855,13 +969,10 @@ CONFIG_AUTOFS4_FS=m
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -895,6 +1006,7 @@ CONFIG_NFSD=m
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -904,6 +1016,7 @@ CONFIG_SMB_FS=m
# 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
@@ -963,7 +1076,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -979,26 +1094,27 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
CONFIG_CRYPTO=y
CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=y
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-CONFIG_CRYPTO_TWOFISH=y
-# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
-# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
# CONFIG_CRYPTO_TEST is not set
@@ -1010,9 +1126,8 @@ CONFIG_CRYPTO_CRC32C=m
# Library routines
#
CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig
index 178c0ad1af75..64248e2e924a 100644
--- a/arch/mips/configs/db1550_defconfig
+++ b/arch/mips/configs/db1550_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:02 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:39 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,63 +59,80 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+CONFIG_MIPS_DB1550=y
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-CONFIG_SOC_AU1X00=y
-# CONFIG_SOC_AU1000 is not set
-# CONFIG_SOC_AU1100 is not set
-# CONFIG_SOC_AU1500 is not set
-CONFIG_SOC_AU1550=y
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-CONFIG_MIPS_DB1550=y
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_MIRAGE is not set
-# CONFIG_MIPS_XXS1500 is not set
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
-CONFIG_DMA_COHERENT=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SOC_AU1550=y
+CONFIG_SOC_AU1X00=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS64 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
@@ -128,15 +148,39 @@ CONFIG_CPU_MIPS32=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 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
+
+#
+# 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_64KB is not set
CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
CONFIG_64BIT_PHYS_ADDR=y
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -145,7 +189,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -154,6 +197,8 @@ CONFIG_MMU=y
CONFIG_PCCARD=m
# CONFIG_PCMCIA_DEBUG is not set
CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
CONFIG_CARDBUS=y
#
@@ -176,6 +221,100 @@ CONFIG_PCMCIA_AU1X00=m
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
CONFIG_TRAD_SIGNALS=y
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+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 is not set
+# CONFIG_NET_IPGRE is not set
+# 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_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_PPTP=m
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
#
# Device Drivers
@@ -186,15 +325,20 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
#
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
@@ -238,9 +382,8 @@ CONFIG_MTD_CFI_UTIL=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_DB1550=y
-CONFIG_MTD_DB1550_BOOT=y
-CONFIG_MTD_DB1550_USER=y
+CONFIG_MTD_ALCHEMY=y
+# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
@@ -281,7 +424,6 @@ CONFIG_MTD_NAND_AU1550=m
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -293,7 +435,6 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -350,6 +491,7 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_HPT366 is not set
# CONFIG_BLK_DEV_SC1200 is not set
# CONFIG_BLK_DEV_PIIX 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
@@ -367,6 +509,7 @@ CONFIG_BLK_DEV_IDEDMA=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
# CONFIG_SCSI is not set
#
@@ -377,6 +520,7 @@ CONFIG_BLK_DEV_IDEDMA=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -389,94 +533,13 @@ CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-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 is not set
-# CONFIG_NET_IPGRE is not set
-# 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_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-
-#
-# IP: Virtual Server Configuration
+# Network device support
#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_IP_NF_CONNTRACK is not set
-CONFIG_IP_NF_CONNTRACK_MARK=y
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -484,6 +547,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -510,12 +588,16 @@ CONFIG_MIPS_AU1X00_ENET=y
# 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_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -528,6 +610,8 @@ CONFIG_MIPS_AU1X00_ENET=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# PCMCIA network device support
@@ -559,6 +643,8 @@ CONFIG_PPPOE=m
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -588,19 +674,6 @@ CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -610,6 +683,17 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
# CONFIG_VT is not set
@@ -629,6 +713,7 @@ CONFIG_SERIAL_AU1X00=y
CONFIG_SERIAL_AU1X00_CONSOLE=y
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
@@ -660,6 +745,11 @@ CONFIG_SYNCLINK_CS=m
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -670,10 +760,20 @@ CONFIG_SYNCLINK_CS=m
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -687,7 +787,6 @@ CONFIG_SYNCLINK_CS=m
# Graphics support
#
# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -697,13 +796,9 @@ CONFIG_SYNCLINK_CS=m
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -721,12 +816,17 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
@@ -745,10 +845,12 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -769,13 +871,10 @@ CONFIG_AUTOFS4_FS=m
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -809,6 +908,7 @@ CONFIG_NFSD=m
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -818,6 +918,7 @@ CONFIG_SMB_FS=m
# 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
@@ -877,7 +978,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -893,26 +996,27 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
CONFIG_CRYPTO=y
CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=y
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-CONFIG_CRYPTO_TWOFISH=y
-# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
-# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
# CONFIG_CRYPTO_TEST is not set
@@ -924,9 +1028,8 @@ CONFIG_CRYPTO_CRC32C=m
# Library routines
#
CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/ddb5476_defconfig b/arch/mips/configs/ddb5476_defconfig
index 70addc73f699..b260e51eb517 100644
--- a/arch/mips/configs/ddb5476_defconfig
+++ b/arch/mips/configs/ddb5476_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:02 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:42 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -50,41 +53,69 @@ CONFIG_CC_ALIGN_JUMPS=0
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
CONFIG_DDB5476=y
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
CONFIG_I8259=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_DDB5XXX_COMMON=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
@@ -93,8 +124,10 @@ CONFIG_HAVE_STD_PC_SERIAL_PORT=y
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# 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
@@ -110,14 +143,38 @@ CONFIG_CPU_R5432=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_R5432=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=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_64KB is not set
+# CONFIG_MIPS_MT is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -126,7 +183,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_ISA=y
CONFIG_MMU=y
@@ -136,11 +192,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-CONFIG_PCMCIA_PROBE=y
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -153,6 +204,80 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=y
+CONFIG_IEEE80211_CRYPT_CCMP=y
+CONFIG_IEEE80211_CRYPT_TKIP=y
+
+#
# Device Drivers
#
@@ -161,7 +286,12 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=y
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
#
# Memory Technology Devices (MTD)
@@ -181,8 +311,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -193,7 +321,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=y
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -239,6 +366,7 @@ CONFIG_IDE_GENERIC=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=y
# CONFIG_SCSI is not set
#
@@ -254,6 +382,7 @@ CONFIG_IDE_GENERIC=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -266,78 +395,13 @@ CONFIG_IDE_GENERIC=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-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 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_TUNNEL=y
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=y
-
-#
-# SCTP Configuration (EXPERIMENTAL)
+# Network device support
#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -345,6 +409,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -352,7 +431,6 @@ CONFIG_NET_ETHERNET=y
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
@@ -377,12 +455,16 @@ CONFIG_NET_ETHERNET=y
# 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_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -395,6 +477,8 @@ CONFIG_NET_ETHERNET=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=y
#
# Wan interfaces
@@ -406,6 +490,8 @@ CONFIG_NET_ETHERNET=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -435,19 +521,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=y
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -457,6 +530,17 @@ CONFIG_SERIO_RAW=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=y
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -477,6 +561,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
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
@@ -503,6 +588,11 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -513,10 +603,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -530,6 +630,11 @@ CONFIG_LEGACY_PTY_COUNT=256
# Graphics support
#
CONFIG_FB=y
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_SOFT_CURSOR is not set
+# CONFIG_FB_MACMODES is not set
# CONFIG_FB_MODE_HELPERS is not set
# CONFIG_FB_TILEBLITTING is not set
# CONFIG_FB_CIRRUS is not set
@@ -537,6 +642,7 @@ CONFIG_FB=y
# CONFIG_FB_CYBER2000 is not set
# CONFIG_FB_ASILIANT is not set
# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
# CONFIG_FB_MATROX is not set
# CONFIG_FB_RADEON_OLD is not set
@@ -549,8 +655,11 @@ CONFIG_FB=y
# CONFIG_FB_KYRO is not set
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_SMIVGX is not set
+# CONFIG_FB_CYBLA is not set
# CONFIG_FB_TRIDENT is not set
# CONFIG_FB_E1356 is not set
+# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_VIRTUAL is not set
#
@@ -575,13 +684,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -599,21 +704,29 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=y
#
# CD-ROM/DVD Filesystems
@@ -634,12 +747,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=y
#
# Miscellaneous filesystems
@@ -668,7 +779,7 @@ CONFIG_NFS_FS=y
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
-# CONFIG_EXPORTFS is not set
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -677,6 +788,7 @@ CONFIG_SUNRPC=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
@@ -697,7 +809,9 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE="ip=any"
@@ -711,7 +825,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -721,7 +859,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CRC16=y
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/mips/configs/ddb5477_defconfig b/arch/mips/configs/ddb5477_defconfig
index 60292808b384..c2a01df3c8df 100644
--- a/arch/mips/configs/ddb5477_defconfig
+++ b/arch/mips/configs/ddb5477_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:02 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:45 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -50,42 +53,70 @@ CONFIG_CC_ALIGN_JUMPS=0
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
CONFIG_DDB5477=y
-CONFIG_DDB5477_BUS_FREQUENCY=0
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+CONFIG_DDB5477_BUS_FREQUENCY=0
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
CONFIG_I8259=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_DDB5XXX_COMMON=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
@@ -93,8 +124,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# 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
@@ -110,14 +143,38 @@ CONFIG_CPU_R5432=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_R5432=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=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_64KB is not set
+# CONFIG_MIPS_MT is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -126,7 +183,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -135,10 +191,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -151,6 +203,80 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=y
+CONFIG_IEEE80211_CRYPT_CCMP=y
+CONFIG_IEEE80211_CRYPT_TKIP=y
+
+#
# Device Drivers
#
@@ -159,7 +285,12 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=y
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
#
# Memory Technology Devices (MTD)
@@ -178,7 +309,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -189,7 +319,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=y
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -212,6 +341,7 @@ CONFIG_ATA_OVER_ETH=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=y
# CONFIG_SCSI is not set
#
@@ -222,6 +352,7 @@ CONFIG_ATA_OVER_ETH=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -234,78 +365,13 @@ CONFIG_ATA_OVER_ETH=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-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 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_TUNNEL=y
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=y
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
+# Network device support
#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -313,6 +379,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -357,13 +438,17 @@ CONFIG_PCNET32=y
# 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_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -376,6 +461,8 @@ CONFIG_PCNET32=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=y
#
# Wan interfaces
@@ -387,6 +474,8 @@ CONFIG_PCNET32=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -416,19 +505,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=y
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -438,6 +514,17 @@ CONFIG_SERIO_RAW=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=y
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -458,6 +545,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
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
@@ -484,6 +572,11 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -494,10 +587,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -517,7 +620,6 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -527,13 +629,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -551,21 +649,29 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=y
CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=y
#
# CD-ROM/DVD Filesystems
@@ -586,12 +692,10 @@ CONFIG_AUTOFS4_FS=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=y
#
# Miscellaneous filesystems
@@ -623,6 +727,7 @@ CONFIG_NFSD=y
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -631,6 +736,7 @@ CONFIG_SUNRPC=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
@@ -651,7 +757,9 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE="ip=any"
@@ -665,7 +773,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -675,7 +807,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig
index 66ec1f41d122..5bc885b72d14 100644
--- a/arch/mips/configs/decstation_defconfig
+++ b/arch/mips/configs/decstation_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:03 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:48 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,30 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
# CONFIG_HOTPLUG is not set
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +44,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -49,48 +53,76 @@ CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
+# CONFIG_MODVERSIONS is not set
CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
CONFIG_MACH_DECSTATION=y
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
CONFIG_EARLY_PRINTK=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=4
@@ -98,8 +130,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=4
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# 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=y
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -115,12 +149,37 @@ CONFIG_CPU_R3000=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_R3000=y
+CONFIG_SYS_HAS_CPU_R4X00=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=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_64KB is not set
+# CONFIG_MIPS_MT is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_WB=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_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 is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -135,10 +194,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
@@ -150,6 +205,80 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -159,6 +288,12 @@ CONFIG_TRAD_SIGNALS=y
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
@@ -177,17 +312,14 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+# CONFIG_CDROM_PKTCDVD is not set
#
# IO Schedulers
@@ -196,7 +328,7 @@ CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
-CONFIG_ATA_OVER_ETH=m
+# CONFIG_ATA_OVER_ETH is not set
#
# ATA/ATAPI/MFM/RLL support
@@ -206,6 +338,7 @@ CONFIG_ATA_OVER_ETH=m
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
CONFIG_SCSI=y
CONFIG_SCSI_PROC_FS=y
@@ -213,10 +346,12 @@ 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_ST=m
# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_CHR_DEV_SG is not set
+CONFIG_BLK_DEV_SR=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -228,9 +363,10 @@ CONFIG_SCSI_CONSTANTS=y
#
# SCSI Transport Attributes
#
-# CONFIG_SCSI_SPI_ATTRS is not set
+CONFIG_SCSI_SPI_ATTRS=m
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
+CONFIG_SCSI_SAS_ATTRS=m
#
# SCSI low-level drivers
@@ -248,6 +384,7 @@ CONFIG_SCSI_DECNCR=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -258,78 +395,28 @@ CONFIG_SCSI_DECNCR=y
#
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-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 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_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
+# Network device support
#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
#
-# QoS and/or fair queueing
+# PHY device support
#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
#
-# Network testing
+# MII PHY device drivers
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
#
# Ethernet (10 or 100Mbit)
@@ -363,6 +450,8 @@ CONFIG_DECLANCE=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -377,48 +466,22 @@ CONFIG_DECLANCE=y
#
# Input device support
#
-CONFIG_INPUT=y
+# CONFIG_INPUT 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_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input I/O drivers
+# Hardware I/O ports
#
+# CONFIG_SERIO is not set
# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
#
# Character devices
#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
+# CONFIG_VT is not set
# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_SERIAL_DEC=y
+CONFIG_SERIAL_DEC_CONSOLE=y
+CONFIG_ZS=y
#
# Serial drivers
@@ -445,18 +508,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
+CONFIG_RTC=y
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -467,10 +532,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -483,13 +558,29 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# Graphics support
#
-# CONFIG_FB is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_PMAG_AA is not set
+CONFIG_FB_PMAG_BA=y
+CONFIG_FB_PMAGB_B=y
+# CONFIG_FB_MAXINE is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+CONFIG_LOGO_DEC_CLUT224=y
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -504,10 +595,6 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
@@ -520,7 +607,10 @@ CONFIG_DUMMY_CONSOLE=y
#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
#
# File systems
@@ -529,6 +619,7 @@ CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
CONFIG_FS_MBCACHE=y
@@ -538,10 +629,12 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -562,12 +655,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
-# CONFIG_TMPFS is not set
+CONFIG_TMPFS=y
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -584,19 +675,31 @@ CONFIG_RAMFS=y
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
+CONFIG_UFS_FS=y
+CONFIG_UFS_FS_WRITE=y
#
# Network File Systems
#
-# CONFIG_NFS_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
# CONFIG_NFSD is not set
-# CONFIG_EXPORTFS is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
# CONFIG_CIFS is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -631,9 +734,24 @@ CONFIG_ULTRIX_PARTITION=y
#
# Kernel hacking
#
-# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_KGDB is not set
+# CONFIG_RUNTIME_DEBUG is not set
+# CONFIG_MIPS_UNCACHED is not set
#
# Security options
@@ -645,7 +763,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -655,7 +797,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=m
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig
index ba2ec01defb1..c0d06ea5566c 100644
--- a/arch/mips/configs/e55_defconfig
+++ b/arch/mips/configs/e55_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:03 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:51 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
# CONFIG_HOTPLUG is not set
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,56 +59,84 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-CONFIG_MACH_VR41XX=y
-# CONFIG_NEC_CMBVR4133 is not set
-CONFIG_CASIO_E55=y
-# CONFIG_IBM_WORKPAD is not set
-# CONFIG_TANBAC_TB0226 is not set
-# CONFIG_TANBAC_TB0229 is not set
-# CONFIG_VICTOR_MPC30X is not set
-# CONFIG_ZAO_CAPCELLA is not set
-# CONFIG_VRC4171 is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+CONFIG_MACH_VR41XX=y
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_NEC_CMBVR4133 is not set
+CONFIG_CASIO_E55=y
+# CONFIG_IBM_WORKPAD is not set
+# CONFIG_TANBAC_TB022X is not set
+# CONFIG_VICTOR_MPC30X is not set
+# CONFIG_ZAO_CAPCELLA is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# 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=y
@@ -121,12 +152,36 @@ CONFIG_CPU_VR41XX=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_VR41XX=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=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_64KB is not set
+# CONFIG_MIPS_MT is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -141,11 +196,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-CONFIG_PCMCIA_PROBE=y
-
-#
# PCI Hotplug Support
#
@@ -157,6 +207,78 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# 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_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_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -168,6 +290,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -185,18 +312,13 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+# CONFIG_CDROM_PKTCDVD is not set
#
# IO Schedulers
@@ -205,7 +327,7 @@ CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
-CONFIG_ATA_OVER_ETH=m
+# CONFIG_ATA_OVER_ETH is not set
#
# ATA/ATAPI/MFM/RLL support
@@ -237,6 +359,7 @@ CONFIG_IDE_GENERIC=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
#
@@ -252,6 +375,7 @@ CONFIG_IDE_GENERIC=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -262,76 +386,13 @@ CONFIG_IDE_GENERIC=y
#
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
+# Network device support
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -339,12 +400,26 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
# CONFIG_MII is not set
# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
# CONFIG_AT1700 is not set
@@ -380,6 +455,8 @@ CONFIG_NET_ETHERNET=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -401,26 +478,14 @@ CONFIG_INPUT=y
#
CONFIG_INPUT_MOUSEDEV=y
CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=320
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_TSDEV is not set
# CONFIG_INPUT_EVDEV is not set
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -430,6 +495,16 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -440,16 +515,15 @@ CONFIG_HW_CONSOLE=y
#
# Serial drivers
#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250 is not set
#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_VR41XX=y
+CONFIG_SERIAL_VR41XX_CONSOLE=y
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -484,10 +558,14 @@ CONFIG_WATCHDOG=y
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
+CONFIG_GPIO_VR41XX=y
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -498,10 +576,20 @@ CONFIG_WATCHDOG=y
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -522,7 +610,6 @@ CONFIG_WATCHDOG=y
# CONFIG_VGA_CONSOLE is not set
# CONFIG_MDA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -536,10 +623,6 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
@@ -552,24 +635,31 @@ CONFIG_DUMMY_CONSOLE=y
#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=y
CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -590,12 +680,10 @@ CONFIG_AUTOFS4_FS=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -617,16 +705,17 @@ CONFIG_RAMFS=y
#
# Network File Systems
#
-CONFIG_NFS_FS=y
+CONFIG_NFS_FS=m
# CONFIG_NFS_V3 is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
-CONFIG_NFSD=y
+CONFIG_NFSD=m
# CONFIG_NFSD_V3 is not set
# CONFIG_NFSD_TCP is not set
-CONFIG_LOCKD=y
-CONFIG_EXPORTFS=y
-CONFIG_SUNRPC=y
+CONFIG_LOCKD=m
+CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -634,6 +723,7 @@ CONFIG_SUNRPC=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
@@ -654,9 +744,11 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
+CONFIG_CMDLINE="console=ttyVR0,19200 mem=8M"
#
# Security options
@@ -668,7 +760,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -678,7 +794,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
+CONFIG_CRC16=m
+CONFIG_CRC32=m
CONFIG_LIBCRC32C=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/ev64120_defconfig b/arch/mips/configs/ev64120_defconfig
index 17e87f70f602..f1309d84d2fe 100644
--- a/arch/mips/configs/ev64120_defconfig
+++ b/arch/mips/configs/ev64120_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:03 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:54 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,41 +59,69 @@ CONFIG_MODULE_SRCVERSION_ALL=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
CONFIG_MIPS_EV64120=y
-# CONFIG_EVB_PCI1 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_EVB_PCI1 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
CONFIG_MIPS_GT64120=y
# CONFIG_SYSCLK_75 is not set
# CONFIG_SYSCLK_83 is not set
@@ -100,8 +131,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# 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
@@ -117,15 +150,39 @@ CONFIG_CPU_R5000=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_R5000=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=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_64KB is not set
+# CONFIG_MIPS_MT is not set
# CONFIG_64BIT_PHYS_ADDR is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -134,7 +191,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -143,10 +199,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -159,6 +211,79 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_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_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -167,7 +292,12 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
@@ -186,7 +316,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -197,7 +326,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -220,6 +348,7 @@ CONFIG_ATA_OVER_ETH=m
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
# CONFIG_SCSI is not set
#
@@ -230,6 +359,7 @@ CONFIG_ATA_OVER_ETH=m
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -242,77 +372,13 @@ CONFIG_ATA_OVER_ETH=m
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_PACKET is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_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_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
+# Network device support
#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -320,6 +386,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -345,12 +426,16 @@ CONFIG_NET_ETHERNET=y
# 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_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -363,6 +448,8 @@ CONFIG_NET_ETHERNET=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# Wan interfaces
@@ -381,6 +468,8 @@ CONFIG_PPP_ASYNC=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -410,19 +499,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -432,6 +508,17 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -452,6 +539,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
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
@@ -478,6 +566,11 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -488,10 +581,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -511,7 +614,6 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -521,13 +623,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -545,21 +643,29 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -580,12 +686,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -614,7 +718,7 @@ CONFIG_NFS_FS=y
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
-# CONFIG_EXPORTFS is not set
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -623,6 +727,7 @@ CONFIG_SUNRPC=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
@@ -643,7 +748,9 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs rw nfsroot=192.168.1.1:/mnt/disk2/fs.gal ip=192.168.1.211:192.168.1.1:::gt::"
@@ -657,7 +764,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -667,7 +798,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
CONFIG_CRC_CCITT=y
-# CONFIG_CRC32 is not set
+CONFIG_CRC16=m
+CONFIG_CRC32=m
CONFIG_LIBCRC32C=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/ev96100_defconfig b/arch/mips/configs/ev96100_defconfig
index 9da4140eae00..8ac55b7acc01 100644
--- a/arch/mips/configs/ev96100_defconfig
+++ b/arch/mips/configs/ev96100_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:03 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:57 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
# CONFIG_HOTPLUG is not set
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,40 +59,68 @@ CONFIG_MODULE_SRCVERSION_ALL=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
CONFIG_MIPS_EV96100=y
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_MIPS_GT64120=y
CONFIG_SWAP_IO_SPACE=y
@@ -99,8 +130,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# 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
@@ -116,6 +149,18 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
CONFIG_CPU_RM7000=y
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_R5000=y
+CONFIG_SYS_HAS_CPU_RM7000=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=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
@@ -123,11 +168,25 @@ CONFIG_PAGE_SIZE_4KB=y
CONFIG_BOARD_SCACHE=y
CONFIG_RM7000_CPU_SCACHE=y
CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
# CONFIG_64BIT_PHYS_ADDR is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=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_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -143,10 +202,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
@@ -158,6 +213,79 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -169,6 +297,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -185,13 +318,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -214,6 +345,7 @@ CONFIG_ATA_OVER_ETH=m
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
# CONFIG_SCSI is not set
#
@@ -224,6 +356,7 @@ CONFIG_ATA_OVER_ETH=m
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -234,77 +367,28 @@ CONFIG_ATA_OVER_ETH=m
#
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
+# Network device support
#
-# CONFIG_PACKET is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-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 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_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
#
-# QoS and/or fair queueing
+# PHY device support
#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
#
-# Network testing
+# MII PHY device drivers
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
#
# Ethernet (10 or 100Mbit)
@@ -338,6 +422,8 @@ CONFIG_MIPS_GT96100ETH=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -367,18 +453,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -388,6 +462,16 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -429,10 +513,13 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -443,10 +530,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -466,7 +563,6 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -480,10 +576,6 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
@@ -496,24 +588,31 @@ CONFIG_DUMMY_CONSOLE=y
#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -534,12 +633,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -568,7 +665,7 @@ CONFIG_NFS_FS=y
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
-# CONFIG_EXPORTFS is not set
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -577,6 +674,7 @@ CONFIG_SUNRPC=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
@@ -597,7 +695,9 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -611,7 +711,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -621,7 +745,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
+CONFIG_CRC16=m
+CONFIG_CRC32=m
CONFIG_LIBCRC32C=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig
index 17fa5c4e3ad1..3ae3838f283c 100644
--- a/arch/mips/configs/ip22_defconfig
+++ b/arch/mips/configs/ip22_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:04 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:01 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,25 +11,30 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
# CONFIG_HOTPLUG is not set
CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -42,6 +44,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -57,41 +60,69 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
CONFIG_SGI_IP22=y
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_ARC=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=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_ARC32=y
@@ -103,8 +134,10 @@ CONFIG_ARC_PROMLIB=y
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# 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
@@ -120,22 +153,48 @@ CONFIG_CPU_R5000=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_R4X00=y
+CONFIG_SYS_HAS_CPU_R5000=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=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_64KB is not set
CONFIG_BOARD_SCACHE=y
CONFIG_IP22_CPU_SCACHE=y
+# CONFIG_MIPS_MT is not set
# CONFIG_64BIT_PHYS_ADDR is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
#
# Bus options (PCI, PCMCIA, EISA, ISA, TC)
#
+CONFIG_HW_HAS_EISA=y
# CONFIG_EISA is not set
CONFIG_MMU=y
@@ -145,10 +204,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
@@ -160,115 +215,7 @@ CONFIG_BINFMT_MISC=m
CONFIG_TRAD_SIGNALS=y
#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_RAM is not set
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_ATA_OVER_ETH=m
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-CONFIG_SCSI=y
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=y
-# CONFIG_CHR_DEV_OSST is not set
-CONFIG_BLK_DEV_SR=y
-# CONFIG_BLK_DEV_SR_VENDOR is not set
-# CONFIG_CHR_DEV_SG is not set
-
-#
-# 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
-
-#
-# SCSI Transport Attributes
-#
-CONFIG_SCSI_SPI_ATTRS=m
-# CONFIG_SCSI_FC_ATTRS is not set
-# CONFIG_SCSI_ISCSI_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
-CONFIG_SGIWD93_SCSI=y
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Networking support
+# Networking
#
CONFIG_NET=y
@@ -277,12 +224,14 @@ CONFIG_NET=y
#
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
CONFIG_NET_KEY=y
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
@@ -296,8 +245,10 @@ CONFIG_INET_AH=m
CONFIG_INET_ESP=m
CONFIG_INET_IPCOMP=m
CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-CONFIG_IP_TCPDIAG_IPV6=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
#
# IP: Virtual Server Configuration
@@ -341,6 +292,9 @@ CONFIG_INET6_TUNNEL=m
CONFIG_IPV6_TUNNEL=m
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
#
# IP: Netfilter Configuration
@@ -348,11 +302,15 @@ CONFIG_NETFILTER=y
CONFIG_IP_NF_CONNTRACK=m
CONFIG_IP_NF_CT_ACCT=y
CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CONNTRACK_EVENTS=y
+CONFIG_IP_NF_CONNTRACK_NETLINK=m
# CONFIG_IP_NF_CT_PROTO_SCTP is not set
CONFIG_IP_NF_FTP=m
CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_NETBIOS_NS is not set
CONFIG_IP_NF_TFTP=m
CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_PPTP=m
CONFIG_IP_NF_QUEUE=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_LIMIT=m
@@ -376,9 +334,12 @@ CONFIG_IP_NF_MATCH_OWNER=m
CONFIG_IP_NF_MATCH_ADDRTYPE=m
CONFIG_IP_NF_MATCH_REALM=m
CONFIG_IP_NF_MATCH_SCTP=m
+CONFIG_IP_NF_MATCH_DCCP=m
CONFIG_IP_NF_MATCH_COMMENT=m
CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_CONNBYTES=m
CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_MATCH_STRING=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_TARGET_LOG=m
@@ -395,12 +356,14 @@ CONFIG_IP_NF_NAT_IRC=m
CONFIG_IP_NF_NAT_FTP=m
CONFIG_IP_NF_NAT_TFTP=m
CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_NAT_PPTP=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_TOS=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_DSCP=m
CONFIG_IP_NF_TARGET_MARK=m
CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_TARGET_CONNMARK=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_RAW=m
@@ -410,7 +373,7 @@ CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
#
-# IPv6: Netfilter Configuration
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
#
CONFIG_IP6_NF_QUEUE=m
CONFIG_IP6_NF_IPTABLES=m
@@ -429,11 +392,16 @@ CONFIG_IP6_NF_MATCH_LENGTH=m
CONFIG_IP6_NF_MATCH_EUI64=m
CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_TARGET_REJECT=m
CONFIG_IP6_NF_MANGLE=m
CONFIG_IP6_NF_TARGET_MARK=m
+CONFIG_IP6_NF_TARGET_HL=m
CONFIG_IP6_NF_RAW=m
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
#
# SCTP Configuration (EXPERIMENTAL)
@@ -456,10 +424,6 @@ CONFIG_SCTP_HMAC_MD5=y
CONFIG_NET_DIVERT=y
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
CONFIG_NET_SCHED=y
# CONFIG_NET_SCH_CLK_JIFFIES is not set
CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
@@ -479,6 +443,7 @@ CONFIG_NET_SCH_INGRESS=m
CONFIG_NET_QOS=y
CONFIG_NET_ESTIMATOR=y
CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
CONFIG_NET_CLS_TCINDEX=m
CONFIG_NET_CLS_ROUTE4=m
CONFIG_NET_CLS_ROUTE=y
@@ -489,6 +454,7 @@ CONFIG_NET_CLS_U32=m
# CONFIG_CLS_U32_MARK is not set
CONFIG_NET_CLS_RSVP=m
CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_EMATCH is not set
# CONFIG_NET_CLS_ACT is not set
CONFIG_NET_CLS_POLICE=y
@@ -496,17 +462,153 @@ CONFIG_NET_CLS_POLICE=y
# Network testing
#
# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+# CONFIG_CHR_DEV_SG is not set
+CONFIG_CHR_DEV_SCH=m
+
+#
+# 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
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_SGIWD93_SCSI=y
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
CONFIG_NETDEVICES=y
CONFIG_DUMMY=m
CONFIG_BONDING=m
CONFIG_EQUALIZER=m
CONFIG_TUN=m
-CONFIG_ETHERTAP=m
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
#
# Ethernet (10 or 100Mbit)
@@ -540,6 +642,8 @@ CONFIG_SGISEEQ=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -569,18 +673,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-CONFIG_SERIO_LIBPS2=y
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
@@ -598,6 +690,16 @@ CONFIG_MOUSE_SERIAL=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -644,11 +746,14 @@ CONFIG_SGI_DS1286=m
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
CONFIG_RAW_DRIVER=m
CONFIG_MAX_RAW_DEVS=256
#
+# TPM devices
+#
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -659,10 +764,20 @@ CONFIG_MAX_RAW_DEVS=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -693,7 +808,6 @@ CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_VGA16 is not set
# CONFIG_LOGO_LINUX_CLUT224 is not set
CONFIG_LOGO_SGI_CLUT224=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -707,10 +821,6 @@ CONFIG_LOGO_SGI_CLUT224=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
@@ -723,13 +833,17 @@ CONFIG_LOGO_SGI_CLUT224=y
#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
#
# File systems
#
CONFIG_EXT2_FS=m
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
@@ -741,12 +855,14 @@ CONFIG_FS_MBCACHE=y
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
CONFIG_XFS_FS=m
-# CONFIG_XFS_RT is not set
-CONFIG_XFS_QUOTA=y
+CONFIG_XFS_EXPORT=y
+CONFIG_XFS_QUOTA=m
CONFIG_XFS_SECURITY=y
# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
CONFIG_MINIX_FS=m
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
CONFIG_QUOTA=y
# CONFIG_QFMT_V1 is not set
CONFIG_QFMT_V2=m
@@ -754,6 +870,7 @@ CONFIG_QUOTACTL=y
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -781,12 +898,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -811,15 +926,20 @@ CONFIG_UFS_FS=m
#
CONFIG_NFS_FS=m
CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
# CONFIG_NFSD_V4 is not set
CONFIG_NFSD_TCP=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
@@ -835,6 +955,7 @@ CONFIG_CIFS=m
CONFIG_CODA_FS=m
# CONFIG_CODA_FS_OLD_API is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -908,7 +1029,9 @@ CONFIG_NLS_UTF8=m
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -931,6 +1054,7 @@ CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_DES=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_TWOFISH=m
@@ -942,10 +1066,10 @@ CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_DEFLATE=m
CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
-CONFIG_CRYPTO_TEST=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -955,9 +1079,12 @@ CONFIG_CRYPTO_TEST=m
# Library routines
#
# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=m
CONFIG_CRC32=m
CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig
index b2a67da1e031..d962f61d5b98 100644
--- a/arch/mips/configs/ip27_defconfig
+++ b/arch/mips/configs/ip27_defconfig
@@ -1,11 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:04 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:04 2005
#
CONFIG_MIPS=y
-CONFIG_64BIT=y
-CONFIG_64BIT=y
#
# Code maturity level options
@@ -13,25 +11,31 @@ CONFIG_64BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=15
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+CONFIG_CPUSETS=y
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +45,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -57,55 +62,85 @@ CONFIG_STOP_MACHINE=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
CONFIG_SGI_IP27=y
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
# CONFIG_SGI_SN0_N_MODE is not set
CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
CONFIG_NUMA=y
# CONFIG_MAPPED_KERNEL is not set
# CONFIG_REPLICATE_KTEXT is not set
# CONFIG_REPLICATE_EXHANDLERS is not set
-# CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
-# CONFIG_SNI_RM200_PCI is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_ARC=y
CONFIG_DMA_IP27=y
+CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
CONFIG_MIPS_L1_CACHE_SHIFT=7
CONFIG_ARC64=y
CONFIG_BOOT_ELF64=y
-CONFIG_QL_ISP_A64=y
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# 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
@@ -121,17 +156,42 @@ CONFIG_CPU_R10000=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_R10000=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=y
# CONFIG_PAGE_SIZE_8KB is not set
# CONFIG_PAGE_SIZE_16KB is not set
# CONFIG_PAGE_SIZE_64KB is not set
CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+CONFIG_DISCONTIGMEM_MANUAL=y
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_DISCONTIGMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_NEED_MULTIPLE_NODES=y
+# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SMP=y
CONFIG_NR_CPUS=64
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
# CONFIG_MIPS_INSANE_LARGE is not set
#
@@ -141,7 +201,6 @@ CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -150,10 +209,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -163,7 +218,7 @@ CONFIG_MMU=y
#
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
-# CONFIG_BUILD_ELF64 is not set
+CONFIG_BUILD_ELF64=y
CONFIG_MIPS32_COMPAT=y
CONFIG_COMPAT=y
CONFIG_MIPS32_O32=y
@@ -171,6 +226,111 @@ CONFIG_MIPS32_O32=y
CONFIG_BINFMT_ELF32=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+CONFIG_NET_SCHED=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_QOS=y
+CONFIG_NET_ESTIMATOR=y
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+# CONFIG_CLS_U32_PERF is not set
+# CONFIG_NET_CLS_IND is not set
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_EMATCH is not set
+# CONFIG_NET_CLS_ACT is not set
+CONFIG_NET_CLS_POLICE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -179,7 +339,12 @@ CONFIG_BINFMT_ELF32=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
@@ -198,7 +363,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -210,7 +374,6 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
# CONFIG_CDROM_PKTCDVD_WCACHE is not set
@@ -232,6 +395,7 @@ CONFIG_ATA_OVER_ETH=m
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
CONFIG_SCSI=y
CONFIG_SCSI_PROC_FS=y
@@ -241,8 +405,10 @@ CONFIG_SCSI_PROC_FS=y
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=y
# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_CHR_DEV_SG is not set
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -256,7 +422,8 @@ CONFIG_SCSI_LOGGING=y
#
CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_FC_ATTRS is not set
-# CONFIG_SCSI_ISCSI_ATTRS is not set
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
#
# SCSI low-level drivers
@@ -271,26 +438,24 @@ CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
# CONFIG_SCSI_IPR is not set
-CONFIG_SCSI_QLOGIC_ISP=y
# CONFIG_SCSI_QLOGIC_FC is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
+CONFIG_SCSI_QLOGIC_1280=y
+CONFIG_SCSI_QLOGIC_1280_1040=y
CONFIG_SCSI_QLA2XXX=y
# CONFIG_SCSI_QLA21XX is not set
# CONFIG_SCSI_QLA22XX is not set
# CONFIG_SCSI_QLA2300 is not set
# CONFIG_SCSI_QLA2322 is not set
# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_DEBUG is not set
@@ -313,11 +478,15 @@ CONFIG_DM_CRYPT=m
CONFIG_DM_SNAPSHOT=m
CONFIG_DM_MIRROR=m
CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
#
# Fusion MPT device support
#
# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
#
# IEEE 1394 (FireWire) support
@@ -330,107 +499,13 @@ CONFIG_DM_ZERO=m
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-CONFIG_NET_SCHED=y
-# CONFIG_NET_SCH_CLK_JIFFIES is not set
-CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
-# CONFIG_NET_SCH_CLK_CPU is not set
-CONFIG_NET_SCH_CBQ=m
-CONFIG_NET_SCH_HTB=m
-CONFIG_NET_SCH_HFSC=m
-CONFIG_NET_SCH_PRIO=m
-CONFIG_NET_SCH_RED=m
-CONFIG_NET_SCH_SFQ=m
-CONFIG_NET_SCH_TEQL=m
-CONFIG_NET_SCH_TBF=m
-CONFIG_NET_SCH_GRED=m
-CONFIG_NET_SCH_DSMARK=m
-CONFIG_NET_SCH_NETEM=m
-CONFIG_NET_SCH_INGRESS=m
-CONFIG_NET_QOS=y
-CONFIG_NET_ESTIMATOR=y
-CONFIG_NET_CLS=y
-CONFIG_NET_CLS_TCINDEX=m
-CONFIG_NET_CLS_ROUTE4=m
-CONFIG_NET_CLS_ROUTE=y
-CONFIG_NET_CLS_FW=m
-CONFIG_NET_CLS_U32=m
-# CONFIG_CLS_U32_PERF is not set
-# CONFIG_NET_CLS_IND is not set
-CONFIG_NET_CLS_RSVP=m
-CONFIG_NET_CLS_RSVP6=m
-# CONFIG_NET_CLS_ACT is not set
-CONFIG_NET_CLS_POLICE=y
-
-#
-# Network testing
+# Network device support
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -438,13 +513,25 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
-CONFIG_SGI_IOC3_ETH=y
-CONFIG_SGI_IOC3_ETH_HW_RX_CSUM=y
-CONFIG_SGI_IOC3_ETH_HW_TX_CSUM=y
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
# CONFIG_NET_VENDOR_3COM is not set
@@ -466,12 +553,16 @@ CONFIG_SGI_IOC3_ETH_HW_TX_CSUM=y
# 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_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -484,6 +575,8 @@ CONFIG_SGI_IOC3_ETH_HW_TX_CSUM=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# Wan interfaces
@@ -496,6 +589,8 @@ CONFIG_SGI_IOC3_ETH_HW_TX_CSUM=y
# CONFIG_NET_FC is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -513,25 +608,15 @@ CONFIG_SGI_IOC3_ETH_HW_TX_CSUM=y
# CONFIG_INPUT is not set
#
-# Userland interfaces
-#
-
-#
-# Input I/O drivers
+# Hardware I/O ports
#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
CONFIG_SERIO=y
# CONFIG_SERIO_I8042 is not set
CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_LIBPS2=m
CONFIG_SERIO_RAW=m
-
-#
-# Input Device Drivers
-#
+# CONFIG_GAMEPORT is not set
#
# Character devices
@@ -549,7 +634,6 @@ CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
# CONFIG_SERIAL_8250_RSA is not set
#
@@ -557,6 +641,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
#
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
@@ -584,6 +669,11 @@ CONFIG_SGI_IP27_RTC=y
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -594,10 +684,20 @@ CONFIG_SGI_IP27_RTC=y
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -611,7 +711,6 @@ CONFIG_SGI_IP27_RTC=y
# Graphics support
#
# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -621,13 +720,9 @@ CONFIG_SGI_IP27_RTC=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -645,12 +740,17 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
@@ -662,17 +762,19 @@ CONFIG_FS_MBCACHE=y
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
CONFIG_XFS_FS=m
-# CONFIG_XFS_RT is not set
-CONFIG_XFS_QUOTA=y
+CONFIG_XFS_QUOTA=m
CONFIG_XFS_SECURITY=y
CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_QUOTACTL=y
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -693,12 +795,10 @@ CONFIG_AUTOFS_FS=m
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -722,13 +822,14 @@ CONFIG_RAMFS=y
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
# CONFIG_NFSD is not set
# CONFIG_ROOT_NFS is not set
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
-# CONFIG_EXPORTFS is not set
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
CONFIG_RPCSEC_GSS_KRB5=y
@@ -738,6 +839,7 @@ CONFIG_RPCSEC_GSS_KRB5=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
@@ -772,7 +874,9 @@ CONFIG_SGI_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=15
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -788,28 +892,29 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
CONFIG_CRYPTO=y
CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=y
-CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_DES=y
-CONFIG_CRYPTO_BLOWFISH=y
-CONFIG_CRYPTO_TWOFISH=y
-CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_CAST5=y
-CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
-CONFIG_CRYPTO_TEST=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -819,9 +924,8 @@ CONFIG_CRYPTO_TEST=m
# Library routines
#
# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=m
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig
index b26e1173365d..bf8fb95b21dc 100644
--- a/arch/mips/configs/ip32_defconfig
+++ b/arch/mips/configs/ip32_defconfig
@@ -1,11 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:04 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:07 2005
#
CONFIG_MIPS=y
-CONFIG_64BIT=y
-CONFIG_64BIT=y
#
# Code maturity level options
@@ -13,11 +11,13 @@ CONFIG_64BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
@@ -25,13 +25,16 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +44,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -50,42 +54,71 @@ CONFIG_CC_ALIGN_JUMPS=0
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
# CONFIG_SGI_IP27 is not set
CONFIG_SGI_IP32=y
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_ARC=y
CONFIG_DMA_IP32=y
-CONFIG_OWN_DMA=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_OWN_DMA=y
+CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
CONFIG_ARC32=y
CONFIG_BOOT_ELF32=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
@@ -95,8 +128,10 @@ CONFIG_ARC_PROMLIB=y
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# 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
@@ -112,6 +147,17 @@ CONFIG_CPU_R5000=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_R5000=y
+CONFIG_SYS_HAS_CPU_RM7000=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=y
# CONFIG_PAGE_SIZE_8KB is not set
# CONFIG_PAGE_SIZE_16KB is not set
@@ -119,9 +165,22 @@ CONFIG_PAGE_SIZE_4KB=y
CONFIG_BOARD_SCACHE=y
CONFIG_R5000_CPU_SCACHE=y
CONFIG_RM7000_CPU_SCACHE=y
+# CONFIG_MIPS_MT is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
#
@@ -130,7 +189,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -139,10 +197,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -160,6 +214,80 @@ CONFIG_MIPS32_O32=y
CONFIG_BINFMT_ELF32=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=y
+CONFIG_IEEE80211_CRYPT_CCMP=y
+CONFIG_IEEE80211_CRYPT_TKIP=y
+
+#
# Device Drivers
#
@@ -168,7 +296,12 @@ CONFIG_BINFMT_ELF32=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=y
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
#
# Memory Technology Devices (MTD)
@@ -187,7 +320,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -199,7 +331,6 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
CONFIG_CDROM_PKTCDVD=y
CONFIG_CDROM_PKTCDVD_BUFFERS=8
# CONFIG_CDROM_PKTCDVD_WCACHE is not set
@@ -221,6 +352,7 @@ CONFIG_ATA_OVER_ETH=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=y
CONFIG_SCSI=y
CONFIG_SCSI_PROC_FS=y
@@ -233,6 +365,7 @@ CONFIG_CHR_DEV_OSST=y
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
@@ -244,9 +377,10 @@ CONFIG_SCSI_LOGGING=y
#
# SCSI Transport Attributes
#
-# CONFIG_SCSI_SPI_ATTRS is not set
+CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
+CONFIG_SCSI_SAS_ATTRS=y
#
# SCSI low-level drivers
@@ -266,18 +400,13 @@ CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
CONFIG_SCSI_QLA2XXX=y
@@ -286,6 +415,8 @@ CONFIG_SCSI_QLA2XXX=y
# CONFIG_SCSI_QLA2300 is not set
# CONFIG_SCSI_QLA2322 is not set
# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_DEBUG is not set
@@ -299,6 +430,8 @@ CONFIG_SCSI_QLA2XXX=y
# Fusion MPT device support
#
# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
#
# IEEE 1394 (FireWire) support
@@ -311,78 +444,13 @@ CONFIG_SCSI_QLA2XXX=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-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 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_TUNNEL=y
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=y
-
-#
-# SCTP Configuration (EXPERIMENTAL)
+# Network device support
#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -390,6 +458,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -416,12 +499,16 @@ CONFIG_SGI_O2MACE_ETH=y
# 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_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -434,6 +521,8 @@ CONFIG_SGI_O2MACE_ETH=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=y
#
# Wan interfaces
@@ -446,6 +535,8 @@ CONFIG_SGI_O2MACE_ETH=y
# CONFIG_NET_FC is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -475,27 +566,25 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
CONFIG_SERIO=y
# CONFIG_SERIO_I8042 is not set
CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
# CONFIG_SERIO_PCIPS2 is not set
# CONFIG_SERIO_MACEPS2 is not set
# CONFIG_SERIO_LIBPS2 is not set
CONFIG_SERIO_RAW=y
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
+# CONFIG_GAMEPORT is not set
#
# Character devices
@@ -518,6 +607,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
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
@@ -544,6 +634,11 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -554,10 +649,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -577,7 +682,6 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -587,13 +691,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -611,21 +711,29 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=y
#
# CD-ROM/DVD Filesystems
@@ -646,13 +754,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=y
#
# Miscellaneous filesystems
@@ -676,13 +781,14 @@ CONFIG_RAMFS=y
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
-# CONFIG_EXPORTFS is not set
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -691,6 +797,7 @@ CONFIG_SUNRPC=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
@@ -721,7 +828,9 @@ CONFIG_SGI_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -735,7 +844,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -745,7 +878,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CRC16=y
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/mips/configs/it8172_defconfig b/arch/mips/configs/it8172_defconfig
index 08bd3ad64761..0940771bafb1 100644
--- a/arch/mips/configs/it8172_defconfig
+++ b/arch/mips/configs/it8172_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:05 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:09 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,11 +11,13 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
@@ -26,13 +25,16 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
# CONFIG_HOTPLUG is not set
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -42,6 +44,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -57,41 +60,69 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
CONFIG_MIPS_ITE8172=y
-# CONFIG_IT8172_REVC is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_IT8172_REVC is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_ITE_BOARD_GEN=y
CONFIG_IT8172_CIR=y
CONFIG_IT8712=y
@@ -100,8 +131,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# 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
@@ -117,14 +150,39 @@ CONFIG_CPU_NEVADA=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_R5432=y
+CONFIG_SYS_HAS_CPU_NEVADA=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=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_64KB is not set
+# CONFIG_MIPS_MT is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -140,10 +198,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
@@ -155,6 +209,80 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -166,12 +294,17 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
+
+#
# Memory Technology Devices (MTD)
#
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
-# CONFIG_MTD_PARTITIONS is not set
# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_PARTITIONS is not set
#
# User Modules And Translation Layers
@@ -207,7 +340,6 @@ CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_XIP is not set
#
# Mapping drivers for chip access
@@ -217,6 +349,7 @@ CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_PHYSMAP_START=0x8000000
CONFIG_MTD_PHYSMAP_LEN=0x2000000
CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
@@ -251,14 +384,12 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -302,6 +433,7 @@ CONFIG_IDE_GENERIC=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
# CONFIG_SCSI is not set
#
@@ -312,6 +444,7 @@ CONFIG_IDE_GENERIC=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -322,78 +455,28 @@ CONFIG_IDE_GENERIC=y
#
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
+# Network device support
#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-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 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_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
#
-# SCTP Configuration (EXPERIMENTAL)
+# PHY device support
#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
#
-# QoS and/or fair queueing
+# MII PHY device drivers
#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
#
# Ethernet (10 or 100Mbit)
@@ -426,6 +509,8 @@ CONFIG_NET_ETHERNET=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -455,18 +540,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -476,6 +549,16 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -521,10 +604,13 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -535,10 +621,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -558,7 +654,6 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -574,15 +669,9 @@ CONFIG_SOUND=y
# Open Sound System
#
CONFIG_SOUND_PRIME=y
-# CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_SONICVIBES is not set
CONFIG_SOUND_IT8172=y
-# CONFIG_SOUND_TRIDENT is not set
# CONFIG_SOUND_MSNDCLAS is not set
# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_OSS is not set
# CONFIG_SOUND_AD1980 is not set
#
@@ -592,10 +681,6 @@ CONFIG_SOUND_IT8172=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
@@ -608,24 +693,31 @@ CONFIG_SOUND_IT8172=y
#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -646,12 +738,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -682,7 +772,7 @@ CONFIG_NFS_FS=y
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
-# CONFIG_EXPORTFS is not set
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -691,6 +781,7 @@ CONFIG_SUNRPC=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
@@ -711,7 +802,9 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -725,7 +818,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -735,7 +852,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
+CONFIG_CRC16=m
+CONFIG_CRC32=m
CONFIG_LIBCRC32C=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/ivr_defconfig b/arch/mips/configs/ivr_defconfig
index 583ef5c5b1cd..9ba61dfc490d 100644
--- a/arch/mips/configs/ivr_defconfig
+++ b/arch/mips/configs/ivr_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:05 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:12 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,11 +11,13 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
@@ -26,13 +25,16 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -42,6 +44,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -57,40 +60,68 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
CONFIG_MIPS_IVR=y
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_ITE_BOARD_GEN=y
CONFIG_IT8172_CIR=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
@@ -98,8 +129,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# 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
@@ -115,14 +148,38 @@ CONFIG_CPU_NEVADA=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_NEVADA=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=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_64KB is not set
+# CONFIG_MIPS_MT is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -131,7 +188,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -140,10 +196,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -156,6 +208,80 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -164,7 +290,12 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
@@ -183,7 +314,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -194,7 +324,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -239,6 +368,7 @@ CONFIG_IDE_GENERIC=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
# CONFIG_SCSI is not set
#
@@ -249,6 +379,7 @@ CONFIG_IDE_GENERIC=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -261,78 +392,13 @@ CONFIG_IDE_GENERIC=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-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 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_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
+# Network device support
#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -340,6 +406,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -365,12 +446,16 @@ CONFIG_NET_ETHERNET=y
# 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_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -383,6 +468,8 @@ CONFIG_NET_ETHERNET=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# Wan interfaces
@@ -394,6 +481,8 @@ CONFIG_NET_ETHERNET=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -423,19 +512,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -445,6 +521,17 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -467,6 +554,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
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
@@ -492,6 +580,11 @@ CONFIG_RTC=y
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -502,10 +595,20 @@ CONFIG_RTC=y
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -525,7 +628,6 @@ CONFIG_RTC=y
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -535,13 +637,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -559,21 +657,29 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -594,12 +700,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -628,7 +732,7 @@ CONFIG_NFS_FS=y
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
-# CONFIG_EXPORTFS is not set
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -637,6 +741,7 @@ CONFIG_SUNRPC=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
@@ -657,7 +762,9 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -671,7 +778,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -681,7 +812,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
+CONFIG_CRC16=m
+CONFIG_CRC32=m
CONFIG_LIBCRC32C=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/jaguar-atx_defconfig b/arch/mips/configs/jaguar-atx_defconfig
index 8abb5a0c6c12..21b2b8042f91 100644
--- a/arch/mips/configs/jaguar-atx_defconfig
+++ b/arch/mips/configs/jaguar-atx_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:05 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:14 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
# CONFIG_EXPERIMENTAL is not set
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -54,36 +57,70 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+CONFIG_MOMENCO_JAGUAR_ATX=y
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-CONFIG_MOMENCO_JAGUAR_ATX=y
-CONFIG_JAGUAR_DMALOW=y
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+CONFIG_JAGUAR_DMALOW=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
CONFIG_LIMITED_DMA=y
+CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_IRQ_CPU_RM7K=y
CONFIG_IRQ_MV64340=y
@@ -95,8 +132,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# 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
@@ -112,6 +151,17 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
# CONFIG_CPU_RM7000 is not set
CONFIG_CPU_RM9000=y
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_RM9000=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=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
@@ -119,13 +169,24 @@ CONFIG_PAGE_SIZE_4KB=y
CONFIG_BOARD_SCACHE=y
CONFIG_RM7000_CPU_SCACHE=y
CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
# CONFIG_64BIT_PHYS_ADDR is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_HIGHMEM=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_SYS_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -134,7 +195,6 @@ CONFIG_HIGHMEM=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -143,10 +203,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
@@ -158,6 +214,68 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_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_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+# CONFIG_NETFILTER is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -166,7 +284,12 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
@@ -185,7 +308,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -195,7 +317,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -218,6 +339,7 @@ CONFIG_ATA_OVER_ETH=m
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
# CONFIG_SCSI is not set
#
@@ -228,6 +350,7 @@ CONFIG_ATA_OVER_ETH=m
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -240,58 +363,8 @@ CONFIG_ATA_OVER_ETH=m
# CONFIG_I2O is not set
#
-# Networking support
+# Network device support
#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_PACKET is not set
-# CONFIG_NETLINK_DEV 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_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_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_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
@@ -304,6 +377,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -343,9 +431,11 @@ CONFIG_EEPRO100=y
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
CONFIG_MV643XX_ETH=y
CONFIG_MV643XX_ETH_0=y
CONFIG_MV643XX_ETH_1=y
@@ -354,6 +444,7 @@ CONFIG_MV643XX_ETH_2=y
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -366,6 +457,8 @@ CONFIG_MV643XX_ETH_2=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# Wan interfaces
@@ -374,6 +467,8 @@ CONFIG_MV643XX_ETH_2=y
# CONFIG_FDDI is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -391,20 +486,10 @@ CONFIG_MV643XX_ETH_2=y
# CONFIG_INPUT is not set
#
-# Userland interfaces
-#
-
-#
-# Input I/O drivers
+# Hardware I/O ports
#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
# CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
-#
-# Input Device Drivers
-#
+# CONFIG_GAMEPORT is not set
#
# Character devices
@@ -425,6 +510,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
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
@@ -451,6 +537,10 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -461,10 +551,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -478,7 +578,6 @@ CONFIG_LEGACY_PTY_COUNT=256
# Graphics support
#
# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -488,13 +587,9 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -512,6 +607,10 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
# CONFIG_EXT2_FS is not set
@@ -519,13 +618,16 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -546,10 +648,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVPTS_FS_XATTR is not set
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -570,7 +672,7 @@ CONFIG_NFS_FS=y
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
-# CONFIG_EXPORTFS is not set
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_SMB_FS is not set
# CONFIG_CIFS is not set
@@ -591,7 +693,9 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -605,7 +709,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -615,7 +743,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CRC16=m
+CONFIG_CRC32=m
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig
index da5d9ee2ecce..9a728c2d8fd5 100644
--- a/arch/mips/configs/jmr3927_defconfig
+++ b/arch/mips/configs/jmr3927_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:06 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:17 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -50,40 +53,68 @@ CONFIG_CC_ALIGN_JUMPS=0
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-CONFIG_TOSHIBA_JMR3927=y
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+CONFIG_TOSHIBA_JMR3927=y
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
CONFIG_MIPS_TX3927=y
CONFIG_SWAP_IO_SPACE=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
@@ -92,8 +123,10 @@ CONFIG_TOSHIBA_BOARDS=y
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# 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=y
# CONFIG_CPU_VR41XX is not set
@@ -109,12 +142,34 @@ CONFIG_CPU_TX39XX=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_TX39XX=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=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_64KB is not set
+# CONFIG_MIPS_MT is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
CONFIG_RTC_DS1742=y
@@ -124,7 +179,6 @@ CONFIG_RTC_DS1742=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -133,10 +187,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -149,6 +199,80 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=y
+CONFIG_IEEE80211_CRYPT_CCMP=y
+CONFIG_IEEE80211_CRYPT_TKIP=y
+
+#
# Device Drivers
#
@@ -157,7 +281,12 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=y
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
#
# Memory Technology Devices (MTD)
@@ -176,7 +305,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -187,7 +315,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=y
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -210,6 +337,7 @@ CONFIG_ATA_OVER_ETH=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=y
# CONFIG_SCSI is not set
#
@@ -220,6 +348,7 @@ CONFIG_ATA_OVER_ETH=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -232,78 +361,13 @@ CONFIG_ATA_OVER_ETH=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-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 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_TUNNEL=y
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=y
-
-#
-# SCTP Configuration (EXPERIMENTAL)
+# Network device support
#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -311,6 +375,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -336,12 +415,16 @@ CONFIG_NET_ETHERNET=y
# 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_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -354,6 +437,8 @@ CONFIG_NET_ETHERNET=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=y
#
# Wan interfaces
@@ -365,6 +450,8 @@ CONFIG_NET_ETHERNET=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -394,19 +481,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=y
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -416,6 +490,17 @@ CONFIG_SERIO_RAW=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=y
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -426,11 +511,9 @@ CONFIG_SERIAL_NONSTANDARD=y
# CONFIG_ROCKETPORT is not set
# CONFIG_CYCLADES is not set
# CONFIG_DIGIEPCA is not set
-# CONFIG_DIGI is not set
# CONFIG_MOXA_INTELLIO is not set
# CONFIG_MOXA_SMARTIO is not set
# CONFIG_ISI is not set
-# CONFIG_SYNCLINK is not set
# CONFIG_SYNCLINKMP is not set
# CONFIG_N_HDLC is not set
# CONFIG_RISCOM8 is not set
@@ -438,10 +521,6 @@ CONFIG_SERIAL_NONSTANDARD=y
# CONFIG_SX is not set
# CONFIG_RIO is not set
# CONFIG_STALDRV is not set
-# CONFIG_SERIAL_TX3912 is not set
-CONFIG_TXX927_SERIAL=y
-CONFIG_TXX927_SERIAL_CONSOLE=y
-# CONFIG_SERIAL_TXX9 is not set
#
# Serial drivers
@@ -451,6 +530,8 @@ CONFIG_TXX927_SERIAL_CONSOLE=y
#
# Non-8250 serial port support
#
+CONFIG_HAS_TXX9_SERIAL=y
+# CONFIG_SERIAL_JSM is not set
# CONFIG_UNIX98_PTYS is not set
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -477,6 +558,11 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -487,10 +573,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -504,6 +600,11 @@ CONFIG_LEGACY_PTY_COUNT=256
# Graphics support
#
CONFIG_FB=y
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_SOFT_CURSOR is not set
+# CONFIG_FB_MACMODES is not set
# CONFIG_FB_MODE_HELPERS is not set
# CONFIG_FB_TILEBLITTING is not set
# CONFIG_FB_CIRRUS is not set
@@ -511,6 +612,7 @@ CONFIG_FB=y
# CONFIG_FB_CYBER2000 is not set
# CONFIG_FB_ASILIANT is not set
# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
# CONFIG_FB_MATROX is not set
# CONFIG_FB_RADEON_OLD is not set
@@ -523,8 +625,11 @@ CONFIG_FB=y
# CONFIG_FB_KYRO is not set
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_SMIVGX is not set
+# CONFIG_FB_CYBLA is not set
# CONFIG_FB_TRIDENT is not set
# CONFIG_FB_E1356 is not set
+# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_VIRTUAL is not set
#
@@ -548,13 +653,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -572,6 +673,10 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
# CONFIG_EXT2_FS is not set
@@ -579,13 +684,16 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=y
#
# CD-ROM/DVD Filesystems
@@ -606,10 +714,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=y
#
# Miscellaneous filesystems
@@ -638,7 +746,7 @@ CONFIG_NFS_FS=y
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
-# CONFIG_EXPORTFS is not set
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -647,6 +755,7 @@ CONFIG_SUNRPC=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
@@ -667,7 +776,9 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -681,7 +792,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -691,7 +826,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CRC16=y
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/mips/configs/lasat200_defconfig b/arch/mips/configs/lasat200_defconfig
index 8d600ae890f4..03cd0ca6e639 100644
--- a/arch/mips/configs/lasat200_defconfig
+++ b/arch/mips/configs/lasat200_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:06 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:19 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,53 +59,83 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-CONFIG_LASAT=y
-CONFIG_PICVUE=y
-CONFIG_PICVUE_PROC=y
-CONFIG_DS1603=y
-CONFIG_LASAT_SYSCTL=y
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+CONFIG_LASAT=y
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+CONFIG_PICVUE=y
+CONFIG_PICVUE_PROC=y
+CONFIG_DS1603=y
+CONFIG_LASAT_SYSCTL=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
CONFIG_MIPS_NILE4=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_MIPS_GT64120=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# 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
@@ -118,17 +151,41 @@ CONFIG_CPU_R5000=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_R5000=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=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_64KB is not set
CONFIG_BOARD_SCACHE=y
CONFIG_R5000_CPU_SCACHE=y
+# CONFIG_MIPS_MT is not set
# CONFIG_64BIT_PHYS_ADDR is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -137,7 +194,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-# CONFIG_PCI_NAMES is not set
CONFIG_MMU=y
#
@@ -146,10 +202,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -162,6 +214,76 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+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_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -170,15 +292,20 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
#
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
@@ -223,6 +350,7 @@ CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_PHYSMAP is not set
CONFIG_MTD_LASAT=y
+# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
@@ -258,7 +386,6 @@ CONFIG_MTD_LASAT=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -269,7 +396,6 @@ CONFIG_MTD_LASAT=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -326,6 +452,7 @@ CONFIG_BLK_DEV_CMD64X=y
# CONFIG_BLK_DEV_HPT366 is not set
# CONFIG_BLK_DEV_SC1200 is not set
# CONFIG_BLK_DEV_PIIX 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
@@ -343,6 +470,7 @@ CONFIG_IDEDMA_AUTO=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
# CONFIG_SCSI is not set
#
@@ -353,6 +481,7 @@ CONFIG_IDEDMA_AUTO=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -365,68 +494,8 @@ CONFIG_IDEDMA_AUTO=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_PACKET is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# 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_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
+# Network device support
#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
@@ -439,6 +508,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -464,12 +548,16 @@ CONFIG_NET_ETHERNET=y
# 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_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -482,6 +570,8 @@ CONFIG_NET_ETHERNET=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# Wan interfaces
@@ -493,6 +583,8 @@ CONFIG_NET_ETHERNET=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -522,19 +614,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -544,6 +623,17 @@ CONFIG_SERIO_RAW=m
# 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 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -564,6 +654,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
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
@@ -590,6 +681,11 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -600,10 +696,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -623,7 +729,6 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -633,13 +738,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -657,10 +758,15 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -670,13 +776,16 @@ CONFIG_JBD=y
CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -697,12 +806,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -728,12 +835,13 @@ CONFIG_RAMFS=y
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
# CONFIG_NFSD is not set
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
-# CONFIG_EXPORTFS is not set
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -742,6 +850,7 @@ CONFIG_SUNRPC=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
@@ -762,7 +871,9 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -776,7 +887,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -786,7 +921,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=m
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig
index 79519ac5af4a..2acdec959dd0 100644
--- a/arch/mips/configs/malta_defconfig
+++ b/arch/mips/configs/malta_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:53:14 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:22 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,44 +59,75 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
CONFIG_MIPS_MALTA=y
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_I8259=y
CONFIG_MIPS_BONITO64=y
CONFIG_MIPS_MSC=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_IRQ_CPU=y
CONFIG_MIPS_BOARDS_GEN=y
CONFIG_MIPS_GT64120=y
CONFIG_SWAP_IO_SPACE=y
@@ -104,8 +138,10 @@ CONFIG_HAVE_STD_PC_SERIAL_PORT=y
#
# CPU selection
#
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS64 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
@@ -121,14 +157,48 @@ CONFIG_CPU_MIPS32=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_SYS_HAS_CPU_MIPS32_R2=y
+CONFIG_SYS_HAS_CPU_MIPS64_R1=y
+CONFIG_SYS_HAS_CPU_NEVADA=y
+CONFIG_SYS_HAS_CPU_RM7000=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=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_64KB is not set
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_MIPS_MT=y
+# CONFIG_MIPS_MT_SMP is not set
+CONFIG_MIPS_VPE_LOADER=y
+CONFIG_MIPS_VPE_LOADER_TOM=y
+CONFIG_MIPS_VPE_APSP_API=y
# CONFIG_64BIT_PHYS_ADDR is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -137,7 +207,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -146,10 +215,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -162,229 +227,7 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=y
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-CONFIG_BLK_DEV_FD=m
-# 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=m
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_BLK_DEV_NBD=m
-# CONFIG_BLK_DEV_SX8 is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_ATA_OVER_ETH=m
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-CONFIG_BLK_DEV_IDECD=y
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-CONFIG_BLK_DEV_IDEPCI=y
-# CONFIG_IDEPCI_SHARE_IRQ is not set
-# 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_IDEDMA_FORCED is not set
-CONFIG_IDEDMA_PCI_AUTO=y
-# CONFIG_IDEDMA_ONLYDISK is not set
-# 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_CY82C693 is not set
-# CONFIG_BLK_DEV_CS5520 is not set
-# CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_HPT34X is not set
-# CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_BLK_DEV_SC1200 is not set
-CONFIG_BLK_DEV_PIIX=y
-# 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 is not set
-# CONFIG_IDE_ARM is not set
-CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_IDEDMA_IVB is not set
-CONFIG_IDEDMA_AUTO=y
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-CONFIG_SCSI=m
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=m
-CONFIG_CHR_DEV_ST=m
-CONFIG_CHR_DEV_OSST=m
-CONFIG_BLK_DEV_SR=m
-CONFIG_BLK_DEV_SR_VENDOR=y
-CONFIG_CHR_DEV_SG=m
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_LOGGING=y
-
-#
-# SCSI Transport Attributes
-#
-CONFIG_SCSI_SPI_ATTRS=m
-CONFIG_SCSI_FC_ATTRS=m
-CONFIG_SCSI_ISCSI_ATTRS=m
-
-#
-# SCSI low-level drivers
-#
-CONFIG_BLK_DEV_3W_XXXX_RAID=m
-CONFIG_SCSI_3W_9XXX=m
-CONFIG_SCSI_ACARD=m
-CONFIG_SCSI_AACRAID=m
-CONFIG_SCSI_AIC7XXX=m
-CONFIG_AIC7XXX_CMDS_PER_DEVICE=32
-CONFIG_AIC7XXX_RESET_DELAY_MS=15000
-# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
-CONFIG_AIC7XXX_DEBUG_MASK=0
-CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_MEGARAID_NEWGEN is not set
-# CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=m
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_DC395x is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
-CONFIG_MD_LINEAR=m
-CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_RAID10=m
-CONFIG_MD_RAID5=m
-CONFIG_MD_RAID6=m
-CONFIG_MD_MULTIPATH=m
-CONFIG_MD_FAULTY=m
-CONFIG_BLK_DEV_DM=m
-CONFIG_DM_CRYPT=m
-CONFIG_DM_SNAPSHOT=m
-CONFIG_DM_MIRROR=m
-CONFIG_DM_ZERO=m
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-
-#
-# Networking support
+# Networking
#
CONFIG_NET=y
@@ -393,15 +236,20 @@ CONFIG_NET=y
#
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
CONFIG_NET_KEY=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_FWMARK=y
CONFIG_IP_ROUTE_MULTIPATH=y
+# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
@@ -419,8 +267,10 @@ CONFIG_INET_AH=m
CONFIG_INET_ESP=m
CONFIG_INET_IPCOMP=m
CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-CONFIG_IP_TCPDIAG_IPV6=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
#
# IP: Virtual Server Configuration
@@ -465,6 +315,9 @@ CONFIG_IPV6_TUNNEL=m
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
CONFIG_BRIDGE_NETFILTER=y
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
#
# IP: Netfilter Configuration
@@ -472,11 +325,15 @@ CONFIG_BRIDGE_NETFILTER=y
CONFIG_IP_NF_CONNTRACK=m
CONFIG_IP_NF_CT_ACCT=y
CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CONNTRACK_EVENTS=y
+CONFIG_IP_NF_CONNTRACK_NETLINK=m
CONFIG_IP_NF_CT_PROTO_SCTP=m
CONFIG_IP_NF_FTP=m
CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_NETBIOS_NS is not set
CONFIG_IP_NF_TFTP=m
CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_PPTP=m
CONFIG_IP_NF_QUEUE=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_LIMIT=m
@@ -501,9 +358,12 @@ CONFIG_IP_NF_MATCH_PHYSDEV=m
CONFIG_IP_NF_MATCH_ADDRTYPE=m
CONFIG_IP_NF_MATCH_REALM=m
CONFIG_IP_NF_MATCH_SCTP=m
+CONFIG_IP_NF_MATCH_DCCP=m
CONFIG_IP_NF_MATCH_COMMENT=m
CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_CONNBYTES=m
CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_MATCH_STRING=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_TARGET_LOG=m
@@ -520,12 +380,14 @@ CONFIG_IP_NF_NAT_IRC=m
CONFIG_IP_NF_NAT_FTP=m
CONFIG_IP_NF_NAT_TFTP=m
CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_NAT_PPTP=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_TOS=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_DSCP=m
CONFIG_IP_NF_TARGET_MARK=m
CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_TARGET_CONNMARK=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_RAW=m
@@ -535,7 +397,7 @@ CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
#
-# IPv6: Netfilter Configuration
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
#
CONFIG_IP6_NF_QUEUE=m
CONFIG_IP6_NF_IPTABLES=m
@@ -555,8 +417,10 @@ CONFIG_IP6_NF_MATCH_EUI64=m
CONFIG_IP6_NF_MATCH_PHYSDEV=m
CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_TARGET_REJECT=m
CONFIG_IP6_NF_MANGLE=m
CONFIG_IP6_NF_TARGET_MARK=m
+CONFIG_IP6_NF_TARGET_HL=m
CONFIG_IP6_NF_RAW=m
#
@@ -582,8 +446,11 @@ CONFIG_BRIDGE_EBT_REDIRECT=m
CONFIG_BRIDGE_EBT_SNAT=m
CONFIG_BRIDGE_EBT_LOG=m
CONFIG_BRIDGE_EBT_ULOG=m
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
#
# SCTP Configuration (EXPERIMENTAL)
@@ -611,10 +478,6 @@ CONFIG_IPDDP_DECAP=y
CONFIG_NET_DIVERT=y
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_CLK_JIFFIES=y
# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
@@ -634,6 +497,7 @@ CONFIG_NET_SCH_INGRESS=m
CONFIG_NET_QOS=y
CONFIG_NET_ESTIMATOR=y
CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
CONFIG_NET_CLS_TCINDEX=m
CONFIG_NET_CLS_ROUTE4=m
CONFIG_NET_CLS_ROUTE=y
@@ -644,6 +508,7 @@ CONFIG_NET_CLS_IND=y
# CONFIG_CLS_U32_MARK is not set
CONFIG_NET_CLS_RSVP=m
CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_EMATCH is not set
# CONFIG_NET_CLS_ACT is not set
CONFIG_NET_CLS_POLICE=y
@@ -651,17 +516,254 @@ CONFIG_NET_CLS_POLICE=y
# Network testing
#
# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=m
+# 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=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+# 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_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+# 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_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_PIIX=y
+# 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 is not set
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=32
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+CONFIG_SCSI_QLA2XXX=m
+# CONFIG_SCSI_QLA21XX is not set
+# CONFIG_SCSI_QLA22XX is not set
+# CONFIG_SCSI_QLA2300 is not set
+# CONFIG_SCSI_QLA2322 is not set
+# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID5=m
+CONFIG_MD_RAID6=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
CONFIG_NETDEVICES=y
CONFIG_DUMMY=m
CONFIG_BONDING=m
CONFIG_EQUALIZER=m
CONFIG_TUN=m
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -669,6 +771,21 @@ CONFIG_TUN=m
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -713,13 +830,17 @@ CONFIG_PCNET32=y
# 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_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -732,6 +853,8 @@ CONFIG_PCNET32=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# Wan interfaces
@@ -744,6 +867,8 @@ CONFIG_PCNET32=y
# CONFIG_NET_FC is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -773,19 +898,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -795,6 +907,17 @@ CONFIG_SERIO_SERPORT=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -815,6 +938,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
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
@@ -840,6 +964,11 @@ CONFIG_RTC=y
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -850,10 +979,20 @@ CONFIG_RTC=y
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -873,7 +1012,6 @@ CONFIG_RTC=y
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -883,13 +1021,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -907,10 +1041,15 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -931,12 +1070,14 @@ CONFIG_JFS_SECURITY=y
# CONFIG_JFS_STATISTICS is not set
CONFIG_FS_POSIX_ACL=y
CONFIG_XFS_FS=m
-# CONFIG_XFS_RT is not set
-CONFIG_XFS_QUOTA=y
+CONFIG_XFS_EXPORT=y
+CONFIG_XFS_QUOTA=m
CONFIG_XFS_SECURITY=y
CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
CONFIG_MINIX_FS=m
CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
CONFIG_QUOTA=y
# CONFIG_QFMT_V1 is not set
CONFIG_QFMT_V2=y
@@ -944,6 +1085,7 @@ CONFIG_QUOTACTL=y
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=y
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -971,12 +1113,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -1002,16 +1142,19 @@ CONFIG_UFS_FS=m
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
CONFIG_NFSD=y
CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
# CONFIG_NFSD_V4 is not set
# CONFIG_NFSD_TCP is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -1020,6 +1163,7 @@ CONFIG_SUNRPC=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
@@ -1079,7 +1223,9 @@ CONFIG_NLS_UTF8=m
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -1101,6 +1247,7 @@ CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_DES=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_TWOFISH=m
@@ -1125,9 +1272,12 @@ CONFIG_CRYPTO_CRC32C=m
# Library routines
#
# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=m
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=m
CONFIG_ZLIB_DEFLATE=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig
new file mode 100644
index 000000000000..fb9bdd9e3151
--- /dev/null
+++ b/arch/mips/configs/mipssim_defconfig
@@ -0,0 +1,775 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:25 2005
+#
+CONFIG_MIPS=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+CONFIG_MIPS_SIM=y
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_IRQ_CPU=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+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_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_MIPS32_R1=y
+CONFIG_SYS_HAS_CPU_MIPS32_R2=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=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_64KB is not set
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_MIPS_MT=y
+# CONFIG_MIPS_MT_SMP is not set
+CONFIG_MIPS_VPE_LOADER=y
+CONFIG_MIPS_VPE_LOADER_TOM=y
+CONFIG_MIPS_VPE_APSP_API=y
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Networking
+#
+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_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+CONFIG_NET_DIVERT=y
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CLK_JIFFIES=y
+# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
+# CONFIG_NET_SCH_CLK_CPU is not set
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_QOS=y
+CONFIG_NET_ESTIMATOR=y
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+# CONFIG_NET_CLS_FW is not set
+# CONFIG_NET_CLS_U32 is not set
+# CONFIG_NET_CLS_RSVP is not set
+# CONFIG_NET_CLS_RSVP6 is not set
+# CONFIG_NET_EMATCH is not set
+# CONFIG_NET_CLS_ACT is not set
+# CONFIG_NET_CLS_POLICE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=y
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+# CONFIG_LBD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+
+#
+# Ethernet (10 or 100Mbit)
+#
+# CONFIG_NET_ETHERNET is not set
+# CONFIG_MIPS_SIM_NET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=1
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+
+#
+# SN Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+CONFIG_ROMFS_FS=y
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+# CONFIG_SYSFS is not set
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE="nfsroot=192.168.192.169:/u1/mipsel,timeo=20 ip=dhcp"
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_KGDB is not set
+# CONFIG_RUNTIME_DEBUG is not set
+# CONFIG_MIPS_UNCACHED is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
diff --git a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig
index 0fea57ef18f2..e2c082128532 100644
--- a/arch/mips/configs/mpc30x_defconfig
+++ b/arch/mips/configs/mpc30x_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:07 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:28 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,57 +59,86 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-CONFIG_MACH_VR41XX=y
-# CONFIG_NEC_CMBVR4133 is not set
-# CONFIG_CASIO_E55 is not set
-# CONFIG_IBM_WORKPAD is not set
-# CONFIG_TANBAC_TB0226 is not set
-# CONFIG_TANBAC_TB0229 is not set
-CONFIG_VICTOR_MPC30X=y
-# CONFIG_ZAO_CAPCELLA is not set
-CONFIG_PCI_VR41XX=y
-CONFIG_VRC4173=y
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+CONFIG_MACH_VR41XX=y
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_NEC_CMBVR4133 is not set
+# CONFIG_CASIO_E55 is not set
+# CONFIG_IBM_WORKPAD is not set
+# CONFIG_TANBAC_TB022X is not set
+CONFIG_VICTOR_MPC30X=y
+# CONFIG_ZAO_CAPCELLA is not set
+CONFIG_PCI_VR41XX=y
+CONFIG_VRC4173=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# 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=y
@@ -122,12 +154,36 @@ CONFIG_CPU_VR41XX=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_VR41XX=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=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_64KB is not set
+# CONFIG_MIPS_MT is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -136,17 +192,26 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
# PCCARD (PCMCIA/CardBus) support
#
-# CONFIG_PCCARD is not set
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+# CONFIG_CARDBUS is not set
#
# PC-card bridges
#
+# CONFIG_YENTA is not set
+# CONFIG_PD6729 is not set
+# CONFIG_I82092 is not set
+# CONFIG_TCIC is not set
+CONFIG_PCMCIA_VRC4173=y
#
# PCI Hotplug Support
@@ -161,6 +226,78 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# 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_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_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -169,7 +306,12 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=y
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
@@ -188,7 +330,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -197,13 +338,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_BLK_DEV_LOOP is not set
# 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 is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+# CONFIG_CDROM_PKTCDVD is not set
#
# IO Schedulers
@@ -217,11 +356,35 @@ CONFIG_ATA_OVER_ETH=m
#
# ATA/ATAPI/MFM/RLL support
#
-# CONFIG_IDE is not set
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECS=m
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_IDEPCI is not set
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
#
@@ -232,6 +395,7 @@ CONFIG_ATA_OVER_ETH=m
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -244,79 +408,13 @@ CONFIG_ATA_OVER_ETH=m
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-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 is not set
-# CONFIG_NET_IPGRE is not set
-# 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_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
+# Network device support
#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -324,20 +422,14 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
-# Ethernet (10 or 100Mbit)
+# PHY device support
#
-CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_NET_VENDOR_3COM is not set
#
-# Tulip family network device support
+# Ethernet (10 or 100Mbit)
#
-# CONFIG_NET_TULIP is not set
-# CONFIG_HP100 is not set
-# CONFIG_NET_PCI is not set
+# CONFIG_NET_ETHERNET is not set
+CONFIG_MII=m
#
# Ethernet (1000 Mbit)
@@ -349,12 +441,16 @@ CONFIG_NET_ETHERNET=y
# 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_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -366,7 +462,59 @@ CONFIG_NET_ETHERNET=y
#
# Wireless LAN (non-hamradio)
#
-# CONFIG_NET_RADIO is not set
+CONFIG_NET_RADIO=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+# CONFIG_PCMCIA_WAVELAN is not set
+# CONFIG_PCMCIA_NETWAVE is not set
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
+CONFIG_HERMES=m
+# CONFIG_PLX_HERMES is not set
+# CONFIG_TMD_HERMES is not set
+# CONFIG_NORTEL_HERMES is not set
+# CONFIG_PCI_HERMES is not set
+# CONFIG_ATMEL is not set
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+# CONFIG_PCMCIA_SPECTRUM is not set
+# CONFIG_AIRO_CS is not set
+# CONFIG_PCMCIA_WL3501 is not set
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
#
# Wan interfaces
@@ -378,6 +526,8 @@ CONFIG_NET_ETHERNET=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -407,19 +557,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -429,6 +566,17 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -439,16 +587,16 @@ CONFIG_HW_CONSOLE=y
#
# Serial drivers
#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250 is not set
#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_VR41XX=y
+CONFIG_SERIAL_VR41XX_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -472,9 +620,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# Ftape, the floppy tape device driver
#
# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+CONFIG_GPIO_VR41XX=y
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -485,10 +644,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -508,7 +677,6 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -518,13 +686,120 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB=m
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_BLUETOOTH_TTY is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
#
+# CONFIG_USB_STORAGE is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+CONFIG_USB_PEGASUS=m
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_MON is not set
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
#
# USB Gadget Support
@@ -542,21 +817,29 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=y
CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -577,12 +860,10 @@ CONFIG_AUTOFS4_FS=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -609,9 +890,8 @@ CONFIG_NFS_FS=y
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
# CONFIG_NFSD is not set
-CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
-# CONFIG_EXPORTFS is not set
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -620,6 +900,7 @@ CONFIG_SUNRPC=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
@@ -640,9 +921,11 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
+CONFIG_CMDLINE="mem=32M console=ttyVR0,19200"
#
# Security options
@@ -656,26 +939,27 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
CONFIG_CRYPTO=y
CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=y
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-CONFIG_CRYPTO_TWOFISH=y
-# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
-# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
# CONFIG_CRYPTO_TEST is not set
@@ -687,9 +971,8 @@ CONFIG_CRYPTO_CRC32C=m
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
+CONFIG_CRC16=m
+CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/ocelot_3_defconfig b/arch/mips/configs/ocelot_3_defconfig
index b4cf97a732bc..ffb23fcab862 100644
--- a/arch/mips/configs/ocelot_3_defconfig
+++ b/arch/mips/configs/ocelot_3_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:07 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:30 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,25 +11,30 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -42,6 +44,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -57,40 +60,68 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
CONFIG_MOMENCO_OCELOT_3=y
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_IRQ_CPU_RM7K=y
CONFIG_IRQ_MV64340=y
@@ -102,8 +133,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# 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
@@ -119,6 +152,17 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
# CONFIG_CPU_RM7000 is not set
CONFIG_CPU_RM9000=y
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_RM9000=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=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
@@ -126,13 +170,26 @@ CONFIG_PAGE_SIZE_4KB=y
CONFIG_BOARD_SCACHE=y
CONFIG_RM7000_CPU_SCACHE=y
CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
# CONFIG_64BIT_PHYS_ADDR is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
-# CONFIG_HIGHMEM is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_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 is not set
# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -141,7 +198,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -150,10 +206,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -166,6 +218,110 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_IPV6_TUNNEL is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_PPTP=m
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP6_NF_QUEUE is not set
+# CONFIG_IP6_NF_IPTABLES is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -174,7 +330,12 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
@@ -193,7 +354,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -205,7 +365,6 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
# CONFIG_CDROM_PKTCDVD is not set
@@ -226,6 +385,7 @@ CONFIG_ATA_OVER_ETH=m
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
CONFIG_SCSI=m
CONFIG_SCSI_PROC_FS=y
@@ -237,6 +397,7 @@ CONFIG_SCSI_PROC_FS=y
# CONFIG_CHR_DEV_OSST is not set
# CONFIG_BLK_DEV_SR is not set
# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -251,6 +412,7 @@ CONFIG_SCSI_PROC_FS=y
# 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=m
#
# SCSI low-level drivers
@@ -266,18 +428,13 @@ CONFIG_SCSI_PROC_FS=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
CONFIG_SCSI_QLA2XXX=m
@@ -286,6 +443,8 @@ CONFIG_SCSI_QLA2XXX=m
# CONFIG_SCSI_QLA2300 is not set
# CONFIG_SCSI_QLA2322 is not set
# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
@@ -300,6 +459,8 @@ CONFIG_SCSI_QLA2XXX=m
# Fusion MPT device support
#
# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
#
# IEEE 1394 (FireWire) support
@@ -312,105 +473,13 @@ CONFIG_SCSI_QLA2XXX=m
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=m
-CONFIG_IP_TCPDIAG_IPV6=y
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-CONFIG_IPV6=m
-# CONFIG_IPV6_PRIVACY is not set
-# CONFIG_INET6_AH is not set
-# CONFIG_INET6_ESP is not set
-# CONFIG_INET6_IPCOMP is not set
-# CONFIG_INET6_TUNNEL is not set
-# CONFIG_IPV6_TUNNEL is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_IP_NF_CONNTRACK is not set
-# CONFIG_IP_NF_CONNTRACK_MARK is not set
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-
-#
-# IPv6: Netfilter Configuration
-#
-# CONFIG_IP6_NF_QUEUE is not set
-# CONFIG_IP6_NF_IPTABLES is not set
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
+# Network device support
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
CONFIG_TUN=m
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -418,6 +487,21 @@ CONFIG_TUN=m
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -440,7 +524,6 @@ CONFIG_NET_PCI=y
# CONFIG_DGRS is not set
# CONFIG_EEPRO100 is not set
CONFIG_E100=y
-# CONFIG_E100_NAPI is not set
# CONFIG_FEALNX is not set
# CONFIG_NATSEMI is not set
# CONFIG_NE2K_PCI is not set
@@ -463,9 +546,12 @@ CONFIG_E100=y
# 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_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
CONFIG_MV643XX_ETH=y
CONFIG_MV643XX_ETH_0=y
CONFIG_MV643XX_ETH_1=y
@@ -474,6 +560,7 @@ CONFIG_MV643XX_ETH_2=y
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -486,6 +573,8 @@ CONFIG_MV643XX_ETH_2=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# Wan interfaces
@@ -505,6 +594,8 @@ CONFIG_PPPOE=m
# CONFIG_NET_FC is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -531,19 +622,6 @@ CONFIG_INPUT=y
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -553,6 +631,17 @@ CONFIG_SERIO=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -573,6 +662,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
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
@@ -598,6 +688,11 @@ CONFIG_RTC=y
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -608,10 +703,20 @@ CONFIG_RTC=y
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -625,6 +730,11 @@ CONFIG_RTC=y
# Graphics support
#
CONFIG_FB=y
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_SOFT_CURSOR is not set
+# CONFIG_FB_MACMODES is not set
CONFIG_FB_MODE_HELPERS=y
# CONFIG_FB_TILEBLITTING is not set
# CONFIG_FB_CIRRUS is not set
@@ -632,6 +742,7 @@ CONFIG_FB_MODE_HELPERS=y
# CONFIG_FB_CYBER2000 is not set
# CONFIG_FB_ASILIANT is not set
# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
# CONFIG_FB_MATROX is not set
# CONFIG_FB_RADEON_OLD is not set
@@ -644,8 +755,11 @@ CONFIG_FB_MODE_HELPERS=y
# CONFIG_FB_KYRO is not set
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_SMIVGX is not set
+# CONFIG_FB_CYBLA is not set
# CONFIG_FB_TRIDENT is not set
# CONFIG_FB_E1356 is not set
+# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_VIRTUAL is not set
#
@@ -675,13 +789,9 @@ CONFIG_LOGO_LINUX_CLUT224=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -699,10 +809,15 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=m
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -715,17 +830,21 @@ CONFIG_REISERFS_FS=m
# CONFIG_REISERFS_PROC_INFO is not set
# CONFIG_REISERFS_FS_XATTR is not set
# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
CONFIG_XFS_FS=m
-# CONFIG_XFS_RT is not set
+CONFIG_XFS_EXPORT=y
# CONFIG_XFS_QUOTA is not set
# CONFIG_XFS_SECURITY is not set
# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=y
CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -746,15 +865,10 @@ CONFIG_AUTOFS4_FS=m
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -778,16 +892,19 @@ CONFIG_CRAMFS=y
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
CONFIG_NFSD=y
CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
# CONFIG_NFSD_V4 is not set
# CONFIG_NFSD_TCP is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -797,6 +914,7 @@ CONFIG_SMB_FS=m
# 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
@@ -856,7 +974,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE="ip=any root=nfs"
@@ -869,7 +989,31 @@ CONFIG_CMDLINE="ip=any root=nfs"
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -879,9 +1023,8 @@ CONFIG_CMDLINE="ip=any root=nfs"
# Library routines
#
CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/ocelot_c_defconfig b/arch/mips/configs/ocelot_c_defconfig
index a38903db85a0..d3a5fee02b79 100644
--- a/arch/mips/configs/ocelot_c_defconfig
+++ b/arch/mips/configs/ocelot_c_defconfig
@@ -1,11 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:07 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:33 2005
#
CONFIG_MIPS=y
-CONFIG_64BIT=y
-CONFIG_64BIT=y
#
# Code maturity level options
@@ -13,24 +11,29 @@ CONFIG_64BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -40,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -49,39 +53,68 @@ CONFIG_CC_ALIGN_JUMPS=0
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-CONFIG_MOMENCO_OCELOT_C=y
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+CONFIG_MOMENCO_OCELOT_C=y
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
# CONFIG_SGI_IP27 is not set
# CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_IRQ_MV64340=y
CONFIG_PCI_MARVELL=y
@@ -91,8 +124,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# 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
@@ -108,6 +143,17 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
CONFIG_CPU_RM7000=y
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_RM7000=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=y
# CONFIG_PAGE_SIZE_8KB is not set
# CONFIG_PAGE_SIZE_16KB is not set
@@ -115,9 +161,23 @@ CONFIG_PAGE_SIZE_4KB=y
CONFIG_BOARD_SCACHE=y
CONFIG_RM7000_CPU_SCACHE=y
CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=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_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -126,7 +186,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -135,10 +194,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -156,6 +211,79 @@ CONFIG_MIPS32_N32=y
CONFIG_BINFMT_ELF32=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=y
+CONFIG_IEEE80211_CRYPT_CCMP=y
+CONFIG_IEEE80211_CRYPT_TKIP=y
+
+#
# Device Drivers
#
@@ -164,7 +292,12 @@ CONFIG_BINFMT_ELF32=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=y
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
#
# Memory Technology Devices (MTD)
@@ -183,7 +316,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -194,7 +326,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
CONFIG_CDROM_PKTCDVD=y
CONFIG_CDROM_PKTCDVD_BUFFERS=8
# CONFIG_CDROM_PKTCDVD_WCACHE is not set
@@ -216,6 +347,7 @@ CONFIG_ATA_OVER_ETH=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=y
# CONFIG_SCSI is not set
#
@@ -226,6 +358,7 @@ CONFIG_ATA_OVER_ETH=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -238,77 +371,13 @@ CONFIG_ATA_OVER_ETH=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_PACKET is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_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_TUNNEL=y
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=y
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
+# Network device support
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -316,6 +385,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -341,13 +425,17 @@ CONFIG_NET_ETHERNET=y
# 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_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
# CONFIG_MV643XX_ETH is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -360,6 +448,8 @@ CONFIG_NET_ETHERNET=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=y
#
# Wan interfaces
@@ -371,6 +461,8 @@ CONFIG_NET_ETHERNET=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -400,19 +492,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=y
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -422,6 +501,17 @@ CONFIG_SERIO_RAW=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=y
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -442,6 +532,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
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
@@ -468,6 +559,11 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -478,10 +574,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -501,7 +607,6 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -511,13 +616,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -535,21 +636,29 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=y
#
# CD-ROM/DVD Filesystems
@@ -570,12 +679,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=y
#
# Miscellaneous filesystems
@@ -607,6 +714,7 @@ CONFIG_NFSD=y
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -615,6 +723,7 @@ CONFIG_SUNRPC=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
@@ -635,7 +744,9 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -649,7 +760,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -659,7 +794,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CRC16=y
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/mips/configs/ocelot_defconfig b/arch/mips/configs/ocelot_defconfig
index 920d59b56a4e..1edde12ebff9 100644
--- a/arch/mips/configs/ocelot_defconfig
+++ b/arch/mips/configs/ocelot_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:08 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:35 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
# CONFIG_HOTPLUG is not set
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -50,40 +53,68 @@ CONFIG_CC_ALIGN_JUMPS=0
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
CONFIG_MOMENCO_OCELOT=y
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_IRQ_CPU_RM7K=y
CONFIG_MIPS_GT64120=y
@@ -96,8 +127,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# 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
@@ -113,6 +146,17 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
CONFIG_CPU_RM7000=y
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_RM7000=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=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
@@ -120,11 +164,25 @@ CONFIG_PAGE_SIZE_4KB=y
CONFIG_BOARD_SCACHE=y
CONFIG_RM7000_CPU_SCACHE=y
CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
# CONFIG_64BIT_PHYS_ADDR is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=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_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -140,10 +198,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
@@ -155,6 +209,79 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=y
+CONFIG_IEEE80211_CRYPT_CCMP=y
+CONFIG_IEEE80211_CRYPT_TKIP=y
+
+#
# Device Drivers
#
@@ -166,6 +293,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -182,13 +314,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=y
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -211,6 +341,7 @@ CONFIG_ATA_OVER_ETH=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=y
# CONFIG_SCSI is not set
#
@@ -221,6 +352,7 @@ CONFIG_ATA_OVER_ETH=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -231,77 +363,28 @@ CONFIG_ATA_OVER_ETH=y
#
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
+# Network device support
#
-# CONFIG_PACKET is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-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 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_TUNNEL=y
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=y
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
#
-# QoS and/or fair queueing
+# PHY device support
#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
+CONFIG_PHYLIB=y
+CONFIG_PHYCONTROL=y
#
-# Network testing
+# MII PHY device drivers
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
#
# Ethernet (10 or 100Mbit)
@@ -334,6 +417,8 @@ CONFIG_NET_ETHERNET=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -363,18 +448,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=y
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -384,6 +457,16 @@ CONFIG_SERIO_RAW=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=y
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -425,10 +508,13 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -439,10 +525,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -462,7 +558,6 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -476,10 +571,6 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
@@ -492,24 +583,31 @@ CONFIG_DUMMY_CONSOLE=y
#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=y
#
# CD-ROM/DVD Filesystems
@@ -530,12 +628,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=y
#
# Miscellaneous filesystems
@@ -567,6 +663,7 @@ CONFIG_NFSD=y
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -575,6 +672,7 @@ CONFIG_SUNRPC=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
@@ -595,7 +693,9 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -609,7 +709,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -619,7 +743,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CRC16=y
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/mips/configs/ocelot_g_defconfig b/arch/mips/configs/ocelot_g_defconfig
index ef5ea50893d1..e2d5188cdc15 100644
--- a/arch/mips/configs/ocelot_g_defconfig
+++ b/arch/mips/configs/ocelot_g_defconfig
@@ -1,11 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:08 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:38 2005
#
CONFIG_MIPS=y
-CONFIG_64BIT=y
-CONFIG_64BIT=y
#
# Code maturity level options
@@ -13,24 +11,29 @@ CONFIG_64BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -40,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -49,39 +53,68 @@ CONFIG_CC_ALIGN_JUMPS=0
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-CONFIG_MOMENCO_OCELOT_G=y
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+CONFIG_MOMENCO_OCELOT_G=y
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
# CONFIG_SGI_IP27 is not set
# CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_IRQ_CPU_RM7K=y
CONFIG_PCI_MARVELL=y
@@ -94,8 +127,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# 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
@@ -111,6 +146,17 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
CONFIG_CPU_RM7000=y
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_RM7000=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=y
# CONFIG_PAGE_SIZE_8KB is not set
# CONFIG_PAGE_SIZE_16KB is not set
@@ -118,9 +164,23 @@ CONFIG_PAGE_SIZE_4KB=y
CONFIG_BOARD_SCACHE=y
CONFIG_RM7000_CPU_SCACHE=y
CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=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_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -129,7 +189,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -138,10 +197,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -159,6 +214,79 @@ CONFIG_MIPS32_N32=y
CONFIG_BINFMT_ELF32=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=y
+CONFIG_IEEE80211_CRYPT_CCMP=y
+CONFIG_IEEE80211_CRYPT_TKIP=y
+
+#
# Device Drivers
#
@@ -167,7 +295,12 @@ CONFIG_BINFMT_ELF32=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=y
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
#
# Memory Technology Devices (MTD)
@@ -186,7 +319,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -197,7 +329,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
CONFIG_CDROM_PKTCDVD=y
CONFIG_CDROM_PKTCDVD_BUFFERS=8
# CONFIG_CDROM_PKTCDVD_WCACHE is not set
@@ -219,6 +350,7 @@ CONFIG_ATA_OVER_ETH=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=y
# CONFIG_SCSI is not set
#
@@ -229,6 +361,7 @@ CONFIG_ATA_OVER_ETH=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -241,77 +374,13 @@ CONFIG_ATA_OVER_ETH=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_PACKET is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_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_TUNNEL=y
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=y
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
+# Network device support
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -319,6 +388,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -345,12 +429,16 @@ CONFIG_GALILEO_64240_ETH=y
# 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_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -363,6 +451,8 @@ CONFIG_GALILEO_64240_ETH=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=y
#
# Wan interfaces
@@ -374,6 +464,8 @@ CONFIG_GALILEO_64240_ETH=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -403,19 +495,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=y
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -425,6 +504,17 @@ CONFIG_SERIO_RAW=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=y
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -445,6 +535,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
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
@@ -471,6 +562,11 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -481,10 +577,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -504,7 +610,6 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -514,13 +619,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -538,21 +639,29 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=y
#
# CD-ROM/DVD Filesystems
@@ -573,12 +682,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=y
#
# Miscellaneous filesystems
@@ -610,6 +717,7 @@ CONFIG_NFSD=y
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -618,6 +726,7 @@ CONFIG_SUNRPC=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
@@ -638,7 +747,9 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -652,7 +763,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -662,7 +797,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CRC16=y
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig
index 813e3a8b480b..47247addee1b 100644
--- a/arch/mips/configs/pb1100_defconfig
+++ b/arch/mips/configs/pb1100_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:08 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:41 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,56 +59,70 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+CONFIG_MIPS_PB1100=y
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-CONFIG_SOC_AU1X00=y
-# CONFIG_SOC_AU1000 is not set
-CONFIG_SOC_AU1100=y
-# CONFIG_SOC_AU1500 is not set
-# CONFIG_SOC_AU1550 is not set
-# CONFIG_MIPS_PB1000 is not set
-CONFIG_MIPS_PB1100=y
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_MIRAGE is not set
-# CONFIG_MIPS_XXS1500 is not set
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SOC_AU1100=y
+CONFIG_SOC_AU1X00=y
CONFIG_SWAP_IO_SPACE=y
# CONFIG_AU1X00_USB_DEVICE is not set
CONFIG_MIPS_L1_CACHE_SHIFT=5
@@ -113,8 +130,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS64 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
@@ -130,15 +149,39 @@ CONFIG_CPU_MIPS32=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 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
+
+#
+# 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_64KB is not set
CONFIG_CPU_HAS_PREFETCH=y
-# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_MIPS_MT is not set
+CONFIG_64BIT_PHYS_ADDR=y
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -154,6 +197,8 @@ CONFIG_MMU=y
CONFIG_PCCARD=m
# CONFIG_PCMCIA_DEBUG is not set
CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
#
# PC-card bridges
@@ -171,6 +216,100 @@ CONFIG_PCMCIA=m
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
CONFIG_TRAD_SIGNALS=y
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+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 is not set
+# CONFIG_NET_IPGRE is not set
+# 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_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_PPTP=m
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
#
# Device Drivers
@@ -181,15 +320,20 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
#
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
@@ -233,9 +377,8 @@ CONFIG_MTD_CFI_UTIL=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_PB1100=y
-CONFIG_MTD_PB1500_BOOT=y
-CONFIG_MTD_PB1500_USER=y
+CONFIG_MTD_ALCHEMY=y
+# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
@@ -270,14 +413,12 @@ CONFIG_MTD_PB1500_USER=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -300,6 +441,7 @@ CONFIG_ATA_OVER_ETH=m
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
# CONFIG_SCSI is not set
#
@@ -310,6 +452,7 @@ CONFIG_ATA_OVER_ETH=m
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -320,94 +463,28 @@ CONFIG_ATA_OVER_ETH=m
#
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-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 is not set
-# CONFIG_NET_IPGRE is not set
-# 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_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_IP_NF_CONNTRACK is not set
-CONFIG_IP_NF_CONNTRACK_MARK=y
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
+# Network device support
#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
#
-# QoS and/or fair queueing
+# PHY device support
#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
#
-# Network testing
+# MII PHY device drivers
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
#
# Ethernet (10 or 100Mbit)
@@ -453,6 +530,8 @@ CONFIG_PPPOE=m
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -482,18 +561,6 @@ CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -503,6 +570,16 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -534,14 +611,14 @@ CONFIG_LEGACY_PTY_COUNT=256
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
-CONFIG_RTC=y
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
#
# PCMCIA character devices
@@ -550,6 +627,10 @@ CONFIG_SYNCLINK_CS=m
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -560,10 +641,20 @@ CONFIG_SYNCLINK_CS=m
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -583,7 +674,6 @@ CONFIG_SYNCLINK_CS=m
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -593,12 +683,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -613,7 +700,10 @@ CONFIG_DUMMY_CONSOLE=y
#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
#
# File systems
@@ -622,6 +712,7 @@ CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
@@ -640,10 +731,12 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -664,13 +757,10 @@ CONFIG_AUTOFS4_FS=m
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -704,6 +794,7 @@ CONFIG_NFSD=m
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -713,6 +804,7 @@ CONFIG_SMB_FS=m
# 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
@@ -772,7 +864,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -788,26 +882,27 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
CONFIG_CRYPTO=y
CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=y
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-CONFIG_CRYPTO_TWOFISH=y
-# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
-# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
# CONFIG_CRYPTO_TEST is not set
@@ -819,9 +914,8 @@ CONFIG_CRYPTO_CRC32C=m
# Library routines
#
CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig
index 49e528340a39..f91a4eaae51a 100644
--- a/arch/mips/configs/pb1500_defconfig
+++ b/arch/mips/configs/pb1500_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:09 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:44 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,63 +59,80 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+CONFIG_MIPS_PB1500=y
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-CONFIG_SOC_AU1X00=y
-# CONFIG_SOC_AU1000 is not set
-# CONFIG_SOC_AU1100 is not set
-CONFIG_SOC_AU1500=y
-# CONFIG_SOC_AU1550 is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-CONFIG_MIPS_PB1500=y
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_MIRAGE is not set
-# CONFIG_MIPS_XXS1500 is not set
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
-CONFIG_DMA_COHERENT=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SOC_AU1500=y
+CONFIG_SOC_AU1X00=y
# CONFIG_AU1X00_USB_DEVICE is not set
CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS64 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
@@ -128,15 +148,39 @@ CONFIG_CPU_MIPS32=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 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
+
+#
+# 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_64KB is not set
CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
CONFIG_64BIT_PHYS_ADDR=y
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -145,7 +189,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -154,6 +197,8 @@ CONFIG_MMU=y
CONFIG_PCCARD=m
# CONFIG_PCMCIA_DEBUG is not set
CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
CONFIG_CARDBUS=y
#
@@ -177,6 +222,100 @@ CONFIG_PCCARD_NONSTATIC=m
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
CONFIG_TRAD_SIGNALS=y
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+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 is not set
+# CONFIG_NET_IPGRE is not set
+# 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_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_PPTP=m
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
#
# Device Drivers
@@ -187,12 +326,87 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
#
-# CONFIG_MTD is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_AMDSTD_RETRY=0
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_ALCHEMY=y
+# 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_BLKMTD 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
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
#
# Parallel port support
@@ -206,7 +420,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -218,7 +431,6 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -275,6 +487,7 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
CONFIG_BLK_DEV_HPT366=y
# CONFIG_BLK_DEV_SC1200 is not set
# CONFIG_BLK_DEV_PIIX 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
@@ -292,6 +505,7 @@ CONFIG_BLK_DEV_IDEDMA=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
# CONFIG_SCSI is not set
#
@@ -302,6 +516,7 @@ CONFIG_BLK_DEV_IDEDMA=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -314,94 +529,13 @@ CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-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 is not set
-# CONFIG_NET_IPGRE is not set
-# 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_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# IP: Netfilter Configuration
+# Network device support
#
-# CONFIG_IP_NF_CONNTRACK is not set
-CONFIG_IP_NF_CONNTRACK_MARK=y
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -409,6 +543,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -435,12 +584,16 @@ CONFIG_MIPS_AU1X00_ENET=y
# 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_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -453,6 +606,8 @@ CONFIG_MIPS_AU1X00_ENET=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# PCMCIA network device support
@@ -484,6 +639,8 @@ CONFIG_PPPOE=m
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -513,19 +670,6 @@ CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -535,6 +679,17 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
# CONFIG_VT is not set
@@ -554,6 +709,7 @@ CONFIG_SERIAL_AU1X00=y
CONFIG_SERIAL_AU1X00_CONSOLE=y
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
@@ -585,6 +741,11 @@ CONFIG_SYNCLINK_CS=m
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -595,10 +756,20 @@ CONFIG_SYNCLINK_CS=m
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -612,7 +783,6 @@ CONFIG_SYNCLINK_CS=m
# Graphics support
#
# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -622,13 +792,9 @@ CONFIG_SYNCLINK_CS=m
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -646,12 +812,17 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
@@ -670,10 +841,12 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -694,13 +867,10 @@ CONFIG_AUTOFS4_FS=m
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -712,6 +882,8 @@ CONFIG_RAMFS=y
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
CONFIG_CRAMFS=m
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
@@ -732,6 +904,7 @@ CONFIG_NFSD=m
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -741,6 +914,7 @@ CONFIG_SMB_FS=m
# 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
@@ -800,7 +974,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -816,27 +992,28 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
CONFIG_CRYPTO=y
CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=y
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-CONFIG_CRYPTO_TWOFISH=y
-# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
-# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
-# CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
# CONFIG_CRYPTO_TEST is not set
#
@@ -847,9 +1024,8 @@ CONFIG_CRYPTO_MICHAEL_MIC=y
# Library routines
#
CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig
index 8e426776c098..bbad27cb40a2 100644
--- a/arch/mips/configs/pb1550_defconfig
+++ b/arch/mips/configs/pb1550_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:09 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:47 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,63 +59,80 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+CONFIG_MIPS_PB1550=y
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-CONFIG_SOC_AU1X00=y
-# CONFIG_SOC_AU1000 is not set
-# CONFIG_SOC_AU1100 is not set
-# CONFIG_SOC_AU1500 is not set
-CONFIG_SOC_AU1550=y
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-CONFIG_MIPS_PB1550=y
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_MIRAGE is not set
-# CONFIG_MIPS_XXS1500 is not set
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
-CONFIG_DMA_COHERENT=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SOC_AU1550=y
+CONFIG_SOC_AU1X00=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS64 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
@@ -128,15 +148,39 @@ CONFIG_CPU_MIPS32=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 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
+
+#
+# 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_64KB is not set
CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
CONFIG_64BIT_PHYS_ADDR=y
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -145,7 +189,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -154,6 +197,8 @@ CONFIG_MMU=y
CONFIG_PCCARD=m
# CONFIG_PCMCIA_DEBUG is not set
CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
CONFIG_CARDBUS=y
#
@@ -177,6 +222,100 @@ CONFIG_PCCARD_NONSTATIC=m
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
CONFIG_TRAD_SIGNALS=y
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+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 is not set
+# CONFIG_NET_IPGRE is not set
+# 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_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_PPTP=m
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
#
# Device Drivers
@@ -187,12 +326,87 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
#
-# CONFIG_MTD is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_AMDSTD_RETRY=0
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_ALCHEMY=y
+# 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_BLKMTD 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
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
#
# Parallel port support
@@ -206,7 +420,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -218,7 +431,6 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -275,6 +487,7 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
CONFIG_BLK_DEV_HPT366=y
# CONFIG_BLK_DEV_SC1200 is not set
# CONFIG_BLK_DEV_PIIX 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
@@ -292,6 +505,7 @@ CONFIG_BLK_DEV_IDEDMA=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
# CONFIG_SCSI is not set
#
@@ -302,6 +516,7 @@ CONFIG_BLK_DEV_IDEDMA=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -314,94 +529,13 @@ CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-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 is not set
-# CONFIG_NET_IPGRE is not set
-# 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_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# IP: Netfilter Configuration
+# Network device support
#
-# CONFIG_IP_NF_CONNTRACK is not set
-CONFIG_IP_NF_CONNTRACK_MARK=y
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -409,6 +543,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -435,12 +584,16 @@ CONFIG_MIPS_AU1X00_ENET=y
# 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_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -453,6 +606,8 @@ CONFIG_MIPS_AU1X00_ENET=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# PCMCIA network device support
@@ -476,6 +631,8 @@ CONFIG_PPPOE=m
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -505,19 +662,6 @@ CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -527,6 +671,17 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
# CONFIG_VT is not set
@@ -546,6 +701,7 @@ CONFIG_SERIAL_AU1X00=y
CONFIG_SERIAL_AU1X00_CONSOLE=y
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
@@ -577,6 +733,11 @@ CONFIG_SYNCLINK_CS=m
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -587,10 +748,20 @@ CONFIG_SYNCLINK_CS=m
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -604,7 +775,6 @@ CONFIG_SYNCLINK_CS=m
# Graphics support
#
# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -614,13 +784,9 @@ CONFIG_SYNCLINK_CS=m
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -638,12 +804,17 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
@@ -662,10 +833,12 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -686,13 +859,10 @@ CONFIG_AUTOFS4_FS=m
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -704,6 +874,8 @@ CONFIG_RAMFS=y
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
CONFIG_CRAMFS=m
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
@@ -724,6 +896,7 @@ CONFIG_NFSD=m
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -733,6 +906,7 @@ CONFIG_SMB_FS=m
# 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
@@ -792,7 +966,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -808,26 +984,27 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
CONFIG_CRYPTO=y
CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=y
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-CONFIG_CRYPTO_TWOFISH=y
-# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
-# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
# CONFIG_CRYPTO_TEST is not set
@@ -839,9 +1016,8 @@ CONFIG_CRYPTO_CRC32C=m
# Library routines
#
CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig
new file mode 100644
index 000000000000..95f84d711912
--- /dev/null
+++ b/arch/mips/configs/pnx8550-jbs_defconfig
@@ -0,0 +1,1069 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:50 2005
+#
+CONFIG_MIPS=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODULE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+CONFIG_PNX8550_JBS=y
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_PNX8550=y
+CONFIG_SOC_PNX8550=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# 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=y
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 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_R4X00=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=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_64KB is not set
+# CONFIG_MIPS_MT is not set
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+# CONFIG_PCI_LEGACY_PROC is not set
+# CONFIG_PCI_DEBUG is not set
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_LBD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECD=m
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+CONFIG_BLK_DEV_IDESCSI=y
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+CONFIG_BLK_DEV_OFFBOARD=y
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+# CONFIG_IDEDMA_PCI_AUTO is not set
+# 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_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX 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 is not set
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+# 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
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+CONFIG_SCSI_QLA2XXX=y
+# CONFIG_SCSI_QLA21XX is not set
+# CONFIG_SCSI_QLA22XX is not set
+# CONFIG_SCSI_QLA2300 is not set
+# CONFIG_SCSI_QLA2322 is not set
+# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 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_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS 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=y
+CONFIG_8139TOO_8129=y
+# CONFIG_8139_OLD_RX_RESET 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_LAN_SAA9730 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 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_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# 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_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_IP3106 is not set
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_BLUETOOTH_TTY is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# 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_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_LD is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=m
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+CONFIG_DEBUG_SLAB=y
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE="console=ttyS1,38400n8 kgdb=ttyS0 root=/dev/nfs ip=bootp"
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_KGDB is not set
+# CONFIG_RUNTIME_DEBUG is not set
+# CONFIG_MIPS_UNCACHED is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
diff --git a/arch/mips/configs/pnx8550-v2pci_defconfig b/arch/mips/configs/pnx8550-v2pci_defconfig
new file mode 100644
index 000000000000..deb24c29ac0a
--- /dev/null
+++ b/arch/mips/configs/pnx8550-v2pci_defconfig
@@ -0,0 +1,1251 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:53 2005
+#
+CONFIG_MIPS=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODULE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+CONFIG_PNX8550_V2PCI=y
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_PNX8550=y
+CONFIG_SOC_PNX8550=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# 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=y
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 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_R4X00=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=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_64KB is not set
+# CONFIG_MIPS_MT is not set
+# CONFIG_64BIT_PHYS_ADDR is not set
+CONFIG_CPU_ADVANCED=y
+CONFIG_CPU_HAS_LLSC=y
+# CONFIG_CPU_HAS_LLDSCD is not set
+# CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+# CONFIG_PCI_LEGACY_PROC is not set
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_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_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_IPV6_TUNNEL is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_NETFILTER_NETLINK is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_PPTP=m
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP6_NF_QUEUE is not set
+# CONFIG_IP6_NF_IPTABLES is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_LBD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_GENERIC is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+# 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=y
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX 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 is not set
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=32
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+CONFIG_SCSI_QLA2XXX=y
+# CONFIG_SCSI_QLA21XX is not set
+# CONFIG_SCSI_QLA22XX is not set
+# CONFIG_SCSI_QLA2300 is not set
+# CONFIG_SCSI_QLA2322 is not set
+# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 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_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+CONFIG_NATSEMI=y
+# 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_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_LAN_SAA9730 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 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_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPPOE is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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_TSDEV is not set
+CONFIG_INPUT_EVDEV=m
+# 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_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_INPUT_JOYSTICK 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_VT_CONSOLE is not set
+CONFIG_HW_CONSOLE=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+# CONFIG_SYNCLINKMP is not set
+# CONFIG_N_HDLC is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_IP3106 is not set
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_SCx200_ACB is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 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
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_SOFT_CURSOR is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+# 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_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON_OLD is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS 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_SMIVGX is not set
+# CONFIG_FB_CYBLA is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_E1356 is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+
+#
+# Logo configuration
+#
+# CONFIG_LOGO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_BLUETOOTH_TTY is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# CONFIG_HID_FF is not set
+CONFIG_USB_HIDDEV=y
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# 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_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_XFS_FS=m
+CONFIG_XFS_EXPORT=y
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_SECURITY is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=m
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/qemu_defconfig b/arch/mips/configs/qemu_defconfig
index b6568e421b99..741a9a971367 100644
--- a/arch/mips/configs/qemu_defconfig
+++ b/arch/mips/configs/qemu_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc6
-# Mon Aug 8 11:49:54 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:56 2005
#
CONFIG_MIPS=y
@@ -17,6 +17,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
# CONFIG_SWAP is not set
# CONFIG_SYSVIPC is not set
# CONFIG_BSD_PROCESS_ACCT is not set
@@ -25,6 +26,7 @@ CONFIG_LOCALVERSION=""
# CONFIG_HOTPLUG is not set
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -74,6 +76,7 @@ CONFIG_BASE_SMALL=1
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
@@ -91,6 +94,7 @@ CONFIG_QEMU=y
# CONFIG_SGI_IP22 is not set
# CONFIG_SGI_IP27 is not set
# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
# CONFIG_SIBYTE_SWARM is not set
# CONFIG_SIBYTE_SENTOSA is not set
# CONFIG_SIBYTE_RHONE is not set
@@ -105,7 +109,6 @@ CONFIG_QEMU=y
# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_COHERENT=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_I8259=y
@@ -119,7 +122,7 @@ CONFIG_HAVE_STD_PC_SERIAL_PORT=y
#
# CPU selection
#
-# CONFIG_CPU_MIPS32_R1 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
@@ -127,7 +130,7 @@ CONFIG_HAVE_STD_PC_SERIAL_PORT=y
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
# CONFIG_CPU_R4300 is not set
-CONFIG_CPU_R4X00=y
+# CONFIG_CPU_R4X00 is not set
# CONFIG_CPU_TX49XX is not set
# CONFIG_CPU_R5000 is not set
# CONFIG_CPU_R5432 is not set
@@ -138,9 +141,11 @@ CONFIG_CPU_R4X00=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 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_CPU_SUPPORTS_64BIT_KERNEL=y
#
# Kernel type
@@ -151,15 +156,18 @@ CONFIG_PAGE_SIZE_4KB=y
# CONFIG_PAGE_SIZE_8KB is not set
# CONFIG_PAGE_SIZE_16KB is not set
# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_CPU_HAS_PREFETCH=y
# CONFIG_MIPS_MT is not set
# CONFIG_64BIT_PHYS_ADDR is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
-CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
@@ -214,8 +222,8 @@ CONFIG_IP_PNP_BOOTP=y
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_BIC=y
# CONFIG_IPV6 is not set
@@ -232,9 +240,15 @@ CONFIG_TCP_CONG_BIC=y
#
# Network testing
#
+# CONFIG_NET_PKTGEN is not set
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=y
+CONFIG_IEEE80211_CRYPT_CCMP=y
+CONFIG_IEEE80211_CRYPT_TKIP=y
#
# Device Drivers
@@ -248,6 +262,11 @@ CONFIG_STANDALONE=y
# CONFIG_FW_LOADER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -265,13 +284,12 @@ CONFIG_STANDALONE=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
# CONFIG_CDROM_PKTCDVD is not set
#
@@ -291,6 +309,7 @@ CONFIG_IOSCHED_NOOP=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=y
# CONFIG_SCSI is not set
#
@@ -331,6 +350,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -470,7 +504,6 @@ CONFIG_SERIAL_CORE_CONSOLE=y
# I2C support
#
# CONFIG_I2C is not set
-# CONFIG_I2C_SENSOR is not set
#
# Dallas's 1-wire bus
@@ -481,12 +514,17 @@ CONFIG_SERIAL_CORE_CONSOLE=y
# Hardware Monitoring support
#
# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -532,7 +570,6 @@ CONFIG_DUMMY_CONSOLE=y
#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
#
# SN Devices
@@ -547,10 +584,6 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
-
-#
-# XFS support
-#
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
@@ -559,6 +592,7 @@ CONFIG_INOTIFY=y
# CONFIG_DNOTIFY is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=y
#
# CD-ROM/DVD Filesystems
@@ -576,11 +610,13 @@ CONFIG_INOTIFY=y
#
# Pseudo filesystems
#
-# CONFIG_PROC_FS is not set
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
# CONFIG_SYSFS is not set
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=y
#
# Miscellaneous filesystems
@@ -634,12 +670,35 @@ CONFIG_CMDLINE="console=ttyS0 debug ip=172.20.0.2:172.20.0.1::255.255.0.0"
# Security options
#
# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -649,7 +708,8 @@ CONFIG_CMDLINE="console=ttyS0 debug ip=172.20.0.2:172.20.0.1::255.255.0.0"
# Library routines
#
# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig
new file mode 100644
index 000000000000..2bc61ca4ba08
--- /dev/null
+++ b/arch/mips/configs/rbhma4500_defconfig
@@ -0,0 +1,1259 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:59 2005
+#
+CONFIG_MIPS=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+# CONFIG_KOBJECT_UEVENT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODULE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_TOSHIBA_RBTX4938=y
+
+#
+# Multiplex Pin Select
+#
+CONFIG_TOSHIBA_RBTX4938_MPLEX_PIO58_61=y
+# CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND is not set
+# CONFIG_TOSHIBA_RBTX4938_MPLEX_ATA is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_I8259=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+CONFIG_HAVE_STD_PC_SERIAL_PORT=y
+CONFIG_TOSHIBA_BOARDS=y
+
+#
+# CPU selection
+#
+# 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=y
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 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_TX49XX=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=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_64KB is not set
+# CONFIG_MIPS_MT is not set
+CONFIG_CPU_ADVANCED=y
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+CONFIG_CPU_HAS_WB=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+# CONFIG_PCI_LEGACY_PROC is not set
+CONFIG_ISA=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=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 is not set
+# CONFIG_NET_IPGRE is not set
+# 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_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_IPV6_TUNNEL is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_PPTP=m
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP6_NF_QUEUE is not set
+# CONFIG_IP6_NF_IPTABLES is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
+
+#
+# Memory Technology Devices (MTD)
+#
+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
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL 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_AMDSTD_RETRY=0
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_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_BLKMTD 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
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_LBD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_GENERIC is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+# CONFIG_IDEDMA_PCI_AUTO is not set
+# 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_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX 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 is not set
+# CONFIG_IDE_ARM is not set
+# CONFIG_IDE_CHIPSETS is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+# CONFIG_SCSI is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_ISA=y
+# CONFIG_E2100 is not set
+# CONFIG_EWRK3 is not set
+# CONFIG_EEXPRESS is not set
+# CONFIG_EEXPRESS_PRO is not set
+# CONFIG_HPLAN_PLUS is not set
+# CONFIG_HPLAN is not set
+# CONFIG_LP486E is not set
+# CONFIG_ETH16I is not set
+CONFIG_NE2000=y
+# CONFIG_SEEQ8005 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_DGRS 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 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_LAN_SAA9730 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 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_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+# CONFIG_ARLAN is not set
+# CONFIG_WAVELAN is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
+# CONFIG_AIRO is not set
+# CONFIG_HERMES is not set
+# CONFIG_ATMEL is not set
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# Wan interfaces
+#
+# 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 is not set
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# 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_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+# CONFIG_MOUSE_SERIAL 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_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_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_HAS_TXX9_SERIAL=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+# 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_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON_OLD is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+CONFIG_FB_ATY=y
+CONFIG_FB_ATY_CT=y
+# CONFIG_FB_ATY_GENERIC_LCD is not set
+# CONFIG_FB_ATY_XL_INIT is not set
+# CONFIG_FB_ATY_GX is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS 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_SMIVGX is not set
+# CONFIG_FB_CYBLA is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_E1356 is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+
+#
+# Logo configuration
+#
+# CONFIG_LOGO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_BLUETOOTH_TTY is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+# CONFIG_USB_STORAGE is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# CONFIG_HID_FF is not set
+CONFIG_USB_HIDDEV=y
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+CONFIG_USB_YEALINK=m
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# 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_USB_ZD1201 is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_LD is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+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 is not set
+CONFIG_XFS_FS=m
+CONFIG_XFS_EXPORT=y
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_SECURITY is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
+
+#
+# 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_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=m
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig
index 17d4fce6c4c6..988a05824f01 100644
--- a/arch/mips/configs/rm200_defconfig
+++ b/arch/mips/configs/rm200_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:09 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:27:03 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,11 +11,13 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
@@ -26,14 +25,17 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -43,6 +45,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -58,43 +61,73 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
CONFIG_SNI_RM200_PCI=y
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_ARC=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_I8259=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_ARC32=y
CONFIG_BOOT_ELF32=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
@@ -106,8 +139,10 @@ CONFIG_ARC_PROMLIB=y
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# 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
@@ -123,24 +158,49 @@ CONFIG_CPU_R4X00=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_R4X00=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=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_64KB is not set
+# CONFIG_MIPS_MT is not set
# CONFIG_64BIT_PHYS_ADDR is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_SYS_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_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 is not set
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
#
# Bus options (PCI, PCMCIA, EISA, ISA, TC)
#
+CONFIG_HW_HAS_EISA=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-# CONFIG_PCI_NAMES is not set
CONFIG_ISA=y
# CONFIG_EISA is not set
CONFIG_MMU=y
@@ -151,11 +211,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-CONFIG_PCMCIA_PROBE=y
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -168,240 +223,7 @@ CONFIG_BINFMT_MISC=m
CONFIG_TRAD_SIGNALS=y
#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-CONFIG_PARPORT=m
-CONFIG_PARPORT_PC=m
-CONFIG_PARPORT_PC_CML1=m
-CONFIG_PARPORT_SERIAL=m
-# CONFIG_PARPORT_PC_FIFO is not set
-# CONFIG_PARPORT_PC_SUPERIO is not set
-# CONFIG_PARPORT_OTHER is not set
-CONFIG_PARPORT_1284=y
-
-#
-# Plug and Play support
-#
-# CONFIG_PNP is not set
-
-#
-# Block devices
-#
-CONFIG_BLK_DEV_FD=m
-# CONFIG_BLK_DEV_XD is not set
-CONFIG_PARIDE=m
-CONFIG_PARIDE_PARPORT=m
-
-#
-# Parallel IDE high-level drivers
-#
-CONFIG_PARIDE_PD=m
-CONFIG_PARIDE_PCD=m
-CONFIG_PARIDE_PF=m
-CONFIG_PARIDE_PT=m
-CONFIG_PARIDE_PG=m
-
-#
-# Parallel IDE protocol modules
-#
-CONFIG_PARIDE_ATEN=m
-CONFIG_PARIDE_BPCK=m
-CONFIG_PARIDE_BPCK6=m
-CONFIG_PARIDE_COMM=m
-CONFIG_PARIDE_DSTR=m
-CONFIG_PARIDE_FIT2=m
-CONFIG_PARIDE_FIT3=m
-CONFIG_PARIDE_EPAT=m
-# CONFIG_PARIDE_EPATC8 is not set
-CONFIG_PARIDE_EPIA=m
-CONFIG_PARIDE_FRIQ=m
-CONFIG_PARIDE_FRPW=m
-CONFIG_PARIDE_KBIC=m
-CONFIG_PARIDE_KTTI=m
-CONFIG_PARIDE_ON20=m
-CONFIG_PARIDE_ON26=m
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_SX8=m
-CONFIG_BLK_DEV_UB=m
-CONFIG_BLK_DEV_RAM=m
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_ATA_OVER_ETH=m
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-CONFIG_SCSI=y
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=m
-# CONFIG_CHR_DEV_OSST is not set
-CONFIG_BLK_DEV_SR=m
-CONFIG_BLK_DEV_SR_VENDOR=y
-# CONFIG_CHR_DEV_SG 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
-
-#
-# SCSI Transport Attributes
-#
-CONFIG_SCSI_SPI_ATTRS=y
-# CONFIG_SCSI_FC_ATTRS is not set
-# CONFIG_SCSI_ISCSI_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_3W_9XXX is not set
-# CONFIG_SCSI_7000FASST is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_IN2000 is not set
-CONFIG_MEGARAID_NEWGEN=y
-CONFIG_MEGARAID_MM=m
-CONFIG_MEGARAID_MAILBOX=m
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-CONFIG_SCSI_PPA=m
-CONFIG_SCSI_IMM=m
-# CONFIG_SCSI_IZIP_EPP16 is not set
-# CONFIG_SCSI_IZIP_SLOW_CTR is not set
-# CONFIG_SCSI_NCR53C406A is not set
-CONFIG_SCSI_SYM53C8XX_2=y
-CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
-CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
-CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
-# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PSI240I is not set
-# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=y
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_DC395x is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
-CONFIG_MD_LINEAR=m
-CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_RAID10=m
-CONFIG_MD_RAID5=m
-# CONFIG_MD_RAID6 is not set
-CONFIG_MD_MULTIPATH=m
-CONFIG_MD_FAULTY=m
-CONFIG_BLK_DEV_DM=m
-# CONFIG_DM_CRYPT is not set
-CONFIG_DM_SNAPSHOT=m
-CONFIG_DM_MIRROR=m
-CONFIG_DM_ZERO=m
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-
-#
-# Networking support
+# Networking
#
CONFIG_NET=y
@@ -410,12 +232,14 @@ CONFIG_NET=y
#
CONFIG_PACKET=m
CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=m
CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
CONFIG_NET_KEY=m
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
# CONFIG_IP_PNP is not set
CONFIG_NET_IPIP=m
CONFIG_NET_IPGRE=m
@@ -429,8 +253,10 @@ CONFIG_IP_PIMSM_V2=y
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-CONFIG_IP_TCPDIAG_IPV6=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
#
# IP: Virtual Server Configuration
@@ -446,6 +272,9 @@ CONFIG_IPV6_TUNNEL=m
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
CONFIG_BRIDGE_NETFILTER=y
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
#
# IP: Netfilter Configuration
@@ -453,11 +282,15 @@ CONFIG_BRIDGE_NETFILTER=y
CONFIG_IP_NF_CONNTRACK=m
# CONFIG_IP_NF_CT_ACCT is not set
CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CONNTRACK_EVENTS=y
+CONFIG_IP_NF_CONNTRACK_NETLINK=m
CONFIG_IP_NF_CT_PROTO_SCTP=m
CONFIG_IP_NF_FTP=m
CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_NETBIOS_NS is not set
CONFIG_IP_NF_TFTP=m
CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_PPTP=m
CONFIG_IP_NF_QUEUE=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_LIMIT=m
@@ -482,9 +315,11 @@ CONFIG_IP_NF_MATCH_PHYSDEV=m
CONFIG_IP_NF_MATCH_ADDRTYPE=m
CONFIG_IP_NF_MATCH_REALM=m
CONFIG_IP_NF_MATCH_SCTP=m
+CONFIG_IP_NF_MATCH_DCCP=m
CONFIG_IP_NF_MATCH_COMMENT=m
CONFIG_IP_NF_MATCH_CONNMARK=m
CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_MATCH_STRING=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_TARGET_LOG=m
@@ -501,12 +336,14 @@ CONFIG_IP_NF_NAT_IRC=m
CONFIG_IP_NF_NAT_FTP=m
CONFIG_IP_NF_NAT_TFTP=m
CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_NAT_PPTP=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_TOS=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_DSCP=m
CONFIG_IP_NF_TARGET_MARK=m
CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_TARGET_CONNMARK=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_RAW=m
@@ -516,7 +353,7 @@ CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
#
-# IPv6: Netfilter Configuration
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
#
CONFIG_IP6_NF_QUEUE=m
CONFIG_IP6_NF_IPTABLES=m
@@ -536,8 +373,10 @@ CONFIG_IP6_NF_MATCH_EUI64=m
CONFIG_IP6_NF_MATCH_PHYSDEV=m
CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_TARGET_REJECT=m
CONFIG_IP6_NF_MANGLE=m
CONFIG_IP6_NF_TARGET_MARK=m
+CONFIG_IP6_NF_TARGET_HL=m
CONFIG_IP6_NF_RAW=m
#
@@ -567,9 +406,12 @@ CONFIG_BRIDGE_EBT_MARK_T=m
CONFIG_BRIDGE_EBT_REDIRECT=m
CONFIG_BRIDGE_EBT_SNAT=m
CONFIG_BRIDGE_EBT_LOG=m
-# CONFIG_BRIDGE_EBT_ULOG is not set
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
+CONFIG_BRIDGE_EBT_ULOG=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
#
# SCTP Configuration (EXPERIMENTAL)
@@ -588,10 +430,6 @@ CONFIG_DECNET=m
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_CLK_JIFFIES=y
# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
@@ -611,6 +449,7 @@ CONFIG_NET_SCH_INGRESS=m
CONFIG_NET_QOS=y
CONFIG_NET_ESTIMATOR=y
CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
CONFIG_NET_CLS_TCINDEX=m
CONFIG_NET_CLS_ROUTE4=m
CONFIG_NET_CLS_ROUTE=y
@@ -621,6 +460,7 @@ CONFIG_NET_CLS_U32=m
# CONFIG_CLS_U32_MARK is not set
CONFIG_NET_CLS_RSVP=m
CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_EMATCH is not set
# CONFIG_NET_CLS_ACT is not set
CONFIG_NET_CLS_POLICE=y
@@ -628,8 +468,6 @@ CONFIG_NET_CLS_POLICE=y
# Network testing
#
# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
CONFIG_HAMRADIO=y
#
@@ -646,8 +484,6 @@ CONFIG_ROSE=m
CONFIG_MKISS=m
CONFIG_6PACK=m
CONFIG_BPQETHER=m
-# CONFIG_DMASCC is not set
-# CONFIG_SCC is not set
# CONFIG_BAYCOM_SER_FDX is not set
# CONFIG_BAYCOM_SER_HDX is not set
# CONFIG_BAYCOM_PAR is not set
@@ -655,12 +491,257 @@ CONFIG_BPQETHER=m
# CONFIG_YAM is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_SERIAL=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+CONFIG_PARPORT_NOT_PC=y
+# CONFIG_PARPORT_GSC is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Plug and Play support
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=m
+CONFIG_PARIDE=m
+CONFIG_PARIDE_PARPORT=m
+
+#
+# Parallel IDE high-level drivers
+#
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+
+#
+# Parallel IDE protocol modules
+#
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_BPCK6=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+# CONFIG_PARIDE_EPATC8 is not set
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_SX8=m
+CONFIG_BLK_DEV_UB=m
+CONFIG_BLK_DEV_RAM=m
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=y
+# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_IN2000 is not set
+CONFIG_MEGARAID_NEWGEN=y
+CONFIG_MEGARAID_MM=m
+CONFIG_MEGARAID_MAILBOX=m
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+# CONFIG_SCSI_NCR53C406A is not set
+CONFIG_SCSI_SYM53C8XX_2=y
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+CONFIG_SCSI_QLA2XXX=y
+# CONFIG_SCSI_QLA21XX is not set
+# CONFIG_SCSI_QLA22XX is not set
+# CONFIG_SCSI_QLA2300 is not set
+# CONFIG_SCSI_QLA2322 is not set
+# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID5=m
+# CONFIG_MD_RAID6 is not set
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+# CONFIG_DM_CRYPT is not set
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
CONFIG_NETDEVICES=y
CONFIG_DUMMY=m
CONFIG_BONDING=m
CONFIG_EQUALIZER=m
CONFIG_TUN=m
-CONFIG_ETHERTAP=m
#
# ARCnet devices
@@ -668,6 +749,21 @@ CONFIG_ETHERTAP=m
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -675,7 +771,6 @@ CONFIG_MII=y
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
@@ -696,7 +791,6 @@ CONFIG_NET_ISA=y
# CONFIG_LP486E is not set
# CONFIG_ETH16I is not set
CONFIG_NE2000=m
-# CONFIG_ZNET is not set
# CONFIG_SEEQ8005 is not set
CONFIG_NET_PCI=y
CONFIG_PCNET32=y
@@ -733,13 +827,17 @@ CONFIG_EEPRO100=m
# 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_SK98LIN is not set
CONFIG_VIA_VELOCITY=m
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -752,6 +850,8 @@ CONFIG_VIA_VELOCITY=m
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# Wan interfaces
@@ -765,6 +865,8 @@ CONFIG_PLIP=m
# CONFIG_NET_FC is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -794,20 +896,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-CONFIG_SERIO_PARKBD=m
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
@@ -828,6 +916,18 @@ CONFIG_MOUSE_PS2=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_PARKBD=m
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -844,13 +944,13 @@ CONFIG_SERIAL_8250_EXTENDED=y
# CONFIG_SERIAL_8250_MANY_PORTS is not set
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_8250_DETECT_IRQ=y
-CONFIG_SERIAL_8250_MULTIPORT=y
CONFIG_SERIAL_8250_RSA=y
#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=m
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -881,6 +981,11 @@ CONFIG_RTC=m
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -891,15 +996,26 @@ CONFIG_RTC=m
CONFIG_W1=m
CONFIG_W1_MATROX=m
CONFIG_W1_DS9490=m
-CONFIG_W1_DS9490_BRIDGE=m
+# CONFIG_W1_DS9490_BRIDGE is not set
CONFIG_W1_THERM=m
CONFIG_W1_SMEM=m
+# CONFIG_W1_DS2433 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -920,7 +1036,6 @@ CONFIG_W1_SMEM=m
CONFIG_VGA_CONSOLE=y
# CONFIG_MDA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -930,6 +1045,8 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB=m
# CONFIG_USB_DEBUG is not set
@@ -940,8 +1057,6 @@ CONFIG_USB_DEVICEFS=y
# CONFIG_USB_BANDWIDTH is not set
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_OTG is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
#
# USB Host Controller Drivers
@@ -949,7 +1064,10 @@ CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB_EHCI_HCD=m
# CONFIG_USB_EHCI_SPLIT_ISO is not set
# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_ISP116X_HCD is not set
CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
CONFIG_USB_UHCI_HCD=m
# CONFIG_USB_SL811_HCD is not set
@@ -965,11 +1083,10 @@ CONFIG_USB_PRINTER=m
#
CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_RW_DETECT is not set
CONFIG_USB_STORAGE_DATAFAB=y
CONFIG_USB_STORAGE_FREECOM=y
CONFIG_USB_STORAGE_DPCM=y
-CONFIG_USB_STORAGE_HP8200e=y
+# CONFIG_USB_STORAGE_USBAT is not set
CONFIG_USB_STORAGE_SDDR09=y
CONFIG_USB_STORAGE_SDDR55=y
CONFIG_USB_STORAGE_JUMPSHOT=y
@@ -992,12 +1109,17 @@ CONFIG_USB_KBD=m
CONFIG_USB_MOUSE=m
CONFIG_USB_AIPTEK=m
CONFIG_USB_WACOM=m
+# CONFIG_USB_ACECAD is not set
CONFIG_USB_KBTAB=m
CONFIG_USB_POWERMATE=m
# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
CONFIG_USB_EGALAX=m
+CONFIG_USB_YEALINK=m
CONFIG_USB_XPAD=m
# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
#
# USB Imaging devices
@@ -1022,30 +1144,15 @@ CONFIG_USB_KAWETH=m
CONFIG_USB_PEGASUS=m
CONFIG_USB_RTL8150=m
CONFIG_USB_USBNET=m
-
-#
-# USB Host-to-Host Cables
-#
-CONFIG_USB_ALI_M5632=y
-CONFIG_USB_AN2720=y
-CONFIG_USB_BELKIN=y
-CONFIG_USB_GENESYS=y
-CONFIG_USB_NET1080=y
-CONFIG_USB_PL2301=y
-CONFIG_USB_KC2190=y
-
-#
-# Intelligent USB Devices/Gadgets
-#
-CONFIG_USB_ARMLINUX=y
-CONFIG_USB_EPSON2888=y
-CONFIG_USB_ZAURUS=y
-CONFIG_USB_CDCETHER=y
-
-#
-# USB Network Adapters
-#
-CONFIG_USB_AX8817X=y
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+# CONFIG_USB_NET_GL620A is not set
+CONFIG_USB_NET_NET1080=m
+# CONFIG_USB_NET_PLUSB is not set
+# CONFIG_USB_NET_RNDIS_HOST is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+CONFIG_USB_NET_ZAURUS=m
+CONFIG_USB_MON=y
#
# USB port drivers
@@ -1057,9 +1164,11 @@ CONFIG_USB_USS720=m
#
CONFIG_USB_SERIAL=m
CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_AIRPRIME=m
CONFIG_USB_SERIAL_BELKIN=m
CONFIG_USB_SERIAL_WHITEHEAT=m
CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+# CONFIG_USB_SERIAL_CP2101 is not set
CONFIG_USB_SERIAL_CYPRESS_M8=m
CONFIG_USB_SERIAL_EMPEG=m
CONFIG_USB_SERIAL_FTDI_SIO=m
@@ -1088,6 +1197,7 @@ CONFIG_USB_SERIAL_KLSI=m
CONFIG_USB_SERIAL_KOBIL_SCT=m
CONFIG_USB_SERIAL_MCT_U232=m
CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_HP4X=m
CONFIG_USB_SERIAL_SAFE=m
CONFIG_USB_SERIAL_SAFE_PADDED=y
# CONFIG_USB_SERIAL_TI is not set
@@ -1110,10 +1220,13 @@ CONFIG_USB_CYTHERM=m
CONFIG_USB_PHIDGETKIT=m
CONFIG_USB_PHIDGETSERVO=m
# CONFIG_USB_IDMOUSE is not set
+CONFIG_USB_SISUSBVGA=m
+# CONFIG_USB_SISUSBVGA_CON is not set
+CONFIG_USB_LD=m
CONFIG_USB_TEST=m
#
-# USB ATM/DSL drivers
+# USB DSL modem support
#
#
@@ -1132,10 +1245,15 @@ CONFIG_USB_TEST=m
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=m
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -1152,17 +1270,20 @@ CONFIG_REISERFS_FS_SECURITY=y
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
CONFIG_XFS_FS=m
-# CONFIG_XFS_RT is not set
-CONFIG_XFS_QUOTA=y
+CONFIG_XFS_EXPORT=y
+CONFIG_XFS_QUOTA=m
CONFIG_XFS_SECURITY=y
# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
CONFIG_MINIX_FS=m
CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_QUOTACTL=y
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -1192,12 +1313,10 @@ CONFIG_NTFS_FS=m
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -1224,15 +1343,18 @@ CONFIG_UFS_FS=m
#
CONFIG_NFS_FS=m
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
CONFIG_NFSD=m
CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
# CONFIG_NFSD_V4 is not set
CONFIG_NFSD_TCP=y
CONFIG_LOCKD=m
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=m
CONFIG_SUNRPC_GSS=m
CONFIG_RPCSEC_GSS_KRB5=m
@@ -1256,6 +1378,7 @@ CONFIG_CODA_FS=m
CONFIG_CODA_FS_OLD_API=y
CONFIG_AFS_FS=m
CONFIG_RXRPC=m
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -1329,7 +1452,9 @@ CONFIG_NLS_UTF8=m
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -1352,6 +1477,7 @@ CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_DES=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_TWOFISH=m
@@ -1360,13 +1486,13 @@ CONFIG_CRYPTO_AES=m
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
-# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_DEFLATE=m
CONFIG_CRYPTO_MICHAEL_MIC=m
-# CONFIG_CRYPTO_CRC32C is not set
-CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -1376,9 +1502,12 @@ CONFIG_CRYPTO_TEST=m
# Library routines
#
CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
+CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=m
CONFIG_ZLIB_DEFLATE=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig
index 1dc935f37582..4365d9c8c42e 100644
--- a/arch/mips/configs/sb1250-swarm_defconfig
+++ b/arch/mips/configs/sb1250-swarm_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:10 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:27:05 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,30 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=15
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_CPUSETS=y
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +44,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -57,32 +61,49 @@ CONFIG_STOP_MACHINE=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-CONFIG_SIBYTE_SB1xxx_SOC=y
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
CONFIG_SIBYTE_SWARM=y
# CONFIG_SIBYTE_SENTOSA is not set
# CONFIG_SIBYTE_RHONE is not set
@@ -91,9 +112,12 @@ CONFIG_SIBYTE_SWARM=y
# CONFIG_SIBYTE_LITTLESUR is not set
# CONFIG_SIBYTE_CRHINE is not set
# CONFIG_SIBYTE_CRHONE is not set
-# CONFIG_SIBYTE_UNKNOWN is not set
-CONFIG_SIBYTE_BOARD=y
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_SIBYTE_SB1250=y
+CONFIG_SIBYTE_SB1xxx_SOC=y
CONFIG_CPU_SB1_PASS_1=y
# CONFIG_CPU_SB1_PASS_2_1250 is not set
# CONFIG_CPU_SB1_PASS_2_2 is not set
@@ -102,18 +126,20 @@ CONFIG_CPU_SB1_PASS_1=y
# CONFIG_CPU_SB1_PASS_3 is not set
CONFIG_SIBYTE_HAS_LDT=y
# CONFIG_SIMULATION is not set
+# CONFIG_CONFIG_SB1_CEX_ALWAYS_FATAL is not set
+# CONFIG_CONFIG_SB1_CERR_STALL is not set
CONFIG_SIBYTE_CFE=y
# CONFIG_SIBYTE_CFE_CONSOLE is not set
# CONFIG_SIBYTE_BUS_WATCHER is not set
# CONFIG_SIBYTE_SB1250_PROF is not set
# CONFIG_SIBYTE_TBPROF is not set
-# CONFIG_SNI_RM200_PCI is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_COHERENT=y
+CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_SWAP_IO_SPACE=y
CONFIG_BOOT_ELF32=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
@@ -121,8 +147,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# 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
@@ -138,22 +166,46 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
CONFIG_CPU_SB1=y
+CONFIG_SYS_HAS_CPU_SB1=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=y
# CONFIG_PAGE_SIZE_8KB is not set
# CONFIG_PAGE_SIZE_16KB is not set
# CONFIG_PAGE_SIZE_64KB is not set
# CONFIG_SIBYTE_DMA_PAGEOPS is not set
CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
CONFIG_SB1_PASS_1_WORKAROUNDS=y
-# CONFIG_64BIT_PHYS_ADDR is not set
-# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
-# CONFIG_HIGHMEM is not set
+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_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SMP=y
CONFIG_NR_CPUS=2
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
#
# Bus options (PCI, PCMCIA, EISA, ISA, TC)
@@ -161,7 +213,6 @@ CONFIG_NR_CPUS=2
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -170,10 +221,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -183,7 +230,86 @@ CONFIG_MMU=y
#
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
-CONFIG_TRAD_SIGNALS=y
+# CONFIG_BUILD_ELF64 is not set
+CONFIG_MIPS32_COMPAT=y
+CONFIG_COMPAT=y
+CONFIG_MIPS32_O32=y
+# CONFIG_MIPS32_N32 is not set
+CONFIG_BINFMT_ELF32=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
#
# Device Drivers
@@ -194,7 +320,12 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
@@ -213,7 +344,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -226,8 +356,6 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=9220
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
# CONFIG_CDROM_PKTCDVD_WCACHE is not set
@@ -263,7 +391,7 @@ CONFIG_BLK_DEV_IDEFLOPPY=y
#
CONFIG_IDE_GENERIC=y
# CONFIG_BLK_DEV_IDEPCI is not set
-CONFIG_BLK_DEV_IDE_SWARM=y
+# CONFIG_BLK_DEV_IDE_SWARM is not set
# CONFIG_IDE_ARM is not set
# CONFIG_BLK_DEV_IDEDMA is not set
# CONFIG_IDEDMA_AUTO is not set
@@ -272,6 +400,7 @@ CONFIG_BLK_DEV_IDE_SWARM=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
# CONFIG_SCSI is not set
#
@@ -282,6 +411,7 @@ CONFIG_BLK_DEV_IDE_SWARM=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -294,78 +424,13 @@ CONFIG_BLK_DEV_IDE_SWARM=y
# CONFIG_I2O is not set
#
-# Networking support
+# Network device support
#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -373,6 +438,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -399,12 +479,16 @@ CONFIG_MII=y
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
CONFIG_NET_SB1250_MAC=y
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -417,6 +501,8 @@ CONFIG_NET_SB1250_MAC=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# Wan interfaces
@@ -428,6 +514,8 @@ CONFIG_NET_SB1250_MAC=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -445,25 +533,15 @@ CONFIG_NET_SB1250_MAC=y
# CONFIG_INPUT is not set
#
-# Userland interfaces
-#
-
-#
-# Input I/O drivers
+# Hardware I/O ports
#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
CONFIG_SERIO=y
# CONFIG_SERIO_I8042 is not set
CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
# CONFIG_SERIO_PCIPS2 is not set
# CONFIG_SERIO_LIBPS2 is not set
CONFIG_SERIO_RAW=m
-
-#
-# Input Device Drivers
-#
+# CONFIG_GAMEPORT is not set
#
# Character devices
@@ -472,11 +550,13 @@ CONFIG_SERIO_RAW=m
CONFIG_SERIAL_NONSTANDARD=y
# CONFIG_ROCKETPORT is not set
# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
# CONFIG_MOXA_SMARTIO is not set
# CONFIG_ISI is not set
-# CONFIG_SYNCLINK is not set
# CONFIG_SYNCLINKMP is not set
# CONFIG_N_HDLC is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
# CONFIG_STALDRV is not set
CONFIG_SIBYTE_SB1250_DUART=y
CONFIG_SIBYTE_SB1250_DUART_CONSOLE=y
@@ -489,6 +569,7 @@ CONFIG_SIBYTE_SB1250_DUART_CONSOLE=y
#
# Non-8250 serial port support
#
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -515,6 +596,11 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -525,10 +611,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -542,7 +638,6 @@ CONFIG_LEGACY_PTY_COUNT=256
# Graphics support
#
# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -552,13 +647,9 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -576,12 +667,17 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
CONFIG_FS_MBCACHE=y
@@ -591,10 +687,12 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -615,11 +713,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -643,13 +740,14 @@ CONFIG_RAMFS=y
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
-# CONFIG_EXPORTFS is not set
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -658,6 +756,7 @@ CONFIG_SUNRPC=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
@@ -678,7 +777,9 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=15
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
# CONFIG_SB1XXX_CORELIS is not set
@@ -695,27 +796,28 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
CONFIG_CRYPTO=y
CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=y
-CONFIG_CRYPTO_MD4=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_DES=y
-CONFIG_CRYPTO_BLOWFISH=y
-CONFIG_CRYPTO_TWOFISH=y
-CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
-# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
-# CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
# CONFIG_CRYPTO_TEST is not set
#
@@ -726,9 +828,8 @@ CONFIG_CRYPTO_MICHAEL_MIC=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=m
CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/sead_defconfig b/arch/mips/configs/sead_defconfig
index dd07e866b128..d835f6db1f41 100644
--- a/arch/mips/configs/sead_defconfig
+++ b/arch/mips/configs/sead_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:10 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:27:07 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,22 +11,26 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
-CONFIG_SWAP=y
-# CONFIG_SYSVIPC is not set
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
# CONFIG_HOTPLUG is not set
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -39,6 +40,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -48,40 +50,69 @@ CONFIG_CC_ALIGN_JUMPS=0
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
CONFIG_MIPS_SEAD=y
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_MIPS_BOARDS_GEN=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
@@ -89,8 +120,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS64 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
@@ -106,15 +139,42 @@ CONFIG_CPU_MIPS32=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_SYS_HAS_CPU_MIPS32_R2=y
+CONFIG_SYS_HAS_CPU_MIPS64_R1=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=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_64KB is not set
CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
# CONFIG_64BIT_PHYS_ADDR is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -128,10 +188,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
@@ -143,6 +199,11 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+# CONFIG_NET is not set
+
+#
# Device Drivers
#
@@ -154,6 +215,10 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -170,7 +235,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
@@ -178,11 +242,8 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=18432
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
-CONFIG_CDROM_PKTCDVD=y
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+# CONFIG_CDROM_PKTCDVD is not set
#
# IO Schedulers
@@ -200,6 +261,7 @@ CONFIG_IOSCHED_CFQ=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=y
# CONFIG_SCSI is not set
#
@@ -210,6 +272,7 @@ CONFIG_IOSCHED_CFQ=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -220,9 +283,8 @@ CONFIG_IOSCHED_CFQ=y
#
#
-# Networking support
+# Network device support
#
-# CONFIG_NET is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
@@ -238,47 +300,18 @@ CONFIG_IOSCHED_CFQ=y
#
# Input device support
#
-CONFIG_INPUT=y
+# CONFIG_INPUT 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_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input I/O drivers
+# Hardware I/O ports
#
+# CONFIG_SERIO is not set
# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=y
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
#
# Character devices
#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
+# CONFIG_VT is not set
# CONFIG_SERIAL_NONSTANDARD is not set
#
@@ -294,7 +327,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_UNIX98_PTYS is not set
+CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -315,10 +348,13 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -329,10 +365,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -347,13 +393,6 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_FB is not set
#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
# Sound
#
# CONFIG_SOUND is not set
@@ -365,10 +404,6 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
@@ -381,28 +416,31 @@ CONFIG_DUMMY_CONSOLE=y
#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
#
# File systems
#
CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
-CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
-CONFIG_FS_POSIX_ACL=y
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=y
#
# CD-ROM/DVD Filesystems
@@ -423,10 +461,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=y
#
# Miscellaneous filesystems
@@ -448,8 +486,18 @@ CONFIG_RAMFS=y
#
# Partition Types
#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
+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 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_EFI_PARTITION is not set
#
# Native Language Support
@@ -464,15 +512,16 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
#
# Security options
#
-CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
#
@@ -488,7 +537,6 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
# CONFIG_CRC32 is not set
# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig
index c9d3f83caf0f..bf60a17de2b0 100644
--- a/arch/mips/configs/tb0226_defconfig
+++ b/arch/mips/configs/tb0226_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:12 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:27:10 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
# CONFIG_HOTPLUG is not set
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,55 +59,87 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-CONFIG_MACH_VR41XX=y
-# CONFIG_NEC_CMBVR4133 is not set
-# CONFIG_CASIO_E55 is not set
-# CONFIG_IBM_WORKPAD is not set
-CONFIG_TANBAC_TB0226=y
-# CONFIG_TANBAC_TB0229 is not set
-# CONFIG_VICTOR_MPC30X is not set
-# CONFIG_ZAO_CAPCELLA is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+CONFIG_MACH_VR41XX=y
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_NEC_CMBVR4133 is not set
+# CONFIG_CASIO_E55 is not set
+# CONFIG_IBM_WORKPAD is not set
+CONFIG_TANBAC_TB022X=y
+CONFIG_TANBAC_TB0226=y
+# CONFIG_VICTOR_MPC30X is not set
+# CONFIG_ZAO_CAPCELLA is not set
+CONFIG_PCI_VR41XX=y
+# CONFIG_VRC4173 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# 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=y
@@ -120,19 +155,44 @@ CONFIG_CPU_VR41XX=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_VR41XX=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=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_64KB is not set
+# CONFIG_MIPS_MT is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
# Bus options (PCI, PCMCIA, EISA, ISA, TC)
#
CONFIG_HW_HAS_PCI=y
-# CONFIG_PCI is not set
+CONFIG_PCI=y
+# CONFIG_PCI_LEGACY_PROC is not set
CONFIG_MMU=y
#
@@ -141,12 +201,9 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
+# CONFIG_HOTPLUG_PCI is not set
#
# Executable file formats
@@ -156,6 +213,87 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
+CONFIG_IP_ROUTE_VERBOSE=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 is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -167,6 +305,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -183,19 +326,21 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=m
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
CONFIG_BLK_DEV_NBD=m
+# 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_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+# CONFIG_CDROM_PKTCDVD is not set
#
# IO Schedulers
@@ -209,33 +354,12 @@ CONFIG_ATA_OVER_ETH=m
#
# ATA/ATAPI/MFM/RLL support
#
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-CONFIG_IDEDISK_MULTI_MODE=y
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-CONFIG_BLK_DEV_IDESCSI=y
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-# CONFIG_IDE_ARM is not set
-# CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
+# CONFIG_IDE is not set
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_PROC_FS=y
@@ -245,15 +369,15 @@ CONFIG_SCSI_PROC_FS=y
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 is not set
-CONFIG_CHR_DEV_SG=y
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
CONFIG_SCSI_MULTI_LUN=y
-CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
#
@@ -262,11 +386,42 @@ CONFIG_SCSI_CONSTANTS=y
# 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
#
# SCSI low-level drivers
#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+CONFIG_SCSI_QLA2XXX=y
+# CONFIG_SCSI_QLA21XX is not set
+# CONFIG_SCSI_QLA22XX is not set
+# CONFIG_SCSI_QLA2300 is not set
+# CONFIG_SCSI_QLA2322 is not set
+# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
#
@@ -277,131 +432,132 @@ CONFIG_SCSI_CONSTANTS=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
#
# IEEE 1394 (FireWire) support
#
+# CONFIG_IEEE1394 is not set
#
# I2O device support
#
+# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
+# Network device support
#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=m
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_IP_MULTIPLE_TABLES=y
-CONFIG_IP_ROUTE_MULTIPATH=y
-CONFIG_IP_ROUTE_VERBOSE=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 is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-CONFIG_SYN_COOKIES=y
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
#
-# SCTP Configuration (EXPERIMENTAL)
+# ARCnet devices
#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
+# CONFIG_ARCNET is not set
#
-# QoS and/or fair queueing
+# PHY device support
#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
#
-# Network testing
+# MII PHY device drivers
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 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_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+CONFIG_EEPRO100=y
+# 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 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_LAN_SAA9730 is not set
#
# Ethernet (1000 Mbit)
#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 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_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
#
# Token Ring devices
#
+# CONFIG_TR is not set
#
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW2200 is not set
#
# Wan interfaces
#
# CONFIG_WAN is not set
-CONFIG_PPP=m
-CONFIG_PPP_MULTILINK=y
-# CONFIG_PPP_FILTER is not set
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPPOE=m
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -421,28 +577,13 @@ CONFIG_INPUT=y
#
# 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_MOUSEDEV is not set
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_TSDEV is not set
# CONFIG_INPUT_EVDEV is not set
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -452,6 +593,12 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -462,16 +609,16 @@ CONFIG_HW_CONSOLE=y
#
# Serial drivers
#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250 is not set
#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_VR41XX=y
+CONFIG_SERIAL_VR41XX_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -489,14 +636,22 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_TANBAC_TB0219 is not set
#
# Ftape, the floppy tape device driver
#
# CONFIG_DRM is not set
+CONFIG_GPIO_VR41XX=y
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -507,10 +662,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -523,48 +688,147 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# Graphics support
#
-CONFIG_FB=y
-# CONFIG_FB_MODE_HELPERS is not set
-# CONFIG_FB_TILEBLITTING is not set
-# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB is not set
#
# Console display driver support
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_FRAMEBUFFER_CONSOLE is not set
#
-# Logo configuration
+# Sound
#
-# CONFIG_LOGO is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_SOUND is not set
#
-# Sound
+# USB support
#
-CONFIG_SOUND=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
#
-# Advanced Linux Sound Architecture
+# Miscellaneous USB options
#
-# CONFIG_SND is not set
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
#
-# Open Sound System
+# USB Host Controller Drivers
#
-# CONFIG_SOUND_PRIME is not set
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_SPLIT_ISO is not set
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
#
-# USB support
+# USB Device Class drivers
#
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_BLUETOOTH_TTY is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM 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
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# 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_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
#
# USB Gadget Support
@@ -582,39 +846,41 @@ CONFIG_SOUND=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
#
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-CONFIG_ZISOFS_FS=y
+# CONFIG_ISO9660_FS is not set
# CONFIG_UDF_FS is not set
#
# DOS/FAT/NT Filesystems
#
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
# CONFIG_NTFS_FS is not set
#
@@ -623,13 +889,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -653,16 +916,19 @@ CONFIG_CRAMFS=m
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
CONFIG_NFSD=m
CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
# CONFIG_NFSD_V4 is not set
# CONFIG_NFSD_TCP is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -673,6 +939,7 @@ CONFIG_SMB_NLS_REMOTE="cp932"
# 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
@@ -732,9 +999,11 @@ CONFIG_NLS_ISO8859_1=m
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
+CONFIG_CMDLINE="mem=32M console=ttyVR0,115200"
#
# Security options
@@ -746,7 +1015,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -756,9 +1049,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
CONFIG_CRC_CCITT=m
-# CONFIG_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
+CONFIG_CRC16=m
+CONFIG_CRC32=m
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=m
CONFIG_ZLIB_DEFLATE=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/tb0229_defconfig b/arch/mips/configs/tb0229_defconfig
index 2cb669188aa9..ac8b64e87b8a 100644
--- a/arch/mips/configs/tb0229_defconfig
+++ b/arch/mips/configs/tb0229_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:12 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:27:13 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,58 +59,87 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-CONFIG_MACH_VR41XX=y
-# CONFIG_NEC_CMBVR4133 is not set
-# CONFIG_CASIO_E55 is not set
-# CONFIG_IBM_WORKPAD is not set
-# CONFIG_TANBAC_TB0226 is not set
-CONFIG_TANBAC_TB0229=y
-CONFIG_TANBAC_TB0219=y
-# CONFIG_VICTOR_MPC30X is not set
-# CONFIG_ZAO_CAPCELLA is not set
-CONFIG_PCI_VR41XX=y
-# CONFIG_VRC4173 is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+CONFIG_MACH_VR41XX=y
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_NEC_CMBVR4133 is not set
+# CONFIG_CASIO_E55 is not set
+# CONFIG_IBM_WORKPAD is not set
+CONFIG_TANBAC_TB022X=y
+# CONFIG_TANBAC_TB0226 is not set
+# CONFIG_VICTOR_MPC30X is not set
+# CONFIG_ZAO_CAPCELLA is not set
+CONFIG_PCI_VR41XX=y
+# CONFIG_VRC4173 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# 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=y
@@ -123,12 +155,36 @@ CONFIG_CPU_VR41XX=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_VR41XX=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=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_64KB is not set
+# CONFIG_MIPS_MT is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -136,8 +192,7 @@ CONFIG_CPU_HAS_SYNC=y
#
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
-CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
+# CONFIG_PCI_LEGACY_PROC is not set
CONFIG_MMU=y
#
@@ -146,10 +201,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -162,6 +213,88 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
+CONFIG_IP_ROUTE_VERBOSE=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 is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -170,7 +303,12 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
@@ -189,7 +327,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -199,11 +336,11 @@ CONFIG_BLK_DEV_LOOP=m
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
CONFIG_BLK_DEV_NBD=m
# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -226,6 +363,7 @@ CONFIG_ATA_OVER_ETH=m
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
#
@@ -236,6 +374,7 @@ CONFIG_ATA_OVER_ETH=m
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -248,83 +387,13 @@ CONFIG_ATA_OVER_ETH=m
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=m
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_IP_MULTIPLE_TABLES=y
-CONFIG_IP_ROUTE_MULTIPATH=y
-CONFIG_IP_ROUTE_VERBOSE=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 is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-CONFIG_SYN_COOKIES=y
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
+# Network device support
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
CONFIG_DUMMY=m
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -332,6 +401,21 @@ CONFIG_DUMMY=m
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -346,7 +430,7 @@ CONFIG_MII=y
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
CONFIG_NET_PCI=y
-CONFIG_PCNET32=y
+# CONFIG_PCNET32 is not set
# CONFIG_AMD8111_ETH is not set
# CONFIG_ADAPTEC_STARFIRE is not set
# CONFIG_B44 is not set
@@ -358,7 +442,11 @@ CONFIG_EEPRO100=y
# CONFIG_NATSEMI is not set
# CONFIG_NE2K_PCI is not set
# CONFIG_8139CP is not set
-# CONFIG_8139TOO is not set
+CONFIG_8139TOO=y
+CONFIG_8139TOO_PIO=y
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
# CONFIG_SUNDANCE is not set
@@ -375,14 +463,19 @@ CONFIG_EEPRO100=y
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
+CONFIG_R8169=y
+# CONFIG_R8169_NAPI is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -395,6 +488,8 @@ CONFIG_EEPRO100=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# Wan interfaces
@@ -416,6 +511,8 @@ CONFIG_SLIP_SMART=y
CONFIG_SLIP_MODE_SLIP6=y
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -435,29 +532,13 @@ CONFIG_INPUT=y
#
# 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_MOUSEDEV is not set
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_TSDEV is not set
# CONFIG_INPUT_EVDEV is not set
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -467,6 +548,12 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -477,16 +564,16 @@ CONFIG_HW_CONSOLE=y
#
# Serial drivers
#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250 is not set
#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_VR41XX=y
+CONFIG_SERIAL_VR41XX_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -505,14 +592,21 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
+CONFIG_TANBAC_TB0219=y
#
# Ftape, the floppy tape device driver
#
# CONFIG_DRM is not set
+CONFIG_GPIO_VR41XX=y
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -523,10 +617,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -546,7 +650,6 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -556,13 +659,122 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB=m
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+# CONFIG_USB_EHCI_SPLIT_ISO is not set
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_BLUETOOTH_TTY is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
#
+# CONFIG_USB_STORAGE is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# 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_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
#
# USB Gadget Support
@@ -580,10 +792,15 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=m
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -597,18 +814,22 @@ CONFIG_JFS_FS=m
# CONFIG_JFS_SECURITY is not set
# CONFIG_JFS_DEBUG is not set
# CONFIG_JFS_STATISTICS is not set
+# CONFIG_FS_POSIX_ACL is not set
CONFIG_XFS_FS=y
-# CONFIG_XFS_RT is not set
+CONFIG_XFS_EXPORT=y
CONFIG_XFS_QUOTA=y
# CONFIG_XFS_SECURITY is not set
CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
# CONFIG_MINIX_FS is not set
CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_QUOTACTL=y
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -635,13 +856,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -665,16 +883,19 @@ CONFIG_CRAMFS=m
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
CONFIG_NFSD=y
CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
# CONFIG_NFSD_V4 is not set
CONFIG_NFSD_TCP=y
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -685,6 +906,7 @@ CONFIG_SMB_NLS_REMOTE="cp932"
# 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
@@ -744,9 +966,11 @@ CONFIG_NLS_ISO8859_1=m
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE="mem=64M console=ttyS0,38400 ip=bootp root=/dev/nfs"
+CONFIG_CMDLINE="mem=64M console=ttyVR0,115200 ip=any root=/dev/nfs"
#
# Security options
@@ -758,7 +982,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -768,9 +1016,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
+CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig
index 17b9f2f65ba0..95344832d66e 100644
--- a/arch/mips/configs/tb0287_defconfig
+++ b/arch/mips/configs/tb0287_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-mm1
-# Thu Sep 1 22:58:34 2005
+# Linux kernel version: 2.6.14-rc5-mm1
+# Tue Oct 25 00:20:22 2005
#
CONFIG_MIPS=y
@@ -19,6 +19,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
+CONFIG_SWAP_PREFETCH=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
@@ -55,74 +56,91 @@ CONFIG_OBSOLETE_MODPARM=y
CONFIG_MODVERSIONS=y
CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_KMOD=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=y
-# CONFIG_64BIT is not set
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-CONFIG_MACH_VR41XX=y
-# CONFIG_NEC_CMBVR4133 is not set
-# CONFIG_CASIO_E55 is not set
-# CONFIG_IBM_WORKPAD is not set
-CONFIG_TANBAC_TB022X=y
-# CONFIG_TANBAC_TB0226 is not set
-CONFIG_TANBAC_TB0287=y
-# CONFIG_VICTOR_MPC30X is not set
-# CONFIG_ZAO_CAPCELLA is not set
-CONFIG_PCI_VR41XX=y
-# CONFIG_VRC4173 is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
+CONFIG_MACH_VR41XX=y
+# CONFIG_PMC_YOSEMITE is not set
# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
# CONFIG_SGI_IP27 is not set
# CONFIG_SGI_IP32 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_CASIO_E55 is not set
+# CONFIG_IBM_WORKPAD is not set
+# CONFIG_NEC_CMBVR4133 is not set
+CONFIG_TANBAC_TB022X=y
+# CONFIG_TANBAC_TB0226 is not set
+CONFIG_TANBAC_TB0287=y
+# CONFIG_VICTOR_MPC30X is not set
+# CONFIG_ZAO_CAPCELLA is not set
+CONFIG_PCI_VR41XX=y
+# CONFIG_VRC4173 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# 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=y
@@ -138,12 +156,25 @@ CONFIG_CPU_VR41XX=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+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=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_64KB is not set
+# CONFIG_MIPS_MT is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
@@ -152,6 +183,9 @@ CONFIG_FLATMEM_MANUAL=y
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -262,7 +296,6 @@ CONFIG_TCP_CONG_HTCP=m
# Network testing
#
# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETFILTER_NETLINK is not set
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
@@ -280,6 +313,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -296,7 +334,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -312,6 +349,7 @@ CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_CDROM_PKTCDVD is not set
#
@@ -321,6 +359,11 @@ CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
# CONFIG_ATA_OVER_ETH is not set
#
@@ -410,13 +453,20 @@ CONFIG_BLK_DEV_SD=y
# 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
+
+#
+# SCSI Transport Layers
+#
+# CONFIG_SAS_CLASS is not set
#
# SCSI low-level drivers
#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_ARCMSR is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
-# CONFIG_SCSI_ARCMSR is not set
# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AACRAID is not set
# CONFIG_SCSI_AIC7XXX is not set
@@ -425,12 +475,10 @@ CONFIG_BLK_DEV_SD=y
# CONFIG_SCSI_DPT_I2O is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
@@ -462,6 +510,7 @@ CONFIG_SCSI_QLA2XXX=y
# CONFIG_FUSION is not set
# CONFIG_FUSION_SPI is not set
# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
#
# IEEE 1394 (FireWire) support
@@ -529,6 +578,7 @@ CONFIG_NET_ETHERNET=y
CONFIG_MII=y
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
#
@@ -572,6 +622,7 @@ CONFIG_R8169=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_HOSTAP is not set
#
# Wan interfaces
@@ -682,6 +733,7 @@ CONFIG_GPIO_VR41XX=y
# TPM devices
#
# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
#
# I2C support
@@ -770,12 +822,15 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
#
# USB Device Class drivers
#
-# CONFIG_USB_BLUETOOTH_TTY is not set
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
#
CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_DEBUG is not set
@@ -891,6 +946,11 @@ CONFIG_USB_MON=y
#
#
+# EDAC - error detection and reporting (RAS)
+#
+# CONFIG_EDAC is not set
+
+#
# Distributed Lock Manager
#
# CONFIG_DLM is not set
@@ -901,20 +961,22 @@ CONFIG_USB_MON=y
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
-# CONFIG_EXT3_FS is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
# CONFIG_REISER4_FS is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
-
-#
-# XFS support
-#
CONFIG_XFS_FS=y
-# CONFIG_XFS_RT is not set
CONFIG_XFS_QUOTA=y
# CONFIG_XFS_SECURITY is not set
CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
CONFIG_ROMFS_FS=m
@@ -948,8 +1010,8 @@ CONFIG_SYSFS=y
CONFIG_TMPFS=y
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
# CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
@@ -1004,6 +1066,11 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_NLS is not set
#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
@@ -1036,6 +1103,3 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_ISA_DMA_API=y
diff --git a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig
index 16e07fca446f..ab13621ef3b9 100644
--- a/arch/mips/configs/workpad_defconfig
+++ b/arch/mips/configs/workpad_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:12 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:27:16 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,56 +59,84 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-CONFIG_MACH_VR41XX=y
-# CONFIG_NEC_CMBVR4133 is not set
-# CONFIG_CASIO_E55 is not set
-CONFIG_IBM_WORKPAD=y
-# CONFIG_TANBAC_TB0226 is not set
-# CONFIG_TANBAC_TB0229 is not set
-# CONFIG_VICTOR_MPC30X is not set
-# CONFIG_ZAO_CAPCELLA is not set
-CONFIG_VRC4171=y
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+CONFIG_MACH_VR41XX=y
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_NEC_CMBVR4133 is not set
+# CONFIG_CASIO_E55 is not set
+CONFIG_IBM_WORKPAD=y
+# CONFIG_TANBAC_TB022X is not set
+# CONFIG_VICTOR_MPC30X is not set
+# CONFIG_ZAO_CAPCELLA is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# 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=y
@@ -121,12 +152,36 @@ CONFIG_CPU_VR41XX=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_VR41XX=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=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_64KB is not set
+# CONFIG_MIPS_MT is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -138,11 +193,17 @@ CONFIG_MMU=y
#
# PCCARD (PCMCIA/CardBus) support
#
-# CONFIG_PCCARD is not set
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
#
# PC-card bridges
#
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
CONFIG_PCMCIA_PROBE=y
#
@@ -157,6 +218,78 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# 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_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_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -165,7 +298,12 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=y
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
@@ -185,18 +323,13 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+# CONFIG_CDROM_PKTCDVD is not set
#
# IO Schedulers
@@ -219,6 +352,7 @@ CONFIG_BLK_DEV_IDE=y
# CONFIG_BLK_DEV_IDE_SATA is not set
CONFIG_BLK_DEV_IDEDISK=y
# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECS=m
# CONFIG_BLK_DEV_IDECD is not set
# CONFIG_BLK_DEV_IDETAPE is not set
# CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -237,6 +371,7 @@ CONFIG_IDE_GENERIC=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
#
@@ -252,6 +387,7 @@ CONFIG_IDE_GENERIC=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -262,76 +398,13 @@ CONFIG_IDE_GENERIC=y
#
#
-# Networking support
-#
-CONFIG_NET=y
-
+# Network device support
#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -339,12 +412,26 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
+CONFIG_MII=m
# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
# CONFIG_AT1700 is not set
@@ -373,6 +460,19 @@ CONFIG_NET_ETHERNET=y
# CONFIG_NET_RADIO is not set
#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+
+#
# Wan interfaces
#
# CONFIG_WAN is not set
@@ -380,6 +480,8 @@ CONFIG_NET_ETHERNET=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -409,18 +511,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -430,6 +520,16 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -440,16 +540,15 @@ CONFIG_HW_CONSOLE=y
#
# Serial drivers
#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250 is not set
#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_VR41XX=y
+CONFIG_SERIAL_VR41XX_CONSOLE=y
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -484,10 +583,19 @@ CONFIG_WATCHDOG=y
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_GPIO_VR41XX is not set
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -498,10 +606,20 @@ CONFIG_WATCHDOG=y
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -522,7 +640,6 @@ CONFIG_WATCHDOG=y
# CONFIG_VGA_CONSOLE is not set
# CONFIG_MDA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -536,10 +653,6 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
@@ -552,7 +665,10 @@ CONFIG_DUMMY_CONSOLE=y
#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
#
# File systems
@@ -561,6 +677,7 @@ CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
CONFIG_FS_MBCACHE=y
@@ -570,10 +687,12 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=y
CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -594,12 +713,10 @@ CONFIG_AUTOFS4_FS=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -630,6 +747,7 @@ CONFIG_NFSD=y
# CONFIG_NFSD_TCP is not set
CONFIG_LOCKD=y
CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -638,6 +756,7 @@ CONFIG_SUNRPC=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
@@ -658,9 +777,11 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
+CONFIG_CMDLINE="console=ttyVR0,19200 mem=16M"
#
# Security options
@@ -672,7 +793,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -682,7 +827,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig
index 6d2290777ad7..5b0b7f30e205 100644
--- a/arch/mips/configs/yosemite_defconfig
+++ b/arch/mips/configs/yosemite_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:13 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:27:18 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,25 +11,31 @@ CONFIG_32BIT=y
# CONFIG_EXPERIMENTAL is not set
CONFIG_CLEAN_COMPILE=y
CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+# CONFIG_CPUSETS is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -42,6 +45,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,34 +60,68 @@ CONFIG_STOP_MACHINE=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-CONFIG_PMC_YOSEMITE=y
-# CONFIG_HYPERTRANSPORT is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+CONFIG_PMC_YOSEMITE=y
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_HYPERTRANSPORT is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_COHERENT=y
+CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_IRQ_CPU_RM7K=y
CONFIG_IRQ_CPU_RM9K=y
@@ -93,8 +131,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# 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
@@ -110,20 +150,43 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
# CONFIG_CPU_RM7000 is not set
CONFIG_CPU_RM9000=y
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_RM9000=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=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_64KB is not set
CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
# CONFIG_64BIT_PHYS_ADDR is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_HIGHMEM=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_SYS_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SMP=y
CONFIG_NR_CPUS=2
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
#
# Bus options (PCI, PCMCIA, EISA, ISA, TC)
@@ -131,7 +194,7 @@ CONFIG_NR_CPUS=2
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
CONFIG_MMU=y
#
@@ -140,10 +203,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
@@ -155,6 +214,69 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=m
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_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_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+# CONFIG_NETFILTER is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -163,10 +285,15 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
# CONFIG_DEBUG_DRIVER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -183,7 +310,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -193,7 +319,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -216,6 +341,7 @@ CONFIG_ATA_OVER_ETH=m
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
# CONFIG_SCSI is not set
#
@@ -226,6 +352,7 @@ CONFIG_ATA_OVER_ETH=m
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -238,59 +365,8 @@ CONFIG_ATA_OVER_ETH=m
# CONFIG_I2O is not set
#
-# Networking support
+# Network device support
#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=m
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=m
-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_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_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_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
@@ -303,6 +379,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -327,13 +418,16 @@ CONFIG_MII=y
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
CONFIG_TITAN_GE=y
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -346,6 +440,8 @@ CONFIG_TITAN_GE=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# Wan interfaces
@@ -354,6 +450,8 @@ CONFIG_TITAN_GE=y
# CONFIG_FDDI is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -371,20 +469,10 @@ CONFIG_TITAN_GE=y
# CONFIG_INPUT is not set
#
-# Userland interfaces
-#
-
-#
-# Input I/O drivers
+# Hardware I/O ports
#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
# CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
-#
-# Input Device Drivers
-#
+# CONFIG_GAMEPORT is not set
#
# Character devices
@@ -405,6 +493,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
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
@@ -432,6 +521,10 @@ CONFIG_GEN_RTC_X=y
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -442,10 +535,20 @@ CONFIG_GEN_RTC_X=y
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -459,7 +562,6 @@ CONFIG_GEN_RTC_X=y
# Graphics support
#
# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -469,13 +571,9 @@ CONFIG_GEN_RTC_X=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -493,6 +591,10 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
# CONFIG_EXT2_FS is not set
@@ -500,13 +602,16 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -527,11 +632,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -552,7 +656,7 @@ CONFIG_NFS_FS=y
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
-# CONFIG_EXPORTFS is not set
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_SMB_FS is not set
# CONFIG_CIFS is not set
@@ -573,8 +677,11 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -599,7 +706,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -609,7 +740,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CRC16=m
+CONFIG_CRC32=m
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/ddb5xxx/Kconfig b/arch/mips/ddb5xxx/Kconfig
new file mode 100644
index 000000000000..e9b5de49f4c2
--- /dev/null
+++ b/arch/mips/ddb5xxx/Kconfig
@@ -0,0 +1,4 @@
+config DDB5477_BUS_FREQUENCY
+ int "bus frequency (in kHZ, 0 for auto-detect)"
+ depends on DDB5477
+ default 0
diff --git a/arch/mips/ddb5xxx/ddb5074/nile4_pic.c b/arch/mips/ddb5xxx/ddb5074/nile4_pic.c
index 68c127cd70c9..8743ffce8653 100644
--- a/arch/mips/ddb5xxx/ddb5074/nile4_pic.c
+++ b/arch/mips/ddb5xxx/ddb5074/nile4_pic.c
@@ -209,14 +209,13 @@ static void nile4_irq_end(unsigned int irq) {
#define nile4_irq_shutdown nile4_disable_irq
static hw_irq_controller nile4_irq_controller = {
- "nile4",
- nile4_irq_startup,
- nile4_irq_shutdown,
- nile4_enable_irq,
- nile4_disable_irq,
- nile4_ack_irq,
- nile4_irq_end,
- NULL
+ .typename = "nile4",
+ .startup = nile4_irq_startup,
+ .shutdown = nile4_irq_shutdown,
+ .enable = nile4_enable_irq,
+ .disable = nile4_disable_irq,
+ .ack = nile4_ack_irq,
+ .end = nile4_irq_end,
};
void nile4_irq_setup(u32 base) {
diff --git a/arch/mips/ddb5xxx/ddb5074/setup.c b/arch/mips/ddb5xxx/ddb5074/setup.c
index a73a5978d550..11535be265b9 100644
--- a/arch/mips/ddb5xxx/ddb5074/setup.c
+++ b/arch/mips/ddb5xxx/ddb5074/setup.c
@@ -85,7 +85,7 @@ static void __init ddb_time_init(void)
-static void __init ddb5074_setup(void)
+void __init plat_setup(void)
{
set_io_port_base(NILE4_PCI_IO_BASE);
isa_slot_offset = NILE4_PCI_MEM_BASE;
@@ -106,8 +106,6 @@ static void __init ddb5074_setup(void)
panic_timeout = 180;
}
-early_initcall(ddb5074_setup);
-
#define USE_NILE4_SERIAL 0
#if USE_NILE4_SERIAL
diff --git a/arch/mips/ddb5xxx/ddb5476/setup.c b/arch/mips/ddb5xxx/ddb5476/setup.c
index 71531f8146ea..f4e480a74edf 100644
--- a/arch/mips/ddb5xxx/ddb5476/setup.c
+++ b/arch/mips/ddb5xxx/ddb5476/setup.c
@@ -124,7 +124,7 @@ static struct {
static void ddb5476_board_init(void);
-static void __init ddb5476_setup(void)
+void __init plat_setup(void)
{
set_io_port_base(KSEG1ADDR(DDB_PCI_IO_BASE));
@@ -158,8 +158,6 @@ static void __init ddb5476_setup(void)
ddb5476_board_init();
}
-early_initcall(ddb5476_setup);
-
/*
* We don't trust bios. We essentially does hardware re-initialization
* as complete as possible, as far as we know we can safely do.
diff --git a/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c b/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c
index a77682be01ac..f66fe5b58636 100644
--- a/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c
+++ b/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c
@@ -53,14 +53,13 @@ static void vrc5476_irq_end(uint irq)
}
static hw_irq_controller vrc5476_irq_controller = {
- "vrc5476",
- vrc5476_irq_startup,
- vrc5476_irq_shutdown,
- vrc5476_irq_enable,
- vrc5476_irq_disable,
- vrc5476_irq_ack,
- vrc5476_irq_end,
- NULL /* no affinity stuff for UP */
+ .typename = "vrc5476",
+ .startup = vrc5476_irq_startup,
+ .shutdown = vrc5476_irq_shutdown,
+ .enable = vrc5476_irq_enable,
+ .disable = vrc5476_irq_disable,
+ .ack = vrc5476_irq_ack,
+ .end = vrc5476_irq_end
};
void __init
diff --git a/arch/mips/ddb5xxx/ddb5477/irq_5477.c b/arch/mips/ddb5xxx/ddb5477/irq_5477.c
index 0d5e706207ec..5fcd5f070cdc 100644
--- a/arch/mips/ddb5xxx/ddb5477/irq_5477.c
+++ b/arch/mips/ddb5xxx/ddb5477/irq_5477.c
@@ -90,14 +90,13 @@ vrc5477_irq_end(unsigned int irq)
}
hw_irq_controller vrc5477_irq_controller = {
- "vrc5477_irq",
- vrc5477_irq_startup,
- vrc5477_irq_shutdown,
- vrc5477_irq_enable,
- vrc5477_irq_disable,
- vrc5477_irq_ack,
- vrc5477_irq_end,
- NULL /* no affinity stuff for UP */
+ .typename = "vrc5477_irq",
+ .startup = vrc5477_irq_startup,
+ .shutdown = vrc5477_irq_shutdown,
+ .enable = vrc5477_irq_enable,
+ .disable = vrc5477_irq_disable,
+ .ack = vrc5477_irq_ack,
+ .end = vrc5477_irq_end
};
void __init vrc5477_irq_init(u32 irq_base)
diff --git a/arch/mips/ddb5xxx/ddb5477/setup.c b/arch/mips/ddb5xxx/ddb5477/setup.c
index d62f5a789b05..81163353c4a8 100644
--- a/arch/mips/ddb5xxx/ddb5477/setup.c
+++ b/arch/mips/ddb5xxx/ddb5477/setup.c
@@ -170,7 +170,7 @@ static void ddb5477_board_init(void);
extern struct pci_controller ddb5477_ext_controller;
extern struct pci_controller ddb5477_io_controller;
-static int ddb5477_setup(void)
+void __init plat_setup(void)
{
/* initialize board - we don't trust the loader */
ddb5477_board_init();
@@ -193,12 +193,8 @@ static int ddb5477_setup(void)
register_pci_controller (&ddb5477_ext_controller);
register_pci_controller (&ddb5477_io_controller);
-
- return 0;
}
-early_initcall(ddb5477_setup);
-
static void __init ddb5477_board_init(void)
{
/* ----------- setup PDARs ------------ */
diff --git a/arch/mips/dec/Makefile b/arch/mips/dec/Makefile
index 688757a97cb8..ed181fdc3ac9 100644
--- a/arch/mips/dec/Makefile
+++ b/arch/mips/dec/Makefile
@@ -2,8 +2,8 @@
# Makefile for the DECstation family specific parts of the kernel
#
-obj-y := ecc-berr.o int-handler.o ioasic-irq.o kn02-irq.o reset.o \
- setup.o time.o
+obj-y := ecc-berr.o int-handler.o ioasic-irq.o kn01-berr.o \
+ kn02-irq.o kn02xa-berr.o reset.o setup.o time.o
obj-$(CONFIG_PROM_CONSOLE) += promcon.o
obj-$(CONFIG_CPU_HAS_WB) += wbflush.o
diff --git a/arch/mips/dec/ecc-berr.c b/arch/mips/dec/ecc-berr.c
index 6dbce92eb068..cc24c5ed0c05 100644
--- a/arch/mips/dec/ecc-berr.c
+++ b/arch/mips/dec/ecc-berr.c
@@ -6,7 +6,7 @@
* 5000/240 (KN03), 5000/260 (KN05) and DECsystem 5900 (KN03),
* 5900/260 (KN05) systems.
*
- * Copyright (c) 2003 Maciej W. Rozycki
+ * Copyright (c) 2003, 2005 Maciej W. Rozycki
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -15,6 +15,7 @@
*/
#include <linux/init.h>
+#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
@@ -57,7 +58,7 @@ static int dec_ecc_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
const char *kind, *agent, *cycle, *event;
const char *status = "", *xbit = "", *fmt = "";
- dma_addr_t address;
+ unsigned long address;
u16 syn = 0, sngl;
int i = 0;
@@ -66,7 +67,7 @@ static int dec_ecc_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
u32 chksyn = *kn0x_chksyn;
int action = MIPS_BE_FATAL;
- /* For non-ECC ack ASAP, so any subsequent errors get caught. */
+ /* For non-ECC ack ASAP, so that any subsequent errors get caught. */
if ((erraddr & (KN0X_EAR_VALID | KN0X_EAR_ECCERR)) == KN0X_EAR_VALID)
dec_ecc_be_ack();
@@ -74,7 +75,7 @@ static int dec_ecc_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
if (!(erraddr & KN0X_EAR_VALID)) {
/* No idea what happened. */
- printk(KERN_ALERT "Unidentified bus error %s.\n", kind);
+ printk(KERN_ALERT "Unidentified bus error %s\n", kind);
return action;
}
@@ -126,7 +127,7 @@ static int dec_ecc_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
/* Ack now, no rewrite will happen. */
dec_ecc_be_ack();
- fmt = KERN_ALERT "%s" "invalid.\n";
+ fmt = KERN_ALERT "%s" "invalid\n";
} else {
sngl = syn & KN0X_ESR_SNGLO;
syn &= KN0X_ESR_SYNLO;
@@ -144,7 +145,8 @@ static int dec_ecc_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
} else if (!sngl) {
status = dbestr;
} else {
- volatile u32 *ptr = (void *)KSEG1ADDR(address);
+ volatile u32 *ptr =
+ (void *)CKSEG1ADDR(address);
*ptr = *ptr; /* Rewrite. */
iob();
@@ -160,12 +162,12 @@ static int dec_ecc_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
if (syn == 0x01) {
fmt = KERN_ALERT "%s"
"%#04x -- %s bit error "
- "at check bit C%s.\n";
+ "at check bit C%s\n";
xbit = "X";
} else {
fmt = KERN_ALERT "%s"
"%#04x -- %s bit error "
- "at check bit C%s%u.\n";
+ "at check bit C%s%u\n";
}
i = syn >> 2;
} else {
@@ -175,16 +177,16 @@ static int dec_ecc_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
if (i < 32)
fmt = KERN_ALERT "%s"
"%#04x -- %s bit error "
- "at data bit D%s%u.\n";
+ "at data bit D%s%u\n";
else
fmt = KERN_ALERT "%s"
- "%#04x -- %s bit error.\n";
+ "%#04x -- %s bit error\n";
}
}
}
if (action != MIPS_BE_FIXUP)
- printk(KERN_ALERT "Bus error %s: %s %s %s at %#010lx.\n",
+ printk(KERN_ALERT "Bus error %s: %s %s %s at %#010lx\n",
kind, agent, cycle, event, address);
if (action != MIPS_BE_FIXUP && erraddr & KN0X_EAR_ECCERR)
@@ -203,11 +205,11 @@ irqreturn_t dec_ecc_be_interrupt(int irq, void *dev_id, struct pt_regs *regs)
int action = dec_ecc_be_backend(regs, 0, 1);
if (action == MIPS_BE_DISCARD)
- return IRQ_NONE;
+ return IRQ_HANDLED;
/*
- * FIXME: Find affected processes and kill them, otherwise we
- * must die.
+ * FIXME: Find the affected processes and kill them, otherwise
+ * we must die.
*
* The interrupt is asynchronously delivered thus EPC and RA
* may be irrelevant, but are printed for a reference.
@@ -225,16 +227,16 @@ irqreturn_t dec_ecc_be_interrupt(int irq, void *dev_id, struct pt_regs *regs)
*/
static inline void dec_kn02_be_init(void)
{
- volatile u32 *csr = (void *)KN02_CSR_BASE;
+ volatile u32 *csr = (void *)CKSEG1ADDR(KN02_SLOT_BASE + KN02_CSR);
unsigned long flags;
- kn0x_erraddr = (void *)(KN02_SLOT_BASE + KN02_ERRADDR);
- kn0x_chksyn = (void *)(KN02_SLOT_BASE + KN02_CHKSYN);
+ kn0x_erraddr = (void *)CKSEG1ADDR(KN02_SLOT_BASE + KN02_ERRADDR);
+ kn0x_chksyn = (void *)CKSEG1ADDR(KN02_SLOT_BASE + KN02_CHKSYN);
spin_lock_irqsave(&kn02_lock, flags);
/* Preset write-only bits of the Control Register cache. */
- cached_kn02_csr = *csr | KN03_CSR_LEDS;
+ cached_kn02_csr = *csr | KN02_CSR_LEDS;
/* Set normal ECC detection and generation. */
cached_kn02_csr &= ~(KN02_CSR_DIAGCHK | KN02_CSR_DIAGGEN);
@@ -248,11 +250,11 @@ static inline void dec_kn02_be_init(void)
static inline void dec_kn03_be_init(void)
{
- volatile u32 *mcr = (void *)(KN03_SLOT_BASE + IOASIC_MCR);
- volatile u32 *mbcs = (void *)(KN03_SLOT_BASE + KN05_MB_CSR);
+ volatile u32 *mcr = (void *)CKSEG1ADDR(KN03_SLOT_BASE + IOASIC_MCR);
+ volatile u32 *mbcs = (void *)CKSEG1ADDR(KN4K_SLOT_BASE + KN4K_MB_CSR);
- kn0x_erraddr = (void *)(KN03_SLOT_BASE + IOASIC_ERRADDR);
- kn0x_chksyn = (void *)(KN03_SLOT_BASE + IOASIC_CHKSYN);
+ kn0x_erraddr = (void *)CKSEG1ADDR(KN03_SLOT_BASE + IOASIC_ERRADDR);
+ kn0x_chksyn = (void *)CKSEG1ADDR(KN03_SLOT_BASE + IOASIC_CHKSYN);
/*
* Set normal ECC detection and generation, enable ECC correction.
@@ -264,7 +266,7 @@ static inline void dec_kn03_be_init(void)
*mcr = (*mcr & ~(KN03_MCR_DIAGCHK | KN03_MCR_DIAGGEN)) |
KN03_MCR_CORRECT;
if (current_cpu_data.cputype == CPU_R4400SC)
- *mbcs |= KN05_MB_CSR_EE;
+ *mbcs |= KN4K_MB_CSR_EE;
fast_iob();
}
diff --git a/arch/mips/dec/int-handler.S b/arch/mips/dec/int-handler.S
index c89768d5c4e5..41fa372007bf 100644
--- a/arch/mips/dec/int-handler.S
+++ b/arch/mips/dec/int-handler.S
@@ -2,9 +2,9 @@
* arch/mips/dec/int-handler.S
*
* Copyright (C) 1995, 1996, 1997 Paul M. Antoine and Harald Koerfgen
- * Copyright (C) 2000, 2001, 2002, 2003 Maciej W. Rozycki
+ * Copyright (C) 2000, 2001, 2002, 2003, 2005 Maciej W. Rozycki
*
- * Written by Ralf Baechle and Andreas Busse, modified for DECStation
+ * Written by Ralf Baechle and Andreas Busse, modified for DECstation
* support by Paul Antoine and Harald Koerfgen.
*
* completly rewritten:
@@ -14,11 +14,12 @@
* by Maciej W. Rozycki.
*/
#include <linux/config.h>
+
+#include <asm/addrspace.h>
#include <asm/asm.h>
-#include <asm/regdef.h>
#include <asm/mipsregs.h>
+#include <asm/regdef.h>
#include <asm/stackframe.h>
-#include <asm/addrspace.h>
#include <asm/dec/interrupts.h>
#include <asm/dec/ioasic_addrs.h>
@@ -28,11 +29,14 @@
#include <asm/dec/kn02xa.h>
#include <asm/dec/kn03.h>
+#define KN02_CSR_BASE CKSEG1ADDR(KN02_SLOT_BASE + KN02_CSR)
+#define KN02XA_IOASIC_BASE CKSEG1ADDR(KN02XA_SLOT_BASE + IOASIC_IOCTL)
+#define KN03_IOASIC_BASE CKSEG1ADDR(KN03_SLOT_BASE + IOASIC_IOCTL)
.text
.set noreorder
/*
- * decstation_handle_int: Interrupt handler for DECStations
+ * decstation_handle_int: Interrupt handler for DECstations
*
* We follow the model in the Indy interrupt code by David Miller, where he
* says: a lot of complication here is taken away because:
@@ -48,7 +52,7 @@
* 3) Linux only thinks in terms of all IRQs on or all IRQs
* off, nothing in between like BSD spl() brain-damage.
*
- * Furthermore, the IRQs on the DECStations look basically (barring
+ * Furthermore, the IRQs on the DECstations look basically (barring
* software IRQs which we don't use at all) like...
*
* DS2100/3100's, aka kn01, aka Pmax:
@@ -61,7 +65,7 @@
* 3 Lance Ethernet
* 4 DZ11 serial
* 5 RTC
- * 6 Memory Controller
+ * 6 Memory Controller & Video
* 7 FPU
*
* DS5000/200, aka kn02, aka 3max:
diff --git a/arch/mips/dec/kn01-berr.c b/arch/mips/dec/kn01-berr.c
new file mode 100644
index 000000000000..b9271db9bc76
--- /dev/null
+++ b/arch/mips/dec/kn01-berr.c
@@ -0,0 +1,201 @@
+/*
+ * linux/arch/mips/dec/kn01-berr.c
+ *
+ * Bus error event handling code for DECstation/DECsystem 3100
+ * and 2100 (KN01) systems equipped with parity error detection
+ * logic.
+ *
+ * Copyright (c) 2005 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include <asm/inst.h>
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+#include <asm/uaccess.h>
+
+#include <asm/dec/kn01.h>
+
+
+/* CP0 hazard avoidance. */
+#define BARRIER \
+ __asm__ __volatile__( \
+ ".set push\n\t" \
+ ".set noreorder\n\t" \
+ "nop\n\t" \
+ ".set pop\n\t")
+
+/*
+ * Bits 7:0 of the Control Register are write-only -- the
+ * corresponding bits of the Status Register have a different
+ * meaning. Hence we use a cache. It speeds up things a bit
+ * as well.
+ *
+ * There is no default value -- it has to be initialized.
+ */
+u16 cached_kn01_csr;
+DEFINE_SPINLOCK(kn01_lock);
+
+
+static inline void dec_kn01_be_ack(void)
+{
+ volatile u16 *csr = (void *)CKSEG1ADDR(KN01_SLOT_BASE + KN01_CSR);
+ unsigned long flags;
+
+ spin_lock_irqsave(&kn01_lock, flags);
+
+ *csr = cached_kn01_csr | KN01_CSR_MEMERR; /* Clear bus IRQ. */
+ iob();
+
+ spin_unlock_irqrestore(&kn01_lock, flags);
+}
+
+static int dec_kn01_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
+{
+ volatile u32 *kn01_erraddr = (void *)CKSEG1ADDR(KN01_SLOT_BASE +
+ KN01_ERRADDR);
+
+ static const char excstr[] = "exception";
+ static const char intstr[] = "interrupt";
+ static const char cpustr[] = "CPU";
+ static const char mreadstr[] = "memory read";
+ static const char readstr[] = "read";
+ static const char writestr[] = "write";
+ static const char timestr[] = "timeout";
+ static const char paritystr[] = "parity error";
+
+ int data = regs->cp0_cause & 4;
+ unsigned int __user *pc = (unsigned int __user *)regs->cp0_epc +
+ ((regs->cp0_cause & CAUSEF_BD) != 0);
+ union mips_instruction insn;
+ unsigned long entrylo, offset;
+ long asid, entryhi, vaddr;
+
+ const char *kind, *agent, *cycle, *event;
+ unsigned long address;
+
+ u32 erraddr = *kn01_erraddr;
+ int action = MIPS_BE_FATAL;
+
+ /* Ack ASAP, so that any subsequent errors get caught. */
+ dec_kn01_be_ack();
+
+ kind = invoker ? intstr : excstr;
+
+ agent = cpustr;
+
+ if (invoker)
+ address = erraddr;
+ else {
+ /* Bloody hardware doesn't record the address for reads... */
+ if (data) {
+ /* This never faults. */
+ __get_user(insn.word, pc);
+ vaddr = regs->regs[insn.i_format.rs] +
+ insn.i_format.simmediate;
+ } else
+ vaddr = (long)pc;
+ if (KSEGX(vaddr) == CKSEG0 || KSEGX(vaddr) == CKSEG1)
+ address = CPHYSADDR(vaddr);
+ else {
+ /* Peek at what physical address the CPU used. */
+ asid = read_c0_entryhi();
+ entryhi = asid & (PAGE_SIZE - 1);
+ entryhi |= vaddr & ~(PAGE_SIZE - 1);
+ write_c0_entryhi(entryhi);
+ BARRIER;
+ tlb_probe();
+ /* No need to check for presence. */
+ tlb_read();
+ entrylo = read_c0_entrylo0();
+ write_c0_entryhi(asid);
+ offset = vaddr & (PAGE_SIZE - 1);
+ address = (entrylo & ~(PAGE_SIZE - 1)) | offset;
+ }
+ }
+
+ /* Treat low 256MB as memory, high -- as I/O. */
+ if (address < 0x10000000) {
+ cycle = mreadstr;
+ event = paritystr;
+ } else {
+ cycle = invoker ? writestr : readstr;
+ event = timestr;
+ }
+
+ if (is_fixup)
+ action = MIPS_BE_FIXUP;
+
+ if (action != MIPS_BE_FIXUP)
+ printk(KERN_ALERT "Bus error %s: %s %s %s at %#010lx\n",
+ kind, agent, cycle, event, address);
+
+ return action;
+}
+
+int dec_kn01_be_handler(struct pt_regs *regs, int is_fixup)
+{
+ return dec_kn01_be_backend(regs, is_fixup, 0);
+}
+
+irqreturn_t dec_kn01_be_interrupt(int irq, void *dev_id,
+ struct pt_regs *regs)
+{
+ volatile u16 *csr = (void *)CKSEG1ADDR(KN01_SLOT_BASE + KN01_CSR);
+ int action;
+
+ if (!(*csr & KN01_CSR_MEMERR))
+ return IRQ_NONE; /* Must have been video. */
+
+ action = dec_kn01_be_backend(regs, 0, 1);
+
+ if (action == MIPS_BE_DISCARD)
+ return IRQ_HANDLED;
+
+ /*
+ * FIXME: Find the affected processes and kill them, otherwise
+ * we must die.
+ *
+ * The interrupt is asynchronously delivered thus EPC and RA
+ * may be irrelevant, but are printed for a reference.
+ */
+ printk(KERN_ALERT "Fatal bus interrupt, epc == %08lx, ra == %08lx\n",
+ regs->cp0_epc, regs->regs[31]);
+ die("Unrecoverable bus error", regs);
+}
+
+
+void __init dec_kn01_be_init(void)
+{
+ volatile u16 *csr = (void *)CKSEG1ADDR(KN01_SLOT_BASE + KN01_CSR);
+ unsigned long flags;
+
+ spin_lock_irqsave(&kn01_lock, flags);
+
+ /* Preset write-only bits of the Control Register cache. */
+ cached_kn01_csr = *csr;
+ cached_kn01_csr &= KN01_CSR_STATUS | KN01_CSR_PARDIS | KN01_CSR_TXDIS;
+ cached_kn01_csr |= KN01_CSR_LEDS;
+
+ /* Enable parity error detection. */
+ cached_kn01_csr &= ~KN01_CSR_PARDIS;
+ *csr = cached_kn01_csr;
+ iob();
+
+ spin_unlock_irqrestore(&kn01_lock, flags);
+
+ /* Clear any leftover errors from the firmware. */
+ dec_kn01_be_ack();
+}
diff --git a/arch/mips/dec/kn02-irq.c b/arch/mips/dec/kn02-irq.c
index e0bfcd1521e2..898bed502a34 100644
--- a/arch/mips/dec/kn02-irq.c
+++ b/arch/mips/dec/kn02-irq.c
@@ -4,7 +4,7 @@
* DECstation 5000/200 (KN02) Control and Status Register
* interrupts.
*
- * Copyright (c) 2002, 2003 Maciej W. Rozycki
+ * Copyright (c) 2002, 2003, 2005 Maciej W. Rozycki
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -37,7 +37,8 @@ static int kn02_irq_base;
static inline void unmask_kn02_irq(unsigned int irq)
{
- volatile u32 *csr = (volatile u32 *)KN02_CSR_BASE;
+ volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE +
+ KN02_CSR);
cached_kn02_csr |= (1 << (irq - kn02_irq_base + 16));
*csr = cached_kn02_csr;
@@ -45,7 +46,8 @@ static inline void unmask_kn02_irq(unsigned int irq)
static inline void mask_kn02_irq(unsigned int irq)
{
- volatile u32 *csr = (volatile u32 *)KN02_CSR_BASE;
+ volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE +
+ KN02_CSR);
cached_kn02_csr &= ~(1 << (irq - kn02_irq_base + 16));
*csr = cached_kn02_csr;
@@ -105,13 +107,14 @@ static struct hw_interrupt_type kn02_irq_type = {
void __init init_kn02_irqs(int base)
{
- volatile u32 *csr = (volatile u32 *)KN02_CSR_BASE;
+ volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE +
+ KN02_CSR);
unsigned long flags;
int i;
/* Mask interrupts. */
spin_lock_irqsave(&kn02_lock, flags);
- cached_kn02_csr &= ~KN03_CSR_IOINTEN;
+ cached_kn02_csr &= ~KN02_CSR_IOINTEN;
*csr = cached_kn02_csr;
iob();
spin_unlock_irqrestore(&kn02_lock, flags);
diff --git a/arch/mips/dec/kn02xa-berr.c b/arch/mips/dec/kn02xa-berr.c
new file mode 100644
index 000000000000..6cd3f94f79fe
--- /dev/null
+++ b/arch/mips/dec/kn02xa-berr.c
@@ -0,0 +1,139 @@
+/*
+ * linux/arch/mips/dec/kn02xa-berr.c
+ *
+ * Bus error event handling code for 5000-series systems equipped
+ * with parity error detection logic, i.e. DECstation/DECsystem
+ * 5000/120, /125, /133 (KN02-BA), 5000/150 (KN04-BA) and Personal
+ * DECstation/DECsystem 5000/20, /25, /33 (KN02-CA), 5000/50
+ * (KN04-CA) systems.
+ *
+ * Copyright (c) 2005 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+
+#include <asm/dec/kn02ca.h>
+#include <asm/dec/kn02xa.h>
+#include <asm/dec/kn05.h>
+
+static inline void dec_kn02xa_be_ack(void)
+{
+ volatile u32 *mer = (void *)CKSEG1ADDR(KN02XA_MER);
+ volatile u32 *mem_intr = (void *)CKSEG1ADDR(KN02XA_MEM_INTR);
+
+ *mer = KN02CA_MER_INTR; /* Clear errors; keep the ARC IRQ. */
+ *mem_intr = 0; /* Any write clears the bus IRQ. */
+ iob();
+}
+
+static int dec_kn02xa_be_backend(struct pt_regs *regs, int is_fixup,
+ int invoker)
+{
+ volatile u32 *kn02xa_mer = (void *)CKSEG1ADDR(KN02XA_MER);
+ volatile u32 *kn02xa_ear = (void *)CKSEG1ADDR(KN02XA_EAR);
+
+ static const char excstr[] = "exception";
+ static const char intstr[] = "interrupt";
+ static const char cpustr[] = "CPU";
+ static const char mreadstr[] = "memory read";
+ static const char readstr[] = "read";
+ static const char writestr[] = "write";
+ static const char timestr[] = "timeout";
+ static const char paritystr[] = "parity error";
+ static const char lanestat[][4] = { " OK", "BAD" };
+
+ const char *kind, *agent, *cycle, *event;
+ unsigned long address;
+
+ u32 mer = *kn02xa_mer;
+ u32 ear = *kn02xa_ear;
+ int action = MIPS_BE_FATAL;
+
+ /* Ack ASAP, so that any subsequent errors get caught. */
+ dec_kn02xa_be_ack();
+
+ kind = invoker ? intstr : excstr;
+
+ /* No DMA errors? */
+ agent = cpustr;
+
+ address = ear & KN02XA_EAR_ADDRESS;
+
+ /* Low 256MB is decoded as memory, high -- as TC. */
+ if (address < 0x10000000) {
+ cycle = mreadstr;
+ event = paritystr;
+ } else {
+ cycle = invoker ? writestr : readstr;
+ event = timestr;
+ }
+
+ if (is_fixup)
+ action = MIPS_BE_FIXUP;
+
+ if (action != MIPS_BE_FIXUP)
+ printk(KERN_ALERT "Bus error %s: %s %s %s at %#010lx\n",
+ kind, agent, cycle, event, address);
+
+ if (action != MIPS_BE_FIXUP && address < 0x10000000)
+ printk(KERN_ALERT " Byte lane status %#3x -- "
+ "#3: %s, #2: %s, #1: %s, #0: %s\n",
+ (mer & KN02XA_MER_BYTERR) >> 8,
+ lanestat[(mer & KN02XA_MER_BYTERR_3) != 0],
+ lanestat[(mer & KN02XA_MER_BYTERR_2) != 0],
+ lanestat[(mer & KN02XA_MER_BYTERR_1) != 0],
+ lanestat[(mer & KN02XA_MER_BYTERR_0) != 0]);
+
+ return action;
+}
+
+int dec_kn02xa_be_handler(struct pt_regs *regs, int is_fixup)
+{
+ return dec_kn02xa_be_backend(regs, is_fixup, 0);
+}
+
+irqreturn_t dec_kn02xa_be_interrupt(int irq, void *dev_id,
+ struct pt_regs *regs)
+{
+ int action = dec_kn02xa_be_backend(regs, 0, 1);
+
+ if (action == MIPS_BE_DISCARD)
+ return IRQ_HANDLED;
+
+ /*
+ * FIXME: Find the affected processes and kill them, otherwise
+ * we must die.
+ *
+ * The interrupt is asynchronously delivered thus EPC and RA
+ * may be irrelevant, but are printed for a reference.
+ */
+ printk(KERN_ALERT "Fatal bus interrupt, epc == %08lx, ra == %08lx\n",
+ regs->cp0_epc, regs->regs[31]);
+ die("Unrecoverable bus error", regs);
+}
+
+
+void __init dec_kn02xa_be_init(void)
+{
+ volatile u32 *mbcs = (void *)CKSEG1ADDR(KN4K_SLOT_BASE + KN4K_MB_CSR);
+
+ /* For KN04 we need to make sure EE (?) is enabled in the MB. */
+ if (current_cpu_data.cputype == CPU_R4000SC)
+ *mbcs |= KN4K_MB_CSR_EE;
+ fast_iob();
+
+ /* Clear any leftover errors from the firmware. */
+ dec_kn02xa_be_ack();
+}
diff --git a/arch/mips/dec/prom/identify.c b/arch/mips/dec/prom/identify.c
index 9380588cb15c..81d5e878ddce 100644
--- a/arch/mips/dec/prom/identify.c
+++ b/arch/mips/dec/prom/identify.c
@@ -2,7 +2,7 @@
* identify.c: machine identification code.
*
* Copyright (C) 1998 Harald Koerfgen and Paul M. Antoine
- * Copyright (C) 2002, 2003, 2004 Maciej W. Rozycki
+ * Copyright (C) 2002, 2003, 2004, 2005 Maciej W. Rozycki
*/
#include <linux/init.h>
#include <linux/kernel.h>
@@ -12,6 +12,7 @@
#include <linux/types.h>
#include <asm/bootinfo.h>
+
#include <asm/dec/ioasic.h>
#include <asm/dec/ioasic_addrs.h>
#include <asm/dec/kn01.h>
@@ -21,6 +22,7 @@
#include <asm/dec/kn03.h>
#include <asm/dec/kn230.h>
#include <asm/dec/prom.h>
+#include <asm/dec/system.h>
#include "dectypes.h"
@@ -68,34 +70,44 @@ EXPORT_SYMBOL(dec_rtc_base);
static inline void prom_init_kn01(void)
{
- dec_rtc_base = (void *)KN01_RTC_BASE;
+ dec_kn_slot_base = KN01_SLOT_BASE;
dec_kn_slot_size = KN01_SLOT_SIZE;
+
+ dec_rtc_base = (void *)CKSEG1ADDR(dec_kn_slot_base + KN01_RTC);
}
static inline void prom_init_kn230(void)
{
- dec_rtc_base = (void *)KN01_RTC_BASE;
+ dec_kn_slot_base = KN01_SLOT_BASE;
dec_kn_slot_size = KN01_SLOT_SIZE;
+
+ dec_rtc_base = (void *)CKSEG1ADDR(dec_kn_slot_base + KN01_RTC);
}
static inline void prom_init_kn02(void)
{
- dec_rtc_base = (void *)KN02_RTC_BASE;
+ dec_kn_slot_base = KN02_SLOT_BASE;
dec_kn_slot_size = KN02_SLOT_SIZE;
+
+ dec_rtc_base = (void *)CKSEG1ADDR(dec_kn_slot_base + KN02_RTC);
}
static inline void prom_init_kn02xa(void)
{
- ioasic_base = (void *)KN02XA_IOASIC_BASE;
- dec_rtc_base = (void *)KN02XA_RTC_BASE;
+ dec_kn_slot_base = KN02XA_SLOT_BASE;
dec_kn_slot_size = IOASIC_SLOT_SIZE;
+
+ ioasic_base = (void *)CKSEG1ADDR(dec_kn_slot_base + IOASIC_IOCTL);
+ dec_rtc_base = (void *)CKSEG1ADDR(dec_kn_slot_base + IOASIC_TOY);
}
static inline void prom_init_kn03(void)
{
- ioasic_base = (void *)KN03_IOASIC_BASE;
- dec_rtc_base = (void *)KN03_RTC_BASE;
+ dec_kn_slot_base = KN03_SLOT_BASE;
dec_kn_slot_size = IOASIC_SLOT_SIZE;
+
+ ioasic_base = (void *)CKSEG1ADDR(dec_kn_slot_base + IOASIC_IOCTL);
+ dec_rtc_base = (void *)CKSEG1ADDR(dec_kn_slot_base + IOASIC_TOY);
}
diff --git a/arch/mips/dec/prom/init.c b/arch/mips/dec/prom/init.c
index 60f74256e689..32a7cc7e4c65 100644
--- a/arch/mips/dec/prom/init.c
+++ b/arch/mips/dec/prom/init.c
@@ -6,6 +6,8 @@
*/
#include <linux/config.h>
#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/linkage.h>
#include <linux/smp.h>
#include <linux/string.h>
#include <linux/types.h>
@@ -85,17 +87,13 @@ void __init which_prom(s32 magic, s32 *prom_vec)
void __init prom_init(void)
{
- extern void dec_machine_halt(void);
+ extern void ATTRIB_NORET dec_machine_halt(void);
static char cpu_msg[] __initdata =
"Sorry, this kernel is compiled for a wrong CPU type!\n";
- static char r3k_msg[] __initdata =
- "Please recompile with \"CONFIG_CPU_R3000 = y\".\n";
- static char r4k_msg[] __initdata =
- "Please recompile with \"CONFIG_CPU_R4x00 = y\".\n";
s32 argc = fw_arg0;
- s32 argv = fw_arg1;
+ s32 *argv = (void *)fw_arg1;
u32 magic = fw_arg2;
- s32 prom_vec = fw_arg3;
+ s32 *prom_vec = (void *)fw_arg3;
/*
* Determine which PROM we have
@@ -113,6 +111,8 @@ void __init prom_init(void)
#if defined(CONFIG_CPU_R3000)
if ((current_cpu_data.cputype == CPU_R4000SC) ||
(current_cpu_data.cputype == CPU_R4400SC)) {
+ static char r4k_msg[] __initdata =
+ "Please recompile with \"CONFIG_CPU_R4x00 = y\".\n";
printk(cpu_msg);
printk(r4k_msg);
dec_machine_halt();
@@ -122,6 +122,8 @@ void __init prom_init(void)
#if defined(CONFIG_CPU_R4X00)
if ((current_cpu_data.cputype == CPU_R3000) ||
(current_cpu_data.cputype == CPU_R3000A)) {
+ static char r3k_msg[] __initdata =
+ "Please recompile with \"CONFIG_CPU_R3000 = y\".\n";
printk(cpu_msg);
printk(r3k_msg);
dec_machine_halt();
diff --git a/arch/mips/dec/prom/memory.c b/arch/mips/dec/prom/memory.c
index e4f6f26425ea..83d4556c3cb5 100644
--- a/arch/mips/dec/prom/memory.c
+++ b/arch/mips/dec/prom/memory.c
@@ -35,22 +35,22 @@ static inline void pmax_setup_memory_region(void)
extern char genexcept_early;
/* Install exception handler */
- memcpy(&old_handler, (void *)(KSEG0 + 0x80), 0x80);
- memcpy((void *)(KSEG0 + 0x80), &genexcept_early, 0x80);
+ memcpy(&old_handler, (void *)(CKSEG0 + 0x80), 0x80);
+ memcpy((void *)(CKSEG0 + 0x80), &genexcept_early, 0x80);
/* read unmapped and uncached (KSEG1)
* DECstations have at least 4MB RAM
* Assume less than 480MB of RAM, as this is max for 5000/2xx
* FIXME this should be replaced by the first free page!
*/
- for (memory_page = (unsigned char *) KSEG1 + CHUNK_SIZE;
- (mem_err== 0) && (memory_page < ((unsigned char *) KSEG1+0x1E000000));
+ for (memory_page = (unsigned char *)CKSEG1 + CHUNK_SIZE;
+ mem_err == 0 && memory_page < (unsigned char *)CKSEG1 + 0x1e00000;
memory_page += CHUNK_SIZE) {
dummy = *memory_page;
}
- memcpy((void *)(KSEG0 + 0x80), &old_handler, 0x80);
+ memcpy((void *)(CKSEG0 + 0x80), &old_handler, 0x80);
- add_memory_region(0, (unsigned long)memory_page - KSEG1 - CHUNK_SIZE,
+ add_memory_region(0, (unsigned long)memory_page - CKSEG1 - CHUNK_SIZE,
BOOT_MEM_RAM);
}
@@ -65,7 +65,7 @@ static inline void rex_setup_memory_region(void)
memmap *bm;
/* some free 64k */
- bm = (memmap *)KSEG0ADDR(0x28000);
+ bm = (memmap *)CKSEG0ADDR(0x28000);
bitmap_size = rex_getbitmap(bm);
diff --git a/arch/mips/dec/reset.c b/arch/mips/dec/reset.c
index 7e4d34d0573d..f78c6da47921 100644
--- a/arch/mips/dec/reset.c
+++ b/arch/mips/dec/reset.c
@@ -14,7 +14,7 @@ typedef void ATTRIB_NORET (* noret_func_t)(void);
static inline void ATTRIB_NORET back_to_prom(void)
{
- noret_func_t func = (void *) KSEG1ADDR(0x1fc00000);
+ noret_func_t func = (void *)CKSEG1ADDR(0x1fc00000);
func();
}
diff --git a/arch/mips/dec/setup.c b/arch/mips/dec/setup.c
index 6a69309baf40..9ef54fe1feaa 100644
--- a/arch/mips/dec/setup.c
+++ b/arch/mips/dec/setup.c
@@ -1,19 +1,20 @@
/*
- * Setup the interrupt stuff.
+ * System-specific setup, especially interrupts.
*
* 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 Harald Koerfgen
- * Copyright (C) 2000, 2001, 2002, 2003 Maciej W. Rozycki
+ * Copyright (C) 2000, 2001, 2002, 2003, 2005 Maciej W. Rozycki
*/
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/param.h>
#include <linux/console.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
#include <linux/module.h>
+#include <linux/param.h>
+#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/types.h>
@@ -38,6 +39,7 @@
#include <asm/dec/kn02ca.h>
#include <asm/dec/kn03.h>
#include <asm/dec/kn230.h>
+#include <asm/dec/system.h>
extern void dec_machine_restart(char *command);
@@ -47,10 +49,16 @@ extern irqreturn_t dec_intr_halt(int irq, void *dev_id, struct pt_regs *regs);
extern asmlinkage void decstation_handle_int(void);
+unsigned long dec_kn_slot_base, dec_kn_slot_size;
+
+EXPORT_SYMBOL(dec_kn_slot_base);
+EXPORT_SYMBOL(dec_kn_slot_size);
+
spinlock_t ioasic_ssr_lock;
volatile u32 *ioasic_base;
-unsigned long dec_kn_slot_size;
+
+EXPORT_SYMBOL(ioasic_base);
/*
* IRQ routing and priority tables. Priorites are set as follows:
@@ -77,6 +85,9 @@ unsigned long dec_kn_slot_size;
int dec_interrupt[DEC_NR_INTS] = {
[0 ... DEC_NR_INTS - 1] = -1
};
+
+EXPORT_SYMBOL(dec_interrupt);
+
int_ptr cpu_mask_nr_tbl[DEC_MAX_CPU_INTS][2] = {
{ { .i = ~0 }, { .p = dec_intr_unimplemented } },
};
@@ -108,11 +119,20 @@ static struct irqaction haltirq = {
/*
* Bus error (DBE/IBE exceptions and bus interrupts) handling setup.
*/
-void __init dec_be_init(void)
+static void __init dec_be_init(void)
{
switch (mips_machtype) {
case MACH_DS23100: /* DS2100/DS3100 Pmin/Pmax */
+ board_be_handler = dec_kn01_be_handler;
+ busirq.handler = dec_kn01_be_interrupt;
busirq.flags |= SA_SHIRQ;
+ dec_kn01_be_init();
+ break;
+ case MACH_DS5000_1XX: /* DS5000/1xx 3min */
+ case MACH_DS5000_XX: /* DS5000/xx Maxine */
+ board_be_handler = dec_kn02xa_be_handler;
+ busirq.handler = dec_kn02xa_be_interrupt;
+ dec_kn02xa_be_init();
break;
case MACH_DS5000_200: /* DS5000/200 3max */
case MACH_DS5000_2X0: /* DS5000/240 3max+ */
@@ -128,7 +148,7 @@ void __init dec_be_init(void)
extern void dec_time_init(void);
extern void dec_timer_setup(struct irqaction *);
-static void __init decstation_setup(void)
+void __init plat_setup(void)
{
board_be_init = dec_be_init;
board_time_init = dec_time_init;
@@ -139,9 +159,10 @@ static void __init decstation_setup(void)
_machine_restart = dec_machine_restart;
_machine_halt = dec_machine_halt;
_machine_power_off = dec_machine_power_off;
-}
-early_initcall(decstation_setup);
+ ioport_resource.start = ~0UL;
+ ioport_resource.end = 0UL;
+}
/*
* Machine-specific initialisation for KN01, aka DS2100 (aka Pmin)
@@ -206,7 +227,7 @@ static int_ptr kn01_cpu_mask_nr_tbl[][2] __initdata = {
{ .p = cpu_all_int } },
};
-void __init dec_init_kn01(void)
+static void __init dec_init_kn01(void)
{
/* IRQ routing. */
memcpy(&dec_interrupt, &kn01_interrupt,
@@ -281,7 +302,7 @@ static int_ptr kn230_cpu_mask_nr_tbl[][2] __initdata = {
{ .p = cpu_all_int } },
};
-void __init dec_init_kn230(void)
+static void __init dec_init_kn230(void)
{
/* IRQ routing. */
memcpy(&dec_interrupt, &kn230_interrupt,
@@ -371,7 +392,7 @@ static int_ptr kn02_asic_mask_nr_tbl[][2] __initdata = {
{ .p = kn02_all_int } },
};
-void __init dec_init_kn02(void)
+static void __init dec_init_kn02(void)
{
/* IRQ routing. */
memcpy(&dec_interrupt, &kn02_interrupt,
@@ -472,7 +493,7 @@ static int_ptr kn02ba_asic_mask_nr_tbl[][2] __initdata = {
{ .p = asic_all_int } },
};
-void __init dec_init_kn02ba(void)
+static void __init dec_init_kn02ba(void)
{
/* IRQ routing. */
memcpy(&dec_interrupt, &kn02ba_interrupt,
@@ -569,7 +590,7 @@ static int_ptr kn02ca_asic_mask_nr_tbl[][2] __initdata = {
{ .p = asic_all_int } },
};
-void __init dec_init_kn02ca(void)
+static void __init dec_init_kn02ca(void)
{
/* IRQ routing. */
memcpy(&dec_interrupt, &kn02ca_interrupt,
@@ -670,7 +691,7 @@ static int_ptr kn03_asic_mask_nr_tbl[][2] __initdata = {
{ .p = asic_all_int } },
};
-void __init dec_init_kn03(void)
+static void __init dec_init_kn03(void)
{
/* IRQ routing. */
memcpy(&dec_interrupt, &kn03_interrupt,
@@ -744,7 +765,3 @@ void __init arch_init_irq(void)
if (dec_interrupt[DEC_IRQ_HALT] >= 0)
setup_irq(dec_interrupt[DEC_IRQ_HALT], &haltirq);
}
-
-EXPORT_SYMBOL(ioasic_base);
-EXPORT_SYMBOL(dec_kn_slot_size);
-EXPORT_SYMBOL(dec_interrupt);
diff --git a/arch/mips/defconfig b/arch/mips/defconfig
index 20f84b119b4c..4b585e642c2a 100644
--- a/arch/mips/defconfig
+++ b/arch/mips/defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:48:59 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:09 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,25 +11,30 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
# CONFIG_HOTPLUG is not set
CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -42,6 +44,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -57,41 +60,69 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
CONFIG_SGI_IP22=y
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_ARC=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=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_ARC32=y
@@ -103,8 +134,10 @@ CONFIG_ARC_PROMLIB=y
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# 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
@@ -120,22 +153,48 @@ CONFIG_CPU_R5000=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_R4X00=y
+CONFIG_SYS_HAS_CPU_R5000=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=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_64KB is not set
CONFIG_BOARD_SCACHE=y
CONFIG_IP22_CPU_SCACHE=y
+# CONFIG_MIPS_MT is not set
# CONFIG_64BIT_PHYS_ADDR is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_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 is not set
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
#
# Bus options (PCI, PCMCIA, EISA, ISA, TC)
#
+CONFIG_HW_HAS_EISA=y
# CONFIG_EISA is not set
CONFIG_MMU=y
@@ -145,10 +204,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
@@ -160,115 +215,7 @@ CONFIG_BINFMT_MISC=m
CONFIG_TRAD_SIGNALS=y
#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_RAM is not set
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_ATA_OVER_ETH=m
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-CONFIG_SCSI=y
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=y
-# CONFIG_CHR_DEV_OSST is not set
-CONFIG_BLK_DEV_SR=y
-# CONFIG_BLK_DEV_SR_VENDOR is not set
-# CONFIG_CHR_DEV_SG is not set
-
-#
-# 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
-
-#
-# SCSI Transport Attributes
-#
-CONFIG_SCSI_SPI_ATTRS=m
-# CONFIG_SCSI_FC_ATTRS is not set
-CONFIG_SCSI_ISCSI_ATTRS=m
-
-#
-# SCSI low-level drivers
-#
-CONFIG_SGIWD93_SCSI=y
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Networking support
+# Networking
#
CONFIG_NET=y
@@ -277,12 +224,14 @@ CONFIG_NET=y
#
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
CONFIG_NET_KEY=y
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
@@ -296,8 +245,10 @@ CONFIG_INET_AH=m
CONFIG_INET_ESP=m
CONFIG_INET_IPCOMP=m
CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-CONFIG_IP_TCPDIAG_IPV6=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
#
# IP: Virtual Server Configuration
@@ -341,6 +292,9 @@ CONFIG_INET6_TUNNEL=m
CONFIG_IPV6_TUNNEL=m
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
#
# IP: Netfilter Configuration
@@ -348,11 +302,15 @@ CONFIG_NETFILTER=y
CONFIG_IP_NF_CONNTRACK=m
CONFIG_IP_NF_CT_ACCT=y
CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CONNTRACK_EVENTS=y
+CONFIG_IP_NF_CONNTRACK_NETLINK=m
# CONFIG_IP_NF_CT_PROTO_SCTP is not set
CONFIG_IP_NF_FTP=m
CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_NETBIOS_NS is not set
CONFIG_IP_NF_TFTP=m
CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_PPTP=m
CONFIG_IP_NF_QUEUE=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_LIMIT=m
@@ -376,9 +334,12 @@ CONFIG_IP_NF_MATCH_OWNER=m
CONFIG_IP_NF_MATCH_ADDRTYPE=m
CONFIG_IP_NF_MATCH_REALM=m
CONFIG_IP_NF_MATCH_SCTP=m
+CONFIG_IP_NF_MATCH_DCCP=m
CONFIG_IP_NF_MATCH_COMMENT=m
CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_CONNBYTES=m
CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_MATCH_STRING=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_TARGET_LOG=m
@@ -395,12 +356,14 @@ CONFIG_IP_NF_NAT_IRC=m
CONFIG_IP_NF_NAT_FTP=m
CONFIG_IP_NF_NAT_TFTP=m
CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_NAT_PPTP=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_TOS=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_DSCP=m
CONFIG_IP_NF_TARGET_MARK=m
CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_TARGET_CONNMARK=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_RAW=m
@@ -410,7 +373,7 @@ CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
#
-# IPv6: Netfilter Configuration
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
#
CONFIG_IP6_NF_QUEUE=m
CONFIG_IP6_NF_IPTABLES=m
@@ -429,11 +392,16 @@ CONFIG_IP6_NF_MATCH_LENGTH=m
CONFIG_IP6_NF_MATCH_EUI64=m
CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_TARGET_REJECT=m
CONFIG_IP6_NF_MANGLE=m
CONFIG_IP6_NF_TARGET_MARK=m
+CONFIG_IP6_NF_TARGET_HL=m
CONFIG_IP6_NF_RAW=m
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
#
# SCTP Configuration (EXPERIMENTAL)
@@ -456,10 +424,6 @@ CONFIG_SCTP_HMAC_MD5=y
CONFIG_NET_DIVERT=y
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
CONFIG_NET_SCHED=y
# CONFIG_NET_SCH_CLK_JIFFIES is not set
CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
@@ -479,6 +443,7 @@ CONFIG_NET_SCH_INGRESS=m
CONFIG_NET_QOS=y
CONFIG_NET_ESTIMATOR=y
CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
CONFIG_NET_CLS_TCINDEX=m
CONFIG_NET_CLS_ROUTE4=m
CONFIG_NET_CLS_ROUTE=y
@@ -489,6 +454,7 @@ CONFIG_NET_CLS_U32=m
# CONFIG_CLS_U32_MARK is not set
CONFIG_NET_CLS_RSVP=m
CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_EMATCH is not set
# CONFIG_NET_CLS_ACT is not set
CONFIG_NET_CLS_POLICE=y
@@ -496,17 +462,153 @@ CONFIG_NET_CLS_POLICE=y
# Network testing
#
# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+# CONFIG_CHR_DEV_SG is not set
+CONFIG_CHR_DEV_SCH=m
+
+#
+# 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
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_SGIWD93_SCSI=y
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
CONFIG_NETDEVICES=y
CONFIG_DUMMY=m
CONFIG_BONDING=m
CONFIG_EQUALIZER=m
CONFIG_TUN=m
-CONFIG_ETHERTAP=m
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
#
# Ethernet (10 or 100Mbit)
@@ -540,6 +642,8 @@ CONFIG_SGISEEQ=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -569,18 +673,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-CONFIG_SERIO_LIBPS2=y
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
@@ -598,6 +690,16 @@ CONFIG_MOUSE_SERIAL=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -644,11 +746,14 @@ CONFIG_SGI_DS1286=m
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
CONFIG_RAW_DRIVER=m
CONFIG_MAX_RAW_DEVS=256
#
+# TPM devices
+#
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -659,10 +764,20 @@ CONFIG_MAX_RAW_DEVS=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -693,7 +808,6 @@ CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_VGA16 is not set
# CONFIG_LOGO_LINUX_CLUT224 is not set
CONFIG_LOGO_SGI_CLUT224=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -707,10 +821,6 @@ CONFIG_LOGO_SGI_CLUT224=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
@@ -723,13 +833,17 @@ CONFIG_LOGO_SGI_CLUT224=y
#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
#
# File systems
#
CONFIG_EXT2_FS=m
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
@@ -741,12 +855,14 @@ CONFIG_FS_MBCACHE=y
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
CONFIG_XFS_FS=m
-# CONFIG_XFS_RT is not set
-CONFIG_XFS_QUOTA=y
+CONFIG_XFS_EXPORT=y
+CONFIG_XFS_QUOTA=m
CONFIG_XFS_SECURITY=y
# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
CONFIG_MINIX_FS=m
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
CONFIG_QUOTA=y
# CONFIG_QFMT_V1 is not set
CONFIG_QFMT_V2=m
@@ -754,6 +870,7 @@ CONFIG_QUOTACTL=y
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -781,12 +898,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -811,15 +926,20 @@ CONFIG_UFS_FS=m
#
CONFIG_NFS_FS=m
CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
# CONFIG_NFSD_V4 is not set
CONFIG_NFSD_TCP=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
@@ -835,6 +955,7 @@ CONFIG_CIFS=m
CONFIG_CODA_FS=m
# CONFIG_CODA_FS_OLD_API is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -908,7 +1029,9 @@ CONFIG_NLS_UTF8=m
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -931,6 +1054,7 @@ CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_DES=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_TWOFISH=m
@@ -942,10 +1066,10 @@ CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_DEFLATE=m
CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
-CONFIG_CRYPTO_TEST=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -955,9 +1079,12 @@ CONFIG_CRYPTO_TEST=m
# Library routines
#
# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=m
CONFIG_CRC32=m
CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
diff --git a/arch/mips/galileo-boards/ev96100/setup.c b/arch/mips/galileo-boards/ev96100/setup.c
index 28bd908c6d55..78dbb18edeb8 100644
--- a/arch/mips/galileo-boards/ev96100/setup.c
+++ b/arch/mips/galileo-boards/ev96100/setup.c
@@ -55,7 +55,7 @@ extern void mips_reboot_setup(void);
unsigned char mac_0_1[12];
-static void __init ev96100_setup(void)
+void __init plat_setup(void)
{
unsigned int config = read_c0_config();
unsigned int status = read_c0_status();
@@ -142,8 +142,6 @@ static void __init ev96100_setup(void)
tmp = GT_READ(GT_PCI0_CFGDATA_OFS);
}
-early_initcall(ev96100_setup);
-
unsigned short get_gt_devid(void)
{
u32 gt_devid;
diff --git a/arch/mips/gt64120/ev64120/Kconfig b/arch/mips/gt64120/ev64120/Kconfig
new file mode 100644
index 000000000000..d691762cb0f7
--- /dev/null
+++ b/arch/mips/gt64120/ev64120/Kconfig
@@ -0,0 +1,3 @@
+config EVB_PCI1
+ bool "Enable Second PCI (PCI1)"
+ depends on MIPS_EV64120
diff --git a/arch/mips/gt64120/ev64120/setup.c b/arch/mips/gt64120/ev64120/setup.c
index dba0961400cc..98b5a96cc039 100644
--- a/arch/mips/gt64120/ev64120/setup.c
+++ b/arch/mips/gt64120/ev64120/setup.c
@@ -69,7 +69,7 @@ unsigned long __init prom_free_prom_memory(void)
*/
extern void gt64120_time_init(void);
-static void __init ev64120_setup(void)
+void __init plat_setup(void)
{
_machine_restart = galileo_machine_restart;
_machine_halt = galileo_machine_halt;
@@ -79,8 +79,6 @@ static void __init ev64120_setup(void)
set_io_port_base(KSEG1);
}
-early_initcall(ev64120_setup);
-
const char *get_system_type(void)
{
return "Galileo EV64120A";
diff --git a/arch/mips/gt64120/momenco_ocelot/setup.c b/arch/mips/gt64120/momenco_ocelot/setup.c
index d610f8c17c81..0d07c33112d0 100644
--- a/arch/mips/gt64120/momenco_ocelot/setup.c
+++ b/arch/mips/gt64120/momenco_ocelot/setup.c
@@ -150,7 +150,7 @@ void PMON_v2_setup()
gt64120_base = 0xe0000000;
}
-static void __init momenco_ocelot_setup(void)
+void __init plat_setup(void)
{
void (*l3func)(unsigned long)=KSEG1ADDR(&setup_l3cache);
unsigned int tmpword;
@@ -307,8 +307,6 @@ static void __init momenco_ocelot_setup(void)
GT_WRITE(GT_DEV_B3_OFS, 0xfef73);
}
-early_initcall(momenco_ocelot_setup);
-
extern int rm7k_tcache_enabled;
/*
* This runs in KSEG1. See the verbiage in rm7k.c::probe_scache()
diff --git a/arch/mips/ite-boards/Kconfig b/arch/mips/ite-boards/Kconfig
new file mode 100644
index 000000000000..a6d59ad8f846
--- /dev/null
+++ b/arch/mips/ite-boards/Kconfig
@@ -0,0 +1,8 @@
+config IT8172_REVC
+ bool "Support for older IT8172 (Rev C)"
+ depends on MIPS_ITE8172
+ help
+ Say Y here to support the older, Revision C version of the Integrated
+ Technology Express, Inc. ITE8172 SBC. Vendor page at
+ <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the
+ board at <http://www.mvista.com/partners/semiconductor/ite.html>.
diff --git a/arch/mips/ite-boards/generic/irq.c b/arch/mips/ite-boards/generic/irq.c
index cb71b9024d6f..e67f96129491 100644
--- a/arch/mips/ite-boards/generic/irq.c
+++ b/arch/mips/ite-boards/generic/irq.c
@@ -138,14 +138,13 @@ static void end_ite_irq(unsigned int irq)
}
static struct hw_interrupt_type it8172_irq_type = {
- "ITE8172",
- startup_ite_irq,
- shutdown_ite_irq,
- enable_it8172_irq,
- disable_it8172_irq,
- mask_and_ack_ite_irq,
- end_ite_irq,
- NULL
+ .typename = "ITE8172",
+ .startup = startup_ite_irq,
+ .shutdown = shutdown_ite_irq,
+ .enable = enable_it8172_irq,
+ .disable = disable_it8172_irq,
+ .ack = mask_and_ack_ite_irq,
+ .end = end_ite_irq,
};
@@ -159,13 +158,13 @@ static void ack_none(unsigned int irq) { }
#define end_none enable_none
static struct hw_interrupt_type cp0_irq_type = {
- "CP0 Count",
- startup_none,
- shutdown_none,
- enable_none,
- disable_none,
- ack_none,
- end_none
+ .typename = "CP0 Count",
+ .startup = startup_none,
+ .shutdown = shutdown_none,
+ .enable = enable_none,
+ .disable = disable_none,
+ .ack = ack_none,
+ .end = end_none
};
void enable_cpu_timer(void)
@@ -182,7 +181,6 @@ void __init arch_init_irq(void)
int i;
unsigned long flags;
- memset(irq_desc, 0, sizeof(irq_desc));
set_except_vector(0, it8172_IRQ);
/* mask all interrupts */
diff --git a/arch/mips/ite-boards/generic/it8172_setup.c b/arch/mips/ite-boards/generic/it8172_setup.c
index a5f6d84bc181..062429dd7ca0 100644
--- a/arch/mips/ite-boards/generic/it8172_setup.c
+++ b/arch/mips/ite-boards/generic/it8172_setup.c
@@ -105,7 +105,7 @@ void __init it8172_init_ram_resource(unsigned long memsize)
it8172_resources.ram.end = memsize;
}
-static void __init it8172_setup(void)
+void __init plat_setup(void)
{
unsigned short dsr;
char *argptr;
@@ -251,8 +251,6 @@ static void __init it8172_setup(void)
#endif /* CONFIG_IT8172_SCR1 */
}
-early_initcall(it8172_setup);
-
#ifdef CONFIG_SERIO_I8042
/*
* According to the ITE Special BIOS Note for waking up the
diff --git a/arch/mips/jazz/Kconfig b/arch/mips/jazz/Kconfig
new file mode 100644
index 000000000000..1f372b0d2559
--- /dev/null
+++ b/arch/mips/jazz/Kconfig
@@ -0,0 +1,33 @@
+config ACER_PICA_61
+ bool "Support for Acer PICA 1 chipset (EXPERIMENTAL)"
+ depends on MACH_JAZZ && EXPERIMENTAL
+ select DMA_NONCOHERENT
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ help
+ This is a machine with a R4400 133/150 MHz CPU. To compile a Linux
+ kernel that runs on these, say Y here. For details about Linux on
+ the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
+ <http://www.linux-mips.org/>.
+
+config MIPS_MAGNUM_4000
+ bool "Support for MIPS Magnum 4000"
+ depends on MACH_JAZZ
+ select DMA_NONCOHERENT
+ select SYS_SUPPORTS_BIG_ENDIAN if EXPERIMENTAL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ help
+ This is a machine with a R4000 100 MHz CPU. To compile a Linux
+ kernel that runs on these, say Y here. For details about Linux on
+ the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
+ <http://www.linux-mips.org/>.
+
+config OLIVETTI_M700
+ bool "Support for Olivetti M700-10"
+ depends on MACH_JAZZ
+ select DMA_NONCOHERENT
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ help
+ This is a machine with a R4000 100 MHz CPU. To compile a Linux
+ kernel that runs on these, say Y here. For details about Linux on
+ the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
+ <http://www.linux-mips.org/>.
diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c
index 0b608fa98d5a..b309b1bcf2e8 100644
--- a/arch/mips/jazz/irq.c
+++ b/arch/mips/jazz/irq.c
@@ -58,14 +58,13 @@ static void end_r4030_irq(unsigned int irq)
}
static struct hw_interrupt_type r4030_irq_type = {
- "R4030",
- startup_r4030_irq,
- shutdown_r4030_irq,
- enable_r4030_irq,
- disable_r4030_irq,
- mask_and_ack_r4030_irq,
- end_r4030_irq,
- NULL
+ .typename = "R4030",
+ .startup = startup_r4030_irq,
+ .shutdown = shutdown_r4030_irq,
+ .enable = enable_r4030_irq,
+ .disable = disable_r4030_irq,
+ .ack = mask_and_ack_r4030_irq,
+ .end = end_r4030_irq,
};
void __init init_r4030_ints(void)
diff --git a/arch/mips/jazz/setup.c b/arch/mips/jazz/setup.c
index fccb06fe209d..044df9d4ab7c 100644
--- a/arch/mips/jazz/setup.c
+++ b/arch/mips/jazz/setup.c
@@ -50,7 +50,7 @@ static struct resource jazz_io_resources[] = {
{ "dma2", 0xc0, 0xdf, IORESOURCE_BUSY },
};
-static void __init jazz_setup(void)
+void __init plat_setup(void)
{
int i;
@@ -97,5 +97,3 @@ static void __init jazz_setup(void)
vdma_init();
}
-
-early_initcall(jazz_setup);
diff --git a/arch/mips/jmr3927/rbhma3100/irq.c b/arch/mips/jmr3927/rbhma3100/irq.c
index b9799b86fc79..7cbe14483f13 100644
--- a/arch/mips/jmr3927/rbhma3100/irq.c
+++ b/arch/mips/jmr3927/rbhma3100/irq.c
@@ -412,13 +412,13 @@ void __init arch_init_irq(void)
}
static hw_irq_controller jmr3927_irq_controller = {
- "jmr3927_irq",
- jmr3927_irq_startup,
- jmr3927_irq_shutdown,
- jmr3927_irq_enable,
- jmr3927_irq_disable,
- jmr3927_irq_ack,
- jmr3927_irq_end,
+ .typename = "jmr3927_irq",
+ .startup = jmr3927_irq_startup,
+ .shutdown = jmr3927_irq_shutdown,
+ .enable = jmr3927_irq_enable,
+ .disable = jmr3927_irq_disable,
+ .ack = jmr3927_irq_ack,
+ .end = jmr3927_irq_end,
};
void jmr3927_irq_init(u32 irq_base)
diff --git a/arch/mips/jmr3927/rbhma3100/setup.c b/arch/mips/jmr3927/rbhma3100/setup.c
index 32039bb2f440..3e2fbdc66097 100644
--- a/arch/mips/jmr3927/rbhma3100/setup.c
+++ b/arch/mips/jmr3927/rbhma3100/setup.c
@@ -44,6 +44,11 @@
#include <linux/ioport.h>
#include <linux/param.h> /* for HZ */
#include <linux/delay.h>
+#ifdef CONFIG_SERIAL_TXX9
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#endif
#include <asm/addrspace.h>
#include <asm/time.h>
@@ -193,7 +198,7 @@ static void jmr3927_board_init(void);
extern struct resource pci_io_resource;
extern struct resource pci_mem_resource;
-static void __init jmr3927_setup(void)
+void __init plat_setup(void)
{
char *argptr;
@@ -211,8 +216,8 @@ static void __init jmr3927_setup(void)
*/
ioport_resource.start = pci_io_resource.start;
ioport_resource.end = pci_io_resource.end;
- iomem_resource.start = pci_mem_resource.start;
- iomem_resource.end = pci_mem_resource.end;
+ iomem_resource.start = 0;
+ iomem_resource.end = 0xffffffff;
/* Reboot on panic */
panic_timeout = 180;
@@ -265,18 +270,35 @@ static void __init jmr3927_setup(void)
strcat(argptr, " ip=bootp");
}
-#ifdef CONFIG_TXX927_SERIAL_CONSOLE
+#ifdef CONFIG_SERIAL_TXX9
+ {
+ extern int early_serial_txx9_setup(struct uart_port *port);
+ int i;
+ struct uart_port req;
+ for(i = 0; i < 2; i++) {
+ memset(&req, 0, sizeof(req));
+ req.line = i;
+ req.iotype = UPIO_MEM;
+ req.membase = (char *)TX3927_SIO_REG(i);
+ req.mapbase = TX3927_SIO_REG(i);
+ req.irq = i == 0 ?
+ JMR3927_IRQ_IRC_SIO0 : JMR3927_IRQ_IRC_SIO1;
+ if (i == 0)
+ req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/;
+ req.uartclk = JMR3927_IMCLK;
+ early_serial_txx9_setup(&req);
+ }
+ }
+#ifdef CONFIG_SERIAL_TXX9_CONSOLE
argptr = prom_getcmdline();
if ((argptr = strstr(argptr, "console=")) == NULL) {
argptr = prom_getcmdline();
strcat(argptr, " console=ttyS1,115200");
}
#endif
+#endif
}
-early_initcall(jmr3927_setup);
-
-
static void tx3927_setup(void);
#ifdef CONFIG_PCI
@@ -335,7 +357,7 @@ static void __init jmr3927_board_init(void)
jmr3927_io_dipsw());
}
-static void __init tx3927_setup(void)
+void __init plat_setup(void)
{
int i;
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index d3303584fbd1..72f2126ad19d 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -11,11 +11,7 @@ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \
binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \
irix5sys.o sysirix.o
-ifdef CONFIG_MODULES
-obj-y += mips_ksyms.o module.o
-obj-$(CONFIG_32BIT) += module-elf32.o
-obj-$(CONFIG_64BIT) += module-elf64.o
-endif
+obj-$(CONFIG_MODULES) += mips_ksyms.o module.o
obj-$(CONFIG_CPU_R3000) += r2300_fpu.o r2300_switch.o
obj-$(CONFIG_CPU_TX39XX) += r2300_fpu.o r2300_switch.o
@@ -38,12 +34,18 @@ obj-$(CONFIG_CPU_R6000) += r6000_fpu.o r4k_switch.o
obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_MIPS_MT_SMP) += smp_mt.o
+
+obj-$(CONFIG_MIPS_VPE_LOADER) += vpe.o
+obj-$(CONFIG_MIPS_VPE_APSP_API) += rtlx.o
+
obj-$(CONFIG_NO_ISA) += dma-no-isa.o
obj-$(CONFIG_I8259) += i8259.o
obj-$(CONFIG_IRQ_CPU) += irq_cpu.o
obj-$(CONFIG_IRQ_CPU_RM7K) += irq-rm7000.o
obj-$(CONFIG_IRQ_CPU_RM9K) += irq-rm9000.o
obj-$(CONFIG_IRQ_MV64340) += irq-mv6434x.o
+obj-$(CONFIG_MIPS_BOARDS_GEN) += irq-msc01.o
obj-$(CONFIG_32BIT) += scall32-o32.o
obj-$(CONFIG_64BIT) += scall64-64.o
@@ -57,8 +59,6 @@ obj-$(CONFIG_PROC_FS) += proc.o
obj-$(CONFIG_64BIT) += cpu-bugs64.o
-obj-$(CONFIG_GEN_RTC) += genrtc.o
-
CFLAGS_cpu-bugs64.o = $(shell if $(CC) $(CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi)
CFLAGS_ioctl32.o += -Ifs/
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
index 2c11abb5a406..ca6b03c773be 100644
--- a/arch/mips/kernel/asm-offsets.c
+++ b/arch/mips/kernel/asm-offsets.c
@@ -95,6 +95,7 @@ void output_thread_info_defines(void)
offset("#define TI_PRE_COUNT ", struct thread_info, preempt_count);
offset("#define TI_ADDR_LIMIT ", struct thread_info, addr_limit);
offset("#define TI_RESTART_BLOCK ", struct thread_info, restart_block);
+ offset("#define TI_TP_VALUE ", struct thread_info, tp_value);
constant("#define _THREAD_SIZE_ORDER ", THREAD_SIZE_ORDER);
constant("#define _THREAD_SIZE ", THREAD_SIZE);
constant("#define _THREAD_MASK ", THREAD_MASK);
@@ -240,6 +241,7 @@ void output_mm_defines(void)
linefeed;
}
+#ifdef CONFIG_32BIT
void output_sc_defines(void)
{
text("/* Linux sigcontext offsets. */");
@@ -251,10 +253,29 @@ void output_sc_defines(void)
offset("#define SC_STATUS ", struct sigcontext, sc_status);
offset("#define SC_FPC_CSR ", struct sigcontext, sc_fpc_csr);
offset("#define SC_FPC_EIR ", struct sigcontext, sc_fpc_eir);
- offset("#define SC_CAUSE ", struct sigcontext, sc_cause);
- offset("#define SC_BADVADDR ", struct sigcontext, sc_badvaddr);
+ offset("#define SC_HI1 ", struct sigcontext, sc_hi1);
+ offset("#define SC_LO1 ", struct sigcontext, sc_lo1);
+ offset("#define SC_HI2 ", struct sigcontext, sc_hi2);
+ offset("#define SC_LO2 ", struct sigcontext, sc_lo2);
+ offset("#define SC_HI3 ", struct sigcontext, sc_hi3);
+ offset("#define SC_LO3 ", struct sigcontext, sc_lo3);
linefeed;
}
+#endif
+
+#ifdef CONFIG_64BIT
+void output_sc_defines(void)
+{
+ text("/* Linux sigcontext offsets. */");
+ offset("#define SC_REGS ", struct sigcontext, sc_regs);
+ offset("#define SC_FPREGS ", struct sigcontext, sc_fpregs);
+ offset("#define SC_MDHI ", struct sigcontext, sc_hi);
+ offset("#define SC_MDLO ", struct sigcontext, sc_lo);
+ offset("#define SC_PC ", struct sigcontext, sc_pc);
+ offset("#define SC_FPC_CSR ", struct sigcontext, sc_fpc_csr);
+ linefeed;
+}
+#endif
#ifdef CONFIG_MIPS32_COMPAT
void output_sc32_defines(void)
diff --git a/arch/mips/kernel/binfmt_elfn32.c b/arch/mips/kernel/binfmt_elfn32.c
index 6b645fbb1ddc..d8e2674a1543 100644
--- a/arch/mips/kernel/binfmt_elfn32.c
+++ b/arch/mips/kernel/binfmt_elfn32.c
@@ -52,7 +52,6 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
#include <asm/processor.h>
#include <linux/module.h>
-#include <linux/config.h>
#include <linux/elfcore.h>
#include <linux/compat.h>
@@ -116,4 +115,7 @@ MODULE_AUTHOR("Ralf Baechle (ralf@linux-mips.org)");
#undef MODULE_DESCRIPTION
#undef MODULE_AUTHOR
+#undef TASK_SIZE
+#define TASK_SIZE TASK_SIZE32
+
#include "../../../fs/binfmt_elf.c"
diff --git a/arch/mips/kernel/binfmt_elfo32.c b/arch/mips/kernel/binfmt_elfo32.c
index b4075e99c452..cec5f327e360 100644
--- a/arch/mips/kernel/binfmt_elfo32.c
+++ b/arch/mips/kernel/binfmt_elfo32.c
@@ -54,7 +54,6 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
#include <asm/processor.h>
#include <linux/module.h>
-#include <linux/config.h>
#include <linux/elfcore.h>
#include <linux/compat.h>
@@ -98,7 +97,7 @@ struct elf_prpsinfo32
#define init_elf_binfmt init_elf32_binfmt
#define jiffies_to_timeval jiffies_to_compat_timeval
-static __inline__ void
+static inline void
jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
{
/*
@@ -113,21 +112,26 @@ jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
#undef ELF_CORE_COPY_REGS
#define ELF_CORE_COPY_REGS(_dest,_regs) elf32_core_copy_regs(_dest,_regs);
-void elf32_core_copy_regs(elf_gregset_t _dest, struct pt_regs *_regs)
+void elf32_core_copy_regs(elf_gregset_t grp, struct pt_regs *regs)
{
int i;
- memset(_dest, 0, sizeof(elf_gregset_t));
-
- /* XXXKW the 6 is from EF_REG0 in gdb/gdb/mips-linux-tdep.c, include/asm-mips/reg.h */
- for (i=6; i<38; i++)
- _dest[i] = (elf_greg_t) _regs->regs[i-6];
- _dest[i++] = (elf_greg_t) _regs->lo;
- _dest[i++] = (elf_greg_t) _regs->hi;
- _dest[i++] = (elf_greg_t) _regs->cp0_epc;
- _dest[i++] = (elf_greg_t) _regs->cp0_badvaddr;
- _dest[i++] = (elf_greg_t) _regs->cp0_status;
- _dest[i++] = (elf_greg_t) _regs->cp0_cause;
+ for (i = 0; i < EF_R0; i++)
+ grp[i] = 0;
+ grp[EF_R0] = 0;
+ for (i = 1; i <= 31; i++)
+ grp[EF_R0 + i] = (elf_greg_t) regs->regs[i];
+ grp[EF_R26] = 0;
+ grp[EF_R27] = 0;
+ grp[EF_LO] = (elf_greg_t) regs->lo;
+ grp[EF_HI] = (elf_greg_t) regs->hi;
+ grp[EF_CP0_EPC] = (elf_greg_t) regs->cp0_epc;
+ grp[EF_CP0_BADVADDR] = (elf_greg_t) regs->cp0_badvaddr;
+ grp[EF_CP0_STATUS] = (elf_greg_t) regs->cp0_status;
+ grp[EF_CP0_CAUSE] = (elf_greg_t) regs->cp0_cause;
+#ifdef EF_UNUSED0
+ grp[EF_UNUSED0] = 0;
+#endif
}
MODULE_DESCRIPTION("Binary format loader for compatibility with o32 Linux/MIPS binaries");
@@ -136,4 +140,7 @@ MODULE_AUTHOR("Ralf Baechle (ralf@linux-mips.org)");
#undef MODULE_DESCRIPTION
#undef MODULE_AUTHOR
+#undef TASK_SIZE
+#define TASK_SIZE TASK_SIZE32
+
#include "../../../fs/binfmt_elf.c"
diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c
index 01117e977a7f..374de839558d 100644
--- a/arch/mips/kernel/branch.c
+++ b/arch/mips/kernel/branch.c
@@ -12,6 +12,7 @@
#include <asm/branch.h>
#include <asm/cpu.h>
#include <asm/cpu-features.h>
+#include <asm/fpu.h>
#include <asm/inst.h>
#include <asm/ptrace.h>
#include <asm/uaccess.h>
@@ -21,7 +22,7 @@
*/
int __compute_return_epc(struct pt_regs *regs)
{
- unsigned int *addr, bit, fcr31;
+ unsigned int *addr, bit, fcr31, dspcontrol;
long epc;
union mips_instruction insn;
@@ -98,6 +99,18 @@ int __compute_return_epc(struct pt_regs *regs)
epc += 8;
regs->cp0_epc = epc;
break;
+ case bposge32_op:
+ if (!cpu_has_dsp)
+ goto sigill;
+
+ dspcontrol = rddsp(0x01);
+
+ if (dspcontrol >= 32) {
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ } else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
}
break;
@@ -161,10 +174,13 @@ int __compute_return_epc(struct pt_regs *regs)
* And now the FPA/cp1 branch instructions.
*/
case cop1_op:
- if (!cpu_has_fpu)
- fcr31 = current->thread.fpu.soft.fcr31;
- else
+ preempt_disable();
+ if (is_fpu_owner())
asm volatile("cfc1\t%0,$31" : "=r" (fcr31));
+ else
+ fcr31 = current->thread.fpu.hard.fcr31;
+ preempt_enable();
+
bit = (insn.i_format.rt >> 2);
bit += (bit != 0);
bit += 23;
@@ -196,4 +212,9 @@ unaligned:
printk("%s: unaligned epc - sending SIGBUS.\n", current->comm);
force_sig(SIGBUS, current);
return -EFAULT;
+
+sigill:
+ printk("%s: DSP branch but not DSP ASE - sending SIGBUS.\n", current->comm);
+ force_sig(SIGBUS, current);
+ return -EFAULT;
}
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 7685f8baf3f0..a263fb7a3971 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -2,9 +2,9 @@
* Processor capabilities determination functions.
*
* Copyright (C) xxxx the Anonymous
- * Copyright (C) 2003 Maciej W. Rozycki
+ * Copyright (C) 2003, 2004 Maciej W. Rozycki
* Copyright (C) 1994 - 2003 Ralf Baechle
- * Copyright (C) 2001 MIPS Inc.
+ * Copyright (C) 2001, 2004 MIPS Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -17,7 +17,6 @@
#include <linux/ptrace.h>
#include <linux/stddef.h>
-#include <asm/bugs.h>
#include <asm/cpu.h>
#include <asm/fpu.h>
#include <asm/mipsregs.h>
@@ -51,36 +50,48 @@ static void r4k_wait(void)
".set\tmips0");
}
-/*
- * The Au1xxx wait is available only if we run CONFIG_PM and
- * the timer setup found we had a 32KHz counter available.
- * There are still problems with functions that may call au1k_wait
- * directly, but that will be discovered pretty quickly.
- */
-extern void (*au1k_wait_ptr)(void);
+/* The Au1xxx wait is available only if using 32khz counter or
+ * external timer source, but specifically not CP0 Counter. */
+int allow_au1k_wait;
-void au1k_wait(void)
+static void au1k_wait(void)
{
-#ifdef CONFIG_PM
/* using the wait instruction makes CP0 counter unusable */
- __asm__(".set\tmips3\n\t"
+ __asm__(".set mips3\n\t"
+ "cache 0x14, 0(%0)\n\t"
+ "cache 0x14, 32(%0)\n\t"
+ "sync\n\t"
+ "nop\n\t"
"wait\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
- ".set\tmips0");
-#else
- __asm__("nop\n\t"
- "nop");
-#endif
+ ".set mips0\n\t"
+ : : "r" (au1k_wait));
}
+static int __initdata nowait = 0;
+
+int __init wait_disable(char *s)
+{
+ nowait = 1;
+
+ return 1;
+}
+
+__setup("nowait", wait_disable);
+
static inline void check_wait(void)
{
struct cpuinfo_mips *c = &current_cpu_data;
printk("Checking for 'wait' instruction... ");
+ if (nowait) {
+ printk (" disabled.\n");
+ return;
+ }
+
switch (c->cputype) {
case CPU_R3081:
case CPU_R3081E:
@@ -109,22 +120,22 @@ static inline void check_wait(void)
/* case CPU_20KC:*/
case CPU_24K:
case CPU_25KF:
+ case CPU_34K:
+ case CPU_PR4450:
cpu_wait = r4k_wait;
printk(" available.\n");
break;
-#ifdef CONFIG_PM
case CPU_AU1000:
case CPU_AU1100:
case CPU_AU1500:
- if (au1k_wait_ptr != NULL) {
- cpu_wait = au1k_wait_ptr;
+ case CPU_AU1550:
+ case CPU_AU1200:
+ if (allow_au1k_wait) {
+ cpu_wait = au1k_wait;
printk(" available.\n");
- }
- else {
+ } else
printk(" unavailable.\n");
- }
break;
-#endif
default:
printk(" unavailable.\n");
break;
@@ -180,7 +191,7 @@ static inline int __cpu_has_fpu(void)
return ((cpu_get_fpu_id() & 0xff00) != FPIR_IMP_NONE);
}
-#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4KTLB \
+#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE \
| MIPS_CPU_COUNTER)
static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
@@ -189,7 +200,8 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
case PRID_IMP_R2000:
c->cputype = CPU_R2000;
c->isa_level = MIPS_CPU_ISA_I;
- c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX;
+ c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
+ MIPS_CPU_NOFPUEX;
if (__cpu_has_fpu())
c->options |= MIPS_CPU_FPU;
c->tlbsize = 64;
@@ -203,7 +215,8 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
else
c->cputype = CPU_R3000;
c->isa_level = MIPS_CPU_ISA_I;
- c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX;
+ c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
+ MIPS_CPU_NOFPUEX;
if (__cpu_has_fpu())
c->options |= MIPS_CPU_FPU;
c->tlbsize = 64;
@@ -266,7 +279,8 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
case PRID_IMP_R4600:
c->cputype = CPU_R4600;
c->isa_level = MIPS_CPU_ISA_III;
- c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC;
+ c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
+ MIPS_CPU_LLSC;
c->tlbsize = 48;
break;
#if 0
@@ -285,7 +299,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
#endif
case PRID_IMP_TX39:
c->isa_level = MIPS_CPU_ISA_I;
- c->options = MIPS_CPU_TLB;
+ c->options = MIPS_CPU_TLB | MIPS_CPU_TX39_CACHE;
if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) {
c->cputype = CPU_TX3927;
@@ -421,74 +435,147 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
}
}
-static inline void decode_config1(struct cpuinfo_mips *c)
+static inline unsigned int decode_config0(struct cpuinfo_mips *c)
{
- unsigned long config0 = read_c0_config();
- unsigned long config1;
+ unsigned int config0;
+ int isa;
+
+ config0 = read_c0_config();
- if ((config0 & (1 << 31)) == 0)
- return; /* actually wort a panic() */
+ if (((config0 & MIPS_CONF_MT) >> 7) == 1)
+ c->options |= MIPS_CPU_TLB;
+ isa = (config0 & MIPS_CONF_AT) >> 13;
+ switch (isa) {
+ case 0:
+ c->isa_level = MIPS_CPU_ISA_M32;
+ break;
+ case 2:
+ c->isa_level = MIPS_CPU_ISA_M64;
+ break;
+ default:
+ panic("Unsupported ISA type, cp0.config0.at: %d.", isa);
+ }
+
+ return config0 & MIPS_CONF_M;
+}
+
+static inline unsigned int decode_config1(struct cpuinfo_mips *c)
+{
+ unsigned int config1;
- /* MIPS32 or MIPS64 compliant CPU. Read Config 1 register. */
- c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
- MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC |
- MIPS_CPU_LLSC | MIPS_CPU_MCHECK;
config1 = read_c0_config1();
- if (config1 & (1 << 3))
+
+ if (config1 & MIPS_CONF1_MD)
+ c->ases |= MIPS_ASE_MDMX;
+ if (config1 & MIPS_CONF1_WR)
c->options |= MIPS_CPU_WATCH;
- if (config1 & (1 << 2))
- c->options |= MIPS_CPU_MIPS16;
- if (config1 & (1 << 1))
+ if (config1 & MIPS_CONF1_CA)
+ c->ases |= MIPS_ASE_MIPS16;
+ if (config1 & MIPS_CONF1_EP)
c->options |= MIPS_CPU_EJTAG;
- if (config1 & 1) {
+ if (config1 & MIPS_CONF1_FP) {
c->options |= MIPS_CPU_FPU;
c->options |= MIPS_CPU_32FPR;
}
+ if (cpu_has_tlb)
+ c->tlbsize = ((config1 & MIPS_CONF1_TLBS) >> 25) + 1;
+
+ return config1 & MIPS_CONF_M;
+}
+
+static inline unsigned int decode_config2(struct cpuinfo_mips *c)
+{
+ unsigned int config2;
+
+ config2 = read_c0_config2();
+
+ if (config2 & MIPS_CONF2_SL)
+ c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
+
+ return config2 & MIPS_CONF_M;
+}
+
+static inline unsigned int decode_config3(struct cpuinfo_mips *c)
+{
+ unsigned int config3;
+
+ config3 = read_c0_config3();
+
+ if (config3 & MIPS_CONF3_SM)
+ c->ases |= MIPS_ASE_SMARTMIPS;
+ if (config3 & MIPS_CONF3_DSP)
+ c->ases |= MIPS_ASE_DSP;
+ if (config3 & MIPS_CONF3_VINT)
+ c->options |= MIPS_CPU_VINT;
+ if (config3 & MIPS_CONF3_VEIC)
+ c->options |= MIPS_CPU_VEIC;
+ if (config3 & MIPS_CONF3_MT)
+ c->ases |= MIPS_ASE_MIPSMT;
+
+ return config3 & MIPS_CONF_M;
+}
+
+static inline void decode_configs(struct cpuinfo_mips *c)
+{
+ /* MIPS32 or MIPS64 compliant CPU. */
+ c->options = MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER |
+ MIPS_CPU_DIVEC | MIPS_CPU_LLSC | MIPS_CPU_MCHECK;
+
c->scache.flags = MIPS_CACHE_NOT_PRESENT;
- c->tlbsize = ((config1 >> 25) & 0x3f) + 1;
+ /* Read Config registers. */
+ if (!decode_config0(c))
+ return; /* actually worth a panic() */
+ if (!decode_config1(c))
+ return;
+ if (!decode_config2(c))
+ return;
+ if (!decode_config3(c))
+ return;
}
static inline void cpu_probe_mips(struct cpuinfo_mips *c)
{
- decode_config1(c);
+ decode_configs(c);
switch (c->processor_id & 0xff00) {
case PRID_IMP_4KC:
c->cputype = CPU_4KC;
- c->isa_level = MIPS_CPU_ISA_M32;
break;
case PRID_IMP_4KEC:
c->cputype = CPU_4KEC;
- c->isa_level = MIPS_CPU_ISA_M32;
+ break;
+ case PRID_IMP_4KECR2:
+ c->cputype = CPU_4KEC;
break;
case PRID_IMP_4KSC:
+ case PRID_IMP_4KSD:
c->cputype = CPU_4KSC;
- c->isa_level = MIPS_CPU_ISA_M32;
break;
case PRID_IMP_5KC:
c->cputype = CPU_5KC;
- c->isa_level = MIPS_CPU_ISA_M64;
break;
case PRID_IMP_20KC:
c->cputype = CPU_20KC;
- c->isa_level = MIPS_CPU_ISA_M64;
break;
case PRID_IMP_24K:
+ case PRID_IMP_24KE:
c->cputype = CPU_24K;
- c->isa_level = MIPS_CPU_ISA_M32;
break;
case PRID_IMP_25KF:
c->cputype = CPU_25KF;
- c->isa_level = MIPS_CPU_ISA_M64;
/* Probe for L2 cache */
c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
break;
+ case PRID_IMP_34K:
+ c->cputype = CPU_34K;
+ c->isa_level = MIPS_CPU_ISA_M32;
+ break;
}
}
static inline void cpu_probe_alchemy(struct cpuinfo_mips *c)
{
- decode_config1(c);
+ decode_configs(c);
switch (c->processor_id & 0xff00) {
case PRID_IMP_AU1_REV1:
case PRID_IMP_AU1_REV2:
@@ -505,50 +592,70 @@ static inline void cpu_probe_alchemy(struct cpuinfo_mips *c)
case 3:
c->cputype = CPU_AU1550;
break;
+ case 4:
+ c->cputype = CPU_AU1200;
+ break;
default:
panic("Unknown Au Core!");
break;
}
- c->isa_level = MIPS_CPU_ISA_M32;
break;
}
}
static inline void cpu_probe_sibyte(struct cpuinfo_mips *c)
{
- decode_config1(c);
+ decode_configs(c);
+
+ /*
+ * For historical reasons the SB1 comes with it's own variant of
+ * cache code which eventually will be folded into c-r4k.c. Until
+ * then we pretend it's got it's own cache architecture.
+ */
+ c->options &= ~MIPS_CPU_4K_CACHE;
+ c->options |= MIPS_CPU_SB1_CACHE;
+
switch (c->processor_id & 0xff00) {
case PRID_IMP_SB1:
c->cputype = CPU_SB1;
- c->isa_level = MIPS_CPU_ISA_M64;
- c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
- MIPS_CPU_COUNTER | MIPS_CPU_DIVEC |
- MIPS_CPU_MCHECK | MIPS_CPU_EJTAG |
- MIPS_CPU_WATCH | MIPS_CPU_LLSC;
-#ifndef CONFIG_SB1_PASS_1_WORKAROUNDS
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
/* FPU in pass1 is known to have issues. */
- c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR;
+ c->options &= ~(MIPS_CPU_FPU | MIPS_CPU_32FPR);
#endif
break;
+ case PRID_IMP_SB1A:
+ c->cputype = CPU_SB1A;
+ break;
}
}
static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c)
{
- decode_config1(c);
+ decode_configs(c);
switch (c->processor_id & 0xff00) {
case PRID_IMP_SR71000:
c->cputype = CPU_SR71000;
- c->isa_level = MIPS_CPU_ISA_M64;
- c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
- MIPS_CPU_4KTLB | MIPS_CPU_FPU |
- MIPS_CPU_COUNTER | MIPS_CPU_MCHECK;
c->scache.ways = 8;
c->tlbsize = 64;
break;
}
}
+static inline void cpu_probe_philips(struct cpuinfo_mips *c)
+{
+ decode_configs(c);
+ switch (c->processor_id & 0xff00) {
+ case PRID_IMP_PR4450:
+ c->cputype = CPU_PR4450;
+ c->isa_level = MIPS_CPU_ISA_M32;
+ break;
+ default:
+ panic("Unknown Philips Core!"); /* REVISIT: die? */
+ break;
+ }
+}
+
+
__init void cpu_probe(void)
{
struct cpuinfo_mips *c = &current_cpu_data;
@@ -571,15 +678,24 @@ __init void cpu_probe(void)
case PRID_COMP_SIBYTE:
cpu_probe_sibyte(c);
break;
-
case PRID_COMP_SANDCRAFT:
cpu_probe_sandcraft(c);
break;
+ case PRID_COMP_PHILIPS:
+ cpu_probe_philips(c);
+ break;
default:
c->cputype = CPU_UNKNOWN;
}
- if (c->options & MIPS_CPU_FPU)
+ if (c->options & MIPS_CPU_FPU) {
c->fpu_id = cpu_get_fpu_id();
+
+ if (c->isa_level == MIPS_CPU_ISA_M32 ||
+ c->isa_level == MIPS_CPU_ISA_M64) {
+ if (c->fpu_id & MIPS_FPIR_3D)
+ c->ases |= MIPS_ASE_MIPS3D;
+ }
+ }
}
__init void cpu_report(void)
diff --git a/arch/mips/kernel/dma-no-isa.c b/arch/mips/kernel/dma-no-isa.c
new file mode 100644
index 000000000000..6df8b07741e3
--- /dev/null
+++ b/arch/mips/kernel/dma-no-isa.c
@@ -0,0 +1,28 @@
+/*
+ * 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 by Ralf Baechle
+ *
+ * Dummy ISA DMA functions for systems that don't have ISA but share drivers
+ * with ISA such as legacy free PCI.
+ */
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+
+DEFINE_SPINLOCK(dma_spin_lock);
+
+int request_dma(unsigned int dmanr, const char * device_id)
+{
+ return -EINVAL;
+}
+
+void free_dma(unsigned int dmanr)
+{
+}
+
+EXPORT_SYMBOL(dma_spin_lock);
+EXPORT_SYMBOL(request_dma);
+EXPORT_SYMBOL(free_dma);
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S
index 5eb429137e06..83c87fe4ee4f 100644
--- a/arch/mips/kernel/entry.S
+++ b/arch/mips/kernel/entry.S
@@ -19,11 +19,11 @@
#include <asm/war.h>
#ifdef CONFIG_PREEMPT
- .macro preempt_stop reg=t0
+ .macro preempt_stop
.endm
#else
- .macro preempt_stop reg=t0
- local_irq_disable \reg
+ .macro preempt_stop
+ local_irq_disable
.endm
#define resume_kernel restore_all
#endif
@@ -37,17 +37,18 @@ FEXPORT(ret_from_irq)
andi t0, t0, KU_USER
beqz t0, resume_kernel
-FEXPORT(resume_userspace)
- local_irq_disable t0 # make sure we dont miss an
+resume_userspace:
+ local_irq_disable # make sure we dont miss an
# interrupt setting need_resched
# between sampling and return
LONG_L a2, TI_FLAGS($28) # current->work
- andi a2, _TIF_WORK_MASK # (ignoring syscall_trace)
- bnez a2, work_pending
+ andi t0, a2, _TIF_WORK_MASK # (ignoring syscall_trace)
+ bnez t0, work_pending
j restore_all
#ifdef CONFIG_PREEMPT
-ENTRY(resume_kernel)
+resume_kernel:
+ local_irq_disable
lw t0, TI_PRE_COUNT($28)
bnez t0, restore_all
need_resched:
@@ -57,12 +58,7 @@ need_resched:
LONG_L t0, PT_STATUS(sp) # Interrupts off?
andi t0, 1
beqz t0, restore_all
- li t0, PREEMPT_ACTIVE
- sw t0, TI_PRE_COUNT($28)
- local_irq_enable t0
- jal schedule
- sw zero, TI_PRE_COUNT($28)
- local_irq_disable t0
+ jal preempt_schedule_irq
b need_resched
#endif
@@ -88,13 +84,13 @@ FEXPORT(restore_partial) # restore partial frame
RESTORE_SP_AND_RET
.set at
-FEXPORT(work_pending)
- andi t0, a2, _TIF_NEED_RESCHED
+work_pending:
+ andi t0, a2, _TIF_NEED_RESCHED # a2 is preloaded with TI_FLAGS
beqz t0, work_notifysig
work_resched:
jal schedule
- local_irq_disable t0 # make sure need_resched and
+ local_irq_disable # make sure need_resched and
# signals dont change between
# sampling and return
LONG_L a2, TI_FLAGS($28)
@@ -109,15 +105,14 @@ work_notifysig: # deal with pending signals and
move a0, sp
li a1, 0
jal do_notify_resume # a2 already loaded
- j restore_all
+ j resume_userspace
FEXPORT(syscall_exit_work_partial)
SAVE_STATIC
-FEXPORT(syscall_exit_work)
- LONG_L t0, TI_FLAGS($28)
- li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
- and t0, t1
- beqz t0, work_pending # trace bit is set
+syscall_exit_work:
+ li t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+ and t0, a2 # a2 is preloaded with TI_FLAGS
+ beqz t0, work_pending # trace bit set?
local_irq_enable # could let do_syscall_trace()
# call schedule() instead
move a0, sp
@@ -128,28 +123,25 @@ FEXPORT(syscall_exit_work)
/*
* Common spurious interrupt handler.
*/
- .text
- .align 5
LEAF(spurious_interrupt)
/*
* Someone tried to fool us by sending an interrupt but we
* couldn't find a cause for it.
*/
+ PTR_LA t1, irq_err_count
#ifdef CONFIG_SMP
- lui t1, %hi(irq_err_count)
-1: ll t0, %lo(irq_err_count)(t1)
+1: ll t0, (t1)
addiu t0, 1
- sc t0, %lo(irq_err_count)(t1)
+ sc t0, (t1)
#if R10000_LLSC_WAR
beqzl t0, 1b
#else
beqz t0, 1b
#endif
#else
- lui t1, %hi(irq_err_count)
- lw t0, %lo(irq_err_count)(t1)
+ lw t0, (t1)
addiu t0, 1
- sw t0, %lo(irq_err_count)(t1)
+ sw t0, (t1)
#endif
j ret_from_irq
END(spurious_interrupt)
diff --git a/arch/mips/kernel/gdb-low.S b/arch/mips/kernel/gdb-low.S
index 512bedbfa7b9..83b8986f9401 100644
--- a/arch/mips/kernel/gdb-low.S
+++ b/arch/mips/kernel/gdb-low.S
@@ -52,16 +52,15 @@
/*
* Called from user mode, go somewhere else.
*/
- lui k1, %hi(saved_vectors)
mfc0 k0, CP0_CAUSE
andi k0, k0, 0x7c
add k1, k1, k0
- lw k0, %lo(saved_vectors)(k1)
+ PTR_L k0, saved_vectors(k1)
jr k0
nop
1:
move k0, sp
- subu sp, k1, GDB_FR_SIZE*2 # see comment above
+ PTR_SUBU sp, k1, GDB_FR_SIZE*2 # see comment above
LONG_S k0, GDB_FR_REG29(sp)
LONG_S $2, GDB_FR_REG2(sp)
diff --git a/arch/mips/kernel/gdb-stub.c b/arch/mips/kernel/gdb-stub.c
index d3fd1ab14274..96d18c43dca0 100644
--- a/arch/mips/kernel/gdb-stub.c
+++ b/arch/mips/kernel/gdb-stub.c
@@ -176,8 +176,10 @@ int kgdb_enabled;
/*
* spin locks for smp case
*/
-static spinlock_t kgdb_lock = SPIN_LOCK_UNLOCKED;
-static spinlock_t kgdb_cpulock[NR_CPUS] = { [0 ... NR_CPUS-1] = SPIN_LOCK_UNLOCKED};
+static DEFINE_SPINLOCK(kgdb_lock);
+static raw_spinlock_t kgdb_cpulock[NR_CPUS] = {
+ [0 ... NR_CPUS-1] = __RAW_SPIN_LOCK_UNLOCKED;
+};
/*
* BUFMAX defines the maximum number of characters in inbound/outbound buffers
@@ -637,29 +639,32 @@ static struct gdb_bp_save async_bp;
* and only one can be active at a time.
*/
extern spinlock_t smp_call_lock;
+
void set_async_breakpoint(unsigned long *epc)
{
/* skip breaking into userland */
if ((*epc & 0x80000000) == 0)
return;
+#ifdef CONFIG_SMP
/* avoid deadlock if someone is make IPC */
if (spin_is_locked(&smp_call_lock))
return;
+#endif
async_bp.addr = *epc;
*epc = (unsigned long)async_breakpoint;
}
-void kgdb_wait(void *arg)
+static void kgdb_wait(void *arg)
{
unsigned flags;
int cpu = smp_processor_id();
local_irq_save(flags);
- spin_lock(&kgdb_cpulock[cpu]);
- spin_unlock(&kgdb_cpulock[cpu]);
+ __raw_spin_lock(&kgdb_cpulock[cpu]);
+ __raw_spin_unlock(&kgdb_cpulock[cpu]);
local_irq_restore(flags);
}
@@ -707,7 +712,7 @@ void handle_exception (struct gdb_regs *regs)
* acquire the CPU spinlocks
*/
for (i = num_online_cpus()-1; i >= 0; i--)
- if (spin_trylock(&kgdb_cpulock[i]) == 0)
+ if (__raw_spin_trylock(&kgdb_cpulock[i]) == 0)
panic("kgdb: couldn't get cpulock %d\n", i);
/*
@@ -982,7 +987,7 @@ finish_kgdb:
exit_kgdb_exception:
/* release locks so other CPUs can go */
for (i = num_online_cpus()-1; i >= 0; i--)
- spin_unlock(&kgdb_cpulock[i]);
+ __raw_spin_unlock(&kgdb_cpulock[i]);
spin_unlock(&kgdb_lock);
__flush_cache_all();
@@ -1036,12 +1041,12 @@ void adel(void)
* malloc is needed by gdb client in "call func()", even a private one
* will make gdb happy
*/
-static void *malloc(size_t size)
+static void * __attribute_used__ malloc(size_t size)
{
return kmalloc(size, GFP_ATOMIC);
}
-static void free(void *where)
+static void __attribute_used__ free (void *where)
{
kfree(where);
}
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
index e7f6c1b90806..aa18a8b7b380 100644
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -82,7 +82,7 @@ NESTED(except_vec3_r4000, 0, sp)
li k0, 14<<2
beq k1, k0, handle_vcei
#ifdef CONFIG_64BIT
- dsll k1, k1, 1
+ dsll k1, k1, 1
#endif
.set pop
PTR_L k0, exception_handlers(k1)
@@ -90,17 +90,17 @@ NESTED(except_vec3_r4000, 0, sp)
/*
* Big shit, we now may have two dirty primary cache lines for the same
- * physical address. We can savely invalidate the line pointed to by
+ * physical address. We can safely invalidate the line pointed to by
* c0_badvaddr because after return from this exception handler the
* load / store will be re-executed.
*/
handle_vced:
- DMFC0 k0, CP0_BADVADDR
+ MFC0 k0, CP0_BADVADDR
li k1, -4 # Is this ...
and k0, k1 # ... really needed?
mtc0 zero, CP0_TAGLO
- cache Index_Store_Tag_D,(k0)
- cache Hit_Writeback_Inv_SD,(k0)
+ cache Index_Store_Tag_D, (k0)
+ cache Hit_Writeback_Inv_SD, (k0)
#ifdef CONFIG_PROC_FS
PTR_LA k0, vced_count
lw k1, (k0)
@@ -148,6 +148,38 @@ NESTED(except_vec_ejtag_debug, 0, sp)
__FINIT
/*
+ * Vectored interrupt handler.
+ * This prototype is copied to ebase + n*IntCtl.VS and patched
+ * to invoke the handler
+ */
+NESTED(except_vec_vi, 0, sp)
+ SAVE_SOME
+ SAVE_AT
+ .set push
+ .set noreorder
+EXPORT(except_vec_vi_lui)
+ lui v0, 0 /* Patched */
+ j except_vec_vi_handler
+EXPORT(except_vec_vi_ori)
+ ori v0, 0 /* Patched */
+ .set pop
+ END(except_vec_vi)
+EXPORT(except_vec_vi_end)
+
+/*
+ * Common Vectored Interrupt code
+ * Complete the register saves and invoke the handler which is passed in $v0
+ */
+NESTED(except_vec_vi_handler, 0, sp)
+ SAVE_TEMP
+ SAVE_STATIC
+ CLI
+ move a0, sp
+ jalr v0
+ j ret_from_irq
+ END(except_vec_vi_handler)
+
+/*
* EJTAG debug exception handler.
*/
NESTED(ejtag_debug_handler, PT_SIZE, sp)
@@ -291,6 +323,8 @@ NESTED(nmi_handler, PT_SIZE, sp)
BUILD_HANDLER mdmx mdmx sti silent /* #22 */
BUILD_HANDLER watch watch sti verbose /* #23 */
BUILD_HANDLER mcheck mcheck cli verbose /* #24 */
+ BUILD_HANDLER mt mt sti verbose /* #25 */
+ BUILD_HANDLER dsp dsp sti silent /* #26 */
BUILD_HANDLER reserved reserved sti verbose /* others */
#ifdef CONFIG_64BIT
diff --git a/arch/mips/kernel/genrtc.c b/arch/mips/kernel/genrtc.c
deleted file mode 100644
index 71416e7bbbaa..000000000000
--- a/arch/mips/kernel/genrtc.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * A glue layer that provides RTC read/write to drivers/char/genrtc.c driver
- * based on MIPS internal RTC routines. It does take care locking
- * issues so that we are SMP/Preemption safe.
- *
- * Copyright (C) 2004 MontaVista Software Inc.
- * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
- *
- * Please read the COPYING file for all license details.
- */
-
-#include <linux/spinlock.h>
-
-#include <asm/rtc.h>
-#include <asm/time.h>
-
-static DEFINE_SPINLOCK(mips_rtc_lock);
-
-unsigned int get_rtc_time(struct rtc_time *time)
-{
- unsigned long nowtime;
-
- spin_lock(&mips_rtc_lock);
- nowtime = rtc_get_time();
- to_tm(nowtime, time);
- time->tm_year -= 1900;
- spin_unlock(&mips_rtc_lock);
-
- return RTC_24H;
-}
-
-int set_rtc_time(struct rtc_time *time)
-{
- unsigned long nowtime;
- int ret;
-
- spin_lock(&mips_rtc_lock);
- nowtime = mktime(time->tm_year+1900, time->tm_mon+1,
- time->tm_mday, time->tm_hour, time->tm_min,
- time->tm_sec);
- ret = rtc_set_time(nowtime);
- spin_unlock(&mips_rtc_lock);
-
- return ret;
-}
-
-unsigned int get_rtc_ss(void)
-{
- struct rtc_time h;
-
- get_rtc_time(&h);
- return h.tm_sec;
-}
-
-int get_rtc_pll(struct rtc_pll_info *pll)
-{
- return -EINVAL;
-}
-
-int set_rtc_pll(struct rtc_pll_info *pll)
-{
- return -EINVAL;
-}
-
diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S
index 2a1b45d66f04..2e9122a4213a 100644
--- a/arch/mips/kernel/head.S
+++ b/arch/mips/kernel/head.S
@@ -22,11 +22,8 @@
#include <asm/page.h>
#include <asm/mipsregs.h>
#include <asm/stackframe.h>
-#ifdef CONFIG_SGI_IP27
-#include <asm/sn/addrs.h>
-#include <asm/sn/sn0/hubni.h>
-#include <asm/sn/klkernvars.h>
-#endif
+
+#include <kernel-entry-init.h>
.macro ARC64_TWIDDLE_PC
#if defined(CONFIG_ARC64) || defined(CONFIG_MAPPED_KERNEL)
@@ -38,18 +35,6 @@
#endif
.endm
-#ifdef CONFIG_SGI_IP27
- /*
- * outputs the local nasid into res. IP27 stuff.
- */
- .macro GET_NASID_ASM res
- dli \res, LOCAL_HUB_ADDR(NI_STATUS_REV_ID)
- ld \res, (\res)
- and \res, NSRI_NODEID_MASK
- dsrl \res, NSRI_NODEID_SHFT
- .endm
-#endif /* CONFIG_SGI_IP27 */
-
/*
* inputs are the text nasid in t1, data nasid in t2.
*/
@@ -131,16 +116,21 @@
EXPORT(stext) # used for profiling
EXPORT(_stext)
+#if defined(CONFIG_QEMU) || defined(CONFIG_MIPS_SIM)
+ /*
+ * Give us a fighting chance of running if execution beings at the
+ * kernel load address. This is needed because this platform does
+ * not have a ELF loader yet.
+ */
+ j kernel_entry
+#endif
__INIT
NESTED(kernel_entry, 16, sp) # kernel entry point
- setup_c0_status_pri
-#ifdef CONFIG_SGI_IP27
- GET_NASID_ASM t1
- move t2, t1 # text and data are here
- MAPPED_KERNEL_SETUP_TLB
-#endif /* IP27 */
+ kernel_entry_setup # cpu specific setup
+
+ setup_c0_status_pri
ARC64_TWIDDLE_PC
@@ -157,6 +147,7 @@ NESTED(kernel_entry, 16, sp) # kernel entry point
LONG_S a2, fw_arg2
LONG_S a3, fw_arg3
+ MTC0 zero, CP0_CONTEXT # clear context register
PTR_LA $28, init_thread_union
PTR_ADDIU sp, $28, _THREAD_SIZE - 32
set_saved_sp sp, t0, t1
@@ -165,6 +156,10 @@ NESTED(kernel_entry, 16, sp) # kernel entry point
j start_kernel
END(kernel_entry)
+#ifdef CONFIG_QEMU
+ __INIT
+#endif
+
#ifdef CONFIG_SMP
/*
* SMP slave cpus entry point. Board specific code for bootstrap calls this
@@ -172,20 +167,7 @@ NESTED(kernel_entry, 16, sp) # kernel entry point
*/
NESTED(smp_bootstrap, 16, sp)
setup_c0_status_sec
-
-#ifdef CONFIG_SGI_IP27
- GET_NASID_ASM t1
- dli t0, KLDIR_OFFSET + (KLI_KERN_VARS * KLDIR_ENT_SIZE) + \
- KLDIR_OFF_POINTER + CAC_BASE
- dsll t1, NASID_SHFT
- or t0, t0, t1
- ld t0, 0(t0) # t0 points to kern_vars struct
- lh t1, KV_RO_NASID_OFFSET(t0)
- lh t2, KV_RW_NASID_OFFSET(t0)
- MAPPED_KERNEL_SETUP_TLB
- ARC64_TWIDDLE_PC
-#endif /* CONFIG_SGI_IP27 */
-
+ smp_slave_setup
j start_secondary
END(smp_bootstrap)
#endif /* CONFIG_SMP */
@@ -200,19 +182,13 @@ NESTED(smp_bootstrap, 16, sp)
.comm fw_arg2, SZREG, SZREG
.comm fw_arg3, SZREG, SZREG
- .macro page name, order=0
- .globl \name
-\name: .size \name, (_PAGE_SIZE << \order)
- .org . + (_PAGE_SIZE << \order)
- .type \name, @object
+ .macro page name, order
+ .comm \name, (_PAGE_SIZE << \order), (_PAGE_SIZE << \order)
.endm
- .data
- .align PAGE_SHIFT
-
/*
- * ... but on 64-bit we've got three-level pagetables with a
- * slightly different layout ...
+ * On 64-bit we've got three-level pagetables with a slightly
+ * different layout ...
*/
page swapper_pg_dir, _PGD_ORDER
#ifdef CONFIG_64BIT
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c
index 447759201d1d..b974ac9057f6 100644
--- a/arch/mips/kernel/i8259.c
+++ b/arch/mips/kernel/i8259.c
@@ -31,7 +31,7 @@ void disable_8259A_irq(unsigned int irq);
* moves to arch independent land
*/
-spinlock_t DEFINE_SPINLOCK(i8259A_lock);
+DEFINE_SPINLOCK(i8259A_lock);
static void end_8259A_irq (unsigned int irq)
{
@@ -52,14 +52,13 @@ static unsigned int startup_8259A_irq(unsigned int irq)
}
static struct hw_interrupt_type i8259A_irq_type = {
- "XT-PIC",
- startup_8259A_irq,
- shutdown_8259A_irq,
- enable_8259A_irq,
- disable_8259A_irq,
- mask_and_ack_8259A,
- end_8259A_irq,
- NULL
+ .typename = "XT-PIC",
+ .startup = startup_8259A_irq,
+ .shutdown = shutdown_8259A_irq,
+ .enable = enable_8259A_irq,
+ .disable = disable_8259A_irq,
+ .ack = mask_and_ack_8259A,
+ .end = end_8259A_irq,
};
/*
@@ -308,7 +307,7 @@ static struct resource pic2_io_resource = {
/*
* On systems with i8259-style interrupt controllers we assume for
- * driver compatibility reasons interrupts 0 - 15 to be the i8295
+ * driver compatibility reasons interrupts 0 - 15 to be the i8259
* interrupts even if the hardware uses a different interrupt numbering.
*/
void __init init_i8259_irqs (void)
@@ -322,7 +321,7 @@ void __init init_i8259_irqs (void)
for (i = 0; i < 16; i++) {
irq_desc[i].status = IRQ_DISABLED;
- irq_desc[i].action = 0;
+ irq_desc[i].action = NULL;
irq_desc[i].depth = 1;
irq_desc[i].handler = &i8259A_irq_type;
}
diff --git a/arch/mips/kernel/ioctl32.c b/arch/mips/kernel/ioctl32.c
index c069719ff0d8..ed9b2da510be 100644
--- a/arch/mips/kernel/ioctl32.c
+++ b/arch/mips/kernel/ioctl32.c
@@ -41,12 +41,6 @@ IOCTL_TABLE_START
#define DECLARES
#include "compat_ioctl.c"
-#ifdef CONFIG_SIBYTE_TBPROF
-COMPATIBLE_IOCTL(SBPROF_ZBSTART)
-COMPATIBLE_IOCTL(SBPROF_ZBSTOP)
-COMPATIBLE_IOCTL(SBPROF_ZBWAITFULL)
-#endif /* CONFIG_SIBYTE_TBPROF */
-
/*HANDLE_IOCTL(RTC_IRQP_READ, w_long)
COMPATIBLE_IOCTL(RTC_IRQP_SET)
HANDLE_IOCTL(RTC_EPOCH_READ, w_long)
diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
index 4af20cd91f9f..10d3644e3608 100644
--- a/arch/mips/kernel/irixelf.c
+++ b/arch/mips/kernel/irixelf.c
@@ -8,7 +8,7 @@
*
* Copyright (C) 1993 - 1994 Eric Youngdale <ericy@cais.com>
* Copyright (C) 1996 - 2004 David S. Miller <dm@engr.sgi.com>
- * Copyright (C) 2004 Steven J. Hill <sjhill@realitydiluted.com>
+ * Copyright (C) 2004 - 2005 Steven J. Hill <sjhill@realitydiluted.com>
*/
#include <linux/module.h>
#include <linux/fs.h>
@@ -31,15 +31,16 @@
#include <linux/elfcore.h>
#include <linux/smp_lock.h>
-#include <asm/uaccess.h>
#include <asm/mipsregs.h>
+#include <asm/namei.h>
#include <asm/prctl.h>
+#include <asm/uaccess.h>
#define DLINFO_ITEMS 12
#include <linux/elf.h>
-#undef DEBUG_ELF
+#undef DEBUG
static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs);
static int load_irix_library(struct file *);
@@ -55,7 +56,7 @@ static struct linux_binfmt irix_format = {
#define elf_addr_t unsigned long
#endif
-#ifdef DEBUG_ELF
+#ifdef DEBUG
/* Debugging routines. */
static char *get_elf_p_type(Elf32_Word p_type)
{
@@ -120,7 +121,7 @@ static void dump_phdrs(struct elf_phdr *ep, int pnum)
print_phdr(i, ep);
}
}
-#endif /* (DEBUG_ELF) */
+#endif /* DEBUG */
static void set_brk(unsigned long start, unsigned long end)
{
@@ -146,20 +147,20 @@ static void padzero(unsigned long elf_bss)
nbyte = elf_bss & (PAGE_SIZE-1);
if (nbyte) {
nbyte = PAGE_SIZE - nbyte;
- clear_user((void *) elf_bss, nbyte);
+ clear_user((void __user *) elf_bss, nbyte);
}
}
-unsigned long * create_irix_tables(char * p, int argc, int envc,
- struct elfhdr * exec, unsigned int load_addr,
- unsigned int interp_load_addr,
- struct pt_regs *regs, struct elf_phdr *ephdr)
+static unsigned long * create_irix_tables(char * p, int argc, int envc,
+ struct elfhdr * exec, unsigned int load_addr,
+ unsigned int interp_load_addr, struct pt_regs *regs,
+ struct elf_phdr *ephdr)
{
elf_addr_t *argv;
elf_addr_t *envp;
elf_addr_t *sp, *csp;
-#ifdef DEBUG_ELF
+#ifdef DEBUG
printk("create_irix_tables: p[%p] argc[%d] envc[%d] "
"load_addr[%08x] interp_load_addr[%08x]\n",
p, argc, envc, load_addr, interp_load_addr);
@@ -248,14 +249,13 @@ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex,
last_bss = 0;
error = load_addr = 0;
-#ifdef DEBUG_ELF
+#ifdef DEBUG
print_elfhdr(interp_elf_ex);
#endif
/* First of all, some simple consistency checks */
if ((interp_elf_ex->e_type != ET_EXEC &&
interp_elf_ex->e_type != ET_DYN) ||
- !irix_elf_check_arch(interp_elf_ex) ||
!interpreter->f_op->mmap) {
printk("IRIX interp has bad e_type %d\n", interp_elf_ex->e_type);
return 0xffffffff;
@@ -290,7 +290,7 @@ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex,
(char *) elf_phdata,
sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
-#ifdef DEBUG_ELF
+#ifdef DEBUG
dump_phdrs(elf_phdata, interp_elf_ex->e_phnum);
#endif
@@ -306,13 +306,11 @@ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex,
elf_type |= MAP_FIXED;
vaddr = eppnt->p_vaddr;
-#ifdef DEBUG_ELF
- printk("INTERP do_mmap(%p, %08lx, %08lx, %08lx, %08lx, %08lx) ",
+ pr_debug("INTERP do_mmap(%p, %08lx, %08lx, %08lx, %08lx, %08lx) ",
interpreter, vaddr,
(unsigned long) (eppnt->p_filesz + (eppnt->p_vaddr & 0xfff)),
(unsigned long) elf_prot, (unsigned long) elf_type,
(unsigned long) (eppnt->p_offset & 0xfffff000));
-#endif
down_write(&current->mm->mmap_sem);
error = do_mmap(interpreter, vaddr,
eppnt->p_filesz + (eppnt->p_vaddr & 0xfff),
@@ -324,14 +322,10 @@ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex,
printk("Aieee IRIX interp mmap error=%d\n", error);
break; /* Real error */
}
-#ifdef DEBUG_ELF
- printk("error=%08lx ", (unsigned long) error);
-#endif
+ pr_debug("error=%08lx ", (unsigned long) error);
if(!load_addr && interp_elf_ex->e_type == ET_DYN) {
load_addr = error;
-#ifdef DEBUG_ELF
- printk("load_addr = error ");
-#endif
+ pr_debug("load_addr = error ");
}
/* Find the end of the file mapping for this phdr, and keep
@@ -345,17 +339,13 @@ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex,
*/
k = eppnt->p_memsz + eppnt->p_vaddr;
if(k > last_bss) last_bss = k;
-#ifdef DEBUG_ELF
- printk("\n");
-#endif
+ pr_debug("\n");
}
}
/* Now use mmap to map the library into memory. */
if(error < 0 && error > -1024) {
-#ifdef DEBUG_ELF
- printk("got error %d\n", error);
-#endif
+ pr_debug("got error %d\n", error);
kfree(elf_phdata);
return 0xffffffff;
}
@@ -365,16 +355,12 @@ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex,
* that there are zero-mapped pages up to and including the
* last bss page.
*/
-#ifdef DEBUG_ELF
- printk("padzero(%08lx) ", (unsigned long) (elf_bss));
-#endif
+ pr_debug("padzero(%08lx) ", (unsigned long) (elf_bss));
padzero(elf_bss);
len = (elf_bss + 0xfff) & 0xfffff000; /* What we have mapped so far */
-#ifdef DEBUG_ELF
- printk("last_bss[%08lx] len[%08lx]\n", (unsigned long) last_bss,
- (unsigned long) len);
-#endif
+ pr_debug("last_bss[%08lx] len[%08lx]\n", (unsigned long) last_bss,
+ (unsigned long) len);
/* Map the last of the bss segment */
if (last_bss > len) {
@@ -396,12 +382,7 @@ static int verify_binary(struct elfhdr *ehp, struct linux_binprm *bprm)
/* First of all, some simple consistency checks */
if((ehp->e_type != ET_EXEC && ehp->e_type != ET_DYN) ||
- !irix_elf_check_arch(ehp) || !bprm->file->f_op->mmap) {
- return -ENOEXEC;
- }
-
- /* Only support MIPS ARCH2 or greater IRIX binaries for now. */
- if(!(ehp->e_flags & EF_MIPS_ARCH) && !(ehp->e_flags & 0x04)) {
+ !bprm->file->f_op->mmap) {
return -ENOEXEC;
}
@@ -411,16 +392,17 @@ static int verify_binary(struct elfhdr *ehp, struct linux_binprm *bprm)
* XXX all registers as 64bits on cpu's capable of this at
* XXX exception time plus frob the XTLB exception vector.
*/
- if((ehp->e_flags & 0x20)) {
+ if((ehp->e_flags & EF_MIPS_ABI2))
return -ENOEXEC;
- }
- return 0; /* It's ok. */
+ return 0;
}
-#define IRIX_INTERP_PREFIX "/usr/gnemul/irix"
-
-/* Look for an IRIX ELF interpreter. */
+/*
+ * This is where the detailed check is performed. Irix binaries
+ * use interpreters with 'libc.so' in the name, so this function
+ * can differentiate between Linux and Irix binaries.
+ */
static inline int look_for_irix_interpreter(char **name,
struct file **interpreter,
struct elfhdr *interp_elf_ex,
@@ -440,12 +422,11 @@ static inline int look_for_irix_interpreter(char **name,
if (*name != NULL)
goto out;
- *name = kmalloc((epp->p_filesz + strlen(IRIX_INTERP_PREFIX)),
- GFP_KERNEL);
+ *name = kmalloc(epp->p_filesz + strlen(IRIX_EMUL), GFP_KERNEL);
if (!*name)
return -ENOMEM;
- strcpy(*name, IRIX_INTERP_PREFIX);
+ strcpy(*name, IRIX_EMUL);
retval = kernel_read(bprm->file, epp->p_offset, (*name + 16),
epp->p_filesz);
if (retval < 0)
@@ -562,7 +543,7 @@ static inline int map_interpreter(struct elf_phdr *epp, struct elfhdr *ihp,
* process and the system, here we map the page and fill the
* structure
*/
-void irix_map_prda_page (void)
+static void irix_map_prda_page(void)
{
unsigned long v;
struct prda *pp;
@@ -601,14 +582,33 @@ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
load_addr = 0;
has_interp = has_ephdr = 0;
- elf_ihdr = elf_ephdr = 0;
+ elf_ihdr = elf_ephdr = NULL;
elf_ex = *((struct elfhdr *) bprm->buf);
retval = -ENOEXEC;
if (verify_binary(&elf_ex, bprm))
goto out;
-#ifdef DEBUG_ELF
+ /*
+ * Telling -o32 static binaries from Linux and Irix apart from each
+ * other is difficult. There are 2 differences to be noted for static
+ * binaries from the 2 operating systems:
+ *
+ * 1) Irix binaries have their .text section before their .init
+ * section. Linux binaries are just the opposite.
+ *
+ * 2) Irix binaries usually have <= 12 sections and Linux
+ * binaries have > 20.
+ *
+ * We will use Method #2 since Method #1 would require us to read in
+ * the section headers which is way too much overhead. This appears
+ * to work for everything we have ran into so far. If anyone has a
+ * better method to tell the binaries apart, I'm listening.
+ */
+ if (elf_ex.e_shnum > 20)
+ goto out;
+
+#ifdef DEBUG
print_elfhdr(&elf_ex);
#endif
@@ -623,11 +623,10 @@ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
}
retval = kernel_read(bprm->file, elf_ex.e_phoff, (char *)elf_phdata, size);
-
if (retval < 0)
goto out_free_ph;
-#ifdef DEBUG_ELF
+#ifdef DEBUG
dump_phdrs(elf_phdata, elf_ex.e_phnum);
#endif
@@ -644,9 +643,8 @@ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
break;
};
}
-#ifdef DEBUG_ELF
- printk("\n");
-#endif
+
+ pr_debug("\n");
elf_bss = 0;
elf_brk = 0;
@@ -657,12 +655,19 @@ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
end_code = 0;
end_data = 0;
- retval = look_for_irix_interpreter(&elf_interpreter,
- &interpreter,
+ /*
+ * If we get a return value, we change the value to be ENOEXEC
+ * so that we can exit gracefully and the main binary format
+ * search loop in 'fs/exec.c' will move onto the next handler
+ * which should be the normal ELF binary handler.
+ */
+ retval = look_for_irix_interpreter(&elf_interpreter, &interpreter,
&interp_elf_ex, elf_phdata, bprm,
elf_ex.e_phnum);
- if (retval)
+ if (retval) {
+ retval = -ENOEXEC;
goto out_free_file;
+ }
if (elf_interpreter) {
retval = verify_irix_interpreter(&interp_elf_ex);
@@ -692,7 +697,6 @@ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
/* Do this so that we can load the interpreter, if need be. We will
* change some of these later.
*/
- set_mm_counter(current->mm, rss, 0);
setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT);
current->mm->start_stack = bprm->p;
@@ -746,18 +750,16 @@ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
* IRIX maps a page at 0x200000 which holds some system
* information. Programs depend on this.
*/
- irix_map_prda_page ();
+ irix_map_prda_page();
padzero(elf_bss);
-#ifdef DEBUG_ELF
- printk("(start_brk) %lx\n" , (long) current->mm->start_brk);
- printk("(end_code) %lx\n" , (long) current->mm->end_code);
- printk("(start_code) %lx\n" , (long) current->mm->start_code);
- printk("(end_data) %lx\n" , (long) current->mm->end_data);
- printk("(start_stack) %lx\n" , (long) current->mm->start_stack);
- printk("(brk) %lx\n" , (long) current->mm->brk);
-#endif
+ pr_debug("(start_brk) %lx\n" , (long) current->mm->start_brk);
+ pr_debug("(end_code) %lx\n" , (long) current->mm->end_code);
+ pr_debug("(start_code) %lx\n" , (long) current->mm->start_code);
+ pr_debug("(end_data) %lx\n" , (long) current->mm->end_data);
+ pr_debug("(start_stack) %lx\n" , (long) current->mm->start_stack);
+ pr_debug("(brk) %lx\n" , (long) current->mm->brk);
#if 0 /* XXX No fucking way dude... */
/* Why this, you ask??? Well SVr4 maps page 0 as read-only,
@@ -782,8 +784,7 @@ out_free_dentry:
allow_write_access(interpreter);
fput(interpreter);
out_free_interp:
- if (elf_interpreter)
- kfree(elf_interpreter);
+ kfree(elf_interpreter);
out_free_file:
out_free_ph:
kfree (elf_phdata);
@@ -813,7 +814,7 @@ static int load_irix_library(struct file *file)
/* First of all, some simple consistency checks. */
if(elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
- !irix_elf_check_arch(&elf_ex) || !file->f_op->mmap)
+ !file->f_op->mmap)
return -ENOEXEC;
/* Now read in all of the header information. */
@@ -874,35 +875,36 @@ static int load_irix_library(struct file *file)
* phdrs there are in the USER_PHDRP array. We return the vaddr the
* first phdr was successfully mapped to.
*/
-unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt)
+unsigned long irix_mapelf(int fd, struct elf_phdr __user *user_phdrp, int cnt)
{
- struct elf_phdr *hp;
+ unsigned long type, vaddr, filesz, offset, flags;
+ struct elf_phdr __user *hp;
struct file *filp;
int i, retval;
-#ifdef DEBUG_ELF
- printk("irix_mapelf: fd[%d] user_phdrp[%p] cnt[%d]\n",
- fd, user_phdrp, cnt);
-#endif
+ pr_debug("irix_mapelf: fd[%d] user_phdrp[%p] cnt[%d]\n",
+ fd, user_phdrp, cnt);
/* First get the verification out of the way. */
hp = user_phdrp;
if (!access_ok(VERIFY_READ, hp, (sizeof(struct elf_phdr) * cnt))) {
-#ifdef DEBUG_ELF
- printk("irix_mapelf: access_ok fails!\n");
-#endif
+ pr_debug("irix_mapelf: bad pointer to ELF PHDR!\n");
+
return -EFAULT;
}
-#ifdef DEBUG_ELF
+#ifdef DEBUG
dump_phdrs(user_phdrp, cnt);
#endif
- for(i = 0; i < cnt; i++, hp++)
- if(hp->p_type != PT_LOAD) {
+ for (i = 0; i < cnt; i++, hp++) {
+ if (__get_user(type, &hp->p_type))
+ return -EFAULT;
+ if (type != PT_LOAD) {
printk("irix_mapelf: One section is not PT_LOAD!\n");
return -ENOEXEC;
}
+ }
filp = fget(fd);
if (!filp)
@@ -917,29 +919,40 @@ unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt)
for(i = 0; i < cnt; i++, hp++) {
int prot;
- prot = (hp->p_flags & PF_R) ? PROT_READ : 0;
- prot |= (hp->p_flags & PF_W) ? PROT_WRITE : 0;
- prot |= (hp->p_flags & PF_X) ? PROT_EXEC : 0;
+ retval = __get_user(vaddr, &hp->p_vaddr);
+ retval |= __get_user(filesz, &hp->p_filesz);
+ retval |= __get_user(offset, &hp->p_offset);
+ retval |= __get_user(flags, &hp->p_flags);
+ if (retval)
+ return retval;
+
+ prot = (flags & PF_R) ? PROT_READ : 0;
+ prot |= (flags & PF_W) ? PROT_WRITE : 0;
+ prot |= (flags & PF_X) ? PROT_EXEC : 0;
+
down_write(&current->mm->mmap_sem);
- retval = do_mmap(filp, (hp->p_vaddr & 0xfffff000),
- (hp->p_filesz + (hp->p_vaddr & 0xfff)),
+ retval = do_mmap(filp, (vaddr & 0xfffff000),
+ (filesz + (vaddr & 0xfff)),
prot, (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
- (hp->p_offset & 0xfffff000));
+ (offset & 0xfffff000));
up_write(&current->mm->mmap_sem);
- if(retval != (hp->p_vaddr & 0xfffff000)) {
+ if (retval != (vaddr & 0xfffff000)) {
printk("irix_mapelf: do_mmap fails with %d!\n", retval);
fput(filp);
return retval;
}
}
-#ifdef DEBUG_ELF
- printk("irix_mapelf: Success, returning %08lx\n",
- (unsigned long) user_phdrp->p_vaddr);
-#endif
+ pr_debug("irix_mapelf: Success, returning %08lx\n",
+ (unsigned long) user_phdrp->p_vaddr);
+
fput(filp);
- return user_phdrp->p_vaddr;
+
+ if (__get_user(vaddr, &user_phdrp->p_vaddr))
+ return -EFAULT;
+
+ return vaddr;
}
/*
@@ -952,9 +965,9 @@ unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt)
/* These are the only things you should do on a core-file: use only these
* functions to write out all the necessary info.
*/
-static int dump_write(struct file *file, const void *addr, int nr)
+static int dump_write(struct file *file, const void __user *addr, int nr)
{
- return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
+ return file->f_op->write(file, (const char __user *) addr, nr, &file->f_pos) == nr;
}
static int dump_seek(struct file *file, off_t off)
@@ -1064,8 +1077,8 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
struct elfhdr elf;
off_t offset = 0, dataoff;
int limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
- int numnote = 4;
- struct memelfnote notes[4];
+ int numnote = 3;
+ struct memelfnote notes[3];
struct elf_prstatus prstatus; /* NT_PRSTATUS */
elf_fpregset_t fpu; /* NT_PRFPREG */
struct elf_prpsinfo psinfo; /* NT_PRPSINFO */
@@ -1073,7 +1086,7 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
/* Count what's needed to dump, up to the limit of coredump size. */
segs = 0;
size = 0;
- for(vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
+ for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
if (maydump(vma))
{
int sz = vma->vm_end-vma->vm_start;
@@ -1187,9 +1200,9 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
len = current->mm->arg_end - current->mm->arg_start;
len = len >= ELF_PRARGSZ ? ELF_PRARGSZ : len;
- copy_from_user(&psinfo.pr_psargs,
- (const char *)current->mm->arg_start, len);
- for(i = 0; i < len; i++)
+ (void *) copy_from_user(&psinfo.pr_psargs,
+ (const char __user *)current->mm->arg_start, len);
+ for (i = 0; i < len; i++)
if (psinfo.pr_psargs[i] == 0)
psinfo.pr_psargs[i] = ' ';
psinfo.pr_psargs[len] = 0;
@@ -1198,20 +1211,15 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
}
strlcpy(psinfo.pr_fname, current->comm, sizeof(psinfo.pr_fname));
- notes[2].name = "CORE";
- notes[2].type = NT_TASKSTRUCT;
- notes[2].datasz = sizeof(*current);
- notes[2].data = current;
-
/* Try to dump the FPU. */
prstatus.pr_fpvalid = dump_fpu (regs, &fpu);
if (!prstatus.pr_fpvalid) {
numnote--;
} else {
- notes[3].name = "CORE";
- notes[3].type = NT_PRFPREG;
- notes[3].datasz = sizeof(fpu);
- notes[3].data = &fpu;
+ notes[2].name = "CORE";
+ notes[2].type = NT_PRFPREG;
+ notes[2].datasz = sizeof(fpu);
+ notes[2].data = &fpu;
}
/* Write notes phdr entry. */
@@ -1256,8 +1264,10 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
phdr.p_memsz = sz;
offset += phdr.p_filesz;
phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
- if (vma->vm_flags & VM_WRITE) phdr.p_flags |= PF_W;
- if (vma->vm_flags & VM_EXEC) phdr.p_flags |= PF_X;
+ if (vma->vm_flags & VM_WRITE)
+ phdr.p_flags |= PF_W;
+ if (vma->vm_flags & VM_EXEC)
+ phdr.p_flags |= PF_X;
phdr.p_align = PAGE_SIZE;
DUMP_WRITE(&phdr, sizeof(phdr));
@@ -1283,7 +1293,7 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
#ifdef DEBUG
printk("elf_core_dump: writing %08lx %lx\n", addr, len);
#endif
- DUMP_WRITE((void *)addr, len);
+ DUMP_WRITE((void __user *)addr, len);
}
if ((off_t) file->f_pos != offset) {
@@ -1299,7 +1309,7 @@ end_coredump:
static int __init init_irix_binfmt(void)
{
- int init_inventory(void);
+ extern int init_inventory(void);
extern asmlinkage unsigned long sys_call_table;
extern asmlinkage unsigned long sys_call_table_irix5;
@@ -1318,7 +1328,9 @@ static int __init init_irix_binfmt(void)
static void __exit exit_irix_binfmt(void)
{
- /* Remove the IRIX ELF loaders. */
+ /*
+ * Remove the Irix ELF loader.
+ */
unregister_binfmt(&irix_format);
}
diff --git a/arch/mips/kernel/irixinv.c b/arch/mips/kernel/irixinv.c
index 60aa98cd1791..de8584f62311 100644
--- a/arch/mips/kernel/irixinv.c
+++ b/arch/mips/kernel/irixinv.c
@@ -30,10 +30,10 @@ void add_to_inventory (int class, int type, int controller, int unit, int state)
inventory_items++;
}
-int dump_inventory_to_user (void *userbuf, int size)
+int dump_inventory_to_user (void __user *userbuf, int size)
{
inventory_t *inv = &inventory [0];
- inventory_t *user = userbuf;
+ inventory_t __user *user = userbuf;
int v;
if (!access_ok(VERIFY_WRITE, userbuf, size))
@@ -41,7 +41,8 @@ int dump_inventory_to_user (void *userbuf, int size)
for (v = 0; v < inventory_items; v++){
inv = &inventory [v];
- copy_to_user (user, inv, sizeof (inventory_t));
+ if (copy_to_user (user, inv, sizeof (inventory_t)))
+ return -EFAULT;
user++;
}
return inventory_items * sizeof (inventory_t);
diff --git a/arch/mips/kernel/irixioctl.c b/arch/mips/kernel/irixioctl.c
index 3cdc22346f4c..e2863821a3dd 100644
--- a/arch/mips/kernel/irixioctl.c
+++ b/arch/mips/kernel/irixioctl.c
@@ -59,7 +59,7 @@ asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg)
{
struct tty_struct *tp, *rtp;
mm_segment_t old_fs;
- int error = 0;
+ int i, error = 0;
#ifdef DEBUG_IOCTLS
printk("[%s:%d] irix_ioctl(%d, ", current->comm, current->pid, fd);
@@ -74,12 +74,13 @@ asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg)
case 0x0000540d: {
struct termios kt;
- struct irix_termios *it = (struct irix_termios *) arg;
+ struct irix_termios __user *it =
+ (struct irix_termios __user *) arg;
#ifdef DEBUG_IOCTLS
printk("TCGETS, %08lx) ", arg);
#endif
- if(!access_ok(VERIFY_WRITE, it, sizeof(*it))) {
+ if (!access_ok(VERIFY_WRITE, it, sizeof(*it))) {
error = -EFAULT;
break;
}
@@ -88,13 +89,14 @@ asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg)
set_fs(old_fs);
if (error)
break;
- __put_user(kt.c_iflag, &it->c_iflag);
- __put_user(kt.c_oflag, &it->c_oflag);
- __put_user(kt.c_cflag, &it->c_cflag);
- __put_user(kt.c_lflag, &it->c_lflag);
- for(error = 0; error < NCCS; error++)
- __put_user(kt.c_cc[error], &it->c_cc[error]);
- error = 0;
+
+ error = __put_user(kt.c_iflag, &it->c_iflag);
+ error |= __put_user(kt.c_oflag, &it->c_oflag);
+ error |= __put_user(kt.c_cflag, &it->c_cflag);
+ error |= __put_user(kt.c_lflag, &it->c_lflag);
+
+ for (i = 0; i < NCCS; i++)
+ error |= __put_user(kt.c_cc[i], &it->c_cc[i]);
break;
}
@@ -112,14 +114,19 @@ asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg)
old_fs = get_fs(); set_fs(get_ds());
error = sys_ioctl(fd, TCGETS, (unsigned long) &kt);
set_fs(old_fs);
- if(error)
+ if (error)
+ break;
+
+ error = __get_user(kt.c_iflag, &it->c_iflag);
+ error |= __get_user(kt.c_oflag, &it->c_oflag);
+ error |= __get_user(kt.c_cflag, &it->c_cflag);
+ error |= __get_user(kt.c_lflag, &it->c_lflag);
+
+ for (i = 0; i < NCCS; i++)
+ error |= __get_user(kt.c_cc[i], &it->c_cc[i]);
+
+ if (error)
break;
- __get_user(kt.c_iflag, &it->c_iflag);
- __get_user(kt.c_oflag, &it->c_oflag);
- __get_user(kt.c_cflag, &it->c_cflag);
- __get_user(kt.c_lflag, &it->c_lflag);
- for(error = 0; error < NCCS; error++)
- __get_user(kt.c_cc[error], &it->c_cc[error]);
old_fs = get_fs(); set_fs(get_ds());
error = sys_ioctl(fd, TCSETS, (unsigned long) &kt);
set_fs(old_fs);
@@ -153,7 +160,7 @@ asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg)
#ifdef DEBUG_IOCTLS
printk("rtp->session=%d ", rtp->session);
#endif
- error = put_user(rtp->session, (unsigned long *) arg);
+ error = put_user(rtp->session, (unsigned long __user *) arg);
break;
case 0x746e:
@@ -195,50 +202,32 @@ asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg)
break;
case 0x8004667e:
-#ifdef DEBUG_IOCTLS
- printk("FIONBIO, %08lx) arg=%d ", arg, *(int *)arg);
-#endif
error = sys_ioctl(fd, FIONBIO, arg);
break;
case 0x80047476:
-#ifdef DEBUG_IOCTLS
- printk("TIOCSPGRP, %08lx) arg=%d ", arg, *(int *)arg);
-#endif
error = sys_ioctl(fd, TIOCSPGRP, arg);
break;
case 0x8020690c:
-#ifdef DEBUG_IOCTLS
- printk("SIOCSIFADDR, %08lx) arg=%d ", arg, *(int *)arg);
-#endif
error = sys_ioctl(fd, SIOCSIFADDR, arg);
break;
case 0x80206910:
-#ifdef DEBUG_IOCTLS
- printk("SIOCSIFFLAGS, %08lx) arg=%d ", arg, *(int *)arg);
-#endif
error = sys_ioctl(fd, SIOCSIFFLAGS, arg);
break;
case 0xc0206911:
-#ifdef DEBUG_IOCTLS
- printk("SIOCGIFFLAGS, %08lx) arg=%d ", arg, *(int *)arg);
-#endif
error = sys_ioctl(fd, SIOCGIFFLAGS, arg);
break;
case 0xc020691b:
-#ifdef DEBUG_IOCTLS
- printk("SIOCGIFMETRIC, %08lx) arg=%d ", arg, *(int *)arg);
-#endif
error = sys_ioctl(fd, SIOCGIFMETRIC, arg);
break;
default: {
#ifdef DEBUG_MISSING_IOCTL
- char *msg = "Unimplemented IOCTL cmd tell linux@engr.sgi.com\n";
+ char *msg = "Unimplemented IOCTL cmd tell linux-mips@linux-mips.org\n";
#ifdef DEBUG_IOCTLS
printk("UNIMP_IOCTL, %08lx)\n", arg);
diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c
index eff89322ba50..908e63684208 100644
--- a/arch/mips/kernel/irixsig.c
+++ b/arch/mips/kernel/irixsig.c
@@ -76,36 +76,39 @@ static inline void dump_irix5_sigctx(struct sigctx_irix5 *c)
}
#endif
-static void setup_irix_frame(struct k_sigaction *ka, struct pt_regs *regs,
- int signr, sigset_t *oldmask)
+static int setup_irix_frame(struct k_sigaction *ka, struct pt_regs *regs,
+ int signr, sigset_t *oldmask)
{
+ struct sigctx_irix5 __user *ctx;
unsigned long sp;
- struct sigctx_irix5 *ctx;
- int i;
+ int error, i;
sp = regs->regs[29];
sp -= sizeof(struct sigctx_irix5);
sp &= ~(0xf);
- ctx = (struct sigctx_irix5 *) sp;
+ ctx = (struct sigctx_irix5 __user *) sp;
if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx)))
goto segv_and_exit;
- __put_user(0, &ctx->weird_fpu_thing);
- __put_user(~(0x00000001), &ctx->rmask);
- __put_user(0, &ctx->regs[0]);
+ error = __put_user(0, &ctx->weird_fpu_thing);
+ error |= __put_user(~(0x00000001), &ctx->rmask);
+ error |= __put_user(0, &ctx->regs[0]);
for(i = 1; i < 32; i++)
- __put_user((u64) regs->regs[i], &ctx->regs[i]);
+ error |= __put_user((u64) regs->regs[i], &ctx->regs[i]);
+
+ error |= __put_user((u64) regs->hi, &ctx->hi);
+ error |= __put_user((u64) regs->lo, &ctx->lo);
+ error |= __put_user((u64) regs->cp0_epc, &ctx->pc);
+ error |= __put_user(!!used_math(), &ctx->usedfp);
+ error |= __put_user((u64) regs->cp0_cause, &ctx->cp0_cause);
+ error |= __put_user((u64) regs->cp0_badvaddr, &ctx->cp0_badvaddr);
- __put_user((u64) regs->hi, &ctx->hi);
- __put_user((u64) regs->lo, &ctx->lo);
- __put_user((u64) regs->cp0_epc, &ctx->pc);
- __put_user(!!used_math(), &ctx->usedfp);
- __put_user((u64) regs->cp0_cause, &ctx->cp0_cause);
- __put_user((u64) regs->cp0_badvaddr, &ctx->cp0_badvaddr);
+ error |= __put_user(0, &ctx->sstk_flags); /* XXX sigstack unimp... todo... */
- __put_user(0, &ctx->sstk_flags); /* XXX sigstack unimp... todo... */
+ error |= __copy_to_user(&ctx->sigset, oldmask, sizeof(irix_sigset_t)) ? -EFAULT : 0;
- __copy_to_user(&ctx->sigset, oldmask, sizeof(irix_sigset_t));
+ if (error)
+ goto segv_and_exit;
#ifdef DEBUG_SIG
dump_irix5_sigctx(ctx);
@@ -117,13 +120,14 @@ static void setup_irix_frame(struct k_sigaction *ka, struct pt_regs *regs,
regs->regs[7] = (unsigned long) ka->sa.sa_handler;
regs->regs[25] = regs->cp0_epc = (unsigned long) ka->sa_restorer;
- return;
+ return 1;
segv_and_exit:
force_sigsegv(signr, current);
+ return 0;
}
-static void inline
+static int inline
setup_irix_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
int signr, sigset_t *oldmask, siginfo_t *info)
{
@@ -131,9 +135,11 @@ setup_irix_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
do_exit(SIGSEGV);
}
-static inline void handle_signal(unsigned long sig, siginfo_t *info,
+static inline int handle_signal(unsigned long sig, siginfo_t *info,
struct k_sigaction *ka, sigset_t *oldset, struct pt_regs * regs)
{
+ int ret;
+
switch(regs->regs[0]) {
case ERESTARTNOHAND:
regs->regs[2] = EINTR;
@@ -151,9 +157,9 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info,
regs->regs[0] = 0; /* Don't deal with this again. */
if (ka->sa.sa_flags & SA_SIGINFO)
- setup_irix_rt_frame(ka, regs, sig, oldset, info);
+ ret = setup_irix_rt_frame(ka, regs, sig, oldset, info);
else
- setup_irix_frame(ka, regs, sig, oldset);
+ ret = setup_irix_frame(ka, regs, sig, oldset);
spin_lock_irq(&current->sighand->siglock);
sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
@@ -161,6 +167,8 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info,
sigaddset(&current->blocked,sig);
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
+
+ return ret;
}
asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs)
@@ -184,10 +192,8 @@ asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs)
oldset = &current->blocked;
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
- if (signr > 0) {
- handle_signal(signr, &info, &ka, oldset, regs);
- return 1;
- }
+ if (signr > 0)
+ return handle_signal(signr, &info, &ka, oldset, regs);
no_signal:
/*
@@ -208,10 +214,11 @@ no_signal:
asmlinkage void
irix_sigreturn(struct pt_regs *regs)
{
- struct sigctx_irix5 *context, *magic;
+ struct sigctx_irix5 __user *context, *magic;
unsigned long umask, mask;
u64 *fregs;
- int sig, i, base = 0;
+ u32 usedfp;
+ int error, sig, i, base = 0;
sigset_t blocked;
/* Always make any pending restarted system calls return -EINTR */
@@ -220,8 +227,8 @@ irix_sigreturn(struct pt_regs *regs)
if (regs->regs[2] == 1000)
base = 1;
- context = (struct sigctx_irix5 *) regs->regs[base + 4];
- magic = (struct sigctx_irix5 *) regs->regs[base + 5];
+ context = (struct sigctx_irix5 __user *) regs->regs[base + 4];
+ magic = (struct sigctx_irix5 __user *) regs->regs[base + 5];
sig = (int) regs->regs[base + 6];
#ifdef DEBUG_SIG
printk("[%s:%d] IRIX sigreturn(scp[%p],ucp[%p],sig[%d])\n",
@@ -236,25 +243,31 @@ irix_sigreturn(struct pt_regs *regs)
dump_irix5_sigctx(context);
#endif
- __get_user(regs->cp0_epc, &context->pc);
- umask = context->rmask; mask = 2;
+ error = __get_user(regs->cp0_epc, &context->pc);
+ error |= __get_user(umask, &context->rmask);
+
+ mask = 2;
for (i = 1; i < 32; i++, mask <<= 1) {
- if(umask & mask)
- __get_user(regs->regs[i], &context->regs[i]);
+ if (umask & mask)
+ error |= __get_user(regs->regs[i], &context->regs[i]);
}
- __get_user(regs->hi, &context->hi);
- __get_user(regs->lo, &context->lo);
+ error |= __get_user(regs->hi, &context->hi);
+ error |= __get_user(regs->lo, &context->lo);
- if ((umask & 1) && context->usedfp) {
+ error |= __get_user(usedfp, &context->usedfp);
+ if ((umask & 1) && usedfp) {
fregs = (u64 *) &current->thread.fpu;
+
for(i = 0; i < 32; i++)
- fregs[i] = (u64) context->fpregs[i];
- __get_user(current->thread.fpu.hard.fcr31, &context->fpcsr);
+ error |= __get_user(fregs[i], &context->fpregs[i]);
+ error |= __get_user(current->thread.fpu.hard.fcr31, &context->fpcsr);
}
/* XXX do sigstack crapola here... XXX */
- if (__copy_from_user(&blocked, &context->sigset, sizeof(blocked)))
+ error |= __copy_from_user(&blocked, &context->sigset, sizeof(blocked)) ? -EFAULT : 0;
+
+ if (error)
goto badframe;
sigdelsetmask(&blocked, ~_BLOCKABLE);
@@ -296,8 +309,8 @@ static inline void dump_sigact_irix5(struct sigact_irix5 *p)
#endif
asmlinkage int
-irix_sigaction(int sig, const struct sigaction *act,
- struct sigaction *oact, void *trampoline)
+irix_sigaction(int sig, const struct sigaction __user *act,
+ struct sigaction __user *oact, void __user *trampoline)
{
struct k_sigaction new_ka, old_ka;
int ret;
@@ -311,12 +324,16 @@ irix_sigaction(int sig, const struct sigaction *act,
#endif
if (act) {
sigset_t mask;
- if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
- __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
- __get_user(new_ka.sa.sa_flags, &act->sa_flags))
+ int err;
+
+ if (!access_ok(VERIFY_READ, act, sizeof(*act)))
return -EFAULT;
+ err = __get_user(new_ka.sa.sa_handler, &act->sa_handler);
+ err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
- __copy_from_user(&mask, &act->sa_mask, sizeof(sigset_t));
+ err |= __copy_from_user(&mask, &act->sa_mask, sizeof(sigset_t)) ? -EFAULT : 0;
+ if (err)
+ return err;
/*
* Hmmm... methinks IRIX libc always passes a valid trampoline
@@ -330,30 +347,37 @@ irix_sigaction(int sig, const struct sigaction *act,
ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
if (!ret && oact) {
- if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
- __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
- __put_user(old_ka.sa.sa_flags, &oact->sa_flags))
+ int err;
+
+ if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
+ return -EFAULT;
+
+ err = __put_user(old_ka.sa.sa_handler, &oact->sa_handler);
+ err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+ err |= __copy_to_user(&oact->sa_mask, &old_ka.sa.sa_mask,
+ sizeof(sigset_t)) ? -EFAULT : 0;
+ if (err)
return -EFAULT;
- __copy_to_user(&old_ka.sa.sa_mask, &oact->sa_mask,
- sizeof(sigset_t));
}
return ret;
}
-asmlinkage int irix_sigpending(irix_sigset_t *set)
+asmlinkage int irix_sigpending(irix_sigset_t __user *set)
{
return do_sigpending(set, sizeof(*set));
}
-asmlinkage int irix_sigprocmask(int how, irix_sigset_t *new, irix_sigset_t *old)
+asmlinkage int irix_sigprocmask(int how, irix_sigset_t __user *new,
+ irix_sigset_t __user *old)
{
sigset_t oldbits, newbits;
if (new) {
if (!access_ok(VERIFY_READ, new, sizeof(*new)))
return -EFAULT;
- __copy_from_user(&newbits, new, sizeof(unsigned long)*4);
+ if (__copy_from_user(&newbits, new, sizeof(unsigned long)*4))
+ return -EFAULT;
sigdelsetmask(&newbits, ~_BLOCKABLE);
spin_lock_irq(&current->sighand->siglock);
@@ -381,20 +405,19 @@ asmlinkage int irix_sigprocmask(int how, irix_sigset_t *new, irix_sigset_t *old)
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
}
- if(old) {
- if (!access_ok(VERIFY_WRITE, old, sizeof(*old)))
- return -EFAULT;
- __copy_to_user(old, &current->blocked, sizeof(unsigned long)*4);
- }
+ if (old)
+ return copy_to_user(old, &current->blocked,
+ sizeof(unsigned long)*4) ? -EFAULT : 0;
return 0;
}
asmlinkage int irix_sigsuspend(struct pt_regs *regs)
{
- sigset_t *uset, saveset, newset;
+ sigset_t saveset, newset;
+ sigset_t __user *uset;
- uset = (sigset_t *) regs->regs[4];
+ uset = (sigset_t __user *) regs->regs[4];
if (copy_from_user(&newset, uset, sizeof(sigset_t)))
return -EFAULT;
sigdelsetmask(&newset, ~_BLOCKABLE);
@@ -440,12 +463,13 @@ struct irix5_siginfo {
} stuff;
};
-asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info,
- struct timespec *tp)
+asmlinkage int irix_sigpoll_sys(unsigned long __user *set,
+ struct irix5_siginfo __user *info, struct timespec __user *tp)
{
long expire = MAX_SCHEDULE_TIMEOUT;
sigset_t kset;
int i, sig, error, timeo = 0;
+ struct timespec ktp;
#ifdef DEBUG_SIG
printk("[%s:%d] irix_sigpoll_sys(%p,%p,%p)\n",
@@ -456,14 +480,8 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info,
if (!set)
return -EINVAL;
- if (!access_ok(VERIFY_READ, set, sizeof(kset))) {
- error = -EFAULT;
- goto out;
- }
-
- __copy_from_user(&kset, set, sizeof(set));
- if (error)
- goto out;
+ if (copy_from_user(&kset, set, sizeof(set)))
+ return -EFAULT;
if (info && clear_user(info, sizeof(*info))) {
error = -EFAULT;
@@ -471,19 +489,21 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info,
}
if (tp) {
- if (!access_ok(VERIFY_READ, tp, sizeof(*tp)))
+ if (copy_from_user(&ktp, tp, sizeof(*tp)))
return -EFAULT;
- if (!tp->tv_sec && !tp->tv_nsec) {
- error = -EINVAL;
- goto out;
- }
- expire = timespec_to_jiffies(tp) + (tp->tv_sec||tp->tv_nsec);
+
+ if (!ktp.tv_sec && !ktp.tv_nsec)
+ return -EINVAL;
+
+ expire = timespec_to_jiffies(&ktp) +
+ (ktp.tv_sec || ktp.tv_nsec);
}
while(1) {
long tmp = 0;
- expire = schedule_timeout_interruptible(expire);
+ current->state = TASK_INTERRUPTIBLE;
+ expire = schedule_timeout(expire);
for (i=0; i<=4; i++)
tmp |= (current->pending.signal.sig[i] & kset.sig[i]);
@@ -500,15 +520,14 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info,
if (timeo)
return -EAGAIN;
- for(sig = 1; i <= 65 /* IRIX_NSIG */; sig++) {
+ for (sig = 1; i <= 65 /* IRIX_NSIG */; sig++) {
if (sigismember (&kset, sig))
continue;
if (sigismember (&current->pending.signal, sig)) {
/* XXX need more than this... */
if (info)
- info->sig = sig;
- error = 0;
- goto out;
+ return copy_to_user(&info->sig, &sig, sizeof(sig));
+ return 0;
}
}
@@ -534,8 +553,9 @@ extern int getrusage(struct task_struct *, int, struct rusage __user *);
#define W_MASK (W_EXITED | W_TRAPPED | W_STOPPED | W_CONT | W_NOHANG)
-asmlinkage int irix_waitsys(int type, int pid, struct irix5_siginfo *info,
- int options, struct rusage *ru)
+asmlinkage int irix_waitsys(int type, int pid,
+ struct irix5_siginfo __user *info, int options,
+ struct rusage __user *ru)
{
int flag, retval;
DECLARE_WAITQUEUE(wait, current);
@@ -543,28 +563,22 @@ asmlinkage int irix_waitsys(int type, int pid, struct irix5_siginfo *info,
struct task_struct *p;
struct list_head *_p;
- if (!info) {
- retval = -EINVAL;
- goto out;
- }
- if (!access_ok(VERIFY_WRITE, info, sizeof(*info))) {
- retval = -EFAULT;
- goto out;
- }
- if (ru) {
- if (!access_ok(VERIFY_WRITE, ru, sizeof(*ru))) {
- retval = -EFAULT;
- goto out;
- }
- }
- if (options & ~(W_MASK)) {
- retval = -EINVAL;
- goto out;
- }
- if (type != IRIX_P_PID && type != IRIX_P_PGID && type != IRIX_P_ALL) {
- retval = -EINVAL;
- goto out;
- }
+ if (!info)
+ return -EINVAL;
+
+ if (!access_ok(VERIFY_WRITE, info, sizeof(*info)))
+ return -EFAULT;
+
+ if (ru)
+ if (!access_ok(VERIFY_WRITE, ru, sizeof(*ru)))
+ return -EFAULT;
+
+ if (options & ~W_MASK)
+ return -EINVAL;
+
+ if (type != IRIX_P_PID && type != IRIX_P_PGID && type != IRIX_P_ALL)
+ return -EINVAL;
+
add_wait_queue(&current->signal->wait_chldexit, &wait);
repeat:
flag = 0;
@@ -595,18 +609,20 @@ repeat:
add_parent(p, p->parent);
write_unlock_irq(&tasklist_lock);
retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;
- if (!retval && ru) {
- retval |= __put_user(SIGCHLD, &info->sig);
- retval |= __put_user(0, &info->code);
- retval |= __put_user(p->pid, &info->stuff.procinfo.pid);
- retval |= __put_user((p->exit_code >> 8) & 0xff,
- &info->stuff.procinfo.procdata.child.status);
- retval |= __put_user(p->utime, &info->stuff.procinfo.procdata.child.utime);
- retval |= __put_user(p->stime, &info->stuff.procinfo.procdata.child.stime);
- }
- if (!retval) {
- p->exit_code = 0;
- }
+ if (retval)
+ goto end_waitsys;
+
+ retval = __put_user(SIGCHLD, &info->sig);
+ retval |= __put_user(0, &info->code);
+ retval |= __put_user(p->pid, &info->stuff.procinfo.pid);
+ retval |= __put_user((p->exit_code >> 8) & 0xff,
+ &info->stuff.procinfo.procdata.child.status);
+ retval |= __put_user(p->utime, &info->stuff.procinfo.procdata.child.utime);
+ retval |= __put_user(p->stime, &info->stuff.procinfo.procdata.child.stime);
+ if (retval)
+ goto end_waitsys;
+
+ p->exit_code = 0;
goto end_waitsys;
case EXIT_ZOMBIE:
@@ -614,16 +630,18 @@ repeat:
current->signal->cstime += p->stime + p->signal->cstime;
if (ru != NULL)
getrusage(p, RUSAGE_BOTH, ru);
- __put_user(SIGCHLD, &info->sig);
- __put_user(1, &info->code); /* CLD_EXITED */
- __put_user(p->pid, &info->stuff.procinfo.pid);
- __put_user((p->exit_code >> 8) & 0xff,
+ retval = __put_user(SIGCHLD, &info->sig);
+ retval |= __put_user(1, &info->code); /* CLD_EXITED */
+ retval |= __put_user(p->pid, &info->stuff.procinfo.pid);
+ retval |= __put_user((p->exit_code >> 8) & 0xff,
&info->stuff.procinfo.procdata.child.status);
- __put_user(p->utime,
+ retval |= __put_user(p->utime,
&info->stuff.procinfo.procdata.child.utime);
- __put_user(p->stime,
+ retval |= __put_user(p->stime,
&info->stuff.procinfo.procdata.child.stime);
- retval = 0;
+ if (retval)
+ return retval;
+
if (p->real_parent != p->parent) {
write_lock_irq(&tasklist_lock);
remove_parent(p);
@@ -656,7 +674,6 @@ end_waitsys:
current->state = TASK_RUNNING;
remove_wait_queue(&current->signal->wait_chldexit, &wait);
-out:
return retval;
}
@@ -675,39 +692,39 @@ struct irix5_context {
asmlinkage int irix_getcontext(struct pt_regs *regs)
{
- int i, base = 0;
- struct irix5_context *ctx;
+ int error, i, base = 0;
+ struct irix5_context __user *ctx;
unsigned long flags;
if (regs->regs[2] == 1000)
base = 1;
- ctx = (struct irix5_context *) regs->regs[base + 4];
+ ctx = (struct irix5_context __user *) regs->regs[base + 4];
#ifdef DEBUG_SIG
printk("[%s:%d] irix_getcontext(%p)\n",
current->comm, current->pid, ctx);
#endif
- if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx)))
+ if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx)));
return -EFAULT;
- __put_user(current->thread.irix_oldctx, &ctx->link);
+ error = __put_user(current->thread.irix_oldctx, &ctx->link);
- __copy_to_user(&ctx->sigmask, &current->blocked, sizeof(irix_sigset_t));
+ error |= __copy_to_user(&ctx->sigmask, &current->blocked, sizeof(irix_sigset_t)) ? -EFAULT : 0;
/* XXX Do sigstack stuff someday... */
- __put_user(0, &ctx->stack.sp);
- __put_user(0, &ctx->stack.size);
- __put_user(0, &ctx->stack.flags);
+ error |= __put_user(0, &ctx->stack.sp);
+ error |= __put_user(0, &ctx->stack.size);
+ error |= __put_user(0, &ctx->stack.flags);
- __put_user(0, &ctx->weird_graphics_thing);
- __put_user(0, &ctx->regs[0]);
+ error |= __put_user(0, &ctx->weird_graphics_thing);
+ error |= __put_user(0, &ctx->regs[0]);
for (i = 1; i < 32; i++)
- __put_user(regs->regs[i], &ctx->regs[i]);
- __put_user(regs->lo, &ctx->regs[32]);
- __put_user(regs->hi, &ctx->regs[33]);
- __put_user(regs->cp0_cause, &ctx->regs[34]);
- __put_user(regs->cp0_epc, &ctx->regs[35]);
+ error |= __put_user(regs->regs[i], &ctx->regs[i]);
+ error |= __put_user(regs->lo, &ctx->regs[32]);
+ error |= __put_user(regs->hi, &ctx->regs[33]);
+ error |= __put_user(regs->cp0_cause, &ctx->regs[34]);
+ error |= __put_user(regs->cp0_epc, &ctx->regs[35]);
flags = 0x0f;
if (!used_math()) {
@@ -716,119 +733,124 @@ asmlinkage int irix_getcontext(struct pt_regs *regs)
/* XXX wheee... */
printk("Wheee, no code for saving IRIX FPU context yet.\n");
}
- __put_user(flags, &ctx->flags);
+ error |= __put_user(flags, &ctx->flags);
- return 0;
+ return error;
}
-asmlinkage unsigned long irix_setcontext(struct pt_regs *regs)
+asmlinkage void irix_setcontext(struct pt_regs *regs)
{
- int error, base = 0;
- struct irix5_context *ctx;
+ struct irix5_context __user *ctx;
+ int err, base = 0;
+ u32 flags;
- if(regs->regs[2] == 1000)
+ if (regs->regs[2] == 1000)
base = 1;
- ctx = (struct irix5_context *) regs->regs[base + 4];
+ ctx = (struct irix5_context __user *) regs->regs[base + 4];
#ifdef DEBUG_SIG
printk("[%s:%d] irix_setcontext(%p)\n",
current->comm, current->pid, ctx);
#endif
- if (!access_ok(VERIFY_READ, ctx, sizeof(*ctx))) {
- error = -EFAULT;
- goto out;
- }
+ if (!access_ok(VERIFY_READ, ctx, sizeof(*ctx)))
+ goto segv_and_exit;
- if (ctx->flags & 0x02) {
+ err = __get_user(flags, &ctx->flags);
+ if (flags & 0x02) {
/* XXX sigstack garbage, todo... */
printk("Wheee, cannot do sigstack stuff in setcontext\n");
}
- if (ctx->flags & 0x04) {
+ if (flags & 0x04) {
int i;
/* XXX extra control block stuff... todo... */
- for(i = 1; i < 32; i++)
- regs->regs[i] = ctx->regs[i];
- regs->lo = ctx->regs[32];
- regs->hi = ctx->regs[33];
- regs->cp0_epc = ctx->regs[35];
+ for (i = 1; i < 32; i++)
+ err |= __get_user(regs->regs[i], &ctx->regs[i]);
+ err |= __get_user(regs->lo, &ctx->regs[32]);
+ err |= __get_user(regs->hi, &ctx->regs[33]);
+ err |= __get_user(regs->cp0_epc, &ctx->regs[35]);
}
- if (ctx->flags & 0x08) {
+ if (flags & 0x08)
/* XXX fpu context, blah... */
- printk("Wheee, cannot restore FPU context yet...\n");
- }
- current->thread.irix_oldctx = ctx->link;
- error = regs->regs[2];
+ printk(KERN_ERR "Wheee, cannot restore FPU context yet...\n");
-out:
- return error;
+ err |= __get_user(current->thread.irix_oldctx, &ctx->link);
+ if (err)
+ goto segv_and_exit;
+
+ /*
+ * Don't let your children do this ...
+ */
+ if (current_thread_info()->flags & TIF_SYSCALL_TRACE)
+ do_syscall_trace(regs, 1);
+ __asm__ __volatile__(
+ "move\t$29,%0\n\t"
+ "j\tsyscall_exit"
+ :/* no outputs */
+ :"r" (&regs));
+ /* Unreached */
+
+segv_and_exit:
+ force_sigsegv(SIGSEGV, current);
}
-struct irix_sigstack { unsigned long sp; int status; };
+struct irix_sigstack {
+ unsigned long sp;
+ int status;
+};
-asmlinkage int irix_sigstack(struct irix_sigstack *new, struct irix_sigstack *old)
+asmlinkage int irix_sigstack(struct irix_sigstack __user *new,
+ struct irix_sigstack __user *old)
{
- int error = -EFAULT;
-
#ifdef DEBUG_SIG
printk("[%s:%d] irix_sigstack(%p,%p)\n",
current->comm, current->pid, new, old);
#endif
- if(new) {
+ if (new) {
if (!access_ok(VERIFY_READ, new, sizeof(*new)))
- goto out;
+ return -EFAULT;
}
- if(old) {
+ if (old) {
if (!access_ok(VERIFY_WRITE, old, sizeof(*old)))
- goto out;
+ return -EFAULT;
}
- error = 0;
-out:
- return error;
+ return 0;
}
struct irix_sigaltstack { unsigned long sp; int size; int status; };
-asmlinkage int irix_sigaltstack(struct irix_sigaltstack *new,
- struct irix_sigaltstack *old)
+asmlinkage int irix_sigaltstack(struct irix_sigaltstack __user *new,
+ struct irix_sigaltstack __user *old)
{
- int error = -EFAULT;
-
#ifdef DEBUG_SIG
printk("[%s:%d] irix_sigaltstack(%p,%p)\n",
current->comm, current->pid, new, old);
#endif
- if (new) {
+ if (new)
if (!access_ok(VERIFY_READ, new, sizeof(*new)))
- goto out;
- }
+ return -EFAULT;
if (old) {
if (!access_ok(VERIFY_WRITE, old, sizeof(*old)))
- goto out;
+ return -EFAULT;
}
- error = 0;
-
-out:
- error = 0;
- return error;
+ return 0;
}
struct irix_procset {
int cmd, ltype, lid, rtype, rid;
};
-asmlinkage int irix_sigsendset(struct irix_procset *pset, int sig)
+asmlinkage int irix_sigsendset(struct irix_procset __user *pset, int sig)
{
if (!access_ok(VERIFY_READ, pset, sizeof(*pset)))
return -EFAULT;
-
#ifdef DEBUG_SIG
printk("[%s:%d] irix_sigsendset([%d,%d,%d,%d,%d],%d)\n",
current->comm, current->pid,
diff --git a/arch/mips/kernel/irq-msc01.c b/arch/mips/kernel/irq-msc01.c
index 43c00ac0b88d..3f653c7cfbf3 100644
--- a/arch/mips/kernel/irq-msc01.c
+++ b/arch/mips/kernel/irq-msc01.c
@@ -74,7 +74,7 @@ static void disable_msc_irq(unsigned int irq)
static void level_mask_and_ack_msc_irq(unsigned int irq)
{
mask_msc_irq(irq);
- if (!cpu_has_ei)
+ if (!cpu_has_veic)
MSCIC_WRITE(MSC01_IC_EOI, 0);
}
@@ -84,7 +84,7 @@ static void level_mask_and_ack_msc_irq(unsigned int irq)
static void edge_mask_and_ack_msc_irq(unsigned int irq)
{
mask_msc_irq(irq);
- if (!cpu_has_ei)
+ if (!cpu_has_veic)
MSCIC_WRITE(MSC01_IC_EOI, 0);
else {
u32 r;
@@ -129,25 +129,23 @@ msc_bind_eic_interrupt (unsigned int irq, unsigned int set)
#define shutdown_msc_irq disable_msc_irq
struct hw_interrupt_type msc_levelirq_type = {
- "SOC-it-Level",
- startup_msc_irq,
- shutdown_msc_irq,
- enable_msc_irq,
- disable_msc_irq,
- level_mask_and_ack_msc_irq,
- end_msc_irq,
- NULL
+ .typename = "SOC-it-Level",
+ .startup = startup_msc_irq,
+ .shutdown = shutdown_msc_irq,
+ .enable = enable_msc_irq,
+ .disable = disable_msc_irq,
+ .ack = level_mask_and_ack_msc_irq,
+ .end = end_msc_irq,
};
struct hw_interrupt_type msc_edgeirq_type = {
- "SOC-it-Edge",
- startup_msc_irq,
- shutdown_msc_irq,
- enable_msc_irq,
- disable_msc_irq,
- edge_mask_and_ack_msc_irq,
- end_msc_irq,
- NULL
+ .typename = "SOC-it-Edge",
+ .startup =startup_msc_irq,
+ .shutdown = shutdown_msc_irq,
+ .enable = enable_msc_irq,
+ .disable = disable_msc_irq,
+ .ack = edge_mask_and_ack_msc_irq,
+ .end = end_msc_irq,
};
@@ -168,14 +166,14 @@ void __init init_msc_irqs(unsigned int base, msc_irqmap_t *imp, int nirq)
switch (imp->im_type) {
case MSC01_IRQ_EDGE:
irq_desc[base+n].handler = &msc_edgeirq_type;
- if (cpu_has_ei)
+ if (cpu_has_veic)
MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT);
else
MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT | imp->im_lvl);
break;
case MSC01_IRQ_LEVEL:
irq_desc[base+n].handler = &msc_levelirq_type;
- if (cpu_has_ei)
+ if (cpu_has_veic)
MSCIC_WRITE(MSC01_IC_SUP+n*8, 0);
else
MSCIC_WRITE(MSC01_IC_SUP+n*8, imp->im_lvl);
diff --git a/arch/mips/kernel/irq-mv6434x.c b/arch/mips/kernel/irq-mv6434x.c
index 088bbbc869e6..0ac067f45cf5 100644
--- a/arch/mips/kernel/irq-mv6434x.c
+++ b/arch/mips/kernel/irq-mv6434x.c
@@ -135,14 +135,13 @@ void ll_mv64340_irq(struct pt_regs *regs)
#define shutdown_mv64340_irq disable_mv64340_irq
struct hw_interrupt_type mv64340_irq_type = {
- "MV-64340",
- startup_mv64340_irq,
- shutdown_mv64340_irq,
- enable_mv64340_irq,
- disable_mv64340_irq,
- mask_and_ack_mv64340_irq,
- end_mv64340_irq,
- NULL
+ .typename = "MV-64340",
+ .startup = startup_mv64340_irq,
+ .shutdown = shutdown_mv64340_irq,
+ .enable = enable_mv64340_irq,
+ .disable = disable_mv64340_irq,
+ .ack = mask_and_ack_mv64340_irq,
+ .end = end_mv64340_irq,
};
void __init mv64340_irq_init(unsigned int base)
diff --git a/arch/mips/kernel/irq-rm7000.c b/arch/mips/kernel/irq-rm7000.c
index f5d779fd0355..0b130c5ac5d9 100644
--- a/arch/mips/kernel/irq-rm7000.c
+++ b/arch/mips/kernel/irq-rm7000.c
@@ -72,13 +72,13 @@ static void rm7k_cpu_irq_end(unsigned int irq)
}
static hw_irq_controller rm7k_irq_controller = {
- "RM7000",
- rm7k_cpu_irq_startup,
- rm7k_cpu_irq_shutdown,
- rm7k_cpu_irq_enable,
- rm7k_cpu_irq_disable,
- rm7k_cpu_irq_ack,
- rm7k_cpu_irq_end,
+ .typename = "RM7000",
+ .startup = rm7k_cpu_irq_startup,
+ .shutdown = rm7k_cpu_irq_shutdown,
+ .enable = rm7k_cpu_irq_enable,
+ .disable = rm7k_cpu_irq_disable,
+ .ack = rm7k_cpu_irq_ack,
+ .end = rm7k_cpu_irq_end,
};
void __init rm7k_cpu_irq_init(int base)
diff --git a/arch/mips/kernel/irq-rm9000.c b/arch/mips/kernel/irq-rm9000.c
index bdd130296256..9b5f20c32acb 100644
--- a/arch/mips/kernel/irq-rm9000.c
+++ b/arch/mips/kernel/irq-rm9000.c
@@ -106,23 +106,23 @@ static void rm9k_cpu_irq_end(unsigned int irq)
}
static hw_irq_controller rm9k_irq_controller = {
- "RM9000",
- rm9k_cpu_irq_startup,
- rm9k_cpu_irq_shutdown,
- rm9k_cpu_irq_enable,
- rm9k_cpu_irq_disable,
- rm9k_cpu_irq_ack,
- rm9k_cpu_irq_end,
+ .typename = "RM9000",
+ .startup = rm9k_cpu_irq_startup,
+ .shutdown = rm9k_cpu_irq_shutdown,
+ .enable = rm9k_cpu_irq_enable,
+ .disable = rm9k_cpu_irq_disable,
+ .ack = rm9k_cpu_irq_ack,
+ .end = rm9k_cpu_irq_end,
};
static hw_irq_controller rm9k_perfcounter_irq = {
- "RM9000",
- rm9k_perfcounter_irq_startup,
- rm9k_perfcounter_irq_shutdown,
- rm9k_cpu_irq_enable,
- rm9k_cpu_irq_disable,
- rm9k_cpu_irq_ack,
- rm9k_cpu_irq_end,
+ .typename = "RM9000",
+ .startup = rm9k_perfcounter_irq_startup,
+ .shutdown = rm9k_perfcounter_irq_shutdown,
+ .enable = rm9k_cpu_irq_enable,
+ .disable = rm9k_cpu_irq_disable,
+ .ack = rm9k_cpu_irq_ack,
+ .end = rm9k_cpu_irq_end,
};
unsigned int rm9000_perfcount_irq;
diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c
index 2b936cf1ef70..5db67e31ec1a 100644
--- a/arch/mips/kernel/irq_cpu.c
+++ b/arch/mips/kernel/irq_cpu.c
@@ -3,6 +3,8 @@
* Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
*
* Copyright (C) 2001 Ralf Baechle
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ * Author: Maciej W. Rozycki <macro@mips.com>
*
* This file define the irq handler for MIPS CPU interrupts.
*
@@ -31,19 +33,21 @@
#include <asm/irq_cpu.h>
#include <asm/mipsregs.h>
+#include <asm/mipsmtregs.h>
#include <asm/system.h>
static int mips_cpu_irq_base;
static inline void unmask_mips_irq(unsigned int irq)
{
- clear_c0_cause(0x100 << (irq - mips_cpu_irq_base));
set_c0_status(0x100 << (irq - mips_cpu_irq_base));
+ irq_enable_hazard();
}
static inline void mask_mips_irq(unsigned int irq)
{
clear_c0_status(0x100 << (irq - mips_cpu_irq_base));
+ irq_disable_hazard();
}
static inline void mips_cpu_irq_enable(unsigned int irq)
@@ -52,6 +56,7 @@ static inline void mips_cpu_irq_enable(unsigned int irq)
local_irq_save(flags);
unmask_mips_irq(irq);
+ back_to_back_c0_hazard();
local_irq_restore(flags);
}
@@ -61,6 +66,7 @@ static void mips_cpu_irq_disable(unsigned int irq)
local_irq_save(flags);
mask_mips_irq(irq);
+ back_to_back_c0_hazard();
local_irq_restore(flags);
}
@@ -71,7 +77,7 @@ static unsigned int mips_cpu_irq_startup(unsigned int irq)
return 0;
}
-#define mips_cpu_irq_shutdown mips_cpu_irq_disable
+#define mips_cpu_irq_shutdown mips_cpu_irq_disable
/*
* While we ack the interrupt interrupts are disabled and thus we don't need
@@ -79,9 +85,6 @@ static unsigned int mips_cpu_irq_startup(unsigned int irq)
*/
static void mips_cpu_irq_ack(unsigned int irq)
{
- /* Only necessary for soft interrupts */
- clear_c0_cause(0x100 << (irq - mips_cpu_irq_base));
-
mask_mips_irq(irq);
}
@@ -92,22 +95,82 @@ static void mips_cpu_irq_end(unsigned int irq)
}
static hw_irq_controller mips_cpu_irq_controller = {
- "MIPS",
- mips_cpu_irq_startup,
- mips_cpu_irq_shutdown,
- mips_cpu_irq_enable,
- mips_cpu_irq_disable,
- mips_cpu_irq_ack,
- mips_cpu_irq_end,
- NULL /* no affinity stuff for UP */
+ .typename = "MIPS",
+ .startup = mips_cpu_irq_startup,
+ .shutdown = mips_cpu_irq_shutdown,
+ .enable = mips_cpu_irq_enable,
+ .disable = mips_cpu_irq_disable,
+ .ack = mips_cpu_irq_ack,
+ .end = mips_cpu_irq_end,
};
+/*
+ * Basically the same as above but taking care of all the MT stuff
+ */
+
+#define unmask_mips_mt_irq unmask_mips_irq
+#define mask_mips_mt_irq mask_mips_irq
+#define mips_mt_cpu_irq_enable mips_cpu_irq_enable
+#define mips_mt_cpu_irq_disable mips_cpu_irq_disable
+
+static unsigned int mips_mt_cpu_irq_startup(unsigned int irq)
+{
+ unsigned int vpflags = dvpe();
+
+ clear_c0_cause(0x100 << (irq - mips_cpu_irq_base));
+ evpe(vpflags);
+ mips_mt_cpu_irq_enable(irq);
+
+ return 0;
+}
+
+#define mips_mt_cpu_irq_shutdown mips_mt_cpu_irq_disable
+
+/*
+ * While we ack the interrupt interrupts are disabled and thus we don't need
+ * to deal with concurrency issues. Same for mips_cpu_irq_end.
+ */
+static void mips_mt_cpu_irq_ack(unsigned int irq)
+{
+ unsigned int vpflags = dvpe();
+ clear_c0_cause(0x100 << (irq - mips_cpu_irq_base));
+ evpe(vpflags);
+ mask_mips_mt_irq(irq);
+}
+
+#define mips_mt_cpu_irq_end mips_cpu_irq_end
+
+static hw_irq_controller mips_mt_cpu_irq_controller = {
+ .typename = "MIPS",
+ .startup = mips_mt_cpu_irq_startup,
+ .shutdown = mips_mt_cpu_irq_shutdown,
+ .enable = mips_mt_cpu_irq_enable,
+ .disable = mips_mt_cpu_irq_disable,
+ .ack = mips_mt_cpu_irq_ack,
+ .end = mips_mt_cpu_irq_end,
+};
void __init mips_cpu_irq_init(int irq_base)
{
int i;
- for (i = irq_base; i < irq_base + 8; i++) {
+ /* Mask interrupts. */
+ clear_c0_status(ST0_IM);
+ clear_c0_cause(CAUSEF_IP);
+
+ /*
+ * Only MT is using the software interrupts currently, so we just
+ * leave them uninitialized for other processors.
+ */
+ if (cpu_has_mipsmt)
+ for (i = irq_base; i < irq_base + 2; i++) {
+ irq_desc[i].status = IRQ_DISABLED;
+ irq_desc[i].action = NULL;
+ irq_desc[i].depth = 1;
+ irq_desc[i].handler = &mips_mt_cpu_irq_controller;
+ }
+
+ for (i = irq_base + 2; i < irq_base + 8; i++) {
irq_desc[i].status = IRQ_DISABLED;
irq_desc[i].action = NULL;
irq_desc[i].depth = 1;
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index ece4564919d8..330cf84d21fe 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -215,81 +215,32 @@ sys32_readdir(unsigned int fd, void * dirent32, unsigned int count)
return(n);
}
-struct rusage32 {
- struct compat_timeval ru_utime;
- struct compat_timeval ru_stime;
- int ru_maxrss;
- int ru_ixrss;
- int ru_idrss;
- int ru_isrss;
- int ru_minflt;
- int ru_majflt;
- int ru_nswap;
- int ru_inblock;
- int ru_oublock;
- int ru_msgsnd;
- int ru_msgrcv;
- int ru_nsignals;
- int ru_nvcsw;
- int ru_nivcsw;
-};
-
-static int
-put_rusage (struct rusage32 *ru, struct rusage *r)
+asmlinkage int
+sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr, int options)
{
- int err;
-
- if (!access_ok(VERIFY_WRITE, ru, sizeof *ru))
- return -EFAULT;
-
- err = __put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec);
- err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec);
- err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec);
- err |= __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec);
- err |= __put_user (r->ru_maxrss, &ru->ru_maxrss);
- err |= __put_user (r->ru_ixrss, &ru->ru_ixrss);
- err |= __put_user (r->ru_idrss, &ru->ru_idrss);
- err |= __put_user (r->ru_isrss, &ru->ru_isrss);
- err |= __put_user (r->ru_minflt, &ru->ru_minflt);
- err |= __put_user (r->ru_majflt, &ru->ru_majflt);
- err |= __put_user (r->ru_nswap, &ru->ru_nswap);
- err |= __put_user (r->ru_inblock, &ru->ru_inblock);
- err |= __put_user (r->ru_oublock, &ru->ru_oublock);
- err |= __put_user (r->ru_msgsnd, &ru->ru_msgsnd);
- err |= __put_user (r->ru_msgrcv, &ru->ru_msgrcv);
- err |= __put_user (r->ru_nsignals, &ru->ru_nsignals);
- err |= __put_user (r->ru_nvcsw, &ru->ru_nvcsw);
- err |= __put_user (r->ru_nivcsw, &ru->ru_nivcsw);
-
- return err;
+ return compat_sys_wait4(pid, stat_addr, options, NULL);
}
-asmlinkage int
-sys32_wait4(compat_pid_t pid, unsigned int * stat_addr, int options,
- struct rusage32 * ru)
+asmlinkage long
+sysn32_waitid(int which, compat_pid_t pid,
+ siginfo_t __user *uinfo, int options,
+ struct compat_rusage __user *uru)
{
- if (!ru)
- return sys_wait4(pid, stat_addr, options, NULL);
- else {
- struct rusage r;
- int ret;
- unsigned int status;
- mm_segment_t old_fs = get_fs();
+ struct rusage ru;
+ long ret;
+ mm_segment_t old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);
- set_fs(old_fs);
- if (put_rusage (ru, &r)) return -EFAULT;
- if (stat_addr && put_user (status, stat_addr))
- return -EFAULT;
+ set_fs (KERNEL_DS);
+ ret = sys_waitid(which, pid, uinfo, options,
+ uru ? (struct rusage __user *) &ru : NULL);
+ set_fs (old_fs);
+
+ if (ret < 0 || uinfo->si_signo == 0)
return ret;
- }
-}
-asmlinkage int
-sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr, int options)
-{
- return sys32_wait4(pid, stat_addr, options, NULL);
+ if (uru)
+ ret = put_compat_rusage(&ru, uru);
+ return ret;
}
struct sysinfo32 {
@@ -1467,3 +1418,80 @@ asmlinkage long sys32_socketcall(int call, unsigned int *args32)
}
return err;
}
+
+struct sigevent32 {
+ u32 sigev_value;
+ u32 sigev_signo;
+ u32 sigev_notify;
+ u32 payload[(64 / 4) - 3];
+};
+
+extern asmlinkage long
+sys_timer_create(clockid_t which_clock,
+ struct sigevent __user *timer_event_spec,
+ timer_t __user * created_timer_id);
+
+long
+sys32_timer_create(u32 clock, struct sigevent32 __user *se32, timer_t __user *timer_id)
+{
+ struct sigevent __user *p = NULL;
+ if (se32) {
+ struct sigevent se;
+ p = compat_alloc_user_space(sizeof(struct sigevent));
+ memset(&se, 0, sizeof(struct sigevent));
+ if (get_user(se.sigev_value.sival_int, &se32->sigev_value) ||
+ __get_user(se.sigev_signo, &se32->sigev_signo) ||
+ __get_user(se.sigev_notify, &se32->sigev_notify) ||
+ __copy_from_user(&se._sigev_un._pad, &se32->payload,
+ sizeof(se32->payload)) ||
+ copy_to_user(p, &se, sizeof(se)))
+ return -EFAULT;
+ }
+ return sys_timer_create(clock, p, timer_id);
+}
+
+asmlinkage long
+sysn32_rt_sigtimedwait(const sigset_t __user *uthese,
+ siginfo_t __user *uinfo,
+ const struct compat_timespec __user *uts32,
+ size_t sigsetsize)
+{
+ struct timespec __user *uts = NULL;
+
+ if (uts32) {
+ struct timespec ts;
+ uts = compat_alloc_user_space(sizeof(struct timespec));
+ if (get_user(ts.tv_sec, &uts32->tv_sec) ||
+ get_user(ts.tv_nsec, &uts32->tv_nsec) ||
+ copy_to_user (uts, &ts, sizeof (ts)))
+ return -EFAULT;
+ }
+ return sys_rt_sigtimedwait(uthese, uinfo, uts, sigsetsize);
+}
+
+save_static_function(sys32_clone);
+__attribute_used__ noinline static int
+_sys32_clone(nabi_no_regargs struct pt_regs regs)
+{
+ unsigned long clone_flags;
+ unsigned long newsp;
+ int __user *parent_tidptr, *child_tidptr;
+
+ clone_flags = regs.regs[4];
+ newsp = regs.regs[5];
+ if (!newsp)
+ newsp = regs.regs[29];
+ parent_tidptr = (int *) regs.regs[6];
+
+ /* Use __dummy4 instead of getting it off the stack, so that
+ syscall() works. */
+ child_tidptr = (int __user *) __dummy4;
+ return do_fork(clone_flags, newsp, &regs, 0,
+ parent_tidptr, child_tidptr);
+}
+
+extern asmlinkage void sys_set_thread_area(u32 addr);
+asmlinkage void sys32_set_thread_area(u32 addr)
+{
+ sys_set_thread_area(AA(addr));
+}
diff --git a/arch/mips/kernel/module-elf32.c b/arch/mips/kernel/module-elf32.c
deleted file mode 100644
index ffd216d6d6dc..000000000000
--- a/arch/mips/kernel/module-elf32.c
+++ /dev/null
@@ -1,250 +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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT 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
- *
- * Copyright (C) 2001 Rusty Russell.
- * Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org)
- */
-
-#undef DEBUG
-
-#include <linux/moduleloader.h>
-#include <linux/elf.h>
-#include <linux/vmalloc.h>
-#include <linux/slab.h>
-#include <linux/fs.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-
-struct mips_hi16 {
- struct mips_hi16 *next;
- Elf32_Addr *addr;
- Elf32_Addr value;
-};
-
-static struct mips_hi16 *mips_hi16_list;
-
-void *module_alloc(unsigned long size)
-{
- if (size == 0)
- return NULL;
- return vmalloc(size);
-}
-
-
-/* Free memory returned from module_alloc */
-void module_free(struct module *mod, void *module_region)
-{
- vfree(module_region);
- /* FIXME: If module_region == mod->init_region, trim exception
- table entries. */
-}
-
-int module_frob_arch_sections(Elf_Ehdr *hdr,
- Elf_Shdr *sechdrs,
- char *secstrings,
- struct module *mod)
-{
- return 0;
-}
-
-static int apply_r_mips_none(struct module *me, uint32_t *location,
- Elf32_Addr v)
-{
- return 0;
-}
-
-static int apply_r_mips_32(struct module *me, uint32_t *location,
- Elf32_Addr v)
-{
- *location += v;
-
- return 0;
-}
-
-static int apply_r_mips_26(struct module *me, uint32_t *location,
- Elf32_Addr v)
-{
- if (v % 4) {
- printk(KERN_ERR "module %s: dangerous relocation\n", me->name);
- return -ENOEXEC;
- }
-
- if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
- printk(KERN_ERR
- "module %s: relocation overflow\n",
- me->name);
- return -ENOEXEC;
- }
-
- *location = (*location & ~0x03ffffff) |
- ((*location + (v >> 2)) & 0x03ffffff);
-
- return 0;
-}
-
-static int apply_r_mips_hi16(struct module *me, uint32_t *location,
- Elf32_Addr v)
-{
- struct mips_hi16 *n;
-
- /*
- * We cannot relocate this one now because we don't know the value of
- * the carry we need to add. Save the information, and let LO16 do the
- * actual relocation.
- */
- n = kmalloc(sizeof *n, GFP_KERNEL);
- if (!n)
- return -ENOMEM;
-
- n->addr = location;
- n->value = v;
- n->next = mips_hi16_list;
- mips_hi16_list = n;
-
- return 0;
-}
-
-static int apply_r_mips_lo16(struct module *me, uint32_t *location,
- Elf32_Addr v)
-{
- unsigned long insnlo = *location;
- Elf32_Addr val, vallo;
-
- /* Sign extend the addend we extract from the lo insn. */
- vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
-
- if (mips_hi16_list != NULL) {
- struct mips_hi16 *l;
-
- l = mips_hi16_list;
- while (l != NULL) {
- struct mips_hi16 *next;
- unsigned long insn;
-
- /*
- * The value for the HI16 had best be the same.
- */
- if (v != l->value)
- goto out_danger;
-
- /*
- * Do the HI16 relocation. Note that we actually don't
- * need to know anything about the LO16 itself, except
- * where to find the low 16 bits of the addend needed
- * by the LO16.
- */
- insn = *l->addr;
- val = ((insn & 0xffff) << 16) + vallo;
- val += v;
-
- /*
- * Account for the sign extension that will happen in
- * the low bits.
- */
- val = ((val >> 16) + ((val & 0x8000) != 0)) & 0xffff;
-
- insn = (insn & ~0xffff) | val;
- *l->addr = insn;
-
- next = l->next;
- kfree(l);
- l = next;
- }
-
- mips_hi16_list = NULL;
- }
-
- /*
- * Ok, we're done with the HI16 relocs. Now deal with the LO16.
- */
- val = v + vallo;
- insnlo = (insnlo & ~0xffff) | (val & 0xffff);
- *location = insnlo;
-
- return 0;
-
-out_danger:
- printk(KERN_ERR "module %s: dangerous " "relocation\n", me->name);
-
- return -ENOEXEC;
-}
-
-static int (*reloc_handlers[]) (struct module *me, uint32_t *location,
- Elf32_Addr v) = {
- [R_MIPS_NONE] = apply_r_mips_none,
- [R_MIPS_32] = apply_r_mips_32,
- [R_MIPS_26] = apply_r_mips_26,
- [R_MIPS_HI16] = apply_r_mips_hi16,
- [R_MIPS_LO16] = apply_r_mips_lo16
-};
-
-int apply_relocate(Elf32_Shdr *sechdrs,
- const char *strtab,
- unsigned int symindex,
- unsigned int relsec,
- struct module *me)
-{
- Elf32_Rel *rel = (void *) sechdrs[relsec].sh_addr;
- Elf32_Sym *sym;
- uint32_t *location;
- unsigned int i;
- Elf32_Addr v;
- int res;
-
- 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++) {
- Elf32_Word r_info = rel[i].r_info;
-
- /* This is where to make the change */
- location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
- + rel[i].r_offset;
- /* This is the symbol it is referring to */
- sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
- + ELF32_R_SYM(r_info);
- if (!sym->st_value) {
- printk(KERN_WARNING "%s: Unknown symbol %s\n",
- me->name, strtab + sym->st_name);
- return -ENOENT;
- }
-
- v = sym->st_value;
-
- res = reloc_handlers[ELF32_R_TYPE(r_info)](me, location, v);
- if (res)
- return res;
- }
-
- return 0;
-}
-
-int apply_relocate_add(Elf32_Shdr *sechdrs,
- const char *strtab,
- unsigned int symindex,
- unsigned int relsec,
- struct module *me)
-{
- /*
- * Current binutils always generate .rela relocations. Keep smiling
- * if it's empty, abort otherwise.
- */
- if (!sechdrs[relsec].sh_size)
- return 0;
-
- printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n",
- me->name);
- return -ENOEXEC;
-}
diff --git a/arch/mips/kernel/module-elf64.c b/arch/mips/kernel/module-elf64.c
deleted file mode 100644
index e804792ee1ee..000000000000
--- a/arch/mips/kernel/module-elf64.c
+++ /dev/null
@@ -1,274 +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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT 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
- *
- * Copyright (C) 2001 Rusty Russell.
- * Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org)
- */
-
-#undef DEBUG
-
-#include <linux/moduleloader.h>
-#include <linux/elf.h>
-#include <linux/vmalloc.h>
-#include <linux/slab.h>
-#include <linux/fs.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-
-struct mips_hi16 {
- struct mips_hi16 *next;
- Elf32_Addr *addr;
- Elf64_Addr value;
-};
-
-static struct mips_hi16 *mips_hi16_list;
-
-void *module_alloc(unsigned long size)
-{
- if (size == 0)
- return NULL;
- return vmalloc(size);
-}
-
-
-/* Free memory returned from module_alloc */
-void module_free(struct module *mod, void *module_region)
-{
- vfree(module_region);
- /* FIXME: If module_region == mod->init_region, trim exception
- table entries. */
-}
-
-int module_frob_arch_sections(Elf_Ehdr *hdr,
- Elf_Shdr *sechdrs,
- char *secstrings,
- struct module *mod)
-{
- return 0;
-}
-
-int apply_relocate(Elf64_Shdr *sechdrs,
- const char *strtab,
- unsigned int symindex,
- unsigned int relsec,
- struct module *me)
-{
- /*
- * We don't want to deal with REL relocations - RELA is so much saner.
- */
- if (!sechdrs[relsec].sh_size)
- return 0;
-
- printk(KERN_ERR "module %s: REL relocation unsupported\n",
- me->name);
- return -ENOEXEC;
-}
-
-static int apply_r_mips_none(struct module *me, uint32_t *location,
- Elf64_Addr v)
-{
- return 0;
-}
-
-static int apply_r_mips_32(struct module *me, uint32_t *location,
- Elf64_Addr v)
-{
- *location = v;
-
- return 0;
-}
-
-static int apply_r_mips_26(struct module *me, uint32_t *location,
- Elf64_Addr v)
-{
- if (v % 4) {
- printk(KERN_ERR "module %s: dangerous relocation\n", me->name);
- return -ENOEXEC;
- }
-
- if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
- printk(KERN_ERR
- "module %s: relocation overflow\n",
- me->name);
- return -ENOEXEC;
- }
-
- *location = (*location & ~0x03ffffff) | ((v >> 2) & 0x03ffffff);
-
- return 0;
-}
-
-static int apply_r_mips_hi16(struct module *me, uint32_t *location,
- Elf64_Addr v)
-{
- struct mips_hi16 *n;
-
- /*
- * We cannot relocate this one now because we don't know the value of
- * the carry we need to add. Save the information, and let LO16 do the
- * actual relocation.
- */
- n = kmalloc(sizeof *n, GFP_KERNEL);
- if (!n)
- return -ENOMEM;
-
- n->addr = location;
- n->value = v;
- n->next = mips_hi16_list;
- mips_hi16_list = n;
-
- return 0;
-}
-
-static int apply_r_mips_lo16(struct module *me, uint32_t *location,
- Elf64_Addr v)
-{
- unsigned long insnlo = *location;
- Elf32_Addr val, vallo;
-
- /* Sign extend the addend we extract from the lo insn. */
- vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
-
- if (mips_hi16_list != NULL) {
- struct mips_hi16 *l;
-
- l = mips_hi16_list;
- while (l != NULL) {
- struct mips_hi16 *next;
- unsigned long insn;
-
- /*
- * The value for the HI16 had best be the same.
- */
- if (v != l->value)
- goto out_danger;
-
- /*
- * Do the HI16 relocation. Note that we actually don't
- * need to know anything about the LO16 itself, except
- * where to find the low 16 bits of the addend needed
- * by the LO16.
- */
- insn = *l->addr;
- val = ((insn & 0xffff) << 16) + vallo;
- val += v;
-
- /*
- * Account for the sign extension that will happen in
- * the low bits.
- */
- val = ((val >> 16) + ((val & 0x8000) != 0)) & 0xffff;
-
- insn = (insn & ~0xffff) | val;
- *l->addr = insn;
-
- next = l->next;
- kfree(l);
- l = next;
- }
-
- mips_hi16_list = NULL;
- }
-
- /*
- * Ok, we're done with the HI16 relocs. Now deal with the LO16.
- */
- insnlo = (insnlo & ~0xffff) | (v & 0xffff);
- *location = insnlo;
-
- return 0;
-
-out_danger:
- printk(KERN_ERR "module %s: dangerous " "relocation\n", me->name);
-
- return -ENOEXEC;
-}
-
-static int apply_r_mips_64(struct module *me, uint32_t *location,
- Elf64_Addr v)
-{
- *(uint64_t *) location = v;
-
- return 0;
-}
-
-
-static int apply_r_mips_higher(struct module *me, uint32_t *location,
- Elf64_Addr v)
-{
- *location = (*location & 0xffff0000) |
- ((((long long) v + 0x80008000LL) >> 32) & 0xffff);
-
- return 0;
-}
-
-static int apply_r_mips_highest(struct module *me, uint32_t *location,
- Elf64_Addr v)
-{
- *location = (*location & 0xffff0000) |
- ((((long long) v + 0x800080008000LL) >> 48) & 0xffff);
-
- return 0;
-}
-
-static int (*reloc_handlers[]) (struct module *me, uint32_t *location,
- Elf64_Addr v) = {
- [R_MIPS_NONE] = apply_r_mips_none,
- [R_MIPS_32] = apply_r_mips_32,
- [R_MIPS_26] = apply_r_mips_26,
- [R_MIPS_HI16] = apply_r_mips_hi16,
- [R_MIPS_LO16] = apply_r_mips_lo16,
- [R_MIPS_64] = apply_r_mips_64,
- [R_MIPS_HIGHER] = apply_r_mips_higher,
- [R_MIPS_HIGHEST] = apply_r_mips_highest
-};
-
-int apply_relocate_add(Elf64_Shdr *sechdrs,
- const char *strtab,
- unsigned int symindex,
- unsigned int relsec,
- struct module *me)
-{
- Elf64_Mips_Rela *rel = (void *) sechdrs[relsec].sh_addr;
- Elf64_Sym *sym;
- uint32_t *location;
- unsigned int i;
- Elf64_Addr v;
- int res;
-
- 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 */
- location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
- + rel[i].r_offset;
- /* This is the symbol it is referring to */
- sym = (Elf64_Sym *)sechdrs[symindex].sh_addr + rel[i].r_sym;
- if (!sym->st_value) {
- printk(KERN_WARNING "%s: Unknown symbol %s\n",
- me->name, strtab + sym->st_name);
- return -ENOENT;
- }
-
- v = sym->st_value;
-
- res = reloc_handlers[rel[i].r_type](me, location, v);
- if (res)
- return res;
- }
-
- return 0;
-}
diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c
index 458af3c7a639..e54a7f442f8a 100644
--- a/arch/mips/kernel/module.c
+++ b/arch/mips/kernel/module.c
@@ -1,9 +1,345 @@
+/*
+ * This program is free software; you can redistribute 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
+ *
+ * Copyright (C) 2001 Rusty Russell.
+ * Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2005 Thiemo Seufer
+ */
+
+#undef DEBUG
+
+#include <linux/moduleloader.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/spinlock.h>
+struct mips_hi16 {
+ struct mips_hi16 *next;
+ Elf_Addr *addr;
+ Elf_Addr value;
+};
+
+static struct mips_hi16 *mips_hi16_list;
+
static LIST_HEAD(dbe_list);
static DEFINE_SPINLOCK(dbe_lock);
+void *module_alloc(unsigned long size)
+{
+ if (size == 0)
+ return NULL;
+ return vmalloc(size);
+}
+
+/* Free memory returned from module_alloc */
+void module_free(struct module *mod, void *module_region)
+{
+ vfree(module_region);
+ /* FIXME: If module_region == mod->init_region, trim exception
+ table entries. */
+}
+
+int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
+ char *secstrings, struct module *mod)
+{
+ return 0;
+}
+
+static int apply_r_mips_none(struct module *me, u32 *location, Elf_Addr v)
+{
+ return 0;
+}
+
+static int apply_r_mips_32_rel(struct module *me, u32 *location, Elf_Addr v)
+{
+ *location += v;
+
+ return 0;
+}
+
+static int apply_r_mips_32_rela(struct module *me, u32 *location, Elf_Addr v)
+{
+ *location = v;
+
+ return 0;
+}
+
+static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v)
+{
+ if (v % 4) {
+ printk(KERN_ERR "module %s: dangerous relocation\n", me->name);
+ return -ENOEXEC;
+ }
+
+ if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
+ printk(KERN_ERR
+ "module %s: relocation overflow\n",
+ me->name);
+ return -ENOEXEC;
+ }
+
+ *location = (*location & ~0x03ffffff) |
+ ((*location + (v >> 2)) & 0x03ffffff);
+
+ return 0;
+}
+
+static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v)
+{
+ if (v % 4) {
+ printk(KERN_ERR "module %s: dangerous relocation\n", me->name);
+ return -ENOEXEC;
+ }
+
+ if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
+ printk(KERN_ERR
+ "module %s: relocation overflow\n",
+ me->name);
+ return -ENOEXEC;
+ }
+
+ *location = (*location & ~0x03ffffff) | ((v >> 2) & 0x03ffffff);
+
+ return 0;
+}
+
+static int apply_r_mips_hi16_rel(struct module *me, u32 *location, Elf_Addr v)
+{
+ struct mips_hi16 *n;
+
+ /*
+ * We cannot relocate this one now because we don't know the value of
+ * the carry we need to add. Save the information, and let LO16 do the
+ * actual relocation.
+ */
+ n = kmalloc(sizeof *n, GFP_KERNEL);
+ if (!n)
+ return -ENOMEM;
+
+ n->addr = (Elf_Addr *)location;
+ n->value = v;
+ n->next = mips_hi16_list;
+ mips_hi16_list = n;
+
+ return 0;
+}
+
+static int apply_r_mips_hi16_rela(struct module *me, u32 *location, Elf_Addr v)
+{
+ *location = (*location & 0xffff0000) |
+ ((((long long) v + 0x8000LL) >> 16) & 0xffff);
+
+ return 0;
+}
+
+static int apply_r_mips_lo16_rel(struct module *me, u32 *location, Elf_Addr v)
+{
+ unsigned long insnlo = *location;
+ Elf_Addr val, vallo;
+
+ /* Sign extend the addend we extract from the lo insn. */
+ vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
+
+ if (mips_hi16_list != NULL) {
+ struct mips_hi16 *l;
+
+ l = mips_hi16_list;
+ while (l != NULL) {
+ struct mips_hi16 *next;
+ unsigned long insn;
+
+ /*
+ * The value for the HI16 had best be the same.
+ */
+ if (v != l->value)
+ goto out_danger;
+
+ /*
+ * Do the HI16 relocation. Note that we actually don't
+ * need to know anything about the LO16 itself, except
+ * where to find the low 16 bits of the addend needed
+ * by the LO16.
+ */
+ insn = *l->addr;
+ val = ((insn & 0xffff) << 16) + vallo;
+ val += v;
+
+ /*
+ * Account for the sign extension that will happen in
+ * the low bits.
+ */
+ val = ((val >> 16) + ((val & 0x8000) != 0)) & 0xffff;
+
+ insn = (insn & ~0xffff) | val;
+ *l->addr = insn;
+
+ next = l->next;
+ kfree(l);
+ l = next;
+ }
+
+ mips_hi16_list = NULL;
+ }
+
+ /*
+ * Ok, we're done with the HI16 relocs. Now deal with the LO16.
+ */
+ val = v + vallo;
+ insnlo = (insnlo & ~0xffff) | (val & 0xffff);
+ *location = insnlo;
+
+ return 0;
+
+out_danger:
+ printk(KERN_ERR "module %s: dangerous " "relocation\n", me->name);
+
+ return -ENOEXEC;
+}
+
+static int apply_r_mips_lo16_rela(struct module *me, u32 *location, Elf_Addr v)
+{
+ *location = (*location & 0xffff0000) | (v & 0xffff);
+
+ return 0;
+}
+
+static int apply_r_mips_64_rela(struct module *me, u32 *location, Elf_Addr v)
+{
+ *(Elf_Addr *)location = v;
+
+ return 0;
+}
+
+static int apply_r_mips_higher_rela(struct module *me, u32 *location,
+ Elf_Addr v)
+{
+ *location = (*location & 0xffff0000) |
+ ((((long long) v + 0x80008000LL) >> 32) & 0xffff);
+
+ return 0;
+}
+
+static int apply_r_mips_highest_rela(struct module *me, u32 *location,
+ Elf_Addr v)
+{
+ *location = (*location & 0xffff0000) |
+ ((((long long) v + 0x800080008000LL) >> 48) & 0xffff);
+
+ return 0;
+}
+
+static int (*reloc_handlers_rel[]) (struct module *me, u32 *location,
+ Elf_Addr v) = {
+ [R_MIPS_NONE] = apply_r_mips_none,
+ [R_MIPS_32] = apply_r_mips_32_rel,
+ [R_MIPS_26] = apply_r_mips_26_rel,
+ [R_MIPS_HI16] = apply_r_mips_hi16_rel,
+ [R_MIPS_LO16] = apply_r_mips_lo16_rel
+};
+
+static int (*reloc_handlers_rela[]) (struct module *me, u32 *location,
+ Elf_Addr v) = {
+ [R_MIPS_NONE] = apply_r_mips_none,
+ [R_MIPS_32] = apply_r_mips_32_rela,
+ [R_MIPS_26] = apply_r_mips_26_rela,
+ [R_MIPS_HI16] = apply_r_mips_hi16_rela,
+ [R_MIPS_LO16] = apply_r_mips_lo16_rela,
+ [R_MIPS_64] = apply_r_mips_64_rela,
+ [R_MIPS_HIGHER] = apply_r_mips_higher_rela,
+ [R_MIPS_HIGHEST] = apply_r_mips_highest_rela
+};
+
+int apply_relocate(Elf_Shdr *sechdrs, const char *strtab,
+ unsigned int symindex, unsigned int relsec,
+ struct module *me)
+{
+ Elf_Mips_Rel *rel = (void *) sechdrs[relsec].sh_addr;
+ Elf_Sym *sym;
+ u32 *location;
+ unsigned int i;
+ Elf_Addr v;
+ int res;
+
+ 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 */
+ location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+ + rel[i].r_offset;
+ /* This is the symbol it is referring to */
+ sym = (Elf_Sym *)sechdrs[symindex].sh_addr
+ + ELF_MIPS_R_SYM(rel[i]);
+ if (!sym->st_value) {
+ printk(KERN_WARNING "%s: Unknown symbol %s\n",
+ me->name, strtab + sym->st_name);
+ return -ENOENT;
+ }
+
+ v = sym->st_value;
+
+ res = reloc_handlers_rel[ELF_MIPS_R_TYPE(rel[i])](me, location, v);
+ if (res)
+ return res;
+ }
+
+ return 0;
+}
+
+int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
+ unsigned int symindex, unsigned int relsec,
+ struct module *me)
+{
+ Elf_Mips_Rela *rel = (void *) sechdrs[relsec].sh_addr;
+ Elf_Sym *sym;
+ u32 *location;
+ unsigned int i;
+ Elf_Addr v;
+ int res;
+
+ 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 */
+ location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+ + rel[i].r_offset;
+ /* This is the symbol it is referring to */
+ sym = (Elf_Sym *)sechdrs[symindex].sh_addr
+ + ELF_MIPS_R_SYM(rel[i]);
+ if (!sym->st_value) {
+ printk(KERN_WARNING "%s: Unknown symbol %s\n",
+ me->name, strtab + sym->st_name);
+ return -ENOENT;
+ }
+
+ v = sym->st_value + rel[i].r_addend;
+
+ res = reloc_handlers_rela[ELF_MIPS_R_TYPE(rel[i])](me, location, v);
+ if (res)
+ return res;
+ }
+
+ return 0;
+}
+
/* Given an address, look for it in the module exception tables. */
const struct exception_table_entry *search_module_dbetables(unsigned long addr)
{
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c
index 0f159f30e894..86fe15b273cd 100644
--- a/arch/mips/kernel/proc.c
+++ b/arch/mips/kernel/proc.c
@@ -2,7 +2,8 @@
* linux/arch/mips/kernel/proc.c
*
* Copyright (C) 1995, 1996, 2001 Ralf Baechle
- * Copyright (C) 2001 MIPS Technologies, Inc.
+ * Copyright (C) 2001, 2004 MIPS Technologies, Inc.
+ * Copyright (C) 2004 Maciej W. Rozycki
*/
#include <linux/config.h>
#include <linux/delay.h>
@@ -19,63 +20,69 @@
unsigned int vced_count, vcei_count;
static const char *cpu_name[] = {
- [CPU_UNKNOWN] "unknown",
- [CPU_R2000] "R2000",
- [CPU_R3000] "R3000",
- [CPU_R3000A] "R3000A",
- [CPU_R3041] "R3041",
- [CPU_R3051] "R3051",
- [CPU_R3052] "R3052",
- [CPU_R3081] "R3081",
- [CPU_R3081E] "R3081E",
- [CPU_R4000PC] "R4000PC",
- [CPU_R4000SC] "R4000SC",
- [CPU_R4000MC] "R4000MC",
- [CPU_R4200] "R4200",
- [CPU_R4400PC] "R4400PC",
- [CPU_R4400SC] "R4400SC",
- [CPU_R4400MC] "R4400MC",
- [CPU_R4600] "R4600",
- [CPU_R6000] "R6000",
- [CPU_R6000A] "R6000A",
- [CPU_R8000] "R8000",
- [CPU_R10000] "R10000",
- [CPU_R12000] "R12000",
- [CPU_R4300] "R4300",
- [CPU_R4650] "R4650",
- [CPU_R4700] "R4700",
- [CPU_R5000] "R5000",
- [CPU_R5000A] "R5000A",
- [CPU_R4640] "R4640",
- [CPU_NEVADA] "Nevada",
- [CPU_RM7000] "RM7000",
- [CPU_RM9000] "RM9000",
- [CPU_R5432] "R5432",
- [CPU_4KC] "MIPS 4Kc",
- [CPU_5KC] "MIPS 5Kc",
- [CPU_R4310] "R4310",
- [CPU_SB1] "SiByte SB1",
- [CPU_TX3912] "TX3912",
- [CPU_TX3922] "TX3922",
- [CPU_TX3927] "TX3927",
- [CPU_AU1000] "Au1000",
- [CPU_AU1500] "Au1500",
- [CPU_4KEC] "MIPS 4KEc",
- [CPU_4KSC] "MIPS 4KSc",
- [CPU_VR41XX] "NEC Vr41xx",
- [CPU_R5500] "R5500",
- [CPU_TX49XX] "TX49xx",
- [CPU_20KC] "MIPS 20Kc",
- [CPU_24K] "MIPS 24K",
- [CPU_25KF] "MIPS 25Kf",
- [CPU_VR4111] "NEC VR4111",
- [CPU_VR4121] "NEC VR4121",
- [CPU_VR4122] "NEC VR4122",
- [CPU_VR4131] "NEC VR4131",
- [CPU_VR4133] "NEC VR4133",
- [CPU_VR4181] "NEC VR4181",
- [CPU_VR4181A] "NEC VR4181A",
- [CPU_SR71000] "Sandcraft SR71000"
+ [CPU_UNKNOWN] = "unknown",
+ [CPU_R2000] = "R2000",
+ [CPU_R3000] = "R3000",
+ [CPU_R3000A] = "R3000A",
+ [CPU_R3041] = "R3041",
+ [CPU_R3051] = "R3051",
+ [CPU_R3052] = "R3052",
+ [CPU_R3081] = "R3081",
+ [CPU_R3081E] = "R3081E",
+ [CPU_R4000PC] = "R4000PC",
+ [CPU_R4000SC] = "R4000SC",
+ [CPU_R4000MC] = "R4000MC",
+ [CPU_R4200] = "R4200",
+ [CPU_R4400PC] = "R4400PC",
+ [CPU_R4400SC] = "R4400SC",
+ [CPU_R4400MC] = "R4400MC",
+ [CPU_R4600] = "R4600",
+ [CPU_R6000] = "R6000",
+ [CPU_R6000A] = "R6000A",
+ [CPU_R8000] = "R8000",
+ [CPU_R10000] = "R10000",
+ [CPU_R12000] = "R12000",
+ [CPU_R4300] = "R4300",
+ [CPU_R4650] = "R4650",
+ [CPU_R4700] = "R4700",
+ [CPU_R5000] = "R5000",
+ [CPU_R5000A] = "R5000A",
+ [CPU_R4640] = "R4640",
+ [CPU_NEVADA] = "Nevada",
+ [CPU_RM7000] = "RM7000",
+ [CPU_RM9000] = "RM9000",
+ [CPU_R5432] = "R5432",
+ [CPU_4KC] = "MIPS 4Kc",
+ [CPU_5KC] = "MIPS 5Kc",
+ [CPU_R4310] = "R4310",
+ [CPU_SB1] = "SiByte SB1",
+ [CPU_SB1A] = "SiByte SB1A",
+ [CPU_TX3912] = "TX3912",
+ [CPU_TX3922] = "TX3922",
+ [CPU_TX3927] = "TX3927",
+ [CPU_AU1000] = "Au1000",
+ [CPU_AU1500] = "Au1500",
+ [CPU_AU1100] = "Au1100",
+ [CPU_AU1550] = "Au1550",
+ [CPU_AU1200] = "Au1200",
+ [CPU_4KEC] = "MIPS 4KEc",
+ [CPU_4KSC] = "MIPS 4KSc",
+ [CPU_VR41XX] = "NEC Vr41xx",
+ [CPU_R5500] = "R5500",
+ [CPU_TX49XX] = "TX49xx",
+ [CPU_20KC] = "MIPS 20Kc",
+ [CPU_24K] = "MIPS 24K",
+ [CPU_25KF] = "MIPS 25Kf",
+ [CPU_34K] = "MIPS 34K",
+ [CPU_VR4111] = "NEC VR4111",
+ [CPU_VR4121] = "NEC VR4121",
+ [CPU_VR4122] = "NEC VR4122",
+ [CPU_VR4131] = "NEC VR4131",
+ [CPU_VR4133] = "NEC VR4133",
+ [CPU_VR4181] = "NEC VR4181",
+ [CPU_VR4181A] = "NEC VR4181A",
+ [CPU_SR71000] = "Sandcraft SR71000",
+ [CPU_PR4450] = "Philips PR4450",
};
@@ -105,8 +112,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
(version >> 4) & 0x0f, version & 0x0f,
(fp_vers >> 4) & 0x0f, fp_vers & 0x0f);
seq_printf(m, "BogoMIPS\t\t: %lu.%02lu\n",
- loops_per_jiffy / (500000/HZ),
- (loops_per_jiffy / (5000/HZ)) % 100);
+ cpu_data[n].udelay_val / (500000/HZ),
+ (cpu_data[n].udelay_val / (5000/HZ)) % 100);
seq_printf(m, "wait instruction\t: %s\n", cpu_wait ? "yes" : "no");
seq_printf(m, "microsecond timers\t: %s\n",
cpu_has_counter ? "yes" : "no");
@@ -115,6 +122,14 @@ static int show_cpuinfo(struct seq_file *m, void *v)
cpu_has_divec ? "yes" : "no");
seq_printf(m, "hardware watchpoint\t: %s\n",
cpu_has_watch ? "yes" : "no");
+ seq_printf(m, "ASEs implemented\t:%s%s%s%s%s%s\n",
+ cpu_has_mips16 ? " mips16" : "",
+ cpu_has_mdmx ? " mdmx" : "",
+ cpu_has_mips3d ? " mips3d" : "",
+ cpu_has_smartmips ? " smartmips" : "",
+ cpu_has_dsp ? " dsp" : "",
+ cpu_has_mipsmt ? " mt" : ""
+ );
sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",
cpu_has_vce ? "%u" : "not available");
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index e4f2f8011387..4fe3d5715c41 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -25,8 +25,10 @@
#include <linux/init.h>
#include <linux/completion.h>
+#include <asm/abi.h>
#include <asm/bootinfo.h>
#include <asm/cpu.h>
+#include <asm/dsp.h>
#include <asm/fpu.h>
#include <asm/pgtable.h>
#include <asm/system.h>
@@ -39,14 +41,6 @@
#include <asm/inst.h>
/*
- * We use this if we don't have any better idle routine..
- * (This to kill: kernel/platform.c.
- */
-void default_idle (void)
-{
-}
-
-/*
* The idle thread. There's no useful work to be done, so just try to conserve
* power and have a low exit latency (ie sit in a loop waiting for somebody to
* say that they'd like to reschedule)
@@ -62,6 +56,54 @@ ATTRIB_NORET void cpu_idle(void)
}
}
+extern int do_signal(sigset_t *oldset, struct pt_regs *regs);
+extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
+
+/*
+ * Native o32 and N64 ABI without DSP ASE
+ */
+extern int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
+ int signr, sigset_t *set);
+extern int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
+ int signr, sigset_t *set, siginfo_t *info);
+
+struct mips_abi mips_abi = {
+ .do_signal = do_signal,
+#ifdef CONFIG_TRAD_SIGNALS
+ .setup_frame = setup_frame,
+#endif
+ .setup_rt_frame = setup_rt_frame
+};
+
+#ifdef CONFIG_MIPS32_O32
+/*
+ * o32 compatibility on 64-bit kernels, without DSP ASE
+ */
+extern int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
+ int signr, sigset_t *set);
+extern int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
+ int signr, sigset_t *set, siginfo_t *info);
+
+struct mips_abi mips_abi_32 = {
+ .do_signal = do_signal32,
+ .setup_frame = setup_frame_32,
+ .setup_rt_frame = setup_rt_frame_32
+};
+#endif /* CONFIG_MIPS32_O32 */
+
+#ifdef CONFIG_MIPS32_N32
+/*
+ * N32 on 64-bit kernels, without DSP ASE
+ */
+extern int setup_rt_frame_n32(struct k_sigaction * ka, struct pt_regs *regs,
+ int signr, sigset_t *set, siginfo_t *info);
+
+struct mips_abi mips_abi_n32 = {
+ .do_signal = do_signal,
+ .setup_rt_frame = setup_rt_frame_n32
+};
+#endif /* CONFIG_MIPS32_N32 */
+
asmlinkage void ret_from_fork(void);
void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
@@ -78,6 +120,8 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
regs->cp0_status = status;
clear_used_math();
lose_fpu();
+ if (cpu_has_dsp)
+ __init_dsp();
regs->cp0_epc = pc;
regs->regs[29] = sp;
current_thread_info()->addr_limit = USER_DS;
@@ -97,14 +141,17 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
struct thread_info *ti = p->thread_info;
struct pt_regs *childregs;
long childksp;
+ p->set_child_tid = p->clear_child_tid = NULL;
childksp = (unsigned long)ti + THREAD_SIZE - 32;
preempt_disable();
- if (is_fpu_owner()) {
+ if (is_fpu_owner())
save_fp(p);
- }
+
+ if (cpu_has_dsp)
+ save_dsp(p);
preempt_enable();
@@ -142,6 +189,9 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
childregs->cp0_status &= ~(ST0_CU2|ST0_CU1);
clear_tsk_thread_flag(p, TIF_USEDFPU);
+ if (clone_flags & CLONE_SETTLS)
+ ti->tp_value = regs->regs[7];
+
return 0;
}
@@ -175,6 +225,14 @@ void dump_regs(elf_greg_t *gp, struct pt_regs *regs)
#endif
}
+int dump_task_regs (struct task_struct *tsk, elf_gregset_t *regs)
+{
+ struct thread_info *ti = tsk->thread_info;
+ long ksp = (unsigned long)ti + THREAD_SIZE - 32;
+ dump_regs(&(*regs)[0], (struct pt_regs *) ksp - 1);
+ return 1;
+}
+
int dump_task_fpu (struct task_struct *t, elf_fpregset_t *fpr)
{
memcpy(fpr, &t->thread.fpu, sizeof(current->thread.fpu));
@@ -211,22 +269,48 @@ long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
}
-struct mips_frame_info {
+static struct mips_frame_info {
+ void *func;
+ int omit_fp; /* compiled without fno-omit-frame-pointer */
int frame_offset;
int pc_offset;
+} schedule_frame, mfinfo[] = {
+ { schedule, 0 }, /* must be first */
+ /* arch/mips/kernel/semaphore.c */
+ { __down, 1 },
+ { __down_interruptible, 1 },
+ /* kernel/sched.c */
+#ifdef CONFIG_PREEMPT
+ { preempt_schedule, 0 },
+#endif
+ { wait_for_completion, 0 },
+ { interruptible_sleep_on, 0 },
+ { interruptible_sleep_on_timeout, 0 },
+ { sleep_on, 0 },
+ { sleep_on_timeout, 0 },
+ { yield, 0 },
+ { io_schedule, 0 },
+ { io_schedule_timeout, 0 },
+#if defined(CONFIG_SMP) && defined(CONFIG_PREEMPT)
+ { __preempt_spin_lock, 0 },
+ { __preempt_write_lock, 0 },
+#endif
+ /* kernel/timer.c */
+ { schedule_timeout, 1 },
+/* { nanosleep_restart, 1 }, */
+ /* lib/rwsem-spinlock.c */
+ { __down_read, 1 },
+ { __down_write, 1 },
};
-static struct mips_frame_info schedule_frame;
-static struct mips_frame_info schedule_timeout_frame;
-static struct mips_frame_info sleep_on_frame;
-static struct mips_frame_info sleep_on_timeout_frame;
-static struct mips_frame_info wait_for_completion_frame;
+
static int mips_frame_info_initialized;
-static int __init get_frame_info(struct mips_frame_info *info, void *func)
+static int __init get_frame_info(struct mips_frame_info *info)
{
int i;
+ void *func = info->func;
union mips_instruction *ip = (union mips_instruction *)func;
info->pc_offset = -1;
- info->frame_offset = -1;
+ info->frame_offset = info->omit_fp ? 0 : -1;
for (i = 0; i < 128; i++, ip++) {
/* if jal, jalr, jr, stop. */
if (ip->j_format.opcode == jal_op ||
@@ -247,14 +331,16 @@ static int __init get_frame_info(struct mips_frame_info *info, void *func)
/* sw / sd $ra, offset($sp) */
if (ip->i_format.rt == 31) {
if (info->pc_offset != -1)
- break;
+ continue;
info->pc_offset =
ip->i_format.simmediate / sizeof(long);
}
/* sw / sd $s8, offset($sp) */
if (ip->i_format.rt == 30) {
+//#if 0 /* gcc 3.4 does aggressive optimization... */
if (info->frame_offset != -1)
- break;
+ continue;
+//#endif
info->frame_offset =
ip->i_format.simmediate / sizeof(long);
}
@@ -272,13 +358,25 @@ static int __init get_frame_info(struct mips_frame_info *info, void *func)
static int __init frame_info_init(void)
{
- mips_frame_info_initialized =
- !get_frame_info(&schedule_frame, schedule) &&
- !get_frame_info(&schedule_timeout_frame, schedule_timeout) &&
- !get_frame_info(&sleep_on_frame, sleep_on) &&
- !get_frame_info(&sleep_on_timeout_frame, sleep_on_timeout) &&
- !get_frame_info(&wait_for_completion_frame, wait_for_completion);
-
+ int i, found;
+ for (i = 0; i < ARRAY_SIZE(mfinfo); i++)
+ if (get_frame_info(&mfinfo[i]))
+ return -1;
+ schedule_frame = mfinfo[0];
+ /* bubble sort */
+ do {
+ struct mips_frame_info tmp;
+ found = 0;
+ for (i = 1; i < ARRAY_SIZE(mfinfo); i++) {
+ if (mfinfo[i-1].func > mfinfo[i].func) {
+ tmp = mfinfo[i];
+ mfinfo[i] = mfinfo[i-1];
+ mfinfo[i-1] = tmp;
+ found = 1;
+ }
+ }
+ } while (found);
+ mips_frame_info_initialized = 1;
return 0;
}
@@ -303,60 +401,39 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
/* get_wchan - a maintenance nightmare^W^Wpain in the ass ... */
unsigned long get_wchan(struct task_struct *p)
{
+ unsigned long stack_page;
unsigned long frame, pc;
if (!p || p == current || p->state == TASK_RUNNING)
return 0;
- if (!mips_frame_info_initialized)
+ stack_page = (unsigned long)p->thread_info;
+ if (!stack_page || !mips_frame_info_initialized)
return 0;
+
pc = thread_saved_pc(p);
if (!in_sched_functions(pc))
- goto out;
-
- if (pc >= (unsigned long) sleep_on_timeout)
- goto schedule_timeout_caller;
- if (pc >= (unsigned long) sleep_on)
- goto schedule_caller;
- if (pc >= (unsigned long) interruptible_sleep_on_timeout)
- goto schedule_timeout_caller;
- if (pc >= (unsigned long)interruptible_sleep_on)
- goto schedule_caller;
- if (pc >= (unsigned long)wait_for_completion)
- goto schedule_caller;
- goto schedule_timeout_caller;
-
-schedule_caller:
- frame = ((unsigned long *)p->thread.reg30)[schedule_frame.frame_offset];
- if (pc >= (unsigned long) sleep_on)
- pc = ((unsigned long *)frame)[sleep_on_frame.pc_offset];
- else
- pc = ((unsigned long *)frame)[wait_for_completion_frame.pc_offset];
- goto out;
+ return pc;
-schedule_timeout_caller:
- /*
- * The schedule_timeout frame
- */
frame = ((unsigned long *)p->thread.reg30)[schedule_frame.frame_offset];
+ do {
+ int i;
- /*
- * frame now points to sleep_on_timeout's frame
- */
- pc = ((unsigned long *)frame)[schedule_timeout_frame.pc_offset];
-
- if (in_sched_functions(pc)) {
- /* schedule_timeout called by [interruptible_]sleep_on_timeout */
- frame = ((unsigned long *)frame)[schedule_timeout_frame.frame_offset];
- pc = ((unsigned long *)frame)[sleep_on_timeout_frame.pc_offset];
- }
+ if (frame < stack_page || frame > stack_page + THREAD_SIZE - 32)
+ return 0;
-out:
+ for (i = ARRAY_SIZE(mfinfo) - 1; i >= 0; i--) {
+ if (pc >= (unsigned long) mfinfo[i].func)
+ break;
+ }
+ if (i < 0)
+ break;
-#ifdef CONFIG_64BIT
- if (current->thread.mflags & MF_32BIT_REGS) /* Kludge for 32-bit ps */
- pc &= 0xffffffffUL;
-#endif
+ if (mfinfo[i].omit_fp)
+ break;
+ pc = ((unsigned long *)frame)[mfinfo[i].pc_offset];
+ frame = ((unsigned long *)frame)[mfinfo[i].frame_offset];
+ } while (in_sched_functions(pc));
return pc;
}
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 0b571a5b4b83..f1b0f3e1f95b 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -28,14 +28,18 @@
#include <linux/security.h>
#include <linux/signal.h>
+#include <asm/byteorder.h>
#include <asm/cpu.h>
+#include <asm/dsp.h>
#include <asm/fpu.h>
#include <asm/mipsregs.h>
+#include <asm/mipsmtregs.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/bootinfo.h>
+#include <asm/reg.h>
/*
* Called by kernel/ptrace.c when detaching..
@@ -47,7 +51,130 @@ void ptrace_disable(struct task_struct *child)
/* Nothing to do.. */
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+/*
+ * Read a general register set. We always use the 64-bit format, even
+ * for 32-bit kernels and for 32-bit processes on a 64-bit kernel.
+ * Registers are sign extended to fill the available space.
+ */
+int ptrace_getregs (struct task_struct *child, __s64 __user *data)
+{
+ struct pt_regs *regs;
+ int i;
+
+ if (!access_ok(VERIFY_WRITE, data, 38 * 8))
+ return -EIO;
+
+ regs = (struct pt_regs *) ((unsigned long) child->thread_info +
+ THREAD_SIZE - 32 - sizeof(struct pt_regs));
+
+ for (i = 0; i < 32; i++)
+ __put_user (regs->regs[i], data + i);
+ __put_user (regs->lo, data + EF_LO - EF_R0);
+ __put_user (regs->hi, data + EF_HI - EF_R0);
+ __put_user (regs->cp0_epc, data + EF_CP0_EPC - EF_R0);
+ __put_user (regs->cp0_badvaddr, data + EF_CP0_BADVADDR - EF_R0);
+ __put_user (regs->cp0_status, data + EF_CP0_STATUS - EF_R0);
+ __put_user (regs->cp0_cause, data + EF_CP0_CAUSE - EF_R0);
+
+ return 0;
+}
+
+/*
+ * Write a general register set. As for PTRACE_GETREGS, we always use
+ * the 64-bit format. On a 32-bit kernel only the lower order half
+ * (according to endianness) will be used.
+ */
+int ptrace_setregs (struct task_struct *child, __s64 __user *data)
+{
+ struct pt_regs *regs;
+ int i;
+
+ if (!access_ok(VERIFY_READ, data, 38 * 8))
+ return -EIO;
+
+ regs = (struct pt_regs *) ((unsigned long) child->thread_info +
+ THREAD_SIZE - 32 - sizeof(struct pt_regs));
+
+ for (i = 0; i < 32; i++)
+ __get_user (regs->regs[i], data + i);
+ __get_user (regs->lo, data + EF_LO - EF_R0);
+ __get_user (regs->hi, data + EF_HI - EF_R0);
+ __get_user (regs->cp0_epc, data + EF_CP0_EPC - EF_R0);
+
+ /* badvaddr, status, and cause may not be written. */
+
+ return 0;
+}
+
+int ptrace_getfpregs (struct task_struct *child, __u32 __user *data)
+{
+ int i;
+
+ if (!access_ok(VERIFY_WRITE, data, 33 * 8))
+ return -EIO;
+
+ if (tsk_used_math(child)) {
+ fpureg_t *fregs = get_fpu_regs(child);
+ for (i = 0; i < 32; i++)
+ __put_user (fregs[i], i + (__u64 __user *) data);
+ } else {
+ for (i = 0; i < 32; i++)
+ __put_user ((__u64) -1, i + (__u64 __user *) data);
+ }
+
+ if (cpu_has_fpu) {
+ unsigned int flags, tmp;
+
+ __put_user (child->thread.fpu.hard.fcr31, data + 64);
+
+ preempt_disable();
+ if (cpu_has_mipsmt) {
+ unsigned int vpflags = dvpe();
+ flags = read_c0_status();
+ __enable_fpu();
+ __asm__ __volatile__("cfc1\t%0,$0" : "=r" (tmp));
+ write_c0_status(flags);
+ evpe(vpflags);
+ } else {
+ flags = read_c0_status();
+ __enable_fpu();
+ __asm__ __volatile__("cfc1\t%0,$0" : "=r" (tmp));
+ write_c0_status(flags);
+ }
+ preempt_enable();
+ __put_user (tmp, data + 65);
+ } else {
+ __put_user (child->thread.fpu.soft.fcr31, data + 64);
+ __put_user ((__u32) 0, data + 65);
+ }
+
+ return 0;
+}
+
+int ptrace_setfpregs (struct task_struct *child, __u32 __user *data)
+{
+ fpureg_t *fregs;
+ int i;
+
+ if (!access_ok(VERIFY_READ, data, 33 * 8))
+ return -EIO;
+
+ fregs = get_fpu_regs(child);
+
+ for (i = 0; i < 32; i++)
+ __get_user (fregs[i], i + (__u64 __user *) data);
+
+ if (cpu_has_fpu)
+ __get_user (child->thread.fpu.hard.fcr31, data + 64);
+ else
+ __get_user (child->thread.fpu.soft.fcr31, data + 64);
+
+ /* FIR may not be written. */
+
+ return 0;
+}
+
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
int ret;
@@ -103,7 +230,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
ret = -EIO;
if (copied != sizeof(tmp))
break;
- ret = put_user(tmp,(unsigned long *) data);
+ ret = put_user(tmp,(unsigned long __user *) data);
break;
}
@@ -169,18 +296,53 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
if (!cpu_has_fpu)
break;
- flags = read_c0_status();
- __enable_fpu();
- __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
- write_c0_status(flags);
+ preempt_disable();
+ if (cpu_has_mipsmt) {
+ unsigned int vpflags = dvpe();
+ flags = read_c0_status();
+ __enable_fpu();
+ __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
+ write_c0_status(flags);
+ evpe(vpflags);
+ } else {
+ flags = read_c0_status();
+ __enable_fpu();
+ __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
+ write_c0_status(flags);
+ }
+ preempt_enable();
+ break;
+ }
+ case DSP_BASE ... DSP_BASE + 5: {
+ dspreg_t *dregs;
+
+ if (!cpu_has_dsp) {
+ tmp = 0;
+ ret = -EIO;
+ goto out_tsk;
+ }
+ if (child->thread.dsp.used_dsp) {
+ dregs = __get_dsp_regs(child);
+ tmp = (unsigned long) (dregs[addr - DSP_BASE]);
+ } else {
+ tmp = -1; /* DSP registers yet used */
+ }
break;
}
+ case DSP_CONTROL:
+ if (!cpu_has_dsp) {
+ tmp = 0;
+ ret = -EIO;
+ goto out_tsk;
+ }
+ tmp = child->thread.dsp.dspcontrol;
+ break;
default:
tmp = 0;
ret = -EIO;
goto out_tsk;
}
- ret = put_user(tmp, (unsigned long *) data);
+ ret = put_user(tmp, (unsigned long __user *) data);
break;
}
@@ -247,6 +409,25 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
else
child->thread.fpu.soft.fcr31 = data;
break;
+ case DSP_BASE ... DSP_BASE + 5: {
+ dspreg_t *dregs;
+
+ if (!cpu_has_dsp) {
+ ret = -EIO;
+ break;
+ }
+
+ dregs = __get_dsp_regs(child);
+ dregs[addr - DSP_BASE] = data;
+ break;
+ }
+ case DSP_CONTROL:
+ if (!cpu_has_dsp) {
+ ret = -EIO;
+ break;
+ }
+ child->thread.dsp.dspcontrol = data;
+ break;
default:
/* The rest are not allowed. */
ret = -EIO;
@@ -255,6 +436,22 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
break;
}
+ case PTRACE_GETREGS:
+ ret = ptrace_getregs (child, (__u64 __user *) data);
+ break;
+
+ case PTRACE_SETREGS:
+ ret = ptrace_setregs (child, (__u64 __user *) data);
+ break;
+
+ case PTRACE_GETFPREGS:
+ ret = ptrace_getfpregs (child, (__u32 __user *) data);
+ break;
+
+ case PTRACE_SETFPREGS:
+ ret = ptrace_setfpregs (child, (__u32 __user *) data);
+ break;
+
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
case PTRACE_CONT: { /* restart after signal. */
ret = -EIO;
@@ -289,6 +486,11 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
ret = ptrace_detach(child, data);
break;
+ case PTRACE_GET_THREAD_AREA:
+ ret = put_user(child->thread_info->tp_value,
+ (unsigned long __user *) data);
+ break;
+
default:
ret = ptrace_request(child, request, addr, data);
break;
@@ -303,21 +505,14 @@ out:
static inline int audit_arch(void)
{
-#ifdef CONFIG_CPU_LITTLE_ENDIAN
-#ifdef CONFIG_64BIT
- if (!(current->thread.mflags & MF_32BIT_REGS))
- return AUDIT_ARCH_MIPSEL64;
-#endif /* MIPS64 */
- return AUDIT_ARCH_MIPSEL;
-
-#else /* big endian... */
+ int arch = EM_MIPS;
#ifdef CONFIG_64BIT
- if (!(current->thread.mflags & MF_32BIT_REGS))
- return AUDIT_ARCH_MIPS64;
-#endif /* MIPS64 */
- return AUDIT_ARCH_MIPS;
-
-#endif /* endian */
+ arch |= __AUDIT_ARCH_64BIT;
+#endif
+#if defined(__LITTLE_ENDIAN)
+ arch |= __AUDIT_ARCH_LE;
+#endif
+ return arch;
}
/*
@@ -327,12 +522,13 @@ static inline int audit_arch(void)
asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
{
if (unlikely(current->audit_context) && entryexit)
- audit_syscall_exit(current, AUDITSC_RESULT(regs->regs[2]), regs->regs[2]);
+ audit_syscall_exit(current, AUDITSC_RESULT(regs->regs[2]),
+ regs->regs[2]);
- if (!test_thread_flag(TIF_SYSCALL_TRACE))
- goto out;
if (!(current->ptrace & PT_PTRACED))
goto out;
+ if (!test_thread_flag(TIF_SYSCALL_TRACE))
+ goto out;
/* The 0x80 provides a way for the tracing parent to distinguish
between a syscall stop and SIGTRAP delivery */
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c
index eee207969c21..9a9b04972132 100644
--- a/arch/mips/kernel/ptrace32.c
+++ b/arch/mips/kernel/ptrace32.c
@@ -24,17 +24,24 @@
#include <linux/smp_lock.h>
#include <linux/user.h>
#include <linux/security.h>
-#include <linux/signal.h>
#include <asm/cpu.h>
+#include <asm/dsp.h>
#include <asm/fpu.h>
#include <asm/mipsregs.h>
+#include <asm/mipsmtregs.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/bootinfo.h>
+int ptrace_getregs (struct task_struct *child, __s64 __user *data);
+int ptrace_setregs (struct task_struct *child, __s64 __user *data);
+
+int ptrace_getfpregs (struct task_struct *child, __u32 __user *data);
+int ptrace_setfpregs (struct task_struct *child, __u32 __user *data);
+
/*
* Tracing a 32-bit process with a 64-bit strace and vice versa will not
* work. I don't know how to fix this.
@@ -99,6 +106,35 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
break;
}
+ /*
+ * Read 4 bytes of the other process' storage
+ * data is a pointer specifying where the user wants the
+ * 4 bytes copied into
+ * addr is a pointer in the user's storage that contains an 8 byte
+ * address in the other process of the 4 bytes that is to be read
+ * (this is run in a 32-bit process looking at a 64-bit process)
+ * when I and D space are separate, these will need to be fixed.
+ */
+ case PTRACE_PEEKTEXT_3264:
+ case PTRACE_PEEKDATA_3264: {
+ u32 tmp;
+ int copied;
+ u32 __user * addrOthers;
+
+ ret = -EIO;
+
+ /* Get the addr in the other process that we want to read */
+ if (get_user(addrOthers, (u32 __user * __user *) (unsigned long) addr) != 0)
+ break;
+
+ copied = access_process_vm(child, (u64)addrOthers, &tmp,
+ sizeof(tmp), 0);
+ if (copied != sizeof(tmp))
+ break;
+ ret = put_user(tmp, (u32 __user *) (unsigned long) data);
+ break;
+ }
+
/* Read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: {
struct pt_regs *regs;
@@ -156,12 +192,44 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
if (!cpu_has_fpu)
break;
- flags = read_c0_status();
- __enable_fpu();
- __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
- write_c0_status(flags);
+ preempt_disable();
+ if (cpu_has_mipsmt) {
+ unsigned int vpflags = dvpe();
+ flags = read_c0_status();
+ __enable_fpu();
+ __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
+ write_c0_status(flags);
+ evpe(vpflags);
+ } else {
+ flags = read_c0_status();
+ __enable_fpu();
+ __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
+ write_c0_status(flags);
+ }
+ preempt_enable();
break;
}
+ case DSP_BASE ... DSP_BASE + 5:
+ if (!cpu_has_dsp) {
+ tmp = 0;
+ ret = -EIO;
+ goto out_tsk;
+ }
+ if (child->thread.dsp.used_dsp) {
+ dspreg_t *dregs = __get_dsp_regs(child);
+ tmp = (unsigned long) (dregs[addr - DSP_BASE]);
+ } else {
+ tmp = -1; /* DSP registers yet used */
+ }
+ break;
+ case DSP_CONTROL:
+ if (!cpu_has_dsp) {
+ tmp = 0;
+ ret = -EIO;
+ goto out_tsk;
+ }
+ tmp = child->thread.dsp.dspcontrol;
+ break;
default:
tmp = 0;
ret = -EIO;
@@ -181,6 +249,31 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
ret = -EIO;
break;
+ /*
+ * Write 4 bytes into the other process' storage
+ * data is the 4 bytes that the user wants written
+ * addr is a pointer in the user's storage that contains an
+ * 8 byte address in the other process where the 4 bytes
+ * that is to be written
+ * (this is run in a 32-bit process looking at a 64-bit process)
+ * when I and D space are separate, these will need to be fixed.
+ */
+ case PTRACE_POKETEXT_3264:
+ case PTRACE_POKEDATA_3264: {
+ u32 __user * addrOthers;
+
+ /* Get the addr in the other process that we want to write into */
+ ret = -EIO;
+ if (get_user(addrOthers, (u32 __user * __user *) (unsigned long) addr) != 0)
+ break;
+ ret = 0;
+ if (access_process_vm(child, (u64)addrOthers, &data,
+ sizeof(data), 1) == sizeof(data))
+ break;
+ ret = -EIO;
+ break;
+ }
+
case PTRACE_POKEUSR: {
struct pt_regs *regs;
ret = 0;
@@ -231,6 +324,22 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
else
child->thread.fpu.soft.fcr31 = data;
break;
+ case DSP_BASE ... DSP_BASE + 5:
+ if (!cpu_has_dsp) {
+ ret = -EIO;
+ break;
+ }
+
+ dspreg_t *dregs = __get_dsp_regs(child);
+ dregs[addr - DSP_BASE] = data;
+ break;
+ case DSP_CONTROL:
+ if (!cpu_has_dsp) {
+ ret = -EIO;
+ break;
+ }
+ child->thread.dsp.dspcontrol = data;
+ break;
default:
/* The rest are not allowed. */
ret = -EIO;
@@ -239,6 +348,22 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
break;
}
+ case PTRACE_GETREGS:
+ ret = ptrace_getregs (child, (__u64 __user *) (__u64) data);
+ break;
+
+ case PTRACE_SETREGS:
+ ret = ptrace_setregs (child, (__u64 __user *) (__u64) data);
+ break;
+
+ case PTRACE_GETFPREGS:
+ ret = ptrace_getfpregs (child, (__u32 __user *) (__u64) data);
+ break;
+
+ case PTRACE_SETFPREGS:
+ ret = ptrace_setfpregs (child, (__u32 __user *) (__u64) data);
+ break;
+
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
case PTRACE_CONT: { /* restart after signal. */
ret = -EIO;
@@ -269,10 +394,25 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
wake_up_process(child);
break;
+ case PTRACE_GET_THREAD_AREA:
+ ret = put_user(child->thread_info->tp_value,
+ (unsigned int __user *) (unsigned long) data);
+ break;
+
case PTRACE_DETACH: /* detach a process that was attached. */
ret = ptrace_detach(child, data);
break;
+ case PTRACE_GETEVENTMSG:
+ ret = put_user(child->ptrace_message,
+ (unsigned int __user *) (unsigned long) data);
+ break;
+
+ case PTRACE_GET_THREAD_AREA_3264:
+ ret = put_user(child->thread_info->tp_value,
+ (unsigned long __user *) (unsigned long) data);
+ break;
+
default:
ret = ptrace_request(child, request, addr, data);
break;
diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S
index 1a14c6b18829..283a98508fc8 100644
--- a/arch/mips/kernel/r4k_fpu.S
+++ b/arch/mips/kernel/r4k_fpu.S
@@ -32,7 +32,7 @@
.set noreorder
.set mips3
- /* Save floating point context */
+
LEAF(_save_fp_context)
cfc1 t1, fcr31
@@ -74,9 +74,6 @@ LEAF(_save_fp_context)
EX sdc1 $f28, SC_FPREGS+224(a0)
EX sdc1 $f30, SC_FPREGS+240(a0)
EX sw t1, SC_FPC_CSR(a0)
- cfc1 t0, $0 # implementation/version
- EX sw t0, SC_FPC_EIR(a0)
-
jr ra
li v0, 0 # success
END(_save_fp_context)
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c
new file mode 100644
index 000000000000..8c81f3cb4e2d
--- /dev/null
+++ b/arch/mips/kernel/rtlx.c
@@ -0,0 +1,341 @@
+/*
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/vmalloc.h>
+#include <linux/elf.h>
+#include <linux/seq_file.h>
+#include <linux/syscalls.h>
+#include <linux/moduleloader.h>
+#include <linux/interrupt.h>
+#include <linux/poll.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <asm/mipsmtregs.h>
+#include <asm/cacheflush.h>
+#include <asm/atomic.h>
+#include <asm/cpu.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/rtlx.h>
+
+#define RTLX_MAJOR 64
+#define RTLX_TARG_VPE 1
+
+struct rtlx_info *rtlx;
+static int major;
+static char module_name[] = "rtlx";
+static inline int spacefree(int read, int write, int size);
+
+static struct chan_waitqueues {
+ wait_queue_head_t rt_queue;
+ wait_queue_head_t lx_queue;
+} channel_wqs[RTLX_CHANNELS];
+
+static struct irqaction irq;
+static int irq_num;
+
+extern void *vpe_get_shared(int index);
+
+static void rtlx_dispatch(struct pt_regs *regs)
+{
+ do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ, regs);
+}
+
+irqreturn_t rtlx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ irqreturn_t r = IRQ_HANDLED;
+ int i;
+
+ for (i = 0; i < RTLX_CHANNELS; i++) {
+ struct rtlx_channel *chan = &rtlx->channel[i];
+
+ if (chan->lx_read != chan->lx_write)
+ wake_up_interruptible(&channel_wqs[i].lx_queue);
+ }
+
+ return r;
+}
+
+void dump_rtlx(void)
+{
+ int i;
+
+ printk("id 0x%lx state %d\n", rtlx->id, rtlx->state);
+
+ for (i = 0; i < RTLX_CHANNELS; i++) {
+ struct rtlx_channel *chan = &rtlx->channel[i];
+
+ printk(" rt_state %d lx_state %d buffer_size %d\n",
+ chan->rt_state, chan->lx_state, chan->buffer_size);
+
+ printk(" rt_read %d rt_write %d\n",
+ chan->rt_read, chan->rt_write);
+
+ printk(" lx_read %d lx_write %d\n",
+ chan->lx_read, chan->lx_write);
+
+ printk(" rt_buffer <%s>\n", chan->rt_buffer);
+ printk(" lx_buffer <%s>\n", chan->lx_buffer);
+ }
+}
+
+/* call when we have the address of the shared structure from the SP side. */
+static int rtlx_init(struct rtlx_info *rtlxi)
+{
+ int i;
+
+ if (rtlxi->id != RTLX_ID) {
+ printk(KERN_WARNING "no valid RTLX id at 0x%p\n", rtlxi);
+ return (-ENOEXEC);
+ }
+
+ /* initialise the wait queues */
+ for (i = 0; i < RTLX_CHANNELS; i++) {
+ init_waitqueue_head(&channel_wqs[i].rt_queue);
+ init_waitqueue_head(&channel_wqs[i].lx_queue);
+ }
+
+ /* set up for interrupt handling */
+ memset(&irq, 0, sizeof(struct irqaction));
+
+ if (cpu_has_vint) {
+ set_vi_handler(MIPS_CPU_RTLX_IRQ, rtlx_dispatch);
+ }
+
+ irq_num = MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ;
+ irq.handler = rtlx_interrupt;
+ irq.flags = SA_INTERRUPT;
+ irq.name = "RTLX";
+ irq.dev_id = rtlx;
+ setup_irq(irq_num, &irq);
+
+ rtlx = rtlxi;
+ return (0);
+}
+
+/* only allow one open process at a time to open each channel */
+static int rtlx_open(struct inode *inode, struct file *filp)
+{
+ int minor, ret;
+ struct rtlx_channel *chan;
+
+ /* assume only 1 device at the mo. */
+ minor = MINOR(inode->i_rdev);
+
+ if (rtlx == NULL) {
+ struct rtlx_info **p;
+ if( (p = vpe_get_shared(RTLX_TARG_VPE)) == NULL) {
+ printk(" vpe_get_shared is NULL. Has an SP program been loaded?\n");
+ return (-EFAULT);
+ }
+
+ if (*p == NULL) {
+ printk(" vpe_shared %p %p\n", p, *p);
+ return (-EFAULT);
+ }
+
+ if ((ret = rtlx_init(*p)) < 0)
+ return (ret);
+ }
+
+ chan = &rtlx->channel[minor];
+
+ /* already open? */
+ if (chan->lx_state == RTLX_STATE_OPENED)
+ return (-EBUSY);
+
+ chan->lx_state = RTLX_STATE_OPENED;
+ return (0);
+}
+
+static int rtlx_release(struct inode *inode, struct file *filp)
+{
+ int minor;
+
+ minor = MINOR(inode->i_rdev);
+ rtlx->channel[minor].lx_state = RTLX_STATE_UNUSED;
+ return (0);
+}
+
+static unsigned int rtlx_poll(struct file *file, poll_table * wait)
+{
+ int minor;
+ unsigned int mask = 0;
+ struct rtlx_channel *chan;
+
+ minor = MINOR(file->f_dentry->d_inode->i_rdev);
+ chan = &rtlx->channel[minor];
+
+ poll_wait(file, &channel_wqs[minor].rt_queue, wait);
+ poll_wait(file, &channel_wqs[minor].lx_queue, wait);
+
+ /* data available to read? */
+ if (chan->lx_read != chan->lx_write)
+ mask |= POLLIN | POLLRDNORM;
+
+ /* space to write */
+ if (spacefree(chan->rt_read, chan->rt_write, chan->buffer_size))
+ mask |= POLLOUT | POLLWRNORM;
+
+ return (mask);
+}
+
+static ssize_t rtlx_read(struct file *file, char __user * buffer, size_t count,
+ loff_t * ppos)
+{
+ size_t fl = 0L;
+ int minor;
+ struct rtlx_channel *lx;
+ DECLARE_WAITQUEUE(wait, current);
+
+ minor = MINOR(file->f_dentry->d_inode->i_rdev);
+ lx = &rtlx->channel[minor];
+
+ /* data available? */
+ if (lx->lx_write == lx->lx_read) {
+ if (file->f_flags & O_NONBLOCK)
+ return (0); // -EAGAIN makes cat whinge
+
+ /* go to sleep */
+ add_wait_queue(&channel_wqs[minor].lx_queue, &wait);
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ while (lx->lx_write == lx->lx_read)
+ schedule();
+
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&channel_wqs[minor].lx_queue, &wait);
+
+ /* back running */
+ }
+
+ /* find out how much in total */
+ count = min( count,
+ (size_t)(lx->lx_write + lx->buffer_size - lx->lx_read) % lx->buffer_size);
+
+ /* then how much from the read pointer onwards */
+ fl = min( count, (size_t)lx->buffer_size - lx->lx_read);
+
+ copy_to_user (buffer, &lx->lx_buffer[lx->lx_read], fl);
+
+ /* and if there is anything left at the beginning of the buffer */
+ if ( count - fl )
+ copy_to_user (buffer + fl, lx->lx_buffer, count - fl);
+
+ /* update the index */
+ lx->lx_read += count;
+ lx->lx_read %= lx->buffer_size;
+
+ return (count);
+}
+
+static inline int spacefree(int read, int write, int size)
+{
+ if (read == write) {
+ /* never fill the buffer completely, so indexes are always equal if empty
+ and only empty, or !equal if data available */
+ return (size - 1);
+ }
+
+ return ((read + size - write) % size) - 1;
+}
+
+static ssize_t rtlx_write(struct file *file, const char __user * buffer,
+ size_t count, loff_t * ppos)
+{
+ int minor;
+ struct rtlx_channel *rt;
+ size_t fl;
+ DECLARE_WAITQUEUE(wait, current);
+
+ minor = MINOR(file->f_dentry->d_inode->i_rdev);
+ rt = &rtlx->channel[minor];
+
+ /* any space left... */
+ if (!spacefree(rt->rt_read, rt->rt_write, rt->buffer_size)) {
+
+ if (file->f_flags & O_NONBLOCK)
+ return (-EAGAIN);
+
+ add_wait_queue(&channel_wqs[minor].rt_queue, &wait);
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ while (!spacefree(rt->rt_read, rt->rt_write, rt->buffer_size))
+ schedule();
+
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&channel_wqs[minor].rt_queue, &wait);
+ }
+
+ /* total number of bytes to copy */
+ count = min( count, (size_t)spacefree(rt->rt_read, rt->rt_write, rt->buffer_size) );
+
+ /* first bit from write pointer to the end of the buffer, or count */
+ fl = min(count, (size_t) rt->buffer_size - rt->rt_write);
+
+ copy_from_user(&rt->rt_buffer[rt->rt_write], buffer, fl);
+
+ /* if there's any left copy to the beginning of the buffer */
+ if( count - fl )
+ copy_from_user(rt->rt_buffer, buffer + fl, count - fl);
+
+ rt->rt_write += count;
+ rt->rt_write %= rt->buffer_size;
+
+ return(count);
+}
+
+static struct file_operations rtlx_fops = {
+ .owner = THIS_MODULE,
+ .open = rtlx_open,
+ .release = rtlx_release,
+ .write = rtlx_write,
+ .read = rtlx_read,
+ .poll = rtlx_poll
+};
+
+static int rtlx_module_init(void)
+{
+ if ((major = register_chrdev(RTLX_MAJOR, module_name, &rtlx_fops)) < 0) {
+ printk("rtlx_module_init: unable to register device\n");
+ return (-EBUSY);
+ }
+
+ if (major == 0)
+ major = RTLX_MAJOR;
+
+ return (0);
+}
+
+static void rtlx_module_exit(void)
+{
+ unregister_chrdev(major, module_name);
+}
+
+module_init(rtlx_module_init);
+module_exit(rtlx_module_exit);
+MODULE_DESCRIPTION("MIPS RTLX");
+MODULE_AUTHOR("Elizabeth Clarke, MIPS Technologies, Inc");
+MODULE_LICENSE("GPL");
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index 17b5030fb6ea..4dd8e8b4fbc2 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -578,7 +578,7 @@ einval: li v0, -EINVAL
sys sys_fremovexattr 2 /* 4235 */
sys sys_tkill 2
sys sys_sendfile64 5
- sys sys_futex 2
+ sys sys_futex 6
sys sys_sched_setaffinity 3
sys sys_sched_getaffinity 3 /* 4240 */
sys sys_io_setup 2
@@ -587,7 +587,7 @@ einval: li v0, -EINVAL
sys sys_io_submit 3
sys sys_io_cancel 3 /* 4245 */
sys sys_exit_group 1
- sys sys_lookup_dcookie 3
+ sys sys_lookup_dcookie 4
sys sys_epoll_create 1
sys sys_epoll_ctl 4
sys sys_epoll_wait 3 /* 4250 */
@@ -618,12 +618,15 @@ einval: li v0, -EINVAL
sys sys_mq_notify 2 /* 4275 */
sys sys_mq_getsetattr 3
sys sys_ni_syscall 0 /* sys_vserver */
- sys sys_waitid 4
+ sys sys_waitid 5
sys sys_ni_syscall 0 /* available, was setaltroot */
- sys sys_add_key 5
+ sys sys_add_key 5 /* 4280 */
sys sys_request_key 4
sys sys_keyctl 5
-
+ sys sys_set_thread_area 1
+ sys sys_inotify_init 0
+ sys sys_inotify_add_watch 3 /* 4285 */
+ sys sys_inotify_rm_watch 2
.endm
/* We pre-compute the number of _instruction_ bytes needed to
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S
index ffb22a2068bf..9085838d6ce3 100644
--- a/arch/mips/kernel/scall64-64.S
+++ b/arch/mips/kernel/scall64-64.S
@@ -449,3 +449,7 @@ sys_call_table:
PTR sys_add_key
PTR sys_request_key /* 5240 */
PTR sys_keyctl
+ PTR sys_set_thread_area
+ PTR sys_inotify_init
+ PTR sys_inotify_add_watch
+ PTR sys_inotify_rm_watch /* 5245 */
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index e52049c87bc3..7e66eb823bf6 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -176,7 +176,7 @@ EXPORT(sysn32_call_table)
PTR sys_fork
PTR sys32_execve
PTR sys_exit
- PTR sys32_wait4
+ PTR compat_sys_wait4
PTR sys_kill /* 6060 */
PTR sys32_newuname
PTR sys_semget
@@ -216,7 +216,7 @@ EXPORT(sysn32_call_table)
PTR compat_sys_getrusage
PTR sys32_sysinfo
PTR compat_sys_times
- PTR sys_ptrace
+ PTR sys32_ptrace
PTR sys_getuid /* 6100 */
PTR sys_syslog
PTR sys_getgid
@@ -243,14 +243,14 @@ EXPORT(sysn32_call_table)
PTR sys_capget
PTR sys_capset
PTR sys32_rt_sigpending /* 6125 */
- PTR compat_sys_rt_sigtimedwait
- PTR sys32_rt_sigqueueinfo
+ PTR sysn32_rt_sigtimedwait
+ PTR sys_rt_sigqueueinfo
PTR sys32_rt_sigsuspend
PTR sys32_sigaltstack
PTR compat_sys_utime /* 6130 */
PTR sys_mknod
PTR sys32_personality
- PTR sys_ustat
+ PTR sys32_ustat
PTR compat_sys_statfs
PTR compat_sys_fstatfs /* 6135 */
PTR sys_sysfs
@@ -329,7 +329,7 @@ EXPORT(sysn32_call_table)
PTR sys_epoll_wait
PTR sys_remap_file_pages /* 6210 */
PTR sysn32_rt_sigreturn
- PTR sys_fcntl
+ PTR compat_sys_fcntl64
PTR sys_set_tid_address
PTR sys_restart_syscall
PTR sys_semtimedop /* 6215 */
@@ -337,15 +337,15 @@ EXPORT(sysn32_call_table)
PTR compat_sys_statfs64
PTR compat_sys_fstatfs64
PTR sys_sendfile64
- PTR sys_timer_create /* 6220 */
- PTR sys_timer_settime
- PTR sys_timer_gettime
+ PTR sys32_timer_create /* 6220 */
+ PTR compat_sys_timer_settime
+ PTR compat_sys_timer_gettime
PTR sys_timer_getoverrun
PTR sys_timer_delete
- PTR sys_clock_settime /* 6225 */
- PTR sys_clock_gettime
- PTR sys_clock_getres
- PTR sys_clock_nanosleep
+ PTR compat_sys_clock_settime /* 6225 */
+ PTR compat_sys_clock_gettime
+ PTR compat_sys_clock_getres
+ PTR compat_sys_clock_nanosleep
PTR sys_tgkill
PTR compat_sys_utimes /* 6230 */
PTR sys_ni_syscall /* sys_mbind */
@@ -358,8 +358,12 @@ EXPORT(sysn32_call_table)
PTR compat_sys_mq_notify
PTR compat_sys_mq_getsetattr
PTR sys_ni_syscall /* 6240, sys_vserver */
- PTR sys_waitid
+ PTR sysn32_waitid
PTR sys_ni_syscall /* available, was setaltroot */
PTR sys_add_key
PTR sys_request_key
PTR sys_keyctl /* 6245 */
+ PTR sys_set_thread_area
+ PTR sys_inotify_init
+ PTR sys_inotify_add_watch
+ PTR sys_inotify_rm_watch
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index 739f3998d76b..5a16401e443a 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -316,13 +316,13 @@ sys_call_table:
PTR sys_vhangup
PTR sys_ni_syscall /* was sys_idle */
PTR sys_ni_syscall /* sys_vm86 */
- PTR sys32_wait4
+ PTR compat_sys_wait4
PTR sys_swapoff /* 4115 */
PTR sys32_sysinfo
PTR sys32_ipc
PTR sys_fsync
PTR sys32_sigreturn
- PTR sys_clone /* 4120 */
+ PTR sys32_clone /* 4120 */
PTR sys_setdomainname
PTR sys32_newuname
PTR sys_ni_syscall /* sys_modify_ldt */
@@ -391,7 +391,7 @@ sys_call_table:
PTR sys_getresuid
PTR sys_ni_syscall /* was query_module */
PTR sys_poll
- PTR sys_nfsservctl
+ PTR compat_sys_nfsservctl
PTR sys_setresgid /* 4190 */
PTR sys_getresgid
PTR sys_prctl
@@ -459,7 +459,7 @@ sys_call_table:
PTR sys_fadvise64_64
PTR compat_sys_statfs64 /* 4255 */
PTR compat_sys_fstatfs64
- PTR sys_timer_create
+ PTR sys32_timer_create
PTR compat_sys_timer_settime
PTR compat_sys_timer_gettime
PTR sys_timer_getoverrun /* 4260 */
@@ -480,9 +480,13 @@ sys_call_table:
PTR compat_sys_mq_notify /* 4275 */
PTR compat_sys_mq_getsetattr
PTR sys_ni_syscall /* sys_vserver */
- PTR sys_waitid
+ PTR sys32_waitid
PTR sys_ni_syscall /* available, was setaltroot */
PTR sys_add_key /* 4280 */
PTR sys_request_key
PTR sys_keyctl
+ PTR sys_set_thread_area
+ PTR sys_inotify_init
+ PTR sys_inotify_add_watch /* 4285 */
+ PTR sys_inotify_rm_watch
.size sys_call_table,.-sys_call_table
diff --git a/arch/mips/kernel/semaphore.c b/arch/mips/kernel/semaphore.c
index 9c40fe5a8e8d..1265358cdca1 100644
--- a/arch/mips/kernel/semaphore.c
+++ b/arch/mips/kernel/semaphore.c
@@ -42,24 +42,28 @@ static inline int __sem_update_count(struct semaphore *sem, int incr)
if (cpu_has_llsc && R10000_LLSC_WAR) {
__asm__ __volatile__(
- "1: ll %0, %2 \n"
+ " .set mips3 \n"
+ "1: ll %0, %2 # __sem_update_count \n"
" sra %1, %0, 31 \n"
" not %1 \n"
" and %1, %0, %1 \n"
- " add %1, %1, %3 \n"
+ " addu %1, %1, %3 \n"
" sc %1, %2 \n"
" beqzl %1, 1b \n"
+ " .set mips0 \n"
: "=&r" (old_count), "=&r" (tmp), "=m" (sem->count)
: "r" (incr), "m" (sem->count));
} else if (cpu_has_llsc) {
__asm__ __volatile__(
- "1: ll %0, %2 \n"
+ " .set mips3 \n"
+ "1: ll %0, %2 # __sem_update_count \n"
" sra %1, %0, 31 \n"
" not %1 \n"
" and %1, %0, %1 \n"
- " add %1, %1, %3 \n"
+ " addu %1, %1, %3 \n"
" sc %1, %2 \n"
" beqz %1, 1b \n"
+ " .set mips0 \n"
: "=&r" (old_count), "=&r" (tmp), "=m" (sem->count)
: "r" (incr), "m" (sem->count));
} else {
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 12b531c295c4..d86affa21278 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -37,12 +37,13 @@
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
+#include <asm/cache.h>
#include <asm/cpu.h>
#include <asm/sections.h>
#include <asm/setup.h>
#include <asm/system.h>
-struct cpuinfo_mips cpu_data[NR_CPUS];
+struct cpuinfo_mips cpu_data[NR_CPUS] __read_mostly;
EXPORT_SYMBOL(cpu_data);
@@ -62,8 +63,8 @@ EXPORT_SYMBOL(PCI_DMA_BUS_IS_PHYS);
*
* These are initialized so they are in the .data section
*/
-unsigned long mips_machtype = MACH_UNKNOWN;
-unsigned long mips_machgroup = MACH_GROUP_UNKNOWN;
+unsigned long mips_machtype __read_mostly = MACH_UNKNOWN;
+unsigned long mips_machgroup __read_mostly = MACH_GROUP_UNKNOWN;
EXPORT_SYMBOL(mips_machtype);
EXPORT_SYMBOL(mips_machgroup);
@@ -77,7 +78,7 @@ static char command_line[CL_SIZE];
* mips_io_port_base is the begin of the address space to which x86 style
* I/O ports are mapped.
*/
-const unsigned long mips_io_port_base = -1;
+const unsigned long mips_io_port_base __read_mostly = -1;
EXPORT_SYMBOL(mips_io_port_base);
/*
@@ -510,31 +511,7 @@ static inline void resource_init(void)
#undef MAXMEM
#undef MAXMEM_PFN
-static int __initdata earlyinit_debug;
-
-static int __init earlyinit_debug_setup(char *str)
-{
- earlyinit_debug = 1;
- return 1;
-}
-__setup("earlyinit_debug", earlyinit_debug_setup);
-
-extern initcall_t __earlyinitcall_start, __earlyinitcall_end;
-
-static void __init do_earlyinitcalls(void)
-{
- initcall_t *call, *start, *end;
-
- start = &__earlyinitcall_start;
- end = &__earlyinitcall_end;
-
- for (call = start; call < end; call++) {
- if (earlyinit_debug)
- printk("calling earlyinitcall 0x%p\n", *call);
-
- (*call)();
- }
-}
+extern void plat_setup(void);
void __init setup_arch(char **cmdline_p)
{
@@ -551,7 +528,7 @@ void __init setup_arch(char **cmdline_p)
#endif
/* call board setup routine */
- do_earlyinitcalls();
+ plat_setup();
strlcpy(command_line, arcs_cmdline, sizeof(command_line));
strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
@@ -573,3 +550,12 @@ int __init fpu_disable(char *s)
}
__setup("nofpu", fpu_disable);
+
+int __init dsp_disable(char *s)
+{
+ cpu_data[0].ases &= ~MIPS_ASE_DSP;
+
+ return 1;
+}
+
+__setup("nodsp", dsp_disable);
diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h
index f9234df53253..0f66ae5838b9 100644
--- a/arch/mips/kernel/signal-common.h
+++ b/arch/mips/kernel/signal-common.h
@@ -8,13 +8,14 @@
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
*/
+#include <linux/config.h>
+
static inline int
setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
{
int err = 0;
err |= __put_user(regs->cp0_epc, &sc->sc_pc);
- err |= __put_user(regs->cp0_status, &sc->sc_status);
#define save_gp_reg(i) do { \
err |= __put_user(regs->regs[i], &sc->sc_regs[i]); \
@@ -30,10 +31,32 @@ setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
save_gp_reg(31);
#undef save_gp_reg
+#ifdef CONFIG_32BIT
err |= __put_user(regs->hi, &sc->sc_mdhi);
err |= __put_user(regs->lo, &sc->sc_mdlo);
- err |= __put_user(regs->cp0_cause, &sc->sc_cause);
- err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
+ if (cpu_has_dsp) {
+ err |= __put_user(mfhi1(), &sc->sc_hi1);
+ err |= __put_user(mflo1(), &sc->sc_lo1);
+ err |= __put_user(mfhi2(), &sc->sc_hi2);
+ err |= __put_user(mflo2(), &sc->sc_lo2);
+ err |= __put_user(mfhi3(), &sc->sc_hi3);
+ err |= __put_user(mflo3(), &sc->sc_lo3);
+ err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
+ }
+#endif
+#ifdef CONFIG_64BIT
+ err |= __put_user(regs->hi, &sc->sc_hi[0]);
+ err |= __put_user(regs->lo, &sc->sc_lo[0]);
+ if (cpu_has_dsp) {
+ err |= __put_user(mfhi1(), &sc->sc_hi[1]);
+ err |= __put_user(mflo1(), &sc->sc_lo[1]);
+ err |= __put_user(mfhi2(), &sc->sc_hi[2]);
+ err |= __put_user(mflo2(), &sc->sc_lo[2]);
+ err |= __put_user(mfhi3(), &sc->sc_hi[3]);
+ err |= __put_user(mflo3(), &sc->sc_lo[3]);
+ err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
+ }
+#endif
err |= __put_user(!!used_math(), &sc->sc_used_math);
@@ -61,15 +84,40 @@ out:
static inline int
restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
{
- int err = 0;
unsigned int used_math;
+ unsigned long treg;
+ int err = 0;
/* Always make any pending restarted system calls return -EINTR */
current_thread_info()->restart_block.fn = do_no_restart_syscall;
err |= __get_user(regs->cp0_epc, &sc->sc_pc);
+#ifdef CONFIG_32BIT
err |= __get_user(regs->hi, &sc->sc_mdhi);
err |= __get_user(regs->lo, &sc->sc_mdlo);
+ if (cpu_has_dsp) {
+ err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
+ err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
+ err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
+ err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
+ err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
+ err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
+ err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
+ }
+#endif
+#ifdef CONFIG_64BIT
+ err |= __get_user(regs->hi, &sc->sc_hi[0]);
+ err |= __get_user(regs->lo, &sc->sc_lo[0]);
+ if (cpu_has_dsp) {
+ err |= __get_user(treg, &sc->sc_hi[1]); mthi1(treg);
+ err |= __get_user(treg, &sc->sc_lo[1]); mthi1(treg);
+ err |= __get_user(treg, &sc->sc_hi[2]); mthi2(treg);
+ err |= __get_user(treg, &sc->sc_lo[2]); mthi2(treg);
+ err |= __get_user(treg, &sc->sc_hi[3]); mthi3(treg);
+ err |= __get_user(treg, &sc->sc_lo[3]); mthi3(treg);
+ err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
+ }
+#endif
#define restore_gp_reg(i) do { \
err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \
@@ -112,7 +160,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
static inline void *
get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
{
- unsigned long sp, almask;
+ unsigned long sp;
/* Default to using normal stack */
sp = regs->regs[29];
@@ -128,10 +176,32 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
sp = current->sas_ss_sp + current->sas_ss_size;
- if (PLAT_TRAMPOLINE_STUFF_LINE)
- almask = ~(PLAT_TRAMPOLINE_STUFF_LINE - 1);
- else
- almask = ALMASK;
+ return (void *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? 32 : ALMASK));
+}
+
+static inline int install_sigtramp(unsigned int __user *tramp,
+ unsigned int syscall)
+{
+ int err;
+
+ /*
+ * Set up the return code ...
+ *
+ * li v0, __NR__foo_sigreturn
+ * syscall
+ */
+
+ err = __put_user(0x24020000 + syscall, tramp + 0);
+ err |= __put_user(0x0000000c , tramp + 1);
+ if (ICACHE_REFILLS_WORKAROUND_WAR) {
+ err |= __put_user(0, tramp + 2);
+ err |= __put_user(0, tramp + 3);
+ err |= __put_user(0, tramp + 4);
+ err |= __put_user(0, tramp + 5);
+ err |= __put_user(0, tramp + 6);
+ err |= __put_user(0, tramp + 7);
+ }
+ flush_cache_sigtramp((unsigned long) tramp);
- return (void *)((sp - frame_size) & almask);
+ return err;
}
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 0209c1dd1429..9202a17db8f7 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -8,6 +8,7 @@
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
*/
#include <linux/config.h>
+#include <linux/cache.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/personality.h>
@@ -21,6 +22,7 @@
#include <linux/unistd.h>
#include <linux/compiler.h>
+#include <asm/abi.h>
#include <asm/asm.h>
#include <linux/bitops.h>
#include <asm/cacheflush.h>
@@ -29,6 +31,7 @@
#include <asm/uaccess.h>
#include <asm/ucontext.h>
#include <asm/cpu-features.h>
+#include <asm/war.h>
#include "signal-common.h"
@@ -36,7 +39,7 @@
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
-static int do_signal(sigset_t *oldset, struct pt_regs *regs);
+int do_signal(sigset_t *oldset, struct pt_regs *regs);
/*
* Atomically swap in the new signal mask, and wait for a signal.
@@ -47,9 +50,10 @@ save_static_function(sys_sigsuspend);
__attribute_used__ noinline static int
_sys_sigsuspend(nabi_no_regargs struct pt_regs regs)
{
- sigset_t *uset, saveset, newset;
+ sigset_t saveset, newset;
+ sigset_t __user *uset;
- uset = (sigset_t *) regs.regs[4];
+ uset = (sigset_t __user *) regs.regs[4];
if (copy_from_user(&newset, uset, sizeof(sigset_t)))
return -EFAULT;
sigdelsetmask(&newset, ~_BLOCKABLE);
@@ -75,7 +79,8 @@ save_static_function(sys_rt_sigsuspend);
__attribute_used__ noinline static int
_sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
{
- sigset_t *unewset, saveset, newset;
+ sigset_t saveset, newset;
+ sigset_t __user *unewset;
size_t sigsetsize;
/* XXX Don't preclude handling different sized sigset_t's. */
@@ -83,7 +88,7 @@ _sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
if (sigsetsize != sizeof(sigset_t))
return -EINVAL;
- unewset = (sigset_t *) regs.regs[4];
+ unewset = (sigset_t __user *) regs.regs[4];
if (copy_from_user(&newset, unewset, sizeof(newset)))
return -EFAULT;
sigdelsetmask(&newset, ~_BLOCKABLE);
@@ -147,33 +152,46 @@ asmlinkage int sys_sigaction(int sig, const struct sigaction *act,
asmlinkage int sys_sigaltstack(nabi_no_regargs struct pt_regs regs)
{
- const stack_t *uss = (const stack_t *) regs.regs[4];
- stack_t *uoss = (stack_t *) regs.regs[5];
+ const stack_t __user *uss = (const stack_t __user *) regs.regs[4];
+ stack_t __user *uoss = (stack_t __user *) regs.regs[5];
unsigned long usp = regs.regs[29];
return do_sigaltstack(uss, uoss, usp);
}
-#if PLAT_TRAMPOLINE_STUFF_LINE
-#define __tramp __attribute__((aligned(PLAT_TRAMPOLINE_STUFF_LINE)))
-#else
-#define __tramp
-#endif
-
+/*
+ * Horribly complicated - with the bloody RM9000 workarounds enabled
+ * the signal trampolines is moving to the end of the structure so we can
+ * increase the alignment without breaking software compatibility.
+ */
#ifdef CONFIG_TRAD_SIGNALS
struct sigframe {
u32 sf_ass[4]; /* argument save space for o32 */
- u32 sf_code[2] __tramp; /* signal trampoline */
- struct sigcontext sf_sc __tramp;
+#if ICACHE_REFILLS_WORKAROUND_WAR
+ u32 sf_pad[2];
+#else
+ u32 sf_code[2]; /* signal trampoline */
+#endif
+ struct sigcontext sf_sc;
sigset_t sf_mask;
+#if ICACHE_REFILLS_WORKAROUND_WAR
+ u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */
+#endif
};
#endif
struct rt_sigframe {
u32 rs_ass[4]; /* argument save space for o32 */
- u32 rs_code[2] __tramp; /* signal trampoline */
- struct siginfo rs_info __tramp;
+#if ICACHE_REFILLS_WORKAROUND_WAR
+ u32 rs_pad[2];
+#else
+ u32 rs_code[2]; /* signal trampoline */
+#endif
+ struct siginfo rs_info;
struct ucontext rs_uc;
+#if ICACHE_REFILLS_WORKAROUND_WAR
+ u32 rs_code[8] ____cacheline_aligned; /* signal trampoline */
+#endif
};
#ifdef CONFIG_TRAD_SIGNALS
@@ -214,7 +232,7 @@ _sys_sigreturn(nabi_no_regargs struct pt_regs regs)
badframe:
force_sig(SIGSEGV, current);
}
-#endif
+#endif /* CONFIG_TRAD_SIGNALS */
save_static_function(sys_rt_sigreturn);
__attribute_used__ noinline static void
@@ -260,7 +278,7 @@ badframe:
}
#ifdef CONFIG_TRAD_SIGNALS
-static void inline setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
+int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
int signr, sigset_t *set)
{
struct sigframe *frame;
@@ -270,17 +288,7 @@ static void inline setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
goto give_sigsegv;
- /*
- * Set up the return code ...
- *
- * li v0, __NR_sigreturn
- * syscall
- */
- if (PLAT_TRAMPOLINE_STUFF_LINE)
- __clear_user(frame->sf_code, PLAT_TRAMPOLINE_STUFF_LINE);
- err |= __put_user(0x24020000 + __NR_sigreturn, frame->sf_code + 0);
- err |= __put_user(0x0000000c , frame->sf_code + 1);
- flush_cache_sigtramp((unsigned long) frame->sf_code);
+ install_sigtramp(frame->sf_code, __NR_sigreturn);
err |= setup_sigcontext(regs, &frame->sf_sc);
err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
@@ -309,14 +317,15 @@ static void inline setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
current->comm, current->pid,
frame, regs->cp0_epc, frame->regs[31]);
#endif
- return;
+ return 1;
give_sigsegv:
force_sigsegv(signr, current);
+ return 0;
}
#endif
-static void inline setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
+int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
int signr, sigset_t *set, siginfo_t *info)
{
struct rt_sigframe *frame;
@@ -326,17 +335,7 @@ static void inline setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
goto give_sigsegv;
- /*
- * Set up the return code ...
- *
- * li v0, __NR_rt_sigreturn
- * syscall
- */
- if (PLAT_TRAMPOLINE_STUFF_LINE)
- __clear_user(frame->rs_code, PLAT_TRAMPOLINE_STUFF_LINE);
- err |= __put_user(0x24020000 + __NR_rt_sigreturn, frame->rs_code + 0);
- err |= __put_user(0x0000000c , frame->rs_code + 1);
- flush_cache_sigtramp((unsigned long) frame->rs_code);
+ install_sigtramp(frame->rs_code, __NR_rt_sigreturn);
/* Create siginfo. */
err |= copy_siginfo_to_user(&frame->rs_info, info);
@@ -378,18 +377,21 @@ static void inline setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
current->comm, current->pid,
frame, regs->cp0_epc, regs->regs[31]);
#endif
- return;
+ return 1;
give_sigsegv:
force_sigsegv(signr, current);
+ return 0;
}
extern void setup_rt_frame_n32(struct k_sigaction * ka,
struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info);
-static inline void handle_signal(unsigned long sig, siginfo_t *info,
+static inline int handle_signal(unsigned long sig, siginfo_t *info,
struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
{
+ int ret;
+
switch(regs->regs[0]) {
case ERESTART_RESTARTBLOCK:
case ERESTARTNOHAND:
@@ -408,22 +410,10 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info,
regs->regs[0] = 0; /* Don't deal with this again. */
-#ifdef CONFIG_TRAD_SIGNALS
- if (ka->sa.sa_flags & SA_SIGINFO) {
-#else
- if (1) {
-#endif
-#ifdef CONFIG_MIPS32_N32
- if ((current->thread.mflags & MF_ABI_MASK) == MF_N32)
- setup_rt_frame_n32 (ka, regs, sig, oldset, info);
- else
-#endif
- setup_rt_frame(ka, regs, sig, oldset, info);
- }
-#ifdef CONFIG_TRAD_SIGNALS
+ if (sig_uses_siginfo(ka))
+ ret = current->thread.abi->setup_rt_frame(ka, regs, sig, oldset, info);
else
- setup_frame(ka, regs, sig, oldset);
-#endif
+ ret = current->thread.abi->setup_frame(ka, regs, sig, oldset);
spin_lock_irq(&current->sighand->siglock);
sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
@@ -431,23 +421,16 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info,
sigaddset(&current->blocked,sig);
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
-}
-extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
-extern int do_irix_signal(sigset_t *oldset, struct pt_regs *regs);
+ return ret;
+}
-static int do_signal(sigset_t *oldset, struct pt_regs *regs)
+int do_signal(sigset_t *oldset, struct pt_regs *regs)
{
struct k_sigaction ka;
siginfo_t info;
int signr;
-#ifdef CONFIG_BINFMT_ELF32
- if ((current->thread.mflags & MF_ABI_MASK) == MF_O32) {
- return do_signal32(oldset, regs);
- }
-#endif
-
/*
* We want the common case to go fast, which is why we may in certain
* cases get here from kernel mode. Just return without doing anything
@@ -463,10 +446,8 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs)
oldset = &current->blocked;
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
- if (signr > 0) {
- handle_signal(signr, &info, &ka, oldset, regs);
- return 1;
- }
+ if (signr > 0)
+ return handle_signal(signr, &info, &ka, oldset, regs);
no_signal:
/*
@@ -499,18 +480,6 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, sigset_t *oldset,
{
/* deal with pending signal delivery */
if (thread_info_flags & _TIF_SIGPENDING) {
-#ifdef CONFIG_BINFMT_ELF32
- if (likely((current->thread.mflags & MF_ABI_MASK) == MF_O32)) {
- do_signal32(oldset, regs);
- return;
- }
-#endif
-#ifdef CONFIG_BINFMT_IRIX
- if (unlikely(current->personality != PER_LINUX)) {
- do_irix_signal(oldset, regs);
- return;
- }
-#endif
- do_signal(oldset, regs);
+ current->thread.abi->do_signal(oldset, regs);
}
}
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index 8ddfbd8d425a..dbe821303125 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -7,6 +7,7 @@
* Copyright (C) 1994 - 2000 Ralf Baechle
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
*/
+#include <linux/cache.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
@@ -21,6 +22,7 @@
#include <linux/suspend.h>
#include <linux/compiler.h>
+#include <asm/abi.h>
#include <asm/asm.h>
#include <linux/bitops.h>
#include <asm/cacheflush.h>
@@ -29,6 +31,7 @@
#include <asm/ucontext.h>
#include <asm/system.h>
#include <asm/fpu.h>
+#include <asm/war.h>
#define SI_PAD_SIZE32 ((SI_MAX_SIZE/sizeof(int)) - 3)
@@ -76,8 +79,10 @@ typedef struct compat_siginfo {
/* POSIX.1b timers */
struct {
- unsigned int _timer1;
- unsigned int _timer2;
+ timer_t _tid; /* timer id */
+ int _overrun; /* overrun count */
+ compat_sigval_t _sigval;/* same as below */
+ int _sys_private; /* not to be passed to user */
} _timer;
/* POSIX.1b signals */
@@ -259,11 +264,12 @@ asmlinkage int sys32_sigaction(int sig, const struct sigaction32 *act,
if (act) {
old_sigset_t mask;
+ s32 handler;
if (!access_ok(VERIFY_READ, act, sizeof(*act)))
return -EFAULT;
- err |= __get_user((u32)(u64)new_ka.sa.sa_handler,
- &act->sa_handler);
+ err |= __get_user(handler, &act->sa_handler);
+ new_ka.sa.sa_handler = (void*)(s64)handler;
err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
err |= __get_user(mask, &act->sa_mask.sig[0]);
if (err)
@@ -331,8 +337,9 @@ asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs)
static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 *sc)
{
+ u32 used_math;
int err = 0;
- __u32 used_math;
+ s32 treg;
/* Always make any pending restarted system calls return -EINTR */
current_thread_info()->restart_block.fn = do_no_restart_syscall;
@@ -340,6 +347,15 @@ static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 *sc)
err |= __get_user(regs->cp0_epc, &sc->sc_pc);
err |= __get_user(regs->hi, &sc->sc_mdhi);
err |= __get_user(regs->lo, &sc->sc_mdlo);
+ if (cpu_has_dsp) {
+ err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
+ err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
+ err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
+ err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
+ err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
+ err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
+ err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
+ }
#define restore_gp_reg(i) do { \
err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \
@@ -378,16 +394,30 @@ static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 *sc)
struct sigframe {
u32 sf_ass[4]; /* argument save space for o32 */
+#if ICACHE_REFILLS_WORKAROUND_WAR
+ u32 sf_pad[2];
+#else
u32 sf_code[2]; /* signal trampoline */
+#endif
struct sigcontext32 sf_sc;
sigset_t sf_mask;
+#if ICACHE_REFILLS_WORKAROUND_WAR
+ u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */
+#endif
};
struct rt_sigframe32 {
u32 rs_ass[4]; /* argument save space for o32 */
+#if ICACHE_REFILLS_WORKAROUND_WAR
+ u32 rs_pad[2];
+#else
u32 rs_code[2]; /* signal trampoline */
+#endif
compat_siginfo_t rs_info;
struct ucontext32 rs_uc;
+#if ICACHE_REFILLS_WORKAROUND_WAR
+ u32 rs_code[8] __attribute__((aligned(32))); /* signal trampoline */
+#endif
};
int copy_siginfo_to_user32(compat_siginfo_t *to, siginfo_t *from)
@@ -411,6 +441,11 @@ int copy_siginfo_to_user32(compat_siginfo_t *to, siginfo_t *from)
err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
else {
switch (from->si_code >> 16) {
+ case __SI_TIMER >> 16:
+ err |= __put_user(from->si_tid, &to->si_tid);
+ err |= __put_user(from->si_overrun, &to->si_overrun);
+ err |= __put_user(from->si_int, &to->si_int);
+ break;
case __SI_CHLD >> 16:
err |= __put_user(from->si_utime, &to->si_utime);
err |= __put_user(from->si_stime, &to->si_stime);
@@ -480,6 +515,7 @@ __attribute_used__ noinline static void
_sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
{
struct rt_sigframe32 *frame;
+ mm_segment_t old_fs;
sigset_t set;
stack_t st;
s32 sp;
@@ -510,7 +546,10 @@ _sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
/* It is more difficult to avoid calling this function than to
call it and ignore errors. */
+ old_fs = get_fs();
+ set_fs (KERNEL_DS);
do_sigaltstack(&st, NULL, regs.regs[29]);
+ set_fs (old_fs);
/*
* Don't let your children do this ...
@@ -550,8 +589,15 @@ static inline int setup_sigcontext32(struct pt_regs *regs,
err |= __put_user(regs->hi, &sc->sc_mdhi);
err |= __put_user(regs->lo, &sc->sc_mdlo);
- err |= __put_user(regs->cp0_cause, &sc->sc_cause);
- err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
+ if (cpu_has_dsp) {
+ err |= __put_user(rddsp(DSP_MASK), &sc->sc_hi1);
+ err |= __put_user(mfhi1(), &sc->sc_hi1);
+ err |= __put_user(mflo1(), &sc->sc_lo1);
+ err |= __put_user(mfhi2(), &sc->sc_hi2);
+ err |= __put_user(mflo2(), &sc->sc_lo2);
+ err |= __put_user(mfhi3(), &sc->sc_hi3);
+ err |= __put_user(mflo3(), &sc->sc_lo3);
+ }
err |= __put_user(!!used_math(), &sc->sc_used_math);
@@ -601,7 +647,7 @@ static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
return (void *)((sp - frame_size) & ALMASK);
}
-static inline void setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
+void setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
int signr, sigset_t *set)
{
struct sigframe *frame;
@@ -654,9 +700,7 @@ give_sigsegv:
force_sigsegv(signr, current);
}
-static inline void setup_rt_frame(struct k_sigaction * ka,
- struct pt_regs *regs, int signr,
- sigset_t *set, siginfo_t *info)
+void setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
{
struct rt_sigframe32 *frame;
int err = 0;
@@ -725,9 +769,11 @@ give_sigsegv:
force_sigsegv(signr, current);
}
-static inline void handle_signal(unsigned long sig, siginfo_t *info,
+static inline int handle_signal(unsigned long sig, siginfo_t *info,
struct k_sigaction *ka, sigset_t *oldset, struct pt_regs * regs)
{
+ int ret;
+
switch (regs->regs[0]) {
case ERESTART_RESTARTBLOCK:
case ERESTARTNOHAND:
@@ -747,9 +793,9 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info,
regs->regs[0] = 0; /* Don't deal with this again. */
if (ka->sa.sa_flags & SA_SIGINFO)
- setup_rt_frame(ka, regs, sig, oldset, info);
+ ret = current->thread.abi->setup_rt_frame(ka, regs, sig, oldset, info);
else
- setup_frame(ka, regs, sig, oldset);
+ ret = current->thread.abi->setup_frame(ka, regs, sig, oldset);
spin_lock_irq(&current->sighand->siglock);
sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
@@ -757,6 +803,8 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info,
sigaddset(&current->blocked,sig);
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
+
+ return ret;
}
int do_signal32(sigset_t *oldset, struct pt_regs *regs)
@@ -780,10 +828,8 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs)
oldset = &current->blocked;
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
- if (signr > 0) {
- handle_signal(signr, &info, &ka, oldset, regs);
- return 1;
- }
+ if (signr > 0)
+ return handle_signal(signr, &info, &ka, oldset, regs);
no_signal:
/*
@@ -819,12 +865,13 @@ asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 *act,
goto out;
if (act) {
+ s32 handler;
int err = 0;
if (!access_ok(VERIFY_READ, act, sizeof(*act)))
return -EFAULT;
- err |= __get_user((u32)(u64)new_sa.sa.sa_handler,
- &act->sa_handler);
+ err |= __get_user(handler, &act->sa_handler);
+ new_sa.sa.sa_handler = (void*)(s64)handler;
err |= __get_user(new_sa.sa.sa_flags, &act->sa_flags);
err |= get_sigset(&new_sa.sa.sa_mask, &act->sa_mask);
if (err)
@@ -902,3 +949,30 @@ asmlinkage int sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t *uinfo)
set_fs (old_fs);
return ret;
}
+
+asmlinkage long
+sys32_waitid(int which, compat_pid_t pid,
+ compat_siginfo_t __user *uinfo, int options,
+ struct compat_rusage __user *uru)
+{
+ siginfo_t info;
+ struct rusage ru;
+ long ret;
+ mm_segment_t old_fs = get_fs();
+
+ info.si_signo = 0;
+ set_fs (KERNEL_DS);
+ ret = sys_waitid(which, pid, (siginfo_t __user *) &info, options,
+ uru ? (struct rusage __user *) &ru : NULL);
+ set_fs (old_fs);
+
+ if (ret < 0 || info.si_signo == 0)
+ return ret;
+
+ if (uru && (ret = put_compat_rusage(&ru, uru)))
+ return ret;
+
+ BUG_ON(info.si_code & __SI_MASK);
+ info.si_code |= __SI_CHLD;
+ return copy_siginfo_to_user32(uinfo, &info);
+}
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
index 3544208d4b4b..ec61b2670ba6 100644
--- a/arch/mips/kernel/signal_n32.c
+++ b/arch/mips/kernel/signal_n32.c
@@ -15,6 +15,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
+#include <linux/cache.h>
+#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
@@ -36,6 +38,7 @@
#include <asm/system.h>
#include <asm/fpu.h>
#include <asm/cpu-features.h>
+#include <asm/war.h>
#include "signal-common.h"
@@ -62,17 +65,18 @@ struct ucontextn32 {
sigset_t uc_sigmask; /* mask last for extensibility */
};
-#if PLAT_TRAMPOLINE_STUFF_LINE
-#define __tramp __attribute__((aligned(PLAT_TRAMPOLINE_STUFF_LINE)))
-#else
-#define __tramp
-#endif
-
struct rt_sigframe_n32 {
u32 rs_ass[4]; /* argument save space for o32 */
- u32 rs_code[2] __tramp; /* signal trampoline */
- struct siginfo rs_info __tramp;
+#if ICACHE_REFILLS_WORKAROUND_WAR
+ u32 rs_pad[2];
+#else
+ u32 rs_code[2]; /* signal trampoline */
+#endif
+ struct siginfo rs_info;
struct ucontextn32 rs_uc;
+#if ICACHE_REFILLS_WORKAROUND_WAR
+ u32 rs_code[8] ____cacheline_aligned; /* signal trampoline */
+#endif
};
save_static_function(sysn32_rt_sigreturn);
@@ -126,7 +130,7 @@ badframe:
force_sig(SIGSEGV, current);
}
-void setup_rt_frame_n32(struct k_sigaction * ka,
+int setup_rt_frame_n32(struct k_sigaction * ka,
struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
{
struct rt_sigframe_n32 *frame;
@@ -137,17 +141,7 @@ void setup_rt_frame_n32(struct k_sigaction * ka,
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
goto give_sigsegv;
- /*
- * Set up the return code ...
- *
- * li v0, __NR_rt_sigreturn
- * syscall
- */
- if (PLAT_TRAMPOLINE_STUFF_LINE)
- __clear_user(frame->rs_code, PLAT_TRAMPOLINE_STUFF_LINE);
- err |= __put_user(0x24020000 + __NR_N32_rt_sigreturn, frame->rs_code + 0);
- err |= __put_user(0x0000000c , frame->rs_code + 1);
- flush_cache_sigtramp((unsigned long) frame->rs_code);
+ install_sigtramp(frame->rs_code, __NR_N32_rt_sigreturn);
/* Create siginfo. */
err |= copy_siginfo_to_user(&frame->rs_info, info);
@@ -190,8 +184,9 @@ void setup_rt_frame_n32(struct k_sigaction * ka,
current->comm, current->pid,
frame, regs->cp0_epc, regs->regs[31]);
#endif
- return;
+ return 1;
give_sigsegv:
force_sigsegv(signr, current);
+ return 0;
}
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index af5cd3b8a396..fcacf1aae98a 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -50,7 +50,6 @@ static void smp_tune_scheduling (void)
{
struct cache_desc *cd = &current_cpu_data.scache;
unsigned long cachesize; /* kB */
- unsigned long bandwidth = 350; /* MB/s */
unsigned long cpu_khz;
/*
@@ -121,7 +120,19 @@ struct call_data_struct *call_data;
* or are or have executed.
*
* You must not call this function with disabled interrupts or from a
- * hardware interrupt handler or from a bottom half handler.
+ * hardware interrupt handler or from a bottom half handler:
+ *
+ * CPU A CPU B
+ * Disable interrupts
+ * smp_call_function()
+ * Take call_lock
+ * Send IPIs
+ * Wait for all cpus to acknowledge IPI
+ * CPU A has not responded, spin waiting
+ * for cpu A to respond, holding call_lock
+ * smp_call_function()
+ * Spin waiting for call_lock
+ * Deadlock Deadlock
*/
int smp_call_function (void (*func) (void *info), void *info, int retry,
int wait)
@@ -130,6 +141,11 @@ int smp_call_function (void (*func) (void *info), void *info, int retry,
int i, cpus = num_online_cpus() - 1;
int cpu = smp_processor_id();
+ /*
+ * Can die spectacularly if this CPU isn't yet marked online
+ */
+ BUG_ON(!cpu_online(cpu));
+
if (!cpus)
return 0;
@@ -214,7 +230,6 @@ void __init smp_cpus_done(unsigned int max_cpus)
/* called from main before smp_init() */
void __init smp_prepare_cpus(unsigned int max_cpus)
{
- cpu_data[0].udelay_val = loops_per_jiffy;
init_new_context(current, &init_mm);
current_thread_info()->cpu = 0;
smp_tune_scheduling();
@@ -236,23 +251,28 @@ void __devinit smp_prepare_boot_cpu(void)
}
/*
- * Startup the CPU with this logical number
+ * Called once for each "cpu_possible(cpu)". Needs to spin up the cpu
+ * and keep control until "cpu_online(cpu)" is set. Note: cpu is
+ * physical, not logical.
*/
-static int __init do_boot_cpu(int cpu)
+int __devinit __cpu_up(unsigned int cpu)
{
struct task_struct *idle;
/*
+ * Processor goes to start_secondary(), sets online flag
* The following code is purely to make sure
* Linux can schedule processes on this slave.
*/
idle = fork_idle(cpu);
if (IS_ERR(idle))
- panic("failed fork for CPU %d\n", cpu);
+ panic(KERN_ERR "Fork failed for CPU %d", cpu);
prom_boot_secondary(cpu, idle);
- /* XXXKW timeout */
+ /*
+ * Trust is futile. We should really have timeouts ...
+ */
while (!cpu_isset(cpu, cpu_callin_map))
udelay(100);
@@ -261,23 +281,6 @@ static int __init do_boot_cpu(int cpu)
return 0;
}
-/*
- * Called once for each "cpu_possible(cpu)". Needs to spin up the cpu
- * and keep control until "cpu_online(cpu)" is set. Note: cpu is
- * physical, not logical.
- */
-int __devinit __cpu_up(unsigned int cpu)
-{
- int ret;
-
- /* Processor goes to start_secondary(), sets online flag */
- ret = do_boot_cpu(cpu);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
/* Not really SMP stuff ... */
int setup_profiling_timer(unsigned int multiplier)
{
diff --git a/arch/mips/kernel/smp_mt.c b/arch/mips/kernel/smp_mt.c
new file mode 100644
index 000000000000..d429544ba4bc
--- /dev/null
+++ b/arch/mips/kernel/smp_mt.c
@@ -0,0 +1,366 @@
+/*
+ * Copyright (C) 2004, 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * Elizabeth Clarke (beth@mips.com)
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/cpumask.h>
+#include <linux/interrupt.h>
+#include <linux/compiler.h>
+
+#include <asm/atomic.h>
+#include <asm/cpu.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/hardirq.h>
+#include <asm/mmu_context.h>
+#include <asm/smp.h>
+#include <asm/time.h>
+#include <asm/mipsregs.h>
+#include <asm/mipsmtregs.h>
+#include <asm/cacheflush.h>
+#include <asm/mips-boards/maltaint.h>
+
+#define MIPS_CPU_IPI_RESCHED_IRQ 0
+#define MIPS_CPU_IPI_CALL_IRQ 1
+
+static int cpu_ipi_resched_irq, cpu_ipi_call_irq;
+
+#if 0
+static void dump_mtregisters(int vpe, int tc)
+{
+ printk("vpe %d tc %d\n", vpe, tc);
+
+ settc(tc);
+
+ printk(" c0 status 0x%lx\n", read_vpe_c0_status());
+ printk(" vpecontrol 0x%lx\n", read_vpe_c0_vpecontrol());
+ printk(" vpeconf0 0x%lx\n", read_vpe_c0_vpeconf0());
+ printk(" tcstatus 0x%lx\n", read_tc_c0_tcstatus());
+ printk(" tcrestart 0x%lx\n", read_tc_c0_tcrestart());
+ printk(" tcbind 0x%lx\n", read_tc_c0_tcbind());
+ printk(" tchalt 0x%lx\n", read_tc_c0_tchalt());
+}
+#endif
+
+void __init sanitize_tlb_entries(void)
+{
+ int i, tlbsiz;
+ unsigned long mvpconf0, ncpu;
+
+ if (!cpu_has_mipsmt)
+ return;
+
+ set_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ /* Disable TLB sharing */
+ clear_c0_mvpcontrol(MVPCONTROL_STLB);
+
+ mvpconf0 = read_c0_mvpconf0();
+
+ printk(KERN_INFO "MVPConf0 0x%lx TLBS %lx PTLBE %ld\n", mvpconf0,
+ (mvpconf0 & MVPCONF0_TLBS) >> MVPCONF0_TLBS_SHIFT,
+ (mvpconf0 & MVPCONF0_PTLBE) >> MVPCONF0_PTLBE_SHIFT);
+
+ tlbsiz = (mvpconf0 & MVPCONF0_PTLBE) >> MVPCONF0_PTLBE_SHIFT;
+ ncpu = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
+
+ printk(" tlbsiz %d ncpu %ld\n", tlbsiz, ncpu);
+
+ if (tlbsiz > 0) {
+ /* share them out across the vpe's */
+ tlbsiz /= ncpu;
+
+ printk(KERN_INFO "setting Config1.MMU_size to %d\n", tlbsiz);
+
+ for (i = 0; i < ncpu; i++) {
+ settc(i);
+
+ if (i == 0)
+ write_c0_config1((read_c0_config1() & ~(0x3f << 25)) | (tlbsiz << 25));
+ else
+ write_vpe_c0_config1((read_vpe_c0_config1() & ~(0x3f << 25)) |
+ (tlbsiz << 25));
+ }
+ }
+
+ clear_c0_mvpcontrol(MVPCONTROL_VPC);
+}
+
+#if 0
+/*
+ * Use c0_MVPConf0 to find out how many CPUs are available, setting up
+ * phys_cpu_present_map and the logical/physical mappings.
+ */
+void __init prom_build_cpu_map(void)
+{
+ int i, num, ncpus;
+
+ cpus_clear(phys_cpu_present_map);
+
+ /* assume we boot on cpu 0.... */
+ cpu_set(0, phys_cpu_present_map);
+ __cpu_number_map[0] = 0;
+ __cpu_logical_map[0] = 0;
+
+ if (cpu_has_mipsmt) {
+ ncpus = ((read_c0_mvpconf0() & (MVPCONF0_PVPE)) >> MVPCONF0_PVPE_SHIFT) + 1;
+ for (i=1, num=0; i< NR_CPUS && i<ncpus; i++) {
+ cpu_set(i, phys_cpu_present_map);
+ __cpu_number_map[i] = ++num;
+ __cpu_logical_map[num] = i;
+ }
+
+ printk(KERN_INFO "%i available secondary CPU(s)\n", num);
+ }
+}
+#endif
+
+static void ipi_resched_dispatch (struct pt_regs *regs)
+{
+ do_IRQ(MIPS_CPU_IPI_RESCHED_IRQ, regs);
+}
+
+static void ipi_call_dispatch (struct pt_regs *regs)
+{
+ do_IRQ(MIPS_CPU_IPI_CALL_IRQ, regs);
+}
+
+irqreturn_t ipi_resched_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ return IRQ_HANDLED;
+}
+
+irqreturn_t ipi_call_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ smp_call_function_interrupt();
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction irq_resched = {
+ .handler = ipi_resched_interrupt,
+ .flags = SA_INTERRUPT,
+ .name = "IPI_resched"
+};
+
+static struct irqaction irq_call = {
+ .handler = ipi_call_interrupt,
+ .flags = SA_INTERRUPT,
+ .name = "IPI_call"
+};
+
+/*
+ * Common setup before any secondaries are started
+ * Make sure all CPU's are in a sensible state before we boot any of the
+ * secondarys
+ */
+void prom_prepare_cpus(unsigned int max_cpus)
+{
+ unsigned long val;
+ int i, num;
+
+ if (!cpu_has_mipsmt)
+ return;
+
+ /* disable MT so we can configure */
+ dvpe();
+ dmt();
+
+ /* Put MVPE's into 'configuration state' */
+ set_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ val = read_c0_mvpconf0();
+
+ /* we'll always have more TC's than VPE's, so loop setting everything
+ to a sensible state */
+ for (i = 0, num = 0; i <= ((val & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT); i++) {
+ settc(i);
+
+ /* VPE's */
+ if (i <= ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)) {
+
+ /* deactivate all but vpe0 */
+ if (i != 0) {
+ unsigned long tmp = read_vpe_c0_vpeconf0();
+
+ tmp &= ~VPECONF0_VPA;
+
+ /* master VPE */
+ tmp |= VPECONF0_MVP;
+ write_vpe_c0_vpeconf0(tmp);
+
+ /* Record this as available CPU */
+ if (i < max_cpus) {
+ cpu_set(i, phys_cpu_present_map);
+ __cpu_number_map[i] = ++num;
+ __cpu_logical_map[num] = i;
+ }
+ }
+
+ /* disable multi-threading with TC's */
+ write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE);
+
+ if (i != 0) {
+ write_vpe_c0_status((read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0);
+ write_vpe_c0_cause(read_vpe_c0_cause() & ~CAUSEF_IP);
+
+ /* set config to be the same as vpe0, particularly kseg0 coherency alg */
+ write_vpe_c0_config( read_c0_config());
+ }
+
+ }
+
+ /* TC's */
+
+ if (i != 0) {
+ unsigned long tmp;
+
+ /* bind a TC to each VPE, May as well put all excess TC's
+ on the last VPE */
+ if ( i >= (((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)+1) )
+ write_tc_c0_tcbind(read_tc_c0_tcbind() | ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) );
+ else {
+ write_tc_c0_tcbind( read_tc_c0_tcbind() | i);
+
+ /* and set XTC */
+ write_vpe_c0_vpeconf0( read_vpe_c0_vpeconf0() | (i << VPECONF0_XTC_SHIFT));
+ }
+
+ tmp = read_tc_c0_tcstatus();
+
+ /* mark not allocated and not dynamically allocatable */
+ tmp &= ~(TCSTATUS_A | TCSTATUS_DA);
+ tmp |= TCSTATUS_IXMT; /* interrupt exempt */
+ write_tc_c0_tcstatus(tmp);
+
+ write_tc_c0_tchalt(TCHALT_H);
+ }
+ }
+
+ /* Release config state */
+ clear_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ /* We'll wait until starting the secondaries before starting MVPE */
+
+ printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num);
+
+ /* set up ipi interrupts */
+ if (cpu_has_vint) {
+ set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch);
+ set_vi_handler (MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch);
+ }
+
+ cpu_ipi_resched_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_RESCHED_IRQ;
+ cpu_ipi_call_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_CALL_IRQ;
+
+ setup_irq(cpu_ipi_resched_irq, &irq_resched);
+ setup_irq(cpu_ipi_call_irq, &irq_call);
+
+ /* need to mark IPI's as IRQ_PER_CPU */
+ irq_desc[cpu_ipi_resched_irq].status |= IRQ_PER_CPU;
+ irq_desc[cpu_ipi_call_irq].status |= IRQ_PER_CPU;
+}
+
+/*
+ * Setup the PC, SP, and GP of a secondary processor and start it
+ * running!
+ * smp_bootstrap is the place to resume from
+ * __KSTK_TOS(idle) is apparently the stack pointer
+ * (unsigned long)idle->thread_info the gp
+ * assumes a 1:1 mapping of TC => VPE
+ */
+void prom_boot_secondary(int cpu, struct task_struct *idle)
+{
+ dvpe();
+ set_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ settc(cpu);
+
+ /* restart */
+ write_tc_c0_tcrestart((unsigned long)&smp_bootstrap);
+
+ /* enable the tc this vpe/cpu will be running */
+ write_tc_c0_tcstatus((read_tc_c0_tcstatus() & ~TCSTATUS_IXMT) | TCSTATUS_A);
+
+ write_tc_c0_tchalt(0);
+
+ /* enable the VPE */
+ write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA);
+
+ /* stack pointer */
+ write_tc_gpr_sp( __KSTK_TOS(idle));
+
+ /* global pointer */
+ write_tc_gpr_gp((unsigned long)idle->thread_info);
+
+ flush_icache_range((unsigned long)idle->thread_info,
+ (unsigned long)idle->thread_info +
+ sizeof(struct thread_info));
+
+ /* finally out of configuration and into chaos */
+ clear_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ evpe(EVPE_ENABLE);
+}
+
+void prom_init_secondary(void)
+{
+ write_c0_status((read_c0_status() & ~ST0_IM ) |
+ (STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP7));
+}
+
+void prom_smp_finish(void)
+{
+ write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ));
+
+ local_irq_enable();
+}
+
+void prom_cpus_done(void)
+{
+}
+
+void core_send_ipi(int cpu, unsigned int action)
+{
+ int i;
+ unsigned long flags;
+ int vpflags;
+
+ local_irq_save (flags);
+
+ vpflags = dvpe(); /* cant access the other CPU's registers whilst MVPE enabled */
+
+ switch (action) {
+ case SMP_CALL_FUNCTION:
+ i = C_SW1;
+ break;
+
+ case SMP_RESCHEDULE_YOURSELF:
+ default:
+ i = C_SW0;
+ break;
+ }
+
+ /* 1:1 mapping of vpe and tc... */
+ settc(cpu);
+ write_vpe_c0_cause(read_vpe_c0_cause() | i);
+ evpe(vpflags);
+
+ local_irq_restore(flags);
+}
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index 21e3e13a4b44..ee98eeb65e85 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -7,6 +7,7 @@
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
* Copyright (C) 2001 MIPS Technologies, Inc.
*/
+#include <linux/config.h>
#include <linux/a.out.h>
#include <linux/errno.h>
#include <linux/linkage.h>
@@ -26,6 +27,7 @@
#include <linux/msg.h>
#include <linux/shm.h>
#include <linux/compiler.h>
+#include <linux/module.h>
#include <asm/branch.h>
#include <asm/cachectl.h>
@@ -56,6 +58,8 @@ out:
unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */
+EXPORT_SYMBOL(shm_align_mask);
+
#define COLOUR_ALIGN(addr,pgoff) \
((((addr) + shm_align_mask) & ~shm_align_mask) + \
(((pgoff) << PAGE_SHIFT) & shm_align_mask))
@@ -173,14 +177,28 @@ _sys_clone(nabi_no_regargs struct pt_regs regs)
{
unsigned long clone_flags;
unsigned long newsp;
- int *parent_tidptr, *child_tidptr;
+ int __user *parent_tidptr, *child_tidptr;
clone_flags = regs.regs[4];
newsp = regs.regs[5];
if (!newsp)
newsp = regs.regs[29];
- parent_tidptr = (int *) regs.regs[6];
- child_tidptr = (int *) regs.regs[7];
+ parent_tidptr = (int __user *) regs.regs[6];
+#ifdef CONFIG_32BIT
+ /* We need to fetch the fifth argument off the stack. */
+ child_tidptr = NULL;
+ if (clone_flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)) {
+ int __user *__user *usp = (int __user *__user *) regs.regs[29];
+ if (regs.regs[2] == __NR_syscall) {
+ if (get_user (child_tidptr, &usp[5]))
+ return -EFAULT;
+ }
+ else if (get_user (child_tidptr, &usp[4]))
+ return -EFAULT;
+ }
+#else
+ child_tidptr = (int __user *) regs.regs[8];
+#endif
return do_fork(clone_flags, newsp, &regs, 0,
parent_tidptr, child_tidptr);
}
@@ -242,6 +260,16 @@ asmlinkage int sys_olduname(struct oldold_utsname * name)
return error;
}
+void sys_set_thread_area(unsigned long addr)
+{
+ struct thread_info *ti = current->thread_info;
+
+ ti->tp_value = addr;
+
+ /* If some future MIPS implementation has this register in hardware,
+ * we will need to update it here (and in context switches). */
+}
+
asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3)
{
int tmp, len;
diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c
index 7ae4af476974..52924f8ce23c 100644
--- a/arch/mips/kernel/sysirix.c
+++ b/arch/mips/kernel/sysirix.c
@@ -73,32 +73,30 @@ asmlinkage int irix_sysmp(struct pt_regs *regs)
}
/* The prctl commands. */
-#define PR_MAXPROCS 1 /* Tasks/user. */
-#define PR_ISBLOCKED 2 /* If blocked, return 1. */
-#define PR_SETSTACKSIZE 3 /* Set largest task stack size. */
-#define PR_GETSTACKSIZE 4 /* Get largest task stack size. */
-#define PR_MAXPPROCS 5 /* Num parallel tasks. */
-#define PR_UNBLKONEXEC 6 /* When task exec/exit's, unblock. */
-#define PR_SETEXITSIG 8 /* When task exit's, set signal. */
-#define PR_RESIDENT 9 /* Make task unswappable. */
-#define PR_ATTACHADDR 10 /* (Re-)Connect a vma to a task. */
-#define PR_DETACHADDR 11 /* Disconnect a vma from a task. */
-#define PR_TERMCHILD 12 /* When parent sleeps with fishes, kill child. */
-#define PR_GETSHMASK 13 /* Get the sproc() share mask. */
-#define PR_GETNSHARE 14 /* Number of share group members. */
-#define PR_COREPID 15 /* Add task pid to name when it core. */
-#define PR_ATTACHADDRPERM 16 /* (Re-)Connect vma, with specified prot. */
-#define PR_PTHREADEXIT 17 /* Kill a pthread without prejudice. */
-
-asmlinkage int irix_prctl(struct pt_regs *regs)
-{
- unsigned long cmd;
- int error = 0, base = 0;
+#define PR_MAXPROCS 1 /* Tasks/user. */
+#define PR_ISBLOCKED 2 /* If blocked, return 1. */
+#define PR_SETSTACKSIZE 3 /* Set largest task stack size. */
+#define PR_GETSTACKSIZE 4 /* Get largest task stack size. */
+#define PR_MAXPPROCS 5 /* Num parallel tasks. */
+#define PR_UNBLKONEXEC 6 /* When task exec/exit's, unblock. */
+#define PR_SETEXITSIG 8 /* When task exit's, set signal. */
+#define PR_RESIDENT 9 /* Make task unswappable. */
+#define PR_ATTACHADDR 10 /* (Re-)Connect a vma to a task. */
+#define PR_DETACHADDR 11 /* Disconnect a vma from a task. */
+#define PR_TERMCHILD 12 /* Kill child if the parent dies. */
+#define PR_GETSHMASK 13 /* Get the sproc() share mask. */
+#define PR_GETNSHARE 14 /* Number of share group members. */
+#define PR_COREPID 15 /* Add task pid to name when it core. */
+#define PR_ATTACHADDRPERM 16 /* (Re-)Connect vma, with specified prot. */
+#define PR_PTHREADEXIT 17 /* Kill a pthread, only for IRIX 6.[234] */
+
+asmlinkage int irix_prctl(unsigned option, ...)
+{
+ va_list args;
+ int error = 0;
- if (regs->regs[2] == 1000)
- base = 1;
- cmd = regs->regs[base + 4];
- switch (cmd) {
+ va_start(args, option);
+ switch (option) {
case PR_MAXPROCS:
printk("irix_prctl[%s:%d]: Wants PR_MAXPROCS\n",
current->comm, current->pid);
@@ -111,7 +109,7 @@ asmlinkage int irix_prctl(struct pt_regs *regs)
printk("irix_prctl[%s:%d]: Wants PR_ISBLOCKED\n",
current->comm, current->pid);
read_lock(&tasklist_lock);
- task = find_task_by_pid(regs->regs[base + 5]);
+ task = find_task_by_pid(va_arg(args, pid_t));
error = -ESRCH;
if (error)
error = (task->run_list.next != NULL);
@@ -121,7 +119,7 @@ asmlinkage int irix_prctl(struct pt_regs *regs)
}
case PR_SETSTACKSIZE: {
- long value = regs->regs[base + 5];
+ long value = va_arg(args, long);
printk("irix_prctl[%s:%d]: Wants PR_SETSTACKSIZE<%08lx>\n",
current->comm, current->pid, (unsigned long) value);
@@ -222,24 +220,20 @@ asmlinkage int irix_prctl(struct pt_regs *regs)
error = -EINVAL;
break;
- case PR_PTHREADEXIT:
- printk("irix_prctl[%s:%d]: Wants PR_PTHREADEXIT\n",
- current->comm, current->pid);
- do_exit(regs->regs[base + 5]);
-
default:
printk("irix_prctl[%s:%d]: Non-existant opcode %d\n",
- current->comm, current->pid, (int)cmd);
+ current->comm, current->pid, option);
error = -EINVAL;
break;
}
+ va_end(args);
return error;
}
#undef DEBUG_PROCGRPS
-extern unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt);
+extern unsigned long irix_mapelf(int fd, struct elf_phdr __user *user_phdrp, int cnt);
extern int getrusage(struct task_struct *p, int who, struct rusage __user *ru);
extern char *prom_getenv(char *name);
extern long prom_setenv(char *name, char *value);
@@ -276,23 +270,19 @@ asmlinkage int irix_syssgi(struct pt_regs *regs)
cmd = regs->regs[base + 4];
switch(cmd) {
case SGI_SYSID: {
- char *buf = (char *) regs->regs[base + 5];
+ char __user *buf = (char __user *) regs->regs[base + 5];
/* XXX Use ethernet addr.... */
- retval = clear_user(buf, 64);
+ retval = clear_user(buf, 64) ? -EFAULT : 0;
break;
}
#if 0
case SGI_RDNAME: {
int pid = (int) regs->regs[base + 5];
- char *buf = (char *) regs->regs[base + 6];
+ char __user *buf = (char __user *) regs->regs[base + 6];
struct task_struct *p;
char tcomm[sizeof(current->comm)];
- if (!access_ok(VERIFY_WRITE, buf, sizeof(tcomm))) {
- retval = -EFAULT;
- break;
- }
read_lock(&tasklist_lock);
p = find_task_by_pid(pid);
if (!p) {
@@ -304,34 +294,28 @@ asmlinkage int irix_syssgi(struct pt_regs *regs)
read_unlock(&tasklist_lock);
/* XXX Need to check sizes. */
- copy_to_user(buf, tcomm, sizeof(tcomm));
- retval = 0;
+ retval = copy_to_user(buf, tcomm, sizeof(tcomm)) ? -EFAULT : 0;
break;
}
case SGI_GETNVRAM: {
- char *name = (char *) regs->regs[base+5];
- char *buf = (char *) regs->regs[base+6];
+ char __user *name = (char __user *) regs->regs[base+5];
+ char __user *buf = (char __user *) regs->regs[base+6];
char *value;
return -EINVAL; /* til I fix it */
- if (!access_ok(VERIFY_WRITE, buf, 128)) {
- retval = -EFAULT;
- break;
- }
value = prom_getenv(name); /* PROM lock? */
if (!value) {
retval = -EINVAL;
break;
}
/* Do I strlen() for the length? */
- copy_to_user(buf, value, 128);
- retval = 0;
+ retval = copy_to_user(buf, value, 128) ? -EFAULT : 0;
break;
}
case SGI_SETNVRAM: {
- char *name = (char *) regs->regs[base+5];
- char *value = (char *) regs->regs[base+6];
+ char __user *name = (char __user *) regs->regs[base+5];
+ char __user *value = (char __user *) regs->regs[base+6];
return -EINVAL; /* til I fix it */
retval = prom_setenv(name, value);
/* XXX make sure retval conforms to syssgi(2) */
@@ -407,16 +391,16 @@ asmlinkage int irix_syssgi(struct pt_regs *regs)
case SGI_SETGROUPS:
retval = sys_setgroups((int) regs->regs[base + 5],
- (gid_t *) regs->regs[base + 6]);
+ (gid_t __user *) regs->regs[base + 6]);
break;
case SGI_GETGROUPS:
retval = sys_getgroups((int) regs->regs[base + 5],
- (gid_t *) regs->regs[base + 6]);
+ (gid_t __user *) regs->regs[base + 6]);
break;
case SGI_RUSAGE: {
- struct rusage *ru = (struct rusage *) regs->regs[base + 6];
+ struct rusage __user *ru = (struct rusage __user *) regs->regs[base + 6];
switch((int) regs->regs[base + 5]) {
case 0:
@@ -453,7 +437,7 @@ asmlinkage int irix_syssgi(struct pt_regs *regs)
case SGI_ELFMAP:
retval = irix_mapelf((int) regs->regs[base + 5],
- (struct elf_phdr *) regs->regs[base + 6],
+ (struct elf_phdr __user *) regs->regs[base + 6],
(int) regs->regs[base + 7]);
break;
@@ -468,24 +452,24 @@ asmlinkage int irix_syssgi(struct pt_regs *regs)
case SGI_PHYSP: {
unsigned long addr = regs->regs[base + 5];
- int *pageno = (int *) (regs->regs[base + 6]);
+ int __user *pageno = (int __user *) (regs->regs[base + 6]);
struct mm_struct *mm = current->mm;
pgd_t *pgdp;
+ pud_t *pudp;
pmd_t *pmdp;
pte_t *ptep;
- if (!access_ok(VERIFY_WRITE, pageno, sizeof(int)))
- return -EFAULT;
-
down_read(&mm->mmap_sem);
pgdp = pgd_offset(mm, addr);
- pmdp = pmd_offset(pgdp, addr);
+ pudp = pud_offset(pgdp, addr);
+ pmdp = pmd_offset(pudp, addr);
ptep = pte_offset(pmdp, addr);
retval = -EINVAL;
if (ptep) {
pte_t pte = *ptep;
if (pte_val(pte) & (_PAGE_VALID | _PAGE_PRESENT)) {
+ /* b0rked on 64-bit */
retval = put_user((pte_val(pte) & PAGE_MASK) >>
PAGE_SHIFT, pageno);
}
@@ -496,7 +480,7 @@ asmlinkage int irix_syssgi(struct pt_regs *regs)
case SGI_INVENT: {
int arg1 = (int) regs->regs [base + 5];
- void *buffer = (void *) regs->regs [base + 6];
+ void __user *buffer = (void __user *) regs->regs [base + 6];
int count = (int) regs->regs [base + 7];
switch (arg1) {
@@ -692,8 +676,8 @@ asmlinkage int irix_pause(void)
}
/* XXX need more than this... */
-asmlinkage int irix_mount(char *dev_name, char *dir_name, unsigned long flags,
- char *type, void *data, int datalen)
+asmlinkage int irix_mount(char __user *dev_name, char __user *dir_name,
+ unsigned long flags, char __user *type, void __user *data, int datalen)
{
printk("[%s:%d] irix_mount(%p,%p,%08lx,%p,%p,%d)\n",
current->comm, current->pid,
@@ -708,8 +692,8 @@ struct irix_statfs {
char f_fname[6], f_fpack[6];
};
-asmlinkage int irix_statfs(const char *path, struct irix_statfs *buf,
- int len, int fs_type)
+asmlinkage int irix_statfs(const char __user *path,
+ struct irix_statfs __user *buf, int len, int fs_type)
{
struct nameidata nd;
struct kstatfs kbuf;
@@ -724,6 +708,7 @@ asmlinkage int irix_statfs(const char *path, struct irix_statfs *buf,
error = -EFAULT;
goto out;
}
+
error = user_path_walk(path, &nd);
if (error)
goto out;
@@ -732,18 +717,17 @@ asmlinkage int irix_statfs(const char *path, struct irix_statfs *buf,
if (error)
goto dput_and_out;
- __put_user(kbuf.f_type, &buf->f_type);
- __put_user(kbuf.f_bsize, &buf->f_bsize);
- __put_user(kbuf.f_frsize, &buf->f_frsize);
- __put_user(kbuf.f_blocks, &buf->f_blocks);
- __put_user(kbuf.f_bfree, &buf->f_bfree);
- __put_user(kbuf.f_files, &buf->f_files);
- __put_user(kbuf.f_ffree, &buf->f_ffree);
+ error = __put_user(kbuf.f_type, &buf->f_type);
+ error |= __put_user(kbuf.f_bsize, &buf->f_bsize);
+ error |= __put_user(kbuf.f_frsize, &buf->f_frsize);
+ error |= __put_user(kbuf.f_blocks, &buf->f_blocks);
+ error |= __put_user(kbuf.f_bfree, &buf->f_bfree);
+ error |= __put_user(kbuf.f_files, &buf->f_files);
+ error |= __put_user(kbuf.f_ffree, &buf->f_ffree);
for (i = 0; i < 6; i++) {
- __put_user(0, &buf->f_fname[i]);
- __put_user(0, &buf->f_fpack[i]);
+ error |= __put_user(0, &buf->f_fname[i]);
+ error |= __put_user(0, &buf->f_fpack[i]);
}
- error = 0;
dput_and_out:
path_release(&nd);
@@ -751,7 +735,7 @@ out:
return error;
}
-asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs *buf)
+asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs __user *buf)
{
struct kstatfs kbuf;
struct file *file;
@@ -761,6 +745,7 @@ asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs *buf)
error = -EFAULT;
goto out;
}
+
if (!(file = fget(fd))) {
error = -EBADF;
goto out;
@@ -770,16 +755,17 @@ asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs *buf)
if (error)
goto out_f;
- __put_user(kbuf.f_type, &buf->f_type);
- __put_user(kbuf.f_bsize, &buf->f_bsize);
- __put_user(kbuf.f_frsize, &buf->f_frsize);
- __put_user(kbuf.f_blocks, &buf->f_blocks);
- __put_user(kbuf.f_bfree, &buf->f_bfree);
- __put_user(kbuf.f_files, &buf->f_files);
- __put_user(kbuf.f_ffree, &buf->f_ffree);
- for(i = 0; i < 6; i++) {
- __put_user(0, &buf->f_fname[i]);
- __put_user(0, &buf->f_fpack[i]);
+ error = __put_user(kbuf.f_type, &buf->f_type);
+ error |= __put_user(kbuf.f_bsize, &buf->f_bsize);
+ error |= __put_user(kbuf.f_frsize, &buf->f_frsize);
+ error |= __put_user(kbuf.f_blocks, &buf->f_blocks);
+ error |= __put_user(kbuf.f_bfree, &buf->f_bfree);
+ error |= __put_user(kbuf.f_files, &buf->f_files);
+ error |= __put_user(kbuf.f_ffree, &buf->f_ffree);
+
+ for (i = 0; i < 6; i++) {
+ error |= __put_user(0, &buf->f_fname[i]);
+ error |= __put_user(0, &buf->f_fpack[i]);
}
out_f:
@@ -806,14 +792,15 @@ asmlinkage int irix_setpgrp(int flags)
return error;
}
-asmlinkage int irix_times(struct tms * tbuf)
+asmlinkage int irix_times(struct tms __user *tbuf)
{
int err = 0;
if (tbuf) {
if (!access_ok(VERIFY_WRITE,tbuf,sizeof *tbuf))
return -EFAULT;
- err |= __put_user(current->utime, &tbuf->tms_utime);
+
+ err = __put_user(current->utime, &tbuf->tms_utime);
err |= __put_user(current->stime, &tbuf->tms_stime);
err |= __put_user(current->signal->cutime, &tbuf->tms_cutime);
err |= __put_user(current->signal->cstime, &tbuf->tms_cstime);
@@ -829,13 +816,13 @@ asmlinkage int irix_exec(struct pt_regs *regs)
if(regs->regs[2] == 1000)
base = 1;
- filename = getname((char *) (long)regs->regs[base + 4]);
+ filename = getname((char __user *) (long)regs->regs[base + 4]);
error = PTR_ERR(filename);
if (IS_ERR(filename))
return error;
- error = do_execve(filename, (char **) (long)regs->regs[base + 5],
- (char **) 0, regs);
+ error = do_execve(filename, (char __user * __user *) (long)regs->regs[base + 5],
+ NULL, regs);
putname(filename);
return error;
@@ -848,12 +835,12 @@ asmlinkage int irix_exece(struct pt_regs *regs)
if (regs->regs[2] == 1000)
base = 1;
- filename = getname((char *) (long)regs->regs[base + 4]);
+ filename = getname((char __user *) (long)regs->regs[base + 4]);
error = PTR_ERR(filename);
if (IS_ERR(filename))
return error;
- error = do_execve(filename, (char **) (long)regs->regs[base + 5],
- (char **) (long)regs->regs[base + 6], regs);
+ error = do_execve(filename, (char __user * __user *) (long)regs->regs[base + 5],
+ (char __user * __user *) (long)regs->regs[base + 6], regs);
putname(filename);
return error;
@@ -909,22 +896,17 @@ asmlinkage int irix_socket(int family, int type, int protocol)
return sys_socket(family, type, protocol);
}
-asmlinkage int irix_getdomainname(char *name, int len)
+asmlinkage int irix_getdomainname(char __user *name, int len)
{
- int error;
-
- if (!access_ok(VERIFY_WRITE, name, len))
- return -EFAULT;
+ int err;
down_read(&uts_sem);
if (len > __NEW_UTS_LEN)
len = __NEW_UTS_LEN;
- error = 0;
- if (copy_to_user(name, system_utsname.domainname, len))
- error = -EFAULT;
+ err = copy_to_user(name, system_utsname.domainname, len) ? -EFAULT : 0;
up_read(&uts_sem);
- return error;
+ return err;
}
asmlinkage unsigned long irix_getpagesize(void)
@@ -940,12 +922,13 @@ asmlinkage int irix_msgsys(int opcode, unsigned long arg0, unsigned long arg1,
case 0:
return sys_msgget((key_t) arg0, (int) arg1);
case 1:
- return sys_msgctl((int) arg0, (int) arg1, (struct msqid_ds *)arg2);
+ return sys_msgctl((int) arg0, (int) arg1,
+ (struct msqid_ds __user *)arg2);
case 2:
- return sys_msgrcv((int) arg0, (struct msgbuf *) arg1,
+ return sys_msgrcv((int) arg0, (struct msgbuf __user *) arg1,
(size_t) arg2, (long) arg3, (int) arg4);
case 3:
- return sys_msgsnd((int) arg0, (struct msgbuf *) arg1,
+ return sys_msgsnd((int) arg0, (struct msgbuf __user *) arg1,
(size_t) arg2, (int) arg3);
default:
return -EINVAL;
@@ -957,12 +940,13 @@ asmlinkage int irix_shmsys(int opcode, unsigned long arg0, unsigned long arg1,
{
switch (opcode) {
case 0:
- return do_shmat((int) arg0, (char *)arg1, (int) arg2,
+ return do_shmat((int) arg0, (char __user *) arg1, (int) arg2,
(unsigned long *) arg3);
case 1:
- return sys_shmctl((int)arg0, (int)arg1, (struct shmid_ds *)arg2);
+ return sys_shmctl((int)arg0, (int)arg1,
+ (struct shmid_ds __user *)arg2);
case 2:
- return sys_shmdt((char *)arg0);
+ return sys_shmdt((char __user *)arg0);
case 3:
return sys_shmget((key_t) arg0, (int) arg1, (int) arg2);
default:
@@ -980,7 +964,7 @@ asmlinkage int irix_semsys(int opcode, unsigned long arg0, unsigned long arg1,
case 1:
return sys_semget((key_t) arg0, (int) arg1, (int) arg2);
case 2:
- return sys_semop((int) arg0, (struct sembuf *)arg1,
+ return sys_semop((int) arg0, (struct sembuf __user *)arg1,
(unsigned int) arg2);
default:
return -EINVAL;
@@ -998,15 +982,16 @@ static inline loff_t llseek(struct file *file, loff_t offset, int origin)
lock_kernel();
retval = fn(file, offset, origin);
unlock_kernel();
+
return retval;
}
asmlinkage int irix_lseek64(int fd, int _unused, int offhi, int offlow,
int origin)
{
- int retval;
struct file * file;
loff_t offset;
+ int retval;
retval = -EBADF;
file = fget(fd);
@@ -1031,12 +1016,12 @@ asmlinkage int irix_sginap(int ticks)
return 0;
}
-asmlinkage int irix_sgikopt(char *istring, char *ostring, int len)
+asmlinkage int irix_sgikopt(char __user *istring, char __user *ostring, int len)
{
return -EINVAL;
}
-asmlinkage int irix_gettimeofday(struct timeval *tv)
+asmlinkage int irix_gettimeofday(struct timeval __user *tv)
{
time_t sec;
long nsec, seq;
@@ -1077,7 +1062,7 @@ asmlinkage unsigned long irix_mmap32(unsigned long addr, size_t len, int prot,
if (max_size > file->f_dentry->d_inode->i_size) {
old_pos = sys_lseek (fd, max_size - 1, 0);
- sys_write (fd, "", 1);
+ sys_write (fd, (void __user *) "", 1);
sys_lseek (fd, old_pos, 0);
}
}
@@ -1102,7 +1087,7 @@ asmlinkage int irix_madvise(unsigned long addr, int len, int behavior)
return -EINVAL;
}
-asmlinkage int irix_pagelock(char *addr, int len, int op)
+asmlinkage int irix_pagelock(char __user *addr, int len, int op)
{
printk("[%s:%d] Wheee.. irix_pagelock(%p,%d,%d)\n",
current->comm, current->pid, addr, len, op);
@@ -1142,7 +1127,7 @@ asmlinkage int irix_BSDsetpgrp(int pid, int pgrp)
return error;
}
-asmlinkage int irix_systeminfo(int cmd, char *buf, int cnt)
+asmlinkage int irix_systeminfo(int cmd, char __user *buf, int cnt)
{
printk("[%s:%d] Wheee.. irix_systeminfo(%d,%p,%d)\n",
current->comm, current->pid, cmd, buf, cnt);
@@ -1158,14 +1143,14 @@ struct iuname {
char _unused3[257], _unused4[257], _unused5[257];
};
-asmlinkage int irix_uname(struct iuname *buf)
+asmlinkage int irix_uname(struct iuname __user *buf)
{
down_read(&uts_sem);
- if (copy_to_user(system_utsname.sysname, buf->sysname, 65)
- || copy_to_user(system_utsname.nodename, buf->nodename, 65)
- || copy_to_user(system_utsname.release, buf->release, 65)
- || copy_to_user(system_utsname.version, buf->version, 65)
- || copy_to_user(system_utsname.machine, buf->machine, 65)) {
+ if (copy_from_user(system_utsname.sysname, buf->sysname, 65)
+ || copy_from_user(system_utsname.nodename, buf->nodename, 65)
+ || copy_from_user(system_utsname.release, buf->release, 65)
+ || copy_from_user(system_utsname.version, buf->version, 65)
+ || copy_from_user(system_utsname.machine, buf->machine, 65)) {
return -EFAULT;
}
up_read(&uts_sem);
@@ -1175,7 +1160,7 @@ asmlinkage int irix_uname(struct iuname *buf)
#undef DEBUG_XSTAT
-static int irix_xstat32_xlate(struct kstat *stat, void *ubuf)
+static int irix_xstat32_xlate(struct kstat *stat, void __user *ubuf)
{
struct xstat32 {
u32 st_dev, st_pad1[3], st_ino, st_mode, st_nlink, st_uid, st_gid;
@@ -1215,7 +1200,7 @@ static int irix_xstat32_xlate(struct kstat *stat, void *ubuf)
return copy_to_user(ubuf, &ub, sizeof(ub)) ? -EFAULT : 0;
}
-static int irix_xstat64_xlate(struct kstat *stat, void *ubuf)
+static int irix_xstat64_xlate(struct kstat *stat, void __user *ubuf)
{
struct xstat64 {
u32 st_dev; s32 st_pad1[3];
@@ -1265,7 +1250,7 @@ static int irix_xstat64_xlate(struct kstat *stat, void *ubuf)
return copy_to_user(ubuf, &ks, sizeof(ks)) ? -EFAULT : 0;
}
-asmlinkage int irix_xstat(int version, char *filename, struct stat *statbuf)
+asmlinkage int irix_xstat(int version, char __user *filename, struct stat __user *statbuf)
{
int retval;
struct kstat stat;
@@ -1291,7 +1276,7 @@ asmlinkage int irix_xstat(int version, char *filename, struct stat *statbuf)
return retval;
}
-asmlinkage int irix_lxstat(int version, char *filename, struct stat *statbuf)
+asmlinkage int irix_lxstat(int version, char __user *filename, struct stat __user *statbuf)
{
int error;
struct kstat stat;
@@ -1318,7 +1303,7 @@ asmlinkage int irix_lxstat(int version, char *filename, struct stat *statbuf)
return error;
}
-asmlinkage int irix_fxstat(int version, int fd, struct stat *statbuf)
+asmlinkage int irix_fxstat(int version, int fd, struct stat __user *statbuf)
{
int error;
struct kstat stat;
@@ -1344,7 +1329,7 @@ asmlinkage int irix_fxstat(int version, int fd, struct stat *statbuf)
return error;
}
-asmlinkage int irix_xmknod(int ver, char *filename, int mode, unsigned dev)
+asmlinkage int irix_xmknod(int ver, char __user *filename, int mode, unsigned dev)
{
int retval;
printk("[%s:%d] Wheee.. irix_xmknod(%d,%s,%x,%x)\n",
@@ -1364,7 +1349,7 @@ asmlinkage int irix_xmknod(int ver, char *filename, int mode, unsigned dev)
return retval;
}
-asmlinkage int irix_swapctl(int cmd, char *arg)
+asmlinkage int irix_swapctl(int cmd, char __user *arg)
{
printk("[%s:%d] Wheee.. irix_swapctl(%d,%p)\n",
current->comm, current->pid, cmd, arg);
@@ -1380,7 +1365,7 @@ struct irix_statvfs {
char f_fstr[32]; u32 f_filler[16];
};
-asmlinkage int irix_statvfs(char *fname, struct irix_statvfs *buf)
+asmlinkage int irix_statvfs(char __user *fname, struct irix_statvfs __user *buf)
{
struct nameidata nd;
struct kstatfs kbuf;
@@ -1388,10 +1373,9 @@ asmlinkage int irix_statvfs(char *fname, struct irix_statvfs *buf)
printk("[%s:%d] Wheee.. irix_statvfs(%s,%p)\n",
current->comm, current->pid, fname, buf);
- if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs))) {
- error = -EFAULT;
- goto out;
- }
+ if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs)))
+ return -EFAULT;
+
error = user_path_walk(fname, &nd);
if (error)
goto out;
@@ -1399,27 +1383,25 @@ asmlinkage int irix_statvfs(char *fname, struct irix_statvfs *buf)
if (error)
goto dput_and_out;
- __put_user(kbuf.f_bsize, &buf->f_bsize);
- __put_user(kbuf.f_frsize, &buf->f_frsize);
- __put_user(kbuf.f_blocks, &buf->f_blocks);
- __put_user(kbuf.f_bfree, &buf->f_bfree);
- __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */
- __put_user(kbuf.f_files, &buf->f_files);
- __put_user(kbuf.f_ffree, &buf->f_ffree);
- __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */
+ error |= __put_user(kbuf.f_bsize, &buf->f_bsize);
+ error |= __put_user(kbuf.f_frsize, &buf->f_frsize);
+ error |= __put_user(kbuf.f_blocks, &buf->f_blocks);
+ error |= __put_user(kbuf.f_bfree, &buf->f_bfree);
+ error |= __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */
+ error |= __put_user(kbuf.f_files, &buf->f_files);
+ error |= __put_user(kbuf.f_ffree, &buf->f_ffree);
+ error |= __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */
#ifdef __MIPSEB__
- __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
+ error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
#else
- __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
+ error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
#endif
for (i = 0; i < 16; i++)
- __put_user(0, &buf->f_basetype[i]);
- __put_user(0, &buf->f_flag);
- __put_user(kbuf.f_namelen, &buf->f_namemax);
+ error |= __put_user(0, &buf->f_basetype[i]);
+ error |= __put_user(0, &buf->f_flag);
+ error |= __put_user(kbuf.f_namelen, &buf->f_namemax);
for (i = 0; i < 32; i++)
- __put_user(0, &buf->f_fstr[i]);
-
- error = 0;
+ error |= __put_user(0, &buf->f_fstr[i]);
dput_and_out:
path_release(&nd);
@@ -1427,7 +1409,7 @@ out:
return error;
}
-asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs *buf)
+asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs __user *buf)
{
struct kstatfs kbuf;
struct file *file;
@@ -1436,10 +1418,9 @@ asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs *buf)
printk("[%s:%d] Wheee.. irix_fstatvfs(%d,%p)\n",
current->comm, current->pid, fd, buf);
- if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs))) {
- error = -EFAULT;
- goto out;
- }
+ if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs)))
+ return -EFAULT;
+
if (!(file = fget(fd))) {
error = -EBADF;
goto out;
@@ -1448,24 +1429,24 @@ asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs *buf)
if (error)
goto out_f;
- __put_user(kbuf.f_bsize, &buf->f_bsize);
- __put_user(kbuf.f_frsize, &buf->f_frsize);
- __put_user(kbuf.f_blocks, &buf->f_blocks);
- __put_user(kbuf.f_bfree, &buf->f_bfree);
- __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */
- __put_user(kbuf.f_files, &buf->f_files);
- __put_user(kbuf.f_ffree, &buf->f_ffree);
- __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */
+ error = __put_user(kbuf.f_bsize, &buf->f_bsize);
+ error |= __put_user(kbuf.f_frsize, &buf->f_frsize);
+ error |= __put_user(kbuf.f_blocks, &buf->f_blocks);
+ error |= __put_user(kbuf.f_bfree, &buf->f_bfree);
+ error |= __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */
+ error |= __put_user(kbuf.f_files, &buf->f_files);
+ error |= __put_user(kbuf.f_ffree, &buf->f_ffree);
+ error |= __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */
#ifdef __MIPSEB__
- __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
+ error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
#else
- __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
+ error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
#endif
for(i = 0; i < 16; i++)
- __put_user(0, &buf->f_basetype[i]);
- __put_user(0, &buf->f_flag);
- __put_user(kbuf.f_namelen, &buf->f_namemax);
- __clear_user(&buf->f_fstr, sizeof(buf->f_fstr));
+ error |= __put_user(0, &buf->f_basetype[i]);
+ error |= __put_user(0, &buf->f_flag);
+ error |= __put_user(kbuf.f_namelen, &buf->f_namemax);
+ error |= __clear_user(&buf->f_fstr, sizeof(buf->f_fstr)) ? -EFAULT : 0;
out_f:
fput(file);
@@ -1489,7 +1470,7 @@ asmlinkage int irix_sigqueue(int pid, int sig, int code, int val)
return -EINVAL;
}
-asmlinkage int irix_truncate64(char *name, int pad, int size1, int size2)
+asmlinkage int irix_truncate64(char __user *name, int pad, int size1, int size2)
{
int retval;
@@ -1522,6 +1503,7 @@ asmlinkage int irix_mmap64(struct pt_regs *regs)
int len, prot, flags, fd, off1, off2, error, base = 0;
unsigned long addr, pgoff, *sp;
struct file *file = NULL;
+ int err;
if (regs->regs[2] == 1000)
base = 1;
@@ -1531,36 +1513,31 @@ asmlinkage int irix_mmap64(struct pt_regs *regs)
prot = regs->regs[base + 6];
if (!base) {
flags = regs->regs[base + 7];
- if (!access_ok(VERIFY_READ, sp, (4 * sizeof(unsigned long)))) {
- error = -EFAULT;
- goto out;
- }
+ if (!access_ok(VERIFY_READ, sp, (4 * sizeof(unsigned long))))
+ return -EFAULT;
fd = sp[0];
- __get_user(off1, &sp[1]);
- __get_user(off2, &sp[2]);
+ err = __get_user(off1, &sp[1]);
+ err |= __get_user(off2, &sp[2]);
} else {
- if (!access_ok(VERIFY_READ, sp, (5 * sizeof(unsigned long)))) {
- error = -EFAULT;
- goto out;
- }
- __get_user(flags, &sp[0]);
- __get_user(fd, &sp[1]);
- __get_user(off1, &sp[2]);
- __get_user(off2, &sp[3]);
+ if (!access_ok(VERIFY_READ, sp, (5 * sizeof(unsigned long))))
+ return -EFAULT;
+ err = __get_user(flags, &sp[0]);
+ err |= __get_user(fd, &sp[1]);
+ err |= __get_user(off1, &sp[2]);
+ err |= __get_user(off2, &sp[3]);
}
- if (off1 & PAGE_MASK) {
- error = -EOVERFLOW;
- goto out;
- }
+ if (err)
+ return err;
+
+ if (off1 & PAGE_MASK)
+ return -EOVERFLOW;
pgoff = (off1 << (32 - PAGE_SHIFT)) | (off2 >> PAGE_SHIFT);
if (!(flags & MAP_ANONYMOUS)) {
- if (!(file = fget(fd))) {
- error = -EBADF;
- goto out;
- }
+ if (!(file = fget(fd)))
+ return -EBADF;
/* Ok, bad taste hack follows, try to think in something else
when reading this */
@@ -1570,7 +1547,7 @@ asmlinkage int irix_mmap64(struct pt_regs *regs)
if (max_size > file->f_dentry->d_inode->i_size) {
old_pos = sys_lseek (fd, max_size - 1, 0);
- sys_write (fd, "", 1);
+ sys_write (fd, (void __user *) "", 1);
sys_lseek (fd, old_pos, 0);
}
}
@@ -1585,7 +1562,6 @@ asmlinkage int irix_mmap64(struct pt_regs *regs)
if (file)
fput(file);
-out:
return error;
}
@@ -1597,7 +1573,7 @@ asmlinkage int irix_dmi(struct pt_regs *regs)
return -EINVAL;
}
-asmlinkage int irix_pread(int fd, char *buf, int cnt, int off64,
+asmlinkage int irix_pread(int fd, char __user *buf, int cnt, int off64,
int off1, int off2)
{
printk("[%s:%d] Wheee.. irix_pread(%d,%p,%d,%d,%d,%d)\n",
@@ -1606,7 +1582,7 @@ asmlinkage int irix_pread(int fd, char *buf, int cnt, int off64,
return -EINVAL;
}
-asmlinkage int irix_pwrite(int fd, char *buf, int cnt, int off64,
+asmlinkage int irix_pwrite(int fd, char __user *buf, int cnt, int off64,
int off1, int off2)
{
printk("[%s:%d] Wheee.. irix_pwrite(%d,%p,%d,%d,%d,%d)\n",
@@ -1638,7 +1614,7 @@ struct irix_statvfs64 {
u32 f_filler[16];
};
-asmlinkage int irix_statvfs64(char *fname, struct irix_statvfs64 *buf)
+asmlinkage int irix_statvfs64(char __user *fname, struct irix_statvfs64 __user *buf)
{
struct nameidata nd;
struct kstatfs kbuf;
@@ -1650,6 +1626,7 @@ asmlinkage int irix_statvfs64(char *fname, struct irix_statvfs64 *buf)
error = -EFAULT;
goto out;
}
+
error = user_path_walk(fname, &nd);
if (error)
goto out;
@@ -1657,27 +1634,25 @@ asmlinkage int irix_statvfs64(char *fname, struct irix_statvfs64 *buf)
if (error)
goto dput_and_out;
- __put_user(kbuf.f_bsize, &buf->f_bsize);
- __put_user(kbuf.f_frsize, &buf->f_frsize);
- __put_user(kbuf.f_blocks, &buf->f_blocks);
- __put_user(kbuf.f_bfree, &buf->f_bfree);
- __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */
- __put_user(kbuf.f_files, &buf->f_files);
- __put_user(kbuf.f_ffree, &buf->f_ffree);
- __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */
+ error = __put_user(kbuf.f_bsize, &buf->f_bsize);
+ error |= __put_user(kbuf.f_frsize, &buf->f_frsize);
+ error |= __put_user(kbuf.f_blocks, &buf->f_blocks);
+ error |= __put_user(kbuf.f_bfree, &buf->f_bfree);
+ error |= __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */
+ error |= __put_user(kbuf.f_files, &buf->f_files);
+ error |= __put_user(kbuf.f_ffree, &buf->f_ffree);
+ error |= __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */
#ifdef __MIPSEB__
- __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
+ error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
#else
- __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
+ error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
#endif
for(i = 0; i < 16; i++)
- __put_user(0, &buf->f_basetype[i]);
- __put_user(0, &buf->f_flag);
- __put_user(kbuf.f_namelen, &buf->f_namemax);
+ error |= __put_user(0, &buf->f_basetype[i]);
+ error |= __put_user(0, &buf->f_flag);
+ error |= __put_user(kbuf.f_namelen, &buf->f_namemax);
for(i = 0; i < 32; i++)
- __put_user(0, &buf->f_fstr[i]);
-
- error = 0;
+ error |= __put_user(0, &buf->f_fstr[i]);
dput_and_out:
path_release(&nd);
@@ -1685,7 +1660,7 @@ out:
return error;
}
-asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs *buf)
+asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs __user *buf)
{
struct kstatfs kbuf;
struct file *file;
@@ -1706,24 +1681,24 @@ asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs *buf)
if (error)
goto out_f;
- __put_user(kbuf.f_bsize, &buf->f_bsize);
- __put_user(kbuf.f_frsize, &buf->f_frsize);
- __put_user(kbuf.f_blocks, &buf->f_blocks);
- __put_user(kbuf.f_bfree, &buf->f_bfree);
- __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */
- __put_user(kbuf.f_files, &buf->f_files);
- __put_user(kbuf.f_ffree, &buf->f_ffree);
- __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */
+ error = __put_user(kbuf.f_bsize, &buf->f_bsize);
+ error |= __put_user(kbuf.f_frsize, &buf->f_frsize);
+ error |= __put_user(kbuf.f_blocks, &buf->f_blocks);
+ error |= __put_user(kbuf.f_bfree, &buf->f_bfree);
+ error |= __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */
+ error |= __put_user(kbuf.f_files, &buf->f_files);
+ error |= __put_user(kbuf.f_ffree, &buf->f_ffree);
+ error |= __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */
#ifdef __MIPSEB__
- __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
+ error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
#else
- __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
+ error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
#endif
for(i = 0; i < 16; i++)
- __put_user(0, &buf->f_basetype[i]);
- __put_user(0, &buf->f_flag);
- __put_user(kbuf.f_namelen, &buf->f_namemax);
- __clear_user(buf->f_fstr, sizeof(buf->f_fstr[i]));
+ error |= __put_user(0, &buf->f_basetype[i]);
+ error |= __put_user(0, &buf->f_flag);
+ error |= __put_user(kbuf.f_namelen, &buf->f_namemax);
+ error |= __clear_user(buf->f_fstr, sizeof(buf->f_fstr[i])) ? -EFAULT : 0;
out_f:
fput(file);
@@ -1731,9 +1706,9 @@ out:
return error;
}
-asmlinkage int irix_getmountid(char *fname, unsigned long *midbuf)
+asmlinkage int irix_getmountid(char __user *fname, unsigned long __user *midbuf)
{
- int err = 0;
+ int err;
printk("[%s:%d] irix_getmountid(%s, %p)\n",
current->comm, current->pid, fname, midbuf);
@@ -1746,7 +1721,7 @@ asmlinkage int irix_getmountid(char *fname, unsigned long *midbuf)
* fsid of the filesystem to try and make the right decision, but
* we don't have this so for now. XXX
*/
- err |= __put_user(0, &midbuf[0]);
+ err = __put_user(0, &midbuf[0]);
err |= __put_user(0, &midbuf[1]);
err |= __put_user(0, &midbuf[2]);
err |= __put_user(0, &midbuf[3]);
@@ -1773,8 +1748,8 @@ struct irix_dirent32 {
};
struct irix_dirent32_callback {
- struct irix_dirent32 *current_dir;
- struct irix_dirent32 *previous;
+ struct irix_dirent32 __user *current_dir;
+ struct irix_dirent32 __user *previous;
int count;
int error;
};
@@ -1782,13 +1757,13 @@ struct irix_dirent32_callback {
#define NAME_OFFSET32(de) ((int) ((de)->d_name - (char *) (de)))
#define ROUND_UP32(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
-static int irix_filldir32(void *__buf, const char *name, int namlen,
- loff_t offset, ino_t ino, unsigned int d_type)
+static int irix_filldir32(void *__buf, const char *name,
+ int namlen, loff_t offset, ino_t ino, unsigned int d_type)
{
- struct irix_dirent32 *dirent;
- struct irix_dirent32_callback *buf =
- (struct irix_dirent32_callback *)__buf;
+ struct irix_dirent32 __user *dirent;
+ struct irix_dirent32_callback *buf = __buf;
unsigned short reclen = ROUND_UP32(NAME_OFFSET32(dirent) + namlen + 1);
+ int err = 0;
#ifdef DEBUG_GETDENTS
printk("\nirix_filldir32[reclen<%d>namlen<%d>count<%d>]",
@@ -1799,25 +1774,26 @@ static int irix_filldir32(void *__buf, const char *name, int namlen,
return -EINVAL;
dirent = buf->previous;
if (dirent)
- __put_user(offset, &dirent->d_off);
+ err = __put_user(offset, &dirent->d_off);
dirent = buf->current_dir;
- buf->previous = dirent;
- __put_user(ino, &dirent->d_ino);
- __put_user(reclen, &dirent->d_reclen);
- copy_to_user(dirent->d_name, name, namlen);
- __put_user(0, &dirent->d_name[namlen]);
- ((char *) dirent) += reclen;
+ err |= __put_user(dirent, &buf->previous);
+ err |= __put_user(ino, &dirent->d_ino);
+ err |= __put_user(reclen, &dirent->d_reclen);
+ err |= copy_to_user((char __user *)dirent->d_name, name, namlen) ? -EFAULT : 0;
+ err |= __put_user(0, &dirent->d_name[namlen]);
+ dirent = (struct irix_dirent32 __user *) ((char __user *) dirent + reclen);
+
buf->current_dir = dirent;
buf->count -= reclen;
- return 0;
+ return err;
}
-asmlinkage int irix_ngetdents(unsigned int fd, void * dirent,
- unsigned int count, int *eob)
+asmlinkage int irix_ngetdents(unsigned int fd, void __user * dirent,
+ unsigned int count, int __user *eob)
{
struct file *file;
- struct irix_dirent32 *lastdirent;
+ struct irix_dirent32 __user *lastdirent;
struct irix_dirent32_callback buf;
int error;
@@ -1830,7 +1806,7 @@ asmlinkage int irix_ngetdents(unsigned int fd, void * dirent,
if (!file)
goto out;
- buf.current_dir = (struct irix_dirent32 *) dirent;
+ buf.current_dir = (struct irix_dirent32 __user *) dirent;
buf.previous = NULL;
buf.count = count;
buf.error = 0;
@@ -1870,8 +1846,8 @@ struct irix_dirent64 {
};
struct irix_dirent64_callback {
- struct irix_dirent64 *curr;
- struct irix_dirent64 *previous;
+ struct irix_dirent64 __user *curr;
+ struct irix_dirent64 __user *previous;
int count;
int error;
};
@@ -1879,37 +1855,44 @@ struct irix_dirent64_callback {
#define NAME_OFFSET64(de) ((int) ((de)->d_name - (char *) (de)))
#define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1))
-static int irix_filldir64(void * __buf, const char * name, int namlen,
- loff_t offset, ino_t ino, unsigned int d_type)
+static int irix_filldir64(void *__buf, const char *name,
+ int namlen, loff_t offset, ino_t ino, unsigned int d_type)
{
- struct irix_dirent64 *dirent;
- struct irix_dirent64_callback * buf =
- (struct irix_dirent64_callback *) __buf;
+ struct irix_dirent64 __user *dirent;
+ struct irix_dirent64_callback * buf = __buf;
unsigned short reclen = ROUND_UP64(NAME_OFFSET64(dirent) + namlen + 1);
+ int err = 0;
- buf->error = -EINVAL; /* only used if we fail.. */
+ if (!access_ok(VERIFY_WRITE, buf, sizeof(*buf)))
+ return -EFAULT;
+
+ if (__put_user(-EINVAL, &buf->error)) /* only used if we fail.. */
+ return -EFAULT;
if (reclen > buf->count)
return -EINVAL;
dirent = buf->previous;
if (dirent)
- __put_user(offset, &dirent->d_off);
+ err = __put_user(offset, &dirent->d_off);
dirent = buf->curr;
buf->previous = dirent;
- __put_user(ino, &dirent->d_ino);
- __put_user(reclen, &dirent->d_reclen);
- __copy_to_user(dirent->d_name, name, namlen);
- __put_user(0, &dirent->d_name[namlen]);
- ((char *) dirent) += reclen;
+ err |= __put_user(ino, &dirent->d_ino);
+ err |= __put_user(reclen, &dirent->d_reclen);
+ err |= __copy_to_user((char __user *)dirent->d_name, name, namlen)
+ ? -EFAULT : 0;
+ err |= __put_user(0, &dirent->d_name[namlen]);
+
+ dirent = (struct irix_dirent64 __user *) ((char __user *) dirent + reclen);
+
buf->curr = dirent;
buf->count -= reclen;
- return 0;
+ return err;
}
-asmlinkage int irix_getdents64(int fd, void *dirent, int cnt)
+asmlinkage int irix_getdents64(int fd, void __user *dirent, int cnt)
{
struct file *file;
- struct irix_dirent64 *lastdirent;
+ struct irix_dirent64 __user *lastdirent;
struct irix_dirent64_callback buf;
int error;
@@ -1929,7 +1912,7 @@ asmlinkage int irix_getdents64(int fd, void *dirent, int cnt)
if (cnt < (sizeof(struct irix_dirent64) + 255))
goto out_f;
- buf.curr = (struct irix_dirent64 *) dirent;
+ buf.curr = (struct irix_dirent64 __user *) dirent;
buf.previous = NULL;
buf.count = cnt;
buf.error = 0;
@@ -1941,7 +1924,8 @@ asmlinkage int irix_getdents64(int fd, void *dirent, int cnt)
error = buf.error;
goto out_f;
}
- lastdirent->d_off = (u64) file->f_pos;
+ if (put_user(file->f_pos, &lastdirent->d_off))
+ return -EFAULT;
#ifdef DEBUG_GETDENTS
printk("returning %d\n", cnt - buf.count);
#endif
@@ -1953,10 +1937,10 @@ out:
return error;
}
-asmlinkage int irix_ngetdents64(int fd, void *dirent, int cnt, int *eob)
+asmlinkage int irix_ngetdents64(int fd, void __user *dirent, int cnt, int *eob)
{
struct file *file;
- struct irix_dirent64 *lastdirent;
+ struct irix_dirent64 __user *lastdirent;
struct irix_dirent64_callback buf;
int error;
@@ -1978,7 +1962,7 @@ asmlinkage int irix_ngetdents64(int fd, void *dirent, int cnt, int *eob)
goto out_f;
*eob = 0;
- buf.curr = (struct irix_dirent64 *) dirent;
+ buf.curr = (struct irix_dirent64 __user *) dirent;
buf.previous = NULL;
buf.count = cnt;
buf.error = 0;
@@ -1990,7 +1974,8 @@ asmlinkage int irix_ngetdents64(int fd, void *dirent, int cnt, int *eob)
error = buf.error;
goto out_f;
}
- lastdirent->d_off = (u64) file->f_pos;
+ if (put_user(file->f_pos, &lastdirent->d_off))
+ return -EFAULT;
#ifdef DEBUG_GETDENTS
printk("eob=%d returning %d\n", *eob, cnt - buf.count);
#endif
@@ -2053,14 +2038,14 @@ out:
return retval;
}
-asmlinkage int irix_utssys(char *inbuf, int arg, int type, char *outbuf)
+asmlinkage int irix_utssys(char __user *inbuf, int arg, int type, char __user *outbuf)
{
int retval;
switch(type) {
case 0:
/* uname() */
- retval = irix_uname((struct iuname *)inbuf);
+ retval = irix_uname((struct iuname __user *)inbuf);
goto out;
case 2:
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index 0dd0df7a3b04..787ed541d442 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -11,6 +11,7 @@
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
+#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
@@ -25,6 +26,7 @@
#include <linux/module.h>
#include <asm/bootinfo.h>
+#include <asm/cache.h>
#include <asm/compiler.h>
#include <asm/cpu.h>
#include <asm/cpu-features.h>
@@ -43,10 +45,6 @@
#define TICK_SIZE (tick_nsec / 1000)
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
/*
* forward reference
*/
@@ -76,7 +74,7 @@ int (*rtc_set_mmss)(unsigned long);
static unsigned int sll32_usecs_per_cycle;
/* how many counter cycles in a jiffy */
-static unsigned long cycles_per_jiffy;
+static unsigned long cycles_per_jiffy __read_mostly;
/* Cycle counter value at the previous timer interrupt.. */
static unsigned int timerhi, timerlo;
@@ -98,7 +96,10 @@ static unsigned int null_hpt_read(void)
return 0;
}
-static void null_hpt_init(unsigned int count) { /* nothing */ }
+static void null_hpt_init(unsigned int count)
+{
+ /* nothing */
+}
/*
@@ -108,8 +109,10 @@ static void c0_timer_ack(void)
{
unsigned int count;
+#ifndef CONFIG_SOC_PNX8550 /* pnx8550 resets to zero */
/* Ack this timer interrupt and set the next one. */
expirelo += cycles_per_jiffy;
+#endif
write_c0_compare(expirelo);
/* Check to see if we have missed any timer interrupts. */
@@ -224,7 +227,6 @@ int do_settimeofday(struct timespec *tv)
set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
ntp_clear();
-
write_sequnlock_irq(&xtime_lock);
clock_was_set();
return 0;
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index a53b1ed7b386..6f3ff9690686 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -9,7 +9,7 @@
* Copyright (C) 1999 Silicon Graphics, Inc.
* Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
* Copyright (C) 2000, 01 MIPS Technologies, Inc.
- * Copyright (C) 2002, 2003, 2004 Maciej W. Rozycki
+ * Copyright (C) 2002, 2003, 2004, 2005 Maciej W. Rozycki
*/
#include <linux/config.h>
#include <linux/init.h>
@@ -20,12 +20,16 @@
#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/kallsyms.h>
+#include <linux/bootmem.h>
#include <asm/bootinfo.h>
#include <asm/branch.h>
#include <asm/break.h>
#include <asm/cpu.h>
+#include <asm/dsp.h>
#include <asm/fpu.h>
+#include <asm/mipsregs.h>
+#include <asm/mipsmtregs.h>
#include <asm/module.h>
#include <asm/pgtable.h>
#include <asm/ptrace.h>
@@ -54,14 +58,19 @@ extern asmlinkage void handle_tr(void);
extern asmlinkage void handle_fpe(void);
extern asmlinkage void handle_mdmx(void);
extern asmlinkage void handle_watch(void);
+extern asmlinkage void handle_mt(void);
+extern asmlinkage void handle_dsp(void);
extern asmlinkage void handle_mcheck(void);
extern asmlinkage void handle_reserved(void);
-extern int fpu_emulator_cop1Handler(int xcptno, struct pt_regs *xcp,
+extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
struct mips_fpu_soft_struct *ctx);
void (*board_be_init)(void);
int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
+void (*board_nmi_handler_setup)(void);
+void (*board_ejtag_handler_setup)(void);
+void (*board_bind_eic_interrupt)(int irq, int regset);
/*
* These constant is for searching for possible module text segments.
@@ -201,32 +210,47 @@ void show_regs(struct pt_regs *regs)
printk("Status: %08x ", (uint32_t) regs->cp0_status);
- if (regs->cp0_status & ST0_KX)
- printk("KX ");
- if (regs->cp0_status & ST0_SX)
- printk("SX ");
- if (regs->cp0_status & ST0_UX)
- printk("UX ");
- switch (regs->cp0_status & ST0_KSU) {
- case KSU_USER:
- printk("USER ");
- break;
- case KSU_SUPERVISOR:
- printk("SUPERVISOR ");
- break;
- case KSU_KERNEL:
- printk("KERNEL ");
- break;
- default:
- printk("BAD_MODE ");
- break;
+ if (current_cpu_data.isa_level == MIPS_CPU_ISA_I) {
+ if (regs->cp0_status & ST0_KUO)
+ printk("KUo ");
+ if (regs->cp0_status & ST0_IEO)
+ printk("IEo ");
+ if (regs->cp0_status & ST0_KUP)
+ printk("KUp ");
+ if (regs->cp0_status & ST0_IEP)
+ printk("IEp ");
+ if (regs->cp0_status & ST0_KUC)
+ printk("KUc ");
+ if (regs->cp0_status & ST0_IEC)
+ printk("IEc ");
+ } else {
+ if (regs->cp0_status & ST0_KX)
+ printk("KX ");
+ if (regs->cp0_status & ST0_SX)
+ printk("SX ");
+ if (regs->cp0_status & ST0_UX)
+ printk("UX ");
+ switch (regs->cp0_status & ST0_KSU) {
+ case KSU_USER:
+ printk("USER ");
+ break;
+ case KSU_SUPERVISOR:
+ printk("SUPERVISOR ");
+ break;
+ case KSU_KERNEL:
+ printk("KERNEL ");
+ break;
+ default:
+ printk("BAD_MODE ");
+ break;
+ }
+ if (regs->cp0_status & ST0_ERL)
+ printk("ERL ");
+ if (regs->cp0_status & ST0_EXL)
+ printk("EXL ");
+ if (regs->cp0_status & ST0_IE)
+ printk("IE ");
}
- if (regs->cp0_status & ST0_ERL)
- printk("ERL ");
- if (regs->cp0_status & ST0_EXL)
- printk("EXL ");
- if (regs->cp0_status & ST0_IE)
- printk("IE ");
printk("\n");
printk("Cause : %08x\n", cause);
@@ -252,29 +276,18 @@ void show_registers(struct pt_regs *regs)
static DEFINE_SPINLOCK(die_lock);
-NORET_TYPE void __die(const char * str, struct pt_regs * regs,
- const char * file, const char * func, unsigned long line)
+NORET_TYPE void ATTRIB_NORET die(const char * str, struct pt_regs * regs)
{
static int die_counter;
console_verbose();
spin_lock_irq(&die_lock);
- printk("%s", str);
- if (file && func)
- printk(" in %s:%s, line %ld", file, func, line);
- printk("[#%d]:\n", ++die_counter);
+ printk("%s[#%d]:\n", str, ++die_counter);
show_registers(regs);
spin_unlock_irq(&die_lock);
do_exit(SIGSEGV);
}
-void __die_if_kernel(const char * str, struct pt_regs * regs,
- const char * file, const char * func, unsigned long line)
-{
- if (!user_mode(regs))
- __die(str, regs, file, func, line);
-}
-
extern const struct exception_table_entry __start___dbe_table[];
extern const struct exception_table_entry __stop___dbe_table[];
@@ -339,9 +352,9 @@ asmlinkage void do_be(struct pt_regs *regs)
static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode)
{
- unsigned int *epc;
+ unsigned int __user *epc;
- epc = (unsigned int *) regs->cp0_epc +
+ epc = (unsigned int __user *) regs->cp0_epc +
((regs->cp0_cause & CAUSEF_BD) != 0);
if (!get_user(*opcode, epc))
return 0;
@@ -360,6 +373,10 @@ static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode)
#define OFFSET 0x0000ffff
#define LL 0xc0000000
#define SC 0xe0000000
+#define SPEC3 0x7c000000
+#define RD 0x0000f800
+#define FUNC 0x0000003f
+#define RDHWR 0x0000003b
/*
* The ll_bit is cleared by r*_switch.S
@@ -371,7 +388,7 @@ static struct task_struct *ll_task = NULL;
static inline void simulate_ll(struct pt_regs *regs, unsigned int opcode)
{
- unsigned long value, *vaddr;
+ unsigned long value, __user *vaddr;
long offset;
int signal = 0;
@@ -385,7 +402,8 @@ static inline void simulate_ll(struct pt_regs *regs, unsigned int opcode)
offset <<= 16;
offset >>= 16;
- vaddr = (unsigned long *)((long)(regs->regs[(opcode & BASE) >> 21]) + offset);
+ vaddr = (unsigned long __user *)
+ ((unsigned long)(regs->regs[(opcode & BASE) >> 21]) + offset);
if ((unsigned long)vaddr & 3) {
signal = SIGBUS;
@@ -407,9 +425,10 @@ static inline void simulate_ll(struct pt_regs *regs, unsigned int opcode)
preempt_enable();
+ compute_return_epc(regs);
+
regs->regs[(opcode & RT) >> 16] = value;
- compute_return_epc(regs);
return;
sig:
@@ -418,7 +437,8 @@ sig:
static inline void simulate_sc(struct pt_regs *regs, unsigned int opcode)
{
- unsigned long *vaddr, reg;
+ unsigned long __user *vaddr;
+ unsigned long reg;
long offset;
int signal = 0;
@@ -432,7 +452,8 @@ static inline void simulate_sc(struct pt_regs *regs, unsigned int opcode)
offset <<= 16;
offset >>= 16;
- vaddr = (unsigned long *)((long)(regs->regs[(opcode & BASE) >> 21]) + offset);
+ vaddr = (unsigned long __user *)
+ ((unsigned long)(regs->regs[(opcode & BASE) >> 21]) + offset);
reg = (opcode & RT) >> 16;
if ((unsigned long)vaddr & 3) {
@@ -443,9 +464,9 @@ static inline void simulate_sc(struct pt_regs *regs, unsigned int opcode)
preempt_disable();
if (ll_bit == 0 || ll_task != current) {
+ compute_return_epc(regs);
regs->regs[reg] = 0;
preempt_enable();
- compute_return_epc(regs);
return;
}
@@ -456,9 +477,9 @@ static inline void simulate_sc(struct pt_regs *regs, unsigned int opcode)
goto sig;
}
+ compute_return_epc(regs);
regs->regs[reg] = 1;
- compute_return_epc(regs);
return;
sig:
@@ -491,6 +512,37 @@ static inline int simulate_llsc(struct pt_regs *regs)
return -EFAULT; /* Strange things going on ... */
}
+/*
+ * Simulate trapping 'rdhwr' instructions to provide user accessible
+ * registers not implemented in hardware. The only current use of this
+ * is the thread area pointer.
+ */
+static inline int simulate_rdhwr(struct pt_regs *regs)
+{
+ struct thread_info *ti = current->thread_info;
+ unsigned int opcode;
+
+ if (unlikely(get_insn_opcode(regs, &opcode)))
+ return -EFAULT;
+
+ if (unlikely(compute_return_epc(regs)))
+ return -EFAULT;
+
+ if ((opcode & OPCODE) == SPEC3 && (opcode & FUNC) == RDHWR) {
+ int rd = (opcode & RD) >> 11;
+ int rt = (opcode & RT) >> 16;
+ switch (rd) {
+ case 29:
+ regs->regs[rt] = ti->tp_value;
+ break;
+ default:
+ return -EFAULT;
+ }
+ }
+
+ return 0;
+}
+
asmlinkage void do_ov(struct pt_regs *regs)
{
siginfo_t info;
@@ -498,7 +550,7 @@ asmlinkage void do_ov(struct pt_regs *regs)
info.si_code = FPE_INTOVF;
info.si_signo = SIGFPE;
info.si_errno = 0;
- info.si_addr = (void *)regs->cp0_epc;
+ info.si_addr = (void __user *) regs->cp0_epc;
force_sig_info(SIGFPE, &info, current);
}
@@ -512,6 +564,14 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
preempt_disable();
+#ifdef CONFIG_PREEMPT
+ if (!is_fpu_owner()) {
+ /* We might lose fpu before disabling preempt... */
+ own_fpu();
+ BUG_ON(!used_math());
+ restore_fp(current);
+ }
+#endif
/*
* Unimplemented operation exception. If we've got the full
* software emulator on-board, let's use it...
@@ -523,11 +583,18 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
* a bit extreme for what should be an infrequent event.
*/
save_fp(current);
+ /* Ensure 'resume' not overwrite saved fp context again. */
+ lose_fpu();
+
+ preempt_enable();
/* Run the emulator */
- sig = fpu_emulator_cop1Handler (0, regs,
+ sig = fpu_emulator_cop1Handler (regs,
&current->thread.fpu.soft);
+ preempt_disable();
+
+ own_fpu(); /* Using the FPU again. */
/*
* We can't allow the emulated instruction to leave any of
* the cause bit set in $fcr31.
@@ -584,7 +651,7 @@ asmlinkage void do_bp(struct pt_regs *regs)
info.si_code = FPE_INTOVF;
info.si_signo = SIGFPE;
info.si_errno = 0;
- info.si_addr = (void *)regs->cp0_epc;
+ info.si_addr = (void __user *) regs->cp0_epc;
force_sig_info(SIGFPE, &info, current);
break;
default:
@@ -621,7 +688,7 @@ asmlinkage void do_tr(struct pt_regs *regs)
info.si_code = FPE_INTOVF;
info.si_signo = SIGFPE;
info.si_errno = 0;
- info.si_addr = (void *)regs->cp0_epc;
+ info.si_addr = (void __user *) regs->cp0_epc;
force_sig_info(SIGFPE, &info, current);
break;
default:
@@ -637,6 +704,9 @@ asmlinkage void do_ri(struct pt_regs *regs)
if (!simulate_llsc(regs))
return;
+ if (!simulate_rdhwr(regs))
+ return;
+
force_sig(SIGILL, current);
}
@@ -650,11 +720,13 @@ asmlinkage void do_cpu(struct pt_regs *regs)
switch (cpid) {
case 0:
- if (cpu_has_llsc)
- break;
+ if (!cpu_has_llsc)
+ if (!simulate_llsc(regs))
+ return;
- if (!simulate_llsc(regs))
+ if (!simulate_rdhwr(regs))
return;
+
break;
case 1:
@@ -668,15 +740,15 @@ asmlinkage void do_cpu(struct pt_regs *regs)
set_used_math();
}
+ preempt_enable();
+
if (!cpu_has_fpu) {
- int sig = fpu_emulator_cop1Handler(0, regs,
+ int sig = fpu_emulator_cop1Handler(regs,
&current->thread.fpu.soft);
if (sig)
force_sig(sig, current);
}
- preempt_enable();
-
return;
case 2:
@@ -716,6 +788,22 @@ asmlinkage void do_mcheck(struct pt_regs *regs)
(regs->cp0_status & ST0_TS) ? "" : "not ");
}
+asmlinkage void do_mt(struct pt_regs *regs)
+{
+ die_if_kernel("MIPS MT Thread exception in kernel", regs);
+
+ force_sig(SIGILL, current);
+}
+
+
+asmlinkage void do_dsp(struct pt_regs *regs)
+{
+ if (cpu_has_dsp)
+ panic("Unexpected DSP exception\n");
+
+ force_sig(SIGILL, current);
+}
+
asmlinkage void do_reserved(struct pt_regs *regs)
{
/*
@@ -728,6 +816,12 @@ asmlinkage void do_reserved(struct pt_regs *regs)
(regs->cp0_cause & 0x7f) >> 2);
}
+asmlinkage void do_default_vi(struct pt_regs *regs)
+{
+ show_regs(regs);
+ panic("Caught unexpected vectored interrupt.");
+}
+
/*
* Some MIPS CPUs can enable/disable for cache parity detection, but do
* it different ways.
@@ -736,16 +830,12 @@ static inline void parity_protection_init(void)
{
switch (current_cpu_data.cputype) {
case CPU_24K:
- /* 24K cache parity not currently implemented in FPGA */
- printk(KERN_INFO "Disable cache parity protection for "
- "MIPS 24K CPU.\n");
- write_c0_ecc(read_c0_ecc() & ~0x80000000);
- break;
case CPU_5KC:
- /* Set the PE bit (bit 31) in the c0_ecc register. */
- printk(KERN_INFO "Enable cache parity protection for "
- "MIPS 5KC/24K CPUs.\n");
- write_c0_ecc(read_c0_ecc() | 0x80000000);
+ write_c0_ecc(0x80000000);
+ back_to_back_c0_hazard();
+ /* Set the PE bit (bit 31) in the c0_errctl register. */
+ printk(KERN_INFO "Cache parity protection %sabled\n",
+ (read_c0_ecc() & 0x80000000) ? "en" : "dis");
break;
case CPU_20KC:
case CPU_25KF:
@@ -783,7 +873,7 @@ asmlinkage void cache_parity_error(void)
reg_val & (1<<22) ? "E0 " : "");
printk("IDX: 0x%08x\n", reg_val & ((1<<22)-1));
-#if defined(CONFIG_CPU_MIPS32) || defined (CONFIG_CPU_MIPS64)
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
if (reg_val & (1<<22))
printk("DErrAddr0: 0x%0*lx\n", field, read_c0_derraddr0());
@@ -840,7 +930,11 @@ void nmi_exception_handler(struct pt_regs *regs)
while(1) ;
}
+#define VECTORSPACING 0x100 /* for EI/VI mode */
+
+unsigned long ebase;
unsigned long exception_handlers[32];
+unsigned long vi_handlers[64];
/*
* As a side effect of the way this is implemented we're limited
@@ -854,13 +948,156 @@ void *set_except_vector(int n, void *addr)
exception_handlers[n] = handler;
if (n == 0 && cpu_has_divec) {
- *(volatile u32 *)(CAC_BASE + 0x200) = 0x08000000 |
+ *(volatile u32 *)(ebase + 0x200) = 0x08000000 |
(0x03ffffff & (handler >> 2));
- flush_icache_range(CAC_BASE + 0x200, CAC_BASE + 0x204);
+ flush_icache_range(ebase + 0x200, ebase + 0x204);
}
return (void *)old_handler;
}
+#ifdef CONFIG_CPU_MIPSR2
+/*
+ * Shadow register allocation
+ * FIXME: SMP...
+ */
+
+/* MIPSR2 shadow register sets */
+struct shadow_registers {
+ spinlock_t sr_lock; /* */
+ int sr_supported; /* Number of shadow register sets supported */
+ int sr_allocated; /* Bitmap of allocated shadow registers */
+} shadow_registers;
+
+void mips_srs_init(void)
+{
+#ifdef CONFIG_CPU_MIPSR2_SRS
+ shadow_registers.sr_supported = ((read_c0_srsctl() >> 26) & 0x0f) + 1;
+ printk ("%d MIPSR2 register sets available\n", shadow_registers.sr_supported);
+#else
+ shadow_registers.sr_supported = 1;
+#endif
+ shadow_registers.sr_allocated = 1; /* Set 0 used by kernel */
+ spin_lock_init(&shadow_registers.sr_lock);
+}
+
+int mips_srs_max(void)
+{
+ return shadow_registers.sr_supported;
+}
+
+int mips_srs_alloc (void)
+{
+ struct shadow_registers *sr = &shadow_registers;
+ unsigned long flags;
+ int set;
+
+ spin_lock_irqsave(&sr->sr_lock, flags);
+
+ for (set = 0; set < sr->sr_supported; set++) {
+ if ((sr->sr_allocated & (1 << set)) == 0) {
+ sr->sr_allocated |= 1 << set;
+ spin_unlock_irqrestore(&sr->sr_lock, flags);
+ return set;
+ }
+ }
+
+ /* None available */
+ spin_unlock_irqrestore(&sr->sr_lock, flags);
+ return -1;
+}
+
+void mips_srs_free (int set)
+{
+ struct shadow_registers *sr = &shadow_registers;
+ unsigned long flags;
+
+ spin_lock_irqsave(&sr->sr_lock, flags);
+ sr->sr_allocated &= ~(1 << set);
+ spin_unlock_irqrestore(&sr->sr_lock, flags);
+}
+
+void *set_vi_srs_handler (int n, void *addr, int srs)
+{
+ unsigned long handler;
+ unsigned long old_handler = vi_handlers[n];
+ u32 *w;
+ unsigned char *b;
+
+ if (!cpu_has_veic && !cpu_has_vint)
+ BUG();
+
+ if (addr == NULL) {
+ handler = (unsigned long) do_default_vi;
+ srs = 0;
+ }
+ else
+ handler = (unsigned long) addr;
+ vi_handlers[n] = (unsigned long) addr;
+
+ b = (unsigned char *)(ebase + 0x200 + n*VECTORSPACING);
+
+ if (srs >= mips_srs_max())
+ panic("Shadow register set %d not supported", srs);
+
+ if (cpu_has_veic) {
+ if (board_bind_eic_interrupt)
+ board_bind_eic_interrupt (n, srs);
+ }
+ else if (cpu_has_vint) {
+ /* SRSMap is only defined if shadow sets are implemented */
+ if (mips_srs_max() > 1)
+ change_c0_srsmap (0xf << n*4, srs << n*4);
+ }
+
+ if (srs == 0) {
+ /*
+ * If no shadow set is selected then use the default handler
+ * that does normal register saving and a standard interrupt exit
+ */
+
+ extern char except_vec_vi, except_vec_vi_lui;
+ extern char except_vec_vi_ori, except_vec_vi_end;
+ const int handler_len = &except_vec_vi_end - &except_vec_vi;
+ const int lui_offset = &except_vec_vi_lui - &except_vec_vi;
+ const int ori_offset = &except_vec_vi_ori - &except_vec_vi;
+
+ if (handler_len > VECTORSPACING) {
+ /*
+ * Sigh... panicing won't help as the console
+ * is probably not configured :(
+ */
+ panic ("VECTORSPACING too small");
+ }
+
+ memcpy (b, &except_vec_vi, handler_len);
+ w = (u32 *)(b + lui_offset);
+ *w = (*w & 0xffff0000) | (((u32)handler >> 16) & 0xffff);
+ w = (u32 *)(b + ori_offset);
+ *w = (*w & 0xffff0000) | ((u32)handler & 0xffff);
+ flush_icache_range((unsigned long)b, (unsigned long)(b+handler_len));
+ }
+ else {
+ /*
+ * In other cases jump directly to the interrupt handler
+ *
+ * It is the handlers responsibility to save registers if required
+ * (eg hi/lo) and return from the exception using "eret"
+ */
+ w = (u32 *)b;
+ *w++ = 0x08000000 | (((u32)handler >> 2) & 0x03fffff); /* j handler */
+ *w = 0;
+ flush_icache_range((unsigned long)b, (unsigned long)(b+8));
+ }
+
+ return (void *)old_handler;
+}
+
+void *set_vi_handler (int n, void *addr)
+{
+ return set_vi_srs_handler (n, addr, 0);
+}
+#endif
+
/*
* This is used by native signal handling
*/
@@ -912,6 +1149,7 @@ static inline void signal32_init(void)
extern void cpu_cache_init(void);
extern void tlb_init(void);
+extern void flush_tlb_handlers(void);
void __init per_cpu_trap_init(void)
{
@@ -929,15 +1167,32 @@ void __init per_cpu_trap_init(void)
#endif
if (current_cpu_data.isa_level == MIPS_CPU_ISA_IV)
status_set |= ST0_XX;
- change_c0_status(ST0_CU|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX,
+ change_c0_status(ST0_CU|ST0_MX|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX,
status_set);
+ if (cpu_has_dsp)
+ set_c0_status(ST0_MX);
+
+#ifdef CONFIG_CPU_MIPSR2
+ write_c0_hwrena (0x0000000f); /* Allow rdhwr to all registers */
+#endif
+
/*
- * Some MIPS CPUs have a dedicated interrupt vector which reduces the
- * interrupt processing overhead. Use it where available.
+ * Interrupt handling.
*/
- if (cpu_has_divec)
- set_c0_cause(CAUSEF_IV);
+ if (cpu_has_veic || cpu_has_vint) {
+ write_c0_ebase (ebase);
+ /* Setting vector spacing enables EI/VI mode */
+ change_c0_intctl (0x3e0, VECTORSPACING);
+ }
+ if (cpu_has_divec) {
+ if (cpu_has_mipsmt) {
+ unsigned int vpflags = dvpe();
+ set_c0_cause(CAUSEF_IV);
+ evpe(vpflags);
+ } else
+ set_c0_cause(CAUSEF_IV);
+ }
cpu_data[cpu].asid_cache = ASID_FIRST_VERSION;
TLBMISS_HANDLER_SETUP();
@@ -951,13 +1206,41 @@ void __init per_cpu_trap_init(void)
tlb_init();
}
+/* Install CPU exception handler */
+void __init set_handler (unsigned long offset, void *addr, unsigned long size)
+{
+ memcpy((void *)(ebase + offset), addr, size);
+ flush_icache_range(ebase + offset, ebase + offset + size);
+}
+
+/* Install uncached CPU exception handler */
+void __init set_uncached_handler (unsigned long offset, void *addr, unsigned long size)
+{
+#ifdef CONFIG_32BIT
+ unsigned long uncached_ebase = KSEG1ADDR(ebase);
+#endif
+#ifdef CONFIG_64BIT
+ unsigned long uncached_ebase = TO_UNCAC(ebase);
+#endif
+
+ memcpy((void *)(uncached_ebase + offset), addr, size);
+}
+
void __init trap_init(void)
{
extern char except_vec3_generic, except_vec3_r4000;
- extern char except_vec_ejtag_debug;
extern char except_vec4;
unsigned long i;
+ if (cpu_has_veic || cpu_has_vint)
+ ebase = (unsigned long) alloc_bootmem_low_pages (0x200 + VECTORSPACING*64);
+ else
+ ebase = CAC_BASE;
+
+#ifdef CONFIG_CPU_MIPSR2
+ mips_srs_init();
+#endif
+
per_cpu_trap_init();
/*
@@ -965,7 +1248,7 @@ void __init trap_init(void)
* This will be overriden later as suitable for a particular
* configuration.
*/
- memcpy((void *)(CAC_BASE + 0x180), &except_vec3_generic, 0x80);
+ set_handler(0x180, &except_vec3_generic, 0x80);
/*
* Setup default vectors
@@ -977,8 +1260,8 @@ void __init trap_init(void)
* Copy the EJTAG debug exception vector handler code to it's final
* destination.
*/
- if (cpu_has_ejtag)
- memcpy((void *)(CAC_BASE + 0x300), &except_vec_ejtag_debug, 0x80);
+ if (cpu_has_ejtag && board_ejtag_handler_setup)
+ board_ejtag_handler_setup ();
/*
* Only some CPUs have the watch exceptions.
@@ -987,11 +1270,15 @@ void __init trap_init(void)
set_except_vector(23, handle_watch);
/*
- * Some MIPS CPUs have a dedicated interrupt vector which reduces the
- * interrupt processing overhead. Use it where available.
+ * Initialise interrupt handlers
*/
- if (cpu_has_divec)
- memcpy((void *)(CAC_BASE + 0x200), &except_vec4, 0x8);
+ if (cpu_has_veic || cpu_has_vint) {
+ int nvec = cpu_has_veic ? 64 : 8;
+ for (i = 0; i < nvec; i++)
+ set_vi_handler (i, NULL);
+ }
+ else if (cpu_has_divec)
+ set_handler(0x200, &except_vec4, 0x8);
/*
* Some CPUs can enable/disable for cache parity detection, but does
@@ -1023,21 +1310,6 @@ void __init trap_init(void)
set_except_vector(11, handle_cpu);
set_except_vector(12, handle_ov);
set_except_vector(13, handle_tr);
- set_except_vector(22, handle_mdmx);
-
- if (cpu_has_fpu && !cpu_has_nofpuex)
- set_except_vector(15, handle_fpe);
-
- if (cpu_has_mcheck)
- set_except_vector(24, handle_mcheck);
-
- if (cpu_has_vce)
- /* Special exception: R4[04]00 uses also the divec space. */
- memcpy((void *)(CAC_BASE + 0x180), &except_vec3_r4000, 0x100);
- else if (cpu_has_4kex)
- memcpy((void *)(CAC_BASE + 0x180), &except_vec3_generic, 0x80);
- else
- memcpy((void *)(CAC_BASE + 0x080), &except_vec3_generic, 0x80);
if (current_cpu_data.cputype == CPU_R6000 ||
current_cpu_data.cputype == CPU_R6000A) {
@@ -1053,10 +1325,37 @@ void __init trap_init(void)
//set_except_vector(15, handle_ndc);
}
+
+ if (board_nmi_handler_setup)
+ board_nmi_handler_setup();
+
+ if (cpu_has_fpu && !cpu_has_nofpuex)
+ set_except_vector(15, handle_fpe);
+
+ set_except_vector(22, handle_mdmx);
+
+ if (cpu_has_mcheck)
+ set_except_vector(24, handle_mcheck);
+
+ if (cpu_has_mipsmt)
+ set_except_vector(25, handle_mt);
+
+ if (cpu_has_dsp)
+ set_except_vector(26, handle_dsp);
+
+ if (cpu_has_vce)
+ /* Special exception: R4[04]00 uses also the divec space. */
+ memcpy((void *)(CAC_BASE + 0x180), &except_vec3_r4000, 0x100);
+ else if (cpu_has_4kex)
+ memcpy((void *)(CAC_BASE + 0x180), &except_vec3_generic, 0x80);
+ else
+ memcpy((void *)(CAC_BASE + 0x080), &except_vec3_generic, 0x80);
+
signal_init();
#ifdef CONFIG_MIPS32_COMPAT
signal32_init();
#endif
- flush_icache_range(CAC_BASE, CAC_BASE + 0x400);
+ flush_icache_range(ebase, ebase + 0x400);
+ flush_tlb_handlers();
}
diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c
index 36c5212e0928..5b5a3736cbbc 100644
--- a/arch/mips/kernel/unaligned.c
+++ b/arch/mips/kernel/unaligned.c
@@ -94,7 +94,7 @@ unsigned long unaligned_instructions;
#endif
static inline int emulate_load_store_insn(struct pt_regs *regs,
- void *addr, unsigned long pc,
+ void __user *addr, unsigned int __user *pc,
unsigned long **regptr, unsigned long *newvalue)
{
union mips_instruction insn;
@@ -107,7 +107,7 @@ static inline int emulate_load_store_insn(struct pt_regs *regs,
/*
* This load never faults.
*/
- __get_user(insn.word, (unsigned int *)pc);
+ __get_user(insn.word, pc);
switch (insn.i_format.opcode) {
/*
@@ -494,8 +494,8 @@ asmlinkage void do_ade(struct pt_regs *regs)
{
unsigned long *regptr, newval;
extern int do_dsemulret(struct pt_regs *);
+ unsigned int __user *pc;
mm_segment_t seg;
- unsigned long pc;
/*
* Address errors may be deliberately induced by the FPU emulator to
@@ -515,7 +515,7 @@ asmlinkage void do_ade(struct pt_regs *regs)
if ((regs->cp0_badvaddr == regs->cp0_epc) || (regs->cp0_epc & 0x1))
goto sigbus;
- pc = exception_epc(regs);
+ pc = (unsigned int __user *) exception_epc(regs);
if ((current->thread.mflags & MF_FIXADE) == 0)
goto sigbus;
@@ -526,7 +526,7 @@ asmlinkage void do_ade(struct pt_regs *regs)
seg = get_fs();
if (!user_mode(regs))
set_fs(KERNEL_DS);
- if (!emulate_load_store_insn(regs, (void *)regs->cp0_badvaddr, pc,
+ if (!emulate_load_store_insn(regs, (void __user *)regs->cp0_badvaddr, pc,
&regptr, &newval)) {
compute_return_epc(regs);
/*
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index 482ac310c937..25cc856d8e7e 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -54,13 +54,6 @@ SECTIONS
*(.data)
- /* Align the initial ramdisk image (INITRD) on page boundaries. */
- . = ALIGN(4096);
- __rd_start = .;
- *(.initrd)
- . = ALIGN(4096);
- __rd_end = .;
-
CONSTRUCTORS
}
_gp = . + 0x8000;
@@ -96,12 +89,6 @@ SECTIONS
.init.setup : { *(.init.setup) }
__setup_end = .;
- .early_initcall.init : {
- __earlyinitcall_start = .;
- *(.initcall.early1.init)
- }
- __earlyinitcall_end = .;
-
__initcall_start = .;
.initcall.init : {
*(.initcall1.init)
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
new file mode 100644
index 000000000000..97fefcc9dbe7
--- /dev/null
+++ b/arch/mips/kernel/vpe.c
@@ -0,0 +1,1296 @@
+/*
+ * Copyright (C) 2004, 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+
+/*
+ * VPE support module
+ *
+ * Provides support for loading a MIPS SP program on VPE1.
+ * The SP enviroment is rather simple, no tlb's. It needs to be relocatable
+ * (or partially linked). You should initialise your stack in the startup
+ * code. This loader looks for the symbol __start and sets up
+ * execution to resume from there. The MIPS SDE kit contains suitable examples.
+ *
+ * To load and run, simply cat a SP 'program file' to /dev/vpe1.
+ * i.e cat spapp >/dev/vpe1.
+ *
+ * You'll need to have the following device files.
+ * mknod /dev/vpe0 c 63 0
+ * mknod /dev/vpe1 c 63 1
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/vmalloc.h>
+#include <linux/elf.h>
+#include <linux/seq_file.h>
+#include <linux/syscalls.h>
+#include <linux/moduleloader.h>
+#include <linux/interrupt.h>
+#include <linux/poll.h>
+#include <linux/bootmem.h>
+#include <asm/mipsregs.h>
+#include <asm/mipsmtregs.h>
+#include <asm/cacheflush.h>
+#include <asm/atomic.h>
+#include <asm/cpu.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+
+typedef void *vpe_handle;
+
+// defined here because the kernel module loader doesn't have
+// anything to do with it.
+#define SHN_MIPS_SCOMMON 0xff03
+
+#ifndef ARCH_SHF_SMALL
+#define ARCH_SHF_SMALL 0
+#endif
+
+/* If this is set, the section belongs in the init part of the module */
+#define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1))
+
+// temp number,
+#define VPE_MAJOR 63
+
+static char module_name[] = "vpe";
+static int major = 0;
+
+/* grab the likely amount of memory we will need. */
+#ifdef CONFIG_MIPS_VPE_LOADER_TOM
+#define P_SIZE (2 * 1024 * 1024)
+#else
+/* add an overhead to the max kmalloc size for non-striped symbols/etc */
+#define P_SIZE (256 * 1024)
+#endif
+
+#define MAX_VPES 16
+
+enum vpe_state {
+ VPE_STATE_UNUSED = 0,
+ VPE_STATE_INUSE,
+ VPE_STATE_RUNNING
+};
+
+enum tc_state {
+ TC_STATE_UNUSED = 0,
+ TC_STATE_INUSE,
+ TC_STATE_RUNNING,
+ TC_STATE_DYNAMIC
+};
+
+struct vpe;
+typedef struct tc {
+ enum tc_state state;
+ int index;
+
+ /* parent VPE */
+ struct vpe *pvpe;
+
+ /* The list of TC's with this VPE */
+ struct list_head tc;
+
+ /* The global list of tc's */
+ struct list_head list;
+} tc_t;
+
+typedef struct vpe {
+ enum vpe_state state;
+
+ /* (device) minor associated with this vpe */
+ int minor;
+
+ /* elfloader stuff */
+ void *load_addr;
+ u32 len;
+ char *pbuffer;
+ u32 plen;
+
+ unsigned long __start;
+
+ /* tc's associated with this vpe */
+ struct list_head tc;
+
+ /* The list of vpe's */
+ struct list_head list;
+
+ /* shared symbol address */
+ void *shared_ptr;
+} vpe_t;
+
+struct vpecontrol_ {
+ /* Virtual processing elements */
+ struct list_head vpe_list;
+
+ /* Thread contexts */
+ struct list_head tc_list;
+} vpecontrol;
+
+static void release_progmem(void *ptr);
+static void dump_vpe(vpe_t * v);
+extern void save_gp_address(unsigned int secbase, unsigned int rel);
+
+/* get the vpe associated with this minor */
+struct vpe *get_vpe(int minor)
+{
+ struct vpe *v;
+
+ list_for_each_entry(v, &vpecontrol.vpe_list, list) {
+ if (v->minor == minor)
+ return v;
+ }
+
+ printk(KERN_DEBUG "VPE: get_vpe minor %d not found\n", minor);
+ return NULL;
+}
+
+/* get the vpe associated with this minor */
+struct tc *get_tc(int index)
+{
+ struct tc *t;
+
+ list_for_each_entry(t, &vpecontrol.tc_list, list) {
+ if (t->index == index)
+ return t;
+ }
+
+ printk(KERN_DEBUG "VPE: get_tc index %d not found\n", index);
+
+ return NULL;
+}
+
+struct tc *get_tc_unused(void)
+{
+ struct tc *t;
+
+ list_for_each_entry(t, &vpecontrol.tc_list, list) {
+ if (t->state == TC_STATE_UNUSED)
+ return t;
+ }
+
+ printk(KERN_DEBUG "VPE: All TC's are in use\n");
+
+ return NULL;
+}
+
+/* allocate a vpe and associate it with this minor (or index) */
+struct vpe *alloc_vpe(int minor)
+{
+ struct vpe *v;
+
+ if ((v = kmalloc(sizeof(struct vpe), GFP_KERNEL)) == NULL) {
+ printk(KERN_WARNING "VPE: alloc_vpe no mem\n");
+ return NULL;
+ }
+
+ memset(v, 0, sizeof(struct vpe));
+
+ INIT_LIST_HEAD(&v->tc);
+ list_add_tail(&v->list, &vpecontrol.vpe_list);
+
+ v->minor = minor;
+ return v;
+}
+
+/* allocate a tc. At startup only tc0 is running, all other can be halted. */
+struct tc *alloc_tc(int index)
+{
+ struct tc *t;
+
+ if ((t = kmalloc(sizeof(struct tc), GFP_KERNEL)) == NULL) {
+ printk(KERN_WARNING "VPE: alloc_tc no mem\n");
+ return NULL;
+ }
+
+ memset(t, 0, sizeof(struct tc));
+
+ INIT_LIST_HEAD(&t->tc);
+ list_add_tail(&t->list, &vpecontrol.tc_list);
+
+ t->index = index;
+
+ return t;
+}
+
+/* clean up and free everything */
+void release_vpe(struct vpe *v)
+{
+ list_del(&v->list);
+ if (v->load_addr)
+ release_progmem(v);
+ kfree(v);
+}
+
+void dump_mtregs(void)
+{
+ unsigned long val;
+
+ val = read_c0_config3();
+ printk("config3 0x%lx MT %ld\n", val,
+ (val & CONFIG3_MT) >> CONFIG3_MT_SHIFT);
+
+ val = read_c0_mvpconf0();
+ printk("mvpconf0 0x%lx, PVPE %ld PTC %ld M %ld\n", val,
+ (val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT,
+ val & MVPCONF0_PTC, (val & MVPCONF0_M) >> MVPCONF0_M_SHIFT);
+
+ val = read_c0_mvpcontrol();
+ printk("MVPControl 0x%lx, STLB %ld VPC %ld EVP %ld\n", val,
+ (val & MVPCONTROL_STLB) >> MVPCONTROL_STLB_SHIFT,
+ (val & MVPCONTROL_VPC) >> MVPCONTROL_VPC_SHIFT,
+ (val & MVPCONTROL_EVP));
+
+ val = read_c0_vpeconf0();
+ printk("VPEConf0 0x%lx MVP %ld\n", val,
+ (val & VPECONF0_MVP) >> VPECONF0_MVP_SHIFT);
+}
+
+/* Find some VPE program space */
+static void *alloc_progmem(u32 len)
+{
+#ifdef CONFIG_MIPS_VPE_LOADER_TOM
+ /* this means you must tell linux to use less memory than you physically have */
+ return (void *)((max_pfn * PAGE_SIZE) + KSEG0);
+#else
+ // simple grab some mem for now
+ return kmalloc(len, GFP_KERNEL);
+#endif
+}
+
+static void release_progmem(void *ptr)
+{
+#ifndef CONFIG_MIPS_VPE_LOADER_TOM
+ kfree(ptr);
+#endif
+}
+
+/* Update size with this section: return offset. */
+static long get_offset(unsigned long *size, Elf_Shdr * sechdr)
+{
+ long ret;
+
+ ret = ALIGN(*size, sechdr->sh_addralign ? : 1);
+ *size = ret + sechdr->sh_size;
+ return ret;
+}
+
+/* Lay out the SHF_ALLOC sections in a way not dissimilar to how ld
+ might -- code, read-only data, read-write data, small data. Tally
+ sizes, and place the offsets into sh_entsize fields: high bit means it
+ belongs in init. */
+static void layout_sections(struct module *mod, const Elf_Ehdr * hdr,
+ Elf_Shdr * sechdrs, const char *secstrings)
+{
+ static unsigned long const masks[][2] = {
+ /* NOTE: all executable code must be the first section
+ * in this array; otherwise modify the text_size
+ * finder in the two loops below */
+ {SHF_EXECINSTR | SHF_ALLOC, ARCH_SHF_SMALL},
+ {SHF_ALLOC, SHF_WRITE | ARCH_SHF_SMALL},
+ {SHF_WRITE | SHF_ALLOC, ARCH_SHF_SMALL},
+ {ARCH_SHF_SMALL | SHF_ALLOC, 0}
+ };
+ unsigned int m, i;
+
+ for (i = 0; i < hdr->e_shnum; i++)
+ sechdrs[i].sh_entsize = ~0UL;
+
+ for (m = 0; m < ARRAY_SIZE(masks); ++m) {
+ for (i = 0; i < hdr->e_shnum; ++i) {
+ Elf_Shdr *s = &sechdrs[i];
+
+ // || strncmp(secstrings + s->sh_name, ".init", 5) == 0)
+ if ((s->sh_flags & masks[m][0]) != masks[m][0]
+ || (s->sh_flags & masks[m][1])
+ || s->sh_entsize != ~0UL)
+ continue;
+ s->sh_entsize = get_offset(&mod->core_size, s);
+ }
+
+ if (m == 0)
+ mod->core_text_size = mod->core_size;
+
+ }
+}
+
+
+/* from module-elf32.c, but subverted a little */
+
+struct mips_hi16 {
+ struct mips_hi16 *next;
+ Elf32_Addr *addr;
+ Elf32_Addr value;
+};
+
+static struct mips_hi16 *mips_hi16_list;
+static unsigned int gp_offs, gp_addr;
+
+static int apply_r_mips_none(struct module *me, uint32_t *location,
+ Elf32_Addr v)
+{
+ return 0;
+}
+
+static int apply_r_mips_gprel16(struct module *me, uint32_t *location,
+ Elf32_Addr v)
+{
+ int rel;
+
+ if( !(*location & 0xffff) ) {
+ rel = (int)v - gp_addr;
+ }
+ else {
+ /* .sbss + gp(relative) + offset */
+ /* kludge! */
+ rel = (int)(short)((int)v + gp_offs +
+ (int)(short)(*location & 0xffff) - gp_addr);
+ }
+
+ if( (rel > 32768) || (rel < -32768) ) {
+ printk(KERN_ERR
+ "apply_r_mips_gprel16: relative address out of range 0x%x %d\n",
+ rel, rel);
+ return -ENOEXEC;
+ }
+
+ *location = (*location & 0xffff0000) | (rel & 0xffff);
+
+ return 0;
+}
+
+static int apply_r_mips_pc16(struct module *me, uint32_t *location,
+ Elf32_Addr v)
+{
+ int rel;
+ rel = (((unsigned int)v - (unsigned int)location));
+ rel >>= 2; // because the offset is in _instructions_ not bytes.
+ rel -= 1; // and one instruction less due to the branch delay slot.
+
+ if( (rel > 32768) || (rel < -32768) ) {
+ printk(KERN_ERR
+ "apply_r_mips_pc16: relative address out of range 0x%x\n", rel);
+ return -ENOEXEC;
+ }
+
+ *location = (*location & 0xffff0000) | (rel & 0xffff);
+
+ return 0;
+}
+
+static int apply_r_mips_32(struct module *me, uint32_t *location,
+ Elf32_Addr v)
+{
+ *location += v;
+
+ return 0;
+}
+
+static int apply_r_mips_26(struct module *me, uint32_t *location,
+ Elf32_Addr v)
+{
+ if (v % 4) {
+ printk(KERN_ERR "module %s: dangerous relocation mod4\n", me->name);
+ return -ENOEXEC;
+ }
+
+/* Not desperately convinced this is a good check of an overflow condition
+ anyway. But it gets in the way of handling undefined weak symbols which
+ we want to set to zero.
+ if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
+ printk(KERN_ERR
+ "module %s: relocation overflow\n",
+ me->name);
+ return -ENOEXEC;
+ }
+*/
+
+ *location = (*location & ~0x03ffffff) |
+ ((*location + (v >> 2)) & 0x03ffffff);
+ return 0;
+}
+
+static int apply_r_mips_hi16(struct module *me, uint32_t *location,
+ Elf32_Addr v)
+{
+ struct mips_hi16 *n;
+
+ /*
+ * We cannot relocate this one now because we don't know the value of
+ * the carry we need to add. Save the information, and let LO16 do the
+ * actual relocation.
+ */
+ n = kmalloc(sizeof *n, GFP_KERNEL);
+ if (!n)
+ return -ENOMEM;
+
+ n->addr = location;
+ n->value = v;
+ n->next = mips_hi16_list;
+ mips_hi16_list = n;
+
+ return 0;
+}
+
+static int apply_r_mips_lo16(struct module *me, uint32_t *location,
+ Elf32_Addr v)
+{
+ unsigned long insnlo = *location;
+ Elf32_Addr val, vallo;
+
+ /* Sign extend the addend we extract from the lo insn. */
+ vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
+
+ if (mips_hi16_list != NULL) {
+ struct mips_hi16 *l;
+
+ l = mips_hi16_list;
+ while (l != NULL) {
+ struct mips_hi16 *next;
+ unsigned long insn;
+
+ /*
+ * The value for the HI16 had best be the same.
+ */
+ if (v != l->value) {
+ printk("%d != %d\n", v, l->value);
+ goto out_danger;
+ }
+
+
+ /*
+ * Do the HI16 relocation. Note that we actually don't
+ * need to know anything about the LO16 itself, except
+ * where to find the low 16 bits of the addend needed
+ * by the LO16.
+ */
+ insn = *l->addr;
+ val = ((insn & 0xffff) << 16) + vallo;
+ val += v;
+
+ /*
+ * Account for the sign extension that will happen in
+ * the low bits.
+ */
+ val = ((val >> 16) + ((val & 0x8000) != 0)) & 0xffff;
+
+ insn = (insn & ~0xffff) | val;
+ *l->addr = insn;
+
+ next = l->next;
+ kfree(l);
+ l = next;
+ }
+
+ mips_hi16_list = NULL;
+ }
+
+ /*
+ * Ok, we're done with the HI16 relocs. Now deal with the LO16.
+ */
+ val = v + vallo;
+ insnlo = (insnlo & ~0xffff) | (val & 0xffff);
+ *location = insnlo;
+
+ return 0;
+
+out_danger:
+ printk(KERN_ERR "module %s: dangerous " "relocation\n", me->name);
+
+ return -ENOEXEC;
+}
+
+static int (*reloc_handlers[]) (struct module *me, uint32_t *location,
+ Elf32_Addr v) = {
+ [R_MIPS_NONE] = apply_r_mips_none,
+ [R_MIPS_32] = apply_r_mips_32,
+ [R_MIPS_26] = apply_r_mips_26,
+ [R_MIPS_HI16] = apply_r_mips_hi16,
+ [R_MIPS_LO16] = apply_r_mips_lo16,
+ [R_MIPS_GPREL16] = apply_r_mips_gprel16,
+ [R_MIPS_PC16] = apply_r_mips_pc16
+};
+
+
+int apply_relocations(Elf32_Shdr *sechdrs,
+ const char *strtab,
+ unsigned int symindex,
+ unsigned int relsec,
+ struct module *me)
+{
+ Elf32_Rel *rel = (void *) sechdrs[relsec].sh_addr;
+ Elf32_Sym *sym;
+ uint32_t *location;
+ unsigned int i;
+ Elf32_Addr v;
+ int res;
+
+ for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+ Elf32_Word r_info = rel[i].r_info;
+
+ /* This is where to make the change */
+ location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+ + rel[i].r_offset;
+ /* This is the symbol it is referring to */
+ sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
+ + ELF32_R_SYM(r_info);
+
+ if (!sym->st_value) {
+ printk(KERN_DEBUG "%s: undefined weak symbol %s\n",
+ me->name, strtab + sym->st_name);
+ /* just print the warning, dont barf */
+ }
+
+ v = sym->st_value;
+
+ res = reloc_handlers[ELF32_R_TYPE(r_info)](me, location, v);
+ if( res ) {
+ printk(KERN_DEBUG
+ "relocation error 0x%x sym refer <%s> value 0x%x "
+ "type 0x%x r_info 0x%x\n",
+ (unsigned int)location, strtab + sym->st_name, v,
+ r_info, ELF32_R_TYPE(r_info));
+ }
+
+ if (res)
+ return res;
+ }
+
+ return 0;
+}
+
+void save_gp_address(unsigned int secbase, unsigned int rel)
+{
+ gp_addr = secbase + rel;
+ gp_offs = gp_addr - (secbase & 0xffff0000);
+}
+/* end module-elf32.c */
+
+
+
+/* Change all symbols so that sh_value encodes the pointer directly. */
+static int simplify_symbols(Elf_Shdr * sechdrs,
+ unsigned int symindex,
+ const char *strtab,
+ const char *secstrings,
+ unsigned int nsecs, struct module *mod)
+{
+ Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
+ unsigned long secbase, bssbase = 0;
+ unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
+ int ret = 0, size;
+
+ /* find the .bss section for COMMON symbols */
+ for (i = 0; i < nsecs; i++) {
+ if (strncmp(secstrings + sechdrs[i].sh_name, ".bss", 4) == 0)
+ bssbase = sechdrs[i].sh_addr;
+ }
+
+ for (i = 1; i < n; i++) {
+ switch (sym[i].st_shndx) {
+ case SHN_COMMON:
+ /* Allocate space for the symbol in the .bss section. st_value is currently size.
+ We want it to have the address of the symbol. */
+
+ size = sym[i].st_value;
+ sym[i].st_value = bssbase;
+
+ bssbase += size;
+ break;
+
+ case SHN_ABS:
+ /* Don't need to do anything */
+ break;
+
+ case SHN_UNDEF:
+ /* ret = -ENOENT; */
+ break;
+
+ case SHN_MIPS_SCOMMON:
+
+ printk(KERN_DEBUG
+ "simplify_symbols: ignoring SHN_MIPS_SCOMMON symbol <%s> st_shndx %d\n",
+ strtab + sym[i].st_name, sym[i].st_shndx);
+
+ // .sbss section
+ break;
+
+ default:
+ secbase = sechdrs[sym[i].st_shndx].sh_addr;
+
+ if (strncmp(strtab + sym[i].st_name, "_gp", 3) == 0) {
+ save_gp_address(secbase, sym[i].st_value);
+ }
+
+ sym[i].st_value += secbase;
+ break;
+ }
+
+ }
+
+ return ret;
+}
+
+#ifdef DEBUG_ELFLOADER
+static void dump_elfsymbols(Elf_Shdr * sechdrs, unsigned int symindex,
+ const char *strtab, struct module *mod)
+{
+ Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
+ unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
+
+ printk(KERN_DEBUG "dump_elfsymbols: n %d\n", n);
+ for (i = 1; i < n; i++) {
+ printk(KERN_DEBUG " i %d name <%s> 0x%x\n", i,
+ strtab + sym[i].st_name, sym[i].st_value);
+ }
+}
+#endif
+
+static void dump_tc(struct tc *t)
+{
+ printk(KERN_WARNING "VPE: TC index %d TCStatus 0x%lx halt 0x%lx\n",
+ t->index, read_tc_c0_tcstatus(), read_tc_c0_tchalt());
+ printk(KERN_WARNING "VPE: tcrestart 0x%lx\n", read_tc_c0_tcrestart());
+}
+
+static void dump_tclist(void)
+{
+ struct tc *t;
+
+ list_for_each_entry(t, &vpecontrol.tc_list, list) {
+ dump_tc(t);
+ }
+}
+
+/* We are prepared so configure and start the VPE... */
+int vpe_run(vpe_t * v)
+{
+ unsigned long val;
+ struct tc *t;
+
+ /* check we are the Master VPE */
+ val = read_c0_vpeconf0();
+ if (!(val & VPECONF0_MVP)) {
+ printk(KERN_WARNING
+ "VPE: only Master VPE's are allowed to configure MT\n");
+ return -1;
+ }
+
+ /* disable MT (using dvpe) */
+ dvpe();
+
+ /* Put MVPE's into 'configuration state' */
+ set_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ if (!list_empty(&v->tc)) {
+ if ((t = list_entry(v->tc.next, struct tc, tc)) == NULL) {
+ printk(KERN_WARNING "VPE: TC %d is already in use.\n",
+ t->index);
+ return -ENOEXEC;
+ }
+ } else {
+ printk(KERN_WARNING "VPE: No TC's associated with VPE %d\n",
+ v->minor);
+ return -ENOEXEC;
+ }
+
+ settc(t->index);
+
+ val = read_vpe_c0_vpeconf0();
+
+ /* should check it is halted, and not activated */
+ if ((read_tc_c0_tcstatus() & TCSTATUS_A) || !(read_tc_c0_tchalt() & TCHALT_H)) {
+ printk(KERN_WARNING "VPE: TC %d is already doing something!\n",
+ t->index);
+
+ dump_tclist();
+ return -ENOEXEC;
+ }
+
+ /* Write the address we want it to start running from in the TCPC register. */
+ write_tc_c0_tcrestart((unsigned long)v->__start);
+
+ /* write the sivc_info address to tccontext */
+ write_tc_c0_tccontext((unsigned long)0);
+
+ /* Set up the XTC bit in vpeconf0 to point at our tc */
+ write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | (t->index << VPECONF0_XTC_SHIFT));
+
+ /* mark the TC as activated, not interrupt exempt and not dynamically allocatable */
+ val = read_tc_c0_tcstatus();
+ val = (val & ~(TCSTATUS_DA | TCSTATUS_IXMT)) | TCSTATUS_A;
+ write_tc_c0_tcstatus(val);
+
+ write_tc_c0_tchalt(read_tc_c0_tchalt() & ~TCHALT_H);
+
+ /* set up VPE1 */
+ write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE); // no multiple TC's
+ write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA); // enable this VPE
+
+ /*
+ * The sde-kit passes 'memsize' to __start in $a3, so set something
+ * here...
+ * Or set $a3 (register 7) to zero and define DFLT_STACK_SIZE and
+ * DFLT_HEAP_SIZE when you compile your program
+ */
+
+ mttgpr(7, 0);
+
+ /* set config to be the same as vpe0, particularly kseg0 coherency alg */
+ write_vpe_c0_config(read_c0_config());
+
+ /* clear out any left overs from a previous program */
+ write_vpe_c0_cause(0);
+
+ /* take system out of configuration state */
+ clear_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ /* clear interrupts enabled IE, ERL, EXL, and KSU from c0 status */
+ write_vpe_c0_status(read_vpe_c0_status() & ~(ST0_ERL | ST0_KSU | ST0_IE | ST0_EXL));
+
+ /* set it running */
+ evpe(EVPE_ENABLE);
+
+ return 0;
+}
+
+static unsigned long find_vpe_symbols(vpe_t * v, Elf_Shdr * sechdrs,
+ unsigned int symindex, const char *strtab,
+ struct module *mod)
+{
+ Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
+ unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
+
+ for (i = 1; i < n; i++) {
+ if (strcmp(strtab + sym[i].st_name, "__start") == 0) {
+ v->__start = sym[i].st_value;
+ }
+
+ if (strcmp(strtab + sym[i].st_name, "vpe_shared") == 0) {
+ v->shared_ptr = (void *)sym[i].st_value;
+ }
+ }
+
+ return 0;
+}
+
+/* Allocates a VPE with some program code space(the load address), copies the contents
+ of the program (p)buffer performing relocatations/etc, free's it when finished.
+*/
+int vpe_elfload(vpe_t * v)
+{
+ Elf_Ehdr *hdr;
+ Elf_Shdr *sechdrs;
+ long err = 0;
+ char *secstrings, *strtab = NULL;
+ unsigned int len, i, symindex = 0, strindex = 0;
+
+ struct module mod; // so we can re-use the relocations code
+
+ memset(&mod, 0, sizeof(struct module));
+ strcpy(mod.name, "VPE dummy prog module");
+
+ hdr = (Elf_Ehdr *) v->pbuffer;
+ len = v->plen;
+
+ /* Sanity checks against insmoding binaries or wrong arch,
+ weird elf version */
+ if (memcmp(hdr->e_ident, ELFMAG, 4) != 0
+ || hdr->e_type != ET_REL || !elf_check_arch(hdr)
+ || hdr->e_shentsize != sizeof(*sechdrs)) {
+ printk(KERN_WARNING
+ "VPE program, wrong arch or weird elf version\n");
+
+ return -ENOEXEC;
+ }
+
+ if (len < hdr->e_shoff + hdr->e_shnum * sizeof(Elf_Shdr)) {
+ printk(KERN_ERR "VPE program length %u truncated\n", len);
+ return -ENOEXEC;
+ }
+
+ /* Convenience variables */
+ sechdrs = (void *)hdr + hdr->e_shoff;
+ secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+ sechdrs[0].sh_addr = 0;
+
+ /* And these should exist, but gcc whinges if we don't init them */
+ symindex = strindex = 0;
+
+ for (i = 1; i < hdr->e_shnum; i++) {
+
+ if (sechdrs[i].sh_type != SHT_NOBITS
+ && len < sechdrs[i].sh_offset + sechdrs[i].sh_size) {
+ printk(KERN_ERR "VPE program length %u truncated\n",
+ len);
+ return -ENOEXEC;
+ }
+
+ /* Mark all sections sh_addr with their address in the
+ temporary image. */
+ sechdrs[i].sh_addr = (size_t) hdr + sechdrs[i].sh_offset;
+
+ /* Internal symbols and strings. */
+ if (sechdrs[i].sh_type == SHT_SYMTAB) {
+ symindex = i;
+ strindex = sechdrs[i].sh_link;
+ strtab = (char *)hdr + sechdrs[strindex].sh_offset;
+ }
+ }
+
+ layout_sections(&mod, hdr, sechdrs, secstrings);
+
+ v->load_addr = alloc_progmem(mod.core_size);
+ memset(v->load_addr, 0, mod.core_size);
+
+ printk("VPE elf_loader: loading to %p\n", v->load_addr);
+
+ for (i = 0; i < hdr->e_shnum; i++) {
+ void *dest;
+
+ if (!(sechdrs[i].sh_flags & SHF_ALLOC))
+ continue;
+
+ dest = v->load_addr + sechdrs[i].sh_entsize;
+
+ if (sechdrs[i].sh_type != SHT_NOBITS)
+ memcpy(dest, (void *)sechdrs[i].sh_addr,
+ sechdrs[i].sh_size);
+ /* Update sh_addr to point to copy in image. */
+ sechdrs[i].sh_addr = (unsigned long)dest;
+ }
+
+ /* Fix up syms, so that st_value is a pointer to location. */
+ err =
+ simplify_symbols(sechdrs, symindex, strtab, secstrings,
+ hdr->e_shnum, &mod);
+ if (err < 0) {
+ printk(KERN_WARNING "VPE: unable to simplify symbols\n");
+ goto cleanup;
+ }
+
+ /* Now do relocations. */
+ for (i = 1; i < hdr->e_shnum; i++) {
+ const char *strtab = (char *)sechdrs[strindex].sh_addr;
+ unsigned int info = sechdrs[i].sh_info;
+
+ /* Not a valid relocation section? */
+ if (info >= hdr->e_shnum)
+ continue;
+
+ /* Don't bother with non-allocated sections */
+ if (!(sechdrs[info].sh_flags & SHF_ALLOC))
+ continue;
+
+ if (sechdrs[i].sh_type == SHT_REL)
+ err =
+ apply_relocations(sechdrs, strtab, symindex, i, &mod);
+ else if (sechdrs[i].sh_type == SHT_RELA)
+ err = apply_relocate_add(sechdrs, strtab, symindex, i,
+ &mod);
+ if (err < 0) {
+ printk(KERN_WARNING
+ "vpe_elfload: error in relocations err %ld\n",
+ err);
+ goto cleanup;
+ }
+ }
+
+ /* make sure it's physically written out */
+ flush_icache_range((unsigned long)v->load_addr,
+ (unsigned long)v->load_addr + v->len);
+
+ if ((find_vpe_symbols(v, sechdrs, symindex, strtab, &mod)) < 0) {
+
+ printk(KERN_WARNING
+ "VPE: program doesn't contain __start or vpe_shared symbols\n");
+ err = -ENOEXEC;
+ }
+
+ printk(" elf loaded\n");
+
+cleanup:
+ return err;
+}
+
+static void dump_vpe(vpe_t * v)
+{
+ struct tc *t;
+
+ printk(KERN_DEBUG "VPEControl 0x%lx\n", read_vpe_c0_vpecontrol());
+ printk(KERN_DEBUG "VPEConf0 0x%lx\n", read_vpe_c0_vpeconf0());
+
+ list_for_each_entry(t, &vpecontrol.tc_list, list) {
+ dump_tc(t);
+ }
+}
+
+/* checks for VPE is unused and gets ready to load program */
+static int vpe_open(struct inode *inode, struct file *filp)
+{
+ int minor;
+ vpe_t *v;
+
+ /* assume only 1 device at the mo. */
+ if ((minor = MINOR(inode->i_rdev)) != 1) {
+ printk(KERN_WARNING "VPE: only vpe1 is supported\n");
+ return -ENODEV;
+ }
+
+ if ((v = get_vpe(minor)) == NULL) {
+ printk(KERN_WARNING "VPE: unable to get vpe\n");
+ return -ENODEV;
+ }
+
+ if (v->state != VPE_STATE_UNUSED) {
+ unsigned long tmp;
+ struct tc *t;
+
+ printk(KERN_WARNING "VPE: device %d already in use\n", minor);
+
+ dvpe();
+ dump_vpe(v);
+
+ printk(KERN_WARNING "VPE: re-initialising %d\n", minor);
+
+ release_progmem(v->load_addr);
+
+ t = get_tc(minor);
+ settc(minor);
+ tmp = read_tc_c0_tcstatus();
+
+ /* mark not allocated and not dynamically allocatable */
+ tmp &= ~(TCSTATUS_A | TCSTATUS_DA);
+ tmp |= TCSTATUS_IXMT; /* interrupt exempt */
+ write_tc_c0_tcstatus(tmp);
+
+ write_tc_c0_tchalt(TCHALT_H);
+
+ }
+
+ // allocate it so when we get write ops we know it's expected.
+ v->state = VPE_STATE_INUSE;
+
+ /* this of-course trashes what was there before... */
+ v->pbuffer = vmalloc(P_SIZE);
+ v->plen = P_SIZE;
+ v->load_addr = NULL;
+ v->len = 0;
+
+ return 0;
+}
+
+static int vpe_release(struct inode *inode, struct file *filp)
+{
+ int minor, ret = 0;
+ vpe_t *v;
+ Elf_Ehdr *hdr;
+
+ minor = MINOR(inode->i_rdev);
+ if ((v = get_vpe(minor)) == NULL)
+ return -ENODEV;
+
+ // simple case of fire and forget, so tell the VPE to run...
+
+ hdr = (Elf_Ehdr *) v->pbuffer;
+ if (memcmp(hdr->e_ident, ELFMAG, 4) == 0) {
+ if (vpe_elfload(v) >= 0)
+ vpe_run(v);
+ else {
+ printk(KERN_WARNING "VPE: ELF load failed.\n");
+ ret = -ENOEXEC;
+ }
+ } else {
+ printk(KERN_WARNING "VPE: only elf files are supported\n");
+ ret = -ENOEXEC;
+ }
+
+ // cleanup any temp buffers
+ if (v->pbuffer)
+ vfree(v->pbuffer);
+ v->plen = 0;
+ return ret;
+}
+
+static ssize_t vpe_write(struct file *file, const char __user * buffer,
+ size_t count, loff_t * ppos)
+{
+ int minor;
+ size_t ret = count;
+ vpe_t *v;
+
+ minor = MINOR(file->f_dentry->d_inode->i_rdev);
+ if ((v = get_vpe(minor)) == NULL)
+ return -ENODEV;
+
+ if (v->pbuffer == NULL) {
+ printk(KERN_ERR "vpe_write: no pbuffer\n");
+ return -ENOMEM;
+ }
+
+ if ((count + v->len) > v->plen) {
+ printk(KERN_WARNING
+ "VPE Loader: elf size too big. Perhaps strip uneeded symbols\n");
+ return -ENOMEM;
+ }
+
+ count -= copy_from_user(v->pbuffer + v->len, buffer, count);
+ if (!count) {
+ printk("vpe_write: copy_to_user failed\n");
+ return -EFAULT;
+ }
+
+ v->len += count;
+ return ret;
+}
+
+static struct file_operations vpe_fops = {
+ .owner = THIS_MODULE,
+ .open = vpe_open,
+ .release = vpe_release,
+ .write = vpe_write
+};
+
+/* module wrapper entry points */
+/* give me a vpe */
+vpe_handle vpe_alloc(void)
+{
+ int i;
+ struct vpe *v;
+
+ /* find a vpe */
+ for (i = 1; i < MAX_VPES; i++) {
+ if ((v = get_vpe(i)) != NULL) {
+ v->state = VPE_STATE_INUSE;
+ return v;
+ }
+ }
+ return NULL;
+}
+
+EXPORT_SYMBOL(vpe_alloc);
+
+/* start running from here */
+int vpe_start(vpe_handle vpe, unsigned long start)
+{
+ struct vpe *v = vpe;
+
+ v->__start = start;
+ return vpe_run(v);
+}
+
+EXPORT_SYMBOL(vpe_start);
+
+/* halt it for now */
+int vpe_stop(vpe_handle vpe)
+{
+ struct vpe *v = vpe;
+ struct tc *t;
+ unsigned int evpe_flags;
+
+ evpe_flags = dvpe();
+
+ if ((t = list_entry(v->tc.next, struct tc, tc)) != NULL) {
+
+ settc(t->index);
+ write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() & ~VPECONF0_VPA);
+ }
+
+ evpe(evpe_flags);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(vpe_stop);
+
+/* I've done with it thank you */
+int vpe_free(vpe_handle vpe)
+{
+ struct vpe *v = vpe;
+ struct tc *t;
+ unsigned int evpe_flags;
+
+ if ((t = list_entry(v->tc.next, struct tc, tc)) == NULL) {
+ return -ENOEXEC;
+ }
+
+ evpe_flags = dvpe();
+
+ /* Put MVPE's into 'configuration state' */
+ set_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ settc(t->index);
+ write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() & ~VPECONF0_VPA);
+
+ /* mark the TC unallocated and halt'ed */
+ write_tc_c0_tcstatus(read_tc_c0_tcstatus() & ~TCSTATUS_A);
+ write_tc_c0_tchalt(TCHALT_H);
+
+ v->state = VPE_STATE_UNUSED;
+
+ clear_c0_mvpcontrol(MVPCONTROL_VPC);
+ evpe(evpe_flags);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(vpe_free);
+
+void *vpe_get_shared(int index)
+{
+ struct vpe *v;
+
+ if ((v = get_vpe(index)) == NULL) {
+ printk(KERN_WARNING "vpe: invalid vpe index %d\n", index);
+ return NULL;
+ }
+
+ return v->shared_ptr;
+}
+
+EXPORT_SYMBOL(vpe_get_shared);
+
+static int __init vpe_module_init(void)
+{
+ struct vpe *v = NULL;
+ struct tc *t;
+ unsigned long val;
+ int i;
+
+ if (!cpu_has_mipsmt) {
+ printk("VPE loader: not a MIPS MT capable processor\n");
+ return -ENODEV;
+ }
+
+ if ((major = register_chrdev(VPE_MAJOR, module_name, &vpe_fops) < 0)) {
+ printk("VPE loader: unable to register character device\n");
+ return -EBUSY;
+ }
+
+ if (major == 0)
+ major = VPE_MAJOR;
+
+ dmt();
+ dvpe();
+
+ /* Put MVPE's into 'configuration state' */
+ set_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ /* dump_mtregs(); */
+
+ INIT_LIST_HEAD(&vpecontrol.vpe_list);
+ INIT_LIST_HEAD(&vpecontrol.tc_list);
+
+ val = read_c0_mvpconf0();
+ for (i = 0; i < ((val & MVPCONF0_PTC) + 1); i++) {
+ t = alloc_tc(i);
+
+ /* VPE's */
+ if (i < ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1) {
+ settc(i);
+
+ if ((v = alloc_vpe(i)) == NULL) {
+ printk(KERN_WARNING "VPE: unable to allocate VPE\n");
+ return -ENODEV;
+ }
+
+ list_add(&t->tc, &v->tc); /* add the tc to the list of this vpe's tc's. */
+
+ /* deactivate all but vpe0 */
+ if (i != 0) {
+ unsigned long tmp = read_vpe_c0_vpeconf0();
+
+ tmp &= ~VPECONF0_VPA;
+
+ /* master VPE */
+ tmp |= VPECONF0_MVP;
+ write_vpe_c0_vpeconf0(tmp);
+ }
+
+ /* disable multi-threading with TC's */
+ write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE);
+
+ if (i != 0) {
+ write_vpe_c0_status((read_c0_status() &
+ ~(ST0_IM | ST0_IE | ST0_KSU))
+ | ST0_CU0);
+
+ /* set config to be the same as vpe0, particularly kseg0 coherency alg */
+ write_vpe_c0_config(read_c0_config());
+ }
+
+ }
+
+ /* TC's */
+ t->pvpe = v; /* set the parent vpe */
+
+ if (i != 0) {
+ unsigned long tmp;
+
+ /* tc 0 will of course be running.... */
+ if (i == 0)
+ t->state = TC_STATE_RUNNING;
+
+ settc(i);
+
+ /* bind a TC to each VPE, May as well put all excess TC's
+ on the last VPE */
+ if (i >= (((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1))
+ write_tc_c0_tcbind(read_tc_c0_tcbind() |
+ ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT));
+ else
+ write_tc_c0_tcbind(read_tc_c0_tcbind() | i);
+
+ tmp = read_tc_c0_tcstatus();
+
+ /* mark not allocated and not dynamically allocatable */
+ tmp &= ~(TCSTATUS_A | TCSTATUS_DA);
+ tmp |= TCSTATUS_IXMT; /* interrupt exempt */
+ write_tc_c0_tcstatus(tmp);
+
+ write_tc_c0_tchalt(TCHALT_H);
+ }
+ }
+
+ /* release config state */
+ clear_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ return 0;
+}
+
+static void __exit vpe_module_exit(void)
+{
+ struct vpe *v, *n;
+
+ list_for_each_entry_safe(v, n, &vpecontrol.vpe_list, list) {
+ if (v->state != VPE_STATE_UNUSED) {
+ release_vpe(v);
+ }
+ }
+
+ unregister_chrdev(major, module_name);
+}
+
+module_init(vpe_module_init);
+module_exit(vpe_module_exit);
+MODULE_DESCRIPTION("MIPS VPE Loader");
+MODULE_AUTHOR("Elizabeth Clarke, MIPS Technologies, Inc");
+MODULE_LICENSE("GPL");
diff --git a/arch/mips/lasat/Kconfig b/arch/mips/lasat/Kconfig
new file mode 100644
index 000000000000..1d2ee8a9be13
--- /dev/null
+++ b/arch/mips/lasat/Kconfig
@@ -0,0 +1,15 @@
+config PICVUE
+ tristate "PICVUE LCD display driver"
+ depends on LASAT
+
+config PICVUE_PROC
+ tristate "PICVUE LCD display driver /proc interface"
+ depends on PICVUE
+
+config DS1603
+ bool "DS1603 RTC driver"
+ depends on LASAT
+
+config LASAT_SYSCTL
+ bool "LASAT sysctl interface"
+ depends on LASAT
diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c
index c90da1639440..852a41901a5e 100644
--- a/arch/mips/lasat/interrupt.c
+++ b/arch/mips/lasat/interrupt.c
@@ -71,14 +71,13 @@ static void end_lasat_irq(unsigned int irq)
}
static struct hw_interrupt_type lasat_irq_type = {
- "Lasat",
- startup_lasat_irq,
- shutdown_lasat_irq,
- enable_lasat_irq,
- disable_lasat_irq,
- mask_and_ack_lasat_irq,
- end_lasat_irq,
- NULL
+ .typename = "Lasat",
+ .startup = startup_lasat_irq,
+ .shutdown = shutdown_lasat_irq,
+ .enable = enable_lasat_irq,
+ .disable = disable_lasat_irq,
+ .ack = mask_and_ack_lasat_irq,
+ .end = end_lasat_irq,
};
static inline int ls1bit32(unsigned int x)
diff --git a/arch/mips/lasat/setup.c b/arch/mips/lasat/setup.c
index f2604fab9a99..dcd819d57dae 100644
--- a/arch/mips/lasat/setup.c
+++ b/arch/mips/lasat/setup.c
@@ -155,7 +155,7 @@ void __init serial_init(void)
}
#endif
-static int __init lasat_setup(void)
+void __init plat_setup(void)
{
int i;
lasat_misc = &lasat_misc_info[mips_machtype];
@@ -185,8 +185,4 @@ static int __init lasat_setup(void)
change_c0_status(ST0_BEV,0);
prom_printf("Lasat specific initialization complete\n");
-
- return 0;
}
-
-early_initcall(lasat_setup);
diff --git a/arch/mips/lib-32/dump_tlb.c b/arch/mips/lib-32/dump_tlb.c
index 019ac8f005d7..46519f4331eb 100644
--- a/arch/mips/lib-32/dump_tlb.c
+++ b/arch/mips/lib-32/dump_tlb.c
@@ -20,16 +20,25 @@
static inline const char *msk2str(unsigned int mask)
{
switch (mask) {
- case PM_4K: return "4kb";
- case PM_16K: return "16kb";
- case PM_64K: return "64kb";
- case PM_256K: return "256kb";
+ case PM_4K:
+ return "4kb";
+ case PM_16K:
+ return "16kb";
+ case PM_64K:
+ return "64kb";
+ case PM_256K:
+ return "256kb";
#ifndef CONFIG_CPU_VR41XX
- case PM_1M: return "1Mb";
- case PM_4M: return "4Mb";
- case PM_16M: return "16Mb";
- case PM_64M: return "64Mb";
- case PM_256M: return "256Mb";
+ case PM_1M:
+ return "1Mb";
+ case PM_4M:
+ return "4Mb";
+ case PM_16M:
+ return "16Mb";
+ case PM_64M:
+ return "64Mb";
+ case PM_256M:
+ return "256Mb";
#endif
}
@@ -47,7 +56,7 @@ void dump_tlb(int first, int last)
unsigned int pagemask, c0, c1, asid;
unsigned long long entrylo0, entrylo1;
unsigned long entryhi;
- int i;
+ int i;
asid = read_c0_entryhi() & 0xff;
@@ -58,7 +67,7 @@ void dump_tlb(int first, int last)
tlb_read();
BARRIER();
pagemask = read_c0_pagemask();
- entryhi = read_c0_entryhi();
+ entryhi = read_c0_entryhi();
entrylo0 = read_c0_entrylo0();
entrylo1 = read_c0_entrylo1();
@@ -78,13 +87,11 @@ void dump_tlb(int first, int last)
printk("\t\t\t[pa=%08Lx c=%d d=%d v=%d g=%Ld]\n",
(entrylo0 << 6) & PAGE_MASK, c0,
(entrylo0 & 4) ? 1 : 0,
- (entrylo0 & 2) ? 1 : 0,
- (entrylo0 & 1));
+ (entrylo0 & 2) ? 1 : 0, (entrylo0 & 1));
printk("\t\t\t[pa=%08Lx c=%d d=%d v=%d g=%Ld]\n",
(entrylo1 << 6) & PAGE_MASK, c1,
(entrylo1 & 4) ? 1 : 0,
- (entrylo1 & 2) ? 1 : 0,
- (entrylo1 & 1));
+ (entrylo1 & 2) ? 1 : 0, (entrylo1 & 1));
printk("\n");
}
}
@@ -99,7 +106,7 @@ void dump_tlb_all(void)
void dump_tlb_wired(void)
{
- int wired;
+ int wired;
wired = read_c0_wired();
printk("Wired: %d", wired);
@@ -138,9 +145,10 @@ void dump_tlb_nonwired(void)
void dump_list_process(struct task_struct *t, void *address)
{
- pgd_t *page_dir, *pgd;
- pmd_t *pmd;
- pte_t *pte, page;
+ pgd_t *page_dir, *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte, page;
unsigned long addr, val;
addr = (unsigned long) address;
@@ -152,21 +160,27 @@ void dump_list_process(struct task_struct *t, void *address)
if (addr > KSEG0)
page_dir = pgd_offset_k(0);
- else
+ else if (t->mm) {
page_dir = pgd_offset(t->mm, 0);
- printk("page_dir == %08x\n", (unsigned int) page_dir);
+ printk("page_dir == %08x\n", (unsigned int) page_dir);
+ } else
+ printk("Current thread has no mm\n");
if (addr > KSEG0)
pgd = pgd_offset_k(addr);
- else
+ else if (t->mm) {
pgd = pgd_offset(t->mm, addr);
- printk("pgd == %08x, ", (unsigned int) pgd);
+ printk("pgd == %08x, ", (unsigned int) pgd);
+ pud = pud_offset(pgd, addr);
+ printk("pud == %08x, ", (unsigned int) pud);
- pmd = pmd_offset(pgd, addr);
- printk("pmd == %08x, ", (unsigned int) pmd);
+ pmd = pmd_offset(pud, addr);
+ printk("pmd == %08x, ", (unsigned int) pmd);
- pte = pte_offset(pmd, addr);
- printk("pte == %08x, ", (unsigned int) pte);
+ pte = pte_offset(pmd, addr);
+ printk("pte == %08x, ", (unsigned int) pte);
+ } else
+ printk("Current thread has no mm\n");
page = *pte;
#ifdef CONFIG_64BIT_PHYS_ADDR
@@ -176,14 +190,22 @@ void dump_list_process(struct task_struct *t, void *address)
#endif
val = pte_val(page);
- if (val & _PAGE_PRESENT) printk("present ");
- if (val & _PAGE_READ) printk("read ");
- if (val & _PAGE_WRITE) printk("write ");
- if (val & _PAGE_ACCESSED) printk("accessed ");
- if (val & _PAGE_MODIFIED) printk("modified ");
- if (val & _PAGE_R4KBUG) printk("r4kbug ");
- if (val & _PAGE_GLOBAL) printk("global ");
- if (val & _PAGE_VALID) printk("valid ");
+ if (val & _PAGE_PRESENT)
+ printk("present ");
+ if (val & _PAGE_READ)
+ printk("read ");
+ if (val & _PAGE_WRITE)
+ printk("write ");
+ if (val & _PAGE_ACCESSED)
+ printk("accessed ");
+ if (val & _PAGE_MODIFIED)
+ printk("modified ");
+ if (val & _PAGE_R4KBUG)
+ printk("r4kbug ");
+ if (val & _PAGE_GLOBAL)
+ printk("global ");
+ if (val & _PAGE_VALID)
+ printk("valid ");
printk("\n");
}
@@ -194,14 +216,16 @@ void dump_list_current(void *address)
unsigned int vtop(void *address)
{
- pgd_t *pgd;
- pmd_t *pmd;
- pte_t *pte;
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
unsigned int addr, paddr;
addr = (unsigned long) address;
pgd = pgd_offset(current->mm, addr);
- pmd = pmd_offset(pgd, addr);
+ pud = pud_offset(pgd, addr);
+ pmd = pmd_offset(pud, addr);
pte = pte_offset(pmd, addr);
paddr = (KSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK;
paddr |= (addr & ~PAGE_MASK);
@@ -214,9 +238,9 @@ void dump16(unsigned long *p)
int i;
for (i = 0; i < 8; i++) {
- printk("*%08lx == %08lx, ", (unsigned long)p, *p);
+ printk("*%08lx == %08lx, ", (unsigned long) p, *p);
p++;
- printk("*%08lx == %08lx\n", (unsigned long)p, *p);
+ printk("*%08lx == %08lx\n", (unsigned long) p, *p);
p++;
}
}
diff --git a/arch/mips/lib-32/r3k_dump_tlb.c b/arch/mips/lib-32/r3k_dump_tlb.c
index a878224004e5..4f2cb74f0766 100644
--- a/arch/mips/lib-32/r3k_dump_tlb.c
+++ b/arch/mips/lib-32/r3k_dump_tlb.c
@@ -105,6 +105,7 @@ void dump_tlb_nonwired(void)
void dump_list_process(struct task_struct *t, void *address)
{
pgd_t *page_dir, *pgd;
+ pud_t *pud;
pmd_t *pmd;
pte_t *pte, page;
unsigned int addr;
@@ -121,7 +122,10 @@ void dump_list_process(struct task_struct *t, void *address)
pgd = pgd_offset(t->mm, addr);
printk("pgd == %08x, ", (unsigned int) pgd);
- pmd = pmd_offset(pgd, addr);
+ pud = pud_offset(pgd, addr);
+ printk("pud == %08x, ", (unsigned int) pud);
+
+ pmd = pmd_offset(pud, addr);
printk("pmd == %08x, ", (unsigned int) pmd);
pte = pte_offset(pmd, addr);
@@ -149,13 +153,15 @@ void dump_list_current(void *address)
unsigned int vtop(void *address)
{
pgd_t *pgd;
+ pud_t *pud;
pmd_t *pmd;
pte_t *pte;
unsigned int addr, paddr;
addr = (unsigned long) address;
pgd = pgd_offset(current->mm, addr);
- pmd = pmd_offset(pgd, addr);
+ pud = pud_offset(pgd, addr);
+ pmd = pmd_offset(pud, addr);
pte = pte_offset(pmd, addr);
paddr = (KSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK;
paddr |= (addr & ~PAGE_MASK);
diff --git a/arch/mips/lib-64/dump_tlb.c b/arch/mips/lib-64/dump_tlb.c
index 42f88e055b4c..11a5f015f040 100644
--- a/arch/mips/lib-64/dump_tlb.c
+++ b/arch/mips/lib-64/dump_tlb.c
@@ -140,6 +140,7 @@ void dump_tlb_nonwired(void)
void dump_list_process(struct task_struct *t, void *address)
{
pgd_t *page_dir, *pgd;
+ pud_t *pud;
pmd_t *pmd;
pte_t *pte, page;
unsigned long addr, val;
@@ -155,7 +156,10 @@ void dump_list_process(struct task_struct *t, void *address)
pgd = pgd_offset(t->mm, addr);
printk("pgd == %016lx\n", (unsigned long) pgd);
- pmd = pmd_offset(pgd, addr);
+ pud = pud_offset(pgd, addr);
+ printk("pud == %016lx\n", (unsigned long) pud);
+
+ pmd = pmd_offset(pud, addr);
printk("pmd == %016lx\n", (unsigned long) pmd);
pte = pte_offset(pmd, addr);
@@ -184,13 +188,15 @@ void dump_list_current(void *address)
unsigned int vtop(void *address)
{
pgd_t *pgd;
+ pud_t *pud;
pmd_t *pmd;
pte_t *pte;
unsigned int addr, paddr;
addr = (unsigned long) address;
pgd = pgd_offset(current->mm, addr);
- pmd = pmd_offset(pgd, addr);
+ pud = pud_offset(pgd, addr);
+ pmd = pmd_offset(pud, addr);
pte = pte_offset(pmd, addr);
paddr = (CKSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK;
paddr |= (addr & ~PAGE_MASK);
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index 037303412909..cf12caf80774 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -2,8 +2,8 @@
# Makefile for MIPS-specific library files..
#
-lib-y += csum_partial_copy.o memcpy.o promlib.o \
- strlen_user.o strncpy_user.o strnlen_user.o
+lib-y += csum_partial_copy.o memcpy.o promlib.o strlen_user.o strncpy_user.o \
+ strnlen_user.o uncached.o
obj-y += iomap.o
diff --git a/arch/mips/lib/csum_partial_copy.c b/arch/mips/lib/csum_partial_copy.c
index ffed0a6a1c16..6e9f366f961d 100644
--- a/arch/mips/lib/csum_partial_copy.c
+++ b/arch/mips/lib/csum_partial_copy.c
@@ -16,8 +16,8 @@
/*
* copy while checksumming, otherwise like csum_partial
*/
-unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst,
- int len, unsigned int sum)
+unsigned int csum_partial_copy_nocheck(const unsigned char *src,
+ unsigned char *dst, int len, unsigned int sum)
{
/*
* It's 2:30 am and I don't feel like doing it real ...
@@ -33,8 +33,8 @@ unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *
* Copy from userspace and compute checksum. If we catch an exception
* then zero the rest of the buffer.
*/
-unsigned int csum_partial_copy_from_user (const unsigned char *src, unsigned char *dst,
- int len, unsigned int sum, int *err_ptr)
+unsigned int csum_partial_copy_from_user (const unsigned char __user *src,
+ unsigned char *dst, int len, unsigned int sum, int *err_ptr)
{
int missing;
diff --git a/arch/mips/lib/memcpy.S b/arch/mips/lib/memcpy.S
index a78865f76547..7f9aafa4d80e 100644
--- a/arch/mips/lib/memcpy.S
+++ b/arch/mips/lib/memcpy.S
@@ -13,6 +13,21 @@
* Mnemonic names for arguments to memcpy/__copy_user
*/
#include <linux/config.h>
+
+/*
+ * Hack to resolve longstanding prefetch issue
+ *
+ * Prefetching may be fatal on some systems if we're prefetching beyond the
+ * end of memory on some systems. It's also a seriously bad idea on non
+ * dma-coherent systems.
+ */
+#if !defined(CONFIG_DMA_COHERENT) || !defined(CONFIG_DMA_IP27)
+#undef CONFIG_CPU_HAS_PREFETCH
+#endif
+#ifdef CONFIG_MIPS_MALTA
+#undef CONFIG_CPU_HAS_PREFETCH
+#endif
+
#include <asm/asm.h>
#include <asm/asm-offsets.h>
#include <asm/regdef.h>
diff --git a/arch/mips/lib/uncached.c b/arch/mips/lib/uncached.c
new file mode 100644
index 000000000000..98ce89f8068b
--- /dev/null
+++ b/arch/mips/lib/uncached.c
@@ -0,0 +1,76 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005 Thiemo Seufer
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ * Author: Maciej W. Rozycki <macro@mips.com>
+ */
+
+#include <linux/init.h>
+
+#include <asm/addrspace.h>
+#include <asm/bug.h>
+
+#ifndef CKSEG2
+#define CKSEG2 CKSSEG
+#endif
+#ifndef TO_PHYS_MASK
+#define TO_PHYS_MASK -1
+#endif
+
+/*
+ * FUNC is executed in one of the uncached segments, depending on its
+ * original address as follows:
+ *
+ * 1. If the original address is in CKSEG0 or CKSEG1, then the uncached
+ * segment used is CKSEG1.
+ * 2. If the original address is in XKPHYS, then the uncached segment
+ * used is XKPHYS(2).
+ * 3. Otherwise it's a bug.
+ *
+ * The same remapping is done with the stack pointer. Stack handling
+ * works because we don't handle stack arguments or more complex return
+ * values, so we can avoid sharing the same stack area between a cached
+ * and the uncached mode.
+ */
+unsigned long __init run_uncached(void *func)
+{
+ register long sp __asm__("$sp");
+ register long ret __asm__("$2");
+ long lfunc = (long)func, ufunc;
+ long usp;
+
+ if (sp >= (long)CKSEG0 && sp < (long)CKSEG2)
+ usp = CKSEG1ADDR(sp);
+ else if ((long long)sp >= (long long)PHYS_TO_XKPHYS(0LL, 0) &&
+ (long long)sp < (long long)PHYS_TO_XKPHYS(8LL, 0))
+ usp = PHYS_TO_XKPHYS((long long)K_CALG_UNCACHED,
+ XKPHYS_TO_PHYS((long long)sp));
+ else {
+ BUG();
+ usp = sp;
+ }
+ if (lfunc >= (long)CKSEG0 && lfunc < (long)CKSEG2)
+ ufunc = CKSEG1ADDR(lfunc);
+ else if ((long long)lfunc >= (long long)PHYS_TO_XKPHYS(0LL, 0) &&
+ (long long)lfunc < (long long)PHYS_TO_XKPHYS(8LL, 0))
+ ufunc = PHYS_TO_XKPHYS((long long)K_CALG_UNCACHED,
+ XKPHYS_TO_PHYS((long long)lfunc));
+ else {
+ BUG();
+ ufunc = lfunc;
+ }
+
+ __asm__ __volatile__ (
+ " move $16, $sp\n"
+ " move $sp, %1\n"
+ " jalr %2\n"
+ " move $sp, $16"
+ : "=r" (ret)
+ : "r" (usp), "r" (ufunc)
+ : "$16", "$31");
+
+ return ret;
+}
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
index 99c550632d44..aa5818a0d884 100644
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -70,7 +70,7 @@ static int fpux_emu(struct pt_regs *,
/* Further private data for which no space exists in mips_fpu_soft_struct */
-struct mips_fpu_emulator_private fpuemuprivate;
+struct mips_fpu_emulator_stats fpuemustats;
/* Control registers */
@@ -79,7 +79,17 @@ struct mips_fpu_emulator_private fpuemuprivate;
/* Convert Mips rounding mode (0..3) to IEEE library modes. */
static const unsigned char ieee_rm[4] = {
- IEEE754_RN, IEEE754_RZ, IEEE754_RU, IEEE754_RD
+ [FPU_CSR_RN] = IEEE754_RN,
+ [FPU_CSR_RZ] = IEEE754_RZ,
+ [FPU_CSR_RU] = IEEE754_RU,
+ [FPU_CSR_RD] = IEEE754_RD,
+};
+/* Convert IEEE library modes to Mips rounding mode (0..3). */
+static const unsigned char mips_rm[4] = {
+ [IEEE754_RN] = FPU_CSR_RN,
+ [IEEE754_RZ] = FPU_CSR_RZ,
+ [IEEE754_RD] = FPU_CSR_RD,
+ [IEEE754_RU] = FPU_CSR_RU,
};
#if __mips >= 4
@@ -196,11 +206,11 @@ static int isBranchInstr(mips_instruction * i)
static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
{
mips_instruction ir;
- vaddr_t emulpc, contpc;
+ void * emulpc, *contpc;
unsigned int cond;
- if (get_user(ir, (mips_instruction *) xcp->cp0_epc)) {
- fpuemuprivate.stats.errors++;
+ if (get_user(ir, (mips_instruction __user *) xcp->cp0_epc)) {
+ fpuemustats.errors++;
return SIGBUS;
}
@@ -221,41 +231,39 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
* Linux MIPS branch emulator operates on context, updating the
* cp0_epc.
*/
- emulpc = REG_TO_VA(xcp->cp0_epc + 4); /* Snapshot emulation target */
+ emulpc = (void *) (xcp->cp0_epc + 4); /* Snapshot emulation target */
if (__compute_return_epc(xcp)) {
#ifdef CP1DBG
printk("failed to emulate branch at %p\n",
- REG_TO_VA(xcp->cp0_epc));
+ (void *) (xcp->cp0_epc));
#endif
return SIGILL;
}
- if (get_user(ir, (mips_instruction *) emulpc)) {
- fpuemuprivate.stats.errors++;
+ if (get_user(ir, (mips_instruction __user *) emulpc)) {
+ fpuemustats.errors++;
return SIGBUS;
}
/* __compute_return_epc() will have updated cp0_epc */
- contpc = REG_TO_VA xcp->cp0_epc;
+ contpc = (void *) xcp->cp0_epc;
/* In order not to confuse ptrace() et al, tweak context */
- xcp->cp0_epc = VA_TO_REG emulpc - 4;
- }
- else {
- emulpc = REG_TO_VA xcp->cp0_epc;
- contpc = REG_TO_VA(xcp->cp0_epc + 4);
+ xcp->cp0_epc = (unsigned long) emulpc - 4;
+ } else {
+ emulpc = (void *) xcp->cp0_epc;
+ contpc = (void *) (xcp->cp0_epc + 4);
}
emul:
- fpuemuprivate.stats.emulated++;
+ fpuemustats.emulated++;
switch (MIPSInst_OPCODE(ir)) {
-#ifndef SINGLE_ONLY_FPU
case ldc1_op:{
- u64 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] +
+ u64 __user *va = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
MIPSInst_SIMM(ir));
u64 val;
- fpuemuprivate.stats.loads++;
+ fpuemustats.loads++;
if (get_user(val, va)) {
- fpuemuprivate.stats.errors++;
+ fpuemustats.errors++;
return SIGBUS;
}
DITOREG(val, MIPSInst_RT(ir));
@@ -263,55 +271,42 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
}
case sdc1_op:{
- u64 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] +
+ u64 __user *va = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
MIPSInst_SIMM(ir));
u64 val;
- fpuemuprivate.stats.stores++;
+ fpuemustats.stores++;
DIFROMREG(val, MIPSInst_RT(ir));
if (put_user(val, va)) {
- fpuemuprivate.stats.errors++;
+ fpuemustats.errors++;
return SIGBUS;
}
break;
}
-#endif
case lwc1_op:{
- u32 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] +
+ u32 __user *va = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
MIPSInst_SIMM(ir));
u32 val;
- fpuemuprivate.stats.loads++;
+ fpuemustats.loads++;
if (get_user(val, va)) {
- fpuemuprivate.stats.errors++;
+ fpuemustats.errors++;
return SIGBUS;
}
-#ifdef SINGLE_ONLY_FPU
- if (MIPSInst_RT(ir) & 1) {
- /* illegal register in single-float mode */
- return SIGILL;
- }
-#endif
SITOREG(val, MIPSInst_RT(ir));
break;
}
case swc1_op:{
- u32 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] +
+ u32 __user *va = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
MIPSInst_SIMM(ir));
u32 val;
- fpuemuprivate.stats.stores++;
-#ifdef SINGLE_ONLY_FPU
- if (MIPSInst_RT(ir) & 1) {
- /* illegal register in single-float mode */
- return SIGILL;
- }
-#endif
+ fpuemustats.stores++;
SIFROMREG(val, MIPSInst_RT(ir));
if (put_user(val, va)) {
- fpuemuprivate.stats.errors++;
+ fpuemustats.errors++;
return SIGBUS;
}
break;
@@ -320,7 +315,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
case cop1_op:
switch (MIPSInst_RS(ir)) {
-#if defined(__mips64) && !defined(SINGLE_ONLY_FPU)
+#if defined(__mips64)
case dmfc_op:
/* copregister fs -> gpr[rt] */
if (MIPSInst_RT(ir) != 0) {
@@ -337,12 +332,6 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
case mfc_op:
/* copregister rd -> gpr[rt] */
-#ifdef SINGLE_ONLY_FPU
- if (MIPSInst_RD(ir) & 1) {
- /* illegal register in single-float mode */
- return SIGILL;
- }
-#endif
if (MIPSInst_RT(ir) != 0) {
SIFROMREG(xcp->regs[MIPSInst_RT(ir)],
MIPSInst_RD(ir));
@@ -351,12 +340,6 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
case mtc_op:
/* copregister rd <- rt */
-#ifdef SINGLE_ONLY_FPU
- if (MIPSInst_RD(ir) & 1) {
- /* illegal register in single-float mode */
- return SIGILL;
- }
-#endif
SITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
break;
@@ -369,9 +352,10 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
}
if (MIPSInst_RD(ir) == FPCREG_CSR) {
value = ctx->fcr31;
+ value = (value & ~0x3) | mips_rm[value & 0x3];
#ifdef CSRTRACE
printk("%p gpr[%d]<-csr=%08x\n",
- REG_TO_VA(xcp->cp0_epc),
+ (void *) (xcp->cp0_epc),
MIPSInst_RT(ir), value);
#endif
}
@@ -398,14 +382,13 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
if (MIPSInst_RD(ir) == FPCREG_CSR) {
#ifdef CSRTRACE
printk("%p gpr[%d]->csr=%08x\n",
- REG_TO_VA(xcp->cp0_epc),
+ (void *) (xcp->cp0_epc),
MIPSInst_RT(ir), value);
#endif
- ctx->fcr31 = value;
- /* copy new rounding mode and
- flush bit to ieee library state! */
- ieee754_csr.nod = (ctx->fcr31 & 0x1000000) != 0;
- ieee754_csr.rm = ieee_rm[value & 0x3];
+ value &= (FPU_CSR_FLUSH | FPU_CSR_ALL_E | FPU_CSR_ALL_S | 0x03);
+ ctx->fcr31 &= ~(FPU_CSR_FLUSH | FPU_CSR_ALL_E | FPU_CSR_ALL_S | 0x03);
+ /* convert to ieee library modes */
+ ctx->fcr31 |= (value & ~0x3) | ieee_rm[value & 0x3];
}
if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
return SIGFPE;
@@ -445,20 +428,20 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
* instruction
*/
xcp->cp0_epc += 4;
- contpc = REG_TO_VA
+ contpc = (void *)
(xcp->cp0_epc +
(MIPSInst_SIMM(ir) << 2));
- if (get_user(ir, (mips_instruction *)
- REG_TO_VA xcp->cp0_epc)) {
- fpuemuprivate.stats.errors++;
+ if (get_user(ir,
+ (mips_instruction __user *) xcp->cp0_epc)) {
+ fpuemustats.errors++;
return SIGBUS;
}
switch (MIPSInst_OPCODE(ir)) {
case lwc1_op:
case swc1_op:
-#if (__mips >= 2 || __mips64) && !defined(SINGLE_ONLY_FPU)
+#if (__mips >= 2 || defined(__mips64))
case ldc1_op:
case sdc1_op:
#endif
@@ -480,7 +463,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
* Single step the non-cp1
* instruction in the dslot
*/
- return mips_dsemul(xcp, ir, VA_TO_REG contpc);
+ return mips_dsemul(xcp, ir, (unsigned long) contpc);
}
else {
/* branch not taken */
@@ -539,8 +522,9 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
}
/* we did it !! */
- xcp->cp0_epc = VA_TO_REG(contpc);
+ xcp->cp0_epc = (unsigned long) contpc;
xcp->cp0_cause &= ~CAUSEF_BD;
+
return 0;
}
@@ -570,7 +554,7 @@ static const unsigned char cmptab[8] = {
static ieee754##p fpemu_##p##_##name (ieee754##p r, ieee754##p s, \
ieee754##p t) \
{ \
- struct ieee754_csr ieee754_csr_save; \
+ struct _ieee754_csr ieee754_csr_save; \
s = f1 (s, t); \
ieee754_csr_save = ieee754_csr; \
s = f2 (s, r); \
@@ -616,54 +600,38 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
{
unsigned rcsr = 0; /* resulting csr */
- fpuemuprivate.stats.cp1xops++;
+ fpuemustats.cp1xops++;
switch (MIPSInst_FMA_FFMT(ir)) {
case s_fmt:{ /* 0 */
ieee754sp(*handler) (ieee754sp, ieee754sp, ieee754sp);
ieee754sp fd, fr, fs, ft;
- u32 *va;
+ u32 __user *va;
u32 val;
switch (MIPSInst_FUNC(ir)) {
case lwxc1_op:
- va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] +
+ va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
xcp->regs[MIPSInst_FT(ir)]);
- fpuemuprivate.stats.loads++;
+ fpuemustats.loads++;
if (get_user(val, va)) {
- fpuemuprivate.stats.errors++;
+ fpuemustats.errors++;
return SIGBUS;
}
-#ifdef SINGLE_ONLY_FPU
- if (MIPSInst_FD(ir) & 1) {
- /* illegal register in single-float
- * mode
- */
- return SIGILL;
- }
-#endif
SITOREG(val, MIPSInst_FD(ir));
break;
case swxc1_op:
- va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] +
+ va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
xcp->regs[MIPSInst_FT(ir)]);
- fpuemuprivate.stats.stores++;
-#ifdef SINGLE_ONLY_FPU
- if (MIPSInst_FS(ir) & 1) {
- /* illegal register in single-float
- * mode
- */
- return SIGILL;
- }
-#endif
+ fpuemustats.stores++;
SIFROMREG(val, MIPSInst_FS(ir));
if (put_user(val, va)) {
- fpuemuprivate.stats.errors++;
+ fpuemustats.errors++;
return SIGBUS;
}
break;
@@ -699,8 +667,6 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S;
ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr;
- if (ieee754_csr.nod)
- ctx->fcr31 |= 0x1000000;
if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
/*printk ("SIGFPE: fpu csr = %08x\n",
ctx->fcr31); */
@@ -715,34 +681,33 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
break;
}
-#ifndef SINGLE_ONLY_FPU
case d_fmt:{ /* 1 */
ieee754dp(*handler) (ieee754dp, ieee754dp, ieee754dp);
ieee754dp fd, fr, fs, ft;
- u64 *va;
+ u64 __user *va;
u64 val;
switch (MIPSInst_FUNC(ir)) {
case ldxc1_op:
- va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] +
+ va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
xcp->regs[MIPSInst_FT(ir)]);
- fpuemuprivate.stats.loads++;
+ fpuemustats.loads++;
if (get_user(val, va)) {
- fpuemuprivate.stats.errors++;
+ fpuemustats.errors++;
return SIGBUS;
}
DITOREG(val, MIPSInst_FD(ir));
break;
case sdxc1_op:
- va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] +
+ va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
xcp->regs[MIPSInst_FT(ir)]);
- fpuemuprivate.stats.stores++;
+ fpuemustats.stores++;
DIFROMREG(val, MIPSInst_FS(ir));
if (put_user(val, va)) {
- fpuemuprivate.stats.errors++;
+ fpuemustats.errors++;
return SIGBUS;
}
break;
@@ -773,7 +738,6 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
}
break;
}
-#endif
case 0x7: /* 7 */
if (MIPSInst_FUNC(ir) != pfetch_op) {
@@ -810,7 +774,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
#endif
} rv; /* resulting value */
- fpuemuprivate.stats.cp1ops++;
+ fpuemustats.cp1ops++;
switch (rfmt = (MIPSInst_FFMT(ir) & 0xf)) {
case s_fmt:{ /* 0 */
union {
@@ -834,7 +798,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
goto scopbop;
/* unary ops */
-#if __mips >= 2 || __mips64
+#if __mips >= 2 || defined(__mips64)
case fsqrt_op:
handler.u = ieee754sp_sqrt;
goto scopuop;
@@ -913,9 +877,6 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
case fcvts_op:
return SIGILL; /* not defined */
case fcvtd_op:{
-#ifdef SINGLE_ONLY_FPU
- return SIGILL; /* not defined */
-#else
ieee754sp fs;
SPFROMREG(fs, MIPSInst_FS(ir));
@@ -923,7 +884,6 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
rfmt = d_fmt;
goto copcsr;
}
-#endif
case fcvtw_op:{
ieee754sp fs;
@@ -933,7 +893,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
goto copcsr;
}
-#if __mips >= 2 || __mips64
+#if __mips >= 2 || defined(__mips64)
case fround_op:
case ftrunc_op:
case fceil_op:
@@ -950,7 +910,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
}
#endif /* __mips >= 2 */
-#if defined(__mips64) && !defined(SINGLE_ONLY_FPU)
+#if defined(__mips64)
case fcvtl_op:{
ieee754sp fs;
@@ -974,7 +934,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
rfmt = l_fmt;
goto copcsr;
}
-#endif /* __mips64 && !fpu(single) */
+#endif /* defined(__mips64) */
default:
if (MIPSInst_FUNC(ir) >= fcmp_op) {
@@ -1001,7 +961,6 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
break;
}
-#ifndef SINGLE_ONLY_FPU
case d_fmt:{
union {
ieee754dp(*b) (ieee754dp, ieee754dp);
@@ -1024,7 +983,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
goto dcopbop;
/* unary ops */
-#if __mips >= 2 || __mips64
+#if __mips >= 2 || defined(__mips64)
case fsqrt_op:
handler.u = ieee754dp_sqrt;
goto dcopuop;
@@ -1108,7 +1067,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
goto copcsr;
}
-#if __mips >= 2 || __mips64
+#if __mips >= 2 || defined(__mips64)
case fround_op:
case ftrunc_op:
case fceil_op:
@@ -1125,7 +1084,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
}
#endif
-#if defined(__mips64) && !defined(SINGLE_ONLY_FPU)
+#if defined(__mips64)
case fcvtl_op:{
ieee754dp fs;
@@ -1149,7 +1108,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
rfmt = l_fmt;
goto copcsr;
}
-#endif /* __mips >= 3 && !fpu(single) */
+#endif /* __mips >= 3 */
default:
if (MIPSInst_FUNC(ir) >= fcmp_op) {
@@ -1177,7 +1136,6 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
}
break;
}
-#endif /* ifndef SINGLE_ONLY_FPU */
case w_fmt:{
ieee754sp fs;
@@ -1189,21 +1147,19 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
rv.s = ieee754sp_fint(fs.bits);
rfmt = s_fmt;
goto copcsr;
-#ifndef SINGLE_ONLY_FPU
case fcvtd_op:
/* convert word to double precision real */
SPFROMREG(fs, MIPSInst_FS(ir));
rv.d = ieee754dp_fint(fs.bits);
rfmt = d_fmt;
goto copcsr;
-#endif
default:
return SIGILL;
}
break;
}
-#if defined(__mips64) && !defined(SINGLE_ONLY_FPU)
+#if defined(__mips64)
case l_fmt:{
switch (MIPSInst_FUNC(ir)) {
case fcvts_op:
@@ -1256,18 +1212,16 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
ctx->fcr31 &= ~cond;
break;
}
-#ifndef SINGLE_ONLY_FPU
case d_fmt:
DPTOREG(rv.d, MIPSInst_FD(ir));
break;
-#endif
case s_fmt:
SPTOREG(rv.s, MIPSInst_FD(ir));
break;
case w_fmt:
SITOREG(rv.w, MIPSInst_FD(ir));
break;
-#if defined(__mips64) && !defined(SINGLE_ONLY_FPU)
+#if defined(__mips64)
case l_fmt:
DITOREG(rv.l, MIPSInst_FD(ir));
break;
@@ -1279,10 +1233,10 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
return 0;
}
-int fpu_emulator_cop1Handler(int xcptno, struct pt_regs *xcp,
+int fpu_emulator_cop1Handler(struct pt_regs *xcp,
struct mips_fpu_soft_struct *ctx)
{
- gpreg_t oldepc, prevepc;
+ unsigned long oldepc, prevepc;
mips_instruction insn;
int sig = 0;
@@ -1290,19 +1244,24 @@ int fpu_emulator_cop1Handler(int xcptno, struct pt_regs *xcp,
do {
prevepc = xcp->cp0_epc;
- if (get_user(insn, (mips_instruction *) xcp->cp0_epc)) {
- fpuemuprivate.stats.errors++;
+ if (get_user(insn, (mips_instruction __user *) xcp->cp0_epc)) {
+ fpuemustats.errors++;
return SIGBUS;
}
if (insn == 0)
xcp->cp0_epc += 4; /* skip nops */
else {
- /* Update ieee754_csr. Only relevant if we have a
- h/w FPU */
- ieee754_csr.nod = (ctx->fcr31 & 0x1000000) != 0;
- ieee754_csr.rm = ieee_rm[ctx->fcr31 & 0x3];
- ieee754_csr.cx = (ctx->fcr31 >> 12) & 0x1f;
+ /*
+ * The 'ieee754_csr' is an alias of
+ * ctx->fcr31. No need to copy ctx->fcr31 to
+ * ieee754_csr. But ieee754_csr.rm is ieee
+ * library modes. (not mips rounding mode)
+ */
+ /* convert to ieee library modes */
+ ieee754_csr.rm = ieee_rm[ieee754_csr.rm];
sig = cop1Emulate(xcp, ctx);
+ /* revert to mips rounding mode */
+ ieee754_csr.rm = mips_rm[ieee754_csr.rm];
}
if (cpu_has_fpu)
diff --git a/arch/mips/math-emu/dp_sqrt.c b/arch/mips/math-emu/dp_sqrt.c
index c35e871ae975..032328c49888 100644
--- a/arch/mips/math-emu/dp_sqrt.c
+++ b/arch/mips/math-emu/dp_sqrt.c
@@ -37,7 +37,7 @@ static const unsigned table[] = {
ieee754dp ieee754dp_sqrt(ieee754dp x)
{
- struct ieee754_csr oldcsr;
+ struct _ieee754_csr oldcsr;
ieee754dp y, z, t;
unsigned scalx, yh;
COMPXDP;
diff --git a/arch/mips/math-emu/dsemul.c b/arch/mips/math-emu/dsemul.c
index aa989c2246da..8079f3d1eca0 100644
--- a/arch/mips/math-emu/dsemul.c
+++ b/arch/mips/math-emu/dsemul.c
@@ -28,9 +28,6 @@
#endif
#define __mips 4
-extern struct mips_fpu_emulator_private fpuemuprivate;
-
-
/*
* Emulate the arbritrary instruction ir at xcp->cp0_epc. Required when
* we have to emulate the instruction in a COP1 branch delay slot. Do
@@ -52,10 +49,10 @@ struct emuframe {
mips_instruction emul;
mips_instruction badinst;
mips_instruction cookie;
- gpreg_t epc;
+ unsigned long epc;
};
-int mips_dsemul(struct pt_regs *regs, mips_instruction ir, gpreg_t cpc)
+int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
{
extern asmlinkage void handle_dsemulret(void);
mips_instruction *dsemul_insns;
@@ -91,7 +88,7 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, gpreg_t cpc)
*/
/* Ensure that the two instructions are in the same cache line */
- dsemul_insns = (mips_instruction *) REG_TO_VA ((regs->regs[29] - sizeof(struct emuframe)) & ~0x7);
+ dsemul_insns = (mips_instruction *) ((regs->regs[29] - sizeof(struct emuframe)) & ~0x7);
fr = (struct emuframe *) dsemul_insns;
/* Verify that the stack pointer is not competely insane */
@@ -104,11 +101,11 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, gpreg_t cpc)
err |= __put_user(cpc, &fr->epc);
if (unlikely(err)) {
- fpuemuprivate.stats.errors++;
+ fpuemustats.errors++;
return SIGBUS;
}
- regs->cp0_epc = VA_TO_REG & fr->emul;
+ regs->cp0_epc = (unsigned long) &fr->emul;
flush_cache_sigtramp((unsigned long)&fr->badinst);
@@ -118,7 +115,7 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, gpreg_t cpc)
int do_dsemulret(struct pt_regs *xcp)
{
struct emuframe *fr;
- gpreg_t epc;
+ unsigned long epc;
u32 insn, cookie;
int err = 0;
@@ -141,7 +138,7 @@ int do_dsemulret(struct pt_regs *xcp)
err |= __get_user(cookie, &fr->cookie);
if (unlikely(err || (insn != BADINST) || (cookie != BD_COOKIE))) {
- fpuemuprivate.stats.errors++;
+ fpuemustats.errors++;
return 0;
}
diff --git a/arch/mips/math-emu/dsemul.h b/arch/mips/math-emu/dsemul.h
index dbd85f95268d..091f0e76730f 100644
--- a/arch/mips/math-emu/dsemul.h
+++ b/arch/mips/math-emu/dsemul.h
@@ -1,11 +1,5 @@
-typedef long gpreg_t;
-typedef void *vaddr_t;
-
-#define REG_TO_VA (vaddr_t)
-#define VA_TO_REG (gpreg_t)
-
-int mips_dsemul(struct pt_regs *regs, mips_instruction ir, gpreg_t cpc);
-int do_dsemulret(struct pt_regs *xcp);
+extern int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc);
+extern int do_dsemulret(struct pt_regs *xcp);
/* Instruction which will always cause an address error */
#define AdELOAD 0x8c000001 /* lw $0,1($0) */
diff --git a/arch/mips/math-emu/ieee754.c b/arch/mips/math-emu/ieee754.c
index f0a364adbf34..a93c45dbdefd 100644
--- a/arch/mips/math-emu/ieee754.c
+++ b/arch/mips/math-emu/ieee754.c
@@ -31,6 +31,8 @@
#include "ieee754int.h"
+#include "ieee754sp.h"
+#include "ieee754dp.h"
#define DP_EBIAS 1023
#define DP_EMIN (-1022)
@@ -40,20 +42,6 @@
#define SP_EMIN (-126)
#define SP_EMAX 127
-/* indexed by class */
-const char *const ieee754_cname[] = {
- "Normal",
- "Zero",
- "Denormal",
- "Infinity",
- "QNaN",
- "SNaN",
-};
-
-/* the control status register
-*/
-struct ieee754_csr ieee754_csr;
-
/* special constants
*/
diff --git a/arch/mips/math-emu/ieee754.h b/arch/mips/math-emu/ieee754.h
index b8772f46972d..171f177c0f88 100644
--- a/arch/mips/math-emu/ieee754.h
+++ b/arch/mips/math-emu/ieee754.h
@@ -1,13 +1,8 @@
-/* single and double precision fp ops
- * missing extended precision.
-*/
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
* http://www.algor.co.uk
*
- * ########################################################################
- *
* This program is free software; you can distribute it and/or modify it
* under the terms of the GNU General Public License (Version 2) as
* published by the Free Software Foundation.
@@ -21,20 +16,18 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
- * ########################################################################
- */
-
-/**************************************************************************
* Nov 7, 2000
* Modification to allow integration with Linux kernel
*
* Kevin D. Kissell, kevink@mips.com and Carsten Langgard, carstenl@mips.com
* Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
- *************************************************************************/
+ */
+#ifndef __ARCH_MIPS_MATH_EMU_IEEE754_H
+#define __ARCH_MIPS_MATH_EMU_IEEE754_H
-#ifdef __KERNEL__
-/* Going from Algorithmics to Linux native environment, add this */
+#include <asm/byteorder.h>
#include <linux/types.h>
+#include <linux/sched.h>
/*
* Not very pretty, but the Linux kernel's normal va_list definition
@@ -44,18 +37,7 @@
#include <stdarg.h>
#endif
-#else
-
-/* Note that __KERNEL__ is taken to mean Linux kernel */
-
-#if #system(OpenBSD)
-#include <machine/types.h>
-#endif
-#include <machine/endian.h>
-
-#endif /* __KERNEL__ */
-
-#if (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN) || defined(__MIPSEL__)
+#ifdef __LITTLE_ENDIAN
struct ieee754dp_konst {
unsigned mantlo:32;
unsigned manthi:20;
@@ -86,13 +68,14 @@ typedef union _ieee754sp {
} ieee754sp;
#endif
-#if (defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN) || defined(__MIPSEB__)
+#ifdef __BIG_ENDIAN
struct ieee754dp_konst {
unsigned sign:1;
unsigned bexp:11;
unsigned manthi:20;
unsigned mantlo:32;
};
+
typedef union _ieee754dp {
struct ieee754dp_konst oparts;
struct {
@@ -222,7 +205,6 @@ ieee754dp ieee754dp_sqrt(ieee754dp x);
#define IEEE754_CLASS_INF 0x03
#define IEEE754_CLASS_SNAN 0x04
#define IEEE754_CLASS_QNAN 0x05
-extern const char *const ieee754_cname[];
/* exception numbers */
#define IEEE754_INEXACT 0x01
@@ -251,93 +233,109 @@ extern const char *const ieee754_cname[];
/* "normal" comparisons
*/
-static __inline int ieee754sp_eq(ieee754sp x, ieee754sp y)
+static inline int ieee754sp_eq(ieee754sp x, ieee754sp y)
{
return ieee754sp_cmp(x, y, IEEE754_CEQ, 0);
}
-static __inline int ieee754sp_ne(ieee754sp x, ieee754sp y)
+static inline int ieee754sp_ne(ieee754sp x, ieee754sp y)
{
return ieee754sp_cmp(x, y,
IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0);
}
-static __inline int ieee754sp_lt(ieee754sp x, ieee754sp y)
+static inline int ieee754sp_lt(ieee754sp x, ieee754sp y)
{
return ieee754sp_cmp(x, y, IEEE754_CLT, 0);
}
-static __inline int ieee754sp_le(ieee754sp x, ieee754sp y)
+static inline int ieee754sp_le(ieee754sp x, ieee754sp y)
{
return ieee754sp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0);
}
-static __inline int ieee754sp_gt(ieee754sp x, ieee754sp y)
+static inline int ieee754sp_gt(ieee754sp x, ieee754sp y)
{
return ieee754sp_cmp(x, y, IEEE754_CGT, 0);
}
-static __inline int ieee754sp_ge(ieee754sp x, ieee754sp y)
+static inline int ieee754sp_ge(ieee754sp x, ieee754sp y)
{
return ieee754sp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0);
}
-static __inline int ieee754dp_eq(ieee754dp x, ieee754dp y)
+static inline int ieee754dp_eq(ieee754dp x, ieee754dp y)
{
return ieee754dp_cmp(x, y, IEEE754_CEQ, 0);
}
-static __inline int ieee754dp_ne(ieee754dp x, ieee754dp y)
+static inline int ieee754dp_ne(ieee754dp x, ieee754dp y)
{
return ieee754dp_cmp(x, y,
IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0);
}
-static __inline int ieee754dp_lt(ieee754dp x, ieee754dp y)
+static inline int ieee754dp_lt(ieee754dp x, ieee754dp y)
{
return ieee754dp_cmp(x, y, IEEE754_CLT, 0);
}
-static __inline int ieee754dp_le(ieee754dp x, ieee754dp y)
+static inline int ieee754dp_le(ieee754dp x, ieee754dp y)
{
return ieee754dp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0);
}
-static __inline int ieee754dp_gt(ieee754dp x, ieee754dp y)
+static inline int ieee754dp_gt(ieee754dp x, ieee754dp y)
{
return ieee754dp_cmp(x, y, IEEE754_CGT, 0);
}
-static __inline int ieee754dp_ge(ieee754dp x, ieee754dp y)
+static inline int ieee754dp_ge(ieee754dp x, ieee754dp y)
{
return ieee754dp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0);
}
-/* like strtod
-*/
+/*
+ * Like strtod
+ */
ieee754dp ieee754dp_fstr(const char *s, char **endp);
char *ieee754dp_tstr(ieee754dp x, int prec, int fmt, int af);
-/* the control status register
-*/
-struct ieee754_csr {
- unsigned pad:13;
+/*
+ * The control status register
+ */
+struct _ieee754_csr {
+#ifdef __BIG_ENDIAN
+ unsigned pad0:7;
unsigned nod:1; /* set 1 for no denormalised numbers */
- unsigned cx:5; /* exceptions this operation */
+ unsigned c:1; /* condition */
+ unsigned pad1:5;
+ unsigned cx:6; /* exceptions this operation */
unsigned mx:5; /* exception enable mask */
unsigned sx:5; /* exceptions total */
unsigned rm:2; /* current rounding mode */
+#endif
+#ifdef __LITTLE_ENDIAN
+ unsigned rm:2; /* current rounding mode */
+ unsigned sx:5; /* exceptions total */
+ unsigned mx:5; /* exception enable mask */
+ unsigned cx:6; /* exceptions this operation */
+ unsigned pad1:5;
+ unsigned c:1; /* condition */
+ unsigned nod:1; /* set 1 for no denormalised numbers */
+ unsigned pad0:7;
+#endif
};
-extern struct ieee754_csr ieee754_csr;
+#define ieee754_csr (*(struct _ieee754_csr *)(&current->thread.fpu.soft.fcr31))
-static __inline unsigned ieee754_getrm(void)
+static inline unsigned ieee754_getrm(void)
{
return (ieee754_csr.rm);
}
-static __inline unsigned ieee754_setrm(unsigned rm)
+static inline unsigned ieee754_setrm(unsigned rm)
{
return (ieee754_csr.rm = rm);
}
@@ -345,14 +343,14 @@ static __inline unsigned ieee754_setrm(unsigned rm)
/*
* get current exceptions
*/
-static __inline unsigned ieee754_getcx(void)
+static inline unsigned ieee754_getcx(void)
{
return (ieee754_csr.cx);
}
/* test for current exception condition
*/
-static __inline int ieee754_cxtest(unsigned n)
+static inline int ieee754_cxtest(unsigned n)
{
return (ieee754_csr.cx & n);
}
@@ -360,21 +358,21 @@ static __inline int ieee754_cxtest(unsigned n)
/*
* get sticky exceptions
*/
-static __inline unsigned ieee754_getsx(void)
+static inline unsigned ieee754_getsx(void)
{
return (ieee754_csr.sx);
}
/* clear sticky conditions
*/
-static __inline unsigned ieee754_clrsx(void)
+static inline unsigned ieee754_clrsx(void)
{
return (ieee754_csr.sx = 0);
}
/* test for sticky exception condition
*/
-static __inline int ieee754_sxtest(unsigned n)
+static inline int ieee754_sxtest(unsigned n)
{
return (ieee754_csr.sx & n);
}
@@ -406,52 +404,34 @@ extern const struct ieee754sp_konst __ieee754sp_spcvals[];
#define ieee754dp_spcvals ((const ieee754dp *)__ieee754dp_spcvals)
#define ieee754sp_spcvals ((const ieee754sp *)__ieee754sp_spcvals)
-/* return infinity with given sign
-*/
-#define ieee754dp_inf(sn) \
- (ieee754dp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)])
-#define ieee754dp_zero(sn) \
- (ieee754dp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
-#define ieee754dp_one(sn) \
- (ieee754dp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
-#define ieee754dp_ten(sn) \
- (ieee754dp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
-#define ieee754dp_indef() \
- (ieee754dp_spcvals[IEEE754_SPCVAL_INDEF])
-#define ieee754dp_max(sn) \
- (ieee754dp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
-#define ieee754dp_min(sn) \
- (ieee754dp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
-#define ieee754dp_mind(sn) \
- (ieee754dp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
-#define ieee754dp_1e31() \
- (ieee754dp_spcvals[IEEE754_SPCVAL_P1E31])
-#define ieee754dp_1e63() \
- (ieee754dp_spcvals[IEEE754_SPCVAL_P1E63])
-
-#define ieee754sp_inf(sn) \
- (ieee754sp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)])
-#define ieee754sp_zero(sn) \
- (ieee754sp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
-#define ieee754sp_one(sn) \
- (ieee754sp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
-#define ieee754sp_ten(sn) \
- (ieee754sp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
-#define ieee754sp_indef() \
- (ieee754sp_spcvals[IEEE754_SPCVAL_INDEF])
-#define ieee754sp_max(sn) \
- (ieee754sp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
-#define ieee754sp_min(sn) \
- (ieee754sp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
-#define ieee754sp_mind(sn) \
- (ieee754sp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
-#define ieee754sp_1e31() \
- (ieee754sp_spcvals[IEEE754_SPCVAL_P1E31])
-#define ieee754sp_1e63() \
- (ieee754sp_spcvals[IEEE754_SPCVAL_P1E63])
-
-/* indefinite integer value
-*/
+/*
+ * Return infinity with given sign
+ */
+#define ieee754dp_inf(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)])
+#define ieee754dp_zero(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
+#define ieee754dp_one(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
+#define ieee754dp_ten(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
+#define ieee754dp_indef() (ieee754dp_spcvals[IEEE754_SPCVAL_INDEF])
+#define ieee754dp_max(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
+#define ieee754dp_min(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
+#define ieee754dp_mind(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
+#define ieee754dp_1e31() (ieee754dp_spcvals[IEEE754_SPCVAL_P1E31])
+#define ieee754dp_1e63() (ieee754dp_spcvals[IEEE754_SPCVAL_P1E63])
+
+#define ieee754sp_inf(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)])
+#define ieee754sp_zero(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
+#define ieee754sp_one(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
+#define ieee754sp_ten(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
+#define ieee754sp_indef() (ieee754sp_spcvals[IEEE754_SPCVAL_INDEF])
+#define ieee754sp_max(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
+#define ieee754sp_min(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
+#define ieee754sp_mind(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
+#define ieee754sp_1e31() (ieee754sp_spcvals[IEEE754_SPCVAL_P1E31])
+#define ieee754sp_1e63() (ieee754sp_spcvals[IEEE754_SPCVAL_P1E63])
+
+/*
+ * Indefinite integer value
+ */
#define ieee754si_indef() INT_MAX
#ifdef LONG_LONG_MAX
#define ieee754di_indef() LONG_LONG_MAX
@@ -487,3 +467,5 @@ extern void ieee754_xcpt(struct ieee754xctx *xcp);
/* compat */
#define ieee754dp_fix(x) ieee754dp_tint(x)
#define ieee754sp_fix(x) ieee754sp_tint(x)
+
+#endif /* __ARCH_MIPS_MATH_EMU_IEEE754_H */
diff --git a/arch/mips/math-emu/kernel_linkage.c b/arch/mips/math-emu/kernel_linkage.c
index 4002f0cf79f3..d187ab71c2ff 100644
--- a/arch/mips/math-emu/kernel_linkage.c
+++ b/arch/mips/math-emu/kernel_linkage.c
@@ -27,8 +27,6 @@
#include <asm/fpu_emulator.h>
-extern struct mips_fpu_emulator_private fpuemuprivate;
-
#define SIGNALLING_NAN 0x7ff800007ff80000LL
void fpu_emulator_init_fpu(void)
@@ -65,7 +63,6 @@ int fpu_emulator_save_context(struct sigcontext *sc)
&sc->sc_fpregs[i]);
}
err |= __put_user(current->thread.fpu.soft.fcr31, &sc->sc_fpc_csr);
- err |= __put_user(fpuemuprivate.eir, &sc->sc_fpc_eir);
return err;
}
@@ -81,7 +78,6 @@ int fpu_emulator_restore_context(struct sigcontext *sc)
&sc->sc_fpregs[i]);
}
err |= __get_user(current->thread.fpu.soft.fcr31, &sc->sc_fpc_csr);
- err |= __get_user(fpuemuprivate.eir, &sc->sc_fpc_eir);
return err;
}
@@ -102,7 +98,6 @@ int fpu_emulator_save_context32(struct sigcontext32 *sc)
&sc->sc_fpregs[i]);
}
err |= __put_user(current->thread.fpu.soft.fcr31, &sc->sc_fpc_csr);
- err |= __put_user(fpuemuprivate.eir, &sc->sc_fpc_eir);
return err;
}
@@ -118,7 +113,6 @@ int fpu_emulator_restore_context32(struct sigcontext32 *sc)
&sc->sc_fpregs[i]);
}
err |= __get_user(current->thread.fpu.soft.fcr31, &sc->sc_fpc_csr);
- err |= __get_user(fpuemuprivate.eir, &sc->sc_fpc_eir);
return err;
}
diff --git a/arch/mips/mips-boards/atlas/atlas_int.c b/arch/mips/mips-boards/atlas/atlas_int.c
index 19d4b0792460..bc0ebc69bfb3 100644
--- a/arch/mips/mips-boards/atlas/atlas_int.c
+++ b/arch/mips/mips-boards/atlas/atlas_int.c
@@ -76,14 +76,13 @@ static void end_atlas_irq(unsigned int irq)
}
static struct hw_interrupt_type atlas_irq_type = {
- "Atlas",
- startup_atlas_irq,
- shutdown_atlas_irq,
- enable_atlas_irq,
- disable_atlas_irq,
- mask_and_ack_atlas_irq,
- end_atlas_irq,
- NULL
+ .typename = "Atlas",
+ .startup = startup_atlas_irq,
+ .shutdown = shutdown_atlas_irq,
+ .enable = enable_atlas_irq,
+ .disable = disable_atlas_irq,
+ .ack = mask_and_ack_atlas_irq,
+ .end = end_atlas_irq,
};
static inline int ls1bit32(unsigned int x)
diff --git a/arch/mips/mips-boards/atlas/atlas_setup.c b/arch/mips/mips-boards/atlas/atlas_setup.c
index 0a1dd9bbc02e..625843b30bed 100644
--- a/arch/mips/mips-boards/atlas/atlas_setup.c
+++ b/arch/mips/mips-boards/atlas/atlas_setup.c
@@ -50,8 +50,10 @@ const char *get_system_type(void)
return "MIPS Atlas";
}
-static int __init atlas_setup(void)
+void __init plat_setup(void)
{
+ mips_pcibios_init();
+
ioport_resource.end = 0x7fffffff;
serial_init ();
@@ -64,12 +66,8 @@ static int __init atlas_setup(void)
board_time_init = mips_time_init;
board_timer_setup = mips_timer_setup;
rtc_get_time = mips_rtc_get_time;
-
- return 0;
}
-early_initcall(atlas_setup);
-
static void __init serial_init(void)
{
#ifdef CONFIG_SERIAL_8250
diff --git a/arch/mips/mips-boards/generic/init.c b/arch/mips/mips-boards/generic/init.c
index 311155d1d3ed..eab5a705e989 100644
--- a/arch/mips/mips-boards/generic/init.c
+++ b/arch/mips/mips-boards/generic/init.c
@@ -1,6 +1,8 @@
/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ * Copyright (C) 1999, 2000, 2004, 2005 MIPS Technologies, Inc.
+ * All rights reserved.
+ * Authors: Carsten Langgaard <carstenl@mips.com>
+ * Maciej W. Rozycki <macro@mips.com>
*
* This program is free software; you can distribute it and/or modify it
* under the terms of the GNU General Public License (Version 2) as
@@ -22,18 +24,19 @@
#include <linux/string.h>
#include <linux/kernel.h>
-#include <asm/io.h>
#include <asm/bootinfo.h>
+#include <asm/gt64120.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/cacheflush.h>
+#include <asm/traps.h>
+
#include <asm/mips-boards/prom.h>
#include <asm/mips-boards/generic.h>
-#ifdef CONFIG_MIPS_GT64120
-#include <asm/gt64120.h>
-#endif
-#include <asm/mips-boards/msc01_pci.h>
#include <asm/mips-boards/bonito64.h>
-#ifdef CONFIG_MIPS_MALTA
+#include <asm/mips-boards/msc01_pci.h>
+
#include <asm/mips-boards/malta.h>
-#endif
#ifdef CONFIG_KGDB
extern int rs_kgdb_hook(int, int);
@@ -223,8 +226,34 @@ void __init kgdb_config (void)
}
#endif
+void __init mips_nmi_setup (void)
+{
+ void *base;
+ extern char except_vec_nmi;
+
+ base = cpu_has_veic ?
+ (void *)(CAC_BASE + 0xa80) :
+ (void *)(CAC_BASE + 0x380);
+ memcpy(base, &except_vec_nmi, 0x80);
+ flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
+}
+
+void __init mips_ejtag_setup (void)
+{
+ void *base;
+ extern char except_vec_ejtag_debug;
+
+ base = cpu_has_veic ?
+ (void *)(CAC_BASE + 0xa00) :
+ (void *)(CAC_BASE + 0x300);
+ memcpy(base, &except_vec_ejtag_debug, 0x80);
+ flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
+}
+
void __init prom_init(void)
{
+ u32 start, map, mask, data;
+
prom_argc = fw_arg0;
_prom_argv = (int *) fw_arg1;
_prom_envp = (int *) fw_arg2;
@@ -266,12 +295,15 @@ void __init prom_init(void)
#else
GT_WRITE(GT_PCI0_CMD_OFS, 0);
#endif
+ /* Fix up PCI I/O mapping if necessary (for Atlas). */
+ start = GT_READ(GT_PCI0IOLD_OFS);
+ map = GT_READ(GT_PCI0IOREMAP_OFS);
+ if ((start & map) != 0) {
+ map &= ~start;
+ GT_WRITE(GT_PCI0IOREMAP_OFS, map);
+ }
-#ifdef CONFIG_MIPS_MALTA
set_io_port_base(MALTA_GT_PORT_BASE);
-#else
- set_io_port_base((unsigned long)ioremap(0, 0x20000000));
-#endif
break;
case MIPS_REVISION_CORID_CORE_EMUL_BON:
@@ -300,18 +332,21 @@ void __init prom_init(void)
BONITO_BONGENCFG_BYTESWAP;
#endif
-#ifdef CONFIG_MIPS_MALTA
set_io_port_base(MALTA_BONITO_PORT_BASE);
-#else
- set_io_port_base((unsigned long)ioremap(0, 0x20000000));
-#endif
break;
case MIPS_REVISION_CORID_CORE_MSC:
case MIPS_REVISION_CORID_CORE_FPGA2:
+ case MIPS_REVISION_CORID_CORE_FPGA3:
case MIPS_REVISION_CORID_CORE_EMUL_MSC:
_pcictrl_msc = (unsigned long)ioremap(MIPS_MSC01_PCI_REG_BASE, 0x2000);
+ mb();
+ MSC_READ(MSC01_PCI_CFG, data);
+ MSC_WRITE(MSC01_PCI_CFG, data & ~MSC01_PCI_CFG_EN_BIT);
+ wmb();
+
+ /* Fix up lane swapping. */
#ifdef CONFIG_CPU_LITTLE_ENDIAN
MSC_WRITE(MSC01_PCI_SWAP, MSC01_PCI_SWAP_NOSWAP);
#else
@@ -320,12 +355,23 @@ void __init prom_init(void)
MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_MEM_SHF |
MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_BAR0_SHF);
#endif
+ /* Fix up target memory mapping. */
+ MSC_READ(MSC01_PCI_BAR0, mask);
+ MSC_WRITE(MSC01_PCI_P2SCMSKL, mask & MSC01_PCI_BAR0_SIZE_MSK);
+
+ /* Don't handle target retries indefinitely. */
+ if ((data & MSC01_PCI_CFG_MAXRTRY_MSK) ==
+ MSC01_PCI_CFG_MAXRTRY_MSK)
+ data = (data & ~(MSC01_PCI_CFG_MAXRTRY_MSK <<
+ MSC01_PCI_CFG_MAXRTRY_SHF)) |
+ ((MSC01_PCI_CFG_MAXRTRY_MSK - 1) <<
+ MSC01_PCI_CFG_MAXRTRY_SHF);
+
+ wmb();
+ MSC_WRITE(MSC01_PCI_CFG, data);
+ mb();
-#ifdef CONFIG_MIPS_MALTA
set_io_port_base(MALTA_MSC_PORT_BASE);
-#else
- set_io_port_base((unsigned long)ioremap(0, 0x20000000));
-#endif
break;
default:
@@ -334,6 +380,9 @@ void __init prom_init(void)
while(1); /* We die here... */
}
#endif
+ board_nmi_handler_setup = mips_nmi_setup;
+ board_ejtag_handler_setup = mips_ejtag_setup;
+
prom_printf("\nLINUX started...\n");
prom_init_cmdline();
prom_meminit();
diff --git a/arch/mips/mips-boards/generic/memory.c b/arch/mips/mips-boards/generic/memory.c
index 5ae2b43e4c2e..2c8afd77a20b 100644
--- a/arch/mips/mips-boards/generic/memory.c
+++ b/arch/mips/mips-boards/generic/memory.c
@@ -22,6 +22,7 @@
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/bootmem.h>
+#include <linux/string.h>
#include <asm/bootinfo.h>
#include <asm/page.h>
@@ -55,18 +56,30 @@ struct prom_pmemblock * __init prom_getmdesc(void)
{
char *memsize_str;
unsigned int memsize;
+ char cmdline[CL_SIZE], *ptr;
- memsize_str = prom_getenv("memsize");
- if (!memsize_str) {
- prom_printf("memsize not set in boot prom, set to default (32Mb)\n");
- memsize = 0x02000000;
- } else {
+ /* Check the command line first for a memsize directive */
+ strcpy(cmdline, arcs_cmdline);
+ ptr = strstr(cmdline, "memsize=");
+ if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' '))
+ ptr = strstr(ptr, " memsize=");
+
+ if (ptr) {
+ memsize = memparse(ptr + 8, &ptr);
+ }
+ else {
+ /* otherwise look in the environment */
+ memsize_str = prom_getenv("memsize");
+ if (!memsize_str) {
+ prom_printf("memsize not set in boot prom, set to default (32Mb)\n");
+ memsize = 0x02000000;
+ } else {
#ifdef DEBUG
- prom_printf("prom_memsize = %s\n", memsize_str);
+ prom_printf("prom_memsize = %s\n", memsize_str);
#endif
- memsize = simple_strtol(memsize_str, NULL, 0);
+ memsize = simple_strtol(memsize_str, NULL, 0);
+ }
}
-
memset(mdesc, 0, sizeof(mdesc));
mdesc[0].type = yamon_dontuse;
diff --git a/arch/mips/mips-boards/generic/mipsIRQ.S b/arch/mips/mips-boards/generic/mipsIRQ.S
index 131f49bccb20..a397ecb872d6 100644
--- a/arch/mips/mips-boards/generic/mipsIRQ.S
+++ b/arch/mips/mips-boards/generic/mipsIRQ.S
@@ -29,6 +29,20 @@
#include <asm/regdef.h>
#include <asm/stackframe.h>
+#ifdef CONFIG_MIPS_ATLAS
+#include <asm/mips-boards/atlasint.h>
+#define CASCADE_IRQ MIPSCPU_INT_ATLAS
+#define CASCADE_DISPATCH atlas_hw0_irqdispatch
+#endif
+#ifdef CONFIG_MIPS_MALTA
+#include <asm/mips-boards/maltaint.h>
+#define CASCADE_IRQ MIPSCPU_INT_I8259A
+#define CASCADE_DISPATCH malta_hw0_irqdispatch
+#endif
+#ifdef CONFIG_MIPS_SEAD
+#include <asm/mips-boards/seadint.h>
+#endif
+
/* A lot of complication here is taken away because:
*
* 1) We handle one interrupt and return, sitting in a loop and moving across
@@ -80,74 +94,62 @@
mfc0 s0, CP0_CAUSE # get irq bits
mfc0 s1, CP0_STATUS # get irq mask
+ andi s0, ST0_IM # CAUSE.CE may be non-zero!
and s0, s1
- /* First we check for r4k counter/timer IRQ. */
- andi a0, s0, CAUSEF_IP7
- beq a0, zero, 1f
- andi a0, s0, CAUSEF_IP2 # delay slot, check hw0 interrupt
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
+ .set mips32
+ clz a0, s0
+ .set mips0
+ negu a0
+ addu a0, 31-CAUSEB_IP
+ bltz a0, spurious
+#else
+ beqz s0, spurious
+ li a0, 7
- /* Wheee, a timer interrupt. */
- move a0, sp
- jal mips_timer_interrupt
- nop
+ and t0, s0, 0xf000
+ sltiu t0, t0, 1
+ sll t0, 2
+ subu a0, t0
+ sll s0, t0
- j ret_from_irq
- nop
+ and t0, s0, 0xc000
+ sltiu t0, t0, 1
+ sll t0, 1
+ subu a0, t0
+ sll s0, t0
-1:
-#if defined(CONFIG_MIPS_SEAD)
- beq a0, zero, 1f
- andi a0, s0, CAUSEF_IP3 # delay slot, check hw1 interrupt
-#else
- beq a0, zero, 1f # delay slot, check hw3 interrupt
- andi a0, s0, CAUSEF_IP5
+ and t0, s0, 0x8000
+ sltiu t0, t0, 1
+ # sll t0, 0
+ subu a0, t0
+ # sll s0, t0
#endif
- /* Wheee, combined hardware level zero interrupt. */
-#if defined(CONFIG_MIPS_ATLAS)
- jal atlas_hw0_irqdispatch
-#elif defined(CONFIG_MIPS_MALTA)
- jal malta_hw0_irqdispatch
-#elif defined(CONFIG_MIPS_SEAD)
- jal sead_hw0_irqdispatch
-#else
-#error "MIPS board not supported\n"
-#endif
- move a0, sp # delay slot
+#ifdef CASCADE_IRQ
+ li a1, CASCADE_IRQ
+ bne a0, a1, 1f
+ addu a0, MIPSCPU_INT_BASE
- j ret_from_irq
- nop # delay slot
+ jal CASCADE_DISPATCH
+ move a0, sp
-1:
-#if defined(CONFIG_MIPS_SEAD)
- beq a0, zero, 1f
- andi a0, s0, CAUSEF_IP5 # delay slot, check hw3 interrupt
- jal sead_hw1_irqdispatch
- move a0, sp # delay slot
- j ret_from_irq
- nop # delay slot
-1:
-#endif
-#if defined(CONFIG_MIPS_MALTA)
- beq a0, zero, 1f # check hw3 (coreHI) interrupt
- nop
- jal corehi_irqdispatch
- move a0, sp
j ret_from_irq
nop
1:
+#else
+ addu a0, MIPSCPU_INT_BASE
#endif
- /*
- * Here by mistake? This is possible, what can happen is that by the
- * time we take the exception the IRQ pin goes low, so just leave if
- * this is the case.
- */
- move a1,s0
- PRINT("Got interrupt: c0_cause = %08x\n")
- mfc0 a1, CP0_EPC
- PRINT("c0_epc = %08x\n")
+
+ jal do_IRQ
+ move a1, sp
j ret_from_irq
nop
+
+
+spurious:
+ j spurious_interrupt
+ nop
END(mipsIRQ)
diff --git a/arch/mips/mips-boards/generic/pci.c b/arch/mips/mips-boards/generic/pci.c
index 92c34bda02ae..1f6f9df74ab2 100644
--- a/arch/mips/mips-boards/generic/pci.c
+++ b/arch/mips/mips-boards/generic/pci.c
@@ -1,6 +1,8 @@
/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved.
+ * Copyright (C) 1999, 2000, 2004, 2005 MIPS Technologies, Inc.
+ * All rights reserved.
+ * Authors: Carsten Langgaard <carstenl@mips.com>
+ * Maciej W. Rozycki <macro@mips.com>
*
* Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
*
@@ -19,65 +21,46 @@
*
* MIPS boards specific PCI support.
*/
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <asm/mips-boards/generic.h>
#include <asm/gt64120.h>
+
+#include <asm/mips-boards/generic.h>
#include <asm/mips-boards/bonito64.h>
#include <asm/mips-boards/msc01_pci.h>
-#ifdef CONFIG_MIPS_MALTA
-#include <asm/mips-boards/malta.h>
-#endif
static struct resource bonito64_mem_resource = {
.name = "Bonito PCI MEM",
- .start = 0x10000000UL,
- .end = 0x1bffffffUL,
.flags = IORESOURCE_MEM,
};
static struct resource bonito64_io_resource = {
- .name = "Bonito IO MEM",
- .start = 0x00002000UL, /* avoid conflicts with YAMON allocated I/O addresses */
+ .name = "Bonito PCI I/O",
+ .start = 0x00000000UL,
.end = 0x000fffffUL,
.flags = IORESOURCE_IO,
};
static struct resource gt64120_mem_resource = {
- .name = "GT64120 PCI MEM",
- .start = 0x10000000UL,
- .end = 0x1bdfffffUL,
+ .name = "GT-64120 PCI MEM",
.flags = IORESOURCE_MEM,
};
static struct resource gt64120_io_resource = {
- .name = "GT64120 IO MEM",
-#ifdef CONFIG_MIPS_ATLAS
- .start = 0x18000000UL,
- .end = 0x181fffffUL,
-#endif
-#ifdef CONFIG_MIPS_MALTA
- .start = 0x00002000UL,
- .end = 0x001fffffUL,
-#endif
+ .name = "GT-64120 PCI I/O",
.flags = IORESOURCE_IO,
};
static struct resource msc_mem_resource = {
.name = "MSC PCI MEM",
- .start = 0x10000000UL,
- .end = 0x1fffffffUL,
.flags = IORESOURCE_MEM,
};
static struct resource msc_io_resource = {
- .name = "MSC IO MEM",
- .start = 0x00002000UL,
- .end = 0x007fffffUL,
+ .name = "MSC PCI I/O",
.flags = IORESOURCE_IO,
};
@@ -89,7 +72,6 @@ static struct pci_controller bonito64_controller = {
.pci_ops = &bonito64_pci_ops,
.io_resource = &bonito64_io_resource,
.mem_resource = &bonito64_mem_resource,
- .mem_offset = 0x10000000UL,
.io_offset = 0x00000000UL,
};
@@ -97,21 +79,18 @@ static struct pci_controller gt64120_controller = {
.pci_ops = &gt64120_pci_ops,
.io_resource = &gt64120_io_resource,
.mem_resource = &gt64120_mem_resource,
- .mem_offset = 0x00000000UL,
- .io_offset = 0x00000000UL,
};
-static struct pci_controller msc_controller = {
+static struct pci_controller msc_controller = {
.pci_ops = &msc_pci_ops,
.io_resource = &msc_io_resource,
.mem_resource = &msc_mem_resource,
- .mem_offset = 0x10000000UL,
- .io_offset = 0x00000000UL,
};
-static int __init pcibios_init(void)
+void __init mips_pcibios_init(void)
{
struct pci_controller *controller;
+ unsigned long start, end, map, start1, end1, map1, map2, map3, mask;
switch (mips_revision_corid) {
case MIPS_REVISION_CORID_QED_RM5261:
@@ -130,34 +109,140 @@ static int __init pcibios_init(void)
(0 << GT_PCI0_CFGADDR_DEVNUM_SHF) | /* GT64120 dev */
(0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | /* Function 0*/
((0x20/4) << GT_PCI0_CFGADDR_REGNUM_SHF) | /* BAR 4*/
- GT_PCI0_CFGADDR_CONFIGEN_BIT );
+ GT_PCI0_CFGADDR_CONFIGEN_BIT);
/* Perform the write */
GT_WRITE(GT_PCI0_CFGDATA_OFS, CPHYSADDR(MIPS_GT_BASE));
+ /* Set up resource ranges from the controller's registers. */
+ start = GT_READ(GT_PCI0M0LD_OFS);
+ end = GT_READ(GT_PCI0M0HD_OFS);
+ map = GT_READ(GT_PCI0M0REMAP_OFS);
+ end = (end & GT_PCI_HD_MSK) | (start & ~GT_PCI_HD_MSK);
+ start1 = GT_READ(GT_PCI0M1LD_OFS);
+ end1 = GT_READ(GT_PCI0M1HD_OFS);
+ map1 = GT_READ(GT_PCI0M1REMAP_OFS);
+ end1 = (end1 & GT_PCI_HD_MSK) | (start1 & ~GT_PCI_HD_MSK);
+ /* Cannot support multiple windows, use the wider. */
+ if (end1 - start1 > end - start) {
+ start = start1;
+ end = end1;
+ map = map1;
+ }
+ mask = ~(start ^ end);
+ /* We don't support remapping with a discontiguous mask. */
+ BUG_ON((start & GT_PCI_HD_MSK) != (map & GT_PCI_HD_MSK) &&
+ mask != ~((mask & -mask) - 1));
+ gt64120_mem_resource.start = start;
+ gt64120_mem_resource.end = end;
+ gt64120_controller.mem_offset = (start & mask) - (map & mask);
+ /* Addresses are 36-bit, so do shifts in the destinations. */
+ gt64120_mem_resource.start <<= GT_PCI_DCRM_SHF;
+ gt64120_mem_resource.end <<= GT_PCI_DCRM_SHF;
+ gt64120_mem_resource.end |= (1 << GT_PCI_DCRM_SHF) - 1;
+ gt64120_controller.mem_offset <<= GT_PCI_DCRM_SHF;
+
+ start = GT_READ(GT_PCI0IOLD_OFS);
+ end = GT_READ(GT_PCI0IOHD_OFS);
+ map = GT_READ(GT_PCI0IOREMAP_OFS);
+ end = (end & GT_PCI_HD_MSK) | (start & ~GT_PCI_HD_MSK);
+ mask = ~(start ^ end);
+ /* We don't support remapping with a discontiguous mask. */
+ BUG_ON((start & GT_PCI_HD_MSK) != (map & GT_PCI_HD_MSK) &&
+ mask != ~((mask & -mask) - 1));
+ gt64120_io_resource.start = map & mask;
+ gt64120_io_resource.end = (map & mask) | ~mask;
+ gt64120_controller.io_offset = 0;
+ /* Addresses are 36-bit, so do shifts in the destinations. */
+ gt64120_io_resource.start <<= GT_PCI_DCRM_SHF;
+ gt64120_io_resource.end <<= GT_PCI_DCRM_SHF;
+ gt64120_io_resource.end |= (1 << GT_PCI_DCRM_SHF) - 1;
+
controller = &gt64120_controller;
break;
case MIPS_REVISION_CORID_BONITO64:
case MIPS_REVISION_CORID_CORE_20K:
case MIPS_REVISION_CORID_CORE_EMUL_BON:
+ /* Set up resource ranges from the controller's registers. */
+ map = BONITO_PCIMAP;
+ map1 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO0) >>
+ BONITO_PCIMAP_PCIMAP_LO0_SHIFT;
+ map2 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO1) >>
+ BONITO_PCIMAP_PCIMAP_LO1_SHIFT;
+ map3 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO2) >>
+ BONITO_PCIMAP_PCIMAP_LO2_SHIFT;
+ /* Combine as many adjacent windows as possible. */
+ map = map1;
+ start = BONITO_PCILO0_BASE;
+ end = 1;
+ if (map3 == map2 + 1) {
+ map = map2;
+ start = BONITO_PCILO1_BASE;
+ end++;
+ }
+ if (map2 == map1 + 1) {
+ map = map1;
+ start = BONITO_PCILO0_BASE;
+ end++;
+ }
+ bonito64_mem_resource.start = start;
+ bonito64_mem_resource.end = start +
+ BONITO_PCIMAP_WINBASE(end) - 1;
+ bonito64_controller.mem_offset = start -
+ BONITO_PCIMAP_WINBASE(map);
+
controller = &bonito64_controller;
break;
case MIPS_REVISION_CORID_CORE_MSC:
case MIPS_REVISION_CORID_CORE_FPGA2:
+ case MIPS_REVISION_CORID_CORE_FPGA3:
case MIPS_REVISION_CORID_CORE_EMUL_MSC:
+ /* Set up resource ranges from the controller's registers. */
+ MSC_READ(MSC01_PCI_SC2PMBASL, start);
+ MSC_READ(MSC01_PCI_SC2PMMSKL, mask);
+ MSC_READ(MSC01_PCI_SC2PMMAPL, map);
+ msc_mem_resource.start = start & mask;
+ msc_mem_resource.end = (start & mask) | ~mask;
+ msc_controller.mem_offset = (start & mask) - (map & mask);
+
+ MSC_READ(MSC01_PCI_SC2PIOBASL, start);
+ MSC_READ(MSC01_PCI_SC2PIOMSKL, mask);
+ MSC_READ(MSC01_PCI_SC2PIOMAPL, map);
+ msc_io_resource.start = map & mask;
+ msc_io_resource.end = (map & mask) | ~mask;
+ msc_controller.io_offset = 0;
+ ioport_resource.end = ~mask;
+
+ /* If ranges overlap I/O takes precedence. */
+ start = start & mask;
+ end = start | ~mask;
+ if ((start >= msc_mem_resource.start &&
+ start <= msc_mem_resource.end) ||
+ (end >= msc_mem_resource.start &&
+ end <= msc_mem_resource.end)) {
+ /* Use the larger space. */
+ start = max(start, msc_mem_resource.start);
+ end = min(end, msc_mem_resource.end);
+ if (start - msc_mem_resource.start >=
+ msc_mem_resource.end - end)
+ msc_mem_resource.end = start - 1;
+ else
+ msc_mem_resource.start = end + 1;
+ }
+
controller = &msc_controller;
break;
default:
- return 1;
+ return;
}
+ if (controller->io_resource->start < 0x00001000UL) /* FIXME */
+ controller->io_resource->start = 0x00001000UL;
+
+ iomem_resource.end &= 0xfffffffffULL; /* 64 GB */
ioport_resource.end = controller->io_resource->end;
register_pci_controller (controller);
-
- return 0;
}
-
-early_initcall(pcibios_init);
diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c
index 16315444dd5a..72a12d931cba 100644
--- a/arch/mips/mips-boards/generic/time.c
+++ b/arch/mips/mips-boards/generic/time.c
@@ -31,22 +31,21 @@
#include <asm/mipsregs.h>
#include <asm/ptrace.h>
+#include <asm/hardirq.h>
+#include <asm/irq.h>
#include <asm/div64.h>
#include <asm/cpu.h>
#include <asm/time.h>
#include <asm/mc146818-time.h>
+#include <asm/msc01_ic.h>
#include <asm/mips-boards/generic.h>
#include <asm/mips-boards/prom.h>
+#include <asm/mips-boards/maltaint.h>
+#include <asm/mc146818-time.h>
unsigned long cpu_khz;
-#if defined(CONFIG_MIPS_SEAD)
-#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ5)
-#else
-#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
-#endif
-
#if defined(CONFIG_MIPS_ATLAS)
static char display_string[] = " LINUX ON ATLAS ";
#endif
@@ -59,20 +58,61 @@ static char display_string[] = " LINUX ON SEAD ";
static unsigned int display_count = 0;
#define MAX_DISPLAY_COUNT (sizeof(display_string) - 8)
-#define MIPS_CPU_TIMER_IRQ (NR_IRQS-1)
-
static unsigned int timer_tick_count=0;
+static int mips_cpu_timer_irq;
-void mips_timer_interrupt(struct pt_regs *regs)
+static inline void scroll_display_message(void)
{
if ((timer_tick_count++ % HZ) == 0) {
mips_display_message(&display_string[display_count++]);
if (display_count == MAX_DISPLAY_COUNT)
- display_count = 0;
+ display_count = 0;
+ }
+}
+
+static void mips_timer_dispatch (struct pt_regs *regs)
+{
+ do_IRQ (mips_cpu_timer_irq, regs);
+}
+irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+#ifdef CONFIG_SMP
+ int cpu = smp_processor_id();
+
+ if (cpu == 0) {
+ /*
+ * CPU 0 handles the global timer interrupt job and process accounting
+ * resets count/compare registers to trigger next timer int.
+ */
+ (void) timer_interrupt(irq, dev_id, regs);
+ scroll_display_message();
+ }
+ else {
+ /* Everyone else needs to reset the timer int here as
+ ll_local_timer_interrupt doesn't */
+ /*
+ * FIXME: need to cope with counter underflow.
+ * More support needs to be added to kernel/time for
+ * counter/timer interrupts on multiple CPU's
+ */
+ write_c0_compare (read_c0_count() + (mips_hpt_frequency/HZ));
+ /*
+ * other CPUs should do profiling and process accounting
+ */
+ local_timer_interrupt (irq, dev_id, regs);
}
- ll_timer_interrupt(MIPS_CPU_TIMER_IRQ, regs);
+ return IRQ_HANDLED;
+#else
+ irqreturn_t r;
+
+ r = timer_interrupt(irq, dev_id, regs);
+
+ scroll_display_message();
+
+ return r;
+#endif
}
/*
@@ -140,10 +180,8 @@ void __init mips_time_init(void)
local_irq_save(flags);
-#if defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_MALTA)
/* Set Data mode - binary. */
CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
-#endif
est_freq = estimate_cpu_frequency ();
@@ -157,11 +195,29 @@ void __init mips_time_init(void)
void __init mips_timer_setup(struct irqaction *irq)
{
+ if (cpu_has_veic) {
+ set_vi_handler (MSC01E_INT_CPUCTR, mips_timer_dispatch);
+ mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR;
+ }
+ else {
+ if (cpu_has_vint)
+ set_vi_handler (MIPSCPU_INT_CPUCTR, mips_timer_dispatch);
+ mips_cpu_timer_irq = MIPSCPU_INT_BASE + MIPSCPU_INT_CPUCTR;
+ }
+
+
/* we are using the cpu counter for timer interrupts */
- irq->handler = no_action; /* we use our own handler */
- setup_irq(MIPS_CPU_TIMER_IRQ, irq);
+ irq->handler = mips_timer_interrupt; /* we use our own handler */
+ setup_irq(mips_cpu_timer_irq, irq);
+
+#ifdef CONFIG_SMP
+ /* irq_desc(riptor) is a global resource, when the interrupt overlaps
+ on seperate cpu's the first one tries to handle the second interrupt.
+ The effect is that the int remains disabled on the second cpu.
+ Mark the interrupt with IRQ_PER_CPU to avoid any confusion */
+ irq_desc[mips_cpu_timer_irq].status |= IRQ_PER_CPU;
+#endif
/* to generate the first timer interrupt */
write_c0_compare (read_c0_count() + mips_hpt_frequency/HZ);
- set_c0_status(ALLINTS);
}
diff --git a/arch/mips/mips-boards/malta/malta_int.c b/arch/mips/mips-boards/malta/malta_int.c
index dd2db35966bc..d06dc5ad6c9e 100644
--- a/arch/mips/mips-boards/malta/malta_int.c
+++ b/arch/mips/mips-boards/malta/malta_int.c
@@ -30,6 +30,7 @@
#include <linux/random.h>
#include <asm/i8259.h>
+#include <asm/irq_cpu.h>
#include <asm/io.h>
#include <asm/mips-boards/malta.h>
#include <asm/mips-boards/maltaint.h>
@@ -37,8 +38,10 @@
#include <asm/gt64120.h>
#include <asm/mips-boards/generic.h>
#include <asm/mips-boards/msc01_pci.h>
+#include <asm/msc01_ic.h>
extern asmlinkage void mipsIRQ(void);
+extern void mips_timer_interrupt(void);
static DEFINE_SPINLOCK(mips_irq_lock);
@@ -54,6 +57,7 @@ static inline int mips_pcibios_iack(void)
switch(mips_revision_corid) {
case MIPS_REVISION_CORID_CORE_MSC:
case MIPS_REVISION_CORID_CORE_FPGA2:
+ case MIPS_REVISION_CORID_CORE_FPGA3:
case MIPS_REVISION_CORID_CORE_EMUL_MSC:
MSC_READ(MSC01_PCI_IACK, irq);
irq &= 0xff;
@@ -91,88 +95,86 @@ static inline int mips_pcibios_iack(void)
return irq;
}
-static inline int get_int(int *irq)
+static inline int get_int(void)
{
unsigned long flags;
-
+ int irq;
spin_lock_irqsave(&mips_irq_lock, flags);
- *irq = mips_pcibios_iack();
+ irq = mips_pcibios_iack();
/*
- * IRQ7 is used to detect spurious interrupts.
- * The interrupt acknowledge cycle returns IRQ7, if no
- * interrupts is requested.
- * We can differentiate between this situation and a
- * "Normal" IRQ7 by reading the ISR.
+ * The only way we can decide if an interrupt is spurious
+ * is by checking the 8259 registers. This needs a spinlock
+ * on an SMP system, so leave it up to the generic code...
*/
- if (*irq == 7)
- {
- outb(PIIX4_OCW3_SEL | PIIX4_OCW3_ISR,
- PIIX4_ICTLR1_OCW3);
- if (!(inb(PIIX4_ICTLR1_OCW3) & (1 << 7))) {
- spin_unlock_irqrestore(&mips_irq_lock, flags);
- printk("We got a spurious interrupt from PIIX4.\n");
- atomic_inc(&irq_err_count);
- return -1; /* Spurious interrupt. */
- }
- }
spin_unlock_irqrestore(&mips_irq_lock, flags);
- return 0;
+ return irq;
}
void malta_hw0_irqdispatch(struct pt_regs *regs)
{
int irq;
- if (get_int(&irq))
- return; /* interrupt has already been cleared */
+ irq = get_int();
+ if (irq < 0)
+ return; /* interrupt has already been cleared */
- do_IRQ(irq, regs);
+ do_IRQ(MALTA_INT_BASE+irq, regs);
}
void corehi_irqdispatch(struct pt_regs *regs)
{
- unsigned int data,datahi;
-
- /* Mask out corehi interrupt. */
- clear_c0_status(IE_IRQ3);
+ unsigned int intrcause,datalo,datahi;
+ unsigned int pcimstat, intisr, inten, intpol, intedge, intsteer, pcicmd, pcibadaddr;
printk("CoreHI interrupt, shouldn't happen, so we die here!!!\n");
printk("epc : %08lx\nStatus: %08lx\nCause : %08lx\nbadVaddr : %08lx\n"
, regs->cp0_epc, regs->cp0_status, regs->cp0_cause, regs->cp0_badvaddr);
+
+ /* Read all the registers and then print them as there is a
+ problem with interspersed printk's upsetting the Bonito controller.
+ Do it for the others too.
+ */
+
switch(mips_revision_corid) {
case MIPS_REVISION_CORID_CORE_MSC:
case MIPS_REVISION_CORID_CORE_FPGA2:
- case MIPS_REVISION_CORID_CORE_EMUL_MSC:
+ case MIPS_REVISION_CORID_CORE_FPGA3:
+ case MIPS_REVISION_CORID_CORE_EMUL_MSC:
+ ll_msc_irq(regs);
break;
case MIPS_REVISION_CORID_QED_RM5261:
case MIPS_REVISION_CORID_CORE_LV:
case MIPS_REVISION_CORID_CORE_FPGA:
case MIPS_REVISION_CORID_CORE_FPGAR2:
- data = GT_READ(GT_INTRCAUSE_OFS);
- printk("GT_INTRCAUSE = %08x\n", data);
- data = GT_READ(GT_CPUERR_ADDRLO_OFS);
+ intrcause = GT_READ(GT_INTRCAUSE_OFS);
+ datalo = GT_READ(GT_CPUERR_ADDRLO_OFS);
datahi = GT_READ(GT_CPUERR_ADDRHI_OFS);
- printk("GT_CPUERR_ADDR = %02x%08x\n", datahi, data);
+ printk("GT_INTRCAUSE = %08x\n", intrcause);
+ printk("GT_CPUERR_ADDR = %02x%08x\n", datahi, datalo);
break;
case MIPS_REVISION_CORID_BONITO64:
case MIPS_REVISION_CORID_CORE_20K:
case MIPS_REVISION_CORID_CORE_EMUL_BON:
- data = BONITO_INTISR;
- printk("BONITO_INTISR = %08x\n", data);
- data = BONITO_INTEN;
- printk("BONITO_INTEN = %08x\n", data);
- data = BONITO_INTPOL;
- printk("BONITO_INTPOL = %08x\n", data);
- data = BONITO_INTEDGE;
- printk("BONITO_INTEDGE = %08x\n", data);
- data = BONITO_INTSTEER;
- printk("BONITO_INTSTEER = %08x\n", data);
- data = BONITO_PCICMD;
- printk("BONITO_PCICMD = %08x\n", data);
+ pcibadaddr = BONITO_PCIBADADDR;
+ pcimstat = BONITO_PCIMSTAT;
+ intisr = BONITO_INTISR;
+ inten = BONITO_INTEN;
+ intpol = BONITO_INTPOL;
+ intedge = BONITO_INTEDGE;
+ intsteer = BONITO_INTSTEER;
+ pcicmd = BONITO_PCICMD;
+ printk("BONITO_INTISR = %08x\n", intisr);
+ printk("BONITO_INTEN = %08x\n", inten);
+ printk("BONITO_INTPOL = %08x\n", intpol);
+ printk("BONITO_INTEDGE = %08x\n", intedge);
+ printk("BONITO_INTSTEER = %08x\n", intsteer);
+ printk("BONITO_PCICMD = %08x\n", pcicmd);
+ printk("BONITO_PCIBADADDR = %08x\n", pcibadaddr);
+ printk("BONITO_PCIMSTAT = %08x\n", pcimstat);
break;
}
@@ -180,8 +182,71 @@ void corehi_irqdispatch(struct pt_regs *regs)
die("CoreHi interrupt", regs);
}
+static struct irqaction i8259irq = {
+ .handler = no_action,
+ .name = "XT-PIC cascade"
+};
+
+static struct irqaction corehi_irqaction = {
+ .handler = no_action,
+ .name = "CoreHi"
+};
+
+msc_irqmap_t __initdata msc_irqmap[] = {
+ {MSC01C_INT_TMR, MSC01_IRQ_EDGE, 0},
+ {MSC01C_INT_PCI, MSC01_IRQ_LEVEL, 0},
+};
+int __initdata msc_nr_irqs = sizeof(msc_irqmap)/sizeof(msc_irqmap_t);
+
+msc_irqmap_t __initdata msc_eicirqmap[] = {
+ {MSC01E_INT_SW0, MSC01_IRQ_LEVEL, 0},
+ {MSC01E_INT_SW1, MSC01_IRQ_LEVEL, 0},
+ {MSC01E_INT_I8259A, MSC01_IRQ_LEVEL, 0},
+ {MSC01E_INT_SMI, MSC01_IRQ_LEVEL, 0},
+ {MSC01E_INT_COREHI, MSC01_IRQ_LEVEL, 0},
+ {MSC01E_INT_CORELO, MSC01_IRQ_LEVEL, 0},
+ {MSC01E_INT_TMR, MSC01_IRQ_EDGE, 0},
+ {MSC01E_INT_PCI, MSC01_IRQ_LEVEL, 0},
+ {MSC01E_INT_PERFCTR, MSC01_IRQ_LEVEL, 0},
+ {MSC01E_INT_CPUCTR, MSC01_IRQ_LEVEL, 0}
+};
+int __initdata msc_nr_eicirqs = sizeof(msc_eicirqmap)/sizeof(msc_irqmap_t);
+
void __init arch_init_irq(void)
{
set_except_vector(0, mipsIRQ);
init_i8259_irqs();
+
+ if (!cpu_has_veic)
+ mips_cpu_irq_init (MIPSCPU_INT_BASE);
+
+ switch(mips_revision_corid) {
+ case MIPS_REVISION_CORID_CORE_MSC:
+ case MIPS_REVISION_CORID_CORE_FPGA2:
+ case MIPS_REVISION_CORID_CORE_FPGA3:
+ case MIPS_REVISION_CORID_CORE_EMUL_MSC:
+ if (cpu_has_veic)
+ init_msc_irqs (MSC01E_INT_BASE, msc_eicirqmap, msc_nr_eicirqs);
+ else
+ init_msc_irqs (MSC01C_INT_BASE, msc_irqmap, msc_nr_irqs);
+ }
+
+ if (cpu_has_veic) {
+ set_vi_handler (MSC01E_INT_I8259A, malta_hw0_irqdispatch);
+ set_vi_handler (MSC01E_INT_COREHI, corehi_irqdispatch);
+ setup_irq (MSC01E_INT_BASE+MSC01E_INT_I8259A, &i8259irq);
+ setup_irq (MSC01E_INT_BASE+MSC01E_INT_COREHI, &corehi_irqaction);
+ }
+ else if (cpu_has_vint) {
+ set_vi_handler (MIPSCPU_INT_I8259A, malta_hw0_irqdispatch);
+ set_vi_handler (MIPSCPU_INT_COREHI, corehi_irqdispatch);
+
+ setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_I8259A, &i8259irq);
+ setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction);
+ }
+ else {
+ set_except_vector(0, mipsIRQ);
+ setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_I8259A, &i8259irq);
+ setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction);
+ }
}
diff --git a/arch/mips/mips-boards/malta/malta_setup.c b/arch/mips/mips-boards/malta/malta_setup.c
index df6db6419ae9..2209e8a9de34 100644
--- a/arch/mips/mips-boards/malta/malta_setup.c
+++ b/arch/mips/mips-boards/malta/malta_setup.c
@@ -111,10 +111,12 @@ void __init fd_activate(void)
}
#endif
-static int __init malta_setup(void)
+void __init plat_setup(void)
{
unsigned int i;
+ mips_pcibios_init();
+
/* Request I/O space for devices used on the Malta board. */
for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++)
request_resource(&ioport_resource, standard_io_resources+i);
@@ -224,8 +226,4 @@ static int __init malta_setup(void)
board_time_init = mips_time_init;
board_timer_setup = mips_timer_setup;
rtc_get_time = mips_rtc_get_time;
-
- return 0;
}
-
-early_initcall(malta_setup);
diff --git a/arch/mips/mips-boards/sead/sead_int.c b/arch/mips/mips-boards/sead/sead_int.c
index e5109657ed5a..e1dd7e009750 100644
--- a/arch/mips/mips-boards/sead/sead_int.c
+++ b/arch/mips/mips-boards/sead/sead_int.c
@@ -2,6 +2,7 @@
* Carsten Langgaard, carstenl@mips.com
* Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved.
* Copyright (C) 2003 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2004 Maciej W. Rozycki
*
* This program is free software; you can distribute it and/or modify it
* under the terms of the GNU General Public License (Version 2) as
@@ -21,7 +22,9 @@
*/
#include <linux/init.h>
#include <linux/irq.h>
-#include <linux/interrupt.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/system.h>
#include <asm/mips-boards/seadint.h>
@@ -39,13 +42,8 @@ asmlinkage void sead_hw1_irqdispatch(struct pt_regs *regs)
void __init arch_init_irq(void)
{
- /*
- * Mask out all interrupt
- */
- clear_c0_status(0x0000ff00);
+ mips_cpu_irq_init(0);
/* Now safe to set the exception vector. */
set_except_vector(0, mipsIRQ);
-
- mips_cpu_irq_init(0);
}
diff --git a/arch/mips/mips-boards/sead/sead_setup.c b/arch/mips/mips-boards/sead/sead_setup.c
index 29892b88a4fc..de90bec5505e 100644
--- a/arch/mips/mips-boards/sead/sead_setup.c
+++ b/arch/mips/mips-boards/sead/sead_setup.c
@@ -57,8 +57,6 @@ static void __init sead_setup(void)
mips_reboot_setup();
}
-early_initcall(sead_setup);
-
static void __init serial_init(void)
{
#ifdef CONFIG_SERIAL_8250
diff --git a/arch/mips/mips-boards/sim/Makefile b/arch/mips/mips-boards/sim/Makefile
new file mode 100644
index 000000000000..5b977de4ecff
--- /dev/null
+++ b/arch/mips/mips-boards/sim/Makefile
@@ -0,0 +1,20 @@
+#
+# Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+#
+# This program is free software; you can distribute it and/or modify it
+# under the terms of the GNU General Public License (Version 2) as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+
+obj-y := sim_setup.o sim_mem.o sim_time.o sim_printf.o sim_int.o sim_irq.o \
+ sim_cmdline.o
+obj-$(CONFIG_SMP) += sim_smp.o
diff --git a/arch/mips/mips-boards/sim/cmdline.c b/arch/mips/mips-boards/sim/cmdline.c
new file mode 100644
index 000000000000..fef9fbd8e710
--- /dev/null
+++ b/arch/mips/mips-boards/sim/cmdline.c
@@ -0,0 +1,59 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Kernel command line creation using the prom monitor (YAMON) argc/argv.
+ */
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+
+extern int prom_argc;
+extern int *_prom_argv;
+
+/*
+ * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer.
+ * This macro take care of sign extension.
+ */
+#define prom_argv(index) ((char *)(((int *)(int)_prom_argv)[(index)]))
+
+char arcs_cmdline[CL_SIZE];
+
+char * __init prom_getcmdline(void)
+{
+ return &(arcs_cmdline[0]);
+}
+
+
+void __init prom_init_cmdline(void)
+{
+ char *cp;
+ int actr;
+
+ actr = 1; /* Always ignore argv[0] */
+
+ cp = &(arcs_cmdline[0]);
+ while(actr < prom_argc) {
+ strcpy(cp, prom_argv(actr));
+ cp += strlen(prom_argv(actr));
+ *cp++ = ' ';
+ actr++;
+ }
+ if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
+ --cp;
+ *cp = '\0';
+}
diff --git a/arch/mips/mips-boards/sim/sim_IRQ.c b/arch/mips/mips-boards/sim/sim_IRQ.c
new file mode 100644
index 000000000000..9987a85aabeb
--- /dev/null
+++ b/arch/mips/mips-boards/sim/sim_IRQ.c
@@ -0,0 +1,148 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Interrupt exception dispatch code.
+ */
+#include <linux/config.h>
+
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+/* A lot of complication here is taken away because:
+ *
+ * 1) We handle one interrupt and return, sitting in a loop and moving across
+ * all the pending IRQ bits in the cause register is _NOT_ the answer, the
+ * common case is one pending IRQ so optimize in that direction.
+ *
+ * 2) We need not check against bits in the status register IRQ mask, that
+ * would make this routine slow as hell.
+ *
+ * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in
+ * between like BSD spl() brain-damage.
+ *
+ * Furthermore, the IRQs on the MIPS board look basically (barring software
+ * IRQs which we don't use at all and all external interrupt sources are
+ * combined together on hardware interrupt 0 (MIPS IRQ 2)) like:
+ *
+ * MIPS IRQ Source
+ * -------- ------
+ * 0 Software (ignored)
+ * 1 Software (ignored)
+ * 2 Combined hardware interrupt (hw0)
+ * 3 Hardware (ignored)
+ * 4 Hardware (ignored)
+ * 5 Hardware (ignored)
+ * 6 Hardware (ignored)
+ * 7 R4k timer (what we use)
+ *
+ * Note: On the SEAD board thing are a little bit different.
+ * Here IRQ 2 (hw0) is wired to the UART0 and IRQ 3 (hw1) is wired
+ * wired to UART1.
+ *
+ * We handle the IRQ according to _our_ priority which is:
+ *
+ * Highest ---- R4k Timer
+ * Lowest ---- Combined hardware interrupt
+ *
+ * then we just return, if multiple IRQs are pending then we will just take
+ * another exception, big deal.
+ */
+
+ .text
+ .set noreorder
+ .set noat
+ .align 5
+ NESTED(mipsIRQ, PT_SIZE, sp)
+ SAVE_ALL
+ CLI
+ .set at
+
+ mfc0 s0, CP0_CAUSE # get irq bits
+ mfc0 s1, CP0_STATUS # get irq mask
+ and s0, s1
+
+ /* First we check for r4k counter/timer IRQ. */
+ andi a0, s0, CAUSEF_IP7
+ beq a0, zero, 1f
+ andi a0, s0, CAUSEF_IP2 # delay slot, check hw0 interrupt
+
+ /* Wheee, a timer interrupt. */
+ move a0, sp
+ jal mips_timer_interrupt
+ nop
+
+ j ret_from_irq
+ nop
+
+1:
+#if defined(CONFIG_MIPS_SEAD)
+ beq a0, zero, 1f
+ andi a0, s0, CAUSEF_IP3 # delay slot, check hw1 interrupt
+#else
+ beq a0, zero, 1f # delay slot, check hw3 interrupt
+ andi a0, s0, CAUSEF_IP5
+#endif
+
+ /* Wheee, combined hardware level zero interrupt. */
+#if defined(CONFIG_MIPS_ATLAS)
+ jal atlas_hw0_irqdispatch
+#elif defined(CONFIG_MIPS_MALTA)
+ jal malta_hw0_irqdispatch
+#elif defined(CONFIG_MIPS_SEAD)
+ jal sead_hw0_irqdispatch
+#else
+#error "MIPS board not supported\n"
+#endif
+ move a0, sp # delay slot
+
+ j ret_from_irq
+ nop # delay slot
+
+1:
+#if defined(CONFIG_MIPS_SEAD)
+ beq a0, zero, 1f
+ andi a0, s0, CAUSEF_IP5 # delay slot, check hw3 interrupt
+ jal sead_hw1_irqdispatch
+ move a0, sp # delay slot
+ j ret_from_irq
+ nop # delay slot
+1:
+#endif
+#if defined(CONFIG_MIPS_MALTA)
+ beq a0, zero, 1f # check hw3 (coreHI) interrupt
+ nop
+ jal corehi_irqdispatch
+ move a0, sp
+ j ret_from_irq
+ nop
+1:
+#endif
+ /*
+ * Here by mistake? This is possible, what can happen is that by the
+ * time we take the exception the IRQ pin goes low, so just leave if
+ * this is the case.
+ */
+ move a1,s0
+ PRINT("Got interrupt: c0_cause = %08x\n")
+ mfc0 a1, CP0_EPC
+ PRINT("c0_epc = %08x\n")
+
+ j ret_from_irq
+ nop
+ END(mipsIRQ)
diff --git a/arch/mips/mips-boards/sim/sim_cmdline.c b/arch/mips/mips-boards/sim/sim_cmdline.c
new file mode 100644
index 000000000000..9df37c6fca36
--- /dev/null
+++ b/arch/mips/mips-boards/sim/sim_cmdline.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+#include <linux/init.h>
+#include <linux/string.h>
+#include <asm/bootinfo.h>
+
+extern char arcs_cmdline[];
+
+char * __init prom_getcmdline(void)
+{
+ return arcs_cmdline;
+}
+
+
+void __init prom_init_cmdline(void)
+{
+ /* nothing to do */
+}
diff --git a/arch/mips/mips-boards/sim/sim_int.c b/arch/mips/mips-boards/sim/sim_int.c
new file mode 100644
index 000000000000..a4d0a2c05031
--- /dev/null
+++ b/arch/mips/mips-boards/sim/sim_int.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 1999, 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <asm/mips-boards/simint.h>
+
+
+extern void mips_cpu_irq_init(int);
+
+extern asmlinkage void simIRQ(void);
+
+asmlinkage void sim_hw0_irqdispatch(struct pt_regs *regs)
+{
+ do_IRQ(2, regs);
+}
+
+void __init arch_init_irq(void)
+{
+ /* Now safe to set the exception vector. */
+ set_except_vector(0, simIRQ);
+
+ mips_cpu_irq_init(MIPSCPU_INT_BASE);
+}
diff --git a/arch/mips/mips-boards/sim/sim_irq.S b/arch/mips/mips-boards/sim/sim_irq.S
new file mode 100644
index 000000000000..835f0387fcd4
--- /dev/null
+++ b/arch/mips/mips-boards/sim/sim_irq.S
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 1999, 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Interrupt exception dispatch code.
+ *
+ */
+#include <linux/config.h>
+
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+#include <asm/mips-boards/simint.h>
+
+
+ .text
+ .set noreorder
+ .set noat
+ .align 5
+ NESTED(simIRQ, PT_SIZE, sp)
+ SAVE_ALL
+ CLI
+ .set at
+
+ mfc0 s0, CP0_CAUSE # get irq bits
+ mfc0 s1, CP0_STATUS # get irq mask
+ andi s0, ST0_IM # CAUSE.CE may be non-zero!
+ and s0, s1
+
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
+ .set mips32
+ clz a0, s0
+ .set mips0
+ negu a0
+ addu a0, 31-CAUSEB_IP
+ bltz a0, spurious
+#else
+ beqz s0, spurious
+ li a0, 7
+
+ and t0, s0, 0xf000
+ sltiu t0, t0, 1
+ sll t0, 2
+ subu a0, t0
+ sll s0, t0
+
+ and t0, s0, 0xc000
+ sltiu t0, t0, 1
+ sll t0, 1
+ subu a0, t0
+ sll s0, t0
+
+ and t0, s0, 0x8000
+ sltiu t0, t0, 1
+ # sll t0, 0
+ subu a0, t0
+ # sll s0, t0
+#endif
+
+#ifdef CASCADE_IRQ
+ li a1, CASCADE_IRQ
+ bne a0, a1, 1f
+ addu a0, MIPSCPU_INT_BASE
+
+ jal CASCADE_DISPATCH
+ move a0, sp
+
+ j ret_from_irq
+ nop
+1:
+#else
+ addu a0, MIPSCPU_INT_BASE
+#endif
+
+ jal do_IRQ
+ move a1, sp
+
+ j ret_from_irq
+ nop
+
+
+spurious:
+ j spurious_interrupt
+ nop
+ END(simIRQ)
diff --git a/arch/mips/mips-boards/sim/sim_mem.c b/arch/mips/mips-boards/sim/sim_mem.c
new file mode 100644
index 000000000000..0dbd7435bb2a
--- /dev/null
+++ b/arch/mips/mips-boards/sim/sim_mem.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+
+#include <asm/mips-boards/prom.h>
+
+/*#define DEBUG*/
+
+enum simmem_memtypes {
+ simmem_reserved = 0,
+ simmem_free,
+};
+struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
+
+#ifdef DEBUG
+static char *mtypes[3] = {
+ "SIM reserved memory",
+ "SIM free memory",
+};
+#endif
+
+/* References to section boundaries */
+extern char _end;
+
+#define PFN_ALIGN(x) (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
+
+
+struct prom_pmemblock * __init prom_getmdesc(void)
+{
+ unsigned int memsize;
+
+ memsize = 0x02000000;
+ prom_printf("Setting default memory size 0x%08x\n", memsize);
+
+ memset(mdesc, 0, sizeof(mdesc));
+
+ mdesc[0].type = simmem_reserved;
+ mdesc[0].base = 0x00000000;
+ mdesc[0].size = 0x00001000;
+
+ mdesc[1].type = simmem_free;
+ mdesc[1].base = 0x00001000;
+ mdesc[1].size = 0x000ff000;
+
+ mdesc[2].type = simmem_reserved;
+ mdesc[2].base = 0x00100000;
+ mdesc[2].size = CPHYSADDR(PFN_ALIGN(&_end)) - mdesc[2].base;
+
+ mdesc[3].type = simmem_free;
+ mdesc[3].base = CPHYSADDR(PFN_ALIGN(&_end));
+ mdesc[3].size = memsize - mdesc[3].base;
+
+ return &mdesc[0];
+}
+
+static int __init prom_memtype_classify (unsigned int type)
+{
+ switch (type) {
+ case simmem_free:
+ return BOOT_MEM_RAM;
+ case simmem_reserved:
+ default:
+ return BOOT_MEM_RESERVED;
+ }
+}
+
+void __init prom_meminit(void)
+{
+ struct prom_pmemblock *p;
+
+ p = prom_getmdesc();
+
+ while (p->size) {
+ long type;
+ unsigned long base, size;
+
+ type = prom_memtype_classify (p->type);
+ base = p->base;
+ size = p->size;
+
+ add_memory_region(base, size, type);
+ p++;
+ }
+}
+
+unsigned long __init prom_free_prom_memory(void)
+{
+ int i;
+ unsigned long freed = 0;
+ unsigned long addr;
+
+ for (i = 0; i < boot_mem_map.nr_map; i++) {
+ if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
+ continue;
+
+ addr = boot_mem_map.map[i].addr;
+ while (addr < boot_mem_map.map[i].addr
+ + boot_mem_map.map[i].size) {
+ ClearPageReserved(virt_to_page(__va(addr)));
+ set_page_count(virt_to_page(__va(addr)), 1);
+ free_page((unsigned long)__va(addr));
+ addr += PAGE_SIZE;
+ freed += PAGE_SIZE;
+ }
+ }
+ printk("Freeing prom memory: %ldkb freed\n", freed >> 10);
+
+ return freed;
+}
diff --git a/arch/mips/mips-boards/sim/sim_printf.c b/arch/mips/mips-boards/sim/sim_printf.c
new file mode 100644
index 000000000000..3ee5a0b501a6
--- /dev/null
+++ b/arch/mips/mips-boards/sim/sim_printf.c
@@ -0,0 +1,74 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Putting things on the screen/serial line using YAMONs facilities.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/serial_reg.h>
+#include <linux/spinlock.h>
+#include <asm/io.h>
+#include <asm/system.h>
+
+static inline unsigned int serial_in(int offset)
+{
+ return inb(0x3f8 + offset);
+}
+
+static inline void serial_out(int offset, int value)
+{
+ outb(value, 0x3f8 + offset);
+}
+
+int putPromChar(char c)
+{
+ while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0)
+ ;
+
+ serial_out(UART_TX, c);
+
+ return 1;
+}
+
+char getPromChar(void)
+{
+ while (!(serial_in(UART_LSR) & 1))
+ ;
+
+ return serial_in(UART_RX);
+}
+
+void prom_printf(char *fmt, ...)
+{
+ va_list args;
+ int l;
+ char *p, *buf_end;
+ char buf[1024];
+
+ va_start(args, fmt);
+ l = vsprintf(buf, fmt, args); /* hopefully i < sizeof(buf) */
+ va_end(args);
+
+ buf_end = buf + l;
+
+ for (p = buf; p < buf_end; p++) {
+ /* Crude cr/nl handling is better than none */
+ if (*p == '\n')
+ putPromChar('\r');
+ putPromChar(*p);
+ }
+}
diff --git a/arch/mips/mips-boards/sim/sim_setup.c b/arch/mips/mips-boards/sim/sim_setup.c
new file mode 100644
index 000000000000..485d5a58d9cf
--- /dev/null
+++ b/arch/mips/mips-boards/sim/sim_setup.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/prom.h>
+#include <asm/serial.h>
+#include <asm/io.h>
+#include <asm/time.h>
+#include <asm/mips-boards/sim.h>
+#include <asm/mips-boards/simint.h>
+
+
+extern void sim_time_init(void);
+extern void sim_timer_setup(struct irqaction *irq);
+static void __init serial_init(void);
+unsigned int _isbonito = 0;
+
+extern void __init sanitize_tlb_entries(void);
+
+
+const char *get_system_type(void)
+{
+ return "MIPSsim";
+}
+
+void __init plat_setup(void)
+{
+ set_io_port_base(0xbfd00000);
+
+ serial_init();
+
+ board_time_init = sim_time_init;
+ board_timer_setup = sim_timer_setup;
+ prom_printf("Linux started...\n");
+
+#ifdef CONFIG_MT_SMP
+ sanitize_tlb_entries();
+#endif
+}
+
+void prom_init(void)
+{
+ set_io_port_base(0xbfd00000);
+
+ prom_printf("\nLINUX started...\n");
+ prom_init_cmdline();
+ prom_meminit();
+}
+
+
+static void __init serial_init(void)
+{
+#ifdef CONFIG_SERIAL_8250
+ struct uart_port s;
+
+ memset(&s, 0, sizeof(s));
+
+ s.iobase = 0x3f8;
+
+ /* hardware int 4 - the serial int, is CPU int 6
+ but poll for now */
+ s.irq = 0;
+ s.uartclk = BASE_BAUD * 16;
+ s.flags = ASYNC_BOOT_AUTOCONF | UPF_SKIP_TEST;
+ s.iotype = SERIAL_IO_PORT | ASYNC_SKIP_TEST;
+ s.regshift = 0;
+ s.timeout = 4;
+
+ if (early_serial_setup(&s) != 0) {
+ prom_printf(KERN_ERR "Serial setup failed!\n");
+ }
+
+#endif
+}
diff --git a/arch/mips/mips-boards/sim/sim_smp.c b/arch/mips/mips-boards/sim/sim_smp.c
new file mode 100644
index 000000000000..19824359f5de
--- /dev/null
+++ b/arch/mips/mips-boards/sim/sim_smp.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+/*
+ * Simulator Platform-specific hooks for SMP operation
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/cpumask.h>
+#include <linux/interrupt.h>
+#include <asm/atomic.h>
+#include <asm/cpu.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/hardirq.h>
+#include <asm/mmu_context.h>
+#include <asm/smp.h>
+#ifdef CONFIG_MIPS_MT_SMTC
+#include <asm/smtc_ipi.h>
+#endif /* CONFIG_MIPS_MT_SMTC */
+
+/* VPE/SMP Prototype implements platform interfaces directly */
+#if !defined(CONFIG_MIPS_MT_SMP)
+
+/*
+ * Cause the specified action to be performed on a targeted "CPU"
+ */
+
+void core_send_ipi(int cpu, unsigned int action)
+{
+#ifdef CONFIG_MIPS_MT_SMTC
+ void smtc_send_ipi(int, int, unsigned int);
+
+ smtc_send_ipi(cpu, LINUX_SMP_IPI, action);
+#endif /* CONFIG_MIPS_MT_SMTC */
+/* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */
+
+}
+
+/*
+ * Detect available CPUs/VPEs/TCs and populate phys_cpu_present_map
+ */
+
+void __init prom_build_cpu_map(void)
+{
+#ifdef CONFIG_MIPS_MT_SMTC
+ extern int mipsmt_build_cpu_map(int startslot);
+ int nextslot;
+
+ cpus_clear(phys_cpu_present_map);
+
+ /* Register the boot CPU */
+
+ smp_prepare_boot_cpu();
+
+ /*
+ * As of November, 2004, MIPSsim only simulates one core
+ * at a time. However, that core may be a MIPS MT core
+ * with multiple virtual processors and thread contexts.
+ */
+
+ if (read_c0_config3() & (1<<2)) {
+ nextslot = mipsmt_build_cpu_map(1);
+ }
+#endif /* CONFIG_MIPS_MT_SMTC */
+}
+
+/*
+ * Platform "CPU" startup hook
+ */
+
+void prom_boot_secondary(int cpu, struct task_struct *idle)
+{
+#ifdef CONFIG_MIPS_MT_SMTC
+ extern void smtc_boot_secondary(int cpu, struct task_struct *t);
+
+ smtc_boot_secondary(cpu, idle);
+#endif /* CONFIG_MIPS_MT_SMTC */
+}
+
+/*
+ * Post-config but pre-boot cleanup entry point
+ */
+
+void prom_init_secondary(void)
+{
+#ifdef CONFIG_MIPS_MT_SMTC
+ void smtc_init_secondary(void);
+
+ smtc_init_secondary();
+#endif /* CONFIG_MIPS_MT_SMTC */
+}
+
+/*
+ * Platform SMP pre-initialization
+ */
+
+void prom_prepare_cpus(unsigned int max_cpus)
+{
+#ifdef CONFIG_MIPS_MT_SMTC
+ void mipsmt_prepare_cpus(int c);
+ /*
+ * As noted above, we can assume a single CPU for now
+ * but it may be multithreaded.
+ */
+
+ if (read_c0_config3() & (1<<2)) {
+ mipsmt_prepare_cpus(max_cpus);
+ }
+#endif /* CONFIG_MIPS_MT_SMTC */
+}
+
+/*
+ * SMP initialization finalization entry point
+ */
+
+void prom_smp_finish(void)
+{
+#ifdef CONFIG_MIPS_MT_SMTC
+ void smtc_smp_finish(void);
+
+ smtc_smp_finish();
+#endif /* CONFIG_MIPS_MT_SMTC */
+}
+
+/*
+ * Hook for after all CPUs are online
+ */
+
+void prom_cpus_done(void)
+{
+#ifdef CONFIG_MIPS_MT_SMTC
+
+#endif /* CONFIG_MIPS_MT_SMTC */
+}
+#endif /* CONFIG_MIPS32R2_MT_SMP */
diff --git a/arch/mips/mips-boards/sim/sim_time.c b/arch/mips/mips-boards/sim/sim_time.c
new file mode 100644
index 000000000000..18b968c696d1
--- /dev/null
+++ b/arch/mips/mips-boards/sim/sim_time.c
@@ -0,0 +1,215 @@
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+
+#include <asm/mipsregs.h>
+#include <asm/ptrace.h>
+#include <asm/hardirq.h>
+#include <asm/div64.h>
+#include <asm/cpu.h>
+#include <asm/time.h>
+
+#include <linux/interrupt.h>
+#include <linux/mc146818rtc.h>
+#include <linux/timex.h>
+#include <asm/mipsregs.h>
+#include <asm/ptrace.h>
+#include <asm/hardirq.h>
+#include <asm/irq.h>
+#include <asm/div64.h>
+#include <asm/cpu.h>
+#include <asm/time.h>
+#include <asm/mc146818-time.h>
+#include <asm/msc01_ic.h>
+
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/prom.h>
+#include <asm/mips-boards/simint.h>
+#include <asm/mc146818-time.h>
+#include <asm/smp.h>
+
+
+unsigned long cpu_khz;
+
+extern asmlinkage void ll_local_timer_interrupt(int irq, struct pt_regs *regs);
+
+irqreturn_t sim_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+#ifdef CONFIG_SMP
+ int cpu = smp_processor_id();
+
+ /*
+ * CPU 0 handles the global timer interrupt job
+ * resets count/compare registers to trigger next timer int.
+ */
+#ifndef CONFIG_MIPS_MT_SMTC
+ if (cpu == 0) {
+ timer_interrupt(irq, dev_id, regs);
+ }
+ else {
+ /* Everyone else needs to reset the timer int here as
+ ll_local_timer_interrupt doesn't */
+ /*
+ * FIXME: need to cope with counter underflow.
+ * More support needs to be added to kernel/time for
+ * counter/timer interrupts on multiple CPU's
+ */
+ write_c0_compare (read_c0_count() + ( mips_hpt_frequency/HZ));
+ }
+#else /* SMTC */
+ /*
+ * In SMTC system, one Count/Compare set exists per VPE.
+ * Which TC within a VPE gets the interrupt is essentially
+ * random - we only know that it shouldn't be one with
+ * IXMT set. Whichever TC gets the interrupt needs to
+ * send special interprocessor interrupts to the other
+ * TCs to make sure that they schedule, etc.
+ *
+ * That code is specific to the SMTC kernel, not to
+ * the simulation platform, so it's invoked from
+ * the general MIPS timer_interrupt routine.
+ *
+ * We have a problem in that the interrupt vector code
+ * had to turn off the timer IM bit to avoid redundant
+ * entries, but we may never get to mips_cpu_irq_end
+ * to turn it back on again if the scheduler gets
+ * involved. So we clear the pending timer here,
+ * and re-enable the mask...
+ */
+
+ int vpflags = dvpe();
+ write_c0_compare (read_c0_count() - 1);
+ clear_c0_cause(0x100 << MIPSCPU_INT_CPUCTR);
+ set_c0_status(0x100 << MIPSCPU_INT_CPUCTR);
+ irq_enable_hazard();
+ evpe(vpflags);
+
+ if(cpu_data[cpu].vpe_id == 0) timer_interrupt(irq, dev_id, regs);
+ else write_c0_compare (read_c0_count() + ( mips_hpt_frequency/HZ));
+ smtc_timer_broadcast(cpu_data[cpu].vpe_id);
+
+#endif /* CONFIG_MIPS_MT_SMTC */
+
+ /*
+ * every CPU should do profiling and process accounting
+ */
+ local_timer_interrupt (irq, dev_id, regs);
+ return IRQ_HANDLED;
+#else
+ return timer_interrupt (irq, dev_id, regs);
+#endif
+}
+
+
+
+/*
+ * Estimate CPU frequency. Sets mips_counter_frequency as a side-effect
+ */
+static unsigned int __init estimate_cpu_frequency(void)
+{
+ unsigned int prid = read_c0_prid() & 0xffff00;
+ unsigned int count;
+
+#if 1
+ /*
+ * hardwire the board frequency to 12MHz.
+ */
+
+ if ((prid == (PRID_COMP_MIPS | PRID_IMP_20KC)) ||
+ (prid == (PRID_COMP_MIPS | PRID_IMP_25KF)))
+ count = 12000000;
+ else
+ count = 6000000;
+#else
+ unsigned int flags;
+
+ local_irq_save(flags);
+
+ /* Start counter exactly on falling edge of update flag */
+ while (CMOS_READ(RTC_REG_A) & RTC_UIP);
+ while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
+
+ /* Start r4k counter. */
+ write_c0_count(0);
+
+ /* Read counter exactly on falling edge of update flag */
+ while (CMOS_READ(RTC_REG_A) & RTC_UIP);
+ while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
+
+ count = read_c0_count();
+
+ /* restore interrupts */
+ local_irq_restore(flags);
+#endif
+
+ mips_hpt_frequency = count;
+
+ if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) &&
+ (prid != (PRID_COMP_MIPS | PRID_IMP_25KF)))
+ count *= 2;
+
+ count += 5000; /* round */
+ count -= count%10000;
+
+ return count;
+}
+
+void __init sim_time_init(void)
+{
+ unsigned int est_freq, flags;
+
+ local_irq_save(flags);
+
+
+ /* Set Data mode - binary. */
+ CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
+
+
+ est_freq = estimate_cpu_frequency ();
+
+ printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
+ (est_freq%1000000)*100/1000000);
+
+ cpu_khz = est_freq / 1000;
+
+ local_irq_restore(flags);
+}
+
+static int mips_cpu_timer_irq;
+
+static void mips_timer_dispatch (struct pt_regs *regs)
+{
+ do_IRQ (mips_cpu_timer_irq, regs);
+}
+
+
+void __init sim_timer_setup(struct irqaction *irq)
+{
+ if (cpu_has_veic) {
+ set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch);
+ mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR;
+ }
+ else {
+ if (cpu_has_vint)
+ set_vi_handler(MIPSCPU_INT_CPUCTR, mips_timer_dispatch);
+ mips_cpu_timer_irq = MIPSCPU_INT_BASE + MIPSCPU_INT_CPUCTR;
+ }
+
+ /* we are using the cpu counter for timer interrupts */
+ irq->handler = sim_timer_interrupt;
+ setup_irq(mips_cpu_timer_irq, irq);
+
+#ifdef CONFIG_SMP
+ /* irq_desc(riptor) is a global resource, when the interrupt overlaps
+ on seperate cpu's the first one tries to handle the second interrupt.
+ The effect is that the int remains disabled on the second cpu.
+ Mark the interrupt with IRQ_PER_CPU to avoid any confusion */
+ irq_desc[mips_cpu_timer_irq].status |= IRQ_PER_CPU;
+#endif
+
+ /* to generate the first timer interrupt */
+ write_c0_compare(read_c0_count() + (mips_hpt_frequency/HZ));
+}
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile
index b56a0abdc3d4..b0178da019f0 100644
--- a/arch/mips/mm/Makefile
+++ b/arch/mips/mm/Makefile
@@ -22,7 +22,7 @@ obj-$(CONFIG_CPU_R8000) += c-r4k.o cex-gen.o pg-r4k.o tlb-r8k.o
obj-$(CONFIG_CPU_RM7000) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
obj-$(CONFIG_CPU_RM9000) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
obj-$(CONFIG_CPU_SB1) += c-sb1.o cerr-sb1.o cex-sb1.o pg-sb1.o \
- tlb-sb1.o
+ tlb-r4k.o
obj-$(CONFIG_CPU_TX39XX) += c-tx39.o pg-r4k.o tlb-r3k.o
obj-$(CONFIG_CPU_TX49XX) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
obj-$(CONFIG_CPU_VR41XX) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c
index c659f99eb39a..27f4fa25e8c9 100644
--- a/arch/mips/mm/c-r3k.c
+++ b/arch/mips/mm/c-r3k.c
@@ -221,12 +221,14 @@ static inline unsigned long get_phys_page (unsigned long addr,
struct mm_struct *mm)
{
pgd_t *pgd;
+ pud_t *pud;
pmd_t *pmd;
pte_t *pte;
unsigned long physpage;
pgd = pgd_offset(mm, addr);
- pmd = pmd_offset(pgd, addr);
+ pud = pud_offset(pgd, addr);
+ pmd = pmd_offset(pud, addr);
pte = pte_offset(pmd, addr);
if ((physpage = pte_val(*pte)) & _PAGE_VALID)
@@ -317,7 +319,7 @@ static void r3k_dma_cache_wback_inv(unsigned long start, unsigned long size)
r3k_flush_dcache_range(start, start + size);
}
-void __init ld_mmu_r23000(void)
+void __init r3k_cache_init(void)
{
extern void build_clear_page(void);
extern void build_copy_page(void);
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 5ea84bc98c6a..38223b44d962 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -16,6 +16,7 @@
#include <asm/bcache.h>
#include <asm/bootinfo.h>
+#include <asm/cache.h>
#include <asm/cacheops.h>
#include <asm/cpu.h>
#include <asm/cpu-features.h>
@@ -26,8 +27,14 @@
#include <asm/system.h>
#include <asm/mmu_context.h>
#include <asm/war.h>
+#include <asm/cacheflush.h> /* for run_uncached() */
-static unsigned long icache_size, dcache_size, scache_size;
+/*
+ * Must die.
+ */
+static unsigned long icache_size __read_mostly;
+static unsigned long dcache_size __read_mostly;
+static unsigned long scache_size __read_mostly;
/*
* Dummy cache handling routines for machines without boardcaches
@@ -43,8 +50,8 @@ static struct bcache_ops no_sc_ops = {
struct bcache_ops *bcops = &no_sc_ops;
-#define cpu_is_r4600_v1_x() ((read_c0_prid() & 0xfffffff0) == 0x2010)
-#define cpu_is_r4600_v2_x() ((read_c0_prid() & 0xfffffff0) == 0x2020)
+#define cpu_is_r4600_v1_x() ((read_c0_prid() & 0xfffffff0) == 0x00002010)
+#define cpu_is_r4600_v2_x() ((read_c0_prid() & 0xfffffff0) == 0x00002020)
#define R4600_HIT_CACHEOP_WAR_IMPL \
do { \
@@ -190,12 +197,12 @@ static inline void r4k_blast_icache_page_indexed_setup(void)
if (ic_lsize == 16)
r4k_blast_icache_page_indexed = blast_icache16_page_indexed;
else if (ic_lsize == 32) {
- if (TX49XX_ICACHE_INDEX_INV_WAR)
- r4k_blast_icache_page_indexed =
- tx49_blast_icache32_page_indexed;
- else if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x())
+ if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x())
r4k_blast_icache_page_indexed =
blast_icache32_r4600_v1_page_indexed;
+ else if (TX49XX_ICACHE_INDEX_INV_WAR)
+ r4k_blast_icache_page_indexed =
+ tx49_blast_icache32_page_indexed;
else
r4k_blast_icache_page_indexed =
blast_icache32_page_indexed;
@@ -361,24 +368,33 @@ static void r4k_flush_cache_mm(struct mm_struct *mm)
struct flush_cache_page_args {
struct vm_area_struct *vma;
- unsigned long page;
+ unsigned long addr;
};
static inline void local_r4k_flush_cache_page(void *args)
{
struct flush_cache_page_args *fcp_args = args;
struct vm_area_struct *vma = fcp_args->vma;
- unsigned long page = fcp_args->page;
+ unsigned long addr = fcp_args->addr;
int exec = vma->vm_flags & VM_EXEC;
struct mm_struct *mm = vma->vm_mm;
pgd_t *pgdp;
+ pud_t *pudp;
pmd_t *pmdp;
pte_t *ptep;
- page &= PAGE_MASK;
- pgdp = pgd_offset(mm, page);
- pmdp = pmd_offset(pgdp, page);
- ptep = pte_offset(pmdp, page);
+ /*
+ * If ownes no valid ASID yet, cannot possibly have gotten
+ * this page into the cache.
+ */
+ if (cpu_context(smp_processor_id(), mm) == 0)
+ return;
+
+ addr &= PAGE_MASK;
+ pgdp = pgd_offset(mm, addr);
+ pudp = pud_offset(pgdp, addr);
+ pmdp = pmd_offset(pudp, addr);
+ ptep = pte_offset(pmdp, addr);
/*
* If the page isn't marked valid, the page cannot possibly be
@@ -395,12 +411,12 @@ static inline void local_r4k_flush_cache_page(void *args)
*/
if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
- r4k_blast_dcache_page(page);
+ r4k_blast_dcache_page(addr);
if (exec && !cpu_icache_snoops_remote_store)
- r4k_blast_scache_page(page);
+ r4k_blast_scache_page(addr);
}
if (exec)
- r4k_blast_icache_page(page);
+ r4k_blast_icache_page(addr);
return;
}
@@ -409,36 +425,30 @@ static inline void local_r4k_flush_cache_page(void *args)
* Do indexed flush, too much work to get the (possible) TLB refills
* to work correctly.
*/
- page = INDEX_BASE + (page & (dcache_size - 1));
+ addr = INDEX_BASE + (addr & (dcache_size - 1));
if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
- r4k_blast_dcache_page_indexed(page);
+ r4k_blast_dcache_page_indexed(addr);
if (exec && !cpu_icache_snoops_remote_store)
- r4k_blast_scache_page_indexed(page);
+ r4k_blast_scache_page_indexed(addr);
}
if (exec) {
if (cpu_has_vtag_icache) {
int cpu = smp_processor_id();
- if (cpu_context(cpu, vma->vm_mm) != 0)
- drop_mmu_context(vma->vm_mm, cpu);
+ if (cpu_context(cpu, mm) != 0)
+ drop_mmu_context(mm, cpu);
} else
- r4k_blast_icache_page_indexed(page);
+ r4k_blast_icache_page_indexed(addr);
}
}
-static void r4k_flush_cache_page(struct vm_area_struct *vma, unsigned long page, unsigned long pfn)
+static void r4k_flush_cache_page(struct vm_area_struct *vma,
+ unsigned long addr, unsigned long pfn)
{
struct flush_cache_page_args args;
- /*
- * If ownes no valid ASID yet, cannot possibly have gotten
- * this page into the cache.
- */
- if (cpu_context(smp_processor_id(), vma->vm_mm) == 0)
- return;
-
args.vma = vma;
- args.page = page;
+ args.addr = addr;
on_each_cpu(local_r4k_flush_cache_page, &args, 1, 1);
}
@@ -454,16 +464,16 @@ static void r4k_flush_data_cache_page(unsigned long addr)
}
struct flush_icache_range_args {
- unsigned long start;
- unsigned long end;
+ unsigned long __user start;
+ unsigned long __user end;
};
static inline void local_r4k_flush_icache_range(void *args)
{
struct flush_icache_range_args *fir_args = args;
- unsigned long dc_lsize = current_cpu_data.dcache.linesz;
- unsigned long ic_lsize = current_cpu_data.icache.linesz;
- unsigned long sc_lsize = current_cpu_data.scache.linesz;
+ unsigned long dc_lsize = cpu_dcache_line_size();
+ unsigned long ic_lsize = cpu_icache_line_size();
+ unsigned long sc_lsize = cpu_scache_line_size();
unsigned long start = fir_args->start;
unsigned long end = fir_args->end;
unsigned long addr, aend;
@@ -472,6 +482,7 @@ static inline void local_r4k_flush_icache_range(void *args)
if (end - start > dcache_size) {
r4k_blast_dcache();
} else {
+ R4600_HIT_CACHEOP_WAR_IMPL;
addr = start & ~(dc_lsize - 1);
aend = (end - 1) & ~(dc_lsize - 1);
@@ -492,7 +503,7 @@ static inline void local_r4k_flush_icache_range(void *args)
aend = (end - 1) & ~(sc_lsize - 1);
while (1) {
- /* Hit_Writeback_Inv_D */
+ /* Hit_Writeback_Inv_SD */
protected_writeback_scache_line(addr);
if (addr == aend)
break;
@@ -517,7 +528,8 @@ static inline void local_r4k_flush_icache_range(void *args)
}
}
-static void r4k_flush_icache_range(unsigned long start, unsigned long end)
+static void r4k_flush_icache_range(unsigned long __user start,
+ unsigned long __user end)
{
struct flush_icache_range_args args;
@@ -525,6 +537,7 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end)
args.end = end;
on_each_cpu(local_r4k_flush_icache_range, &args, 1, 1);
+ instruction_hazard();
}
/*
@@ -613,7 +626,7 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
BUG_ON(size == 0);
if (cpu_has_subset_pcaches) {
- unsigned long sc_lsize = current_cpu_data.scache.linesz;
+ unsigned long sc_lsize = cpu_scache_line_size();
if (size >= scache_size) {
r4k_blast_scache();
@@ -639,7 +652,7 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
if (size >= dcache_size) {
r4k_blast_dcache();
} else {
- unsigned long dc_lsize = current_cpu_data.dcache.linesz;
+ unsigned long dc_lsize = cpu_dcache_line_size();
R4600_HIT_CACHEOP_WAR_IMPL;
a = addr & ~(dc_lsize - 1);
@@ -663,7 +676,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
BUG_ON(size == 0);
if (cpu_has_subset_pcaches) {
- unsigned long sc_lsize = current_cpu_data.scache.linesz;
+ unsigned long sc_lsize = cpu_scache_line_size();
if (size >= scache_size) {
r4k_blast_scache();
@@ -684,7 +697,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
if (size >= dcache_size) {
r4k_blast_dcache();
} else {
- unsigned long dc_lsize = current_cpu_data.dcache.linesz;
+ unsigned long dc_lsize = cpu_dcache_line_size();
R4600_HIT_CACHEOP_WAR_IMPL;
a = addr & ~(dc_lsize - 1);
@@ -708,9 +721,9 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
*/
static void local_r4k_flush_cache_sigtramp(void * arg)
{
- unsigned long ic_lsize = current_cpu_data.icache.linesz;
- unsigned long dc_lsize = current_cpu_data.dcache.linesz;
- unsigned long sc_lsize = current_cpu_data.scache.linesz;
+ unsigned long ic_lsize = cpu_icache_line_size();
+ unsigned long dc_lsize = cpu_dcache_line_size();
+ unsigned long sc_lsize = cpu_scache_line_size();
unsigned long addr = (unsigned long) arg;
R4600_HIT_CACHEOP_WAR_IMPL;
@@ -762,6 +775,7 @@ static inline void rm7k_erratum31(void)
for (addr = INDEX_BASE; addr <= INDEX_BASE + 4096; addr += ic_lsize) {
__asm__ __volatile__ (
+ ".set push\n\t"
".set noreorder\n\t"
".set mips3\n\t"
"cache\t%1, 0(%0)\n\t"
@@ -776,8 +790,7 @@ static inline void rm7k_erratum31(void)
"cache\t%1, 0x1000(%0)\n\t"
"cache\t%1, 0x2000(%0)\n\t"
"cache\t%1, 0x3000(%0)\n\t"
- ".set\tmips0\n\t"
- ".set\treorder\n\t"
+ ".set pop\n"
:
: "r" (addr), "i" (Index_Store_Tag_I), "i" (Fill));
}
@@ -1011,9 +1024,19 @@ static void __init probe_pcache(void)
* normally they'd suffer from aliases but magic in the hardware deals
* with that for us so we don't need to take care ourselves.
*/
- if (c->cputype != CPU_R10000 && c->cputype != CPU_R12000)
- if (c->dcache.waysize > PAGE_SIZE)
- c->dcache.flags |= MIPS_CACHE_ALIASES;
+ switch (c->cputype) {
+ case CPU_20KC:
+ case CPU_25KF:
+ case CPU_R10000:
+ case CPU_R12000:
+ case CPU_SB1:
+ break;
+ case CPU_24K:
+ if (!(read_c0_config7() & (1 << 16)))
+ default:
+ if (c->dcache.waysize > PAGE_SIZE)
+ c->dcache.flags |= MIPS_CACHE_ALIASES;
+ }
switch (c->cputype) {
case CPU_20KC:
@@ -1024,7 +1047,11 @@ static void __init probe_pcache(void)
c->icache.flags |= MIPS_CACHE_VTAG;
break;
+ case CPU_AU1000:
case CPU_AU1500:
+ case CPU_AU1100:
+ case CPU_AU1550:
+ case CPU_AU1200:
c->icache.flags |= MIPS_CACHE_IC_F_DC;
break;
}
@@ -1102,7 +1129,6 @@ static int __init probe_scache(void)
return 1;
}
-typedef int (*probe_func_t)(unsigned long);
extern int r5k_sc_init(void);
extern int rm7k_sc_init(void);
@@ -1110,7 +1136,6 @@ static void __init setup_scache(void)
{
struct cpuinfo_mips *c = &current_cpu_data;
unsigned int config = read_c0_config();
- probe_func_t probe_scache_kseg1;
int sc_present = 0;
/*
@@ -1123,8 +1148,7 @@ static void __init setup_scache(void)
case CPU_R4000MC:
case CPU_R4400SC:
case CPU_R4400MC:
- probe_scache_kseg1 = (probe_func_t) (CKSEG1ADDR(&probe_scache));
- sc_present = probe_scache_kseg1(config);
+ sc_present = run_uncached(probe_scache);
if (sc_present)
c->options |= MIPS_CPU_CACHE_CDEX_S;
break;
@@ -1198,7 +1222,7 @@ static inline void coherency_setup(void)
}
}
-void __init ld_mmu_r4xx0(void)
+void __init r4k_cache_init(void)
{
extern void build_clear_page(void);
extern void build_copy_page(void);
@@ -1206,15 +1230,11 @@ void __init ld_mmu_r4xx0(void)
struct cpuinfo_mips *c = &current_cpu_data;
/* Default cache error handler for R4000 and R5000 family */
- memcpy((void *)(CAC_BASE + 0x100), &except_vec2_generic, 0x80);
- memcpy((void *)(UNCAC_BASE + 0x100), &except_vec2_generic, 0x80);
+ set_uncached_handler (0x100, &except_vec2_generic, 0x80);
probe_pcache();
setup_scache();
- if (c->dcache.sets * c->dcache.ways > PAGE_SIZE)
- c->dcache.flags |= MIPS_CACHE_ALIASES;
-
r4k_blast_dcache_page_setup();
r4k_blast_dcache_page_indexed_setup();
r4k_blast_dcache_setup();
@@ -1252,9 +1272,8 @@ void __init ld_mmu_r4xx0(void)
_dma_cache_inv = r4k_dma_cache_inv;
#endif
- __flush_cache_all();
- coherency_setup();
-
build_clear_page();
build_copy_page();
+ local_r4k___flush_cache_all(NULL);
+ coherency_setup();
}
diff --git a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c
index 502f68c664b2..2f08b535f20e 100644
--- a/arch/mips/mm/c-sb1.c
+++ b/arch/mips/mm/c-sb1.c
@@ -235,7 +235,7 @@ static inline void __sb1_flush_icache_range(unsigned long start,
/*
* Invalidate all caches on this CPU
*/
-static void local_sb1___flush_cache_all(void)
+static void __attribute_used__ local_sb1___flush_cache_all(void)
{
__sb1_writeback_inv_dcache_all();
__sb1_flush_icache_all();
@@ -492,19 +492,17 @@ static __init void probe_cache_sizes(void)
}
/*
- * This is called from loadmmu.c. We have to set up all the
+ * This is called from cache.c. We have to set up all the
* memory management function pointers, as well as initialize
* the caches and tlbs
*/
-void ld_mmu_sb1(void)
+void sb1_cache_init(void)
{
extern char except_vec2_sb1;
extern char handle_vec2_sb1;
/* Special cache error handler for SB1 */
- memcpy((void *)(CAC_BASE + 0x100), &except_vec2_sb1, 0x80);
- memcpy((void *)(UNCAC_BASE + 0x100), &except_vec2_sb1, 0x80);
- memcpy((void *)CKSEG1ADDR(&handle_vec2_sb1), &handle_vec2_sb1, 0x80);
+ set_uncached_handler (0x100, &except_vec2_sb1, 0x80);
probe_cache_sizes();
diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c
index ff5afab64b2f..0a97a9434eba 100644
--- a/arch/mips/mm/c-tx39.c
+++ b/arch/mips/mm/c-tx39.c
@@ -167,15 +167,16 @@ static void tx39_flush_cache_mm(struct mm_struct *mm)
static void tx39_flush_cache_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
{
- struct mm_struct *mm = vma->vm_mm;
+ int exec;
- if (!cpu_has_dc_aliases)
+ if (!(cpu_context(smp_processor_id(), vma->vm_mm)))
return;
- if (cpu_context(smp_processor_id(), mm) != 0) {
+ exec = vma->vm_flags & VM_EXEC;
+ if (cpu_has_dc_aliases || exec)
tx39_blast_dcache();
+ if (exec)
tx39_blast_icache();
- }
}
static void tx39_flush_cache_page(struct vm_area_struct *vma, unsigned long page, unsigned long pfn)
@@ -183,6 +184,7 @@ static void tx39_flush_cache_page(struct vm_area_struct *vma, unsigned long page
int exec = vma->vm_flags & VM_EXEC;
struct mm_struct *mm = vma->vm_mm;
pgd_t *pgdp;
+ pud_t *pudp;
pmd_t *pmdp;
pte_t *ptep;
@@ -195,7 +197,8 @@ static void tx39_flush_cache_page(struct vm_area_struct *vma, unsigned long page
page &= PAGE_MASK;
pgdp = pgd_offset(mm, page);
- pmdp = pmd_offset(pgdp, page);
+ pudp = pud_offset(pgdp, page);
+ pmdp = pmd_offset(pudp, page);
ptep = pte_offset(pmdp, page);
/*
@@ -407,7 +410,7 @@ static __init void tx39_probe_cache(void)
}
}
-void __init ld_mmu_tx39(void)
+void __init tx39_cache_init(void)
{
extern void build_clear_page(void);
extern void build_copy_page(void);
@@ -490,4 +493,5 @@ void __init ld_mmu_tx39(void)
build_clear_page();
build_copy_page();
+ tx39h_flush_icache_all();
}
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index 1d95cdb77bed..314701a66b13 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -23,8 +23,10 @@ void (*__flush_cache_all)(void);
void (*flush_cache_mm)(struct mm_struct *mm);
void (*flush_cache_range)(struct vm_area_struct *vma, unsigned long start,
unsigned long end);
-void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn);
-void (*flush_icache_range)(unsigned long start, unsigned long end);
+void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page,
+ unsigned long pfn);
+void (*flush_icache_range)(unsigned long __user start,
+ unsigned long __user end);
void (*flush_icache_page)(struct vm_area_struct *vma, struct page *page);
/* MIPS specific cache operations */
@@ -32,6 +34,8 @@ void (*flush_cache_sigtramp)(unsigned long addr);
void (*flush_data_cache_page)(unsigned long addr);
void (*flush_icache_all)(void);
+EXPORT_SYMBOL(flush_data_cache_page);
+
#ifdef CONFIG_DMA_NONCOHERENT
/* DMA cache operations. */
@@ -49,10 +53,12 @@ EXPORT_SYMBOL(_dma_cache_inv);
* We could optimize the case where the cache argument is not BCACHE but
* that seems very atypical use ...
*/
-asmlinkage int sys_cacheflush(unsigned long addr, unsigned long int bytes,
- unsigned int cache)
+asmlinkage int sys_cacheflush(unsigned long __user addr,
+ unsigned long bytes, unsigned int cache)
{
- if (!access_ok(VERIFY_WRITE, (void *) addr, bytes))
+ if (bytes == 0)
+ return 0;
+ if (!access_ok(VERIFY_WRITE, (void __user *) addr, bytes))
return -EFAULT;
flush_icache_range(addr, addr + bytes);
@@ -100,58 +106,48 @@ void __update_cache(struct vm_area_struct *vma, unsigned long address,
}
}
-extern void ld_mmu_r23000(void);
-extern void ld_mmu_r4xx0(void);
-extern void ld_mmu_tx39(void);
-extern void ld_mmu_r6000(void);
-extern void ld_mmu_tfp(void);
-extern void ld_mmu_andes(void);
-extern void ld_mmu_sb1(void);
+#define __weak __attribute__((weak))
+
+static char cache_panic[] __initdata = "Yeee, unsupported cache architecture.";
void __init cpu_cache_init(void)
{
- if (cpu_has_4ktlb) {
-#if defined(CONFIG_CPU_R4X00) || defined(CONFIG_CPU_VR41XX) || \
- defined(CONFIG_CPU_R4300) || defined(CONFIG_CPU_R5000) || \
- defined(CONFIG_CPU_NEVADA) || defined(CONFIG_CPU_R5432) || \
- defined(CONFIG_CPU_R5500) || defined(CONFIG_CPU_MIPS32) || \
- defined(CONFIG_CPU_MIPS64) || defined(CONFIG_CPU_TX49XX) || \
- defined(CONFIG_CPU_RM7000) || defined(CONFIG_CPU_RM9000)
- ld_mmu_r4xx0();
-#endif
- } else switch (current_cpu_data.cputype) {
-#ifdef CONFIG_CPU_R3000
- case CPU_R2000:
- case CPU_R3000:
- case CPU_R3000A:
- case CPU_R3081E:
- ld_mmu_r23000();
- break;
-#endif
-#ifdef CONFIG_CPU_TX39XX
- case CPU_TX3912:
- case CPU_TX3922:
- case CPU_TX3927:
- ld_mmu_tx39();
- break;
-#endif
-#ifdef CONFIG_CPU_R10000
- case CPU_R10000:
- case CPU_R12000:
- ld_mmu_r4xx0();
- break;
-#endif
-#ifdef CONFIG_CPU_SB1
- case CPU_SB1:
- ld_mmu_sb1();
- break;
-#endif
-
- case CPU_R8000:
- panic("R8000 is unsupported");
- break;
-
- default:
- panic("Yeee, unsupported cache architecture.");
+ if (cpu_has_3k_cache) {
+ extern void __weak r3k_cache_init(void);
+
+ r3k_cache_init();
+ return;
+ }
+ if (cpu_has_6k_cache) {
+ extern void __weak r6k_cache_init(void);
+
+ r6k_cache_init();
+ return;
+ }
+ if (cpu_has_4k_cache) {
+ extern void __weak r4k_cache_init(void);
+
+ r4k_cache_init();
+ return;
}
+ if (cpu_has_8k_cache) {
+ extern void __weak r8k_cache_init(void);
+
+ r8k_cache_init();
+ return;
+ }
+ if (cpu_has_tx39_cache) {
+ extern void __weak tx39_cache_init(void);
+
+ tx39_cache_init();
+ return;
+ }
+ if (cpu_has_sb1_cache) {
+ extern void __weak sb1_cache_init(void);
+
+ sb1_cache_init();
+ return;
+ }
+
+ panic(cache_panic);
}
diff --git a/arch/mips/mm/cerr-sb1.c b/arch/mips/mm/cerr-sb1.c
index 7166ffe63502..1cf3c6006ccd 100644
--- a/arch/mips/mm/cerr-sb1.c
+++ b/arch/mips/mm/cerr-sb1.c
@@ -19,13 +19,19 @@
#include <linux/sched.h>
#include <asm/mipsregs.h>
#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
-#ifndef CONFIG_SIBYTE_BUS_WATCHER
+#if !defined(CONFIG_SIBYTE_BUS_WATCHER) || defined(CONFIG_SIBYTE_BW_TRACE)
#include <asm/io.h>
-#include <asm/sibyte/sb1250_regs.h>
#include <asm/sibyte/sb1250_scd.h>
#endif
+/*
+ * We'd like to dump the L2_ECC_TAG register on errors, but errata make
+ * that unsafe... So for now we don't. (BCM1250/BCM112x erratum SOC-48.)
+ */
+#undef DUMP_L2_ECC_TAG_ON_ERROR
+
/* SB1 definitions */
/* XXX should come from config1 XXX */
@@ -139,12 +145,18 @@ static inline void breakout_cerrd(unsigned int val)
static void check_bus_watcher(void)
{
uint32_t status, l2_err, memio_err;
+#ifdef DUMP_L2_ECC_TAG_ON_ERROR
+ uint64_t l2_tag;
+#endif
/* Destructive read, clears register and interrupt */
status = csr_in32(IOADDR(A_SCD_BUS_ERR_STATUS));
/* Bit 31 is always on, but there's no #define for that */
if (status & ~(1UL << 31)) {
l2_err = csr_in32(IOADDR(A_BUS_L2_ERRORS));
+#ifdef DUMP_L2_ECC_TAG_ON_ERROR
+ l2_tag = in64(IO_SPACE_BASE | A_L2_ECC_TAG);
+#endif
memio_err = csr_in32(IOADDR(A_BUS_MEM_IO_ERRORS));
prom_printf("Bus watcher error counters: %08x %08x\n", l2_err, memio_err);
prom_printf("\nLast recorded signature:\n");
@@ -153,6 +165,9 @@ static void check_bus_watcher(void)
(int)(G_SCD_BERR_TID(status) >> 6),
(int)G_SCD_BERR_RID(status),
(int)G_SCD_BERR_DCODE(status));
+#ifdef DUMP_L2_ECC_TAG_ON_ERROR
+ prom_printf("Last L2 tag w/ bad ECC: %016llx\n", l2_tag);
+#endif
} else {
prom_printf("Bus watcher indicates no error\n");
}
@@ -166,6 +181,16 @@ asmlinkage void sb1_cache_error(void)
uint64_t cerr_dpa;
uint32_t errctl, cerr_i, cerr_d, dpalo, dpahi, eepc, res;
+#ifdef CONFIG_SIBYTE_BW_TRACE
+ /* Freeze the trace buffer now */
+#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
+ csr_out32(M_BCM1480_SCD_TRACE_CFG_FREEZE, IO_SPACE_BASE | A_SCD_TRACE_CFG);
+#else
+ csr_out32(M_SCD_TRACE_CFG_FREEZE, IO_SPACE_BASE | A_SCD_TRACE_CFG);
+#endif
+ prom_printf("Trace buffer frozen\n");
+#endif
+
prom_printf("Cache error exception on CPU %x:\n",
(read_c0_prid() >> 25) & 0x7);
@@ -229,11 +254,19 @@ asmlinkage void sb1_cache_error(void)
check_bus_watcher();
- while (1);
/*
- * This tends to make things get really ugly; let's just stall instead.
- * panic("Can't handle the cache error!");
+ * Calling panic() when a fatal cache error occurs scrambles the
+ * state of the system (and the cache), making it difficult to
+ * investigate after the fact. However, if you just stall the CPU,
+ * the other CPU may keep on running, which is typically very
+ * undesirable.
*/
+#ifdef CONFIG_SB1_CERR_STALL
+ while (1)
+ ;
+#else
+ panic("unhandled cache error");
+#endif
}
@@ -434,7 +467,8 @@ static struct dc_state dc_states[] = {
};
#define DC_TAG_VALID(state) \
- (((state) == 0xf) || ((state) == 0x13) || ((state) == 0x19) || ((state == 0x16)) || ((state) == 0x1c))
+ (((state) == 0x0) || ((state) == 0xf) || ((state) == 0x13) || \
+ ((state) == 0x19) || ((state) == 0x16) || ((state) == 0x1c))
static char *dc_state_str(unsigned char state)
{
@@ -505,6 +539,7 @@ static uint32_t extract_dc(unsigned short addr, int data)
uint64_t datalo;
uint32_t datalohi, datalolo, datahi;
int offset;
+ char bad_ecc = 0;
for (offset = 0; offset < 4; offset++) {
/* Index-load-data-D */
@@ -525,8 +560,7 @@ static uint32_t extract_dc(unsigned short addr, int data)
ecc = dc_ecc(datalo);
if (ecc != datahi) {
int bits = 0;
- prom_printf(" ** bad ECC (%02x %02x) ->",
- datahi, ecc);
+ bad_ecc |= 1 << (3-offset);
ecc ^= datahi;
while (ecc) {
if (ecc & 1) bits++;
@@ -537,6 +571,10 @@ static uint32_t extract_dc(unsigned short addr, int data)
prom_printf(" %02X-%016llX", datahi, datalo);
}
prom_printf("\n");
+ if (bad_ecc)
+ prom_printf(" dwords w/ bad ECC: %d %d %d %d\n",
+ !!(bad_ecc & 8), !!(bad_ecc & 4),
+ !!(bad_ecc & 2), !!(bad_ecc & 1));
}
}
return res;
diff --git a/arch/mips/mm/cex-sb1.S b/arch/mips/mm/cex-sb1.S
index 2c3a23aa88c3..0e71580774ff 100644
--- a/arch/mips/mm/cex-sb1.S
+++ b/arch/mips/mm/cex-sb1.S
@@ -64,6 +64,10 @@ LEAF(except_vec2_sb1)
sd k0,0x170($0)
sd k1,0x178($0)
+#if CONFIG_SB1_CEX_ALWAYS_FATAL
+ j handle_vec2_sb1
+ nop
+#else
/*
* M_ERRCTL_RECOVERABLE is bit 31, which makes it easy to tell
* if we can fast-path out of here for a h/w-recovered error.
@@ -134,6 +138,7 @@ unrecoverable:
/* Unrecoverable Icache or Dcache error; log it and/or fail */
j handle_vec2_sb1
nop
+#endif
END(except_vec2_sb1)
diff --git a/arch/mips/mm/dma-coherent.c b/arch/mips/mm/dma-coherent.c
index a617f8c327e8..f6b3c722230c 100644
--- a/arch/mips/mm/dma-coherent.c
+++ b/arch/mips/mm/dma-coherent.c
@@ -9,10 +9,10 @@
*/
#include <linux/config.h>
#include <linux/types.h>
+#include <linux/dma-mapping.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/string.h>
-#include <linux/pci.h>
#include <asm/cache.h>
#include <asm/io.h>
diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
index 4ce02028a292..cd4ea8474f89 100644
--- a/arch/mips/mm/dma-noncoherent.c
+++ b/arch/mips/mm/dma-noncoherent.c
@@ -105,22 +105,7 @@ dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
{
unsigned long addr = (unsigned long) ptr;
- switch (direction) {
- case DMA_TO_DEVICE:
- dma_cache_wback(addr, size);
- break;
-
- case DMA_FROM_DEVICE:
- dma_cache_inv(addr, size);
- break;
-
- case DMA_BIDIRECTIONAL:
- dma_cache_wback_inv(addr, size);
- break;
-
- default:
- BUG();
- }
+ __dma_sync(addr, size, direction);
return virt_to_phys(ptr);
}
@@ -133,22 +118,7 @@ void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
unsigned long addr;
addr = dma_addr + PAGE_OFFSET;
- switch (direction) {
- case DMA_TO_DEVICE:
- //dma_cache_wback(addr, size);
- break;
-
- case DMA_FROM_DEVICE:
- //dma_cache_inv(addr, size);
- break;
-
- case DMA_BIDIRECTIONAL:
- //dma_cache_wback_inv(addr, size);
- break;
-
- default:
- BUG();
- }
+ //__dma_sync(addr, size, direction);
}
EXPORT_SYMBOL(dma_unmap_single);
@@ -164,10 +134,11 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
unsigned long addr;
addr = (unsigned long) page_address(sg->page);
- if (addr)
+ if (addr) {
__dma_sync(addr + sg->offset, sg->length, direction);
- sg->dma_address = (dma_addr_t)
- (page_to_phys(sg->page) + sg->offset);
+ sg->dma_address = (dma_addr_t)page_to_phys(sg->page)
+ + sg->offset;
+ }
}
return nents;
@@ -218,9 +189,8 @@ void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
for (i = 0; i < nhwentries; i++, sg++) {
addr = (unsigned long) page_address(sg->page);
- if (!addr)
- continue;
- dma_cache_wback_inv(addr + sg->offset, sg->length);
+ if (addr)
+ __dma_sync(addr + sg->offset, sg->length, direction);
}
}
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index ec8077c74e9c..2d9624fd10ec 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -25,6 +25,7 @@
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/ptrace.h>
+#include <asm/highmem.h> /* For VMALLOC_END */
/*
* This routine handles page faults. It determines the address,
@@ -57,7 +58,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
* only copy the information from the master page table,
* nothing more.
*/
- if (unlikely(address >= VMALLOC_START))
+ if (unlikely(address >= VMALLOC_START && address <= VMALLOC_END))
goto vmalloc_fault;
/*
@@ -140,7 +141,7 @@ bad_area_nosemaphore:
info.si_signo = SIGSEGV;
info.si_errno = 0;
/* info.si_code has been set above */
- info.si_addr = (void *) address;
+ info.si_addr = (void __user *) address;
force_sig_info(SIGSEGV, &info, tsk);
return;
}
@@ -196,7 +197,7 @@ do_sigbus:
info.si_signo = SIGBUS;
info.si_errno = 0;
info.si_code = BUS_ADRERR;
- info.si_addr = (void *) address;
+ info.si_addr = (void __user *) address;
force_sig_info(SIGBUS, &info, tsk);
return;
@@ -212,6 +213,7 @@ vmalloc_fault:
*/
int offset = __pgd_offset(address);
pgd_t *pgd, *pgd_k;
+ pud_t *pud, *pud_k;
pmd_t *pmd, *pmd_k;
pte_t *pte_k;
@@ -222,8 +224,13 @@ vmalloc_fault:
goto no_context;
set_pgd(pgd, *pgd_k);
- pmd = pmd_offset(pgd, address);
- pmd_k = pmd_offset(pgd_k, address);
+ pud = pud_offset(pgd, address);
+ pud_k = pud_offset(pgd_k, address);
+ if (!pud_present(*pud_k))
+ goto no_context;
+
+ pmd = pmd_offset(pud, address);
+ pmd_k = pmd_offset(pud_k, address);
if (!pmd_present(*pmd_k))
goto no_context;
set_pmd(pmd, *pmd_k);
diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c
index dd5e2e31885b..1f7b37b38f5c 100644
--- a/arch/mips/mm/highmem.c
+++ b/arch/mips/mm/highmem.c
@@ -83,6 +83,25 @@ void __kunmap_atomic(void *kvaddr, enum km_type type)
preempt_check_resched();
}
+/*
+ * This is the same as kmap_atomic() but can map memory that doesn't
+ * have a struct page associated with it.
+ */
+void *kmap_atomic_pfn(unsigned long pfn, enum km_type type)
+{
+ enum fixed_addresses idx;
+ unsigned long vaddr;
+
+ inc_preempt_count();
+
+ idx = type + KM_TYPE_NR*smp_processor_id();
+ vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+ set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
+ flush_tlb_one(vaddr);
+
+ return (void*) vaddr;
+}
+
struct page *__kmap_atomic_to_page(void *ptr)
{
unsigned long idx, vaddr = (unsigned long)ptr;
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index dc6830b10fab..f75ab748e8cd 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -83,7 +83,7 @@ pte_t *kmap_pte;
pgprot_t kmap_prot;
#define kmap_get_fixmap_pte(vaddr) \
- pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
+ pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr))
static void __init kmap_init(void)
{
@@ -96,36 +96,42 @@ static void __init kmap_init(void)
kmap_prot = PAGE_KERNEL;
}
-#ifdef CONFIG_64BIT
-static void __init fixrange_init(unsigned long start, unsigned long end,
+#ifdef CONFIG_32BIT
+void __init fixrange_init(unsigned long start, unsigned long end,
pgd_t *pgd_base)
{
pgd_t *pgd;
+ pud_t *pud;
pmd_t *pmd;
pte_t *pte;
- int i, j;
+ int i, j, k;
unsigned long vaddr;
vaddr = start;
i = __pgd_offset(vaddr);
- j = __pmd_offset(vaddr);
+ j = __pud_offset(vaddr);
+ k = __pmd_offset(vaddr);
pgd = pgd_base + i;
for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
- pmd = (pmd_t *)pgd;
- for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
- if (pmd_none(*pmd)) {
- pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
- set_pmd(pmd, __pmd(pte));
- if (pte != pte_offset_kernel(pmd, 0))
- BUG();
+ pud = (pud_t *)pgd;
+ for ( ; (j < PTRS_PER_PUD) && (vaddr != end); pud++, j++) {
+ pmd = (pmd_t *)pud;
+ for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) {
+ if (pmd_none(*pmd)) {
+ pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+ set_pmd(pmd, __pmd(pte));
+ if (pte != pte_offset_kernel(pmd, 0))
+ BUG();
+ }
+ vaddr += PMD_SIZE;
}
- vaddr += PMD_SIZE;
+ k = 0;
}
j = 0;
}
}
-#endif /* CONFIG_64BIT */
+#endif /* CONFIG_32BIT */
#endif /* CONFIG_HIGHMEM */
#ifndef CONFIG_NEED_MULTIPLE_NODES
diff --git a/arch/mips/mm/ioremap.c b/arch/mips/mm/ioremap.c
index adf352273f63..3101d1db5592 100644
--- a/arch/mips/mm/ioremap.c
+++ b/arch/mips/mm/ioremap.c
@@ -55,7 +55,7 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address,
if (address >= end)
BUG();
do {
- pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
+ pte_t * pte = pte_alloc_kernel(pmd, address);
if (!pte)
return -ENOMEM;
remap_area_pte(pte, address, end - address, address + phys_addr, flags);
@@ -77,11 +77,15 @@ static int remap_area_pages(unsigned long address, phys_t phys_addr,
flush_cache_all();
if (address >= end)
BUG();
- spin_lock(&init_mm.page_table_lock);
do {
+ pud_t *pud;
pmd_t *pmd;
- pmd = pmd_alloc(&init_mm, dir, address);
+
error = -ENOMEM;
+ pud = pud_alloc(&init_mm, dir, address);
+ if (!pud)
+ break;
+ pmd = pmd_alloc(&init_mm, pud, address);
if (!pmd)
break;
if (remap_area_pmd(pmd, address, end - address,
@@ -91,21 +95,11 @@ static int remap_area_pages(unsigned long address, phys_t phys_addr,
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
} while (address && (address < end));
- spin_unlock(&init_mm.page_table_lock);
flush_tlb_all();
return error;
}
/*
- * Allow physical addresses to be fixed up to help 36 bit peripherals.
- */
-phys_t __attribute__ ((weak))
-fixup_bigphys_addr(phys_t phys_addr, phys_t size)
-{
- return phys_addr;
-}
-
-/*
* Generic mapping function (not visible outside):
*/
@@ -121,7 +115,7 @@ fixup_bigphys_addr(phys_t phys_addr, phys_t size)
#define IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL))
-void * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
+void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
{
struct vm_struct * area;
unsigned long offset;
@@ -141,7 +135,7 @@ void * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
*/
if (IS_LOW512(phys_addr) && IS_LOW512(last_addr) &&
flags == _CACHE_UNCACHED)
- return (void *) KSEG1ADDR(phys_addr);
+ return (void __iomem *) CKSEG1ADDR(phys_addr);
/*
* Don't allow anybody to remap normal RAM that we're using..
@@ -177,10 +171,10 @@ void * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
return NULL;
}
- return (void *) (offset + (char *)addr);
+ return (void __iomem *) (offset + (char *)addr);
}
-#define IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == KSEG1)
+#define IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1)
void __iounmap(volatile void __iomem *addr)
{
@@ -190,10 +184,8 @@ void __iounmap(volatile void __iomem *addr)
return;
p = remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr));
- if (!p) {
+ if (!p)
printk(KERN_ERR "iounmap: bad address %p\n", addr);
- return;
- }
kfree(p);
}
diff --git a/arch/mips/mm/pg-r4k.c b/arch/mips/mm/pg-r4k.c
index 9f8b16541577..f51e180072e3 100644
--- a/arch/mips/mm/pg-r4k.c
+++ b/arch/mips/mm/pg-r4k.c
@@ -25,7 +25,10 @@
#include <asm/cpu.h>
#include <asm/war.h>
-#define half_scache_line_size() (cpu_scache_line_size() >> 1)
+#define half_scache_line_size() (cpu_scache_line_size() >> 1)
+#define cpu_is_r4600_v1_x() ((read_c0_prid() & 0xfffffff0) == 0x00002010)
+#define cpu_is_r4600_v2_x() ((read_c0_prid() & 0xfffffff0) == 0x00002020)
+
/*
* Maximum sizes:
@@ -198,15 +201,15 @@ static inline void build_cdex_p(void)
if (store_offset & (cpu_dcache_line_size() - 1))
return;
- if (R4600_V1_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2010)) {
+ if (R4600_V1_HIT_CACHEOP_WAR && cpu_is_r4600_v1_x()) {
build_nop();
build_nop();
build_nop();
build_nop();
}
- if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020))
- build_insn_word(0x8c200000); /* lw $zero, ($at) */
+ if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
+ build_insn_word(0x3c01a000); /* lui $at, 0xa000 */
mi.c_format.opcode = cache_op;
mi.c_format.rs = 4; /* $a0 */
@@ -361,7 +364,7 @@ void __init build_clear_page(void)
build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0));
- if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020))
+ if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
build_insn_word(0x3c01a000); /* lui $at, 0xa000 */
dest = label();
@@ -404,9 +407,6 @@ dest = label();
build_jr_ra();
- flush_icache_range((unsigned long)&clear_page_array,
- (unsigned long) epc);
-
BUG_ON(epc > clear_page_array + ARRAY_SIZE(clear_page_array));
}
@@ -420,7 +420,7 @@ void __init build_copy_page(void)
build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0));
- if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020))
+ if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
build_insn_word(0x3c01a000); /* lui $at, 0xa000 */
dest = label();
@@ -482,8 +482,5 @@ dest = label();
build_jr_ra();
- flush_icache_range((unsigned long)&copy_page_array,
- (unsigned long) epc);
-
BUG_ON(epc > copy_page_array + ARRAY_SIZE(copy_page_array));
}
diff --git a/arch/mips/mm/pg-sb1.c b/arch/mips/mm/pg-sb1.c
index 1b6df7133c1e..148c65b9cd8b 100644
--- a/arch/mips/mm/pg-sb1.c
+++ b/arch/mips/mm/pg-sb1.c
@@ -60,7 +60,8 @@ static inline void clear_page_cpu(void *page)
" .set noreorder \n"
#ifdef CONFIG_CPU_HAS_PREFETCH
" daddiu %0, %0, 128 \n"
- " pref " SB1_PREF_STORE_STREAMED_HINT ", -128(%0) \n" /* Prefetch the first 4 lines */
+ " pref " SB1_PREF_STORE_STREAMED_HINT ", -128(%0) \n"
+ /* Prefetch the first 4 lines */
" pref " SB1_PREF_STORE_STREAMED_HINT ", -96(%0) \n"
" pref " SB1_PREF_STORE_STREAMED_HINT ", -64(%0) \n"
" pref " SB1_PREF_STORE_STREAMED_HINT ", -32(%0) \n"
@@ -106,7 +107,8 @@ static inline void copy_page_cpu(void *to, void *from)
#ifdef CONFIG_CPU_HAS_PREFETCH
" daddiu %0, %0, 128 \n"
" daddiu %1, %1, 128 \n"
- " pref " SB1_PREF_LOAD_STREAMED_HINT ", -128(%0)\n" /* Prefetch the first 4 lines */
+ " pref " SB1_PREF_LOAD_STREAMED_HINT ", -128(%0)\n"
+ /* Prefetch the first 4 lines */
" pref " SB1_PREF_STORE_STREAMED_HINT ", -128(%1)\n"
" pref " SB1_PREF_LOAD_STREAMED_HINT ", -96(%0)\n"
" pref " SB1_PREF_STORE_STREAMED_HINT ", -96(%1)\n"
@@ -207,66 +209,73 @@ typedef struct dmadscr_s {
u64 pad_b;
} dmadscr_t;
-static dmadscr_t page_descr[NR_CPUS] __attribute__((aligned(SMP_CACHE_BYTES)));
+static dmadscr_t page_descr[DM_NUM_CHANNELS]
+ __attribute__((aligned(SMP_CACHE_BYTES)));
void sb1_dma_init(void)
{
- int cpu = smp_processor_id();
- u64 base_val = CPHYSADDR(&page_descr[cpu]) | V_DM_DSCR_BASE_RINGSZ(1);
+ int i;
- bus_writeq(base_val,
- (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
- bus_writeq(base_val | M_DM_DSCR_BASE_RESET,
- (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
- bus_writeq(base_val | M_DM_DSCR_BASE_ENABL,
- (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+ for (i = 0; i < DM_NUM_CHANNELS; i++) {
+ const u64 base_val = CPHYSADDR(&page_descr[i]) |
+ V_DM_DSCR_BASE_RINGSZ(1);
+ volatile void *base_reg =
+ IOADDR(A_DM_REGISTER(i, R_DM_DSCR_BASE));
+
+ __raw_writeq(base_val, base_reg);
+ __raw_writeq(base_val | M_DM_DSCR_BASE_RESET, base_reg);
+ __raw_writeq(base_val | M_DM_DSCR_BASE_ENABL, base_reg);
+ }
}
void clear_page(void *page)
{
- int cpu = smp_processor_id();
+ u64 to_phys = CPHYSADDR(page);
+ unsigned int cpu = smp_processor_id();
- /* if the page is above Kseg0, use old way */
+ /* if the page is not in KSEG0, use old way */
if ((long)KSEGX(page) != (long)CKSEG0)
return clear_page_cpu(page);
- page_descr[cpu].dscr_a = CPHYSADDR(page) | M_DM_DSCRA_ZERO_MEM | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT;
+ page_descr[cpu].dscr_a = to_phys | M_DM_DSCRA_ZERO_MEM |
+ M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT;
page_descr[cpu].dscr_b = V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE);
- bus_writeq(1, (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
+ __raw_writeq(1, IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
/*
* Don't really want to do it this way, but there's no
* reliable way to delay completion detection.
*/
- while (!(bus_readq((void *)(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) &
- M_DM_DSCR_BASE_INTERRUPT))))
+ while (!(__raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)))
+ & M_DM_DSCR_BASE_INTERRUPT))
;
- bus_readq((void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+ __raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
}
void copy_page(void *to, void *from)
{
- unsigned long from_phys = CPHYSADDR(from);
- unsigned long to_phys = CPHYSADDR(to);
- int cpu = smp_processor_id();
+ u64 from_phys = CPHYSADDR(from);
+ u64 to_phys = CPHYSADDR(to);
+ unsigned int cpu = smp_processor_id();
- /* if either page is above Kseg0, use old way */
+ /* if any page is not in KSEG0, use old way */
if ((long)KSEGX(to) != (long)CKSEG0
|| (long)KSEGX(from) != (long)CKSEG0)
return copy_page_cpu(to, from);
- page_descr[cpu].dscr_a = CPHYSADDR(to_phys) | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT;
- page_descr[cpu].dscr_b = CPHYSADDR(from_phys) | V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE);
- bus_writeq(1, (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
+ page_descr[cpu].dscr_a = to_phys | M_DM_DSCRA_L2C_DEST |
+ M_DM_DSCRA_INTERRUPT;
+ page_descr[cpu].dscr_b = from_phys | V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE);
+ __raw_writeq(1, IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
/*
* Don't really want to do it this way, but there's no
* reliable way to delay completion detection.
*/
- while (!(bus_readq((void *)(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) &
- M_DM_DSCR_BASE_INTERRUPT))))
+ while (!(__raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)))
+ & M_DM_DSCR_BASE_INTERRUPT))
;
- bus_readq((void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+ __raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
}
#else /* !CONFIG_SIBYTE_DMA_PAGEOPS */
diff --git a/arch/mips/mm/pgtable-32.c b/arch/mips/mm/pgtable-32.c
index 4f07f81e8500..4a3c4919e314 100644
--- a/arch/mips/mm/pgtable-32.c
+++ b/arch/mips/mm/pgtable-32.c
@@ -10,6 +10,7 @@
#include <linux/mm.h>
#include <linux/bootmem.h>
#include <linux/highmem.h>
+#include <asm/fixmap.h>
#include <asm/pgtable.h>
void pgd_init(unsigned long page)
@@ -29,42 +30,12 @@ void pgd_init(unsigned long page)
}
}
-#ifdef CONFIG_HIGHMEM
-static void __init fixrange_init (unsigned long start, unsigned long end,
- pgd_t *pgd_base)
-{
- pgd_t *pgd;
- pmd_t *pmd;
- pte_t *pte;
- int i, j;
- unsigned long vaddr;
-
- vaddr = start;
- i = __pgd_offset(vaddr);
- j = __pmd_offset(vaddr);
- pgd = pgd_base + i;
-
- for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
- pmd = (pmd_t *)pgd;
- for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
- if (pmd_none(*pmd)) {
- pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
- set_pmd(pmd, __pmd((unsigned long)pte));
- if (pte != pte_offset_kernel(pmd, 0))
- BUG();
- }
- vaddr += PMD_SIZE;
- }
- j = 0;
- }
-}
-#endif
-
void __init pagetable_init(void)
{
#ifdef CONFIG_HIGHMEM
unsigned long vaddr;
pgd_t *pgd, *pgd_base;
+ pud_t *pud;
pmd_t *pmd;
pte_t *pte;
#endif
@@ -90,7 +61,8 @@ void __init pagetable_init(void)
fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
pgd = swapper_pg_dir + __pgd_offset(vaddr);
- pmd = pmd_offset(pgd, vaddr);
+ pud = pud_offset(pgd, vaddr);
+ pmd = pmd_offset(pud, vaddr);
pte = pte_offset_kernel(pmd, vaddr);
pkmap_page_table = pte;
#endif
diff --git a/arch/mips/mm/sc-rm7k.c b/arch/mips/mm/sc-rm7k.c
index 4e92f931aaba..9e8ff8badb19 100644
--- a/arch/mips/mm/sc-rm7k.c
+++ b/arch/mips/mm/sc-rm7k.c
@@ -15,6 +15,7 @@
#include <asm/cacheops.h>
#include <asm/mipsregs.h>
#include <asm/processor.h>
+#include <asm/cacheflush.h> /* for run_uncached() */
/* Primary cache parameters. */
#define sc_lsize 32
@@ -96,25 +97,13 @@ static void rm7k_sc_inv(unsigned long addr, unsigned long size)
}
/*
- * This function is executed in the uncached segment CKSEG1.
- * It must not touch the stack, because the stack pointer still points
- * into CKSEG0.
- *
- * Three options:
- * - Write it in assembly and guarantee that we don't use the stack.
- * - Disable caching for CKSEG0 before calling it.
- * - Pray that GCC doesn't randomly start using the stack.
- *
- * This being Linux, we obviously take the least sane of those options -
- * following DaveM's lead in c-r4k.c
- *
- * It seems we get our kicks from relying on unguaranteed behaviour in GCC
+ * This function is executed in uncached address space.
*/
static __init void __rm7k_sc_enable(void)
{
int i;
- set_c0_config(1 << 3); /* CONF_SE */
+ set_c0_config(RM7K_CONF_SE);
write_c0_taglo(0);
write_c0_taghi(0);
@@ -127,24 +116,22 @@ static __init void __rm7k_sc_enable(void)
".set mips0\n\t"
".set reorder"
:
- : "r" (KSEG0ADDR(i)), "i" (Index_Store_Tag_SD));
+ : "r" (CKSEG0ADDR(i)), "i" (Index_Store_Tag_SD));
}
}
static __init void rm7k_sc_enable(void)
{
- void (*func)(void) = (void *) KSEG1ADDR(&__rm7k_sc_enable);
-
- if (read_c0_config() & 0x08) /* CONF_SE */
+ if (read_c0_config() & RM7K_CONF_SE)
return;
- printk(KERN_INFO "Enabling secondary cache...");
- func();
+ printk(KERN_INFO "Enabling secondary cache...\n");
+ run_uncached(__rm7k_sc_enable);
}
static void rm7k_sc_disable(void)
{
- clear_c0_config(1<<3); /* CONF_SE */
+ clear_c0_config(RM7K_CONF_SE);
}
struct bcache_ops rm7k_sc_ops = {
@@ -158,19 +145,19 @@ void __init rm7k_sc_init(void)
{
unsigned int config = read_c0_config();
- if ((config >> 31) & 1) /* Bit 31 set -> no S-Cache */
+ if ((config & RM7K_CONF_SC))
return;
printk(KERN_INFO "Secondary cache size %dK, linesize %d bytes.\n",
(scache_size >> 10), sc_lsize);
- if (!((config >> 3) & 1)) /* CONF_SE */
+ if (!(config & RM7K_CONF_SE))
rm7k_sc_enable();
/*
* While we're at it let's deal with the tertiary cache.
*/
- if (!((config >> 17) & 1)) {
+ if (!(config & RM7K_CONF_TC)) {
/*
* We can't enable the L3 cache yet. There may be board-specific
@@ -183,9 +170,9 @@ void __init rm7k_sc_init(void)
* to probe it.
*/
printk(KERN_INFO "Tertiary cache present, %s enabled\n",
- config&(1<<12) ? "already" : "not (yet)");
+ (config & RM7K_CONF_TE) ? "already" : "not (yet)");
- if ((config >> 12) & 1)
+ if ((config & RM7K_CONF_TE))
rm7k_tcache_enabled = 1;
}
diff --git a/arch/mips/mm/tlb-andes.c b/arch/mips/mm/tlb-andes.c
index 167e08e9661a..3f422a849c41 100644
--- a/arch/mips/mm/tlb-andes.c
+++ b/arch/mips/mm/tlb-andes.c
@@ -195,6 +195,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
{
unsigned long flags;
pgd_t *pgdp;
+ pud_t *pudp;
pmd_t *pmdp;
pte_t *ptep;
int idx, pid;
@@ -220,7 +221,8 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
write_c0_entryhi(address | (pid));
pgdp = pgd_offset(vma->vm_mm, address);
tlb_probe();
- pmdp = pmd_offset(pgdp, address);
+ pudp = pud_offset(pgdp, address);
+ pmdp = pmd_offset(pudp, address);
idx = read_c0_index();
ptep = pte_offset_map(pmdp, address);
write_c0_entrylo0(pte_val(*ptep++) >> 6);
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index 59d38bc05b69..8297970f0bb1 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -21,6 +21,12 @@
extern void build_tlb_refill_handler(void);
+/*
+ * Make sure all entries differ. If they're not different
+ * MIPS32 will take revenge ...
+ */
+#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
+
/* CP0 hazard avoidance. */
#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
"nop; nop; nop; nop; nop; nop;\n\t" \
@@ -42,11 +48,8 @@ void local_flush_tlb_all(void)
/* Blast 'em all away. */
while (entry < current_cpu_data.tlbsize) {
- /*
- * Make sure all entries differ. If they're not different
- * MIPS32 will take revenge ...
- */
- write_c0_entryhi(CKSEG0 + (entry << (PAGE_SHIFT + 1)));
+ /* Make sure all entries differ. */
+ write_c0_entryhi(UNIQUE_ENTRYHI(entry));
write_c0_index(entry);
mtc0_tlbw_hazard();
tlb_write_indexed();
@@ -57,12 +60,21 @@ void local_flush_tlb_all(void)
local_irq_restore(flags);
}
+/* All entries common to a mm share an asid. To effectively flush
+ these entries, we just bump the asid. */
void local_flush_tlb_mm(struct mm_struct *mm)
{
- int cpu = smp_processor_id();
+ int cpu;
+
+ preempt_disable();
- if (cpu_context(cpu, mm) != 0)
- drop_mmu_context(mm,cpu);
+ cpu = smp_processor_id();
+
+ if (cpu_context(cpu, mm) != 0) {
+ drop_mmu_context(mm, cpu);
+ }
+
+ preempt_enable();
}
void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
@@ -75,9 +87,9 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
unsigned long flags;
int size;
- local_irq_save(flags);
size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
size = (size + 1) >> 1;
+ local_irq_save(flags);
if (size <= current_cpu_data.tlbsize/2) {
int oldpid = read_c0_entryhi();
int newpid = cpu_asid(cpu, mm);
@@ -99,8 +111,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
if (idx < 0)
continue;
/* Make sure all entries differ. */
- write_c0_entryhi(CKSEG0 +
- (idx << (PAGE_SHIFT + 1)));
+ write_c0_entryhi(UNIQUE_ENTRYHI(idx));
mtc0_tlbw_hazard();
tlb_write_indexed();
}
@@ -118,9 +129,9 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
unsigned long flags;
int size;
- local_irq_save(flags);
size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
size = (size + 1) >> 1;
+ local_irq_save(flags);
if (size <= current_cpu_data.tlbsize / 2) {
int pid = read_c0_entryhi();
@@ -142,7 +153,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
if (idx < 0)
continue;
/* Make sure all entries differ. */
- write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1)));
+ write_c0_entryhi(UNIQUE_ENTRYHI(idx));
mtc0_tlbw_hazard();
tlb_write_indexed();
}
@@ -176,7 +187,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
if (idx < 0)
goto finish;
/* Make sure all entries differ. */
- write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1)));
+ write_c0_entryhi(UNIQUE_ENTRYHI(idx));
mtc0_tlbw_hazard();
tlb_write_indexed();
tlbw_use_hazard();
@@ -197,8 +208,8 @@ void local_flush_tlb_one(unsigned long page)
int oldpid, idx;
local_irq_save(flags);
- page &= (PAGE_MASK << 1);
oldpid = read_c0_entryhi();
+ page &= (PAGE_MASK << 1);
write_c0_entryhi(page);
mtc0_tlbw_hazard();
tlb_probe();
@@ -208,7 +219,7 @@ void local_flush_tlb_one(unsigned long page)
write_c0_entrylo1(0);
if (idx >= 0) {
/* Make sure all entries differ. */
- write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1)));
+ write_c0_entryhi(UNIQUE_ENTRYHI(idx));
mtc0_tlbw_hazard();
tlb_write_indexed();
tlbw_use_hazard();
@@ -227,6 +238,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
{
unsigned long flags;
pgd_t *pgdp;
+ pud_t *pudp;
pmd_t *pmdp;
pte_t *ptep;
int idx, pid;
@@ -237,35 +249,34 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
if (current->active_mm != vma->vm_mm)
return;
- pid = read_c0_entryhi() & ASID_MASK;
-
local_irq_save(flags);
+
+ pid = read_c0_entryhi() & ASID_MASK;
address &= (PAGE_MASK << 1);
write_c0_entryhi(address | pid);
pgdp = pgd_offset(vma->vm_mm, address);
mtc0_tlbw_hazard();
tlb_probe();
BARRIER;
- pmdp = pmd_offset(pgdp, address);
+ pudp = pud_offset(pgdp, address);
+ pmdp = pmd_offset(pudp, address);
idx = read_c0_index();
ptep = pte_offset_map(pmdp, address);
- #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
- write_c0_entrylo0(ptep->pte_high);
- ptep++;
- write_c0_entrylo1(ptep->pte_high);
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
+ write_c0_entrylo0(ptep->pte_high);
+ ptep++;
+ write_c0_entrylo1(ptep->pte_high);
#else
- write_c0_entrylo0(pte_val(*ptep++) >> 6);
- write_c0_entrylo1(pte_val(*ptep) >> 6);
+ write_c0_entrylo0(pte_val(*ptep++) >> 6);
+ write_c0_entrylo1(pte_val(*ptep) >> 6);
#endif
- write_c0_entryhi(address | pid);
mtc0_tlbw_hazard();
if (idx < 0)
tlb_write_random();
else
tlb_write_indexed();
tlbw_use_hazard();
- write_c0_entryhi(pid);
local_irq_restore(flags);
}
@@ -357,7 +368,8 @@ __init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
old_pagemask = read_c0_pagemask();
wired = read_c0_wired();
if (--temp_tlb_entry < wired) {
- printk(KERN_WARNING "No TLB space left for add_temporary_entry\n");
+ printk(KERN_WARNING
+ "No TLB space left for add_temporary_entry\n");
ret = -ENOSPC;
goto out;
}
@@ -388,7 +400,7 @@ static void __init probe_tlb(unsigned long config)
* is not supported, we assume R4k style. Cpu probing already figured
* out the number of tlb entries.
*/
- if ((c->processor_id & 0xff0000) == PRID_COMP_LEGACY)
+ if ((c->processor_id & 0xff0000) == PRID_COMP_LEGACY)
return;
reg = read_c0_config1();
diff --git a/arch/mips/mm/tlb-sb1.c b/arch/mips/mm/tlb-sb1.c
deleted file mode 100644
index 6256cafcf3a2..000000000000
--- a/arch/mips/mm/tlb-sb1.c
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org)
- * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-#include <linux/init.h>
-#include <asm/mmu_context.h>
-#include <asm/bootinfo.h>
-#include <asm/cpu.h>
-
-extern void build_tlb_refill_handler(void);
-
-#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
-
-/* Dump the current entry* and pagemask registers */
-static inline void dump_cur_tlb_regs(void)
-{
- unsigned int entryhihi, entryhilo, entrylo0hi, entrylo0lo, entrylo1hi;
- unsigned int entrylo1lo, pagemask;
-
- __asm__ __volatile__ (
- ".set push \n"
- ".set noreorder \n"
- ".set mips64 \n"
- ".set noat \n"
- " tlbr \n"
- " dmfc0 $1, $10 \n"
- " dsrl32 %0, $1, 0 \n"
- " sll %1, $1, 0 \n"
- " dmfc0 $1, $2 \n"
- " dsrl32 %2, $1, 0 \n"
- " sll %3, $1, 0 \n"
- " dmfc0 $1, $3 \n"
- " dsrl32 %4, $1, 0 \n"
- " sll %5, $1, 0 \n"
- " mfc0 %6, $5 \n"
- ".set pop \n"
- : "=r" (entryhihi), "=r" (entryhilo),
- "=r" (entrylo0hi), "=r" (entrylo0lo),
- "=r" (entrylo1hi), "=r" (entrylo1lo),
- "=r" (pagemask));
-
- printk("%08X%08X %08X%08X %08X%08X %08X",
- entryhihi, entryhilo,
- entrylo0hi, entrylo0lo,
- entrylo1hi, entrylo1lo,
- pagemask);
-}
-
-void sb1_dump_tlb(void)
-{
- unsigned long old_ctx;
- unsigned long flags;
- int entry;
- local_irq_save(flags);
- old_ctx = read_c0_entryhi();
- printk("Current TLB registers state:\n"
- " EntryHi EntryLo0 EntryLo1 PageMask Index\n"
- "--------------------------------------------------------------------\n");
- dump_cur_tlb_regs();
- printk(" %08X\n", read_c0_index());
- printk("\n\nFull TLB Dump:\n"
- "Idx EntryHi EntryLo0 EntryLo1 PageMask\n"
- "--------------------------------------------------------------\n");
- for (entry = 0; entry < current_cpu_data.tlbsize; entry++) {
- write_c0_index(entry);
- printk("\n%02i ", entry);
- dump_cur_tlb_regs();
- }
- printk("\n");
- write_c0_entryhi(old_ctx);
- local_irq_restore(flags);
-}
-
-void local_flush_tlb_all(void)
-{
- unsigned long flags;
- unsigned long old_ctx;
- int entry;
-
- local_irq_save(flags);
- /* Save old context and create impossible VPN2 value */
- old_ctx = read_c0_entryhi() & ASID_MASK;
- write_c0_entrylo0(0);
- write_c0_entrylo1(0);
-
- entry = read_c0_wired();
- while (entry < current_cpu_data.tlbsize) {
- write_c0_entryhi(UNIQUE_ENTRYHI(entry));
- write_c0_index(entry);
- tlb_write_indexed();
- entry++;
- }
- write_c0_entryhi(old_ctx);
- local_irq_restore(flags);
-}
-
-
-/*
- * Use a bogus region of memory (starting at 0) to sanitize the TLB's.
- * Use increments of the maximum page size (16MB), and check for duplicate
- * entries before doing a given write. Then, when we're safe from collisions
- * with the firmware, go back and give all the entries invalid addresses with
- * the normal flush routine. Wired entries will be killed as well!
- */
-static void __init sb1_sanitize_tlb(void)
-{
- int entry;
- long addr = 0;
-
- long inc = 1<<24; /* 16MB */
- /* Save old context and create impossible VPN2 value */
- write_c0_entrylo0(0);
- write_c0_entrylo1(0);
- for (entry = 0; entry < current_cpu_data.tlbsize; entry++) {
- do {
- addr += inc;
- write_c0_entryhi(addr);
- tlb_probe();
- } while ((int)(read_c0_index()) >= 0);
- write_c0_index(entry);
- tlb_write_indexed();
- }
- /* Now that we know we're safe from collisions, we can safely flush
- the TLB with the "normal" routine. */
- local_flush_tlb_all();
-}
-
-void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
- unsigned long end)
-{
- struct mm_struct *mm = vma->vm_mm;
- unsigned long flags;
- int cpu;
-
- local_irq_save(flags);
- cpu = smp_processor_id();
- if (cpu_context(cpu, mm) != 0) {
- int size;
- size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
- size = (size + 1) >> 1;
- if (size <= (current_cpu_data.tlbsize/2)) {
- int oldpid = read_c0_entryhi() & ASID_MASK;
- int newpid = cpu_asid(cpu, mm);
-
- start &= (PAGE_MASK << 1);
- end += ((PAGE_SIZE << 1) - 1);
- end &= (PAGE_MASK << 1);
- while (start < end) {
- int idx;
-
- write_c0_entryhi(start | newpid);
- start += (PAGE_SIZE << 1);
- tlb_probe();
- idx = read_c0_index();
- write_c0_entrylo0(0);
- write_c0_entrylo1(0);
- write_c0_entryhi(UNIQUE_ENTRYHI(idx));
- if (idx < 0)
- continue;
- tlb_write_indexed();
- }
- write_c0_entryhi(oldpid);
- } else {
- drop_mmu_context(mm, cpu);
- }
- }
- local_irq_restore(flags);
-}
-
-void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
-{
- unsigned long flags;
- int size;
-
- size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
- size = (size + 1) >> 1;
-
- local_irq_save(flags);
- if (size <= (current_cpu_data.tlbsize/2)) {
- int pid = read_c0_entryhi();
-
- start &= (PAGE_MASK << 1);
- end += ((PAGE_SIZE << 1) - 1);
- end &= (PAGE_MASK << 1);
-
- while (start < end) {
- int idx;
-
- write_c0_entryhi(start);
- start += (PAGE_SIZE << 1);
- tlb_probe();
- idx = read_c0_index();
- write_c0_entrylo0(0);
- write_c0_entrylo1(0);
- write_c0_entryhi(UNIQUE_ENTRYHI(idx));
- if (idx < 0)
- continue;
- tlb_write_indexed();
- }
- write_c0_entryhi(pid);
- } else {
- local_flush_tlb_all();
- }
- local_irq_restore(flags);
-}
-
-void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
-{
- unsigned long flags;
- int cpu = smp_processor_id();
-
- local_irq_save(flags);
- if (cpu_context(cpu, vma->vm_mm) != 0) {
- int oldpid, newpid, idx;
- newpid = cpu_asid(cpu, vma->vm_mm);
- page &= (PAGE_MASK << 1);
- oldpid = read_c0_entryhi() & ASID_MASK;
- write_c0_entryhi(page | newpid);
- tlb_probe();
- idx = read_c0_index();
- write_c0_entrylo0(0);
- write_c0_entrylo1(0);
- if (idx < 0)
- goto finish;
- /* Make sure all entries differ. */
- write_c0_entryhi(UNIQUE_ENTRYHI(idx));
- tlb_write_indexed();
- finish:
- write_c0_entryhi(oldpid);
- }
- local_irq_restore(flags);
-}
-
-/*
- * Remove one kernel space TLB entry. This entry is assumed to be marked
- * global so we don't do the ASID thing.
- */
-void local_flush_tlb_one(unsigned long page)
-{
- unsigned long flags;
- int oldpid, idx;
-
- page &= (PAGE_MASK << 1);
- oldpid = read_c0_entryhi() & ASID_MASK;
-
- local_irq_save(flags);
- write_c0_entryhi(page);
- tlb_probe();
- idx = read_c0_index();
- if (idx >= 0) {
- /* Make sure all entries differ. */
- write_c0_entryhi(UNIQUE_ENTRYHI(idx));
- write_c0_entrylo0(0);
- write_c0_entrylo1(0);
- tlb_write_indexed();
- }
-
- write_c0_entryhi(oldpid);
- local_irq_restore(flags);
-}
-
-/* All entries common to a mm share an asid. To effectively flush
- these entries, we just bump the asid. */
-void local_flush_tlb_mm(struct mm_struct *mm)
-{
- int cpu;
-
- preempt_disable();
-
- cpu = smp_processor_id();
-
- if (cpu_context(cpu, mm) != 0) {
- drop_mmu_context(mm, cpu);
- }
-
- preempt_enable();
-}
-
-/* Stolen from mips32 routines */
-
-void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
-{
- unsigned long flags;
- pgd_t *pgdp;
- pmd_t *pmdp;
- pte_t *ptep;
- int idx, pid;
-
- /*
- * Handle debugger faulting in for debugee.
- */
- if (current->active_mm != vma->vm_mm)
- return;
-
- local_irq_save(flags);
-
- pid = read_c0_entryhi() & ASID_MASK;
- address &= (PAGE_MASK << 1);
- write_c0_entryhi(address | (pid));
- pgdp = pgd_offset(vma->vm_mm, address);
- tlb_probe();
- pmdp = pmd_offset(pgdp, address);
- idx = read_c0_index();
- ptep = pte_offset_map(pmdp, address);
- write_c0_entrylo0(pte_val(*ptep++) >> 6);
- write_c0_entrylo1(pte_val(*ptep) >> 6);
- if (idx < 0) {
- tlb_write_random();
- } else {
- tlb_write_indexed();
- }
- local_irq_restore(flags);
-}
-
-void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
- unsigned long entryhi, unsigned long pagemask)
-{
- unsigned long flags;
- unsigned long wired;
- unsigned long old_pagemask;
- unsigned long old_ctx;
-
- local_irq_save(flags);
- old_ctx = read_c0_entryhi() & 0xff;
- old_pagemask = read_c0_pagemask();
- wired = read_c0_wired();
- write_c0_wired(wired + 1);
- write_c0_index(wired);
-
- write_c0_pagemask(pagemask);
- write_c0_entryhi(entryhi);
- write_c0_entrylo0(entrylo0);
- write_c0_entrylo1(entrylo1);
- tlb_write_indexed();
-
- write_c0_entryhi(old_ctx);
- write_c0_pagemask(old_pagemask);
-
- local_flush_tlb_all();
- local_irq_restore(flags);
-}
-
-/*
- * This is called from loadmmu.c. We have to set up all the
- * memory management function pointers, as well as initialize
- * the caches and tlbs
- */
-void tlb_init(void)
-{
- write_c0_pagemask(PM_DEFAULT_MASK);
- write_c0_wired(0);
-
- /*
- * We don't know what state the firmware left the TLB's in, so this is
- * the ultra-conservative way to flush the TLB's and avoid machine
- * check exceptions due to duplicate TLB entries
- */
- sb1_sanitize_tlb();
-
- build_tlb_refill_handler();
-}
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 6569be3983c7..0f9485806bac 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -6,6 +6,7 @@
* Synthesize TLB refill handlers at runtime.
*
* Copyright (C) 2004,2005 by Thiemo Seufer
+ * Copyright (C) 2005 Maciej W. Rozycki
*/
#include <stdarg.h>
@@ -91,7 +92,7 @@ enum opcode {
insn_addu, insn_addiu, insn_and, insn_andi, insn_beq,
insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl,
insn_bne, insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0,
- insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32,
+ insn_dsll, insn_dsll32, insn_dsra, insn_dsrl,
insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, insn_ld,
insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, insn_mtc0,
insn_ori, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll,
@@ -134,7 +135,6 @@ static __initdata struct insn insn_table[] = {
{ insn_dsll32, M(spec_op,0,0,0,0,dsll32_op), RT | RD | RE },
{ insn_dsra, M(spec_op,0,0,0,0,dsra_op), RT | RD | RE },
{ insn_dsrl, M(spec_op,0,0,0,0,dsrl_op), RT | RD | RE },
- { insn_dsrl32, M(spec_op,0,0,0,0,dsrl32_op), RT | RD | RE },
{ insn_dsubu, M(spec_op,0,0,0,0,dsubu_op), RS | RT | RD },
{ insn_eret, M(cop0_op,cop_op,0,0,0,eret_op), 0 },
{ insn_j, M(j_op,0,0,0,0,0), JIMM },
@@ -366,7 +366,6 @@ I_u2u1u3(_dsll);
I_u2u1u3(_dsll32);
I_u2u1u3(_dsra);
I_u2u1u3(_dsrl);
-I_u2u1u3(_dsrl32);
I_u3u1u2(_dsubu);
I_0(_eret);
I_u1(_j);
@@ -412,7 +411,6 @@ enum label_id {
label_nopage_tlbm,
label_smp_pgtable_change,
label_r3000_write_probe_fail,
- label_r3000_write_probe_ok
};
struct label {
@@ -445,7 +443,6 @@ L_LA(_nopage_tlbs)
L_LA(_nopage_tlbm)
L_LA(_smp_pgtable_change)
L_LA(_r3000_write_probe_fail)
-L_LA(_r3000_write_probe_ok)
/* convenience macros for instructions */
#ifdef CONFIG_64BIT
@@ -490,7 +487,7 @@ L_LA(_r3000_write_probe_ok)
static __init int __attribute__((unused)) in_compat_space_p(long addr)
{
/* Is this address in 32bit compat space? */
- return (((addr) & 0xffffffff00000000) == 0xffffffff00000000);
+ return (((addr) & 0xffffffff00000000L) == 0xffffffff00000000L);
}
static __init int __attribute__((unused)) rel_highest(long val)
@@ -734,7 +731,7 @@ static void __init build_r3000_tlb_refill_handler(void)
if (p > tlb_handler + 32)
panic("TLB refill handler space exceeded");
- printk("Synthesized TLB handler (%u instructions).\n",
+ printk("Synthesized TLB refill handler (%u instructions).\n",
(unsigned int)(p - tlb_handler));
#ifdef DEBUG_TLB
{
@@ -746,7 +743,6 @@ static void __init build_r3000_tlb_refill_handler(void)
#endif
memcpy((void *)CAC_BASE, tlb_handler, 0x80);
- flush_icache_range(CAC_BASE, CAC_BASE + 0x80);
}
/*
@@ -783,6 +779,8 @@ static __initdata u32 final_handler[64];
static __init void __attribute__((unused)) build_tlb_probe_entry(u32 **p)
{
switch (current_cpu_data.cputype) {
+ /* Found by experiment: R4600 v2.0 needs this, too. */
+ case CPU_R4600:
case CPU_R5000:
case CPU_R5000A:
case CPU_NEVADA:
@@ -834,12 +832,20 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l,
case CPU_R4700:
case CPU_R5000:
case CPU_R5000A:
+ i_nop(p);
+ tlbw(p);
+ i_nop(p);
+ break;
+
+ case CPU_R4300:
case CPU_5KC:
case CPU_TX49XX:
case CPU_AU1000:
case CPU_AU1100:
case CPU_AU1500:
case CPU_AU1550:
+ case CPU_AU1200:
+ case CPU_PR4450:
i_nop(p);
tlbw(p);
break;
@@ -848,6 +854,7 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l,
case CPU_R12000:
case CPU_4KC:
case CPU_SB1:
+ case CPU_SB1A:
case CPU_4KSC:
case CPU_20KC:
case CPU_25KF:
@@ -875,6 +882,7 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l,
case CPU_4KEC:
case CPU_24K:
+ case CPU_34K:
i_ehb(p);
tlbw(p);
break;
@@ -911,6 +919,7 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l,
case CPU_VR4131:
case CPU_VR4133:
+ case CPU_R5432:
i_nop(p);
i_nop(p);
tlbw(p);
@@ -942,34 +951,29 @@ build_get_pmde64(u32 **p, struct label **l, struct reloc **r,
/* No i_nop needed here, since the next insn doesn't touch TMP. */
#ifdef CONFIG_SMP
+# ifdef CONFIG_BUILD_ELF64
/*
- * 64 bit SMP has the lower part of &pgd_current[smp_processor_id()]
+ * 64 bit SMP running in XKPHYS has smp_processor_id() << 3
* stored in CONTEXT.
*/
- if (in_compat_space_p(pgdc)) {
- i_dmfc0(p, ptr, C0_CONTEXT);
- i_dsra(p, ptr, ptr, 23);
- i_ld(p, ptr, 0, ptr);
- } else {
-#ifdef CONFIG_BUILD_ELF64
- i_dmfc0(p, ptr, C0_CONTEXT);
- i_dsrl(p, ptr, ptr, 23);
- i_dsll(p, ptr, ptr, 3);
- i_LA_mostly(p, tmp, pgdc);
- i_daddu(p, ptr, ptr, tmp);
- i_dmfc0(p, tmp, C0_BADVADDR);
- i_ld(p, ptr, rel_lo(pgdc), ptr);
-#else
- i_dmfc0(p, ptr, C0_CONTEXT);
- i_lui(p, tmp, rel_highest(pgdc));
- i_dsll(p, ptr, ptr, 9);
- i_daddiu(p, tmp, tmp, rel_higher(pgdc));
- i_dsrl32(p, ptr, ptr, 0);
- i_and(p, ptr, ptr, tmp);
- i_dmfc0(p, tmp, C0_BADVADDR);
- i_ld(p, ptr, 0, ptr);
-#endif
- }
+ i_dmfc0(p, ptr, C0_CONTEXT);
+ i_dsrl(p, ptr, ptr, 23);
+ i_LA_mostly(p, tmp, pgdc);
+ i_daddu(p, ptr, ptr, tmp);
+ i_dmfc0(p, tmp, C0_BADVADDR);
+ i_ld(p, ptr, rel_lo(pgdc), ptr);
+# else
+ /*
+ * 64 bit SMP running in compat space has the lower part of
+ * &pgd_current[smp_processor_id()] stored in CONTEXT.
+ */
+ if (!in_compat_space_p(pgdc))
+ panic("Invalid page directory address!");
+
+ i_dmfc0(p, ptr, C0_CONTEXT);
+ i_dsra(p, ptr, ptr, 23);
+ i_ld(p, ptr, 0, ptr);
+# endif
#else
i_LA_mostly(p, ptr, pgdc);
i_ld(p, ptr, rel_lo(pgdc), ptr);
@@ -1026,7 +1030,6 @@ build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr)
i_mfc0(p, ptr, C0_CONTEXT);
i_LA_mostly(p, tmp, pgdc);
i_srl(p, ptr, ptr, 23);
- i_sll(p, ptr, ptr, 2);
i_addu(p, ptr, tmp, ptr);
#else
i_LA_mostly(p, ptr, pgdc);
@@ -1245,13 +1248,19 @@ static void __init build_r4000_tlb_refill_handler(void)
{
int i;
- for (i = 0; i < 64; i++)
- printk("%08x\n", final_handler[i]);
+ f = final_handler;
+#ifdef CONFIG_64BIT
+ if (final_len > 32)
+ final_len = 64;
+ else
+ f = final_handler + 32;
+#endif /* CONFIG_64BIT */
+ for (i = 0; i < final_len; i++)
+ printk("%08x\n", f[i]);
}
#endif
memcpy((void *)CAC_BASE, final_handler, 0x100);
- flush_icache_range(CAC_BASE, CAC_BASE + 0x100);
}
/*
@@ -1277,37 +1286,41 @@ u32 __tlb_handler_align handle_tlbs[FASTPATH_SIZE];
u32 __tlb_handler_align handle_tlbm[FASTPATH_SIZE];
static void __init
-iPTE_LW(u32 **p, struct label **l, unsigned int pte, int offset,
- unsigned int ptr)
+iPTE_LW(u32 **p, struct label **l, unsigned int pte, unsigned int ptr)
{
#ifdef CONFIG_SMP
# ifdef CONFIG_64BIT_PHYS_ADDR
if (cpu_has_64bits)
- i_lld(p, pte, offset, ptr);
+ i_lld(p, pte, 0, ptr);
else
# endif
- i_LL(p, pte, offset, ptr);
+ i_LL(p, pte, 0, ptr);
#else
# ifdef CONFIG_64BIT_PHYS_ADDR
if (cpu_has_64bits)
- i_ld(p, pte, offset, ptr);
+ i_ld(p, pte, 0, ptr);
else
# endif
- i_LW(p, pte, offset, ptr);
+ i_LW(p, pte, 0, ptr);
#endif
}
static void __init
-iPTE_SW(u32 **p, struct reloc **r, unsigned int pte, int offset,
- unsigned int ptr)
+iPTE_SW(u32 **p, struct reloc **r, unsigned int pte, unsigned int ptr,
+ unsigned int mode)
{
+#ifdef CONFIG_64BIT_PHYS_ADDR
+ unsigned int hwmode = mode & (_PAGE_VALID | _PAGE_DIRTY);
+#endif
+
+ i_ori(p, pte, pte, mode);
#ifdef CONFIG_SMP
# ifdef CONFIG_64BIT_PHYS_ADDR
if (cpu_has_64bits)
- i_scd(p, pte, offset, ptr);
+ i_scd(p, pte, 0, ptr);
else
# endif
- i_SC(p, pte, offset, ptr);
+ i_SC(p, pte, 0, ptr);
if (r10000_llsc_war())
il_beqzl(p, r, pte, label_smp_pgtable_change);
@@ -1318,7 +1331,7 @@ iPTE_SW(u32 **p, struct reloc **r, unsigned int pte, int offset,
if (!cpu_has_64bits) {
/* no i_nop needed */
i_ll(p, pte, sizeof(pte_t) / 2, ptr);
- i_ori(p, pte, pte, _PAGE_VALID);
+ i_ori(p, pte, pte, hwmode);
i_sc(p, pte, sizeof(pte_t) / 2, ptr);
il_beqz(p, r, pte, label_smp_pgtable_change);
/* no i_nop needed */
@@ -1331,15 +1344,15 @@ iPTE_SW(u32 **p, struct reloc **r, unsigned int pte, int offset,
#else
# ifdef CONFIG_64BIT_PHYS_ADDR
if (cpu_has_64bits)
- i_sd(p, pte, offset, ptr);
+ i_sd(p, pte, 0, ptr);
else
# endif
- i_SW(p, pte, offset, ptr);
+ i_SW(p, pte, 0, ptr);
# ifdef CONFIG_64BIT_PHYS_ADDR
if (!cpu_has_64bits) {
i_lw(p, pte, sizeof(pte_t) / 2, ptr);
- i_ori(p, pte, pte, _PAGE_VALID);
+ i_ori(p, pte, pte, hwmode);
i_sw(p, pte, sizeof(pte_t) / 2, ptr);
i_lw(p, pte, 0, ptr);
}
@@ -1359,7 +1372,7 @@ build_pte_present(u32 **p, struct label **l, struct reloc **r,
i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
il_bnez(p, r, pte, lid);
- iPTE_LW(p, l, pte, 0, ptr);
+ iPTE_LW(p, l, pte, ptr);
}
/* Make PTE valid, store result in PTR. */
@@ -1367,8 +1380,9 @@ static void __init
build_make_valid(u32 **p, struct reloc **r, unsigned int pte,
unsigned int ptr)
{
- i_ori(p, pte, pte, _PAGE_VALID | _PAGE_ACCESSED);
- iPTE_SW(p, r, pte, 0, ptr);
+ unsigned int mode = _PAGE_VALID | _PAGE_ACCESSED;
+
+ iPTE_SW(p, r, pte, ptr, mode);
}
/*
@@ -1382,7 +1396,7 @@ build_pte_writable(u32 **p, struct label **l, struct reloc **r,
i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
il_bnez(p, r, pte, lid);
- iPTE_LW(p, l, pte, 0, ptr);
+ iPTE_LW(p, l, pte, ptr);
}
/* Make PTE writable, update software status bits as well, then store
@@ -1392,9 +1406,10 @@ static void __init
build_make_write(u32 **p, struct reloc **r, unsigned int pte,
unsigned int ptr)
{
- i_ori(p, pte, pte,
- _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY);
- iPTE_SW(p, r, pte, 0, ptr);
+ unsigned int mode = (_PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID
+ | _PAGE_DIRTY);
+
+ iPTE_SW(p, r, pte, ptr, mode);
}
/*
@@ -1407,41 +1422,48 @@ build_pte_modifiable(u32 **p, struct label **l, struct reloc **r,
{
i_andi(p, pte, pte, _PAGE_WRITE);
il_beqz(p, r, pte, lid);
- iPTE_LW(p, l, pte, 0, ptr);
+ iPTE_LW(p, l, pte, ptr);
}
/*
* R3000 style TLB load/store/modify handlers.
*/
-/* This places the pte in the page table at PTR into ENTRYLO0. */
+/*
+ * This places the pte into ENTRYLO0 and writes it with tlbwi.
+ * Then it returns.
+ */
static void __init
-build_r3000_pte_reload(u32 **p, unsigned int ptr)
+build_r3000_pte_reload_tlbwi(u32 **p, unsigned int pte, unsigned int tmp)
{
- i_lw(p, ptr, 0, ptr);
- i_nop(p); /* load delay */
- i_mtc0(p, ptr, C0_ENTRYLO0);
- i_nop(p); /* cp0 delay */
+ i_mtc0(p, pte, C0_ENTRYLO0); /* cp0 delay */
+ i_mfc0(p, tmp, C0_EPC); /* cp0 delay */
+ i_tlbwi(p);
+ i_jr(p, tmp);
+ i_rfe(p); /* branch delay */
}
/*
- * The index register may have the probe fail bit set,
- * because we would trap on access kseg2, i.e. without refill.
+ * This places the pte into ENTRYLO0 and writes it with tlbwi
+ * or tlbwr as appropriate. This is because the index register
+ * may have the probe fail bit set as a result of a trap on a
+ * kseg2 access, i.e. without refill. Then it returns.
*/
static void __init
-build_r3000_tlb_write(u32 **p, struct label **l, struct reloc **r,
- unsigned int tmp)
+build_r3000_tlb_reload_write(u32 **p, struct label **l, struct reloc **r,
+ unsigned int pte, unsigned int tmp)
{
i_mfc0(p, tmp, C0_INDEX);
- i_nop(p); /* cp0 delay */
- il_bltz(p, r, tmp, label_r3000_write_probe_fail);
- i_nop(p); /* branch delay */
- i_tlbwi(p);
- il_b(p, r, label_r3000_write_probe_ok);
- i_nop(p); /* branch delay */
+ i_mtc0(p, pte, C0_ENTRYLO0); /* cp0 delay */
+ il_bltz(p, r, tmp, label_r3000_write_probe_fail); /* cp0 delay */
+ i_mfc0(p, tmp, C0_EPC); /* branch delay */
+ i_tlbwi(p); /* cp0 delay */
+ i_jr(p, tmp);
+ i_rfe(p); /* branch delay */
l_r3000_write_probe_fail(l, *p);
- i_tlbwr(p);
- l_r3000_write_probe_ok(l, *p);
+ i_tlbwr(p); /* cp0 delay */
+ i_jr(p, tmp);
+ i_rfe(p); /* branch delay */
}
static void __init
@@ -1461,17 +1483,7 @@ build_r3000_tlbchange_handler_head(u32 **p, unsigned int pte,
i_andi(p, pte, pte, 0xffc); /* load delay */
i_addu(p, ptr, ptr, pte);
i_lw(p, pte, 0, ptr);
- i_nop(p); /* load delay */
- i_tlbp(p);
-}
-
-static void __init
-build_r3000_tlbchange_handler_tail(u32 **p, unsigned int tmp)
-{
- i_mfc0(p, tmp, C0_EPC);
- i_nop(p); /* cp0 delay */
- i_jr(p, tmp);
- i_rfe(p); /* branch delay */
+ i_tlbp(p); /* load delay */
}
static void __init build_r3000_tlb_load_handler(void)
@@ -1486,10 +1498,9 @@ static void __init build_r3000_tlb_load_handler(void)
build_r3000_tlbchange_handler_head(&p, K0, K1);
build_pte_present(&p, &l, &r, K0, K1, label_nopage_tlbl);
+ i_nop(&p); /* load delay */
build_make_valid(&p, &r, K0, K1);
- build_r3000_pte_reload(&p, K1);
- build_r3000_tlb_write(&p, &l, &r, K0);
- build_r3000_tlbchange_handler_tail(&p, K0);
+ build_r3000_tlb_reload_write(&p, &l, &r, K0, K1);
l_nopage_tlbl(&l, p);
i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
@@ -1506,13 +1517,10 @@ static void __init build_r3000_tlb_load_handler(void)
{
int i;
- for (i = 0; i < FASTPATH_SIZE; i++)
+ for (i = 0; i < (p - handle_tlbl); i++)
printk("%08x\n", handle_tlbl[i]);
}
#endif
-
- flush_icache_range((unsigned long)handle_tlbl,
- (unsigned long)handle_tlbl + FASTPATH_SIZE * sizeof(u32));
}
static void __init build_r3000_tlb_store_handler(void)
@@ -1527,10 +1535,9 @@ static void __init build_r3000_tlb_store_handler(void)
build_r3000_tlbchange_handler_head(&p, K0, K1);
build_pte_writable(&p, &l, &r, K0, K1, label_nopage_tlbs);
+ i_nop(&p); /* load delay */
build_make_write(&p, &r, K0, K1);
- build_r3000_pte_reload(&p, K1);
- build_r3000_tlb_write(&p, &l, &r, K0);
- build_r3000_tlbchange_handler_tail(&p, K0);
+ build_r3000_tlb_reload_write(&p, &l, &r, K0, K1);
l_nopage_tlbs(&l, p);
i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
@@ -1547,13 +1554,10 @@ static void __init build_r3000_tlb_store_handler(void)
{
int i;
- for (i = 0; i < FASTPATH_SIZE; i++)
+ for (i = 0; i < (p - handle_tlbs); i++)
printk("%08x\n", handle_tlbs[i]);
}
#endif
-
- flush_icache_range((unsigned long)handle_tlbs,
- (unsigned long)handle_tlbs + FASTPATH_SIZE * sizeof(u32));
}
static void __init build_r3000_tlb_modify_handler(void)
@@ -1568,10 +1572,9 @@ static void __init build_r3000_tlb_modify_handler(void)
build_r3000_tlbchange_handler_head(&p, K0, K1);
build_pte_modifiable(&p, &l, &r, K0, K1, label_nopage_tlbm);
+ i_nop(&p); /* load delay */
build_make_write(&p, &r, K0, K1);
- build_r3000_pte_reload(&p, K1);
- i_tlbwi(&p);
- build_r3000_tlbchange_handler_tail(&p, K0);
+ build_r3000_pte_reload_tlbwi(&p, K0, K1);
l_nopage_tlbm(&l, p);
i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
@@ -1588,13 +1591,10 @@ static void __init build_r3000_tlb_modify_handler(void)
{
int i;
- for (i = 0; i < FASTPATH_SIZE; i++)
+ for (i = 0; i < (p - handle_tlbm); i++)
printk("%08x\n", handle_tlbm[i]);
}
#endif
-
- flush_icache_range((unsigned long)handle_tlbm,
- (unsigned long)handle_tlbm + FASTPATH_SIZE * sizeof(u32));
}
/*
@@ -1620,7 +1620,7 @@ build_r4000_tlbchange_handler_head(u32 **p, struct label **l,
#ifdef CONFIG_SMP
l_smp_pgtable_change(l, *p);
# endif
- iPTE_LW(p, l, pte, 0, ptr); /* get even pte */
+ iPTE_LW(p, l, pte, ptr); /* get even pte */
build_tlb_probe_entry(p);
}
@@ -1680,13 +1680,10 @@ static void __init build_r4000_tlb_load_handler(void)
{
int i;
- for (i = 0; i < FASTPATH_SIZE; i++)
+ for (i = 0; i < (p - handle_tlbl); i++)
printk("%08x\n", handle_tlbl[i]);
}
#endif
-
- flush_icache_range((unsigned long)handle_tlbl,
- (unsigned long)handle_tlbl + FASTPATH_SIZE * sizeof(u32));
}
static void __init build_r4000_tlb_store_handler(void)
@@ -1719,13 +1716,10 @@ static void __init build_r4000_tlb_store_handler(void)
{
int i;
- for (i = 0; i < FASTPATH_SIZE; i++)
+ for (i = 0; i < (p - handle_tlbs); i++)
printk("%08x\n", handle_tlbs[i]);
}
#endif
-
- flush_icache_range((unsigned long)handle_tlbs,
- (unsigned long)handle_tlbs + FASTPATH_SIZE * sizeof(u32));
}
static void __init build_r4000_tlb_modify_handler(void)
@@ -1759,13 +1753,10 @@ static void __init build_r4000_tlb_modify_handler(void)
{
int i;
- for (i = 0; i < FASTPATH_SIZE; i++)
+ for (i = 0; i < (p - handle_tlbm); i++)
printk("%08x\n", handle_tlbm[i]);
}
#endif
-
- flush_icache_range((unsigned long)handle_tlbm,
- (unsigned long)handle_tlbm + FASTPATH_SIZE * sizeof(u32));
}
void __init build_tlb_refill_handler(void)
@@ -1813,3 +1804,13 @@ void __init build_tlb_refill_handler(void)
}
}
}
+
+void __init flush_tlb_handlers(void)
+{
+ flush_icache_range((unsigned long)handle_tlbl,
+ (unsigned long)handle_tlbl + sizeof(handle_tlbl));
+ flush_icache_range((unsigned long)handle_tlbs,
+ (unsigned long)handle_tlbs + sizeof(handle_tlbs));
+ flush_icache_range((unsigned long)handle_tlbm,
+ (unsigned long)handle_tlbm + sizeof(handle_tlbm));
+}
diff --git a/arch/mips/momentum/Kconfig b/arch/mips/momentum/Kconfig
new file mode 100644
index 000000000000..70a61cf7174d
--- /dev/null
+++ b/arch/mips/momentum/Kconfig
@@ -0,0 +1,6 @@
+config JAGUAR_DMALOW
+ bool "Low DMA Mode"
+ depends on MOMENCO_JAGUAR_ATX
+ help
+ Select to Y if jump JP5 is set on your board, N otherwise. Normally
+ the jumper is set, so if you feel unsafe, just say Y.
diff --git a/arch/mips/momentum/jaguar_atx/prom.c b/arch/mips/momentum/jaguar_atx/prom.c
index 14ae2e713585..aae7a802767a 100644
--- a/arch/mips/momentum/jaguar_atx/prom.c
+++ b/arch/mips/momentum/jaguar_atx/prom.c
@@ -236,8 +236,9 @@ void __init prom_init(void)
#endif
}
-void __init prom_free_prom_memory(void)
+unsigned long __init prom_free_prom_memory(void)
{
+ return 0;
}
void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
diff --git a/arch/mips/momentum/jaguar_atx/setup.c b/arch/mips/momentum/jaguar_atx/setup.c
index 90288cf2b1e0..768bf4406452 100644
--- a/arch/mips/momentum/jaguar_atx/setup.c
+++ b/arch/mips/momentum/jaguar_atx/setup.c
@@ -351,7 +351,7 @@ static __init int __init ja_pci_init(void)
arch_initcall(ja_pci_init);
-static int __init momenco_jaguar_atx_setup(void)
+void __init plat_setup(void)
{
unsigned int tmpword;
@@ -467,8 +467,4 @@ static int __init momenco_jaguar_atx_setup(void)
}
#endif
-
- return 0;
}
-
-early_initcall(momenco_jaguar_atx_setup);
diff --git a/arch/mips/momentum/ocelot_3/prom.c b/arch/mips/momentum/ocelot_3/prom.c
index c4fa9c525faa..9803daa2a792 100644
--- a/arch/mips/momentum/ocelot_3/prom.c
+++ b/arch/mips/momentum/ocelot_3/prom.c
@@ -239,8 +239,9 @@ void __init prom_init(void)
#endif
}
-void __init prom_free_prom_memory(void)
+unsigned long __init prom_free_prom_memory(void)
{
+ return 0;
}
void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
diff --git a/arch/mips/momentum/ocelot_3/setup.c b/arch/mips/momentum/ocelot_3/setup.c
index ce2efcbab7aa..a7803e08f9db 100644
--- a/arch/mips/momentum/ocelot_3/setup.c
+++ b/arch/mips/momentum/ocelot_3/setup.c
@@ -307,7 +307,7 @@ static __init int __init ja_pci_init(void)
arch_initcall(ja_pci_init);
-static int __init momenco_ocelot_3_setup(void)
+void __init plat_setup(void)
{
unsigned int tmpword;
@@ -391,8 +391,4 @@ static int __init momenco_ocelot_3_setup(void)
/* Support for 128 MB memory */
add_memory_region(0x0, 0x08000000, BOOT_MEM_RAM);
-
- return 0;
}
-
-early_initcall(momenco_ocelot_3_setup);
diff --git a/arch/mips/momentum/ocelot_c/cpci-irq.c b/arch/mips/momentum/ocelot_c/cpci-irq.c
index dea48b3ad687..bd885785e2f9 100644
--- a/arch/mips/momentum/ocelot_c/cpci-irq.c
+++ b/arch/mips/momentum/ocelot_c/cpci-irq.c
@@ -129,14 +129,13 @@ void ll_cpci_irq(struct pt_regs *regs)
#define shutdown_cpci_irq disable_cpci_irq
struct hw_interrupt_type cpci_irq_type = {
- "CPCI/FPGA",
- startup_cpci_irq,
- shutdown_cpci_irq,
- enable_cpci_irq,
- disable_cpci_irq,
- mask_and_ack_cpci_irq,
- end_cpci_irq,
- NULL
+ .typename = "CPCI/FPGA",
+ .startup = startup_cpci_irq,
+ .shutdown = shutdown_cpci_irq,
+ .enable = enable_cpci_irq,
+ .disable = disable_cpci_irq,
+ .ack = mask_and_ack_cpci_irq,
+ .end = end_cpci_irq,
};
void cpci_irq_init(void)
diff --git a/arch/mips/momentum/ocelot_c/setup.c b/arch/mips/momentum/ocelot_c/setup.c
index 844ddd06349b..ce70fc96f160 100644
--- a/arch/mips/momentum/ocelot_c/setup.c
+++ b/arch/mips/momentum/ocelot_c/setup.c
@@ -222,7 +222,7 @@ void momenco_time_init(void)
rtc_set_time = m48t37y_set_time;
}
-static void __init momenco_ocelot_c_setup(void)
+void __init plat_setup(void)
{
unsigned int tmpword;
@@ -340,8 +340,6 @@ static void __init momenco_ocelot_c_setup(void)
}
}
-early_initcall(momenco_ocelot_c_setup);
-
#ifndef CONFIG_64BIT
/* This needs to be one of the first initcalls, because no I/O port access
can work before this */
diff --git a/arch/mips/momentum/ocelot_c/uart-irq.c b/arch/mips/momentum/ocelot_c/uart-irq.c
index ebe1507b17df..755bde5146be 100644
--- a/arch/mips/momentum/ocelot_c/uart-irq.c
+++ b/arch/mips/momentum/ocelot_c/uart-irq.c
@@ -122,14 +122,13 @@ void ll_uart_irq(struct pt_regs *regs)
#define shutdown_uart_irq disable_uart_irq
struct hw_interrupt_type uart_irq_type = {
- "UART/FPGA",
- startup_uart_irq,
- shutdown_uart_irq,
- enable_uart_irq,
- disable_uart_irq,
- mask_and_ack_uart_irq,
- end_uart_irq,
- NULL
+ .typename = "UART/FPGA",
+ .startup = startup_uart_irq,
+ .shutdown = shutdown_uart_irq,
+ .enable = enable_uart_irq,
+ .disable = disable_uart_irq,
+ .ack = mask_and_ack_uart_irq,
+ .end = end_uart_irq,
};
void uart_irq_init(void)
diff --git a/arch/mips/momentum/ocelot_g/setup.c b/arch/mips/momentum/ocelot_g/setup.c
index 38a78ab8c830..6336751391c3 100644
--- a/arch/mips/momentum/ocelot_g/setup.c
+++ b/arch/mips/momentum/ocelot_g/setup.c
@@ -160,7 +160,7 @@ static void __init setup_l3cache(unsigned long size)
printk("Done\n");
}
-static int __init momenco_ocelot_g_setup(void)
+void __init plat_setup(void)
{
void (*l3func)(unsigned long) = (void *) KSEG1ADDR(setup_l3cache);
unsigned int tmpword;
@@ -240,12 +240,8 @@ static int __init momenco_ocelot_g_setup(void)
/* FIXME: Fix up the DiskOnChip mapping */
MV_WRITE(0x468, 0xfef73);
-
- return 0;
}
-early_initcall(momenco_ocelot_g_setup);
-
/* This needs to be one of the first initcalls, because no I/O port access
can work before this */
diff --git a/arch/mips/oprofile/Kconfig b/arch/mips/oprofile/Kconfig
index 19d37730b664..55feaf798596 100644
--- a/arch/mips/oprofile/Kconfig
+++ b/arch/mips/oprofile/Kconfig
@@ -11,7 +11,7 @@ config PROFILING
config OPROFILE
tristate "OProfile system profiling (EXPERIMENTAL)"
- depends on PROFILING
+ depends on PROFILING && EXPERIMENTAL
help
OProfile is a profiling system capable of profiling the
whole system, include the kernel, kernel modules, libraries,
diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c
index ab65ce3d471a..dd2cc42f1b6d 100644
--- a/arch/mips/oprofile/common.c
+++ b/arch/mips/oprofile/common.c
@@ -3,7 +3,8 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 2004 by Ralf Baechle
+ * Copyright (C) 2004, 2005 Ralf Baechle
+ * Copyright (C) 2005 MIPS Technologies, Inc.
*/
#include <linux/errno.h>
#include <linux/init.h>
@@ -45,10 +46,10 @@ static int op_mips_create_files(struct super_block * sb, struct dentry * root)
oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
- /* Dummies. */
oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
oprofilefs_create_ulong(sb, dir, "exl", &ctr[i].exl);
+ /* Dummy. */
oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
}
@@ -68,9 +69,10 @@ static void op_mips_stop(void)
on_each_cpu(model->cpu_stop, NULL, 0, 1);
}
-void __init oprofile_arch_init(struct oprofile_operations *ops)
+int __init oprofile_arch_init(struct oprofile_operations *ops)
{
struct op_mips_model *lmodel = NULL;
+ int res;
switch (current_cpu_data.cputype) {
case CPU_24K:
@@ -83,21 +85,25 @@ void __init oprofile_arch_init(struct oprofile_operations *ops)
};
if (!lmodel)
- return;
+ return -ENODEV;
- if (lmodel->init())
- return;
+ res = lmodel->init();
+ if (res)
+ return res;
model = lmodel;
- ops->create_files = op_mips_create_files;
- ops->setup = op_mips_setup;
- ops->start = op_mips_start;
- ops->stop = op_mips_stop;
- ops->cpu_type = lmodel->cpu_type;
+ ops->create_files = op_mips_create_files;
+ ops->setup = op_mips_setup;
+ //ops->shutdown = op_mips_shutdown;
+ ops->start = op_mips_start;
+ ops->stop = op_mips_stop;
+ ops->cpu_type = lmodel->cpu_type;
printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
lmodel->cpu_type);
+
+ return 0;
}
void oprofile_arch_exit(void)
diff --git a/arch/mips/oprofile/op_impl.h b/arch/mips/oprofile/op_impl.h
index 9f5cdff041be..f0121557047d 100644
--- a/arch/mips/oprofile/op_impl.h
+++ b/arch/mips/oprofile/op_impl.h
@@ -10,6 +10,11 @@
#ifndef OP_IMPL_H
#define OP_IMPL_H 1
+struct pt_regs;
+
+extern void null_perf_irq(struct pt_regs *regs);
+extern void (*perf_irq)(struct pt_regs *regs);
+
/* Per-counter configuration as set via oprofilefs. */
struct op_counter_config {
unsigned long enabled;
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c
new file mode 100644
index 000000000000..d36b64dfcb2f
--- /dev/null
+++ b/arch/mips/oprofile/op_model_mipsxx.c
@@ -0,0 +1,215 @@
+/*
+ * 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, 2005 by Ralf Baechle
+ * Copyright (C) 2005 by MIPS Technologies, Inc.
+ */
+#include <linux/oprofile.h>
+#include <linux/interrupt.h>
+#include <linux/smp.h>
+
+#include "op_impl.h"
+
+#define M_PERFCTL_EXL (1UL << 0)
+#define M_PERFCTL_KERNEL (1UL << 1)
+#define M_PERFCTL_SUPERVISOR (1UL << 2)
+#define M_PERFCTL_USER (1UL << 3)
+#define M_PERFCTL_INTERRUPT_ENABLE (1UL << 4)
+#define M_PERFCTL_EVENT(event) ((event) << 5)
+#define M_PERFCTL_WIDE (1UL << 30)
+#define M_PERFCTL_MORE (1UL << 31)
+
+#define M_COUNTER_OVERFLOW (1UL << 31)
+
+struct op_mips_model op_model_mipsxx;
+
+static struct mipsxx_register_config {
+ unsigned int control[4];
+ unsigned int counter[4];
+} reg;
+
+/* Compute all of the registers in preparation for enabling profiling. */
+
+static void mipsxx_reg_setup(struct op_counter_config *ctr)
+{
+ unsigned int counters = op_model_mipsxx.num_counters;
+ int i;
+
+ /* Compute the performance counter control word. */
+ /* For now count kernel and user mode */
+ for (i = 0; i < counters; i++) {
+ reg.control[i] = 0;
+ reg.counter[i] = 0;
+
+ if (!ctr[i].enabled)
+ continue;
+
+ reg.control[i] = M_PERFCTL_EVENT(ctr[i].event) |
+ M_PERFCTL_INTERRUPT_ENABLE;
+ if (ctr[i].kernel)
+ reg.control[i] |= M_PERFCTL_KERNEL;
+ if (ctr[i].user)
+ reg.control[i] |= M_PERFCTL_USER;
+ if (ctr[i].exl)
+ reg.control[i] |= M_PERFCTL_EXL;
+ reg.counter[i] = 0x80000000 - ctr[i].count;
+ }
+}
+
+/* Program all of the registers in preparation for enabling profiling. */
+
+static void mipsxx_cpu_setup (void *args)
+{
+ unsigned int counters = op_model_mipsxx.num_counters;
+
+ switch (counters) {
+ case 4:
+ write_c0_perfctrl3(0);
+ write_c0_perfcntr3(reg.counter[3]);
+ case 3:
+ write_c0_perfctrl2(0);
+ write_c0_perfcntr2(reg.counter[2]);
+ case 2:
+ write_c0_perfctrl1(0);
+ write_c0_perfcntr1(reg.counter[1]);
+ case 1:
+ write_c0_perfctrl0(0);
+ write_c0_perfcntr0(reg.counter[0]);
+ }
+}
+
+/* Start all counters on current CPU */
+static void mipsxx_cpu_start(void *args)
+{
+ unsigned int counters = op_model_mipsxx.num_counters;
+
+ switch (counters) {
+ case 4:
+ write_c0_perfctrl3(reg.control[3]);
+ case 3:
+ write_c0_perfctrl2(reg.control[2]);
+ case 2:
+ write_c0_perfctrl1(reg.control[1]);
+ case 1:
+ write_c0_perfctrl0(reg.control[0]);
+ }
+}
+
+/* Stop all counters on current CPU */
+static void mipsxx_cpu_stop(void *args)
+{
+ unsigned int counters = op_model_mipsxx.num_counters;
+
+ switch (counters) {
+ case 4:
+ write_c0_perfctrl3(0);
+ case 3:
+ write_c0_perfctrl2(0);
+ case 2:
+ write_c0_perfctrl1(0);
+ case 1:
+ write_c0_perfctrl0(0);
+ }
+}
+
+static void mipsxx_perfcount_handler(struct pt_regs *regs)
+{
+ unsigned int counters = op_model_mipsxx.num_counters;
+ unsigned int control;
+ unsigned int counter;
+
+ switch (counters) {
+#define HANDLE_COUNTER(n) \
+ case n + 1: \
+ control = read_c0_perfctrl ## n(); \
+ counter = read_c0_perfcntr ## n(); \
+ if ((control & M_PERFCTL_INTERRUPT_ENABLE) && \
+ (counter & M_COUNTER_OVERFLOW)) { \
+ oprofile_add_sample(regs, n); \
+ write_c0_perfcntr ## n(reg.counter[n]); \
+ }
+ HANDLE_COUNTER(3)
+ HANDLE_COUNTER(2)
+ HANDLE_COUNTER(1)
+ HANDLE_COUNTER(0)
+ }
+}
+
+#define M_CONFIG1_PC (1 << 4)
+
+static inline int n_counters(void)
+{
+ if (!(read_c0_config1() & M_CONFIG1_PC))
+ return 0;
+ if (!(read_c0_perfctrl0() & M_PERFCTL_MORE))
+ return 1;
+ if (!(read_c0_perfctrl1() & M_PERFCTL_MORE))
+ return 2;
+ if (!(read_c0_perfctrl2() & M_PERFCTL_MORE))
+ return 3;
+
+ return 4;
+}
+
+static inline void reset_counters(int counters)
+{
+ switch (counters) {
+ case 4:
+ write_c0_perfctrl3(0);
+ write_c0_perfcntr3(0);
+ case 3:
+ write_c0_perfctrl2(0);
+ write_c0_perfcntr2(0);
+ case 2:
+ write_c0_perfctrl1(0);
+ write_c0_perfcntr1(0);
+ case 1:
+ write_c0_perfctrl0(0);
+ write_c0_perfcntr0(0);
+ }
+}
+
+static int __init mipsxx_init(void)
+{
+ int counters;
+
+ counters = n_counters();
+ if (counters == 0)
+ return -ENODEV;
+
+ reset_counters(counters);
+
+ op_model_mipsxx.num_counters = counters;
+ switch (current_cpu_data.cputype) {
+ case CPU_24K:
+ op_model_mipsxx.cpu_type = "mips/24K";
+ break;
+
+ default:
+ printk(KERN_ERR "Profiling unsupported for this CPU\n");
+
+ return -ENODEV;
+ }
+
+ perf_irq = mipsxx_perfcount_handler;
+
+ return 0;
+}
+
+static void mipsxx_exit(void)
+{
+ reset_counters(op_model_mipsxx.num_counters);
+
+ perf_irq = null_perf_irq;
+}
+
+struct op_mips_model op_model_mipsxx = {
+ .reg_setup = mipsxx_reg_setup,
+ .cpu_setup = mipsxx_cpu_setup,
+ .init = mipsxx_init,
+ .exit = mipsxx_exit,
+ .cpu_start = mipsxx_cpu_start,
+ .cpu_stop = mipsxx_cpu_stop,
+};
diff --git a/arch/mips/oprofile/op_model_rm9000.c b/arch/mips/oprofile/op_model_rm9000.c
index bee47793cb1a..9b75e41c78ef 100644
--- a/arch/mips/oprofile/op_model_rm9000.c
+++ b/arch/mips/oprofile/op_model_rm9000.c
@@ -5,6 +5,7 @@
*
* Copyright (C) 2004 by Ralf Baechle
*/
+#include <linux/init.h>
#include <linux/oprofile.h>
#include <linux/interrupt.h>
#include <linux/smp.h>
@@ -114,7 +115,7 @@ static irqreturn_t rm9000_perfcount_handler(int irq, void * dev_id,
return IRQ_HANDLED;
}
-static int rm9000_init(void)
+static int __init rm9000_init(void)
{
return request_irq(rm9000_perfcount_irq, rm9000_perfcount_handler,
0, "Perfcounter", NULL);
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
index 83d81c9cdc2b..7b7468304022 100644
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_MIPS_ITE8172) += fixup-ite8172g.o
obj-$(CONFIG_MIPS_IVR) += fixup-ivr.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_MIPS_MALTA) += fixup-malta.o
obj-$(CONFIG_MOMENCO_JAGUAR_ATX)+= fixup-jaguar.o
obj-$(CONFIG_MOMENCO_OCELOT) += fixup-ocelot.o pci-ocelot.o
@@ -45,11 +46,13 @@ obj-$(CONFIG_PMC_YOSEMITE) += fixup-yosemite.o ops-titan.o ops-titan-ht.o \
obj-$(CONFIG_SGI_IP27) += pci-ip27.o
obj-$(CONFIG_SGI_IP32) += fixup-ip32.o ops-mace.o pci-ip32.o
obj-$(CONFIG_SIBYTE_SB1250) += fixup-sb1250.o pci-sb1250.o
+obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1480.o pci-bcm1480ht.o
obj-$(CONFIG_SNI_RM200_PCI) += fixup-sni.o ops-sni.o
obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o
obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o
obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o
obj-$(CONFIG_TOSHIBA_JMR3927) += fixup-jmr3927.o pci-jmr3927.o
obj-$(CONFIG_TOSHIBA_RBTX4927) += fixup-rbtx4927.o ops-tx4927.o
+obj-$(CONFIG_TOSHIBA_RBTX4938) += fixup-tx4938.o ops-tx4938.o
obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o
obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capcella.o
diff --git a/arch/mips/pci/fixup-atlas.c b/arch/mips/pci/fixup-atlas.c
index 2406835833d6..87920b245931 100644
--- a/arch/mips/pci/fixup-atlas.c
+++ b/arch/mips/pci/fixup-atlas.c
@@ -1,14 +1,37 @@
+/*
+ * Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ * Author: Maciej W. Rozycki <macro@mips.com>
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
#include <linux/config.h>
#include <linux/init.h>
#include <linux/pci.h>
+
#include <asm/mips-boards/atlasint.h>
-#define INTD ATLASINT_INTD
-#define INTC ATLASINT_INTC
-#define INTB ATLASINT_INTB
+#define PCIA ATLASINT_PCIA
+#define PCIB ATLASINT_PCIB
+#define PCIC ATLASINT_PCIC
+#define PCID ATLASINT_PCID
#define INTA ATLASINT_INTA
-#define SCSI ATLASINT_SCSI
+#define INTB ATLASINT_INTB
#define ETH ATLASINT_ETH
+#define INTC ATLASINT_INTC
+#define SCSI ATLASINT_SCSI
+#define INTD ATLASINT_INTD
static char irq_tab[][5] __initdata = {
/* INTA INTB INTC INTD */
@@ -27,13 +50,13 @@ static char irq_tab[][5] __initdata = {
{0, 0, 0, 0, 0 }, /* 12: Unused */
{0, 0, 0, 0, 0 }, /* 13: Unused */
{0, 0, 0, 0, 0 }, /* 14: Unused */
- {0, 0, 0, 0, 0 }, /* 15: Unused */
+ {0, PCIA, PCIB, PCIC, PCID }, /* 15: cPCI (behind 21150) */
{0, SCSI, 0, 0, 0 }, /* 16: SYM53C810A SCSI */
{0, 0, 0, 0, 0 }, /* 17: Core */
- {0, INTA, INTB, INTC, INTD }, /* 18: PCI Slot 1 */
- {0, ETH, 0, 0, 0 }, /* 19: SAA9730 Ethernet */
- {0, 0, 0, 0, 0 }, /* 20: PCI Slot 3 */
- {0, 0, 0, 0, 0 } /* 21: PCI Slot 4 */
+ {0, INTA, INTB, INTC, INTD }, /* 18: PCI Slot */
+ {0, ETH, 0, 0, 0 }, /* 19: SAA9730 Eth. et al. */
+ {0, 0, 0, 0, 0 }, /* 20: Unused */
+ {0, 0, 0, 0, 0 } /* 21: Unused */
};
int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
diff --git a/arch/mips/pci/fixup-au1000.c b/arch/mips/pci/fixup-au1000.c
index 39fe2b16fcec..c2f8304fe55b 100644
--- a/arch/mips/pci/fixup-au1000.c
+++ b/arch/mips/pci/fixup-au1000.c
@@ -26,7 +26,6 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/kernel.h>
@@ -34,82 +33,7 @@
#include <asm/mach-au1x00/au1000.h>
-/*
- * Shortcut
- */
-#ifdef CONFIG_SOC_AU1500
-#define INTA AU1000_PCI_INTA
-#define INTB AU1000_PCI_INTB
-#define INTC AU1000_PCI_INTC
-#define INTD AU1000_PCI_INTD
-#endif
-
-#ifdef CONFIG_SOC_AU1550
-#define INTA AU1550_PCI_INTA
-#define INTB AU1550_PCI_INTB
-#define INTC AU1550_PCI_INTC
-#define INTD AU1550_PCI_INTD
-#endif
-
-#define INTX 0xFF /* not valid */
-
-#ifdef CONFIG_MIPS_DB1500
-static char irq_tab_alchemy[][5] __initdata = {
- [12] = { -1, INTA, INTX, INTX, INTX}, /* IDSEL 12 - HPT371 */
- [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot */
-};
-#endif
-
-#ifdef CONFIG_MIPS_BOSPORUS
-static char irq_tab_alchemy[][5] __initdata = {
- [11] = { -1, INTA, INTB, INTX, INTX}, /* IDSEL 11 - miniPCI */
- [12] = { -1, INTA, INTX, INTX, INTX}, /* IDSEL 12 - SN1741 */
- [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot */
-};
-#endif
-
-#ifdef CONFIG_MIPS_MIRAGE
-static char irq_tab_alchemy[][5] __initdata = {
- [11] = { -1, INTD, INTX, INTX, INTX}, /* IDSEL 11 - SMI VGX */
- [12] = { -1, INTX, INTX, INTC, INTX}, /* IDSEL 12 - PNX1300 */
- [13] = { -1, INTA, INTB, INTX, INTX}, /* IDSEL 13 - miniPCI */
-};
-#endif
-
-#ifdef CONFIG_MIPS_DB1550
-static char irq_tab_alchemy[][5] __initdata = {
- [11] = { -1, INTC, INTX, INTX, INTX}, /* IDSEL 11 - on-board HPT371 */
- [12] = { -1, INTB, INTC, INTD, INTA}, /* IDSEL 12 - PCI slot 2 (left) */
- [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot 1 (right) */
-};
-#endif
-
-#ifdef CONFIG_MIPS_PB1500
-static char irq_tab_alchemy[][5] __initdata = {
- [12] = { -1, INTA, INTX, INTX, INTX}, /* IDSEL 12 - HPT370 */
- [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot */
-};
-#endif
-
-#ifdef CONFIG_MIPS_PB1550
-static char irq_tab_alchemy[][5] __initdata = {
- [12] = { -1, INTB, INTC, INTD, INTA}, /* IDSEL 12 - PCI slot 2 (left) */
- [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot 1 (right) */
-};
-#endif
-
-#ifdef CONFIG_MIPS_MTX1
-static char irq_tab_alchemy[][5] __initdata = {
- [0] = { -1, INTA, INTB, INTX, INTX}, /* IDSEL 00 - AdapterA-Slot0 (top) */
- [1] = { -1, INTB, INTA, INTX, INTX}, /* IDSEL 01 - AdapterA-Slot1 (bottom) */
- [2] = { -1, INTC, INTD, INTX, INTX}, /* IDSEL 02 - AdapterB-Slot0 (top) */
- [3] = { -1, INTD, INTC, INTX, INTX}, /* IDSEL 03 - AdapterB-Slot1 (bottom) */
- [4] = { -1, INTA, INTB, INTX, INTX}, /* IDSEL 04 - AdapterC-Slot0 (top) */
- [5] = { -1, INTB, INTA, INTX, INTX}, /* IDSEL 05 - AdapterC-Slot1 (bottom) */
- [6] = { -1, INTC, INTD, INTX, INTX}, /* IDSEL 06 - AdapterD-Slot0 (top) */
- [7] = { -1, INTD, INTC, INTX, INTX}, /* IDSEL 07 - AdapterD-Slot1 (bottom) */
-};
-#endif
+extern char irq_tab_alchemy[][5];
int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
diff --git a/arch/mips/pci/fixup-cobalt.c b/arch/mips/pci/fixup-cobalt.c
index 57e1ca2116bb..909292f50d06 100644
--- a/arch/mips/pci/fixup-cobalt.c
+++ b/arch/mips/pci/fixup-cobalt.c
@@ -21,6 +21,20 @@
extern int cobalt_board_id;
+static void qube_raq_galileo_early_fixup(struct pci_dev *dev)
+{
+ if (dev->devfn == PCI_DEVFN(0, 0) &&
+ (dev->class >> 8) == PCI_CLASS_MEMORY_OTHER) {
+
+ dev->class = (PCI_CLASS_BRIDGE_HOST << 8) | (dev->class & 0xff);
+
+ printk(KERN_INFO "Galileo: fixed bridge class\n");
+ }
+}
+
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_GT64111,
+ qube_raq_galileo_early_fixup);
+
static void qube_raq_via_bmIDE_fixup(struct pci_dev *dev)
{
unsigned short cfgword;
@@ -48,6 +62,9 @@ static void qube_raq_galileo_fixup(struct pci_dev *dev)
{
unsigned short galileo_id;
+ if (dev->devfn != PCI_DEVFN(0, 0))
+ return;
+
/* Fix PCI latency-timer and cache-line-size values in Galileo
* host bridge.
*/
@@ -55,6 +72,13 @@ static void qube_raq_galileo_fixup(struct pci_dev *dev)
pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 7);
/*
+ * The code described by the comment below has been removed
+ * as it causes bus mastering by the Ethernet controllers
+ * to break under any kind of network load. We always set
+ * the retry timeouts to their maximum.
+ *
+ * --x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--
+ *
* On all machines prior to Q2, we had the STOP line disconnected
* from Galileo to VIA on PCI. The new Galileo does not function
* correctly unless we have it connected.
@@ -64,21 +88,43 @@ static void qube_raq_galileo_fixup(struct pci_dev *dev)
*/
pci_read_config_word(dev, PCI_REVISION_ID, &galileo_id);
galileo_id &= 0xff; /* mask off class info */
+
+ printk(KERN_INFO "Galileo: revision %u\n", galileo_id);
+
+#if 0
if (galileo_id >= 0x10) {
/* New Galileo, assumes PCI stop line to VIA is connected. */
GALILEO_OUTL(0x4020, GT_PCI0_TOR_OFS);
- } else if (galileo_id == 0x1 || galileo_id == 0x2) {
+ } else if (galileo_id == 0x1 || galileo_id == 0x2)
+#endif
+ {
signed int timeo;
/* XXX WE MUST DO THIS ELSE GALILEO LOCKS UP! -DaveM */
timeo = GALILEO_INL(GT_PCI0_TOR_OFS);
/* Old Galileo, assumes PCI STOP line to VIA is disconnected. */
- GALILEO_OUTL(0xffff, GT_PCI0_TOR_OFS);
+ GALILEO_OUTL(
+ (0xff << 16) | /* retry count */
+ (0xff << 8) | /* timeout 1 */
+ 0xff, /* timeout 0 */
+ GT_PCI0_TOR_OFS);
+
+ /* enable PCI retry exceeded interrupt */
+ GALILEO_OUTL(GALILEO_INTR_RETRY_CTR | GALILEO_INL(GT_INTRMASK_OFS), GT_INTRMASK_OFS);
}
}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_GALILEO, PCI_ANY_ID,
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_GT64111,
qube_raq_galileo_fixup);
+static char irq_tab_qube1[] __initdata = {
+ [COBALT_PCICONF_CPU] = 0,
+ [COBALT_PCICONF_ETH0] = COBALT_QUBE1_ETH0_IRQ,
+ [COBALT_PCICONF_RAQSCSI] = COBALT_SCSI_IRQ,
+ [COBALT_PCICONF_VIA] = 0,
+ [COBALT_PCICONF_PCISLOT] = COBALT_QUBE_SLOT_IRQ,
+ [COBALT_PCICONF_ETH1] = 0
+};
+
static char irq_tab_cobalt[] __initdata = {
[COBALT_PCICONF_CPU] = 0,
[COBALT_PCICONF_ETH0] = COBALT_ETH0_IRQ,
@@ -99,6 +145,9 @@ static char irq_tab_raq2[] __initdata = {
int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
+ if (cobalt_board_id < COBALT_BRD_ID_QUBE2)
+ return irq_tab_qube1[slot];
+
if (cobalt_board_id == COBALT_BRD_ID_RAQ2)
return irq_tab_raq2[slot];
diff --git a/arch/mips/pci/fixup-pnx8550.c b/arch/mips/pci/fixup-pnx8550.c
new file mode 100644
index 000000000000..4256b3b30b77
--- /dev/null
+++ b/arch/mips/pci/fixup-pnx8550.c
@@ -0,0 +1,57 @@
+/*
+ * Philips PNX8550 pci fixups.
+ *
+ * Copyright 2005 Embedded Alley Solutions, Inc
+ * source@embeddealley.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/mach-pnx8550/pci.h>
+#include <asm/mach-pnx8550/int.h>
+
+
+#undef DEBUG
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+extern char irq_tab_jbs[][5];
+
+void __init pcibios_fixup_resources(struct pci_dev *dev)
+{
+ /* no need to fixup IO resources */
+}
+
+void __init pcibios_fixup(void)
+{
+ /* nothing to do here */
+}
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return irq_tab_jbs[slot][pin];
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
diff --git a/arch/mips/pci/fixup-tx4938.c b/arch/mips/pci/fixup-tx4938.c
new file mode 100644
index 000000000000..f455520ada88
--- /dev/null
+++ b/arch/mips/pci/fixup-tx4938.c
@@ -0,0 +1,92 @@
+/*
+ * Toshiba rbtx4938 pci routines
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/tx4938/rbtx4938.h>
+
+extern struct pci_controller tx4938_pci_controller[];
+
+int pci_get_irq(struct pci_dev *dev, int pin)
+{
+ int irq = pin;
+ u8 slot = PCI_SLOT(dev->devfn);
+ struct pci_controller *controller = (struct pci_controller *)dev->sysdata;
+
+ if (controller == &tx4938_pci_controller[1]) {
+ /* TX4938 PCIC1 */
+ switch (slot) {
+ case TX4938_PCIC_IDSEL_AD_TO_SLOT(31):
+ if (tx4938_ccfgptr->pcfg & TX4938_PCFG_ETH0_SEL)
+ return RBTX4938_IRQ_IRC + TX4938_IR_ETH0;
+ break;
+ case TX4938_PCIC_IDSEL_AD_TO_SLOT(30):
+ if (tx4938_ccfgptr->pcfg & TX4938_PCFG_ETH1_SEL)
+ return RBTX4938_IRQ_IRC + TX4938_IR_ETH1;
+ break;
+ }
+ return 0;
+ }
+
+ /* IRQ rotation */
+ irq--; /* 0-3 */
+ if (dev->bus->parent == NULL &&
+ (slot == TX4938_PCIC_IDSEL_AD_TO_SLOT(23))) {
+ /* PCI CardSlot (IDSEL=A23) */
+ /* PCIA => PCIA (IDSEL=A23) */
+ irq = (irq + 0 + slot) % 4;
+ } else {
+ /* PCI Backplane */
+ irq = (irq + 33 - slot) % 4;
+ }
+ irq++; /* 1-4 */
+
+ switch (irq) {
+ case 1:
+ irq = RBTX4938_IRQ_IOC_PCIA;
+ break;
+ case 2:
+ irq = RBTX4938_IRQ_IOC_PCIB;
+ break;
+ case 3:
+ irq = RBTX4938_IRQ_IOC_PCIC;
+ break;
+ case 4:
+ irq = RBTX4938_IRQ_IOC_PCID;
+ break;
+ }
+ return irq;
+}
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ unsigned char irq = 0;
+
+ irq = pci_get_irq(dev, pin);
+
+ printk(KERN_INFO "PCI: 0x%02x:0x%02x(0x%02x,0x%02x) IRQ=%d\n",
+ dev->bus->number, dev->devfn, PCI_SLOT(dev->devfn),
+ PCI_FUNC(dev->devfn), irq);
+
+ return irq;
+}
+
+/*
+ * Do platform specific device initialization at pci_enable_device() time
+ */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
+
diff --git a/arch/mips/pci/ops-au1000.c b/arch/mips/pci/ops-au1000.c
index c1c91ca0f9c2..be1420126c42 100644
--- a/arch/mips/pci/ops-au1000.c
+++ b/arch/mips/pci/ops-au1000.c
@@ -50,11 +50,6 @@
int (*board_pci_idsel)(unsigned int devsel, int assert);
-/* CP0 hazard avoidance. */
-#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
- "nop; nop; nop; nop;\t" \
- ".set reorder\n\t")
-
void mod_wired_entry(int entry, unsigned long entrylo0,
unsigned long entrylo1, unsigned long entryhi,
unsigned long pagemask)
@@ -66,16 +61,12 @@ void mod_wired_entry(int entry, unsigned long entrylo0,
old_ctx = read_c0_entryhi() & 0xff;
old_pagemask = read_c0_pagemask();
write_c0_index(entry);
- BARRIER;
write_c0_pagemask(pagemask);
write_c0_entryhi(entryhi);
write_c0_entrylo0(entrylo0);
write_c0_entrylo1(entrylo1);
- BARRIER;
tlb_write_indexed();
- BARRIER;
write_c0_entryhi(old_ctx);
- BARRIER;
write_c0_pagemask(old_pagemask);
}
@@ -128,9 +119,8 @@ static int config_access(unsigned char access_type, struct pci_bus *bus,
last_entryLo0 = last_entryLo1 = 0xffffffff;
}
- /* Since the Au1xxx doesn't do the idsel timing exactly to spec,
- * many board vendors implement their own off-chip idsel, so call
- * it now. If it doesn't succeed, may as well bail out at this point.
+ /* Allow board vendors to implement their own off-chip idsel.
+ * If it doesn't succeed, may as well bail out at this point.
*/
if (board_pci_idsel) {
if (board_pci_idsel(device, 1) == 0) {
diff --git a/arch/mips/pci/ops-bonito64.c b/arch/mips/pci/ops-bonito64.c
index 4b4e086a7eb1..dc35270b65a2 100644
--- a/arch/mips/pci/ops-bonito64.c
+++ b/arch/mips/pci/ops-bonito64.c
@@ -1,6 +1,8 @@
/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved.
+ * Copyright (C) 1999, 2000, 2004 MIPS Technologies, Inc.
+ * All rights reserved.
+ * Authors: Carsten Langgaard <carstenl@mips.com>
+ * Maciej W. Rozycki <macro@mips.com>
*
* This program is free software; you can distribute it and/or modify it
* under the terms of the GNU General Public License (Version 2) as
@@ -17,7 +19,6 @@
*
* MIPS boards specific PCI support.
*/
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/kernel.h>
@@ -57,13 +58,6 @@ static int bonito64_pcibios_config_access(unsigned char access_type,
return -1;
}
-#ifdef CONFIG_MIPS_BOARDS_GEN
- if ((busnum == 0) && (PCI_SLOT(devfn) == 17)) {
- /* MIPS Core boards have Bonito connected as device 17 */
- return -1;
- }
-#endif
-
/* Clear cause register bits */
BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR |
BONITO_PCICMD_MTABORT_CLR);
diff --git a/arch/mips/pci/ops-gt64111.c b/arch/mips/pci/ops-gt64111.c
index c5b0fc184c2a..c1807934768d 100644
--- a/arch/mips/pci/ops-gt64111.c
+++ b/arch/mips/pci/ops-gt64111.c
@@ -18,15 +18,15 @@
#include <asm/cobalt/cobalt.h>
/*
- * Accessing device 31 hangs the GT64120. Not sure if this will also hang
- * the GT64111, let's be paranoid for now.
+ * Device 31 on the GT64111 is used to generate PCI special
+ * cycles, so we shouldn't expected to find a device there ...
*/
static inline int pci_range_ck(struct pci_bus *bus, unsigned int devfn)
{
- if (bus->number == 0 && devfn == PCI_DEVFN(31, 0))
- return -1;
+ if (bus->number == 0 && PCI_SLOT(devfn) < 31)
+ return 0;
- return 0;
+ return -1;
}
static int gt64111_pci_read_config(struct pci_bus *bus, unsigned int devfn,
diff --git a/arch/mips/pci/ops-gt64120.c b/arch/mips/pci/ops-gt64120.c
index 7b99dfa33dfc..6335844d607a 100644
--- a/arch/mips/pci/ops-gt64120.c
+++ b/arch/mips/pci/ops-gt64120.c
@@ -1,6 +1,8 @@
/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved.
+ * Copyright (C) 1999, 2000, 2004 MIPS Technologies, Inc.
+ * All rights reserved.
+ * Authors: Carsten Langgaard <carstenl@mips.com>
+ * Maciej W. Rozycki <macro@mips.com>
*
* This program is free software; you can distribute it and/or modify it
* under the terms of the GNU General Public License (Version 2) as
@@ -43,10 +45,6 @@ static int gt64120_pcibios_config_access(unsigned char access_type,
unsigned char busnum = bus->number;
u32 intr;
- if ((busnum == 0) && (PCI_SLOT(devfn) == 0))
- /* Galileo itself is devfn 0, don't move it around */
- return -1;
-
if ((busnum == 0) && (devfn >= PCI_DEVFN(31, 0)))
return -1; /* Because of a bug in the galileo (for slot 31). */
diff --git a/arch/mips/pci/ops-msc.c b/arch/mips/pci/ops-msc.c
index 7bc099643a9d..5d9fbb0f4670 100644
--- a/arch/mips/pci/ops-msc.c
+++ b/arch/mips/pci/ops-msc.c
@@ -21,7 +21,6 @@
* MIPS boards specific PCI support.
*
*/
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/kernel.h>
@@ -49,34 +48,17 @@ static int msc_pcibios_config_access(unsigned char access_type,
struct pci_bus *bus, unsigned int devfn, int where, u32 * data)
{
unsigned char busnum = bus->number;
- unsigned char type;
u32 intr;
-#ifdef CONFIG_MIPS_BOARDS_GEN
- if ((busnum == 0) && (PCI_SLOT(devfn) == 17)) {
- /* MIPS Core boards have SOCit connected as device 17 */
- return -1;
- }
-#endif
-
/* Clear status register bits. */
MSC_WRITE(MSC01_PCI_INTSTAT,
(MSC01_PCI_INTCFG_MA_BIT | MSC01_PCI_INTCFG_TA_BIT));
- /* Setup address */
- if (busnum == 0)
- type = 0; /* Type 0 */
- else
- type = 1; /* Type 1 */
-
MSC_WRITE(MSC01_PCI_CFGADDR,
((busnum << MSC01_PCI_CFGADDR_BNUM_SHF) |
- (PCI_SLOT(devfn) << MSC01_PCI_CFGADDR_DNUM_SHF)
- | (PCI_FUNC(devfn) <<
- MSC01_PCI_CFGADDR_FNUM_SHF) | ((where /
- 4) <<
- MSC01_PCI_CFGADDR_RNUM_SHF)
- | (type)));
+ (PCI_SLOT(devfn) << MSC01_PCI_CFGADDR_DNUM_SHF) |
+ (PCI_FUNC(devfn) << MSC01_PCI_CFGADDR_FNUM_SHF) |
+ ((where / 4) << MSC01_PCI_CFGADDR_RNUM_SHF)));
/* Perform access */
if (access_type == PCI_ACCESS_WRITE)
@@ -86,15 +68,12 @@ static int msc_pcibios_config_access(unsigned char access_type,
/* Detect Master/Target abort */
MSC_READ(MSC01_PCI_INTSTAT, intr);
- if (intr & (MSC01_PCI_INTCFG_MA_BIT |
- MSC01_PCI_INTCFG_TA_BIT)) {
+ if (intr & (MSC01_PCI_INTCFG_MA_BIT | MSC01_PCI_INTCFG_TA_BIT)) {
/* Error occurred */
/* Clear bits */
- MSC_READ(MSC01_PCI_INTSTAT, intr);
MSC_WRITE(MSC01_PCI_INTSTAT,
- (MSC01_PCI_INTCFG_MA_BIT |
- MSC01_PCI_INTCFG_TA_BIT));
+ (MSC01_PCI_INTCFG_MA_BIT | MSC01_PCI_INTCFG_TA_BIT));
return -1;
}
diff --git a/arch/mips/pci/ops-nile4.c b/arch/mips/pci/ops-nile4.c
index a7169928b351..a8d38dc8c504 100644
--- a/arch/mips/pci/ops-nile4.c
+++ b/arch/mips/pci/ops-nile4.c
@@ -15,7 +15,7 @@
volatile unsigned long *const vrc_pciregs = (void *) Vrc5074_BASE;
-static spinlock_t nile4_pci_lock;
+static DEFINE_SPINLOCK(nile4_pci_lock);
static int nile4_pcibios_config_access(unsigned char access_type,
struct pci_bus *bus, unsigned int devfn, int where, u32 * val)
diff --git a/arch/mips/pci/ops-pnx8550.c b/arch/mips/pci/ops-pnx8550.c
new file mode 100644
index 000000000000..454b65cc3354
--- /dev/null
+++ b/arch/mips/pci/ops-pnx8550.c
@@ -0,0 +1,284 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *
+ * 2.6 port, Embedded Alley Solutions, Inc
+ *
+ * Based on:
+ * Author: source@mvista.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+
+#include <asm/mach-pnx8550/pci.h>
+#include <asm/mach-pnx8550/glb.h>
+#include <asm/debug.h>
+
+
+static inline void clear_status(void)
+{
+ unsigned long pci_stat;
+
+ pci_stat = inl(PCI_BASE | PCI_GPPM_STATUS);
+ outl(pci_stat, PCI_BASE | PCI_GPPM_ICLR);
+}
+
+static inline unsigned int
+calc_cfg_addr(struct pci_bus *bus, unsigned int devfn, int where)
+{
+ unsigned int addr;
+
+ addr = ((bus->number > 0) ? (((bus->number & 0xff) << PCI_CFG_BUS_SHIFT) | 1) : 0);
+ addr |= ((devfn & 0xff) << PCI_CFG_FUNC_SHIFT) | (where & 0xfc);
+
+ return addr;
+}
+
+static int
+config_access(unsigned int pci_cmd, struct pci_bus *bus, unsigned int devfn, int where, unsigned int pci_mode, unsigned int *val)
+{
+ unsigned int flags;
+ unsigned long loops = 0;
+ unsigned long ioaddr = calc_cfg_addr(bus, devfn, where);
+
+ local_irq_save(flags);
+ /*Clear pending interrupt status */
+ if (inl(PCI_BASE | PCI_GPPM_STATUS)) {
+ clear_status();
+ while (!(inl(PCI_BASE | PCI_GPPM_STATUS) == 0)) ;
+ }
+
+ outl(ioaddr, PCI_BASE | PCI_GPPM_ADDR);
+
+ if ((pci_cmd == PCI_CMD_IOW) || (pci_cmd == PCI_CMD_CONFIG_WRITE))
+ outl(*val, PCI_BASE | PCI_GPPM_WDAT);
+
+ outl(INIT_PCI_CYCLE | pci_cmd | (pci_mode & PCI_BYTE_ENABLE_MASK),
+ PCI_BASE | PCI_GPPM_CTRL);
+
+ loops =
+ ((loops_per_jiffy *
+ PCI_IO_JIFFIES_TIMEOUT) >> (PCI_IO_JIFFIES_SHIFT));
+ while (1) {
+ if (inl(PCI_BASE | PCI_GPPM_STATUS) & GPPM_DONE) {
+ if ((pci_cmd == PCI_CMD_IOR) ||
+ (pci_cmd == PCI_CMD_CONFIG_READ))
+ *val = inl(PCI_BASE | PCI_GPPM_RDAT);
+ clear_status();
+ local_irq_restore(flags);
+ return PCIBIOS_SUCCESSFUL;
+ } else if (inl(PCI_BASE | PCI_GPPM_STATUS) & GPPM_R_MABORT) {
+ break;
+ }
+
+ loops--;
+ if (loops == 0) {
+ printk("%s : Arbiter Locked.\n", __FUNCTION__);
+ }
+ }
+
+ clear_status();
+ if ((pci_cmd == PCI_CMD_IOR) || (pci_cmd == PCI_CMD_IOW)) {
+ printk("%s timeout (GPPM_CTRL=%X) ioaddr %lX pci_cmd %X\n",
+ __FUNCTION__, inl(PCI_BASE | PCI_GPPM_CTRL), ioaddr,
+ pci_cmd);
+ }
+
+ if ((pci_cmd == PCI_CMD_IOR) || (pci_cmd == PCI_CMD_CONFIG_READ))
+ *val = 0xffffffff;
+ local_irq_restore(flags);
+ return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+/*
+ * We can't address 8 and 16 bit words directly. Instead we have to
+ * read/write a 32bit word and mask/modify the data we actually want.
+ */
+static int
+read_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 * val)
+{
+ unsigned int data = 0;
+ int err;
+
+ if (bus == 0)
+ return -1;
+
+ err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, ~(1 << (where & 3)), &data);
+ switch (where & 0x03) {
+ case 0:
+ *val = (unsigned char)(data & 0x000000ff);
+ break;
+ case 1:
+ *val = (unsigned char)((data & 0x0000ff00) >> 8);
+ break;
+ case 2:
+ *val = (unsigned char)((data & 0x00ff0000) >> 16);
+ break;
+ case 3:
+ *val = (unsigned char)((data & 0xff000000) >> 24);
+ break;
+ }
+
+ return err;
+}
+
+static int
+read_config_word(struct pci_bus *bus, unsigned int devfn, int where, u16 * val)
+{
+ unsigned int data = 0;
+ int err;
+
+ if (bus == 0)
+ return -1;
+
+ if (where & 0x01)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, ~(3 << (where & 3)), &data);
+ switch (where & 0x02) {
+ case 0:
+ *val = (unsigned short)(data & 0x0000ffff);
+ break;
+ case 2:
+ *val = (unsigned short)((data & 0xffff0000) >> 16);
+ break;
+ }
+
+ return err;
+}
+
+static int
+read_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 * val)
+{
+ int err;
+ if (bus == 0)
+ return -1;
+
+ if (where & 0x03)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, 0, val);
+
+ return err;
+}
+
+static int
+write_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 val)
+{
+ unsigned int data = (unsigned int)val;
+ int err;
+
+ if (bus == 0)
+ return -1;
+
+ switch (where & 0x03) {
+ case 1:
+ data = (data << 8);
+ break;
+ case 2:
+ data = (data << 16);
+ break;
+ case 3:
+ data = (data << 24);
+ break;
+ default:
+ break;
+ }
+
+ err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, ~(1 << (where & 3)), &data);
+
+ return err;
+}
+
+static int
+write_config_word(struct pci_bus *bus, unsigned int devfn, int where, u16 val)
+{
+ unsigned int data = (unsigned int)val;
+ int err;
+
+ if (bus == 0)
+ return -1;
+
+ if (where & 0x01)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ switch (where & 0x02) {
+ case 2:
+ data = (data << 16);
+ break;
+ default:
+ break;
+ }
+ err = config_access(PCI_CMD_CONFIG_WRITE, bus, devfn, where, ~(3 << (where & 3)), &data);
+
+ return err;
+}
+
+static int
+write_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 val)
+{
+ int err;
+ if (bus == 0)
+ return -1;
+
+ if (where & 0x03)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ err = config_access(PCI_CMD_CONFIG_WRITE, bus, devfn, where, 0, &val);
+
+ return err;
+}
+
+static int config_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val)
+{
+ switch (size) {
+ case 1: {
+ u8 _val;
+ int rc = read_config_byte(bus, devfn, where, &_val);
+ *val = _val;
+ return rc;
+ }
+ case 2: {
+ u16 _val;
+ int rc = read_config_word(bus, devfn, where, &_val);
+ *val = _val;
+ return rc;
+ }
+ default:
+ return read_config_dword(bus, devfn, where, val);
+ }
+}
+
+static int config_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
+{
+ switch (size) {
+ case 1:
+ return write_config_byte(bus, devfn, where, (u8) val);
+ case 2:
+ return write_config_word(bus, devfn, where, (u16) val);
+ default:
+ return write_config_dword(bus, devfn, where, val);
+ }
+}
+
+struct pci_ops pnx8550_pci_ops = {
+ config_read,
+ config_write
+};
diff --git a/arch/mips/pci/ops-tx4938.c b/arch/mips/pci/ops-tx4938.c
new file mode 100644
index 000000000000..4c0dcfce5297
--- /dev/null
+++ b/arch/mips/pci/ops-tx4938.c
@@ -0,0 +1,198 @@
+/*
+ * Define the pci_ops for the Toshiba rbtx4938
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/addrspace.h>
+#include <asm/tx4938/rbtx4938.h>
+
+/* initialize in setup */
+struct resource pci_io_resource = {
+ .name = "pci IO space",
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_IO
+};
+
+/* initialize in setup */
+struct resource pci_mem_resource = {
+ .name = "pci memory space",
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_MEM
+};
+
+struct resource tx4938_pcic1_pci_io_resource = {
+ .name = "PCI1 IO",
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_IO
+};
+struct resource tx4938_pcic1_pci_mem_resource = {
+ .name = "PCI1 mem",
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_MEM
+};
+
+static int mkaddr(int bus, int dev_fn, int where, int *flagsp)
+{
+ if (bus > 0) {
+ /* Type 1 configuration */
+ tx4938_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
+ ((dev_fn & 0xff) << 0x08) | (where & 0xfc) | 1;
+ } else {
+ if (dev_fn >= PCI_DEVFN(TX4938_PCIC_MAX_DEVNU, 0))
+ return -1;
+
+ /* Type 0 configuration */
+ tx4938_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
+ ((dev_fn & 0xff) << 0x08) | (where & 0xfc);
+ }
+ /* clear M_ABORT and Disable M_ABORT Int. */
+ tx4938_pcicptr->pcistatus =
+ (tx4938_pcicptr->pcistatus & 0x0000ffff) |
+ (PCI_STATUS_REC_MASTER_ABORT << 16);
+ tx4938_pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT;
+
+ return 0;
+}
+
+static int check_abort(int flags)
+{
+ int code = PCIBIOS_SUCCESSFUL;
+ /* wait write cycle completion before checking error status */
+ while (tx4938_pcicptr->pcicstatus & TX4938_PCIC_PCICSTATUS_IWB)
+ ;
+ if (tx4938_pcicptr->pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) {
+ tx4938_pcicptr->pcistatus =
+ (tx4938_pcicptr->
+ pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT
+ << 16);
+ tx4938_pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT;
+ code = PCIBIOS_DEVICE_NOT_FOUND;
+ }
+ return code;
+}
+
+static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 * val)
+{
+ int flags, retval, dev, busno, func;
+
+ dev = PCI_SLOT(devfn);
+ func = PCI_FUNC(devfn);
+
+ /* check if the bus is top-level */
+ if (bus->parent != NULL)
+ busno = bus->number;
+ else {
+ busno = 0;
+ }
+
+ if (mkaddr(busno, devfn, where, &flags))
+ return -1;
+
+ switch (size) {
+ case 1:
+ *val = *(volatile u8 *) ((ulong) & tx4938_pcicptr->g2pcfgdata |
+#ifdef __BIG_ENDIAN
+ ((where & 3) ^ 3));
+#else
+ (where & 3));
+#endif
+ break;
+ case 2:
+ *val = *(volatile u16 *) ((ulong) & tx4938_pcicptr->g2pcfgdata |
+#ifdef __BIG_ENDIAN
+ ((where & 3) ^ 2));
+#else
+ (where & 3));
+#endif
+ break;
+ case 4:
+ *val = tx4938_pcicptr->g2pcfgdata;
+ break;
+ }
+
+ retval = check_abort(flags);
+ if (retval == PCIBIOS_DEVICE_NOT_FOUND)
+ *val = 0xffffffff;
+
+ return retval;
+}
+
+static int tx4938_pcibios_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 val)
+{
+ int flags, dev, busno, func;
+
+ busno = bus->number;
+ dev = PCI_SLOT(devfn);
+ func = PCI_FUNC(devfn);
+
+ /* check if the bus is top-level */
+ if (bus->parent != NULL) {
+ busno = bus->number;
+ } else {
+ busno = 0;
+ }
+
+ if (mkaddr(busno, devfn, where, &flags))
+ return -1;
+
+ switch (size) {
+ case 1:
+ *(volatile u8 *) ((ulong) & tx4938_pcicptr->g2pcfgdata |
+#ifdef __BIG_ENDIAN
+ ((where & 3) ^ 3)) = val;
+#else
+ (where & 3)) = val;
+#endif
+ break;
+ case 2:
+ *(volatile u16 *) ((ulong) & tx4938_pcicptr->g2pcfgdata |
+#ifdef __BIG_ENDIAN
+ ((where & 0x3) ^ 0x2)) = val;
+#else
+ (where & 3)) = val;
+#endif
+ break;
+ case 4:
+ tx4938_pcicptr->g2pcfgdata = val;
+ break;
+ }
+
+ return check_abort(flags);
+}
+
+struct pci_ops tx4938_pci_ops = {
+ tx4938_pcibios_read_config,
+ tx4938_pcibios_write_config
+};
+
+struct pci_controller tx4938_pci_controller[] = {
+ /* h/w only supports devices 0x00 to 0x14 */
+ {
+ .pci_ops = &tx4938_pci_ops,
+ .io_resource = &pci_io_resource,
+ .mem_resource = &pci_mem_resource,
+ },
+ /* h/w only supports devices 0x00 to 0x14 */
+ {
+ .pci_ops = &tx4938_pci_ops,
+ .io_resource = &tx4938_pcic1_pci_io_resource,
+ .mem_resource = &tx4938_pcic1_pci_mem_resource,
+ }
+};
diff --git a/arch/mips/pci/pci-bcm1480.c b/arch/mips/pci/pci-bcm1480.c
new file mode 100644
index 000000000000..f194b4e4f86a
--- /dev/null
+++ b/arch/mips/pci/pci-bcm1480.c
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2001,2002,2005 Broadcom Corporation
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * BCM1x80/1x55-specific PCI support
+ *
+ * This module provides the glue between Linux's PCI subsystem
+ * and the hardware. We basically provide glue for accessing
+ * configuration space, and set up the translation for I/O
+ * space accesses.
+ *
+ * To access configuration space, we use ioremap. In the 32-bit
+ * kernel, this consumes either 4 or 8 page table pages, and 16MB of
+ * kernel mapped memory. Hopefully neither of these should be a huge
+ * problem.
+ *
+ * XXX: AT THIS TIME, ONLY the NATIVE PCI-X INTERFACE IS SUPPORTED.
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/tty.h>
+
+#include <asm/sibyte/bcm1480_regs.h>
+#include <asm/sibyte/bcm1480_scd.h>
+#include <asm/sibyte/board.h>
+#include <asm/io.h>
+
+/*
+ * Macros for calculating offsets into config space given a device
+ * structure or dev/fun/reg
+ */
+#define CFGOFFSET(bus,devfn,where) (((bus)<<16)+((devfn)<<8)+(where))
+#define CFGADDR(bus,devfn,where) CFGOFFSET((bus)->number,(devfn),where)
+
+static void *cfg_space;
+
+#define PCI_BUS_ENABLED 1
+#define PCI_DEVICE_MODE 2
+
+static int bcm1480_bus_status = 0;
+
+#define PCI_BRIDGE_DEVICE 0
+
+/*
+ * Read/write 32-bit values in config space.
+ */
+static inline u32 READCFG32(u32 addr)
+{
+ return *(u32 *)(cfg_space + (addr&~3));
+}
+
+static inline void WRITECFG32(u32 addr, u32 data)
+{
+ *(u32 *)(cfg_space + (addr & ~3)) = data;
+}
+
+int pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return dev->irq;
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
+
+/*
+ * Some checks before doing config cycles:
+ * In PCI Device Mode, hide everything on bus 0 except the LDT host
+ * bridge. Otherwise, access is controlled by bridge MasterEn bits.
+ */
+static int bcm1480_pci_can_access(struct pci_bus *bus, int devfn)
+{
+ u32 devno;
+
+ if (!(bcm1480_bus_status & (PCI_BUS_ENABLED | PCI_DEVICE_MODE)))
+ return 0;
+
+ if (bus->number == 0) {
+ devno = PCI_SLOT(devfn);
+ if (bcm1480_bus_status & PCI_DEVICE_MODE)
+ return 0;
+ else
+ return 1;
+ } else
+ return 1;
+}
+
+/*
+ * Read/write access functions for various sizes of values
+ * in config space. Return all 1's for disallowed accesses
+ * for a kludgy but adequate simulation of master aborts.
+ */
+
+static int bcm1480_pcibios_read(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 * val)
+{
+ u32 data = 0;
+
+ if ((size == 2) && (where & 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ else if ((size == 4) && (where & 3))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ if (bcm1480_pci_can_access(bus, devfn))
+ data = READCFG32(CFGADDR(bus, devfn, where));
+ else
+ data = 0xFFFFFFFF;
+
+ if (size == 1)
+ *val = (data >> ((where & 3) << 3)) & 0xff;
+ else if (size == 2)
+ *val = (data >> ((where & 3) << 3)) & 0xffff;
+ else
+ *val = data;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int bcm1480_pcibios_write(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ u32 cfgaddr = CFGADDR(bus, devfn, where);
+ u32 data = 0;
+
+ if ((size == 2) && (where & 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ else if ((size == 4) && (where & 3))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ if (!bcm1480_pci_can_access(bus, devfn))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ data = READCFG32(cfgaddr);
+
+ if (size == 1)
+ data = (data & ~(0xff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ else if (size == 2)
+ data = (data & ~(0xffff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ else
+ data = val;
+
+ WRITECFG32(cfgaddr, data);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops bcm1480_pci_ops = {
+ bcm1480_pcibios_read,
+ bcm1480_pcibios_write,
+};
+
+static struct resource bcm1480_mem_resource = {
+ .name = "BCM1480 PCI MEM",
+ .start = 0x30000000UL,
+ .end = 0x3fffffffUL,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource bcm1480_io_resource = {
+ .name = "BCM1480 PCI I/O",
+ .start = 0x2c000000UL,
+ .end = 0x2dffffffUL,
+ .flags = IORESOURCE_IO,
+};
+
+struct pci_controller bcm1480_controller = {
+ .pci_ops = &bcm1480_pci_ops,
+ .mem_resource = &bcm1480_mem_resource,
+ .io_resource = &bcm1480_io_resource,
+};
+
+
+static int __init bcm1480_pcibios_init(void)
+{
+ uint32_t cmdreg;
+ uint64_t reg;
+ extern int pci_probe_only;
+
+ /* CFE will assign PCI resources */
+ pci_probe_only = 1;
+
+ /* Avoid ISA compat ranges. */
+ PCIBIOS_MIN_IO = 0x00008000UL;
+ PCIBIOS_MIN_MEM = 0x01000000UL;
+
+ /* Set I/O resource limits. - unlimited for now to accomodate HT */
+ ioport_resource.end = 0xffffffffUL;
+ iomem_resource.end = 0xffffffffUL;
+
+ cfg_space = ioremap(A_BCM1480_PHYS_PCI_CFG_MATCH_BITS, 16*1024*1024);
+
+ /*
+ * See if the PCI bus has been configured by the firmware.
+ */
+ reg = *((volatile uint64_t *) IOADDR(A_SCD_SYSTEM_CFG));
+ if (!(reg & M_BCM1480_SYS_PCI_HOST)) {
+ bcm1480_bus_status |= PCI_DEVICE_MODE;
+ } else {
+ cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0),
+ PCI_COMMAND));
+ if (!(cmdreg & PCI_COMMAND_MASTER)) {
+ printk
+ ("PCI: Skipping PCI probe. Bus is not initialized.\n");
+ iounmap(cfg_space);
+ return 1; /* XXX */
+ }
+ bcm1480_bus_status |= PCI_BUS_ENABLED;
+ }
+
+ /* turn on ExpMemEn */
+ cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0), 0x40));
+ printk("PCIFeatureCtrl = %x\n", cmdreg);
+ WRITECFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0), 0x40),
+ cmdreg | 0x10);
+ cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0), 0x40));
+ printk("PCIFeatureCtrl = %x\n", cmdreg);
+
+ /*
+ * Establish mappings in KSEG2 (kernel virtual) to PCI I/O
+ * space. Use "match bytes" policy to make everything look
+ * little-endian. So, you need to also set
+ * CONFIG_SWAP_IO_SPACE, but this is the combination that
+ * works correctly with most of Linux's drivers.
+ * XXX ehs: Should this happen in PCI Device mode?
+ */
+
+ set_io_port_base((unsigned long)
+ ioremap(A_BCM1480_PHYS_PCI_IO_MATCH_BYTES, 65536));
+ isa_slot_offset = (unsigned long)
+ ioremap(A_BCM1480_PHYS_PCI_MEM_MATCH_BYTES, 1024*1024);
+
+ register_pci_controller(&bcm1480_controller);
+
+#ifdef CONFIG_VGA_CONSOLE
+ take_over_console(&vga_con,0,MAX_NR_CONSOLES-1,1);
+#endif
+ return 0;
+}
+
+arch_initcall(bcm1480_pcibios_init);
diff --git a/arch/mips/pci/pci-bcm1480ht.c b/arch/mips/pci/pci-bcm1480ht.c
new file mode 100644
index 000000000000..aca4a2e7a1c6
--- /dev/null
+++ b/arch/mips/pci/pci-bcm1480ht.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2001,2002,2005 Broadcom Corporation
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * BCM1480/1455-specific HT support (looking like PCI)
+ *
+ * This module provides the glue between Linux's PCI subsystem
+ * and the hardware. We basically provide glue for accessing
+ * configuration space, and set up the translation for I/O
+ * space accesses.
+ *
+ * To access configuration space, we use ioremap. In the 32-bit
+ * kernel, this consumes either 4 or 8 page table pages, and 16MB of
+ * kernel mapped memory. Hopefully neither of these should be a huge
+ * problem.
+ *
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/tty.h>
+
+#include <asm/sibyte/bcm1480_regs.h>
+#include <asm/sibyte/bcm1480_scd.h>
+#include <asm/sibyte/board.h>
+#include <asm/io.h>
+
+/*
+ * Macros for calculating offsets into config space given a device
+ * structure or dev/fun/reg
+ */
+#define CFGOFFSET(bus,devfn,where) (((bus)<<16)+((devfn)<<8)+(where))
+#define CFGADDR(bus,devfn,where) CFGOFFSET((bus)->number,(devfn),where)
+
+static void *ht_cfg_space;
+
+#define PCI_BUS_ENABLED 1
+#define PCI_DEVICE_MODE 2
+
+static int bcm1480ht_bus_status = 0;
+
+#define PCI_BRIDGE_DEVICE 0
+#define HT_BRIDGE_DEVICE 1
+
+/*
+ * HT's level-sensitive interrupts require EOI, which is generated
+ * through a 4MB memory-mapped region
+ */
+unsigned long ht_eoi_space;
+
+/*
+ * Read/write 32-bit values in config space.
+ */
+static inline u32 READCFG32(u32 addr)
+{
+ return *(u32 *)(ht_cfg_space + (addr&~3));
+}
+
+static inline void WRITECFG32(u32 addr, u32 data)
+{
+ *(u32 *)(ht_cfg_space + (addr & ~3)) = data;
+}
+
+/*
+ * Some checks before doing config cycles:
+ * In PCI Device Mode, hide everything on bus 0 except the LDT host
+ * bridge. Otherwise, access is controlled by bridge MasterEn bits.
+ */
+static int bcm1480ht_can_access(struct pci_bus *bus, int devfn)
+{
+ u32 devno;
+
+ if (!(bcm1480ht_bus_status & (PCI_BUS_ENABLED | PCI_DEVICE_MODE)))
+ return 0;
+
+ if (bus->number == 0) {
+ devno = PCI_SLOT(devfn);
+ if (bcm1480ht_bus_status & PCI_DEVICE_MODE)
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * Read/write access functions for various sizes of values
+ * in config space. Return all 1's for disallowed accesses
+ * for a kludgy but adequate simulation of master aborts.
+ */
+
+static int bcm1480ht_pcibios_read(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 * val)
+{
+ u32 data = 0;
+
+ if ((size == 2) && (where & 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ else if ((size == 4) && (where & 3))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ if (bcm1480ht_can_access(bus, devfn))
+ data = READCFG32(CFGADDR(bus, devfn, where));
+ else
+ data = 0xFFFFFFFF;
+
+ if (size == 1)
+ *val = (data >> ((where & 3) << 3)) & 0xff;
+ else if (size == 2)
+ *val = (data >> ((where & 3) << 3)) & 0xffff;
+ else
+ *val = data;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int bcm1480ht_pcibios_write(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ u32 cfgaddr = CFGADDR(bus, devfn, where);
+ u32 data = 0;
+
+ if ((size == 2) && (where & 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ else if ((size == 4) && (where & 3))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ if (!bcm1480ht_can_access(bus, devfn))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ data = READCFG32(cfgaddr);
+
+ if (size == 1)
+ data = (data & ~(0xff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ else if (size == 2)
+ data = (data & ~(0xffff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ else
+ data = val;
+
+ WRITECFG32(cfgaddr, data);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int bcm1480ht_pcibios_get_busno(void)
+{
+ return 0;
+}
+
+struct pci_ops bcm1480ht_pci_ops = {
+ .read = bcm1480ht_pcibios_read,
+ .write = bcm1480ht_pcibios_write,
+};
+
+static struct resource bcm1480ht_mem_resource = {
+ .name = "BCM1480 HT MEM",
+ .start = 0x40000000UL,
+ .end = 0x5fffffffUL,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource bcm1480ht_io_resource = {
+ .name = "BCM1480 HT I/O",
+ .start = 0x00000000UL,
+ .end = 0x01ffffffUL,
+ .flags = IORESOURCE_IO,
+};
+
+struct pci_controller bcm1480ht_controller = {
+ .pci_ops = &bcm1480ht_pci_ops,
+ .mem_resource = &bcm1480ht_mem_resource,
+ .io_resource = &bcm1480ht_io_resource,
+ .index = 1,
+ .get_busno = bcm1480ht_pcibios_get_busno,
+};
+
+static int __init bcm1480ht_pcibios_init(void)
+{
+ uint32_t cmdreg;
+
+ ht_cfg_space = ioremap(A_BCM1480_PHYS_HT_CFG_MATCH_BITS, 16*1024*1024);
+
+ /*
+ * See if the PCI bus has been configured by the firmware.
+ */
+ cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0),
+ PCI_COMMAND));
+ if (!(cmdreg & PCI_COMMAND_MASTER)) {
+ printk("HT: Skipping HT probe. Bus is not initialized.\n");
+ iounmap(ht_cfg_space);
+ return 1; /* XXX */
+ }
+ bcm1480ht_bus_status |= PCI_BUS_ENABLED;
+
+ ht_eoi_space = (unsigned long)
+ ioremap(A_BCM1480_PHYS_HT_SPECIAL_MATCH_BYTES,
+ 4 * 1024 * 1024);
+
+ register_pci_controller(&bcm1480ht_controller);
+
+ return 0;
+}
+
+arch_initcall(bcm1480ht_pcibios_init);
diff --git a/arch/mips/pci/pci-ip27.c b/arch/mips/pci/pci-ip27.c
index 068e0e508e15..efc96ce99eeb 100644
--- a/arch/mips/pci/pci-ip27.c
+++ b/arch/mips/pci/pci-ip27.c
@@ -485,5 +485,12 @@ static void __init pci_fixup_ioc3(struct pci_dev *d)
pci_disable_swapping(d);
}
+int pcibus_to_node(struct pci_bus *bus)
+{
+ struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
+
+ return bc->nasid;
+}
+
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3,
pci_fixup_ioc3);
diff --git a/arch/mips/pci/pci-ip32.c b/arch/mips/pci/pci-ip32.c
index 000dc6af6cd3..180af89bcb1e 100644
--- a/arch/mips/pci/pci-ip32.c
+++ b/arch/mips/pci/pci-ip32.c
@@ -136,7 +136,9 @@ static int __init mace_init(void)
BUG_ON(request_irq(MACE_PCI_BRIDGE_IRQ, macepci_error, 0,
"MACE PCI error", NULL));
- ioport_resource.end = mace_pci_io_resource.end;
+ iomem_resource = mace_pci_mem_resource;
+ ioport_resource = mace_pci_io_resource;
+
register_pci_controller(&mace_pci_controller);
return 0;
diff --git a/arch/mips/pci/pci-lasat.c b/arch/mips/pci/pci-lasat.c
index ae3cc4b254b5..88fb191ad2eb 100644
--- a/arch/mips/pci/pci-lasat.c
+++ b/arch/mips/pci/pci-lasat.c
@@ -7,12 +7,8 @@
*/
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
#include <asm/bootinfo.h>
extern struct pci_ops nile4_pci_ops;
@@ -20,14 +16,14 @@ extern struct pci_ops gt64120_pci_ops;
static struct resource lasat_pci_mem_resource = {
.name = "LASAT PCI MEM",
.start = 0x18000000,
- .end = 0x19FFFFFF,
+ .end = 0x19ffffff,
.flags = IORESOURCE_MEM,
};
static struct resource lasat_pci_io_resource = {
.name = "LASAT PCI IO",
.start = 0x1a000000,
- .end = 0x1bFFFFFF,
+ .end = 0x1bffffff,
.flags = IORESOURCE_IO,
};
@@ -38,23 +34,25 @@ static struct pci_controller lasat_pci_controller = {
static int __init lasat_pci_setup(void)
{
- printk("PCI: starting\n");
+ printk("PCI: starting\n");
- switch (mips_machtype) {
- case MACH_LASAT_100:
+ switch (mips_machtype) {
+ case MACH_LASAT_100:
lasat_pci_controller.pci_ops = &gt64120_pci_ops;
break;
- case MACH_LASAT_200:
+ case MACH_LASAT_200:
lasat_pci_controller.pci_ops = &nile4_pci_ops;
break;
- default:
+ default:
panic("pcibios_init: mips_machtype incorrect");
}
register_pci_controller(&lasat_pci_controller);
- return 0;
+
+ return 0;
}
-early_initcall(lasat_pci_setup);
+
+arch_initcall(lasat_pci_setup);
#define LASATINT_ETH1 0
#define LASATINT_ETH0 1
@@ -68,24 +66,22 @@ early_initcall(lasat_pci_setup);
int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
- switch (slot) {
- case 1:
- return LASATINT_PCIA; /* Expansion Module 0 */
- case 2:
- return LASATINT_PCIB; /* Expansion Module 1 */
- case 3:
- return LASATINT_PCIC; /* Expansion Module 2 */
- case 4:
- return LASATINT_ETH1; /* Ethernet 1 (LAN 2) */
- case 5:
- return LASATINT_ETH0; /* Ethernet 0 (LAN 1) */
- case 6:
- return LASATINT_HDC; /* IDE controller */
- default:
- return 0xff; /* Illegal */
- }
+ switch (slot) {
+ case 1:
+ case 2:
+ case 3:
+ return LASATINT_PCIA + (((slot-1) + (pin-1)) % 4);
+ case 4:
+ return LASATINT_ETH1; /* Ethernet 1 (LAN 2) */
+ case 5:
+ return LASATINT_ETH0; /* Ethernet 0 (LAN 1) */
+ case 6:
+ return LASATINT_HDC; /* IDE controller */
+ default:
+ return 0xff; /* Illegal */
+ }
- return -1;
+ return -1;
}
/* Do platform specific device initialization at pci_enable_device() time */
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
index a8d499b0a36f..21402ffd7c98 100644
--- a/arch/mips/pci/pci.c
+++ b/arch/mips/pci/pci.c
@@ -127,15 +127,20 @@ static int __init pcibios_init(void)
if (!hose->iommu)
PCI_DMA_BUS_IS_PHYS = 1;
+ if (hose->get_busno && pci_probe_only)
+ next_busno = (*hose->get_busno)();
+
bus = pci_scan_bus(next_busno, hose->pci_ops, hose);
hose->bus = bus;
hose->need_domain_info = need_domain_info;
- next_busno = bus->subordinate + 1;
- /* Don't allow 8-bit bus number overflow inside the hose -
- reserve some space for bridges. */
- if (next_busno > 224) {
- next_busno = 0;
- need_domain_info = 1;
+ if (bus) {
+ next_busno = bus->subordinate + 1;
+ /* Don't allow 8-bit bus number overflow inside the hose -
+ reserve some space for bridges. */
+ if (next_busno > 224) {
+ next_busno = 0;
+ need_domain_info = 1;
+ }
}
continue;
@@ -164,7 +169,7 @@ static int pcibios_enable_resources(struct pci_dev *dev, int mask)
pci_read_config_word(dev, PCI_COMMAND, &cmd);
old_cmd = cmd;
- for(idx=0; idx<6; idx++) {
+ for (idx=0; idx < PCI_NUM_RESOURCES; idx++) {
/* Only set up the requested stuff */
if (!(mask & (1<<idx)))
continue;
diff --git a/arch/mips/philips/pnx8550/common/Kconfig b/arch/mips/philips/pnx8550/common/Kconfig
new file mode 100644
index 000000000000..072572d173cc
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/Kconfig
@@ -0,0 +1 @@
+# Place holder
diff --git a/arch/mips/philips/pnx8550/common/Makefile b/arch/mips/philips/pnx8550/common/Makefile
new file mode 100644
index 000000000000..6e38f3bc443c
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/Makefile
@@ -0,0 +1,27 @@
+#
+# Per Hallsmark, per.hallsmark@mvista.com
+#
+# ########################################################################
+#
+# This program is free software; you can distribute it and/or modify it
+# under the terms of the GNU General Public License (Version 2) as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# #######################################################################
+#
+# Makefile for the PNX8550 specific kernel interface routines
+# under Linux.
+#
+
+obj-y := setup.o prom.o mipsIRQ.o int.o reset.o time.o proc.o platform.o
+obj-$(CONFIG_PCI) += pci.o
+obj-$(CONFIG_KGDB) += gdb_hook.o
diff --git a/arch/mips/philips/pnx8550/common/gdb_hook.c b/arch/mips/philips/pnx8550/common/gdb_hook.c
new file mode 100644
index 000000000000..ad4624f6d9bc
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/gdb_hook.c
@@ -0,0 +1,109 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * This is the interface to the remote debugger stub.
+ *
+ */
+#include <linux/types.h>
+#include <linux/serial.h>
+#include <linux/serialP.h>
+#include <linux/serial_reg.h>
+#include <linux/serial_ip3106.h>
+
+#include <asm/serial.h>
+#include <asm/io.h>
+
+#include <uart.h>
+
+static struct serial_state rs_table[IP3106_NR_PORTS] = {
+};
+static struct async_struct kdb_port_info = {0};
+
+void rs_kgdb_hook(int tty_no)
+{
+ struct serial_state *ser = &rs_table[tty_no];
+
+ kdb_port_info.state = ser;
+ kdb_port_info.magic = SERIAL_MAGIC;
+ kdb_port_info.port = tty_no;
+ kdb_port_info.flags = ser->flags;
+
+ /*
+ * Clear all interrupts
+ */
+ /* Clear all the transmitter FIFO counters (pointer and status) */
+ ip3106_lcr(UART_BASE, tty_no) |= IP3106_UART_LCR_TX_RST;
+ /* Clear all the receiver FIFO counters (pointer and status) */
+ ip3106_lcr(UART_BASE, tty_no) |= IP3106_UART_LCR_RX_RST;
+ /* Clear all interrupts */
+ ip3106_iclr(UART_BASE, tty_no) = IP3106_UART_INT_ALLRX |
+ IP3106_UART_INT_ALLTX;
+
+ /*
+ * Now, initialize the UART
+ */
+ ip3106_lcr(UART_BASE, tty_no) = IP3106_UART_LCR_8BIT;
+ ip3106_baud(UART_BASE, tty_no) = 5; // 38400 Baud
+}
+
+int putDebugChar(char c)
+{
+ /* Wait until FIFO not full */
+ while (((ip3106_fifo(UART_BASE, kdb_port_info.port) & IP3106_UART_FIFO_TXFIFO) >> 16) >= 16)
+ ;
+ /* Send one char */
+ ip3106_fifo(UART_BASE, kdb_port_info.port) = c;
+
+ return 1;
+}
+
+char getDebugChar(void)
+{
+ char ch;
+
+ /* Wait until there is a char in the FIFO */
+ while (!((ip3106_fifo(UART_BASE, kdb_port_info.port) &
+ IP3106_UART_FIFO_RXFIFO) >> 8))
+ ;
+ /* Read one char */
+ ch = ip3106_fifo(UART_BASE, kdb_port_info.port) &
+ IP3106_UART_FIFO_RBRTHR;
+ /* Advance the RX FIFO read pointer */
+ ip3106_lcr(UART_BASE, kdb_port_info.port) |= IP3106_UART_LCR_RX_NEXT;
+ return (ch);
+}
+
+void rs_disable_debug_interrupts(void)
+{
+ ip3106_ien(UART_BASE, kdb_port_info.port) = 0; /* Disable all interrupts */
+}
+
+void rs_enable_debug_interrupts(void)
+{
+ /* Clear all the transmitter FIFO counters (pointer and status) */
+ ip3106_lcr(UART_BASE, kdb_port_info.port) |= IP3106_UART_LCR_TX_RST;
+ /* Clear all the receiver FIFO counters (pointer and status) */
+ ip3106_lcr(UART_BASE, kdb_port_info.port) |= IP3106_UART_LCR_RX_RST;
+ /* Clear all interrupts */
+ ip3106_iclr(UART_BASE, kdb_port_info.port) = IP3106_UART_INT_ALLRX |
+ IP3106_UART_INT_ALLTX;
+ ip3106_ien(UART_BASE, kdb_port_info.port) = IP3106_UART_INT_ALLRX; /* Enable RX interrupts */
+}
diff --git a/arch/mips/philips/pnx8550/common/int.c b/arch/mips/philips/pnx8550/common/int.c
new file mode 100644
index 000000000000..546144988bf5
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/int.c
@@ -0,0 +1,293 @@
+/*
+ *
+ * Copyright (C) 2005 Embedded Alley Solutions, Inc
+ * Ported to 2.6.
+ *
+ * Per Hallsmark, per.hallsmark@mvista.com
+ * Copyright (C) 2000, 2001 MIPS Technologies, Inc.
+ * Copyright (C) 2001 Ralf Baechle
+ *
+ * Cleaned up and bug fixing: Pete Popov, ppopov@embeddedalley.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/random.h>
+#include <linux/module.h>
+
+#include <asm/io.h>
+#include <asm/gdb-stub.h>
+#include <int.h>
+#include <uart.h>
+
+extern asmlinkage void cp0_irqdispatch(void);
+
+static DEFINE_SPINLOCK(irq_lock);
+
+/* default prio for interrupts */
+/* first one is a no-no so therefore always prio 0 (disabled) */
+static char gic_prio[PNX8550_INT_GIC_TOTINT] = {
+ 0, 1, 1, 1, 1, 15, 1, 1, 1, 1, // 0 - 9
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 10 - 19
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 20 - 29
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 30 - 39
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 40 - 49
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, // 50 - 59
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 60 - 69
+ 1 // 70
+};
+
+void hw0_irqdispatch(int irq, struct pt_regs *regs)
+{
+ /* find out which interrupt */
+ irq = PNX8550_GIC_VECTOR_0 >> 3;
+
+ if (irq == 0) {
+ printk("hw0_irqdispatch: irq 0, spurious interrupt?\n");
+ return;
+ }
+ do_IRQ(PNX8550_INT_GIC_MIN + irq, regs);
+}
+
+
+void timer_irqdispatch(int irq, struct pt_regs *regs)
+{
+ irq = (0x01c0 & read_c0_config7()) >> 6;
+
+ if (irq == 0) {
+ printk("timer_irqdispatch: irq 0, spurious interrupt?\n");
+ return;
+ }
+
+ if (irq & 0x1) {
+ do_IRQ(PNX8550_INT_TIMER1, regs);
+ }
+ if (irq & 0x2) {
+ do_IRQ(PNX8550_INT_TIMER2, regs);
+ }
+ if (irq & 0x4) {
+ do_IRQ(PNX8550_INT_TIMER3, regs);
+ }
+}
+
+static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask)
+{
+ unsigned long status = read_c0_status();
+
+ status &= ~((clr_mask & 0xFF) << 8);
+ status |= (set_mask & 0xFF) << 8;
+
+ write_c0_status(status);
+}
+
+static inline void mask_gic_int(unsigned int irq_nr)
+{
+ /* interrupt disabled, bit 26(WE_ENABLE)=1 and bit 16(enable)=0 */
+ PNX8550_GIC_REQ(irq_nr) = 1<<28; /* set priority to 0 */
+}
+
+static inline void unmask_gic_int(unsigned int irq_nr)
+{
+ /* set prio mask to lower four bits and enable interrupt */
+ PNX8550_GIC_REQ(irq_nr) = (1<<26 | 1<<16) | (1<<28) | gic_prio[irq_nr];
+}
+
+static inline void mask_irq(unsigned int irq_nr)
+{
+ if ((PNX8550_INT_CP0_MIN <= irq_nr) && (irq_nr <= PNX8550_INT_CP0_MAX)) {
+ modify_cp0_intmask(1 << irq_nr, 0);
+ } else if ((PNX8550_INT_GIC_MIN <= irq_nr) &&
+ (irq_nr <= PNX8550_INT_GIC_MAX)) {
+ mask_gic_int(irq_nr - PNX8550_INT_GIC_MIN);
+ } else if ((PNX8550_INT_TIMER_MIN <= irq_nr) &&
+ (irq_nr <= PNX8550_INT_TIMER_MAX)) {
+ modify_cp0_intmask(1 << 7, 0);
+ } else {
+ printk("mask_irq: irq %d doesn't exist!\n", irq_nr);
+ }
+}
+
+static inline void unmask_irq(unsigned int irq_nr)
+{
+ if ((PNX8550_INT_CP0_MIN <= irq_nr) && (irq_nr <= PNX8550_INT_CP0_MAX)) {
+ modify_cp0_intmask(0, 1 << irq_nr);
+ } else if ((PNX8550_INT_GIC_MIN <= irq_nr) &&
+ (irq_nr <= PNX8550_INT_GIC_MAX)) {
+ unmask_gic_int(irq_nr - PNX8550_INT_GIC_MIN);
+ } else if ((PNX8550_INT_TIMER_MIN <= irq_nr) &&
+ (irq_nr <= PNX8550_INT_TIMER_MAX)) {
+ modify_cp0_intmask(0, 1 << 7);
+ } else {
+ printk("mask_irq: irq %d doesn't exist!\n", irq_nr);
+ }
+}
+
+#define pnx8550_disable pnx8550_ack
+static void pnx8550_ack(unsigned int irq)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&irq_lock, flags);
+ mask_irq(irq);
+ spin_unlock_irqrestore(&irq_lock, flags);
+}
+
+#define pnx8550_enable pnx8550_unmask
+static void pnx8550_unmask(unsigned int irq)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&irq_lock, flags);
+ unmask_irq(irq);
+ spin_unlock_irqrestore(&irq_lock, flags);
+}
+
+static unsigned int startup_irq(unsigned int irq_nr)
+{
+ pnx8550_unmask(irq_nr);
+ return 0;
+}
+
+static void shutdown_irq(unsigned int irq_nr)
+{
+ pnx8550_ack(irq_nr);
+ return;
+}
+
+int pnx8550_set_gic_priority(int irq, int priority)
+{
+ int gic_irq = irq-PNX8550_INT_GIC_MIN;
+ int prev_priority = PNX8550_GIC_REQ(gic_irq) & 0xf;
+
+ gic_prio[gic_irq] = priority;
+ PNX8550_GIC_REQ(gic_irq) |= (0x10000000 | gic_prio[gic_irq]);
+
+ return prev_priority;
+}
+
+static inline void mask_and_ack_level_irq(unsigned int irq)
+{
+ pnx8550_disable(irq);
+ return;
+}
+
+static void end_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
+ pnx8550_enable(irq);
+ }
+}
+
+static struct hw_interrupt_type level_irq_type = {
+ .typename = "PNX Level IRQ",
+ .startup = startup_irq,
+ .shutdown = shutdown_irq,
+ .enable = pnx8550_enable,
+ .disable = pnx8550_disable,
+ .ack = mask_and_ack_level_irq,
+ .end = end_irq,
+};
+
+static struct irqaction gic_action = {
+ .handler = no_action,
+ .flags = SA_INTERRUPT,
+ .name = "GIC",
+};
+
+static struct irqaction timer_action = {
+ .handler = no_action,
+ .flags = SA_INTERRUPT,
+ .name = "Timer",
+};
+
+void __init arch_init_irq(void)
+{
+ int i;
+ int configPR;
+
+ /* init of cp0 interrupts */
+ set_except_vector(0, cp0_irqdispatch);
+
+ for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) {
+ irq_desc[i].handler = &level_irq_type;
+ pnx8550_ack(i); /* mask the irq just in case */
+ }
+
+ /* init of GIC/IPC interrupts */
+ /* should be done before cp0 since cp0 init enables the GIC int */
+ for (i = PNX8550_INT_GIC_MIN; i <= PNX8550_INT_GIC_MAX; i++) {
+ int gic_int_line = i - PNX8550_INT_GIC_MIN;
+ if (gic_int_line == 0 )
+ continue; // don't fiddle with int 0
+ /*
+ * enable change of TARGET, ENABLE and ACTIVE_LOW bits
+ * set TARGET 0 to route through hw0 interrupt
+ * set ACTIVE_LOW 0 active high (correct?)
+ *
+ * We really should setup an interrupt description table
+ * to do this nicely.
+ * Note, PCI INTA is active low on the bus, but inverted
+ * in the GIC, so to us it's active high.
+ */
+#ifdef CONFIG_PNX8550_V2PCI
+ if (gic_int_line == (PNX8550_INT_GPIO0 - PNX8550_INT_GIC_MIN)) {
+ /* PCI INT through gpio 8, which is setup in
+ * pnx8550_setup.c and routed to GPIO
+ * Interrupt Level 0 (GPIO Connection 58).
+ * Set it active low. */
+
+ PNX8550_GIC_REQ(gic_int_line) = 0x1E020000;
+ } else
+#endif
+ {
+ PNX8550_GIC_REQ(i - PNX8550_INT_GIC_MIN) = 0x1E000000;
+ }
+
+ /* mask/priority is still 0 so we will not get any
+ * interrupts until it is unmasked */
+
+ irq_desc[i].handler = &level_irq_type;
+ }
+
+ /* Priority level 0 */
+ PNX8550_GIC_PRIMASK_0 = PNX8550_GIC_PRIMASK_1 = 0;
+
+ /* Set int vector table address */
+ PNX8550_GIC_VECTOR_0 = PNX8550_GIC_VECTOR_1 = 0;
+
+ irq_desc[MIPS_CPU_GIC_IRQ].handler = &level_irq_type;
+ setup_irq(MIPS_CPU_GIC_IRQ, &gic_action);
+
+ /* init of Timer interrupts */
+ for (i = PNX8550_INT_TIMER_MIN; i <= PNX8550_INT_TIMER_MAX; i++) {
+ irq_desc[i].handler = &level_irq_type;
+ }
+
+ /* Stop Timer 1-3 */
+ configPR = read_c0_config7();
+ configPR |= 0x00000038;
+ write_c0_config7(configPR);
+
+ irq_desc[MIPS_CPU_TIMER_IRQ].handler = &level_irq_type;
+ setup_irq(MIPS_CPU_TIMER_IRQ, &timer_action);
+}
+
+EXPORT_SYMBOL(pnx8550_set_gic_priority);
diff --git a/arch/mips/philips/pnx8550/common/mipsIRQ.S b/arch/mips/philips/pnx8550/common/mipsIRQ.S
new file mode 100644
index 000000000000..338bffda3fab
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/mipsIRQ.S
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2002 Philips, Inc. All rights.
+ * Copyright (c) 2002 Red Hat, Inc. All rights.
+ *
+ * This software may be freely redistributed under the terms of the
+ * GNU General Public License.
+ *
+ * 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.
+ *
+ * Based upon arch/mips/galileo-boards/ev64240/int-handler.S
+ *
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+/*
+ * cp0_irqdispatch
+ *
+ * Code to handle in-core interrupt exception.
+ */
+
+ .align 5
+ .set reorder
+ .set noat
+ NESTED(cp0_irqdispatch, PT_SIZE, sp)
+ SAVE_ALL
+ CLI
+ .set at
+ mfc0 t0,CP0_CAUSE
+ mfc0 t2,CP0_STATUS
+
+ and t0,t2
+
+ andi t1,t0,STATUSF_IP2 /* int0 hardware line */
+ bnez t1,ll_hw0_irq
+ nop
+
+ andi t1,t0,STATUSF_IP7 /* int5 hardware line */
+ bnez t1,ll_timer_irq
+ nop
+
+ /* wrong alarm or masked ... */
+
+ j spurious_interrupt
+ nop
+ END(cp0_irqdispatch)
+
+ .align 5
+ .set reorder
+ll_hw0_irq:
+ li a0,2
+ move a1,sp
+ jal hw0_irqdispatch
+ nop
+ j ret_from_irq
+ nop
+
+ .align 5
+ .set reorder
+ll_timer_irq:
+ mfc0 t3,CP0_CONFIG,7
+ andi t4,t3,0x01c0
+ beqz t4,ll_timer_out
+ nop
+ li a0,7
+ move a1,sp
+ jal timer_irqdispatch
+ nop
+
+ll_timer_out: j ret_from_irq
+ nop
diff --git a/arch/mips/philips/pnx8550/common/pci.c b/arch/mips/philips/pnx8550/common/pci.c
new file mode 100644
index 000000000000..baa6905f649f
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/pci.c
@@ -0,0 +1,133 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *
+ * Author: source@mvista.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <pci.h>
+#include <glb.h>
+#include <nand.h>
+
+static struct resource pci_io_resource = {
+ "pci IO space",
+ (u32)(PNX8550_PCIIO + 0x1000), /* reserve regacy I/O space */
+ (u32)(PNX8550_PCIIO + PNX8550_PCIIO_SIZE),
+ IORESOURCE_IO
+};
+
+static struct resource pci_mem_resource = {
+ "pci memory space",
+ (u32)(PNX8550_PCIMEM),
+ (u32)(PNX8550_PCIMEM + PNX8550_PCIMEM_SIZE - 1),
+ IORESOURCE_MEM
+};
+
+extern struct pci_ops pnx8550_pci_ops;
+
+static struct pci_controller pnx8550_controller = {
+ .pci_ops = &pnx8550_pci_ops,
+ .io_resource = &pci_io_resource,
+ .mem_resource = &pci_mem_resource,
+};
+
+/* Return the total size of DRAM-memory, (RANK0 + RANK1) */
+static inline unsigned long get_system_mem_size(void)
+{
+ /* Read IP2031_RANK0_ADDR_LO */
+ unsigned long dram_r0_lo = inl(PCI_BASE | 0x65010);
+ /* Read IP2031_RANK1_ADDR_HI */
+ unsigned long dram_r1_hi = inl(PCI_BASE | 0x65018);
+
+ return dram_r1_hi - dram_r0_lo + 1;
+}
+
+static int __init pnx8550_pci_setup(void)
+{
+ int pci_mem_code;
+ int mem_size = get_system_mem_size() >> 20;
+
+ /* Clear the Global 2 Register, PCI Inta Output Enable Registers
+ Bit 1:Enable DAC Powerdown
+ -> 0:DACs are enabled and are working normally
+ 1:DACs are powerdown
+ Bit 0:Enable of PCI inta output
+ -> 0 = Disable PCI inta output
+ 1 = Enable PCI inta output
+ */
+ PNX8550_GLB2_ENAB_INTA_O = 0;
+
+ /* Calc the PCI mem size code */
+ if (mem_size >= 128)
+ pci_mem_code = SIZE_128M;
+ else if (mem_size >= 64)
+ pci_mem_code = SIZE_64M;
+ else if (mem_size >= 32)
+ pci_mem_code = SIZE_32M;
+ else
+ pci_mem_code = SIZE_16M;
+
+ /* Set PCI_XIO registers */
+ outl(pci_mem_resource.start, PCI_BASE | PCI_BASE1_LO);
+ outl(pci_mem_resource.end + 1, PCI_BASE | PCI_BASE1_HI);
+ outl(pci_io_resource.start, PCI_BASE | PCI_BASE2_LO);
+ outl(pci_io_resource.end, PCI_BASE | PCI_BASE2_HI);
+
+ /* Send memory transaction via PCI_BASE2 */
+ outl(0x00000001, PCI_BASE | PCI_IO);
+
+ /* Unlock the setup register */
+ outl(0xca, PCI_BASE | PCI_UNLOCKREG);
+
+ /*
+ * BAR0 of PNX8550 (pci base 10) must be zero in order for ide
+ * to work, and in order for bus_to_baddr to work without any
+ * hacks.
+ */
+ outl(0x00000000, PCI_BASE | PCI_BASE10);
+
+ /*
+ *These two bars are set by default or the boot code.
+ * However, it's safer to set them here so we're not boot
+ * code dependent.
+ */
+ outl(0x1be00000, PCI_BASE | PCI_BASE14); /* PNX MMIO */
+ outl(PNX8550_NAND_BASE_ADDR, PCI_BASE | PCI_BASE18); /* XIO */
+
+ outl(PCI_EN_TA |
+ PCI_EN_PCI2MMI |
+ PCI_EN_XIO |
+ PCI_SETUP_BASE18_SIZE(SIZE_32M) |
+ PCI_SETUP_BASE18_EN |
+ PCI_SETUP_BASE14_EN |
+ PCI_SETUP_BASE10_PREF |
+ PCI_SETUP_BASE10_SIZE(pci_mem_code) |
+ PCI_SETUP_CFGMANAGE_EN |
+ PCI_SETUP_PCIARB_EN,
+ PCI_BASE |
+ PCI_SETUP); /* PCI_SETUP */
+ outl(0x00000000, PCI_BASE | PCI_CTRL); /* PCI_CONTROL */
+
+ register_pci_controller(&pnx8550_controller);
+
+ return 0;
+}
+
+arch_initcall(pnx8550_pci_setup);
diff --git a/arch/mips/philips/pnx8550/common/platform.c b/arch/mips/philips/pnx8550/common/platform.c
new file mode 100644
index 000000000000..8aa9bd65b45e
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/platform.c
@@ -0,0 +1,135 @@
+/*
+ * Platform device support for Philips PNX8550 SoCs
+ *
+ * Copyright 2005, Embedded Alley Solutions, Inc
+ *
+ * Based on arch/mips/au1000/common/platform.c
+ * Platform device support for Au1x00 SoCs.
+ *
+ * Copyright 2004, Matt Porter <mporter@kernel.crashing.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/resource.h>
+#include <linux/serial.h>
+#include <linux/serial_ip3106.h>
+
+#include <int.h>
+#include <usb.h>
+#include <uart.h>
+
+extern struct uart_ops ip3106_pops;
+
+static struct resource pnx8550_usb_ohci_resources[] = {
+ [0] = {
+ .start = PNX8550_USB_OHCI_OP_BASE,
+ .end = PNX8550_USB_OHCI_OP_BASE +
+ PNX8550_USB_OHCI_OP_LEN,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PNX8550_INT_USB,
+ .end = PNX8550_INT_USB,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource pnx8550_uart_resources[] = {
+ [0] = {
+ .start = PNX8550_UART_PORT0,
+ .end = PNX8550_UART_PORT0 + 0xfff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PNX8550_UART_INT(0),
+ .end = PNX8550_UART_INT(0),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = PNX8550_UART_PORT1,
+ .end = PNX8550_UART_PORT1 + 0xfff,
+ .flags = IORESOURCE_MEM,
+ },
+ [3] = {
+ .start = PNX8550_UART_INT(1),
+ .end = PNX8550_UART_INT(1),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct ip3106_port ip3106_ports[] = {
+ [0] = {
+ .port = {
+ .type = PORT_IP3106,
+ .iotype = SERIAL_IO_MEM,
+ .membase = (void __iomem *)PNX8550_UART_PORT0,
+ .mapbase = PNX8550_UART_PORT0,
+ .irq = PNX8550_UART_INT(0),
+ .uartclk = 3692300,
+ .fifosize = 16,
+ .ops = &ip3106_pops,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 0,
+ },
+ },
+ [1] = {
+ .port = {
+ .type = PORT_IP3106,
+ .iotype = SERIAL_IO_MEM,
+ .membase = (void __iomem *)PNX8550_UART_PORT1,
+ .mapbase = PNX8550_UART_PORT1,
+ .irq = PNX8550_UART_INT(1),
+ .uartclk = 3692300,
+ .fifosize = 16,
+ .ops = &ip3106_pops,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 1,
+ },
+ },
+};
+
+/* The dmamask must be set for OHCI to work */
+static u64 ohci_dmamask = ~(u32)0;
+
+static u64 uart_dmamask = ~(u32)0;
+
+static struct platform_device pnx8550_usb_ohci_device = {
+ .name = "pnx8550-ohci",
+ .id = -1,
+ .dev = {
+ .dma_mask = &ohci_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(pnx8550_usb_ohci_resources),
+ .resource = pnx8550_usb_ohci_resources,
+};
+
+static struct platform_device pnx8550_uart_device = {
+ .name = "ip3106-uart",
+ .id = -1,
+ .dev = {
+ .dma_mask = &uart_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = ip3106_ports,
+ },
+ .num_resources = ARRAY_SIZE(pnx8550_uart_resources),
+ .resource = pnx8550_uart_resources,
+};
+
+static struct platform_device *pnx8550_platform_devices[] __initdata = {
+ &pnx8550_usb_ohci_device,
+ &pnx8550_uart_device,
+};
+
+int pnx8550_platform_init(void)
+{
+ return platform_add_devices(pnx8550_platform_devices,
+ ARRAY_SIZE(pnx8550_platform_devices));
+}
+
+arch_initcall(pnx8550_platform_init);
diff --git a/arch/mips/philips/pnx8550/common/proc.c b/arch/mips/philips/pnx8550/common/proc.c
new file mode 100644
index 000000000000..72a016767e09
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/proc.c
@@ -0,0 +1,113 @@
+/*
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/irq.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/random.h>
+
+#include <asm/io.h>
+#include <asm/gdb-stub.h>
+#include <int.h>
+#include <uart.h>
+
+
+static int pnx8550_timers_read (char* page, char** start, off_t offset, int count, int* eof, void* data)
+{
+ int len = 0;
+ int configPR = read_c0_config7();
+
+ if (offset==0) {
+ len += sprintf(&page[len],"Timer: count, compare, tc, status\n");
+ len += sprintf(&page[len]," 1: %11i, %8i, %1i, %s\n",
+ read_c0_count(), read_c0_compare(),
+ (configPR>>6)&0x1, ((configPR>>3)&0x1)? "off":"on");
+ len += sprintf(&page[len]," 2: %11i, %8i, %1i, %s\n",
+ read_c0_count2(), read_c0_compare2(),
+ (configPR>>7)&0x1, ((configPR>>4)&0x1)? "off":"on");
+ len += sprintf(&page[len]," 3: %11i, %8i, %1i, %s\n",
+ read_c0_count3(), read_c0_compare3(),
+ (configPR>>8)&0x1, ((configPR>>5)&0x1)? "off":"on");
+ }
+
+ return len;
+}
+
+static int pnx8550_registers_read (char* page, char** start, off_t offset, int count, int* eof, void* data)
+{
+ int len = 0;
+
+ if (offset==0) {
+ len += sprintf(&page[len],"config1: %#10.8x\n",read_c0_config1());
+ len += sprintf(&page[len],"config2: %#10.8x\n",read_c0_config2());
+ len += sprintf(&page[len],"config3: %#10.8x\n",read_c0_config3());
+ len += sprintf(&page[len],"configPR: %#10.8x\n",read_c0_config7());
+ len += sprintf(&page[len],"status: %#10.8x\n",read_c0_status());
+ len += sprintf(&page[len],"cause: %#10.8x\n",read_c0_cause());
+ len += sprintf(&page[len],"count: %#10.8x\n",read_c0_count());
+ len += sprintf(&page[len],"count_2: %#10.8x\n",read_c0_count2());
+ len += sprintf(&page[len],"count_3: %#10.8x\n",read_c0_count3());
+ len += sprintf(&page[len],"compare: %#10.8x\n",read_c0_compare());
+ len += sprintf(&page[len],"compare_2: %#10.8x\n",read_c0_compare2());
+ len += sprintf(&page[len],"compare_3: %#10.8x\n",read_c0_compare3());
+ }
+
+ 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 int pnx8550_proc_init( void )
+{
+
+ // Create /proc/pnx8550
+ pnx8550_dir = create_proc_entry("pnx8550", S_IFDIR|S_IRUGO, NULL);
+ if (pnx8550_dir){
+ pnx8550_dir->nlink = 1;
+ }
+ else {
+ printk(KERN_ERR "Can't create pnx8550 proc dir\n");
+ return -1;
+ }
+
+ // Create /proc/pnx8550/timers
+ pnx8550_timers = create_proc_entry("timers", S_IFREG|S_IRUGO, pnx8550_dir );
+ if (pnx8550_timers){
+ pnx8550_timers->nlink = 1;
+ pnx8550_timers->read_proc = pnx8550_timers_read;
+ }
+ else {
+ printk(KERN_ERR "Can't create pnx8550 timers proc file\n");
+ }
+
+ // Create /proc/pnx8550/registers
+ pnx8550_registers = create_proc_entry("registers", S_IFREG|S_IRUGO, pnx8550_dir );
+ if (pnx8550_registers){
+ pnx8550_registers->nlink = 1;
+ pnx8550_registers->read_proc = pnx8550_registers_read;
+ }
+ else {
+ printk(KERN_ERR "Can't create pnx8550 registers proc file\n");
+ }
+
+ return 0;
+}
+
+__initcall(pnx8550_proc_init);
diff --git a/arch/mips/philips/pnx8550/common/prom.c b/arch/mips/philips/pnx8550/common/prom.c
new file mode 100644
index 000000000000..70aac9759412
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/prom.c
@@ -0,0 +1,138 @@
+/*
+ *
+ * Per Hallsmark, per.hallsmark@mvista.com
+ *
+ * Based on jmr3927/common/prom.c
+ *
+ * 2004 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/serial_ip3106.h>
+
+#include <asm/bootinfo.h>
+#include <uart.h>
+
+/* #define DEBUG_CMDLINE */
+
+extern int prom_argc;
+extern char **prom_argv, **prom_envp;
+
+typedef struct
+{
+ char *name;
+/* char *val; */
+}t_env_var;
+
+
+char * prom_getcmdline(void)
+{
+ return &(arcs_cmdline[0]);
+}
+
+void prom_init_cmdline(void)
+{
+ char *cp;
+ int actr;
+
+ actr = 1; /* Always ignore argv[0] */
+
+ cp = &(arcs_cmdline[0]);
+ while(actr < prom_argc) {
+ strcpy(cp, prom_argv[actr]);
+ cp += strlen(prom_argv[actr]);
+ *cp++ = ' ';
+ actr++;
+ }
+ if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
+ --cp;
+ *cp = '\0';
+}
+
+char *prom_getenv(char *envname)
+{
+ /*
+ * Return a pointer to the given environment variable.
+ * Environment variables are stored in the form of "memsize=64".
+ */
+
+ t_env_var *env = (t_env_var *)prom_envp;
+ int i;
+
+ i = strlen(envname);
+
+ while(env->name) {
+ if(strncmp(envname, env->name, i) == 0) {
+ return(env->name + strlen(envname) + 1);
+ }
+ env++;
+ }
+ return(NULL);
+}
+
+inline unsigned char str2hexnum(unsigned char c)
+{
+ if(c >= '0' && c <= '9')
+ return c - '0';
+ if(c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ if(c >= 'A' && c <= 'F')
+ return c - 'A' + 10;
+ return 0; /* foo */
+}
+
+inline void str2eaddr(unsigned char *ea, unsigned char *str)
+{
+ int i;
+
+ for(i = 0; i < 6; i++) {
+ unsigned char num;
+
+ if((*str == '.') || (*str == ':'))
+ str++;
+ num = str2hexnum(*str++) << 4;
+ num |= (str2hexnum(*str++));
+ ea[i] = num;
+ }
+}
+
+int get_ethernet_addr(char *ethernet_addr)
+{
+ char *ethaddr_str;
+
+ ethaddr_str = prom_getenv("ethaddr");
+ if (!ethaddr_str) {
+ printk("ethaddr not set in boot prom\n");
+ return -1;
+ }
+ str2eaddr(ethernet_addr, ethaddr_str);
+ return 0;
+}
+
+unsigned long __init prom_free_prom_memory(void)
+{
+ return 0;
+}
+
+extern int pnx8550_console_port;
+
+/* used by prom_printf */
+void prom_putchar(char c)
+{
+ if (pnx8550_console_port != -1) {
+ /* Wait until FIFO not full */
+ while( ((ip3106_fifo(UART_BASE, pnx8550_console_port) & IP3106_UART_FIFO_TXFIFO) >> 16) >= 16)
+ ;
+ /* Send one char */
+ ip3106_fifo(UART_BASE, pnx8550_console_port) = c;
+ }
+}
+
+EXPORT_SYMBOL(prom_getcmdline);
+EXPORT_SYMBOL(get_ethernet_addr);
+EXPORT_SYMBOL(str2eaddr);
diff --git a/arch/mips/philips/pnx8550/common/reset.c b/arch/mips/philips/pnx8550/common/reset.c
new file mode 100644
index 000000000000..7b2cbc5b2c7c
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/reset.c
@@ -0,0 +1,49 @@
+/*.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * Reset the PNX8550 board.
+ *
+ */
+#include <linux/slab.h>
+#include <asm/reboot.h>
+#include <glb.h>
+
+void pnx8550_machine_restart(char *command)
+{
+ char head[] = "************* Machine restart *************";
+ char foot[] = "*******************************************";
+
+ printk("\n\n");
+ printk("%s\n", head);
+ if (command != NULL)
+ printk("* %s\n", command);
+ printk("%s\n", foot);
+
+ PNX8550_RST_CTL = PNX8550_RST_DO_SW_RST;
+}
+
+void pnx8550_machine_halt(void)
+{
+ printk("*** Machine halt. (Not implemented) ***\n");
+}
+
+void pnx8550_machine_power_off(void)
+{
+ printk("*** Machine power off. (Not implemented) ***\n");
+}
diff --git a/arch/mips/philips/pnx8550/common/setup.c b/arch/mips/philips/pnx8550/common/setup.c
new file mode 100644
index 000000000000..ee6bf72094f6
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/setup.c
@@ -0,0 +1,149 @@
+/*
+ *
+ * 2.6 port, Embedded Alley Solutions, Inc
+ *
+ * Based on Per Hallsmark, per.hallsmark@mvista.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/serial_ip3106.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/pgtable.h>
+#include <asm/time.h>
+
+#include <glb.h>
+#include <int.h>
+#include <pci.h>
+#include <uart.h>
+#include <nand.h>
+
+extern void prom_printf(char *fmt, ...);
+
+extern void __init board_setup(void);
+extern void pnx8550_machine_restart(char *);
+extern void pnx8550_machine_halt(void);
+extern void pnx8550_machine_power_off(void);
+extern struct resource ioport_resource;
+extern struct resource iomem_resource;
+extern void (*board_time_init)(void);
+extern void pnx8550_time_init(void);
+extern void (*board_timer_setup)(struct irqaction *irq);
+extern void pnx8550_timer_setup(struct irqaction *irq);
+extern void rs_kgdb_hook(int tty_no);
+extern void prom_printf(char *fmt, ...);
+extern char *prom_getcmdline(void);
+
+struct resource standard_io_resources[] = {
+ {"dma1", 0x00, 0x1f, IORESOURCE_BUSY},
+ {"timer", 0x40, 0x5f, IORESOURCE_BUSY},
+ {"dma page reg", 0x80, 0x8f, IORESOURCE_BUSY},
+ {"dma2", 0xc0, 0xdf, IORESOURCE_BUSY},
+};
+
+#define STANDARD_IO_RESOURCES (sizeof(standard_io_resources)/sizeof(struct resource))
+
+extern struct resource pci_io_resource;
+extern struct resource pci_mem_resource;
+
+/* Return the total size of DRAM-memory, (RANK0 + RANK1) */
+unsigned long get_system_mem_size(void)
+{
+ /* Read IP2031_RANK0_ADDR_LO */
+ unsigned long dram_r0_lo = inl(PCI_BASE | 0x65010);
+ /* Read IP2031_RANK1_ADDR_HI */
+ unsigned long dram_r1_hi = inl(PCI_BASE | 0x65018);
+
+ return dram_r1_hi - dram_r0_lo + 1;
+}
+
+int pnx8550_console_port = -1;
+
+void __init plat_setup(void)
+{
+ int i;
+ char* argptr;
+
+ board_setup(); /* board specific setup */
+
+ _machine_restart = pnx8550_machine_restart;
+ _machine_halt = pnx8550_machine_halt;
+ _machine_power_off = pnx8550_machine_power_off;
+
+ board_time_init = pnx8550_time_init;
+ board_timer_setup = pnx8550_timer_setup;
+
+ /* Clear the Global 2 Register, PCI Inta Output Enable Registers
+ Bit 1:Enable DAC Powerdown
+ -> 0:DACs are enabled and are working normally
+ 1:DACs are powerdown
+ Bit 0:Enable of PCI inta output
+ -> 0 = Disable PCI inta output
+ 1 = Enable PCI inta output
+ */
+ PNX8550_GLB2_ENAB_INTA_O = 0;
+
+ /* IO/MEM resources. */
+ set_io_port_base(KSEG1);
+ ioport_resource.start = 0;
+ ioport_resource.end = ~0;
+ iomem_resource.start = 0;
+ iomem_resource.end = ~0;
+
+ /* Request I/O space for devices on this board */
+ for (i = 0; i < STANDARD_IO_RESOURCES; i++)
+ request_resource(&ioport_resource, standard_io_resources + i);
+
+ /* Place the Mode Control bit for GPIO pin 16 in primary function */
+ /* Pin 16 is used by UART1, UA1_TX */
+ outl((PNX8550_GPIO_MODE_PRIMOP << PNX8550_GPIO_MC_16_BIT) |
+ (PNX8550_GPIO_MODE_PRIMOP << PNX8550_GPIO_MC_17_BIT),
+ PNX8550_GPIO_MC1);
+
+ argptr = prom_getcmdline();
+ if ((argptr = strstr(argptr, "console=ttyS")) != NULL) {
+ argptr += strlen("console=ttyS");
+ pnx8550_console_port = *argptr == '0' ? 0 : 1;
+
+ /* We must initialize the UART (console) before prom_printf */
+ /* Set LCR to 8-bit and BAUD to 38400 (no 5) */
+ ip3106_lcr(UART_BASE, pnx8550_console_port) =
+ IP3106_UART_LCR_8BIT;
+ ip3106_baud(UART_BASE, pnx8550_console_port) = 5;
+ }
+
+#ifdef CONFIG_KGDB
+ argptr = prom_getcmdline();
+ if ((argptr = strstr(argptr, "kgdb=ttyS")) != NULL) {
+ int line;
+ argptr += strlen("kgdb=ttyS");
+ line = *argptr == '0' ? 0 : 1;
+ rs_kgdb_hook(line);
+ prom_printf("KGDB: Using ttyS%i for session, "
+ "please connect your debugger\n", line ? 1 : 0);
+ }
+#endif
+ return;
+}
diff --git a/arch/mips/philips/pnx8550/common/time.c b/arch/mips/philips/pnx8550/common/time.c
new file mode 100644
index 000000000000..70664ea96b92
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/time.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2001, 2002, 2003 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * Common time service routines for MIPS machines. See
+ * Documents/MIPS/README.txt.
+ *
+ * This program is free software; you can redistribute 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/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/param.h>
+#include <linux/time.h>
+#include <linux/timer.h>
+#include <linux/smp.h>
+#include <linux/kernel_stat.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include <asm/time.h>
+#include <asm/hardirq.h>
+#include <asm/div64.h>
+#include <asm/debug.h>
+
+#include <int.h>
+#include <cm.h>
+
+extern unsigned int mips_hpt_frequency;
+
+/*
+ * pnx8550_time_init() - it does the following things:
+ *
+ * 1) board_time_init() -
+ * a) (optional) set up RTC routines,
+ * b) (optional) calibrate and set the mips_hpt_frequency
+ * (only needed if you intended to use fixed_rate_gettimeoffset
+ * or use cpu counter as timer interrupt source)
+ */
+
+void pnx8550_time_init(void)
+{
+ unsigned int n;
+ unsigned int m;
+ unsigned int p;
+ unsigned int pow2p;
+
+ /* PLL0 sets MIPS clock (PLL1 <=> TM1, PLL6 <=> TM2, PLL5 <=> mem) */
+ /* (but only if CLK_MIPS_CTL select value [bits 3:1] is 1: FIXME) */
+
+ n = (PNX8550_CM_PLL0_CTL & PNX8550_CM_PLL_N_MASK) >> 16;
+ m = (PNX8550_CM_PLL0_CTL & PNX8550_CM_PLL_M_MASK) >> 8;
+ p = (PNX8550_CM_PLL0_CTL & PNX8550_CM_PLL_P_MASK) >> 2;
+ pow2p = (1 << p);
+
+ db_assert(m != 0 && pow2p != 0);
+
+ /*
+ * Compute the frequency as in the PNX8550 User Manual 1.0, p.186
+ * (a.k.a. 8-10). Divide by HZ for a timer offset that results in
+ * HZ timer interrupts per second.
+ */
+ mips_hpt_frequency = 27UL * ((1000000UL * n)/(m * pow2p));
+}
+
+/*
+ * pnx8550_timer_setup() - it does the following things:
+ *
+ * 5) board_timer_setup() -
+ * a) (optional) over-write any choices made above by time_init().
+ * b) machine specific code should setup the timer irqaction.
+ * c) enable the timer interrupt
+ */
+
+void __init pnx8550_timer_setup(struct irqaction *irq)
+{
+ int configPR;
+
+ setup_irq(PNX8550_INT_TIMER1, irq);
+
+ /* Start timer1 */
+ configPR = read_c0_config7();
+ configPR &= ~0x00000008;
+ write_c0_config7(configPR);
+
+ /* Timer 2 stop */
+ configPR = read_c0_config7();
+ configPR |= 0x00000010;
+ write_c0_config7(configPR);
+
+ write_c0_count2(0);
+ write_c0_compare2(0xffffffff);
+
+ /* Timer 3 stop */
+ configPR = read_c0_config7();
+ configPR |= 0x00000020;
+ write_c0_config7(configPR);
+}
diff --git a/arch/mips/philips/pnx8550/jbs/Makefile b/arch/mips/philips/pnx8550/jbs/Makefile
new file mode 100644
index 000000000000..e8228dbca8f6
--- /dev/null
+++ b/arch/mips/philips/pnx8550/jbs/Makefile
@@ -0,0 +1,4 @@
+
+# Makefile for the Philips JBS Board.
+
+lib-y := init.o board_setup.o irqmap.o
diff --git a/arch/mips/philips/pnx8550/jbs/board_setup.c b/arch/mips/philips/pnx8550/jbs/board_setup.c
new file mode 100644
index 000000000000..f92826e0096d
--- /dev/null
+++ b/arch/mips/philips/pnx8550/jbs/board_setup.c
@@ -0,0 +1,65 @@
+/*
+ * JBS Specific board startup routines.
+ *
+ * Copyright 2005, Embedded Alley Solutions, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/mc146818rtc.h>
+#include <linux/delay.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/pgtable.h>
+
+#include <glb.h>
+
+/* CP0 hazard avoidance. */
+#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
+ "nop; nop; nop; nop; nop; nop;\n\t" \
+ ".set reorder\n\t")
+
+void __init board_setup(void)
+{
+ unsigned long config0, configpr;
+
+ config0 = read_c0_config();
+
+ /* clear all three cache coherency fields */
+ config0 &= ~(0x7 | (7<<25) | (7<<28));
+ config0 |= (CONF_CM_DEFAULT | (CONF_CM_DEFAULT<<25) |
+ (CONF_CM_DEFAULT<<28));
+ write_c0_config(config0);
+ BARRIER;
+
+ configpr = read_c0_config7();
+ configpr |= (1<<19); /* enable tlb */
+ write_c0_config7(configpr);
+ BARRIER;
+}
diff --git a/arch/mips/philips/pnx8550/jbs/init.c b/arch/mips/philips/pnx8550/jbs/init.c
new file mode 100644
index 000000000000..85f449174bc3
--- /dev/null
+++ b/arch/mips/philips/pnx8550/jbs/init.c
@@ -0,0 +1,57 @@
+/*
+ *
+ * Copyright 2005 Embedded Alley Solutions, Inc
+ * source@embeddedalley.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/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+
+int prom_argc;
+char **prom_argv, **prom_envp;
+extern void __init prom_init_cmdline(void);
+extern char *prom_getenv(char *envname);
+
+const char *get_system_type(void)
+{
+ return "Philips PNX8550/JBS";
+}
+
+void __init prom_init(void)
+{
+
+ unsigned long memsize;
+
+ mips_machgroup = MACH_GROUP_PHILIPS;
+ mips_machtype = MACH_PHILIPS_JBS;
+
+ //memsize = 0x02800000; /* Trimedia uses memory above */
+ memsize = 0x08000000; /* Trimedia uses memory above */
+ add_memory_region(0, memsize, BOOT_MEM_RAM);
+}
diff --git a/arch/mips/philips/pnx8550/jbs/irqmap.c b/arch/mips/philips/pnx8550/jbs/irqmap.c
new file mode 100644
index 000000000000..f78e0423dc98
--- /dev/null
+++ b/arch/mips/philips/pnx8550/jbs/irqmap.c
@@ -0,0 +1,36 @@
+/*
+ * Philips JBS board irqmap.
+ *
+ * Copyright 2005 Embedded Alley Solutions, Inc
+ * source@embeddealley.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 <int.h>
+
+char irq_tab_jbs[][5] __initdata = {
+ [8] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff},
+ [9] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff},
+ [17] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff},
+};
+
diff --git a/arch/mips/pmc-sierra/Kconfig b/arch/mips/pmc-sierra/Kconfig
new file mode 100644
index 000000000000..24d514c9dff9
--- /dev/null
+++ b/arch/mips/pmc-sierra/Kconfig
@@ -0,0 +1,3 @@
+config HYPERTRANSPORT
+ bool "Hypertransport Support for PMC-Sierra Yosemite"
+ depends on PMC_YOSEMITE
diff --git a/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h b/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h
index c19f01a32045..a31288335fba 100644
--- a/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h
+++ b/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h
@@ -34,7 +34,6 @@
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/slab.h>
-#include <linux/version.h>
#include <asm/pci.h>
#include <asm/io.h>
#include <linux/init.h>
diff --git a/arch/mips/pmc-sierra/yosemite/ht-irq.c b/arch/mips/pmc-sierra/yosemite/ht-irq.c
index d22c9ffe4914..5aec4057314e 100644
--- a/arch/mips/pmc-sierra/yosemite/ht-irq.c
+++ b/arch/mips/pmc-sierra/yosemite/ht-irq.c
@@ -26,7 +26,6 @@
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/kernel.h>
-#include <linux/version.h>
#include <linux/init.h>
#include <asm/pci.h>
diff --git a/arch/mips/pmc-sierra/yosemite/ht.c b/arch/mips/pmc-sierra/yosemite/ht.c
index dad228d3a220..54b65a80abf5 100644
--- a/arch/mips/pmc-sierra/yosemite/ht.c
+++ b/arch/mips/pmc-sierra/yosemite/ht.c
@@ -28,7 +28,6 @@
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/slab.h>
-#include <linux/version.h>
#include <asm/pci.h>
#include <asm/io.h>
diff --git a/arch/mips/pmc-sierra/yosemite/prom.c b/arch/mips/pmc-sierra/yosemite/prom.c
index 1fb3e697948d..555bfacf7647 100644
--- a/arch/mips/pmc-sierra/yosemite/prom.c
+++ b/arch/mips/pmc-sierra/yosemite/prom.c
@@ -132,8 +132,9 @@ void __init prom_init(void)
prom_grab_secondary();
}
-void __init prom_free_prom_memory(void)
+unsigned long __init prom_free_prom_memory(void)
{
+ return 0;
}
void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
diff --git a/arch/mips/pmc-sierra/yosemite/setup.c b/arch/mips/pmc-sierra/yosemite/setup.c
index 7225bbf20ce4..bdc2ab55bed6 100644
--- a/arch/mips/pmc-sierra/yosemite/setup.c
+++ b/arch/mips/pmc-sierra/yosemite/setup.c
@@ -212,7 +212,7 @@ static void __init py_late_time_init(void)
py_rtc_setup();
}
-static int __init pmc_yosemite_setup(void)
+void __init plat_setup(void)
{
board_time_init = yosemite_time_init;
late_time_init = py_late_time_init;
@@ -228,8 +228,4 @@ static int __init pmc_yosemite_setup(void)
OCD_WRITE(RM9000x2_OCD_HTBAR0, HYPERTRANSPORT_BAR0_ADDR);
OCD_WRITE(RM9000x2_OCD_HTMASK0, HYPERTRANSPORT_SIZE0);
#endif
-
- return 0;
}
-
-early_initcall(pmc_yosemite_setup);
diff --git a/arch/mips/pmc-sierra/yosemite/smp.c b/arch/mips/pmc-sierra/yosemite/smp.c
index 1d3b0734c78c..0527170d6adb 100644
--- a/arch/mips/pmc-sierra/yosemite/smp.c
+++ b/arch/mips/pmc-sierra/yosemite/smp.c
@@ -9,7 +9,7 @@ extern void (*mips_hpt_init)(unsigned int);
#define LAUNCHSTACK_SIZE 256
-static spinlock_t launch_lock __initdata;
+static __initdata DEFINE_SPINLOCK(launch_lock);
static unsigned long secondary_sp __initdata;
static unsigned long secondary_gp __initdata;
diff --git a/arch/mips/qemu/q-setup.c b/arch/mips/qemu/q-setup.c
index 1a80eee8cd35..022eb1af6db1 100644
--- a/arch/mips/qemu/q-setup.c
+++ b/arch/mips/qemu/q-setup.c
@@ -4,6 +4,11 @@
#define QEMU_PORT_BASE 0xb4000000
+const char *get_system_type(void)
+{
+ return "Qemu";
+}
+
static void __init qemu_timer_setup(struct irqaction *irq)
{
/* set the clock to 100 Hz */
diff --git a/arch/mips/sgi-ip22/ip22-eisa.c b/arch/mips/sgi-ip22/ip22-eisa.c
index fa0e719c5bd1..b19820110aa3 100644
--- a/arch/mips/sgi-ip22/ip22-eisa.c
+++ b/arch/mips/sgi-ip22/ip22-eisa.c
@@ -29,6 +29,7 @@
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
+#include <asm/io.h>
#include <asm/irq.h>
#include <asm/mipsregs.h>
#include <asm/addrspace.h>
@@ -37,42 +38,29 @@
#include <asm/sgi/mc.h>
#include <asm/sgi/ip22.h>
-#define EISA_MAX_SLOTS 4
+/* I2 has four EISA slots. */
+#define IP22_EISA_MAX_SLOTS 4
#define EISA_MAX_IRQ 16
-#define EISA_TO_PHYS(x) (0x00080000 | (x))
-#define EISA_TO_KSEG1(x) ((void *) KSEG1ADDR(EISA_TO_PHYS((x))))
-
-#define EIU_MODE_REG 0x0009ffc0
-#define EIU_STAT_REG 0x0009ffc4
-#define EIU_PREMPT_REG 0x0009ffc8
-#define EIU_QUIET_REG 0x0009ffcc
-#define EIU_INTRPT_ACK 0x00090004
-
-#define EISA_DMA1_STATUS 8
-#define EISA_INT1_CTRL 0x20
-#define EISA_INT1_MASK 0x21
-#define EISA_INT2_CTRL 0xA0
-#define EISA_INT2_MASK 0xA1
-#define EISA_DMA2_STATUS 0xD0
-#define EISA_DMA2_WRITE_SINGLE 0xD4
-#define EISA_EXT_NMI_RESET_CTRL 0x461
-#define EISA_INT1_EDGE_LEVEL 0x4D0
-#define EISA_INT2_EDGE_LEVEL 0x4D1
-#define EISA_VENDOR_ID_OFFSET 0xC80
-
-#define EIU_WRITE_32(x,y) { *((u32 *) KSEG1ADDR(x)) = (u32) (y); mb(); }
-#define EIU_READ_8(x) *((u8 *) KSEG1ADDR(x))
-#define EISA_WRITE_8(x,y) { *((u8 *) EISA_TO_KSEG1(x)) = (u8) (y); mb(); }
-#define EISA_READ_8(x) *((u8 *) EISA_TO_KSEG1(x))
-
-static char *decode_eisa_sig(u8 * sig)
+#define EIU_MODE_REG 0x0001ffc0
+#define EIU_STAT_REG 0x0001ffc4
+#define EIU_PREMPT_REG 0x0001ffc8
+#define EIU_QUIET_REG 0x0001ffcc
+#define EIU_INTRPT_ACK 0x00010004
+
+static char __init *decode_eisa_sig(unsigned long addr)
{
- static char sig_str[8];
- u16 rev;
+ static char sig_str[EISA_SIG_LEN];
+ u8 sig[4];
+ u16 rev;
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ sig[i] = inb (addr + i);
- if (sig[0] & 0x80)
- return NULL;
+ if (!i && (sig[0] & 0x80))
+ return NULL;
+ }
sig_str[0] = ((sig[0] >> 2) & 0x1f) + ('A' - 1);
sig_str[1] = (((sig[0] & 3) << 3) | (sig[1] >> 5)) + ('A' - 1);
@@ -83,23 +71,26 @@ static char *decode_eisa_sig(u8 * sig)
return sig_str;
}
-static void ip22_eisa_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ip22_eisa_intr(int irq, void *dev_id, struct pt_regs *regs)
{
u8 eisa_irq;
u8 dma1, dma2;
- eisa_irq = EIU_READ_8(EIU_INTRPT_ACK);
- dma1 = EISA_READ_8(EISA_DMA1_STATUS);
- dma2 = EISA_READ_8(EISA_DMA2_STATUS);
-
- if (eisa_irq >= EISA_MAX_IRQ) {
- /* Oops, Bad Stuff Happened... */
- printk(KERN_ERR "eisa_irq %d out of bound\n", eisa_irq);
+ eisa_irq = inb(EIU_INTRPT_ACK);
+ dma1 = inb(EISA_DMA1_STATUS);
+ dma2 = inb(EISA_DMA2_STATUS);
- EISA_WRITE_8(EISA_INT2_CTRL, 0x20);
- EISA_WRITE_8(EISA_INT1_CTRL, 0x20);
- } else
+ if (eisa_irq < EISA_MAX_IRQ) {
do_IRQ(eisa_irq, regs);
+ return IRQ_HANDLED;
+ }
+
+ /* Oops, Bad Stuff Happened... */
+ printk(KERN_ERR "eisa_irq %d out of bound\n", eisa_irq);
+
+ outb(0x20, EISA_INT2_CTRL);
+ outb(0x20, EISA_INT1_CTRL);
+ return IRQ_NONE;
}
static void enable_eisa1_irq(unsigned int irq)
@@ -109,9 +100,9 @@ static void enable_eisa1_irq(unsigned int irq)
local_irq_save(flags);
- mask = EISA_READ_8(EISA_INT1_MASK);
+ mask = inb(EISA_INT1_MASK);
mask &= ~((u8) (1 << irq));
- EISA_WRITE_8(EISA_INT1_MASK, mask);
+ outb(mask, EISA_INT1_MASK);
local_irq_restore(flags);
}
@@ -122,9 +113,9 @@ static unsigned int startup_eisa1_irq(unsigned int irq)
/* Only use edge interrupts for EISA */
- edge = EISA_READ_8(EISA_INT1_EDGE_LEVEL);
+ edge = inb(EISA_INT1_EDGE_LEVEL);
edge &= ~((u8) (1 << irq));
- EISA_WRITE_8(EISA_INT1_EDGE_LEVEL, edge);
+ outb(edge, EISA_INT1_EDGE_LEVEL);
enable_eisa1_irq(irq);
return 0;
@@ -134,9 +125,9 @@ static void disable_eisa1_irq(unsigned int irq)
{
u8 mask;
- mask = EISA_READ_8(EISA_INT1_MASK);
+ mask = inb(EISA_INT1_MASK);
mask |= ((u8) (1 << irq));
- EISA_WRITE_8(EISA_INT1_MASK, mask);
+ outb(mask, EISA_INT1_MASK);
}
#define shutdown_eisa1_irq disable_eisa1_irq
@@ -145,7 +136,7 @@ static void mask_and_ack_eisa1_irq(unsigned int irq)
{
disable_eisa1_irq(irq);
- EISA_WRITE_8(EISA_INT1_CTRL, 0x20);
+ outb(0x20, EISA_INT1_CTRL);
}
static void end_eisa1_irq(unsigned int irq)
@@ -171,9 +162,9 @@ static void enable_eisa2_irq(unsigned int irq)
local_irq_save(flags);
- mask = EISA_READ_8(EISA_INT2_MASK);
+ mask = inb(EISA_INT2_MASK);
mask &= ~((u8) (1 << (irq - 8)));
- EISA_WRITE_8(EISA_INT2_MASK, mask);
+ outb(mask, EISA_INT2_MASK);
local_irq_restore(flags);
}
@@ -184,9 +175,9 @@ static unsigned int startup_eisa2_irq(unsigned int irq)
/* Only use edge interrupts for EISA */
- edge = EISA_READ_8(EISA_INT2_EDGE_LEVEL);
+ edge = inb(EISA_INT2_EDGE_LEVEL);
edge &= ~((u8) (1 << (irq - 8)));
- EISA_WRITE_8(EISA_INT2_EDGE_LEVEL, edge);
+ outb(edge, EISA_INT2_EDGE_LEVEL);
enable_eisa2_irq(irq);
return 0;
@@ -196,9 +187,9 @@ static void disable_eisa2_irq(unsigned int irq)
{
u8 mask;
- mask = EISA_READ_8(EISA_INT2_MASK);
+ mask = inb(EISA_INT2_MASK);
mask |= ((u8) (1 << (irq - 8)));
- EISA_WRITE_8(EISA_INT2_MASK, mask);
+ outb(mask, EISA_INT2_MASK);
}
#define shutdown_eisa2_irq disable_eisa2_irq
@@ -207,8 +198,7 @@ static void mask_and_ack_eisa2_irq(unsigned int irq)
{
disable_eisa2_irq(irq);
- EISA_WRITE_8(EISA_INT2_CTRL, 0x20);
- EISA_WRITE_8(EISA_INT1_CTRL, 0x20);
+ outb(0x20, EISA_INT2_CTRL);
}
static void end_eisa2_irq(unsigned int irq)
@@ -241,7 +231,6 @@ int __init ip22_eisa_init(void)
{
int i, c;
char *str;
- u8 *slot_addr;
if (!(sgimc->systemid & SGIMC_SYSID_EPRESENT)) {
printk(KERN_INFO "EISA: bus not present.\n");
@@ -249,11 +238,8 @@ int __init ip22_eisa_init(void)
}
printk(KERN_INFO "EISA: Probing bus...\n");
- for (c = 0, i = 1; i <= EISA_MAX_SLOTS; i++) {
- slot_addr =
- (u8 *) EISA_TO_KSEG1((0x1000 * i) +
- EISA_VENDOR_ID_OFFSET);
- if ((str = decode_eisa_sig(slot_addr))) {
+ for (c = 0, i = 1; i <= IP22_EISA_MAX_SLOTS; i++) {
+ if ((str = decode_eisa_sig(0x1000 * i + EISA_VENDOR_ID_OFFSET))) {
printk(KERN_INFO "EISA: slot %d : %s detected.\n",
i, str);
c++;
@@ -268,25 +254,25 @@ int __init ip22_eisa_init(void)
Please wave your favorite dead chicken over the busses */
/* First say hello to the EIU */
- EIU_WRITE_32(EIU_PREMPT_REG, 0x0000FFFF);
- EIU_WRITE_32(EIU_QUIET_REG, 1);
- EIU_WRITE_32(EIU_MODE_REG, 0x40f3c07F);
+ outl(0x0000FFFF, EIU_PREMPT_REG);
+ outl(1, EIU_QUIET_REG);
+ outl(0x40f3c07F, EIU_MODE_REG);
/* Now be nice to the EISA chipset */
- EISA_WRITE_8(EISA_EXT_NMI_RESET_CTRL, 1);
- for (i = 0; i < 10000; i++); /* Wait long enough for the dust to settle */
- EISA_WRITE_8(EISA_EXT_NMI_RESET_CTRL, 0);
- EISA_WRITE_8(EISA_INT1_CTRL, 0x11);
- EISA_WRITE_8(EISA_INT2_CTRL, 0x11);
- EISA_WRITE_8(EISA_INT1_MASK, 0);
- EISA_WRITE_8(EISA_INT2_MASK, 8);
- EISA_WRITE_8(EISA_INT1_MASK, 4);
- EISA_WRITE_8(EISA_INT2_MASK, 2);
- EISA_WRITE_8(EISA_INT1_MASK, 1);
- EISA_WRITE_8(EISA_INT2_MASK, 1);
- EISA_WRITE_8(EISA_INT1_MASK, 0xfb);
- EISA_WRITE_8(EISA_INT2_MASK, 0xff);
- EISA_WRITE_8(EISA_DMA2_WRITE_SINGLE, 0);
+ outb(1, EISA_EXT_NMI_RESET_CTRL);
+ udelay(50); /* Wait long enough for the dust to settle */
+ outb(0, EISA_EXT_NMI_RESET_CTRL);
+ outb(0x11, EISA_INT1_CTRL);
+ outb(0x11, EISA_INT2_CTRL);
+ outb(0, EISA_INT1_MASK);
+ outb(8, EISA_INT2_MASK);
+ outb(4, EISA_INT1_MASK);
+ outb(2, EISA_INT2_MASK);
+ outb(1, EISA_INT1_MASK);
+ outb(1, EISA_INT2_MASK);
+ outb(0xfb, EISA_INT1_MASK);
+ outb(0xff, EISA_INT2_MASK);
+ outb(0, EISA_DMA2_WRITE_SINGLE);
for (i = SGINT_EISA; i < (SGINT_EISA + EISA_MAX_IRQ); i++) {
irq_desc[i].status = IRQ_DISABLED;
diff --git a/arch/mips/sgi-ip22/ip22-setup.c b/arch/mips/sgi-ip22/ip22-setup.c
index 0e96a5d67993..5e59b4c8876b 100644
--- a/arch/mips/sgi-ip22/ip22-setup.c
+++ b/arch/mips/sgi-ip22/ip22-setup.c
@@ -53,7 +53,7 @@ EXPORT_SYMBOL(ip22_do_break);
extern void ip22_be_init(void) __init;
extern void ip22_time_init(void) __init;
-static int __init ip22_setup(void)
+void __init plat_setup(void)
{
char *ctype;
@@ -137,8 +137,4 @@ static int __init ip22_setup(void)
}
}
#endif
-
- return 0;
}
-
-early_initcall(ip22_setup);
diff --git a/arch/mips/sgi-ip27/Kconfig b/arch/mips/sgi-ip27/Kconfig
new file mode 100644
index 000000000000..7b0bc4437243
--- /dev/null
+++ b/arch/mips/sgi-ip27/Kconfig
@@ -0,0 +1,54 @@
+#config SGI_SN0_XXL
+# bool "IP27 XXL"
+# depends on SGI_IP27
+# This options adds support for userspace processes upto 16TB size.
+# Normally the limit is just .5TB.
+
+config SGI_SN0_N_MODE
+ bool "IP27 N-Mode"
+ depends on SGI_IP27
+ help
+ The nodes of Origin 200, Origin 2000 and Onyx 2 systems can be
+ configured in either N-Modes which allows for more nodes or M-Mode
+ which allows for more memory. Your system is most probably
+ running in M-Mode, so you should say N here.
+
+config ARCH_DISCONTIGMEM_ENABLE
+ bool
+ default y if SGI_IP27
+ help
+ Say Y to upport efficient handling of discontiguous physical memory,
+ for architectures which are either NUMA (Non-Uniform Memory Access)
+ or have huge holes in the physical address space for other reasons.
+ See <file:Documentation/vm/numa> for more.
+
+config NUMA
+ bool "NUMA Support"
+ depends on SGI_IP27
+ help
+ Say Y to compile the kernel to support NUMA (Non-Uniform Memory
+ Access). This option is for configuring high-end multiprocessor
+ server machines. If in doubt, say N.
+
+config MAPPED_KERNEL
+ bool "Mapped kernel support"
+ depends on SGI_IP27
+ help
+ Change the way a Linux kernel is loaded into memory on a MIPS64
+ machine. This is required in order to support text replication and
+ NUMA. If you need to understand it, read the source code.
+
+config REPLICATE_KTEXT
+ bool "Kernel text replication support"
+ depends on SGI_IP27
+ help
+ Say Y here to enable replicating the kernel text across multiple
+ nodes in a NUMA cluster. This trades memory for speed.
+
+config REPLICATE_EXHANDLERS
+ bool "Exception handler replication support"
+ depends on SGI_IP27
+ help
+ Say Y here to enable replicating the kernel exception handlers
+ across multiple nodes in a NUMA cluster. This trades memory for
+ speed.
diff --git a/arch/mips/sgi-ip27/ip27-berr.c b/arch/mips/sgi-ip27/ip27-berr.c
index e1829a5d3b19..07631a97670b 100644
--- a/arch/mips/sgi-ip27/ip27-berr.c
+++ b/arch/mips/sgi-ip27/ip27-berr.c
@@ -10,6 +10,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/signal.h> /* for SIGBUS */
#include <asm/module.h>
#include <asm/sn/addrs.h>
diff --git a/arch/mips/sgi-ip27/ip27-console.c b/arch/mips/sgi-ip27/ip27-console.c
index d97f5b5ef844..3e1ac299b804 100644
--- a/arch/mips/sgi-ip27/ip27-console.c
+++ b/arch/mips/sgi-ip27/ip27-console.c
@@ -30,8 +30,10 @@
static inline struct ioc3_uartregs *console_uart(void)
{
struct ioc3 *ioc3;
+ nasid_t nasid;
- ioc3 = (struct ioc3 *)KL_CONFIG_CH_CONS_INFO(get_nasid())->memory_base;
+ nasid = (master_nasid == INVALID_NASID) ? get_nasid() : master_nasid;
+ ioc3 = (struct ioc3 *)KL_CONFIG_CH_CONS_INFO(nasid)->memory_base;
return &ioc3->sregs.uarta;
}
diff --git a/arch/mips/sgi-ip27/ip27-init.c b/arch/mips/sgi-ip27/ip27-init.c
index 6dcee5c46c74..8651a0e75404 100644
--- a/arch/mips/sgi-ip27/ip27-init.c
+++ b/arch/mips/sgi-ip27/ip27-init.c
@@ -56,12 +56,12 @@ static void __init per_hub_init(cnodeid_t cnode)
{
struct hub_data *hub = hub_data(cnode);
nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
+ int i;
cpu_set(smp_processor_id(), hub->h_cpus);
if (test_and_set_bit(cnode, hub_init_mask))
return;
-
/*
* Set CRB timeout at 5ms, (< PI timeout of 10ms)
*/
@@ -88,6 +88,24 @@ static void __init per_hub_init(cnodeid_t cnode)
__flush_cache_all();
}
#endif
+
+ /*
+ * Some interrupts are reserved by hardware or by software convention.
+ * Mark these as reserved right away so they won't be used accidently
+ * later.
+ */
+ for (i = 0; i <= BASE_PCI_IRQ; i++) {
+ __set_bit(i, hub->irq_alloc_mask);
+ LOCAL_HUB_CLR_INTR(INT_PEND0_BASELVL + i);
+ }
+
+ __set_bit(IP_PEND0_6_63, hub->irq_alloc_mask);
+ LOCAL_HUB_S(PI_INT_PEND_MOD, IP_PEND0_6_63);
+
+ for (i = NI_BRDCAST_ERR_A; i <= MSC_PANIC_INTR; i++) {
+ __set_bit(i, hub->irq_alloc_mask);
+ LOCAL_HUB_CLR_INTR(INT_PEND1_BASELVL + i);
+ }
}
void __init per_cpu_init(void)
@@ -104,30 +122,12 @@ void __init per_cpu_init(void)
clear_c0_status(ST0_IM);
+ per_hub_init(cnode);
+
for (i = 0; i < LEVELS_PER_SLICE; i++)
si->level_to_irq[i] = -1;
/*
- * Some interrupts are reserved by hardware or by software convention.
- * Mark these as reserved right away so they won't be used accidently
- * later.
- */
- for (i = 0; i <= BASE_PCI_IRQ; i++) {
- __set_bit(i, si->irq_alloc_mask);
- LOCAL_HUB_S(PI_INT_PEND_MOD, i);
- }
-
- __set_bit(IP_PEND0_6_63, si->irq_alloc_mask);
- LOCAL_HUB_S(PI_INT_PEND_MOD, IP_PEND0_6_63);
-
- for (i = NI_BRDCAST_ERR_A; i <= MSC_PANIC_INTR; i++) {
- __set_bit(i, si->irq_alloc_mask + 1);
- LOCAL_HUB_S(PI_INT_PEND_MOD, i);
- }
-
- LOCAL_HUB_L(PI_INT_PEND0);
-
- /*
* We use this so we can find the local hub's data as fast as only
* possible.
*/
@@ -140,8 +140,6 @@ void __init per_cpu_init(void)
install_cpu_nmi_handler(cputoslice(cpu));
set_c0_status(SRB_DEV0 | SRB_DEV1);
-
- per_hub_init(cnode);
}
/*
@@ -198,7 +196,7 @@ extern void ip27_setup_console(void);
extern void ip27_time_init(void);
extern void ip27_reboot_setup(void);
-static int __init ip27_setup(void)
+void __init plat_setup(void)
{
hubreg_t p, e, n_mode;
nasid_t nid;
@@ -245,8 +243,4 @@ static int __init ip27_setup(void)
set_io_port_base(IO_BASE);
board_time_init = ip27_time_init;
-
- return 0;
}
-
-early_initcall(ip27_setup);
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c
index 61817a18aed2..73e5e52781d8 100644
--- a/arch/mips/sgi-ip27/ip27-irq.c
+++ b/arch/mips/sgi-ip27/ip27-irq.c
@@ -5,6 +5,9 @@
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
* Copyright (C) 1999 - 2001 Kanoj Sarcar
*/
+
+#undef DEBUG
+
#include <linux/config.h>
#include <linux/init.h>
#include <linux/irq.h>
@@ -14,11 +17,11 @@
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
-#include <linux/irq.h>
#include <linux/timex.h>
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/smp_lock.h>
+#include <linux/kernel.h>
#include <linux/kernel_stat.h>
#include <linux/delay.h>
#include <linux/bitops.h>
@@ -37,13 +40,6 @@
#include <asm/sn/hub.h>
#include <asm/sn/intr.h>
-#undef DEBUG_IRQ
-#ifdef DEBUG_IRQ
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
/*
* Linux has a controller-independent x86 interrupt architecture.
* every controller has a 'controller-template', that is used
@@ -74,14 +70,15 @@ extern int irq_to_slot[];
static inline int alloc_level(int cpu, int irq)
{
+ struct hub_data *hub = hub_data(cpu_to_node(cpu));
struct slice_data *si = cpu_data[cpu].data;
- int level; /* pre-allocated entries */
+ int level;
- level = find_first_zero_bit(si->irq_alloc_mask, LEVELS_PER_SLICE);
+ level = find_first_zero_bit(hub->irq_alloc_mask, LEVELS_PER_SLICE);
if (level >= LEVELS_PER_SLICE)
panic("Cpu %d flooded with devices\n", cpu);
- __set_bit(level, si->irq_alloc_mask);
+ __set_bit(level, hub->irq_alloc_mask);
si->level_to_irq[level] = irq;
return level;
@@ -216,9 +213,11 @@ static int intr_connect_level(int cpu, int bit)
{
nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
struct slice_data *si = cpu_data[cpu].data;
+ unsigned long flags;
- __set_bit(bit, si->irq_enable_mask);
+ set_bit(bit, si->irq_enable_mask);
+ local_irq_save(flags);
if (!cputoslice(cpu)) {
REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]);
REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]);
@@ -226,6 +225,7 @@ static int intr_connect_level(int cpu, int bit)
REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]);
REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]);
}
+ local_irq_restore(flags);
return 0;
}
@@ -235,7 +235,7 @@ static int intr_disconnect_level(int cpu, int bit)
nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
struct slice_data *si = cpu_data[cpu].data;
- __clear_bit(bit, si->irq_enable_mask);
+ clear_bit(bit, si->irq_enable_mask);
if (!cputoslice(cpu)) {
REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]);
@@ -261,7 +261,7 @@ static unsigned int startup_bridge_irq(unsigned int irq)
bc = IRQ_TO_BRIDGE(irq);
bridge = bc->base;
- DBG("bridge_startup(): irq= 0x%x pin=%d\n", irq, pin);
+ pr_debug("bridge_startup(): irq= 0x%x pin=%d\n", irq, pin);
/*
* "map" irq to a swlevel greater than 6 since the first 6 bits
* of INT_PEND0 are taken
@@ -298,12 +298,13 @@ static unsigned int startup_bridge_irq(unsigned int irq)
static void shutdown_bridge_irq(unsigned int irq)
{
struct bridge_controller *bc = IRQ_TO_BRIDGE(irq);
+ struct hub_data *hub = hub_data(cpu_to_node(bc->irq_cpu));
bridge_t *bridge = bc->base;
struct slice_data *si = cpu_data[bc->irq_cpu].data;
int pin, swlevel;
cpuid_t cpu;
- DBG("bridge_shutdown: irq 0x%x\n", irq);
+ pr_debug("bridge_shutdown: irq 0x%x\n", irq);
pin = SLOT_FROM_PCI_IRQ(irq);
/*
@@ -313,7 +314,7 @@ static void shutdown_bridge_irq(unsigned int irq)
swlevel = find_level(&cpu, irq);
intr_disconnect_level(cpu, swlevel);
- __clear_bit(swlevel, si->irq_alloc_mask);
+ __clear_bit(swlevel, hub->irq_alloc_mask);
si->level_to_irq[swlevel] = -1;
bridge->b_int_enable &= ~(1 << pin);
@@ -433,25 +434,24 @@ void install_ipi(void)
int slice = LOCAL_HUB_L(PI_CPU_NUM);
int cpu = smp_processor_id();
struct slice_data *si = cpu_data[cpu].data;
- hubreg_t mask, set;
+ struct hub_data *hub = hub_data(cpu_to_node(cpu));
+ int resched, call;
+
+ resched = CPU_RESCHED_A_IRQ + slice;
+ __set_bit(resched, hub->irq_alloc_mask);
+ __set_bit(resched, si->irq_enable_mask);
+ LOCAL_HUB_CLR_INTR(resched);
+
+ call = CPU_CALL_A_IRQ + slice;
+ __set_bit(call, hub->irq_alloc_mask);
+ __set_bit(call, si->irq_enable_mask);
+ LOCAL_HUB_CLR_INTR(call);
if (slice == 0) {
- LOCAL_HUB_CLR_INTR(CPU_RESCHED_A_IRQ);
- LOCAL_HUB_CLR_INTR(CPU_CALL_A_IRQ);
- mask = LOCAL_HUB_L(PI_INT_MASK0_A); /* Slice A */
- set = (1UL << CPU_RESCHED_A_IRQ) | (1UL << CPU_CALL_A_IRQ);
- mask |= set;
- si->irq_enable_mask[0] |= set;
- si->irq_alloc_mask[0] |= set;
- LOCAL_HUB_S(PI_INT_MASK0_A, mask);
+ LOCAL_HUB_S(PI_INT_MASK0_A, si->irq_enable_mask[0]);
+ LOCAL_HUB_S(PI_INT_MASK1_A, si->irq_enable_mask[1]);
} else {
- LOCAL_HUB_CLR_INTR(CPU_RESCHED_B_IRQ);
- LOCAL_HUB_CLR_INTR(CPU_CALL_B_IRQ);
- mask = LOCAL_HUB_L(PI_INT_MASK0_B); /* Slice B */
- set = (1UL << CPU_RESCHED_B_IRQ) | (1UL << CPU_CALL_B_IRQ);
- mask |= set;
- si->irq_enable_mask[1] |= set;
- si->irq_alloc_mask[1] |= set;
- LOCAL_HUB_S(PI_INT_MASK0_B, mask);
+ LOCAL_HUB_S(PI_INT_MASK0_B, si->irq_enable_mask[0]);
+ LOCAL_HUB_S(PI_INT_MASK1_B, si->irq_enable_mask[1]);
}
}
diff --git a/arch/mips/sgi-ip27/ip27-smp.c b/arch/mips/sgi-ip27/ip27-smp.c
index 17f768cba94f..3a8291b7d26d 100644
--- a/arch/mips/sgi-ip27/ip27-smp.c
+++ b/arch/mips/sgi-ip27/ip27-smp.c
@@ -127,37 +127,28 @@ void cpu_node_probe(void)
printk("Discovered %d cpus on %d nodes\n", highest + 1, num_online_nodes());
}
-static void intr_clear_bits(nasid_t nasid, volatile hubreg_t *pend,
- int base_level)
+static __init void intr_clear_all(nasid_t nasid)
{
- volatile hubreg_t bits;
int i;
- /* Check pending interrupts */
- if ((bits = HUB_L(pend)) != 0)
- for (i = 0; i < N_INTPEND_BITS; i++)
- if (bits & (1 << i))
- LOCAL_HUB_CLR_INTR(base_level + i);
-}
-
-static void intr_clear_all(nasid_t nasid)
-{
REMOTE_HUB_S(nasid, PI_INT_MASK0_A, 0);
REMOTE_HUB_S(nasid, PI_INT_MASK0_B, 0);
REMOTE_HUB_S(nasid, PI_INT_MASK1_A, 0);
REMOTE_HUB_S(nasid, PI_INT_MASK1_B, 0);
- intr_clear_bits(nasid, REMOTE_HUB_ADDR(nasid, PI_INT_PEND0),
- INT_PEND0_BASELVL);
- intr_clear_bits(nasid, REMOTE_HUB_ADDR(nasid, PI_INT_PEND1),
- INT_PEND1_BASELVL);
+
+ for (i = 0; i < 128; i++)
+ REMOTE_HUB_CLR_INTR(nasid, i);
}
void __init prom_prepare_cpus(unsigned int max_cpus)
{
cnodeid_t cnode;
- for_each_online_node(cnode)
+ for_each_online_node(cnode) {
+ if (cnode == 0)
+ continue;
intr_clear_all(COMPACT_TO_NASID_NODEID(cnode));
+ }
replicate_kernel_text();
diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c
index fc3a8e90d763..2eb22d692ed9 100644
--- a/arch/mips/sgi-ip32/ip32-irq.c
+++ b/arch/mips/sgi-ip32/ip32-irq.c
@@ -163,14 +163,13 @@ static void end_cpu_irq(unsigned int irq)
#define mask_and_ack_cpu_irq disable_cpu_irq
static struct hw_interrupt_type ip32_cpu_interrupt = {
- "IP32 CPU",
- startup_cpu_irq,
- shutdown_cpu_irq,
- enable_cpu_irq,
- disable_cpu_irq,
- mask_and_ack_cpu_irq,
- end_cpu_irq,
- NULL
+ .typename = "IP32 CPU",
+ .startup = startup_cpu_irq,
+ .shutdown = shutdown_cpu_irq,
+ .enable = enable_cpu_irq,
+ .disable = disable_cpu_irq,
+ .ack = mask_and_ack_cpu_irq,
+ .end = end_cpu_irq,
};
/*
@@ -234,14 +233,13 @@ static void end_crime_irq(unsigned int irq)
#define shutdown_crime_irq disable_crime_irq
static struct hw_interrupt_type ip32_crime_interrupt = {
- "IP32 CRIME",
- startup_crime_irq,
- shutdown_crime_irq,
- enable_crime_irq,
- disable_crime_irq,
- mask_and_ack_crime_irq,
- end_crime_irq,
- NULL
+ .typename = "IP32 CRIME",
+ .startup = startup_crime_irq,
+ .shutdown = shutdown_crime_irq,
+ .enable = enable_crime_irq,
+ .disable = disable_crime_irq,
+ .ack = mask_and_ack_crime_irq,
+ .end = end_crime_irq,
};
/*
@@ -294,14 +292,13 @@ static void end_macepci_irq(unsigned int irq)
#define mask_and_ack_macepci_irq disable_macepci_irq
static struct hw_interrupt_type ip32_macepci_interrupt = {
- "IP32 MACE PCI",
- startup_macepci_irq,
- shutdown_macepci_irq,
- enable_macepci_irq,
- disable_macepci_irq,
- mask_and_ack_macepci_irq,
- end_macepci_irq,
- NULL
+ .typename = "IP32 MACE PCI",
+ .startup = startup_macepci_irq,
+ .shutdown = shutdown_macepci_irq,
+ .enable = enable_macepci_irq,
+ .disable = disable_macepci_irq,
+ .ack = mask_and_ack_macepci_irq,
+ .end = end_macepci_irq,
};
/* This is used for MACE ISA interrupts. That means bits 4-6 in the
@@ -425,14 +422,13 @@ static void end_maceisa_irq(unsigned irq)
#define shutdown_maceisa_irq disable_maceisa_irq
static struct hw_interrupt_type ip32_maceisa_interrupt = {
- "IP32 MACE ISA",
- startup_maceisa_irq,
- shutdown_maceisa_irq,
- enable_maceisa_irq,
- disable_maceisa_irq,
- mask_and_ack_maceisa_irq,
- end_maceisa_irq,
- NULL
+ .typename = "IP32 MACE ISA",
+ .startup = startup_maceisa_irq,
+ .shutdown = shutdown_maceisa_irq,
+ .enable = enable_maceisa_irq,
+ .disable = disable_maceisa_irq,
+ .ack = mask_and_ack_maceisa_irq,
+ .end = end_maceisa_irq,
};
/* This is used for regular non-ISA, non-PCI MACE interrupts. That means
@@ -476,14 +472,13 @@ static void end_mace_irq(unsigned int irq)
#define mask_and_ack_mace_irq disable_mace_irq
static struct hw_interrupt_type ip32_mace_interrupt = {
- "IP32 MACE",
- startup_mace_irq,
- shutdown_mace_irq,
- enable_mace_irq,
- disable_mace_irq,
- mask_and_ack_mace_irq,
- end_mace_irq,
- NULL
+ .typename = "IP32 MACE",
+ .startup = startup_mace_irq,
+ .shutdown = shutdown_mace_irq,
+ .enable = enable_mace_irq,
+ .disable = disable_mace_irq,
+ .ack = mask_and_ack_mace_irq,
+ .end = end_mace_irq,
};
static void ip32_unknown_interrupt(struct pt_regs *regs)
diff --git a/arch/mips/sgi-ip32/ip32-memory.c b/arch/mips/sgi-ip32/ip32-memory.c
index fc76ca92bab9..d37d40a3cdae 100644
--- a/arch/mips/sgi-ip32/ip32-memory.c
+++ b/arch/mips/sgi-ip32/ip32-memory.c
@@ -36,8 +36,8 @@ void __init prom_meminit (void)
if (base + size > (256 << 20))
base += CRIME_HI_MEM_BASE;
- printk("CRIME MC: bank %u base 0x%016lx size %luMB\n",
- bank, base, size);
+ printk("CRIME MC: bank %u base 0x%016lx size %luMiB\n",
+ bank, base, size >> 20);
add_memory_region (base, size, BOOT_MEM_RAM);
}
}
diff --git a/arch/mips/sgi-ip32/ip32-setup.c b/arch/mips/sgi-ip32/ip32-setup.c
index 8d270be58224..d10a269aeae1 100644
--- a/arch/mips/sgi-ip32/ip32-setup.c
+++ b/arch/mips/sgi-ip32/ip32-setup.c
@@ -92,7 +92,7 @@ void __init ip32_timer_setup(struct irqaction *irq)
setup_irq(IP32_R4K_TIMER_IRQ, irq);
}
-static int __init ip32_setup(void)
+void __init plat_setup(void)
{
board_be_init = ip32_be_init;
@@ -152,8 +152,4 @@ static int __init ip32_setup(void)
}
}
#endif
-
- return 0;
}
-
-early_initcall(ip32_setup);
diff --git a/arch/mips/sibyte/Kconfig b/arch/mips/sibyte/Kconfig
new file mode 100644
index 000000000000..de46f62ac462
--- /dev/null
+++ b/arch/mips/sibyte/Kconfig
@@ -0,0 +1,161 @@
+config SIBYTE_SB1250
+ bool
+ select HW_HAS_PCI
+ select SIBYTE_HAS_LDT
+ select SIBYTE_SB1xxx_SOC
+
+config SIBYTE_BCM1120
+ bool
+ select SIBYTE_BCM112X
+ select SIBYTE_SB1xxx_SOC
+
+config SIBYTE_BCM1125
+ bool
+ select HW_HAS_PCI
+ select SIBYTE_BCM112X
+ select SIBYTE_SB1xxx_SOC
+
+config SIBYTE_BCM1125H
+ bool
+ select HW_HAS_PCI
+ select SIBYTE_BCM112X
+ select SIBYTE_HAS_LDT
+ select SIBYTE_SB1xxx_SOC
+
+config SIBYTE_BCM112X
+ bool
+ select SIBYTE_SB1xxx_SOC
+
+config SIBYTE_BCM1x80
+ bool
+ select HW_HAS_PCI
+ select SIBYTE_SB1xxx_SOC
+
+config SIBYTE_BCM1x55
+ bool
+ select HW_HAS_PCI
+ select SIBYTE_SB1xxx_SOC
+
+config SIBYTE_SB1xxx_SOC
+ bool
+ depends on EXPERIMENTAL
+ select DMA_COHERENT
+ select SIBYTE_CFE
+ select SWAP_IO_SPACE
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL
+
+choice
+ prompt "SiByte SOC Stepping"
+ depends on SIBYTE_SB1xxx_SOC
+
+config CPU_SB1_PASS_1
+ bool "1250 Pass1"
+ depends on SIBYTE_SB1250
+ select CPU_HAS_PREFETCH
+
+config CPU_SB1_PASS_2_1250
+ bool "1250 An"
+ depends on SIBYTE_SB1250
+ select CPU_SB1_PASS_2
+ help
+ Also called BCM1250 Pass 2
+
+config CPU_SB1_PASS_2_2
+ bool "1250 Bn"
+ depends on SIBYTE_SB1250
+ select CPU_HAS_PREFETCH
+ help
+ Also called BCM1250 Pass 2.2
+
+config CPU_SB1_PASS_4
+ bool "1250 Cn"
+ depends on SIBYTE_SB1250
+ select CPU_HAS_PREFETCH
+ help
+ Also called BCM1250 Pass 3
+
+config CPU_SB1_PASS_2_112x
+ bool "112x Hybrid"
+ depends on SIBYTE_BCM112X
+ select CPU_SB1_PASS_2
+
+config CPU_SB1_PASS_3
+ bool "112x An"
+ depends on SIBYTE_BCM112X
+ select CPU_HAS_PREFETCH
+
+endchoice
+
+config CPU_SB1_PASS_2
+ bool
+
+config SIBYTE_HAS_LDT
+ bool
+ depends on PCI && (SIBYTE_SB1250 || SIBYTE_BCM1125H)
+ default y
+
+config SIMULATION
+ bool "Running under simulation"
+ depends on SIBYTE_SB1xxx_SOC
+ help
+ Build a kernel suitable for running under the GDB simulator.
+ Primarily adjusts the kernel's notion of time.
+
+config CONFIG_SB1_CEX_ALWAYS_FATAL
+ bool "All cache exceptions considered fatal (no recovery attempted)"
+ depends on SIBYTE_SB1xxx_SOC
+
+config CONFIG_SB1_CERR_STALL
+ bool "Stall (rather than panic) on fatal cache error"
+ depends on SIBYTE_SB1xxx_SOC
+
+config SIBYTE_CFE
+ bool "Booting from CFE"
+ depends on SIBYTE_SB1xxx_SOC
+ help
+ Make use of the CFE API for enumerating available memory,
+ controlling secondary CPUs, and possibly console output.
+
+config SIBYTE_CFE_CONSOLE
+ bool "Use firmware console"
+ depends on SIBYTE_CFE
+ help
+ Use the CFE API's console write routines during boot. Other console
+ options (VT console, sb1250 duart console, etc.) should not be
+ configured.
+
+config SIBYTE_STANDALONE
+ bool
+ depends on SIBYTE_SB1xxx_SOC && !SIBYTE_CFE
+ default y
+
+config SIBYTE_STANDALONE_RAM_SIZE
+ int "Memory size (in megabytes)"
+ depends on SIBYTE_STANDALONE
+ default "32"
+
+config SIBYTE_BUS_WATCHER
+ bool "Support for Bus Watcher statistics"
+ depends on SIBYTE_SB1xxx_SOC
+ help
+ Handle and keep statistics on the bus error interrupts (COR_ECC,
+ BAD_ECC, IO_BUS).
+
+config SIBYTE_BW_TRACE
+ bool "Capture bus trace before bus error"
+ depends on SIBYTE_BUS_WATCHER
+ help
+ Run a continuous bus trace, dumping the raw data as soon as
+ a ZBbus error is detected. Cannot work if ZBbus profiling
+ is turned on, and also will interfere with JTAG-based trace
+ buffer activity. Raw buffer data is dumped to console, and
+ must be processed off-line.
+
+config SIBYTE_SB1250_PROF
+ bool "Support for SB1/SOC profiling - SB1/SCD perf counters"
+ depends on SIBYTE_SB1xxx_SOC
+
+config SIBYTE_TBPROF
+ bool "Support for ZBbus profiling"
+ depends on SIBYTE_SB1xxx_SOC
diff --git a/arch/mips/sibyte/bcm1480/Makefile b/arch/mips/sibyte/bcm1480/Makefile
new file mode 100644
index 000000000000..538d5a51ae94
--- /dev/null
+++ b/arch/mips/sibyte/bcm1480/Makefile
@@ -0,0 +1,5 @@
+obj-y := setup.o irq.o irq_handler.o time.o
+
+obj-$(CONFIG_SMP) += smp.o
+
+EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c
new file mode 100644
index 000000000000..b2a1ba5d23df
--- /dev/null
+++ b/arch/mips/sibyte/bcm1480/irq.c
@@ -0,0 +1,476 @@
+/*
+ * Copyright (C) 2000,2001,2002,2003,2004 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/errno.h>
+#include <asm/signal.h>
+#include <asm/system.h>
+#include <asm/ptrace.h>
+#include <asm/io.h>
+
+#include <asm/sibyte/bcm1480_regs.h>
+#include <asm/sibyte/bcm1480_int.h>
+#include <asm/sibyte/bcm1480_scd.h>
+
+#include <asm/sibyte/sb1250_uart.h>
+#include <asm/sibyte/sb1250.h>
+
+/*
+ * These are the routines that handle all the low level interrupt stuff.
+ * Actions handled here are: initialization of the interrupt map, requesting of
+ * interrupt lines by handlers, dispatching if interrupts to handlers, probing
+ * for interrupt lines
+ */
+
+
+#define shutdown_bcm1480_irq disable_bcm1480_irq
+static void end_bcm1480_irq(unsigned int irq);
+static void enable_bcm1480_irq(unsigned int irq);
+static void disable_bcm1480_irq(unsigned int irq);
+static unsigned int startup_bcm1480_irq(unsigned int irq);
+static void ack_bcm1480_irq(unsigned int irq);
+#ifdef CONFIG_SMP
+static void bcm1480_set_affinity(unsigned int irq, cpumask_t mask);
+#endif
+
+#ifdef CONFIG_PCI
+extern unsigned long ht_eoi_space;
+#endif
+
+#ifdef CONFIG_KGDB
+#include <asm/gdb-stub.h>
+extern void breakpoint(void);
+static int kgdb_irq;
+#ifdef CONFIG_GDB_CONSOLE
+extern void register_gdb_console(void);
+#endif
+
+/* kgdb is on when configured. Pass "nokgdb" kernel arg to turn it off */
+static int kgdb_flag = 1;
+static int __init nokgdb(char *str)
+{
+ kgdb_flag = 0;
+ return 1;
+}
+__setup("nokgdb", nokgdb);
+
+/* Default to UART1 */
+int kgdb_port = 1;
+#ifdef CONFIG_SIBYTE_SB1250_DUART
+extern char sb1250_duart_present[];
+#endif
+#endif
+
+static struct hw_interrupt_type bcm1480_irq_type = {
+ .typename = "BCM1480-IMR",
+ .startup = startup_bcm1480_irq,
+ .shutdown = shutdown_bcm1480_irq,
+ .enable = enable_bcm1480_irq,
+ .disable = disable_bcm1480_irq,
+ .ack = ack_bcm1480_irq,
+ .end = end_bcm1480_irq,
+#ifdef CONFIG_SMP
+ .set_affinity = bcm1480_set_affinity
+#endif
+};
+
+/* Store the CPU id (not the logical number) */
+int bcm1480_irq_owner[BCM1480_NR_IRQS];
+
+DEFINE_SPINLOCK(bcm1480_imr_lock);
+
+void bcm1480_mask_irq(int cpu, int irq)
+{
+ unsigned long flags;
+ u64 cur_ints,hl_spacing;
+
+ spin_lock_irqsave(&bcm1480_imr_lock, flags);
+ hl_spacing = 0;
+ if ((irq >= BCM1480_NR_IRQS_HALF) && (irq <= BCM1480_NR_IRQS)) {
+ hl_spacing = BCM1480_IMR_HL_SPACING;
+ irq -= BCM1480_NR_IRQS_HALF;
+ }
+ cur_ints = ____raw_readq(IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + hl_spacing));
+ cur_ints |= (((u64) 1) << irq);
+ ____raw_writeq(cur_ints, IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + hl_spacing));
+ spin_unlock_irqrestore(&bcm1480_imr_lock, flags);
+}
+
+void bcm1480_unmask_irq(int cpu, int irq)
+{
+ unsigned long flags;
+ u64 cur_ints,hl_spacing;
+
+ spin_lock_irqsave(&bcm1480_imr_lock, flags);
+ hl_spacing = 0;
+ if ((irq >= BCM1480_NR_IRQS_HALF) && (irq <= BCM1480_NR_IRQS)) {
+ hl_spacing = BCM1480_IMR_HL_SPACING;
+ irq -= BCM1480_NR_IRQS_HALF;
+ }
+ cur_ints = ____raw_readq(IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + hl_spacing));
+ cur_ints &= ~(((u64) 1) << irq);
+ ____raw_writeq(cur_ints, IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + hl_spacing));
+ spin_unlock_irqrestore(&bcm1480_imr_lock, flags);
+}
+
+#ifdef CONFIG_SMP
+static void bcm1480_set_affinity(unsigned int irq, cpumask_t mask)
+{
+ int i = 0, old_cpu, cpu, int_on;
+ u64 cur_ints;
+ irq_desc_t *desc = irq_desc + irq;
+ unsigned long flags;
+ unsigned int irq_dirty;
+
+ i = first_cpu(mask);
+ if (next_cpu(i, mask) <= NR_CPUS) {
+ printk("attempted to set irq affinity for irq %d to multiple CPUs\n", irq);
+ return;
+ }
+
+ /* Convert logical CPU to physical CPU */
+ cpu = cpu_logical_map(i);
+
+ /* Protect against other affinity changers and IMR manipulation */
+ spin_lock_irqsave(&desc->lock, flags);
+ spin_lock(&bcm1480_imr_lock);
+
+ /* Swizzle each CPU's IMR (but leave the IP selection alone) */
+ old_cpu = bcm1480_irq_owner[irq];
+ irq_dirty = irq;
+ if ((irq_dirty >= BCM1480_NR_IRQS_HALF) && (irq_dirty <= BCM1480_NR_IRQS)) {
+ irq_dirty -= BCM1480_NR_IRQS_HALF;
+ }
+
+ int k;
+ for (k=0; k<2; k++) { /* Loop through high and low interrupt mask register */
+ cur_ints = ____raw_readq(IOADDR(A_BCM1480_IMR_MAPPER(old_cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + (k*BCM1480_IMR_HL_SPACING)));
+ int_on = !(cur_ints & (((u64) 1) << irq_dirty));
+ if (int_on) {
+ /* If it was on, mask it */
+ cur_ints |= (((u64) 1) << irq_dirty);
+ ____raw_writeq(cur_ints, IOADDR(A_BCM1480_IMR_MAPPER(old_cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + (k*BCM1480_IMR_HL_SPACING)));
+ }
+ bcm1480_irq_owner[irq] = cpu;
+ if (int_on) {
+ /* unmask for the new CPU */
+ cur_ints = ____raw_readq(IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + (k*BCM1480_IMR_HL_SPACING)));
+ cur_ints &= ~(((u64) 1) << irq_dirty);
+ ____raw_writeq(cur_ints, IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + (k*BCM1480_IMR_HL_SPACING)));
+ }
+ }
+ spin_unlock(&bcm1480_imr_lock);
+ spin_unlock_irqrestore(&desc->lock, flags);
+}
+#endif
+
+
+/* Defined in arch/mips/sibyte/bcm1480/irq_handler.S */
+extern void bcm1480_irq_handler(void);
+
+/*****************************************************************************/
+
+static unsigned int startup_bcm1480_irq(unsigned int irq)
+{
+ bcm1480_unmask_irq(bcm1480_irq_owner[irq], irq);
+
+ return 0; /* never anything pending */
+}
+
+
+static void disable_bcm1480_irq(unsigned int irq)
+{
+ bcm1480_mask_irq(bcm1480_irq_owner[irq], irq);
+}
+
+static void enable_bcm1480_irq(unsigned int irq)
+{
+ bcm1480_unmask_irq(bcm1480_irq_owner[irq], irq);
+}
+
+
+static void ack_bcm1480_irq(unsigned int irq)
+{
+ u64 pending;
+ unsigned int irq_dirty;
+
+ /*
+ * If the interrupt was an HT interrupt, now is the time to
+ * clear it. NOTE: we assume the HT bridge was set up to
+ * deliver the interrupts to all CPUs (which makes affinity
+ * changing easier for us)
+ */
+ irq_dirty = irq;
+ if ((irq_dirty >= BCM1480_NR_IRQS_HALF) && (irq_dirty <= BCM1480_NR_IRQS)) {
+ irq_dirty -= BCM1480_NR_IRQS_HALF;
+ }
+ int k;
+ for (k=0; k<2; k++) { /* Loop through high and low LDT interrupts */
+ pending = __raw_readq(IOADDR(A_BCM1480_IMR_REGISTER(bcm1480_irq_owner[irq],
+ R_BCM1480_IMR_LDT_INTERRUPT_H + (k*BCM1480_IMR_HL_SPACING))));
+ pending &= ((u64)1 << (irq_dirty));
+ if (pending) {
+#ifdef CONFIG_SMP
+ int i;
+ for (i=0; i<NR_CPUS; i++) {
+ /*
+ * Clear for all CPUs so an affinity switch
+ * doesn't find an old status
+ */
+ __raw_writeq(pending, IOADDR(A_BCM1480_IMR_REGISTER(cpu_logical_map(i),
+ R_BCM1480_IMR_LDT_INTERRUPT_CLR_H + (k*BCM1480_IMR_HL_SPACING))));
+ }
+#else
+ __raw_writeq(pending, IOADDR(A_BCM1480_IMR_REGISTER(0, R_BCM1480_IMR_LDT_INTERRUPT_CLR_H + (k*BCM1480_IMR_HL_SPACING))));
+#endif
+
+ /*
+ * Generate EOI. For Pass 1 parts, EOI is a nop. For
+ * Pass 2, the LDT world may be edge-triggered, but
+ * this EOI shouldn't hurt. If they are
+ * level-sensitive, the EOI is required.
+ */
+#ifdef CONFIG_PCI
+ if (ht_eoi_space)
+ *(uint32_t *)(ht_eoi_space+(irq<<16)+(7<<2)) = 0;
+#endif
+ }
+ }
+ bcm1480_mask_irq(bcm1480_irq_owner[irq], irq);
+}
+
+
+static void end_bcm1480_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+ bcm1480_unmask_irq(bcm1480_irq_owner[irq], irq);
+ }
+}
+
+
+void __init init_bcm1480_irqs(void)
+{
+ int i;
+
+ for (i = 0; i < NR_IRQS; i++) {
+ irq_desc[i].status = IRQ_DISABLED;
+ irq_desc[i].action = 0;
+ irq_desc[i].depth = 1;
+ if (i < BCM1480_NR_IRQS) {
+ irq_desc[i].handler = &bcm1480_irq_type;
+ bcm1480_irq_owner[i] = 0;
+ } else {
+ irq_desc[i].handler = &no_irq_type;
+ }
+ }
+}
+
+
+static irqreturn_t bcm1480_dummy_handler(int irq, void *dev_id,
+ struct pt_regs *regs)
+{
+ return IRQ_NONE;
+}
+
+static struct irqaction bcm1480_dummy_action = {
+ .handler = bcm1480_dummy_handler,
+ .flags = 0,
+ .mask = CPU_MASK_NONE,
+ .name = "bcm1480-private",
+ .next = NULL,
+ .dev_id = 0
+};
+
+int bcm1480_steal_irq(int irq)
+{
+ irq_desc_t *desc = irq_desc + irq;
+ unsigned long flags;
+ int retval = 0;
+
+ if (irq >= BCM1480_NR_IRQS)
+ return -EINVAL;
+
+ spin_lock_irqsave(&desc->lock,flags);
+ /* Don't allow sharing at all for these */
+ if (desc->action != NULL)
+ retval = -EBUSY;
+ else {
+ desc->action = &bcm1480_dummy_action;
+ desc->depth = 0;
+ }
+ spin_unlock_irqrestore(&desc->lock,flags);
+ return 0;
+}
+
+/*
+ * init_IRQ is called early in the boot sequence from init/main.c. It
+ * is responsible for setting up the interrupt mapper and installing the
+ * handler that will be responsible for dispatching interrupts to the
+ * "right" place.
+ */
+/*
+ * For now, map all interrupts to IP[2]. We could save
+ * some cycles by parceling out system interrupts to different
+ * IP lines, but keep it simple for bringup. We'll also direct
+ * all interrupts to a single CPU; we should probably route
+ * PCI and LDT to one cpu and everything else to the other
+ * to balance the load a bit.
+ *
+ * On the second cpu, everything is set to IP5, which is
+ * ignored, EXCEPT the mailbox interrupt. That one is
+ * set to IP[2] so it is handled. This is needed so we
+ * can do cross-cpu function calls, as requred by SMP
+ */
+
+#define IMR_IP2_VAL K_BCM1480_INT_MAP_I0
+#define IMR_IP3_VAL K_BCM1480_INT_MAP_I1
+#define IMR_IP4_VAL K_BCM1480_INT_MAP_I2
+#define IMR_IP5_VAL K_BCM1480_INT_MAP_I3
+#define IMR_IP6_VAL K_BCM1480_INT_MAP_I4
+
+void __init arch_init_irq(void)
+{
+
+ unsigned int i, cpu;
+ u64 tmp;
+ unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
+ STATUSF_IP1 | STATUSF_IP0;
+
+ /* Default everything to IP2 */
+ /* Start with _high registers which has no bit 0 interrupt source */
+ for (i = 1; i < BCM1480_NR_IRQS_HALF; i++) { /* was I0 */
+ for (cpu = 0; cpu < 4; cpu++) {
+ __raw_writeq(IMR_IP2_VAL,
+ IOADDR(A_BCM1480_IMR_REGISTER(cpu,
+ R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) + (i << 3)));
+ }
+ }
+
+ /* Now do _low registers */
+ for (i = 0; i < BCM1480_NR_IRQS_HALF; i++) {
+ for (cpu = 0; cpu < 4; cpu++) {
+ __raw_writeq(IMR_IP2_VAL,
+ IOADDR(A_BCM1480_IMR_REGISTER(cpu,
+ R_BCM1480_IMR_INTERRUPT_MAP_BASE_L) + (i << 3)));
+ }
+ }
+
+ init_bcm1480_irqs();
+
+ /*
+ * Map the high 16 bits of mailbox_0 registers to IP[3], for
+ * inter-cpu messages
+ */
+ /* Was I1 */
+ for (cpu = 0; cpu < 4; cpu++) {
+ __raw_writeq(IMR_IP3_VAL, IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) +
+ (K_BCM1480_INT_MBOX_0_0 << 3)));
+ }
+
+
+ /* Clear the mailboxes. The firmware may leave them dirty */
+ for (cpu = 0; cpu < 4; cpu++) {
+ __raw_writeq(0xffffffffffffffffULL,
+ IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_MAILBOX_0_CLR_CPU)));
+ __raw_writeq(0xffffffffffffffffULL,
+ IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_MAILBOX_1_CLR_CPU)));
+ }
+
+
+ /* Mask everything except the high 16 bit of mailbox_0 registers for all cpus */
+ tmp = ~((u64) 0) ^ ( (((u64) 1) << K_BCM1480_INT_MBOX_0_0));
+ for (cpu = 0; cpu < 4; cpu++) {
+ __raw_writeq(tmp, IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_INTERRUPT_MASK_H)));
+ }
+ tmp = ~((u64) 0);
+ for (cpu = 0; cpu < 4; cpu++) {
+ __raw_writeq(tmp, IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_INTERRUPT_MASK_L)));
+ }
+
+ bcm1480_steal_irq(K_BCM1480_INT_MBOX_0_0);
+
+ /*
+ * Note that the timer interrupts are also mapped, but this is
+ * done in bcm1480_time_init(). Also, the profiling driver
+ * does its own management of IP7.
+ */
+
+#ifdef CONFIG_KGDB
+ imask |= STATUSF_IP6;
+#endif
+ /* Enable necessary IPs, disable the rest */
+ change_c0_status(ST0_IM, imask);
+ set_except_vector(0, bcm1480_irq_handler);
+
+#ifdef CONFIG_KGDB
+ if (kgdb_flag) {
+ kgdb_irq = K_BCM1480_INT_UART_0 + kgdb_port;
+
+#ifdef CONFIG_SIBYTE_SB1250_DUART
+ sb1250_duart_present[kgdb_port] = 0;
+#endif
+ /* Setup uart 1 settings, mapper */
+ /* QQQ FIXME */
+ __raw_writeq(M_DUART_IMR_BRK, IO_SPACE_BASE + A_DUART_IMRREG(kgdb_port));
+
+ bcm1480_steal_irq(kgdb_irq);
+ __raw_writeq(IMR_IP6_VAL,
+ IO_SPACE_BASE + A_BCM1480_IMR_REGISTER(0, R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) +
+ (kgdb_irq<<3));
+ bcm1480_unmask_irq(0, kgdb_irq);
+
+#ifdef CONFIG_GDB_CONSOLE
+ register_gdb_console();
+#endif
+ prom_printf("Waiting for GDB on UART port %d\n", kgdb_port);
+ set_debug_traps();
+ breakpoint();
+ }
+#endif
+}
+
+#ifdef CONFIG_KGDB
+
+#include <linux/delay.h>
+
+#define duart_out(reg, val) csr_out32(val, IOADDR(A_DUART_CHANREG(kgdb_port,reg)))
+#define duart_in(reg) csr_in32(IOADDR(A_DUART_CHANREG(kgdb_port,reg)))
+
+void bcm1480_kgdb_interrupt(struct pt_regs *regs)
+{
+ /*
+ * Clear break-change status (allow some time for the remote
+ * host to stop the break, since we would see another
+ * interrupt on the end-of-break too)
+ */
+ kstat.irqs[smp_processor_id()][kgdb_irq]++;
+ mdelay(500);
+ duart_out(R_DUART_CMD, V_DUART_MISC_CMD_RESET_BREAK_INT |
+ M_DUART_RX_EN | M_DUART_TX_EN);
+ set_async_breakpoint(&regs->cp0_epc);
+}
+
+#endif /* CONFIG_KGDB */
diff --git a/arch/mips/sibyte/bcm1480/irq_handler.S b/arch/mips/sibyte/bcm1480/irq_handler.S
new file mode 100644
index 000000000000..408db88d050f
--- /dev/null
+++ b/arch/mips/sibyte/bcm1480/irq_handler.S
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2000,2001,2002,2003,2004 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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.
+ */
+
+/*
+ * bcm1480_irq_handler() is the routine that is actually called when an
+ * interrupt occurs. It is installed as the exception vector handler in
+ * init_IRQ() in arch/mips/sibyte/bcm1480/irq.c
+ *
+ * In the handle we figure out which interrupts need handling, and use that
+ * to call the dispatcher, which will take care of actually calling
+ * registered handlers
+ *
+ * Note that we take care of all raised interrupts in one go at the handler.
+ * This is more BSDish than the Indy code, and also, IMHO, more sane.
+ */
+#include <linux/config.h>
+
+#include <asm/addrspace.h>
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/sibyte/sb1250_defs.h>
+#include <asm/sibyte/bcm1480_regs.h>
+#include <asm/sibyte/bcm1480_int.h>
+
+/*
+ * What a pain. We have to be really careful saving the upper 32 bits of any
+ * register across function calls if we don't want them trashed--since were
+ * running in -o32, the calling routing never saves the full 64 bits of a
+ * register across a function call. Being the interrupt handler, we're
+ * guaranteed that interrupts are disabled during this code so we don't have
+ * to worry about random interrupts blasting the high 32 bits.
+ */
+
+ .text
+ .set push
+ .set noreorder
+ .set noat
+ .set mips64
+ #.set mips4
+ .align 5
+ NESTED(bcm1480_irq_handler, PT_SIZE, sp)
+ SAVE_ALL
+ CLI
+
+#ifdef CONFIG_SIBYTE_BCM1480_PROF
+ /* Set compare to count to silence count/compare timer interrupts */
+ mfc0 t1, CP0_COUNT
+ mtc0 t1, CP0_COMPARE /* pause to clear IP[7] bit of cause ? */
+#endif
+ /* Read cause */
+ mfc0 s0, CP0_CAUSE
+
+#ifdef CONFIG_SIBYTE_BCM1480_PROF
+ /* Cpu performance counter interrupt is routed to IP[7] */
+ andi t1, s0, CAUSEF_IP7
+ beqz t1, 0f
+ srl t1, s0, (CAUSEB_BD-2) /* Shift BD bit to bit 2 */
+ and t1, t1, 0x4 /* mask to get just BD bit */
+#ifdef CONFIG_MIPS64
+ dmfc0 a0, CP0_EPC
+ daddu a0, a0, t1 /* a0 = EPC + (BD ? 4 : 0) */
+#else
+ mfc0 a0, CP0_EPC
+ addu a0, a0, t1 /* a0 = EPC + (BD ? 4 : 0) */
+#endif
+ jal sbprof_cpu_intr
+ nop
+ j ret_from_irq
+ nop
+0:
+#endif
+
+ /* Timer interrupt is routed to IP[4] */
+ andi t1, s0, CAUSEF_IP4
+ beqz t1, 1f
+ nop
+ jal bcm1480_timer_interrupt
+ move a0, sp /* Pass the registers along */
+ j ret_from_irq
+ nop /* delay slot */
+1:
+
+#ifdef CONFIG_SMP
+ /* Mailbox interrupt is routed to IP[3] */
+ andi t1, s0, CAUSEF_IP3
+ beqz t1, 2f
+ nop
+ jal bcm1480_mailbox_interrupt
+ move a0, sp
+ j ret_from_irq
+ nop /* delay slot */
+2:
+#endif
+
+#ifdef CONFIG_KGDB
+ /* KGDB (uart 1) interrupt is routed to IP[6] */
+ andi t1, s0, CAUSEF_IP6
+ beqz t1, 3f
+ nop /* delay slot */
+ jal bcm1480_kgdb_interrupt
+ move a0, sp
+ j ret_from_irq
+ nop /* delay slot */
+3:
+#endif
+
+ and t1, s0, CAUSEF_IP2
+ beqz t1, 9f
+ nop
+
+ /*
+ * Default...we've hit an IP[2] interrupt, which means we've got
+ * to check the 1480 interrupt registers to figure out what to do
+ * Need to detect which CPU we're on, now that smp_affinity is
+ * supported.
+ */
+ PTR_LA v0, CKSEG1 + A_BCM1480_IMR_CPU0_BASE
+#ifdef CONFIG_SMP
+ lw t1, TI_CPU($28)
+ sll t1, t1, BCM1480_IMR_REGISTER_SPACING_SHIFT
+ addu v0, v0, t1
+#endif
+
+ /* Read IP[2] status (get both high and low halves of status) */
+ ld s0, R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H(v0)
+ ld s1, R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L(v0)
+
+ move s2, zero /* intr number */
+ li s3, 64
+
+ beqz s0, 9f /* No interrupts. Return. */
+ move a1, sp
+
+ xori s4, s0, 1 /* if s0 (_H) == 1, it's a low intr, so... */
+ movz s2, s3, s4 /* start the intr number at 64, and */
+ movz s0, s1, s4 /* look at the low status value. */
+
+ dclz s1, s0 /* Find the next interrupt. */
+ dsubu a0, zero, s1
+ daddiu a0, a0, 63
+ jal do_IRQ
+ daddu a0, a0, s2
+
+9: j ret_from_irq
+ nop
+
+ .set pop
+ END(bcm1480_irq_handler)
diff --git a/arch/mips/sibyte/bcm1480/setup.c b/arch/mips/sibyte/bcm1480/setup.c
new file mode 100644
index 000000000000..d90a0b87874c
--- /dev/null
+++ b/arch/mips/sibyte/bcm1480/setup.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2000,2001,2002,2003,2004 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/reboot.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+#include <asm/mipsregs.h>
+#include <asm/io.h>
+#include <asm/sibyte/sb1250.h>
+
+#include <asm/sibyte/bcm1480_regs.h>
+#include <asm/sibyte/bcm1480_scd.h>
+#include <asm/sibyte/sb1250_scd.h>
+
+unsigned int sb1_pass;
+unsigned int soc_pass;
+unsigned int soc_type;
+unsigned int periph_rev;
+unsigned int zbbus_mhz;
+
+static unsigned int part_type;
+
+static char *soc_str;
+static char *pass_str;
+
+static inline int setup_bcm1x80_bcm1x55(void);
+
+/* Setup code likely to be common to all SiByte platforms */
+
+static inline int sys_rev_decode(void)
+{
+ int ret = 0;
+
+ switch (soc_type) {
+ case K_SYS_SOC_TYPE_BCM1x80:
+ if (part_type == K_SYS_PART_BCM1480)
+ soc_str = "BCM1480";
+ else if (part_type == K_SYS_PART_BCM1280)
+ soc_str = "BCM1280";
+ else
+ soc_str = "BCM1x80";
+ ret = setup_bcm1x80_bcm1x55();
+ break;
+
+ case K_SYS_SOC_TYPE_BCM1x55:
+ if (part_type == K_SYS_PART_BCM1455)
+ soc_str = "BCM1455";
+ else if (part_type == K_SYS_PART_BCM1255)
+ soc_str = "BCM1255";
+ else
+ soc_str = "BCM1x55";
+ ret = setup_bcm1x80_bcm1x55();
+ break;
+
+ default:
+ prom_printf("Unknown part type %x\n", part_type);
+ ret = 1;
+ break;
+ }
+ return ret;
+}
+
+static inline int setup_bcm1x80_bcm1x55(void)
+{
+ int ret = 0;
+
+ switch (soc_pass) {
+ case K_SYS_REVISION_BCM1480_S0:
+ periph_rev = 1;
+ pass_str = "S0 (pass1)";
+ break;
+ case K_SYS_REVISION_BCM1480_A1:
+ periph_rev = 1;
+ pass_str = "A1 (pass1)";
+ break;
+ case K_SYS_REVISION_BCM1480_A2:
+ periph_rev = 1;
+ pass_str = "A2 (pass1)";
+ break;
+ case K_SYS_REVISION_BCM1480_A3:
+ periph_rev = 1;
+ pass_str = "A3 (pass1)";
+ break;
+ case K_SYS_REVISION_BCM1480_B0:
+ periph_rev = 1;
+ pass_str = "B0 (pass2)";
+ break;
+ default:
+ prom_printf("Unknown %s rev %x\n", soc_str, soc_pass);
+ periph_rev = 1;
+ pass_str = "Unknown Revision";
+ break;
+ }
+ return ret;
+}
+
+void bcm1480_setup(void)
+{
+ uint64_t sys_rev;
+ int plldiv;
+
+ sb1_pass = read_c0_prid() & 0xff;
+ sys_rev = __raw_readq(IOADDR(A_SCD_SYSTEM_REVISION));
+ soc_type = SYS_SOC_TYPE(sys_rev);
+ part_type = G_SYS_PART(sys_rev);
+ soc_pass = G_SYS_REVISION(sys_rev);
+
+ if (sys_rev_decode()) {
+ prom_printf("Restart after failure to identify SiByte chip\n");
+ machine_restart(NULL);
+ }
+
+ plldiv = G_BCM1480_SYS_PLL_DIV(__raw_readq(IOADDR(A_SCD_SYSTEM_CFG)));
+ zbbus_mhz = ((plldiv >> 1) * 50) + ((plldiv & 1) * 25);
+
+ prom_printf("Broadcom SiByte %s %s @ %d MHz (SB-1A rev %d)\n",
+ soc_str, pass_str, zbbus_mhz * 2, sb1_pass);
+ prom_printf("Board type: %s\n", get_system_type());
+}
diff --git a/arch/mips/sibyte/bcm1480/smp.c b/arch/mips/sibyte/bcm1480/smp.c
new file mode 100644
index 000000000000..584a4b33faac
--- /dev/null
+++ b/arch/mips/sibyte/bcm1480/smp.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2001,2002,2004 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/smp.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/bcm1480_regs.h>
+#include <asm/sibyte/bcm1480_int.h>
+
+extern void smp_call_function_interrupt(void);
+
+/*
+ * These are routines for dealing with the bcm1480 smp capabilities
+ * independent of board/firmware
+ */
+
+static void *mailbox_0_set_regs[] = {
+ IOADDR(A_BCM1480_IMR_CPU0_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU),
+ IOADDR(A_BCM1480_IMR_CPU1_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU),
+ IOADDR(A_BCM1480_IMR_CPU2_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU),
+ IOADDR(A_BCM1480_IMR_CPU3_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU),
+};
+
+static void *mailbox_0_clear_regs[] = {
+ IOADDR(A_BCM1480_IMR_CPU0_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU),
+ IOADDR(A_BCM1480_IMR_CPU1_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU),
+ IOADDR(A_BCM1480_IMR_CPU2_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU),
+ IOADDR(A_BCM1480_IMR_CPU3_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU),
+};
+
+static void *mailbox_0_regs[] = {
+ IOADDR(A_BCM1480_IMR_CPU0_BASE + R_BCM1480_IMR_MAILBOX_0_CPU),
+ IOADDR(A_BCM1480_IMR_CPU1_BASE + R_BCM1480_IMR_MAILBOX_0_CPU),
+ IOADDR(A_BCM1480_IMR_CPU2_BASE + R_BCM1480_IMR_MAILBOX_0_CPU),
+ IOADDR(A_BCM1480_IMR_CPU3_BASE + R_BCM1480_IMR_MAILBOX_0_CPU),
+};
+
+/*
+ * SMP init and finish on secondary CPUs
+ */
+void bcm1480_smp_init(void)
+{
+ unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
+ STATUSF_IP1 | STATUSF_IP0;
+
+ /* Set interrupt mask, but don't enable */
+ change_c0_status(ST0_IM, imask);
+}
+
+void bcm1480_smp_finish(void)
+{
+ extern void bcm1480_time_init(void);
+ bcm1480_time_init();
+ local_irq_enable();
+}
+
+/*
+ * These are routines for dealing with the sb1250 smp capabilities
+ * independent of board/firmware
+ */
+
+/*
+ * Simple enough; everything is set up, so just poke the appropriate mailbox
+ * register, and we should be set
+ */
+void core_send_ipi(int cpu, unsigned int action)
+{
+ __raw_writeq((((u64)action)<< 48), mailbox_0_set_regs[cpu]);
+}
+
+void bcm1480_mailbox_interrupt(struct pt_regs *regs)
+{
+ int cpu = smp_processor_id();
+ unsigned int action;
+
+ kstat_this_cpu.irqs[K_BCM1480_INT_MBOX_0_0]++;
+ /* Load the mailbox register to figure out what we're supposed to do */
+ action = (__raw_readq(mailbox_0_regs[cpu]) >> 48) & 0xffff;
+
+ /* Clear the mailbox to clear the interrupt */
+ __raw_writeq(((u64)action)<<48, mailbox_0_clear_regs[cpu]);
+
+ /*
+ * Nothing to do for SMP_RESCHEDULE_YOURSELF; returning from the
+ * interrupt will do the reschedule for us
+ */
+
+ if (action & SMP_CALL_FUNCTION)
+ smp_call_function_interrupt();
+}
diff --git a/arch/mips/sibyte/bcm1480/time.c b/arch/mips/sibyte/bcm1480/time.c
new file mode 100644
index 000000000000..e545752695a1
--- /dev/null
+++ b/arch/mips/sibyte/bcm1480/time.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2000,2001,2004 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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.
+ */
+
+/*
+ * These are routines to set up and handle interrupts from the
+ * bcm1480 general purpose timer 0. We're using the timer as a
+ * system clock, so we set it up to run at 100 Hz. On every
+ * interrupt, we update our idea of what the time of day is,
+ * then call do_timer() in the architecture-independent kernel
+ * code to do general bookkeeping (e.g. update jiffies, run
+ * bottom halves, etc.)
+ */
+#include <linux/config.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/irq.h>
+#include <asm/ptrace.h>
+#include <asm/addrspace.h>
+#include <asm/time.h>
+#include <asm/io.h>
+
+#include <asm/sibyte/bcm1480_regs.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/bcm1480_int.h>
+#include <asm/sibyte/bcm1480_scd.h>
+
+#include <asm/sibyte/sb1250.h>
+
+
+#define IMR_IP2_VAL K_BCM1480_INT_MAP_I0
+#define IMR_IP3_VAL K_BCM1480_INT_MAP_I1
+#define IMR_IP4_VAL K_BCM1480_INT_MAP_I2
+
+extern int bcm1480_steal_irq(int irq);
+
+void bcm1480_time_init(void)
+{
+ int cpu = smp_processor_id();
+ int irq = K_BCM1480_INT_TIMER_0+cpu;
+
+ /* Only have 4 general purpose timers */
+ if (cpu > 3) {
+ BUG();
+ }
+
+ if (!cpu) {
+ /* Use our own gettimeoffset() routine */
+ do_gettimeoffset = bcm1480_gettimeoffset;
+ }
+
+ bcm1480_mask_irq(cpu, irq);
+
+ /* Map the timer interrupt to ip[4] of this cpu */
+ __raw_writeq(IMR_IP4_VAL, IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_INTERRUPT_MAP_BASE_H)
+ + (irq<<3)));
+
+ /* the general purpose timer ticks at 1 Mhz independent of the rest of the system */
+ /* Disable the timer and set up the count */
+ __raw_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+ __raw_writeq(
+#ifndef CONFIG_SIMULATION
+ 1000000/HZ
+#else
+ 50000/HZ
+#endif
+ , IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
+
+ /* Set the timer running */
+ __raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
+ IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+
+ bcm1480_unmask_irq(cpu, irq);
+ bcm1480_steal_irq(irq);
+ /*
+ * This interrupt is "special" in that it doesn't use the request_irq
+ * way to hook the irq line. The timer interrupt is initialized early
+ * enough to make this a major pain, and it's also firing enough to
+ * warrant a bit of special case code. bcm1480_timer_interrupt is
+ * called directly from irq_handler.S when IP[4] is set during an
+ * interrupt
+ */
+}
+
+#include <asm/sibyte/sb1250.h>
+
+void bcm1480_timer_interrupt(struct pt_regs *regs)
+{
+ int cpu = smp_processor_id();
+ int irq = K_BCM1480_INT_TIMER_0+cpu;
+
+ /* Reset the timer */
+ __raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
+ IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+
+ /*
+ * CPU 0 handles the global timer interrupt job
+ */
+ if (cpu == 0) {
+ ll_timer_interrupt(irq, regs);
+ }
+
+ /*
+ * every CPU should do profiling and process accouting
+ */
+ ll_local_timer_interrupt(irq, regs);
+}
+
+/*
+ * We use our own do_gettimeoffset() instead of the generic one,
+ * because the generic one does not work for SMP case.
+ * In addition, since we use general timer 0 for system time,
+ * we can get accurate intra-jiffy offset without calibration.
+ */
+unsigned long bcm1480_gettimeoffset(void)
+{
+ unsigned long count =
+ __raw_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT)));
+
+ return 1000000/HZ - count;
+}
diff --git a/arch/mips/sibyte/cfe/smp.c b/arch/mips/sibyte/cfe/smp.c
index e44ce1a9eea9..e8485124b8fc 100644
--- a/arch/mips/sibyte/cfe/smp.c
+++ b/arch/mips/sibyte/cfe/smp.c
@@ -70,8 +70,15 @@ void prom_boot_secondary(int cpu, struct task_struct *idle)
*/
void prom_init_secondary(void)
{
+#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
+ extern void bcm1480_smp_init(void);
+ bcm1480_smp_init();
+#elif defined(CONFIG_SIBYTE_SB1250)
extern void sb1250_smp_init(void);
sb1250_smp_init();
+#else
+#error invalid SMP configuration
+#endif
}
/*
@@ -80,8 +87,15 @@ void prom_init_secondary(void)
*/
void prom_smp_finish(void)
{
+#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
+ extern void bcm1480_smp_finish(void);
+ bcm1480_smp_finish();
+#elif defined(CONFIG_SIBYTE_SB1250)
extern void sb1250_smp_finish(void);
sb1250_smp_finish();
+#else
+#error invalid SMP configuration
+#endif
}
/*
diff --git a/arch/mips/sibyte/sb1250/bcm1250_tbprof.c b/arch/mips/sibyte/sb1250/bcm1250_tbprof.c
index 7f813ae9eaff..992e0d8dbb67 100644
--- a/arch/mips/sibyte/sb1250/bcm1250_tbprof.c
+++ b/arch/mips/sibyte/sb1250/bcm1250_tbprof.c
@@ -28,6 +28,8 @@
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/reboot.h>
+#include <linux/smp_lock.h>
+#include <linux/wait.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/sibyte/sb1250.h>
@@ -64,24 +66,25 @@ static void arm_tb(void)
u_int64_t tb_options = M_SCD_TRACE_CFG_FREEZE_FULL;
/* Generate an SCD_PERFCNT interrupt in TB_PERIOD Zclks to
trigger start of trace. XXX vary sampling period */
- bus_writeq(0, IOADDR(A_SCD_PERF_CNT_1));
- scdperfcnt = bus_readq(IOADDR(A_SCD_PERF_CNT_CFG));
+ __raw_writeq(0, IOADDR(A_SCD_PERF_CNT_1));
+ scdperfcnt = __raw_readq(IOADDR(A_SCD_PERF_CNT_CFG));
/* Unfortunately, in Pass 2 we must clear all counters to knock down
a previous interrupt request. This means that bus profiling
requires ALL of the SCD perf counters. */
- bus_writeq((scdperfcnt & ~M_SPC_CFG_SRC1) | // keep counters 0,2,3 as is
- M_SPC_CFG_ENABLE | // enable counting
- M_SPC_CFG_CLEAR | // clear all counters
- V_SPC_CFG_SRC1(1), // counter 1 counts cycles
- IOADDR(A_SCD_PERF_CNT_CFG));
- bus_writeq(next, IOADDR(A_SCD_PERF_CNT_1));
+ __raw_writeq((scdperfcnt & ~M_SPC_CFG_SRC1) |
+ // keep counters 0,2,3 as is
+ M_SPC_CFG_ENABLE | // enable counting
+ M_SPC_CFG_CLEAR | // clear all counters
+ V_SPC_CFG_SRC1(1), // counter 1 counts cycles
+ IOADDR(A_SCD_PERF_CNT_CFG));
+ __raw_writeq(next, IOADDR(A_SCD_PERF_CNT_1));
/* Reset the trace buffer */
- bus_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
+ __raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
#if 0 && defined(M_SCD_TRACE_CFG_FORCECNT)
/* XXXKW may want to expose control to the data-collector */
tb_options |= M_SCD_TRACE_CFG_FORCECNT;
#endif
- bus_writeq(tb_options, IOADDR(A_SCD_TRACE_CFG));
+ __raw_writeq(tb_options, IOADDR(A_SCD_TRACE_CFG));
sbp.tb_armed = 1;
}
@@ -93,23 +96,30 @@ static irqreturn_t sbprof_tb_intr(int irq, void *dev_id, struct pt_regs *regs)
/* XXX should use XKPHYS to make writes bypass L2 */
u_int64_t *p = sbp.sbprof_tbbuf[sbp.next_tb_sample++];
/* Read out trace */
- bus_writeq(M_SCD_TRACE_CFG_START_READ, IOADDR(A_SCD_TRACE_CFG));
+ __raw_writeq(M_SCD_TRACE_CFG_START_READ,
+ IOADDR(A_SCD_TRACE_CFG));
__asm__ __volatile__ ("sync" : : : "memory");
/* Loop runs backwards because bundles are read out in reverse order */
for (i = 256 * 6; i > 0; i -= 6) {
// Subscripts decrease to put bundle in the order
// t0 lo, t0 hi, t1 lo, t1 hi, t2 lo, t2 hi
- p[i-1] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t2 hi
- p[i-2] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t2 lo
- p[i-3] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t1 hi
- p[i-4] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t1 lo
- p[i-5] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t0 hi
- p[i-6] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t0 lo
+ p[i - 1] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
+ // read t2 hi
+ p[i - 2] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
+ // read t2 lo
+ p[i - 3] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
+ // read t1 hi
+ p[i - 4] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
+ // read t1 lo
+ p[i - 5] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
+ // read t0 hi
+ p[i - 6] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
+ // read t0 lo
}
if (!sbp.tb_enable) {
DBG(printk(DEVNAME ": tb_intr shutdown\n"));
- bus_writeq(M_SCD_TRACE_CFG_RESET,
- IOADDR(A_SCD_TRACE_CFG));
+ __raw_writeq(M_SCD_TRACE_CFG_RESET,
+ IOADDR(A_SCD_TRACE_CFG));
sbp.tb_armed = 0;
wake_up(&sbp.tb_sync);
} else {
@@ -118,7 +128,7 @@ static irqreturn_t sbprof_tb_intr(int irq, void *dev_id, struct pt_regs *regs)
} else {
/* No more trace buffer samples */
DBG(printk(DEVNAME ": tb_intr full\n"));
- bus_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
+ __raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
sbp.tb_armed = 0;
if (!sbp.tb_enable) {
wake_up(&sbp.tb_sync);
@@ -152,13 +162,11 @@ int sbprof_zbprof_start(struct file *filp)
return -EBUSY;
}
/* Make sure there isn't a perf-cnt interrupt waiting */
- scdperfcnt = bus_readq(IOADDR(A_SCD_PERF_CNT_CFG));
+ scdperfcnt = __raw_readq(IOADDR(A_SCD_PERF_CNT_CFG));
/* Disable and clear counters, override SRC_1 */
- bus_writeq((scdperfcnt & ~(M_SPC_CFG_SRC1 | M_SPC_CFG_ENABLE)) |
- M_SPC_CFG_ENABLE |
- M_SPC_CFG_CLEAR |
- V_SPC_CFG_SRC1(1),
- IOADDR(A_SCD_PERF_CNT_CFG));
+ __raw_writeq((scdperfcnt & ~(M_SPC_CFG_SRC1 | M_SPC_CFG_ENABLE)) |
+ M_SPC_CFG_ENABLE | M_SPC_CFG_CLEAR | V_SPC_CFG_SRC1(1),
+ IOADDR(A_SCD_PERF_CNT_CFG));
/* We grab this interrupt to prevent others from trying to use
it, even though we don't want to service the interrupts
@@ -172,55 +180,55 @@ int sbprof_zbprof_start(struct file *filp)
/* I need the core to mask these, but the interrupt mapper to
pass them through. I am exploiting my knowledge that
cp0_status masks out IP[5]. krw */
- bus_writeq(K_INT_MAP_I3,
- IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
- (K_INT_PERF_CNT << 3)));
+ __raw_writeq(K_INT_MAP_I3,
+ IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
+ (K_INT_PERF_CNT << 3)));
/* Initialize address traps */
- bus_writeq(0, IOADDR(A_ADDR_TRAP_UP_0));
- bus_writeq(0, IOADDR(A_ADDR_TRAP_UP_1));
- bus_writeq(0, IOADDR(A_ADDR_TRAP_UP_2));
- bus_writeq(0, IOADDR(A_ADDR_TRAP_UP_3));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_0));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_1));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_2));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_3));
- bus_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_0));
- bus_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_1));
- bus_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_2));
- bus_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_3));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_0));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_1));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_2));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_3));
- bus_writeq(0, IOADDR(A_ADDR_TRAP_CFG_0));
- bus_writeq(0, IOADDR(A_ADDR_TRAP_CFG_1));
- bus_writeq(0, IOADDR(A_ADDR_TRAP_CFG_2));
- bus_writeq(0, IOADDR(A_ADDR_TRAP_CFG_3));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_0));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_1));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_2));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_3));
/* Initialize Trace Event 0-7 */
// when interrupt
- bus_writeq(M_SCD_TREVT_INTERRUPT, IOADDR(A_SCD_TRACE_EVENT_0));
- bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_1));
- bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_2));
- bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_3));
- bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_4));
- bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_5));
- bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_6));
- bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_7));
+ __raw_writeq(M_SCD_TREVT_INTERRUPT, IOADDR(A_SCD_TRACE_EVENT_0));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_1));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_2));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_3));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_4));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_5));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_6));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_7));
/* Initialize Trace Sequence 0-7 */
// Start on event 0 (interrupt)
- bus_writeq(V_SCD_TRSEQ_FUNC_START | 0x0fff,
- IOADDR(A_SCD_TRACE_SEQUENCE_0));
+ __raw_writeq(V_SCD_TRSEQ_FUNC_START | 0x0fff,
+ IOADDR(A_SCD_TRACE_SEQUENCE_0));
// dsamp when d used | asamp when a used
- bus_writeq(M_SCD_TRSEQ_ASAMPLE | M_SCD_TRSEQ_DSAMPLE |
- K_SCD_TRSEQ_TRIGGER_ALL,
- IOADDR(A_SCD_TRACE_SEQUENCE_1));
- bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_2));
- bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_3));
- bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_4));
- bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_5));
- bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_6));
- bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_7));
+ __raw_writeq(M_SCD_TRSEQ_ASAMPLE | M_SCD_TRSEQ_DSAMPLE |
+ K_SCD_TRSEQ_TRIGGER_ALL,
+ IOADDR(A_SCD_TRACE_SEQUENCE_1));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_2));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_3));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_4));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_5));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_6));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_7));
/* Now indicate the PERF_CNT interrupt as a trace-relevant interrupt */
- bus_writeq((1ULL << K_INT_PERF_CNT),
- IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_TRACE)));
+ __raw_writeq(1ULL << K_INT_PERF_CNT,
+ IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_TRACE)));
arm_tb();
@@ -231,6 +239,7 @@ int sbprof_zbprof_start(struct file *filp)
int sbprof_zbprof_stop(void)
{
+ DEFINE_WAIT(wait);
DBG(printk(DEVNAME ": stopping\n"));
if (sbp.tb_enable) {
@@ -240,7 +249,9 @@ int sbprof_zbprof_stop(void)
this sleep happens. */
if (sbp.tb_armed) {
DBG(printk(DEVNAME ": wait for disarm\n"));
- interruptible_sleep_on(&sbp.tb_sync);
+ prepare_to_wait(&sbp.tb_sync, &wait, TASK_INTERRUPTIBLE);
+ schedule();
+ finish_wait(&sbp.tb_sync, &wait);
DBG(printk(DEVNAME ": disarm complete\n"));
}
free_irq(K_INT_TRACE_FREEZE, &sbp);
@@ -333,13 +344,13 @@ static ssize_t sbprof_tb_read(struct file *filp, char *buf,
return count;
}
-static int sbprof_tb_ioctl(struct inode *inode,
- struct file *filp,
- unsigned int command,
- unsigned long arg)
+static long sbprof_tb_ioctl(struct file *filp,
+ unsigned int command,
+ unsigned long arg)
{
int error = 0;
+ lock_kernel();
switch (command) {
case SBPROF_ZBSTART:
error = sbprof_zbprof_start(filp);
@@ -348,13 +359,17 @@ static int sbprof_tb_ioctl(struct inode *inode,
error = sbprof_zbprof_stop();
break;
case SBPROF_ZBWAITFULL:
- interruptible_sleep_on(&sbp.tb_read);
+ DEFINE_WAIT(wait);
+ prepare_to_wait(&sbp.tb_read, &wait, TASK_INTERRUPTIBLE);
+ schedule();
+ finish_wait(&sbp.tb_read, &wait);
/* XXXKW check if interrupted? */
return put_user(TB_FULL, (int *) arg);
default:
error = -EINVAL;
break;
}
+ unlock_kernel();
return error;
}
@@ -364,7 +379,8 @@ static struct file_operations sbprof_tb_fops = {
.open = sbprof_tb_open,
.release = sbprof_tb_release,
.read = sbprof_tb_read,
- .ioctl = sbprof_tb_ioctl,
+ .unlocked_ioctl = sbprof_tb_ioctl,
+ .compat_ioctl = sbprof_tb_ioctl,
.mmap = NULL,
};
diff --git a/arch/mips/sibyte/sb1250/bus_watcher.c b/arch/mips/sibyte/sb1250/bus_watcher.c
index 1a97e3127aeb..482dee054e68 100644
--- a/arch/mips/sibyte/sb1250/bus_watcher.c
+++ b/arch/mips/sibyte/sb1250/bus_watcher.c
@@ -189,7 +189,7 @@ static irqreturn_t sibyte_bw_int(int irq, void *data, struct pt_regs *regs)
for (i=0; i<256*6; i++)
printk("%016llx\n",
- (unsigned long long)bus_readq(IOADDR(A_SCD_TRACE_READ)));
+ (long long)__raw_readq(IOADDR(A_SCD_TRACE_READ)));
csr_out32(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
csr_out32(M_SCD_TRACE_CFG_START, IOADDR(A_SCD_TRACE_CFG));
diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c
index 2725b263cced..589537bfcc3d 100644
--- a/arch/mips/sibyte/sb1250/irq.c
+++ b/arch/mips/sibyte/sb1250/irq.c
@@ -53,7 +53,7 @@ static void disable_sb1250_irq(unsigned int irq);
static unsigned int startup_sb1250_irq(unsigned int irq);
static void ack_sb1250_irq(unsigned int irq);
#ifdef CONFIG_SMP
-static void sb1250_set_affinity(unsigned int irq, unsigned long mask);
+static void sb1250_set_affinity(unsigned int irq, cpumask_t mask);
#endif
#ifdef CONFIG_SIBYTE_HAS_LDT
@@ -71,17 +71,15 @@ extern char sb1250_duart_present[];
#endif
static struct hw_interrupt_type sb1250_irq_type = {
- "SB1250-IMR",
- startup_sb1250_irq,
- shutdown_sb1250_irq,
- enable_sb1250_irq,
- disable_sb1250_irq,
- ack_sb1250_irq,
- end_sb1250_irq,
+ .typename = "SB1250-IMR",
+ .startup = startup_sb1250_irq,
+ .shutdown = shutdown_sb1250_irq,
+ .enable = enable_sb1250_irq,
+ .disable = disable_sb1250_irq,
+ .ack = ack_sb1250_irq,
+ .end = end_sb1250_irq,
#ifdef CONFIG_SMP
- sb1250_set_affinity
-#else
- NULL
+ .set_affinity = sb1250_set_affinity
#endif
};
@@ -96,11 +94,11 @@ void sb1250_mask_irq(int cpu, int irq)
u64 cur_ints;
spin_lock_irqsave(&sb1250_imr_lock, flags);
- cur_ints = __bus_readq(IOADDR(A_IMR_MAPPER(cpu) +
- R_IMR_INTERRUPT_MASK));
+ cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(cpu) +
+ R_IMR_INTERRUPT_MASK));
cur_ints |= (((u64) 1) << irq);
- __bus_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
- R_IMR_INTERRUPT_MASK));
+ ____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
+ R_IMR_INTERRUPT_MASK));
spin_unlock_irqrestore(&sb1250_imr_lock, flags);
}
@@ -110,32 +108,25 @@ void sb1250_unmask_irq(int cpu, int irq)
u64 cur_ints;
spin_lock_irqsave(&sb1250_imr_lock, flags);
- cur_ints = __bus_readq(IOADDR(A_IMR_MAPPER(cpu) +
- R_IMR_INTERRUPT_MASK));
+ cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(cpu) +
+ R_IMR_INTERRUPT_MASK));
cur_ints &= ~(((u64) 1) << irq);
- __bus_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
- R_IMR_INTERRUPT_MASK));
+ ____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
+ R_IMR_INTERRUPT_MASK));
spin_unlock_irqrestore(&sb1250_imr_lock, flags);
}
#ifdef CONFIG_SMP
-static void sb1250_set_affinity(unsigned int irq, unsigned long mask)
+static void sb1250_set_affinity(unsigned int irq, cpumask_t mask)
{
int i = 0, old_cpu, cpu, int_on;
u64 cur_ints;
irq_desc_t *desc = irq_desc + irq;
unsigned long flags;
- while (mask) {
- if (mask & 1) {
- mask >>= 1;
- break;
- }
- mask >>= 1;
- i++;
- }
+ i = first_cpu(mask);
- if (mask) {
+ if (cpus_weight(mask) > 1) {
printk("attempted to set irq affinity for irq %d to multiple CPUs\n", irq);
return;
}
@@ -149,23 +140,23 @@ static void sb1250_set_affinity(unsigned int irq, unsigned long mask)
/* Swizzle each CPU's IMR (but leave the IP selection alone) */
old_cpu = sb1250_irq_owner[irq];
- cur_ints = __bus_readq(IOADDR(A_IMR_MAPPER(old_cpu) +
- R_IMR_INTERRUPT_MASK));
+ cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(old_cpu) +
+ R_IMR_INTERRUPT_MASK));
int_on = !(cur_ints & (((u64) 1) << irq));
if (int_on) {
/* If it was on, mask it */
cur_ints |= (((u64) 1) << irq);
- __bus_writeq(cur_ints, IOADDR(A_IMR_MAPPER(old_cpu) +
- R_IMR_INTERRUPT_MASK));
+ ____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(old_cpu) +
+ R_IMR_INTERRUPT_MASK));
}
sb1250_irq_owner[irq] = cpu;
if (int_on) {
/* unmask for the new CPU */
- cur_ints = __bus_readq(IOADDR(A_IMR_MAPPER(cpu) +
- R_IMR_INTERRUPT_MASK));
+ cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(cpu) +
+ R_IMR_INTERRUPT_MASK));
cur_ints &= ~(((u64) 1) << irq);
- __bus_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
- R_IMR_INTERRUPT_MASK));
+ ____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
+ R_IMR_INTERRUPT_MASK));
}
spin_unlock(&sb1250_imr_lock);
spin_unlock_irqrestore(&desc->lock, flags);
@@ -208,8 +199,8 @@ static void ack_sb1250_irq(unsigned int irq)
* deliver the interrupts to all CPUs (which makes affinity
* changing easier for us)
*/
- pending = bus_readq(IOADDR(A_IMR_REGISTER(sb1250_irq_owner[irq],
- R_IMR_LDT_INTERRUPT)));
+ pending = __raw_readq(IOADDR(A_IMR_REGISTER(sb1250_irq_owner[irq],
+ R_IMR_LDT_INTERRUPT)));
pending &= ((u64)1 << (irq));
if (pending) {
int i;
@@ -224,8 +215,8 @@ static void ack_sb1250_irq(unsigned int irq)
* Clear for all CPUs so an affinity switch
* doesn't find an old status
*/
- bus_writeq(pending,
- IOADDR(A_IMR_REGISTER(cpu,
+ __raw_writeq(pending,
+ IOADDR(A_IMR_REGISTER(cpu,
R_IMR_LDT_INTERRUPT_CLR)));
}
@@ -340,12 +331,14 @@ void __init arch_init_irq(void)
/* Default everything to IP2 */
for (i = 0; i < SB1250_NR_IRQS; i++) { /* was I0 */
- bus_writeq(IMR_IP2_VAL,
- IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
- (i << 3)));
- bus_writeq(IMR_IP2_VAL,
- IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MAP_BASE) +
- (i << 3)));
+ __raw_writeq(IMR_IP2_VAL,
+ IOADDR(A_IMR_REGISTER(0,
+ R_IMR_INTERRUPT_MAP_BASE) +
+ (i << 3)));
+ __raw_writeq(IMR_IP2_VAL,
+ IOADDR(A_IMR_REGISTER(1,
+ R_IMR_INTERRUPT_MAP_BASE) +
+ (i << 3)));
}
init_sb1250_irqs();
@@ -355,23 +348,23 @@ void __init arch_init_irq(void)
* inter-cpu messages
*/
/* Was I1 */
- bus_writeq(IMR_IP3_VAL,
- IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
- (K_INT_MBOX_0 << 3)));
- bus_writeq(IMR_IP3_VAL,
- IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MAP_BASE) +
- (K_INT_MBOX_0 << 3)));
+ __raw_writeq(IMR_IP3_VAL,
+ IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
+ (K_INT_MBOX_0 << 3)));
+ __raw_writeq(IMR_IP3_VAL,
+ IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MAP_BASE) +
+ (K_INT_MBOX_0 << 3)));
/* Clear the mailboxes. The firmware may leave them dirty */
- bus_writeq(0xffffffffffffffffULL,
- IOADDR(A_IMR_REGISTER(0, R_IMR_MAILBOX_CLR_CPU)));
- bus_writeq(0xffffffffffffffffULL,
- IOADDR(A_IMR_REGISTER(1, R_IMR_MAILBOX_CLR_CPU)));
+ __raw_writeq(0xffffffffffffffffULL,
+ IOADDR(A_IMR_REGISTER(0, R_IMR_MAILBOX_CLR_CPU)));
+ __raw_writeq(0xffffffffffffffffULL,
+ IOADDR(A_IMR_REGISTER(1, R_IMR_MAILBOX_CLR_CPU)));
/* Mask everything except the mailbox registers for both cpus */
tmp = ~((u64) 0) ^ (((u64) 1) << K_INT_MBOX_0);
- bus_writeq(tmp, IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK)));
- bus_writeq(tmp, IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MASK)));
+ __raw_writeq(tmp, IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK)));
+ __raw_writeq(tmp, IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MASK)));
sb1250_steal_irq(K_INT_MBOX_0);
@@ -396,12 +389,14 @@ void __init arch_init_irq(void)
sb1250_duart_present[kgdb_port] = 0;
#endif
/* Setup uart 1 settings, mapper */
- bus_writeq(M_DUART_IMR_BRK, IOADDR(A_DUART_IMRREG(kgdb_port)));
+ __raw_writeq(M_DUART_IMR_BRK,
+ IOADDR(A_DUART_IMRREG(kgdb_port)));
sb1250_steal_irq(kgdb_irq);
- bus_writeq(IMR_IP6_VAL,
- IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
- (kgdb_irq<<3)));
+ __raw_writeq(IMR_IP6_VAL,
+ IOADDR(A_IMR_REGISTER(0,
+ R_IMR_INTERRUPT_MAP_BASE) +
+ (kgdb_irq << 3)));
sb1250_unmask_irq(0, kgdb_irq);
}
#endif
diff --git a/arch/mips/sibyte/sb1250/setup.c b/arch/mips/sibyte/sb1250/setup.c
index f8c605be96c7..df2e266c700c 100644
--- a/arch/mips/sibyte/sb1250/setup.c
+++ b/arch/mips/sibyte/sb1250/setup.c
@@ -153,7 +153,7 @@ void sb1250_setup(void)
int bad_config = 0;
sb1_pass = read_c0_prid() & 0xff;
- sys_rev = bus_readq(IOADDR(A_SCD_SYSTEM_REVISION));
+ sys_rev = __raw_readq(IOADDR(A_SCD_SYSTEM_REVISION));
soc_type = SYS_SOC_TYPE(sys_rev);
soc_pass = G_SYS_REVISION(sys_rev);
@@ -162,7 +162,7 @@ void sb1250_setup(void)
machine_restart(NULL);
}
- plldiv = G_SYS_PLL_DIV(bus_readq(IOADDR(A_SCD_SYSTEM_CFG)));
+ plldiv = G_SYS_PLL_DIV(__raw_readq(IOADDR(A_SCD_SYSTEM_CFG)));
zbbus_mhz = ((plldiv >> 1) * 50) + ((plldiv & 1) * 25);
prom_printf("Broadcom SiByte %s %s @ %d MHz (SB1 rev %d)\n",
diff --git a/arch/mips/sibyte/sb1250/smp.c b/arch/mips/sibyte/sb1250/smp.c
index be91b3990952..f859db02d3c9 100644
--- a/arch/mips/sibyte/sb1250/smp.c
+++ b/arch/mips/sibyte/sb1250/smp.c
@@ -29,18 +29,18 @@
#include <asm/sibyte/sb1250_int.h>
static void *mailbox_set_regs[] = {
- (void *)IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_SET_CPU),
- (void *)IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_SET_CPU)
+ IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_SET_CPU),
+ IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_SET_CPU)
};
static void *mailbox_clear_regs[] = {
- (void *)IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_CLR_CPU),
- (void *)IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_CLR_CPU)
+ IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_CLR_CPU),
+ IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_CLR_CPU)
};
static void *mailbox_regs[] = {
- (void *)IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_CPU),
- (void *)IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_CPU)
+ IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_CPU),
+ IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_CPU)
};
/*
@@ -73,7 +73,7 @@ void sb1250_smp_finish(void)
*/
void core_send_ipi(int cpu, unsigned int action)
{
- bus_writeq((((u64)action) << 48), mailbox_set_regs[cpu]);
+ __raw_writeq((((u64)action) << 48), mailbox_set_regs[cpu]);
}
void sb1250_mailbox_interrupt(struct pt_regs *regs)
@@ -83,10 +83,10 @@ void sb1250_mailbox_interrupt(struct pt_regs *regs)
kstat_this_cpu.irqs[K_INT_MBOX_0]++;
/* Load the mailbox register to figure out what we're supposed to do */
- action = (__bus_readq(mailbox_regs[cpu]) >> 48) & 0xffff;
+ action = (____raw_readq(mailbox_regs[cpu]) >> 48) & 0xffff;
/* Clear the mailbox to clear the interrupt */
- __bus_writeq(((u64)action) << 48, mailbox_clear_regs[cpu]);
+ ____raw_writeq(((u64)action) << 48, mailbox_clear_regs[cpu]);
/*
* Nothing to do for SMP_RESCHEDULE_YOURSELF; returning from the
diff --git a/arch/mips/sibyte/sb1250/time.c b/arch/mips/sibyte/sb1250/time.c
index 8b4c848c907b..511c89d65f38 100644
--- a/arch/mips/sibyte/sb1250/time.c
+++ b/arch/mips/sibyte/sb1250/time.c
@@ -67,24 +67,24 @@ void sb1250_time_init(void)
sb1250_mask_irq(cpu, irq);
/* Map the timer interrupt to ip[4] of this cpu */
- bus_writeq(IMR_IP4_VAL,
- IOADDR(A_IMR_REGISTER(cpu, R_IMR_INTERRUPT_MAP_BASE) +
- (irq << 3)));
+ __raw_writeq(IMR_IP4_VAL,
+ IOADDR(A_IMR_REGISTER(cpu, R_IMR_INTERRUPT_MAP_BASE) +
+ (irq << 3)));
/* the general purpose timer ticks at 1 Mhz independent if the rest of the system */
/* Disable the timer and set up the count */
- bus_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+ __raw_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
#ifdef CONFIG_SIMULATION
- bus_writeq(50000 / HZ,
- IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
+ __raw_writeq(50000 / HZ,
+ IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
#else
- bus_writeq(1000000/HZ,
- IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
+ __raw_writeq(1000000 / HZ,
+ IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
#endif
/* Set the timer running */
- bus_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
- IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+ __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
+ IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
sb1250_unmask_irq(cpu, irq);
sb1250_steal_irq(irq);
@@ -100,25 +100,25 @@ void sb1250_time_init(void)
void sb1250_timer_interrupt(struct pt_regs *regs)
{
- extern asmlinkage void ll_local_timer_interrupt(int irq, struct pt_regs *regs);
int cpu = smp_processor_id();
int irq = K_INT_TIMER_0 + cpu;
/* Reset the timer */
- __bus_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
- IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+ ____raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
+ IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
- /*
- * CPU 0 handles the global timer interrupt job
- */
if (cpu == 0) {
+ /*
+ * CPU 0 handles the global timer interrupt job
+ */
ll_timer_interrupt(irq, regs);
}
-
- /*
- * every CPU should do profiling and process accouting
- */
- ll_local_timer_interrupt(irq, regs);
+ else {
+ /*
+ * other CPUs should just do profiling and process accounting
+ */
+ ll_local_timer_interrupt(irq, regs);
+ }
}
/*
@@ -130,7 +130,7 @@ void sb1250_timer_interrupt(struct pt_regs *regs)
unsigned long sb1250_gettimeoffset(void)
{
unsigned long count =
- bus_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT)));
+ __raw_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT)));
return 1000000/HZ - count;
}
diff --git a/arch/mips/sibyte/swarm/rtc_m41t81.c b/arch/mips/sibyte/swarm/rtc_m41t81.c
index a686bb716ec6..5b4fc26c1b36 100644
--- a/arch/mips/sibyte/swarm/rtc_m41t81.c
+++ b/arch/mips/sibyte/swarm/rtc_m41t81.c
@@ -82,59 +82,60 @@
#define M41T81REG_SQW 0x13 /* square wave register */
#define M41T81_CCR_ADDRESS 0x68
-#define SMB_CSR(reg) ((u8 *) (IOADDR(A_SMB_REGISTER(1, reg))))
+
+#define SMB_CSR(reg) IOADDR(A_SMB_REGISTER(1, reg))
static int m41t81_read(uint8_t addr)
{
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
- bus_writeq(addr & 0xff, SMB_CSR(R_SMB_CMD));
- bus_writeq((V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR1BYTE),
- SMB_CSR(R_SMB_START));
+ __raw_writeq(addr & 0xff, SMB_CSR(R_SMB_CMD));
+ __raw_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR1BYTE,
+ SMB_CSR(R_SMB_START));
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
- bus_writeq((V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE),
- SMB_CSR(R_SMB_START));
+ __raw_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE,
+ SMB_CSR(R_SMB_START));
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
- if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+ if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
/* Clear error bit by writing a 1 */
- bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+ __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
return -1;
}
- return (bus_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
+ return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
}
static int m41t81_write(uint8_t addr, int b)
{
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
- bus_writeq((addr & 0xFF), SMB_CSR(R_SMB_CMD));
- bus_writeq((b & 0xff), SMB_CSR(R_SMB_DATA));
- bus_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR2BYTE,
- SMB_CSR(R_SMB_START));
+ __raw_writeq(addr & 0xff, SMB_CSR(R_SMB_CMD));
+ __raw_writeq(b & 0xff, SMB_CSR(R_SMB_DATA));
+ __raw_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR2BYTE,
+ SMB_CSR(R_SMB_START));
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
- if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+ if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
/* Clear error bit by writing a 1 */
- bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+ __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
return -1;
}
/* read the same byte again to make sure it is written */
- bus_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE,
- SMB_CSR(R_SMB_START));
+ __raw_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE,
+ SMB_CSR(R_SMB_START));
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
return 0;
diff --git a/arch/mips/sibyte/swarm/rtc_xicor1241.c b/arch/mips/sibyte/swarm/rtc_xicor1241.c
index 981d21f16e64..d9ff9323f24e 100644
--- a/arch/mips/sibyte/swarm/rtc_xicor1241.c
+++ b/arch/mips/sibyte/swarm/rtc_xicor1241.c
@@ -57,52 +57,52 @@
#define X1241_CCR_ADDRESS 0x6F
-#define SMB_CSR(reg) ((u8 *) (IOADDR(A_SMB_REGISTER(1, reg))))
+#define SMB_CSR(reg) IOADDR(A_SMB_REGISTER(1, reg))
static int xicor_read(uint8_t addr)
{
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
- bus_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD));
- bus_writeq((addr & 0xff), SMB_CSR(R_SMB_DATA));
- bus_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE),
- SMB_CSR(R_SMB_START));
+ __raw_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD));
+ __raw_writeq(addr & 0xff, SMB_CSR(R_SMB_DATA));
+ __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE,
+ SMB_CSR(R_SMB_START));
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
- bus_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE),
- SMB_CSR(R_SMB_START));
+ __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE,
+ SMB_CSR(R_SMB_START));
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
- if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+ if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
/* Clear error bit by writing a 1 */
- bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+ __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
return -1;
}
- return (bus_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
+ return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
}
static int xicor_write(uint8_t addr, int b)
{
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
- bus_writeq(addr, SMB_CSR(R_SMB_CMD));
- bus_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA));
- bus_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE,
- SMB_CSR(R_SMB_START));
+ __raw_writeq(addr, SMB_CSR(R_SMB_CMD));
+ __raw_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA));
+ __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE,
+ SMB_CSR(R_SMB_START));
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
- if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+ if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
/* Clear error bit by writing a 1 */
- bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+ __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
return -1;
} else {
return 0;
diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c
index 4daeaa413def..b614ca0ddb69 100644
--- a/arch/mips/sibyte/swarm/setup.c
+++ b/arch/mips/sibyte/swarm/setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation
+ * Copyright (C) 2000, 2001, 2002, 2003, 2004 Broadcom Corporation
* Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
*
* This program is free software; you can redistribute it and/or
@@ -39,11 +39,23 @@
#include <asm/time.h>
#include <asm/traps.h>
#include <asm/sibyte/sb1250.h>
+#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
+#include <asm/sibyte/bcm1480_regs.h>
+#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
#include <asm/sibyte/sb1250_regs.h>
+#else
+#error invalid SiByte board configuation
+#endif
#include <asm/sibyte/sb1250_genbus.h>
#include <asm/sibyte/board.h>
+#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
+extern void bcm1480_setup(void);
+#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
extern void sb1250_setup(void);
+#else
+#error invalid SiByte board configuation
+#endif
extern int xicor_probe(void);
extern int xicor_set_time(unsigned long);
@@ -66,27 +78,34 @@ void __init swarm_timer_setup(struct irqaction *irq)
*/
/* We only need to setup the generic timer */
- sb1250_time_init();
+#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
+ bcm1480_time_init();
+#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
+ sb1250_time_init();
+#else
+#error invalid SiByte board configuation
+#endif
}
int swarm_be_handler(struct pt_regs *regs, int is_fixup)
{
if (!is_fixup && (regs->cp0_cause & 4)) {
/* Data bus error - print PA */
-#ifdef CONFIG_64BIT
- printk("DBE physical address: %010lx\n",
+ printk("DBE physical address: %010Lx\n",
__read_64bit_c0_register($26, 1));
-#else
- printk("DBE physical address: %010llx\n",
- __read_64bit_c0_split($26, 1));
-#endif
}
return (is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL);
}
-static int __init swarm_setup(void)
+void __init plat_setup(void)
{
+#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
+ bcm1480_setup();
+#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
sb1250_setup();
+#else
+#error invalid SiByte board configuation
+#endif
panic_timeout = 5; /* For debug. */
@@ -133,12 +152,8 @@ static int __init swarm_setup(void)
};
/* XXXKW for CFE, get lines/cols from environment */
#endif
-
- return 0;
}
-early_initcall(swarm_setup);
-
#ifdef LEDS_PHYS
#ifdef CONFIG_SIBYTE_CARMEL
diff --git a/arch/mips/sibyte/swarm/time.c b/arch/mips/sibyte/swarm/time.c
index c1f1a9defeeb..97c73c793c35 100644
--- a/arch/mips/sibyte/swarm/time.c
+++ b/arch/mips/sibyte/swarm/time.c
@@ -79,48 +79,48 @@ static unsigned int usec_bias = 0;
static int xicor_read(uint8_t addr)
{
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
- bus_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD));
- bus_writeq((addr & 0xff), SMB_CSR(R_SMB_DATA));
- bus_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE),
- SMB_CSR(R_SMB_START));
+ __raw_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD));
+ __raw_writeq(addr & 0xff, SMB_CSR(R_SMB_DATA));
+ __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE,
+ SMB_CSR(R_SMB_START));
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
- bus_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE),
- SMB_CSR(R_SMB_START));
+ __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE,
+ SMB_CSR(R_SMB_START));
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
- if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+ if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
/* Clear error bit by writing a 1 */
- bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+ __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
return -1;
}
- return (bus_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
+ return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
}
static int xicor_write(uint8_t addr, int b)
{
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
- bus_writeq(addr, SMB_CSR(R_SMB_CMD));
- bus_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA));
- bus_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE,
- SMB_CSR(R_SMB_START));
+ __raw_writeq(addr, SMB_CSR(R_SMB_CMD));
+ __raw_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA));
+ __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE,
+ SMB_CSR(R_SMB_START));
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
- if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+ if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
/* Clear error bit by writing a 1 */
- bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+ __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
return -1;
} else {
return 0;
@@ -228,8 +228,8 @@ void __init swarm_time_init(void)
/* Establish communication with the Xicor 1241 RTC */
/* XXXKW how do I share the SMBus with the I2C subsystem? */
- bus_writeq(K_SMB_FREQ_400KHZ, SMB_CSR(R_SMB_FREQ));
- bus_writeq(0, SMB_CSR(R_SMB_CONTROL));
+ __raw_writeq(K_SMB_FREQ_400KHZ, SMB_CSR(R_SMB_FREQ));
+ __raw_writeq(0, SMB_CSR(R_SMB_CONTROL));
if ((status = xicor_read(X1241REG_SR_RTCF)) < 0) {
printk("x1241: couldn't detect on SWARM SMBus 1\n");
diff --git a/arch/mips/sni/irq.c b/arch/mips/sni/irq.c
index 141a310d74d8..952038aa4b90 100644
--- a/arch/mips/sni/irq.c
+++ b/arch/mips/sni/irq.c
@@ -58,14 +58,13 @@ static void end_pciasic_irq(unsigned int irq)
}
static struct hw_interrupt_type pciasic_irq_type = {
- "ASIC-PCI",
- startup_pciasic_irq,
- shutdown_pciasic_irq,
- enable_pciasic_irq,
- disable_pciasic_irq,
- mask_and_ack_pciasic_irq,
- end_pciasic_irq,
- NULL
+ .typename = "ASIC-PCI",
+ .startup = startup_pciasic_irq,
+ .shutdown = shutdown_pciasic_irq,
+ .enable = enable_pciasic_irq,
+ .disable = disable_pciasic_irq,
+ .ack = mask_and_ack_pciasic_irq,
+ .end = end_pciasic_irq,
};
/*
diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c
index 1b3f8a0903e1..262c85680709 100644
--- a/arch/mips/sni/setup.c
+++ b/arch/mips/sni/setup.c
@@ -167,7 +167,7 @@ static inline void sni_pcimt_time_init(void)
rtc_set_time = mc146818_set_rtc_mmss;
}
-static int __init sni_rm200_pci_setup(void)
+void __init plat_setup(void)
{
sni_pcimt_detect();
sni_pcimt_sc_init();
@@ -196,8 +196,4 @@ static int __init sni_rm200_pci_setup(void)
#ifdef CONFIG_PCI
register_pci_controller(&sni_controller);
#endif
-
- return 0;
}
-
-early_initcall(sni_rm200_pci_setup);
diff --git a/arch/mips/tx4927/Kconfig b/arch/mips/tx4927/Kconfig
new file mode 100644
index 000000000000..5fbbe12e0fc1
--- /dev/null
+++ b/arch/mips/tx4927/Kconfig
@@ -0,0 +1,3 @@
+config TOSHIBA_FPCIB0
+ bool "FPCIB0 Backplane Support"
+ depends on TOSHIBA_RBTX4927
diff --git a/arch/mips/tx4927/common/tx4927_setup.c b/arch/mips/tx4927/common/tx4927_setup.c
index 26d7c53612a8..77c3b66fb959 100644
--- a/arch/mips/tx4927/common/tx4927_setup.c
+++ b/arch/mips/tx4927/common/tx4927_setup.c
@@ -64,7 +64,7 @@ static void tx4927_write_buffer_flush(void)
}
-static void __init tx4927_setup(void)
+void __init plat_setup(void)
{
board_time_init = tx4927_time_init;
board_timer_setup = tx4927_timer_setup;
@@ -76,12 +76,8 @@ static void __init tx4927_setup(void)
toshiba_rbtx4927_setup();
}
#endif
-
- return;
}
-early_initcall(tx4927_setup);
-
void __init tx4927_time_init(void)
{
diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
index fc0720599fd9..990fcb294bab 100644
--- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
+++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
@@ -77,6 +77,11 @@
#include <linux/hdreg.h>
#include <linux/ide.h>
#endif
+#ifdef CONFIG_SERIAL_TXX9
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#endif
#undef TOSHIBA_RBTX4927_SETUP_DEBUG
@@ -920,12 +925,30 @@ void __init toshiba_rbtx4927_setup(void)
#endif /* CONFIG_PCI */
+#ifdef CONFIG_SERIAL_TXX9
+ {
+ extern int early_serial_txx9_setup(struct uart_port *port);
+ int i;
+ struct uart_port req;
+ for(i = 0; i < 2; i++) {
+ memset(&req, 0, sizeof(req));
+ req.line = i;
+ req.iotype = UPIO_MEM;
+ req.membase = (char *)(0xff1ff300 + i * 0x100);
+ req.mapbase = 0xff1ff300 + i * 0x100;
+ req.irq = 32 + i;
+ req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/;
+ req.uartclk = 50000000;
+ early_serial_txx9_setup(&req);
+ }
+ }
#ifdef CONFIG_SERIAL_TXX9_CONSOLE
argptr = prom_getcmdline();
if (strstr(argptr, "console=") == NULL) {
strcat(argptr, " console=ttyS0,38400");
}
#endif
+#endif
#ifdef CONFIG_ROOT_NFS
argptr = prom_getcmdline();
diff --git a/arch/mips/tx4938/Kconfig b/arch/mips/tx4938/Kconfig
new file mode 100644
index 000000000000..d90e9cd85138
--- /dev/null
+++ b/arch/mips/tx4938/Kconfig
@@ -0,0 +1,24 @@
+if TOSHIBA_RBTX4938
+
+comment "Multiplex Pin Select"
+choice
+ prompt "PIO[58:61]"
+ default TOSHIBA_RBTX4938_MPLEX_PIO58_61
+
+config TOSHIBA_RBTX4938_MPLEX_PIO58_61
+ bool "PIO"
+config TOSHIBA_RBTX4938_MPLEX_NAND
+ bool "NAND"
+config TOSHIBA_RBTX4938_MPLEX_ATA
+ bool "ATA"
+
+endchoice
+
+config TX4938_NAND_BOOT
+ depends on EXPERIMENTAL && TOSHIBA_RBTX4938_MPLEX_NAND
+ bool "NAND Boot Support (EXPERIMENTAL)"
+ help
+ This is only for Toshiba RBTX4938 reference board, which has NAND IPL.
+ Select this option if you need to use NAND boot.
+
+endif
diff --git a/arch/mips/tx4938/common/Makefile b/arch/mips/tx4938/common/Makefile
new file mode 100644
index 000000000000..74c95c5bcdbf
--- /dev/null
+++ b/arch/mips/tx4938/common/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for common code for Toshiba TX4927 based systems
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+obj-y += prom.o setup.o irq.o irq_handler.o rtc_rx5c348.o
+obj-$(CONFIG_KGDB) += dbgio.o
+
diff --git a/arch/mips/tx4938/common/dbgio.c b/arch/mips/tx4938/common/dbgio.c
new file mode 100644
index 000000000000..bea59ff1842a
--- /dev/null
+++ b/arch/mips/tx4938/common/dbgio.c
@@ -0,0 +1,50 @@
+/*
+ * linux/arch/mips/tx4938/common/dbgio.c
+ *
+ * kgdb interface for gdb
+ *
+ * Author: MontaVista Software, Inc.
+ * source@mvista.com
+ *
+ * Copyright 2005 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Support for TX4938 in 2.6 - Hiroshi DOYU <Hiroshi_DOYU@montavista.co.jp>
+ */
+
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/tx4938/tx4938_mips.h>
+
+extern u8 txx9_sio_kdbg_rd(void);
+extern int txx9_sio_kdbg_wr( u8 ch );
+
+u8 getDebugChar(void)
+{
+ return (txx9_sio_kdbg_rd());
+}
+
+int putDebugChar(u8 byte)
+{
+ return (txx9_sio_kdbg_wr(byte));
+}
+
diff --git a/arch/mips/tx4938/common/irq.c b/arch/mips/tx4938/common/irq.c
new file mode 100644
index 000000000000..4f90d7faf634
--- /dev/null
+++ b/arch/mips/tx4938/common/irq.c
@@ -0,0 +1,424 @@
+/*
+ * linux/arch/mps/tx4938/common/irq.c
+ *
+ * Common tx4938 irq handler
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/irq.h>
+#include <asm/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/tx4938/rbtx4938.h>
+
+/**********************************************************************************/
+/* Forwad definitions for all pic's */
+/**********************************************************************************/
+
+static unsigned int tx4938_irq_cp0_startup(unsigned int irq);
+static void tx4938_irq_cp0_shutdown(unsigned int irq);
+static void tx4938_irq_cp0_enable(unsigned int irq);
+static void tx4938_irq_cp0_disable(unsigned int irq);
+static void tx4938_irq_cp0_mask_and_ack(unsigned int irq);
+static void tx4938_irq_cp0_end(unsigned int irq);
+
+static unsigned int tx4938_irq_pic_startup(unsigned int irq);
+static void tx4938_irq_pic_shutdown(unsigned int irq);
+static void tx4938_irq_pic_enable(unsigned int irq);
+static void tx4938_irq_pic_disable(unsigned int irq);
+static void tx4938_irq_pic_mask_and_ack(unsigned int irq);
+static void tx4938_irq_pic_end(unsigned int irq);
+
+/**********************************************************************************/
+/* Kernel structs for all pic's */
+/**********************************************************************************/
+DEFINE_SPINLOCK(tx4938_cp0_lock);
+DEFINE_SPINLOCK(tx4938_pic_lock);
+
+#define TX4938_CP0_NAME "TX4938-CP0"
+static struct hw_interrupt_type tx4938_irq_cp0_type = {
+ .typename = TX4938_CP0_NAME,
+ .startup = tx4938_irq_cp0_startup,
+ .shutdown = tx4938_irq_cp0_shutdown,
+ .enable = tx4938_irq_cp0_enable,
+ .disable = tx4938_irq_cp0_disable,
+ .ack = tx4938_irq_cp0_mask_and_ack,
+ .end = tx4938_irq_cp0_end,
+ .set_affinity = NULL
+};
+
+#define TX4938_PIC_NAME "TX4938-PIC"
+static struct hw_interrupt_type tx4938_irq_pic_type = {
+ .typename = TX4938_PIC_NAME,
+ .startup = tx4938_irq_pic_startup,
+ .shutdown = tx4938_irq_pic_shutdown,
+ .enable = tx4938_irq_pic_enable,
+ .disable = tx4938_irq_pic_disable,
+ .ack = tx4938_irq_pic_mask_and_ack,
+ .end = tx4938_irq_pic_end,
+ .set_affinity = NULL
+};
+
+static struct irqaction tx4938_irq_pic_action = {
+ .handler = no_action,
+ .flags = 0,
+ .mask = CPU_MASK_NONE,
+ .name = TX4938_PIC_NAME
+};
+
+/**********************************************************************************/
+/* Functions for cp0 */
+/**********************************************************************************/
+
+#define tx4938_irq_cp0_mask(irq) ( 1 << ( irq-TX4938_IRQ_CP0_BEG+8 ) )
+
+static void __init
+tx4938_irq_cp0_init(void)
+{
+ int i;
+
+ for (i = TX4938_IRQ_CP0_BEG; i <= TX4938_IRQ_CP0_END; i++) {
+ irq_desc[i].status = IRQ_DISABLED;
+ irq_desc[i].action = 0;
+ irq_desc[i].depth = 1;
+ irq_desc[i].handler = &tx4938_irq_cp0_type;
+ }
+
+ return;
+}
+
+static unsigned int
+tx4938_irq_cp0_startup(unsigned int irq)
+{
+ tx4938_irq_cp0_enable(irq);
+
+ return (0);
+}
+
+static void
+tx4938_irq_cp0_shutdown(unsigned int irq)
+{
+ tx4938_irq_cp0_disable(irq);
+}
+
+static void
+tx4938_irq_cp0_enable(unsigned int irq)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&tx4938_cp0_lock, flags);
+
+ set_c0_status(tx4938_irq_cp0_mask(irq));
+
+ spin_unlock_irqrestore(&tx4938_cp0_lock, flags);
+}
+
+static void
+tx4938_irq_cp0_disable(unsigned int irq)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&tx4938_cp0_lock, flags);
+
+ clear_c0_status(tx4938_irq_cp0_mask(irq));
+
+ spin_unlock_irqrestore(&tx4938_cp0_lock, flags);
+
+ return;
+}
+
+static void
+tx4938_irq_cp0_mask_and_ack(unsigned int irq)
+{
+ tx4938_irq_cp0_disable(irq);
+
+ return;
+}
+
+static void
+tx4938_irq_cp0_end(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+ tx4938_irq_cp0_enable(irq);
+ }
+
+ return;
+}
+
+/**********************************************************************************/
+/* Functions for pic */
+/**********************************************************************************/
+
+u32
+tx4938_irq_pic_addr(int irq)
+{
+ /* MVMCP -- need to formulize this */
+ irq -= TX4938_IRQ_PIC_BEG;
+
+ switch (irq) {
+ case 17:
+ case 16:
+ case 1:
+ case 0:{
+ return (TX4938_MKA(TX4938_IRC_IRLVL0));
+ }
+ case 19:
+ case 18:
+ case 3:
+ case 2:{
+ return (TX4938_MKA(TX4938_IRC_IRLVL1));
+ }
+ case 21:
+ case 20:
+ case 5:
+ case 4:{
+ return (TX4938_MKA(TX4938_IRC_IRLVL2));
+ }
+ case 23:
+ case 22:
+ case 7:
+ case 6:{
+ return (TX4938_MKA(TX4938_IRC_IRLVL3));
+ }
+ case 25:
+ case 24:
+ case 9:
+ case 8:{
+ return (TX4938_MKA(TX4938_IRC_IRLVL4));
+ }
+ case 27:
+ case 26:
+ case 11:
+ case 10:{
+ return (TX4938_MKA(TX4938_IRC_IRLVL5));
+ }
+ case 29:
+ case 28:
+ case 13:
+ case 12:{
+ return (TX4938_MKA(TX4938_IRC_IRLVL6));
+ }
+ case 31:
+ case 30:
+ case 15:
+ case 14:{
+ return (TX4938_MKA(TX4938_IRC_IRLVL7));
+ }
+ }
+
+ return (0);
+}
+
+u32
+tx4938_irq_pic_mask(int irq)
+{
+ /* MVMCP -- need to formulize this */
+ irq -= TX4938_IRQ_PIC_BEG;
+
+ switch (irq) {
+ case 31:
+ case 29:
+ case 27:
+ case 25:
+ case 23:
+ case 21:
+ case 19:
+ case 17:{
+ return (0x07000000);
+ }
+ case 30:
+ case 28:
+ case 26:
+ case 24:
+ case 22:
+ case 20:
+ case 18:
+ case 16:{
+ return (0x00070000);
+ }
+ case 15:
+ case 13:
+ case 11:
+ case 9:
+ case 7:
+ case 5:
+ case 3:
+ case 1:{
+ return (0x00000700);
+ }
+ case 14:
+ case 12:
+ case 10:
+ case 8:
+ case 6:
+ case 4:
+ case 2:
+ case 0:{
+ return (0x00000007);
+ }
+ }
+ return (0x00000000);
+}
+
+static void
+tx4938_irq_pic_modify(unsigned pic_reg, unsigned clr_bits, unsigned set_bits)
+{
+ unsigned long val = 0;
+
+ val = TX4938_RD(pic_reg);
+ val &= (~clr_bits);
+ val |= (set_bits);
+ TX4938_WR(pic_reg, val);
+ mmiowb();
+ TX4938_RD(pic_reg);
+
+ return;
+}
+
+static void __init
+tx4938_irq_pic_init(void)
+{
+ unsigned long flags;
+ int i;
+
+ for (i = TX4938_IRQ_PIC_BEG; i <= TX4938_IRQ_PIC_END; i++) {
+ irq_desc[i].status = IRQ_DISABLED;
+ irq_desc[i].action = 0;
+ irq_desc[i].depth = 2;
+ irq_desc[i].handler = &tx4938_irq_pic_type;
+ }
+
+ setup_irq(TX4938_IRQ_NEST_PIC_ON_CP0, &tx4938_irq_pic_action);
+
+ spin_lock_irqsave(&tx4938_pic_lock, flags);
+
+ TX4938_WR(0xff1ff640, 0x6); /* irq level mask -- only accept hightest */
+ TX4938_WR(0xff1ff600, TX4938_RD(0xff1ff600) | 0x1); /* irq enable */
+
+ spin_unlock_irqrestore(&tx4938_pic_lock, flags);
+
+ return;
+}
+
+static unsigned int
+tx4938_irq_pic_startup(unsigned int irq)
+{
+ tx4938_irq_pic_enable(irq);
+
+ return (0);
+}
+
+static void
+tx4938_irq_pic_shutdown(unsigned int irq)
+{
+ tx4938_irq_pic_disable(irq);
+
+ return;
+}
+
+static void
+tx4938_irq_pic_enable(unsigned int irq)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&tx4938_pic_lock, flags);
+
+ tx4938_irq_pic_modify(tx4938_irq_pic_addr(irq), 0,
+ tx4938_irq_pic_mask(irq));
+
+ spin_unlock_irqrestore(&tx4938_pic_lock, flags);
+
+ return;
+}
+
+static void
+tx4938_irq_pic_disable(unsigned int irq)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&tx4938_pic_lock, flags);
+
+ tx4938_irq_pic_modify(tx4938_irq_pic_addr(irq),
+ tx4938_irq_pic_mask(irq), 0);
+
+ spin_unlock_irqrestore(&tx4938_pic_lock, flags);
+
+ return;
+}
+
+static void
+tx4938_irq_pic_mask_and_ack(unsigned int irq)
+{
+ tx4938_irq_pic_disable(irq);
+
+ return;
+}
+
+static void
+tx4938_irq_pic_end(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+ tx4938_irq_pic_enable(irq);
+ }
+
+ return;
+}
+
+/**********************************************************************************/
+/* Main init functions */
+/**********************************************************************************/
+
+void __init
+tx4938_irq_init(void)
+{
+ extern asmlinkage void tx4938_irq_handler(void);
+
+ tx4938_irq_cp0_init();
+ tx4938_irq_pic_init();
+ set_except_vector(0, tx4938_irq_handler);
+
+ return;
+}
+
+int
+tx4938_irq_nested(void)
+{
+ int sw_irq = 0;
+ u32 level2;
+
+ level2 = TX4938_RD(0xff1ff6a0);
+ if ((level2 & 0x10000) == 0) {
+ level2 &= 0x1f;
+ sw_irq = TX4938_IRQ_PIC_BEG + level2;
+ if (sw_irq == 26) {
+ {
+ extern int toshiba_rbtx4938_irq_nested(int sw_irq);
+ sw_irq = toshiba_rbtx4938_irq_nested(sw_irq);
+ }
+ }
+ }
+
+ wbflush();
+ return (sw_irq);
+}
diff --git a/arch/mips/tx4938/common/irq_handler.S b/arch/mips/tx4938/common/irq_handler.S
new file mode 100644
index 000000000000..1b2f72bac42d
--- /dev/null
+++ b/arch/mips/tx4938/common/irq_handler.S
@@ -0,0 +1,84 @@
+/*
+ * linux/arch/mips/tx4938/common/handler.S
+ *
+ * Primary interrupt handler for tx4938 based systems
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/tx4938/rbtx4938.h>
+
+
+ .align 5
+ NESTED(tx4938_irq_handler, PT_SIZE, sp)
+ SAVE_ALL
+ CLI
+ .set at
+
+ mfc0 t0, CP0_CAUSE
+ mfc0 t1, CP0_STATUS
+ and t0, t1
+
+ andi t1, t0, STATUSF_IP7 /* cpu timer */
+ bnez t1, ll_ip7
+
+ /* IP6..IP3 multiplexed -- do not use */
+
+ andi t1, t0, STATUSF_IP2 /* tx4938 pic */
+ bnez t1, ll_ip2
+
+ andi t1, t0, STATUSF_IP1 /* user line 1 */
+ bnez t1, ll_ip1
+
+ andi t1, t0, STATUSF_IP0 /* user line 0 */
+ bnez t1, ll_ip0
+
+ .set reorder
+
+ nop
+ END(tx4938_irq_handler)
+
+ .align 5
+
+
+ll_ip7:
+ li a0, TX4938_IRQ_CPU_TIMER
+ move a1, sp
+ jal do_IRQ
+ j ret_from_irq
+
+
+ll_ip2:
+ jal tx4938_irq_nested
+ nop
+ beqz v0, goto_spurious_interrupt
+ nop
+ move a0, v0
+ move a1, sp
+ jal do_IRQ
+ j ret_from_irq
+
+goto_spurious_interrupt:
+ j ret_from_irq
+
+ll_ip1:
+ li a0, TX4938_IRQ_USER1
+ move a1, sp
+ jal do_IRQ
+ j ret_from_irq
+
+ll_ip0:
+ li a0, TX4938_IRQ_USER0
+ move a1, sp
+ jal do_IRQ
+ j ret_from_irq
diff --git a/arch/mips/tx4938/common/prom.c b/arch/mips/tx4938/common/prom.c
new file mode 100644
index 000000000000..3189a65f7d7e
--- /dev/null
+++ b/arch/mips/tx4938/common/prom.c
@@ -0,0 +1,129 @@
+/*
+ * linux/arch/mips/tx4938/common/prom.c
+ *
+ * common tx4938 memory interface
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/tx4938/tx4938.h>
+
+static unsigned int __init
+tx4938_process_sdccr(u64 * addr)
+{
+ u64 val;
+ unsigned int sdccr_ce;
+ unsigned int sdccr_rs;
+ unsigned int sdccr_cs;
+ unsigned int sdccr_mw;
+ unsigned int rs = 0;
+ unsigned int cs = 0;
+ unsigned int mw = 0;
+ unsigned int bc = 4;
+ unsigned int msize = 0;
+
+ val = (*((vu64 *) (addr)));
+
+ /* MVMCP -- need #defs for these bits masks */
+ sdccr_ce = ((val & (1 << 10)) >> 10);
+ sdccr_rs = ((val & (3 << 5)) >> 5);
+ sdccr_cs = ((val & (7 << 2)) >> 2);
+ sdccr_mw = ((val & (1 << 0)) >> 0);
+
+ if (sdccr_ce) {
+ switch (sdccr_rs) {
+ case 0:{
+ rs = 2048;
+ break;
+ }
+ case 1:{
+ rs = 4096;
+ break;
+ }
+ case 2:{
+ rs = 8192;
+ break;
+ }
+ default:{
+ rs = 0;
+ break;
+ }
+ }
+ switch (sdccr_cs) {
+ case 0:{
+ cs = 256;
+ break;
+ }
+ case 1:{
+ cs = 512;
+ break;
+ }
+ case 2:{
+ cs = 1024;
+ break;
+ }
+ case 3:{
+ cs = 2048;
+ break;
+ }
+ case 4:{
+ cs = 4096;
+ break;
+ }
+ default:{
+ cs = 0;
+ break;
+ }
+ }
+ switch (sdccr_mw) {
+ case 0:{
+ mw = 8;
+ break;
+ } /* 8 bytes = 64 bits */
+ case 1:{
+ mw = 4;
+ break;
+ } /* 4 bytes = 32 bits */
+ }
+ }
+
+ /* bytes per chip MB per chip bank count */
+ msize = (((rs * cs * mw) / (1024 * 1024)) * (bc));
+
+ /* MVMCP -- bc hard coded to 4 from table 9.3.1 */
+ /* boad supports bc=2 but no way to detect */
+
+ return (msize);
+}
+
+unsigned int __init
+tx4938_get_mem_size(void)
+{
+ unsigned int c0;
+ unsigned int c1;
+ unsigned int c2;
+ unsigned int c3;
+ unsigned int total;
+
+ /* MVMCP -- need #defs for these registers */
+ c0 = tx4938_process_sdccr((u64 *) 0xff1f8000);
+ c1 = tx4938_process_sdccr((u64 *) 0xff1f8008);
+ c2 = tx4938_process_sdccr((u64 *) 0xff1f8010);
+ c3 = tx4938_process_sdccr((u64 *) 0xff1f8018);
+ total = c0 + c1 + c2 + c3;
+
+ return (total);
+}
diff --git a/arch/mips/tx4938/common/rtc_rx5c348.c b/arch/mips/tx4938/common/rtc_rx5c348.c
new file mode 100644
index 000000000000..d249edbb6af4
--- /dev/null
+++ b/arch/mips/tx4938/common/rtc_rx5c348.c
@@ -0,0 +1,202 @@
+/*
+ * RTC routines for RICOH Rx5C348 SPI chip.
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/rtc.h>
+#include <linux/time.h>
+#include <asm/time.h>
+#include <asm/tx4938/spi.h>
+
+#define EPOCH 2000
+
+/* registers */
+#define Rx5C348_REG_SECOND 0
+#define Rx5C348_REG_MINUTE 1
+#define Rx5C348_REG_HOUR 2
+#define Rx5C348_REG_WEEK 3
+#define Rx5C348_REG_DAY 4
+#define Rx5C348_REG_MONTH 5
+#define Rx5C348_REG_YEAR 6
+#define Rx5C348_REG_ADJUST 7
+#define Rx5C348_REG_ALARM_W_MIN 8
+#define Rx5C348_REG_ALARM_W_HOUR 9
+#define Rx5C348_REG_ALARM_W_WEEK 10
+#define Rx5C348_REG_ALARM_D_MIN 11
+#define Rx5C348_REG_ALARM_D_HOUR 12
+#define Rx5C348_REG_CTL1 14
+#define Rx5C348_REG_CTL2 15
+
+/* register bits */
+#define Rx5C348_BIT_PM 0x20 /* REG_HOUR */
+#define Rx5C348_BIT_Y2K 0x80 /* REG_MONTH */
+#define Rx5C348_BIT_24H 0x20 /* REG_CTL1 */
+#define Rx5C348_BIT_XSTP 0x10 /* REG_CTL2 */
+
+/* commands */
+#define Rx5C348_CMD_W(addr) (((addr) << 4) | 0x08) /* single write */
+#define Rx5C348_CMD_R(addr) (((addr) << 4) | 0x0c) /* single read */
+#define Rx5C348_CMD_MW(addr) (((addr) << 4) | 0x00) /* burst write */
+#define Rx5C348_CMD_MR(addr) (((addr) << 4) | 0x04) /* burst read */
+
+static struct spi_dev_desc srtc_dev_desc = {
+ .baud = 1000000, /* 1.0Mbps @ Vdd 2.0V */
+ .tcss = 31,
+ .tcsh = 1,
+ .tcsr = 62,
+ /* 31us for Tcss (62us for Tcsr) is required for carry operation) */
+ .byteorder = 1, /* MSB-First */
+ .polarity = 0, /* High-Active */
+ .phase = 1, /* Shift-Then-Sample */
+
+};
+static int srtc_chipid;
+static int srtc_24h;
+
+static inline int
+spi_rtc_io(unsigned char *inbuf, unsigned char *outbuf, unsigned int count)
+{
+ unsigned char *inbufs[1], *outbufs[1];
+ unsigned int incounts[2], outcounts[2];
+ inbufs[0] = inbuf;
+ incounts[0] = count;
+ incounts[1] = 0;
+ outbufs[0] = outbuf;
+ outcounts[0] = count;
+ outcounts[1] = 0;
+ return txx9_spi_io(srtc_chipid, &srtc_dev_desc,
+ inbufs, incounts, outbufs, outcounts, 0);
+}
+
+/*
+ * Conversion between binary and BCD.
+ */
+#ifndef BCD_TO_BIN
+#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
+#endif
+
+#ifndef BIN_TO_BCD
+#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
+#endif
+
+/* RTC-dependent code for time.c */
+
+static int
+rtc_rx5c348_set_time(unsigned long t)
+{
+ unsigned char inbuf[8];
+ struct rtc_time tm;
+ u8 year, month, day, hour, minute, second, century;
+
+ /* convert */
+ to_tm(t, &tm);
+
+ year = tm.tm_year % 100;
+ month = tm.tm_mon+1; /* tm_mon starts from 0 to 11 */
+ day = tm.tm_mday;
+ hour = tm.tm_hour;
+ minute = tm.tm_min;
+ second = tm.tm_sec;
+ century = tm.tm_year / 100;
+
+ inbuf[0] = Rx5C348_CMD_MW(Rx5C348_REG_SECOND);
+ BIN_TO_BCD(second);
+ inbuf[1] = second;
+ BIN_TO_BCD(minute);
+ inbuf[2] = minute;
+
+ if (srtc_24h) {
+ BIN_TO_BCD(hour);
+ inbuf[3] = hour;
+ } else {
+ /* hour 0 is AM12, noon is PM12 */
+ inbuf[3] = 0;
+ if (hour >= 12)
+ inbuf[3] = Rx5C348_BIT_PM;
+ hour = (hour + 11) % 12 + 1;
+ BIN_TO_BCD(hour);
+ inbuf[3] |= hour;
+ }
+ inbuf[4] = 0; /* ignore week */
+ BIN_TO_BCD(day);
+ inbuf[5] = day;
+ BIN_TO_BCD(month);
+ inbuf[6] = month;
+ if (century >= 20)
+ inbuf[6] |= Rx5C348_BIT_Y2K;
+ BIN_TO_BCD(year);
+ inbuf[7] = year;
+ /* write in one transfer to avoid data inconsistency */
+ return spi_rtc_io(inbuf, NULL, 8);
+}
+
+static unsigned long
+rtc_rx5c348_get_time(void)
+{
+ unsigned char inbuf[8], outbuf[8];
+ unsigned int year, month, day, hour, minute, second;
+
+ inbuf[0] = Rx5C348_CMD_MR(Rx5C348_REG_SECOND);
+ memset(inbuf + 1, 0, 7);
+ /* read in one transfer to avoid data inconsistency */
+ if (spi_rtc_io(inbuf, outbuf, 8))
+ return 0;
+ second = outbuf[1];
+ BCD_TO_BIN(second);
+ minute = outbuf[2];
+ BCD_TO_BIN(minute);
+ if (srtc_24h) {
+ hour = outbuf[3];
+ BCD_TO_BIN(hour);
+ } else {
+ hour = outbuf[3] & ~Rx5C348_BIT_PM;
+ BCD_TO_BIN(hour);
+ hour %= 12;
+ if (outbuf[3] & Rx5C348_BIT_PM)
+ hour += 12;
+ }
+ day = outbuf[5];
+ BCD_TO_BIN(day);
+ month = outbuf[6] & ~Rx5C348_BIT_Y2K;
+ BCD_TO_BIN(month);
+ year = outbuf[7];
+ BCD_TO_BIN(year);
+ year += EPOCH;
+
+ return mktime(year, month, day, hour, minute, second);
+}
+
+void __init
+rtc_rx5c348_init(int chipid)
+{
+ unsigned char inbuf[2], outbuf[2];
+ srtc_chipid = chipid;
+ /* turn on RTC if it is not on */
+ inbuf[0] = Rx5C348_CMD_R(Rx5C348_REG_CTL2);
+ inbuf[1] = 0;
+ spi_rtc_io(inbuf, outbuf, 2);
+ if (outbuf[1] & Rx5C348_BIT_XSTP) {
+ inbuf[0] = Rx5C348_CMD_W(Rx5C348_REG_CTL2);
+ inbuf[1] = 0;
+ spi_rtc_io(inbuf, NULL, 2);
+ }
+
+ inbuf[0] = Rx5C348_CMD_R(Rx5C348_REG_CTL1);
+ inbuf[1] = 0;
+ spi_rtc_io(inbuf, outbuf, 2);
+ if (outbuf[1] & Rx5C348_BIT_24H)
+ srtc_24h = 1;
+
+ /* set the function pointers */
+ rtc_get_time = rtc_rx5c348_get_time;
+ rtc_set_time = rtc_rx5c348_set_time;
+}
diff --git a/arch/mips/tx4938/common/setup.c b/arch/mips/tx4938/common/setup.c
new file mode 100644
index 000000000000..fc992953bf95
--- /dev/null
+++ b/arch/mips/tx4938/common/setup.c
@@ -0,0 +1,91 @@
+/*
+ * linux/arch/mips/tx4938/common/setup.c
+ *
+ * common tx4938 setup routines
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/irq.h>
+#include <asm/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/time.h>
+#include <asm/tx4938/rbtx4938.h>
+
+extern void toshiba_rbtx4938_setup(void);
+extern void rbtx4938_time_init(void);
+
+void __init tx4938_setup(void);
+void __init tx4938_time_init(void);
+void __init tx4938_timer_setup(struct irqaction *irq);
+void dump_cp0(char *key);
+
+void (*__wbflush) (void);
+
+static void
+tx4938_write_buffer_flush(void)
+{
+ mmiowb();
+
+ __asm__ __volatile__(
+ ".set push\n\t"
+ ".set noreorder\n\t"
+ "lw $0,%0\n\t"
+ "nop\n\t"
+ ".set pop"
+ : /* no output */
+ : "m" (*(int *)KSEG1)
+ : "memory");
+}
+
+void __init
+plat_setup(void)
+{
+ board_time_init = tx4938_time_init;
+ board_timer_setup = tx4938_timer_setup;
+ __wbflush = tx4938_write_buffer_flush;
+ toshiba_rbtx4938_setup();
+}
+
+void __init
+tx4938_time_init(void)
+{
+ rbtx4938_time_init();
+}
+
+void __init
+tx4938_timer_setup(struct irqaction *irq)
+{
+ u32 count;
+ u32 c1;
+ u32 c2;
+
+ setup_irq(TX4938_IRQ_CPU_TIMER, irq);
+
+ c1 = read_c0_count();
+ count = c1 + (mips_hpt_frequency / HZ);
+ write_c0_compare(count);
+ c2 = read_c0_count();
+}
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/Makefile b/arch/mips/tx4938/toshiba_rbtx4938/Makefile
new file mode 100644
index 000000000000..226941279d75
--- /dev/null
+++ b/arch/mips/tx4938/toshiba_rbtx4938/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for common code for Toshiba TX4927 based systems
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+obj-y += prom.o setup.o irq.o spi_eeprom.o spi_txx9.o
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/irq.c b/arch/mips/tx4938/toshiba_rbtx4938/irq.c
new file mode 100644
index 000000000000..230f5a93c2e6
--- /dev/null
+++ b/arch/mips/tx4938/toshiba_rbtx4938/irq.c
@@ -0,0 +1,244 @@
+/*
+ * linux/arch/mips/tx4938/toshiba_rbtx4938/irq.c
+ *
+ * Toshiba RBTX4938 specific interrupt handlers
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+
+/*
+IRQ Device
+
+16 TX4938-CP0/00 Software 0
+17 TX4938-CP0/01 Software 1
+18 TX4938-CP0/02 Cascade TX4938-CP0
+19 TX4938-CP0/03 Multiplexed -- do not use
+20 TX4938-CP0/04 Multiplexed -- do not use
+21 TX4938-CP0/05 Multiplexed -- do not use
+22 TX4938-CP0/06 Multiplexed -- do not use
+23 TX4938-CP0/07 CPU TIMER
+
+24 TX4938-PIC/00
+25 TX4938-PIC/01
+26 TX4938-PIC/02 Cascade RBTX4938-IOC
+27 TX4938-PIC/03 RBTX4938 RTL-8019AS Ethernet
+28 TX4938-PIC/04
+29 TX4938-PIC/05 TX4938 ETH1
+30 TX4938-PIC/06 TX4938 ETH0
+31 TX4938-PIC/07
+32 TX4938-PIC/08 TX4938 SIO 0
+33 TX4938-PIC/09 TX4938 SIO 1
+34 TX4938-PIC/10 TX4938 DMA0
+35 TX4938-PIC/11 TX4938 DMA1
+36 TX4938-PIC/12 TX4938 DMA2
+37 TX4938-PIC/13 TX4938 DMA3
+38 TX4938-PIC/14
+39 TX4938-PIC/15
+40 TX4938-PIC/16 TX4938 PCIC
+41 TX4938-PIC/17 TX4938 TMR0
+42 TX4938-PIC/18 TX4938 TMR1
+43 TX4938-PIC/19 TX4938 TMR2
+44 TX4938-PIC/20
+45 TX4938-PIC/21
+46 TX4938-PIC/22 TX4938 PCIERR
+47 TX4938-PIC/23
+48 TX4938-PIC/24
+49 TX4938-PIC/25
+50 TX4938-PIC/26
+51 TX4938-PIC/27
+52 TX4938-PIC/28
+53 TX4938-PIC/29
+54 TX4938-PIC/30
+55 TX4938-PIC/31 TX4938 SPI
+
+56 RBTX4938-IOC/00 PCI-D
+57 RBTX4938-IOC/01 PCI-C
+58 RBTX4938-IOC/02 PCI-B
+59 RBTX4938-IOC/03 PCI-A
+60 RBTX4938-IOC/04 RTC
+61 RBTX4938-IOC/05 ATA
+62 RBTX4938-IOC/06 MODEM
+63 RBTX4938-IOC/07 SWINT
+*/
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/timex.h>
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/reboot.h>
+#include <asm/time.h>
+#include <linux/version.h>
+#include <linux/bootmem.h>
+#include <asm/tx4938/rbtx4938.h>
+
+static unsigned int toshiba_rbtx4938_irq_ioc_startup(unsigned int irq);
+static void toshiba_rbtx4938_irq_ioc_shutdown(unsigned int irq);
+static void toshiba_rbtx4938_irq_ioc_enable(unsigned int irq);
+static void toshiba_rbtx4938_irq_ioc_disable(unsigned int irq);
+static void toshiba_rbtx4938_irq_ioc_mask_and_ack(unsigned int irq);
+static void toshiba_rbtx4938_irq_ioc_end(unsigned int irq);
+
+DEFINE_SPINLOCK(toshiba_rbtx4938_ioc_lock);
+
+#define TOSHIBA_RBTX4938_IOC_NAME "RBTX4938-IOC"
+static struct hw_interrupt_type toshiba_rbtx4938_irq_ioc_type = {
+ .typename = TOSHIBA_RBTX4938_IOC_NAME,
+ .startup = toshiba_rbtx4938_irq_ioc_startup,
+ .shutdown = toshiba_rbtx4938_irq_ioc_shutdown,
+ .enable = toshiba_rbtx4938_irq_ioc_enable,
+ .disable = toshiba_rbtx4938_irq_ioc_disable,
+ .ack = toshiba_rbtx4938_irq_ioc_mask_and_ack,
+ .end = toshiba_rbtx4938_irq_ioc_end,
+ .set_affinity = NULL
+};
+
+#define TOSHIBA_RBTX4938_IOC_INTR_ENAB 0xb7f02000
+#define TOSHIBA_RBTX4938_IOC_INTR_STAT 0xb7f0200a
+
+int
+toshiba_rbtx4938_irq_nested(int sw_irq)
+{
+ u8 level3;
+
+ level3 = reg_rd08(TOSHIBA_RBTX4938_IOC_INTR_STAT) & 0xff;
+ if (level3) {
+ /* must use fls so onboard ATA has priority */
+ sw_irq = TOSHIBA_RBTX4938_IRQ_IOC_BEG + fls(level3) - 1;
+ }
+
+ wbflush();
+ return sw_irq;
+}
+
+static struct irqaction toshiba_rbtx4938_irq_ioc_action = {
+ .handler = no_action,
+ .flags = 0,
+ .mask = CPU_MASK_NONE,
+ .name = TOSHIBA_RBTX4938_IOC_NAME,
+};
+
+/**********************************************************************************/
+/* Functions for ioc */
+/**********************************************************************************/
+static void __init
+toshiba_rbtx4938_irq_ioc_init(void)
+{
+ int i;
+
+ for (i = TOSHIBA_RBTX4938_IRQ_IOC_BEG;
+ i <= TOSHIBA_RBTX4938_IRQ_IOC_END; i++) {
+ irq_desc[i].status = IRQ_DISABLED;
+ irq_desc[i].action = 0;
+ irq_desc[i].depth = 3;
+ irq_desc[i].handler = &toshiba_rbtx4938_irq_ioc_type;
+ }
+
+ setup_irq(RBTX4938_IRQ_IOCINT,
+ &toshiba_rbtx4938_irq_ioc_action);
+}
+
+static unsigned int
+toshiba_rbtx4938_irq_ioc_startup(unsigned int irq)
+{
+ toshiba_rbtx4938_irq_ioc_enable(irq);
+
+ return 0;
+}
+
+static void
+toshiba_rbtx4938_irq_ioc_shutdown(unsigned int irq)
+{
+ toshiba_rbtx4938_irq_ioc_disable(irq);
+}
+
+static void
+toshiba_rbtx4938_irq_ioc_enable(unsigned int irq)
+{
+ unsigned long flags;
+ volatile unsigned char v;
+
+ spin_lock_irqsave(&toshiba_rbtx4938_ioc_lock, flags);
+
+ v = TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB);
+ v |= (1 << (irq - TOSHIBA_RBTX4938_IRQ_IOC_BEG));
+ TX4938_WR08(TOSHIBA_RBTX4938_IOC_INTR_ENAB, v);
+ mmiowb();
+ TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB);
+
+ spin_unlock_irqrestore(&toshiba_rbtx4938_ioc_lock, flags);
+}
+
+static void
+toshiba_rbtx4938_irq_ioc_disable(unsigned int irq)
+{
+ unsigned long flags;
+ volatile unsigned char v;
+
+ spin_lock_irqsave(&toshiba_rbtx4938_ioc_lock, flags);
+
+ v = TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB);
+ v &= ~(1 << (irq - TOSHIBA_RBTX4938_IRQ_IOC_BEG));
+ TX4938_WR08(TOSHIBA_RBTX4938_IOC_INTR_ENAB, v);
+ mmiowb();
+ TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB);
+
+ spin_unlock_irqrestore(&toshiba_rbtx4938_ioc_lock, flags);
+}
+
+static void
+toshiba_rbtx4938_irq_ioc_mask_and_ack(unsigned int irq)
+{
+ toshiba_rbtx4938_irq_ioc_disable(irq);
+}
+
+static void
+toshiba_rbtx4938_irq_ioc_end(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+ toshiba_rbtx4938_irq_ioc_enable(irq);
+ }
+}
+
+extern void __init txx9_spi_irqinit(int irc_irq);
+
+void __init arch_init_irq(void)
+{
+ extern void tx4938_irq_init(void);
+
+ /* Now, interrupt control disabled, */
+ /* all IRC interrupts are masked, */
+ /* all IRC interrupt mode are Low Active. */
+
+ /* mask all IOC interrupts */
+ *rbtx4938_imask_ptr = 0;
+
+ /* clear SoftInt interrupts */
+ *rbtx4938_softint_ptr = 0;
+ tx4938_irq_init();
+ toshiba_rbtx4938_irq_ioc_init();
+ /* Onboard 10M Ether: High Active */
+ TX4938_WR(TX4938_MKA(TX4938_IRC_IRDM0), 0x00000040);
+
+ if (tx4938_ccfgptr->pcfg & TX4938_PCFG_SPI_SEL) {
+ txx9_spi_irqinit(RBTX4938_IRQ_IRC_SPI);
+ }
+
+ wbflush();
+}
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/prom.c b/arch/mips/tx4938/toshiba_rbtx4938/prom.c
new file mode 100644
index 000000000000..7df8b32ba265
--- /dev/null
+++ b/arch/mips/tx4938/toshiba_rbtx4938/prom.c
@@ -0,0 +1,78 @@
+/*
+ * linux/arch/mips/tx4938/toshiba_rbtx4938/prom.c
+ *
+ * rbtx4938 specific prom routines
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/tx4938/tx4938.h>
+
+void __init prom_init_cmdline(void)
+{
+ int argc = (int) fw_arg0;
+ char **argv = (char **) fw_arg1;
+ int i;
+
+ /* ignore all built-in args if any f/w args given */
+ if (argc > 1) {
+ *arcs_cmdline = '\0';
+ }
+
+ for (i = 1; i < argc; i++) {
+ if (i != 1) {
+ strcat(arcs_cmdline, " ");
+ }
+ strcat(arcs_cmdline, argv[i]);
+ }
+}
+
+void __init prom_init(void)
+{
+ extern int tx4938_get_mem_size(void);
+ int msize;
+#ifndef CONFIG_TX4938_NAND_BOOT
+ prom_init_cmdline();
+#endif
+ mips_machgroup = MACH_GROUP_TOSHIBA;
+ mips_machtype = MACH_TOSHIBA_RBTX4938;
+
+ msize = tx4938_get_mem_size();
+ add_memory_region(0, msize << 20, BOOT_MEM_RAM);
+
+ return;
+}
+
+unsigned long __init prom_free_prom_memory(void)
+{
+ return 0;
+}
+
+void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
+{
+ return;
+}
+
+const char *get_system_type(void)
+{
+ return "Toshiba RBTX4938";
+}
+
+char * __init prom_getcmdline(void)
+{
+ return &(arcs_cmdline[0]);
+}
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
new file mode 100644
index 000000000000..9f1dcc8ca5a3
--- /dev/null
+++ b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
@@ -0,0 +1,1035 @@
+/*
+ * linux/arch/mips/tx4938/toshiba_rbtx4938/setup.c
+ *
+ * Setup pointers to hardware-dependent routines.
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/ioport.h>
+#include <linux/proc_fs.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/console.h>
+#include <linux/pci.h>
+#include <asm/wbflush.h>
+#include <asm/reboot.h>
+#include <asm/irq.h>
+#include <asm/time.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/bootinfo.h>
+#include <asm/tx4938/rbtx4938.h>
+#ifdef CONFIG_SERIAL_TXX9
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#endif
+
+extern void rbtx4938_time_init(void) __init;
+extern char * __init prom_getcmdline(void);
+static inline void tx4938_report_pcic_status1(struct tx4938_pcic_reg *pcicptr);
+
+/* These functions are used for rebooting or halting the machine*/
+extern void rbtx4938_machine_restart(char *command);
+extern void rbtx4938_machine_halt(void);
+extern void rbtx4938_machine_power_off(void);
+
+/* clocks */
+unsigned int txx9_master_clock;
+unsigned int txx9_cpu_clock;
+unsigned int txx9_gbus_clock;
+
+unsigned long rbtx4938_ce_base[8];
+unsigned long rbtx4938_ce_size[8];
+int txboard_pci66_mode;
+static int tx4938_pcic_trdyto; /* default: disabled */
+static int tx4938_pcic_retryto; /* default: disabled */
+static int tx4938_ccfg_toeon = 1;
+
+struct tx4938_pcic_reg *pcicptrs[4] = {
+ tx4938_pcicptr /* default setting for TX4938 */
+};
+
+static struct {
+ unsigned long base;
+ unsigned long size;
+} phys_regions[16] __initdata;
+static int num_phys_regions __initdata;
+
+#define PHYS_REGION_MINSIZE 0x10000
+
+void rbtx4938_machine_halt(void)
+{
+ printk(KERN_NOTICE "System Halted\n");
+ local_irq_disable();
+
+ while (1)
+ __asm__(".set\tmips3\n\t"
+ "wait\n\t"
+ ".set\tmips0");
+}
+
+void rbtx4938_machine_power_off(void)
+{
+ rbtx4938_machine_halt();
+ /* no return */
+}
+
+void rbtx4938_machine_restart(char *command)
+{
+ local_irq_disable();
+
+ printk("Rebooting...");
+ *rbtx4938_softresetlock_ptr = 1;
+ *rbtx4938_sfvol_ptr = 1;
+ *rbtx4938_softreset_ptr = 1;
+ wbflush();
+
+ while(1);
+}
+
+void __init
+txboard_add_phys_region(unsigned long base, unsigned long size)
+{
+ if (num_phys_regions >= ARRAY_SIZE(phys_regions)) {
+ printk("phys_region overflow\n");
+ return;
+ }
+ phys_regions[num_phys_regions].base = base;
+ phys_regions[num_phys_regions].size = size;
+ num_phys_regions++;
+}
+unsigned long __init
+txboard_find_free_phys_region(unsigned long begin, unsigned long end,
+ unsigned long size)
+{
+ unsigned long base;
+ int i;
+
+ for (base = begin / size * size; base < end; base += size) {
+ for (i = 0; i < num_phys_regions; i++) {
+ if (phys_regions[i].size &&
+ base <= phys_regions[i].base + (phys_regions[i].size - 1) &&
+ base + (size - 1) >= phys_regions[i].base)
+ break;
+ }
+ if (i == num_phys_regions)
+ return base;
+ }
+ return 0;
+}
+unsigned long __init
+txboard_find_free_phys_region_shrink(unsigned long begin, unsigned long end,
+ unsigned long *size)
+{
+ unsigned long sz, base;
+ for (sz = *size; sz >= PHYS_REGION_MINSIZE; sz /= 2) {
+ base = txboard_find_free_phys_region(begin, end, sz);
+ if (base) {
+ *size = sz;
+ return base;
+ }
+ }
+ return 0;
+}
+unsigned long __init
+txboard_request_phys_region_range(unsigned long begin, unsigned long end,
+ unsigned long size)
+{
+ unsigned long base;
+ base = txboard_find_free_phys_region(begin, end, size);
+ if (base)
+ txboard_add_phys_region(base, size);
+ return base;
+}
+unsigned long __init
+txboard_request_phys_region(unsigned long size)
+{
+ unsigned long base;
+ unsigned long begin = 0, end = 0x20000000; /* search low 512MB */
+ base = txboard_find_free_phys_region(begin, end, size);
+ if (base)
+ txboard_add_phys_region(base, size);
+ return base;
+}
+unsigned long __init
+txboard_request_phys_region_shrink(unsigned long *size)
+{
+ unsigned long base;
+ unsigned long begin = 0, end = 0x20000000; /* search low 512MB */
+ base = txboard_find_free_phys_region_shrink(begin, end, size);
+ if (base)
+ txboard_add_phys_region(base, *size);
+ return base;
+}
+
+#ifdef CONFIG_PCI
+void __init
+tx4938_pcic_setup(struct tx4938_pcic_reg *pcicptr,
+ struct pci_controller *channel,
+ unsigned long pci_io_base,
+ int extarb)
+{
+ int i;
+
+ /* Disable All Initiator Space */
+ pcicptr->pciccfg &= ~(TX4938_PCIC_PCICCFG_G2PMEN(0)|
+ TX4938_PCIC_PCICCFG_G2PMEN(1)|
+ TX4938_PCIC_PCICCFG_G2PMEN(2)|
+ TX4938_PCIC_PCICCFG_G2PIOEN);
+
+ /* GB->PCI mappings */
+ pcicptr->g2piomask = (channel->io_resource->end - channel->io_resource->start) >> 4;
+ pcicptr->g2piogbase = pci_io_base |
+#ifdef __BIG_ENDIAN
+ TX4938_PCIC_G2PIOGBASE_ECHG
+#else
+ TX4938_PCIC_G2PIOGBASE_BSDIS
+#endif
+ ;
+ pcicptr->g2piopbase = 0;
+ for (i = 0; i < 3; i++) {
+ pcicptr->g2pmmask[i] = 0;
+ pcicptr->g2pmgbase[i] = 0;
+ pcicptr->g2pmpbase[i] = 0;
+ }
+ if (channel->mem_resource->end) {
+ pcicptr->g2pmmask[0] = (channel->mem_resource->end - channel->mem_resource->start) >> 4;
+ pcicptr->g2pmgbase[0] = channel->mem_resource->start |
+#ifdef __BIG_ENDIAN
+ TX4938_PCIC_G2PMnGBASE_ECHG
+#else
+ TX4938_PCIC_G2PMnGBASE_BSDIS
+#endif
+ ;
+ pcicptr->g2pmpbase[0] = channel->mem_resource->start;
+ }
+ /* PCI->GB mappings (I/O 256B) */
+ pcicptr->p2giopbase = 0; /* 256B */
+ pcicptr->p2giogbase = 0;
+ /* PCI->GB mappings (MEM 512MB (64MB on R1.x)) */
+ pcicptr->p2gm0plbase = 0;
+ pcicptr->p2gm0pubase = 0;
+ pcicptr->p2gmgbase[0] = 0 |
+ TX4938_PCIC_P2GMnGBASE_TMEMEN |
+#ifdef __BIG_ENDIAN
+ TX4938_PCIC_P2GMnGBASE_TECHG
+#else
+ TX4938_PCIC_P2GMnGBASE_TBSDIS
+#endif
+ ;
+ /* PCI->GB mappings (MEM 16MB) */
+ pcicptr->p2gm1plbase = 0xffffffff;
+ pcicptr->p2gm1pubase = 0xffffffff;
+ pcicptr->p2gmgbase[1] = 0;
+ /* PCI->GB mappings (MEM 1MB) */
+ pcicptr->p2gm2pbase = 0xffffffff; /* 1MB */
+ pcicptr->p2gmgbase[2] = 0;
+
+ pcicptr->pciccfg &= TX4938_PCIC_PCICCFG_GBWC_MASK;
+ /* Enable Initiator Memory Space */
+ if (channel->mem_resource->end)
+ pcicptr->pciccfg |= TX4938_PCIC_PCICCFG_G2PMEN(0);
+ /* Enable Initiator I/O Space */
+ if (channel->io_resource->end)
+ pcicptr->pciccfg |= TX4938_PCIC_PCICCFG_G2PIOEN;
+ /* Enable Initiator Config */
+ pcicptr->pciccfg |=
+ TX4938_PCIC_PCICCFG_ICAEN |
+ TX4938_PCIC_PCICCFG_TCAR;
+
+ /* Do not use MEMMUL, MEMINF: YMFPCI card causes M_ABORT. */
+ pcicptr->pcicfg1 = 0;
+
+ pcicptr->g2ptocnt &= ~0xffff;
+
+ if (tx4938_pcic_trdyto >= 0) {
+ pcicptr->g2ptocnt &= ~0xff;
+ pcicptr->g2ptocnt |= (tx4938_pcic_trdyto & 0xff);
+ }
+
+ if (tx4938_pcic_retryto >= 0) {
+ pcicptr->g2ptocnt &= ~0xff00;
+ pcicptr->g2ptocnt |= ((tx4938_pcic_retryto<<8) & 0xff00);
+ }
+
+ /* Clear All Local Bus Status */
+ pcicptr->pcicstatus = TX4938_PCIC_PCICSTATUS_ALL;
+ /* Enable All Local Bus Interrupts */
+ pcicptr->pcicmask = TX4938_PCIC_PCICSTATUS_ALL;
+ /* Clear All Initiator Status */
+ pcicptr->g2pstatus = TX4938_PCIC_G2PSTATUS_ALL;
+ /* Enable All Initiator Interrupts */
+ pcicptr->g2pmask = TX4938_PCIC_G2PSTATUS_ALL;
+ /* Clear All PCI Status Error */
+ pcicptr->pcistatus =
+ (pcicptr->pcistatus & 0x0000ffff) |
+ (TX4938_PCIC_PCISTATUS_ALL << 16);
+ /* Enable All PCI Status Error Interrupts */
+ pcicptr->pcimask = TX4938_PCIC_PCISTATUS_ALL;
+
+ if (!extarb) {
+ /* Reset Bus Arbiter */
+ pcicptr->pbacfg = TX4938_PCIC_PBACFG_RPBA;
+ pcicptr->pbabm = 0;
+ /* Enable Bus Arbiter */
+ pcicptr->pbacfg = TX4938_PCIC_PBACFG_PBAEN;
+ }
+
+ /* PCIC Int => IRC IRQ16 */
+ pcicptr->pcicfg2 =
+ (pcicptr->pcicfg2 & 0xffffff00) | TX4938_IR_PCIC;
+
+ pcicptr->pcistatus = PCI_COMMAND_MASTER |
+ PCI_COMMAND_MEMORY |
+ PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
+}
+
+int __init
+tx4938_report_pciclk(void)
+{
+ unsigned long pcode = TX4938_REV_PCODE();
+ int pciclk = 0;
+ printk("TX%lx PCIC --%s PCICLK:",
+ pcode,
+ (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI66) ? " PCI66" : "");
+ if (tx4938_ccfgptr->pcfg & TX4938_PCFG_PCICLKEN_ALL) {
+
+ switch ((unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIDIVMODE_MASK) {
+ case TX4938_CCFG_PCIDIVMODE_4:
+ pciclk = txx9_cpu_clock / 4; break;
+ case TX4938_CCFG_PCIDIVMODE_4_5:
+ pciclk = txx9_cpu_clock * 2 / 9; break;
+ case TX4938_CCFG_PCIDIVMODE_5:
+ pciclk = txx9_cpu_clock / 5; break;
+ case TX4938_CCFG_PCIDIVMODE_5_5:
+ pciclk = txx9_cpu_clock * 2 / 11; break;
+ case TX4938_CCFG_PCIDIVMODE_8:
+ pciclk = txx9_cpu_clock / 8; break;
+ case TX4938_CCFG_PCIDIVMODE_9:
+ pciclk = txx9_cpu_clock / 9; break;
+ case TX4938_CCFG_PCIDIVMODE_10:
+ pciclk = txx9_cpu_clock / 10; break;
+ case TX4938_CCFG_PCIDIVMODE_11:
+ pciclk = txx9_cpu_clock / 11; break;
+ }
+ printk("Internal(%dMHz)", pciclk / 1000000);
+ } else {
+ printk("External");
+ pciclk = -1;
+ }
+ printk("\n");
+ return pciclk;
+}
+
+void __init set_tx4938_pcicptr(int ch, struct tx4938_pcic_reg *pcicptr)
+{
+ pcicptrs[ch] = pcicptr;
+}
+
+struct tx4938_pcic_reg *get_tx4938_pcicptr(int ch)
+{
+ return pcicptrs[ch];
+}
+
+static struct pci_dev *fake_pci_dev(struct pci_controller *hose,
+ int top_bus, int busnr, int devfn)
+{
+ static struct pci_dev dev;
+ static struct pci_bus bus;
+
+ dev.sysdata = (void *)hose;
+ dev.devfn = devfn;
+ bus.number = busnr;
+ bus.ops = hose->pci_ops;
+ bus.parent = NULL;
+ dev.bus = &bus;
+
+ return &dev;
+}
+
+#define EARLY_PCI_OP(rw, size, type) \
+static int early_##rw##_config_##size(struct pci_controller *hose, \
+ int top_bus, int bus, int devfn, int offset, type value) \
+{ \
+ return pci_##rw##_config_##size( \
+ fake_pci_dev(hose, top_bus, bus, devfn), \
+ offset, value); \
+}
+
+EARLY_PCI_OP(read, word, u16 *)
+
+int txboard_pci66_check(struct pci_controller *hose, int top_bus, int current_bus)
+{
+ u32 pci_devfn;
+ unsigned short vid;
+ int devfn_start = 0;
+ int devfn_stop = 0xff;
+ int cap66 = -1;
+ u16 stat;
+
+ printk("PCI: Checking 66MHz capabilities...\n");
+
+ for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) {
+ early_read_config_word(hose, top_bus, current_bus, pci_devfn,
+ PCI_VENDOR_ID, &vid);
+
+ if (vid == 0xffff) continue;
+
+ /* check 66MHz capability */
+ if (cap66 < 0)
+ cap66 = 1;
+ if (cap66) {
+ early_read_config_word(hose, top_bus, current_bus, pci_devfn,
+ PCI_STATUS, &stat);
+ if (!(stat & PCI_STATUS_66MHZ)) {
+ printk(KERN_DEBUG "PCI: %02x:%02x not 66MHz capable.\n",
+ current_bus, pci_devfn);
+ cap66 = 0;
+ break;
+ }
+ }
+ }
+ return cap66 > 0;
+}
+
+int __init
+tx4938_pciclk66_setup(void)
+{
+ int pciclk;
+
+ /* Assert M66EN */
+ tx4938_ccfgptr->ccfg |= TX4938_CCFG_PCI66;
+ /* Double PCICLK (if possible) */
+ if (tx4938_ccfgptr->pcfg & TX4938_PCFG_PCICLKEN_ALL) {
+ unsigned int pcidivmode =
+ tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIDIVMODE_MASK;
+ switch (pcidivmode) {
+ case TX4938_CCFG_PCIDIVMODE_8:
+ case TX4938_CCFG_PCIDIVMODE_4:
+ pcidivmode = TX4938_CCFG_PCIDIVMODE_4;
+ pciclk = txx9_cpu_clock / 4;
+ break;
+ case TX4938_CCFG_PCIDIVMODE_9:
+ case TX4938_CCFG_PCIDIVMODE_4_5:
+ pcidivmode = TX4938_CCFG_PCIDIVMODE_4_5;
+ pciclk = txx9_cpu_clock * 2 / 9;
+ break;
+ case TX4938_CCFG_PCIDIVMODE_10:
+ case TX4938_CCFG_PCIDIVMODE_5:
+ pcidivmode = TX4938_CCFG_PCIDIVMODE_5;
+ pciclk = txx9_cpu_clock / 5;
+ break;
+ case TX4938_CCFG_PCIDIVMODE_11:
+ case TX4938_CCFG_PCIDIVMODE_5_5:
+ default:
+ pcidivmode = TX4938_CCFG_PCIDIVMODE_5_5;
+ pciclk = txx9_cpu_clock * 2 / 11;
+ break;
+ }
+ tx4938_ccfgptr->ccfg =
+ (tx4938_ccfgptr->ccfg & ~TX4938_CCFG_PCIDIVMODE_MASK)
+ | pcidivmode;
+ printk(KERN_DEBUG "PCICLK: ccfg:%08lx\n",
+ (unsigned long)tx4938_ccfgptr->ccfg);
+ } else {
+ pciclk = -1;
+ }
+ return pciclk;
+}
+
+extern struct pci_controller tx4938_pci_controller[];
+static int __init tx4938_pcibios_init(void)
+{
+ unsigned long mem_base[2];
+ unsigned long mem_size[2] = {TX4938_PCIMEM_SIZE_0,TX4938_PCIMEM_SIZE_1}; /* MAX 128M,64K */
+ unsigned long io_base[2];
+ unsigned long io_size[2] = {TX4938_PCIIO_SIZE_0,TX4938_PCIIO_SIZE_1}; /* MAX 16M,64K */
+ /* TX4938 PCIC1: 64K MEM/IO is enough for ETH0,ETH1 */
+ int extarb = !(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB);
+
+ PCIBIOS_MIN_IO = 0x00001000UL;
+ PCIBIOS_MIN_MEM = 0x01000000UL;
+
+ mem_base[0] = txboard_request_phys_region_shrink(&mem_size[0]);
+ io_base[0] = txboard_request_phys_region_shrink(&io_size[0]);
+
+ printk("TX4938 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n",
+ (unsigned short)(tx4938_pcicptr->pciid >> 16),
+ (unsigned short)(tx4938_pcicptr->pciid & 0xffff),
+ (unsigned short)(tx4938_pcicptr->pciccrev & 0xff),
+ extarb ? "External" : "Internal");
+
+ /* setup PCI area */
+ tx4938_pci_controller[0].io_resource->start = io_base[0];
+ tx4938_pci_controller[0].io_resource->end = (io_base[0] + io_size[0]) - 1;
+ tx4938_pci_controller[0].mem_resource->start = mem_base[0];
+ tx4938_pci_controller[0].mem_resource->end = mem_base[0] + mem_size[0] - 1;
+
+ set_tx4938_pcicptr(0, tx4938_pcicptr);
+
+ register_pci_controller(&tx4938_pci_controller[0]);
+
+ if (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI66) {
+ printk("TX4938_CCFG_PCI66 already configured\n");
+ txboard_pci66_mode = -1; /* already configured */
+ }
+
+ /* Reset PCI Bus */
+ *rbtx4938_pcireset_ptr = 0;
+ /* Reset PCIC */
+ tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIRST;
+ if (txboard_pci66_mode > 0)
+ tx4938_pciclk66_setup();
+ mdelay(10);
+ /* clear PCIC reset */
+ tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIRST;
+ *rbtx4938_pcireset_ptr = 1;
+ wbflush();
+ tx4938_report_pcic_status1(tx4938_pcicptr);
+
+ tx4938_report_pciclk();
+ tx4938_pcic_setup(tx4938_pcicptr, &tx4938_pci_controller[0], io_base[0], extarb);
+ if (txboard_pci66_mode == 0 &&
+ txboard_pci66_check(&tx4938_pci_controller[0], 0, 0)) {
+ /* Reset PCI Bus */
+ *rbtx4938_pcireset_ptr = 0;
+ /* Reset PCIC */
+ tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIRST;
+ tx4938_pciclk66_setup();
+ mdelay(10);
+ /* clear PCIC reset */
+ tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIRST;
+ *rbtx4938_pcireset_ptr = 1;
+ wbflush();
+ /* Reinitialize PCIC */
+ tx4938_report_pciclk();
+ tx4938_pcic_setup(tx4938_pcicptr, &tx4938_pci_controller[0], io_base[0], extarb);
+ }
+
+ mem_base[1] = txboard_request_phys_region_shrink(&mem_size[1]);
+ io_base[1] = txboard_request_phys_region_shrink(&io_size[1]);
+ /* Reset PCIC1 */
+ tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIC1RST;
+ /* PCI1DMD==0 => PCI1CLK==GBUSCLK/2 => PCI66 */
+ if (!(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1DMD))
+ tx4938_ccfgptr->ccfg |= TX4938_CCFG_PCI1_66;
+ else
+ tx4938_ccfgptr->ccfg &= ~TX4938_CCFG_PCI1_66;
+ mdelay(10);
+ /* clear PCIC1 reset */
+ tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIC1RST;
+ tx4938_report_pcic_status1(tx4938_pcic1ptr);
+
+ printk("TX4938 PCIC1 -- DID:%04x VID:%04x RID:%02x",
+ (unsigned short)(tx4938_pcic1ptr->pciid >> 16),
+ (unsigned short)(tx4938_pcic1ptr->pciid & 0xffff),
+ (unsigned short)(tx4938_pcic1ptr->pciccrev & 0xff));
+ printk("%s PCICLK:%dMHz\n",
+ (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1_66) ? " PCI66" : "",
+ txx9_gbus_clock /
+ ((tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1DMD) ? 4 : 2) /
+ 1000000);
+
+ /* assumption: CPHYSADDR(mips_io_port_base) == io_base[0] */
+ tx4938_pci_controller[1].io_resource->start =
+ io_base[1] - io_base[0];
+ tx4938_pci_controller[1].io_resource->end =
+ io_base[1] - io_base[0] + io_size[1] - 1;
+ tx4938_pci_controller[1].mem_resource->start = mem_base[1];
+ tx4938_pci_controller[1].mem_resource->end =
+ mem_base[1] + mem_size[1] - 1;
+ set_tx4938_pcicptr(1, tx4938_pcic1ptr);
+
+ register_pci_controller(&tx4938_pci_controller[1]);
+
+ tx4938_pcic_setup(tx4938_pcic1ptr, &tx4938_pci_controller[1], io_base[1], extarb);
+
+ /* map ioport 0 to PCI I/O space address 0 */
+ set_io_port_base(KSEG1 + io_base[0]);
+
+ return 0;
+}
+
+arch_initcall(tx4938_pcibios_init);
+
+#endif /* CONFIG_PCI */
+
+/* SPI support */
+
+/* chip select for SPI devices */
+#define SEEPROM1_CS 7 /* PIO7 */
+#define SEEPROM2_CS 0 /* IOC */
+#define SEEPROM3_CS 1 /* IOC */
+#define SRTC_CS 2 /* IOC */
+
+static int rbtx4938_spi_cs_func(int chipid, int on)
+{
+ unsigned char bit;
+ switch (chipid) {
+ case RBTX4938_SEEPROM1_CHIPID:
+ if (on)
+ tx4938_pioptr->dout &= ~(1 << SEEPROM1_CS);
+ else
+ tx4938_pioptr->dout |= (1 << SEEPROM1_CS);
+ return 0;
+ break;
+ case RBTX4938_SEEPROM2_CHIPID:
+ bit = (1 << SEEPROM2_CS);
+ break;
+ case RBTX4938_SEEPROM3_CHIPID:
+ bit = (1 << SEEPROM3_CS);
+ break;
+ case RBTX4938_SRTC_CHIPID:
+ bit = (1 << SRTC_CS);
+ break;
+ default:
+ return -ENODEV;
+ }
+ /* bit1,2,4 are low active, bit3 is high active */
+ *rbtx4938_spics_ptr =
+ (*rbtx4938_spics_ptr & ~bit) |
+ ((on ? (bit ^ 0x0b) : ~(bit ^ 0x0b)) & bit);
+ return 0;
+}
+
+#ifdef CONFIG_PCI
+extern int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len);
+
+int rbtx4938_get_tx4938_ethaddr(struct pci_dev *dev, unsigned char *addr)
+{
+ struct pci_controller *channel = (struct pci_controller *)dev->bus->sysdata;
+ static unsigned char dat[17];
+ static int read_dat = 0;
+ int ch = 0;
+
+ if (channel != &tx4938_pci_controller[1])
+ return -ENODEV;
+ /* TX4938 PCIC1 */
+ switch (PCI_SLOT(dev->devfn)) {
+ case TX4938_PCIC_IDSEL_AD_TO_SLOT(31):
+ ch = 0;
+ break;
+ case TX4938_PCIC_IDSEL_AD_TO_SLOT(30):
+ ch = 1;
+ break;
+ default:
+ return -ENODEV;
+ }
+ if (!read_dat) {
+ unsigned char sum;
+ int i;
+ read_dat = 1;
+ /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */
+ if (spi_eeprom_read(RBTX4938_SEEPROM1_CHIPID,
+ 0, dat, sizeof(dat))) {
+ printk(KERN_ERR "seeprom: read error.\n");
+ } else {
+ if (strcmp(dat, "MAC") != 0)
+ printk(KERN_WARNING "seeprom: bad signature.\n");
+ for (i = 0, sum = 0; i < sizeof(dat); i++)
+ sum += dat[i];
+ if (sum)
+ printk(KERN_WARNING "seeprom: bad checksum.\n");
+ }
+ }
+ memcpy(addr, &dat[4 + 6 * ch], 6);
+ return 0;
+}
+#endif /* CONFIG_PCI */
+
+extern void __init txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on));
+static void __init rbtx4938_spi_setup(void)
+{
+ /* set SPI_SEL */
+ tx4938_ccfgptr->pcfg |= TX4938_PCFG_SPI_SEL;
+ /* chip selects for SPI devices */
+ tx4938_pioptr->dout |= (1 << SEEPROM1_CS);
+ tx4938_pioptr->dir |= (1 << SEEPROM1_CS);
+ txx9_spi_init(TX4938_SPI_REG, rbtx4938_spi_cs_func);
+}
+
+static struct resource rbtx4938_fpga_resource;
+
+static char pcode_str[8];
+static struct resource tx4938_reg_resource = {
+ pcode_str, TX4938_REG_BASE, TX4938_REG_BASE+TX4938_REG_SIZE, IORESOURCE_MEM
+};
+
+void __init tx4938_board_setup(void)
+{
+ int i;
+ unsigned long divmode;
+ int cpuclk = 0;
+ unsigned long pcode = TX4938_REV_PCODE();
+
+ ioport_resource.start = 0x1000;
+ ioport_resource.end = 0xffffffff;
+ iomem_resource.start = 0x1000;
+ iomem_resource.end = 0xffffffff; /* expand to 4GB */
+
+ sprintf(pcode_str, "TX%lx", pcode);
+ /* SDRAMC,EBUSC are configured by PROM */
+ for (i = 0; i < 8; i++) {
+ if (!(tx4938_ebuscptr->cr[i] & 0x8))
+ continue; /* disabled */
+ rbtx4938_ce_base[i] = (unsigned long)TX4938_EBUSC_BA(i);
+ txboard_add_phys_region(rbtx4938_ce_base[i], TX4938_EBUSC_SIZE(i));
+ }
+
+ /* clocks */
+ if (txx9_master_clock) {
+ /* calculate gbus_clock and cpu_clock from master_clock */
+ divmode = (unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_DIVMODE_MASK;
+ switch (divmode) {
+ case TX4938_CCFG_DIVMODE_8:
+ case TX4938_CCFG_DIVMODE_10:
+ case TX4938_CCFG_DIVMODE_12:
+ case TX4938_CCFG_DIVMODE_16:
+ case TX4938_CCFG_DIVMODE_18:
+ txx9_gbus_clock = txx9_master_clock * 4; break;
+ default:
+ txx9_gbus_clock = txx9_master_clock;
+ }
+ switch (divmode) {
+ case TX4938_CCFG_DIVMODE_2:
+ case TX4938_CCFG_DIVMODE_8:
+ cpuclk = txx9_gbus_clock * 2; break;
+ case TX4938_CCFG_DIVMODE_2_5:
+ case TX4938_CCFG_DIVMODE_10:
+ cpuclk = txx9_gbus_clock * 5 / 2; break;
+ case TX4938_CCFG_DIVMODE_3:
+ case TX4938_CCFG_DIVMODE_12:
+ cpuclk = txx9_gbus_clock * 3; break;
+ case TX4938_CCFG_DIVMODE_4:
+ case TX4938_CCFG_DIVMODE_16:
+ cpuclk = txx9_gbus_clock * 4; break;
+ case TX4938_CCFG_DIVMODE_4_5:
+ case TX4938_CCFG_DIVMODE_18:
+ cpuclk = txx9_gbus_clock * 9 / 2; break;
+ }
+ txx9_cpu_clock = cpuclk;
+ } else {
+ if (txx9_cpu_clock == 0) {
+ txx9_cpu_clock = 300000000; /* 300MHz */
+ }
+ /* calculate gbus_clock and master_clock from cpu_clock */
+ cpuclk = txx9_cpu_clock;
+ divmode = (unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_DIVMODE_MASK;
+ switch (divmode) {
+ case TX4938_CCFG_DIVMODE_2:
+ case TX4938_CCFG_DIVMODE_8:
+ txx9_gbus_clock = cpuclk / 2; break;
+ case TX4938_CCFG_DIVMODE_2_5:
+ case TX4938_CCFG_DIVMODE_10:
+ txx9_gbus_clock = cpuclk * 2 / 5; break;
+ case TX4938_CCFG_DIVMODE_3:
+ case TX4938_CCFG_DIVMODE_12:
+ txx9_gbus_clock = cpuclk / 3; break;
+ case TX4938_CCFG_DIVMODE_4:
+ case TX4938_CCFG_DIVMODE_16:
+ txx9_gbus_clock = cpuclk / 4; break;
+ case TX4938_CCFG_DIVMODE_4_5:
+ case TX4938_CCFG_DIVMODE_18:
+ txx9_gbus_clock = cpuclk * 2 / 9; break;
+ }
+ switch (divmode) {
+ case TX4938_CCFG_DIVMODE_8:
+ case TX4938_CCFG_DIVMODE_10:
+ case TX4938_CCFG_DIVMODE_12:
+ case TX4938_CCFG_DIVMODE_16:
+ case TX4938_CCFG_DIVMODE_18:
+ txx9_master_clock = txx9_gbus_clock / 4; break;
+ default:
+ txx9_master_clock = txx9_gbus_clock;
+ }
+ }
+ /* change default value to udelay/mdelay take reasonable time */
+ loops_per_jiffy = txx9_cpu_clock / HZ / 2;
+
+ /* CCFG */
+ /* clear WatchDogReset,BusErrorOnWrite flag (W1C) */
+ tx4938_ccfgptr->ccfg |= TX4938_CCFG_WDRST | TX4938_CCFG_BEOW;
+ /* clear PCIC1 reset */
+ if (tx4938_ccfgptr->clkctr & TX4938_CLKCTR_PCIC1RST)
+ tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIC1RST;
+
+ /* enable Timeout BusError */
+ if (tx4938_ccfg_toeon)
+ tx4938_ccfgptr->ccfg |= TX4938_CCFG_TOE;
+
+ /* DMA selection */
+ tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_DMASEL_ALL;
+
+ /* Use external clock for external arbiter */
+ if (!(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB))
+ tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_PCICLKEN_ALL;
+
+ printk("%s -- %dMHz(M%dMHz) CRIR:%08lx CCFG:%Lx PCFG:%Lx\n",
+ pcode_str,
+ cpuclk / 1000000, txx9_master_clock / 1000000,
+ (unsigned long)tx4938_ccfgptr->crir,
+ tx4938_ccfgptr->ccfg,
+ tx4938_ccfgptr->pcfg);
+
+ printk("%s SDRAMC --", pcode_str);
+ for (i = 0; i < 4; i++) {
+ unsigned long long cr = tx4938_sdramcptr->cr[i];
+ unsigned long ram_base, ram_size;
+ if (!((unsigned long)cr & 0x00000400))
+ continue; /* disabled */
+ ram_base = (unsigned long)(cr >> 49) << 21;
+ ram_size = ((unsigned long)(cr >> 33) + 1) << 21;
+ if (ram_base >= 0x20000000)
+ continue; /* high memory (ignore) */
+ printk(" CR%d:%016Lx", i, cr);
+ txboard_add_phys_region(ram_base, ram_size);
+ }
+ printk(" TR:%09Lx\n", tx4938_sdramcptr->tr);
+
+ /* SRAM */
+ if (pcode == 0x4938 && tx4938_sramcptr->cr & 1) {
+ unsigned int size = 0x800;
+ unsigned long base =
+ (tx4938_sramcptr->cr >> (39-11)) & ~(size - 1);
+ txboard_add_phys_region(base, size);
+ }
+
+ /* IRC */
+ /* disable interrupt control */
+ tx4938_ircptr->cer = 0;
+
+ /* TMR */
+ /* disable all timers */
+ for (i = 0; i < TX4938_NR_TMR; i++) {
+ tx4938_tmrptr(i)->tcr = 0x00000020;
+ tx4938_tmrptr(i)->tisr = 0;
+ tx4938_tmrptr(i)->cpra = 0xffffffff;
+ tx4938_tmrptr(i)->itmr = 0;
+ tx4938_tmrptr(i)->ccdr = 0;
+ tx4938_tmrptr(i)->pgmr = 0;
+ }
+
+ /* enable DMA */
+ TX4938_WR64(0xff1fb150, TX4938_DMA_MCR_MSTEN);
+ TX4938_WR64(0xff1fb950, TX4938_DMA_MCR_MSTEN);
+
+ /* PIO */
+ tx4938_pioptr->maskcpu = 0;
+ tx4938_pioptr->maskext = 0;
+
+ /* TX4938 internal registers */
+ if (request_resource(&iomem_resource, &tx4938_reg_resource))
+ printk("request resource for internal registers failed\n");
+}
+
+#ifdef CONFIG_PCI
+static inline void tx4938_report_pcic_status1(struct tx4938_pcic_reg *pcicptr)
+{
+ unsigned short pcistatus = (unsigned short)(pcicptr->pcistatus >> 16);
+ unsigned long g2pstatus = pcicptr->g2pstatus;
+ unsigned long pcicstatus = pcicptr->pcicstatus;
+ static struct {
+ unsigned long flag;
+ const char *str;
+ } pcistat_tbl[] = {
+ { PCI_STATUS_DETECTED_PARITY, "DetectedParityError" },
+ { PCI_STATUS_SIG_SYSTEM_ERROR, "SignaledSystemError" },
+ { PCI_STATUS_REC_MASTER_ABORT, "ReceivedMasterAbort" },
+ { PCI_STATUS_REC_TARGET_ABORT, "ReceivedTargetAbort" },
+ { PCI_STATUS_SIG_TARGET_ABORT, "SignaledTargetAbort" },
+ { PCI_STATUS_PARITY, "MasterParityError" },
+ }, g2pstat_tbl[] = {
+ { TX4938_PCIC_G2PSTATUS_TTOE, "TIOE" },
+ { TX4938_PCIC_G2PSTATUS_RTOE, "RTOE" },
+ }, pcicstat_tbl[] = {
+ { TX4938_PCIC_PCICSTATUS_PME, "PME" },
+ { TX4938_PCIC_PCICSTATUS_TLB, "TLB" },
+ { TX4938_PCIC_PCICSTATUS_NIB, "NIB" },
+ { TX4938_PCIC_PCICSTATUS_ZIB, "ZIB" },
+ { TX4938_PCIC_PCICSTATUS_PERR, "PERR" },
+ { TX4938_PCIC_PCICSTATUS_SERR, "SERR" },
+ { TX4938_PCIC_PCICSTATUS_GBE, "GBE" },
+ { TX4938_PCIC_PCICSTATUS_IWB, "IWB" },
+ };
+ int i;
+
+ printk("pcistat:%04x(", pcistatus);
+ for (i = 0; i < ARRAY_SIZE(pcistat_tbl); i++)
+ if (pcistatus & pcistat_tbl[i].flag)
+ printk("%s ", pcistat_tbl[i].str);
+ printk("), g2pstatus:%08lx(", g2pstatus);
+ for (i = 0; i < ARRAY_SIZE(g2pstat_tbl); i++)
+ if (g2pstatus & g2pstat_tbl[i].flag)
+ printk("%s ", g2pstat_tbl[i].str);
+ printk("), pcicstatus:%08lx(", pcicstatus);
+ for (i = 0; i < ARRAY_SIZE(pcicstat_tbl); i++)
+ if (pcicstatus & pcicstat_tbl[i].flag)
+ printk("%s ", pcicstat_tbl[i].str);
+ printk(")\n");
+}
+
+void tx4938_report_pcic_status(void)
+{
+ int i;
+ struct tx4938_pcic_reg *pcicptr;
+ for (i = 0; (pcicptr = get_tx4938_pcicptr(i)) != NULL; i++)
+ tx4938_report_pcic_status1(pcicptr);
+}
+
+#endif /* CONFIG_PCI */
+
+/* We use onchip r4k counter or TMR timer as our system wide timer
+ * interrupt running at 100HZ. */
+
+extern void __init rtc_rx5c348_init(int chipid);
+void __init rbtx4938_time_init(void)
+{
+ rtc_rx5c348_init(RBTX4938_SRTC_CHIPID);
+ mips_hpt_frequency = txx9_cpu_clock / 2;
+}
+
+void __init toshiba_rbtx4938_setup(void)
+{
+ unsigned long long pcfg;
+ char *argptr;
+
+ iomem_resource.end = 0xffffffff; /* 4GB */
+
+ if (txx9_master_clock == 0)
+ txx9_master_clock = 25000000; /* 25MHz */
+ tx4938_board_setup();
+ /* setup irq stuff */
+ TX4938_WR(TX4938_MKA(TX4938_IRC_IRDM0), 0x00000000); /* irq trigger */
+ TX4938_WR(TX4938_MKA(TX4938_IRC_IRDM1), 0x00000000); /* irq trigger */
+ /* setup serial stuff */
+ TX4938_WR(0xff1ff314, 0x00000000); /* h/w flow control off */
+ TX4938_WR(0xff1ff414, 0x00000000); /* h/w flow control off */
+
+#ifndef CONFIG_PCI
+ set_io_port_base(RBTX4938_ETHER_BASE);
+#endif
+
+#ifdef CONFIG_SERIAL_TXX9
+ {
+ extern int early_serial_txx9_setup(struct uart_port *port);
+ int i;
+ struct uart_port req;
+ for(i = 0; i < 2; i++) {
+ memset(&req, 0, sizeof(req));
+ req.line = i;
+ req.iotype = UPIO_MEM;
+ req.membase = (char *)(0xff1ff300 + i * 0x100);
+ req.mapbase = 0xff1ff300 + i * 0x100;
+ req.irq = 32 + i;
+ req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/;
+ req.uartclk = 50000000;
+ early_serial_txx9_setup(&req);
+ }
+ }
+#ifdef CONFIG_SERIAL_TXX9_CONSOLE
+ argptr = prom_getcmdline();
+ if (strstr(argptr, "console=") == NULL) {
+ strcat(argptr, " console=ttyS0,38400");
+ }
+#endif
+#endif
+
+#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_PIO58_61
+ printk("PIOSEL: disabling both ata and nand selection\n");
+ local_irq_disable();
+ tx4938_ccfgptr->pcfg &= ~(TX4938_PCFG_NDF_SEL | TX4938_PCFG_ATA_SEL);
+#endif
+
+#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND
+ printk("PIOSEL: enabling nand selection\n");
+ tx4938_ccfgptr->pcfg |= TX4938_PCFG_NDF_SEL;
+ tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_ATA_SEL;
+#endif
+
+#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_ATA
+ printk("PIOSEL: enabling ata selection\n");
+ tx4938_ccfgptr->pcfg |= TX4938_PCFG_ATA_SEL;
+ tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_NDF_SEL;
+#endif
+
+#ifdef CONFIG_IP_PNP
+ argptr = prom_getcmdline();
+ if (strstr(argptr, "ip=") == NULL) {
+ strcat(argptr, " ip=any");
+ }
+#endif
+
+
+#ifdef CONFIG_FB
+ {
+ conswitchp = &dummy_con;
+ }
+#endif
+
+ rbtx4938_spi_setup();
+ pcfg = tx4938_ccfgptr->pcfg; /* updated */
+ /* fixup piosel */
+ if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) ==
+ TX4938_PCFG_ATA_SEL) {
+ *rbtx4938_piosel_ptr = (*rbtx4938_piosel_ptr & 0x03) | 0x04;
+ }
+ else if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) ==
+ TX4938_PCFG_NDF_SEL) {
+ *rbtx4938_piosel_ptr = (*rbtx4938_piosel_ptr & 0x03) | 0x08;
+ }
+ else {
+ *rbtx4938_piosel_ptr &= ~(0x08 | 0x04);
+ }
+
+ rbtx4938_fpga_resource.name = "FPGA Registers";
+ rbtx4938_fpga_resource.start = CPHYSADDR(RBTX4938_FPGA_REG_ADDR);
+ rbtx4938_fpga_resource.end = CPHYSADDR(RBTX4938_FPGA_REG_ADDR) + 0xffff;
+ rbtx4938_fpga_resource.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+ if (request_resource(&iomem_resource, &rbtx4938_fpga_resource))
+ printk("request resource for fpga failed\n");
+
+ /* disable all OnBoard I/O interrupts */
+ *rbtx4938_imask_ptr = 0;
+
+ _machine_restart = rbtx4938_machine_restart;
+ _machine_halt = rbtx4938_machine_halt;
+ _machine_power_off = rbtx4938_machine_power_off;
+
+ *rbtx4938_led_ptr = 0xff;
+ printk("RBTX4938 --- FPGA(Rev %02x)", *rbtx4938_fpga_rev_ptr);
+ printk(" DIPSW:%02x,%02x\n",
+ *rbtx4938_dipsw_ptr, *rbtx4938_bdipsw_ptr);
+}
+
+#ifdef CONFIG_PROC_FS
+extern void spi_eeprom_proc_create(struct proc_dir_entry *dir, int chipid);
+static int __init tx4938_spi_proc_setup(void)
+{
+ struct proc_dir_entry *tx4938_spi_eeprom_dir;
+
+ tx4938_spi_eeprom_dir = proc_mkdir("spi_eeprom", 0);
+
+ if (!tx4938_spi_eeprom_dir)
+ return -ENOMEM;
+
+ /* don't allow user access to RBTX4938_SEEPROM1_CHIPID
+ * as it contains eth0 and eth1 MAC addresses
+ */
+ spi_eeprom_proc_create(tx4938_spi_eeprom_dir, RBTX4938_SEEPROM2_CHIPID);
+ spi_eeprom_proc_create(tx4938_spi_eeprom_dir, RBTX4938_SEEPROM3_CHIPID);
+
+ return 0;
+}
+
+__initcall(tx4938_spi_proc_setup);
+#endif
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c b/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c
new file mode 100644
index 000000000000..951a208ee9b3
--- /dev/null
+++ b/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c
@@ -0,0 +1,219 @@
+/*
+ * linux/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+#include <asm/tx4938/spi.h>
+#include <asm/tx4938/tx4938.h>
+
+/* ATMEL 250x0 instructions */
+#define ATMEL_WREN 0x06
+#define ATMEL_WRDI 0x04
+#define ATMEL_RDSR 0x05
+#define ATMEL_WRSR 0x01
+#define ATMEL_READ 0x03
+#define ATMEL_WRITE 0x02
+
+#define ATMEL_SR_BSY 0x01
+#define ATMEL_SR_WEN 0x02
+#define ATMEL_SR_BP0 0x04
+#define ATMEL_SR_BP1 0x08
+
+DEFINE_SPINLOCK(spi_eeprom_lock);
+
+static struct spi_dev_desc seeprom_dev_desc = {
+ .baud = 1500000, /* 1.5Mbps */
+ .tcss = 1,
+ .tcsh = 1,
+ .tcsr = 1,
+ .byteorder = 1, /* MSB-First */
+ .polarity = 0, /* High-Active */
+ .phase = 0, /* Sample-Then-Shift */
+
+};
+static inline int
+spi_eeprom_io(int chipid,
+ unsigned char **inbufs, unsigned int *incounts,
+ unsigned char **outbufs, unsigned int *outcounts)
+{
+ return txx9_spi_io(chipid, &seeprom_dev_desc,
+ inbufs, incounts, outbufs, outcounts, 0);
+}
+
+int spi_eeprom_write_enable(int chipid, int enable)
+{
+ unsigned char inbuf[1];
+ unsigned char *inbufs[1];
+ unsigned int incounts[2];
+ unsigned long flags;
+ int stat;
+ inbuf[0] = enable ? ATMEL_WREN : ATMEL_WRDI;
+ inbufs[0] = inbuf;
+ incounts[0] = sizeof(inbuf);
+ incounts[1] = 0;
+ spin_lock_irqsave(&spi_eeprom_lock, flags);
+ stat = spi_eeprom_io(chipid, inbufs, incounts, NULL, NULL);
+ spin_unlock_irqrestore(&spi_eeprom_lock, flags);
+ return stat;
+}
+
+static int spi_eeprom_read_status_nolock(int chipid)
+{
+ unsigned char inbuf[2], outbuf[2];
+ unsigned char *inbufs[1], *outbufs[1];
+ unsigned int incounts[2], outcounts[2];
+ int stat;
+ inbuf[0] = ATMEL_RDSR;
+ inbuf[1] = 0;
+ inbufs[0] = inbuf;
+ incounts[0] = sizeof(inbuf);
+ incounts[1] = 0;
+ outbufs[0] = outbuf;
+ outcounts[0] = sizeof(outbuf);
+ outcounts[1] = 0;
+ stat = spi_eeprom_io(chipid, inbufs, incounts, outbufs, outcounts);
+ if (stat < 0)
+ return stat;
+ return outbuf[1];
+}
+
+int spi_eeprom_read_status(int chipid)
+{
+ unsigned long flags;
+ int stat;
+ spin_lock_irqsave(&spi_eeprom_lock, flags);
+ stat = spi_eeprom_read_status_nolock(chipid);
+ spin_unlock_irqrestore(&spi_eeprom_lock, flags);
+ return stat;
+}
+
+int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len)
+{
+ unsigned char inbuf[2];
+ unsigned char *inbufs[2], *outbufs[2];
+ unsigned int incounts[2], outcounts[3];
+ unsigned long flags;
+ int stat;
+ inbuf[0] = ATMEL_READ;
+ inbuf[1] = address;
+ inbufs[0] = inbuf;
+ inbufs[1] = NULL;
+ incounts[0] = sizeof(inbuf);
+ incounts[1] = 0;
+ outbufs[0] = NULL;
+ outbufs[1] = buf;
+ outcounts[0] = 2;
+ outcounts[1] = len;
+ outcounts[2] = 0;
+ spin_lock_irqsave(&spi_eeprom_lock, flags);
+ stat = spi_eeprom_io(chipid, inbufs, incounts, outbufs, outcounts);
+ spin_unlock_irqrestore(&spi_eeprom_lock, flags);
+ return stat;
+}
+
+int spi_eeprom_write(int chipid, int address, unsigned char *buf, int len)
+{
+ unsigned char inbuf[2];
+ unsigned char *inbufs[2];
+ unsigned int incounts[3];
+ unsigned long flags;
+ int i, stat;
+
+ if (address / 8 != (address + len - 1) / 8)
+ return -EINVAL;
+ stat = spi_eeprom_write_enable(chipid, 1);
+ if (stat < 0)
+ return stat;
+ stat = spi_eeprom_read_status(chipid);
+ if (stat < 0)
+ return stat;
+ if (!(stat & ATMEL_SR_WEN))
+ return -EPERM;
+
+ inbuf[0] = ATMEL_WRITE;
+ inbuf[1] = address;
+ inbufs[0] = inbuf;
+ inbufs[1] = buf;
+ incounts[0] = sizeof(inbuf);
+ incounts[1] = len;
+ incounts[2] = 0;
+ spin_lock_irqsave(&spi_eeprom_lock, flags);
+ stat = spi_eeprom_io(chipid, inbufs, incounts, NULL, NULL);
+ if (stat < 0)
+ goto unlock_return;
+
+ /* write start. max 10ms */
+ for (i = 10; i > 0; i--) {
+ int stat = spi_eeprom_read_status_nolock(chipid);
+ if (stat < 0)
+ goto unlock_return;
+ if (!(stat & ATMEL_SR_BSY))
+ break;
+ mdelay(1);
+ }
+ spin_unlock_irqrestore(&spi_eeprom_lock, flags);
+ if (i == 0)
+ return -EIO;
+ return len;
+ unlock_return:
+ spin_unlock_irqrestore(&spi_eeprom_lock, flags);
+ return stat;
+}
+
+#ifdef CONFIG_PROC_FS
+#define MAX_SIZE 0x80 /* for ATMEL 25010 */
+static int spi_eeprom_read_proc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ unsigned int size = MAX_SIZE;
+ if (spi_eeprom_read((int)data, 0, (unsigned char *)page, size) < 0)
+ size = 0;
+ return size;
+}
+
+static int spi_eeprom_write_proc(struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ unsigned int size = MAX_SIZE;
+ int i;
+ if (file->f_pos >= size)
+ return -EIO;
+ if (file->f_pos + count > size)
+ count = size - file->f_pos;
+ for (i = 0; i < count; i += 8) {
+ int len = count - i < 8 ? count - i : 8;
+ if (spi_eeprom_write((int)data, file->f_pos,
+ (unsigned char *)buffer, len) < 0) {
+ count = -EIO;
+ break;
+ }
+ buffer += len;
+ file->f_pos += len;
+ }
+ return count;
+}
+
+__init void spi_eeprom_proc_create(struct proc_dir_entry *dir, int chipid)
+{
+ struct proc_dir_entry *entry;
+ char name[128];
+ sprintf(name, "seeprom-%d", chipid);
+ entry = create_proc_entry(name, 0600, dir);
+ if (entry) {
+ entry->read_proc = spi_eeprom_read_proc;
+ entry->write_proc = spi_eeprom_write_proc;
+ entry->data = (void *)chipid;
+ }
+}
+#endif /* CONFIG_PROC_FS */
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c b/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c
new file mode 100644
index 000000000000..fae3136f462d
--- /dev/null
+++ b/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c
@@ -0,0 +1,159 @@
+/*
+ * linux/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+#include <asm/tx4938/spi.h>
+#include <asm/tx4938/tx4938.h>
+
+static int (*txx9_spi_cs_func)(int chipid, int on);
+static DEFINE_SPINLOCK(txx9_spi_lock);
+
+extern unsigned int txx9_gbus_clock;
+
+#define SPI_FIFO_SIZE 4
+
+void __init txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on))
+{
+ txx9_spi_cs_func = cs_func;
+ /* enter config mode */
+ tx4938_spiptr->mcr = TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR;
+}
+
+static DECLARE_WAIT_QUEUE_HEAD(txx9_spi_wait);
+static void txx9_spi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ /* disable rx intr */
+ tx4938_spiptr->cr0 &= ~TXx9_SPCR0_RBSIE;
+ wake_up(&txx9_spi_wait);
+}
+static struct irqaction txx9_spi_action = {
+ txx9_spi_interrupt, 0, 0, "spi", NULL, NULL,
+};
+
+void __init txx9_spi_irqinit(int irc_irq)
+{
+ setup_irq(irc_irq, &txx9_spi_action);
+}
+
+int txx9_spi_io(int chipid, struct spi_dev_desc *desc,
+ unsigned char **inbufs, unsigned int *incounts,
+ unsigned char **outbufs, unsigned int *outcounts,
+ int cansleep)
+{
+ unsigned int incount, outcount;
+ unsigned char *inp, *outp;
+ int ret;
+ unsigned long flags;
+
+ spin_lock_irqsave(&txx9_spi_lock, flags);
+ if ((tx4938_spiptr->mcr & TXx9_SPMCR_OPMODE) == TXx9_SPMCR_ACTIVE) {
+ spin_unlock_irqrestore(&txx9_spi_lock, flags);
+ return -EBUSY;
+ }
+ /* enter config mode */
+ tx4938_spiptr->mcr = TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR;
+ tx4938_spiptr->cr0 =
+ (desc->byteorder ? TXx9_SPCR0_SBOS : 0) |
+ (desc->polarity ? TXx9_SPCR0_SPOL : 0) |
+ (desc->phase ? TXx9_SPCR0_SPHA : 0) |
+ 0x08;
+ tx4938_spiptr->cr1 =
+ (((TXX9_IMCLK + desc->baud) / (2 * desc->baud) - 1) << 8) |
+ 0x08 /* 8 bit only */;
+ /* enter active mode */
+ tx4938_spiptr->mcr = TXx9_SPMCR_ACTIVE;
+ spin_unlock_irqrestore(&txx9_spi_lock, flags);
+
+ /* CS ON */
+ if ((ret = txx9_spi_cs_func(chipid, 1)) < 0) {
+ spin_unlock_irqrestore(&txx9_spi_lock, flags);
+ return ret;
+ }
+ udelay(desc->tcss);
+
+ /* do scatter IO */
+ inp = inbufs ? *inbufs : NULL;
+ outp = outbufs ? *outbufs : NULL;
+ incount = 0;
+ outcount = 0;
+ while (1) {
+ unsigned char data;
+ unsigned int count;
+ int i;
+ if (!incount) {
+ incount = incounts ? *incounts++ : 0;
+ inp = (incount && inbufs) ? *inbufs++ : NULL;
+ }
+ if (!outcount) {
+ outcount = outcounts ? *outcounts++ : 0;
+ outp = (outcount && outbufs) ? *outbufs++ : NULL;
+ }
+ if (!inp && !outp)
+ break;
+ count = SPI_FIFO_SIZE;
+ if (incount)
+ count = min(count, incount);
+ if (outcount)
+ count = min(count, outcount);
+
+ /* now tx must be idle... */
+ while (!(tx4938_spiptr->sr & TXx9_SPSR_SIDLE))
+ ;
+
+ tx4938_spiptr->cr0 =
+ (tx4938_spiptr->cr0 & ~TXx9_SPCR0_RXIFL_MASK) |
+ ((count - 1) << 12);
+ if (cansleep) {
+ /* enable rx intr */
+ tx4938_spiptr->cr0 |= TXx9_SPCR0_RBSIE;
+ }
+ /* send */
+ for (i = 0; i < count; i++)
+ tx4938_spiptr->dr = inp ? *inp++ : 0;
+ /* wait all rx data */
+ if (cansleep) {
+ wait_event(txx9_spi_wait,
+ tx4938_spiptr->sr & TXx9_SPSR_SRRDY);
+ } else {
+ while (!(tx4938_spiptr->sr & TXx9_SPSR_RBSI))
+ ;
+ }
+ /* receive */
+ for (i = 0; i < count; i++) {
+ data = tx4938_spiptr->dr;
+ if (outp)
+ *outp++ = data;
+ }
+ if (incount)
+ incount -= count;
+ if (outcount)
+ outcount -= count;
+ }
+
+ /* CS OFF */
+ udelay(desc->tcsh);
+ txx9_spi_cs_func(chipid, 0);
+ udelay(desc->tcsr);
+
+ spin_lock_irqsave(&txx9_spi_lock, flags);
+ /* enter config mode */
+ tx4938_spiptr->mcr = TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR;
+ spin_unlock_irqrestore(&txx9_spi_lock, flags);
+
+ return 0;
+}
diff --git a/arch/mips/vr41xx/Kconfig b/arch/mips/vr41xx/Kconfig
new file mode 100644
index 000000000000..a7add16c9aa4
--- /dev/null
+++ b/arch/mips/vr41xx/Kconfig
@@ -0,0 +1,88 @@
+config CASIO_E55
+ bool "Support for CASIO CASSIOPEIA E-10/15/55/65"
+ depends on MACH_VR41XX
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select ISA
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config IBM_WORKPAD
+ bool "Support for IBM WorkPad z50"
+ depends on MACH_VR41XX
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select ISA
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config NEC_CMBVR4133
+ bool "Support for NEC CMB-VR4133"
+ depends on MACH_VR41XX
+ select CPU_VR41XX
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select HW_HAS_PCI
+
+config ROCKHOPPER
+ bool "Support for Rockhopper baseboard"
+ depends on NEC_CMBVR4133
+ select I8259
+ select HAVE_STD_PC_SERIAL_PORT
+
+config TANBAC_TB022X
+ bool "Support for TANBAC VR4131 multichip module and TANBAC VR4131DIMM"
+ depends on MACH_VR41XX
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select IRQ_CPU
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ help
+ The TANBAC VR4131 multichip module(TB0225) and
+ the TANBAC VR4131DIMM(TB0229) are MIPS-based platforms
+ manufactured by TANBAC.
+ Please refer to <http://www.tanbac.co.jp/>
+ about VR4131 multichip module and VR4131DIMM.
+
+config TANBAC_TB0226
+ bool "Support for TANBAC Mbase(TB0226)"
+ depends on TANBAC_TB022X
+ select GPIO_VR41XX
+ help
+ The TANBAC Mbase(TB0226) is a MIPS-based platform
+ manufactured by TANBAC.
+ Please refer to <http://www.tanbac.co.jp/> about Mbase.
+
+config TANBAC_TB0287
+ bool "Support for TANBAC Mini-ITX DIMM base(TB0287)"
+ depends on TANBAC_TB022X
+ help
+ The TANBAC Mini-ITX DIMM base(TB0287) is a MIPS-based platform
+ manufactured by TANBAC.
+ Please refer to <http://www.tanbac.co.jp/> about Mini-ITX DIMM base.
+
+config VICTOR_MPC30X
+ bool "Support for Victor MP-C303/304"
+ depends on MACH_VR41XX
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select IRQ_CPU
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config ZAO_CAPCELLA
+ bool "Support for ZAO Networks Capcella"
+ depends on MACH_VR41XX
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select IRQ_CPU
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config PCI_VR41XX
+ bool "Add PCI control unit support of NEC VR4100 series"
+ depends on MACH_VR41XX && HW_HAS_PCI
+ default y
+ select PCI
+
+config VRC4173
+ tristate "Add NEC VRC4173 companion chip support"
+ depends on MACH_VR41XX && PCI_VR41XX
+ help
+ The NEC VRC4173 is a companion chip for NEC VR4122/VR4131.
diff --git a/arch/mips/vr41xx/common/cmu.c b/arch/mips/vr41xx/common/cmu.c
index fcd3cb8cdd9d..d758e432961b 100644
--- a/arch/mips/vr41xx/common/cmu.c
+++ b/arch/mips/vr41xx/common/cmu.c
@@ -69,7 +69,7 @@
static void __iomem *cmu_base;
static uint16_t cmuclkmsk, cmuclkmsk2;
-static spinlock_t cmu_lock;
+static DEFINE_SPINLOCK(cmu_lock);
#define cmu_read(offset) readw(cmu_base + (offset))
#define cmu_write(offset, value) writew((value), cmu_base + (offset))
diff --git a/arch/mips/vr41xx/common/init.c b/arch/mips/vr41xx/common/init.c
index e03be896cbc4..578f6496ffd4 100644
--- a/arch/mips/vr41xx/common/init.c
+++ b/arch/mips/vr41xx/common/init.c
@@ -58,6 +58,14 @@ static void __init timer_init(void)
board_timer_setup = setup_timer_irq;
}
+void __init plat_setup(void)
+{
+ vr41xx_calculate_clock_frequency();
+
+ timer_init();
+ iomem_resource_init();
+}
+
void __init prom_init(void)
{
int argc, i;
@@ -71,12 +79,6 @@ void __init prom_init(void)
if (i < (argc - 1))
strcat(arcs_cmdline, " ");
}
-
- vr41xx_calculate_clock_frequency();
-
- timer_init();
-
- iomem_resource_init();
}
unsigned long __init prom_free_prom_memory (void)
diff --git a/arch/mips/vr41xx/common/vrc4173.c b/arch/mips/vr41xx/common/vrc4173.c
index ba58764ef8ea..462a9af30eef 100644
--- a/arch/mips/vr41xx/common/vrc4173.c
+++ b/arch/mips/vr41xx/common/vrc4173.c
@@ -81,8 +81,8 @@ EXPORT_SYMBOL(vrc4173_io_offset);
static int vrc4173_initialized;
static uint16_t vrc4173_cmuclkmsk;
static uint16_t vrc4173_selectreg;
-static spinlock_t vrc4173_cmu_lock;
-static spinlock_t vrc4173_giu_lock;
+static DEFINE_SPINLOCK(vrc4173_cmu_lock);
+static DEFINE_SPINLOCK(vrc4173_giu_lock);
static inline void set_cmusrst(uint16_t val)
{
diff --git a/arch/mips/vr41xx/nec-cmbvr4133/setup.c b/arch/mips/vr41xx/nec-cmbvr4133/setup.c
index db686ce42e85..53272a5c3cbe 100644
--- a/arch/mips/vr41xx/nec-cmbvr4133/setup.c
+++ b/arch/mips/vr41xx/nec-cmbvr4133/setup.c
@@ -56,7 +56,7 @@ static struct mtd_partition cmbvr4133_mtd_parts[] = {
extern void i8259_init(void);
-static int __init nec_cmbvr4133_setup(void)
+static void __init nec_cmbvr4133_setup(void)
{
#ifdef CONFIG_ROCKHOPPER
extern void disable_pcnet(void);
@@ -90,7 +90,4 @@ static int __init nec_cmbvr4133_setup(void)
#ifdef CONFIG_ROCKHOPPER
i8259_init();
#endif
- return 0;
}
-
-early_initcall(nec_cmbvr4133_setup);
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index e15f09eaed12..a065349aee37 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -270,7 +270,6 @@ void flush_dcache_page(struct page *page)
unsigned long offset;
unsigned long addr;
pgoff_t pgoff;
- pte_t *pte;
unsigned long pfn = page_to_pfn(page);
@@ -301,21 +300,16 @@ void flush_dcache_page(struct page *page)
* taking a page fault if the pte doesn't exist.
* This is just for speed. If the page translation
* isn't there, there's no point exciting the
- * nadtlb handler into a nullification frenzy */
-
-
- if(!(pte = translation_exists(mpnt, addr)))
- continue;
-
- /* make sure we really have this page: the private
+ * nadtlb handler into a nullification frenzy.
+ *
+ * Make sure we really have this page: the private
* mappings may cover this area but have COW'd this
- * particular page */
- if(pte_pfn(*pte) != pfn)
- continue;
-
- __flush_cache_page(mpnt, addr);
-
- break;
+ * particular page.
+ */
+ if (translation_exists(mpnt, addr, pfn)) {
+ __flush_cache_page(mpnt, addr);
+ break;
+ }
}
flush_dcache_mmap_unlock(mapping);
}
diff --git a/arch/parisc/kernel/ioctl32.c b/arch/parisc/kernel/ioctl32.c
index 8cad8f004f00..0a331104ad56 100644
--- a/arch/parisc/kernel/ioctl32.c
+++ b/arch/parisc/kernel/ioctl32.c
@@ -561,11 +561,6 @@ IOCTL_TABLE_START
#define DECLARES
#include "compat_ioctl.c"
-/* Might be moved to compat_ioctl.h with some ifdefs... */
-COMPATIBLE_IOCTL(TIOCSTART)
-COMPATIBLE_IOCTL(TIOCSTOP)
-COMPATIBLE_IOCTL(TIOCSLTC)
-
/* PA-specific ioctls */
COMPATIBLE_IOCTL(PA_PERF_ON)
COMPATIBLE_IOCTL(PA_PERF_OFF)
diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c
index ae6213d71670..f94a02ef3d95 100644
--- a/arch/parisc/kernel/pci-dma.c
+++ b/arch/parisc/kernel/pci-dma.c
@@ -114,7 +114,7 @@ static inline int map_pmd_uncached(pmd_t * pmd, unsigned long vaddr,
if (end > PGDIR_SIZE)
end = PGDIR_SIZE;
do {
- pte_t * pte = pte_alloc_kernel(&init_mm, pmd, vaddr);
+ pte_t * pte = pte_alloc_kernel(pmd, vaddr);
if (!pte)
return -ENOMEM;
if (map_pte_uncached(pte, orig_vaddr, end - vaddr, paddr_ptr))
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index f3428e5e86fb..18130c3748f3 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -78,7 +78,7 @@ void ptrace_disable(struct task_struct *child)
pa_psw(child)->l = 0;
}
-long sys_ptrace(long request, pid_t pid, long addr, long data)
+long sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
long ret;
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
index bc979e1abdec..cded25680787 100644
--- a/arch/parisc/kernel/time.c
+++ b/arch/parisc/kernel/time.c
@@ -33,10 +33,6 @@
#include <linux/timex.h>
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
/* xtime and wall_jiffies keep wall-clock time */
extern unsigned long wall_jiffies;
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index 2886ad70db48..29b998e430e6 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -505,7 +505,9 @@ void show_mem(void)
for (j = node_start_pfn(i); j < node_end_pfn(i); j++) {
struct page *p;
+ unsigned long flags;
+ pgdat_resize_lock(NODE_DATA(i), &flags);
p = nid_page_nr(i, j) - node_start_pfn(i);
total++;
@@ -517,6 +519,7 @@ void show_mem(void)
free++;
else
shared += page_count(p) - 1;
+ pgdat_resize_unlock(NODE_DATA(i), &flags);
}
}
#endif
diff --git a/arch/parisc/mm/ioremap.c b/arch/parisc/mm/ioremap.c
index f2df502cdae3..5c7a1b3b9326 100644
--- a/arch/parisc/mm/ioremap.c
+++ b/arch/parisc/mm/ioremap.c
@@ -52,7 +52,7 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned lo
if (address >= end)
BUG();
do {
- pte_t * pte = pte_alloc_kernel(NULL, pmd, address);
+ pte_t * pte = pte_alloc_kernel(pmd, address);
if (!pte)
return -ENOMEM;
remap_area_pte(pte, address, end - address, address + phys_addr, flags);
@@ -75,10 +75,9 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr,
flush_cache_all();
if (address >= end)
BUG();
- spin_lock(&init_mm.page_table_lock);
do {
pmd_t *pmd;
- pmd = pmd_alloc(dir, address);
+ pmd = pmd_alloc(&init_mm, dir, address);
error = -ENOMEM;
if (!pmd)
break;
@@ -89,7 +88,6 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr,
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
} while (address && (address < end));
- spin_unlock(&init_mm.page_table_lock);
flush_tlb_all();
return error;
}
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
new file mode 100644
index 000000000000..967ecf92d6a7
--- /dev/null
+++ b/arch/powerpc/Kconfig
@@ -0,0 +1,900 @@
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+#
+
+mainmenu "Linux/PowerPC Kernel Configuration"
+
+config PPC64
+ bool "64-bit kernel"
+ default n
+ help
+ This option selects whether a 32-bit or a 64-bit kernel
+ will be built.
+
+config PPC32
+ bool
+ default y if !PPC64
+
+config 64BIT
+ bool
+ default y if PPC64
+
+config PPC_MERGE
+ def_bool y
+
+config MMU
+ bool
+ default y
+
+config UID16
+ bool
+
+config GENERIC_HARDIRQS
+ bool
+ default y
+
+config RWSEM_GENERIC_SPINLOCK
+ bool
+
+config RWSEM_XCHGADD_ALGORITHM
+ bool
+ default y
+
+config GENERIC_CALIBRATE_DELAY
+ bool
+ default y
+
+config PPC
+ bool
+ default y
+
+config EARLY_PRINTK
+ bool
+ default y if PPC64
+
+config COMPAT
+ bool
+ default y if PPC64
+
+config SYSVIPC_COMPAT
+ bool
+ depends on COMPAT && SYSVIPC
+ default y
+
+# All PPC32s use generic nvram driver through ppc_md
+config GENERIC_NVRAM
+ bool
+ default y if PPC32
+
+config SCHED_NO_NO_OMIT_FRAME_POINTER
+ bool
+ default y
+
+config ARCH_MAY_HAVE_PC_FDC
+ bool
+ default y
+
+menu "Processor support"
+choice
+ prompt "Processor Type"
+ depends on PPC32
+ default 6xx
+
+config 6xx
+ bool "6xx/7xx/74xx"
+ select PPC_FPU
+ help
+ There are four families of PowerPC chips supported. The more common
+ types (601, 603, 604, 740, 750, 7400), the Motorola embedded
+ versions (821, 823, 850, 855, 860, 52xx, 82xx, 83xx), the AMCC
+ embedded versions (403 and 405) and the high end 64 bit Power
+ processors (POWER 3, POWER4, and IBM PPC970 also known as G5).
+
+ Unless you are building a kernel for one of the embedded processor
+ systems, 64 bit IBM RS/6000 or an Apple G5, choose 6xx.
+ Note that the kernel runs in 32-bit mode even on 64-bit chips.
+
+config PPC_52xx
+ bool "Freescale 52xx"
+
+config PPC_82xx
+ bool "Freescale 82xx"
+
+config PPC_83xx
+ bool "Freescale 83xx"
+
+config 40x
+ bool "AMCC 40x"
+
+config 44x
+ bool "AMCC 44x"
+
+config 8xx
+ bool "Freescale 8xx"
+
+config E200
+ bool "Freescale e200"
+
+config E500
+ bool "Freescale e500"
+endchoice
+
+config POWER4_ONLY
+ bool "Optimize for POWER4"
+ depends on PPC64
+ default n
+ ---help---
+ Cause the compiler to optimize for POWER4/POWER5/PPC970 processors.
+ The resulting binary will not work on POWER3 or RS64 processors
+ when compiled with binutils 2.15 or later.
+
+config POWER3
+ bool
+ depends on PPC64
+ default y if !POWER4_ONLY
+
+config POWER4
+ depends on PPC64
+ def_bool y
+
+config PPC_FPU
+ bool
+ default y if PPC64
+
+config BOOKE
+ bool
+ depends on E200 || E500
+ default y
+
+config FSL_BOOKE
+ bool
+ depends on E200 || E500
+ default y
+
+config PTE_64BIT
+ bool
+ depends on 44x || E500
+ default y if 44x
+ default y if E500 && PHYS_64BIT
+
+config PHYS_64BIT
+ bool 'Large physical address support' if E500
+ depends on 44x || E500
+ default y if 44x
+ ---help---
+ This option enables kernel support for larger than 32-bit physical
+ addresses. This features is not be available on all e500 cores.
+
+ If in doubt, say N here.
+
+config ALTIVEC
+ bool "AltiVec Support"
+ depends on 6xx || POWER4
+ ---help---
+ This option enables kernel support for the Altivec extensions to the
+ PowerPC processor. The kernel currently supports saving and restoring
+ altivec registers, and turning on the 'altivec enable' bit so user
+ processes can execute altivec instructions.
+
+ This option is only usefully if you have a processor that supports
+ altivec (G4, otherwise known as 74xx series), but does not have
+ any affect on a non-altivec cpu (it does, however add code to the
+ kernel).
+
+ If in doubt, say Y here.
+
+config SPE
+ bool "SPE Support"
+ depends on E200 || E500
+ ---help---
+ This option enables kernel support for the Signal Processing
+ Extensions (SPE) to the PowerPC processor. The kernel currently
+ supports saving and restoring SPE registers, and turning on the
+ 'spe enable' bit so user processes can execute SPE instructions.
+
+ This option is only useful if you have a processor that supports
+ SPE (e500, otherwise known as 85xx series), but does not have any
+ effect on a non-spe cpu (it does, however add code to the kernel).
+
+ If in doubt, say Y here.
+
+config PPC_STD_MMU
+ bool
+ depends on 6xx || POWER3 || POWER4 || PPC64
+ default y
+
+config PPC_STD_MMU_32
+ def_bool y
+ depends on PPC_STD_MMU && PPC32
+
+config SMP
+ depends on PPC_STD_MMU
+ bool "Symmetric multi-processing support"
+ ---help---
+ This enables support for systems with more than one CPU. If you have
+ a system with only one CPU, say N. If you have a system with more
+ than one CPU, say Y. Note that the kernel does not currently
+ support SMP machines with 603/603e/603ev or PPC750 ("G3") processors
+ since they have inadequate hardware support for multiprocessor
+ operation.
+
+ If you say N here, the kernel will run on single and multiprocessor
+ machines, but will use only one CPU of a multiprocessor machine. If
+ you say Y here, the kernel will run on single-processor machines.
+ On a single-processor machine, the kernel will run faster if you say
+ N here.
+
+ If you don't know what to do here, say N.
+
+config NR_CPUS
+ int "Maximum number of CPUs (2-32)"
+ range 2 128
+ depends on SMP
+ default "32" if PPC64
+ default "4"
+
+config NOT_COHERENT_CACHE
+ bool
+ depends on 4xx || 8xx || E200
+ default y
+endmenu
+
+source "init/Kconfig"
+
+menu "Platform support"
+ depends on PPC64 || 6xx
+
+choice
+ prompt "Machine type"
+ default PPC_MULTIPLATFORM
+
+config PPC_MULTIPLATFORM
+ bool "Generic desktop/server/laptop"
+ help
+ Select this option if configuring for an IBM pSeries or
+ RS/6000 machine, an Apple machine, or a PReP, CHRP,
+ Maple or Cell-based machine.
+
+config PPC_ISERIES
+ bool "IBM Legacy iSeries"
+ depends on PPC64
+
+config EMBEDDED6xx
+ bool "Embedded 6xx/7xx/7xxx-based board"
+ depends on PPC32
+
+config APUS
+ bool "Amiga-APUS"
+ depends on PPC32 && BROKEN
+ help
+ Select APUS if configuring for a PowerUP Amiga.
+ More information is available at:
+ <http://linux-apus.sourceforge.net/>.
+endchoice
+
+config PPC_PSERIES
+ depends on PPC_MULTIPLATFORM && PPC64
+ bool " IBM pSeries & new (POWER5-based) iSeries"
+ select PPC_I8259
+ select PPC_RTAS
+ select RTAS_ERROR_LOGGING
+ default y
+
+config PPC_CHRP
+ bool " Common Hardware Reference Platform (CHRP) based machines"
+ depends on PPC_MULTIPLATFORM && PPC32
+ select PPC_I8259
+ select PPC_INDIRECT_PCI
+ select PPC_RTAS
+ select PPC_MPC106
+ default y
+
+config PPC_PMAC
+ bool " Apple PowerMac based machines"
+ depends on PPC_MULTIPLATFORM
+ select PPC_INDIRECT_PCI if PPC32
+ select PPC_MPC106 if PPC32
+ default y
+
+config PPC_PMAC64
+ bool
+ depends on PPC_PMAC && POWER4
+ select U3_DART
+ default y
+
+config PPC_PREP
+ bool " PowerPC Reference Platform (PReP) based machines"
+ depends on PPC_MULTIPLATFORM && PPC32
+ select PPC_I8259
+ select PPC_INDIRECT_PCI
+ default y
+
+config PPC_MAPLE
+ depends on PPC_MULTIPLATFORM && PPC64
+ bool " Maple 970FX Evaluation Board"
+ select U3_DART
+ select MPIC_BROKEN_U3
+ default n
+ help
+ This option enables support for the Maple 970FX Evaluation Board.
+ For more informations, refer to <http://www.970eval.com>
+
+config PPC_BPA
+ bool " Broadband Processor Architecture"
+ depends on PPC_MULTIPLATFORM && PPC64
+ select PPC_RTAS
+
+config PPC_OF
+ bool
+ depends on PPC_MULTIPLATFORM # for now
+ default y
+
+config XICS
+ depends on PPC_PSERIES
+ bool
+ default y
+
+config U3_DART
+ bool
+ depends on PPC_MULTIPLATFORM && PPC64
+ default n
+
+config MPIC
+ depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE || PPC_CHRP
+ bool
+ default y
+
+config PPC_RTAS
+ bool
+ default n
+
+config RTAS_ERROR_LOGGING
+ bool
+ depends on PPC_RTAS
+ default n
+
+config MPIC_BROKEN_U3
+ bool
+ depends on PPC_MAPLE
+ default y
+
+config BPA_IIC
+ depends on PPC_BPA
+ bool
+ default y
+
+config IBMVIO
+ depends on PPC_PSERIES || PPC_ISERIES
+ bool
+ default y
+
+config PPC_MPC106
+ bool
+ default n
+
+source "drivers/cpufreq/Kconfig"
+
+config CPU_FREQ_PMAC
+ bool "Support for Apple PowerBooks"
+ depends on CPU_FREQ && ADB_PMU && PPC32
+ select CPU_FREQ_TABLE
+ help
+ This adds support for frequency switching on Apple PowerBooks,
+ this currently includes some models of iBook & Titanium
+ PowerBook.
+
+config PPC601_SYNC_FIX
+ bool "Workarounds for PPC601 bugs"
+ depends on 6xx && (PPC_PREP || PPC_PMAC)
+ help
+ Some versions of the PPC601 (the first PowerPC chip) have bugs which
+ mean that extra synchronization instructions are required near
+ certain instructions, typically those that make major changes to the
+ CPU state. These extra instructions reduce performance slightly.
+ If you say N here, these extra instructions will not be included,
+ resulting in a kernel which will run faster but may not run at all
+ on some systems with the PPC601 chip.
+
+ If in doubt, say Y here.
+
+config TAU
+ bool "Thermal Management Support"
+ depends on 6xx
+ help
+ G3 and G4 processors have an on-chip temperature sensor called the
+ 'Thermal Assist Unit (TAU)', which, in theory, can measure the on-die
+ temperature within 2-4 degrees Celsius. This option shows the current
+ on-die temperature in /proc/cpuinfo if the cpu supports it.
+
+ Unfortunately, on some chip revisions, this sensor is very inaccurate
+ and in some cases, does not work at all, so don't assume the cpu
+ temp is actually what /proc/cpuinfo says it is.
+
+config TAU_INT
+ bool "Interrupt driven TAU driver (DANGEROUS)"
+ depends on TAU
+ ---help---
+ The TAU supports an interrupt driven mode which causes an interrupt
+ whenever the temperature goes out of range. This is the fastest way
+ to get notified the temp has exceeded a range. With this option off,
+ a timer is used to re-check the temperature periodically.
+
+ However, on some cpus it appears that the TAU interrupt hardware
+ is buggy and can cause a situation which would lead unexplained hard
+ lockups.
+
+ Unless you are extending the TAU driver, or enjoy kernel/hardware
+ debugging, leave this option off.
+
+config TAU_AVERAGE
+ bool "Average high and low temp"
+ depends on TAU
+ ---help---
+ The TAU hardware can compare the temperature to an upper and lower
+ bound. The default behavior is to show both the upper and lower
+ bound in /proc/cpuinfo. If the range is large, the temperature is
+ either changing a lot, or the TAU hardware is broken (likely on some
+ G4's). If the range is small (around 4 degrees), the temperature is
+ relatively stable. If you say Y here, a single temperature value,
+ halfway between the upper and lower bounds, will be reported in
+ /proc/cpuinfo.
+
+ If in doubt, say N here.
+endmenu
+
+source arch/powerpc/platforms/embedded6xx/Kconfig
+source arch/powerpc/platforms/4xx/Kconfig
+source arch/powerpc/platforms/85xx/Kconfig
+source arch/powerpc/platforms/8xx/Kconfig
+
+menu "Kernel options"
+
+config HIGHMEM
+ bool "High memory support"
+ depends on PPC32
+
+source kernel/Kconfig.hz
+source kernel/Kconfig.preempt
+source "fs/Kconfig.binfmt"
+
+# We optimistically allocate largepages from the VM, so make the limit
+# large enough (16MB). This badly named config option is actually
+# max order + 1
+config FORCE_MAX_ZONEORDER
+ int
+ depends on PPC64
+ default "13"
+
+config MATH_EMULATION
+ bool "Math emulation"
+ depends on 4xx || 8xx || E200 || E500
+ ---help---
+ Some PowerPC chips designed for embedded applications do not have
+ a floating-point unit and therefore do not implement the
+ floating-point instructions in the PowerPC instruction set. If you
+ say Y here, the kernel will include code to emulate a floating-point
+ unit, which will allow programs that use floating-point
+ instructions to run.
+
+config IOMMU_VMERGE
+ bool "Enable IOMMU virtual merging (EXPERIMENTAL)"
+ depends on EXPERIMENTAL && PPC64
+ default n
+ help
+ Cause IO segments sent to a device for DMA to be merged virtually
+ by the IOMMU when they happen to have been allocated contiguously.
+ This doesn't add pressure to the IOMMU allocator. However, some
+ drivers don't support getting large merged segments coming back
+ from *_map_sg(). Say Y if you know the drivers you are using are
+ properly handling this case.
+
+config HOTPLUG_CPU
+ bool "Support for enabling/disabling CPUs"
+ depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || PPC_PMAC)
+ ---help---
+ Say Y here to be able to disable and re-enable individual
+ CPUs at runtime on SMP machines.
+
+ Say N if you are unsure.
+
+config KEXEC
+ bool "kexec system call (EXPERIMENTAL)"
+ depends on PPC_MULTIPLATFORM && EXPERIMENTAL
+ help
+ kexec is a system call that implements the ability to shutdown your
+ current kernel, and to start another kernel. It is like a reboot
+ but it is indepedent of the system firmware. And like a reboot
+ you can start any kernel with it, not just Linux.
+
+ The name comes from the similiarity to the exec system call.
+
+ It is an ongoing process to be certain the hardware in a machine
+ is properly shutdown, so do not be surprised if this code does not
+ initially work for you. It may help to enable device hotplugging
+ support. As of this writing the exact hardware interface is
+ strongly in flux, so no good recommendation can be made.
+
+config EMBEDDEDBOOT
+ bool
+ depends on 8xx || 8260
+ default y
+
+config PC_KEYBOARD
+ bool "PC PS/2 style Keyboard"
+ depends on 4xx || CPM2
+
+config PPCBUG_NVRAM
+ bool "Enable reading PPCBUG NVRAM during boot" if PPLUS || LOPEC
+ default y if PPC_PREP
+
+config IRQ_ALL_CPUS
+ bool "Distribute interrupts on all CPUs by default"
+ depends on SMP && !MV64360
+ help
+ This option gives the kernel permission to distribute IRQs across
+ multiple CPUs. Saying N here will route all IRQs to the first
+ CPU. Generally saying Y is safe, although some problems have been
+ reported with SMP Power Macintoshes with this option enabled.
+
+source "arch/powerpc/platforms/pseries/Kconfig"
+
+config NUMA
+ bool "NUMA support"
+ depends on PPC64
+ default y if SMP && PPC_PSERIES
+
+config ARCH_SELECT_MEMORY_MODEL
+ def_bool y
+ depends on PPC64
+
+config ARCH_FLATMEM_ENABLE
+ def_bool y
+ depends on PPC64 && !NUMA
+
+config ARCH_DISCONTIGMEM_ENABLE
+ def_bool y
+ depends on SMP && PPC_PSERIES
+
+config ARCH_DISCONTIGMEM_DEFAULT
+ def_bool y
+ depends on ARCH_DISCONTIGMEM_ENABLE
+
+config ARCH_SPARSEMEM_ENABLE
+ def_bool y
+ depends on ARCH_DISCONTIGMEM_ENABLE
+
+source "mm/Kconfig"
+
+config HAVE_ARCH_EARLY_PFN_TO_NID
+ def_bool y
+ depends on NEED_MULTIPLE_NODES
+
+# Some NUMA nodes have memory ranges that span
+# other nodes. Even though a pfn is valid and
+# between a node's start and end pfns, it may not
+# reside on that node.
+#
+# This is a relatively temporary hack that should
+# be able to go away when sparsemem is fully in
+# place
+
+config NODES_SPAN_OTHER_NODES
+ def_bool y
+ depends on NEED_MULTIPLE_NODES
+
+config SCHED_SMT
+ bool "SMT (Hyperthreading) scheduler support"
+ depends on PPC64 && SMP
+ default off
+ help
+ SMT scheduler support improves the CPU scheduler's decision making
+ when dealing with POWER5 cpus at a cost of slightly increased
+ overhead in some places. If unsure say N here.
+
+config PROC_DEVICETREE
+ bool "Support for device tree in /proc"
+ depends on PROC_FS
+ help
+ This option adds a device-tree directory under /proc which contains
+ an image of the device tree that the kernel copies from Open
+ Firmware or other boot firmware. If unsure, say Y here.
+
+source "arch/powerpc/platforms/prep/Kconfig"
+
+config CMDLINE_BOOL
+ bool "Default bootloader kernel arguments"
+ depends on !PPC_ISERIES
+
+config CMDLINE
+ string "Initial kernel command string"
+ depends on CMDLINE_BOOL
+ default "console=ttyS0,9600 console=tty0 root=/dev/sda2"
+ help
+ On some platforms, there is currently no way for the boot loader to
+ pass arguments to the kernel. For these platforms, you can supply
+ some command-line options at build time by entering them here. In
+ most cases you will need to specify the root device here.
+
+if !44x || BROKEN
+source kernel/power/Kconfig
+endif
+
+config SECCOMP
+ bool "Enable seccomp to safely compute untrusted bytecode"
+ depends on PROC_FS
+ default y
+ help
+ This kernel feature is useful for number crunching applications
+ that may need to compute untrusted bytecode during their
+ execution. By using pipes or other transports made available to
+ the process as file descriptors supporting the read/write
+ syscalls, it's possible to isolate those applications in
+ their own address space using seccomp. Once seccomp is
+ enabled via /proc/<pid>/seccomp, it cannot be disabled
+ and the task is only allowed to execute a few safe syscalls
+ defined by each seccomp mode.
+
+ If unsure, say Y. Only embedded should say N here.
+
+endmenu
+
+config ISA_DMA_API
+ bool
+ default y
+
+menu "Bus options"
+
+config ISA
+ bool "Support for ISA-bus hardware"
+ depends on PPC_PREP || PPC_CHRP
+ select PPC_I8259
+ help
+ Find out whether you have ISA slots on your motherboard. ISA is the
+ name of a bus system, i.e. the way the CPU talks to the other stuff
+ inside your box. If you have an Apple machine, say N here; if you
+ have an IBM RS/6000 or pSeries machine or a PReP machine, say Y. If
+ you have an embedded board, consult your board documentation.
+
+config GENERIC_ISA_DMA
+ bool
+ depends on PPC64 || POWER4 || 6xx && !CPM2
+ default y
+
+config PPC_I8259
+ bool
+ default y if 85xx
+ default n
+
+config PPC_INDIRECT_PCI
+ bool
+ depends on PCI
+ default y if 40x || 44x || 85xx || 83xx
+ default n
+
+config EISA
+ bool
+
+config SBUS
+ bool
+
+# Yes MCA RS/6000s exist but Linux-PPC does not currently support any
+config MCA
+ bool
+
+config PCI
+ bool "PCI support" if 40x || CPM2 || 83xx || 85xx || PPC_MPC52xx || (EMBEDDED && PPC_ISERIES)
+ default y if !40x && !CPM2 && !8xx && !APUS && !83xx && !85xx
+ default PCI_PERMEDIA if !4xx && !CPM2 && !8xx && APUS
+ default PCI_QSPAN if !4xx && !CPM2 && 8xx
+ help
+ Find out whether your system includes a PCI bus. PCI is the name of
+ a bus system, i.e. the way the CPU talks to the other stuff inside
+ your box. If you say Y here, the kernel will include drivers and
+ infrastructure code to support PCI bus devices.
+
+config PCI_DOMAINS
+ bool
+ default PCI
+
+config MPC83xx_PCI2
+ bool " Supprt for 2nd PCI host controller"
+ depends on PCI && MPC834x
+ default y if MPC834x_SYS
+
+config PCI_QSPAN
+ bool "QSpan PCI"
+ depends on !4xx && !CPM2 && 8xx
+ select PPC_I8259
+ help
+ Say Y here if you have a system based on a Motorola 8xx-series
+ embedded processor with a QSPAN PCI interface, otherwise say N.
+
+config PCI_8260
+ bool
+ depends on PCI && 8260
+ select PPC_INDIRECT_PCI
+ default y
+
+config 8260_PCI9
+ bool " Enable workaround for MPC826x erratum PCI 9"
+ depends on PCI_8260 && !ADS8272
+ default y
+
+choice
+ prompt " IDMA channel for PCI 9 workaround"
+ depends on 8260_PCI9
+
+config 8260_PCI9_IDMA1
+ bool "IDMA1"
+
+config 8260_PCI9_IDMA2
+ bool "IDMA2"
+
+config 8260_PCI9_IDMA3
+ bool "IDMA3"
+
+config 8260_PCI9_IDMA4
+ bool "IDMA4"
+
+endchoice
+
+source "drivers/pci/Kconfig"
+
+source "drivers/pcmcia/Kconfig"
+
+source "drivers/pci/hotplug/Kconfig"
+
+endmenu
+
+menu "Advanced setup"
+ depends on PPC32
+
+config ADVANCED_OPTIONS
+ bool "Prompt for advanced kernel configuration options"
+ help
+ This option will enable prompting for a variety of advanced kernel
+ configuration options. These options can cause the kernel to not
+ work if they are set incorrectly, but can be used to optimize certain
+ aspects of kernel memory management.
+
+ Unless you know what you are doing, say N here.
+
+comment "Default settings for advanced configuration options are used"
+ depends on !ADVANCED_OPTIONS
+
+config HIGHMEM_START_BOOL
+ bool "Set high memory pool address"
+ depends on ADVANCED_OPTIONS && HIGHMEM
+ help
+ This option allows you to set the base address of the kernel virtual
+ area used to map high memory pages. This can be useful in
+ optimizing the layout of kernel virtual memory.
+
+ Say N here unless you know what you are doing.
+
+config HIGHMEM_START
+ hex "Virtual start address of high memory pool" if HIGHMEM_START_BOOL
+ default "0xfe000000"
+
+config LOWMEM_SIZE_BOOL
+ bool "Set maximum low memory"
+ depends on ADVANCED_OPTIONS
+ help
+ This option allows you to set the maximum amount of memory which
+ will be used as "low memory", that is, memory which the kernel can
+ access directly, without having to set up a kernel virtual mapping.
+ This can be useful in optimizing the layout of kernel virtual
+ memory.
+
+ Say N here unless you know what you are doing.
+
+config LOWMEM_SIZE
+ hex "Maximum low memory size (in bytes)" if LOWMEM_SIZE_BOOL
+ default "0x30000000"
+
+config KERNEL_START_BOOL
+ bool "Set custom kernel base address"
+ depends on ADVANCED_OPTIONS
+ help
+ This option allows you to set the kernel virtual address at which
+ the kernel will map low memory (the kernel image will be linked at
+ this address). This can be useful in optimizing the virtual memory
+ layout of the system.
+
+ Say N here unless you know what you are doing.
+
+config KERNEL_START
+ hex "Virtual address of kernel base" if KERNEL_START_BOOL
+ default "0xc0000000"
+
+config TASK_SIZE_BOOL
+ bool "Set custom user task size"
+ depends on ADVANCED_OPTIONS
+ help
+ This option allows you to set the amount of virtual address space
+ allocated to user tasks. This can be useful in optimizing the
+ virtual memory layout of the system.
+
+ Say N here unless you know what you are doing.
+
+config TASK_SIZE
+ hex "Size of user task space" if TASK_SIZE_BOOL
+ default "0x80000000"
+
+config CONSISTENT_START_BOOL
+ bool "Set custom consistent memory pool address"
+ depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE
+ help
+ This option allows you to set the base virtual address
+ of the the consistent memory pool. This pool of virtual
+ memory is used to make consistent memory allocations.
+
+config CONSISTENT_START
+ hex "Base virtual address of consistent memory pool" if CONSISTENT_START_BOOL
+ default "0xff100000" if NOT_COHERENT_CACHE
+
+config CONSISTENT_SIZE_BOOL
+ bool "Set custom consistent memory pool size"
+ depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE
+ help
+ This option allows you to set the size of the the
+ consistent memory pool. This pool of virtual memory
+ is used to make consistent memory allocations.
+
+config CONSISTENT_SIZE
+ hex "Size of consistent memory pool" if CONSISTENT_SIZE_BOOL
+ default "0x00200000" if NOT_COHERENT_CACHE
+
+config BOOT_LOAD_BOOL
+ bool "Set the boot link/load address"
+ depends on ADVANCED_OPTIONS && !PPC_MULTIPLATFORM
+ help
+ This option allows you to set the initial load address of the zImage
+ or zImage.initrd file. This can be useful if you are on a board
+ which has a small amount of memory.
+
+ Say N here unless you know what you are doing.
+
+config BOOT_LOAD
+ hex "Link/load address for booting" if BOOT_LOAD_BOOL
+ default "0x00400000" if 40x || 8xx || 8260
+ default "0x01000000" if 44x
+ default "0x00800000"
+
+config PIN_TLB
+ bool "Pinned Kernel TLBs (860 ONLY)"
+ depends on ADVANCED_OPTIONS && 8xx
+endmenu
+
+if PPC64
+config KERNEL_START
+ hex
+ default "0xc000000000000000"
+endif
+
+source "net/Kconfig"
+
+source "drivers/Kconfig"
+
+source "fs/Kconfig"
+
+# XXX source "arch/ppc/8xx_io/Kconfig"
+
+# XXX source "arch/ppc/8260_io/Kconfig"
+
+source "arch/powerpc/platforms/iseries/Kconfig"
+
+source "lib/Kconfig"
+
+source "arch/powerpc/oprofile/Kconfig"
+
+source "arch/powerpc/Kconfig.debug"
+
+source "security/Kconfig"
+
+config KEYS_COMPAT
+ bool
+ depends on COMPAT && KEYS
+ default y
+
+source "crypto/Kconfig"
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
new file mode 100644
index 000000000000..0baf64ec80d0
--- /dev/null
+++ b/arch/powerpc/Kconfig.debug
@@ -0,0 +1,128 @@
+menu "Kernel hacking"
+
+source "lib/Kconfig.debug"
+
+config DEBUG_STACKOVERFLOW
+ bool "Check for stack overflows"
+ depends on DEBUG_KERNEL && PPC64
+ help
+ This option will cause messages to be printed if free stack space
+ drops below a certain limit.
+
+config KPROBES
+ bool "Kprobes"
+ depends on DEBUG_KERNEL && PPC64
+ help
+ Kprobes allows you to trap at almost any kernel address and
+ execute a callback function. register_kprobe() establishes
+ a probepoint and specifies the callback. Kprobes is useful
+ for kernel debugging, non-intrusive instrumentation and testing.
+ If in doubt, say "N".
+
+config DEBUG_STACK_USAGE
+ bool "Stack utilization instrumentation"
+ depends on DEBUG_KERNEL && PPC64
+ help
+ Enables the display of the minimum amount of free stack which each
+ task has ever had available in the sysrq-T and sysrq-P debug output.
+
+ This option will slow down process creation somewhat.
+
+config DEBUGGER
+ bool "Enable debugger hooks"
+ depends on DEBUG_KERNEL
+ help
+ Include in-kernel hooks for kernel debuggers. Unless you are
+ intending to debug the kernel, say N here.
+
+config KGDB
+ bool "Include kgdb kernel debugger"
+ depends on DEBUGGER && (BROKEN || PPC_GEN550 || 4xx)
+ select DEBUG_INFO
+ help
+ Include in-kernel hooks for kgdb, the Linux kernel source level
+ debugger. See <http://kgdb.sourceforge.net/> for more information.
+ Unless you are intending to debug the kernel, say N here.
+
+choice
+ prompt "Serial Port"
+ depends on KGDB
+ default KGDB_TTYS1
+
+config KGDB_TTYS0
+ bool "ttyS0"
+
+config KGDB_TTYS1
+ bool "ttyS1"
+
+config KGDB_TTYS2
+ bool "ttyS2"
+
+config KGDB_TTYS3
+ bool "ttyS3"
+
+endchoice
+
+config KGDB_CONSOLE
+ bool "Enable serial console thru kgdb port"
+ depends on KGDB && 8xx || CPM2
+ help
+ If you enable this, all serial console messages will be sent
+ over the gdb stub.
+ If unsure, say N.
+
+config XMON
+ bool "Include xmon kernel debugger"
+ depends on DEBUGGER && !PPC_ISERIES
+ help
+ Include in-kernel hooks for the xmon kernel monitor/debugger.
+ Unless you are intending to debug the kernel, say N here.
+ Make sure to enable also CONFIG_BOOTX_TEXT on Macs. Otherwise
+ nothing will appear on the screen (xmon writes directly to the
+ framebuffer memory).
+ The cmdline option 'xmon' or 'xmon=early' will drop into xmon
+ very early during boot. 'xmon=on' will just enable the xmon
+ debugger hooks. 'xmon=off' will disable the debugger hooks
+ if CONFIG_XMON_DEFAULT is set.
+
+config XMON_DEFAULT
+ bool "Enable xmon by default"
+ depends on XMON
+ help
+ xmon is normally disabled unless booted with 'xmon=on'.
+ Use 'xmon=off' to disable xmon init during runtime.
+
+config IRQSTACKS
+ bool "Use separate kernel stacks when processing interrupts"
+ depends on PPC64
+ help
+ If you say Y here the kernel will use separate kernel stacks
+ for handling hard and soft interrupts. This can help avoid
+ overflowing the process kernel stacks.
+
+config BDI_SWITCH
+ bool "Include BDI-2000 user context switcher"
+ depends on DEBUG_KERNEL && PPC32
+ help
+ Include in-kernel support for the Abatron BDI2000 debugger.
+ Unless you are intending to debug the kernel with one of these
+ machines, say N here.
+
+config BOOTX_TEXT
+ bool "Support for early boot text console (BootX or OpenFirmware only)"
+ depends PPC_OF && !PPC_ISERIES
+ help
+ Say Y here to see progress messages from the boot firmware in text
+ mode. Requires either BootX or Open Firmware.
+
+config SERIAL_TEXT_DEBUG
+ bool "Support for early boot texts over serial port"
+ depends on 4xx || LOPEC || MV64X60 || PPLUS || PRPMC800 || \
+ PPC_GEN550 || PPC_MPC52xx
+
+config PPC_OCP
+ bool
+ depends on IBM_OCP || XILINX_OCP
+ default y
+
+endmenu
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
new file mode 100644
index 000000000000..2f4cce06a7e5
--- /dev/null
+++ b/arch/powerpc/Makefile
@@ -0,0 +1,222 @@
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies. Remember to do have actions
+# for "archclean" and "archdep" for cleaning up and making dependencies for
+# this architecture.
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1994 by Linus Torvalds
+# Changes for PPC by Gary Thomas
+# Rewritten by Cort Dougan and Paul Mackerras
+#
+
+# This must match PAGE_OFFSET in include/asm-powerpc/page.h.
+KERNELLOAD := $(CONFIG_KERNEL_START)
+
+HAS_BIARCH := $(call cc-option-yn, -m32)
+
+ifeq ($(CONFIG_PPC64),y)
+OLDARCH := ppc64
+SZ := 64
+
+# Set default 32 bits cross compilers for vdso and boot wrapper
+CROSS32_COMPILE ?=
+
+CROSS32CC := $(CROSS32_COMPILE)gcc
+CROSS32AS := $(CROSS32_COMPILE)as
+CROSS32LD := $(CROSS32_COMPILE)ld
+CROSS32OBJCOPY := $(CROSS32_COMPILE)objcopy
+
+ifeq ($(HAS_BIARCH),y)
+ifeq ($(CROSS32_COMPILE),)
+CROSS32CC := $(CC) -m32
+CROSS32AS := $(AS) -a32
+CROSS32LD := $(LD) -m elf32ppc
+CROSS32OBJCOPY := $(OBJCOPY)
+endif
+endif
+
+export CROSS32CC CROSS32AS CROSS32LD CROSS32OBJCOPY
+
+new_nm := $(shell if $(NM) --help 2>&1 | grep -- '--synthetic' > /dev/null; then echo y; else echo n; fi)
+
+ifeq ($(new_nm),y)
+NM := $(NM) --synthetic
+endif
+
+else
+OLDARCH := ppc
+SZ := 32
+endif
+
+UTS_MACHINE := $(OLDARCH)
+
+ifeq ($(HAS_BIARCH),y)
+override AS += -a$(SZ)
+override LD += -m elf$(SZ)ppc
+override CC += -m$(SZ)
+endif
+
+LDFLAGS_vmlinux := -Ttext $(KERNELLOAD) -Bstatic -e $(KERNELLOAD)
+
+# The -Iarch/$(ARCH)/include is temporary while we are merging
+CPPFLAGS += -Iarch/$(ARCH) -Iarch/$(ARCH)/include
+AFLAGS += -Iarch/$(ARCH)
+CFLAGS += -Iarch/$(ARCH) -msoft-float -pipe
+CFLAGS-$(CONFIG_PPC64) := -mminimal-toc -mtraceback=none -mcall-aixdesc
+CFLAGS-$(CONFIG_PPC32) := -ffixed-r2 -mmultiple
+CFLAGS += $(CFLAGS-y)
+CPP = $(CC) -E $(CFLAGS)
+# Temporary hack until we have migrated to asm-powerpc
+LINUXINCLUDE += -Iarch/$(ARCH)/include
+
+CHECKFLAGS += -m$(SZ) -D__powerpc__ -D__powerpc$(SZ)__
+
+ifeq ($(CONFIG_PPC64),y)
+GCC_VERSION := $(call cc-version)
+GCC_BROKEN_VEC := $(shell if [ $(GCC_VERSION) -lt 0400 ] ; then echo "y"; fi)
+
+ifeq ($(CONFIG_POWER4_ONLY),y)
+ifeq ($(CONFIG_ALTIVEC),y)
+ifeq ($(GCC_BROKEN_VEC),y)
+ CFLAGS += $(call cc-option,-mcpu=970)
+else
+ CFLAGS += $(call cc-option,-mcpu=power4)
+endif
+else
+ CFLAGS += $(call cc-option,-mcpu=power4)
+endif
+else
+ CFLAGS += $(call cc-option,-mtune=power4)
+endif
+endif
+
+# No AltiVec instruction when building kernel
+CFLAGS += $(call cc-option,-mno-altivec)
+
+# Enable unit-at-a-time mode when possible. It shrinks the
+# kernel considerably.
+CFLAGS += $(call cc-option,-funit-at-a-time)
+
+ifndef CONFIG_FSL_BOOKE
+CFLAGS += -mstring
+endif
+
+cpu-as-$(CONFIG_PPC64BRIDGE) += -Wa,-mppc64bridge
+cpu-as-$(CONFIG_4xx) += -Wa,-m405
+cpu-as-$(CONFIG_6xx) += -Wa,-maltivec
+cpu-as-$(CONFIG_POWER4) += -Wa,-maltivec
+cpu-as-$(CONFIG_E500) += -Wa,-me500
+cpu-as-$(CONFIG_E200) += -Wa,-me200
+
+AFLAGS += $(cpu-as-y)
+CFLAGS += $(cpu-as-y)
+
+# Default to the common case.
+KBUILD_DEFCONFIG := common_defconfig
+
+head-y := arch/powerpc/kernel/head_32.o
+head-$(CONFIG_PPC64) := arch/powerpc/kernel/head_64.o
+head-$(CONFIG_8xx) := arch/powerpc/kernel/head_8xx.o
+head-$(CONFIG_4xx) := arch/powerpc/kernel/head_4xx.o
+head-$(CONFIG_44x) := arch/powerpc/kernel/head_44x.o
+head-$(CONFIG_FSL_BOOKE) := arch/powerpc/kernel/head_fsl_booke.o
+
+head-$(CONFIG_PPC64) += arch/powerpc/kernel/entry_64.o
+head-$(CONFIG_PPC_FPU) += arch/powerpc/kernel/fpu.o
+
+core-y += arch/powerpc/kernel/ \
+ arch/$(OLDARCH)/kernel/ \
+ arch/powerpc/mm/ \
+ arch/powerpc/lib/ \
+ arch/powerpc/sysdev/ \
+ arch/powerpc/platforms/
+core-$(CONFIG_MATH_EMULATION) += arch/ppc/math-emu/
+core-$(CONFIG_XMON) += arch/powerpc/xmon/
+core-$(CONFIG_APUS) += arch/ppc/amiga/
+drivers-$(CONFIG_8xx) += arch/ppc/8xx_io/
+drivers-$(CONFIG_4xx) += arch/ppc/4xx_io/
+drivers-$(CONFIG_CPM2) += arch/ppc/8260_io/
+
+drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/
+
+defaultimage-$(CONFIG_PPC32) := uImage zImage
+defaultimage-$(CONFIG_PPC_ISERIES) := vmlinux
+defaultimage-$(CONFIG_PPC_PSERIES) := zImage
+KBUILD_IMAGE := $(defaultimage-y)
+all: $(KBUILD_IMAGE)
+
+CPPFLAGS_vmlinux.lds := -Upowerpc
+
+# All the instructions talk about "make bzImage".
+bzImage: zImage
+
+BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm
+
+.PHONY: $(BOOT_TARGETS)
+
+boot := arch/$(OLDARCH)/boot
+
+# urk
+ifeq ($(CONFIG_PPC64),y)
+$(BOOT_TARGETS): vmlinux
+ $(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@)
+else
+$(BOOT_TARGETS): vmlinux
+ $(Q)$(MAKE) ARCH=ppc $(build)=$(boot) $@
+endif
+
+uImage: vmlinux
+ $(Q)$(MAKE) ARCH=$(OLDARCH) $(build)=$(boot)/images $(boot)/images/$@
+
+define archhelp
+ @echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/images/zImage.*)'
+ @echo ' uImage - Create a bootable image for U-Boot / PPCBoot'
+ @echo ' install - Install kernel using'
+ @echo ' (your) ~/bin/installkernel or'
+ @echo ' (distribution) /sbin/installkernel or'
+ @echo ' install to $$(INSTALL_PATH) and run lilo'
+ @echo ' *_defconfig - Select default config from arch/$(ARCH)/ppc/configs'
+endef
+
+archclean:
+ $(Q)$(MAKE) $(clean)=$(boot)
+ # Temporary hack until we have migrated to asm-powerpc
+ $(Q)rm -rf arch/$(ARCH)/include
+
+archprepare: checkbin
+
+# Temporary hack until we have migrated to asm-powerpc
+include/asm: arch/$(ARCH)/include/asm
+arch/$(ARCH)/include/asm:
+ $(Q)if [ ! -d arch/$(ARCH)/include ]; then mkdir -p arch/$(ARCH)/include; fi
+ $(Q)ln -fsn $(srctree)/include/asm-$(OLDARCH) arch/$(ARCH)/include/asm
+
+# Use the file '.tmp_gas_check' for binutils tests, as gas won't output
+# to stdout and these checks are run even on install targets.
+TOUT := .tmp_gas_check
+# Ensure this is binutils 2.12.1 (or 2.12.90.0.7) or later for altivec
+# instructions.
+# gcc-3.4 and binutils-2.14 are a fatal combination.
+GCC_VERSION := $(call cc-version)
+
+checkbin:
+ @if test "$(GCC_VERSION)" = "0304" ; then \
+ if ! /bin/echo mftb 5 | $(AS) -v -mppc -many -o $(TOUT) >/dev/null 2>&1 ; then \
+ echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build '; \
+ echo 'correctly with gcc-3.4 and your version of binutils.'; \
+ echo '*** Please upgrade your binutils or downgrade your gcc'; \
+ false; \
+ fi ; \
+ fi
+ @if ! /bin/echo dssall | $(AS) -many -o $(TOUT) >/dev/null 2>&1 ; then \
+ echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build ' ; \
+ echo 'correctly with old versions of binutils.' ; \
+ echo '*** Please upgrade your binutils to 2.12.1 or newer' ; \
+ false ; \
+ fi
+
+CLEAN_FILES += $(TOUT)
+
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
new file mode 100644
index 000000000000..572d4f5eaacb
--- /dev/null
+++ b/arch/powerpc/kernel/Makefile
@@ -0,0 +1,56 @@
+#
+# Makefile for the linux kernel.
+#
+
+ifeq ($(CONFIG_PPC64),y)
+EXTRA_CFLAGS += -mno-minimal-toc
+endif
+ifeq ($(CONFIG_PPC32),y)
+CFLAGS_prom_init.o += -fPIC
+CFLAGS_btext.o += -fPIC
+endif
+
+obj-y := semaphore.o cputable.o ptrace.o syscalls.o \
+ signal_32.o pmc.o
+obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \
+ ptrace32.o systbl.o
+obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
+obj-$(CONFIG_POWER4) += idle_power4.o
+obj-$(CONFIG_PPC_OF) += of_device.o
+obj-$(CONFIG_PPC_RTAS) += rtas.o
+obj-$(CONFIG_IBMVIO) += vio.o
+
+ifeq ($(CONFIG_PPC_MERGE),y)
+
+extra-$(CONFIG_PPC_STD_MMU) := head_32.o
+extra-$(CONFIG_PPC64) := head_64.o
+extra-$(CONFIG_40x) := head_4xx.o
+extra-$(CONFIG_44x) := head_44x.o
+extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o
+extra-$(CONFIG_8xx) := head_8xx.o
+extra-y += vmlinux.lds
+
+obj-y += process.o init_task.o time.o \
+ prom.o traps.o setup-common.o
+obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o systbl.o
+obj-$(CONFIG_PPC64) += misc_64.o
+obj-$(CONFIG_PPC_OF) += prom_init.o
+obj-$(CONFIG_MODULES) += ppc_ksyms.o
+obj-$(CONFIG_BOOTX_TEXT) += btext.o
+obj-$(CONFIG_6xx) += idle_6xx.o
+
+ifeq ($(CONFIG_PPC_ISERIES),y)
+$(obj)/head_64.o: $(obj)/lparmap.s
+AFLAGS_head_64.o += -I$(obj)
+endif
+
+else
+# stuff used from here for ARCH=ppc or ARCH=ppc64
+obj-$(CONFIG_PPC64) += traps.o process.o init_task.o time.o \
+ setup-common.o
+
+
+endif
+
+extra-$(CONFIG_PPC_FPU) += fpu.o
+extra-$(CONFIG_PPC64) += entry_64.o
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
new file mode 100644
index 000000000000..330cd783206f
--- /dev/null
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -0,0 +1,273 @@
+/*
+ * This program is used to generate definitions needed by
+ * assembly language modules.
+ *
+ * We use the technique used in the OSF Mach kernel code:
+ * generate asm statements containing #defines,
+ * compile this file to assembler, and then extract the
+ * #defines from the assembly-language output.
+ *
+ * This program is free software; you can redistribute 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/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#ifdef CONFIG_PPC64
+#include <linux/time.h>
+#include <linux/hardirq.h>
+#else
+#include <linux/ptrace.h>
+#include <linux/suspend.h>
+#endif
+
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/cputable.h>
+#include <asm/thread_info.h>
+#include <asm/rtas.h>
+#ifdef CONFIG_PPC64
+#include <asm/paca.h>
+#include <asm/lppaca.h>
+#include <asm/iSeries/HvLpEvent.h>
+#include <asm/cache.h>
+#include <asm/systemcfg.h>
+#include <asm/compat.h>
+#endif
+
+#define DEFINE(sym, val) \
+ asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+
+#define BLANK() asm volatile("\n->" : : )
+
+int main(void)
+{
+ DEFINE(THREAD, offsetof(struct task_struct, thread));
+ DEFINE(MM, offsetof(struct task_struct, mm));
+#ifdef CONFIG_PPC64
+ DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context));
+#else
+ DEFINE(THREAD_INFO, offsetof(struct task_struct, thread_info));
+ DEFINE(PTRACE, offsetof(struct task_struct, ptrace));
+#endif /* CONFIG_PPC64 */
+
+ DEFINE(KSP, offsetof(struct thread_struct, ksp));
+ DEFINE(PT_REGS, offsetof(struct thread_struct, regs));
+ DEFINE(THREAD_FPEXC_MODE, offsetof(struct thread_struct, fpexc_mode));
+ DEFINE(THREAD_FPR0, offsetof(struct thread_struct, fpr[0]));
+ DEFINE(THREAD_FPSCR, offsetof(struct thread_struct, fpscr));
+#ifdef CONFIG_ALTIVEC
+ DEFINE(THREAD_VR0, offsetof(struct thread_struct, vr[0]));
+ DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave));
+ DEFINE(THREAD_VSCR, offsetof(struct thread_struct, vscr));
+ DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr));
+#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_PPC64
+ DEFINE(KSP_VSID, offsetof(struct thread_struct, ksp_vsid));
+#else /* CONFIG_PPC64 */
+ DEFINE(PGDIR, offsetof(struct thread_struct, pgdir));
+ DEFINE(LAST_SYSCALL, offsetof(struct thread_struct, last_syscall));
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+ DEFINE(THREAD_DBCR0, offsetof(struct thread_struct, dbcr0));
+ DEFINE(PT_PTRACED, PT_PTRACED);
+#endif
+#ifdef CONFIG_SPE
+ DEFINE(THREAD_EVR0, offsetof(struct thread_struct, evr[0]));
+ DEFINE(THREAD_ACC, offsetof(struct thread_struct, acc));
+ DEFINE(THREAD_SPEFSCR, offsetof(struct thread_struct, spefscr));
+ DEFINE(THREAD_USED_SPE, offsetof(struct thread_struct, used_spe));
+#endif /* CONFIG_SPE */
+#endif /* CONFIG_PPC64 */
+
+ DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
+ DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
+ DEFINE(TI_SC_NOERR, offsetof(struct thread_info, syscall_noerror));
+#ifdef CONFIG_PPC32
+ DEFINE(TI_TASK, offsetof(struct thread_info, task));
+ DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain));
+ DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
+#endif /* CONFIG_PPC32 */
+
+#ifdef CONFIG_PPC64
+ DEFINE(DCACHEL1LINESIZE, offsetof(struct ppc64_caches, dline_size));
+ DEFINE(DCACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_dline_size));
+ DEFINE(DCACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, dlines_per_page));
+ DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size));
+ DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size));
+ DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page));
+ DEFINE(PLATFORM, offsetof(struct systemcfg, platform));
+ DEFINE(PLATFORM_LPAR, PLATFORM_LPAR);
+
+ /* paca */
+ DEFINE(PACA_SIZE, sizeof(struct paca_struct));
+ DEFINE(PACAPACAINDEX, offsetof(struct paca_struct, paca_index));
+ DEFINE(PACAPROCSTART, offsetof(struct paca_struct, cpu_start));
+ DEFINE(PACAKSAVE, offsetof(struct paca_struct, kstack));
+ DEFINE(PACACURRENT, offsetof(struct paca_struct, __current));
+ DEFINE(PACASAVEDMSR, offsetof(struct paca_struct, saved_msr));
+ DEFINE(PACASTABREAL, offsetof(struct paca_struct, stab_real));
+ DEFINE(PACASTABVIRT, offsetof(struct paca_struct, stab_addr));
+ DEFINE(PACASTABRR, offsetof(struct paca_struct, stab_rr));
+ DEFINE(PACAR1, offsetof(struct paca_struct, saved_r1));
+ DEFINE(PACATOC, offsetof(struct paca_struct, kernel_toc));
+ DEFINE(PACAPROCENABLED, offsetof(struct paca_struct, proc_enabled));
+ DEFINE(PACASLBCACHE, offsetof(struct paca_struct, slb_cache));
+ DEFINE(PACASLBCACHEPTR, offsetof(struct paca_struct, slb_cache_ptr));
+ DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id));
+#ifdef CONFIG_HUGETLB_PAGE
+ DEFINE(PACALOWHTLBAREAS, offsetof(struct paca_struct, context.low_htlb_areas));
+ DEFINE(PACAHIGHHTLBAREAS, offsetof(struct paca_struct, context.high_htlb_areas));
+#endif /* CONFIG_HUGETLB_PAGE */
+ DEFINE(PACADEFAULTDECR, offsetof(struct paca_struct, default_decr));
+ DEFINE(PACA_EXGEN, offsetof(struct paca_struct, exgen));
+ DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc));
+ DEFINE(PACA_EXSLB, offsetof(struct paca_struct, exslb));
+ DEFINE(PACA_EXDSI, offsetof(struct paca_struct, exdsi));
+ DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp));
+ DEFINE(PACALPPACA, offsetof(struct paca_struct, lppaca));
+ DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
+
+ DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0));
+ DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1));
+ DEFINE(LPPACAANYINT, offsetof(struct lppaca, int_dword.any_int));
+ DEFINE(LPPACADECRINT, offsetof(struct lppaca, int_dword.fields.decr_int));
+#endif /* CONFIG_PPC64 */
+
+ /* RTAS */
+ DEFINE(RTASBASE, offsetof(struct rtas_t, base));
+ DEFINE(RTASENTRY, offsetof(struct rtas_t, entry));
+
+ /* Interrupt register frame */
+ DEFINE(STACK_FRAME_OVERHEAD, STACK_FRAME_OVERHEAD);
+#ifndef CONFIG_PPC64
+ DEFINE(INT_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs));
+#else /* CONFIG_PPC64 */
+ DEFINE(SWITCH_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs));
+ /* 288 = # of volatile regs, int & fp, for leaf routines */
+ /* which do not stack a frame. See the PPC64 ABI. */
+ DEFINE(INT_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 288);
+ /* Create extra stack space for SRR0 and SRR1 when calling prom/rtas. */
+ DEFINE(PROM_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16);
+ DEFINE(RTAS_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16);
+#endif /* CONFIG_PPC64 */
+ DEFINE(GPR0, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[0]));
+ DEFINE(GPR1, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[1]));
+ DEFINE(GPR2, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[2]));
+ DEFINE(GPR3, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[3]));
+ DEFINE(GPR4, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[4]));
+ DEFINE(GPR5, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[5]));
+ DEFINE(GPR6, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[6]));
+ DEFINE(GPR7, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[7]));
+ DEFINE(GPR8, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[8]));
+ DEFINE(GPR9, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[9]));
+ DEFINE(GPR10, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[10]));
+ DEFINE(GPR11, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[11]));
+ DEFINE(GPR12, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[12]));
+ DEFINE(GPR13, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[13]));
+#ifndef CONFIG_PPC64
+ DEFINE(GPR14, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[14]));
+ DEFINE(GPR15, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[15]));
+ DEFINE(GPR16, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[16]));
+ DEFINE(GPR17, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[17]));
+ DEFINE(GPR18, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[18]));
+ DEFINE(GPR19, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[19]));
+ DEFINE(GPR20, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[20]));
+ DEFINE(GPR21, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[21]));
+ DEFINE(GPR22, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[22]));
+ DEFINE(GPR23, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[23]));
+ DEFINE(GPR24, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[24]));
+ DEFINE(GPR25, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[25]));
+ DEFINE(GPR26, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[26]));
+ DEFINE(GPR27, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[27]));
+ DEFINE(GPR28, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[28]));
+ DEFINE(GPR29, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[29]));
+ DEFINE(GPR30, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[30]));
+ DEFINE(GPR31, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[31]));
+#endif /* CONFIG_PPC64 */
+ /*
+ * Note: these symbols include _ because they overlap with special
+ * register names
+ */
+ DEFINE(_NIP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, nip));
+ DEFINE(_MSR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, msr));
+ DEFINE(_CTR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, ctr));
+ DEFINE(_LINK, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, link));
+ DEFINE(_CCR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, ccr));
+ DEFINE(_XER, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, xer));
+ DEFINE(_DAR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dar));
+ DEFINE(_DSISR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dsisr));
+ DEFINE(ORIG_GPR3, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, orig_gpr3));
+ DEFINE(RESULT, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, result));
+ DEFINE(_TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap));
+#ifndef CONFIG_PPC64
+ DEFINE(_MQ, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, mq));
+ /*
+ * The PowerPC 400-class & Book-E processors have neither the DAR
+ * nor the DSISR SPRs. Hence, we overload them to hold the similar
+ * DEAR and ESR SPRs for such processors. For critical interrupts
+ * we use them to hold SRR0 and SRR1.
+ */
+ DEFINE(_DEAR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dar));
+ DEFINE(_ESR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dsisr));
+#else /* CONFIG_PPC64 */
+ DEFINE(SOFTE, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, softe));
+
+ /* These _only_ to be used with {PROM,RTAS}_FRAME_SIZE!!! */
+ DEFINE(_SRR0, STACK_FRAME_OVERHEAD+sizeof(struct pt_regs));
+ DEFINE(_SRR1, STACK_FRAME_OVERHEAD+sizeof(struct pt_regs)+8);
+#endif /* CONFIG_PPC64 */
+
+ DEFINE(CLONE_VM, CLONE_VM);
+ DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
+
+#ifndef CONFIG_PPC64
+ DEFINE(MM_PGD, offsetof(struct mm_struct, pgd));
+#endif /* ! CONFIG_PPC64 */
+
+ /* About the CPU features table */
+ DEFINE(CPU_SPEC_ENTRY_SIZE, sizeof(struct cpu_spec));
+ DEFINE(CPU_SPEC_PVR_MASK, offsetof(struct cpu_spec, pvr_mask));
+ DEFINE(CPU_SPEC_PVR_VALUE, offsetof(struct cpu_spec, pvr_value));
+ DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
+ DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
+
+#ifndef CONFIG_PPC64
+ DEFINE(pbe_address, offsetof(struct pbe, address));
+ DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address));
+ DEFINE(pbe_next, offsetof(struct pbe, next));
+
+ DEFINE(TASK_SIZE, TASK_SIZE);
+ DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28);
+#else /* CONFIG_PPC64 */
+ /* systemcfg offsets for use by vdso */
+ DEFINE(CFG_TB_ORIG_STAMP, offsetof(struct systemcfg, tb_orig_stamp));
+ DEFINE(CFG_TB_TICKS_PER_SEC, offsetof(struct systemcfg, tb_ticks_per_sec));
+ DEFINE(CFG_TB_TO_XS, offsetof(struct systemcfg, tb_to_xs));
+ DEFINE(CFG_STAMP_XSEC, offsetof(struct systemcfg, stamp_xsec));
+ DEFINE(CFG_TB_UPDATE_COUNT, offsetof(struct systemcfg, tb_update_count));
+ DEFINE(CFG_TZ_MINUTEWEST, offsetof(struct systemcfg, tz_minuteswest));
+ DEFINE(CFG_TZ_DSTTIME, offsetof(struct systemcfg, tz_dsttime));
+ DEFINE(CFG_SYSCALL_MAP32, offsetof(struct systemcfg, syscall_map_32));
+ DEFINE(CFG_SYSCALL_MAP64, offsetof(struct systemcfg, syscall_map_64));
+
+ /* timeval/timezone offsets for use by vdso */
+ DEFINE(TVAL64_TV_SEC, offsetof(struct timeval, tv_sec));
+ DEFINE(TVAL64_TV_USEC, offsetof(struct timeval, tv_usec));
+ DEFINE(TVAL32_TV_SEC, offsetof(struct compat_timeval, tv_sec));
+ DEFINE(TVAL32_TV_USEC, offsetof(struct compat_timeval, tv_usec));
+ DEFINE(TZONE_TZ_MINWEST, offsetof(struct timezone, tz_minuteswest));
+ DEFINE(TZONE_TZ_DSTTIME, offsetof(struct timezone, tz_dsttime));
+#endif /* CONFIG_PPC64 */
+ return 0;
+}
diff --git a/arch/ppc64/kernel/binfmt_elf32.c b/arch/powerpc/kernel/binfmt_elf32.c
index fadc699a0497..8ad6b0f33651 100644
--- a/arch/ppc64/kernel/binfmt_elf32.c
+++ b/arch/powerpc/kernel/binfmt_elf32.c
@@ -70,9 +70,6 @@ cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value)
value->tv_sec = jiffies / HZ;
}
-extern void start_thread32(struct pt_regs *, unsigned long, unsigned long);
-#undef start_thread
-#define start_thread start_thread32
#define init_elf_binfmt init_elf32_binfmt
#include "../../../fs/binfmt_elf.c"
diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c
new file mode 100644
index 000000000000..bdfba92b2b38
--- /dev/null
+++ b/arch/powerpc/kernel/btext.c
@@ -0,0 +1,853 @@
+/*
+ * Procedures for drawing on the screen early on in the boot process.
+ *
+ * Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include <asm/sections.h>
+#include <asm/prom.h>
+#include <asm/btext.h>
+#include <asm/prom.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/io.h>
+#include <asm/lmb.h>
+#include <asm/processor.h>
+
+#define NO_SCROLL
+
+#ifndef NO_SCROLL
+static void scrollscreen(void);
+#endif
+
+static void draw_byte(unsigned char c, long locX, long locY);
+static void draw_byte_32(unsigned char *bits, unsigned int *base, int rb);
+static void draw_byte_16(unsigned char *bits, unsigned int *base, int rb);
+static void draw_byte_8(unsigned char *bits, unsigned int *base, int rb);
+
+static int g_loc_X;
+static int g_loc_Y;
+static int g_max_loc_X;
+static int g_max_loc_Y;
+
+static int dispDeviceRowBytes;
+static int dispDeviceDepth;
+static int dispDeviceRect[4];
+static unsigned char *dispDeviceBase, *logicalDisplayBase;
+
+unsigned long disp_BAT[2] __initdata = {0, 0};
+
+#define cmapsz (16*256)
+
+static unsigned char vga_font[cmapsz];
+
+int boot_text_mapped;
+int force_printk_to_btext = 0;
+
+#ifdef CONFIG_PPC32
+/* Calc BAT values for mapping the display and store them
+ * in disp_BAT. Those values are then used from head.S to map
+ * the display during identify_machine() and MMU_Init()
+ *
+ * The display is mapped to virtual address 0xD0000000, rather
+ * than 1:1, because some some CHRP machines put the frame buffer
+ * in the region starting at 0xC0000000 (KERNELBASE).
+ * This mapping is temporary and will disappear as soon as the
+ * setup done by MMU_Init() is applied.
+ *
+ * For now, we align the BAT and then map 8Mb on 601 and 16Mb
+ * on other PPCs. This may cause trouble if the framebuffer
+ * is really badly aligned, but I didn't encounter this case
+ * yet.
+ */
+void __init
+btext_prepare_BAT(void)
+{
+ unsigned long vaddr = KERNELBASE + 0x10000000;
+ unsigned long addr;
+ unsigned long lowbits;
+
+ addr = (unsigned long)dispDeviceBase;
+ if (!addr) {
+ boot_text_mapped = 0;
+ return;
+ }
+ if (PVR_VER(mfspr(SPRN_PVR)) != 1) {
+ /* 603, 604, G3, G4, ... */
+ lowbits = addr & ~0xFF000000UL;
+ addr &= 0xFF000000UL;
+ disp_BAT[0] = vaddr | (BL_16M<<2) | 2;
+ disp_BAT[1] = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW);
+ } else {
+ /* 601 */
+ lowbits = addr & ~0xFF800000UL;
+ addr &= 0xFF800000UL;
+ disp_BAT[0] = vaddr | (_PAGE_NO_CACHE | PP_RWXX) | 4;
+ disp_BAT[1] = addr | BL_8M | 0x40;
+ }
+ logicalDisplayBase = (void *) (vaddr + lowbits);
+}
+#endif
+
+/* This function will enable the early boot text when doing OF booting. This
+ * way, xmon output should work too
+ */
+void __init
+btext_setup_display(int width, int height, int depth, int pitch,
+ unsigned long address)
+{
+ g_loc_X = 0;
+ g_loc_Y = 0;
+ g_max_loc_X = width / 8;
+ g_max_loc_Y = height / 16;
+ logicalDisplayBase = (unsigned char *)address;
+ dispDeviceBase = (unsigned char *)address;
+ dispDeviceRowBytes = pitch;
+ dispDeviceDepth = depth;
+ dispDeviceRect[0] = dispDeviceRect[1] = 0;
+ dispDeviceRect[2] = width;
+ dispDeviceRect[3] = height;
+ boot_text_mapped = 1;
+}
+
+/* Here's a small text engine to use during early boot
+ * or for debugging purposes
+ *
+ * todo:
+ *
+ * - build some kind of vgacon with it to enable early printk
+ * - move to a separate file
+ * - add a few video driver hooks to keep in sync with display
+ * changes.
+ */
+
+void map_boot_text(void)
+{
+ unsigned long base, offset, size;
+ unsigned char *vbase;
+
+ /* By default, we are no longer mapped */
+ boot_text_mapped = 0;
+ if (dispDeviceBase == 0)
+ return;
+ base = ((unsigned long) dispDeviceBase) & 0xFFFFF000UL;
+ offset = ((unsigned long) dispDeviceBase) - base;
+ size = dispDeviceRowBytes * dispDeviceRect[3] + offset
+ + dispDeviceRect[0];
+ vbase = __ioremap(base, size, _PAGE_NO_CACHE);
+ if (vbase == 0)
+ return;
+ logicalDisplayBase = vbase + offset;
+ boot_text_mapped = 1;
+}
+
+int btext_initialize(struct device_node *np)
+{
+ unsigned int width, height, depth, pitch;
+ unsigned long address = 0;
+ u32 *prop;
+
+ prop = (u32 *)get_property(np, "width", NULL);
+ if (prop == NULL)
+ return -EINVAL;
+ width = *prop;
+ prop = (u32 *)get_property(np, "height", NULL);
+ if (prop == NULL)
+ return -EINVAL;
+ height = *prop;
+ prop = (u32 *)get_property(np, "depth", NULL);
+ if (prop == NULL)
+ return -EINVAL;
+ depth = *prop;
+ pitch = width * ((depth + 7) / 8);
+ prop = (u32 *)get_property(np, "linebytes", NULL);
+ if (prop)
+ pitch = *prop;
+ if (pitch == 1)
+ pitch = 0x1000;
+ prop = (u32 *)get_property(np, "address", NULL);
+ if (prop)
+ address = *prop;
+
+ /* FIXME: Add support for PCI reg properties */
+
+ if (address == 0)
+ return -EINVAL;
+
+ g_loc_X = 0;
+ g_loc_Y = 0;
+ g_max_loc_X = width / 8;
+ g_max_loc_Y = height / 16;
+ logicalDisplayBase = (unsigned char *)address;
+ dispDeviceBase = (unsigned char *)address;
+ dispDeviceRowBytes = pitch;
+ dispDeviceDepth = depth;
+ dispDeviceRect[0] = dispDeviceRect[1] = 0;
+ dispDeviceRect[2] = width;
+ dispDeviceRect[3] = height;
+
+ map_boot_text();
+
+ return 0;
+}
+
+void __init init_boot_display(void)
+{
+ char *name;
+ struct device_node *np = NULL;
+ int rc = -ENODEV;
+
+ printk("trying to initialize btext ...\n");
+
+ name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
+ if (name != NULL) {
+ np = of_find_node_by_path(name);
+ if (np != NULL) {
+ if (strcmp(np->type, "display") != 0) {
+ printk("boot stdout isn't a display !\n");
+ of_node_put(np);
+ np = NULL;
+ }
+ }
+ }
+ if (np)
+ rc = btext_initialize(np);
+ if (rc == 0)
+ return;
+
+ for (np = NULL; (np = of_find_node_by_type(np, "display"));) {
+ if (get_property(np, "linux,opened", NULL)) {
+ printk("trying %s ...\n", np->full_name);
+ rc = btext_initialize(np);
+ printk("result: %d\n", rc);
+ }
+ if (rc == 0)
+ return;
+ }
+}
+
+/* Calc the base address of a given point (x,y) */
+static unsigned char * calc_base(int x, int y)
+{
+ unsigned char *base;
+
+ base = logicalDisplayBase;
+ if (base == 0)
+ base = dispDeviceBase;
+ base += (x + dispDeviceRect[0]) * (dispDeviceDepth >> 3);
+ base += (y + dispDeviceRect[1]) * dispDeviceRowBytes;
+ return base;
+}
+
+/* Adjust the display to a new resolution */
+void btext_update_display(unsigned long phys, int width, int height,
+ int depth, int pitch)
+{
+ if (dispDeviceBase == 0)
+ return;
+
+ /* check it's the same frame buffer (within 256MB) */
+ if ((phys ^ (unsigned long)dispDeviceBase) & 0xf0000000)
+ return;
+
+ dispDeviceBase = (__u8 *) phys;
+ dispDeviceRect[0] = 0;
+ dispDeviceRect[1] = 0;
+ dispDeviceRect[2] = width;
+ dispDeviceRect[3] = height;
+ dispDeviceDepth = depth;
+ dispDeviceRowBytes = pitch;
+ if (boot_text_mapped) {
+ iounmap(logicalDisplayBase);
+ boot_text_mapped = 0;
+ }
+ map_boot_text();
+ g_loc_X = 0;
+ g_loc_Y = 0;
+ g_max_loc_X = width / 8;
+ g_max_loc_Y = height / 16;
+}
+EXPORT_SYMBOL(btext_update_display);
+
+void btext_clearscreen(void)
+{
+ unsigned long *base = (unsigned long *)calc_base(0, 0);
+ unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) *
+ (dispDeviceDepth >> 3)) >> 3;
+ int i,j;
+
+ for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1]); i++)
+ {
+ unsigned long *ptr = base;
+ for(j=width; j; --j)
+ *(ptr++) = 0;
+ base += (dispDeviceRowBytes >> 3);
+ }
+}
+
+#ifndef NO_SCROLL
+static void scrollscreen(void)
+{
+ unsigned long *src = (unsigned long *)calc_base(0,16);
+ unsigned long *dst = (unsigned long *)calc_base(0,0);
+ unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) *
+ (dispDeviceDepth >> 3)) >> 3;
+ int i,j;
+
+ for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1] - 16); i++)
+ {
+ unsigned long *src_ptr = src;
+ unsigned long *dst_ptr = dst;
+ for(j=width; j; --j)
+ *(dst_ptr++) = *(src_ptr++);
+ src += (dispDeviceRowBytes >> 3);
+ dst += (dispDeviceRowBytes >> 3);
+ }
+ for (i=0; i<16; i++)
+ {
+ unsigned long *dst_ptr = dst;
+ for(j=width; j; --j)
+ *(dst_ptr++) = 0;
+ dst += (dispDeviceRowBytes >> 3);
+ }
+}
+#endif /* ndef NO_SCROLL */
+
+void btext_drawchar(char c)
+{
+ int cline = 0;
+#ifdef NO_SCROLL
+ int x;
+#endif
+ if (!boot_text_mapped)
+ return;
+
+ switch (c) {
+ case '\b':
+ if (g_loc_X > 0)
+ --g_loc_X;
+ break;
+ case '\t':
+ g_loc_X = (g_loc_X & -8) + 8;
+ break;
+ case '\r':
+ g_loc_X = 0;
+ break;
+ case '\n':
+ g_loc_X = 0;
+ g_loc_Y++;
+ cline = 1;
+ break;
+ default:
+ draw_byte(c, g_loc_X++, g_loc_Y);
+ }
+ if (g_loc_X >= g_max_loc_X) {
+ g_loc_X = 0;
+ g_loc_Y++;
+ cline = 1;
+ }
+#ifndef NO_SCROLL
+ while (g_loc_Y >= g_max_loc_Y) {
+ scrollscreen();
+ g_loc_Y--;
+ }
+#else
+ /* wrap around from bottom to top of screen so we don't
+ waste time scrolling each line. -- paulus. */
+ if (g_loc_Y >= g_max_loc_Y)
+ g_loc_Y = 0;
+ if (cline) {
+ for (x = 0; x < g_max_loc_X; ++x)
+ draw_byte(' ', x, g_loc_Y);
+ }
+#endif
+}
+
+void btext_drawstring(const char *c)
+{
+ if (!boot_text_mapped)
+ return;
+ while (*c)
+ btext_drawchar(*c++);
+}
+
+void btext_drawhex(unsigned long v)
+{
+ char *hex_table = "0123456789abcdef";
+
+ if (!boot_text_mapped)
+ return;
+#ifdef CONFIG_PPC64
+ btext_drawchar(hex_table[(v >> 60) & 0x0000000FUL]);
+ btext_drawchar(hex_table[(v >> 56) & 0x0000000FUL]);
+ btext_drawchar(hex_table[(v >> 52) & 0x0000000FUL]);
+ btext_drawchar(hex_table[(v >> 48) & 0x0000000FUL]);
+ btext_drawchar(hex_table[(v >> 44) & 0x0000000FUL]);
+ btext_drawchar(hex_table[(v >> 40) & 0x0000000FUL]);
+ btext_drawchar(hex_table[(v >> 36) & 0x0000000FUL]);
+ btext_drawchar(hex_table[(v >> 32) & 0x0000000FUL]);
+#endif
+ btext_drawchar(hex_table[(v >> 28) & 0x0000000FUL]);
+ btext_drawchar(hex_table[(v >> 24) & 0x0000000FUL]);
+ btext_drawchar(hex_table[(v >> 20) & 0x0000000FUL]);
+ btext_drawchar(hex_table[(v >> 16) & 0x0000000FUL]);
+ btext_drawchar(hex_table[(v >> 12) & 0x0000000FUL]);
+ btext_drawchar(hex_table[(v >> 8) & 0x0000000FUL]);
+ btext_drawchar(hex_table[(v >> 4) & 0x0000000FUL]);
+ btext_drawchar(hex_table[(v >> 0) & 0x0000000FUL]);
+ btext_drawchar(' ');
+}
+
+static void draw_byte(unsigned char c, long locX, long locY)
+{
+ unsigned char *base = calc_base(locX << 3, locY << 4);
+ unsigned char *font = &vga_font[((unsigned int)c) * 16];
+ int rb = dispDeviceRowBytes;
+
+ switch(dispDeviceDepth) {
+ case 24:
+ case 32:
+ draw_byte_32(font, (unsigned int *)base, rb);
+ break;
+ case 15:
+ case 16:
+ draw_byte_16(font, (unsigned int *)base, rb);
+ break;
+ case 8:
+ draw_byte_8(font, (unsigned int *)base, rb);
+ break;
+ }
+}
+
+static unsigned int expand_bits_8[16] = {
+ 0x00000000,
+ 0x000000ff,
+ 0x0000ff00,
+ 0x0000ffff,
+ 0x00ff0000,
+ 0x00ff00ff,
+ 0x00ffff00,
+ 0x00ffffff,
+ 0xff000000,
+ 0xff0000ff,
+ 0xff00ff00,
+ 0xff00ffff,
+ 0xffff0000,
+ 0xffff00ff,
+ 0xffffff00,
+ 0xffffffff
+};
+
+static unsigned int expand_bits_16[4] = {
+ 0x00000000,
+ 0x0000ffff,
+ 0xffff0000,
+ 0xffffffff
+};
+
+
+static void draw_byte_32(unsigned char *font, unsigned int *base, int rb)
+{
+ int l, bits;
+ int fg = 0xFFFFFFFFUL;
+ int bg = 0x00000000UL;
+
+ for (l = 0; l < 16; ++l)
+ {
+ bits = *font++;
+ base[0] = (-(bits >> 7) & fg) ^ bg;
+ base[1] = (-((bits >> 6) & 1) & fg) ^ bg;
+ base[2] = (-((bits >> 5) & 1) & fg) ^ bg;
+ base[3] = (-((bits >> 4) & 1) & fg) ^ bg;
+ base[4] = (-((bits >> 3) & 1) & fg) ^ bg;
+ base[5] = (-((bits >> 2) & 1) & fg) ^ bg;
+ base[6] = (-((bits >> 1) & 1) & fg) ^ bg;
+ base[7] = (-(bits & 1) & fg) ^ bg;
+ base = (unsigned int *) ((char *)base + rb);
+ }
+}
+
+static void draw_byte_16(unsigned char *font, unsigned int *base, int rb)
+{
+ int l, bits;
+ int fg = 0xFFFFFFFFUL;
+ int bg = 0x00000000UL;
+ unsigned int *eb = (int *)expand_bits_16;
+
+ for (l = 0; l < 16; ++l)
+ {
+ bits = *font++;
+ base[0] = (eb[bits >> 6] & fg) ^ bg;
+ base[1] = (eb[(bits >> 4) & 3] & fg) ^ bg;
+ base[2] = (eb[(bits >> 2) & 3] & fg) ^ bg;
+ base[3] = (eb[bits & 3] & fg) ^ bg;
+ base = (unsigned int *) ((char *)base + rb);
+ }
+}
+
+static void draw_byte_8(unsigned char *font, unsigned int *base, int rb)
+{
+ int l, bits;
+ int fg = 0x0F0F0F0FUL;
+ int bg = 0x00000000UL;
+ unsigned int *eb = (int *)expand_bits_8;
+
+ for (l = 0; l < 16; ++l)
+ {
+ bits = *font++;
+ base[0] = (eb[bits >> 4] & fg) ^ bg;
+ base[1] = (eb[bits & 0xf] & fg) ^ bg;
+ base = (unsigned int *) ((char *)base + rb);
+ }
+}
+
+static unsigned char vga_font[cmapsz] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd,
+0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff,
+0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe,
+0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
+0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd,
+0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e,
+0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30,
+0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63,
+0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8,
+0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e,
+0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb,
+0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6,
+0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
+0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0,
+0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c,
+0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c,
+0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c,
+0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18,
+0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c,
+0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30,
+0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18,
+0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
+0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
+0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe,
+0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
+0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18,
+0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
+0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
+0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
+0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
+0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde,
+0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38,
+0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0,
+0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c,
+0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68,
+0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
+0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c,
+0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60,
+0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe7,
+0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66,
+0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c,
+0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c,
+0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
+0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3,
+0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18,
+0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3,
+0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30,
+0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
+0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60,
+0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc,
+0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60,
+0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06,
+0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60,
+0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb,
+0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66,
+0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60,
+0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30,
+0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3,
+0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6,
+0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18,
+0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6,
+0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
+0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00,
+0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe,
+0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c,
+0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38,
+0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06,
+0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe,
+0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00,
+0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66,
+0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6,
+0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00,
+0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b,
+0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c,
+0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6,
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18,
+0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00,
+0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,
+0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
+0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18,
+0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66,
+0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18,
+0xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30,
+0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc,
+0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c,
+0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
+0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06,
+0x0c, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30,
+0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
+0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36,
+0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44,
+0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
+0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
+0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
+0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
+0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36,
+0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0,
+0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0,
+0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8,
+0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66,
+0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
+0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66,
+0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60,
+0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
+0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18,
+0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
+0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x1b, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00,
+0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c,
+0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c,
+0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00,
+};
diff --git a/arch/ppc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 6b76cf58d9e0..b91345fa0805 100644
--- a/arch/ppc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -1,8 +1,9 @@
/*
- * arch/ppc/kernel/cputable.c
- *
* Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org)
*
+ * Modifications for ppc64:
+ * Copyright (C) 2003 Dave Engebretsen <engebret@us.ibm.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
@@ -14,96 +15,302 @@
#include <linux/sched.h>
#include <linux/threads.h>
#include <linux/init.h>
-#include <asm/cputable.h>
+#include <linux/module.h>
-struct cpu_spec* cur_cpu_spec[NR_CPUS];
+#include <asm/oprofile_impl.h>
+#include <asm/cputable.h>
-extern void __setup_cpu_601(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
-extern void __setup_cpu_603(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
-extern void __setup_cpu_604(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
-extern void __setup_cpu_750(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
-extern void __setup_cpu_750cx(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
-extern void __setup_cpu_750fx(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
-extern void __setup_cpu_7400(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
-extern void __setup_cpu_7410(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
-extern void __setup_cpu_745x(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
-extern void __setup_cpu_power3(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
-extern void __setup_cpu_power4(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
-extern void __setup_cpu_ppc970(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
-extern void __setup_cpu_generic(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
+struct cpu_spec* cur_cpu_spec = NULL;
+EXPORT_SYMBOL(cur_cpu_spec);
-#define CLASSIC_PPC (!defined(CONFIG_8xx) && !defined(CONFIG_4xx) && \
- !defined(CONFIG_POWER3) && !defined(CONFIG_POWER4) && \
- !defined(CONFIG_BOOKE))
+/* NOTE:
+ * Unlike ppc32, ppc64 will only call this once for the boot CPU, it's
+ * the responsibility of the appropriate CPU save/restore functions to
+ * eventually copy these settings over. Those save/restore aren't yet
+ * part of the cputable though. That has to be fixed for both ppc32
+ * and ppc64
+ */
+#ifdef CONFIG_PPC64
+extern void __setup_cpu_power3(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_power4(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_be(unsigned long offset, struct cpu_spec* spec);
+#else
+extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_750cx(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_750fx(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_7400(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_7410(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_745x(unsigned long offset, struct cpu_spec* spec);
+#endif /* CONFIG_PPC32 */
+extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
/* This table only contains "desktop" CPUs, it need to be filled with embedded
* ones as well...
*/
-#define COMMON_PPC (PPC_FEATURE_32 | PPC_FEATURE_HAS_FPU | \
- PPC_FEATURE_HAS_MMU)
+#define COMMON_USER (PPC_FEATURE_32 | PPC_FEATURE_HAS_FPU | \
+ PPC_FEATURE_HAS_MMU)
+#define COMMON_USER_PPC64 (COMMON_USER | PPC_FEATURE_64)
-/* We only set the altivec features if the kernel was compiled with altivec
- * support
- */
-#ifdef CONFIG_ALTIVEC
-#define CPU_FTR_ALTIVEC_COMP CPU_FTR_ALTIVEC
-#define PPC_FEATURE_ALTIVEC_COMP PPC_FEATURE_HAS_ALTIVEC
-#else
-#define CPU_FTR_ALTIVEC_COMP 0
-#define PPC_FEATURE_ALTIVEC_COMP 0
-#endif
/* We only set the spe features if the kernel was compiled with
* spe support
*/
#ifdef CONFIG_SPE
-#define PPC_FEATURE_SPE_COMP PPC_FEATURE_HAS_SPE
+#define PPC_FEATURE_SPE_COMP PPC_FEATURE_HAS_SPE
#else
-#define PPC_FEATURE_SPE_COMP 0
+#define PPC_FEATURE_SPE_COMP 0
#endif
-/* We need to mark all pages as being coherent if we're SMP or we
- * have a 74[45]x and an MPC107 host bridge.
- */
-#if defined(CONFIG_SMP) || defined(CONFIG_MPC10X_BRIDGE)
-#define CPU_FTR_COMMON CPU_FTR_NEED_COHERENT
-#else
-#define CPU_FTR_COMMON 0
+struct cpu_spec cpu_specs[] = {
+#ifdef CONFIG_PPC64
+ { /* Power3 */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x00400000,
+ .cpu_name = "POWER3 (630)",
+ .cpu_features = CPU_FTRS_POWER3,
+ .cpu_user_features = COMMON_USER_PPC64,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 8,
+ .cpu_setup = __setup_cpu_power3,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc64/power3",
+ .oprofile_model = &op_model_rs64,
#endif
-
-/* The powersave features NAP & DOZE seems to confuse BDI when
- debugging. So if a BDI is used, disable theses
- */
-#ifndef CONFIG_BDI_SWITCH
-#define CPU_FTR_MAYBE_CAN_DOZE CPU_FTR_CAN_DOZE
-#define CPU_FTR_MAYBE_CAN_NAP CPU_FTR_CAN_NAP
+ },
+ { /* Power3+ */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x00410000,
+ .cpu_name = "POWER3 (630+)",
+ .cpu_features = CPU_FTRS_POWER3,
+ .cpu_user_features = COMMON_USER_PPC64,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 8,
+ .cpu_setup = __setup_cpu_power3,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc64/power3",
+ .oprofile_model = &op_model_rs64,
+#endif
+ },
+ { /* Northstar */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x00330000,
+ .cpu_name = "RS64-II (northstar)",
+ .cpu_features = CPU_FTRS_RS64,
+ .cpu_user_features = COMMON_USER_PPC64,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 8,
+ .cpu_setup = __setup_cpu_power3,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc64/rs64",
+ .oprofile_model = &op_model_rs64,
+#endif
+ },
+ { /* Pulsar */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x00340000,
+ .cpu_name = "RS64-III (pulsar)",
+ .cpu_features = CPU_FTRS_RS64,
+ .cpu_user_features = COMMON_USER_PPC64,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 8,
+ .cpu_setup = __setup_cpu_power3,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc64/rs64",
+ .oprofile_model = &op_model_rs64,
+#endif
+ },
+ { /* I-star */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x00360000,
+ .cpu_name = "RS64-III (icestar)",
+ .cpu_features = CPU_FTRS_RS64,
+ .cpu_user_features = COMMON_USER_PPC64,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 8,
+ .cpu_setup = __setup_cpu_power3,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc64/rs64",
+ .oprofile_model = &op_model_rs64,
+#endif
+ },
+ { /* S-star */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x00370000,
+ .cpu_name = "RS64-IV (sstar)",
+ .cpu_features = CPU_FTRS_RS64,
+ .cpu_user_features = COMMON_USER_PPC64,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 8,
+ .cpu_setup = __setup_cpu_power3,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc64/rs64",
+ .oprofile_model = &op_model_rs64,
+#endif
+ },
+ { /* Power4 */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x00350000,
+ .cpu_name = "POWER4 (gp)",
+ .cpu_features = CPU_FTRS_POWER4,
+ .cpu_user_features = COMMON_USER_PPC64,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 8,
+ .cpu_setup = __setup_cpu_power4,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc64/power4",
+ .oprofile_model = &op_model_rs64,
+#endif
+ },
+ { /* Power4+ */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x00380000,
+ .cpu_name = "POWER4+ (gq)",
+ .cpu_features = CPU_FTRS_POWER4,
+ .cpu_user_features = COMMON_USER_PPC64,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 8,
+ .cpu_setup = __setup_cpu_power4,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc64/power4",
+ .oprofile_model = &op_model_power4,
+#endif
+ },
+ { /* PPC970 */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x00390000,
+ .cpu_name = "PPC970",
+ .cpu_features = CPU_FTRS_PPC970,
+ .cpu_user_features = COMMON_USER_PPC64 |
+ PPC_FEATURE_HAS_ALTIVEC_COMP,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 8,
+ .cpu_setup = __setup_cpu_ppc970,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc64/970",
+ .oprofile_model = &op_model_power4,
+#endif
+ },
+#endif /* CONFIG_PPC64 */
+#if defined(CONFIG_PPC64) || defined(CONFIG_POWER4)
+ { /* PPC970FX */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x003c0000,
+ .cpu_name = "PPC970FX",
+#ifdef CONFIG_PPC32
+ .cpu_features = CPU_FTRS_970_32,
#else
-#define CPU_FTR_MAYBE_CAN_DOZE 0
-#define CPU_FTR_MAYBE_CAN_NAP 0
+ .cpu_features = CPU_FTRS_PPC970,
#endif
-
-struct cpu_spec cpu_specs[] = {
+ .cpu_user_features = COMMON_USER_PPC64 |
+ PPC_FEATURE_HAS_ALTIVEC_COMP,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 8,
+ .cpu_setup = __setup_cpu_ppc970,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc64/970",
+ .oprofile_model = &op_model_power4,
+#endif
+ },
+#endif /* defined(CONFIG_PPC64) || defined(CONFIG_POWER4) */
+#ifdef CONFIG_PPC64
+ { /* PPC970MP */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x00440000,
+ .cpu_name = "PPC970MP",
+ .cpu_features = CPU_FTRS_PPC970,
+ .cpu_user_features = COMMON_USER_PPC64 |
+ PPC_FEATURE_HAS_ALTIVEC_COMP,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .cpu_setup = __setup_cpu_ppc970,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc64/970",
+ .oprofile_model = &op_model_power4,
+#endif
+ },
+ { /* Power5 */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x003a0000,
+ .cpu_name = "POWER5 (gr)",
+ .cpu_features = CPU_FTRS_POWER5,
+ .cpu_user_features = COMMON_USER_PPC64,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 6,
+ .cpu_setup = __setup_cpu_power4,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc64/power5",
+ .oprofile_model = &op_model_power4,
+#endif
+ },
+ { /* Power5 */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x003b0000,
+ .cpu_name = "POWER5 (gs)",
+ .cpu_features = CPU_FTRS_POWER5,
+ .cpu_user_features = COMMON_USER_PPC64,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 6,
+ .cpu_setup = __setup_cpu_power4,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc64/power5",
+ .oprofile_model = &op_model_power4,
+#endif
+ },
+ { /* BE DD1.x */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x00700000,
+ .cpu_name = "Cell Broadband Engine",
+ .cpu_features = CPU_FTRS_CELL,
+ .cpu_user_features = COMMON_USER_PPC64 |
+ PPC_FEATURE_HAS_ALTIVEC_COMP,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .cpu_setup = __setup_cpu_be,
+ },
+ { /* default match */
+ .pvr_mask = 0x00000000,
+ .pvr_value = 0x00000000,
+ .cpu_name = "POWER4 (compatible)",
+ .cpu_features = CPU_FTRS_COMPATIBLE,
+ .cpu_user_features = COMMON_USER_PPC64,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 6,
+ .cpu_setup = __setup_cpu_power4,
+ }
+#endif /* CONFIG_PPC64 */
+#ifdef CONFIG_PPC32
#if CLASSIC_PPC
- { /* 601 */
+ { /* 601 */
.pvr_mask = 0xffff0000,
.pvr_value = 0x00010000,
.cpu_name = "601",
- .cpu_features = CPU_FTR_COMMON | CPU_FTR_601 |
- CPU_FTR_HPTE_TABLE,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_601_INSTR |
+ .cpu_features = CPU_FTRS_PPC601,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_601_INSTR |
PPC_FEATURE_UNIFIED_CACHE | PPC_FEATURE_NO_TB,
.icache_bsize = 32,
.dcache_bsize = 32,
- .cpu_setup = __setup_cpu_601
},
{ /* 603 */
.pvr_mask = 0xffff0000,
.pvr_value = 0x00030000,
.cpu_name = "603",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_603,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_603
@@ -112,10 +319,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x00060000,
.cpu_name = "603e",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_603,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_603
@@ -124,10 +329,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x00070000,
.cpu_name = "603ev",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_603,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_603
@@ -136,10 +339,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x00040000,
.cpu_name = "604",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_604_PERF_MON | CPU_FTR_HPTE_TABLE,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_604,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 2,
@@ -149,10 +350,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xfffff000,
.pvr_value = 0x00090000,
.cpu_name = "604e",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_604_PERF_MON | CPU_FTR_HPTE_TABLE,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_604,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -162,10 +361,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x00090000,
.cpu_name = "604r",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_604_PERF_MON | CPU_FTR_HPTE_TABLE,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_604,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -175,10 +372,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x000a0000,
.cpu_name = "604ev",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_604_PERF_MON | CPU_FTR_HPTE_TABLE,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_604,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -188,11 +383,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffffffff,
.pvr_value = 0x00084202,
.cpu_name = "740/750",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_HPTE_TABLE |
- CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_740_NOTAU,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -202,11 +394,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xfffffff0,
.pvr_value = 0x00080100,
.cpu_name = "750CX",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
- CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_750,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -216,11 +405,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xfffffff0,
.pvr_value = 0x00082200,
.cpu_name = "750CX",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
- CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_750,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -230,11 +416,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xfffffff0,
.pvr_value = 0x00082210,
.cpu_name = "750CXe",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
- CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_750,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -244,11 +427,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffffffff,
.pvr_value = 0x00083214,
.cpu_name = "750CXe",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
- CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_750,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -258,11 +438,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xfffff000,
.pvr_value = 0x00083000,
.cpu_name = "745/755",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
- CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_750,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -272,12 +449,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffffff00,
.pvr_value = 0x70000100,
.cpu_name = "750FX",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
- CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP |
- CPU_FTR_DUAL_PLL_750FX | CPU_FTR_NO_DPM,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_750FX1,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -287,12 +460,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffffffff,
.pvr_value = 0x70000200,
.cpu_name = "750FX",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
- CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP |
- CPU_FTR_NO_DPM,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_750FX2,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -302,12 +471,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x70000000,
.cpu_name = "750FX",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
- CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP |
- CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_750FX,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -317,12 +482,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x70020000,
.cpu_name = "750GX",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB |
- CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE |
- CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_DUAL_PLL_750FX |
- CPU_FTR_HAS_HIGH_BATS,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_750GX,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -332,11 +493,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x00080000,
.cpu_name = "740/750",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
- CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_740,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -346,11 +504,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffffffff,
.pvr_value = 0x000c1101,
.cpu_name = "7400 (1.1)",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP |
- CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+ .cpu_features = CPU_FTRS_7400_NOTAU,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -360,12 +515,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x000c0000,
.cpu_name = "7400",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
- CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
- CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+ .cpu_features = CPU_FTRS_7400,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -375,12 +526,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x800c0000,
.cpu_name = "7410",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
- CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
- CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+ .cpu_features = CPU_FTRS_7400,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -390,12 +537,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffffffff,
.pvr_value = 0x80000200,
.cpu_name = "7450",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
- CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
- CPU_FTR_NEED_COHERENT,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+ .cpu_features = CPU_FTRS_7450_20,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@@ -405,14 +548,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffffffff,
.pvr_value = 0x80000201,
.cpu_name = "7450",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR |
- CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
- CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
- CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP |
- CPU_FTR_NEED_COHERENT,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+ .cpu_features = CPU_FTRS_7450_21,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@@ -422,13 +559,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x80000000,
.cpu_name = "7450",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR |
- CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
- CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
- CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_NEED_COHERENT,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+ .cpu_features = CPU_FTRS_7450_23,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@@ -438,12 +570,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffffff00,
.pvr_value = 0x80010100,
.cpu_name = "7455",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
- CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
- CPU_FTR_HAS_HIGH_BATS | CPU_FTR_NEED_COHERENT,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+ .cpu_features = CPU_FTRS_7455_1,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@@ -453,14 +581,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffffffff,
.pvr_value = 0x80010200,
.cpu_name = "7455",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR |
- CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
- CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
- CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP |
- CPU_FTR_NEED_COHERENT | CPU_FTR_HAS_HIGH_BATS,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+ .cpu_features = CPU_FTRS_7455_20,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@@ -470,14 +592,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x80010000,
.cpu_name = "7455",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR |
- CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
- CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
- CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS |
- CPU_FTR_NEED_COHERENT,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+ .cpu_features = CPU_FTRS_7455,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@@ -487,14 +603,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffffffff,
.pvr_value = 0x80020100,
.cpu_name = "7447/7457",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR |
- CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
- CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
- CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS |
- CPU_FTR_NEED_COHERENT | CPU_FTR_NO_BTIC,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+ .cpu_features = CPU_FTRS_7447_10,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@@ -504,14 +614,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffffffff,
.pvr_value = 0x80020101,
.cpu_name = "7447/7457",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR |
- CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
- CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
- CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS |
- CPU_FTR_NEED_COHERENT | CPU_FTR_NO_BTIC,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+ .cpu_features = CPU_FTRS_7447_10,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@@ -521,14 +625,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x80020000,
.cpu_name = "7447/7457",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR |
- CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
- CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
- CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS |
- CPU_FTR_NEED_COHERENT,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+ .cpu_features = CPU_FTRS_7447,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@@ -538,13 +636,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x80030000,
.cpu_name = "7447A",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR |
- CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
- CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR |
- CPU_FTR_HAS_HIGH_BATS | CPU_FTR_NEED_COHERENT,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+ .cpu_features = CPU_FTRS_7447A,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@@ -554,13 +647,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x80040000,
.cpu_name = "7448",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR |
- CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
- CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR |
- CPU_FTR_HAS_HIGH_BATS | CPU_FTR_NEED_COHERENT,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+ .cpu_features = CPU_FTRS_7447A,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@@ -570,10 +658,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0x7fff0000,
.pvr_value = 0x00810000,
.cpu_name = "82xx",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_82XX,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_603
@@ -582,10 +668,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0x7fff0000,
.pvr_value = 0x00820000,
.cpu_name = "G2_LE",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB |
- CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_G2_LE,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_603
@@ -594,10 +678,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0x7fff0000,
.pvr_value = 0x00830000,
.cpu_name = "e300",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB |
- CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_E300,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_603
@@ -606,114 +688,12 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0x00000000,
.pvr_value = 0x00000000,
.cpu_name = "(generic PPC)",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_HPTE_TABLE,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_CLASSIC32,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
- .cpu_setup = __setup_cpu_generic
},
#endif /* CLASSIC_PPC */
-#ifdef CONFIG_PPC64BRIDGE
- { /* Power3 */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00400000,
- .cpu_name = "Power3 (630)",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_HPTE_TABLE,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_power3
- },
- { /* Power3+ */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00410000,
- .cpu_name = "Power3 (630+)",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_HPTE_TABLE,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_power3
- },
- { /* I-star */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00360000,
- .cpu_name = "I-star",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_HPTE_TABLE,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_power3
- },
- { /* S-star */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00370000,
- .cpu_name = "S-star",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_HPTE_TABLE,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_power3
- },
-#endif /* CONFIG_PPC64BRIDGE */
-#ifdef CONFIG_POWER4
- { /* Power4 */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00350000,
- .cpu_name = "Power4",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_HPTE_TABLE,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_power4
- },
- { /* PPC970 */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00390000,
- .cpu_name = "PPC970",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_HPTE_TABLE |
- CPU_FTR_ALTIVEC_COMP | CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_64 |
- PPC_FEATURE_ALTIVEC_COMP,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_ppc970
- },
- { /* PPC970FX */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x003c0000,
- .cpu_name = "PPC970FX",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_HPTE_TABLE |
- CPU_FTR_ALTIVEC_COMP | CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_64 |
- PPC_FEATURE_ALTIVEC_COMP,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_ppc970
- },
-#endif /* CONFIG_POWER4 */
#ifdef CONFIG_8xx
{ /* 8xx */
.pvr_mask = 0xffff0000,
@@ -721,8 +701,7 @@ struct cpu_spec cpu_specs[] = {
.cpu_name = "8xx",
/* CPU_FTR_MAYBE_CAN_DOZE is possible,
* if the 8xx code is there.... */
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_8XX,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.icache_bsize = 16,
.dcache_bsize = 16,
@@ -733,8 +712,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffffff00,
.pvr_value = 0x00200200,
.cpu_name = "403GC",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.icache_bsize = 16,
.dcache_bsize = 16,
@@ -743,8 +721,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffffff00,
.pvr_value = 0x00201400,
.cpu_name = "403GCX",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_NO_TB,
.icache_bsize = 16,
@@ -754,8 +731,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x00200000,
.cpu_name = "403G ??",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.icache_bsize = 16,
.dcache_bsize = 16,
@@ -764,8 +740,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x40110000,
.cpu_name = "405GP",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32,
@@ -775,8 +750,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x40130000,
.cpu_name = "STB03xxx",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32,
@@ -786,8 +760,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x41810000,
.cpu_name = "STB04xxx",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32,
@@ -797,8 +770,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x41610000,
.cpu_name = "NP405L",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32,
@@ -808,8 +780,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x40B10000,
.cpu_name = "NP4GS3",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32,
@@ -819,8 +790,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x41410000,
.cpu_name = "NP405H",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32,
@@ -830,8 +800,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x50910000,
.cpu_name = "405GPr",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32,
@@ -841,8 +810,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x51510000,
.cpu_name = "STBx25xx",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32,
@@ -852,8 +820,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x41F10000,
.cpu_name = "405LP",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.icache_bsize = 32,
.dcache_bsize = 32,
@@ -862,8 +829,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x20010000,
.cpu_name = "Virtex-II Pro",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32,
@@ -873,8 +839,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x51210000,
.cpu_name = "405EP",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32,
@@ -887,9 +852,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xf0000fff,
.pvr_value = 0x40000850,
.cpu_name = "440EP Rev. A",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
- .cpu_user_features = COMMON_PPC, /* 440EP has an FPU */
+ .cpu_features = CPU_FTRS_44X,
+ .cpu_user_features = COMMON_USER, /* 440EP has an FPU */
.icache_bsize = 32,
.dcache_bsize = 32,
},
@@ -897,28 +861,25 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xf0000fff,
.pvr_value = 0x400008d3,
.cpu_name = "440EP Rev. B",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
- .cpu_user_features = COMMON_PPC, /* 440EP has an FPU */
+ .cpu_features = CPU_FTRS_44X,
+ .cpu_user_features = COMMON_USER, /* 440EP has an FPU */
.icache_bsize = 32,
.dcache_bsize = 32,
},
- { /* 440GP Rev. B */
+ { /* 440GP Rev. B */
.pvr_mask = 0xf0000fff,
.pvr_value = 0x40000440,
.cpu_name = "440GP Rev. B",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_44X,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.icache_bsize = 32,
.dcache_bsize = 32,
},
- { /* 440GP Rev. C */
+ { /* 440GP Rev. C */
.pvr_mask = 0xf0000fff,
.pvr_value = 0x40000481,
.cpu_name = "440GP Rev. C",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_44X,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.icache_bsize = 32,
.dcache_bsize = 32,
@@ -927,8 +888,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xf0000fff,
.pvr_value = 0x50000850,
.cpu_name = "440GX Rev. A",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_44X,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.icache_bsize = 32,
.dcache_bsize = 32,
@@ -937,8 +897,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xf0000fff,
.pvr_value = 0x50000851,
.cpu_name = "440GX Rev. B",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_44X,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.icache_bsize = 32,
.dcache_bsize = 32,
@@ -947,8 +906,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xf0000fff,
.pvr_value = 0x50000892,
.cpu_name = "440GX Rev. C",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_44X,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.icache_bsize = 32,
.dcache_bsize = 32,
@@ -957,8 +915,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xf0000fff,
.pvr_value = 0x50000894,
.cpu_name = "440GX Rev. F",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_44X,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.icache_bsize = 32,
.dcache_bsize = 32,
@@ -967,44 +924,42 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xff000fff,
.pvr_value = 0x53000891,
.cpu_name = "440SP Rev. A",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_44X,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.icache_bsize = 32,
.dcache_bsize = 32,
},
#endif /* CONFIG_44x */
#ifdef CONFIG_FSL_BOOKE
- { /* e200z5 */
+ { /* e200z5 */
.pvr_mask = 0xfff00000,
.pvr_value = 0x81000000,
.cpu_name = "e200z5",
/* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
- .cpu_features = CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_E200,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_EFP_SINGLE |
PPC_FEATURE_UNIFIED_CACHE,
.dcache_bsize = 32,
},
- { /* e200z6 */
+ { /* e200z6 */
.pvr_mask = 0xfff00000,
.pvr_value = 0x81100000,
.cpu_name = "e200z6",
/* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
- .cpu_features = CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_E200,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_SPE_COMP |
PPC_FEATURE_HAS_EFP_SINGLE |
PPC_FEATURE_UNIFIED_CACHE,
.dcache_bsize = 32,
},
- { /* e500 */
+ { /* e500 */
.pvr_mask = 0xffff0000,
.pvr_value = 0x80200000,
.cpu_name = "e500",
/* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_E500,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_SPE_COMP |
PPC_FEATURE_HAS_EFP_SINGLE,
@@ -1012,13 +967,12 @@ struct cpu_spec cpu_specs[] = {
.dcache_bsize = 32,
.num_pmcs = 4,
},
- { /* e500v2 */
+ { /* e500v2 */
.pvr_mask = 0xffff0000,
.pvr_value = 0x80210000,
.cpu_name = "e500v2",
/* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_BIG_PHYS,
+ .cpu_features = CPU_FTRS_E500_2,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_SPE_COMP |
PPC_FEATURE_HAS_EFP_SINGLE | PPC_FEATURE_HAS_EFP_DOUBLE,
@@ -1032,10 +986,11 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0x00000000,
.pvr_value = 0x00000000,
.cpu_name = "(generic PPC)",
- .cpu_features = CPU_FTR_COMMON,
+ .cpu_features = CPU_FTRS_GENERIC_32,
.cpu_user_features = PPC_FEATURE_32,
.icache_bsize = 32,
.dcache_bsize = 32,
}
#endif /* !CLASSIC_PPC */
+#endif /* CONFIG_PPC32 */
};
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
new file mode 100644
index 000000000000..2e99ae41723c
--- /dev/null
+++ b/arch/powerpc/kernel/entry_32.S
@@ -0,0 +1,1000 @@
+/*
+ * PowerPC version
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ * Rewritten by Cort Dougan (cort@fsmlabs.com) for PReP
+ * Copyright (C) 1996 Cort Dougan <cort@fsmlabs.com>
+ * Adapted for Power Macintosh by Paul Mackerras.
+ * Low-level exception handlers and MMU support
+ * rewritten by Paul Mackerras.
+ * Copyright (C) 1996 Paul Mackerras.
+ * MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek@jlc.net).
+ *
+ * This file contains the system call entry code, context switch
+ * code, and exception/interrupt return code for PowerPC.
+ *
+ * This program is free software; you can redistribute 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/config.h>
+#include <linux/errno.h>
+#include <linux/sys.h>
+#include <linux/threads.h>
+#include <asm/reg.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+#include <asm/cputable.h>
+#include <asm/thread_info.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/unistd.h>
+
+#undef SHOW_SYSCALLS
+#undef SHOW_SYSCALLS_TASK
+
+/*
+ * MSR_KERNEL is > 0x10000 on 4xx/Book-E since it include MSR_CE.
+ */
+#if MSR_KERNEL >= 0x10000
+#define LOAD_MSR_KERNEL(r, x) lis r,(x)@h; ori r,r,(x)@l
+#else
+#define LOAD_MSR_KERNEL(r, x) li r,(x)
+#endif
+
+#ifdef CONFIG_BOOKE
+#include "head_booke.h"
+#define TRANSFER_TO_HANDLER_EXC_LEVEL(exc_level) \
+ mtspr exc_level##_SPRG,r8; \
+ BOOKE_LOAD_EXC_LEVEL_STACK(exc_level); \
+ lwz r0,GPR10-INT_FRAME_SIZE(r8); \
+ stw r0,GPR10(r11); \
+ lwz r0,GPR11-INT_FRAME_SIZE(r8); \
+ stw r0,GPR11(r11); \
+ mfspr r8,exc_level##_SPRG
+
+ .globl mcheck_transfer_to_handler
+mcheck_transfer_to_handler:
+ TRANSFER_TO_HANDLER_EXC_LEVEL(MCHECK)
+ b transfer_to_handler_full
+
+ .globl debug_transfer_to_handler
+debug_transfer_to_handler:
+ TRANSFER_TO_HANDLER_EXC_LEVEL(DEBUG)
+ b transfer_to_handler_full
+
+ .globl crit_transfer_to_handler
+crit_transfer_to_handler:
+ TRANSFER_TO_HANDLER_EXC_LEVEL(CRIT)
+ /* fall through */
+#endif
+
+#ifdef CONFIG_40x
+ .globl crit_transfer_to_handler
+crit_transfer_to_handler:
+ lwz r0,crit_r10@l(0)
+ stw r0,GPR10(r11)
+ lwz r0,crit_r11@l(0)
+ stw r0,GPR11(r11)
+ /* fall through */
+#endif
+
+/*
+ * This code finishes saving the registers to the exception frame
+ * and jumps to the appropriate handler for the exception, turning
+ * on address translation.
+ * Note that we rely on the caller having set cr0.eq iff the exception
+ * occurred in kernel mode (i.e. MSR:PR = 0).
+ */
+ .globl transfer_to_handler_full
+transfer_to_handler_full:
+ SAVE_NVGPRS(r11)
+ /* fall through */
+
+ .globl transfer_to_handler
+transfer_to_handler:
+ stw r2,GPR2(r11)
+ stw r12,_NIP(r11)
+ stw r9,_MSR(r11)
+ andi. r2,r9,MSR_PR
+ mfctr r12
+ mfspr r2,SPRN_XER
+ stw r12,_CTR(r11)
+ stw r2,_XER(r11)
+ mfspr r12,SPRN_SPRG3
+ addi r2,r12,-THREAD
+ tovirt(r2,r2) /* set r2 to current */
+ beq 2f /* if from user, fix up THREAD.regs */
+ addi r11,r1,STACK_FRAME_OVERHEAD
+ stw r11,PT_REGS(r12)
+#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+ /* Check to see if the dbcr0 register is set up to debug. Use the
+ single-step bit to do this. */
+ lwz r12,THREAD_DBCR0(r12)
+ andis. r12,r12,DBCR0_IC@h
+ beq+ 3f
+ /* From user and task is ptraced - load up global dbcr0 */
+ li r12,-1 /* clear all pending debug events */
+ mtspr SPRN_DBSR,r12
+ lis r11,global_dbcr0@ha
+ tophys(r11,r11)
+ addi r11,r11,global_dbcr0@l
+ lwz r12,0(r11)
+ mtspr SPRN_DBCR0,r12
+ lwz r12,4(r11)
+ addi r12,r12,-1
+ stw r12,4(r11)
+#endif
+ b 3f
+2: /* if from kernel, check interrupted DOZE/NAP mode and
+ * check for stack overflow
+ */
+#ifdef CONFIG_6xx
+ mfspr r11,SPRN_HID0
+ mtcr r11
+BEGIN_FTR_SECTION
+ bt- 8,power_save_6xx_restore /* Check DOZE */
+END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
+BEGIN_FTR_SECTION
+ bt- 9,power_save_6xx_restore /* Check NAP */
+END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
+#endif /* CONFIG_6xx */
+ .globl transfer_to_handler_cont
+transfer_to_handler_cont:
+ lwz r11,THREAD_INFO-THREAD(r12)
+ cmplw r1,r11 /* if r1 <= current->thread_info */
+ ble- stack_ovf /* then the kernel stack overflowed */
+3:
+ mflr r9
+ lwz r11,0(r9) /* virtual address of handler */
+ lwz r9,4(r9) /* where to go when done */
+ FIX_SRR1(r10,r12)
+ mtspr SPRN_SRR0,r11
+ mtspr SPRN_SRR1,r10
+ mtlr r9
+ SYNC
+ RFI /* jump to handler, enable MMU */
+
+/*
+ * On kernel stack overflow, load up an initial stack pointer
+ * and call StackOverflow(regs), which should not return.
+ */
+stack_ovf:
+ /* sometimes we use a statically-allocated stack, which is OK. */
+ lis r11,_end@h
+ ori r11,r11,_end@l
+ cmplw r1,r11
+ ble 3b /* r1 <= &_end is OK */
+ SAVE_NVGPRS(r11)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ lis r1,init_thread_union@ha
+ addi r1,r1,init_thread_union@l
+ addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
+ lis r9,StackOverflow@ha
+ addi r9,r9,StackOverflow@l
+ LOAD_MSR_KERNEL(r10,MSR_KERNEL)
+ FIX_SRR1(r10,r12)
+ mtspr SPRN_SRR0,r9
+ mtspr SPRN_SRR1,r10
+ SYNC
+ RFI
+
+/*
+ * Handle a system call.
+ */
+ .stabs "arch/powerpc/kernel/",N_SO,0,0,0f
+ .stabs "entry_32.S",N_SO,0,0,0f
+0:
+
+_GLOBAL(DoSyscall)
+ stw r0,THREAD+LAST_SYSCALL(r2)
+ stw r3,ORIG_GPR3(r1)
+ li r12,0
+ stw r12,RESULT(r1)
+ lwz r11,_CCR(r1) /* Clear SO bit in CR */
+ rlwinm r11,r11,0,4,2
+ stw r11,_CCR(r1)
+#ifdef SHOW_SYSCALLS
+ bl do_show_syscall
+#endif /* SHOW_SYSCALLS */
+ rlwinm r10,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
+ li r11,0
+ stb r11,TI_SC_NOERR(r10)
+ lwz r11,TI_FLAGS(r10)
+ andi. r11,r11,_TIF_SYSCALL_T_OR_A
+ bne- syscall_dotrace
+syscall_dotrace_cont:
+ cmplwi 0,r0,NR_syscalls
+ lis r10,sys_call_table@h
+ ori r10,r10,sys_call_table@l
+ slwi r0,r0,2
+ bge- 66f
+ lwzx r10,r10,r0 /* Fetch system call handler [ptr] */
+ mtlr r10
+ addi r9,r1,STACK_FRAME_OVERHEAD
+ PPC440EP_ERR42
+ blrl /* Call handler */
+ .globl ret_from_syscall
+ret_from_syscall:
+#ifdef SHOW_SYSCALLS
+ bl do_show_syscall_exit
+#endif
+ mr r6,r3
+ li r11,-_LAST_ERRNO
+ cmplw 0,r3,r11
+ rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
+ blt+ 30f
+ lbz r11,TI_SC_NOERR(r12)
+ cmpwi r11,0
+ bne 30f
+ neg r3,r3
+ lwz r10,_CCR(r1) /* Set SO bit in CR */
+ oris r10,r10,0x1000
+ stw r10,_CCR(r1)
+
+ /* disable interrupts so current_thread_info()->flags can't change */
+30: LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */
+ SYNC
+ MTMSRD(r10)
+ lwz r9,TI_FLAGS(r12)
+ andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED)
+ bne- syscall_exit_work
+syscall_exit_cont:
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+ /* If the process has its own DBCR0 value, load it up. The single
+ step bit tells us that dbcr0 should be loaded. */
+ lwz r0,THREAD+THREAD_DBCR0(r2)
+ andis. r10,r0,DBCR0_IC@h
+ bnel- load_dbcr0
+#endif
+ stwcx. r0,0,r1 /* to clear the reservation */
+ lwz r4,_LINK(r1)
+ lwz r5,_CCR(r1)
+ mtlr r4
+ mtcr r5
+ lwz r7,_NIP(r1)
+ lwz r8,_MSR(r1)
+ FIX_SRR1(r8, r0)
+ lwz r2,GPR2(r1)
+ lwz r1,GPR1(r1)
+ mtspr SPRN_SRR0,r7
+ mtspr SPRN_SRR1,r8
+ SYNC
+ RFI
+
+66: li r3,-ENOSYS
+ b ret_from_syscall
+
+ .globl ret_from_fork
+ret_from_fork:
+ REST_NVGPRS(r1)
+ bl schedule_tail
+ li r3,0
+ b ret_from_syscall
+
+/* Traced system call support */
+syscall_dotrace:
+ SAVE_NVGPRS(r1)
+ li r0,0xc00
+ stw r0,_TRAP(r1)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ bl do_syscall_trace_enter
+ lwz r0,GPR0(r1) /* Restore original registers */
+ lwz r3,GPR3(r1)
+ lwz r4,GPR4(r1)
+ lwz r5,GPR5(r1)
+ lwz r6,GPR6(r1)
+ lwz r7,GPR7(r1)
+ lwz r8,GPR8(r1)
+ REST_NVGPRS(r1)
+ b syscall_dotrace_cont
+
+syscall_exit_work:
+ stw r6,RESULT(r1) /* Save result */
+ stw r3,GPR3(r1) /* Update return value */
+ andi. r0,r9,_TIF_SYSCALL_T_OR_A
+ beq 5f
+ ori r10,r10,MSR_EE
+ SYNC
+ MTMSRD(r10) /* re-enable interrupts */
+ lwz r4,_TRAP(r1)
+ andi. r4,r4,1
+ beq 4f
+ SAVE_NVGPRS(r1)
+ li r4,0xc00
+ stw r4,_TRAP(r1)
+4:
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ bl do_syscall_trace_leave
+ REST_NVGPRS(r1)
+2:
+ lwz r3,GPR3(r1)
+ LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */
+ SYNC
+ MTMSRD(r10) /* disable interrupts again */
+ rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
+ lwz r9,TI_FLAGS(r12)
+5:
+ andi. r0,r9,_TIF_NEED_RESCHED
+ bne 1f
+ lwz r5,_MSR(r1)
+ andi. r5,r5,MSR_PR
+ beq syscall_exit_cont
+ andi. r0,r9,_TIF_SIGPENDING
+ beq syscall_exit_cont
+ b do_user_signal
+1:
+ ori r10,r10,MSR_EE
+ SYNC
+ MTMSRD(r10) /* re-enable interrupts */
+ bl schedule
+ b 2b
+
+#ifdef SHOW_SYSCALLS
+do_show_syscall:
+#ifdef SHOW_SYSCALLS_TASK
+ lis r11,show_syscalls_task@ha
+ lwz r11,show_syscalls_task@l(r11)
+ cmp 0,r2,r11
+ bnelr
+#endif
+ stw r31,GPR31(r1)
+ mflr r31
+ lis r3,7f@ha
+ addi r3,r3,7f@l
+ lwz r4,GPR0(r1)
+ lwz r5,GPR3(r1)
+ lwz r6,GPR4(r1)
+ lwz r7,GPR5(r1)
+ lwz r8,GPR6(r1)
+ lwz r9,GPR7(r1)
+ bl printk
+ lis r3,77f@ha
+ addi r3,r3,77f@l
+ lwz r4,GPR8(r1)
+ mr r5,r2
+ bl printk
+ lwz r0,GPR0(r1)
+ lwz r3,GPR3(r1)
+ lwz r4,GPR4(r1)
+ lwz r5,GPR5(r1)
+ lwz r6,GPR6(r1)
+ lwz r7,GPR7(r1)
+ lwz r8,GPR8(r1)
+ mtlr r31
+ lwz r31,GPR31(r1)
+ blr
+
+do_show_syscall_exit:
+#ifdef SHOW_SYSCALLS_TASK
+ lis r11,show_syscalls_task@ha
+ lwz r11,show_syscalls_task@l(r11)
+ cmp 0,r2,r11
+ bnelr
+#endif
+ stw r31,GPR31(r1)
+ mflr r31
+ stw r3,RESULT(r1) /* Save result */
+ mr r4,r3
+ lis r3,79f@ha
+ addi r3,r3,79f@l
+ bl printk
+ lwz r3,RESULT(r1)
+ mtlr r31
+ lwz r31,GPR31(r1)
+ blr
+
+7: .string "syscall %d(%x, %x, %x, %x, %x, "
+77: .string "%x), current=%p\n"
+79: .string " -> %x\n"
+ .align 2,0
+
+#ifdef SHOW_SYSCALLS_TASK
+ .data
+ .globl show_syscalls_task
+show_syscalls_task:
+ .long -1
+ .text
+#endif
+#endif /* SHOW_SYSCALLS */
+
+/*
+ * The sigsuspend and rt_sigsuspend system calls can call do_signal
+ * and thus put the process into the stopped state where we might
+ * want to examine its user state with ptrace. Therefore we need
+ * to save all the nonvolatile registers (r13 - r31) before calling
+ * the C code.
+ */
+ .globl ppc_sigsuspend
+ppc_sigsuspend:
+ SAVE_NVGPRS(r1)
+ lwz r0,_TRAP(r1)
+ rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */
+ stw r0,_TRAP(r1) /* register set saved */
+ b sys_sigsuspend
+
+ .globl ppc_rt_sigsuspend
+ppc_rt_sigsuspend:
+ SAVE_NVGPRS(r1)
+ lwz r0,_TRAP(r1)
+ rlwinm r0,r0,0,0,30
+ stw r0,_TRAP(r1)
+ b sys_rt_sigsuspend
+
+ .globl ppc_fork
+ppc_fork:
+ SAVE_NVGPRS(r1)
+ lwz r0,_TRAP(r1)
+ rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */
+ stw r0,_TRAP(r1) /* register set saved */
+ b sys_fork
+
+ .globl ppc_vfork
+ppc_vfork:
+ SAVE_NVGPRS(r1)
+ lwz r0,_TRAP(r1)
+ rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */
+ stw r0,_TRAP(r1) /* register set saved */
+ b sys_vfork
+
+ .globl ppc_clone
+ppc_clone:
+ SAVE_NVGPRS(r1)
+ lwz r0,_TRAP(r1)
+ rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */
+ stw r0,_TRAP(r1) /* register set saved */
+ b sys_clone
+
+ .globl ppc_swapcontext
+ppc_swapcontext:
+ SAVE_NVGPRS(r1)
+ lwz r0,_TRAP(r1)
+ rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */
+ stw r0,_TRAP(r1) /* register set saved */
+ b sys_swapcontext
+
+/*
+ * Top-level page fault handling.
+ * This is in assembler because if do_page_fault tells us that
+ * it is a bad kernel page fault, we want to save the non-volatile
+ * registers before calling bad_page_fault.
+ */
+ .globl handle_page_fault
+handle_page_fault:
+ stw r4,_DAR(r1)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ bl do_page_fault
+ cmpwi r3,0
+ beq+ ret_from_except
+ SAVE_NVGPRS(r1)
+ lwz r0,_TRAP(r1)
+ clrrwi r0,r0,1
+ stw r0,_TRAP(r1)
+ mr r5,r3
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ lwz r4,_DAR(r1)
+ bl bad_page_fault
+ b ret_from_except_full
+
+/*
+ * This routine switches between two different tasks. The process
+ * state of one is saved on its kernel stack. Then the state
+ * of the other is restored from its kernel stack. The memory
+ * management hardware is updated to the second process's state.
+ * Finally, we can return to the second process.
+ * On entry, r3 points to the THREAD for the current task, r4
+ * points to the THREAD for the new task.
+ *
+ * This routine is always called with interrupts disabled.
+ *
+ * Note: there are two ways to get to the "going out" portion
+ * of this code; either by coming in via the entry (_switch)
+ * or via "fork" which must set up an environment equivalent
+ * to the "_switch" path. If you change this , you'll have to
+ * change the fork code also.
+ *
+ * The code which creates the new task context is in 'copy_thread'
+ * in arch/ppc/kernel/process.c
+ */
+_GLOBAL(_switch)
+ stwu r1,-INT_FRAME_SIZE(r1)
+ mflr r0
+ stw r0,INT_FRAME_SIZE+4(r1)
+ /* r3-r12 are caller saved -- Cort */
+ SAVE_NVGPRS(r1)
+ stw r0,_NIP(r1) /* Return to switch caller */
+ mfmsr r11
+ li r0,MSR_FP /* Disable floating-point */
+#ifdef CONFIG_ALTIVEC
+BEGIN_FTR_SECTION
+ oris r0,r0,MSR_VEC@h /* Disable altivec */
+ mfspr r12,SPRN_VRSAVE /* save vrsave register value */
+ stw r12,THREAD+THREAD_VRSAVE(r2)
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+ oris r0,r0,MSR_SPE@h /* Disable SPE */
+ mfspr r12,SPRN_SPEFSCR /* save spefscr register value */
+ stw r12,THREAD+THREAD_SPEFSCR(r2)
+#endif /* CONFIG_SPE */
+ and. r0,r0,r11 /* FP or altivec or SPE enabled? */
+ beq+ 1f
+ andc r11,r11,r0
+ MTMSRD(r11)
+ isync
+1: stw r11,_MSR(r1)
+ mfcr r10
+ stw r10,_CCR(r1)
+ stw r1,KSP(r3) /* Set old stack pointer */
+
+#ifdef CONFIG_SMP
+ /* We need a sync somewhere here to make sure that if the
+ * previous task gets rescheduled on another CPU, it sees all
+ * stores it has performed on this one.
+ */
+ sync
+#endif /* CONFIG_SMP */
+
+ tophys(r0,r4)
+ CLR_TOP32(r0)
+ mtspr SPRN_SPRG3,r0 /* Update current THREAD phys addr */
+ lwz r1,KSP(r4) /* Load new stack pointer */
+
+ /* save the old current 'last' for return value */
+ mr r3,r2
+ addi r2,r4,-THREAD /* Update current */
+
+#ifdef CONFIG_ALTIVEC
+BEGIN_FTR_SECTION
+ lwz r0,THREAD+THREAD_VRSAVE(r2)
+ mtspr SPRN_VRSAVE,r0 /* if G4, restore VRSAVE reg */
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+ lwz r0,THREAD+THREAD_SPEFSCR(r2)
+ mtspr SPRN_SPEFSCR,r0 /* restore SPEFSCR reg */
+#endif /* CONFIG_SPE */
+
+ lwz r0,_CCR(r1)
+ mtcrf 0xFF,r0
+ /* r3-r12 are destroyed -- Cort */
+ REST_NVGPRS(r1)
+
+ lwz r4,_NIP(r1) /* Return to _switch caller in new task */
+ mtlr r4
+ addi r1,r1,INT_FRAME_SIZE
+ blr
+
+ .globl fast_exception_return
+fast_exception_return:
+#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
+ andi. r10,r9,MSR_RI /* check for recoverable interrupt */
+ beq 1f /* if not, we've got problems */
+#endif
+
+2: REST_4GPRS(3, r11)
+ lwz r10,_CCR(r11)
+ REST_GPR(1, r11)
+ mtcr r10
+ lwz r10,_LINK(r11)
+ mtlr r10
+ REST_GPR(10, r11)
+ mtspr SPRN_SRR1,r9
+ mtspr SPRN_SRR0,r12
+ REST_GPR(9, r11)
+ REST_GPR(12, r11)
+ lwz r11,GPR11(r11)
+ SYNC
+ RFI
+
+#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
+/* check if the exception happened in a restartable section */
+1: lis r3,exc_exit_restart_end@ha
+ addi r3,r3,exc_exit_restart_end@l
+ cmplw r12,r3
+ bge 3f
+ lis r4,exc_exit_restart@ha
+ addi r4,r4,exc_exit_restart@l
+ cmplw r12,r4
+ blt 3f
+ lis r3,fee_restarts@ha
+ tophys(r3,r3)
+ lwz r5,fee_restarts@l(r3)
+ addi r5,r5,1
+ stw r5,fee_restarts@l(r3)
+ mr r12,r4 /* restart at exc_exit_restart */
+ b 2b
+
+ .comm fee_restarts,4
+
+/* aargh, a nonrecoverable interrupt, panic */
+/* aargh, we don't know which trap this is */
+/* but the 601 doesn't implement the RI bit, so assume it's OK */
+3:
+BEGIN_FTR_SECTION
+ b 2b
+END_FTR_SECTION_IFSET(CPU_FTR_601)
+ li r10,-1
+ stw r10,_TRAP(r11)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ lis r10,MSR_KERNEL@h
+ ori r10,r10,MSR_KERNEL@l
+ bl transfer_to_handler_full
+ .long nonrecoverable_exception
+ .long ret_from_except
+#endif
+
+ .globl sigreturn_exit
+sigreturn_exit:
+ subi r1,r3,STACK_FRAME_OVERHEAD
+ rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
+ lwz r9,TI_FLAGS(r12)
+ andi. r0,r9,_TIF_SYSCALL_T_OR_A
+ beq+ ret_from_except_full
+ bl do_syscall_trace_leave
+ /* fall through */
+
+ .globl ret_from_except_full
+ret_from_except_full:
+ REST_NVGPRS(r1)
+ /* fall through */
+
+ .globl ret_from_except
+ret_from_except:
+ /* Hard-disable interrupts so that current_thread_info()->flags
+ * can't change between when we test it and when we return
+ * from the interrupt. */
+ LOAD_MSR_KERNEL(r10,MSR_KERNEL)
+ SYNC /* Some chip revs have problems here... */
+ MTMSRD(r10) /* disable interrupts */
+
+ lwz r3,_MSR(r1) /* Returning to user mode? */
+ andi. r0,r3,MSR_PR
+ beq resume_kernel
+
+user_exc_return: /* r10 contains MSR_KERNEL here */
+ /* Check current_thread_info()->flags */
+ rlwinm r9,r1,0,0,(31-THREAD_SHIFT)
+ lwz r9,TI_FLAGS(r9)
+ andi. r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED)
+ bne do_work
+
+restore_user:
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+ /* Check whether this process has its own DBCR0 value. The single
+ step bit tells us that dbcr0 should be loaded. */
+ lwz r0,THREAD+THREAD_DBCR0(r2)
+ andis. r10,r0,DBCR0_IC@h
+ bnel- load_dbcr0
+#endif
+
+#ifdef CONFIG_PREEMPT
+ b restore
+
+/* N.B. the only way to get here is from the beq following ret_from_except. */
+resume_kernel:
+ /* check current_thread_info->preempt_count */
+ rlwinm r9,r1,0,0,(31-THREAD_SHIFT)
+ lwz r0,TI_PREEMPT(r9)
+ cmpwi 0,r0,0 /* if non-zero, just restore regs and return */
+ bne restore
+ lwz r0,TI_FLAGS(r9)
+ andi. r0,r0,_TIF_NEED_RESCHED
+ beq+ restore
+ andi. r0,r3,MSR_EE /* interrupts off? */
+ beq restore /* don't schedule if so */
+1: bl preempt_schedule_irq
+ rlwinm r9,r1,0,0,(31-THREAD_SHIFT)
+ lwz r3,TI_FLAGS(r9)
+ andi. r0,r3,_TIF_NEED_RESCHED
+ bne- 1b
+#else
+resume_kernel:
+#endif /* CONFIG_PREEMPT */
+
+ /* interrupts are hard-disabled at this point */
+restore:
+ lwz r0,GPR0(r1)
+ lwz r2,GPR2(r1)
+ REST_4GPRS(3, r1)
+ REST_2GPRS(7, r1)
+
+ lwz r10,_XER(r1)
+ lwz r11,_CTR(r1)
+ mtspr SPRN_XER,r10
+ mtctr r11
+
+ PPC405_ERR77(0,r1)
+ stwcx. r0,0,r1 /* to clear the reservation */
+
+#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
+ lwz r9,_MSR(r1)
+ andi. r10,r9,MSR_RI /* check if this exception occurred */
+ beql nonrecoverable /* at a bad place (MSR:RI = 0) */
+
+ lwz r10,_CCR(r1)
+ lwz r11,_LINK(r1)
+ mtcrf 0xFF,r10
+ mtlr r11
+
+ /*
+ * Once we put values in SRR0 and SRR1, we are in a state
+ * where exceptions are not recoverable, since taking an
+ * exception will trash SRR0 and SRR1. Therefore we clear the
+ * MSR:RI bit to indicate this. If we do take an exception,
+ * we can't return to the point of the exception but we
+ * can restart the exception exit path at the label
+ * exc_exit_restart below. -- paulus
+ */
+ LOAD_MSR_KERNEL(r10,MSR_KERNEL & ~MSR_RI)
+ SYNC
+ MTMSRD(r10) /* clear the RI bit */
+ .globl exc_exit_restart
+exc_exit_restart:
+ lwz r9,_MSR(r1)
+ lwz r12,_NIP(r1)
+ FIX_SRR1(r9,r10)
+ mtspr SPRN_SRR0,r12
+ mtspr SPRN_SRR1,r9
+ REST_4GPRS(9, r1)
+ lwz r1,GPR1(r1)
+ .globl exc_exit_restart_end
+exc_exit_restart_end:
+ SYNC
+ RFI
+
+#else /* !(CONFIG_4xx || CONFIG_BOOKE) */
+ /*
+ * This is a bit different on 4xx/Book-E because it doesn't have
+ * the RI bit in the MSR.
+ * The TLB miss handler checks if we have interrupted
+ * the exception exit path and restarts it if so
+ * (well maybe one day it will... :).
+ */
+ lwz r11,_LINK(r1)
+ mtlr r11
+ lwz r10,_CCR(r1)
+ mtcrf 0xff,r10
+ REST_2GPRS(9, r1)
+ .globl exc_exit_restart
+exc_exit_restart:
+ lwz r11,_NIP(r1)
+ lwz r12,_MSR(r1)
+exc_exit_start:
+ mtspr SPRN_SRR0,r11
+ mtspr SPRN_SRR1,r12
+ REST_2GPRS(11, r1)
+ lwz r1,GPR1(r1)
+ .globl exc_exit_restart_end
+exc_exit_restart_end:
+ PPC405_ERR77_SYNC
+ rfi
+ b . /* prevent prefetch past rfi */
+
+/*
+ * Returning from a critical interrupt in user mode doesn't need
+ * to be any different from a normal exception. For a critical
+ * interrupt in the kernel, we just return (without checking for
+ * preemption) since the interrupt may have happened at some crucial
+ * place (e.g. inside the TLB miss handler), and because we will be
+ * running with r1 pointing into critical_stack, not the current
+ * process's kernel stack (and therefore current_thread_info() will
+ * give the wrong answer).
+ * We have to restore various SPRs that may have been in use at the
+ * time of the critical interrupt.
+ *
+ */
+#ifdef CONFIG_40x
+#define PPC_40x_TURN_OFF_MSR_DR \
+ /* avoid any possible TLB misses here by turning off MSR.DR, we \
+ * assume the instructions here are mapped by a pinned TLB entry */ \
+ li r10,MSR_IR; \
+ mtmsr r10; \
+ isync; \
+ tophys(r1, r1);
+#else
+#define PPC_40x_TURN_OFF_MSR_DR
+#endif
+
+#define RET_FROM_EXC_LEVEL(exc_lvl_srr0, exc_lvl_srr1, exc_lvl_rfi) \
+ REST_NVGPRS(r1); \
+ lwz r3,_MSR(r1); \
+ andi. r3,r3,MSR_PR; \
+ LOAD_MSR_KERNEL(r10,MSR_KERNEL); \
+ bne user_exc_return; \
+ lwz r0,GPR0(r1); \
+ lwz r2,GPR2(r1); \
+ REST_4GPRS(3, r1); \
+ REST_2GPRS(7, r1); \
+ lwz r10,_XER(r1); \
+ lwz r11,_CTR(r1); \
+ mtspr SPRN_XER,r10; \
+ mtctr r11; \
+ PPC405_ERR77(0,r1); \
+ stwcx. r0,0,r1; /* to clear the reservation */ \
+ lwz r11,_LINK(r1); \
+ mtlr r11; \
+ lwz r10,_CCR(r1); \
+ mtcrf 0xff,r10; \
+ PPC_40x_TURN_OFF_MSR_DR; \
+ lwz r9,_DEAR(r1); \
+ lwz r10,_ESR(r1); \
+ mtspr SPRN_DEAR,r9; \
+ mtspr SPRN_ESR,r10; \
+ lwz r11,_NIP(r1); \
+ lwz r12,_MSR(r1); \
+ mtspr exc_lvl_srr0,r11; \
+ mtspr exc_lvl_srr1,r12; \
+ lwz r9,GPR9(r1); \
+ lwz r12,GPR12(r1); \
+ lwz r10,GPR10(r1); \
+ lwz r11,GPR11(r1); \
+ lwz r1,GPR1(r1); \
+ PPC405_ERR77_SYNC; \
+ exc_lvl_rfi; \
+ b .; /* prevent prefetch past exc_lvl_rfi */
+
+ .globl ret_from_crit_exc
+ret_from_crit_exc:
+ RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, RFCI)
+
+#ifdef CONFIG_BOOKE
+ .globl ret_from_debug_exc
+ret_from_debug_exc:
+ RET_FROM_EXC_LEVEL(SPRN_DSRR0, SPRN_DSRR1, RFDI)
+
+ .globl ret_from_mcheck_exc
+ret_from_mcheck_exc:
+ RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, RFMCI)
+#endif /* CONFIG_BOOKE */
+
+/*
+ * Load the DBCR0 value for a task that is being ptraced,
+ * having first saved away the global DBCR0. Note that r0
+ * has the dbcr0 value to set upon entry to this.
+ */
+load_dbcr0:
+ mfmsr r10 /* first disable debug exceptions */
+ rlwinm r10,r10,0,~MSR_DE
+ mtmsr r10
+ isync
+ mfspr r10,SPRN_DBCR0
+ lis r11,global_dbcr0@ha
+ addi r11,r11,global_dbcr0@l
+ stw r10,0(r11)
+ mtspr SPRN_DBCR0,r0
+ lwz r10,4(r11)
+ addi r10,r10,1
+ stw r10,4(r11)
+ li r11,-1
+ mtspr SPRN_DBSR,r11 /* clear all pending debug events */
+ blr
+
+ .comm global_dbcr0,8
+#endif /* !(CONFIG_4xx || CONFIG_BOOKE) */
+
+do_work: /* r10 contains MSR_KERNEL here */
+ andi. r0,r9,_TIF_NEED_RESCHED
+ beq do_user_signal
+
+do_resched: /* r10 contains MSR_KERNEL here */
+ ori r10,r10,MSR_EE
+ SYNC
+ MTMSRD(r10) /* hard-enable interrupts */
+ bl schedule
+recheck:
+ LOAD_MSR_KERNEL(r10,MSR_KERNEL)
+ SYNC
+ MTMSRD(r10) /* disable interrupts */
+ rlwinm r9,r1,0,0,(31-THREAD_SHIFT)
+ lwz r9,TI_FLAGS(r9)
+ andi. r0,r9,_TIF_NEED_RESCHED
+ bne- do_resched
+ andi. r0,r9,_TIF_SIGPENDING
+ beq restore_user
+do_user_signal: /* r10 contains MSR_KERNEL here */
+ ori r10,r10,MSR_EE
+ SYNC
+ MTMSRD(r10) /* hard-enable interrupts */
+ /* save r13-r31 in the exception frame, if not already done */
+ lwz r3,_TRAP(r1)
+ andi. r0,r3,1
+ beq 2f
+ SAVE_NVGPRS(r1)
+ rlwinm r3,r3,0,0,30
+ stw r3,_TRAP(r1)
+2: li r3,0
+ addi r4,r1,STACK_FRAME_OVERHEAD
+ bl do_signal
+ REST_NVGPRS(r1)
+ b recheck
+
+/*
+ * We come here when we are at the end of handling an exception
+ * that occurred at a place where taking an exception will lose
+ * state information, such as the contents of SRR0 and SRR1.
+ */
+nonrecoverable:
+ lis r10,exc_exit_restart_end@ha
+ addi r10,r10,exc_exit_restart_end@l
+ cmplw r12,r10
+ bge 3f
+ lis r11,exc_exit_restart@ha
+ addi r11,r11,exc_exit_restart@l
+ cmplw r12,r11
+ blt 3f
+ lis r10,ee_restarts@ha
+ lwz r12,ee_restarts@l(r10)
+ addi r12,r12,1
+ stw r12,ee_restarts@l(r10)
+ mr r12,r11 /* restart at exc_exit_restart */
+ blr
+3: /* OK, we can't recover, kill this process */
+ /* but the 601 doesn't implement the RI bit, so assume it's OK */
+BEGIN_FTR_SECTION
+ blr
+END_FTR_SECTION_IFSET(CPU_FTR_601)
+ lwz r3,_TRAP(r1)
+ andi. r0,r3,1
+ beq 4f
+ SAVE_NVGPRS(r1)
+ rlwinm r3,r3,0,0,30
+ stw r3,_TRAP(r1)
+4: addi r3,r1,STACK_FRAME_OVERHEAD
+ bl nonrecoverable_exception
+ /* shouldn't return */
+ b 4b
+
+ .comm ee_restarts,4
+
+/*
+ * PROM code for specific machines follows. Put it
+ * here so it's easy to add arch-specific sections later.
+ * -- Cort
+ */
+#ifdef CONFIG_PPC_RTAS
+/*
+ * On CHRP, the Run-Time Abstraction Services (RTAS) have to be
+ * called with the MMU off.
+ */
+_GLOBAL(enter_rtas)
+ stwu r1,-INT_FRAME_SIZE(r1)
+ mflr r0
+ stw r0,INT_FRAME_SIZE+4(r1)
+ LOADADDR(r4, rtas)
+ lis r6,1f@ha /* physical return address for rtas */
+ addi r6,r6,1f@l
+ tophys(r6,r6)
+ tophys(r7,r1)
+ lwz r8,RTASENTRY(r4)
+ lwz r4,RTASBASE(r4)
+ mfmsr r9
+ stw r9,8(r1)
+ LOAD_MSR_KERNEL(r0,MSR_KERNEL)
+ SYNC /* disable interrupts so SRR0/1 */
+ MTMSRD(r0) /* don't get trashed */
+ li r9,MSR_KERNEL & ~(MSR_IR|MSR_DR)
+ mtlr r6
+ mtspr SPRN_SPRG2,r7
+ mtspr SPRN_SRR0,r8
+ mtspr SPRN_SRR1,r9
+ RFI
+1: tophys(r9,r1)
+ lwz r8,INT_FRAME_SIZE+4(r9) /* get return address */
+ lwz r9,8(r9) /* original msr value */
+ FIX_SRR1(r9,r0)
+ addi r1,r1,INT_FRAME_SIZE
+ li r0,0
+ mtspr SPRN_SPRG2,r0
+ mtspr SPRN_SRR0,r8
+ mtspr SPRN_SRR1,r9
+ RFI /* return to caller */
+
+ .globl machine_check_in_rtas
+machine_check_in_rtas:
+ twi 31,0,0
+ /* XXX load up BATs and panic */
+
+#endif /* CONFIG_PPC_RTAS */
diff --git a/arch/ppc64/kernel/entry.S b/arch/powerpc/kernel/entry_64.S
index e8c0bbf4d000..984a10630714 100644
--- a/arch/ppc64/kernel/entry.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -42,9 +42,6 @@
.SYS_CALL_TABLE:
.tc .sys_call_table[TC],.sys_call_table
-.SYS_CALL_TABLE32:
- .tc .sys_call_table32[TC],.sys_call_table32
-
/* This value is used to mark exception frames on the stack. */
exception_marker:
.tc ID_72656773_68657265[TC],0x7265677368657265
@@ -133,7 +130,7 @@ system_call: /* label this so stack traces look sane */
ld r11,.SYS_CALL_TABLE@toc(2)
andi. r10,r10,_TIF_32BIT
beq 15f
- ld r11,.SYS_CALL_TABLE32@toc(2)
+ addi r11,r11,8 /* use 32-bit syscall entries */
clrldi r3,r3,32
clrldi r4,r4,32
clrldi r5,r5,32
@@ -141,7 +138,7 @@ system_call: /* label this so stack traces look sane */
clrldi r7,r7,32
clrldi r8,r8,32
15:
- slwi r0,r0,3
+ slwi r0,r0,4
ldx r10,r11,r0 /* Fetch system call handler [ptr] */
mtctr r10
bctrl /* Call handler */
@@ -191,8 +188,8 @@ syscall_exit_trace_cont:
ld r1,GPR1(r1)
mtlr r4
mtcr r5
- mtspr SRR0,r7
- mtspr SRR1,r8
+ mtspr SPRN_SRR0,r7
+ mtspr SPRN_SRR1,r8
rfid
b . /* prevent speculative execution */
@@ -265,7 +262,7 @@ _GLOBAL(save_nvgprs)
*/
_GLOBAL(ppc32_sigsuspend)
bl .save_nvgprs
- bl .sys32_sigsuspend
+ bl .compat_sys_sigsuspend
b 70f
_GLOBAL(ppc64_rt_sigsuspend)
@@ -275,7 +272,7 @@ _GLOBAL(ppc64_rt_sigsuspend)
_GLOBAL(ppc32_rt_sigsuspend)
bl .save_nvgprs
- bl .sys32_rt_sigsuspend
+ bl .compat_sys_rt_sigsuspend
70: cmpdi 0,r3,0
/* If it returned an error, we need to return via syscall_exit to set
the SO bit in cr0 and potentially stop for ptrace. */
@@ -310,7 +307,7 @@ _GLOBAL(ppc_clone)
_GLOBAL(ppc32_swapcontext)
bl .save_nvgprs
- bl .sys32_swapcontext
+ bl .compat_sys_swapcontext
b 80f
_GLOBAL(ppc64_swapcontext)
@@ -319,11 +316,11 @@ _GLOBAL(ppc64_swapcontext)
b 80f
_GLOBAL(ppc32_sigreturn)
- bl .sys32_sigreturn
+ bl .compat_sys_sigreturn
b 80f
_GLOBAL(ppc32_rt_sigreturn)
- bl .sys32_rt_sigreturn
+ bl .compat_sys_rt_sigreturn
b 80f
_GLOBAL(ppc64_rt_sigreturn)
@@ -531,7 +528,7 @@ restore:
mtctr r3
mtlr r0
ld r3,_XER(r1)
- mtspr XER,r3
+ mtspr SPRN_XER,r3
REST_8GPRS(5, r1)
@@ -543,12 +540,12 @@ restore:
mtmsrd r0,1
ld r0,_MSR(r1)
- mtspr SRR1,r0
+ mtspr SPRN_SRR1,r0
ld r2,_CCR(r1)
mtcrf 0xFF,r2
ld r2,_NIP(r1)
- mtspr SRR0,r2
+ mtspr SPRN_SRR0,r2
ld r0,GPR0(r1)
ld r2,GPR2(r1)
@@ -643,7 +640,7 @@ _GLOBAL(enter_rtas)
std r4,_CCR(r1)
mfctr r5
std r5,_CTR(r1)
- mfspr r6,XER
+ mfspr r6,SPRN_XER
std r6,_XER(r1)
mfdar r7
std r7,_DAR(r1)
@@ -697,14 +694,14 @@ _GLOBAL(enter_rtas)
ld r5,RTASENTRY(r4) /* get the rtas->entry value */
ld r4,RTASBASE(r4) /* get the rtas->base value */
- mtspr SRR0,r5
- mtspr SRR1,r6
+ mtspr SPRN_SRR0,r5
+ mtspr SPRN_SRR1,r6
rfid
b . /* prevent speculative execution */
_STATIC(rtas_return_loc)
/* relocation is off at this point */
- mfspr r4,SPRG3 /* Get PACA */
+ mfspr r4,SPRN_SPRG3 /* Get PACA */
SET_REG_TO_CONST(r5, KERNELBASE)
sub r4,r4,r5 /* RELOC the PACA base pointer */
@@ -718,8 +715,8 @@ _STATIC(rtas_return_loc)
LOADADDR(r3,.rtas_restore_regs)
ld r4,PACASAVEDMSR(r4) /* Restore our MSR */
- mtspr SRR0,r3
- mtspr SRR1,r4
+ mtspr SPRN_SRR0,r3
+ mtspr SPRN_SRR1,r4
rfid
b . /* prevent speculative execution */
@@ -730,14 +727,14 @@ _STATIC(rtas_restore_regs)
REST_8GPRS(14, r1) /* Restore the non-volatiles */
REST_10GPRS(22, r1) /* ditto */
- mfspr r13,SPRG3
+ mfspr r13,SPRN_SPRG3
ld r4,_CCR(r1)
mtcr r4
ld r5,_CTR(r1)
mtctr r5
ld r6,_XER(r1)
- mtspr XER,r6
+ mtspr SPRN_XER,r6
ld r7,_DAR(r1)
mtdar r7
ld r8,_DSISR(r1)
@@ -774,7 +771,7 @@ _GLOBAL(enter_prom)
std r4,_CCR(r1)
mfctr r5
std r5,_CTR(r1)
- mfspr r6,XER
+ mfspr r6,SPRN_XER
std r6,_XER(r1)
mfdar r7
std r7,_DAR(r1)
@@ -827,7 +824,7 @@ _GLOBAL(enter_prom)
ld r5,_CTR(r1)
mtctr r5
ld r6,_XER(r1)
- mtspr XER,r6
+ mtspr SPRN_XER,r6
ld r7,_DAR(r1)
mtdar r7
ld r8,_DSISR(r1)
diff --git a/arch/ppc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S
index 665d7d34304c..4d6001fa1cf2 100644
--- a/arch/ppc/kernel/fpu.S
+++ b/arch/powerpc/kernel/fpu.S
@@ -10,7 +10,7 @@
*/
#include <linux/config.h>
-#include <asm/processor.h>
+#include <asm/reg.h>
#include <asm/page.h>
#include <asm/mmu.h>
#include <asm/pgtable.h>
@@ -27,13 +27,9 @@
* Load up this task's FP registers from its thread_struct,
* enable the FPU for the current task and return to the task.
*/
- .globl load_up_fpu
-load_up_fpu:
+_GLOBAL(load_up_fpu)
mfmsr r5
ori r5,r5,MSR_FP
-#ifdef CONFIG_PPC64BRIDGE
- clrldi r5,r5,1 /* turn off 64-bit mode */
-#endif /* CONFIG_PPC64BRIDGE */
SYNC
MTMSRD(r5) /* enable use of fpu now */
isync
@@ -43,67 +39,57 @@ load_up_fpu:
* to another. Instead we call giveup_fpu in switch_to.
*/
#ifndef CONFIG_SMP
- tophys(r6,0) /* get __pa constant */
- addis r3,r6,last_task_used_math@ha
- lwz r4,last_task_used_math@l(r3)
- cmpwi 0,r4,0
+ LOADBASE(r3, last_task_used_math)
+ toreal(r3)
+ LDL r4,OFF(last_task_used_math)(r3)
+ CMPI 0,r4,0
beq 1f
- add r4,r4,r6
+ toreal(r4)
addi r4,r4,THREAD /* want last_task_used_math->thread */
SAVE_32FPRS(0, r4)
mffs fr0
- stfd fr0,THREAD_FPSCR-4(r4)
- lwz r5,PT_REGS(r4)
- add r5,r5,r6
- lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+ stfd fr0,THREAD_FPSCR(r4)
+ LDL r5,PT_REGS(r4)
+ toreal(r5)
+ LDL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
li r10,MSR_FP|MSR_FE0|MSR_FE1
andc r4,r4,r10 /* disable FP for previous task */
- stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+ STL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1:
#endif /* CONFIG_SMP */
/* enable use of FP after return */
+#ifdef CONFIG_PPC32
mfspr r5,SPRN_SPRG3 /* current task's THREAD (phys) */
lwz r4,THREAD_FPEXC_MODE(r5)
ori r9,r9,MSR_FP /* enable FP for current */
or r9,r9,r4
- lfd fr0,THREAD_FPSCR-4(r5)
+#else
+ ld r4,PACACURRENT(r13)
+ addi r5,r4,THREAD /* Get THREAD */
+ ld r4,THREAD_FPEXC_MODE(r5)
+ ori r12,r12,MSR_FP
+ or r12,r12,r4
+ std r12,_MSR(r1)
+#endif
+ lfd fr0,THREAD_FPSCR(r5)
mtfsf 0xff,fr0
REST_32FPRS(0, r5)
#ifndef CONFIG_SMP
subi r4,r5,THREAD
- sub r4,r4,r6
- stw r4,last_task_used_math@l(r3)
+ fromreal(r4)
+ STL r4,OFF(last_task_used_math)(r3)
#endif /* CONFIG_SMP */
/* restore registers and return */
/* we haven't used ctr or xer or lr */
b fast_exception_return
/*
- * FP unavailable trap from kernel - print a message, but let
- * the task use FP in the kernel until it returns to user mode.
- */
- .globl KernelFP
-KernelFP:
- lwz r3,_MSR(r1)
- ori r3,r3,MSR_FP
- stw r3,_MSR(r1) /* enable use of FP after return */
- lis r3,86f@h
- ori r3,r3,86f@l
- mr r4,r2 /* current */
- lwz r5,_NIP(r1)
- bl printk
- b ret_from_except
-86: .string "floating point used in kernel (task=%p, pc=%x)\n"
- .align 4,0
-
-/*
* giveup_fpu(tsk)
* Disable FP for the task given as the argument,
* and save the floating-point registers in its thread_struct.
* Enables the FPU for use in the kernel on return.
*/
- .globl giveup_fpu
-giveup_fpu:
+_GLOBAL(giveup_fpu)
mfmsr r5
ori r5,r5,MSR_FP
SYNC_601
@@ -111,23 +97,48 @@ giveup_fpu:
MTMSRD(r5) /* enable use of fpu now */
SYNC_601
isync
- cmpwi 0,r3,0
+ CMPI 0,r3,0
beqlr- /* if no previous owner, done */
addi r3,r3,THREAD /* want THREAD of task */
- lwz r5,PT_REGS(r3)
- cmpwi 0,r5,0
+ LDL r5,PT_REGS(r3)
+ CMPI 0,r5,0
SAVE_32FPRS(0, r3)
mffs fr0
- stfd fr0,THREAD_FPSCR-4(r3)
+ stfd fr0,THREAD_FPSCR(r3)
beq 1f
- lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+ LDL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
li r3,MSR_FP|MSR_FE0|MSR_FE1
andc r4,r4,r3 /* disable FP for previous task */
- stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+ STL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1:
#ifndef CONFIG_SMP
li r5,0
- lis r4,last_task_used_math@ha
- stw r5,last_task_used_math@l(r4)
+ LOADBASE(r4,last_task_used_math)
+ STL r5,OFF(last_task_used_math)(r4)
#endif /* CONFIG_SMP */
blr
+
+/*
+ * These are used in the alignment trap handler when emulating
+ * single-precision loads and stores.
+ * We restore and save the fpscr so the task gets the same result
+ * and exceptions as if the cpu had performed the load or store.
+ */
+
+_GLOBAL(cvt_fd)
+ lfd 0,THREAD_FPSCR(r5) /* load up fpscr value */
+ mtfsf 0xff,0
+ lfs 0,0(r3)
+ stfd 0,0(r4)
+ mffs 0
+ stfd 0,THREAD_FPSCR(r5) /* save new fpscr value */
+ blr
+
+_GLOBAL(cvt_df)
+ lfd 0,THREAD_FPSCR(r5) /* load up fpscr value */
+ mtfsf 0xff,0
+ lfd 0,0(r3)
+ stfs 0,0(r4)
+ mffs 0
+ stfd 0,THREAD_FPSCR(r5) /* save new fpscr value */
+ blr
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S
new file mode 100644
index 000000000000..b102e3a2415e
--- /dev/null
+++ b/arch/powerpc/kernel/head_32.S
@@ -0,0 +1,1381 @@
+/*
+ * PowerPC version
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
+ * Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
+ * Adapted for Power Macintosh by Paul Mackerras.
+ * Low-level exception handlers and MMU support
+ * rewritten by Paul Mackerras.
+ * Copyright (C) 1996 Paul Mackerras.
+ * MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek@jlc.net).
+ * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ * This file contains the low-level support and setup for the
+ * PowerPC platform, including trap and interrupt dispatch.
+ * (The PPC 8xx embedded CPUs use head_8xx.S instead.)
+ *
+ * This program is free software; you can redistribute 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/config.h>
+#include <asm/reg.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/cputable.h>
+#include <asm/cache.h>
+#include <asm/thread_info.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+
+#ifdef CONFIG_APUS
+#include <asm/amigappc.h>
+#endif
+
+/* 601 only have IBAT; cr0.eq is set on 601 when using this macro */
+#define LOAD_BAT(n, reg, RA, RB) \
+ /* see the comment for clear_bats() -- Cort */ \
+ li RA,0; \
+ mtspr SPRN_IBAT##n##U,RA; \
+ mtspr SPRN_DBAT##n##U,RA; \
+ lwz RA,(n*16)+0(reg); \
+ lwz RB,(n*16)+4(reg); \
+ mtspr SPRN_IBAT##n##U,RA; \
+ mtspr SPRN_IBAT##n##L,RB; \
+ beq 1f; \
+ lwz RA,(n*16)+8(reg); \
+ lwz RB,(n*16)+12(reg); \
+ mtspr SPRN_DBAT##n##U,RA; \
+ mtspr SPRN_DBAT##n##L,RB; \
+1:
+
+ .text
+ .stabs "arch/powerpc/kernel/",N_SO,0,0,0f
+ .stabs "head_32.S",N_SO,0,0,0f
+0:
+ .globl _stext
+_stext:
+
+/*
+ * _start is defined this way because the XCOFF loader in the OpenFirmware
+ * on the powermac expects the entry point to be a procedure descriptor.
+ */
+ .text
+ .globl _start
+_start:
+ /*
+ * These are here for legacy reasons, the kernel used to
+ * need to look like a coff function entry for the pmac
+ * but we're always started by some kind of bootloader now.
+ * -- Cort
+ */
+ nop /* used by __secondary_hold on prep (mtx) and chrp smp */
+ nop /* used by __secondary_hold on prep (mtx) and chrp smp */
+ nop
+
+/* PMAC
+ * Enter here with the kernel text, data and bss loaded starting at
+ * 0, running with virtual == physical mapping.
+ * r5 points to the prom entry point (the client interface handler
+ * address). Address translation is turned on, with the prom
+ * managing the hash table. Interrupts are disabled. The stack
+ * pointer (r1) points to just below the end of the half-meg region
+ * from 0x380000 - 0x400000, which is mapped in already.
+ *
+ * If we are booted from MacOS via BootX, we enter with the kernel
+ * image loaded somewhere, and the following values in registers:
+ * r3: 'BooX' (0x426f6f58)
+ * r4: virtual address of boot_infos_t
+ * r5: 0
+ *
+ * APUS
+ * r3: 'APUS'
+ * r4: physical address of memory base
+ * Linux/m68k style BootInfo structure at &_end.
+ *
+ * PREP
+ * This is jumped to on prep systems right after the kernel is relocated
+ * to its proper place in memory by the boot loader. The expected layout
+ * of the regs is:
+ * r3: ptr to residual data
+ * r4: initrd_start or if no initrd then 0
+ * r5: initrd_end - unused if r4 is 0
+ * r6: Start of command line string
+ * r7: End of command line string
+ *
+ * This just gets a minimal mmu environment setup so we can call
+ * start_here() to do the real work.
+ * -- Cort
+ */
+
+ .globl __start
+__start:
+/*
+ * We have to do any OF calls before we map ourselves to KERNELBASE,
+ * because OF may have I/O devices mapped into that area
+ * (particularly on CHRP).
+ */
+ cmpwi 0,r5,0
+ beq 1f
+ bl prom_init
+ trap
+
+1: mr r31,r3 /* save parameters */
+ mr r30,r4
+ li r24,0 /* cpu # */
+
+/*
+ * early_init() does the early machine identification and does
+ * the necessary low-level setup and clears the BSS
+ * -- Cort <cort@fsmlabs.com>
+ */
+ bl early_init
+
+#ifdef CONFIG_APUS
+/* On APUS the __va/__pa constants need to be set to the correct
+ * values before continuing.
+ */
+ mr r4,r30
+ bl fix_mem_constants
+#endif /* CONFIG_APUS */
+
+/* Switch MMU off, clear BATs and flush TLB. At this point, r3 contains
+ * the physical address we are running at, returned by early_init()
+ */
+ bl mmu_off
+__after_mmu_off:
+ bl clear_bats
+ bl flush_tlbs
+
+ bl initial_bats
+
+/*
+ * Call setup_cpu for CPU 0 and initialize 6xx Idle
+ */
+ bl reloc_offset
+ li r24,0 /* cpu# */
+ bl call_setup_cpu /* Call setup_cpu for this CPU */
+#ifdef CONFIG_6xx
+ bl reloc_offset
+ bl init_idle_6xx
+#endif /* CONFIG_6xx */
+
+
+#ifndef CONFIG_APUS
+/*
+ * We need to run with _start at physical address 0.
+ * On CHRP, we are loaded at 0x10000 since OF on CHRP uses
+ * the exception vectors at 0 (and therefore this copy
+ * overwrites OF's exception vectors with our own).
+ * The MMU is off at this point.
+ */
+ bl reloc_offset
+ mr r26,r3
+ addis r4,r3,KERNELBASE@h /* current address of _start */
+ cmpwi 0,r4,0 /* are we already running at 0? */
+ bne relocate_kernel
+#endif /* CONFIG_APUS */
+/*
+ * we now have the 1st 16M of ram mapped with the bats.
+ * prep needs the mmu to be turned on here, but pmac already has it on.
+ * this shouldn't bother the pmac since it just gets turned on again
+ * as we jump to our code at KERNELBASE. -- Cort
+ * Actually no, pmac doesn't have it on any more. BootX enters with MMU
+ * off, and in other cases, we now turn it off before changing BATs above.
+ */
+turn_on_mmu:
+ mfmsr r0
+ ori r0,r0,MSR_DR|MSR_IR
+ mtspr SPRN_SRR1,r0
+ lis r0,start_here@h
+ ori r0,r0,start_here@l
+ mtspr SPRN_SRR0,r0
+ SYNC
+ RFI /* enables MMU */
+
+/*
+ * We need __secondary_hold as a place to hold the other cpus on
+ * an SMP machine, even when we are running a UP kernel.
+ */
+ . = 0xc0 /* for prep bootloader */
+ li r3,1 /* MTX only has 1 cpu */
+ .globl __secondary_hold
+__secondary_hold:
+ /* tell the master we're here */
+ stw r3,__secondary_hold_acknowledge@l(0)
+#ifdef CONFIG_SMP
+100: lwz r4,0(0)
+ /* wait until we're told to start */
+ cmpw 0,r4,r3
+ bne 100b
+ /* our cpu # was at addr 0 - go */
+ mr r24,r3 /* cpu # */
+ b __secondary_start
+#else
+ b .
+#endif /* CONFIG_SMP */
+
+ .globl __secondary_hold_spinloop
+__secondary_hold_spinloop:
+ .long 0
+ .globl __secondary_hold_acknowledge
+__secondary_hold_acknowledge:
+ .long -1
+
+/*
+ * Exception entry code. This code runs with address translation
+ * turned off, i.e. using physical addresses.
+ * We assume sprg3 has the physical address of the current
+ * task's thread_struct.
+ */
+#define EXCEPTION_PROLOG \
+ mtspr SPRN_SPRG0,r10; \
+ mtspr SPRN_SPRG1,r11; \
+ mfcr r10; \
+ EXCEPTION_PROLOG_1; \
+ EXCEPTION_PROLOG_2
+
+#define EXCEPTION_PROLOG_1 \
+ mfspr r11,SPRN_SRR1; /* check whether user or kernel */ \
+ andi. r11,r11,MSR_PR; \
+ tophys(r11,r1); /* use tophys(r1) if kernel */ \
+ beq 1f; \
+ mfspr r11,SPRN_SPRG3; \
+ lwz r11,THREAD_INFO-THREAD(r11); \
+ addi r11,r11,THREAD_SIZE; \
+ tophys(r11,r11); \
+1: subi r11,r11,INT_FRAME_SIZE /* alloc exc. frame */
+
+
+#define EXCEPTION_PROLOG_2 \
+ CLR_TOP32(r11); \
+ stw r10,_CCR(r11); /* save registers */ \
+ stw r12,GPR12(r11); \
+ stw r9,GPR9(r11); \
+ mfspr r10,SPRN_SPRG0; \
+ stw r10,GPR10(r11); \
+ mfspr r12,SPRN_SPRG1; \
+ stw r12,GPR11(r11); \
+ mflr r10; \
+ stw r10,_LINK(r11); \
+ mfspr r12,SPRN_SRR0; \
+ mfspr r9,SPRN_SRR1; \
+ stw r1,GPR1(r11); \
+ stw r1,0(r11); \
+ tovirt(r1,r11); /* set new kernel sp */ \
+ li r10,MSR_KERNEL & ~(MSR_IR|MSR_DR); /* can take exceptions */ \
+ MTMSRD(r10); /* (except for mach check in rtas) */ \
+ stw r0,GPR0(r11); \
+ lis r10,0x7265; /* put exception frame marker */ \
+ addi r10,r10,0x6773; \
+ stw r10,8(r11); \
+ SAVE_4GPRS(3, r11); \
+ SAVE_2GPRS(7, r11)
+
+/*
+ * Note: code which follows this uses cr0.eq (set if from kernel),
+ * r11, r12 (SRR0), and r9 (SRR1).
+ *
+ * Note2: once we have set r1 we are in a position to take exceptions
+ * again, and we could thus set MSR:RI at that point.
+ */
+
+/*
+ * Exception vectors.
+ */
+#define EXCEPTION(n, label, hdlr, xfer) \
+ . = n; \
+label: \
+ EXCEPTION_PROLOG; \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ xfer(n, hdlr)
+
+#define EXC_XFER_TEMPLATE(n, hdlr, trap, copyee, tfer, ret) \
+ li r10,trap; \
+ stw r10,_TRAP(r11); \
+ li r10,MSR_KERNEL; \
+ copyee(r10, r9); \
+ bl tfer; \
+i##n: \
+ .long hdlr; \
+ .long ret
+
+#define COPY_EE(d, s) rlwimi d,s,0,16,16
+#define NOCOPY(d, s)
+
+#define EXC_XFER_STD(n, hdlr) \
+ EXC_XFER_TEMPLATE(n, hdlr, n, NOCOPY, transfer_to_handler_full, \
+ ret_from_except_full)
+
+#define EXC_XFER_LITE(n, hdlr) \
+ EXC_XFER_TEMPLATE(n, hdlr, n+1, NOCOPY, transfer_to_handler, \
+ ret_from_except)
+
+#define EXC_XFER_EE(n, hdlr) \
+ EXC_XFER_TEMPLATE(n, hdlr, n, COPY_EE, transfer_to_handler_full, \
+ ret_from_except_full)
+
+#define EXC_XFER_EE_LITE(n, hdlr) \
+ EXC_XFER_TEMPLATE(n, hdlr, n+1, COPY_EE, transfer_to_handler, \
+ ret_from_except)
+
+/* System reset */
+/* core99 pmac starts the seconary here by changing the vector, and
+ putting it back to what it was (unknown_exception) when done. */
+#if defined(CONFIG_GEMINI) && defined(CONFIG_SMP)
+ . = 0x100
+ b __secondary_start_gemini
+#else
+ EXCEPTION(0x100, Reset, unknown_exception, EXC_XFER_STD)
+#endif
+
+/* Machine check */
+/*
+ * On CHRP, this is complicated by the fact that we could get a
+ * machine check inside RTAS, and we have no guarantee that certain
+ * critical registers will have the values we expect. The set of
+ * registers that might have bad values includes all the GPRs
+ * and all the BATs. We indicate that we are in RTAS by putting
+ * a non-zero value, the address of the exception frame to use,
+ * in SPRG2. The machine check handler checks SPRG2 and uses its
+ * value if it is non-zero. If we ever needed to free up SPRG2,
+ * we could use a field in the thread_info or thread_struct instead.
+ * (Other exception handlers assume that r1 is a valid kernel stack
+ * pointer when we take an exception from supervisor mode.)
+ * -- paulus.
+ */
+ . = 0x200
+ mtspr SPRN_SPRG0,r10
+ mtspr SPRN_SPRG1,r11
+ mfcr r10
+#ifdef CONFIG_PPC_CHRP
+ mfspr r11,SPRN_SPRG2
+ cmpwi 0,r11,0
+ bne 7f
+#endif /* CONFIG_PPC_CHRP */
+ EXCEPTION_PROLOG_1
+7: EXCEPTION_PROLOG_2
+ addi r3,r1,STACK_FRAME_OVERHEAD
+#ifdef CONFIG_PPC_CHRP
+ mfspr r4,SPRN_SPRG2
+ cmpwi cr1,r4,0
+ bne cr1,1f
+#endif
+ EXC_XFER_STD(0x200, machine_check_exception)
+#ifdef CONFIG_PPC_CHRP
+1: b machine_check_in_rtas
+#endif
+
+/* Data access exception. */
+ . = 0x300
+DataAccess:
+ EXCEPTION_PROLOG
+ mfspr r10,SPRN_DSISR
+ andis. r0,r10,0xa470 /* weird error? */
+ bne 1f /* if not, try to put a PTE */
+ mfspr r4,SPRN_DAR /* into the hash table */
+ rlwinm r3,r10,32-15,21,21 /* DSISR_STORE -> _PAGE_RW */
+ bl hash_page
+1: stw r10,_DSISR(r11)
+ mr r5,r10
+ mfspr r4,SPRN_DAR
+ EXC_XFER_EE_LITE(0x300, handle_page_fault)
+
+
+/* Instruction access exception. */
+ . = 0x400
+InstructionAccess:
+ EXCEPTION_PROLOG
+ andis. r0,r9,0x4000 /* no pte found? */
+ beq 1f /* if so, try to put a PTE */
+ li r3,0 /* into the hash table */
+ mr r4,r12 /* SRR0 is fault address */
+ bl hash_page
+1: mr r4,r12
+ mr r5,r9
+ EXC_XFER_EE_LITE(0x400, handle_page_fault)
+
+/* External interrupt */
+ EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
+
+/* Alignment exception */
+ . = 0x600
+Alignment:
+ EXCEPTION_PROLOG
+ mfspr r4,SPRN_DAR
+ stw r4,_DAR(r11)
+ mfspr r5,SPRN_DSISR
+ stw r5,_DSISR(r11)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ EXC_XFER_EE(0x600, alignment_exception)
+
+/* Program check exception */
+ EXCEPTION(0x700, ProgramCheck, program_check_exception, EXC_XFER_STD)
+
+/* Floating-point unavailable */
+ . = 0x800
+FPUnavailable:
+ EXCEPTION_PROLOG
+ bne load_up_fpu /* if from user, just load it up */
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ EXC_XFER_EE_LITE(0x800, kernel_fp_unavailable_exception)
+
+/* Decrementer */
+ EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE)
+
+ EXCEPTION(0xa00, Trap_0a, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0xb00, Trap_0b, unknown_exception, EXC_XFER_EE)
+
+/* System call */
+ . = 0xc00
+SystemCall:
+ EXCEPTION_PROLOG
+ EXC_XFER_EE_LITE(0xc00, DoSyscall)
+
+/* Single step - not used on 601 */
+ EXCEPTION(0xd00, SingleStep, single_step_exception, EXC_XFER_STD)
+ EXCEPTION(0xe00, Trap_0e, unknown_exception, EXC_XFER_EE)
+
+/*
+ * The Altivec unavailable trap is at 0x0f20. Foo.
+ * We effectively remap it to 0x3000.
+ * We include an altivec unavailable exception vector even if
+ * not configured for Altivec, so that you can't panic a
+ * non-altivec kernel running on a machine with altivec just
+ * by executing an altivec instruction.
+ */
+ . = 0xf00
+ b Trap_0f
+
+ . = 0xf20
+ b AltiVecUnavailable
+
+Trap_0f:
+ EXCEPTION_PROLOG
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ EXC_XFER_EE(0xf00, unknown_exception)
+
+/*
+ * Handle TLB miss for instruction on 603/603e.
+ * Note: we get an alternate set of r0 - r3 to use automatically.
+ */
+ . = 0x1000
+InstructionTLBMiss:
+/*
+ * r0: stored ctr
+ * r1: linux style pte ( later becomes ppc hardware pte )
+ * r2: ptr to linux-style pte
+ * r3: scratch
+ */
+ mfctr r0
+ /* Get PTE (linux-style) and check access */
+ mfspr r3,SPRN_IMISS
+ lis r1,KERNELBASE@h /* check if kernel address */
+ cmplw 0,r3,r1
+ mfspr r2,SPRN_SPRG3
+ li r1,_PAGE_USER|_PAGE_PRESENT /* low addresses tested as user */
+ lwz r2,PGDIR(r2)
+ blt+ 112f
+ lis r2,swapper_pg_dir@ha /* if kernel address, use */
+ addi r2,r2,swapper_pg_dir@l /* kernel page table */
+ mfspr r1,SPRN_SRR1 /* and MSR_PR bit from SRR1 */
+ rlwinm r1,r1,32-12,29,29 /* shift MSR_PR to _PAGE_USER posn */
+112: tophys(r2,r2)
+ rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */
+ lwz r2,0(r2) /* get pmd entry */
+ rlwinm. r2,r2,0,0,19 /* extract address of pte page */
+ beq- InstructionAddressInvalid /* return if no mapping */
+ rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */
+ lwz r3,0(r2) /* get linux-style pte */
+ andc. r1,r1,r3 /* check access & ~permission */
+ bne- InstructionAddressInvalid /* return if access not permitted */
+ ori r3,r3,_PAGE_ACCESSED /* set _PAGE_ACCESSED in pte */
+ /*
+ * NOTE! We are assuming this is not an SMP system, otherwise
+ * we would need to update the pte atomically with lwarx/stwcx.
+ */
+ stw r3,0(r2) /* update PTE (accessed bit) */
+ /* Convert linux-style PTE to low word of PPC-style PTE */
+ rlwinm r1,r3,32-10,31,31 /* _PAGE_RW -> PP lsb */
+ rlwinm r2,r3,32-7,31,31 /* _PAGE_DIRTY -> PP lsb */
+ and r1,r1,r2 /* writable if _RW and _DIRTY */
+ rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */
+ rlwimi r3,r3,32-1,31,31 /* _PAGE_USER -> PP lsb */
+ ori r1,r1,0xe14 /* clear out reserved bits and M */
+ andc r1,r3,r1 /* PP = user? (rw&dirty? 2: 3): 0 */
+ mtspr SPRN_RPA,r1
+ mfspr r3,SPRN_IMISS
+ tlbli r3
+ mfspr r3,SPRN_SRR1 /* Need to restore CR0 */
+ mtcrf 0x80,r3
+ rfi
+InstructionAddressInvalid:
+ mfspr r3,SPRN_SRR1
+ rlwinm r1,r3,9,6,6 /* Get load/store bit */
+
+ addis r1,r1,0x2000
+ mtspr SPRN_DSISR,r1 /* (shouldn't be needed) */
+ mtctr r0 /* Restore CTR */
+ andi. r2,r3,0xFFFF /* Clear upper bits of SRR1 */
+ or r2,r2,r1
+ mtspr SPRN_SRR1,r2
+ mfspr r1,SPRN_IMISS /* Get failing address */
+ rlwinm. r2,r2,0,31,31 /* Check for little endian access */
+ rlwimi r2,r2,1,30,30 /* change 1 -> 3 */
+ xor r1,r1,r2
+ mtspr SPRN_DAR,r1 /* Set fault address */
+ mfmsr r0 /* Restore "normal" registers */
+ xoris r0,r0,MSR_TGPR>>16
+ mtcrf 0x80,r3 /* Restore CR0 */
+ mtmsr r0
+ b InstructionAccess
+
+/*
+ * Handle TLB miss for DATA Load operation on 603/603e
+ */
+ . = 0x1100
+DataLoadTLBMiss:
+/*
+ * r0: stored ctr
+ * r1: linux style pte ( later becomes ppc hardware pte )
+ * r2: ptr to linux-style pte
+ * r3: scratch
+ */
+ mfctr r0
+ /* Get PTE (linux-style) and check access */
+ mfspr r3,SPRN_DMISS
+ lis r1,KERNELBASE@h /* check if kernel address */
+ cmplw 0,r3,r1
+ mfspr r2,SPRN_SPRG3
+ li r1,_PAGE_USER|_PAGE_PRESENT /* low addresses tested as user */
+ lwz r2,PGDIR(r2)
+ blt+ 112f
+ lis r2,swapper_pg_dir@ha /* if kernel address, use */
+ addi r2,r2,swapper_pg_dir@l /* kernel page table */
+ mfspr r1,SPRN_SRR1 /* and MSR_PR bit from SRR1 */
+ rlwinm r1,r1,32-12,29,29 /* shift MSR_PR to _PAGE_USER posn */
+112: tophys(r2,r2)
+ rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */
+ lwz r2,0(r2) /* get pmd entry */
+ rlwinm. r2,r2,0,0,19 /* extract address of pte page */
+ beq- DataAddressInvalid /* return if no mapping */
+ rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */
+ lwz r3,0(r2) /* get linux-style pte */
+ andc. r1,r1,r3 /* check access & ~permission */
+ bne- DataAddressInvalid /* return if access not permitted */
+ ori r3,r3,_PAGE_ACCESSED /* set _PAGE_ACCESSED in pte */
+ /*
+ * NOTE! We are assuming this is not an SMP system, otherwise
+ * we would need to update the pte atomically with lwarx/stwcx.
+ */
+ stw r3,0(r2) /* update PTE (accessed bit) */
+ /* Convert linux-style PTE to low word of PPC-style PTE */
+ rlwinm r1,r3,32-10,31,31 /* _PAGE_RW -> PP lsb */
+ rlwinm r2,r3,32-7,31,31 /* _PAGE_DIRTY -> PP lsb */
+ and r1,r1,r2 /* writable if _RW and _DIRTY */
+ rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */
+ rlwimi r3,r3,32-1,31,31 /* _PAGE_USER -> PP lsb */
+ ori r1,r1,0xe14 /* clear out reserved bits and M */
+ andc r1,r3,r1 /* PP = user? (rw&dirty? 2: 3): 0 */
+ mtspr SPRN_RPA,r1
+ mfspr r3,SPRN_DMISS
+ tlbld r3
+ mfspr r3,SPRN_SRR1 /* Need to restore CR0 */
+ mtcrf 0x80,r3
+ rfi
+DataAddressInvalid:
+ mfspr r3,SPRN_SRR1
+ rlwinm r1,r3,9,6,6 /* Get load/store bit */
+ addis r1,r1,0x2000
+ mtspr SPRN_DSISR,r1
+ mtctr r0 /* Restore CTR */
+ andi. r2,r3,0xFFFF /* Clear upper bits of SRR1 */
+ mtspr SPRN_SRR1,r2
+ mfspr r1,SPRN_DMISS /* Get failing address */
+ rlwinm. r2,r2,0,31,31 /* Check for little endian access */
+ beq 20f /* Jump if big endian */
+ xori r1,r1,3
+20: mtspr SPRN_DAR,r1 /* Set fault address */
+ mfmsr r0 /* Restore "normal" registers */
+ xoris r0,r0,MSR_TGPR>>16
+ mtcrf 0x80,r3 /* Restore CR0 */
+ mtmsr r0
+ b DataAccess
+
+/*
+ * Handle TLB miss for DATA Store on 603/603e
+ */
+ . = 0x1200
+DataStoreTLBMiss:
+/*
+ * r0: stored ctr
+ * r1: linux style pte ( later becomes ppc hardware pte )
+ * r2: ptr to linux-style pte
+ * r3: scratch
+ */
+ mfctr r0
+ /* Get PTE (linux-style) and check access */
+ mfspr r3,SPRN_DMISS
+ lis r1,KERNELBASE@h /* check if kernel address */
+ cmplw 0,r3,r1
+ mfspr r2,SPRN_SPRG3
+ li r1,_PAGE_RW|_PAGE_USER|_PAGE_PRESENT /* access flags */
+ lwz r2,PGDIR(r2)
+ blt+ 112f
+ lis r2,swapper_pg_dir@ha /* if kernel address, use */
+ addi r2,r2,swapper_pg_dir@l /* kernel page table */
+ mfspr r1,SPRN_SRR1 /* and MSR_PR bit from SRR1 */
+ rlwinm r1,r1,32-12,29,29 /* shift MSR_PR to _PAGE_USER posn */
+112: tophys(r2,r2)
+ rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */
+ lwz r2,0(r2) /* get pmd entry */
+ rlwinm. r2,r2,0,0,19 /* extract address of pte page */
+ beq- DataAddressInvalid /* return if no mapping */
+ rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */
+ lwz r3,0(r2) /* get linux-style pte */
+ andc. r1,r1,r3 /* check access & ~permission */
+ bne- DataAddressInvalid /* return if access not permitted */
+ ori r3,r3,_PAGE_ACCESSED|_PAGE_DIRTY
+ /*
+ * NOTE! We are assuming this is not an SMP system, otherwise
+ * we would need to update the pte atomically with lwarx/stwcx.
+ */
+ stw r3,0(r2) /* update PTE (accessed/dirty bits) */
+ /* Convert linux-style PTE to low word of PPC-style PTE */
+ rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */
+ li r1,0xe15 /* clear out reserved bits and M */
+ andc r1,r3,r1 /* PP = user? 2: 0 */
+ mtspr SPRN_RPA,r1
+ mfspr r3,SPRN_DMISS
+ tlbld r3
+ mfspr r3,SPRN_SRR1 /* Need to restore CR0 */
+ mtcrf 0x80,r3
+ rfi
+
+#ifndef CONFIG_ALTIVEC
+#define altivec_assist_exception unknown_exception
+#endif
+
+ EXCEPTION(0x1300, Trap_13, instruction_breakpoint_exception, EXC_XFER_EE)
+ EXCEPTION(0x1400, SMI, SMIException, EXC_XFER_EE)
+ EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1600, Trap_16, altivec_assist_exception, EXC_XFER_EE)
+ EXCEPTION(0x1700, Trap_17, TAUException, EXC_XFER_STD)
+ EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1a00, Trap_1a, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1b00, Trap_1b, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1c00, Trap_1c, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1d00, Trap_1d, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1e00, Trap_1e, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1f00, Trap_1f, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2000, RunMode, RunModeException, EXC_XFER_EE)
+ EXCEPTION(0x2100, Trap_21, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2200, Trap_22, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2300, Trap_23, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2400, Trap_24, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2500, Trap_25, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2600, Trap_26, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2700, Trap_27, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2800, Trap_28, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2900, Trap_29, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2a00, Trap_2a, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2b00, Trap_2b, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2c00, Trap_2c, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2d00, Trap_2d, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2e00, Trap_2e, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2f00, MOLTrampoline, unknown_exception, EXC_XFER_EE_LITE)
+
+ .globl mol_trampoline
+ .set mol_trampoline, i0x2f00
+
+ . = 0x3000
+
+AltiVecUnavailable:
+ EXCEPTION_PROLOG
+#ifdef CONFIG_ALTIVEC
+ bne load_up_altivec /* if from user, just load it up */
+#endif /* CONFIG_ALTIVEC */
+ EXC_XFER_EE_LITE(0xf20, altivec_unavailable_exception)
+
+#ifdef CONFIG_ALTIVEC
+/* Note that the AltiVec support is closely modeled after the FP
+ * support. Changes to one are likely to be applicable to the
+ * other! */
+load_up_altivec:
+/*
+ * Disable AltiVec for the task which had AltiVec previously,
+ * and save its AltiVec registers in its thread_struct.
+ * Enables AltiVec for use in the kernel on return.
+ * On SMP we know the AltiVec units are free, since we give it up every
+ * switch. -- Kumar
+ */
+ mfmsr r5
+ oris r5,r5,MSR_VEC@h
+ MTMSRD(r5) /* enable use of AltiVec now */
+ isync
+/*
+ * For SMP, we don't do lazy AltiVec switching because it just gets too
+ * horrendously complex, especially when a task switches from one CPU
+ * to another. Instead we call giveup_altivec in switch_to.
+ */
+#ifndef CONFIG_SMP
+ tophys(r6,0)
+ addis r3,r6,last_task_used_altivec@ha
+ lwz r4,last_task_used_altivec@l(r3)
+ cmpwi 0,r4,0
+ beq 1f
+ add r4,r4,r6
+ addi r4,r4,THREAD /* want THREAD of last_task_used_altivec */
+ SAVE_32VRS(0,r10,r4)
+ mfvscr vr0
+ li r10,THREAD_VSCR
+ stvx vr0,r10,r4
+ lwz r5,PT_REGS(r4)
+ add r5,r5,r6
+ lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+ lis r10,MSR_VEC@h
+ andc r4,r4,r10 /* disable altivec for previous task */
+ stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:
+#endif /* CONFIG_SMP */
+ /* enable use of AltiVec after return */
+ oris r9,r9,MSR_VEC@h
+ mfspr r5,SPRN_SPRG3 /* current task's THREAD (phys) */
+ li r4,1
+ li r10,THREAD_VSCR
+ stw r4,THREAD_USED_VR(r5)
+ lvx vr0,r10,r5
+ mtvscr vr0
+ REST_32VRS(0,r10,r5)
+#ifndef CONFIG_SMP
+ subi r4,r5,THREAD
+ sub r4,r4,r6
+ stw r4,last_task_used_altivec@l(r3)
+#endif /* CONFIG_SMP */
+ /* restore registers and return */
+ /* we haven't used ctr or xer or lr */
+ b fast_exception_return
+
+/*
+ * AltiVec unavailable trap from kernel - print a message, but let
+ * the task use AltiVec in the kernel until it returns to user mode.
+ */
+KernelAltiVec:
+ lwz r3,_MSR(r1)
+ oris r3,r3,MSR_VEC@h
+ stw r3,_MSR(r1) /* enable use of AltiVec after return */
+ lis r3,87f@h
+ ori r3,r3,87f@l
+ mr r4,r2 /* current */
+ lwz r5,_NIP(r1)
+ bl printk
+ b ret_from_except
+87: .string "AltiVec used in kernel (task=%p, pc=%x) \n"
+ .align 4,0
+
+/*
+ * giveup_altivec(tsk)
+ * Disable AltiVec for the task given as the argument,
+ * and save the AltiVec registers in its thread_struct.
+ * Enables AltiVec for use in the kernel on return.
+ */
+
+ .globl giveup_altivec
+giveup_altivec:
+ mfmsr r5
+ oris r5,r5,MSR_VEC@h
+ SYNC
+ MTMSRD(r5) /* enable use of AltiVec now */
+ isync
+ cmpwi 0,r3,0
+ beqlr- /* if no previous owner, done */
+ addi r3,r3,THREAD /* want THREAD of task */
+ lwz r5,PT_REGS(r3)
+ cmpwi 0,r5,0
+ SAVE_32VRS(0, r4, r3)
+ mfvscr vr0
+ li r4,THREAD_VSCR
+ stvx vr0,r4,r3
+ beq 1f
+ lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+ lis r3,MSR_VEC@h
+ andc r4,r4,r3 /* disable AltiVec for previous task */
+ stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:
+#ifndef CONFIG_SMP
+ li r5,0
+ lis r4,last_task_used_altivec@ha
+ stw r5,last_task_used_altivec@l(r4)
+#endif /* CONFIG_SMP */
+ blr
+#endif /* CONFIG_ALTIVEC */
+
+/*
+ * This code is jumped to from the startup code to copy
+ * the kernel image to physical address 0.
+ */
+relocate_kernel:
+ addis r9,r26,klimit@ha /* fetch klimit */
+ lwz r25,klimit@l(r9)
+ addis r25,r25,-KERNELBASE@h
+ li r3,0 /* Destination base address */
+ li r6,0 /* Destination offset */
+ li r5,0x4000 /* # bytes of memory to copy */
+ bl copy_and_flush /* copy the first 0x4000 bytes */
+ addi r0,r3,4f@l /* jump to the address of 4f */
+ mtctr r0 /* in copy and do the rest. */
+ bctr /* jump to the copy */
+4: mr r5,r25
+ bl copy_and_flush /* copy the rest */
+ b turn_on_mmu
+
+/*
+ * Copy routine used to copy the kernel to start at physical address 0
+ * and flush and invalidate the caches as needed.
+ * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset
+ * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5.
+ */
+_GLOBAL(copy_and_flush)
+ addi r5,r5,-4
+ addi r6,r6,-4
+4: li r0,L1_CACHE_BYTES/4
+ mtctr r0
+3: addi r6,r6,4 /* copy a cache line */
+ lwzx r0,r6,r4
+ stwx r0,r6,r3
+ bdnz 3b
+ dcbst r6,r3 /* write it to memory */
+ sync
+ icbi r6,r3 /* flush the icache line */
+ cmplw 0,r6,r5
+ blt 4b
+ sync /* additional sync needed on g4 */
+ isync
+ addi r5,r5,4
+ addi r6,r6,4
+ blr
+
+#ifdef CONFIG_APUS
+/*
+ * On APUS the physical base address of the kernel is not known at compile
+ * time, which means the __pa/__va constants used are incorrect. In the
+ * __init section is recorded the virtual addresses of instructions using
+ * these constants, so all that has to be done is fix these before
+ * continuing the kernel boot.
+ *
+ * r4 = The physical address of the kernel base.
+ */
+fix_mem_constants:
+ mr r10,r4
+ addis r10,r10,-KERNELBASE@h /* virt_to_phys constant */
+ neg r11,r10 /* phys_to_virt constant */
+
+ lis r12,__vtop_table_begin@h
+ ori r12,r12,__vtop_table_begin@l
+ add r12,r12,r10 /* table begin phys address */
+ lis r13,__vtop_table_end@h
+ ori r13,r13,__vtop_table_end@l
+ add r13,r13,r10 /* table end phys address */
+ subi r12,r12,4
+ subi r13,r13,4
+1: lwzu r14,4(r12) /* virt address of instruction */
+ add r14,r14,r10 /* phys address of instruction */
+ lwz r15,0(r14) /* instruction, now insert top */
+ rlwimi r15,r10,16,16,31 /* half of vp const in low half */
+ stw r15,0(r14) /* of instruction and restore. */
+ dcbst r0,r14 /* write it to memory */
+ sync
+ icbi r0,r14 /* flush the icache line */
+ cmpw r12,r13
+ bne 1b
+ sync /* additional sync needed on g4 */
+ isync
+
+/*
+ * Map the memory where the exception handlers will
+ * be copied to when hash constants have been patched.
+ */
+#ifdef CONFIG_APUS_FAST_EXCEPT
+ lis r8,0xfff0
+#else
+ lis r8,0
+#endif
+ ori r8,r8,0x2 /* 128KB, supervisor */
+ mtspr SPRN_DBAT3U,r8
+ mtspr SPRN_DBAT3L,r8
+
+ lis r12,__ptov_table_begin@h
+ ori r12,r12,__ptov_table_begin@l
+ add r12,r12,r10 /* table begin phys address */
+ lis r13,__ptov_table_end@h
+ ori r13,r13,__ptov_table_end@l
+ add r13,r13,r10 /* table end phys address */
+ subi r12,r12,4
+ subi r13,r13,4
+1: lwzu r14,4(r12) /* virt address of instruction */
+ add r14,r14,r10 /* phys address of instruction */
+ lwz r15,0(r14) /* instruction, now insert top */
+ rlwimi r15,r11,16,16,31 /* half of pv const in low half*/
+ stw r15,0(r14) /* of instruction and restore. */
+ dcbst r0,r14 /* write it to memory */
+ sync
+ icbi r0,r14 /* flush the icache line */
+ cmpw r12,r13
+ bne 1b
+
+ sync /* additional sync needed on g4 */
+ isync /* No speculative loading until now */
+ blr
+
+/***********************************************************************
+ * Please note that on APUS the exception handlers are located at the
+ * physical address 0xfff0000. For this reason, the exception handlers
+ * cannot use relative branches to access the code below.
+ ***********************************************************************/
+#endif /* CONFIG_APUS */
+
+#ifdef CONFIG_SMP
+#ifdef CONFIG_GEMINI
+ .globl __secondary_start_gemini
+__secondary_start_gemini:
+ mfspr r4,SPRN_HID0
+ ori r4,r4,HID0_ICFI
+ li r3,0
+ ori r3,r3,HID0_ICE
+ andc r4,r4,r3
+ mtspr SPRN_HID0,r4
+ sync
+ b __secondary_start
+#endif /* CONFIG_GEMINI */
+
+ .globl __secondary_start_pmac_0
+__secondary_start_pmac_0:
+ /* NB the entries for cpus 0, 1, 2 must each occupy 8 bytes. */
+ li r24,0
+ b 1f
+ li r24,1
+ b 1f
+ li r24,2
+ b 1f
+ li r24,3
+1:
+ /* on powersurge, we come in here with IR=0 and DR=1, and DBAT 0
+ set to map the 0xf0000000 - 0xffffffff region */
+ mfmsr r0
+ rlwinm r0,r0,0,28,26 /* clear DR (0x10) */
+ SYNC
+ mtmsr r0
+ isync
+
+ .globl __secondary_start
+__secondary_start:
+ /* Copy some CPU settings from CPU 0 */
+ bl __restore_cpu_setup
+
+ lis r3,-KERNELBASE@h
+ mr r4,r24
+ bl call_setup_cpu /* Call setup_cpu for this CPU */
+#ifdef CONFIG_6xx
+ lis r3,-KERNELBASE@h
+ bl init_idle_6xx
+#endif /* CONFIG_6xx */
+
+ /* get current_thread_info and current */
+ lis r1,secondary_ti@ha
+ tophys(r1,r1)
+ lwz r1,secondary_ti@l(r1)
+ tophys(r2,r1)
+ lwz r2,TI_TASK(r2)
+
+ /* stack */
+ addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
+ li r0,0
+ tophys(r3,r1)
+ stw r0,0(r3)
+
+ /* load up the MMU */
+ bl load_up_mmu
+
+ /* ptr to phys current thread */
+ tophys(r4,r2)
+ addi r4,r4,THREAD /* phys address of our thread_struct */
+ CLR_TOP32(r4)
+ mtspr SPRN_SPRG3,r4
+ li r3,0
+ mtspr SPRN_SPRG2,r3 /* 0 => not in RTAS */
+
+ /* enable MMU and jump to start_secondary */
+ li r4,MSR_KERNEL
+ FIX_SRR1(r4,r5)
+ lis r3,start_secondary@h
+ ori r3,r3,start_secondary@l
+ mtspr SPRN_SRR0,r3
+ mtspr SPRN_SRR1,r4
+ SYNC
+ RFI
+#endif /* CONFIG_SMP */
+
+/*
+ * Those generic dummy functions are kept for CPUs not
+ * included in CONFIG_6xx
+ */
+#if !defined(CONFIG_6xx)
+_GLOBAL(__save_cpu_setup)
+ blr
+_GLOBAL(__restore_cpu_setup)
+ blr
+#endif /* !defined(CONFIG_6xx) */
+
+
+/*
+ * Load stuff into the MMU. Intended to be called with
+ * IR=0 and DR=0.
+ */
+load_up_mmu:
+ sync /* Force all PTE updates to finish */
+ isync
+ tlbia /* Clear all TLB entries */
+ sync /* wait for tlbia/tlbie to finish */
+ TLBSYNC /* ... on all CPUs */
+ /* Load the SDR1 register (hash table base & size) */
+ lis r6,_SDR1@ha
+ tophys(r6,r6)
+ lwz r6,_SDR1@l(r6)
+ mtspr SPRN_SDR1,r6
+ li r0,16 /* load up segment register values */
+ mtctr r0 /* for context 0 */
+ lis r3,0x2000 /* Ku = 1, VSID = 0 */
+ li r4,0
+3: mtsrin r3,r4
+ addi r3,r3,0x111 /* increment VSID */
+ addis r4,r4,0x1000 /* address of next segment */
+ bdnz 3b
+
+/* Load the BAT registers with the values set up by MMU_init.
+ MMU_init takes care of whether we're on a 601 or not. */
+ mfpvr r3
+ srwi r3,r3,16
+ cmpwi r3,1
+ lis r3,BATS@ha
+ addi r3,r3,BATS@l
+ tophys(r3,r3)
+ LOAD_BAT(0,r3,r4,r5)
+ LOAD_BAT(1,r3,r4,r5)
+ LOAD_BAT(2,r3,r4,r5)
+ LOAD_BAT(3,r3,r4,r5)
+
+ blr
+
+/*
+ * This is where the main kernel code starts.
+ */
+start_here:
+ /* ptr to current */
+ lis r2,init_task@h
+ ori r2,r2,init_task@l
+ /* Set up for using our exception vectors */
+ /* ptr to phys current thread */
+ tophys(r4,r2)
+ addi r4,r4,THREAD /* init task's THREAD */
+ CLR_TOP32(r4)
+ mtspr SPRN_SPRG3,r4
+ li r3,0
+ mtspr SPRN_SPRG2,r3 /* 0 => not in RTAS */
+
+ /* stack */
+ lis r1,init_thread_union@ha
+ addi r1,r1,init_thread_union@l
+ li r0,0
+ stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
+/*
+ * Do early platform-specific initialization,
+ * and set up the MMU.
+ */
+ mr r3,r31
+ mr r4,r30
+ bl machine_init
+ bl MMU_init
+
+#ifdef CONFIG_APUS
+ /* Copy exception code to exception vector base on APUS. */
+ lis r4,KERNELBASE@h
+#ifdef CONFIG_APUS_FAST_EXCEPT
+ lis r3,0xfff0 /* Copy to 0xfff00000 */
+#else
+ lis r3,0 /* Copy to 0x00000000 */
+#endif
+ li r5,0x4000 /* # bytes of memory to copy */
+ li r6,0
+ bl copy_and_flush /* copy the first 0x4000 bytes */
+#endif /* CONFIG_APUS */
+
+/*
+ * Go back to running unmapped so we can load up new values
+ * for SDR1 (hash table pointer) and the segment registers
+ * and change to using our exception vectors.
+ */
+ lis r4,2f@h
+ ori r4,r4,2f@l
+ tophys(r4,r4)
+ li r3,MSR_KERNEL & ~(MSR_IR|MSR_DR)
+ FIX_SRR1(r3,r5)
+ mtspr SPRN_SRR0,r4
+ mtspr SPRN_SRR1,r3
+ SYNC
+ RFI
+/* Load up the kernel context */
+2: bl load_up_mmu
+
+#ifdef CONFIG_BDI_SWITCH
+ /* Add helper information for the Abatron bdiGDB debugger.
+ * We do this here because we know the mmu is disabled, and
+ * will be enabled for real in just a few instructions.
+ */
+ lis r5, abatron_pteptrs@h
+ ori r5, r5, abatron_pteptrs@l
+ stw r5, 0xf0(r0) /* This much match your Abatron config */
+ lis r6, swapper_pg_dir@h
+ ori r6, r6, swapper_pg_dir@l
+ tophys(r5, r5)
+ stw r6, 0(r5)
+#endif /* CONFIG_BDI_SWITCH */
+
+/* Now turn on the MMU for real! */
+ li r4,MSR_KERNEL
+ FIX_SRR1(r4,r5)
+ lis r3,start_kernel@h
+ ori r3,r3,start_kernel@l
+ mtspr SPRN_SRR0,r3
+ mtspr SPRN_SRR1,r4
+ SYNC
+ RFI
+
+/*
+ * Set up the segment registers for a new context.
+ */
+_GLOBAL(set_context)
+ mulli r3,r3,897 /* multiply context by skew factor */
+ rlwinm r3,r3,4,8,27 /* VSID = (context & 0xfffff) << 4 */
+ addis r3,r3,0x6000 /* Set Ks, Ku bits */
+ li r0,NUM_USER_SEGMENTS
+ mtctr r0
+
+#ifdef CONFIG_BDI_SWITCH
+ /* Context switch the PTE pointer for the Abatron BDI2000.
+ * The PGDIR is passed as second argument.
+ */
+ lis r5, KERNELBASE@h
+ lwz r5, 0xf0(r5)
+ stw r4, 0x4(r5)
+#endif
+ li r4,0
+ isync
+3:
+ mtsrin r3,r4
+ addi r3,r3,0x111 /* next VSID */
+ rlwinm r3,r3,0,8,3 /* clear out any overflow from VSID field */
+ addis r4,r4,0x1000 /* address of next segment */
+ bdnz 3b
+ sync
+ isync
+ blr
+
+/*
+ * An undocumented "feature" of 604e requires that the v bit
+ * be cleared before changing BAT values.
+ *
+ * Also, newer IBM firmware does not clear bat3 and 4 so
+ * this makes sure it's done.
+ * -- Cort
+ */
+clear_bats:
+ li r10,0
+ mfspr r9,SPRN_PVR
+ rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */
+ cmpwi r9, 1
+ beq 1f
+
+ mtspr SPRN_DBAT0U,r10
+ mtspr SPRN_DBAT0L,r10
+ mtspr SPRN_DBAT1U,r10
+ mtspr SPRN_DBAT1L,r10
+ mtspr SPRN_DBAT2U,r10
+ mtspr SPRN_DBAT2L,r10
+ mtspr SPRN_DBAT3U,r10
+ mtspr SPRN_DBAT3L,r10
+1:
+ mtspr SPRN_IBAT0U,r10
+ mtspr SPRN_IBAT0L,r10
+ mtspr SPRN_IBAT1U,r10
+ mtspr SPRN_IBAT1L,r10
+ mtspr SPRN_IBAT2U,r10
+ mtspr SPRN_IBAT2L,r10
+ mtspr SPRN_IBAT3U,r10
+ mtspr SPRN_IBAT3L,r10
+BEGIN_FTR_SECTION
+ /* Here's a tweak: at this point, CPU setup have
+ * not been called yet, so HIGH_BAT_EN may not be
+ * set in HID0 for the 745x processors. However, it
+ * seems that doesn't affect our ability to actually
+ * write to these SPRs.
+ */
+ mtspr SPRN_DBAT4U,r10
+ mtspr SPRN_DBAT4L,r10
+ mtspr SPRN_DBAT5U,r10
+ mtspr SPRN_DBAT5L,r10
+ mtspr SPRN_DBAT6U,r10
+ mtspr SPRN_DBAT6L,r10
+ mtspr SPRN_DBAT7U,r10
+ mtspr SPRN_DBAT7L,r10
+ mtspr SPRN_IBAT4U,r10
+ mtspr SPRN_IBAT4L,r10
+ mtspr SPRN_IBAT5U,r10
+ mtspr SPRN_IBAT5L,r10
+ mtspr SPRN_IBAT6U,r10
+ mtspr SPRN_IBAT6L,r10
+ mtspr SPRN_IBAT7U,r10
+ mtspr SPRN_IBAT7L,r10
+END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS)
+ blr
+
+flush_tlbs:
+ lis r10, 0x40
+1: addic. r10, r10, -0x1000
+ tlbie r10
+ blt 1b
+ sync
+ blr
+
+mmu_off:
+ addi r4, r3, __after_mmu_off - _start
+ mfmsr r3
+ andi. r0,r3,MSR_DR|MSR_IR /* MMU enabled? */
+ beqlr
+ andc r3,r3,r0
+ mtspr SPRN_SRR0,r4
+ mtspr SPRN_SRR1,r3
+ sync
+ RFI
+
+/*
+ * Use the first pair of BAT registers to map the 1st 16MB
+ * of RAM to KERNELBASE. From this point on we can't safely
+ * call OF any more.
+ */
+initial_bats:
+ lis r11,KERNELBASE@h
+ mfspr r9,SPRN_PVR
+ rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */
+ cmpwi 0,r9,1
+ bne 4f
+ ori r11,r11,4 /* set up BAT registers for 601 */
+ li r8,0x7f /* valid, block length = 8MB */
+ oris r9,r11,0x800000@h /* set up BAT reg for 2nd 8M */
+ oris r10,r8,0x800000@h /* set up BAT reg for 2nd 8M */
+ mtspr SPRN_IBAT0U,r11 /* N.B. 601 has valid bit in */
+ mtspr SPRN_IBAT0L,r8 /* lower BAT register */
+ mtspr SPRN_IBAT1U,r9
+ mtspr SPRN_IBAT1L,r10
+ isync
+ blr
+
+4: tophys(r8,r11)
+#ifdef CONFIG_SMP
+ ori r8,r8,0x12 /* R/W access, M=1 */
+#else
+ ori r8,r8,2 /* R/W access */
+#endif /* CONFIG_SMP */
+#ifdef CONFIG_APUS
+ ori r11,r11,BL_8M<<2|0x2 /* set up 8MB BAT registers for 604 */
+#else
+ ori r11,r11,BL_256M<<2|0x2 /* set up BAT registers for 604 */
+#endif /* CONFIG_APUS */
+
+ mtspr SPRN_DBAT0L,r8 /* N.B. 6xx (not 601) have valid */
+ mtspr SPRN_DBAT0U,r11 /* bit in upper BAT register */
+ mtspr SPRN_IBAT0L,r8
+ mtspr SPRN_IBAT0U,r11
+ isync
+ blr
+
+
+#ifdef CONFIG_8260
+/* Jump into the system reset for the rom.
+ * We first disable the MMU, and then jump to the ROM reset address.
+ *
+ * r3 is the board info structure, r4 is the location for starting.
+ * I use this for building a small kernel that can load other kernels,
+ * rather than trying to write or rely on a rom monitor that can tftp load.
+ */
+ .globl m8260_gorom
+m8260_gorom:
+ mfmsr r0
+ rlwinm r0,r0,0,17,15 /* clear MSR_EE in r0 */
+ sync
+ mtmsr r0
+ sync
+ mfspr r11, SPRN_HID0
+ lis r10, 0
+ ori r10,r10,HID0_ICE|HID0_DCE
+ andc r11, r11, r10
+ mtspr SPRN_HID0, r11
+ isync
+ li r5, MSR_ME|MSR_RI
+ lis r6,2f@h
+ addis r6,r6,-KERNELBASE@h
+ ori r6,r6,2f@l
+ mtspr SPRN_SRR0,r6
+ mtspr SPRN_SRR1,r5
+ isync
+ sync
+ rfi
+2:
+ mtlr r4
+ blr
+#endif
+
+
+/*
+ * We put a few things here that have to be page-aligned.
+ * This stuff goes at the beginning of the data segment,
+ * which is page-aligned.
+ */
+ .data
+ .globl sdata
+sdata:
+ .globl empty_zero_page
+empty_zero_page:
+ .space 4096
+
+ .globl swapper_pg_dir
+swapper_pg_dir:
+ .space 4096
+
+/*
+ * This space gets a copy of optional info passed to us by the bootstrap
+ * Used to pass parameters into the kernel like root=/dev/sda1, etc.
+ */
+ .globl cmd_line
+cmd_line:
+ .space 512
+
+ .globl intercept_table
+intercept_table:
+ .long 0, 0, i0x200, i0x300, i0x400, 0, i0x600, i0x700
+ .long i0x800, 0, 0, 0, 0, i0xd00, 0, 0
+ .long 0, 0, 0, i0x1300, 0, 0, 0, 0
+ .long 0, 0, 0, 0, 0, 0, 0, 0
+ .long 0, 0, 0, 0, 0, 0, 0, 0
+ .long 0, 0, 0, 0, 0, 0, 0, 0
+
+/* Room for two PTE pointers, usually the kernel and current user pointers
+ * to their respective root page table.
+ */
+abatron_pteptrs:
+ .space 8
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
new file mode 100644
index 000000000000..8b49679fad54
--- /dev/null
+++ b/arch/powerpc/kernel/head_44x.S
@@ -0,0 +1,782 @@
+/*
+ * arch/ppc/kernel/head_44x.S
+ *
+ * Kernel execution entry point code.
+ *
+ * Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org>
+ * Initial PowerPC version.
+ * Copyright (c) 1996 Cort Dougan <cort@cs.nmt.edu>
+ * Rewritten for PReP
+ * Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
+ * Low-level exception handers, MMU support, and rewrite.
+ * Copyright (c) 1997 Dan Malek <dmalek@jlc.net>
+ * PowerPC 8xx modifications.
+ * Copyright (c) 1998-1999 TiVo, Inc.
+ * PowerPC 403GCX modifications.
+ * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ * PowerPC 403GCX/405GP modifications.
+ * Copyright 2000 MontaVista Software Inc.
+ * PPC405 modifications
+ * PowerPC 403GCX/405GP modifications.
+ * Author: MontaVista Software, Inc.
+ * frank_rowand@mvista.com or source@mvista.com
+ * debbie_chu@mvista.com
+ * Copyright 2002-2005 MontaVista Software, Inc.
+ * PowerPC 44x support, Matt Porter <mporter@kernel.crashing.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/config.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/ibm4xx.h>
+#include <asm/ibm44x.h>
+#include <asm/cputable.h>
+#include <asm/thread_info.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+#include "head_booke.h"
+
+
+/* As with the other PowerPC ports, it is expected that when code
+ * execution begins here, the following registers contain valid, yet
+ * optional, information:
+ *
+ * r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.)
+ * r4 - Starting address of the init RAM disk
+ * r5 - Ending address of the init RAM disk
+ * r6 - Start of kernel command line string (e.g. "mem=128")
+ * r7 - End of kernel command line string
+ *
+ */
+ .text
+_GLOBAL(_stext)
+_GLOBAL(_start)
+ /*
+ * Reserve a word at a fixed location to store the address
+ * of abatron_pteptrs
+ */
+ nop
+/*
+ * Save parameters we are passed
+ */
+ mr r31,r3
+ mr r30,r4
+ mr r29,r5
+ mr r28,r6
+ mr r27,r7
+ li r24,0 /* CPU number */
+
+/*
+ * Set up the initial MMU state
+ *
+ * We are still executing code at the virtual address
+ * mappings set by the firmware for the base of RAM.
+ *
+ * We first invalidate all TLB entries but the one
+ * we are running from. We then load the KERNELBASE
+ * mappings so we can begin to use kernel addresses
+ * natively and so the interrupt vector locations are
+ * permanently pinned (necessary since Book E
+ * implementations always have translation enabled).
+ *
+ * TODO: Use the known TLB entry we are running from to
+ * determine which physical region we are located
+ * in. This can be used to determine where in RAM
+ * (on a shared CPU system) or PCI memory space
+ * (on a DRAMless system) we are located.
+ * For now, we assume a perfect world which means
+ * we are located at the base of DRAM (physical 0).
+ */
+
+/*
+ * Search TLB for entry that we are currently using.
+ * Invalidate all entries but the one we are using.
+ */
+ /* Load our current PID->MMUCR TID and MSR IS->MMUCR STS */
+ mfspr r3,SPRN_PID /* Get PID */
+ mfmsr r4 /* Get MSR */
+ andi. r4,r4,MSR_IS@l /* TS=1? */
+ beq wmmucr /* If not, leave STS=0 */
+ oris r3,r3,PPC44x_MMUCR_STS@h /* Set STS=1 */
+wmmucr: mtspr SPRN_MMUCR,r3 /* Put MMUCR */
+ sync
+
+ bl invstr /* Find our address */
+invstr: mflr r5 /* Make it accessible */
+ tlbsx r23,0,r5 /* Find entry we are in */
+ li r4,0 /* Start at TLB entry 0 */
+ li r3,0 /* Set PAGEID inval value */
+1: cmpw r23,r4 /* Is this our entry? */
+ beq skpinv /* If so, skip the inval */
+ tlbwe r3,r4,PPC44x_TLB_PAGEID /* If not, inval the entry */
+skpinv: addi r4,r4,1 /* Increment */
+ cmpwi r4,64 /* Are we done? */
+ bne 1b /* If not, repeat */
+ isync /* If so, context change */
+
+/*
+ * Configure and load pinned entry into TLB slot 63.
+ */
+
+ lis r3,KERNELBASE@h /* Load the kernel virtual address */
+ ori r3,r3,KERNELBASE@l
+
+ /* Kernel is at the base of RAM */
+ li r4, 0 /* Load the kernel physical address */
+
+ /* Load the kernel PID = 0 */
+ li r0,0
+ mtspr SPRN_PID,r0
+ sync
+
+ /* Initialize MMUCR */
+ li r5,0
+ mtspr SPRN_MMUCR,r5
+ sync
+
+ /* pageid fields */
+ clrrwi r3,r3,10 /* Mask off the effective page number */
+ ori r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_256M
+
+ /* xlat fields */
+ clrrwi r4,r4,10 /* Mask off the real page number */
+ /* ERPN is 0 for first 4GB page */
+
+ /* attrib fields */
+ /* Added guarded bit to protect against speculative loads/stores */
+ li r5,0
+ ori r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G)
+
+ li r0,63 /* TLB slot 63 */
+
+ tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */
+ tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */
+ tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */
+
+ /* Force context change */
+ mfmsr r0
+ mtspr SPRN_SRR1, r0
+ lis r0,3f@h
+ ori r0,r0,3f@l
+ mtspr SPRN_SRR0,r0
+ sync
+ rfi
+
+ /* If necessary, invalidate original entry we used */
+3: cmpwi r23,63
+ beq 4f
+ li r6,0
+ tlbwe r6,r23,PPC44x_TLB_PAGEID
+ isync
+
+4:
+#ifdef CONFIG_SERIAL_TEXT_DEBUG
+ /*
+ * Add temporary UART mapping for early debug.
+ * We can map UART registers wherever we want as long as they don't
+ * interfere with other system mappings (e.g. with pinned entries).
+ * For an example of how we handle this - see ocotea.h. --ebs
+ */
+ /* pageid fields */
+ lis r3,UART0_IO_BASE@h
+ ori r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_4K
+
+ /* xlat fields */
+ lis r4,UART0_PHYS_IO_BASE@h /* RPN depends on SoC */
+#ifndef CONFIG_440EP
+ ori r4,r4,0x0001 /* ERPN is 1 for second 4GB page */
+#endif
+
+ /* attrib fields */
+ li r5,0
+ ori r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_I | PPC44x_TLB_G)
+
+ li r0,0 /* TLB slot 0 */
+
+ tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */
+ tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */
+ tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */
+
+ /* Force context change */
+ isync
+#endif /* CONFIG_SERIAL_TEXT_DEBUG */
+
+ /* Establish the interrupt vector offsets */
+ SET_IVOR(0, CriticalInput);
+ SET_IVOR(1, MachineCheck);
+ SET_IVOR(2, DataStorage);
+ SET_IVOR(3, InstructionStorage);
+ SET_IVOR(4, ExternalInput);
+ SET_IVOR(5, Alignment);
+ SET_IVOR(6, Program);
+ SET_IVOR(7, FloatingPointUnavailable);
+ SET_IVOR(8, SystemCall);
+ SET_IVOR(9, AuxillaryProcessorUnavailable);
+ SET_IVOR(10, Decrementer);
+ SET_IVOR(11, FixedIntervalTimer);
+ SET_IVOR(12, WatchdogTimer);
+ SET_IVOR(13, DataTLBError);
+ SET_IVOR(14, InstructionTLBError);
+ SET_IVOR(15, Debug);
+
+ /* Establish the interrupt vector base */
+ lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */
+ mtspr SPRN_IVPR,r4
+
+#ifdef CONFIG_440EP
+ /* Clear DAPUIB flag in CCR0 (enable APU between CPU and FPU) */
+ mfspr r2,SPRN_CCR0
+ lis r3,0xffef
+ ori r3,r3,0xffff
+ and r2,r2,r3
+ mtspr SPRN_CCR0,r2
+ isync
+#endif
+
+ /*
+ * This is where the main kernel code starts.
+ */
+
+ /* ptr to current */
+ lis r2,init_task@h
+ ori r2,r2,init_task@l
+
+ /* ptr to current thread */
+ addi r4,r2,THREAD /* init task's THREAD */
+ mtspr SPRN_SPRG3,r4
+
+ /* stack */
+ lis r1,init_thread_union@h
+ ori r1,r1,init_thread_union@l
+ li r0,0
+ stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
+
+ bl early_init
+
+/*
+ * Decide what sort of machine this is and initialize the MMU.
+ */
+ mr r3,r31
+ mr r4,r30
+ mr r5,r29
+ mr r6,r28
+ mr r7,r27
+ bl machine_init
+ bl MMU_init
+
+ /* Setup PTE pointers for the Abatron bdiGDB */
+ lis r6, swapper_pg_dir@h
+ ori r6, r6, swapper_pg_dir@l
+ lis r5, abatron_pteptrs@h
+ ori r5, r5, abatron_pteptrs@l
+ lis r4, KERNELBASE@h
+ ori r4, r4, KERNELBASE@l
+ stw r5, 0(r4) /* Save abatron_pteptrs at a fixed location */
+ stw r6, 0(r5)
+
+ /* Let's move on */
+ lis r4,start_kernel@h
+ ori r4,r4,start_kernel@l
+ lis r3,MSR_KERNEL@h
+ ori r3,r3,MSR_KERNEL@l
+ mtspr SPRN_SRR0,r4
+ mtspr SPRN_SRR1,r3
+ rfi /* change context and jump to start_kernel */
+
+/*
+ * Interrupt vector entry code
+ *
+ * The Book E MMUs are always on so we don't need to handle
+ * interrupts in real mode as with previous PPC processors. In
+ * this case we handle interrupts in the kernel virtual address
+ * space.
+ *
+ * Interrupt vectors are dynamically placed relative to the
+ * interrupt prefix as determined by the address of interrupt_base.
+ * The interrupt vectors offsets are programmed using the labels
+ * for each interrupt vector entry.
+ *
+ * Interrupt vectors must be aligned on a 16 byte boundary.
+ * We align on a 32 byte cache line boundary for good measure.
+ */
+
+interrupt_base:
+ /* Critical Input Interrupt */
+ CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception)
+
+ /* Machine Check Interrupt */
+#ifdef CONFIG_440A
+ MCHECK_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
+#else
+ CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
+#endif
+
+ /* Data Storage Interrupt */
+ START_EXCEPTION(DataStorage)
+ mtspr SPRN_SPRG0, r10 /* Save some working registers */
+ mtspr SPRN_SPRG1, r11
+ mtspr SPRN_SPRG4W, r12
+ mtspr SPRN_SPRG5W, r13
+ mfcr r11
+ mtspr SPRN_SPRG7W, r11
+
+ /*
+ * Check if it was a store fault, if not then bail
+ * because a user tried to access a kernel or
+ * read-protected page. Otherwise, get the
+ * offending address and handle it.
+ */
+ mfspr r10, SPRN_ESR
+ andis. r10, r10, ESR_ST@h
+ beq 2f
+
+ mfspr r10, SPRN_DEAR /* Get faulting address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ lis r11, TASK_SIZE@h
+ cmplw r10, r11
+ blt+ 3f
+ lis r11, swapper_pg_dir@h
+ ori r11, r11, swapper_pg_dir@l
+
+ mfspr r12,SPRN_MMUCR
+ rlwinm r12,r12,0,0,23 /* Clear TID */
+
+ b 4f
+
+ /* Get the PGD for the current thread */
+3:
+ mfspr r11,SPRN_SPRG3
+ lwz r11,PGDIR(r11)
+
+ /* Load PID into MMUCR TID */
+ mfspr r12,SPRN_MMUCR /* Get MMUCR */
+ mfspr r13,SPRN_PID /* Get PID */
+ rlwimi r12,r13,0,24,31 /* Set TID */
+
+4:
+ mtspr SPRN_MMUCR,r12
+
+ rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */
+ lwzx r11, r12, r11 /* Get pgd/pmd entry */
+ rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */
+ beq 2f /* Bail if no table */
+
+ rlwimi r12, r10, 23, 20, 28 /* Compute pte address */
+ lwz r11, 4(r12) /* Get pte entry */
+
+ andi. r13, r11, _PAGE_RW /* Is it writeable? */
+ beq 2f /* Bail if not */
+
+ /* Update 'changed'.
+ */
+ ori r11, r11, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE
+ stw r11, 4(r12) /* Update Linux page table */
+
+ li r13, PPC44x_TLB_SR@l /* Set SR */
+ rlwimi r13, r11, 29, 29, 29 /* SX = _PAGE_HWEXEC */
+ rlwimi r13, r11, 0, 30, 30 /* SW = _PAGE_RW */
+ rlwimi r13, r11, 29, 28, 28 /* UR = _PAGE_USER */
+ rlwimi r12, r11, 31, 26, 26 /* (_PAGE_USER>>1)->r12 */
+ rlwimi r12, r11, 29, 30, 30 /* (_PAGE_USER>>3)->r12 */
+ and r12, r12, r11 /* HWEXEC/RW & USER */
+ rlwimi r13, r12, 0, 26, 26 /* UX = HWEXEC & USER */
+ rlwimi r13, r12, 3, 27, 27 /* UW = RW & USER */
+
+ rlwimi r11,r13,0,26,31 /* Insert static perms */
+
+ rlwinm r11,r11,0,20,15 /* Clear U0-U3 */
+
+ /* find the TLB index that caused the fault. It has to be here. */
+ tlbsx r10, 0, r10
+
+ tlbwe r11, r10, PPC44x_TLB_ATTRIB /* Write ATTRIB */
+
+ /* Done...restore registers and get out of here.
+ */
+ mfspr r11, SPRN_SPRG7R
+ mtcr r11
+ mfspr r13, SPRN_SPRG5R
+ mfspr r12, SPRN_SPRG4R
+
+ mfspr r11, SPRN_SPRG1
+ mfspr r10, SPRN_SPRG0
+ rfi /* Force context change */
+
+2:
+ /*
+ * The bailout. Restore registers to pre-exception conditions
+ * and call the heavyweights to help us out.
+ */
+ mfspr r11, SPRN_SPRG7R
+ mtcr r11
+ mfspr r13, SPRN_SPRG5R
+ mfspr r12, SPRN_SPRG4R
+
+ mfspr r11, SPRN_SPRG1
+ mfspr r10, SPRN_SPRG0
+ b data_access
+
+ /* Instruction Storage Interrupt */
+ INSTRUCTION_STORAGE_EXCEPTION
+
+ /* External Input Interrupt */
+ EXCEPTION(0x0500, ExternalInput, do_IRQ, EXC_XFER_LITE)
+
+ /* Alignment Interrupt */
+ ALIGNMENT_EXCEPTION
+
+ /* Program Interrupt */
+ PROGRAM_EXCEPTION
+
+ /* Floating Point Unavailable Interrupt */
+#ifdef CONFIG_PPC_FPU
+ FP_UNAVAILABLE_EXCEPTION
+#else
+ EXCEPTION(0x2010, FloatingPointUnavailable, unknown_exception, EXC_XFER_EE)
+#endif
+
+ /* System Call Interrupt */
+ START_EXCEPTION(SystemCall)
+ NORMAL_EXCEPTION_PROLOG
+ EXC_XFER_EE_LITE(0x0c00, DoSyscall)
+
+ /* Auxillary Processor Unavailable Interrupt */
+ EXCEPTION(0x2020, AuxillaryProcessorUnavailable, unknown_exception, EXC_XFER_EE)
+
+ /* Decrementer Interrupt */
+ DECREMENTER_EXCEPTION
+
+ /* Fixed Internal Timer Interrupt */
+ /* TODO: Add FIT support */
+ EXCEPTION(0x1010, FixedIntervalTimer, unknown_exception, EXC_XFER_EE)
+
+ /* Watchdog Timer Interrupt */
+ /* TODO: Add watchdog support */
+#ifdef CONFIG_BOOKE_WDT
+ CRITICAL_EXCEPTION(0x1020, WatchdogTimer, WatchdogException)
+#else
+ CRITICAL_EXCEPTION(0x1020, WatchdogTimer, unknown_exception)
+#endif
+
+ /* Data TLB Error Interrupt */
+ START_EXCEPTION(DataTLBError)
+ mtspr SPRN_SPRG0, r10 /* Save some working registers */
+ mtspr SPRN_SPRG1, r11
+ mtspr SPRN_SPRG4W, r12
+ mtspr SPRN_SPRG5W, r13
+ mfcr r11
+ mtspr SPRN_SPRG7W, r11
+ mfspr r10, SPRN_DEAR /* Get faulting address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ lis r11, TASK_SIZE@h
+ cmplw r10, r11
+ blt+ 3f
+ lis r11, swapper_pg_dir@h
+ ori r11, r11, swapper_pg_dir@l
+
+ mfspr r12,SPRN_MMUCR
+ rlwinm r12,r12,0,0,23 /* Clear TID */
+
+ b 4f
+
+ /* Get the PGD for the current thread */
+3:
+ mfspr r11,SPRN_SPRG3
+ lwz r11,PGDIR(r11)
+
+ /* Load PID into MMUCR TID */
+ mfspr r12,SPRN_MMUCR
+ mfspr r13,SPRN_PID /* Get PID */
+ rlwimi r12,r13,0,24,31 /* Set TID */
+
+4:
+ mtspr SPRN_MMUCR,r12
+
+ rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */
+ lwzx r11, r12, r11 /* Get pgd/pmd entry */
+ rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */
+ beq 2f /* Bail if no table */
+
+ rlwimi r12, r10, 23, 20, 28 /* Compute pte address */
+ lwz r11, 4(r12) /* Get pte entry */
+ andi. r13, r11, _PAGE_PRESENT /* Is the page present? */
+ beq 2f /* Bail if not present */
+
+ ori r11, r11, _PAGE_ACCESSED
+ stw r11, 4(r12)
+
+ /* Jump to common tlb load */
+ b finish_tlb_load
+
+2:
+ /* The bailout. Restore registers to pre-exception conditions
+ * and call the heavyweights to help us out.
+ */
+ mfspr r11, SPRN_SPRG7R
+ mtcr r11
+ mfspr r13, SPRN_SPRG5R
+ mfspr r12, SPRN_SPRG4R
+ mfspr r11, SPRN_SPRG1
+ mfspr r10, SPRN_SPRG0
+ b data_access
+
+ /* Instruction TLB Error Interrupt */
+ /*
+ * Nearly the same as above, except we get our
+ * information from different registers and bailout
+ * to a different point.
+ */
+ START_EXCEPTION(InstructionTLBError)
+ mtspr SPRN_SPRG0, r10 /* Save some working registers */
+ mtspr SPRN_SPRG1, r11
+ mtspr SPRN_SPRG4W, r12
+ mtspr SPRN_SPRG5W, r13
+ mfcr r11
+ mtspr SPRN_SPRG7W, r11
+ mfspr r10, SPRN_SRR0 /* Get faulting address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ lis r11, TASK_SIZE@h
+ cmplw r10, r11
+ blt+ 3f
+ lis r11, swapper_pg_dir@h
+ ori r11, r11, swapper_pg_dir@l
+
+ mfspr r12,SPRN_MMUCR
+ rlwinm r12,r12,0,0,23 /* Clear TID */
+
+ b 4f
+
+ /* Get the PGD for the current thread */
+3:
+ mfspr r11,SPRN_SPRG3
+ lwz r11,PGDIR(r11)
+
+ /* Load PID into MMUCR TID */
+ mfspr r12,SPRN_MMUCR
+ mfspr r13,SPRN_PID /* Get PID */
+ rlwimi r12,r13,0,24,31 /* Set TID */
+
+4:
+ mtspr SPRN_MMUCR,r12
+
+ rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */
+ lwzx r11, r12, r11 /* Get pgd/pmd entry */
+ rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */
+ beq 2f /* Bail if no table */
+
+ rlwimi r12, r10, 23, 20, 28 /* Compute pte address */
+ lwz r11, 4(r12) /* Get pte entry */
+ andi. r13, r11, _PAGE_PRESENT /* Is the page present? */
+ beq 2f /* Bail if not present */
+
+ ori r11, r11, _PAGE_ACCESSED
+ stw r11, 4(r12)
+
+ /* Jump to common TLB load point */
+ b finish_tlb_load
+
+2:
+ /* The bailout. Restore registers to pre-exception conditions
+ * and call the heavyweights to help us out.
+ */
+ mfspr r11, SPRN_SPRG7R
+ mtcr r11
+ mfspr r13, SPRN_SPRG5R
+ mfspr r12, SPRN_SPRG4R
+ mfspr r11, SPRN_SPRG1
+ mfspr r10, SPRN_SPRG0
+ b InstructionStorage
+
+ /* Debug Interrupt */
+ DEBUG_EXCEPTION
+
+/*
+ * Local functions
+ */
+ /*
+ * Data TLB exceptions will bail out to this point
+ * if they can't resolve the lightweight TLB fault.
+ */
+data_access:
+ NORMAL_EXCEPTION_PROLOG
+ mfspr r5,SPRN_ESR /* Grab the ESR, save it, pass arg3 */
+ stw r5,_ESR(r11)
+ mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */
+ EXC_XFER_EE_LITE(0x0300, handle_page_fault)
+
+/*
+
+ * Both the instruction and data TLB miss get to this
+ * point to load the TLB.
+ * r10 - EA of fault
+ * r11 - available to use
+ * r12 - Pointer to the 64-bit PTE
+ * r13 - available to use
+ * MMUCR - loaded with proper value when we get here
+ * Upon exit, we reload everything and RFI.
+ */
+finish_tlb_load:
+ /*
+ * We set execute, because we don't have the granularity to
+ * properly set this at the page level (Linux problem).
+ * If shared is set, we cause a zero PID->TID load.
+ * Many of these bits are software only. Bits we don't set
+ * here we (properly should) assume have the appropriate value.
+ */
+
+ /* Load the next available TLB index */
+ lis r13, tlb_44x_index@ha
+ lwz r13, tlb_44x_index@l(r13)
+ /* Load the TLB high watermark */
+ lis r11, tlb_44x_hwater@ha
+ lwz r11, tlb_44x_hwater@l(r11)
+
+ /* Increment, rollover, and store TLB index */
+ addi r13, r13, 1
+ cmpw 0, r13, r11 /* reserve entries */
+ ble 7f
+ li r13, 0
+7:
+ /* Store the next available TLB index */
+ lis r11, tlb_44x_index@ha
+ stw r13, tlb_44x_index@l(r11)
+
+ lwz r11, 0(r12) /* Get MS word of PTE */
+ lwz r12, 4(r12) /* Get LS word of PTE */
+ rlwimi r11, r12, 0, 0 , 19 /* Insert RPN */
+ tlbwe r11, r13, PPC44x_TLB_XLAT /* Write XLAT */
+
+ /*
+ * Create PAGEID. This is the faulting address,
+ * page size, and valid flag.
+ */
+ li r11, PPC44x_TLB_VALID | PPC44x_TLB_4K
+ rlwimi r10, r11, 0, 20, 31 /* Insert valid and page size */
+ tlbwe r10, r13, PPC44x_TLB_PAGEID /* Write PAGEID */
+
+ li r10, PPC44x_TLB_SR@l /* Set SR */
+ rlwimi r10, r12, 0, 30, 30 /* Set SW = _PAGE_RW */
+ rlwimi r10, r12, 29, 29, 29 /* SX = _PAGE_HWEXEC */
+ rlwimi r10, r12, 29, 28, 28 /* UR = _PAGE_USER */
+ rlwimi r11, r12, 31, 26, 26 /* (_PAGE_USER>>1)->r12 */
+ and r11, r12, r11 /* HWEXEC & USER */
+ rlwimi r10, r11, 0, 26, 26 /* UX = HWEXEC & USER */
+
+ rlwimi r12, r10, 0, 26, 31 /* Insert static perms */
+ rlwinm r12, r12, 0, 20, 15 /* Clear U0-U3 */
+ tlbwe r12, r13, PPC44x_TLB_ATTRIB /* Write ATTRIB */
+
+ /* Done...restore registers and get out of here.
+ */
+ mfspr r11, SPRN_SPRG7R
+ mtcr r11
+ mfspr r13, SPRN_SPRG5R
+ mfspr r12, SPRN_SPRG4R
+ mfspr r11, SPRN_SPRG1
+ mfspr r10, SPRN_SPRG0
+ rfi /* Force context change */
+
+/*
+ * Global functions
+ */
+
+/*
+ * extern void giveup_altivec(struct task_struct *prev)
+ *
+ * The 44x core does not have an AltiVec unit.
+ */
+_GLOBAL(giveup_altivec)
+ blr
+
+/*
+ * extern void giveup_fpu(struct task_struct *prev)
+ *
+ * The 44x core does not have an FPU.
+ */
+#ifndef CONFIG_PPC_FPU
+_GLOBAL(giveup_fpu)
+ blr
+#endif
+
+/*
+ * extern void abort(void)
+ *
+ * At present, this routine just applies a system reset.
+ */
+_GLOBAL(abort)
+ mfspr r13,SPRN_DBCR0
+ oris r13,r13,DBCR0_RST_SYSTEM@h
+ mtspr SPRN_DBCR0,r13
+
+_GLOBAL(set_context)
+
+#ifdef CONFIG_BDI_SWITCH
+ /* Context switch the PTE pointer for the Abatron BDI2000.
+ * The PGDIR is the second parameter.
+ */
+ lis r5, abatron_pteptrs@h
+ ori r5, r5, abatron_pteptrs@l
+ stw r4, 0x4(r5)
+#endif
+ mtspr SPRN_PID,r3
+ isync /* Force context change */
+ blr
+
+/*
+ * We put a few things here that have to be page-aligned. This stuff
+ * goes at the beginning of the data segment, which is page-aligned.
+ */
+ .data
+ .align 12
+ .globl sdata
+sdata:
+ .globl empty_zero_page
+empty_zero_page:
+ .space 4096
+
+/*
+ * To support >32-bit physical addresses, we use an 8KB pgdir.
+ */
+ .globl swapper_pg_dir
+swapper_pg_dir:
+ .space 8192
+
+/* Reserved 4k for the critical exception stack & 4k for the machine
+ * check stack per CPU for kernel mode exceptions */
+ .section .bss
+ .align 12
+exception_stack_bottom:
+ .space BOOKE_EXCEPTION_STACK_SIZE
+ .globl exception_stack_top
+exception_stack_top:
+
+/*
+ * This space gets a copy of optional info passed to us by the bootstrap
+ * which is used to pass parameters into the kernel like root=/dev/sda1, etc.
+ */
+ .globl cmd_line
+cmd_line:
+ .space 512
+
+/*
+ * Room for two PTE pointers, usually the kernel and current user pointers
+ * to their respective root page table.
+ */
+abatron_pteptrs:
+ .space 8
diff --git a/arch/powerpc/kernel/head_4xx.S b/arch/powerpc/kernel/head_4xx.S
new file mode 100644
index 000000000000..2590e97f5539
--- /dev/null
+++ b/arch/powerpc/kernel/head_4xx.S
@@ -0,0 +1,1022 @@
+/*
+ * Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org>
+ * Initial PowerPC version.
+ * Copyright (c) 1996 Cort Dougan <cort@cs.nmt.edu>
+ * Rewritten for PReP
+ * Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
+ * Low-level exception handers, MMU support, and rewrite.
+ * Copyright (c) 1997 Dan Malek <dmalek@jlc.net>
+ * PowerPC 8xx modifications.
+ * Copyright (c) 1998-1999 TiVo, Inc.
+ * PowerPC 403GCX modifications.
+ * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ * PowerPC 403GCX/405GP modifications.
+ * Copyright 2000 MontaVista Software Inc.
+ * PPC405 modifications
+ * PowerPC 403GCX/405GP modifications.
+ * Author: MontaVista Software, Inc.
+ * frank_rowand@mvista.com or source@mvista.com
+ * debbie_chu@mvista.com
+ *
+ *
+ * Module name: head_4xx.S
+ *
+ * Description:
+ * Kernel execution entry point code.
+ *
+ * This program is free software; you can redistribute 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/config.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/ibm4xx.h>
+#include <asm/cputable.h>
+#include <asm/thread_info.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+
+/* As with the other PowerPC ports, it is expected that when code
+ * execution begins here, the following registers contain valid, yet
+ * optional, information:
+ *
+ * r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.)
+ * r4 - Starting address of the init RAM disk
+ * r5 - Ending address of the init RAM disk
+ * r6 - Start of kernel command line string (e.g. "mem=96m")
+ * r7 - End of kernel command line string
+ *
+ * This is all going to change RSN when we add bi_recs....... -- Dan
+ */
+ .text
+_GLOBAL(_stext)
+_GLOBAL(_start)
+
+ /* Save parameters we are passed.
+ */
+ mr r31,r3
+ mr r30,r4
+ mr r29,r5
+ mr r28,r6
+ mr r27,r7
+
+ /* We have to turn on the MMU right away so we get cache modes
+ * set correctly.
+ */
+ bl initial_mmu
+
+/* We now have the lower 16 Meg mapped into TLB entries, and the caches
+ * ready to work.
+ */
+turn_on_mmu:
+ lis r0,MSR_KERNEL@h
+ ori r0,r0,MSR_KERNEL@l
+ mtspr SPRN_SRR1,r0
+ lis r0,start_here@h
+ ori r0,r0,start_here@l
+ mtspr SPRN_SRR0,r0
+ SYNC
+ rfi /* enables MMU */
+ b . /* prevent prefetch past rfi */
+
+/*
+ * This area is used for temporarily saving registers during the
+ * critical exception prolog.
+ */
+ . = 0xc0
+crit_save:
+_GLOBAL(crit_r10)
+ .space 4
+_GLOBAL(crit_r11)
+ .space 4
+
+/*
+ * Exception vector entry code. This code runs with address translation
+ * turned off (i.e. using physical addresses). We assume SPRG3 has the
+ * physical address of the current task thread_struct.
+ * Note that we have to have decremented r1 before we write to any fields
+ * of the exception frame, since a critical interrupt could occur at any
+ * time, and it will write to the area immediately below the current r1.
+ */
+#define NORMAL_EXCEPTION_PROLOG \
+ mtspr SPRN_SPRG0,r10; /* save two registers to work with */\
+ mtspr SPRN_SPRG1,r11; \
+ mtspr SPRN_SPRG2,r1; \
+ mfcr r10; /* save CR in r10 for now */\
+ mfspr r11,SPRN_SRR1; /* check whether user or kernel */\
+ andi. r11,r11,MSR_PR; \
+ beq 1f; \
+ mfspr r1,SPRN_SPRG3; /* if from user, start at top of */\
+ lwz r1,THREAD_INFO-THREAD(r1); /* this thread's kernel stack */\
+ addi r1,r1,THREAD_SIZE; \
+1: subi r1,r1,INT_FRAME_SIZE; /* Allocate an exception frame */\
+ tophys(r11,r1); \
+ stw r10,_CCR(r11); /* save various registers */\
+ stw r12,GPR12(r11); \
+ stw r9,GPR9(r11); \
+ mfspr r10,SPRN_SPRG0; \
+ stw r10,GPR10(r11); \
+ mfspr r12,SPRN_SPRG1; \
+ stw r12,GPR11(r11); \
+ mflr r10; \
+ stw r10,_LINK(r11); \
+ mfspr r10,SPRN_SPRG2; \
+ mfspr r12,SPRN_SRR0; \
+ stw r10,GPR1(r11); \
+ mfspr r9,SPRN_SRR1; \
+ stw r10,0(r11); \
+ rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\
+ stw r0,GPR0(r11); \
+ SAVE_4GPRS(3, r11); \
+ SAVE_2GPRS(7, r11)
+
+/*
+ * Exception prolog for critical exceptions. This is a little different
+ * from the normal exception prolog above since a critical exception
+ * can potentially occur at any point during normal exception processing.
+ * Thus we cannot use the same SPRG registers as the normal prolog above.
+ * Instead we use a couple of words of memory at low physical addresses.
+ * This is OK since we don't support SMP on these processors.
+ */
+#define CRITICAL_EXCEPTION_PROLOG \
+ stw r10,crit_r10@l(0); /* save two registers to work with */\
+ stw r11,crit_r11@l(0); \
+ mfcr r10; /* save CR in r10 for now */\
+ mfspr r11,SPRN_SRR3; /* check whether user or kernel */\
+ andi. r11,r11,MSR_PR; \
+ lis r11,critical_stack_top@h; \
+ ori r11,r11,critical_stack_top@l; \
+ beq 1f; \
+ /* COMING FROM USER MODE */ \
+ mfspr r11,SPRN_SPRG3; /* if from user, start at top of */\
+ lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
+ addi r11,r11,THREAD_SIZE; \
+1: subi r11,r11,INT_FRAME_SIZE; /* Allocate an exception frame */\
+ tophys(r11,r11); \
+ stw r10,_CCR(r11); /* save various registers */\
+ stw r12,GPR12(r11); \
+ stw r9,GPR9(r11); \
+ mflr r10; \
+ stw r10,_LINK(r11); \
+ mfspr r12,SPRN_DEAR; /* save DEAR and ESR in the frame */\
+ stw r12,_DEAR(r11); /* since they may have had stuff */\
+ mfspr r9,SPRN_ESR; /* in them at the point where the */\
+ stw r9,_ESR(r11); /* exception was taken */\
+ mfspr r12,SPRN_SRR2; \
+ stw r1,GPR1(r11); \
+ mfspr r9,SPRN_SRR3; \
+ stw r1,0(r11); \
+ tovirt(r1,r11); \
+ rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\
+ stw r0,GPR0(r11); \
+ SAVE_4GPRS(3, r11); \
+ SAVE_2GPRS(7, r11)
+
+ /*
+ * State at this point:
+ * r9 saved in stack frame, now saved SRR3 & ~MSR_WE
+ * r10 saved in crit_r10 and in stack frame, trashed
+ * r11 saved in crit_r11 and in stack frame,
+ * now phys stack/exception frame pointer
+ * r12 saved in stack frame, now saved SRR2
+ * CR saved in stack frame, CR0.EQ = !SRR3.PR
+ * LR, DEAR, ESR in stack frame
+ * r1 saved in stack frame, now virt stack/excframe pointer
+ * r0, r3-r8 saved in stack frame
+ */
+
+/*
+ * Exception vectors.
+ */
+#define START_EXCEPTION(n, label) \
+ . = n; \
+label:
+
+#define EXCEPTION(n, label, hdlr, xfer) \
+ START_EXCEPTION(n, label); \
+ NORMAL_EXCEPTION_PROLOG; \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ xfer(n, hdlr)
+
+#define CRITICAL_EXCEPTION(n, label, hdlr) \
+ START_EXCEPTION(n, label); \
+ CRITICAL_EXCEPTION_PROLOG; \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
+ NOCOPY, crit_transfer_to_handler, \
+ ret_from_crit_exc)
+
+#define EXC_XFER_TEMPLATE(hdlr, trap, msr, copyee, tfer, ret) \
+ li r10,trap; \
+ stw r10,_TRAP(r11); \
+ lis r10,msr@h; \
+ ori r10,r10,msr@l; \
+ copyee(r10, r9); \
+ bl tfer; \
+ .long hdlr; \
+ .long ret
+
+#define COPY_EE(d, s) rlwimi d,s,0,16,16
+#define NOCOPY(d, s)
+
+#define EXC_XFER_STD(n, hdlr) \
+ EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, NOCOPY, transfer_to_handler_full, \
+ ret_from_except_full)
+
+#define EXC_XFER_LITE(n, hdlr) \
+ EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, NOCOPY, transfer_to_handler, \
+ ret_from_except)
+
+#define EXC_XFER_EE(n, hdlr) \
+ EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, COPY_EE, transfer_to_handler_full, \
+ ret_from_except_full)
+
+#define EXC_XFER_EE_LITE(n, hdlr) \
+ EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, COPY_EE, transfer_to_handler, \
+ ret_from_except)
+
+
+/*
+ * 0x0100 - Critical Interrupt Exception
+ */
+ CRITICAL_EXCEPTION(0x0100, CriticalInterrupt, unknown_exception)
+
+/*
+ * 0x0200 - Machine Check Exception
+ */
+ CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
+
+/*
+ * 0x0300 - Data Storage Exception
+ * This happens for just a few reasons. U0 set (but we don't do that),
+ * or zone protection fault (user violation, write to protected page).
+ * If this is just an update of modified status, we do that quickly
+ * and exit. Otherwise, we call heavywight functions to do the work.
+ */
+ START_EXCEPTION(0x0300, DataStorage)
+ mtspr SPRN_SPRG0, r10 /* Save some working registers */
+ mtspr SPRN_SPRG1, r11
+#ifdef CONFIG_403GCX
+ stw r12, 0(r0)
+ stw r9, 4(r0)
+ mfcr r11
+ mfspr r12, SPRN_PID
+ stw r11, 8(r0)
+ stw r12, 12(r0)
+#else
+ mtspr SPRN_SPRG4, r12
+ mtspr SPRN_SPRG5, r9
+ mfcr r11
+ mfspr r12, SPRN_PID
+ mtspr SPRN_SPRG7, r11
+ mtspr SPRN_SPRG6, r12
+#endif
+
+ /* First, check if it was a zone fault (which means a user
+ * tried to access a kernel or read-protected page - always
+ * a SEGV). All other faults here must be stores, so no
+ * need to check ESR_DST as well. */
+ mfspr r10, SPRN_ESR
+ andis. r10, r10, ESR_DIZ@h
+ bne 2f
+
+ mfspr r10, SPRN_DEAR /* Get faulting address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ lis r11, TASK_SIZE@h
+ cmplw r10, r11
+ blt+ 3f
+ lis r11, swapper_pg_dir@h
+ ori r11, r11, swapper_pg_dir@l
+ li r9, 0
+ mtspr SPRN_PID, r9 /* TLB will have 0 TID */
+ b 4f
+
+ /* Get the PGD for the current thread.
+ */
+3:
+ mfspr r11,SPRN_SPRG3
+ lwz r11,PGDIR(r11)
+4:
+ tophys(r11, r11)
+ rlwimi r11, r10, 12, 20, 29 /* Create L1 (pgdir/pmd) address */
+ lwz r11, 0(r11) /* Get L1 entry */
+ rlwinm. r12, r11, 0, 0, 19 /* Extract L2 (pte) base address */
+ beq 2f /* Bail if no table */
+
+ rlwimi r12, r10, 22, 20, 29 /* Compute PTE address */
+ lwz r11, 0(r12) /* Get Linux PTE */
+
+ andi. r9, r11, _PAGE_RW /* Is it writeable? */
+ beq 2f /* Bail if not */
+
+ /* Update 'changed'.
+ */
+ ori r11, r11, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE
+ stw r11, 0(r12) /* Update Linux page table */
+
+ /* Most of the Linux PTE is ready to load into the TLB LO.
+ * We set ZSEL, where only the LS-bit determines user access.
+ * We set execute, because we don't have the granularity to
+ * properly set this at the page level (Linux problem).
+ * If shared is set, we cause a zero PID->TID load.
+ * Many of these bits are software only. Bits we don't set
+ * here we (properly should) assume have the appropriate value.
+ */
+ li r12, 0x0ce2
+ andc r11, r11, r12 /* Make sure 20, 21 are zero */
+
+ /* find the TLB index that caused the fault. It has to be here.
+ */
+ tlbsx r9, 0, r10
+
+ tlbwe r11, r9, TLB_DATA /* Load TLB LO */
+
+ /* Done...restore registers and get out of here.
+ */
+#ifdef CONFIG_403GCX
+ lwz r12, 12(r0)
+ lwz r11, 8(r0)
+ mtspr SPRN_PID, r12
+ mtcr r11
+ lwz r9, 4(r0)
+ lwz r12, 0(r0)
+#else
+ mfspr r12, SPRN_SPRG6
+ mfspr r11, SPRN_SPRG7
+ mtspr SPRN_PID, r12
+ mtcr r11
+ mfspr r9, SPRN_SPRG5
+ mfspr r12, SPRN_SPRG4
+#endif
+ mfspr r11, SPRN_SPRG1
+ mfspr r10, SPRN_SPRG0
+ PPC405_ERR77_SYNC
+ rfi /* Should sync shadow TLBs */
+ b . /* prevent prefetch past rfi */
+
+2:
+ /* The bailout. Restore registers to pre-exception conditions
+ * and call the heavyweights to help us out.
+ */
+#ifdef CONFIG_403GCX
+ lwz r12, 12(r0)
+ lwz r11, 8(r0)
+ mtspr SPRN_PID, r12
+ mtcr r11
+ lwz r9, 4(r0)
+ lwz r12, 0(r0)
+#else
+ mfspr r12, SPRN_SPRG6
+ mfspr r11, SPRN_SPRG7
+ mtspr SPRN_PID, r12
+ mtcr r11
+ mfspr r9, SPRN_SPRG5
+ mfspr r12, SPRN_SPRG4
+#endif
+ mfspr r11, SPRN_SPRG1
+ mfspr r10, SPRN_SPRG0
+ b DataAccess
+
+/*
+ * 0x0400 - Instruction Storage Exception
+ * This is caused by a fetch from non-execute or guarded pages.
+ */
+ START_EXCEPTION(0x0400, InstructionAccess)
+ NORMAL_EXCEPTION_PROLOG
+ mr r4,r12 /* Pass SRR0 as arg2 */
+ li r5,0 /* Pass zero as arg3 */
+ EXC_XFER_EE_LITE(0x400, handle_page_fault)
+
+/* 0x0500 - External Interrupt Exception */
+ EXCEPTION(0x0500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
+
+/* 0x0600 - Alignment Exception */
+ START_EXCEPTION(0x0600, Alignment)
+ NORMAL_EXCEPTION_PROLOG
+ mfspr r4,SPRN_DEAR /* Grab the DEAR and save it */
+ stw r4,_DEAR(r11)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ EXC_XFER_EE(0x600, alignment_exception)
+
+/* 0x0700 - Program Exception */
+ START_EXCEPTION(0x0700, ProgramCheck)
+ NORMAL_EXCEPTION_PROLOG
+ mfspr r4,SPRN_ESR /* Grab the ESR and save it */
+ stw r4,_ESR(r11)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ EXC_XFER_STD(0x700, program_check_exception)
+
+ EXCEPTION(0x0800, Trap_08, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x0900, Trap_09, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x0A00, Trap_0A, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x0B00, Trap_0B, unknown_exception, EXC_XFER_EE)
+
+/* 0x0C00 - System Call Exception */
+ START_EXCEPTION(0x0C00, SystemCall)
+ NORMAL_EXCEPTION_PROLOG
+ EXC_XFER_EE_LITE(0xc00, DoSyscall)
+
+ EXCEPTION(0x0D00, Trap_0D, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x0E00, Trap_0E, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x0F00, Trap_0F, unknown_exception, EXC_XFER_EE)
+
+/* 0x1000 - Programmable Interval Timer (PIT) Exception */
+ START_EXCEPTION(0x1000, Decrementer)
+ NORMAL_EXCEPTION_PROLOG
+ lis r0,TSR_PIS@h
+ mtspr SPRN_TSR,r0 /* Clear the PIT exception */
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ EXC_XFER_LITE(0x1000, timer_interrupt)
+
+#if 0
+/* NOTE:
+ * FIT and WDT handlers are not implemented yet.
+ */
+
+/* 0x1010 - Fixed Interval Timer (FIT) Exception
+*/
+ STND_EXCEPTION(0x1010, FITException, unknown_exception)
+
+/* 0x1020 - Watchdog Timer (WDT) Exception
+*/
+#ifdef CONFIG_BOOKE_WDT
+ CRITICAL_EXCEPTION(0x1020, WDTException, WatchdogException)
+#else
+ CRITICAL_EXCEPTION(0x1020, WDTException, unknown_exception)
+#endif
+#endif
+
+/* 0x1100 - Data TLB Miss Exception
+ * As the name implies, translation is not in the MMU, so search the
+ * page tables and fix it. The only purpose of this function is to
+ * load TLB entries from the page table if they exist.
+ */
+ START_EXCEPTION(0x1100, DTLBMiss)
+ mtspr SPRN_SPRG0, r10 /* Save some working registers */
+ mtspr SPRN_SPRG1, r11
+#ifdef CONFIG_403GCX
+ stw r12, 0(r0)
+ stw r9, 4(r0)
+ mfcr r11
+ mfspr r12, SPRN_PID
+ stw r11, 8(r0)
+ stw r12, 12(r0)
+#else
+ mtspr SPRN_SPRG4, r12
+ mtspr SPRN_SPRG5, r9
+ mfcr r11
+ mfspr r12, SPRN_PID
+ mtspr SPRN_SPRG7, r11
+ mtspr SPRN_SPRG6, r12
+#endif
+ mfspr r10, SPRN_DEAR /* Get faulting address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ lis r11, TASK_SIZE@h
+ cmplw r10, r11
+ blt+ 3f
+ lis r11, swapper_pg_dir@h
+ ori r11, r11, swapper_pg_dir@l
+ li r9, 0
+ mtspr SPRN_PID, r9 /* TLB will have 0 TID */
+ b 4f
+
+ /* Get the PGD for the current thread.
+ */
+3:
+ mfspr r11,SPRN_SPRG3
+ lwz r11,PGDIR(r11)
+4:
+ tophys(r11, r11)
+ rlwimi r11, r10, 12, 20, 29 /* Create L1 (pgdir/pmd) address */
+ lwz r12, 0(r11) /* Get L1 entry */
+ andi. r9, r12, _PMD_PRESENT /* Check if it points to a PTE page */
+ beq 2f /* Bail if no table */
+
+ rlwimi r12, r10, 22, 20, 29 /* Compute PTE address */
+ lwz r11, 0(r12) /* Get Linux PTE */
+ andi. r9, r11, _PAGE_PRESENT
+ beq 5f
+
+ ori r11, r11, _PAGE_ACCESSED
+ stw r11, 0(r12)
+
+ /* Create TLB tag. This is the faulting address plus a static
+ * set of bits. These are size, valid, E, U0.
+ */
+ li r12, 0x00c0
+ rlwimi r10, r12, 0, 20, 31
+
+ b finish_tlb_load
+
+2: /* Check for possible large-page pmd entry */
+ rlwinm. r9, r12, 2, 22, 24
+ beq 5f
+
+ /* Create TLB tag. This is the faulting address, plus a static
+ * set of bits (valid, E, U0) plus the size from the PMD.
+ */
+ ori r9, r9, 0x40
+ rlwimi r10, r9, 0, 20, 31
+ mr r11, r12
+
+ b finish_tlb_load
+
+5:
+ /* The bailout. Restore registers to pre-exception conditions
+ * and call the heavyweights to help us out.
+ */
+#ifdef CONFIG_403GCX
+ lwz r12, 12(r0)
+ lwz r11, 8(r0)
+ mtspr SPRN_PID, r12
+ mtcr r11
+ lwz r9, 4(r0)
+ lwz r12, 0(r0)
+#else
+ mfspr r12, SPRN_SPRG6
+ mfspr r11, SPRN_SPRG7
+ mtspr SPRN_PID, r12
+ mtcr r11
+ mfspr r9, SPRN_SPRG5
+ mfspr r12, SPRN_SPRG4
+#endif
+ mfspr r11, SPRN_SPRG1
+ mfspr r10, SPRN_SPRG0
+ b DataAccess
+
+/* 0x1200 - Instruction TLB Miss Exception
+ * Nearly the same as above, except we get our information from different
+ * registers and bailout to a different point.
+ */
+ START_EXCEPTION(0x1200, ITLBMiss)
+ mtspr SPRN_SPRG0, r10 /* Save some working registers */
+ mtspr SPRN_SPRG1, r11
+#ifdef CONFIG_403GCX
+ stw r12, 0(r0)
+ stw r9, 4(r0)
+ mfcr r11
+ mfspr r12, SPRN_PID
+ stw r11, 8(r0)
+ stw r12, 12(r0)
+#else
+ mtspr SPRN_SPRG4, r12
+ mtspr SPRN_SPRG5, r9
+ mfcr r11
+ mfspr r12, SPRN_PID
+ mtspr SPRN_SPRG7, r11
+ mtspr SPRN_SPRG6, r12
+#endif
+ mfspr r10, SPRN_SRR0 /* Get faulting address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ lis r11, TASK_SIZE@h
+ cmplw r10, r11
+ blt+ 3f
+ lis r11, swapper_pg_dir@h
+ ori r11, r11, swapper_pg_dir@l
+ li r9, 0
+ mtspr SPRN_PID, r9 /* TLB will have 0 TID */
+ b 4f
+
+ /* Get the PGD for the current thread.
+ */
+3:
+ mfspr r11,SPRN_SPRG3
+ lwz r11,PGDIR(r11)
+4:
+ tophys(r11, r11)
+ rlwimi r11, r10, 12, 20, 29 /* Create L1 (pgdir/pmd) address */
+ lwz r12, 0(r11) /* Get L1 entry */
+ andi. r9, r12, _PMD_PRESENT /* Check if it points to a PTE page */
+ beq 2f /* Bail if no table */
+
+ rlwimi r12, r10, 22, 20, 29 /* Compute PTE address */
+ lwz r11, 0(r12) /* Get Linux PTE */
+ andi. r9, r11, _PAGE_PRESENT
+ beq 5f
+
+ ori r11, r11, _PAGE_ACCESSED
+ stw r11, 0(r12)
+
+ /* Create TLB tag. This is the faulting address plus a static
+ * set of bits. These are size, valid, E, U0.
+ */
+ li r12, 0x00c0
+ rlwimi r10, r12, 0, 20, 31
+
+ b finish_tlb_load
+
+2: /* Check for possible large-page pmd entry */
+ rlwinm. r9, r12, 2, 22, 24
+ beq 5f
+
+ /* Create TLB tag. This is the faulting address, plus a static
+ * set of bits (valid, E, U0) plus the size from the PMD.
+ */
+ ori r9, r9, 0x40
+ rlwimi r10, r9, 0, 20, 31
+ mr r11, r12
+
+ b finish_tlb_load
+
+5:
+ /* The bailout. Restore registers to pre-exception conditions
+ * and call the heavyweights to help us out.
+ */
+#ifdef CONFIG_403GCX
+ lwz r12, 12(r0)
+ lwz r11, 8(r0)
+ mtspr SPRN_PID, r12
+ mtcr r11
+ lwz r9, 4(r0)
+ lwz r12, 0(r0)
+#else
+ mfspr r12, SPRN_SPRG6
+ mfspr r11, SPRN_SPRG7
+ mtspr SPRN_PID, r12
+ mtcr r11
+ mfspr r9, SPRN_SPRG5
+ mfspr r12, SPRN_SPRG4
+#endif
+ mfspr r11, SPRN_SPRG1
+ mfspr r10, SPRN_SPRG0
+ b InstructionAccess
+
+ EXCEPTION(0x1300, Trap_13, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1400, Trap_14, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE)
+#ifdef CONFIG_IBM405_ERR51
+ /* 405GP errata 51 */
+ START_EXCEPTION(0x1700, Trap_17)
+ b DTLBMiss
+#else
+ EXCEPTION(0x1700, Trap_17, unknown_exception, EXC_XFER_EE)
+#endif
+ EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1A00, Trap_1A, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1B00, Trap_1B, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1C00, Trap_1C, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1D00, Trap_1D, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1E00, Trap_1E, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1F00, Trap_1F, unknown_exception, EXC_XFER_EE)
+
+/* Check for a single step debug exception while in an exception
+ * handler before state has been saved. This is to catch the case
+ * where an instruction that we are trying to single step causes
+ * an exception (eg ITLB/DTLB miss) and thus the first instruction of
+ * the exception handler generates a single step debug exception.
+ *
+ * If we get a debug trap on the first instruction of an exception handler,
+ * we reset the MSR_DE in the _exception handler's_ MSR (the debug trap is
+ * a critical exception, so we are using SPRN_CSRR1 to manipulate the MSR).
+ * The exception handler was handling a non-critical interrupt, so it will
+ * save (and later restore) the MSR via SPRN_SRR1, which will still have
+ * the MSR_DE bit set.
+ */
+ /* 0x2000 - Debug Exception */
+ START_EXCEPTION(0x2000, DebugTrap)
+ CRITICAL_EXCEPTION_PROLOG
+
+ /*
+ * If this is a single step or branch-taken exception in an
+ * exception entry sequence, it was probably meant to apply to
+ * the code where the exception occurred (since exception entry
+ * doesn't turn off DE automatically). We simulate the effect
+ * of turning off DE on entry to an exception handler by turning
+ * off DE in the SRR3 value and clearing the debug status.
+ */
+ mfspr r10,SPRN_DBSR /* check single-step/branch taken */
+ andis. r10,r10,DBSR_IC@h
+ beq+ 2f
+
+ andi. r10,r9,MSR_IR|MSR_PR /* check supervisor + MMU off */
+ beq 1f /* branch and fix it up */
+
+ mfspr r10,SPRN_SRR2 /* Faulting instruction address */
+ cmplwi r10,0x2100
+ bgt+ 2f /* address above exception vectors */
+
+ /* here it looks like we got an inappropriate debug exception. */
+1: rlwinm r9,r9,0,~MSR_DE /* clear DE in the SRR3 value */
+ lis r10,DBSR_IC@h /* clear the IC event */
+ mtspr SPRN_DBSR,r10
+ /* restore state and get out */
+ lwz r10,_CCR(r11)
+ lwz r0,GPR0(r11)
+ lwz r1,GPR1(r11)
+ mtcrf 0x80,r10
+ mtspr SPRN_SRR2,r12
+ mtspr SPRN_SRR3,r9
+ lwz r9,GPR9(r11)
+ lwz r12,GPR12(r11)
+ lwz r10,crit_r10@l(0)
+ lwz r11,crit_r11@l(0)
+ PPC405_ERR77_SYNC
+ rfci
+ b .
+
+ /* continue normal handling for a critical exception... */
+2: mfspr r4,SPRN_DBSR
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ EXC_XFER_TEMPLATE(DebugException, 0x2002, \
+ (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
+ NOCOPY, crit_transfer_to_handler, ret_from_crit_exc)
+
+/*
+ * The other Data TLB exceptions bail out to this point
+ * if they can't resolve the lightweight TLB fault.
+ */
+DataAccess:
+ NORMAL_EXCEPTION_PROLOG
+ mfspr r5,SPRN_ESR /* Grab the ESR, save it, pass arg3 */
+ stw r5,_ESR(r11)
+ mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */
+ EXC_XFER_EE_LITE(0x300, handle_page_fault)
+
+/* Other PowerPC processors, namely those derived from the 6xx-series
+ * have vectors from 0x2100 through 0x2F00 defined, but marked as reserved.
+ * However, for the 4xx-series processors these are neither defined nor
+ * reserved.
+ */
+
+ /* Damn, I came up one instruction too many to fit into the
+ * exception space :-). Both the instruction and data TLB
+ * miss get to this point to load the TLB.
+ * r10 - TLB_TAG value
+ * r11 - Linux PTE
+ * r12, r9 - avilable to use
+ * PID - loaded with proper value when we get here
+ * Upon exit, we reload everything and RFI.
+ * Actually, it will fit now, but oh well.....a common place
+ * to load the TLB.
+ */
+tlb_4xx_index:
+ .long 0
+finish_tlb_load:
+ /* load the next available TLB index.
+ */
+ lwz r9, tlb_4xx_index@l(0)
+ addi r9, r9, 1
+ andi. r9, r9, (PPC4XX_TLB_SIZE-1)
+ stw r9, tlb_4xx_index@l(0)
+
+6:
+ /*
+ * Clear out the software-only bits in the PTE to generate the
+ * TLB_DATA value. These are the bottom 2 bits of the RPM, the
+ * top 3 bits of the zone field, and M.
+ */
+ li r12, 0x0ce2
+ andc r11, r11, r12
+
+ tlbwe r11, r9, TLB_DATA /* Load TLB LO */
+ tlbwe r10, r9, TLB_TAG /* Load TLB HI */
+
+ /* Done...restore registers and get out of here.
+ */
+#ifdef CONFIG_403GCX
+ lwz r12, 12(r0)
+ lwz r11, 8(r0)
+ mtspr SPRN_PID, r12
+ mtcr r11
+ lwz r9, 4(r0)
+ lwz r12, 0(r0)
+#else
+ mfspr r12, SPRN_SPRG6
+ mfspr r11, SPRN_SPRG7
+ mtspr SPRN_PID, r12
+ mtcr r11
+ mfspr r9, SPRN_SPRG5
+ mfspr r12, SPRN_SPRG4
+#endif
+ mfspr r11, SPRN_SPRG1
+ mfspr r10, SPRN_SPRG0
+ PPC405_ERR77_SYNC
+ rfi /* Should sync shadow TLBs */
+ b . /* prevent prefetch past rfi */
+
+/* extern void giveup_fpu(struct task_struct *prev)
+ *
+ * The PowerPC 4xx family of processors do not have an FPU, so this just
+ * returns.
+ */
+_GLOBAL(giveup_fpu)
+ blr
+
+/* This is where the main kernel code starts.
+ */
+start_here:
+
+ /* ptr to current */
+ lis r2,init_task@h
+ ori r2,r2,init_task@l
+
+ /* ptr to phys current thread */
+ tophys(r4,r2)
+ addi r4,r4,THREAD /* init task's THREAD */
+ mtspr SPRN_SPRG3,r4
+
+ /* stack */
+ lis r1,init_thread_union@ha
+ addi r1,r1,init_thread_union@l
+ li r0,0
+ stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
+
+ bl early_init /* We have to do this with MMU on */
+
+/*
+ * Decide what sort of machine this is and initialize the MMU.
+ */
+ mr r3,r31
+ mr r4,r30
+ mr r5,r29
+ mr r6,r28
+ mr r7,r27
+ bl machine_init
+ bl MMU_init
+
+/* Go back to running unmapped so we can load up new values
+ * and change to using our exception vectors.
+ * On the 4xx, all we have to do is invalidate the TLB to clear
+ * the old 16M byte TLB mappings.
+ */
+ lis r4,2f@h
+ ori r4,r4,2f@l
+ tophys(r4,r4)
+ lis r3,(MSR_KERNEL & ~(MSR_IR|MSR_DR))@h
+ ori r3,r3,(MSR_KERNEL & ~(MSR_IR|MSR_DR))@l
+ mtspr SPRN_SRR0,r4
+ mtspr SPRN_SRR1,r3
+ rfi
+ b . /* prevent prefetch past rfi */
+
+/* Load up the kernel context */
+2:
+ sync /* Flush to memory before changing TLB */
+ tlbia
+ isync /* Flush shadow TLBs */
+
+ /* set up the PTE pointers for the Abatron bdiGDB.
+ */
+ lis r6, swapper_pg_dir@h
+ ori r6, r6, swapper_pg_dir@l
+ lis r5, abatron_pteptrs@h
+ ori r5, r5, abatron_pteptrs@l
+ stw r5, 0xf0(r0) /* Must match your Abatron config file */
+ tophys(r5,r5)
+ stw r6, 0(r5)
+
+/* Now turn on the MMU for real! */
+ lis r4,MSR_KERNEL@h
+ ori r4,r4,MSR_KERNEL@l
+ lis r3,start_kernel@h
+ ori r3,r3,start_kernel@l
+ mtspr SPRN_SRR0,r3
+ mtspr SPRN_SRR1,r4
+ rfi /* enable MMU and jump to start_kernel */
+ b . /* prevent prefetch past rfi */
+
+/* Set up the initial MMU state so we can do the first level of
+ * kernel initialization. This maps the first 16 MBytes of memory 1:1
+ * virtual to physical and more importantly sets the cache mode.
+ */
+initial_mmu:
+ tlbia /* Invalidate all TLB entries */
+ isync
+
+ /* We should still be executing code at physical address 0x0000xxxx
+ * at this point. However, start_here is at virtual address
+ * 0xC000xxxx. So, set up a TLB mapping to cover this once
+ * translation is enabled.
+ */
+
+ lis r3,KERNELBASE@h /* Load the kernel virtual address */
+ ori r3,r3,KERNELBASE@l
+ tophys(r4,r3) /* Load the kernel physical address */
+
+ iccci r0,r3 /* Invalidate the i-cache before use */
+
+ /* Load the kernel PID.
+ */
+ li r0,0
+ mtspr SPRN_PID,r0
+ sync
+
+ /* Configure and load two entries into TLB slots 62 and 63.
+ * In case we are pinning TLBs, these are reserved in by the
+ * other TLB functions. If not reserving, then it doesn't
+ * matter where they are loaded.
+ */
+ clrrwi r4,r4,10 /* Mask off the real page number */
+ ori r4,r4,(TLB_WR | TLB_EX) /* Set the write and execute bits */
+
+ clrrwi r3,r3,10 /* Mask off the effective page number */
+ ori r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_16M))
+
+ li r0,63 /* TLB slot 63 */
+
+ tlbwe r4,r0,TLB_DATA /* Load the data portion of the entry */
+ tlbwe r3,r0,TLB_TAG /* Load the tag portion of the entry */
+
+#if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(SERIAL_DEBUG_IO_BASE)
+
+ /* Load a TLB entry for the UART, so that ppc4xx_progress() can use
+ * the UARTs nice and early. We use a 4k real==virtual mapping. */
+
+ lis r3,SERIAL_DEBUG_IO_BASE@h
+ ori r3,r3,SERIAL_DEBUG_IO_BASE@l
+ mr r4,r3
+ clrrwi r4,r4,12
+ ori r4,r4,(TLB_WR|TLB_I|TLB_M|TLB_G)
+
+ clrrwi r3,r3,12
+ ori r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_4K))
+
+ li r0,0 /* TLB slot 0 */
+ tlbwe r4,r0,TLB_DATA
+ tlbwe r3,r0,TLB_TAG
+#endif /* CONFIG_SERIAL_DEBUG_TEXT && SERIAL_DEBUG_IO_BASE */
+
+ isync
+
+ /* Establish the exception vector base
+ */
+ lis r4,KERNELBASE@h /* EVPR only uses the high 16-bits */
+ tophys(r0,r4) /* Use the physical address */
+ mtspr SPRN_EVPR,r0
+
+ blr
+
+_GLOBAL(abort)
+ mfspr r13,SPRN_DBCR0
+ oris r13,r13,DBCR0_RST_SYSTEM@h
+ mtspr SPRN_DBCR0,r13
+
+_GLOBAL(set_context)
+
+#ifdef CONFIG_BDI_SWITCH
+ /* Context switch the PTE pointer for the Abatron BDI2000.
+ * The PGDIR is the second parameter.
+ */
+ lis r5, KERNELBASE@h
+ lwz r5, 0xf0(r5)
+ stw r4, 0x4(r5)
+#endif
+ sync
+ mtspr SPRN_PID,r3
+ isync /* Need an isync to flush shadow */
+ /* TLBs after changing PID */
+ blr
+
+/* We put a few things here that have to be page-aligned. This stuff
+ * goes at the beginning of the data segment, which is page-aligned.
+ */
+ .data
+ .align 12
+ .globl sdata
+sdata:
+ .globl empty_zero_page
+empty_zero_page:
+ .space 4096
+ .globl swapper_pg_dir
+swapper_pg_dir:
+ .space 4096
+
+
+/* Stack for handling critical exceptions from kernel mode */
+ .section .bss
+ .align 12
+exception_stack_bottom:
+ .space 4096
+critical_stack_top:
+ .globl exception_stack_top
+exception_stack_top:
+
+/* This space gets a copy of optional info passed to us by the bootstrap
+ * which is used to pass parameters into the kernel like root=/dev/sda1, etc.
+ */
+ .globl cmd_line
+cmd_line:
+ .space 512
+
+/* Room for two PTE pointers, usually the kernel and current user pointers
+ * to their respective root page table.
+ */
+abatron_pteptrs:
+ .space 8
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
new file mode 100644
index 000000000000..147215a0d6c0
--- /dev/null
+++ b/arch/powerpc/kernel/head_64.S
@@ -0,0 +1,1957 @@
+/*
+ * arch/ppc64/kernel/head.S
+ *
+ * PowerPC version
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
+ * Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
+ * Adapted for Power Macintosh by Paul Mackerras.
+ * Low-level exception handlers and MMU support
+ * rewritten by Paul Mackerras.
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ * Adapted for 64bit PowerPC by Dave Engebretsen, Peter Bergner, and
+ * Mike Corrigan {engebret|bergner|mikejc}@us.ibm.com
+ *
+ * This file contains the low-level support and setup for the
+ * PowerPC-64 platform, including trap and interrupt dispatch.
+ *
+ * This program is free software; you can redistribute 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/config.h>
+#include <linux/threads.h>
+#include <asm/reg.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+#include <asm/systemcfg.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/bug.h>
+#include <asm/cputable.h>
+#include <asm/setup.h>
+#include <asm/hvcall.h>
+#include <asm/iSeries/LparMap.h>
+#include <asm/thread_info.h>
+
+#ifdef CONFIG_PPC_ISERIES
+#define DO_SOFT_DISABLE
+#endif
+
+/*
+ * We layout physical memory as follows:
+ * 0x0000 - 0x00ff : Secondary processor spin code
+ * 0x0100 - 0x2fff : pSeries Interrupt prologs
+ * 0x3000 - 0x5fff : interrupt support, iSeries and common interrupt prologs
+ * 0x6000 - 0x6fff : Initial (CPU0) segment table
+ * 0x7000 - 0x7fff : FWNMI data area
+ * 0x8000 - : Early init and support code
+ */
+
+/*
+ * SPRG Usage
+ *
+ * Register Definition
+ *
+ * SPRG0 reserved for hypervisor
+ * SPRG1 temp - used to save gpr
+ * SPRG2 temp - used to save gpr
+ * SPRG3 virt addr of paca
+ */
+
+/*
+ * Entering into this code we make the following assumptions:
+ * For pSeries:
+ * 1. The MMU is off & open firmware is running in real mode.
+ * 2. The kernel is entered at __start
+ *
+ * For iSeries:
+ * 1. The MMU is on (as it always is for iSeries)
+ * 2. The kernel is entered at system_reset_iSeries
+ */
+
+ .text
+ .globl _stext
+_stext:
+#ifdef CONFIG_PPC_MULTIPLATFORM
+_GLOBAL(__start)
+ /* NOP this out unconditionally */
+BEGIN_FTR_SECTION
+ b .__start_initialization_multiplatform
+END_FTR_SECTION(0, 1)
+#endif /* CONFIG_PPC_MULTIPLATFORM */
+
+ /* Catch branch to 0 in real mode */
+ trap
+
+#ifdef CONFIG_PPC_ISERIES
+ /*
+ * At offset 0x20, there is a pointer to iSeries LPAR data.
+ * This is required by the hypervisor
+ */
+ . = 0x20
+ .llong hvReleaseData-KERNELBASE
+
+ /*
+ * At offset 0x28 and 0x30 are offsets to the mschunks_map
+ * array (used by the iSeries LPAR debugger to do translation
+ * between physical addresses and absolute addresses) and
+ * to the pidhash table (also used by the debugger)
+ */
+ .llong mschunks_map-KERNELBASE
+ .llong 0 /* pidhash-KERNELBASE SFRXXX */
+
+ /* Offset 0x38 - Pointer to start of embedded System.map */
+ .globl embedded_sysmap_start
+embedded_sysmap_start:
+ .llong 0
+ /* Offset 0x40 - Pointer to end of embedded System.map */
+ .globl embedded_sysmap_end
+embedded_sysmap_end:
+ .llong 0
+
+#endif /* CONFIG_PPC_ISERIES */
+
+ /* Secondary processors spin on this value until it goes to 1. */
+ .globl __secondary_hold_spinloop
+__secondary_hold_spinloop:
+ .llong 0x0
+
+ /* Secondary processors write this value with their cpu # */
+ /* after they enter the spin loop immediately below. */
+ .globl __secondary_hold_acknowledge
+__secondary_hold_acknowledge:
+ .llong 0x0
+
+ . = 0x60
+/*
+ * The following code is used on pSeries to hold secondary processors
+ * in a spin loop after they have been freed from OpenFirmware, but
+ * before the bulk of the kernel has been relocated. This code
+ * is relocated to physical address 0x60 before prom_init is run.
+ * All of it must fit below the first exception vector at 0x100.
+ */
+_GLOBAL(__secondary_hold)
+ mfmsr r24
+ ori r24,r24,MSR_RI
+ mtmsrd r24 /* RI on */
+
+ /* Grab our linux cpu number */
+ mr r24,r3
+
+ /* Tell the master cpu we're here */
+ /* Relocation is off & we are located at an address less */
+ /* than 0x100, so only need to grab low order offset. */
+ std r24,__secondary_hold_acknowledge@l(0)
+ sync
+
+ /* All secondary cpus wait here until told to start. */
+100: ld r4,__secondary_hold_spinloop@l(0)
+ cmpdi 0,r4,1
+ bne 100b
+
+#ifdef CONFIG_HMT
+ b .hmt_init
+#else
+#ifdef CONFIG_SMP
+ mr r3,r24
+ b .pSeries_secondary_smp_init
+#else
+ BUG_OPCODE
+#endif
+#endif
+
+/* This value is used to mark exception frames on the stack. */
+ .section ".toc","aw"
+exception_marker:
+ .tc ID_72656773_68657265[TC],0x7265677368657265
+ .text
+
+/*
+ * The following macros define the code that appears as
+ * the prologue to each of the exception handlers. They
+ * are split into two parts to allow a single kernel binary
+ * to be used for pSeries and iSeries.
+ * LOL. One day... - paulus
+ */
+
+/*
+ * We make as much of the exception code common between native
+ * exception handlers (including pSeries LPAR) and iSeries LPAR
+ * implementations as possible.
+ */
+
+/*
+ * This is the start of the interrupt handlers for pSeries
+ * This code runs with relocation off.
+ */
+#define EX_R9 0
+#define EX_R10 8
+#define EX_R11 16
+#define EX_R12 24
+#define EX_R13 32
+#define EX_SRR0 40
+#define EX_R3 40 /* SLB miss saves R3, but not SRR0 */
+#define EX_DAR 48
+#define EX_LR 48 /* SLB miss saves LR, but not DAR */
+#define EX_DSISR 56
+#define EX_CCR 60
+
+#define EXCEPTION_PROLOG_PSERIES(area, label) \
+ mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \
+ std r9,area+EX_R9(r13); /* save r9 - r12 */ \
+ std r10,area+EX_R10(r13); \
+ std r11,area+EX_R11(r13); \
+ std r12,area+EX_R12(r13); \
+ mfspr r9,SPRN_SPRG1; \
+ std r9,area+EX_R13(r13); \
+ mfcr r9; \
+ clrrdi r12,r13,32; /* get high part of &label */ \
+ mfmsr r10; \
+ mfspr r11,SPRN_SRR0; /* save SRR0 */ \
+ ori r12,r12,(label)@l; /* virt addr of handler */ \
+ ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \
+ mtspr SPRN_SRR0,r12; \
+ mfspr r12,SPRN_SRR1; /* and SRR1 */ \
+ mtspr SPRN_SRR1,r10; \
+ rfid; \
+ b . /* prevent speculative execution */
+
+/*
+ * This is the start of the interrupt handlers for iSeries
+ * This code runs with relocation on.
+ */
+#define EXCEPTION_PROLOG_ISERIES_1(area) \
+ mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \
+ std r9,area+EX_R9(r13); /* save r9 - r12 */ \
+ std r10,area+EX_R10(r13); \
+ std r11,area+EX_R11(r13); \
+ std r12,area+EX_R12(r13); \
+ mfspr r9,SPRN_SPRG1; \
+ std r9,area+EX_R13(r13); \
+ mfcr r9
+
+#define EXCEPTION_PROLOG_ISERIES_2 \
+ mfmsr r10; \
+ ld r11,PACALPPACA+LPPACASRR0(r13); \
+ ld r12,PACALPPACA+LPPACASRR1(r13); \
+ ori r10,r10,MSR_RI; \
+ mtmsrd r10,1
+
+/*
+ * The common exception prolog is used for all except a few exceptions
+ * such as a segment miss on a kernel address. We have to be prepared
+ * to take another exception from the point where we first touch the
+ * kernel stack onwards.
+ *
+ * On entry r13 points to the paca, r9-r13 are saved in the paca,
+ * r9 contains the saved CR, r11 and r12 contain the saved SRR0 and
+ * SRR1, and relocation is on.
+ */
+#define EXCEPTION_PROLOG_COMMON(n, area) \
+ andi. r10,r12,MSR_PR; /* See if coming from user */ \
+ mr r10,r1; /* Save r1 */ \
+ subi r1,r1,INT_FRAME_SIZE; /* alloc frame on kernel stack */ \
+ beq- 1f; \
+ ld r1,PACAKSAVE(r13); /* kernel stack to use */ \
+1: cmpdi cr1,r1,0; /* check if r1 is in userspace */ \
+ bge- cr1,bad_stack; /* abort if it is */ \
+ std r9,_CCR(r1); /* save CR in stackframe */ \
+ std r11,_NIP(r1); /* save SRR0 in stackframe */ \
+ std r12,_MSR(r1); /* save SRR1 in stackframe */ \
+ std r10,0(r1); /* make stack chain pointer */ \
+ std r0,GPR0(r1); /* save r0 in stackframe */ \
+ std r10,GPR1(r1); /* save r1 in stackframe */ \
+ std r2,GPR2(r1); /* save r2 in stackframe */ \
+ SAVE_4GPRS(3, r1); /* save r3 - r6 in stackframe */ \
+ SAVE_2GPRS(7, r1); /* save r7, r8 in stackframe */ \
+ ld r9,area+EX_R9(r13); /* move r9, r10 to stackframe */ \
+ ld r10,area+EX_R10(r13); \
+ std r9,GPR9(r1); \
+ std r10,GPR10(r1); \
+ ld r9,area+EX_R11(r13); /* move r11 - r13 to stackframe */ \
+ ld r10,area+EX_R12(r13); \
+ ld r11,area+EX_R13(r13); \
+ std r9,GPR11(r1); \
+ std r10,GPR12(r1); \
+ std r11,GPR13(r1); \
+ ld r2,PACATOC(r13); /* get kernel TOC into r2 */ \
+ mflr r9; /* save LR in stackframe */ \
+ std r9,_LINK(r1); \
+ mfctr r10; /* save CTR in stackframe */ \
+ std r10,_CTR(r1); \
+ mfspr r11,SPRN_XER; /* save XER in stackframe */ \
+ std r11,_XER(r1); \
+ li r9,(n)+1; \
+ std r9,_TRAP(r1); /* set trap number */ \
+ li r10,0; \
+ ld r11,exception_marker@toc(r2); \
+ std r10,RESULT(r1); /* clear regs->result */ \
+ std r11,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame */
+
+/*
+ * Exception vectors.
+ */
+#define STD_EXCEPTION_PSERIES(n, label) \
+ . = n; \
+ .globl label##_pSeries; \
+label##_pSeries: \
+ HMT_MEDIUM; \
+ mtspr SPRN_SPRG1,r13; /* save r13 */ \
+ RUNLATCH_ON(r13); \
+ EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
+
+#define STD_EXCEPTION_ISERIES(n, label, area) \
+ .globl label##_iSeries; \
+label##_iSeries: \
+ HMT_MEDIUM; \
+ mtspr SPRN_SPRG1,r13; /* save r13 */ \
+ RUNLATCH_ON(r13); \
+ EXCEPTION_PROLOG_ISERIES_1(area); \
+ EXCEPTION_PROLOG_ISERIES_2; \
+ b label##_common
+
+#define MASKABLE_EXCEPTION_ISERIES(n, label) \
+ .globl label##_iSeries; \
+label##_iSeries: \
+ HMT_MEDIUM; \
+ mtspr SPRN_SPRG1,r13; /* save r13 */ \
+ RUNLATCH_ON(r13); \
+ EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN); \
+ lbz r10,PACAPROCENABLED(r13); \
+ cmpwi 0,r10,0; \
+ beq- label##_iSeries_masked; \
+ EXCEPTION_PROLOG_ISERIES_2; \
+ b label##_common; \
+
+#ifdef DO_SOFT_DISABLE
+#define DISABLE_INTS \
+ lbz r10,PACAPROCENABLED(r13); \
+ li r11,0; \
+ std r10,SOFTE(r1); \
+ mfmsr r10; \
+ stb r11,PACAPROCENABLED(r13); \
+ ori r10,r10,MSR_EE; \
+ mtmsrd r10,1
+
+#define ENABLE_INTS \
+ lbz r10,PACAPROCENABLED(r13); \
+ mfmsr r11; \
+ std r10,SOFTE(r1); \
+ ori r11,r11,MSR_EE; \
+ mtmsrd r11,1
+
+#else /* hard enable/disable interrupts */
+#define DISABLE_INTS
+
+#define ENABLE_INTS \
+ ld r12,_MSR(r1); \
+ mfmsr r11; \
+ rlwimi r11,r12,0,MSR_EE; \
+ mtmsrd r11,1
+
+#endif
+
+#define STD_EXCEPTION_COMMON(trap, label, hdlr) \
+ .align 7; \
+ .globl label##_common; \
+label##_common: \
+ EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \
+ DISABLE_INTS; \
+ bl .save_nvgprs; \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ bl hdlr; \
+ b .ret_from_except
+
+#define STD_EXCEPTION_COMMON_LITE(trap, label, hdlr) \
+ .align 7; \
+ .globl label##_common; \
+label##_common: \
+ EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \
+ DISABLE_INTS; \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ bl hdlr; \
+ b .ret_from_except_lite
+
+/*
+ * Start of pSeries system interrupt routines
+ */
+ . = 0x100
+ .globl __start_interrupts
+__start_interrupts:
+
+ STD_EXCEPTION_PSERIES(0x100, system_reset)
+
+ . = 0x200
+_machine_check_pSeries:
+ HMT_MEDIUM
+ mtspr SPRN_SPRG1,r13 /* save r13 */
+ RUNLATCH_ON(r13)
+ EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
+
+ . = 0x300
+ .globl data_access_pSeries
+data_access_pSeries:
+ HMT_MEDIUM
+ mtspr SPRN_SPRG1,r13
+BEGIN_FTR_SECTION
+ mtspr SPRN_SPRG2,r12
+ mfspr r13,SPRN_DAR
+ mfspr r12,SPRN_DSISR
+ srdi r13,r13,60
+ rlwimi r13,r12,16,0x20
+ mfcr r12
+ cmpwi r13,0x2c
+ beq .do_stab_bolted_pSeries
+ mtcrf 0x80,r12
+ mfspr r12,SPRN_SPRG2
+END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
+ EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common)
+
+ . = 0x380
+ .globl data_access_slb_pSeries
+data_access_slb_pSeries:
+ HMT_MEDIUM
+ mtspr SPRN_SPRG1,r13
+ RUNLATCH_ON(r13)
+ mfspr r13,SPRN_SPRG3 /* get paca address into r13 */
+ std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */
+ std r10,PACA_EXSLB+EX_R10(r13)
+ std r11,PACA_EXSLB+EX_R11(r13)
+ std r12,PACA_EXSLB+EX_R12(r13)
+ std r3,PACA_EXSLB+EX_R3(r13)
+ mfspr r9,SPRN_SPRG1
+ std r9,PACA_EXSLB+EX_R13(r13)
+ mfcr r9
+ mfspr r12,SPRN_SRR1 /* and SRR1 */
+ mfspr r3,SPRN_DAR
+ b .do_slb_miss /* Rel. branch works in real mode */
+
+ STD_EXCEPTION_PSERIES(0x400, instruction_access)
+
+ . = 0x480
+ .globl instruction_access_slb_pSeries
+instruction_access_slb_pSeries:
+ HMT_MEDIUM
+ mtspr SPRN_SPRG1,r13
+ RUNLATCH_ON(r13)
+ mfspr r13,SPRN_SPRG3 /* get paca address into r13 */
+ std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */
+ std r10,PACA_EXSLB+EX_R10(r13)
+ std r11,PACA_EXSLB+EX_R11(r13)
+ std r12,PACA_EXSLB+EX_R12(r13)
+ std r3,PACA_EXSLB+EX_R3(r13)
+ mfspr r9,SPRN_SPRG1
+ std r9,PACA_EXSLB+EX_R13(r13)
+ mfcr r9
+ mfspr r12,SPRN_SRR1 /* and SRR1 */
+ mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */
+ b .do_slb_miss /* Rel. branch works in real mode */
+
+ STD_EXCEPTION_PSERIES(0x500, hardware_interrupt)
+ STD_EXCEPTION_PSERIES(0x600, alignment)
+ STD_EXCEPTION_PSERIES(0x700, program_check)
+ STD_EXCEPTION_PSERIES(0x800, fp_unavailable)
+ STD_EXCEPTION_PSERIES(0x900, decrementer)
+ STD_EXCEPTION_PSERIES(0xa00, trap_0a)
+ STD_EXCEPTION_PSERIES(0xb00, trap_0b)
+
+ . = 0xc00
+ .globl system_call_pSeries
+system_call_pSeries:
+ HMT_MEDIUM
+ RUNLATCH_ON(r9)
+ mr r9,r13
+ mfmsr r10
+ mfspr r13,SPRN_SPRG3
+ mfspr r11,SPRN_SRR0
+ clrrdi r12,r13,32
+ oris r12,r12,system_call_common@h
+ ori r12,r12,system_call_common@l
+ mtspr SPRN_SRR0,r12
+ ori r10,r10,MSR_IR|MSR_DR|MSR_RI
+ mfspr r12,SPRN_SRR1
+ mtspr SPRN_SRR1,r10
+ rfid
+ b . /* prevent speculative execution */
+
+ STD_EXCEPTION_PSERIES(0xd00, single_step)
+ STD_EXCEPTION_PSERIES(0xe00, trap_0e)
+
+ /* We need to deal with the Altivec unavailable exception
+ * here which is at 0xf20, thus in the middle of the
+ * prolog code of the PerformanceMonitor one. A little
+ * trickery is thus necessary
+ */
+ . = 0xf00
+ b performance_monitor_pSeries
+
+ STD_EXCEPTION_PSERIES(0xf20, altivec_unavailable)
+
+ STD_EXCEPTION_PSERIES(0x1300, instruction_breakpoint)
+ STD_EXCEPTION_PSERIES(0x1700, altivec_assist)
+
+ . = 0x3000
+
+/*** pSeries interrupt support ***/
+
+ /* moved from 0xf00 */
+ STD_EXCEPTION_PSERIES(., performance_monitor)
+
+ .align 7
+_GLOBAL(do_stab_bolted_pSeries)
+ mtcrf 0x80,r12
+ mfspr r12,SPRN_SPRG2
+ EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted)
+
+/*
+ * Vectors for the FWNMI option. Share common code.
+ */
+ .globl system_reset_fwnmi
+system_reset_fwnmi:
+ HMT_MEDIUM
+ mtspr SPRN_SPRG1,r13 /* save r13 */
+ RUNLATCH_ON(r13)
+ EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
+
+ .globl machine_check_fwnmi
+machine_check_fwnmi:
+ HMT_MEDIUM
+ mtspr SPRN_SPRG1,r13 /* save r13 */
+ RUNLATCH_ON(r13)
+ EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
+
+#ifdef CONFIG_PPC_ISERIES
+/*** ISeries-LPAR interrupt handlers ***/
+
+ STD_EXCEPTION_ISERIES(0x200, machine_check, PACA_EXMC)
+
+ .globl data_access_iSeries
+data_access_iSeries:
+ mtspr SPRN_SPRG1,r13
+BEGIN_FTR_SECTION
+ mtspr SPRN_SPRG2,r12
+ mfspr r13,SPRN_DAR
+ mfspr r12,SPRN_DSISR
+ srdi r13,r13,60
+ rlwimi r13,r12,16,0x20
+ mfcr r12
+ cmpwi r13,0x2c
+ beq .do_stab_bolted_iSeries
+ mtcrf 0x80,r12
+ mfspr r12,SPRN_SPRG2
+END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
+ EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN)
+ EXCEPTION_PROLOG_ISERIES_2
+ b data_access_common
+
+.do_stab_bolted_iSeries:
+ mtcrf 0x80,r12
+ mfspr r12,SPRN_SPRG2
+ EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
+ EXCEPTION_PROLOG_ISERIES_2
+ b .do_stab_bolted
+
+ .globl data_access_slb_iSeries
+data_access_slb_iSeries:
+ mtspr SPRN_SPRG1,r13 /* save r13 */
+ EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
+ std r3,PACA_EXSLB+EX_R3(r13)
+ ld r12,PACALPPACA+LPPACASRR1(r13)
+ mfspr r3,SPRN_DAR
+ b .do_slb_miss
+
+ STD_EXCEPTION_ISERIES(0x400, instruction_access, PACA_EXGEN)
+
+ .globl instruction_access_slb_iSeries
+instruction_access_slb_iSeries:
+ mtspr SPRN_SPRG1,r13 /* save r13 */
+ EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
+ std r3,PACA_EXSLB+EX_R3(r13)
+ ld r12,PACALPPACA+LPPACASRR1(r13)
+ ld r3,PACALPPACA+LPPACASRR0(r13)
+ b .do_slb_miss
+
+ MASKABLE_EXCEPTION_ISERIES(0x500, hardware_interrupt)
+ STD_EXCEPTION_ISERIES(0x600, alignment, PACA_EXGEN)
+ STD_EXCEPTION_ISERIES(0x700, program_check, PACA_EXGEN)
+ STD_EXCEPTION_ISERIES(0x800, fp_unavailable, PACA_EXGEN)
+ MASKABLE_EXCEPTION_ISERIES(0x900, decrementer)
+ STD_EXCEPTION_ISERIES(0xa00, trap_0a, PACA_EXGEN)
+ STD_EXCEPTION_ISERIES(0xb00, trap_0b, PACA_EXGEN)
+
+ .globl system_call_iSeries
+system_call_iSeries:
+ mr r9,r13
+ mfspr r13,SPRN_SPRG3
+ EXCEPTION_PROLOG_ISERIES_2
+ b system_call_common
+
+ STD_EXCEPTION_ISERIES( 0xd00, single_step, PACA_EXGEN)
+ STD_EXCEPTION_ISERIES( 0xe00, trap_0e, PACA_EXGEN)
+ STD_EXCEPTION_ISERIES( 0xf00, performance_monitor, PACA_EXGEN)
+
+ .globl system_reset_iSeries
+system_reset_iSeries:
+ mfspr r13,SPRN_SPRG3 /* Get paca address */
+ mfmsr r24
+ ori r24,r24,MSR_RI
+ mtmsrd r24 /* RI on */
+ lhz r24,PACAPACAINDEX(r13) /* Get processor # */
+ cmpwi 0,r24,0 /* Are we processor 0? */
+ beq .__start_initialization_iSeries /* Start up the first processor */
+ mfspr r4,SPRN_CTRLF
+ li r5,CTRL_RUNLATCH /* Turn off the run light */
+ andc r4,r4,r5
+ mtspr SPRN_CTRLT,r4
+
+1:
+ HMT_LOW
+#ifdef CONFIG_SMP
+ lbz r23,PACAPROCSTART(r13) /* Test if this processor
+ * should start */
+ sync
+ LOADADDR(r3,current_set)
+ sldi r28,r24,3 /* get current_set[cpu#] */
+ ldx r3,r3,r28
+ addi r1,r3,THREAD_SIZE
+ subi r1,r1,STACK_FRAME_OVERHEAD
+
+ cmpwi 0,r23,0
+ beq iSeries_secondary_smp_loop /* Loop until told to go */
+ bne .__secondary_start /* Loop until told to go */
+iSeries_secondary_smp_loop:
+ /* Let the Hypervisor know we are alive */
+ /* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */
+ lis r3,0x8002
+ rldicr r3,r3,32,15 /* r0 = (r3 << 32) & 0xffff000000000000 */
+#else /* CONFIG_SMP */
+ /* Yield the processor. This is required for non-SMP kernels
+ which are running on multi-threaded machines. */
+ lis r3,0x8000
+ rldicr r3,r3,32,15 /* r3 = (r3 << 32) & 0xffff000000000000 */
+ addi r3,r3,18 /* r3 = 0x8000000000000012 which is "yield" */
+ li r4,0 /* "yield timed" */
+ li r5,-1 /* "yield forever" */
+#endif /* CONFIG_SMP */
+ li r0,-1 /* r0=-1 indicates a Hypervisor call */
+ sc /* Invoke the hypervisor via a system call */
+ mfspr r13,SPRN_SPRG3 /* Put r13 back ???? */
+ b 1b /* If SMP not configured, secondaries
+ * loop forever */
+
+ .globl decrementer_iSeries_masked
+decrementer_iSeries_masked:
+ li r11,1
+ stb r11,PACALPPACA+LPPACADECRINT(r13)
+ lwz r12,PACADEFAULTDECR(r13)
+ mtspr SPRN_DEC,r12
+ /* fall through */
+
+ .globl hardware_interrupt_iSeries_masked
+hardware_interrupt_iSeries_masked:
+ mtcrf 0x80,r9 /* Restore regs */
+ ld r11,PACALPPACA+LPPACASRR0(r13)
+ ld r12,PACALPPACA+LPPACASRR1(r13)
+ mtspr SPRN_SRR0,r11
+ mtspr SPRN_SRR1,r12
+ ld r9,PACA_EXGEN+EX_R9(r13)
+ ld r10,PACA_EXGEN+EX_R10(r13)
+ ld r11,PACA_EXGEN+EX_R11(r13)
+ ld r12,PACA_EXGEN+EX_R12(r13)
+ ld r13,PACA_EXGEN+EX_R13(r13)
+ rfid
+ b . /* prevent speculative execution */
+#endif /* CONFIG_PPC_ISERIES */
+
+/*** Common interrupt handlers ***/
+
+ STD_EXCEPTION_COMMON(0x100, system_reset, .system_reset_exception)
+
+ /*
+ * Machine check is different because we use a different
+ * save area: PACA_EXMC instead of PACA_EXGEN.
+ */
+ .align 7
+ .globl machine_check_common
+machine_check_common:
+ EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC)
+ DISABLE_INTS
+ bl .save_nvgprs
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ bl .machine_check_exception
+ b .ret_from_except
+
+ STD_EXCEPTION_COMMON_LITE(0x900, decrementer, .timer_interrupt)
+ STD_EXCEPTION_COMMON(0xa00, trap_0a, .unknown_exception)
+ STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception)
+ STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception)
+ STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception)
+ STD_EXCEPTION_COMMON(0xf00, performance_monitor, .performance_monitor_exception)
+ STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception)
+#ifdef CONFIG_ALTIVEC
+ STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception)
+#else
+ STD_EXCEPTION_COMMON(0x1700, altivec_assist, .unknown_exception)
+#endif
+
+/*
+ * Here we have detected that the kernel stack pointer is bad.
+ * R9 contains the saved CR, r13 points to the paca,
+ * r10 contains the (bad) kernel stack pointer,
+ * r11 and r12 contain the saved SRR0 and SRR1.
+ * We switch to using an emergency stack, save the registers there,
+ * and call kernel_bad_stack(), which panics.
+ */
+bad_stack:
+ ld r1,PACAEMERGSP(r13)
+ subi r1,r1,64+INT_FRAME_SIZE
+ std r9,_CCR(r1)
+ std r10,GPR1(r1)
+ std r11,_NIP(r1)
+ std r12,_MSR(r1)
+ mfspr r11,SPRN_DAR
+ mfspr r12,SPRN_DSISR
+ std r11,_DAR(r1)
+ std r12,_DSISR(r1)
+ mflr r10
+ mfctr r11
+ mfxer r12
+ std r10,_LINK(r1)
+ std r11,_CTR(r1)
+ std r12,_XER(r1)
+ SAVE_GPR(0,r1)
+ SAVE_GPR(2,r1)
+ SAVE_4GPRS(3,r1)
+ SAVE_2GPRS(7,r1)
+ SAVE_10GPRS(12,r1)
+ SAVE_10GPRS(22,r1)
+ addi r11,r1,INT_FRAME_SIZE
+ std r11,0(r1)
+ li r12,0
+ std r12,0(r11)
+ ld r2,PACATOC(r13)
+1: addi r3,r1,STACK_FRAME_OVERHEAD
+ bl .kernel_bad_stack
+ b 1b
+
+/*
+ * Return from an exception with minimal checks.
+ * The caller is assumed to have done EXCEPTION_PROLOG_COMMON.
+ * If interrupts have been enabled, or anything has been
+ * done that might have changed the scheduling status of
+ * any task or sent any task a signal, you should use
+ * ret_from_except or ret_from_except_lite instead of this.
+ */
+ .globl fast_exception_return
+fast_exception_return:
+ ld r12,_MSR(r1)
+ ld r11,_NIP(r1)
+ andi. r3,r12,MSR_RI /* check if RI is set */
+ beq- unrecov_fer
+ ld r3,_CCR(r1)
+ ld r4,_LINK(r1)
+ ld r5,_CTR(r1)
+ ld r6,_XER(r1)
+ mtcr r3
+ mtlr r4
+ mtctr r5
+ mtxer r6
+ REST_GPR(0, r1)
+ REST_8GPRS(2, r1)
+
+ mfmsr r10
+ clrrdi r10,r10,2 /* clear RI (LE is 0 already) */
+ mtmsrd r10,1
+
+ mtspr SPRN_SRR1,r12
+ mtspr SPRN_SRR0,r11
+ REST_4GPRS(10, r1)
+ ld r1,GPR1(r1)
+ rfid
+ b . /* prevent speculative execution */
+
+unrecov_fer:
+ bl .save_nvgprs
+1: addi r3,r1,STACK_FRAME_OVERHEAD
+ bl .unrecoverable_exception
+ b 1b
+
+/*
+ * Here r13 points to the paca, r9 contains the saved CR,
+ * SRR0 and SRR1 are saved in r11 and r12,
+ * r9 - r13 are saved in paca->exgen.
+ */
+ .align 7
+ .globl data_access_common
+data_access_common:
+ RUNLATCH_ON(r10) /* It wont fit in the 0x300 handler */
+ mfspr r10,SPRN_DAR
+ std r10,PACA_EXGEN+EX_DAR(r13)
+ mfspr r10,SPRN_DSISR
+ stw r10,PACA_EXGEN+EX_DSISR(r13)
+ EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN)
+ ld r3,PACA_EXGEN+EX_DAR(r13)
+ lwz r4,PACA_EXGEN+EX_DSISR(r13)
+ li r5,0x300
+ b .do_hash_page /* Try to handle as hpte fault */
+
+ .align 7
+ .globl instruction_access_common
+instruction_access_common:
+ EXCEPTION_PROLOG_COMMON(0x400, PACA_EXGEN)
+ ld r3,_NIP(r1)
+ andis. r4,r12,0x5820
+ li r5,0x400
+ b .do_hash_page /* Try to handle as hpte fault */
+
+ .align 7
+ .globl hardware_interrupt_common
+ .globl hardware_interrupt_entry
+hardware_interrupt_common:
+ EXCEPTION_PROLOG_COMMON(0x500, PACA_EXGEN)
+hardware_interrupt_entry:
+ DISABLE_INTS
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ bl .do_IRQ
+ b .ret_from_except_lite
+
+ .align 7
+ .globl alignment_common
+alignment_common:
+ mfspr r10,SPRN_DAR
+ std r10,PACA_EXGEN+EX_DAR(r13)
+ mfspr r10,SPRN_DSISR
+ stw r10,PACA_EXGEN+EX_DSISR(r13)
+ EXCEPTION_PROLOG_COMMON(0x600, PACA_EXGEN)
+ ld r3,PACA_EXGEN+EX_DAR(r13)
+ lwz r4,PACA_EXGEN+EX_DSISR(r13)
+ std r3,_DAR(r1)
+ std r4,_DSISR(r1)
+ bl .save_nvgprs
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ ENABLE_INTS
+ bl .alignment_exception
+ b .ret_from_except
+
+ .align 7
+ .globl program_check_common
+program_check_common:
+ EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN)
+ bl .save_nvgprs
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ ENABLE_INTS
+ bl .program_check_exception
+ b .ret_from_except
+
+ .align 7
+ .globl fp_unavailable_common
+fp_unavailable_common:
+ EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN)
+ bne .load_up_fpu /* if from user, just load it up */
+ bl .save_nvgprs
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ ENABLE_INTS
+ bl .kernel_fp_unavailable_exception
+ BUG_OPCODE
+
+ .align 7
+ .globl altivec_unavailable_common
+altivec_unavailable_common:
+ EXCEPTION_PROLOG_COMMON(0xf20, PACA_EXGEN)
+#ifdef CONFIG_ALTIVEC
+BEGIN_FTR_SECTION
+ bne .load_up_altivec /* if from user, just load it up */
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+#endif
+ bl .save_nvgprs
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ ENABLE_INTS
+ bl .altivec_unavailable_exception
+ b .ret_from_except
+
+#ifdef CONFIG_ALTIVEC
+/*
+ * load_up_altivec(unused, unused, tsk)
+ * Disable VMX for the task which had it previously,
+ * and save its vector registers in its thread_struct.
+ * Enables the VMX for use in the kernel on return.
+ * On SMP we know the VMX is free, since we give it up every
+ * switch (ie, no lazy save of the vector registers).
+ * On entry: r13 == 'current' && last_task_used_altivec != 'current'
+ */
+_STATIC(load_up_altivec)
+ mfmsr r5 /* grab the current MSR */
+ oris r5,r5,MSR_VEC@h
+ mtmsrd r5 /* enable use of VMX now */
+ isync
+
+/*
+ * For SMP, we don't do lazy VMX switching because it just gets too
+ * horrendously complex, especially when a task switches from one CPU
+ * to another. Instead we call giveup_altvec in switch_to.
+ * VRSAVE isn't dealt with here, that is done in the normal context
+ * switch code. Note that we could rely on vrsave value to eventually
+ * avoid saving all of the VREGs here...
+ */
+#ifndef CONFIG_SMP
+ ld r3,last_task_used_altivec@got(r2)
+ ld r4,0(r3)
+ cmpdi 0,r4,0
+ beq 1f
+ /* Save VMX state to last_task_used_altivec's THREAD struct */
+ addi r4,r4,THREAD
+ SAVE_32VRS(0,r5,r4)
+ mfvscr vr0
+ li r10,THREAD_VSCR
+ stvx vr0,r10,r4
+ /* Disable VMX for last_task_used_altivec */
+ ld r5,PT_REGS(r4)
+ ld r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+ lis r6,MSR_VEC@h
+ andc r4,r4,r6
+ std r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:
+#endif /* CONFIG_SMP */
+ /* Hack: if we get an altivec unavailable trap with VRSAVE
+ * set to all zeros, we assume this is a broken application
+ * that fails to set it properly, and thus we switch it to
+ * all 1's
+ */
+ mfspr r4,SPRN_VRSAVE
+ cmpdi 0,r4,0
+ bne+ 1f
+ li r4,-1
+ mtspr SPRN_VRSAVE,r4
+1:
+ /* enable use of VMX after return */
+ ld r4,PACACURRENT(r13)
+ addi r5,r4,THREAD /* Get THREAD */
+ oris r12,r12,MSR_VEC@h
+ std r12,_MSR(r1)
+ li r4,1
+ li r10,THREAD_VSCR
+ stw r4,THREAD_USED_VR(r5)
+ lvx vr0,r10,r5
+ mtvscr vr0
+ REST_32VRS(0,r4,r5)
+#ifndef CONFIG_SMP
+ /* Update last_task_used_math to 'current' */
+ subi r4,r5,THREAD /* Back to 'current' */
+ std r4,0(r3)
+#endif /* CONFIG_SMP */
+ /* restore registers and return */
+ b fast_exception_return
+#endif /* CONFIG_ALTIVEC */
+
+/*
+ * Hash table stuff
+ */
+ .align 7
+_GLOBAL(do_hash_page)
+ std r3,_DAR(r1)
+ std r4,_DSISR(r1)
+
+ andis. r0,r4,0xa450 /* weird error? */
+ bne- .handle_page_fault /* if not, try to insert a HPTE */
+BEGIN_FTR_SECTION
+ andis. r0,r4,0x0020 /* Is it a segment table fault? */
+ bne- .do_ste_alloc /* If so handle it */
+END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
+
+ /*
+ * We need to set the _PAGE_USER bit if MSR_PR is set or if we are
+ * accessing a userspace segment (even from the kernel). We assume
+ * kernel addresses always have the high bit set.
+ */
+ rlwinm r4,r4,32-25+9,31-9,31-9 /* DSISR_STORE -> _PAGE_RW */
+ rotldi r0,r3,15 /* Move high bit into MSR_PR posn */
+ orc r0,r12,r0 /* MSR_PR | ~high_bit */
+ rlwimi r4,r0,32-13,30,30 /* becomes _PAGE_USER access bit */
+ ori r4,r4,1 /* add _PAGE_PRESENT */
+ rlwimi r4,r5,22+2,31-2,31-2 /* Set _PAGE_EXEC if trap is 0x400 */
+
+ /*
+ * On iSeries, we soft-disable interrupts here, then
+ * hard-enable interrupts so that the hash_page code can spin on
+ * the hash_table_lock without problems on a shared processor.
+ */
+ DISABLE_INTS
+
+ /*
+ * r3 contains the faulting address
+ * r4 contains the required access permissions
+ * r5 contains the trap number
+ *
+ * at return r3 = 0 for success
+ */
+ bl .hash_page /* build HPTE if possible */
+ cmpdi r3,0 /* see if hash_page succeeded */
+
+#ifdef DO_SOFT_DISABLE
+ /*
+ * If we had interrupts soft-enabled at the point where the
+ * DSI/ISI occurred, and an interrupt came in during hash_page,
+ * handle it now.
+ * We jump to ret_from_except_lite rather than fast_exception_return
+ * because ret_from_except_lite will check for and handle pending
+ * interrupts if necessary.
+ */
+ beq .ret_from_except_lite
+ /* For a hash failure, we don't bother re-enabling interrupts */
+ ble- 12f
+
+ /*
+ * hash_page couldn't handle it, set soft interrupt enable back
+ * to what it was before the trap. Note that .local_irq_restore
+ * handles any interrupts pending at this point.
+ */
+ ld r3,SOFTE(r1)
+ bl .local_irq_restore
+ b 11f
+#else
+ beq fast_exception_return /* Return from exception on success */
+ ble- 12f /* Failure return from hash_page */
+
+ /* fall through */
+#endif
+
+/* Here we have a page fault that hash_page can't handle. */
+_GLOBAL(handle_page_fault)
+ ENABLE_INTS
+11: ld r4,_DAR(r1)
+ ld r5,_DSISR(r1)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ bl .do_page_fault
+ cmpdi r3,0
+ beq+ .ret_from_except_lite
+ bl .save_nvgprs
+ mr r5,r3
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ lwz r4,_DAR(r1)
+ bl .bad_page_fault
+ b .ret_from_except
+
+/* We have a page fault that hash_page could handle but HV refused
+ * the PTE insertion
+ */
+12: bl .save_nvgprs
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ lwz r4,_DAR(r1)
+ bl .low_hash_fault
+ b .ret_from_except
+
+ /* here we have a segment miss */
+_GLOBAL(do_ste_alloc)
+ bl .ste_allocate /* try to insert stab entry */
+ cmpdi r3,0
+ beq+ fast_exception_return
+ b .handle_page_fault
+
+/*
+ * r13 points to the PACA, r9 contains the saved CR,
+ * r11 and r12 contain the saved SRR0 and SRR1.
+ * r9 - r13 are saved in paca->exslb.
+ * We assume we aren't going to take any exceptions during this procedure.
+ * We assume (DAR >> 60) == 0xc.
+ */
+ .align 7
+_GLOBAL(do_stab_bolted)
+ stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */
+ std r11,PACA_EXSLB+EX_SRR0(r13) /* save SRR0 in exc. frame */
+
+ /* Hash to the primary group */
+ ld r10,PACASTABVIRT(r13)
+ mfspr r11,SPRN_DAR
+ srdi r11,r11,28
+ rldimi r10,r11,7,52 /* r10 = first ste of the group */
+
+ /* Calculate VSID */
+ /* This is a kernel address, so protovsid = ESID */
+ ASM_VSID_SCRAMBLE(r11, r9)
+ rldic r9,r11,12,16 /* r9 = vsid << 12 */
+
+ /* Search the primary group for a free entry */
+1: ld r11,0(r10) /* Test valid bit of the current ste */
+ andi. r11,r11,0x80
+ beq 2f
+ addi r10,r10,16
+ andi. r11,r10,0x70
+ bne 1b
+
+ /* Stick for only searching the primary group for now. */
+ /* At least for now, we use a very simple random castout scheme */
+ /* Use the TB as a random number ; OR in 1 to avoid entry 0 */
+ mftb r11
+ rldic r11,r11,4,57 /* r11 = (r11 << 4) & 0x70 */
+ ori r11,r11,0x10
+
+ /* r10 currently points to an ste one past the group of interest */
+ /* make it point to the randomly selected entry */
+ subi r10,r10,128
+ or r10,r10,r11 /* r10 is the entry to invalidate */
+
+ isync /* mark the entry invalid */
+ ld r11,0(r10)
+ rldicl r11,r11,56,1 /* clear the valid bit */
+ rotldi r11,r11,8
+ std r11,0(r10)
+ sync
+
+ clrrdi r11,r11,28 /* Get the esid part of the ste */
+ slbie r11
+
+2: std r9,8(r10) /* Store the vsid part of the ste */
+ eieio
+
+ mfspr r11,SPRN_DAR /* Get the new esid */
+ clrrdi r11,r11,28 /* Permits a full 32b of ESID */
+ ori r11,r11,0x90 /* Turn on valid and kp */
+ std r11,0(r10) /* Put new entry back into the stab */
+
+ sync
+
+ /* All done -- return from exception. */
+ lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */
+ ld r11,PACA_EXSLB+EX_SRR0(r13) /* get saved SRR0 */
+
+ andi. r10,r12,MSR_RI
+ beq- unrecov_slb
+
+ mtcrf 0x80,r9 /* restore CR */
+
+ mfmsr r10
+ clrrdi r10,r10,2
+ mtmsrd r10,1
+
+ mtspr SPRN_SRR0,r11
+ mtspr SPRN_SRR1,r12
+ ld r9,PACA_EXSLB+EX_R9(r13)
+ ld r10,PACA_EXSLB+EX_R10(r13)
+ ld r11,PACA_EXSLB+EX_R11(r13)
+ ld r12,PACA_EXSLB+EX_R12(r13)
+ ld r13,PACA_EXSLB+EX_R13(r13)
+ rfid
+ b . /* prevent speculative execution */
+
+/*
+ * r13 points to the PACA, r9 contains the saved CR,
+ * r11 and r12 contain the saved SRR0 and SRR1.
+ * r3 has the faulting address
+ * r9 - r13 are saved in paca->exslb.
+ * r3 is saved in paca->slb_r3
+ * We assume we aren't going to take any exceptions during this procedure.
+ */
+_GLOBAL(do_slb_miss)
+ mflr r10
+
+ stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */
+ std r10,PACA_EXSLB+EX_LR(r13) /* save LR */
+
+ bl .slb_allocate /* handle it */
+
+ /* All done -- return from exception. */
+
+ ld r10,PACA_EXSLB+EX_LR(r13)
+ ld r3,PACA_EXSLB+EX_R3(r13)
+ lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */
+#ifdef CONFIG_PPC_ISERIES
+ ld r11,PACALPPACA+LPPACASRR0(r13) /* get SRR0 value */
+#endif /* CONFIG_PPC_ISERIES */
+
+ mtlr r10
+
+ andi. r10,r12,MSR_RI /* check for unrecoverable exception */
+ beq- unrecov_slb
+
+.machine push
+.machine "power4"
+ mtcrf 0x80,r9
+ mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */
+.machine pop
+
+#ifdef CONFIG_PPC_ISERIES
+ mtspr SPRN_SRR0,r11
+ mtspr SPRN_SRR1,r12
+#endif /* CONFIG_PPC_ISERIES */
+ ld r9,PACA_EXSLB+EX_R9(r13)
+ ld r10,PACA_EXSLB+EX_R10(r13)
+ ld r11,PACA_EXSLB+EX_R11(r13)
+ ld r12,PACA_EXSLB+EX_R12(r13)
+ ld r13,PACA_EXSLB+EX_R13(r13)
+ rfid
+ b . /* prevent speculative execution */
+
+unrecov_slb:
+ EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB)
+ DISABLE_INTS
+ bl .save_nvgprs
+1: addi r3,r1,STACK_FRAME_OVERHEAD
+ bl .unrecoverable_exception
+ b 1b
+
+/*
+ * Space for CPU0's segment table.
+ *
+ * On iSeries, the hypervisor must fill in at least one entry before
+ * we get control (with relocate on). The address is give to the hv
+ * as a page number (see xLparMap in lpardata.c), so this must be at a
+ * fixed address (the linker can't compute (u64)&initial_stab >>
+ * PAGE_SHIFT).
+ */
+ . = STAB0_PHYS_ADDR /* 0x6000 */
+ .globl initial_stab
+initial_stab:
+ .space 4096
+
+/*
+ * Data area reserved for FWNMI option.
+ * This address (0x7000) is fixed by the RPA.
+ */
+ .= 0x7000
+ .globl fwnmi_data_area
+fwnmi_data_area:
+
+ /* iSeries does not use the FWNMI stuff, so it is safe to put
+ * this here, even if we later allow kernels that will boot on
+ * both pSeries and iSeries */
+#ifdef CONFIG_PPC_ISERIES
+ . = LPARMAP_PHYS
+#include "lparmap.s"
+/*
+ * This ".text" is here for old compilers that generate a trailing
+ * .note section when compiling .c files to .s
+ */
+ .text
+#endif /* CONFIG_PPC_ISERIES */
+
+ . = 0x8000
+
+/*
+ * On pSeries, secondary processors spin in the following code.
+ * At entry, r3 = this processor's number (physical cpu id)
+ */
+_GLOBAL(pSeries_secondary_smp_init)
+ mr r24,r3
+
+ /* turn on 64-bit mode */
+ bl .enable_64b_mode
+ isync
+
+ /* Copy some CPU settings from CPU 0 */
+ bl .__restore_cpu_setup
+
+ /* Set up a paca value for this processor. Since we have the
+ * physical cpu id in r24, we need to search the pacas to find
+ * which logical id maps to our physical one.
+ */
+ LOADADDR(r13, paca) /* Get base vaddr of paca array */
+ li r5,0 /* logical cpu id */
+1: lhz r6,PACAHWCPUID(r13) /* Load HW procid from paca */
+ cmpw r6,r24 /* Compare to our id */
+ beq 2f
+ addi r13,r13,PACA_SIZE /* Loop to next PACA on miss */
+ addi r5,r5,1
+ cmpwi r5,NR_CPUS
+ blt 1b
+
+ mr r3,r24 /* not found, copy phys to r3 */
+ b .kexec_wait /* next kernel might do better */
+
+2: mtspr SPRN_SPRG3,r13 /* Save vaddr of paca in SPRG3 */
+ /* From now on, r24 is expected to be logical cpuid */
+ mr r24,r5
+3: HMT_LOW
+ lbz r23,PACAPROCSTART(r13) /* Test if this processor should */
+ /* start. */
+ sync
+
+ /* Create a temp kernel stack for use before relocation is on. */
+ ld r1,PACAEMERGSP(r13)
+ subi r1,r1,STACK_FRAME_OVERHEAD
+
+ cmpwi 0,r23,0
+#ifdef CONFIG_SMP
+ bne .__secondary_start
+#endif
+ b 3b /* Loop until told to go */
+
+#ifdef CONFIG_PPC_ISERIES
+_STATIC(__start_initialization_iSeries)
+ /* Clear out the BSS */
+ LOADADDR(r11,__bss_stop)
+ LOADADDR(r8,__bss_start)
+ sub r11,r11,r8 /* bss size */
+ addi r11,r11,7 /* round up to an even double word */
+ rldicl. r11,r11,61,3 /* shift right by 3 */
+ beq 4f
+ addi r8,r8,-8
+ li r0,0
+ mtctr r11 /* zero this many doublewords */
+3: stdu r0,8(r8)
+ bdnz 3b
+4:
+ LOADADDR(r1,init_thread_union)
+ addi r1,r1,THREAD_SIZE
+ li r0,0
+ stdu r0,-STACK_FRAME_OVERHEAD(r1)
+
+ LOADADDR(r3,cpu_specs)
+ LOADADDR(r4,cur_cpu_spec)
+ li r5,0
+ bl .identify_cpu
+
+ LOADADDR(r2,__toc_start)
+ addi r2,r2,0x4000
+ addi r2,r2,0x4000
+
+ bl .iSeries_early_setup
+ bl .early_setup
+
+ /* relocation is on at this point */
+
+ b .start_here_common
+#endif /* CONFIG_PPC_ISERIES */
+
+#ifdef CONFIG_PPC_MULTIPLATFORM
+
+_STATIC(__mmu_off)
+ mfmsr r3
+ andi. r0,r3,MSR_IR|MSR_DR
+ beqlr
+ andc r3,r3,r0
+ mtspr SPRN_SRR0,r4
+ mtspr SPRN_SRR1,r3
+ sync
+ rfid
+ b . /* prevent speculative execution */
+
+
+/*
+ * Here is our main kernel entry point. We support currently 2 kind of entries
+ * depending on the value of r5.
+ *
+ * r5 != NULL -> OF entry, we go to prom_init, "legacy" parameter content
+ * in r3...r7
+ *
+ * r5 == NULL -> kexec style entry. r3 is a physical pointer to the
+ * DT block, r4 is a physical pointer to the kernel itself
+ *
+ */
+_GLOBAL(__start_initialization_multiplatform)
+ /*
+ * Are we booted from a PROM Of-type client-interface ?
+ */
+ cmpldi cr0,r5,0
+ bne .__boot_from_prom /* yes -> prom */
+
+ /* Save parameters */
+ mr r31,r3
+ mr r30,r4
+
+ /* Make sure we are running in 64 bits mode */
+ bl .enable_64b_mode
+
+ /* Setup some critical 970 SPRs before switching MMU off */
+ bl .__970_cpu_preinit
+
+ /* cpu # */
+ li r24,0
+
+ /* Switch off MMU if not already */
+ LOADADDR(r4, .__after_prom_start - KERNELBASE)
+ add r4,r4,r30
+ bl .__mmu_off
+ b .__after_prom_start
+
+_STATIC(__boot_from_prom)
+ /* Save parameters */
+ mr r31,r3
+ mr r30,r4
+ mr r29,r5
+ mr r28,r6
+ mr r27,r7
+
+ /* Make sure we are running in 64 bits mode */
+ bl .enable_64b_mode
+
+ /* put a relocation offset into r3 */
+ bl .reloc_offset
+
+ LOADADDR(r2,__toc_start)
+ addi r2,r2,0x4000
+ addi r2,r2,0x4000
+
+ /* Relocate the TOC from a virt addr to a real addr */
+ add r2,r2,r3
+
+ /* Restore parameters */
+ mr r3,r31
+ mr r4,r30
+ mr r5,r29
+ mr r6,r28
+ mr r7,r27
+
+ /* Do all of the interaction with OF client interface */
+ bl .prom_init
+ /* We never return */
+ trap
+
+/*
+ * At this point, r3 contains the physical address we are running at,
+ * returned by prom_init()
+ */
+_STATIC(__after_prom_start)
+
+/*
+ * We need to run with __start at physical address 0.
+ * This will leave some code in the first 256B of
+ * real memory, which are reserved for software use.
+ * The remainder of the first page is loaded with the fixed
+ * interrupt vectors. The next two pages are filled with
+ * unknown exception placeholders.
+ *
+ * Note: This process overwrites the OF exception vectors.
+ * r26 == relocation offset
+ * r27 == KERNELBASE
+ */
+ bl .reloc_offset
+ mr r26,r3
+ SET_REG_TO_CONST(r27,KERNELBASE)
+
+ li r3,0 /* target addr */
+
+ // XXX FIXME: Use phys returned by OF (r30)
+ add r4,r27,r26 /* source addr */
+ /* current address of _start */
+ /* i.e. where we are running */
+ /* the source addr */
+
+ LOADADDR(r5,copy_to_here) /* # bytes of memory to copy */
+ sub r5,r5,r27
+
+ li r6,0x100 /* Start offset, the first 0x100 */
+ /* bytes were copied earlier. */
+
+ bl .copy_and_flush /* copy the first n bytes */
+ /* this includes the code being */
+ /* executed here. */
+
+ LOADADDR(r0, 4f) /* Jump to the copy of this code */
+ mtctr r0 /* that we just made/relocated */
+ bctr
+
+4: LOADADDR(r5,klimit)
+ add r5,r5,r26
+ ld r5,0(r5) /* get the value of klimit */
+ sub r5,r5,r27
+ bl .copy_and_flush /* copy the rest */
+ b .start_here_multiplatform
+
+#endif /* CONFIG_PPC_MULTIPLATFORM */
+
+/*
+ * Copy routine used to copy the kernel to start at physical address 0
+ * and flush and invalidate the caches as needed.
+ * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset
+ * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5.
+ *
+ * Note: this routine *only* clobbers r0, r6 and lr
+ */
+_GLOBAL(copy_and_flush)
+ addi r5,r5,-8
+ addi r6,r6,-8
+4: li r0,16 /* Use the least common */
+ /* denominator cache line */
+ /* size. This results in */
+ /* extra cache line flushes */
+ /* but operation is correct. */
+ /* Can't get cache line size */
+ /* from NACA as it is being */
+ /* moved too. */
+
+ mtctr r0 /* put # words/line in ctr */
+3: addi r6,r6,8 /* copy a cache line */
+ ldx r0,r6,r4
+ stdx r0,r6,r3
+ bdnz 3b
+ dcbst r6,r3 /* write it to memory */
+ sync
+ icbi r6,r3 /* flush the icache line */
+ cmpld 0,r6,r5
+ blt 4b
+ sync
+ addi r5,r5,8
+ addi r6,r6,8
+ blr
+
+.align 8
+copy_to_here:
+
+#ifdef CONFIG_SMP
+#ifdef CONFIG_PPC_PMAC
+/*
+ * On PowerMac, secondary processors starts from the reset vector, which
+ * is temporarily turned into a call to one of the functions below.
+ */
+ .section ".text";
+ .align 2 ;
+
+ .globl __secondary_start_pmac_0
+__secondary_start_pmac_0:
+ /* NB the entries for cpus 0, 1, 2 must each occupy 8 bytes. */
+ li r24,0
+ b 1f
+ li r24,1
+ b 1f
+ li r24,2
+ b 1f
+ li r24,3
+1:
+
+_GLOBAL(pmac_secondary_start)
+ /* turn on 64-bit mode */
+ bl .enable_64b_mode
+ isync
+
+ /* Copy some CPU settings from CPU 0 */
+ bl .__restore_cpu_setup
+
+ /* pSeries do that early though I don't think we really need it */
+ mfmsr r3
+ ori r3,r3,MSR_RI
+ mtmsrd r3 /* RI on */
+
+ /* Set up a paca value for this processor. */
+ LOADADDR(r4, paca) /* Get base vaddr of paca array */
+ mulli r13,r24,PACA_SIZE /* Calculate vaddr of right paca */
+ add r13,r13,r4 /* for this processor. */
+ mtspr SPRN_SPRG3,r13 /* Save vaddr of paca in SPRG3 */
+
+ /* Create a temp kernel stack for use before relocation is on. */
+ ld r1,PACAEMERGSP(r13)
+ subi r1,r1,STACK_FRAME_OVERHEAD
+
+ b .__secondary_start
+
+#endif /* CONFIG_PPC_PMAC */
+
+/*
+ * This function is called after the master CPU has released the
+ * secondary processors. The execution environment is relocation off.
+ * The paca for this processor has the following fields initialized at
+ * this point:
+ * 1. Processor number
+ * 2. Segment table pointer (virtual address)
+ * On entry the following are set:
+ * r1 = stack pointer. vaddr for iSeries, raddr (temp stack) for pSeries
+ * r24 = cpu# (in Linux terms)
+ * r13 = paca virtual address
+ * SPRG3 = paca virtual address
+ */
+_GLOBAL(__secondary_start)
+
+ HMT_MEDIUM /* Set thread priority to MEDIUM */
+
+ ld r2,PACATOC(r13)
+ li r6,0
+ stb r6,PACAPROCENABLED(r13)
+
+#ifndef CONFIG_PPC_ISERIES
+ /* Initialize the page table pointer register. */
+ LOADADDR(r6,_SDR1)
+ ld r6,0(r6) /* get the value of _SDR1 */
+ mtspr SPRN_SDR1,r6 /* set the htab location */
+#endif
+ /* Initialize the first segment table (or SLB) entry */
+ ld r3,PACASTABVIRT(r13) /* get addr of segment table */
+ bl .stab_initialize
+
+ /* Initialize the kernel stack. Just a repeat for iSeries. */
+ LOADADDR(r3,current_set)
+ sldi r28,r24,3 /* get current_set[cpu#] */
+ ldx r1,r3,r28
+ addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
+ std r1,PACAKSAVE(r13)
+
+ ld r3,PACASTABREAL(r13) /* get raddr of segment table */
+ ori r4,r3,1 /* turn on valid bit */
+
+#ifdef CONFIG_PPC_ISERIES
+ li r0,-1 /* hypervisor call */
+ li r3,1
+ sldi r3,r3,63 /* 0x8000000000000000 */
+ ori r3,r3,4 /* 0x8000000000000004 */
+ sc /* HvCall_setASR */
+#else
+ /* set the ASR */
+ ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */
+ ld r3,0(r3)
+ lwz r3,PLATFORM(r3) /* r3 = platform flags */
+ andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */
+ beq 98f /* branch if result is 0 */
+ mfspr r3,SPRN_PVR
+ srwi r3,r3,16
+ cmpwi r3,0x37 /* SStar */
+ beq 97f
+ cmpwi r3,0x36 /* IStar */
+ beq 97f
+ cmpwi r3,0x34 /* Pulsar */
+ bne 98f
+97: li r3,H_SET_ASR /* hcall = H_SET_ASR */
+ HVSC /* Invoking hcall */
+ b 99f
+98: /* !(rpa hypervisor) || !(star) */
+ mtasr r4 /* set the stab location */
+99:
+#endif
+ li r7,0
+ mtlr r7
+
+ /* enable MMU and jump to start_secondary */
+ LOADADDR(r3,.start_secondary_prolog)
+ SET_REG_TO_CONST(r4, MSR_KERNEL)
+#ifdef DO_SOFT_DISABLE
+ ori r4,r4,MSR_EE
+#endif
+ mtspr SPRN_SRR0,r3
+ mtspr SPRN_SRR1,r4
+ rfid
+ b . /* prevent speculative execution */
+
+/*
+ * Running with relocation on at this point. All we want to do is
+ * zero the stack back-chain pointer before going into C code.
+ */
+_GLOBAL(start_secondary_prolog)
+ li r3,0
+ std r3,0(r1) /* Zero the stack frame pointer */
+ bl .start_secondary
+#endif
+
+/*
+ * This subroutine clobbers r11 and r12
+ */
+_GLOBAL(enable_64b_mode)
+ mfmsr r11 /* grab the current MSR */
+ li r12,1
+ rldicr r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
+ or r11,r11,r12
+ li r12,1
+ rldicr r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
+ or r11,r11,r12
+ mtmsrd r11
+ isync
+ blr
+
+#ifdef CONFIG_PPC_MULTIPLATFORM
+/*
+ * This is where the main kernel code starts.
+ */
+_STATIC(start_here_multiplatform)
+ /* get a new offset, now that the kernel has moved. */
+ bl .reloc_offset
+ mr r26,r3
+
+ /* Clear out the BSS. It may have been done in prom_init,
+ * already but that's irrelevant since prom_init will soon
+ * be detached from the kernel completely. Besides, we need
+ * to clear it now for kexec-style entry.
+ */
+ LOADADDR(r11,__bss_stop)
+ LOADADDR(r8,__bss_start)
+ sub r11,r11,r8 /* bss size */
+ addi r11,r11,7 /* round up to an even double word */
+ rldicl. r11,r11,61,3 /* shift right by 3 */
+ beq 4f
+ addi r8,r8,-8
+ li r0,0
+ mtctr r11 /* zero this many doublewords */
+3: stdu r0,8(r8)
+ bdnz 3b
+4:
+
+ mfmsr r6
+ ori r6,r6,MSR_RI
+ mtmsrd r6 /* RI on */
+
+#ifdef CONFIG_HMT
+ /* Start up the second thread on cpu 0 */
+ mfspr r3,SPRN_PVR
+ srwi r3,r3,16
+ cmpwi r3,0x34 /* Pulsar */
+ beq 90f
+ cmpwi r3,0x36 /* Icestar */
+ beq 90f
+ cmpwi r3,0x37 /* SStar */
+ beq 90f
+ b 91f /* HMT not supported */
+90: li r3,0
+ bl .hmt_start_secondary
+91:
+#endif
+
+ /* The following gets the stack and TOC set up with the regs */
+ /* pointing to the real addr of the kernel stack. This is */
+ /* all done to support the C function call below which sets */
+ /* up the htab. This is done because we have relocated the */
+ /* kernel but are still running in real mode. */
+
+ LOADADDR(r3,init_thread_union)
+ add r3,r3,r26
+
+ /* set up a stack pointer (physical address) */
+ addi r1,r3,THREAD_SIZE
+ li r0,0
+ stdu r0,-STACK_FRAME_OVERHEAD(r1)
+
+ /* set up the TOC (physical address) */
+ LOADADDR(r2,__toc_start)
+ addi r2,r2,0x4000
+ addi r2,r2,0x4000
+ add r2,r2,r26
+
+ LOADADDR(r3,cpu_specs)
+ add r3,r3,r26
+ LOADADDR(r4,cur_cpu_spec)
+ add r4,r4,r26
+ mr r5,r26
+ bl .identify_cpu
+
+ /* Save some low level config HIDs of CPU0 to be copied to
+ * other CPUs later on, or used for suspend/resume
+ */
+ bl .__save_cpu_setup
+ sync
+
+ /* Setup a valid physical PACA pointer in SPRG3 for early_setup
+ * note that boot_cpuid can always be 0 nowadays since there is
+ * nowhere it can be initialized differently before we reach this
+ * code
+ */
+ LOADADDR(r27, boot_cpuid)
+ add r27,r27,r26
+ lwz r27,0(r27)
+
+ LOADADDR(r24, paca) /* Get base vaddr of paca array */
+ mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */
+ add r13,r13,r24 /* for this processor. */
+ add r13,r13,r26 /* convert to physical addr */
+ mtspr SPRN_SPRG3,r13 /* PPPBBB: Temp... -Peter */
+
+ /* Do very early kernel initializations, including initial hash table,
+ * stab and slb setup before we turn on relocation. */
+
+ /* Restore parameters passed from prom_init/kexec */
+ mr r3,r31
+ bl .early_setup
+
+ /* set the ASR */
+ ld r3,PACASTABREAL(r13)
+ ori r4,r3,1 /* turn on valid bit */
+ ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */
+ ld r3,0(r3)
+ lwz r3,PLATFORM(r3) /* r3 = platform flags */
+ andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */
+ beq 98f /* branch if result is 0 */
+ mfspr r3,SPRN_PVR
+ srwi r3,r3,16
+ cmpwi r3,0x37 /* SStar */
+ beq 97f
+ cmpwi r3,0x36 /* IStar */
+ beq 97f
+ cmpwi r3,0x34 /* Pulsar */
+ bne 98f
+97: li r3,H_SET_ASR /* hcall = H_SET_ASR */
+ HVSC /* Invoking hcall */
+ b 99f
+98: /* !(rpa hypervisor) || !(star) */
+ mtasr r4 /* set the stab location */
+99:
+ /* Set SDR1 (hash table pointer) */
+ ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */
+ ld r3,0(r3)
+ lwz r3,PLATFORM(r3) /* r3 = platform flags */
+ /* Test if bit 0 is set (LPAR bit) */
+ andi. r3,r3,PLATFORM_LPAR
+ bne 98f /* branch if result is !0 */
+ LOADADDR(r6,_SDR1) /* Only if NOT LPAR */
+ add r6,r6,r26
+ ld r6,0(r6) /* get the value of _SDR1 */
+ mtspr SPRN_SDR1,r6 /* set the htab location */
+98:
+ LOADADDR(r3,.start_here_common)
+ SET_REG_TO_CONST(r4, MSR_KERNEL)
+ mtspr SPRN_SRR0,r3
+ mtspr SPRN_SRR1,r4
+ rfid
+ b . /* prevent speculative execution */
+#endif /* CONFIG_PPC_MULTIPLATFORM */
+
+ /* This is where all platforms converge execution */
+_STATIC(start_here_common)
+ /* relocation is on at this point */
+
+ /* The following code sets up the SP and TOC now that we are */
+ /* running with translation enabled. */
+
+ LOADADDR(r3,init_thread_union)
+
+ /* set up the stack */
+ addi r1,r3,THREAD_SIZE
+ li r0,0
+ stdu r0,-STACK_FRAME_OVERHEAD(r1)
+
+ /* Apply the CPUs-specific fixups (nop out sections not relevant
+ * to this CPU
+ */
+ li r3,0
+ bl .do_cpu_ftr_fixups
+
+ LOADADDR(r26, boot_cpuid)
+ lwz r26,0(r26)
+
+ LOADADDR(r24, paca) /* Get base vaddr of paca array */
+ mulli r13,r26,PACA_SIZE /* Calculate vaddr of right paca */
+ add r13,r13,r24 /* for this processor. */
+ mtspr SPRN_SPRG3,r13
+
+ /* ptr to current */
+ LOADADDR(r4,init_task)
+ std r4,PACACURRENT(r13)
+
+ /* Load the TOC */
+ ld r2,PACATOC(r13)
+ std r1,PACAKSAVE(r13)
+
+ bl .setup_system
+
+ /* Load up the kernel context */
+5:
+#ifdef DO_SOFT_DISABLE
+ li r5,0
+ stb r5,PACAPROCENABLED(r13) /* Soft Disabled */
+ mfmsr r5
+ ori r5,r5,MSR_EE /* Hard Enabled */
+ mtmsrd r5
+#endif
+
+ bl .start_kernel
+
+_GLOBAL(hmt_init)
+#ifdef CONFIG_HMT
+ LOADADDR(r5, hmt_thread_data)
+ mfspr r7,SPRN_PVR
+ srwi r7,r7,16
+ cmpwi r7,0x34 /* Pulsar */
+ beq 90f
+ cmpwi r7,0x36 /* Icestar */
+ beq 91f
+ cmpwi r7,0x37 /* SStar */
+ beq 91f
+ b 101f
+90: mfspr r6,SPRN_PIR
+ andi. r6,r6,0x1f
+ b 92f
+91: mfspr r6,SPRN_PIR
+ andi. r6,r6,0x3ff
+92: sldi r4,r24,3
+ stwx r6,r5,r4
+ bl .hmt_start_secondary
+ b 101f
+
+__hmt_secondary_hold:
+ LOADADDR(r5, hmt_thread_data)
+ clrldi r5,r5,4
+ li r7,0
+ mfspr r6,SPRN_PIR
+ mfspr r8,SPRN_PVR
+ srwi r8,r8,16
+ cmpwi r8,0x34
+ bne 93f
+ andi. r6,r6,0x1f
+ b 103f
+93: andi. r6,r6,0x3f
+
+103: lwzx r8,r5,r7
+ cmpw r8,r6
+ beq 104f
+ addi r7,r7,8
+ b 103b
+
+104: addi r7,r7,4
+ lwzx r9,r5,r7
+ mr r24,r9
+101:
+#endif
+ mr r3,r24
+ b .pSeries_secondary_smp_init
+
+#ifdef CONFIG_HMT
+_GLOBAL(hmt_start_secondary)
+ LOADADDR(r4,__hmt_secondary_hold)
+ clrldi r4,r4,4
+ mtspr SPRN_NIADORM, r4
+ mfspr r4, SPRN_MSRDORM
+ li r5, -65
+ and r4, r4, r5
+ mtspr SPRN_MSRDORM, r4
+ lis r4,0xffef
+ ori r4,r4,0x7403
+ mtspr SPRN_TSC, r4
+ li r4,0x1f4
+ mtspr SPRN_TST, r4
+ mfspr r4, SPRN_HID0
+ ori r4, r4, 0x1
+ mtspr SPRN_HID0, r4
+ mfspr r4, SPRN_CTRLF
+ oris r4, r4, 0x40
+ mtspr SPRN_CTRLT, r4
+ blr
+#endif
+
+#if defined(CONFIG_KEXEC) || defined(CONFIG_SMP)
+_GLOBAL(smp_release_cpus)
+ /* All secondary cpus are spinning on a common
+ * spinloop, release them all now so they can start
+ * to spin on their individual paca spinloops.
+ * For non SMP kernels, the secondary cpus never
+ * get out of the common spinloop.
+ * XXX This does nothing useful on iSeries, secondaries are
+ * already waiting on their paca.
+ */
+ li r3,1
+ LOADADDR(r5,__secondary_hold_spinloop)
+ std r3,0(r5)
+ sync
+ blr
+#endif /* CONFIG_SMP */
+
+
+/*
+ * We put a few things here that have to be page-aligned.
+ * This stuff goes at the beginning of the bss, which is page-aligned.
+ */
+ .section ".bss"
+
+ .align PAGE_SHIFT
+
+ .globl empty_zero_page
+empty_zero_page:
+ .space PAGE_SIZE
+
+ .globl swapper_pg_dir
+swapper_pg_dir:
+ .space PAGE_SIZE
+
+/*
+ * This space gets a copy of optional info passed to us by the bootstrap
+ * Used to pass parameters into the kernel like root=/dev/sda1, etc.
+ */
+ .globl cmd_line
+cmd_line:
+ .space COMMAND_LINE_SIZE
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
new file mode 100644
index 000000000000..bc6d1ac55235
--- /dev/null
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -0,0 +1,860 @@
+/*
+ * arch/ppc/kernel/except_8xx.S
+ *
+ * PowerPC version
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
+ * Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
+ * Low-level exception handlers and MMU support
+ * rewritten by Paul Mackerras.
+ * Copyright (C) 1996 Paul Mackerras.
+ * MPC8xx modifications by Dan Malek
+ * Copyright (C) 1997 Dan Malek (dmalek@jlc.net).
+ *
+ * This file contains low-level support and setup for PowerPC 8xx
+ * embedded processors, including trap and interrupt dispatch.
+ *
+ * This program is free software; you can redistribute 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/config.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+#include <asm/cache.h>
+#include <asm/pgtable.h>
+#include <asm/cputable.h>
+#include <asm/thread_info.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+
+/* Macro to make the code more readable. */
+#ifdef CONFIG_8xx_CPU6
+#define DO_8xx_CPU6(val, reg) \
+ li reg, val; \
+ stw reg, 12(r0); \
+ lwz reg, 12(r0);
+#else
+#define DO_8xx_CPU6(val, reg)
+#endif
+ .text
+ .globl _stext
+_stext:
+ .text
+ .globl _start
+_start:
+
+/* MPC8xx
+ * This port was done on an MBX board with an 860. Right now I only
+ * support an ELF compressed (zImage) boot from EPPC-Bug because the
+ * code there loads up some registers before calling us:
+ * r3: ptr to board info data
+ * r4: initrd_start or if no initrd then 0
+ * r5: initrd_end - unused if r4 is 0
+ * r6: Start of command line string
+ * r7: End of command line string
+ *
+ * I decided to use conditional compilation instead of checking PVR and
+ * adding more processor specific branches around code I don't need.
+ * Since this is an embedded processor, I also appreciate any memory
+ * savings I can get.
+ *
+ * The MPC8xx does not have any BATs, but it supports large page sizes.
+ * We first initialize the MMU to support 8M byte pages, then load one
+ * entry into each of the instruction and data TLBs to map the first
+ * 8M 1:1. I also mapped an additional I/O space 1:1 so we can get to
+ * the "internal" processor registers before MMU_init is called.
+ *
+ * The TLB code currently contains a major hack. Since I use the condition
+ * code register, I have to save and restore it. I am out of registers, so
+ * I just store it in memory location 0 (the TLB handlers are not reentrant).
+ * To avoid making any decisions, I need to use the "segment" valid bit
+ * in the first level table, but that would require many changes to the
+ * Linux page directory/table functions that I don't want to do right now.
+ *
+ * I used to use SPRG2 for a temporary register in the TLB handler, but it
+ * has since been put to other uses. I now use a hack to save a register
+ * and the CCR at memory location 0.....Someday I'll fix this.....
+ * -- Dan
+ */
+ .globl __start
+__start:
+ mr r31,r3 /* save parameters */
+ mr r30,r4
+ mr r29,r5
+ mr r28,r6
+ mr r27,r7
+
+ /* We have to turn on the MMU right away so we get cache modes
+ * set correctly.
+ */
+ bl initial_mmu
+
+/* We now have the lower 8 Meg mapped into TLB entries, and the caches
+ * ready to work.
+ */
+
+turn_on_mmu:
+ mfmsr r0
+ ori r0,r0,MSR_DR|MSR_IR
+ mtspr SPRN_SRR1,r0
+ lis r0,start_here@h
+ ori r0,r0,start_here@l
+ mtspr SPRN_SRR0,r0
+ SYNC
+ rfi /* enables MMU */
+
+/*
+ * Exception entry code. This code runs with address translation
+ * turned off, i.e. using physical addresses.
+ * We assume sprg3 has the physical address of the current
+ * task's thread_struct.
+ */
+#define EXCEPTION_PROLOG \
+ mtspr SPRN_SPRG0,r10; \
+ mtspr SPRN_SPRG1,r11; \
+ mfcr r10; \
+ EXCEPTION_PROLOG_1; \
+ EXCEPTION_PROLOG_2
+
+#define EXCEPTION_PROLOG_1 \
+ mfspr r11,SPRN_SRR1; /* check whether user or kernel */ \
+ andi. r11,r11,MSR_PR; \
+ tophys(r11,r1); /* use tophys(r1) if kernel */ \
+ beq 1f; \
+ mfspr r11,SPRN_SPRG3; \
+ lwz r11,THREAD_INFO-THREAD(r11); \
+ addi r11,r11,THREAD_SIZE; \
+ tophys(r11,r11); \
+1: subi r11,r11,INT_FRAME_SIZE /* alloc exc. frame */
+
+
+#define EXCEPTION_PROLOG_2 \
+ CLR_TOP32(r11); \
+ stw r10,_CCR(r11); /* save registers */ \
+ stw r12,GPR12(r11); \
+ stw r9,GPR9(r11); \
+ mfspr r10,SPRN_SPRG0; \
+ stw r10,GPR10(r11); \
+ mfspr r12,SPRN_SPRG1; \
+ stw r12,GPR11(r11); \
+ mflr r10; \
+ stw r10,_LINK(r11); \
+ mfspr r12,SPRN_SRR0; \
+ mfspr r9,SPRN_SRR1; \
+ stw r1,GPR1(r11); \
+ stw r1,0(r11); \
+ tovirt(r1,r11); /* set new kernel sp */ \
+ li r10,MSR_KERNEL & ~(MSR_IR|MSR_DR); /* can take exceptions */ \
+ MTMSRD(r10); /* (except for mach check in rtas) */ \
+ stw r0,GPR0(r11); \
+ SAVE_4GPRS(3, r11); \
+ SAVE_2GPRS(7, r11)
+
+/*
+ * Note: code which follows this uses cr0.eq (set if from kernel),
+ * r11, r12 (SRR0), and r9 (SRR1).
+ *
+ * Note2: once we have set r1 we are in a position to take exceptions
+ * again, and we could thus set MSR:RI at that point.
+ */
+
+/*
+ * Exception vectors.
+ */
+#define EXCEPTION(n, label, hdlr, xfer) \
+ . = n; \
+label: \
+ EXCEPTION_PROLOG; \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ xfer(n, hdlr)
+
+#define EXC_XFER_TEMPLATE(n, hdlr, trap, copyee, tfer, ret) \
+ li r10,trap; \
+ stw r10,_TRAP(r11); \
+ li r10,MSR_KERNEL; \
+ copyee(r10, r9); \
+ bl tfer; \
+i##n: \
+ .long hdlr; \
+ .long ret
+
+#define COPY_EE(d, s) rlwimi d,s,0,16,16
+#define NOCOPY(d, s)
+
+#define EXC_XFER_STD(n, hdlr) \
+ EXC_XFER_TEMPLATE(n, hdlr, n, NOCOPY, transfer_to_handler_full, \
+ ret_from_except_full)
+
+#define EXC_XFER_LITE(n, hdlr) \
+ EXC_XFER_TEMPLATE(n, hdlr, n+1, NOCOPY, transfer_to_handler, \
+ ret_from_except)
+
+#define EXC_XFER_EE(n, hdlr) \
+ EXC_XFER_TEMPLATE(n, hdlr, n, COPY_EE, transfer_to_handler_full, \
+ ret_from_except_full)
+
+#define EXC_XFER_EE_LITE(n, hdlr) \
+ EXC_XFER_TEMPLATE(n, hdlr, n+1, COPY_EE, transfer_to_handler, \
+ ret_from_except)
+
+/* System reset */
+ EXCEPTION(0x100, Reset, unknown_exception, EXC_XFER_STD)
+
+/* Machine check */
+ . = 0x200
+MachineCheck:
+ EXCEPTION_PROLOG
+ mfspr r4,SPRN_DAR
+ stw r4,_DAR(r11)
+ mfspr r5,SPRN_DSISR
+ stw r5,_DSISR(r11)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ EXC_XFER_STD(0x200, machine_check_exception)
+
+/* Data access exception.
+ * This is "never generated" by the MPC8xx. We jump to it for other
+ * translation errors.
+ */
+ . = 0x300
+DataAccess:
+ EXCEPTION_PROLOG
+ mfspr r10,SPRN_DSISR
+ stw r10,_DSISR(r11)
+ mr r5,r10
+ mfspr r4,SPRN_DAR
+ EXC_XFER_EE_LITE(0x300, handle_page_fault)
+
+/* Instruction access exception.
+ * This is "never generated" by the MPC8xx. We jump to it for other
+ * translation errors.
+ */
+ . = 0x400
+InstructionAccess:
+ EXCEPTION_PROLOG
+ mr r4,r12
+ mr r5,r9
+ EXC_XFER_EE_LITE(0x400, handle_page_fault)
+
+/* External interrupt */
+ EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
+
+/* Alignment exception */
+ . = 0x600
+Alignment:
+ EXCEPTION_PROLOG
+ mfspr r4,SPRN_DAR
+ stw r4,_DAR(r11)
+ mfspr r5,SPRN_DSISR
+ stw r5,_DSISR(r11)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ EXC_XFER_EE(0x600, alignment_exception)
+
+/* Program check exception */
+ EXCEPTION(0x700, ProgramCheck, program_check_exception, EXC_XFER_STD)
+
+/* No FPU on MPC8xx. This exception is not supposed to happen.
+*/
+ EXCEPTION(0x800, FPUnavailable, unknown_exception, EXC_XFER_STD)
+
+/* Decrementer */
+ EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE)
+
+ EXCEPTION(0xa00, Trap_0a, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0xb00, Trap_0b, unknown_exception, EXC_XFER_EE)
+
+/* System call */
+ . = 0xc00
+SystemCall:
+ EXCEPTION_PROLOG
+ EXC_XFER_EE_LITE(0xc00, DoSyscall)
+
+/* Single step - not used on 601 */
+ EXCEPTION(0xd00, SingleStep, single_step_exception, EXC_XFER_STD)
+ EXCEPTION(0xe00, Trap_0e, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0xf00, Trap_0f, unknown_exception, EXC_XFER_EE)
+
+/* On the MPC8xx, this is a software emulation interrupt. It occurs
+ * for all unimplemented and illegal instructions.
+ */
+ EXCEPTION(0x1000, SoftEmu, SoftwareEmulation, EXC_XFER_STD)
+
+ . = 0x1100
+/*
+ * For the MPC8xx, this is a software tablewalk to load the instruction
+ * TLB. It is modelled after the example in the Motorola manual. The task
+ * switch loads the M_TWB register with the pointer to the first level table.
+ * If we discover there is no second level table (value is zero) or if there
+ * is an invalid pte, we load that into the TLB, which causes another fault
+ * into the TLB Error interrupt where we can handle such problems.
+ * We have to use the MD_xxx registers for the tablewalk because the
+ * equivalent MI_xxx registers only perform the attribute functions.
+ */
+InstructionTLBMiss:
+#ifdef CONFIG_8xx_CPU6
+ stw r3, 8(r0)
+#endif
+ DO_8xx_CPU6(0x3f80, r3)
+ mtspr SPRN_M_TW, r10 /* Save a couple of working registers */
+ mfcr r10
+ stw r10, 0(r0)
+ stw r11, 4(r0)
+ mfspr r10, SPRN_SRR0 /* Get effective address of fault */
+ DO_8xx_CPU6(0x3780, r3)
+ mtspr SPRN_MD_EPN, r10 /* Have to use MD_EPN for walk, MI_EPN can't */
+ mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ andi. r11, r10, 0x0800 /* Address >= 0x80000000 */
+ beq 3f
+ lis r11, swapper_pg_dir@h
+ ori r11, r11, swapper_pg_dir@l
+ rlwimi r10, r11, 0, 2, 19
+3:
+ lwz r11, 0(r10) /* Get the level 1 entry */
+ rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */
+ beq 2f /* If zero, don't try to find a pte */
+
+ /* We have a pte table, so load the MI_TWC with the attributes
+ * for this "segment."
+ */
+ ori r11,r11,1 /* Set valid bit */
+ DO_8xx_CPU6(0x2b80, r3)
+ mtspr SPRN_MI_TWC, r11 /* Set segment attributes */
+ DO_8xx_CPU6(0x3b80, r3)
+ mtspr SPRN_MD_TWC, r11 /* Load pte table base address */
+ mfspr r11, SPRN_MD_TWC /* ....and get the pte address */
+ lwz r10, 0(r11) /* Get the pte */
+
+ ori r10, r10, _PAGE_ACCESSED
+ stw r10, 0(r11)
+
+ /* The Linux PTE won't go exactly into the MMU TLB.
+ * Software indicator bits 21, 22 and 28 must be clear.
+ * Software indicator bits 24, 25, 26, and 27 must be
+ * set. All other Linux PTE bits control the behavior
+ * of the MMU.
+ */
+2: li r11, 0x00f0
+ rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */
+ DO_8xx_CPU6(0x2d80, r3)
+ mtspr SPRN_MI_RPN, r10 /* Update TLB entry */
+
+ mfspr r10, SPRN_M_TW /* Restore registers */
+ lwz r11, 0(r0)
+ mtcr r11
+ lwz r11, 4(r0)
+#ifdef CONFIG_8xx_CPU6
+ lwz r3, 8(r0)
+#endif
+ rfi
+
+ . = 0x1200
+DataStoreTLBMiss:
+#ifdef CONFIG_8xx_CPU6
+ stw r3, 8(r0)
+#endif
+ DO_8xx_CPU6(0x3f80, r3)
+ mtspr SPRN_M_TW, r10 /* Save a couple of working registers */
+ mfcr r10
+ stw r10, 0(r0)
+ stw r11, 4(r0)
+ mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ andi. r11, r10, 0x0800
+ beq 3f
+ lis r11, swapper_pg_dir@h
+ ori r11, r11, swapper_pg_dir@l
+ rlwimi r10, r11, 0, 2, 19
+3:
+ lwz r11, 0(r10) /* Get the level 1 entry */
+ rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */
+ beq 2f /* If zero, don't try to find a pte */
+
+ /* We have a pte table, so load fetch the pte from the table.
+ */
+ ori r11, r11, 1 /* Set valid bit in physical L2 page */
+ DO_8xx_CPU6(0x3b80, r3)
+ mtspr SPRN_MD_TWC, r11 /* Load pte table base address */
+ mfspr r10, SPRN_MD_TWC /* ....and get the pte address */
+ lwz r10, 0(r10) /* Get the pte */
+
+ /* Insert the Guarded flag into the TWC from the Linux PTE.
+ * It is bit 27 of both the Linux PTE and the TWC (at least
+ * I got that right :-). It will be better when we can put
+ * this into the Linux pgd/pmd and load it in the operation
+ * above.
+ */
+ rlwimi r11, r10, 0, 27, 27
+ DO_8xx_CPU6(0x3b80, r3)
+ mtspr SPRN_MD_TWC, r11
+
+ mfspr r11, SPRN_MD_TWC /* get the pte address again */
+ ori r10, r10, _PAGE_ACCESSED
+ stw r10, 0(r11)
+
+ /* The Linux PTE won't go exactly into the MMU TLB.
+ * Software indicator bits 21, 22 and 28 must be clear.
+ * Software indicator bits 24, 25, 26, and 27 must be
+ * set. All other Linux PTE bits control the behavior
+ * of the MMU.
+ */
+2: li r11, 0x00f0
+ rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */
+ DO_8xx_CPU6(0x3d80, r3)
+ mtspr SPRN_MD_RPN, r10 /* Update TLB entry */
+
+ mfspr r10, SPRN_M_TW /* Restore registers */
+ lwz r11, 0(r0)
+ mtcr r11
+ lwz r11, 4(r0)
+#ifdef CONFIG_8xx_CPU6
+ lwz r3, 8(r0)
+#endif
+ rfi
+
+/* This is an instruction TLB error on the MPC8xx. This could be due
+ * to many reasons, such as executing guarded memory or illegal instruction
+ * addresses. There is nothing to do but handle a big time error fault.
+ */
+ . = 0x1300
+InstructionTLBError:
+ b InstructionAccess
+
+/* This is the data TLB error on the MPC8xx. This could be due to
+ * many reasons, including a dirty update to a pte. We can catch that
+ * one here, but anything else is an error. First, we track down the
+ * Linux pte. If it is valid, write access is allowed, but the
+ * page dirty bit is not set, we will set it and reload the TLB. For
+ * any other case, we bail out to a higher level function that can
+ * handle it.
+ */
+ . = 0x1400
+DataTLBError:
+#ifdef CONFIG_8xx_CPU6
+ stw r3, 8(r0)
+#endif
+ DO_8xx_CPU6(0x3f80, r3)
+ mtspr SPRN_M_TW, r10 /* Save a couple of working registers */
+ mfcr r10
+ stw r10, 0(r0)
+ stw r11, 4(r0)
+
+ /* First, make sure this was a store operation.
+ */
+ mfspr r10, SPRN_DSISR
+ andis. r11, r10, 0x0200 /* If set, indicates store op */
+ beq 2f
+
+ /* The EA of a data TLB miss is automatically stored in the MD_EPN
+ * register. The EA of a data TLB error is automatically stored in
+ * the DAR, but not the MD_EPN register. We must copy the 20 most
+ * significant bits of the EA from the DAR to MD_EPN before we
+ * start walking the page tables. We also need to copy the CASID
+ * value from the M_CASID register.
+ * Addendum: The EA of a data TLB error is _supposed_ to be stored
+ * in DAR, but it seems that this doesn't happen in some cases, such
+ * as when the error is due to a dcbi instruction to a page with a
+ * TLB that doesn't have the changed bit set. In such cases, there
+ * does not appear to be any way to recover the EA of the error
+ * since it is neither in DAR nor MD_EPN. As a workaround, the
+ * _PAGE_HWWRITE bit is set for all kernel data pages when the PTEs
+ * are initialized in mapin_ram(). This will avoid the problem,
+ * assuming we only use the dcbi instruction on kernel addresses.
+ */
+ mfspr r10, SPRN_DAR
+ rlwinm r11, r10, 0, 0, 19
+ ori r11, r11, MD_EVALID
+ mfspr r10, SPRN_M_CASID
+ rlwimi r11, r10, 0, 28, 31
+ DO_8xx_CPU6(0x3780, r3)
+ mtspr SPRN_MD_EPN, r11
+
+ mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ andi. r11, r10, 0x0800
+ beq 3f
+ lis r11, swapper_pg_dir@h
+ ori r11, r11, swapper_pg_dir@l
+ rlwimi r10, r11, 0, 2, 19
+3:
+ lwz r11, 0(r10) /* Get the level 1 entry */
+ rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */
+ beq 2f /* If zero, bail */
+
+ /* We have a pte table, so fetch the pte from the table.
+ */
+ ori r11, r11, 1 /* Set valid bit in physical L2 page */
+ DO_8xx_CPU6(0x3b80, r3)
+ mtspr SPRN_MD_TWC, r11 /* Load pte table base address */
+ mfspr r11, SPRN_MD_TWC /* ....and get the pte address */
+ lwz r10, 0(r11) /* Get the pte */
+
+ andi. r11, r10, _PAGE_RW /* Is it writeable? */
+ beq 2f /* Bail out if not */
+
+ /* Update 'changed', among others.
+ */
+ ori r10, r10, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE
+ mfspr r11, SPRN_MD_TWC /* Get pte address again */
+ stw r10, 0(r11) /* and update pte in table */
+
+ /* The Linux PTE won't go exactly into the MMU TLB.
+ * Software indicator bits 21, 22 and 28 must be clear.
+ * Software indicator bits 24, 25, 26, and 27 must be
+ * set. All other Linux PTE bits control the behavior
+ * of the MMU.
+ */
+ li r11, 0x00f0
+ rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */
+ DO_8xx_CPU6(0x3d80, r3)
+ mtspr SPRN_MD_RPN, r10 /* Update TLB entry */
+
+ mfspr r10, SPRN_M_TW /* Restore registers */
+ lwz r11, 0(r0)
+ mtcr r11
+ lwz r11, 4(r0)
+#ifdef CONFIG_8xx_CPU6
+ lwz r3, 8(r0)
+#endif
+ rfi
+2:
+ mfspr r10, SPRN_M_TW /* Restore registers */
+ lwz r11, 0(r0)
+ mtcr r11
+ lwz r11, 4(r0)
+#ifdef CONFIG_8xx_CPU6
+ lwz r3, 8(r0)
+#endif
+ b DataAccess
+
+ EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1700, Trap_17, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1a00, Trap_1a, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1b00, Trap_1b, unknown_exception, EXC_XFER_EE)
+
+/* On the MPC8xx, these next four traps are used for development
+ * support of breakpoints and such. Someday I will get around to
+ * using them.
+ */
+ EXCEPTION(0x1c00, Trap_1c, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1d00, Trap_1d, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1e00, Trap_1e, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1f00, Trap_1f, unknown_exception, EXC_XFER_EE)
+
+ . = 0x2000
+
+ .globl giveup_fpu
+giveup_fpu:
+ blr
+
+/*
+ * This is where the main kernel code starts.
+ */
+start_here:
+ /* ptr to current */
+ lis r2,init_task@h
+ ori r2,r2,init_task@l
+
+ /* ptr to phys current thread */
+ tophys(r4,r2)
+ addi r4,r4,THREAD /* init task's THREAD */
+ mtspr SPRN_SPRG3,r4
+ li r3,0
+ mtspr SPRN_SPRG2,r3 /* 0 => r1 has kernel sp */
+
+ /* stack */
+ lis r1,init_thread_union@ha
+ addi r1,r1,init_thread_union@l
+ li r0,0
+ stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
+
+ bl early_init /* We have to do this with MMU on */
+
+/*
+ * Decide what sort of machine this is and initialize the MMU.
+ */
+ mr r3,r31
+ mr r4,r30
+ mr r5,r29
+ mr r6,r28
+ mr r7,r27
+ bl machine_init
+ bl MMU_init
+
+/*
+ * Go back to running unmapped so we can load up new values
+ * and change to using our exception vectors.
+ * On the 8xx, all we have to do is invalidate the TLB to clear
+ * the old 8M byte TLB mappings and load the page table base register.
+ */
+ /* The right way to do this would be to track it down through
+ * init's THREAD like the context switch code does, but this is
+ * easier......until someone changes init's static structures.
+ */
+ lis r6, swapper_pg_dir@h
+ ori r6, r6, swapper_pg_dir@l
+ tophys(r6,r6)
+#ifdef CONFIG_8xx_CPU6
+ lis r4, cpu6_errata_word@h
+ ori r4, r4, cpu6_errata_word@l
+ li r3, 0x3980
+ stw r3, 12(r4)
+ lwz r3, 12(r4)
+#endif
+ mtspr SPRN_M_TWB, r6
+ lis r4,2f@h
+ ori r4,r4,2f@l
+ tophys(r4,r4)
+ li r3,MSR_KERNEL & ~(MSR_IR|MSR_DR)
+ mtspr SPRN_SRR0,r4
+ mtspr SPRN_SRR1,r3
+ rfi
+/* Load up the kernel context */
+2:
+ SYNC /* Force all PTE updates to finish */
+ tlbia /* Clear all TLB entries */
+ sync /* wait for tlbia/tlbie to finish */
+ TLBSYNC /* ... on all CPUs */
+
+ /* set up the PTE pointers for the Abatron bdiGDB.
+ */
+ tovirt(r6,r6)
+ lis r5, abatron_pteptrs@h
+ ori r5, r5, abatron_pteptrs@l
+ stw r5, 0xf0(r0) /* Must match your Abatron config file */
+ tophys(r5,r5)
+ stw r6, 0(r5)
+
+/* Now turn on the MMU for real! */
+ li r4,MSR_KERNEL
+ lis r3,start_kernel@h
+ ori r3,r3,start_kernel@l
+ mtspr SPRN_SRR0,r3
+ mtspr SPRN_SRR1,r4
+ rfi /* enable MMU and jump to start_kernel */
+
+/* Set up the initial MMU state so we can do the first level of
+ * kernel initialization. This maps the first 8 MBytes of memory 1:1
+ * virtual to physical. Also, set the cache mode since that is defined
+ * by TLB entries and perform any additional mapping (like of the IMMR).
+ * If configured to pin some TLBs, we pin the first 8 Mbytes of kernel,
+ * 24 Mbytes of data, and the 8M IMMR space. Anything not covered by
+ * these mappings is mapped by page tables.
+ */
+initial_mmu:
+ tlbia /* Invalidate all TLB entries */
+#ifdef CONFIG_PIN_TLB
+ lis r8, MI_RSV4I@h
+ ori r8, r8, 0x1c00
+#else
+ li r8, 0
+#endif
+ mtspr SPRN_MI_CTR, r8 /* Set instruction MMU control */
+
+#ifdef CONFIG_PIN_TLB
+ lis r10, (MD_RSV4I | MD_RESETVAL)@h
+ ori r10, r10, 0x1c00
+ mr r8, r10
+#else
+ lis r10, MD_RESETVAL@h
+#endif
+#ifndef CONFIG_8xx_COPYBACK
+ oris r10, r10, MD_WTDEF@h
+#endif
+ mtspr SPRN_MD_CTR, r10 /* Set data TLB control */
+
+ /* Now map the lower 8 Meg into the TLBs. For this quick hack,
+ * we can load the instruction and data TLB registers with the
+ * same values.
+ */
+ lis r8, KERNELBASE@h /* Create vaddr for TLB */
+ ori r8, r8, MI_EVALID /* Mark it valid */
+ mtspr SPRN_MI_EPN, r8
+ mtspr SPRN_MD_EPN, r8
+ li r8, MI_PS8MEG /* Set 8M byte page */
+ ori r8, r8, MI_SVALID /* Make it valid */
+ mtspr SPRN_MI_TWC, r8
+ mtspr SPRN_MD_TWC, r8
+ li r8, MI_BOOTINIT /* Create RPN for address 0 */
+ mtspr SPRN_MI_RPN, r8 /* Store TLB entry */
+ mtspr SPRN_MD_RPN, r8
+ lis r8, MI_Kp@h /* Set the protection mode */
+ mtspr SPRN_MI_AP, r8
+ mtspr SPRN_MD_AP, r8
+
+ /* Map another 8 MByte at the IMMR to get the processor
+ * internal registers (among other things).
+ */
+#ifdef CONFIG_PIN_TLB
+ addi r10, r10, 0x0100
+ mtspr SPRN_MD_CTR, r10
+#endif
+ mfspr r9, 638 /* Get current IMMR */
+ andis. r9, r9, 0xff80 /* Get 8Mbyte boundary */
+
+ mr r8, r9 /* Create vaddr for TLB */
+ ori r8, r8, MD_EVALID /* Mark it valid */
+ mtspr SPRN_MD_EPN, r8
+ li r8, MD_PS8MEG /* Set 8M byte page */
+ ori r8, r8, MD_SVALID /* Make it valid */
+ mtspr SPRN_MD_TWC, r8
+ mr r8, r9 /* Create paddr for TLB */
+ ori r8, r8, MI_BOOTINIT|0x2 /* Inhibit cache -- Cort */
+ mtspr SPRN_MD_RPN, r8
+
+#ifdef CONFIG_PIN_TLB
+ /* Map two more 8M kernel data pages.
+ */
+ addi r10, r10, 0x0100
+ mtspr SPRN_MD_CTR, r10
+
+ lis r8, KERNELBASE@h /* Create vaddr for TLB */
+ addis r8, r8, 0x0080 /* Add 8M */
+ ori r8, r8, MI_EVALID /* Mark it valid */
+ mtspr SPRN_MD_EPN, r8
+ li r9, MI_PS8MEG /* Set 8M byte page */
+ ori r9, r9, MI_SVALID /* Make it valid */
+ mtspr SPRN_MD_TWC, r9
+ li r11, MI_BOOTINIT /* Create RPN for address 0 */
+ addis r11, r11, 0x0080 /* Add 8M */
+ mtspr SPRN_MD_RPN, r8
+
+ addis r8, r8, 0x0080 /* Add 8M */
+ mtspr SPRN_MD_EPN, r8
+ mtspr SPRN_MD_TWC, r9
+ addis r11, r11, 0x0080 /* Add 8M */
+ mtspr SPRN_MD_RPN, r8
+#endif
+
+ /* Since the cache is enabled according to the information we
+ * just loaded into the TLB, invalidate and enable the caches here.
+ * We should probably check/set other modes....later.
+ */
+ lis r8, IDC_INVALL@h
+ mtspr SPRN_IC_CST, r8
+ mtspr SPRN_DC_CST, r8
+ lis r8, IDC_ENABLE@h
+ mtspr SPRN_IC_CST, r8
+#ifdef CONFIG_8xx_COPYBACK
+ mtspr SPRN_DC_CST, r8
+#else
+ /* For a debug option, I left this here to easily enable
+ * the write through cache mode
+ */
+ lis r8, DC_SFWT@h
+ mtspr SPRN_DC_CST, r8
+ lis r8, IDC_ENABLE@h
+ mtspr SPRN_DC_CST, r8
+#endif
+ blr
+
+
+/*
+ * Set up to use a given MMU context.
+ * r3 is context number, r4 is PGD pointer.
+ *
+ * We place the physical address of the new task page directory loaded
+ * into the MMU base register, and set the ASID compare register with
+ * the new "context."
+ */
+_GLOBAL(set_context)
+
+#ifdef CONFIG_BDI_SWITCH
+ /* Context switch the PTE pointer for the Abatron BDI2000.
+ * The PGDIR is passed as second argument.
+ */
+ lis r5, KERNELBASE@h
+ lwz r5, 0xf0(r5)
+ stw r4, 0x4(r5)
+#endif
+
+#ifdef CONFIG_8xx_CPU6
+ lis r6, cpu6_errata_word@h
+ ori r6, r6, cpu6_errata_word@l
+ tophys (r4, r4)
+ li r7, 0x3980
+ stw r7, 12(r6)
+ lwz r7, 12(r6)
+ mtspr SPRN_M_TWB, r4 /* Update MMU base address */
+ li r7, 0x3380
+ stw r7, 12(r6)
+ lwz r7, 12(r6)
+ mtspr SPRN_M_CASID, r3 /* Update context */
+#else
+ mtspr SPRN_M_CASID,r3 /* Update context */
+ tophys (r4, r4)
+ mtspr SPRN_M_TWB, r4 /* and pgd */
+#endif
+ SYNC
+ blr
+
+#ifdef CONFIG_8xx_CPU6
+/* It's here because it is unique to the 8xx.
+ * It is important we get called with interrupts disabled. I used to
+ * do that, but it appears that all code that calls this already had
+ * interrupt disabled.
+ */
+ .globl set_dec_cpu6
+set_dec_cpu6:
+ lis r7, cpu6_errata_word@h
+ ori r7, r7, cpu6_errata_word@l
+ li r4, 0x2c00
+ stw r4, 8(r7)
+ lwz r4, 8(r7)
+ mtspr 22, r3 /* Update Decrementer */
+ SYNC
+ blr
+#endif
+
+/*
+ * We put a few things here that have to be page-aligned.
+ * This stuff goes at the beginning of the data segment,
+ * which is page-aligned.
+ */
+ .data
+ .globl sdata
+sdata:
+ .globl empty_zero_page
+empty_zero_page:
+ .space 4096
+
+ .globl swapper_pg_dir
+swapper_pg_dir:
+ .space 4096
+
+/*
+ * This space gets a copy of optional info passed to us by the bootstrap
+ * Used to pass parameters into the kernel like root=/dev/sda1, etc.
+ */
+ .globl cmd_line
+cmd_line:
+ .space 512
+
+/* Room for two PTE table poiners, usually the kernel and current user
+ * pointer to their respective root page table (pgdir).
+ */
+abatron_pteptrs:
+ .space 8
+
+#ifdef CONFIG_8xx_CPU6
+ .globl cpu6_errata_word
+cpu6_errata_word:
+ .space 16
+#endif
+
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
new file mode 100644
index 000000000000..5063c603fad4
--- /dev/null
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -0,0 +1,1063 @@
+/*
+ * arch/ppc/kernel/head_fsl_booke.S
+ *
+ * Kernel execution entry point code.
+ *
+ * Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org>
+ * Initial PowerPC version.
+ * Copyright (c) 1996 Cort Dougan <cort@cs.nmt.edu>
+ * Rewritten for PReP
+ * Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
+ * Low-level exception handers, MMU support, and rewrite.
+ * Copyright (c) 1997 Dan Malek <dmalek@jlc.net>
+ * PowerPC 8xx modifications.
+ * Copyright (c) 1998-1999 TiVo, Inc.
+ * PowerPC 403GCX modifications.
+ * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ * PowerPC 403GCX/405GP modifications.
+ * Copyright 2000 MontaVista Software Inc.
+ * PPC405 modifications
+ * PowerPC 403GCX/405GP modifications.
+ * Author: MontaVista Software, Inc.
+ * frank_rowand@mvista.com or source@mvista.com
+ * debbie_chu@mvista.com
+ * Copyright 2002-2004 MontaVista Software, Inc.
+ * PowerPC 44x support, Matt Porter <mporter@kernel.crashing.org>
+ * Copyright 2004 Freescale Semiconductor, Inc
+ * PowerPC e500 modifications, Kumar Gala <kumar.gala@freescale.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/threads.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/cputable.h>
+#include <asm/thread_info.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+#include "head_booke.h"
+
+/* As with the other PowerPC ports, it is expected that when code
+ * execution begins here, the following registers contain valid, yet
+ * optional, information:
+ *
+ * r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.)
+ * r4 - Starting address of the init RAM disk
+ * r5 - Ending address of the init RAM disk
+ * r6 - Start of kernel command line string (e.g. "mem=128")
+ * r7 - End of kernel command line string
+ *
+ */
+ .text
+_GLOBAL(_stext)
+_GLOBAL(_start)
+ /*
+ * Reserve a word at a fixed location to store the address
+ * of abatron_pteptrs
+ */
+ nop
+/*
+ * Save parameters we are passed
+ */
+ mr r31,r3
+ mr r30,r4
+ mr r29,r5
+ mr r28,r6
+ mr r27,r7
+ li r24,0 /* CPU number */
+
+/* We try to not make any assumptions about how the boot loader
+ * setup or used the TLBs. We invalidate all mappings from the
+ * boot loader and load a single entry in TLB1[0] to map the
+ * first 16M of kernel memory. Any boot info passed from the
+ * bootloader needs to live in this first 16M.
+ *
+ * Requirement on bootloader:
+ * - The page we're executing in needs to reside in TLB1 and
+ * have IPROT=1. If not an invalidate broadcast could
+ * evict the entry we're currently executing in.
+ *
+ * r3 = Index of TLB1 were executing in
+ * r4 = Current MSR[IS]
+ * r5 = Index of TLB1 temp mapping
+ *
+ * Later in mapin_ram we will correctly map lowmem, and resize TLB1[0]
+ * if needed
+ */
+
+/* 1. Find the index of the entry we're executing in */
+ bl invstr /* Find our address */
+invstr: mflr r6 /* Make it accessible */
+ mfmsr r7
+ rlwinm r4,r7,27,31,31 /* extract MSR[IS] */
+ mfspr r7, SPRN_PID0
+ slwi r7,r7,16
+ or r7,r7,r4
+ mtspr SPRN_MAS6,r7
+ tlbsx 0,r6 /* search MSR[IS], SPID=PID0 */
+#ifndef CONFIG_E200
+ mfspr r7,SPRN_MAS1
+ andis. r7,r7,MAS1_VALID@h
+ bne match_TLB
+ mfspr r7,SPRN_PID1
+ slwi r7,r7,16
+ or r7,r7,r4
+ mtspr SPRN_MAS6,r7
+ tlbsx 0,r6 /* search MSR[IS], SPID=PID1 */
+ mfspr r7,SPRN_MAS1
+ andis. r7,r7,MAS1_VALID@h
+ bne match_TLB
+ mfspr r7, SPRN_PID2
+ slwi r7,r7,16
+ or r7,r7,r4
+ mtspr SPRN_MAS6,r7
+ tlbsx 0,r6 /* Fall through, we had to match */
+#endif
+match_TLB:
+ mfspr r7,SPRN_MAS0
+ rlwinm r3,r7,16,20,31 /* Extract MAS0(Entry) */
+
+ mfspr r7,SPRN_MAS1 /* Insure IPROT set */
+ oris r7,r7,MAS1_IPROT@h
+ mtspr SPRN_MAS1,r7
+ tlbwe
+
+/* 2. Invalidate all entries except the entry we're executing in */
+ mfspr r9,SPRN_TLB1CFG
+ andi. r9,r9,0xfff
+ li r6,0 /* Set Entry counter to 0 */
+1: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
+ rlwimi r7,r6,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r6) */
+ mtspr SPRN_MAS0,r7
+ tlbre
+ mfspr r7,SPRN_MAS1
+ rlwinm r7,r7,0,2,31 /* Clear MAS1 Valid and IPROT */
+ cmpw r3,r6
+ beq skpinv /* Dont update the current execution TLB */
+ mtspr SPRN_MAS1,r7
+ tlbwe
+ isync
+skpinv: addi r6,r6,1 /* Increment */
+ cmpw r6,r9 /* Are we done? */
+ bne 1b /* If not, repeat */
+
+ /* Invalidate TLB0 */
+ li r6,0x04
+ tlbivax 0,r6
+#ifdef CONFIG_SMP
+ tlbsync
+#endif
+ /* Invalidate TLB1 */
+ li r6,0x0c
+ tlbivax 0,r6
+#ifdef CONFIG_SMP
+ tlbsync
+#endif
+ msync
+
+/* 3. Setup a temp mapping and jump to it */
+ andi. r5, r3, 0x1 /* Find an entry not used and is non-zero */
+ addi r5, r5, 0x1
+ lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
+ rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */
+ mtspr SPRN_MAS0,r7
+ tlbre
+
+ /* Just modify the entry ID and EPN for the temp mapping */
+ lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
+ rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */
+ mtspr SPRN_MAS0,r7
+ xori r6,r4,1 /* Setup TMP mapping in the other Address space */
+ slwi r6,r6,12
+ oris r6,r6,(MAS1_VALID|MAS1_IPROT)@h
+ ori r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_4K))@l
+ mtspr SPRN_MAS1,r6
+ mfspr r6,SPRN_MAS2
+ li r7,0 /* temp EPN = 0 */
+ rlwimi r7,r6,0,20,31
+ mtspr SPRN_MAS2,r7
+ tlbwe
+
+ xori r6,r4,1
+ slwi r6,r6,5 /* setup new context with other address space */
+ bl 1f /* Find our address */
+1: mflr r9
+ rlwimi r7,r9,0,20,31
+ addi r7,r7,24
+ mtspr SPRN_SRR0,r7
+ mtspr SPRN_SRR1,r6
+ rfi
+
+/* 4. Clear out PIDs & Search info */
+ li r6,0
+ mtspr SPRN_PID0,r6
+#ifndef CONFIG_E200
+ mtspr SPRN_PID1,r6
+ mtspr SPRN_PID2,r6
+#endif
+ mtspr SPRN_MAS6,r6
+
+/* 5. Invalidate mapping we started in */
+ lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
+ rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */
+ mtspr SPRN_MAS0,r7
+ tlbre
+ li r6,0
+ mtspr SPRN_MAS1,r6
+ tlbwe
+ /* Invalidate TLB1 */
+ li r9,0x0c
+ tlbivax 0,r9
+#ifdef CONFIG_SMP
+ tlbsync
+#endif
+ msync
+
+/* 6. Setup KERNELBASE mapping in TLB1[0] */
+ lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */
+ mtspr SPRN_MAS0,r6
+ lis r6,(MAS1_VALID|MAS1_IPROT)@h
+ ori r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_16M))@l
+ mtspr SPRN_MAS1,r6
+ li r7,0
+ lis r6,KERNELBASE@h
+ ori r6,r6,KERNELBASE@l
+ rlwimi r6,r7,0,20,31
+ mtspr SPRN_MAS2,r6
+ li r7,(MAS3_SX|MAS3_SW|MAS3_SR)
+ mtspr SPRN_MAS3,r7
+ tlbwe
+
+/* 7. Jump to KERNELBASE mapping */
+ lis r7,MSR_KERNEL@h
+ ori r7,r7,MSR_KERNEL@l
+ bl 1f /* Find our address */
+1: mflr r9
+ rlwimi r6,r9,0,20,31
+ addi r6,r6,24
+ mtspr SPRN_SRR0,r6
+ mtspr SPRN_SRR1,r7
+ rfi /* start execution out of TLB1[0] entry */
+
+/* 8. Clear out the temp mapping */
+ lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
+ rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */
+ mtspr SPRN_MAS0,r7
+ tlbre
+ mtspr SPRN_MAS1,r8
+ tlbwe
+ /* Invalidate TLB1 */
+ li r9,0x0c
+ tlbivax 0,r9
+#ifdef CONFIG_SMP
+ tlbsync
+#endif
+ msync
+
+ /* Establish the interrupt vector offsets */
+ SET_IVOR(0, CriticalInput);
+ SET_IVOR(1, MachineCheck);
+ SET_IVOR(2, DataStorage);
+ SET_IVOR(3, InstructionStorage);
+ SET_IVOR(4, ExternalInput);
+ SET_IVOR(5, Alignment);
+ SET_IVOR(6, Program);
+ SET_IVOR(7, FloatingPointUnavailable);
+ SET_IVOR(8, SystemCall);
+ SET_IVOR(9, AuxillaryProcessorUnavailable);
+ SET_IVOR(10, Decrementer);
+ SET_IVOR(11, FixedIntervalTimer);
+ SET_IVOR(12, WatchdogTimer);
+ SET_IVOR(13, DataTLBError);
+ SET_IVOR(14, InstructionTLBError);
+ SET_IVOR(15, Debug);
+ SET_IVOR(32, SPEUnavailable);
+ SET_IVOR(33, SPEFloatingPointData);
+ SET_IVOR(34, SPEFloatingPointRound);
+#ifndef CONFIG_E200
+ SET_IVOR(35, PerformanceMonitor);
+#endif
+
+ /* Establish the interrupt vector base */
+ lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */
+ mtspr SPRN_IVPR,r4
+
+ /* Setup the defaults for TLB entries */
+ li r2,(MAS4_TSIZED(BOOKE_PAGESZ_4K))@l
+#ifdef CONFIG_E200
+ oris r2,r2,MAS4_TLBSELD(1)@h
+#endif
+ mtspr SPRN_MAS4, r2
+
+#if 0
+ /* Enable DOZE */
+ mfspr r2,SPRN_HID0
+ oris r2,r2,HID0_DOZE@h
+ mtspr SPRN_HID0, r2
+#endif
+#ifdef CONFIG_E200
+ /* enable dedicated debug exception handling resources (Debug APU) */
+ mfspr r2,SPRN_HID0
+ ori r2,r2,HID0_DAPUEN@l
+ mtspr SPRN_HID0,r2
+#endif
+
+#if !defined(CONFIG_BDI_SWITCH)
+ /*
+ * The Abatron BDI JTAG debugger does not tolerate others
+ * mucking with the debug registers.
+ */
+ lis r2,DBCR0_IDM@h
+ mtspr SPRN_DBCR0,r2
+ /* clear any residual debug events */
+ li r2,-1
+ mtspr SPRN_DBSR,r2
+#endif
+
+ /*
+ * This is where the main kernel code starts.
+ */
+
+ /* ptr to current */
+ lis r2,init_task@h
+ ori r2,r2,init_task@l
+
+ /* ptr to current thread */
+ addi r4,r2,THREAD /* init task's THREAD */
+ mtspr SPRN_SPRG3,r4
+
+ /* stack */
+ lis r1,init_thread_union@h
+ ori r1,r1,init_thread_union@l
+ li r0,0
+ stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
+
+ bl early_init
+
+ mfspr r3,SPRN_TLB1CFG
+ andi. r3,r3,0xfff
+ lis r4,num_tlbcam_entries@ha
+ stw r3,num_tlbcam_entries@l(r4)
+/*
+ * Decide what sort of machine this is and initialize the MMU.
+ */
+ mr r3,r31
+ mr r4,r30
+ mr r5,r29
+ mr r6,r28
+ mr r7,r27
+ bl machine_init
+ bl MMU_init
+
+ /* Setup PTE pointers for the Abatron bdiGDB */
+ lis r6, swapper_pg_dir@h
+ ori r6, r6, swapper_pg_dir@l
+ lis r5, abatron_pteptrs@h
+ ori r5, r5, abatron_pteptrs@l
+ lis r4, KERNELBASE@h
+ ori r4, r4, KERNELBASE@l
+ stw r5, 0(r4) /* Save abatron_pteptrs at a fixed location */
+ stw r6, 0(r5)
+
+ /* Let's move on */
+ lis r4,start_kernel@h
+ ori r4,r4,start_kernel@l
+ lis r3,MSR_KERNEL@h
+ ori r3,r3,MSR_KERNEL@l
+ mtspr SPRN_SRR0,r4
+ mtspr SPRN_SRR1,r3
+ rfi /* change context and jump to start_kernel */
+
+/* Macros to hide the PTE size differences
+ *
+ * FIND_PTE -- walks the page tables given EA & pgdir pointer
+ * r10 -- EA of fault
+ * r11 -- PGDIR pointer
+ * r12 -- free
+ * label 2: is the bailout case
+ *
+ * if we find the pte (fall through):
+ * r11 is low pte word
+ * r12 is pointer to the pte
+ */
+#ifdef CONFIG_PTE_64BIT
+#define PTE_FLAGS_OFFSET 4
+#define FIND_PTE \
+ rlwinm r12, r10, 13, 19, 29; /* Compute pgdir/pmd offset */ \
+ lwzx r11, r12, r11; /* Get pgd/pmd entry */ \
+ rlwinm. r12, r11, 0, 0, 20; /* Extract pt base address */ \
+ beq 2f; /* Bail if no table */ \
+ rlwimi r12, r10, 23, 20, 28; /* Compute pte address */ \
+ lwz r11, 4(r12); /* Get pte entry */
+#else
+#define PTE_FLAGS_OFFSET 0
+#define FIND_PTE \
+ rlwimi r11, r10, 12, 20, 29; /* Create L1 (pgdir/pmd) address */ \
+ lwz r11, 0(r11); /* Get L1 entry */ \
+ rlwinm. r12, r11, 0, 0, 19; /* Extract L2 (pte) base address */ \
+ beq 2f; /* Bail if no table */ \
+ rlwimi r12, r10, 22, 20, 29; /* Compute PTE address */ \
+ lwz r11, 0(r12); /* Get Linux PTE */
+#endif
+
+/*
+ * Interrupt vector entry code
+ *
+ * The Book E MMUs are always on so we don't need to handle
+ * interrupts in real mode as with previous PPC processors. In
+ * this case we handle interrupts in the kernel virtual address
+ * space.
+ *
+ * Interrupt vectors are dynamically placed relative to the
+ * interrupt prefix as determined by the address of interrupt_base.
+ * The interrupt vectors offsets are programmed using the labels
+ * for each interrupt vector entry.
+ *
+ * Interrupt vectors must be aligned on a 16 byte boundary.
+ * We align on a 32 byte cache line boundary for good measure.
+ */
+
+interrupt_base:
+ /* Critical Input Interrupt */
+ CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception)
+
+ /* Machine Check Interrupt */
+#ifdef CONFIG_E200
+ /* no RFMCI, MCSRRs on E200 */
+ CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
+#else
+ MCHECK_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
+#endif
+
+ /* Data Storage Interrupt */
+ START_EXCEPTION(DataStorage)
+ mtspr SPRN_SPRG0, r10 /* Save some working registers */
+ mtspr SPRN_SPRG1, r11
+ mtspr SPRN_SPRG4W, r12
+ mtspr SPRN_SPRG5W, r13
+ mfcr r11
+ mtspr SPRN_SPRG7W, r11
+
+ /*
+ * Check if it was a store fault, if not then bail
+ * because a user tried to access a kernel or
+ * read-protected page. Otherwise, get the
+ * offending address and handle it.
+ */
+ mfspr r10, SPRN_ESR
+ andis. r10, r10, ESR_ST@h
+ beq 2f
+
+ mfspr r10, SPRN_DEAR /* Get faulting address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ lis r11, TASK_SIZE@h
+ ori r11, r11, TASK_SIZE@l
+ cmplw 0, r10, r11
+ bge 2f
+
+ /* Get the PGD for the current thread */
+3:
+ mfspr r11,SPRN_SPRG3
+ lwz r11,PGDIR(r11)
+4:
+ FIND_PTE
+
+ /* Are _PAGE_USER & _PAGE_RW set & _PAGE_HWWRITE not? */
+ andi. r13, r11, _PAGE_RW|_PAGE_USER|_PAGE_HWWRITE
+ cmpwi 0, r13, _PAGE_RW|_PAGE_USER
+ bne 2f /* Bail if not */
+
+ /* Update 'changed'. */
+ ori r11, r11, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE
+ stw r11, PTE_FLAGS_OFFSET(r12) /* Update Linux page table */
+
+ /* MAS2 not updated as the entry does exist in the tlb, this
+ fault taken to detect state transition (eg: COW -> DIRTY)
+ */
+ andi. r11, r11, _PAGE_HWEXEC
+ rlwimi r11, r11, 31, 27, 27 /* SX <- _PAGE_HWEXEC */
+ ori r11, r11, (MAS3_UW|MAS3_SW|MAS3_UR|MAS3_SR)@l /* set static perms */
+
+ /* update search PID in MAS6, AS = 0 */
+ mfspr r12, SPRN_PID0
+ slwi r12, r12, 16
+ mtspr SPRN_MAS6, r12
+
+ /* find the TLB index that caused the fault. It has to be here. */
+ tlbsx 0, r10
+
+ /* only update the perm bits, assume the RPN is fine */
+ mfspr r12, SPRN_MAS3
+ rlwimi r12, r11, 0, 20, 31
+ mtspr SPRN_MAS3,r12
+ tlbwe
+
+ /* Done...restore registers and get out of here. */
+ mfspr r11, SPRN_SPRG7R
+ mtcr r11
+ mfspr r13, SPRN_SPRG5R
+ mfspr r12, SPRN_SPRG4R
+ mfspr r11, SPRN_SPRG1
+ mfspr r10, SPRN_SPRG0
+ rfi /* Force context change */
+
+2:
+ /*
+ * The bailout. Restore registers to pre-exception conditions
+ * and call the heavyweights to help us out.
+ */
+ mfspr r11, SPRN_SPRG7R
+ mtcr r11
+ mfspr r13, SPRN_SPRG5R
+ mfspr r12, SPRN_SPRG4R
+ mfspr r11, SPRN_SPRG1
+ mfspr r10, SPRN_SPRG0
+ b data_access
+
+ /* Instruction Storage Interrupt */
+ INSTRUCTION_STORAGE_EXCEPTION
+
+ /* External Input Interrupt */
+ EXCEPTION(0x0500, ExternalInput, do_IRQ, EXC_XFER_LITE)
+
+ /* Alignment Interrupt */
+ ALIGNMENT_EXCEPTION
+
+ /* Program Interrupt */
+ PROGRAM_EXCEPTION
+
+ /* Floating Point Unavailable Interrupt */
+#ifdef CONFIG_PPC_FPU
+ FP_UNAVAILABLE_EXCEPTION
+#else
+#ifdef CONFIG_E200
+ /* E200 treats 'normal' floating point instructions as FP Unavail exception */
+ EXCEPTION(0x0800, FloatingPointUnavailable, program_check_exception, EXC_XFER_EE)
+#else
+ EXCEPTION(0x0800, FloatingPointUnavailable, unknown_exception, EXC_XFER_EE)
+#endif
+#endif
+
+ /* System Call Interrupt */
+ START_EXCEPTION(SystemCall)
+ NORMAL_EXCEPTION_PROLOG
+ EXC_XFER_EE_LITE(0x0c00, DoSyscall)
+
+ /* Auxillary Processor Unavailable Interrupt */
+ EXCEPTION(0x2900, AuxillaryProcessorUnavailable, unknown_exception, EXC_XFER_EE)
+
+ /* Decrementer Interrupt */
+ DECREMENTER_EXCEPTION
+
+ /* Fixed Internal Timer Interrupt */
+ /* TODO: Add FIT support */
+ EXCEPTION(0x3100, FixedIntervalTimer, unknown_exception, EXC_XFER_EE)
+
+ /* Watchdog Timer Interrupt */
+#ifdef CONFIG_BOOKE_WDT
+ CRITICAL_EXCEPTION(0x3200, WatchdogTimer, WatchdogException)
+#else
+ CRITICAL_EXCEPTION(0x3200, WatchdogTimer, unknown_exception)
+#endif
+
+ /* Data TLB Error Interrupt */
+ START_EXCEPTION(DataTLBError)
+ mtspr SPRN_SPRG0, r10 /* Save some working registers */
+ mtspr SPRN_SPRG1, r11
+ mtspr SPRN_SPRG4W, r12
+ mtspr SPRN_SPRG5W, r13
+ mfcr r11
+ mtspr SPRN_SPRG7W, r11
+ mfspr r10, SPRN_DEAR /* Get faulting address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ lis r11, TASK_SIZE@h
+ ori r11, r11, TASK_SIZE@l
+ cmplw 5, r10, r11
+ blt 5, 3f
+ lis r11, swapper_pg_dir@h
+ ori r11, r11, swapper_pg_dir@l
+
+ mfspr r12,SPRN_MAS1 /* Set TID to 0 */
+ rlwinm r12,r12,0,16,1
+ mtspr SPRN_MAS1,r12
+
+ b 4f
+
+ /* Get the PGD for the current thread */
+3:
+ mfspr r11,SPRN_SPRG3
+ lwz r11,PGDIR(r11)
+
+4:
+ FIND_PTE
+ andi. r13, r11, _PAGE_PRESENT /* Is the page present? */
+ beq 2f /* Bail if not present */
+
+#ifdef CONFIG_PTE_64BIT
+ lwz r13, 0(r12)
+#endif
+ ori r11, r11, _PAGE_ACCESSED
+ stw r11, PTE_FLAGS_OFFSET(r12)
+
+ /* Jump to common tlb load */
+ b finish_tlb_load
+2:
+ /* The bailout. Restore registers to pre-exception conditions
+ * and call the heavyweights to help us out.
+ */
+ mfspr r11, SPRN_SPRG7R
+ mtcr r11
+ mfspr r13, SPRN_SPRG5R
+ mfspr r12, SPRN_SPRG4R
+ mfspr r11, SPRN_SPRG1
+ mfspr r10, SPRN_SPRG0
+ b data_access
+
+ /* Instruction TLB Error Interrupt */
+ /*
+ * Nearly the same as above, except we get our
+ * information from different registers and bailout
+ * to a different point.
+ */
+ START_EXCEPTION(InstructionTLBError)
+ mtspr SPRN_SPRG0, r10 /* Save some working registers */
+ mtspr SPRN_SPRG1, r11
+ mtspr SPRN_SPRG4W, r12
+ mtspr SPRN_SPRG5W, r13
+ mfcr r11
+ mtspr SPRN_SPRG7W, r11
+ mfspr r10, SPRN_SRR0 /* Get faulting address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ lis r11, TASK_SIZE@h
+ ori r11, r11, TASK_SIZE@l
+ cmplw 5, r10, r11
+ blt 5, 3f
+ lis r11, swapper_pg_dir@h
+ ori r11, r11, swapper_pg_dir@l
+
+ mfspr r12,SPRN_MAS1 /* Set TID to 0 */
+ rlwinm r12,r12,0,16,1
+ mtspr SPRN_MAS1,r12
+
+ b 4f
+
+ /* Get the PGD for the current thread */
+3:
+ mfspr r11,SPRN_SPRG3
+ lwz r11,PGDIR(r11)
+
+4:
+ FIND_PTE
+ andi. r13, r11, _PAGE_PRESENT /* Is the page present? */
+ beq 2f /* Bail if not present */
+
+#ifdef CONFIG_PTE_64BIT
+ lwz r13, 0(r12)
+#endif
+ ori r11, r11, _PAGE_ACCESSED
+ stw r11, PTE_FLAGS_OFFSET(r12)
+
+ /* Jump to common TLB load point */
+ b finish_tlb_load
+
+2:
+ /* The bailout. Restore registers to pre-exception conditions
+ * and call the heavyweights to help us out.
+ */
+ mfspr r11, SPRN_SPRG7R
+ mtcr r11
+ mfspr r13, SPRN_SPRG5R
+ mfspr r12, SPRN_SPRG4R
+ mfspr r11, SPRN_SPRG1
+ mfspr r10, SPRN_SPRG0
+ b InstructionStorage
+
+#ifdef CONFIG_SPE
+ /* SPE Unavailable */
+ START_EXCEPTION(SPEUnavailable)
+ NORMAL_EXCEPTION_PROLOG
+ bne load_up_spe
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ EXC_XFER_EE_LITE(0x2010, KernelSPE)
+#else
+ EXCEPTION(0x2020, SPEUnavailable, unknown_exception, EXC_XFER_EE)
+#endif /* CONFIG_SPE */
+
+ /* SPE Floating Point Data */
+#ifdef CONFIG_SPE
+ EXCEPTION(0x2030, SPEFloatingPointData, SPEFloatingPointException, EXC_XFER_EE);
+#else
+ EXCEPTION(0x2040, SPEFloatingPointData, unknown_exception, EXC_XFER_EE)
+#endif /* CONFIG_SPE */
+
+ /* SPE Floating Point Round */
+ EXCEPTION(0x2050, SPEFloatingPointRound, unknown_exception, EXC_XFER_EE)
+
+ /* Performance Monitor */
+ EXCEPTION(0x2060, PerformanceMonitor, performance_monitor_exception, EXC_XFER_STD)
+
+
+ /* Debug Interrupt */
+ DEBUG_EXCEPTION
+
+/*
+ * Local functions
+ */
+
+ /*
+ * Data TLB exceptions will bail out to this point
+ * if they can't resolve the lightweight TLB fault.
+ */
+data_access:
+ NORMAL_EXCEPTION_PROLOG
+ mfspr r5,SPRN_ESR /* Grab the ESR, save it, pass arg3 */
+ stw r5,_ESR(r11)
+ mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */
+ andis. r10,r5,(ESR_ILK|ESR_DLK)@h
+ bne 1f
+ EXC_XFER_EE_LITE(0x0300, handle_page_fault)
+1:
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ EXC_XFER_EE_LITE(0x0300, CacheLockingException)
+
+/*
+
+ * Both the instruction and data TLB miss get to this
+ * point to load the TLB.
+ * r10 - EA of fault
+ * r11 - TLB (info from Linux PTE)
+ * r12, r13 - available to use
+ * CR5 - results of addr < TASK_SIZE
+ * MAS0, MAS1 - loaded with proper value when we get here
+ * MAS2, MAS3 - will need additional info from Linux PTE
+ * Upon exit, we reload everything and RFI.
+ */
+finish_tlb_load:
+ /*
+ * We set execute, because we don't have the granularity to
+ * properly set this at the page level (Linux problem).
+ * Many of these bits are software only. Bits we don't set
+ * here we (properly should) assume have the appropriate value.
+ */
+
+ mfspr r12, SPRN_MAS2
+#ifdef CONFIG_PTE_64BIT
+ rlwimi r12, r11, 26, 24, 31 /* extract ...WIMGE from pte */
+#else
+ rlwimi r12, r11, 26, 27, 31 /* extract WIMGE from pte */
+#endif
+ mtspr SPRN_MAS2, r12
+
+ bge 5, 1f
+
+ /* is user addr */
+ andi. r12, r11, (_PAGE_USER | _PAGE_HWWRITE | _PAGE_HWEXEC)
+ andi. r10, r11, _PAGE_USER /* Test for _PAGE_USER */
+ srwi r10, r12, 1
+ or r12, r12, r10 /* Copy user perms into supervisor */
+ iseleq r12, 0, r12
+ b 2f
+
+ /* is kernel addr */
+1: rlwinm r12, r11, 31, 29, 29 /* Extract _PAGE_HWWRITE into SW */
+ ori r12, r12, (MAS3_SX | MAS3_SR)
+
+#ifdef CONFIG_PTE_64BIT
+2: rlwimi r12, r13, 24, 0, 7 /* grab RPN[32:39] */
+ rlwimi r12, r11, 24, 8, 19 /* grab RPN[40:51] */
+ mtspr SPRN_MAS3, r12
+BEGIN_FTR_SECTION
+ srwi r10, r13, 8 /* grab RPN[8:31] */
+ mtspr SPRN_MAS7, r10
+END_FTR_SECTION_IFSET(CPU_FTR_BIG_PHYS)
+#else
+2: rlwimi r11, r12, 0, 20, 31 /* Extract RPN from PTE and merge with perms */
+ mtspr SPRN_MAS3, r11
+#endif
+#ifdef CONFIG_E200
+ /* Round robin TLB1 entries assignment */
+ mfspr r12, SPRN_MAS0
+
+ /* Extract TLB1CFG(NENTRY) */
+ mfspr r11, SPRN_TLB1CFG
+ andi. r11, r11, 0xfff
+
+ /* Extract MAS0(NV) */
+ andi. r13, r12, 0xfff
+ addi r13, r13, 1
+ cmpw 0, r13, r11
+ addi r12, r12, 1
+
+ /* check if we need to wrap */
+ blt 7f
+
+ /* wrap back to first free tlbcam entry */
+ lis r13, tlbcam_index@ha
+ lwz r13, tlbcam_index@l(r13)
+ rlwimi r12, r13, 0, 20, 31
+7:
+ mtspr SPRN_MAS0,r12
+#endif /* CONFIG_E200 */
+
+ tlbwe
+
+ /* Done...restore registers and get out of here. */
+ mfspr r11, SPRN_SPRG7R
+ mtcr r11
+ mfspr r13, SPRN_SPRG5R
+ mfspr r12, SPRN_SPRG4R
+ mfspr r11, SPRN_SPRG1
+ mfspr r10, SPRN_SPRG0
+ rfi /* Force context change */
+
+#ifdef CONFIG_SPE
+/* Note that the SPE support is closely modeled after the AltiVec
+ * support. Changes to one are likely to be applicable to the
+ * other! */
+load_up_spe:
+/*
+ * Disable SPE for the task which had SPE previously,
+ * and save its SPE registers in its thread_struct.
+ * Enables SPE for use in the kernel on return.
+ * On SMP we know the SPE units are free, since we give it up every
+ * switch. -- Kumar
+ */
+ mfmsr r5
+ oris r5,r5,MSR_SPE@h
+ mtmsr r5 /* enable use of SPE now */
+ isync
+/*
+ * For SMP, we don't do lazy SPE switching because it just gets too
+ * horrendously complex, especially when a task switches from one CPU
+ * to another. Instead we call giveup_spe in switch_to.
+ */
+#ifndef CONFIG_SMP
+ lis r3,last_task_used_spe@ha
+ lwz r4,last_task_used_spe@l(r3)
+ cmpi 0,r4,0
+ beq 1f
+ addi r4,r4,THREAD /* want THREAD of last_task_used_spe */
+ SAVE_32EVRS(0,r10,r4)
+ evxor evr10, evr10, evr10 /* clear out evr10 */
+ evmwumiaa evr10, evr10, evr10 /* evr10 <- ACC = 0 * 0 + ACC */
+ li r5,THREAD_ACC
+ evstddx evr10, r4, r5 /* save off accumulator */
+ lwz r5,PT_REGS(r4)
+ lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+ lis r10,MSR_SPE@h
+ andc r4,r4,r10 /* disable SPE for previous task */
+ stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:
+#endif /* CONFIG_SMP */
+ /* enable use of SPE after return */
+ oris r9,r9,MSR_SPE@h
+ mfspr r5,SPRN_SPRG3 /* current task's THREAD (phys) */
+ li r4,1
+ li r10,THREAD_ACC
+ stw r4,THREAD_USED_SPE(r5)
+ evlddx evr4,r10,r5
+ evmra evr4,evr4
+ REST_32EVRS(0,r10,r5)
+#ifndef CONFIG_SMP
+ subi r4,r5,THREAD
+ stw r4,last_task_used_spe@l(r3)
+#endif /* CONFIG_SMP */
+ /* restore registers and return */
+2: REST_4GPRS(3, r11)
+ lwz r10,_CCR(r11)
+ REST_GPR(1, r11)
+ mtcr r10
+ lwz r10,_LINK(r11)
+ mtlr r10
+ REST_GPR(10, r11)
+ mtspr SPRN_SRR1,r9
+ mtspr SPRN_SRR0,r12
+ REST_GPR(9, r11)
+ REST_GPR(12, r11)
+ lwz r11,GPR11(r11)
+ SYNC
+ rfi
+
+/*
+ * SPE unavailable trap from kernel - print a message, but let
+ * the task use SPE in the kernel until it returns to user mode.
+ */
+KernelSPE:
+ lwz r3,_MSR(r1)
+ oris r3,r3,MSR_SPE@h
+ stw r3,_MSR(r1) /* enable use of SPE after return */
+ lis r3,87f@h
+ ori r3,r3,87f@l
+ mr r4,r2 /* current */
+ lwz r5,_NIP(r1)
+ bl printk
+ b ret_from_except
+87: .string "SPE used in kernel (task=%p, pc=%x) \n"
+ .align 4,0
+
+#endif /* CONFIG_SPE */
+
+/*
+ * Global functions
+ */
+
+/*
+ * extern void loadcam_entry(unsigned int index)
+ *
+ * Load TLBCAM[index] entry in to the L2 CAM MMU
+ */
+_GLOBAL(loadcam_entry)
+ lis r4,TLBCAM@ha
+ addi r4,r4,TLBCAM@l
+ mulli r5,r3,20
+ add r3,r5,r4
+ lwz r4,0(r3)
+ mtspr SPRN_MAS0,r4
+ lwz r4,4(r3)
+ mtspr SPRN_MAS1,r4
+ lwz r4,8(r3)
+ mtspr SPRN_MAS2,r4
+ lwz r4,12(r3)
+ mtspr SPRN_MAS3,r4
+ tlbwe
+ isync
+ blr
+
+/*
+ * extern void giveup_altivec(struct task_struct *prev)
+ *
+ * The e500 core does not have an AltiVec unit.
+ */
+_GLOBAL(giveup_altivec)
+ blr
+
+#ifdef CONFIG_SPE
+/*
+ * extern void giveup_spe(struct task_struct *prev)
+ *
+ */
+_GLOBAL(giveup_spe)
+ mfmsr r5
+ oris r5,r5,MSR_SPE@h
+ SYNC
+ mtmsr r5 /* enable use of SPE now */
+ isync
+ cmpi 0,r3,0
+ beqlr- /* if no previous owner, done */
+ addi r3,r3,THREAD /* want THREAD of task */
+ lwz r5,PT_REGS(r3)
+ cmpi 0,r5,0
+ SAVE_32EVRS(0, r4, r3)
+ evxor evr6, evr6, evr6 /* clear out evr6 */
+ evmwumiaa evr6, evr6, evr6 /* evr6 <- ACC = 0 * 0 + ACC */
+ li r4,THREAD_ACC
+ evstddx evr6, r4, r3 /* save off accumulator */
+ mfspr r6,SPRN_SPEFSCR
+ stw r6,THREAD_SPEFSCR(r3) /* save spefscr register value */
+ beq 1f
+ lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+ lis r3,MSR_SPE@h
+ andc r4,r4,r3 /* disable SPE for previous task */
+ stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:
+#ifndef CONFIG_SMP
+ li r5,0
+ lis r4,last_task_used_spe@ha
+ stw r5,last_task_used_spe@l(r4)
+#endif /* CONFIG_SMP */
+ blr
+#endif /* CONFIG_SPE */
+
+/*
+ * extern void giveup_fpu(struct task_struct *prev)
+ *
+ * Not all FSL Book-E cores have an FPU
+ */
+#ifndef CONFIG_PPC_FPU
+_GLOBAL(giveup_fpu)
+ blr
+#endif
+
+/*
+ * extern void abort(void)
+ *
+ * At present, this routine just applies a system reset.
+ */
+_GLOBAL(abort)
+ li r13,0
+ mtspr SPRN_DBCR0,r13 /* disable all debug events */
+ mfmsr r13
+ ori r13,r13,MSR_DE@l /* Enable Debug Events */
+ mtmsr r13
+ mfspr r13,SPRN_DBCR0
+ lis r13,(DBCR0_IDM|DBCR0_RST_CHIP)@h
+ mtspr SPRN_DBCR0,r13
+
+_GLOBAL(set_context)
+
+#ifdef CONFIG_BDI_SWITCH
+ /* Context switch the PTE pointer for the Abatron BDI2000.
+ * The PGDIR is the second parameter.
+ */
+ lis r5, abatron_pteptrs@h
+ ori r5, r5, abatron_pteptrs@l
+ stw r4, 0x4(r5)
+#endif
+ mtspr SPRN_PID,r3
+ isync /* Force context change */
+ blr
+
+/*
+ * We put a few things here that have to be page-aligned. This stuff
+ * goes at the beginning of the data segment, which is page-aligned.
+ */
+ .data
+ .align 12
+ .globl sdata
+sdata:
+ .globl empty_zero_page
+empty_zero_page:
+ .space 4096
+ .globl swapper_pg_dir
+swapper_pg_dir:
+ .space 4096
+
+/* Reserved 4k for the critical exception stack & 4k for the machine
+ * check stack per CPU for kernel mode exceptions */
+ .section .bss
+ .align 12
+exception_stack_bottom:
+ .space BOOKE_EXCEPTION_STACK_SIZE * NR_CPUS
+ .globl exception_stack_top
+exception_stack_top:
+
+/*
+ * This space gets a copy of optional info passed to us by the bootstrap
+ * which is used to pass parameters into the kernel like root=/dev/sda1, etc.
+ */
+ .globl cmd_line
+cmd_line:
+ .space 512
+
+/*
+ * Room for two PTE pointers, usually the kernel and current user pointers
+ * to their respective root page table.
+ */
+abatron_pteptrs:
+ .space 8
diff --git a/arch/powerpc/kernel/idle_6xx.S b/arch/powerpc/kernel/idle_6xx.S
new file mode 100644
index 000000000000..444fdcc769f1
--- /dev/null
+++ b/arch/powerpc/kernel/idle_6xx.S
@@ -0,0 +1,233 @@
+/*
+ * This file contains the power_save function for 6xx & 7xxx CPUs
+ * rewritten in assembler
+ *
+ * Warning ! This code assumes that if your machine has a 750fx
+ * it will have PLL 1 set to low speed mode (used during NAP/DOZE).
+ * if this is not the case some additional changes will have to
+ * be done to check a runtime var (a bit like powersave-nap)
+ *
+ * This program is free software; you can redistribute 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/config.h>
+#include <linux/threads.h>
+#include <asm/reg.h>
+#include <asm/page.h>
+#include <asm/cputable.h>
+#include <asm/thread_info.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+
+#undef DEBUG
+
+ .text
+
+/*
+ * Init idle, called at early CPU setup time from head.S for each CPU
+ * Make sure no rest of NAP mode remains in HID0, save default
+ * values for some CPU specific registers. Called with r24
+ * containing CPU number and r3 reloc offset
+ */
+_GLOBAL(init_idle_6xx)
+BEGIN_FTR_SECTION
+ mfspr r4,SPRN_HID0
+ rlwinm r4,r4,0,10,8 /* Clear NAP */
+ mtspr SPRN_HID0, r4
+ b 1f
+END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
+ blr
+1:
+ slwi r5,r24,2
+ add r5,r5,r3
+BEGIN_FTR_SECTION
+ mfspr r4,SPRN_MSSCR0
+ addis r6,r5, nap_save_msscr0@ha
+ stw r4,nap_save_msscr0@l(r6)
+END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR)
+BEGIN_FTR_SECTION
+ mfspr r4,SPRN_HID1
+ addis r6,r5,nap_save_hid1@ha
+ stw r4,nap_save_hid1@l(r6)
+END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX)
+ blr
+
+/*
+ * Here is the power_save_6xx function. This could eventually be
+ * split into several functions & changing the function pointer
+ * depending on the various features.
+ */
+_GLOBAL(ppc6xx_idle)
+ /* Check if we can nap or doze, put HID0 mask in r3
+ */
+ lis r3, 0
+BEGIN_FTR_SECTION
+ lis r3,HID0_DOZE@h
+END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
+BEGIN_FTR_SECTION
+ /* We must dynamically check for the NAP feature as it
+ * can be cleared by CPU init after the fixups are done
+ */
+ lis r4,cur_cpu_spec@ha
+ lwz r4,cur_cpu_spec@l(r4)
+ lwz r4,CPU_SPEC_FEATURES(r4)
+ andi. r0,r4,CPU_FTR_CAN_NAP
+ beq 1f
+ /* Now check if user or arch enabled NAP mode */
+ lis r4,powersave_nap@ha
+ lwz r4,powersave_nap@l(r4)
+ cmpwi 0,r4,0
+ beq 1f
+ lis r3,HID0_NAP@h
+1:
+END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
+ cmpwi 0,r3,0
+ beqlr
+
+ /* Clear MSR:EE */
+ mfmsr r7
+ rlwinm r0,r7,0,17,15
+ mtmsr r0
+
+ /* Check current_thread_info()->flags */
+ rlwinm r4,r1,0,0,18
+ lwz r4,TI_FLAGS(r4)
+ andi. r0,r4,_TIF_NEED_RESCHED
+ beq 1f
+ mtmsr r7 /* out of line this ? */
+ blr
+1:
+ /* Some pre-nap cleanups needed on some CPUs */
+ andis. r0,r3,HID0_NAP@h
+ beq 2f
+BEGIN_FTR_SECTION
+ /* Disable L2 prefetch on some 745x and try to ensure
+ * L2 prefetch engines are idle. As explained by errata
+ * text, we can't be sure they are, we just hope very hard
+ * that well be enough (sic !). At least I noticed Apple
+ * doesn't even bother doing the dcbf's here...
+ */
+ mfspr r4,SPRN_MSSCR0
+ rlwinm r4,r4,0,0,29
+ sync
+ mtspr SPRN_MSSCR0,r4
+ sync
+ isync
+ lis r4,KERNELBASE@h
+ dcbf 0,r4
+ dcbf 0,r4
+ dcbf 0,r4
+ dcbf 0,r4
+END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR)
+#ifdef DEBUG
+ lis r6,nap_enter_count@ha
+ lwz r4,nap_enter_count@l(r6)
+ addi r4,r4,1
+ stw r4,nap_enter_count@l(r6)
+#endif
+2:
+BEGIN_FTR_SECTION
+ /* Go to low speed mode on some 750FX */
+ lis r4,powersave_lowspeed@ha
+ lwz r4,powersave_lowspeed@l(r4)
+ cmpwi 0,r4,0
+ beq 1f
+ mfspr r4,SPRN_HID1
+ oris r4,r4,0x0001
+ mtspr SPRN_HID1,r4
+1:
+END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX)
+
+ /* Go to NAP or DOZE now */
+ mfspr r4,SPRN_HID0
+ lis r5,(HID0_NAP|HID0_SLEEP)@h
+BEGIN_FTR_SECTION
+ oris r5,r5,HID0_DOZE@h
+END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
+ andc r4,r4,r5
+ or r4,r4,r3
+BEGIN_FTR_SECTION
+ oris r4,r4,HID0_DPM@h /* that should be done once for all */
+END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM)
+ mtspr SPRN_HID0,r4
+BEGIN_FTR_SECTION
+ DSSALL
+ sync
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+ ori r7,r7,MSR_EE /* Could be ommited (already set) */
+ oris r7,r7,MSR_POW@h
+ sync
+ isync
+ mtmsr r7
+ isync
+ sync
+ blr
+
+/*
+ * Return from NAP/DOZE mode, restore some CPU specific registers,
+ * we are called with DR/IR still off and r2 containing physical
+ * address of current.
+ */
+_GLOBAL(power_save_6xx_restore)
+ mfspr r11,SPRN_HID0
+ rlwinm. r11,r11,0,10,8 /* Clear NAP & copy NAP bit !state to cr1 EQ */
+ cror 4*cr1+eq,4*cr0+eq,4*cr0+eq
+BEGIN_FTR_SECTION
+ rlwinm r11,r11,0,9,7 /* Clear DOZE */
+END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
+ mtspr SPRN_HID0, r11
+
+#ifdef DEBUG
+ beq cr1,1f
+ lis r11,(nap_return_count-KERNELBASE)@ha
+ lwz r9,nap_return_count@l(r11)
+ addi r9,r9,1
+ stw r9,nap_return_count@l(r11)
+1:
+#endif
+
+ rlwinm r9,r1,0,0,18
+ tophys(r9,r9)
+ lwz r11,TI_CPU(r9)
+ slwi r11,r11,2
+ /* Todo make sure all these are in the same page
+ * and load r22 (@ha part + CPU offset) only once
+ */
+BEGIN_FTR_SECTION
+ beq cr1,1f
+ addis r9,r11,(nap_save_msscr0-KERNELBASE)@ha
+ lwz r9,nap_save_msscr0@l(r9)
+ mtspr SPRN_MSSCR0, r9
+ sync
+ isync
+1:
+END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR)
+BEGIN_FTR_SECTION
+ addis r9,r11,(nap_save_hid1-KERNELBASE)@ha
+ lwz r9,nap_save_hid1@l(r9)
+ mtspr SPRN_HID1, r9
+END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX)
+ b transfer_to_handler_cont
+
+ .data
+
+_GLOBAL(nap_save_msscr0)
+ .space 4*NR_CPUS
+
+_GLOBAL(nap_save_hid1)
+ .space 4*NR_CPUS
+
+_GLOBAL(powersave_nap)
+ .long 0
+_GLOBAL(powersave_lowspeed)
+ .long 0
+
+#ifdef DEBUG
+_GLOBAL(nap_enter_count)
+ .space 4
+_GLOBAL(nap_return_count)
+ .space 4
+#endif
diff --git a/arch/ppc64/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S
index ca02afe2a795..1494e2f177f7 100644
--- a/arch/ppc64/kernel/idle_power4.S
+++ b/arch/powerpc/kernel/idle_power4.S
@@ -39,13 +39,13 @@ END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP)
* can be cleared by CPU init after the fixups are done
*/
LOADBASE(r3,cur_cpu_spec)
- ld r4,cur_cpu_spec@l(r3)
+ ld r4,OFF(cur_cpu_spec)(r3)
ld r4,CPU_SPEC_FEATURES(r4)
andi. r0,r4,CPU_FTR_CAN_NAP
beqlr
/* Now check if user or arch enabled NAP mode */
LOADBASE(r3,powersave_nap)
- lwz r4,powersave_nap@l(r3)
+ lwz r4,OFF(powersave_nap)(r3)
cmpwi 0,r4,0
beqlr
@@ -63,8 +63,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP)
beq 1f
mtmsrd r7 /* out of line this ? */
blr
-1:
- /* Go to NAP now */
+1:
+ /* Go to NAP now */
BEGIN_FTR_SECTION
DSSALL
sync
@@ -76,4 +76,3 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
isync
sync
blr
-
diff --git a/arch/ppc64/kernel/init_task.c b/arch/powerpc/kernel/init_task.c
index 941043ae040f..941043ae040f 100644
--- a/arch/ppc64/kernel/init_task.c
+++ b/arch/powerpc/kernel/init_task.c
diff --git a/arch/ppc64/kernel/lparmap.c b/arch/powerpc/kernel/lparmap.c
index b81de286df5e..b81de286df5e 100644
--- a/arch/ppc64/kernel/lparmap.c
+++ b/arch/powerpc/kernel/lparmap.c
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
new file mode 100644
index 000000000000..3bedb532aed9
--- /dev/null
+++ b/arch/powerpc/kernel/misc_32.S
@@ -0,0 +1,1037 @@
+/*
+ * This file contains miscellaneous low-level functions.
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
+ * and Paul Mackerras.
+ *
+ * This program is free software; you can redistribute 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/config.h>
+#include <linux/sys.h>
+#include <asm/unistd.h>
+#include <asm/errno.h>
+#include <asm/reg.h>
+#include <asm/page.h>
+#include <asm/cache.h>
+#include <asm/cputable.h>
+#include <asm/mmu.h>
+#include <asm/ppc_asm.h>
+#include <asm/thread_info.h>
+#include <asm/asm-offsets.h>
+
+ .text
+
+ .align 5
+_GLOBAL(__delay)
+ cmpwi 0,r3,0
+ mtctr r3
+ beqlr
+1: bdnz 1b
+ blr
+
+/*
+ * This returns the high 64 bits of the product of two 64-bit numbers.
+ */
+_GLOBAL(mulhdu)
+ cmpwi r6,0
+ cmpwi cr1,r3,0
+ mr r10,r4
+ mulhwu r4,r4,r5
+ beq 1f
+ mulhwu r0,r10,r6
+ mullw r7,r10,r5
+ addc r7,r0,r7
+ addze r4,r4
+1: beqlr cr1 /* all done if high part of A is 0 */
+ mr r10,r3
+ mullw r9,r3,r5
+ mulhwu r3,r3,r5
+ beq 2f
+ mullw r0,r10,r6
+ mulhwu r8,r10,r6
+ addc r7,r0,r7
+ adde r4,r4,r8
+ addze r3,r3
+2: addc r4,r4,r9
+ addze r3,r3
+ blr
+
+/*
+ * Returns (address we're running at) - (address we were linked at)
+ * for use before the text and data are mapped to KERNELBASE.
+ */
+_GLOBAL(reloc_offset)
+ mflr r0
+ bl 1f
+1: mflr r3
+ LOADADDR(r4,1b)
+ subf r3,r4,r3
+ mtlr r0
+ blr
+
+/*
+ * add_reloc_offset(x) returns x + reloc_offset().
+ */
+_GLOBAL(add_reloc_offset)
+ mflr r0
+ bl 1f
+1: mflr r5
+ LOADADDR(r4,1b)
+ subf r5,r4,r5
+ add r3,r3,r5
+ mtlr r0
+ blr
+
+/*
+ * sub_reloc_offset(x) returns x - reloc_offset().
+ */
+_GLOBAL(sub_reloc_offset)
+ mflr r0
+ bl 1f
+1: mflr r5
+ lis r4,1b@ha
+ addi r4,r4,1b@l
+ subf r5,r4,r5
+ subf r3,r5,r3
+ mtlr r0
+ blr
+
+/*
+ * reloc_got2 runs through the .got2 section adding an offset
+ * to each entry.
+ */
+_GLOBAL(reloc_got2)
+ mflr r11
+ lis r7,__got2_start@ha
+ addi r7,r7,__got2_start@l
+ lis r8,__got2_end@ha
+ addi r8,r8,__got2_end@l
+ subf r8,r7,r8
+ srwi. r8,r8,2
+ beqlr
+ mtctr r8
+ bl 1f
+1: mflr r0
+ lis r4,1b@ha
+ addi r4,r4,1b@l
+ subf r0,r4,r0
+ add r7,r0,r7
+2: lwz r0,0(r7)
+ add r0,r0,r3
+ stw r0,0(r7)
+ addi r7,r7,4
+ bdnz 2b
+ mtlr r11
+ blr
+
+/*
+ * identify_cpu,
+ * called with r3 = data offset and r4 = CPU number
+ * doesn't change r3
+ */
+_GLOBAL(identify_cpu)
+ addis r8,r3,cpu_specs@ha
+ addi r8,r8,cpu_specs@l
+ mfpvr r7
+1:
+ lwz r5,CPU_SPEC_PVR_MASK(r8)
+ and r5,r5,r7
+ lwz r6,CPU_SPEC_PVR_VALUE(r8)
+ cmplw 0,r6,r5
+ beq 1f
+ addi r8,r8,CPU_SPEC_ENTRY_SIZE
+ b 1b
+1:
+ addis r6,r3,cur_cpu_spec@ha
+ addi r6,r6,cur_cpu_spec@l
+ sub r8,r8,r3
+ stw r8,0(r6)
+ blr
+
+/*
+ * do_cpu_ftr_fixups - goes through the list of CPU feature fixups
+ * and writes nop's over sections of code that don't apply for this cpu.
+ * r3 = data offset (not changed)
+ */
+_GLOBAL(do_cpu_ftr_fixups)
+ /* Get CPU 0 features */
+ addis r6,r3,cur_cpu_spec@ha
+ addi r6,r6,cur_cpu_spec@l
+ lwz r4,0(r6)
+ add r4,r4,r3
+ lwz r4,CPU_SPEC_FEATURES(r4)
+
+ /* Get the fixup table */
+ addis r6,r3,__start___ftr_fixup@ha
+ addi r6,r6,__start___ftr_fixup@l
+ addis r7,r3,__stop___ftr_fixup@ha
+ addi r7,r7,__stop___ftr_fixup@l
+
+ /* Do the fixup */
+1: cmplw 0,r6,r7
+ bgelr
+ addi r6,r6,16
+ lwz r8,-16(r6) /* mask */
+ and r8,r8,r4
+ lwz r9,-12(r6) /* value */
+ cmplw 0,r8,r9
+ beq 1b
+ lwz r8,-8(r6) /* section begin */
+ lwz r9,-4(r6) /* section end */
+ subf. r9,r8,r9
+ beq 1b
+ /* write nops over the section of code */
+ /* todo: if large section, add a branch at the start of it */
+ srwi r9,r9,2
+ mtctr r9
+ add r8,r8,r3
+ lis r0,0x60000000@h /* nop */
+3: stw r0,0(r8)
+ andi. r10,r4,CPU_FTR_SPLIT_ID_CACHE@l
+ beq 2f
+ dcbst 0,r8 /* suboptimal, but simpler */
+ sync
+ icbi 0,r8
+2: addi r8,r8,4
+ bdnz 3b
+ sync /* additional sync needed on g4 */
+ isync
+ b 1b
+
+/*
+ * call_setup_cpu - call the setup_cpu function for this cpu
+ * r3 = data offset, r24 = cpu number
+ *
+ * Setup function is called with:
+ * r3 = data offset
+ * r4 = ptr to CPU spec (relocated)
+ */
+_GLOBAL(call_setup_cpu)
+ addis r4,r3,cur_cpu_spec@ha
+ addi r4,r4,cur_cpu_spec@l
+ lwz r4,0(r4)
+ add r4,r4,r3
+ lwz r5,CPU_SPEC_SETUP(r4)
+ cmpi 0,r5,0
+ add r5,r5,r3
+ beqlr
+ mtctr r5
+ bctr
+
+#if defined(CONFIG_CPU_FREQ_PMAC) && defined(CONFIG_6xx)
+
+/* This gets called by via-pmu.c to switch the PLL selection
+ * on 750fx CPU. This function should really be moved to some
+ * other place (as most of the cpufreq code in via-pmu
+ */
+_GLOBAL(low_choose_750fx_pll)
+ /* Clear MSR:EE */
+ mfmsr r7
+ rlwinm r0,r7,0,17,15
+ mtmsr r0
+
+ /* If switching to PLL1, disable HID0:BTIC */
+ cmplwi cr0,r3,0
+ beq 1f
+ mfspr r5,SPRN_HID0
+ rlwinm r5,r5,0,27,25
+ sync
+ mtspr SPRN_HID0,r5
+ isync
+ sync
+
+1:
+ /* Calc new HID1 value */
+ mfspr r4,SPRN_HID1 /* Build a HID1:PS bit from parameter */
+ rlwinm r5,r3,16,15,15 /* Clear out HID1:PS from value read */
+ rlwinm r4,r4,0,16,14 /* Could have I used rlwimi here ? */
+ or r4,r4,r5
+ mtspr SPRN_HID1,r4
+
+ /* Store new HID1 image */
+ rlwinm r6,r1,0,0,18
+ lwz r6,TI_CPU(r6)
+ slwi r6,r6,2
+ addis r6,r6,nap_save_hid1@ha
+ stw r4,nap_save_hid1@l(r6)
+
+ /* If switching to PLL0, enable HID0:BTIC */
+ cmplwi cr0,r3,0
+ bne 1f
+ mfspr r5,SPRN_HID0
+ ori r5,r5,HID0_BTIC
+ sync
+ mtspr SPRN_HID0,r5
+ isync
+ sync
+
+1:
+ /* Return */
+ mtmsr r7
+ blr
+
+_GLOBAL(low_choose_7447a_dfs)
+ /* Clear MSR:EE */
+ mfmsr r7
+ rlwinm r0,r7,0,17,15
+ mtmsr r0
+
+ /* Calc new HID1 value */
+ mfspr r4,SPRN_HID1
+ insrwi r4,r3,1,9 /* insert parameter into bit 9 */
+ sync
+ mtspr SPRN_HID1,r4
+ sync
+ isync
+
+ /* Return */
+ mtmsr r7
+ blr
+
+#endif /* CONFIG_CPU_FREQ_PMAC && CONFIG_6xx */
+
+/*
+ * complement mask on the msr then "or" some values on.
+ * _nmask_and_or_msr(nmask, value_to_or)
+ */
+_GLOBAL(_nmask_and_or_msr)
+ mfmsr r0 /* Get current msr */
+ andc r0,r0,r3 /* And off the bits set in r3 (first parm) */
+ or r0,r0,r4 /* Or on the bits in r4 (second parm) */
+ SYNC /* Some chip revs have problems here... */
+ mtmsr r0 /* Update machine state */
+ isync
+ blr /* Done */
+
+
+/*
+ * Flush MMU TLB
+ */
+_GLOBAL(_tlbia)
+#if defined(CONFIG_40x)
+ sync /* Flush to memory before changing mapping */
+ tlbia
+ isync /* Flush shadow TLB */
+#elif defined(CONFIG_44x)
+ li r3,0
+ sync
+
+ /* Load high watermark */
+ lis r4,tlb_44x_hwater@ha
+ lwz r5,tlb_44x_hwater@l(r4)
+
+1: tlbwe r3,r3,PPC44x_TLB_PAGEID
+ addi r3,r3,1
+ cmpw 0,r3,r5
+ ble 1b
+
+ isync
+#elif defined(CONFIG_FSL_BOOKE)
+ /* Invalidate all entries in TLB0 */
+ li r3, 0x04
+ tlbivax 0,3
+ /* Invalidate all entries in TLB1 */
+ li r3, 0x0c
+ tlbivax 0,3
+ /* Invalidate all entries in TLB2 */
+ li r3, 0x14
+ tlbivax 0,3
+ /* Invalidate all entries in TLB3 */
+ li r3, 0x1c
+ tlbivax 0,3
+ msync
+#ifdef CONFIG_SMP
+ tlbsync
+#endif /* CONFIG_SMP */
+#else /* !(CONFIG_40x || CONFIG_44x || CONFIG_FSL_BOOKE) */
+#if defined(CONFIG_SMP)
+ rlwinm r8,r1,0,0,18
+ lwz r8,TI_CPU(r8)
+ oris r8,r8,10
+ mfmsr r10
+ SYNC
+ rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */
+ rlwinm r0,r0,0,28,26 /* clear DR */
+ mtmsr r0
+ SYNC_601
+ isync
+ lis r9,mmu_hash_lock@h
+ ori r9,r9,mmu_hash_lock@l
+ tophys(r9,r9)
+10: lwarx r7,0,r9
+ cmpwi 0,r7,0
+ bne- 10b
+ stwcx. r8,0,r9
+ bne- 10b
+ sync
+ tlbia
+ sync
+ TLBSYNC
+ li r0,0
+ stw r0,0(r9) /* clear mmu_hash_lock */
+ mtmsr r10
+ SYNC_601
+ isync
+#else /* CONFIG_SMP */
+ sync
+ tlbia
+ sync
+#endif /* CONFIG_SMP */
+#endif /* ! defined(CONFIG_40x) */
+ blr
+
+/*
+ * Flush MMU TLB for a particular address
+ */
+_GLOBAL(_tlbie)
+#if defined(CONFIG_40x)
+ tlbsx. r3, 0, r3
+ bne 10f
+ sync
+ /* There are only 64 TLB entries, so r3 < 64, which means bit 25 is clear.
+ * Since 25 is the V bit in the TLB_TAG, loading this value will invalidate
+ * the TLB entry. */
+ tlbwe r3, r3, TLB_TAG
+ isync
+10:
+#elif defined(CONFIG_44x)
+ mfspr r4,SPRN_MMUCR
+ mfspr r5,SPRN_PID /* Get PID */
+ rlwimi r4,r5,0,24,31 /* Set TID */
+ mtspr SPRN_MMUCR,r4
+
+ tlbsx. r3, 0, r3
+ bne 10f
+ sync
+ /* There are only 64 TLB entries, so r3 < 64,
+ * which means bit 22, is clear. Since 22 is
+ * the V bit in the TLB_PAGEID, loading this
+ * value will invalidate the TLB entry.
+ */
+ tlbwe r3, r3, PPC44x_TLB_PAGEID
+ isync
+10:
+#elif defined(CONFIG_FSL_BOOKE)
+ rlwinm r4, r3, 0, 0, 19
+ ori r5, r4, 0x08 /* TLBSEL = 1 */
+ ori r6, r4, 0x10 /* TLBSEL = 2 */
+ ori r7, r4, 0x18 /* TLBSEL = 3 */
+ tlbivax 0, r4
+ tlbivax 0, r5
+ tlbivax 0, r6
+ tlbivax 0, r7
+ msync
+#if defined(CONFIG_SMP)
+ tlbsync
+#endif /* CONFIG_SMP */
+#else /* !(CONFIG_40x || CONFIG_44x || CONFIG_FSL_BOOKE) */
+#if defined(CONFIG_SMP)
+ rlwinm r8,r1,0,0,18
+ lwz r8,TI_CPU(r8)
+ oris r8,r8,11
+ mfmsr r10
+ SYNC
+ rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */
+ rlwinm r0,r0,0,28,26 /* clear DR */
+ mtmsr r0
+ SYNC_601
+ isync
+ lis r9,mmu_hash_lock@h
+ ori r9,r9,mmu_hash_lock@l
+ tophys(r9,r9)
+10: lwarx r7,0,r9
+ cmpwi 0,r7,0
+ bne- 10b
+ stwcx. r8,0,r9
+ bne- 10b
+ eieio
+ tlbie r3
+ sync
+ TLBSYNC
+ li r0,0
+ stw r0,0(r9) /* clear mmu_hash_lock */
+ mtmsr r10
+ SYNC_601
+ isync
+#else /* CONFIG_SMP */
+ tlbie r3
+ sync
+#endif /* CONFIG_SMP */
+#endif /* ! CONFIG_40x */
+ blr
+
+/*
+ * Flush instruction cache.
+ * This is a no-op on the 601.
+ */
+_GLOBAL(flush_instruction_cache)
+#if defined(CONFIG_8xx)
+ isync
+ lis r5, IDC_INVALL@h
+ mtspr SPRN_IC_CST, r5
+#elif defined(CONFIG_4xx)
+#ifdef CONFIG_403GCX
+ li r3, 512
+ mtctr r3
+ lis r4, KERNELBASE@h
+1: iccci 0, r4
+ addi r4, r4, 16
+ bdnz 1b
+#else
+ lis r3, KERNELBASE@h
+ iccci 0,r3
+#endif
+#elif CONFIG_FSL_BOOKE
+BEGIN_FTR_SECTION
+ mfspr r3,SPRN_L1CSR0
+ ori r3,r3,L1CSR0_CFI|L1CSR0_CLFC
+ /* msync; isync recommended here */
+ mtspr SPRN_L1CSR0,r3
+ isync
+ blr
+END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
+ mfspr r3,SPRN_L1CSR1
+ ori r3,r3,L1CSR1_ICFI|L1CSR1_ICLFR
+ mtspr SPRN_L1CSR1,r3
+#else
+ mfspr r3,SPRN_PVR
+ rlwinm r3,r3,16,16,31
+ cmpwi 0,r3,1
+ beqlr /* for 601, do nothing */
+ /* 603/604 processor - use invalidate-all bit in HID0 */
+ mfspr r3,SPRN_HID0
+ ori r3,r3,HID0_ICFI
+ mtspr SPRN_HID0,r3
+#endif /* CONFIG_8xx/4xx */
+ isync
+ blr
+
+/*
+ * Write any modified data cache blocks out to memory
+ * and invalidate the corresponding instruction cache blocks.
+ * This is a no-op on the 601.
+ *
+ * flush_icache_range(unsigned long start, unsigned long stop)
+ */
+_GLOBAL(flush_icache_range)
+BEGIN_FTR_SECTION
+ blr /* for 601, do nothing */
+END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
+ li r5,L1_CACHE_BYTES-1
+ andc r3,r3,r5
+ subf r4,r3,r4
+ add r4,r4,r5
+ srwi. r4,r4,L1_CACHE_SHIFT
+ beqlr
+ mtctr r4
+ mr r6,r3
+1: dcbst 0,r3
+ addi r3,r3,L1_CACHE_BYTES
+ bdnz 1b
+ sync /* wait for dcbst's to get to ram */
+ mtctr r4
+2: icbi 0,r6
+ addi r6,r6,L1_CACHE_BYTES
+ bdnz 2b
+ sync /* additional sync needed on g4 */
+ isync
+ blr
+/*
+ * Write any modified data cache blocks out to memory.
+ * Does not invalidate the corresponding cache lines (especially for
+ * any corresponding instruction cache).
+ *
+ * clean_dcache_range(unsigned long start, unsigned long stop)
+ */
+_GLOBAL(clean_dcache_range)
+ li r5,L1_CACHE_BYTES-1
+ andc r3,r3,r5
+ subf r4,r3,r4
+ add r4,r4,r5
+ srwi. r4,r4,L1_CACHE_SHIFT
+ beqlr
+ mtctr r4
+
+1: dcbst 0,r3
+ addi r3,r3,L1_CACHE_BYTES
+ bdnz 1b
+ sync /* wait for dcbst's to get to ram */
+ blr
+
+/*
+ * Write any modified data cache blocks out to memory and invalidate them.
+ * Does not invalidate the corresponding instruction cache blocks.
+ *
+ * flush_dcache_range(unsigned long start, unsigned long stop)
+ */
+_GLOBAL(flush_dcache_range)
+ li r5,L1_CACHE_BYTES-1
+ andc r3,r3,r5
+ subf r4,r3,r4
+ add r4,r4,r5
+ srwi. r4,r4,L1_CACHE_SHIFT
+ beqlr
+ mtctr r4
+
+1: dcbf 0,r3
+ addi r3,r3,L1_CACHE_BYTES
+ bdnz 1b
+ sync /* wait for dcbst's to get to ram */
+ blr
+
+/*
+ * Like above, but invalidate the D-cache. This is used by the 8xx
+ * to invalidate the cache so the PPC core doesn't get stale data
+ * from the CPM (no cache snooping here :-).
+ *
+ * invalidate_dcache_range(unsigned long start, unsigned long stop)
+ */
+_GLOBAL(invalidate_dcache_range)
+ li r5,L1_CACHE_BYTES-1
+ andc r3,r3,r5
+ subf r4,r3,r4
+ add r4,r4,r5
+ srwi. r4,r4,L1_CACHE_SHIFT
+ beqlr
+ mtctr r4
+
+1: dcbi 0,r3
+ addi r3,r3,L1_CACHE_BYTES
+ bdnz 1b
+ sync /* wait for dcbi's to get to ram */
+ blr
+
+#ifdef CONFIG_NOT_COHERENT_CACHE
+/*
+ * 40x cores have 8K or 16K dcache and 32 byte line size.
+ * 44x has a 32K dcache and 32 byte line size.
+ * 8xx has 1, 2, 4, 8K variants.
+ * For now, cover the worst case of the 44x.
+ * Must be called with external interrupts disabled.
+ */
+#define CACHE_NWAYS 64
+#define CACHE_NLINES 16
+
+_GLOBAL(flush_dcache_all)
+ li r4, (2 * CACHE_NWAYS * CACHE_NLINES)
+ mtctr r4
+ lis r5, KERNELBASE@h
+1: lwz r3, 0(r5) /* Load one word from every line */
+ addi r5, r5, L1_CACHE_BYTES
+ bdnz 1b
+ blr
+#endif /* CONFIG_NOT_COHERENT_CACHE */
+
+/*
+ * Flush a particular page from the data cache to RAM.
+ * Note: this is necessary because the instruction cache does *not*
+ * snoop from the data cache.
+ * This is a no-op on the 601 which has a unified cache.
+ *
+ * void __flush_dcache_icache(void *page)
+ */
+_GLOBAL(__flush_dcache_icache)
+BEGIN_FTR_SECTION
+ blr /* for 601, do nothing */
+END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
+ rlwinm r3,r3,0,0,19 /* Get page base address */
+ li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */
+ mtctr r4
+ mr r6,r3
+0: dcbst 0,r3 /* Write line to ram */
+ addi r3,r3,L1_CACHE_BYTES
+ bdnz 0b
+ sync
+ mtctr r4
+1: icbi 0,r6
+ addi r6,r6,L1_CACHE_BYTES
+ bdnz 1b
+ sync
+ isync
+ blr
+
+/*
+ * Flush a particular page from the data cache to RAM, identified
+ * by its physical address. We turn off the MMU so we can just use
+ * the physical address (this may be a highmem page without a kernel
+ * mapping).
+ *
+ * void __flush_dcache_icache_phys(unsigned long physaddr)
+ */
+_GLOBAL(__flush_dcache_icache_phys)
+BEGIN_FTR_SECTION
+ blr /* for 601, do nothing */
+END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
+ mfmsr r10
+ rlwinm r0,r10,0,28,26 /* clear DR */
+ mtmsr r0
+ isync
+ rlwinm r3,r3,0,0,19 /* Get page base address */
+ li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */
+ mtctr r4
+ mr r6,r3
+0: dcbst 0,r3 /* Write line to ram */
+ addi r3,r3,L1_CACHE_BYTES
+ bdnz 0b
+ sync
+ mtctr r4
+1: icbi 0,r6
+ addi r6,r6,L1_CACHE_BYTES
+ bdnz 1b
+ sync
+ mtmsr r10 /* restore DR */
+ isync
+ blr
+
+/*
+ * Clear pages using the dcbz instruction, which doesn't cause any
+ * memory traffic (except to write out any cache lines which get
+ * displaced). This only works on cacheable memory.
+ *
+ * void clear_pages(void *page, int order) ;
+ */
+_GLOBAL(clear_pages)
+ li r0,4096/L1_CACHE_BYTES
+ slw r0,r0,r4
+ mtctr r0
+#ifdef CONFIG_8xx
+ li r4, 0
+1: stw r4, 0(r3)
+ stw r4, 4(r3)
+ stw r4, 8(r3)
+ stw r4, 12(r3)
+#else
+1: dcbz 0,r3
+#endif
+ addi r3,r3,L1_CACHE_BYTES
+ bdnz 1b
+ blr
+
+/*
+ * Copy a whole page. We use the dcbz instruction on the destination
+ * to reduce memory traffic (it eliminates the unnecessary reads of
+ * the destination into cache). This requires that the destination
+ * is cacheable.
+ */
+#define COPY_16_BYTES \
+ lwz r6,4(r4); \
+ lwz r7,8(r4); \
+ lwz r8,12(r4); \
+ lwzu r9,16(r4); \
+ stw r6,4(r3); \
+ stw r7,8(r3); \
+ stw r8,12(r3); \
+ stwu r9,16(r3)
+
+_GLOBAL(copy_page)
+ addi r3,r3,-4
+ addi r4,r4,-4
+
+#ifdef CONFIG_8xx
+ /* don't use prefetch on 8xx */
+ li r0,4096/L1_CACHE_BYTES
+ mtctr r0
+1: COPY_16_BYTES
+ bdnz 1b
+ blr
+
+#else /* not 8xx, we can prefetch */
+ li r5,4
+
+#if MAX_COPY_PREFETCH > 1
+ li r0,MAX_COPY_PREFETCH
+ li r11,4
+ mtctr r0
+11: dcbt r11,r4
+ addi r11,r11,L1_CACHE_BYTES
+ bdnz 11b
+#else /* MAX_COPY_PREFETCH == 1 */
+ dcbt r5,r4
+ li r11,L1_CACHE_BYTES+4
+#endif /* MAX_COPY_PREFETCH */
+ li r0,4096/L1_CACHE_BYTES - MAX_COPY_PREFETCH
+ crclr 4*cr0+eq
+2:
+ mtctr r0
+1:
+ dcbt r11,r4
+ dcbz r5,r3
+ COPY_16_BYTES
+#if L1_CACHE_BYTES >= 32
+ COPY_16_BYTES
+#if L1_CACHE_BYTES >= 64
+ COPY_16_BYTES
+ COPY_16_BYTES
+#if L1_CACHE_BYTES >= 128
+ COPY_16_BYTES
+ COPY_16_BYTES
+ COPY_16_BYTES
+ COPY_16_BYTES
+#endif
+#endif
+#endif
+ bdnz 1b
+ beqlr
+ crnot 4*cr0+eq,4*cr0+eq
+ li r0,MAX_COPY_PREFETCH
+ li r11,4
+ b 2b
+#endif /* CONFIG_8xx */
+
+/*
+ * void atomic_clear_mask(atomic_t mask, atomic_t *addr)
+ * void atomic_set_mask(atomic_t mask, atomic_t *addr);
+ */
+_GLOBAL(atomic_clear_mask)
+10: lwarx r5,0,r4
+ andc r5,r5,r3
+ PPC405_ERR77(0,r4)
+ stwcx. r5,0,r4
+ bne- 10b
+ blr
+_GLOBAL(atomic_set_mask)
+10: lwarx r5,0,r4
+ or r5,r5,r3
+ PPC405_ERR77(0,r4)
+ stwcx. r5,0,r4
+ bne- 10b
+ blr
+
+/*
+ * I/O string operations
+ *
+ * insb(port, buf, len)
+ * outsb(port, buf, len)
+ * insw(port, buf, len)
+ * outsw(port, buf, len)
+ * insl(port, buf, len)
+ * outsl(port, buf, len)
+ * insw_ns(port, buf, len)
+ * outsw_ns(port, buf, len)
+ * insl_ns(port, buf, len)
+ * outsl_ns(port, buf, len)
+ *
+ * The *_ns versions don't do byte-swapping.
+ */
+_GLOBAL(_insb)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,1
+ blelr-
+00: lbz r5,0(r3)
+ eieio
+ stbu r5,1(r4)
+ bdnz 00b
+ blr
+
+_GLOBAL(_outsb)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,1
+ blelr-
+00: lbzu r5,1(r4)
+ stb r5,0(r3)
+ eieio
+ bdnz 00b
+ blr
+
+_GLOBAL(_insw)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,2
+ blelr-
+00: lhbrx r5,0,r3
+ eieio
+ sthu r5,2(r4)
+ bdnz 00b
+ blr
+
+_GLOBAL(_outsw)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,2
+ blelr-
+00: lhzu r5,2(r4)
+ eieio
+ sthbrx r5,0,r3
+ bdnz 00b
+ blr
+
+_GLOBAL(_insl)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,4
+ blelr-
+00: lwbrx r5,0,r3
+ eieio
+ stwu r5,4(r4)
+ bdnz 00b
+ blr
+
+_GLOBAL(_outsl)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,4
+ blelr-
+00: lwzu r5,4(r4)
+ stwbrx r5,0,r3
+ eieio
+ bdnz 00b
+ blr
+
+_GLOBAL(__ide_mm_insw)
+_GLOBAL(_insw_ns)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,2
+ blelr-
+00: lhz r5,0(r3)
+ eieio
+ sthu r5,2(r4)
+ bdnz 00b
+ blr
+
+_GLOBAL(__ide_mm_outsw)
+_GLOBAL(_outsw_ns)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,2
+ blelr-
+00: lhzu r5,2(r4)
+ sth r5,0(r3)
+ eieio
+ bdnz 00b
+ blr
+
+_GLOBAL(__ide_mm_insl)
+_GLOBAL(_insl_ns)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,4
+ blelr-
+00: lwz r5,0(r3)
+ eieio
+ stwu r5,4(r4)
+ bdnz 00b
+ blr
+
+_GLOBAL(__ide_mm_outsl)
+_GLOBAL(_outsl_ns)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,4
+ blelr-
+00: lwzu r5,4(r4)
+ stw r5,0(r3)
+ eieio
+ bdnz 00b
+ blr
+
+/*
+ * Extended precision shifts.
+ *
+ * Updated to be valid for shift counts from 0 to 63 inclusive.
+ * -- Gabriel
+ *
+ * R3/R4 has 64 bit value
+ * R5 has shift count
+ * result in R3/R4
+ *
+ * ashrdi3: arithmetic right shift (sign propagation)
+ * lshrdi3: logical right shift
+ * ashldi3: left shift
+ */
+_GLOBAL(__ashrdi3)
+ subfic r6,r5,32
+ srw r4,r4,r5 # LSW = count > 31 ? 0 : LSW >> count
+ addi r7,r5,32 # could be xori, or addi with -32
+ slw r6,r3,r6 # t1 = count > 31 ? 0 : MSW << (32-count)
+ rlwinm r8,r7,0,32 # t3 = (count < 32) ? 32 : 0
+ sraw r7,r3,r7 # t2 = MSW >> (count-32)
+ or r4,r4,r6 # LSW |= t1
+ slw r7,r7,r8 # t2 = (count < 32) ? 0 : t2
+ sraw r3,r3,r5 # MSW = MSW >> count
+ or r4,r4,r7 # LSW |= t2
+ blr
+
+_GLOBAL(__ashldi3)
+ subfic r6,r5,32
+ slw r3,r3,r5 # MSW = count > 31 ? 0 : MSW << count
+ addi r7,r5,32 # could be xori, or addi with -32
+ srw r6,r4,r6 # t1 = count > 31 ? 0 : LSW >> (32-count)
+ slw r7,r4,r7 # t2 = count < 32 ? 0 : LSW << (count-32)
+ or r3,r3,r6 # MSW |= t1
+ slw r4,r4,r5 # LSW = LSW << count
+ or r3,r3,r7 # MSW |= t2
+ blr
+
+_GLOBAL(__lshrdi3)
+ subfic r6,r5,32
+ srw r4,r4,r5 # LSW = count > 31 ? 0 : LSW >> count
+ addi r7,r5,32 # could be xori, or addi with -32
+ slw r6,r3,r6 # t1 = count > 31 ? 0 : MSW << (32-count)
+ srw r7,r3,r7 # t2 = count < 32 ? 0 : MSW >> (count-32)
+ or r4,r4,r6 # LSW |= t1
+ srw r3,r3,r5 # MSW = MSW >> count
+ or r4,r4,r7 # LSW |= t2
+ blr
+
+_GLOBAL(abs)
+ srawi r4,r3,31
+ xor r3,r3,r4
+ sub r3,r3,r4
+ blr
+
+_GLOBAL(_get_SP)
+ mr r3,r1 /* Close enough */
+ blr
+
+/*
+ * Create a kernel thread
+ * kernel_thread(fn, arg, flags)
+ */
+_GLOBAL(kernel_thread)
+ stwu r1,-16(r1)
+ stw r30,8(r1)
+ stw r31,12(r1)
+ mr r30,r3 /* function */
+ mr r31,r4 /* argument */
+ ori r3,r5,CLONE_VM /* flags */
+ oris r3,r3,CLONE_UNTRACED>>16
+ li r4,0 /* new sp (unused) */
+ li r0,__NR_clone
+ sc
+ cmpwi 0,r3,0 /* parent or child? */
+ bne 1f /* return if parent */
+ li r0,0 /* make top-level stack frame */
+ stwu r0,-16(r1)
+ mtlr r30 /* fn addr in lr */
+ mr r3,r31 /* load arg and call fn */
+ PPC440EP_ERR42
+ blrl
+ li r0,__NR_exit /* exit if function returns */
+ li r3,0
+ sc
+1: lwz r30,8(r1)
+ lwz r31,12(r1)
+ addi r1,r1,16
+ blr
+
+_GLOBAL(execve)
+ li r0,__NR_execve
+ sc
+ bnslr
+ neg r3,r3
+ blr
+
+/*
+ * This routine is just here to keep GCC happy - sigh...
+ */
+_GLOBAL(__main)
+ blr
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
new file mode 100644
index 000000000000..b3e95ff0dba0
--- /dev/null
+++ b/arch/powerpc/kernel/misc_64.S
@@ -0,0 +1,880 @@
+/*
+ * arch/powerpc/kernel/misc64.S
+ *
+ * This file contains miscellaneous low-level functions.
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
+ * and Paul Mackerras.
+ * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com)
+ * PPC64 updates by Dave Engebretsen (engebret@us.ibm.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/config.h>
+#include <linux/sys.h>
+#include <asm/unistd.h>
+#include <asm/errno.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/cache.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/cputable.h>
+#include <asm/thread_info.h>
+
+ .text
+
+/*
+ * Returns (address we are running at) - (address we were linked at)
+ * for use before the text and data are mapped to KERNELBASE.
+ */
+
+_GLOBAL(reloc_offset)
+ mflr r0
+ bl 1f
+1: mflr r3
+ LOADADDR(r4,1b)
+ subf r3,r4,r3
+ mtlr r0
+ blr
+
+/*
+ * add_reloc_offset(x) returns x + reloc_offset().
+ */
+_GLOBAL(add_reloc_offset)
+ mflr r0
+ bl 1f
+1: mflr r5
+ LOADADDR(r4,1b)
+ subf r5,r4,r5
+ add r3,r3,r5
+ mtlr r0
+ blr
+
+_GLOBAL(get_msr)
+ mfmsr r3
+ blr
+
+_GLOBAL(get_dar)
+ mfdar r3
+ blr
+
+_GLOBAL(get_srr0)
+ mfsrr0 r3
+ blr
+
+_GLOBAL(get_srr1)
+ mfsrr1 r3
+ blr
+
+_GLOBAL(get_sp)
+ mr r3,r1
+ blr
+
+#ifdef CONFIG_IRQSTACKS
+_GLOBAL(call_do_softirq)
+ mflr r0
+ std r0,16(r1)
+ stdu r1,THREAD_SIZE-112(r3)
+ mr r1,r3
+ bl .__do_softirq
+ ld r1,0(r1)
+ ld r0,16(r1)
+ mtlr r0
+ blr
+
+_GLOBAL(call_handle_IRQ_event)
+ mflr r0
+ std r0,16(r1)
+ stdu r1,THREAD_SIZE-112(r6)
+ mr r1,r6
+ bl .handle_IRQ_event
+ ld r1,0(r1)
+ ld r0,16(r1)
+ mtlr r0
+ blr
+#endif /* CONFIG_IRQSTACKS */
+
+ /*
+ * To be called by C code which needs to do some operations with MMU
+ * disabled. Note that interrupts have to be disabled by the caller
+ * prior to calling us. The code called _MUST_ be in the RMO of course
+ * and part of the linear mapping as we don't attempt to translate the
+ * stack pointer at all. The function is called with the stack switched
+ * to this CPU emergency stack
+ *
+ * prototype is void *call_with_mmu_off(void *func, void *data);
+ *
+ * the called function is expected to be of the form
+ *
+ * void *called(void *data);
+ */
+_GLOBAL(call_with_mmu_off)
+ mflr r0 /* get link, save it on stackframe */
+ std r0,16(r1)
+ mr r1,r5 /* save old stack ptr */
+ ld r1,PACAEMERGSP(r13) /* get emerg. stack */
+ subi r1,r1,STACK_FRAME_OVERHEAD
+ std r0,16(r1) /* save link on emerg. stack */
+ std r5,0(r1) /* save old stack ptr in backchain */
+ ld r3,0(r3) /* get to real function ptr (assume same TOC) */
+ bl 2f /* we need LR to return, continue at label 2 */
+
+ ld r0,16(r1) /* we return here from the call, get LR and */
+ ld r1,0(r1) /* .. old stack ptr */
+ mtspr SPRN_SRR0,r0 /* and get back to virtual mode with these */
+ mfmsr r4
+ ori r4,r4,MSR_IR|MSR_DR
+ mtspr SPRN_SRR1,r4
+ rfid
+
+2: mtspr SPRN_SRR0,r3 /* coming from above, enter real mode */
+ mr r3,r4 /* get parameter */
+ mfmsr r0
+ ori r0,r0,MSR_IR|MSR_DR
+ xori r0,r0,MSR_IR|MSR_DR
+ mtspr SPRN_SRR1,r0
+ rfid
+
+
+ .section ".toc","aw"
+PPC64_CACHES:
+ .tc ppc64_caches[TC],ppc64_caches
+ .section ".text"
+
+/*
+ * Write any modified data cache blocks out to memory
+ * and invalidate the corresponding instruction cache blocks.
+ *
+ * flush_icache_range(unsigned long start, unsigned long stop)
+ *
+ * flush all bytes from start through stop-1 inclusive
+ */
+
+_KPROBE(__flush_icache_range)
+
+/*
+ * Flush the data cache to memory
+ *
+ * Different systems have different cache line sizes
+ * and in some cases i-cache and d-cache line sizes differ from
+ * each other.
+ */
+ ld r10,PPC64_CACHES@toc(r2)
+ lwz r7,DCACHEL1LINESIZE(r10)/* Get cache line size */
+ addi r5,r7,-1
+ andc r6,r3,r5 /* round low to line bdy */
+ subf r8,r6,r4 /* compute length */
+ add r8,r8,r5 /* ensure we get enough */
+ lwz r9,DCACHEL1LOGLINESIZE(r10) /* Get log-2 of cache line size */
+ srw. r8,r8,r9 /* compute line count */
+ beqlr /* nothing to do? */
+ mtctr r8
+1: dcbst 0,r6
+ add r6,r6,r7
+ bdnz 1b
+ sync
+
+/* Now invalidate the instruction cache */
+
+ lwz r7,ICACHEL1LINESIZE(r10) /* Get Icache line size */
+ addi r5,r7,-1
+ andc r6,r3,r5 /* round low to line bdy */
+ subf r8,r6,r4 /* compute length */
+ add r8,r8,r5
+ lwz r9,ICACHEL1LOGLINESIZE(r10) /* Get log-2 of Icache line size */
+ srw. r8,r8,r9 /* compute line count */
+ beqlr /* nothing to do? */
+ mtctr r8
+2: icbi 0,r6
+ add r6,r6,r7
+ bdnz 2b
+ isync
+ blr
+ .previous .text
+/*
+ * Like above, but only do the D-cache.
+ *
+ * flush_dcache_range(unsigned long start, unsigned long stop)
+ *
+ * flush all bytes from start to stop-1 inclusive
+ */
+_GLOBAL(flush_dcache_range)
+
+/*
+ * Flush the data cache to memory
+ *
+ * Different systems have different cache line sizes
+ */
+ ld r10,PPC64_CACHES@toc(r2)
+ lwz r7,DCACHEL1LINESIZE(r10) /* Get dcache line size */
+ addi r5,r7,-1
+ andc r6,r3,r5 /* round low to line bdy */
+ subf r8,r6,r4 /* compute length */
+ add r8,r8,r5 /* ensure we get enough */
+ lwz r9,DCACHEL1LOGLINESIZE(r10) /* Get log-2 of dcache line size */
+ srw. r8,r8,r9 /* compute line count */
+ beqlr /* nothing to do? */
+ mtctr r8
+0: dcbst 0,r6
+ add r6,r6,r7
+ bdnz 0b
+ sync
+ blr
+
+/*
+ * Like above, but works on non-mapped physical addresses.
+ * Use only for non-LPAR setups ! It also assumes real mode
+ * is cacheable. Used for flushing out the DART before using
+ * it as uncacheable memory
+ *
+ * flush_dcache_phys_range(unsigned long start, unsigned long stop)
+ *
+ * flush all bytes from start to stop-1 inclusive
+ */
+_GLOBAL(flush_dcache_phys_range)
+ ld r10,PPC64_CACHES@toc(r2)
+ lwz r7,DCACHEL1LINESIZE(r10) /* Get dcache line size */
+ addi r5,r7,-1
+ andc r6,r3,r5 /* round low to line bdy */
+ subf r8,r6,r4 /* compute length */
+ add r8,r8,r5 /* ensure we get enough */
+ lwz r9,DCACHEL1LOGLINESIZE(r10) /* Get log-2 of dcache line size */
+ srw. r8,r8,r9 /* compute line count */
+ beqlr /* nothing to do? */
+ mfmsr r5 /* Disable MMU Data Relocation */
+ ori r0,r5,MSR_DR
+ xori r0,r0,MSR_DR
+ sync
+ mtmsr r0
+ sync
+ isync
+ mtctr r8
+0: dcbst 0,r6
+ add r6,r6,r7
+ bdnz 0b
+ sync
+ isync
+ mtmsr r5 /* Re-enable MMU Data Relocation */
+ sync
+ isync
+ blr
+
+_GLOBAL(flush_inval_dcache_range)
+ ld r10,PPC64_CACHES@toc(r2)
+ lwz r7,DCACHEL1LINESIZE(r10) /* Get dcache line size */
+ addi r5,r7,-1
+ andc r6,r3,r5 /* round low to line bdy */
+ subf r8,r6,r4 /* compute length */
+ add r8,r8,r5 /* ensure we get enough */
+ lwz r9,DCACHEL1LOGLINESIZE(r10)/* Get log-2 of dcache line size */
+ srw. r8,r8,r9 /* compute line count */
+ beqlr /* nothing to do? */
+ sync
+ isync
+ mtctr r8
+0: dcbf 0,r6
+ add r6,r6,r7
+ bdnz 0b
+ sync
+ isync
+ blr
+
+
+/*
+ * Flush a particular page from the data cache to RAM.
+ * Note: this is necessary because the instruction cache does *not*
+ * snoop from the data cache.
+ *
+ * void __flush_dcache_icache(void *page)
+ */
+_GLOBAL(__flush_dcache_icache)
+/*
+ * Flush the data cache to memory
+ *
+ * Different systems have different cache line sizes
+ */
+
+/* Flush the dcache */
+ ld r7,PPC64_CACHES@toc(r2)
+ clrrdi r3,r3,PAGE_SHIFT /* Page align */
+ lwz r4,DCACHEL1LINESPERPAGE(r7) /* Get # dcache lines per page */
+ lwz r5,DCACHEL1LINESIZE(r7) /* Get dcache line size */
+ mr r6,r3
+ mtctr r4
+0: dcbst 0,r6
+ add r6,r6,r5
+ bdnz 0b
+ sync
+
+/* Now invalidate the icache */
+
+ lwz r4,ICACHEL1LINESPERPAGE(r7) /* Get # icache lines per page */
+ lwz r5,ICACHEL1LINESIZE(r7) /* Get icache line size */
+ mtctr r4
+1: icbi 0,r3
+ add r3,r3,r5
+ bdnz 1b
+ isync
+ blr
+
+/*
+ * I/O string operations
+ *
+ * insb(port, buf, len)
+ * outsb(port, buf, len)
+ * insw(port, buf, len)
+ * outsw(port, buf, len)
+ * insl(port, buf, len)
+ * outsl(port, buf, len)
+ * insw_ns(port, buf, len)
+ * outsw_ns(port, buf, len)
+ * insl_ns(port, buf, len)
+ * outsl_ns(port, buf, len)
+ *
+ * The *_ns versions don't do byte-swapping.
+ */
+_GLOBAL(_insb)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,1
+ blelr-
+00: lbz r5,0(r3)
+ eieio
+ stbu r5,1(r4)
+ bdnz 00b
+ twi 0,r5,0
+ isync
+ blr
+
+_GLOBAL(_outsb)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,1
+ blelr-
+00: lbzu r5,1(r4)
+ stb r5,0(r3)
+ bdnz 00b
+ sync
+ blr
+
+_GLOBAL(_insw)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,2
+ blelr-
+00: lhbrx r5,0,r3
+ eieio
+ sthu r5,2(r4)
+ bdnz 00b
+ twi 0,r5,0
+ isync
+ blr
+
+_GLOBAL(_outsw)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,2
+ blelr-
+00: lhzu r5,2(r4)
+ sthbrx r5,0,r3
+ bdnz 00b
+ sync
+ blr
+
+_GLOBAL(_insl)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,4
+ blelr-
+00: lwbrx r5,0,r3
+ eieio
+ stwu r5,4(r4)
+ bdnz 00b
+ twi 0,r5,0
+ isync
+ blr
+
+_GLOBAL(_outsl)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,4
+ blelr-
+00: lwzu r5,4(r4)
+ stwbrx r5,0,r3
+ bdnz 00b
+ sync
+ blr
+
+/* _GLOBAL(ide_insw) now in drivers/ide/ide-iops.c */
+_GLOBAL(_insw_ns)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,2
+ blelr-
+00: lhz r5,0(r3)
+ eieio
+ sthu r5,2(r4)
+ bdnz 00b
+ twi 0,r5,0
+ isync
+ blr
+
+/* _GLOBAL(ide_outsw) now in drivers/ide/ide-iops.c */
+_GLOBAL(_outsw_ns)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,2
+ blelr-
+00: lhzu r5,2(r4)
+ sth r5,0(r3)
+ bdnz 00b
+ sync
+ blr
+
+_GLOBAL(_insl_ns)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,4
+ blelr-
+00: lwz r5,0(r3)
+ eieio
+ stwu r5,4(r4)
+ bdnz 00b
+ twi 0,r5,0
+ isync
+ blr
+
+_GLOBAL(_outsl_ns)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,4
+ blelr-
+00: lwzu r5,4(r4)
+ stw r5,0(r3)
+ bdnz 00b
+ sync
+ blr
+
+/*
+ * identify_cpu and calls setup_cpu
+ * In: r3 = base of the cpu_specs array
+ * r4 = address of cur_cpu_spec
+ * r5 = relocation offset
+ */
+_GLOBAL(identify_cpu)
+ mfpvr r7
+1:
+ lwz r8,CPU_SPEC_PVR_MASK(r3)
+ and r8,r8,r7
+ lwz r9,CPU_SPEC_PVR_VALUE(r3)
+ cmplw 0,r9,r8
+ beq 1f
+ addi r3,r3,CPU_SPEC_ENTRY_SIZE
+ b 1b
+1:
+ sub r0,r3,r5
+ std r0,0(r4)
+ ld r4,CPU_SPEC_SETUP(r3)
+ add r4,r4,r5
+ ld r4,0(r4)
+ add r4,r4,r5
+ mtctr r4
+ /* Calling convention for cpu setup is r3=offset, r4=cur_cpu_spec */
+ mr r4,r3
+ mr r3,r5
+ bctr
+
+/*
+ * do_cpu_ftr_fixups - goes through the list of CPU feature fixups
+ * and writes nop's over sections of code that don't apply for this cpu.
+ * r3 = data offset (not changed)
+ */
+_GLOBAL(do_cpu_ftr_fixups)
+ /* Get CPU 0 features */
+ LOADADDR(r6,cur_cpu_spec)
+ sub r6,r6,r3
+ ld r4,0(r6)
+ sub r4,r4,r3
+ ld r4,CPU_SPEC_FEATURES(r4)
+ /* Get the fixup table */
+ LOADADDR(r6,__start___ftr_fixup)
+ sub r6,r6,r3
+ LOADADDR(r7,__stop___ftr_fixup)
+ sub r7,r7,r3
+ /* Do the fixup */
+1: cmpld r6,r7
+ bgelr
+ addi r6,r6,32
+ ld r8,-32(r6) /* mask */
+ and r8,r8,r4
+ ld r9,-24(r6) /* value */
+ cmpld r8,r9
+ beq 1b
+ ld r8,-16(r6) /* section begin */
+ ld r9,-8(r6) /* section end */
+ subf. r9,r8,r9
+ beq 1b
+ /* write nops over the section of code */
+ /* todo: if large section, add a branch at the start of it */
+ srwi r9,r9,2
+ mtctr r9
+ sub r8,r8,r3
+ lis r0,0x60000000@h /* nop */
+3: stw r0,0(r8)
+ andi. r10,r4,CPU_FTR_SPLIT_ID_CACHE@l
+ beq 2f
+ dcbst 0,r8 /* suboptimal, but simpler */
+ sync
+ icbi 0,r8
+2: addi r8,r8,4
+ bdnz 3b
+ sync /* additional sync needed on g4 */
+ isync
+ b 1b
+
+#if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE)
+/*
+ * Do an IO access in real mode
+ */
+_GLOBAL(real_readb)
+ mfmsr r7
+ ori r0,r7,MSR_DR
+ xori r0,r0,MSR_DR
+ sync
+ mtmsrd r0
+ sync
+ isync
+ mfspr r6,SPRN_HID4
+ rldicl r5,r6,32,0
+ ori r5,r5,0x100
+ rldicl r5,r5,32,0
+ sync
+ mtspr SPRN_HID4,r5
+ isync
+ slbia
+ isync
+ lbz r3,0(r3)
+ sync
+ mtspr SPRN_HID4,r6
+ isync
+ slbia
+ isync
+ mtmsrd r7
+ sync
+ isync
+ blr
+
+ /*
+ * Do an IO access in real mode
+ */
+_GLOBAL(real_writeb)
+ mfmsr r7
+ ori r0,r7,MSR_DR
+ xori r0,r0,MSR_DR
+ sync
+ mtmsrd r0
+ sync
+ isync
+ mfspr r6,SPRN_HID4
+ rldicl r5,r6,32,0
+ ori r5,r5,0x100
+ rldicl r5,r5,32,0
+ sync
+ mtspr SPRN_HID4,r5
+ isync
+ slbia
+ isync
+ stb r3,0(r4)
+ sync
+ mtspr SPRN_HID4,r6
+ isync
+ slbia
+ isync
+ mtmsrd r7
+ sync
+ isync
+ blr
+#endif /* defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) */
+
+/*
+ * Create a kernel thread
+ * kernel_thread(fn, arg, flags)
+ */
+_GLOBAL(kernel_thread)
+ std r29,-24(r1)
+ std r30,-16(r1)
+ stdu r1,-STACK_FRAME_OVERHEAD(r1)
+ mr r29,r3
+ mr r30,r4
+ ori r3,r5,CLONE_VM /* flags */
+ oris r3,r3,(CLONE_UNTRACED>>16)
+ li r4,0 /* new sp (unused) */
+ li r0,__NR_clone
+ sc
+ cmpdi 0,r3,0 /* parent or child? */
+ bne 1f /* return if parent */
+ li r0,0
+ stdu r0,-STACK_FRAME_OVERHEAD(r1)
+ ld r2,8(r29)
+ ld r29,0(r29)
+ mtlr r29 /* fn addr in lr */
+ mr r3,r30 /* load arg and call fn */
+ blrl
+ li r0,__NR_exit /* exit after child exits */
+ li r3,0
+ sc
+1: addi r1,r1,STACK_FRAME_OVERHEAD
+ ld r29,-24(r1)
+ ld r30,-16(r1)
+ blr
+
+/*
+ * disable_kernel_fp()
+ * Disable the FPU.
+ */
+_GLOBAL(disable_kernel_fp)
+ mfmsr r3
+ rldicl r0,r3,(63-MSR_FP_LG),1
+ rldicl r3,r0,(MSR_FP_LG+1),0
+ mtmsrd r3 /* disable use of fpu now */
+ isync
+ blr
+
+#ifdef CONFIG_ALTIVEC
+
+#if 0 /* this has no callers for now */
+/*
+ * disable_kernel_altivec()
+ * Disable the VMX.
+ */
+_GLOBAL(disable_kernel_altivec)
+ mfmsr r3
+ rldicl r0,r3,(63-MSR_VEC_LG),1
+ rldicl r3,r0,(MSR_VEC_LG+1),0
+ mtmsrd r3 /* disable use of VMX now */
+ isync
+ blr
+#endif /* 0 */
+
+/*
+ * giveup_altivec(tsk)
+ * Disable VMX for the task given as the argument,
+ * and save the vector registers in its thread_struct.
+ * Enables the VMX for use in the kernel on return.
+ */
+_GLOBAL(giveup_altivec)
+ mfmsr r5
+ oris r5,r5,MSR_VEC@h
+ mtmsrd r5 /* enable use of VMX now */
+ isync
+ cmpdi 0,r3,0
+ beqlr- /* if no previous owner, done */
+ addi r3,r3,THREAD /* want THREAD of task */
+ ld r5,PT_REGS(r3)
+ cmpdi 0,r5,0
+ SAVE_32VRS(0,r4,r3)
+ mfvscr vr0
+ li r4,THREAD_VSCR
+ stvx vr0,r4,r3
+ beq 1f
+ ld r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+ lis r3,MSR_VEC@h
+ andc r4,r4,r3 /* disable FP for previous task */
+ std r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:
+#ifndef CONFIG_SMP
+ li r5,0
+ ld r4,last_task_used_altivec@got(r2)
+ std r5,0(r4)
+#endif /* CONFIG_SMP */
+ blr
+
+#endif /* CONFIG_ALTIVEC */
+
+_GLOBAL(__setup_cpu_power3)
+ blr
+
+_GLOBAL(execve)
+ li r0,__NR_execve
+ sc
+ bnslr
+ neg r3,r3
+ blr
+
+/* kexec_wait(phys_cpu)
+ *
+ * wait for the flag to change, indicating this kernel is going away but
+ * the slave code for the next one is at addresses 0 to 100.
+ *
+ * This is used by all slaves.
+ *
+ * Physical (hardware) cpu id should be in r3.
+ */
+_GLOBAL(kexec_wait)
+ bl 1f
+1: mflr r5
+ addi r5,r5,kexec_flag-1b
+
+99: HMT_LOW
+#ifdef CONFIG_KEXEC /* use no memory without kexec */
+ lwz r4,0(r5)
+ cmpwi 0,r4,0
+ bnea 0x60
+#endif
+ b 99b
+
+/* this can be in text because we won't change it until we are
+ * running in real anyways
+ */
+kexec_flag:
+ .long 0
+
+
+#ifdef CONFIG_KEXEC
+
+/* kexec_smp_wait(void)
+ *
+ * call with interrupts off
+ * note: this is a terminal routine, it does not save lr
+ *
+ * get phys id from paca
+ * set paca id to -1 to say we got here
+ * switch to real mode
+ * join other cpus in kexec_wait(phys_id)
+ */
+_GLOBAL(kexec_smp_wait)
+ lhz r3,PACAHWCPUID(r13)
+ li r4,-1
+ sth r4,PACAHWCPUID(r13) /* let others know we left */
+ bl real_mode
+ b .kexec_wait
+
+/*
+ * switch to real mode (turn mmu off)
+ * we use the early kernel trick that the hardware ignores bits
+ * 0 and 1 (big endian) of the effective address in real mode
+ *
+ * don't overwrite r3 here, it is live for kexec_wait above.
+ */
+real_mode: /* assume normal blr return */
+1: li r9,MSR_RI
+ li r10,MSR_DR|MSR_IR
+ mflr r11 /* return address to SRR0 */
+ mfmsr r12
+ andc r9,r12,r9
+ andc r10,r12,r10
+
+ mtmsrd r9,1
+ mtspr SPRN_SRR1,r10
+ mtspr SPRN_SRR0,r11
+ rfid
+
+
+/*
+ * kexec_sequence(newstack, start, image, control, clear_all())
+ *
+ * does the grungy work with stack switching and real mode switches
+ * also does simple calls to other code
+ */
+
+_GLOBAL(kexec_sequence)
+ mflr r0
+ std r0,16(r1)
+
+ /* switch stacks to newstack -- &kexec_stack.stack */
+ stdu r1,THREAD_SIZE-112(r3)
+ mr r1,r3
+
+ li r0,0
+ std r0,16(r1)
+
+ /* save regs for local vars on new stack.
+ * yes, we won't go back, but ...
+ */
+ std r31,-8(r1)
+ std r30,-16(r1)
+ std r29,-24(r1)
+ std r28,-32(r1)
+ std r27,-40(r1)
+ std r26,-48(r1)
+ std r25,-56(r1)
+
+ stdu r1,-112-64(r1)
+
+ /* save args into preserved regs */
+ mr r31,r3 /* newstack (both) */
+ mr r30,r4 /* start (real) */
+ mr r29,r5 /* image (virt) */
+ mr r28,r6 /* control, unused */
+ mr r27,r7 /* clear_all() fn desc */
+ mr r26,r8 /* spare */
+ lhz r25,PACAHWCPUID(r13) /* get our phys cpu from paca */
+
+ /* disable interrupts, we are overwriting kernel data next */
+ mfmsr r3
+ rlwinm r3,r3,0,17,15
+ mtmsrd r3,1
+
+ /* copy dest pages, flush whole dest image */
+ mr r3,r29
+ bl .kexec_copy_flush /* (image) */
+
+ /* turn off mmu */
+ bl real_mode
+
+ /* clear out hardware hash page table and tlb */
+ ld r5,0(r27) /* deref function descriptor */
+ mtctr r5
+ bctrl /* ppc_md.hash_clear_all(void); */
+
+/*
+ * kexec image calling is:
+ * the first 0x100 bytes of the entry point are copied to 0
+ *
+ * all slaves branch to slave = 0x60 (absolute)
+ * slave(phys_cpu_id);
+ *
+ * master goes to start = entry point
+ * start(phys_cpu_id, start, 0);
+ *
+ *
+ * a wrapper is needed to call existing kernels, here is an approximate
+ * description of one method:
+ *
+ * v2: (2.6.10)
+ * start will be near the boot_block (maybe 0x100 bytes before it?)
+ * it will have a 0x60, which will b to boot_block, where it will wait
+ * and 0 will store phys into struct boot-block and load r3 from there,
+ * copy kernel 0-0x100 and tell slaves to back down to 0x60 again
+ *
+ * v1: (2.6.9)
+ * boot block will have all cpus scanning device tree to see if they
+ * are the boot cpu ?????
+ * other device tree differences (prop sizes, va vs pa, etc)...
+ */
+
+ /* copy 0x100 bytes starting at start to 0 */
+ li r3,0
+ mr r4,r30
+ li r5,0x100
+ li r6,0
+ bl .copy_and_flush /* (dest, src, copy limit, start offset) */
+1: /* assume normal blr return */
+
+ /* release other cpus to the new kernel secondary start at 0x60 */
+ mflr r5
+ li r6,1
+ stw r6,kexec_flag-1b(5)
+ mr r3,r25 # my phys cpu
+ mr r4,r30 # start, aka phys mem offset
+ mtlr 4
+ li r5,0
+ blr /* image->start(physid, image->start, 0); */
+#endif /* CONFIG_KEXEC */
diff --git a/arch/ppc64/kernel/of_device.c b/arch/powerpc/kernel/of_device.c
index 9f200f0f2ad5..7065e40e2f42 100644
--- a/arch/ppc64/kernel/of_device.c
+++ b/arch/powerpc/kernel/of_device.c
@@ -4,6 +4,8 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
+#include <linux/slab.h>
+
#include <asm/errno.h>
#include <asm/of_device.h>
@@ -184,6 +186,7 @@ void of_release_dev(struct device *dev)
struct of_device *ofdev;
ofdev = to_of_device(dev);
+ of_node_put(ofdev->node);
kfree(ofdev);
}
@@ -244,7 +247,7 @@ struct of_device* of_platform_device_create(struct device_node *np,
return NULL;
memset(dev, 0, sizeof(*dev));
- dev->node = np;
+ dev->node = of_node_get(np);
dev->dma_mask = 0xffffffffUL;
dev->dev.dma_mask = &dev->dma_mask;
dev->dev.parent = parent;
@@ -261,7 +264,6 @@ struct of_device* of_platform_device_create(struct device_node *np,
return dev;
}
-
EXPORT_SYMBOL(of_match_device);
EXPORT_SYMBOL(of_platform_bus_type);
EXPORT_SYMBOL(of_register_driver);
diff --git a/arch/ppc64/kernel/pmc.c b/arch/powerpc/kernel/pmc.c
index 63d9481c3ec2..2d333cc84082 100644
--- a/arch/ppc64/kernel/pmc.c
+++ b/arch/powerpc/kernel/pmc.c
@@ -1,7 +1,10 @@
/*
- * linux/arch/ppc64/kernel/pmc.c
+ * arch/powerpc/kernel/pmc.c
*
* Copyright (C) 2004 David Gibson, IBM Corporation.
+ * Includes code formerly from arch/ppc/kernel/perfmon.c:
+ * Author: Andy Fleming
+ * Copyright (c) 2004 Freescale Semiconductor, Inc
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -17,6 +20,20 @@
#include <asm/processor.h>
#include <asm/pmc.h>
+#if defined(CONFIG_FSL_BOOKE) && !defined(CONFIG_E200)
+static void dummy_perf(struct pt_regs *regs)
+{
+ unsigned int pmgc0 = mfpmr(PMRN_PMGC0);
+
+ pmgc0 &= ~PMGC0_PMIE;
+ mtpmr(PMRN_PMGC0, pmgc0);
+}
+#elif defined(CONFIG_PPC64) || defined(CONFIG_6xx)
+
+#ifndef MMCR0_PMAO
+#define MMCR0_PMAO 0
+#endif
+
/* Ensure exceptions are disabled */
static void dummy_perf(struct pt_regs *regs)
{
@@ -25,6 +42,11 @@ static void dummy_perf(struct pt_regs *regs)
mmcr0 &= ~(MMCR0_PMXE|MMCR0_PMAO);
mtspr(SPRN_MMCR0, mmcr0);
}
+#else
+static void dummy_perf(struct pt_regs *regs)
+{
+}
+#endif
static DEFINE_SPINLOCK(pmc_owner_lock);
static void *pmc_owner_caller; /* mostly for debugging */
@@ -66,11 +88,12 @@ void release_pmc_hardware(void)
}
EXPORT_SYMBOL_GPL(release_pmc_hardware);
+#ifdef CONFIG_PPC64
void power4_enable_pmcs(void)
{
unsigned long hid0;
- hid0 = mfspr(HID0);
+ hid0 = mfspr(SPRN_HID0);
hid0 |= 1UL << (63 - 20);
/* POWER4 requires the following sequence */
@@ -83,6 +106,7 @@ void power4_enable_pmcs(void)
"mfspr %0, %1\n"
"mfspr %0, %1\n"
"mfspr %0, %1\n"
- "isync" : "=&r" (hid0) : "i" (HID0), "0" (hid0):
+ "isync" : "=&r" (hid0) : "i" (SPRN_HID0), "0" (hid0):
"memory");
}
+#endif /* CONFIG_PPC64 */
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
new file mode 100644
index 000000000000..8bc540337ba0
--- /dev/null
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -0,0 +1,273 @@
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/threads.h>
+#include <linux/smp.h>
+#include <linux/sched.h>
+#include <linux/elfcore.h>
+#include <linux/string.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/vt_kern.h>
+#include <linux/nvram.h>
+#include <linux/console.h>
+#include <linux/irq.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/ide.h>
+#include <linux/bitops.h>
+
+#include <asm/page.h>
+#include <asm/semaphore.h>
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/ide.h>
+#include <asm/atomic.h>
+#include <asm/checksum.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+#include <linux/adb.h>
+#include <linux/cuda.h>
+#include <linux/pmu.h>
+#include <asm/prom.h>
+#include <asm/system.h>
+#include <asm/pci-bridge.h>
+#include <asm/irq.h>
+#include <asm/pmac_feature.h>
+#include <asm/dma.h>
+#include <asm/machdep.h>
+#include <asm/hw_irq.h>
+#include <asm/nvram.h>
+#include <asm/mmu_context.h>
+#include <asm/backlight.h>
+#include <asm/time.h>
+#include <asm/cputable.h>
+#include <asm/btext.h>
+#include <asm/div64.h>
+
+#ifdef CONFIG_8xx
+#include <asm/commproc.h>
+#endif
+
+#ifdef CONFIG_PPC32
+extern void transfer_to_handler(void);
+extern void do_IRQ(struct pt_regs *regs);
+extern void machine_check_exception(struct pt_regs *regs);
+extern void alignment_exception(struct pt_regs *regs);
+extern void program_check_exception(struct pt_regs *regs);
+extern void single_step_exception(struct pt_regs *regs);
+extern int do_signal(sigset_t *, struct pt_regs *);
+extern int pmac_newworld;
+extern int sys_sigreturn(struct pt_regs *regs);
+
+EXPORT_SYMBOL(clear_pages);
+EXPORT_SYMBOL(ISA_DMA_THRESHOLD);
+EXPORT_SYMBOL(DMA_MODE_READ);
+EXPORT_SYMBOL(DMA_MODE_WRITE);
+EXPORT_SYMBOL(__div64_32);
+
+EXPORT_SYMBOL(do_signal);
+EXPORT_SYMBOL(transfer_to_handler);
+EXPORT_SYMBOL(do_IRQ);
+EXPORT_SYMBOL(machine_check_exception);
+EXPORT_SYMBOL(alignment_exception);
+EXPORT_SYMBOL(program_check_exception);
+EXPORT_SYMBOL(single_step_exception);
+EXPORT_SYMBOL(sys_sigreturn);
+#endif
+
+#if defined(CONFIG_PPC_PREP)
+EXPORT_SYMBOL(_prep_type);
+EXPORT_SYMBOL(ucSystemType);
+#endif
+
+#if !defined(__INLINE_BITOPS)
+EXPORT_SYMBOL(set_bit);
+EXPORT_SYMBOL(clear_bit);
+EXPORT_SYMBOL(change_bit);
+EXPORT_SYMBOL(test_and_set_bit);
+EXPORT_SYMBOL(test_and_clear_bit);
+EXPORT_SYMBOL(test_and_change_bit);
+#endif /* __INLINE_BITOPS */
+
+EXPORT_SYMBOL(strcpy);
+EXPORT_SYMBOL(strncpy);
+EXPORT_SYMBOL(strcat);
+EXPORT_SYMBOL(strncat);
+EXPORT_SYMBOL(strchr);
+EXPORT_SYMBOL(strrchr);
+EXPORT_SYMBOL(strpbrk);
+EXPORT_SYMBOL(strstr);
+EXPORT_SYMBOL(strlen);
+EXPORT_SYMBOL(strnlen);
+EXPORT_SYMBOL(strcmp);
+EXPORT_SYMBOL(strncmp);
+EXPORT_SYMBOL(strcasecmp);
+
+EXPORT_SYMBOL(csum_partial);
+EXPORT_SYMBOL(csum_partial_copy_generic);
+EXPORT_SYMBOL(ip_fast_csum);
+EXPORT_SYMBOL(csum_tcpudp_magic);
+
+EXPORT_SYMBOL(__copy_tofrom_user);
+EXPORT_SYMBOL(__clear_user);
+EXPORT_SYMBOL(__strncpy_from_user);
+EXPORT_SYMBOL(__strnlen_user);
+
+EXPORT_SYMBOL(_insb);
+EXPORT_SYMBOL(_outsb);
+EXPORT_SYMBOL(_insw);
+EXPORT_SYMBOL(_outsw);
+EXPORT_SYMBOL(_insl);
+EXPORT_SYMBOL(_outsl);
+EXPORT_SYMBOL(_insw_ns);
+EXPORT_SYMBOL(_outsw_ns);
+EXPORT_SYMBOL(_insl_ns);
+EXPORT_SYMBOL(_outsl_ns);
+EXPORT_SYMBOL(ioremap);
+#ifdef CONFIG_44x
+EXPORT_SYMBOL(ioremap64);
+#endif
+EXPORT_SYMBOL(__ioremap);
+EXPORT_SYMBOL(iounmap);
+#ifdef CONFIG_PPC32
+EXPORT_SYMBOL(ioremap_bot); /* aka VMALLOC_END */
+#endif
+
+#if defined(CONFIG_PPC32) && (defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE))
+EXPORT_SYMBOL(ppc_ide_md);
+#endif
+
+#if defined(CONFIG_PCI) && defined(CONFIG_PPC32)
+EXPORT_SYMBOL(isa_io_base);
+EXPORT_SYMBOL(isa_mem_base);
+EXPORT_SYMBOL(pci_dram_offset);
+EXPORT_SYMBOL(pci_alloc_consistent);
+EXPORT_SYMBOL(pci_free_consistent);
+EXPORT_SYMBOL(pci_bus_io_base);
+EXPORT_SYMBOL(pci_bus_io_base_phys);
+EXPORT_SYMBOL(pci_bus_mem_base_phys);
+EXPORT_SYMBOL(pci_bus_to_hose);
+EXPORT_SYMBOL(pci_resource_to_bus);
+EXPORT_SYMBOL(pci_phys_to_bus);
+EXPORT_SYMBOL(pci_bus_to_phys);
+#endif /* CONFIG_PCI */
+
+#ifdef CONFIG_NOT_COHERENT_CACHE
+EXPORT_SYMBOL(flush_dcache_all);
+#endif
+
+EXPORT_SYMBOL(start_thread);
+EXPORT_SYMBOL(kernel_thread);
+
+EXPORT_SYMBOL(giveup_fpu);
+#ifdef CONFIG_ALTIVEC
+EXPORT_SYMBOL(giveup_altivec);
+#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+EXPORT_SYMBOL(giveup_spe);
+#endif /* CONFIG_SPE */
+
+#ifdef CONFIG_PPC64
+EXPORT_SYMBOL(__flush_icache_range);
+#else
+EXPORT_SYMBOL(flush_instruction_cache);
+EXPORT_SYMBOL(flush_icache_range);
+EXPORT_SYMBOL(flush_tlb_kernel_range);
+EXPORT_SYMBOL(flush_tlb_page);
+EXPORT_SYMBOL(_tlbie);
+#endif
+EXPORT_SYMBOL(flush_dcache_range);
+
+#ifdef CONFIG_SMP
+EXPORT_SYMBOL(smp_call_function);
+#ifdef CONFIG_PPC32
+EXPORT_SYMBOL(smp_hw_index);
+#endif
+#endif
+
+#ifdef CONFIG_ADB
+EXPORT_SYMBOL(adb_request);
+EXPORT_SYMBOL(adb_register);
+EXPORT_SYMBOL(adb_unregister);
+EXPORT_SYMBOL(adb_poll);
+EXPORT_SYMBOL(adb_try_handler_change);
+#endif /* CONFIG_ADB */
+#ifdef CONFIG_ADB_CUDA
+EXPORT_SYMBOL(cuda_request);
+EXPORT_SYMBOL(cuda_poll);
+#endif /* CONFIG_ADB_CUDA */
+#if defined(CONFIG_PPC_MULTIPLATFORM) && defined(CONFIG_PPC32)
+EXPORT_SYMBOL(_machine);
+#endif
+#ifdef CONFIG_PPC_PMAC
+EXPORT_SYMBOL(sys_ctrler);
+#endif
+#ifdef CONFIG_VT
+EXPORT_SYMBOL(kd_mksound);
+#endif
+EXPORT_SYMBOL(to_tm);
+
+#ifdef CONFIG_PPC32
+long long __ashrdi3(long long, int);
+long long __ashldi3(long long, int);
+long long __lshrdi3(long long, int);
+EXPORT_SYMBOL(__ashrdi3);
+EXPORT_SYMBOL(__ashldi3);
+EXPORT_SYMBOL(__lshrdi3);
+#endif
+
+EXPORT_SYMBOL(memcpy);
+EXPORT_SYMBOL(memset);
+EXPORT_SYMBOL(memmove);
+EXPORT_SYMBOL(memscan);
+EXPORT_SYMBOL(memcmp);
+EXPORT_SYMBOL(memchr);
+
+#if defined(CONFIG_FB_VGA16_MODULE)
+EXPORT_SYMBOL(screen_info);
+#endif
+
+#ifdef CONFIG_PPC32
+EXPORT_SYMBOL(__delay);
+EXPORT_SYMBOL(timer_interrupt);
+EXPORT_SYMBOL(irq_desc);
+EXPORT_SYMBOL(tb_ticks_per_jiffy);
+EXPORT_SYMBOL(console_drivers);
+EXPORT_SYMBOL(cacheable_memcpy);
+#endif
+
+EXPORT_SYMBOL(__up);
+EXPORT_SYMBOL(__down);
+EXPORT_SYMBOL(__down_interruptible);
+
+#ifdef CONFIG_8xx
+EXPORT_SYMBOL(cpm_install_handler);
+EXPORT_SYMBOL(cpm_free_handler);
+#endif /* CONFIG_8xx */
+#if defined(CONFIG_8xx) || defined(CONFIG_40x) || defined(CONFIG_85xx) ||\
+ defined(CONFIG_83xx)
+EXPORT_SYMBOL(__res);
+#endif
+
+#ifdef CONFIG_PPC32
+EXPORT_SYMBOL(next_mmu_context);
+EXPORT_SYMBOL(set_context);
+#endif
+
+#ifdef CONFIG_PPC_STD_MMU_32
+extern long mol_trampoline;
+EXPORT_SYMBOL(mol_trampoline); /* For MOL */
+EXPORT_SYMBOL(flush_hash_pages); /* For MOL */
+EXPORT_SYMBOL_GPL(__handle_mm_fault); /* For MOL */
+#ifdef CONFIG_SMP
+extern int mmu_hash_lock;
+EXPORT_SYMBOL(mmu_hash_lock); /* For MOL */
+#endif /* CONFIG_SMP */
+extern long *intercept_table;
+EXPORT_SYMBOL(intercept_table);
+#endif /* CONFIG_PPC_STD_MMU_32 */
+#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+EXPORT_SYMBOL(__mtdcr);
+EXPORT_SYMBOL(__mfdcr);
+#endif
diff --git a/arch/ppc64/kernel/process.c b/arch/powerpc/kernel/process.c
index 887005358eb1..8f85dabe4df3 100644
--- a/arch/ppc64/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/ppc64/kernel/process.c
+ * arch/ppc/kernel/process.c
*
* Derived from "arch/i386/kernel/process.c"
* Copyright (C) 1995 Linus Torvalds
@@ -7,7 +7,7 @@
* Updated and modified by Cort Dougan (cort@cs.nmt.edu) and
* Paul Mackerras (paulus@cs.anu.edu.au)
*
- * PowerPC version
+ * PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
*
* This program is free software; you can redistribute it and/or
@@ -17,7 +17,6 @@
*/
#include <linux/config.h>
-#include <linux/module.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
@@ -26,15 +25,17 @@
#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
+#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/user.h>
#include <linux/elf.h>
#include <linux/init.h>
-#include <linux/init_task.h>
#include <linux/prctl.h>
-#include <linux/ptrace.h>
+#include <linux/init_task.h>
+#include <linux/module.h>
#include <linux/kallsyms.h>
-#include <linux/interrupt.h>
+#include <linux/mqueue.h>
+#include <linux/hardirq.h>
#include <linux/utsname.h>
#include <linux/kprobes.h>
@@ -44,21 +45,19 @@
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/mmu.h>
-#include <asm/mmu_context.h>
#include <asm/prom.h>
-#include <asm/ppcdebug.h>
-#include <asm/machdep.h>
-#include <asm/iSeries/HvCallHpt.h>
-#include <asm/cputable.h>
+#ifdef CONFIG_PPC64
#include <asm/firmware.h>
-#include <asm/sections.h>
-#include <asm/tlbflush.h>
-#include <asm/time.h>
#include <asm/plpar_wrappers.h>
+#include <asm/time.h>
+#endif
+
+extern unsigned long _get_SP(void);
#ifndef CONFIG_SMP
struct task_struct *last_task_used_math = NULL;
struct task_struct *last_task_used_altivec = NULL;
+struct task_struct *last_task_used_spe = NULL;
#endif
/*
@@ -121,7 +120,6 @@ int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs)
}
#ifdef CONFIG_ALTIVEC
-
void enable_kernel_altivec(void)
{
WARN_ON(preemptible());
@@ -130,7 +128,7 @@ void enable_kernel_altivec(void)
if (current->thread.regs && (current->thread.regs->msr & MSR_VEC))
giveup_altivec(current);
else
- giveup_altivec(NULL); /* just enables FP for kernel */
+ giveup_altivec(NULL); /* just enable AltiVec for kernel - force */
#else
giveup_altivec(last_task_used_altivec);
#endif /* CONFIG_SMP */
@@ -161,9 +159,48 @@ int dump_task_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs)
memcpy(vrregs, &current->thread.vr[0], sizeof(*vrregs));
return 1;
}
-
#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+
+void enable_kernel_spe(void)
+{
+ WARN_ON(preemptible());
+
+#ifdef CONFIG_SMP
+ if (current->thread.regs && (current->thread.regs->msr & MSR_SPE))
+ giveup_spe(current);
+ else
+ giveup_spe(NULL); /* just enable SPE for kernel - force */
+#else
+ giveup_spe(last_task_used_spe);
+#endif /* __SMP __ */
+}
+EXPORT_SYMBOL(enable_kernel_spe);
+
+void flush_spe_to_thread(struct task_struct *tsk)
+{
+ if (tsk->thread.regs) {
+ preempt_disable();
+ if (tsk->thread.regs->msr & MSR_SPE) {
+#ifdef CONFIG_SMP
+ BUG_ON(tsk != current);
+#endif
+ giveup_spe(current);
+ }
+ preempt_enable();
+ }
+}
+
+int dump_spe(struct pt_regs *regs, elf_vrregset_t *evrregs)
+{
+ flush_spe_to_thread(current);
+ /* We copy u32 evr[32] + u64 acc + u32 spefscr -> 35 */
+ memcpy(evrregs, &current->thread.evr[0], sizeof(u32) * 35);
+ return 1;
+}
+#endif /* CONFIG_SPE */
+
static void set_dabr_spr(unsigned long val)
{
mtspr(SPRN_DABR, val);
@@ -173,24 +210,27 @@ int set_dabr(unsigned long dabr)
{
int ret = 0;
+#ifdef CONFIG_PPC64
if (firmware_has_feature(FW_FEATURE_XDABR)) {
/* We want to catch accesses from kernel and userspace */
unsigned long flags = H_DABRX_KERNEL|H_DABRX_USER;
ret = plpar_set_xdabr(dabr, flags);
} else if (firmware_has_feature(FW_FEATURE_DABR)) {
ret = plpar_set_dabr(dabr);
- } else {
+ } else
+#endif
set_dabr_spr(dabr);
- }
return ret;
}
+#ifdef CONFIG_PPC64
DEFINE_PER_CPU(struct cpu_usage, cpu_usage_array);
static DEFINE_PER_CPU(unsigned long, current_dabr);
+#endif
struct task_struct *__switch_to(struct task_struct *prev,
- struct task_struct *new)
+ struct task_struct *new)
{
struct thread_struct *new_thread, *old_thread;
unsigned long flags;
@@ -200,7 +240,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
/* avoid complexity of lazy save/restore of fpu
* by just saving it every time we switch out if
* this task used the fpu during the last quantum.
- *
+ *
* If it tries to use the fpu again, it'll trap and
* reload its fp regs. So we don't have to do a restore
* every switch, just a save.
@@ -209,31 +249,65 @@ struct task_struct *__switch_to(struct task_struct *prev,
if (prev->thread.regs && (prev->thread.regs->msr & MSR_FP))
giveup_fpu(prev);
#ifdef CONFIG_ALTIVEC
+ /*
+ * If the previous thread used altivec in the last quantum
+ * (thus changing altivec regs) then save them.
+ * We used to check the VRSAVE register but not all apps
+ * set it, so we don't rely on it now (and in fact we need
+ * to save & restore VSCR even if VRSAVE == 0). -- paulus
+ *
+ * On SMP we always save/restore altivec regs just to avoid the
+ * complexity of changing processors.
+ * -- Cort
+ */
if (prev->thread.regs && (prev->thread.regs->msr & MSR_VEC))
giveup_altivec(prev);
#endif /* CONFIG_ALTIVEC */
-#endif /* CONFIG_SMP */
+#ifdef CONFIG_SPE
+ /*
+ * If the previous thread used spe in the last quantum
+ * (thus changing spe regs) then save them.
+ *
+ * On SMP we always save/restore spe regs just to avoid the
+ * complexity of changing processors.
+ */
+ if ((prev->thread.regs && (prev->thread.regs->msr & MSR_SPE)))
+ giveup_spe(prev);
+#endif /* CONFIG_SPE */
-#if defined(CONFIG_ALTIVEC) && !defined(CONFIG_SMP)
+#else /* CONFIG_SMP */
+#ifdef CONFIG_ALTIVEC
/* Avoid the trap. On smp this this never happens since
* we don't set last_task_used_altivec -- Cort
*/
if (new->thread.regs && last_task_used_altivec == new)
new->thread.regs->msr |= MSR_VEC;
#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+ /* Avoid the trap. On smp this this never happens since
+ * we don't set last_task_used_spe
+ */
+ if (new->thread.regs && last_task_used_spe == new)
+ new->thread.regs->msr |= MSR_SPE;
+#endif /* CONFIG_SPE */
+#endif /* CONFIG_SMP */
+
+#ifdef CONFIG_PPC64 /* for now */
if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr)) {
set_dabr(new->thread.dabr);
__get_cpu_var(current_dabr) = new->thread.dabr;
}
flush_tlb_pending();
+#endif
new_thread = &new->thread;
old_thread = &current->thread;
- /* Collect purr utilization data per process and per processor
- * wise purr is nothing but processor time base
+#ifdef CONFIG_PPC64
+ /*
+ * Collect processor utilization data per process
*/
if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
struct cpu_usage *cu = &__get_cpu_var(cpu_usage_array);
@@ -243,6 +317,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
old_thread->accum_tb += (current_tb - start_tb);
new_thread->start_tb = current_tb;
}
+#endif
local_irq_save(flags);
last = _switch(old_thread, new_thread);
@@ -254,6 +329,13 @@ struct task_struct *__switch_to(struct task_struct *prev,
static int instructions_to_print = 16;
+#ifdef CONFIG_PPC64
+#define BAD_PC(pc) ((REGION_ID(pc) != KERNEL_REGION_ID) && \
+ (REGION_ID(pc) != VMALLOC_REGION_ID))
+#else
+#define BAD_PC(pc) ((pc) < KERNELBASE)
+#endif
+
static void show_instructions(struct pt_regs *regs)
{
int i;
@@ -268,9 +350,7 @@ static void show_instructions(struct pt_regs *regs)
if (!(i % 8))
printk("\n");
- if (((REGION_ID(pc) != KERNEL_REGION_ID) &&
- (REGION_ID(pc) != VMALLOC_REGION_ID)) ||
- __get_user(instr, (unsigned int *)pc)) {
+ if (BAD_PC(pc) || __get_user(instr, (unsigned int *)pc)) {
printk("XXXXXXXX ");
} else {
if (regs->nip == pc)
@@ -285,50 +365,82 @@ static void show_instructions(struct pt_regs *regs)
printk("\n");
}
+static struct regbit {
+ unsigned long bit;
+ const char *name;
+} msr_bits[] = {
+ {MSR_EE, "EE"},
+ {MSR_PR, "PR"},
+ {MSR_FP, "FP"},
+ {MSR_ME, "ME"},
+ {MSR_IR, "IR"},
+ {MSR_DR, "DR"},
+ {0, NULL}
+};
+
+static void printbits(unsigned long val, struct regbit *bits)
+{
+ const char *sep = "";
+
+ printk("<");
+ for (; bits->bit; ++bits)
+ if (val & bits->bit) {
+ printk("%s%s", sep, bits->name);
+ sep = ",";
+ }
+ printk(">");
+}
+
+#ifdef CONFIG_PPC64
+#define REG "%016lX"
+#define REGS_PER_LINE 4
+#define LAST_VOLATILE 13
+#else
+#define REG "%08lX"
+#define REGS_PER_LINE 8
+#define LAST_VOLATILE 12
+#endif
+
void show_regs(struct pt_regs * regs)
{
- int i;
- unsigned long trap;
+ int i, trap;
- printk("NIP: %016lX XER: %08X LR: %016lX CTR: %016lX\n",
- regs->nip, (unsigned int)regs->xer, regs->link, regs->ctr);
+ printk("NIP: "REG" LR: "REG" CTR: "REG"\n",
+ regs->nip, regs->link, regs->ctr);
printk("REGS: %p TRAP: %04lx %s (%s)\n",
regs, regs->trap, print_tainted(), system_utsname.release);
- printk("MSR: %016lx EE: %01x PR: %01x FP: %01x ME: %01x "
- "IR/DR: %01x%01x CR: %08X\n",
- regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0,
- regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0,
- regs->msr&MSR_IR ? 1 : 0,
- regs->msr&MSR_DR ? 1 : 0,
- (unsigned int)regs->ccr);
+ printk("MSR: "REG" ", regs->msr);
+ printbits(regs->msr, msr_bits);
+ printk(" CR: %08lX XER: %08lX\n", regs->ccr, regs->xer);
trap = TRAP(regs);
- printk("DAR: %016lx DSISR: %016lx\n", regs->dar, regs->dsisr);
- printk("TASK: %p[%d] '%s' THREAD: %p",
+ if (trap == 0x300 || trap == 0x600)
+ printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr);
+ printk("TASK = %p[%d] '%s' THREAD: %p",
current, current->pid, current->comm, current->thread_info);
#ifdef CONFIG_SMP
printk(" CPU: %d", smp_processor_id());
#endif /* CONFIG_SMP */
- for (i = 0; i < 32; i++) {
- if ((i % 4) == 0) {
+ for (i = 0; i < 32; i++) {
+ if ((i % REGS_PER_LINE) == 0)
printk("\n" KERN_INFO "GPR%02d: ", i);
- }
-
- printk("%016lX ", regs->gpr[i]);
- if (i == 13 && !FULL_REGS(regs))
+ printk(REG " ", regs->gpr[i]);
+ if (i == LAST_VOLATILE && !FULL_REGS(regs))
break;
}
printk("\n");
+#ifdef CONFIG_KALLSYMS
/*
* Lookup NIP late so we have the best change of getting the
* above info out without failing
*/
- printk("NIP [%016lx] ", regs->nip);
+ printk("NIP ["REG"] ", regs->nip);
print_symbol("%s\n", regs->nip);
- printk("LR [%016lx] ", regs->link);
+ printk("LR ["REG"] ", regs->link);
print_symbol("%s\n", regs->link);
- show_stack(current, (unsigned long *)regs->gpr[1]);
+#endif
+ show_stack(current, (unsigned long *) regs->gpr[1]);
if (!user_mode(regs))
show_instructions(regs);
}
@@ -344,16 +456,22 @@ void exit_thread(void)
if (last_task_used_altivec == current)
last_task_used_altivec = NULL;
#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+ if (last_task_used_spe == current)
+ last_task_used_spe = NULL;
+#endif
#endif /* CONFIG_SMP */
}
void flush_thread(void)
{
+#ifdef CONFIG_PPC64
struct thread_info *t = current_thread_info();
- kprobe_flush_task(current);
if (t->flags & _TIF_ABI_PENDING)
t->flags ^= (_TIF_ABI_PENDING | _TIF_32BIT);
+#endif
+ kprobe_flush_task(current);
#ifndef CONFIG_SMP
if (last_task_used_math == current)
@@ -362,12 +480,18 @@ void flush_thread(void)
if (last_task_used_altivec == current)
last_task_used_altivec = NULL;
#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+ if (last_task_used_spe == current)
+ last_task_used_spe = NULL;
+#endif
#endif /* CONFIG_SMP */
+#ifdef CONFIG_PPC64 /* for now */
if (current->thread.dabr) {
current->thread.dabr = 0;
set_dabr(0);
}
+#endif
}
void
@@ -375,7 +499,6 @@ release_thread(struct task_struct *t)
{
}
-
/*
* This gets called before we allocate a new thread and copy
* the current task into it.
@@ -384,36 +507,44 @@ void prepare_to_copy(struct task_struct *tsk)
{
flush_fp_to_thread(current);
flush_altivec_to_thread(current);
+ flush_spe_to_thread(current);
}
/*
* Copy a thread..
*/
-int
-copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
- unsigned long unused, struct task_struct *p, struct pt_regs *regs)
+int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+ unsigned long unused, struct task_struct *p,
+ struct pt_regs *regs)
{
struct pt_regs *childregs, *kregs;
extern void ret_from_fork(void);
unsigned long sp = (unsigned long)p->thread_info + THREAD_SIZE;
+ CHECK_FULL_REGS(regs);
/* Copy registers */
sp -= sizeof(struct pt_regs);
childregs = (struct pt_regs *) sp;
*childregs = *regs;
if ((childregs->msr & MSR_PR) == 0) {
- /* for kernel thread, set stackptr in new task */
+ /* for kernel thread, set `current' and stackptr in new task */
childregs->gpr[1] = sp + sizeof(struct pt_regs);
- p->thread.regs = NULL; /* no user register state */
+#ifdef CONFIG_PPC32
+ childregs->gpr[2] = (unsigned long) p;
+#else
clear_ti_thread_flag(p->thread_info, TIF_32BIT);
+#endif
+ p->thread.regs = NULL; /* no user register state */
} else {
childregs->gpr[1] = usp;
p->thread.regs = childregs;
if (clone_flags & CLONE_SETTLS) {
- if (test_thread_flag(TIF_32BIT))
- childregs->gpr[2] = childregs->gpr[6];
- else
+#ifdef CONFIG_PPC64
+ if (!test_thread_flag(TIF_32BIT))
childregs->gpr[13] = childregs->gpr[6];
+ else
+#endif
+ childregs->gpr[2] = childregs->gpr[6];
}
}
childregs->gpr[3] = 0; /* Result from fork() */
@@ -431,6 +562,8 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
kregs = (struct pt_regs *) sp;
sp -= STACK_FRAME_OVERHEAD;
p->thread.ksp = sp;
+
+#ifdef CONFIG_PPC64
if (cpu_has_feature(CPU_FTR_SLB)) {
unsigned long sp_vsid = get_kernel_vsid(sp);
@@ -449,6 +582,10 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
* function.
*/
kregs->nip = *((unsigned long *)ret_from_fork);
+#else
+ kregs->nip = (unsigned long)ret_from_fork;
+ p->thread.last_syscall = -1;
+#endif
return 0;
}
@@ -456,30 +593,17 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
/*
* Set up a thread for executing a new program
*/
-void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp)
+void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
{
- unsigned long entry, toc, load_addr = regs->gpr[2];
+#ifdef CONFIG_PPC64
+ unsigned long load_addr = regs->gpr[2]; /* saved by ELF_PLAT_INIT */
+#endif
- /* fdptr is a relocated pointer to the function descriptor for
- * the elf _start routine. The first entry in the function
- * descriptor is the entry address of _start and the second
- * entry is the TOC value we need to use.
- */
set_fs(USER_DS);
- __get_user(entry, (unsigned long __user *)fdptr);
- __get_user(toc, (unsigned long __user *)fdptr+1);
-
- /* Check whether the e_entry function descriptor entries
- * need to be relocated before we can use them.
- */
- if (load_addr != 0) {
- entry += load_addr;
- toc += load_addr;
- }
/*
* If we exec out of a kernel thread then thread.regs will not be
- * set. Do it now.
+ * set. Do it now.
*/
if (!current->thread.regs) {
unsigned long childregs = (unsigned long)current->thread_info +
@@ -488,36 +612,101 @@ void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp)
current->thread.regs = (struct pt_regs *)childregs;
}
- regs->nip = entry;
+ memset(regs->gpr, 0, sizeof(regs->gpr));
+ regs->ctr = 0;
+ regs->link = 0;
+ regs->xer = 0;
+ regs->ccr = 0;
regs->gpr[1] = sp;
- regs->gpr[2] = toc;
- regs->msr = MSR_USER64;
+
+#ifdef CONFIG_PPC32
+ regs->mq = 0;
+ regs->nip = start;
+ regs->msr = MSR_USER;
+#else
+ if (!test_thread_flag(TIF_32BIT)) {
+ unsigned long entry, toc;
+
+ /* start is a relocated pointer to the function descriptor for
+ * the elf _start routine. The first entry in the function
+ * descriptor is the entry address of _start and the second
+ * entry is the TOC value we need to use.
+ */
+ __get_user(entry, (unsigned long __user *)start);
+ __get_user(toc, (unsigned long __user *)start+1);
+
+ /* Check whether the e_entry function descriptor entries
+ * need to be relocated before we can use them.
+ */
+ if (load_addr != 0) {
+ entry += load_addr;
+ toc += load_addr;
+ }
+ regs->nip = entry;
+ regs->gpr[2] = toc;
+ regs->msr = MSR_USER64;
+ } else {
+ regs->nip = start;
+ regs->gpr[2] = 0;
+ regs->msr = MSR_USER32;
+ }
+#endif
+
#ifndef CONFIG_SMP
if (last_task_used_math == current)
- last_task_used_math = 0;
-#endif /* CONFIG_SMP */
- memset(current->thread.fpr, 0, sizeof(current->thread.fpr));
- current->thread.fpscr = 0;
+ last_task_used_math = NULL;
#ifdef CONFIG_ALTIVEC
-#ifndef CONFIG_SMP
if (last_task_used_altivec == current)
- last_task_used_altivec = 0;
+ last_task_used_altivec = NULL;
+#endif
+#ifdef CONFIG_SPE
+ if (last_task_used_spe == current)
+ last_task_used_spe = NULL;
+#endif
#endif /* CONFIG_SMP */
+ memset(current->thread.fpr, 0, sizeof(current->thread.fpr));
+ current->thread.fpscr.val = 0;
+#ifdef CONFIG_ALTIVEC
memset(current->thread.vr, 0, sizeof(current->thread.vr));
- current->thread.vscr.u[0] = 0;
- current->thread.vscr.u[1] = 0;
- current->thread.vscr.u[2] = 0;
+ memset(&current->thread.vscr, 0, sizeof(current->thread.vscr));
current->thread.vscr.u[3] = 0x00010000; /* Java mode disabled */
current->thread.vrsave = 0;
current->thread.used_vr = 0;
#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+ memset(current->thread.evr, 0, sizeof(current->thread.evr));
+ current->thread.acc = 0;
+ current->thread.spefscr = 0;
+ current->thread.used_spe = 0;
+#endif /* CONFIG_SPE */
}
-EXPORT_SYMBOL(start_thread);
+
+#define PR_FP_ALL_EXCEPT (PR_FP_EXC_DIV | PR_FP_EXC_OVF | PR_FP_EXC_UND \
+ | PR_FP_EXC_RES | PR_FP_EXC_INV)
int set_fpexc_mode(struct task_struct *tsk, unsigned int val)
{
struct pt_regs *regs = tsk->thread.regs;
+ /* This is a bit hairy. If we are an SPE enabled processor
+ * (have embedded fp) we store the IEEE exception enable flags in
+ * fpexc_mode. fpexc_mode is also used for setting FP exception
+ * mode (asyn, precise, disabled) for 'Classic' FP. */
+ if (val & PR_FP_EXC_SW_ENABLE) {
+#ifdef CONFIG_SPE
+ tsk->thread.fpexc_mode = val &
+ (PR_FP_EXC_SW_ENABLE | PR_FP_ALL_EXCEPT);
+ return 0;
+#else
+ return -EINVAL;
+#endif
+ }
+
+ /* on a CONFIG_SPE this does not hurt us. The bits that
+ * __pack_fe01 use do not overlap with bits used for
+ * PR_FP_EXC_SW_ENABLE. Additionally, the MSR[FE0,FE1] bits
+ * on CONFIG_SPE implementations are reserved so writing to
+ * them does not change anything */
if (val > PR_FP_EXC_PRECISE)
return -EINVAL;
tsk->thread.fpexc_mode = __pack_fe01(val);
@@ -531,38 +720,41 @@ int get_fpexc_mode(struct task_struct *tsk, unsigned long adr)
{
unsigned int val;
- val = __unpack_fe01(tsk->thread.fpexc_mode);
+ if (tsk->thread.fpexc_mode & PR_FP_EXC_SW_ENABLE)
+#ifdef CONFIG_SPE
+ val = tsk->thread.fpexc_mode;
+#else
+ return -EINVAL;
+#endif
+ else
+ val = __unpack_fe01(tsk->thread.fpexc_mode);
return put_user(val, (unsigned int __user *) adr);
}
-int sys_clone(unsigned long clone_flags, unsigned long p2, unsigned long p3,
- unsigned long p4, unsigned long p5, unsigned long p6,
+#define TRUNC_PTR(x) ((typeof(x))(((unsigned long)(x)) & 0xffffffff))
+
+int sys_clone(unsigned long clone_flags, unsigned long usp,
+ int __user *parent_tidp, void __user *child_threadptr,
+ int __user *child_tidp, int p6,
struct pt_regs *regs)
{
- unsigned long parent_tidptr = 0;
- unsigned long child_tidptr = 0;
-
- if (p2 == 0)
- p2 = regs->gpr[1]; /* stack pointer for child */
-
- if (clone_flags & (CLONE_PARENT_SETTID | CLONE_CHILD_SETTID |
- CLONE_CHILD_CLEARTID)) {
- parent_tidptr = p3;
- child_tidptr = p5;
- if (test_thread_flag(TIF_32BIT)) {
- parent_tidptr &= 0xffffffff;
- child_tidptr &= 0xffffffff;
- }
+ CHECK_FULL_REGS(regs);
+ if (usp == 0)
+ usp = regs->gpr[1]; /* stack pointer for child */
+#ifdef CONFIG_PPC64
+ if (test_thread_flag(TIF_32BIT)) {
+ parent_tidp = TRUNC_PTR(parent_tidp);
+ child_tidp = TRUNC_PTR(child_tidp);
}
-
- return do_fork(clone_flags, p2, regs, 0,
- (int __user *)parent_tidptr, (int __user *)child_tidptr);
+#endif
+ return do_fork(clone_flags, usp, regs, 0, parent_tidp, child_tidp);
}
int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3,
unsigned long p4, unsigned long p5, unsigned long p6,
struct pt_regs *regs)
{
+ CHECK_FULL_REGS(regs);
return do_fork(SIGCHLD, regs->gpr[1], regs, 0, NULL, NULL);
}
@@ -570,8 +762,9 @@ int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,
unsigned long p4, unsigned long p5, unsigned long p6,
struct pt_regs *regs)
{
- return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gpr[1], regs, 0,
- NULL, NULL);
+ CHECK_FULL_REGS(regs);
+ return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gpr[1],
+ regs, 0, NULL, NULL);
}
int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
@@ -579,30 +772,27 @@ int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
struct pt_regs *regs)
{
int error;
- char * filename;
-
+ char *filename;
+
filename = getname((char __user *) a0);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
flush_fp_to_thread(current);
flush_altivec_to_thread(current);
+ flush_spe_to_thread(current);
error = do_execve(filename, (char __user * __user *) a1,
- (char __user * __user *) a2, regs);
-
+ (char __user * __user *) a2, regs);
if (error == 0) {
task_lock(current);
current->ptrace &= ~PT_DTRACE;
task_unlock(current);
}
putname(filename);
-
out:
return error;
}
-static int kstack_depth_to_print = 64;
-
static int validate_sp(unsigned long sp, struct task_struct *p,
unsigned long nbytes)
{
@@ -627,6 +817,20 @@ static int validate_sp(unsigned long sp, struct task_struct *p,
return 0;
}
+#ifdef CONFIG_PPC64
+#define MIN_STACK_FRAME 112 /* same as STACK_FRAME_OVERHEAD, in fact */
+#define FRAME_LR_SAVE 2
+#define INT_FRAME_SIZE (sizeof(struct pt_regs) + STACK_FRAME_OVERHEAD + 288)
+#define REGS_MARKER 0x7265677368657265ul
+#define FRAME_MARKER 12
+#else
+#define MIN_STACK_FRAME 16
+#define FRAME_LR_SAVE 1
+#define INT_FRAME_SIZE (sizeof(struct pt_regs) + STACK_FRAME_OVERHEAD)
+#define REGS_MARKER 0x72656773ul
+#define FRAME_MARKER 2
+#endif
+
unsigned long get_wchan(struct task_struct *p)
{
unsigned long ip, sp;
@@ -636,15 +840,15 @@ unsigned long get_wchan(struct task_struct *p)
return 0;
sp = p->thread.ksp;
- if (!validate_sp(sp, p, 112))
+ if (!validate_sp(sp, p, MIN_STACK_FRAME))
return 0;
do {
sp = *(unsigned long *)sp;
- if (!validate_sp(sp, p, 112))
+ if (!validate_sp(sp, p, MIN_STACK_FRAME))
return 0;
if (count > 0) {
- ip = *(unsigned long *)(sp + 16);
+ ip = ((unsigned long *)sp)[FRAME_LR_SAVE];
if (!in_sched_functions(ip))
return ip;
}
@@ -653,33 +857,35 @@ unsigned long get_wchan(struct task_struct *p)
}
EXPORT_SYMBOL(get_wchan);
-void show_stack(struct task_struct *p, unsigned long *_sp)
+static int kstack_depth_to_print = 64;
+
+void show_stack(struct task_struct *tsk, unsigned long *stack)
{
- unsigned long ip, newsp, lr;
+ unsigned long sp, ip, lr, newsp;
int count = 0;
- unsigned long sp = (unsigned long)_sp;
int firstframe = 1;
+ sp = (unsigned long) stack;
+ if (tsk == NULL)
+ tsk = current;
if (sp == 0) {
- if (p) {
- sp = p->thread.ksp;
- } else {
- sp = __get_SP();
- p = current;
- }
+ if (tsk == current)
+ asm("mr %0,1" : "=r" (sp));
+ else
+ sp = tsk->thread.ksp;
}
lr = 0;
printk("Call Trace:\n");
do {
- if (!validate_sp(sp, p, 112))
+ if (!validate_sp(sp, tsk, MIN_STACK_FRAME))
return;
- _sp = (unsigned long *) sp;
- newsp = _sp[0];
- ip = _sp[2];
+ stack = (unsigned long *) sp;
+ newsp = stack[0];
+ ip = stack[FRAME_LR_SAVE];
if (!firstframe || ip != lr) {
- printk("[%016lx] [%016lx] ", sp, ip);
+ printk("["REG"] ["REG"] ", sp, ip);
print_symbol("%s", ip);
if (firstframe)
printk(" (unreliable)");
@@ -691,8 +897,8 @@ void show_stack(struct task_struct *p, unsigned long *_sp)
* See if this is an exception frame.
* We look for the "regshere" marker in the current frame.
*/
- if (validate_sp(sp, p, sizeof(struct pt_regs) + 400)
- && _sp[12] == 0x7265677368657265ul) {
+ if (validate_sp(sp, tsk, INT_FRAME_SIZE)
+ && stack[FRAME_MARKER] == REGS_MARKER) {
struct pt_regs *regs = (struct pt_regs *)
(sp + STACK_FRAME_OVERHEAD);
printk("--- Exception: %lx", regs->trap);
@@ -708,6 +914,6 @@ void show_stack(struct task_struct *p, unsigned long *_sp)
void dump_stack(void)
{
- show_stack(current, (unsigned long *)__get_SP());
+ show_stack(current, NULL);
}
EXPORT_SYMBOL(dump_stack);
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
new file mode 100644
index 000000000000..2eccd0e159e3
--- /dev/null
+++ b/arch/powerpc/kernel/prom.c
@@ -0,0 +1,2170 @@
+/*
+ * Procedures for creating, accessing and interpreting the device tree.
+ *
+ * Paul Mackerras August 1996.
+ * Copyright (C) 1996-2005 Paul Mackerras.
+ *
+ * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
+ * {engebret|bergner}@us.ibm.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.
+ */
+
+#undef DEBUG
+
+#include <stdarg.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/threads.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/stringify.h>
+#include <linux/delay.h>
+#include <linux/initrd.h>
+#include <linux/bitops.h>
+#include <linux/module.h>
+
+#include <asm/prom.h>
+#include <asm/rtas.h>
+#include <asm/lmb.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/smp.h>
+#include <asm/system.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/pci.h>
+#include <asm/iommu.h>
+#include <asm/btext.h>
+#include <asm/sections.h>
+#include <asm/machdep.h>
+#include <asm/pSeries_reconfig.h>
+#include <asm/pci-bridge.h>
+#ifdef CONFIG_PPC64
+#include <asm/systemcfg.h>
+#endif
+
+#ifdef DEBUG
+#define DBG(fmt...) printk(KERN_ERR fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+struct pci_reg_property {
+ struct pci_address addr;
+ u32 size_hi;
+ u32 size_lo;
+};
+
+struct isa_reg_property {
+ u32 space;
+ u32 address;
+ u32 size;
+};
+
+
+typedef int interpret_func(struct device_node *, unsigned long *,
+ int, int, int);
+
+extern struct rtas_t rtas;
+extern struct lmb lmb;
+extern unsigned long klimit;
+
+static int __initdata dt_root_addr_cells;
+static int __initdata dt_root_size_cells;
+
+#ifdef CONFIG_PPC64
+static int __initdata iommu_is_off;
+int __initdata iommu_force_on;
+unsigned long tce_alloc_start, tce_alloc_end;
+#endif
+
+typedef u32 cell_t;
+
+#if 0
+static struct boot_param_header *initial_boot_params __initdata;
+#else
+struct boot_param_header *initial_boot_params;
+#endif
+
+static struct device_node *allnodes = NULL;
+
+/* use when traversing tree through the allnext, child, sibling,
+ * or parent members of struct device_node.
+ */
+static DEFINE_RWLOCK(devtree_lock);
+
+/* export that to outside world */
+struct device_node *of_chosen;
+
+struct device_node *dflt_interrupt_controller;
+int num_interrupt_controllers;
+
+/*
+ * Wrapper for allocating memory for various data that needs to be
+ * attached to device nodes as they are processed at boot or when
+ * added to the device tree later (e.g. DLPAR). At boot there is
+ * already a region reserved so we just increment *mem_start by size;
+ * otherwise we call kmalloc.
+ */
+static void * prom_alloc(unsigned long size, unsigned long *mem_start)
+{
+ unsigned long tmp;
+
+ if (!mem_start)
+ return kmalloc(size, GFP_KERNEL);
+
+ tmp = *mem_start;
+ *mem_start += size;
+ return (void *)tmp;
+}
+
+/*
+ * Find the device_node with a given phandle.
+ */
+static struct device_node * find_phandle(phandle ph)
+{
+ struct device_node *np;
+
+ for (np = allnodes; np != 0; np = np->allnext)
+ if (np->linux_phandle == ph)
+ return np;
+ return NULL;
+}
+
+/*
+ * Find the interrupt parent of a node.
+ */
+static struct device_node * __devinit intr_parent(struct device_node *p)
+{
+ phandle *parp;
+
+ parp = (phandle *) get_property(p, "interrupt-parent", NULL);
+ if (parp == NULL)
+ return p->parent;
+ p = find_phandle(*parp);
+ if (p != NULL)
+ return p;
+ /*
+ * On a powermac booted with BootX, we don't get to know the
+ * phandles for any nodes, so find_phandle will return NULL.
+ * Fortunately these machines only have one interrupt controller
+ * so there isn't in fact any ambiguity. -- paulus
+ */
+ if (num_interrupt_controllers == 1)
+ p = dflt_interrupt_controller;
+ return p;
+}
+
+/*
+ * Find out the size of each entry of the interrupts property
+ * for a node.
+ */
+int __devinit prom_n_intr_cells(struct device_node *np)
+{
+ struct device_node *p;
+ unsigned int *icp;
+
+ for (p = np; (p = intr_parent(p)) != NULL; ) {
+ icp = (unsigned int *)
+ get_property(p, "#interrupt-cells", NULL);
+ if (icp != NULL)
+ return *icp;
+ if (get_property(p, "interrupt-controller", NULL) != NULL
+ || get_property(p, "interrupt-map", NULL) != NULL) {
+ printk("oops, node %s doesn't have #interrupt-cells\n",
+ p->full_name);
+ return 1;
+ }
+ }
+#ifdef DEBUG_IRQ
+ printk("prom_n_intr_cells failed for %s\n", np->full_name);
+#endif
+ return 1;
+}
+
+/*
+ * Map an interrupt from a device up to the platform interrupt
+ * descriptor.
+ */
+static int __devinit map_interrupt(unsigned int **irq, struct device_node **ictrler,
+ struct device_node *np, unsigned int *ints,
+ int nintrc)
+{
+ struct device_node *p, *ipar;
+ unsigned int *imap, *imask, *ip;
+ int i, imaplen, match;
+ int newintrc = 0, newaddrc = 0;
+ unsigned int *reg;
+ int naddrc;
+
+ reg = (unsigned int *) get_property(np, "reg", NULL);
+ naddrc = prom_n_addr_cells(np);
+ p = intr_parent(np);
+ while (p != NULL) {
+ if (get_property(p, "interrupt-controller", NULL) != NULL)
+ /* this node is an interrupt controller, stop here */
+ break;
+ imap = (unsigned int *)
+ get_property(p, "interrupt-map", &imaplen);
+ if (imap == NULL) {
+ p = intr_parent(p);
+ continue;
+ }
+ imask = (unsigned int *)
+ get_property(p, "interrupt-map-mask", NULL);
+ if (imask == NULL) {
+ printk("oops, %s has interrupt-map but no mask\n",
+ p->full_name);
+ return 0;
+ }
+ imaplen /= sizeof(unsigned int);
+ match = 0;
+ ipar = NULL;
+ while (imaplen > 0 && !match) {
+ /* check the child-interrupt field */
+ match = 1;
+ for (i = 0; i < naddrc && match; ++i)
+ match = ((reg[i] ^ imap[i]) & imask[i]) == 0;
+ for (; i < naddrc + nintrc && match; ++i)
+ match = ((ints[i-naddrc] ^ imap[i]) & imask[i]) == 0;
+ imap += naddrc + nintrc;
+ imaplen -= naddrc + nintrc;
+ /* grab the interrupt parent */
+ ipar = find_phandle((phandle) *imap++);
+ --imaplen;
+ if (ipar == NULL && num_interrupt_controllers == 1)
+ /* cope with BootX not giving us phandles */
+ ipar = dflt_interrupt_controller;
+ if (ipar == NULL) {
+ printk("oops, no int parent %x in map of %s\n",
+ imap[-1], p->full_name);
+ return 0;
+ }
+ /* find the parent's # addr and intr cells */
+ ip = (unsigned int *)
+ get_property(ipar, "#interrupt-cells", NULL);
+ if (ip == NULL) {
+ printk("oops, no #interrupt-cells on %s\n",
+ ipar->full_name);
+ return 0;
+ }
+ newintrc = *ip;
+ ip = (unsigned int *)
+ get_property(ipar, "#address-cells", NULL);
+ newaddrc = (ip == NULL)? 0: *ip;
+ imap += newaddrc + newintrc;
+ imaplen -= newaddrc + newintrc;
+ }
+ if (imaplen < 0) {
+ printk("oops, error decoding int-map on %s, len=%d\n",
+ p->full_name, imaplen);
+ return 0;
+ }
+ if (!match) {
+#ifdef DEBUG_IRQ
+ printk("oops, no match in %s int-map for %s\n",
+ p->full_name, np->full_name);
+#endif
+ return 0;
+ }
+ p = ipar;
+ naddrc = newaddrc;
+ nintrc = newintrc;
+ ints = imap - nintrc;
+ reg = ints - naddrc;
+ }
+ if (p == NULL) {
+#ifdef DEBUG_IRQ
+ printk("hmmm, int tree for %s doesn't have ctrler\n",
+ np->full_name);
+#endif
+ return 0;
+ }
+ *irq = ints;
+ *ictrler = p;
+ return nintrc;
+}
+
+static unsigned char map_isa_senses[4] = {
+ IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE,
+ IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE,
+ IRQ_SENSE_EDGE | IRQ_POLARITY_NEGATIVE,
+ IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE
+};
+
+static unsigned char map_mpic_senses[4] = {
+ IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE,
+ IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE,
+ /* 2 seems to be used for the 8259 cascade... */
+ IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE,
+ IRQ_SENSE_EDGE | IRQ_POLARITY_NEGATIVE,
+};
+
+static int __devinit finish_node_interrupts(struct device_node *np,
+ unsigned long *mem_start,
+ int measure_only)
+{
+ unsigned int *ints;
+ int intlen, intrcells, intrcount;
+ int i, j, n, sense;
+ unsigned int *irq, virq;
+ struct device_node *ic;
+
+ if (num_interrupt_controllers == 0) {
+ /*
+ * Old machines just have a list of interrupt numbers
+ * and no interrupt-controller nodes.
+ */
+ ints = (unsigned int *) get_property(np, "AAPL,interrupts",
+ &intlen);
+ /* XXX old interpret_pci_props looked in parent too */
+ /* XXX old interpret_macio_props looked for interrupts
+ before AAPL,interrupts */
+ if (ints == NULL)
+ ints = (unsigned int *) get_property(np, "interrupts",
+ &intlen);
+ if (ints == NULL)
+ return 0;
+
+ np->n_intrs = intlen / sizeof(unsigned int);
+ np->intrs = prom_alloc(np->n_intrs * sizeof(np->intrs[0]),
+ mem_start);
+ if (!np->intrs)
+ return -ENOMEM;
+ if (measure_only)
+ return 0;
+
+ for (i = 0; i < np->n_intrs; ++i) {
+ np->intrs[i].line = *ints++;
+ np->intrs[i].sense = IRQ_SENSE_LEVEL
+ | IRQ_POLARITY_NEGATIVE;
+ }
+ return 0;
+ }
+
+ ints = (unsigned int *) get_property(np, "interrupts", &intlen);
+ if (ints == NULL)
+ return 0;
+ intrcells = prom_n_intr_cells(np);
+ intlen /= intrcells * sizeof(unsigned int);
+
+ np->intrs = prom_alloc(intlen * sizeof(*(np->intrs)), mem_start);
+ if (!np->intrs)
+ return -ENOMEM;
+
+ if (measure_only)
+ return 0;
+
+ intrcount = 0;
+ for (i = 0; i < intlen; ++i, ints += intrcells) {
+ n = map_interrupt(&irq, &ic, np, ints, intrcells);
+ if (n <= 0)
+ continue;
+
+ /* don't map IRQ numbers under a cascaded 8259 controller */
+ if (ic && device_is_compatible(ic, "chrp,iic")) {
+ np->intrs[intrcount].line = irq[0];
+ sense = (n > 1)? (irq[1] & 3): 3;
+ np->intrs[intrcount].sense = map_isa_senses[sense];
+ } else {
+ virq = virt_irq_create_mapping(irq[0]);
+#ifdef CONFIG_PPC64
+ if (virq == NO_IRQ) {
+ printk(KERN_CRIT "Could not allocate interrupt"
+ " number for %s\n", np->full_name);
+ continue;
+ }
+#endif
+ np->intrs[intrcount].line = irq_offset_up(virq);
+ sense = (n > 1)? (irq[1] & 3): 1;
+ np->intrs[intrcount].sense = map_mpic_senses[sense];
+ }
+
+#ifdef CONFIG_PPC64
+ /* We offset irq numbers for the u3 MPIC by 128 in PowerMac */
+ if (systemcfg->platform == PLATFORM_POWERMAC && ic && ic->parent) {
+ char *name = get_property(ic->parent, "name", NULL);
+ if (name && !strcmp(name, "u3"))
+ np->intrs[intrcount].line += 128;
+ else if (!(name && !strcmp(name, "mac-io")))
+ /* ignore other cascaded controllers, such as
+ the k2-sata-root */
+ break;
+ }
+#endif
+ if (n > 2) {
+ printk("hmmm, got %d intr cells for %s:", n,
+ np->full_name);
+ for (j = 0; j < n; ++j)
+ printk(" %d", irq[j]);
+ printk("\n");
+ }
+ ++intrcount;
+ }
+ np->n_intrs = intrcount;
+
+ return 0;
+}
+
+static int __devinit interpret_pci_props(struct device_node *np,
+ unsigned long *mem_start,
+ int naddrc, int nsizec,
+ int measure_only)
+{
+ struct address_range *adr;
+ struct pci_reg_property *pci_addrs;
+ int i, l, n_addrs;
+
+ pci_addrs = (struct pci_reg_property *)
+ get_property(np, "assigned-addresses", &l);
+ if (!pci_addrs)
+ return 0;
+
+ n_addrs = l / sizeof(*pci_addrs);
+
+ adr = prom_alloc(n_addrs * sizeof(*adr), mem_start);
+ if (!adr)
+ return -ENOMEM;
+
+ if (measure_only)
+ return 0;
+
+ np->addrs = adr;
+ np->n_addrs = n_addrs;
+
+ for (i = 0; i < n_addrs; i++) {
+ adr[i].space = pci_addrs[i].addr.a_hi;
+ adr[i].address = pci_addrs[i].addr.a_lo |
+ ((u64)pci_addrs[i].addr.a_mid << 32);
+ adr[i].size = pci_addrs[i].size_lo;
+ }
+
+ return 0;
+}
+
+static int __init interpret_dbdma_props(struct device_node *np,
+ unsigned long *mem_start,
+ int naddrc, int nsizec,
+ int measure_only)
+{
+ struct reg_property32 *rp;
+ struct address_range *adr;
+ unsigned long base_address;
+ int i, l;
+ struct device_node *db;
+
+ base_address = 0;
+ if (!measure_only) {
+ for (db = np->parent; db != NULL; db = db->parent) {
+ if (!strcmp(db->type, "dbdma") && db->n_addrs != 0) {
+ base_address = db->addrs[0].address;
+ break;
+ }
+ }
+ }
+
+ rp = (struct reg_property32 *) get_property(np, "reg", &l);
+ if (rp != 0 && l >= sizeof(struct reg_property32)) {
+ i = 0;
+ adr = (struct address_range *) (*mem_start);
+ while ((l -= sizeof(struct reg_property32)) >= 0) {
+ if (!measure_only) {
+ adr[i].space = 2;
+ adr[i].address = rp[i].address + base_address;
+ adr[i].size = rp[i].size;
+ }
+ ++i;
+ }
+ np->addrs = adr;
+ np->n_addrs = i;
+ (*mem_start) += i * sizeof(struct address_range);
+ }
+
+ return 0;
+}
+
+static int __init interpret_macio_props(struct device_node *np,
+ unsigned long *mem_start,
+ int naddrc, int nsizec,
+ int measure_only)
+{
+ struct reg_property32 *rp;
+ struct address_range *adr;
+ unsigned long base_address;
+ int i, l;
+ struct device_node *db;
+
+ base_address = 0;
+ if (!measure_only) {
+ for (db = np->parent; db != NULL; db = db->parent) {
+ if (!strcmp(db->type, "mac-io") && db->n_addrs != 0) {
+ base_address = db->addrs[0].address;
+ break;
+ }
+ }
+ }
+
+ rp = (struct reg_property32 *) get_property(np, "reg", &l);
+ if (rp != 0 && l >= sizeof(struct reg_property32)) {
+ i = 0;
+ adr = (struct address_range *) (*mem_start);
+ while ((l -= sizeof(struct reg_property32)) >= 0) {
+ if (!measure_only) {
+ adr[i].space = 2;
+ adr[i].address = rp[i].address + base_address;
+ adr[i].size = rp[i].size;
+ }
+ ++i;
+ }
+ np->addrs = adr;
+ np->n_addrs = i;
+ (*mem_start) += i * sizeof(struct address_range);
+ }
+
+ return 0;
+}
+
+static int __init interpret_isa_props(struct device_node *np,
+ unsigned long *mem_start,
+ int naddrc, int nsizec,
+ int measure_only)
+{
+ struct isa_reg_property *rp;
+ struct address_range *adr;
+ int i, l;
+
+ rp = (struct isa_reg_property *) get_property(np, "reg", &l);
+ if (rp != 0 && l >= sizeof(struct isa_reg_property)) {
+ i = 0;
+ adr = (struct address_range *) (*mem_start);
+ while ((l -= sizeof(struct isa_reg_property)) >= 0) {
+ if (!measure_only) {
+ adr[i].space = rp[i].space;
+ adr[i].address = rp[i].address;
+ adr[i].size = rp[i].size;
+ }
+ ++i;
+ }
+ np->addrs = adr;
+ np->n_addrs = i;
+ (*mem_start) += i * sizeof(struct address_range);
+ }
+
+ return 0;
+}
+
+static int __init interpret_root_props(struct device_node *np,
+ unsigned long *mem_start,
+ int naddrc, int nsizec,
+ int measure_only)
+{
+ struct address_range *adr;
+ int i, l;
+ unsigned int *rp;
+ int rpsize = (naddrc + nsizec) * sizeof(unsigned int);
+
+ rp = (unsigned int *) get_property(np, "reg", &l);
+ if (rp != 0 && l >= rpsize) {
+ i = 0;
+ adr = (struct address_range *) (*mem_start);
+ while ((l -= rpsize) >= 0) {
+ if (!measure_only) {
+ adr[i].space = 0;
+ adr[i].address = rp[naddrc - 1];
+ adr[i].size = rp[naddrc + nsizec - 1];
+ }
+ ++i;
+ rp += naddrc + nsizec;
+ }
+ np->addrs = adr;
+ np->n_addrs = i;
+ (*mem_start) += i * sizeof(struct address_range);
+ }
+
+ return 0;
+}
+
+static int __devinit finish_node(struct device_node *np,
+ unsigned long *mem_start,
+ interpret_func *ifunc,
+ int naddrc, int nsizec,
+ int measure_only)
+{
+ struct device_node *child;
+ int *ip, rc = 0;
+
+ /* get the device addresses and interrupts */
+ if (ifunc != NULL)
+ rc = ifunc(np, mem_start, naddrc, nsizec, measure_only);
+ if (rc)
+ goto out;
+
+ rc = finish_node_interrupts(np, mem_start, measure_only);
+ if (rc)
+ goto out;
+
+ /* Look for #address-cells and #size-cells properties. */
+ ip = (int *) get_property(np, "#address-cells", NULL);
+ if (ip != NULL)
+ naddrc = *ip;
+ ip = (int *) get_property(np, "#size-cells", NULL);
+ if (ip != NULL)
+ nsizec = *ip;
+
+ if (!strcmp(np->name, "device-tree") || np->parent == NULL)
+ ifunc = interpret_root_props;
+ else if (np->type == 0)
+ ifunc = NULL;
+ else if (!strcmp(np->type, "pci") || !strcmp(np->type, "vci"))
+ ifunc = interpret_pci_props;
+ else if (!strcmp(np->type, "dbdma"))
+ ifunc = interpret_dbdma_props;
+ else if (!strcmp(np->type, "mac-io") || ifunc == interpret_macio_props)
+ ifunc = interpret_macio_props;
+ else if (!strcmp(np->type, "isa"))
+ ifunc = interpret_isa_props;
+ else if (!strcmp(np->name, "uni-n") || !strcmp(np->name, "u3"))
+ ifunc = interpret_root_props;
+ else if (!((ifunc == interpret_dbdma_props
+ || ifunc == interpret_macio_props)
+ && (!strcmp(np->type, "escc")
+ || !strcmp(np->type, "media-bay"))))
+ ifunc = NULL;
+
+ for (child = np->child; child != NULL; child = child->sibling) {
+ rc = finish_node(child, mem_start, ifunc,
+ naddrc, nsizec, measure_only);
+ if (rc)
+ goto out;
+ }
+out:
+ return rc;
+}
+
+static void __init scan_interrupt_controllers(void)
+{
+ struct device_node *np;
+ int n = 0;
+ char *name, *ic;
+ int iclen;
+
+ for (np = allnodes; np != NULL; np = np->allnext) {
+ ic = get_property(np, "interrupt-controller", &iclen);
+ name = get_property(np, "name", NULL);
+ /* checking iclen makes sure we don't get a false
+ match on /chosen.interrupt_controller */
+ if ((name != NULL
+ && strcmp(name, "interrupt-controller") == 0)
+ || (ic != NULL && iclen == 0
+ && strcmp(name, "AppleKiwi"))) {
+ if (n == 0)
+ dflt_interrupt_controller = np;
+ ++n;
+ }
+ }
+ num_interrupt_controllers = n;
+}
+
+/**
+ * finish_device_tree is called once things are running normally
+ * (i.e. with text and data mapped to the address they were linked at).
+ * It traverses the device tree and fills in some of the additional,
+ * fields in each node like {n_}addrs and {n_}intrs, the virt interrupt
+ * mapping is also initialized at this point.
+ */
+void __init finish_device_tree(void)
+{
+ unsigned long start, end, size = 0;
+
+ DBG(" -> finish_device_tree\n");
+
+#ifdef CONFIG_PPC64
+ /* Initialize virtual IRQ map */
+ virt_irq_init();
+#endif
+ scan_interrupt_controllers();
+
+ /*
+ * Finish device-tree (pre-parsing some properties etc...)
+ * We do this in 2 passes. One with "measure_only" set, which
+ * will only measure the amount of memory needed, then we can
+ * allocate that memory, and call finish_node again. However,
+ * we must be careful as most routines will fail nowadays when
+ * prom_alloc() returns 0, so we must make sure our first pass
+ * doesn't start at 0. We pre-initialize size to 16 for that
+ * reason and then remove those additional 16 bytes
+ */
+ size = 16;
+ finish_node(allnodes, &size, NULL, 0, 0, 1);
+ size -= 16;
+ end = start = (unsigned long) __va(lmb_alloc(size, 128));
+ finish_node(allnodes, &end, NULL, 0, 0, 0);
+ BUG_ON(end != start + size);
+
+ DBG(" <- finish_device_tree\n");
+}
+
+static inline char *find_flat_dt_string(u32 offset)
+{
+ return ((char *)initial_boot_params) +
+ initial_boot_params->off_dt_strings + offset;
+}
+
+/**
+ * This function is used to scan the flattened device-tree, it is
+ * used to extract the memory informations at boot before we can
+ * unflatten the tree
+ */
+static int __init scan_flat_dt(int (*it)(unsigned long node,
+ const char *uname, int depth,
+ void *data),
+ void *data)
+{
+ unsigned long p = ((unsigned long)initial_boot_params) +
+ initial_boot_params->off_dt_struct;
+ int rc = 0;
+ int depth = -1;
+
+ do {
+ u32 tag = *((u32 *)p);
+ char *pathp;
+
+ p += 4;
+ if (tag == OF_DT_END_NODE) {
+ depth --;
+ continue;
+ }
+ if (tag == OF_DT_NOP)
+ continue;
+ if (tag == OF_DT_END)
+ break;
+ if (tag == OF_DT_PROP) {
+ u32 sz = *((u32 *)p);
+ p += 8;
+ if (initial_boot_params->version < 0x10)
+ p = _ALIGN(p, sz >= 8 ? 8 : 4);
+ p += sz;
+ p = _ALIGN(p, 4);
+ continue;
+ }
+ if (tag != OF_DT_BEGIN_NODE) {
+ printk(KERN_WARNING "Invalid tag %x scanning flattened"
+ " device tree !\n", tag);
+ return -EINVAL;
+ }
+ depth++;
+ pathp = (char *)p;
+ p = _ALIGN(p + strlen(pathp) + 1, 4);
+ if ((*pathp) == '/') {
+ char *lp, *np;
+ for (lp = NULL, np = pathp; *np; np++)
+ if ((*np) == '/')
+ lp = np+1;
+ if (lp != NULL)
+ pathp = lp;
+ }
+ rc = it(p, pathp, depth, data);
+ if (rc != 0)
+ break;
+ } while(1);
+
+ return rc;
+}
+
+/**
+ * This function can be used within scan_flattened_dt callback to get
+ * access to properties
+ */
+static void* __init get_flat_dt_prop(unsigned long node, const char *name,
+ unsigned long *size)
+{
+ unsigned long p = node;
+
+ do {
+ u32 tag = *((u32 *)p);
+ u32 sz, noff;
+ const char *nstr;
+
+ p += 4;
+ if (tag == OF_DT_NOP)
+ continue;
+ if (tag != OF_DT_PROP)
+ return NULL;
+
+ sz = *((u32 *)p);
+ noff = *((u32 *)(p + 4));
+ p += 8;
+ if (initial_boot_params->version < 0x10)
+ p = _ALIGN(p, sz >= 8 ? 8 : 4);
+
+ nstr = find_flat_dt_string(noff);
+ if (nstr == NULL) {
+ printk(KERN_WARNING "Can't find property index"
+ " name !\n");
+ return NULL;
+ }
+ if (strcmp(name, nstr) == 0) {
+ if (size)
+ *size = sz;
+ return (void *)p;
+ }
+ p += sz;
+ p = _ALIGN(p, 4);
+ } while(1);
+}
+
+static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
+ unsigned long align)
+{
+ void *res;
+
+ *mem = _ALIGN(*mem, align);
+ res = (void *)*mem;
+ *mem += size;
+
+ return res;
+}
+
+static unsigned long __init unflatten_dt_node(unsigned long mem,
+ unsigned long *p,
+ struct device_node *dad,
+ struct device_node ***allnextpp,
+ unsigned long fpsize)
+{
+ struct device_node *np;
+ struct property *pp, **prev_pp = NULL;
+ char *pathp;
+ u32 tag;
+ unsigned int l, allocl;
+ int has_name = 0;
+ int new_format = 0;
+
+ tag = *((u32 *)(*p));
+ if (tag != OF_DT_BEGIN_NODE) {
+ printk("Weird tag at start of node: %x\n", tag);
+ return mem;
+ }
+ *p += 4;
+ pathp = (char *)*p;
+ l = allocl = strlen(pathp) + 1;
+ *p = _ALIGN(*p + l, 4);
+
+ /* version 0x10 has a more compact unit name here instead of the full
+ * path. we accumulate the full path size using "fpsize", we'll rebuild
+ * it later. We detect this because the first character of the name is
+ * not '/'.
+ */
+ if ((*pathp) != '/') {
+ new_format = 1;
+ if (fpsize == 0) {
+ /* root node: special case. fpsize accounts for path
+ * plus terminating zero. root node only has '/', so
+ * fpsize should be 2, but we want to avoid the first
+ * level nodes to have two '/' so we use fpsize 1 here
+ */
+ fpsize = 1;
+ allocl = 2;
+ } else {
+ /* account for '/' and path size minus terminal 0
+ * already in 'l'
+ */
+ fpsize += l;
+ allocl = fpsize;
+ }
+ }
+
+
+ np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl,
+ __alignof__(struct device_node));
+ if (allnextpp) {
+ memset(np, 0, sizeof(*np));
+ np->full_name = ((char*)np) + sizeof(struct device_node);
+ if (new_format) {
+ char *p = np->full_name;
+ /* rebuild full path for new format */
+ if (dad && dad->parent) {
+ strcpy(p, dad->full_name);
+#ifdef DEBUG
+ if ((strlen(p) + l + 1) != allocl) {
+ DBG("%s: p: %d, l: %d, a: %d\n",
+ pathp, strlen(p), l, allocl);
+ }
+#endif
+ p += strlen(p);
+ }
+ *(p++) = '/';
+ memcpy(p, pathp, l);
+ } else
+ memcpy(np->full_name, pathp, l);
+ prev_pp = &np->properties;
+ **allnextpp = np;
+ *allnextpp = &np->allnext;
+ if (dad != NULL) {
+ np->parent = dad;
+ /* we temporarily use the next field as `last_child'*/
+ if (dad->next == 0)
+ dad->child = np;
+ else
+ dad->next->sibling = np;
+ dad->next = np;
+ }
+ kref_init(&np->kref);
+ }
+ while(1) {
+ u32 sz, noff;
+ char *pname;
+
+ tag = *((u32 *)(*p));
+ if (tag == OF_DT_NOP) {
+ *p += 4;
+ continue;
+ }
+ if (tag != OF_DT_PROP)
+ break;
+ *p += 4;
+ sz = *((u32 *)(*p));
+ noff = *((u32 *)((*p) + 4));
+ *p += 8;
+ if (initial_boot_params->version < 0x10)
+ *p = _ALIGN(*p, sz >= 8 ? 8 : 4);
+
+ pname = find_flat_dt_string(noff);
+ if (pname == NULL) {
+ printk("Can't find property name in list !\n");
+ break;
+ }
+ if (strcmp(pname, "name") == 0)
+ has_name = 1;
+ l = strlen(pname) + 1;
+ pp = unflatten_dt_alloc(&mem, sizeof(struct property),
+ __alignof__(struct property));
+ if (allnextpp) {
+ if (strcmp(pname, "linux,phandle") == 0) {
+ np->node = *((u32 *)*p);
+ if (np->linux_phandle == 0)
+ np->linux_phandle = np->node;
+ }
+ if (strcmp(pname, "ibm,phandle") == 0)
+ np->linux_phandle = *((u32 *)*p);
+ pp->name = pname;
+ pp->length = sz;
+ pp->value = (void *)*p;
+ *prev_pp = pp;
+ prev_pp = &pp->next;
+ }
+ *p = _ALIGN((*p) + sz, 4);
+ }
+ /* with version 0x10 we may not have the name property, recreate
+ * it here from the unit name if absent
+ */
+ if (!has_name) {
+ char *p = pathp, *ps = pathp, *pa = NULL;
+ int sz;
+
+ while (*p) {
+ if ((*p) == '@')
+ pa = p;
+ if ((*p) == '/')
+ ps = p + 1;
+ p++;
+ }
+ if (pa < ps)
+ pa = p;
+ sz = (pa - ps) + 1;
+ pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz,
+ __alignof__(struct property));
+ if (allnextpp) {
+ pp->name = "name";
+ pp->length = sz;
+ pp->value = (unsigned char *)(pp + 1);
+ *prev_pp = pp;
+ prev_pp = &pp->next;
+ memcpy(pp->value, ps, sz - 1);
+ ((char *)pp->value)[sz - 1] = 0;
+ DBG("fixed up name for %s -> %s\n", pathp, pp->value);
+ }
+ }
+ if (allnextpp) {
+ *prev_pp = NULL;
+ np->name = get_property(np, "name", NULL);
+ np->type = get_property(np, "device_type", NULL);
+
+ if (!np->name)
+ np->name = "<NULL>";
+ if (!np->type)
+ np->type = "<NULL>";
+ }
+ while (tag == OF_DT_BEGIN_NODE) {
+ mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
+ tag = *((u32 *)(*p));
+ }
+ if (tag != OF_DT_END_NODE) {
+ printk("Weird tag at end of node: %x\n", tag);
+ return mem;
+ }
+ *p += 4;
+ return mem;
+}
+
+
+/**
+ * unflattens the device-tree passed by the firmware, creating the
+ * tree of struct device_node. It also fills the "name" and "type"
+ * pointers of the nodes so the normal device-tree walking functions
+ * can be used (this used to be done by finish_device_tree)
+ */
+void __init unflatten_device_tree(void)
+{
+ unsigned long start, mem, size;
+ struct device_node **allnextp = &allnodes;
+ char *p = NULL;
+ int l = 0;
+
+ DBG(" -> unflatten_device_tree()\n");
+
+ /* First pass, scan for size */
+ start = ((unsigned long)initial_boot_params) +
+ initial_boot_params->off_dt_struct;
+ size = unflatten_dt_node(0, &start, NULL, NULL, 0);
+ size = (size | 3) + 1;
+
+ DBG(" size is %lx, allocating...\n", size);
+
+ /* Allocate memory for the expanded device tree */
+ mem = lmb_alloc(size + 4, __alignof__(struct device_node));
+ if (!mem) {
+ DBG("Couldn't allocate memory with lmb_alloc()!\n");
+ panic("Couldn't allocate memory with lmb_alloc()!\n");
+ }
+ mem = (unsigned long) __va(mem);
+
+ ((u32 *)mem)[size / 4] = 0xdeadbeef;
+
+ DBG(" unflattening %lx...\n", mem);
+
+ /* Second pass, do actual unflattening */
+ start = ((unsigned long)initial_boot_params) +
+ initial_boot_params->off_dt_struct;
+ unflatten_dt_node(mem, &start, NULL, &allnextp, 0);
+ if (*((u32 *)start) != OF_DT_END)
+ printk(KERN_WARNING "Weird tag at end of tree: %08x\n", *((u32 *)start));
+ if (((u32 *)mem)[size / 4] != 0xdeadbeef)
+ printk(KERN_WARNING "End of tree marker overwritten: %08x\n",
+ ((u32 *)mem)[size / 4] );
+ *allnextp = NULL;
+
+ /* Get pointer to OF "/chosen" node for use everywhere */
+ of_chosen = of_find_node_by_path("/chosen");
+ if (of_chosen == NULL)
+ of_chosen = of_find_node_by_path("/chosen@0");
+
+ /* Retreive command line */
+ if (of_chosen != NULL) {
+ p = (char *)get_property(of_chosen, "bootargs", &l);
+ if (p != NULL && l > 0)
+ strlcpy(cmd_line, p, min(l, COMMAND_LINE_SIZE));
+ }
+#ifdef CONFIG_CMDLINE
+ if (l == 0 || (l == 1 && (*p) == 0))
+ strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
+#endif /* CONFIG_CMDLINE */
+
+ DBG("Command line is: %s\n", cmd_line);
+
+ DBG(" <- unflatten_device_tree()\n");
+}
+
+
+static int __init early_init_dt_scan_cpus(unsigned long node,
+ const char *uname, int depth, void *data)
+{
+ char *type = get_flat_dt_prop(node, "device_type", NULL);
+ u32 *prop;
+ unsigned long size = 0;
+
+ /* We are scanning "cpu" nodes only */
+ if (type == NULL || strcmp(type, "cpu") != 0)
+ return 0;
+
+#ifdef CONFIG_PPC_PSERIES
+ /* On LPAR, look for the first ibm,pft-size property for the hash table size
+ */
+ if (systemcfg->platform == PLATFORM_PSERIES_LPAR && ppc64_pft_size == 0) {
+ u32 *pft_size;
+ pft_size = get_flat_dt_prop(node, "ibm,pft-size", NULL);
+ if (pft_size != NULL) {
+ /* pft_size[0] is the NUMA CEC cookie */
+ ppc64_pft_size = pft_size[1];
+ }
+ }
+#endif
+
+ boot_cpuid = 0;
+ boot_cpuid_phys = 0;
+ if (initial_boot_params && initial_boot_params->version >= 2) {
+ /* version 2 of the kexec param format adds the phys cpuid
+ * of booted proc.
+ */
+ boot_cpuid_phys = initial_boot_params->boot_cpuid_phys;
+ } else {
+ /* Check if it's the boot-cpu, set it's hw index now */
+ if (get_flat_dt_prop(node, "linux,boot-cpu", NULL) != NULL) {
+ prop = get_flat_dt_prop(node, "reg", NULL);
+ if (prop != NULL)
+ boot_cpuid_phys = *prop;
+ }
+ }
+ set_hard_smp_processor_id(0, boot_cpuid_phys);
+
+#ifdef CONFIG_ALTIVEC
+ /* Check if we have a VMX and eventually update CPU features */
+ prop = (u32 *)get_flat_dt_prop(node, "ibm,vmx", &size);
+ if (prop && (*prop) > 0) {
+ cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC;
+ cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC;
+ }
+
+ /* Same goes for Apple's "altivec" property */
+ prop = (u32 *)get_flat_dt_prop(node, "altivec", NULL);
+ if (prop) {
+ cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC;
+ cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC;
+ }
+#endif /* CONFIG_ALTIVEC */
+
+#ifdef CONFIG_PPC_PSERIES
+ /*
+ * Check for an SMT capable CPU and set the CPU feature. We do
+ * this by looking at the size of the ibm,ppc-interrupt-server#s
+ * property
+ */
+ prop = (u32 *)get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s",
+ &size);
+ cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT;
+ if (prop && ((size / sizeof(u32)) > 1))
+ cur_cpu_spec->cpu_features |= CPU_FTR_SMT;
+#endif
+
+ return 0;
+}
+
+static int __init early_init_dt_scan_chosen(unsigned long node,
+ const char *uname, int depth, void *data)
+{
+ u32 *prop;
+ unsigned long *lprop;
+
+ DBG("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
+
+ if (depth != 1 ||
+ (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0))
+ return 0;
+
+ /* get platform type */
+ prop = (u32 *)get_flat_dt_prop(node, "linux,platform", NULL);
+ if (prop == NULL)
+ return 0;
+#ifdef CONFIG_PPC64
+ systemcfg->platform = *prop;
+#else
+#ifdef CONFIG_PPC_MULTIPLATFORM
+ _machine = *prop;
+#endif
+#endif
+
+#ifdef CONFIG_PPC64
+ /* check if iommu is forced on or off */
+ if (get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL)
+ iommu_is_off = 1;
+ if (get_flat_dt_prop(node, "linux,iommu-force-on", NULL) != NULL)
+ iommu_force_on = 1;
+#endif
+
+ lprop = get_flat_dt_prop(node, "linux,memory-limit", NULL);
+ if (lprop)
+ memory_limit = *lprop;
+
+#ifdef CONFIG_PPC64
+ lprop = get_flat_dt_prop(node, "linux,tce-alloc-start", NULL);
+ if (lprop)
+ tce_alloc_start = *lprop;
+ lprop = get_flat_dt_prop(node, "linux,tce-alloc-end", NULL);
+ if (lprop)
+ tce_alloc_end = *lprop;
+#endif
+
+#ifdef CONFIG_PPC_RTAS
+ /* To help early debugging via the front panel, we retreive a minimal
+ * set of RTAS infos now if available
+ */
+ {
+ u64 *basep, *entryp;
+
+ basep = get_flat_dt_prop(node, "linux,rtas-base", NULL);
+ entryp = get_flat_dt_prop(node, "linux,rtas-entry", NULL);
+ prop = get_flat_dt_prop(node, "linux,rtas-size", NULL);
+ if (basep && entryp && prop) {
+ rtas.base = *basep;
+ rtas.entry = *entryp;
+ rtas.size = *prop;
+ }
+ }
+#endif /* CONFIG_PPC_RTAS */
+
+ /* break now */
+ return 1;
+}
+
+static int __init early_init_dt_scan_root(unsigned long node,
+ const char *uname, int depth, void *data)
+{
+ u32 *prop;
+
+ if (depth != 0)
+ return 0;
+
+ prop = get_flat_dt_prop(node, "#size-cells", NULL);
+ dt_root_size_cells = (prop == NULL) ? 1 : *prop;
+ DBG("dt_root_size_cells = %x\n", dt_root_size_cells);
+
+ prop = get_flat_dt_prop(node, "#address-cells", NULL);
+ dt_root_addr_cells = (prop == NULL) ? 2 : *prop;
+ DBG("dt_root_addr_cells = %x\n", dt_root_addr_cells);
+
+ /* break now */
+ return 1;
+}
+
+static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp)
+{
+ cell_t *p = *cellp;
+ unsigned long r;
+
+ /* Ignore more than 2 cells */
+ while (s > sizeof(unsigned long) / 4) {
+ p++;
+ s--;
+ }
+ r = *p++;
+#ifdef CONFIG_PPC64
+ if (s > 1) {
+ r <<= 32;
+ r |= *(p++);
+ s--;
+ }
+#endif
+
+ *cellp = p;
+ return r;
+}
+
+
+static int __init early_init_dt_scan_memory(unsigned long node,
+ const char *uname, int depth, void *data)
+{
+ char *type = get_flat_dt_prop(node, "device_type", NULL);
+ cell_t *reg, *endp;
+ unsigned long l;
+
+ /* We are scanning "memory" nodes only */
+ if (type == NULL || strcmp(type, "memory") != 0)
+ return 0;
+
+ reg = (cell_t *)get_flat_dt_prop(node, "reg", &l);
+ if (reg == NULL)
+ return 0;
+
+ endp = reg + (l / sizeof(cell_t));
+
+ DBG("memory scan node %s ..., reg size %ld, data: %x %x %x %x, ...\n",
+ uname, l, reg[0], reg[1], reg[2], reg[3]);
+
+ while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
+ unsigned long base, size;
+
+ base = dt_mem_next_cell(dt_root_addr_cells, &reg);
+ size = dt_mem_next_cell(dt_root_size_cells, &reg);
+
+ if (size == 0)
+ continue;
+ DBG(" - %lx , %lx\n", base, size);
+#ifdef CONFIG_PPC64
+ if (iommu_is_off) {
+ if (base >= 0x80000000ul)
+ continue;
+ if ((base + size) > 0x80000000ul)
+ size = 0x80000000ul - base;
+ }
+#endif
+ lmb_add(base, size);
+ }
+ return 0;
+}
+
+static void __init early_reserve_mem(void)
+{
+ unsigned long base, size;
+ unsigned long *reserve_map;
+
+ reserve_map = (unsigned long *)(((unsigned long)initial_boot_params) +
+ initial_boot_params->off_mem_rsvmap);
+ while (1) {
+ base = *(reserve_map++);
+ size = *(reserve_map++);
+ if (size == 0)
+ break;
+ DBG("reserving: %lx -> %lx\n", base, size);
+ lmb_reserve(base, size);
+ }
+
+#if 0
+ DBG("memory reserved, lmbs :\n");
+ lmb_dump_all();
+#endif
+}
+
+void __init early_init_devtree(void *params)
+{
+ DBG(" -> early_init_devtree()\n");
+
+ /* Setup flat device-tree pointer */
+ initial_boot_params = params;
+
+ /* Retrieve various informations from the /chosen node of the
+ * device-tree, including the platform type, initrd location and
+ * size, TCE reserve, and more ...
+ */
+ scan_flat_dt(early_init_dt_scan_chosen, NULL);
+
+ /* Scan memory nodes and rebuild LMBs */
+ lmb_init();
+ scan_flat_dt(early_init_dt_scan_root, NULL);
+ scan_flat_dt(early_init_dt_scan_memory, NULL);
+ lmb_enforce_memory_limit(memory_limit);
+ lmb_analyze();
+#ifdef CONFIG_PPC64
+ systemcfg->physicalMemorySize = lmb_phys_mem_size();
+#endif
+ lmb_reserve(0, __pa(klimit));
+
+ DBG("Phys. mem: %lx\n", lmb_phys_mem_size());
+
+ /* Reserve LMB regions used by kernel, initrd, dt, etc... */
+ early_reserve_mem();
+
+ DBG("Scanning CPUs ...\n");
+
+ /* Retreive hash table size from flattened tree plus other
+ * CPU related informations (altivec support, boot CPU ID, ...)
+ */
+ scan_flat_dt(early_init_dt_scan_cpus, NULL);
+
+ DBG(" <- early_init_devtree()\n");
+}
+
+#undef printk
+
+int
+prom_n_addr_cells(struct device_node* np)
+{
+ int* ip;
+ do {
+ if (np->parent)
+ np = np->parent;
+ ip = (int *) get_property(np, "#address-cells", NULL);
+ if (ip != NULL)
+ return *ip;
+ } while (np->parent);
+ /* No #address-cells property for the root node, default to 1 */
+ return 1;
+}
+
+int
+prom_n_size_cells(struct device_node* np)
+{
+ int* ip;
+ do {
+ if (np->parent)
+ np = np->parent;
+ ip = (int *) get_property(np, "#size-cells", NULL);
+ if (ip != NULL)
+ return *ip;
+ } while (np->parent);
+ /* No #size-cells property for the root node, default to 1 */
+ return 1;
+}
+
+/**
+ * Work out the sense (active-low level / active-high edge)
+ * of each interrupt from the device tree.
+ */
+void __init prom_get_irq_senses(unsigned char *senses, int off, int max)
+{
+ struct device_node *np;
+ int i, j;
+
+ /* default to level-triggered */
+ memset(senses, IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE, max - off);
+
+ for (np = allnodes; np != 0; np = np->allnext) {
+ for (j = 0; j < np->n_intrs; j++) {
+ i = np->intrs[j].line;
+ if (i >= off && i < max)
+ senses[i-off] = np->intrs[j].sense;
+ }
+ }
+}
+
+/**
+ * Construct and return a list of the device_nodes with a given name.
+ */
+struct device_node *find_devices(const char *name)
+{
+ struct device_node *head, **prevp, *np;
+
+ prevp = &head;
+ for (np = allnodes; np != 0; np = np->allnext) {
+ if (np->name != 0 && strcasecmp(np->name, name) == 0) {
+ *prevp = np;
+ prevp = &np->next;
+ }
+ }
+ *prevp = NULL;
+ return head;
+}
+EXPORT_SYMBOL(find_devices);
+
+/**
+ * Construct and return a list of the device_nodes with a given type.
+ */
+struct device_node *find_type_devices(const char *type)
+{
+ struct device_node *head, **prevp, *np;
+
+ prevp = &head;
+ for (np = allnodes; np != 0; np = np->allnext) {
+ if (np->type != 0 && strcasecmp(np->type, type) == 0) {
+ *prevp = np;
+ prevp = &np->next;
+ }
+ }
+ *prevp = NULL;
+ return head;
+}
+EXPORT_SYMBOL(find_type_devices);
+
+/**
+ * Returns all nodes linked together
+ */
+struct device_node *find_all_nodes(void)
+{
+ struct device_node *head, **prevp, *np;
+
+ prevp = &head;
+ for (np = allnodes; np != 0; np = np->allnext) {
+ *prevp = np;
+ prevp = &np->next;
+ }
+ *prevp = NULL;
+ return head;
+}
+EXPORT_SYMBOL(find_all_nodes);
+
+/** Checks if the given "compat" string matches one of the strings in
+ * the device's "compatible" property
+ */
+int device_is_compatible(struct device_node *device, const char *compat)
+{
+ const char* cp;
+ int cplen, l;
+
+ cp = (char *) get_property(device, "compatible", &cplen);
+ if (cp == NULL)
+ return 0;
+ while (cplen > 0) {
+ if (strncasecmp(cp, compat, strlen(compat)) == 0)
+ return 1;
+ l = strlen(cp) + 1;
+ cp += l;
+ cplen -= l;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(device_is_compatible);
+
+
+/**
+ * Indicates whether the root node has a given value in its
+ * compatible property.
+ */
+int machine_is_compatible(const char *compat)
+{
+ struct device_node *root;
+ int rc = 0;
+
+ root = of_find_node_by_path("/");
+ if (root) {
+ rc = device_is_compatible(root, compat);
+ of_node_put(root);
+ }
+ return rc;
+}
+EXPORT_SYMBOL(machine_is_compatible);
+
+/**
+ * Construct and return a list of the device_nodes with a given type
+ * and compatible property.
+ */
+struct device_node *find_compatible_devices(const char *type,
+ const char *compat)
+{
+ struct device_node *head, **prevp, *np;
+
+ prevp = &head;
+ for (np = allnodes; np != 0; np = np->allnext) {
+ if (type != NULL
+ && !(np->type != 0 && strcasecmp(np->type, type) == 0))
+ continue;
+ if (device_is_compatible(np, compat)) {
+ *prevp = np;
+ prevp = &np->next;
+ }
+ }
+ *prevp = NULL;
+ return head;
+}
+EXPORT_SYMBOL(find_compatible_devices);
+
+/**
+ * Find the device_node with a given full_name.
+ */
+struct device_node *find_path_device(const char *path)
+{
+ struct device_node *np;
+
+ for (np = allnodes; np != 0; np = np->allnext)
+ if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0)
+ return np;
+ return NULL;
+}
+EXPORT_SYMBOL(find_path_device);
+
+/*******
+ *
+ * New implementation of the OF "find" APIs, return a refcounted
+ * object, call of_node_put() when done. The device tree and list
+ * are protected by a rw_lock.
+ *
+ * Note that property management will need some locking as well,
+ * this isn't dealt with yet.
+ *
+ *******/
+
+/**
+ * of_find_node_by_name - Find a node by its "name" property
+ * @from: The node to start searching from or NULL, the node
+ * you pass will not be searched, only the next one
+ * will; typically, you pass what the previous call
+ * returned. of_node_put() will be called on it
+ * @name: The name string to match against
+ *
+ * Returns a node pointer with refcount incremented, use
+ * of_node_put() on it when done.
+ */
+struct device_node *of_find_node_by_name(struct device_node *from,
+ const char *name)
+{
+ struct device_node *np;
+
+ read_lock(&devtree_lock);
+ np = from ? from->allnext : allnodes;
+ for (; np != 0; np = np->allnext)
+ if (np->name != 0 && strcasecmp(np->name, name) == 0
+ && of_node_get(np))
+ break;
+ if (from)
+ of_node_put(from);
+ read_unlock(&devtree_lock);
+ return np;
+}
+EXPORT_SYMBOL(of_find_node_by_name);
+
+/**
+ * of_find_node_by_type - Find a node by its "device_type" property
+ * @from: The node to start searching from or NULL, the node
+ * you pass will not be searched, only the next one
+ * will; typically, you pass what the previous call
+ * returned. of_node_put() will be called on it
+ * @name: The type string to match against
+ *
+ * Returns a node pointer with refcount incremented, use
+ * of_node_put() on it when done.
+ */
+struct device_node *of_find_node_by_type(struct device_node *from,
+ const char *type)
+{
+ struct device_node *np;
+
+ read_lock(&devtree_lock);
+ np = from ? from->allnext : allnodes;
+ for (; np != 0; np = np->allnext)
+ if (np->type != 0 && strcasecmp(np->type, type) == 0
+ && of_node_get(np))
+ break;
+ if (from)
+ of_node_put(from);
+ read_unlock(&devtree_lock);
+ return np;
+}
+EXPORT_SYMBOL(of_find_node_by_type);
+
+/**
+ * of_find_compatible_node - Find a node based on type and one of the
+ * tokens in its "compatible" property
+ * @from: The node to start searching from or NULL, the node
+ * you pass will not be searched, only the next one
+ * will; typically, you pass what the previous call
+ * returned. of_node_put() will be called on it
+ * @type: The type string to match "device_type" or NULL to ignore
+ * @compatible: The string to match to one of the tokens in the device
+ * "compatible" list.
+ *
+ * Returns a node pointer with refcount incremented, use
+ * of_node_put() on it when done.
+ */
+struct device_node *of_find_compatible_node(struct device_node *from,
+ const char *type, const char *compatible)
+{
+ struct device_node *np;
+
+ read_lock(&devtree_lock);
+ np = from ? from->allnext : allnodes;
+ for (; np != 0; np = np->allnext) {
+ if (type != NULL
+ && !(np->type != 0 && strcasecmp(np->type, type) == 0))
+ continue;
+ if (device_is_compatible(np, compatible) && of_node_get(np))
+ break;
+ }
+ if (from)
+ of_node_put(from);
+ read_unlock(&devtree_lock);
+ return np;
+}
+EXPORT_SYMBOL(of_find_compatible_node);
+
+/**
+ * of_find_node_by_path - Find a node matching a full OF path
+ * @path: The full path to match
+ *
+ * Returns a node pointer with refcount incremented, use
+ * of_node_put() on it when done.
+ */
+struct device_node *of_find_node_by_path(const char *path)
+{
+ struct device_node *np = allnodes;
+
+ read_lock(&devtree_lock);
+ for (; np != 0; np = np->allnext) {
+ if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0
+ && of_node_get(np))
+ break;
+ }
+ read_unlock(&devtree_lock);
+ return np;
+}
+EXPORT_SYMBOL(of_find_node_by_path);
+
+/**
+ * of_find_node_by_phandle - Find a node given a phandle
+ * @handle: phandle of the node to find
+ *
+ * Returns a node pointer with refcount incremented, use
+ * of_node_put() on it when done.
+ */
+struct device_node *of_find_node_by_phandle(phandle handle)
+{
+ struct device_node *np;
+
+ read_lock(&devtree_lock);
+ for (np = allnodes; np != 0; np = np->allnext)
+ if (np->linux_phandle == handle)
+ break;
+ if (np)
+ of_node_get(np);
+ read_unlock(&devtree_lock);
+ return np;
+}
+EXPORT_SYMBOL(of_find_node_by_phandle);
+
+/**
+ * of_find_all_nodes - Get next node in global list
+ * @prev: Previous node or NULL to start iteration
+ * of_node_put() will be called on it
+ *
+ * Returns a node pointer with refcount incremented, use
+ * of_node_put() on it when done.
+ */
+struct device_node *of_find_all_nodes(struct device_node *prev)
+{
+ struct device_node *np;
+
+ read_lock(&devtree_lock);
+ np = prev ? prev->allnext : allnodes;
+ for (; np != 0; np = np->allnext)
+ if (of_node_get(np))
+ break;
+ if (prev)
+ of_node_put(prev);
+ read_unlock(&devtree_lock);
+ return np;
+}
+EXPORT_SYMBOL(of_find_all_nodes);
+
+/**
+ * of_get_parent - Get a node's parent if any
+ * @node: Node to get parent
+ *
+ * Returns a node pointer with refcount incremented, use
+ * of_node_put() on it when done.
+ */
+struct device_node *of_get_parent(const struct device_node *node)
+{
+ struct device_node *np;
+
+ if (!node)
+ return NULL;
+
+ read_lock(&devtree_lock);
+ np = of_node_get(node->parent);
+ read_unlock(&devtree_lock);
+ return np;
+}
+EXPORT_SYMBOL(of_get_parent);
+
+/**
+ * of_get_next_child - Iterate a node childs
+ * @node: parent node
+ * @prev: previous child of the parent node, or NULL to get first
+ *
+ * Returns a node pointer with refcount incremented, use
+ * of_node_put() on it when done.
+ */
+struct device_node *of_get_next_child(const struct device_node *node,
+ struct device_node *prev)
+{
+ struct device_node *next;
+
+ read_lock(&devtree_lock);
+ next = prev ? prev->sibling : node->child;
+ for (; next != 0; next = next->sibling)
+ if (of_node_get(next))
+ break;
+ if (prev)
+ of_node_put(prev);
+ read_unlock(&devtree_lock);
+ return next;
+}
+EXPORT_SYMBOL(of_get_next_child);
+
+/**
+ * of_node_get - Increment refcount of a node
+ * @node: Node to inc refcount, NULL is supported to
+ * simplify writing of callers
+ *
+ * Returns node.
+ */
+struct device_node *of_node_get(struct device_node *node)
+{
+ if (node)
+ kref_get(&node->kref);
+ return node;
+}
+EXPORT_SYMBOL(of_node_get);
+
+static inline struct device_node * kref_to_device_node(struct kref *kref)
+{
+ return container_of(kref, struct device_node, kref);
+}
+
+/**
+ * of_node_release - release a dynamically allocated node
+ * @kref: kref element of the node to be released
+ *
+ * In of_node_put() this function is passed to kref_put()
+ * as the destructor.
+ */
+static void of_node_release(struct kref *kref)
+{
+ struct device_node *node = kref_to_device_node(kref);
+ struct property *prop = node->properties;
+
+ if (!OF_IS_DYNAMIC(node))
+ return;
+ while (prop) {
+ struct property *next = prop->next;
+ kfree(prop->name);
+ kfree(prop->value);
+ kfree(prop);
+ prop = next;
+ }
+ kfree(node->intrs);
+ kfree(node->addrs);
+ kfree(node->full_name);
+ kfree(node->data);
+ kfree(node);
+}
+
+/**
+ * of_node_put - Decrement refcount of a node
+ * @node: Node to dec refcount, NULL is supported to
+ * simplify writing of callers
+ *
+ */
+void of_node_put(struct device_node *node)
+{
+ if (node)
+ kref_put(&node->kref, of_node_release);
+}
+EXPORT_SYMBOL(of_node_put);
+
+/*
+ * Plug a device node into the tree and global list.
+ */
+void of_attach_node(struct device_node *np)
+{
+ write_lock(&devtree_lock);
+ np->sibling = np->parent->child;
+ np->allnext = allnodes;
+ np->parent->child = np;
+ allnodes = np;
+ write_unlock(&devtree_lock);
+}
+
+/*
+ * "Unplug" a node from the device tree. The caller must hold
+ * a reference to the node. The memory associated with the node
+ * is not freed until its refcount goes to zero.
+ */
+void of_detach_node(const struct device_node *np)
+{
+ struct device_node *parent;
+
+ write_lock(&devtree_lock);
+
+ parent = np->parent;
+
+ if (allnodes == np)
+ allnodes = np->allnext;
+ else {
+ struct device_node *prev;
+ for (prev = allnodes;
+ prev->allnext != np;
+ prev = prev->allnext)
+ ;
+ prev->allnext = np->allnext;
+ }
+
+ if (parent->child == np)
+ parent->child = np->sibling;
+ else {
+ struct device_node *prevsib;
+ for (prevsib = np->parent->child;
+ prevsib->sibling != np;
+ prevsib = prevsib->sibling)
+ ;
+ prevsib->sibling = np->sibling;
+ }
+
+ write_unlock(&devtree_lock);
+}
+
+#ifdef CONFIG_PPC_PSERIES
+/*
+ * Fix up the uninitialized fields in a new device node:
+ * name, type, n_addrs, addrs, n_intrs, intrs, and pci-specific fields
+ *
+ * A lot of boot-time code is duplicated here, because functions such
+ * as finish_node_interrupts, interpret_pci_props, etc. cannot use the
+ * slab allocator.
+ *
+ * This should probably be split up into smaller chunks.
+ */
+
+static int of_finish_dynamic_node(struct device_node *node,
+ unsigned long *unused1, int unused2,
+ int unused3, int unused4)
+{
+ struct device_node *parent = of_get_parent(node);
+ int err = 0;
+ phandle *ibm_phandle;
+
+ node->name = get_property(node, "name", NULL);
+ node->type = get_property(node, "device_type", NULL);
+
+ if (!parent) {
+ err = -ENODEV;
+ goto out;
+ }
+
+ /* We don't support that function on PowerMac, at least
+ * not yet
+ */
+ if (systemcfg->platform == PLATFORM_POWERMAC)
+ return -ENODEV;
+
+ /* fix up new node's linux_phandle field */
+ if ((ibm_phandle = (unsigned int *)get_property(node, "ibm,phandle", NULL)))
+ node->linux_phandle = *ibm_phandle;
+
+out:
+ of_node_put(parent);
+ return err;
+}
+
+static int prom_reconfig_notifier(struct notifier_block *nb,
+ unsigned long action, void *node)
+{
+ int err;
+
+ switch (action) {
+ case PSERIES_RECONFIG_ADD:
+ err = finish_node(node, NULL, of_finish_dynamic_node, 0, 0, 0);
+ if (err < 0) {
+ printk(KERN_ERR "finish_node returned %d\n", err);
+ err = NOTIFY_BAD;
+ }
+ break;
+ default:
+ err = NOTIFY_DONE;
+ break;
+ }
+ return err;
+}
+
+static struct notifier_block prom_reconfig_nb = {
+ .notifier_call = prom_reconfig_notifier,
+ .priority = 10, /* This one needs to run first */
+};
+
+static int __init prom_reconfig_setup(void)
+{
+ return pSeries_reconfig_notifier_register(&prom_reconfig_nb);
+}
+__initcall(prom_reconfig_setup);
+#endif
+
+/*
+ * Find a property with a given name for a given node
+ * and return the value.
+ */
+unsigned char *get_property(struct device_node *np, const char *name,
+ int *lenp)
+{
+ struct property *pp;
+
+ for (pp = np->properties; pp != 0; pp = pp->next)
+ if (strcmp(pp->name, name) == 0) {
+ if (lenp != 0)
+ *lenp = pp->length;
+ return pp->value;
+ }
+ return NULL;
+}
+EXPORT_SYMBOL(get_property);
+
+/*
+ * Add a property to a node
+ */
+void prom_add_property(struct device_node* np, struct property* prop)
+{
+ struct property **next = &np->properties;
+
+ prop->next = NULL;
+ while (*next)
+ next = &(*next)->next;
+ *next = prop;
+}
+
+/* I quickly hacked that one, check against spec ! */
+static inline unsigned long
+bus_space_to_resource_flags(unsigned int bus_space)
+{
+ u8 space = (bus_space >> 24) & 0xf;
+ if (space == 0)
+ space = 0x02;
+ if (space == 0x02)
+ return IORESOURCE_MEM;
+ else if (space == 0x01)
+ return IORESOURCE_IO;
+ else {
+ printk(KERN_WARNING "prom.c: bus_space_to_resource_flags(), space: %x\n",
+ bus_space);
+ return 0;
+ }
+}
+
+#ifdef CONFIG_PCI
+static struct resource *find_parent_pci_resource(struct pci_dev* pdev,
+ struct address_range *range)
+{
+ unsigned long mask;
+ int i;
+
+ /* Check this one */
+ mask = bus_space_to_resource_flags(range->space);
+ for (i=0; i<DEVICE_COUNT_RESOURCE; i++) {
+ if ((pdev->resource[i].flags & mask) == mask &&
+ pdev->resource[i].start <= range->address &&
+ pdev->resource[i].end > range->address) {
+ if ((range->address + range->size - 1) > pdev->resource[i].end) {
+ /* Add better message */
+ printk(KERN_WARNING "PCI/OF resource overlap !\n");
+ return NULL;
+ }
+ break;
+ }
+ }
+ if (i == DEVICE_COUNT_RESOURCE)
+ return NULL;
+ return &pdev->resource[i];
+}
+
+/*
+ * Request an OF device resource. Currently handles child of PCI devices,
+ * or other nodes attached to the root node. Ultimately, put some
+ * link to resources in the OF node.
+ */
+struct resource *request_OF_resource(struct device_node* node, int index,
+ const char* name_postfix)
+{
+ struct pci_dev* pcidev;
+ u8 pci_bus, pci_devfn;
+ unsigned long iomask;
+ struct device_node* nd;
+ struct resource* parent;
+ struct resource *res = NULL;
+ int nlen, plen;
+
+ if (index >= node->n_addrs)
+ goto fail;
+
+ /* Sanity check on bus space */
+ iomask = bus_space_to_resource_flags(node->addrs[index].space);
+ if (iomask & IORESOURCE_MEM)
+ parent = &iomem_resource;
+ else if (iomask & IORESOURCE_IO)
+ parent = &ioport_resource;
+ else
+ goto fail;
+
+ /* Find a PCI parent if any */
+ nd = node;
+ pcidev = NULL;
+ while (nd) {
+ if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn))
+ pcidev = pci_find_slot(pci_bus, pci_devfn);
+ if (pcidev) break;
+ nd = nd->parent;
+ }
+ if (pcidev)
+ parent = find_parent_pci_resource(pcidev, &node->addrs[index]);
+ if (!parent) {
+ printk(KERN_WARNING "request_OF_resource(%s), parent not found\n",
+ node->name);
+ goto fail;
+ }
+
+ res = __request_region(parent, node->addrs[index].address,
+ node->addrs[index].size, NULL);
+ if (!res)
+ goto fail;
+ nlen = strlen(node->name);
+ plen = name_postfix ? strlen(name_postfix) : 0;
+ res->name = (const char *)kmalloc(nlen+plen+1, GFP_KERNEL);
+ if (res->name) {
+ strcpy((char *)res->name, node->name);
+ if (plen)
+ strcpy((char *)res->name+nlen, name_postfix);
+ }
+ return res;
+fail:
+ return NULL;
+}
+EXPORT_SYMBOL(request_OF_resource);
+
+int release_OF_resource(struct device_node *node, int index)
+{
+ struct pci_dev* pcidev;
+ u8 pci_bus, pci_devfn;
+ unsigned long iomask, start, end;
+ struct device_node* nd;
+ struct resource* parent;
+ struct resource *res = NULL;
+
+ if (index >= node->n_addrs)
+ return -EINVAL;
+
+ /* Sanity check on bus space */
+ iomask = bus_space_to_resource_flags(node->addrs[index].space);
+ if (iomask & IORESOURCE_MEM)
+ parent = &iomem_resource;
+ else if (iomask & IORESOURCE_IO)
+ parent = &ioport_resource;
+ else
+ return -EINVAL;
+
+ /* Find a PCI parent if any */
+ nd = node;
+ pcidev = NULL;
+ while(nd) {
+ if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn))
+ pcidev = pci_find_slot(pci_bus, pci_devfn);
+ if (pcidev) break;
+ nd = nd->parent;
+ }
+ if (pcidev)
+ parent = find_parent_pci_resource(pcidev, &node->addrs[index]);
+ if (!parent) {
+ printk(KERN_WARNING "release_OF_resource(%s), parent not found\n",
+ node->name);
+ return -ENODEV;
+ }
+
+ /* Find us in the parent and its childs */
+ res = parent->child;
+ start = node->addrs[index].address;
+ end = start + node->addrs[index].size - 1;
+ while (res) {
+ if (res->start == start && res->end == end &&
+ (res->flags & IORESOURCE_BUSY))
+ break;
+ if (res->start <= start && res->end >= end)
+ res = res->child;
+ else
+ res = res->sibling;
+ }
+ if (!res)
+ return -ENODEV;
+
+ if (res->name) {
+ kfree(res->name);
+ res->name = NULL;
+ }
+ release_resource(res);
+ kfree(res);
+
+ return 0;
+}
+EXPORT_SYMBOL(release_OF_resource);
+#endif /* CONFIG_PCI */
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
new file mode 100644
index 000000000000..9750b3cd8ecd
--- /dev/null
+++ b/arch/powerpc/kernel/prom_init.c
@@ -0,0 +1,2109 @@
+/*
+ * Procedures for interfacing to Open Firmware.
+ *
+ * Paul Mackerras August 1996.
+ * Copyright (C) 1996-2005 Paul Mackerras.
+ *
+ * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
+ * {engebret|bergner}@us.ibm.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.
+ */
+
+#undef DEBUG_PROM
+
+#include <stdarg.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/threads.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/proc_fs.h>
+#include <linux/stringify.h>
+#include <linux/delay.h>
+#include <linux/initrd.h>
+#include <linux/bitops.h>
+#include <asm/prom.h>
+#include <asm/rtas.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/smp.h>
+#include <asm/system.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/pci.h>
+#include <asm/iommu.h>
+#include <asm/btext.h>
+#include <asm/sections.h>
+#include <asm/machdep.h>
+
+#ifdef CONFIG_LOGO_LINUX_CLUT224
+#include <linux/linux_logo.h>
+extern const struct linux_logo logo_linux_clut224;
+#endif
+
+/*
+ * Properties whose value is longer than this get excluded from our
+ * copy of the device tree. This value does need to be big enough to
+ * ensure that we don't lose things like the interrupt-map property
+ * on a PCI-PCI bridge.
+ */
+#define MAX_PROPERTY_LENGTH (1UL * 1024 * 1024)
+
+/*
+ * Eventually bump that one up
+ */
+#define DEVTREE_CHUNK_SIZE 0x100000
+
+/*
+ * This is the size of the local memory reserve map that gets copied
+ * into the boot params passed to the kernel. That size is totally
+ * flexible as the kernel just reads the list until it encounters an
+ * entry with size 0, so it can be changed without breaking binary
+ * compatibility
+ */
+#define MEM_RESERVE_MAP_SIZE 8
+
+/*
+ * prom_init() is called very early on, before the kernel text
+ * and data have been mapped to KERNELBASE. At this point the code
+ * is running at whatever address it has been loaded at.
+ * On ppc32 we compile with -mrelocatable, which means that references
+ * to extern and static variables get relocated automatically.
+ * On ppc64 we have to relocate the references explicitly with
+ * RELOC. (Note that strings count as static variables.)
+ *
+ * Because OF may have mapped I/O devices into the area starting at
+ * KERNELBASE, particularly on CHRP machines, we can't safely call
+ * OF once the kernel has been mapped to KERNELBASE. Therefore all
+ * OF calls must be done within prom_init().
+ *
+ * ADDR is used in calls to call_prom. The 4th and following
+ * arguments to call_prom should be 32-bit values.
+ * On ppc64, 64 bit values are truncated to 32 bits (and
+ * fortunately don't get interpreted as two arguments).
+ */
+#ifdef CONFIG_PPC64
+#define RELOC(x) (*PTRRELOC(&(x)))
+#define ADDR(x) (u32) add_reloc_offset((unsigned long)(x))
+#else
+#define RELOC(x) (x)
+#define ADDR(x) (u32) (x)
+#endif
+
+#define PROM_BUG() do { \
+ prom_printf("kernel BUG at %s line 0x%x!\n", \
+ RELOC(__FILE__), __LINE__); \
+ __asm__ __volatile__(".long " BUG_ILLEGAL_INSTR); \
+} while (0)
+
+#ifdef DEBUG_PROM
+#define prom_debug(x...) prom_printf(x)
+#else
+#define prom_debug(x...)
+#endif
+
+#ifdef CONFIG_PPC32
+#define PLATFORM_POWERMAC _MACH_Pmac
+#define PLATFORM_CHRP _MACH_chrp
+#endif
+
+
+typedef u32 prom_arg_t;
+
+struct prom_args {
+ u32 service;
+ u32 nargs;
+ u32 nret;
+ prom_arg_t args[10];
+};
+
+struct prom_t {
+ ihandle root;
+ ihandle chosen;
+ int cpu;
+ ihandle stdout;
+ ihandle mmumap;
+};
+
+struct mem_map_entry {
+ unsigned long base;
+ unsigned long size;
+};
+
+typedef u32 cell_t;
+
+extern void __start(unsigned long r3, unsigned long r4, unsigned long r5);
+
+#ifdef CONFIG_PPC64
+extern int enter_prom(struct prom_args *args, unsigned long entry);
+#else
+static inline int enter_prom(struct prom_args *args, unsigned long entry)
+{
+ return ((int (*)(struct prom_args *))entry)(args);
+}
+#endif
+
+extern void copy_and_flush(unsigned long dest, unsigned long src,
+ unsigned long size, unsigned long offset);
+
+/* prom structure */
+static struct prom_t __initdata prom;
+
+static unsigned long prom_entry __initdata;
+
+#define PROM_SCRATCH_SIZE 256
+
+static char __initdata of_stdout_device[256];
+static char __initdata prom_scratch[PROM_SCRATCH_SIZE];
+
+static unsigned long __initdata dt_header_start;
+static unsigned long __initdata dt_struct_start, dt_struct_end;
+static unsigned long __initdata dt_string_start, dt_string_end;
+
+static unsigned long __initdata prom_initrd_start, prom_initrd_end;
+
+#ifdef CONFIG_PPC64
+static int __initdata iommu_force_on;
+static int __initdata ppc64_iommu_off;
+static unsigned long __initdata prom_tce_alloc_start;
+static unsigned long __initdata prom_tce_alloc_end;
+#endif
+
+static int __initdata of_platform;
+
+static char __initdata prom_cmd_line[COMMAND_LINE_SIZE];
+
+static unsigned long __initdata prom_memory_limit;
+
+static unsigned long __initdata alloc_top;
+static unsigned long __initdata alloc_top_high;
+static unsigned long __initdata alloc_bottom;
+static unsigned long __initdata rmo_top;
+static unsigned long __initdata ram_top;
+
+static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE];
+static int __initdata mem_reserve_cnt;
+
+static cell_t __initdata regbuf[1024];
+
+
+#define MAX_CPU_THREADS 2
+
+/* TO GO */
+#ifdef CONFIG_HMT
+struct {
+ unsigned int pir;
+ unsigned int threadid;
+} hmt_thread_data[NR_CPUS];
+#endif /* CONFIG_HMT */
+
+/*
+ * Error results ... some OF calls will return "-1" on error, some
+ * will return 0, some will return either. To simplify, here are
+ * macros to use with any ihandle or phandle return value to check if
+ * it is valid
+ */
+
+#define PROM_ERROR (-1u)
+#define PHANDLE_VALID(p) ((p) != 0 && (p) != PROM_ERROR)
+#define IHANDLE_VALID(i) ((i) != 0 && (i) != PROM_ERROR)
+
+
+/* This is the one and *ONLY* place where we actually call open
+ * firmware.
+ */
+
+static int __init call_prom(const char *service, int nargs, int nret, ...)
+{
+ int i;
+ struct prom_args args;
+ va_list list;
+
+ args.service = ADDR(service);
+ args.nargs = nargs;
+ args.nret = nret;
+
+ va_start(list, nret);
+ for (i = 0; i < nargs; i++)
+ args.args[i] = va_arg(list, prom_arg_t);
+ va_end(list);
+
+ for (i = 0; i < nret; i++)
+ args.args[nargs+i] = 0;
+
+ if (enter_prom(&args, RELOC(prom_entry)) < 0)
+ return PROM_ERROR;
+
+ return (nret > 0) ? args.args[nargs] : 0;
+}
+
+static int __init call_prom_ret(const char *service, int nargs, int nret,
+ prom_arg_t *rets, ...)
+{
+ int i;
+ struct prom_args args;
+ va_list list;
+
+ args.service = ADDR(service);
+ args.nargs = nargs;
+ args.nret = nret;
+
+ va_start(list, rets);
+ for (i = 0; i < nargs; i++)
+ args.args[i] = va_arg(list, prom_arg_t);
+ va_end(list);
+
+ for (i = 0; i < nret; i++)
+ rets[nargs+i] = 0;
+
+ if (enter_prom(&args, RELOC(prom_entry)) < 0)
+ return PROM_ERROR;
+
+ if (rets != NULL)
+ for (i = 1; i < nret; ++i)
+ rets[i-1] = args.args[nargs+i];
+
+ return (nret > 0) ? args.args[nargs] : 0;
+}
+
+
+static void __init prom_print(const char *msg)
+{
+ const char *p, *q;
+ struct prom_t *_prom = &RELOC(prom);
+
+ if (_prom->stdout == 0)
+ return;
+
+ for (p = msg; *p != 0; p = q) {
+ for (q = p; *q != 0 && *q != '\n'; ++q)
+ ;
+ if (q > p)
+ call_prom("write", 3, 1, _prom->stdout, p, q - p);
+ if (*q == 0)
+ break;
+ ++q;
+ call_prom("write", 3, 1, _prom->stdout, ADDR("\r\n"), 2);
+ }
+}
+
+
+static void __init prom_print_hex(unsigned long val)
+{
+ int i, nibbles = sizeof(val)*2;
+ char buf[sizeof(val)*2+1];
+ struct prom_t *_prom = &RELOC(prom);
+
+ for (i = nibbles-1; i >= 0; i--) {
+ buf[i] = (val & 0xf) + '0';
+ if (buf[i] > '9')
+ buf[i] += ('a'-'0'-10);
+ val >>= 4;
+ }
+ buf[nibbles] = '\0';
+ call_prom("write", 3, 1, _prom->stdout, buf, nibbles);
+}
+
+
+static void __init prom_printf(const char *format, ...)
+{
+ const char *p, *q, *s;
+ va_list args;
+ unsigned long v;
+ struct prom_t *_prom = &RELOC(prom);
+
+ va_start(args, format);
+#ifdef CONFIG_PPC64
+ format = PTRRELOC(format);
+#endif
+ for (p = format; *p != 0; p = q) {
+ for (q = p; *q != 0 && *q != '\n' && *q != '%'; ++q)
+ ;
+ if (q > p)
+ call_prom("write", 3, 1, _prom->stdout, p, q - p);
+ if (*q == 0)
+ break;
+ if (*q == '\n') {
+ ++q;
+ call_prom("write", 3, 1, _prom->stdout,
+ ADDR("\r\n"), 2);
+ continue;
+ }
+ ++q;
+ if (*q == 0)
+ break;
+ switch (*q) {
+ case 's':
+ ++q;
+ s = va_arg(args, const char *);
+ prom_print(s);
+ break;
+ case 'x':
+ ++q;
+ v = va_arg(args, unsigned long);
+ prom_print_hex(v);
+ break;
+ }
+ }
+}
+
+
+static unsigned int __init prom_claim(unsigned long virt, unsigned long size,
+ unsigned long align)
+{
+ int ret;
+ struct prom_t *_prom = &RELOC(prom);
+
+ ret = call_prom("claim", 3, 1, (prom_arg_t)virt, (prom_arg_t)size,
+ (prom_arg_t)align);
+ if (ret != -1 && _prom->mmumap != 0)
+ /* old pmacs need us to map as well */
+ call_prom("call-method", 6, 1,
+ ADDR("map"), _prom->mmumap, 0, size, virt, virt);
+ return ret;
+}
+
+static void __init __attribute__((noreturn)) prom_panic(const char *reason)
+{
+#ifdef CONFIG_PPC64
+ reason = PTRRELOC(reason);
+#endif
+ prom_print(reason);
+ /* ToDo: should put up an SRC here on p/iSeries */
+ call_prom("exit", 0, 0);
+
+ for (;;) /* should never get here */
+ ;
+}
+
+
+static int __init prom_next_node(phandle *nodep)
+{
+ phandle node;
+
+ if ((node = *nodep) != 0
+ && (*nodep = call_prom("child", 1, 1, node)) != 0)
+ return 1;
+ if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
+ return 1;
+ for (;;) {
+ if ((node = call_prom("parent", 1, 1, node)) == 0)
+ return 0;
+ if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
+ return 1;
+ }
+}
+
+static int __init prom_getprop(phandle node, const char *pname,
+ void *value, size_t valuelen)
+{
+ return call_prom("getprop", 4, 1, node, ADDR(pname),
+ (u32)(unsigned long) value, (u32) valuelen);
+}
+
+static int __init prom_getproplen(phandle node, const char *pname)
+{
+ return call_prom("getproplen", 2, 1, node, ADDR(pname));
+}
+
+static int __init prom_setprop(phandle node, const char *pname,
+ void *value, size_t valuelen)
+{
+ return call_prom("setprop", 4, 1, node, ADDR(pname),
+ (u32)(unsigned long) value, (u32) valuelen);
+}
+
+/* We can't use the standard versions because of RELOC headaches. */
+#define isxdigit(c) (('0' <= (c) && (c) <= '9') \
+ || ('a' <= (c) && (c) <= 'f') \
+ || ('A' <= (c) && (c) <= 'F'))
+
+#define isdigit(c) ('0' <= (c) && (c) <= '9')
+#define islower(c) ('a' <= (c) && (c) <= 'z')
+#define toupper(c) (islower(c) ? ((c) - 'a' + 'A') : (c))
+
+unsigned long prom_strtoul(const char *cp, const char **endp)
+{
+ unsigned long result = 0, base = 10, value;
+
+ if (*cp == '0') {
+ base = 8;
+ cp++;
+ if (toupper(*cp) == 'X') {
+ cp++;
+ base = 16;
+ }
+ }
+
+ while (isxdigit(*cp) &&
+ (value = isdigit(*cp) ? *cp - '0' : toupper(*cp) - 'A' + 10) < base) {
+ result = result * base + value;
+ cp++;
+ }
+
+ if (endp)
+ *endp = cp;
+
+ return result;
+}
+
+unsigned long prom_memparse(const char *ptr, const char **retptr)
+{
+ unsigned long ret = prom_strtoul(ptr, retptr);
+ int shift = 0;
+
+ /*
+ * We can't use a switch here because GCC *may* generate a
+ * jump table which won't work, because we're not running at
+ * the address we're linked at.
+ */
+ if ('G' == **retptr || 'g' == **retptr)
+ shift = 30;
+
+ if ('M' == **retptr || 'm' == **retptr)
+ shift = 20;
+
+ if ('K' == **retptr || 'k' == **retptr)
+ shift = 10;
+
+ if (shift) {
+ ret <<= shift;
+ (*retptr)++;
+ }
+
+ return ret;
+}
+
+/*
+ * Early parsing of the command line passed to the kernel, used for
+ * "mem=x" and the options that affect the iommu
+ */
+static void __init early_cmdline_parse(void)
+{
+ struct prom_t *_prom = &RELOC(prom);
+ char *opt, *p;
+ int l = 0;
+
+ RELOC(prom_cmd_line[0]) = 0;
+ p = RELOC(prom_cmd_line);
+ if ((long)_prom->chosen > 0)
+ l = prom_getprop(_prom->chosen, "bootargs", p, COMMAND_LINE_SIZE-1);
+#ifdef CONFIG_CMDLINE
+ if (l == 0) /* dbl check */
+ strlcpy(RELOC(prom_cmd_line),
+ RELOC(CONFIG_CMDLINE), sizeof(prom_cmd_line));
+#endif /* CONFIG_CMDLINE */
+ prom_printf("command line: %s\n", RELOC(prom_cmd_line));
+
+#ifdef CONFIG_PPC64
+ opt = strstr(RELOC(prom_cmd_line), RELOC("iommu="));
+ if (opt) {
+ prom_printf("iommu opt is: %s\n", opt);
+ opt += 6;
+ while (*opt && *opt == ' ')
+ opt++;
+ if (!strncmp(opt, RELOC("off"), 3))
+ RELOC(ppc64_iommu_off) = 1;
+ else if (!strncmp(opt, RELOC("force"), 5))
+ RELOC(iommu_force_on) = 1;
+ }
+#endif
+
+ opt = strstr(RELOC(prom_cmd_line), RELOC("mem="));
+ if (opt) {
+ opt += 4;
+ RELOC(prom_memory_limit) = prom_memparse(opt, (const char **)&opt);
+#ifdef CONFIG_PPC64
+ /* Align to 16 MB == size of ppc64 large page */
+ RELOC(prom_memory_limit) = ALIGN(RELOC(prom_memory_limit), 0x1000000);
+#endif
+ }
+}
+
+#ifdef CONFIG_PPC_PSERIES
+/*
+ * To tell the firmware what our capabilities are, we have to pass
+ * it a fake 32-bit ELF header containing a couple of PT_NOTE sections
+ * that contain structures that contain the actual values.
+ */
+static struct fake_elf {
+ Elf32_Ehdr elfhdr;
+ Elf32_Phdr phdr[2];
+ struct chrpnote {
+ u32 namesz;
+ u32 descsz;
+ u32 type;
+ char name[8]; /* "PowerPC" */
+ struct chrpdesc {
+ u32 real_mode;
+ u32 real_base;
+ u32 real_size;
+ u32 virt_base;
+ u32 virt_size;
+ u32 load_base;
+ } chrpdesc;
+ } chrpnote;
+ struct rpanote {
+ u32 namesz;
+ u32 descsz;
+ u32 type;
+ char name[24]; /* "IBM,RPA-Client-Config" */
+ struct rpadesc {
+ u32 lpar_affinity;
+ u32 min_rmo_size;
+ u32 min_rmo_percent;
+ u32 max_pft_size;
+ u32 splpar;
+ u32 min_load;
+ u32 new_mem_def;
+ u32 ignore_me;
+ } rpadesc;
+ } rpanote;
+} fake_elf = {
+ .elfhdr = {
+ .e_ident = { 0x7f, 'E', 'L', 'F',
+ ELFCLASS32, ELFDATA2MSB, EV_CURRENT },
+ .e_type = ET_EXEC, /* yeah right */
+ .e_machine = EM_PPC,
+ .e_version = EV_CURRENT,
+ .e_phoff = offsetof(struct fake_elf, phdr),
+ .e_phentsize = sizeof(Elf32_Phdr),
+ .e_phnum = 2
+ },
+ .phdr = {
+ [0] = {
+ .p_type = PT_NOTE,
+ .p_offset = offsetof(struct fake_elf, chrpnote),
+ .p_filesz = sizeof(struct chrpnote)
+ }, [1] = {
+ .p_type = PT_NOTE,
+ .p_offset = offsetof(struct fake_elf, rpanote),
+ .p_filesz = sizeof(struct rpanote)
+ }
+ },
+ .chrpnote = {
+ .namesz = sizeof("PowerPC"),
+ .descsz = sizeof(struct chrpdesc),
+ .type = 0x1275,
+ .name = "PowerPC",
+ .chrpdesc = {
+ .real_mode = ~0U, /* ~0 means "don't care" */
+ .real_base = ~0U,
+ .real_size = ~0U,
+ .virt_base = ~0U,
+ .virt_size = ~0U,
+ .load_base = ~0U
+ },
+ },
+ .rpanote = {
+ .namesz = sizeof("IBM,RPA-Client-Config"),
+ .descsz = sizeof(struct rpadesc),
+ .type = 0x12759999,
+ .name = "IBM,RPA-Client-Config",
+ .rpadesc = {
+ .lpar_affinity = 0,
+ .min_rmo_size = 64, /* in megabytes */
+ .min_rmo_percent = 0,
+ .max_pft_size = 48, /* 2^48 bytes max PFT size */
+ .splpar = 1,
+ .min_load = ~0U,
+ .new_mem_def = 0
+ }
+ }
+};
+
+static void __init prom_send_capabilities(void)
+{
+ ihandle elfloader;
+
+ elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader"));
+ if (elfloader == 0) {
+ prom_printf("couldn't open /packages/elf-loader\n");
+ return;
+ }
+ call_prom("call-method", 3, 1, ADDR("process-elf-header"),
+ elfloader, ADDR(&fake_elf));
+ call_prom("close", 1, 0, elfloader);
+}
+#endif
+
+/*
+ * Memory allocation strategy... our layout is normally:
+ *
+ * at 14Mb or more we have vmlinux, then a gap and initrd. In some
+ * rare cases, initrd might end up being before the kernel though.
+ * We assume this won't override the final kernel at 0, we have no
+ * provision to handle that in this version, but it should hopefully
+ * never happen.
+ *
+ * alloc_top is set to the top of RMO, eventually shrink down if the
+ * TCEs overlap
+ *
+ * alloc_bottom is set to the top of kernel/initrd
+ *
+ * from there, allocations are done this way : rtas is allocated
+ * topmost, and the device-tree is allocated from the bottom. We try
+ * to grow the device-tree allocation as we progress. If we can't,
+ * then we fail, we don't currently have a facility to restart
+ * elsewhere, but that shouldn't be necessary.
+ *
+ * Note that calls to reserve_mem have to be done explicitly, memory
+ * allocated with either alloc_up or alloc_down isn't automatically
+ * reserved.
+ */
+
+
+/*
+ * Allocates memory in the RMO upward from the kernel/initrd
+ *
+ * When align is 0, this is a special case, it means to allocate in place
+ * at the current location of alloc_bottom or fail (that is basically
+ * extending the previous allocation). Used for the device-tree flattening
+ */
+static unsigned long __init alloc_up(unsigned long size, unsigned long align)
+{
+ unsigned long base = RELOC(alloc_bottom);
+ unsigned long addr = 0;
+
+ if (align)
+ base = _ALIGN_UP(base, align);
+ prom_debug("alloc_up(%x, %x)\n", size, align);
+ if (RELOC(ram_top) == 0)
+ prom_panic("alloc_up() called with mem not initialized\n");
+
+ if (align)
+ base = _ALIGN_UP(RELOC(alloc_bottom), align);
+ else
+ base = RELOC(alloc_bottom);
+
+ for(; (base + size) <= RELOC(alloc_top);
+ base = _ALIGN_UP(base + 0x100000, align)) {
+ prom_debug(" trying: 0x%x\n\r", base);
+ addr = (unsigned long)prom_claim(base, size, 0);
+ if (addr != PROM_ERROR && addr != 0)
+ break;
+ addr = 0;
+ if (align == 0)
+ break;
+ }
+ if (addr == 0)
+ return 0;
+ RELOC(alloc_bottom) = addr;
+
+ prom_debug(" -> %x\n", addr);
+ prom_debug(" alloc_bottom : %x\n", RELOC(alloc_bottom));
+ prom_debug(" alloc_top : %x\n", RELOC(alloc_top));
+ prom_debug(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
+ prom_debug(" rmo_top : %x\n", RELOC(rmo_top));
+ prom_debug(" ram_top : %x\n", RELOC(ram_top));
+
+ return addr;
+}
+
+/*
+ * Allocates memory downward, either from top of RMO, or if highmem
+ * is set, from the top of RAM. Note that this one doesn't handle
+ * failures. It does claim memory if highmem is not set.
+ */
+static unsigned long __init alloc_down(unsigned long size, unsigned long align,
+ int highmem)
+{
+ unsigned long base, addr = 0;
+
+ prom_debug("alloc_down(%x, %x, %s)\n", size, align,
+ highmem ? RELOC("(high)") : RELOC("(low)"));
+ if (RELOC(ram_top) == 0)
+ prom_panic("alloc_down() called with mem not initialized\n");
+
+ if (highmem) {
+ /* Carve out storage for the TCE table. */
+ addr = _ALIGN_DOWN(RELOC(alloc_top_high) - size, align);
+ if (addr <= RELOC(alloc_bottom))
+ return 0;
+ /* Will we bump into the RMO ? If yes, check out that we
+ * didn't overlap existing allocations there, if we did,
+ * we are dead, we must be the first in town !
+ */
+ if (addr < RELOC(rmo_top)) {
+ /* Good, we are first */
+ if (RELOC(alloc_top) == RELOC(rmo_top))
+ RELOC(alloc_top) = RELOC(rmo_top) = addr;
+ else
+ return 0;
+ }
+ RELOC(alloc_top_high) = addr;
+ goto bail;
+ }
+
+ base = _ALIGN_DOWN(RELOC(alloc_top) - size, align);
+ for (; base > RELOC(alloc_bottom);
+ base = _ALIGN_DOWN(base - 0x100000, align)) {
+ prom_debug(" trying: 0x%x\n\r", base);
+ addr = (unsigned long)prom_claim(base, size, 0);
+ if (addr != PROM_ERROR && addr != 0)
+ break;
+ addr = 0;
+ }
+ if (addr == 0)
+ return 0;
+ RELOC(alloc_top) = addr;
+
+ bail:
+ prom_debug(" -> %x\n", addr);
+ prom_debug(" alloc_bottom : %x\n", RELOC(alloc_bottom));
+ prom_debug(" alloc_top : %x\n", RELOC(alloc_top));
+ prom_debug(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
+ prom_debug(" rmo_top : %x\n", RELOC(rmo_top));
+ prom_debug(" ram_top : %x\n", RELOC(ram_top));
+
+ return addr;
+}
+
+/*
+ * Parse a "reg" cell
+ */
+static unsigned long __init prom_next_cell(int s, cell_t **cellp)
+{
+ cell_t *p = *cellp;
+ unsigned long r = 0;
+
+ /* Ignore more than 2 cells */
+ while (s > sizeof(unsigned long) / 4) {
+ p++;
+ s--;
+ }
+ r = *p++;
+#ifdef CONFIG_PPC64
+ if (s > 1) {
+ r <<= 32;
+ r |= *(p++);
+ }
+#endif
+ *cellp = p;
+ return r;
+}
+
+/*
+ * Very dumb function for adding to the memory reserve list, but
+ * we don't need anything smarter at this point
+ *
+ * XXX Eventually check for collisions. They should NEVER happen.
+ * If problems seem to show up, it would be a good start to track
+ * them down.
+ */
+static void reserve_mem(unsigned long base, unsigned long size)
+{
+ unsigned long top = base + size;
+ unsigned long cnt = RELOC(mem_reserve_cnt);
+
+ if (size == 0)
+ return;
+
+ /* We need to always keep one empty entry so that we
+ * have our terminator with "size" set to 0 since we are
+ * dumb and just copy this entire array to the boot params
+ */
+ base = _ALIGN_DOWN(base, PAGE_SIZE);
+ top = _ALIGN_UP(top, PAGE_SIZE);
+ size = top - base;
+
+ if (cnt >= (MEM_RESERVE_MAP_SIZE - 1))
+ prom_panic("Memory reserve map exhausted !\n");
+ RELOC(mem_reserve_map)[cnt].base = base;
+ RELOC(mem_reserve_map)[cnt].size = size;
+ RELOC(mem_reserve_cnt) = cnt + 1;
+}
+
+/*
+ * Initialize memory allocation mecanism, parse "memory" nodes and
+ * obtain that way the top of memory and RMO to setup out local allocator
+ */
+static void __init prom_init_mem(void)
+{
+ phandle node;
+ char *path, type[64];
+ unsigned int plen;
+ cell_t *p, *endp;
+ struct prom_t *_prom = &RELOC(prom);
+ u32 rac, rsc;
+
+ /*
+ * We iterate the memory nodes to find
+ * 1) top of RMO (first node)
+ * 2) top of memory
+ */
+ rac = 2;
+ prom_getprop(_prom->root, "#address-cells", &rac, sizeof(rac));
+ rsc = 1;
+ prom_getprop(_prom->root, "#size-cells", &rsc, sizeof(rsc));
+ prom_debug("root_addr_cells: %x\n", (unsigned long) rac);
+ prom_debug("root_size_cells: %x\n", (unsigned long) rsc);
+
+ prom_debug("scanning memory:\n");
+ path = RELOC(prom_scratch);
+
+ for (node = 0; prom_next_node(&node); ) {
+ type[0] = 0;
+ prom_getprop(node, "device_type", type, sizeof(type));
+
+ if (type[0] == 0) {
+ /*
+ * CHRP Longtrail machines have no device_type
+ * on the memory node, so check the name instead...
+ */
+ prom_getprop(node, "name", type, sizeof(type));
+ }
+ if (strcmp(type, RELOC("memory")))
+ continue;
+
+ plen = prom_getprop(node, "reg", RELOC(regbuf), sizeof(regbuf));
+ if (plen > sizeof(regbuf)) {
+ prom_printf("memory node too large for buffer !\n");
+ plen = sizeof(regbuf);
+ }
+ p = RELOC(regbuf);
+ endp = p + (plen / sizeof(cell_t));
+
+#ifdef DEBUG_PROM
+ memset(path, 0, PROM_SCRATCH_SIZE);
+ call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
+ prom_debug(" node %s :\n", path);
+#endif /* DEBUG_PROM */
+
+ while ((endp - p) >= (rac + rsc)) {
+ unsigned long base, size;
+
+ base = prom_next_cell(rac, &p);
+ size = prom_next_cell(rsc, &p);
+
+ if (size == 0)
+ continue;
+ prom_debug(" %x %x\n", base, size);
+ if (base == 0)
+ RELOC(rmo_top) = size;
+ if ((base + size) > RELOC(ram_top))
+ RELOC(ram_top) = base + size;
+ }
+ }
+
+ RELOC(alloc_bottom) = PAGE_ALIGN((unsigned long)&RELOC(_end) + 0x4000);
+
+ /* Check if we have an initrd after the kernel, if we do move our bottom
+ * point to after it
+ */
+ if (RELOC(prom_initrd_start)) {
+ if (RELOC(prom_initrd_end) > RELOC(alloc_bottom))
+ RELOC(alloc_bottom) = PAGE_ALIGN(RELOC(prom_initrd_end));
+ }
+
+ /*
+ * If prom_memory_limit is set we reduce the upper limits *except* for
+ * alloc_top_high. This must be the real top of RAM so we can put
+ * TCE's up there.
+ */
+
+ RELOC(alloc_top_high) = RELOC(ram_top);
+
+ if (RELOC(prom_memory_limit)) {
+ if (RELOC(prom_memory_limit) <= RELOC(alloc_bottom)) {
+ prom_printf("Ignoring mem=%x <= alloc_bottom.\n",
+ RELOC(prom_memory_limit));
+ RELOC(prom_memory_limit) = 0;
+ } else if (RELOC(prom_memory_limit) >= RELOC(ram_top)) {
+ prom_printf("Ignoring mem=%x >= ram_top.\n",
+ RELOC(prom_memory_limit));
+ RELOC(prom_memory_limit) = 0;
+ } else {
+ RELOC(ram_top) = RELOC(prom_memory_limit);
+ RELOC(rmo_top) = min(RELOC(rmo_top), RELOC(prom_memory_limit));
+ }
+ }
+
+ /*
+ * Setup our top alloc point, that is top of RMO or top of
+ * segment 0 when running non-LPAR.
+ * Some RS64 machines have buggy firmware where claims up at
+ * 1GB fail. Cap at 768MB as a workaround.
+ * Since 768MB is plenty of room, and we need to cap to something
+ * reasonable on 32-bit, cap at 768MB on all machines.
+ */
+ if (!RELOC(rmo_top))
+ RELOC(rmo_top) = RELOC(ram_top);
+ RELOC(rmo_top) = min(0x30000000ul, RELOC(rmo_top));
+ RELOC(alloc_top) = RELOC(rmo_top);
+
+ prom_printf("memory layout at init:\n");
+ prom_printf(" memory_limit : %x (16 MB aligned)\n", RELOC(prom_memory_limit));
+ prom_printf(" alloc_bottom : %x\n", RELOC(alloc_bottom));
+ prom_printf(" alloc_top : %x\n", RELOC(alloc_top));
+ prom_printf(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
+ prom_printf(" rmo_top : %x\n", RELOC(rmo_top));
+ prom_printf(" ram_top : %x\n", RELOC(ram_top));
+}
+
+
+/*
+ * Allocate room for and instantiate RTAS
+ */
+static void __init prom_instantiate_rtas(void)
+{
+ phandle rtas_node;
+ ihandle rtas_inst;
+ u32 base, entry = 0;
+ u32 size = 0;
+
+ prom_debug("prom_instantiate_rtas: start...\n");
+
+ rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas"));
+ prom_debug("rtas_node: %x\n", rtas_node);
+ if (!PHANDLE_VALID(rtas_node))
+ return;
+
+ prom_getprop(rtas_node, "rtas-size", &size, sizeof(size));
+ if (size == 0)
+ return;
+
+ base = alloc_down(size, PAGE_SIZE, 0);
+ if (base == 0) {
+ prom_printf("RTAS allocation failed !\n");
+ return;
+ }
+
+ rtas_inst = call_prom("open", 1, 1, ADDR("/rtas"));
+ if (!IHANDLE_VALID(rtas_inst)) {
+ prom_printf("opening rtas package failed");
+ return;
+ }
+
+ prom_printf("instantiating rtas at 0x%x ...", base);
+
+ if (call_prom_ret("call-method", 3, 2, &entry,
+ ADDR("instantiate-rtas"),
+ rtas_inst, base) == PROM_ERROR
+ || entry == 0) {
+ prom_printf(" failed\n");
+ return;
+ }
+ prom_printf(" done\n");
+
+ reserve_mem(base, size);
+
+ prom_setprop(rtas_node, "linux,rtas-base", &base, sizeof(base));
+ prom_setprop(rtas_node, "linux,rtas-entry", &entry, sizeof(entry));
+
+ prom_debug("rtas base = 0x%x\n", base);
+ prom_debug("rtas entry = 0x%x\n", entry);
+ prom_debug("rtas size = 0x%x\n", (long)size);
+
+ prom_debug("prom_instantiate_rtas: end...\n");
+}
+
+#ifdef CONFIG_PPC64
+/*
+ * Allocate room for and initialize TCE tables
+ */
+static void __init prom_initialize_tce_table(void)
+{
+ phandle node;
+ ihandle phb_node;
+ char compatible[64], type[64], model[64];
+ char *path = RELOC(prom_scratch);
+ u64 base, align;
+ u32 minalign, minsize;
+ u64 tce_entry, *tce_entryp;
+ u64 local_alloc_top, local_alloc_bottom;
+ u64 i;
+
+ if (RELOC(ppc64_iommu_off))
+ return;
+
+ prom_debug("starting prom_initialize_tce_table\n");
+
+ /* Cache current top of allocs so we reserve a single block */
+ local_alloc_top = RELOC(alloc_top_high);
+ local_alloc_bottom = local_alloc_top;
+
+ /* Search all nodes looking for PHBs. */
+ for (node = 0; prom_next_node(&node); ) {
+ compatible[0] = 0;
+ type[0] = 0;
+ model[0] = 0;
+ prom_getprop(node, "compatible",
+ compatible, sizeof(compatible));
+ prom_getprop(node, "device_type", type, sizeof(type));
+ prom_getprop(node, "model", model, sizeof(model));
+
+ if ((type[0] == 0) || (strstr(type, RELOC("pci")) == NULL))
+ continue;
+
+ /* Keep the old logic in tack to avoid regression. */
+ if (compatible[0] != 0) {
+ if ((strstr(compatible, RELOC("python")) == NULL) &&
+ (strstr(compatible, RELOC("Speedwagon")) == NULL) &&
+ (strstr(compatible, RELOC("Winnipeg")) == NULL))
+ continue;
+ } else if (model[0] != 0) {
+ if ((strstr(model, RELOC("ython")) == NULL) &&
+ (strstr(model, RELOC("peedwagon")) == NULL) &&
+ (strstr(model, RELOC("innipeg")) == NULL))
+ continue;
+ }
+
+ if (prom_getprop(node, "tce-table-minalign", &minalign,
+ sizeof(minalign)) == PROM_ERROR)
+ minalign = 0;
+ if (prom_getprop(node, "tce-table-minsize", &minsize,
+ sizeof(minsize)) == PROM_ERROR)
+ minsize = 4UL << 20;
+
+ /*
+ * Even though we read what OF wants, we just set the table
+ * size to 4 MB. This is enough to map 2GB of PCI DMA space.
+ * By doing this, we avoid the pitfalls of trying to DMA to
+ * MMIO space and the DMA alias hole.
+ *
+ * On POWER4, firmware sets the TCE region by assuming
+ * each TCE table is 8MB. Using this memory for anything
+ * else will impact performance, so we always allocate 8MB.
+ * Anton
+ */
+ if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p))
+ minsize = 8UL << 20;
+ else
+ minsize = 4UL << 20;
+
+ /* Align to the greater of the align or size */
+ align = max(minalign, minsize);
+ base = alloc_down(minsize, align, 1);
+ if (base == 0)
+ prom_panic("ERROR, cannot find space for TCE table.\n");
+ if (base < local_alloc_bottom)
+ local_alloc_bottom = base;
+
+ /* Save away the TCE table attributes for later use. */
+ prom_setprop(node, "linux,tce-base", &base, sizeof(base));
+ prom_setprop(node, "linux,tce-size", &minsize, sizeof(minsize));
+
+ /* It seems OF doesn't null-terminate the path :-( */
+ memset(path, 0, sizeof(path));
+ /* Call OF to setup the TCE hardware */
+ if (call_prom("package-to-path", 3, 1, node,
+ path, PROM_SCRATCH_SIZE-1) == PROM_ERROR) {
+ prom_printf("package-to-path failed\n");
+ }
+
+ prom_debug("TCE table: %s\n", path);
+ prom_debug("\tnode = 0x%x\n", node);
+ prom_debug("\tbase = 0x%x\n", base);
+ prom_debug("\tsize = 0x%x\n", minsize);
+
+ /* Initialize the table to have a one-to-one mapping
+ * over the allocated size.
+ */
+ tce_entryp = (unsigned long *)base;
+ for (i = 0; i < (minsize >> 3) ;tce_entryp++, i++) {
+ tce_entry = (i << PAGE_SHIFT);
+ tce_entry |= 0x3;
+ *tce_entryp = tce_entry;
+ }
+
+ prom_printf("opening PHB %s", path);
+ phb_node = call_prom("open", 1, 1, path);
+ if (phb_node == 0)
+ prom_printf("... failed\n");
+ else
+ prom_printf("... done\n");
+
+ call_prom("call-method", 6, 0, ADDR("set-64-bit-addressing"),
+ phb_node, -1, minsize,
+ (u32) base, (u32) (base >> 32));
+ call_prom("close", 1, 0, phb_node);
+ }
+
+ reserve_mem(local_alloc_bottom, local_alloc_top - local_alloc_bottom);
+
+ if (RELOC(prom_memory_limit)) {
+ /*
+ * We align the start to a 16MB boundary so we can map
+ * the TCE area using large pages if possible.
+ * The end should be the top of RAM so no need to align it.
+ */
+ RELOC(prom_tce_alloc_start) = _ALIGN_DOWN(local_alloc_bottom,
+ 0x1000000);
+ RELOC(prom_tce_alloc_end) = local_alloc_top;
+ }
+
+ /* Flag the first invalid entry */
+ prom_debug("ending prom_initialize_tce_table\n");
+}
+#endif
+
+/*
+ * With CHRP SMP we need to use the OF to start the other processors.
+ * We can't wait until smp_boot_cpus (the OF is trashed by then)
+ * so we have to put the processors into a holding pattern controlled
+ * by the kernel (not OF) before we destroy the OF.
+ *
+ * This uses a chunk of low memory, puts some holding pattern
+ * code there and sends the other processors off to there until
+ * smp_boot_cpus tells them to do something. The holding pattern
+ * checks that address until its cpu # is there, when it is that
+ * cpu jumps to __secondary_start(). smp_boot_cpus() takes care
+ * of setting those values.
+ *
+ * We also use physical address 0x4 here to tell when a cpu
+ * is in its holding pattern code.
+ *
+ * -- Cort
+ */
+extern void __secondary_hold(void);
+extern unsigned long __secondary_hold_spinloop;
+extern unsigned long __secondary_hold_acknowledge;
+
+/*
+ * We want to reference the copy of __secondary_hold_* in the
+ * 0 - 0x100 address range
+ */
+#define LOW_ADDR(x) (((unsigned long) &(x)) & 0xff)
+
+static void __init prom_hold_cpus(void)
+{
+ unsigned long i;
+ unsigned int reg;
+ phandle node;
+ char type[64];
+ int cpuid = 0;
+ unsigned int interrupt_server[MAX_CPU_THREADS];
+ unsigned int cpu_threads, hw_cpu_num;
+ int propsize;
+ struct prom_t *_prom = &RELOC(prom);
+ unsigned long *spinloop
+ = (void *) LOW_ADDR(__secondary_hold_spinloop);
+ unsigned long *acknowledge
+ = (void *) LOW_ADDR(__secondary_hold_acknowledge);
+#ifdef CONFIG_PPC64
+ /* __secondary_hold is actually a descriptor, not the text address */
+ unsigned long secondary_hold
+ = __pa(*PTRRELOC((unsigned long *)__secondary_hold));
+#else
+ unsigned long secondary_hold = LOW_ADDR(__secondary_hold);
+#endif
+
+ prom_debug("prom_hold_cpus: start...\n");
+ prom_debug(" 1) spinloop = 0x%x\n", (unsigned long)spinloop);
+ prom_debug(" 1) *spinloop = 0x%x\n", *spinloop);
+ prom_debug(" 1) acknowledge = 0x%x\n",
+ (unsigned long)acknowledge);
+ prom_debug(" 1) *acknowledge = 0x%x\n", *acknowledge);
+ prom_debug(" 1) secondary_hold = 0x%x\n", secondary_hold);
+
+ /* Set the common spinloop variable, so all of the secondary cpus
+ * will block when they are awakened from their OF spinloop.
+ * This must occur for both SMP and non SMP kernels, since OF will
+ * be trashed when we move the kernel.
+ */
+ *spinloop = 0;
+
+#ifdef CONFIG_HMT
+ for (i = 0; i < NR_CPUS; i++)
+ RELOC(hmt_thread_data)[i].pir = 0xdeadbeef;
+#endif
+ /* look for cpus */
+ for (node = 0; prom_next_node(&node); ) {
+ type[0] = 0;
+ prom_getprop(node, "device_type", type, sizeof(type));
+ if (strcmp(type, RELOC("cpu")) != 0)
+ continue;
+
+ /* Skip non-configured cpus. */
+ if (prom_getprop(node, "status", type, sizeof(type)) > 0)
+ if (strcmp(type, RELOC("okay")) != 0)
+ continue;
+
+ reg = -1;
+ prom_getprop(node, "reg", &reg, sizeof(reg));
+
+ prom_debug("\ncpuid = 0x%x\n", cpuid);
+ prom_debug("cpu hw idx = 0x%x\n", reg);
+
+ /* Init the acknowledge var which will be reset by
+ * the secondary cpu when it awakens from its OF
+ * spinloop.
+ */
+ *acknowledge = (unsigned long)-1;
+
+ propsize = prom_getprop(node, "ibm,ppc-interrupt-server#s",
+ &interrupt_server,
+ sizeof(interrupt_server));
+ if (propsize < 0) {
+ /* no property. old hardware has no SMT */
+ cpu_threads = 1;
+ interrupt_server[0] = reg; /* fake it with phys id */
+ } else {
+ /* We have a threaded processor */
+ cpu_threads = propsize / sizeof(u32);
+ if (cpu_threads > MAX_CPU_THREADS) {
+ prom_printf("SMT: too many threads!\n"
+ "SMT: found %x, max is %x\n",
+ cpu_threads, MAX_CPU_THREADS);
+ cpu_threads = 1; /* ToDo: panic? */
+ }
+ }
+
+ hw_cpu_num = interrupt_server[0];
+ if (hw_cpu_num != _prom->cpu) {
+ /* Primary Thread of non-boot cpu */
+ prom_printf("%x : starting cpu hw idx %x... ", cpuid, reg);
+ call_prom("start-cpu", 3, 0, node,
+ secondary_hold, reg);
+
+ for (i = 0; (i < 100000000) &&
+ (*acknowledge == ((unsigned long)-1)); i++ )
+ mb();
+
+ if (*acknowledge == reg)
+ prom_printf("done\n");
+ else
+ prom_printf("failed: %x\n", *acknowledge);
+ }
+#ifdef CONFIG_SMP
+ else
+ prom_printf("%x : boot cpu %x\n", cpuid, reg);
+#endif /* CONFIG_SMP */
+
+ /* Reserve cpu #s for secondary threads. They start later. */
+ cpuid += cpu_threads;
+ }
+#ifdef CONFIG_HMT
+ /* Only enable HMT on processors that provide support. */
+ if (__is_processor(PV_PULSAR) ||
+ __is_processor(PV_ICESTAR) ||
+ __is_processor(PV_SSTAR)) {
+ prom_printf(" starting secondary threads\n");
+
+ for (i = 0; i < NR_CPUS; i += 2) {
+ if (!cpu_online(i))
+ continue;
+
+ if (i == 0) {
+ unsigned long pir = mfspr(SPRN_PIR);
+ if (__is_processor(PV_PULSAR)) {
+ RELOC(hmt_thread_data)[i].pir =
+ pir & 0x1f;
+ } else {
+ RELOC(hmt_thread_data)[i].pir =
+ pir & 0x3ff;
+ }
+ }
+ }
+ } else {
+ prom_printf("Processor is not HMT capable\n");
+ }
+#endif
+
+ if (cpuid > NR_CPUS)
+ prom_printf("WARNING: maximum CPUs (" __stringify(NR_CPUS)
+ ") exceeded: ignoring extras\n");
+
+ prom_debug("prom_hold_cpus: end...\n");
+}
+
+
+static void __init prom_init_client_services(unsigned long pp)
+{
+ struct prom_t *_prom = &RELOC(prom);
+
+ /* Get a handle to the prom entry point before anything else */
+ RELOC(prom_entry) = pp;
+
+ /* get a handle for the stdout device */
+ _prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen"));
+ if (!PHANDLE_VALID(_prom->chosen))
+ prom_panic("cannot find chosen"); /* msg won't be printed :( */
+
+ /* get device tree root */
+ _prom->root = call_prom("finddevice", 1, 1, ADDR("/"));
+ if (!PHANDLE_VALID(_prom->root))
+ prom_panic("cannot find device tree root"); /* msg won't be printed :( */
+
+ _prom->mmumap = 0;
+}
+
+#ifdef CONFIG_PPC32
+/*
+ * For really old powermacs, we need to map things we claim.
+ * For that, we need the ihandle of the mmu.
+ */
+static void __init prom_find_mmu(void)
+{
+ struct prom_t *_prom = &RELOC(prom);
+ phandle oprom;
+ char version[64];
+
+ oprom = call_prom("finddevice", 1, 1, ADDR("/openprom"));
+ if (!PHANDLE_VALID(oprom))
+ return;
+ if (prom_getprop(oprom, "model", version, sizeof(version)) <= 0)
+ return;
+ version[sizeof(version) - 1] = 0;
+ prom_printf("OF version is '%s'\n", version);
+ /* XXX might need to add other versions here */
+ if (strcmp(version, "Open Firmware, 1.0.5") != 0)
+ return;
+ prom_getprop(_prom->chosen, "mmu", &_prom->mmumap,
+ sizeof(_prom->mmumap));
+}
+#else
+#define prom_find_mmu()
+#endif
+
+static void __init prom_init_stdout(void)
+{
+ struct prom_t *_prom = &RELOC(prom);
+ char *path = RELOC(of_stdout_device);
+ char type[16];
+ u32 val;
+
+ if (prom_getprop(_prom->chosen, "stdout", &val, sizeof(val)) <= 0)
+ prom_panic("cannot find stdout");
+
+ _prom->stdout = val;
+
+ /* Get the full OF pathname of the stdout device */
+ memset(path, 0, 256);
+ call_prom("instance-to-path", 3, 1, _prom->stdout, path, 255);
+ val = call_prom("instance-to-package", 1, 1, _prom->stdout);
+ prom_setprop(_prom->chosen, "linux,stdout-package", &val, sizeof(val));
+ prom_printf("OF stdout device is: %s\n", RELOC(of_stdout_device));
+ prom_setprop(_prom->chosen, "linux,stdout-path",
+ RELOC(of_stdout_device), strlen(RELOC(of_stdout_device))+1);
+
+ /* If it's a display, note it */
+ memset(type, 0, sizeof(type));
+ prom_getprop(val, "device_type", type, sizeof(type));
+ if (strcmp(type, RELOC("display")) == 0)
+ prom_setprop(val, "linux,boot-display", NULL, 0);
+}
+
+static void __init prom_close_stdin(void)
+{
+ struct prom_t *_prom = &RELOC(prom);
+ ihandle val;
+
+ if (prom_getprop(_prom->chosen, "stdin", &val, sizeof(val)) > 0)
+ call_prom("close", 1, 0, val);
+}
+
+static int __init prom_find_machine_type(void)
+{
+ struct prom_t *_prom = &RELOC(prom);
+ char compat[256];
+ int len, i = 0;
+ phandle rtas;
+
+ len = prom_getprop(_prom->root, "compatible",
+ compat, sizeof(compat)-1);
+ if (len > 0) {
+ compat[len] = 0;
+ while (i < len) {
+ char *p = &compat[i];
+ int sl = strlen(p);
+ if (sl == 0)
+ break;
+ if (strstr(p, RELOC("Power Macintosh")) ||
+ strstr(p, RELOC("MacRISC")))
+ return PLATFORM_POWERMAC;
+#ifdef CONFIG_PPC64
+ if (strstr(p, RELOC("Momentum,Maple")))
+ return PLATFORM_MAPLE;
+#endif
+ i += sl + 1;
+ }
+ }
+#ifdef CONFIG_PPC64
+ /* Default to pSeries. We need to know if we are running LPAR */
+ rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
+ if (PHANDLE_VALID(rtas)) {
+ int x = prom_getproplen(rtas, "ibm,hypertas-functions");
+ if (x != PROM_ERROR) {
+ prom_printf("Hypertas detected, assuming LPAR !\n");
+ return PLATFORM_PSERIES_LPAR;
+ }
+ }
+ return PLATFORM_PSERIES;
+#else
+ return PLATFORM_CHRP;
+#endif
+}
+
+static int __init prom_set_color(ihandle ih, int i, int r, int g, int b)
+{
+ return call_prom("call-method", 6, 1, ADDR("color!"), ih, i, b, g, r);
+}
+
+/*
+ * If we have a display that we don't know how to drive,
+ * we will want to try to execute OF's open method for it
+ * later. However, OF will probably fall over if we do that
+ * we've taken over the MMU.
+ * So we check whether we will need to open the display,
+ * and if so, open it now.
+ */
+static void __init prom_check_displays(void)
+{
+ char type[16], *path;
+ phandle node;
+ ihandle ih;
+ int i;
+
+ static unsigned char default_colors[] = {
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xaa,
+ 0x00, 0xaa, 0x00,
+ 0x00, 0xaa, 0xaa,
+ 0xaa, 0x00, 0x00,
+ 0xaa, 0x00, 0xaa,
+ 0xaa, 0xaa, 0x00,
+ 0xaa, 0xaa, 0xaa,
+ 0x55, 0x55, 0x55,
+ 0x55, 0x55, 0xff,
+ 0x55, 0xff, 0x55,
+ 0x55, 0xff, 0xff,
+ 0xff, 0x55, 0x55,
+ 0xff, 0x55, 0xff,
+ 0xff, 0xff, 0x55,
+ 0xff, 0xff, 0xff
+ };
+ const unsigned char *clut;
+
+ prom_printf("Looking for displays\n");
+ for (node = 0; prom_next_node(&node); ) {
+ memset(type, 0, sizeof(type));
+ prom_getprop(node, "device_type", type, sizeof(type));
+ if (strcmp(type, RELOC("display")) != 0)
+ continue;
+
+ /* It seems OF doesn't null-terminate the path :-( */
+ path = RELOC(prom_scratch);
+ memset(path, 0, PROM_SCRATCH_SIZE);
+
+ /*
+ * leave some room at the end of the path for appending extra
+ * arguments
+ */
+ if (call_prom("package-to-path", 3, 1, node, path,
+ PROM_SCRATCH_SIZE-10) == PROM_ERROR)
+ continue;
+ prom_printf("found display : %s, opening ... ", path);
+
+ ih = call_prom("open", 1, 1, path);
+ if (ih == 0) {
+ prom_printf("failed\n");
+ continue;
+ }
+
+ /* Success */
+ prom_printf("done\n");
+ prom_setprop(node, "linux,opened", NULL, 0);
+
+ /* Setup a usable color table when the appropriate
+ * method is available. Should update this to set-colors */
+ clut = RELOC(default_colors);
+ for (i = 0; i < 32; i++, clut += 3)
+ if (prom_set_color(ih, i, clut[0], clut[1],
+ clut[2]) != 0)
+ break;
+
+#ifdef CONFIG_LOGO_LINUX_CLUT224
+ clut = PTRRELOC(RELOC(logo_linux_clut224.clut));
+ for (i = 0; i < RELOC(logo_linux_clut224.clutsize); i++, clut += 3)
+ if (prom_set_color(ih, i + 32, clut[0], clut[1],
+ clut[2]) != 0)
+ break;
+#endif /* CONFIG_LOGO_LINUX_CLUT224 */
+ }
+}
+
+
+/* Return (relocated) pointer to this much memory: moves initrd if reqd. */
+static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end,
+ unsigned long needed, unsigned long align)
+{
+ void *ret;
+
+ *mem_start = _ALIGN(*mem_start, align);
+ while ((*mem_start + needed) > *mem_end) {
+ unsigned long room, chunk;
+
+ prom_debug("Chunk exhausted, claiming more at %x...\n",
+ RELOC(alloc_bottom));
+ room = RELOC(alloc_top) - RELOC(alloc_bottom);
+ if (room > DEVTREE_CHUNK_SIZE)
+ room = DEVTREE_CHUNK_SIZE;
+ if (room < PAGE_SIZE)
+ prom_panic("No memory for flatten_device_tree (no room)");
+ chunk = alloc_up(room, 0);
+ if (chunk == 0)
+ prom_panic("No memory for flatten_device_tree (claim failed)");
+ *mem_end = RELOC(alloc_top);
+ }
+
+ ret = (void *)*mem_start;
+ *mem_start += needed;
+
+ return ret;
+}
+
+#define dt_push_token(token, mem_start, mem_end) \
+ do { *((u32 *)make_room(mem_start, mem_end, 4, 4)) = token; } while(0)
+
+static unsigned long __init dt_find_string(char *str)
+{
+ char *s, *os;
+
+ s = os = (char *)RELOC(dt_string_start);
+ s += 4;
+ while (s < (char *)RELOC(dt_string_end)) {
+ if (strcmp(s, str) == 0)
+ return s - os;
+ s += strlen(s) + 1;
+ }
+ return 0;
+}
+
+/*
+ * The Open Firmware 1275 specification states properties must be 31 bytes or
+ * less, however not all firmwares obey this. Make it 64 bytes to be safe.
+ */
+#define MAX_PROPERTY_NAME 64
+
+static void __init scan_dt_build_strings(phandle node,
+ unsigned long *mem_start,
+ unsigned long *mem_end)
+{
+ char *prev_name, *namep, *sstart;
+ unsigned long soff;
+ phandle child;
+
+ sstart = (char *)RELOC(dt_string_start);
+
+ /* get and store all property names */
+ prev_name = RELOC("");
+ for (;;) {
+ /* 64 is max len of name including nul. */
+ namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1);
+ if (call_prom("nextprop", 3, 1, node, prev_name, namep) != 1) {
+ /* No more nodes: unwind alloc */
+ *mem_start = (unsigned long)namep;
+ break;
+ }
+
+ /* skip "name" */
+ if (strcmp(namep, RELOC("name")) == 0) {
+ *mem_start = (unsigned long)namep;
+ prev_name = RELOC("name");
+ continue;
+ }
+ /* get/create string entry */
+ soff = dt_find_string(namep);
+ if (soff != 0) {
+ *mem_start = (unsigned long)namep;
+ namep = sstart + soff;
+ } else {
+ /* Trim off some if we can */
+ *mem_start = (unsigned long)namep + strlen(namep) + 1;
+ RELOC(dt_string_end) = *mem_start;
+ }
+ prev_name = namep;
+ }
+
+ /* do all our children */
+ child = call_prom("child", 1, 1, node);
+ while (child != 0) {
+ scan_dt_build_strings(child, mem_start, mem_end);
+ child = call_prom("peer", 1, 1, child);
+ }
+}
+
+static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
+ unsigned long *mem_end)
+{
+ phandle child;
+ char *namep, *prev_name, *sstart, *p, *ep, *lp, *path;
+ unsigned long soff;
+ unsigned char *valp;
+ static char pname[MAX_PROPERTY_NAME];
+ int l, room;
+
+ dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end);
+
+ /* get the node's full name */
+ namep = (char *)*mem_start;
+ room = *mem_end - *mem_start;
+ if (room > 255)
+ room = 255;
+ l = call_prom("package-to-path", 3, 1, node, namep, room);
+ if (l >= 0) {
+ /* Didn't fit? Get more room. */
+ if (l >= room) {
+ if (l >= *mem_end - *mem_start)
+ namep = make_room(mem_start, mem_end, l+1, 1);
+ call_prom("package-to-path", 3, 1, node, namep, l);
+ }
+ namep[l] = '\0';
+
+ /* Fixup an Apple bug where they have bogus \0 chars in the
+ * middle of the path in some properties, and extract
+ * the unit name (everything after the last '/').
+ */
+ for (lp = p = namep, ep = namep + l; p < ep; p++) {
+ if (*p == '/')
+ lp = namep;
+ else if (*p != 0)
+ *lp++ = *p;
+ }
+ *lp = 0;
+ *mem_start = _ALIGN((unsigned long)lp + 1, 4);
+ }
+
+ /* get it again for debugging */
+ path = RELOC(prom_scratch);
+ memset(path, 0, PROM_SCRATCH_SIZE);
+ call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
+
+ /* get and store all properties */
+ prev_name = RELOC("");
+ sstart = (char *)RELOC(dt_string_start);
+ for (;;) {
+ if (call_prom("nextprop", 3, 1, node, prev_name,
+ RELOC(pname)) != 1)
+ break;
+
+ /* skip "name" */
+ if (strcmp(RELOC(pname), RELOC("name")) == 0) {
+ prev_name = RELOC("name");
+ continue;
+ }
+
+ /* find string offset */
+ soff = dt_find_string(RELOC(pname));
+ if (soff == 0) {
+ prom_printf("WARNING: Can't find string index for"
+ " <%s>, node %s\n", RELOC(pname), path);
+ break;
+ }
+ prev_name = sstart + soff;
+
+ /* get length */
+ l = call_prom("getproplen", 2, 1, node, RELOC(pname));
+
+ /* sanity checks */
+ if (l == PROM_ERROR)
+ continue;
+ if (l > MAX_PROPERTY_LENGTH) {
+ prom_printf("WARNING: ignoring large property ");
+ /* It seems OF doesn't null-terminate the path :-( */
+ prom_printf("[%s] ", path);
+ prom_printf("%s length 0x%x\n", RELOC(pname), l);
+ continue;
+ }
+
+ /* push property head */
+ dt_push_token(OF_DT_PROP, mem_start, mem_end);
+ dt_push_token(l, mem_start, mem_end);
+ dt_push_token(soff, mem_start, mem_end);
+
+ /* push property content */
+ valp = make_room(mem_start, mem_end, l, 4);
+ call_prom("getprop", 4, 1, node, RELOC(pname), valp, l);
+ *mem_start = _ALIGN(*mem_start, 4);
+ }
+
+ /* Add a "linux,phandle" property. */
+ soff = dt_find_string(RELOC("linux,phandle"));
+ if (soff == 0)
+ prom_printf("WARNING: Can't find string index for"
+ " <linux-phandle> node %s\n", path);
+ else {
+ dt_push_token(OF_DT_PROP, mem_start, mem_end);
+ dt_push_token(4, mem_start, mem_end);
+ dt_push_token(soff, mem_start, mem_end);
+ valp = make_room(mem_start, mem_end, 4, 4);
+ *(u32 *)valp = node;
+ }
+
+ /* do all our children */
+ child = call_prom("child", 1, 1, node);
+ while (child != 0) {
+ scan_dt_build_struct(child, mem_start, mem_end);
+ child = call_prom("peer", 1, 1, child);
+ }
+
+ dt_push_token(OF_DT_END_NODE, mem_start, mem_end);
+}
+
+static void __init flatten_device_tree(void)
+{
+ phandle root;
+ unsigned long mem_start, mem_end, room;
+ struct boot_param_header *hdr;
+ struct prom_t *_prom = &RELOC(prom);
+ char *namep;
+ u64 *rsvmap;
+
+ /*
+ * Check how much room we have between alloc top & bottom (+/- a
+ * few pages), crop to 4Mb, as this is our "chuck" size
+ */
+ room = RELOC(alloc_top) - RELOC(alloc_bottom) - 0x4000;
+ if (room > DEVTREE_CHUNK_SIZE)
+ room = DEVTREE_CHUNK_SIZE;
+ prom_debug("starting device tree allocs at %x\n", RELOC(alloc_bottom));
+
+ /* Now try to claim that */
+ mem_start = (unsigned long)alloc_up(room, PAGE_SIZE);
+ if (mem_start == 0)
+ prom_panic("Can't allocate initial device-tree chunk\n");
+ mem_end = RELOC(alloc_top);
+
+ /* Get root of tree */
+ root = call_prom("peer", 1, 1, (phandle)0);
+ if (root == (phandle)0)
+ prom_panic ("couldn't get device tree root\n");
+
+ /* Build header and make room for mem rsv map */
+ mem_start = _ALIGN(mem_start, 4);
+ hdr = make_room(&mem_start, &mem_end,
+ sizeof(struct boot_param_header), 4);
+ RELOC(dt_header_start) = (unsigned long)hdr;
+ rsvmap = make_room(&mem_start, &mem_end, sizeof(mem_reserve_map), 8);
+
+ /* Start of strings */
+ mem_start = PAGE_ALIGN(mem_start);
+ RELOC(dt_string_start) = mem_start;
+ mem_start += 4; /* hole */
+
+ /* Add "linux,phandle" in there, we'll need it */
+ namep = make_room(&mem_start, &mem_end, 16, 1);
+ strcpy(namep, RELOC("linux,phandle"));
+ mem_start = (unsigned long)namep + strlen(namep) + 1;
+
+ /* Build string array */
+ prom_printf("Building dt strings...\n");
+ scan_dt_build_strings(root, &mem_start, &mem_end);
+ RELOC(dt_string_end) = mem_start;
+
+ /* Build structure */
+ mem_start = PAGE_ALIGN(mem_start);
+ RELOC(dt_struct_start) = mem_start;
+ prom_printf("Building dt structure...\n");
+ scan_dt_build_struct(root, &mem_start, &mem_end);
+ dt_push_token(OF_DT_END, &mem_start, &mem_end);
+ RELOC(dt_struct_end) = PAGE_ALIGN(mem_start);
+
+ /* Finish header */
+ hdr->boot_cpuid_phys = _prom->cpu;
+ hdr->magic = OF_DT_HEADER;
+ hdr->totalsize = RELOC(dt_struct_end) - RELOC(dt_header_start);
+ hdr->off_dt_struct = RELOC(dt_struct_start) - RELOC(dt_header_start);
+ hdr->off_dt_strings = RELOC(dt_string_start) - RELOC(dt_header_start);
+ hdr->dt_strings_size = RELOC(dt_string_end) - RELOC(dt_string_start);
+ hdr->off_mem_rsvmap = ((unsigned long)rsvmap) - RELOC(dt_header_start);
+ hdr->version = OF_DT_VERSION;
+ /* Version 16 is not backward compatible */
+ hdr->last_comp_version = 0x10;
+
+ /* Reserve the whole thing and copy the reserve map in, we
+ * also bump mem_reserve_cnt to cause further reservations to
+ * fail since it's too late.
+ */
+ reserve_mem(RELOC(dt_header_start), hdr->totalsize);
+ memcpy(rsvmap, RELOC(mem_reserve_map), sizeof(mem_reserve_map));
+
+#ifdef DEBUG_PROM
+ {
+ int i;
+ prom_printf("reserved memory map:\n");
+ for (i = 0; i < RELOC(mem_reserve_cnt); i++)
+ prom_printf(" %x - %x\n",
+ RELOC(mem_reserve_map)[i].base,
+ RELOC(mem_reserve_map)[i].size);
+ }
+#endif
+ RELOC(mem_reserve_cnt) = MEM_RESERVE_MAP_SIZE;
+
+ prom_printf("Device tree strings 0x%x -> 0x%x\n",
+ RELOC(dt_string_start), RELOC(dt_string_end));
+ prom_printf("Device tree struct 0x%x -> 0x%x\n",
+ RELOC(dt_struct_start), RELOC(dt_struct_end));
+
+}
+
+
+static void __init fixup_device_tree(void)
+{
+#if defined(CONFIG_PPC64) && defined(CONFIG_PPC_PMAC)
+ phandle u3, i2c, mpic;
+ u32 u3_rev;
+ u32 interrupts[2];
+ u32 parent;
+
+ /* Some G5s have a missing interrupt definition, fix it up here */
+ u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000"));
+ if (!PHANDLE_VALID(u3))
+ return;
+ i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000"));
+ if (!PHANDLE_VALID(i2c))
+ return;
+ mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000"));
+ if (!PHANDLE_VALID(mpic))
+ return;
+
+ /* check if proper rev of u3 */
+ if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev))
+ == PROM_ERROR)
+ return;
+ if (u3_rev != 0x35 && u3_rev != 0x37)
+ return;
+ /* does it need fixup ? */
+ if (prom_getproplen(i2c, "interrupts") > 0)
+ return;
+
+ prom_printf("fixing up bogus interrupts for u3 i2c...\n");
+
+ /* interrupt on this revision of u3 is number 0 and level */
+ interrupts[0] = 0;
+ interrupts[1] = 1;
+ prom_setprop(i2c, "interrupts", &interrupts, sizeof(interrupts));
+ parent = (u32)mpic;
+ prom_setprop(i2c, "interrupt-parent", &parent, sizeof(parent));
+#endif
+}
+
+
+static void __init prom_find_boot_cpu(void)
+{
+ struct prom_t *_prom = &RELOC(prom);
+ u32 getprop_rval;
+ ihandle prom_cpu;
+ phandle cpu_pkg;
+
+ _prom->cpu = 0;
+ if (prom_getprop(_prom->chosen, "cpu", &prom_cpu, sizeof(prom_cpu)) <= 0)
+ return;
+
+ cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu);
+
+ prom_getprop(cpu_pkg, "reg", &getprop_rval, sizeof(getprop_rval));
+ _prom->cpu = getprop_rval;
+
+ prom_debug("Booting CPU hw index = 0x%x\n", _prom->cpu);
+}
+
+static void __init prom_check_initrd(unsigned long r3, unsigned long r4)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+ struct prom_t *_prom = &RELOC(prom);
+
+ if (r3 && r4 && r4 != 0xdeadbeef) {
+ unsigned long val;
+
+ RELOC(prom_initrd_start) = (r3 >= KERNELBASE) ? __pa(r3) : r3;
+ RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4;
+
+ val = RELOC(prom_initrd_start);
+ prom_setprop(_prom->chosen, "linux,initrd-start", &val,
+ sizeof(val));
+ val = RELOC(prom_initrd_end);
+ prom_setprop(_prom->chosen, "linux,initrd-end", &val,
+ sizeof(val));
+
+ reserve_mem(RELOC(prom_initrd_start),
+ RELOC(prom_initrd_end) - RELOC(prom_initrd_start));
+
+ prom_debug("initrd_start=0x%x\n", RELOC(prom_initrd_start));
+ prom_debug("initrd_end=0x%x\n", RELOC(prom_initrd_end));
+ }
+#endif /* CONFIG_BLK_DEV_INITRD */
+}
+
+/*
+ * We enter here early on, when the Open Firmware prom is still
+ * handling exceptions and the MMU hash table for us.
+ */
+
+unsigned long __init prom_init(unsigned long r3, unsigned long r4,
+ unsigned long pp,
+ unsigned long r6, unsigned long r7)
+{
+ struct prom_t *_prom;
+ unsigned long hdr;
+ u32 getprop_rval;
+ unsigned long offset = reloc_offset();
+
+#ifdef CONFIG_PPC32
+ reloc_got2(offset);
+#endif
+
+ _prom = &RELOC(prom);
+
+ /*
+ * First zero the BSS
+ */
+ memset(&RELOC(__bss_start), 0, __bss_stop - __bss_start);
+
+ /*
+ * Init interface to Open Firmware, get some node references,
+ * like /chosen
+ */
+ prom_init_client_services(pp);
+
+ /*
+ * Init prom stdout device
+ */
+ prom_init_stdout();
+
+ /*
+ * See if this OF is old enough that we need to do explicit maps
+ */
+ prom_find_mmu();
+
+ /*
+ * Check for an initrd
+ */
+ prom_check_initrd(r3, r4);
+
+ /*
+ * Get default machine type. At this point, we do not differentiate
+ * between pSeries SMP and pSeries LPAR
+ */
+ RELOC(of_platform) = prom_find_machine_type();
+ getprop_rval = RELOC(of_platform);
+ prom_setprop(_prom->chosen, "linux,platform",
+ &getprop_rval, sizeof(getprop_rval));
+
+#ifdef CONFIG_PPC_PSERIES
+ /*
+ * On pSeries, inform the firmware about our capabilities
+ */
+ if (RELOC(of_platform) & PLATFORM_PSERIES)
+ prom_send_capabilities();
+#endif
+
+ /*
+ * On pSeries and BPA, copy the CPU hold code
+ */
+ if (RELOC(of_platform) != PLATFORM_POWERMAC)
+ copy_and_flush(0, KERNELBASE + offset, 0x100, 0);
+
+ /*
+ * Do early parsing of command line
+ */
+ early_cmdline_parse();
+
+ /*
+ * Initialize memory management within prom_init
+ */
+ prom_init_mem();
+
+ /*
+ * Determine which cpu is actually running right _now_
+ */
+ prom_find_boot_cpu();
+
+ /*
+ * Initialize display devices
+ */
+ prom_check_displays();
+
+#ifdef CONFIG_PPC64
+ /*
+ * Initialize IOMMU (TCE tables) on pSeries. Do that before anything else
+ * that uses the allocator, we need to make sure we get the top of memory
+ * available for us here...
+ */
+ if (RELOC(of_platform) == PLATFORM_PSERIES)
+ prom_initialize_tce_table();
+#endif
+
+ /*
+ * On non-powermacs, try to instantiate RTAS and puts all CPUs
+ * in spin-loops. PowerMacs don't have a working RTAS and use
+ * a different way to spin CPUs
+ */
+ if (RELOC(of_platform) != PLATFORM_POWERMAC) {
+ prom_instantiate_rtas();
+ prom_hold_cpus();
+ }
+
+ /*
+ * Fill in some infos for use by the kernel later on
+ */
+ if (RELOC(prom_memory_limit))
+ prom_setprop(_prom->chosen, "linux,memory-limit",
+ &RELOC(prom_memory_limit),
+ sizeof(prom_memory_limit));
+#ifdef CONFIG_PPC64
+ if (RELOC(ppc64_iommu_off))
+ prom_setprop(_prom->chosen, "linux,iommu-off", NULL, 0);
+
+ if (RELOC(iommu_force_on))
+ prom_setprop(_prom->chosen, "linux,iommu-force-on", NULL, 0);
+
+ if (RELOC(prom_tce_alloc_start)) {
+ prom_setprop(_prom->chosen, "linux,tce-alloc-start",
+ &RELOC(prom_tce_alloc_start),
+ sizeof(prom_tce_alloc_start));
+ prom_setprop(_prom->chosen, "linux,tce-alloc-end",
+ &RELOC(prom_tce_alloc_end),
+ sizeof(prom_tce_alloc_end));
+ }
+#endif
+
+ /*
+ * Fixup any known bugs in the device-tree
+ */
+ fixup_device_tree();
+
+ /*
+ * Now finally create the flattened device-tree
+ */
+ prom_printf("copying OF device tree ...\n");
+ flatten_device_tree();
+
+ /* in case stdin is USB and still active on IBM machines... */
+ prom_close_stdin();
+
+ /*
+ * Call OF "quiesce" method to shut down pending DMA's from
+ * devices etc...
+ */
+ prom_printf("Calling quiesce ...\n");
+ call_prom("quiesce", 0, 0);
+
+ /*
+ * And finally, call the kernel passing it the flattened device
+ * tree and NULL as r5, thus triggering the new entry point which
+ * is common to us and kexec
+ */
+ hdr = RELOC(dt_header_start);
+ prom_printf("returning from prom_init\n");
+ prom_debug("->dt_header_start=0x%x\n", hdr);
+
+#ifdef CONFIG_PPC32
+ reloc_got2(-offset);
+#endif
+
+ __start(hdr, KERNELBASE + offset, 0);
+
+ return 0;
+}
diff --git a/arch/ppc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index e7aee4108dea..568ea335d616 100644
--- a/arch/ppc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/kernel/ptrace.c
- *
* PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
*
@@ -10,13 +8,14 @@
* linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
*
* Modified by Cort Dougan (cort@hq.fsmlabs.com)
- * and Paul Mackerras (paulus@linuxcare.com.au).
+ * and Paul Mackerras (paulus@samba.org).
*
* This file is subject to the terms and conditions of the GNU General
* Public License. See the file README.legal in the main directory of
* this archive for more details.
*/
+#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
@@ -29,13 +28,19 @@
#include <linux/signal.h>
#include <linux/seccomp.h>
#include <linux/audit.h>
+#ifdef CONFIG_PPC32
#include <linux/module.h>
+#endif
#include <asm/uaccess.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/system.h>
+#ifdef CONFIG_PPC64
+#include <asm/ptrace-common.h>
+#endif
+#ifdef CONFIG_PPC32
/*
* Set of msr bits that gdb can change on behalf of a process.
*/
@@ -44,12 +49,14 @@
#else
#define MSR_DEBUGCHANGE (MSR_SE | MSR_BE)
#endif
+#endif /* CONFIG_PPC32 */
/*
* does not yet catch signals sent when the child dies.
* in exit.c or in signal.c.
*/
+#ifdef CONFIG_PPC32
/*
* Get contents of register REGNO in task TASK.
*/
@@ -228,6 +235,7 @@ clear_single_step(struct task_struct *task)
#endif
}
}
+#endif /* CONFIG_PPC32 */
/*
* Called by kernel/ptrace.c when detaching..
@@ -240,7 +248,7 @@ void ptrace_disable(struct task_struct *child)
clear_single_step(child);
}
-int sys_ptrace(long request, long pid, long addr, long data)
+long sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
int ret = -EPERM;
@@ -296,25 +304,28 @@ int sys_ptrace(long request, long pid, long addr, long data)
}
/* read the word at location addr in the USER area. */
- /* XXX this will need fixing for 64-bit */
case PTRACE_PEEKUSR: {
unsigned long index, tmp;
ret = -EIO;
/* convert to index and check */
+#ifdef CONFIG_PPC32
index = (unsigned long) addr >> 2;
- if ((addr & 3) || index > PT_FPSCR
- || child->thread.regs == NULL)
+ if ((addr & 3) || (index > PT_FPSCR)
+ || (child->thread.regs == NULL))
+#else
+ index = (unsigned long) addr >> 3;
+ if ((addr & 7) || (index > PT_FPSCR))
+#endif
break;
+#ifdef CONFIG_PPC32
CHECK_FULL_REGS(child->thread.regs);
+#endif
if (index < PT_FPR0) {
tmp = get_reg(child, (int) index);
} else {
- preempt_disable();
- if (child->thread.regs->msr & MSR_FP)
- giveup_fpu(child);
- preempt_enable();
+ flush_fp_to_thread(child);
tmp = ((unsigned long *)child->thread.fpr)[index - PT_FPR0];
}
ret = put_user(tmp,(unsigned long __user *) data);
@@ -325,7 +336,8 @@ int sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA:
ret = 0;
- if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
+ if (access_process_vm(child, addr, &data, sizeof(data), 1)
+ == sizeof(data))
break;
ret = -EIO;
break;
@@ -336,21 +348,25 @@ int sys_ptrace(long request, long pid, long addr, long data)
ret = -EIO;
/* convert to index and check */
+#ifdef CONFIG_PPC32
index = (unsigned long) addr >> 2;
- if ((addr & 3) || index > PT_FPSCR
- || child->thread.regs == NULL)
+ if ((addr & 3) || (index > PT_FPSCR)
+ || (child->thread.regs == NULL))
+#else
+ index = (unsigned long) addr >> 3;
+ if ((addr & 7) || (index > PT_FPSCR))
+#endif
break;
+#ifdef CONFIG_PPC32
CHECK_FULL_REGS(child->thread.regs);
+#endif
if (index == PT_ORIG_R3)
break;
if (index < PT_FPR0) {
ret = put_reg(child, index, data);
} else {
- preempt_disable();
- if (child->thread.regs->msr & MSR_FP)
- giveup_fpu(child);
- preempt_enable();
+ flush_fp_to_thread(child);
((unsigned long *)child->thread.fpr)[index - PT_FPR0] = data;
ret = 0;
}
@@ -362,11 +378,10 @@ int sys_ptrace(long request, long pid, long addr, long data)
ret = -EIO;
if (!valid_signal(data))
break;
- if (request == PTRACE_SYSCALL) {
+ if (request == PTRACE_SYSCALL)
set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- } else {
+ else
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- }
child->exit_code = data;
/* make sure the single step bit is not set. */
clear_single_step(child);
@@ -404,28 +419,102 @@ int sys_ptrace(long request, long pid, long addr, long data)
break;
}
+#ifdef CONFIG_PPC64
+ case PTRACE_GET_DEBUGREG: {
+ ret = -EINVAL;
+ /* We only support one DABR and no IABRS at the moment */
+ if (addr > 0)
+ break;
+ ret = put_user(child->thread.dabr,
+ (unsigned long __user *)data);
+ break;
+ }
+
+ case PTRACE_SET_DEBUGREG:
+ ret = ptrace_set_debugreg(child, addr, data);
+ break;
+#endif
+
case PTRACE_DETACH:
ret = ptrace_detach(child, data);
break;
+#ifdef CONFIG_PPC64
+ case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */
+ int i;
+ unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
+ unsigned long __user *tmp = (unsigned long __user *)addr;
+
+ for (i = 0; i < 32; i++) {
+ ret = put_user(*reg, tmp);
+ if (ret)
+ break;
+ reg++;
+ tmp++;
+ }
+ break;
+ }
+
+ case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */
+ int i;
+ unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
+ unsigned long __user *tmp = (unsigned long __user *)addr;
+
+ for (i = 0; i < 32; i++) {
+ ret = get_user(*reg, tmp);
+ if (ret)
+ break;
+ reg++;
+ tmp++;
+ }
+ break;
+ }
+
+ case PPC_PTRACE_GETFPREGS: { /* Get FPRs 0 - 31. */
+ int i;
+ unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
+ unsigned long __user *tmp = (unsigned long __user *)addr;
+
+ flush_fp_to_thread(child);
+
+ for (i = 0; i < 32; i++) {
+ ret = put_user(*reg, tmp);
+ if (ret)
+ break;
+ reg++;
+ tmp++;
+ }
+ break;
+ }
+
+ case PPC_PTRACE_SETFPREGS: { /* Get FPRs 0 - 31. */
+ int i;
+ unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
+ unsigned long __user *tmp = (unsigned long __user *)addr;
+
+ flush_fp_to_thread(child);
+
+ for (i = 0; i < 32; i++) {
+ ret = get_user(*reg, tmp);
+ if (ret)
+ break;
+ reg++;
+ tmp++;
+ }
+ break;
+ }
+#endif /* CONFIG_PPC64 */
+
#ifdef CONFIG_ALTIVEC
case PTRACE_GETVRREGS:
/* Get the child altivec register state. */
- preempt_disable();
- if (child->thread.regs->msr & MSR_VEC)
- giveup_altivec(child);
- preempt_enable();
+ flush_altivec_to_thread(child);
ret = get_vrregs((unsigned long __user *)data, child);
break;
case PTRACE_SETVRREGS:
/* Set the child altivec register state. */
- /* this is to clear the MSR_VEC bit to force a reload
- * of register state from memory */
- preempt_disable();
- if (child->thread.regs->msr & MSR_VEC)
- giveup_altivec(child);
- preempt_enable();
+ flush_altivec_to_thread(child);
ret = set_vrregs(child, (unsigned long __user *)data);
break;
#endif
@@ -478,12 +567,21 @@ static void do_syscall_trace(void)
void do_syscall_trace_enter(struct pt_regs *regs)
{
+#ifdef CONFIG_PPC64
+ secure_computing(regs->gpr[0]);
+#endif
+
if (test_thread_flag(TIF_SYSCALL_TRACE)
&& (current->ptrace & PT_PTRACED))
do_syscall_trace();
if (unlikely(current->audit_context))
- audit_syscall_entry(current, AUDIT_ARCH_PPC,
+ audit_syscall_entry(current,
+#ifdef CONFIG_PPC32
+ AUDIT_ARCH_PPC,
+#else
+ test_thread_flag(TIF_32BIT)?AUDIT_ARCH_PPC:AUDIT_ARCH_PPC64,
+#endif
regs->gpr[0],
regs->gpr[3], regs->gpr[4],
regs->gpr[5], regs->gpr[6]);
@@ -491,17 +589,25 @@ void do_syscall_trace_enter(struct pt_regs *regs)
void do_syscall_trace_leave(struct pt_regs *regs)
{
+#ifdef CONFIG_PPC32
secure_computing(regs->gpr[0]);
+#endif
if (unlikely(current->audit_context))
audit_syscall_exit(current,
(regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
regs->result);
- if ((test_thread_flag(TIF_SYSCALL_TRACE))
+ if ((test_thread_flag(TIF_SYSCALL_TRACE)
+#ifdef CONFIG_PPC64
+ || test_thread_flag(TIF_SINGLESTEP)
+#endif
+ )
&& (current->ptrace & PT_PTRACED))
do_syscall_trace();
}
+#ifdef CONFIG_PPC32
EXPORT_SYMBOL(do_syscall_trace_enter);
EXPORT_SYMBOL(do_syscall_trace_leave);
+#endif
diff --git a/arch/ppc64/kernel/ptrace32.c b/arch/powerpc/kernel/ptrace32.c
index fb8c22d6084a..91eb952e0293 100644
--- a/arch/ppc64/kernel/ptrace32.c
+++ b/arch/powerpc/kernel/ptrace32.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/ppc64/kernel/ptrace32.c
+ * ptrace for 32-bit processes running on a 64-bit kernel.
*
* PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
@@ -10,10 +10,10 @@
* linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
*
* Modified by Cort Dougan (cort@hq.fsmlabs.com)
- * and Paul Mackerras (paulus@linuxcare.com.au).
+ * and Paul Mackerras (paulus@samba.org).
*
* This file is subject to the terms and conditions of the GNU General
- * Public License. See the file README.legal in the main directory of
+ * Public License. See the file COPYING in the main directory of
* this archive for more details.
*/
@@ -40,7 +40,8 @@
* in exit.c or in signal.c.
*/
-int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data)
+long compat_sys_ptrace(int request, int pid, unsigned long addr,
+ unsigned long data)
{
struct task_struct *child;
int ret = -EPERM;
diff --git a/arch/ppc64/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 5e8eb33b8e54..4d22eeeeb91d 100644
--- a/arch/ppc64/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -25,28 +25,29 @@
#include <asm/page.h>
#include <asm/param.h>
#include <asm/system.h>
-#include <asm/abs_addr.h>
-#include <asm/udbg.h>
#include <asm/delay.h>
#include <asm/uaccess.h>
+#include <asm/lmb.h>
+#ifdef CONFIG_PPC64
#include <asm/systemcfg.h>
+#endif
-struct flash_block_list_header rtas_firmware_flash_list = {0, NULL};
-
-struct rtas_t rtas = {
+struct rtas_t rtas = {
.lock = SPIN_LOCK_UNLOCKED
};
EXPORT_SYMBOL(rtas);
-char rtas_err_buf[RTAS_ERROR_LOG_MAX];
-
DEFINE_SPINLOCK(rtas_data_buf_lock);
-char rtas_data_buf[RTAS_DATA_BUF_SIZE]__page_aligned;
+char rtas_data_buf[RTAS_DATA_BUF_SIZE] __cacheline_aligned;
unsigned long rtas_rmo_buf;
-void
-call_rtas_display_status(unsigned char c)
+/*
+ * call_rtas_display_status and call_rtas_display_status_delay
+ * are designed only for very early low-level debugging, which
+ * is why the token is hard-coded to 10.
+ */
+void call_rtas_display_status(unsigned char c)
{
struct rtas_args *args = &rtas.args;
unsigned long s;
@@ -66,8 +67,7 @@ call_rtas_display_status(unsigned char c)
spin_unlock_irqrestore(&rtas.lock, s);
}
-void
-call_rtas_display_status_delay(unsigned char c)
+void call_rtas_display_status_delay(unsigned char c)
{
static int pending_newline = 0; /* did last write end with unprinted newline? */
static int width = 16;
@@ -91,8 +91,7 @@ call_rtas_display_status_delay(unsigned char c)
}
}
-void
-rtas_progress(char *s, unsigned short hex)
+void rtas_progress(char *s, unsigned short hex)
{
struct device_node *root;
int width, *p;
@@ -208,18 +207,16 @@ rtas_progress(char *s, unsigned short hex)
spin_unlock(&progress_lock);
}
-int
-rtas_token(const char *service)
+int rtas_token(const char *service)
{
int *tokp;
- if (rtas.dev == NULL) {
- PPCDBG(PPCDBG_RTAS,"\tNo rtas device in device-tree...\n");
+ if (rtas.dev == NULL)
return RTAS_UNKNOWN_SERVICE;
- }
tokp = (int *) get_property(rtas.dev, service, NULL);
return tokp ? *tokp : RTAS_UNKNOWN_SERVICE;
}
+#ifdef CONFIG_RTAS_ERROR_LOGGING
/*
* Return the firmware-specified size of the error log buffer
* for all rtas calls that require an error buffer argument.
@@ -234,31 +231,38 @@ int rtas_get_error_log_max(void)
rtas_error_log_max = rtas_token ("rtas-error-log-max");
if ((rtas_error_log_max == RTAS_UNKNOWN_SERVICE) ||
(rtas_error_log_max > RTAS_ERROR_LOG_MAX)) {
- printk (KERN_WARNING "RTAS: bad log buffer size %d\n", rtas_error_log_max);
+ printk (KERN_WARNING "RTAS: bad log buffer size %d\n",
+ rtas_error_log_max);
rtas_error_log_max = RTAS_ERROR_LOG_MAX;
}
return rtas_error_log_max;
}
+EXPORT_SYMBOL(rtas_get_error_log_max);
+char rtas_err_buf[RTAS_ERROR_LOG_MAX];
+int rtas_last_error_token;
+
/** Return a copy of the detailed error text associated with the
* most recent failed call to rtas. Because the error text
* might go stale if there are any other intervening rtas calls,
* this routine must be called atomically with whatever produced
* the error (i.e. with rtas.lock still held from the previous call).
*/
-static int
-__fetch_rtas_last_error(void)
+static char *__fetch_rtas_last_error(char *altbuf)
{
struct rtas_args err_args, save_args;
u32 bufsz;
+ char *buf = NULL;
+
+ if (rtas_last_error_token == -1)
+ return NULL;
bufsz = rtas_get_error_log_max();
- err_args.token = rtas_token("rtas-last-error");
+ err_args.token = rtas_last_error_token;
err_args.nargs = 2;
err_args.nret = 1;
-
err_args.args[0] = (rtas_arg_t)__pa(rtas_err_buf);
err_args.args[1] = bufsz;
err_args.args[2] = 0;
@@ -271,23 +275,38 @@ __fetch_rtas_last_error(void)
err_args = rtas.args;
rtas.args = save_args;
- return err_args.args[2];
+ /* Log the error in the unlikely case that there was one. */
+ if (unlikely(err_args.args[2] == 0)) {
+ if (altbuf) {
+ buf = altbuf;
+ } else {
+ buf = rtas_err_buf;
+ if (mem_init_done)
+ buf = kmalloc(RTAS_ERROR_LOG_MAX, GFP_ATOMIC);
+ }
+ if (buf)
+ memcpy(buf, rtas_err_buf, RTAS_ERROR_LOG_MAX);
+ }
+
+ return buf;
}
+#define get_errorlog_buffer() kmalloc(RTAS_ERROR_LOG_MAX, GFP_KERNEL)
+
+#else /* CONFIG_RTAS_ERROR_LOGGING */
+#define __fetch_rtas_last_error(x) NULL
+#define get_errorlog_buffer() NULL
+#endif
+
int rtas_call(int token, int nargs, int nret, int *outputs, ...)
{
va_list list;
- int i, logit = 0;
+ int i;
unsigned long s;
struct rtas_args *rtas_args;
- char * buff_copy = NULL;
+ char *buff_copy = NULL;
int ret;
- PPCDBG(PPCDBG_RTAS, "Entering rtas_call\n");
- PPCDBG(PPCDBG_RTAS, "\ttoken = 0x%x\n", token);
- PPCDBG(PPCDBG_RTAS, "\tnargs = %d\n", nargs);
- PPCDBG(PPCDBG_RTAS, "\tnret = %d\n", nret);
- PPCDBG(PPCDBG_RTAS, "\t&outputs = 0x%lx\n", outputs);
if (token == RTAS_UNKNOWN_SERVICE)
return -1;
@@ -300,46 +319,25 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...)
rtas_args->nret = nret;
rtas_args->rets = (rtas_arg_t *)&(rtas_args->args[nargs]);
va_start(list, outputs);
- for (i = 0; i < nargs; ++i) {
+ for (i = 0; i < nargs; ++i)
rtas_args->args[i] = va_arg(list, rtas_arg_t);
- PPCDBG(PPCDBG_RTAS, "\tnarg[%d] = 0x%x\n", i, rtas_args->args[i]);
- }
va_end(list);
for (i = 0; i < nret; ++i)
rtas_args->rets[i] = 0;
- PPCDBG(PPCDBG_RTAS, "\tentering rtas with 0x%lx\n",
- __pa(rtas_args));
enter_rtas(__pa(rtas_args));
- PPCDBG(PPCDBG_RTAS, "\treturned from rtas ...\n");
/* A -1 return code indicates that the last command couldn't
be completed due to a hardware error. */
if (rtas_args->rets[0] == -1)
- logit = (__fetch_rtas_last_error() == 0);
-
- ifppcdebug(PPCDBG_RTAS) {
- for(i=0; i < nret ;i++)
- udbg_printf("\tnret[%d] = 0x%lx\n", i, (ulong)rtas_args->rets[i]);
- }
+ buff_copy = __fetch_rtas_last_error(NULL);
if (nret > 1 && outputs != NULL)
for (i = 0; i < nret-1; ++i)
outputs[i] = rtas_args->rets[i+1];
ret = (nret > 0)? rtas_args->rets[0]: 0;
- /* Log the error in the unlikely case that there was one. */
- if (unlikely(logit)) {
- buff_copy = rtas_err_buf;
- if (mem_init_done) {
- buff_copy = kmalloc(RTAS_ERROR_LOG_MAX, GFP_ATOMIC);
- if (buff_copy)
- memcpy(buff_copy, rtas_err_buf,
- RTAS_ERROR_LOG_MAX);
- }
- }
-
/* Gotta do something different here, use global lock for now... */
spin_unlock_irqrestore(&rtas.lock, s);
@@ -354,8 +352,7 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...)
/* Given an RTAS status code of 990n compute the hinted delay of 10^n
* (last digit) milliseconds. For now we bound at n=5 (100 sec).
*/
-unsigned int
-rtas_extended_busy_delay_time(int status)
+unsigned int rtas_extended_busy_delay_time(int status)
{
int order = status - 9900;
unsigned long ms;
@@ -366,7 +363,7 @@ rtas_extended_busy_delay_time(int status)
order = 5; /* bound */
/* Use microseconds for reasonable accuracy */
- for (ms=1; order > 0; order--)
+ for (ms = 1; order > 0; order--)
ms *= 10;
return ms;
@@ -493,112 +490,23 @@ int rtas_set_indicator(int indicator, int index, int new_value)
return rc;
}
-#define FLASH_BLOCK_LIST_VERSION (1UL)
-static void
-rtas_flash_firmware(void)
-{
- unsigned long image_size;
- struct flash_block_list *f, *next, *flist;
- unsigned long rtas_block_list;
- int i, status, update_token;
-
- update_token = rtas_token("ibm,update-flash-64-and-reboot");
- if (update_token == RTAS_UNKNOWN_SERVICE) {
- printk(KERN_ALERT "FLASH: ibm,update-flash-64-and-reboot is not available -- not a service partition?\n");
- printk(KERN_ALERT "FLASH: firmware will not be flashed\n");
- return;
- }
-
- /* NOTE: the "first" block list is a global var with no data
- * blocks in the kernel data segment. We do this because
- * we want to ensure this block_list addr is under 4GB.
- */
- rtas_firmware_flash_list.num_blocks = 0;
- flist = (struct flash_block_list *)&rtas_firmware_flash_list;
- rtas_block_list = virt_to_abs(flist);
- if (rtas_block_list >= 4UL*1024*1024*1024) {
- printk(KERN_ALERT "FLASH: kernel bug...flash list header addr above 4GB\n");
- return;
- }
-
- printk(KERN_ALERT "FLASH: preparing saved firmware image for flash\n");
- /* Update the block_list in place. */
- image_size = 0;
- for (f = flist; f; f = next) {
- /* Translate data addrs to absolute */
- for (i = 0; i < f->num_blocks; i++) {
- f->blocks[i].data = (char *)virt_to_abs(f->blocks[i].data);
- image_size += f->blocks[i].length;
- }
- next = f->next;
- /* Don't translate NULL pointer for last entry */
- if (f->next)
- f->next = (struct flash_block_list *)virt_to_abs(f->next);
- else
- f->next = NULL;
- /* make num_blocks into the version/length field */
- f->num_blocks = (FLASH_BLOCK_LIST_VERSION << 56) | ((f->num_blocks+1)*16);
- }
-
- printk(KERN_ALERT "FLASH: flash image is %ld bytes\n", image_size);
- printk(KERN_ALERT "FLASH: performing flash and reboot\n");
- rtas_progress("Flashing \n", 0x0);
- rtas_progress("Please Wait... ", 0x0);
- printk(KERN_ALERT "FLASH: this will take several minutes. Do not power off!\n");
- status = rtas_call(update_token, 1, 1, NULL, rtas_block_list);
- switch (status) { /* should only get "bad" status */
- case 0:
- printk(KERN_ALERT "FLASH: success\n");
- break;
- case -1:
- printk(KERN_ALERT "FLASH: hardware error. Firmware may not be not flashed\n");
- break;
- case -3:
- printk(KERN_ALERT "FLASH: image is corrupt or not correct for this platform. Firmware not flashed\n");
- break;
- case -4:
- printk(KERN_ALERT "FLASH: flash failed when partially complete. System may not reboot\n");
- break;
- default:
- printk(KERN_ALERT "FLASH: unknown flash return code %d\n", status);
- break;
- }
-}
-
-void rtas_flash_bypass_warning(void)
-{
- printk(KERN_ALERT "FLASH: firmware flash requires a reboot\n");
- printk(KERN_ALERT "FLASH: the firmware image will NOT be flashed\n");
-}
-
-
-void
-rtas_restart(char *cmd)
+void rtas_restart(char *cmd)
{
- if (rtas_firmware_flash_list.next)
- rtas_flash_firmware();
-
printk("RTAS system-reboot returned %d\n",
rtas_call(rtas_token("system-reboot"), 0, 1, NULL));
for (;;);
}
-void
-rtas_power_off(void)
+void rtas_power_off(void)
{
- if (rtas_firmware_flash_list.next)
- rtas_flash_bypass_warning();
/* allow power on only with power button press */
printk("RTAS power-off returned %d\n",
rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1));
for (;;);
}
-void
-rtas_halt(void)
+void rtas_halt(void)
{
- if (rtas_firmware_flash_list.next)
- rtas_flash_bypass_warning();
rtas_power_off();
}
@@ -631,9 +539,8 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
{
struct rtas_args args;
unsigned long flags;
- char * buff_copy;
+ char *buff_copy, *errbuf = NULL;
int nargs;
- int err_rc = 0;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
@@ -652,7 +559,7 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
nargs * sizeof(rtas_arg_t)) != 0)
return -EFAULT;
- buff_copy = kmalloc(RTAS_ERROR_LOG_MAX, GFP_KERNEL);
+ buff_copy = get_errorlog_buffer();
spin_lock_irqsave(&rtas.lock, flags);
@@ -664,19 +571,14 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
/* A -1 return code indicates that the last command couldn't
be completed due to a hardware error. */
- if (args.rets[0] == -1) {
- err_rc = __fetch_rtas_last_error();
- if ((err_rc == 0) && buff_copy) {
- memcpy(buff_copy, rtas_err_buf, RTAS_ERROR_LOG_MAX);
- }
- }
+ if (args.rets[0] == -1)
+ errbuf = __fetch_rtas_last_error(buff_copy);
spin_unlock_irqrestore(&rtas.lock, flags);
if (buff_copy) {
- if ((args.rets[0] == -1) && (err_rc == 0)) {
- log_error(buff_copy, ERR_TYPE_RTAS_LOG, 0);
- }
+ if (errbuf)
+ log_error(errbuf, ERR_TYPE_RTAS_LOG, 0);
kfree(buff_copy);
}
@@ -689,6 +591,7 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
return 0;
}
+#ifdef CONFIG_SMP
/* This version can't take the spinlock, because it never returns */
struct rtas_args rtas_stop_self_args = {
@@ -713,6 +616,7 @@ void rtas_stop_self(void)
panic("Alas, I survived.\n");
}
+#endif
/*
* Call early during boot, before mem init or bootmem, to retreive the RTAS
@@ -721,6 +625,8 @@ void rtas_stop_self(void)
*/
void __init rtas_initialize(void)
{
+ unsigned long rtas_region = RTAS_INSTANTIATE_MAX;
+
/* Get RTAS dev node and fill up our "rtas" structure with infos
* about it.
*/
@@ -742,26 +648,27 @@ void __init rtas_initialize(void)
} else
rtas.dev = NULL;
}
+ if (!rtas.dev)
+ return;
+
/* If RTAS was found, allocate the RMO buffer for it and look for
* the stop-self token if any
*/
- if (rtas.dev) {
- unsigned long rtas_region = RTAS_INSTANTIATE_MAX;
- if (systemcfg->platform == PLATFORM_PSERIES_LPAR)
- rtas_region = min(lmb.rmo_size, RTAS_INSTANTIATE_MAX);
-
- rtas_rmo_buf = lmb_alloc_base(RTAS_RMOBUF_MAX, PAGE_SIZE,
- rtas_region);
+#ifdef CONFIG_PPC64
+ if (systemcfg->platform == PLATFORM_PSERIES_LPAR)
+ rtas_region = min(lmb.rmo_size, RTAS_INSTANTIATE_MAX);
+#endif
+ rtas_rmo_buf = lmb_alloc_base(RTAS_RMOBUF_MAX, PAGE_SIZE, rtas_region);
#ifdef CONFIG_HOTPLUG_CPU
- rtas_stop_self_args.token = rtas_token("stop-self");
+ rtas_stop_self_args.token = rtas_token("stop-self");
#endif /* CONFIG_HOTPLUG_CPU */
- }
-
+#ifdef CONFIG_RTAS_ERROR_LOGGING
+ rtas_last_error_token = rtas_token("rtas-last-error");
+#endif
}
-EXPORT_SYMBOL(rtas_firmware_flash_list);
EXPORT_SYMBOL(rtas_token);
EXPORT_SYMBOL(rtas_call);
EXPORT_SYMBOL(rtas_data_buf);
@@ -771,4 +678,3 @@ EXPORT_SYMBOL(rtas_get_sensor);
EXPORT_SYMBOL(rtas_get_power_level);
EXPORT_SYMBOL(rtas_set_power_level);
EXPORT_SYMBOL(rtas_set_indicator);
-EXPORT_SYMBOL(rtas_get_error_log_max);
diff --git a/arch/powerpc/kernel/semaphore.c b/arch/powerpc/kernel/semaphore.c
new file mode 100644
index 000000000000..2f8c3c951394
--- /dev/null
+++ b/arch/powerpc/kernel/semaphore.c
@@ -0,0 +1,135 @@
+/*
+ * PowerPC-specific semaphore code.
+ *
+ * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu>
+ *
+ * This program is free software; you can redistribute 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.
+ *
+ * April 2001 - Reworked by Paul Mackerras <paulus@samba.org>
+ * to eliminate the SMP races in the old version between the updates
+ * of `count' and `waking'. Now we use negative `count' values to
+ * indicate that some process(es) are waiting for the semaphore.
+ */
+
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include <asm/atomic.h>
+#include <asm/semaphore.h>
+#include <asm/errno.h>
+
+/*
+ * Atomically update sem->count.
+ * This does the equivalent of the following:
+ *
+ * old_count = sem->count;
+ * tmp = MAX(old_count, 0) + incr;
+ * sem->count = tmp;
+ * return old_count;
+ */
+static inline int __sem_update_count(struct semaphore *sem, int incr)
+{
+ int old_count, tmp;
+
+ __asm__ __volatile__("\n"
+"1: lwarx %0,0,%3\n"
+" srawi %1,%0,31\n"
+" andc %1,%0,%1\n"
+" add %1,%1,%4\n"
+ PPC405_ERR77(0,%3)
+" stwcx. %1,0,%3\n"
+" bne 1b"
+ : "=&r" (old_count), "=&r" (tmp), "=m" (sem->count)
+ : "r" (&sem->count), "r" (incr), "m" (sem->count)
+ : "cc");
+
+ return old_count;
+}
+
+void __up(struct semaphore *sem)
+{
+ /*
+ * Note that we incremented count in up() before we came here,
+ * but that was ineffective since the result was <= 0, and
+ * any negative value of count is equivalent to 0.
+ * This ends up setting count to 1, unless count is now > 0
+ * (i.e. because some other cpu has called up() in the meantime),
+ * in which case we just increment count.
+ */
+ __sem_update_count(sem, 1);
+ wake_up(&sem->wait);
+}
+EXPORT_SYMBOL(__up);
+
+/*
+ * Note that when we come in to __down or __down_interruptible,
+ * we have already decremented count, but that decrement was
+ * ineffective since the result was < 0, and any negative value
+ * of count is equivalent to 0.
+ * Thus it is only when we decrement count from some value > 0
+ * that we have actually got the semaphore.
+ */
+void __sched __down(struct semaphore *sem)
+{
+ struct task_struct *tsk = current;
+ DECLARE_WAITQUEUE(wait, tsk);
+
+ __set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+ add_wait_queue_exclusive(&sem->wait, &wait);
+
+ /*
+ * Try to get the semaphore. If the count is > 0, then we've
+ * got the semaphore; we decrement count and exit the loop.
+ * If the count is 0 or negative, we set it to -1, indicating
+ * that we are asleep, and then sleep.
+ */
+ while (__sem_update_count(sem, -1) <= 0) {
+ schedule();
+ set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+ }
+ remove_wait_queue(&sem->wait, &wait);
+ __set_task_state(tsk, TASK_RUNNING);
+
+ /*
+ * If there are any more sleepers, wake one of them up so
+ * that it can either get the semaphore, or set count to -1
+ * indicating that there are still processes sleeping.
+ */
+ wake_up(&sem->wait);
+}
+EXPORT_SYMBOL(__down);
+
+int __sched __down_interruptible(struct semaphore * sem)
+{
+ int retval = 0;
+ struct task_struct *tsk = current;
+ DECLARE_WAITQUEUE(wait, tsk);
+
+ __set_task_state(tsk, TASK_INTERRUPTIBLE);
+ add_wait_queue_exclusive(&sem->wait, &wait);
+
+ while (__sem_update_count(sem, -1) <= 0) {
+ if (signal_pending(current)) {
+ /*
+ * A signal is pending - give up trying.
+ * Set sem->count to 0 if it is negative,
+ * since we are no longer sleeping.
+ */
+ __sem_update_count(sem, 0);
+ retval = -EINTR;
+ break;
+ }
+ schedule();
+ set_task_state(tsk, TASK_INTERRUPTIBLE);
+ }
+ remove_wait_queue(&sem->wait, &wait);
+ __set_task_state(tsk, TASK_RUNNING);
+
+ wake_up(&sem->wait);
+ return retval;
+}
+EXPORT_SYMBOL(__down_interruptible);
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
new file mode 100644
index 000000000000..1292460fcde2
--- /dev/null
+++ b/arch/powerpc/kernel/setup-common.c
@@ -0,0 +1,410 @@
+/*
+ * Common boot and setup code for both 32-bit and 64-bit.
+ * Extracted from arch/powerpc/kernel/setup_64.c.
+ *
+ * Copyright (C) 2001 PPC64 Team, IBM Corp
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/reboot.h>
+#include <linux/delay.h>
+#include <linux/initrd.h>
+#include <linux/ide.h>
+#include <linux/seq_file.h>
+#include <linux/ioport.h>
+#include <linux/console.h>
+#include <linux/utsname.h>
+#include <linux/tty.h>
+#include <linux/root_dev.h>
+#include <linux/notifier.h>
+#include <linux/cpu.h>
+#include <linux/unistd.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/processor.h>
+#include <asm/pgtable.h>
+#include <asm/smp.h>
+#include <asm/elf.h>
+#include <asm/machdep.h>
+#include <asm/time.h>
+#include <asm/cputable.h>
+#include <asm/sections.h>
+#include <asm/btext.h>
+#include <asm/nvram.h>
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/rtas.h>
+#include <asm/iommu.h>
+#include <asm/serial.h>
+#include <asm/cache.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+#include <asm/lmb.h>
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(fmt...) udbg_printf(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+/*
+ * This still seems to be needed... -- paulus
+ */
+struct screen_info screen_info = {
+ .orig_x = 0,
+ .orig_y = 25,
+ .orig_video_cols = 80,
+ .orig_video_lines = 25,
+ .orig_video_isVGA = 1,
+ .orig_video_points = 16
+};
+
+#ifdef __DO_IRQ_CANON
+/* XXX should go elsewhere eventually */
+int ppc_do_canonicalize_irqs;
+EXPORT_SYMBOL(ppc_do_canonicalize_irqs);
+#endif
+
+/* also used by kexec */
+void machine_shutdown(void)
+{
+ if (ppc_md.nvram_sync)
+ ppc_md.nvram_sync();
+}
+
+void machine_restart(char *cmd)
+{
+ machine_shutdown();
+ ppc_md.restart(cmd);
+#ifdef CONFIG_SMP
+ smp_send_stop();
+#endif
+ printk(KERN_EMERG "System Halted, OK to turn off power\n");
+ local_irq_disable();
+ while (1) ;
+}
+
+void machine_power_off(void)
+{
+ machine_shutdown();
+ ppc_md.power_off();
+#ifdef CONFIG_SMP
+ smp_send_stop();
+#endif
+ printk(KERN_EMERG "System Halted, OK to turn off power\n");
+ local_irq_disable();
+ while (1) ;
+}
+/* Used by the G5 thermal driver */
+EXPORT_SYMBOL_GPL(machine_power_off);
+
+void (*pm_power_off)(void) = machine_power_off;
+EXPORT_SYMBOL_GPL(pm_power_off);
+
+void machine_halt(void)
+{
+ machine_shutdown();
+ ppc_md.halt();
+#ifdef CONFIG_SMP
+ smp_send_stop();
+#endif
+ printk(KERN_EMERG "System Halted, OK to turn off power\n");
+ local_irq_disable();
+ while (1) ;
+}
+
+
+#ifdef CONFIG_TAU
+extern u32 cpu_temp(unsigned long cpu);
+extern u32 cpu_temp_both(unsigned long cpu);
+#endif /* CONFIG_TAU */
+
+#ifdef CONFIG_SMP
+DEFINE_PER_CPU(unsigned int, pvr);
+#endif
+
+static int show_cpuinfo(struct seq_file *m, void *v)
+{
+ unsigned long cpu_id = (unsigned long)v - 1;
+ unsigned int pvr;
+ unsigned short maj;
+ unsigned short min;
+
+ if (cpu_id == NR_CPUS) {
+#if defined(CONFIG_SMP) && defined(CONFIG_PPC32)
+ unsigned long bogosum = 0;
+ int i;
+ for (i = 0; i < NR_CPUS; ++i)
+ if (cpu_online(i))
+ bogosum += loops_per_jiffy;
+ seq_printf(m, "total bogomips\t: %lu.%02lu\n",
+ bogosum/(500000/HZ), bogosum/(5000/HZ) % 100);
+#endif /* CONFIG_SMP && CONFIG_PPC32 */
+ seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq);
+
+ if (ppc_md.show_cpuinfo != NULL)
+ ppc_md.show_cpuinfo(m);
+
+ return 0;
+ }
+
+ /* We only show online cpus: disable preempt (overzealous, I
+ * knew) to prevent cpu going down. */
+ preempt_disable();
+ if (!cpu_online(cpu_id)) {
+ preempt_enable();
+ return 0;
+ }
+
+#ifdef CONFIG_SMP
+#ifdef CONFIG_PPC64 /* XXX for now */
+ pvr = per_cpu(pvr, cpu_id);
+#else
+ pvr = cpu_data[cpu_id].pvr;
+#endif
+#else
+ pvr = mfspr(SPRN_PVR);
+#endif
+ maj = (pvr >> 8) & 0xFF;
+ min = pvr & 0xFF;
+
+ seq_printf(m, "processor\t: %lu\n", cpu_id);
+ seq_printf(m, "cpu\t\t: ");
+
+ if (cur_cpu_spec->pvr_mask)
+ seq_printf(m, "%s", cur_cpu_spec->cpu_name);
+ else
+ seq_printf(m, "unknown (%08x)", pvr);
+
+#ifdef CONFIG_ALTIVEC
+ if (cpu_has_feature(CPU_FTR_ALTIVEC))
+ seq_printf(m, ", altivec supported");
+#endif /* CONFIG_ALTIVEC */
+
+ seq_printf(m, "\n");
+
+#ifdef CONFIG_TAU
+ if (cur_cpu_spec->cpu_features & CPU_FTR_TAU) {
+#ifdef CONFIG_TAU_AVERAGE
+ /* more straightforward, but potentially misleading */
+ seq_printf(m, "temperature \t: %u C (uncalibrated)\n",
+ cpu_temp(i));
+#else
+ /* show the actual temp sensor range */
+ u32 temp;
+ temp = cpu_temp_both(i);
+ seq_printf(m, "temperature \t: %u-%u C (uncalibrated)\n",
+ temp & 0xff, temp >> 16);
+#endif
+ }
+#endif /* CONFIG_TAU */
+
+ /*
+ * Assume here that all clock rates are the same in a
+ * smp system. -- Cort
+ */
+ if (ppc_proc_freq)
+ seq_printf(m, "clock\t\t: %lu.%06luMHz\n",
+ ppc_proc_freq / 1000000, ppc_proc_freq % 1000000);
+
+ if (ppc_md.show_percpuinfo != NULL)
+ ppc_md.show_percpuinfo(m, cpu_id);
+
+ /* If we are a Freescale core do a simple check so
+ * we dont have to keep adding cases in the future */
+ if (PVR_VER(pvr) & 0x8000) {
+ maj = PVR_MAJ(pvr);
+ min = PVR_MIN(pvr);
+ } else {
+ switch (PVR_VER(pvr)) {
+ case 0x0020: /* 403 family */
+ maj = PVR_MAJ(pvr) + 1;
+ min = PVR_MIN(pvr);
+ break;
+ case 0x1008: /* 740P/750P ?? */
+ maj = ((pvr >> 8) & 0xFF) - 1;
+ min = pvr & 0xFF;
+ break;
+ default:
+ maj = (pvr >> 8) & 0xFF;
+ min = pvr & 0xFF;
+ break;
+ }
+ }
+
+ seq_printf(m, "revision\t: %hd.%hd (pvr %04x %04x)\n",
+ maj, min, PVR_VER(pvr), PVR_REV(pvr));
+
+#ifdef CONFIG_PPC32
+ seq_printf(m, "bogomips\t: %lu.%02lu\n",
+ loops_per_jiffy / (500000/HZ),
+ (loops_per_jiffy / (5000/HZ)) % 100);
+#endif
+
+#ifdef CONFIG_SMP
+ seq_printf(m, "\n");
+#endif
+
+ preempt_enable();
+ return 0;
+}
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+ unsigned long i = *pos;
+
+ return i <= NR_CPUS ? (void *)(i + 1) : NULL;
+}
+
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ ++*pos;
+ return c_start(m, pos);
+}
+
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+
+struct seq_operations cpuinfo_op = {
+ .start =c_start,
+ .next = c_next,
+ .stop = c_stop,
+ .show = show_cpuinfo,
+};
+
+#ifdef CONFIG_PPC_MULTIPLATFORM
+static int __init set_preferred_console(void)
+{
+ struct device_node *prom_stdout = NULL;
+ char *name;
+ u32 *spd;
+ int offset = 0;
+
+ DBG(" -> set_preferred_console()\n");
+
+ /* The user has requested a console so this is already set up. */
+ if (strstr(saved_command_line, "console=")) {
+ DBG(" console was specified !\n");
+ return -EBUSY;
+ }
+
+ if (!of_chosen) {
+ DBG(" of_chosen is NULL !\n");
+ return -ENODEV;
+ }
+ /* We are getting a weird phandle from OF ... */
+ /* ... So use the full path instead */
+ name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
+ if (name == NULL) {
+ DBG(" no linux,stdout-path !\n");
+ return -ENODEV;
+ }
+ prom_stdout = of_find_node_by_path(name);
+ if (!prom_stdout) {
+ DBG(" can't find stdout package %s !\n", name);
+ return -ENODEV;
+ }
+ DBG("stdout is %s\n", prom_stdout->full_name);
+
+ name = (char *)get_property(prom_stdout, "name", NULL);
+ if (!name) {
+ DBG(" stdout package has no name !\n");
+ goto not_found;
+ }
+ spd = (u32 *)get_property(prom_stdout, "current-speed", NULL);
+
+ if (0)
+ ;
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+ else if (strcmp(name, "serial") == 0) {
+ int i;
+ u32 *reg = (u32 *)get_property(prom_stdout, "reg", &i);
+ if (i > 8) {
+ switch (reg[1]) {
+ case 0x3f8:
+ offset = 0;
+ break;
+ case 0x2f8:
+ offset = 1;
+ break;
+ case 0x898:
+ offset = 2;
+ break;
+ case 0x890:
+ offset = 3;
+ break;
+ default:
+ /* We dont recognise the serial port */
+ goto not_found;
+ }
+ }
+ }
+#endif /* CONFIG_SERIAL_8250_CONSOLE */
+#ifdef CONFIG_PPC_PSERIES
+ else if (strcmp(name, "vty") == 0) {
+ u32 *reg = (u32 *)get_property(prom_stdout, "reg", NULL);
+ char *compat = (char *)get_property(prom_stdout, "compatible", NULL);
+
+ if (reg && compat && (strcmp(compat, "hvterm-protocol") == 0)) {
+ /* Host Virtual Serial Interface */
+ switch (reg[0]) {
+ case 0x30000000:
+ offset = 0;
+ break;
+ case 0x30000001:
+ offset = 1;
+ break;
+ default:
+ goto not_found;
+ }
+ of_node_put(prom_stdout);
+ DBG("Found hvsi console at offset %d\n", offset);
+ return add_preferred_console("hvsi", offset, NULL);
+ } else {
+ /* pSeries LPAR virtual console */
+ of_node_put(prom_stdout);
+ DBG("Found hvc console\n");
+ return add_preferred_console("hvc", 0, NULL);
+ }
+ }
+#endif /* CONFIG_PPC_PSERIES */
+#ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE
+ else if (strcmp(name, "ch-a") == 0)
+ offset = 0;
+ else if (strcmp(name, "ch-b") == 0)
+ offset = 1;
+#endif /* CONFIG_SERIAL_PMACZILOG_CONSOLE */
+ else
+ goto not_found;
+ of_node_put(prom_stdout);
+
+ DBG("Found serial console at ttyS%d\n", offset);
+
+ if (spd) {
+ static char __initdata opt[16];
+ sprintf(opt, "%d", *spd);
+ return add_preferred_console("ttyS", offset, opt);
+ } else
+ return add_preferred_console("ttyS", offset, NULL);
+
+ not_found:
+ DBG("No preferred console found !\n");
+ of_node_put(prom_stdout);
+ return -ENODEV;
+}
+console_initcall(set_preferred_console);
+#endif /* CONFIG_PPC_MULTIPLATFORM */
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
new file mode 100644
index 000000000000..9680ae99b084
--- /dev/null
+++ b/arch/powerpc/kernel/setup_32.c
@@ -0,0 +1,372 @@
+/*
+ * Common prep/pmac/chrp boot and setup code.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/reboot.h>
+#include <linux/delay.h>
+#include <linux/initrd.h>
+#include <linux/ide.h>
+#include <linux/tty.h>
+#include <linux/bootmem.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/cpu.h>
+#include <linux/console.h>
+
+#include <asm/residual.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/processor.h>
+#include <asm/pgtable.h>
+#include <asm/setup.h>
+#include <asm/amigappc.h>
+#include <asm/smp.h>
+#include <asm/elf.h>
+#include <asm/cputable.h>
+#include <asm/bootx.h>
+#include <asm/btext.h>
+#include <asm/machdep.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/pmac_feature.h>
+#include <asm/sections.h>
+#include <asm/nvram.h>
+#include <asm/xmon.h>
+#include <asm/time.h>
+
+#define DBG(fmt...)
+
+#if defined CONFIG_KGDB
+#include <asm/kgdb.h>
+#endif
+
+extern void platform_init(void);
+extern void bootx_init(unsigned long r4, unsigned long phys);
+
+extern void ppc6xx_idle(void);
+extern void power4_idle(void);
+
+boot_infos_t *boot_infos;
+struct ide_machdep_calls ppc_ide_md;
+
+/* XXX should go elsewhere */
+int __irq_offset_value;
+EXPORT_SYMBOL(__irq_offset_value);
+
+int boot_cpuid;
+EXPORT_SYMBOL_GPL(boot_cpuid);
+int boot_cpuid_phys;
+
+unsigned long ISA_DMA_THRESHOLD;
+unsigned int DMA_MODE_READ;
+unsigned int DMA_MODE_WRITE;
+
+int have_of = 1;
+
+#ifdef CONFIG_PPC_MULTIPLATFORM
+int _machine = 0;
+
+extern void prep_init(void);
+extern void pmac_init(void);
+extern void chrp_init(void);
+
+dev_t boot_dev;
+#endif /* CONFIG_PPC_MULTIPLATFORM */
+
+#ifdef CONFIG_MAGIC_SYSRQ
+unsigned long SYSRQ_KEY = 0x54;
+#endif /* CONFIG_MAGIC_SYSRQ */
+
+#ifdef CONFIG_VGA_CONSOLE
+unsigned long vgacon_remap_base;
+#endif
+
+struct machdep_calls ppc_md;
+EXPORT_SYMBOL(ppc_md);
+
+/*
+ * These are used in binfmt_elf.c to put aux entries on the stack
+ * for each elf executable being started.
+ */
+int dcache_bsize;
+int icache_bsize;
+int ucache_bsize;
+
+/*
+ * We're called here very early in the boot. We determine the machine
+ * type and call the appropriate low-level setup functions.
+ * -- Cort <cort@fsmlabs.com>
+ *
+ * Note that the kernel may be running at an address which is different
+ * from the address that it was linked at, so we must use RELOC/PTRRELOC
+ * to access static data (including strings). -- paulus
+ */
+unsigned long __init early_init(unsigned long dt_ptr)
+{
+ unsigned long offset = reloc_offset();
+
+ /* First zero the BSS -- use memset_io, some platforms don't have
+ * caches on yet */
+ memset_io(PTRRELOC(&__bss_start), 0, _end - __bss_start);
+
+ /*
+ * Identify the CPU type and fix up code sections
+ * that depend on which cpu we have.
+ */
+ identify_cpu(offset, 0);
+ do_cpu_ftr_fixups(offset);
+
+ return KERNELBASE + offset;
+}
+
+#ifdef CONFIG_PPC_MULTIPLATFORM
+/*
+ * The PPC_MULTIPLATFORM version of platform_init...
+ */
+void __init platform_init(void)
+{
+ /* if we didn't get any bootinfo telling us what we are... */
+ if (_machine == 0) {
+ /* prep boot loader tells us if we're prep or not */
+ if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) )
+ _machine = _MACH_prep;
+ }
+
+#ifdef CONFIG_PPC_PREP
+ /* not much more to do here, if prep */
+ if (_machine == _MACH_prep) {
+ prep_init();
+ return;
+ }
+#endif
+
+#ifdef CONFIG_ADB
+ if (strstr(cmd_line, "adb_sync")) {
+ extern int __adb_probe_sync;
+ __adb_probe_sync = 1;
+ }
+#endif /* CONFIG_ADB */
+
+ switch (_machine) {
+#ifdef CONFIG_PPC_PMAC
+ case _MACH_Pmac:
+ pmac_init();
+ break;
+#endif
+#ifdef CONFIG_PPC_CHRP
+ case _MACH_chrp:
+ chrp_init();
+ break;
+#endif
+ }
+}
+#endif
+
+/*
+ * Find out what kind of machine we're on and save any data we need
+ * from the early boot process (devtree is copied on pmac by prom_init()).
+ * This is called very early on the boot process, after a minimal
+ * MMU environment has been set up but before MMU_init is called.
+ */
+void __init machine_init(unsigned long dt_ptr, unsigned long phys)
+{
+ early_init_devtree(__va(dt_ptr));
+
+#ifdef CONFIG_CMDLINE
+ strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line));
+#endif /* CONFIG_CMDLINE */
+
+ platform_init();
+
+#ifdef CONFIG_6xx
+ ppc_md.power_save = ppc6xx_idle;
+#endif
+
+ if (ppc_md.progress)
+ ppc_md.progress("id mach(): done", 0x200);
+}
+
+#ifdef CONFIG_BOOKE_WDT
+/* Checks wdt=x and wdt_period=xx command-line option */
+int __init early_parse_wdt(char *p)
+{
+ if (p && strncmp(p, "0", 1) != 0)
+ booke_wdt_enabled = 1;
+
+ return 0;
+}
+early_param("wdt", early_parse_wdt);
+
+int __init early_parse_wdt_period (char *p)
+{
+ if (p)
+ booke_wdt_period = simple_strtoul(p, NULL, 0);
+
+ return 0;
+}
+early_param("wdt_period", early_parse_wdt_period);
+#endif /* CONFIG_BOOKE_WDT */
+
+/* Checks "l2cr=xxxx" command-line option */
+int __init ppc_setup_l2cr(char *str)
+{
+ if (cpu_has_feature(CPU_FTR_L2CR)) {
+ unsigned long val = simple_strtoul(str, NULL, 0);
+ printk(KERN_INFO "l2cr set to %lx\n", val);
+ _set_L2CR(0); /* force invalidate by disable cache */
+ _set_L2CR(val); /* and enable it */
+ }
+ return 1;
+}
+__setup("l2cr=", ppc_setup_l2cr);
+
+#ifdef CONFIG_GENERIC_NVRAM
+
+/* Generic nvram hooks used by drivers/char/gen_nvram.c */
+unsigned char nvram_read_byte(int addr)
+{
+ if (ppc_md.nvram_read_val)
+ return ppc_md.nvram_read_val(addr);
+ return 0xff;
+}
+EXPORT_SYMBOL(nvram_read_byte);
+
+void nvram_write_byte(unsigned char val, int addr)
+{
+ if (ppc_md.nvram_write_val)
+ ppc_md.nvram_write_val(addr, val);
+}
+EXPORT_SYMBOL(nvram_write_byte);
+
+void nvram_sync(void)
+{
+ if (ppc_md.nvram_sync)
+ ppc_md.nvram_sync();
+}
+EXPORT_SYMBOL(nvram_sync);
+
+#endif /* CONFIG_NVRAM */
+
+static struct cpu cpu_devices[NR_CPUS];
+
+int __init ppc_init(void)
+{
+ int i;
+
+ /* clear the progress line */
+ if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff);
+
+ /* register CPU devices */
+ for (i = 0; i < NR_CPUS; i++)
+ if (cpu_possible(i))
+ register_cpu(&cpu_devices[i], i, NULL);
+
+ /* call platform init */
+ if (ppc_md.init != NULL) {
+ ppc_md.init();
+ }
+ return 0;
+}
+
+arch_initcall(ppc_init);
+
+/* Warning, IO base is not yet inited */
+void __init setup_arch(char **cmdline_p)
+{
+ extern char *klimit;
+ extern void do_init_bootmem(void);
+
+ /* so udelay does something sensible, assume <= 1000 bogomips */
+ loops_per_jiffy = 500000000 / HZ;
+
+ unflatten_device_tree();
+ finish_device_tree();
+
+#ifdef CONFIG_BOOTX_TEXT
+ init_boot_display();
+#endif
+
+#ifdef CONFIG_PPC_PMAC
+ /* This could be called "early setup arch", it must be done
+ * now because xmon need it
+ */
+ if (_machine == _MACH_Pmac)
+ pmac_feature_init(); /* New cool way */
+#endif
+
+#ifdef CONFIG_XMON
+ xmon_map_scc();
+ if (strstr(cmd_line, "xmon")) {
+ xmon_init(1);
+ debugger(NULL);
+ }
+#endif /* CONFIG_XMON */
+ if ( ppc_md.progress ) ppc_md.progress("setup_arch: enter", 0x3eab);
+
+#if defined(CONFIG_KGDB)
+ if (ppc_md.kgdb_map_scc)
+ ppc_md.kgdb_map_scc();
+ set_debug_traps();
+ if (strstr(cmd_line, "gdb")) {
+ if (ppc_md.progress)
+ ppc_md.progress("setup_arch: kgdb breakpoint", 0x4000);
+ printk("kgdb breakpoint activated\n");
+ breakpoint();
+ }
+#endif
+
+ /*
+ * Set cache line size based on type of cpu as a default.
+ * Systems with OF can look in the properties on the cpu node(s)
+ * for a possibly more accurate value.
+ */
+ if (cpu_has_feature(CPU_FTR_SPLIT_ID_CACHE)) {
+ dcache_bsize = cur_cpu_spec->dcache_bsize;
+ icache_bsize = cur_cpu_spec->icache_bsize;
+ ucache_bsize = 0;
+ } else
+ ucache_bsize = dcache_bsize = icache_bsize
+ = cur_cpu_spec->dcache_bsize;
+
+ /* reboot on panic */
+ panic_timeout = 180;
+
+ init_mm.start_code = PAGE_OFFSET;
+ init_mm.end_code = (unsigned long) _etext;
+ init_mm.end_data = (unsigned long) _edata;
+ init_mm.brk = (unsigned long) klimit;
+
+ /* Save unparsed command line copy for /proc/cmdline */
+ strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
+ *cmdline_p = cmd_line;
+
+ parse_early_param();
+
+ /* set up the bootmem stuff with available memory */
+ do_init_bootmem();
+ if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab);
+
+#ifdef CONFIG_PPC_OCP
+ /* Initialize OCP device list */
+ ocp_early_init();
+ if ( ppc_md.progress ) ppc_md.progress("ocp: exit", 0x3eab);
+#endif
+
+#ifdef CONFIG_DUMMY_CONSOLE
+ conswitchp = &dummy_con;
+#endif
+
+ ppc_md.setup_arch();
+ if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);
+
+ paging_init();
+
+ /* this is for modules since _machine can be a define -- Cort */
+ ppc_md.ppc_machine = _machine;
+}
diff --git a/arch/ppc64/kernel/setup.c b/arch/powerpc/kernel/setup_64.c
index 5ac48bd64891..40c48100bf1b 100644
--- a/arch/ppc64/kernel/setup.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -37,7 +37,6 @@
#include <asm/prom.h>
#include <asm/processor.h>
#include <asm/pgtable.h>
-#include <asm/bootinfo.h>
#include <asm/smp.h>
#include <asm/elf.h>
#include <asm/machdep.h>
@@ -58,6 +57,9 @@
#include <asm/mmu.h>
#include <asm/lmb.h>
#include <asm/iSeries/ItLpNaca.h>
+#include <asm/firmware.h>
+#include <asm/systemcfg.h>
+#include <asm/xmon.h>
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
@@ -136,24 +138,7 @@ static struct notifier_block ppc64_panic_block = {
.priority = INT_MIN /* may not return; must be done last */
};
-/*
- * Perhaps we can put the pmac screen_info[] here
- * on pmac as well so we don't need the ifdef's.
- * Until we get multiple-console support in here
- * that is. -- Cort
- * Maybe tie it to serial consoles, since this is really what
- * these processors use on existing boards. -- Dan
- */
-struct screen_info screen_info = {
- .orig_x = 0,
- .orig_y = 25,
- .orig_video_cols = 80,
- .orig_video_lines = 25,
- .orig_video_isVGA = 1,
- .orig_video_points = 16
-};
-
-#if defined(CONFIG_PPC_MULTIPLATFORM) && defined(CONFIG_SMP)
+#ifdef CONFIG_SMP
static int smt_enabled_cmdline;
@@ -306,15 +291,13 @@ static void __init setup_cpu_maps(void)
systemcfg->processorCount = num_present_cpus();
}
-#endif /* defined(CONFIG_PPC_MULTIPLATFORM) && defined(CONFIG_SMP) */
-
-
-#ifdef CONFIG_PPC_MULTIPLATFORM
+#endif /* CONFIG_SMP */
extern struct machdep_calls pSeries_md;
extern struct machdep_calls pmac_md;
extern struct machdep_calls maple_md;
extern struct machdep_calls bpa_md;
+extern struct machdep_calls iseries_md;
/* Ultimately, stuff them in an elf section like initcalls... */
static struct machdep_calls __initdata *machines[] = {
@@ -330,6 +313,9 @@ static struct machdep_calls __initdata *machines[] = {
#ifdef CONFIG_PPC_BPA
&bpa_md,
#endif
+#ifdef CONFIG_PPC_ISERIES
+ &iseries_md,
+#endif
NULL
};
@@ -401,7 +387,8 @@ void __init early_setup(unsigned long dt_ptr)
/*
* Initialize stab / SLB management
*/
- stab_initialize(lpaca->stab_real);
+ if (!firmware_has_feature(FW_FEATURE_ISERIES))
+ stab_initialize(lpaca->stab_real);
/*
* Initialize the MMU Hash table and create the linear mapping
@@ -532,8 +519,6 @@ static void __init check_for_initrd(void)
#endif /* CONFIG_BLK_DEV_INITRD */
}
-#endif /* CONFIG_PPC_MULTIPLATFORM */
-
/*
* Do some initial setup of the system. The parameters are those which
* were passed in from the bootloader.
@@ -542,14 +527,6 @@ void __init setup_system(void)
{
DBG(" -> setup_system()\n");
-#ifdef CONFIG_PPC_ISERIES
- /* pSeries systems are identified in prom.c via OF. */
- if (itLpNaca.xLparInstalled == 1)
- systemcfg->platform = PLATFORM_ISERIES_LPAR;
-
- ppc_md.init_early();
-#else /* CONFIG_PPC_ISERIES */
-
/*
* Unflatten the device-tree passed by prom_init or kexec
*/
@@ -592,6 +569,10 @@ void __init setup_system(void)
*/
finish_device_tree();
+#ifdef CONFIG_BOOTX_TEXT
+ init_boot_display();
+#endif
+
/*
* Initialize xmon
*/
@@ -607,9 +588,8 @@ void __init setup_system(void)
strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
parse_early_param();
-#endif /* !CONFIG_PPC_ISERIES */
-#if defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES)
+#ifdef CONFIG_SMP
/*
* iSeries has already initialized the cpu maps at this point.
*/
@@ -619,7 +599,7 @@ void __init setup_system(void)
* we can map physical -> logical CPU ids
*/
smp_release_cpus();
-#endif /* defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES) */
+#endif
printk("Starting Linux PPC64 %s\n", system_utsname.version);
@@ -644,51 +624,6 @@ void __init setup_system(void)
DBG(" <- setup_system()\n");
}
-/* also used by kexec */
-void machine_shutdown(void)
-{
- if (ppc_md.nvram_sync)
- ppc_md.nvram_sync();
-}
-
-void machine_restart(char *cmd)
-{
- machine_shutdown();
- ppc_md.restart(cmd);
-#ifdef CONFIG_SMP
- smp_send_stop();
-#endif
- printk(KERN_EMERG "System Halted, OK to turn off power\n");
- local_irq_disable();
- while (1) ;
-}
-
-void machine_power_off(void)
-{
- machine_shutdown();
- ppc_md.power_off();
-#ifdef CONFIG_SMP
- smp_send_stop();
-#endif
- printk(KERN_EMERG "System Halted, OK to turn off power\n");
- local_irq_disable();
- while (1) ;
-}
-/* Used by the G5 thermal driver */
-EXPORT_SYMBOL_GPL(machine_power_off);
-
-void machine_halt(void)
-{
- machine_shutdown();
- ppc_md.halt();
-#ifdef CONFIG_SMP
- smp_send_stop();
-#endif
- printk(KERN_EMERG "System Halted, OK to turn off power\n");
- local_irq_disable();
- while (1) ;
-}
-
static int ppc64_panic_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
@@ -696,99 +631,6 @@ static int ppc64_panic_event(struct notifier_block *this,
return NOTIFY_DONE;
}
-
-#ifdef CONFIG_SMP
-DEFINE_PER_CPU(unsigned int, pvr);
-#endif
-
-static int show_cpuinfo(struct seq_file *m, void *v)
-{
- unsigned long cpu_id = (unsigned long)v - 1;
- unsigned int pvr;
- unsigned short maj;
- unsigned short min;
-
- if (cpu_id == NR_CPUS) {
- seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq);
-
- if (ppc_md.get_cpuinfo != NULL)
- ppc_md.get_cpuinfo(m);
-
- return 0;
- }
-
- /* We only show online cpus: disable preempt (overzealous, I
- * knew) to prevent cpu going down. */
- preempt_disable();
- if (!cpu_online(cpu_id)) {
- preempt_enable();
- return 0;
- }
-
-#ifdef CONFIG_SMP
- pvr = per_cpu(pvr, cpu_id);
-#else
- pvr = mfspr(SPRN_PVR);
-#endif
- maj = (pvr >> 8) & 0xFF;
- min = pvr & 0xFF;
-
- seq_printf(m, "processor\t: %lu\n", cpu_id);
- seq_printf(m, "cpu\t\t: ");
-
- if (cur_cpu_spec->pvr_mask)
- seq_printf(m, "%s", cur_cpu_spec->cpu_name);
- else
- seq_printf(m, "unknown (%08x)", pvr);
-
-#ifdef CONFIG_ALTIVEC
- if (cpu_has_feature(CPU_FTR_ALTIVEC))
- seq_printf(m, ", altivec supported");
-#endif /* CONFIG_ALTIVEC */
-
- seq_printf(m, "\n");
-
- /*
- * Assume here that all clock rates are the same in a
- * smp system. -- Cort
- */
- seq_printf(m, "clock\t\t: %lu.%06luMHz\n", ppc_proc_freq / 1000000,
- ppc_proc_freq % 1000000);
-
- seq_printf(m, "revision\t: %hd.%hd\n\n", maj, min);
-
- preempt_enable();
- return 0;
-}
-
-static void *c_start(struct seq_file *m, loff_t *pos)
-{
- return *pos <= NR_CPUS ? (void *)((*pos)+1) : NULL;
-}
-static void *c_next(struct seq_file *m, void *v, loff_t *pos)
-{
- ++*pos;
- return c_start(m, pos);
-}
-static void c_stop(struct seq_file *m, void *v)
-{
-}
-struct seq_operations cpuinfo_op = {
- .start =c_start,
- .next = c_next,
- .stop = c_stop,
- .show = show_cpuinfo,
-};
-
-/*
- * These three variables are used to save values passed to us by prom_init()
- * via the device tree. The TCE variables are needed because with a memory_limit
- * in force we may need to explicitly map the TCE are at the top of RAM.
- */
-unsigned long memory_limit;
-unsigned long tce_alloc_start;
-unsigned long tce_alloc_end;
-
#ifdef CONFIG_PPC_ISERIES
/*
* On iSeries we just parse the mem=X option from the command line.
@@ -806,130 +648,6 @@ static int __init early_parsemem(char *p)
early_param("mem", early_parsemem);
#endif /* CONFIG_PPC_ISERIES */
-#ifdef CONFIG_PPC_MULTIPLATFORM
-static int __init set_preferred_console(void)
-{
- struct device_node *prom_stdout = NULL;
- char *name;
- u32 *spd;
- int offset = 0;
-
- DBG(" -> set_preferred_console()\n");
-
- /* The user has requested a console so this is already set up. */
- if (strstr(saved_command_line, "console=")) {
- DBG(" console was specified !\n");
- return -EBUSY;
- }
-
- if (!of_chosen) {
- DBG(" of_chosen is NULL !\n");
- return -ENODEV;
- }
- /* We are getting a weird phandle from OF ... */
- /* ... So use the full path instead */
- name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
- if (name == NULL) {
- DBG(" no linux,stdout-path !\n");
- return -ENODEV;
- }
- prom_stdout = of_find_node_by_path(name);
- if (!prom_stdout) {
- DBG(" can't find stdout package %s !\n", name);
- return -ENODEV;
- }
- DBG("stdout is %s\n", prom_stdout->full_name);
-
- name = (char *)get_property(prom_stdout, "name", NULL);
- if (!name) {
- DBG(" stdout package has no name !\n");
- goto not_found;
- }
- spd = (u32 *)get_property(prom_stdout, "current-speed", NULL);
-
- if (0)
- ;
-#ifdef CONFIG_SERIAL_8250_CONSOLE
- else if (strcmp(name, "serial") == 0) {
- int i;
- u32 *reg = (u32 *)get_property(prom_stdout, "reg", &i);
- if (i > 8) {
- switch (reg[1]) {
- case 0x3f8:
- offset = 0;
- break;
- case 0x2f8:
- offset = 1;
- break;
- case 0x898:
- offset = 2;
- break;
- case 0x890:
- offset = 3;
- break;
- default:
- /* We dont recognise the serial port */
- goto not_found;
- }
- }
- }
-#endif /* CONFIG_SERIAL_8250_CONSOLE */
-#ifdef CONFIG_PPC_PSERIES
- else if (strcmp(name, "vty") == 0) {
- u32 *reg = (u32 *)get_property(prom_stdout, "reg", NULL);
- char *compat = (char *)get_property(prom_stdout, "compatible", NULL);
-
- if (reg && compat && (strcmp(compat, "hvterm-protocol") == 0)) {
- /* Host Virtual Serial Interface */
- int offset;
- switch (reg[0]) {
- case 0x30000000:
- offset = 0;
- break;
- case 0x30000001:
- offset = 1;
- break;
- default:
- goto not_found;
- }
- of_node_put(prom_stdout);
- DBG("Found hvsi console at offset %d\n", offset);
- return add_preferred_console("hvsi", offset, NULL);
- } else {
- /* pSeries LPAR virtual console */
- of_node_put(prom_stdout);
- DBG("Found hvc console\n");
- return add_preferred_console("hvc", 0, NULL);
- }
- }
-#endif /* CONFIG_PPC_PSERIES */
-#ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE
- else if (strcmp(name, "ch-a") == 0)
- offset = 0;
- else if (strcmp(name, "ch-b") == 0)
- offset = 1;
-#endif /* CONFIG_SERIAL_PMACZILOG_CONSOLE */
- else
- goto not_found;
- of_node_put(prom_stdout);
-
- DBG("Found serial console at ttyS%d\n", offset);
-
- if (spd) {
- static char __initdata opt[16];
- sprintf(opt, "%d", *spd);
- return add_preferred_console("ttyS", offset, opt);
- } else
- return add_preferred_console("ttyS", offset, NULL);
-
- not_found:
- DBG("No preferred console found !\n");
- of_node_put(prom_stdout);
- return -ENODEV;
-}
-console_initcall(set_preferred_console);
-#endif /* CONFIG_PPC_MULTIPLATFORM */
-
#ifdef CONFIG_IRQSTACKS
static void __init irqstack_early_init(void)
{
@@ -983,23 +701,22 @@ void __init setup_syscall_map(void)
{
unsigned int i, count64 = 0, count32 = 0;
extern unsigned long *sys_call_table;
- extern unsigned long *sys_call_table32;
extern unsigned long sys_ni_syscall;
for (i = 0; i < __NR_syscalls; i++) {
- if (sys_call_table[i] == sys_ni_syscall)
- continue;
- count64++;
- systemcfg->syscall_map_64[i >> 5] |= 0x80000000UL >> (i & 0x1f);
- }
- for (i = 0; i < __NR_syscalls; i++) {
- if (sys_call_table32[i] == sys_ni_syscall)
- continue;
- count32++;
- systemcfg->syscall_map_32[i >> 5] |= 0x80000000UL >> (i & 0x1f);
+ if (sys_call_table[i*2] != sys_ni_syscall) {
+ count64++;
+ systemcfg->syscall_map_64[i >> 5] |=
+ 0x80000000UL >> (i & 0x1f);
+ }
+ if (sys_call_table[i*2+1] != sys_ni_syscall) {
+ count32++;
+ systemcfg->syscall_map_32[i >> 5] |=
+ 0x80000000UL >> (i & 0x1f);
+ }
}
- printk(KERN_INFO "Syscall map setup, %d 32 bits and %d 64 bits syscalls\n",
+ printk(KERN_INFO "Syscall map setup, %d 32-bit and %d 64-bit syscalls\n",
count32, count64);
}
@@ -1047,6 +764,10 @@ void __init setup_arch(char **cmdline_p)
/* initialize the syscall map in systemcfg */
setup_syscall_map();
+#ifdef CONFIG_DUMMY_CONSOLE
+ conswitchp = &dummy_con;
+#endif
+
ppc_md.setup_arch();
/* Use the default idle loop if the platform hasn't provided one. */
@@ -1091,15 +812,6 @@ void ppc64_terminate_msg(unsigned int src, const char *msg)
printk("[terminate]%04x %s\n", src, msg);
}
-/* This should only be called on processor 0 during calibrate decr */
-void __init setup_default_decr(void)
-{
- struct paca_struct *lpaca = get_paca();
-
- lpaca->default_decr = tb_ticks_per_jiffy;
- lpaca->next_jiffy_update_tb = get_tb() + tb_ticks_per_jiffy;
-}
-
#ifndef CONFIG_PPC_ISERIES
/*
* This function can be used by platforms to "find" legacy serial ports.
diff --git a/arch/ppc64/kernel/signal32.c b/arch/powerpc/kernel/signal_32.c
index a8b7a5a56bb4..444c3e81884c 100644
--- a/arch/ppc64/kernel/signal32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -1,56 +1,353 @@
/*
- * signal32.c: Support 32bit signal syscalls.
+ * Signal handling for 32bit PPC and 32bit tasks on 64bit PPC
*
+ * PowerPC version
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
* Copyright (C) 2001 IBM
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
*
- * These routines maintain argument size conversion between 32bit and 64bit
- * environment.
+ * Derived from "arch/i386/kernel/signal.c"
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
*
- * This program is free software; you can redistribute 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 free software; you can redistribute 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/config.h>
#include <linux/sched.h>
-#include <linux/mm.h>
+#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
-#include <linux/syscalls.h>
#include <linux/errno.h>
#include <linux/elf.h>
+#ifdef CONFIG_PPC64
+#include <linux/syscalls.h>
#include <linux/compat.h>
#include <linux/ptrace.h>
-#include <asm/ppc32.h>
+#else
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+#include <linux/tty.h>
+#include <linux/binfmts.h>
+#include <linux/suspend.h>
+#endif
+
#include <asm/uaccess.h>
+#include <asm/cacheflush.h>
+#ifdef CONFIG_PPC64
+#include <asm/ppc32.h>
#include <asm/ppcdebug.h>
#include <asm/unistd.h>
-#include <asm/cacheflush.h>
#include <asm/vdso.h>
+#else
+#include <asm/ucontext.h>
+#include <asm/pgtable.h>
+#endif
-#define DEBUG_SIG 0
+#undef DEBUG_SIG
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
-#define GP_REGS_SIZE32 min(sizeof(elf_gregset_t32), sizeof(struct pt_regs32))
+#ifdef CONFIG_PPC64
+#define do_signal do_signal32
+#define sys_sigsuspend compat_sys_sigsuspend
+#define sys_rt_sigsuspend compat_sys_rt_sigsuspend
+#define sys_rt_sigreturn compat_sys_rt_sigreturn
+#define sys_sigaction compat_sys_sigaction
+#define sys_swapcontext compat_sys_swapcontext
+#define sys_sigreturn compat_sys_sigreturn
+
+#define old_sigaction old_sigaction32
+#define sigcontext sigcontext32
+#define mcontext mcontext32
+#define ucontext ucontext32
+
+/*
+ * Returning 0 means we return to userspace via
+ * ret_from_except and thus restore all user
+ * registers from *regs. This is what we need
+ * to do when a signal has been delivered.
+ */
+#define sigreturn_exit(regs) return 0
+
+#define GP_REGS_SIZE min(sizeof(elf_gregset_t32), sizeof(struct pt_regs32))
+#undef __SIGNAL_FRAMESIZE
+#define __SIGNAL_FRAMESIZE __SIGNAL_FRAMESIZE32
+#undef ELF_NVRREG
+#define ELF_NVRREG ELF_NVRREG32
+
+/*
+ * Functions for flipping sigsets (thanks to brain dead generic
+ * implementation that makes things simple for little endian only)
+ */
+static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set)
+{
+ compat_sigset_t cset;
+
+ switch (_NSIG_WORDS) {
+ case 4: cset.sig[5] = set->sig[3] & 0xffffffffull;
+ cset.sig[7] = set->sig[3] >> 32;
+ case 3: cset.sig[4] = set->sig[2] & 0xffffffffull;
+ cset.sig[5] = set->sig[2] >> 32;
+ case 2: cset.sig[2] = set->sig[1] & 0xffffffffull;
+ cset.sig[3] = set->sig[1] >> 32;
+ case 1: cset.sig[0] = set->sig[0] & 0xffffffffull;
+ cset.sig[1] = set->sig[0] >> 32;
+ }
+ return copy_to_user(uset, &cset, sizeof(*uset));
+}
+
+static inline int get_sigset_t(sigset_t *set,
+ const compat_sigset_t __user *uset)
+{
+ compat_sigset_t s32;
+
+ if (copy_from_user(&s32, uset, sizeof(*uset)))
+ return -EFAULT;
+
+ /*
+ * Swap the 2 words of the 64-bit sigset_t (they are stored
+ * in the "wrong" endian in 32-bit user storage).
+ */
+ switch (_NSIG_WORDS) {
+ case 4: set->sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
+ case 3: set->sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);
+ case 2: set->sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
+ case 1: set->sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
+ }
+ return 0;
+}
+
+static inline int get_old_sigaction(struct k_sigaction *new_ka,
+ struct old_sigaction __user *act)
+{
+ compat_old_sigset_t mask;
+ compat_uptr_t handler, restorer;
+
+ if (get_user(handler, &act->sa_handler) ||
+ __get_user(restorer, &act->sa_restorer) ||
+ __get_user(new_ka->sa.sa_flags, &act->sa_flags) ||
+ __get_user(mask, &act->sa_mask))
+ return -EFAULT;
+ new_ka->sa.sa_handler = compat_ptr(handler);
+ new_ka->sa.sa_restorer = compat_ptr(restorer);
+ siginitset(&new_ka->sa.sa_mask, mask);
+ return 0;
+}
+
+static inline compat_uptr_t to_user_ptr(void *kp)
+{
+ return (compat_uptr_t)(u64)kp;
+}
+
+#define from_user_ptr(p) compat_ptr(p)
+
+static inline int save_general_regs(struct pt_regs *regs,
+ struct mcontext __user *frame)
+{
+ elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
+ int i;
+
+ for (i = 0; i <= PT_RESULT; i ++)
+ if (__put_user((unsigned int)gregs[i], &frame->mc_gregs[i]))
+ return -EFAULT;
+ return 0;
+}
+
+static inline int restore_general_regs(struct pt_regs *regs,
+ struct mcontext __user *sr)
+{
+ elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
+ int i;
+
+ for (i = 0; i <= PT_RESULT; i++) {
+ if ((i == PT_MSR) || (i == PT_SOFTE))
+ continue;
+ if (__get_user(gregs[i], &sr->mc_gregs[i]))
+ return -EFAULT;
+ }
+ return 0;
+}
+
+#else /* CONFIG_PPC64 */
+
+extern void sigreturn_exit(struct pt_regs *);
+
+#define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs))
+
+static inline int put_sigset_t(sigset_t __user *uset, sigset_t *set)
+{
+ return copy_to_user(uset, set, sizeof(*uset));
+}
+
+static inline int get_sigset_t(sigset_t *set, const sigset_t __user *uset)
+{
+ return copy_from_user(set, uset, sizeof(*uset));
+}
+
+static inline int get_old_sigaction(struct k_sigaction *new_ka,
+ struct old_sigaction __user *act)
+{
+ old_sigset_t mask;
+
+ if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
+ __get_user(new_ka->sa.sa_handler, &act->sa_handler) ||
+ __get_user(new_ka->sa.sa_restorer, &act->sa_restorer))
+ return -EFAULT;
+ __get_user(new_ka->sa.sa_flags, &act->sa_flags);
+ __get_user(mask, &act->sa_mask);
+ siginitset(&new_ka->sa.sa_mask, mask);
+ return 0;
+}
+
+#define to_user_ptr(p) (p)
+#define from_user_ptr(p) (p)
+
+static inline int save_general_regs(struct pt_regs *regs,
+ struct mcontext __user *frame)
+{
+ return __copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE);
+}
+
+static inline int restore_general_regs(struct pt_regs *regs,
+ struct mcontext __user *sr)
+{
+ /* copy up to but not including MSR */
+ if (__copy_from_user(regs, &sr->mc_gregs,
+ PT_MSR * sizeof(elf_greg_t)))
+ return -EFAULT;
+ /* copy from orig_r3 (the word after the MSR) up to the end */
+ if (__copy_from_user(&regs->orig_gpr3, &sr->mc_gregs[PT_ORIG_R3],
+ GP_REGS_SIZE - PT_ORIG_R3 * sizeof(elf_greg_t)))
+ return -EFAULT;
+ return 0;
+}
+
+#endif /* CONFIG_PPC64 */
+
+int do_signal(sigset_t *oldset, struct pt_regs *regs);
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+long sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7,
+ struct pt_regs *regs)
+{
+ sigset_t saveset;
+
+ mask &= _BLOCKABLE;
+ spin_lock_irq(&current->sighand->siglock);
+ saveset = current->blocked;
+ siginitset(&current->blocked, mask);
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
+ regs->result = -EINTR;
+ regs->gpr[3] = EINTR;
+ regs->ccr |= 0x10000000;
+ while (1) {
+ current->state = TASK_INTERRUPTIBLE;
+ schedule();
+ if (do_signal(&saveset, regs))
+ sigreturn_exit(regs);
+ }
+}
+
+long sys_rt_sigsuspend(
+#ifdef CONFIG_PPC64
+ compat_sigset_t __user *unewset,
+#else
+ sigset_t __user *unewset,
+#endif
+ size_t sigsetsize, int p3, int p4,
+ int p6, int p7, struct pt_regs *regs)
+{
+ sigset_t saveset, newset;
+
+ /* XXX: Don't preclude handling different sized sigset_t's. */
+ if (sigsetsize != sizeof(sigset_t))
+ return -EINVAL;
+
+ if (get_sigset_t(&newset, unewset))
+ return -EFAULT;
+ sigdelsetmask(&newset, ~_BLOCKABLE);
+
+ spin_lock_irq(&current->sighand->siglock);
+ saveset = current->blocked;
+ current->blocked = newset;
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
+ regs->result = -EINTR;
+ regs->gpr[3] = EINTR;
+ regs->ccr |= 0x10000000;
+ while (1) {
+ current->state = TASK_INTERRUPTIBLE;
+ schedule();
+ if (do_signal(&saveset, regs))
+ sigreturn_exit(regs);
+ }
+}
+
+#ifdef CONFIG_PPC32
+long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, int r5,
+ int r6, int r7, int r8, struct pt_regs *regs)
+{
+ return do_sigaltstack(uss, uoss, regs->gpr[1]);
+}
+#endif
+
+long sys_sigaction(int sig, struct old_sigaction __user *act,
+ struct old_sigaction __user *oact)
+{
+ struct k_sigaction new_ka, old_ka;
+ int ret;
+
+#ifdef CONFIG_PPC64
+ if (sig < 0)
+ sig = -sig;
+#endif
+
+ if (act) {
+ if (get_old_sigaction(&new_ka, act))
+ return -EFAULT;
+ }
+
+ ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+ if (!ret && oact) {
+ if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
+ __put_user(to_user_ptr(old_ka.sa.sa_handler),
+ &oact->sa_handler) ||
+ __put_user(to_user_ptr(old_ka.sa.sa_restorer),
+ &oact->sa_restorer) ||
+ __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
+ __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
+ return -EFAULT;
+ }
+
+ return ret;
+}
/*
* When we have signals to deliver, we set up on the
* user stack, going down from the original stack pointer:
- * a sigregs32 struct
- * a sigcontext32 struct
- * a gap of __SIGNAL_FRAMESIZE32 bytes
+ * a sigregs struct
+ * a sigcontext struct
+ * a gap of __SIGNAL_FRAMESIZE bytes
*
* Each of these things must be a multiple of 16 bytes in size.
*
*/
-struct sigregs32 {
- struct mcontext32 mctx; /* all the register values */
+struct sigregs {
+ struct mcontext mctx; /* all the register values */
/*
* Programs using the rs6000/xcoff abi can save up to 19 gp
* regs and 18 fp regs below sp before decrementing it.
@@ -64,17 +361,21 @@ struct sigregs32 {
/*
* When we have rt signals to deliver, we set up on the
* user stack, going down from the original stack pointer:
- * one rt_sigframe32 struct (siginfo + ucontext + ABI gap)
- * a gap of __SIGNAL_FRAMESIZE32+16 bytes
- * (the +16 is to get the siginfo and ucontext32 in the same
+ * one rt_sigframe struct (siginfo + ucontext + ABI gap)
+ * a gap of __SIGNAL_FRAMESIZE+16 bytes
+ * (the +16 is to get the siginfo and ucontext in the same
* positions as in older kernels).
*
* Each of these things must be a multiple of 16 bytes in size.
*
*/
-struct rt_sigframe32 {
- compat_siginfo_t info;
- struct ucontext32 uc;
+struct rt_sigframe {
+#ifdef CONFIG_PPC64
+ compat_siginfo_t info;
+#else
+ struct siginfo info;
+#endif
+ struct ucontext uc;
/*
* Programs using the rs6000/xcoff abi can save up to 19 gp
* regs and 18 fp regs below sp before decrementing it.
@@ -82,76 +383,34 @@ struct rt_sigframe32 {
int abigap[56];
};
-
-/*
- * Common utility functions used by signal and context support
- *
- */
-
-/*
- * Restore the user process's signal mask
- * (implemented in signal.c)
- */
-extern void restore_sigmask(sigset_t *set);
-
-/*
- * Functions for flipping sigsets (thanks to brain dead generic
- * implementation that makes things simple for little endian only
- */
-static inline void compat_from_sigset(compat_sigset_t *compat, sigset_t *set)
-{
- switch (_NSIG_WORDS) {
- case 4: compat->sig[5] = set->sig[3] & 0xffffffffull ;
- compat->sig[7] = set->sig[3] >> 32;
- case 3: compat->sig[4] = set->sig[2] & 0xffffffffull ;
- compat->sig[5] = set->sig[2] >> 32;
- case 2: compat->sig[2] = set->sig[1] & 0xffffffffull ;
- compat->sig[3] = set->sig[1] >> 32;
- case 1: compat->sig[0] = set->sig[0] & 0xffffffffull ;
- compat->sig[1] = set->sig[0] >> 32;
- }
-}
-
-static inline void sigset_from_compat(sigset_t *set, compat_sigset_t *compat)
-{
- switch (_NSIG_WORDS) {
- case 4: set->sig[3] = compat->sig[6] | (((long)compat->sig[7]) << 32);
- case 3: set->sig[2] = compat->sig[4] | (((long)compat->sig[5]) << 32);
- case 2: set->sig[1] = compat->sig[2] | (((long)compat->sig[3]) << 32);
- case 1: set->sig[0] = compat->sig[0] | (((long)compat->sig[1]) << 32);
- }
-}
-
-
/*
* Save the current user registers on the user stack.
- * We only save the altivec registers if the process has used
- * altivec instructions at some point.
+ * We only save the altivec/spe registers if the process has used
+ * altivec/spe instructions at some point.
*/
-static int save_user_regs(struct pt_regs *regs, struct mcontext32 __user *frame, int sigret)
+static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
+ int sigret)
{
- elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
- int i, err = 0;
-
+#ifdef CONFIG_PPC32
+ CHECK_FULL_REGS(regs);
+#endif
/* Make sure floating point registers are stored in regs */
flush_fp_to_thread(current);
/* save general and floating-point registers */
- for (i = 0; i <= PT_RESULT; i ++)
- err |= __put_user((unsigned int)gregs[i], &frame->mc_gregs[i]);
- err |= __copy_to_user(&frame->mc_fregs, current->thread.fpr,
- ELF_NFPREG * sizeof(double));
- if (err)
+ if (save_general_regs(regs, frame) ||
+ __copy_to_user(&frame->mc_fregs, current->thread.fpr,
+ ELF_NFPREG * sizeof(double)))
return 1;
- current->thread.fpscr = 0; /* turn off all fp exceptions */
+ current->thread.fpscr.val = 0; /* turn off all fp exceptions */
#ifdef CONFIG_ALTIVEC
/* save altivec registers */
if (current->thread.used_vr) {
flush_altivec_to_thread(current);
if (__copy_to_user(&frame->mc_vregs, current->thread.vr,
- ELF_NVRREG32 * sizeof(vector128)))
+ ELF_NVRREG * sizeof(vector128)))
return 1;
/* set MSR_VEC in the saved MSR value to indicate that
frame->mc_vregs contains valid data */
@@ -169,6 +428,25 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext32 __user *frame,
return 1;
#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+ /* save spe registers */
+ if (current->thread.used_spe) {
+ flush_spe_to_thread(current);
+ if (__copy_to_user(&frame->mc_vregs, current->thread.evr,
+ ELF_NEVRREG * sizeof(u32)))
+ return 1;
+ /* set MSR_SPE in the saved MSR value to indicate that
+ frame->mc_vregs contains valid data */
+ if (__put_user(regs->msr | MSR_SPE, &frame->mc_gregs[PT_MSR]))
+ return 1;
+ }
+ /* else assert((regs->msr & MSR_SPE) == 0) */
+
+ /* We always copy to/from spefscr */
+ if (__put_user(current->thread.spefscr, (u32 __user *)&frame->mc_vregs + ELF_NEVRREG))
+ return 1;
+#endif /* CONFIG_SPE */
+
if (sigret) {
/* Set up the sigreturn trampoline: li r0,sigret; sc */
if (__put_user(0x38000000UL + sigret, &frame->tramp[0])
@@ -186,13 +464,11 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext32 __user *frame,
* (except for MSR).
*/
static long restore_user_regs(struct pt_regs *regs,
- struct mcontext32 __user *sr, int sig)
+ struct mcontext __user *sr, int sig)
{
- elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
- int i;
- long err = 0;
+ long err;
unsigned int save_r2 = 0;
-#ifdef CONFIG_ALTIVEC
+#if defined(CONFIG_ALTIVEC) || defined(CONFIG_SPE)
unsigned long msr;
#endif
@@ -202,11 +478,7 @@ static long restore_user_regs(struct pt_regs *regs,
*/
if (!sig)
save_r2 = (unsigned int)regs->gpr[2];
- for (i = 0; i <= PT_RESULT; i++) {
- if ((i == PT_MSR) || (i == PT_SOFTE))
- continue;
- err |= __get_user(gregs[i], &sr->mc_gregs[i]);
- }
+ err = restore_general_regs(regs, sr);
if (!sig)
regs->gpr[2] = (unsigned long) save_r2;
if (err)
@@ -229,135 +501,51 @@ static long restore_user_regs(struct pt_regs *regs,
sizeof(sr->mc_vregs)))
return 1;
} else if (current->thread.used_vr)
- memset(current->thread.vr, 0, ELF_NVRREG32 * sizeof(vector128));
+ memset(current->thread.vr, 0, ELF_NVRREG * sizeof(vector128));
/* Always get VRSAVE back */
if (__get_user(current->thread.vrsave, (u32 __user *)&sr->mc_vregs[32]))
return 1;
#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+ /* force the process to reload the spe registers from
+ current->thread when it next does spe instructions */
+ regs->msr &= ~MSR_SPE;
+ if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_SPE) != 0) {
+ /* restore spe registers from the stack */
+ if (__copy_from_user(current->thread.evr, &sr->mc_vregs,
+ ELF_NEVRREG * sizeof(u32)))
+ return 1;
+ } else if (current->thread.used_spe)
+ memset(current->thread.evr, 0, ELF_NEVRREG * sizeof(u32));
+
+ /* Always get SPEFSCR back */
+ if (__get_user(current->thread.spefscr, (u32 __user *)&sr->mc_vregs + ELF_NEVRREG))
+ return 1;
+#endif /* CONFIG_SPE */
+
#ifndef CONFIG_SMP
preempt_disable();
if (last_task_used_math == current)
last_task_used_math = NULL;
if (last_task_used_altivec == current)
last_task_used_altivec = NULL;
+#ifdef CONFIG_SPE
+ if (last_task_used_spe == current)
+ last_task_used_spe = NULL;
+#endif
preempt_enable();
#endif
return 0;
}
-
-/*
- * Start of nonRT signal support
- *
- * sigset_t is 32 bits for non-rt signals
- *
- * System Calls
- * sigaction sys32_sigaction
- * sigreturn sys32_sigreturn
- *
- * Note sigsuspend has no special 32 bit routine - uses the 64 bit routine
- *
- * Other routines
- * setup_frame32
- */
-
-/*
- * Atomically swap in the new signal mask, and wait for a signal.
- */
-long sys32_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7,
- struct pt_regs *regs)
-{
- sigset_t saveset;
-
- mask &= _BLOCKABLE;
- spin_lock_irq(&current->sighand->siglock);
- saveset = current->blocked;
- siginitset(&current->blocked, mask);
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
-
- regs->result = -EINTR;
- regs->gpr[3] = EINTR;
- regs->ccr |= 0x10000000;
- while (1) {
- current->state = TASK_INTERRUPTIBLE;
- schedule();
- if (do_signal32(&saveset, regs))
- /*
- * Returning 0 means we return to userspace via
- * ret_from_except and thus restore all user
- * registers from *regs. This is what we need
- * to do when a signal has been delivered.
- */
- return 0;
- }
-}
-
-long sys32_sigaction(int sig, struct old_sigaction32 __user *act,
- struct old_sigaction32 __user *oact)
-{
- struct k_sigaction new_ka, old_ka;
- int ret;
-
- if (sig < 0)
- sig = -sig;
-
- if (act) {
- compat_old_sigset_t mask;
- compat_uptr_t handler, restorer;
-
- if (get_user(handler, &act->sa_handler) ||
- __get_user(restorer, &act->sa_restorer) ||
- __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
- __get_user(mask, &act->sa_mask))
- return -EFAULT;
- new_ka.sa.sa_handler = compat_ptr(handler);
- new_ka.sa.sa_restorer = compat_ptr(restorer);
- siginitset(&new_ka.sa.sa_mask, mask);
- }
-
- ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
- if (!ret && oact) {
- if (put_user((long)old_ka.sa.sa_handler, &oact->sa_handler) ||
- __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer) ||
- __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
- __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
- return -EFAULT;
- }
-
- return ret;
-}
-
-
-
-/*
- * Start of RT signal support
- *
- * sigset_t is 64 bits for rt signals
- *
- * System Calls
- * sigaction sys32_rt_sigaction
- * sigpending sys32_rt_sigpending
- * sigprocmask sys32_rt_sigprocmask
- * sigreturn sys32_rt_sigreturn
- * sigqueueinfo sys32_rt_sigqueueinfo
- * sigsuspend sys32_rt_sigsuspend
- *
- * Other routines
- * setup_rt_frame32
- * copy_siginfo_to_user32
- * siginfo32to64
- */
-
-
-long sys32_rt_sigaction(int sig, const struct sigaction32 __user *act,
+#ifdef CONFIG_PPC64
+long compat_sys_rt_sigaction(int sig, const struct sigaction32 __user *act,
struct sigaction32 __user *oact, size_t sigsetsize)
{
struct k_sigaction new_ka, old_ka;
int ret;
- compat_sigset_t set32;
/* XXX: Don't preclude handling different sized sigset_t's. */
if (sigsetsize != sizeof(compat_sigset_t))
@@ -368,9 +556,7 @@ long sys32_rt_sigaction(int sig, const struct sigaction32 __user *act,
ret = get_user(handler, &act->sa_handler);
new_ka.sa.sa_handler = compat_ptr(handler);
- ret |= __copy_from_user(&set32, &act->sa_mask,
- sizeof(compat_sigset_t));
- sigset_from_compat(&new_ka.sa.sa_mask, &set32);
+ ret |= get_sigset_t(&new_ka.sa.sa_mask, &act->sa_mask);
ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
if (ret)
return -EFAULT;
@@ -378,10 +564,8 @@ long sys32_rt_sigaction(int sig, const struct sigaction32 __user *act,
ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
if (!ret && oact) {
- compat_from_sigset(&set32, &old_ka.sa.sa_mask);
ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
- ret |= __copy_to_user(&oact->sa_mask, &set32,
- sizeof(compat_sigset_t));
+ ret |= put_sigset_t(&oact->sa_mask, &old_ka.sa.sa_mask);
ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
}
return ret;
@@ -394,41 +578,37 @@ long sys32_rt_sigaction(int sig, const struct sigaction32 __user *act,
* of a signed int (msr in 32-bit mode) and the register representation
* of a signed int (msr in 64-bit mode) is performed.
*/
-long sys32_rt_sigprocmask(u32 how, compat_sigset_t __user *set,
+long compat_sys_rt_sigprocmask(u32 how, compat_sigset_t __user *set,
compat_sigset_t __user *oset, size_t sigsetsize)
{
sigset_t s;
sigset_t __user *up;
- compat_sigset_t s32;
int ret;
mm_segment_t old_fs = get_fs();
if (set) {
- if (copy_from_user (&s32, set, sizeof(compat_sigset_t)))
- return -EFAULT;
- sigset_from_compat(&s, &s32);
+ if (get_sigset_t(&s, set))
+ return -EFAULT;
}
-
+
set_fs(KERNEL_DS);
/* This is valid because of the set_fs() */
up = (sigset_t __user *) &s;
ret = sys_rt_sigprocmask((int)how, set ? up : NULL, oset ? up : NULL,
- sigsetsize);
+ sigsetsize);
set_fs(old_fs);
if (ret)
return ret;
if (oset) {
- compat_from_sigset(&s32, &s);
- if (copy_to_user (oset, &s32, sizeof(compat_sigset_t)))
+ if (put_sigset_t(oset, &s))
return -EFAULT;
}
return 0;
}
-long sys32_rt_sigpending(compat_sigset_t __user *set, compat_size_t sigsetsize)
+long compat_sys_rt_sigpending(compat_sigset_t __user *set, compat_size_t sigsetsize)
{
sigset_t s;
- compat_sigset_t s32;
int ret;
mm_segment_t old_fs = get_fs();
@@ -437,8 +617,7 @@ long sys32_rt_sigpending(compat_sigset_t __user *set, compat_size_t sigsetsize)
ret = sys_rt_sigpending((sigset_t __user *) &s, sigsetsize);
set_fs(old_fs);
if (!ret) {
- compat_from_sigset(&s32, &s);
- if (copy_to_user (set, &s32, sizeof(compat_sigset_t)))
+ if (put_sigset_t(set, &s))
return -EFAULT;
}
return ret;
@@ -500,6 +679,8 @@ int copy_siginfo_to_user32(struct compat_siginfo __user *d, siginfo_t *s)
return err;
}
+#define copy_siginfo_to_user copy_siginfo_to_user32
+
/*
* Note: it is necessary to treat pid and sig as unsigned ints, with the
* corresponding cast to a signed int to insure that the proper conversion
@@ -507,12 +688,12 @@ int copy_siginfo_to_user32(struct compat_siginfo __user *d, siginfo_t *s)
* (msr in 32-bit mode) and the register representation of a signed int
* (msr in 64-bit mode) is performed.
*/
-long sys32_rt_sigqueueinfo(u32 pid, u32 sig, compat_siginfo_t __user *uinfo)
+long compat_sys_rt_sigqueueinfo(u32 pid, u32 sig, compat_siginfo_t __user *uinfo)
{
siginfo_t info;
int ret;
mm_segment_t old_fs = get_fs();
-
+
if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE32))
return -EFAULT;
@@ -522,58 +703,14 @@ long sys32_rt_sigqueueinfo(u32 pid, u32 sig, compat_siginfo_t __user *uinfo)
set_fs (old_fs);
return ret;
}
-
-int sys32_rt_sigsuspend(compat_sigset_t __user * unewset, size_t sigsetsize, int p3,
- int p4, int p6, int p7, struct pt_regs *regs)
-{
- sigset_t saveset, newset;
- compat_sigset_t s32;
-
- /* XXX: Don't preclude handling different sized sigset_t's. */
- if (sigsetsize != sizeof(sigset_t))
- return -EINVAL;
-
- if (copy_from_user(&s32, unewset, sizeof(s32)))
- return -EFAULT;
-
- /*
- * Swap the 2 words of the 64-bit sigset_t (they are stored
- * in the "wrong" endian in 32-bit user storage).
- */
- sigset_from_compat(&newset, &s32);
-
- sigdelsetmask(&newset, ~_BLOCKABLE);
- spin_lock_irq(&current->sighand->siglock);
- saveset = current->blocked;
- current->blocked = newset;
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
-
- regs->result = -EINTR;
- regs->gpr[3] = EINTR;
- regs->ccr |= 0x10000000;
- while (1) {
- current->state = TASK_INTERRUPTIBLE;
- schedule();
- if (do_signal32(&saveset, regs))
- /*
- * Returning 0 means we return to userspace via
- * ret_from_except and thus restore all user
- * registers from *regs. This is what we need
- * to do when a signal has been delivered.
- */
- return 0;
- }
-}
-
/*
* Start Alternate signal stack support
*
* System Calls
- * sigaltatck sys32_sigaltstack
+ * sigaltatck compat_sys_sigaltstack
*/
-int sys32_sigaltstack(u32 __new, u32 __old, int r5,
+int compat_sys_sigaltstack(u32 __new, u32 __old, int r5,
int r6, int r7, int r8, struct pt_regs *regs)
{
stack_32_t __user * newstack = (stack_32_t __user *)(long) __new;
@@ -615,76 +752,94 @@ int sys32_sigaltstack(u32 __new, u32 __old, int r5,
return -EFAULT;
return ret;
}
+#endif /* CONFIG_PPC64 */
+
+/*
+ * Restore the user process's signal mask
+ */
+#ifdef CONFIG_PPC64
+extern void restore_sigmask(sigset_t *set);
+#else /* CONFIG_PPC64 */
+static void restore_sigmask(sigset_t *set)
+{
+ sigdelsetmask(set, ~_BLOCKABLE);
+ spin_lock_irq(&current->sighand->siglock);
+ current->blocked = *set;
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+}
+#endif
/*
* Set up a signal frame for a "real-time" signal handler
* (one which gets siginfo).
*/
-static int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
- siginfo_t *info, sigset_t *oldset,
- struct pt_regs * regs, unsigned long newsp)
+static int handle_rt_signal(unsigned long sig, struct k_sigaction *ka,
+ siginfo_t *info, sigset_t *oldset,
+ struct pt_regs *regs, unsigned long newsp)
{
- struct rt_sigframe32 __user *rt_sf;
- struct mcontext32 __user *frame;
+ struct rt_sigframe __user *rt_sf;
+ struct mcontext __user *frame;
unsigned long origsp = newsp;
- compat_sigset_t c_oldset;
/* Set up Signal Frame */
/* Put a Real Time Context onto stack */
newsp -= sizeof(*rt_sf);
- rt_sf = (struct rt_sigframe32 __user *)newsp;
+ rt_sf = (struct rt_sigframe __user *)newsp;
/* create a stack frame for the caller of the handler */
- newsp -= __SIGNAL_FRAMESIZE32 + 16;
+ newsp -= __SIGNAL_FRAMESIZE + 16;
if (!access_ok(VERIFY_WRITE, (void __user *)newsp, origsp - newsp))
goto badframe;
- compat_from_sigset(&c_oldset, oldset);
-
/* Put the siginfo & fill in most of the ucontext */
- if (copy_siginfo_to_user32(&rt_sf->info, info)
+ if (copy_siginfo_to_user(&rt_sf->info, info)
|| __put_user(0, &rt_sf->uc.uc_flags)
|| __put_user(0, &rt_sf->uc.uc_link)
|| __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp)
|| __put_user(sas_ss_flags(regs->gpr[1]),
&rt_sf->uc.uc_stack.ss_flags)
|| __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size)
- || __put_user((u32)(u64)&rt_sf->uc.uc_mcontext, &rt_sf->uc.uc_regs)
- || __copy_to_user(&rt_sf->uc.uc_sigmask, &c_oldset, sizeof(c_oldset)))
+ || __put_user(to_user_ptr(&rt_sf->uc.uc_mcontext),
+ &rt_sf->uc.uc_regs)
+ || put_sigset_t(&rt_sf->uc.uc_sigmask, oldset))
goto badframe;
/* Save user registers on the stack */
frame = &rt_sf->uc.uc_mcontext;
- if (put_user(regs->gpr[1], (u32 __user *)newsp))
- goto badframe;
-
+#ifdef CONFIG_PPC64
if (vdso32_rt_sigtramp && current->thread.vdso_base) {
if (save_user_regs(regs, frame, 0))
goto badframe;
regs->link = current->thread.vdso_base + vdso32_rt_sigtramp;
- } else {
+ } else
+#endif
+ {
if (save_user_regs(regs, frame, __NR_rt_sigreturn))
goto badframe;
regs->link = (unsigned long) frame->tramp;
}
- regs->gpr[1] = (unsigned long) newsp;
+ if (put_user(regs->gpr[1], (u32 __user *)newsp))
+ goto badframe;
+ regs->gpr[1] = newsp;
regs->gpr[3] = sig;
regs->gpr[4] = (unsigned long) &rt_sf->info;
regs->gpr[5] = (unsigned long) &rt_sf->uc;
regs->gpr[6] = (unsigned long) rt_sf;
regs->nip = (unsigned long) ka->sa.sa_handler;
regs->trap = 0;
+#ifdef CONFIG_PPC64
regs->result = 0;
if (test_thread_flag(TIF_SINGLESTEP))
ptrace_notify(SIGTRAP);
-
+#endif
return 1;
badframe:
-#if DEBUG_SIG
+#ifdef DEBUG_SIG
printk("badframe in handle_rt_signal, regs=%p frame=%p newsp=%lx\n",
regs, frame, newsp);
#endif
@@ -692,46 +847,50 @@ badframe:
return 0;
}
-static long do_setcontext32(struct ucontext32 __user *ucp, struct pt_regs *regs, int sig)
+static int do_setcontext(struct ucontext __user *ucp, struct pt_regs *regs, int sig)
{
- compat_sigset_t c_set;
sigset_t set;
- u32 mcp;
+ struct mcontext __user *mcp;
+
+ if (get_sigset_t(&set, &ucp->uc_sigmask))
+ return -EFAULT;
+#ifdef CONFIG_PPC64
+ {
+ u32 cmcp;
- if (__copy_from_user(&c_set, &ucp->uc_sigmask, sizeof(c_set))
- || __get_user(mcp, &ucp->uc_regs))
+ if (__get_user(cmcp, &ucp->uc_regs))
+ return -EFAULT;
+ mcp = (struct mcontext __user *)(u64)cmcp;
+ }
+#else
+ if (__get_user(mcp, &ucp->uc_regs))
return -EFAULT;
- sigset_from_compat(&set, &c_set);
+#endif
restore_sigmask(&set);
- if (restore_user_regs(regs, (struct mcontext32 __user *)(u64)mcp, sig))
+ if (restore_user_regs(regs, mcp, sig))
return -EFAULT;
return 0;
}
-/*
- * Handle {get,set,swap}_context operations for 32 bits processes
- */
-
-long sys32_swapcontext(struct ucontext32 __user *old_ctx,
- struct ucontext32 __user *new_ctx,
+long sys_swapcontext(struct ucontext __user *old_ctx,
+ struct ucontext __user *new_ctx,
int ctx_size, int r6, int r7, int r8, struct pt_regs *regs)
{
unsigned char tmp;
- compat_sigset_t c_set;
/* Context size is for future use. Right now, we only make sure
* we are passed something we understand
*/
- if (ctx_size < sizeof(struct ucontext32))
+ if (ctx_size < sizeof(struct ucontext))
return -EINVAL;
if (old_ctx != NULL) {
- compat_from_sigset(&c_set, &current->blocked);
if (!access_ok(VERIFY_WRITE, old_ctx, sizeof(*old_ctx))
|| save_user_regs(regs, &old_ctx->uc_mcontext, 0)
- || __copy_to_user(&old_ctx->uc_sigmask, &c_set, sizeof(c_set))
- || __put_user((u32)(u64)&old_ctx->uc_mcontext, &old_ctx->uc_regs))
+ || put_sigset_t(&old_ctx->uc_sigmask, &current->blocked)
+ || __put_user(to_user_ptr(&old_ctx->uc_mcontext),
+ &old_ctx->uc_regs))
return -EFAULT;
}
if (new_ctx == NULL)
@@ -752,27 +911,26 @@ long sys32_swapcontext(struct ucontext32 __user *old_ctx,
* or if another thread unmaps the region containing the context.
* We kill the task with a SIGSEGV in this situation.
*/
- if (do_setcontext32(new_ctx, regs, 0))
+ if (do_setcontext(new_ctx, regs, 0))
do_exit(SIGSEGV);
-
+ sigreturn_exit(regs);
+ /* doesn't actually return back to here */
return 0;
}
-long sys32_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
+long sys_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
struct pt_regs *regs)
{
- struct rt_sigframe32 __user *rt_sf;
- int ret;
-
+ struct rt_sigframe __user *rt_sf;
/* Always make any pending restarted system calls return -EINTR */
current_thread_info()->restart_block.fn = do_no_restart_syscall;
- rt_sf = (struct rt_sigframe32 __user *)
- (regs->gpr[1] + __SIGNAL_FRAMESIZE32 + 16);
+ rt_sf = (struct rt_sigframe __user *)
+ (regs->gpr[1] + __SIGNAL_FRAMESIZE + 16);
if (!access_ok(VERIFY_READ, rt_sf, sizeof(*rt_sf)))
goto bad;
- if (do_setcontext32(&rt_sf->uc, regs, 1))
+ if (do_setcontext(&rt_sf->uc, regs, 1))
goto bad;
/*
@@ -781,62 +939,165 @@ long sys32_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
* signal return. But other architectures do this and we have
* always done it up until now so it is probably better not to
* change it. -- paulus
- * We use the sys32_ version that does the 32/64 bits conversion
+ */
+#ifdef CONFIG_PPC64
+ /*
+ * We use the compat_sys_ version that does the 32/64 bits conversion
* and takes userland pointer directly. What about error checking ?
* nobody does any...
*/
- sys32_sigaltstack((u32)(u64)&rt_sf->uc.uc_stack, 0, 0, 0, 0, 0, regs);
-
- ret = regs->result;
-
- return ret;
+ compat_sys_sigaltstack((u32)(u64)&rt_sf->uc.uc_stack, 0, 0, 0, 0, 0, regs);
+ return (int)regs->result;
+#else
+ do_sigaltstack(&rt_sf->uc.uc_stack, NULL, regs->gpr[1]);
+ sigreturn_exit(regs); /* doesn't return here */
+ return 0;
+#endif
bad:
force_sig(SIGSEGV, current);
return 0;
}
+#ifdef CONFIG_PPC32
+int sys_debug_setcontext(struct ucontext __user *ctx,
+ int ndbg, struct sig_dbg_op __user *dbg,
+ int r6, int r7, int r8,
+ struct pt_regs *regs)
+{
+ struct sig_dbg_op op;
+ int i;
+ unsigned long new_msr = regs->msr;
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+ unsigned long new_dbcr0 = current->thread.dbcr0;
+#endif
+
+ for (i=0; i<ndbg; i++) {
+ if (__copy_from_user(&op, dbg, sizeof(op)))
+ return -EFAULT;
+ switch (op.dbg_type) {
+ case SIG_DBG_SINGLE_STEPPING:
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+ if (op.dbg_value) {
+ new_msr |= MSR_DE;
+ new_dbcr0 |= (DBCR0_IDM | DBCR0_IC);
+ } else {
+ new_msr &= ~MSR_DE;
+ new_dbcr0 &= ~(DBCR0_IDM | DBCR0_IC);
+ }
+#else
+ if (op.dbg_value)
+ new_msr |= MSR_SE;
+ else
+ new_msr &= ~MSR_SE;
+#endif
+ break;
+ case SIG_DBG_BRANCH_TRACING:
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+ return -EINVAL;
+#else
+ if (op.dbg_value)
+ new_msr |= MSR_BE;
+ else
+ new_msr &= ~MSR_BE;
+#endif
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ }
+
+ /* We wait until here to actually install the values in the
+ registers so if we fail in the above loop, it will not
+ affect the contents of these registers. After this point,
+ failure is a problem, anyway, and it's very unlikely unless
+ the user is really doing something wrong. */
+ regs->msr = new_msr;
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+ current->thread.dbcr0 = new_dbcr0;
+#endif
+
+ /*
+ * If we get a fault copying the context into the kernel's
+ * image of the user's registers, we can't just return -EFAULT
+ * because the user's registers will be corrupted. For instance
+ * the NIP value may have been updated but not some of the
+ * other registers. Given that we have done the access_ok
+ * and successfully read the first and last bytes of the region
+ * above, this should only happen in an out-of-memory situation
+ * or if another thread unmaps the region containing the context.
+ * We kill the task with a SIGSEGV in this situation.
+ */
+ if (do_setcontext(ctx, regs, 1)) {
+ force_sig(SIGSEGV, current);
+ goto out;
+ }
+
+ /*
+ * It's not clear whether or why it is desirable to save the
+ * sigaltstack setting on signal delivery and restore it on
+ * signal return. But other architectures do this and we have
+ * always done it up until now so it is probably better not to
+ * change it. -- paulus
+ */
+ do_sigaltstack(&ctx->uc_stack, NULL, regs->gpr[1]);
+
+ sigreturn_exit(regs);
+ /* doesn't actually return back to here */
+
+ out:
+ return 0;
+}
+#endif
/*
* OK, we're invoking a handler
*/
-static int handle_signal32(unsigned long sig, struct k_sigaction *ka,
- siginfo_t *info, sigset_t *oldset,
- struct pt_regs * regs, unsigned long newsp)
+static int handle_signal(unsigned long sig, struct k_sigaction *ka,
+ siginfo_t *info, sigset_t *oldset, struct pt_regs *regs,
+ unsigned long newsp)
{
- struct sigcontext32 __user *sc;
- struct sigregs32 __user *frame;
+ struct sigcontext __user *sc;
+ struct sigregs __user *frame;
unsigned long origsp = newsp;
/* Set up Signal Frame */
- newsp -= sizeof(struct sigregs32);
- frame = (struct sigregs32 __user *) newsp;
+ newsp -= sizeof(struct sigregs);
+ frame = (struct sigregs __user *) newsp;
/* Put a sigcontext on the stack */
newsp -= sizeof(*sc);
- sc = (struct sigcontext32 __user *) newsp;
+ sc = (struct sigcontext __user *) newsp;
/* create a stack frame for the caller of the handler */
- newsp -= __SIGNAL_FRAMESIZE32;
+ newsp -= __SIGNAL_FRAMESIZE;
if (!access_ok(VERIFY_WRITE, (void __user *) newsp, origsp - newsp))
goto badframe;
#if _NSIG != 64
-#error "Please adjust handle_signal32()"
+#error "Please adjust handle_signal()"
#endif
- if (__put_user((u32)(u64)ka->sa.sa_handler, &sc->handler)
+ if (__put_user(to_user_ptr(ka->sa.sa_handler), &sc->handler)
|| __put_user(oldset->sig[0], &sc->oldmask)
+#ifdef CONFIG_PPC64
|| __put_user((oldset->sig[0] >> 32), &sc->_unused[3])
- || __put_user((u32)(u64)frame, &sc->regs)
+#else
+ || __put_user(oldset->sig[1], &sc->_unused[3])
+#endif
+ || __put_user(to_user_ptr(frame), &sc->regs)
|| __put_user(sig, &sc->signal))
goto badframe;
+#ifdef CONFIG_PPC64
if (vdso32_sigtramp && current->thread.vdso_base) {
if (save_user_regs(regs, &frame->mctx, 0))
goto badframe;
regs->link = current->thread.vdso_base + vdso32_sigtramp;
- } else {
+ } else
+#endif
+ {
if (save_user_regs(regs, &frame->mctx, __NR_sigreturn))
goto badframe;
regs->link = (unsigned long) frame->mctx.tramp;
@@ -844,22 +1105,24 @@ static int handle_signal32(unsigned long sig, struct k_sigaction *ka,
if (put_user(regs->gpr[1], (u32 __user *)newsp))
goto badframe;
- regs->gpr[1] = (unsigned long) newsp;
+ regs->gpr[1] = newsp;
regs->gpr[3] = sig;
regs->gpr[4] = (unsigned long) sc;
regs->nip = (unsigned long) ka->sa.sa_handler;
regs->trap = 0;
+#ifdef CONFIG_PPC64
regs->result = 0;
if (test_thread_flag(TIF_SINGLESTEP))
ptrace_notify(SIGTRAP);
+#endif
return 1;
badframe:
-#if DEBUG_SIG
- printk("badframe in handle_signal, regs=%p frame=%x newsp=%x\n",
- regs, frame, *newspp);
+#ifdef DEBUG_SIG
+ printk("badframe in handle_signal, regs=%p frame=%p newsp=%lx\n",
+ regs, frame, newsp);
#endif
force_sigsegv(sig, current);
return 0;
@@ -868,65 +1131,69 @@ badframe:
/*
* Do a signal return; undo the signal stack.
*/
-long sys32_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
+long sys_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
struct pt_regs *regs)
{
- struct sigcontext32 __user *sc;
- struct sigcontext32 sigctx;
- struct mcontext32 __user *sr;
+ struct sigcontext __user *sc;
+ struct sigcontext sigctx;
+ struct mcontext __user *sr;
sigset_t set;
- int ret;
/* Always make any pending restarted system calls return -EINTR */
current_thread_info()->restart_block.fn = do_no_restart_syscall;
- sc = (struct sigcontext32 __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE32);
+ sc = (struct sigcontext __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
goto badframe;
+#ifdef CONFIG_PPC64
/*
* Note that PPC32 puts the upper 32 bits of the sigmask in the
* unused part of the signal stackframe
*/
set.sig[0] = sigctx.oldmask + ((long)(sigctx._unused[3]) << 32);
+#else
+ set.sig[0] = sigctx.oldmask;
+ set.sig[1] = sigctx._unused[3];
+#endif
restore_sigmask(&set);
- sr = (struct mcontext32 __user *)(u64)sigctx.regs;
+ sr = (struct mcontext __user *)from_user_ptr(sigctx.regs);
if (!access_ok(VERIFY_READ, sr, sizeof(*sr))
|| restore_user_regs(regs, sr, 1))
goto badframe;
- ret = regs->result;
- return ret;
+#ifdef CONFIG_PPC64
+ return (int)regs->result;
+#else
+ sigreturn_exit(regs); /* doesn't return */
+ return 0;
+#endif
badframe:
force_sig(SIGSEGV, current);
return 0;
}
-
-
-/*
- * Start of do_signal32 routine
- *
- * This routine gets control when a pending signal needs to be processed
- * in the 32 bit target thread -
- *
- * It handles both rt and non-rt signals
- */
-
/*
* Note that 'init' is a special process: it doesn't get signals it doesn't
* want to handle. Thus you cannot kill init even with a SIGKILL even by
* mistake.
*/
-
-int do_signal32(sigset_t *oldset, struct pt_regs *regs)
+int do_signal(sigset_t *oldset, struct pt_regs *regs)
{
siginfo_t info;
+ struct k_sigaction ka;
unsigned int frame, newsp;
int signr, ret;
- struct k_sigaction ka;
+
+#ifdef CONFIG_PPC32
+ if (try_to_freeze()) {
+ signr = 0;
+ if (!signal_pending(current))
+ goto no_signal;
+ }
+#endif
if (!oldset)
oldset = &current->blocked;
@@ -934,7 +1201,9 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs)
newsp = frame = 0;
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-
+#ifdef CONFIG_PPC32
+no_signal:
+#endif
if (TRAP(regs) == 0x0C00 /* System Call! */
&& regs->ccr & 0x10000000 /* error signalled */
&& ((ret = regs->gpr[3]) == ERESTARTSYS
@@ -964,12 +1233,13 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs)
return 0; /* no signals delivered */
if ((ka.sa.sa_flags & SA_ONSTACK) && current->sas_ss_size
- && (!on_sig_stack(regs->gpr[1])))
- newsp = (current->sas_ss_sp + current->sas_ss_size);
+ && !on_sig_stack(regs->gpr[1]))
+ newsp = current->sas_ss_sp + current->sas_ss_size;
else
newsp = regs->gpr[1];
newsp &= ~0xfUL;
+#ifdef CONFIG_PPC64
/*
* Reenable the DABR before delivering the signal to
* user space. The DABR will have been cleared if it
@@ -977,12 +1247,13 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs)
*/
if (current->thread.dabr)
set_dabr(current->thread.dabr);
+#endif
/* Whee! Actually deliver the signal. */
if (ka.sa.sa_flags & SA_SIGINFO)
- ret = handle_rt_signal32(signr, &ka, &info, oldset, regs, newsp);
+ ret = handle_rt_signal(signr, &ka, &info, oldset, regs, newsp);
else
- ret = handle_signal32(signr, &ka, &info, oldset, regs, newsp);
+ ret = handle_signal(signr, &ka, &info, oldset, regs, newsp);
if (ret) {
spin_lock_irq(&current->sighand->siglock);
diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c
index e93c13458910..a8210ed5c686 100644
--- a/arch/ppc64/kernel/sys_ppc32.c
+++ b/arch/powerpc/kernel/sys_ppc32.c
@@ -53,8 +53,7 @@
#include <asm/time.h>
#include <asm/mmu_context.h>
#include <asm/systemcfg.h>
-
-#include "pci.h"
+#include <asm/ppc-pci.h>
/* readdir & getdents */
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
@@ -114,96 +113,6 @@ out:
return error;
}
-struct linux_dirent32 {
- u32 d_ino;
- u32 d_off;
- unsigned short d_reclen;
- char d_name[1];
-};
-
-struct getdents_callback32 {
- struct linux_dirent32 __user * current_dir;
- struct linux_dirent32 __user * previous;
- int count;
- int error;
-};
-
-static int filldir(void * __buf, const char * name, int namlen, off_t offset,
- ino_t ino, unsigned int d_type)
-{
- struct linux_dirent32 __user * dirent;
- struct getdents_callback32 * buf = (struct getdents_callback32 *) __buf;
- int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 2);
-
- buf->error = -EINVAL; /* only used if we fail.. */
- if (reclen > buf->count)
- return -EINVAL;
- dirent = buf->previous;
- if (dirent) {
- if (__put_user(offset, &dirent->d_off))
- goto efault;
- }
- dirent = buf->current_dir;
- if (__put_user(ino, &dirent->d_ino))
- goto efault;
- if (__put_user(reclen, &dirent->d_reclen))
- goto efault;
- if (copy_to_user(dirent->d_name, name, namlen))
- goto efault;
- if (__put_user(0, dirent->d_name + namlen))
- goto efault;
- if (__put_user(d_type, (char __user *) dirent + reclen - 1))
- goto efault;
- buf->previous = dirent;
- dirent = (void __user *)dirent + reclen;
- buf->current_dir = dirent;
- buf->count -= reclen;
- return 0;
-efault:
- buf->error = -EFAULT;
- return -EFAULT;
-}
-
-asmlinkage long sys32_getdents(unsigned int fd, struct linux_dirent32 __user *dirent,
- unsigned int count)
-{
- struct file * file;
- struct linux_dirent32 __user * lastdirent;
- struct getdents_callback32 buf;
- int error;
-
- error = -EFAULT;
- if (!access_ok(VERIFY_WRITE, dirent, count))
- goto out;
-
- error = -EBADF;
- file = fget(fd);
- if (!file)
- goto out;
-
- buf.current_dir = dirent;
- buf.previous = NULL;
- buf.count = count;
- buf.error = 0;
-
- error = vfs_readdir(file, (filldir_t)filldir, &buf);
- if (error < 0)
- goto out_putf;
- error = buf.error;
- lastdirent = buf.previous;
- if (lastdirent) {
- if (put_user(file->f_pos, &lastdirent->d_off))
- error = -EFAULT;
- else
- error = count - buf.count;
- }
-
-out_putf:
- fput(file);
-out:
- return error;
-}
-
asmlinkage long ppc32_select(u32 n, compat_ulong_t __user *inp,
compat_ulong_t __user *outp, compat_ulong_t __user *exp,
compat_uptr_t tvp_x)
@@ -248,7 +157,7 @@ int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_sysfs(u32 option, u32 arg1, u32 arg2)
+asmlinkage long compat_sys_sysfs(u32 option, u32 arg1, u32 arg2)
{
return sys_sysfs((int)option, arg1, arg2);
}
@@ -270,7 +179,7 @@ struct timex32 {
extern int do_adjtimex(struct timex *);
extern void ppc_adjtimex(void);
-asmlinkage long sys32_adjtimex(struct timex32 __user *utp)
+asmlinkage long compat_sys_adjtimex(struct timex32 __user *utp)
{
struct timex txc;
int ret;
@@ -329,7 +238,7 @@ asmlinkage long sys32_adjtimex(struct timex32 __user *utp)
return ret;
}
-asmlinkage long sys32_pause(void)
+asmlinkage long compat_sys_pause(void)
{
current->state = TASK_INTERRUPTIBLE;
schedule();
@@ -375,7 +284,7 @@ struct sysinfo32 {
char _f[20-2*sizeof(int)-sizeof(int)];
};
-asmlinkage long sys32_sysinfo(struct sysinfo32 __user *info)
+asmlinkage long compat_sys_sysinfo(struct sysinfo32 __user *info)
{
struct sysinfo s;
int ret, err;
@@ -432,7 +341,7 @@ asmlinkage long sys32_sysinfo(struct sysinfo32 __user *info)
sorts of things, like timeval and itimerval. */
extern struct timezone sys_tz;
-asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
+asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
{
if (tv) {
struct timeval ktv;
@@ -450,7 +359,7 @@ asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv, struct time
-asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
+asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
{
struct timespec kts;
struct timezone ktz;
@@ -468,7 +377,7 @@ asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, struct time
}
#ifdef CONFIG_SYSVIPC
-long sys32_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr,
+long compat_sys_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr,
u32 fifth)
{
int version;
@@ -539,7 +448,7 @@ long sys32_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr,
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_sendfile(u32 out_fd, u32 in_fd, compat_off_t __user * offset, u32 count)
+asmlinkage long compat_sys_sendfile(u32 out_fd, u32 in_fd, compat_off_t __user * offset, u32 count)
{
mm_segment_t old_fs = get_fs();
int ret;
@@ -561,7 +470,7 @@ asmlinkage long sys32_sendfile(u32 out_fd, u32 in_fd, compat_off_t __user * offs
return ret;
}
-asmlinkage int sys32_sendfile64(int out_fd, int in_fd, compat_loff_t __user *offset, s32 count)
+asmlinkage int compat_sys_sendfile64(int out_fd, int in_fd, compat_loff_t __user *offset, s32 count)
{
mm_segment_t old_fs = get_fs();
int ret;
@@ -583,7 +492,7 @@ asmlinkage int sys32_sendfile64(int out_fd, int in_fd, compat_loff_t __user *off
return ret;
}
-long sys32_execve(unsigned long a0, unsigned long a1, unsigned long a2,
+long compat_sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
unsigned long a3, unsigned long a4, unsigned long a5,
struct pt_regs *regs)
{
@@ -610,58 +519,12 @@ out:
return error;
}
-/* Set up a thread for executing a new program. */
-void start_thread32(struct pt_regs* regs, unsigned long nip, unsigned long sp)
-{
- set_fs(USER_DS);
-
- /*
- * If we exec out of a kernel thread then thread.regs will not be
- * set. Do it now.
- */
- if (!current->thread.regs) {
- unsigned long childregs = (unsigned long)current->thread_info +
- THREAD_SIZE;
- childregs -= sizeof(struct pt_regs);
- current->thread.regs = (struct pt_regs *)childregs;
- }
-
- /*
- * ELF_PLAT_INIT already clears all registers but it also sets r2.
- * So just clear r2 here.
- */
- regs->gpr[2] = 0;
-
- regs->nip = nip;
- regs->gpr[1] = sp;
- regs->msr = MSR_USER32;
-#ifndef CONFIG_SMP
- if (last_task_used_math == current)
- last_task_used_math = 0;
-#endif /* CONFIG_SMP */
- current->thread.fpscr = 0;
- memset(current->thread.fpr, 0, sizeof(current->thread.fpr));
-#ifdef CONFIG_ALTIVEC
-#ifndef CONFIG_SMP
- if (last_task_used_altivec == current)
- last_task_used_altivec = 0;
-#endif /* CONFIG_SMP */
- memset(current->thread.vr, 0, sizeof(current->thread.vr));
- current->thread.vscr.u[0] = 0;
- current->thread.vscr.u[1] = 0;
- current->thread.vscr.u[2] = 0;
- current->thread.vscr.u[3] = 0x00010000; /* Java mode disabled */
- current->thread.vrsave = 0;
- current->thread.used_vr = 0;
-#endif /* CONFIG_ALTIVEC */
-}
-
/* Note: it is necessary to treat option as an unsigned int,
* with the corresponding cast to a signed int to insure that the
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_prctl(u32 option, u32 arg2, u32 arg3, u32 arg4, u32 arg5)
+asmlinkage long compat_sys_prctl(u32 option, u32 arg2, u32 arg3, u32 arg4, u32 arg5)
{
return sys_prctl((int)option,
(unsigned long) arg2,
@@ -675,7 +538,7 @@ asmlinkage long sys32_prctl(u32 option, u32 arg2, u32 arg3, u32 arg4, u32 arg5)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_sched_rr_get_interval(u32 pid, struct compat_timespec __user *interval)
+asmlinkage long compat_sys_sched_rr_get_interval(u32 pid, struct compat_timespec __user *interval)
{
struct timespec t;
int ret;
@@ -690,7 +553,7 @@ asmlinkage long sys32_sched_rr_get_interval(u32 pid, struct compat_timespec __us
return ret;
}
-asmlinkage int sys32_pciconfig_read(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
+asmlinkage int compat_sys_pciconfig_read(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
{
return sys_pciconfig_read((unsigned long) bus,
(unsigned long) dfn,
@@ -699,7 +562,7 @@ asmlinkage int sys32_pciconfig_read(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf
compat_ptr(ubuf));
}
-asmlinkage int sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
+asmlinkage int compat_sys_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
{
return sys_pciconfig_write((unsigned long) bus,
(unsigned long) dfn,
@@ -708,7 +571,7 @@ asmlinkage int sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubu
compat_ptr(ubuf));
}
-asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn)
+asmlinkage int compat_sys_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn)
{
return sys_pciconfig_iobase(which, in_bus, in_devfn);
}
@@ -719,7 +582,7 @@ asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_access(const char __user * filename, u32 mode)
+asmlinkage long compat_sys_access(const char __user * filename, u32 mode)
{
return sys_access(filename, (int)mode);
}
@@ -730,7 +593,7 @@ asmlinkage long sys32_access(const char __user * filename, u32 mode)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_creat(const char __user * pathname, u32 mode)
+asmlinkage long compat_sys_creat(const char __user * pathname, u32 mode)
{
return sys_creat(pathname, (int)mode);
}
@@ -741,7 +604,7 @@ asmlinkage long sys32_creat(const char __user * pathname, u32 mode)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_waitpid(u32 pid, unsigned int __user * stat_addr, u32 options)
+asmlinkage long compat_sys_waitpid(u32 pid, unsigned int __user * stat_addr, u32 options)
{
return sys_waitpid((int)pid, stat_addr, (int)options);
}
@@ -752,7 +615,7 @@ asmlinkage long sys32_waitpid(u32 pid, unsigned int __user * stat_addr, u32 opti
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_getgroups(u32 gidsetsize, gid_t __user *grouplist)
+asmlinkage long compat_sys_getgroups(u32 gidsetsize, gid_t __user *grouplist)
{
return sys_getgroups((int)gidsetsize, grouplist);
}
@@ -763,7 +626,7 @@ asmlinkage long sys32_getgroups(u32 gidsetsize, gid_t __user *grouplist)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_getpgid(u32 pid)
+asmlinkage long compat_sys_getpgid(u32 pid)
{
return sys_getpgid((int)pid);
}
@@ -775,7 +638,7 @@ asmlinkage long sys32_getpgid(u32 pid)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_getsid(u32 pid)
+asmlinkage long compat_sys_getsid(u32 pid)
{
return sys_getsid((int)pid);
}
@@ -786,7 +649,7 @@ asmlinkage long sys32_getsid(u32 pid)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_kill(u32 pid, u32 sig)
+asmlinkage long compat_sys_kill(u32 pid, u32 sig)
{
return sys_kill((int)pid, (int)sig);
}
@@ -797,12 +660,12 @@ asmlinkage long sys32_kill(u32 pid, u32 sig)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_mkdir(const char __user * pathname, u32 mode)
+asmlinkage long compat_sys_mkdir(const char __user * pathname, u32 mode)
{
return sys_mkdir(pathname, (int)mode);
}
-long sys32_nice(u32 increment)
+long compat_sys_nice(u32 increment)
{
/* sign extend increment */
return sys_nice((int)increment);
@@ -819,7 +682,7 @@ off_t ppc32_lseek(unsigned int fd, u32 offset, unsigned int origin)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_readlink(const char __user * path, char __user * buf, u32 bufsiz)
+asmlinkage long compat_sys_readlink(const char __user * path, char __user * buf, u32 bufsiz)
{
return sys_readlink(path, buf, (int)bufsiz);
}
@@ -829,7 +692,7 @@ asmlinkage long sys32_readlink(const char __user * path, char __user * buf, u32
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_sched_get_priority_max(u32 policy)
+asmlinkage long compat_sys_sched_get_priority_max(u32 policy)
{
return sys_sched_get_priority_max((int)policy);
}
@@ -840,7 +703,7 @@ asmlinkage long sys32_sched_get_priority_max(u32 policy)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_sched_get_priority_min(u32 policy)
+asmlinkage long compat_sys_sched_get_priority_min(u32 policy)
{
return sys_sched_get_priority_min((int)policy);
}
@@ -851,7 +714,7 @@ asmlinkage long sys32_sched_get_priority_min(u32 policy)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_sched_getparam(u32 pid, struct sched_param __user *param)
+asmlinkage long compat_sys_sched_getparam(u32 pid, struct sched_param __user *param)
{
return sys_sched_getparam((int)pid, param);
}
@@ -862,7 +725,7 @@ asmlinkage long sys32_sched_getparam(u32 pid, struct sched_param __user *param)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_sched_getscheduler(u32 pid)
+asmlinkage long compat_sys_sched_getscheduler(u32 pid)
{
return sys_sched_getscheduler((int)pid);
}
@@ -873,7 +736,7 @@ asmlinkage long sys32_sched_getscheduler(u32 pid)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_sched_setparam(u32 pid, struct sched_param __user *param)
+asmlinkage long compat_sys_sched_setparam(u32 pid, struct sched_param __user *param)
{
return sys_sched_setparam((int)pid, param);
}
@@ -884,7 +747,7 @@ asmlinkage long sys32_sched_setparam(u32 pid, struct sched_param __user *param)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_sched_setscheduler(u32 pid, u32 policy, struct sched_param __user *param)
+asmlinkage long compat_sys_sched_setscheduler(u32 pid, u32 policy, struct sched_param __user *param)
{
return sys_sched_setscheduler((int)pid, (int)policy, param);
}
@@ -895,7 +758,7 @@ asmlinkage long sys32_sched_setscheduler(u32 pid, u32 policy, struct sched_param
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_setdomainname(char __user *name, u32 len)
+asmlinkage long compat_sys_setdomainname(char __user *name, u32 len)
{
return sys_setdomainname(name, (int)len);
}
@@ -906,13 +769,13 @@ asmlinkage long sys32_setdomainname(char __user *name, u32 len)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_setgroups(u32 gidsetsize, gid_t __user *grouplist)
+asmlinkage long compat_sys_setgroups(u32 gidsetsize, gid_t __user *grouplist)
{
return sys_setgroups((int)gidsetsize, grouplist);
}
-asmlinkage long sys32_sethostname(char __user *name, u32 len)
+asmlinkage long compat_sys_sethostname(char __user *name, u32 len)
{
/* sign extend len */
return sys_sethostname(name, (int)len);
@@ -924,30 +787,30 @@ asmlinkage long sys32_sethostname(char __user *name, u32 len)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_setpgid(u32 pid, u32 pgid)
+asmlinkage long compat_sys_setpgid(u32 pid, u32 pgid)
{
return sys_setpgid((int)pid, (int)pgid);
}
-long sys32_getpriority(u32 which, u32 who)
+long compat_sys_getpriority(u32 which, u32 who)
{
/* sign extend which and who */
return sys_getpriority((int)which, (int)who);
}
-long sys32_setpriority(u32 which, u32 who, u32 niceval)
+long compat_sys_setpriority(u32 which, u32 who, u32 niceval)
{
/* sign extend which, who and niceval */
return sys_setpriority((int)which, (int)who, (int)niceval);
}
-long sys32_ioprio_get(u32 which, u32 who)
+long compat_sys_ioprio_get(u32 which, u32 who)
{
/* sign extend which and who */
return sys_ioprio_get((int)which, (int)who);
}
-long sys32_ioprio_set(u32 which, u32 who, u32 ioprio)
+long compat_sys_ioprio_set(u32 which, u32 who, u32 ioprio)
{
/* sign extend which, who and ioprio */
return sys_ioprio_set((int)which, (int)who, (int)ioprio);
@@ -958,12 +821,12 @@ long sys32_ioprio_set(u32 which, u32 who, u32 ioprio)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_ssetmask(u32 newmask)
+asmlinkage long compat_sys_ssetmask(u32 newmask)
{
return sys_ssetmask((int) newmask);
}
-asmlinkage long sys32_syslog(u32 type, char __user * buf, u32 len)
+asmlinkage long compat_sys_syslog(u32 type, char __user * buf, u32 len)
{
/* sign extend len */
return sys_syslog(type, buf, (int)len);
@@ -975,7 +838,7 @@ asmlinkage long sys32_syslog(u32 type, char __user * buf, u32 len)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_umask(u32 mask)
+asmlinkage long compat_sys_umask(u32 mask)
{
return sys_umask((int)mask);
}
@@ -991,7 +854,7 @@ struct __sysctl_args32 {
u32 __unused[4];
};
-asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
+asmlinkage long compat_sys_sysctl(struct __sysctl_args32 __user *args)
{
struct __sysctl_args32 tmp;
int error;
@@ -1032,55 +895,7 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
}
#endif
-asmlinkage int sys32_uname(struct old_utsname __user * name)
-{
- int err = 0;
-
- down_read(&uts_sem);
- if (copy_to_user(name, &system_utsname, sizeof(*name)))
- err = -EFAULT;
- up_read(&uts_sem);
- if (!err && personality(current->personality) == PER_LINUX32) {
- /* change "ppc64" to "ppc" */
- if (__put_user(0, name->machine + 3)
- || __put_user(0, name->machine + 4))
- err = -EFAULT;
- }
- return err;
-}
-
-asmlinkage int sys32_olduname(struct oldold_utsname __user * name)
-{
- int error;
-
- if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
- return -EFAULT;
-
- down_read(&uts_sem);
- error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
- error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
- error |= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
- error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
- error |= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
- error |= __put_user(0,name->release+__OLD_UTS_LEN);
- error |= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
- error |= __put_user(0,name->version+__OLD_UTS_LEN);
- error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
- error |= __put_user(0,name->machine+__OLD_UTS_LEN);
- if (personality(current->personality) == PER_LINUX32) {
- /* change "ppc64" to "ppc" */
- error |= __put_user(0, name->machine + 3);
- error |= __put_user(0, name->machine + 4);
- }
-
- up_read(&uts_sem);
-
- error = error ? -EFAULT : 0;
-
- return error;
-}
-
-unsigned long sys32_mmap2(unsigned long addr, size_t len,
+unsigned long compat_sys_mmap2(unsigned long addr, size_t len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff)
{
@@ -1088,29 +903,7 @@ unsigned long sys32_mmap2(unsigned long addr, size_t len,
return sys_mmap(addr, len, prot, flags, fd, pgoff << 12);
}
-int get_compat_timeval(struct timeval *tv, struct compat_timeval __user *ctv)
-{
- return (!access_ok(VERIFY_READ, ctv, sizeof(*ctv)) ||
- __get_user(tv->tv_sec, &ctv->tv_sec) ||
- __get_user(tv->tv_usec, &ctv->tv_usec)) ? -EFAULT : 0;
-}
-
-asmlinkage long sys32_utimes(char __user *filename, struct compat_timeval __user *tvs)
-{
- struct timeval ktvs[2], *ptr;
-
- ptr = NULL;
- if (tvs) {
- if (get_compat_timeval(&ktvs[0], &tvs[0]) ||
- get_compat_timeval(&ktvs[1], &tvs[1]))
- return -EFAULT;
- ptr = ktvs;
- }
-
- return do_utimes(filename, ptr);
-}
-
-long sys32_tgkill(u32 tgid, u32 pid, int sig)
+long compat_sys_tgkill(u32 tgid, u32 pid, int sig)
{
/* sign extend tgid, pid */
return sys_tgkill((int)tgid, (int)pid, sig);
@@ -1121,30 +914,30 @@ long sys32_tgkill(u32 tgid, u32 pid, int sig)
* The 32 bit ABI passes long longs in an odd even register pair.
*/
-compat_ssize_t sys32_pread64(unsigned int fd, char __user *ubuf, compat_size_t count,
+compat_ssize_t compat_sys_pread64(unsigned int fd, char __user *ubuf, compat_size_t count,
u32 reg6, u32 poshi, u32 poslo)
{
return sys_pread64(fd, ubuf, count, ((loff_t)poshi << 32) | poslo);
}
-compat_ssize_t sys32_pwrite64(unsigned int fd, char __user *ubuf, compat_size_t count,
+compat_ssize_t compat_sys_pwrite64(unsigned int fd, char __user *ubuf, compat_size_t count,
u32 reg6, u32 poshi, u32 poslo)
{
return sys_pwrite64(fd, ubuf, count, ((loff_t)poshi << 32) | poslo);
}
-compat_ssize_t sys32_readahead(int fd, u32 r4, u32 offhi, u32 offlo, u32 count)
+compat_ssize_t compat_sys_readahead(int fd, u32 r4, u32 offhi, u32 offlo, u32 count)
{
return sys_readahead(fd, ((loff_t)offhi << 32) | offlo, count);
}
-asmlinkage int sys32_truncate64(const char __user * path, u32 reg4,
+asmlinkage int compat_sys_truncate64(const char __user * path, u32 reg4,
unsigned long high, unsigned long low)
{
return sys_truncate(path, (high << 32) | low);
}
-asmlinkage int sys32_ftruncate64(unsigned int fd, u32 reg4, unsigned long high,
+asmlinkage int compat_sys_ftruncate64(unsigned int fd, u32 reg4, unsigned long high,
unsigned long low)
{
return sys_ftruncate(fd, (high << 32) | low);
@@ -1164,13 +957,6 @@ long ppc32_fadvise64(int fd, u32 unused, u32 offset_high, u32 offset_low,
advice);
}
-long ppc32_fadvise64_64(int fd, int advice, u32 offset_high, u32 offset_low,
- u32 len_high, u32 len_low)
-{
- return sys_fadvise64(fd, (u64)offset_high << 32 | offset_low,
- (u64)len_high << 32 | len_low, advice);
-}
-
long ppc32_timer_create(clockid_t clock,
struct compat_sigevent __user *ev32,
timer_t __user *timer_id)
@@ -1203,7 +989,7 @@ long ppc32_timer_create(clockid_t clock,
return err;
}
-asmlinkage long sys32_add_key(const char __user *_type,
+asmlinkage long compat_sys_add_key(const char __user *_type,
const char __user *_description,
const void __user *_payload,
u32 plen,
@@ -1212,7 +998,7 @@ asmlinkage long sys32_add_key(const char __user *_type,
return sys_add_key(_type, _description, _payload, plen, ringid);
}
-asmlinkage long sys32_request_key(const char __user *_type,
+asmlinkage long compat_sys_request_key(const char __user *_type,
const char __user *_description,
const char __user *_callout_info,
u32 destringid)
diff --git a/arch/ppc64/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c
index 05f16633bd2c..f72ced11212d 100644
--- a/arch/ppc64/kernel/syscalls.c
+++ b/arch/powerpc/kernel/syscalls.c
@@ -1,7 +1,6 @@
/*
- * linux/arch/ppc64/kernel/sys_ppc.c
+ * Implementation of various system calls for Linux/PowerPC
*
- * PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
*
* Derived from "arch/i386/kernel/sys_i386.c"
@@ -52,9 +51,8 @@ extern unsigned long wall_jiffies;
*
* This is really horribly ugly.
*/
-asmlinkage int
-sys_ipc (uint call, int first, unsigned long second, long third,
- void __user *ptr, long fifth)
+int sys_ipc(uint call, int first, unsigned long second, long third,
+ void __user *ptr, long fifth)
{
int version, ret;
@@ -88,7 +86,7 @@ sys_ipc (uint call, int first, unsigned long second, long third,
}
case MSGSND:
ret = sys_msgsnd(first, (struct msgbuf __user *)ptr,
- (size_t)second, third);
+ (size_t)second, third);
break;
case MSGRCV:
switch (version) {
@@ -113,41 +111,29 @@ sys_ipc (uint call, int first, unsigned long second, long third,
}
break;
case MSGGET:
- ret = sys_msgget ((key_t)first, (int)second);
+ ret = sys_msgget((key_t)first, (int)second);
break;
case MSGCTL:
ret = sys_msgctl(first, (int)second,
(struct msqid_ds __user *)ptr);
break;
- case SHMAT:
- switch (version) {
- default: {
- ulong raddr;
- ret = do_shmat(first, (char __user *) ptr,
- (int)second, &raddr);
- if (ret)
- break;
- ret = put_user (raddr, (ulong __user *) third);
- break;
- }
- case 1: /* iBCS2 emulator entry point */
- ret = -EINVAL;
- if (!segment_eq(get_fs(), get_ds()))
- break;
- ret = do_shmat(first, (char __user *)ptr,
- (int)second, (ulong *)third);
+ case SHMAT: {
+ ulong raddr;
+ ret = do_shmat(first, (char __user *)ptr, (int)second, &raddr);
+ if (ret)
break;
- }
+ ret = put_user(raddr, (ulong __user *) third);
break;
- case SHMDT:
- ret = sys_shmdt ((char __user *)ptr);
+ }
+ case SHMDT:
+ ret = sys_shmdt((char __user *)ptr);
break;
case SHMGET:
- ret = sys_shmget (first, (size_t)second, third);
+ ret = sys_shmget(first, (size_t)second, third);
break;
case SHMCTL:
ret = sys_shmctl(first, (int)second,
- (struct shmid_ds __user *)ptr);
+ (struct shmid_ds __user *)ptr);
break;
}
@@ -158,43 +144,89 @@ sys_ipc (uint call, int first, unsigned long second, long third,
* sys_pipe() is the normal C calling standard for creating
* a pipe. It's not the way unix traditionally does this, though.
*/
-asmlinkage int sys_pipe(int __user *fildes)
+int sys_pipe(int __user *fildes)
{
int fd[2];
int error;
-
+
error = do_pipe(fd);
if (!error) {
if (copy_to_user(fildes, fd, 2*sizeof(int)))
error = -EFAULT;
}
-
return error;
}
-unsigned long sys_mmap(unsigned long addr, size_t len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, off_t offset)
+static inline unsigned long do_mmap2(unsigned long addr, size_t len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long off, int shift)
{
struct file * file = NULL;
- unsigned long ret = -EBADF;
+ unsigned long ret = -EINVAL;
+ if (shift) {
+ if (off & ((1 << shift) - 1))
+ goto out;
+ off >>= shift;
+ }
+
+ ret = -EBADF;
if (!(flags & MAP_ANONYMOUS)) {
if (!(file = fget(fd)))
goto out;
}
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
down_write(&current->mm->mmap_sem);
- ret = do_mmap(file, addr, len, prot, flags, offset);
+ ret = do_mmap_pgoff(file, addr, len, prot, flags, off);
up_write(&current->mm->mmap_sem);
if (file)
fput(file);
-
out:
return ret;
}
+unsigned long sys_mmap2(unsigned long addr, size_t len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long pgoff)
+{
+ return do_mmap2(addr, len, prot, flags, fd, pgoff, PAGE_SHIFT-12);
+}
+
+unsigned long sys_mmap(unsigned long addr, size_t len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, off_t offset)
+{
+ return do_mmap2(addr, len, prot, flags, fd, offset, PAGE_SHIFT);
+}
+
+#ifdef CONFIG_PPC32
+/*
+ * Due to some executables calling the wrong select we sometimes
+ * get wrong args. This determines how the args are being passed
+ * (a single ptr to them all args passed) then calls
+ * sys_select() with the appropriate args. -- Cort
+ */
+int
+ppc_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, struct timeval __user *tvp)
+{
+ if ( (unsigned long)n >= 4096 )
+ {
+ unsigned long __user *buffer = (unsigned long __user *)n;
+ if (!access_ok(VERIFY_READ, buffer, 5*sizeof(unsigned long))
+ || __get_user(n, buffer)
+ || __get_user(inp, ((fd_set __user * __user *)(buffer+1)))
+ || __get_user(outp, ((fd_set __user * __user *)(buffer+2)))
+ || __get_user(exp, ((fd_set __user * __user *)(buffer+3)))
+ || __get_user(tvp, ((struct timeval __user * __user *)(buffer+4))))
+ return -EFAULT;
+ }
+ return sys_select(n, inp, outp, exp, tvp);
+}
+#endif
+
+#ifdef CONFIG_PPC64
long ppc64_personality(unsigned long personality)
{
long ret;
@@ -207,8 +239,25 @@ long ppc64_personality(unsigned long personality)
ret = PER_LINUX;
return ret;
}
+#endif
+
+#ifdef CONFIG_PPC64
+#define OVERRIDE_MACHINE (personality(current->personality) == PER_LINUX32)
+#else
+#define OVERRIDE_MACHINE 0
+#endif
+
+static inline int override_machine(char *mach)
+{
+ if (OVERRIDE_MACHINE) {
+ /* change ppc64 to ppc */
+ if (__put_user(0, mach+3) || __put_user(0, mach+4))
+ return -EFAULT;
+ }
+ return 0;
+}
-long ppc64_newuname(struct new_utsname __user * name)
+long ppc_newuname(struct new_utsname __user * name)
{
int err = 0;
@@ -216,16 +265,54 @@ long ppc64_newuname(struct new_utsname __user * name)
if (copy_to_user(name, &system_utsname, sizeof(*name)))
err = -EFAULT;
up_read(&uts_sem);
- if (!err && personality(current->personality) == PER_LINUX32) {
- /* change ppc64 to ppc */
- if (__put_user(0, name->machine + 3)
- || __put_user(0, name->machine + 4))
- err = -EFAULT;
- }
+ if (!err)
+ err = override_machine(name->machine);
return err;
}
-asmlinkage time_t sys64_time(time_t __user * tloc)
+int sys_uname(struct old_utsname __user *name)
+{
+ int err = 0;
+
+ down_read(&uts_sem);
+ if (copy_to_user(name, &system_utsname, sizeof(*name)))
+ err = -EFAULT;
+ up_read(&uts_sem);
+ if (!err)
+ err = override_machine(name->machine);
+ return err;
+}
+
+int sys_olduname(struct oldold_utsname __user *name)
+{
+ int error;
+
+ if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname)))
+ return -EFAULT;
+
+ down_read(&uts_sem);
+ error = __copy_to_user(&name->sysname, &system_utsname.sysname,
+ __OLD_UTS_LEN);
+ error |= __put_user(0, name->sysname + __OLD_UTS_LEN);
+ error |= __copy_to_user(&name->nodename, &system_utsname.nodename,
+ __OLD_UTS_LEN);
+ error |= __put_user(0, name->nodename + __OLD_UTS_LEN);
+ error |= __copy_to_user(&name->release, &system_utsname.release,
+ __OLD_UTS_LEN);
+ error |= __put_user(0, name->release + __OLD_UTS_LEN);
+ error |= __copy_to_user(&name->version, &system_utsname.version,
+ __OLD_UTS_LEN);
+ error |= __put_user(0, name->version + __OLD_UTS_LEN);
+ error |= __copy_to_user(&name->machine, &system_utsname.machine,
+ __OLD_UTS_LEN);
+ error |= override_machine(name->machine);
+ up_read(&uts_sem);
+
+ return error? -EFAULT: 0;
+}
+
+#ifdef CONFIG_PPC64
+time_t sys64_time(time_t __user * tloc)
{
time_t secs;
time_t usecs;
@@ -247,6 +334,14 @@ asmlinkage time_t sys64_time(time_t __user * tloc)
return secs;
}
+#endif
+
+long ppc_fadvise64_64(int fd, int advice, u32 offset_high, u32 offset_low,
+ u32 len_high, u32 len_low)
+{
+ return sys_fadvise64(fd, (u64)offset_high << 32 | offset_low,
+ (u64)len_high << 32 | len_low, advice);
+}
void do_show_syscall(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7, unsigned long r8,
diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S
new file mode 100644
index 000000000000..65eaea91b499
--- /dev/null
+++ b/arch/powerpc/kernel/systbl.S
@@ -0,0 +1,321 @@
+/*
+ * This file contains the table of syscall-handling functions.
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
+ * and Paul Mackerras.
+ *
+ * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com)
+ * PPC64 updates by Dave Engebretsen (engebret@us.ibm.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/config.h>
+#include <asm/ppc_asm.h>
+
+#ifdef CONFIG_PPC64
+#define SYSCALL(func) .llong .sys_##func,.sys_##func
+#define COMPAT_SYS(func) .llong .sys_##func,.compat_sys_##func
+#define PPC_SYS(func) .llong .ppc_##func,.ppc_##func
+#define OLDSYS(func) .llong .sys_ni_syscall,.sys_ni_syscall
+#define SYS32ONLY(func) .llong .sys_ni_syscall,.compat_sys_##func
+#define SYSX(f, f3264, f32) .llong .f,.f3264
+#else
+#define SYSCALL(func) .long sys_##func
+#define COMPAT_SYS(func) .long sys_##func
+#define PPC_SYS(func) .long ppc_##func
+#define OLDSYS(func) .long sys_##func
+#define SYS32ONLY(func) .long sys_##func
+#define SYSX(f, f3264, f32) .long f32
+#endif
+
+#ifdef CONFIG_PPC64
+#define sys_sigpending sys_ni_syscall
+#define sys_old_getrlimit sys_ni_syscall
+#else
+#define ppc_rtas sys_ni_syscall
+#endif
+
+_GLOBAL(sys_call_table)
+SYSCALL(restart_syscall)
+SYSCALL(exit)
+PPC_SYS(fork)
+SYSCALL(read)
+SYSCALL(write)
+COMPAT_SYS(open)
+SYSCALL(close)
+COMPAT_SYS(waitpid)
+COMPAT_SYS(creat)
+SYSCALL(link)
+SYSCALL(unlink)
+COMPAT_SYS(execve)
+SYSCALL(chdir)
+SYSX(sys64_time,compat_sys_time,sys_time)
+SYSCALL(mknod)
+SYSCALL(chmod)
+SYSCALL(lchown)
+SYSCALL(ni_syscall)
+OLDSYS(stat)
+SYSX(sys_lseek,ppc32_lseek,sys_lseek)
+SYSCALL(getpid)
+COMPAT_SYS(mount)
+SYSX(sys_ni_syscall,sys_oldumount,sys_oldumount)
+SYSCALL(setuid)
+SYSCALL(getuid)
+COMPAT_SYS(stime)
+COMPAT_SYS(ptrace)
+SYSCALL(alarm)
+OLDSYS(fstat)
+COMPAT_SYS(pause)
+COMPAT_SYS(utime)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+COMPAT_SYS(access)
+COMPAT_SYS(nice)
+SYSCALL(ni_syscall)
+SYSCALL(sync)
+COMPAT_SYS(kill)
+SYSCALL(rename)
+COMPAT_SYS(mkdir)
+SYSCALL(rmdir)
+SYSCALL(dup)
+SYSCALL(pipe)
+COMPAT_SYS(times)
+SYSCALL(ni_syscall)
+SYSCALL(brk)
+SYSCALL(setgid)
+SYSCALL(getgid)
+SYSCALL(signal)
+SYSCALL(geteuid)
+SYSCALL(getegid)
+SYSCALL(acct)
+SYSCALL(umount)
+SYSCALL(ni_syscall)
+COMPAT_SYS(ioctl)
+COMPAT_SYS(fcntl)
+SYSCALL(ni_syscall)
+COMPAT_SYS(setpgid)
+SYSCALL(ni_syscall)
+SYSX(sys_ni_syscall,sys_olduname, sys_olduname)
+COMPAT_SYS(umask)
+SYSCALL(chroot)
+SYSCALL(ustat)
+SYSCALL(dup2)
+SYSCALL(getppid)
+SYSCALL(getpgrp)
+SYSCALL(setsid)
+SYS32ONLY(sigaction)
+SYSCALL(sgetmask)
+COMPAT_SYS(ssetmask)
+SYSCALL(setreuid)
+SYSCALL(setregid)
+SYSX(sys_ni_syscall,ppc32_sigsuspend,ppc_sigsuspend)
+COMPAT_SYS(sigpending)
+COMPAT_SYS(sethostname)
+COMPAT_SYS(setrlimit)
+COMPAT_SYS(old_getrlimit)
+COMPAT_SYS(getrusage)
+COMPAT_SYS(gettimeofday)
+COMPAT_SYS(settimeofday)
+COMPAT_SYS(getgroups)
+COMPAT_SYS(setgroups)
+SYSX(sys_ni_syscall,sys_ni_syscall,ppc_select)
+SYSCALL(symlink)
+OLDSYS(lstat)
+COMPAT_SYS(readlink)
+SYSCALL(uselib)
+SYSCALL(swapon)
+SYSCALL(reboot)
+SYSX(sys_ni_syscall,old32_readdir,old_readdir)
+SYSCALL(mmap)
+SYSCALL(munmap)
+SYSCALL(truncate)
+SYSCALL(ftruncate)
+SYSCALL(fchmod)
+SYSCALL(fchown)
+COMPAT_SYS(getpriority)
+COMPAT_SYS(setpriority)
+SYSCALL(ni_syscall)
+COMPAT_SYS(statfs)
+COMPAT_SYS(fstatfs)
+SYSCALL(ni_syscall)
+COMPAT_SYS(socketcall)
+COMPAT_SYS(syslog)
+COMPAT_SYS(setitimer)
+COMPAT_SYS(getitimer)
+COMPAT_SYS(newstat)
+COMPAT_SYS(newlstat)
+COMPAT_SYS(newfstat)
+SYSX(sys_ni_syscall,sys_uname,sys_uname)
+SYSCALL(ni_syscall)
+SYSCALL(vhangup)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+COMPAT_SYS(wait4)
+SYSCALL(swapoff)
+COMPAT_SYS(sysinfo)
+COMPAT_SYS(ipc)
+SYSCALL(fsync)
+SYSX(sys_ni_syscall,ppc32_sigreturn,sys_sigreturn)
+PPC_SYS(clone)
+COMPAT_SYS(setdomainname)
+PPC_SYS(newuname)
+SYSCALL(ni_syscall)
+COMPAT_SYS(adjtimex)
+SYSCALL(mprotect)
+SYSX(sys_ni_syscall,compat_sys_sigprocmask,sys_sigprocmask)
+SYSCALL(ni_syscall)
+SYSCALL(init_module)
+SYSCALL(delete_module)
+SYSCALL(ni_syscall)
+SYSCALL(quotactl)
+COMPAT_SYS(getpgid)
+SYSCALL(fchdir)
+SYSCALL(bdflush)
+COMPAT_SYS(sysfs)
+SYSX(ppc64_personality,ppc64_personality,sys_personality)
+SYSCALL(ni_syscall)
+SYSCALL(setfsuid)
+SYSCALL(setfsgid)
+SYSCALL(llseek)
+COMPAT_SYS(getdents)
+SYSX(sys_select,ppc32_select,ppc_select)
+SYSCALL(flock)
+SYSCALL(msync)
+COMPAT_SYS(readv)
+COMPAT_SYS(writev)
+COMPAT_SYS(getsid)
+SYSCALL(fdatasync)
+COMPAT_SYS(sysctl)
+SYSCALL(mlock)
+SYSCALL(munlock)
+SYSCALL(mlockall)
+SYSCALL(munlockall)
+COMPAT_SYS(sched_setparam)
+COMPAT_SYS(sched_getparam)
+COMPAT_SYS(sched_setscheduler)
+COMPAT_SYS(sched_getscheduler)
+SYSCALL(sched_yield)
+COMPAT_SYS(sched_get_priority_max)
+COMPAT_SYS(sched_get_priority_min)
+COMPAT_SYS(sched_rr_get_interval)
+COMPAT_SYS(nanosleep)
+SYSCALL(mremap)
+SYSCALL(setresuid)
+SYSCALL(getresuid)
+SYSCALL(ni_syscall)
+SYSCALL(poll)
+COMPAT_SYS(nfsservctl)
+SYSCALL(setresgid)
+SYSCALL(getresgid)
+COMPAT_SYS(prctl)
+SYSX(ppc64_rt_sigreturn,ppc32_rt_sigreturn,sys_rt_sigreturn)
+COMPAT_SYS(rt_sigaction)
+COMPAT_SYS(rt_sigprocmask)
+COMPAT_SYS(rt_sigpending)
+COMPAT_SYS(rt_sigtimedwait)
+COMPAT_SYS(rt_sigqueueinfo)
+SYSX(ppc64_rt_sigsuspend,ppc32_rt_sigsuspend,ppc_rt_sigsuspend)
+COMPAT_SYS(pread64)
+COMPAT_SYS(pwrite64)
+SYSCALL(chown)
+SYSCALL(getcwd)
+SYSCALL(capget)
+SYSCALL(capset)
+COMPAT_SYS(sigaltstack)
+SYSX(sys_sendfile64,compat_sys_sendfile,sys_sendfile)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+PPC_SYS(vfork)
+COMPAT_SYS(getrlimit)
+COMPAT_SYS(readahead)
+SYS32ONLY(mmap2)
+SYS32ONLY(truncate64)
+SYS32ONLY(ftruncate64)
+SYSX(sys_ni_syscall,sys_stat64,sys_stat64)
+SYSX(sys_ni_syscall,sys_lstat64,sys_lstat64)
+SYSX(sys_ni_syscall,sys_fstat64,sys_fstat64)
+COMPAT_SYS(pciconfig_read)
+COMPAT_SYS(pciconfig_write)
+COMPAT_SYS(pciconfig_iobase)
+SYSCALL(ni_syscall)
+SYSCALL(getdents64)
+SYSCALL(pivot_root)
+SYSX(sys_ni_syscall,compat_sys_fcntl64,sys_fcntl64)
+SYSCALL(madvise)
+SYSCALL(mincore)
+SYSCALL(gettid)
+SYSCALL(tkill)
+SYSCALL(setxattr)
+SYSCALL(lsetxattr)
+SYSCALL(fsetxattr)
+SYSCALL(getxattr)
+SYSCALL(lgetxattr)
+SYSCALL(fgetxattr)
+SYSCALL(listxattr)
+SYSCALL(llistxattr)
+SYSCALL(flistxattr)
+SYSCALL(removexattr)
+SYSCALL(lremovexattr)
+SYSCALL(fremovexattr)
+COMPAT_SYS(futex)
+COMPAT_SYS(sched_setaffinity)
+COMPAT_SYS(sched_getaffinity)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYS32ONLY(sendfile64)
+COMPAT_SYS(io_setup)
+SYSCALL(io_destroy)
+COMPAT_SYS(io_getevents)
+COMPAT_SYS(io_submit)
+SYSCALL(io_cancel)
+SYSCALL(set_tid_address)
+SYSX(sys_fadvise64,ppc32_fadvise64,sys_fadvise64)
+SYSCALL(exit_group)
+SYSX(sys_lookup_dcookie,ppc32_lookup_dcookie,sys_lookup_dcookie)
+SYSCALL(epoll_create)
+SYSCALL(epoll_ctl)
+SYSCALL(epoll_wait)
+SYSCALL(remap_file_pages)
+SYSX(sys_timer_create,ppc32_timer_create,sys_timer_create)
+COMPAT_SYS(timer_settime)
+COMPAT_SYS(timer_gettime)
+SYSCALL(timer_getoverrun)
+SYSCALL(timer_delete)
+COMPAT_SYS(clock_settime)
+COMPAT_SYS(clock_gettime)
+COMPAT_SYS(clock_getres)
+COMPAT_SYS(clock_nanosleep)
+SYSX(ppc64_swapcontext,ppc32_swapcontext,ppc_swapcontext)
+COMPAT_SYS(tgkill)
+COMPAT_SYS(utimes)
+COMPAT_SYS(statfs64)
+COMPAT_SYS(fstatfs64)
+SYSX(sys_ni_syscall, ppc_fadvise64_64, ppc_fadvise64_64)
+PPC_SYS(rtas)
+OLDSYS(debug_setcontext)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+COMPAT_SYS(mbind)
+COMPAT_SYS(get_mempolicy)
+COMPAT_SYS(set_mempolicy)
+COMPAT_SYS(mq_open)
+SYSCALL(mq_unlink)
+COMPAT_SYS(mq_timedsend)
+COMPAT_SYS(mq_timedreceive)
+COMPAT_SYS(mq_notify)
+COMPAT_SYS(mq_getsetattr)
+COMPAT_SYS(kexec_load)
+COMPAT_SYS(add_key)
+COMPAT_SYS(request_key)
+COMPAT_SYS(keyctl)
+COMPAT_SYS(waitid)
+COMPAT_SYS(ioprio_set)
+COMPAT_SYS(ioprio_get)
+SYSCALL(inotify_init)
+SYSCALL(inotify_add_watch)
+SYSCALL(inotify_rm_watch)
diff --git a/arch/ppc64/kernel/time.c b/arch/powerpc/kernel/time.c
index b56c6a324e17..23436b6c1881 100644
--- a/arch/ppc64/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -1,5 +1,4 @@
/*
- *
* Common time routines among all ppc machines.
*
* Written by Cort Dougan (cort@cs.nmt.edu) to merge
@@ -44,33 +43,32 @@
#include <linux/interrupt.h>
#include <linux/timex.h>
#include <linux/kernel_stat.h>
-#include <linux/mc146818rtc.h>
#include <linux/time.h>
#include <linux/init.h>
#include <linux/profile.h>
#include <linux/cpu.h>
#include <linux/security.h>
+#include <linux/percpu.h>
+#include <linux/rtc.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/nvram.h>
#include <asm/cache.h>
#include <asm/machdep.h>
-#ifdef CONFIG_PPC_ISERIES
-#include <asm/iSeries/ItLpQueue.h>
-#include <asm/iSeries/HvCallXm.h>
-#endif
#include <asm/uaccess.h>
#include <asm/time.h>
-#include <asm/ppcdebug.h>
#include <asm/prom.h>
-#include <asm/sections.h>
+#include <asm/irq.h>
+#include <asm/div64.h>
+#ifdef CONFIG_PPC64
#include <asm/systemcfg.h>
#include <asm/firmware.h>
-
-u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
+#endif
+#ifdef CONFIG_PPC_ISERIES
+#include <asm/iSeries/ItLpQueue.h>
+#include <asm/iSeries/HvCallXm.h>
+#endif
/* keep track of when we need to update the rtc */
time_t last_rtc_update;
@@ -81,27 +79,37 @@ unsigned long iSeries_recal_tb = 0;
static unsigned long first_settimeofday = 1;
#endif
+/* The decrementer counts down by 128 every 128ns on a 601. */
+#define DECREMENTER_COUNT_601 (1000000000 / HZ)
+
#define XSEC_PER_SEC (1024*1024)
+#ifdef CONFIG_PPC64
+#define SCALE_XSEC(xsec, max) (((xsec) * max) / XSEC_PER_SEC)
+#else
+/* compute ((xsec << 12) * max) >> 32 */
+#define SCALE_XSEC(xsec, max) mulhwu((xsec) << 12, max)
+#endif
+
unsigned long tb_ticks_per_jiffy;
unsigned long tb_ticks_per_usec = 100; /* sane default */
EXPORT_SYMBOL(tb_ticks_per_usec);
unsigned long tb_ticks_per_sec;
-unsigned long tb_to_xs;
-unsigned tb_to_us;
+u64 tb_to_xs;
+unsigned tb_to_us;
unsigned long processor_freq;
DEFINE_SPINLOCK(rtc_lock);
EXPORT_SYMBOL_GPL(rtc_lock);
-unsigned long tb_to_ns_scale;
-unsigned long tb_to_ns_shift;
+u64 tb_to_ns_scale;
+unsigned tb_to_ns_shift;
struct gettimeofday_struct do_gtod;
extern unsigned long wall_jiffies;
-extern int smp_tb_synchronized;
extern struct timezone sys_tz;
+static long timezone_offset;
void ppc_adjtimex(void);
@@ -110,6 +118,20 @@ static unsigned adjusting_time = 0;
unsigned long ppc_proc_freq;
unsigned long ppc_tb_freq;
+#ifdef CONFIG_PPC32 /* XXX for now */
+#define boot_cpuid 0
+#endif
+
+u64 tb_last_jiffy __cacheline_aligned_in_smp;
+unsigned long tb_last_stamp;
+
+/*
+ * Note that on ppc32 this only stores the bottom 32 bits of
+ * the timebase value, but that's enough to tell when a jiffy
+ * has passed.
+ */
+DEFINE_PER_CPU(unsigned long, last_jiffy);
+
static __inline__ void timer_check_rtc(void)
{
/*
@@ -128,31 +150,31 @@ static __inline__ void timer_check_rtc(void)
* We should have an rtc call that only sets the minutes and
* seconds like on Intel to avoid problems with non UTC clocks.
*/
- if (ntp_synced() &&
- xtime.tv_sec - last_rtc_update >= 659 &&
- abs((xtime.tv_nsec/1000) - (1000000-1000000/HZ)) < 500000/HZ &&
- jiffies - wall_jiffies == 1) {
- struct rtc_time tm;
- to_tm(xtime.tv_sec+1, &tm);
- tm.tm_year -= 1900;
- tm.tm_mon -= 1;
- if (ppc_md.set_rtc_time(&tm) == 0)
- last_rtc_update = xtime.tv_sec+1;
- else
- /* Try again one minute later */
- last_rtc_update += 60;
+ if (ppc_md.set_rtc_time && ntp_synced() &&
+ xtime.tv_sec - last_rtc_update >= 659 &&
+ abs((xtime.tv_nsec/1000) - (1000000-1000000/HZ)) < 500000/HZ &&
+ jiffies - wall_jiffies == 1) {
+ struct rtc_time tm;
+ to_tm(xtime.tv_sec + 1 + timezone_offset, &tm);
+ tm.tm_year -= 1900;
+ tm.tm_mon -= 1;
+ if (ppc_md.set_rtc_time(&tm) == 0)
+ last_rtc_update = xtime.tv_sec + 1;
+ else
+ /* Try again one minute later */
+ last_rtc_update += 60;
}
}
/*
* This version of gettimeofday has microsecond resolution.
*/
-static inline void __do_gettimeofday(struct timeval *tv, unsigned long tb_val)
+static inline void __do_gettimeofday(struct timeval *tv, u64 tb_val)
{
- unsigned long sec, usec, tb_ticks;
- unsigned long xsec, tb_xsec;
- struct gettimeofday_vars * temp_varp;
- unsigned long temp_tb_to_xs, temp_stamp_xsec;
+ unsigned long sec, usec;
+ u64 tb_ticks, xsec;
+ struct gettimeofday_vars *temp_varp;
+ u64 temp_tb_to_xs, temp_stamp_xsec;
/*
* These calculations are faster (gets rid of divides)
@@ -164,11 +186,10 @@ static inline void __do_gettimeofday(struct timeval *tv, unsigned long tb_val)
tb_ticks = tb_val - temp_varp->tb_orig_stamp;
temp_tb_to_xs = temp_varp->tb_to_xs;
temp_stamp_xsec = temp_varp->stamp_xsec;
- tb_xsec = mulhdu( tb_ticks, temp_tb_to_xs );
- xsec = temp_stamp_xsec + tb_xsec;
+ xsec = temp_stamp_xsec + mulhdu(tb_ticks, temp_tb_to_xs);
sec = xsec / XSEC_PER_SEC;
- xsec -= sec * XSEC_PER_SEC;
- usec = (xsec * USEC_PER_SEC)/XSEC_PER_SEC;
+ usec = (unsigned long)xsec & (XSEC_PER_SEC - 1);
+ usec = SCALE_XSEC(usec, 1000000);
tv->tv_sec = sec;
tv->tv_usec = usec;
@@ -176,6 +197,26 @@ static inline void __do_gettimeofday(struct timeval *tv, unsigned long tb_val)
void do_gettimeofday(struct timeval *tv)
{
+ if (__USE_RTC()) {
+ /* do this the old way */
+ unsigned long flags, seq;
+ unsigned int sec, nsec, usec, lost;
+
+ do {
+ seq = read_seqbegin_irqsave(&xtime_lock, flags);
+ sec = xtime.tv_sec;
+ nsec = xtime.tv_nsec + tb_ticks_since(tb_last_stamp);
+ lost = jiffies - wall_jiffies;
+ } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
+ usec = nsec / 1000 + lost * (1000000 / HZ);
+ while (usec >= 1000000) {
+ usec -= 1000000;
+ ++sec;
+ }
+ tv->tv_sec = sec;
+ tv->tv_usec = usec;
+ return;
+ }
__do_gettimeofday(tv, get_tb());
}
@@ -185,6 +226,8 @@ EXPORT_SYMBOL(do_gettimeofday);
static inline void timer_sync_xtime(unsigned long cur_tb)
{
+#ifdef CONFIG_PPC64
+ /* why do we do this? */
struct timeval my_tv;
__do_gettimeofday(&my_tv, cur_tb);
@@ -193,47 +236,76 @@ static inline void timer_sync_xtime(unsigned long cur_tb)
xtime.tv_sec = my_tv.tv_sec;
xtime.tv_nsec = my_tv.tv_usec * 1000;
}
+#endif
}
/*
- * When the timebase - tb_orig_stamp gets too big, we do a manipulation
- * between tb_orig_stamp and stamp_xsec. The goal here is to keep the
- * difference tb - tb_orig_stamp small enough to always fit inside a
- * 32 bits number. This is a requirement of our fast 32 bits userland
- * implementation in the vdso. If we "miss" a call to this function
- * (interrupt latency, CPU locked in a spinlock, ...) and we end up
- * with a too big difference, then the vdso will fallback to calling
- * the syscall
+ * There are two copies of tb_to_xs and stamp_xsec so that no
+ * lock is needed to access and use these values in
+ * do_gettimeofday. We alternate the copies and as long as a
+ * reasonable time elapses between changes, there will never
+ * be inconsistent values. ntpd has a minimum of one minute
+ * between updates.
*/
-static __inline__ void timer_recalc_offset(unsigned long cur_tb)
+static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec,
+ u64 new_tb_to_xs)
{
- struct gettimeofday_vars * temp_varp;
unsigned temp_idx;
- unsigned long offset, new_stamp_xsec, new_tb_orig_stamp;
-
- if (((cur_tb - do_gtod.varp->tb_orig_stamp) & 0x80000000u) == 0)
- return;
+ struct gettimeofday_vars *temp_varp;
temp_idx = (do_gtod.var_idx == 0);
temp_varp = &do_gtod.vars[temp_idx];
- new_tb_orig_stamp = cur_tb;
- offset = new_tb_orig_stamp - do_gtod.varp->tb_orig_stamp;
- new_stamp_xsec = do_gtod.varp->stamp_xsec + mulhdu(offset, do_gtod.varp->tb_to_xs);
-
- temp_varp->tb_to_xs = do_gtod.varp->tb_to_xs;
- temp_varp->tb_orig_stamp = new_tb_orig_stamp;
+ temp_varp->tb_to_xs = new_tb_to_xs;
+ temp_varp->tb_orig_stamp = new_tb_stamp;
temp_varp->stamp_xsec = new_stamp_xsec;
smp_mb();
do_gtod.varp = temp_varp;
do_gtod.var_idx = temp_idx;
+#ifdef CONFIG_PPC64
+ /*
+ * tb_update_count is used to allow the userspace gettimeofday code
+ * to assure itself that it sees a consistent view of the tb_to_xs and
+ * stamp_xsec variables. It reads the tb_update_count, then reads
+ * tb_to_xs and stamp_xsec and then reads tb_update_count again. If
+ * the two values of tb_update_count match and are even then the
+ * tb_to_xs and stamp_xsec values are consistent. If not, then it
+ * loops back and reads them again until this criteria is met.
+ */
++(systemcfg->tb_update_count);
smp_wmb();
- systemcfg->tb_orig_stamp = new_tb_orig_stamp;
+ systemcfg->tb_orig_stamp = new_tb_stamp;
systemcfg->stamp_xsec = new_stamp_xsec;
+ systemcfg->tb_to_xs = new_tb_to_xs;
smp_wmb();
++(systemcfg->tb_update_count);
+#endif
+}
+
+/*
+ * When the timebase - tb_orig_stamp gets too big, we do a manipulation
+ * between tb_orig_stamp and stamp_xsec. The goal here is to keep the
+ * difference tb - tb_orig_stamp small enough to always fit inside a
+ * 32 bits number. This is a requirement of our fast 32 bits userland
+ * implementation in the vdso. If we "miss" a call to this function
+ * (interrupt latency, CPU locked in a spinlock, ...) and we end up
+ * with a too big difference, then the vdso will fallback to calling
+ * the syscall
+ */
+static __inline__ void timer_recalc_offset(u64 cur_tb)
+{
+ unsigned long offset;
+ u64 new_stamp_xsec;
+
+ if (__USE_RTC())
+ return;
+ offset = cur_tb - do_gtod.varp->tb_orig_stamp;
+ if ((offset & 0x80000000u) == 0)
+ return;
+ new_stamp_xsec = do_gtod.varp->stamp_xsec
+ + mulhdu(offset, do_gtod.varp->tb_to_xs);
+ update_gtod(cur_tb, new_stamp_xsec, do_gtod.varp->tb_to_xs);
}
#ifdef CONFIG_SMP
@@ -313,26 +385,37 @@ static void iSeries_tb_recal(void)
* call will not be needed)
*/
-unsigned long tb_last_stamp __cacheline_aligned_in_smp;
-
/*
* timer_interrupt - gets called when the decrementer overflows,
* with interrupts disabled.
*/
-int timer_interrupt(struct pt_regs * regs)
+void timer_interrupt(struct pt_regs * regs)
{
int next_dec;
- unsigned long cur_tb;
- struct paca_struct *lpaca = get_paca();
- unsigned long cpu = smp_processor_id();
+ int cpu = smp_processor_id();
+ unsigned long ticks;
+
+#ifdef CONFIG_PPC32
+ if (atomic_read(&ppc_n_lost_interrupts) != 0)
+ do_IRQ(regs);
+#endif
irq_enter();
profile_tick(CPU_PROFILING, regs);
- lpaca->lppaca.int_dword.fields.decr_int = 0;
+#ifdef CONFIG_PPC_ISERIES
+ get_paca()->lppaca.int_dword.fields.decr_int = 0;
+#endif
+
+ while ((ticks = tb_ticks_since(per_cpu(last_jiffy, cpu)))
+ >= tb_ticks_per_jiffy) {
+ /* Update last_jiffy */
+ per_cpu(last_jiffy, cpu) += tb_ticks_per_jiffy;
+ /* Handle RTCL overflow on 601 */
+ if (__USE_RTC() && per_cpu(last_jiffy, cpu) >= 1000000000)
+ per_cpu(last_jiffy, cpu) -= 1000000000;
- while (lpaca->next_jiffy_update_tb <= (cur_tb = get_tb())) {
/*
* We cannot disable the decrementer, so in the period
* between this cpu's being marked offline in cpu_online_map
@@ -342,27 +425,27 @@ int timer_interrupt(struct pt_regs * regs)
*/
if (!cpu_is_offline(cpu))
update_process_times(user_mode(regs));
+
/*
* No need to check whether cpu is offline here; boot_cpuid
* should have been fixed up by now.
*/
- if (cpu == boot_cpuid) {
- write_seqlock(&xtime_lock);
- tb_last_stamp = lpaca->next_jiffy_update_tb;
- timer_recalc_offset(lpaca->next_jiffy_update_tb);
- do_timer(regs);
- timer_sync_xtime(lpaca->next_jiffy_update_tb);
- timer_check_rtc();
- write_sequnlock(&xtime_lock);
- if ( adjusting_time && (time_adjust == 0) )
- ppc_adjtimex();
- }
- lpaca->next_jiffy_update_tb += tb_ticks_per_jiffy;
+ if (cpu != boot_cpuid)
+ continue;
+
+ write_seqlock(&xtime_lock);
+ tb_last_jiffy += tb_ticks_per_jiffy;
+ tb_last_stamp = per_cpu(last_jiffy, cpu);
+ timer_recalc_offset(tb_last_jiffy);
+ do_timer(regs);
+ timer_sync_xtime(tb_last_jiffy);
+ timer_check_rtc();
+ write_sequnlock(&xtime_lock);
+ if (adjusting_time && (time_adjust == 0))
+ ppc_adjtimex();
}
- next_dec = lpaca->next_jiffy_update_tb - cur_tb;
- if (next_dec > lpaca->default_decr)
- next_dec = lpaca->default_decr;
+ next_dec = tb_ticks_per_jiffy - ticks;
set_dec(next_dec);
#ifdef CONFIG_PPC_ISERIES
@@ -370,17 +453,47 @@ int timer_interrupt(struct pt_regs * regs)
process_hvlpevents(regs);
#endif
+#ifdef CONFIG_PPC64
/* collect purr register values often, for accurate calculations */
if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
struct cpu_usage *cu = &__get_cpu_var(cpu_usage_array);
cu->current_tb = mfspr(SPRN_PURR);
}
+#endif
irq_exit();
+}
+
+void wakeup_decrementer(void)
+{
+ int i;
- return 1;
+ set_dec(tb_ticks_per_jiffy);
+ /*
+ * We don't expect this to be called on a machine with a 601,
+ * so using get_tbl is fine.
+ */
+ tb_last_stamp = tb_last_jiffy = get_tb();
+ for_each_cpu(i)
+ per_cpu(last_jiffy, i) = tb_last_stamp;
}
+#ifdef CONFIG_SMP
+void __init smp_space_timers(unsigned int max_cpus)
+{
+ int i;
+ unsigned long offset = tb_ticks_per_jiffy / max_cpus;
+ unsigned long previous_tb = per_cpu(last_jiffy, boot_cpuid);
+
+ for_each_cpu(i) {
+ if (i != boot_cpuid) {
+ previous_tb += offset;
+ per_cpu(last_jiffy, i) = previous_tb;
+ }
+ }
+}
+#endif
+
/*
* Scheduler clock - returns current time in nanosec units.
*
@@ -390,6 +503,8 @@ int timer_interrupt(struct pt_regs * regs)
*/
unsigned long long sched_clock(void)
{
+ if (__USE_RTC())
+ return get_rtc();
return mulhdu(get_tb(), tb_to_ns_scale) << tb_to_ns_shift;
}
@@ -398,31 +513,31 @@ int do_settimeofday(struct timespec *tv)
time_t wtm_sec, new_sec = tv->tv_sec;
long wtm_nsec, new_nsec = tv->tv_nsec;
unsigned long flags;
- unsigned long delta_xsec;
long int tb_delta;
- unsigned long new_xsec;
+ u64 new_xsec, tb_delta_xs;
if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
return -EINVAL;
write_seqlock_irqsave(&xtime_lock, flags);
- /* Updating the RTC is not the job of this code. If the time is
- * stepped under NTP, the RTC will be update after STA_UNSYNC
- * is cleared. Tool like clock/hwclock either copy the RTC
+
+ /*
+ * Updating the RTC is not the job of this code. If the time is
+ * stepped under NTP, the RTC will be updated after STA_UNSYNC
+ * is cleared. Tools like clock/hwclock either copy the RTC
* to the system time, in which case there is no point in writing
* to the RTC again, or write to the RTC but then they don't call
* settimeofday to perform this operation.
*/
#ifdef CONFIG_PPC_ISERIES
- if ( first_settimeofday ) {
+ if (first_settimeofday) {
iSeries_tb_recal();
first_settimeofday = 0;
}
#endif
tb_delta = tb_ticks_since(tb_last_stamp);
tb_delta += (jiffies - wall_jiffies) * tb_ticks_per_jiffy;
-
- new_nsec -= tb_delta / tb_ticks_per_usec / 1000;
+ tb_delta_xs = mulhdu(tb_delta, do_gtod.varp->tb_to_xs);
wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - new_sec);
wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - new_nsec);
@@ -437,28 +552,18 @@ int do_settimeofday(struct timespec *tv)
ntp_clear();
- delta_xsec = mulhdu( (tb_last_stamp-do_gtod.varp->tb_orig_stamp),
- do_gtod.varp->tb_to_xs );
-
- new_xsec = (new_nsec * XSEC_PER_SEC) / NSEC_PER_SEC;
- new_xsec += new_sec * XSEC_PER_SEC;
- if ( new_xsec > delta_xsec ) {
- do_gtod.varp->stamp_xsec = new_xsec - delta_xsec;
- systemcfg->stamp_xsec = new_xsec - delta_xsec;
- }
- else {
- /* This is only for the case where the user is setting the time
- * way back to a time such that the boot time would have been
- * before 1970 ... eg. we booted ten days ago, and we are setting
- * the time to Jan 5, 1970 */
- do_gtod.varp->stamp_xsec = new_xsec;
- do_gtod.varp->tb_orig_stamp = tb_last_stamp;
- systemcfg->stamp_xsec = new_xsec;
- systemcfg->tb_orig_stamp = tb_last_stamp;
+ new_xsec = 0;
+ if (new_nsec != 0) {
+ new_xsec = (u64)new_nsec * XSEC_PER_SEC;
+ do_div(new_xsec, NSEC_PER_SEC);
}
+ new_xsec += (u64)new_sec * XSEC_PER_SEC - tb_delta_xs;
+ update_gtod(tb_last_jiffy, new_xsec, do_gtod.varp->tb_to_xs);
+#ifdef CONFIG_PPC64
systemcfg->tz_minuteswest = sys_tz.tz_minuteswest;
systemcfg->tz_dsttime = sys_tz.tz_dsttime;
+#endif
write_sequnlock_irqrestore(&xtime_lock, flags);
clock_was_set();
@@ -467,11 +572,9 @@ int do_settimeofday(struct timespec *tv)
EXPORT_SYMBOL(do_settimeofday);
-#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_MAPLE) || defined(CONFIG_PPC_BPA)
void __init generic_calibrate_decr(void)
{
struct device_node *cpu;
- struct div_result divres;
unsigned int *fp;
int node_found;
@@ -505,37 +608,74 @@ void __init generic_calibrate_decr(void)
ppc_proc_freq = *fp;
}
}
+#ifdef CONFIG_BOOKE
+ /* Set the time base to zero */
+ mtspr(SPRN_TBWL, 0);
+ mtspr(SPRN_TBWU, 0);
+
+ /* Clear any pending timer interrupts */
+ mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS);
+
+ /* Enable decrementer interrupt */
+ mtspr(SPRN_TCR, TCR_DIE);
+#endif
if (!node_found)
printk(KERN_ERR "WARNING: Estimating processor frequency "
"(not found)\n");
of_node_put(cpu);
+}
- printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n",
- ppc_tb_freq/1000000, ppc_tb_freq%1000000);
- printk(KERN_INFO "time_init: processor frequency = %lu.%.6lu MHz\n",
- ppc_proc_freq/1000000, ppc_proc_freq%1000000);
-
- tb_ticks_per_jiffy = ppc_tb_freq / HZ;
- tb_ticks_per_sec = tb_ticks_per_jiffy * HZ;
- tb_ticks_per_usec = ppc_tb_freq / 1000000;
- tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000);
- div128_by_32(1024*1024, 0, tb_ticks_per_sec, &divres);
- tb_to_xs = divres.result_low;
+unsigned long get_boot_time(void)
+{
+ struct rtc_time tm;
- setup_default_decr();
+ if (ppc_md.get_boot_time)
+ return ppc_md.get_boot_time();
+ 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);
}
-#endif
+/* This function is only called on the boot processor */
void __init time_init(void)
{
- /* This function is only called on the boot processor */
unsigned long flags;
- struct rtc_time tm;
+ unsigned long tm = 0;
struct div_result res;
- unsigned long scale, shift;
+ u64 scale;
+ unsigned shift;
+
+ if (ppc_md.time_init != NULL)
+ timezone_offset = ppc_md.time_init();
+
+ if (__USE_RTC()) {
+ /* 601 processor: dec counts down by 128 every 128ns */
+ ppc_tb_freq = 1000000000;
+ tb_last_stamp = get_rtcl();
+ tb_last_jiffy = tb_last_stamp;
+ } else {
+ /* Normal PowerPC with timebase register */
+ ppc_md.calibrate_decr();
+ printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n",
+ ppc_tb_freq / 1000000, ppc_tb_freq % 1000000);
+ printk(KERN_INFO "time_init: processor frequency = %lu.%.6lu MHz\n",
+ ppc_proc_freq / 1000000, ppc_proc_freq % 1000000);
+ tb_last_stamp = tb_last_jiffy = get_tb();
+ }
+
+ tb_ticks_per_jiffy = ppc_tb_freq / HZ;
+ tb_ticks_per_sec = tb_ticks_per_jiffy * HZ;
+ tb_ticks_per_usec = ppc_tb_freq / 1000000;
+ tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000);
+ div128_by_32(1024*1024, 0, tb_ticks_per_sec, &res);
+ tb_to_xs = res.result_low;
- ppc_md.calibrate_decr();
+#ifdef CONFIG_PPC64
+ get_paca()->default_decr = tb_ticks_per_jiffy;
+#endif
/*
* Compute scale factor for sched_clock.
@@ -559,29 +699,36 @@ void __init time_init(void)
#ifdef CONFIG_PPC_ISERIES
if (!piranha_simulator)
#endif
- ppc_md.get_boot_time(&tm);
+ tm = get_boot_time();
write_seqlock_irqsave(&xtime_lock, flags);
- xtime.tv_sec = mktime(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
- tm.tm_hour, tm.tm_min, tm.tm_sec);
- tb_last_stamp = get_tb();
+ xtime.tv_sec = tm;
+ xtime.tv_nsec = 0;
do_gtod.varp = &do_gtod.vars[0];
do_gtod.var_idx = 0;
- do_gtod.varp->tb_orig_stamp = tb_last_stamp;
- get_paca()->next_jiffy_update_tb = tb_last_stamp + tb_ticks_per_jiffy;
- do_gtod.varp->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC;
+ do_gtod.varp->tb_orig_stamp = tb_last_jiffy;
+ __get_cpu_var(last_jiffy) = tb_last_stamp;
+ do_gtod.varp->stamp_xsec = (u64) xtime.tv_sec * XSEC_PER_SEC;
do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
do_gtod.varp->tb_to_xs = tb_to_xs;
do_gtod.tb_to_us = tb_to_us;
- systemcfg->tb_orig_stamp = tb_last_stamp;
+#ifdef CONFIG_PPC64
+ systemcfg->tb_orig_stamp = tb_last_jiffy;
systemcfg->tb_update_count = 0;
systemcfg->tb_ticks_per_sec = tb_ticks_per_sec;
systemcfg->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC;
systemcfg->tb_to_xs = tb_to_xs;
+#endif
time_freq = 0;
- xtime.tv_nsec = 0;
+ /* If platform provided a timezone (pmac), we correct the time */
+ if (timezone_offset) {
+ sys_tz.tz_minuteswest = -timezone_offset / 60;
+ sys_tz.tz_dsttime = 0;
+ xtime.tv_sec -= timezone_offset;
+ }
+
last_rtc_update = xtime.tv_sec;
set_normalized_timespec(&wall_to_monotonic,
-xtime.tv_sec, -xtime.tv_nsec);
@@ -604,25 +751,28 @@ void __init time_init(void)
void ppc_adjtimex(void)
{
- unsigned long den, new_tb_ticks_per_sec, tb_ticks, old_xsec, new_tb_to_xs, new_xsec, new_stamp_xsec;
+#ifdef CONFIG_PPC64
+ unsigned long den, new_tb_ticks_per_sec, tb_ticks, old_xsec,
+ new_tb_to_xs, new_xsec, new_stamp_xsec;
unsigned long tb_ticks_per_sec_delta;
long delta_freq, ltemp;
struct div_result divres;
unsigned long flags;
- struct gettimeofday_vars * temp_varp;
- unsigned temp_idx;
long singleshot_ppm = 0;
- /* Compute parts per million frequency adjustment to accomplish the time adjustment
- implied by time_offset to be applied over the elapsed time indicated by time_constant.
- Use SHIFT_USEC to get it into the same units as time_freq. */
+ /*
+ * Compute parts per million frequency adjustment to
+ * accomplish the time adjustment implied by time_offset to be
+ * applied over the elapsed time indicated by time_constant.
+ * Use SHIFT_USEC to get it into the same units as
+ * time_freq.
+ */
if ( time_offset < 0 ) {
ltemp = -time_offset;
ltemp <<= SHIFT_USEC - SHIFT_UPDATE;
ltemp >>= SHIFT_KG + time_constant;
ltemp = -ltemp;
- }
- else {
+ } else {
ltemp = time_offset;
ltemp <<= SHIFT_USEC - SHIFT_UPDATE;
ltemp >>= SHIFT_KG + time_constant;
@@ -639,7 +789,10 @@ void ppc_adjtimex(void)
adjusting_time = 1;
- /* Compute parts per million frequency adjustment to match time_adjust */
+ /*
+ * Compute parts per million frequency adjustment
+ * to match time_adjust
+ */
singleshot_ppm = tickadj * HZ;
/*
* The adjustment should be tickadj*HZ to match the code in
@@ -647,7 +800,7 @@ void ppc_adjtimex(void)
* large. 3/4 of tickadj*HZ seems about right
*/
singleshot_ppm -= singleshot_ppm / 4;
- /* Use SHIFT_USEC to get it into the same units as time_freq */
+ /* Use SHIFT_USEC to get it into the same units as time_freq */
singleshot_ppm <<= SHIFT_USEC;
if ( time_adjust < 0 )
singleshot_ppm = -singleshot_ppm;
@@ -663,7 +816,10 @@ void ppc_adjtimex(void)
/* Add up all of the frequency adjustments */
delta_freq = time_freq + ltemp + singleshot_ppm;
- /* Compute a new value for tb_ticks_per_sec based on the frequency adjustment */
+ /*
+ * Compute a new value for tb_ticks_per_sec based on
+ * the frequency adjustment
+ */
den = 1000000 * (1 << (SHIFT_USEC - 8));
if ( delta_freq < 0 ) {
tb_ticks_per_sec_delta = ( tb_ticks_per_sec * ( (-delta_freq) >> (SHIFT_USEC - 8))) / den;
@@ -678,61 +834,37 @@ void ppc_adjtimex(void)
printk("ppc_adjtimex: ltemp = %ld, time_freq = %ld, singleshot_ppm = %ld\n", ltemp, time_freq, singleshot_ppm);
printk("ppc_adjtimex: tb_ticks_per_sec - base = %ld new = %ld\n", tb_ticks_per_sec, new_tb_ticks_per_sec);
#endif
-
- /* Compute a new value of tb_to_xs (used to convert tb to microseconds and a new value of
- stamp_xsec which is the time (in 1/2^20 second units) corresponding to tb_orig_stamp. This
- new value of stamp_xsec compensates for the change in frequency (implied by the new tb_to_xs)
- which guarantees that the current time remains the same */
+
+ /*
+ * Compute a new value of tb_to_xs (used to convert tb to
+ * microseconds) and a new value of stamp_xsec which is the
+ * time (in 1/2^20 second units) corresponding to
+ * tb_orig_stamp. This new value of stamp_xsec compensates
+ * for the change in frequency (implied by the new tb_to_xs)
+ * which guarantees that the current time remains the same.
+ */
write_seqlock_irqsave( &xtime_lock, flags );
tb_ticks = get_tb() - do_gtod.varp->tb_orig_stamp;
- div128_by_32( 1024*1024, 0, new_tb_ticks_per_sec, &divres );
+ div128_by_32(1024*1024, 0, new_tb_ticks_per_sec, &divres);
new_tb_to_xs = divres.result_low;
- new_xsec = mulhdu( tb_ticks, new_tb_to_xs );
+ new_xsec = mulhdu(tb_ticks, new_tb_to_xs);
- old_xsec = mulhdu( tb_ticks, do_gtod.varp->tb_to_xs );
+ old_xsec = mulhdu(tb_ticks, do_gtod.varp->tb_to_xs);
new_stamp_xsec = do_gtod.varp->stamp_xsec + old_xsec - new_xsec;
- /* There are two copies of tb_to_xs and stamp_xsec so that no lock is needed to access and use these
- values in do_gettimeofday. We alternate the copies and as long as a reasonable time elapses between
- changes, there will never be inconsistent values. ntpd has a minimum of one minute between updates */
-
- temp_idx = (do_gtod.var_idx == 0);
- temp_varp = &do_gtod.vars[temp_idx];
-
- temp_varp->tb_to_xs = new_tb_to_xs;
- temp_varp->stamp_xsec = new_stamp_xsec;
- temp_varp->tb_orig_stamp = do_gtod.varp->tb_orig_stamp;
- smp_mb();
- do_gtod.varp = temp_varp;
- do_gtod.var_idx = temp_idx;
-
- /*
- * tb_update_count is used to allow the problem state gettimeofday code
- * to assure itself that it sees a consistent view of the tb_to_xs and
- * stamp_xsec variables. It reads the tb_update_count, then reads
- * tb_to_xs and stamp_xsec and then reads tb_update_count again. If
- * the two values of tb_update_count match and are even then the
- * tb_to_xs and stamp_xsec values are consistent. If not, then it
- * loops back and reads them again until this criteria is met.
- */
- ++(systemcfg->tb_update_count);
- smp_wmb();
- systemcfg->tb_to_xs = new_tb_to_xs;
- systemcfg->stamp_xsec = new_stamp_xsec;
- smp_wmb();
- ++(systemcfg->tb_update_count);
+ update_gtod(do_gtod.varp->tb_orig_stamp, new_stamp_xsec, new_tb_to_xs);
write_sequnlock_irqrestore( &xtime_lock, flags );
-
+#endif /* CONFIG_PPC64 */
}
-#define TICK_SIZE tick
#define FEBRUARY 2
#define STARTOFTIME 1970
#define SECDAY 86400L
#define SECYR (SECDAY * 365)
-#define leapyear(year) ((year) % 4 == 0)
+#define leapyear(year) ((year) % 4 == 0 && \
+ ((year) % 100 != 0 || (year) % 400 == 0))
#define days_in_year(a) (leapyear(a) ? 366 : 365)
#define days_in_month(a) (month_days[(a) - 1])
@@ -750,37 +882,25 @@ void GregorianDay(struct rtc_time * tm)
int day;
int MonthOffset[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
- lastYear=tm->tm_year-1;
+ lastYear = tm->tm_year - 1;
/*
* Number of leap corrections to apply up to end of last year
*/
- leapsToDate = lastYear/4 - lastYear/100 + lastYear/400;
+ leapsToDate = lastYear / 4 - lastYear / 100 + lastYear / 400;
/*
* This year is a leap year if it is divisible by 4 except when it is
* divisible by 100 unless it is divisible by 400
*
- * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 will be
+ * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 was
*/
- if((tm->tm_year%4==0) &&
- ((tm->tm_year%100!=0) || (tm->tm_year%400==0)) &&
- (tm->tm_mon>2))
- {
- /*
- * We are past Feb. 29 in a leap year
- */
- day=1;
- }
- else
- {
- day=0;
- }
+ day = tm->tm_mon > 2 && leapyear(tm->tm_year);
day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] +
tm->tm_mday;
- tm->tm_wday=day%7;
+ tm->tm_wday = day % 7;
}
void to_tm(int tim, struct rtc_time * tm)
@@ -826,14 +946,16 @@ void to_tm(int tim, struct rtc_time * tm)
* oscillators and the precision with which the timebase frequency
* is measured but does not harm.
*/
-unsigned mulhwu_scale_factor(unsigned inscale, unsigned outscale) {
+unsigned mulhwu_scale_factor(unsigned inscale, unsigned outscale)
+{
unsigned mlt=0, tmp, err;
/* No concern for performance, it's done once: use a stupid
* but safe and compact method to find the multiplier.
*/
for (tmp = 1U<<31; tmp != 0; tmp >>= 1) {
- if (mulhwu(inscale, mlt|tmp) < outscale) mlt|=tmp;
+ if (mulhwu(inscale, mlt|tmp) < outscale)
+ mlt |= tmp;
}
/* We might still be off by 1 for the best approximation.
@@ -843,39 +965,41 @@ unsigned mulhwu_scale_factor(unsigned inscale, unsigned outscale) {
* some might have been forgotten in the test however.
*/
- err = inscale*(mlt+1);
- if (err <= inscale/2) mlt++;
+ err = inscale * (mlt+1);
+ if (err <= inscale/2)
+ mlt++;
return mlt;
- }
+}
/*
* Divide a 128-bit dividend by a 32-bit divisor, leaving a 128 bit
* result.
*/
-
-void div128_by_32( unsigned long dividend_high, unsigned long dividend_low,
- unsigned divisor, struct div_result *dr )
+void div128_by_32(u64 dividend_high, u64 dividend_low,
+ unsigned divisor, struct div_result *dr)
{
- unsigned long a,b,c,d, w,x,y,z, ra,rb,rc;
+ unsigned long a, b, c, d;
+ unsigned long w, x, y, z;
+ u64 ra, rb, rc;
a = dividend_high >> 32;
b = dividend_high & 0xffffffff;
c = dividend_low >> 32;
d = dividend_low & 0xffffffff;
- w = a/divisor;
- ra = (a - (w * divisor)) << 32;
+ w = a / divisor;
+ ra = ((u64)(a - (w * divisor)) << 32) + b;
- x = (ra + b)/divisor;
- rb = ((ra + b) - (x * divisor)) << 32;
+ rb = ((u64) do_div(ra, divisor) << 32) + c;
+ x = ra;
- y = (rb + c)/divisor;
- rc = ((rb + c) - (y * divisor)) << 32;
+ rc = ((u64) do_div(rb, divisor) << 32) + d;
+ y = rb;
- z = (rc + d)/divisor;
+ do_div(rc, divisor);
+ z = rc;
- dr->result_high = (w << 32) + x;
- dr->result_low = (y << 32) + z;
+ dr->result_high = ((u64)w << 32) + x;
+ dr->result_low = ((u64)y << 32) + z;
}
-
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
new file mode 100644
index 000000000000..5d638ecddbd0
--- /dev/null
+++ b/arch/powerpc/kernel/traps.c
@@ -0,0 +1,1101 @@
+/*
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.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.
+ *
+ * Modified by Cort Dougan (cort@cs.nmt.edu)
+ * and Paul Mackerras (paulus@samba.org)
+ */
+
+/*
+ * This file handles the architecture-dependent parts of hardware exceptions
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/prctl.h>
+#include <linux/delay.h>
+#include <linux/kprobes.h>
+
+#include <asm/kdebug.h>
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/rtas.h>
+#include <asm/xmon.h>
+#include <asm/pmc.h>
+#ifdef CONFIG_PPC32
+#include <asm/reg.h>
+#endif
+#ifdef CONFIG_PMAC_BACKLIGHT
+#include <asm/backlight.h>
+#endif
+#ifdef CONFIG_PPC64
+#include <asm/firmware.h>
+#include <asm/processor.h>
+#include <asm/systemcfg.h>
+#endif
+
+#ifdef CONFIG_PPC64 /* XXX */
+#define _IO_BASE pci_io_base
+#endif
+
+#ifdef CONFIG_DEBUGGER
+int (*__debugger)(struct pt_regs *regs);
+int (*__debugger_ipi)(struct pt_regs *regs);
+int (*__debugger_bpt)(struct pt_regs *regs);
+int (*__debugger_sstep)(struct pt_regs *regs);
+int (*__debugger_iabr_match)(struct pt_regs *regs);
+int (*__debugger_dabr_match)(struct pt_regs *regs);
+int (*__debugger_fault_handler)(struct pt_regs *regs);
+
+EXPORT_SYMBOL(__debugger);
+EXPORT_SYMBOL(__debugger_ipi);
+EXPORT_SYMBOL(__debugger_bpt);
+EXPORT_SYMBOL(__debugger_sstep);
+EXPORT_SYMBOL(__debugger_iabr_match);
+EXPORT_SYMBOL(__debugger_dabr_match);
+EXPORT_SYMBOL(__debugger_fault_handler);
+#endif
+
+struct notifier_block *powerpc_die_chain;
+static DEFINE_SPINLOCK(die_notifier_lock);
+
+int register_die_notifier(struct notifier_block *nb)
+{
+ int err = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&die_notifier_lock, flags);
+ err = notifier_chain_register(&powerpc_die_chain, nb);
+ spin_unlock_irqrestore(&die_notifier_lock, flags);
+ return err;
+}
+
+/*
+ * Trap & Exception support
+ */
+
+static DEFINE_SPINLOCK(die_lock);
+
+int die(const char *str, struct pt_regs *regs, long err)
+{
+ static int die_counter;
+ int nl = 0;
+
+ if (debugger(regs))
+ return 1;
+
+ console_verbose();
+ spin_lock_irq(&die_lock);
+ bust_spinlocks(1);
+#ifdef CONFIG_PMAC_BACKLIGHT
+ if (_machine == _MACH_Pmac) {
+ set_backlight_enable(1);
+ set_backlight_level(BACKLIGHT_MAX);
+ }
+#endif
+ printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter);
+#ifdef CONFIG_PREEMPT
+ printk("PREEMPT ");
+ nl = 1;
+#endif
+#ifdef CONFIG_SMP
+ printk("SMP NR_CPUS=%d ", NR_CPUS);
+ nl = 1;
+#endif
+#ifdef CONFIG_DEBUG_PAGEALLOC
+ printk("DEBUG_PAGEALLOC ");
+ nl = 1;
+#endif
+#ifdef CONFIG_NUMA
+ printk("NUMA ");
+ nl = 1;
+#endif
+#ifdef CONFIG_PPC64
+ switch (systemcfg->platform) {
+ case PLATFORM_PSERIES:
+ printk("PSERIES ");
+ nl = 1;
+ break;
+ case PLATFORM_PSERIES_LPAR:
+ printk("PSERIES LPAR ");
+ nl = 1;
+ break;
+ case PLATFORM_ISERIES_LPAR:
+ printk("ISERIES LPAR ");
+ nl = 1;
+ break;
+ case PLATFORM_POWERMAC:
+ printk("POWERMAC ");
+ nl = 1;
+ break;
+ case PLATFORM_BPA:
+ printk("BPA ");
+ nl = 1;
+ break;
+ }
+#endif
+ if (nl)
+ printk("\n");
+ print_modules();
+ show_regs(regs);
+ bust_spinlocks(0);
+ spin_unlock_irq(&die_lock);
+
+ if (in_interrupt())
+ panic("Fatal exception in interrupt");
+
+ if (panic_on_oops) {
+#ifdef CONFIG_PPC64
+ printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
+ ssleep(5);
+#endif
+ panic("Fatal exception");
+ }
+ do_exit(err);
+
+ return 0;
+}
+
+void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
+{
+ siginfo_t info;
+
+ if (!user_mode(regs)) {
+ if (die("Exception in kernel mode", regs, signr))
+ return;
+ }
+
+ memset(&info, 0, sizeof(info));
+ info.si_signo = signr;
+ info.si_code = code;
+ info.si_addr = (void __user *) addr;
+ force_sig_info(signr, &info, current);
+
+ /*
+ * Init gets no signals that it doesn't have a handler for.
+ * That's all very well, but if it has caused a synchronous
+ * exception and we ignore the resulting signal, it will just
+ * generate the same exception over and over again and we get
+ * nowhere. Better to kill it and let the kernel panic.
+ */
+ if (current->pid == 1) {
+ __sighandler_t handler;
+
+ spin_lock_irq(&current->sighand->siglock);
+ handler = current->sighand->action[signr-1].sa.sa_handler;
+ spin_unlock_irq(&current->sighand->siglock);
+ if (handler == SIG_DFL) {
+ /* init has generated a synchronous exception
+ and it doesn't have a handler for the signal */
+ printk(KERN_CRIT "init has generated signal %d "
+ "but has no handler for it\n", signr);
+ do_exit(signr);
+ }
+ }
+}
+
+#ifdef CONFIG_PPC64
+void system_reset_exception(struct pt_regs *regs)
+{
+ /* See if any machine dependent calls */
+ if (ppc_md.system_reset_exception)
+ ppc_md.system_reset_exception(regs);
+
+ die("System Reset", regs, SIGABRT);
+
+ /* Must die if the interrupt is not recoverable */
+ if (!(regs->msr & MSR_RI))
+ panic("Unrecoverable System Reset");
+
+ /* What should we do here? We could issue a shutdown or hard reset. */
+}
+#endif
+
+/*
+ * I/O accesses can cause machine checks on powermacs.
+ * Check if the NIP corresponds to the address of a sync
+ * instruction for which there is an entry in the exception
+ * table.
+ * Note that the 601 only takes a machine check on TEA
+ * (transfer error ack) signal assertion, and does not
+ * set any of the top 16 bits of SRR1.
+ * -- paulus.
+ */
+static inline int check_io_access(struct pt_regs *regs)
+{
+#ifdef CONFIG_PPC_PMAC
+ unsigned long msr = regs->msr;
+ const struct exception_table_entry *entry;
+ unsigned int *nip = (unsigned int *)regs->nip;
+
+ if (((msr & 0xffff0000) == 0 || (msr & (0x80000 | 0x40000)))
+ && (entry = search_exception_tables(regs->nip)) != NULL) {
+ /*
+ * Check that it's a sync instruction, or somewhere
+ * in the twi; isync; nop sequence that inb/inw/inl uses.
+ * As the address is in the exception table
+ * we should be able to read the instr there.
+ * For the debug message, we look at the preceding
+ * load or store.
+ */
+ if (*nip == 0x60000000) /* nop */
+ nip -= 2;
+ else if (*nip == 0x4c00012c) /* isync */
+ --nip;
+ if (*nip == 0x7c0004ac || (*nip >> 26) == 3) {
+ /* sync or twi */
+ unsigned int rb;
+
+ --nip;
+ rb = (*nip >> 11) & 0x1f;
+ printk(KERN_DEBUG "%s bad port %lx at %p\n",
+ (*nip & 0x100)? "OUT to": "IN from",
+ regs->gpr[rb] - _IO_BASE, nip);
+ regs->msr |= MSR_RI;
+ regs->nip = entry->fixup;
+ return 1;
+ }
+ }
+#endif /* CONFIG_PPC_PMAC */
+ return 0;
+}
+
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+/* On 4xx, the reason for the machine check or program exception
+ is in the ESR. */
+#define get_reason(regs) ((regs)->dsisr)
+#ifndef CONFIG_FSL_BOOKE
+#define get_mc_reason(regs) ((regs)->dsisr)
+#else
+#define get_mc_reason(regs) (mfspr(SPRN_MCSR))
+#endif
+#define REASON_FP ESR_FP
+#define REASON_ILLEGAL (ESR_PIL | ESR_PUO)
+#define REASON_PRIVILEGED ESR_PPR
+#define REASON_TRAP ESR_PTR
+
+/* single-step stuff */
+#define single_stepping(regs) (current->thread.dbcr0 & DBCR0_IC)
+#define clear_single_step(regs) (current->thread.dbcr0 &= ~DBCR0_IC)
+
+#else
+/* On non-4xx, the reason for the machine check or program
+ exception is in the MSR. */
+#define get_reason(regs) ((regs)->msr)
+#define get_mc_reason(regs) ((regs)->msr)
+#define REASON_FP 0x100000
+#define REASON_ILLEGAL 0x80000
+#define REASON_PRIVILEGED 0x40000
+#define REASON_TRAP 0x20000
+
+#define single_stepping(regs) ((regs)->msr & MSR_SE)
+#define clear_single_step(regs) ((regs)->msr &= ~MSR_SE)
+#endif
+
+/*
+ * This is "fall-back" implementation for configurations
+ * which don't provide platform-specific machine check info
+ */
+void __attribute__ ((weak))
+platform_machine_check(struct pt_regs *regs)
+{
+}
+
+void machine_check_exception(struct pt_regs *regs)
+{
+#ifdef CONFIG_PPC64
+ int recover = 0;
+
+ /* See if any machine dependent calls */
+ if (ppc_md.machine_check_exception)
+ recover = ppc_md.machine_check_exception(regs);
+
+ if (recover)
+ return;
+#else
+ unsigned long reason = get_mc_reason(regs);
+
+ if (user_mode(regs)) {
+ regs->msr |= MSR_RI;
+ _exception(SIGBUS, regs, BUS_ADRERR, regs->nip);
+ return;
+ }
+
+#if defined(CONFIG_8xx) && defined(CONFIG_PCI)
+ /* the qspan pci read routines can cause machine checks -- Cort */
+ bad_page_fault(regs, regs->dar, SIGBUS);
+ return;
+#endif
+
+ if (debugger_fault_handler(regs)) {
+ regs->msr |= MSR_RI;
+ return;
+ }
+
+ if (check_io_access(regs))
+ return;
+
+#if defined(CONFIG_4xx) && !defined(CONFIG_440A)
+ if (reason & ESR_IMCP) {
+ printk("Instruction");
+ mtspr(SPRN_ESR, reason & ~ESR_IMCP);
+ } else
+ printk("Data");
+ printk(" machine check in kernel mode.\n");
+#elif defined(CONFIG_440A)
+ printk("Machine check in kernel mode.\n");
+ if (reason & ESR_IMCP){
+ printk("Instruction Synchronous Machine Check exception\n");
+ mtspr(SPRN_ESR, reason & ~ESR_IMCP);
+ }
+ else {
+ u32 mcsr = mfspr(SPRN_MCSR);
+ if (mcsr & MCSR_IB)
+ printk("Instruction Read PLB Error\n");
+ if (mcsr & MCSR_DRB)
+ printk("Data Read PLB Error\n");
+ if (mcsr & MCSR_DWB)
+ printk("Data Write PLB Error\n");
+ if (mcsr & MCSR_TLBP)
+ printk("TLB Parity Error\n");
+ if (mcsr & MCSR_ICP){
+ flush_instruction_cache();
+ printk("I-Cache Parity Error\n");
+ }
+ if (mcsr & MCSR_DCSP)
+ printk("D-Cache Search Parity Error\n");
+ if (mcsr & MCSR_DCFP)
+ printk("D-Cache Flush Parity Error\n");
+ if (mcsr & MCSR_IMPE)
+ printk("Machine Check exception is imprecise\n");
+
+ /* Clear MCSR */
+ mtspr(SPRN_MCSR, mcsr);
+ }
+#elif defined (CONFIG_E500)
+ printk("Machine check in kernel mode.\n");
+ printk("Caused by (from MCSR=%lx): ", reason);
+
+ if (reason & MCSR_MCP)
+ printk("Machine Check Signal\n");
+ if (reason & MCSR_ICPERR)
+ printk("Instruction Cache Parity Error\n");
+ if (reason & MCSR_DCP_PERR)
+ printk("Data Cache Push Parity Error\n");
+ if (reason & MCSR_DCPERR)
+ printk("Data Cache Parity Error\n");
+ if (reason & MCSR_GL_CI)
+ printk("Guarded Load or Cache-Inhibited stwcx.\n");
+ if (reason & MCSR_BUS_IAERR)
+ printk("Bus - Instruction Address Error\n");
+ if (reason & MCSR_BUS_RAERR)
+ printk("Bus - Read Address Error\n");
+ if (reason & MCSR_BUS_WAERR)
+ printk("Bus - Write Address Error\n");
+ if (reason & MCSR_BUS_IBERR)
+ printk("Bus - Instruction Data Error\n");
+ if (reason & MCSR_BUS_RBERR)
+ printk("Bus - Read Data Bus Error\n");
+ if (reason & MCSR_BUS_WBERR)
+ printk("Bus - Read Data Bus Error\n");
+ if (reason & MCSR_BUS_IPERR)
+ printk("Bus - Instruction Parity Error\n");
+ if (reason & MCSR_BUS_RPERR)
+ printk("Bus - Read Parity Error\n");
+#elif defined (CONFIG_E200)
+ printk("Machine check in kernel mode.\n");
+ printk("Caused by (from MCSR=%lx): ", reason);
+
+ if (reason & MCSR_MCP)
+ printk("Machine Check Signal\n");
+ if (reason & MCSR_CP_PERR)
+ printk("Cache Push Parity Error\n");
+ if (reason & MCSR_CPERR)
+ printk("Cache Parity Error\n");
+ if (reason & MCSR_EXCP_ERR)
+ printk("ISI, ITLB, or Bus Error on first instruction fetch for an exception handler\n");
+ if (reason & MCSR_BUS_IRERR)
+ printk("Bus - Read Bus Error on instruction fetch\n");
+ if (reason & MCSR_BUS_DRERR)
+ printk("Bus - Read Bus Error on data load\n");
+ if (reason & MCSR_BUS_WRERR)
+ printk("Bus - Write Bus Error on buffered store or cache line push\n");
+#else /* !CONFIG_4xx && !CONFIG_E500 && !CONFIG_E200 */
+ printk("Machine check in kernel mode.\n");
+ printk("Caused by (from SRR1=%lx): ", reason);
+ switch (reason & 0x601F0000) {
+ case 0x80000:
+ printk("Machine check signal\n");
+ break;
+ case 0: /* for 601 */
+ case 0x40000:
+ case 0x140000: /* 7450 MSS error and TEA */
+ printk("Transfer error ack signal\n");
+ break;
+ case 0x20000:
+ printk("Data parity error signal\n");
+ break;
+ case 0x10000:
+ printk("Address parity error signal\n");
+ break;
+ case 0x20000000:
+ printk("L1 Data Cache error\n");
+ break;
+ case 0x40000000:
+ printk("L1 Instruction Cache error\n");
+ break;
+ case 0x00100000:
+ printk("L2 data cache parity error\n");
+ break;
+ default:
+ printk("Unknown values in msr\n");
+ }
+#endif /* CONFIG_4xx */
+
+ /*
+ * Optional platform-provided routine to print out
+ * additional info, e.g. bus error registers.
+ */
+ platform_machine_check(regs);
+#endif /* CONFIG_PPC64 */
+
+ if (debugger_fault_handler(regs))
+ return;
+ die("Machine check", regs, SIGBUS);
+
+ /* Must die if the interrupt is not recoverable */
+ if (!(regs->msr & MSR_RI))
+ panic("Unrecoverable Machine check");
+}
+
+void SMIException(struct pt_regs *regs)
+{
+ die("System Management Interrupt", regs, SIGABRT);
+}
+
+void unknown_exception(struct pt_regs *regs)
+{
+ printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
+ regs->nip, regs->msr, regs->trap);
+
+ _exception(SIGTRAP, regs, 0, 0);
+}
+
+void instruction_breakpoint_exception(struct pt_regs *regs)
+{
+ if (notify_die(DIE_IABR_MATCH, "iabr_match", regs, 5,
+ 5, SIGTRAP) == NOTIFY_STOP)
+ return;
+ if (debugger_iabr_match(regs))
+ return;
+ _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
+}
+
+void RunModeException(struct pt_regs *regs)
+{
+ _exception(SIGTRAP, regs, 0, 0);
+}
+
+void __kprobes single_step_exception(struct pt_regs *regs)
+{
+ regs->msr &= ~(MSR_SE | MSR_BE); /* Turn off 'trace' bits */
+
+ if (notify_die(DIE_SSTEP, "single_step", regs, 5,
+ 5, SIGTRAP) == NOTIFY_STOP)
+ return;
+ if (debugger_sstep(regs))
+ return;
+
+ _exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
+}
+
+/*
+ * After we have successfully emulated an instruction, we have to
+ * check if the instruction was being single-stepped, and if so,
+ * pretend we got a single-step exception. This was pointed out
+ * by Kumar Gala. -- paulus
+ */
+static void emulate_single_step(struct pt_regs *regs)
+{
+ if (single_stepping(regs)) {
+ clear_single_step(regs);
+ _exception(SIGTRAP, regs, TRAP_TRACE, 0);
+ }
+}
+
+static void parse_fpe(struct pt_regs *regs)
+{
+ int code = 0;
+ unsigned long fpscr;
+
+ flush_fp_to_thread(current);
+
+ fpscr = current->thread.fpscr.val;
+
+ /* Invalid operation */
+ if ((fpscr & FPSCR_VE) && (fpscr & FPSCR_VX))
+ code = FPE_FLTINV;
+
+ /* Overflow */
+ else if ((fpscr & FPSCR_OE) && (fpscr & FPSCR_OX))
+ code = FPE_FLTOVF;
+
+ /* Underflow */
+ else if ((fpscr & FPSCR_UE) && (fpscr & FPSCR_UX))
+ code = FPE_FLTUND;
+
+ /* Divide by zero */
+ else if ((fpscr & FPSCR_ZE) && (fpscr & FPSCR_ZX))
+ code = FPE_FLTDIV;
+
+ /* Inexact result */
+ else if ((fpscr & FPSCR_XE) && (fpscr & FPSCR_XX))
+ code = FPE_FLTRES;
+
+ _exception(SIGFPE, regs, code, regs->nip);
+}
+
+/*
+ * Illegal instruction emulation support. Originally written to
+ * provide the PVR to user applications using the mfspr rd, PVR.
+ * Return non-zero if we can't emulate, or -EFAULT if the associated
+ * memory access caused an access fault. Return zero on success.
+ *
+ * There are a couple of ways to do this, either "decode" the instruction
+ * or directly match lots of bits. In this case, matching lots of
+ * bits is faster and easier.
+ *
+ */
+#define INST_MFSPR_PVR 0x7c1f42a6
+#define INST_MFSPR_PVR_MASK 0xfc1fffff
+
+#define INST_DCBA 0x7c0005ec
+#define INST_DCBA_MASK 0x7c0007fe
+
+#define INST_MCRXR 0x7c000400
+#define INST_MCRXR_MASK 0x7c0007fe
+
+#define INST_STRING 0x7c00042a
+#define INST_STRING_MASK 0x7c0007fe
+#define INST_STRING_GEN_MASK 0x7c00067e
+#define INST_LSWI 0x7c0004aa
+#define INST_LSWX 0x7c00042a
+#define INST_STSWI 0x7c0005aa
+#define INST_STSWX 0x7c00052a
+
+static int emulate_string_inst(struct pt_regs *regs, u32 instword)
+{
+ u8 rT = (instword >> 21) & 0x1f;
+ u8 rA = (instword >> 16) & 0x1f;
+ u8 NB_RB = (instword >> 11) & 0x1f;
+ u32 num_bytes;
+ unsigned long EA;
+ int pos = 0;
+
+ /* Early out if we are an invalid form of lswx */
+ if ((instword & INST_STRING_MASK) == INST_LSWX)
+ if ((rT == rA) || (rT == NB_RB))
+ return -EINVAL;
+
+ EA = (rA == 0) ? 0 : regs->gpr[rA];
+
+ switch (instword & INST_STRING_MASK) {
+ case INST_LSWX:
+ case INST_STSWX:
+ EA += NB_RB;
+ num_bytes = regs->xer & 0x7f;
+ break;
+ case INST_LSWI:
+ case INST_STSWI:
+ num_bytes = (NB_RB == 0) ? 32 : NB_RB;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ while (num_bytes != 0)
+ {
+ u8 val;
+ u32 shift = 8 * (3 - (pos & 0x3));
+
+ switch ((instword & INST_STRING_MASK)) {
+ case INST_LSWX:
+ case INST_LSWI:
+ if (get_user(val, (u8 __user *)EA))
+ return -EFAULT;
+ /* first time updating this reg,
+ * zero it out */
+ if (pos == 0)
+ regs->gpr[rT] = 0;
+ regs->gpr[rT] |= val << shift;
+ break;
+ case INST_STSWI:
+ case INST_STSWX:
+ val = regs->gpr[rT] >> shift;
+ if (put_user(val, (u8 __user *)EA))
+ return -EFAULT;
+ break;
+ }
+ /* move EA to next address */
+ EA += 1;
+ num_bytes--;
+
+ /* manage our position within the register */
+ if (++pos == 4) {
+ pos = 0;
+ if (++rT == 32)
+ rT = 0;
+ }
+ }
+
+ return 0;
+}
+
+static int emulate_instruction(struct pt_regs *regs)
+{
+ u32 instword;
+ u32 rd;
+
+ if (!user_mode(regs))
+ return -EINVAL;
+ CHECK_FULL_REGS(regs);
+
+ if (get_user(instword, (u32 __user *)(regs->nip)))
+ return -EFAULT;
+
+ /* Emulate the mfspr rD, PVR. */
+ if ((instword & INST_MFSPR_PVR_MASK) == INST_MFSPR_PVR) {
+ rd = (instword >> 21) & 0x1f;
+ regs->gpr[rd] = mfspr(SPRN_PVR);
+ return 0;
+ }
+
+ /* Emulating the dcba insn is just a no-op. */
+ if ((instword & INST_DCBA_MASK) == INST_DCBA)
+ return 0;
+
+ /* Emulate the mcrxr insn. */
+ if ((instword & INST_MCRXR_MASK) == INST_MCRXR) {
+ int shift = (instword >> 21) & 0x1c;
+ unsigned long msk = 0xf0000000UL >> shift;
+
+ regs->ccr = (regs->ccr & ~msk) | ((regs->xer >> shift) & msk);
+ regs->xer &= ~0xf0000000UL;
+ return 0;
+ }
+
+ /* Emulate load/store string insn. */
+ if ((instword & INST_STRING_GEN_MASK) == INST_STRING)
+ return emulate_string_inst(regs, instword);
+
+ return -EINVAL;
+}
+
+/*
+ * Look through the list of trap instructions that are used for BUG(),
+ * BUG_ON() and WARN_ON() and see if we hit one. At this point we know
+ * that the exception was caused by a trap instruction of some kind.
+ * Returns 1 if we should continue (i.e. it was a WARN_ON) or 0
+ * otherwise.
+ */
+extern struct bug_entry __start___bug_table[], __stop___bug_table[];
+
+#ifndef CONFIG_MODULES
+#define module_find_bug(x) NULL
+#endif
+
+struct bug_entry *find_bug(unsigned long bugaddr)
+{
+ struct bug_entry *bug;
+
+ for (bug = __start___bug_table; bug < __stop___bug_table; ++bug)
+ if (bugaddr == bug->bug_addr)
+ return bug;
+ return module_find_bug(bugaddr);
+}
+
+static int check_bug_trap(struct pt_regs *regs)
+{
+ struct bug_entry *bug;
+ unsigned long addr;
+
+ if (regs->msr & MSR_PR)
+ return 0; /* not in kernel */
+ addr = regs->nip; /* address of trap instruction */
+ if (addr < PAGE_OFFSET)
+ return 0;
+ bug = find_bug(regs->nip);
+ if (bug == NULL)
+ return 0;
+ if (bug->line & BUG_WARNING_TRAP) {
+ /* this is a WARN_ON rather than BUG/BUG_ON */
+#ifdef CONFIG_XMON
+ xmon_printf(KERN_ERR "Badness in %s at %s:%d\n",
+ bug->function, bug->file,
+ bug->line & ~BUG_WARNING_TRAP);
+#endif /* CONFIG_XMON */
+ printk(KERN_ERR "Badness in %s at %s:%d\n",
+ bug->function, bug->file,
+ bug->line & ~BUG_WARNING_TRAP);
+ dump_stack();
+ return 1;
+ }
+#ifdef CONFIG_XMON
+ xmon_printf(KERN_CRIT "kernel BUG in %s at %s:%d!\n",
+ bug->function, bug->file, bug->line);
+ xmon(regs);
+#endif /* CONFIG_XMON */
+ printk(KERN_CRIT "kernel BUG in %s at %s:%d!\n",
+ bug->function, bug->file, bug->line);
+
+ return 0;
+}
+
+void __kprobes program_check_exception(struct pt_regs *regs)
+{
+ unsigned int reason = get_reason(regs);
+ extern int do_mathemu(struct pt_regs *regs);
+
+#ifdef CONFIG_MATH_EMULATION
+ /* (reason & REASON_ILLEGAL) would be the obvious thing here,
+ * but there seems to be a hardware bug on the 405GP (RevD)
+ * that means ESR is sometimes set incorrectly - either to
+ * ESR_DST (!?) or 0. In the process of chasing this with the
+ * hardware people - not sure if it can happen on any illegal
+ * instruction or only on FP instructions, whether there is a
+ * pattern to occurences etc. -dgibson 31/Mar/2003 */
+ if (!(reason & REASON_TRAP) && do_mathemu(regs) == 0) {
+ emulate_single_step(regs);
+ return;
+ }
+#endif /* CONFIG_MATH_EMULATION */
+
+ if (reason & REASON_FP) {
+ /* IEEE FP exception */
+ parse_fpe(regs);
+ return;
+ }
+ if (reason & REASON_TRAP) {
+ /* trap exception */
+ if (notify_die(DIE_BPT, "breakpoint", regs, 5, 5, SIGTRAP)
+ == NOTIFY_STOP)
+ return;
+ if (debugger_bpt(regs))
+ return;
+ if (check_bug_trap(regs)) {
+ regs->nip += 4;
+ return;
+ }
+ _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
+ return;
+ }
+
+ /* Try to emulate it if we should. */
+ if (reason & (REASON_ILLEGAL | REASON_PRIVILEGED)) {
+ switch (emulate_instruction(regs)) {
+ case 0:
+ regs->nip += 4;
+ emulate_single_step(regs);
+ return;
+ case -EFAULT:
+ _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
+ return;
+ }
+ }
+
+ if (reason & REASON_PRIVILEGED)
+ _exception(SIGILL, regs, ILL_PRVOPC, regs->nip);
+ else
+ _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
+}
+
+void alignment_exception(struct pt_regs *regs)
+{
+ int fixed;
+
+ fixed = fix_alignment(regs);
+
+ if (fixed == 1) {
+ regs->nip += 4; /* skip over emulated instruction */
+ emulate_single_step(regs);
+ return;
+ }
+
+ /* Operand address was bad */
+ if (fixed == -EFAULT) {
+ if (user_mode(regs))
+ _exception(SIGSEGV, regs, SEGV_ACCERR, regs->dar);
+ else
+ /* Search exception table */
+ bad_page_fault(regs, regs->dar, SIGSEGV);
+ return;
+ }
+ _exception(SIGBUS, regs, BUS_ADRALN, regs->dar);
+}
+
+void StackOverflow(struct pt_regs *regs)
+{
+ printk(KERN_CRIT "Kernel stack overflow in process %p, r1=%lx\n",
+ current, regs->gpr[1]);
+ debugger(regs);
+ show_regs(regs);
+ panic("kernel stack overflow");
+}
+
+void nonrecoverable_exception(struct pt_regs *regs)
+{
+ printk(KERN_ERR "Non-recoverable exception at PC=%lx MSR=%lx\n",
+ regs->nip, regs->msr);
+ debugger(regs);
+ die("nonrecoverable exception", regs, SIGKILL);
+}
+
+void trace_syscall(struct pt_regs *regs)
+{
+ printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld %s\n",
+ current, current->pid, regs->nip, regs->link, regs->gpr[0],
+ regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted());
+}
+
+void kernel_fp_unavailable_exception(struct pt_regs *regs)
+{
+ printk(KERN_EMERG "Unrecoverable FP Unavailable Exception "
+ "%lx at %lx\n", regs->trap, regs->nip);
+ die("Unrecoverable FP Unavailable Exception", regs, SIGABRT);
+}
+
+void altivec_unavailable_exception(struct pt_regs *regs)
+{
+#if !defined(CONFIG_ALTIVEC)
+ if (user_mode(regs)) {
+ /* A user program has executed an altivec instruction,
+ but this kernel doesn't support altivec. */
+ _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
+ return;
+ }
+#endif
+ printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception "
+ "%lx at %lx\n", regs->trap, regs->nip);
+ die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT);
+}
+
+#ifdef CONFIG_PPC64
+extern perf_irq_t perf_irq;
+#endif
+
+#if defined(CONFIG_PPC64) || defined(CONFIG_E500)
+void performance_monitor_exception(struct pt_regs *regs)
+{
+ perf_irq(regs);
+}
+#endif
+
+#ifdef CONFIG_8xx
+void SoftwareEmulation(struct pt_regs *regs)
+{
+ extern int do_mathemu(struct pt_regs *);
+ extern int Soft_emulate_8xx(struct pt_regs *);
+ int errcode;
+
+ CHECK_FULL_REGS(regs);
+
+ if (!user_mode(regs)) {
+ debugger(regs);
+ die("Kernel Mode Software FPU Emulation", regs, SIGFPE);
+ }
+
+#ifdef CONFIG_MATH_EMULATION
+ errcode = do_mathemu(regs);
+#else
+ errcode = Soft_emulate_8xx(regs);
+#endif
+ if (errcode) {
+ if (errcode > 0)
+ _exception(SIGFPE, regs, 0, 0);
+ else if (errcode == -EFAULT)
+ _exception(SIGSEGV, regs, 0, 0);
+ else
+ _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
+ } else
+ emulate_single_step(regs);
+}
+#endif /* CONFIG_8xx */
+
+#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+
+void DebugException(struct pt_regs *regs, unsigned long debug_status)
+{
+ if (debug_status & DBSR_IC) { /* instruction completion */
+ regs->msr &= ~MSR_DE;
+ if (user_mode(regs)) {
+ current->thread.dbcr0 &= ~DBCR0_IC;
+ } else {
+ /* Disable instruction completion */
+ mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~DBCR0_IC);
+ /* Clear the instruction completion event */
+ mtspr(SPRN_DBSR, DBSR_IC);
+ if (debugger_sstep(regs))
+ return;
+ }
+ _exception(SIGTRAP, regs, TRAP_TRACE, 0);
+ }
+}
+#endif /* CONFIG_4xx || CONFIG_BOOKE */
+
+#if !defined(CONFIG_TAU_INT)
+void TAUException(struct pt_regs *regs)
+{
+ printk("TAU trap at PC: %lx, MSR: %lx, vector=%lx %s\n",
+ regs->nip, regs->msr, regs->trap, print_tainted());
+}
+#endif /* CONFIG_INT_TAU */
+
+#ifdef CONFIG_ALTIVEC
+void altivec_assist_exception(struct pt_regs *regs)
+{
+ int err;
+
+ if (!user_mode(regs)) {
+ printk(KERN_EMERG "VMX/Altivec assist exception in kernel mode"
+ " at %lx\n", regs->nip);
+ die("Kernel VMX/Altivec assist exception", regs, SIGILL);
+ }
+
+ flush_altivec_to_thread(current);
+
+ err = emulate_altivec(regs);
+ if (err == 0) {
+ regs->nip += 4; /* skip emulated instruction */
+ emulate_single_step(regs);
+ return;
+ }
+
+ if (err == -EFAULT) {
+ /* got an error reading the instruction */
+ _exception(SIGSEGV, regs, SEGV_ACCERR, regs->nip);
+ } else {
+ /* didn't recognize the instruction */
+ /* XXX quick hack for now: set the non-Java bit in the VSCR */
+ if (printk_ratelimit())
+ printk(KERN_ERR "Unrecognized altivec instruction "
+ "in %s at %lx\n", current->comm, regs->nip);
+ current->thread.vscr.u[3] |= 0x10000;
+ }
+}
+#endif /* CONFIG_ALTIVEC */
+
+#ifdef CONFIG_FSL_BOOKE
+void CacheLockingException(struct pt_regs *regs, unsigned long address,
+ unsigned long error_code)
+{
+ /* We treat cache locking instructions from the user
+ * as priv ops, in the future we could try to do
+ * something smarter
+ */
+ if (error_code & (ESR_DLK|ESR_ILK))
+ _exception(SIGILL, regs, ILL_PRVOPC, regs->nip);
+ return;
+}
+#endif /* CONFIG_FSL_BOOKE */
+
+#ifdef CONFIG_SPE
+void SPEFloatingPointException(struct pt_regs *regs)
+{
+ unsigned long spefscr;
+ int fpexc_mode;
+ int code = 0;
+
+ spefscr = current->thread.spefscr;
+ fpexc_mode = current->thread.fpexc_mode;
+
+ /* Hardware does not neccessarily set sticky
+ * underflow/overflow/invalid flags */
+ if ((spefscr & SPEFSCR_FOVF) && (fpexc_mode & PR_FP_EXC_OVF)) {
+ code = FPE_FLTOVF;
+ spefscr |= SPEFSCR_FOVFS;
+ }
+ else if ((spefscr & SPEFSCR_FUNF) && (fpexc_mode & PR_FP_EXC_UND)) {
+ code = FPE_FLTUND;
+ spefscr |= SPEFSCR_FUNFS;
+ }
+ else if ((spefscr & SPEFSCR_FDBZ) && (fpexc_mode & PR_FP_EXC_DIV))
+ code = FPE_FLTDIV;
+ else if ((spefscr & SPEFSCR_FINV) && (fpexc_mode & PR_FP_EXC_INV)) {
+ code = FPE_FLTINV;
+ spefscr |= SPEFSCR_FINVS;
+ }
+ else if ((spefscr & (SPEFSCR_FG | SPEFSCR_FX)) && (fpexc_mode & PR_FP_EXC_RES))
+ code = FPE_FLTRES;
+
+ current->thread.spefscr = spefscr;
+
+ _exception(SIGFPE, regs, code, regs->nip);
+ return;
+}
+#endif
+
+/*
+ * We enter here if we get an unrecoverable exception, that is, one
+ * that happened at a point where the RI (recoverable interrupt) bit
+ * in the MSR is 0. This indicates that SRR0/1 are live, and that
+ * we therefore lost state by taking this exception.
+ */
+void unrecoverable_exception(struct pt_regs *regs)
+{
+ printk(KERN_EMERG "Unrecoverable exception %lx at %lx\n",
+ regs->trap, regs->nip);
+ die("Unrecoverable exception", regs, SIGABRT);
+}
+
+#ifdef CONFIG_BOOKE_WDT
+/*
+ * Default handler for a Watchdog exception,
+ * spins until a reboot occurs
+ */
+void __attribute__ ((weak)) WatchdogHandler(struct pt_regs *regs)
+{
+ /* Generic WatchdogHandler, implement your own */
+ mtspr(SPRN_TCR, mfspr(SPRN_TCR)&(~TCR_WIE));
+ return;
+}
+
+void WatchdogException(struct pt_regs *regs)
+{
+ printk (KERN_EMERG "PowerPC Book-E Watchdog Exception\n");
+ WatchdogHandler(regs);
+}
+#endif
+
+/*
+ * We enter here if we discover during exception entry that we are
+ * running in supervisor mode with a userspace value in the stack pointer.
+ */
+void kernel_bad_stack(struct pt_regs *regs)
+{
+ printk(KERN_EMERG "Bad kernel stack pointer %lx at %lx\n",
+ regs->gpr[1], regs->nip);
+ die("Bad kernel stack pointer", regs, SIGABRT);
+}
+
+void __init trap_init(void)
+{
+}
diff --git a/arch/ppc/kernel/vecemu.c b/arch/powerpc/kernel/vecemu.c
index 604d0947cb20..604d0947cb20 100644
--- a/arch/ppc/kernel/vecemu.c
+++ b/arch/powerpc/kernel/vecemu.c
diff --git a/arch/ppc64/kernel/vector.S b/arch/powerpc/kernel/vector.S
index b79d33e4001e..66b3d03c5fa5 100644
--- a/arch/ppc64/kernel/vector.S
+++ b/arch/powerpc/kernel/vector.S
@@ -1,11 +1,26 @@
+#include <linux/config.h>
#include <asm/ppc_asm.h>
-#include <asm/processor.h>
+#include <asm/reg.h>
/*
* The routines below are in assembler so we can closely control the
* usage of floating-point registers. These routines must be called
* with preempt disabled.
*/
+#ifdef CONFIG_PPC32
+ .data
+fpzero:
+ .long 0
+fpone:
+ .long 0x3f800000 /* 1.0 in single-precision FP */
+fphalf:
+ .long 0x3f000000 /* 0.5 in single-precision FP */
+
+#define LDCONST(fr, name) \
+ lis r11,name@ha; \
+ lfs fr,name@l(r11)
+#else
+
.section ".toc","aw"
fpzero:
.tc FD_0_0[TC],0
@@ -14,32 +29,42 @@ fpone:
fphalf:
.tc FD_3fe00000_0[TC],0x3fe0000000000000 /* 0.5 */
+#define LDCONST(fr, name) \
+ lfd fr,name@toc(r2)
+#endif
+
.text
/*
* Internal routine to enable floating point and set FPSCR to 0.
* Don't call it from C; it doesn't use the normal calling convention.
*/
fpenable:
+#ifdef CONFIG_PPC32
+ stwu r1,-64(r1)
+#else
+ stdu r1,-64(r1)
+#endif
mfmsr r10
ori r11,r10,MSR_FP
mtmsr r11
isync
- stfd fr31,-8(r1)
- stfd fr0,-16(r1)
- stfd fr1,-24(r1)
+ stfd fr0,24(r1)
+ stfd fr1,16(r1)
+ stfd fr31,8(r1)
+ LDCONST(fr1, fpzero)
mffs fr31
- lfd fr1,fpzero@toc(r2)
mtfsf 0xff,fr1
blr
fpdisable:
mtlr r12
mtfsf 0xff,fr31
- lfd fr1,-24(r1)
- lfd fr0,-16(r1)
- lfd fr31,-8(r1)
+ lfd fr31,8(r1)
+ lfd fr1,16(r1)
+ lfd fr0,24(r1)
mtmsr r10
isync
+ addi r1,r1,64
blr
/*
@@ -82,7 +107,7 @@ _GLOBAL(vsubfp)
_GLOBAL(vmaddfp)
mflr r12
bl fpenable
- stfd fr2,-32(r1)
+ stfd fr2,32(r1)
li r0,4
mtctr r0
li r7,0
@@ -93,7 +118,7 @@ _GLOBAL(vmaddfp)
stfsx fr0,r3,r7
addi r7,r7,4
bdnz 1b
- lfd fr2,-32(r1)
+ lfd fr2,32(r1)
b fpdisable
/*
@@ -102,7 +127,7 @@ _GLOBAL(vmaddfp)
_GLOBAL(vnmsubfp)
mflr r12
bl fpenable
- stfd fr2,-32(r1)
+ stfd fr2,32(r1)
li r0,4
mtctr r0
li r7,0
@@ -113,7 +138,7 @@ _GLOBAL(vnmsubfp)
stfsx fr0,r3,r7
addi r7,r7,4
bdnz 1b
- lfd fr2,-32(r1)
+ lfd fr2,32(r1)
b fpdisable
/*
@@ -124,7 +149,7 @@ _GLOBAL(vrefp)
mflr r12
bl fpenable
li r0,4
- lfd fr1,fpone@toc(r2)
+ LDCONST(fr1, fpone)
mtctr r0
li r6,0
1: lfsx fr0,r4,r6
@@ -143,13 +168,13 @@ _GLOBAL(vrefp)
_GLOBAL(vrsqrtefp)
mflr r12
bl fpenable
- stfd fr2,-32(r1)
- stfd fr3,-40(r1)
- stfd fr4,-48(r1)
- stfd fr5,-56(r1)
+ stfd fr2,32(r1)
+ stfd fr3,40(r1)
+ stfd fr4,48(r1)
+ stfd fr5,56(r1)
li r0,4
- lfd fr4,fpone@toc(r2)
- lfd fr5,fphalf@toc(r2)
+ LDCONST(fr4, fpone)
+ LDCONST(fr5, fphalf)
mtctr r0
li r6,0
1: lfsx fr0,r4,r6
@@ -165,8 +190,8 @@ _GLOBAL(vrsqrtefp)
stfsx fr1,r3,r6
addi r6,r6,4
bdnz 1b
- lfd fr5,-56(r1)
- lfd fr4,-48(r1)
- lfd fr3,-40(r1)
- lfd fr2,-32(r1)
+ lfd fr5,56(r1)
+ lfd fr4,48(r1)
+ lfd fr3,40(r1)
+ lfd fr2,32(r1)
b fpdisable
diff --git a/arch/ppc64/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 0e555b7a6587..97082a4203ad 100644
--- a/arch/ppc64/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -69,6 +69,16 @@ static int vio_bus_remove(struct device *dev)
return 1;
}
+/* convert from struct device to struct vio_dev and pass to driver. */
+static void vio_bus_shutdown(struct device *dev)
+{
+ struct vio_dev *viodev = to_vio_dev(dev);
+ struct vio_driver *viodrv = to_vio_driver(dev->driver);
+
+ if (viodrv->shutdown)
+ viodrv->shutdown(viodev);
+}
+
/**
* vio_register_driver: - Register a new vio driver
* @drv: The vio_driver structure to be registered.
@@ -76,13 +86,13 @@ static int vio_bus_remove(struct device *dev)
int vio_register_driver(struct vio_driver *viodrv)
{
printk(KERN_DEBUG "%s: driver %s registering\n", __FUNCTION__,
- viodrv->name);
+ viodrv->driver.name);
/* fill in 'struct driver' fields */
- viodrv->driver.name = viodrv->name;
viodrv->driver.bus = &vio_bus_type;
viodrv->driver.probe = vio_bus_probe;
viodrv->driver.remove = vio_bus_remove;
+ viodrv->driver.shutdown = vio_bus_shutdown;
return driver_register(&viodrv->driver);
}
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
new file mode 100644
index 000000000000..d4dfcfbce272
--- /dev/null
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -0,0 +1,279 @@
+#include <linux/config.h>
+#ifdef CONFIG_PPC64
+#include <asm/page.h>
+#else
+#define PAGE_SIZE 4096
+#endif
+#include <asm-generic/vmlinux.lds.h>
+
+#ifdef CONFIG_PPC64
+OUTPUT_ARCH(powerpc:common64)
+jiffies = jiffies_64;
+#else
+OUTPUT_ARCH(powerpc:common)
+jiffies = jiffies_64 + 4;
+#endif
+SECTIONS
+{
+ /* Sections to be discarded. */
+ /DISCARD/ : {
+ *(.exitcall.exit)
+ *(.exit.data)
+ }
+
+
+ /* Read-only sections, merged into text segment: */
+#ifdef CONFIG_PPC32
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+/* .init : { *(.init) } =0*/
+ .plt : { *(.plt) }
+#endif
+ .text : {
+ *(.text .text.*)
+ SCHED_TEXT
+ LOCK_TEXT
+ KPROBES_TEXT
+ *(.fixup)
+#ifdef CONFIG_PPC32
+ *(.got1)
+ __got2_start = .;
+ *(.got2)
+ __got2_end = .;
+#else
+ . = ALIGN(PAGE_SIZE);
+ _etext = .;
+#endif
+ }
+#ifdef CONFIG_PPC32
+ _etext = .;
+ PROVIDE (etext = .);
+
+ RODATA
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ .fixup : { *(.fixup) }
+#endif
+
+ __ex_table : {
+ __start___ex_table = .;
+ *(__ex_table)
+ __stop___ex_table = .;
+ }
+
+ __bug_table : {
+ __start___bug_table = .;
+ *(__bug_table)
+ __stop___bug_table = .;
+ }
+
+#ifdef CONFIG_PPC64
+ __ftr_fixup : {
+ __start___ftr_fixup = .;
+ *(__ftr_fixup)
+ __stop___ftr_fixup = .;
+ }
+
+ RODATA
+#endif
+
+#ifdef CONFIG_PPC32
+ /* Read-write section, merged into data segment: */
+ . = ALIGN(PAGE_SIZE);
+ _sdata = .;
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.got.plt) *(.got)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+
+ . = ALIGN(PAGE_SIZE);
+ __nosave_begin = .;
+ .data_nosave : { *(.data.nosave) }
+ . = ALIGN(PAGE_SIZE);
+ __nosave_end = .;
+
+ . = ALIGN(32);
+ .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+
+ _edata = .;
+ PROVIDE (edata = .);
+
+ . = ALIGN(8192);
+ .data.init_task : { *(.data.init_task) }
+#endif
+
+ /* will be freed after init */
+ . = ALIGN(PAGE_SIZE);
+ __init_begin = .;
+ .init.text : {
+ _sinittext = .;
+ *(.init.text)
+ _einittext = .;
+ }
+#ifdef CONFIG_PPC32
+ /* .exit.text is discarded at runtime, not link time,
+ to deal with references from __bug_table */
+ .exit.text : { *(.exit.text) }
+#endif
+ .init.data : {
+ *(.init.data);
+ __vtop_table_begin = .;
+ *(.vtop_fixup);
+ __vtop_table_end = .;
+ __ptov_table_begin = .;
+ *(.ptov_fixup);
+ __ptov_table_end = .;
+ }
+
+ . = ALIGN(16);
+ .init.setup : {
+ __setup_start = .;
+ *(.init.setup)
+ __setup_end = .;
+ }
+
+ .initcall.init : {
+ __initcall_start = .;
+ *(.initcall1.init)
+ *(.initcall2.init)
+ *(.initcall3.init)
+ *(.initcall4.init)
+ *(.initcall5.init)
+ *(.initcall6.init)
+ *(.initcall7.init)
+ __initcall_end = .;
+ }
+
+ .con_initcall.init : {
+ __con_initcall_start = .;
+ *(.con_initcall.init)
+ __con_initcall_end = .;
+ }
+
+ SECURITY_INIT
+
+#ifdef CONFIG_PPC32
+ __start___ftr_fixup = .;
+ __ftr_fixup : { *(__ftr_fixup) }
+ __stop___ftr_fixup = .;
+#else
+ . = ALIGN(PAGE_SIZE);
+ .init.ramfs : {
+ __initramfs_start = .;
+ *(.init.ramfs)
+ __initramfs_end = .;
+ }
+#endif
+
+#ifdef CONFIG_PPC32
+ . = ALIGN(32);
+#endif
+ .data.percpu : {
+ __per_cpu_start = .;
+ *(.data.percpu)
+ __per_cpu_end = .;
+ }
+
+ . = ALIGN(PAGE_SIZE);
+#ifdef CONFIG_PPC64
+ . = ALIGN(16384);
+ __init_end = .;
+ /* freed after init ends here */
+
+ /* Read/write sections */
+ . = ALIGN(PAGE_SIZE);
+ . = ALIGN(16384);
+ _sdata = .;
+ /* The initial task and kernel stack */
+ .data.init_task : {
+ *(.data.init_task)
+ }
+
+ . = ALIGN(PAGE_SIZE);
+ .data.page_aligned : {
+ *(.data.page_aligned)
+ }
+
+ .data.cacheline_aligned : {
+ *(.data.cacheline_aligned)
+ }
+
+ .data : {
+ *(.data .data.rel* .toc1)
+ *(.branch_lt)
+ }
+
+ .opd : {
+ *(.opd)
+ }
+
+ .got : {
+ __toc_start = .;
+ *(.got)
+ *(.toc)
+ . = ALIGN(PAGE_SIZE);
+ _edata = .;
+ }
+
+ . = ALIGN(PAGE_SIZE);
+#else
+ __initramfs_start = .;
+ .init.ramfs : {
+ *(.init.ramfs)
+ }
+ __initramfs_end = .;
+
+ . = ALIGN(4096);
+ __init_end = .;
+
+ . = ALIGN(4096);
+ _sextratext = .;
+ _eextratext = .;
+
+ __bss_start = .;
+#endif
+
+ .bss : {
+ __bss_start = .;
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ __bss_stop = .;
+ }
+
+#ifdef CONFIG_PPC64
+ . = ALIGN(PAGE_SIZE);
+#endif
+ _end = . ;
+#ifdef CONFIG_PPC32
+ PROVIDE (end = .);
+#endif
+}
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
new file mode 100644
index 000000000000..e6b2be3bcec1
--- /dev/null
+++ b/arch/powerpc/lib/Makefile
@@ -0,0 +1,19 @@
+#
+# Makefile for ppc-specific library files..
+#
+
+ifeq ($(CONFIG_PPC_MERGE),y)
+obj-y := string.o
+endif
+
+obj-y += strcase.o
+obj-$(CONFIG_PPC32) += div64.o copy_32.o checksum_32.o
+obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \
+ memcpy_64.o usercopy_64.o mem_64.o
+obj-$(CONFIG_PPC_ISERIES) += e2a.o
+obj-$(CONFIG_XMON) += sstep.o
+
+ifeq ($(CONFIG_PPC64),y)
+obj-$(CONFIG_SMP) += locks.o
+obj-$(CONFIG_DEBUG_KERNEL) += sstep.o
+endif
diff --git a/arch/powerpc/lib/checksum_32.S b/arch/powerpc/lib/checksum_32.S
new file mode 100644
index 000000000000..7874e8a80455
--- /dev/null
+++ b/arch/powerpc/lib/checksum_32.S
@@ -0,0 +1,225 @@
+/*
+ * This file contains assembly-language implementations
+ * of IP-style 1's complement checksum routines.
+ *
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.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.
+ *
+ * Severely hacked about by Paul Mackerras (paulus@cs.anu.edu.au).
+ */
+
+#include <linux/sys.h>
+#include <asm/processor.h>
+#include <asm/errno.h>
+#include <asm/ppc_asm.h>
+
+ .text
+
+/*
+ * ip_fast_csum(buf, len) -- Optimized for IP header
+ * len is in words and is always >= 5.
+ */
+_GLOBAL(ip_fast_csum)
+ lwz r0,0(r3)
+ lwzu r5,4(r3)
+ addic. r4,r4,-2
+ addc r0,r0,r5
+ mtctr r4
+ blelr-
+1: lwzu r4,4(r3)
+ adde r0,r0,r4
+ bdnz 1b
+ addze r0,r0 /* add in final carry */
+ rlwinm r3,r0,16,0,31 /* fold two halves together */
+ add r3,r0,r3
+ not r3,r3
+ srwi r3,r3,16
+ blr
+
+/*
+ * Compute checksum of TCP or UDP pseudo-header:
+ * csum_tcpudp_magic(saddr, daddr, len, proto, sum)
+ */
+_GLOBAL(csum_tcpudp_magic)
+ rlwimi r5,r6,16,0,15 /* put proto in upper half of len */
+ addc r0,r3,r4 /* add 4 32-bit words together */
+ adde r0,r0,r5
+ adde r0,r0,r7
+ addze r0,r0 /* add in final carry */
+ rlwinm r3,r0,16,0,31 /* fold two halves together */
+ add r3,r0,r3
+ not r3,r3
+ srwi r3,r3,16
+ blr
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * csum_partial(buff, len, sum)
+ */
+_GLOBAL(csum_partial)
+ addic r0,r5,0
+ subi r3,r3,4
+ srwi. r6,r4,2
+ beq 3f /* if we're doing < 4 bytes */
+ andi. r5,r3,2 /* Align buffer to longword boundary */
+ beq+ 1f
+ lhz r5,4(r3) /* do 2 bytes to get aligned */
+ addi r3,r3,2
+ subi r4,r4,2
+ addc r0,r0,r5
+ srwi. r6,r4,2 /* # words to do */
+ beq 3f
+1: mtctr r6
+2: lwzu r5,4(r3) /* the bdnz has zero overhead, so it should */
+ adde r0,r0,r5 /* be unnecessary to unroll this loop */
+ bdnz 2b
+ andi. r4,r4,3
+3: cmpwi 0,r4,2
+ blt+ 4f
+ lhz r5,4(r3)
+ addi r3,r3,2
+ subi r4,r4,2
+ adde r0,r0,r5
+4: cmpwi 0,r4,1
+ bne+ 5f
+ lbz r5,4(r3)
+ slwi r5,r5,8 /* Upper byte of word */
+ adde r0,r0,r5
+5: addze r3,r0 /* add in final carry */
+ blr
+
+/*
+ * Computes the checksum of a memory block at src, length len,
+ * and adds in "sum" (32-bit), while copying the block to dst.
+ * If an access exception occurs on src or dst, it stores -EFAULT
+ * to *src_err or *dst_err respectively, and (for an error on
+ * src) zeroes the rest of dst.
+ *
+ * csum_partial_copy_generic(src, dst, len, sum, src_err, dst_err)
+ */
+_GLOBAL(csum_partial_copy_generic)
+ addic r0,r6,0
+ subi r3,r3,4
+ subi r4,r4,4
+ srwi. r6,r5,2
+ beq 3f /* if we're doing < 4 bytes */
+ andi. r9,r4,2 /* Align dst to longword boundary */
+ beq+ 1f
+81: lhz r6,4(r3) /* do 2 bytes to get aligned */
+ addi r3,r3,2
+ subi r5,r5,2
+91: sth r6,4(r4)
+ addi r4,r4,2
+ addc r0,r0,r6
+ srwi. r6,r5,2 /* # words to do */
+ beq 3f
+1: srwi. r6,r5,4 /* # groups of 4 words to do */
+ beq 10f
+ mtctr r6
+71: lwz r6,4(r3)
+72: lwz r9,8(r3)
+73: lwz r10,12(r3)
+74: lwzu r11,16(r3)
+ adde r0,r0,r6
+75: stw r6,4(r4)
+ adde r0,r0,r9
+76: stw r9,8(r4)
+ adde r0,r0,r10
+77: stw r10,12(r4)
+ adde r0,r0,r11
+78: stwu r11,16(r4)
+ bdnz 71b
+10: rlwinm. r6,r5,30,30,31 /* # words left to do */
+ beq 13f
+ mtctr r6
+82: lwzu r9,4(r3)
+92: stwu r9,4(r4)
+ adde r0,r0,r9
+ bdnz 82b
+13: andi. r5,r5,3
+3: cmpwi 0,r5,2
+ blt+ 4f
+83: lhz r6,4(r3)
+ addi r3,r3,2
+ subi r5,r5,2
+93: sth r6,4(r4)
+ addi r4,r4,2
+ adde r0,r0,r6
+4: cmpwi 0,r5,1
+ bne+ 5f
+84: lbz r6,4(r3)
+94: stb r6,4(r4)
+ slwi r6,r6,8 /* Upper byte of word */
+ adde r0,r0,r6
+5: addze r3,r0 /* add in final carry */
+ blr
+
+/* These shouldn't go in the fixup section, since that would
+ cause the ex_table addresses to get out of order. */
+
+src_error_4:
+ mfctr r6 /* update # bytes remaining from ctr */
+ rlwimi r5,r6,4,0,27
+ b 79f
+src_error_1:
+ li r6,0
+ subi r5,r5,2
+95: sth r6,4(r4)
+ addi r4,r4,2
+79: srwi. r6,r5,2
+ beq 3f
+ mtctr r6
+src_error_2:
+ li r6,0
+96: stwu r6,4(r4)
+ bdnz 96b
+3: andi. r5,r5,3
+ beq src_error
+src_error_3:
+ li r6,0
+ mtctr r5
+ addi r4,r4,3
+97: stbu r6,1(r4)
+ bdnz 97b
+src_error:
+ cmpwi 0,r7,0
+ beq 1f
+ li r6,-EFAULT
+ stw r6,0(r7)
+1: addze r3,r0
+ blr
+
+dst_error:
+ cmpwi 0,r8,0
+ beq 1f
+ li r6,-EFAULT
+ stw r6,0(r8)
+1: addze r3,r0
+ blr
+
+.section __ex_table,"a"
+ .long 81b,src_error_1
+ .long 91b,dst_error
+ .long 71b,src_error_4
+ .long 72b,src_error_4
+ .long 73b,src_error_4
+ .long 74b,src_error_4
+ .long 75b,dst_error
+ .long 76b,dst_error
+ .long 77b,dst_error
+ .long 78b,dst_error
+ .long 82b,src_error_2
+ .long 92b,dst_error
+ .long 83b,src_error_3
+ .long 93b,dst_error
+ .long 84b,src_error_3
+ .long 94b,dst_error
+ .long 95b,dst_error
+ .long 96b,dst_error
+ .long 97b,dst_error
diff --git a/arch/ppc64/lib/checksum.S b/arch/powerpc/lib/checksum_64.S
index ef96c6c58efc..ef96c6c58efc 100644
--- a/arch/ppc64/lib/checksum.S
+++ b/arch/powerpc/lib/checksum_64.S
diff --git a/arch/powerpc/lib/copy_32.S b/arch/powerpc/lib/copy_32.S
new file mode 100644
index 000000000000..bee51414812e
--- /dev/null
+++ b/arch/powerpc/lib/copy_32.S
@@ -0,0 +1,543 @@
+/*
+ * Memory copy functions for 32-bit PowerPC.
+ *
+ * Copyright (C) 1996-2005 Paul Mackerras.
+ *
+ * This program is free software; you can redistribute 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/config.h>
+#include <asm/processor.h>
+#include <asm/cache.h>
+#include <asm/errno.h>
+#include <asm/ppc_asm.h>
+
+#define COPY_16_BYTES \
+ lwz r7,4(r4); \
+ lwz r8,8(r4); \
+ lwz r9,12(r4); \
+ lwzu r10,16(r4); \
+ stw r7,4(r6); \
+ stw r8,8(r6); \
+ stw r9,12(r6); \
+ stwu r10,16(r6)
+
+#define COPY_16_BYTES_WITHEX(n) \
+8 ## n ## 0: \
+ lwz r7,4(r4); \
+8 ## n ## 1: \
+ lwz r8,8(r4); \
+8 ## n ## 2: \
+ lwz r9,12(r4); \
+8 ## n ## 3: \
+ lwzu r10,16(r4); \
+8 ## n ## 4: \
+ stw r7,4(r6); \
+8 ## n ## 5: \
+ stw r8,8(r6); \
+8 ## n ## 6: \
+ stw r9,12(r6); \
+8 ## n ## 7: \
+ stwu r10,16(r6)
+
+#define COPY_16_BYTES_EXCODE(n) \
+9 ## n ## 0: \
+ addi r5,r5,-(16 * n); \
+ b 104f; \
+9 ## n ## 1: \
+ addi r5,r5,-(16 * n); \
+ b 105f; \
+.section __ex_table,"a"; \
+ .align 2; \
+ .long 8 ## n ## 0b,9 ## n ## 0b; \
+ .long 8 ## n ## 1b,9 ## n ## 0b; \
+ .long 8 ## n ## 2b,9 ## n ## 0b; \
+ .long 8 ## n ## 3b,9 ## n ## 0b; \
+ .long 8 ## n ## 4b,9 ## n ## 1b; \
+ .long 8 ## n ## 5b,9 ## n ## 1b; \
+ .long 8 ## n ## 6b,9 ## n ## 1b; \
+ .long 8 ## n ## 7b,9 ## n ## 1b; \
+ .text
+
+ .text
+ .stabs "arch/powerpc/lib/",N_SO,0,0,0f
+ .stabs "copy32.S",N_SO,0,0,0f
+0:
+
+CACHELINE_BYTES = L1_CACHE_BYTES
+LG_CACHELINE_BYTES = L1_CACHE_SHIFT
+CACHELINE_MASK = (L1_CACHE_BYTES-1)
+
+/*
+ * Use dcbz on the complete cache lines in the destination
+ * to set them to zero. This requires that the destination
+ * area is cacheable. -- paulus
+ */
+_GLOBAL(cacheable_memzero)
+ mr r5,r4
+ li r4,0
+ addi r6,r3,-4
+ cmplwi 0,r5,4
+ blt 7f
+ stwu r4,4(r6)
+ beqlr
+ andi. r0,r6,3
+ add r5,r0,r5
+ subf r6,r0,r6
+ clrlwi r7,r6,32-LG_CACHELINE_BYTES
+ add r8,r7,r5
+ srwi r9,r8,LG_CACHELINE_BYTES
+ addic. r9,r9,-1 /* total number of complete cachelines */
+ ble 2f
+ xori r0,r7,CACHELINE_MASK & ~3
+ srwi. r0,r0,2
+ beq 3f
+ mtctr r0
+4: stwu r4,4(r6)
+ bdnz 4b
+3: mtctr r9
+ li r7,4
+#if !defined(CONFIG_8xx)
+10: dcbz r7,r6
+#else
+10: stw r4, 4(r6)
+ stw r4, 8(r6)
+ stw r4, 12(r6)
+ stw r4, 16(r6)
+#if CACHE_LINE_SIZE >= 32
+ stw r4, 20(r6)
+ stw r4, 24(r6)
+ stw r4, 28(r6)
+ stw r4, 32(r6)
+#endif /* CACHE_LINE_SIZE */
+#endif
+ addi r6,r6,CACHELINE_BYTES
+ bdnz 10b
+ clrlwi r5,r8,32-LG_CACHELINE_BYTES
+ addi r5,r5,4
+2: srwi r0,r5,2
+ mtctr r0
+ bdz 6f
+1: stwu r4,4(r6)
+ bdnz 1b
+6: andi. r5,r5,3
+7: cmpwi 0,r5,0
+ beqlr
+ mtctr r5
+ addi r6,r6,3
+8: stbu r4,1(r6)
+ bdnz 8b
+ blr
+
+_GLOBAL(memset)
+ rlwimi r4,r4,8,16,23
+ rlwimi r4,r4,16,0,15
+ addi r6,r3,-4
+ cmplwi 0,r5,4
+ blt 7f
+ stwu r4,4(r6)
+ beqlr
+ andi. r0,r6,3
+ add r5,r0,r5
+ subf r6,r0,r6
+ srwi r0,r5,2
+ mtctr r0
+ bdz 6f
+1: stwu r4,4(r6)
+ bdnz 1b
+6: andi. r5,r5,3
+7: cmpwi 0,r5,0
+ beqlr
+ mtctr r5
+ addi r6,r6,3
+8: stbu r4,1(r6)
+ bdnz 8b
+ blr
+
+/*
+ * This version uses dcbz on the complete cache lines in the
+ * destination area to reduce memory traffic. This requires that
+ * the destination area is cacheable.
+ * We only use this version if the source and dest don't overlap.
+ * -- paulus.
+ */
+_GLOBAL(cacheable_memcpy)
+ add r7,r3,r5 /* test if the src & dst overlap */
+ add r8,r4,r5
+ cmplw 0,r4,r7
+ cmplw 1,r3,r8
+ crand 0,0,4 /* cr0.lt &= cr1.lt */
+ blt memcpy /* if regions overlap */
+
+ addi r4,r4,-4
+ addi r6,r3,-4
+ neg r0,r3
+ andi. r0,r0,CACHELINE_MASK /* # bytes to start of cache line */
+ beq 58f
+
+ cmplw 0,r5,r0 /* is this more than total to do? */
+ blt 63f /* if not much to do */
+ andi. r8,r0,3 /* get it word-aligned first */
+ subf r5,r0,r5
+ mtctr r8
+ beq+ 61f
+70: lbz r9,4(r4) /* do some bytes */
+ stb r9,4(r6)
+ addi r4,r4,1
+ addi r6,r6,1
+ bdnz 70b
+61: srwi. r0,r0,2
+ mtctr r0
+ beq 58f
+72: lwzu r9,4(r4) /* do some words */
+ stwu r9,4(r6)
+ bdnz 72b
+
+58: srwi. r0,r5,LG_CACHELINE_BYTES /* # complete cachelines */
+ clrlwi r5,r5,32-LG_CACHELINE_BYTES
+ li r11,4
+ mtctr r0
+ beq 63f
+53:
+#if !defined(CONFIG_8xx)
+ dcbz r11,r6
+#endif
+ COPY_16_BYTES
+#if L1_CACHE_BYTES >= 32
+ COPY_16_BYTES
+#if L1_CACHE_BYTES >= 64
+ COPY_16_BYTES
+ COPY_16_BYTES
+#if L1_CACHE_BYTES >= 128
+ COPY_16_BYTES
+ COPY_16_BYTES
+ COPY_16_BYTES
+ COPY_16_BYTES
+#endif
+#endif
+#endif
+ bdnz 53b
+
+63: srwi. r0,r5,2
+ mtctr r0
+ beq 64f
+30: lwzu r0,4(r4)
+ stwu r0,4(r6)
+ bdnz 30b
+
+64: andi. r0,r5,3
+ mtctr r0
+ beq+ 65f
+40: lbz r0,4(r4)
+ stb r0,4(r6)
+ addi r4,r4,1
+ addi r6,r6,1
+ bdnz 40b
+65: blr
+
+_GLOBAL(memmove)
+ cmplw 0,r3,r4
+ bgt backwards_memcpy
+ /* fall through */
+
+_GLOBAL(memcpy)
+ srwi. r7,r5,3
+ addi r6,r3,-4
+ addi r4,r4,-4
+ beq 2f /* if less than 8 bytes to do */
+ andi. r0,r6,3 /* get dest word aligned */
+ mtctr r7
+ bne 5f
+1: lwz r7,4(r4)
+ lwzu r8,8(r4)
+ stw r7,4(r6)
+ stwu r8,8(r6)
+ bdnz 1b
+ andi. r5,r5,7
+2: cmplwi 0,r5,4
+ blt 3f
+ lwzu r0,4(r4)
+ addi r5,r5,-4
+ stwu r0,4(r6)
+3: cmpwi 0,r5,0
+ beqlr
+ mtctr r5
+ addi r4,r4,3
+ addi r6,r6,3
+4: lbzu r0,1(r4)
+ stbu r0,1(r6)
+ bdnz 4b
+ blr
+5: subfic r0,r0,4
+ mtctr r0
+6: lbz r7,4(r4)
+ addi r4,r4,1
+ stb r7,4(r6)
+ addi r6,r6,1
+ bdnz 6b
+ subf r5,r0,r5
+ rlwinm. r7,r5,32-3,3,31
+ beq 2b
+ mtctr r7
+ b 1b
+
+_GLOBAL(backwards_memcpy)
+ rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */
+ add r6,r3,r5
+ add r4,r4,r5
+ beq 2f
+ andi. r0,r6,3
+ mtctr r7
+ bne 5f
+1: lwz r7,-4(r4)
+ lwzu r8,-8(r4)
+ stw r7,-4(r6)
+ stwu r8,-8(r6)
+ bdnz 1b
+ andi. r5,r5,7
+2: cmplwi 0,r5,4
+ blt 3f
+ lwzu r0,-4(r4)
+ subi r5,r5,4
+ stwu r0,-4(r6)
+3: cmpwi 0,r5,0
+ beqlr
+ mtctr r5
+4: lbzu r0,-1(r4)
+ stbu r0,-1(r6)
+ bdnz 4b
+ blr
+5: mtctr r0
+6: lbzu r7,-1(r4)
+ stbu r7,-1(r6)
+ bdnz 6b
+ subf r5,r0,r5
+ rlwinm. r7,r5,32-3,3,31
+ beq 2b
+ mtctr r7
+ b 1b
+
+_GLOBAL(__copy_tofrom_user)
+ addi r4,r4,-4
+ addi r6,r3,-4
+ neg r0,r3
+ andi. r0,r0,CACHELINE_MASK /* # bytes to start of cache line */
+ beq 58f
+
+ cmplw 0,r5,r0 /* is this more than total to do? */
+ blt 63f /* if not much to do */
+ andi. r8,r0,3 /* get it word-aligned first */
+ mtctr r8
+ beq+ 61f
+70: lbz r9,4(r4) /* do some bytes */
+71: stb r9,4(r6)
+ addi r4,r4,1
+ addi r6,r6,1
+ bdnz 70b
+61: subf r5,r0,r5
+ srwi. r0,r0,2
+ mtctr r0
+ beq 58f
+72: lwzu r9,4(r4) /* do some words */
+73: stwu r9,4(r6)
+ bdnz 72b
+
+ .section __ex_table,"a"
+ .align 2
+ .long 70b,100f
+ .long 71b,101f
+ .long 72b,102f
+ .long 73b,103f
+ .text
+
+58: srwi. r0,r5,LG_CACHELINE_BYTES /* # complete cachelines */
+ clrlwi r5,r5,32-LG_CACHELINE_BYTES
+ li r11,4
+ beq 63f
+
+#ifdef CONFIG_8xx
+ /* Don't use prefetch on 8xx */
+ mtctr r0
+ li r0,0
+53: COPY_16_BYTES_WITHEX(0)
+ bdnz 53b
+
+#else /* not CONFIG_8xx */
+ /* Here we decide how far ahead to prefetch the source */
+ li r3,4
+ cmpwi r0,1
+ li r7,0
+ ble 114f
+ li r7,1
+#if MAX_COPY_PREFETCH > 1
+ /* Heuristically, for large transfers we prefetch
+ MAX_COPY_PREFETCH cachelines ahead. For small transfers
+ we prefetch 1 cacheline ahead. */
+ cmpwi r0,MAX_COPY_PREFETCH
+ ble 112f
+ li r7,MAX_COPY_PREFETCH
+112: mtctr r7
+111: dcbt r3,r4
+ addi r3,r3,CACHELINE_BYTES
+ bdnz 111b
+#else
+ dcbt r3,r4
+ addi r3,r3,CACHELINE_BYTES
+#endif /* MAX_COPY_PREFETCH > 1 */
+
+114: subf r8,r7,r0
+ mr r0,r7
+ mtctr r8
+
+53: dcbt r3,r4
+54: dcbz r11,r6
+ .section __ex_table,"a"
+ .align 2
+ .long 54b,105f
+ .text
+/* the main body of the cacheline loop */
+ COPY_16_BYTES_WITHEX(0)
+#if L1_CACHE_BYTES >= 32
+ COPY_16_BYTES_WITHEX(1)
+#if L1_CACHE_BYTES >= 64
+ COPY_16_BYTES_WITHEX(2)
+ COPY_16_BYTES_WITHEX(3)
+#if L1_CACHE_BYTES >= 128
+ COPY_16_BYTES_WITHEX(4)
+ COPY_16_BYTES_WITHEX(5)
+ COPY_16_BYTES_WITHEX(6)
+ COPY_16_BYTES_WITHEX(7)
+#endif
+#endif
+#endif
+ bdnz 53b
+ cmpwi r0,0
+ li r3,4
+ li r7,0
+ bne 114b
+#endif /* CONFIG_8xx */
+
+63: srwi. r0,r5,2
+ mtctr r0
+ beq 64f
+30: lwzu r0,4(r4)
+31: stwu r0,4(r6)
+ bdnz 30b
+
+64: andi. r0,r5,3
+ mtctr r0
+ beq+ 65f
+40: lbz r0,4(r4)
+41: stb r0,4(r6)
+ addi r4,r4,1
+ addi r6,r6,1
+ bdnz 40b
+65: li r3,0
+ blr
+
+/* read fault, initial single-byte copy */
+100: li r9,0
+ b 90f
+/* write fault, initial single-byte copy */
+101: li r9,1
+90: subf r5,r8,r5
+ li r3,0
+ b 99f
+/* read fault, initial word copy */
+102: li r9,0
+ b 91f
+/* write fault, initial word copy */
+103: li r9,1
+91: li r3,2
+ b 99f
+
+/*
+ * this stuff handles faults in the cacheline loop and branches to either
+ * 104f (if in read part) or 105f (if in write part), after updating r5
+ */
+ COPY_16_BYTES_EXCODE(0)
+#if L1_CACHE_BYTES >= 32
+ COPY_16_BYTES_EXCODE(1)
+#if L1_CACHE_BYTES >= 64
+ COPY_16_BYTES_EXCODE(2)
+ COPY_16_BYTES_EXCODE(3)
+#if L1_CACHE_BYTES >= 128
+ COPY_16_BYTES_EXCODE(4)
+ COPY_16_BYTES_EXCODE(5)
+ COPY_16_BYTES_EXCODE(6)
+ COPY_16_BYTES_EXCODE(7)
+#endif
+#endif
+#endif
+
+/* read fault in cacheline loop */
+104: li r9,0
+ b 92f
+/* fault on dcbz (effectively a write fault) */
+/* or write fault in cacheline loop */
+105: li r9,1
+92: li r3,LG_CACHELINE_BYTES
+ mfctr r8
+ add r0,r0,r8
+ b 106f
+/* read fault in final word loop */
+108: li r9,0
+ b 93f
+/* write fault in final word loop */
+109: li r9,1
+93: andi. r5,r5,3
+ li r3,2
+ b 99f
+/* read fault in final byte loop */
+110: li r9,0
+ b 94f
+/* write fault in final byte loop */
+111: li r9,1
+94: li r5,0
+ li r3,0
+/*
+ * At this stage the number of bytes not copied is
+ * r5 + (ctr << r3), and r9 is 0 for read or 1 for write.
+ */
+99: mfctr r0
+106: slw r3,r0,r3
+ add. r3,r3,r5
+ beq 120f /* shouldn't happen */
+ cmpwi 0,r9,0
+ bne 120f
+/* for a read fault, first try to continue the copy one byte at a time */
+ mtctr r3
+130: lbz r0,4(r4)
+131: stb r0,4(r6)
+ addi r4,r4,1
+ addi r6,r6,1
+ bdnz 130b
+/* then clear out the destination: r3 bytes starting at 4(r6) */
+132: mfctr r3
+ srwi. r0,r3,2
+ li r9,0
+ mtctr r0
+ beq 113f
+112: stwu r9,4(r6)
+ bdnz 112b
+113: andi. r0,r3,3
+ mtctr r0
+ beq 120f
+114: stb r9,4(r6)
+ addi r6,r6,1
+ bdnz 114b
+120: blr
+
+ .section __ex_table,"a"
+ .align 2
+ .long 30b,108b
+ .long 31b,109b
+ .long 40b,110b
+ .long 41b,111b
+ .long 130b,132b
+ .long 131b,120b
+ .long 112b,120b
+ .long 114b,120b
+ .text
diff --git a/arch/ppc64/lib/copypage.S b/arch/powerpc/lib/copypage_64.S
index 733d61618bbf..733d61618bbf 100644
--- a/arch/ppc64/lib/copypage.S
+++ b/arch/powerpc/lib/copypage_64.S
diff --git a/arch/ppc64/lib/copyuser.S b/arch/powerpc/lib/copyuser_64.S
index a0b3fbbd6fb1..a0b3fbbd6fb1 100644
--- a/arch/ppc64/lib/copyuser.S
+++ b/arch/powerpc/lib/copyuser_64.S
diff --git a/arch/powerpc/lib/div64.S b/arch/powerpc/lib/div64.S
new file mode 100644
index 000000000000..83d9832fd919
--- /dev/null
+++ b/arch/powerpc/lib/div64.S
@@ -0,0 +1,59 @@
+/*
+ * Divide a 64-bit unsigned number by a 32-bit unsigned number.
+ * This routine assumes that the top 32 bits of the dividend are
+ * non-zero to start with.
+ * On entry, r3 points to the dividend, which get overwritten with
+ * the 64-bit quotient, and r4 contains the divisor.
+ * On exit, r3 contains the remainder.
+ *
+ * Copyright (C) 2002 Paul Mackerras, IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <asm/ppc_asm.h>
+#include <asm/processor.h>
+
+_GLOBAL(__div64_32)
+ lwz r5,0(r3) # get the dividend into r5/r6
+ lwz r6,4(r3)
+ cmplw r5,r4
+ li r7,0
+ li r8,0
+ blt 1f
+ divwu r7,r5,r4 # if dividend.hi >= divisor,
+ mullw r0,r7,r4 # quotient.hi = dividend.hi / divisor
+ subf. r5,r0,r5 # dividend.hi %= divisor
+ beq 3f
+1: mr r11,r5 # here dividend.hi != 0
+ andis. r0,r5,0xc000
+ bne 2f
+ cntlzw r0,r5 # we are shifting the dividend right
+ li r10,-1 # to make it < 2^32, and shifting
+ srw r10,r10,r0 # the divisor right the same amount,
+ addc r9,r4,r10 # rounding up (so the estimate cannot
+ andc r11,r6,r10 # ever be too large, only too small)
+ andc r9,r9,r10
+ addze r9,r9
+ or r11,r5,r11
+ rotlw r9,r9,r0
+ rotlw r11,r11,r0
+ divwu r11,r11,r9 # then we divide the shifted quantities
+2: mullw r10,r11,r4 # to get an estimate of the quotient,
+ mulhwu r9,r11,r4 # multiply the estimate by the divisor,
+ subfc r6,r10,r6 # take the product from the divisor,
+ add r8,r8,r11 # and add the estimate to the accumulated
+ subfe. r5,r9,r5 # quotient
+ bne 1b
+3: cmplw r6,r4
+ blt 4f
+ divwu r0,r6,r4 # perform the remaining 32-bit division
+ mullw r10,r0,r4 # and get the remainder
+ add r8,r8,r0
+ subf r6,r10,r6
+4: stw r7,0(r3) # return the quotient in *r3
+ stw r8,4(r3)
+ mr r3,r6 # return the remainder in r3
+ blr
diff --git a/arch/ppc64/lib/e2a.c b/arch/powerpc/lib/e2a.c
index d2b834887920..d2b834887920 100644
--- a/arch/ppc64/lib/e2a.c
+++ b/arch/powerpc/lib/e2a.c
diff --git a/arch/ppc64/lib/locks.c b/arch/powerpc/lib/locks.c
index 033643ab69e0..3794715b2972 100644
--- a/arch/ppc64/lib/locks.c
+++ b/arch/powerpc/lib/locks.c
@@ -17,11 +17,12 @@
#include <linux/spinlock.h>
#include <linux/module.h>
#include <linux/stringify.h>
-#include <asm/hvcall.h>
-#include <asm/iSeries/HvCall.h>
+#include <linux/smp.h>
/* waiting for a spinlock... */
#if defined(CONFIG_PPC_SPLPAR) || defined(CONFIG_PPC_ISERIES)
+#include <asm/hvcall.h>
+#include <asm/iSeries/HvCall.h>
void __spin_yield(raw_spinlock_t *lock)
{
diff --git a/arch/powerpc/lib/mem_64.S b/arch/powerpc/lib/mem_64.S
new file mode 100644
index 000000000000..68df20283ff5
--- /dev/null
+++ b/arch/powerpc/lib/mem_64.S
@@ -0,0 +1,119 @@
+/*
+ * String handling functions for PowerPC.
+ *
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ * This program is free software; you can redistribute 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/processor.h>
+#include <asm/errno.h>
+#include <asm/ppc_asm.h>
+
+_GLOBAL(memset)
+ neg r0,r3
+ rlwimi r4,r4,8,16,23
+ andi. r0,r0,7 /* # bytes to be 8-byte aligned */
+ rlwimi r4,r4,16,0,15
+ cmplw cr1,r5,r0 /* do we get that far? */
+ rldimi r4,r4,32,0
+ mtcrf 1,r0
+ mr r6,r3
+ blt cr1,8f
+ beq+ 3f /* if already 8-byte aligned */
+ subf r5,r0,r5
+ bf 31,1f
+ stb r4,0(r6)
+ addi r6,r6,1
+1: bf 30,2f
+ sth r4,0(r6)
+ addi r6,r6,2
+2: bf 29,3f
+ stw r4,0(r6)
+ addi r6,r6,4
+3: srdi. r0,r5,6
+ clrldi r5,r5,58
+ mtctr r0
+ beq 5f
+4: std r4,0(r6)
+ std r4,8(r6)
+ std r4,16(r6)
+ std r4,24(r6)
+ std r4,32(r6)
+ std r4,40(r6)
+ std r4,48(r6)
+ std r4,56(r6)
+ addi r6,r6,64
+ bdnz 4b
+5: srwi. r0,r5,3
+ clrlwi r5,r5,29
+ mtcrf 1,r0
+ beq 8f
+ bf 29,6f
+ std r4,0(r6)
+ std r4,8(r6)
+ std r4,16(r6)
+ std r4,24(r6)
+ addi r6,r6,32
+6: bf 30,7f
+ std r4,0(r6)
+ std r4,8(r6)
+ addi r6,r6,16
+7: bf 31,8f
+ std r4,0(r6)
+ addi r6,r6,8
+8: cmpwi r5,0
+ mtcrf 1,r5
+ beqlr+
+ bf 29,9f
+ stw r4,0(r6)
+ addi r6,r6,4
+9: bf 30,10f
+ sth r4,0(r6)
+ addi r6,r6,2
+10: bflr 31
+ stb r4,0(r6)
+ blr
+
+_GLOBAL(memmove)
+ cmplw 0,r3,r4
+ bgt .backwards_memcpy
+ b .memcpy
+
+_GLOBAL(backwards_memcpy)
+ rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */
+ add r6,r3,r5
+ add r4,r4,r5
+ beq 2f
+ andi. r0,r6,3
+ mtctr r7
+ bne 5f
+1: lwz r7,-4(r4)
+ lwzu r8,-8(r4)
+ stw r7,-4(r6)
+ stwu r8,-8(r6)
+ bdnz 1b
+ andi. r5,r5,7
+2: cmplwi 0,r5,4
+ blt 3f
+ lwzu r0,-4(r4)
+ subi r5,r5,4
+ stwu r0,-4(r6)
+3: cmpwi 0,r5,0
+ beqlr
+ mtctr r5
+4: lbzu r0,-1(r4)
+ stbu r0,-1(r6)
+ bdnz 4b
+ blr
+5: mtctr r0
+6: lbzu r7,-1(r4)
+ stbu r7,-1(r6)
+ bdnz 6b
+ subf r5,r0,r5
+ rlwinm. r7,r5,32-3,3,31
+ beq 2b
+ mtctr r7
+ b 1b
diff --git a/arch/ppc64/lib/memcpy.S b/arch/powerpc/lib/memcpy_64.S
index 9ccacdf5bcb9..9ccacdf5bcb9 100644
--- a/arch/ppc64/lib/memcpy.S
+++ b/arch/powerpc/lib/memcpy_64.S
diff --git a/arch/powerpc/lib/rheap.c b/arch/powerpc/lib/rheap.c
new file mode 100644
index 000000000000..42c5de2c898f
--- /dev/null
+++ b/arch/powerpc/lib/rheap.c
@@ -0,0 +1,693 @@
+/*
+ * arch/ppc/syslib/rheap.c
+ *
+ * A Remote Heap. Remote means that we don't touch the memory that the
+ * heap points to. Normal heap implementations use the memory they manage
+ * to place their list. We cannot do that because the memory we manage may
+ * have special properties, for example it is uncachable or of different
+ * endianess.
+ *
+ * Author: Pantelis Antoniou <panto@intracom.gr>
+ *
+ * 2004 (c) INTRACOM S.A. Greece. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+
+#include <asm/rheap.h>
+
+/*
+ * Fixup a list_head, needed when copying lists. If the pointers fall
+ * between s and e, apply the delta. This assumes that
+ * sizeof(struct list_head *) == sizeof(unsigned long *).
+ */
+static inline void fixup(unsigned long s, unsigned long e, int d,
+ struct list_head *l)
+{
+ unsigned long *pp;
+
+ pp = (unsigned long *)&l->next;
+ if (*pp >= s && *pp < e)
+ *pp += d;
+
+ pp = (unsigned long *)&l->prev;
+ if (*pp >= s && *pp < e)
+ *pp += d;
+}
+
+/* Grow the allocated blocks */
+static int grow(rh_info_t * info, int max_blocks)
+{
+ rh_block_t *block, *blk;
+ int i, new_blocks;
+ int delta;
+ unsigned long blks, blke;
+
+ if (max_blocks <= info->max_blocks)
+ return -EINVAL;
+
+ new_blocks = max_blocks - info->max_blocks;
+
+ block = kmalloc(sizeof(rh_block_t) * max_blocks, GFP_KERNEL);
+ if (block == NULL)
+ return -ENOMEM;
+
+ if (info->max_blocks > 0) {
+
+ /* copy old block area */
+ memcpy(block, info->block,
+ sizeof(rh_block_t) * info->max_blocks);
+
+ delta = (char *)block - (char *)info->block;
+
+ /* and fixup list pointers */
+ blks = (unsigned long)info->block;
+ blke = (unsigned long)(info->block + info->max_blocks);
+
+ for (i = 0, blk = block; i < info->max_blocks; i++, blk++)
+ fixup(blks, blke, delta, &blk->list);
+
+ fixup(blks, blke, delta, &info->empty_list);
+ fixup(blks, blke, delta, &info->free_list);
+ fixup(blks, blke, delta, &info->taken_list);
+
+ /* free the old allocated memory */
+ if ((info->flags & RHIF_STATIC_BLOCK) == 0)
+ kfree(info->block);
+ }
+
+ info->block = block;
+ info->empty_slots += new_blocks;
+ info->max_blocks = max_blocks;
+ info->flags &= ~RHIF_STATIC_BLOCK;
+
+ /* add all new blocks to the free list */
+ for (i = 0, blk = block + info->max_blocks; i < new_blocks; i++, blk++)
+ list_add(&blk->list, &info->empty_list);
+
+ return 0;
+}
+
+/*
+ * Assure at least the required amount of empty slots. If this function
+ * causes a grow in the block area then all pointers kept to the block
+ * area are invalid!
+ */
+static int assure_empty(rh_info_t * info, int slots)
+{
+ int max_blocks;
+
+ /* This function is not meant to be used to grow uncontrollably */
+ if (slots >= 4)
+ return -EINVAL;
+
+ /* Enough space */
+ if (info->empty_slots >= slots)
+ return 0;
+
+ /* Next 16 sized block */
+ max_blocks = ((info->max_blocks + slots) + 15) & ~15;
+
+ return grow(info, max_blocks);
+}
+
+static rh_block_t *get_slot(rh_info_t * info)
+{
+ rh_block_t *blk;
+
+ /* If no more free slots, and failure to extend. */
+ /* XXX: You should have called assure_empty before */
+ if (info->empty_slots == 0) {
+ printk(KERN_ERR "rh: out of slots; crash is imminent.\n");
+ return NULL;
+ }
+
+ /* Get empty slot to use */
+ blk = list_entry(info->empty_list.next, rh_block_t, list);
+ list_del_init(&blk->list);
+ info->empty_slots--;
+
+ /* Initialize */
+ blk->start = NULL;
+ blk->size = 0;
+ blk->owner = NULL;
+
+ return blk;
+}
+
+static inline void release_slot(rh_info_t * info, rh_block_t * blk)
+{
+ list_add(&blk->list, &info->empty_list);
+ info->empty_slots++;
+}
+
+static void attach_free_block(rh_info_t * info, rh_block_t * blkn)
+{
+ rh_block_t *blk;
+ rh_block_t *before;
+ rh_block_t *after;
+ rh_block_t *next;
+ int size;
+ unsigned long s, e, bs, be;
+ struct list_head *l;
+
+ /* We assume that they are aligned properly */
+ size = blkn->size;
+ s = (unsigned long)blkn->start;
+ e = s + size;
+
+ /* Find the blocks immediately before and after the given one
+ * (if any) */
+ before = NULL;
+ after = NULL;
+ next = NULL;
+
+ list_for_each(l, &info->free_list) {
+ blk = list_entry(l, rh_block_t, list);
+
+ bs = (unsigned long)blk->start;
+ be = bs + blk->size;
+
+ if (next == NULL && s >= bs)
+ next = blk;
+
+ if (be == s)
+ before = blk;
+
+ if (e == bs)
+ after = blk;
+
+ /* If both are not null, break now */
+ if (before != NULL && after != NULL)
+ break;
+ }
+
+ /* Now check if they are really adjacent */
+ if (before != NULL && s != (unsigned long)before->start + before->size)
+ before = NULL;
+
+ if (after != NULL && e != (unsigned long)after->start)
+ after = NULL;
+
+ /* No coalescing; list insert and return */
+ if (before == NULL && after == NULL) {
+
+ if (next != NULL)
+ list_add(&blkn->list, &next->list);
+ else
+ list_add(&blkn->list, &info->free_list);
+
+ return;
+ }
+
+ /* We don't need it anymore */
+ release_slot(info, blkn);
+
+ /* Grow the before block */
+ if (before != NULL && after == NULL) {
+ before->size += size;
+ return;
+ }
+
+ /* Grow the after block backwards */
+ if (before == NULL && after != NULL) {
+ after->start = (int8_t *)after->start - size;
+ after->size += size;
+ return;
+ }
+
+ /* Grow the before block, and release the after block */
+ before->size += size + after->size;
+ list_del(&after->list);
+ release_slot(info, after);
+}
+
+static void attach_taken_block(rh_info_t * info, rh_block_t * blkn)
+{
+ rh_block_t *blk;
+ struct list_head *l;
+
+ /* Find the block immediately before the given one (if any) */
+ list_for_each(l, &info->taken_list) {
+ blk = list_entry(l, rh_block_t, list);
+ if (blk->start > blkn->start) {
+ list_add_tail(&blkn->list, &blk->list);
+ return;
+ }
+ }
+
+ list_add_tail(&blkn->list, &info->taken_list);
+}
+
+/*
+ * Create a remote heap dynamically. Note that no memory for the blocks
+ * are allocated. It will upon the first allocation
+ */
+rh_info_t *rh_create(unsigned int alignment)
+{
+ rh_info_t *info;
+
+ /* Alignment must be a power of two */
+ if ((alignment & (alignment - 1)) != 0)
+ return ERR_PTR(-EINVAL);
+
+ info = kmalloc(sizeof(*info), GFP_KERNEL);
+ if (info == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ info->alignment = alignment;
+
+ /* Initially everything as empty */
+ info->block = NULL;
+ info->max_blocks = 0;
+ info->empty_slots = 0;
+ info->flags = 0;
+
+ INIT_LIST_HEAD(&info->empty_list);
+ INIT_LIST_HEAD(&info->free_list);
+ INIT_LIST_HEAD(&info->taken_list);
+
+ return info;
+}
+
+/*
+ * Destroy a dynamically created remote heap. Deallocate only if the areas
+ * are not static
+ */
+void rh_destroy(rh_info_t * info)
+{
+ if ((info->flags & RHIF_STATIC_BLOCK) == 0 && info->block != NULL)
+ kfree(info->block);
+
+ if ((info->flags & RHIF_STATIC_INFO) == 0)
+ kfree(info);
+}
+
+/*
+ * Initialize in place a remote heap info block. This is needed to support
+ * operation very early in the startup of the kernel, when it is not yet safe
+ * to call kmalloc.
+ */
+void rh_init(rh_info_t * info, unsigned int alignment, int max_blocks,
+ rh_block_t * block)
+{
+ int i;
+ rh_block_t *blk;
+
+ /* Alignment must be a power of two */
+ if ((alignment & (alignment - 1)) != 0)
+ return;
+
+ info->alignment = alignment;
+
+ /* Initially everything as empty */
+ info->block = block;
+ info->max_blocks = max_blocks;
+ info->empty_slots = max_blocks;
+ info->flags = RHIF_STATIC_INFO | RHIF_STATIC_BLOCK;
+
+ INIT_LIST_HEAD(&info->empty_list);
+ INIT_LIST_HEAD(&info->free_list);
+ INIT_LIST_HEAD(&info->taken_list);
+
+ /* Add all new blocks to the free list */
+ for (i = 0, blk = block; i < max_blocks; i++, blk++)
+ list_add(&blk->list, &info->empty_list);
+}
+
+/* Attach a free memory region, coalesces regions if adjuscent */
+int rh_attach_region(rh_info_t * info, void *start, int size)
+{
+ rh_block_t *blk;
+ unsigned long s, e, m;
+ int r;
+
+ /* The region must be aligned */
+ s = (unsigned long)start;
+ e = s + size;
+ m = info->alignment - 1;
+
+ /* Round start up */
+ s = (s + m) & ~m;
+
+ /* Round end down */
+ e = e & ~m;
+
+ /* Take final values */
+ start = (void *)s;
+ size = (int)(e - s);
+
+ /* Grow the blocks, if needed */
+ r = assure_empty(info, 1);
+ if (r < 0)
+ return r;
+
+ blk = get_slot(info);
+ blk->start = start;
+ blk->size = size;
+ blk->owner = NULL;
+
+ attach_free_block(info, blk);
+
+ return 0;
+}
+
+/* Detatch given address range, splits free block if needed. */
+void *rh_detach_region(rh_info_t * info, void *start, int size)
+{
+ struct list_head *l;
+ rh_block_t *blk, *newblk;
+ unsigned long s, e, m, bs, be;
+
+ /* Validate size */
+ if (size <= 0)
+ return ERR_PTR(-EINVAL);
+
+ /* The region must be aligned */
+ s = (unsigned long)start;
+ e = s + size;
+ m = info->alignment - 1;
+
+ /* Round start up */
+ s = (s + m) & ~m;
+
+ /* Round end down */
+ e = e & ~m;
+
+ if (assure_empty(info, 1) < 0)
+ return ERR_PTR(-ENOMEM);
+
+ blk = NULL;
+ list_for_each(l, &info->free_list) {
+ blk = list_entry(l, rh_block_t, list);
+ /* The range must lie entirely inside one free block */
+ bs = (unsigned long)blk->start;
+ be = (unsigned long)blk->start + blk->size;
+ if (s >= bs && e <= be)
+ break;
+ blk = NULL;
+ }
+
+ if (blk == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ /* Perfect fit */
+ if (bs == s && be == e) {
+ /* Delete from free list, release slot */
+ list_del(&blk->list);
+ release_slot(info, blk);
+ return (void *)s;
+ }
+
+ /* blk still in free list, with updated start and/or size */
+ if (bs == s || be == e) {
+ if (bs == s)
+ blk->start = (int8_t *)blk->start + size;
+ blk->size -= size;
+
+ } else {
+ /* The front free fragment */
+ blk->size = s - bs;
+
+ /* the back free fragment */
+ newblk = get_slot(info);
+ newblk->start = (void *)e;
+ newblk->size = be - e;
+
+ list_add(&newblk->list, &blk->list);
+ }
+
+ return (void *)s;
+}
+
+void *rh_alloc(rh_info_t * info, int size, const char *owner)
+{
+ struct list_head *l;
+ rh_block_t *blk;
+ rh_block_t *newblk;
+ void *start;
+
+ /* Validate size */
+ if (size <= 0)
+ return ERR_PTR(-EINVAL);
+
+ /* Align to configured alignment */
+ size = (size + (info->alignment - 1)) & ~(info->alignment - 1);
+
+ if (assure_empty(info, 1) < 0)
+ return ERR_PTR(-ENOMEM);
+
+ blk = NULL;
+ list_for_each(l, &info->free_list) {
+ blk = list_entry(l, rh_block_t, list);
+ if (size <= blk->size)
+ break;
+ blk = NULL;
+ }
+
+ if (blk == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ /* Just fits */
+ if (blk->size == size) {
+ /* Move from free list to taken list */
+ list_del(&blk->list);
+ blk->owner = owner;
+ start = blk->start;
+
+ attach_taken_block(info, blk);
+
+ return start;
+ }
+
+ newblk = get_slot(info);
+ newblk->start = blk->start;
+ newblk->size = size;
+ newblk->owner = owner;
+
+ /* blk still in free list, with updated start, size */
+ blk->start = (int8_t *)blk->start + size;
+ blk->size -= size;
+
+ start = newblk->start;
+
+ attach_taken_block(info, newblk);
+
+ return start;
+}
+
+/* allocate at precisely the given address */
+void *rh_alloc_fixed(rh_info_t * info, void *start, int size, const char *owner)
+{
+ struct list_head *l;
+ rh_block_t *blk, *newblk1, *newblk2;
+ unsigned long s, e, m, bs, be;
+
+ /* Validate size */
+ if (size <= 0)
+ return ERR_PTR(-EINVAL);
+
+ /* The region must be aligned */
+ s = (unsigned long)start;
+ e = s + size;
+ m = info->alignment - 1;
+
+ /* Round start up */
+ s = (s + m) & ~m;
+
+ /* Round end down */
+ e = e & ~m;
+
+ if (assure_empty(info, 2) < 0)
+ return ERR_PTR(-ENOMEM);
+
+ blk = NULL;
+ list_for_each(l, &info->free_list) {
+ blk = list_entry(l, rh_block_t, list);
+ /* The range must lie entirely inside one free block */
+ bs = (unsigned long)blk->start;
+ be = (unsigned long)blk->start + blk->size;
+ if (s >= bs && e <= be)
+ break;
+ }
+
+ if (blk == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ /* Perfect fit */
+ if (bs == s && be == e) {
+ /* Move from free list to taken list */
+ list_del(&blk->list);
+ blk->owner = owner;
+
+ start = blk->start;
+ attach_taken_block(info, blk);
+
+ return start;
+
+ }
+
+ /* blk still in free list, with updated start and/or size */
+ if (bs == s || be == e) {
+ if (bs == s)
+ blk->start = (int8_t *)blk->start + size;
+ blk->size -= size;
+
+ } else {
+ /* The front free fragment */
+ blk->size = s - bs;
+
+ /* The back free fragment */
+ newblk2 = get_slot(info);
+ newblk2->start = (void *)e;
+ newblk2->size = be - e;
+
+ list_add(&newblk2->list, &blk->list);
+ }
+
+ newblk1 = get_slot(info);
+ newblk1->start = (void *)s;
+ newblk1->size = e - s;
+ newblk1->owner = owner;
+
+ start = newblk1->start;
+ attach_taken_block(info, newblk1);
+
+ return start;
+}
+
+int rh_free(rh_info_t * info, void *start)
+{
+ rh_block_t *blk, *blk2;
+ struct list_head *l;
+ int size;
+
+ /* Linear search for block */
+ blk = NULL;
+ list_for_each(l, &info->taken_list) {
+ blk2 = list_entry(l, rh_block_t, list);
+ if (start < blk2->start)
+ break;
+ blk = blk2;
+ }
+
+ if (blk == NULL || start > (blk->start + blk->size))
+ return -EINVAL;
+
+ /* Remove from taken list */
+ list_del(&blk->list);
+
+ /* Get size of freed block */
+ size = blk->size;
+ attach_free_block(info, blk);
+
+ return size;
+}
+
+int rh_get_stats(rh_info_t * info, int what, int max_stats, rh_stats_t * stats)
+{
+ rh_block_t *blk;
+ struct list_head *l;
+ struct list_head *h;
+ int nr;
+
+ switch (what) {
+
+ case RHGS_FREE:
+ h = &info->free_list;
+ break;
+
+ case RHGS_TAKEN:
+ h = &info->taken_list;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ /* Linear search for block */
+ nr = 0;
+ list_for_each(l, h) {
+ blk = list_entry(l, rh_block_t, list);
+ if (stats != NULL && nr < max_stats) {
+ stats->start = blk->start;
+ stats->size = blk->size;
+ stats->owner = blk->owner;
+ stats++;
+ }
+ nr++;
+ }
+
+ return nr;
+}
+
+int rh_set_owner(rh_info_t * info, void *start, const char *owner)
+{
+ rh_block_t *blk, *blk2;
+ struct list_head *l;
+ int size;
+
+ /* Linear search for block */
+ blk = NULL;
+ list_for_each(l, &info->taken_list) {
+ blk2 = list_entry(l, rh_block_t, list);
+ if (start < blk2->start)
+ break;
+ blk = blk2;
+ }
+
+ if (blk == NULL || start > (blk->start + blk->size))
+ return -EINVAL;
+
+ blk->owner = owner;
+ size = blk->size;
+
+ return size;
+}
+
+void rh_dump(rh_info_t * info)
+{
+ static rh_stats_t st[32]; /* XXX maximum 32 blocks */
+ int maxnr;
+ int i, nr;
+
+ maxnr = sizeof(st) / sizeof(st[0]);
+
+ printk(KERN_INFO
+ "info @0x%p (%d slots empty / %d max)\n",
+ info, info->empty_slots, info->max_blocks);
+
+ printk(KERN_INFO " Free:\n");
+ nr = rh_get_stats(info, RHGS_FREE, maxnr, st);
+ if (nr > maxnr)
+ nr = maxnr;
+ for (i = 0; i < nr; i++)
+ printk(KERN_INFO
+ " 0x%p-0x%p (%u)\n",
+ st[i].start, (int8_t *) st[i].start + st[i].size,
+ st[i].size);
+ printk(KERN_INFO "\n");
+
+ printk(KERN_INFO " Taken:\n");
+ nr = rh_get_stats(info, RHGS_TAKEN, maxnr, st);
+ if (nr > maxnr)
+ nr = maxnr;
+ for (i = 0; i < nr; i++)
+ printk(KERN_INFO
+ " 0x%p-0x%p (%u) %s\n",
+ st[i].start, (int8_t *) st[i].start + st[i].size,
+ st[i].size, st[i].owner != NULL ? st[i].owner : "");
+ printk(KERN_INFO "\n");
+}
+
+void rh_dump_blk(rh_info_t * info, rh_block_t * blk)
+{
+ printk(KERN_INFO
+ "blk @0x%p: 0x%p-0x%p (%u)\n",
+ blk, blk->start, (int8_t *) blk->start + blk->size, blk->size);
+}
diff --git a/arch/ppc64/lib/sstep.c b/arch/powerpc/lib/sstep.c
index e79123d1485c..666c2aa55016 100644
--- a/arch/ppc64/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -10,13 +10,18 @@
*/
#include <linux/kernel.h>
#include <linux/ptrace.h>
+#include <linux/config.h>
#include <asm/sstep.h>
#include <asm/processor.h>
extern char system_call_common[];
+#ifdef CONFIG_PPC64
/* Bits in SRR1 that are copied from MSR */
#define MSR_MASK 0xffffffff87c0ffff
+#else
+#define MSR_MASK 0x87c0ffff
+#endif
/*
* Determine whether a conditional branch instruction would branch.
@@ -66,6 +71,7 @@ int emulate_step(struct pt_regs *regs, unsigned int instr)
if (branch_taken(instr, regs))
regs->nip = imm;
return 1;
+#ifdef CONFIG_PPC64
case 17: /* sc */
/*
* N.B. this uses knowledge about how the syscall
@@ -79,6 +85,7 @@ int emulate_step(struct pt_regs *regs, unsigned int instr)
regs->nip = (unsigned long) &system_call_common;
regs->msr = MSR_KERNEL;
return 1;
+#endif
case 18: /* b */
imm = instr & 0x03fffffc;
if (imm & 0x02000000)
@@ -121,6 +128,15 @@ int emulate_step(struct pt_regs *regs, unsigned int instr)
if ((regs->msr & MSR_SF) == 0)
regs->nip &= 0xffffffffUL;
return 1;
+ case 0x124: /* mtmsr */
+ imm = regs->gpr[rd];
+ if ((imm & MSR_RI) == 0)
+ /* can't step mtmsr that would clear MSR_RI */
+ return -1;
+ regs->msr = imm;
+ regs->nip += 4;
+ return 1;
+#ifdef CONFIG_PPC64
case 0x164: /* mtmsrd */
/* only MSR_EE and MSR_RI get changed if bit 15 set */
/* mtmsrd doesn't change MSR_HV and MSR_ME */
@@ -135,6 +151,7 @@ int emulate_step(struct pt_regs *regs, unsigned int instr)
if ((imm & MSR_SF) == 0)
regs->nip &= 0xffffffffUL;
return 1;
+#endif
}
}
return 0;
diff --git a/arch/ppc64/lib/strcase.c b/arch/powerpc/lib/strcase.c
index e84f243368c0..36b521091bbc 100644
--- a/arch/ppc64/lib/strcase.c
+++ b/arch/powerpc/lib/strcase.c
@@ -1,11 +1,3 @@
-/*
- * c 2001 PPC 64 Team, IBM Corp
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
#include <linux/ctype.h>
int strcasecmp(const char *s1, const char *s2)
diff --git a/arch/powerpc/lib/string.S b/arch/powerpc/lib/string.S
new file mode 100644
index 000000000000..b9ca84ed8927
--- /dev/null
+++ b/arch/powerpc/lib/string.S
@@ -0,0 +1,198 @@
+/*
+ * String handling functions for PowerPC.
+ *
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ * This program is free software; you can redistribute 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/config.h>
+#include <asm/processor.h>
+#include <asm/errno.h>
+#include <asm/ppc_asm.h>
+
+ .section __ex_table,"a"
+#ifdef CONFIG_PPC64
+ .align 3
+#define EXTBL .llong
+#else
+ .align 2
+#define EXTBL .long
+#endif
+ .text
+
+_GLOBAL(strcpy)
+ addi r5,r3,-1
+ addi r4,r4,-1
+1: lbzu r0,1(r4)
+ cmpwi 0,r0,0
+ stbu r0,1(r5)
+ bne 1b
+ blr
+
+/* This clears out any unused part of the destination buffer,
+ just as the libc version does. -- paulus */
+_GLOBAL(strncpy)
+ cmpwi 0,r5,0
+ beqlr
+ mtctr r5
+ addi r6,r3,-1
+ addi r4,r4,-1
+1: lbzu r0,1(r4)
+ cmpwi 0,r0,0
+ stbu r0,1(r6)
+ bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */
+ bnelr /* if we didn't hit a null char, we're done */
+ mfctr r5
+ cmpwi 0,r5,0 /* any space left in destination buffer? */
+ beqlr /* we know r0 == 0 here */
+2: stbu r0,1(r6) /* clear it out if so */
+ bdnz 2b
+ blr
+
+_GLOBAL(strcat)
+ addi r5,r3,-1
+ addi r4,r4,-1
+1: lbzu r0,1(r5)
+ cmpwi 0,r0,0
+ bne 1b
+ addi r5,r5,-1
+1: lbzu r0,1(r4)
+ cmpwi 0,r0,0
+ stbu r0,1(r5)
+ bne 1b
+ blr
+
+_GLOBAL(strcmp)
+ addi r5,r3,-1
+ addi r4,r4,-1
+1: lbzu r3,1(r5)
+ cmpwi 1,r3,0
+ lbzu r0,1(r4)
+ subf. r3,r0,r3
+ beqlr 1
+ beq 1b
+ blr
+
+_GLOBAL(strlen)
+ addi r4,r3,-1
+1: lbzu r0,1(r4)
+ cmpwi 0,r0,0
+ bne 1b
+ subf r3,r3,r4
+ blr
+
+_GLOBAL(memcmp)
+ cmpwi 0,r5,0
+ ble- 2f
+ mtctr r5
+ addi r6,r3,-1
+ addi r4,r4,-1
+1: lbzu r3,1(r6)
+ lbzu r0,1(r4)
+ subf. r3,r0,r3
+ bdnzt 2,1b
+ blr
+2: li r3,0
+ blr
+
+_GLOBAL(memchr)
+ cmpwi 0,r5,0
+ ble- 2f
+ mtctr r5
+ addi r3,r3,-1
+1: lbzu r0,1(r3)
+ cmpw 0,r0,r4
+ bdnzf 2,1b
+ beqlr
+2: li r3,0
+ blr
+
+_GLOBAL(__clear_user)
+ addi r6,r3,-4
+ li r3,0
+ li r5,0
+ cmplwi 0,r4,4
+ blt 7f
+ /* clear a single word */
+11: stwu r5,4(r6)
+ beqlr
+ /* clear word sized chunks */
+ andi. r0,r6,3
+ add r4,r0,r4
+ subf r6,r0,r6
+ srwi r0,r4,2
+ andi. r4,r4,3
+ mtctr r0
+ bdz 7f
+1: stwu r5,4(r6)
+ bdnz 1b
+ /* clear byte sized chunks */
+7: cmpwi 0,r4,0
+ beqlr
+ mtctr r4
+ addi r6,r6,3
+8: stbu r5,1(r6)
+ bdnz 8b
+ blr
+90: mr r3,r4
+ blr
+91: mfctr r3
+ slwi r3,r3,2
+ add r3,r3,r4
+ blr
+92: mfctr r3
+ blr
+
+ .section __ex_table,"a"
+ EXTBL 11b,90b
+ EXTBL 1b,91b
+ EXTBL 8b,92b
+ .text
+
+_GLOBAL(__strncpy_from_user)
+ addi r6,r3,-1
+ addi r4,r4,-1
+ cmpwi 0,r5,0
+ beq 2f
+ mtctr r5
+1: lbzu r0,1(r4)
+ cmpwi 0,r0,0
+ stbu r0,1(r6)
+ bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */
+ beq 3f
+2: addi r6,r6,1
+3: subf r3,r3,r6
+ blr
+99: li r3,-EFAULT
+ blr
+
+ .section __ex_table,"a"
+ EXTBL 1b,99b
+ .text
+
+/* r3 = str, r4 = len (> 0), r5 = top (highest addr) */
+_GLOBAL(__strnlen_user)
+ addi r7,r3,-1
+ subf r6,r7,r5 /* top+1 - str */
+ cmplw 0,r4,r6
+ bge 0f
+ mr r6,r4
+0: mtctr r6 /* ctr = min(len, top - str) */
+1: lbzu r0,1(r7) /* get next byte */
+ cmpwi 0,r0,0
+ bdnzf 2,1b /* loop if --ctr != 0 && byte != 0 */
+ addi r7,r7,1
+ subf r3,r3,r7 /* number of bytes we have looked at */
+ beqlr /* return if we found a 0 byte */
+ cmpw 0,r3,r4 /* did we look at all len bytes? */
+ blt 99f /* if not, must have hit top */
+ addi r3,r4,1 /* return len + 1 to indicate no null found */
+ blr
+99: li r3,0 /* bad address, return 0 */
+ blr
+
+ .section __ex_table,"a"
+ EXTBL 1b,99b
diff --git a/arch/ppc64/lib/usercopy.c b/arch/powerpc/lib/usercopy_64.c
index 5eea6f3c1e03..5eea6f3c1e03 100644
--- a/arch/ppc64/lib/usercopy.c
+++ b/arch/powerpc/lib/usercopy_64.c
diff --git a/arch/powerpc/mm/44x_mmu.c b/arch/powerpc/mm/44x_mmu.c
new file mode 100644
index 000000000000..3d79ce281b67
--- /dev/null
+++ b/arch/powerpc/mm/44x_mmu.c
@@ -0,0 +1,120 @@
+/*
+ * Modifications by Matt Porter (mporter@mvista.com) to support
+ * PPC44x Book E processors.
+ *
+ * This file contains the routines for initializing the MMU
+ * on the 4xx series of chips.
+ * -- paulus
+ *
+ * Derived from arch/ppc/mm/init.c:
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ * and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ * Copyright (C) 1996 Paul Mackerras
+ * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ * Derived from "arch/i386/mm/init.c"
+ * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
+ *
+ * This program is free software; you can redistribute 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/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/stddef.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/highmem.h>
+
+#include <asm/pgalloc.h>
+#include <asm/prom.h>
+#include <asm/io.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/mmu.h>
+#include <asm/uaccess.h>
+#include <asm/smp.h>
+#include <asm/bootx.h>
+#include <asm/machdep.h>
+#include <asm/setup.h>
+
+#include "mmu_decl.h"
+
+extern char etext[], _stext[];
+
+/* Used by the 44x TLB replacement exception handler.
+ * Just needed it declared someplace.
+ */
+unsigned int tlb_44x_index = 0;
+unsigned int tlb_44x_hwater = 62;
+
+/*
+ * "Pins" a 256MB TLB entry in AS0 for kernel lowmem
+ */
+static void __init
+ppc44x_pin_tlb(int slot, unsigned int virt, unsigned int phys)
+{
+ unsigned long attrib = 0;
+
+ __asm__ __volatile__("\
+ clrrwi %2,%2,10\n\
+ ori %2,%2,%4\n\
+ clrrwi %1,%1,10\n\
+ li %0,0\n\
+ ori %0,%0,%5\n\
+ tlbwe %2,%3,%6\n\
+ tlbwe %1,%3,%7\n\
+ tlbwe %0,%3,%8"
+ :
+ : "r" (attrib), "r" (phys), "r" (virt), "r" (slot),
+ "i" (PPC44x_TLB_VALID | PPC44x_TLB_256M),
+ "i" (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G),
+ "i" (PPC44x_TLB_PAGEID),
+ "i" (PPC44x_TLB_XLAT),
+ "i" (PPC44x_TLB_ATTRIB));
+}
+
+/*
+ * MMU_init_hw does the chip-specific initialization of the MMU hardware.
+ */
+void __init MMU_init_hw(void)
+{
+ flush_instruction_cache();
+}
+
+unsigned long __init mmu_mapin_ram(void)
+{
+ unsigned int pinned_tlbs = 1;
+ int i;
+
+ /* Determine number of entries necessary to cover lowmem */
+ pinned_tlbs = (unsigned int)
+ (_ALIGN(total_lowmem, PPC44x_PIN_SIZE) >> PPC44x_PIN_SHIFT);
+
+ /* Write upper watermark to save location */
+ tlb_44x_hwater = PPC44x_LOW_SLOT - pinned_tlbs;
+
+ /* If necessary, set additional pinned TLBs */
+ if (pinned_tlbs > 1)
+ for (i = (PPC44x_LOW_SLOT-(pinned_tlbs-1)); i < PPC44x_LOW_SLOT; i++) {
+ unsigned int phys_addr = (PPC44x_LOW_SLOT-i) * PPC44x_PIN_SIZE;
+ ppc44x_pin_tlb(i, phys_addr+PAGE_OFFSET, phys_addr);
+ }
+
+ return total_lowmem;
+}
diff --git a/arch/powerpc/mm/4xx_mmu.c b/arch/powerpc/mm/4xx_mmu.c
new file mode 100644
index 000000000000..b7bcbc232f39
--- /dev/null
+++ b/arch/powerpc/mm/4xx_mmu.c
@@ -0,0 +1,141 @@
+/*
+ * This file contains the routines for initializing the MMU
+ * on the 4xx series of chips.
+ * -- paulus
+ *
+ * Derived from arch/ppc/mm/init.c:
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ * and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ * Copyright (C) 1996 Paul Mackerras
+ * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ * Derived from "arch/i386/mm/init.c"
+ * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
+ *
+ * This program is free software; you can redistribute 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/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/stddef.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/highmem.h>
+
+#include <asm/pgalloc.h>
+#include <asm/prom.h>
+#include <asm/io.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/mmu.h>
+#include <asm/uaccess.h>
+#include <asm/smp.h>
+#include <asm/bootx.h>
+#include <asm/machdep.h>
+#include <asm/setup.h>
+#include "mmu_decl.h"
+
+extern int __map_without_ltlbs;
+/*
+ * MMU_init_hw does the chip-specific initialization of the MMU hardware.
+ */
+void __init MMU_init_hw(void)
+{
+ /*
+ * The Zone Protection Register (ZPR) defines how protection will
+ * be applied to every page which is a member of a given zone. At
+ * present, we utilize only two of the 4xx's zones.
+ * The zone index bits (of ZSEL) in the PTE are used for software
+ * indicators, except the LSB. For user access, zone 1 is used,
+ * for kernel access, zone 0 is used. We set all but zone 1
+ * to zero, allowing only kernel access as indicated in the PTE.
+ * For zone 1, we set a 01 binary (a value of 10 will not work)
+ * to allow user access as indicated in the PTE. This also allows
+ * kernel access as indicated in the PTE.
+ */
+
+ mtspr(SPRN_ZPR, 0x10000000);
+
+ flush_instruction_cache();
+
+ /*
+ * Set up the real-mode cache parameters for the exception vector
+ * handlers (which are run in real-mode).
+ */
+
+ mtspr(SPRN_DCWR, 0x00000000); /* All caching is write-back */
+
+ /*
+ * Cache instruction and data space where the exception
+ * vectors and the kernel live in real-mode.
+ */
+
+ mtspr(SPRN_DCCR, 0xF0000000); /* 512 MB of data space at 0x0. */
+ mtspr(SPRN_ICCR, 0xF0000000); /* 512 MB of instr. space at 0x0. */
+}
+
+#define LARGE_PAGE_SIZE_16M (1<<24)
+#define LARGE_PAGE_SIZE_4M (1<<22)
+
+unsigned long __init mmu_mapin_ram(void)
+{
+ unsigned long v, s;
+ phys_addr_t p;
+
+ v = KERNELBASE;
+ p = PPC_MEMSTART;
+ s = 0;
+
+ if (__map_without_ltlbs) {
+ return s;
+ }
+
+ while (s <= (total_lowmem - LARGE_PAGE_SIZE_16M)) {
+ pmd_t *pmdp;
+ unsigned long val = p | _PMD_SIZE_16M | _PAGE_HWEXEC | _PAGE_HWWRITE;
+
+ spin_lock(&init_mm.page_table_lock);
+ pmdp = pmd_offset(pgd_offset_k(v), v);
+ pmd_val(*pmdp++) = val;
+ pmd_val(*pmdp++) = val;
+ pmd_val(*pmdp++) = val;
+ pmd_val(*pmdp++) = val;
+ spin_unlock(&init_mm.page_table_lock);
+
+ v += LARGE_PAGE_SIZE_16M;
+ p += LARGE_PAGE_SIZE_16M;
+ s += LARGE_PAGE_SIZE_16M;
+ }
+
+ while (s <= (total_lowmem - LARGE_PAGE_SIZE_4M)) {
+ pmd_t *pmdp;
+ unsigned long val = p | _PMD_SIZE_4M | _PAGE_HWEXEC | _PAGE_HWWRITE;
+
+ spin_lock(&init_mm.page_table_lock);
+ pmdp = pmd_offset(pgd_offset_k(v), v);
+ pmd_val(*pmdp) = val;
+ spin_unlock(&init_mm.page_table_lock);
+
+ v += LARGE_PAGE_SIZE_4M;
+ p += LARGE_PAGE_SIZE_4M;
+ s += LARGE_PAGE_SIZE_4M;
+ }
+
+ return s;
+}
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
new file mode 100644
index 000000000000..93441e7a2921
--- /dev/null
+++ b/arch/powerpc/mm/Makefile
@@ -0,0 +1,21 @@
+#
+# Makefile for the linux ppc-specific parts of the memory manager.
+#
+
+ifeq ($(CONFIG_PPC64),y)
+EXTRA_CFLAGS += -mno-minimal-toc
+endif
+
+obj-y := fault.o mem.o lmb.o
+obj-$(CONFIG_PPC32) += init_32.o pgtable_32.o mmu_context_32.o
+hash-$(CONFIG_PPC_MULTIPLATFORM) := hash_native_64.o
+obj-$(CONFIG_PPC64) += init_64.o pgtable_64.o mmu_context_64.o \
+ hash_utils_64.o hash_low_64.o tlb_64.o \
+ slb_low.o slb.o stab.o mmap.o imalloc.o \
+ $(hash-y)
+obj-$(CONFIG_PPC_STD_MMU_32) += ppc_mmu_32.o hash_low_32.o tlb_32.o
+obj-$(CONFIG_40x) += 4xx_mmu.o
+obj-$(CONFIG_44x) += 44x_mmu.o
+obj-$(CONFIG_FSL_BOOKE) += fsl_booke_mmu.o
+obj-$(CONFIG_NEED_MULTIPLE_NODES) += numa.o
+obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
diff --git a/arch/ppc64/mm/fault.c b/arch/powerpc/mm/fault.c
index be3f25cf3e9f..841d8b6323a8 100644
--- a/arch/ppc64/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -1,7 +1,7 @@
/*
* arch/ppc/mm/fault.c
*
- * PowerPC version
+ * PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
*
* Derived from "arch/i386/mm/fault.c"
@@ -24,10 +24,11 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/types.h>
+#include <linux/ptrace.h>
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
+#include <linux/highmem.h>
#include <linux/module.h>
#include <linux/kprobes.h>
@@ -37,6 +38,7 @@
#include <asm/mmu_context.h>
#include <asm/system.h>
#include <asm/uaccess.h>
+#include <asm/tlbflush.h>
#include <asm/kdebug.h>
#include <asm/siginfo.h>
@@ -78,6 +80,7 @@ static int store_updates_sp(struct pt_regs *regs)
return 0;
}
+#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
static void do_dabr(struct pt_regs *regs, unsigned long error_code)
{
siginfo_t info;
@@ -99,12 +102,18 @@ static void do_dabr(struct pt_regs *regs, unsigned long error_code)
info.si_addr = (void __user *)regs->nip;
force_sig_info(SIGTRAP, &info, current);
}
+#endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/
/*
- * The error_code parameter is
+ * For 600- and 800-family processors, the error_code parameter is DSISR
+ * for a data fault, SRR1 for an instruction fault. For 400-family processors
+ * the error_code parameter is ESR for a data fault, 0 for an instruction
+ * fault.
+ * For 64-bit processors, the error_code parameter is
* - DSISR for a non-SLB data access fault,
* - SRR1 & 0x08000000 for a non-SLB instruction access fault
* - 0 any SLB fault.
+ *
* The return value is 0 if the fault was handled, or the signal
* number if this is a kernel fault that can't be handled here.
*/
@@ -114,12 +123,25 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
struct vm_area_struct * vma;
struct mm_struct *mm = current->mm;
siginfo_t info;
- unsigned long code = SEGV_MAPERR;
- unsigned long is_write = error_code & DSISR_ISSTORE;
- unsigned long trap = TRAP(regs);
- unsigned long is_exec = trap == 0x400;
+ int code = SEGV_MAPERR;
+ int is_write = 0;
+ int trap = TRAP(regs);
+ int is_exec = trap == 0x400;
- BUG_ON((trap == 0x380) || (trap == 0x480));
+#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
+ /*
+ * Fortunately the bit assignments in SRR1 for an instruction
+ * fault and DSISR for a data fault are mostly the same for the
+ * bits we are interested in. But there are some bits which
+ * indicate errors in DSISR but can validly be set in SRR1.
+ */
+ if (trap == 0x400)
+ error_code &= 0x48200000;
+ else
+ is_write = error_code & DSISR_ISSTORE;
+#else
+ is_write = error_code & ESR_DST;
+#endif /* CONFIG_4xx || CONFIG_BOOKE */
if (notify_die(DIE_PAGE_FAULT, "page_fault", regs, error_code,
11, SIGSEGV) == NOTIFY_STOP)
@@ -134,10 +156,13 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
if (!user_mode(regs) && (address >= TASK_SIZE))
return SIGSEGV;
+#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
if (error_code & DSISR_DABRMATCH) {
+ /* DABR match */
do_dabr(regs, error_code);
return 0;
}
+#endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/
if (in_atomic() || mm == NULL) {
if (!user_mode(regs))
@@ -176,10 +201,8 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
vma = find_vma(mm, address);
if (!vma)
goto bad_area;
-
- if (vma->vm_start <= address) {
+ if (vma->vm_start <= address)
goto good_area;
- }
if (!(vma->vm_flags & VM_GROWSDOWN))
goto bad_area;
@@ -214,35 +237,76 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
&& (!user_mode(regs) || !store_updates_sp(regs)))
goto bad_area;
}
-
if (expand_stack(vma, address))
goto bad_area;
good_area:
code = SEGV_ACCERR;
+#if defined(CONFIG_6xx)
+ if (error_code & 0x95700000)
+ /* an error such as lwarx to I/O controller space,
+ address matching DABR, eciwx, etc. */
+ goto bad_area;
+#endif /* CONFIG_6xx */
+#if defined(CONFIG_8xx)
+ /* The MPC8xx seems to always set 0x80000000, which is
+ * "undefined". Of those that can be set, this is the only
+ * one which seems bad.
+ */
+ if (error_code & 0x10000000)
+ /* Guarded storage error. */
+ goto bad_area;
+#endif /* CONFIG_8xx */
if (is_exec) {
+#ifdef CONFIG_PPC64
/* protection fault */
if (error_code & DSISR_PROTFAULT)
goto bad_area;
if (!(vma->vm_flags & VM_EXEC))
goto bad_area;
+#endif
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+ pte_t *ptep;
+
+ /* Since 4xx/Book-E supports per-page execute permission,
+ * we lazily flush dcache to icache. */
+ ptep = NULL;
+ if (get_pteptr(mm, address, &ptep) && pte_present(*ptep)) {
+ struct page *page = pte_page(*ptep);
+
+ if (! test_bit(PG_arch_1, &page->flags)) {
+ flush_dcache_icache_page(page);
+ set_bit(PG_arch_1, &page->flags);
+ }
+ pte_update(ptep, 0, _PAGE_HWEXEC);
+ _tlbie(address);
+ pte_unmap(ptep);
+ up_read(&mm->mmap_sem);
+ return 0;
+ }
+ if (ptep != NULL)
+ pte_unmap(ptep);
+#endif
/* a write */
} else if (is_write) {
if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
/* a read */
} else {
- if (!(vma->vm_flags & VM_READ))
+ /* protection fault */
+ if (error_code & 0x08000000)
+ goto bad_area;
+ if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
goto bad_area;
}
- survive:
/*
* If for any reason at all we couldn't handle the fault,
* make sure we exit gracefully rather than endlessly redo
* the fault.
*/
+ survive:
switch (handle_mm_fault(mm, vma, address, is_write)) {
case VM_FAULT_MINOR:
@@ -268,15 +332,11 @@ bad_area:
bad_area_nosemaphore:
/* User mode accesses cause a SIGSEGV */
if (user_mode(regs)) {
- info.si_signo = SIGSEGV;
- info.si_errno = 0;
- info.si_code = code;
- info.si_addr = (void __user *) address;
- force_sig_info(SIGSEGV, &info, current);
+ _exception(SIGSEGV, regs, code, address);
return 0;
}
- if (trap == 0x400 && (error_code & DSISR_PROTFAULT)
+ if (is_exec && (error_code & DSISR_PROTFAULT)
&& printk_ratelimit())
printk(KERN_CRIT "kernel tried to execute NX-protected"
" page (%lx) - exploit attempt? (uid: %d)\n",
@@ -315,8 +375,8 @@ do_sigbus:
/*
* bad_page_fault is called when we have a bad access from the kernel.
- * It is called from do_page_fault above and from some of the procedures
- * in traps.c.
+ * It is called from the DSI and ISI handlers in head.S and from some
+ * of the procedures in traps.c.
*/
void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
{
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
new file mode 100644
index 000000000000..af9ca0eb6d55
--- /dev/null
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -0,0 +1,237 @@
+/*
+ * Modifications by Kumar Gala (kumar.gala@freescale.com) to support
+ * E500 Book E processors.
+ *
+ * Copyright 2004 Freescale Semiconductor, Inc
+ *
+ * This file contains the routines for initializing the MMU
+ * on the 4xx series of chips.
+ * -- paulus
+ *
+ * Derived from arch/ppc/mm/init.c:
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ * and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ * Copyright (C) 1996 Paul Mackerras
+ * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ * Derived from "arch/i386/mm/init.c"
+ * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
+ *
+ * This program is free software; you can redistribute 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/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/stddef.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/highmem.h>
+
+#include <asm/pgalloc.h>
+#include <asm/prom.h>
+#include <asm/io.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/mmu.h>
+#include <asm/uaccess.h>
+#include <asm/smp.h>
+#include <asm/bootx.h>
+#include <asm/machdep.h>
+#include <asm/setup.h>
+
+extern void loadcam_entry(unsigned int index);
+unsigned int tlbcam_index;
+unsigned int num_tlbcam_entries;
+static unsigned long __cam0, __cam1, __cam2;
+extern unsigned long total_lowmem;
+extern unsigned long __max_low_memory;
+#define MAX_LOW_MEM CONFIG_LOWMEM_SIZE
+
+#define NUM_TLBCAMS (16)
+
+struct tlbcam {
+ u32 MAS0;
+ u32 MAS1;
+ u32 MAS2;
+ u32 MAS3;
+ u32 MAS7;
+} TLBCAM[NUM_TLBCAMS];
+
+struct tlbcamrange {
+ unsigned long start;
+ unsigned long limit;
+ phys_addr_t phys;
+} tlbcam_addrs[NUM_TLBCAMS];
+
+extern unsigned int tlbcam_index;
+
+/*
+ * Return PA for this VA if it is mapped by a CAM, or 0
+ */
+unsigned long v_mapped_by_tlbcam(unsigned long va)
+{
+ int b;
+ for (b = 0; b < tlbcam_index; ++b)
+ if (va >= tlbcam_addrs[b].start && va < tlbcam_addrs[b].limit)
+ return tlbcam_addrs[b].phys + (va - tlbcam_addrs[b].start);
+ return 0;
+}
+
+/*
+ * Return VA for a given PA or 0 if not mapped
+ */
+unsigned long p_mapped_by_tlbcam(unsigned long pa)
+{
+ int b;
+ for (b = 0; b < tlbcam_index; ++b)
+ if (pa >= tlbcam_addrs[b].phys
+ && pa < (tlbcam_addrs[b].limit-tlbcam_addrs[b].start)
+ +tlbcam_addrs[b].phys)
+ return tlbcam_addrs[b].start+(pa-tlbcam_addrs[b].phys);
+ return 0;
+}
+
+/*
+ * Set up one of the I/D BAT (block address translation) register pairs.
+ * The parameters are not checked; in particular size must be a power
+ * of 4 between 4k and 256M.
+ */
+void settlbcam(int index, unsigned long virt, phys_addr_t phys,
+ unsigned int size, int flags, unsigned int pid)
+{
+ unsigned int tsize, lz;
+
+ asm ("cntlzw %0,%1" : "=r" (lz) : "r" (size));
+ tsize = (21 - lz) / 2;
+
+#ifdef CONFIG_SMP
+ if ((flags & _PAGE_NO_CACHE) == 0)
+ flags |= _PAGE_COHERENT;
+#endif
+
+ TLBCAM[index].MAS0 = MAS0_TLBSEL(1) | MAS0_ESEL(index) | MAS0_NV(index+1);
+ TLBCAM[index].MAS1 = MAS1_VALID | MAS1_IPROT | MAS1_TSIZE(tsize) | MAS1_TID(pid);
+ TLBCAM[index].MAS2 = virt & PAGE_MASK;
+
+ TLBCAM[index].MAS2 |= (flags & _PAGE_WRITETHRU) ? MAS2_W : 0;
+ TLBCAM[index].MAS2 |= (flags & _PAGE_NO_CACHE) ? MAS2_I : 0;
+ TLBCAM[index].MAS2 |= (flags & _PAGE_COHERENT) ? MAS2_M : 0;
+ TLBCAM[index].MAS2 |= (flags & _PAGE_GUARDED) ? MAS2_G : 0;
+ TLBCAM[index].MAS2 |= (flags & _PAGE_ENDIAN) ? MAS2_E : 0;
+
+ TLBCAM[index].MAS3 = (phys & PAGE_MASK) | MAS3_SX | MAS3_SR;
+ TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_SW : 0);
+
+#ifndef CONFIG_KGDB /* want user access for breakpoints */
+ if (flags & _PAGE_USER) {
+ TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
+ TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
+ }
+#else
+ TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
+ TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
+#endif
+
+ tlbcam_addrs[index].start = virt;
+ tlbcam_addrs[index].limit = virt + size - 1;
+ tlbcam_addrs[index].phys = phys;
+
+ loadcam_entry(index);
+}
+
+void invalidate_tlbcam_entry(int index)
+{
+ TLBCAM[index].MAS0 = MAS0_TLBSEL(1) | MAS0_ESEL(index);
+ TLBCAM[index].MAS1 = ~MAS1_VALID;
+
+ loadcam_entry(index);
+}
+
+void __init cam_mapin_ram(unsigned long cam0, unsigned long cam1,
+ unsigned long cam2)
+{
+ settlbcam(0, KERNELBASE, PPC_MEMSTART, cam0, _PAGE_KERNEL, 0);
+ tlbcam_index++;
+ if (cam1) {
+ tlbcam_index++;
+ settlbcam(1, KERNELBASE+cam0, PPC_MEMSTART+cam0, cam1, _PAGE_KERNEL, 0);
+ }
+ if (cam2) {
+ tlbcam_index++;
+ settlbcam(2, KERNELBASE+cam0+cam1, PPC_MEMSTART+cam0+cam1, cam2, _PAGE_KERNEL, 0);
+ }
+}
+
+/*
+ * MMU_init_hw does the chip-specific initialization of the MMU hardware.
+ */
+void __init MMU_init_hw(void)
+{
+ flush_instruction_cache();
+}
+
+unsigned long __init mmu_mapin_ram(void)
+{
+ cam_mapin_ram(__cam0, __cam1, __cam2);
+
+ return __cam0 + __cam1 + __cam2;
+}
+
+
+void __init
+adjust_total_lowmem(void)
+{
+ unsigned long max_low_mem = MAX_LOW_MEM;
+ unsigned long cam_max = 0x10000000;
+ unsigned long ram;
+
+ /* adjust CAM size to max_low_mem */
+ if (max_low_mem < cam_max)
+ cam_max = max_low_mem;
+
+ /* adjust lowmem size to max_low_mem */
+ if (max_low_mem < total_lowmem)
+ ram = max_low_mem;
+ else
+ ram = total_lowmem;
+
+ /* Calculate CAM values */
+ __cam0 = 1UL << 2 * (__ilog2(ram) / 2);
+ if (__cam0 > cam_max)
+ __cam0 = cam_max;
+ ram -= __cam0;
+ if (ram) {
+ __cam1 = 1UL << 2 * (__ilog2(ram) / 2);
+ if (__cam1 > cam_max)
+ __cam1 = cam_max;
+ ram -= __cam1;
+ }
+ if (ram) {
+ __cam2 = 1UL << 2 * (__ilog2(ram) / 2);
+ if (__cam2 > cam_max)
+ __cam2 = cam_max;
+ ram -= __cam2;
+ }
+
+ printk(KERN_INFO "Memory CAM mapping: CAM0=%ldMb, CAM1=%ldMb,"
+ " CAM2=%ldMb residual: %ldMb\n",
+ __cam0 >> 20, __cam1 >> 20, __cam2 >> 20,
+ (total_lowmem - __cam0 - __cam1 - __cam2) >> 20);
+ __max_low_memory = max_low_mem = __cam0 + __cam1 + __cam2;
+}
diff --git a/arch/powerpc/mm/hash_low_32.S b/arch/powerpc/mm/hash_low_32.S
new file mode 100644
index 000000000000..12ccd7155bac
--- /dev/null
+++ b/arch/powerpc/mm/hash_low_32.S
@@ -0,0 +1,618 @@
+/*
+ * arch/ppc/kernel/hashtable.S
+ *
+ * $Id: hashtable.S,v 1.6 1999/10/08 01:56:15 paulus Exp $
+ *
+ * PowerPC version
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
+ * Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
+ * Adapted for Power Macintosh by Paul Mackerras.
+ * Low-level exception handlers and MMU support
+ * rewritten by Paul Mackerras.
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ * This file contains low-level assembler routines for managing
+ * the PowerPC MMU hash table. (PPC 8xx processors don't use a
+ * hash table, so this file is not used on them.)
+ *
+ * This program is free software; you can redistribute 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/config.h>
+#include <asm/reg.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/cputable.h>
+#include <asm/ppc_asm.h>
+#include <asm/thread_info.h>
+#include <asm/asm-offsets.h>
+
+#ifdef CONFIG_SMP
+ .comm mmu_hash_lock,4
+#endif /* CONFIG_SMP */
+
+/*
+ * Sync CPUs with hash_page taking & releasing the hash
+ * table lock
+ */
+#ifdef CONFIG_SMP
+ .text
+_GLOBAL(hash_page_sync)
+ lis r8,mmu_hash_lock@h
+ ori r8,r8,mmu_hash_lock@l
+ lis r0,0x0fff
+ b 10f
+11: lwz r6,0(r8)
+ cmpwi 0,r6,0
+ bne 11b
+10: lwarx r6,0,r8
+ cmpwi 0,r6,0
+ bne- 11b
+ stwcx. r0,0,r8
+ bne- 10b
+ isync
+ eieio
+ li r0,0
+ stw r0,0(r8)
+ blr
+#endif
+
+/*
+ * Load a PTE into the hash table, if possible.
+ * The address is in r4, and r3 contains an access flag:
+ * _PAGE_RW (0x400) if a write.
+ * r9 contains the SRR1 value, from which we use the MSR_PR bit.
+ * SPRG3 contains the physical address of the current task's thread.
+ *
+ * Returns to the caller if the access is illegal or there is no
+ * mapping for the address. Otherwise it places an appropriate PTE
+ * in the hash table and returns from the exception.
+ * Uses r0, r3 - r8, ctr, lr.
+ */
+ .text
+_GLOBAL(hash_page)
+#ifdef CONFIG_PPC64BRIDGE
+ mfmsr r0
+ clrldi r0,r0,1 /* make sure it's in 32-bit mode */
+ MTMSRD(r0)
+ isync
+#endif
+ tophys(r7,0) /* gets -KERNELBASE into r7 */
+#ifdef CONFIG_SMP
+ addis r8,r7,mmu_hash_lock@h
+ ori r8,r8,mmu_hash_lock@l
+ lis r0,0x0fff
+ b 10f
+11: lwz r6,0(r8)
+ cmpwi 0,r6,0
+ bne 11b
+10: lwarx r6,0,r8
+ cmpwi 0,r6,0
+ bne- 11b
+ stwcx. r0,0,r8
+ bne- 10b
+ isync
+#endif
+ /* Get PTE (linux-style) and check access */
+ lis r0,KERNELBASE@h /* check if kernel address */
+ cmplw 0,r4,r0
+ mfspr r8,SPRN_SPRG3 /* current task's THREAD (phys) */
+ ori r3,r3,_PAGE_USER|_PAGE_PRESENT /* test low addresses as user */
+ lwz r5,PGDIR(r8) /* virt page-table root */
+ blt+ 112f /* assume user more likely */
+ lis r5,swapper_pg_dir@ha /* if kernel address, use */
+ addi r5,r5,swapper_pg_dir@l /* kernel page table */
+ rlwimi r3,r9,32-12,29,29 /* MSR_PR -> _PAGE_USER */
+112: add r5,r5,r7 /* convert to phys addr */
+ rlwimi r5,r4,12,20,29 /* insert top 10 bits of address */
+ lwz r8,0(r5) /* get pmd entry */
+ rlwinm. r8,r8,0,0,19 /* extract address of pte page */
+#ifdef CONFIG_SMP
+ beq- hash_page_out /* return if no mapping */
+#else
+ /* XXX it seems like the 601 will give a machine fault on the
+ rfi if its alignment is wrong (bottom 4 bits of address are
+ 8 or 0xc) and we have had a not-taken conditional branch
+ to the address following the rfi. */
+ beqlr-
+#endif
+ rlwimi r8,r4,22,20,29 /* insert next 10 bits of address */
+ rlwinm r0,r3,32-3,24,24 /* _PAGE_RW access -> _PAGE_DIRTY */
+ ori r0,r0,_PAGE_ACCESSED|_PAGE_HASHPTE
+
+ /*
+ * Update the linux PTE atomically. We do the lwarx up-front
+ * because almost always, there won't be a permission violation
+ * and there won't already be an HPTE, and thus we will have
+ * to update the PTE to set _PAGE_HASHPTE. -- paulus.
+ */
+retry:
+ lwarx r6,0,r8 /* get linux-style pte */
+ andc. r5,r3,r6 /* check access & ~permission */
+#ifdef CONFIG_SMP
+ bne- hash_page_out /* return if access not permitted */
+#else
+ bnelr-
+#endif
+ or r5,r0,r6 /* set accessed/dirty bits */
+ stwcx. r5,0,r8 /* attempt to update PTE */
+ bne- retry /* retry if someone got there first */
+
+ mfsrin r3,r4 /* get segment reg for segment */
+ mfctr r0
+ stw r0,_CTR(r11)
+ bl create_hpte /* add the hash table entry */
+
+#ifdef CONFIG_SMP
+ eieio
+ addis r8,r7,mmu_hash_lock@ha
+ li r0,0
+ stw r0,mmu_hash_lock@l(r8)
+#endif
+
+ /* Return from the exception */
+ lwz r5,_CTR(r11)
+ mtctr r5
+ lwz r0,GPR0(r11)
+ lwz r7,GPR7(r11)
+ lwz r8,GPR8(r11)
+ b fast_exception_return
+
+#ifdef CONFIG_SMP
+hash_page_out:
+ eieio
+ addis r8,r7,mmu_hash_lock@ha
+ li r0,0
+ stw r0,mmu_hash_lock@l(r8)
+ blr
+#endif /* CONFIG_SMP */
+
+/*
+ * Add an entry for a particular page to the hash table.
+ *
+ * add_hash_page(unsigned context, unsigned long va, unsigned long pmdval)
+ *
+ * We assume any necessary modifications to the pte (e.g. setting
+ * the accessed bit) have already been done and that there is actually
+ * a hash table in use (i.e. we're not on a 603).
+ */
+_GLOBAL(add_hash_page)
+ mflr r0
+ stw r0,4(r1)
+
+ /* Convert context and va to VSID */
+ mulli r3,r3,897*16 /* multiply context by context skew */
+ rlwinm r0,r4,4,28,31 /* get ESID (top 4 bits of va) */
+ mulli r0,r0,0x111 /* multiply by ESID skew */
+ add r3,r3,r0 /* note create_hpte trims to 24 bits */
+
+#ifdef CONFIG_SMP
+ rlwinm r8,r1,0,0,18 /* use cpu number to make tag */
+ lwz r8,TI_CPU(r8) /* to go in mmu_hash_lock */
+ oris r8,r8,12
+#endif /* CONFIG_SMP */
+
+ /*
+ * We disable interrupts here, even on UP, because we don't
+ * want to race with hash_page, and because we want the
+ * _PAGE_HASHPTE bit to be a reliable indication of whether
+ * the HPTE exists (or at least whether one did once).
+ * We also turn off the MMU for data accesses so that we
+ * we can't take a hash table miss (assuming the code is
+ * covered by a BAT). -- paulus
+ */
+ mfmsr r10
+ SYNC
+ rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */
+ rlwinm r0,r0,0,28,26 /* clear MSR_DR */
+ mtmsr r0
+ SYNC_601
+ isync
+
+ tophys(r7,0)
+
+#ifdef CONFIG_SMP
+ addis r9,r7,mmu_hash_lock@ha
+ addi r9,r9,mmu_hash_lock@l
+10: lwarx r0,0,r9 /* take the mmu_hash_lock */
+ cmpi 0,r0,0
+ bne- 11f
+ stwcx. r8,0,r9
+ beq+ 12f
+11: lwz r0,0(r9)
+ cmpi 0,r0,0
+ beq 10b
+ b 11b
+12: isync
+#endif
+
+ /*
+ * Fetch the linux pte and test and set _PAGE_HASHPTE atomically.
+ * If _PAGE_HASHPTE was already set, we don't replace the existing
+ * HPTE, so we just unlock and return.
+ */
+ mr r8,r5
+ rlwimi r8,r4,22,20,29
+1: lwarx r6,0,r8
+ andi. r0,r6,_PAGE_HASHPTE
+ bne 9f /* if HASHPTE already set, done */
+ ori r5,r6,_PAGE_HASHPTE
+ stwcx. r5,0,r8
+ bne- 1b
+
+ bl create_hpte
+
+9:
+#ifdef CONFIG_SMP
+ eieio
+ li r0,0
+ stw r0,0(r9) /* clear mmu_hash_lock */
+#endif
+
+ /* reenable interrupts and DR */
+ mtmsr r10
+ SYNC_601
+ isync
+
+ lwz r0,4(r1)
+ mtlr r0
+ blr
+
+/*
+ * This routine adds a hardware PTE to the hash table.
+ * It is designed to be called with the MMU either on or off.
+ * r3 contains the VSID, r4 contains the virtual address,
+ * r5 contains the linux PTE, r6 contains the old value of the
+ * linux PTE (before setting _PAGE_HASHPTE) and r7 contains the
+ * offset to be added to addresses (0 if the MMU is on,
+ * -KERNELBASE if it is off).
+ * On SMP, the caller should have the mmu_hash_lock held.
+ * We assume that the caller has (or will) set the _PAGE_HASHPTE
+ * bit in the linux PTE in memory. The value passed in r6 should
+ * be the old linux PTE value; if it doesn't have _PAGE_HASHPTE set
+ * this routine will skip the search for an existing HPTE.
+ * This procedure modifies r0, r3 - r6, r8, cr0.
+ * -- paulus.
+ *
+ * For speed, 4 of the instructions get patched once the size and
+ * physical address of the hash table are known. These definitions
+ * of Hash_base and Hash_bits below are just an example.
+ */
+Hash_base = 0xc0180000
+Hash_bits = 12 /* e.g. 256kB hash table */
+Hash_msk = (((1 << Hash_bits) - 1) * 64)
+
+#ifndef CONFIG_PPC64BRIDGE
+/* defines for the PTE format for 32-bit PPCs */
+#define PTE_SIZE 8
+#define PTEG_SIZE 64
+#define LG_PTEG_SIZE 6
+#define LDPTEu lwzu
+#define STPTE stw
+#define CMPPTE cmpw
+#define PTE_H 0x40
+#define PTE_V 0x80000000
+#define TST_V(r) rlwinm. r,r,0,0,0
+#define SET_V(r) oris r,r,PTE_V@h
+#define CLR_V(r,t) rlwinm r,r,0,1,31
+
+#else
+/* defines for the PTE format for 64-bit PPCs */
+#define PTE_SIZE 16
+#define PTEG_SIZE 128
+#define LG_PTEG_SIZE 7
+#define LDPTEu ldu
+#define STPTE std
+#define CMPPTE cmpd
+#define PTE_H 2
+#define PTE_V 1
+#define TST_V(r) andi. r,r,PTE_V
+#define SET_V(r) ori r,r,PTE_V
+#define CLR_V(r,t) li t,PTE_V; andc r,r,t
+#endif /* CONFIG_PPC64BRIDGE */
+
+#define HASH_LEFT 31-(LG_PTEG_SIZE+Hash_bits-1)
+#define HASH_RIGHT 31-LG_PTEG_SIZE
+
+_GLOBAL(create_hpte)
+ /* Convert linux-style PTE (r5) to low word of PPC-style PTE (r8) */
+ rlwinm r8,r5,32-10,31,31 /* _PAGE_RW -> PP lsb */
+ rlwinm r0,r5,32-7,31,31 /* _PAGE_DIRTY -> PP lsb */
+ and r8,r8,r0 /* writable if _RW & _DIRTY */
+ rlwimi r5,r5,32-1,30,30 /* _PAGE_USER -> PP msb */
+ rlwimi r5,r5,32-2,31,31 /* _PAGE_USER -> PP lsb */
+ ori r8,r8,0xe14 /* clear out reserved bits and M */
+ andc r8,r5,r8 /* PP = user? (rw&dirty? 2: 3): 0 */
+BEGIN_FTR_SECTION
+ ori r8,r8,_PAGE_COHERENT /* set M (coherence required) */
+END_FTR_SECTION_IFSET(CPU_FTR_NEED_COHERENT)
+
+ /* Construct the high word of the PPC-style PTE (r5) */
+#ifndef CONFIG_PPC64BRIDGE
+ rlwinm r5,r3,7,1,24 /* put VSID in 0x7fffff80 bits */
+ rlwimi r5,r4,10,26,31 /* put in API (abbrev page index) */
+#else /* CONFIG_PPC64BRIDGE */
+ clrlwi r3,r3,8 /* reduce vsid to 24 bits */
+ sldi r5,r3,12 /* shift vsid into position */
+ rlwimi r5,r4,16,20,24 /* put in API (abbrev page index) */
+#endif /* CONFIG_PPC64BRIDGE */
+ SET_V(r5) /* set V (valid) bit */
+
+ /* Get the address of the primary PTE group in the hash table (r3) */
+_GLOBAL(hash_page_patch_A)
+ addis r0,r7,Hash_base@h /* base address of hash table */
+ rlwimi r0,r3,LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT /* VSID -> hash */
+ rlwinm r3,r4,20+LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT /* PI -> hash */
+ xor r3,r3,r0 /* make primary hash */
+ li r0,8 /* PTEs/group */
+
+ /*
+ * Test the _PAGE_HASHPTE bit in the old linux PTE, and skip the search
+ * if it is clear, meaning that the HPTE isn't there already...
+ */
+ andi. r6,r6,_PAGE_HASHPTE
+ beq+ 10f /* no PTE: go look for an empty slot */
+ tlbie r4
+
+ addis r4,r7,htab_hash_searches@ha
+ lwz r6,htab_hash_searches@l(r4)
+ addi r6,r6,1 /* count how many searches we do */
+ stw r6,htab_hash_searches@l(r4)
+
+ /* Search the primary PTEG for a PTE whose 1st (d)word matches r5 */
+ mtctr r0
+ addi r4,r3,-PTE_SIZE
+1: LDPTEu r6,PTE_SIZE(r4) /* get next PTE */
+ CMPPTE 0,r6,r5
+ bdnzf 2,1b /* loop while ctr != 0 && !cr0.eq */
+ beq+ found_slot
+
+ /* Search the secondary PTEG for a matching PTE */
+ ori r5,r5,PTE_H /* set H (secondary hash) bit */
+_GLOBAL(hash_page_patch_B)
+ xoris r4,r3,Hash_msk>>16 /* compute secondary hash */
+ xori r4,r4,(-PTEG_SIZE & 0xffff)
+ addi r4,r4,-PTE_SIZE
+ mtctr r0
+2: LDPTEu r6,PTE_SIZE(r4)
+ CMPPTE 0,r6,r5
+ bdnzf 2,2b
+ beq+ found_slot
+ xori r5,r5,PTE_H /* clear H bit again */
+
+ /* Search the primary PTEG for an empty slot */
+10: mtctr r0
+ addi r4,r3,-PTE_SIZE /* search primary PTEG */
+1: LDPTEu r6,PTE_SIZE(r4) /* get next PTE */
+ TST_V(r6) /* test valid bit */
+ bdnzf 2,1b /* loop while ctr != 0 && !cr0.eq */
+ beq+ found_empty
+
+ /* update counter of times that the primary PTEG is full */
+ addis r4,r7,primary_pteg_full@ha
+ lwz r6,primary_pteg_full@l(r4)
+ addi r6,r6,1
+ stw r6,primary_pteg_full@l(r4)
+
+ /* Search the secondary PTEG for an empty slot */
+ ori r5,r5,PTE_H /* set H (secondary hash) bit */
+_GLOBAL(hash_page_patch_C)
+ xoris r4,r3,Hash_msk>>16 /* compute secondary hash */
+ xori r4,r4,(-PTEG_SIZE & 0xffff)
+ addi r4,r4,-PTE_SIZE
+ mtctr r0
+2: LDPTEu r6,PTE_SIZE(r4)
+ TST_V(r6)
+ bdnzf 2,2b
+ beq+ found_empty
+ xori r5,r5,PTE_H /* clear H bit again */
+
+ /*
+ * Choose an arbitrary slot in the primary PTEG to overwrite.
+ * Since both the primary and secondary PTEGs are full, and we
+ * have no information that the PTEs in the primary PTEG are
+ * more important or useful than those in the secondary PTEG,
+ * and we know there is a definite (although small) speed
+ * advantage to putting the PTE in the primary PTEG, we always
+ * put the PTE in the primary PTEG.
+ */
+ addis r4,r7,next_slot@ha
+ lwz r6,next_slot@l(r4)
+ addi r6,r6,PTE_SIZE
+ andi. r6,r6,7*PTE_SIZE
+ stw r6,next_slot@l(r4)
+ add r4,r3,r6
+
+#ifndef CONFIG_SMP
+ /* Store PTE in PTEG */
+found_empty:
+ STPTE r5,0(r4)
+found_slot:
+ STPTE r8,PTE_SIZE/2(r4)
+
+#else /* CONFIG_SMP */
+/*
+ * Between the tlbie above and updating the hash table entry below,
+ * another CPU could read the hash table entry and put it in its TLB.
+ * There are 3 cases:
+ * 1. using an empty slot
+ * 2. updating an earlier entry to change permissions (i.e. enable write)
+ * 3. taking over the PTE for an unrelated address
+ *
+ * In each case it doesn't really matter if the other CPUs have the old
+ * PTE in their TLB. So we don't need to bother with another tlbie here,
+ * which is convenient as we've overwritten the register that had the
+ * address. :-) The tlbie above is mainly to make sure that this CPU comes
+ * and gets the new PTE from the hash table.
+ *
+ * We do however have to make sure that the PTE is never in an invalid
+ * state with the V bit set.
+ */
+found_empty:
+found_slot:
+ CLR_V(r5,r0) /* clear V (valid) bit in PTE */
+ STPTE r5,0(r4)
+ sync
+ TLBSYNC
+ STPTE r8,PTE_SIZE/2(r4) /* put in correct RPN, WIMG, PP bits */
+ sync
+ SET_V(r5)
+ STPTE r5,0(r4) /* finally set V bit in PTE */
+#endif /* CONFIG_SMP */
+
+ sync /* make sure pte updates get to memory */
+ blr
+
+ .comm next_slot,4
+ .comm primary_pteg_full,4
+ .comm htab_hash_searches,4
+
+/*
+ * Flush the entry for a particular page from the hash table.
+ *
+ * flush_hash_pages(unsigned context, unsigned long va, unsigned long pmdval,
+ * int count)
+ *
+ * We assume that there is a hash table in use (Hash != 0).
+ */
+_GLOBAL(flush_hash_pages)
+ tophys(r7,0)
+
+ /*
+ * We disable interrupts here, even on UP, because we want
+ * the _PAGE_HASHPTE bit to be a reliable indication of
+ * whether the HPTE exists (or at least whether one did once).
+ * We also turn off the MMU for data accesses so that we
+ * we can't take a hash table miss (assuming the code is
+ * covered by a BAT). -- paulus
+ */
+ mfmsr r10
+ SYNC
+ rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */
+ rlwinm r0,r0,0,28,26 /* clear MSR_DR */
+ mtmsr r0
+ SYNC_601
+ isync
+
+ /* First find a PTE in the range that has _PAGE_HASHPTE set */
+ rlwimi r5,r4,22,20,29
+1: lwz r0,0(r5)
+ cmpwi cr1,r6,1
+ andi. r0,r0,_PAGE_HASHPTE
+ bne 2f
+ ble cr1,19f
+ addi r4,r4,0x1000
+ addi r5,r5,4
+ addi r6,r6,-1
+ b 1b
+
+ /* Convert context and va to VSID */
+2: mulli r3,r3,897*16 /* multiply context by context skew */
+ rlwinm r0,r4,4,28,31 /* get ESID (top 4 bits of va) */
+ mulli r0,r0,0x111 /* multiply by ESID skew */
+ add r3,r3,r0 /* note code below trims to 24 bits */
+
+ /* Construct the high word of the PPC-style PTE (r11) */
+#ifndef CONFIG_PPC64BRIDGE
+ rlwinm r11,r3,7,1,24 /* put VSID in 0x7fffff80 bits */
+ rlwimi r11,r4,10,26,31 /* put in API (abbrev page index) */
+#else /* CONFIG_PPC64BRIDGE */
+ clrlwi r3,r3,8 /* reduce vsid to 24 bits */
+ sldi r11,r3,12 /* shift vsid into position */
+ rlwimi r11,r4,16,20,24 /* put in API (abbrev page index) */
+#endif /* CONFIG_PPC64BRIDGE */
+ SET_V(r11) /* set V (valid) bit */
+
+#ifdef CONFIG_SMP
+ addis r9,r7,mmu_hash_lock@ha
+ addi r9,r9,mmu_hash_lock@l
+ rlwinm r8,r1,0,0,18
+ add r8,r8,r7
+ lwz r8,TI_CPU(r8)
+ oris r8,r8,9
+10: lwarx r0,0,r9
+ cmpi 0,r0,0
+ bne- 11f
+ stwcx. r8,0,r9
+ beq+ 12f
+11: lwz r0,0(r9)
+ cmpi 0,r0,0
+ beq 10b
+ b 11b
+12: isync
+#endif
+
+ /*
+ * Check the _PAGE_HASHPTE bit in the linux PTE. If it is
+ * already clear, we're done (for this pte). If not,
+ * clear it (atomically) and proceed. -- paulus.
+ */
+33: lwarx r8,0,r5 /* fetch the pte */
+ andi. r0,r8,_PAGE_HASHPTE
+ beq 8f /* done if HASHPTE is already clear */
+ rlwinm r8,r8,0,31,29 /* clear HASHPTE bit */
+ stwcx. r8,0,r5 /* update the pte */
+ bne- 33b
+
+ /* Get the address of the primary PTE group in the hash table (r3) */
+_GLOBAL(flush_hash_patch_A)
+ addis r8,r7,Hash_base@h /* base address of hash table */
+ rlwimi r8,r3,LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT /* VSID -> hash */
+ rlwinm r0,r4,20+LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT /* PI -> hash */
+ xor r8,r0,r8 /* make primary hash */
+
+ /* Search the primary PTEG for a PTE whose 1st (d)word matches r5 */
+ li r0,8 /* PTEs/group */
+ mtctr r0
+ addi r12,r8,-PTE_SIZE
+1: LDPTEu r0,PTE_SIZE(r12) /* get next PTE */
+ CMPPTE 0,r0,r11
+ bdnzf 2,1b /* loop while ctr != 0 && !cr0.eq */
+ beq+ 3f
+
+ /* Search the secondary PTEG for a matching PTE */
+ ori r11,r11,PTE_H /* set H (secondary hash) bit */
+ li r0,8 /* PTEs/group */
+_GLOBAL(flush_hash_patch_B)
+ xoris r12,r8,Hash_msk>>16 /* compute secondary hash */
+ xori r12,r12,(-PTEG_SIZE & 0xffff)
+ addi r12,r12,-PTE_SIZE
+ mtctr r0
+2: LDPTEu r0,PTE_SIZE(r12)
+ CMPPTE 0,r0,r11
+ bdnzf 2,2b
+ xori r11,r11,PTE_H /* clear H again */
+ bne- 4f /* should rarely fail to find it */
+
+3: li r0,0
+ STPTE r0,0(r12) /* invalidate entry */
+4: sync
+ tlbie r4 /* in hw tlb too */
+ sync
+
+8: ble cr1,9f /* if all ptes checked */
+81: addi r6,r6,-1
+ addi r5,r5,4 /* advance to next pte */
+ addi r4,r4,0x1000
+ lwz r0,0(r5) /* check next pte */
+ cmpwi cr1,r6,1
+ andi. r0,r0,_PAGE_HASHPTE
+ bne 33b
+ bgt cr1,81b
+
+9:
+#ifdef CONFIG_SMP
+ TLBSYNC
+ li r0,0
+ stw r0,0(r9) /* clear mmu_hash_lock */
+#endif
+
+19: mtmsr r10
+ SYNC_601
+ isync
+ blr
diff --git a/arch/ppc64/mm/hash_low.S b/arch/powerpc/mm/hash_low_64.S
index ee5a5d36bfa8..d6ed9102eeea 100644
--- a/arch/ppc64/mm/hash_low.S
+++ b/arch/powerpc/mm/hash_low_64.S
@@ -10,7 +10,7 @@
* described in the kernel's COPYING file.
*/
-#include <asm/processor.h>
+#include <asm/reg.h>
#include <asm/pgtable.h>
#include <asm/mmu.h>
#include <asm/page.h>
diff --git a/arch/ppc64/mm/hash_native.c b/arch/powerpc/mm/hash_native_64.c
index bfd385b7713c..174d14576c28 100644
--- a/arch/ppc64/mm/hash_native.c
+++ b/arch/powerpc/mm/hash_native_64.c
@@ -335,10 +335,9 @@ static void native_hpte_clear(void)
local_irq_restore(flags);
}
-static void native_flush_hash_range(unsigned long context,
- unsigned long number, int local)
+static void native_flush_hash_range(unsigned long number, int local)
{
- unsigned long vsid, vpn, va, hash, secondary, slot, flags, avpn;
+ unsigned long va, vpn, hash, secondary, slot, flags, avpn;
int i, j;
hpte_t *hptep;
unsigned long hpte_v;
@@ -349,13 +348,7 @@ static void native_flush_hash_range(unsigned long context,
j = 0;
for (i = 0; i < number; i++) {
- if (batch->addr[i] < KERNELBASE)
- vsid = get_vsid(context, batch->addr[i]);
- else
- vsid = get_kernel_vsid(batch->addr[i]);
-
- va = (vsid << 28) | (batch->addr[i] & 0x0fffffff);
- batch->vaddr[j] = va;
+ va = batch->vaddr[j];
if (large)
vpn = va >> HPAGE_SHIFT;
else
diff --git a/arch/ppc64/mm/hash_utils.c b/arch/powerpc/mm/hash_utils_64.c
index 09475c8edf7c..6e9e05cce02c 100644
--- a/arch/ppc64/mm/hash_utils.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -78,7 +78,7 @@ extern unsigned long dart_tablebase;
hpte_t *htab_address;
unsigned long htab_hash_mask;
-extern unsigned long _SDR1;
+unsigned long _SDR1;
#define KB (1024)
#define MB (1024*KB)
@@ -90,7 +90,6 @@ static inline void loop_forever(void)
;
}
-#ifdef CONFIG_PPC_MULTIPLATFORM
static inline void create_pte_mapping(unsigned long start, unsigned long end,
unsigned long mode, int large)
{
@@ -111,7 +110,7 @@ static inline void create_pte_mapping(unsigned long start, unsigned long end,
unsigned long vpn, hash, hpteg;
unsigned long vsid = get_kernel_vsid(addr);
unsigned long va = (vsid << 28) | (addr & 0xfffffff);
- int ret;
+ int ret = -1;
if (large)
vpn = va >> HPAGE_SHIFT;
@@ -129,16 +128,25 @@ static inline void create_pte_mapping(unsigned long start, unsigned long end,
hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
+#ifdef CONFIG_PPC_ISERIES
+ if (systemcfg->platform & PLATFORM_ISERIES_LPAR)
+ ret = iSeries_hpte_bolt_or_insert(hpteg, va,
+ virt_to_abs(addr) >> PAGE_SHIFT,
+ vflags, tmp_mode);
+ else
+#endif
#ifdef CONFIG_PPC_PSERIES
if (systemcfg->platform & PLATFORM_LPAR)
ret = pSeries_lpar_hpte_insert(hpteg, va,
virt_to_abs(addr) >> PAGE_SHIFT,
vflags, tmp_mode);
else
-#endif /* CONFIG_PPC_PSERIES */
+#endif
+#ifdef CONFIG_PPC_MULTIPLATFORM
ret = native_hpte_insert(hpteg, va,
virt_to_abs(addr) >> PAGE_SHIFT,
vflags, tmp_mode);
+#endif
if (ret == -1) {
ppc64_terminate_msg(0x20, "create_pte_mapping");
@@ -147,6 +155,27 @@ static inline void create_pte_mapping(unsigned long start, unsigned long end,
}
}
+static unsigned long get_hashtable_size(void)
+{
+ unsigned long rnd_mem_size, pteg_count;
+
+ /* If hash size wasn't obtained in prom.c, we calculate it now based on
+ * the total RAM size
+ */
+ if (ppc64_pft_size)
+ return 1UL << ppc64_pft_size;
+
+ /* round mem_size up to next power of 2 */
+ rnd_mem_size = 1UL << __ilog2(systemcfg->physicalMemorySize);
+ if (rnd_mem_size < systemcfg->physicalMemorySize)
+ rnd_mem_size <<= 1;
+
+ /* # pages / 2 */
+ pteg_count = max(rnd_mem_size >> (12 + 1), 1UL << 11);
+
+ return pteg_count << 7;
+}
+
void __init htab_initialize(void)
{
unsigned long table, htab_size_bytes;
@@ -162,7 +191,7 @@ void __init htab_initialize(void)
* Calculate the required size of the htab. We want the number of
* PTEGs to equal one half the number of real pages.
*/
- htab_size_bytes = 1UL << ppc64_pft_size;
+ htab_size_bytes = get_hashtable_size();
pteg_count = htab_size_bytes >> 7;
/* For debug, make the HTAB 1/8 as big as it normally would be. */
@@ -261,7 +290,6 @@ void __init htab_initialize(void)
}
#undef KB
#undef MB
-#endif /* CONFIG_PPC_MULTIPLATFORM */
/*
* Called by asm hashtable.S for doing lazy icache flush
@@ -355,18 +383,11 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
return ret;
}
-void flush_hash_page(unsigned long context, unsigned long ea, pte_t pte,
- int local)
+void flush_hash_page(unsigned long va, pte_t pte, int local)
{
- unsigned long vsid, vpn, va, hash, secondary, slot;
+ unsigned long vpn, hash, secondary, slot;
unsigned long huge = pte_huge(pte);
- if (ea < KERNELBASE)
- vsid = get_vsid(context, ea);
- else
- vsid = get_kernel_vsid(ea);
-
- va = (vsid << 28) | (ea & 0x0fffffff);
if (huge)
vpn = va >> HPAGE_SHIFT;
else
@@ -381,17 +402,17 @@ void flush_hash_page(unsigned long context, unsigned long ea, pte_t pte,
ppc_md.hpte_invalidate(slot, va, huge, local);
}
-void flush_hash_range(unsigned long context, unsigned long number, int local)
+void flush_hash_range(unsigned long number, int local)
{
if (ppc_md.flush_hash_range) {
- ppc_md.flush_hash_range(context, number, local);
+ ppc_md.flush_hash_range(number, local);
} else {
int i;
- struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
+ struct ppc64_tlb_batch *batch =
+ &__get_cpu_var(ppc64_tlb_batch);
for (i = 0; i < number; i++)
- flush_hash_page(context, batch->addr[i], batch->pte[i],
- local);
+ flush_hash_page(batch->vaddr[i], batch->pte[i], local);
}
}
diff --git a/arch/ppc64/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 0ea0994ed974..0ea0994ed974 100644
--- a/arch/ppc64/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
diff --git a/arch/ppc64/mm/imalloc.c b/arch/powerpc/mm/imalloc.c
index c65b87b92756..f4ca29cf5364 100644
--- a/arch/ppc64/mm/imalloc.c
+++ b/arch/powerpc/mm/imalloc.c
@@ -300,12 +300,7 @@ void im_free(void * addr)
for (p = &imlist ; (tmp = *p) ; p = &tmp->next) {
if (tmp->addr == addr) {
*p = tmp->next;
-
- /* XXX: do we need the lock? */
- spin_lock(&init_mm.page_table_lock);
unmap_vm_area(tmp);
- spin_unlock(&init_mm.page_table_lock);
-
kfree(tmp);
up(&imlist_sem);
return;
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
new file mode 100644
index 000000000000..4612a79dfb6e
--- /dev/null
+++ b/arch/powerpc/mm/init_32.c
@@ -0,0 +1,254 @@
+/*
+ * PowerPC version
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ * and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ * Copyright (C) 1996 Paul Mackerras
+ * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ * PPC44x/36-bit changes by Matt Porter (mporter@mvista.com)
+ *
+ * Derived from "arch/i386/mm/init.c"
+ * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
+ *
+ * This program is free software; you can redistribute 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/config.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+#include <linux/initrd.h>
+#include <linux/pagemap.h>
+
+#include <asm/pgalloc.h>
+#include <asm/prom.h>
+#include <asm/io.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/mmu.h>
+#include <asm/smp.h>
+#include <asm/machdep.h>
+#include <asm/btext.h>
+#include <asm/tlb.h>
+#include <asm/prom.h>
+#include <asm/lmb.h>
+#include <asm/sections.h>
+
+#include "mmu_decl.h"
+
+#if defined(CONFIG_KERNEL_START_BOOL) || defined(CONFIG_LOWMEM_SIZE_BOOL)
+/* The ammount of lowmem must be within 0xF0000000 - KERNELBASE. */
+#if (CONFIG_LOWMEM_SIZE > (0xF0000000 - KERNELBASE))
+#error "You must adjust CONFIG_LOWMEM_SIZE or CONFIG_START_KERNEL"
+#endif
+#endif
+#define MAX_LOW_MEM CONFIG_LOWMEM_SIZE
+
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
+
+unsigned long total_memory;
+unsigned long total_lowmem;
+
+unsigned long ppc_memstart;
+unsigned long ppc_memoffset = PAGE_OFFSET;
+
+int boot_mapsize;
+#ifdef CONFIG_PPC_PMAC
+unsigned long agp_special_page;
+EXPORT_SYMBOL(agp_special_page);
+#endif
+
+#ifdef CONFIG_HIGHMEM
+pte_t *kmap_pte;
+pgprot_t kmap_prot;
+
+EXPORT_SYMBOL(kmap_prot);
+EXPORT_SYMBOL(kmap_pte);
+#endif
+
+void MMU_init(void);
+
+/* XXX should be in current.h -- paulus */
+extern struct task_struct *current_set[NR_CPUS];
+
+char *klimit = _end;
+struct device_node *memory_node;
+
+extern int init_bootmem_done;
+
+/*
+ * this tells the system to map all of ram with the segregs
+ * (i.e. page tables) instead of the bats.
+ * -- Cort
+ */
+int __map_without_bats;
+int __map_without_ltlbs;
+
+/* max amount of low RAM to map in */
+unsigned long __max_low_memory = MAX_LOW_MEM;
+
+/*
+ * limit of what is accessible with initial MMU setup -
+ * 256MB usually, but only 16MB on 601.
+ */
+unsigned long __initial_memory_limit = 0x10000000;
+
+/*
+ * Check for command-line options that affect what MMU_init will do.
+ */
+void MMU_setup(void)
+{
+ /* Check for nobats option (used in mapin_ram). */
+ if (strstr(cmd_line, "nobats")) {
+ __map_without_bats = 1;
+ }
+
+ if (strstr(cmd_line, "noltlbs")) {
+ __map_without_ltlbs = 1;
+ }
+}
+
+/*
+ * MMU_init sets up the basic memory mappings for the kernel,
+ * including both RAM and possibly some I/O regions,
+ * and sets up the page tables and the MMU hardware ready to go.
+ */
+void __init MMU_init(void)
+{
+ if (ppc_md.progress)
+ ppc_md.progress("MMU:enter", 0x111);
+
+ /* 601 can only access 16MB at the moment */
+ if (PVR_VER(mfspr(SPRN_PVR)) == 1)
+ __initial_memory_limit = 0x01000000;
+
+ /* parse args from command line */
+ MMU_setup();
+
+ if (lmb.memory.cnt > 1) {
+ lmb.memory.cnt = 1;
+ lmb_analyze();
+ printk(KERN_WARNING "Only using first contiguous memory region");
+ }
+
+ total_memory = lmb_end_of_DRAM();
+ total_lowmem = total_memory;
+
+#ifdef CONFIG_FSL_BOOKE
+ /* Freescale Book-E parts expect lowmem to be mapped by fixed TLB
+ * entries, so we need to adjust lowmem to match the amount we can map
+ * in the fixed entries */
+ adjust_total_lowmem();
+#endif /* CONFIG_FSL_BOOKE */
+
+ if (total_lowmem > __max_low_memory) {
+ total_lowmem = __max_low_memory;
+#ifndef CONFIG_HIGHMEM
+ total_memory = total_lowmem;
+ lmb_enforce_memory_limit(total_lowmem);
+ lmb_analyze();
+#endif /* CONFIG_HIGHMEM */
+ }
+
+ /* Initialize the MMU hardware */
+ if (ppc_md.progress)
+ ppc_md.progress("MMU:hw init", 0x300);
+ MMU_init_hw();
+
+ /* Map in all of RAM starting at KERNELBASE */
+ if (ppc_md.progress)
+ ppc_md.progress("MMU:mapin", 0x301);
+ mapin_ram();
+
+#ifdef CONFIG_HIGHMEM
+ ioremap_base = PKMAP_BASE;
+#else
+ ioremap_base = 0xfe000000UL; /* for now, could be 0xfffff000 */
+#endif /* CONFIG_HIGHMEM */
+ ioremap_bot = ioremap_base;
+
+ /* Map in I/O resources */
+ if (ppc_md.progress)
+ ppc_md.progress("MMU:setio", 0x302);
+ if (ppc_md.setup_io_mappings)
+ ppc_md.setup_io_mappings();
+
+ /* Initialize the context management stuff */
+ mmu_context_init();
+
+ if (ppc_md.progress)
+ ppc_md.progress("MMU:exit", 0x211);
+}
+
+/* This is only called until mem_init is done. */
+void __init *early_get_page(void)
+{
+ void *p;
+
+ if (init_bootmem_done) {
+ p = alloc_bootmem_pages(PAGE_SIZE);
+ } else {
+ p = __va(lmb_alloc_base(PAGE_SIZE, PAGE_SIZE,
+ __initial_memory_limit));
+ }
+ return p;
+}
+
+/* Free up now-unused memory */
+static void free_sec(unsigned long start, unsigned long end, const char *name)
+{
+ unsigned long cnt = 0;
+
+ while (start < end) {
+ ClearPageReserved(virt_to_page(start));
+ set_page_count(virt_to_page(start), 1);
+ free_page(start);
+ cnt++;
+ start += PAGE_SIZE;
+ }
+ if (cnt) {
+ printk(" %ldk %s", cnt << (PAGE_SHIFT - 10), name);
+ totalram_pages += cnt;
+ }
+}
+
+void free_initmem(void)
+{
+#define FREESEC(TYPE) \
+ free_sec((unsigned long)(&__ ## TYPE ## _begin), \
+ (unsigned long)(&__ ## TYPE ## _end), \
+ #TYPE);
+
+ printk ("Freeing unused kernel memory:");
+ FREESEC(init);
+ printk("\n");
+ ppc_md.progress = NULL;
+#undef FREESEC
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+ if (start < end)
+ printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+ for (; start < end; start += PAGE_SIZE) {
+ ClearPageReserved(virt_to_page(start));
+ set_page_count(virt_to_page(start), 1);
+ free_page(start);
+ totalram_pages++;
+ }
+}
+#endif
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
new file mode 100644
index 000000000000..b0fc822ec29f
--- /dev/null
+++ b/arch/powerpc/mm/init_64.c
@@ -0,0 +1,223 @@
+/*
+ * PowerPC version
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ * and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ * Copyright (C) 1996 Paul Mackerras
+ * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ * Derived from "arch/i386/mm/init.c"
+ * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
+ *
+ * Dave Engebretsen <engebret@us.ibm.com>
+ * Rework for PPC64 port.
+ *
+ * This program is free software; you can redistribute 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/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/stddef.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+#include <linux/idr.h>
+#include <linux/nodemask.h>
+#include <linux/module.h>
+
+#include <asm/pgalloc.h>
+#include <asm/page.h>
+#include <asm/prom.h>
+#include <asm/lmb.h>
+#include <asm/rtas.h>
+#include <asm/io.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/mmu.h>
+#include <asm/uaccess.h>
+#include <asm/smp.h>
+#include <asm/machdep.h>
+#include <asm/tlb.h>
+#include <asm/eeh.h>
+#include <asm/processor.h>
+#include <asm/mmzone.h>
+#include <asm/cputable.h>
+#include <asm/ppcdebug.h>
+#include <asm/sections.h>
+#include <asm/system.h>
+#include <asm/iommu.h>
+#include <asm/abs_addr.h>
+#include <asm/vdso.h>
+#include <asm/imalloc.h>
+
+#if PGTABLE_RANGE > USER_VSID_RANGE
+#warning Limited user VSID range means pagetable space is wasted
+#endif
+
+#if (TASK_SIZE_USER64 < PGTABLE_RANGE) && (TASK_SIZE_USER64 < USER_VSID_RANGE)
+#warning TASK_SIZE is smaller than it needs to be.
+#endif
+
+unsigned long klimit = (unsigned long)_end;
+
+/* max amount of RAM to use */
+unsigned long __max_memory;
+
+/* info on what we think the IO hole is */
+unsigned long io_hole_start;
+unsigned long io_hole_size;
+
+/*
+ * Do very early mm setup.
+ */
+void __init mm_init_ppc64(void)
+{
+#ifndef CONFIG_PPC_ISERIES
+ unsigned long i;
+#endif
+
+ ppc64_boot_msg(0x100, "MM Init");
+
+ /* This is the story of the IO hole... please, keep seated,
+ * unfortunately, we are out of oxygen masks at the moment.
+ * So we need some rough way to tell where your big IO hole
+ * is. On pmac, it's between 2G and 4G, on POWER3, it's around
+ * that area as well, on POWER4 we don't have one, etc...
+ * We need that as a "hint" when sizing the TCE table on POWER3
+ * So far, the simplest way that seem work well enough for us it
+ * to just assume that the first discontinuity in our physical
+ * RAM layout is the IO hole. That may not be correct in the future
+ * (and isn't on iSeries but then we don't care ;)
+ */
+
+#ifndef CONFIG_PPC_ISERIES
+ for (i = 1; i < lmb.memory.cnt; i++) {
+ unsigned long base, prevbase, prevsize;
+
+ prevbase = lmb.memory.region[i-1].base;
+ prevsize = lmb.memory.region[i-1].size;
+ base = lmb.memory.region[i].base;
+ if (base > (prevbase + prevsize)) {
+ io_hole_start = prevbase + prevsize;
+ io_hole_size = base - (prevbase + prevsize);
+ break;
+ }
+ }
+#endif /* CONFIG_PPC_ISERIES */
+ if (io_hole_start)
+ printk("IO Hole assumed to be %lx -> %lx\n",
+ io_hole_start, io_hole_start + io_hole_size - 1);
+
+ ppc64_boot_msg(0x100, "MM Init Done");
+}
+
+void free_initmem(void)
+{
+ unsigned long addr;
+
+ addr = (unsigned long)__init_begin;
+ for (; addr < (unsigned long)__init_end; addr += PAGE_SIZE) {
+ memset((void *)addr, 0xcc, PAGE_SIZE);
+ ClearPageReserved(virt_to_page(addr));
+ set_page_count(virt_to_page(addr), 1);
+ free_page(addr);
+ totalram_pages++;
+ }
+ printk ("Freeing unused kernel memory: %luk freed\n",
+ ((unsigned long)__init_end - (unsigned long)__init_begin) >> 10);
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+ if (start < end)
+ printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+ for (; start < end; start += PAGE_SIZE) {
+ ClearPageReserved(virt_to_page(start));
+ set_page_count(virt_to_page(start), 1);
+ free_page(start);
+ totalram_pages++;
+ }
+}
+#endif
+
+static struct kcore_list kcore_vmem;
+
+static int __init setup_kcore(void)
+{
+ int i;
+
+ for (i=0; i < lmb.memory.cnt; i++) {
+ unsigned long base, size;
+ struct kcore_list *kcore_mem;
+
+ base = lmb.memory.region[i].base;
+ size = lmb.memory.region[i].size;
+
+ /* GFP_ATOMIC to avoid might_sleep warnings during boot */
+ kcore_mem = kmalloc(sizeof(struct kcore_list), GFP_ATOMIC);
+ if (!kcore_mem)
+ panic("mem_init: kmalloc failed\n");
+
+ kclist_add(kcore_mem, __va(base), size);
+ }
+
+ kclist_add(&kcore_vmem, (void *)VMALLOC_START, VMALLOC_END-VMALLOC_START);
+
+ return 0;
+}
+module_init(setup_kcore);
+
+static void zero_ctor(void *addr, kmem_cache_t *cache, unsigned long flags)
+{
+ memset(addr, 0, kmem_cache_size(cache));
+}
+
+static const int pgtable_cache_size[2] = {
+ PTE_TABLE_SIZE, PMD_TABLE_SIZE
+};
+static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = {
+ "pgd_pte_cache", "pud_pmd_cache",
+};
+
+kmem_cache_t *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)];
+
+void pgtable_cache_init(void)
+{
+ int i;
+
+ BUILD_BUG_ON(PTE_TABLE_SIZE != pgtable_cache_size[PTE_CACHE_NUM]);
+ BUILD_BUG_ON(PMD_TABLE_SIZE != pgtable_cache_size[PMD_CACHE_NUM]);
+ BUILD_BUG_ON(PUD_TABLE_SIZE != pgtable_cache_size[PUD_CACHE_NUM]);
+ BUILD_BUG_ON(PGD_TABLE_SIZE != pgtable_cache_size[PGD_CACHE_NUM]);
+
+ for (i = 0; i < ARRAY_SIZE(pgtable_cache_size); i++) {
+ int size = pgtable_cache_size[i];
+ const char *name = pgtable_cache_name[i];
+
+ pgtable_cache[i] = kmem_cache_create(name,
+ size, size,
+ SLAB_HWCACHE_ALIGN
+ | SLAB_MUST_HWCACHE_ALIGN,
+ zero_ctor,
+ NULL);
+ if (! pgtable_cache[i])
+ panic("pgtable_cache_init(): could not create %s!\n",
+ name);
+ }
+}
diff --git a/arch/ppc64/kernel/lmb.c b/arch/powerpc/mm/lmb.c
index 5adaca2ddc9d..9b5aa6808eb8 100644
--- a/arch/ppc64/kernel/lmb.c
+++ b/arch/powerpc/mm/lmb.c
@@ -1,5 +1,5 @@
/*
- * Procedures for interfacing to Open Firmware.
+ * Procedures for maintaining information about logical memory blocks.
*
* Peter Bergner, IBM Corp. June 2001.
* Copyright (C) 2001 Peter Bergner.
@@ -18,7 +18,9 @@
#include <asm/page.h>
#include <asm/prom.h>
#include <asm/lmb.h>
-#include <asm/abs_addr.h>
+#ifdef CONFIG_PPC32
+#include "mmu_decl.h" /* for __max_low_memory */
+#endif
struct lmb lmb;
@@ -54,16 +56,14 @@ void lmb_dump_all(void)
#endif /* DEBUG */
}
-static unsigned long __init
-lmb_addrs_overlap(unsigned long base1, unsigned long size1,
- unsigned long base2, unsigned long size2)
+static unsigned long __init lmb_addrs_overlap(unsigned long base1,
+ unsigned long size1, unsigned long base2, unsigned long size2)
{
return ((base1 < (base2+size2)) && (base2 < (base1+size1)));
}
-static long __init
-lmb_addrs_adjacent(unsigned long base1, unsigned long size1,
- unsigned long base2, unsigned long size2)
+static long __init lmb_addrs_adjacent(unsigned long base1, unsigned long size1,
+ unsigned long base2, unsigned long size2)
{
if (base2 == base1 + size1)
return 1;
@@ -73,8 +73,8 @@ lmb_addrs_adjacent(unsigned long base1, unsigned long size1,
return 0;
}
-static long __init
-lmb_regions_adjacent(struct lmb_region *rgn, unsigned long r1, unsigned long r2)
+static long __init lmb_regions_adjacent(struct lmb_region *rgn,
+ unsigned long r1, unsigned long r2)
{
unsigned long base1 = rgn->region[r1].base;
unsigned long size1 = rgn->region[r1].size;
@@ -85,8 +85,8 @@ lmb_regions_adjacent(struct lmb_region *rgn, unsigned long r1, unsigned long r2)
}
/* Assumption: base addr of region 1 < base addr of region 2 */
-static void __init
-lmb_coalesce_regions(struct lmb_region *rgn, unsigned long r1, unsigned long r2)
+static void __init lmb_coalesce_regions(struct lmb_region *rgn,
+ unsigned long r1, unsigned long r2)
{
unsigned long i;
@@ -99,8 +99,7 @@ lmb_coalesce_regions(struct lmb_region *rgn, unsigned long r1, unsigned long r2)
}
/* This routine called with relocation disabled. */
-void __init
-lmb_init(void)
+void __init lmb_init(void)
{
/* Create a dummy zero size LMB which will get coalesced away later.
* This simplifies the lmb_add() code below...
@@ -115,9 +114,8 @@ lmb_init(void)
lmb.reserved.cnt = 1;
}
-/* This routine called with relocation disabled. */
-void __init
-lmb_analyze(void)
+/* This routine may be called with relocation disabled. */
+void __init lmb_analyze(void)
{
int i;
@@ -128,8 +126,8 @@ lmb_analyze(void)
}
/* This routine called with relocation disabled. */
-static long __init
-lmb_add_region(struct lmb_region *rgn, unsigned long base, unsigned long size)
+static long __init lmb_add_region(struct lmb_region *rgn, unsigned long base,
+ unsigned long size)
{
unsigned long i, coalesced = 0;
long adjacent;
@@ -158,18 +156,17 @@ lmb_add_region(struct lmb_region *rgn, unsigned long base, unsigned long size)
coalesced++;
}
- if ( coalesced ) {
+ if (coalesced)
return coalesced;
- } else if ( rgn->cnt >= MAX_LMB_REGIONS ) {
+ if (rgn->cnt >= MAX_LMB_REGIONS)
return -1;
- }
/* Couldn't coalesce the LMB, so add it to the sorted table. */
- for (i=rgn->cnt-1; i >= 0; i--) {
+ for (i = rgn->cnt-1; i >= 0; i--) {
if (base < rgn->region[i].base) {
rgn->region[i+1].base = rgn->region[i].base;
rgn->region[i+1].size = rgn->region[i].size;
- } else {
+ } else {
rgn->region[i+1].base = base;
rgn->region[i+1].size = size;
break;
@@ -180,30 +177,28 @@ lmb_add_region(struct lmb_region *rgn, unsigned long base, unsigned long size)
return 0;
}
-/* This routine called with relocation disabled. */
-long __init
-lmb_add(unsigned long base, unsigned long size)
+/* This routine may be called with relocation disabled. */
+long __init lmb_add(unsigned long base, unsigned long size)
{
struct lmb_region *_rgn = &(lmb.memory);
/* On pSeries LPAR systems, the first LMB is our RMO region. */
- if ( base == 0 )
+ if (base == 0)
lmb.rmo_size = size;
return lmb_add_region(_rgn, base, size);
}
-long __init
-lmb_reserve(unsigned long base, unsigned long size)
+long __init lmb_reserve(unsigned long base, unsigned long size)
{
struct lmb_region *_rgn = &(lmb.reserved);
return lmb_add_region(_rgn, base, size);
}
-long __init
-lmb_overlaps_region(struct lmb_region *rgn, unsigned long base, unsigned long size)
+long __init lmb_overlaps_region(struct lmb_region *rgn, unsigned long base,
+ unsigned long size)
{
unsigned long i;
@@ -218,39 +213,44 @@ lmb_overlaps_region(struct lmb_region *rgn, unsigned long base, unsigned long si
return (i < rgn->cnt) ? i : -1;
}
-unsigned long __init
-lmb_alloc(unsigned long size, unsigned long align)
+unsigned long __init lmb_alloc(unsigned long size, unsigned long align)
{
return lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE);
}
-unsigned long __init
-lmb_alloc_base(unsigned long size, unsigned long align, unsigned long max_addr)
+unsigned long __init lmb_alloc_base(unsigned long size, unsigned long align,
+ unsigned long max_addr)
{
long i, j;
unsigned long base = 0;
- for (i=lmb.memory.cnt-1; i >= 0; i--) {
+#ifdef CONFIG_PPC32
+ /* On 32-bit, make sure we allocate lowmem */
+ if (max_addr == LMB_ALLOC_ANYWHERE)
+ max_addr = __max_low_memory;
+#endif
+ for (i = lmb.memory.cnt-1; i >= 0; i--) {
unsigned long lmbbase = lmb.memory.region[i].base;
unsigned long lmbsize = lmb.memory.region[i].size;
- if ( max_addr == LMB_ALLOC_ANYWHERE )
- base = _ALIGN_DOWN(lmbbase+lmbsize-size, align);
- else if ( lmbbase < max_addr )
- base = _ALIGN_DOWN(min(lmbbase+lmbsize,max_addr)-size, align);
- else
+ if (max_addr == LMB_ALLOC_ANYWHERE)
+ base = _ALIGN_DOWN(lmbbase + lmbsize - size, align);
+ else if (lmbbase < max_addr) {
+ base = min(lmbbase + lmbsize, max_addr);
+ base = _ALIGN_DOWN(base - size, align);
+ } else
continue;
- while ( (lmbbase <= base) &&
- ((j = lmb_overlaps_region(&lmb.reserved,base,size)) >= 0) ) {
- base = _ALIGN_DOWN(lmb.reserved.region[j].base-size, align);
- }
+ while ((lmbbase <= base) &&
+ ((j = lmb_overlaps_region(&lmb.reserved, base, size)) >= 0) )
+ base = _ALIGN_DOWN(lmb.reserved.region[j].base - size,
+ align);
- if ( (base != 0) && (lmbbase <= base) )
+ if ((base != 0) && (lmbbase <= base))
break;
}
- if ( i < 0 )
+ if (i < 0)
return 0;
lmb_add_region(&lmb.reserved, base, size);
@@ -259,14 +259,12 @@ lmb_alloc_base(unsigned long size, unsigned long align, unsigned long max_addr)
}
/* You must call lmb_analyze() before this. */
-unsigned long __init
-lmb_phys_mem_size(void)
+unsigned long __init lmb_phys_mem_size(void)
{
return lmb.memory.size;
}
-unsigned long __init
-lmb_end_of_DRAM(void)
+unsigned long __init lmb_end_of_DRAM(void)
{
int idx = lmb.memory.cnt - 1;
@@ -277,9 +275,8 @@ lmb_end_of_DRAM(void)
* Truncate the lmb list to memory_limit if it's set
* You must call lmb_analyze() after this.
*/
-void __init lmb_enforce_memory_limit(void)
+void __init lmb_enforce_memory_limit(unsigned long memory_limit)
{
- extern unsigned long memory_limit;
unsigned long i, limit;
if (! memory_limit)
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
new file mode 100644
index 000000000000..117b00012e14
--- /dev/null
+++ b/arch/powerpc/mm/mem.c
@@ -0,0 +1,564 @@
+/*
+ * PowerPC version
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ * and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ * Copyright (C) 1996 Paul Mackerras
+ * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ * PPC44x/36-bit changes by Matt Porter (mporter@mvista.com)
+ *
+ * Derived from "arch/i386/mm/init.c"
+ * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
+ *
+ * This program is free software; you can redistribute 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/config.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+#include <linux/initrd.h>
+#include <linux/pagemap.h>
+
+#include <asm/pgalloc.h>
+#include <asm/prom.h>
+#include <asm/io.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/mmu.h>
+#include <asm/smp.h>
+#include <asm/machdep.h>
+#include <asm/btext.h>
+#include <asm/tlb.h>
+#include <asm/prom.h>
+#include <asm/lmb.h>
+#include <asm/sections.h>
+#ifdef CONFIG_PPC64
+#include <asm/vdso.h>
+#endif
+
+#include "mmu_decl.h"
+
+#ifndef CPU_FTR_COHERENT_ICACHE
+#define CPU_FTR_COHERENT_ICACHE 0 /* XXX for now */
+#define CPU_FTR_NOEXECUTE 0
+#endif
+
+int init_bootmem_done;
+int mem_init_done;
+unsigned long memory_limit;
+
+/*
+ * This is called by /dev/mem to know if a given address has to
+ * be mapped non-cacheable or not
+ */
+int page_is_ram(unsigned long pfn)
+{
+ unsigned long paddr = (pfn << PAGE_SHIFT);
+
+#ifndef CONFIG_PPC64 /* XXX for now */
+ return paddr < __pa(high_memory);
+#else
+ int i;
+ for (i=0; i < lmb.memory.cnt; i++) {
+ unsigned long base;
+
+ base = lmb.memory.region[i].base;
+
+ if ((paddr >= base) &&
+ (paddr < (base + lmb.memory.region[i].size))) {
+ return 1;
+ }
+ }
+
+ return 0;
+#endif
+}
+EXPORT_SYMBOL(page_is_ram);
+
+pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+ unsigned long size, pgprot_t vma_prot)
+{
+ if (ppc_md.phys_mem_access_prot)
+ return ppc_md.phys_mem_access_prot(file, pfn, size, vma_prot);
+
+ if (!page_is_ram(pfn))
+ vma_prot = __pgprot(pgprot_val(vma_prot)
+ | _PAGE_GUARDED | _PAGE_NO_CACHE);
+ return vma_prot;
+}
+EXPORT_SYMBOL(phys_mem_access_prot);
+
+#ifdef CONFIG_MEMORY_HOTPLUG
+
+void online_page(struct page *page)
+{
+ ClearPageReserved(page);
+ free_cold_page(page);
+ totalram_pages++;
+ num_physpages++;
+}
+
+/*
+ * This works only for the non-NUMA case. Later, we'll need a lookup
+ * to convert from real physical addresses to nid, that doesn't use
+ * pfn_to_nid().
+ */
+int __devinit add_memory(u64 start, u64 size)
+{
+ struct pglist_data *pgdata = NODE_DATA(0);
+ struct zone *zone;
+ unsigned long start_pfn = start >> PAGE_SHIFT;
+ unsigned long nr_pages = size >> PAGE_SHIFT;
+
+ /* this should work for most non-highmem platforms */
+ zone = pgdata->node_zones;
+
+ return __add_pages(zone, start_pfn, nr_pages);
+
+ return 0;
+}
+
+/*
+ * First pass at this code will check to determine if the remove
+ * request is within the RMO. Do not allow removal within the RMO.
+ */
+int __devinit remove_memory(u64 start, u64 size)
+{
+ struct zone *zone;
+ unsigned long start_pfn, end_pfn, nr_pages;
+
+ start_pfn = start >> PAGE_SHIFT;
+ nr_pages = size >> PAGE_SHIFT;
+ end_pfn = start_pfn + nr_pages;
+
+ printk("%s(): Attempting to remove memoy in range "
+ "%lx to %lx\n", __func__, start, start+size);
+ /*
+ * check for range within RMO
+ */
+ zone = page_zone(pfn_to_page(start_pfn));
+
+ printk("%s(): memory will be removed from "
+ "the %s zone\n", __func__, zone->name);
+
+ /*
+ * not handling removing memory ranges that
+ * overlap multiple zones yet
+ */
+ if (end_pfn > (zone->zone_start_pfn + zone->spanned_pages))
+ goto overlap;
+
+ /* make sure it is NOT in RMO */
+ if ((start < lmb.rmo_size) || ((start+size) < lmb.rmo_size)) {
+ printk("%s(): range to be removed must NOT be in RMO!\n",
+ __func__);
+ goto in_rmo;
+ }
+
+ return __remove_pages(zone, start_pfn, nr_pages);
+
+overlap:
+ printk("%s(): memory range to be removed overlaps "
+ "multiple zones!!!\n", __func__);
+in_rmo:
+ return -1;
+}
+#endif /* CONFIG_MEMORY_HOTPLUG */
+
+void show_mem(void)
+{
+ unsigned long total = 0, reserved = 0;
+ unsigned long shared = 0, cached = 0;
+ unsigned long highmem = 0;
+ struct page *page;
+ pg_data_t *pgdat;
+ unsigned long i;
+
+ printk("Mem-info:\n");
+ show_free_areas();
+ printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
+ for_each_pgdat(pgdat) {
+ unsigned long flags;
+ pgdat_resize_lock(pgdat, &flags);
+ for (i = 0; i < pgdat->node_spanned_pages; i++) {
+ page = pgdat_page_nr(pgdat, i);
+ total++;
+ if (PageHighMem(page))
+ highmem++;
+ if (PageReserved(page))
+ reserved++;
+ else if (PageSwapCache(page))
+ cached++;
+ else if (page_count(page))
+ shared += page_count(page) - 1;
+ }
+ pgdat_resize_unlock(pgdat, &flags);
+ }
+ printk("%ld pages of RAM\n", total);
+#ifdef CONFIG_HIGHMEM
+ printk("%ld pages of HIGHMEM\n", highmem);
+#endif
+ printk("%ld reserved pages\n", reserved);
+ printk("%ld pages shared\n", shared);
+ printk("%ld pages swap cached\n", cached);
+}
+
+/*
+ * Initialize the bootmem system and give it all the memory we
+ * have available. If we are using highmem, we only put the
+ * lowmem into the bootmem system.
+ */
+#ifndef CONFIG_NEED_MULTIPLE_NODES
+void __init do_init_bootmem(void)
+{
+ unsigned long i;
+ unsigned long start, bootmap_pages;
+ unsigned long total_pages;
+ int boot_mapsize;
+
+ max_pfn = total_pages = lmb_end_of_DRAM() >> PAGE_SHIFT;
+#ifdef CONFIG_HIGHMEM
+ total_pages = total_lowmem >> PAGE_SHIFT;
+#endif
+
+ /*
+ * Find an area to use for the bootmem bitmap. Calculate the size of
+ * bitmap required as (Total Memory) / PAGE_SIZE / BITS_PER_BYTE.
+ * Add 1 additional page in case the address isn't page-aligned.
+ */
+ bootmap_pages = bootmem_bootmap_pages(total_pages);
+
+ start = lmb_alloc(bootmap_pages << PAGE_SHIFT, PAGE_SIZE);
+ BUG_ON(!start);
+
+ boot_mapsize = init_bootmem(start >> PAGE_SHIFT, total_pages);
+
+ /* Add all physical memory to the bootmem map, mark each area
+ * present.
+ */
+ for (i = 0; i < lmb.memory.cnt; i++) {
+ unsigned long base = lmb.memory.region[i].base;
+ unsigned long size = lmb_size_bytes(&lmb.memory, i);
+#ifdef CONFIG_HIGHMEM
+ if (base >= total_lowmem)
+ continue;
+ if (base + size > total_lowmem)
+ size = total_lowmem - base;
+#endif
+ free_bootmem(base, size);
+ }
+
+ /* reserve the sections we're already using */
+ for (i = 0; i < lmb.reserved.cnt; i++)
+ reserve_bootmem(lmb.reserved.region[i].base,
+ lmb_size_bytes(&lmb.reserved, i));
+
+ /* XXX need to clip this if using highmem? */
+ for (i = 0; i < lmb.memory.cnt; i++)
+ memory_present(0, lmb_start_pfn(&lmb.memory, i),
+ lmb_end_pfn(&lmb.memory, i));
+ init_bootmem_done = 1;
+}
+
+/*
+ * paging_init() sets up the page tables - in fact we've already done this.
+ */
+void __init paging_init(void)
+{
+ unsigned long zones_size[MAX_NR_ZONES];
+ unsigned long zholes_size[MAX_NR_ZONES];
+ unsigned long total_ram = lmb_phys_mem_size();
+ unsigned long top_of_ram = lmb_end_of_DRAM();
+
+#ifdef CONFIG_HIGHMEM
+ map_page(PKMAP_BASE, 0, 0); /* XXX gross */
+ pkmap_page_table = pte_offset_kernel(pmd_offset(pgd_offset_k
+ (PKMAP_BASE), PKMAP_BASE), PKMAP_BASE);
+ map_page(KMAP_FIX_BEGIN, 0, 0); /* XXX gross */
+ kmap_pte = pte_offset_kernel(pmd_offset(pgd_offset_k
+ (KMAP_FIX_BEGIN), KMAP_FIX_BEGIN), KMAP_FIX_BEGIN);
+ kmap_prot = PAGE_KERNEL;
+#endif /* CONFIG_HIGHMEM */
+
+ printk(KERN_INFO "Top of RAM: 0x%lx, Total RAM: 0x%lx\n",
+ top_of_ram, total_ram);
+ printk(KERN_INFO "Memory hole size: %ldMB\n",
+ (top_of_ram - total_ram) >> 20);
+ /*
+ * All pages are DMA-able so we put them all in the DMA zone.
+ */
+ memset(zones_size, 0, sizeof(zones_size));
+ memset(zholes_size, 0, sizeof(zholes_size));
+
+ zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT;
+ zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT;
+
+#ifdef CONFIG_HIGHMEM
+ zones_size[ZONE_DMA] = total_lowmem >> PAGE_SHIFT;
+ zones_size[ZONE_HIGHMEM] = (total_memory - total_lowmem) >> PAGE_SHIFT;
+ zholes_size[ZONE_HIGHMEM] = (top_of_ram - total_ram) >> PAGE_SHIFT;
+#else
+ zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT;
+ zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT;
+#endif /* CONFIG_HIGHMEM */
+
+ free_area_init_node(0, NODE_DATA(0), zones_size,
+ __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size);
+}
+#endif /* ! CONFIG_NEED_MULTIPLE_NODES */
+
+void __init mem_init(void)
+{
+#ifdef CONFIG_NEED_MULTIPLE_NODES
+ int nid;
+#endif
+ pg_data_t *pgdat;
+ unsigned long i;
+ struct page *page;
+ unsigned long reservedpages = 0, codesize, initsize, datasize, bsssize;
+
+ num_physpages = max_pfn; /* RAM is assumed contiguous */
+ high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
+
+#ifdef CONFIG_NEED_MULTIPLE_NODES
+ for_each_online_node(nid) {
+ if (NODE_DATA(nid)->node_spanned_pages != 0) {
+ printk("freeing bootmem node %x\n", nid);
+ totalram_pages +=
+ free_all_bootmem_node(NODE_DATA(nid));
+ }
+ }
+#else
+ max_mapnr = num_physpages;
+ totalram_pages += free_all_bootmem();
+#endif
+ for_each_pgdat(pgdat) {
+ for (i = 0; i < pgdat->node_spanned_pages; i++) {
+ page = pgdat_page_nr(pgdat, i);
+ if (PageReserved(page))
+ reservedpages++;
+ }
+ }
+
+ codesize = (unsigned long)&_sdata - (unsigned long)&_stext;
+ datasize = (unsigned long)&__init_begin - (unsigned long)&_sdata;
+ initsize = (unsigned long)&__init_end - (unsigned long)&__init_begin;
+ bsssize = (unsigned long)&__bss_stop - (unsigned long)&__bss_start;
+
+#ifdef CONFIG_HIGHMEM
+ {
+ unsigned long pfn, highmem_mapnr;
+
+ highmem_mapnr = total_lowmem >> PAGE_SHIFT;
+ for (pfn = highmem_mapnr; pfn < max_mapnr; ++pfn) {
+ struct page *page = pfn_to_page(pfn);
+
+ ClearPageReserved(page);
+ set_page_count(page, 1);
+ __free_page(page);
+ totalhigh_pages++;
+ }
+ totalram_pages += totalhigh_pages;
+ printk(KERN_INFO "High memory: %luk\n",
+ totalhigh_pages << (PAGE_SHIFT-10));
+ }
+#endif /* CONFIG_HIGHMEM */
+
+ printk(KERN_INFO "Memory: %luk/%luk available (%luk kernel code, "
+ "%luk reserved, %luk data, %luk bss, %luk init)\n",
+ (unsigned long)nr_free_pages() << (PAGE_SHIFT-10),
+ num_physpages << (PAGE_SHIFT-10),
+ codesize >> 10,
+ reservedpages << (PAGE_SHIFT-10),
+ datasize >> 10,
+ bsssize >> 10,
+ initsize >> 10);
+
+ mem_init_done = 1;
+
+#ifdef CONFIG_PPC64
+ /* Initialize the vDSO */
+ vdso_init();
+#endif
+}
+
+/*
+ * This is called when a page has been modified by the kernel.
+ * It just marks the page as not i-cache clean. We do the i-cache
+ * flush later when the page is given to a user process, if necessary.
+ */
+void flush_dcache_page(struct page *page)
+{
+ if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
+ return;
+ /* avoid an atomic op if possible */
+ if (test_bit(PG_arch_1, &page->flags))
+ clear_bit(PG_arch_1, &page->flags);
+}
+EXPORT_SYMBOL(flush_dcache_page);
+
+void flush_dcache_icache_page(struct page *page)
+{
+#ifdef CONFIG_BOOKE
+ void *start = kmap_atomic(page, KM_PPC_SYNC_ICACHE);
+ __flush_dcache_icache(start);
+ kunmap_atomic(start, KM_PPC_SYNC_ICACHE);
+#elif defined(CONFIG_8xx) || defined(CONFIG_PPC64)
+ /* On 8xx there is no need to kmap since highmem is not supported */
+ __flush_dcache_icache(page_address(page));
+#else
+ __flush_dcache_icache_phys(page_to_pfn(page) << PAGE_SHIFT);
+#endif
+
+}
+void clear_user_page(void *page, unsigned long vaddr, struct page *pg)
+{
+ clear_page(page);
+
+ if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
+ return;
+ /*
+ * We shouldnt have to do this, but some versions of glibc
+ * require it (ld.so assumes zero filled pages are icache clean)
+ * - Anton
+ */
+
+ /* avoid an atomic op if possible */
+ if (test_bit(PG_arch_1, &pg->flags))
+ clear_bit(PG_arch_1, &pg->flags);
+}
+EXPORT_SYMBOL(clear_user_page);
+
+void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
+ struct page *pg)
+{
+ copy_page(vto, vfrom);
+
+ /*
+ * We should be able to use the following optimisation, however
+ * there are two problems.
+ * Firstly a bug in some versions of binutils meant PLT sections
+ * were not marked executable.
+ * Secondly the first word in the GOT section is blrl, used
+ * to establish the GOT address. Until recently the GOT was
+ * not marked executable.
+ * - Anton
+ */
+#if 0
+ if (!vma->vm_file && ((vma->vm_flags & VM_EXEC) == 0))
+ return;
+#endif
+
+ if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
+ return;
+
+ /* avoid an atomic op if possible */
+ if (test_bit(PG_arch_1, &pg->flags))
+ clear_bit(PG_arch_1, &pg->flags);
+}
+
+void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
+ unsigned long addr, int len)
+{
+ unsigned long maddr;
+
+ maddr = (unsigned long) kmap(page) + (addr & ~PAGE_MASK);
+ flush_icache_range(maddr, maddr + len);
+ kunmap(page);
+}
+EXPORT_SYMBOL(flush_icache_user_range);
+
+/*
+ * This is called at the end of handling a user page fault, when the
+ * fault has been handled by updating a PTE in the linux page tables.
+ * We use it to preload an HPTE into the hash table corresponding to
+ * the updated linux PTE.
+ *
+ * This must always be called with the mm->page_table_lock held
+ */
+void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
+ pte_t pte)
+{
+ /* handle i-cache coherency */
+ unsigned long pfn = pte_pfn(pte);
+#ifdef CONFIG_PPC32
+ pmd_t *pmd;
+#else
+ unsigned long vsid;
+ void *pgdir;
+ pte_t *ptep;
+ int local = 0;
+ cpumask_t tmp;
+ unsigned long flags;
+#endif
+
+ /* handle i-cache coherency */
+ if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE) &&
+ !cpu_has_feature(CPU_FTR_NOEXECUTE) &&
+ pfn_valid(pfn)) {
+ struct page *page = pfn_to_page(pfn);
+ if (!PageReserved(page)
+ && !test_bit(PG_arch_1, &page->flags)) {
+ if (vma->vm_mm == current->active_mm) {
+#ifdef CONFIG_8xx
+ /* On 8xx, cache control instructions (particularly
+ * "dcbst" from flush_dcache_icache) fault as write
+ * operation if there is an unpopulated TLB entry
+ * for the address in question. To workaround that,
+ * we invalidate the TLB here, thus avoiding dcbst
+ * misbehaviour.
+ */
+ _tlbie(address);
+#endif
+ __flush_dcache_icache((void *) address);
+ } else
+ flush_dcache_icache_page(page);
+ set_bit(PG_arch_1, &page->flags);
+ }
+ }
+
+#ifdef CONFIG_PPC_STD_MMU
+ /* We only want HPTEs for linux PTEs that have _PAGE_ACCESSED set */
+ if (!pte_young(pte) || address >= TASK_SIZE)
+ return;
+#ifdef CONFIG_PPC32
+ if (Hash == 0)
+ return;
+ pmd = pmd_offset(pgd_offset(vma->vm_mm, address), address);
+ if (!pmd_none(*pmd))
+ add_hash_page(vma->vm_mm->context, address, pmd_val(*pmd));
+#else
+ pgdir = vma->vm_mm->pgd;
+ if (pgdir == NULL)
+ return;
+
+ ptep = find_linux_pte(pgdir, address);
+ if (!ptep)
+ return;
+
+ vsid = get_vsid(vma->vm_mm->context.id, address);
+
+ local_irq_save(flags);
+ tmp = cpumask_of_cpu(smp_processor_id());
+ if (cpus_equal(vma->vm_mm->cpu_vm_mask, tmp))
+ local = 1;
+
+ __hash_page(address, 0, vsid, ptep, 0x300, local);
+ local_irq_restore(flags);
+#endif
+#endif
+}
diff --git a/arch/ppc64/mm/mmap.c b/arch/powerpc/mm/mmap.c
index fe65f522aff3..fe65f522aff3 100644
--- a/arch/ppc64/mm/mmap.c
+++ b/arch/powerpc/mm/mmap.c
diff --git a/arch/powerpc/mm/mmu_context_32.c b/arch/powerpc/mm/mmu_context_32.c
new file mode 100644
index 000000000000..a8816e0f6a86
--- /dev/null
+++ b/arch/powerpc/mm/mmu_context_32.c
@@ -0,0 +1,86 @@
+/*
+ * This file contains the routines for handling the MMU on those
+ * PowerPC implementations where the MMU substantially follows the
+ * architecture specification. This includes the 6xx, 7xx, 7xxx,
+ * 8260, and POWER3 implementations but excludes the 8xx and 4xx.
+ * -- paulus
+ *
+ * Derived from arch/ppc/mm/init.c:
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ * and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ * Copyright (C) 1996 Paul Mackerras
+ * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ * Derived from "arch/i386/mm/init.c"
+ * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
+ *
+ * This program is free software; you can redistribute 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/config.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/mmu_context.h>
+#include <asm/tlbflush.h>
+
+mm_context_t next_mmu_context;
+unsigned long context_map[LAST_CONTEXT / BITS_PER_LONG + 1];
+#ifdef FEW_CONTEXTS
+atomic_t nr_free_contexts;
+struct mm_struct *context_mm[LAST_CONTEXT+1];
+void steal_context(void);
+#endif /* FEW_CONTEXTS */
+
+/*
+ * Initialize the context management stuff.
+ */
+void __init
+mmu_context_init(void)
+{
+ /*
+ * Some processors have too few contexts to reserve one for
+ * init_mm, and require using context 0 for a normal task.
+ * Other processors reserve the use of context zero for the kernel.
+ * This code assumes FIRST_CONTEXT < 32.
+ */
+ context_map[0] = (1 << FIRST_CONTEXT) - 1;
+ next_mmu_context = FIRST_CONTEXT;
+#ifdef FEW_CONTEXTS
+ atomic_set(&nr_free_contexts, LAST_CONTEXT - FIRST_CONTEXT + 1);
+#endif /* FEW_CONTEXTS */
+}
+
+#ifdef FEW_CONTEXTS
+/*
+ * Steal a context from a task that has one at the moment.
+ * This is only used on 8xx and 4xx and we presently assume that
+ * they don't do SMP. If they do then this will have to check
+ * whether the MM we steal is in use.
+ * We also assume that this is only used on systems that don't
+ * use an MMU hash table - this is true for 8xx and 4xx.
+ * This isn't an LRU system, it just frees up each context in
+ * turn (sort-of pseudo-random replacement :). This would be the
+ * place to implement an LRU scheme if anyone was motivated to do it.
+ * -- paulus
+ */
+void
+steal_context(void)
+{
+ struct mm_struct *mm;
+
+ /* free up context `next_mmu_context' */
+ /* if we shouldn't free context 0, don't... */
+ if (next_mmu_context < FIRST_CONTEXT)
+ next_mmu_context = FIRST_CONTEXT;
+ mm = context_mm[next_mmu_context];
+ flush_tlb_mm(mm);
+ destroy_context(mm);
+}
+#endif /* FEW_CONTEXTS */
diff --git a/arch/powerpc/mm/mmu_context_64.c b/arch/powerpc/mm/mmu_context_64.c
new file mode 100644
index 000000000000..714a84dd8d5d
--- /dev/null
+++ b/arch/powerpc/mm/mmu_context_64.c
@@ -0,0 +1,63 @@
+/*
+ * MMU context allocation for 64-bit kernels.
+ *
+ * Copyright (C) 2004 Anton Blanchard, IBM Corp. <anton@samba.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/config.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/spinlock.h>
+#include <linux/idr.h>
+
+#include <asm/mmu_context.h>
+
+static DEFINE_SPINLOCK(mmu_context_lock);
+static DEFINE_IDR(mmu_context_idr);
+
+int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+ int index;
+ int err;
+
+again:
+ if (!idr_pre_get(&mmu_context_idr, GFP_KERNEL))
+ return -ENOMEM;
+
+ spin_lock(&mmu_context_lock);
+ err = idr_get_new_above(&mmu_context_idr, NULL, 1, &index);
+ spin_unlock(&mmu_context_lock);
+
+ if (err == -EAGAIN)
+ goto again;
+ else if (err)
+ return err;
+
+ if (index > MAX_CONTEXT) {
+ idr_remove(&mmu_context_idr, index);
+ return -ENOMEM;
+ }
+
+ mm->context.id = index;
+
+ return 0;
+}
+
+void destroy_context(struct mm_struct *mm)
+{
+ spin_lock(&mmu_context_lock);
+ idr_remove(&mmu_context_idr, mm->context.id);
+ spin_unlock(&mmu_context_lock);
+
+ mm->context.id = NO_CONTEXT;
+}
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
new file mode 100644
index 000000000000..a4d7a327c0e5
--- /dev/null
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -0,0 +1,87 @@
+/*
+ * Declarations of procedures and variables shared between files
+ * in arch/ppc/mm/.
+ *
+ * Derived from arch/ppc/mm/init.c:
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ * and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ * Copyright (C) 1996 Paul Mackerras
+ * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ * Derived from "arch/i386/mm/init.c"
+ * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
+ *
+ * This program is free software; you can redistribute 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/tlbflush.h>
+#include <asm/mmu.h>
+
+#ifdef CONFIG_PPC32
+extern void mapin_ram(void);
+extern int map_page(unsigned long va, phys_addr_t pa, int flags);
+extern void setbat(int index, unsigned long virt, unsigned long phys,
+ unsigned int size, int flags);
+extern void settlbcam(int index, unsigned long virt, phys_addr_t phys,
+ unsigned int size, int flags, unsigned int pid);
+extern void invalidate_tlbcam_entry(int index);
+
+extern int __map_without_bats;
+extern unsigned long ioremap_base;
+extern unsigned long ioremap_bot;
+extern unsigned int rtas_data, rtas_size;
+
+extern PTE *Hash, *Hash_end;
+extern unsigned long Hash_size, Hash_mask;
+
+extern unsigned int num_tlbcam_entries;
+#endif
+
+extern unsigned long __max_low_memory;
+extern unsigned long __initial_memory_limit;
+extern unsigned long total_memory;
+extern unsigned long total_lowmem;
+
+/* ...and now those things that may be slightly different between processor
+ * architectures. -- Dan
+ */
+#if defined(CONFIG_8xx)
+#define flush_HPTE(X, va, pg) _tlbie(va)
+#define MMU_init_hw() do { } while(0)
+#define mmu_mapin_ram() (0UL)
+
+#elif defined(CONFIG_4xx)
+#define flush_HPTE(X, va, pg) _tlbie(va)
+extern void MMU_init_hw(void);
+extern unsigned long mmu_mapin_ram(void);
+
+#elif defined(CONFIG_FSL_BOOKE)
+#define flush_HPTE(X, va, pg) _tlbie(va)
+extern void MMU_init_hw(void);
+extern unsigned long mmu_mapin_ram(void);
+extern void adjust_total_lowmem(void);
+
+#elif defined(CONFIG_PPC32)
+/* anything 32-bit except 4xx or 8xx */
+extern void MMU_init_hw(void);
+extern unsigned long mmu_mapin_ram(void);
+
+/* Be careful....this needs to be updated if we ever encounter 603 SMPs,
+ * which includes all new 82xx processors. We need tlbie/tlbsync here
+ * in that case (I think). -- Dan.
+ */
+static inline void flush_HPTE(unsigned context, unsigned long va,
+ unsigned long pdval)
+{
+ if ((Hash != 0) &&
+ cpu_has_feature(CPU_FTR_HPTE_TABLE))
+ flush_hash_pages(0, va, pdval, 1);
+ else
+ _tlbie(va);
+}
+#endif
diff --git a/arch/ppc64/mm/numa.c b/arch/powerpc/mm/numa.c
index cb864b8f2750..4035cad8d7f1 100644
--- a/arch/ppc64/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -20,6 +20,7 @@
#include <asm/lmb.h>
#include <asm/machdep.h>
#include <asm/abs_addr.h>
+#include <asm/system.h>
static int numa_enabled = 1;
@@ -300,7 +301,6 @@ static unsigned long __init numa_enforce_memory_limit(unsigned long start, unsig
* we've already adjusted it for the limit and it takes care of
* having memory holes below the limit.
*/
- extern unsigned long memory_limit;
if (! memory_limit)
return size;
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
new file mode 100644
index 000000000000..f4e5ac122615
--- /dev/null
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -0,0 +1,467 @@
+/*
+ * This file contains the routines setting up the linux page tables.
+ * -- paulus
+ *
+ * Derived from arch/ppc/mm/init.c:
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ * and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ * Copyright (C) 1996 Paul Mackerras
+ * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ * Derived from "arch/i386/mm/init.c"
+ * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
+ *
+ * This program is free software; you can redistribute 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/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/highmem.h>
+
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/io.h>
+
+#include "mmu_decl.h"
+
+unsigned long ioremap_base;
+unsigned long ioremap_bot;
+int io_bat_index;
+
+#if defined(CONFIG_6xx) || defined(CONFIG_POWER3)
+#define HAVE_BATS 1
+#endif
+
+#if defined(CONFIG_FSL_BOOKE)
+#define HAVE_TLBCAM 1
+#endif
+
+extern char etext[], _stext[];
+
+#ifdef CONFIG_SMP
+extern void hash_page_sync(void);
+#endif
+
+#ifdef HAVE_BATS
+extern unsigned long v_mapped_by_bats(unsigned long va);
+extern unsigned long p_mapped_by_bats(unsigned long pa);
+void setbat(int index, unsigned long virt, unsigned long phys,
+ unsigned int size, int flags);
+
+#else /* !HAVE_BATS */
+#define v_mapped_by_bats(x) (0UL)
+#define p_mapped_by_bats(x) (0UL)
+#endif /* HAVE_BATS */
+
+#ifdef HAVE_TLBCAM
+extern unsigned int tlbcam_index;
+extern unsigned long v_mapped_by_tlbcam(unsigned long va);
+extern unsigned long p_mapped_by_tlbcam(unsigned long pa);
+#else /* !HAVE_TLBCAM */
+#define v_mapped_by_tlbcam(x) (0UL)
+#define p_mapped_by_tlbcam(x) (0UL)
+#endif /* HAVE_TLBCAM */
+
+#ifdef CONFIG_PTE_64BIT
+/* 44x uses an 8kB pgdir because it has 8-byte Linux PTEs. */
+#define PGDIR_ORDER 1
+#else
+#define PGDIR_ORDER 0
+#endif
+
+pgd_t *pgd_alloc(struct mm_struct *mm)
+{
+ pgd_t *ret;
+
+ ret = (pgd_t *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, PGDIR_ORDER);
+ return ret;
+}
+
+void pgd_free(pgd_t *pgd)
+{
+ free_pages((unsigned long)pgd, PGDIR_ORDER);
+}
+
+pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
+{
+ pte_t *pte;
+ extern int mem_init_done;
+ extern void *early_get_page(void);
+
+ if (mem_init_done) {
+ pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
+ } else {
+ pte = (pte_t *)early_get_page();
+ if (pte)
+ clear_page(pte);
+ }
+ return pte;
+}
+
+struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
+{
+ struct page *ptepage;
+
+#ifdef CONFIG_HIGHPTE
+ gfp_t flags = GFP_KERNEL | __GFP_HIGHMEM | __GFP_REPEAT;
+#else
+ gfp_t flags = GFP_KERNEL | __GFP_REPEAT;
+#endif
+
+ ptepage = alloc_pages(flags, 0);
+ if (ptepage)
+ clear_highpage(ptepage);
+ return ptepage;
+}
+
+void pte_free_kernel(pte_t *pte)
+{
+#ifdef CONFIG_SMP
+ hash_page_sync();
+#endif
+ free_page((unsigned long)pte);
+}
+
+void pte_free(struct page *ptepage)
+{
+#ifdef CONFIG_SMP
+ hash_page_sync();
+#endif
+ __free_page(ptepage);
+}
+
+#ifndef CONFIG_PHYS_64BIT
+void __iomem *
+ioremap(phys_addr_t addr, unsigned long size)
+{
+ return __ioremap(addr, size, _PAGE_NO_CACHE);
+}
+#else /* CONFIG_PHYS_64BIT */
+void __iomem *
+ioremap64(unsigned long long addr, unsigned long size)
+{
+ return __ioremap(addr, size, _PAGE_NO_CACHE);
+}
+
+void __iomem *
+ioremap(phys_addr_t addr, unsigned long size)
+{
+ phys_addr_t addr64 = fixup_bigphys_addr(addr, size);
+
+ return ioremap64(addr64, size);
+}
+#endif /* CONFIG_PHYS_64BIT */
+
+void __iomem *
+__ioremap(phys_addr_t addr, unsigned long size, unsigned long flags)
+{
+ unsigned long v, i;
+ phys_addr_t p;
+ int err;
+
+ /*
+ * Choose an address to map it to.
+ * Once the vmalloc system is running, we use it.
+ * Before then, we use space going down from ioremap_base
+ * (ioremap_bot records where we're up to).
+ */
+ p = addr & PAGE_MASK;
+ size = PAGE_ALIGN(addr + size) - p;
+
+ /*
+ * If the address lies within the first 16 MB, assume it's in ISA
+ * memory space
+ */
+ if (p < 16*1024*1024)
+ p += _ISA_MEM_BASE;
+
+ /*
+ * Don't allow anybody to remap normal RAM that we're using.
+ * mem_init() sets high_memory so only do the check after that.
+ */
+ if (mem_init_done && (p < virt_to_phys(high_memory))) {
+ printk("__ioremap(): phys addr "PHYS_FMT" is RAM lr %p\n", p,
+ __builtin_return_address(0));
+ return NULL;
+ }
+
+ if (size == 0)
+ return NULL;
+
+ /*
+ * Is it already mapped? Perhaps overlapped by a previous
+ * BAT mapping. If the whole area is mapped then we're done,
+ * otherwise remap it since we want to keep the virt addrs for
+ * each request contiguous.
+ *
+ * We make the assumption here that if the bottom and top
+ * of the range we want are mapped then it's mapped to the
+ * same virt address (and this is contiguous).
+ * -- Cort
+ */
+ if ((v = p_mapped_by_bats(p)) /*&& p_mapped_by_bats(p+size-1)*/ )
+ goto out;
+
+ if ((v = p_mapped_by_tlbcam(p)))
+ goto out;
+
+ if (mem_init_done) {
+ struct vm_struct *area;
+ area = get_vm_area(size, VM_IOREMAP);
+ if (area == 0)
+ return NULL;
+ v = (unsigned long) area->addr;
+ } else {
+ v = (ioremap_bot -= size);
+ }
+
+ if ((flags & _PAGE_PRESENT) == 0)
+ flags |= _PAGE_KERNEL;
+ if (flags & _PAGE_NO_CACHE)
+ flags |= _PAGE_GUARDED;
+
+ /*
+ * Should check if it is a candidate for a BAT mapping
+ */
+
+ err = 0;
+ for (i = 0; i < size && err == 0; i += PAGE_SIZE)
+ err = map_page(v+i, p+i, flags);
+ if (err) {
+ if (mem_init_done)
+ vunmap((void *)v);
+ return NULL;
+ }
+
+out:
+ return (void __iomem *) (v + ((unsigned long)addr & ~PAGE_MASK));
+}
+
+void iounmap(volatile void __iomem *addr)
+{
+ /*
+ * If mapped by BATs then there is nothing to do.
+ * Calling vfree() generates a benign warning.
+ */
+ if (v_mapped_by_bats((unsigned long)addr)) return;
+
+ if (addr > high_memory && (unsigned long) addr < ioremap_bot)
+ vunmap((void *) (PAGE_MASK & (unsigned long)addr));
+}
+
+void __iomem *ioport_map(unsigned long port, unsigned int len)
+{
+ return (void __iomem *) (port + _IO_BASE);
+}
+
+void ioport_unmap(void __iomem *addr)
+{
+ /* Nothing to do */
+}
+EXPORT_SYMBOL(ioport_map);
+EXPORT_SYMBOL(ioport_unmap);
+
+int
+map_page(unsigned long va, phys_addr_t pa, int flags)
+{
+ pmd_t *pd;
+ pte_t *pg;
+ int err = -ENOMEM;
+
+ /* Use upper 10 bits of VA to index the first level map */
+ pd = pmd_offset(pgd_offset_k(va), va);
+ /* Use middle 10 bits of VA to index the second-level map */
+ pg = pte_alloc_kernel(pd, va);
+ if (pg != 0) {
+ err = 0;
+ set_pte_at(&init_mm, va, pg, pfn_pte(pa >> PAGE_SHIFT, __pgprot(flags)));
+ if (mem_init_done)
+ flush_HPTE(0, va, pmd_val(*pd));
+ }
+ return err;
+}
+
+/*
+ * Map in all of physical memory starting at KERNELBASE.
+ */
+void __init mapin_ram(void)
+{
+ unsigned long v, p, s, f;
+
+ s = mmu_mapin_ram();
+ v = KERNELBASE + s;
+ p = PPC_MEMSTART + s;
+ for (; s < total_lowmem; s += PAGE_SIZE) {
+ if ((char *) v >= _stext && (char *) v < etext)
+ f = _PAGE_RAM_TEXT;
+ else
+ f = _PAGE_RAM;
+ map_page(v, p, f);
+ v += PAGE_SIZE;
+ p += PAGE_SIZE;
+ }
+}
+
+/* is x a power of 2? */
+#define is_power_of_2(x) ((x) != 0 && (((x) & ((x) - 1)) == 0))
+
+/* is x a power of 4? */
+#define is_power_of_4(x) ((x) != 0 && (((x) & (x-1)) == 0) && (ffs(x) & 1))
+
+/*
+ * Set up a mapping for a block of I/O.
+ * virt, phys, size must all be page-aligned.
+ * This should only be called before ioremap is called.
+ */
+void __init io_block_mapping(unsigned long virt, phys_addr_t phys,
+ unsigned int size, int flags)
+{
+ int i;
+
+ if (virt > KERNELBASE && virt < ioremap_bot)
+ ioremap_bot = ioremap_base = virt;
+
+#ifdef HAVE_BATS
+ /*
+ * Use a BAT for this if possible...
+ */
+ if (io_bat_index < 2 && is_power_of_2(size)
+ && (virt & (size - 1)) == 0 && (phys & (size - 1)) == 0) {
+ setbat(io_bat_index, virt, phys, size, flags);
+ ++io_bat_index;
+ return;
+ }
+#endif /* HAVE_BATS */
+
+#ifdef HAVE_TLBCAM
+ /*
+ * Use a CAM for this if possible...
+ */
+ if (tlbcam_index < num_tlbcam_entries && is_power_of_4(size)
+ && (virt & (size - 1)) == 0 && (phys & (size - 1)) == 0) {
+ settlbcam(tlbcam_index, virt, phys, size, flags, 0);
+ ++tlbcam_index;
+ return;
+ }
+#endif /* HAVE_TLBCAM */
+
+ /* No BATs available, put it in the page tables. */
+ for (i = 0; i < size; i += PAGE_SIZE)
+ map_page(virt + i, phys + i, flags);
+}
+
+/* Scan the real Linux page tables and return a PTE pointer for
+ * a virtual address in a context.
+ * Returns true (1) if PTE was found, zero otherwise. The pointer to
+ * the PTE pointer is unmodified if PTE is not found.
+ */
+int
+get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep)
+{
+ pgd_t *pgd;
+ pmd_t *pmd;
+ pte_t *pte;
+ int retval = 0;
+
+ pgd = pgd_offset(mm, addr & PAGE_MASK);
+ if (pgd) {
+ pmd = pmd_offset(pgd, addr & PAGE_MASK);
+ if (pmd_present(*pmd)) {
+ pte = pte_offset_map(pmd, addr & PAGE_MASK);
+ if (pte) {
+ retval = 1;
+ *ptep = pte;
+ /* XXX caller needs to do pte_unmap, yuck */
+ }
+ }
+ }
+ return(retval);
+}
+
+/* Find physical address for this virtual address. Normally used by
+ * I/O functions, but anyone can call it.
+ */
+unsigned long iopa(unsigned long addr)
+{
+ unsigned long pa;
+
+ /* I don't know why this won't work on PMacs or CHRP. It
+ * appears there is some bug, or there is some implicit
+ * mapping done not properly represented by BATs or in page
+ * tables.......I am actively working on resolving this, but
+ * can't hold up other stuff. -- Dan
+ */
+ pte_t *pte;
+ struct mm_struct *mm;
+
+ /* Check the BATs */
+ pa = v_mapped_by_bats(addr);
+ if (pa)
+ return pa;
+
+ /* Allow mapping of user addresses (within the thread)
+ * for DMA if necessary.
+ */
+ if (addr < TASK_SIZE)
+ mm = current->mm;
+ else
+ mm = &init_mm;
+
+ pa = 0;
+ if (get_pteptr(mm, addr, &pte)) {
+ pa = (pte_val(*pte) & PAGE_MASK) | (addr & ~PAGE_MASK);
+ pte_unmap(pte);
+ }
+
+ return(pa);
+}
+
+/* This is will find the virtual address for a physical one....
+ * Swiped from APUS, could be dangerous :-).
+ * This is only a placeholder until I really find a way to make this
+ * work. -- Dan
+ */
+unsigned long
+mm_ptov (unsigned long paddr)
+{
+ unsigned long ret;
+#if 0
+ if (paddr < 16*1024*1024)
+ ret = ZTWO_VADDR(paddr);
+ else {
+ int i;
+
+ for (i = 0; i < kmap_chunk_count;){
+ unsigned long phys = kmap_chunks[i++];
+ unsigned long size = kmap_chunks[i++];
+ unsigned long virt = kmap_chunks[i++];
+ if (paddr >= phys
+ && paddr < (phys + size)){
+ ret = virt + paddr - phys;
+ goto exit;
+ }
+ }
+
+ ret = (unsigned long) __va(paddr);
+ }
+exit:
+#ifdef DEBUGPV
+ printk ("PTOV(%lx)=%lx\n", paddr, ret);
+#endif
+#else
+ ret = (unsigned long)paddr + KERNELBASE;
+#endif
+ return ret;
+}
+
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
new file mode 100644
index 000000000000..b79a78206135
--- /dev/null
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -0,0 +1,347 @@
+/*
+ * This file contains ioremap and related functions for 64-bit machines.
+ *
+ * Derived from arch/ppc64/mm/init.c
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modifications by Paul Mackerras (PowerMac) (paulus@samba.org)
+ * and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ * Copyright (C) 1996 Paul Mackerras
+ * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ * Derived from "arch/i386/mm/init.c"
+ * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
+ *
+ * Dave Engebretsen <engebret@us.ibm.com>
+ * Rework for PPC64 port.
+ *
+ * This program is free software; you can redistribute 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/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/stddef.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+#include <linux/idr.h>
+#include <linux/nodemask.h>
+#include <linux/module.h>
+
+#include <asm/pgalloc.h>
+#include <asm/page.h>
+#include <asm/prom.h>
+#include <asm/lmb.h>
+#include <asm/rtas.h>
+#include <asm/io.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/mmu.h>
+#include <asm/uaccess.h>
+#include <asm/smp.h>
+#include <asm/machdep.h>
+#include <asm/tlb.h>
+#include <asm/eeh.h>
+#include <asm/processor.h>
+#include <asm/mmzone.h>
+#include <asm/cputable.h>
+#include <asm/ppcdebug.h>
+#include <asm/sections.h>
+#include <asm/system.h>
+#include <asm/iommu.h>
+#include <asm/abs_addr.h>
+#include <asm/vdso.h>
+#include <asm/imalloc.h>
+
+unsigned long ioremap_bot = IMALLOC_BASE;
+static unsigned long phbs_io_bot = PHBS_IO_BASE;
+
+#ifdef CONFIG_PPC_ISERIES
+
+void __iomem *ioremap(unsigned long addr, unsigned long size)
+{
+ return (void __iomem *)addr;
+}
+
+extern void __iomem *__ioremap(unsigned long addr, unsigned long size,
+ unsigned long flags)
+{
+ return (void __iomem *)addr;
+}
+
+void iounmap(volatile void __iomem *addr)
+{
+ return;
+}
+
+#else
+
+/*
+ * map_io_page currently only called by __ioremap
+ * map_io_page adds an entry to the ioremap page table
+ * and adds an entry to the HPT, possibly bolting it
+ */
+static int map_io_page(unsigned long ea, unsigned long pa, int flags)
+{
+ pgd_t *pgdp;
+ pud_t *pudp;
+ pmd_t *pmdp;
+ pte_t *ptep;
+ unsigned long vsid;
+
+ if (mem_init_done) {
+ pgdp = pgd_offset_k(ea);
+ pudp = pud_alloc(&init_mm, pgdp, ea);
+ if (!pudp)
+ return -ENOMEM;
+ pmdp = pmd_alloc(&init_mm, pudp, ea);
+ if (!pmdp)
+ return -ENOMEM;
+ ptep = pte_alloc_kernel(pmdp, ea);
+ if (!ptep)
+ return -ENOMEM;
+ set_pte_at(&init_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT,
+ __pgprot(flags)));
+ } else {
+ unsigned long va, vpn, hash, hpteg;
+
+ /*
+ * If the mm subsystem is not fully up, we cannot create a
+ * linux page table entry for this mapping. Simply bolt an
+ * entry in the hardware page table.
+ */
+ vsid = get_kernel_vsid(ea);
+ va = (vsid << 28) | (ea & 0xFFFFFFF);
+ vpn = va >> PAGE_SHIFT;
+
+ hash = hpt_hash(vpn, 0);
+
+ hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
+
+ /* Panic if a pte grpup is full */
+ if (ppc_md.hpte_insert(hpteg, va, pa >> PAGE_SHIFT,
+ HPTE_V_BOLTED,
+ _PAGE_NO_CACHE|_PAGE_GUARDED|PP_RWXX)
+ == -1) {
+ panic("map_io_page: could not insert mapping");
+ }
+ }
+ return 0;
+}
+
+
+static void __iomem * __ioremap_com(unsigned long addr, unsigned long pa,
+ unsigned long ea, unsigned long size,
+ unsigned long flags)
+{
+ unsigned long i;
+
+ if ((flags & _PAGE_PRESENT) == 0)
+ flags |= pgprot_val(PAGE_KERNEL);
+
+ for (i = 0; i < size; i += PAGE_SIZE)
+ if (map_io_page(ea+i, pa+i, flags))
+ return NULL;
+
+ return (void __iomem *) (ea + (addr & ~PAGE_MASK));
+}
+
+
+void __iomem *
+ioremap(unsigned long addr, unsigned long size)
+{
+ return __ioremap(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED);
+}
+
+void __iomem * __ioremap(unsigned long addr, unsigned long size,
+ unsigned long flags)
+{
+ unsigned long pa, ea;
+ void __iomem *ret;
+
+ /*
+ * Choose an address to map it to.
+ * Once the imalloc system is running, we use it.
+ * Before that, we map using addresses going
+ * up from ioremap_bot. imalloc will use
+ * the addresses from ioremap_bot through
+ * IMALLOC_END
+ *
+ */
+ pa = addr & PAGE_MASK;
+ size = PAGE_ALIGN(addr + size) - pa;
+
+ if (size == 0)
+ return NULL;
+
+ if (mem_init_done) {
+ struct vm_struct *area;
+ area = im_get_free_area(size);
+ if (area == NULL)
+ return NULL;
+ ea = (unsigned long)(area->addr);
+ ret = __ioremap_com(addr, pa, ea, size, flags);
+ if (!ret)
+ im_free(area->addr);
+ } else {
+ ea = ioremap_bot;
+ ret = __ioremap_com(addr, pa, ea, size, flags);
+ if (ret)
+ ioremap_bot += size;
+ }
+ return ret;
+}
+
+#define IS_PAGE_ALIGNED(_val) ((_val) == ((_val) & PAGE_MASK))
+
+int __ioremap_explicit(unsigned long pa, unsigned long ea,
+ unsigned long size, unsigned long flags)
+{
+ struct vm_struct *area;
+ void __iomem *ret;
+
+ /* For now, require page-aligned values for pa, ea, and size */
+ if (!IS_PAGE_ALIGNED(pa) || !IS_PAGE_ALIGNED(ea) ||
+ !IS_PAGE_ALIGNED(size)) {
+ printk(KERN_ERR "unaligned value in %s\n", __FUNCTION__);
+ return 1;
+ }
+
+ if (!mem_init_done) {
+ /* Two things to consider in this case:
+ * 1) No records will be kept (imalloc, etc) that the region
+ * has been remapped
+ * 2) It won't be easy to iounmap() the region later (because
+ * of 1)
+ */
+ ;
+ } else {
+ area = im_get_area(ea, size,
+ IM_REGION_UNUSED|IM_REGION_SUBSET|IM_REGION_EXISTS);
+ if (area == NULL) {
+ /* Expected when PHB-dlpar is in play */
+ return 1;
+ }
+ if (ea != (unsigned long) area->addr) {
+ printk(KERN_ERR "unexpected addr return from "
+ "im_get_area\n");
+ return 1;
+ }
+ }
+
+ ret = __ioremap_com(pa, pa, ea, size, flags);
+ if (ret == NULL) {
+ printk(KERN_ERR "ioremap_explicit() allocation failure !\n");
+ return 1;
+ }
+ if (ret != (void *) ea) {
+ printk(KERN_ERR "__ioremap_com() returned unexpected addr\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+/*
+ * Unmap an IO region and remove it from imalloc'd list.
+ * Access to IO memory should be serialized by driver.
+ * This code is modeled after vmalloc code - unmap_vm_area()
+ *
+ * XXX what about calls before mem_init_done (ie python_countermeasures())
+ */
+void iounmap(volatile void __iomem *token)
+{
+ void *addr;
+
+ if (!mem_init_done)
+ return;
+
+ addr = (void *) ((unsigned long __force) token & PAGE_MASK);
+
+ im_free(addr);
+}
+
+static int iounmap_subset_regions(unsigned long addr, unsigned long size)
+{
+ struct vm_struct *area;
+
+ /* Check whether subsets of this region exist */
+ area = im_get_area(addr, size, IM_REGION_SUPERSET);
+ if (area == NULL)
+ return 1;
+
+ while (area) {
+ iounmap((void __iomem *) area->addr);
+ area = im_get_area(addr, size,
+ IM_REGION_SUPERSET);
+ }
+
+ return 0;
+}
+
+int iounmap_explicit(volatile void __iomem *start, unsigned long size)
+{
+ struct vm_struct *area;
+ unsigned long addr;
+ int rc;
+
+ addr = (unsigned long __force) start & PAGE_MASK;
+
+ /* Verify that the region either exists or is a subset of an existing
+ * region. In the latter case, split the parent region to create
+ * the exact region
+ */
+ area = im_get_area(addr, size,
+ IM_REGION_EXISTS | IM_REGION_SUBSET);
+ if (area == NULL) {
+ /* Determine whether subset regions exist. If so, unmap */
+ rc = iounmap_subset_regions(addr, size);
+ if (rc) {
+ printk(KERN_ERR
+ "%s() cannot unmap nonexistent range 0x%lx\n",
+ __FUNCTION__, addr);
+ return 1;
+ }
+ } else {
+ iounmap((void __iomem *) area->addr);
+ }
+ /*
+ * FIXME! This can't be right:
+ iounmap(area->addr);
+ * Maybe it should be "iounmap(area);"
+ */
+ return 0;
+}
+
+#endif
+
+EXPORT_SYMBOL(ioremap);
+EXPORT_SYMBOL(__ioremap);
+EXPORT_SYMBOL(iounmap);
+
+void __iomem * reserve_phb_iospace(unsigned long size)
+{
+ void __iomem *virt_addr;
+
+ if (phbs_io_bot >= IMALLOC_BASE)
+ panic("reserve_phb_iospace(): phb io space overflow\n");
+
+ virt_addr = (void __iomem *) phbs_io_bot;
+ phbs_io_bot += size;
+
+ return virt_addr;
+}
diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c
new file mode 100644
index 000000000000..cef9e83cc7e9
--- /dev/null
+++ b/arch/powerpc/mm/ppc_mmu_32.c
@@ -0,0 +1,285 @@
+/*
+ * This file contains the routines for handling the MMU on those
+ * PowerPC implementations where the MMU substantially follows the
+ * architecture specification. This includes the 6xx, 7xx, 7xxx,
+ * 8260, and POWER3 implementations but excludes the 8xx and 4xx.
+ * -- paulus
+ *
+ * Derived from arch/ppc/mm/init.c:
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ * and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ * Copyright (C) 1996 Paul Mackerras
+ * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ * Derived from "arch/i386/mm/init.c"
+ * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
+ *
+ * This program is free software; you can redistribute 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/config.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/highmem.h>
+
+#include <asm/prom.h>
+#include <asm/mmu.h>
+#include <asm/machdep.h>
+#include <asm/lmb.h>
+
+#include "mmu_decl.h"
+
+PTE *Hash, *Hash_end;
+unsigned long Hash_size, Hash_mask;
+unsigned long _SDR1;
+
+union ubat { /* BAT register values to be loaded */
+ BAT bat;
+#ifdef CONFIG_PPC64BRIDGE
+ u64 word[2];
+#else
+ u32 word[2];
+#endif
+} BATS[4][2]; /* 4 pairs of IBAT, DBAT */
+
+struct batrange { /* stores address ranges mapped by BATs */
+ unsigned long start;
+ unsigned long limit;
+ unsigned long phys;
+} bat_addrs[4];
+
+/*
+ * Return PA for this VA if it is mapped by a BAT, or 0
+ */
+unsigned long v_mapped_by_bats(unsigned long va)
+{
+ int b;
+ for (b = 0; b < 4; ++b)
+ if (va >= bat_addrs[b].start && va < bat_addrs[b].limit)
+ return bat_addrs[b].phys + (va - bat_addrs[b].start);
+ return 0;
+}
+
+/*
+ * Return VA for a given PA or 0 if not mapped
+ */
+unsigned long p_mapped_by_bats(unsigned long pa)
+{
+ int b;
+ for (b = 0; b < 4; ++b)
+ if (pa >= bat_addrs[b].phys
+ && pa < (bat_addrs[b].limit-bat_addrs[b].start)
+ +bat_addrs[b].phys)
+ return bat_addrs[b].start+(pa-bat_addrs[b].phys);
+ return 0;
+}
+
+unsigned long __init mmu_mapin_ram(void)
+{
+#ifdef CONFIG_POWER4
+ return 0;
+#else
+ unsigned long tot, bl, done;
+ unsigned long max_size = (256<<20);
+ unsigned long align;
+
+ if (__map_without_bats)
+ return 0;
+
+ /* Set up BAT2 and if necessary BAT3 to cover RAM. */
+
+ /* Make sure we don't map a block larger than the
+ smallest alignment of the physical address. */
+ /* alignment of PPC_MEMSTART */
+ align = ~(PPC_MEMSTART-1) & PPC_MEMSTART;
+ /* set BAT block size to MIN(max_size, align) */
+ if (align && align < max_size)
+ max_size = align;
+
+ tot = total_lowmem;
+ for (bl = 128<<10; bl < max_size; bl <<= 1) {
+ if (bl * 2 > tot)
+ break;
+ }
+
+ setbat(2, KERNELBASE, PPC_MEMSTART, bl, _PAGE_RAM);
+ done = (unsigned long)bat_addrs[2].limit - KERNELBASE + 1;
+ if ((done < tot) && !bat_addrs[3].limit) {
+ /* use BAT3 to cover a bit more */
+ tot -= done;
+ for (bl = 128<<10; bl < max_size; bl <<= 1)
+ if (bl * 2 > tot)
+ break;
+ setbat(3, KERNELBASE+done, PPC_MEMSTART+done, bl, _PAGE_RAM);
+ done = (unsigned long)bat_addrs[3].limit - KERNELBASE + 1;
+ }
+
+ return done;
+#endif
+}
+
+/*
+ * Set up one of the I/D BAT (block address translation) register pairs.
+ * The parameters are not checked; in particular size must be a power
+ * of 2 between 128k and 256M.
+ */
+void __init setbat(int index, unsigned long virt, unsigned long phys,
+ unsigned int size, int flags)
+{
+ unsigned int bl;
+ int wimgxpp;
+ union ubat *bat = BATS[index];
+
+ if (((flags & _PAGE_NO_CACHE) == 0) &&
+ cpu_has_feature(CPU_FTR_NEED_COHERENT))
+ flags |= _PAGE_COHERENT;
+
+ bl = (size >> 17) - 1;
+ if (PVR_VER(mfspr(SPRN_PVR)) != 1) {
+ /* 603, 604, etc. */
+ /* Do DBAT first */
+ wimgxpp = flags & (_PAGE_WRITETHRU | _PAGE_NO_CACHE
+ | _PAGE_COHERENT | _PAGE_GUARDED);
+ wimgxpp |= (flags & _PAGE_RW)? BPP_RW: BPP_RX;
+ bat[1].word[0] = virt | (bl << 2) | 2; /* Vs=1, Vp=0 */
+ bat[1].word[1] = phys | wimgxpp;
+#ifndef CONFIG_KGDB /* want user access for breakpoints */
+ if (flags & _PAGE_USER)
+#endif
+ bat[1].bat.batu.vp = 1;
+ if (flags & _PAGE_GUARDED) {
+ /* G bit must be zero in IBATs */
+ bat[0].word[0] = bat[0].word[1] = 0;
+ } else {
+ /* make IBAT same as DBAT */
+ bat[0] = bat[1];
+ }
+ } else {
+ /* 601 cpu */
+ if (bl > BL_8M)
+ bl = BL_8M;
+ wimgxpp = flags & (_PAGE_WRITETHRU | _PAGE_NO_CACHE
+ | _PAGE_COHERENT);
+ wimgxpp |= (flags & _PAGE_RW)?
+ ((flags & _PAGE_USER)? PP_RWRW: PP_RWXX): PP_RXRX;
+ bat->word[0] = virt | wimgxpp | 4; /* Ks=0, Ku=1 */
+ bat->word[1] = phys | bl | 0x40; /* V=1 */
+ }
+
+ bat_addrs[index].start = virt;
+ bat_addrs[index].limit = virt + ((bl + 1) << 17) - 1;
+ bat_addrs[index].phys = phys;
+}
+
+/*
+ * Initialize the hash table and patch the instructions in hashtable.S.
+ */
+void __init MMU_init_hw(void)
+{
+ unsigned int hmask, mb, mb2;
+ unsigned int n_hpteg, lg_n_hpteg;
+
+ extern unsigned int hash_page_patch_A[];
+ extern unsigned int hash_page_patch_B[], hash_page_patch_C[];
+ extern unsigned int hash_page[];
+ extern unsigned int flush_hash_patch_A[], flush_hash_patch_B[];
+
+ if (!cpu_has_feature(CPU_FTR_HPTE_TABLE)) {
+ /*
+ * Put a blr (procedure return) instruction at the
+ * start of hash_page, since we can still get DSI
+ * exceptions on a 603.
+ */
+ hash_page[0] = 0x4e800020;
+ flush_icache_range((unsigned long) &hash_page[0],
+ (unsigned long) &hash_page[1]);
+ return;
+ }
+
+ if ( ppc_md.progress ) ppc_md.progress("hash:enter", 0x105);
+
+#ifdef CONFIG_PPC64BRIDGE
+#define LG_HPTEG_SIZE 7 /* 128 bytes per HPTEG */
+#define SDR1_LOW_BITS (lg_n_hpteg - 11)
+#define MIN_N_HPTEG 2048 /* min 256kB hash table */
+#else
+#define LG_HPTEG_SIZE 6 /* 64 bytes per HPTEG */
+#define SDR1_LOW_BITS ((n_hpteg - 1) >> 10)
+#define MIN_N_HPTEG 1024 /* min 64kB hash table */
+#endif
+
+ /*
+ * Allow 1 HPTE (1/8 HPTEG) for each page of memory.
+ * This is less than the recommended amount, but then
+ * Linux ain't AIX.
+ */
+ n_hpteg = total_memory / (PAGE_SIZE * 8);
+ if (n_hpteg < MIN_N_HPTEG)
+ n_hpteg = MIN_N_HPTEG;
+ lg_n_hpteg = __ilog2(n_hpteg);
+ if (n_hpteg & (n_hpteg - 1)) {
+ ++lg_n_hpteg; /* round up if not power of 2 */
+ n_hpteg = 1 << lg_n_hpteg;
+ }
+ Hash_size = n_hpteg << LG_HPTEG_SIZE;
+
+ /*
+ * Find some memory for the hash table.
+ */
+ if ( ppc_md.progress ) ppc_md.progress("hash:find piece", 0x322);
+ Hash = __va(lmb_alloc_base(Hash_size, Hash_size,
+ __initial_memory_limit));
+ cacheable_memzero(Hash, Hash_size);
+ _SDR1 = __pa(Hash) | SDR1_LOW_BITS;
+
+ Hash_end = (PTE *) ((unsigned long)Hash + Hash_size);
+
+ printk("Total memory = %ldMB; using %ldkB for hash table (at %p)\n",
+ total_memory >> 20, Hash_size >> 10, Hash);
+
+
+ /*
+ * Patch up the instructions in hashtable.S:create_hpte
+ */
+ if ( ppc_md.progress ) ppc_md.progress("hash:patch", 0x345);
+ Hash_mask = n_hpteg - 1;
+ hmask = Hash_mask >> (16 - LG_HPTEG_SIZE);
+ mb2 = mb = 32 - LG_HPTEG_SIZE - lg_n_hpteg;
+ if (lg_n_hpteg > 16)
+ mb2 = 16 - LG_HPTEG_SIZE;
+
+ hash_page_patch_A[0] = (hash_page_patch_A[0] & ~0xffff)
+ | ((unsigned int)(Hash) >> 16);
+ hash_page_patch_A[1] = (hash_page_patch_A[1] & ~0x7c0) | (mb << 6);
+ hash_page_patch_A[2] = (hash_page_patch_A[2] & ~0x7c0) | (mb2 << 6);
+ hash_page_patch_B[0] = (hash_page_patch_B[0] & ~0xffff) | hmask;
+ hash_page_patch_C[0] = (hash_page_patch_C[0] & ~0xffff) | hmask;
+
+ /*
+ * Ensure that the locations we've patched have been written
+ * out from the data cache and invalidated in the instruction
+ * cache, on those machines with split caches.
+ */
+ flush_icache_range((unsigned long) &hash_page_patch_A[0],
+ (unsigned long) &hash_page_patch_C[1]);
+
+ /*
+ * Patch up the instructions in hashtable.S:flush_hash_page
+ */
+ flush_hash_patch_A[0] = (flush_hash_patch_A[0] & ~0xffff)
+ | ((unsigned int)(Hash) >> 16);
+ flush_hash_patch_A[1] = (flush_hash_patch_A[1] & ~0x7c0) | (mb << 6);
+ flush_hash_patch_A[2] = (flush_hash_patch_A[2] & ~0x7c0) | (mb2 << 6);
+ flush_hash_patch_B[0] = (flush_hash_patch_B[0] & ~0xffff) | hmask;
+ flush_icache_range((unsigned long) &flush_hash_patch_A[0],
+ (unsigned long) &flush_hash_patch_B[1]);
+
+ if ( ppc_md.progress ) ppc_md.progress("hash:done", 0x205);
+}
diff --git a/arch/ppc64/mm/slb.c b/arch/powerpc/mm/slb.c
index 0473953f6a37..0473953f6a37 100644
--- a/arch/ppc64/mm/slb.c
+++ b/arch/powerpc/mm/slb.c
diff --git a/arch/ppc64/mm/slb_low.S b/arch/powerpc/mm/slb_low.S
index a3a03da503bc..a3a03da503bc 100644
--- a/arch/ppc64/mm/slb_low.S
+++ b/arch/powerpc/mm/slb_low.S
diff --git a/arch/ppc64/mm/stab.c b/arch/powerpc/mm/stab.c
index 1b83f002bf27..1b83f002bf27 100644
--- a/arch/ppc64/mm/stab.c
+++ b/arch/powerpc/mm/stab.c
diff --git a/arch/powerpc/mm/tlb_32.c b/arch/powerpc/mm/tlb_32.c
new file mode 100644
index 000000000000..6c3dc3c44c86
--- /dev/null
+++ b/arch/powerpc/mm/tlb_32.c
@@ -0,0 +1,183 @@
+/*
+ * This file contains the routines for TLB flushing.
+ * On machines where the MMU uses a hash table to store virtual to
+ * physical translations, these routines flush entries from the
+ * hash table also.
+ * -- paulus
+ *
+ * Derived from arch/ppc/mm/init.c:
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ * and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ * Copyright (C) 1996 Paul Mackerras
+ * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ * Derived from "arch/i386/mm/init.c"
+ * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
+ *
+ * This program is free software; you can redistribute 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/config.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/highmem.h>
+#include <asm/tlbflush.h>
+#include <asm/tlb.h>
+
+#include "mmu_decl.h"
+
+/*
+ * Called when unmapping pages to flush entries from the TLB/hash table.
+ */
+void flush_hash_entry(struct mm_struct *mm, pte_t *ptep, unsigned long addr)
+{
+ unsigned long ptephys;
+
+ if (Hash != 0) {
+ ptephys = __pa(ptep) & PAGE_MASK;
+ flush_hash_pages(mm->context, addr, ptephys, 1);
+ }
+}
+
+/*
+ * Called by ptep_set_access_flags, must flush on CPUs for which the
+ * DSI handler can't just "fixup" the TLB on a write fault
+ */
+void flush_tlb_page_nohash(struct vm_area_struct *vma, unsigned long addr)
+{
+ if (Hash != 0)
+ return;
+ _tlbie(addr);
+}
+
+/*
+ * Called at the end of a mmu_gather operation to make sure the
+ * TLB flush is completely done.
+ */
+void tlb_flush(struct mmu_gather *tlb)
+{
+ if (Hash == 0) {
+ /*
+ * 603 needs to flush the whole TLB here since
+ * it doesn't use a hash table.
+ */
+ _tlbia();
+ }
+}
+
+/*
+ * TLB flushing:
+ *
+ * - flush_tlb_mm(mm) flushes the specified mm context TLB's
+ * - flush_tlb_page(vma, vmaddr) flushes one page
+ * - flush_tlb_range(vma, start, end) flushes a range of pages
+ * - flush_tlb_kernel_range(start, end) flushes kernel pages
+ *
+ * since the hardware hash table functions as an extension of the
+ * tlb as far as the linux tables are concerned, flush it too.
+ * -- Cort
+ */
+
+/*
+ * 750 SMP is a Bad Idea because the 750 doesn't broadcast all
+ * the cache operations on the bus. Hence we need to use an IPI
+ * to get the other CPU(s) to invalidate their TLBs.
+ */
+#ifdef CONFIG_SMP_750
+#define FINISH_FLUSH smp_send_tlb_invalidate(0)
+#else
+#define FINISH_FLUSH do { } while (0)
+#endif
+
+static void flush_range(struct mm_struct *mm, unsigned long start,
+ unsigned long end)
+{
+ pmd_t *pmd;
+ unsigned long pmd_end;
+ int count;
+ unsigned int ctx = mm->context;
+
+ if (Hash == 0) {
+ _tlbia();
+ return;
+ }
+ start &= PAGE_MASK;
+ if (start >= end)
+ return;
+ end = (end - 1) | ~PAGE_MASK;
+ pmd = pmd_offset(pgd_offset(mm, start), start);
+ for (;;) {
+ pmd_end = ((start + PGDIR_SIZE) & PGDIR_MASK) - 1;
+ if (pmd_end > end)
+ pmd_end = end;
+ if (!pmd_none(*pmd)) {
+ count = ((pmd_end - start) >> PAGE_SHIFT) + 1;
+ flush_hash_pages(ctx, start, pmd_val(*pmd), count);
+ }
+ if (pmd_end == end)
+ break;
+ start = pmd_end + 1;
+ ++pmd;
+ }
+}
+
+/*
+ * Flush kernel TLB entries in the given range
+ */
+void flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+ flush_range(&init_mm, start, end);
+ FINISH_FLUSH;
+}
+
+/*
+ * Flush all the (user) entries for the address space described by mm.
+ */
+void flush_tlb_mm(struct mm_struct *mm)
+{
+ struct vm_area_struct *mp;
+
+ if (Hash == 0) {
+ _tlbia();
+ return;
+ }
+
+ for (mp = mm->mmap; mp != NULL; mp = mp->vm_next)
+ flush_range(mp->vm_mm, mp->vm_start, mp->vm_end);
+ FINISH_FLUSH;
+}
+
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
+{
+ struct mm_struct *mm;
+ pmd_t *pmd;
+
+ if (Hash == 0) {
+ _tlbie(vmaddr);
+ return;
+ }
+ mm = (vmaddr < TASK_SIZE)? vma->vm_mm: &init_mm;
+ pmd = pmd_offset(pgd_offset(mm, vmaddr), vmaddr);
+ if (!pmd_none(*pmd))
+ flush_hash_pages(mm->context, vmaddr, pmd_val(*pmd), 1);
+ FINISH_FLUSH;
+}
+
+/*
+ * For each address in the range, find the pte for the address
+ * and check _PAGE_HASHPTE bit; if it is set, find and destroy
+ * the corresponding HPTE.
+ */
+void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
+ unsigned long end)
+{
+ flush_range(vma->vm_mm, start, end);
+ FINISH_FLUSH;
+}
diff --git a/arch/ppc64/mm/tlb.c b/arch/powerpc/mm/tlb_64.c
index 21fbffb23a43..09ab81a10f4f 100644
--- a/arch/ppc64/mm/tlb.c
+++ b/arch/powerpc/mm/tlb_64.c
@@ -128,12 +128,10 @@ void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf)
void hpte_update(struct mm_struct *mm, unsigned long addr,
unsigned long pte, int wrprot)
{
- int i;
- unsigned long context = 0;
struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
+ unsigned long vsid;
+ int i;
- if (REGION_ID(addr) == USER_REGION_ID)
- context = mm->context.id;
i = batch->index;
/*
@@ -143,19 +141,21 @@ void hpte_update(struct mm_struct *mm, unsigned long addr,
* up scanning and resetting referenced bits then our batch context
* will change mid stream.
*/
- if (i != 0 && (context != batch->context ||
- batch->large != pte_huge(pte))) {
+ if (i != 0 && (mm != batch->mm || batch->large != pte_huge(pte))) {
flush_tlb_pending();
i = 0;
}
-
if (i == 0) {
- batch->context = context;
batch->mm = mm;
batch->large = pte_huge(pte);
}
+ if (addr < KERNELBASE) {
+ vsid = get_vsid(mm->context.id, addr);
+ WARN_ON(vsid == 0);
+ } else
+ vsid = get_kernel_vsid(addr);
+ batch->vaddr[i] = (vsid << 28 ) | (addr & 0x0fffffff);
batch->pte[i] = __pte(pte);
- batch->addr[i] = addr;
batch->index = ++i;
if (i >= PPC64_TLB_BATCH_NR)
flush_tlb_pending();
@@ -177,10 +177,9 @@ void __flush_tlb_pending(struct ppc64_tlb_batch *batch)
local = 1;
if (i == 1)
- flush_hash_page(batch->context, batch->addr[0], batch->pte[0],
- local);
+ flush_hash_page(batch->vaddr[0], batch->pte[0], local);
else
- flush_hash_range(batch->context, i, local);
+ flush_hash_range(i, local);
batch->index = 0;
put_cpu();
}
diff --git a/arch/ppc/oprofile/Kconfig b/arch/powerpc/oprofile/Kconfig
index 19d37730b664..19d37730b664 100644
--- a/arch/ppc/oprofile/Kconfig
+++ b/arch/powerpc/oprofile/Kconfig
diff --git a/arch/ppc/oprofile/Makefile b/arch/powerpc/oprofile/Makefile
index e2218d32a4eb..0782d0cca89c 100644
--- a/arch/ppc/oprofile/Makefile
+++ b/arch/powerpc/oprofile/Makefile
@@ -7,8 +7,5 @@ DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \
timer_int.o )
oprofile-y := $(DRIVER_OBJS) common.o
-
-ifeq ($(CONFIG_FSL_BOOKE),y)
- oprofile-y += op_model_fsl_booke.o
-endif
-
+oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o
+oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o
diff --git a/arch/ppc64/oprofile/common.c b/arch/powerpc/oprofile/common.c
index e5f572710aa0..af2c05d20ba5 100644
--- a/arch/ppc64/oprofile/common.c
+++ b/arch/powerpc/oprofile/common.c
@@ -1,5 +1,9 @@
/*
+ * PPC 64 oprofile support:
* Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
+ * PPC 32 oprofile support: (based on PPC 64 support)
+ * Copyright (C) Freescale Semiconductor, Inc 2004
+ * Author: Andy Fleming
*
* Based on alpha version.
*
@@ -10,6 +14,9 @@
*/
#include <linux/oprofile.h>
+#ifndef __powerpc64__
+#include <linux/slab.h>
+#endif /* ! __powerpc64__ */
#include <linux/init.h>
#include <linux/smp.h>
#include <linux/errno.h>
@@ -19,17 +26,21 @@
#include <asm/cputable.h>
#include <asm/oprofile_impl.h>
-static struct op_ppc64_model *model;
+static struct op_powerpc_model *model;
static struct op_counter_config ctr[OP_MAX_COUNTER];
static struct op_system_config sys;
+#ifndef __powerpc64__
+static char *cpu_type;
+#endif /* ! __powerpc64__ */
+
static void op_handle_interrupt(struct pt_regs *regs)
{
model->handle_interrupt(regs, ctr);
}
-static int op_ppc64_setup(void)
+static int op_powerpc_setup(void)
{
int err;
@@ -42,41 +53,49 @@ static int op_ppc64_setup(void)
model->reg_setup(ctr, &sys, model->num_counters);
/* Configure the registers on all cpus. */
+#ifdef __powerpc64__
on_each_cpu(model->cpu_setup, NULL, 0, 1);
+#else /* __powerpc64__ */
+#if 0
+ /* FIXME: Make multi-cpu work */
+ on_each_cpu(model->reg_setup, NULL, 0, 1);
+#endif
+#endif /* __powerpc64__ */
return 0;
}
-static void op_ppc64_shutdown(void)
+static void op_powerpc_shutdown(void)
{
release_pmc_hardware();
}
-static void op_ppc64_cpu_start(void *dummy)
+static void op_powerpc_cpu_start(void *dummy)
{
model->start(ctr);
}
-static int op_ppc64_start(void)
+static int op_powerpc_start(void)
{
- on_each_cpu(op_ppc64_cpu_start, NULL, 0, 1);
+ on_each_cpu(op_powerpc_cpu_start, NULL, 0, 1);
return 0;
}
-static inline void op_ppc64_cpu_stop(void *dummy)
+static inline void op_powerpc_cpu_stop(void *dummy)
{
model->stop();
}
-static void op_ppc64_stop(void)
+static void op_powerpc_stop(void)
{
- on_each_cpu(op_ppc64_cpu_stop, NULL, 0, 1);
+ on_each_cpu(op_powerpc_cpu_stop, NULL, 0, 1);
}
-static int op_ppc64_create_files(struct super_block *sb, struct dentry *root)
+static int op_powerpc_create_files(struct super_block *sb, struct dentry *root)
{
int i;
+#ifdef __powerpc64__
/*
* There is one mmcr0, mmcr1 and mmcra for setting the events for
* all of the counters.
@@ -84,6 +103,7 @@ static int op_ppc64_create_files(struct super_block *sb, struct dentry *root)
oprofilefs_create_ulong(sb, root, "mmcr0", &sys.mmcr0);
oprofilefs_create_ulong(sb, root, "mmcr1", &sys.mmcr1);
oprofilefs_create_ulong(sb, root, "mmcra", &sys.mmcra);
+#endif /* __powerpc64__ */
for (i = 0; i < model->num_counters; ++i) {
struct dentry *dir;
@@ -95,44 +115,70 @@ static int op_ppc64_create_files(struct super_block *sb, struct dentry *root)
oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
+#ifdef __powerpc64__
/*
* We dont support per counter user/kernel selection, but
* we leave the entries because userspace expects them
*/
+#endif /* __powerpc64__ */
oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
+
+#ifndef __powerpc64__
+ /* FIXME: Not sure if this is used */
+#endif /* ! __powerpc64__ */
oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
}
oprofilefs_create_ulong(sb, root, "enable_kernel", &sys.enable_kernel);
oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user);
+#ifdef __powerpc64__
oprofilefs_create_ulong(sb, root, "backtrace_spinlocks",
&sys.backtrace_spinlocks);
+#endif /* __powerpc64__ */
/* Default to tracing both kernel and user */
sys.enable_kernel = 1;
sys.enable_user = 1;
-
+#ifdef __powerpc64__
/* Turn on backtracing through spinlocks by default */
sys.backtrace_spinlocks = 1;
+#endif /* __powerpc64__ */
return 0;
}
int __init oprofile_arch_init(struct oprofile_operations *ops)
{
+#ifndef __powerpc64__
+#ifdef CONFIG_FSL_BOOKE
+ model = &op_model_fsl_booke;
+#else
+ return -ENODEV;
+#endif
+
+ cpu_type = kmalloc(32, GFP_KERNEL);
+ if (NULL == cpu_type)
+ return -ENOMEM;
+
+ sprintf(cpu_type, "ppc/%s", cur_cpu_spec->cpu_name);
+
+ model->num_counters = cur_cpu_spec->num_pmcs;
+
+ ops->cpu_type = cpu_type;
+#else /* __powerpc64__ */
if (!cur_cpu_spec->oprofile_model || !cur_cpu_spec->oprofile_cpu_type)
return -ENODEV;
-
model = cur_cpu_spec->oprofile_model;
model->num_counters = cur_cpu_spec->num_pmcs;
ops->cpu_type = cur_cpu_spec->oprofile_cpu_type;
- ops->create_files = op_ppc64_create_files;
- ops->setup = op_ppc64_setup;
- ops->shutdown = op_ppc64_shutdown;
- ops->start = op_ppc64_start;
- ops->stop = op_ppc64_stop;
+#endif /* __powerpc64__ */
+ ops->create_files = op_powerpc_create_files;
+ ops->setup = op_powerpc_setup;
+ ops->shutdown = op_powerpc_shutdown;
+ ops->start = op_powerpc_start;
+ ops->stop = op_powerpc_stop;
printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
ops->cpu_type);
@@ -142,4 +188,8 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
void oprofile_arch_exit(void)
{
+#ifndef __powerpc64__
+ kfree(cpu_type);
+ cpu_type = NULL;
+#endif /* ! __powerpc64__ */
}
diff --git a/arch/ppc/oprofile/op_model_fsl_booke.c b/arch/powerpc/oprofile/op_model_fsl_booke.c
index fc9c859358c6..86124a94c9af 100644
--- a/arch/ppc/oprofile/op_model_fsl_booke.c
+++ b/arch/powerpc/oprofile/op_model_fsl_booke.c
@@ -24,9 +24,8 @@
#include <asm/cputable.h>
#include <asm/reg_booke.h>
#include <asm/page.h>
-#include <asm/perfmon.h>
-
-#include "op_impl.h"
+#include <asm/pmc.h>
+#include <asm/oprofile_impl.h>
static unsigned long reset_value[OP_MAX_COUNTER];
@@ -176,7 +175,7 @@ static void fsl_booke_handle_interrupt(struct pt_regs *regs,
pmc_start_ctrs(1);
}
-struct op_ppc32_model op_model_fsl_booke = {
+struct op_powerpc_model op_model_fsl_booke = {
.reg_setup = fsl_booke_reg_setup,
.start = fsl_booke_start,
.stop = fsl_booke_stop,
diff --git a/arch/ppc64/oprofile/op_model_power4.c b/arch/powerpc/oprofile/op_model_power4.c
index 32b2bb5625fe..886449315847 100644
--- a/arch/ppc64/oprofile/op_model_power4.c
+++ b/arch/powerpc/oprofile/op_model_power4.c
@@ -300,7 +300,7 @@ static void power4_handle_interrupt(struct pt_regs *regs,
mtspr(SPRN_MMCR0, mmcr0);
}
-struct op_ppc64_model op_model_power4 = {
+struct op_powerpc_model op_model_power4 = {
.reg_setup = power4_reg_setup,
.cpu_setup = power4_cpu_setup,
.start = power4_start,
diff --git a/arch/ppc64/oprofile/op_model_rs64.c b/arch/powerpc/oprofile/op_model_rs64.c
index 08c5b333f5c4..e010b85996e8 100644
--- a/arch/ppc64/oprofile/op_model_rs64.c
+++ b/arch/powerpc/oprofile/op_model_rs64.c
@@ -209,7 +209,7 @@ static void rs64_handle_interrupt(struct pt_regs *regs,
mtspr(SPRN_MMCR0, mmcr0);
}
-struct op_ppc64_model op_model_rs64 = {
+struct op_powerpc_model op_model_rs64 = {
.reg_setup = rs64_reg_setup,
.cpu_setup = rs64_cpu_setup,
.start = rs64_start,
diff --git a/arch/powerpc/platforms/4xx/Kconfig b/arch/powerpc/platforms/4xx/Kconfig
new file mode 100644
index 000000000000..ed39d6a3d22a
--- /dev/null
+++ b/arch/powerpc/platforms/4xx/Kconfig
@@ -0,0 +1,280 @@
+config 4xx
+ bool
+ depends on 40x || 44x
+ default y
+
+config WANT_EARLY_SERIAL
+ bool
+ select SERIAL_8250
+ default n
+
+menu "AMCC 4xx options"
+ depends on 4xx
+
+choice
+ prompt "Machine Type"
+ depends on 40x
+ default WALNUT
+
+config BUBINGA
+ bool "Bubinga"
+ select WANT_EARLY_SERIAL
+ help
+ This option enables support for the IBM 405EP evaluation board.
+
+config CPCI405
+ bool "CPCI405"
+ help
+ This option enables support for the CPCI405 board.
+
+config EP405
+ bool "EP405/EP405PC"
+ help
+ This option enables support for the EP405/EP405PC boards.
+
+config REDWOOD_5
+ bool "Redwood-5"
+ help
+ This option enables support for the IBM STB04 evaluation board.
+
+config REDWOOD_6
+ bool "Redwood-6"
+ help
+ This option enables support for the IBM STBx25xx evaluation board.
+
+config SYCAMORE
+ bool "Sycamore"
+ help
+ This option enables support for the IBM PPC405GPr evaluation board.
+
+config WALNUT
+ bool "Walnut"
+ help
+ This option enables support for the IBM PPC405GP evaluation board.
+
+config XILINX_ML300
+ bool "Xilinx-ML300"
+ help
+ This option enables support for the Xilinx ML300 evaluation board.
+
+endchoice
+
+choice
+ prompt "Machine Type"
+ depends on 44x
+ default EBONY
+
+config BAMBOO
+ bool "Bamboo"
+ select WANT_EARLY_SERIAL
+ help
+ This option enables support for the IBM PPC440EP evaluation board.
+
+config EBONY
+ bool "Ebony"
+ select WANT_EARLY_SERIAL
+ help
+ This option enables support for the IBM PPC440GP evaluation board.
+
+config LUAN
+ bool "Luan"
+ select WANT_EARLY_SERIAL
+ help
+ This option enables support for the IBM PPC440SP evaluation board.
+
+config OCOTEA
+ bool "Ocotea"
+ select WANT_EARLY_SERIAL
+ help
+ This option enables support for the IBM PPC440GX evaluation board.
+
+endchoice
+
+config EP405PC
+ bool "EP405PC Support"
+ depends on EP405
+
+
+# It's often necessary to know the specific 4xx processor type.
+# Fortunately, it is impled (so far) from the board type, so we
+# don't need to ask more redundant questions.
+config NP405H
+ bool
+ depends on ASH
+ default y
+
+config 440EP
+ bool
+ depends on BAMBOO
+ select PPC_FPU
+ default y
+
+config 440GP
+ bool
+ depends on EBONY
+ default y
+
+config 440GX
+ bool
+ depends on OCOTEA
+ default y
+
+config 440SP
+ bool
+ depends on LUAN
+ default y
+
+config 440
+ bool
+ depends on 440GP || 440SP || 440EP
+ default y
+
+config 440A
+ bool
+ depends on 440GX
+ default y
+
+config IBM440EP_ERR42
+ bool
+ depends on 440EP
+ default y
+
+# All 405-based cores up until the 405GPR and 405EP have this errata.
+config IBM405_ERR77
+ bool
+ depends on 40x && !403GCX && !405GPR && !405EP
+ default y
+
+# All 40x-based cores, up until the 405GPR and 405EP have this errata.
+config IBM405_ERR51
+ bool
+ depends on 40x && !405GPR && !405EP
+ default y
+
+config BOOKE
+ bool
+ depends on 44x
+ default y
+
+config IBM_OCP
+ bool
+ depends on ASH || BAMBOO || BUBINGA || CPCI405 || EBONY || EP405 || LUAN || OCOTEA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT
+ default y
+
+config XILINX_OCP
+ bool
+ depends on XILINX_ML300
+ default y
+
+config IBM_EMAC4
+ bool
+ depends on 440GX || 440SP
+ default y
+
+config BIOS_FIXUP
+ bool
+ depends on BUBINGA || EP405 || SYCAMORE || WALNUT
+ default y
+
+# OAK doesn't exist but wanted to keep this around for any future 403GCX boards
+config 403GCX
+ bool
+ depends OAK
+ default y
+
+config 405EP
+ bool
+ depends on BUBINGA
+ default y
+
+config 405GP
+ bool
+ depends on CPCI405 || EP405 || WALNUT
+ default y
+
+config 405GPR
+ bool
+ depends on SYCAMORE
+ default y
+
+config VIRTEX_II_PRO
+ bool
+ depends on XILINX_ML300
+ default y
+
+config STB03xxx
+ bool
+ depends on REDWOOD_5 || REDWOOD_6
+ default y
+
+config EMBEDDEDBOOT
+ bool
+ depends on EP405 || XILINX_ML300
+ default y
+
+config IBM_OPENBIOS
+ bool
+ depends on ASH || BUBINGA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT
+ default y
+
+config PPC4xx_DMA
+ bool "PPC4xx DMA controller support"
+ depends on 4xx
+
+config PPC4xx_EDMA
+ bool
+ depends on !STB03xxx && PPC4xx_DMA
+ default y
+
+config PPC_GEN550
+ bool
+ depends on 4xx
+ default y
+
+choice
+ prompt "TTYS0 device and default console"
+ depends on 40x
+ default UART0_TTYS0
+
+config UART0_TTYS0
+ bool "UART0"
+
+config UART0_TTYS1
+ bool "UART1"
+
+endchoice
+
+config SERIAL_SICC
+ bool "SICC Serial port support"
+ depends on STB03xxx
+
+config UART1_DFLT_CONSOLE
+ bool
+ depends on SERIAL_SICC && UART0_TTYS1
+ default y
+
+config SERIAL_SICC_CONSOLE
+ bool
+ depends on SERIAL_SICC && UART0_TTYS1
+ default y
+endmenu
+
+
+menu "IBM 40x options"
+ depends on 40x
+
+config SERIAL_SICC
+ bool "SICC Serial port"
+ depends on STB03xxx
+
+config UART1_DFLT_CONSOLE
+ bool
+ depends on SERIAL_SICC && UART0_TTYS1
+ default y
+
+config SERIAL_SICC_CONSOLE
+ bool
+ depends on SERIAL_SICC && UART0_TTYS1
+ default y
+
+endmenu
diff --git a/arch/powerpc/platforms/4xx/Makefile b/arch/powerpc/platforms/4xx/Makefile
new file mode 100644
index 000000000000..79ff6b1e887c
--- /dev/null
+++ b/arch/powerpc/platforms/4xx/Makefile
@@ -0,0 +1 @@
+# empty makefile so make clean works \ No newline at end of file
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
new file mode 100644
index 000000000000..c5bc2821d991
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -0,0 +1,86 @@
+config 85xx
+ bool
+ depends on E500
+ default y
+
+config PPC_INDIRECT_PCI_BE
+ bool
+ depends on 85xx
+ default y
+
+menu "Freescale 85xx options"
+ depends on E500
+
+choice
+ prompt "Machine Type"
+ depends on 85xx
+ default MPC8540_ADS
+
+config MPC8540_ADS
+ bool "Freescale MPC8540 ADS"
+ help
+ This option enables support for the MPC 8540 ADS evaluation board.
+
+config MPC8548_CDS
+ bool "Freescale MPC8548 CDS"
+ help
+ This option enablese support for the MPC8548 CDS evaluation board.
+
+config MPC8555_CDS
+ bool "Freescale MPC8555 CDS"
+ help
+ This option enablese support for the MPC8555 CDS evaluation board.
+
+config MPC8560_ADS
+ bool "Freescale MPC8560 ADS"
+ help
+ This option enables support for the MPC 8560 ADS evaluation board.
+
+config SBC8560
+ bool "WindRiver PowerQUICC III SBC8560"
+ help
+ This option enables support for the WindRiver PowerQUICC III
+ SBC8560 board.
+
+config STX_GP3
+ bool "Silicon Turnkey Express GP3"
+ help
+ This option enables support for the Silicon Turnkey Express GP3
+ board.
+
+endchoice
+
+# It's often necessary to know the specific 85xx processor type.
+# Fortunately, it is implied (so far) from the board type, so we
+# don't need to ask more redundant questions.
+config MPC8540
+ bool
+ depends on MPC8540_ADS
+ default y
+
+config MPC8548
+ bool
+ depends on MPC8548_CDS
+ default y
+
+config MPC8555
+ bool
+ depends on MPC8555_CDS
+ default y
+
+config MPC8560
+ bool
+ depends on SBC8560 || MPC8560_ADS || STX_GP3
+ default y
+
+config 85xx_PCI2
+ bool "Supprt for 2nd PCI host controller"
+ depends on MPC8555_CDS
+ default y
+
+config PPC_GEN550
+ bool
+ depends on MPC8540 || SBC8560 || MPC8555
+ default y
+
+endmenu
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile
new file mode 100644
index 000000000000..6407197ffd89
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -0,0 +1 @@
+# empty makefile so make clean works
diff --git a/arch/powerpc/platforms/8xx/Kconfig b/arch/powerpc/platforms/8xx/Kconfig
new file mode 100644
index 000000000000..c8c0ba3cf8e8
--- /dev/null
+++ b/arch/powerpc/platforms/8xx/Kconfig
@@ -0,0 +1,352 @@
+config FADS
+ bool
+
+choice
+ prompt "8xx Machine Type"
+ depends on 8xx
+ default RPXLITE
+
+config RPXLITE
+ bool "RPX-Lite"
+ ---help---
+ Single-board computers based around the PowerPC MPC8xx chips and
+ intended for embedded applications. The following types are
+ supported:
+
+ RPX-Lite:
+ Embedded Planet RPX Lite. PC104 form-factor SBC based on the MPC823.
+
+ RPX-Classic:
+ Embedded Planet RPX Classic Low-fat. Credit-card-size SBC based on
+ the MPC 860
+
+ BSE-IP:
+ Bright Star Engineering ip-Engine.
+
+ TQM823L:
+ TQM850L:
+ TQM855L:
+ TQM860L:
+ MPC8xx based family of mini modules, half credit card size,
+ up to 64 MB of RAM, 8 MB Flash, (Fast) Ethernet, 2 x serial ports,
+ 2 x CAN bus interface, ...
+ Manufacturer: TQ Components, www.tq-group.de
+ Date of Release: October (?) 1999
+ End of Life: not yet :-)
+ URL:
+ - module: <http://www.denx.de/PDF/TQM8xxLHWM201.pdf>
+ - starter kit: <http://www.denx.de/PDF/STK8xxLHWM201.pdf>
+ - images: <http://www.denx.de/embedded-ppc-en.html>
+
+ FPS850L:
+ FingerPrint Sensor System (based on TQM850L)
+ Manufacturer: IKENDI AG, <http://www.ikendi.com/>
+ Date of Release: November 1999
+ End of life: end 2000 ?
+ URL: see TQM850L
+
+ IVMS8:
+ MPC860 based board used in the "Integrated Voice Mail System",
+ Small Version (8 voice channels)
+ Manufacturer: Speech Design, <http://www.speech-design.de/>
+ Date of Release: December 2000 (?)
+ End of life: -
+ URL: <http://www.speech-design.de/>
+
+ IVML24:
+ MPC860 based board used in the "Integrated Voice Mail System",
+ Large Version (24 voice channels)
+ Manufacturer: Speech Design, <http://www.speech-design.de/>
+ Date of Release: March 2001 (?)
+ End of life: -
+ URL: <http://www.speech-design.de/>
+
+ HERMES:
+ Hermes-Pro ISDN/LAN router with integrated 8 x hub
+ Manufacturer: Multidata Gesellschaft fur Datentechnik und Informatik
+ <http://www.multidata.de/>
+ Date of Release: 2000 (?)
+ End of life: -
+ URL: <http://www.multidata.de/english/products/hpro.htm>
+
+ IP860:
+ VMEBus IP (Industry Pack) carrier board with MPC860
+ Manufacturer: MicroSys GmbH, <http://www.microsys.de/>
+ Date of Release: ?
+ End of life: -
+ URL: <http://www.microsys.de/html/ip860.html>
+
+ PCU_E:
+ PCU = Peripheral Controller Unit, Extended
+ Manufacturer: Siemens AG, ICN (Information and Communication Networks)
+ <http://www.siemens.de/page/1,3771,224315-1-999_2_226207-0,00.html>
+ Date of Release: April 2001
+ End of life: August 2001
+ URL: n. a.
+
+config RPXCLASSIC
+ bool "RPX-Classic"
+ help
+ The RPX-Classic is a single-board computer based on the Motorola
+ MPC860. It features 16MB of DRAM and a variable amount of flash,
+ I2C EEPROM, thermal monitoring, a PCMCIA slot, a DIP switch and two
+ LEDs. Variants with Ethernet ports exist. Say Y here to support it
+ directly.
+
+config BSEIP
+ bool "BSE-IP"
+ help
+ Say Y here to support the Bright Star Engineering ipEngine SBC.
+ This is a credit-card-sized device featuring a MPC823 processor,
+ 26MB DRAM, 4MB flash, Ethernet, a 16K-gate FPGA, USB, an LCD/video
+ controller, and two RS232 ports.
+
+config MPC8XXFADS
+ bool "FADS"
+ select FADS
+
+config MPC86XADS
+ bool "MPC86XADS"
+ help
+ MPC86x Application Development System by Freescale Semiconductor.
+ The MPC86xADS is meant to serve as a platform for s/w and h/w
+ development around the MPC86X processor families.
+ select FADS
+
+config MPC885ADS
+ bool "MPC885ADS"
+ help
+ Freescale Semiconductor MPC885 Application Development System (ADS).
+ Also known as DUET.
+ The MPC885ADS is meant to serve as a platform for s/w and h/w
+ development around the MPC885 processor family.
+
+config TQM823L
+ bool "TQM823L"
+ help
+ Say Y here to support the TQM823L, one of an MPC8xx-based family of
+ mini SBCs (half credit-card size) from TQ Components first released
+ in late 1999. Technical references are at
+ <http://www.denx.de/PDF/TQM8xxLHWM201.pdf>, and
+ <http://www.denx.de/PDF/STK8xxLHWM201.pdf>, and an image at
+ <http://www.denx.de/embedded-ppc-en.html>.
+
+config TQM850L
+ bool "TQM850L"
+ help
+ Say Y here to support the TQM850L, one of an MPC8xx-based family of
+ mini SBCs (half credit-card size) from TQ Components first released
+ in late 1999. Technical references are at
+ <http://www.denx.de/PDF/TQM8xxLHWM201.pdf>, and
+ <http://www.denx.de/PDF/STK8xxLHWM201.pdf>, and an image at
+ <http://www.denx.de/embedded-ppc-en.html>.
+
+config TQM855L
+ bool "TQM855L"
+ help
+ Say Y here to support the TQM855L, one of an MPC8xx-based family of
+ mini SBCs (half credit-card size) from TQ Components first released
+ in late 1999. Technical references are at
+ <http://www.denx.de/PDF/TQM8xxLHWM201.pdf>, and
+ <http://www.denx.de/PDF/STK8xxLHWM201.pdf>, and an image at
+ <http://www.denx.de/embedded-ppc-en.html>.
+
+config TQM860L
+ bool "TQM860L"
+ help
+ Say Y here to support the TQM860L, one of an MPC8xx-based family of
+ mini SBCs (half credit-card size) from TQ Components first released
+ in late 1999. Technical references are at
+ <http://www.denx.de/PDF/TQM8xxLHWM201.pdf>, and
+ <http://www.denx.de/PDF/STK8xxLHWM201.pdf>, and an image at
+ <http://www.denx.de/embedded-ppc-en.html>.
+
+config FPS850L
+ bool "FPS850L"
+
+config IVMS8
+ bool "IVMS8"
+ help
+ Say Y here to support the Integrated Voice-Mail Small 8-channel SBC
+ from Speech Design, released March 2001. The manufacturer's website
+ is at <http://www.speech-design.de/>.
+
+config IVML24
+ bool "IVML24"
+ help
+ Say Y here to support the Integrated Voice-Mail Large 24-channel SBC
+ from Speech Design, released March 2001. The manufacturer's website
+ is at <http://www.speech-design.de/>.
+
+config HERMES_PRO
+ bool "HERMES"
+
+config IP860
+ bool "IP860"
+
+config LWMON
+ bool "LWMON"
+
+config PCU_E
+ bool "PCU_E"
+
+config CCM
+ bool "CCM"
+
+config LANTEC
+ bool "LANTEC"
+
+config MBX
+ bool "MBX"
+ help
+ MBX is a line of Motorola single-board computer based around the
+ MPC821 and MPC860 processors, and intended for embedded-controller
+ applications. Say Y here to support these boards directly.
+
+config WINCEPT
+ bool "WinCept"
+ help
+ The Wincept 100/110 is a Motorola single-board computer based on the
+ MPC821 PowerPC, introduced in 1998 and designed to be used in
+ thin-client machines. Say Y to support it directly.
+
+endchoice
+
+#
+# MPC8xx Communication options
+#
+
+menu "MPC8xx CPM Options"
+ depends on 8xx
+
+config SCC_ENET
+ bool "CPM SCC Ethernet"
+ depends on NET_ETHERNET
+ help
+ Enable Ethernet support via the Motorola MPC8xx serial
+ communications controller.
+
+choice
+ prompt "SCC used for Ethernet"
+ depends on SCC_ENET
+ default SCC1_ENET
+
+config SCC1_ENET
+ bool "SCC1"
+ help
+ Use MPC8xx serial communications controller 1 to drive Ethernet
+ (default).
+
+config SCC2_ENET
+ bool "SCC2"
+ help
+ Use MPC8xx serial communications controller 2 to drive Ethernet.
+
+config SCC3_ENET
+ bool "SCC3"
+ help
+ Use MPC8xx serial communications controller 3 to drive Ethernet.
+
+endchoice
+
+config FEC_ENET
+ bool "860T FEC Ethernet"
+ depends on NET_ETHERNET
+ help
+ Enable Ethernet support via the Fast Ethernet Controller (FCC) on
+ the Motorola MPC8260.
+
+config USE_MDIO
+ bool "Use MDIO for PHY configuration"
+ depends on FEC_ENET
+ help
+ On some boards the hardware configuration of the ethernet PHY can be
+ used without any software interaction over the MDIO interface, so
+ all MII code can be omitted. Say N here if unsure or if you don't
+ need link status reports.
+
+config FEC_AM79C874
+ bool "Support AMD79C874 PHY"
+ depends on USE_MDIO
+
+config FEC_LXT970
+ bool "Support LXT970 PHY"
+ depends on USE_MDIO
+
+config FEC_LXT971
+ bool "Support LXT971 PHY"
+ depends on USE_MDIO
+
+config FEC_QS6612
+ bool "Support QS6612 PHY"
+ depends on USE_MDIO
+
+config ENET_BIG_BUFFERS
+ bool "Use Big CPM Ethernet Buffers"
+ depends on SCC_ENET || FEC_ENET
+ help
+ Allocate large buffers for MPC8xx Ethernet. Increases throughput
+ and decreases the likelihood of dropped packets, but costs memory.
+
+config HTDMSOUND
+ bool "Embedded Planet HIOX Audio"
+ depends on SOUND=y
+
+# This doesn't really belong here, but it is convenient to ask
+# 8xx specific questions.
+comment "Generic MPC8xx Options"
+
+config 8xx_COPYBACK
+ bool "Copy-Back Data Cache (else Writethrough)"
+ help
+ Saying Y here will cause the cache on an MPC8xx processor to be used
+ in Copy-Back mode. If you say N here, it is used in Writethrough
+ mode.
+
+ If in doubt, say Y here.
+
+config 8xx_CPU6
+ bool "CPU6 Silicon Errata (860 Pre Rev. C)"
+ help
+ MPC860 CPUs, prior to Rev C have some bugs in the silicon, which
+ require workarounds for Linux (and most other OSes to work). If you
+ get a BUG() very early in boot, this might fix the problem. For
+ more details read the document entitled "MPC860 Family Device Errata
+ Reference" on Motorola's website. This option also incurs a
+ performance hit.
+
+ If in doubt, say N here.
+
+choice
+ prompt "Microcode patch selection"
+ default NO_UCODE_PATCH
+ help
+ Help not implemented yet, coming soon.
+
+config NO_UCODE_PATCH
+ bool "None"
+
+config USB_SOF_UCODE_PATCH
+ bool "USB SOF patch"
+ help
+ Help not implemented yet, coming soon.
+
+config I2C_SPI_UCODE_PATCH
+ bool "I2C/SPI relocation patch"
+ help
+ Help not implemented yet, coming soon.
+
+config I2C_SPI_SMC1_UCODE_PATCH
+ bool "I2C/SPI/SMC1 relocation patch"
+ help
+ Help not implemented yet, coming soon.
+
+endchoice
+
+config UCODE_PATCH
+ bool
+ default y
+ depends on !NO_UCODE_PATCH
+
+endmenu
+
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile
new file mode 100644
index 000000000000..172c0db63504
--- /dev/null
+++ b/arch/powerpc/platforms/Makefile
@@ -0,0 +1,13 @@
+ifeq ($(CONFIG_PPC_MERGE),y)
+obj-$(CONFIG_PPC_PMAC) += powermac/
+else
+ifeq ($(CONFIG_PPC64),y)
+obj-$(CONFIG_PPC_PMAC) += powermac/
+endif
+endif
+obj-$(CONFIG_PPC_CHRP) += chrp/
+obj-$(CONFIG_4xx) += 4xx/
+obj-$(CONFIG_85xx) += 85xx/
+obj-$(CONFIG_PPC_PSERIES) += pseries/
+obj-$(CONFIG_PPC_ISERIES) += iseries/
+obj-$(CONFIG_PPC_MAPLE) += maple/
diff --git a/arch/powerpc/platforms/apus/Kconfig b/arch/powerpc/platforms/apus/Kconfig
new file mode 100644
index 000000000000..6bde3bffed86
--- /dev/null
+++ b/arch/powerpc/platforms/apus/Kconfig
@@ -0,0 +1,130 @@
+
+config AMIGA
+ bool
+ depends on APUS
+ default y
+ help
+ This option enables support for the Amiga series of computers.
+
+config ZORRO
+ bool
+ depends on APUS
+ default y
+ help
+ This enables support for the Zorro bus in the Amiga. If you have
+ expansion cards in your Amiga that conform to the Amiga
+ AutoConfig(tm) specification, say Y, otherwise N. Note that even
+ expansion cards that do not fit in the Zorro slots but fit in e.g.
+ the CPU slot may fall in this category, so you have to say Y to let
+ Linux use these.
+
+config ABSTRACT_CONSOLE
+ bool
+ depends on APUS
+ default y
+
+config APUS_FAST_EXCEPT
+ bool
+ depends on APUS
+ default y
+
+config AMIGA_PCMCIA
+ bool "Amiga 1200/600 PCMCIA support"
+ depends on APUS && EXPERIMENTAL
+ help
+ Include support in the kernel for pcmcia on Amiga 1200 and Amiga
+ 600. If you intend to use pcmcia cards say Y; otherwise say N.
+
+config AMIGA_BUILTIN_SERIAL
+ tristate "Amiga builtin serial support"
+ depends on APUS
+ help
+ If you want to use your Amiga's built-in serial port in Linux,
+ answer Y.
+
+ To compile this driver as a module, choose M here.
+
+config GVPIOEXT
+ tristate "GVP IO-Extender support"
+ depends on APUS
+ help
+ If you want to use a GVP IO-Extender serial card in Linux, say Y.
+ Otherwise, say N.
+
+config GVPIOEXT_LP
+ tristate "GVP IO-Extender parallel printer support"
+ depends on GVPIOEXT
+ help
+ Say Y to enable driving a printer from the parallel port on your
+ GVP IO-Extender card, N otherwise.
+
+config GVPIOEXT_PLIP
+ tristate "GVP IO-Extender PLIP support"
+ depends on GVPIOEXT
+ help
+ Say Y to enable doing IP over the parallel port on your GVP
+ IO-Extender card, N otherwise.
+
+config MULTIFACE_III_TTY
+ tristate "Multiface Card III serial support"
+ depends on APUS
+ help
+ If you want to use a Multiface III card's serial port in Linux,
+ answer Y.
+
+ To compile this driver as a module, choose M here.
+
+config A2232
+ tristate "Commodore A2232 serial support (EXPERIMENTAL)"
+ depends on EXPERIMENTAL && APUS
+ ---help---
+ This option supports the 2232 7-port serial card shipped with the
+ Amiga 2000 and other Zorro-bus machines, dating from 1989. At
+ a max of 19,200 bps, the ports are served by a 6551 ACIA UART chip
+ each, plus a 8520 CIA, and a master 6502 CPU and buffer as well. The
+ ports were connected with 8 pin DIN connectors on the card bracket,
+ for which 8 pin to DB25 adapters were supplied. The card also had
+ jumpers internally to toggle various pinning configurations.
+
+ This driver can be built as a module; but then "generic_serial"
+ will also be built as a module. This has to be loaded before
+ "ser_a2232". If you want to do this, answer M here.
+
+config WHIPPET_SERIAL
+ tristate "Hisoft Whippet PCMCIA serial support"
+ depends on AMIGA_PCMCIA
+ help
+ HiSoft has a web page at <http://www.hisoft.co.uk/>, but there
+ is no listing for the Whippet in their Amiga section.
+
+config APNE
+ tristate "PCMCIA NE2000 support"
+ depends on AMIGA_PCMCIA
+ help
+ If you have a PCMCIA NE2000 compatible adapter, say Y. Otherwise,
+ say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called apne.
+
+config SERIAL_CONSOLE
+ bool "Support for serial port console"
+ depends on APUS && (AMIGA_BUILTIN_SERIAL=y || GVPIOEXT=y || MULTIFACE_III_TTY=y)
+
+config HEARTBEAT
+ bool "Use power LED as a heartbeat"
+ depends on APUS
+ help
+ Use the power-on LED on your machine as a load meter. The exact
+ behavior is platform-dependent, but normally the flash frequency is
+ a hyperbolic function of the 5-minute load average.
+
+config PROC_HARDWARE
+ bool "/proc/hardware support"
+ depends on APUS
+
+source "drivers/zorro/Kconfig"
+
+config PCI_PERMEDIA
+ bool "PCI for Permedia2"
+ depends on !4xx && !8xx && APUS
diff --git a/arch/powerpc/platforms/chrp/Makefile b/arch/powerpc/platforms/chrp/Makefile
new file mode 100644
index 000000000000..902feb1ac431
--- /dev/null
+++ b/arch/powerpc/platforms/chrp/Makefile
@@ -0,0 +1,4 @@
+obj-y += setup.o time.o pegasos_eth.o
+obj-$(CONFIG_PCI) += pci.o
+obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_NVRAM) += nvram.o
diff --git a/arch/powerpc/platforms/chrp/chrp.h b/arch/powerpc/platforms/chrp/chrp.h
new file mode 100644
index 000000000000..3a2057fa314a
--- /dev/null
+++ b/arch/powerpc/platforms/chrp/chrp.h
@@ -0,0 +1,12 @@
+/*
+ * Declarations of CHRP platform-specific things.
+ */
+
+extern void chrp_nvram_init(void);
+extern void chrp_get_rtc_time(struct rtc_time *);
+extern int chrp_set_rtc_time(struct rtc_time *);
+extern void chrp_calibrate_decr(void);
+extern long chrp_time_init(void);
+
+extern void chrp_find_bridges(void);
+extern void chrp_event_scan(void);
diff --git a/arch/powerpc/platforms/chrp/nvram.c b/arch/powerpc/platforms/chrp/nvram.c
new file mode 100644
index 000000000000..4ac7125aa09c
--- /dev/null
+++ b/arch/powerpc/platforms/chrp/nvram.c
@@ -0,0 +1,84 @@
+/*
+ * c 2001 PPC 64 Team, IBM Corp
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * /dev/nvram driver for PPC
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <asm/uaccess.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include "chrp.h"
+
+static unsigned int nvram_size;
+static unsigned char nvram_buf[4];
+static DEFINE_SPINLOCK(nvram_lock);
+
+static unsigned char chrp_nvram_read(int addr)
+{
+ unsigned long done, flags;
+ unsigned char ret;
+
+ if (addr >= nvram_size) {
+ printk(KERN_DEBUG "%s: read addr %d > nvram_size %u\n",
+ current->comm, addr, nvram_size);
+ return 0xff;
+ }
+ spin_lock_irqsave(&nvram_lock, flags);
+ if ((call_rtas("nvram-fetch", 3, 2, &done, addr, __pa(nvram_buf), 1) != 0) || 1 != done)
+ ret = 0xff;
+ else
+ ret = nvram_buf[0];
+ spin_unlock_irqrestore(&nvram_lock, flags);
+
+ return ret;
+}
+
+static void chrp_nvram_write(int addr, unsigned char val)
+{
+ unsigned long done, flags;
+
+ if (addr >= nvram_size) {
+ printk(KERN_DEBUG "%s: write addr %d > nvram_size %u\n",
+ current->comm, addr, nvram_size);
+ return;
+ }
+ spin_lock_irqsave(&nvram_lock, flags);
+ nvram_buf[0] = val;
+ if ((call_rtas("nvram-store", 3, 2, &done, addr, __pa(nvram_buf), 1) != 0) || 1 != done)
+ printk(KERN_DEBUG "rtas IO error storing 0x%02x at %d", val, addr);
+ spin_unlock_irqrestore(&nvram_lock, flags);
+}
+
+void __init chrp_nvram_init(void)
+{
+ struct device_node *nvram;
+ unsigned int *nbytes_p, proplen;
+
+ nvram = of_find_node_by_type(NULL, "nvram");
+ if (nvram == NULL)
+ return;
+
+ nbytes_p = (unsigned int *)get_property(nvram, "#bytes", &proplen);
+ if (nbytes_p == NULL || proplen != sizeof(unsigned int))
+ return;
+
+ nvram_size = *nbytes_p;
+
+ printk(KERN_INFO "CHRP nvram contains %u bytes\n", nvram_size);
+ of_node_put(nvram);
+
+ ppc_md.nvram_read_val = chrp_nvram_read;
+ ppc_md.nvram_write_val = chrp_nvram_write;
+
+ return;
+}
diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c
new file mode 100644
index 000000000000..82c429d487f3
--- /dev/null
+++ b/arch/powerpc/platforms/chrp/pci.c
@@ -0,0 +1,310 @@
+/*
+ * CHRP pci routines.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/ide.h>
+
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/hydra.h>
+#include <asm/prom.h>
+#include <asm/gg2.h>
+#include <asm/machdep.h>
+#include <asm/sections.h>
+#include <asm/pci-bridge.h>
+#include <asm/open_pic.h>
+#include <asm/grackle.h>
+#include <asm/rtas.h>
+
+/* LongTrail */
+void __iomem *gg2_pci_config_base;
+
+/*
+ * The VLSI Golden Gate II has only 512K of PCI configuration space, so we
+ * limit the bus number to 3 bits
+ */
+
+int gg2_read_config(struct pci_bus *bus, unsigned int devfn, int off,
+ int len, u32 *val)
+{
+ volatile void __iomem *cfg_data;
+ struct pci_controller *hose = bus->sysdata;
+
+ if (bus->number > 7)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ /*
+ * Note: the caller has already checked that off is
+ * suitably aligned and that len is 1, 2 or 4.
+ */
+ cfg_data = hose->cfg_data + ((bus->number<<16) | (devfn<<8) | off);
+ switch (len) {
+ case 1:
+ *val = in_8(cfg_data);
+ break;
+ case 2:
+ *val = in_le16(cfg_data);
+ break;
+ default:
+ *val = in_le32(cfg_data);
+ break;
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int gg2_write_config(struct pci_bus *bus, unsigned int devfn, int off,
+ int len, u32 val)
+{
+ volatile void __iomem *cfg_data;
+ struct pci_controller *hose = bus->sysdata;
+
+ if (bus->number > 7)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ /*
+ * Note: the caller has already checked that off is
+ * suitably aligned and that len is 1, 2 or 4.
+ */
+ cfg_data = hose->cfg_data + ((bus->number<<16) | (devfn<<8) | off);
+ switch (len) {
+ case 1:
+ out_8(cfg_data, val);
+ break;
+ case 2:
+ out_le16(cfg_data, val);
+ break;
+ default:
+ out_le32(cfg_data, val);
+ break;
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops gg2_pci_ops =
+{
+ gg2_read_config,
+ gg2_write_config
+};
+
+/*
+ * Access functions for PCI config space using RTAS calls.
+ */
+int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
+ int len, u32 *val)
+{
+ struct pci_controller *hose = bus->sysdata;
+ unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
+ | (((bus->number - hose->first_busno) & 0xff) << 16)
+ | (hose->index << 24);
+ int ret = -1;
+ int rval;
+
+ rval = rtas_call(rtas_token("read-pci-config"), 2, 2, &ret, addr, len);
+ *val = ret;
+ return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL;
+}
+
+int rtas_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
+ int len, u32 val)
+{
+ struct pci_controller *hose = bus->sysdata;
+ unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
+ | (((bus->number - hose->first_busno) & 0xff) << 16)
+ | (hose->index << 24);
+ int rval;
+
+ rval = rtas_call(rtas_token("write-pci-config"), 3, 1, NULL,
+ addr, len, val);
+ return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops rtas_pci_ops =
+{
+ rtas_read_config,
+ rtas_write_config
+};
+
+volatile struct Hydra __iomem *Hydra = NULL;
+
+int __init
+hydra_init(void)
+{
+ struct device_node *np;
+
+ np = find_devices("mac-io");
+ if (np == NULL || np->n_addrs == 0)
+ return 0;
+ Hydra = ioremap(np->addrs[0].address, np->addrs[0].size);
+ printk("Hydra Mac I/O at %lx\n", np->addrs[0].address);
+ printk("Hydra Feature_Control was %x",
+ in_le32(&Hydra->Feature_Control));
+ out_le32(&Hydra->Feature_Control, (HYDRA_FC_SCC_CELL_EN |
+ HYDRA_FC_SCSI_CELL_EN |
+ HYDRA_FC_SCCA_ENABLE |
+ HYDRA_FC_SCCB_ENABLE |
+ HYDRA_FC_ARB_BYPASS |
+ HYDRA_FC_MPIC_ENABLE |
+ HYDRA_FC_SLOW_SCC_PCLK |
+ HYDRA_FC_MPIC_IS_MASTER));
+ printk(", now %x\n", in_le32(&Hydra->Feature_Control));
+ return 1;
+}
+
+void __init
+chrp_pcibios_fixup(void)
+{
+ struct pci_dev *dev = NULL;
+ struct device_node *np;
+
+ /* PCI interrupts are controlled by the OpenPIC */
+ for_each_pci_dev(dev) {
+ np = pci_device_to_OF_node(dev);
+ if ((np != 0) && (np->n_intrs > 0) && (np->intrs[0].line != 0))
+ dev->irq = np->intrs[0].line;
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+ }
+}
+
+#define PRG_CL_RESET_VALID 0x00010000
+
+static void __init
+setup_python(struct pci_controller *hose, struct device_node *dev)
+{
+ u32 __iomem *reg;
+ u32 val;
+ unsigned long addr = dev->addrs[0].address;
+
+ setup_indirect_pci(hose, addr + 0xf8000, addr + 0xf8010);
+
+ /* Clear the magic go-slow bit */
+ reg = ioremap(dev->addrs[0].address + 0xf6000, 0x40);
+ val = in_be32(&reg[12]);
+ if (val & PRG_CL_RESET_VALID) {
+ out_be32(&reg[12], val & ~PRG_CL_RESET_VALID);
+ in_be32(&reg[12]);
+ }
+ iounmap(reg);
+}
+
+/* Marvell Discovery II based Pegasos 2 */
+static void __init setup_peg2(struct pci_controller *hose, struct device_node *dev)
+{
+ struct device_node *root = find_path_device("/");
+ struct device_node *rtas;
+
+ rtas = of_find_node_by_name (root, "rtas");
+ if (rtas) {
+ hose->ops = &rtas_pci_ops;
+ } else {
+ printk ("RTAS supporting Pegasos OF not found, please upgrade"
+ " your firmware\n");
+ }
+ pci_assign_all_buses = 1;
+}
+
+void __init
+chrp_find_bridges(void)
+{
+ struct device_node *dev;
+ int *bus_range;
+ int len, index = -1;
+ struct pci_controller *hose;
+ unsigned int *dma;
+ char *model, *machine;
+ int is_longtrail = 0, is_mot = 0, is_pegasos = 0;
+ struct device_node *root = find_path_device("/");
+
+ /*
+ * The PCI host bridge nodes on some machines don't have
+ * properties to adequately identify them, so we have to
+ * look at what sort of machine this is as well.
+ */
+ machine = get_property(root, "model", NULL);
+ if (machine != NULL) {
+ is_longtrail = strncmp(machine, "IBM,LongTrail", 13) == 0;
+ is_mot = strncmp(machine, "MOT", 3) == 0;
+ if (strncmp(machine, "Pegasos2", 8) == 0)
+ is_pegasos = 2;
+ else if (strncmp(machine, "Pegasos", 7) == 0)
+ is_pegasos = 1;
+ }
+ for (dev = root->child; dev != NULL; dev = dev->sibling) {
+ if (dev->type == NULL || strcmp(dev->type, "pci") != 0)
+ continue;
+ ++index;
+ /* The GG2 bridge on the LongTrail doesn't have an address */
+ if (dev->n_addrs < 1 && !is_longtrail) {
+ printk(KERN_WARNING "Can't use %s: no address\n",
+ dev->full_name);
+ continue;
+ }
+ bus_range = (int *) get_property(dev, "bus-range", &len);
+ if (bus_range == NULL || len < 2 * sizeof(int)) {
+ printk(KERN_WARNING "Can't get bus-range for %s\n",
+ dev->full_name);
+ continue;
+ }
+ if (bus_range[1] == bus_range[0])
+ printk(KERN_INFO "PCI bus %d", bus_range[0]);
+ else
+ printk(KERN_INFO "PCI buses %d..%d",
+ bus_range[0], bus_range[1]);
+ printk(" controlled by %s", dev->type);
+ if (dev->n_addrs > 0)
+ printk(" at %lx", dev->addrs[0].address);
+ printk("\n");
+
+ hose = pcibios_alloc_controller();
+ if (!hose) {
+ printk("Can't allocate PCI controller structure for %s\n",
+ dev->full_name);
+ continue;
+ }
+ hose->arch_data = dev;
+ hose->first_busno = bus_range[0];
+ hose->last_busno = bus_range[1];
+
+ model = get_property(dev, "model", NULL);
+ if (model == NULL)
+ model = "<none>";
+ if (device_is_compatible(dev, "IBM,python")) {
+ setup_python(hose, dev);
+ } else if (is_mot
+ || strncmp(model, "Motorola, Grackle", 17) == 0) {
+ setup_grackle(hose);
+ } else if (is_longtrail) {
+ void __iomem *p = ioremap(GG2_PCI_CONFIG_BASE, 0x80000);
+ hose->ops = &gg2_pci_ops;
+ hose->cfg_data = p;
+ gg2_pci_config_base = p;
+ } else if (is_pegasos == 1) {
+ setup_indirect_pci(hose, 0xfec00cf8, 0xfee00cfc);
+ } else if (is_pegasos == 2) {
+ setup_peg2(hose, dev);
+ } else {
+ printk("No methods for %s (model %s), using RTAS\n",
+ dev->full_name, model);
+ hose->ops = &rtas_pci_ops;
+ }
+
+ pci_process_bridge_OF_ranges(hose, dev, index == 0);
+
+ /* check the first bridge for a property that we can
+ use to set pci_dram_offset */
+ dma = (unsigned int *)
+ get_property(dev, "ibm,dma-ranges", &len);
+ if (index == 0 && dma != NULL && len >= 6 * sizeof(*dma)) {
+ pci_dram_offset = dma[2] - dma[3];
+ printk("pci_dram_offset = %lx\n", pci_dram_offset);
+ }
+ }
+
+ /* Do not fixup interrupts from OF tree on pegasos */
+ if (is_pegasos == 0)
+ ppc_md.pcibios_fixup = chrp_pcibios_fixup;
+}
diff --git a/arch/powerpc/platforms/chrp/pegasos_eth.c b/arch/powerpc/platforms/chrp/pegasos_eth.c
new file mode 100644
index 000000000000..a9052305c35d
--- /dev/null
+++ b/arch/powerpc/platforms/chrp/pegasos_eth.c
@@ -0,0 +1,213 @@
+/*
+ * arch/ppc/platforms/chrp_pegasos_eth.c
+ *
+ * Copyright (C) 2005 Sven Luther <sl@bplan-gmbh.de>
+ * Thanks to :
+ * Dale Farnsworth <dale@farnsworth.org>
+ * Mark A. Greer <mgreer@mvista.com>
+ * Nicolas DET <nd@bplan-gmbh.de>
+ * Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ * And anyone else who helped me on this.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/mv643xx.h>
+#include <linux/pci.h>
+
+#define PEGASOS2_MARVELL_REGBASE (0xf1000000)
+#define PEGASOS2_MARVELL_REGSIZE (0x00004000)
+#define PEGASOS2_SRAM_BASE (0xf2000000)
+#define PEGASOS2_SRAM_SIZE (256*1024)
+
+#define PEGASOS2_SRAM_BASE_ETH0 (PEGASOS2_SRAM_BASE)
+#define PEGASOS2_SRAM_BASE_ETH1 (PEGASOS2_SRAM_BASE_ETH0 + (PEGASOS2_SRAM_SIZE / 2) )
+
+
+#define PEGASOS2_SRAM_RXRING_SIZE (PEGASOS2_SRAM_SIZE/4)
+#define PEGASOS2_SRAM_TXRING_SIZE (PEGASOS2_SRAM_SIZE/4)
+
+#undef BE_VERBOSE
+
+static struct resource mv643xx_eth_shared_resources[] = {
+ [0] = {
+ .name = "ethernet shared base",
+ .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS,
+ .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS +
+ MV643XX_ETH_SHARED_REGS_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device mv643xx_eth_shared_device = {
+ .name = MV643XX_ETH_SHARED_NAME,
+ .id = 0,
+ .num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources),
+ .resource = mv643xx_eth_shared_resources,
+};
+
+static struct resource mv643xx_eth0_resources[] = {
+ [0] = {
+ .name = "eth0 irq",
+ .start = 9,
+ .end = 9,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+
+static struct mv643xx_eth_platform_data eth0_pd = {
+ .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH0,
+ .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE,
+ .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16,
+
+ .rx_sram_addr = PEGASOS2_SRAM_BASE_ETH0 + PEGASOS2_SRAM_TXRING_SIZE,
+ .rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE,
+ .rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16,
+};
+
+static struct platform_device eth0_device = {
+ .name = MV643XX_ETH_NAME,
+ .id = 0,
+ .num_resources = ARRAY_SIZE(mv643xx_eth0_resources),
+ .resource = mv643xx_eth0_resources,
+ .dev = {
+ .platform_data = &eth0_pd,
+ },
+};
+
+static struct resource mv643xx_eth1_resources[] = {
+ [0] = {
+ .name = "eth1 irq",
+ .start = 9,
+ .end = 9,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mv643xx_eth_platform_data eth1_pd = {
+ .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH1,
+ .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE,
+ .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16,
+
+ .rx_sram_addr = PEGASOS2_SRAM_BASE_ETH1 + PEGASOS2_SRAM_TXRING_SIZE,
+ .rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE,
+ .rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16,
+};
+
+static struct platform_device eth1_device = {
+ .name = MV643XX_ETH_NAME,
+ .id = 1,
+ .num_resources = ARRAY_SIZE(mv643xx_eth1_resources),
+ .resource = mv643xx_eth1_resources,
+ .dev = {
+ .platform_data = &eth1_pd,
+ },
+};
+
+static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
+ &mv643xx_eth_shared_device,
+ &eth0_device,
+ &eth1_device,
+};
+
+/***********/
+/***********/
+#define MV_READ(offset,val) { val = readl(mv643xx_reg_base + offset); }
+#define MV_WRITE(offset,data) writel(data, mv643xx_reg_base + offset)
+
+static void __iomem *mv643xx_reg_base;
+
+static int Enable_SRAM(void)
+{
+ u32 ALong;
+
+ if (mv643xx_reg_base == NULL)
+ mv643xx_reg_base = ioremap(PEGASOS2_MARVELL_REGBASE,
+ PEGASOS2_MARVELL_REGSIZE);
+
+ if (mv643xx_reg_base == NULL)
+ return -ENOMEM;
+
+#ifdef BE_VERBOSE
+ printk("Pegasos II/Marvell MV64361: register remapped from %p to %p\n",
+ (void *)PEGASOS2_MARVELL_REGBASE, (void *)mv643xx_reg_base);
+#endif
+
+ MV_WRITE(MV64340_SRAM_CONFIG, 0);
+
+ MV_WRITE(MV64340_INTEGRATED_SRAM_BASE_ADDR, PEGASOS2_SRAM_BASE >> 16);
+
+ MV_READ(MV64340_BASE_ADDR_ENABLE, ALong);
+ ALong &= ~(1 << 19);
+ MV_WRITE(MV64340_BASE_ADDR_ENABLE, ALong);
+
+ ALong = 0x02;
+ ALong |= PEGASOS2_SRAM_BASE & 0xffff0000;
+ MV_WRITE(MV643XX_ETH_BAR_4, ALong);
+
+ MV_WRITE(MV643XX_ETH_SIZE_REG_4, (PEGASOS2_SRAM_SIZE-1) & 0xffff0000);
+
+ MV_READ(MV643XX_ETH_BASE_ADDR_ENABLE_REG, ALong);
+ ALong &= ~(1 << 4);
+ MV_WRITE(MV643XX_ETH_BASE_ADDR_ENABLE_REG, ALong);
+
+#ifdef BE_VERBOSE
+ printk("Pegasos II/Marvell MV64361: register unmapped\n");
+ printk("Pegasos II/Marvell MV64361: SRAM at %p, size=%x\n", (void*) PEGASOS2_SRAM_BASE, PEGASOS2_SRAM_SIZE);
+#endif
+
+ iounmap(mv643xx_reg_base);
+ mv643xx_reg_base = NULL;
+
+ return 1;
+}
+
+
+/***********/
+/***********/
+int mv643xx_eth_add_pds(void)
+{
+ int ret = 0;
+ static struct pci_device_id pci_marvell_mv64360[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_MV64360) },
+ { }
+ };
+
+#ifdef BE_VERBOSE
+ printk("Pegasos II/Marvell MV64361: init\n");
+#endif
+
+ if (pci_dev_present(pci_marvell_mv64360)) {
+ ret = platform_add_devices(mv643xx_eth_pd_devs,
+ ARRAY_SIZE(mv643xx_eth_pd_devs));
+
+ if ( Enable_SRAM() < 0)
+ {
+ eth0_pd.tx_sram_addr = 0;
+ eth0_pd.tx_sram_size = 0;
+ eth0_pd.rx_sram_addr = 0;
+ eth0_pd.rx_sram_size = 0;
+
+ eth1_pd.tx_sram_addr = 0;
+ eth1_pd.tx_sram_size = 0;
+ eth1_pd.rx_sram_addr = 0;
+ eth1_pd.rx_sram_size = 0;
+
+#ifdef BE_VERBOSE
+ printk("Pegasos II/Marvell MV64361: Can't enable the "
+ "SRAM\n");
+#endif
+ }
+ }
+
+#ifdef BE_VERBOSE
+ printk("Pegasos II/Marvell MV64361: init is over\n");
+#endif
+
+ return ret;
+}
+
+device_initcall(mv643xx_eth_add_pds);
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
new file mode 100644
index 000000000000..ecd32d5d85f4
--- /dev/null
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -0,0 +1,522 @@
+/*
+ * arch/ppc/platforms/setup.c
+ *
+ * Copyright (C) 1995 Linus Torvalds
+ * Adapted from 'alpha' version by Gary Thomas
+ * Modified by Cort Dougan (cort@cs.nmt.edu)
+ */
+
+/*
+ * bootup setup stuff..
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/tty.h>
+#include <linux/major.h>
+#include <linux/interrupt.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/version.h>
+#include <linux/adb.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/ide.h>
+#include <linux/console.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/initrd.h>
+#include <linux/module.h>
+
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/prom.h>
+#include <asm/gg2.h>
+#include <asm/pci-bridge.h>
+#include <asm/dma.h>
+#include <asm/machdep.h>
+#include <asm/irq.h>
+#include <asm/hydra.h>
+#include <asm/sections.h>
+#include <asm/time.h>
+#include <asm/btext.h>
+#include <asm/i8259.h>
+#include <asm/mpic.h>
+#include <asm/rtas.h>
+#include <asm/xmon.h>
+
+#include "chrp.h"
+
+void rtas_indicator_progress(char *, unsigned short);
+void btext_progress(char *, unsigned short);
+
+int _chrp_type;
+EXPORT_SYMBOL(_chrp_type);
+
+struct mpic *chrp_mpic;
+
+/*
+ * XXX this should be in xmon.h, but putting it there means xmon.h
+ * has to include <linux/interrupt.h> (to get irqreturn_t), which
+ * causes all sorts of problems. -- paulus
+ */
+extern irqreturn_t xmon_irq(int, void *, struct pt_regs *);
+
+extern unsigned long loops_per_jiffy;
+
+#ifdef CONFIG_SMP
+extern struct smp_ops_t chrp_smp_ops;
+#endif
+
+static const char *gg2_memtypes[4] = {
+ "FPM", "SDRAM", "EDO", "BEDO"
+};
+static const char *gg2_cachesizes[4] = {
+ "256 KB", "512 KB", "1 MB", "Reserved"
+};
+static const char *gg2_cachetypes[4] = {
+ "Asynchronous", "Reserved", "Flow-Through Synchronous",
+ "Pipelined Synchronous"
+};
+static const char *gg2_cachemodes[4] = {
+ "Disabled", "Write-Through", "Copy-Back", "Transparent Mode"
+};
+
+void chrp_show_cpuinfo(struct seq_file *m)
+{
+ int i, sdramen;
+ unsigned int t;
+ struct device_node *root;
+ const char *model = "";
+
+ root = find_path_device("/");
+ if (root)
+ model = get_property(root, "model", NULL);
+ seq_printf(m, "machine\t\t: CHRP %s\n", model);
+
+ /* longtrail (goldengate) stuff */
+ if (!strncmp(model, "IBM,LongTrail", 13)) {
+ /* VLSI VAS96011/12 `Golden Gate 2' */
+ /* Memory banks */
+ sdramen = (in_le32(gg2_pci_config_base + GG2_PCI_DRAM_CTRL)
+ >>31) & 1;
+ for (i = 0; i < (sdramen ? 4 : 6); i++) {
+ t = in_le32(gg2_pci_config_base+
+ GG2_PCI_DRAM_BANK0+
+ i*4);
+ if (!(t & 1))
+ continue;
+ switch ((t>>8) & 0x1f) {
+ case 0x1f:
+ model = "4 MB";
+ break;
+ case 0x1e:
+ model = "8 MB";
+ break;
+ case 0x1c:
+ model = "16 MB";
+ break;
+ case 0x18:
+ model = "32 MB";
+ break;
+ case 0x10:
+ model = "64 MB";
+ break;
+ case 0x00:
+ model = "128 MB";
+ break;
+ default:
+ model = "Reserved";
+ break;
+ }
+ seq_printf(m, "memory bank %d\t: %s %s\n", i, model,
+ gg2_memtypes[sdramen ? 1 : ((t>>1) & 3)]);
+ }
+ /* L2 cache */
+ t = in_le32(gg2_pci_config_base+GG2_PCI_CC_CTRL);
+ seq_printf(m, "board l2\t: %s %s (%s)\n",
+ gg2_cachesizes[(t>>7) & 3],
+ gg2_cachetypes[(t>>2) & 3],
+ gg2_cachemodes[t & 3]);
+ }
+}
+
+/*
+ * Fixes for the National Semiconductor PC78308VUL SuperI/O
+ *
+ * Some versions of Open Firmware incorrectly initialize the IRQ settings
+ * for keyboard and mouse
+ */
+static inline void __init sio_write(u8 val, u8 index)
+{
+ outb(index, 0x15c);
+ outb(val, 0x15d);
+}
+
+static inline u8 __init sio_read(u8 index)
+{
+ outb(index, 0x15c);
+ return inb(0x15d);
+}
+
+static void __init sio_fixup_irq(const char *name, u8 device, u8 level,
+ u8 type)
+{
+ u8 level0, type0, active;
+
+ /* select logical device */
+ sio_write(device, 0x07);
+ active = sio_read(0x30);
+ level0 = sio_read(0x70);
+ type0 = sio_read(0x71);
+ if (level0 != level || type0 != type || !active) {
+ printk(KERN_WARNING "sio: %s irq level %d, type %d, %sactive: "
+ "remapping to level %d, type %d, active\n",
+ name, level0, type0, !active ? "in" : "", level, type);
+ sio_write(0x01, 0x30);
+ sio_write(level, 0x70);
+ sio_write(type, 0x71);
+ }
+}
+
+static void __init sio_init(void)
+{
+ struct device_node *root;
+
+ if ((root = find_path_device("/")) &&
+ !strncmp(get_property(root, "model", NULL), "IBM,LongTrail", 13)) {
+ /* logical device 0 (KBC/Keyboard) */
+ sio_fixup_irq("keyboard", 0, 1, 2);
+ /* select logical device 1 (KBC/Mouse) */
+ sio_fixup_irq("mouse", 1, 12, 2);
+ }
+}
+
+
+static void __init pegasos_set_l2cr(void)
+{
+ struct device_node *np;
+
+ /* On Pegasos, enable the l2 cache if needed, as the OF forgets it */
+ if (_chrp_type != _CHRP_Pegasos)
+ return;
+
+ /* Enable L2 cache if needed */
+ np = find_type_devices("cpu");
+ if (np != NULL) {
+ unsigned int *l2cr = (unsigned int *)
+ get_property (np, "l2cr", NULL);
+ if (l2cr == NULL) {
+ printk ("Pegasos l2cr : no cpu l2cr property found\n");
+ return;
+ }
+ if (!((*l2cr) & 0x80000000)) {
+ printk ("Pegasos l2cr : L2 cache was not active, "
+ "activating\n");
+ _set_L2CR(0);
+ _set_L2CR((*l2cr) | 0x80000000);
+ }
+ }
+}
+
+void __init chrp_setup_arch(void)
+{
+ struct device_node *root = find_path_device ("/");
+ char *machine = NULL;
+ struct device_node *device;
+ unsigned int *p = NULL;
+
+ /* init to some ~sane value until calibrate_delay() runs */
+ loops_per_jiffy = 50000000/HZ;
+
+ if (root)
+ machine = get_property(root, "model", NULL);
+ if (machine && strncmp(machine, "Pegasos", 7) == 0) {
+ _chrp_type = _CHRP_Pegasos;
+ } else if (machine && strncmp(machine, "IBM", 3) == 0) {
+ _chrp_type = _CHRP_IBM;
+ } else if (machine && strncmp(machine, "MOT", 3) == 0) {
+ _chrp_type = _CHRP_Motorola;
+ } else {
+ /* Let's assume it is an IBM chrp if all else fails */
+ _chrp_type = _CHRP_IBM;
+ }
+ printk("chrp type = %x\n", _chrp_type);
+
+ rtas_initialize();
+ if (rtas_token("display-character") >= 0)
+ ppc_md.progress = rtas_progress;
+
+#ifdef CONFIG_BOOTX_TEXT
+ if (ppc_md.progress == NULL && boot_text_mapped)
+ ppc_md.progress = btext_progress;
+#endif
+
+#ifdef CONFIG_BLK_DEV_INITRD
+ /* this is fine for chrp */
+ initrd_below_start_ok = 1;
+
+ if (initrd_start)
+ ROOT_DEV = Root_RAM0;
+ else
+#endif
+ ROOT_DEV = Root_SDA2; /* sda2 (sda1 is for the kernel) */
+
+ /* On pegasos, enable the L2 cache if not already done by OF */
+ pegasos_set_l2cr();
+
+ /* Lookup PCI host bridges */
+ chrp_find_bridges();
+
+ /*
+ * Temporary fixes for PCI devices.
+ * -- Geert
+ */
+ hydra_init(); /* Mac I/O */
+
+ /*
+ * Fix the Super I/O configuration
+ */
+ sio_init();
+
+ /* Get the event scan rate for the rtas so we know how
+ * often it expects a heartbeat. -- Cort
+ */
+ device = find_devices("rtas");
+ if (device)
+ p = (unsigned int *) get_property
+ (device, "rtas-event-scan-rate", NULL);
+ if (p && *p) {
+ ppc_md.heartbeat = chrp_event_scan;
+ ppc_md.heartbeat_reset = HZ / (*p * 30) - 1;
+ ppc_md.heartbeat_count = 1;
+ printk("RTAS Event Scan Rate: %u (%lu jiffies)\n",
+ *p, ppc_md.heartbeat_reset);
+ }
+
+ pci_create_OF_bus_map();
+
+ /*
+ * Print the banner, then scroll down so boot progress
+ * can be printed. -- Cort
+ */
+ if (ppc_md.progress) ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0x0);
+}
+
+void
+chrp_event_scan(void)
+{
+ unsigned char log[1024];
+ int ret = 0;
+
+ /* XXX: we should loop until the hardware says no more error logs -- Cort */
+ rtas_call(rtas_token("event-scan"), 4, 1, &ret, 0xffffffff, 0,
+ __pa(log), 1024);
+ ppc_md.heartbeat_count = ppc_md.heartbeat_reset;
+}
+
+/*
+ * Finds the open-pic node and sets up the mpic driver.
+ */
+static void __init chrp_find_openpic(void)
+{
+ struct device_node *np, *root;
+ int len, i, j, irq_count;
+ int isu_size, idu_size;
+ unsigned int *iranges, *opprop = NULL;
+ int oplen = 0;
+ unsigned long opaddr;
+ int na = 1;
+ unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS];
+
+ np = find_type_devices("open-pic");
+ if (np == NULL)
+ return;
+ root = find_path_device("/");
+ if (root) {
+ opprop = (unsigned int *) get_property
+ (root, "platform-open-pic", &oplen);
+ na = prom_n_addr_cells(root);
+ }
+ if (opprop && oplen >= na * sizeof(unsigned int)) {
+ opaddr = opprop[na-1]; /* assume 32-bit */
+ oplen /= na * sizeof(unsigned int);
+ } else {
+ if (np->n_addrs == 0)
+ return;
+ opaddr = np->addrs[0].address;
+ oplen = 0;
+ }
+
+ printk(KERN_INFO "OpenPIC at %lx\n", opaddr);
+
+ irq_count = NR_IRQS - NUM_ISA_INTERRUPTS - 4; /* leave room for IPIs */
+ prom_get_irq_senses(init_senses, NUM_8259_INTERRUPTS, NR_IRQS - 4);
+
+ iranges = (unsigned int *) get_property(np, "interrupt-ranges", &len);
+ if (iranges == NULL)
+ len = 0; /* non-distributed mpic */
+ else
+ len /= 2 * sizeof(unsigned int);
+
+ /*
+ * The first pair of cells in interrupt-ranges refers to the
+ * IDU; subsequent pairs refer to the ISUs.
+ */
+ if (oplen < len) {
+ printk(KERN_ERR "Insufficient addresses for distributed"
+ " OpenPIC (%d < %d)\n", np->n_addrs, len);
+ len = oplen;
+ }
+
+ isu_size = 0;
+ idu_size = 0;
+ if (len > 0 && iranges[1] != 0) {
+ printk(KERN_INFO "OpenPIC irqs %d..%d in IDU\n",
+ iranges[0], iranges[0] + iranges[1] - 1);
+ idu_size = iranges[1];
+ }
+ if (len > 1)
+ isu_size = iranges[3];
+
+ chrp_mpic = mpic_alloc(opaddr, MPIC_PRIMARY,
+ isu_size, NUM_ISA_INTERRUPTS, irq_count,
+ NR_IRQS - 4, init_senses, irq_count,
+ " MPIC ");
+ if (chrp_mpic == NULL) {
+ printk(KERN_ERR "Failed to allocate MPIC structure\n");
+ return;
+ }
+
+ j = na - 1;
+ for (i = 1; i < len; ++i) {
+ iranges += 2;
+ j += na;
+ printk(KERN_INFO "OpenPIC irqs %d..%d in ISU at %x\n",
+ iranges[0], iranges[0] + iranges[1] - 1,
+ opprop[j]);
+ mpic_assign_isu(chrp_mpic, i - 1, opprop[j]);
+ }
+
+ mpic_init(chrp_mpic);
+ mpic_setup_cascade(NUM_ISA_INTERRUPTS, i8259_irq_cascade, NULL);
+}
+
+#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
+static struct irqaction xmon_irqaction = {
+ .handler = xmon_irq,
+ .mask = CPU_MASK_NONE,
+ .name = "XMON break",
+};
+#endif
+
+void __init chrp_init_IRQ(void)
+{
+ struct device_node *np;
+ unsigned long chrp_int_ack = 0;
+#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
+ struct device_node *kbd;
+#endif
+
+ for (np = find_devices("pci"); np != NULL; np = np->next) {
+ unsigned int *addrp = (unsigned int *)
+ get_property(np, "8259-interrupt-acknowledge", NULL);
+
+ if (addrp == NULL)
+ continue;
+ chrp_int_ack = addrp[prom_n_addr_cells(np)-1];
+ break;
+ }
+ if (np == NULL)
+ printk(KERN_ERR "Cannot find PCI interrupt acknowledge address\n");
+
+ chrp_find_openpic();
+
+ i8259_init(chrp_int_ack, 0);
+
+ if (_chrp_type == _CHRP_Pegasos)
+ ppc_md.get_irq = i8259_irq;
+ else
+ ppc_md.get_irq = mpic_get_irq;
+
+#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
+ /* see if there is a keyboard in the device tree
+ with a parent of type "adb" */
+ for (kbd = find_devices("keyboard"); kbd; kbd = kbd->next)
+ if (kbd->parent && kbd->parent->type
+ && strcmp(kbd->parent->type, "adb") == 0)
+ break;
+ if (kbd)
+ setup_irq(HYDRA_INT_ADB_NMI, &xmon_irqaction);
+#endif
+}
+
+void __init
+chrp_init2(void)
+{
+#ifdef CONFIG_NVRAM
+ chrp_nvram_init();
+#endif
+
+ request_region(0x20,0x20,"pic1");
+ request_region(0xa0,0x20,"pic2");
+ request_region(0x00,0x20,"dma1");
+ request_region(0x40,0x20,"timer");
+ request_region(0x80,0x10,"dma page reg");
+ request_region(0xc0,0x20,"dma2");
+
+ if (ppc_md.progress)
+ ppc_md.progress(" Have fun! ", 0x7777);
+}
+
+void __init chrp_init(void)
+{
+ ISA_DMA_THRESHOLD = ~0L;
+ DMA_MODE_READ = 0x44;
+ DMA_MODE_WRITE = 0x48;
+ isa_io_base = CHRP_ISA_IO_BASE; /* default value */
+ ppc_do_canonicalize_irqs = 1;
+
+ /* Assume we have an 8259... */
+ __irq_offset_value = NUM_ISA_INTERRUPTS;
+
+ ppc_md.setup_arch = chrp_setup_arch;
+ ppc_md.show_cpuinfo = chrp_show_cpuinfo;
+
+ ppc_md.init_IRQ = chrp_init_IRQ;
+ ppc_md.init = chrp_init2;
+
+ ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot;
+
+ ppc_md.restart = rtas_restart;
+ ppc_md.power_off = rtas_power_off;
+ ppc_md.halt = rtas_halt;
+
+ ppc_md.time_init = chrp_time_init;
+ ppc_md.set_rtc_time = chrp_set_rtc_time;
+ ppc_md.get_rtc_time = chrp_get_rtc_time;
+ ppc_md.calibrate_decr = chrp_calibrate_decr;
+
+#ifdef CONFIG_SMP
+ smp_ops = &chrp_smp_ops;
+#endif /* CONFIG_SMP */
+}
+
+#ifdef CONFIG_BOOTX_TEXT
+void
+btext_progress(char *s, unsigned short hex)
+{
+ btext_drawstring(s);
+ btext_drawstring("\n");
+}
+#endif /* CONFIG_BOOTX_TEXT */
diff --git a/arch/powerpc/platforms/chrp/smp.c b/arch/powerpc/platforms/chrp/smp.c
new file mode 100644
index 000000000000..31ee49c25014
--- /dev/null
+++ b/arch/powerpc/platforms/chrp/smp.c
@@ -0,0 +1,122 @@
+/*
+ * Smp support for CHRP machines.
+ *
+ * Written by Cort Dougan (cort@cs.nmt.edu) borrowing a great
+ * deal of code from the sparc and intel versions.
+ *
+ * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+
+#include <asm/ptrace.h>
+#include <asm/atomic.h>
+#include <asm/irq.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/sections.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/smp.h>
+#include <asm/residual.h>
+#include <asm/time.h>
+#include <asm/open_pic.h>
+#include <asm/machdep.h>
+#include <asm/smp.h>
+#include <asm/mpic.h>
+
+extern unsigned long smp_chrp_cpu_nr;
+
+static int __init smp_chrp_probe(void)
+{
+ struct device_node *cpus = NULL;
+ unsigned int *reg;
+ int reglen;
+ int ncpus = 0;
+ int cpuid;
+ unsigned int phys;
+
+ /* Count CPUs in the device-tree */
+ cpuid = 1; /* the boot cpu is logical cpu 0 */
+ while ((cpus = of_find_node_by_type(cpus, "cpu")) != NULL) {
+ phys = ncpus;
+ reg = (unsigned int *) get_property(cpus, "reg", &reglen);
+ if (reg && reglen >= sizeof(unsigned int))
+ /* hmmm, not having a reg property would be bad */
+ phys = *reg;
+ if (phys != boot_cpuid_phys) {
+ set_hard_smp_processor_id(cpuid, phys);
+ ++cpuid;
+ }
+ ++ncpus;
+ }
+
+ printk(KERN_INFO "CHRP SMP probe found %d cpus\n", ncpus);
+
+ /* Nothing more to do if less than 2 of them */
+ if (ncpus <= 1)
+ return 1;
+
+ mpic_request_ipis();
+
+ return ncpus;
+}
+
+static void __devinit smp_chrp_kick_cpu(int nr)
+{
+ *(unsigned long *)KERNELBASE = nr;
+ asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory");
+}
+
+static void __devinit smp_chrp_setup_cpu(int cpu_nr)
+{
+ mpic_setup_this_cpu();
+}
+
+static DEFINE_SPINLOCK(timebase_lock);
+static unsigned int timebase_upper = 0, timebase_lower = 0;
+
+void __devinit smp_chrp_give_timebase(void)
+{
+ spin_lock(&timebase_lock);
+ rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL);
+ timebase_upper = get_tbu();
+ timebase_lower = get_tbl();
+ spin_unlock(&timebase_lock);
+
+ while (timebase_upper || timebase_lower)
+ barrier();
+ rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL);
+}
+
+void __devinit smp_chrp_take_timebase(void)
+{
+ while (!(timebase_upper || timebase_lower))
+ barrier();
+ spin_lock(&timebase_lock);
+ set_tb(timebase_upper, timebase_lower);
+ timebase_upper = 0;
+ timebase_lower = 0;
+ spin_unlock(&timebase_lock);
+ printk("CPU %i taken timebase\n", smp_processor_id());
+}
+
+/* CHRP with openpic */
+struct smp_ops_t chrp_smp_ops = {
+ .message_pass = smp_mpic_message_pass,
+ .probe = smp_chrp_probe,
+ .kick_cpu = smp_chrp_kick_cpu,
+ .setup_cpu = smp_chrp_setup_cpu,
+ .give_timebase = smp_chrp_give_timebase,
+ .take_timebase = smp_chrp_take_timebase,
+};
diff --git a/arch/powerpc/platforms/chrp/time.c b/arch/powerpc/platforms/chrp/time.c
new file mode 100644
index 000000000000..9e53535ddb82
--- /dev/null
+++ b/arch/powerpc/platforms/chrp/time.c
@@ -0,0 +1,188 @@
+/*
+ * arch/ppc/platforms/chrp_time.c
+ *
+ * Copyright (C) 1991, 1992, 1995 Linus Torvalds
+ *
+ * Adapted for PowerPC (PReP) by Gary Thomas
+ * Modified by Cort Dougan (cort@cs.nmt.edu).
+ * Copied and modified from arch/i386/kernel/time.c
+ *
+ */
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/kernel_stat.h>
+#include <linux/mc146818rtc.h>
+#include <linux/init.h>
+#include <linux/bcd.h>
+
+#include <asm/io.h>
+#include <asm/nvram.h>
+#include <asm/prom.h>
+#include <asm/sections.h>
+#include <asm/time.h>
+
+extern spinlock_t rtc_lock;
+
+static int nvram_as1 = NVRAM_AS1;
+static int nvram_as0 = NVRAM_AS0;
+static int nvram_data = NVRAM_DATA;
+
+long __init chrp_time_init(void)
+{
+ struct device_node *rtcs;
+ int base;
+
+ rtcs = find_compatible_devices("rtc", "pnpPNP,b00");
+ if (rtcs == NULL)
+ rtcs = find_compatible_devices("rtc", "ds1385-rtc");
+ if (rtcs == NULL || rtcs->addrs == NULL)
+ return 0;
+ base = rtcs->addrs[0].address;
+ nvram_as1 = 0;
+ nvram_as0 = base;
+ nvram_data = base + 1;
+
+ return 0;
+}
+
+int chrp_cmos_clock_read(int addr)
+{
+ if (nvram_as1 != 0)
+ outb(addr>>8, nvram_as1);
+ outb(addr, nvram_as0);
+ return (inb(nvram_data));
+}
+
+void chrp_cmos_clock_write(unsigned long val, int addr)
+{
+ if (nvram_as1 != 0)
+ outb(addr>>8, nvram_as1);
+ outb(addr, nvram_as0);
+ outb(val, nvram_data);
+ return;
+}
+
+/*
+ * Set the hardware clock. -- Cort
+ */
+int chrp_set_rtc_time(struct rtc_time *tmarg)
+{
+ unsigned char save_control, save_freq_select;
+ struct rtc_time tm = *tmarg;
+
+ spin_lock(&rtc_lock);
+
+ save_control = chrp_cmos_clock_read(RTC_CONTROL); /* tell the clock it's being set */
+
+ chrp_cmos_clock_write((save_control|RTC_SET), RTC_CONTROL);
+
+ save_freq_select = chrp_cmos_clock_read(RTC_FREQ_SELECT); /* stop and reset prescaler */
+
+ chrp_cmos_clock_write((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
+
+ tm.tm_year -= 1900;
+ if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+ BIN_TO_BCD(tm.tm_sec);
+ BIN_TO_BCD(tm.tm_min);
+ BIN_TO_BCD(tm.tm_hour);
+ BIN_TO_BCD(tm.tm_mon);
+ BIN_TO_BCD(tm.tm_mday);
+ BIN_TO_BCD(tm.tm_year);
+ }
+ chrp_cmos_clock_write(tm.tm_sec,RTC_SECONDS);
+ chrp_cmos_clock_write(tm.tm_min,RTC_MINUTES);
+ chrp_cmos_clock_write(tm.tm_hour,RTC_HOURS);
+ chrp_cmos_clock_write(tm.tm_mon,RTC_MONTH);
+ chrp_cmos_clock_write(tm.tm_mday,RTC_DAY_OF_MONTH);
+ chrp_cmos_clock_write(tm.tm_year,RTC_YEAR);
+
+ /* The following flags have to be released exactly in this order,
+ * otherwise the DS12887 (popular MC146818A clone with integrated
+ * battery and quartz) will not reset the oscillator and will not
+ * update precisely 500 ms later. You won't find this mentioned in
+ * the Dallas Semiconductor data sheets, but who believes data
+ * sheets anyway ... -- Markus Kuhn
+ */
+ chrp_cmos_clock_write(save_control, RTC_CONTROL);
+ chrp_cmos_clock_write(save_freq_select, RTC_FREQ_SELECT);
+
+ spin_unlock(&rtc_lock);
+ return 0;
+}
+
+void chrp_get_rtc_time(struct rtc_time *tm)
+{
+ unsigned int year, mon, day, hour, min, sec;
+ int uip, i;
+
+ /* The Linux interpretation of the CMOS clock register contents:
+ * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
+ * RTC registers show the second which has precisely just started.
+ * Let's hope other operating systems interpret the RTC the same way.
+ */
+
+ /* Since the UIP flag is set for about 2.2 ms and the clock
+ * is typically written with a precision of 1 jiffy, trying
+ * to obtain a precision better than a few milliseconds is
+ * an illusion. Only consistency is interesting, this also
+ * allows to use the routine for /dev/rtc without a potential
+ * 1 second kernel busy loop triggered by any reader of /dev/rtc.
+ */
+
+ for ( i = 0; i<1000000; i++) {
+ uip = chrp_cmos_clock_read(RTC_FREQ_SELECT);
+ sec = chrp_cmos_clock_read(RTC_SECONDS);
+ min = chrp_cmos_clock_read(RTC_MINUTES);
+ hour = chrp_cmos_clock_read(RTC_HOURS);
+ day = chrp_cmos_clock_read(RTC_DAY_OF_MONTH);
+ mon = chrp_cmos_clock_read(RTC_MONTH);
+ year = chrp_cmos_clock_read(RTC_YEAR);
+ uip |= chrp_cmos_clock_read(RTC_FREQ_SELECT);
+ if ((uip & RTC_UIP)==0) break;
+ }
+
+ if (!(chrp_cmos_clock_read(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+ BCD_TO_BIN(sec);
+ BCD_TO_BIN(min);
+ BCD_TO_BIN(hour);
+ BCD_TO_BIN(day);
+ BCD_TO_BIN(mon);
+ BCD_TO_BIN(year);
+ }
+ if ((year += 1900) < 1970)
+ year += 100;
+ tm->tm_sec = sec;
+ tm->tm_min = min;
+ tm->tm_hour = hour;
+ tm->tm_mday = day;
+ tm->tm_mon = mon;
+ tm->tm_year = year;
+}
+
+
+void __init chrp_calibrate_decr(void)
+{
+ struct device_node *cpu;
+ unsigned int freq, *fp;
+
+ /*
+ * The cpu node should have a timebase-frequency property
+ * to tell us the rate at which the decrementer counts.
+ */
+ freq = 16666000; /* hardcoded default */
+ cpu = find_type_devices("cpu");
+ if (cpu != 0) {
+ fp = (unsigned int *)
+ get_property(cpu, "timebase-frequency", NULL);
+ if (fp != 0)
+ freq = *fp;
+ }
+ ppc_tb_freq = freq;
+}
diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig
new file mode 100644
index 000000000000..81250090f98d
--- /dev/null
+++ b/arch/powerpc/platforms/embedded6xx/Kconfig
@@ -0,0 +1,318 @@
+choice
+ prompt "Machine Type"
+ depends on EMBEDDED6xx
+
+config KATANA
+ bool "Artesyn-Katana"
+ help
+ Select KATANA if configuring an Artesyn KATANA 750i or 3750
+ cPCI board.
+
+config WILLOW
+ bool "Cogent-Willow"
+
+config CPCI690
+ bool "Force-CPCI690"
+ help
+ Select CPCI690 if configuring a Force CPCI690 cPCI board.
+
+config POWERPMC250
+ bool "Force-PowerPMC250"
+
+config CHESTNUT
+ bool "IBM 750FX Eval board or 750GX Eval board"
+ help
+ Select CHESTNUT if configuring an IBM 750FX Eval Board or a
+ IBM 750GX Eval board.
+
+config SPRUCE
+ bool "IBM-Spruce"
+ select PPC_INDIRECT_PCI
+
+config HDPU
+ bool "Sky-HDPU"
+ help
+ Select HDPU if configuring a Sky Computers Compute Blade.
+
+config HDPU_FEATURES
+ depends HDPU
+ tristate "HDPU-Features"
+ help
+ Select to enable HDPU enhanced features.
+
+config EV64260
+ bool "Marvell-EV64260BP"
+ help
+ Select EV64260 if configuring a Marvell (formerly Galileo)
+ EV64260BP Evaluation platform.
+
+config LOPEC
+ bool "Motorola-LoPEC"
+ select PPC_I8259
+
+config MVME5100
+ bool "Motorola-MVME5100"
+ select PPC_INDIRECT_PCI
+
+config PPLUS
+ bool "Motorola-PowerPlus"
+ select PPC_I8259
+ select PPC_INDIRECT_PCI
+
+config PRPMC750
+ bool "Motorola-PrPMC750"
+ select PPC_INDIRECT_PCI
+
+config PRPMC800
+ bool "Motorola-PrPMC800"
+ select PPC_INDIRECT_PCI
+
+config SANDPOINT
+ bool "Motorola-Sandpoint"
+ select PPC_I8259
+ help
+ Select SANDPOINT if configuring for a Motorola Sandpoint X3
+ (any flavor).
+
+config RADSTONE_PPC7D
+ bool "Radstone Technology PPC7D board"
+ select PPC_I8259
+
+config PAL4
+ bool "SBS-Palomar4"
+
+config GEMINI
+ bool "Synergy-Gemini"
+ select PPC_INDIRECT_PCI
+ depends on BROKEN
+ help
+ Select Gemini if configuring for a Synergy Microsystems' Gemini
+ series Single Board Computer. More information is available at:
+ <http://www.synergymicro.com/PressRel/97_10_15.html>.
+
+config EST8260
+ bool "EST8260"
+ ---help---
+ The EST8260 is a single-board computer manufactured by Wind River
+ Systems, Inc. (formerly Embedded Support Tools Corp.) and based on
+ the MPC8260. Wind River Systems has a website at
+ <http://www.windriver.com/>, but the EST8260 cannot be found on it
+ and has probably been discontinued or rebadged.
+
+config SBC82xx
+ bool "SBC82xx"
+ ---help---
+ SBC PowerQUICC II, single-board computer with MPC82xx CPU
+ Manufacturer: Wind River Systems, Inc.
+ Date of Release: May 2003
+ End of Life: -
+ URL: <http://www.windriver.com/>
+
+config SBS8260
+ bool "SBS8260"
+
+config RPX8260
+ bool "RPXSUPER"
+
+config TQM8260
+ bool "TQM8260"
+ ---help---
+ MPC8260 based module, little larger than credit card,
+ up to 128 MB global + 64 MB local RAM, 32 MB Flash,
+ 32 kB EEPROM, 256 kB L@ Cache, 10baseT + 100baseT Ethernet,
+ 2 x serial ports, ...
+ Manufacturer: TQ Components, www.tq-group.de
+ Date of Release: June 2001
+ End of Life: not yet :-)
+ URL: <http://www.denx.de/PDF/TQM82xx_SPEC_Rev005.pdf>
+
+config ADS8272
+ bool "ADS8272"
+
+config PQ2FADS
+ bool "Freescale-PQ2FADS"
+ help
+ Select PQ2FADS if you wish to configure for a Freescale
+ PQ2FADS board (-VR or -ZU).
+
+config LITE5200
+ bool "Freescale LITE5200 / (IceCube)"
+ select PPC_MPC52xx
+ help
+ Support for the LITE5200 dev board for the MPC5200 from Freescale.
+ This is for the LITE5200 version 2.0 board. Don't know if it changes
+ much but it's only been tested on this board version. I think this
+ board is also known as IceCube.
+
+config MPC834x_SYS
+ bool "Freescale MPC834x SYS"
+ help
+ This option enables support for the MPC 834x SYS evaluation board.
+
+ Be aware that PCI buses can only function when SYS board is plugged
+ into the PIB (Platform IO Board) board from Freescale which provide
+ 3 PCI slots. The PIBs PCI initialization is the bootloader's
+ responsiblilty.
+
+config EV64360
+ bool "Marvell-EV64360BP"
+ help
+ Select EV64360 if configuring a Marvell EV64360BP Evaluation
+ platform.
+endchoice
+
+config PQ2ADS
+ bool
+ depends on ADS8272
+ default y
+
+config TQM8xxL
+ bool
+ depends on 8xx && (TQM823L || TQM850L || FPS850L || TQM855L || TQM860L)
+ default y
+
+config PPC_MPC52xx
+ bool
+
+config 8260
+ bool "CPM2 Support" if WILLOW
+ depends on 6xx
+ default y if TQM8260 || RPX8260 || EST8260 || SBS8260 || SBC82xx || PQ2FADS
+ help
+ The MPC8260 is a typical embedded CPU made by Motorola. Selecting
+ this option means that you wish to build a kernel for a machine with
+ an 8260 class CPU.
+
+config 8272
+ bool
+ depends on 6xx
+ default y if ADS8272
+ select 8260
+ help
+ The MPC8272 CPM has a different internal dpram setup than other CPM2
+ devices
+
+config 83xx
+ bool
+ default y if MPC834x_SYS
+
+config MPC834x
+ bool
+ default y if MPC834x_SYS
+
+config CPM2
+ bool
+ depends on 8260 || MPC8560 || MPC8555
+ default y
+ help
+ The CPM2 (Communications Processor Module) is a coprocessor on
+ embedded CPUs made by Motorola. Selecting this option means that
+ you wish to build a kernel for a machine with a CPM2 coprocessor
+ on it (826x, 827x, 8560).
+
+config PPC_GEN550
+ bool
+ depends on SANDPOINT || SPRUCE || PPLUS || \
+ PRPMC750 || PRPMC800 || LOPEC || \
+ (EV64260 && !SERIAL_MPSC) || CHESTNUT || RADSTONE_PPC7D || \
+ 83xx
+ default y
+
+config FORCE
+ bool
+ depends on 6xx && POWERPMC250
+ default y
+
+config GT64260
+ bool
+ depends on EV64260 || CPCI690
+ default y
+
+config MV64360 # Really MV64360 & MV64460
+ bool
+ depends on CHESTNUT || KATANA || RADSTONE_PPC7D || HDPU || EV64360
+ default y
+
+config MV64X60
+ bool
+ depends on (GT64260 || MV64360)
+ select PPC_INDIRECT_PCI
+ default y
+
+menu "Set bridge options"
+ depends on MV64X60
+
+config NOT_COHERENT_CACHE
+ bool "Turn off Cache Coherency"
+ default n
+ help
+ Some 64x60 bridges lock up when trying to enforce cache coherency.
+ When this option is selected, cache coherency will be turned off.
+ Note that this can cause other problems (e.g., stale data being
+ speculatively loaded via a cached mapping). Use at your own risk.
+
+config MV64X60_BASE
+ hex "Set bridge base used by firmware"
+ default "0xf1000000"
+ help
+ A firmware can leave the base address of the bridge's registers at
+ a non-standard location. If so, set this value to reflect the
+ address of that non-standard location.
+
+config MV64X60_NEW_BASE
+ hex "Set bridge base used by kernel"
+ default "0xf1000000"
+ help
+ If the current base address of the bridge's registers is not where
+ you want it, set this value to the address that you want it moved to.
+
+endmenu
+
+config NONMONARCH_SUPPORT
+ bool "Enable Non-Monarch Support"
+ depends on PRPMC800
+
+config HARRIER
+ bool
+ depends on PRPMC800
+ default y
+
+config EPIC_SERIAL_MODE
+ bool
+ depends on 6xx && (LOPEC || SANDPOINT)
+ default y
+
+config MPC10X_BRIDGE
+ bool
+ depends on POWERPMC250 || LOPEC || SANDPOINT
+ select PPC_INDIRECT_PCI
+ default y
+
+config MPC10X_OPENPIC
+ bool
+ depends on POWERPMC250 || LOPEC || SANDPOINT
+ default y
+
+config MPC10X_STORE_GATHERING
+ bool "Enable MPC10x store gathering"
+ depends on MPC10X_BRIDGE
+
+config SANDPOINT_ENABLE_UART1
+ bool "Enable DUART mode on Sandpoint"
+ depends on SANDPOINT
+ help
+ If this option is enabled then the MPC824x processor will run
+ in DUART mode instead of UART mode.
+
+config HARRIER_STORE_GATHERING
+ bool "Enable Harrier store gathering"
+ depends on HARRIER
+
+config MVME5100_IPMC761_PRESENT
+ bool "MVME5100 configured with an IPMC761"
+ depends on MVME5100
+ select PPC_I8259
+
+config SPRUCE_BAUD_33M
+ bool "Spruce baud clock support"
+ depends on SPRUCE
diff --git a/arch/powerpc/platforms/iseries/Kconfig b/arch/powerpc/platforms/iseries/Kconfig
new file mode 100644
index 000000000000..3d957a30c8c2
--- /dev/null
+++ b/arch/powerpc/platforms/iseries/Kconfig
@@ -0,0 +1,31 @@
+
+menu "iSeries device drivers"
+ depends on PPC_ISERIES
+
+config VIOCONS
+ tristate "iSeries Virtual Console Support"
+
+config VIODASD
+ tristate "iSeries Virtual I/O disk support"
+ help
+ If you are running on an iSeries system and you want to use
+ virtual disks created and managed by OS/400, say Y.
+
+config VIOCD
+ tristate "iSeries Virtual I/O CD support"
+ help
+ If you are running Linux on an IBM iSeries system and you want to
+ read a CD drive owned by OS/400, say Y here.
+
+config VIOTAPE
+ tristate "iSeries Virtual Tape Support"
+ help
+ If you are running Linux on an iSeries system and you want Linux
+ to read and/or write a tape drive owned by OS/400, say Y here.
+
+endmenu
+
+config VIOPATH
+ bool
+ depends on VIOCONS || VIODASD || VIOCD || VIOTAPE || VETH
+ default y
diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile
new file mode 100644
index 000000000000..127b465308be
--- /dev/null
+++ b/arch/powerpc/platforms/iseries/Makefile
@@ -0,0 +1,9 @@
+EXTRA_CFLAGS += -mno-minimal-toc
+
+obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o mf.o lpevents.o \
+ hvcall.o proc.o htab.o iommu.o misc.o
+obj-$(CONFIG_PCI) += pci.o irq.o vpdinfo.o
+obj-$(CONFIG_IBMVIO) += vio.o
+obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_VIOPATH) += viopath.o
+obj-$(CONFIG_MODULES) += ksyms.o
diff --git a/include/asm-ppc64/iSeries/HvCallHpt.h b/arch/powerpc/platforms/iseries/call_hpt.h
index 43a1969230b8..321f3bb7a8f5 100644
--- a/include/asm-ppc64/iSeries/HvCallHpt.h
+++ b/arch/powerpc/platforms/iseries/call_hpt.h
@@ -1,5 +1,4 @@
/*
- * HvCallHpt.h
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
@@ -16,8 +15,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _HVCALLHPT_H
-#define _HVCALLHPT_H
+#ifndef _PLATFORMS_ISERIES_CALL_HPT_H
+#define _PLATFORMS_ISERIES_CALL_HPT_H
/*
* This file contains the "hypervisor call" interface which is used to
@@ -99,4 +98,4 @@ static inline void HvCallHpt_addValidate(u32 hpteIndex, u32 hBit, hpte_t *hpte)
HvCall4(HvCallHptAddValidate, hpteIndex, hBit, hpte->v, hpte->r);
}
-#endif /* _HVCALLHPT_H */
+#endif /* _PLATFORMS_ISERIES_CALL_HPT_H */
diff --git a/include/asm-ppc64/iSeries/HvCallPci.h b/arch/powerpc/platforms/iseries/call_pci.h
index c8d675c40f5e..a86e065b9577 100644
--- a/include/asm-ppc64/iSeries/HvCallPci.h
+++ b/arch/powerpc/platforms/iseries/call_pci.h
@@ -22,8 +22,8 @@
* Created, Jan 9, 2001
*/
-#ifndef _HVCALLPCI_H
-#define _HVCALLPCI_H
+#ifndef _PLATFORMS_ISERIES_CALL_PCI_H
+#define _PLATFORMS_ISERIES_CALL_PCI_H
#include <asm/iSeries/HvCallSc.h>
#include <asm/iSeries/HvTypes.h>
@@ -126,25 +126,6 @@ enum HvCallPci_VpdType {
#define HvCallPciUnmaskInterrupts HvCallPci + 49
#define HvCallPciGetBusUnitInfo HvCallPci + 50
-static inline u64 HvCallPci_configLoad8(u16 busNumber, u8 subBusNumber,
- u8 deviceId, u32 offset, u8 *value)
-{
- struct HvCallPci_DsaAddr dsa;
- struct HvCallPci_LoadReturn retVal;
-
- *((u64*)&dsa) = 0;
-
- dsa.busNumber = busNumber;
- dsa.subBusNumber = subBusNumber;
- dsa.deviceId = deviceId;
-
- HvCall3Ret16(HvCallPciConfigLoad8, &retVal, *(u64 *)&dsa, offset, 0);
-
- *value = retVal.value;
-
- return retVal.rc;
-}
-
static inline u64 HvCallPci_configLoad16(u16 busNumber, u8 subBusNumber,
u8 deviceId, u32 offset, u16 *value)
{
@@ -164,25 +145,6 @@ static inline u64 HvCallPci_configLoad16(u16 busNumber, u8 subBusNumber,
return retVal.rc;
}
-static inline u64 HvCallPci_configLoad32(u16 busNumber, u8 subBusNumber,
- u8 deviceId, u32 offset, u32 *value)
-{
- struct HvCallPci_DsaAddr dsa;
- struct HvCallPci_LoadReturn retVal;
-
- *((u64*)&dsa) = 0;
-
- dsa.busNumber = busNumber;
- dsa.subBusNumber = subBusNumber;
- dsa.deviceId = deviceId;
-
- HvCall3Ret16(HvCallPciConfigLoad32, &retVal, *(u64 *)&dsa, offset, 0);
-
- *value = retVal.value;
-
- return retVal.rc;
-}
-
static inline u64 HvCallPci_configStore8(u16 busNumber, u8 subBusNumber,
u8 deviceId, u32 offset, u8 value)
{
@@ -197,186 +159,6 @@ static inline u64 HvCallPci_configStore8(u16 busNumber, u8 subBusNumber,
return HvCall4(HvCallPciConfigStore8, *(u64 *)&dsa, offset, value, 0);
}
-static inline u64 HvCallPci_configStore16(u16 busNumber, u8 subBusNumber,
- u8 deviceId, u32 offset, u16 value)
-{
- struct HvCallPci_DsaAddr dsa;
-
- *((u64*)&dsa) = 0;
-
- dsa.busNumber = busNumber;
- dsa.subBusNumber = subBusNumber;
- dsa.deviceId = deviceId;
-
- return HvCall4(HvCallPciConfigStore16, *(u64 *)&dsa, offset, value, 0);
-}
-
-static inline u64 HvCallPci_configStore32(u16 busNumber, u8 subBusNumber,
- u8 deviceId, u32 offset, u32 value)
-{
- struct HvCallPci_DsaAddr dsa;
-
- *((u64*)&dsa) = 0;
-
- dsa.busNumber = busNumber;
- dsa.subBusNumber = subBusNumber;
- dsa.deviceId = deviceId;
-
- return HvCall4(HvCallPciConfigStore32, *(u64 *)&dsa, offset, value, 0);
-}
-
-static inline u64 HvCallPci_barLoad8(u16 busNumberParm, u8 subBusParm,
- u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
- u8 *valueParm)
-{
- struct HvCallPci_DsaAddr dsa;
- struct HvCallPci_LoadReturn retVal;
-
- *((u64*)&dsa) = 0;
-
- dsa.busNumber = busNumberParm;
- dsa.subBusNumber = subBusParm;
- dsa.deviceId = deviceIdParm;
- dsa.barNumber = barNumberParm;
-
- HvCall3Ret16(HvCallPciBarLoad8, &retVal, *(u64 *)&dsa, offsetParm, 0);
-
- *valueParm = retVal.value;
-
- return retVal.rc;
-}
-
-static inline u64 HvCallPci_barLoad16(u16 busNumberParm, u8 subBusParm,
- u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
- u16 *valueParm)
-{
- struct HvCallPci_DsaAddr dsa;
- struct HvCallPci_LoadReturn retVal;
-
- *((u64*)&dsa) = 0;
-
- dsa.busNumber = busNumberParm;
- dsa.subBusNumber = subBusParm;
- dsa.deviceId = deviceIdParm;
- dsa.barNumber = barNumberParm;
-
- HvCall3Ret16(HvCallPciBarLoad16, &retVal, *(u64 *)&dsa, offsetParm, 0);
-
- *valueParm = retVal.value;
-
- return retVal.rc;
-}
-
-static inline u64 HvCallPci_barLoad32(u16 busNumberParm, u8 subBusParm,
- u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
- u32 *valueParm)
-{
- struct HvCallPci_DsaAddr dsa;
- struct HvCallPci_LoadReturn retVal;
-
- *((u64*)&dsa) = 0;
-
- dsa.busNumber = busNumberParm;
- dsa.subBusNumber = subBusParm;
- dsa.deviceId = deviceIdParm;
- dsa.barNumber = barNumberParm;
-
- HvCall3Ret16(HvCallPciBarLoad32, &retVal, *(u64 *)&dsa, offsetParm, 0);
-
- *valueParm = retVal.value;
-
- return retVal.rc;
-}
-
-static inline u64 HvCallPci_barLoad64(u16 busNumberParm, u8 subBusParm,
- u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
- u64 *valueParm)
-{
- struct HvCallPci_DsaAddr dsa;
- struct HvCallPci_LoadReturn retVal;
-
- *((u64*)&dsa) = 0;
-
- dsa.busNumber = busNumberParm;
- dsa.subBusNumber = subBusParm;
- dsa.deviceId = deviceIdParm;
- dsa.barNumber = barNumberParm;
-
- HvCall3Ret16(HvCallPciBarLoad64, &retVal, *(u64 *)&dsa, offsetParm, 0);
-
- *valueParm = retVal.value;
-
- return retVal.rc;
-}
-
-static inline u64 HvCallPci_barStore8(u16 busNumberParm, u8 subBusParm,
- u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
- u8 valueParm)
-{
- struct HvCallPci_DsaAddr dsa;
-
- *((u64*)&dsa) = 0;
-
- dsa.busNumber = busNumberParm;
- dsa.subBusNumber = subBusParm;
- dsa.deviceId = deviceIdParm;
- dsa.barNumber = barNumberParm;
-
- return HvCall4(HvCallPciBarStore8, *(u64 *)&dsa, offsetParm,
- valueParm, 0);
-}
-
-static inline u64 HvCallPci_barStore16(u16 busNumberParm, u8 subBusParm,
- u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
- u16 valueParm)
-{
- struct HvCallPci_DsaAddr dsa;
-
- *((u64*)&dsa) = 0;
-
- dsa.busNumber = busNumberParm;
- dsa.subBusNumber = subBusParm;
- dsa.deviceId = deviceIdParm;
- dsa.barNumber = barNumberParm;
-
- return HvCall4(HvCallPciBarStore16, *(u64 *)&dsa, offsetParm,
- valueParm, 0);
-}
-
-static inline u64 HvCallPci_barStore32(u16 busNumberParm, u8 subBusParm,
- u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
- u32 valueParm)
-{
- struct HvCallPci_DsaAddr dsa;
-
- *((u64*)&dsa) = 0;
-
- dsa.busNumber = busNumberParm;
- dsa.subBusNumber = subBusParm;
- dsa.deviceId = deviceIdParm;
- dsa.barNumber = barNumberParm;
-
- return HvCall4(HvCallPciBarStore32, *(u64 *)&dsa, offsetParm,
- valueParm, 0);
-}
-
-static inline u64 HvCallPci_barStore64(u16 busNumberParm, u8 subBusParm,
- u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
- u64 valueParm)
-{
- struct HvCallPci_DsaAddr dsa;
-
- *((u64*)&dsa) = 0;
-
- dsa.busNumber = busNumberParm;
- dsa.subBusNumber = subBusParm;
- dsa.deviceId = deviceIdParm;
- dsa.barNumber = barNumberParm;
-
- return HvCall4(HvCallPciBarStore64, *(u64 *)&dsa, offsetParm,
- valueParm, 0);
-}
-
static inline u64 HvCallPci_eoi(u16 busNumberParm, u8 subBusParm,
u8 deviceIdParm)
{
@@ -437,20 +219,6 @@ static inline u64 HvCallPci_unmaskFisr(u16 busNumberParm, u8 subBusParm,
return HvCall2(HvCallPciUnmaskFisr, *(u64*)&dsa, fisrMask);
}
-static inline u64 HvCallPci_setSlotReset(u16 busNumberParm, u8 subBusParm,
- u8 deviceIdParm, u64 onNotOff)
-{
- struct HvCallPci_DsaAddr dsa;
-
- *((u64*)&dsa) = 0;
-
- dsa.busNumber = busNumberParm;
- dsa.subBusNumber = subBusParm;
- dsa.deviceId = deviceIdParm;
-
- return HvCall2(HvCallPciSetSlotReset, *(u64*)&dsa, onNotOff);
-}
-
static inline u64 HvCallPci_getDeviceInfo(u16 busNumberParm, u8 subBusParm,
u8 deviceNumberParm, u64 parms, u32 sizeofParms)
{
@@ -519,15 +287,4 @@ static inline int HvCallPci_getBusVpd(u16 busNumParm, u64 destParm,
return xRc & 0xFFFF;
}
-static inline int HvCallPci_getBusAdapterVpd(u16 busNumParm, u64 destParm,
- u16 sizeParm)
-{
- u64 xRc = HvCall4(HvCallPciGetCardVpd, busNumParm, destParm,
- sizeParm, HvCallPci_BusAdapterVpd);
- if (xRc == -1)
- return -1;
- else
- return xRc & 0xFFFF;
-}
-
-#endif /* _HVCALLPCI_H */
+#endif /* _PLATFORMS_ISERIES_CALL_PCI_H */
diff --git a/include/asm-ppc64/iSeries/HvCallSm.h b/arch/powerpc/platforms/iseries/call_sm.h
index 8a3dbb071a43..ef223166cf22 100644
--- a/include/asm-ppc64/iSeries/HvCallSm.h
+++ b/arch/powerpc/platforms/iseries/call_sm.h
@@ -1,5 +1,4 @@
/*
- * HvCallSm.h
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
@@ -16,8 +15,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _HVCALLSM_H
-#define _HVCALLSM_H
+#ifndef _ISERIES_CALL_SM_H
+#define _ISERIES_CALL_SM_H
/*
* This file contains the "hypervisor call" interface which is used to
@@ -35,4 +34,4 @@ static inline u64 HvCallSm_get64BitsOfAccessMap(HvLpIndex lpIndex,
return HvCall2(HvCallSmGet64BitsOfAccessMap, lpIndex, indexIntoBitMap);
}
-#endif /* _HVCALLSM_H */
+#endif /* _ISERIES_CALL_SM_H */
diff --git a/arch/ppc64/kernel/iSeries_htab.c b/arch/powerpc/platforms/iseries/htab.c
index 073b76661747..b3c6c3374ca6 100644
--- a/arch/ppc64/kernel/iSeries_htab.c
+++ b/arch/powerpc/platforms/iseries/htab.c
@@ -1,10 +1,10 @@
/*
* iSeries hashtable management.
- * Derived from pSeries_htab.c
+ * Derived from pSeries_htab.c
*
* SMP scalability work:
* Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
- *
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
@@ -14,11 +14,13 @@
#include <asm/pgtable.h>
#include <asm/mmu.h>
#include <asm/mmu_context.h>
-#include <asm/iSeries/HvCallHpt.h>
#include <asm/abs_addr.h>
#include <linux/spinlock.h>
-static spinlock_t iSeries_hlocks[64] __cacheline_aligned_in_smp = { [0 ... 63] = SPIN_LOCK_UNLOCKED};
+#include "call_hpt.h"
+
+static spinlock_t iSeries_hlocks[64] __cacheline_aligned_in_smp =
+ { [0 ... 63] = SPIN_LOCK_UNLOCKED};
/*
* Very primitive algorithm for picking up a lock
@@ -84,6 +86,25 @@ static long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va,
return (secondary << 3) | (slot & 7);
}
+long iSeries_hpte_bolt_or_insert(unsigned long hpte_group,
+ unsigned long va, unsigned long prpn, unsigned long vflags,
+ unsigned long rflags)
+{
+ long slot;
+ hpte_t lhpte;
+
+ slot = HvCallHpt_findValid(&lhpte, va >> PAGE_SHIFT);
+
+ if (lhpte.v & HPTE_V_VALID) {
+ /* Bolt the existing HPTE */
+ HvCallHpt_setSwBits(slot, 0x10, 0);
+ HvCallHpt_setPp(slot, PP_RWXX);
+ return 0;
+ }
+
+ return iSeries_hpte_insert(hpte_group, va, prpn, vflags, rflags);
+}
+
static unsigned long iSeries_hpte_getword0(unsigned long slot)
{
hpte_t hpte;
@@ -107,7 +128,7 @@ static long iSeries_hpte_remove(unsigned long hpte_group)
hpte_v = iSeries_hpte_getword0(hpte_group + slot_offset);
if (! (hpte_v & HPTE_V_BOLTED)) {
- HvCallHpt_invalidateSetSwBitsGet(hpte_group +
+ HvCallHpt_invalidateSetSwBitsGet(hpte_group +
slot_offset, 0, 0);
iSeries_hunlock(hpte_group);
return i;
@@ -124,9 +145,9 @@ static long iSeries_hpte_remove(unsigned long hpte_group)
/*
* The HyperVisor expects the "flags" argument in this form:
- * bits 0..59 : reserved
- * bit 60 : N
- * bits 61..63 : PP2,PP1,PP0
+ * bits 0..59 : reserved
+ * bit 60 : N
+ * bits 61..63 : PP2,PP1,PP0
*/
static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp,
unsigned long va, int large, int local)
@@ -152,7 +173,7 @@ static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp,
}
/*
- * Functions used to find the PTE for a particular virtual address.
+ * Functions used to find the PTE for a particular virtual address.
* Only used during boot when bolting pages.
*
* Input : vpn : virtual page number
@@ -170,7 +191,7 @@ static long iSeries_hpte_find(unsigned long vpn)
* 0x00000000xxxxxxxx : Entry found in primary group, slot x
* 0x80000000xxxxxxxx : Entry found in secondary group, slot x
*/
- slot = HvCallHpt_findValid(&hpte, vpn);
+ slot = HvCallHpt_findValid(&hpte, vpn);
if (hpte.v & HPTE_V_VALID) {
if (slot < 0) {
slot &= 0x7fffffffffffffff;
@@ -197,7 +218,7 @@ static void iSeries_hpte_updateboltedpp(unsigned long newpp, unsigned long ea)
vsid = get_kernel_vsid(ea);
va = (vsid << 28) | (ea & 0x0fffffff);
vpn = va >> PAGE_SHIFT;
- slot = iSeries_hpte_find(vpn);
+ slot = iSeries_hpte_find(vpn);
if (slot == -1)
panic("updateboltedpp: Could not find page to bolt\n");
HvCallHpt_setPp(slot, newpp);
@@ -215,7 +236,7 @@ static void iSeries_hpte_invalidate(unsigned long slot, unsigned long va,
iSeries_hlock(slot);
hpte_v = iSeries_hpte_getword0(slot);
-
+
if ((HPTE_V_AVPN_VAL(hpte_v) == avpn) && (hpte_v & HPTE_V_VALID))
HvCallHpt_invalidateSetSwBitsGet(slot, 0, 0);
@@ -230,7 +251,7 @@ void hpte_init_iSeries(void)
ppc_md.hpte_updatepp = iSeries_hpte_updatepp;
ppc_md.hpte_updateboltedpp = iSeries_hpte_updateboltedpp;
ppc_md.hpte_insert = iSeries_hpte_insert;
- ppc_md.hpte_remove = iSeries_hpte_remove;
+ ppc_md.hpte_remove = iSeries_hpte_remove;
htab_finish_init();
}
diff --git a/arch/ppc64/kernel/hvCall.S b/arch/powerpc/platforms/iseries/hvcall.S
index 4c699eab1b95..07ae6ad5f49f 100644
--- a/arch/ppc64/kernel/hvCall.S
+++ b/arch/powerpc/platforms/iseries/hvcall.S
@@ -1,7 +1,4 @@
/*
- * arch/ppc64/kernel/hvCall.S
- *
- *
* This file contains the code to perform calls to the
* iSeries LPAR hypervisor
*
@@ -13,15 +10,16 @@
#include <asm/ppc_asm.h>
#include <asm/processor.h>
+#include <asm/ptrace.h> /* XXX for STACK_FRAME_OVERHEAD */
.text
-/*
+/*
* Hypervisor call
- *
+ *
* Invoke the iSeries hypervisor via the System Call instruction
* Parameters are passed to this routine in registers r3 - r10
- *
+ *
* r3 contains the HV function to be called
* r4-r10 contain the operands to the hypervisor function
*
@@ -41,11 +39,11 @@ _GLOBAL(HvCall7)
mfcr r0
std r0,-8(r1)
stdu r1,-(STACK_FRAME_OVERHEAD+16)(r1)
-
+
/* r0 = 0xffffffffffffffff indicates a hypervisor call */
-
+
li r0,-1
-
+
/* Invoke the hypervisor */
sc
@@ -55,7 +53,7 @@ _GLOBAL(HvCall7)
mtcrf 0xff,r0
/* return to caller, return value in r3 */
-
+
blr
_GLOBAL(HvCall0Ret16)
@@ -92,7 +90,5 @@ _GLOBAL(HvCall7Ret16)
ld r0,-8(r1)
mtcrf 0xff,r0
ld r31,-16(r1)
-
- blr
-
+ blr
diff --git a/arch/ppc64/kernel/HvCall.c b/arch/powerpc/platforms/iseries/hvlog.c
index b772e65b57a2..f61e2e9ac9ec 100644
--- a/arch/ppc64/kernel/HvCall.c
+++ b/arch/powerpc/platforms/iseries/hvlog.c
@@ -1,5 +1,4 @@
/*
- * HvCall.c
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
diff --git a/arch/ppc64/kernel/HvLpConfig.c b/arch/powerpc/platforms/iseries/hvlpconfig.c
index cb1d6473203c..dc28621aea0d 100644
--- a/arch/ppc64/kernel/HvLpConfig.c
+++ b/arch/powerpc/platforms/iseries/hvlpconfig.c
@@ -1,5 +1,4 @@
/*
- * HvLpConfig.c
* Copyright (C) 2001 Kyle A. Lucke, IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
diff --git a/arch/ppc64/kernel/iSeries_iommu.c b/arch/powerpc/platforms/iseries/iommu.c
index f8ff1bb054dc..1db26d8be640 100644
--- a/arch/ppc64/kernel/iSeries_iommu.c
+++ b/arch/powerpc/platforms/iseries/iommu.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc64/kernel/iSeries_iommu.c
- *
* Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
*
* Rewrite, cleanup:
@@ -30,9 +28,11 @@
#include <linux/list.h>
#include <asm/iommu.h>
+#include <asm/tce.h>
#include <asm/machdep.h>
+#include <asm/abs_addr.h>
+#include <asm/pci-bridge.h>
#include <asm/iSeries/HvCallXm.h>
-#include <asm/iSeries/iSeries_pci.h>
extern struct list_head iSeries_Global_Device_List;
@@ -90,15 +90,16 @@ static void tce_free_iSeries(struct iommu_table *tbl, long index, long npages)
*/
static struct iommu_table *iommu_table_find(struct iommu_table * tbl)
{
- struct iSeries_Device_Node *dp;
-
- list_for_each_entry(dp, &iSeries_Global_Device_List, Device_List) {
- if ((dp->iommu_table != NULL) &&
- (dp->iommu_table->it_type == TCE_PCI) &&
- (dp->iommu_table->it_offset == tbl->it_offset) &&
- (dp->iommu_table->it_index == tbl->it_index) &&
- (dp->iommu_table->it_size == tbl->it_size))
- return dp->iommu_table;
+ struct pci_dn *pdn;
+
+ list_for_each_entry(pdn, &iSeries_Global_Device_List, Device_List) {
+ struct iommu_table *it = pdn->iommu_table;
+ if ((it != NULL) &&
+ (it->it_type == TCE_PCI) &&
+ (it->it_offset == tbl->it_offset) &&
+ (it->it_index == tbl->it_index) &&
+ (it->it_size == tbl->it_size))
+ return it;
}
return NULL;
}
@@ -112,7 +113,7 @@ static struct iommu_table *iommu_table_find(struct iommu_table * tbl)
* 2. TCE table per Bus.
* 3. TCE Table per IOA.
*/
-static void iommu_table_getparms(struct iSeries_Device_Node* dn,
+static void iommu_table_getparms(struct pci_dn *pdn,
struct iommu_table* tbl)
{
struct iommu_table_cb *parms;
@@ -123,11 +124,11 @@ static void iommu_table_getparms(struct iSeries_Device_Node* dn,
memset(parms, 0, sizeof(*parms));
- parms->itc_busno = ISERIES_BUS(dn);
- parms->itc_slotno = dn->LogicalSlot;
+ parms->itc_busno = pdn->busno;
+ parms->itc_slotno = pdn->LogicalSlot;
parms->itc_virtbus = 0;
- HvCallXm_getTceTableParms(ISERIES_HV_ADDR(parms));
+ HvCallXm_getTceTableParms(iseries_hv_addr(parms));
if (parms->itc_size == 0)
panic("PCI_DMA: parms->size is zero, parms is 0x%p", parms);
@@ -144,18 +145,19 @@ static void iommu_table_getparms(struct iSeries_Device_Node* dn,
}
-void iommu_devnode_init_iSeries(struct iSeries_Device_Node *dn)
+void iommu_devnode_init_iSeries(struct device_node *dn)
{
struct iommu_table *tbl;
+ struct pci_dn *pdn = PCI_DN(dn);
tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
- iommu_table_getparms(dn, tbl);
+ iommu_table_getparms(pdn, tbl);
/* Look for existing tce table */
- dn->iommu_table = iommu_table_find(tbl);
- if (dn->iommu_table == NULL)
- dn->iommu_table = iommu_init_table(tbl);
+ pdn->iommu_table = iommu_table_find(tbl);
+ if (pdn->iommu_table == NULL)
+ pdn->iommu_table = iommu_init_table(tbl);
else
kfree(tbl);
}
diff --git a/include/asm-ppc64/iSeries/ItIplParmsReal.h b/arch/powerpc/platforms/iseries/ipl_parms.h
index ae3417dc599e..77c135ddbf1b 100644
--- a/include/asm-ppc64/iSeries/ItIplParmsReal.h
+++ b/arch/powerpc/platforms/iseries/ipl_parms.h
@@ -1,5 +1,4 @@
/*
- * ItIplParmsReal.h
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
@@ -16,8 +15,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _ITIPLPARMSREAL_H
-#define _ITIPLPARMSREAL_H
+#ifndef _ISERIES_IPL_PARMS_H
+#define _ISERIES_IPL_PARMS_H
/*
* This struct maps the IPL Parameters DMA'd from the SP.
@@ -68,4 +67,4 @@ struct ItIplParmsReal {
extern struct ItIplParmsReal xItIplParmsReal;
-#endif /* _ITIPLPARMSREAL_H */
+#endif /* _ISERIES_IPL_PARMS_H */
diff --git a/arch/ppc64/kernel/iSeries_irq.c b/arch/powerpc/platforms/iseries/irq.c
index 77376c1bd611..937ac99b9d33 100644
--- a/arch/ppc64/kernel/iSeries_irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -38,9 +38,10 @@
#include <asm/ppcdebug.h>
#include <asm/iSeries/HvTypes.h>
#include <asm/iSeries/HvLpEvent.h>
-#include <asm/iSeries/HvCallPci.h>
#include <asm/iSeries/HvCallXm.h>
-#include <asm/iSeries/iSeries_irq.h>
+
+#include "irq.h"
+#include "call_pci.h"
/* This maps virtual irq numbers to real irqs */
unsigned int virt_irq_to_real_map[NR_IRQS];
@@ -351,3 +352,15 @@ int __init iSeries_allocate_IRQ(HvBusNumber busNumber,
irq_desc[virtirq].handler = &iSeries_IRQ_handler;
return virtirq;
}
+
+int virt_irq_create_mapping(unsigned int real_irq)
+{
+ BUG(); /* Don't call this on iSeries, yet */
+
+ return 0;
+}
+
+void virt_irq_init(void)
+{
+ return;
+}
diff --git a/include/asm-ppc64/iSeries/iSeries_irq.h b/arch/powerpc/platforms/iseries/irq.h
index 6c9767ac1302..5f643f16ecc0 100644
--- a/include/asm-ppc64/iSeries/iSeries_irq.h
+++ b/arch/powerpc/platforms/iseries/irq.h
@@ -1,8 +1,8 @@
-#ifndef __ISERIES_IRQ_H__
-#define __ISERIES_IRQ_H__
+#ifndef _ISERIES_IRQ_H
+#define _ISERIES_IRQ_H
extern void iSeries_init_IRQ(void);
extern int iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, HvAgentId);
extern void iSeries_activate_IRQs(void);
-#endif /* __ISERIES_IRQ_H__ */
+#endif /* _ISERIES_IRQ_H */
diff --git a/arch/powerpc/platforms/iseries/ksyms.c b/arch/powerpc/platforms/iseries/ksyms.c
new file mode 100644
index 000000000000..f271b3539721
--- /dev/null
+++ b/arch/powerpc/platforms/iseries/ksyms.c
@@ -0,0 +1,27 @@
+/*
+ * (C) 2001-2005 PPC 64 Team, IBM Corp
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/module.h>
+
+#include <asm/hw_irq.h>
+#include <asm/iSeries/HvCallSc.h>
+
+EXPORT_SYMBOL(HvCall0);
+EXPORT_SYMBOL(HvCall1);
+EXPORT_SYMBOL(HvCall2);
+EXPORT_SYMBOL(HvCall3);
+EXPORT_SYMBOL(HvCall4);
+EXPORT_SYMBOL(HvCall5);
+EXPORT_SYMBOL(HvCall6);
+EXPORT_SYMBOL(HvCall7);
+
+#ifdef CONFIG_SMP
+EXPORT_SYMBOL(local_get_flags);
+EXPORT_SYMBOL(local_irq_disable);
+EXPORT_SYMBOL(local_irq_restore);
+#endif
diff --git a/arch/ppc64/kernel/LparData.c b/arch/powerpc/platforms/iseries/lpardata.c
index 0a9c23ca2f0c..ed2ffee6f731 100644
--- a/arch/ppc64/kernel/LparData.c
+++ b/arch/powerpc/platforms/iseries/lpardata.c
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright 2001 Mike Corrigan, IBM Corp
*
* This program is free software; you can redistribute it and/or
@@ -19,18 +19,18 @@
#include <asm/lppaca.h>
#include <asm/iSeries/ItLpRegSave.h>
#include <asm/paca.h>
-#include <asm/iSeries/HvReleaseData.h>
#include <asm/iSeries/LparMap.h>
-#include <asm/iSeries/ItVpdAreas.h>
-#include <asm/iSeries/ItIplParmsReal.h>
#include <asm/iSeries/ItExtVpdPanel.h>
#include <asm/iSeries/ItLpQueue.h>
-#include <asm/iSeries/IoHriProcessorVpd.h>
-#include <asm/iSeries/ItSpCommArea.h>
+#include "vpd_areas.h"
+#include "spcomm_area.h"
+#include "ipl_parms.h"
+#include "processor_vpd.h"
+#include "release_data.h"
-/* The HvReleaseData is the root of the information shared between
- * the hypervisor and Linux.
+/* The HvReleaseData is the root of the information shared between
+ * the hypervisor and Linux.
*/
struct HvReleaseData hvReleaseData = {
.xDesc = 0xc8a5d9c4, /* "HvRD" ebcdic */
@@ -79,7 +79,7 @@ extern void trap_0e_iSeries(void);
extern void performance_monitor_iSeries(void);
extern void data_access_slb_iSeries(void);
extern void instruction_access_slb_iSeries(void);
-
+
struct ItLpNaca itLpNaca = {
.xDesc = 0xd397d581, /* "LpNa" ebcdic */
.xSize = 0x0400, /* size of ItLpNaca */
@@ -106,7 +106,7 @@ struct ItLpNaca itLpNaca = {
.xLoadAreaChunks = 0, /* chunks for load area */
.xPaseSysCallCRMask = 0, /* PASE mask */
.xSlicSegmentTablePtr = 0, /* seg table */
- .xOldLpQueue = { 0 }, /* Old LP Queue */
+ .xOldLpQueue = { 0 }, /* Old LP Queue */
.xInterruptHdlr = {
(u64)system_reset_iSeries, /* 0x100 System Reset */
(u64)machine_check_iSeries, /* 0x200 Machine Check */
@@ -134,7 +134,7 @@ struct ItLpNaca itLpNaca = {
EXPORT_SYMBOL(itLpNaca);
/* May be filled in by the hypervisor so cannot end up in the BSS */
-struct ItIplParmsReal xItIplParmsReal __attribute__((__section__(".data")));
+struct ItIplParmsReal xItIplParmsReal __attribute__((__section__(".data")));
/* May be filled in by the hypervisor so cannot end up in the BSS */
struct ItExtVpdPanel xItExtVpdPanel __attribute__((__section__(".data")));
@@ -151,7 +151,7 @@ struct IoHriProcessorVpd xIoHriProcessorVpd[maxPhysicalProcessors] = {
.xPVR = 0x3600
}
};
-
+
/* Space for Main Store Vpd 27,200 bytes */
/* May be filled in by the hypervisor so cannot end up in the BSS */
u64 xMsVpd[3400] __attribute__((__section__(".data")));
@@ -197,7 +197,7 @@ struct ItVpdAreas itVpdAreas = {
26992, /* 7 length of MS VPD */
0, /* 8 */
sizeof(struct ItLpNaca),/* 9 length of LP Naca */
- 0, /* 10 */
+ 0, /* 10 */
256, /* 11 length of Recovery Log Buf */
sizeof(struct SpCommArea), /* 12 length of SP Comm Area */
0,0,0, /* 13 - 15 */
@@ -207,7 +207,7 @@ struct ItVpdAreas itVpdAreas = {
0,0 /* 24 - 25 */
},
.xSlicVpdAdrs = { /* VPD addresses */
- 0,0,0, /* 0 - 2 */
+ 0,0,0, /* 0 - 2 */
&xItExtVpdPanel, /* 3 Extended VPD */
&paca[0], /* 4 first Paca */
0, /* 5 */
diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/powerpc/platforms/iseries/lpevents.c
index 4231861288a3..54c7753dbe05 100644
--- a/arch/ppc64/kernel/ItLpQueue.c
+++ b/arch/powerpc/platforms/iseries/lpevents.c
@@ -1,5 +1,4 @@
/*
- * ItLpQueue.c
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
@@ -14,11 +13,14 @@
#include <linux/bootmem.h>
#include <linux/seq_file.h>
#include <linux/proc_fs.h>
+#include <linux/module.h>
+
#include <asm/system.h>
#include <asm/paca.h>
#include <asm/iSeries/ItLpQueue.h>
#include <asm/iSeries/HvLpEvent.h>
#include <asm/iSeries/HvCallEvent.h>
+#include <asm/iSeries/ItLpNaca.h>
/*
* The LpQueue is used to pass event data from the hypervisor to
@@ -43,7 +45,8 @@ static char *event_types[HvLpEvent_Type_NumTypes] = {
};
/* Array of LpEvent handler functions */
-extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes];
+static LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes];
+static unsigned lpEventHandlerPaths[HvLpEvent_Type_NumTypes];
static struct HvLpEvent * get_next_hvlpevent(void)
{
@@ -181,11 +184,7 @@ void setup_hvlpevent_queue(void)
{
void *eventStack;
- /*
- * Allocate a page for the Event Stack. The Hypervisor needs the
- * absolute real address, so we subtract out the KERNELBASE and add
- * in the absolute real address of the kernel load area.
- */
+ /* Allocate a page for the Event Stack. */
eventStack = alloc_bootmem_pages(LpEventStackSize);
memset(eventStack, 0, LpEventStackSize);
@@ -199,6 +198,70 @@ void setup_hvlpevent_queue(void)
hvlpevent_queue.xIndex = 0;
}
+/* Register a handler for an LpEvent type */
+int HvLpEvent_registerHandler(HvLpEvent_Type eventType, LpEventHandler handler)
+{
+ if (eventType < HvLpEvent_Type_NumTypes) {
+ lpEventHandler[eventType] = handler;
+ return 0;
+ }
+ return 1;
+}
+EXPORT_SYMBOL(HvLpEvent_registerHandler);
+
+int HvLpEvent_unregisterHandler(HvLpEvent_Type eventType)
+{
+ might_sleep();
+
+ if (eventType < HvLpEvent_Type_NumTypes) {
+ if (!lpEventHandlerPaths[eventType]) {
+ lpEventHandler[eventType] = NULL;
+ /*
+ * We now sleep until all other CPUs have scheduled.
+ * This ensures that the deletion is seen by all
+ * other CPUs, and that the deleted handler isn't
+ * still running on another CPU when we return.
+ */
+ synchronize_rcu();
+ return 0;
+ }
+ }
+ return 1;
+}
+EXPORT_SYMBOL(HvLpEvent_unregisterHandler);
+
+/*
+ * lpIndex is the partition index of the target partition.
+ * needed only for VirtualIo, VirtualLan and SessionMgr. Zero
+ * indicates to use our partition index - for the other types.
+ */
+int HvLpEvent_openPath(HvLpEvent_Type eventType, HvLpIndex lpIndex)
+{
+ if ((eventType < HvLpEvent_Type_NumTypes) &&
+ lpEventHandler[eventType]) {
+ if (lpIndex == 0)
+ lpIndex = itLpNaca.xLpIndex;
+ HvCallEvent_openLpEventPath(lpIndex, eventType);
+ ++lpEventHandlerPaths[eventType];
+ return 0;
+ }
+ return 1;
+}
+
+int HvLpEvent_closePath(HvLpEvent_Type eventType, HvLpIndex lpIndex)
+{
+ if ((eventType < HvLpEvent_Type_NumTypes) &&
+ lpEventHandler[eventType] &&
+ lpEventHandlerPaths[eventType]) {
+ if (lpIndex == 0)
+ lpIndex = itLpNaca.xLpIndex;
+ HvCallEvent_closeLpEventPath(lpIndex, eventType);
+ --lpEventHandlerPaths[eventType];
+ return 0;
+ }
+ return 1;
+}
+
static int proc_lpevents_show(struct seq_file *m, void *v)
{
int cpu, i;
diff --git a/include/asm-ppc64/iSeries/IoHriMainStore.h b/arch/powerpc/platforms/iseries/main_store.h
index 45ed3ea67d06..74f6889f834f 100644
--- a/include/asm-ppc64/iSeries/IoHriMainStore.h
+++ b/arch/powerpc/platforms/iseries/main_store.h
@@ -1,5 +1,4 @@
/*
- * IoHriMainStore.h
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
@@ -17,8 +16,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _IOHRIMAINSTORE_H
-#define _IOHRIMAINSTORE_H
+#ifndef _ISERIES_MAIN_STORE_H
+#define _ISERIES_MAIN_STORE_H
/* Main Store Vpd for Condor,iStar,sStar */
struct IoHriMainStoreSegment4 {
@@ -163,4 +162,4 @@ struct IoHriMainStoreSegment5 {
extern u64 xMsVpd[];
-#endif /* _IOHRIMAINSTORE_H */
+#endif /* _ISERIES_MAIN_STORE_H */
diff --git a/arch/ppc64/kernel/mf.c b/arch/powerpc/platforms/iseries/mf.c
index ef4a338ebd01..e5de31aa0015 100644
--- a/arch/ppc64/kernel/mf.c
+++ b/arch/powerpc/platforms/iseries/mf.c
@@ -1,29 +1,28 @@
/*
- * mf.c
- * Copyright (C) 2001 Troy D. Armstrong IBM Corporation
- * Copyright (C) 2004-2005 Stephen Rothwell IBM Corporation
- *
- * This modules exists as an interface between a Linux secondary partition
- * running on an iSeries and the primary partition's Virtual Service
- * Processor (VSP) object. The VSP has final authority over powering on/off
- * all partitions in the iSeries. It also provides miscellaneous low-level
- * machine facility type operations.
- *
- *
- * This program is free software; you can redistribute 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
- */
+ * Copyright (C) 2001 Troy D. Armstrong IBM Corporation
+ * Copyright (C) 2004-2005 Stephen Rothwell IBM Corporation
+ *
+ * This modules exists as an interface between a Linux secondary partition
+ * running on an iSeries and the primary partition's Virtual Service
+ * Processor (VSP) object. The VSP has final authority over powering on/off
+ * all partitions in the iSeries. It also provides miscellaneous low-level
+ * machine facility type operations.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
#include <linux/types.h>
#include <linux/errno.h>
@@ -33,15 +32,21 @@
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/bcd.h>
+#include <linux/rtc.h>
#include <asm/time.h>
#include <asm/uaccess.h>
#include <asm/paca.h>
+#include <asm/abs_addr.h>
#include <asm/iSeries/vio.h>
#include <asm/iSeries/mf.h>
#include <asm/iSeries/HvLpConfig.h>
#include <asm/iSeries/ItLpQueue.h>
+#include "setup.h"
+
+extern int piranha_simulator;
+
/*
* This is the structure layout for the Machine Facilites LPAR event
* flows.
@@ -1061,10 +1066,10 @@ static void mf_getSrcHistory(char *buffer, int size)
ev->event.data.vsp_cmd.lp_index = HvLpConfig_getLpIndex();
ev->event.data.vsp_cmd.result_code = 0xFF;
ev->event.data.vsp_cmd.reserved = 0;
- ev->event.data.vsp_cmd.sub_data.page[0] = ISERIES_HV_ADDR(pages[0]);
- ev->event.data.vsp_cmd.sub_data.page[1] = ISERIES_HV_ADDR(pages[1]);
- ev->event.data.vsp_cmd.sub_data.page[2] = ISERIES_HV_ADDR(pages[2]);
- ev->event.data.vsp_cmd.sub_data.page[3] = ISERIES_HV_ADDR(pages[3]);
+ ev->event.data.vsp_cmd.sub_data.page[0] = iseries_hv_addr(pages[0]);
+ ev->event.data.vsp_cmd.sub_data.page[1] = iseries_hv_addr(pages[1]);
+ ev->event.data.vsp_cmd.sub_data.page[2] = iseries_hv_addr(pages[2]);
+ ev->event.data.vsp_cmd.sub_data.page[3] = iseries_hv_addr(pages[3]);
mb();
if (signal_event(ev) != 0)
return;
@@ -1279,3 +1284,38 @@ static int __init mf_proc_init(void)
__initcall(mf_proc_init);
#endif /* CONFIG_PROC_FS */
+
+/*
+ * Get the RTC from the virtual service processor
+ * This requires flowing LpEvents to the primary partition
+ */
+void iSeries_get_rtc_time(struct rtc_time *rtc_tm)
+{
+ if (piranha_simulator)
+ return;
+
+ mf_get_rtc(rtc_tm);
+ rtc_tm->tm_mon--;
+}
+
+/*
+ * Set the RTC in the virtual service processor
+ * This requires flowing LpEvents to the primary partition
+ */
+int iSeries_set_rtc_time(struct rtc_time *tm)
+{
+ mf_set_rtc(tm);
+ return 0;
+}
+
+unsigned long iSeries_get_boot_time(void)
+{
+ struct rtc_time tm;
+
+ if (piranha_simulator)
+ return 0;
+
+ mf_get_boot_rtc(&tm);
+ return mktime(tm.tm_year + 1900, tm.tm_mon, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec);
+}
diff --git a/arch/powerpc/platforms/iseries/misc.S b/arch/powerpc/platforms/iseries/misc.S
new file mode 100644
index 000000000000..09f14522e176
--- /dev/null
+++ b/arch/powerpc/platforms/iseries/misc.S
@@ -0,0 +1,55 @@
+/*
+ * This file contains miscellaneous low-level functions.
+ * Copyright (C) 1995-2005 IBM Corp
+ *
+ * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
+ * and Paul Mackerras.
+ * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com)
+ * PPC64 updates by Dave Engebretsen (engebret@us.ibm.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/processor.h>
+#include <asm/asm-offsets.h>
+
+ .text
+
+/* unsigned long local_save_flags(void) */
+_GLOBAL(local_get_flags)
+ lbz r3,PACAPROCENABLED(r13)
+ blr
+
+/* unsigned long local_irq_disable(void) */
+_GLOBAL(local_irq_disable)
+ lbz r3,PACAPROCENABLED(r13)
+ li r4,0
+ stb r4,PACAPROCENABLED(r13)
+ blr /* Done */
+
+/* void local_irq_restore(unsigned long flags) */
+_GLOBAL(local_irq_restore)
+ lbz r5,PACAPROCENABLED(r13)
+ /* Check if things are setup the way we want _already_. */
+ cmpw 0,r3,r5
+ beqlr
+ /* are we enabling interrupts? */
+ cmpdi 0,r3,0
+ stb r3,PACAPROCENABLED(r13)
+ beqlr
+ /* Check pending interrupts */
+ /* A decrementer, IPI or PMC interrupt may have occurred
+ * while we were in the hypervisor (which enables) */
+ ld r4,PACALPPACA+LPPACAANYINT(r13)
+ cmpdi r4,0
+ beqlr
+
+ /*
+ * Handle pending interrupts in interrupt context
+ */
+ li r0,0x5555
+ sc
+ blr
diff --git a/arch/ppc64/kernel/iSeries_pci.c b/arch/powerpc/platforms/iseries/pci.c
index fbc273c32bcc..959e59fd9c11 100644
--- a/arch/ppc64/kernel/iSeries_pci.c
+++ b/arch/powerpc/platforms/iseries/pci.c
@@ -1,28 +1,26 @@
/*
- * iSeries_pci.c
- *
* Copyright (C) 2001 Allan Trautman, IBM Corporation
*
* iSeries specific routines for PCI.
- *
+ *
* Based on code from pci.c and iSeries_pci.c 32bit
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/kernel.h>
-#include <linux/list.h>
+#include <linux/list.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/module.h>
@@ -36,21 +34,23 @@
#include <asm/pci-bridge.h>
#include <asm/ppcdebug.h>
#include <asm/iommu.h>
+#include <asm/abs_addr.h>
-#include <asm/iSeries/HvCallPci.h>
#include <asm/iSeries/HvCallXm.h>
-#include <asm/iSeries/iSeries_irq.h>
-#include <asm/iSeries/iSeries_pci.h>
#include <asm/iSeries/mf.h>
+#include <asm/ppc-pci.h>
+
+#include "irq.h"
#include "pci.h"
+#include "call_pci.h"
extern unsigned long io_page_mask;
/*
- * Forward declares of prototypes.
+ * Forward declares of prototypes.
*/
-static struct iSeries_Device_Node *find_Device_Node(int bus, int devfn);
+static struct device_node *find_Device_Node(int bus, int devfn);
static void scan_PHB_slots(struct pci_controller *Phb);
static void scan_EADS_bridge(HvBusNumber Bus, HvSubBusNumber SubBus, int IdSel);
static int scan_bridge_slot(HvBusNumber Bus, struct HvCallPci_BridgeInfo *Info);
@@ -68,7 +68,7 @@ static long Pci_Cfg_Write_Count;
#endif
static long Pci_Error_Count;
-static int Pci_Retry_Max = 3; /* Only retry 3 times */
+static int Pci_Retry_Max = 3; /* Only retry 3 times */
static int Pci_Error_Flag = 1; /* Set Retry Error on. */
static struct pci_ops iSeries_pci_ops;
@@ -87,7 +87,7 @@ static long current_iomm_table_entry;
/*
* Lookup Tables.
*/
-static struct iSeries_Device_Node **iomm_table;
+static struct device_node **iomm_table;
static u8 *iobar_table;
/*
@@ -179,7 +179,7 @@ static void allocate_device_bars(struct pci_dev *dev)
for (bar_num = 0; bar_num <= PCI_ROM_RESOURCE; ++bar_num) {
bar_res = &dev->resource[bar_num];
iomm_table_allocate_entry(dev, bar_num);
- }
+ }
}
/*
@@ -201,29 +201,31 @@ static void pci_Log_Error(char *Error_Text, int Bus, int SubBus,
/*
* build_device_node(u16 Bus, int SubBus, u8 DevFn)
*/
-static struct iSeries_Device_Node *build_device_node(HvBusNumber Bus,
+static struct device_node *build_device_node(HvBusNumber Bus,
HvSubBusNumber SubBus, int AgentId, int Function)
{
- struct iSeries_Device_Node *node;
+ struct device_node *node;
+ struct pci_dn *pdn;
PPCDBG(PPCDBG_BUSWALK,
"-build_device_node 0x%02X.%02X.%02X Function: %02X\n",
Bus, SubBus, AgentId, Function);
- node = kmalloc(sizeof(struct iSeries_Device_Node), GFP_KERNEL);
+ node = kmalloc(sizeof(struct device_node), GFP_KERNEL);
if (node == NULL)
return NULL;
-
- memset(node, 0, sizeof(struct iSeries_Device_Node));
- list_add_tail(&node->Device_List, &iSeries_Global_Device_List);
-#if 0
- node->DsaAddr = ((u64)Bus << 48) + ((u64)SubBus << 40) + ((u64)0x10 << 32);
-#endif
- node->DsaAddr.DsaAddr = 0;
- node->DsaAddr.Dsa.busNumber = Bus;
- node->DsaAddr.Dsa.subBusNumber = SubBus;
- node->DsaAddr.Dsa.deviceId = 0x10;
- node->DevFn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId), Function);
+ memset(node, 0, sizeof(struct device_node));
+ pdn = kzalloc(sizeof(*pdn), GFP_KERNEL);
+ if (pdn == NULL) {
+ kfree(node);
+ return NULL;
+ }
+ node->data = pdn;
+ pdn->node = node;
+ list_add_tail(&pdn->Device_List, &iSeries_Global_Device_List);
+ pdn->busno = Bus;
+ pdn->bussubno = SubBus;
+ pdn->devfn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId), Function);
return node;
}
@@ -278,28 +280,28 @@ unsigned long __init find_and_init_phbs(void)
/*
* iSeries_pcibios_init
- *
+ *
* Chance to initialize and structures or variable before PCI Bus walk.
*/
void iSeries_pcibios_init(void)
{
- PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_init Entry.\n");
+ PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_init Entry.\n");
iomm_table_initialize();
find_and_init_phbs();
io_page_mask = -1;
- PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_init Exit.\n");
+ PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_init Exit.\n");
}
/*
- * iSeries_pci_final_fixup(void)
+ * iSeries_pci_final_fixup(void)
*/
void __init iSeries_pci_final_fixup(void)
{
struct pci_dev *pdev = NULL;
- struct iSeries_Device_Node *node;
- int DeviceCount = 0;
+ struct device_node *node;
+ int DeviceCount = 0;
- PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup Entry.\n");
+ PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup Entry.\n");
/* Fix up at the device node and pci_dev relationship */
mf_display_src(0xC9000100);
@@ -313,7 +315,7 @@ void __init iSeries_pci_final_fixup(void)
if (node != NULL) {
++DeviceCount;
pdev->sysdata = (void *)node;
- node->PciDev = pdev;
+ PCI_DN(node)->pcidev = pdev;
PPCDBG(PPCDBG_BUSWALK,
"pdev 0x%p <==> DevNode 0x%p\n",
pdev, node);
@@ -323,7 +325,7 @@ void __init iSeries_pci_final_fixup(void)
} else
printk("PCI: Device Tree not found for 0x%016lX\n",
(unsigned long)pdev);
- pdev->irq = node->Irq;
+ pdev->irq = PCI_DN(node)->Irq;
}
iSeries_activate_IRQs();
mf_display_src(0xC9000200);
@@ -332,24 +334,24 @@ void __init iSeries_pci_final_fixup(void)
void pcibios_fixup_bus(struct pci_bus *PciBus)
{
PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup_bus(0x%04X) Entry.\n",
- PciBus->number);
+ PciBus->number);
}
void pcibios_fixup_resources(struct pci_dev *pdev)
{
PPCDBG(PPCDBG_BUSWALK, "fixup_resources pdev %p\n", pdev);
-}
+}
/*
- * Loop through each node function to find usable EADs bridges.
+ * Loop through each node function to find usable EADs bridges.
*/
static void scan_PHB_slots(struct pci_controller *Phb)
{
struct HvCallPci_DeviceInfo *DevInfo;
- HvBusNumber bus = Phb->local_number; /* System Bus */
+ HvBusNumber bus = Phb->local_number; /* System Bus */
const HvSubBusNumber SubBus = 0; /* EADs is always 0. */
int HvRc = 0;
- int IdSel;
+ int IdSel;
const int MaxAgents = 8;
DevInfo = (struct HvCallPci_DeviceInfo*)
@@ -358,11 +360,11 @@ static void scan_PHB_slots(struct pci_controller *Phb)
return;
/*
- * Probe for EADs Bridges
+ * Probe for EADs Bridges
*/
for (IdSel = 1; IdSel < MaxAgents; ++IdSel) {
- HvRc = HvCallPci_getDeviceInfo(bus, SubBus, IdSel,
- ISERIES_HV_ADDR(DevInfo),
+ HvRc = HvCallPci_getDeviceInfo(bus, SubBus, IdSel,
+ iseries_hv_addr(DevInfo),
sizeof(struct HvCallPci_DeviceInfo));
if (HvRc == 0) {
if (DevInfo->deviceType == HvCallPci_NodeDevice)
@@ -393,19 +395,19 @@ static void scan_EADS_bridge(HvBusNumber bus, HvSubBusNumber SubBus,
/* Note: hvSubBus and irq is always be 0 at this level! */
for (Function = 0; Function < 8; ++Function) {
- AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
+ AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
HvRc = HvCallXm_connectBusUnit(bus, SubBus, AgentId, 0);
- if (HvRc == 0) {
+ if (HvRc == 0) {
printk("found device at bus %d idsel %d func %d (AgentId %x)\n",
bus, IdSel, Function, AgentId);
- /* Connect EADs: 0x18.00.12 = 0x00 */
+ /* Connect EADs: 0x18.00.12 = 0x00 */
PPCDBG(PPCDBG_BUSWALK,
"PCI:Connect EADs: 0x%02X.%02X.%02X\n",
bus, SubBus, AgentId);
- HvRc = HvCallPci_getBusUnitInfo(bus, SubBus, AgentId,
- ISERIES_HV_ADDR(BridgeInfo),
+ HvRc = HvCallPci_getBusUnitInfo(bus, SubBus, AgentId,
+ iseries_hv_addr(BridgeInfo),
sizeof(struct HvCallPci_BridgeInfo));
- if (HvRc == 0) {
+ if (HvRc == 0) {
printk("bridge info: type %x subbus %x maxAgents %x maxsubbus %x logslot %x\n",
BridgeInfo->busUnitInfo.deviceType,
BridgeInfo->subBusNumber,
@@ -428,7 +430,7 @@ static void scan_EADS_bridge(HvBusNumber bus, HvSubBusNumber SubBus,
printk("PCI: Invalid Bridge Configuration(0x%02X)",
BridgeInfo->busUnitInfo.deviceType);
}
- } else if (HvRc != 0x000B)
+ } else if (HvRc != 0x000B)
pci_Log_Error("EADs Connect",
bus, SubBus, AgentId, HvRc);
}
@@ -441,7 +443,7 @@ static void scan_EADS_bridge(HvBusNumber bus, HvSubBusNumber SubBus,
static int scan_bridge_slot(HvBusNumber Bus,
struct HvCallPci_BridgeInfo *BridgeInfo)
{
- struct iSeries_Device_Node *node;
+ struct device_node *node;
HvSubBusNumber SubBus = BridgeInfo->subBusNumber;
u16 VendorId = 0;
int HvRc = 0;
@@ -451,16 +453,16 @@ static int scan_bridge_slot(HvBusNumber Bus,
HvAgentId EADsIdSel = ISERIES_PCI_AGENTID(IdSel, Function);
/* iSeries_allocate_IRQ.: 0x18.00.12(0xA3) */
- Irq = iSeries_allocate_IRQ(Bus, 0, EADsIdSel);
+ Irq = iSeries_allocate_IRQ(Bus, 0, EADsIdSel);
PPCDBG(PPCDBG_BUSWALK,
"PCI:- allocate and assign IRQ 0x%02X.%02X.%02X = 0x%02X\n",
Bus, 0, EADsIdSel, Irq);
/*
- * Connect all functions of any device found.
+ * Connect all functions of any device found.
*/
- for (IdSel = 1; IdSel <= BridgeInfo->maxAgents; ++IdSel) {
- for (Function = 0; Function < 8; ++Function) {
+ for (IdSel = 1; IdSel <= BridgeInfo->maxAgents; ++IdSel) {
+ for (Function = 0; Function < 8; ++Function) {
HvAgentId AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
HvRc = HvCallXm_connectBusUnit(Bus, SubBus,
AgentId, Irq);
@@ -484,15 +486,15 @@ static int scan_bridge_slot(HvBusNumber Bus,
"PCI:- FoundDevice: 0x%02X.%02X.%02X = 0x%04X, irq %d\n",
Bus, SubBus, AgentId, VendorId, Irq);
HvRc = HvCallPci_configStore8(Bus, SubBus, AgentId,
- PCI_INTERRUPT_LINE, Irq);
+ PCI_INTERRUPT_LINE, Irq);
if (HvRc != 0)
pci_Log_Error("PciCfgStore Irq Failed!",
Bus, SubBus, AgentId, HvRc);
++DeviceCount;
node = build_device_node(Bus, SubBus, EADsIdSel, Function);
- node->Irq = Irq;
- node->LogicalSlot = BridgeInfo->logicalSlotNumber;
+ PCI_DN(node)->Irq = Irq;
+ PCI_DN(node)->LogicalSlot = BridgeInfo->logicalSlotNumber;
} /* for (Function = 0; Function < 8; ++Function) */
} /* for (IdSel = 1; IdSel <= MaxAgents; ++IdSel) */
@@ -542,16 +544,13 @@ EXPORT_SYMBOL(iSeries_memcpy_fromio);
/*
* Look down the chain to find the matching Device Device
*/
-static struct iSeries_Device_Node *find_Device_Node(int bus, int devfn)
+static struct device_node *find_Device_Node(int bus, int devfn)
{
- struct list_head *pos;
+ struct pci_dn *pdn;
- list_for_each(pos, &iSeries_Global_Device_List) {
- struct iSeries_Device_Node *node =
- list_entry(pos, struct iSeries_Device_Node, Device_List);
-
- if ((bus == ISERIES_BUS(node)) && (devfn == node->DevFn))
- return node;
+ list_for_each_entry(pdn, &iSeries_Global_Device_List, Device_List) {
+ if ((bus == pdn->busno) && (devfn == pdn->devfn))
+ return pdn->node;
}
return NULL;
}
@@ -562,12 +561,12 @@ static struct iSeries_Device_Node *find_Device_Node(int bus, int devfn)
* Sanity Check Node PciDev to passed pci_dev
* If none is found, returns a NULL which the client must handle.
*/
-static struct iSeries_Device_Node *get_Device_Node(struct pci_dev *pdev)
+static struct device_node *get_Device_Node(struct pci_dev *pdev)
{
- struct iSeries_Device_Node *node;
+ struct device_node *node;
node = pdev->sysdata;
- if (node == NULL || node->PciDev != pdev)
+ if (node == NULL || PCI_DN(node)->pcidev != pdev)
node = find_Device_Node(pdev->bus->number, pdev->devfn);
return node;
}
@@ -595,7 +594,7 @@ static u64 hv_cfg_write_func[4] = {
static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn,
int offset, int size, u32 *val)
{
- struct iSeries_Device_Node *node = find_Device_Node(bus->number, devfn);
+ struct device_node *node = find_Device_Node(bus->number, devfn);
u64 fn;
struct HvCallPci_LoadReturn ret;
@@ -607,7 +606,7 @@ static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn,
}
fn = hv_cfg_read_func[(size - 1) & 3];
- HvCall3Ret16(fn, &ret, node->DsaAddr.DsaAddr, offset, 0);
+ HvCall3Ret16(fn, &ret, iseries_ds_addr(node), offset, 0);
if (ret.rc != 0) {
*val = ~0;
@@ -625,7 +624,7 @@ static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn,
static int iSeries_pci_write_config(struct pci_bus *bus, unsigned int devfn,
int offset, int size, u32 val)
{
- struct iSeries_Device_Node *node = find_Device_Node(bus->number, devfn);
+ struct device_node *node = find_Device_Node(bus->number, devfn);
u64 fn;
u64 ret;
@@ -635,7 +634,7 @@ static int iSeries_pci_write_config(struct pci_bus *bus, unsigned int devfn,
return PCIBIOS_BAD_REGISTER_NUMBER;
fn = hv_cfg_write_func[(size - 1) & 3];
- ret = HvCall4(fn, node->DsaAddr.DsaAddr, offset, val, 0);
+ ret = HvCall4(fn, iseries_ds_addr(node), offset, val, 0);
if (ret != 0)
return PCIBIOS_DEVICE_NOT_FOUND;
@@ -657,14 +656,16 @@ static struct pci_ops iSeries_pci_ops = {
* PCI: Device 23.90 ReadL Retry( 1)
* PCI: Device 23.90 ReadL Retry Successful(1)
*/
-static int CheckReturnCode(char *TextHdr, struct iSeries_Device_Node *DevNode,
+static int CheckReturnCode(char *TextHdr, struct device_node *DevNode,
int *retry, u64 ret)
{
if (ret != 0) {
+ struct pci_dn *pdn = PCI_DN(DevNode);
+
++Pci_Error_Count;
(*retry)++;
printk("PCI: %s: Device 0x%04X:%02X I/O Error(%2d): 0x%04X\n",
- TextHdr, DevNode->DsaAddr.Dsa.busNumber, DevNode->DevFn,
+ TextHdr, pdn->busno, pdn->devfn,
*retry, (int)ret);
/*
* Bump the retry and check for retry count exceeded.
@@ -687,14 +688,14 @@ static int CheckReturnCode(char *TextHdr, struct iSeries_Device_Node *DevNode,
* Note: Make sure the passed variable end up on the stack to avoid
* the exposure of being device global.
*/
-static inline struct iSeries_Device_Node *xlate_iomm_address(
+static inline struct device_node *xlate_iomm_address(
const volatile void __iomem *IoAddress,
u64 *dsaptr, u64 *BarOffsetPtr)
{
unsigned long OrigIoAddr;
unsigned long BaseIoAddr;
unsigned long TableIndex;
- struct iSeries_Device_Node *DevNode;
+ struct device_node *DevNode;
OrigIoAddr = (unsigned long __force)IoAddress;
if ((OrigIoAddr < BASE_IO_MEMORY) || (OrigIoAddr >= max_io_memory))
@@ -705,7 +706,7 @@ static inline struct iSeries_Device_Node *xlate_iomm_address(
if (DevNode != NULL) {
int barnum = iobar_table[TableIndex];
- *dsaptr = DevNode->DsaAddr.DsaAddr | (barnum << 24);
+ *dsaptr = iseries_ds_addr(DevNode) | (barnum << 24);
*BarOffsetPtr = BaseIoAddr % IOMM_TABLE_ENTRY_SIZE;
} else
panic("PCI: Invalid PCI IoAddress detected!\n");
@@ -727,7 +728,7 @@ u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
u64 dsa;
int retry = 0;
struct HvCallPci_LoadReturn ret;
- struct iSeries_Device_Node *DevNode =
+ struct device_node *DevNode =
xlate_iomm_address(IoAddress, &dsa, &BarOffset);
if (DevNode == NULL) {
@@ -757,7 +758,7 @@ u16 iSeries_Read_Word(const volatile void __iomem *IoAddress)
u64 dsa;
int retry = 0;
struct HvCallPci_LoadReturn ret;
- struct iSeries_Device_Node *DevNode =
+ struct device_node *DevNode =
xlate_iomm_address(IoAddress, &dsa, &BarOffset);
if (DevNode == NULL) {
@@ -788,7 +789,7 @@ u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
u64 dsa;
int retry = 0;
struct HvCallPci_LoadReturn ret;
- struct iSeries_Device_Node *DevNode =
+ struct device_node *DevNode =
xlate_iomm_address(IoAddress, &dsa, &BarOffset);
if (DevNode == NULL) {
@@ -826,7 +827,7 @@ void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress)
u64 dsa;
int retry = 0;
u64 rc;
- struct iSeries_Device_Node *DevNode =
+ struct device_node *DevNode =
xlate_iomm_address(IoAddress, &dsa, &BarOffset);
if (DevNode == NULL) {
@@ -854,7 +855,7 @@ void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress)
u64 dsa;
int retry = 0;
u64 rc;
- struct iSeries_Device_Node *DevNode =
+ struct device_node *DevNode =
xlate_iomm_address(IoAddress, &dsa, &BarOffset);
if (DevNode == NULL) {
@@ -882,7 +883,7 @@ void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress)
u64 dsa;
int retry = 0;
u64 rc;
- struct iSeries_Device_Node *DevNode =
+ struct device_node *DevNode =
xlate_iomm_address(IoAddress, &dsa, &BarOffset);
if (DevNode == NULL) {
diff --git a/include/asm-ppc64/iSeries/iSeries_pci.h b/arch/powerpc/platforms/iseries/pci.h
index 575f611f8b33..33a8489fde54 100644
--- a/include/asm-ppc64/iSeries/iSeries_pci.h
+++ b/arch/powerpc/platforms/iseries/pci.h
@@ -1,8 +1,8 @@
-#ifndef _ISERIES_64_PCI_H
-#define _ISERIES_64_PCI_H
+#ifndef _PLATFORMS_ISERIES_PCI_H
+#define _PLATFORMS_ISERIES_PCI_H
/*
- * File iSeries_pci.h created by Allan Trautman on Tue Feb 20, 2001.
+ * Created by Allan Trautman on Tue Feb 20, 2001.
*
* Define some useful macros for the iSeries pci routines.
* Copyright (C) 2001 Allan H Trautman, IBM Corporation
@@ -30,23 +30,9 @@
* End Change Activity
*/
-#include <asm/iSeries/HvCallPci.h>
-#include <asm/abs_addr.h>
+#include <asm/pci-bridge.h>
struct pci_dev; /* For Forward Reference */
-struct iSeries_Device_Node;
-
-/*
- * Gets iSeries Bus, SubBus, DevFn using iSeries_Device_Node structure
- */
-
-#define ISERIES_BUS(DevPtr) DevPtr->DsaAddr.Dsa.busNumber
-#define ISERIES_SUBBUS(DevPtr) DevPtr->DsaAddr.Dsa.subBusNumber
-#define ISERIES_DEVICE(DevPtr) DevPtr->DsaAddr.Dsa.deviceId
-#define ISERIES_DSA(DevPtr) DevPtr->DsaAddr.DsaAddr
-#define ISERIES_DEVNODE(PciDev) ((struct iSeries_Device_Node *)PciDev->sysdata)
-
-#define EADsMaxAgents 7
/*
* Decodes Linux DevFn to iSeries DevFn, bridge device, or function.
@@ -62,27 +48,16 @@ struct iSeries_Device_Node;
#define ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus) ((subbus >> 2) & 0x7)
/*
- * Converts Virtual Address to Real Address for Hypervisor calls
+ * Generate a Direct Select Address for the Hypervisor
*/
-#define ISERIES_HV_ADDR(virtaddr) \
- (0x8000000000000000 | virt_to_abs(virtaddr))
+static inline u64 iseries_ds_addr(struct device_node *node)
+{
+ struct pci_dn *pdn = PCI_DN(node);
-/*
- * iSeries Device Information
- */
-struct iSeries_Device_Node {
- struct list_head Device_List;
- struct pci_dev *PciDev;
- union HvDsaMap DsaAddr; /* Direct Select Address */
- /* busNumber, subBusNumber, */
- /* deviceId, barNumber */
- int DevFn; /* Linux devfn */
- int Irq; /* Assigned IRQ */
- int Flags; /* Possible flags(disable/bist)*/
- u8 LogicalSlot; /* Hv Slot Index for Tces */
- struct iommu_table *iommu_table;/* Device TCE Table */
-};
+ return ((u64)pdn->busno << 48) + ((u64)pdn->bussubno << 40)
+ + ((u64)0x10 << 32);
+}
extern void iSeries_Device_Information(struct pci_dev*, int);
-#endif /* _ISERIES_64_PCI_H */
+#endif /* _PLATFORMS_ISERIES_PCI_H */
diff --git a/arch/ppc64/kernel/iSeries_proc.c b/arch/powerpc/platforms/iseries/proc.c
index 0fe3116eba29..6f1929cac66b 100644
--- a/arch/ppc64/kernel/iSeries_proc.c
+++ b/arch/powerpc/platforms/iseries/proc.c
@@ -1,5 +1,4 @@
/*
- * iSeries_proc.c
* Copyright (C) 2001 Kyle A. Lucke IBM Corporation
* Copyright (C) 2001 Mike Corrigan & Dave Engebretsen IBM Corporation
*
@@ -27,8 +26,9 @@
#include <asm/lppaca.h>
#include <asm/iSeries/ItLpQueue.h>
#include <asm/iSeries/HvCallXm.h>
-#include <asm/iSeries/IoHriMainStore.h>
-#include <asm/iSeries/IoHriProcessorVpd.h>
+
+#include "processor_vpd.h"
+#include "main_store.h"
static int __init iseries_proc_create(void)
{
@@ -68,12 +68,15 @@ static int proc_titantod_show(struct seq_file *m, void *v)
unsigned long tb_ticks = (tb0 - startTb);
unsigned long titan_jiffies = titan_usec / (1000000/HZ);
unsigned long titan_jiff_usec = titan_jiffies * (1000000/HZ);
- unsigned long titan_jiff_rem_usec = titan_usec - titan_jiff_usec;
+ unsigned long titan_jiff_rem_usec =
+ titan_usec - titan_jiff_usec;
unsigned long tb_jiffies = tb_ticks / tb_ticks_per_jiffy;
unsigned long tb_jiff_ticks = tb_jiffies * tb_ticks_per_jiffy;
unsigned long tb_jiff_rem_ticks = tb_ticks - tb_jiff_ticks;
- unsigned long tb_jiff_rem_usec = tb_jiff_rem_ticks / tb_ticks_per_usec;
- unsigned long new_tb_ticks_per_jiffy = (tb_ticks * (1000000/HZ))/titan_usec;
+ unsigned long tb_jiff_rem_usec =
+ tb_jiff_rem_ticks / tb_ticks_per_usec;
+ unsigned long new_tb_ticks_per_jiffy =
+ (tb_ticks * (1000000/HZ))/titan_usec;
seq_printf(m, " titan elapsed = %lu uSec\n", titan_usec);
seq_printf(m, " tb elapsed = %lu ticks\n", tb_ticks);
diff --git a/include/asm-ppc64/iSeries/IoHriProcessorVpd.h b/arch/powerpc/platforms/iseries/processor_vpd.h
index 73b73d80b8b1..7ac5d0d0dbfa 100644
--- a/include/asm-ppc64/iSeries/IoHriProcessorVpd.h
+++ b/arch/powerpc/platforms/iseries/processor_vpd.h
@@ -1,5 +1,4 @@
/*
- * IoHriProcessorVpd.h
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
@@ -16,8 +15,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _IOHRIPROCESSORVPD_H
-#define _IOHRIPROCESSORVPD_H
+#ifndef _ISERIES_PROCESSOR_VPD_H
+#define _ISERIES_PROCESSOR_VPD_H
#include <asm/types.h>
@@ -83,4 +82,4 @@ struct IoHriProcessorVpd {
extern struct IoHriProcessorVpd xIoHriProcessorVpd[];
-#endif /* _IOHRIPROCESSORVPD_H */
+#endif /* _ISERIES_PROCESSOR_VPD_H */
diff --git a/include/asm-ppc64/iSeries/HvReleaseData.h b/arch/powerpc/platforms/iseries/release_data.h
index c8162e5ccb21..c68b9c3e5caf 100644
--- a/include/asm-ppc64/iSeries/HvReleaseData.h
+++ b/arch/powerpc/platforms/iseries/release_data.h
@@ -1,5 +1,4 @@
/*
- * HvReleaseData.h
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
@@ -16,8 +15,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _HVRELEASEDATA_H
-#define _HVRELEASEDATA_H
+#ifndef _ISERIES_RELEASE_DATA_H
+#define _ISERIES_RELEASE_DATA_H
/*
* This control block contains the critical information about the
@@ -61,4 +60,4 @@ struct HvReleaseData {
extern struct HvReleaseData hvReleaseData;
-#endif /* _HVRELEASEDATA_H */
+#endif /* _ISERIES_RELEASE_DATA_H */
diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/powerpc/platforms/iseries/setup.c
index 3ffefbbc6623..1544c6f10a38 100644
--- a/arch/ppc64/kernel/iSeries_setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -2,8 +2,6 @@
* Copyright (c) 2000 Mike Corrigan <mikejc@us.ibm.com>
* Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
*
- * Module name: iSeries_setup.c
- *
* Description:
* Architecture- / platform-specific boot-time initialization code for
* the IBM iSeries LPAR. Adapted from original code by Grant Erickson and
@@ -42,26 +40,27 @@
#include <asm/firmware.h>
#include <asm/time.h>
-#include "iSeries_setup.h"
#include <asm/naca.h>
#include <asm/paca.h>
#include <asm/cache.h>
#include <asm/sections.h>
#include <asm/abs_addr.h>
-#include <asm/iSeries/HvCallHpt.h>
#include <asm/iSeries/HvLpConfig.h>
#include <asm/iSeries/HvCallEvent.h>
-#include <asm/iSeries/HvCallSm.h>
#include <asm/iSeries/HvCallXm.h>
#include <asm/iSeries/ItLpQueue.h>
-#include <asm/iSeries/IoHriMainStore.h>
#include <asm/iSeries/mf.h>
#include <asm/iSeries/HvLpEvent.h>
-#include <asm/iSeries/iSeries_irq.h>
-#include <asm/iSeries/IoHriProcessorVpd.h>
-#include <asm/iSeries/ItVpdAreas.h>
#include <asm/iSeries/LparMap.h>
+#include "setup.h"
+#include "irq.h"
+#include "vpd_areas.h"
+#include "processor_vpd.h"
+#include "main_store.h"
+#include "call_sm.h"
+#include "call_hpt.h"
+
extern void hvlog(char *fmt, ...);
#ifdef DEBUG
@@ -74,8 +73,8 @@ extern void hvlog(char *fmt, ...);
extern void ppcdbg_initialize(void);
static void build_iSeries_Memory_Map(void);
-static void setup_iSeries_cache_sizes(void);
-static void iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr);
+static void iseries_shared_idle(void);
+static void iseries_dedicated_idle(void);
#ifdef CONFIG_PCI
extern void iSeries_pci_final_fixup(void);
#else
@@ -83,14 +82,6 @@ static void iSeries_pci_final_fixup(void) { }
#endif
/* Global Variables */
-static unsigned long procFreqHz;
-static unsigned long procFreqMhz;
-static unsigned long procFreqMhzHundreths;
-
-static unsigned long tbFreqHz;
-static unsigned long tbFreqMhz;
-static unsigned long tbFreqMhzHundreths;
-
int piranha_simulator;
extern int rd_size; /* Defined in drivers/block/rd.c */
@@ -311,14 +302,14 @@ static void __init iSeries_get_cmdline(void)
static void __init iSeries_init_early(void)
{
- extern unsigned long memory_limit;
-
DBG(" -> iSeries_init_early()\n");
ppc64_firmware_features = FW_FEATURE_ISERIES;
ppcdbg_initialize();
+ ppc64_interrupt_controller = IC_ISERIES;
+
#if defined(CONFIG_BLK_DEV_INITRD)
/*
* If the init RAM disk has been configured and there is
@@ -341,12 +332,6 @@ static void __init iSeries_init_early(void)
iSeries_recal_titan = HvCallXm_loadTod();
/*
- * Cache sizes must be initialized before hpte_init_iSeries is called
- * as the later need them for flush_icache_range()
- */
- setup_iSeries_cache_sizes();
-
- /*
* Initialize the hash table management pointers
*/
hpte_init_iSeries();
@@ -356,12 +341,6 @@ static void __init iSeries_init_early(void)
*/
iommu_init_early_iSeries();
- /*
- * Initialize the table which translate Linux physical addresses to
- * AS/400 absolute addresses
- */
- build_iSeries_Memory_Map();
-
iSeries_get_cmdline();
/* Save unparsed command line copy for /proc/cmdline */
@@ -379,14 +358,6 @@ static void __init iSeries_init_early(void)
}
}
- /* Bolt kernel mappings for all of memory (or just a bit if we've got a limit) */
- iSeries_bolt_kernel(0, systemcfg->physicalMemorySize);
-
- lmb_init();
- lmb_add(0, systemcfg->physicalMemorySize);
- lmb_analyze();
- lmb_reserve(0, __pa(klimit));
-
/* Initialize machine-dependency vectors */
#ifdef CONFIG_SMP
smp_init_iSeries();
@@ -457,7 +428,6 @@ static void __init build_iSeries_Memory_Map(void)
u32 loadAreaFirstChunk, loadAreaLastChunk, loadAreaSize;
u32 nextPhysChunk;
u32 hptFirstChunk, hptLastChunk, hptSizeChunks, hptSizePages;
- u32 num_ptegs;
u32 totalChunks,moreChunks;
u32 currChunk, thisChunk, absChunk;
u32 currDword;
@@ -520,10 +490,7 @@ static void __init build_iSeries_Memory_Map(void)
printk("HPT absolute addr = %016lx, size = %dK\n",
chunk_to_addr(hptFirstChunk), hptSizeChunks * 256);
- /* Fill in the hashed page table hash mask */
- num_ptegs = hptSizePages *
- (PAGE_SIZE / (sizeof(hpte_t) * HPTES_PER_GROUP));
- htab_hash_mask = num_ptegs - 1;
+ ppc64_pft_size = __ilog2(hptSizePages * PAGE_SIZE);
/*
* The actual hashed page table is in the hypervisor,
@@ -592,144 +559,33 @@ static void __init build_iSeries_Memory_Map(void)
}
/*
- * Set up the variables that describe the cache line sizes
- * for this machine.
- */
-static void __init setup_iSeries_cache_sizes(void)
-{
- unsigned int i, n;
- unsigned int procIx = get_paca()->lppaca.dyn_hv_phys_proc_index;
-
- systemcfg->icache_size =
- ppc64_caches.isize = xIoHriProcessorVpd[procIx].xInstCacheSize * 1024;
- systemcfg->icache_line_size =
- ppc64_caches.iline_size =
- xIoHriProcessorVpd[procIx].xInstCacheOperandSize;
- systemcfg->dcache_size =
- ppc64_caches.dsize =
- xIoHriProcessorVpd[procIx].xDataL1CacheSizeKB * 1024;
- systemcfg->dcache_line_size =
- ppc64_caches.dline_size =
- xIoHriProcessorVpd[procIx].xDataCacheOperandSize;
- ppc64_caches.ilines_per_page = PAGE_SIZE / ppc64_caches.iline_size;
- ppc64_caches.dlines_per_page = PAGE_SIZE / ppc64_caches.dline_size;
-
- i = ppc64_caches.iline_size;
- n = 0;
- while ((i = (i / 2)))
- ++n;
- ppc64_caches.log_iline_size = n;
-
- i = ppc64_caches.dline_size;
- n = 0;
- while ((i = (i / 2)))
- ++n;
- ppc64_caches.log_dline_size = n;
-
- printk("D-cache line size = %d\n",
- (unsigned int)ppc64_caches.dline_size);
- printk("I-cache line size = %d\n",
- (unsigned int)ppc64_caches.iline_size);
-}
-
-/*
- * Create a pte. Used during initialization only.
- */
-static void iSeries_make_pte(unsigned long va, unsigned long pa,
- int mode)
-{
- hpte_t local_hpte, rhpte;
- unsigned long hash, vpn;
- long slot;
-
- vpn = va >> PAGE_SHIFT;
- hash = hpt_hash(vpn, 0);
-
- local_hpte.r = pa | mode;
- local_hpte.v = ((va >> 23) << HPTE_V_AVPN_SHIFT)
- | HPTE_V_BOLTED | HPTE_V_VALID;
-
- slot = HvCallHpt_findValid(&rhpte, vpn);
- if (slot < 0) {
- /* Must find space in primary group */
- panic("hash_page: hpte already exists\n");
- }
- HvCallHpt_addValidate(slot, 0, &local_hpte);
-}
-
-/*
- * Bolt the kernel addr space into the HPT
- */
-static void __init iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr)
-{
- unsigned long pa;
- unsigned long mode_rw = _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX;
- hpte_t hpte;
-
- for (pa = saddr; pa < eaddr ;pa += PAGE_SIZE) {
- unsigned long ea = (unsigned long)__va(pa);
- unsigned long vsid = get_kernel_vsid(ea);
- unsigned long va = (vsid << 28) | (pa & 0xfffffff);
- unsigned long vpn = va >> PAGE_SHIFT;
- unsigned long slot = HvCallHpt_findValid(&hpte, vpn);
-
- /* Make non-kernel text non-executable */
- if (!in_kernel_text(ea))
- mode_rw |= HW_NO_EXEC;
-
- if (hpte.v & HPTE_V_VALID) {
- /* HPTE exists, so just bolt it */
- HvCallHpt_setSwBits(slot, 0x10, 0);
- /* And make sure the pp bits are correct */
- HvCallHpt_setPp(slot, PP_RWXX);
- } else
- /* No HPTE exists, so create a new bolted one */
- iSeries_make_pte(va, phys_to_abs(pa), mode_rw);
- }
-}
-
-/*
* Document me.
*/
static void __init iSeries_setup_arch(void)
{
unsigned procIx = get_paca()->lppaca.dyn_hv_phys_proc_index;
- /* Add an eye catcher and the systemcfg layout version number */
- strcpy(systemcfg->eye_catcher, "SYSTEMCFG:PPC64");
- systemcfg->version.major = SYSTEMCFG_MAJOR;
- systemcfg->version.minor = SYSTEMCFG_MINOR;
+ if (get_paca()->lppaca.shared_proc) {
+ ppc_md.idle_loop = iseries_shared_idle;
+ printk(KERN_INFO "Using shared processor idle loop\n");
+ } else {
+ ppc_md.idle_loop = iseries_dedicated_idle;
+ printk(KERN_INFO "Using dedicated idle loop\n");
+ }
/* Setup the Lp Event Queue */
setup_hvlpevent_queue();
- /* Compute processor frequency */
- procFreqHz = ((1UL << 34) * 1000000) /
- xIoHriProcessorVpd[procIx].xProcFreq;
- procFreqMhz = procFreqHz / 1000000;
- procFreqMhzHundreths = (procFreqHz / 10000) - (procFreqMhz * 100);
- ppc_proc_freq = procFreqHz;
-
- /* Compute time base frequency */
- tbFreqHz = ((1UL << 32) * 1000000) /
- xIoHriProcessorVpd[procIx].xTimeBaseFreq;
- tbFreqMhz = tbFreqHz / 1000000;
- tbFreqMhzHundreths = (tbFreqHz / 10000) - (tbFreqMhz * 100);
- ppc_tb_freq = tbFreqHz;
-
printk("Max logical processors = %d\n",
itVpdAreas.xSlicMaxLogicalProcs);
printk("Max physical processors = %d\n",
itVpdAreas.xSlicMaxPhysicalProcs);
- printk("Processor frequency = %lu.%02lu\n", procFreqMhz,
- procFreqMhzHundreths);
- printk("Time base frequency = %lu.%02lu\n", tbFreqMhz,
- tbFreqMhzHundreths);
+
systemcfg->processor = xIoHriProcessorVpd[procIx].xPVR;
printk("Processor version = %x\n", systemcfg->processor);
}
-static void iSeries_get_cpuinfo(struct seq_file *m)
+static void iSeries_show_cpuinfo(struct seq_file *m)
{
seq_printf(m, "machine\t\t: 64-bit iSeries Logical Partition\n");
}
@@ -768,49 +624,6 @@ static void iSeries_halt(void)
mf_power_off();
}
-/*
- * void __init iSeries_calibrate_decr()
- *
- * Description:
- * This routine retrieves the internal processor frequency from the VPD,
- * and sets up the kernel timer decrementer based on that value.
- *
- */
-static void __init iSeries_calibrate_decr(void)
-{
- unsigned long cyclesPerUsec;
- struct div_result divres;
-
- /* Compute decrementer (and TB) frequency in cycles/sec */
- cyclesPerUsec = ppc_tb_freq / 1000000;
-
- /*
- * Set the amount to refresh the decrementer by. This
- * is the number of decrementer ticks it takes for
- * 1/HZ seconds.
- */
- tb_ticks_per_jiffy = ppc_tb_freq / HZ;
-
-#if 0
- /* TEST CODE FOR ADJTIME */
- tb_ticks_per_jiffy += tb_ticks_per_jiffy / 5000;
- /* END OF TEST CODE */
-#endif
-
- /*
- * tb_ticks_per_sec = freq; would give better accuracy
- * but tb_ticks_per_sec = tb_ticks_per_jiffy*HZ; assures
- * that jiffies (and xtime) will match the time returned
- * by do_gettimeofday.
- */
- tb_ticks_per_sec = tb_ticks_per_jiffy * HZ;
- tb_ticks_per_usec = cyclesPerUsec;
- tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000);
- div128_by_32(1024 * 1024, 0, tb_ticks_per_sec, &divres);
- tb_to_xs = divres.result_low;
- setup_default_decr();
-}
-
static void __init iSeries_progress(char * st, unsigned short code)
{
printk("Progress: [%04x] - %s\n", (unsigned)code, st);
@@ -878,7 +691,7 @@ static void yield_shared_processor(void)
process_iSeries_events();
}
-static int iseries_shared_idle(void)
+static void iseries_shared_idle(void)
{
while (1) {
while (!need_resched() && !hvlpevent_is_pending()) {
@@ -900,11 +713,9 @@ static int iseries_shared_idle(void)
schedule();
}
-
- return 0;
}
-static int iseries_dedicated_idle(void)
+static void iseries_dedicated_idle(void)
{
long oldval;
@@ -934,44 +745,252 @@ static int iseries_dedicated_idle(void)
ppc64_runlatch_on();
schedule();
}
-
- return 0;
}
#ifndef CONFIG_PCI
void __init iSeries_init_IRQ(void) { }
#endif
-void __init iSeries_early_setup(void)
+static int __init iseries_probe(int platform)
{
- iSeries_fixup_klimit();
+ return PLATFORM_ISERIES_LPAR == platform;
+}
- ppc_md.setup_arch = iSeries_setup_arch;
- ppc_md.get_cpuinfo = iSeries_get_cpuinfo;
- ppc_md.init_IRQ = iSeries_init_IRQ;
- ppc_md.get_irq = iSeries_get_irq;
- ppc_md.init_early = iSeries_init_early,
+struct machdep_calls __initdata iseries_md = {
+ .setup_arch = iSeries_setup_arch,
+ .show_cpuinfo = iSeries_show_cpuinfo,
+ .init_IRQ = iSeries_init_IRQ,
+ .get_irq = iSeries_get_irq,
+ .init_early = iSeries_init_early,
+ .pcibios_fixup = iSeries_pci_final_fixup,
+ .restart = iSeries_restart,
+ .power_off = iSeries_power_off,
+ .halt = iSeries_halt,
+ .get_boot_time = iSeries_get_boot_time,
+ .set_rtc_time = iSeries_set_rtc_time,
+ .get_rtc_time = iSeries_get_rtc_time,
+ .calibrate_decr = generic_calibrate_decr,
+ .progress = iSeries_progress,
+ .probe = iseries_probe,
+ /* XXX Implement enable_pmcs for iSeries */
+};
- ppc_md.pcibios_fixup = iSeries_pci_final_fixup;
+struct blob {
+ unsigned char data[PAGE_SIZE];
+ unsigned long next;
+};
- ppc_md.restart = iSeries_restart;
- ppc_md.power_off = iSeries_power_off;
- ppc_md.halt = iSeries_halt;
+struct iseries_flat_dt {
+ struct boot_param_header header;
+ u64 reserve_map[2];
+ struct blob dt;
+ struct blob strings;
+};
- ppc_md.get_boot_time = iSeries_get_boot_time;
- ppc_md.set_rtc_time = iSeries_set_rtc_time;
- ppc_md.get_rtc_time = iSeries_get_rtc_time;
- ppc_md.calibrate_decr = iSeries_calibrate_decr;
- ppc_md.progress = iSeries_progress;
+struct iseries_flat_dt iseries_dt;
- /* XXX Implement enable_pmcs for iSeries */
+void dt_init(struct iseries_flat_dt *dt)
+{
+ dt->header.off_mem_rsvmap =
+ offsetof(struct iseries_flat_dt, reserve_map);
+ dt->header.off_dt_struct = offsetof(struct iseries_flat_dt, dt);
+ dt->header.off_dt_strings = offsetof(struct iseries_flat_dt, strings);
+ dt->header.totalsize = sizeof(struct iseries_flat_dt);
+ dt->header.dt_strings_size = sizeof(struct blob);
- if (get_paca()->lppaca.shared_proc) {
- ppc_md.idle_loop = iseries_shared_idle;
- printk(KERN_INFO "Using shared processor idle loop\n");
- } else {
- ppc_md.idle_loop = iseries_dedicated_idle;
- printk(KERN_INFO "Using dedicated idle loop\n");
+ /* There is no notion of hardware cpu id on iSeries */
+ dt->header.boot_cpuid_phys = smp_processor_id();
+
+ dt->dt.next = (unsigned long)&dt->dt.data;
+ dt->strings.next = (unsigned long)&dt->strings.data;
+
+ dt->header.magic = OF_DT_HEADER;
+ dt->header.version = 0x10;
+ dt->header.last_comp_version = 0x10;
+
+ dt->reserve_map[0] = 0;
+ dt->reserve_map[1] = 0;
+}
+
+void dt_check_blob(struct blob *b)
+{
+ if (b->next >= (unsigned long)&b->next) {
+ DBG("Ran out of space in flat device tree blob!\n");
+ BUG();
}
}
+void dt_push_u32(struct iseries_flat_dt *dt, u32 value)
+{
+ *((u32*)dt->dt.next) = value;
+ dt->dt.next += sizeof(u32);
+
+ dt_check_blob(&dt->dt);
+}
+
+void dt_push_u64(struct iseries_flat_dt *dt, u64 value)
+{
+ *((u64*)dt->dt.next) = value;
+ dt->dt.next += sizeof(u64);
+
+ dt_check_blob(&dt->dt);
+}
+
+unsigned long dt_push_bytes(struct blob *blob, char *data, int len)
+{
+ unsigned long start = blob->next - (unsigned long)blob->data;
+
+ memcpy((char *)blob->next, data, len);
+ blob->next = _ALIGN(blob->next + len, 4);
+
+ dt_check_blob(blob);
+
+ return start;
+}
+
+void dt_start_node(struct iseries_flat_dt *dt, char *name)
+{
+ dt_push_u32(dt, OF_DT_BEGIN_NODE);
+ dt_push_bytes(&dt->dt, name, strlen(name) + 1);
+}
+
+#define dt_end_node(dt) dt_push_u32(dt, OF_DT_END_NODE)
+
+void dt_prop(struct iseries_flat_dt *dt, char *name, char *data, int len)
+{
+ unsigned long offset;
+
+ dt_push_u32(dt, OF_DT_PROP);
+
+ /* Length of the data */
+ dt_push_u32(dt, len);
+
+ /* Put the property name in the string blob. */
+ offset = dt_push_bytes(&dt->strings, name, strlen(name) + 1);
+
+ /* The offset of the properties name in the string blob. */
+ dt_push_u32(dt, (u32)offset);
+
+ /* The actual data. */
+ dt_push_bytes(&dt->dt, data, len);
+}
+
+void dt_prop_str(struct iseries_flat_dt *dt, char *name, char *data)
+{
+ dt_prop(dt, name, data, strlen(data) + 1); /* + 1 for NULL */
+}
+
+void dt_prop_u32(struct iseries_flat_dt *dt, char *name, u32 data)
+{
+ dt_prop(dt, name, (char *)&data, sizeof(u32));
+}
+
+void dt_prop_u64(struct iseries_flat_dt *dt, char *name, u64 data)
+{
+ dt_prop(dt, name, (char *)&data, sizeof(u64));
+}
+
+void dt_prop_u64_list(struct iseries_flat_dt *dt, char *name, u64 *data, int n)
+{
+ dt_prop(dt, name, (char *)data, sizeof(u64) * n);
+}
+
+void dt_prop_empty(struct iseries_flat_dt *dt, char *name)
+{
+ dt_prop(dt, name, NULL, 0);
+}
+
+void dt_cpus(struct iseries_flat_dt *dt)
+{
+ unsigned char buf[32];
+ unsigned char *p;
+ unsigned int i, index;
+ struct IoHriProcessorVpd *d;
+
+ /* yuck */
+ snprintf(buf, 32, "PowerPC,%s", cur_cpu_spec->cpu_name);
+ p = strchr(buf, ' ');
+ if (!p) p = buf + strlen(buf);
+
+ dt_start_node(dt, "cpus");
+ dt_prop_u32(dt, "#address-cells", 1);
+ dt_prop_u32(dt, "#size-cells", 0);
+
+ for (i = 0; i < NR_CPUS; i++) {
+ if (paca[i].lppaca.dyn_proc_status >= 2)
+ continue;
+
+ snprintf(p, 32 - (p - buf), "@%d", i);
+ dt_start_node(dt, buf);
+
+ dt_prop_str(dt, "device_type", "cpu");
+
+ index = paca[i].lppaca.dyn_hv_phys_proc_index;
+ d = &xIoHriProcessorVpd[index];
+
+ dt_prop_u32(dt, "i-cache-size", d->xInstCacheSize * 1024);
+ dt_prop_u32(dt, "i-cache-line-size", d->xInstCacheOperandSize);
+
+ dt_prop_u32(dt, "d-cache-size", d->xDataL1CacheSizeKB * 1024);
+ dt_prop_u32(dt, "d-cache-line-size", d->xDataCacheOperandSize);
+
+ /* magic conversions to Hz copied from old code */
+ dt_prop_u32(dt, "clock-frequency",
+ ((1UL << 34) * 1000000) / d->xProcFreq);
+ dt_prop_u32(dt, "timebase-frequency",
+ ((1UL << 32) * 1000000) / d->xTimeBaseFreq);
+
+ dt_prop_u32(dt, "reg", i);
+
+ dt_end_node(dt);
+ }
+
+ dt_end_node(dt);
+}
+
+void build_flat_dt(struct iseries_flat_dt *dt)
+{
+ u64 tmp[2];
+
+ dt_init(dt);
+
+ dt_start_node(dt, "");
+
+ dt_prop_u32(dt, "#address-cells", 2);
+ dt_prop_u32(dt, "#size-cells", 2);
+
+ /* /memory */
+ dt_start_node(dt, "memory@0");
+ dt_prop_str(dt, "name", "memory");
+ dt_prop_str(dt, "device_type", "memory");
+ tmp[0] = 0;
+ tmp[1] = systemcfg->physicalMemorySize;
+ dt_prop_u64_list(dt, "reg", tmp, 2);
+ dt_end_node(dt);
+
+ /* /chosen */
+ dt_start_node(dt, "chosen");
+ dt_prop_u32(dt, "linux,platform", PLATFORM_ISERIES_LPAR);
+ dt_end_node(dt);
+
+ dt_cpus(dt);
+
+ dt_end_node(dt);
+
+ dt_push_u32(dt, OF_DT_END);
+}
+
+void * __init iSeries_early_setup(void)
+{
+ iSeries_fixup_klimit();
+
+ /*
+ * Initialize the table which translate Linux physical addresses to
+ * AS/400 absolute addresses
+ */
+ build_iSeries_Memory_Map();
+
+ build_flat_dt(&iseries_dt);
+
+ return (void *) __pa(&iseries_dt);
+}
diff --git a/arch/ppc64/kernel/iSeries_setup.h b/arch/powerpc/platforms/iseries/setup.h
index c6eb29a245ac..5213044ec411 100644
--- a/arch/ppc64/kernel/iSeries_setup.h
+++ b/arch/powerpc/platforms/iseries/setup.h
@@ -2,8 +2,6 @@
* Copyright (c) 2000 Mike Corrigan <mikejc@us.ibm.com>
* Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
*
- * Module name: as400_setup.h
- *
* Description:
* Architecture- / platform-specific boot-time initialization code for
* the IBM AS/400 LPAR. Adapted from original code by Grant Erickson and
@@ -19,7 +17,7 @@
#ifndef __ISERIES_SETUP_H__
#define __ISERIES_SETUP_H__
-extern void iSeries_get_boot_time(struct rtc_time *tm);
+extern unsigned long iSeries_get_boot_time(void);
extern int iSeries_set_rtc_time(struct rtc_time *tm);
extern void iSeries_get_rtc_time(struct rtc_time *tm);
diff --git a/arch/ppc64/kernel/iSeries_smp.c b/arch/powerpc/platforms/iseries/smp.c
index f74386e31638..f720916682f6 100644
--- a/arch/ppc64/kernel/iSeries_smp.c
+++ b/arch/powerpc/platforms/iseries/smp.c
@@ -47,17 +47,17 @@
static unsigned long iSeries_smp_message[NR_CPUS];
-void iSeries_smp_message_recv( struct pt_regs * regs )
+void iSeries_smp_message_recv(struct pt_regs *regs)
{
int cpu = smp_processor_id();
int msg;
- if ( num_online_cpus() < 2 )
+ if (num_online_cpus() < 2)
return;
- for ( msg = 0; msg < 4; ++msg )
- if ( test_and_clear_bit( msg, &iSeries_smp_message[cpu] ) )
- smp_message_recv( msg, regs );
+ for (msg = 0; msg < 4; msg++)
+ if (test_and_clear_bit(msg, &iSeries_smp_message[cpu]))
+ smp_message_recv(msg, regs);
}
static inline void smp_iSeries_do_message(int cpu, int msg)
@@ -74,48 +74,22 @@ static void smp_iSeries_message_pass(int target, int msg)
smp_iSeries_do_message(target, msg);
else {
for_each_online_cpu(i) {
- if (target == MSG_ALL_BUT_SELF
- && i == smp_processor_id())
+ if ((target == MSG_ALL_BUT_SELF) &&
+ (i == smp_processor_id()))
continue;
smp_iSeries_do_message(i, msg);
}
}
}
-static int smp_iSeries_numProcs(void)
-{
- unsigned np, i;
-
- np = 0;
- for (i=0; i < NR_CPUS; ++i) {
- if (paca[i].lppaca.dyn_proc_status < 2) {
- cpu_set(i, cpu_possible_map);
- cpu_set(i, cpu_present_map);
- cpu_set(i, cpu_sibling_map[i]);
- ++np;
- }
- }
- return np;
-}
-
static int smp_iSeries_probe(void)
{
- unsigned i;
- unsigned np = 0;
-
- for (i=0; i < NR_CPUS; ++i) {
- if (paca[i].lppaca.dyn_proc_status < 2) {
- /*paca[i].active = 1;*/
- ++np;
- }
- }
-
- return np;
+ return cpus_weight(cpu_possible_map);
}
static void smp_iSeries_kick_cpu(int nr)
{
- BUG_ON(nr < 0 || nr >= NR_CPUS);
+ BUG_ON((nr < 0) || (nr >= NR_CPUS));
/* Verify that our partition has a processor nr */
if (paca[nr].lppaca.dyn_proc_status >= 2)
@@ -144,6 +118,4 @@ static struct smp_ops_t iSeries_smp_ops = {
void __init smp_init_iSeries(void)
{
smp_ops = &iSeries_smp_ops;
- systemcfg->processorCount = smp_iSeries_numProcs();
}
-
diff --git a/include/asm-ppc64/iSeries/ItSpCommArea.h b/arch/powerpc/platforms/iseries/spcomm_area.h
index 5535f8271c9f..6e3b685115c9 100644
--- a/include/asm-ppc64/iSeries/ItSpCommArea.h
+++ b/arch/powerpc/platforms/iseries/spcomm_area.h
@@ -1,5 +1,4 @@
/*
- * ItSpCommArea.h
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
@@ -17,8 +16,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _ITSPCOMMAREA_H
-#define _ITSPCOMMAREA_H
+#ifndef _ISERIES_SPCOMM_AREA_H
+#define _ISERIES_SPCOMM_AREA_H
struct SpCommArea {
@@ -34,4 +33,4 @@ struct SpCommArea {
extern struct SpCommArea xSpCommArea;
-#endif /* _ITSPCOMMAREA_H */
+#endif /* _ISERIES_SPCOMM_AREA_H */
diff --git a/arch/ppc64/kernel/iSeries_vio.c b/arch/powerpc/platforms/iseries/vio.c
index 6b754b0c8344..c0f7d2e9153f 100644
--- a/arch/ppc64/kernel/iSeries_vio.c
+++ b/arch/powerpc/platforms/iseries/vio.c
@@ -14,6 +14,7 @@
#include <asm/vio.h>
#include <asm/iommu.h>
+#include <asm/tce.h>
#include <asm/abs_addr.h>
#include <asm/page.h>
#include <asm/iSeries/vio.h>
diff --git a/arch/ppc64/kernel/viopath.c b/arch/powerpc/platforms/iseries/viopath.c
index 2a6c4f01c45e..c0c767bd37f1 100644
--- a/arch/ppc64/kernel/viopath.c
+++ b/arch/powerpc/platforms/iseries/viopath.c
@@ -1,5 +1,4 @@
/* -*- linux-c -*-
- * arch/ppc64/kernel/viopath.c
*
* iSeries Virtual I/O Message Path code
*
@@ -7,7 +6,7 @@
* Ryan Arnold <ryanarn@us.ibm.com>
* Colin Devilbiss <devilbis@us.ibm.com>
*
- * (C) Copyright 2000-2003 IBM Corporation
+ * (C) Copyright 2000-2005 IBM Corporation
*
* This code is used by the iSeries virtual disk, cd,
* tape, and console to communicate with OS/400 in another
diff --git a/include/asm-ppc64/iSeries/ItVpdAreas.h b/arch/powerpc/platforms/iseries/vpd_areas.h
index 71b3ad24f95a..601e6dd860ed 100644
--- a/include/asm-ppc64/iSeries/ItVpdAreas.h
+++ b/arch/powerpc/platforms/iseries/vpd_areas.h
@@ -1,5 +1,4 @@
/*
- * ItVpdAreas.h
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
@@ -16,8 +15,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _ITVPDAREAS_H
-#define _ITVPDAREAS_H
+#ifndef _ISERIES_VPD_AREAS_H
+#define _ISERIES_VPD_AREAS_H
/*
* This file defines the address and length of all of the VPD area passed to
@@ -86,4 +85,4 @@ struct ItVpdAreas {
extern struct ItVpdAreas itVpdAreas;
-#endif /* _ITVPDAREAS_H */
+#endif /* _ISERIES_VPD_AREAS_H */
diff --git a/arch/ppc64/kernel/iSeries_VpdInfo.c b/arch/powerpc/platforms/iseries/vpdinfo.c
index 5d921792571f..9c318849dee7 100644
--- a/arch/ppc64/kernel/iSeries_VpdInfo.c
+++ b/arch/powerpc/platforms/iseries/vpdinfo.c
@@ -1,6 +1,4 @@
/*
- * File iSeries_vpdInfo.c created by Allan Trautman on Fri Feb 2 2001.
- *
* This code gets the card location of the hardware
* Copyright (C) 2001 <Allan H Trautman> <IBM Corp>
* Copyright (C) 2005 Stephen Rothwel, IBM Corp
@@ -29,12 +27,15 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>
+
#include <asm/types.h>
#include <asm/resource.h>
-
-#include <asm/iSeries/HvCallPci.h>
+#include <asm/abs_addr.h>
+#include <asm/pci-bridge.h>
#include <asm/iSeries/HvTypes.h>
-#include <asm/iSeries/iSeries_pci.h>
+
+#include "pci.h"
+#include "call_pci.h"
/*
* Size of Bus VPD data
@@ -214,7 +215,7 @@ static void __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent,
printk("PCI: Bus VPD Buffer allocation failure.\n");
return;
}
- BusVpdLen = HvCallPci_getBusVpd(bus, ISERIES_HV_ADDR(BusVpdPtr),
+ BusVpdLen = HvCallPci_getBusVpd(bus, iseries_hv_addr(BusVpdPtr),
BUS_VPDSIZE);
if (BusVpdLen == 0) {
printk("PCI: Bus VPD Buffer zero length.\n");
@@ -242,7 +243,8 @@ out_free:
*/
void __init iSeries_Device_Information(struct pci_dev *PciDev, int count)
{
- struct iSeries_Device_Node *DevNode = PciDev->sysdata;
+ struct device_node *DevNode = PciDev->sysdata;
+ struct pci_dn *pdn;
u16 bus;
u8 frame;
char card[4];
@@ -255,8 +257,9 @@ void __init iSeries_Device_Information(struct pci_dev *PciDev, int count)
return;
}
- bus = ISERIES_BUS(DevNode);
- subbus = ISERIES_SUBBUS(DevNode);
+ pdn = PCI_DN(DevNode);
+ bus = pdn->busno;
+ subbus = pdn->bussubno;
agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus),
ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus));
iSeries_Get_Location_Code(bus, agent, &frame, card);
diff --git a/arch/powerpc/platforms/maple/Makefile b/arch/powerpc/platforms/maple/Makefile
new file mode 100644
index 000000000000..1be1a993c5f5
--- /dev/null
+++ b/arch/powerpc/platforms/maple/Makefile
@@ -0,0 +1 @@
+obj-y += setup.o pci.o time.o
diff --git a/arch/powerpc/platforms/maple/maple.h b/arch/powerpc/platforms/maple/maple.h
new file mode 100644
index 000000000000..0657c579b840
--- /dev/null
+++ b/arch/powerpc/platforms/maple/maple.h
@@ -0,0 +1,12 @@
+/*
+ * Declarations for maple-specific code.
+ *
+ * Maple is the name of a PPC970 evaluation board.
+ */
+extern int maple_set_rtc_time(struct rtc_time *tm);
+extern void maple_get_rtc_time(struct rtc_time *tm);
+extern unsigned long maple_get_boot_time(void);
+extern void maple_calibrate_decr(void);
+extern void maple_pci_init(void);
+extern void maple_pcibios_fixup(void);
+extern int maple_pci_get_legacy_ide_irq(struct pci_dev *dev, int channel);
diff --git a/arch/ppc64/kernel/maple_pci.c b/arch/powerpc/platforms/maple/pci.c
index 1d297e0edfc0..340c21caeae2 100644
--- a/arch/ppc64/kernel/maple_pci.c
+++ b/arch/powerpc/platforms/maple/pci.c
@@ -23,8 +23,9 @@
#include <asm/pci-bridge.h>
#include <asm/machdep.h>
#include <asm/iommu.h>
+#include <asm/ppc-pci.h>
-#include "pci.h"
+#include "maple.h"
#ifdef DEBUG
#define DBG(x...) printk(x)
@@ -276,7 +277,7 @@ static void __init setup_u3_agp(struct pci_controller* hose)
{
/* On G5, we move AGP up to high bus number so we don't need
* to reassign bus numbers for HT. If we ever have P2P bridges
- * on AGP, we'll have to move pci_assign_all_busses to the
+ * on AGP, we'll have to move pci_assign_all_buses to the
* pci_controller structure so we enable it for AGP and not for
* HT childs.
* We hard code the address because of the different size of
@@ -360,7 +361,7 @@ static int __init add_bridge(struct device_node *dev)
/* Interpret the "ranges" property */
/* This also maps the I/O region and sets isa_io/mem_base */
- pci_process_bridge_OF_ranges(hose, dev);
+ pci_process_bridge_OF_ranges(hose, dev, primary);
pci_setup_phb_io(hose, primary);
/* Fixup "bus-range" OF property */
diff --git a/arch/ppc64/kernel/maple_setup.c b/arch/powerpc/platforms/maple/setup.c
index fc0567498a3a..7ece8983a105 100644
--- a/arch/ppc64/kernel/maple_setup.c
+++ b/arch/powerpc/platforms/maple/setup.c
@@ -1,5 +1,5 @@
/*
- * arch/ppc64/kernel/maple_setup.c
+ * Maple (970 eval board) setup code
*
* (c) Copyright 2004 Benjamin Herrenschmidt (benh@kernel.crashing.org),
* IBM Corp.
@@ -59,8 +59,10 @@
#include <asm/time.h>
#include <asm/of_device.h>
#include <asm/lmb.h>
+#include <asm/mpic.h>
+#include <asm/udbg.h>
-#include "mpic.h"
+#include "maple.h"
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
@@ -68,13 +70,6 @@
#define DBG(fmt...)
#endif
-extern int maple_set_rtc_time(struct rtc_time *tm);
-extern void maple_get_rtc_time(struct rtc_time *tm);
-extern void maple_get_boot_time(struct rtc_time *tm);
-extern void maple_calibrate_decr(void);
-extern void maple_pci_init(void);
-extern void maple_pcibios_fixup(void);
-extern int maple_pci_get_legacy_ide_irq(struct pci_dev *dev, int channel);
extern void generic_find_legacy_serial_ports(u64 *physport,
unsigned int *default_speed);
diff --git a/arch/ppc64/kernel/maple_time.c b/arch/powerpc/platforms/maple/time.c
index d65210abcd03..40fc07a8e606 100644
--- a/arch/ppc64/kernel/maple_time.c
+++ b/arch/powerpc/platforms/maple/time.c
@@ -36,6 +36,8 @@
#include <asm/machdep.h>
#include <asm/time.h>
+#include "maple.h"
+
#ifdef DEBUG
#define DBG(x...) printk(x)
#else
@@ -156,8 +158,9 @@ int maple_set_rtc_time(struct rtc_time *tm)
return 0;
}
-void __init maple_get_boot_time(struct rtc_time *tm)
+unsigned long __init maple_get_boot_time(void)
{
+ struct rtc_time tm;
struct device_node *rtcs;
rtcs = find_compatible_devices("rtc", "pnpPNP,b00");
@@ -170,6 +173,8 @@ void __init maple_get_boot_time(struct rtc_time *tm)
"legacy address (0x%x)\n", maple_rtc_addr);
}
- maple_get_rtc_time(tm);
+ maple_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);
}
diff --git a/arch/powerpc/platforms/powermac/Makefile b/arch/powerpc/platforms/powermac/Makefile
new file mode 100644
index 000000000000..4369676f1d54
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/Makefile
@@ -0,0 +1,8 @@
+obj-y += pic.o setup.o time.o feature.o pci.o \
+ sleep.o low_i2c.o cache.o
+obj-$(CONFIG_PMAC_BACKLIGHT) += backlight.o
+obj-$(CONFIG_CPU_FREQ_PMAC) += cpufreq.o
+obj-$(CONFIG_NVRAM) += nvram.o
+# ppc64 pmac doesn't define CONFIG_NVRAM but needs nvram stuff
+obj-$(CONFIG_PPC64) += nvram.o
+obj-$(CONFIG_SMP) += smp.o
diff --git a/arch/powerpc/platforms/powermac/backlight.c b/arch/powerpc/platforms/powermac/backlight.c
new file mode 100644
index 000000000000..8be2f7d071f0
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/backlight.c
@@ -0,0 +1,202 @@
+/*
+ * Miscellaneous procedures for dealing with the PowerMac hardware.
+ * Contains support for the backlight.
+ *
+ * Copyright (C) 2000 Benjamin Herrenschmidt
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/stddef.h>
+#include <linux/reboot.h>
+#include <linux/nvram.h>
+#include <linux/console.h>
+#include <asm/sections.h>
+#include <asm/ptrace.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/nvram.h>
+#include <asm/backlight.h>
+
+#include <linux/adb.h>
+#include <linux/pmu.h>
+
+static struct backlight_controller *backlighter;
+static void* backlighter_data;
+static int backlight_autosave;
+static int backlight_level = BACKLIGHT_MAX;
+static int backlight_enabled = 1;
+static int backlight_req_level = -1;
+static int backlight_req_enable = -1;
+
+static void backlight_callback(void *);
+static DECLARE_WORK(backlight_work, backlight_callback, NULL);
+
+void register_backlight_controller(struct backlight_controller *ctrler,
+ void *data, char *type)
+{
+ struct device_node* bk_node;
+ char *prop;
+ int valid = 0;
+
+ /* There's already a matching controller, bail out */
+ if (backlighter != NULL)
+ return;
+
+ bk_node = find_devices("backlight");
+
+#ifdef CONFIG_ADB_PMU
+ /* Special case for the old PowerBook since I can't test on it */
+ backlight_autosave = machine_is_compatible("AAPL,3400/2400")
+ || machine_is_compatible("AAPL,3500");
+ if ((backlight_autosave
+ || machine_is_compatible("AAPL,PowerBook1998")
+ || machine_is_compatible("PowerBook1,1"))
+ && !strcmp(type, "pmu"))
+ valid = 1;
+#endif
+ if (bk_node) {
+ prop = get_property(bk_node, "backlight-control", NULL);
+ if (prop && !strncmp(prop, type, strlen(type)))
+ valid = 1;
+ }
+ if (!valid)
+ return;
+ backlighter = ctrler;
+ backlighter_data = data;
+
+ if (bk_node && !backlight_autosave)
+ prop = get_property(bk_node, "bklt", NULL);
+ else
+ prop = NULL;
+ if (prop) {
+ backlight_level = ((*prop)+1) >> 1;
+ if (backlight_level > BACKLIGHT_MAX)
+ backlight_level = BACKLIGHT_MAX;
+ }
+
+#ifdef CONFIG_ADB_PMU
+ if (backlight_autosave) {
+ struct adb_request req;
+ pmu_request(&req, NULL, 2, 0xd9, 0);
+ while (!req.complete)
+ pmu_poll();
+ backlight_level = req.reply[0] >> 4;
+ }
+#endif
+ acquire_console_sem();
+ if (!backlighter->set_enable(1, backlight_level, data))
+ backlight_enabled = 1;
+ release_console_sem();
+
+ printk(KERN_INFO "Registered \"%s\" backlight controller,"
+ "level: %d/15\n", type, backlight_level);
+}
+EXPORT_SYMBOL(register_backlight_controller);
+
+void unregister_backlight_controller(struct backlight_controller
+ *ctrler, void *data)
+{
+ /* We keep the current backlight level (for now) */
+ if (ctrler == backlighter && data == backlighter_data)
+ backlighter = NULL;
+}
+EXPORT_SYMBOL(unregister_backlight_controller);
+
+static int __set_backlight_enable(int enable)
+{
+ int rc;
+
+ if (!backlighter)
+ return -ENODEV;
+ acquire_console_sem();
+ rc = backlighter->set_enable(enable, backlight_level,
+ backlighter_data);
+ if (!rc)
+ backlight_enabled = enable;
+ release_console_sem();
+ return rc;
+}
+int set_backlight_enable(int enable)
+{
+ if (!backlighter)
+ return -ENODEV;
+ backlight_req_enable = enable;
+ schedule_work(&backlight_work);
+ return 0;
+}
+
+EXPORT_SYMBOL(set_backlight_enable);
+
+int get_backlight_enable(void)
+{
+ if (!backlighter)
+ return -ENODEV;
+ return backlight_enabled;
+}
+EXPORT_SYMBOL(get_backlight_enable);
+
+static int __set_backlight_level(int level)
+{
+ int rc = 0;
+
+ if (!backlighter)
+ return -ENODEV;
+ if (level < BACKLIGHT_MIN)
+ level = BACKLIGHT_OFF;
+ if (level > BACKLIGHT_MAX)
+ level = BACKLIGHT_MAX;
+ acquire_console_sem();
+ if (backlight_enabled)
+ rc = backlighter->set_level(level, backlighter_data);
+ if (!rc)
+ backlight_level = level;
+ release_console_sem();
+ if (!rc && !backlight_autosave) {
+ level <<=1;
+ if (level & 0x10)
+ level |= 0x01;
+ // -- todo: save to property "bklt"
+ }
+ return rc;
+}
+int set_backlight_level(int level)
+{
+ if (!backlighter)
+ return -ENODEV;
+ backlight_req_level = level;
+ schedule_work(&backlight_work);
+ return 0;
+}
+
+EXPORT_SYMBOL(set_backlight_level);
+
+int get_backlight_level(void)
+{
+ if (!backlighter)
+ return -ENODEV;
+ return backlight_level;
+}
+EXPORT_SYMBOL(get_backlight_level);
+
+static void backlight_callback(void *dummy)
+{
+ int level, enable;
+
+ do {
+ level = backlight_req_level;
+ enable = backlight_req_enable;
+ mb();
+
+ if (level >= 0)
+ __set_backlight_level(level);
+ if (enable >= 0)
+ __set_backlight_enable(enable);
+ } while(cmpxchg(&backlight_req_level, level, -1) != level ||
+ cmpxchg(&backlight_req_enable, enable, -1) != enable);
+}
diff --git a/arch/powerpc/platforms/powermac/cache.S b/arch/powerpc/platforms/powermac/cache.S
new file mode 100644
index 000000000000..fb977de6b704
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/cache.S
@@ -0,0 +1,359 @@
+/*
+ * This file contains low-level cache management functions
+ * used for sleep and CPU speed changes on Apple machines.
+ * (In fact the only thing that is Apple-specific is that we assume
+ * that we can read from ROM at physical address 0xfff00000.)
+ *
+ * Copyright (C) 2004 Paul Mackerras (paulus@samba.org) and
+ * Benjamin Herrenschmidt (benh@kernel.crashing.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/config.h>
+#include <asm/processor.h>
+#include <asm/ppc_asm.h>
+#include <asm/cputable.h>
+
+/*
+ * Flush and disable all data caches (dL1, L2, L3). This is used
+ * when going to sleep, when doing a PMU based cpufreq transition,
+ * or when "offlining" a CPU on SMP machines. This code is over
+ * paranoid, but I've had enough issues with various CPU revs and
+ * bugs that I decided it was worth beeing over cautious
+ */
+
+_GLOBAL(flush_disable_caches)
+#ifndef CONFIG_6xx
+ blr
+#else
+BEGIN_FTR_SECTION
+ b flush_disable_745x
+END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
+BEGIN_FTR_SECTION
+ b flush_disable_75x
+END_FTR_SECTION_IFSET(CPU_FTR_L2CR)
+ b __flush_disable_L1
+
+/* This is the code for G3 and 74[01]0 */
+flush_disable_75x:
+ mflr r10
+
+ /* Turn off EE and DR in MSR */
+ mfmsr r11
+ rlwinm r0,r11,0,~MSR_EE
+ rlwinm r0,r0,0,~MSR_DR
+ sync
+ mtmsr r0
+ isync
+
+ /* Stop DST streams */
+BEGIN_FTR_SECTION
+ DSSALL
+ sync
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+
+ /* Stop DPM */
+ mfspr r8,SPRN_HID0 /* Save SPRN_HID0 in r8 */
+ rlwinm r4,r8,0,12,10 /* Turn off HID0[DPM] */
+ sync
+ mtspr SPRN_HID0,r4 /* Disable DPM */
+ sync
+
+ /* Disp-flush L1. We have a weird problem here that I never
+ * totally figured out. On 750FX, using the ROM for the flush
+ * results in a non-working flush. We use that workaround for
+ * now until I finally understand what's going on. --BenH
+ */
+
+ /* ROM base by default */
+ lis r4,0xfff0
+ mfpvr r3
+ srwi r3,r3,16
+ cmplwi cr0,r3,0x7000
+ bne+ 1f
+ /* RAM base on 750FX */
+ li r4,0
+1: li r4,0x4000
+ mtctr r4
+1: lwz r0,0(r4)
+ addi r4,r4,32
+ bdnz 1b
+ sync
+ isync
+
+ /* Disable / invalidate / enable L1 data */
+ mfspr r3,SPRN_HID0
+ rlwinm r3,r3,0,~(HID0_DCE | HID0_ICE)
+ mtspr SPRN_HID0,r3
+ sync
+ isync
+ ori r3,r3,(HID0_DCE|HID0_DCI|HID0_ICE|HID0_ICFI)
+ sync
+ isync
+ mtspr SPRN_HID0,r3
+ xori r3,r3,(HID0_DCI|HID0_ICFI)
+ mtspr SPRN_HID0,r3
+ sync
+
+ /* Get the current enable bit of the L2CR into r4 */
+ mfspr r5,SPRN_L2CR
+ /* Set to data-only (pre-745x bit) */
+ oris r3,r5,L2CR_L2DO@h
+ b 2f
+ /* When disabling L2, code must be in L1 */
+ .balign 32
+1: mtspr SPRN_L2CR,r3
+3: sync
+ isync
+ b 1f
+2: b 3f
+3: sync
+ isync
+ b 1b
+1: /* disp-flush L2. The interesting thing here is that the L2 can be
+ * up to 2Mb ... so using the ROM, we'll end up wrapping back to memory
+ * but that is probbaly fine. We disp-flush over 4Mb to be safe
+ */
+ lis r4,2
+ mtctr r4
+ lis r4,0xfff0
+1: lwz r0,0(r4)
+ addi r4,r4,32
+ bdnz 1b
+ sync
+ isync
+ lis r4,2
+ mtctr r4
+ lis r4,0xfff0
+1: dcbf 0,r4
+ addi r4,r4,32
+ bdnz 1b
+ sync
+ isync
+
+ /* now disable L2 */
+ rlwinm r5,r5,0,~L2CR_L2E
+ b 2f
+ /* When disabling L2, code must be in L1 */
+ .balign 32
+1: mtspr SPRN_L2CR,r5
+3: sync
+ isync
+ b 1f
+2: b 3f
+3: sync
+ isync
+ b 1b
+1: sync
+ isync
+ /* Invalidate L2. This is pre-745x, we clear the L2I bit ourselves */
+ oris r4,r5,L2CR_L2I@h
+ mtspr SPRN_L2CR,r4
+ sync
+ isync
+
+ /* Wait for the invalidation to complete */
+1: mfspr r3,SPRN_L2CR
+ rlwinm. r0,r3,0,31,31
+ bne 1b
+
+ /* Clear L2I */
+ xoris r4,r4,L2CR_L2I@h
+ sync
+ mtspr SPRN_L2CR,r4
+ sync
+
+ /* now disable the L1 data cache */
+ mfspr r0,SPRN_HID0
+ rlwinm r0,r0,0,~(HID0_DCE|HID0_ICE)
+ mtspr SPRN_HID0,r0
+ sync
+ isync
+
+ /* Restore HID0[DPM] to whatever it was before */
+ sync
+ mfspr r0,SPRN_HID0
+ rlwimi r0,r8,0,11,11 /* Turn back HID0[DPM] */
+ mtspr SPRN_HID0,r0
+ sync
+
+ /* restore DR and EE */
+ sync
+ mtmsr r11
+ isync
+
+ mtlr r10
+ blr
+
+/* This code is for 745x processors */
+flush_disable_745x:
+ /* Turn off EE and DR in MSR */
+ mfmsr r11
+ rlwinm r0,r11,0,~MSR_EE
+ rlwinm r0,r0,0,~MSR_DR
+ sync
+ mtmsr r0
+ isync
+
+ /* Stop prefetch streams */
+ DSSALL
+ sync
+
+ /* Disable L2 prefetching */
+ mfspr r0,SPRN_MSSCR0
+ rlwinm r0,r0,0,0,29
+ mtspr SPRN_MSSCR0,r0
+ sync
+ isync
+ lis r4,0
+ dcbf 0,r4
+ dcbf 0,r4
+ dcbf 0,r4
+ dcbf 0,r4
+ dcbf 0,r4
+ dcbf 0,r4
+ dcbf 0,r4
+ dcbf 0,r4
+
+ /* Due to a bug with the HW flush on some CPU revs, we occasionally
+ * experience data corruption. I'm adding a displacement flush along
+ * with a dcbf loop over a few Mb to "help". The problem isn't totally
+ * fixed by this in theory, but at least, in practice, I couldn't reproduce
+ * it even with a big hammer...
+ */
+
+ lis r4,0x0002
+ mtctr r4
+ li r4,0
+1:
+ lwz r0,0(r4)
+ addi r4,r4,32 /* Go to start of next cache line */
+ bdnz 1b
+ isync
+
+ /* Now, flush the first 4MB of memory */
+ lis r4,0x0002
+ mtctr r4
+ li r4,0
+ sync
+1:
+ dcbf 0,r4
+ addi r4,r4,32 /* Go to start of next cache line */
+ bdnz 1b
+
+ /* Flush and disable the L1 data cache */
+ mfspr r6,SPRN_LDSTCR
+ lis r3,0xfff0 /* read from ROM for displacement flush */
+ li r4,0xfe /* start with only way 0 unlocked */
+ li r5,128 /* 128 lines in each way */
+1: mtctr r5
+ rlwimi r6,r4,0,24,31
+ mtspr SPRN_LDSTCR,r6
+ sync
+ isync
+2: lwz r0,0(r3) /* touch each cache line */
+ addi r3,r3,32
+ bdnz 2b
+ rlwinm r4,r4,1,24,30 /* move on to the next way */
+ ori r4,r4,1
+ cmpwi r4,0xff /* all done? */
+ bne 1b
+ /* now unlock the L1 data cache */
+ li r4,0
+ rlwimi r6,r4,0,24,31
+ sync
+ mtspr SPRN_LDSTCR,r6
+ sync
+ isync
+
+ /* Flush the L2 cache using the hardware assist */
+ mfspr r3,SPRN_L2CR
+ cmpwi r3,0 /* check if it is enabled first */
+ bge 4f
+ oris r0,r3,(L2CR_L2IO_745x|L2CR_L2DO_745x)@h
+ b 2f
+ /* When disabling/locking L2, code must be in L1 */
+ .balign 32
+1: mtspr SPRN_L2CR,r0 /* lock the L2 cache */
+3: sync
+ isync
+ b 1f
+2: b 3f
+3: sync
+ isync
+ b 1b
+1: sync
+ isync
+ ori r0,r3,L2CR_L2HWF_745x
+ sync
+ mtspr SPRN_L2CR,r0 /* set the hardware flush bit */
+3: mfspr r0,SPRN_L2CR /* wait for it to go to 0 */
+ andi. r0,r0,L2CR_L2HWF_745x
+ bne 3b
+ sync
+ rlwinm r3,r3,0,~L2CR_L2E
+ b 2f
+ /* When disabling L2, code must be in L1 */
+ .balign 32
+1: mtspr SPRN_L2CR,r3 /* disable the L2 cache */
+3: sync
+ isync
+ b 1f
+2: b 3f
+3: sync
+ isync
+ b 1b
+1: sync
+ isync
+ oris r4,r3,L2CR_L2I@h
+ mtspr SPRN_L2CR,r4
+ sync
+ isync
+1: mfspr r4,SPRN_L2CR
+ andis. r0,r4,L2CR_L2I@h
+ bne 1b
+ sync
+
+BEGIN_FTR_SECTION
+ /* Flush the L3 cache using the hardware assist */
+4: mfspr r3,SPRN_L3CR
+ cmpwi r3,0 /* check if it is enabled */
+ bge 6f
+ oris r0,r3,L3CR_L3IO@h
+ ori r0,r0,L3CR_L3DO
+ sync
+ mtspr SPRN_L3CR,r0 /* lock the L3 cache */
+ sync
+ isync
+ ori r0,r0,L3CR_L3HWF
+ sync
+ mtspr SPRN_L3CR,r0 /* set the hardware flush bit */
+5: mfspr r0,SPRN_L3CR /* wait for it to go to zero */
+ andi. r0,r0,L3CR_L3HWF
+ bne 5b
+ rlwinm r3,r3,0,~L3CR_L3E
+ sync
+ mtspr SPRN_L3CR,r3 /* disable the L3 cache */
+ sync
+ ori r4,r3,L3CR_L3I
+ mtspr SPRN_L3CR,r4
+1: mfspr r4,SPRN_L3CR
+ andi. r0,r4,L3CR_L3I
+ bne 1b
+ sync
+END_FTR_SECTION_IFSET(CPU_FTR_L3CR)
+
+6: mfspr r0,SPRN_HID0 /* now disable the L1 data cache */
+ rlwinm r0,r0,0,~HID0_DCE
+ mtspr SPRN_HID0,r0
+ sync
+ isync
+ mtmsr r11 /* restore DR and EE */
+ isync
+ blr
+#endif /* CONFIG_6xx */
diff --git a/arch/powerpc/platforms/powermac/cpufreq.c b/arch/powerpc/platforms/powermac/cpufreq.c
new file mode 100644
index 000000000000..c47f8b69725c
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/cpufreq.c
@@ -0,0 +1,726 @@
+/*
+ * arch/ppc/platforms/pmac_cpufreq.c
+ *
+ * Copyright (C) 2002 - 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ * Copyright (C) 2004 John Steele Scott <toojays@toojays.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * TODO: Need a big cleanup here. Basically, we need to have different
+ * cpufreq_driver structures for the different type of HW instead of the
+ * current mess. We also need to better deal with the detection of the
+ * type of machine.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/adb.h>
+#include <linux/pmu.h>
+#include <linux/slab.h>
+#include <linux/cpufreq.h>
+#include <linux/init.h>
+#include <linux/sysdev.h>
+#include <linux/i2c.h>
+#include <linux/hardirq.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/irq.h>
+#include <asm/pmac_feature.h>
+#include <asm/mmu_context.h>
+#include <asm/sections.h>
+#include <asm/cputable.h>
+#include <asm/time.h>
+#include <asm/system.h>
+#include <asm/mpic.h>
+#include <asm/keylargo.h>
+
+/* WARNING !!! This will cause calibrate_delay() to be called,
+ * but this is an __init function ! So you MUST go edit
+ * init/main.c to make it non-init before enabling DEBUG_FREQ
+ */
+#undef DEBUG_FREQ
+
+/*
+ * There is a problem with the core cpufreq code on SMP kernels,
+ * it won't recalculate the Bogomips properly
+ */
+#ifdef CONFIG_SMP
+#warning "WARNING, CPUFREQ not recommended on SMP kernels"
+#endif
+
+extern void low_choose_7447a_dfs(int dfs);
+extern void low_choose_750fx_pll(int pll);
+extern void low_sleep_handler(void);
+
+/*
+ * Currently, PowerMac cpufreq supports only high & low frequencies
+ * that are set by the firmware
+ */
+static unsigned int low_freq;
+static unsigned int hi_freq;
+static unsigned int cur_freq;
+static unsigned int sleep_freq;
+
+/*
+ * Different models uses different mecanisms to switch the frequency
+ */
+static int (*set_speed_proc)(int low_speed);
+static unsigned int (*get_speed_proc)(void);
+
+/*
+ * Some definitions used by the various speedprocs
+ */
+static u32 voltage_gpio;
+static u32 frequency_gpio;
+static u32 slew_done_gpio;
+static int no_schedule;
+static int has_cpu_l2lve;
+static int is_pmu_based;
+
+/* There are only two frequency states for each processor. Values
+ * are in kHz for the time being.
+ */
+#define CPUFREQ_HIGH 0
+#define CPUFREQ_LOW 1
+
+static struct cpufreq_frequency_table pmac_cpu_freqs[] = {
+ {CPUFREQ_HIGH, 0},
+ {CPUFREQ_LOW, 0},
+ {0, CPUFREQ_TABLE_END},
+};
+
+static struct freq_attr* pmac_cpu_freqs_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+
+static inline void local_delay(unsigned long ms)
+{
+ if (no_schedule)
+ mdelay(ms);
+ else
+ msleep(ms);
+}
+
+#ifdef DEBUG_FREQ
+static inline void debug_calc_bogomips(void)
+{
+ /* This will cause a recalc of bogomips and display the
+ * result. We backup/restore the value to avoid affecting the
+ * core cpufreq framework's own calculation.
+ */
+ extern void calibrate_delay(void);
+
+ unsigned long save_lpj = loops_per_jiffy;
+ calibrate_delay();
+ loops_per_jiffy = save_lpj;
+}
+#endif /* DEBUG_FREQ */
+
+/* Switch CPU speed under 750FX CPU control
+ */
+static int cpu_750fx_cpu_speed(int low_speed)
+{
+ u32 hid2;
+
+ if (low_speed == 0) {
+ /* ramping up, set voltage first */
+ pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
+ /* Make sure we sleep for at least 1ms */
+ local_delay(10);
+
+ /* tweak L2 for high voltage */
+ if (has_cpu_l2lve) {
+ hid2 = mfspr(SPRN_HID2);
+ hid2 &= ~0x2000;
+ mtspr(SPRN_HID2, hid2);
+ }
+ }
+#ifdef CONFIG_6xx
+ low_choose_750fx_pll(low_speed);
+#endif
+ if (low_speed == 1) {
+ /* tweak L2 for low voltage */
+ if (has_cpu_l2lve) {
+ hid2 = mfspr(SPRN_HID2);
+ hid2 |= 0x2000;
+ mtspr(SPRN_HID2, hid2);
+ }
+
+ /* ramping down, set voltage last */
+ pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
+ local_delay(10);
+ }
+
+ return 0;
+}
+
+static unsigned int cpu_750fx_get_cpu_speed(void)
+{
+ if (mfspr(SPRN_HID1) & HID1_PS)
+ return low_freq;
+ else
+ return hi_freq;
+}
+
+/* Switch CPU speed using DFS */
+static int dfs_set_cpu_speed(int low_speed)
+{
+ if (low_speed == 0) {
+ /* ramping up, set voltage first */
+ pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
+ /* Make sure we sleep for at least 1ms */
+ local_delay(1);
+ }
+
+ /* set frequency */
+#ifdef CONFIG_6xx
+ low_choose_7447a_dfs(low_speed);
+#endif
+ udelay(100);
+
+ if (low_speed == 1) {
+ /* ramping down, set voltage last */
+ pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
+ local_delay(1);
+ }
+
+ return 0;
+}
+
+static unsigned int dfs_get_cpu_speed(void)
+{
+ if (mfspr(SPRN_HID1) & HID1_DFS)
+ return low_freq;
+ else
+ return hi_freq;
+}
+
+
+/* Switch CPU speed using slewing GPIOs
+ */
+static int gpios_set_cpu_speed(int low_speed)
+{
+ int gpio, timeout = 0;
+
+ /* If ramping up, set voltage first */
+ if (low_speed == 0) {
+ pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
+ /* Delay is way too big but it's ok, we schedule */
+ local_delay(10);
+ }
+
+ /* Set frequency */
+ gpio = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0);
+ if (low_speed == ((gpio & 0x01) == 0))
+ goto skip;
+
+ pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, frequency_gpio,
+ low_speed ? 0x04 : 0x05);
+ udelay(200);
+ do {
+ if (++timeout > 100)
+ break;
+ local_delay(1);
+ gpio = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, slew_done_gpio, 0);
+ } while((gpio & 0x02) == 0);
+ skip:
+ /* If ramping down, set voltage last */
+ if (low_speed == 1) {
+ pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
+ /* Delay is way too big but it's ok, we schedule */
+ local_delay(10);
+ }
+
+#ifdef DEBUG_FREQ
+ debug_calc_bogomips();
+#endif
+
+ return 0;
+}
+
+/* Switch CPU speed under PMU control
+ */
+static int pmu_set_cpu_speed(int low_speed)
+{
+ struct adb_request req;
+ unsigned long save_l2cr;
+ unsigned long save_l3cr;
+ unsigned int pic_prio;
+ unsigned long flags;
+
+ preempt_disable();
+
+#ifdef DEBUG_FREQ
+ printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1));
+#endif
+ pmu_suspend();
+
+ /* Disable all interrupt sources on openpic */
+ pic_prio = mpic_cpu_get_priority();
+ mpic_cpu_set_priority(0xf);
+
+ /* Make sure the decrementer won't interrupt us */
+ asm volatile("mtdec %0" : : "r" (0x7fffffff));
+ /* Make sure any pending DEC interrupt occuring while we did
+ * the above didn't re-enable the DEC */
+ mb();
+ asm volatile("mtdec %0" : : "r" (0x7fffffff));
+
+ /* We can now disable MSR_EE */
+ local_irq_save(flags);
+
+ /* Giveup the FPU & vec */
+ enable_kernel_fp();
+
+#ifdef CONFIG_ALTIVEC
+ if (cpu_has_feature(CPU_FTR_ALTIVEC))
+ enable_kernel_altivec();
+#endif /* CONFIG_ALTIVEC */
+
+ /* Save & disable L2 and L3 caches */
+ save_l3cr = _get_L3CR(); /* (returns -1 if not available) */
+ save_l2cr = _get_L2CR(); /* (returns -1 if not available) */
+
+ /* Send the new speed command. My assumption is that this command
+ * will cause PLL_CFG[0..3] to be changed next time CPU goes to sleep
+ */
+ pmu_request(&req, NULL, 6, PMU_CPU_SPEED, 'W', 'O', 'O', 'F', low_speed);
+ while (!req.complete)
+ pmu_poll();
+
+ /* Prepare the northbridge for the speed transition */
+ pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,1);
+
+ /* Call low level code to backup CPU state and recover from
+ * hardware reset
+ */
+ low_sleep_handler();
+
+ /* Restore the northbridge */
+ pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,0);
+
+ /* Restore L2 cache */
+ if (save_l2cr != 0xffffffff && (save_l2cr & L2CR_L2E) != 0)
+ _set_L2CR(save_l2cr);
+ /* Restore L3 cache */
+ if (save_l3cr != 0xffffffff && (save_l3cr & L3CR_L3E) != 0)
+ _set_L3CR(save_l3cr);
+
+ /* Restore userland MMU context */
+ set_context(current->active_mm->context, current->active_mm->pgd);
+
+#ifdef DEBUG_FREQ
+ printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1));
+#endif
+
+ /* Restore low level PMU operations */
+ pmu_unlock();
+
+ /* Restore decrementer */
+ wakeup_decrementer();
+
+ /* Restore interrupts */
+ mpic_cpu_set_priority(pic_prio);
+
+ /* Let interrupts flow again ... */
+ local_irq_restore(flags);
+
+#ifdef DEBUG_FREQ
+ debug_calc_bogomips();
+#endif
+
+ pmu_resume();
+
+ preempt_enable();
+
+ return 0;
+}
+
+static int do_set_cpu_speed(int speed_mode, int notify)
+{
+ struct cpufreq_freqs freqs;
+ unsigned long l3cr;
+ static unsigned long prev_l3cr;
+
+ freqs.old = cur_freq;
+ freqs.new = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
+ freqs.cpu = smp_processor_id();
+
+ if (freqs.old == freqs.new)
+ return 0;
+
+ if (notify)
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ if (speed_mode == CPUFREQ_LOW &&
+ cpu_has_feature(CPU_FTR_L3CR)) {
+ l3cr = _get_L3CR();
+ if (l3cr & L3CR_L3E) {
+ prev_l3cr = l3cr;
+ _set_L3CR(0);
+ }
+ }
+ set_speed_proc(speed_mode == CPUFREQ_LOW);
+ if (speed_mode == CPUFREQ_HIGH &&
+ cpu_has_feature(CPU_FTR_L3CR)) {
+ l3cr = _get_L3CR();
+ if ((prev_l3cr & L3CR_L3E) && l3cr != prev_l3cr)
+ _set_L3CR(prev_l3cr);
+ }
+ if (notify)
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ cur_freq = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
+
+ return 0;
+}
+
+static unsigned int pmac_cpufreq_get_speed(unsigned int cpu)
+{
+ return cur_freq;
+}
+
+static int pmac_cpufreq_verify(struct cpufreq_policy *policy)
+{
+ return cpufreq_frequency_table_verify(policy, pmac_cpu_freqs);
+}
+
+static int pmac_cpufreq_target( struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ unsigned int newstate = 0;
+
+ if (cpufreq_frequency_table_target(policy, pmac_cpu_freqs,
+ target_freq, relation, &newstate))
+ return -EINVAL;
+
+ return do_set_cpu_speed(newstate, 1);
+}
+
+unsigned int pmac_get_one_cpufreq(int i)
+{
+ /* Supports only one CPU for now */
+ return (i == 0) ? cur_freq : 0;
+}
+
+static int pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
+{
+ if (policy->cpu != 0)
+ return -ENODEV;
+
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+ policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+ policy->cur = cur_freq;
+
+ cpufreq_frequency_table_get_attr(pmac_cpu_freqs, policy->cpu);
+ return cpufreq_frequency_table_cpuinfo(policy, pmac_cpu_freqs);
+}
+
+static u32 read_gpio(struct device_node *np)
+{
+ u32 *reg = (u32 *)get_property(np, "reg", NULL);
+ u32 offset;
+
+ if (reg == NULL)
+ return 0;
+ /* That works for all keylargos but shall be fixed properly
+ * some day... The problem is that it seems we can't rely
+ * on the "reg" property of the GPIO nodes, they are either
+ * relative to the base of KeyLargo or to the base of the
+ * GPIO space, and the device-tree doesn't help.
+ */
+ offset = *reg;
+ if (offset < KEYLARGO_GPIO_LEVELS0)
+ offset += KEYLARGO_GPIO_LEVELS0;
+ return offset;
+}
+
+static int pmac_cpufreq_suspend(struct cpufreq_policy *policy, pm_message_t pmsg)
+{
+ /* Ok, this could be made a bit smarter, but let's be robust for now. We
+ * always force a speed change to high speed before sleep, to make sure
+ * we have appropriate voltage and/or bus speed for the wakeup process,
+ * and to make sure our loops_per_jiffies are "good enough", that is will
+ * not cause too short delays if we sleep in low speed and wake in high
+ * speed..
+ */
+ no_schedule = 1;
+ sleep_freq = cur_freq;
+ if (cur_freq == low_freq && !is_pmu_based)
+ do_set_cpu_speed(CPUFREQ_HIGH, 0);
+ return 0;
+}
+
+static int pmac_cpufreq_resume(struct cpufreq_policy *policy)
+{
+ /* If we resume, first check if we have a get() function */
+ if (get_speed_proc)
+ cur_freq = get_speed_proc();
+ else
+ cur_freq = 0;
+
+ /* We don't, hrm... we don't really know our speed here, best
+ * is that we force a switch to whatever it was, which is
+ * probably high speed due to our suspend() routine
+ */
+ do_set_cpu_speed(sleep_freq == low_freq ?
+ CPUFREQ_LOW : CPUFREQ_HIGH, 0);
+
+ no_schedule = 0;
+ return 0;
+}
+
+static struct cpufreq_driver pmac_cpufreq_driver = {
+ .verify = pmac_cpufreq_verify,
+ .target = pmac_cpufreq_target,
+ .get = pmac_cpufreq_get_speed,
+ .init = pmac_cpufreq_cpu_init,
+ .suspend = pmac_cpufreq_suspend,
+ .resume = pmac_cpufreq_resume,
+ .flags = CPUFREQ_PM_NO_WARN,
+ .attr = pmac_cpu_freqs_attr,
+ .name = "powermac",
+ .owner = THIS_MODULE,
+};
+
+
+static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
+{
+ struct device_node *volt_gpio_np = of_find_node_by_name(NULL,
+ "voltage-gpio");
+ struct device_node *freq_gpio_np = of_find_node_by_name(NULL,
+ "frequency-gpio");
+ struct device_node *slew_done_gpio_np = of_find_node_by_name(NULL,
+ "slewing-done");
+ u32 *value;
+
+ /*
+ * Check to see if it's GPIO driven or PMU only
+ *
+ * The way we extract the GPIO address is slightly hackish, but it
+ * works well enough for now. We need to abstract the whole GPIO
+ * stuff sooner or later anyway
+ */
+
+ if (volt_gpio_np)
+ voltage_gpio = read_gpio(volt_gpio_np);
+ if (freq_gpio_np)
+ frequency_gpio = read_gpio(freq_gpio_np);
+ if (slew_done_gpio_np)
+ slew_done_gpio = read_gpio(slew_done_gpio_np);
+
+ /* If we use the frequency GPIOs, calculate the min/max speeds based
+ * on the bus frequencies
+ */
+ if (frequency_gpio && slew_done_gpio) {
+ int lenp, rc;
+ u32 *freqs, *ratio;
+
+ freqs = (u32 *)get_property(cpunode, "bus-frequencies", &lenp);
+ lenp /= sizeof(u32);
+ if (freqs == NULL || lenp != 2) {
+ printk(KERN_ERR "cpufreq: bus-frequencies incorrect or missing\n");
+ return 1;
+ }
+ ratio = (u32 *)get_property(cpunode, "processor-to-bus-ratio*2", NULL);
+ if (ratio == NULL) {
+ printk(KERN_ERR "cpufreq: processor-to-bus-ratio*2 missing\n");
+ return 1;
+ }
+
+ /* Get the min/max bus frequencies */
+ low_freq = min(freqs[0], freqs[1]);
+ hi_freq = max(freqs[0], freqs[1]);
+
+ /* Grrrr.. It _seems_ that the device-tree is lying on the low bus
+ * frequency, it claims it to be around 84Mhz on some models while
+ * it appears to be approx. 101Mhz on all. Let's hack around here...
+ * fortunately, we don't need to be too precise
+ */
+ if (low_freq < 98000000)
+ low_freq = 101000000;
+
+ /* Convert those to CPU core clocks */
+ low_freq = (low_freq * (*ratio)) / 2000;
+ hi_freq = (hi_freq * (*ratio)) / 2000;
+
+ /* Now we get the frequencies, we read the GPIO to see what is out current
+ * speed
+ */
+ rc = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0);
+ cur_freq = (rc & 0x01) ? hi_freq : low_freq;
+
+ set_speed_proc = gpios_set_cpu_speed;
+ return 1;
+ }
+
+ /* If we use the PMU, look for the min & max frequencies in the
+ * device-tree
+ */
+ value = (u32 *)get_property(cpunode, "min-clock-frequency", NULL);
+ if (!value)
+ return 1;
+ low_freq = (*value) / 1000;
+ /* The PowerBook G4 12" (PowerBook6,1) has an error in the device-tree
+ * here */
+ if (low_freq < 100000)
+ low_freq *= 10;
+
+ value = (u32 *)get_property(cpunode, "max-clock-frequency", NULL);
+ if (!value)
+ return 1;
+ hi_freq = (*value) / 1000;
+ set_speed_proc = pmu_set_cpu_speed;
+ is_pmu_based = 1;
+
+ return 0;
+}
+
+static int pmac_cpufreq_init_7447A(struct device_node *cpunode)
+{
+ struct device_node *volt_gpio_np;
+
+ if (get_property(cpunode, "dynamic-power-step", NULL) == NULL)
+ return 1;
+
+ volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");
+ if (volt_gpio_np)
+ voltage_gpio = read_gpio(volt_gpio_np);
+ if (!voltage_gpio){
+ printk(KERN_ERR "cpufreq: missing cpu-vcore-select gpio\n");
+ return 1;
+ }
+
+ /* OF only reports the high frequency */
+ hi_freq = cur_freq;
+ low_freq = cur_freq/2;
+
+ /* Read actual frequency from CPU */
+ cur_freq = dfs_get_cpu_speed();
+ set_speed_proc = dfs_set_cpu_speed;
+ get_speed_proc = dfs_get_cpu_speed;
+
+ return 0;
+}
+
+static int pmac_cpufreq_init_750FX(struct device_node *cpunode)
+{
+ struct device_node *volt_gpio_np;
+ u32 pvr, *value;
+
+ if (get_property(cpunode, "dynamic-power-step", NULL) == NULL)
+ return 1;
+
+ hi_freq = cur_freq;
+ value = (u32 *)get_property(cpunode, "reduced-clock-frequency", NULL);
+ if (!value)
+ return 1;
+ low_freq = (*value) / 1000;
+
+ volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");
+ if (volt_gpio_np)
+ voltage_gpio = read_gpio(volt_gpio_np);
+
+ pvr = mfspr(SPRN_PVR);
+ has_cpu_l2lve = !((pvr & 0xf00) == 0x100);
+
+ set_speed_proc = cpu_750fx_cpu_speed;
+ get_speed_proc = cpu_750fx_get_cpu_speed;
+ cur_freq = cpu_750fx_get_cpu_speed();
+
+ return 0;
+}
+
+/* Currently, we support the following machines:
+ *
+ * - Titanium PowerBook 1Ghz (PMU based, 667Mhz & 1Ghz)
+ * - Titanium PowerBook 800 (PMU based, 667Mhz & 800Mhz)
+ * - Titanium PowerBook 400 (PMU based, 300Mhz & 400Mhz)
+ * - Titanium PowerBook 500 (PMU based, 300Mhz & 500Mhz)
+ * - iBook2 500/600 (PMU based, 400Mhz & 500/600Mhz)
+ * - iBook2 700 (CPU based, 400Mhz & 700Mhz, support low voltage)
+ * - Recent MacRISC3 laptops
+ * - All new machines with 7447A CPUs
+ */
+static int __init pmac_cpufreq_setup(void)
+{
+ struct device_node *cpunode;
+ u32 *value;
+
+ if (strstr(cmd_line, "nocpufreq"))
+ return 0;
+
+ /* Assume only one CPU */
+ cpunode = find_type_devices("cpu");
+ if (!cpunode)
+ goto out;
+
+ /* Get current cpu clock freq */
+ value = (u32 *)get_property(cpunode, "clock-frequency", NULL);
+ if (!value)
+ goto out;
+ cur_freq = (*value) / 1000;
+
+ /* Check for 7447A based MacRISC3 */
+ if (machine_is_compatible("MacRISC3") &&
+ get_property(cpunode, "dynamic-power-step", NULL) &&
+ PVR_VER(mfspr(SPRN_PVR)) == 0x8003) {
+ pmac_cpufreq_init_7447A(cpunode);
+ /* Check for other MacRISC3 machines */
+ } else if (machine_is_compatible("PowerBook3,4") ||
+ machine_is_compatible("PowerBook3,5") ||
+ machine_is_compatible("MacRISC3")) {
+ pmac_cpufreq_init_MacRISC3(cpunode);
+ /* Else check for iBook2 500/600 */
+ } else if (machine_is_compatible("PowerBook4,1")) {
+ hi_freq = cur_freq;
+ low_freq = 400000;
+ set_speed_proc = pmu_set_cpu_speed;
+ is_pmu_based = 1;
+ }
+ /* Else check for TiPb 550 */
+ else if (machine_is_compatible("PowerBook3,3") && cur_freq == 550000) {
+ hi_freq = cur_freq;
+ low_freq = 500000;
+ set_speed_proc = pmu_set_cpu_speed;
+ is_pmu_based = 1;
+ }
+ /* Else check for TiPb 400 & 500 */
+ else if (machine_is_compatible("PowerBook3,2")) {
+ /* We only know about the 400 MHz and the 500Mhz model
+ * they both have 300 MHz as low frequency
+ */
+ if (cur_freq < 350000 || cur_freq > 550000)
+ goto out;
+ hi_freq = cur_freq;
+ low_freq = 300000;
+ set_speed_proc = pmu_set_cpu_speed;
+ is_pmu_based = 1;
+ }
+ /* Else check for 750FX */
+ else if (PVR_VER(mfspr(SPRN_PVR)) == 0x7000)
+ pmac_cpufreq_init_750FX(cpunode);
+out:
+ if (set_speed_proc == NULL)
+ return -ENODEV;
+
+ pmac_cpu_freqs[CPUFREQ_LOW].frequency = low_freq;
+ pmac_cpu_freqs[CPUFREQ_HIGH].frequency = hi_freq;
+
+ printk(KERN_INFO "Registering PowerMac CPU frequency driver\n");
+ printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Boot: %d Mhz\n",
+ low_freq/1000, hi_freq/1000, cur_freq/1000);
+
+ return cpufreq_register_driver(&pmac_cpufreq_driver);
+}
+
+module_init(pmac_cpufreq_setup);
+
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c
new file mode 100644
index 000000000000..10f1d942c661
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/feature.c
@@ -0,0 +1,3063 @@
+/*
+ * arch/ppc/platforms/pmac_feature.c
+ *
+ * Copyright (C) 1996-2001 Paul Mackerras (paulus@cs.anu.edu.au)
+ * Ben. Herrenschmidt (benh@kernel.crashing.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.
+ *
+ * TODO:
+ *
+ * - Replace mdelay with some schedule loop if possible
+ * - Shorten some obfuscated delays on some routines (like modem
+ * power)
+ * - Refcount some clocks (see darwin)
+ * - Split split split...
+ *
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/adb.h>
+#include <linux/pmu.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <asm/sections.h>
+#include <asm/errno.h>
+#include <asm/ohare.h>
+#include <asm/heathrow.h>
+#include <asm/keylargo.h>
+#include <asm/uninorth.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/pmac_feature.h>
+#include <asm/dbdma.h>
+#include <asm/pci-bridge.h>
+#include <asm/pmac_low_i2c.h>
+
+#undef DEBUG_FEATURE
+
+#ifdef DEBUG_FEATURE
+#define DBG(fmt...) printk(KERN_DEBUG fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+#ifdef CONFIG_6xx
+extern int powersave_lowspeed;
+#endif
+
+extern int powersave_nap;
+extern struct device_node *k2_skiplist[2];
+
+
+/*
+ * We use a single global lock to protect accesses. Each driver has
+ * to take care of its own locking
+ */
+static DEFINE_SPINLOCK(feature_lock);
+
+#define LOCK(flags) spin_lock_irqsave(&feature_lock, flags);
+#define UNLOCK(flags) spin_unlock_irqrestore(&feature_lock, flags);
+
+
+/*
+ * Instance of some macio stuffs
+ */
+struct macio_chip macio_chips[MAX_MACIO_CHIPS];
+
+struct macio_chip *macio_find(struct device_node *child, int type)
+{
+ while(child) {
+ int i;
+
+ for (i=0; i < MAX_MACIO_CHIPS && macio_chips[i].of_node; i++)
+ if (child == macio_chips[i].of_node &&
+ (!type || macio_chips[i].type == type))
+ return &macio_chips[i];
+ child = child->parent;
+ }
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(macio_find);
+
+static const char *macio_names[] =
+{
+ "Unknown",
+ "Grand Central",
+ "OHare",
+ "OHareII",
+ "Heathrow",
+ "Gatwick",
+ "Paddington",
+ "Keylargo",
+ "Pangea",
+ "Intrepid",
+ "K2"
+};
+
+
+
+/*
+ * Uninorth reg. access. Note that Uni-N regs are big endian
+ */
+
+#define UN_REG(r) (uninorth_base + ((r) >> 2))
+#define UN_IN(r) (in_be32(UN_REG(r)))
+#define UN_OUT(r,v) (out_be32(UN_REG(r), (v)))
+#define UN_BIS(r,v) (UN_OUT((r), UN_IN(r) | (v)))
+#define UN_BIC(r,v) (UN_OUT((r), UN_IN(r) & ~(v)))
+
+static struct device_node *uninorth_node;
+static u32 __iomem *uninorth_base;
+static u32 uninorth_rev;
+static int uninorth_u3;
+static void __iomem *u3_ht;
+
+/*
+ * For each motherboard family, we have a table of functions pointers
+ * that handle the various features.
+ */
+
+typedef long (*feature_call)(struct device_node *node, long param, long value);
+
+struct feature_table_entry {
+ unsigned int selector;
+ feature_call function;
+};
+
+struct pmac_mb_def
+{
+ const char* model_string;
+ const char* model_name;
+ int model_id;
+ struct feature_table_entry* features;
+ unsigned long board_flags;
+};
+static struct pmac_mb_def pmac_mb;
+
+/*
+ * Here are the chip specific feature functions
+ */
+
+static inline int simple_feature_tweak(struct device_node *node, int type,
+ int reg, u32 mask, int value)
+{
+ struct macio_chip* macio;
+ unsigned long flags;
+
+ macio = macio_find(node, type);
+ if (!macio)
+ return -ENODEV;
+ LOCK(flags);
+ if (value)
+ MACIO_BIS(reg, mask);
+ else
+ MACIO_BIC(reg, mask);
+ (void)MACIO_IN32(reg);
+ UNLOCK(flags);
+
+ return 0;
+}
+
+#ifndef CONFIG_POWER4
+
+static long ohare_htw_scc_enable(struct device_node *node, long param,
+ long value)
+{
+ struct macio_chip* macio;
+ unsigned long chan_mask;
+ unsigned long fcr;
+ unsigned long flags;
+ int htw, trans;
+ unsigned long rmask;
+
+ macio = macio_find(node, 0);
+ if (!macio)
+ return -ENODEV;
+ if (!strcmp(node->name, "ch-a"))
+ chan_mask = MACIO_FLAG_SCCA_ON;
+ else if (!strcmp(node->name, "ch-b"))
+ chan_mask = MACIO_FLAG_SCCB_ON;
+ else
+ return -ENODEV;
+
+ htw = (macio->type == macio_heathrow || macio->type == macio_paddington
+ || macio->type == macio_gatwick);
+ /* On these machines, the HRW_SCC_TRANS_EN_N bit mustn't be touched */
+ trans = (pmac_mb.model_id != PMAC_TYPE_YOSEMITE &&
+ pmac_mb.model_id != PMAC_TYPE_YIKES);
+ if (value) {
+#ifdef CONFIG_ADB_PMU
+ if ((param & 0xfff) == PMAC_SCC_IRDA)
+ pmu_enable_irled(1);
+#endif /* CONFIG_ADB_PMU */
+ LOCK(flags);
+ fcr = MACIO_IN32(OHARE_FCR);
+ /* Check if scc cell need enabling */
+ if (!(fcr & OH_SCC_ENABLE)) {
+ fcr |= OH_SCC_ENABLE;
+ if (htw) {
+ /* Side effect: this will also power up the
+ * modem, but it's too messy to figure out on which
+ * ports this controls the tranceiver and on which
+ * it controls the modem
+ */
+ if (trans)
+ fcr &= ~HRW_SCC_TRANS_EN_N;
+ MACIO_OUT32(OHARE_FCR, fcr);
+ fcr |= (rmask = HRW_RESET_SCC);
+ MACIO_OUT32(OHARE_FCR, fcr);
+ } else {
+ fcr |= (rmask = OH_SCC_RESET);
+ MACIO_OUT32(OHARE_FCR, fcr);
+ }
+ UNLOCK(flags);
+ (void)MACIO_IN32(OHARE_FCR);
+ mdelay(15);
+ LOCK(flags);
+ fcr &= ~rmask;
+ MACIO_OUT32(OHARE_FCR, fcr);
+ }
+ if (chan_mask & MACIO_FLAG_SCCA_ON)
+ fcr |= OH_SCCA_IO;
+ if (chan_mask & MACIO_FLAG_SCCB_ON)
+ fcr |= OH_SCCB_IO;
+ MACIO_OUT32(OHARE_FCR, fcr);
+ macio->flags |= chan_mask;
+ UNLOCK(flags);
+ if (param & PMAC_SCC_FLAG_XMON)
+ macio->flags |= MACIO_FLAG_SCC_LOCKED;
+ } else {
+ if (macio->flags & MACIO_FLAG_SCC_LOCKED)
+ return -EPERM;
+ LOCK(flags);
+ fcr = MACIO_IN32(OHARE_FCR);
+ if (chan_mask & MACIO_FLAG_SCCA_ON)
+ fcr &= ~OH_SCCA_IO;
+ if (chan_mask & MACIO_FLAG_SCCB_ON)
+ fcr &= ~OH_SCCB_IO;
+ MACIO_OUT32(OHARE_FCR, fcr);
+ if ((fcr & (OH_SCCA_IO | OH_SCCB_IO)) == 0) {
+ fcr &= ~OH_SCC_ENABLE;
+ if (htw && trans)
+ fcr |= HRW_SCC_TRANS_EN_N;
+ MACIO_OUT32(OHARE_FCR, fcr);
+ }
+ macio->flags &= ~(chan_mask);
+ UNLOCK(flags);
+ mdelay(10);
+#ifdef CONFIG_ADB_PMU
+ if ((param & 0xfff) == PMAC_SCC_IRDA)
+ pmu_enable_irled(0);
+#endif /* CONFIG_ADB_PMU */
+ }
+ return 0;
+}
+
+static long ohare_floppy_enable(struct device_node *node, long param,
+ long value)
+{
+ return simple_feature_tweak(node, macio_ohare,
+ OHARE_FCR, OH_FLOPPY_ENABLE, value);
+}
+
+static long ohare_mesh_enable(struct device_node *node, long param, long value)
+{
+ return simple_feature_tweak(node, macio_ohare,
+ OHARE_FCR, OH_MESH_ENABLE, value);
+}
+
+static long ohare_ide_enable(struct device_node *node, long param, long value)
+{
+ switch(param) {
+ case 0:
+ /* For some reason, setting the bit in set_initial_features()
+ * doesn't stick. I'm still investigating... --BenH.
+ */
+ if (value)
+ simple_feature_tweak(node, macio_ohare,
+ OHARE_FCR, OH_IOBUS_ENABLE, 1);
+ return simple_feature_tweak(node, macio_ohare,
+ OHARE_FCR, OH_IDE0_ENABLE, value);
+ case 1:
+ return simple_feature_tweak(node, macio_ohare,
+ OHARE_FCR, OH_BAY_IDE_ENABLE, value);
+ default:
+ return -ENODEV;
+ }
+}
+
+static long ohare_ide_reset(struct device_node *node, long param, long value)
+{
+ switch(param) {
+ case 0:
+ return simple_feature_tweak(node, macio_ohare,
+ OHARE_FCR, OH_IDE0_RESET_N, !value);
+ case 1:
+ return simple_feature_tweak(node, macio_ohare,
+ OHARE_FCR, OH_IDE1_RESET_N, !value);
+ default:
+ return -ENODEV;
+ }
+}
+
+static long ohare_sleep_state(struct device_node *node, long param, long value)
+{
+ struct macio_chip* macio = &macio_chips[0];
+
+ if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
+ return -EPERM;
+ if (value == 1) {
+ MACIO_BIC(OHARE_FCR, OH_IOBUS_ENABLE);
+ } else if (value == 0) {
+ MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE);
+ }
+
+ return 0;
+}
+
+static long heathrow_modem_enable(struct device_node *node, long param,
+ long value)
+{
+ struct macio_chip* macio;
+ u8 gpio;
+ unsigned long flags;
+
+ macio = macio_find(node, macio_unknown);
+ if (!macio)
+ return -ENODEV;
+ gpio = MACIO_IN8(HRW_GPIO_MODEM_RESET) & ~1;
+ if (!value) {
+ LOCK(flags);
+ MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio);
+ UNLOCK(flags);
+ (void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
+ mdelay(250);
+ }
+ if (pmac_mb.model_id != PMAC_TYPE_YOSEMITE &&
+ pmac_mb.model_id != PMAC_TYPE_YIKES) {
+ LOCK(flags);
+ if (value)
+ MACIO_BIC(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);
+ else
+ MACIO_BIS(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);
+ UNLOCK(flags);
+ (void)MACIO_IN32(HEATHROW_FCR);
+ mdelay(250);
+ }
+ if (value) {
+ LOCK(flags);
+ MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio | 1);
+ (void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
+ UNLOCK(flags); mdelay(250); LOCK(flags);
+ MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio);
+ (void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
+ UNLOCK(flags); mdelay(250); LOCK(flags);
+ MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio | 1);
+ (void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
+ UNLOCK(flags); mdelay(250);
+ }
+ return 0;
+}
+
+static long heathrow_floppy_enable(struct device_node *node, long param,
+ long value)
+{
+ return simple_feature_tweak(node, macio_unknown,
+ HEATHROW_FCR,
+ HRW_SWIM_ENABLE|HRW_BAY_FLOPPY_ENABLE,
+ value);
+}
+
+static long heathrow_mesh_enable(struct device_node *node, long param,
+ long value)
+{
+ struct macio_chip* macio;
+ unsigned long flags;
+
+ macio = macio_find(node, macio_unknown);
+ if (!macio)
+ return -ENODEV;
+ LOCK(flags);
+ /* Set clear mesh cell enable */
+ if (value)
+ MACIO_BIS(HEATHROW_FCR, HRW_MESH_ENABLE);
+ else
+ MACIO_BIC(HEATHROW_FCR, HRW_MESH_ENABLE);
+ (void)MACIO_IN32(HEATHROW_FCR);
+ udelay(10);
+ /* Set/Clear termination power */
+ if (value)
+ MACIO_BIC(HEATHROW_MBCR, 0x04000000);
+ else
+ MACIO_BIS(HEATHROW_MBCR, 0x04000000);
+ (void)MACIO_IN32(HEATHROW_MBCR);
+ udelay(10);
+ UNLOCK(flags);
+
+ return 0;
+}
+
+static long heathrow_ide_enable(struct device_node *node, long param,
+ long value)
+{
+ switch(param) {
+ case 0:
+ return simple_feature_tweak(node, macio_unknown,
+ HEATHROW_FCR, HRW_IDE0_ENABLE, value);
+ case 1:
+ return simple_feature_tweak(node, macio_unknown,
+ HEATHROW_FCR, HRW_BAY_IDE_ENABLE, value);
+ default:
+ return -ENODEV;
+ }
+}
+
+static long heathrow_ide_reset(struct device_node *node, long param,
+ long value)
+{
+ switch(param) {
+ case 0:
+ return simple_feature_tweak(node, macio_unknown,
+ HEATHROW_FCR, HRW_IDE0_RESET_N, !value);
+ case 1:
+ return simple_feature_tweak(node, macio_unknown,
+ HEATHROW_FCR, HRW_IDE1_RESET_N, !value);
+ default:
+ return -ENODEV;
+ }
+}
+
+static long heathrow_bmac_enable(struct device_node *node, long param,
+ long value)
+{
+ struct macio_chip* macio;
+ unsigned long flags;
+
+ macio = macio_find(node, 0);
+ if (!macio)
+ return -ENODEV;
+ if (value) {
+ LOCK(flags);
+ MACIO_BIS(HEATHROW_FCR, HRW_BMAC_IO_ENABLE);
+ MACIO_BIS(HEATHROW_FCR, HRW_BMAC_RESET);
+ UNLOCK(flags);
+ (void)MACIO_IN32(HEATHROW_FCR);
+ mdelay(10);
+ LOCK(flags);
+ MACIO_BIC(HEATHROW_FCR, HRW_BMAC_RESET);
+ UNLOCK(flags);
+ (void)MACIO_IN32(HEATHROW_FCR);
+ mdelay(10);
+ } else {
+ LOCK(flags);
+ MACIO_BIC(HEATHROW_FCR, HRW_BMAC_IO_ENABLE);
+ UNLOCK(flags);
+ }
+ return 0;
+}
+
+static long heathrow_sound_enable(struct device_node *node, long param,
+ long value)
+{
+ struct macio_chip* macio;
+ unsigned long flags;
+
+ /* B&W G3 and Yikes don't support that properly (the
+ * sound appear to never come back after beeing shut down).
+ */
+ if (pmac_mb.model_id == PMAC_TYPE_YOSEMITE ||
+ pmac_mb.model_id == PMAC_TYPE_YIKES)
+ return 0;
+
+ macio = macio_find(node, 0);
+ if (!macio)
+ return -ENODEV;
+ if (value) {
+ LOCK(flags);
+ MACIO_BIS(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
+ MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N);
+ UNLOCK(flags);
+ (void)MACIO_IN32(HEATHROW_FCR);
+ } else {
+ LOCK(flags);
+ MACIO_BIS(HEATHROW_FCR, HRW_SOUND_POWER_N);
+ MACIO_BIC(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
+ UNLOCK(flags);
+ }
+ return 0;
+}
+
+static u32 save_fcr[6];
+static u32 save_mbcr;
+static u32 save_gpio_levels[2];
+static u8 save_gpio_extint[KEYLARGO_GPIO_EXTINT_CNT];
+static u8 save_gpio_normal[KEYLARGO_GPIO_CNT];
+static u32 save_unin_clock_ctl;
+static struct dbdma_regs save_dbdma[13];
+static struct dbdma_regs save_alt_dbdma[13];
+
+static void dbdma_save(struct macio_chip *macio, struct dbdma_regs *save)
+{
+ int i;
+
+ /* Save state & config of DBDMA channels */
+ for (i = 0; i < 13; i++) {
+ volatile struct dbdma_regs __iomem * chan = (void __iomem *)
+ (macio->base + ((0x8000+i*0x100)>>2));
+ save[i].cmdptr_hi = in_le32(&chan->cmdptr_hi);
+ save[i].cmdptr = in_le32(&chan->cmdptr);
+ save[i].intr_sel = in_le32(&chan->intr_sel);
+ save[i].br_sel = in_le32(&chan->br_sel);
+ save[i].wait_sel = in_le32(&chan->wait_sel);
+ }
+}
+
+static void dbdma_restore(struct macio_chip *macio, struct dbdma_regs *save)
+{
+ int i;
+
+ /* Save state & config of DBDMA channels */
+ for (i = 0; i < 13; i++) {
+ volatile struct dbdma_regs __iomem * chan = (void __iomem *)
+ (macio->base + ((0x8000+i*0x100)>>2));
+ out_le32(&chan->control, (ACTIVE|DEAD|WAKE|FLUSH|PAUSE|RUN)<<16);
+ while (in_le32(&chan->status) & ACTIVE)
+ mb();
+ out_le32(&chan->cmdptr_hi, save[i].cmdptr_hi);
+ out_le32(&chan->cmdptr, save[i].cmdptr);
+ out_le32(&chan->intr_sel, save[i].intr_sel);
+ out_le32(&chan->br_sel, save[i].br_sel);
+ out_le32(&chan->wait_sel, save[i].wait_sel);
+ }
+}
+
+static void heathrow_sleep(struct macio_chip *macio, int secondary)
+{
+ if (secondary) {
+ dbdma_save(macio, save_alt_dbdma);
+ save_fcr[2] = MACIO_IN32(0x38);
+ save_fcr[3] = MACIO_IN32(0x3c);
+ } else {
+ dbdma_save(macio, save_dbdma);
+ save_fcr[0] = MACIO_IN32(0x38);
+ save_fcr[1] = MACIO_IN32(0x3c);
+ save_mbcr = MACIO_IN32(0x34);
+ /* Make sure sound is shut down */
+ MACIO_BIS(HEATHROW_FCR, HRW_SOUND_POWER_N);
+ MACIO_BIC(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
+ /* This seems to be necessary as well or the fan
+ * keeps coming up and battery drains fast */
+ MACIO_BIC(HEATHROW_FCR, HRW_IOBUS_ENABLE);
+ MACIO_BIC(HEATHROW_FCR, HRW_IDE0_RESET_N);
+ /* Make sure eth is down even if module or sleep
+ * won't work properly */
+ MACIO_BIC(HEATHROW_FCR, HRW_BMAC_IO_ENABLE | HRW_BMAC_RESET);
+ }
+ /* Make sure modem is shut down */
+ MACIO_OUT8(HRW_GPIO_MODEM_RESET,
+ MACIO_IN8(HRW_GPIO_MODEM_RESET) & ~1);
+ MACIO_BIS(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);
+ MACIO_BIC(HEATHROW_FCR, OH_SCCA_IO|OH_SCCB_IO|HRW_SCC_ENABLE);
+
+ /* Let things settle */
+ (void)MACIO_IN32(HEATHROW_FCR);
+}
+
+static void heathrow_wakeup(struct macio_chip *macio, int secondary)
+{
+ if (secondary) {
+ MACIO_OUT32(0x38, save_fcr[2]);
+ (void)MACIO_IN32(0x38);
+ mdelay(1);
+ MACIO_OUT32(0x3c, save_fcr[3]);
+ (void)MACIO_IN32(0x38);
+ mdelay(10);
+ dbdma_restore(macio, save_alt_dbdma);
+ } else {
+ MACIO_OUT32(0x38, save_fcr[0] | HRW_IOBUS_ENABLE);
+ (void)MACIO_IN32(0x38);
+ mdelay(1);
+ MACIO_OUT32(0x3c, save_fcr[1]);
+ (void)MACIO_IN32(0x38);
+ mdelay(1);
+ MACIO_OUT32(0x34, save_mbcr);
+ (void)MACIO_IN32(0x38);
+ mdelay(10);
+ dbdma_restore(macio, save_dbdma);
+ }
+}
+
+static long heathrow_sleep_state(struct device_node *node, long param,
+ long value)
+{
+ if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
+ return -EPERM;
+ if (value == 1) {
+ if (macio_chips[1].type == macio_gatwick)
+ heathrow_sleep(&macio_chips[0], 1);
+ heathrow_sleep(&macio_chips[0], 0);
+ } else if (value == 0) {
+ heathrow_wakeup(&macio_chips[0], 0);
+ if (macio_chips[1].type == macio_gatwick)
+ heathrow_wakeup(&macio_chips[0], 1);
+ }
+ return 0;
+}
+
+static long core99_scc_enable(struct device_node *node, long param, long value)
+{
+ struct macio_chip* macio;
+ unsigned long flags;
+ unsigned long chan_mask;
+ u32 fcr;
+
+ macio = macio_find(node, 0);
+ if (!macio)
+ return -ENODEV;
+ if (!strcmp(node->name, "ch-a"))
+ chan_mask = MACIO_FLAG_SCCA_ON;
+ else if (!strcmp(node->name, "ch-b"))
+ chan_mask = MACIO_FLAG_SCCB_ON;
+ else
+ return -ENODEV;
+
+ if (value) {
+ int need_reset_scc = 0;
+ int need_reset_irda = 0;
+
+ LOCK(flags);
+ fcr = MACIO_IN32(KEYLARGO_FCR0);
+ /* Check if scc cell need enabling */
+ if (!(fcr & KL0_SCC_CELL_ENABLE)) {
+ fcr |= KL0_SCC_CELL_ENABLE;
+ need_reset_scc = 1;
+ }
+ if (chan_mask & MACIO_FLAG_SCCA_ON) {
+ fcr |= KL0_SCCA_ENABLE;
+ /* Don't enable line drivers for I2S modem */
+ if ((param & 0xfff) == PMAC_SCC_I2S1)
+ fcr &= ~KL0_SCC_A_INTF_ENABLE;
+ else
+ fcr |= KL0_SCC_A_INTF_ENABLE;
+ }
+ if (chan_mask & MACIO_FLAG_SCCB_ON) {
+ fcr |= KL0_SCCB_ENABLE;
+ /* Perform irda specific inits */
+ if ((param & 0xfff) == PMAC_SCC_IRDA) {
+ fcr &= ~KL0_SCC_B_INTF_ENABLE;
+ fcr |= KL0_IRDA_ENABLE;
+ fcr |= KL0_IRDA_CLK32_ENABLE | KL0_IRDA_CLK19_ENABLE;
+ fcr |= KL0_IRDA_SOURCE1_SEL;
+ fcr &= ~(KL0_IRDA_FAST_CONNECT|KL0_IRDA_DEFAULT1|KL0_IRDA_DEFAULT0);
+ fcr &= ~(KL0_IRDA_SOURCE2_SEL|KL0_IRDA_HIGH_BAND);
+ need_reset_irda = 1;
+ } else
+ fcr |= KL0_SCC_B_INTF_ENABLE;
+ }
+ MACIO_OUT32(KEYLARGO_FCR0, fcr);
+ macio->flags |= chan_mask;
+ if (need_reset_scc) {
+ MACIO_BIS(KEYLARGO_FCR0, KL0_SCC_RESET);
+ (void)MACIO_IN32(KEYLARGO_FCR0);
+ UNLOCK(flags);
+ mdelay(15);
+ LOCK(flags);
+ MACIO_BIC(KEYLARGO_FCR0, KL0_SCC_RESET);
+ }
+ if (need_reset_irda) {
+ MACIO_BIS(KEYLARGO_FCR0, KL0_IRDA_RESET);
+ (void)MACIO_IN32(KEYLARGO_FCR0);
+ UNLOCK(flags);
+ mdelay(15);
+ LOCK(flags);
+ MACIO_BIC(KEYLARGO_FCR0, KL0_IRDA_RESET);
+ }
+ UNLOCK(flags);
+ if (param & PMAC_SCC_FLAG_XMON)
+ macio->flags |= MACIO_FLAG_SCC_LOCKED;
+ } else {
+ if (macio->flags & MACIO_FLAG_SCC_LOCKED)
+ return -EPERM;
+ LOCK(flags);
+ fcr = MACIO_IN32(KEYLARGO_FCR0);
+ if (chan_mask & MACIO_FLAG_SCCA_ON)
+ fcr &= ~KL0_SCCA_ENABLE;
+ if (chan_mask & MACIO_FLAG_SCCB_ON) {
+ fcr &= ~KL0_SCCB_ENABLE;
+ /* Perform irda specific clears */
+ if ((param & 0xfff) == PMAC_SCC_IRDA) {
+ fcr &= ~KL0_IRDA_ENABLE;
+ fcr &= ~(KL0_IRDA_CLK32_ENABLE | KL0_IRDA_CLK19_ENABLE);
+ fcr &= ~(KL0_IRDA_FAST_CONNECT|KL0_IRDA_DEFAULT1|KL0_IRDA_DEFAULT0);
+ fcr &= ~(KL0_IRDA_SOURCE1_SEL|KL0_IRDA_SOURCE2_SEL|KL0_IRDA_HIGH_BAND);
+ }
+ }
+ MACIO_OUT32(KEYLARGO_FCR0, fcr);
+ if ((fcr & (KL0_SCCA_ENABLE | KL0_SCCB_ENABLE)) == 0) {
+ fcr &= ~KL0_SCC_CELL_ENABLE;
+ MACIO_OUT32(KEYLARGO_FCR0, fcr);
+ }
+ macio->flags &= ~(chan_mask);
+ UNLOCK(flags);
+ mdelay(10);
+ }
+ return 0;
+}
+
+static long
+core99_modem_enable(struct device_node *node, long param, long value)
+{
+ struct macio_chip* macio;
+ u8 gpio;
+ unsigned long flags;
+
+ /* Hack for internal USB modem */
+ if (node == NULL) {
+ if (macio_chips[0].type != macio_keylargo)
+ return -ENODEV;
+ node = macio_chips[0].of_node;
+ }
+ macio = macio_find(node, 0);
+ if (!macio)
+ return -ENODEV;
+ gpio = MACIO_IN8(KL_GPIO_MODEM_RESET);
+ gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE;
+ gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA;
+
+ if (!value) {
+ LOCK(flags);
+ MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
+ UNLOCK(flags);
+ (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
+ mdelay(250);
+ }
+ LOCK(flags);
+ if (value) {
+ MACIO_BIC(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
+ UNLOCK(flags);
+ (void)MACIO_IN32(KEYLARGO_FCR2);
+ mdelay(250);
+ } else {
+ MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
+ UNLOCK(flags);
+ }
+ if (value) {
+ LOCK(flags);
+ MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
+ (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
+ UNLOCK(flags); mdelay(250); LOCK(flags);
+ MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
+ (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
+ UNLOCK(flags); mdelay(250); LOCK(flags);
+ MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
+ (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
+ UNLOCK(flags); mdelay(250);
+ }
+ return 0;
+}
+
+static long
+pangea_modem_enable(struct device_node *node, long param, long value)
+{
+ struct macio_chip* macio;
+ u8 gpio;
+ unsigned long flags;
+
+ /* Hack for internal USB modem */
+ if (node == NULL) {
+ if (macio_chips[0].type != macio_pangea &&
+ macio_chips[0].type != macio_intrepid)
+ return -ENODEV;
+ node = macio_chips[0].of_node;
+ }
+ macio = macio_find(node, 0);
+ if (!macio)
+ return -ENODEV;
+ gpio = MACIO_IN8(KL_GPIO_MODEM_RESET);
+ gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE;
+ gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA;
+
+ if (!value) {
+ LOCK(flags);
+ MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
+ UNLOCK(flags);
+ (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
+ mdelay(250);
+ }
+ LOCK(flags);
+ if (value) {
+ MACIO_OUT8(KL_GPIO_MODEM_POWER,
+ KEYLARGO_GPIO_OUTPUT_ENABLE);
+ UNLOCK(flags);
+ (void)MACIO_IN32(KEYLARGO_FCR2);
+ mdelay(250);
+ } else {
+ MACIO_OUT8(KL_GPIO_MODEM_POWER,
+ KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA);
+ UNLOCK(flags);
+ }
+ if (value) {
+ LOCK(flags);
+ MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
+ (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
+ UNLOCK(flags); mdelay(250); LOCK(flags);
+ MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
+ (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
+ UNLOCK(flags); mdelay(250); LOCK(flags);
+ MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
+ (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
+ UNLOCK(flags); mdelay(250);
+ }
+ return 0;
+}
+
+static long
+core99_ata100_enable(struct device_node *node, long value)
+{
+ unsigned long flags;
+ struct pci_dev *pdev = NULL;
+ u8 pbus, pid;
+
+ if (uninorth_rev < 0x24)
+ return -ENODEV;
+
+ LOCK(flags);
+ if (value)
+ UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_ATA100);
+ else
+ UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_ATA100);
+ (void)UN_IN(UNI_N_CLOCK_CNTL);
+ UNLOCK(flags);
+ udelay(20);
+
+ if (value) {
+ if (pci_device_from_OF_node(node, &pbus, &pid) == 0)
+ pdev = pci_find_slot(pbus, pid);
+ if (pdev == NULL)
+ return 0;
+ pci_enable_device(pdev);
+ pci_set_master(pdev);
+ }
+ return 0;
+}
+
+static long
+core99_ide_enable(struct device_node *node, long param, long value)
+{
+ /* Bus ID 0 to 2 are KeyLargo based IDE, busID 3 is U2
+ * based ata-100
+ */
+ switch(param) {
+ case 0:
+ return simple_feature_tweak(node, macio_unknown,
+ KEYLARGO_FCR1, KL1_EIDE0_ENABLE, value);
+ case 1:
+ return simple_feature_tweak(node, macio_unknown,
+ KEYLARGO_FCR1, KL1_EIDE1_ENABLE, value);
+ case 2:
+ return simple_feature_tweak(node, macio_unknown,
+ KEYLARGO_FCR1, KL1_UIDE_ENABLE, value);
+ case 3:
+ return core99_ata100_enable(node, value);
+ default:
+ return -ENODEV;
+ }
+}
+
+static long
+core99_ide_reset(struct device_node *node, long param, long value)
+{
+ switch(param) {
+ case 0:
+ return simple_feature_tweak(node, macio_unknown,
+ KEYLARGO_FCR1, KL1_EIDE0_RESET_N, !value);
+ case 1:
+ return simple_feature_tweak(node, macio_unknown,
+ KEYLARGO_FCR1, KL1_EIDE1_RESET_N, !value);
+ case 2:
+ return simple_feature_tweak(node, macio_unknown,
+ KEYLARGO_FCR1, KL1_UIDE_RESET_N, !value);
+ default:
+ return -ENODEV;
+ }
+}
+
+static long
+core99_gmac_enable(struct device_node *node, long param, long value)
+{
+ unsigned long flags;
+
+ LOCK(flags);
+ if (value)
+ UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC);
+ else
+ UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC);
+ (void)UN_IN(UNI_N_CLOCK_CNTL);
+ UNLOCK(flags);
+ udelay(20);
+
+ return 0;
+}
+
+static long
+core99_gmac_phy_reset(struct device_node *node, long param, long value)
+{
+ unsigned long flags;
+ struct macio_chip *macio;
+
+ macio = &macio_chips[0];
+ if (macio->type != macio_keylargo && macio->type != macio_pangea &&
+ macio->type != macio_intrepid)
+ return -ENODEV;
+
+ LOCK(flags);
+ MACIO_OUT8(KL_GPIO_ETH_PHY_RESET, KEYLARGO_GPIO_OUTPUT_ENABLE);
+ (void)MACIO_IN8(KL_GPIO_ETH_PHY_RESET);
+ UNLOCK(flags);
+ mdelay(10);
+ LOCK(flags);
+ MACIO_OUT8(KL_GPIO_ETH_PHY_RESET, /*KEYLARGO_GPIO_OUTPUT_ENABLE | */
+ KEYLARGO_GPIO_OUTOUT_DATA);
+ UNLOCK(flags);
+ mdelay(10);
+
+ return 0;
+}
+
+static long
+core99_sound_chip_enable(struct device_node *node, long param, long value)
+{
+ struct macio_chip* macio;
+ unsigned long flags;
+
+ macio = macio_find(node, 0);
+ if (!macio)
+ return -ENODEV;
+
+ /* Do a better probe code, screamer G4 desktops &
+ * iMacs can do that too, add a recalibrate in
+ * the driver as well
+ */
+ if (pmac_mb.model_id == PMAC_TYPE_PISMO ||
+ pmac_mb.model_id == PMAC_TYPE_TITANIUM) {
+ LOCK(flags);
+ if (value)
+ MACIO_OUT8(KL_GPIO_SOUND_POWER,
+ KEYLARGO_GPIO_OUTPUT_ENABLE |
+ KEYLARGO_GPIO_OUTOUT_DATA);
+ else
+ MACIO_OUT8(KL_GPIO_SOUND_POWER,
+ KEYLARGO_GPIO_OUTPUT_ENABLE);
+ (void)MACIO_IN8(KL_GPIO_SOUND_POWER);
+ UNLOCK(flags);
+ }
+ return 0;
+}
+
+static long
+core99_airport_enable(struct device_node *node, long param, long value)
+{
+ struct macio_chip* macio;
+ unsigned long flags;
+ int state;
+
+ macio = macio_find(node, 0);
+ if (!macio)
+ return -ENODEV;
+
+ /* Hint: we allow passing of macio itself for the sake of the
+ * sleep code
+ */
+ if (node != macio->of_node &&
+ (!node->parent || node->parent != macio->of_node))
+ return -ENODEV;
+ state = (macio->flags & MACIO_FLAG_AIRPORT_ON) != 0;
+ if (value == state)
+ return 0;
+ if (value) {
+ /* This code is a reproduction of OF enable-cardslot
+ * and init-wireless methods, slightly hacked until
+ * I got it working.
+ */
+ LOCK(flags);
+ MACIO_OUT8(KEYLARGO_GPIO_0+0xf, 5);
+ (void)MACIO_IN8(KEYLARGO_GPIO_0+0xf);
+ UNLOCK(flags);
+ mdelay(10);
+ LOCK(flags);
+ MACIO_OUT8(KEYLARGO_GPIO_0+0xf, 4);
+ (void)MACIO_IN8(KEYLARGO_GPIO_0+0xf);
+ UNLOCK(flags);
+
+ mdelay(10);
+
+ LOCK(flags);
+ MACIO_BIC(KEYLARGO_FCR2, KL2_CARDSEL_16);
+ (void)MACIO_IN32(KEYLARGO_FCR2);
+ udelay(10);
+ MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xb, 0);
+ (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xb);
+ udelay(10);
+ MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xa, 0x28);
+ (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xa);
+ udelay(10);
+ MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xd, 0x28);
+ (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xd);
+ udelay(10);
+ MACIO_OUT8(KEYLARGO_GPIO_0+0xd, 0x28);
+ (void)MACIO_IN8(KEYLARGO_GPIO_0+0xd);
+ udelay(10);
+ MACIO_OUT8(KEYLARGO_GPIO_0+0xe, 0x28);
+ (void)MACIO_IN8(KEYLARGO_GPIO_0+0xe);
+ UNLOCK(flags);
+ udelay(10);
+ MACIO_OUT32(0x1c000, 0);
+ mdelay(1);
+ MACIO_OUT8(0x1a3e0, 0x41);
+ (void)MACIO_IN8(0x1a3e0);
+ udelay(10);
+ LOCK(flags);
+ MACIO_BIS(KEYLARGO_FCR2, KL2_CARDSEL_16);
+ (void)MACIO_IN32(KEYLARGO_FCR2);
+ UNLOCK(flags);
+ mdelay(100);
+
+ macio->flags |= MACIO_FLAG_AIRPORT_ON;
+ } else {
+ LOCK(flags);
+ MACIO_BIC(KEYLARGO_FCR2, KL2_CARDSEL_16);
+ (void)MACIO_IN32(KEYLARGO_FCR2);
+ MACIO_OUT8(KL_GPIO_AIRPORT_0, 0);
+ MACIO_OUT8(KL_GPIO_AIRPORT_1, 0);
+ MACIO_OUT8(KL_GPIO_AIRPORT_2, 0);
+ MACIO_OUT8(KL_GPIO_AIRPORT_3, 0);
+ MACIO_OUT8(KL_GPIO_AIRPORT_4, 0);
+ (void)MACIO_IN8(KL_GPIO_AIRPORT_4);
+ UNLOCK(flags);
+
+ macio->flags &= ~MACIO_FLAG_AIRPORT_ON;
+ }
+ return 0;
+}
+
+#ifdef CONFIG_SMP
+static long
+core99_reset_cpu(struct device_node *node, long param, long value)
+{
+ unsigned int reset_io = 0;
+ unsigned long flags;
+ struct macio_chip *macio;
+ struct device_node *np;
+ const int dflt_reset_lines[] = { KL_GPIO_RESET_CPU0,
+ KL_GPIO_RESET_CPU1,
+ KL_GPIO_RESET_CPU2,
+ KL_GPIO_RESET_CPU3 };
+
+ macio = &macio_chips[0];
+ if (macio->type != macio_keylargo)
+ return -ENODEV;
+
+ np = find_path_device("/cpus");
+ if (np == NULL)
+ return -ENODEV;
+ for (np = np->child; np != NULL; np = np->sibling) {
+ u32 *num = (u32 *)get_property(np, "reg", NULL);
+ u32 *rst = (u32 *)get_property(np, "soft-reset", NULL);
+ if (num == NULL || rst == NULL)
+ continue;
+ if (param == *num) {
+ reset_io = *rst;
+ break;
+ }
+ }
+ if (np == NULL || reset_io == 0)
+ reset_io = dflt_reset_lines[param];
+
+ LOCK(flags);
+ MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE);
+ (void)MACIO_IN8(reset_io);
+ udelay(1);
+ MACIO_OUT8(reset_io, 0);
+ (void)MACIO_IN8(reset_io);
+ UNLOCK(flags);
+
+ return 0;
+}
+#endif /* CONFIG_SMP */
+
+static long
+core99_usb_enable(struct device_node *node, long param, long value)
+{
+ struct macio_chip *macio;
+ unsigned long flags;
+ char *prop;
+ int number;
+ u32 reg;
+
+ macio = &macio_chips[0];
+ if (macio->type != macio_keylargo && macio->type != macio_pangea &&
+ macio->type != macio_intrepid)
+ return -ENODEV;
+
+ prop = (char *)get_property(node, "AAPL,clock-id", NULL);
+ if (!prop)
+ return -ENODEV;
+ if (strncmp(prop, "usb0u048", 8) == 0)
+ number = 0;
+ else if (strncmp(prop, "usb1u148", 8) == 0)
+ number = 2;
+ else if (strncmp(prop, "usb2u248", 8) == 0)
+ number = 4;
+ else
+ return -ENODEV;
+
+ /* Sorry for the brute-force locking, but this is only used during
+ * sleep and the timing seem to be critical
+ */
+ LOCK(flags);
+ if (value) {
+ /* Turn ON */
+ if (number == 0) {
+ MACIO_BIC(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1));
+ (void)MACIO_IN32(KEYLARGO_FCR0);
+ UNLOCK(flags);
+ mdelay(1);
+ LOCK(flags);
+ MACIO_BIS(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE);
+ } else if (number == 2) {
+ MACIO_BIC(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1));
+ UNLOCK(flags);
+ (void)MACIO_IN32(KEYLARGO_FCR0);
+ mdelay(1);
+ LOCK(flags);
+ MACIO_BIS(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE);
+ } else if (number == 4) {
+ MACIO_BIC(KEYLARGO_FCR1, (KL1_USB2_PAD_SUSPEND0 | KL1_USB2_PAD_SUSPEND1));
+ UNLOCK(flags);
+ (void)MACIO_IN32(KEYLARGO_FCR1);
+ mdelay(1);
+ LOCK(flags);
+ MACIO_BIS(KEYLARGO_FCR1, KL1_USB2_CELL_ENABLE);
+ }
+ if (number < 4) {
+ reg = MACIO_IN32(KEYLARGO_FCR4);
+ reg &= ~(KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) |
+ KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number));
+ reg &= ~(KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) |
+ KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1));
+ MACIO_OUT32(KEYLARGO_FCR4, reg);
+ (void)MACIO_IN32(KEYLARGO_FCR4);
+ udelay(10);
+ } else {
+ reg = MACIO_IN32(KEYLARGO_FCR3);
+ reg &= ~(KL3_IT_PORT_WAKEUP_ENABLE(0) | KL3_IT_PORT_RESUME_WAKE_EN(0) |
+ KL3_IT_PORT_CONNECT_WAKE_EN(0) | KL3_IT_PORT_DISCONNECT_WAKE_EN(0));
+ reg &= ~(KL3_IT_PORT_WAKEUP_ENABLE(1) | KL3_IT_PORT_RESUME_WAKE_EN(1) |
+ KL3_IT_PORT_CONNECT_WAKE_EN(1) | KL3_IT_PORT_DISCONNECT_WAKE_EN(1));
+ MACIO_OUT32(KEYLARGO_FCR3, reg);
+ (void)MACIO_IN32(KEYLARGO_FCR3);
+ udelay(10);
+ }
+ if (macio->type == macio_intrepid) {
+ /* wait for clock stopped bits to clear */
+ u32 test0 = 0, test1 = 0;
+ u32 status0, status1;
+ int timeout = 1000;
+
+ UNLOCK(flags);
+ switch (number) {
+ case 0:
+ test0 = UNI_N_CLOCK_STOPPED_USB0;
+ test1 = UNI_N_CLOCK_STOPPED_USB0PCI;
+ break;
+ case 2:
+ test0 = UNI_N_CLOCK_STOPPED_USB1;
+ test1 = UNI_N_CLOCK_STOPPED_USB1PCI;
+ break;
+ case 4:
+ test0 = UNI_N_CLOCK_STOPPED_USB2;
+ test1 = UNI_N_CLOCK_STOPPED_USB2PCI;
+ break;
+ }
+ do {
+ if (--timeout <= 0) {
+ printk(KERN_ERR "core99_usb_enable: "
+ "Timeout waiting for clocks\n");
+ break;
+ }
+ mdelay(1);
+ status0 = UN_IN(UNI_N_CLOCK_STOP_STATUS0);
+ status1 = UN_IN(UNI_N_CLOCK_STOP_STATUS1);
+ } while ((status0 & test0) | (status1 & test1));
+ LOCK(flags);
+ }
+ } else {
+ /* Turn OFF */
+ if (number < 4) {
+ reg = MACIO_IN32(KEYLARGO_FCR4);
+ reg |= KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) |
+ KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number);
+ reg |= KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) |
+ KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1);
+ MACIO_OUT32(KEYLARGO_FCR4, reg);
+ (void)MACIO_IN32(KEYLARGO_FCR4);
+ udelay(1);
+ } else {
+ reg = MACIO_IN32(KEYLARGO_FCR3);
+ reg |= KL3_IT_PORT_WAKEUP_ENABLE(0) | KL3_IT_PORT_RESUME_WAKE_EN(0) |
+ KL3_IT_PORT_CONNECT_WAKE_EN(0) | KL3_IT_PORT_DISCONNECT_WAKE_EN(0);
+ reg |= KL3_IT_PORT_WAKEUP_ENABLE(1) | KL3_IT_PORT_RESUME_WAKE_EN(1) |
+ KL3_IT_PORT_CONNECT_WAKE_EN(1) | KL3_IT_PORT_DISCONNECT_WAKE_EN(1);
+ MACIO_OUT32(KEYLARGO_FCR3, reg);
+ (void)MACIO_IN32(KEYLARGO_FCR3);
+ udelay(1);
+ }
+ if (number == 0) {
+ if (macio->type != macio_intrepid)
+ MACIO_BIC(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE);
+ (void)MACIO_IN32(KEYLARGO_FCR0);
+ udelay(1);
+ MACIO_BIS(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1));
+ (void)MACIO_IN32(KEYLARGO_FCR0);
+ } else if (number == 2) {
+ if (macio->type != macio_intrepid)
+ MACIO_BIC(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE);
+ (void)MACIO_IN32(KEYLARGO_FCR0);
+ udelay(1);
+ MACIO_BIS(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1));
+ (void)MACIO_IN32(KEYLARGO_FCR0);
+ } else if (number == 4) {
+ udelay(1);
+ MACIO_BIS(KEYLARGO_FCR1, (KL1_USB2_PAD_SUSPEND0 | KL1_USB2_PAD_SUSPEND1));
+ (void)MACIO_IN32(KEYLARGO_FCR1);
+ }
+ udelay(1);
+ }
+ UNLOCK(flags);
+
+ return 0;
+}
+
+static long
+core99_firewire_enable(struct device_node *node, long param, long value)
+{
+ unsigned long flags;
+ struct macio_chip *macio;
+
+ macio = &macio_chips[0];
+ if (macio->type != macio_keylargo && macio->type != macio_pangea &&
+ macio->type != macio_intrepid)
+ return -ENODEV;
+ if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED))
+ return -ENODEV;
+
+ LOCK(flags);
+ if (value) {
+ UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW);
+ (void)UN_IN(UNI_N_CLOCK_CNTL);
+ } else {
+ UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW);
+ (void)UN_IN(UNI_N_CLOCK_CNTL);
+ }
+ UNLOCK(flags);
+ mdelay(1);
+
+ return 0;
+}
+
+static long
+core99_firewire_cable_power(struct device_node *node, long param, long value)
+{
+ unsigned long flags;
+ struct macio_chip *macio;
+
+ /* Trick: we allow NULL node */
+ if ((pmac_mb.board_flags & PMAC_MB_HAS_FW_POWER) == 0)
+ return -ENODEV;
+ macio = &macio_chips[0];
+ if (macio->type != macio_keylargo && macio->type != macio_pangea &&
+ macio->type != macio_intrepid)
+ return -ENODEV;
+ if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED))
+ return -ENODEV;
+
+ LOCK(flags);
+ if (value) {
+ MACIO_OUT8(KL_GPIO_FW_CABLE_POWER , 0);
+ MACIO_IN8(KL_GPIO_FW_CABLE_POWER);
+ udelay(10);
+ } else {
+ MACIO_OUT8(KL_GPIO_FW_CABLE_POWER , 4);
+ MACIO_IN8(KL_GPIO_FW_CABLE_POWER); udelay(10);
+ }
+ UNLOCK(flags);
+ mdelay(1);
+
+ return 0;
+}
+
+static long
+intrepid_aack_delay_enable(struct device_node *node, long param, long value)
+{
+ unsigned long flags;
+
+ if (uninorth_rev < 0xd2)
+ return -ENODEV;
+
+ LOCK(flags);
+ if (param)
+ UN_BIS(UNI_N_AACK_DELAY, UNI_N_AACK_DELAY_ENABLE);
+ else
+ UN_BIC(UNI_N_AACK_DELAY, UNI_N_AACK_DELAY_ENABLE);
+ UNLOCK(flags);
+
+ return 0;
+}
+
+
+#endif /* CONFIG_POWER4 */
+
+static long
+core99_read_gpio(struct device_node *node, long param, long value)
+{
+ struct macio_chip *macio = &macio_chips[0];
+
+ return MACIO_IN8(param);
+}
+
+
+static long
+core99_write_gpio(struct device_node *node, long param, long value)
+{
+ struct macio_chip *macio = &macio_chips[0];
+
+ MACIO_OUT8(param, (u8)(value & 0xff));
+ return 0;
+}
+
+#ifdef CONFIG_POWER4
+static long g5_gmac_enable(struct device_node *node, long param, long value)
+{
+ struct macio_chip *macio = &macio_chips[0];
+ unsigned long flags;
+
+ if (node == NULL)
+ return -ENODEV;
+
+ LOCK(flags);
+ if (value) {
+ MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);
+ mb();
+ k2_skiplist[0] = NULL;
+ } else {
+ k2_skiplist[0] = node;
+ mb();
+ MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);
+ }
+
+ UNLOCK(flags);
+ mdelay(1);
+
+ return 0;
+}
+
+static long g5_fw_enable(struct device_node *node, long param, long value)
+{
+ struct macio_chip *macio = &macio_chips[0];
+ unsigned long flags;
+
+ if (node == NULL)
+ return -ENODEV;
+
+ LOCK(flags);
+ if (value) {
+ MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE);
+ mb();
+ k2_skiplist[1] = NULL;
+ } else {
+ k2_skiplist[1] = node;
+ mb();
+ MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE);
+ }
+
+ UNLOCK(flags);
+ mdelay(1);
+
+ return 0;
+}
+
+static long g5_mpic_enable(struct device_node *node, long param, long value)
+{
+ unsigned long flags;
+
+ if (node->parent == NULL || strcmp(node->parent->name, "u3"))
+ return 0;
+
+ LOCK(flags);
+ UN_BIS(U3_TOGGLE_REG, U3_MPIC_RESET | U3_MPIC_OUTPUT_ENABLE);
+ UNLOCK(flags);
+
+ return 0;
+}
+
+static long g5_eth_phy_reset(struct device_node *node, long param, long value)
+{
+ struct macio_chip *macio = &macio_chips[0];
+ struct device_node *phy;
+ int need_reset;
+
+ /*
+ * We must not reset the combo PHYs, only the BCM5221 found in
+ * the iMac G5.
+ */
+ phy = of_get_next_child(node, NULL);
+ if (!phy)
+ return -ENODEV;
+ need_reset = device_is_compatible(phy, "B5221");
+ of_node_put(phy);
+ if (!need_reset)
+ return 0;
+
+ /* PHY reset is GPIO 29, not in device-tree unfortunately */
+ MACIO_OUT8(K2_GPIO_EXTINT_0 + 29,
+ KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA);
+ /* Thankfully, this is now always called at a time when we can
+ * schedule by sungem.
+ */
+ msleep(10);
+ MACIO_OUT8(K2_GPIO_EXTINT_0 + 29, 0);
+
+ return 0;
+}
+
+static long g5_i2s_enable(struct device_node *node, long param, long value)
+{
+ /* Very crude implementation for now */
+ struct macio_chip *macio = &macio_chips[0];
+ unsigned long flags;
+
+ if (value == 0)
+ return 0; /* don't disable yet */
+
+ LOCK(flags);
+ MACIO_BIS(KEYLARGO_FCR3, KL3_CLK45_ENABLE | KL3_CLK49_ENABLE |
+ KL3_I2S0_CLK18_ENABLE);
+ udelay(10);
+ MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_I2S0_CELL_ENABLE |
+ K2_FCR1_I2S0_CLK_ENABLE_BIT | K2_FCR1_I2S0_ENABLE);
+ udelay(10);
+ MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_I2S0_RESET);
+ UNLOCK(flags);
+ udelay(10);
+
+ return 0;
+}
+
+
+#ifdef CONFIG_SMP
+static long g5_reset_cpu(struct device_node *node, long param, long value)
+{
+ unsigned int reset_io = 0;
+ unsigned long flags;
+ struct macio_chip *macio;
+ struct device_node *np;
+
+ macio = &macio_chips[0];
+ if (macio->type != macio_keylargo2)
+ return -ENODEV;
+
+ np = find_path_device("/cpus");
+ if (np == NULL)
+ return -ENODEV;
+ for (np = np->child; np != NULL; np = np->sibling) {
+ u32 *num = (u32 *)get_property(np, "reg", NULL);
+ u32 *rst = (u32 *)get_property(np, "soft-reset", NULL);
+ if (num == NULL || rst == NULL)
+ continue;
+ if (param == *num) {
+ reset_io = *rst;
+ break;
+ }
+ }
+ if (np == NULL || reset_io == 0)
+ return -ENODEV;
+
+ LOCK(flags);
+ MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE);
+ (void)MACIO_IN8(reset_io);
+ udelay(1);
+ MACIO_OUT8(reset_io, 0);
+ (void)MACIO_IN8(reset_io);
+ UNLOCK(flags);
+
+ return 0;
+}
+#endif /* CONFIG_SMP */
+
+/*
+ * This can be called from pmac_smp so isn't static
+ *
+ * This takes the second CPU off the bus on dual CPU machines
+ * running UP
+ */
+void g5_phy_disable_cpu1(void)
+{
+ UN_OUT(U3_API_PHY_CONFIG_1, 0);
+}
+#endif /* CONFIG_POWER4 */
+
+#ifndef CONFIG_POWER4
+
+static void
+keylargo_shutdown(struct macio_chip *macio, int sleep_mode)
+{
+ u32 temp;
+
+ if (sleep_mode) {
+ mdelay(1);
+ MACIO_BIS(KEYLARGO_FCR0, KL0_USB_REF_SUSPEND);
+ (void)MACIO_IN32(KEYLARGO_FCR0);
+ mdelay(1);
+ }
+
+ MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE |
+ KL0_SCC_CELL_ENABLE |
+ KL0_IRDA_ENABLE | KL0_IRDA_CLK32_ENABLE |
+ KL0_IRDA_CLK19_ENABLE);
+
+ MACIO_BIC(KEYLARGO_MBCR, KL_MBCR_MB0_DEV_MASK);
+ MACIO_BIS(KEYLARGO_MBCR, KL_MBCR_MB0_IDE_ENABLE);
+
+ MACIO_BIC(KEYLARGO_FCR1,
+ KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT |
+ KL1_AUDIO_CLK_OUT_ENABLE | KL1_AUDIO_CELL_ENABLE |
+ KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT |
+ KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE |
+ KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE |
+ KL1_EIDE0_ENABLE | KL1_EIDE0_RESET_N |
+ KL1_EIDE1_ENABLE | KL1_EIDE1_RESET_N |
+ KL1_UIDE_ENABLE);
+
+ MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
+ MACIO_BIC(KEYLARGO_FCR2, KL2_IOBUS_ENABLE);
+
+ temp = MACIO_IN32(KEYLARGO_FCR3);
+ if (macio->rev >= 2) {
+ temp |= KL3_SHUTDOWN_PLL2X;
+ if (sleep_mode)
+ temp |= KL3_SHUTDOWN_PLL_TOTAL;
+ }
+
+ temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 |
+ KL3_SHUTDOWN_PLLKW35;
+ if (sleep_mode)
+ temp |= KL3_SHUTDOWN_PLLKW12;
+ temp &= ~(KL3_CLK66_ENABLE | KL3_CLK49_ENABLE | KL3_CLK45_ENABLE
+ | KL3_CLK31_ENABLE | KL3_I2S1_CLK18_ENABLE | KL3_I2S0_CLK18_ENABLE);
+ if (sleep_mode)
+ temp &= ~(KL3_TIMER_CLK18_ENABLE | KL3_VIA_CLK16_ENABLE);
+ MACIO_OUT32(KEYLARGO_FCR3, temp);
+
+ /* Flush posted writes & wait a bit */
+ (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1);
+}
+
+static void
+pangea_shutdown(struct macio_chip *macio, int sleep_mode)
+{
+ u32 temp;
+
+ MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE |
+ KL0_SCC_CELL_ENABLE |
+ KL0_USB0_CELL_ENABLE | KL0_USB1_CELL_ENABLE);
+
+ MACIO_BIC(KEYLARGO_FCR1,
+ KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT |
+ KL1_AUDIO_CLK_OUT_ENABLE | KL1_AUDIO_CELL_ENABLE |
+ KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT |
+ KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE |
+ KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE |
+ KL1_UIDE_ENABLE);
+ if (pmac_mb.board_flags & PMAC_MB_MOBILE)
+ MACIO_BIC(KEYLARGO_FCR1, KL1_UIDE_RESET_N);
+
+ MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
+
+ temp = MACIO_IN32(KEYLARGO_FCR3);
+ temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 |
+ KL3_SHUTDOWN_PLLKW35;
+ temp &= ~(KL3_CLK49_ENABLE | KL3_CLK45_ENABLE | KL3_CLK31_ENABLE
+ | KL3_I2S0_CLK18_ENABLE | KL3_I2S1_CLK18_ENABLE);
+ if (sleep_mode)
+ temp &= ~(KL3_VIA_CLK16_ENABLE | KL3_TIMER_CLK18_ENABLE);
+ MACIO_OUT32(KEYLARGO_FCR3, temp);
+
+ /* Flush posted writes & wait a bit */
+ (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1);
+}
+
+static void
+intrepid_shutdown(struct macio_chip *macio, int sleep_mode)
+{
+ u32 temp;
+
+ MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE |
+ KL0_SCC_CELL_ENABLE);
+
+ MACIO_BIC(KEYLARGO_FCR1,
+ /*KL1_USB2_CELL_ENABLE |*/
+ KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT |
+ KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE |
+ KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE);
+ if (pmac_mb.board_flags & PMAC_MB_MOBILE)
+ MACIO_BIC(KEYLARGO_FCR1, KL1_UIDE_RESET_N);
+
+ temp = MACIO_IN32(KEYLARGO_FCR3);
+ temp &= ~(KL3_CLK49_ENABLE | KL3_CLK45_ENABLE |
+ KL3_I2S1_CLK18_ENABLE | KL3_I2S0_CLK18_ENABLE);
+ if (sleep_mode)
+ temp &= ~(KL3_TIMER_CLK18_ENABLE | KL3_IT_VIA_CLK32_ENABLE);
+ MACIO_OUT32(KEYLARGO_FCR3, temp);
+
+ /* Flush posted writes & wait a bit */
+ (void)MACIO_IN32(KEYLARGO_FCR0);
+ mdelay(10);
+}
+
+
+void pmac_tweak_clock_spreading(int enable)
+{
+ struct macio_chip *macio = &macio_chips[0];
+
+ /* Hack for doing clock spreading on some machines PowerBooks and
+ * iBooks. This implements the "platform-do-clockspreading" OF
+ * property as decoded manually on various models. For safety, we also
+ * check the product ID in the device-tree in cases we'll whack the i2c
+ * chip to make reasonably sure we won't set wrong values in there
+ *
+ * Of course, ultimately, we have to implement a real parser for
+ * the platform-do-* stuff...
+ */
+
+ if (macio->type == macio_intrepid) {
+ if (enable)
+ UN_OUT(UNI_N_CLOCK_SPREADING, 2);
+ else
+ UN_OUT(UNI_N_CLOCK_SPREADING, 0);
+ mdelay(40);
+ }
+
+ while (machine_is_compatible("PowerBook5,2") ||
+ machine_is_compatible("PowerBook5,3") ||
+ machine_is_compatible("PowerBook6,2") ||
+ machine_is_compatible("PowerBook6,3")) {
+ struct device_node *ui2c = of_find_node_by_type(NULL, "i2c");
+ struct device_node *dt = of_find_node_by_name(NULL, "device-tree");
+ u8 buffer[9];
+ u32 *productID;
+ int i, rc, changed = 0;
+
+ if (dt == NULL)
+ break;
+ productID = (u32 *)get_property(dt, "pid#", NULL);
+ if (productID == NULL)
+ break;
+ while(ui2c) {
+ struct device_node *p = of_get_parent(ui2c);
+ if (p && !strcmp(p->name, "uni-n"))
+ break;
+ ui2c = of_find_node_by_type(ui2c, "i2c");
+ }
+ if (ui2c == NULL)
+ break;
+ DBG("Trying to bump clock speed for PID: %08x...\n", *productID);
+ rc = pmac_low_i2c_open(ui2c, 1);
+ if (rc != 0)
+ break;
+ pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined);
+ rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9);
+ DBG("read result: %d,", rc);
+ if (rc != 0) {
+ pmac_low_i2c_close(ui2c);
+ break;
+ }
+ for (i=0; i<9; i++)
+ DBG(" %02x", buffer[i]);
+ DBG("\n");
+
+ switch(*productID) {
+ case 0x1182: /* AlBook 12" rev 2 */
+ case 0x1183: /* iBook G4 12" */
+ buffer[0] = (buffer[0] & 0x8f) | 0x70;
+ buffer[2] = (buffer[2] & 0x7f) | 0x00;
+ buffer[5] = (buffer[5] & 0x80) | 0x31;
+ buffer[6] = (buffer[6] & 0x40) | 0xb0;
+ buffer[7] = (buffer[7] & 0x00) | (enable ? 0xc0 : 0xba);
+ buffer[8] = (buffer[8] & 0x00) | 0x30;
+ changed = 1;
+ break;
+ case 0x3142: /* AlBook 15" (ATI M10) */
+ case 0x3143: /* AlBook 17" (ATI M10) */
+ buffer[0] = (buffer[0] & 0xaf) | 0x50;
+ buffer[2] = (buffer[2] & 0x7f) | 0x00;
+ buffer[5] = (buffer[5] & 0x80) | 0x31;
+ buffer[6] = (buffer[6] & 0x40) | 0xb0;
+ buffer[7] = (buffer[7] & 0x00) | (enable ? 0xd0 : 0xc0);
+ buffer[8] = (buffer[8] & 0x00) | 0x30;
+ changed = 1;
+ break;
+ default:
+ DBG("i2c-hwclock: Machine model not handled\n");
+ break;
+ }
+ if (!changed) {
+ pmac_low_i2c_close(ui2c);
+ break;
+ }
+ pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_stdsub);
+ rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_write, 0x80, buffer, 9);
+ DBG("write result: %d,", rc);
+ pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined);
+ rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9);
+ DBG("read result: %d,", rc);
+ if (rc != 0) {
+ pmac_low_i2c_close(ui2c);
+ break;
+ }
+ for (i=0; i<9; i++)
+ DBG(" %02x", buffer[i]);
+ pmac_low_i2c_close(ui2c);
+ break;
+ }
+}
+
+
+static int
+core99_sleep(void)
+{
+ struct macio_chip *macio;
+ int i;
+
+ macio = &macio_chips[0];
+ if (macio->type != macio_keylargo && macio->type != macio_pangea &&
+ macio->type != macio_intrepid)
+ return -ENODEV;
+
+ /* We power off the wireless slot in case it was not done
+ * by the driver. We don't power it on automatically however
+ */
+ if (macio->flags & MACIO_FLAG_AIRPORT_ON)
+ core99_airport_enable(macio->of_node, 0, 0);
+
+ /* We power off the FW cable. Should be done by the driver... */
+ if (macio->flags & MACIO_FLAG_FW_SUPPORTED) {
+ core99_firewire_enable(NULL, 0, 0);
+ core99_firewire_cable_power(NULL, 0, 0);
+ }
+
+ /* We make sure int. modem is off (in case driver lost it) */
+ if (macio->type == macio_keylargo)
+ core99_modem_enable(macio->of_node, 0, 0);
+ else
+ pangea_modem_enable(macio->of_node, 0, 0);
+
+ /* We make sure the sound is off as well */
+ core99_sound_chip_enable(macio->of_node, 0, 0);
+
+ /*
+ * Save various bits of KeyLargo
+ */
+
+ /* Save the state of the various GPIOs */
+ save_gpio_levels[0] = MACIO_IN32(KEYLARGO_GPIO_LEVELS0);
+ save_gpio_levels[1] = MACIO_IN32(KEYLARGO_GPIO_LEVELS1);
+ for (i=0; i<KEYLARGO_GPIO_EXTINT_CNT; i++)
+ save_gpio_extint[i] = MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+i);
+ for (i=0; i<KEYLARGO_GPIO_CNT; i++)
+ save_gpio_normal[i] = MACIO_IN8(KEYLARGO_GPIO_0+i);
+
+ /* Save the FCRs */
+ if (macio->type == macio_keylargo)
+ save_mbcr = MACIO_IN32(KEYLARGO_MBCR);
+ save_fcr[0] = MACIO_IN32(KEYLARGO_FCR0);
+ save_fcr[1] = MACIO_IN32(KEYLARGO_FCR1);
+ save_fcr[2] = MACIO_IN32(KEYLARGO_FCR2);
+ save_fcr[3] = MACIO_IN32(KEYLARGO_FCR3);
+ save_fcr[4] = MACIO_IN32(KEYLARGO_FCR4);
+ if (macio->type == macio_pangea || macio->type == macio_intrepid)
+ save_fcr[5] = MACIO_IN32(KEYLARGO_FCR5);
+
+ /* Save state & config of DBDMA channels */
+ dbdma_save(macio, save_dbdma);
+
+ /*
+ * Turn off as much as we can
+ */
+ if (macio->type == macio_pangea)
+ pangea_shutdown(macio, 1);
+ else if (macio->type == macio_intrepid)
+ intrepid_shutdown(macio, 1);
+ else if (macio->type == macio_keylargo)
+ keylargo_shutdown(macio, 1);
+
+ /*
+ * Put the host bridge to sleep
+ */
+
+ save_unin_clock_ctl = UN_IN(UNI_N_CLOCK_CNTL);
+ /* Note: do not switch GMAC off, driver does it when necessary, WOL must keep it
+ * enabled !
+ */
+ UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl &
+ ~(/*UNI_N_CLOCK_CNTL_GMAC|*/UNI_N_CLOCK_CNTL_FW/*|UNI_N_CLOCK_CNTL_PCI*/));
+ udelay(100);
+ UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_SLEEPING);
+ UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_SLEEP);
+ mdelay(10);
+
+ /*
+ * FIXME: A bit of black magic with OpenPIC (don't ask me why)
+ */
+ if (pmac_mb.model_id == PMAC_TYPE_SAWTOOTH) {
+ MACIO_BIS(0x506e0, 0x00400000);
+ MACIO_BIS(0x506e0, 0x80000000);
+ }
+ return 0;
+}
+
+static int
+core99_wake_up(void)
+{
+ struct macio_chip *macio;
+ int i;
+
+ macio = &macio_chips[0];
+ if (macio->type != macio_keylargo && macio->type != macio_pangea &&
+ macio->type != macio_intrepid)
+ return -ENODEV;
+
+ /*
+ * Wakeup the host bridge
+ */
+ UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_NORMAL);
+ udelay(10);
+ UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_RUNNING);
+ udelay(10);
+
+ /*
+ * Restore KeyLargo
+ */
+
+ if (macio->type == macio_keylargo) {
+ MACIO_OUT32(KEYLARGO_MBCR, save_mbcr);
+ (void)MACIO_IN32(KEYLARGO_MBCR); udelay(10);
+ }
+ MACIO_OUT32(KEYLARGO_FCR0, save_fcr[0]);
+ (void)MACIO_IN32(KEYLARGO_FCR0); udelay(10);
+ MACIO_OUT32(KEYLARGO_FCR1, save_fcr[1]);
+ (void)MACIO_IN32(KEYLARGO_FCR1); udelay(10);
+ MACIO_OUT32(KEYLARGO_FCR2, save_fcr[2]);
+ (void)MACIO_IN32(KEYLARGO_FCR2); udelay(10);
+ MACIO_OUT32(KEYLARGO_FCR3, save_fcr[3]);
+ (void)MACIO_IN32(KEYLARGO_FCR3); udelay(10);
+ MACIO_OUT32(KEYLARGO_FCR4, save_fcr[4]);
+ (void)MACIO_IN32(KEYLARGO_FCR4); udelay(10);
+ if (macio->type == macio_pangea || macio->type == macio_intrepid) {
+ MACIO_OUT32(KEYLARGO_FCR5, save_fcr[5]);
+ (void)MACIO_IN32(KEYLARGO_FCR5); udelay(10);
+ }
+
+ dbdma_restore(macio, save_dbdma);
+
+ MACIO_OUT32(KEYLARGO_GPIO_LEVELS0, save_gpio_levels[0]);
+ MACIO_OUT32(KEYLARGO_GPIO_LEVELS1, save_gpio_levels[1]);
+ for (i=0; i<KEYLARGO_GPIO_EXTINT_CNT; i++)
+ MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+i, save_gpio_extint[i]);
+ for (i=0; i<KEYLARGO_GPIO_CNT; i++)
+ MACIO_OUT8(KEYLARGO_GPIO_0+i, save_gpio_normal[i]);
+
+ /* FIXME more black magic with OpenPIC ... */
+ if (pmac_mb.model_id == PMAC_TYPE_SAWTOOTH) {
+ MACIO_BIC(0x506e0, 0x00400000);
+ MACIO_BIC(0x506e0, 0x80000000);
+ }
+
+ UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl);
+ udelay(100);
+
+ return 0;
+}
+
+static long
+core99_sleep_state(struct device_node *node, long param, long value)
+{
+ /* Param == 1 means to enter the "fake sleep" mode that is
+ * used for CPU speed switch
+ */
+ if (param == 1) {
+ if (value == 1) {
+ UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_SLEEPING);
+ UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_IDLE2);
+ } else {
+ UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_NORMAL);
+ udelay(10);
+ UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_RUNNING);
+ udelay(10);
+ }
+ return 0;
+ }
+ if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
+ return -EPERM;
+
+ if (value == 1)
+ return core99_sleep();
+ else if (value == 0)
+ return core99_wake_up();
+ return 0;
+}
+
+#endif /* CONFIG_POWER4 */
+
+static long
+generic_dev_can_wake(struct device_node *node, long param, long value)
+{
+ /* Todo: eventually check we are really dealing with on-board
+ * video device ...
+ */
+
+ if (pmac_mb.board_flags & PMAC_MB_MAY_SLEEP)
+ pmac_mb.board_flags |= PMAC_MB_CAN_SLEEP;
+ return 0;
+}
+
+static long generic_get_mb_info(struct device_node *node, long param, long value)
+{
+ switch(param) {
+ case PMAC_MB_INFO_MODEL:
+ return pmac_mb.model_id;
+ case PMAC_MB_INFO_FLAGS:
+ return pmac_mb.board_flags;
+ case PMAC_MB_INFO_NAME:
+ /* hack hack hack... but should work */
+ *((const char **)value) = pmac_mb.model_name;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+
+/*
+ * Table definitions
+ */
+
+/* Used on any machine
+ */
+static struct feature_table_entry any_features[] = {
+ { PMAC_FTR_GET_MB_INFO, generic_get_mb_info },
+ { PMAC_FTR_DEVICE_CAN_WAKE, generic_dev_can_wake },
+ { 0, NULL }
+};
+
+#ifndef CONFIG_POWER4
+
+/* OHare based motherboards. Currently, we only use these on the
+ * 2400,3400 and 3500 series powerbooks. Some older desktops seem
+ * to have issues with turning on/off those asic cells
+ */
+static struct feature_table_entry ohare_features[] = {
+ { PMAC_FTR_SCC_ENABLE, ohare_htw_scc_enable },
+ { PMAC_FTR_SWIM3_ENABLE, ohare_floppy_enable },
+ { PMAC_FTR_MESH_ENABLE, ohare_mesh_enable },
+ { PMAC_FTR_IDE_ENABLE, ohare_ide_enable},
+ { PMAC_FTR_IDE_RESET, ohare_ide_reset},
+ { PMAC_FTR_SLEEP_STATE, ohare_sleep_state },
+ { 0, NULL }
+};
+
+/* Heathrow desktop machines (Beige G3).
+ * Separated as some features couldn't be properly tested
+ * and the serial port control bits appear to confuse it.
+ */
+static struct feature_table_entry heathrow_desktop_features[] = {
+ { PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable },
+ { PMAC_FTR_MESH_ENABLE, heathrow_mesh_enable },
+ { PMAC_FTR_IDE_ENABLE, heathrow_ide_enable },
+ { PMAC_FTR_IDE_RESET, heathrow_ide_reset },
+ { PMAC_FTR_BMAC_ENABLE, heathrow_bmac_enable },
+ { 0, NULL }
+};
+
+/* Heathrow based laptop, that is the Wallstreet and mainstreet
+ * powerbooks.
+ */
+static struct feature_table_entry heathrow_laptop_features[] = {
+ { PMAC_FTR_SCC_ENABLE, ohare_htw_scc_enable },
+ { PMAC_FTR_MODEM_ENABLE, heathrow_modem_enable },
+ { PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable },
+ { PMAC_FTR_MESH_ENABLE, heathrow_mesh_enable },
+ { PMAC_FTR_IDE_ENABLE, heathrow_ide_enable },
+ { PMAC_FTR_IDE_RESET, heathrow_ide_reset },
+ { PMAC_FTR_BMAC_ENABLE, heathrow_bmac_enable },
+ { PMAC_FTR_SOUND_CHIP_ENABLE, heathrow_sound_enable },
+ { PMAC_FTR_SLEEP_STATE, heathrow_sleep_state },
+ { 0, NULL }
+};
+
+/* Paddington based machines
+ * The lombard (101) powerbook, first iMac models, B&W G3 and Yikes G4.
+ */
+static struct feature_table_entry paddington_features[] = {
+ { PMAC_FTR_SCC_ENABLE, ohare_htw_scc_enable },
+ { PMAC_FTR_MODEM_ENABLE, heathrow_modem_enable },
+ { PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable },
+ { PMAC_FTR_MESH_ENABLE, heathrow_mesh_enable },
+ { PMAC_FTR_IDE_ENABLE, heathrow_ide_enable },
+ { PMAC_FTR_IDE_RESET, heathrow_ide_reset },
+ { PMAC_FTR_BMAC_ENABLE, heathrow_bmac_enable },
+ { PMAC_FTR_SOUND_CHIP_ENABLE, heathrow_sound_enable },
+ { PMAC_FTR_SLEEP_STATE, heathrow_sleep_state },
+ { 0, NULL }
+};
+
+/* Core99 & MacRISC 2 machines (all machines released since the
+ * iBook (included), that is all AGP machines, except pangea
+ * chipset. The pangea chipset is the "combo" UniNorth/KeyLargo
+ * used on iBook2 & iMac "flow power".
+ */
+static struct feature_table_entry core99_features[] = {
+ { PMAC_FTR_SCC_ENABLE, core99_scc_enable },
+ { PMAC_FTR_MODEM_ENABLE, core99_modem_enable },
+ { PMAC_FTR_IDE_ENABLE, core99_ide_enable },
+ { PMAC_FTR_IDE_RESET, core99_ide_reset },
+ { PMAC_FTR_GMAC_ENABLE, core99_gmac_enable },
+ { PMAC_FTR_GMAC_PHY_RESET, core99_gmac_phy_reset },
+ { PMAC_FTR_SOUND_CHIP_ENABLE, core99_sound_chip_enable },
+ { PMAC_FTR_AIRPORT_ENABLE, core99_airport_enable },
+ { PMAC_FTR_USB_ENABLE, core99_usb_enable },
+ { PMAC_FTR_1394_ENABLE, core99_firewire_enable },
+ { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power },
+ { PMAC_FTR_SLEEP_STATE, core99_sleep_state },
+#ifdef CONFIG_SMP
+ { PMAC_FTR_RESET_CPU, core99_reset_cpu },
+#endif /* CONFIG_SMP */
+ { PMAC_FTR_READ_GPIO, core99_read_gpio },
+ { PMAC_FTR_WRITE_GPIO, core99_write_gpio },
+ { 0, NULL }
+};
+
+/* RackMac
+ */
+static struct feature_table_entry rackmac_features[] = {
+ { PMAC_FTR_SCC_ENABLE, core99_scc_enable },
+ { PMAC_FTR_IDE_ENABLE, core99_ide_enable },
+ { PMAC_FTR_IDE_RESET, core99_ide_reset },
+ { PMAC_FTR_GMAC_ENABLE, core99_gmac_enable },
+ { PMAC_FTR_GMAC_PHY_RESET, core99_gmac_phy_reset },
+ { PMAC_FTR_USB_ENABLE, core99_usb_enable },
+ { PMAC_FTR_1394_ENABLE, core99_firewire_enable },
+ { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power },
+ { PMAC_FTR_SLEEP_STATE, core99_sleep_state },
+#ifdef CONFIG_SMP
+ { PMAC_FTR_RESET_CPU, core99_reset_cpu },
+#endif /* CONFIG_SMP */
+ { PMAC_FTR_READ_GPIO, core99_read_gpio },
+ { PMAC_FTR_WRITE_GPIO, core99_write_gpio },
+ { 0, NULL }
+};
+
+/* Pangea features
+ */
+static struct feature_table_entry pangea_features[] = {
+ { PMAC_FTR_SCC_ENABLE, core99_scc_enable },
+ { PMAC_FTR_MODEM_ENABLE, pangea_modem_enable },
+ { PMAC_FTR_IDE_ENABLE, core99_ide_enable },
+ { PMAC_FTR_IDE_RESET, core99_ide_reset },
+ { PMAC_FTR_GMAC_ENABLE, core99_gmac_enable },
+ { PMAC_FTR_GMAC_PHY_RESET, core99_gmac_phy_reset },
+ { PMAC_FTR_SOUND_CHIP_ENABLE, core99_sound_chip_enable },
+ { PMAC_FTR_AIRPORT_ENABLE, core99_airport_enable },
+ { PMAC_FTR_USB_ENABLE, core99_usb_enable },
+ { PMAC_FTR_1394_ENABLE, core99_firewire_enable },
+ { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power },
+ { PMAC_FTR_SLEEP_STATE, core99_sleep_state },
+ { PMAC_FTR_READ_GPIO, core99_read_gpio },
+ { PMAC_FTR_WRITE_GPIO, core99_write_gpio },
+ { 0, NULL }
+};
+
+/* Intrepid features
+ */
+static struct feature_table_entry intrepid_features[] = {
+ { PMAC_FTR_SCC_ENABLE, core99_scc_enable },
+ { PMAC_FTR_MODEM_ENABLE, pangea_modem_enable },
+ { PMAC_FTR_IDE_ENABLE, core99_ide_enable },
+ { PMAC_FTR_IDE_RESET, core99_ide_reset },
+ { PMAC_FTR_GMAC_ENABLE, core99_gmac_enable },
+ { PMAC_FTR_GMAC_PHY_RESET, core99_gmac_phy_reset },
+ { PMAC_FTR_SOUND_CHIP_ENABLE, core99_sound_chip_enable },
+ { PMAC_FTR_AIRPORT_ENABLE, core99_airport_enable },
+ { PMAC_FTR_USB_ENABLE, core99_usb_enable },
+ { PMAC_FTR_1394_ENABLE, core99_firewire_enable },
+ { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power },
+ { PMAC_FTR_SLEEP_STATE, core99_sleep_state },
+ { PMAC_FTR_READ_GPIO, core99_read_gpio },
+ { PMAC_FTR_WRITE_GPIO, core99_write_gpio },
+ { PMAC_FTR_AACK_DELAY_ENABLE, intrepid_aack_delay_enable },
+ { 0, NULL }
+};
+
+#else /* CONFIG_POWER4 */
+
+/* G5 features
+ */
+static struct feature_table_entry g5_features[] = {
+ { PMAC_FTR_GMAC_ENABLE, g5_gmac_enable },
+ { PMAC_FTR_1394_ENABLE, g5_fw_enable },
+ { PMAC_FTR_ENABLE_MPIC, g5_mpic_enable },
+ { PMAC_FTR_GMAC_PHY_RESET, g5_eth_phy_reset },
+ { PMAC_FTR_SOUND_CHIP_ENABLE, g5_i2s_enable },
+#ifdef CONFIG_SMP
+ { PMAC_FTR_RESET_CPU, g5_reset_cpu },
+#endif /* CONFIG_SMP */
+ { PMAC_FTR_READ_GPIO, core99_read_gpio },
+ { PMAC_FTR_WRITE_GPIO, core99_write_gpio },
+ { 0, NULL }
+};
+
+#endif /* CONFIG_POWER4 */
+
+static struct pmac_mb_def pmac_mb_defs[] = {
+#ifndef CONFIG_POWER4
+ /*
+ * Desktops
+ */
+
+ { "AAPL,8500", "PowerMac 8500/8600",
+ PMAC_TYPE_PSURGE, NULL,
+ 0
+ },
+ { "AAPL,9500", "PowerMac 9500/9600",
+ PMAC_TYPE_PSURGE, NULL,
+ 0
+ },
+ { "AAPL,7200", "PowerMac 7200",
+ PMAC_TYPE_PSURGE, NULL,
+ 0
+ },
+ { "AAPL,7300", "PowerMac 7200/7300",
+ PMAC_TYPE_PSURGE, NULL,
+ 0
+ },
+ { "AAPL,7500", "PowerMac 7500",
+ PMAC_TYPE_PSURGE, NULL,
+ 0
+ },
+ { "AAPL,ShinerESB", "Apple Network Server",
+ PMAC_TYPE_ANS, NULL,
+ 0
+ },
+ { "AAPL,e407", "Alchemy",
+ PMAC_TYPE_ALCHEMY, NULL,
+ 0
+ },
+ { "AAPL,e411", "Gazelle",
+ PMAC_TYPE_GAZELLE, NULL,
+ 0
+ },
+ { "AAPL,Gossamer", "PowerMac G3 (Gossamer)",
+ PMAC_TYPE_GOSSAMER, heathrow_desktop_features,
+ 0
+ },
+ { "AAPL,PowerMac G3", "PowerMac G3 (Silk)",
+ PMAC_TYPE_SILK, heathrow_desktop_features,
+ 0
+ },
+ { "PowerMac1,1", "Blue&White G3",
+ PMAC_TYPE_YOSEMITE, paddington_features,
+ 0
+ },
+ { "PowerMac1,2", "PowerMac G4 PCI Graphics",
+ PMAC_TYPE_YIKES, paddington_features,
+ 0
+ },
+ { "PowerMac2,1", "iMac FireWire",
+ PMAC_TYPE_FW_IMAC, core99_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
+ },
+ { "PowerMac2,2", "iMac FireWire",
+ PMAC_TYPE_FW_IMAC, core99_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
+ },
+ { "PowerMac3,1", "PowerMac G4 AGP Graphics",
+ PMAC_TYPE_SAWTOOTH, core99_features,
+ PMAC_MB_OLD_CORE99
+ },
+ { "PowerMac3,2", "PowerMac G4 AGP Graphics",
+ PMAC_TYPE_SAWTOOTH, core99_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
+ },
+ { "PowerMac3,3", "PowerMac G4 AGP Graphics",
+ PMAC_TYPE_SAWTOOTH, core99_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
+ },
+ { "PowerMac3,4", "PowerMac G4 Silver",
+ PMAC_TYPE_QUICKSILVER, core99_features,
+ PMAC_MB_MAY_SLEEP
+ },
+ { "PowerMac3,5", "PowerMac G4 Silver",
+ PMAC_TYPE_QUICKSILVER, core99_features,
+ PMAC_MB_MAY_SLEEP
+ },
+ { "PowerMac3,6", "PowerMac G4 Windtunnel",
+ PMAC_TYPE_WINDTUNNEL, core99_features,
+ PMAC_MB_MAY_SLEEP,
+ },
+ { "PowerMac4,1", "iMac \"Flower Power\"",
+ PMAC_TYPE_PANGEA_IMAC, pangea_features,
+ PMAC_MB_MAY_SLEEP
+ },
+ { "PowerMac4,2", "Flat panel iMac",
+ PMAC_TYPE_FLAT_PANEL_IMAC, pangea_features,
+ PMAC_MB_CAN_SLEEP
+ },
+ { "PowerMac4,4", "eMac",
+ PMAC_TYPE_EMAC, core99_features,
+ PMAC_MB_MAY_SLEEP
+ },
+ { "PowerMac5,1", "PowerMac G4 Cube",
+ PMAC_TYPE_CUBE, core99_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
+ },
+ { "PowerMac6,1", "Flat panel iMac",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP,
+ },
+ { "PowerMac6,3", "Flat panel iMac",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP,
+ },
+ { "PowerMac6,4", "eMac",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP,
+ },
+ { "PowerMac10,1", "Mac mini",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER,
+ },
+ { "iMac,1", "iMac (first generation)",
+ PMAC_TYPE_ORIG_IMAC, paddington_features,
+ 0
+ },
+
+ /*
+ * Xserve's
+ */
+
+ { "RackMac1,1", "XServe",
+ PMAC_TYPE_RACKMAC, rackmac_features,
+ 0,
+ },
+ { "RackMac1,2", "XServe rev. 2",
+ PMAC_TYPE_RACKMAC, rackmac_features,
+ 0,
+ },
+
+ /*
+ * Laptops
+ */
+
+ { "AAPL,3400/2400", "PowerBook 3400",
+ PMAC_TYPE_HOOPER, ohare_features,
+ PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
+ },
+ { "AAPL,3500", "PowerBook 3500",
+ PMAC_TYPE_KANGA, ohare_features,
+ PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
+ },
+ { "AAPL,PowerBook1998", "PowerBook Wallstreet",
+ PMAC_TYPE_WALLSTREET, heathrow_laptop_features,
+ PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
+ },
+ { "PowerBook1,1", "PowerBook 101 (Lombard)",
+ PMAC_TYPE_101_PBOOK, paddington_features,
+ PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
+ },
+ { "PowerBook2,1", "iBook (first generation)",
+ PMAC_TYPE_ORIG_IBOOK, core99_features,
+ PMAC_MB_CAN_SLEEP | PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE
+ },
+ { "PowerBook2,2", "iBook FireWire",
+ PMAC_TYPE_FW_IBOOK, core99_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER |
+ PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE
+ },
+ { "PowerBook3,1", "PowerBook Pismo",
+ PMAC_TYPE_PISMO, core99_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER |
+ PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE
+ },
+ { "PowerBook3,2", "PowerBook Titanium",
+ PMAC_TYPE_TITANIUM, core99_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
+ },
+ { "PowerBook3,3", "PowerBook Titanium II",
+ PMAC_TYPE_TITANIUM2, core99_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
+ },
+ { "PowerBook3,4", "PowerBook Titanium III",
+ PMAC_TYPE_TITANIUM3, core99_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
+ },
+ { "PowerBook3,5", "PowerBook Titanium IV",
+ PMAC_TYPE_TITANIUM4, core99_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
+ },
+ { "PowerBook4,1", "iBook 2",
+ PMAC_TYPE_IBOOK2, pangea_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
+ },
+ { "PowerBook4,2", "iBook 2",
+ PMAC_TYPE_IBOOK2, pangea_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
+ },
+ { "PowerBook4,3", "iBook 2 rev. 2",
+ PMAC_TYPE_IBOOK2, pangea_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
+ },
+ { "PowerBook5,1", "PowerBook G4 17\"",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
+ { "PowerBook5,2", "PowerBook G4 15\"",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
+ { "PowerBook5,3", "PowerBook G4 17\"",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
+ { "PowerBook5,4", "PowerBook G4 15\"",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
+ { "PowerBook5,5", "PowerBook G4 17\"",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
+ { "PowerBook5,6", "PowerBook G4 15\"",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
+ { "PowerBook5,7", "PowerBook G4 17\"",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
+ { "PowerBook6,1", "PowerBook G4 12\"",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
+ { "PowerBook6,2", "PowerBook G4",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
+ { "PowerBook6,3", "iBook G4",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
+ { "PowerBook6,4", "PowerBook G4 12\"",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
+ { "PowerBook6,5", "iBook G4",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
+ { "PowerBook6,7", "iBook G4",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
+ { "PowerBook6,8", "PowerBook G4 12\"",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
+#else /* CONFIG_POWER4 */
+ { "PowerMac7,2", "PowerMac G5",
+ PMAC_TYPE_POWERMAC_G5, g5_features,
+ 0,
+ },
+#ifdef CONFIG_PPC64
+ { "PowerMac7,3", "PowerMac G5",
+ PMAC_TYPE_POWERMAC_G5, g5_features,
+ 0,
+ },
+ { "PowerMac8,1", "iMac G5",
+ PMAC_TYPE_IMAC_G5, g5_features,
+ 0,
+ },
+ { "PowerMac9,1", "PowerMac G5",
+ PMAC_TYPE_POWERMAC_G5_U3L, g5_features,
+ 0,
+ },
+ { "RackMac3,1", "XServe G5",
+ PMAC_TYPE_XSERVE_G5, g5_features,
+ 0,
+ },
+#endif /* CONFIG_PPC64 */
+#endif /* CONFIG_POWER4 */
+};
+
+/*
+ * The toplevel feature_call callback
+ */
+long pmac_do_feature_call(unsigned int selector, ...)
+{
+ struct device_node *node;
+ long param, value;
+ int i;
+ feature_call func = NULL;
+ va_list args;
+
+ if (pmac_mb.features)
+ for (i=0; pmac_mb.features[i].function; i++)
+ if (pmac_mb.features[i].selector == selector) {
+ func = pmac_mb.features[i].function;
+ break;
+ }
+ if (!func)
+ for (i=0; any_features[i].function; i++)
+ if (any_features[i].selector == selector) {
+ func = any_features[i].function;
+ break;
+ }
+ if (!func)
+ return -ENODEV;
+
+ va_start(args, selector);
+ node = (struct device_node*)va_arg(args, void*);
+ param = va_arg(args, long);
+ value = va_arg(args, long);
+ va_end(args);
+
+ return func(node, param, value);
+}
+
+static int __init probe_motherboard(void)
+{
+ int i;
+ struct macio_chip *macio = &macio_chips[0];
+ const char *model = NULL;
+ struct device_node *dt;
+
+ /* Lookup known motherboard type in device-tree. First try an
+ * exact match on the "model" property, then try a "compatible"
+ * match is none is found.
+ */
+ dt = find_devices("device-tree");
+ if (dt != NULL)
+ model = (const char *) get_property(dt, "model", NULL);
+ for(i=0; model && i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) {
+ if (strcmp(model, pmac_mb_defs[i].model_string) == 0) {
+ pmac_mb = pmac_mb_defs[i];
+ goto found;
+ }
+ }
+ for(i=0; i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) {
+ if (machine_is_compatible(pmac_mb_defs[i].model_string)) {
+ pmac_mb = pmac_mb_defs[i];
+ goto found;
+ }
+ }
+
+ /* Fallback to selection depending on mac-io chip type */
+ switch(macio->type) {
+#ifndef CONFIG_POWER4
+ case macio_grand_central:
+ pmac_mb.model_id = PMAC_TYPE_PSURGE;
+ pmac_mb.model_name = "Unknown PowerSurge";
+ break;
+ case macio_ohare:
+ pmac_mb.model_id = PMAC_TYPE_UNKNOWN_OHARE;
+ pmac_mb.model_name = "Unknown OHare-based";
+ break;
+ case macio_heathrow:
+ pmac_mb.model_id = PMAC_TYPE_UNKNOWN_HEATHROW;
+ pmac_mb.model_name = "Unknown Heathrow-based";
+ pmac_mb.features = heathrow_desktop_features;
+ break;
+ case macio_paddington:
+ pmac_mb.model_id = PMAC_TYPE_UNKNOWN_PADDINGTON;
+ pmac_mb.model_name = "Unknown Paddington-based";
+ pmac_mb.features = paddington_features;
+ break;
+ case macio_keylargo:
+ pmac_mb.model_id = PMAC_TYPE_UNKNOWN_CORE99;
+ pmac_mb.model_name = "Unknown Keylargo-based";
+ pmac_mb.features = core99_features;
+ break;
+ case macio_pangea:
+ pmac_mb.model_id = PMAC_TYPE_UNKNOWN_PANGEA;
+ pmac_mb.model_name = "Unknown Pangea-based";
+ pmac_mb.features = pangea_features;
+ break;
+ case macio_intrepid:
+ pmac_mb.model_id = PMAC_TYPE_UNKNOWN_INTREPID;
+ pmac_mb.model_name = "Unknown Intrepid-based";
+ pmac_mb.features = intrepid_features;
+ break;
+#else /* CONFIG_POWER4 */
+ case macio_keylargo2:
+ pmac_mb.model_id = PMAC_TYPE_UNKNOWN_K2;
+ pmac_mb.model_name = "Unknown K2-based";
+ pmac_mb.features = g5_features;
+ break;
+#endif /* CONFIG_POWER4 */
+ default:
+ return -ENODEV;
+ }
+found:
+#ifndef CONFIG_POWER4
+ /* Fixup Hooper vs. Comet */
+ if (pmac_mb.model_id == PMAC_TYPE_HOOPER) {
+ u32 __iomem * mach_id_ptr = ioremap(0xf3000034, 4);
+ if (!mach_id_ptr)
+ return -ENODEV;
+ /* Here, I used to disable the media-bay on comet. It
+ * appears this is wrong, the floppy connector is actually
+ * a kind of media-bay and works with the current driver.
+ */
+ if (__raw_readl(mach_id_ptr) & 0x20000000UL)
+ pmac_mb.model_id = PMAC_TYPE_COMET;
+ iounmap(mach_id_ptr);
+ }
+#endif /* CONFIG_POWER4 */
+
+#ifdef CONFIG_6xx
+ /* Set default value of powersave_nap on machines that support it.
+ * It appears that uninorth rev 3 has a problem with it, we don't
+ * enable it on those. In theory, the flush-on-lock property is
+ * supposed to be set when not supported, but I'm not very confident
+ * that all Apple OF revs did it properly, I do it the paranoid way.
+ */
+ while (uninorth_base && uninorth_rev > 3) {
+ struct device_node *np = find_path_device("/cpus");
+ if (!np || !np->child) {
+ printk(KERN_WARNING "Can't find CPU(s) in device tree !\n");
+ break;
+ }
+ np = np->child;
+ /* Nap mode not supported on SMP */
+ if (np->sibling)
+ break;
+ /* Nap mode not supported if flush-on-lock property is present */
+ if (get_property(np, "flush-on-lock", NULL))
+ break;
+ powersave_nap = 1;
+ printk(KERN_INFO "Processor NAP mode on idle enabled.\n");
+ break;
+ }
+
+ /* On CPUs that support it (750FX), lowspeed by default during
+ * NAP mode
+ */
+ powersave_lowspeed = 1;
+#endif /* CONFIG_6xx */
+#ifdef CONFIG_POWER4
+ powersave_nap = 1;
+#endif
+ /* Check for "mobile" machine */
+ if (model && (strncmp(model, "PowerBook", 9) == 0
+ || strncmp(model, "iBook", 5) == 0))
+ pmac_mb.board_flags |= PMAC_MB_MOBILE;
+
+
+ printk(KERN_INFO "PowerMac motherboard: %s\n", pmac_mb.model_name);
+ return 0;
+}
+
+/* Initialize the Core99 UniNorth host bridge and memory controller
+ */
+static void __init probe_uninorth(void)
+{
+ unsigned long actrl;
+
+ /* Locate core99 Uni-N */
+ uninorth_node = of_find_node_by_name(NULL, "uni-n");
+ /* Locate G5 u3 */
+ if (uninorth_node == NULL) {
+ uninorth_node = of_find_node_by_name(NULL, "u3");
+ uninorth_u3 = 1;
+ }
+ if (uninorth_node && uninorth_node->n_addrs > 0) {
+ unsigned long address = uninorth_node->addrs[0].address;
+ uninorth_base = ioremap(address, 0x40000);
+ uninorth_rev = in_be32(UN_REG(UNI_N_VERSION));
+ if (uninorth_u3)
+ u3_ht = ioremap(address + U3_HT_CONFIG_BASE, 0x1000);
+ } else
+ uninorth_node = NULL;
+
+ if (!uninorth_node)
+ return;
+
+ printk(KERN_INFO "Found %s memory controller & host bridge, revision: %d\n",
+ uninorth_u3 ? "U3" : "UniNorth", uninorth_rev);
+ printk(KERN_INFO "Mapped at 0x%08lx\n", (unsigned long)uninorth_base);
+
+ /* Set the arbitrer QAck delay according to what Apple does
+ */
+ if (uninorth_rev < 0x11) {
+ actrl = UN_IN(UNI_N_ARB_CTRL) & ~UNI_N_ARB_CTRL_QACK_DELAY_MASK;
+ actrl |= ((uninorth_rev < 3) ? UNI_N_ARB_CTRL_QACK_DELAY105 :
+ UNI_N_ARB_CTRL_QACK_DELAY) << UNI_N_ARB_CTRL_QACK_DELAY_SHIFT;
+ UN_OUT(UNI_N_ARB_CTRL, actrl);
+ }
+
+ /* Some more magic as done by them in recent MacOS X on UniNorth
+ * revs 1.5 to 2.O and Pangea. Seem to toggle the UniN Maxbus/PCI
+ * memory timeout
+ */
+ if ((uninorth_rev >= 0x11 && uninorth_rev <= 0x24) || uninorth_rev == 0xc0)
+ UN_OUT(0x2160, UN_IN(0x2160) & 0x00ffffff);
+}
+
+static void __init probe_one_macio(const char *name, const char *compat, int type)
+{
+ struct device_node* node;
+ int i;
+ volatile u32 __iomem * base;
+ u32* revp;
+
+ node = find_devices(name);
+ if (!node || !node->n_addrs)
+ return;
+ if (compat)
+ do {
+ if (device_is_compatible(node, compat))
+ break;
+ node = node->next;
+ } while (node);
+ if (!node)
+ return;
+ for(i=0; i<MAX_MACIO_CHIPS; i++) {
+ if (!macio_chips[i].of_node)
+ break;
+ if (macio_chips[i].of_node == node)
+ return;
+ }
+ if (i >= MAX_MACIO_CHIPS) {
+ printk(KERN_ERR "pmac_feature: Please increase MAX_MACIO_CHIPS !\n");
+ printk(KERN_ERR "pmac_feature: %s skipped\n", node->full_name);
+ return;
+ }
+ base = ioremap(node->addrs[0].address, node->addrs[0].size);
+ if (!base) {
+ printk(KERN_ERR "pmac_feature: Can't map mac-io chip !\n");
+ return;
+ }
+ if (type == macio_keylargo) {
+ u32 *did = (u32 *)get_property(node, "device-id", NULL);
+ if (*did == 0x00000025)
+ type = macio_pangea;
+ if (*did == 0x0000003e)
+ type = macio_intrepid;
+ }
+ macio_chips[i].of_node = node;
+ macio_chips[i].type = type;
+ macio_chips[i].base = base;
+ macio_chips[i].flags = MACIO_FLAG_SCCB_ON | MACIO_FLAG_SCCB_ON;
+ macio_chips[i].name = macio_names[type];
+ revp = (u32 *)get_property(node, "revision-id", NULL);
+ if (revp)
+ macio_chips[i].rev = *revp;
+ printk(KERN_INFO "Found a %s mac-io controller, rev: %d, mapped at 0x%p\n",
+ macio_names[type], macio_chips[i].rev, macio_chips[i].base);
+}
+
+static int __init
+probe_macios(void)
+{
+ /* Warning, ordering is important */
+ probe_one_macio("gc", NULL, macio_grand_central);
+ probe_one_macio("ohare", NULL, macio_ohare);
+ probe_one_macio("pci106b,7", NULL, macio_ohareII);
+ probe_one_macio("mac-io", "keylargo", macio_keylargo);
+ probe_one_macio("mac-io", "paddington", macio_paddington);
+ probe_one_macio("mac-io", "gatwick", macio_gatwick);
+ probe_one_macio("mac-io", "heathrow", macio_heathrow);
+ probe_one_macio("mac-io", "K2-Keylargo", macio_keylargo2);
+
+ /* Make sure the "main" macio chip appear first */
+ if (macio_chips[0].type == macio_gatwick
+ && macio_chips[1].type == macio_heathrow) {
+ struct macio_chip temp = macio_chips[0];
+ macio_chips[0] = macio_chips[1];
+ macio_chips[1] = temp;
+ }
+ if (macio_chips[0].type == macio_ohareII
+ && macio_chips[1].type == macio_ohare) {
+ struct macio_chip temp = macio_chips[0];
+ macio_chips[0] = macio_chips[1];
+ macio_chips[1] = temp;
+ }
+ macio_chips[0].lbus.index = 0;
+ macio_chips[1].lbus.index = 1;
+
+ return (macio_chips[0].of_node == NULL) ? -ENODEV : 0;
+}
+
+static void __init
+initial_serial_shutdown(struct device_node *np)
+{
+ int len;
+ struct slot_names_prop {
+ int count;
+ char name[1];
+ } *slots;
+ char *conn;
+ int port_type = PMAC_SCC_ASYNC;
+ int modem = 0;
+
+ slots = (struct slot_names_prop *)get_property(np, "slot-names", &len);
+ conn = get_property(np, "AAPL,connector", &len);
+ if (conn && (strcmp(conn, "infrared") == 0))
+ port_type = PMAC_SCC_IRDA;
+ else if (device_is_compatible(np, "cobalt"))
+ modem = 1;
+ else if (slots && slots->count > 0) {
+ if (strcmp(slots->name, "IrDA") == 0)
+ port_type = PMAC_SCC_IRDA;
+ else if (strcmp(slots->name, "Modem") == 0)
+ modem = 1;
+ }
+ if (modem)
+ pmac_call_feature(PMAC_FTR_MODEM_ENABLE, np, 0, 0);
+ pmac_call_feature(PMAC_FTR_SCC_ENABLE, np, port_type, 0);
+}
+
+static void __init
+set_initial_features(void)
+{
+ struct device_node *np;
+
+ /* That hack appears to be necessary for some StarMax motherboards
+ * but I'm not too sure it was audited for side-effects on other
+ * ohare based machines...
+ * Since I still have difficulties figuring the right way to
+ * differenciate them all and since that hack was there for a long
+ * time, I'll keep it around
+ */
+ if (macio_chips[0].type == macio_ohare && !find_devices("via-pmu")) {
+ struct macio_chip *macio = &macio_chips[0];
+ MACIO_OUT32(OHARE_FCR, STARMAX_FEATURES);
+ } else if (macio_chips[0].type == macio_ohare) {
+ struct macio_chip *macio = &macio_chips[0];
+ MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE);
+ } else if (macio_chips[1].type == macio_ohare) {
+ struct macio_chip *macio = &macio_chips[1];
+ MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE);
+ }
+
+#ifdef CONFIG_POWER4
+ if (macio_chips[0].type == macio_keylargo2) {
+#ifndef CONFIG_SMP
+ /* On SMP machines running UP, we have the second CPU eating
+ * bus cycles. We need to take it off the bus. This is done
+ * from pmac_smp for SMP kernels running on one CPU
+ */
+ np = of_find_node_by_type(NULL, "cpu");
+ if (np != NULL)
+ np = of_find_node_by_type(np, "cpu");
+ if (np != NULL) {
+ g5_phy_disable_cpu1();
+ of_node_put(np);
+ }
+#endif /* CONFIG_SMP */
+ /* Enable GMAC for now for PCI probing. It will be disabled
+ * later on after PCI probe
+ */
+ np = of_find_node_by_name(NULL, "ethernet");
+ while(np) {
+ if (device_is_compatible(np, "K2-GMAC"))
+ g5_gmac_enable(np, 0, 1);
+ np = of_find_node_by_name(np, "ethernet");
+ }
+
+ /* Enable FW before PCI probe. Will be disabled later on
+ * Note: We should have a batter way to check that we are
+ * dealing with uninorth internal cell and not a PCI cell
+ * on the external PCI. The code below works though.
+ */
+ np = of_find_node_by_name(NULL, "firewire");
+ while(np) {
+ if (device_is_compatible(np, "pci106b,5811")) {
+ macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED;
+ g5_fw_enable(np, 0, 1);
+ }
+ np = of_find_node_by_name(np, "firewire");
+ }
+ }
+#else /* CONFIG_POWER4 */
+
+ if (macio_chips[0].type == macio_keylargo ||
+ macio_chips[0].type == macio_pangea ||
+ macio_chips[0].type == macio_intrepid) {
+ /* Enable GMAC for now for PCI probing. It will be disabled
+ * later on after PCI probe
+ */
+ np = of_find_node_by_name(NULL, "ethernet");
+ while(np) {
+ if (np->parent
+ && device_is_compatible(np->parent, "uni-north")
+ && device_is_compatible(np, "gmac"))
+ core99_gmac_enable(np, 0, 1);
+ np = of_find_node_by_name(np, "ethernet");
+ }
+
+ /* Enable FW before PCI probe. Will be disabled later on
+ * Note: We should have a batter way to check that we are
+ * dealing with uninorth internal cell and not a PCI cell
+ * on the external PCI. The code below works though.
+ */
+ np = of_find_node_by_name(NULL, "firewire");
+ while(np) {
+ if (np->parent
+ && device_is_compatible(np->parent, "uni-north")
+ && (device_is_compatible(np, "pci106b,18") ||
+ device_is_compatible(np, "pci106b,30") ||
+ device_is_compatible(np, "pci11c1,5811"))) {
+ macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED;
+ core99_firewire_enable(np, 0, 1);
+ }
+ np = of_find_node_by_name(np, "firewire");
+ }
+
+ /* Enable ATA-100 before PCI probe. */
+ np = of_find_node_by_name(NULL, "ata-6");
+ while(np) {
+ if (np->parent
+ && device_is_compatible(np->parent, "uni-north")
+ && device_is_compatible(np, "kauai-ata")) {
+ core99_ata100_enable(np, 1);
+ }
+ np = of_find_node_by_name(np, "ata-6");
+ }
+
+ /* Switch airport off */
+ np = find_devices("radio");
+ while(np) {
+ if (np && np->parent == macio_chips[0].of_node) {
+ macio_chips[0].flags |= MACIO_FLAG_AIRPORT_ON;
+ core99_airport_enable(np, 0, 0);
+ }
+ np = np->next;
+ }
+ }
+
+ /* On all machines that support sound PM, switch sound off */
+ if (macio_chips[0].of_node)
+ pmac_do_feature_call(PMAC_FTR_SOUND_CHIP_ENABLE,
+ macio_chips[0].of_node, 0, 0);
+
+ /* While on some desktop G3s, we turn it back on */
+ if (macio_chips[0].of_node && macio_chips[0].type == macio_heathrow
+ && (pmac_mb.model_id == PMAC_TYPE_GOSSAMER ||
+ pmac_mb.model_id == PMAC_TYPE_SILK)) {
+ struct macio_chip *macio = &macio_chips[0];
+ MACIO_BIS(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
+ MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N);
+ }
+
+ /* Some machine models need the clock chip to be properly setup for
+ * clock spreading now. This should be a platform function but we
+ * don't do these at the moment
+ */
+ pmac_tweak_clock_spreading(1);
+
+#endif /* CONFIG_POWER4 */
+
+ /* On all machines, switch modem & serial ports off */
+ np = find_devices("ch-a");
+ while(np) {
+ initial_serial_shutdown(np);
+ np = np->next;
+ }
+ np = find_devices("ch-b");
+ while(np) {
+ initial_serial_shutdown(np);
+ np = np->next;
+ }
+}
+
+void __init
+pmac_feature_init(void)
+{
+ /* Detect the UniNorth memory controller */
+ probe_uninorth();
+
+ /* Probe mac-io controllers */
+ if (probe_macios()) {
+ printk(KERN_WARNING "No mac-io chip found\n");
+ return;
+ }
+
+ /* Setup low-level i2c stuffs */
+ pmac_init_low_i2c();
+
+ /* Probe machine type */
+ if (probe_motherboard())
+ printk(KERN_WARNING "Unknown PowerMac !\n");
+
+ /* Set some initial features (turn off some chips that will
+ * be later turned on)
+ */
+ set_initial_features();
+}
+
+int __init pmac_feature_late_init(void)
+{
+#if 0
+ struct device_node *np;
+
+ /* Request some resources late */
+ if (uninorth_node)
+ request_OF_resource(uninorth_node, 0, NULL);
+ np = find_devices("hammerhead");
+ if (np)
+ request_OF_resource(np, 0, NULL);
+ np = find_devices("interrupt-controller");
+ if (np)
+ request_OF_resource(np, 0, NULL);
+#endif
+ return 0;
+}
+
+device_initcall(pmac_feature_late_init);
+
+#if 0
+static void dump_HT_speeds(char *name, u32 cfg, u32 frq)
+{
+ int freqs[16] = { 200,300,400,500,600,800,1000,0,0,0,0,0,0,0,0,0 };
+ int bits[8] = { 8,16,0,32,2,4,0,0 };
+ int freq = (frq >> 8) & 0xf;
+
+ if (freqs[freq] == 0)
+ printk("%s: Unknown HT link frequency %x\n", name, freq);
+ else
+ printk("%s: %d MHz on main link, (%d in / %d out) bits width\n",
+ name, freqs[freq],
+ bits[(cfg >> 28) & 0x7], bits[(cfg >> 24) & 0x7]);
+}
+
+void __init pmac_check_ht_link(void)
+{
+ u32 ufreq, freq, ucfg, cfg;
+ struct device_node *pcix_node;
+ u8 px_bus, px_devfn;
+ struct pci_controller *px_hose;
+
+ (void)in_be32(u3_ht + U3_HT_LINK_COMMAND);
+ ucfg = cfg = in_be32(u3_ht + U3_HT_LINK_CONFIG);
+ ufreq = freq = in_be32(u3_ht + U3_HT_LINK_FREQ);
+ dump_HT_speeds("U3 HyperTransport", cfg, freq);
+
+ pcix_node = of_find_compatible_node(NULL, "pci", "pci-x");
+ if (pcix_node == NULL) {
+ printk("No PCI-X bridge found\n");
+ return;
+ }
+ if (pci_device_from_OF_node(pcix_node, &px_bus, &px_devfn) != 0) {
+ printk("PCI-X bridge found but not matched to pci\n");
+ return;
+ }
+ px_hose = pci_find_hose_for_OF_device(pcix_node);
+ if (px_hose == NULL) {
+ printk("PCI-X bridge found but not matched to host\n");
+ return;
+ }
+ early_read_config_dword(px_hose, px_bus, px_devfn, 0xc4, &cfg);
+ early_read_config_dword(px_hose, px_bus, px_devfn, 0xcc, &freq);
+ dump_HT_speeds("PCI-X HT Uplink", cfg, freq);
+ early_read_config_dword(px_hose, px_bus, px_devfn, 0xc8, &cfg);
+ early_read_config_dword(px_hose, px_bus, px_devfn, 0xd0, &freq);
+ dump_HT_speeds("PCI-X HT Downlink", cfg, freq);
+}
+#endif /* 0 */
+
+/*
+ * Early video resume hook
+ */
+
+static void (*pmac_early_vresume_proc)(void *data);
+static void *pmac_early_vresume_data;
+
+void pmac_set_early_video_resume(void (*proc)(void *data), void *data)
+{
+ if (_machine != _MACH_Pmac)
+ return;
+ preempt_disable();
+ pmac_early_vresume_proc = proc;
+ pmac_early_vresume_data = data;
+ preempt_enable();
+}
+EXPORT_SYMBOL(pmac_set_early_video_resume);
+
+void pmac_call_early_video_resume(void)
+{
+ if (pmac_early_vresume_proc)
+ pmac_early_vresume_proc(pmac_early_vresume_data);
+}
+
+/*
+ * AGP related suspend/resume code
+ */
+
+static struct pci_dev *pmac_agp_bridge;
+static int (*pmac_agp_suspend)(struct pci_dev *bridge);
+static int (*pmac_agp_resume)(struct pci_dev *bridge);
+
+void pmac_register_agp_pm(struct pci_dev *bridge,
+ int (*suspend)(struct pci_dev *bridge),
+ int (*resume)(struct pci_dev *bridge))
+{
+ if (suspend || resume) {
+ pmac_agp_bridge = bridge;
+ pmac_agp_suspend = suspend;
+ pmac_agp_resume = resume;
+ return;
+ }
+ if (bridge != pmac_agp_bridge)
+ return;
+ pmac_agp_suspend = pmac_agp_resume = NULL;
+ return;
+}
+EXPORT_SYMBOL(pmac_register_agp_pm);
+
+void pmac_suspend_agp_for_card(struct pci_dev *dev)
+{
+ if (pmac_agp_bridge == NULL || pmac_agp_suspend == NULL)
+ return;
+ if (pmac_agp_bridge->bus != dev->bus)
+ return;
+ pmac_agp_suspend(pmac_agp_bridge);
+}
+EXPORT_SYMBOL(pmac_suspend_agp_for_card);
+
+void pmac_resume_agp_for_card(struct pci_dev *dev)
+{
+ if (pmac_agp_bridge == NULL || pmac_agp_resume == NULL)
+ return;
+ if (pmac_agp_bridge->bus != dev->bus)
+ return;
+ pmac_agp_resume(pmac_agp_bridge);
+}
+EXPORT_SYMBOL(pmac_resume_agp_for_card);
diff --git a/arch/ppc64/kernel/pmac_low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c
index f3f39e8e337a..f3f39e8e337a 100644
--- a/arch/ppc64/kernel/pmac_low_i2c.c
+++ b/arch/powerpc/platforms/powermac/low_i2c.c
diff --git a/arch/ppc64/kernel/pmac_nvram.c b/arch/powerpc/platforms/powermac/nvram.c
index e32a902236e3..4042e2f06ee0 100644
--- a/arch/ppc64/kernel/pmac_nvram.c
+++ b/arch/powerpc/platforms/powermac/nvram.c
@@ -15,10 +15,13 @@
#include <linux/kernel.h>
#include <linux/stddef.h>
#include <linux/string.h>
+#include <linux/nvram.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/errno.h>
+#include <linux/adb.h>
+#include <linux/pmu.h>
#include <linux/bootmem.h>
#include <linux/completion.h>
#include <linux/spinlock.h>
@@ -72,20 +75,38 @@ struct core99_header {
/*
* Read and write the non-volatile RAM on PowerMacs and CHRP machines.
*/
+static int nvram_naddrs;
static volatile unsigned char *nvram_data;
+static int is_core_99;
static int core99_bank = 0;
+static int nvram_partitions[3];
// XXX Turn that into a sem
static DEFINE_SPINLOCK(nv_lock);
+extern int pmac_newworld;
extern int system_running;
static int (*core99_write_bank)(int bank, u8* datas);
static int (*core99_erase_bank)(int bank);
-static char *nvram_image __pmacdata;
+static char *nvram_image;
-static ssize_t __pmac core99_nvram_read(char *buf, size_t count, loff_t *index)
+static unsigned char core99_nvram_read_byte(int addr)
+{
+ if (nvram_image == NULL)
+ return 0xff;
+ return nvram_image[addr];
+}
+
+static void core99_nvram_write_byte(int addr, unsigned char val)
+{
+ if (nvram_image == NULL)
+ return;
+ nvram_image[addr] = val;
+}
+
+static ssize_t core99_nvram_read(char *buf, size_t count, loff_t *index)
{
int i;
@@ -103,7 +124,7 @@ static ssize_t __pmac core99_nvram_read(char *buf, size_t count, loff_t *index)
return count;
}
-static ssize_t __pmac core99_nvram_write(char *buf, size_t count, loff_t *index)
+static ssize_t core99_nvram_write(char *buf, size_t count, loff_t *index)
{
int i;
@@ -121,14 +142,95 @@ static ssize_t __pmac core99_nvram_write(char *buf, size_t count, loff_t *index)
return count;
}
-static ssize_t __pmac core99_nvram_size(void)
+static ssize_t core99_nvram_size(void)
{
if (nvram_image == NULL)
return -ENODEV;
return NVRAM_SIZE;
}
-static u8 __pmac chrp_checksum(struct chrp_header* hdr)
+#ifdef CONFIG_PPC32
+static volatile unsigned char *nvram_addr;
+static int nvram_mult;
+
+static unsigned char direct_nvram_read_byte(int addr)
+{
+ return in_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult]);
+}
+
+static void direct_nvram_write_byte(int addr, unsigned char val)
+{
+ out_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult], val);
+}
+
+
+static unsigned char indirect_nvram_read_byte(int addr)
+{
+ unsigned char val;
+ unsigned long flags;
+
+ spin_lock_irqsave(&nv_lock, flags);
+ out_8(nvram_addr, addr >> 5);
+ val = in_8(&nvram_data[(addr & 0x1f) << 4]);
+ spin_unlock_irqrestore(&nv_lock, flags);
+
+ return val;
+}
+
+static void indirect_nvram_write_byte(int addr, unsigned char val)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&nv_lock, flags);
+ out_8(nvram_addr, addr >> 5);
+ out_8(&nvram_data[(addr & 0x1f) << 4], val);
+ spin_unlock_irqrestore(&nv_lock, flags);
+}
+
+
+#ifdef CONFIG_ADB_PMU
+
+static void pmu_nvram_complete(struct adb_request *req)
+{
+ if (req->arg)
+ complete((struct completion *)req->arg);
+}
+
+static unsigned char pmu_nvram_read_byte(int addr)
+{
+ struct adb_request req;
+ DECLARE_COMPLETION(req_complete);
+
+ req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL;
+ if (pmu_request(&req, pmu_nvram_complete, 3, PMU_READ_NVRAM,
+ (addr >> 8) & 0xff, addr & 0xff))
+ return 0xff;
+ if (system_state == SYSTEM_RUNNING)
+ wait_for_completion(&req_complete);
+ while (!req.complete)
+ pmu_poll();
+ return req.reply[0];
+}
+
+static void pmu_nvram_write_byte(int addr, unsigned char val)
+{
+ struct adb_request req;
+ DECLARE_COMPLETION(req_complete);
+
+ req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL;
+ if (pmu_request(&req, pmu_nvram_complete, 4, PMU_WRITE_NVRAM,
+ (addr >> 8) & 0xff, addr & 0xff, val))
+ return;
+ if (system_state == SYSTEM_RUNNING)
+ wait_for_completion(&req_complete);
+ while (!req.complete)
+ pmu_poll();
+}
+
+#endif /* CONFIG_ADB_PMU */
+#endif /* CONFIG_PPC32 */
+
+static u8 chrp_checksum(struct chrp_header* hdr)
{
u8 *ptr;
u16 sum = hdr->signature;
@@ -139,7 +241,7 @@ static u8 __pmac chrp_checksum(struct chrp_header* hdr)
return sum;
}
-static u32 __pmac core99_calc_adler(u8 *buffer)
+static u32 core99_calc_adler(u8 *buffer)
{
int cnt;
u32 low, high;
@@ -161,7 +263,7 @@ static u32 __pmac core99_calc_adler(u8 *buffer)
return (high << 16) | low;
}
-static u32 __pmac core99_check(u8* datas)
+static u32 core99_check(u8* datas)
{
struct core99_header* hdr99 = (struct core99_header*)datas;
@@ -180,7 +282,7 @@ static u32 __pmac core99_check(u8* datas)
return hdr99->generation;
}
-static int __pmac sm_erase_bank(int bank)
+static int sm_erase_bank(int bank)
{
int stat, i;
unsigned long timeout;
@@ -194,7 +296,7 @@ static int __pmac sm_erase_bank(int bank)
timeout = 0;
do {
if (++timeout > 1000000) {
- printk(KERN_ERR "nvram: Sharp/Miron flash erase timeout !\n");
+ printk(KERN_ERR "nvram: Sharp/Micron flash erase timeout !\n");
break;
}
out_8(base, SM_FLASH_CMD_READ_STATUS);
@@ -212,7 +314,7 @@ static int __pmac sm_erase_bank(int bank)
return 0;
}
-static int __pmac sm_write_bank(int bank, u8* datas)
+static int sm_write_bank(int bank, u8* datas)
{
int i, stat = 0;
unsigned long timeout;
@@ -247,7 +349,7 @@ static int __pmac sm_write_bank(int bank, u8* datas)
return 0;
}
-static int __pmac amd_erase_bank(int bank)
+static int amd_erase_bank(int bank)
{
int i, stat = 0;
unsigned long timeout;
@@ -294,7 +396,7 @@ static int __pmac amd_erase_bank(int bank)
return 0;
}
-static int __pmac amd_write_bank(int bank, u8* datas)
+static int amd_write_bank(int bank, u8* datas)
{
int i, stat = 0;
unsigned long timeout;
@@ -340,12 +442,49 @@ static int __pmac amd_write_bank(int bank, u8* datas)
return 0;
}
+static void __init lookup_partitions(void)
+{
+ u8 buffer[17];
+ int i, offset;
+ struct chrp_header* hdr;
+
+ if (pmac_newworld) {
+ nvram_partitions[pmac_nvram_OF] = -1;
+ nvram_partitions[pmac_nvram_XPRAM] = -1;
+ nvram_partitions[pmac_nvram_NR] = -1;
+ hdr = (struct chrp_header *)buffer;
+
+ offset = 0;
+ buffer[16] = 0;
+ do {
+ for (i=0;i<16;i++)
+ buffer[i] = ppc_md.nvram_read_val(offset+i);
+ if (!strcmp(hdr->name, "common"))
+ nvram_partitions[pmac_nvram_OF] = offset + 0x10;
+ if (!strcmp(hdr->name, "APL,MacOS75")) {
+ nvram_partitions[pmac_nvram_XPRAM] = offset + 0x10;
+ nvram_partitions[pmac_nvram_NR] = offset + 0x110;
+ }
+ offset += (hdr->len * 0x10);
+ } while(offset < NVRAM_SIZE);
+ } else {
+ nvram_partitions[pmac_nvram_OF] = 0x1800;
+ nvram_partitions[pmac_nvram_XPRAM] = 0x1300;
+ nvram_partitions[pmac_nvram_NR] = 0x1400;
+ }
+ DBG("nvram: OF partition at 0x%x\n", nvram_partitions[pmac_nvram_OF]);
+ DBG("nvram: XP partition at 0x%x\n", nvram_partitions[pmac_nvram_XPRAM]);
+ DBG("nvram: NR partition at 0x%x\n", nvram_partitions[pmac_nvram_NR]);
+}
-static int __pmac core99_nvram_sync(void)
+static void core99_nvram_sync(void)
{
struct core99_header* hdr99;
unsigned long flags;
+ if (!is_core_99 || !nvram_data || !nvram_image)
+ return;
+
spin_lock_irqsave(&nv_lock, flags);
if (!memcmp(nvram_image, (u8*)nvram_data + core99_bank*NVRAM_SIZE,
NVRAM_SIZE))
@@ -370,32 +509,28 @@ static int __pmac core99_nvram_sync(void)
bail:
spin_unlock_irqrestore(&nv_lock, flags);
- return 0;
+#ifdef DEBUG
+ mdelay(2000);
+#endif
}
-int __init pmac_nvram_init(void)
+static int __init core99_nvram_setup(struct device_node *dp)
{
- struct device_node *dp;
- u32 gen_bank0, gen_bank1;
int i;
+ u32 gen_bank0, gen_bank1;
- dp = find_devices("nvram");
- if (dp == NULL) {
- printk(KERN_ERR "Can't find NVRAM device\n");
- return -ENODEV;
- }
- if (!device_is_compatible(dp, "nvram,flash")) {
- printk(KERN_ERR "Incompatible type of NVRAM\n");
- return -ENXIO;
+ if (nvram_naddrs < 1) {
+ printk(KERN_ERR "nvram: no address\n");
+ return -EINVAL;
}
-
nvram_image = alloc_bootmem(NVRAM_SIZE);
if (nvram_image == NULL) {
printk(KERN_ERR "nvram: can't allocate ram image\n");
return -ENOMEM;
}
nvram_data = ioremap(dp->addrs[0].address, NVRAM_SIZE*2);
-
+ nvram_naddrs = 1; /* Make sure we get the correct case */
+
DBG("nvram: Checking bank 0...\n");
gen_bank0 = core99_check((u8 *)nvram_data);
@@ -408,11 +543,12 @@ int __init pmac_nvram_init(void)
for (i=0; i<NVRAM_SIZE; i++)
nvram_image[i] = nvram_data[i + core99_bank*NVRAM_SIZE];
+ ppc_md.nvram_read_val = core99_nvram_read_byte;
+ ppc_md.nvram_write_val = core99_nvram_write_byte;
ppc_md.nvram_read = core99_nvram_read;
ppc_md.nvram_write = core99_nvram_write;
ppc_md.nvram_size = core99_nvram_size;
ppc_md.nvram_sync = core99_nvram_sync;
-
/*
* Maybe we could be smarter here though making an exclusive list
* of known flash chips is a bit nasty as older OF didn't provide us
@@ -427,67 +563,81 @@ int __init pmac_nvram_init(void)
core99_erase_bank = sm_erase_bank;
core99_write_bank = sm_write_bank;
}
-
return 0;
}
-int __pmac pmac_get_partition(int partition)
+int __init pmac_nvram_init(void)
{
- struct nvram_partition *part;
- const char *name;
- int sig;
-
- switch(partition) {
- case pmac_nvram_OF:
- name = "common";
- sig = NVRAM_SIG_SYS;
- break;
- case pmac_nvram_XPRAM:
- name = "APL,MacOS75";
- sig = NVRAM_SIG_OS;
- break;
- case pmac_nvram_NR:
- default:
- /* Oldworld stuff */
+ struct device_node *dp;
+ int err = 0;
+
+ nvram_naddrs = 0;
+
+ dp = find_devices("nvram");
+ if (dp == NULL) {
+ printk(KERN_ERR "Can't find NVRAM device\n");
return -ENODEV;
}
+ nvram_naddrs = dp->n_addrs;
+ is_core_99 = device_is_compatible(dp, "nvram,flash");
+ if (is_core_99)
+ err = core99_nvram_setup(dp);
+#ifdef CONFIG_PPC32
+ else if (_machine == _MACH_chrp && nvram_naddrs == 1) {
+ nvram_data = ioremap(dp->addrs[0].address + isa_mem_base,
+ dp->addrs[0].size);
+ nvram_mult = 1;
+ ppc_md.nvram_read_val = direct_nvram_read_byte;
+ ppc_md.nvram_write_val = direct_nvram_write_byte;
+ } else if (nvram_naddrs == 1) {
+ nvram_data = ioremap(dp->addrs[0].address, dp->addrs[0].size);
+ nvram_mult = (dp->addrs[0].size + NVRAM_SIZE - 1) / NVRAM_SIZE;
+ ppc_md.nvram_read_val = direct_nvram_read_byte;
+ ppc_md.nvram_write_val = direct_nvram_write_byte;
+ } else if (nvram_naddrs == 2) {
+ nvram_addr = ioremap(dp->addrs[0].address, dp->addrs[0].size);
+ nvram_data = ioremap(dp->addrs[1].address, dp->addrs[1].size);
+ ppc_md.nvram_read_val = indirect_nvram_read_byte;
+ ppc_md.nvram_write_val = indirect_nvram_write_byte;
+ } else if (nvram_naddrs == 0 && sys_ctrler == SYS_CTRLER_PMU) {
+#ifdef CONFIG_ADB_PMU
+ nvram_naddrs = -1;
+ ppc_md.nvram_read_val = pmu_nvram_read_byte;
+ ppc_md.nvram_write_val = pmu_nvram_write_byte;
+#endif /* CONFIG_ADB_PMU */
+ }
+#endif
+ else {
+ printk(KERN_ERR "Incompatible type of NVRAM\n");
+ return -ENXIO;
+ }
+ lookup_partitions();
+ return err;
+}
- part = nvram_find_partition(sig, name);
- if (part == NULL)
- return 0;
-
- return part->index;
+int pmac_get_partition(int partition)
+{
+ return nvram_partitions[partition];
}
-u8 __pmac pmac_xpram_read(int xpaddr)
+u8 pmac_xpram_read(int xpaddr)
{
int offset = pmac_get_partition(pmac_nvram_XPRAM);
- loff_t index;
- u8 buf;
- ssize_t count;
if (offset < 0 || xpaddr < 0 || xpaddr > 0x100)
return 0xff;
- index = offset + xpaddr;
- count = ppc_md.nvram_read(&buf, 1, &index);
- if (count != 1)
- return 0xff;
- return buf;
+ return ppc_md.nvram_read_val(xpaddr + offset);
}
-void __pmac pmac_xpram_write(int xpaddr, u8 data)
+void pmac_xpram_write(int xpaddr, u8 data)
{
int offset = pmac_get_partition(pmac_nvram_XPRAM);
- loff_t index;
- u8 buf;
if (offset < 0 || xpaddr < 0 || xpaddr > 0x100)
return;
- index = offset + xpaddr;
- buf = data;
- ppc_md.nvram_write(&buf, 1, &index);
+ ppc_md.nvram_write_val(xpaddr + offset, data);
}
EXPORT_SYMBOL(pmac_get_partition);
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
new file mode 100644
index 000000000000..8f818d092e2b
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -0,0 +1,1170 @@
+/*
+ * Support for PCI bridges found on Power Macintoshes.
+ *
+ * Copyright (C) 2003 Benjamin Herrenschmuidt (benh@kernel.crashing.org)
+ * Copyright (C) 1997 Paul Mackerras (paulus@samba.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/kernel.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+
+#include <asm/sections.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/machdep.h>
+#include <asm/pmac_feature.h>
+#include <asm/grackle.h>
+#ifdef CONFIG_PPC64
+#include <asm/iommu.h>
+#include <asm/ppc-pci.h>
+#endif
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+static int add_bridge(struct device_node *dev);
+
+/* XXX Could be per-controller, but I don't think we risk anything by
+ * assuming we won't have both UniNorth and Bandit */
+static int has_uninorth;
+#ifdef CONFIG_PPC64
+static struct pci_controller *u3_agp;
+static struct pci_controller *u3_ht;
+#endif /* CONFIG_PPC64 */
+
+extern u8 pci_cache_line_size;
+extern int pcibios_assign_bus_offset;
+
+struct device_node *k2_skiplist[2];
+
+/*
+ * Magic constants for enabling cache coherency in the bandit/PSX bridge.
+ */
+#define BANDIT_DEVID_2 8
+#define BANDIT_REVID 3
+
+#define BANDIT_DEVNUM 11
+#define BANDIT_MAGIC 0x50
+#define BANDIT_COHERENT 0x40
+
+static int __init fixup_one_level_bus_range(struct device_node *node, int higher)
+{
+ for (; node != 0;node = node->sibling) {
+ int * bus_range;
+ unsigned int *class_code;
+ int len;
+
+ /* For PCI<->PCI bridges or CardBus bridges, we go down */
+ class_code = (unsigned int *) get_property(node, "class-code", NULL);
+ if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
+ (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
+ continue;
+ bus_range = (int *) get_property(node, "bus-range", &len);
+ if (bus_range != NULL && len > 2 * sizeof(int)) {
+ if (bus_range[1] > higher)
+ higher = bus_range[1];
+ }
+ higher = fixup_one_level_bus_range(node->child, higher);
+ }
+ return higher;
+}
+
+/* This routine fixes the "bus-range" property of all bridges in the
+ * system since they tend to have their "last" member wrong on macs
+ *
+ * Note that the bus numbers manipulated here are OF bus numbers, they
+ * are not Linux bus numbers.
+ */
+static void __init fixup_bus_range(struct device_node *bridge)
+{
+ int * bus_range;
+ int len;
+
+ /* Lookup the "bus-range" property for the hose */
+ bus_range = (int *) get_property(bridge, "bus-range", &len);
+ if (bus_range == NULL || len < 2 * sizeof(int)) {
+ printk(KERN_WARNING "Can't get bus-range for %s\n",
+ bridge->full_name);
+ return;
+ }
+ bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]);
+}
+
+/*
+ * Apple MacRISC (U3, UniNorth, Bandit, Chaos) PCI controllers.
+ *
+ * The "Bandit" version is present in all early PCI PowerMacs,
+ * and up to the first ones using Grackle. Some machines may
+ * have 2 bandit controllers (2 PCI busses).
+ *
+ * "Chaos" is used in some "Bandit"-type machines as a bridge
+ * for the separate display bus. It is accessed the same
+ * way as bandit, but cannot be probed for devices. It therefore
+ * has its own config access functions.
+ *
+ * The "UniNorth" version is present in all Core99 machines
+ * (iBook, G4, new IMacs, and all the recent Apple machines).
+ * It contains 3 controllers in one ASIC.
+ *
+ * The U3 is the bridge used on G5 machines. It contains an
+ * AGP bus which is dealt with the old UniNorth access routines
+ * and a HyperTransport bus which uses its own set of access
+ * functions.
+ */
+
+#define MACRISC_CFA0(devfn, off) \
+ ((1 << (unsigned long)PCI_SLOT(dev_fn)) \
+ | (((unsigned long)PCI_FUNC(dev_fn)) << 8) \
+ | (((unsigned long)(off)) & 0xFCUL))
+
+#define MACRISC_CFA1(bus, devfn, off) \
+ ((((unsigned long)(bus)) << 16) \
+ |(((unsigned long)(devfn)) << 8) \
+ |(((unsigned long)(off)) & 0xFCUL) \
+ |1UL)
+
+static unsigned long macrisc_cfg_access(struct pci_controller* hose,
+ u8 bus, u8 dev_fn, u8 offset)
+{
+ unsigned int caddr;
+
+ if (bus == hose->first_busno) {
+ if (dev_fn < (11 << 3))
+ return 0;
+ caddr = MACRISC_CFA0(dev_fn, offset);
+ } else
+ caddr = MACRISC_CFA1(bus, dev_fn, offset);
+
+ /* Uninorth will return garbage if we don't read back the value ! */
+ do {
+ out_le32(hose->cfg_addr, caddr);
+ } while (in_le32(hose->cfg_addr) != caddr);
+
+ offset &= has_uninorth ? 0x07 : 0x03;
+ return ((unsigned long)hose->cfg_data) + offset;
+}
+
+static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn,
+ int offset, int len, u32 *val)
+{
+ struct pci_controller *hose;
+ unsigned long addr;
+
+ hose = pci_bus_to_host(bus);
+ if (hose == NULL)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ addr = macrisc_cfg_access(hose, bus->number, devfn, offset);
+ if (!addr)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ /*
+ * Note: the caller has already checked that offset is
+ * suitably aligned and that len is 1, 2 or 4.
+ */
+ switch (len) {
+ case 1:
+ *val = in_8((u8 *)addr);
+ break;
+ case 2:
+ *val = in_le16((u16 *)addr);
+ break;
+ default:
+ *val = in_le32((u32 *)addr);
+ break;
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int macrisc_write_config(struct pci_bus *bus, unsigned int devfn,
+ int offset, int len, u32 val)
+{
+ struct pci_controller *hose;
+ unsigned long addr;
+
+ hose = pci_bus_to_host(bus);
+ if (hose == NULL)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ addr = macrisc_cfg_access(hose, bus->number, devfn, offset);
+ if (!addr)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ /*
+ * Note: the caller has already checked that offset is
+ * suitably aligned and that len is 1, 2 or 4.
+ */
+ switch (len) {
+ case 1:
+ out_8((u8 *)addr, val);
+ (void) in_8((u8 *)addr);
+ break;
+ case 2:
+ out_le16((u16 *)addr, val);
+ (void) in_le16((u16 *)addr);
+ break;
+ default:
+ out_le32((u32 *)addr, val);
+ (void) in_le32((u32 *)addr);
+ break;
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops macrisc_pci_ops =
+{
+ macrisc_read_config,
+ macrisc_write_config
+};
+
+#ifdef CONFIG_PPC32
+/*
+ * Verify that a specific (bus, dev_fn) exists on chaos
+ */
+static int
+chaos_validate_dev(struct pci_bus *bus, int devfn, int offset)
+{
+ struct device_node *np;
+ u32 *vendor, *device;
+
+ np = pci_busdev_to_OF_node(bus, devfn);
+ if (np == NULL)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ vendor = (u32 *)get_property(np, "vendor-id", NULL);
+ device = (u32 *)get_property(np, "device-id", NULL);
+ if (vendor == NULL || device == NULL)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ if ((*vendor == 0x106b) && (*device == 3) && (offset >= 0x10)
+ && (offset != 0x14) && (offset != 0x18) && (offset <= 0x24))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+chaos_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
+ int len, u32 *val)
+{
+ int result = chaos_validate_dev(bus, devfn, offset);
+ if (result == PCIBIOS_BAD_REGISTER_NUMBER)
+ *val = ~0U;
+ if (result != PCIBIOS_SUCCESSFUL)
+ return result;
+ return macrisc_read_config(bus, devfn, offset, len, val);
+}
+
+static int
+chaos_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
+ int len, u32 val)
+{
+ int result = chaos_validate_dev(bus, devfn, offset);
+ if (result != PCIBIOS_SUCCESSFUL)
+ return result;
+ return macrisc_write_config(bus, devfn, offset, len, val);
+}
+
+static struct pci_ops chaos_pci_ops =
+{
+ chaos_read_config,
+ chaos_write_config
+};
+
+static void __init setup_chaos(struct pci_controller *hose,
+ struct reg_property *addr)
+{
+ /* assume a `chaos' bridge */
+ hose->ops = &chaos_pci_ops;
+ hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000);
+ hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000);
+}
+#else
+#define setup_chaos(hose, addr)
+#endif /* CONFIG_PPC32 */
+
+#ifdef CONFIG_PPC64
+/*
+ * These versions of U3 HyperTransport config space access ops do not
+ * implement self-view of the HT host yet
+ */
+
+/*
+ * This function deals with some "special cases" devices.
+ *
+ * 0 -> No special case
+ * 1 -> Skip the device but act as if the access was successfull
+ * (return 0xff's on reads, eventually, cache config space
+ * accesses in a later version)
+ * -1 -> Hide the device (unsuccessful acess)
+ */
+static int u3_ht_skip_device(struct pci_controller *hose,
+ struct pci_bus *bus, unsigned int devfn)
+{
+ struct device_node *busdn, *dn;
+ int i;
+
+ /* We only allow config cycles to devices that are in OF device-tree
+ * as we are apparently having some weird things going on with some
+ * revs of K2 on recent G5s
+ */
+ if (bus->self)
+ busdn = pci_device_to_OF_node(bus->self);
+ else
+ busdn = hose->arch_data;
+ for (dn = busdn->child; dn; dn = dn->sibling)
+ if (dn->data && PCI_DN(dn)->devfn == devfn)
+ break;
+ if (dn == NULL)
+ return -1;
+
+ /*
+ * When a device in K2 is powered down, we die on config
+ * cycle accesses. Fix that here.
+ */
+ for (i=0; i<2; i++)
+ if (k2_skiplist[i] == dn)
+ return 1;
+
+ return 0;
+}
+
+#define U3_HT_CFA0(devfn, off) \
+ ((((unsigned long)devfn) << 8) | offset)
+#define U3_HT_CFA1(bus, devfn, off) \
+ (U3_HT_CFA0(devfn, off) \
+ + (((unsigned long)bus) << 16) \
+ + 0x01000000UL)
+
+static unsigned long u3_ht_cfg_access(struct pci_controller* hose,
+ u8 bus, u8 devfn, u8 offset)
+{
+ if (bus == hose->first_busno) {
+ /* For now, we don't self probe U3 HT bridge */
+ if (PCI_SLOT(devfn) == 0)
+ return 0;
+ return ((unsigned long)hose->cfg_data) + U3_HT_CFA0(devfn, offset);
+ } else
+ return ((unsigned long)hose->cfg_data) + U3_HT_CFA1(bus, devfn, offset);
+}
+
+static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
+ int offset, int len, u32 *val)
+{
+ struct pci_controller *hose;
+ unsigned long addr;
+
+ hose = pci_bus_to_host(bus);
+ if (hose == NULL)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
+ if (!addr)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ switch (u3_ht_skip_device(hose, bus, devfn)) {
+ case 0:
+ break;
+ case 1:
+ switch (len) {
+ case 1:
+ *val = 0xff; break;
+ case 2:
+ *val = 0xffff; break;
+ default:
+ *val = 0xfffffffful; break;
+ }
+ return PCIBIOS_SUCCESSFUL;
+ default:
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ /*
+ * Note: the caller has already checked that offset is
+ * suitably aligned and that len is 1, 2 or 4.
+ */
+ switch (len) {
+ case 1:
+ *val = in_8((u8 *)addr);
+ break;
+ case 2:
+ *val = in_le16((u16 *)addr);
+ break;
+ default:
+ *val = in_le32((u32 *)addr);
+ break;
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
+ int offset, int len, u32 val)
+{
+ struct pci_controller *hose;
+ unsigned long addr;
+
+ hose = pci_bus_to_host(bus);
+ if (hose == NULL)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
+ if (!addr)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ switch (u3_ht_skip_device(hose, bus, devfn)) {
+ case 0:
+ break;
+ case 1:
+ return PCIBIOS_SUCCESSFUL;
+ default:
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ /*
+ * Note: the caller has already checked that offset is
+ * suitably aligned and that len is 1, 2 or 4.
+ */
+ switch (len) {
+ case 1:
+ out_8((u8 *)addr, val);
+ (void) in_8((u8 *)addr);
+ break;
+ case 2:
+ out_le16((u16 *)addr, val);
+ (void) in_le16((u16 *)addr);
+ break;
+ default:
+ out_le32((u32 *)addr, val);
+ (void) in_le32((u32 *)addr);
+ break;
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops u3_ht_pci_ops =
+{
+ u3_ht_read_config,
+ u3_ht_write_config
+};
+#endif /* CONFIG_PPC64 */
+
+#ifdef CONFIG_PPC32
+/*
+ * For a bandit bridge, turn on cache coherency if necessary.
+ * N.B. we could clean this up using the hose ops directly.
+ */
+static void __init init_bandit(struct pci_controller *bp)
+{
+ unsigned int vendev, magic;
+ int rev;
+
+ /* read the word at offset 0 in config space for device 11 */
+ out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + PCI_VENDOR_ID);
+ udelay(2);
+ vendev = in_le32(bp->cfg_data);
+ if (vendev == (PCI_DEVICE_ID_APPLE_BANDIT << 16) +
+ PCI_VENDOR_ID_APPLE) {
+ /* read the revision id */
+ out_le32(bp->cfg_addr,
+ (1UL << BANDIT_DEVNUM) + PCI_REVISION_ID);
+ udelay(2);
+ rev = in_8(bp->cfg_data);
+ if (rev != BANDIT_REVID)
+ printk(KERN_WARNING
+ "Unknown revision %d for bandit\n", rev);
+ } else if (vendev != (BANDIT_DEVID_2 << 16) + PCI_VENDOR_ID_APPLE) {
+ printk(KERN_WARNING "bandit isn't? (%x)\n", vendev);
+ return;
+ }
+
+ /* read the word at offset 0x50 */
+ out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + BANDIT_MAGIC);
+ udelay(2);
+ magic = in_le32(bp->cfg_data);
+ if ((magic & BANDIT_COHERENT) != 0)
+ return;
+ magic |= BANDIT_COHERENT;
+ udelay(2);
+ out_le32(bp->cfg_data, magic);
+ printk(KERN_INFO "Cache coherency enabled for bandit/PSX\n");
+}
+
+/*
+ * Tweak the PCI-PCI bridge chip on the blue & white G3s.
+ */
+static void __init init_p2pbridge(void)
+{
+ struct device_node *p2pbridge;
+ struct pci_controller* hose;
+ u8 bus, devfn;
+ u16 val;
+
+ /* XXX it would be better here to identify the specific
+ PCI-PCI bridge chip we have. */
+ if ((p2pbridge = find_devices("pci-bridge")) == 0
+ || p2pbridge->parent == NULL
+ || strcmp(p2pbridge->parent->name, "pci") != 0)
+ return;
+ if (pci_device_from_OF_node(p2pbridge, &bus, &devfn) < 0) {
+ DBG("Can't find PCI infos for PCI<->PCI bridge\n");
+ return;
+ }
+ /* Warning: At this point, we have not yet renumbered all busses.
+ * So we must use OF walking to find out hose
+ */
+ hose = pci_find_hose_for_OF_device(p2pbridge);
+ if (!hose) {
+ DBG("Can't find hose for PCI<->PCI bridge\n");
+ return;
+ }
+ if (early_read_config_word(hose, bus, devfn,
+ PCI_BRIDGE_CONTROL, &val) < 0) {
+ printk(KERN_ERR "init_p2pbridge: couldn't read bridge control\n");
+ return;
+ }
+ val &= ~PCI_BRIDGE_CTL_MASTER_ABORT;
+ early_write_config_word(hose, bus, devfn, PCI_BRIDGE_CONTROL, val);
+}
+
+/*
+ * Some Apple desktop machines have a NEC PD720100A USB2 controller
+ * on the motherboard. Open Firmware, on these, will disable the
+ * EHCI part of it so it behaves like a pair of OHCI's. This fixup
+ * code re-enables it ;)
+ */
+static void __init fixup_nec_usb2(void)
+{
+ struct device_node *nec;
+
+ for (nec = NULL; (nec = of_find_node_by_name(nec, "usb")) != NULL;) {
+ struct pci_controller *hose;
+ u32 data, *prop;
+ u8 bus, devfn;
+
+ prop = (u32 *)get_property(nec, "vendor-id", NULL);
+ if (prop == NULL)
+ continue;
+ if (0x1033 != *prop)
+ continue;
+ prop = (u32 *)get_property(nec, "device-id", NULL);
+ if (prop == NULL)
+ continue;
+ if (0x0035 != *prop)
+ continue;
+ prop = (u32 *)get_property(nec, "reg", NULL);
+ if (prop == NULL)
+ continue;
+ devfn = (prop[0] >> 8) & 0xff;
+ bus = (prop[0] >> 16) & 0xff;
+ if (PCI_FUNC(devfn) != 0)
+ continue;
+ hose = pci_find_hose_for_OF_device(nec);
+ if (!hose)
+ continue;
+ early_read_config_dword(hose, bus, devfn, 0xe4, &data);
+ if (data & 1UL) {
+ printk("Found NEC PD720100A USB2 chip with disabled EHCI, fixing up...\n");
+ data &= ~1UL;
+ early_write_config_dword(hose, bus, devfn, 0xe4, data);
+ early_write_config_byte(hose, bus, devfn | 2, PCI_INTERRUPT_LINE,
+ nec->intrs[0].line);
+ }
+ }
+}
+
+static void __init setup_bandit(struct pci_controller *hose,
+ struct reg_property *addr)
+{
+ hose->ops = &macrisc_pci_ops;
+ hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000);
+ hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000);
+ init_bandit(hose);
+}
+
+static int __init setup_uninorth(struct pci_controller *hose,
+ struct reg_property *addr)
+{
+ pci_assign_all_buses = 1;
+ has_uninorth = 1;
+ hose->ops = &macrisc_pci_ops;
+ hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000);
+ hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000);
+ /* We "know" that the bridge at f2000000 has the PCI slots. */
+ return addr->address == 0xf2000000;
+}
+#endif
+
+#ifdef CONFIG_PPC64
+static void __init setup_u3_agp(struct pci_controller* hose)
+{
+ /* On G5, we move AGP up to high bus number so we don't need
+ * to reassign bus numbers for HT. If we ever have P2P bridges
+ * on AGP, we'll have to move pci_assign_all_busses to the
+ * pci_controller structure so we enable it for AGP and not for
+ * HT childs.
+ * We hard code the address because of the different size of
+ * the reg address cell, we shall fix that by killing struct
+ * reg_property and using some accessor functions instead
+ */
+ hose->first_busno = 0xf0;
+ hose->last_busno = 0xff;
+ has_uninorth = 1;
+ hose->ops = &macrisc_pci_ops;
+ hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000);
+ hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000);
+
+ u3_agp = hose;
+}
+
+static void __init setup_u3_ht(struct pci_controller* hose)
+{
+ struct device_node *np = (struct device_node *)hose->arch_data;
+ int i, cur;
+
+ hose->ops = &u3_ht_pci_ops;
+
+ /* We hard code the address because of the different size of
+ * the reg address cell, we shall fix that by killing struct
+ * reg_property and using some accessor functions instead
+ */
+ hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000, 0x02000000);
+
+ /*
+ * /ht node doesn't expose a "ranges" property, so we "remove" regions that
+ * have been allocated to AGP. So far, this version of the code doesn't assign
+ * any of the 0xfxxxxxxx "fine" memory regions to /ht.
+ * We need to fix that sooner or later by either parsing all child "ranges"
+ * properties or figuring out the U3 address space decoding logic and
+ * then read its configuration register (if any).
+ */
+ hose->io_base_phys = 0xf4000000;
+ hose->pci_io_size = 0x00400000;
+ hose->io_resource.name = np->full_name;
+ hose->io_resource.start = 0;
+ hose->io_resource.end = 0x003fffff;
+ hose->io_resource.flags = IORESOURCE_IO;
+ hose->pci_mem_offset = 0;
+ hose->first_busno = 0;
+ hose->last_busno = 0xef;
+ hose->mem_resources[0].name = np->full_name;
+ hose->mem_resources[0].start = 0x80000000;
+ hose->mem_resources[0].end = 0xefffffff;
+ hose->mem_resources[0].flags = IORESOURCE_MEM;
+
+ u3_ht = hose;
+
+ if (u3_agp == NULL) {
+ DBG("U3 has no AGP, using full resource range\n");
+ return;
+ }
+
+ /* We "remove" the AGP resources from the resources allocated to HT, that
+ * is we create "holes". However, that code does assumptions that so far
+ * happen to be true (cross fingers...), typically that resources in the
+ * AGP node are properly ordered
+ */
+ cur = 0;
+ for (i=0; i<3; i++) {
+ struct resource *res = &u3_agp->mem_resources[i];
+ if (res->flags != IORESOURCE_MEM)
+ continue;
+ /* We don't care about "fine" resources */
+ if (res->start >= 0xf0000000)
+ continue;
+ /* Check if it's just a matter of "shrinking" us in one direction */
+ if (hose->mem_resources[cur].start == res->start) {
+ DBG("U3/HT: shrink start of %d, %08lx -> %08lx\n",
+ cur, hose->mem_resources[cur].start, res->end + 1);
+ hose->mem_resources[cur].start = res->end + 1;
+ continue;
+ }
+ if (hose->mem_resources[cur].end == res->end) {
+ DBG("U3/HT: shrink end of %d, %08lx -> %08lx\n",
+ cur, hose->mem_resources[cur].end, res->start - 1);
+ hose->mem_resources[cur].end = res->start - 1;
+ continue;
+ }
+ /* No, it's not the case, we need a hole */
+ if (cur == 2) {
+ /* not enough resources for a hole, we drop part of the range */
+ printk(KERN_WARNING "Running out of resources for /ht host !\n");
+ hose->mem_resources[cur].end = res->start - 1;
+ continue;
+ }
+ cur++;
+ DBG("U3/HT: hole, %d end at %08lx, %d start at %08lx\n",
+ cur-1, res->start - 1, cur, res->end + 1);
+ hose->mem_resources[cur].name = np->full_name;
+ hose->mem_resources[cur].flags = IORESOURCE_MEM;
+ hose->mem_resources[cur].start = res->end + 1;
+ hose->mem_resources[cur].end = hose->mem_resources[cur-1].end;
+ hose->mem_resources[cur-1].end = res->start - 1;
+ }
+}
+
+/* XXX this needs to be converged between ppc32 and ppc64... */
+static struct pci_controller * __init pcibios_alloc_controller(void)
+{
+ struct pci_controller *hose;
+
+ hose = alloc_bootmem(sizeof(struct pci_controller));
+ if (hose)
+ pci_setup_pci_controller(hose);
+ return hose;
+}
+#endif
+
+/*
+ * We assume that if we have a G3 powermac, we have one bridge called
+ * "pci" (a MPC106) and no bandit or chaos bridges, and contrariwise,
+ * if we have one or more bandit or chaos bridges, we don't have a MPC106.
+ */
+static int __init add_bridge(struct device_node *dev)
+{
+ int len;
+ struct pci_controller *hose;
+#ifdef CONFIG_PPC32
+ struct reg_property *addr;
+#endif
+ char *disp_name;
+ int *bus_range;
+ int primary = 1;
+
+ DBG("Adding PCI host bridge %s\n", dev->full_name);
+
+#ifdef CONFIG_PPC32
+ /* XXX fix this */
+ addr = (struct reg_property *) get_property(dev, "reg", &len);
+ if (addr == NULL || len < sizeof(*addr)) {
+ printk(KERN_WARNING "Can't use %s: no address\n",
+ dev->full_name);
+ return -ENODEV;
+ }
+#endif
+ bus_range = (int *) get_property(dev, "bus-range", &len);
+ if (bus_range == NULL || len < 2 * sizeof(int)) {
+ printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n",
+ dev->full_name);
+ }
+
+ hose = pcibios_alloc_controller();
+ if (!hose)
+ return -ENOMEM;
+ hose->arch_data = dev;
+ hose->first_busno = bus_range ? bus_range[0] : 0;
+ hose->last_busno = bus_range ? bus_range[1] : 0xff;
+
+ disp_name = NULL;
+#ifdef CONFIG_POWER4
+ if (device_is_compatible(dev, "u3-agp")) {
+ setup_u3_agp(hose);
+ disp_name = "U3-AGP";
+ primary = 0;
+ } else if (device_is_compatible(dev, "u3-ht")) {
+ setup_u3_ht(hose);
+ disp_name = "U3-HT";
+ primary = 1;
+ }
+ printk(KERN_INFO "Found %s PCI host bridge. Firmware bus number: %d->%d\n",
+ disp_name, hose->first_busno, hose->last_busno);
+#else
+ if (device_is_compatible(dev, "uni-north")) {
+ primary = setup_uninorth(hose, addr);
+ disp_name = "UniNorth";
+ } else if (strcmp(dev->name, "pci") == 0) {
+ /* XXX assume this is a mpc106 (grackle) */
+ setup_grackle(hose);
+ disp_name = "Grackle (MPC106)";
+ } else if (strcmp(dev->name, "bandit") == 0) {
+ setup_bandit(hose, addr);
+ disp_name = "Bandit";
+ } else if (strcmp(dev->name, "chaos") == 0) {
+ setup_chaos(hose, addr);
+ disp_name = "Chaos";
+ primary = 0;
+ }
+ printk(KERN_INFO "Found %s PCI host bridge at 0x%08lx. Firmware bus number: %d->%d\n",
+ disp_name, addr->address, hose->first_busno, hose->last_busno);
+#endif
+ DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n",
+ hose, hose->cfg_addr, hose->cfg_data);
+
+ /* Interpret the "ranges" property */
+ /* This also maps the I/O region and sets isa_io/mem_base */
+ pci_process_bridge_OF_ranges(hose, dev, primary);
+
+ /* Fixup "bus-range" OF property */
+ fixup_bus_range(dev);
+
+ return 0;
+}
+
+static void __init
+pcibios_fixup_OF_interrupts(void)
+{
+ struct pci_dev* dev = NULL;
+
+ /*
+ * Open Firmware often doesn't initialize the
+ * PCI_INTERRUPT_LINE config register properly, so we
+ * should find the device node and apply the interrupt
+ * obtained from the OF device-tree
+ */
+ for_each_pci_dev(dev) {
+ struct device_node *node;
+ node = pci_device_to_OF_node(dev);
+ /* this is the node, see if it has interrupts */
+ if (node && node->n_intrs > 0)
+ dev->irq = node->intrs[0].line;
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+ }
+}
+
+void __init
+pmac_pcibios_fixup(void)
+{
+ /* Fixup interrupts according to OF tree */
+ pcibios_fixup_OF_interrupts();
+}
+
+#ifdef CONFIG_PPC64
+static void __init pmac_fixup_phb_resources(void)
+{
+ struct pci_controller *hose, *tmp;
+
+ list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
+ printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n",
+ hose->global_number,
+ hose->io_resource.start, hose->io_resource.end);
+ }
+}
+#endif
+
+void __init pmac_pci_init(void)
+{
+ struct device_node *np, *root;
+ struct device_node *ht = NULL;
+
+ root = of_find_node_by_path("/");
+ if (root == NULL) {
+ printk(KERN_CRIT "pmac_pci_init: can't find root "
+ "of device tree\n");
+ return;
+ }
+ for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) {
+ if (np->name == NULL)
+ continue;
+ if (strcmp(np->name, "bandit") == 0
+ || strcmp(np->name, "chaos") == 0
+ || strcmp(np->name, "pci") == 0) {
+ if (add_bridge(np) == 0)
+ of_node_get(np);
+ }
+ if (strcmp(np->name, "ht") == 0) {
+ of_node_get(np);
+ ht = np;
+ }
+ }
+ of_node_put(root);
+
+#ifdef CONFIG_PPC64
+ /* Probe HT last as it relies on the agp resources to be already
+ * setup
+ */
+ if (ht && add_bridge(ht) != 0)
+ of_node_put(ht);
+
+ /*
+ * We need to call pci_setup_phb_io for the HT bridge first
+ * so it gets the I/O port numbers starting at 0, and we
+ * need to call it for the AGP bridge after that so it gets
+ * small positive I/O port numbers.
+ */
+ if (u3_ht)
+ pci_setup_phb_io(u3_ht, 1);
+ if (u3_agp)
+ pci_setup_phb_io(u3_agp, 0);
+
+ /*
+ * On ppc64, fixup the IO resources on our host bridges as
+ * the common code does it only for children of the host bridges
+ */
+ pmac_fixup_phb_resources();
+
+ /* Setup the linkage between OF nodes and PHBs */
+ pci_devs_phb_init();
+
+ /* Fixup the PCI<->OF mapping for U3 AGP due to bus renumbering. We
+ * assume there is no P2P bridge on the AGP bus, which should be a
+ * safe assumptions hopefully.
+ */
+ if (u3_agp) {
+ struct device_node *np = u3_agp->arch_data;
+ PCI_DN(np)->busno = 0xf0;
+ for (np = np->child; np; np = np->sibling)
+ PCI_DN(np)->busno = 0xf0;
+ }
+
+ /* map in PCI I/O space */
+ phbs_remap_io();
+
+ /* pmac_check_ht_link(); */
+
+ /* Tell pci.c to not use the common resource allocation mechanism */
+ pci_probe_only = 1;
+
+ /* Allow all IO */
+ io_page_mask = -1;
+
+#else /* CONFIG_PPC64 */
+ init_p2pbridge();
+ fixup_nec_usb2();
+
+ /* We are still having some issues with the Xserve G4, enabling
+ * some offset between bus number and domains for now when we
+ * assign all busses should help for now
+ */
+ if (pci_assign_all_buses)
+ pcibios_assign_bus_offset = 0x10;
+#endif
+}
+
+int
+pmac_pci_enable_device_hook(struct pci_dev *dev, int initial)
+{
+ struct device_node* node;
+ int updatecfg = 0;
+ int uninorth_child;
+
+ node = pci_device_to_OF_node(dev);
+
+ /* We don't want to enable USB controllers absent from the OF tree
+ * (iBook second controller)
+ */
+ if (dev->vendor == PCI_VENDOR_ID_APPLE
+ && (dev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x10))
+ && !node) {
+ printk(KERN_INFO "Apple USB OHCI %s disabled by firmware\n",
+ pci_name(dev));
+ return -EINVAL;
+ }
+
+ if (!node)
+ return 0;
+
+ uninorth_child = node->parent &&
+ device_is_compatible(node->parent, "uni-north");
+
+ /* Firewire & GMAC were disabled after PCI probe, the driver is
+ * claiming them, we must re-enable them now.
+ */
+ if (uninorth_child && !strcmp(node->name, "firewire") &&
+ (device_is_compatible(node, "pci106b,18") ||
+ device_is_compatible(node, "pci106b,30") ||
+ device_is_compatible(node, "pci11c1,5811"))) {
+ pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, node, 0, 1);
+ pmac_call_feature(PMAC_FTR_1394_ENABLE, node, 0, 1);
+ updatecfg = 1;
+ }
+ if (uninorth_child && !strcmp(node->name, "ethernet") &&
+ device_is_compatible(node, "gmac")) {
+ pmac_call_feature(PMAC_FTR_GMAC_ENABLE, node, 0, 1);
+ updatecfg = 1;
+ }
+
+ if (updatecfg) {
+ u16 cmd;
+
+ /*
+ * Make sure PCI is correctly configured
+ *
+ * We use old pci_bios versions of the function since, by
+ * default, gmac is not powered up, and so will be absent
+ * from the kernel initial PCI lookup.
+ *
+ * Should be replaced by 2.4 new PCI mechanisms and really
+ * register the device.
+ */
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
+ | PCI_COMMAND_INVALIDATE;
+ pci_write_config_word(dev, PCI_COMMAND, cmd);
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 16);
+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
+ L1_CACHE_BYTES >> 2);
+ }
+
+ return 0;
+}
+
+/* We power down some devices after they have been probed. They'll
+ * be powered back on later on
+ */
+void __init pmac_pcibios_after_init(void)
+{
+ struct device_node* nd;
+
+#ifdef CONFIG_BLK_DEV_IDE
+ struct pci_dev *dev = NULL;
+
+ /* OF fails to initialize IDE controllers on macs
+ * (and maybe other machines)
+ *
+ * Ideally, this should be moved to the IDE layer, but we need
+ * to check specifically with Andre Hedrick how to do it cleanly
+ * since the common IDE code seem to care about the fact that the
+ * BIOS may have disabled a controller.
+ *
+ * -- BenH
+ */
+ for_each_pci_dev(dev) {
+ if ((dev->class >> 16) == PCI_BASE_CLASS_STORAGE)
+ pci_enable_device(dev);
+ }
+#endif /* CONFIG_BLK_DEV_IDE */
+
+ nd = find_devices("firewire");
+ while (nd) {
+ if (nd->parent && (device_is_compatible(nd, "pci106b,18") ||
+ device_is_compatible(nd, "pci106b,30") ||
+ device_is_compatible(nd, "pci11c1,5811"))
+ && device_is_compatible(nd->parent, "uni-north")) {
+ pmac_call_feature(PMAC_FTR_1394_ENABLE, nd, 0, 0);
+ pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, nd, 0, 0);
+ }
+ nd = nd->next;
+ }
+ nd = find_devices("ethernet");
+ while (nd) {
+ if (nd->parent && device_is_compatible(nd, "gmac")
+ && device_is_compatible(nd->parent, "uni-north"))
+ pmac_call_feature(PMAC_FTR_GMAC_ENABLE, nd, 0, 0);
+ nd = nd->next;
+ }
+}
+
+#ifdef CONFIG_PPC32
+void pmac_pci_fixup_cardbus(struct pci_dev* dev)
+{
+ if (_machine != _MACH_Pmac)
+ return;
+ /*
+ * Fix the interrupt routing on the various cardbus bridges
+ * used on powerbooks
+ */
+ if (dev->vendor != PCI_VENDOR_ID_TI)
+ return;
+ if (dev->device == PCI_DEVICE_ID_TI_1130 ||
+ dev->device == PCI_DEVICE_ID_TI_1131) {
+ u8 val;
+ /* Enable PCI interrupt */
+ if (pci_read_config_byte(dev, 0x91, &val) == 0)
+ pci_write_config_byte(dev, 0x91, val | 0x30);
+ /* Disable ISA interrupt mode */
+ if (pci_read_config_byte(dev, 0x92, &val) == 0)
+ pci_write_config_byte(dev, 0x92, val & ~0x06);
+ }
+ if (dev->device == PCI_DEVICE_ID_TI_1210 ||
+ dev->device == PCI_DEVICE_ID_TI_1211 ||
+ dev->device == PCI_DEVICE_ID_TI_1410 ||
+ dev->device == PCI_DEVICE_ID_TI_1510) {
+ u8 val;
+ /* 0x8c == TI122X_IRQMUX, 2 says to route the INTA
+ signal out the MFUNC0 pin */
+ if (pci_read_config_byte(dev, 0x8c, &val) == 0)
+ pci_write_config_byte(dev, 0x8c, (val & ~0x0f) | 2);
+ /* Disable ISA interrupt mode */
+ if (pci_read_config_byte(dev, 0x92, &val) == 0)
+ pci_write_config_byte(dev, 0x92, val & ~0x06);
+ }
+}
+
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_TI, PCI_ANY_ID, pmac_pci_fixup_cardbus);
+
+void pmac_pci_fixup_pciata(struct pci_dev* dev)
+{
+ u8 progif = 0;
+
+ /*
+ * On PowerMacs, we try to switch any PCI ATA controller to
+ * fully native mode
+ */
+ if (_machine != _MACH_Pmac)
+ return;
+ /* Some controllers don't have the class IDE */
+ if (dev->vendor == PCI_VENDOR_ID_PROMISE)
+ switch(dev->device) {
+ case PCI_DEVICE_ID_PROMISE_20246:
+ case PCI_DEVICE_ID_PROMISE_20262:
+ case PCI_DEVICE_ID_PROMISE_20263:
+ case PCI_DEVICE_ID_PROMISE_20265:
+ case PCI_DEVICE_ID_PROMISE_20267:
+ case PCI_DEVICE_ID_PROMISE_20268:
+ case PCI_DEVICE_ID_PROMISE_20269:
+ case PCI_DEVICE_ID_PROMISE_20270:
+ case PCI_DEVICE_ID_PROMISE_20271:
+ case PCI_DEVICE_ID_PROMISE_20275:
+ case PCI_DEVICE_ID_PROMISE_20276:
+ case PCI_DEVICE_ID_PROMISE_20277:
+ goto good;
+ }
+ /* Others, check PCI class */
+ if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE)
+ return;
+ good:
+ pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
+ if ((progif & 5) != 5) {
+ printk(KERN_INFO "Forcing PCI IDE into native mode: %s\n", pci_name(dev));
+ (void) pci_write_config_byte(dev, PCI_CLASS_PROG, progif|5);
+ if (pci_read_config_byte(dev, PCI_CLASS_PROG, &progif) ||
+ (progif & 5) != 5)
+ printk(KERN_ERR "Rewrite of PROGIF failed !\n");
+ }
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pmac_pci_fixup_pciata);
+#endif
+
+/*
+ * Disable second function on K2-SATA, it's broken
+ * and disable IO BARs on first one
+ */
+static void fixup_k2_sata(struct pci_dev* dev)
+{
+ int i;
+ u16 cmd;
+
+ if (PCI_FUNC(dev->devfn) > 0) {
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
+ pci_write_config_word(dev, PCI_COMMAND, cmd);
+ for (i = 0; i < 6; i++) {
+ dev->resource[i].start = dev->resource[i].end = 0;
+ dev->resource[i].flags = 0;
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 0);
+ }
+ } else {
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ cmd &= ~PCI_COMMAND_IO;
+ pci_write_config_word(dev, PCI_COMMAND, cmd);
+ for (i = 0; i < 5; i++) {
+ dev->resource[i].start = dev->resource[i].end = 0;
+ dev->resource[i].flags = 0;
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 0);
+ }
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, 0x0240, fixup_k2_sata);
+
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
new file mode 100644
index 000000000000..0037a8c8c81f
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -0,0 +1,678 @@
+/*
+ * Support for the interrupt controllers found on Power Macintosh,
+ * currently Apple's "Grand Central" interrupt controller in all
+ * it's incarnations. OpenPIC support used on newer machines is
+ * in a separate file
+ *
+ * Copyright (C) 1997 Paul Mackerras (paulus@samba.org)
+ *
+ * Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.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/config.h>
+#include <linux/stddef.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/sysdev.h>
+#include <linux/adb.h>
+#include <linux/pmu.h>
+#include <linux/module.h>
+
+#include <asm/sections.h>
+#include <asm/io.h>
+#include <asm/smp.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/time.h>
+#include <asm/pmac_feature.h>
+#include <asm/mpic.h>
+
+#include "pmac.h"
+
+/*
+ * XXX this should be in xmon.h, but putting it there means xmon.h
+ * has to include <linux/interrupt.h> (to get irqreturn_t), which
+ * causes all sorts of problems. -- paulus
+ */
+extern irqreturn_t xmon_irq(int, void *, struct pt_regs *);
+
+#ifdef CONFIG_PPC32
+struct pmac_irq_hw {
+ unsigned int event;
+ unsigned int enable;
+ unsigned int ack;
+ unsigned int level;
+};
+
+/* Default addresses */
+static volatile struct pmac_irq_hw *pmac_irq_hw[4] = {
+ (struct pmac_irq_hw *) 0xf3000020,
+ (struct pmac_irq_hw *) 0xf3000010,
+ (struct pmac_irq_hw *) 0xf4000020,
+ (struct pmac_irq_hw *) 0xf4000010,
+};
+
+#define GC_LEVEL_MASK 0x3ff00000
+#define OHARE_LEVEL_MASK 0x1ff00000
+#define HEATHROW_LEVEL_MASK 0x1ff00000
+
+static int max_irqs;
+static int max_real_irqs;
+static u32 level_mask[4];
+
+static DEFINE_SPINLOCK(pmac_pic_lock);
+
+#define GATWICK_IRQ_POOL_SIZE 10
+static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE];
+
+/*
+ * Mark an irq as "lost". This is only used on the pmac
+ * since it can lose interrupts (see pmac_set_irq_mask).
+ * -- Cort
+ */
+void
+__set_lost(unsigned long irq_nr, int nokick)
+{
+ if (!test_and_set_bit(irq_nr, ppc_lost_interrupts)) {
+ atomic_inc(&ppc_n_lost_interrupts);
+ if (!nokick)
+ set_dec(1);
+ }
+}
+
+static void
+pmac_mask_and_ack_irq(unsigned int irq_nr)
+{
+ unsigned long bit = 1UL << (irq_nr & 0x1f);
+ int i = irq_nr >> 5;
+ unsigned long flags;
+
+ if ((unsigned)irq_nr >= max_irqs)
+ return;
+
+ clear_bit(irq_nr, ppc_cached_irq_mask);
+ if (test_and_clear_bit(irq_nr, ppc_lost_interrupts))
+ atomic_dec(&ppc_n_lost_interrupts);
+ spin_lock_irqsave(&pmac_pic_lock, flags);
+ out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]);
+ out_le32(&pmac_irq_hw[i]->ack, bit);
+ do {
+ /* make sure ack gets to controller before we enable
+ interrupts */
+ mb();
+ } while((in_le32(&pmac_irq_hw[i]->enable) & bit)
+ != (ppc_cached_irq_mask[i] & bit));
+ spin_unlock_irqrestore(&pmac_pic_lock, flags);
+}
+
+static void pmac_set_irq_mask(unsigned int irq_nr, int nokicklost)
+{
+ unsigned long bit = 1UL << (irq_nr & 0x1f);
+ int i = irq_nr >> 5;
+ unsigned long flags;
+
+ if ((unsigned)irq_nr >= max_irqs)
+ return;
+
+ spin_lock_irqsave(&pmac_pic_lock, flags);
+ /* enable unmasked interrupts */
+ out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]);
+
+ do {
+ /* make sure mask gets to controller before we
+ return to user */
+ mb();
+ } while((in_le32(&pmac_irq_hw[i]->enable) & bit)
+ != (ppc_cached_irq_mask[i] & bit));
+
+ /*
+ * Unfortunately, setting the bit in the enable register
+ * when the device interrupt is already on *doesn't* set
+ * the bit in the flag register or request another interrupt.
+ */
+ if (bit & ppc_cached_irq_mask[i] & in_le32(&pmac_irq_hw[i]->level))
+ __set_lost((ulong)irq_nr, nokicklost);
+ spin_unlock_irqrestore(&pmac_pic_lock, flags);
+}
+
+/* When an irq gets requested for the first client, if it's an
+ * edge interrupt, we clear any previous one on the controller
+ */
+static unsigned int pmac_startup_irq(unsigned int irq_nr)
+{
+ unsigned long bit = 1UL << (irq_nr & 0x1f);
+ int i = irq_nr >> 5;
+
+ if ((irq_desc[irq_nr].status & IRQ_LEVEL) == 0)
+ out_le32(&pmac_irq_hw[i]->ack, bit);
+ set_bit(irq_nr, ppc_cached_irq_mask);
+ pmac_set_irq_mask(irq_nr, 0);
+
+ return 0;
+}
+
+static void pmac_mask_irq(unsigned int irq_nr)
+{
+ clear_bit(irq_nr, ppc_cached_irq_mask);
+ pmac_set_irq_mask(irq_nr, 0);
+ mb();
+}
+
+static void pmac_unmask_irq(unsigned int irq_nr)
+{
+ set_bit(irq_nr, ppc_cached_irq_mask);
+ pmac_set_irq_mask(irq_nr, 0);
+}
+
+static void pmac_end_irq(unsigned int irq_nr)
+{
+ if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))
+ && irq_desc[irq_nr].action) {
+ set_bit(irq_nr, ppc_cached_irq_mask);
+ pmac_set_irq_mask(irq_nr, 1);
+ }
+}
+
+
+struct hw_interrupt_type pmac_pic = {
+ .typename = " PMAC-PIC ",
+ .startup = pmac_startup_irq,
+ .enable = pmac_unmask_irq,
+ .disable = pmac_mask_irq,
+ .ack = pmac_mask_and_ack_irq,
+ .end = pmac_end_irq,
+};
+
+struct hw_interrupt_type gatwick_pic = {
+ .typename = " GATWICK ",
+ .startup = pmac_startup_irq,
+ .enable = pmac_unmask_irq,
+ .disable = pmac_mask_irq,
+ .ack = pmac_mask_and_ack_irq,
+ .end = pmac_end_irq,
+};
+
+static irqreturn_t gatwick_action(int cpl, void *dev_id, struct pt_regs *regs)
+{
+ int irq, bits;
+
+ for (irq = max_irqs; (irq -= 32) >= max_real_irqs; ) {
+ int i = irq >> 5;
+ bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i];
+ /* We must read level interrupts from the level register */
+ bits |= (in_le32(&pmac_irq_hw[i]->level) & level_mask[i]);
+ bits &= ppc_cached_irq_mask[i];
+ if (bits == 0)
+ continue;
+ irq += __ilog2(bits);
+ __do_IRQ(irq, regs);
+ return IRQ_HANDLED;
+ }
+ printk("gatwick irq not from gatwick pic\n");
+ return IRQ_NONE;
+}
+
+int
+pmac_get_irq(struct pt_regs *regs)
+{
+ int irq;
+ unsigned long bits = 0;
+
+#ifdef CONFIG_SMP
+ void psurge_smp_message_recv(struct pt_regs *);
+
+ /* IPI's are a hack on the powersurge -- Cort */
+ if ( smp_processor_id() != 0 ) {
+ psurge_smp_message_recv(regs);
+ return -2; /* ignore, already handled */
+ }
+#endif /* CONFIG_SMP */
+ for (irq = max_real_irqs; (irq -= 32) >= 0; ) {
+ int i = irq >> 5;
+ bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i];
+ /* We must read level interrupts from the level register */
+ bits |= (in_le32(&pmac_irq_hw[i]->level) & level_mask[i]);
+ bits &= ppc_cached_irq_mask[i];
+ if (bits == 0)
+ continue;
+ irq += __ilog2(bits);
+ break;
+ }
+
+ return irq;
+}
+
+/* This routine will fix some missing interrupt values in the device tree
+ * on the gatwick mac-io controller used by some PowerBooks
+ */
+static void __init
+pmac_fix_gatwick_interrupts(struct device_node *gw, int irq_base)
+{
+ struct device_node *node;
+ int count;
+
+ memset(gatwick_int_pool, 0, sizeof(gatwick_int_pool));
+ node = gw->child;
+ count = 0;
+ while(node)
+ {
+ /* Fix SCC */
+ if (strcasecmp(node->name, "escc") == 0)
+ if (node->child) {
+ if (node->child->n_intrs < 3) {
+ node->child->intrs = &gatwick_int_pool[count];
+ count += 3;
+ }
+ node->child->n_intrs = 3;
+ node->child->intrs[0].line = 15+irq_base;
+ node->child->intrs[1].line = 4+irq_base;
+ node->child->intrs[2].line = 5+irq_base;
+ printk(KERN_INFO "irq: fixed SCC on second controller (%d,%d,%d)\n",
+ node->child->intrs[0].line,
+ node->child->intrs[1].line,
+ node->child->intrs[2].line);
+ }
+ /* Fix media-bay & left SWIM */
+ if (strcasecmp(node->name, "media-bay") == 0) {
+ struct device_node* ya_node;
+
+ if (node->n_intrs == 0)
+ node->intrs = &gatwick_int_pool[count++];
+ node->n_intrs = 1;
+ node->intrs[0].line = 29+irq_base;
+ printk(KERN_INFO "irq: fixed media-bay on second controller (%d)\n",
+ node->intrs[0].line);
+
+ ya_node = node->child;
+ while(ya_node)
+ {
+ if (strcasecmp(ya_node->name, "floppy") == 0) {
+ if (ya_node->n_intrs < 2) {
+ ya_node->intrs = &gatwick_int_pool[count];
+ count += 2;
+ }
+ ya_node->n_intrs = 2;
+ ya_node->intrs[0].line = 19+irq_base;
+ ya_node->intrs[1].line = 1+irq_base;
+ printk(KERN_INFO "irq: fixed floppy on second controller (%d,%d)\n",
+ ya_node->intrs[0].line, ya_node->intrs[1].line);
+ }
+ if (strcasecmp(ya_node->name, "ata4") == 0) {
+ if (ya_node->n_intrs < 2) {
+ ya_node->intrs = &gatwick_int_pool[count];
+ count += 2;
+ }
+ ya_node->n_intrs = 2;
+ ya_node->intrs[0].line = 14+irq_base;
+ ya_node->intrs[1].line = 3+irq_base;
+ printk(KERN_INFO "irq: fixed ide on second controller (%d,%d)\n",
+ ya_node->intrs[0].line, ya_node->intrs[1].line);
+ }
+ ya_node = ya_node->sibling;
+ }
+ }
+ node = node->sibling;
+ }
+ if (count > 10) {
+ printk("WARNING !! Gatwick interrupt pool overflow\n");
+ printk(" GATWICK_IRQ_POOL_SIZE = %d\n", GATWICK_IRQ_POOL_SIZE);
+ printk(" requested = %d\n", count);
+ }
+}
+
+/*
+ * The PowerBook 3400/2400/3500 can have a combo ethernet/modem
+ * card which includes an ohare chip that acts as a second interrupt
+ * controller. If we find this second ohare, set it up and fix the
+ * interrupt value in the device tree for the ethernet chip.
+ */
+static int __init enable_second_ohare(void)
+{
+ unsigned char bus, devfn;
+ unsigned short cmd;
+ unsigned long addr;
+ struct device_node *irqctrler = find_devices("pci106b,7");
+ struct device_node *ether;
+
+ if (irqctrler == NULL || irqctrler->n_addrs <= 0)
+ return -1;
+ addr = (unsigned long) ioremap(irqctrler->addrs[0].address, 0x40);
+ pmac_irq_hw[1] = (volatile struct pmac_irq_hw *)(addr + 0x20);
+ max_irqs = 64;
+ if (pci_device_from_OF_node(irqctrler, &bus, &devfn) == 0) {
+ struct pci_controller* hose = pci_find_hose_for_OF_device(irqctrler);
+ if (!hose)
+ printk(KERN_ERR "Can't find PCI hose for OHare2 !\n");
+ else {
+ early_read_config_word(hose, bus, devfn, PCI_COMMAND, &cmd);
+ cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
+ cmd &= ~PCI_COMMAND_IO;
+ early_write_config_word(hose, bus, devfn, PCI_COMMAND, cmd);
+ }
+ }
+
+ /* Fix interrupt for the modem/ethernet combo controller. The number
+ in the device tree (27) is bogus (correct for the ethernet-only
+ board but not the combo ethernet/modem board).
+ The real interrupt is 28 on the second controller -> 28+32 = 60.
+ */
+ ether = find_devices("pci1011,14");
+ if (ether && ether->n_intrs > 0) {
+ ether->intrs[0].line = 60;
+ printk(KERN_INFO "irq: Fixed ethernet IRQ to %d\n",
+ ether->intrs[0].line);
+ }
+
+ /* Return the interrupt number of the cascade */
+ return irqctrler->intrs[0].line;
+}
+
+#ifdef CONFIG_XMON
+static struct irqaction xmon_action = {
+ .handler = xmon_irq,
+ .flags = 0,
+ .mask = CPU_MASK_NONE,
+ .name = "NMI - XMON"
+};
+#endif
+
+static struct irqaction gatwick_cascade_action = {
+ .handler = gatwick_action,
+ .flags = SA_INTERRUPT,
+ .mask = CPU_MASK_NONE,
+ .name = "cascade",
+};
+#endif /* CONFIG_PPC32 */
+
+static int pmac_u3_cascade(struct pt_regs *regs, void *data)
+{
+ return mpic_get_one_irq((struct mpic *)data, regs);
+}
+
+void __init pmac_pic_init(void)
+{
+ struct device_node *irqctrler = NULL;
+ struct device_node *irqctrler2 = NULL;
+ struct device_node *np;
+#ifdef CONFIG_PPC32
+ int i;
+ unsigned long addr;
+ int irq_cascade = -1;
+#endif
+ struct mpic *mpic1, *mpic2;
+
+ /* We first try to detect Apple's new Core99 chipset, since mac-io
+ * is quite different on those machines and contains an IBM MPIC2.
+ */
+ np = find_type_devices("open-pic");
+ while (np) {
+ if (np->parent && !strcmp(np->parent->name, "u3"))
+ irqctrler2 = np;
+ else
+ irqctrler = np;
+ np = np->next;
+ }
+ if (irqctrler != NULL && irqctrler->n_addrs > 0) {
+ unsigned char senses[128];
+
+ printk(KERN_INFO "PowerMac using OpenPIC irq controller at 0x%08x\n",
+ (unsigned int)irqctrler->addrs[0].address);
+ pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler, 0, 0);
+
+ prom_get_irq_senses(senses, 0, 128);
+ mpic1 = mpic_alloc(irqctrler->addrs[0].address,
+ MPIC_PRIMARY | MPIC_WANTS_RESET,
+ 0, 0, 128, 252, senses, 128, " OpenPIC ");
+ BUG_ON(mpic1 == NULL);
+ mpic_init(mpic1);
+
+ if (irqctrler2 != NULL && irqctrler2->n_intrs > 0 &&
+ irqctrler2->n_addrs > 0) {
+ printk(KERN_INFO "Slave OpenPIC at 0x%08x hooked on IRQ %d\n",
+ (u32)irqctrler2->addrs[0].address,
+ irqctrler2->intrs[0].line);
+
+ pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler2, 0, 0);
+ prom_get_irq_senses(senses, 128, 128 + 124);
+
+ /* We don't need to set MPIC_BROKEN_U3 here since we don't have
+ * hypertransport interrupts routed to it
+ */
+ mpic2 = mpic_alloc(irqctrler2->addrs[0].address,
+ MPIC_BIG_ENDIAN | MPIC_WANTS_RESET,
+ 0, 128, 124, 0, senses, 124,
+ " U3-MPIC ");
+ BUG_ON(mpic2 == NULL);
+ mpic_init(mpic2);
+ mpic_setup_cascade(irqctrler2->intrs[0].line,
+ pmac_u3_cascade, mpic2);
+ }
+#if defined(CONFIG_XMON) && defined(CONFIG_PPC32)
+ {
+ struct device_node* pswitch;
+ int nmi_irq;
+
+ pswitch = find_devices("programmer-switch");
+ if (pswitch && pswitch->n_intrs) {
+ nmi_irq = pswitch->intrs[0].line;
+ mpic_irq_set_priority(nmi_irq, 9);
+ setup_irq(nmi_irq, &xmon_action);
+ }
+ }
+#endif /* CONFIG_XMON */
+ return;
+ }
+ irqctrler = NULL;
+
+#ifdef CONFIG_PPC32
+ /* Get the level/edge settings, assume if it's not
+ * a Grand Central nor an OHare, then it's an Heathrow
+ * (or Paddington).
+ */
+ ppc_md.get_irq = pmac_get_irq;
+ if (find_devices("gc"))
+ level_mask[0] = GC_LEVEL_MASK;
+ else if (find_devices("ohare")) {
+ level_mask[0] = OHARE_LEVEL_MASK;
+ /* We might have a second cascaded ohare */
+ level_mask[1] = OHARE_LEVEL_MASK;
+ } else {
+ level_mask[0] = HEATHROW_LEVEL_MASK;
+ level_mask[1] = 0;
+ /* We might have a second cascaded heathrow */
+ level_mask[2] = HEATHROW_LEVEL_MASK;
+ level_mask[3] = 0;
+ }
+
+ /*
+ * G3 powermacs and 1999 G3 PowerBooks have 64 interrupts,
+ * 1998 G3 Series PowerBooks have 128,
+ * other powermacs have 32.
+ * The combo ethernet/modem card for the Powerstar powerbooks
+ * (2400/3400/3500, ohare based) has a second ohare chip
+ * effectively making a total of 64.
+ */
+ max_irqs = max_real_irqs = 32;
+ irqctrler = find_devices("mac-io");
+ if (irqctrler)
+ {
+ max_real_irqs = 64;
+ if (irqctrler->next)
+ max_irqs = 128;
+ else
+ max_irqs = 64;
+ }
+ for ( i = 0; i < max_real_irqs ; i++ )
+ irq_desc[i].handler = &pmac_pic;
+
+ /* get addresses of first controller */
+ if (irqctrler) {
+ if (irqctrler->n_addrs > 0) {
+ addr = (unsigned long)
+ ioremap(irqctrler->addrs[0].address, 0x40);
+ for (i = 0; i < 2; ++i)
+ pmac_irq_hw[i] = (volatile struct pmac_irq_hw*)
+ (addr + (2 - i) * 0x10);
+ }
+
+ /* get addresses of second controller */
+ irqctrler = irqctrler->next;
+ if (irqctrler && irqctrler->n_addrs > 0) {
+ addr = (unsigned long)
+ ioremap(irqctrler->addrs[0].address, 0x40);
+ for (i = 2; i < 4; ++i)
+ pmac_irq_hw[i] = (volatile struct pmac_irq_hw*)
+ (addr + (4 - i) * 0x10);
+ irq_cascade = irqctrler->intrs[0].line;
+ if (device_is_compatible(irqctrler, "gatwick"))
+ pmac_fix_gatwick_interrupts(irqctrler, max_real_irqs);
+ }
+ } else {
+ /* older powermacs have a GC (grand central) or ohare at
+ f3000000, with interrupt control registers at f3000020. */
+ addr = (unsigned long) ioremap(0xf3000000, 0x40);
+ pmac_irq_hw[0] = (volatile struct pmac_irq_hw *) (addr + 0x20);
+ }
+
+ /* PowerBooks 3400 and 3500 can have a second controller in a second
+ ohare chip, on the combo ethernet/modem card */
+ if (machine_is_compatible("AAPL,3400/2400")
+ || machine_is_compatible("AAPL,3500"))
+ irq_cascade = enable_second_ohare();
+
+ /* disable all interrupts in all controllers */
+ for (i = 0; i * 32 < max_irqs; ++i)
+ out_le32(&pmac_irq_hw[i]->enable, 0);
+ /* mark level interrupts */
+ for (i = 0; i < max_irqs; i++)
+ if (level_mask[i >> 5] & (1UL << (i & 0x1f)))
+ irq_desc[i].status = IRQ_LEVEL;
+
+ /* get interrupt line of secondary interrupt controller */
+ if (irq_cascade >= 0) {
+ printk(KERN_INFO "irq: secondary controller on irq %d\n",
+ (int)irq_cascade);
+ for ( i = max_real_irqs ; i < max_irqs ; i++ )
+ irq_desc[i].handler = &gatwick_pic;
+ setup_irq(irq_cascade, &gatwick_cascade_action);
+ }
+ printk("System has %d possible interrupts\n", max_irqs);
+ if (max_irqs != max_real_irqs)
+ printk(KERN_DEBUG "%d interrupts on main controller\n",
+ max_real_irqs);
+
+#ifdef CONFIG_XMON
+ setup_irq(20, &xmon_action);
+#endif /* CONFIG_XMON */
+#endif /* CONFIG_PPC32 */
+}
+
+#ifdef CONFIG_PM
+/*
+ * These procedures are used in implementing sleep on the powerbooks.
+ * sleep_save_intrs() saves the states of all interrupt enables
+ * and disables all interrupts except for the nominated one.
+ * sleep_restore_intrs() restores the states of all interrupt enables.
+ */
+unsigned long sleep_save_mask[2];
+
+/* This used to be passed by the PMU driver but that link got
+ * broken with the new driver model. We use this tweak for now...
+ */
+static int pmacpic_find_viaint(void)
+{
+ int viaint = -1;
+
+#ifdef CONFIG_ADB_PMU
+ struct device_node *np;
+
+ if (pmu_get_model() != PMU_OHARE_BASED)
+ goto not_found;
+ np = of_find_node_by_name(NULL, "via-pmu");
+ if (np == NULL)
+ goto not_found;
+ viaint = np->intrs[0].line;
+#endif /* CONFIG_ADB_PMU */
+
+not_found:
+ return viaint;
+}
+
+static int pmacpic_suspend(struct sys_device *sysdev, pm_message_t state)
+{
+ int viaint = pmacpic_find_viaint();
+
+ sleep_save_mask[0] = ppc_cached_irq_mask[0];
+ sleep_save_mask[1] = ppc_cached_irq_mask[1];
+ ppc_cached_irq_mask[0] = 0;
+ ppc_cached_irq_mask[1] = 0;
+ if (viaint > 0)
+ set_bit(viaint, ppc_cached_irq_mask);
+ out_le32(&pmac_irq_hw[0]->enable, ppc_cached_irq_mask[0]);
+ if (max_real_irqs > 32)
+ out_le32(&pmac_irq_hw[1]->enable, ppc_cached_irq_mask[1]);
+ (void)in_le32(&pmac_irq_hw[0]->event);
+ /* make sure mask gets to controller before we return to caller */
+ mb();
+ (void)in_le32(&pmac_irq_hw[0]->enable);
+
+ return 0;
+}
+
+static int pmacpic_resume(struct sys_device *sysdev)
+{
+ int i;
+
+ out_le32(&pmac_irq_hw[0]->enable, 0);
+ if (max_real_irqs > 32)
+ out_le32(&pmac_irq_hw[1]->enable, 0);
+ mb();
+ for (i = 0; i < max_real_irqs; ++i)
+ if (test_bit(i, sleep_save_mask))
+ pmac_unmask_irq(i);
+
+ return 0;
+}
+
+#endif /* CONFIG_PM */
+
+static struct sysdev_class pmacpic_sysclass = {
+ set_kset_name("pmac_pic"),
+};
+
+static struct sys_device device_pmacpic = {
+ .id = 0,
+ .cls = &pmacpic_sysclass,
+};
+
+static struct sysdev_driver driver_pmacpic = {
+#ifdef CONFIG_PM
+ .suspend = &pmacpic_suspend,
+ .resume = &pmacpic_resume,
+#endif /* CONFIG_PM */
+};
+
+static int __init init_pmacpic_sysfs(void)
+{
+#ifdef CONFIG_PPC32
+ if (max_irqs == 0)
+ return -ENODEV;
+#endif
+ printk(KERN_DEBUG "Registering pmac pic with sysfs...\n");
+ sysdev_class_register(&pmacpic_sysclass);
+ sysdev_register(&device_pmacpic);
+ sysdev_driver_register(&pmacpic_sysclass, &driver_pmacpic);
+ return 0;
+}
+
+subsys_initcall(init_pmacpic_sysfs);
+
diff --git a/arch/powerpc/platforms/powermac/pic.h b/arch/powerpc/platforms/powermac/pic.h
new file mode 100644
index 000000000000..664103dfeef9
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/pic.h
@@ -0,0 +1,11 @@
+#ifndef __PPC_PLATFORMS_PMAC_PIC_H
+#define __PPC_PLATFORMS_PMAC_PIC_H
+
+#include <linux/irq.h>
+
+extern struct hw_interrupt_type pmac_pic;
+
+void pmac_pic_init(void);
+int pmac_get_irq(struct pt_regs *regs);
+
+#endif /* __PPC_PLATFORMS_PMAC_PIC_H */
diff --git a/arch/powerpc/platforms/powermac/pmac.h b/arch/powerpc/platforms/powermac/pmac.h
new file mode 100644
index 000000000000..2ad25e13423e
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/pmac.h
@@ -0,0 +1,51 @@
+#ifndef __PMAC_H__
+#define __PMAC_H__
+
+#include <linux/pci.h>
+#include <linux/ide.h>
+#include <linux/irq.h>
+
+/*
+ * Declaration for the various functions exported by the
+ * pmac_* files. Mostly for use by pmac_setup
+ */
+
+struct rtc_time;
+
+extern long pmac_time_init(void);
+extern unsigned long pmac_get_boot_time(void);
+extern void pmac_get_rtc_time(struct rtc_time *);
+extern int pmac_set_rtc_time(struct rtc_time *);
+extern void pmac_read_rtc_time(void);
+extern void pmac_calibrate_decr(void);
+extern void pmac_pcibios_fixup(void);
+extern void pmac_pci_init(void);
+extern unsigned long pmac_ide_get_base(int index);
+extern void pmac_ide_init_hwif_ports(hw_regs_t *hw,
+ unsigned long data_port, unsigned long ctrl_port, int *irq);
+
+extern void pmac_nvram_update(void);
+extern unsigned char pmac_nvram_read_byte(int addr);
+extern void pmac_nvram_write_byte(int addr, unsigned char val);
+extern int pmac_pci_enable_device_hook(struct pci_dev *dev, int initial);
+extern void pmac_pcibios_after_init(void);
+extern int of_show_percpuinfo(struct seq_file *m, int i);
+
+extern void pmac_pci_init(void);
+extern void pmac_setup_pci_dma(void);
+extern void pmac_check_ht_link(void);
+
+extern void pmac_setup_smp(void);
+
+extern unsigned long pmac_ide_get_base(int index);
+extern void pmac_ide_init_hwif_ports(hw_regs_t *hw,
+ unsigned long data_port, unsigned long ctrl_port, int *irq);
+
+extern int pmac_nvram_init(void);
+
+extern struct hw_interrupt_type pmac_pic;
+
+void pmac_pic_init(void);
+int pmac_get_irq(struct pt_regs *regs);
+
+#endif /* __PMAC_H__ */
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
new file mode 100644
index 000000000000..6f62af597291
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -0,0 +1,794 @@
+/*
+ * Powermac setup and early boot code plus other random bits.
+ *
+ * PowerPC version
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Adapted for Power Macintosh by Paul Mackerras
+ * Copyright (C) 1996 Paul Mackerras (paulus@samba.org)
+ *
+ * Derived from "arch/alpha/kernel/setup.c"
+ * Copyright (C) 1995 Linus Torvalds
+ *
+ * Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.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.
+ *
+ */
+
+/*
+ * bootup setup stuff..
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/tty.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/major.h>
+#include <linux/initrd.h>
+#include <linux/vt_kern.h>
+#include <linux/console.h>
+#include <linux/ide.h>
+#include <linux/pci.h>
+#include <linux/adb.h>
+#include <linux/cuda.h>
+#include <linux/pmu.h>
+#include <linux/irq.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/bitops.h>
+#include <linux/suspend.h>
+
+#include <asm/reg.h>
+#include <asm/sections.h>
+#include <asm/prom.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/io.h>
+#include <asm/pci-bridge.h>
+#include <asm/ohare.h>
+#include <asm/mediabay.h>
+#include <asm/machdep.h>
+#include <asm/dma.h>
+#include <asm/cputable.h>
+#include <asm/btext.h>
+#include <asm/pmac_feature.h>
+#include <asm/time.h>
+#include <asm/of_device.h>
+#include <asm/mmu_context.h>
+#include <asm/iommu.h>
+#include <asm/smu.h>
+#include <asm/pmc.h>
+#include <asm/mpic.h>
+
+#include "pmac.h"
+
+#undef SHOW_GATWICK_IRQS
+
+unsigned char drive_info;
+
+int ppc_override_l2cr = 0;
+int ppc_override_l2cr_value;
+int has_l2cache = 0;
+
+int pmac_newworld = 1;
+
+static int current_root_goodness = -1;
+
+extern int pmac_newworld;
+extern struct machdep_calls pmac_md;
+
+#define DEFAULT_ROOT_DEVICE Root_SDA1 /* sda1 - slightly silly choice */
+
+#ifdef CONFIG_PPC64
+#include <asm/udbg.h>
+int sccdbg;
+#endif
+
+extern void zs_kgdb_hook(int tty_num);
+
+sys_ctrler_t sys_ctrler = SYS_CTRLER_UNKNOWN;
+EXPORT_SYMBOL(sys_ctrler);
+
+#ifdef CONFIG_PMAC_SMU
+unsigned long smu_cmdbuf_abs;
+EXPORT_SYMBOL(smu_cmdbuf_abs);
+#endif
+
+#ifdef CONFIG_SMP
+extern struct smp_ops_t psurge_smp_ops;
+extern struct smp_ops_t core99_smp_ops;
+#endif /* CONFIG_SMP */
+
+static void pmac_show_cpuinfo(struct seq_file *m)
+{
+ struct device_node *np;
+ char *pp;
+ int plen;
+ int mbmodel;
+ unsigned int mbflags;
+ char* mbname;
+
+ mbmodel = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL,
+ PMAC_MB_INFO_MODEL, 0);
+ mbflags = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL,
+ PMAC_MB_INFO_FLAGS, 0);
+ if (pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_NAME,
+ (long) &mbname) != 0)
+ mbname = "Unknown";
+
+ /* find motherboard type */
+ seq_printf(m, "machine\t\t: ");
+ np = of_find_node_by_path("/");
+ if (np != NULL) {
+ pp = (char *) get_property(np, "model", NULL);
+ if (pp != NULL)
+ seq_printf(m, "%s\n", pp);
+ else
+ seq_printf(m, "PowerMac\n");
+ pp = (char *) get_property(np, "compatible", &plen);
+ if (pp != NULL) {
+ seq_printf(m, "motherboard\t:");
+ while (plen > 0) {
+ int l = strlen(pp) + 1;
+ seq_printf(m, " %s", pp);
+ plen -= l;
+ pp += l;
+ }
+ seq_printf(m, "\n");
+ }
+ of_node_put(np);
+ } else
+ seq_printf(m, "PowerMac\n");
+
+ /* print parsed model */
+ seq_printf(m, "detected as\t: %d (%s)\n", mbmodel, mbname);
+ seq_printf(m, "pmac flags\t: %08x\n", mbflags);
+
+ /* find l2 cache info */
+ np = of_find_node_by_name(NULL, "l2-cache");
+ if (np == NULL)
+ np = of_find_node_by_type(NULL, "cache");
+ if (np != NULL) {
+ unsigned int *ic = (unsigned int *)
+ get_property(np, "i-cache-size", NULL);
+ unsigned int *dc = (unsigned int *)
+ get_property(np, "d-cache-size", NULL);
+ seq_printf(m, "L2 cache\t:");
+ has_l2cache = 1;
+ if (get_property(np, "cache-unified", NULL) != 0 && dc) {
+ seq_printf(m, " %dK unified", *dc / 1024);
+ } else {
+ if (ic)
+ seq_printf(m, " %dK instruction", *ic / 1024);
+ if (dc)
+ seq_printf(m, "%s %dK data",
+ (ic? " +": ""), *dc / 1024);
+ }
+ pp = get_property(np, "ram-type", NULL);
+ if (pp)
+ seq_printf(m, " %s", pp);
+ seq_printf(m, "\n");
+ of_node_put(np);
+ }
+
+ /* Indicate newworld/oldworld */
+ seq_printf(m, "pmac-generation\t: %s\n",
+ pmac_newworld ? "NewWorld" : "OldWorld");
+}
+
+static void pmac_show_percpuinfo(struct seq_file *m, int i)
+{
+#ifdef CONFIG_CPU_FREQ_PMAC
+ extern unsigned int pmac_get_one_cpufreq(int i);
+ unsigned int freq = pmac_get_one_cpufreq(i);
+ if (freq != 0) {
+ seq_printf(m, "clock\t\t: %dMHz\n", freq/1000);
+ return;
+ }
+#endif /* CONFIG_CPU_FREQ_PMAC */
+}
+
+#ifndef CONFIG_ADB_CUDA
+int find_via_cuda(void)
+{
+ if (!find_devices("via-cuda"))
+ return 0;
+ printk("WARNING ! Your machine is CUDA-based but your kernel\n");
+ printk(" wasn't compiled with CONFIG_ADB_CUDA option !\n");
+ return 0;
+}
+#endif
+
+#ifndef CONFIG_ADB_PMU
+int find_via_pmu(void)
+{
+ if (!find_devices("via-pmu"))
+ return 0;
+ printk("WARNING ! Your machine is PMU-based but your kernel\n");
+ printk(" wasn't compiled with CONFIG_ADB_PMU option !\n");
+ return 0;
+}
+#endif
+
+#ifndef CONFIG_PMAC_SMU
+int smu_init(void)
+{
+ /* should check and warn if SMU is present */
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_PPC32
+static volatile u32 *sysctrl_regs;
+
+static void __init ohare_init(void)
+{
+ /* this area has the CPU identification register
+ and some registers used by smp boards */
+ sysctrl_regs = (volatile u32 *) ioremap(0xf8000000, 0x1000);
+
+ /*
+ * Turn on the L2 cache.
+ * We assume that we have a PSX memory controller iff
+ * we have an ohare I/O controller.
+ */
+ if (find_devices("ohare") != NULL) {
+ if (((sysctrl_regs[2] >> 24) & 0xf) >= 3) {
+ if (sysctrl_regs[4] & 0x10)
+ sysctrl_regs[4] |= 0x04000020;
+ else
+ sysctrl_regs[4] |= 0x04000000;
+ if(has_l2cache)
+ printk(KERN_INFO "Level 2 cache enabled\n");
+ }
+ }
+}
+
+static void __init l2cr_init(void)
+{
+ /* Checks "l2cr-value" property in the registry */
+ if (cpu_has_feature(CPU_FTR_L2CR)) {
+ struct device_node *np = find_devices("cpus");
+ if (np == 0)
+ np = find_type_devices("cpu");
+ if (np != 0) {
+ unsigned int *l2cr = (unsigned int *)
+ get_property(np, "l2cr-value", NULL);
+ if (l2cr != 0) {
+ ppc_override_l2cr = 1;
+ ppc_override_l2cr_value = *l2cr;
+ _set_L2CR(0);
+ _set_L2CR(ppc_override_l2cr_value);
+ }
+ }
+ }
+
+ if (ppc_override_l2cr)
+ printk(KERN_INFO "L2CR overridden (0x%x), "
+ "backside cache is %s\n",
+ ppc_override_l2cr_value,
+ (ppc_override_l2cr_value & 0x80000000)
+ ? "enabled" : "disabled");
+}
+#endif
+
+void __init pmac_setup_arch(void)
+{
+ struct device_node *cpu, *ic;
+ int *fp;
+ unsigned long pvr;
+
+ pvr = PVR_VER(mfspr(SPRN_PVR));
+
+ /* Set loops_per_jiffy to a half-way reasonable value,
+ for use until calibrate_delay gets called. */
+ loops_per_jiffy = 50000000 / HZ;
+ cpu = of_find_node_by_type(NULL, "cpu");
+ if (cpu != NULL) {
+ fp = (int *) get_property(cpu, "clock-frequency", NULL);
+ if (fp != NULL) {
+ if (pvr >= 0x30 && pvr < 0x80)
+ /* PPC970 etc. */
+ loops_per_jiffy = *fp / (3 * HZ);
+ else if (pvr == 4 || pvr >= 8)
+ /* 604, G3, G4 etc. */
+ loops_per_jiffy = *fp / HZ;
+ else
+ /* 601, 603, etc. */
+ loops_per_jiffy = *fp / (2 * HZ);
+ }
+ of_node_put(cpu);
+ }
+
+ /* See if newworld or oldworld */
+ for (ic = NULL; (ic = of_find_all_nodes(ic)) != NULL; )
+ if (get_property(ic, "interrupt-controller", NULL))
+ break;
+ pmac_newworld = (ic != NULL);
+ if (ic)
+ of_node_put(ic);
+
+ /* Lookup PCI hosts */
+ pmac_pci_init();
+
+#ifdef CONFIG_PPC32
+ ohare_init();
+ l2cr_init();
+#endif /* CONFIG_PPC32 */
+
+#ifdef CONFIG_PPC64
+ /* Probe motherboard chipset */
+ /* this is done earlier in setup_arch for 32-bit */
+ pmac_feature_init();
+
+ /* We can NAP */
+ powersave_nap = 1;
+ printk(KERN_INFO "Using native/NAP idle loop\n");
+#endif
+
+#ifdef CONFIG_KGDB
+ zs_kgdb_hook(0);
+#endif
+
+ find_via_cuda();
+ find_via_pmu();
+ smu_init();
+
+#ifdef CONFIG_NVRAM
+ pmac_nvram_init();
+#endif
+
+#ifdef CONFIG_PPC32
+#ifdef CONFIG_BLK_DEV_INITRD
+ if (initrd_start)
+ ROOT_DEV = Root_RAM0;
+ else
+#endif
+ ROOT_DEV = DEFAULT_ROOT_DEVICE;
+#endif
+
+#ifdef CONFIG_SMP
+ /* Check for Core99 */
+ if (find_devices("uni-n") || find_devices("u3"))
+ smp_ops = &core99_smp_ops;
+#ifdef CONFIG_PPC32
+ else
+ smp_ops = &psurge_smp_ops;
+#endif
+#endif /* CONFIG_SMP */
+}
+
+char *bootpath;
+char *bootdevice;
+void *boot_host;
+int boot_target;
+int boot_part;
+extern dev_t boot_dev;
+
+#ifdef CONFIG_SCSI
+void __init note_scsi_host(struct device_node *node, void *host)
+{
+ int l;
+ char *p;
+
+ l = strlen(node->full_name);
+ if (bootpath != NULL && bootdevice != NULL
+ && strncmp(node->full_name, bootdevice, l) == 0
+ && (bootdevice[l] == '/' || bootdevice[l] == 0)) {
+ boot_host = host;
+ /*
+ * There's a bug in OF 1.0.5. (Why am I not surprised.)
+ * If you pass a path like scsi/sd@1:0 to canon, it returns
+ * something like /bandit@F2000000/gc@10/53c94@10000/sd@0,0
+ * That is, the scsi target number doesn't get preserved.
+ * So we pick the target number out of bootpath and use that.
+ */
+ p = strstr(bootpath, "/sd@");
+ if (p != NULL) {
+ p += 4;
+ boot_target = simple_strtoul(p, NULL, 10);
+ p = strchr(p, ':');
+ if (p != NULL)
+ boot_part = simple_strtoul(p + 1, NULL, 10);
+ }
+ }
+}
+EXPORT_SYMBOL(note_scsi_host);
+#endif
+
+#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
+static dev_t __init find_ide_boot(void)
+{
+ char *p;
+ int n;
+ dev_t __init pmac_find_ide_boot(char *bootdevice, int n);
+
+ if (bootdevice == NULL)
+ return 0;
+ p = strrchr(bootdevice, '/');
+ if (p == NULL)
+ return 0;
+ n = p - bootdevice;
+
+ return pmac_find_ide_boot(bootdevice, n);
+}
+#endif /* CONFIG_BLK_DEV_IDE && CONFIG_BLK_DEV_IDE_PMAC */
+
+static void __init find_boot_device(void)
+{
+#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
+ boot_dev = find_ide_boot();
+#endif
+}
+
+/* TODO: Merge the suspend-to-ram with the common code !!!
+ * currently, this is a stub implementation for suspend-to-disk
+ * only
+ */
+
+#ifdef CONFIG_SOFTWARE_SUSPEND
+
+static int pmac_pm_prepare(suspend_state_t state)
+{
+ printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
+
+ return 0;
+}
+
+static int pmac_pm_enter(suspend_state_t state)
+{
+ printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
+
+ /* Giveup the lazy FPU & vec so we don't have to back them
+ * up from the low level code
+ */
+ enable_kernel_fp();
+
+#ifdef CONFIG_ALTIVEC
+ if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC)
+ enable_kernel_altivec();
+#endif /* CONFIG_ALTIVEC */
+
+ return 0;
+}
+
+static int pmac_pm_finish(suspend_state_t state)
+{
+ printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
+
+ /* Restore userland MMU context */
+ set_context(current->active_mm->context, current->active_mm->pgd);
+
+ return 0;
+}
+
+static struct pm_ops pmac_pm_ops = {
+ .pm_disk_mode = PM_DISK_SHUTDOWN,
+ .prepare = pmac_pm_prepare,
+ .enter = pmac_pm_enter,
+ .finish = pmac_pm_finish,
+};
+
+#endif /* CONFIG_SOFTWARE_SUSPEND */
+
+static int initializing = 1;
+
+static int pmac_late_init(void)
+{
+ initializing = 0;
+#ifdef CONFIG_SOFTWARE_SUSPEND
+ pm_set_ops(&pmac_pm_ops);
+#endif /* CONFIG_SOFTWARE_SUSPEND */
+ return 0;
+}
+
+late_initcall(pmac_late_init);
+
+/* can't be __init - can be called whenever a disk is first accessed */
+void note_bootable_part(dev_t dev, int part, int goodness)
+{
+ static int found_boot = 0;
+ char *p;
+
+ if (!initializing)
+ return;
+ if ((goodness <= current_root_goodness) &&
+ ROOT_DEV != DEFAULT_ROOT_DEVICE)
+ return;
+ p = strstr(saved_command_line, "root=");
+ if (p != NULL && (p == saved_command_line || p[-1] == ' '))
+ return;
+
+ if (!found_boot) {
+ find_boot_device();
+ found_boot = 1;
+ }
+ if (!boot_dev || dev == boot_dev) {
+ ROOT_DEV = dev + part;
+ boot_dev = 0;
+ current_root_goodness = goodness;
+ }
+}
+
+#ifdef CONFIG_ADB_CUDA
+static void cuda_restart(void)
+{
+ struct adb_request req;
+
+ cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_RESET_SYSTEM);
+ for (;;)
+ cuda_poll();
+}
+
+static void cuda_shutdown(void)
+{
+ struct adb_request req;
+
+ cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_POWERDOWN);
+ for (;;)
+ cuda_poll();
+}
+
+#else
+#define cuda_restart()
+#define cuda_shutdown()
+#endif
+
+#ifndef CONFIG_ADB_PMU
+#define pmu_restart()
+#define pmu_shutdown()
+#endif
+
+#ifndef CONFIG_PMAC_SMU
+#define smu_restart()
+#define smu_shutdown()
+#endif
+
+static void pmac_restart(char *cmd)
+{
+ switch (sys_ctrler) {
+ case SYS_CTRLER_CUDA:
+ cuda_restart();
+ break;
+ case SYS_CTRLER_PMU:
+ pmu_restart();
+ break;
+ case SYS_CTRLER_SMU:
+ smu_restart();
+ break;
+ default: ;
+ }
+}
+
+static void pmac_power_off(void)
+{
+ switch (sys_ctrler) {
+ case SYS_CTRLER_CUDA:
+ cuda_shutdown();
+ break;
+ case SYS_CTRLER_PMU:
+ pmu_shutdown();
+ break;
+ case SYS_CTRLER_SMU:
+ smu_shutdown();
+ break;
+ default: ;
+ }
+}
+
+static void
+pmac_halt(void)
+{
+ pmac_power_off();
+}
+
+#ifdef CONFIG_PPC32
+void __init pmac_init(void)
+{
+ /* isa_io_base gets set in pmac_pci_init */
+ isa_mem_base = PMAC_ISA_MEM_BASE;
+ pci_dram_offset = PMAC_PCI_DRAM_OFFSET;
+ ISA_DMA_THRESHOLD = ~0L;
+ DMA_MODE_READ = 1;
+ DMA_MODE_WRITE = 2;
+
+ ppc_md = pmac_md;
+
+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+#ifdef CONFIG_BLK_DEV_IDE_PMAC
+ ppc_ide_md.ide_init_hwif = pmac_ide_init_hwif_ports;
+ ppc_ide_md.default_io_base = pmac_ide_get_base;
+#endif /* CONFIG_BLK_DEV_IDE_PMAC */
+#endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */
+
+ if (ppc_md.progress) ppc_md.progress("pmac_init(): exit", 0);
+
+}
+#endif
+
+/*
+ * Early initialization.
+ */
+static void __init pmac_init_early(void)
+{
+#ifdef CONFIG_PPC64
+ /* Initialize hash table, from now on, we can take hash faults
+ * and call ioremap
+ */
+ hpte_init_native();
+
+ /* Init SCC */
+ if (strstr(cmd_line, "sccdbg")) {
+ sccdbg = 1;
+ udbg_init_scc(NULL);
+ }
+
+ /* Setup interrupt mapping options */
+ ppc64_interrupt_controller = IC_OPEN_PIC;
+
+ iommu_init_early_u3();
+#endif
+}
+
+static void __init pmac_progress(char *s, unsigned short hex)
+{
+#ifdef CONFIG_PPC64
+ if (sccdbg) {
+ udbg_puts(s);
+ udbg_puts("\n");
+ return;
+ }
+#endif
+#ifdef CONFIG_BOOTX_TEXT
+ if (boot_text_mapped) {
+ btext_drawstring(s);
+ btext_drawchar('\n');
+ }
+#endif /* CONFIG_BOOTX_TEXT */
+}
+
+/*
+ * pmac has no legacy IO, anything calling this function has to
+ * fail or bad things will happen
+ */
+static int pmac_check_legacy_ioport(unsigned int baseport)
+{
+ return -ENODEV;
+}
+
+static int __init pmac_declare_of_platform_devices(void)
+{
+ struct device_node *np, *npp;
+
+ np = find_devices("uni-n");
+ if (np) {
+ for (np = np->child; np != NULL; np = np->sibling)
+ if (strncmp(np->name, "i2c", 3) == 0) {
+ of_platform_device_create(np, "uni-n-i2c",
+ NULL);
+ break;
+ }
+ }
+ np = find_devices("valkyrie");
+ if (np)
+ of_platform_device_create(np, "valkyrie", NULL);
+ np = find_devices("platinum");
+ if (np)
+ of_platform_device_create(np, "platinum", NULL);
+
+ npp = of_find_node_by_name(NULL, "u3");
+ if (npp) {
+ for (np = NULL; (np = of_get_next_child(npp, np)) != NULL;) {
+ if (strncmp(np->name, "i2c", 3) == 0) {
+ of_platform_device_create(np, "u3-i2c", NULL);
+ of_node_put(np);
+ break;
+ }
+ }
+ of_node_put(npp);
+ }
+ np = of_find_node_by_type(NULL, "smu");
+ if (np) {
+ of_platform_device_create(np, "smu", NULL);
+ of_node_put(np);
+ }
+
+ return 0;
+}
+
+device_initcall(pmac_declare_of_platform_devices);
+
+/*
+ * Called very early, MMU is off, device-tree isn't unflattened
+ */
+static int __init pmac_probe(int platform)
+{
+#ifdef CONFIG_PPC64
+ if (platform != PLATFORM_POWERMAC)
+ return 0;
+
+ /*
+ * On U3, the DART (iommu) must be allocated now since it
+ * has an impact on htab_initialize (due to the large page it
+ * occupies having to be broken up so the DART itself is not
+ * part of the cacheable linar mapping
+ */
+ alloc_u3_dart_table();
+#endif
+
+#ifdef CONFIG_PMAC_SMU
+ /*
+ * SMU based G5s need some memory below 2Gb, at least the current
+ * driver needs that. We have to allocate it now. We allocate 4k
+ * (1 small page) for now.
+ */
+ smu_cmdbuf_abs = lmb_alloc_base(4096, 4096, 0x80000000UL);
+#endif /* CONFIG_PMAC_SMU */
+
+ return 1;
+}
+
+#ifdef CONFIG_PPC64
+static int pmac_probe_mode(struct pci_bus *bus)
+{
+ struct device_node *node = bus->sysdata;
+
+ /* We need to use normal PCI probing for the AGP bus,
+ since the device for the AGP bridge isn't in the tree. */
+ if (bus->self == NULL && device_is_compatible(node, "u3-agp"))
+ return PCI_PROBE_NORMAL;
+
+ return PCI_PROBE_DEVTREE;
+}
+#endif
+
+struct machdep_calls __initdata pmac_md = {
+#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64)
+ .cpu_die = generic_mach_cpu_die,
+#endif
+ .probe = pmac_probe,
+ .setup_arch = pmac_setup_arch,
+ .init_early = pmac_init_early,
+ .show_cpuinfo = pmac_show_cpuinfo,
+ .show_percpuinfo = pmac_show_percpuinfo,
+ .init_IRQ = pmac_pic_init,
+ .get_irq = mpic_get_irq, /* changed later */
+ .pcibios_fixup = pmac_pcibios_fixup,
+ .restart = pmac_restart,
+ .power_off = pmac_power_off,
+ .halt = pmac_halt,
+ .time_init = pmac_time_init,
+ .get_boot_time = pmac_get_boot_time,
+ .set_rtc_time = pmac_set_rtc_time,
+ .get_rtc_time = pmac_get_rtc_time,
+ .calibrate_decr = pmac_calibrate_decr,
+ .feature_call = pmac_do_feature_call,
+ .check_legacy_ioport = pmac_check_legacy_ioport,
+ .progress = pmac_progress,
+#ifdef CONFIG_PPC64
+ .pci_probe_mode = pmac_probe_mode,
+ .idle_loop = native_idle,
+ .enable_pmcs = power4_enable_pmcs,
+#endif
+#ifdef CONFIG_PPC32
+ .pcibios_enable_device_hook = pmac_pci_enable_device_hook,
+ .pcibios_after_init = pmac_pcibios_after_init,
+ .phys_mem_access_prot = pci_phys_mem_access_prot,
+#endif
+};
diff --git a/arch/powerpc/platforms/powermac/sleep.S b/arch/powerpc/platforms/powermac/sleep.S
new file mode 100644
index 000000000000..22b113d19b24
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/sleep.S
@@ -0,0 +1,396 @@
+/*
+ * This file contains sleep low-level functions for PowerBook G3.
+ * Copyright (C) 1999 Benjamin Herrenschmidt (benh@kernel.crashing.org)
+ * and Paul Mackerras (paulus@samba.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/config.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/ppc_asm.h>
+#include <asm/cputable.h>
+#include <asm/cache.h>
+#include <asm/thread_info.h>
+#include <asm/asm-offsets.h>
+
+#define MAGIC 0x4c617273 /* 'Lars' */
+
+/*
+ * Structure for storing CPU registers on the stack.
+ */
+#define SL_SP 0
+#define SL_PC 4
+#define SL_MSR 8
+#define SL_SDR1 0xc
+#define SL_SPRG0 0x10 /* 4 sprg's */
+#define SL_DBAT0 0x20
+#define SL_IBAT0 0x28
+#define SL_DBAT1 0x30
+#define SL_IBAT1 0x38
+#define SL_DBAT2 0x40
+#define SL_IBAT2 0x48
+#define SL_DBAT3 0x50
+#define SL_IBAT3 0x58
+#define SL_TB 0x60
+#define SL_R2 0x68
+#define SL_CR 0x6c
+#define SL_R12 0x70 /* r12 to r31 */
+#define SL_SIZE (SL_R12 + 80)
+
+ .section .text
+ .align 5
+
+#if defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ_PMAC)
+
+/* This gets called by via-pmu.c late during the sleep process.
+ * The PMU was already send the sleep command and will shut us down
+ * soon. We need to save all that is needed and setup the wakeup
+ * vector that will be called by the ROM on wakeup
+ */
+_GLOBAL(low_sleep_handler)
+#ifndef CONFIG_6xx
+ blr
+#else
+ mflr r0
+ stw r0,4(r1)
+ stwu r1,-SL_SIZE(r1)
+ mfcr r0
+ stw r0,SL_CR(r1)
+ stw r2,SL_R2(r1)
+ stmw r12,SL_R12(r1)
+
+ /* Save MSR & SDR1 */
+ mfmsr r4
+ stw r4,SL_MSR(r1)
+ mfsdr1 r4
+ stw r4,SL_SDR1(r1)
+
+ /* Get a stable timebase and save it */
+1: mftbu r4
+ stw r4,SL_TB(r1)
+ mftb r5
+ stw r5,SL_TB+4(r1)
+ mftbu r3
+ cmpw r3,r4
+ bne 1b
+
+ /* Save SPRGs */
+ mfsprg r4,0
+ stw r4,SL_SPRG0(r1)
+ mfsprg r4,1
+ stw r4,SL_SPRG0+4(r1)
+ mfsprg r4,2
+ stw r4,SL_SPRG0+8(r1)
+ mfsprg r4,3
+ stw r4,SL_SPRG0+12(r1)
+
+ /* Save BATs */
+ mfdbatu r4,0
+ stw r4,SL_DBAT0(r1)
+ mfdbatl r4,0
+ stw r4,SL_DBAT0+4(r1)
+ mfdbatu r4,1
+ stw r4,SL_DBAT1(r1)
+ mfdbatl r4,1
+ stw r4,SL_DBAT1+4(r1)
+ mfdbatu r4,2
+ stw r4,SL_DBAT2(r1)
+ mfdbatl r4,2
+ stw r4,SL_DBAT2+4(r1)
+ mfdbatu r4,3
+ stw r4,SL_DBAT3(r1)
+ mfdbatl r4,3
+ stw r4,SL_DBAT3+4(r1)
+ mfibatu r4,0
+ stw r4,SL_IBAT0(r1)
+ mfibatl r4,0
+ stw r4,SL_IBAT0+4(r1)
+ mfibatu r4,1
+ stw r4,SL_IBAT1(r1)
+ mfibatl r4,1
+ stw r4,SL_IBAT1+4(r1)
+ mfibatu r4,2
+ stw r4,SL_IBAT2(r1)
+ mfibatl r4,2
+ stw r4,SL_IBAT2+4(r1)
+ mfibatu r4,3
+ stw r4,SL_IBAT3(r1)
+ mfibatl r4,3
+ stw r4,SL_IBAT3+4(r1)
+
+ /* Backup various CPU config stuffs */
+ bl __save_cpu_setup
+
+ /* The ROM can wake us up via 2 different vectors:
+ * - On wallstreet & lombard, we must write a magic
+ * value 'Lars' at address 4 and a pointer to a
+ * memory location containing the PC to resume from
+ * at address 0.
+ * - On Core99, we must store the wakeup vector at
+ * address 0x80 and eventually it's parameters
+ * at address 0x84. I've have some trouble with those
+ * parameters however and I no longer use them.
+ */
+ lis r5,grackle_wake_up@ha
+ addi r5,r5,grackle_wake_up@l
+ tophys(r5,r5)
+ stw r5,SL_PC(r1)
+ lis r4,KERNELBASE@h
+ tophys(r5,r1)
+ addi r5,r5,SL_PC
+ lis r6,MAGIC@ha
+ addi r6,r6,MAGIC@l
+ stw r5,0(r4)
+ stw r6,4(r4)
+ /* Setup stuffs at 0x80-0x84 for Core99 */
+ lis r3,core99_wake_up@ha
+ addi r3,r3,core99_wake_up@l
+ tophys(r3,r3)
+ stw r3,0x80(r4)
+ stw r5,0x84(r4)
+ /* Store a pointer to our backup storage into
+ * a kernel global
+ */
+ lis r3,sleep_storage@ha
+ addi r3,r3,sleep_storage@l
+ stw r5,0(r3)
+
+ .globl low_cpu_die
+low_cpu_die:
+ /* Flush & disable all caches */
+ bl flush_disable_caches
+
+ /* Turn off data relocation. */
+ mfmsr r3 /* Save MSR in r7 */
+ rlwinm r3,r3,0,28,26 /* Turn off DR bit */
+ sync
+ mtmsr r3
+ isync
+
+BEGIN_FTR_SECTION
+ /* Flush any pending L2 data prefetches to work around HW bug */
+ sync
+ lis r3,0xfff0
+ lwz r0,0(r3) /* perform cache-inhibited load to ROM */
+ sync /* (caches are disabled at this point) */
+END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
+
+/*
+ * Set the HID0 and MSR for sleep.
+ */
+ mfspr r2,SPRN_HID0
+ rlwinm r2,r2,0,10,7 /* clear doze, nap */
+ oris r2,r2,HID0_SLEEP@h
+ sync
+ isync
+ mtspr SPRN_HID0,r2
+ sync
+
+/* This loop puts us back to sleep in case we have a spurrious
+ * wakeup so that the host bridge properly stays asleep. The
+ * CPU will be turned off, either after a known time (about 1
+ * second) on wallstreet & lombard, or as soon as the CPU enters
+ * SLEEP mode on core99
+ */
+ mfmsr r2
+ oris r2,r2,MSR_POW@h
+1: sync
+ mtmsr r2
+ isync
+ b 1b
+
+/*
+ * Here is the resume code.
+ */
+
+
+/*
+ * Core99 machines resume here
+ * r4 has the physical address of SL_PC(sp) (unused)
+ */
+_GLOBAL(core99_wake_up)
+ /* Make sure HID0 no longer contains any sleep bit and that data cache
+ * is disabled
+ */
+ mfspr r3,SPRN_HID0
+ rlwinm r3,r3,0,11,7 /* clear SLEEP, NAP, DOZE bits */
+ rlwinm 3,r3,0,18,15 /* clear DCE, ICE */
+ mtspr SPRN_HID0,r3
+ sync
+ isync
+
+ /* sanitize MSR */
+ mfmsr r3
+ ori r3,r3,MSR_EE|MSR_IP
+ xori r3,r3,MSR_EE|MSR_IP
+ sync
+ isync
+ mtmsr r3
+ sync
+ isync
+
+ /* Recover sleep storage */
+ lis r3,sleep_storage@ha
+ addi r3,r3,sleep_storage@l
+ tophys(r3,r3)
+ lwz r1,0(r3)
+
+ /* Pass thru to older resume code ... */
+/*
+ * Here is the resume code for older machines.
+ * r1 has the physical address of SL_PC(sp).
+ */
+
+grackle_wake_up:
+
+ /* Restore the kernel's segment registers before
+ * we do any r1 memory access as we are not sure they
+ * are in a sane state above the first 256Mb region
+ */
+ li r0,16 /* load up segment register values */
+ mtctr r0 /* for context 0 */
+ lis r3,0x2000 /* Ku = 1, VSID = 0 */
+ li r4,0
+3: mtsrin r3,r4
+ addi r3,r3,0x111 /* increment VSID */
+ addis r4,r4,0x1000 /* address of next segment */
+ bdnz 3b
+ sync
+ isync
+
+ subi r1,r1,SL_PC
+
+ /* Restore various CPU config stuffs */
+ bl __restore_cpu_setup
+
+ /* Make sure all FPRs have been initialized */
+ bl reloc_offset
+ bl __init_fpu_registers
+
+ /* Invalidate & enable L1 cache, we don't care about
+ * whatever the ROM may have tried to write to memory
+ */
+ bl __inval_enable_L1
+
+ /* Restore the BATs, and SDR1. Then we can turn on the MMU. */
+ lwz r4,SL_SDR1(r1)
+ mtsdr1 r4
+ lwz r4,SL_SPRG0(r1)
+ mtsprg 0,r4
+ lwz r4,SL_SPRG0+4(r1)
+ mtsprg 1,r4
+ lwz r4,SL_SPRG0+8(r1)
+ mtsprg 2,r4
+ lwz r4,SL_SPRG0+12(r1)
+ mtsprg 3,r4
+
+ lwz r4,SL_DBAT0(r1)
+ mtdbatu 0,r4
+ lwz r4,SL_DBAT0+4(r1)
+ mtdbatl 0,r4
+ lwz r4,SL_DBAT1(r1)
+ mtdbatu 1,r4
+ lwz r4,SL_DBAT1+4(r1)
+ mtdbatl 1,r4
+ lwz r4,SL_DBAT2(r1)
+ mtdbatu 2,r4
+ lwz r4,SL_DBAT2+4(r1)
+ mtdbatl 2,r4
+ lwz r4,SL_DBAT3(r1)
+ mtdbatu 3,r4
+ lwz r4,SL_DBAT3+4(r1)
+ mtdbatl 3,r4
+ lwz r4,SL_IBAT0(r1)
+ mtibatu 0,r4
+ lwz r4,SL_IBAT0+4(r1)
+ mtibatl 0,r4
+ lwz r4,SL_IBAT1(r1)
+ mtibatu 1,r4
+ lwz r4,SL_IBAT1+4(r1)
+ mtibatl 1,r4
+ lwz r4,SL_IBAT2(r1)
+ mtibatu 2,r4
+ lwz r4,SL_IBAT2+4(r1)
+ mtibatl 2,r4
+ lwz r4,SL_IBAT3(r1)
+ mtibatu 3,r4
+ lwz r4,SL_IBAT3+4(r1)
+ mtibatl 3,r4
+
+BEGIN_FTR_SECTION
+ li r4,0
+ mtspr SPRN_DBAT4U,r4
+ mtspr SPRN_DBAT4L,r4
+ mtspr SPRN_DBAT5U,r4
+ mtspr SPRN_DBAT5L,r4
+ mtspr SPRN_DBAT6U,r4
+ mtspr SPRN_DBAT6L,r4
+ mtspr SPRN_DBAT7U,r4
+ mtspr SPRN_DBAT7L,r4
+ mtspr SPRN_IBAT4U,r4
+ mtspr SPRN_IBAT4L,r4
+ mtspr SPRN_IBAT5U,r4
+ mtspr SPRN_IBAT5L,r4
+ mtspr SPRN_IBAT6U,r4
+ mtspr SPRN_IBAT6L,r4
+ mtspr SPRN_IBAT7U,r4
+ mtspr SPRN_IBAT7L,r4
+END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS)
+
+ /* Flush all TLBs */
+ lis r4,0x1000
+1: addic. r4,r4,-0x1000
+ tlbie r4
+ blt 1b
+ sync
+
+ /* restore the MSR and turn on the MMU */
+ lwz r3,SL_MSR(r1)
+ bl turn_on_mmu
+
+ /* get back the stack pointer */
+ tovirt(r1,r1)
+
+ /* Restore TB */
+ li r3,0
+ mttbl r3
+ lwz r3,SL_TB(r1)
+ lwz r4,SL_TB+4(r1)
+ mttbu r3
+ mttbl r4
+
+ /* Restore the callee-saved registers and return */
+ lwz r0,SL_CR(r1)
+ mtcr r0
+ lwz r2,SL_R2(r1)
+ lmw r12,SL_R12(r1)
+ addi r1,r1,SL_SIZE
+ lwz r0,4(r1)
+ mtlr r0
+ blr
+
+turn_on_mmu:
+ mflr r4
+ tovirt(r4,r4)
+ mtsrr0 r4
+ mtsrr1 r3
+ sync
+ isync
+ rfi
+
+#endif /* defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ) */
+
+ .section .data
+ .balign L1_CACHE_BYTES
+sleep_storage:
+ .long 0
+ .balign L1_CACHE_BYTES, 0
+
+#endif /* CONFIG_6xx */
+ .section .text
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
new file mode 100644
index 000000000000..e1f9443cc872
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -0,0 +1,865 @@
+/*
+ * SMP support for power macintosh.
+ *
+ * We support both the old "powersurge" SMP architecture
+ * and the current Core99 (G4 PowerMac) machines.
+ *
+ * Note that we don't support the very first rev. of
+ * Apple/DayStar 2 CPUs board, the one with the funky
+ * watchdog. Hopefully, none of these should be there except
+ * maybe internally to Apple. I should probably still add some
+ * code to detect this card though and disable SMP. --BenH.
+ *
+ * Support Macintosh G4 SMP by Troy Benjegerdes (hozer@drgw.net)
+ * and Ben Herrenschmidt <benh@kernel.crashing.org>.
+ *
+ * Support for DayStar quad CPU cards
+ * Copyright (C) XLR8, Inc. 1994-2000
+ *
+ * This program is free software; you can redistribute 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/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/errno.h>
+#include <linux/hardirq.h>
+#include <linux/cpu.h>
+
+#include <asm/ptrace.h>
+#include <asm/atomic.h>
+#include <asm/irq.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/sections.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/smp.h>
+#include <asm/machdep.h>
+#include <asm/pmac_feature.h>
+#include <asm/time.h>
+#include <asm/mpic.h>
+#include <asm/cacheflush.h>
+#include <asm/keylargo.h>
+#include <asm/pmac_low_i2c.h>
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(fmt...) udbg_printf(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+extern void __secondary_start_pmac_0(void);
+
+#ifdef CONFIG_PPC32
+
+/* Sync flag for HW tb sync */
+static volatile int sec_tb_reset = 0;
+
+/*
+ * Powersurge (old powermac SMP) support.
+ */
+
+/* Addresses for powersurge registers */
+#define HAMMERHEAD_BASE 0xf8000000
+#define HHEAD_CONFIG 0x90
+#define HHEAD_SEC_INTR 0xc0
+
+/* register for interrupting the primary processor on the powersurge */
+/* N.B. this is actually the ethernet ROM! */
+#define PSURGE_PRI_INTR 0xf3019000
+
+/* register for storing the start address for the secondary processor */
+/* N.B. this is the PCI config space address register for the 1st bridge */
+#define PSURGE_START 0xf2800000
+
+/* Daystar/XLR8 4-CPU card */
+#define PSURGE_QUAD_REG_ADDR 0xf8800000
+
+#define PSURGE_QUAD_IRQ_SET 0
+#define PSURGE_QUAD_IRQ_CLR 1
+#define PSURGE_QUAD_IRQ_PRIMARY 2
+#define PSURGE_QUAD_CKSTOP_CTL 3
+#define PSURGE_QUAD_PRIMARY_ARB 4
+#define PSURGE_QUAD_BOARD_ID 6
+#define PSURGE_QUAD_WHICH_CPU 7
+#define PSURGE_QUAD_CKSTOP_RDBK 8
+#define PSURGE_QUAD_RESET_CTL 11
+
+#define PSURGE_QUAD_OUT(r, v) (out_8(quad_base + ((r) << 4) + 4, (v)))
+#define PSURGE_QUAD_IN(r) (in_8(quad_base + ((r) << 4) + 4) & 0x0f)
+#define PSURGE_QUAD_BIS(r, v) (PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) | (v)))
+#define PSURGE_QUAD_BIC(r, v) (PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) & ~(v)))
+
+/* virtual addresses for the above */
+static volatile u8 __iomem *hhead_base;
+static volatile u8 __iomem *quad_base;
+static volatile u32 __iomem *psurge_pri_intr;
+static volatile u8 __iomem *psurge_sec_intr;
+static volatile u32 __iomem *psurge_start;
+
+/* values for psurge_type */
+#define PSURGE_NONE -1
+#define PSURGE_DUAL 0
+#define PSURGE_QUAD_OKEE 1
+#define PSURGE_QUAD_COTTON 2
+#define PSURGE_QUAD_ICEGRASS 3
+
+/* what sort of powersurge board we have */
+static int psurge_type = PSURGE_NONE;
+
+/*
+ * Set and clear IPIs for powersurge.
+ */
+static inline void psurge_set_ipi(int cpu)
+{
+ if (psurge_type == PSURGE_NONE)
+ return;
+ if (cpu == 0)
+ in_be32(psurge_pri_intr);
+ else if (psurge_type == PSURGE_DUAL)
+ out_8(psurge_sec_intr, 0);
+ else
+ PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_SET, 1 << cpu);
+}
+
+static inline void psurge_clr_ipi(int cpu)
+{
+ if (cpu > 0) {
+ switch(psurge_type) {
+ case PSURGE_DUAL:
+ out_8(psurge_sec_intr, ~0);
+ case PSURGE_NONE:
+ break;
+ default:
+ PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, 1 << cpu);
+ }
+ }
+}
+
+/*
+ * On powersurge (old SMP powermac architecture) we don't have
+ * separate IPIs for separate messages like openpic does. Instead
+ * we have a bitmap for each processor, where a 1 bit means that
+ * the corresponding message is pending for that processor.
+ * Ideally each cpu's entry would be in a different cache line.
+ * -- paulus.
+ */
+static unsigned long psurge_smp_message[NR_CPUS];
+
+void psurge_smp_message_recv(struct pt_regs *regs)
+{
+ int cpu = smp_processor_id();
+ int msg;
+
+ /* clear interrupt */
+ psurge_clr_ipi(cpu);
+
+ if (num_online_cpus() < 2)
+ return;
+
+ /* make sure there is a message there */
+ for (msg = 0; msg < 4; msg++)
+ if (test_and_clear_bit(msg, &psurge_smp_message[cpu]))
+ smp_message_recv(msg, regs);
+}
+
+irqreturn_t psurge_primary_intr(int irq, void *d, struct pt_regs *regs)
+{
+ psurge_smp_message_recv(regs);
+ return IRQ_HANDLED;
+}
+
+static void smp_psurge_message_pass(int target, int msg)
+{
+ int i;
+
+ if (num_online_cpus() < 2)
+ return;
+
+ for (i = 0; i < NR_CPUS; i++) {
+ if (!cpu_online(i))
+ continue;
+ if (target == MSG_ALL
+ || (target == MSG_ALL_BUT_SELF && i != smp_processor_id())
+ || target == i) {
+ set_bit(msg, &psurge_smp_message[i]);
+ psurge_set_ipi(i);
+ }
+ }
+}
+
+/*
+ * Determine a quad card presence. We read the board ID register, we
+ * force the data bus to change to something else, and we read it again.
+ * It it's stable, then the register probably exist (ugh !)
+ */
+static int __init psurge_quad_probe(void)
+{
+ int type;
+ unsigned int i;
+
+ type = PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID);
+ if (type < PSURGE_QUAD_OKEE || type > PSURGE_QUAD_ICEGRASS
+ || type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID))
+ return PSURGE_DUAL;
+
+ /* looks OK, try a slightly more rigorous test */
+ /* bogus is not necessarily cacheline-aligned,
+ though I don't suppose that really matters. -- paulus */
+ for (i = 0; i < 100; i++) {
+ volatile u32 bogus[8];
+ bogus[(0+i)%8] = 0x00000000;
+ bogus[(1+i)%8] = 0x55555555;
+ bogus[(2+i)%8] = 0xFFFFFFFF;
+ bogus[(3+i)%8] = 0xAAAAAAAA;
+ bogus[(4+i)%8] = 0x33333333;
+ bogus[(5+i)%8] = 0xCCCCCCCC;
+ bogus[(6+i)%8] = 0xCCCCCCCC;
+ bogus[(7+i)%8] = 0x33333333;
+ wmb();
+ asm volatile("dcbf 0,%0" : : "r" (bogus) : "memory");
+ mb();
+ if (type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID))
+ return PSURGE_DUAL;
+ }
+ return type;
+}
+
+static void __init psurge_quad_init(void)
+{
+ int procbits;
+
+ if (ppc_md.progress) ppc_md.progress("psurge_quad_init", 0x351);
+ procbits = ~PSURGE_QUAD_IN(PSURGE_QUAD_WHICH_CPU);
+ if (psurge_type == PSURGE_QUAD_ICEGRASS)
+ PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits);
+ else
+ PSURGE_QUAD_BIC(PSURGE_QUAD_CKSTOP_CTL, procbits);
+ mdelay(33);
+ out_8(psurge_sec_intr, ~0);
+ PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, procbits);
+ PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits);
+ if (psurge_type != PSURGE_QUAD_ICEGRASS)
+ PSURGE_QUAD_BIS(PSURGE_QUAD_CKSTOP_CTL, procbits);
+ PSURGE_QUAD_BIC(PSURGE_QUAD_PRIMARY_ARB, procbits);
+ mdelay(33);
+ PSURGE_QUAD_BIC(PSURGE_QUAD_RESET_CTL, procbits);
+ mdelay(33);
+ PSURGE_QUAD_BIS(PSURGE_QUAD_PRIMARY_ARB, procbits);
+ mdelay(33);
+}
+
+static int __init smp_psurge_probe(void)
+{
+ int i, ncpus;
+
+ /* We don't do SMP on the PPC601 -- paulus */
+ if (PVR_VER(mfspr(SPRN_PVR)) == 1)
+ return 1;
+
+ /*
+ * The powersurge cpu board can be used in the generation
+ * of powermacs that have a socket for an upgradeable cpu card,
+ * including the 7500, 8500, 9500, 9600.
+ * The device tree doesn't tell you if you have 2 cpus because
+ * OF doesn't know anything about the 2nd processor.
+ * Instead we look for magic bits in magic registers,
+ * in the hammerhead memory controller in the case of the
+ * dual-cpu powersurge board. -- paulus.
+ */
+ if (find_devices("hammerhead") == NULL)
+ return 1;
+
+ hhead_base = ioremap(HAMMERHEAD_BASE, 0x800);
+ quad_base = ioremap(PSURGE_QUAD_REG_ADDR, 1024);
+ psurge_sec_intr = hhead_base + HHEAD_SEC_INTR;
+
+ psurge_type = psurge_quad_probe();
+ if (psurge_type != PSURGE_DUAL) {
+ psurge_quad_init();
+ /* All released cards using this HW design have 4 CPUs */
+ ncpus = 4;
+ } else {
+ iounmap(quad_base);
+ if ((in_8(hhead_base + HHEAD_CONFIG) & 0x02) == 0) {
+ /* not a dual-cpu card */
+ iounmap(hhead_base);
+ psurge_type = PSURGE_NONE;
+ return 1;
+ }
+ ncpus = 2;
+ }
+
+ psurge_start = ioremap(PSURGE_START, 4);
+ psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4);
+
+ /* this is not actually strictly necessary -- paulus. */
+ for (i = 1; i < ncpus; ++i)
+ smp_hw_index[i] = i;
+
+ if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352);
+
+ return ncpus;
+}
+
+static void __init smp_psurge_kick_cpu(int nr)
+{
+ unsigned long start = __pa(__secondary_start_pmac_0) + nr * 8;
+ unsigned long a;
+
+ /* may need to flush here if secondary bats aren't setup */
+ for (a = KERNELBASE; a < KERNELBASE + 0x800000; a += 32)
+ asm volatile("dcbf 0,%0" : : "r" (a) : "memory");
+ asm volatile("sync");
+
+ if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu", 0x353);
+
+ out_be32(psurge_start, start);
+ mb();
+
+ psurge_set_ipi(nr);
+ udelay(10);
+ psurge_clr_ipi(nr);
+
+ if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354);
+}
+
+/*
+ * With the dual-cpu powersurge board, the decrementers and timebases
+ * of both cpus are frozen after the secondary cpu is started up,
+ * until we give the secondary cpu another interrupt. This routine
+ * uses this to get the timebases synchronized.
+ * -- paulus.
+ */
+static void __init psurge_dual_sync_tb(int cpu_nr)
+{
+ int t;
+
+ set_dec(tb_ticks_per_jiffy);
+ set_tb(0, 0);
+ last_jiffy_stamp(cpu_nr) = 0;
+
+ if (cpu_nr > 0) {
+ mb();
+ sec_tb_reset = 1;
+ return;
+ }
+
+ /* wait for the secondary to have reset its TB before proceeding */
+ for (t = 10000000; t > 0 && !sec_tb_reset; --t)
+ ;
+
+ /* now interrupt the secondary, starting both TBs */
+ psurge_set_ipi(1);
+
+ smp_tb_synchronized = 1;
+}
+
+static struct irqaction psurge_irqaction = {
+ .handler = psurge_primary_intr,
+ .flags = SA_INTERRUPT,
+ .mask = CPU_MASK_NONE,
+ .name = "primary IPI",
+};
+
+static void __init smp_psurge_setup_cpu(int cpu_nr)
+{
+
+ if (cpu_nr == 0) {
+ /* If we failed to start the second CPU, we should still
+ * send it an IPI to start the timebase & DEC or we might
+ * have them stuck.
+ */
+ if (num_online_cpus() < 2) {
+ if (psurge_type == PSURGE_DUAL)
+ psurge_set_ipi(1);
+ return;
+ }
+ /* reset the entry point so if we get another intr we won't
+ * try to startup again */
+ out_be32(psurge_start, 0x100);
+ if (setup_irq(30, &psurge_irqaction))
+ printk(KERN_ERR "Couldn't get primary IPI interrupt");
+ }
+
+ if (psurge_type == PSURGE_DUAL)
+ psurge_dual_sync_tb(cpu_nr);
+}
+
+void __init smp_psurge_take_timebase(void)
+{
+ /* Dummy implementation */
+}
+
+void __init smp_psurge_give_timebase(void)
+{
+ /* Dummy implementation */
+}
+
+/* PowerSurge-style Macs */
+struct smp_ops_t psurge_smp_ops = {
+ .message_pass = smp_psurge_message_pass,
+ .probe = smp_psurge_probe,
+ .kick_cpu = smp_psurge_kick_cpu,
+ .setup_cpu = smp_psurge_setup_cpu,
+ .give_timebase = smp_psurge_give_timebase,
+ .take_timebase = smp_psurge_take_timebase,
+};
+#endif /* CONFIG_PPC32 - actually powersurge support */
+
+#ifdef CONFIG_PPC64
+/*
+ * G5s enable/disable the timebase via an i2c-connected clock chip.
+ */
+static struct device_node *pmac_tb_clock_chip_host;
+static u8 pmac_tb_pulsar_addr;
+static void (*pmac_tb_freeze)(int freeze);
+static DEFINE_SPINLOCK(timebase_lock);
+static unsigned long timebase;
+
+static void smp_core99_cypress_tb_freeze(int freeze)
+{
+ u8 data;
+ int rc;
+
+ /* Strangely, the device-tree says address is 0xd2, but darwin
+ * accesses 0xd0 ...
+ */
+ pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined);
+ rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
+ 0xd0 | pmac_low_i2c_read,
+ 0x81, &data, 1);
+ if (rc != 0)
+ goto bail;
+
+ data = (data & 0xf3) | (freeze ? 0x00 : 0x0c);
+
+ pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub);
+ rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
+ 0xd0 | pmac_low_i2c_write,
+ 0x81, &data, 1);
+
+ bail:
+ if (rc != 0) {
+ printk("Cypress Timebase %s rc: %d\n",
+ freeze ? "freeze" : "unfreeze", rc);
+ panic("Timebase freeze failed !\n");
+ }
+}
+
+
+static void smp_core99_pulsar_tb_freeze(int freeze)
+{
+ u8 data;
+ int rc;
+
+ pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined);
+ rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
+ pmac_tb_pulsar_addr | pmac_low_i2c_read,
+ 0x2e, &data, 1);
+ if (rc != 0)
+ goto bail;
+
+ data = (data & 0x88) | (freeze ? 0x11 : 0x22);
+
+ pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub);
+ rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
+ pmac_tb_pulsar_addr | pmac_low_i2c_write,
+ 0x2e, &data, 1);
+ bail:
+ if (rc != 0) {
+ printk(KERN_ERR "Pulsar Timebase %s rc: %d\n",
+ freeze ? "freeze" : "unfreeze", rc);
+ panic("Timebase freeze failed !\n");
+ }
+}
+
+
+static void smp_core99_give_timebase(void)
+{
+ /* Open i2c bus for synchronous access */
+ if (pmac_low_i2c_open(pmac_tb_clock_chip_host, 0))
+ panic("Can't open i2c for TB sync !\n");
+
+ spin_lock(&timebase_lock);
+ (*pmac_tb_freeze)(1);
+ mb();
+ timebase = get_tb();
+ spin_unlock(&timebase_lock);
+
+ while (timebase)
+ barrier();
+
+ spin_lock(&timebase_lock);
+ (*pmac_tb_freeze)(0);
+ spin_unlock(&timebase_lock);
+
+ /* Close i2c bus */
+ pmac_low_i2c_close(pmac_tb_clock_chip_host);
+}
+
+
+static void __devinit smp_core99_take_timebase(void)
+{
+ while (!timebase)
+ barrier();
+ spin_lock(&timebase_lock);
+ set_tb(timebase >> 32, timebase & 0xffffffff);
+ timebase = 0;
+ spin_unlock(&timebase_lock);
+}
+
+static void __init smp_core99_setup(int ncpus)
+{
+ struct device_node *cc = NULL;
+ struct device_node *p;
+ u32 *reg;
+ int ok;
+
+ /* HW sync only on these platforms */
+ if (!machine_is_compatible("PowerMac7,2") &&
+ !machine_is_compatible("PowerMac7,3") &&
+ !machine_is_compatible("RackMac3,1"))
+ return;
+
+ /* Look for the clock chip */
+ while ((cc = of_find_node_by_name(cc, "i2c-hwclock")) != NULL) {
+ p = of_get_parent(cc);
+ ok = p && device_is_compatible(p, "uni-n-i2c");
+ of_node_put(p);
+ if (!ok)
+ continue;
+
+ reg = (u32 *)get_property(cc, "reg", NULL);
+ if (reg == NULL)
+ continue;
+
+ switch (*reg) {
+ case 0xd2:
+ if (device_is_compatible(cc, "pulsar-legacy-slewing")) {
+ pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
+ pmac_tb_pulsar_addr = 0xd2;
+ printk(KERN_INFO "Timebase clock is Pulsar chip\n");
+ } else if (device_is_compatible(cc, "cy28508")) {
+ pmac_tb_freeze = smp_core99_cypress_tb_freeze;
+ printk(KERN_INFO "Timebase clock is Cypress chip\n");
+ }
+ break;
+ case 0xd4:
+ pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
+ pmac_tb_pulsar_addr = 0xd4;
+ printk(KERN_INFO "Timebase clock is Pulsar chip\n");
+ break;
+ }
+ if (pmac_tb_freeze != NULL) {
+ pmac_tb_clock_chip_host = of_get_parent(cc);
+ of_node_put(cc);
+ break;
+ }
+ }
+ if (pmac_tb_freeze == NULL) {
+ smp_ops->give_timebase = smp_generic_give_timebase;
+ smp_ops->take_timebase = smp_generic_take_timebase;
+ }
+}
+
+/* nothing to do here, caches are already set up by service processor */
+static inline void __devinit core99_init_caches(int cpu)
+{
+}
+
+#else /* CONFIG_PPC64 */
+
+/*
+ * SMP G4 powermacs use a GPIO to enable/disable the timebase.
+ */
+
+static unsigned int core99_tb_gpio; /* Timebase freeze GPIO */
+
+static unsigned int pri_tb_hi, pri_tb_lo;
+static unsigned int pri_tb_stamp;
+
+/* not __init, called in sleep/wakeup code */
+void smp_core99_give_timebase(void)
+{
+ unsigned long flags;
+ unsigned int t;
+
+ /* wait for the secondary to be in take_timebase */
+ for (t = 100000; t > 0 && !sec_tb_reset; --t)
+ udelay(10);
+ if (!sec_tb_reset) {
+ printk(KERN_WARNING "Timeout waiting sync on second CPU\n");
+ return;
+ }
+
+ /* freeze the timebase and read it */
+ /* disable interrupts so the timebase is disabled for the
+ shortest possible time */
+ local_irq_save(flags);
+ pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 4);
+ pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0);
+ mb();
+ pri_tb_hi = get_tbu();
+ pri_tb_lo = get_tbl();
+ pri_tb_stamp = last_jiffy_stamp(smp_processor_id());
+ mb();
+
+ /* tell the secondary we're ready */
+ sec_tb_reset = 2;
+ mb();
+
+ /* wait for the secondary to have taken it */
+ for (t = 100000; t > 0 && sec_tb_reset; --t)
+ udelay(10);
+ if (sec_tb_reset)
+ printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n");
+ else
+ smp_tb_synchronized = 1;
+
+ /* Now, restart the timebase by leaving the GPIO to an open collector */
+ pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 0);
+ pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0);
+ local_irq_restore(flags);
+}
+
+/* not __init, called in sleep/wakeup code */
+void smp_core99_take_timebase(void)
+{
+ unsigned long flags;
+
+ /* tell the primary we're here */
+ sec_tb_reset = 1;
+ mb();
+
+ /* wait for the primary to set pri_tb_hi/lo */
+ while (sec_tb_reset < 2)
+ mb();
+
+ /* set our stuff the same as the primary */
+ local_irq_save(flags);
+ set_dec(1);
+ set_tb(pri_tb_hi, pri_tb_lo);
+ last_jiffy_stamp(smp_processor_id()) = pri_tb_stamp;
+ mb();
+
+ /* tell the primary we're done */
+ sec_tb_reset = 0;
+ mb();
+ local_irq_restore(flags);
+}
+
+/* L2 and L3 cache settings to pass from CPU0 to CPU1 on G4 cpus */
+volatile static long int core99_l2_cache;
+volatile static long int core99_l3_cache;
+
+static void __devinit core99_init_caches(int cpu)
+{
+ if (!cpu_has_feature(CPU_FTR_L2CR))
+ return;
+
+ if (cpu == 0) {
+ core99_l2_cache = _get_L2CR();
+ printk("CPU0: L2CR is %lx\n", core99_l2_cache);
+ } else {
+ printk("CPU%d: L2CR was %lx\n", cpu, _get_L2CR());
+ _set_L2CR(0);
+ _set_L2CR(core99_l2_cache);
+ printk("CPU%d: L2CR set to %lx\n", cpu, core99_l2_cache);
+ }
+
+ if (!cpu_has_feature(CPU_FTR_L3CR))
+ return;
+
+ if (cpu == 0){
+ core99_l3_cache = _get_L3CR();
+ printk("CPU0: L3CR is %lx\n", core99_l3_cache);
+ } else {
+ printk("CPU%d: L3CR was %lx\n", cpu, _get_L3CR());
+ _set_L3CR(0);
+ _set_L3CR(core99_l3_cache);
+ printk("CPU%d: L3CR set to %lx\n", cpu, core99_l3_cache);
+ }
+}
+
+static void __init smp_core99_setup(int ncpus)
+{
+ struct device_node *cpu;
+ u32 *tbprop = NULL;
+ int i;
+
+ core99_tb_gpio = KL_GPIO_TB_ENABLE; /* default value */
+ cpu = of_find_node_by_type(NULL, "cpu");
+ if (cpu != NULL) {
+ tbprop = (u32 *)get_property(cpu, "timebase-enable", NULL);
+ if (tbprop)
+ core99_tb_gpio = *tbprop;
+ of_node_put(cpu);
+ }
+
+ /* XXX should get this from reg properties */
+ for (i = 1; i < ncpus; ++i)
+ smp_hw_index[i] = i;
+ powersave_nap = 0;
+}
+#endif
+
+static int __init smp_core99_probe(void)
+{
+ struct device_node *cpus;
+ int ncpus = 0;
+
+ if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345);
+
+ /* Count CPUs in the device-tree */
+ for (cpus = NULL; (cpus = of_find_node_by_type(cpus, "cpu")) != NULL;)
+ ++ncpus;
+
+ printk(KERN_INFO "PowerMac SMP probe found %d cpus\n", ncpus);
+
+ /* Nothing more to do if less than 2 of them */
+ if (ncpus <= 1)
+ return 1;
+
+ smp_core99_setup(ncpus);
+ mpic_request_ipis();
+ core99_init_caches(0);
+
+ return ncpus;
+}
+
+static void __devinit smp_core99_kick_cpu(int nr)
+{
+ unsigned int save_vector;
+ unsigned long new_vector;
+ unsigned long flags;
+ volatile unsigned int *vector
+ = ((volatile unsigned int *)(KERNELBASE+0x100));
+
+ if (nr < 0 || nr > 3)
+ return;
+ if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu", 0x346);
+
+ local_irq_save(flags);
+ local_irq_disable();
+
+ /* Save reset vector */
+ save_vector = *vector;
+
+ /* Setup fake reset vector that does
+ * b __secondary_start_pmac_0 + nr*8 - KERNELBASE
+ */
+ new_vector = (unsigned long) __secondary_start_pmac_0 + nr * 8;
+ *vector = 0x48000002 + new_vector - KERNELBASE;
+
+ /* flush data cache and inval instruction cache */
+ flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);
+
+ /* Put some life in our friend */
+ pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0);
+
+ /* FIXME: We wait a bit for the CPU to take the exception, I should
+ * instead wait for the entry code to set something for me. Well,
+ * ideally, all that crap will be done in prom.c and the CPU left
+ * in a RAM-based wait loop like CHRP.
+ */
+ mdelay(1);
+
+ /* Restore our exception vector */
+ *vector = save_vector;
+ flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);
+
+ local_irq_restore(flags);
+ if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu done", 0x347);
+}
+
+static void __devinit smp_core99_setup_cpu(int cpu_nr)
+{
+ /* Setup L2/L3 */
+ if (cpu_nr != 0)
+ core99_init_caches(cpu_nr);
+
+ /* Setup openpic */
+ mpic_setup_this_cpu();
+
+ if (cpu_nr == 0) {
+#ifdef CONFIG_POWER4
+ extern void g5_phy_disable_cpu1(void);
+
+ /* If we didn't start the second CPU, we must take
+ * it off the bus
+ */
+ if (machine_is_compatible("MacRISC4") &&
+ num_online_cpus() < 2)
+ g5_phy_disable_cpu1();
+#endif /* CONFIG_POWER4 */
+ if (ppc_md.progress) ppc_md.progress("core99_setup_cpu 0 done", 0x349);
+ }
+}
+
+
+/* Core99 Macs (dual G4s and G5s) */
+struct smp_ops_t core99_smp_ops = {
+ .message_pass = smp_mpic_message_pass,
+ .probe = smp_core99_probe,
+ .kick_cpu = smp_core99_kick_cpu,
+ .setup_cpu = smp_core99_setup_cpu,
+ .give_timebase = smp_core99_give_timebase,
+ .take_timebase = smp_core99_take_timebase,
+};
+
+#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)
+
+int __cpu_disable(void)
+{
+ cpu_clear(smp_processor_id(), cpu_online_map);
+
+ /* XXX reset cpu affinity here */
+ mpic_cpu_set_priority(0xf);
+ asm volatile("mtdec %0" : : "r" (0x7fffffff));
+ mb();
+ udelay(20);
+ asm volatile("mtdec %0" : : "r" (0x7fffffff));
+ return 0;
+}
+
+extern void low_cpu_die(void) __attribute__((noreturn)); /* in sleep.S */
+static int cpu_dead[NR_CPUS];
+
+void cpu_die(void)
+{
+ local_irq_disable();
+ cpu_dead[smp_processor_id()] = 1;
+ mb();
+ low_cpu_die();
+}
+
+void __cpu_die(unsigned int cpu)
+{
+ int timeout;
+
+ timeout = 1000;
+ while (!cpu_dead[cpu]) {
+ if (--timeout == 0) {
+ printk("CPU %u refused to die!\n", cpu);
+ break;
+ }
+ msleep(1);
+ }
+ cpu_callin_map[cpu] = 0;
+ cpu_dead[cpu] = 0;
+}
+
+#endif
diff --git a/arch/powerpc/platforms/powermac/time.c b/arch/powerpc/platforms/powermac/time.c
new file mode 100644
index 000000000000..5947b21a8588
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/time.c
@@ -0,0 +1,360 @@
+/*
+ * Support for periodic interrupts (100 per second) and for getting
+ * the current time from the RTC on Power Macintoshes.
+ *
+ * We use the decrementer register for our periodic interrupts.
+ *
+ * Paul Mackerras August 1996.
+ * Copyright (C) 1996 Paul Mackerras.
+ * Copyright (C) 2003-2005 Benjamin Herrenschmidt.
+ *
+ */
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/time.h>
+#include <linux/adb.h>
+#include <linux/cuda.h>
+#include <linux/pmu.h>
+#include <linux/interrupt.h>
+#include <linux/hardirq.h>
+#include <linux/rtc.h>
+
+#include <asm/sections.h>
+#include <asm/prom.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/machdep.h>
+#include <asm/time.h>
+#include <asm/nvram.h>
+#include <asm/smu.h>
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+/* Apparently the RTC stores seconds since 1 Jan 1904 */
+#define RTC_OFFSET 2082844800
+
+/*
+ * Calibrate the decrementer frequency with the VIA timer 1.
+ */
+#define VIA_TIMER_FREQ_6 4700000 /* time 1 frequency * 6 */
+
+/* VIA registers */
+#define RS 0x200 /* skip between registers */
+#define T1CL (4*RS) /* Timer 1 ctr/latch (low 8 bits) */
+#define T1CH (5*RS) /* Timer 1 counter (high 8 bits) */
+#define T1LL (6*RS) /* Timer 1 latch (low 8 bits) */
+#define T1LH (7*RS) /* Timer 1 latch (high 8 bits) */
+#define ACR (11*RS) /* Auxiliary control register */
+#define IFR (13*RS) /* Interrupt flag register */
+
+/* Bits in ACR */
+#define T1MODE 0xc0 /* Timer 1 mode */
+#define T1MODE_CONT 0x40 /* continuous interrupts */
+
+/* Bits in IFR and IER */
+#define T1_INT 0x40 /* Timer 1 interrupt */
+
+long __init pmac_time_init(void)
+{
+ s32 delta = 0;
+#ifdef CONFIG_NVRAM
+ int dst;
+
+ delta = ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x9)) << 16;
+ delta |= ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xa)) << 8;
+ delta |= pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xb);
+ if (delta & 0x00800000UL)
+ delta |= 0xFF000000UL;
+ dst = ((pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x8) & 0x80) != 0);
+ printk("GMT Delta read from XPRAM: %d minutes, DST: %s\n", delta/60,
+ dst ? "on" : "off");
+#endif
+ return delta;
+}
+
+static void to_rtc_time(unsigned long now, struct rtc_time *tm)
+{
+ to_tm(now, tm);
+ tm->tm_year -= 1900;
+ tm->tm_mon -= 1;
+}
+
+static unsigned long from_rtc_time(struct rtc_time *tm)
+{
+ return mktime(tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+}
+
+#ifdef CONFIG_ADB_CUDA
+static unsigned long cuda_get_time(void)
+{
+ struct adb_request req;
+ unsigned long now;
+
+ if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0)
+ return 0;
+ while (!req.complete)
+ cuda_poll();
+ if (req.reply_len != 7)
+ printk(KERN_ERR "cuda_get_time: got %d byte reply\n",
+ req.reply_len);
+ now = (req.reply[3] << 24) + (req.reply[4] << 16)
+ + (req.reply[5] << 8) + req.reply[6];
+ return now - RTC_OFFSET;
+}
+
+#define cuda_get_rtc_time(tm) to_rtc_time(cuda_get_time(), (tm))
+
+static int cuda_set_rtc_time(struct rtc_time *tm)
+{
+ unsigned int nowtime;
+ struct adb_request req;
+
+ nowtime = from_rtc_time(tm) + RTC_OFFSET;
+ if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME,
+ nowtime >> 24, nowtime >> 16, nowtime >> 8,
+ nowtime) < 0)
+ return -ENXIO;
+ while (!req.complete)
+ cuda_poll();
+ if ((req.reply_len != 3) && (req.reply_len != 7))
+ printk(KERN_ERR "cuda_set_rtc_time: got %d byte reply\n",
+ req.reply_len);
+ return 0;
+}
+
+#else
+#define cuda_get_time() 0
+#define cuda_get_rtc_time(tm)
+#define cuda_set_rtc_time(tm) 0
+#endif
+
+#ifdef CONFIG_ADB_PMU
+static unsigned long pmu_get_time(void)
+{
+ struct adb_request req;
+ unsigned long now;
+
+ if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0)
+ return 0;
+ pmu_wait_complete(&req);
+ if (req.reply_len != 4)
+ printk(KERN_ERR "pmu_get_time: got %d byte reply from PMU\n",
+ req.reply_len);
+ now = (req.reply[0] << 24) + (req.reply[1] << 16)
+ + (req.reply[2] << 8) + req.reply[3];
+ return now - RTC_OFFSET;
+}
+
+#define pmu_get_rtc_time(tm) to_rtc_time(pmu_get_time(), (tm))
+
+static int pmu_set_rtc_time(struct rtc_time *tm)
+{
+ unsigned int nowtime;
+ struct adb_request req;
+
+ nowtime = from_rtc_time(tm) + RTC_OFFSET;
+ if (pmu_request(&req, NULL, 5, PMU_SET_RTC, nowtime >> 24,
+ nowtime >> 16, nowtime >> 8, nowtime) < 0)
+ return -ENXIO;
+ pmu_wait_complete(&req);
+ if (req.reply_len != 0)
+ printk(KERN_ERR "pmu_set_rtc_time: %d byte reply from PMU\n",
+ req.reply_len);
+ return 0;
+}
+
+#else
+#define pmu_get_time() 0
+#define pmu_get_rtc_time(tm)
+#define pmu_set_rtc_time(tm) 0
+#endif
+
+#ifdef CONFIG_PMAC_SMU
+static unsigned long smu_get_time(void)
+{
+ struct rtc_time tm;
+
+ if (smu_get_rtc_time(&tm, 1))
+ return 0;
+ return from_rtc_time(&tm);
+}
+
+#else
+#define smu_get_time() 0
+#define smu_get_rtc_time(tm, spin)
+#define smu_set_rtc_time(tm, spin) 0
+#endif
+
+unsigned long pmac_get_boot_time(void)
+{
+ /* Get the time from the RTC, used only at boot time */
+ switch (sys_ctrler) {
+ case SYS_CTRLER_CUDA:
+ return cuda_get_time();
+ case SYS_CTRLER_PMU:
+ return pmu_get_time();
+ case SYS_CTRLER_SMU:
+ return smu_get_time();
+ default:
+ return 0;
+ }
+}
+
+void pmac_get_rtc_time(struct rtc_time *tm)
+{
+ /* Get the time from the RTC, used only at boot time */
+ switch (sys_ctrler) {
+ case SYS_CTRLER_CUDA:
+ cuda_get_rtc_time(tm);
+ break;
+ case SYS_CTRLER_PMU:
+ pmu_get_rtc_time(tm);
+ break;
+ case SYS_CTRLER_SMU:
+ smu_get_rtc_time(tm, 1);
+ break;
+ default:
+ ;
+ }
+}
+
+int pmac_set_rtc_time(struct rtc_time *tm)
+{
+ switch (sys_ctrler) {
+ case SYS_CTRLER_CUDA:
+ return cuda_set_rtc_time(tm);
+ case SYS_CTRLER_PMU:
+ return pmu_set_rtc_time(tm);
+ case SYS_CTRLER_SMU:
+ return smu_set_rtc_time(tm, 1);
+ default:
+ return -ENODEV;
+ }
+}
+
+#ifdef CONFIG_PPC32
+/*
+ * Calibrate the decrementer register using VIA timer 1.
+ * This is used both on powermacs and CHRP machines.
+ */
+int __init via_calibrate_decr(void)
+{
+ struct device_node *vias;
+ volatile unsigned char __iomem *via;
+ int count = VIA_TIMER_FREQ_6 / 100;
+ unsigned int dstart, dend;
+
+ vias = find_devices("via-cuda");
+ if (vias == 0)
+ vias = find_devices("via-pmu");
+ if (vias == 0)
+ vias = find_devices("via");
+ if (vias == 0 || vias->n_addrs == 0)
+ return 0;
+ via = ioremap(vias->addrs[0].address, vias->addrs[0].size);
+
+ /* set timer 1 for continuous interrupts */
+ out_8(&via[ACR], (via[ACR] & ~T1MODE) | T1MODE_CONT);
+ /* set the counter to a small value */
+ out_8(&via[T1CH], 2);
+ /* set the latch to `count' */
+ out_8(&via[T1LL], count);
+ out_8(&via[T1LH], count >> 8);
+ /* wait until it hits 0 */
+ while ((in_8(&via[IFR]) & T1_INT) == 0)
+ ;
+ dstart = get_dec();
+ /* clear the interrupt & wait until it hits 0 again */
+ in_8(&via[T1CL]);
+ while ((in_8(&via[IFR]) & T1_INT) == 0)
+ ;
+ dend = get_dec();
+
+ ppc_tb_freq = (dstart - dend) * 100 / 6;
+
+ iounmap(via);
+
+ return 1;
+}
+#endif
+
+#ifdef CONFIG_PM
+/*
+ * Reset the time after a sleep.
+ */
+static int
+time_sleep_notify(struct pmu_sleep_notifier *self, int when)
+{
+ static unsigned long time_diff;
+ unsigned long flags;
+ unsigned long seq;
+ struct timespec tv;
+
+ switch (when) {
+ case PBOOK_SLEEP_NOW:
+ do {
+ seq = read_seqbegin_irqsave(&xtime_lock, flags);
+ time_diff = xtime.tv_sec - pmac_get_boot_time();
+ } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
+ break;
+ case PBOOK_WAKE:
+ tv.tv_sec = pmac_get_boot_time() + time_diff;
+ tv.tv_nsec = 0;
+ do_settimeofday(&tv);
+ break;
+ }
+ return PBOOK_SLEEP_OK;
+}
+
+static struct pmu_sleep_notifier time_sleep_notifier = {
+ time_sleep_notify, SLEEP_LEVEL_MISC,
+};
+#endif /* CONFIG_PM */
+
+/*
+ * Query the OF and get the decr frequency.
+ */
+void __init pmac_calibrate_decr(void)
+{
+#ifdef CONFIG_PM
+ /* XXX why here? */
+ pmu_register_sleep_notifier(&time_sleep_notifier);
+#endif /* CONFIG_PM */
+
+ generic_calibrate_decr();
+
+#ifdef CONFIG_PPC32
+ /* We assume MacRISC2 machines have correct device-tree
+ * calibration. That's better since the VIA itself seems
+ * to be slightly off. --BenH
+ */
+ if (!machine_is_compatible("MacRISC2") &&
+ !machine_is_compatible("MacRISC3") &&
+ !machine_is_compatible("MacRISC4"))
+ if (via_calibrate_decr())
+ return;
+
+ /* Special case: QuickSilver G4s seem to have a badly calibrated
+ * timebase-frequency in OF, VIA is much better on these. We should
+ * probably implement calibration based on the KL timer on these
+ * machines anyway... -BenH
+ */
+ if (machine_is_compatible("PowerMac3,5"))
+ if (via_calibrate_decr())
+ return;
+#endif
+}
diff --git a/arch/powerpc/platforms/prep/Kconfig b/arch/powerpc/platforms/prep/Kconfig
new file mode 100644
index 000000000000..673ac47a1626
--- /dev/null
+++ b/arch/powerpc/platforms/prep/Kconfig
@@ -0,0 +1,22 @@
+
+config PREP_RESIDUAL
+ bool "Support for PReP Residual Data"
+ depends on PPC_PREP
+ help
+ Some PReP systems have residual data passed to the kernel by the
+ firmware. This allows detection of memory size, devices present and
+ other useful pieces of information. Sometimes this information is
+ not present or incorrect, in which case it could lead to the machine
+ behaving incorrectly. If this happens, either disable PREP_RESIDUAL
+ or pass the 'noresidual' option to the kernel.
+
+ If you are running a PReP system, say Y here, otherwise say N.
+
+config PROC_PREPRESIDUAL
+ bool "Support for reading of PReP Residual Data in /proc"
+ depends on PREP_RESIDUAL && PROC_FS
+ help
+ Enabling this option will create a /proc/residual file which allows
+ you to get at the residual data on PReP systems. You will need a tool
+ (lsresidual) to parse it. If you aren't on a PReP system, you don't
+ want this.
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig
new file mode 100644
index 000000000000..2d57f588151d
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -0,0 +1,42 @@
+
+config PPC_SPLPAR
+ depends on PPC_PSERIES
+ bool "Support for shared-processor logical partitions"
+ default n
+ help
+ Enabling this option will make the kernel run more efficiently
+ on logically-partitioned pSeries systems which use shared
+ processors, that is, which share physical processors between
+ two or more partitions.
+
+config HMT
+ bool "Hardware multithreading"
+ depends on SMP && PPC_PSERIES && BROKEN
+ help
+ This option enables hardware multithreading on RS64 cpus.
+ pSeries systems p620 and p660 have such a cpu type.
+
+config EEH
+ bool "PCI Extended Error Handling (EEH)" if EMBEDDED
+ depends on PPC_PSERIES
+ default y if !EMBEDDED
+
+config RTAS_PROC
+ bool "Proc interface to RTAS"
+ depends on PPC_RTAS
+ default y
+
+config RTAS_FLASH
+ tristate "Firmware flash interface"
+ depends on PPC64 && RTAS_PROC
+
+config SCANLOG
+ tristate "Scanlog dump interface"
+ depends on RTAS_PROC && PPC_PSERIES
+
+config LPARCFG
+ tristate "LPAR Configuration Data"
+ depends on PPC_PSERIES || PPC_ISERIES
+ help
+ Provide system capacity information via human readable
+ <key word>=<value> pairs through a /proc/ppc64/lparcfg interface.
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
new file mode 100644
index 000000000000..5ef494e3a70f
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -0,0 +1,5 @@
+obj-y := pci.o lpar.o hvCall.o nvram.o reconfig.o \
+ setup.o iommu.o rtas-fw.o ras.o
+obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_IBMVIO) += vio.o
+obj-$(CONFIG_XICS) += xics.o
diff --git a/arch/ppc64/kernel/pSeries_hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S
index 176e8da76466..176e8da76466 100644
--- a/arch/ppc64/kernel/pSeries_hvCall.S
+++ b/arch/powerpc/platforms/pseries/hvCall.S
diff --git a/arch/ppc64/kernel/pSeries_iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index d17f0108a032..9e90d41131d8 100644
--- a/arch/ppc64/kernel/pSeries_iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -46,7 +46,8 @@
#include <asm/pSeries_reconfig.h>
#include <asm/systemcfg.h>
#include <asm/firmware.h>
-#include "pci.h"
+#include <asm/tce.h>
+#include <asm/ppc-pci.h>
#define DBG(fmt...)
@@ -59,6 +60,9 @@ static void tce_build_pSeries(struct iommu_table *tbl, long index,
union tce_entry t;
union tce_entry *tp;
+ index <<= TCE_PAGE_FACTOR;
+ npages <<= TCE_PAGE_FACTOR;
+
t.te_word = 0;
t.te_rdwr = 1; // Read allowed
@@ -69,11 +73,11 @@ static void tce_build_pSeries(struct iommu_table *tbl, long index,
while (npages--) {
/* can't move this out since we might cross LMB boundary */
- t.te_rpn = (virt_to_abs(uaddr)) >> PAGE_SHIFT;
+ t.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
tp->te_word = t.te_word;
- uaddr += PAGE_SIZE;
+ uaddr += TCE_PAGE_SIZE;
tp++;
}
}
@@ -84,6 +88,9 @@ static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages)
union tce_entry t;
union tce_entry *tp;
+ npages <<= TCE_PAGE_FACTOR;
+ index <<= TCE_PAGE_FACTOR;
+
t.te_word = 0;
tp = ((union tce_entry *)tbl->it_base) + index;
@@ -103,7 +110,7 @@ static void tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
union tce_entry tce;
tce.te_word = 0;
- tce.te_rpn = (virt_to_abs(uaddr)) >> PAGE_SHIFT;
+ tce.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
tce.te_rdwr = 1;
if (direction != DMA_TO_DEVICE)
tce.te_pciwr = 1;
@@ -136,6 +143,9 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
union tce_entry tce, *tcep;
long l, limit;
+ tcenum <<= TCE_PAGE_FACTOR;
+ npages <<= TCE_PAGE_FACTOR;
+
if (npages == 1)
return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr,
direction);
@@ -155,7 +165,7 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
}
tce.te_word = 0;
- tce.te_rpn = (virt_to_abs(uaddr)) >> PAGE_SHIFT;
+ tce.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
tce.te_rdwr = 1;
if (direction != DMA_TO_DEVICE)
tce.te_pciwr = 1;
@@ -166,7 +176,7 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
* Set up the page with TCE data, looping through and setting
* the values.
*/
- limit = min_t(long, npages, PAGE_SIZE/sizeof(union tce_entry));
+ limit = min_t(long, npages, 4096/sizeof(union tce_entry));
for (l = 0; l < limit; l++) {
tcep[l] = tce;
@@ -196,6 +206,9 @@ static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages
u64 rc;
union tce_entry tce;
+ tcenum <<= TCE_PAGE_FACTOR;
+ npages <<= TCE_PAGE_FACTOR;
+
tce.te_word = 0;
while (npages--) {
@@ -221,6 +234,9 @@ static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long n
u64 rc;
union tce_entry tce;
+ tcenum <<= TCE_PAGE_FACTOR;
+ npages <<= TCE_PAGE_FACTOR;
+
tce.te_word = 0;
rc = plpar_tce_stuff((u64)tbl->it_index,
diff --git a/arch/ppc64/kernel/pSeries_lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index a6de83f2078f..268d8362dde7 100644
--- a/arch/ppc64/kernel/pSeries_lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -486,8 +486,7 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
* Take a spinlock around flushes to avoid bouncing the hypervisor tlbie
* lock.
*/
-void pSeries_lpar_flush_hash_range(unsigned long context, unsigned long number,
- int local)
+void pSeries_lpar_flush_hash_range(unsigned long number, int local)
{
int i;
unsigned long flags = 0;
@@ -498,7 +497,7 @@ void pSeries_lpar_flush_hash_range(unsigned long context, unsigned long number,
spin_lock_irqsave(&pSeries_lpar_tlbie_lock, flags);
for (i = 0; i < number; i++)
- flush_hash_page(context, batch->addr[i], batch->pte[i], local);
+ flush_hash_page(batch->vaddr[i], batch->pte[i], local);
if (lock_tlbie)
spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags);
diff --git a/arch/ppc64/kernel/pSeries_nvram.c b/arch/powerpc/platforms/pseries/nvram.c
index 18abfb1f4e24..18abfb1f4e24 100644
--- a/arch/ppc64/kernel/pSeries_nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
diff --git a/arch/ppc64/kernel/pSeries_pci.c b/arch/powerpc/platforms/pseries/pci.c
index 928f8febdb3b..c198656a3bb5 100644
--- a/arch/ppc64/kernel/pSeries_pci.c
+++ b/arch/powerpc/platforms/pseries/pci.c
@@ -29,8 +29,7 @@
#include <asm/pci-bridge.h>
#include <asm/prom.h>
-
-#include "pci.h"
+#include <asm/ppc-pci.h>
static int __devinitdata s7a_workaround = -1;
diff --git a/arch/ppc64/kernel/ras.c b/arch/powerpc/platforms/pseries/ras.c
index 41b97dc9cc0a..6562ff4b0a82 100644
--- a/arch/ppc64/kernel/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -1,17 +1,16 @@
/*
- * ras.c
* Copyright (C) 2001 Dave Engebretsen IBM Corporation
- *
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT 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
@@ -19,7 +18,7 @@
/* Change Activity:
* 2001/09/21 : engebret : Created with minimal EPOW and HW exception support.
- * End Change Activity
+ * End Change Activity
*/
#include <linux/errno.h>
@@ -323,7 +322,7 @@ static int recover_mce(struct pt_regs *regs, struct rtas_error_log * err)
nonfatal = 1;
}
- log_error((char *)err, ERR_TYPE_RTAS_LOG, !nonfatal);
+ log_error((char *)err, ERR_TYPE_RTAS_LOG, !nonfatal);
return nonfatal;
}
diff --git a/arch/ppc64/kernel/pSeries_reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index 58c61219d08e..58c61219d08e 100644
--- a/arch/ppc64/kernel/pSeries_reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
diff --git a/arch/powerpc/platforms/pseries/rtas-fw.c b/arch/powerpc/platforms/pseries/rtas-fw.c
new file mode 100644
index 000000000000..15d81d758ca0
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/rtas-fw.c
@@ -0,0 +1,138 @@
+/*
+ *
+ * Procedures for firmware flash updates on pSeries systems.
+ *
+ * Peter Bergner, IBM March 2001.
+ * Copyright (C) 2001 IBM.
+ *
+ * This program is free software; you can redistribute 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 <stdarg.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <asm/prom.h>
+#include <asm/rtas.h>
+#include <asm/semaphore.h>
+#include <asm/machdep.h>
+#include <asm/page.h>
+#include <asm/param.h>
+#include <asm/system.h>
+#include <asm/abs_addr.h>
+#include <asm/udbg.h>
+#include <asm/delay.h>
+#include <asm/uaccess.h>
+#include <asm/systemcfg.h>
+
+#include "rtas-fw.h"
+
+struct flash_block_list_header rtas_firmware_flash_list = {0, NULL};
+
+#define FLASH_BLOCK_LIST_VERSION (1UL)
+
+static void rtas_flash_firmware(void)
+{
+ unsigned long image_size;
+ struct flash_block_list *f, *next, *flist;
+ unsigned long rtas_block_list;
+ int i, status, update_token;
+
+ update_token = rtas_token("ibm,update-flash-64-and-reboot");
+ if (update_token == RTAS_UNKNOWN_SERVICE) {
+ printk(KERN_ALERT "FLASH: ibm,update-flash-64-and-reboot is not available -- not a service partition?\n");
+ printk(KERN_ALERT "FLASH: firmware will not be flashed\n");
+ return;
+ }
+
+ /* NOTE: the "first" block list is a global var with no data
+ * blocks in the kernel data segment. We do this because
+ * we want to ensure this block_list addr is under 4GB.
+ */
+ rtas_firmware_flash_list.num_blocks = 0;
+ flist = (struct flash_block_list *)&rtas_firmware_flash_list;
+ rtas_block_list = virt_to_abs(flist);
+ if (rtas_block_list >= 4UL*1024*1024*1024) {
+ printk(KERN_ALERT "FLASH: kernel bug...flash list header addr above 4GB\n");
+ return;
+ }
+
+ printk(KERN_ALERT "FLASH: preparing saved firmware image for flash\n");
+ /* Update the block_list in place. */
+ image_size = 0;
+ for (f = flist; f; f = next) {
+ /* Translate data addrs to absolute */
+ for (i = 0; i < f->num_blocks; i++) {
+ f->blocks[i].data = (char *)virt_to_abs(f->blocks[i].data);
+ image_size += f->blocks[i].length;
+ }
+ next = f->next;
+ /* Don't translate NULL pointer for last entry */
+ if (f->next)
+ f->next = (struct flash_block_list *)virt_to_abs(f->next);
+ else
+ f->next = NULL;
+ /* make num_blocks into the version/length field */
+ f->num_blocks = (FLASH_BLOCK_LIST_VERSION << 56) | ((f->num_blocks+1)*16);
+ }
+
+ printk(KERN_ALERT "FLASH: flash image is %ld bytes\n", image_size);
+ printk(KERN_ALERT "FLASH: performing flash and reboot\n");
+ rtas_progress("Flashing \n", 0x0);
+ rtas_progress("Please Wait... ", 0x0);
+ printk(KERN_ALERT "FLASH: this will take several minutes. Do not power off!\n");
+ status = rtas_call(update_token, 1, 1, NULL, rtas_block_list);
+ switch (status) { /* should only get "bad" status */
+ case 0:
+ printk(KERN_ALERT "FLASH: success\n");
+ break;
+ case -1:
+ printk(KERN_ALERT "FLASH: hardware error. Firmware may not be not flashed\n");
+ break;
+ case -3:
+ printk(KERN_ALERT "FLASH: image is corrupt or not correct for this platform. Firmware not flashed\n");
+ break;
+ case -4:
+ printk(KERN_ALERT "FLASH: flash failed when partially complete. System may not reboot\n");
+ break;
+ default:
+ printk(KERN_ALERT "FLASH: unknown flash return code %d\n", status);
+ break;
+ }
+}
+
+void rtas_flash_bypass_warning(void)
+{
+ printk(KERN_ALERT "FLASH: firmware flash requires a reboot\n");
+ printk(KERN_ALERT "FLASH: the firmware image will NOT be flashed\n");
+}
+
+
+void rtas_fw_restart(char *cmd)
+{
+ if (rtas_firmware_flash_list.next)
+ rtas_flash_firmware();
+ rtas_restart(cmd);
+}
+
+void rtas_fw_power_off(void)
+{
+ if (rtas_firmware_flash_list.next)
+ rtas_flash_bypass_warning();
+ rtas_power_off();
+}
+
+void rtas_fw_halt(void)
+{
+ if (rtas_firmware_flash_list.next)
+ rtas_flash_bypass_warning();
+ rtas_halt();
+}
+
+EXPORT_SYMBOL(rtas_firmware_flash_list);
diff --git a/arch/powerpc/platforms/pseries/rtas-fw.h b/arch/powerpc/platforms/pseries/rtas-fw.h
new file mode 100644
index 000000000000..e70fa69974a3
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/rtas-fw.h
@@ -0,0 +1,3 @@
+void rtas_fw_restart(char *cmd);
+void rtas_fw_power_off(void);
+void rtas_fw_halt(void);
diff --git a/arch/ppc64/kernel/pSeries_setup.c b/arch/powerpc/platforms/pseries/setup.c
index 3009701eb90d..10cb0f2d9b5b 100644
--- a/arch/ppc64/kernel/pSeries_setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/ppc/kernel/setup.c
+ * 64-bit pSeries and RS/6000 setup code.
*
* Copyright (C) 1995 Linus Torvalds
* Adapted from 'alpha' version by Gary Thomas
@@ -59,13 +59,15 @@
#include <asm/time.h>
#include <asm/nvram.h>
#include <asm/plpar_wrappers.h>
-#include <asm/xics.h>
+#include "xics.h"
#include <asm/firmware.h>
#include <asm/pmc.h>
+#include <asm/mpic.h>
+#include <asm/ppc-pci.h>
+#include <asm/i8259.h>
+#include <asm/udbg.h>
-#include "i8259.h"
-#include "mpic.h"
-#include "pci.h"
+#include "rtas-fw.h"
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
@@ -84,13 +86,12 @@ int fwnmi_active; /* TRUE if an FWNMI handler is present */
extern void pSeries_system_reset_exception(struct pt_regs *regs);
extern int pSeries_machine_check_exception(struct pt_regs *regs);
-static int pseries_shared_idle(void);
-static int pseries_dedicated_idle(void);
+static void pseries_shared_idle(void);
+static void pseries_dedicated_idle(void);
-static volatile void __iomem * chrp_int_ack_special;
struct mpic *pSeries_mpic;
-void pSeries_get_cpuinfo(struct seq_file *m)
+void pSeries_show_cpuinfo(struct seq_file *m)
{
struct device_node *root;
const char *model = "";
@@ -119,19 +120,11 @@ static void __init fwnmi_init(void)
fwnmi_active = 1;
}
-static int pSeries_irq_cascade(struct pt_regs *regs, void *data)
-{
- if (chrp_int_ack_special)
- return readb(chrp_int_ack_special);
- else
- return i8259_irq(smp_processor_id());
-}
-
static void __init pSeries_init_mpic(void)
{
unsigned int *addrp;
struct device_node *np;
- int i;
+ unsigned long intack = 0;
/* All ISUs are setup, complete initialization */
mpic_init(pSeries_mpic);
@@ -142,16 +135,14 @@ static void __init pSeries_init_mpic(void)
get_property(np, "8259-interrupt-acknowledge", NULL)))
printk(KERN_ERR "Cannot find pci to get ack address\n");
else
- chrp_int_ack_special = ioremap(addrp[prom_n_addr_cells(np)-1], 1);
+ intack = addrp[prom_n_addr_cells(np)-1];
of_node_put(np);
/* Setup the legacy interrupts & controller */
- for (i = 0; i < NUM_ISA_INTERRUPTS; i++)
- irq_desc[i].handler = &i8259_pic;
- i8259_init(0);
+ i8259_init(intack, 0);
/* Hook cascade to mpic */
- mpic_setup_cascade(NUM_ISA_INTERRUPTS, pSeries_irq_cascade, NULL);
+ mpic_setup_cascade(NUM_ISA_INTERRUPTS, i8259_irq_cascade, NULL);
}
static void __init pSeries_setup_mpic(void)
@@ -241,10 +232,6 @@ static void __init pSeries_setup_arch(void)
find_and_init_phbs();
eeh_init();
-#ifdef CONFIG_DUMMY_CONSOLE
- conswitchp = &dummy_con;
-#endif
-
pSeries_nvram_init();
/* Choose an idle loop */
@@ -488,8 +475,8 @@ static inline void dedicated_idle_sleep(unsigned int cpu)
}
}
-static int pseries_dedicated_idle(void)
-{
+static void pseries_dedicated_idle(void)
+{
long oldval;
struct paca_struct *lpaca = get_paca();
unsigned int cpu = smp_processor_id();
@@ -544,7 +531,7 @@ static int pseries_dedicated_idle(void)
}
}
-static int pseries_shared_idle(void)
+static void pseries_shared_idle(void)
{
struct paca_struct *lpaca = get_paca();
unsigned int cpu = smp_processor_id();
@@ -586,8 +573,6 @@ static int pseries_shared_idle(void)
if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
cpu_die();
}
-
- return 0;
}
static int pSeries_pci_probe_mode(struct pci_bus *bus)
@@ -601,14 +586,14 @@ struct machdep_calls __initdata pSeries_md = {
.probe = pSeries_probe,
.setup_arch = pSeries_setup_arch,
.init_early = pSeries_init_early,
- .get_cpuinfo = pSeries_get_cpuinfo,
+ .show_cpuinfo = pSeries_show_cpuinfo,
.log_error = pSeries_log_error,
.pcibios_fixup = pSeries_final_fixup,
.pci_probe_mode = pSeries_pci_probe_mode,
.irq_bus_setup = pSeries_irq_bus_setup,
- .restart = rtas_restart,
- .power_off = rtas_power_off,
- .halt = rtas_halt,
+ .restart = rtas_fw_restart,
+ .power_off = rtas_fw_power_off,
+ .halt = rtas_fw_halt,
.panic = rtas_os_term,
.cpu_die = pSeries_mach_cpu_die,
.get_boot_time = rtas_get_boot_time,
diff --git a/arch/ppc64/kernel/pSeries_smp.c b/arch/powerpc/platforms/pseries/smp.c
index d2c7e2c4733b..9c9458ddfc25 100644
--- a/arch/ppc64/kernel/pSeries_smp.c
+++ b/arch/powerpc/platforms/pseries/smp.c
@@ -1,5 +1,5 @@
/*
- * SMP support for pSeries and BPA machines.
+ * SMP support for pSeries machines.
*
* Dave Engebretsen, Peter Bergner, and
* Mike Corrigan {engebret|bergner|mikec}@us.ibm.com
@@ -39,16 +39,14 @@
#include <asm/paca.h>
#include <asm/time.h>
#include <asm/machdep.h>
-#include <asm/xics.h>
+#include "xics.h"
#include <asm/cputable.h>
#include <asm/firmware.h>
#include <asm/system.h>
#include <asm/rtas.h>
#include <asm/plpar_wrappers.h>
#include <asm/pSeries_reconfig.h>
-
-#include "mpic.h"
-#include "bpa_iic.h"
+#include <asm/mpic.h>
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
@@ -343,36 +341,6 @@ static void __devinit smp_xics_setup_cpu(int cpu)
}
#endif /* CONFIG_XICS */
-#ifdef CONFIG_BPA_IIC
-static void smp_iic_message_pass(int target, int msg)
-{
- unsigned int i;
-
- if (target < NR_CPUS) {
- iic_cause_IPI(target, msg);
- } else {
- for_each_online_cpu(i) {
- if (target == MSG_ALL_BUT_SELF
- && i == smp_processor_id())
- continue;
- iic_cause_IPI(i, msg);
- }
- }
-}
-
-static int __init smp_iic_probe(void)
-{
- iic_request_IPIs();
-
- return cpus_weight(cpu_possible_map);
-}
-
-static void __devinit smp_iic_setup_cpu(int cpu)
-{
- if (cpu != boot_cpuid)
- iic_setup_cpu();
-}
-#endif /* CONFIG_BPA_IIC */
static DEFINE_SPINLOCK(timebase_lock);
static unsigned long timebase = 0;
@@ -444,15 +412,6 @@ static struct smp_ops_t pSeries_xics_smp_ops = {
.cpu_bootable = smp_pSeries_cpu_bootable,
};
#endif
-#ifdef CONFIG_BPA_IIC
-static struct smp_ops_t bpa_iic_smp_ops = {
- .message_pass = smp_iic_message_pass,
- .probe = smp_iic_probe,
- .kick_cpu = smp_pSeries_kick_cpu,
- .setup_cpu = smp_iic_setup_cpu,
- .cpu_bootable = smp_pSeries_cpu_bootable,
-};
-#endif
/* This is called very early */
void __init smp_init_pSeries(void)
@@ -472,11 +431,6 @@ void __init smp_init_pSeries(void)
smp_ops = &pSeries_xics_smp_ops;
break;
#endif
-#ifdef CONFIG_BPA_IIC
- case IC_BPA_IIC:
- smp_ops = &bpa_iic_smp_ops;
- break;
-#endif
default:
panic("Invalid interrupt controller");
}
diff --git a/arch/ppc64/kernel/pSeries_vio.c b/arch/powerpc/platforms/pseries/vio.c
index e0ae06f58f86..866379b80c09 100644
--- a/arch/ppc64/kernel/pSeries_vio.c
+++ b/arch/powerpc/platforms/pseries/vio.c
@@ -22,6 +22,7 @@
#include <asm/prom.h>
#include <asm/vio.h>
#include <asm/hvcall.h>
+#include <asm/tce.h>
extern struct subsystem devices_subsys; /* needed for vio_find_name() */
diff --git a/arch/ppc64/kernel/xics.c b/arch/powerpc/platforms/pseries/xics.c
index daf93885dcfa..c72c86f05cb6 100644
--- a/arch/ppc64/kernel/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -1,5 +1,5 @@
-/*
- * arch/ppc64/kernel/xics.c
+/*
+ * arch/powerpc/platforms/pseries/xics.c
*
* Copyright 2000 IBM Corporation.
*
@@ -25,11 +25,11 @@
#include <asm/pgtable.h>
#include <asm/smp.h>
#include <asm/rtas.h>
-#include <asm/xics.h>
#include <asm/hvcall.h>
#include <asm/machdep.h>
+#include <asm/i8259.h>
-#include "i8259.h"
+#include "xics.h"
static unsigned int xics_startup(unsigned int irq);
static void xics_enable_irq(unsigned int irq);
@@ -62,7 +62,7 @@ static struct radix_tree_root irq_map = RADIX_TREE_INIT(GFP_ATOMIC);
/* Want a priority other than 0. Various HW issues require this. */
#define DEFAULT_PRIORITY 5
-/*
+/*
* Mark IPIs as higher priority so we can take them inside interrupts that
* arent marked SA_INTERRUPT
*/
@@ -169,11 +169,11 @@ static inline long plpar_xirr(unsigned long *xirr_ret)
static int pSeriesLP_xirr_info_get(int n_cpu)
{
unsigned long lpar_rc;
- unsigned long return_value;
+ unsigned long return_value;
lpar_rc = plpar_xirr(&return_value);
if (lpar_rc != H_Success)
- panic(" bad return code xirr - rc = %lx \n", lpar_rc);
+ panic(" bad return code xirr - rc = %lx \n", lpar_rc);
return (int)return_value;
}
@@ -185,7 +185,7 @@ static void pSeriesLP_xirr_info_set(int n_cpu, int value)
lpar_rc = plpar_eoi(val64);
if (lpar_rc != H_Success)
panic("bad return code EOI - rc = %ld, value=%lx\n", lpar_rc,
- val64);
+ val64);
}
void pSeriesLP_cppr_info(int n_cpu, u8 value)
@@ -194,7 +194,7 @@ void pSeriesLP_cppr_info(int n_cpu, u8 value)
lpar_rc = plpar_cppr(value);
if (lpar_rc != H_Success)
- panic("bad return code cppr - rc = %lx\n", lpar_rc);
+ panic("bad return code cppr - rc = %lx\n", lpar_rc);
}
static void pSeriesLP_qirr_info(int n_cpu , u8 value)
@@ -203,7 +203,7 @@ static void pSeriesLP_qirr_info(int n_cpu , u8 value)
lpar_rc = plpar_ipi(get_hard_smp_processor_id(n_cpu), value);
if (lpar_rc != H_Success)
- panic("bad return code qirr - rc = %lx\n", lpar_rc);
+ panic("bad return code qirr - rc = %lx\n", lpar_rc);
}
xics_ops pSeriesLP_ops = {
@@ -366,7 +366,7 @@ int xics_get_irq(struct pt_regs *regs)
/* for sanity, this had better be < NR_IRQS - 16 */
if (vec == xics_irq_8259_cascade_real) {
- irq = i8259_irq(cpu);
+ irq = i8259_irq(regs);
if (irq == -1) {
/* Spurious cascaded interrupt. Still must ack xics */
xics_end_irq(irq_offset_up(xics_irq_8259_cascade));
@@ -462,7 +462,7 @@ void xics_init_IRQ(void)
struct xics_interrupt_node {
unsigned long addr;
unsigned long size;
- } intnodes[NR_CPUS];
+ } intnodes[NR_CPUS];
ppc64_boot_msg(0x20, "XICS Init");
@@ -487,7 +487,7 @@ nextnode:
ireg = (uint *)get_property(np, "reg", &ilen);
if (!ireg)
panic("xics_init_IRQ: can't find interrupt reg property");
-
+
while (ilen) {
intnodes[indx].addr = (unsigned long)*ireg++ << 32;
ilen -= sizeof(uint);
@@ -555,7 +555,7 @@ nextnode:
continue;
hard_id = get_hard_smp_processor_id(i);
- xics_per_cpu[i] = ioremap(intnodes[hard_id].addr,
+ xics_per_cpu[i] = ioremap(intnodes[hard_id].addr,
intnodes[hard_id].size);
}
#else
@@ -589,7 +589,7 @@ static int __init xics_setup_i8259(void)
no_action, 0, "8259 cascade", NULL))
printk(KERN_ERR "xics_setup_i8259: couldn't get 8259 "
"cascade\n");
- i8259_init(0);
+ i8259_init(0, 0);
}
return 0;
}
diff --git a/include/asm-ppc64/xics.h b/arch/powerpc/platforms/pseries/xics.h
index 1092af55d707..e14c70868f1d 100644
--- a/include/asm-ppc64/xics.h
+++ b/arch/powerpc/platforms/pseries/xics.h
@@ -1,5 +1,5 @@
-/*
- * arch/ppc64/kernel/xics.h
+/*
+ * arch/powerpc/platforms/pseries/xics.h
*
* Copyright 2000 IBM Corporation.
*
@@ -9,8 +9,8 @@
* 2 of the License, or (at your option) any later version.
*/
-#ifndef _PPC64_KERNEL_XICS_H
-#define _PPC64_KERNEL_XICS_H
+#ifndef _POWERPC_KERNEL_XICS_H
+#define _POWERPC_KERNEL_XICS_H
#include <linux/cache.h>
@@ -31,4 +31,4 @@ struct xics_ipi_struct {
extern struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
-#endif /* _PPC64_KERNEL_XICS_H */
+#endif /* _POWERPC_KERNEL_XICS_H */
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
new file mode 100644
index 000000000000..8acd21dee05d
--- /dev/null
+++ b/arch/powerpc/sysdev/Makefile
@@ -0,0 +1,7 @@
+obj-$(CONFIG_MPIC) += mpic.o
+obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o
+obj-$(CONFIG_PPC_I8259) += i8259.o
+obj-$(CONFIG_PPC_MPC106) += grackle.o
+obj-$(CONFIG_BOOKE) += dcr.o
+obj-$(CONFIG_40x) += dcr.o
+obj-$(CONFIG_U3_DART) += u3_iommu.o
diff --git a/arch/ppc/syslib/dcr.S b/arch/powerpc/sysdev/dcr.S
index 895f10243a43..895f10243a43 100644
--- a/arch/ppc/syslib/dcr.S
+++ b/arch/powerpc/sysdev/dcr.S
diff --git a/arch/powerpc/sysdev/grackle.c b/arch/powerpc/sysdev/grackle.c
new file mode 100644
index 000000000000..b6ec793a23be
--- /dev/null
+++ b/arch/powerpc/sysdev/grackle.c
@@ -0,0 +1,64 @@
+/*
+ * Functions for setting up and using a MPC106 northbridge
+ * Extracted from arch/powerpc/platforms/powermac/pci.c.
+ *
+ * Copyright (C) 2003 Benjamin Herrenschmuidt (benh@kernel.crashing.org)
+ * Copyright (C) 1997 Paul Mackerras (paulus@samba.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/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/grackle.h>
+
+#define GRACKLE_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \
+ | (((o) & ~3) << 24))
+
+#define GRACKLE_PICR1_STG 0x00000040
+#define GRACKLE_PICR1_LOOPSNOOP 0x00000010
+
+/* N.B. this is called before bridges is initialized, so we can't
+ use grackle_pcibios_{read,write}_config_dword. */
+static inline void grackle_set_stg(struct pci_controller* bp, int enable)
+{
+ unsigned int val;
+
+ out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
+ val = in_le32(bp->cfg_data);
+ val = enable? (val | GRACKLE_PICR1_STG) :
+ (val & ~GRACKLE_PICR1_STG);
+ out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
+ out_le32(bp->cfg_data, val);
+ (void)in_le32(bp->cfg_data);
+}
+
+static inline void grackle_set_loop_snoop(struct pci_controller *bp, int enable)
+{
+ unsigned int val;
+
+ out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
+ val = in_le32(bp->cfg_data);
+ val = enable? (val | GRACKLE_PICR1_LOOPSNOOP) :
+ (val & ~GRACKLE_PICR1_LOOPSNOOP);
+ out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
+ out_le32(bp->cfg_data, val);
+ (void)in_le32(bp->cfg_data);
+}
+
+void __init setup_grackle(struct pci_controller *hose)
+{
+ setup_indirect_pci(hose, 0xfec00000, 0xfee00000);
+ if (machine_is_compatible("AAPL,PowerBook1998"))
+ grackle_set_loop_snoop(hose, 1);
+#if 0 /* Disabled for now, HW problems ??? */
+ grackle_set_stg(hose, 1);
+#endif
+}
diff --git a/arch/ppc/syslib/i8259.c b/arch/powerpc/sysdev/i8259.c
index 5c7908c20e43..90bce6e0c191 100644
--- a/arch/ppc/syslib/i8259.c
+++ b/arch/powerpc/sysdev/i8259.c
@@ -1,18 +1,26 @@
+/*
+ * i8259 interrupt controller driver.
+ *
+ * This program is free software; you can redistribute 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/ioport.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include <asm/i8259.h>
-static volatile unsigned char *pci_intack; /* RO, gives us the irq vector */
+static volatile void __iomem *pci_intack; /* RO, gives us the irq vector */
-unsigned char cached_8259[2] = { 0xff, 0xff };
+static unsigned char cached_8259[2] = { 0xff, 0xff };
#define cached_A1 (cached_8259[0])
#define cached_21 (cached_8259[1])
static DEFINE_SPINLOCK(i8259_lock);
-int i8259_pic_irq_offset;
+static int i8259_pic_irq_offset;
/*
* Acknowledge the IRQ using either the PCI host bridge's interrupt
@@ -20,8 +28,7 @@ int i8259_pic_irq_offset;
* which is called. It should be noted that polling is broken on some
* IBM and Motorola PReP boxes so we must use the int-ack feature on them.
*/
-int
-i8259_irq(struct pt_regs *regs)
+int i8259_irq(struct pt_regs *regs)
{
int irq;
@@ -29,7 +36,7 @@ i8259_irq(struct pt_regs *regs)
/* Either int-ack or poll for the IRQ */
if (pci_intack)
- irq = *pci_intack;
+ irq = readb(pci_intack);
else {
/* Perform an interrupt acknowledge cycle on controller 1. */
outb(0x0C, 0x20); /* prepare for poll */
@@ -59,7 +66,12 @@ i8259_irq(struct pt_regs *regs)
}
spin_unlock(&i8259_lock);
- return irq;
+ return irq + i8259_pic_irq_offset;
+}
+
+int i8259_irq_cascade(struct pt_regs *regs, void *unused)
+{
+ return i8259_irq(regs);
}
static void i8259_mask_and_ack_irq(unsigned int irq_nr)
@@ -67,20 +79,18 @@ static void i8259_mask_and_ack_irq(unsigned int irq_nr)
unsigned long flags;
spin_lock_irqsave(&i8259_lock, flags);
- if ( irq_nr >= i8259_pic_irq_offset )
- irq_nr -= i8259_pic_irq_offset;
-
+ irq_nr -= i8259_pic_irq_offset;
if (irq_nr > 7) {
cached_A1 |= 1 << (irq_nr-8);
- inb(0xA1); /* DUMMY */
- outb(cached_A1,0xA1);
- outb(0x20,0xA0); /* Non-specific EOI */
- outb(0x20,0x20); /* Non-specific EOI to cascade */
+ inb(0xA1); /* DUMMY */
+ outb(cached_A1, 0xA1);
+ outb(0x20, 0xA0); /* Non-specific EOI */
+ outb(0x20, 0x20); /* Non-specific EOI to cascade */
} else {
cached_21 |= 1 << irq_nr;
- inb(0x21); /* DUMMY */
- outb(cached_21,0x21);
- outb(0x20,0x20); /* Non-specific EOI */
+ inb(0x21); /* DUMMY */
+ outb(cached_21, 0x21);
+ outb(0x20, 0x20); /* Non-specific EOI */
}
spin_unlock_irqrestore(&i8259_lock, flags);
}
@@ -96,9 +106,8 @@ static void i8259_mask_irq(unsigned int irq_nr)
unsigned long flags;
spin_lock_irqsave(&i8259_lock, flags);
- if ( irq_nr >= i8259_pic_irq_offset )
- irq_nr -= i8259_pic_irq_offset;
- if ( irq_nr < 8 )
+ irq_nr -= i8259_pic_irq_offset;
+ if (irq_nr < 8)
cached_21 |= 1 << irq_nr;
else
cached_A1 |= 1 << (irq_nr-8);
@@ -111,9 +120,8 @@ static void i8259_unmask_irq(unsigned int irq_nr)
unsigned long flags;
spin_lock_irqsave(&i8259_lock, flags);
- if ( irq_nr >= i8259_pic_irq_offset )
- irq_nr -= i8259_pic_irq_offset;
- if ( irq_nr < 8 )
+ irq_nr -= i8259_pic_irq_offset;
+ if (irq_nr < 8)
cached_21 &= ~(1 << irq_nr);
else
cached_A1 &= ~(1 << (irq_nr-8));
@@ -169,12 +177,14 @@ static struct irqaction i8259_irqaction = {
* intack_addr - PCI interrupt acknowledge (real) address which will return
* the active irq from the 8259
*/
-void __init
-i8259_init(long intack_addr)
+void __init i8259_init(unsigned long intack_addr, int offset)
{
unsigned long flags;
+ int i;
spin_lock_irqsave(&i8259_lock, flags);
+ i8259_pic_irq_offset = offset;
+
/* init master interrupt controller */
outb(0x11, 0x20); /* Start init sequence */
outb(0x00, 0x21); /* Vector base */
@@ -198,11 +208,14 @@ i8259_init(long intack_addr)
spin_unlock_irqrestore(&i8259_lock, flags);
/* reserve our resources */
- setup_irq( i8259_pic_irq_offset + 2, &i8259_irqaction);
+ setup_irq(offset + 2, &i8259_irqaction);
request_resource(&ioport_resource, &pic1_iores);
request_resource(&ioport_resource, &pic2_iores);
request_resource(&ioport_resource, &pic_edgectrl_iores);
if (intack_addr != 0)
pci_intack = ioremap(intack_addr, 1);
+
+ for (i = 0; i < NUM_ISA_INTERRUPTS; ++i)
+ irq_desc[offset + i].handler = &i8259_pic;
}
diff --git a/arch/ppc/syslib/indirect_pci.c b/arch/powerpc/sysdev/indirect_pci.c
index e71488469704..e71488469704 100644
--- a/arch/ppc/syslib/indirect_pci.c
+++ b/arch/powerpc/sysdev/indirect_pci.c
diff --git a/arch/ppc64/kernel/mpic.c b/arch/powerpc/sysdev/mpic.c
index 5f5bc73754d9..105f05341a41 100644
--- a/arch/ppc64/kernel/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -1,5 +1,5 @@
/*
- * arch/ppc64/kernel/mpic.c
+ * arch/powerpc/kernel/mpic.c
*
* Driver for interrupt controllers following the OpenPIC standard, the
* common implementation beeing IBM's MPIC. This driver also can deal
@@ -31,8 +31,8 @@
#include <asm/pgtable.h>
#include <asm/irq.h>
#include <asm/machdep.h>
-
-#include "mpic.h"
+#include <asm/mpic.h>
+#include <asm/smp.h>
#ifdef DEBUG
#define DBG(fmt...) printk(fmt)
@@ -44,6 +44,9 @@ static struct mpic *mpics;
static struct mpic *mpic_primary;
static DEFINE_SPINLOCK(mpic_lock);
+#ifdef CONFIG_PPC32 /* XXX for now */
+#define distribute_irqs CONFIG_IRQ_ALL_CPUS
+#endif
/*
* Register accessor functions
@@ -355,7 +358,7 @@ static void mpic_enable_irq(unsigned int irq)
struct mpic *mpic = mpic_from_irq(irq);
unsigned int src = irq - mpic->irq_offset;
- DBG("%s: enable_irq: %d (src %d)\n", mpic->name, irq, src);
+ DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src);
mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & ~MPIC_VECPRI_MASK);
@@ -480,6 +483,7 @@ struct mpic * __init mpic_alloc(unsigned long phys_addr,
if (mpic == NULL)
return NULL;
+
memset(mpic, 0, sizeof(struct mpic));
mpic->name = name;
@@ -506,7 +510,7 @@ struct mpic * __init mpic_alloc(unsigned long phys_addr,
mpic->senses_count = senses_count;
/* Map the global registers */
- mpic->gregs = ioremap(phys_addr + MPIC_GREG_BASE, 0x2000);
+ mpic->gregs = ioremap(phys_addr + MPIC_GREG_BASE, 0x1000);
mpic->tmregs = mpic->gregs + ((MPIC_TIMER_BASE - MPIC_GREG_BASE) >> 2);
BUG_ON(mpic->gregs == NULL);
@@ -644,7 +648,6 @@ void __init mpic_init(struct mpic *mpic)
continue;
irq_desc[mpic->ipi_offset+i].status |= IRQ_PER_CPU;
irq_desc[mpic->ipi_offset+i].handler = &mpic->hc_ipi;
-
#endif /* CONFIG_SMP */
}
@@ -700,7 +703,7 @@ void __init mpic_init(struct mpic *mpic)
/* init hw */
mpic_irq_write(i, MPIC_IRQ_VECTOR_PRI, vecpri);
mpic_irq_write(i, MPIC_IRQ_DESTINATION,
- 1 << get_hard_smp_processor_id(boot_cpuid));
+ 1 << hard_smp_processor_id());
/* init linux descriptors */
if (i < mpic->irq_count) {
@@ -792,6 +795,21 @@ void mpic_setup_this_cpu(void)
#endif /* CONFIG_SMP */
}
+int mpic_cpu_get_priority(void)
+{
+ struct mpic *mpic = mpic_primary;
+
+ return mpic_cpu_read(MPIC_CPU_CURRENT_TASK_PRI);
+}
+
+void mpic_cpu_set_priority(int prio)
+{
+ struct mpic *mpic = mpic_primary;
+
+ prio &= MPIC_CPU_TASKPRI_MASK;
+ mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, prio);
+}
+
/*
* XXX: someone who knows mpic should check this.
* do we need to eoi the ipi including for kexec cpu here (see xics comments)?
@@ -885,4 +903,25 @@ void mpic_request_ipis(void)
printk("IPIs requested... \n");
}
+
+void smp_mpic_message_pass(int target, int msg)
+{
+ /* make sure we're sending something that translates to an IPI */
+ if ((unsigned int)msg > 3) {
+ printk("SMP %d: smp_message_pass: unknown msg %d\n",
+ smp_processor_id(), msg);
+ return;
+ }
+ switch (target) {
+ case MSG_ALL:
+ mpic_send_ipi(msg, 0xffffffff);
+ break;
+ case MSG_ALL_BUT_SELF:
+ mpic_send_ipi(msg, 0xffffffff & ~(1 << smp_processor_id()));
+ break;
+ default:
+ mpic_send_ipi(msg, 1 << target);
+ break;
+ }
+}
#endif /* CONFIG_SMP */
diff --git a/arch/ppc64/kernel/u3_iommu.c b/arch/powerpc/sysdev/u3_iommu.c
index 41ea09cb9ac7..fba871a1bda5 100644
--- a/arch/ppc64/kernel/u3_iommu.c
+++ b/arch/powerpc/sysdev/u3_iommu.c
@@ -44,39 +44,11 @@
#include <asm/abs_addr.h>
#include <asm/cacheflush.h>
#include <asm/lmb.h>
-
-#include "pci.h"
+#include <asm/dart.h>
+#include <asm/ppc-pci.h>
extern int iommu_force_on;
-/* physical base of DART registers */
-#define DART_BASE 0xf8033000UL
-
-/* Offset from base to control register */
-#define DARTCNTL 0
-/* Offset from base to exception register */
-#define DARTEXCP 0x10
-/* Offset from base to TLB tag registers */
-#define DARTTAG 0x1000
-
-
-/* Control Register fields */
-
-/* base address of table (pfn) */
-#define DARTCNTL_BASE_MASK 0xfffff
-#define DARTCNTL_BASE_SHIFT 12
-
-#define DARTCNTL_FLUSHTLB 0x400
-#define DARTCNTL_ENABLE 0x200
-
-/* size of table in pages */
-#define DARTCNTL_SIZE_MASK 0x1ff
-#define DARTCNTL_SIZE_SHIFT 0
-
-/* DART table fields */
-#define DARTMAP_VALID 0x80000000
-#define DARTMAP_RPNMASK 0x00ffffff
-
/* Physical base address and size of the DART table */
unsigned long dart_tablebase; /* exported to htab_initialize */
static unsigned long dart_tablesize;
@@ -152,18 +124,21 @@ static void dart_build(struct iommu_table *tbl, long index,
DBG("dart: build at: %lx, %lx, addr: %x\n", index, npages, uaddr);
+ index <<= DART_PAGE_FACTOR;
+ npages <<= DART_PAGE_FACTOR;
+
dp = ((unsigned int*)tbl->it_base) + index;
/* On U3, all memory is contigous, so we can move this
* out of the loop.
*/
while (npages--) {
- rpn = virt_to_abs(uaddr) >> PAGE_SHIFT;
+ rpn = virt_to_abs(uaddr) >> DART_PAGE_SHIFT;
*(dp++) = DARTMAP_VALID | (rpn & DARTMAP_RPNMASK);
rpn++;
- uaddr += PAGE_SIZE;
+ uaddr += DART_PAGE_SIZE;
}
dart_dirty = 1;
@@ -181,6 +156,9 @@ static void dart_free(struct iommu_table *tbl, long index, long npages)
DBG("dart: free at: %lx, %lx\n", index, npages);
+ index <<= DART_PAGE_FACTOR;
+ npages <<= DART_PAGE_FACTOR;
+
dp = ((unsigned int *)tbl->it_base) + index;
while (npages--)
@@ -209,10 +187,10 @@ static int dart_init(struct device_node *dart_node)
* that to work around what looks like a problem with the HT bridge
* prefetching into invalid pages and corrupting data
*/
- tmp = lmb_alloc(PAGE_SIZE, PAGE_SIZE);
+ tmp = lmb_alloc(DART_PAGE_SIZE, DART_PAGE_SIZE);
if (!tmp)
panic("U3-DART: Cannot allocate spare page!");
- dart_emptyval = DARTMAP_VALID | ((tmp >> PAGE_SHIFT) & DARTMAP_RPNMASK);
+ dart_emptyval = DARTMAP_VALID | ((tmp >> DART_PAGE_SHIFT) & DARTMAP_RPNMASK);
/* Map in DART registers. FIXME: Use device node to get base address */
dart = ioremap(DART_BASE, 0x7000);
@@ -223,8 +201,8 @@ static int dart_init(struct device_node *dart_node)
* table size and enable bit
*/
regword = DARTCNTL_ENABLE |
- ((dart_tablebase >> PAGE_SHIFT) << DARTCNTL_BASE_SHIFT) |
- (((dart_tablesize >> PAGE_SHIFT) & DARTCNTL_SIZE_MASK)
+ ((dart_tablebase >> DART_PAGE_SHIFT) << DARTCNTL_BASE_SHIFT) |
+ (((dart_tablesize >> DART_PAGE_SHIFT) & DARTCNTL_SIZE_MASK)
<< DARTCNTL_SIZE_SHIFT);
dart_vbase = ioremap(virt_to_abs(dart_tablebase), dart_tablesize);
diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile
new file mode 100644
index 000000000000..79a784f0e7a9
--- /dev/null
+++ b/arch/powerpc/xmon/Makefile
@@ -0,0 +1,11 @@
+# Makefile for xmon
+
+ifdef CONFIG_PPC64
+EXTRA_CFLAGS += -mno-minimal-toc
+endif
+
+obj-$(CONFIG_8xx) += start_8xx.o
+obj-$(CONFIG_6xx) += start_32.o
+obj-$(CONFIG_4xx) += start_32.o
+obj-$(CONFIG_PPC64) += start_64.o
+obj-y += xmon.o ppc-dis.o ppc-opc.o subr_prf.o setjmp.o
diff --git a/arch/ppc64/xmon/ansidecl.h b/arch/powerpc/xmon/ansidecl.h
index c9b9f0929e9e..c9b9f0929e9e 100644
--- a/arch/ppc64/xmon/ansidecl.h
+++ b/arch/powerpc/xmon/ansidecl.h
diff --git a/arch/ppc64/xmon/nonstdio.h b/arch/powerpc/xmon/nonstdio.h
index 84211a21c6f4..84211a21c6f4 100644
--- a/arch/ppc64/xmon/nonstdio.h
+++ b/arch/powerpc/xmon/nonstdio.h
diff --git a/arch/ppc64/xmon/ppc-dis.c b/arch/powerpc/xmon/ppc-dis.c
index ac0a9d2427e0..ac0a9d2427e0 100644
--- a/arch/ppc64/xmon/ppc-dis.c
+++ b/arch/powerpc/xmon/ppc-dis.c
diff --git a/arch/ppc64/xmon/ppc-opc.c b/arch/powerpc/xmon/ppc-opc.c
index 5ee8fc32f824..5ee8fc32f824 100644
--- a/arch/ppc64/xmon/ppc-opc.c
+++ b/arch/powerpc/xmon/ppc-opc.c
diff --git a/arch/ppc64/xmon/ppc.h b/arch/powerpc/xmon/ppc.h
index 342237e8dd69..342237e8dd69 100644
--- a/arch/ppc64/xmon/ppc.h
+++ b/arch/powerpc/xmon/ppc.h
diff --git a/arch/powerpc/xmon/setjmp.S b/arch/powerpc/xmon/setjmp.S
new file mode 100644
index 000000000000..f8e40dfd2bff
--- /dev/null
+++ b/arch/powerpc/xmon/setjmp.S
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ * This program is free software; you can redistribute 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.
+ *
+ * NOTE: assert(sizeof(buf) > 23 * sizeof(long))
+ */
+#include <asm/processor.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+
+_GLOBAL(xmon_setjmp)
+ mflr r0
+ STL r0,0(r3)
+ STL r1,SZL(r3)
+ STL r2,2*SZL(r3)
+ mfcr r0
+ STL r0,3*SZL(r3)
+ STL r13,4*SZL(r3)
+ STL r14,5*SZL(r3)
+ STL r15,6*SZL(r3)
+ STL r16,7*SZL(r3)
+ STL r17,8*SZL(r3)
+ STL r18,9*SZL(r3)
+ STL r19,10*SZL(r3)
+ STL r20,11*SZL(r3)
+ STL r21,12*SZL(r3)
+ STL r22,13*SZL(r3)
+ STL r23,14*SZL(r3)
+ STL r24,15*SZL(r3)
+ STL r25,16*SZL(r3)
+ STL r26,17*SZL(r3)
+ STL r27,18*SZL(r3)
+ STL r28,19*SZL(r3)
+ STL r29,20*SZL(r3)
+ STL r30,21*SZL(r3)
+ STL r31,22*SZL(r3)
+ li r3,0
+ blr
+
+_GLOBAL(xmon_longjmp)
+ CMPI r4,0
+ bne 1f
+ li r4,1
+1: LDL r13,4*SZL(r3)
+ LDL r14,5*SZL(r3)
+ LDL r15,6*SZL(r3)
+ LDL r16,7*SZL(r3)
+ LDL r17,8*SZL(r3)
+ LDL r18,9*SZL(r3)
+ LDL r19,10*SZL(r3)
+ LDL r20,11*SZL(r3)
+ LDL r21,12*SZL(r3)
+ LDL r22,13*SZL(r3)
+ LDL r23,14*SZL(r3)
+ LDL r24,15*SZL(r3)
+ LDL r25,16*SZL(r3)
+ LDL r26,17*SZL(r3)
+ LDL r27,18*SZL(r3)
+ LDL r28,19*SZL(r3)
+ LDL r29,20*SZL(r3)
+ LDL r30,21*SZL(r3)
+ LDL r31,22*SZL(r3)
+ LDL r0,3*SZL(r3)
+ mtcrf 0x38,r0
+ LDL r0,0(r3)
+ LDL r1,SZL(r3)
+ LDL r2,2*SZL(r3)
+ mtlr r0
+ mr r3,r4
+ blr
+
+/*
+ * Grab the register values as they are now.
+ * This won't do a particularily good job because we really
+ * want our caller's caller's registers, and our caller has
+ * already executed its prologue.
+ * ToDo: We could reach back into the caller's save area to do
+ * a better job of representing the caller's state (note that
+ * that will be different for 32-bit and 64-bit, because of the
+ * different ABIs, though).
+ */
+_GLOBAL(xmon_save_regs)
+ STL r0,0*SZL(r3)
+ STL r2,2*SZL(r3)
+ STL r3,3*SZL(r3)
+ STL r4,4*SZL(r3)
+ STL r5,5*SZL(r3)
+ STL r6,6*SZL(r3)
+ STL r7,7*SZL(r3)
+ STL r8,8*SZL(r3)
+ STL r9,9*SZL(r3)
+ STL r10,10*SZL(r3)
+ STL r11,11*SZL(r3)
+ STL r12,12*SZL(r3)
+ STL r13,13*SZL(r3)
+ STL r14,14*SZL(r3)
+ STL r15,15*SZL(r3)
+ STL r16,16*SZL(r3)
+ STL r17,17*SZL(r3)
+ STL r18,18*SZL(r3)
+ STL r19,19*SZL(r3)
+ STL r20,20*SZL(r3)
+ STL r21,21*SZL(r3)
+ STL r22,22*SZL(r3)
+ STL r23,23*SZL(r3)
+ STL r24,24*SZL(r3)
+ STL r25,25*SZL(r3)
+ STL r26,26*SZL(r3)
+ STL r27,27*SZL(r3)
+ STL r28,28*SZL(r3)
+ STL r29,29*SZL(r3)
+ STL r30,30*SZL(r3)
+ STL r31,31*SZL(r3)
+ /* go up one stack frame for SP */
+ LDL r4,0(r1)
+ STL r4,1*SZL(r3)
+ /* get caller's LR */
+ LDL r0,LRSAVE(r4)
+ STL r0,_NIP-STACK_FRAME_OVERHEAD(r3)
+ STL r0,_LINK-STACK_FRAME_OVERHEAD(r3)
+ mfmsr r0
+ STL r0,_MSR-STACK_FRAME_OVERHEAD(r3)
+ mfctr r0
+ STL r0,_CTR-STACK_FRAME_OVERHEAD(r3)
+ mfxer r0
+ STL r0,_XER-STACK_FRAME_OVERHEAD(r3)
+ mfcr r0
+ STL r0,_CCR-STACK_FRAME_OVERHEAD(r3)
+ li r0,0
+ STL r0,_TRAP-STACK_FRAME_OVERHEAD(r3)
+ blr
diff --git a/arch/powerpc/xmon/start_32.c b/arch/powerpc/xmon/start_32.c
new file mode 100644
index 000000000000..69b658c0f760
--- /dev/null
+++ b/arch/powerpc/xmon/start_32.c
@@ -0,0 +1,624 @@
+/*
+ * Copyright (C) 1996 Paul Mackerras.
+ */
+#include <linux/config.h>
+#include <linux/string.h>
+#include <asm/machdep.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <linux/adb.h>
+#include <linux/pmu.h>
+#include <linux/cuda.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/sysrq.h>
+#include <linux/bitops.h>
+#include <asm/xmon.h>
+#include <asm/prom.h>
+#include <asm/bootx.h>
+#include <asm/machdep.h>
+#include <asm/errno.h>
+#include <asm/pmac_feature.h>
+#include <asm/processor.h>
+#include <asm/delay.h>
+#include <asm/btext.h>
+
+static volatile unsigned char __iomem *sccc, *sccd;
+unsigned int TXRDY, RXRDY, DLAB;
+static int xmon_expect(const char *str, unsigned int timeout);
+
+static int use_serial;
+static int use_screen;
+static int via_modem;
+static int xmon_use_sccb;
+static struct device_node *channel_node;
+
+#define TB_SPEED 25000000
+
+static inline unsigned int readtb(void)
+{
+ unsigned int ret;
+
+ asm volatile("mftb %0" : "=r" (ret) :);
+ return ret;
+}
+
+void buf_access(void)
+{
+ if (DLAB)
+ sccd[3] &= ~DLAB; /* reset DLAB */
+}
+
+extern int adb_init(void);
+
+#ifdef CONFIG_PPC_CHRP
+/*
+ * This looks in the "ranges" property for the primary PCI host bridge
+ * to find the physical address of the start of PCI/ISA I/O space.
+ * It is basically a cut-down version of pci_process_bridge_OF_ranges.
+ */
+static unsigned long chrp_find_phys_io_base(void)
+{
+ struct device_node *node;
+ unsigned int *ranges;
+ unsigned long base = CHRP_ISA_IO_BASE;
+ int rlen = 0;
+ int np;
+
+ node = find_devices("isa");
+ if (node != NULL) {
+ node = node->parent;
+ if (node == NULL || node->type == NULL
+ || strcmp(node->type, "pci") != 0)
+ node = NULL;
+ }
+ if (node == NULL)
+ node = find_devices("pci");
+ if (node == NULL)
+ return base;
+
+ ranges = (unsigned int *) get_property(node, "ranges", &rlen);
+ np = prom_n_addr_cells(node) + 5;
+ while ((rlen -= np * sizeof(unsigned int)) >= 0) {
+ if ((ranges[0] >> 24) == 1 && ranges[2] == 0) {
+ /* I/O space starting at 0, grab the phys base */
+ base = ranges[np - 3];
+ break;
+ }
+ ranges += np;
+ }
+ return base;
+}
+#endif /* CONFIG_PPC_CHRP */
+
+#ifdef CONFIG_MAGIC_SYSRQ
+static void sysrq_handle_xmon(int key, struct pt_regs *regs,
+ struct tty_struct *tty)
+{
+ xmon(regs);
+}
+
+static struct sysrq_key_op sysrq_xmon_op =
+{
+ .handler = sysrq_handle_xmon,
+ .help_msg = "Xmon",
+ .action_msg = "Entering xmon",
+};
+#endif
+
+void
+xmon_map_scc(void)
+{
+#ifdef CONFIG_PPC_MULTIPLATFORM
+ volatile unsigned char __iomem *base;
+
+ if (_machine == _MACH_Pmac) {
+ struct device_node *np;
+ unsigned long addr;
+#ifdef CONFIG_BOOTX_TEXT
+ if (!use_screen && !use_serial
+ && !machine_is_compatible("iMac")) {
+ /* see if there is a keyboard in the device tree
+ with a parent of type "adb" */
+ for (np = find_devices("keyboard"); np; np = np->next)
+ if (np->parent && np->parent->type
+ && strcmp(np->parent->type, "adb") == 0)
+ break;
+
+ /* needs to be hacked if xmon_printk is to be used
+ from within find_via_pmu() */
+#ifdef CONFIG_ADB_PMU
+ if (np != NULL && boot_text_mapped && find_via_pmu())
+ use_screen = 1;
+#endif
+#ifdef CONFIG_ADB_CUDA
+ if (np != NULL && boot_text_mapped && find_via_cuda())
+ use_screen = 1;
+#endif
+ }
+ if (!use_screen && (np = find_devices("escc")) != NULL) {
+ /*
+ * look for the device node for the serial port
+ * we're using and see if it says it has a modem
+ */
+ char *name = xmon_use_sccb? "ch-b": "ch-a";
+ char *slots;
+ int l;
+
+ np = np->child;
+ while (np != NULL && strcmp(np->name, name) != 0)
+ np = np->sibling;
+ if (np != NULL) {
+ /* XXX should parse this properly */
+ channel_node = np;
+ slots = get_property(np, "slot-names", &l);
+ if (slots != NULL && l >= 10
+ && strcmp(slots+4, "Modem") == 0)
+ via_modem = 1;
+ }
+ }
+ btext_drawstring("xmon uses ");
+ if (use_screen)
+ btext_drawstring("screen and keyboard\n");
+ else {
+ if (via_modem)
+ btext_drawstring("modem on ");
+ btext_drawstring(xmon_use_sccb? "printer": "modem");
+ btext_drawstring(" port\n");
+ }
+
+#endif /* CONFIG_BOOTX_TEXT */
+
+#ifdef CHRP_ESCC
+ addr = 0xc1013020;
+#else
+ addr = 0xf3013020;
+#endif
+ TXRDY = 4;
+ RXRDY = 1;
+
+ np = find_devices("mac-io");
+ if (np && np->n_addrs)
+ addr = np->addrs[0].address + 0x13020;
+ base = (volatile unsigned char *) ioremap(addr & PAGE_MASK, PAGE_SIZE);
+ sccc = base + (addr & ~PAGE_MASK);
+ sccd = sccc + 0x10;
+
+ } else {
+ base = (volatile unsigned char *) isa_io_base;
+
+#ifdef CONFIG_PPC_CHRP
+ if (_machine == _MACH_chrp)
+ base = (volatile unsigned char __iomem *)
+ ioremap(chrp_find_phys_io_base(), 0x1000);
+#endif
+
+ sccc = base + 0x3fd;
+ sccd = base + 0x3f8;
+ if (xmon_use_sccb) {
+ sccc -= 0x100;
+ sccd -= 0x100;
+ }
+ TXRDY = 0x20;
+ RXRDY = 1;
+ DLAB = 0x80;
+ }
+#elif defined(CONFIG_GEMINI)
+ /* should already be mapped by the kernel boot */
+ sccc = (volatile unsigned char __iomem *) 0xffeffb0d;
+ sccd = (volatile unsigned char __iomem *) 0xffeffb08;
+ TXRDY = 0x20;
+ RXRDY = 1;
+ DLAB = 0x80;
+#elif defined(CONFIG_405GP)
+ sccc = (volatile unsigned char __iomem *)0xef600305;
+ sccd = (volatile unsigned char __iomem *)0xef600300;
+ TXRDY = 0x20;
+ RXRDY = 1;
+ DLAB = 0x80;
+#endif /* platform */
+
+ register_sysrq_key('x', &sysrq_xmon_op);
+}
+
+static int scc_initialized = 0;
+
+void xmon_init_scc(void);
+extern void cuda_poll(void);
+
+static inline void do_poll_adb(void)
+{
+#ifdef CONFIG_ADB_PMU
+ if (sys_ctrler == SYS_CTRLER_PMU)
+ pmu_poll_adb();
+#endif /* CONFIG_ADB_PMU */
+#ifdef CONFIG_ADB_CUDA
+ if (sys_ctrler == SYS_CTRLER_CUDA)
+ cuda_poll();
+#endif /* CONFIG_ADB_CUDA */
+}
+
+int
+xmon_write(void *handle, void *ptr, int nb)
+{
+ char *p = ptr;
+ int i, c, ct;
+
+#ifdef CONFIG_SMP
+ static unsigned long xmon_write_lock;
+ int lock_wait = 1000000;
+ int locked;
+
+ while ((locked = test_and_set_bit(0, &xmon_write_lock)) != 0)
+ if (--lock_wait == 0)
+ break;
+#endif
+
+#ifdef CONFIG_BOOTX_TEXT
+ if (use_screen) {
+ /* write it on the screen */
+ for (i = 0; i < nb; ++i)
+ btext_drawchar(*p++);
+ goto out;
+ }
+#endif
+ if (!scc_initialized)
+ xmon_init_scc();
+ ct = 0;
+ for (i = 0; i < nb; ++i) {
+ while ((*sccc & TXRDY) == 0)
+ do_poll_adb();
+ c = p[i];
+ if (c == '\n' && !ct) {
+ c = '\r';
+ ct = 1;
+ --i;
+ } else {
+ ct = 0;
+ }
+ buf_access();
+ *sccd = c;
+ eieio();
+ }
+
+ out:
+#ifdef CONFIG_SMP
+ if (!locked)
+ clear_bit(0, &xmon_write_lock);
+#endif
+ return nb;
+}
+
+int xmon_wants_key;
+int xmon_adb_keycode;
+
+#ifdef CONFIG_BOOTX_TEXT
+static int xmon_adb_shiftstate;
+
+static unsigned char xmon_keytab[128] =
+ "asdfhgzxcv\000bqwer" /* 0x00 - 0x0f */
+ "yt123465=97-80]o" /* 0x10 - 0x1f */
+ "u[ip\rlj'k;\\,/nm." /* 0x20 - 0x2f */
+ "\t `\177\0\033\0\0\0\0\0\0\0\0\0\0" /* 0x30 - 0x3f */
+ "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */
+ "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */
+
+static unsigned char xmon_shift_keytab[128] =
+ "ASDFHGZXCV\000BQWER" /* 0x00 - 0x0f */
+ "YT!@#$^%+(&_*)}O" /* 0x10 - 0x1f */
+ "U{IP\rLJ\"K:|<?NM>" /* 0x20 - 0x2f */
+ "\t ~\177\0\033\0\0\0\0\0\0\0\0\0\0" /* 0x30 - 0x3f */
+ "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */
+ "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */
+
+static int
+xmon_get_adb_key(void)
+{
+ int k, t, on;
+
+ xmon_wants_key = 1;
+ for (;;) {
+ xmon_adb_keycode = -1;
+ t = 0;
+ on = 0;
+ do {
+ if (--t < 0) {
+ on = 1 - on;
+ btext_drawchar(on? 0xdb: 0x20);
+ btext_drawchar('\b');
+ t = 200000;
+ }
+ do_poll_adb();
+ } while (xmon_adb_keycode == -1);
+ k = xmon_adb_keycode;
+ if (on)
+ btext_drawstring(" \b");
+
+ /* test for shift keys */
+ if ((k & 0x7f) == 0x38 || (k & 0x7f) == 0x7b) {
+ xmon_adb_shiftstate = (k & 0x80) == 0;
+ continue;
+ }
+ if (k >= 0x80)
+ continue; /* ignore up transitions */
+ k = (xmon_adb_shiftstate? xmon_shift_keytab: xmon_keytab)[k];
+ if (k != 0)
+ break;
+ }
+ xmon_wants_key = 0;
+ return k;
+}
+#endif /* CONFIG_BOOTX_TEXT */
+
+int
+xmon_read(void *handle, void *ptr, int nb)
+{
+ char *p = ptr;
+ int i;
+
+#ifdef CONFIG_BOOTX_TEXT
+ if (use_screen) {
+ for (i = 0; i < nb; ++i)
+ *p++ = xmon_get_adb_key();
+ return i;
+ }
+#endif
+ if (!scc_initialized)
+ xmon_init_scc();
+ for (i = 0; i < nb; ++i) {
+ while ((*sccc & RXRDY) == 0)
+ do_poll_adb();
+ buf_access();
+ *p++ = *sccd;
+ }
+ return i;
+}
+
+int
+xmon_read_poll(void)
+{
+ if ((*sccc & RXRDY) == 0) {
+ do_poll_adb();
+ return -1;
+ }
+ buf_access();
+ return *sccd;
+}
+
+static unsigned char scc_inittab[] = {
+ 13, 0, /* set baud rate divisor */
+ 12, 1,
+ 14, 1, /* baud rate gen enable, src=rtxc */
+ 11, 0x50, /* clocks = br gen */
+ 5, 0xea, /* tx 8 bits, assert DTR & RTS */
+ 4, 0x46, /* x16 clock, 1 stop */
+ 3, 0xc1, /* rx enable, 8 bits */
+};
+
+void
+xmon_init_scc(void)
+{
+ if ( _machine == _MACH_chrp )
+ {
+ sccd[3] = 0x83; eieio(); /* LCR = 8N1 + DLAB */
+ sccd[0] = 12; eieio(); /* DLL = 9600 baud */
+ sccd[1] = 0; eieio();
+ sccd[2] = 0; eieio(); /* FCR = 0 */
+ sccd[3] = 3; eieio(); /* LCR = 8N1 */
+ sccd[1] = 0; eieio(); /* IER = 0 */
+ }
+ else if ( _machine == _MACH_Pmac )
+ {
+ int i, x;
+
+ if (channel_node != 0)
+ pmac_call_feature(
+ PMAC_FTR_SCC_ENABLE,
+ channel_node,
+ PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1);
+ printk(KERN_INFO "Serial port locked ON by debugger !\n");
+ if (via_modem && channel_node != 0) {
+ unsigned int t0;
+
+ pmac_call_feature(
+ PMAC_FTR_MODEM_ENABLE,
+ channel_node, 0, 1);
+ printk(KERN_INFO "Modem powered up by debugger !\n");
+ t0 = readtb();
+ while (readtb() - t0 < 3*TB_SPEED)
+ eieio();
+ }
+ /* use the B channel if requested */
+ if (xmon_use_sccb) {
+ sccc = (volatile unsigned char *)
+ ((unsigned long)sccc & ~0x20);
+ sccd = sccc + 0x10;
+ }
+ for (i = 20000; i != 0; --i) {
+ x = *sccc; eieio();
+ }
+ *sccc = 9; eieio(); /* reset A or B side */
+ *sccc = ((unsigned long)sccc & 0x20)? 0x80: 0x40; eieio();
+ for (i = 0; i < sizeof(scc_inittab); ++i) {
+ *sccc = scc_inittab[i];
+ eieio();
+ }
+ }
+ scc_initialized = 1;
+ if (via_modem) {
+ for (;;) {
+ xmon_write(NULL, "ATE1V1\r", 7);
+ if (xmon_expect("OK", 5)) {
+ xmon_write(NULL, "ATA\r", 4);
+ if (xmon_expect("CONNECT", 40))
+ break;
+ }
+ xmon_write(NULL, "+++", 3);
+ xmon_expect("OK", 3);
+ }
+ }
+}
+
+void *xmon_stdin;
+void *xmon_stdout;
+void *xmon_stderr;
+
+int xmon_putc(int c, void *f)
+{
+ char ch = c;
+
+ if (c == '\n')
+ xmon_putc('\r', f);
+ return xmon_write(f, &ch, 1) == 1? c: -1;
+}
+
+int xmon_putchar(int c)
+{
+ return xmon_putc(c, xmon_stdout);
+}
+
+int xmon_fputs(char *str, void *f)
+{
+ int n = strlen(str);
+
+ return xmon_write(f, str, n) == n? 0: -1;
+}
+
+int
+xmon_readchar(void)
+{
+ char ch;
+
+ for (;;) {
+ switch (xmon_read(xmon_stdin, &ch, 1)) {
+ case 1:
+ return ch;
+ case -1:
+ xmon_printf("read(stdin) returned -1\r\n", 0, 0);
+ return -1;
+ }
+ }
+}
+
+static char line[256];
+static char *lineptr;
+static int lineleft;
+
+int xmon_expect(const char *str, unsigned int timeout)
+{
+ int c;
+ unsigned int t0;
+
+ timeout *= TB_SPEED;
+ t0 = readtb();
+ do {
+ lineptr = line;
+ for (;;) {
+ c = xmon_read_poll();
+ if (c == -1) {
+ if (readtb() - t0 > timeout)
+ return 0;
+ continue;
+ }
+ if (c == '\n')
+ break;
+ if (c != '\r' && lineptr < &line[sizeof(line) - 1])
+ *lineptr++ = c;
+ }
+ *lineptr = 0;
+ } while (strstr(line, str) == NULL);
+ return 1;
+}
+
+int
+xmon_getchar(void)
+{
+ int c;
+
+ if (lineleft == 0) {
+ lineptr = line;
+ for (;;) {
+ c = xmon_readchar();
+ if (c == -1 || c == 4)
+ break;
+ if (c == '\r' || c == '\n') {
+ *lineptr++ = '\n';
+ xmon_putchar('\n');
+ break;
+ }
+ switch (c) {
+ case 0177:
+ case '\b':
+ if (lineptr > line) {
+ xmon_putchar('\b');
+ xmon_putchar(' ');
+ xmon_putchar('\b');
+ --lineptr;
+ }
+ break;
+ case 'U' & 0x1F:
+ while (lineptr > line) {
+ xmon_putchar('\b');
+ xmon_putchar(' ');
+ xmon_putchar('\b');
+ --lineptr;
+ }
+ break;
+ default:
+ if (lineptr >= &line[sizeof(line) - 1])
+ xmon_putchar('\a');
+ else {
+ xmon_putchar(c);
+ *lineptr++ = c;
+ }
+ }
+ }
+ lineleft = lineptr - line;
+ lineptr = line;
+ }
+ if (lineleft == 0)
+ return -1;
+ --lineleft;
+ return *lineptr++;
+}
+
+char *
+xmon_fgets(char *str, int nb, void *f)
+{
+ char *p;
+ int c;
+
+ for (p = str; p < str + nb - 1; ) {
+ c = xmon_getchar();
+ if (c == -1) {
+ if (p == str)
+ return NULL;
+ break;
+ }
+ *p++ = c;
+ if (c == '\n')
+ break;
+ }
+ *p = 0;
+ return str;
+}
+
+void
+xmon_enter(void)
+{
+#ifdef CONFIG_ADB_PMU
+ if (_machine == _MACH_Pmac) {
+ pmu_suspend();
+ }
+#endif
+}
+
+void
+xmon_leave(void)
+{
+#ifdef CONFIG_ADB_PMU
+ if (_machine == _MACH_Pmac) {
+ pmu_resume();
+ }
+#endif
+}
diff --git a/arch/ppc64/xmon/start.c b/arch/powerpc/xmon/start_64.c
index e50c158191e1..e50c158191e1 100644
--- a/arch/ppc64/xmon/start.c
+++ b/arch/powerpc/xmon/start_64.c
diff --git a/arch/powerpc/xmon/start_8xx.c b/arch/powerpc/xmon/start_8xx.c
new file mode 100644
index 000000000000..a48bd594cf61
--- /dev/null
+++ b/arch/powerpc/xmon/start_8xx.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 1996 Paul Mackerras.
+ * Copyright (C) 2000 Dan Malek.
+ * Quick hack of Paul's code to make XMON work on 8xx processors. Lots
+ * of assumptions, like the SMC1 is used, it has been initialized by the
+ * loader at some point, and we can just stuff and suck bytes.
+ * We rely upon the 8xx uart driver to support us, as the interface
+ * changes between boot up and operational phases of the kernel.
+ */
+#include <linux/string.h>
+#include <asm/machdep.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <linux/kernel.h>
+#include <asm/8xx_immap.h>
+#include <asm/mpc8xx.h>
+#include <asm/commproc.h>
+
+extern void xmon_printf(const char *fmt, ...);
+extern int xmon_8xx_write(char *str, int nb);
+extern int xmon_8xx_read_poll(void);
+extern int xmon_8xx_read_char(void);
+void prom_drawhex(uint);
+void prom_drawstring(const char *str);
+
+static int use_screen = 1; /* default */
+
+#define TB_SPEED 25000000
+
+static inline unsigned int readtb(void)
+{
+ unsigned int ret;
+
+ asm volatile("mftb %0" : "=r" (ret) :);
+ return ret;
+}
+
+void buf_access(void)
+{
+}
+
+void
+xmon_map_scc(void)
+{
+
+ cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm);
+ use_screen = 0;
+
+ prom_drawstring("xmon uses serial port\n");
+}
+
+static int scc_initialized = 0;
+
+void xmon_init_scc(void);
+
+int
+xmon_write(void *handle, void *ptr, int nb)
+{
+ char *p = ptr;
+ int i, c, ct;
+
+ if (!scc_initialized)
+ xmon_init_scc();
+
+ return(xmon_8xx_write(ptr, nb));
+}
+
+int xmon_wants_key;
+
+int
+xmon_read(void *handle, void *ptr, int nb)
+{
+ char *p = ptr;
+ int i;
+
+ if (!scc_initialized)
+ xmon_init_scc();
+
+ for (i = 0; i < nb; ++i) {
+ *p++ = xmon_8xx_read_char();
+ }
+ return i;
+}
+
+int
+xmon_read_poll(void)
+{
+ return(xmon_8xx_read_poll());
+}
+
+void
+xmon_init_scc()
+{
+ scc_initialized = 1;
+}
+
+#if 0
+extern int (*prom_entry)(void *);
+
+int
+xmon_exit(void)
+{
+ struct prom_args {
+ char *service;
+ } args;
+
+ for (;;) {
+ args.service = "exit";
+ (*prom_entry)(&args);
+ }
+}
+#endif
+
+void *xmon_stdin;
+void *xmon_stdout;
+void *xmon_stderr;
+
+void
+xmon_init(void)
+{
+}
+
+int
+xmon_putc(int c, void *f)
+{
+ char ch = c;
+
+ if (c == '\n')
+ xmon_putc('\r', f);
+ return xmon_write(f, &ch, 1) == 1? c: -1;
+}
+
+int
+xmon_putchar(int c)
+{
+ return xmon_putc(c, xmon_stdout);
+}
+
+int
+xmon_fputs(char *str, void *f)
+{
+ int n = strlen(str);
+
+ return xmon_write(f, str, n) == n? 0: -1;
+}
+
+int
+xmon_readchar(void)
+{
+ char ch;
+
+ for (;;) {
+ switch (xmon_read(xmon_stdin, &ch, 1)) {
+ case 1:
+ return ch;
+ case -1:
+ xmon_printf("read(stdin) returned -1\r\n", 0, 0);
+ return -1;
+ }
+ }
+}
+
+static char line[256];
+static char *lineptr;
+static int lineleft;
+
+#if 0
+int xmon_expect(const char *str, unsigned int timeout)
+{
+ int c;
+ unsigned int t0;
+
+ timeout *= TB_SPEED;
+ t0 = readtb();
+ do {
+ lineptr = line;
+ for (;;) {
+ c = xmon_read_poll();
+ if (c == -1) {
+ if (readtb() - t0 > timeout)
+ return 0;
+ continue;
+ }
+ if (c == '\n')
+ break;
+ if (c != '\r' && lineptr < &line[sizeof(line) - 1])
+ *lineptr++ = c;
+ }
+ *lineptr = 0;
+ } while (strstr(line, str) == NULL);
+ return 1;
+}
+#endif
+
+int
+xmon_getchar(void)
+{
+ int c;
+
+ if (lineleft == 0) {
+ lineptr = line;
+ for (;;) {
+ c = xmon_readchar();
+ if (c == -1 || c == 4)
+ break;
+ if (c == '\r' || c == '\n') {
+ *lineptr++ = '\n';
+ xmon_putchar('\n');
+ break;
+ }
+ switch (c) {
+ case 0177:
+ case '\b':
+ if (lineptr > line) {
+ xmon_putchar('\b');
+ xmon_putchar(' ');
+ xmon_putchar('\b');
+ --lineptr;
+ }
+ break;
+ case 'U' & 0x1F:
+ while (lineptr > line) {
+ xmon_putchar('\b');
+ xmon_putchar(' ');
+ xmon_putchar('\b');
+ --lineptr;
+ }
+ break;
+ default:
+ if (lineptr >= &line[sizeof(line) - 1])
+ xmon_putchar('\a');
+ else {
+ xmon_putchar(c);
+ *lineptr++ = c;
+ }
+ }
+ }
+ lineleft = lineptr - line;
+ lineptr = line;
+ }
+ if (lineleft == 0)
+ return -1;
+ --lineleft;
+ return *lineptr++;
+}
+
+char *
+xmon_fgets(char *str, int nb, void *f)
+{
+ char *p;
+ int c;
+
+ for (p = str; p < str + nb - 1; ) {
+ c = xmon_getchar();
+ if (c == -1) {
+ if (p == str)
+ return 0;
+ break;
+ }
+ *p++ = c;
+ if (c == '\n')
+ break;
+ }
+ *p = 0;
+ return str;
+}
+
+void
+prom_drawhex(uint val)
+{
+ unsigned char buf[10];
+
+ int i;
+ for (i = 7; i >= 0; i--)
+ {
+ buf[i] = "0123456789abcdef"[val & 0x0f];
+ val >>= 4;
+ }
+ buf[8] = '\0';
+ xmon_fputs(buf, xmon_stdout);
+}
+
+void
+prom_drawstring(const char *str)
+{
+ xmon_fputs(str, xmon_stdout);
+}
diff --git a/arch/ppc64/xmon/subr_prf.c b/arch/powerpc/xmon/subr_prf.c
index 5242bd7d0959..b48738c6dd33 100644
--- a/arch/ppc64/xmon/subr_prf.c
+++ b/arch/powerpc/xmon/subr_prf.c
@@ -18,13 +18,13 @@
#include <linux/kernel.h>
#include <linux/string.h>
+#include <linux/module.h>
#include <stdarg.h>
#include "nonstdio.h"
extern int xmon_write(void *, void *, int);
-void
-xmon_vfprintf(void *f, const char *fmt, va_list ap)
+void xmon_vfprintf(void *f, const char *fmt, va_list ap)
{
static char xmon_buf[2048];
int n;
@@ -33,8 +33,7 @@ xmon_vfprintf(void *f, const char *fmt, va_list ap)
xmon_write(f, xmon_buf, n);
}
-void
-xmon_printf(const char *fmt, ...)
+void xmon_printf(const char *fmt, ...)
{
va_list ap;
@@ -42,9 +41,9 @@ xmon_printf(const char *fmt, ...)
xmon_vfprintf(stdout, fmt, ap);
va_end(ap);
}
+EXPORT_SYMBOL(xmon_printf);
-void
-xmon_fprintf(void *f, const char *fmt, ...)
+void xmon_fprintf(void *f, const char *fmt, ...)
{
va_list ap;
diff --git a/arch/ppc64/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 74e63a886a69..1124f1146202 100644
--- a/arch/ppc64/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -17,25 +17,31 @@
#include <linux/delay.h>
#include <linux/kallsyms.h>
#include <linux/cpumask.h>
+#include <linux/module.h>
#include <asm/ptrace.h>
#include <asm/string.h>
#include <asm/prom.h>
#include <asm/machdep.h>
+#include <asm/xmon.h>
+#ifdef CONFIG_PMAC_BACKLIGHT
+#include <asm/backlight.h>
+#endif
#include <asm/processor.h>
#include <asm/pgtable.h>
#include <asm/mmu.h>
#include <asm/mmu_context.h>
-#include <asm/paca.h>
-#include <asm/ppcdebug.h>
#include <asm/cputable.h>
#include <asm/rtas.h>
#include <asm/sstep.h>
#include <asm/bug.h>
+
+#ifdef CONFIG_PPC64
#include <asm/hvcall.h>
+#include <asm/paca.h>
+#endif
#include "nonstdio.h"
-#include "privinst.h"
#define scanhex xmon_scanhex
#define skipbl xmon_skipbl
@@ -58,7 +64,7 @@ static unsigned long ncsum = 4096;
static int termch;
static char tmpstr[128];
-#define JMP_BUF_LEN (184/sizeof(long))
+#define JMP_BUF_LEN 23
static long bus_error_jmp[JMP_BUF_LEN];
static int catch_memory_errors;
static long *xmon_fault_jmp[NR_CPUS];
@@ -130,23 +136,36 @@ static void cacheflush(void);
static int cpu_cmd(void);
static void csum(void);
static void bootcmds(void);
+static void proccall(void);
void dump_segments(void);
static void symbol_lookup(void);
static void xmon_print_symbol(unsigned long address, const char *mid,
const char *after);
static const char *getvecname(unsigned long vec);
-static void debug_trace(void);
-
extern int print_insn_powerpc(unsigned long, unsigned long, int);
extern void printf(const char *fmt, ...);
extern void xmon_vfprintf(void *f, const char *fmt, va_list ap);
extern int xmon_putc(int c, void *f);
extern int putchar(int ch);
+
+extern void xmon_enter(void);
+extern void xmon_leave(void);
+
extern int xmon_read_poll(void);
-extern int setjmp(long *);
-extern void longjmp(long *, int);
-extern unsigned long _ASR;
+extern long setjmp(long *);
+extern void longjmp(long *, long);
+extern void xmon_save_regs(struct pt_regs *);
+
+#ifdef CONFIG_PPC64
+#define REG "%.16lx"
+#define REGS_PER_LINE 4
+#define LAST_VOLATILE 13
+#else
+#define REG "%.8lx"
+#define REGS_PER_LINE 8
+#define LAST_VOLATILE 12
+#endif
#define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
@@ -186,47 +205,45 @@ Commands:\n\
ml locate a block of memory\n\
mz zero a block of memory\n\
mi show information about memory allocation\n\
- p show the task list\n\
+ p call a procedure\n\
r print registers\n\
s single step\n\
S print special registers\n\
t print backtrace\n\
- T Enable/Disable PPCDBG flags\n\
x exit monitor and recover\n\
- X exit monitor and dont recover\n\
- u dump segment table or SLB\n\
- ? help\n"
- "\
- zr reboot\n\
+ X exit monitor and dont recover\n"
+#ifdef CONFIG_PPC64
+" u dump segment table or SLB\n"
+#endif
+#ifdef CONFIG_PPC_STD_MMU_32
+" u dump segment registers\n"
+#endif
+" ? help\n"
+" zr reboot\n\
zh halt\n"
;
static struct pt_regs *xmon_regs;
-extern inline void sync(void)
+static inline void sync(void)
{
asm volatile("sync; isync");
}
-/* (Ref: 64-bit PowerPC ELF ABI Spplement; Ian Lance Taylor, Zembu Labs).
- A PPC stack frame looks like this:
-
- High Address
- Back Chain
- FP reg save area
- GP reg save area
- Local var space
- Parameter save area (SP+48)
- TOC save area (SP+40)
- link editor doubleword (SP+32)
- compiler doubleword (SP+24)
- LR save (SP+16)
- CR save (SP+8)
- Back Chain (SP+0)
-
- Note that the LR (ret addr) may not be saved in the current frame if
- no functions have been called from the current function.
- */
+static inline void store_inst(void *p)
+{
+ asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
+}
+
+static inline void cflush(void *p)
+{
+ asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
+}
+
+static inline void cinval(void *p)
+{
+ asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
+}
/*
* Disable surveillance (the service processor watchdog function)
@@ -310,8 +327,8 @@ int xmon_core(struct pt_regs *regs, int fromipi)
unsigned long timeout;
#endif
- msr = get_msr();
- set_msrd(msr & ~MSR_EE); /* disable interrupts */
+ msr = mfmsr();
+ mtmsr(msr & ~MSR_EE); /* disable interrupts */
bp = in_breakpoint_table(regs->nip, &offset);
if (bp != NULL) {
@@ -487,7 +504,7 @@ int xmon_core(struct pt_regs *regs, int fromipi)
insert_cpu_bpts();
- set_msrd(msr); /* restore interrupt enable */
+ mtmsr(msr); /* restore interrupt enable */
return cmd != 'X';
}
@@ -497,56 +514,23 @@ int xmon(struct pt_regs *excp)
struct pt_regs regs;
if (excp == NULL) {
- /* Ok, grab regs as they are now.
- This won't do a particularily good job because the
- prologue has already been executed.
- ToDo: We could reach back into the callers save
- area to do a better job of representing the
- caller's state.
- */
- asm volatile ("std 0,0(%0)\n\
- std 1,8(%0)\n\
- std 2,16(%0)\n\
- std 3,24(%0)\n\
- std 4,32(%0)\n\
- std 5,40(%0)\n\
- std 6,48(%0)\n\
- std 7,56(%0)\n\
- std 8,64(%0)\n\
- std 9,72(%0)\n\
- std 10,80(%0)\n\
- std 11,88(%0)\n\
- std 12,96(%0)\n\
- std 13,104(%0)\n\
- std 14,112(%0)\n\
- std 15,120(%0)\n\
- std 16,128(%0)\n\
- std 17,136(%0)\n\
- std 18,144(%0)\n\
- std 19,152(%0)\n\
- std 20,160(%0)\n\
- std 21,168(%0)\n\
- std 22,176(%0)\n\
- std 23,184(%0)\n\
- std 24,192(%0)\n\
- std 25,200(%0)\n\
- std 26,208(%0)\n\
- std 27,216(%0)\n\
- std 28,224(%0)\n\
- std 29,232(%0)\n\
- std 30,240(%0)\n\
- std 31,248(%0)" : : "b" (&regs));
-
- regs.nip = regs.link = ((unsigned long *)(regs.gpr[1]))[2];
- regs.msr = get_msr();
- regs.ctr = get_ctr();
- regs.xer = get_xer();
- regs.ccr = get_cr();
- regs.trap = 0;
+ xmon_save_regs(&regs);
excp = &regs;
}
return xmon_core(excp, 0);
}
+EXPORT_SYMBOL(xmon);
+
+irqreturn_t
+xmon_irq(int irq, void *d, struct pt_regs *regs)
+{
+ unsigned long flags;
+ local_irq_save(flags);
+ printf("Keyboard interrupt\n");
+ xmon(regs);
+ local_irq_restore(flags);
+ return IRQ_HANDLED;
+}
int xmon_bpt(struct pt_regs *regs)
{
@@ -718,7 +702,7 @@ static void insert_cpu_bpts(void)
if (dabr.enabled)
set_dabr(dabr.address | (dabr.enabled & 7));
if (iabr && cpu_has_feature(CPU_FTR_IABR))
- set_iabr(iabr->address
+ mtspr(SPRN_IABR, iabr->address
| (iabr->enabled & (BP_IABR|BP_IABR_TE)));
}
@@ -746,7 +730,7 @@ static void remove_cpu_bpts(void)
{
set_dabr(0);
if (cpu_has_feature(CPU_FTR_IABR))
- set_iabr(0);
+ mtspr(SPRN_IABR, 0);
}
/* Command interpreting routine */
@@ -830,9 +814,6 @@ cmds(struct pt_regs *excp)
case '?':
printf(help_string);
break;
- case 'p':
- show_state();
- break;
case 'b':
bpt_cmds();
break;
@@ -846,12 +827,14 @@ cmds(struct pt_regs *excp)
case 'z':
bootcmds();
break;
- case 'T':
- debug_trace();
+ case 'p':
+ proccall();
break;
+#ifdef CONFIG_PPC_STD_MMU
case 'u':
dump_segments();
break;
+#endif
default:
printf("Unrecognized command: ");
do {
@@ -1070,6 +1053,7 @@ bpt_cmds(void)
cmd = inchar();
switch (cmd) {
+#ifndef CONFIG_8xx
case 'd': /* bd - hardware data breakpoint */
mode = 7;
cmd = inchar();
@@ -1111,6 +1095,7 @@ bpt_cmds(void)
iabr = bp;
}
break;
+#endif
case 'c':
if (!scanhex(&a)) {
@@ -1152,7 +1137,7 @@ bpt_cmds(void)
/* print all breakpoints */
printf(" type address\n");
if (dabr.enabled) {
- printf(" data %.16lx [", dabr.address);
+ printf(" data "REG" [", dabr.address);
if (dabr.enabled & 1)
printf("r");
if (dabr.enabled & 2)
@@ -1231,6 +1216,18 @@ static void get_function_bounds(unsigned long pc, unsigned long *startp,
static int xmon_depth_to_print = 64;
+#ifdef CONFIG_PPC64
+#define LRSAVE_OFFSET 0x10
+#define REG_FRAME_MARKER 0x7265677368657265ul /* "regshere" */
+#define MARKER_OFFSET 0x60
+#define REGS_OFFSET 0x70
+#else
+#define LRSAVE_OFFSET 4
+#define REG_FRAME_MARKER 0x72656773
+#define MARKER_OFFSET 8
+#define REGS_OFFSET 16
+#endif
+
static void xmon_show_stack(unsigned long sp, unsigned long lr,
unsigned long pc)
{
@@ -1247,7 +1244,7 @@ static void xmon_show_stack(unsigned long sp, unsigned long lr,
break;
}
- if (!mread(sp + 16, &ip, sizeof(unsigned long))
+ if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
|| !mread(sp, &newsp, sizeof(unsigned long))) {
printf("Couldn't read stack frame at %lx\n", sp);
break;
@@ -1266,7 +1263,7 @@ static void xmon_show_stack(unsigned long sp, unsigned long lr,
get_function_bounds(pc, &fnstart, &fnend);
nextip = 0;
if (newsp > sp)
- mread(newsp + 16, &nextip,
+ mread(newsp + LRSAVE_OFFSET, &nextip,
sizeof(unsigned long));
if (lr == ip) {
if (lr < PAGE_OFFSET
@@ -1280,24 +1277,24 @@ static void xmon_show_stack(unsigned long sp, unsigned long lr,
xmon_print_symbol(lr, " ", "\n");
}
if (printip) {
- printf("[%.16lx] ", sp);
+ printf("["REG"] ", sp);
xmon_print_symbol(ip, " ", " (unreliable)\n");
}
pc = lr = 0;
} else {
- printf("[%.16lx] ", sp);
+ printf("["REG"] ", sp);
xmon_print_symbol(ip, " ", "\n");
}
/* Look for "regshere" marker to see if this is
an exception frame. */
- if (mread(sp + 0x60, &marker, sizeof(unsigned long))
- && marker == 0x7265677368657265ul) {
- if (mread(sp + 0x70, &regs, sizeof(regs))
+ if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
+ && marker == REG_FRAME_MARKER) {
+ if (mread(sp + REGS_OFFSET, &regs, sizeof(regs))
!= sizeof(regs)) {
printf("Couldn't read registers at %lx\n",
- sp + 0x70);
+ sp + REGS_OFFSET);
break;
}
printf("--- Exception: %lx %s at ", regs.trap,
@@ -1371,7 +1368,9 @@ void excprint(struct pt_regs *fp)
}
printf(" current = 0x%lx\n", current);
+#ifdef CONFIG_PPC64
printf(" paca = 0x%lx\n", get_paca());
+#endif
if (current) {
printf(" pid = %ld, comm = %s\n",
current->pid, current->comm);
@@ -1383,7 +1382,7 @@ void excprint(struct pt_regs *fp)
void prregs(struct pt_regs *fp)
{
- int n;
+ int n, trap;
unsigned long base;
struct pt_regs regs;
@@ -1396,7 +1395,7 @@ void prregs(struct pt_regs *fp)
__delay(200);
} else {
catch_memory_errors = 0;
- printf("*** Error reading registers from %.16lx\n",
+ printf("*** Error reading registers from "REG"\n",
base);
return;
}
@@ -1404,22 +1403,36 @@ void prregs(struct pt_regs *fp)
fp = &regs;
}
+#ifdef CONFIG_PPC64
if (FULL_REGS(fp)) {
for (n = 0; n < 16; ++n)
- printf("R%.2ld = %.16lx R%.2ld = %.16lx\n",
+ printf("R%.2ld = "REG" R%.2ld = "REG"\n",
n, fp->gpr[n], n+16, fp->gpr[n+16]);
} else {
for (n = 0; n < 7; ++n)
- printf("R%.2ld = %.16lx R%.2ld = %.16lx\n",
+ printf("R%.2ld = "REG" R%.2ld = "REG"\n",
n, fp->gpr[n], n+7, fp->gpr[n+7]);
}
+#else
+ for (n = 0; n < 32; ++n) {
+ printf("R%.2d = %.8x%s", n, fp->gpr[n],
+ (n & 3) == 3? "\n": " ");
+ if (n == 12 && !FULL_REGS(fp)) {
+ printf("\n");
+ break;
+ }
+ }
+#endif
printf("pc = ");
xmon_print_symbol(fp->nip, " ", "\n");
printf("lr = ");
xmon_print_symbol(fp->link, " ", "\n");
- printf("msr = %.16lx cr = %.8lx\n", fp->msr, fp->ccr);
- printf("ctr = %.16lx xer = %.16lx trap = %8lx\n",
+ printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
+ printf("ctr = "REG" xer = "REG" trap = %4lx\n",
fp->ctr, fp->xer, fp->trap);
+ trap = TRAP(fp);
+ if (trap == 0x300 || trap == 0x380 || trap == 0x600)
+ printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
}
void cacheflush(void)
@@ -1519,8 +1532,7 @@ static unsigned long regno;
extern char exc_prolog;
extern char dec_exc;
-void
-super_regs(void)
+void super_regs(void)
{
int cmd;
unsigned long val;
@@ -1536,12 +1548,14 @@ super_regs(void)
asm("mr %0,1" : "=r" (sp) :);
asm("mr %0,2" : "=r" (toc) :);
- printf("msr = %.16lx sprg0= %.16lx\n", get_msr(), get_sprg0());
- printf("pvr = %.16lx sprg1= %.16lx\n", get_pvr(), get_sprg1());
- printf("dec = %.16lx sprg2= %.16lx\n", get_dec(), get_sprg2());
- printf("sp = %.16lx sprg3= %.16lx\n", sp, get_sprg3());
- printf("toc = %.16lx dar = %.16lx\n", toc, get_dar());
- printf("srr0 = %.16lx srr1 = %.16lx\n", get_srr0(), get_srr1());
+ printf("msr = "REG" sprg0= "REG"\n",
+ mfmsr(), mfspr(SPRN_SPRG0));
+ printf("pvr = "REG" sprg1= "REG"\n",
+ mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
+ printf("dec = "REG" sprg2= "REG"\n",
+ mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
+ printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
+ printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
#ifdef CONFIG_PPC_ISERIES
// Dump out relevant Paca data areas.
printf("Paca: \n");
@@ -1578,11 +1592,6 @@ super_regs(void)
case 'r':
printf("spr %lx = %lx\n", regno, read_spr(regno));
break;
- case 'm':
- val = get_msr();
- scanhex(&val);
- set_msrd(val);
- break;
}
scannl();
}
@@ -1604,13 +1613,13 @@ mread(unsigned long adrs, void *buf, int size)
q = (char *)buf;
switch (size) {
case 2:
- *(short *)q = *(short *)p;
+ *(u16 *)q = *(u16 *)p;
break;
case 4:
- *(int *)q = *(int *)p;
+ *(u32 *)q = *(u32 *)p;
break;
case 8:
- *(long *)q = *(long *)p;
+ *(u64 *)q = *(u64 *)p;
break;
default:
for( ; n < size; ++n) {
@@ -1641,13 +1650,13 @@ mwrite(unsigned long adrs, void *buf, int size)
q = (char *) buf;
switch (size) {
case 2:
- *(short *)p = *(short *)q;
+ *(u16 *)p = *(u16 *)q;
break;
case 4:
- *(int *)p = *(int *)q;
+ *(u32 *)p = *(u32 *)q;
break;
case 8:
- *(long *)p = *(long *)q;
+ *(u64 *)p = *(u64 *)q;
break;
default:
for ( ; n < size; ++n) {
@@ -1667,11 +1676,12 @@ mwrite(unsigned long adrs, void *buf, int size)
}
static int fault_type;
+static int fault_except;
static char *fault_chars[] = { "--", "**", "##" };
-static int
-handle_fault(struct pt_regs *regs)
+static int handle_fault(struct pt_regs *regs)
{
+ fault_except = TRAP(regs);
switch (TRAP(regs)) {
case 0x200:
fault_type = 0;
@@ -1960,7 +1970,7 @@ prdump(unsigned long adrs, long ndump)
unsigned char temp[16];
for (n = ndump; n > 0;) {
- printf("%.16lx", adrs);
+ printf(REG, adrs);
putchar(' ');
r = n < 16? n: 16;
nr = mread(adrs, temp, r);
@@ -2008,7 +2018,7 @@ ppc_inst_dump(unsigned long adr, long count, int praddr)
if (nr == 0) {
if (praddr) {
const char *x = fault_chars[fault_type];
- printf("%.16lx %s%s%s%s\n", adr, x, x, x, x);
+ printf(REG" %s%s%s%s\n", adr, x, x, x, x);
}
break;
}
@@ -2023,7 +2033,7 @@ ppc_inst_dump(unsigned long adr, long count, int praddr)
dotted = 0;
last_inst = inst;
if (praddr)
- printf("%.16lx %.8x", adr, inst);
+ printf(REG" %.8x", adr, inst);
printf("\t");
print_insn_powerpc(inst, adr, 0); /* always returns 4 */
printf("\n");
@@ -2152,6 +2162,42 @@ memzcan(void)
printf("%.8x\n", a - mskip);
}
+void proccall(void)
+{
+ unsigned long args[8];
+ unsigned long ret;
+ int i;
+ typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
+ unsigned long, unsigned long, unsigned long,
+ unsigned long, unsigned long, unsigned long);
+ callfunc_t func;
+
+ if (!scanhex(&adrs))
+ return;
+ if (termch != '\n')
+ termch = 0;
+ for (i = 0; i < 8; ++i)
+ args[i] = 0;
+ for (i = 0; i < 8; ++i) {
+ if (!scanhex(&args[i]) || termch == '\n')
+ break;
+ termch = 0;
+ }
+ func = (callfunc_t) adrs;
+ ret = 0;
+ if (setjmp(bus_error_jmp) == 0) {
+ catch_memory_errors = 1;
+ sync();
+ ret = func(args[0], args[1], args[2], args[3],
+ args[4], args[5], args[6], args[7]);
+ sync();
+ printf("return value is %x\n", ret);
+ } else {
+ printf("*** %x exception occurred\n", fault_except);
+ }
+ catch_memory_errors = 0;
+}
+
/* Input scanning routines */
int
skipbl(void)
@@ -2174,7 +2220,12 @@ static char *regnames[N_PTREGS] = {
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
- "pc", "msr", "or3", "ctr", "lr", "xer", "ccr", "softe",
+ "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
+#ifdef CONFIG_PPC64
+ "softe",
+#else
+ "mq",
+#endif
"trap", "dar", "dsisr", "res"
};
@@ -2280,8 +2331,7 @@ scannl(void)
c = inchar();
}
-int
-hexdigit(int c)
+int hexdigit(int c)
{
if( '0' <= c && c <= '9' )
return c - '0';
@@ -2378,7 +2428,7 @@ static void xmon_print_symbol(unsigned long address, const char *mid,
const char *name = NULL;
unsigned long offset, size;
- printf("%.16lx", address);
+ printf(REG, address);
if (setjmp(bus_error_jmp) == 0) {
catch_memory_errors = 1;
sync();
@@ -2399,55 +2449,7 @@ static void xmon_print_symbol(unsigned long address, const char *mid,
printf("%s", after);
}
-static void debug_trace(void)
-{
- unsigned long val, cmd, on;
-
- cmd = skipbl();
- if (cmd == '\n') {
- /* show current state */
- unsigned long i;
- printf("ppc64_debug_switch = 0x%lx\n", ppc64_debug_switch);
- for (i = 0; i < PPCDBG_NUM_FLAGS ;i++) {
- on = PPCDBG_BITVAL(i) & ppc64_debug_switch;
- printf("%02x %s %12s ", i, on ? "on " : "off", trace_names[i] ? trace_names[i] : "");
- if (((i+1) % 3) == 0)
- printf("\n");
- }
- printf("\n");
- return;
- }
- while (cmd != '\n') {
- on = 1; /* default if no sign given */
- while (cmd == '+' || cmd == '-') {
- on = (cmd == '+');
- cmd = inchar();
- if (cmd == ' ' || cmd == '\n') { /* Turn on or off based on + or - */
- ppc64_debug_switch = on ? PPCDBG_ALL:PPCDBG_NONE;
- printf("Setting all values to %s...\n", on ? "on" : "off");
- if (cmd == '\n') return;
- else cmd = skipbl();
- }
- else
- termch = cmd;
- }
- termch = cmd; /* not +/- ... let scanhex see it */
- scanhex((void *)&val);
- if (val >= 64) {
- printf("Value %x out of range:\n", val);
- return;
- }
- if (on) {
- ppc64_debug_switch |= PPCDBG_BITVAL(val);
- printf("enable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
- } else {
- ppc64_debug_switch &= ~PPCDBG_BITVAL(val);
- printf("disable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
- }
- cmd = skipbl();
- }
-}
-
+#ifdef CONFIG_PPC64
static void dump_slb(void)
{
int i;
@@ -2484,6 +2486,27 @@ static void dump_stab(void)
}
}
+void dump_segments(void)
+{
+ if (cpu_has_feature(CPU_FTR_SLB))
+ dump_slb();
+ else
+ dump_stab();
+}
+#endif
+
+#ifdef CONFIG_PPC_STD_MMU_32
+void dump_segments(void)
+{
+ int i;
+
+ printf("sr0-15 =");
+ for (i = 0; i < 16; ++i)
+ printf(" %x", mfsrin(i));
+ printf("\n");
+}
+#endif
+
void xmon_init(int enable)
{
if (enable) {
@@ -2504,11 +2527,3 @@ void xmon_init(int enable)
__debugger_fault_handler = NULL;
}
}
-
-void dump_segments(void)
-{
- if (cpu_has_feature(CPU_FTR_SLB))
- dump_slb();
- else
- dump_stab();
-}
diff --git a/arch/ppc/8xx_io/commproc.c b/arch/ppc/8xx_io/commproc.c
index 11726e2a4ec8..b42789f8eb76 100644
--- a/arch/ppc/8xx_io/commproc.c
+++ b/arch/ppc/8xx_io/commproc.c
@@ -73,7 +73,7 @@ cpm_mask_irq(unsigned int irq)
{
int cpm_vec = irq - CPM_IRQ_OFFSET;
- ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr &= ~(1 << cpm_vec);
+ out_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr, in_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr) & ~(1 << cpm_vec));
}
static void
@@ -81,7 +81,7 @@ cpm_unmask_irq(unsigned int irq)
{
int cpm_vec = irq - CPM_IRQ_OFFSET;
- ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr |= (1 << cpm_vec);
+ out_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr, in_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr) | (1 << cpm_vec));
}
static void
@@ -95,7 +95,7 @@ cpm_eoi(unsigned int irq)
{
int cpm_vec = irq - CPM_IRQ_OFFSET;
- ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cisr = (1 << cpm_vec);
+ out_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cisr, (1 << cpm_vec));
}
struct hw_interrupt_type cpm_pic = {
@@ -133,7 +133,7 @@ m8xx_cpm_reset(void)
* manual recommends it.
* Bit 25, FAM can also be set to use FEC aggressive mode (860T).
*/
- imp->im_siu_conf.sc_sdcr = 1;
+ out_be32(&imp->im_siu_conf.sc_sdcr, 1),
/* Reclaim the DP memory for our use. */
m8xx_cpm_dpinit();
@@ -178,10 +178,10 @@ cpm_interrupt_init(void)
/* Initialize the CPM interrupt controller.
*/
- ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr =
+ out_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr,
(CICR_SCD_SCC4 | CICR_SCC_SCC3 | CICR_SCB_SCC2 | CICR_SCA_SCC1) |
- ((CPM_INTERRUPT/2) << 13) | CICR_HP_MASK;
- ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr = 0;
+ ((CPM_INTERRUPT/2) << 13) | CICR_HP_MASK);
+ out_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr, 0);
/* install the CPM interrupt controller routines for the CPM
* interrupt vectors
@@ -198,7 +198,7 @@ cpm_interrupt_init(void)
if (setup_irq(CPM_IRQ_OFFSET + CPMVEC_ERROR, &cpm_error_irqaction))
panic("Could not allocate CPM error IRQ!");
- ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr |= CICR_IEN;
+ out_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr, in_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr) | CICR_IEN);
}
/*
@@ -212,8 +212,8 @@ cpm_get_irq(struct pt_regs *regs)
/* Get the vector by setting the ACK bit and then reading
* the register.
*/
- ((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_civr = 1;
- cpm_vec = ((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_civr;
+ out_be16(&((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_civr, 1);
+ cpm_vec = in_be16(&((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_civr);
cpm_vec >>= 11;
return cpm_vec;
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index 776941c75672..114b90fdea24 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -568,6 +568,7 @@ config CHESTNUT
config SPRUCE
bool "IBM-Spruce"
+ select PPC_INDIRECT_PCI
config HDPU
bool "Sky-HDPU"
@@ -588,27 +589,35 @@ config EV64260
config LOPEC
bool "Motorola-LoPEC"
+ select PPC_I8259
config MVME5100
bool "Motorola-MVME5100"
+ select PPC_INDIRECT_PCI
config PPLUS
bool "Motorola-PowerPlus"
+ select PPC_I8259
+ select PPC_INDIRECT_PCI
config PRPMC750
bool "Motorola-PrPMC750"
+ select PPC_INDIRECT_PCI
config PRPMC800
bool "Motorola-PrPMC800"
+ select PPC_INDIRECT_PCI
config SANDPOINT
bool "Motorola-Sandpoint"
+ select PPC_I8259
help
Select SANDPOINT if configuring for a Motorola Sandpoint X3
(any flavor).
config RADSTONE_PPC7D
bool "Radstone Technology PPC7D board"
+ select PPC_I8259
config PAL4
bool "SBS-Palomar4"
@@ -616,6 +625,7 @@ config PAL4
config GEMINI
bool "Synergy-Gemini"
depends on BROKEN
+ select PPC_INDIRECT_PCI
help
Select Gemini if configuring for a Synergy Microsystems' Gemini
series Single Board Computer. More information is available at:
@@ -747,13 +757,16 @@ config CPM2
on it (826x, 827x, 8560).
config PPC_CHRP
- bool
+ bool " Common Hardware Reference Platform (CHRP) based machines"
depends on PPC_MULTIPLATFORM
+ select PPC_I8259
+ select PPC_INDIRECT_PCI
default y
config PPC_PMAC
- bool
+ bool " Apple PowerMac based machines"
depends on PPC_MULTIPLATFORM
+ select PPC_INDIRECT_PCI
default y
config PPC_PMAC64
@@ -762,8 +775,10 @@ config PPC_PMAC64
default y
config PPC_PREP
- bool
+ bool " PowerPC Reference Platform (PReP) based machines"
depends on PPC_MULTIPLATFORM
+ select PPC_I8259
+ select PPC_INDIRECT_PCI
default y
config PPC_OF
@@ -797,6 +812,7 @@ config MV64360 # Really MV64360 & MV64460
config MV64X60
bool
depends on (GT64260 || MV64360)
+ select PPC_INDIRECT_PCI
default y
menu "Set bridge options"
@@ -845,6 +861,7 @@ config EPIC_SERIAL_MODE
config MPC10X_BRIDGE
bool
depends on POWERPMC250 || LOPEC || SANDPOINT
+ select PPC_INDIRECT_PCI
default y
config MPC10X_OPENPIC
@@ -870,6 +887,7 @@ config HARRIER_STORE_GATHERING
config MVME5100_IPMC761_PRESENT
bool "MVME5100 configured with an IPMC761"
depends on MVME5100
+ select PPC_I8259
config SPRUCE_BAUD_33M
bool "Spruce baud clock support"
@@ -1127,6 +1145,7 @@ menu "Bus options"
config ISA
bool "Support for ISA-bus hardware"
depends on PPC_PREP || PPC_CHRP
+ select PPC_I8259
help
Find out whether you have ISA slots on your motherboard. ISA is the
name of a bus system, i.e. the way the CPU talks to the other stuff
@@ -1139,6 +1158,17 @@ config GENERIC_ISA_DMA
depends on POWER3 || POWER4 || 6xx && !CPM2
default y
+config PPC_I8259
+ bool
+ default y if 85xx
+ default n
+
+config PPC_INDIRECT_PCI
+ bool
+ depends on PCI
+ default y if 40x || 44x || 85xx || 83xx
+ default n
+
config EISA
bool
help
@@ -1175,6 +1205,7 @@ config MPC83xx_PCI2
config PCI_QSPAN
bool "QSpan PCI"
depends on !4xx && !CPM2 && 8xx
+ select PPC_I8259
help
Say Y here if you have a system based on a Motorola 8xx-series
embedded processor with a QSPAN PCI interface, otherwise say N.
@@ -1182,6 +1213,7 @@ config PCI_QSPAN
config PCI_8260
bool
depends on PCI && 8260
+ select PPC_INDIRECT_PCI
default y
config 8260_PCI9
@@ -1368,7 +1400,7 @@ endmenu
source "lib/Kconfig"
-source "arch/ppc/oprofile/Kconfig"
+source "arch/powerpc/oprofile/Kconfig"
source "arch/ppc/Kconfig.debug"
diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile
index 16e2675f3270..94d5716fa7c3 100644
--- a/arch/ppc/Makefile
+++ b/arch/ppc/Makefile
@@ -26,6 +26,10 @@ CPPFLAGS += -Iarch/$(ARCH) -Iarch/$(ARCH)/include
AFLAGS += -Iarch/$(ARCH)
CFLAGS += -Iarch/$(ARCH) -msoft-float -pipe \
-ffixed-r2 -mmultiple
+
+# No AltiVec instruction when building kernel
+CFLAGS += $(call cc-option, -mno-altivec)
+
CPP = $(CC) -E $(CFLAGS)
# Temporary hack until we have migrated to asm-powerpc
LINUXINCLUDE += -Iarch/$(ARCH)/include
@@ -57,10 +61,12 @@ head-$(CONFIG_FSL_BOOKE) := arch/ppc/kernel/head_fsl_booke.o
head-$(CONFIG_6xx) += arch/ppc/kernel/idle_6xx.o
head-$(CONFIG_POWER4) += arch/ppc/kernel/idle_power4.o
-head-$(CONFIG_PPC_FPU) += arch/ppc/kernel/fpu.o
+head-$(CONFIG_PPC_FPU) += arch/powerpc/kernel/fpu.o
-core-y += arch/ppc/kernel/ arch/ppc/platforms/ \
- arch/ppc/mm/ arch/ppc/lib/ arch/ppc/syslib/
+core-y += arch/ppc/kernel/ arch/powerpc/kernel/ \
+ arch/ppc/platforms/ \
+ arch/ppc/mm/ arch/ppc/lib/ \
+ arch/ppc/syslib/ arch/powerpc/sysdev/
core-$(CONFIG_4xx) += arch/ppc/platforms/4xx/
core-$(CONFIG_83xx) += arch/ppc/platforms/83xx/
core-$(CONFIG_85xx) += arch/ppc/platforms/85xx/
@@ -71,7 +77,7 @@ drivers-$(CONFIG_8xx) += arch/ppc/8xx_io/
drivers-$(CONFIG_4xx) += arch/ppc/4xx_io/
drivers-$(CONFIG_CPM2) += arch/ppc/8260_io/
-drivers-$(CONFIG_OPROFILE) += arch/ppc/oprofile/
+drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/
BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm
diff --git a/arch/ppc/boot/of1275/claim.c b/arch/ppc/boot/of1275/claim.c
index e060292ae2a7..13169a5c4339 100644
--- a/arch/ppc/boot/of1275/claim.c
+++ b/arch/ppc/boot/of1275/claim.c
@@ -29,6 +29,7 @@ claim(unsigned int virt, unsigned int size, unsigned int align)
args.virt = virt;
args.size = size;
args.align = align;
+ args.ret = (void *) 0;
(*of_prom_entry)(&args);
return args.ret;
}
diff --git a/arch/ppc/boot/openfirmware/chrpmain.c b/arch/ppc/boot/openfirmware/chrpmain.c
index effe4a0624b0..245dbd9fc120 100644
--- a/arch/ppc/boot/openfirmware/chrpmain.c
+++ b/arch/ppc/boot/openfirmware/chrpmain.c
@@ -78,7 +78,7 @@ boot(int a1, int a2, void *prom)
begin_avail = avail_high = avail_ram;
end_avail = scratch + sizeof(scratch);
printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len);
- gunzip(dst, 0x400000, im, &len);
+ gunzip(dst, PROG_SIZE - PROG_START, im, &len);
printf("done %u bytes\n\r", len);
printf("%u bytes of heap consumed, max in use %u\n\r",
avail_high - begin_avail, heap_max);
diff --git a/arch/ppc/boot/openfirmware/coffmain.c b/arch/ppc/boot/openfirmware/coffmain.c
index 04ba9d57e110..2da8855e2be0 100644
--- a/arch/ppc/boot/openfirmware/coffmain.c
+++ b/arch/ppc/boot/openfirmware/coffmain.c
@@ -38,7 +38,7 @@ static char heap[SCRATCH_SIZE];
static unsigned long ram_start = 0;
static unsigned long ram_end = 0x1000000;
-static unsigned long prog_start = 0x900000;
+static unsigned long prog_start = 0x800000;
static unsigned long prog_size = 0x700000;
typedef void (*kernel_start_t)(int, int, void *);
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index b1457a8a9c0f..b35346df1e37 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -1,6 +1,7 @@
#
# Makefile for the linux kernel.
#
+ifneq ($(CONFIG_PPC_MERGE),y)
extra-$(CONFIG_PPC_STD_MMU) := head.o
extra-$(CONFIG_40x) := head_4xx.o
@@ -9,13 +10,12 @@ extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o
extra-$(CONFIG_8xx) := head_8xx.o
extra-$(CONFIG_6xx) += idle_6xx.o
extra-$(CONFIG_POWER4) += idle_power4.o
-extra-$(CONFIG_PPC_FPU) += fpu.o
extra-y += vmlinux.lds
obj-y := entry.o traps.o irq.o idle.o time.o misc.o \
- process.o signal.o ptrace.o align.o \
- semaphore.o syscalls.o setup.o \
- cputable.o ppc_htab.o perfmon.o
+ process.o align.o \
+ setup.o \
+ ppc_htab.o
obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o
obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o
obj-$(CONFIG_POWER4) += cpu_setup_power4.o
@@ -25,7 +25,6 @@ obj-$(CONFIG_PCI) += pci.o
obj-$(CONFIG_KGDB) += ppc-stub.o
obj-$(CONFIG_SMP) += smp.o smp-tbsync.o
obj-$(CONFIG_TAU) += temp.o
-obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
ifndef CONFIG_E200
obj-$(CONFIG_FSL_BOOKE) += perfmon_fsl_booke.o
endif
@@ -35,3 +34,21 @@ ifndef CONFIG_MATH_EMULATION
obj-$(CONFIG_8xx) += softemu8xx.o
endif
+# These are here while we do the architecture merge
+
+else
+obj-y := irq.o idle.o \
+ align.o
+obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o
+obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o
+obj-$(CONFIG_MODULES) += module.o
+obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-mapping.o
+obj-$(CONFIG_PCI) += pci.o
+obj-$(CONFIG_KGDB) += ppc-stub.o
+obj-$(CONFIG_SMP) += smp.o smp-tbsync.o
+obj-$(CONFIG_TAU) += temp.o
+ifndef CONFIG_E200
+obj-$(CONFIG_FSL_BOOKE) += perfmon_fsl_booke.o
+endif
+obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
+endif
diff --git a/arch/ppc/kernel/align.c b/arch/ppc/kernel/align.c
index ff81da9598d8..ab398c4b70b6 100644
--- a/arch/ppc/kernel/align.c
+++ b/arch/ppc/kernel/align.c
@@ -375,7 +375,7 @@ fix_alignment(struct pt_regs *regs)
#ifdef CONFIG_PPC_FPU
preempt_disable();
enable_kernel_fp();
- cvt_fd(&data.f, &data.d, &current->thread.fpscr);
+ cvt_fd(&data.f, &data.d, &current->thread);
preempt_enable();
#else
return 0;
@@ -385,7 +385,7 @@ fix_alignment(struct pt_regs *regs)
#ifdef CONFIG_PPC_FPU
preempt_disable();
enable_kernel_fp();
- cvt_df(&data.d, &data.f, &current->thread.fpscr);
+ cvt_df(&data.d, &data.f, &current->thread);
preempt_enable();
#else
return 0;
diff --git a/arch/ppc/kernel/asm-offsets.c b/arch/ppc/kernel/asm-offsets.c
index d9ad1d776d0e..968261d69572 100644
--- a/arch/ppc/kernel/asm-offsets.c
+++ b/arch/ppc/kernel/asm-offsets.c
@@ -130,10 +130,10 @@ main(void)
DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
+ DEFINE(TI_SC_NOERR, offsetof(struct thread_info, syscall_noerror));
DEFINE(TI_TASK, offsetof(struct thread_info, task));
DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain));
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
- DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags));
DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
@@ -141,6 +141,7 @@ main(void)
DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address));
DEFINE(pbe_next, offsetof(struct pbe, next));
+ DEFINE(TASK_SIZE, TASK_SIZE);
DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28);
return 0;
}
diff --git a/arch/ppc/kernel/cpu_setup_6xx.S b/arch/ppc/kernel/cpu_setup_6xx.S
index ba396438ede3..55ed7716636f 100644
--- a/arch/ppc/kernel/cpu_setup_6xx.S
+++ b/arch/ppc/kernel/cpu_setup_6xx.S
@@ -17,8 +17,6 @@
#include <asm/asm-offsets.h>
#include <asm/cache.h>
-_GLOBAL(__setup_cpu_601)
- blr
_GLOBAL(__setup_cpu_603)
b setup_common_caches
_GLOBAL(__setup_cpu_604)
@@ -292,10 +290,10 @@ _GLOBAL(__init_fpu_registers)
#define CS_SIZE 32
.data
- .balign L1_CACHE_LINE_SIZE
+ .balign L1_CACHE_BYTES
cpu_state_storage:
.space CS_SIZE
- .balign L1_CACHE_LINE_SIZE,0
+ .balign L1_CACHE_BYTES,0
.text
/* Called in normal context to backup CPU 0 state. This
diff --git a/arch/ppc/kernel/cpu_setup_power4.S b/arch/ppc/kernel/cpu_setup_power4.S
index 7e4fbb653724..d7bfd60e21fc 100644
--- a/arch/ppc/kernel/cpu_setup_power4.S
+++ b/arch/ppc/kernel/cpu_setup_power4.S
@@ -63,8 +63,6 @@ _GLOBAL(__970_cpu_preinit)
isync
blr
-_GLOBAL(__setup_cpu_power4)
- blr
_GLOBAL(__setup_cpu_ppc970)
mfspr r0,SPRN_HID0
li r11,5 /* clear DOZE and SLEEP */
@@ -88,10 +86,10 @@ _GLOBAL(__setup_cpu_ppc970)
#define CS_SIZE 32
.data
- .balign L1_CACHE_LINE_SIZE
+ .balign L1_CACHE_BYTES
cpu_state_storage:
.space CS_SIZE
- .balign L1_CACHE_LINE_SIZE,0
+ .balign L1_CACHE_BYTES,0
.text
/* Called in normal context to backup CPU 0 state. This
diff --git a/arch/ppc/kernel/dma-mapping.c b/arch/ppc/kernel/dma-mapping.c
index 0f710d2baec6..685fd0defe23 100644
--- a/arch/ppc/kernel/dma-mapping.c
+++ b/arch/ppc/kernel/dma-mapping.c
@@ -335,8 +335,6 @@ static int __init dma_alloc_init(void)
pte_t *pte;
int ret = 0;
- spin_lock(&init_mm.page_table_lock);
-
do {
pgd = pgd_offset(&init_mm, CONSISTENT_BASE);
pmd = pmd_alloc(&init_mm, pgd, CONSISTENT_BASE);
@@ -347,7 +345,7 @@ static int __init dma_alloc_init(void)
}
WARN_ON(!pmd_none(*pmd));
- pte = pte_alloc_kernel(&init_mm, pmd, CONSISTENT_BASE);
+ pte = pte_alloc_kernel(pmd, CONSISTENT_BASE);
if (!pte) {
printk(KERN_ERR "%s: no pte tables\n", __func__);
ret = -ENOMEM;
@@ -357,8 +355,6 @@ static int __init dma_alloc_init(void)
consistent_pte = pte;
} while (0);
- spin_unlock(&init_mm.page_table_lock);
-
return ret;
}
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
index 03d4886869f3..f044edbb454f 100644
--- a/arch/ppc/kernel/entry.S
+++ b/arch/ppc/kernel/entry.S
@@ -200,9 +200,8 @@ _GLOBAL(DoSyscall)
bl do_show_syscall
#endif /* SHOW_SYSCALLS */
rlwinm r10,r1,0,0,18 /* current_thread_info() */
- lwz r11,TI_LOCAL_FLAGS(r10)
- rlwinm r11,r11,0,~_TIFL_FORCE_NOERROR
- stw r11,TI_LOCAL_FLAGS(r10)
+ li r11,0
+ stb r11,TI_SC_NOERR(r10)
lwz r11,TI_FLAGS(r10)
andi. r11,r11,_TIF_SYSCALL_T_OR_A
bne- syscall_dotrace
@@ -227,8 +226,8 @@ ret_from_syscall:
cmplw 0,r3,r11
rlwinm r12,r1,0,0,18 /* current_thread_info() */
blt+ 30f
- lwz r11,TI_LOCAL_FLAGS(r12)
- andi. r11,r11,_TIFL_FORCE_NOERROR
+ lbz r11,TI_SC_NOERR(r12)
+ cmpwi r11,0
bne 30f
neg r3,r3
lwz r10,_CCR(r1) /* Set SO bit in CR */
@@ -633,7 +632,8 @@ sigreturn_exit:
rlwinm r12,r1,0,0,18 /* current_thread_info() */
lwz r9,TI_FLAGS(r12)
andi. r0,r9,_TIF_SYSCALL_T_OR_A
- bnel- do_syscall_trace_leave
+ beq+ ret_from_except_full
+ bl do_syscall_trace_leave
/* fall through */
.globl ret_from_except_full
diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S
index 1960fb8c259c..c5a890dca9cf 100644
--- a/arch/ppc/kernel/head.S
+++ b/arch/ppc/kernel/head.S
@@ -349,12 +349,12 @@ i##n: \
/* System reset */
/* core99 pmac starts the seconary here by changing the vector, and
- putting it back to what it was (UnknownException) when done. */
+ putting it back to what it was (unknown_exception) when done. */
#if defined(CONFIG_GEMINI) && defined(CONFIG_SMP)
. = 0x100
b __secondary_start_gemini
#else
- EXCEPTION(0x100, Reset, UnknownException, EXC_XFER_STD)
+ EXCEPTION(0x100, Reset, unknown_exception, EXC_XFER_STD)
#endif
/* Machine check */
@@ -389,7 +389,7 @@ i##n: \
cmpwi cr1,r4,0
bne cr1,1f
#endif
- EXC_XFER_STD(0x200, MachineCheckException)
+ EXC_XFER_STD(0x200, machine_check_exception)
#ifdef CONFIG_PPC_CHRP
1: b machine_check_in_rtas
#endif
@@ -456,10 +456,10 @@ Alignment:
mfspr r5,SPRN_DSISR
stw r5,_DSISR(r11)
addi r3,r1,STACK_FRAME_OVERHEAD
- EXC_XFER_EE(0x600, AlignmentException)
+ EXC_XFER_EE(0x600, alignment_exception)
/* Program check exception */
- EXCEPTION(0x700, ProgramCheck, ProgramCheckException, EXC_XFER_STD)
+ EXCEPTION(0x700, ProgramCheck, program_check_exception, EXC_XFER_STD)
/* Floating-point unavailable */
. = 0x800
@@ -467,13 +467,13 @@ FPUnavailable:
EXCEPTION_PROLOG
bne load_up_fpu /* if from user, just load it up */
addi r3,r1,STACK_FRAME_OVERHEAD
- EXC_XFER_EE_LITE(0x800, KernelFP)
+ EXC_XFER_EE_LITE(0x800, kernel_fp_unavailable_exception)
/* Decrementer */
EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE)
- EXCEPTION(0xa00, Trap_0a, UnknownException, EXC_XFER_EE)
- EXCEPTION(0xb00, Trap_0b, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0xa00, Trap_0a, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0xb00, Trap_0b, unknown_exception, EXC_XFER_EE)
/* System call */
. = 0xc00
@@ -482,8 +482,8 @@ SystemCall:
EXC_XFER_EE_LITE(0xc00, DoSyscall)
/* Single step - not used on 601 */
- EXCEPTION(0xd00, SingleStep, SingleStepException, EXC_XFER_STD)
- EXCEPTION(0xe00, Trap_0e, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0xd00, SingleStep, single_step_exception, EXC_XFER_STD)
+ EXCEPTION(0xe00, Trap_0e, unknown_exception, EXC_XFER_EE)
/*
* The Altivec unavailable trap is at 0x0f20. Foo.
@@ -502,7 +502,7 @@ SystemCall:
Trap_0f:
EXCEPTION_PROLOG
addi r3,r1,STACK_FRAME_OVERHEAD
- EXC_XFER_EE(0xf00, UnknownException)
+ EXC_XFER_EE(0xf00, unknown_exception)
/*
* Handle TLB miss for instruction on 603/603e.
@@ -702,44 +702,44 @@ DataStoreTLBMiss:
rfi
#ifndef CONFIG_ALTIVEC
-#define AltivecAssistException UnknownException
+#define altivec_assist_exception unknown_exception
#endif
- EXCEPTION(0x1300, Trap_13, InstructionBreakpoint, EXC_XFER_EE)
+ EXCEPTION(0x1300, Trap_13, instruction_breakpoint_exception, EXC_XFER_EE)
EXCEPTION(0x1400, SMI, SMIException, EXC_XFER_EE)
- EXCEPTION(0x1500, Trap_15, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE)
#ifdef CONFIG_POWER4
- EXCEPTION(0x1600, Trap_16, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1700, Trap_17, AltivecAssistException, EXC_XFER_EE)
+ EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1700, Trap_17, altivec_assist_exception, EXC_XFER_EE)
EXCEPTION(0x1800, Trap_18, TAUException, EXC_XFER_STD)
#else /* !CONFIG_POWER4 */
- EXCEPTION(0x1600, Trap_16, AltivecAssistException, EXC_XFER_EE)
+ EXCEPTION(0x1600, Trap_16, altivec_assist_exception, EXC_XFER_EE)
EXCEPTION(0x1700, Trap_17, TAUException, EXC_XFER_STD)
- EXCEPTION(0x1800, Trap_18, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE)
#endif /* CONFIG_POWER4 */
- EXCEPTION(0x1900, Trap_19, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1a00, Trap_1a, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1b00, Trap_1b, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1c00, Trap_1c, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1d00, Trap_1d, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1e00, Trap_1e, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1f00, Trap_1f, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1a00, Trap_1a, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1b00, Trap_1b, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1c00, Trap_1c, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1d00, Trap_1d, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1e00, Trap_1e, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1f00, Trap_1f, unknown_exception, EXC_XFER_EE)
EXCEPTION(0x2000, RunMode, RunModeException, EXC_XFER_EE)
- EXCEPTION(0x2100, Trap_21, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2200, Trap_22, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2300, Trap_23, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2400, Trap_24, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2500, Trap_25, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2600, Trap_26, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2700, Trap_27, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2800, Trap_28, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2900, Trap_29, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2a00, Trap_2a, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2b00, Trap_2b, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2c00, Trap_2c, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2d00, Trap_2d, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2e00, Trap_2e, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2f00, MOLTrampoline, UnknownException, EXC_XFER_EE_LITE)
+ EXCEPTION(0x2100, Trap_21, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2200, Trap_22, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2300, Trap_23, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2400, Trap_24, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2500, Trap_25, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2600, Trap_26, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2700, Trap_27, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2800, Trap_28, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2900, Trap_29, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2a00, Trap_2a, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2b00, Trap_2b, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2c00, Trap_2c, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2d00, Trap_2d, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2e00, Trap_2e, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2f00, MOLTrampoline, unknown_exception, EXC_XFER_EE_LITE)
.globl mol_trampoline
.set mol_trampoline, i0x2f00
@@ -751,7 +751,7 @@ AltiVecUnavailable:
#ifdef CONFIG_ALTIVEC
bne load_up_altivec /* if from user, just load it up */
#endif /* CONFIG_ALTIVEC */
- EXC_XFER_EE_LITE(0xf20, AltivecUnavailException)
+ EXC_XFER_EE_LITE(0xf20, altivec_unavailable_exception)
#ifdef CONFIG_PPC64BRIDGE
DataAccess:
@@ -767,12 +767,12 @@ DataSegment:
addi r3,r1,STACK_FRAME_OVERHEAD
mfspr r4,SPRN_DAR
stw r4,_DAR(r11)
- EXC_XFER_STD(0x380, UnknownException)
+ EXC_XFER_STD(0x380, unknown_exception)
InstructionSegment:
EXCEPTION_PROLOG
addi r3,r1,STACK_FRAME_OVERHEAD
- EXC_XFER_STD(0x480, UnknownException)
+ EXC_XFER_STD(0x480, unknown_exception)
#endif /* CONFIG_PPC64BRIDGE */
#ifdef CONFIG_ALTIVEC
@@ -804,7 +804,7 @@ load_up_altivec:
beq 1f
add r4,r4,r6
addi r4,r4,THREAD /* want THREAD of last_task_used_altivec */
- SAVE_32VR(0,r10,r4)
+ SAVE_32VRS(0,r10,r4)
mfvscr vr0
li r10,THREAD_VSCR
stvx vr0,r10,r4
@@ -824,7 +824,7 @@ load_up_altivec:
stw r4,THREAD_USED_VR(r5)
lvx vr0,r10,r5
mtvscr vr0
- REST_32VR(0,r10,r5)
+ REST_32VRS(0,r10,r5)
#ifndef CONFIG_SMP
subi r4,r5,THREAD
sub r4,r4,r6
@@ -870,7 +870,7 @@ giveup_altivec:
addi r3,r3,THREAD /* want THREAD of task */
lwz r5,PT_REGS(r3)
cmpwi 0,r5,0
- SAVE_32VR(0, r4, r3)
+ SAVE_32VRS(0, r4, r3)
mfvscr vr0
li r4,THREAD_VSCR
stvx vr0,r4,r3
@@ -916,7 +916,7 @@ relocate_kernel:
copy_and_flush:
addi r5,r5,-4
addi r6,r6,-4
-4: li r0,L1_CACHE_LINE_SIZE/4
+4: li r0,L1_CACHE_BYTES/4
mtctr r0
3: addi r6,r6,4 /* copy a cache line */
lwzx r0,r6,r4
@@ -1059,7 +1059,6 @@ __secondary_start:
lis r3,-KERNELBASE@h
mr r4,r24
- bl identify_cpu
bl call_setup_cpu /* Call setup_cpu for this CPU */
#ifdef CONFIG_6xx
lis r3,-KERNELBASE@h
@@ -1109,11 +1108,6 @@ __secondary_start:
* Those generic dummy functions are kept for CPUs not
* included in CONFIG_6xx
*/
-_GLOBAL(__setup_cpu_power3)
- blr
-_GLOBAL(__setup_cpu_generic)
- blr
-
#if !defined(CONFIG_6xx) && !defined(CONFIG_POWER4)
_GLOBAL(__save_cpu_setup)
blr
diff --git a/arch/ppc/kernel/head_44x.S b/arch/ppc/kernel/head_44x.S
index 599245b0407e..8b49679fad54 100644
--- a/arch/ppc/kernel/head_44x.S
+++ b/arch/ppc/kernel/head_44x.S
@@ -309,13 +309,13 @@ skpinv: addi r4,r4,1 /* Increment */
interrupt_base:
/* Critical Input Interrupt */
- CRITICAL_EXCEPTION(0x0100, CriticalInput, UnknownException)
+ CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception)
/* Machine Check Interrupt */
#ifdef CONFIG_440A
- MCHECK_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
+ MCHECK_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
#else
- CRITICAL_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
+ CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
#endif
/* Data Storage Interrupt */
@@ -442,7 +442,7 @@ interrupt_base:
#ifdef CONFIG_PPC_FPU
FP_UNAVAILABLE_EXCEPTION
#else
- EXCEPTION(0x2010, FloatingPointUnavailable, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x2010, FloatingPointUnavailable, unknown_exception, EXC_XFER_EE)
#endif
/* System Call Interrupt */
@@ -451,21 +451,21 @@ interrupt_base:
EXC_XFER_EE_LITE(0x0c00, DoSyscall)
/* Auxillary Processor Unavailable Interrupt */
- EXCEPTION(0x2020, AuxillaryProcessorUnavailable, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x2020, AuxillaryProcessorUnavailable, unknown_exception, EXC_XFER_EE)
/* Decrementer Interrupt */
DECREMENTER_EXCEPTION
/* Fixed Internal Timer Interrupt */
/* TODO: Add FIT support */
- EXCEPTION(0x1010, FixedIntervalTimer, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x1010, FixedIntervalTimer, unknown_exception, EXC_XFER_EE)
/* Watchdog Timer Interrupt */
/* TODO: Add watchdog support */
#ifdef CONFIG_BOOKE_WDT
CRITICAL_EXCEPTION(0x1020, WatchdogTimer, WatchdogException)
#else
- CRITICAL_EXCEPTION(0x1020, WatchdogTimer, UnknownException)
+ CRITICAL_EXCEPTION(0x1020, WatchdogTimer, unknown_exception)
#endif
/* Data TLB Error Interrupt */
@@ -743,14 +743,18 @@ _GLOBAL(set_context)
* goes at the beginning of the data segment, which is page-aligned.
*/
.data
-_GLOBAL(sdata)
-_GLOBAL(empty_zero_page)
+ .align 12
+ .globl sdata
+sdata:
+ .globl empty_zero_page
+empty_zero_page:
.space 4096
/*
* To support >32-bit physical addresses, we use an 8KB pgdir.
*/
-_GLOBAL(swapper_pg_dir)
+ .globl swapper_pg_dir
+swapper_pg_dir:
.space 8192
/* Reserved 4k for the critical exception stack & 4k for the machine
@@ -759,13 +763,15 @@ _GLOBAL(swapper_pg_dir)
.align 12
exception_stack_bottom:
.space BOOKE_EXCEPTION_STACK_SIZE
-_GLOBAL(exception_stack_top)
+ .globl exception_stack_top
+exception_stack_top:
/*
* This space gets a copy of optional info passed to us by the bootstrap
* which is used to pass parameters into the kernel like root=/dev/sda1, etc.
*/
-_GLOBAL(cmd_line)
+ .globl cmd_line
+cmd_line:
.space 512
/*
@@ -774,5 +780,3 @@ _GLOBAL(cmd_line)
*/
abatron_pteptrs:
.space 8
-
-
diff --git a/arch/ppc/kernel/head_4xx.S b/arch/ppc/kernel/head_4xx.S
index 8562b807b37c..10c261c67021 100644
--- a/arch/ppc/kernel/head_4xx.S
+++ b/arch/ppc/kernel/head_4xx.S
@@ -245,12 +245,12 @@ label:
/*
* 0x0100 - Critical Interrupt Exception
*/
- CRITICAL_EXCEPTION(0x0100, CriticalInterrupt, UnknownException)
+ CRITICAL_EXCEPTION(0x0100, CriticalInterrupt, unknown_exception)
/*
* 0x0200 - Machine Check Exception
*/
- CRITICAL_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
+ CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
/*
* 0x0300 - Data Storage Exception
@@ -405,7 +405,7 @@ label:
mfspr r4,SPRN_DEAR /* Grab the DEAR and save it */
stw r4,_DEAR(r11)
addi r3,r1,STACK_FRAME_OVERHEAD
- EXC_XFER_EE(0x600, AlignmentException)
+ EXC_XFER_EE(0x600, alignment_exception)
/* 0x0700 - Program Exception */
START_EXCEPTION(0x0700, ProgramCheck)
@@ -413,21 +413,21 @@ label:
mfspr r4,SPRN_ESR /* Grab the ESR and save it */
stw r4,_ESR(r11)
addi r3,r1,STACK_FRAME_OVERHEAD
- EXC_XFER_STD(0x700, ProgramCheckException)
+ EXC_XFER_STD(0x700, program_check_exception)
- EXCEPTION(0x0800, Trap_08, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x0900, Trap_09, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x0A00, Trap_0A, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x0B00, Trap_0B, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x0800, Trap_08, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x0900, Trap_09, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x0A00, Trap_0A, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x0B00, Trap_0B, unknown_exception, EXC_XFER_EE)
/* 0x0C00 - System Call Exception */
START_EXCEPTION(0x0C00, SystemCall)
NORMAL_EXCEPTION_PROLOG
EXC_XFER_EE_LITE(0xc00, DoSyscall)
- EXCEPTION(0x0D00, Trap_0D, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x0E00, Trap_0E, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x0F00, Trap_0F, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x0D00, Trap_0D, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x0E00, Trap_0E, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x0F00, Trap_0F, unknown_exception, EXC_XFER_EE)
/* 0x1000 - Programmable Interval Timer (PIT) Exception */
START_EXCEPTION(0x1000, Decrementer)
@@ -444,14 +444,14 @@ label:
/* 0x1010 - Fixed Interval Timer (FIT) Exception
*/
- STND_EXCEPTION(0x1010, FITException, UnknownException)
+ STND_EXCEPTION(0x1010, FITException, unknown_exception)
/* 0x1020 - Watchdog Timer (WDT) Exception
*/
#ifdef CONFIG_BOOKE_WDT
CRITICAL_EXCEPTION(0x1020, WDTException, WatchdogException)
#else
- CRITICAL_EXCEPTION(0x1020, WDTException, UnknownException)
+ CRITICAL_EXCEPTION(0x1020, WDTException, unknown_exception)
#endif
#endif
@@ -656,25 +656,25 @@ label:
mfspr r10, SPRN_SPRG0
b InstructionAccess
- EXCEPTION(0x1300, Trap_13, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1400, Trap_14, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1500, Trap_15, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1600, Trap_16, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x1300, Trap_13, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1400, Trap_14, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE)
#ifdef CONFIG_IBM405_ERR51
/* 405GP errata 51 */
START_EXCEPTION(0x1700, Trap_17)
b DTLBMiss
#else
- EXCEPTION(0x1700, Trap_17, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x1700, Trap_17, unknown_exception, EXC_XFER_EE)
#endif
- EXCEPTION(0x1800, Trap_18, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1900, Trap_19, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1A00, Trap_1A, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1B00, Trap_1B, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1C00, Trap_1C, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1D00, Trap_1D, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1E00, Trap_1E, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1F00, Trap_1F, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1A00, Trap_1A, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1B00, Trap_1B, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1C00, Trap_1C, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1D00, Trap_1D, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1E00, Trap_1E, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1F00, Trap_1F, unknown_exception, EXC_XFER_EE)
/* Check for a single step debug exception while in an exception
* handler before state has been saved. This is to catch the case
@@ -988,10 +988,14 @@ _GLOBAL(set_context)
* goes at the beginning of the data segment, which is page-aligned.
*/
.data
-_GLOBAL(sdata)
-_GLOBAL(empty_zero_page)
+ .align 12
+ .globl sdata
+sdata:
+ .globl empty_zero_page
+empty_zero_page:
.space 4096
-_GLOBAL(swapper_pg_dir)
+ .globl swapper_pg_dir
+swapper_pg_dir:
.space 4096
@@ -1001,12 +1005,14 @@ _GLOBAL(swapper_pg_dir)
exception_stack_bottom:
.space 4096
critical_stack_top:
-_GLOBAL(exception_stack_top)
+ .globl exception_stack_top
+exception_stack_top:
/* This space gets a copy of optional info passed to us by the bootstrap
* which is used to pass parameters into the kernel like root=/dev/sda1, etc.
*/
-_GLOBAL(cmd_line)
+ .globl cmd_line
+cmd_line:
.space 512
/* Room for two PTE pointers, usually the kernel and current user pointers
diff --git a/arch/ppc/kernel/head_8xx.S b/arch/ppc/kernel/head_8xx.S
index cb1a3a54a026..de0978742221 100644
--- a/arch/ppc/kernel/head_8xx.S
+++ b/arch/ppc/kernel/head_8xx.S
@@ -203,7 +203,7 @@ i##n: \
ret_from_except)
/* System reset */
- EXCEPTION(0x100, Reset, UnknownException, EXC_XFER_STD)
+ EXCEPTION(0x100, Reset, unknown_exception, EXC_XFER_STD)
/* Machine check */
. = 0x200
@@ -214,7 +214,7 @@ MachineCheck:
mfspr r5,SPRN_DSISR
stw r5,_DSISR(r11)
addi r3,r1,STACK_FRAME_OVERHEAD
- EXC_XFER_STD(0x200, MachineCheckException)
+ EXC_XFER_STD(0x200, machine_check_exception)
/* Data access exception.
* This is "never generated" by the MPC8xx. We jump to it for other
@@ -252,20 +252,20 @@ Alignment:
mfspr r5,SPRN_DSISR
stw r5,_DSISR(r11)
addi r3,r1,STACK_FRAME_OVERHEAD
- EXC_XFER_EE(0x600, AlignmentException)
+ EXC_XFER_EE(0x600, alignment_exception)
/* Program check exception */
- EXCEPTION(0x700, ProgramCheck, ProgramCheckException, EXC_XFER_STD)
+ EXCEPTION(0x700, ProgramCheck, program_check_exception, EXC_XFER_STD)
/* No FPU on MPC8xx. This exception is not supposed to happen.
*/
- EXCEPTION(0x800, FPUnavailable, UnknownException, EXC_XFER_STD)
+ EXCEPTION(0x800, FPUnavailable, unknown_exception, EXC_XFER_STD)
/* Decrementer */
EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE)
- EXCEPTION(0xa00, Trap_0a, UnknownException, EXC_XFER_EE)
- EXCEPTION(0xb00, Trap_0b, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0xa00, Trap_0a, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0xb00, Trap_0b, unknown_exception, EXC_XFER_EE)
/* System call */
. = 0xc00
@@ -274,9 +274,9 @@ SystemCall:
EXC_XFER_EE_LITE(0xc00, DoSyscall)
/* Single step - not used on 601 */
- EXCEPTION(0xd00, SingleStep, SingleStepException, EXC_XFER_STD)
- EXCEPTION(0xe00, Trap_0e, UnknownException, EXC_XFER_EE)
- EXCEPTION(0xf00, Trap_0f, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0xd00, SingleStep, single_step_exception, EXC_XFER_STD)
+ EXCEPTION(0xe00, Trap_0e, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0xf00, Trap_0f, unknown_exception, EXC_XFER_EE)
/* On the MPC8xx, this is a software emulation interrupt. It occurs
* for all unimplemented and illegal instructions.
@@ -540,22 +540,22 @@ DataTLBError:
#endif
b DataAccess
- EXCEPTION(0x1500, Trap_15, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1600, Trap_16, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1700, Trap_17, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1800, Trap_18, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1900, Trap_19, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1a00, Trap_1a, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1b00, Trap_1b, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1700, Trap_17, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1a00, Trap_1a, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1b00, Trap_1b, unknown_exception, EXC_XFER_EE)
/* On the MPC8xx, these next four traps are used for development
* support of breakpoints and such. Someday I will get around to
* using them.
*/
- EXCEPTION(0x1c00, Trap_1c, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1d00, Trap_1d, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1e00, Trap_1e, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1f00, Trap_1f, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x1c00, Trap_1c, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1d00, Trap_1d, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1e00, Trap_1e, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1f00, Trap_1f, unknown_exception, EXC_XFER_EE)
. = 0x2000
diff --git a/arch/ppc/kernel/head_booke.h b/arch/ppc/kernel/head_booke.h
index 9342acf12e72..aeb349b47af3 100644
--- a/arch/ppc/kernel/head_booke.h
+++ b/arch/ppc/kernel/head_booke.h
@@ -335,7 +335,7 @@ label:
mfspr r4,SPRN_DEAR; /* Grab the DEAR and save it */ \
stw r4,_DEAR(r11); \
addi r3,r1,STACK_FRAME_OVERHEAD; \
- EXC_XFER_EE(0x0600, AlignmentException)
+ EXC_XFER_EE(0x0600, alignment_exception)
#define PROGRAM_EXCEPTION \
START_EXCEPTION(Program) \
@@ -343,7 +343,7 @@ label:
mfspr r4,SPRN_ESR; /* Grab the ESR and save it */ \
stw r4,_ESR(r11); \
addi r3,r1,STACK_FRAME_OVERHEAD; \
- EXC_XFER_STD(0x0700, ProgramCheckException)
+ EXC_XFER_STD(0x0700, program_check_exception)
#define DECREMENTER_EXCEPTION \
START_EXCEPTION(Decrementer) \
diff --git a/arch/ppc/kernel/head_fsl_booke.S b/arch/ppc/kernel/head_fsl_booke.S
index 8e52e8408316..5063c603fad4 100644
--- a/arch/ppc/kernel/head_fsl_booke.S
+++ b/arch/ppc/kernel/head_fsl_booke.S
@@ -426,14 +426,14 @@ skpinv: addi r6,r6,1 /* Increment */
interrupt_base:
/* Critical Input Interrupt */
- CRITICAL_EXCEPTION(0x0100, CriticalInput, UnknownException)
+ CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception)
/* Machine Check Interrupt */
#ifdef CONFIG_E200
/* no RFMCI, MCSRRs on E200 */
- CRITICAL_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
+ CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
#else
- MCHECK_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
+ MCHECK_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
#endif
/* Data Storage Interrupt */
@@ -542,9 +542,9 @@ interrupt_base:
#else
#ifdef CONFIG_E200
/* E200 treats 'normal' floating point instructions as FP Unavail exception */
- EXCEPTION(0x0800, FloatingPointUnavailable, ProgramCheckException, EXC_XFER_EE)
+ EXCEPTION(0x0800, FloatingPointUnavailable, program_check_exception, EXC_XFER_EE)
#else
- EXCEPTION(0x0800, FloatingPointUnavailable, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x0800, FloatingPointUnavailable, unknown_exception, EXC_XFER_EE)
#endif
#endif
@@ -554,20 +554,20 @@ interrupt_base:
EXC_XFER_EE_LITE(0x0c00, DoSyscall)
/* Auxillary Processor Unavailable Interrupt */
- EXCEPTION(0x2900, AuxillaryProcessorUnavailable, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x2900, AuxillaryProcessorUnavailable, unknown_exception, EXC_XFER_EE)
/* Decrementer Interrupt */
DECREMENTER_EXCEPTION
/* Fixed Internal Timer Interrupt */
/* TODO: Add FIT support */
- EXCEPTION(0x3100, FixedIntervalTimer, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x3100, FixedIntervalTimer, unknown_exception, EXC_XFER_EE)
/* Watchdog Timer Interrupt */
#ifdef CONFIG_BOOKE_WDT
CRITICAL_EXCEPTION(0x3200, WatchdogTimer, WatchdogException)
#else
- CRITICAL_EXCEPTION(0x3200, WatchdogTimer, UnknownException)
+ CRITICAL_EXCEPTION(0x3200, WatchdogTimer, unknown_exception)
#endif
/* Data TLB Error Interrupt */
@@ -696,21 +696,21 @@ interrupt_base:
addi r3,r1,STACK_FRAME_OVERHEAD
EXC_XFER_EE_LITE(0x2010, KernelSPE)
#else
- EXCEPTION(0x2020, SPEUnavailable, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x2020, SPEUnavailable, unknown_exception, EXC_XFER_EE)
#endif /* CONFIG_SPE */
/* SPE Floating Point Data */
#ifdef CONFIG_SPE
EXCEPTION(0x2030, SPEFloatingPointData, SPEFloatingPointException, EXC_XFER_EE);
#else
- EXCEPTION(0x2040, SPEFloatingPointData, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x2040, SPEFloatingPointData, unknown_exception, EXC_XFER_EE)
#endif /* CONFIG_SPE */
/* SPE Floating Point Round */
- EXCEPTION(0x2050, SPEFloatingPointRound, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x2050, SPEFloatingPointRound, unknown_exception, EXC_XFER_EE)
/* Performance Monitor */
- EXCEPTION(0x2060, PerformanceMonitor, PerformanceMonitorException, EXC_XFER_STD)
+ EXCEPTION(0x2060, PerformanceMonitor, performance_monitor_exception, EXC_XFER_STD)
/* Debug Interrupt */
@@ -853,7 +853,7 @@ load_up_spe:
cmpi 0,r4,0
beq 1f
addi r4,r4,THREAD /* want THREAD of last_task_used_spe */
- SAVE_32EVR(0,r10,r4)
+ SAVE_32EVRS(0,r10,r4)
evxor evr10, evr10, evr10 /* clear out evr10 */
evmwumiaa evr10, evr10, evr10 /* evr10 <- ACC = 0 * 0 + ACC */
li r5,THREAD_ACC
@@ -873,7 +873,7 @@ load_up_spe:
stw r4,THREAD_USED_SPE(r5)
evlddx evr4,r10,r5
evmra evr4,evr4
- REST_32EVR(0,r10,r5)
+ REST_32EVRS(0,r10,r5)
#ifndef CONFIG_SMP
subi r4,r5,THREAD
stw r4,last_task_used_spe@l(r3)
@@ -963,7 +963,7 @@ _GLOBAL(giveup_spe)
addi r3,r3,THREAD /* want THREAD of task */
lwz r5,PT_REGS(r3)
cmpi 0,r5,0
- SAVE_32EVR(0, r4, r3)
+ SAVE_32EVRS(0, r4, r3)
evxor evr6, evr6, evr6 /* clear out evr6 */
evmwumiaa evr6, evr6, evr6 /* evr6 <- ACC = 0 * 0 + ACC */
li r4,THREAD_ACC
@@ -1028,10 +1028,14 @@ _GLOBAL(set_context)
* goes at the beginning of the data segment, which is page-aligned.
*/
.data
-_GLOBAL(sdata)
-_GLOBAL(empty_zero_page)
+ .align 12
+ .globl sdata
+sdata:
+ .globl empty_zero_page
+empty_zero_page:
.space 4096
-_GLOBAL(swapper_pg_dir)
+ .globl swapper_pg_dir
+swapper_pg_dir:
.space 4096
/* Reserved 4k for the critical exception stack & 4k for the machine
@@ -1040,13 +1044,15 @@ _GLOBAL(swapper_pg_dir)
.align 12
exception_stack_bottom:
.space BOOKE_EXCEPTION_STACK_SIZE * NR_CPUS
-_GLOBAL(exception_stack_top)
+ .globl exception_stack_top
+exception_stack_top:
/*
* This space gets a copy of optional info passed to us by the bootstrap
* which is used to pass parameters into the kernel like root=/dev/sda1, etc.
*/
-_GLOBAL(cmd_line)
+ .globl cmd_line
+cmd_line:
.space 512
/*
@@ -1055,4 +1061,3 @@ _GLOBAL(cmd_line)
*/
abatron_pteptrs:
.space 8
-
diff --git a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c
index fba29c876b62..11e5b44713f7 100644
--- a/arch/ppc/kernel/idle.c
+++ b/arch/ppc/kernel/idle.c
@@ -32,6 +32,7 @@
#include <asm/cache.h>
#include <asm/cputable.h>
#include <asm/machdep.h>
+#include <asm/smp.h>
void default_idle(void)
{
@@ -74,7 +75,7 @@ void cpu_idle(void)
/*
* Register the sysctl to set/clear powersave_nap.
*/
-extern unsigned long powersave_nap;
+extern int powersave_nap;
static ctl_table powersave_nap_ctl_table[]={
{
diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c
index 8843f3af230f..772e428aaa59 100644
--- a/arch/ppc/kernel/irq.c
+++ b/arch/ppc/kernel/irq.c
@@ -57,6 +57,7 @@
#include <asm/cache.h>
#include <asm/prom.h>
#include <asm/ptrace.h>
+#include <asm/machdep.h>
#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
diff --git a/arch/ppc/kernel/l2cr.S b/arch/ppc/kernel/l2cr.S
index 861115249b35..d7f4e982b539 100644
--- a/arch/ppc/kernel/l2cr.S
+++ b/arch/ppc/kernel/l2cr.S
@@ -203,7 +203,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
* L1 icache
*/
b 20f
- .balign L1_CACHE_LINE_SIZE
+ .balign L1_CACHE_BYTES
22:
sync
mtspr SPRN_L2CR,r3
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index 90d917d2e856..3056ede2424d 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -125,9 +125,8 @@ _GLOBAL(identify_cpu)
1:
addis r6,r3,cur_cpu_spec@ha
addi r6,r6,cur_cpu_spec@l
- slwi r4,r4,2
sub r8,r8,r3
- stwx r8,r4,r6
+ stw r8,0(r6)
blr
/*
@@ -186,19 +185,18 @@ _GLOBAL(do_cpu_ftr_fixups)
*
* Setup function is called with:
* r3 = data offset
- * r4 = CPU number
- * r5 = ptr to CPU spec (relocated)
+ * r4 = ptr to CPU spec (relocated)
*/
_GLOBAL(call_setup_cpu)
- addis r5,r3,cur_cpu_spec@ha
- addi r5,r5,cur_cpu_spec@l
- slwi r4,r24,2
- lwzx r5,r4,r5
+ addis r4,r3,cur_cpu_spec@ha
+ addi r4,r4,cur_cpu_spec@l
+ lwz r4,0(r4)
+ add r4,r4,r3
+ lwz r5,CPU_SPEC_SETUP(r4)
+ cmpi 0,r5,0
add r5,r5,r3
- lwz r6,CPU_SPEC_SETUP(r5)
- add r6,r6,r3
- mtctr r6
- mr r4,r24
+ beqlr
+ mtctr r5
bctr
#if defined(CONFIG_CPU_FREQ_PMAC) && defined(CONFIG_6xx)
@@ -273,134 +271,6 @@ _GLOBAL(low_choose_7447a_dfs)
#endif /* CONFIG_CPU_FREQ_PMAC && CONFIG_6xx */
-/* void local_save_flags_ptr(unsigned long *flags) */
-_GLOBAL(local_save_flags_ptr)
- mfmsr r4
- stw r4,0(r3)
- blr
- /*
- * Need these nops here for taking over save/restore to
- * handle lost intrs
- * -- Cort
- */
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
-_GLOBAL(local_save_flags_ptr_end)
-
-/* void local_irq_restore(unsigned long flags) */
-_GLOBAL(local_irq_restore)
-/*
- * Just set/clear the MSR_EE bit through restore/flags but do not
- * change anything else. This is needed by the RT system and makes
- * sense anyway.
- * -- Cort
- */
- mfmsr r4
- /* Copy all except the MSR_EE bit from r4 (current MSR value)
- to r3. This is the sort of thing the rlwimi instruction is
- designed for. -- paulus. */
- rlwimi r3,r4,0,17,15
- /* Check if things are setup the way we want _already_. */
- cmpw 0,r3,r4
- beqlr
-1: SYNC
- mtmsr r3
- SYNC
- blr
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
-_GLOBAL(local_irq_restore_end)
-
-_GLOBAL(local_irq_disable)
- mfmsr r0 /* Get current interrupt state */
- rlwinm r3,r0,16+1,32-1,31 /* Extract old value of 'EE' */
- rlwinm r0,r0,0,17,15 /* clear MSR_EE in r0 */
- SYNC /* Some chip revs have problems here... */
- mtmsr r0 /* Update machine state */
- blr /* Done */
- /*
- * Need these nops here for taking over save/restore to
- * handle lost intrs
- * -- Cort
- */
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
-_GLOBAL(local_irq_disable_end)
-
-_GLOBAL(local_irq_enable)
- mfmsr r3 /* Get current state */
- ori r3,r3,MSR_EE /* Turn on 'EE' bit */
- SYNC /* Some chip revs have problems here... */
- mtmsr r3 /* Update machine state */
- blr
- /*
- * Need these nops here for taking over save/restore to
- * handle lost intrs
- * -- Cort
- */
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
-_GLOBAL(local_irq_enable_end)
-
/*
* complement mask on the msr then "or" some values on.
* _nmask_and_or_msr(nmask, value_to_or)
@@ -628,21 +498,21 @@ _GLOBAL(flush_icache_range)
BEGIN_FTR_SECTION
blr /* for 601, do nothing */
END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
- li r5,L1_CACHE_LINE_SIZE-1
+ li r5,L1_CACHE_BYTES-1
andc r3,r3,r5
subf r4,r3,r4
add r4,r4,r5
- srwi. r4,r4,LG_L1_CACHE_LINE_SIZE
+ srwi. r4,r4,L1_CACHE_SHIFT
beqlr
mtctr r4
mr r6,r3
1: dcbst 0,r3
- addi r3,r3,L1_CACHE_LINE_SIZE
+ addi r3,r3,L1_CACHE_BYTES
bdnz 1b
sync /* wait for dcbst's to get to ram */
mtctr r4
2: icbi 0,r6
- addi r6,r6,L1_CACHE_LINE_SIZE
+ addi r6,r6,L1_CACHE_BYTES
bdnz 2b
sync /* additional sync needed on g4 */
isync
@@ -655,16 +525,16 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
* clean_dcache_range(unsigned long start, unsigned long stop)
*/
_GLOBAL(clean_dcache_range)
- li r5,L1_CACHE_LINE_SIZE-1
+ li r5,L1_CACHE_BYTES-1
andc r3,r3,r5
subf r4,r3,r4
add r4,r4,r5
- srwi. r4,r4,LG_L1_CACHE_LINE_SIZE
+ srwi. r4,r4,L1_CACHE_SHIFT
beqlr
mtctr r4
1: dcbst 0,r3
- addi r3,r3,L1_CACHE_LINE_SIZE
+ addi r3,r3,L1_CACHE_BYTES
bdnz 1b
sync /* wait for dcbst's to get to ram */
blr
@@ -676,16 +546,16 @@ _GLOBAL(clean_dcache_range)
* flush_dcache_range(unsigned long start, unsigned long stop)
*/
_GLOBAL(flush_dcache_range)
- li r5,L1_CACHE_LINE_SIZE-1
+ li r5,L1_CACHE_BYTES-1
andc r3,r3,r5
subf r4,r3,r4
add r4,r4,r5
- srwi. r4,r4,LG_L1_CACHE_LINE_SIZE
+ srwi. r4,r4,L1_CACHE_SHIFT
beqlr
mtctr r4
1: dcbf 0,r3
- addi r3,r3,L1_CACHE_LINE_SIZE
+ addi r3,r3,L1_CACHE_BYTES
bdnz 1b
sync /* wait for dcbst's to get to ram */
blr
@@ -698,16 +568,16 @@ _GLOBAL(flush_dcache_range)
* invalidate_dcache_range(unsigned long start, unsigned long stop)
*/
_GLOBAL(invalidate_dcache_range)
- li r5,L1_CACHE_LINE_SIZE-1
+ li r5,L1_CACHE_BYTES-1
andc r3,r3,r5
subf r4,r3,r4
add r4,r4,r5
- srwi. r4,r4,LG_L1_CACHE_LINE_SIZE
+ srwi. r4,r4,L1_CACHE_SHIFT
beqlr
mtctr r4
1: dcbi 0,r3
- addi r3,r3,L1_CACHE_LINE_SIZE
+ addi r3,r3,L1_CACHE_BYTES
bdnz 1b
sync /* wait for dcbi's to get to ram */
blr
@@ -728,7 +598,7 @@ _GLOBAL(flush_dcache_all)
mtctr r4
lis r5, KERNELBASE@h
1: lwz r3, 0(r5) /* Load one word from every line */
- addi r5, r5, L1_CACHE_LINE_SIZE
+ addi r5, r5, L1_CACHE_BYTES
bdnz 1b
blr
#endif /* CONFIG_NOT_COHERENT_CACHE */
@@ -746,16 +616,16 @@ BEGIN_FTR_SECTION
blr /* for 601, do nothing */
END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
rlwinm r3,r3,0,0,19 /* Get page base address */
- li r4,4096/L1_CACHE_LINE_SIZE /* Number of lines in a page */
+ li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */
mtctr r4
mr r6,r3
0: dcbst 0,r3 /* Write line to ram */
- addi r3,r3,L1_CACHE_LINE_SIZE
+ addi r3,r3,L1_CACHE_BYTES
bdnz 0b
sync
mtctr r4
1: icbi 0,r6
- addi r6,r6,L1_CACHE_LINE_SIZE
+ addi r6,r6,L1_CACHE_BYTES
bdnz 1b
sync
isync
@@ -778,16 +648,16 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
mtmsr r0
isync
rlwinm r3,r3,0,0,19 /* Get page base address */
- li r4,4096/L1_CACHE_LINE_SIZE /* Number of lines in a page */
+ li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */
mtctr r4
mr r6,r3
0: dcbst 0,r3 /* Write line to ram */
- addi r3,r3,L1_CACHE_LINE_SIZE
+ addi r3,r3,L1_CACHE_BYTES
bdnz 0b
sync
mtctr r4
1: icbi 0,r6
- addi r6,r6,L1_CACHE_LINE_SIZE
+ addi r6,r6,L1_CACHE_BYTES
bdnz 1b
sync
mtmsr r10 /* restore DR */
@@ -802,7 +672,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
* void clear_pages(void *page, int order) ;
*/
_GLOBAL(clear_pages)
- li r0,4096/L1_CACHE_LINE_SIZE
+ li r0,4096/L1_CACHE_BYTES
slw r0,r0,r4
mtctr r0
#ifdef CONFIG_8xx
@@ -814,7 +684,7 @@ _GLOBAL(clear_pages)
#else
1: dcbz 0,r3
#endif
- addi r3,r3,L1_CACHE_LINE_SIZE
+ addi r3,r3,L1_CACHE_BYTES
bdnz 1b
blr
@@ -840,7 +710,7 @@ _GLOBAL(copy_page)
#ifdef CONFIG_8xx
/* don't use prefetch on 8xx */
- li r0,4096/L1_CACHE_LINE_SIZE
+ li r0,4096/L1_CACHE_BYTES
mtctr r0
1: COPY_16_BYTES
bdnz 1b
@@ -854,13 +724,13 @@ _GLOBAL(copy_page)
li r11,4
mtctr r0
11: dcbt r11,r4
- addi r11,r11,L1_CACHE_LINE_SIZE
+ addi r11,r11,L1_CACHE_BYTES
bdnz 11b
#else /* MAX_COPY_PREFETCH == 1 */
dcbt r5,r4
- li r11,L1_CACHE_LINE_SIZE+4
+ li r11,L1_CACHE_BYTES+4
#endif /* MAX_COPY_PREFETCH */
- li r0,4096/L1_CACHE_LINE_SIZE - MAX_COPY_PREFETCH
+ li r0,4096/L1_CACHE_BYTES - MAX_COPY_PREFETCH
crclr 4*cr0+eq
2:
mtctr r0
@@ -868,12 +738,12 @@ _GLOBAL(copy_page)
dcbt r11,r4
dcbz r5,r3
COPY_16_BYTES
-#if L1_CACHE_LINE_SIZE >= 32
+#if L1_CACHE_BYTES >= 32
COPY_16_BYTES
-#if L1_CACHE_LINE_SIZE >= 64
+#if L1_CACHE_BYTES >= 64
COPY_16_BYTES
COPY_16_BYTES
-#if L1_CACHE_LINE_SIZE >= 128
+#if L1_CACHE_BYTES >= 128
COPY_16_BYTES
COPY_16_BYTES
COPY_16_BYTES
@@ -1098,33 +968,6 @@ _GLOBAL(_get_SP)
blr
/*
- * These are used in the alignment trap handler when emulating
- * single-precision loads and stores.
- * We restore and save the fpscr so the task gets the same result
- * and exceptions as if the cpu had performed the load or store.
- */
-
-#ifdef CONFIG_PPC_FPU
-_GLOBAL(cvt_fd)
- lfd 0,-4(r5) /* load up fpscr value */
- mtfsf 0xff,0
- lfs 0,0(r3)
- stfd 0,0(r4)
- mffs 0 /* save new fpscr value */
- stfd 0,-4(r5)
- blr
-
-_GLOBAL(cvt_df)
- lfd 0,-4(r5) /* load up fpscr value */
- mtfsf 0xff,0
- lfd 0,0(r3)
- stfs 0,0(r4)
- mffs 0 /* save new fpscr value */
- stfd 0,-4(r5)
- blr
-#endif
-
-/*
* Create a kernel thread
* kernel_thread(fn, arg, flags)
*/
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
index 854e45beb387..e8f4e576750a 100644
--- a/arch/ppc/kernel/pci.c
+++ b/arch/ppc/kernel/pci.c
@@ -21,6 +21,7 @@
#include <asm/byteorder.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
+#include <asm/machdep.h>
#undef DEBUG
@@ -53,7 +54,7 @@ static u8* pci_to_OF_bus_map;
/* By default, we don't re-assign bus numbers. We do this only on
* some pmacs
*/
-int pci_assign_all_busses;
+int pci_assign_all_buses;
struct pci_controller* hose_head;
struct pci_controller** hose_tail = &hose_head;
@@ -644,7 +645,7 @@ pcibios_alloc_controller(void)
/*
* Functions below are used on OpenFirmware machines.
*/
-static void __openfirmware
+static void
make_one_node_map(struct device_node* node, u8 pci_bus)
{
int *bus_range;
@@ -678,7 +679,7 @@ make_one_node_map(struct device_node* node, u8 pci_bus)
}
}
-void __openfirmware
+void
pcibios_make_OF_bus_map(void)
{
int i;
@@ -720,7 +721,7 @@ pcibios_make_OF_bus_map(void)
typedef int (*pci_OF_scan_iterator)(struct device_node* node, void* data);
-static struct device_node* __openfirmware
+static struct device_node*
scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void* data)
{
struct device_node* sub_node;
@@ -761,7 +762,7 @@ scan_OF_pci_childs_iterator(struct device_node* node, void* data)
return 0;
}
-static struct device_node* __openfirmware
+static struct device_node*
scan_OF_childs_for_device(struct device_node* node, u8 bus, u8 dev_fn)
{
u8 filter_data[2] = {bus, dev_fn};
@@ -813,18 +814,20 @@ pci_busdev_to_OF_node(struct pci_bus *bus, int devfn)
/* Now, lookup childs of the hose */
return scan_OF_childs_for_device(node->child, busnr, devfn);
}
+EXPORT_SYMBOL(pci_busdev_to_OF_node);
struct device_node*
pci_device_to_OF_node(struct pci_dev *dev)
{
return pci_busdev_to_OF_node(dev->bus, dev->devfn);
}
+EXPORT_SYMBOL(pci_device_to_OF_node);
/* This routine is meant to be used early during boot, when the
* PCI bus numbers have not yet been assigned, and you need to
* issue PCI config cycles to an OF device.
* It could also be used to "fix" RTAS config cycles if you want
- * to set pci_assign_all_busses to 1 and still use RTAS for PCI
+ * to set pci_assign_all_buses to 1 and still use RTAS for PCI
* config cycles.
*/
struct pci_controller*
@@ -842,7 +845,7 @@ pci_find_hose_for_OF_device(struct device_node* node)
return NULL;
}
-static int __openfirmware
+static int
find_OF_pci_device_filter(struct device_node* node, void* data)
{
return ((void *)node == data);
@@ -890,6 +893,7 @@ pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn)
}
return -ENODEV;
}
+EXPORT_SYMBOL(pci_device_from_OF_node);
void __init
pci_process_bridge_OF_ranges(struct pci_controller *hose,
@@ -1030,6 +1034,10 @@ static ssize_t pci_show_devspec(struct device *dev, struct device_attribute *att
}
static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL);
+#else /* CONFIG_PPC_OF */
+void pcibios_make_OF_bus_map(void)
+{
+}
#endif /* CONFIG_PPC_OF */
/* Add sysfs properties */
@@ -1262,12 +1270,12 @@ pcibios_init(void)
/* Scan all of the recorded PCI controllers. */
for (next_busno = 0, hose = hose_head; hose; hose = hose->next) {
- if (pci_assign_all_busses)
+ if (pci_assign_all_buses)
hose->first_busno = next_busno;
hose->last_busno = 0xff;
bus = pci_scan_bus(hose->first_busno, hose->ops, hose);
hose->last_busno = bus->subordinate;
- if (pci_assign_all_busses || next_busno <= hose->last_busno)
+ if (pci_assign_all_buses || next_busno <= hose->last_busno)
next_busno = hose->last_busno + pcibios_assign_bus_offset;
}
pci_bus_count = next_busno;
@@ -1276,7 +1284,7 @@ pcibios_init(void)
* numbers vs. kernel bus numbers since we may have to
* remap them.
*/
- if (pci_assign_all_busses && have_of)
+ if (pci_assign_all_buses && have_of)
pcibios_make_OF_bus_map();
/* Do machine dependent PCI interrupt routing */
@@ -1586,16 +1594,17 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,
* above routine
*/
pgprot_t pci_phys_mem_access_prot(struct file *file,
- unsigned long offset,
+ unsigned long pfn,
unsigned long size,
pgprot_t protection)
{
struct pci_dev *pdev = NULL;
struct resource *found = NULL;
unsigned long prot = pgprot_val(protection);
+ unsigned long offset = pfn << PAGE_SHIFT;
int i;
- if (page_is_ram(offset >> PAGE_SHIFT))
+ if (page_is_ram(pfn))
return prot;
prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
diff --git a/arch/ppc/kernel/perfmon.c b/arch/ppc/kernel/perfmon.c
deleted file mode 100644
index 22df9a596a0f..000000000000
--- a/arch/ppc/kernel/perfmon.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/* kernel/perfmon.c
- * PPC 32 Performance Monitor Infrastructure
- *
- * Author: Andy Fleming
- * Copyright (c) 2004 Freescale Semiconductor, 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.
- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/user.h>
-#include <linux/a.out.h>
-#include <linux/interrupt.h>
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/prctl.h>
-
-#include <asm/pgtable.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/reg.h>
-#include <asm/xmon.h>
-
-/* A lock to regulate grabbing the interrupt */
-DEFINE_SPINLOCK(perfmon_lock);
-
-#if defined (CONFIG_FSL_BOOKE) && !defined (CONFIG_E200)
-static void dummy_perf(struct pt_regs *regs)
-{
- unsigned int pmgc0 = mfpmr(PMRN_PMGC0);
-
- pmgc0 &= ~PMGC0_PMIE;
- mtpmr(PMRN_PMGC0, pmgc0);
-}
-
-#elif defined(CONFIG_6xx)
-/* Ensure exceptions are disabled */
-static void dummy_perf(struct pt_regs *regs)
-{
- unsigned int mmcr0 = mfspr(SPRN_MMCR0);
-
- mmcr0 &= ~MMCR0_PMXE;
- mtspr(SPRN_MMCR0, mmcr0);
-}
-#else
-static void dummy_perf(struct pt_regs *regs)
-{
-}
-#endif
-
-void (*perf_irq)(struct pt_regs *) = dummy_perf;
-
-/* Grab the interrupt, if it's free.
- * Returns 0 on success, -1 if the interrupt is taken already */
-int request_perfmon_irq(void (*handler)(struct pt_regs *))
-{
- int err = 0;
-
- spin_lock(&perfmon_lock);
-
- if (perf_irq == dummy_perf)
- perf_irq = handler;
- else {
- pr_info("perfmon irq already handled by %p\n", perf_irq);
- err = -1;
- }
-
- spin_unlock(&perfmon_lock);
-
- return err;
-}
-
-void free_perfmon_irq(void)
-{
- spin_lock(&perfmon_lock);
-
- perf_irq = dummy_perf;
-
- spin_unlock(&perfmon_lock);
-}
-
-EXPORT_SYMBOL(perf_irq);
-EXPORT_SYMBOL(request_perfmon_irq);
-EXPORT_SYMBOL(free_perfmon_irq);
diff --git a/arch/ppc/kernel/perfmon_fsl_booke.c b/arch/ppc/kernel/perfmon_fsl_booke.c
index 03526bfb0840..32455dfcc36b 100644
--- a/arch/ppc/kernel/perfmon_fsl_booke.c
+++ b/arch/ppc/kernel/perfmon_fsl_booke.c
@@ -32,7 +32,7 @@
#include <asm/io.h>
#include <asm/reg.h>
#include <asm/xmon.h>
-#include <asm/perfmon.h>
+#include <asm/pmc.h>
static inline u32 get_pmlca(int ctr);
static inline void set_pmlca(int ctr, u32 pmlca);
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
index 88f6bb7b6964..ae24196d78f6 100644
--- a/arch/ppc/kernel/ppc_ksyms.c
+++ b/arch/ppc/kernel/ppc_ksyms.c
@@ -53,10 +53,10 @@
extern void transfer_to_handler(void);
extern void do_IRQ(struct pt_regs *regs);
-extern void MachineCheckException(struct pt_regs *regs);
-extern void AlignmentException(struct pt_regs *regs);
-extern void ProgramCheckException(struct pt_regs *regs);
-extern void SingleStepException(struct pt_regs *regs);
+extern void machine_check_exception(struct pt_regs *regs);
+extern void alignment_exception(struct pt_regs *regs);
+extern void program_check_exception(struct pt_regs *regs);
+extern void single_step_exception(struct pt_regs *regs);
extern int do_signal(sigset_t *, struct pt_regs *);
extern int pmac_newworld;
extern int sys_sigreturn(struct pt_regs *regs);
@@ -72,10 +72,10 @@ EXPORT_SYMBOL(clear_user_page);
EXPORT_SYMBOL(do_signal);
EXPORT_SYMBOL(transfer_to_handler);
EXPORT_SYMBOL(do_IRQ);
-EXPORT_SYMBOL(MachineCheckException);
-EXPORT_SYMBOL(AlignmentException);
-EXPORT_SYMBOL(ProgramCheckException);
-EXPORT_SYMBOL(SingleStepException);
+EXPORT_SYMBOL(machine_check_exception);
+EXPORT_SYMBOL(alignment_exception);
+EXPORT_SYMBOL(program_check_exception);
+EXPORT_SYMBOL(single_step_exception);
EXPORT_SYMBOL(sys_sigreturn);
EXPORT_SYMBOL(ppc_n_lost_interrupts);
EXPORT_SYMBOL(ppc_lost_interrupts);
@@ -230,9 +230,6 @@ EXPORT_SYMBOL(find_all_nodes);
EXPORT_SYMBOL(get_property);
EXPORT_SYMBOL(request_OF_resource);
EXPORT_SYMBOL(release_OF_resource);
-EXPORT_SYMBOL(pci_busdev_to_OF_node);
-EXPORT_SYMBOL(pci_device_to_OF_node);
-EXPORT_SYMBOL(pci_device_from_OF_node);
EXPORT_SYMBOL(of_find_node_by_name);
EXPORT_SYMBOL(of_find_node_by_type);
EXPORT_SYMBOL(of_find_compatible_node);
@@ -272,16 +269,6 @@ EXPORT_SYMBOL(screen_info);
#endif
EXPORT_SYMBOL(__delay);
-#ifndef INLINE_IRQS
-EXPORT_SYMBOL(local_irq_enable);
-EXPORT_SYMBOL(local_irq_enable_end);
-EXPORT_SYMBOL(local_irq_disable);
-EXPORT_SYMBOL(local_irq_disable_end);
-EXPORT_SYMBOL(local_save_flags_ptr);
-EXPORT_SYMBOL(local_save_flags_ptr_end);
-EXPORT_SYMBOL(local_irq_restore);
-EXPORT_SYMBOL(local_irq_restore_end);
-#endif
EXPORT_SYMBOL(timer_interrupt);
EXPORT_SYMBOL(irq_desc);
EXPORT_SYMBOL(tb_ticks_per_jiffy);
@@ -335,11 +322,6 @@ EXPORT_SYMBOL(mmu_hash_lock); /* For MOL */
extern long *intercept_table;
EXPORT_SYMBOL(intercept_table);
#endif /* CONFIG_PPC_STD_MMU */
-EXPORT_SYMBOL(cur_cpu_spec);
-#ifdef CONFIG_PPC_PMAC
-extern unsigned long agp_special_page;
-EXPORT_SYMBOL(agp_special_page);
-#endif
#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
EXPORT_SYMBOL(__mtdcr);
EXPORT_SYMBOL(__mfdcr);
diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c
index 82de66e4db6d..cb1c7b92f8c6 100644
--- a/arch/ppc/kernel/process.c
+++ b/arch/ppc/kernel/process.c
@@ -152,18 +152,66 @@ int check_stack(struct task_struct *tsk)
}
#endif /* defined(CHECK_STACK) */
-#ifdef CONFIG_ALTIVEC
-int
-dump_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs)
+/*
+ * Make sure the floating-point register state in the
+ * the thread_struct is up to date for task tsk.
+ */
+void flush_fp_to_thread(struct task_struct *tsk)
{
- if (regs->msr & MSR_VEC)
- giveup_altivec(current);
- memcpy(vrregs, &current->thread.vr[0], sizeof(*vrregs));
+ if (tsk->thread.regs) {
+ /*
+ * We need to disable preemption here because if we didn't,
+ * another process could get scheduled after the regs->msr
+ * test but before we have finished saving the FP registers
+ * to the thread_struct. That process could take over the
+ * FPU, and then when we get scheduled again we would store
+ * bogus values for the remaining FP registers.
+ */
+ preempt_disable();
+ if (tsk->thread.regs->msr & MSR_FP) {
+#ifdef CONFIG_SMP
+ /*
+ * This should only ever be called for current or
+ * for a stopped child process. Since we save away
+ * the FP register state on context switch on SMP,
+ * there is something wrong if a stopped child appears
+ * to still have its FP state in the CPU registers.
+ */
+ BUG_ON(tsk != current);
+#endif
+ giveup_fpu(current);
+ }
+ preempt_enable();
+ }
+}
+
+void enable_kernel_fp(void)
+{
+ WARN_ON(preemptible());
+
+#ifdef CONFIG_SMP
+ if (current->thread.regs && (current->thread.regs->msr & MSR_FP))
+ giveup_fpu(current);
+ else
+ giveup_fpu(NULL); /* just enables FP for kernel */
+#else
+ giveup_fpu(last_task_used_math);
+#endif /* CONFIG_SMP */
+}
+EXPORT_SYMBOL(enable_kernel_fp);
+
+int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs)
+{
+ preempt_disable();
+ if (tsk->thread.regs && (tsk->thread.regs->msr & MSR_FP))
+ giveup_fpu(tsk);
+ preempt_enable();
+ memcpy(fpregs, &tsk->thread.fpr[0], sizeof(*fpregs));
return 1;
}
-void
-enable_kernel_altivec(void)
+#ifdef CONFIG_ALTIVEC
+void enable_kernel_altivec(void)
{
WARN_ON(preemptible());
@@ -177,19 +225,35 @@ enable_kernel_altivec(void)
#endif /* __SMP __ */
}
EXPORT_SYMBOL(enable_kernel_altivec);
-#endif /* CONFIG_ALTIVEC */
-#ifdef CONFIG_SPE
-int
-dump_spe(struct pt_regs *regs, elf_vrregset_t *evrregs)
+/*
+ * Make sure the VMX/Altivec register state in the
+ * the thread_struct is up to date for task tsk.
+ */
+void flush_altivec_to_thread(struct task_struct *tsk)
{
- if (regs->msr & MSR_SPE)
- giveup_spe(current);
- /* We copy u32 evr[32] + u64 acc + u32 spefscr -> 35 */
- memcpy(evrregs, &current->thread.evr[0], sizeof(u32) * 35);
+ if (tsk->thread.regs) {
+ preempt_disable();
+ if (tsk->thread.regs->msr & MSR_VEC) {
+#ifdef CONFIG_SMP
+ BUG_ON(tsk != current);
+#endif
+ giveup_altivec(current);
+ }
+ preempt_enable();
+ }
+}
+
+int dump_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs)
+{
+ if (regs->msr & MSR_VEC)
+ giveup_altivec(current);
+ memcpy(vrregs, &current->thread.vr[0], sizeof(*vrregs));
return 1;
}
+#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
void
enable_kernel_spe(void)
{
@@ -205,34 +269,30 @@ enable_kernel_spe(void)
#endif /* __SMP __ */
}
EXPORT_SYMBOL(enable_kernel_spe);
-#endif /* CONFIG_SPE */
-void
-enable_kernel_fp(void)
+void flush_spe_to_thread(struct task_struct *tsk)
{
- WARN_ON(preemptible());
-
+ if (tsk->thread.regs) {
+ preempt_disable();
+ if (tsk->thread.regs->msr & MSR_SPE) {
#ifdef CONFIG_SMP
- if (current->thread.regs && (current->thread.regs->msr & MSR_FP))
- giveup_fpu(current);
- else
- giveup_fpu(NULL); /* just enables FP for kernel */
-#else
- giveup_fpu(last_task_used_math);
-#endif /* CONFIG_SMP */
+ BUG_ON(tsk != current);
+#endif
+ giveup_spe(current);
+ }
+ preempt_enable();
+ }
}
-EXPORT_SYMBOL(enable_kernel_fp);
-int
-dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs)
+int dump_spe(struct pt_regs *regs, elf_vrregset_t *evrregs)
{
- preempt_disable();
- if (tsk->thread.regs && (tsk->thread.regs->msr & MSR_FP))
- giveup_fpu(tsk);
- preempt_enable();
- memcpy(fpregs, &tsk->thread.fpr[0], sizeof(*fpregs));
+ if (regs->msr & MSR_SPE)
+ giveup_spe(current);
+ /* We copy u32 evr[32] + u64 acc + u32 spefscr -> 35 */
+ memcpy(evrregs, &current->thread.evr[0], sizeof(u32) * 35);
return 1;
}
+#endif /* CONFIG_SPE */
struct task_struct *__switch_to(struct task_struct *prev,
struct task_struct *new)
@@ -287,11 +347,13 @@ struct task_struct *__switch_to(struct task_struct *prev,
#endif /* CONFIG_SPE */
#endif /* CONFIG_SMP */
+#ifdef CONFIG_ALTIVEC
/* Avoid the trap. On smp this this never happens since
* we don't set last_task_used_altivec -- Cort
*/
if (new->thread.regs && last_task_used_altivec == new)
new->thread.regs->msr |= MSR_VEC;
+#endif
#ifdef CONFIG_SPE
/* Avoid the trap. On smp this this never happens since
* we don't set last_task_used_spe
@@ -482,7 +544,7 @@ void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp)
last_task_used_spe = NULL;
#endif
memset(current->thread.fpr, 0, sizeof(current->thread.fpr));
- current->thread.fpscr = 0;
+ current->thread.fpscr.val = 0;
#ifdef CONFIG_ALTIVEC
memset(current->thread.vr, 0, sizeof(current->thread.vr));
memset(&current->thread.vscr, 0, sizeof(current->thread.vscr));
@@ -557,14 +619,16 @@ int sys_clone(unsigned long clone_flags, unsigned long usp,
return do_fork(clone_flags, usp, regs, 0, parent_tidp, child_tidp);
}
-int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6,
+int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3,
+ unsigned long p4, unsigned long p5, unsigned long p6,
struct pt_regs *regs)
{
CHECK_FULL_REGS(regs);
return do_fork(SIGCHLD, regs->gpr[1], regs, 0, NULL, NULL);
}
-int sys_vfork(int p1, int p2, int p3, int p4, int p5, int p6,
+int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,
+ unsigned long p4, unsigned long p5, unsigned long p6,
struct pt_regs *regs)
{
CHECK_FULL_REGS(regs);
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index 545cfd0fab59..6bcb85d2b7fd 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -71,7 +71,8 @@ struct ide_machdep_calls ppc_ide_md;
unsigned long boot_mem_size;
unsigned long ISA_DMA_THRESHOLD;
-unsigned long DMA_MODE_READ, DMA_MODE_WRITE;
+unsigned int DMA_MODE_READ;
+unsigned int DMA_MODE_WRITE;
#ifdef CONFIG_PPC_MULTIPLATFORM
int _machine = 0;
@@ -82,8 +83,18 @@ extern void pmac_init(unsigned long r3, unsigned long r4,
unsigned long r5, unsigned long r6, unsigned long r7);
extern void chrp_init(unsigned long r3, unsigned long r4,
unsigned long r5, unsigned long r6, unsigned long r7);
+
+dev_t boot_dev;
#endif /* CONFIG_PPC_MULTIPLATFORM */
+int have_of;
+EXPORT_SYMBOL(have_of);
+
+#ifdef __DO_IRQ_CANON
+int ppc_do_canonicalize_irqs;
+EXPORT_SYMBOL(ppc_do_canonicalize_irqs);
+#endif
+
#ifdef CONFIG_MAGIC_SYSRQ
unsigned long SYSRQ_KEY = 0x54;
#endif /* CONFIG_MAGIC_SYSRQ */
@@ -185,18 +196,18 @@ int show_cpuinfo(struct seq_file *m, void *v)
seq_printf(m, "processor\t: %d\n", i);
seq_printf(m, "cpu\t\t: ");
- if (cur_cpu_spec[i]->pvr_mask)
- seq_printf(m, "%s", cur_cpu_spec[i]->cpu_name);
+ if (cur_cpu_spec->pvr_mask)
+ seq_printf(m, "%s", cur_cpu_spec->cpu_name);
else
seq_printf(m, "unknown (%08x)", pvr);
#ifdef CONFIG_ALTIVEC
- if (cur_cpu_spec[i]->cpu_features & CPU_FTR_ALTIVEC)
+ if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC)
seq_printf(m, ", altivec supported");
#endif
seq_printf(m, "\n");
#ifdef CONFIG_TAU
- if (cur_cpu_spec[i]->cpu_features & CPU_FTR_TAU) {
+ if (cur_cpu_spec->cpu_features & CPU_FTR_TAU) {
#ifdef CONFIG_TAU_AVERAGE
/* more straightforward, but potentially misleading */
seq_printf(m, "temperature \t: %u C (uncalibrated)\n",
@@ -339,7 +350,7 @@ early_init(int r3, int r4, int r5)
* Assume here that all clock rates are the same in a
* smp system. -- Cort
*/
-int __openfirmware
+int
of_show_percpuinfo(struct seq_file *m, int i)
{
struct device_node *cpu_node;
@@ -404,11 +415,15 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
_machine = _MACH_prep;
}
+#ifdef CONFIG_PPC_PREP
/* not much more to do here, if prep */
if (_machine == _MACH_prep) {
prep_init(r3, r4, r5, r6, r7);
return;
}
+#endif
+
+ have_of = 1;
/* prom_init has already been called from __start */
if (boot_infos)
@@ -479,12 +494,16 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
#endif /* CONFIG_ADB */
switch (_machine) {
+#ifdef CONFIG_PPC_PMAC
case _MACH_Pmac:
pmac_init(r3, r4, r5, r6, r7);
break;
+#endif
+#ifdef CONFIG_PPC_CHRP
case _MACH_chrp:
chrp_init(r3, r4, r5, r6, r7);
break;
+#endif
}
}
@@ -721,7 +740,7 @@ void __init setup_arch(char **cmdline_p)
#endif
#ifdef CONFIG_XMON
- xmon_map_scc();
+ xmon_init(1);
if (strstr(cmd_line, "xmon"))
xmon(NULL);
#endif /* CONFIG_XMON */
@@ -745,12 +764,12 @@ void __init setup_arch(char **cmdline_p)
* for a possibly more accurate value.
*/
if (cpu_has_feature(CPU_FTR_SPLIT_ID_CACHE)) {
- dcache_bsize = cur_cpu_spec[0]->dcache_bsize;
- icache_bsize = cur_cpu_spec[0]->icache_bsize;
+ dcache_bsize = cur_cpu_spec->dcache_bsize;
+ icache_bsize = cur_cpu_spec->icache_bsize;
ucache_bsize = 0;
} else
ucache_bsize = dcache_bsize = icache_bsize
- = cur_cpu_spec[0]->dcache_bsize;
+ = cur_cpu_spec->dcache_bsize;
/* reboot on panic */
panic_timeout = 180;
diff --git a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c
deleted file mode 100644
index 2244bf91e593..000000000000
--- a/arch/ppc/kernel/signal.c
+++ /dev/null
@@ -1,771 +0,0 @@
-/*
- * arch/ppc/kernel/signal.c
- *
- * PowerPC version
- * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
- *
- * Derived from "arch/i386/kernel/signal.c"
- * Copyright (C) 1991, 1992 Linus Torvalds
- * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
- *
- * This program is free software; you can redistribute 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/sched.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/kernel.h>
-#include <linux/signal.h>
-#include <linux/errno.h>
-#include <linux/wait.h>
-#include <linux/ptrace.h>
-#include <linux/unistd.h>
-#include <linux/stddef.h>
-#include <linux/elf.h>
-#include <linux/tty.h>
-#include <linux/binfmts.h>
-#include <linux/suspend.h>
-#include <asm/ucontext.h>
-#include <asm/uaccess.h>
-#include <asm/pgtable.h>
-#include <asm/cacheflush.h>
-
-#undef DEBUG_SIG
-
-#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
-
-extern void sigreturn_exit(struct pt_regs *);
-
-#define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs))
-
-int do_signal(sigset_t *oldset, struct pt_regs *regs);
-
-/*
- * Atomically swap in the new signal mask, and wait for a signal.
- */
-int
-sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7,
- struct pt_regs *regs)
-{
- sigset_t saveset;
-
- mask &= _BLOCKABLE;
- spin_lock_irq(&current->sighand->siglock);
- saveset = current->blocked;
- siginitset(&current->blocked, mask);
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
-
- regs->result = -EINTR;
- regs->gpr[3] = EINTR;
- regs->ccr |= 0x10000000;
- while (1) {
- current->state = TASK_INTERRUPTIBLE;
- schedule();
- if (do_signal(&saveset, regs))
- sigreturn_exit(regs);
- }
-}
-
-int
-sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, int p3, int p4,
- int p6, int p7, struct pt_regs *regs)
-{
- sigset_t saveset, newset;
-
- /* XXX: Don't preclude handling different sized sigset_t's. */
- if (sigsetsize != sizeof(sigset_t))
- return -EINVAL;
-
- if (copy_from_user(&newset, unewset, sizeof(newset)))
- return -EFAULT;
- sigdelsetmask(&newset, ~_BLOCKABLE);
-
- spin_lock_irq(&current->sighand->siglock);
- saveset = current->blocked;
- current->blocked = newset;
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
-
- regs->result = -EINTR;
- regs->gpr[3] = EINTR;
- regs->ccr |= 0x10000000;
- while (1) {
- current->state = TASK_INTERRUPTIBLE;
- schedule();
- if (do_signal(&saveset, regs))
- sigreturn_exit(regs);
- }
-}
-
-
-int
-sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, int r5,
- int r6, int r7, int r8, struct pt_regs *regs)
-{
- return do_sigaltstack(uss, uoss, regs->gpr[1]);
-}
-
-int
-sys_sigaction(int sig, const struct old_sigaction __user *act,
- struct old_sigaction __user *oact)
-{
- struct k_sigaction new_ka, old_ka;
- int ret;
-
- if (act) {
- old_sigset_t mask;
- if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
- __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
- __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
- return -EFAULT;
- __get_user(new_ka.sa.sa_flags, &act->sa_flags);
- __get_user(mask, &act->sa_mask);
- siginitset(&new_ka.sa.sa_mask, mask);
- }
-
- ret = do_sigaction(sig, (act? &new_ka: NULL), (oact? &old_ka: NULL));
-
- if (!ret && oact) {
- if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
- __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
- __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
- return -EFAULT;
- __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
- __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
- }
-
- return ret;
-}
-
-/*
- * When we have signals to deliver, we set up on the
- * user stack, going down from the original stack pointer:
- * a sigregs struct
- * a sigcontext struct
- * a gap of __SIGNAL_FRAMESIZE bytes
- *
- * Each of these things must be a multiple of 16 bytes in size.
- *
- */
-struct sigregs {
- struct mcontext mctx; /* all the register values */
- /* Programs using the rs6000/xcoff abi can save up to 19 gp regs
- and 18 fp regs below sp before decrementing it. */
- int abigap[56];
-};
-
-/* We use the mc_pad field for the signal return trampoline. */
-#define tramp mc_pad
-
-/*
- * When we have rt signals to deliver, we set up on the
- * user stack, going down from the original stack pointer:
- * one rt_sigframe struct (siginfo + ucontext + ABI gap)
- * a gap of __SIGNAL_FRAMESIZE+16 bytes
- * (the +16 is to get the siginfo and ucontext in the same
- * positions as in older kernels).
- *
- * Each of these things must be a multiple of 16 bytes in size.
- *
- */
-struct rt_sigframe
-{
- struct siginfo info;
- struct ucontext uc;
- /* Programs using the rs6000/xcoff abi can save up to 19 gp regs
- and 18 fp regs below sp before decrementing it. */
- int abigap[56];
-};
-
-/*
- * Save the current user registers on the user stack.
- * We only save the altivec/spe registers if the process has used
- * altivec/spe instructions at some point.
- */
-static int
-save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, int sigret)
-{
- /* save general and floating-point registers */
- CHECK_FULL_REGS(regs);
- preempt_disable();
- if (regs->msr & MSR_FP)
- giveup_fpu(current);
-#ifdef CONFIG_ALTIVEC
- if (current->thread.used_vr && (regs->msr & MSR_VEC))
- giveup_altivec(current);
-#endif /* CONFIG_ALTIVEC */
-#ifdef CONFIG_SPE
- if (current->thread.used_spe && (regs->msr & MSR_SPE))
- giveup_spe(current);
-#endif /* CONFIG_ALTIVEC */
- preempt_enable();
-
- if (__copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE)
- || __copy_to_user(&frame->mc_fregs, current->thread.fpr,
- ELF_NFPREG * sizeof(double)))
- return 1;
-
- current->thread.fpscr = 0; /* turn off all fp exceptions */
-
-#ifdef CONFIG_ALTIVEC
- /* save altivec registers */
- if (current->thread.used_vr) {
- if (__copy_to_user(&frame->mc_vregs, current->thread.vr,
- ELF_NVRREG * sizeof(vector128)))
- return 1;
- /* set MSR_VEC in the saved MSR value to indicate that
- frame->mc_vregs contains valid data */
- if (__put_user(regs->msr | MSR_VEC, &frame->mc_gregs[PT_MSR]))
- return 1;
- }
- /* else assert((regs->msr & MSR_VEC) == 0) */
-
- /* We always copy to/from vrsave, it's 0 if we don't have or don't
- * use altivec. Since VSCR only contains 32 bits saved in the least
- * significant bits of a vector, we "cheat" and stuff VRSAVE in the
- * most significant bits of that same vector. --BenH
- */
- if (__put_user(current->thread.vrsave, (u32 __user *)&frame->mc_vregs[32]))
- return 1;
-#endif /* CONFIG_ALTIVEC */
-
-#ifdef CONFIG_SPE
- /* save spe registers */
- if (current->thread.used_spe) {
- if (__copy_to_user(&frame->mc_vregs, current->thread.evr,
- ELF_NEVRREG * sizeof(u32)))
- return 1;
- /* set MSR_SPE in the saved MSR value to indicate that
- frame->mc_vregs contains valid data */
- if (__put_user(regs->msr | MSR_SPE, &frame->mc_gregs[PT_MSR]))
- return 1;
- }
- /* else assert((regs->msr & MSR_SPE) == 0) */
-
- /* We always copy to/from spefscr */
- if (__put_user(current->thread.spefscr, (u32 *)&frame->mc_vregs + ELF_NEVRREG))
- return 1;
-#endif /* CONFIG_SPE */
-
- if (sigret) {
- /* Set up the sigreturn trampoline: li r0,sigret; sc */
- if (__put_user(0x38000000UL + sigret, &frame->tramp[0])
- || __put_user(0x44000002UL, &frame->tramp[1]))
- return 1;
- flush_icache_range((unsigned long) &frame->tramp[0],
- (unsigned long) &frame->tramp[2]);
- }
-
- return 0;
-}
-
-/*
- * Restore the current user register values from the user stack,
- * (except for MSR).
- */
-static int
-restore_user_regs(struct pt_regs *regs, struct mcontext __user *sr, int sig)
-{
- unsigned long save_r2 = 0;
-#if defined(CONFIG_ALTIVEC) || defined(CONFIG_SPE)
- unsigned long msr;
-#endif
-
- /* backup/restore the TLS as we don't want it to be modified */
- if (!sig)
- save_r2 = regs->gpr[2];
- /* copy up to but not including MSR */
- if (__copy_from_user(regs, &sr->mc_gregs, PT_MSR * sizeof(elf_greg_t)))
- return 1;
- /* copy from orig_r3 (the word after the MSR) up to the end */
- if (__copy_from_user(&regs->orig_gpr3, &sr->mc_gregs[PT_ORIG_R3],
- GP_REGS_SIZE - PT_ORIG_R3 * sizeof(elf_greg_t)))
- return 1;
- if (!sig)
- regs->gpr[2] = save_r2;
-
- /* force the process to reload the FP registers from
- current->thread when it next does FP instructions */
- regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1);
- if (__copy_from_user(current->thread.fpr, &sr->mc_fregs,
- sizeof(sr->mc_fregs)))
- return 1;
-
-#ifdef CONFIG_ALTIVEC
- /* force the process to reload the altivec registers from
- current->thread when it next does altivec instructions */
- regs->msr &= ~MSR_VEC;
- if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_VEC) != 0) {
- /* restore altivec registers from the stack */
- if (__copy_from_user(current->thread.vr, &sr->mc_vregs,
- sizeof(sr->mc_vregs)))
- return 1;
- } else if (current->thread.used_vr)
- memset(&current->thread.vr, 0, ELF_NVRREG * sizeof(vector128));
-
- /* Always get VRSAVE back */
- if (__get_user(current->thread.vrsave, (u32 __user *)&sr->mc_vregs[32]))
- return 1;
-#endif /* CONFIG_ALTIVEC */
-
-#ifdef CONFIG_SPE
- /* force the process to reload the spe registers from
- current->thread when it next does spe instructions */
- regs->msr &= ~MSR_SPE;
- if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_SPE) != 0) {
- /* restore spe registers from the stack */
- if (__copy_from_user(current->thread.evr, &sr->mc_vregs,
- ELF_NEVRREG * sizeof(u32)))
- return 1;
- } else if (current->thread.used_spe)
- memset(&current->thread.evr, 0, ELF_NEVRREG * sizeof(u32));
-
- /* Always get SPEFSCR back */
- if (__get_user(current->thread.spefscr, (u32 *)&sr->mc_vregs + ELF_NEVRREG))
- return 1;
-#endif /* CONFIG_SPE */
-
-#ifndef CONFIG_SMP
- preempt_disable();
- if (last_task_used_math == current)
- last_task_used_math = NULL;
- if (last_task_used_altivec == current)
- last_task_used_altivec = NULL;
- if (last_task_used_spe == current)
- last_task_used_spe = NULL;
- preempt_enable();
-#endif
- return 0;
-}
-
-/*
- * Restore the user process's signal mask
- */
-static void
-restore_sigmask(sigset_t *set)
-{
- sigdelsetmask(set, ~_BLOCKABLE);
- spin_lock_irq(&current->sighand->siglock);
- current->blocked = *set;
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
-}
-
-/*
- * Set up a signal frame for a "real-time" signal handler
- * (one which gets siginfo).
- */
-static void
-handle_rt_signal(unsigned long sig, struct k_sigaction *ka,
- siginfo_t *info, sigset_t *oldset, struct pt_regs * regs,
- unsigned long newsp)
-{
- struct rt_sigframe __user *rt_sf;
- struct mcontext __user *frame;
- unsigned long origsp = newsp;
-
- /* Set up Signal Frame */
- /* Put a Real Time Context onto stack */
- newsp -= sizeof(*rt_sf);
- rt_sf = (struct rt_sigframe __user *) newsp;
-
- /* create a stack frame for the caller of the handler */
- newsp -= __SIGNAL_FRAMESIZE + 16;
-
- if (!access_ok(VERIFY_WRITE, (void __user *) newsp, origsp - newsp))
- goto badframe;
-
- /* Put the siginfo & fill in most of the ucontext */
- if (copy_siginfo_to_user(&rt_sf->info, info)
- || __put_user(0, &rt_sf->uc.uc_flags)
- || __put_user(0, &rt_sf->uc.uc_link)
- || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp)
- || __put_user(sas_ss_flags(regs->gpr[1]),
- &rt_sf->uc.uc_stack.ss_flags)
- || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size)
- || __put_user(&rt_sf->uc.uc_mcontext, &rt_sf->uc.uc_regs)
- || __copy_to_user(&rt_sf->uc.uc_sigmask, oldset, sizeof(*oldset)))
- goto badframe;
-
- /* Save user registers on the stack */
- frame = &rt_sf->uc.uc_mcontext;
- if (save_user_regs(regs, frame, __NR_rt_sigreturn))
- goto badframe;
-
- if (put_user(regs->gpr[1], (unsigned long __user *)newsp))
- goto badframe;
- regs->gpr[1] = newsp;
- regs->gpr[3] = sig;
- regs->gpr[4] = (unsigned long) &rt_sf->info;
- regs->gpr[5] = (unsigned long) &rt_sf->uc;
- regs->gpr[6] = (unsigned long) rt_sf;
- regs->nip = (unsigned long) ka->sa.sa_handler;
- regs->link = (unsigned long) frame->tramp;
- regs->trap = 0;
-
- return;
-
-badframe:
-#ifdef DEBUG_SIG
- printk("badframe in handle_rt_signal, regs=%p frame=%p newsp=%lx\n",
- regs, frame, newsp);
-#endif
- force_sigsegv(sig, current);
-}
-
-static int do_setcontext(struct ucontext __user *ucp, struct pt_regs *regs, int sig)
-{
- sigset_t set;
- struct mcontext __user *mcp;
-
- if (__copy_from_user(&set, &ucp->uc_sigmask, sizeof(set))
- || __get_user(mcp, &ucp->uc_regs))
- return -EFAULT;
- restore_sigmask(&set);
- if (restore_user_regs(regs, mcp, sig))
- return -EFAULT;
-
- return 0;
-}
-
-int sys_swapcontext(struct ucontext __user *old_ctx,
- struct ucontext __user *new_ctx,
- int ctx_size, int r6, int r7, int r8, struct pt_regs *regs)
-{
- unsigned char tmp;
-
- /* Context size is for future use. Right now, we only make sure
- * we are passed something we understand
- */
- if (ctx_size < sizeof(struct ucontext))
- return -EINVAL;
-
- if (old_ctx != NULL) {
- if (!access_ok(VERIFY_WRITE, old_ctx, sizeof(*old_ctx))
- || save_user_regs(regs, &old_ctx->uc_mcontext, 0)
- || __copy_to_user(&old_ctx->uc_sigmask,
- &current->blocked, sizeof(sigset_t))
- || __put_user(&old_ctx->uc_mcontext, &old_ctx->uc_regs))
- return -EFAULT;
- }
- if (new_ctx == NULL)
- return 0;
- if (!access_ok(VERIFY_READ, new_ctx, sizeof(*new_ctx))
- || __get_user(tmp, (u8 __user *) new_ctx)
- || __get_user(tmp, (u8 __user *) (new_ctx + 1) - 1))
- return -EFAULT;
-
- /*
- * If we get a fault copying the context into the kernel's
- * image of the user's registers, we can't just return -EFAULT
- * because the user's registers will be corrupted. For instance
- * the NIP value may have been updated but not some of the
- * other registers. Given that we have done the access_ok
- * and successfully read the first and last bytes of the region
- * above, this should only happen in an out-of-memory situation
- * or if another thread unmaps the region containing the context.
- * We kill the task with a SIGSEGV in this situation.
- */
- if (do_setcontext(new_ctx, regs, 0))
- do_exit(SIGSEGV);
- sigreturn_exit(regs);
- /* doesn't actually return back to here */
- return 0;
-}
-
-int sys_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
- struct pt_regs *regs)
-{
- struct rt_sigframe __user *rt_sf;
-
- /* Always make any pending restarted system calls return -EINTR */
- current_thread_info()->restart_block.fn = do_no_restart_syscall;
-
- rt_sf = (struct rt_sigframe __user *)
- (regs->gpr[1] + __SIGNAL_FRAMESIZE + 16);
- if (!access_ok(VERIFY_READ, rt_sf, sizeof(struct rt_sigframe)))
- goto bad;
- if (do_setcontext(&rt_sf->uc, regs, 1))
- goto bad;
-
- /*
- * It's not clear whether or why it is desirable to save the
- * sigaltstack setting on signal delivery and restore it on
- * signal return. But other architectures do this and we have
- * always done it up until now so it is probably better not to
- * change it. -- paulus
- */
- do_sigaltstack(&rt_sf->uc.uc_stack, NULL, regs->gpr[1]);
-
- sigreturn_exit(regs); /* doesn't return here */
- return 0;
-
- bad:
- force_sig(SIGSEGV, current);
- return 0;
-}
-
-int sys_debug_setcontext(struct ucontext __user *ctx,
- int ndbg, struct sig_dbg_op __user *dbg,
- int r6, int r7, int r8,
- struct pt_regs *regs)
-{
- struct sig_dbg_op op;
- int i;
- unsigned long new_msr = regs->msr;
-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
- unsigned long new_dbcr0 = current->thread.dbcr0;
-#endif
-
- for (i=0; i<ndbg; i++) {
- if (__copy_from_user(&op, dbg, sizeof(op)))
- return -EFAULT;
- switch (op.dbg_type) {
- case SIG_DBG_SINGLE_STEPPING:
-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
- if (op.dbg_value) {
- new_msr |= MSR_DE;
- new_dbcr0 |= (DBCR0_IDM | DBCR0_IC);
- } else {
- new_msr &= ~MSR_DE;
- new_dbcr0 &= ~(DBCR0_IDM | DBCR0_IC);
- }
-#else
- if (op.dbg_value)
- new_msr |= MSR_SE;
- else
- new_msr &= ~MSR_SE;
-#endif
- break;
- case SIG_DBG_BRANCH_TRACING:
-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
- return -EINVAL;
-#else
- if (op.dbg_value)
- new_msr |= MSR_BE;
- else
- new_msr &= ~MSR_BE;
-#endif
- break;
-
- default:
- return -EINVAL;
- }
- }
-
- /* We wait until here to actually install the values in the
- registers so if we fail in the above loop, it will not
- affect the contents of these registers. After this point,
- failure is a problem, anyway, and it's very unlikely unless
- the user is really doing something wrong. */
- regs->msr = new_msr;
-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
- current->thread.dbcr0 = new_dbcr0;
-#endif
-
- /*
- * If we get a fault copying the context into the kernel's
- * image of the user's registers, we can't just return -EFAULT
- * because the user's registers will be corrupted. For instance
- * the NIP value may have been updated but not some of the
- * other registers. Given that we have done the access_ok
- * and successfully read the first and last bytes of the region
- * above, this should only happen in an out-of-memory situation
- * or if another thread unmaps the region containing the context.
- * We kill the task with a SIGSEGV in this situation.
- */
- if (do_setcontext(ctx, regs, 1)) {
- force_sig(SIGSEGV, current);
- goto out;
- }
-
- /*
- * It's not clear whether or why it is desirable to save the
- * sigaltstack setting on signal delivery and restore it on
- * signal return. But other architectures do this and we have
- * always done it up until now so it is probably better not to
- * change it. -- paulus
- */
- do_sigaltstack(&ctx->uc_stack, NULL, regs->gpr[1]);
-
- sigreturn_exit(regs);
- /* doesn't actually return back to here */
-
- out:
- return 0;
-}
-
-/*
- * OK, we're invoking a handler
- */
-static void
-handle_signal(unsigned long sig, struct k_sigaction *ka,
- siginfo_t *info, sigset_t *oldset, struct pt_regs * regs,
- unsigned long newsp)
-{
- struct sigcontext __user *sc;
- struct sigregs __user *frame;
- unsigned long origsp = newsp;
-
- /* Set up Signal Frame */
- newsp -= sizeof(struct sigregs);
- frame = (struct sigregs __user *) newsp;
-
- /* Put a sigcontext on the stack */
- newsp -= sizeof(*sc);
- sc = (struct sigcontext __user *) newsp;
-
- /* create a stack frame for the caller of the handler */
- newsp -= __SIGNAL_FRAMESIZE;
-
- if (!access_ok(VERIFY_WRITE, (void __user *) newsp, origsp - newsp))
- goto badframe;
-
-#if _NSIG != 64
-#error "Please adjust handle_signal()"
-#endif
- if (__put_user((unsigned long) ka->sa.sa_handler, &sc->handler)
- || __put_user(oldset->sig[0], &sc->oldmask)
- || __put_user(oldset->sig[1], &sc->_unused[3])
- || __put_user((struct pt_regs __user *)frame, &sc->regs)
- || __put_user(sig, &sc->signal))
- goto badframe;
-
- if (save_user_regs(regs, &frame->mctx, __NR_sigreturn))
- goto badframe;
-
- if (put_user(regs->gpr[1], (unsigned long __user *)newsp))
- goto badframe;
- regs->gpr[1] = newsp;
- regs->gpr[3] = sig;
- regs->gpr[4] = (unsigned long) sc;
- regs->nip = (unsigned long) ka->sa.sa_handler;
- regs->link = (unsigned long) frame->mctx.tramp;
- regs->trap = 0;
-
- return;
-
-badframe:
-#ifdef DEBUG_SIG
- printk("badframe in handle_signal, regs=%p frame=%p newsp=%lx\n",
- regs, frame, newsp);
-#endif
- force_sigsegv(sig, current);
-}
-
-/*
- * Do a signal return; undo the signal stack.
- */
-int sys_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
- struct pt_regs *regs)
-{
- struct sigcontext __user *sc;
- struct sigcontext sigctx;
- struct mcontext __user *sr;
- sigset_t set;
-
- /* Always make any pending restarted system calls return -EINTR */
- current_thread_info()->restart_block.fn = do_no_restart_syscall;
-
- sc = (struct sigcontext __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
- if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
- goto badframe;
-
- set.sig[0] = sigctx.oldmask;
- set.sig[1] = sigctx._unused[3];
- restore_sigmask(&set);
-
- sr = (struct mcontext __user *) sigctx.regs;
- if (!access_ok(VERIFY_READ, sr, sizeof(*sr))
- || restore_user_regs(regs, sr, 1))
- goto badframe;
-
- sigreturn_exit(regs); /* doesn't return */
- return 0;
-
-badframe:
- force_sig(SIGSEGV, current);
- return 0;
-}
-
-/*
- * Note that 'init' is a special process: it doesn't get signals it doesn't
- * want to handle. Thus you cannot kill init even with a SIGKILL even by
- * mistake.
- */
-int do_signal(sigset_t *oldset, struct pt_regs *regs)
-{
- siginfo_t info;
- struct k_sigaction ka;
- unsigned long frame, newsp;
- int signr, ret;
-
- if (try_to_freeze()) {
- signr = 0;
- if (!signal_pending(current))
- goto no_signal;
- }
-
- if (!oldset)
- oldset = &current->blocked;
-
- newsp = frame = 0;
-
- signr = get_signal_to_deliver(&info, &ka, regs, NULL);
- no_signal:
- if (TRAP(regs) == 0x0C00 /* System Call! */
- && regs->ccr & 0x10000000 /* error signalled */
- && ((ret = regs->gpr[3]) == ERESTARTSYS
- || ret == ERESTARTNOHAND || ret == ERESTARTNOINTR
- || ret == ERESTART_RESTARTBLOCK)) {
-
- if (signr > 0
- && (ret == ERESTARTNOHAND || ret == ERESTART_RESTARTBLOCK
- || (ret == ERESTARTSYS
- && !(ka.sa.sa_flags & SA_RESTART)))) {
- /* make the system call return an EINTR error */
- regs->result = -EINTR;
- regs->gpr[3] = EINTR;
- /* note that the cr0.SO bit is already set */
- } else {
- regs->nip -= 4; /* Back up & retry system call */
- regs->result = 0;
- regs->trap = 0;
- if (ret == ERESTART_RESTARTBLOCK)
- regs->gpr[0] = __NR_restart_syscall;
- else
- regs->gpr[3] = regs->orig_gpr3;
- }
- }
-
- if (signr == 0)
- return 0; /* no signals delivered */
-
- if ((ka.sa.sa_flags & SA_ONSTACK) && current->sas_ss_size
- && !on_sig_stack(regs->gpr[1]))
- newsp = current->sas_ss_sp + current->sas_ss_size;
- else
- newsp = regs->gpr[1];
- newsp &= ~0xfUL;
-
- /* Whee! Actually deliver the signal. */
- if (ka.sa.sa_flags & SA_SIGINFO)
- handle_rt_signal(signr, &ka, &info, oldset, regs, newsp);
- else
- handle_signal(signr, &ka, &info, oldset, regs, newsp);
-
- spin_lock_irq(&current->sighand->siglock);
- sigorsets(&current->blocked,&current->blocked,&ka.sa.sa_mask);
- if (!(ka.sa.sa_flags & SA_NODEFER))
- sigaddset(&current->blocked, signr);
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
-
- return 1;
-}
-
diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c
index 726fe7ce1747..bc5bf1124836 100644
--- a/arch/ppc/kernel/smp.c
+++ b/arch/ppc/kernel/smp.c
@@ -34,11 +34,11 @@
#include <asm/thread_info.h>
#include <asm/tlbflush.h>
#include <asm/xmon.h>
+#include <asm/machdep.h>
volatile int smp_commenced;
int smp_tb_synchronized;
struct cpuinfo_PPC cpu_data[NR_CPUS];
-struct klock_info_struct klock_info = { KLOCK_CLEAR, 0 };
atomic_t ipi_recv;
atomic_t ipi_sent;
cpumask_t cpu_online_map;
@@ -51,7 +51,7 @@ EXPORT_SYMBOL(cpu_online_map);
EXPORT_SYMBOL(cpu_possible_map);
/* SMP operations for this machine */
-static struct smp_ops_t *smp_ops;
+struct smp_ops_t *smp_ops;
/* all cpu mappings are 1-1 -- Cort */
volatile unsigned long cpu_callin_map[NR_CPUS];
@@ -74,11 +74,11 @@ extern void __save_cpu_setup(void);
#define PPC_MSG_XMON_BREAK 3
static inline void
-smp_message_pass(int target, int msg, unsigned long data, int wait)
+smp_message_pass(int target, int msg)
{
- if (smp_ops){
+ if (smp_ops) {
atomic_inc(&ipi_sent);
- smp_ops->message_pass(target,msg,data,wait);
+ smp_ops->message_pass(target, msg);
}
}
@@ -119,7 +119,7 @@ void smp_message_recv(int msg, struct pt_regs *regs)
void smp_send_tlb_invalidate(int cpu)
{
if ( PVR_VER(mfspr(SPRN_PVR)) == 8 )
- smp_message_pass(MSG_ALL_BUT_SELF, PPC_MSG_INVALIDATE_TLB, 0, 0);
+ smp_message_pass(MSG_ALL_BUT_SELF, PPC_MSG_INVALIDATE_TLB);
}
void smp_send_reschedule(int cpu)
@@ -135,13 +135,13 @@ void smp_send_reschedule(int cpu)
*/
/* This is only used if `cpu' is running an idle task,
so it will reschedule itself anyway... */
- smp_message_pass(cpu, PPC_MSG_RESCHEDULE, 0, 0);
+ smp_message_pass(cpu, PPC_MSG_RESCHEDULE);
}
#ifdef CONFIG_XMON
void smp_send_xmon_break(int cpu)
{
- smp_message_pass(cpu, PPC_MSG_XMON_BREAK, 0, 0);
+ smp_message_pass(cpu, PPC_MSG_XMON_BREAK);
}
#endif /* CONFIG_XMON */
@@ -224,7 +224,7 @@ static int __smp_call_function(void (*func) (void *info), void *info,
spin_lock(&call_lock);
call_data = &data;
/* Send a message to all other CPUs and wait for them to respond */
- smp_message_pass(target, PPC_MSG_CALL_FUNCTION, 0, 0);
+ smp_message_pass(target, PPC_MSG_CALL_FUNCTION);
/* Wait for response */
timeout = 1000000;
@@ -294,7 +294,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
smp_store_cpu_info(smp_processor_id());
cpu_callin_map[smp_processor_id()] = 1;
- smp_ops = ppc_md.smp_ops;
if (smp_ops == NULL) {
printk("SMP not supported on this machine.\n");
return;
@@ -308,9 +307,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
/* Backup CPU 0 state */
__save_cpu_setup();
- if (smp_ops->space_timers)
- smp_ops->space_timers(num_cpus);
-
for_each_cpu(cpu) {
if (cpu == smp_processor_id())
continue;
diff --git a/arch/ppc/kernel/syscalls.c b/arch/ppc/kernel/syscalls.c
deleted file mode 100644
index 127f040de9de..000000000000
--- a/arch/ppc/kernel/syscalls.c
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * arch/ppc/kernel/sys_ppc.c
- *
- * PowerPC version
- * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
- *
- * Derived from "arch/i386/kernel/sys_i386.c"
- * Adapted from the i386 version by Gary Thomas
- * Modified by Cort Dougan (cort@cs.nmt.edu)
- * and Paul Mackerras (paulus@cs.anu.edu.au).
- *
- * This file contains various random system calls that
- * have a non-standard calling sequence on the Linux/PPC
- * platform.
- *
- * This program is free software; you can redistribute 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 <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/sem.h>
-#include <linux/msg.h>
-#include <linux/shm.h>
-#include <linux/stat.h>
-#include <linux/syscalls.h>
-#include <linux/mman.h>
-#include <linux/sys.h>
-#include <linux/ipc.h>
-#include <linux/utsname.h>
-#include <linux/file.h>
-#include <linux/unistd.h>
-
-#include <asm/uaccess.h>
-#include <asm/ipc.h>
-#include <asm/semaphore.h>
-
-
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-int
-sys_ipc (uint call, int first, int second, int third, void __user *ptr, long fifth)
-{
- int version, ret;
-
- version = call >> 16; /* hack for backward compatibility */
- call &= 0xffff;
-
- ret = -ENOSYS;
- switch (call) {
- case SEMOP:
- ret = sys_semtimedop (first, (struct sembuf __user *)ptr,
- second, NULL);
- break;
- case SEMTIMEDOP:
- ret = sys_semtimedop (first, (struct sembuf __user *)ptr,
- second, (const struct timespec __user *) fifth);
- break;
- case SEMGET:
- ret = sys_semget (first, second, third);
- break;
- case SEMCTL: {
- union semun fourth;
-
- if (!ptr)
- break;
- if ((ret = access_ok(VERIFY_READ, ptr, sizeof(long)) ? 0 : -EFAULT)
- || (ret = get_user(fourth.__pad, (void __user *__user *)ptr)))
- break;
- ret = sys_semctl (first, second, third, fourth);
- break;
- }
- case MSGSND:
- ret = sys_msgsnd (first, (struct msgbuf __user *) ptr, second, third);
- break;
- case MSGRCV:
- switch (version) {
- case 0: {
- struct ipc_kludge tmp;
-
- if (!ptr)
- break;
- if ((ret = access_ok(VERIFY_READ, ptr, sizeof(tmp)) ? 0 : -EFAULT)
- || (ret = copy_from_user(&tmp,
- (struct ipc_kludge __user *) ptr,
- sizeof (tmp)) ? -EFAULT : 0))
- break;
- ret = sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp,
- third);
- break;
- }
- default:
- ret = sys_msgrcv (first, (struct msgbuf __user *) ptr,
- second, fifth, third);
- break;
- }
- break;
- case MSGGET:
- ret = sys_msgget ((key_t) first, second);
- break;
- case MSGCTL:
- ret = sys_msgctl (first, second, (struct msqid_ds __user *) ptr);
- break;
- case SHMAT: {
- ulong raddr;
-
- if ((ret = access_ok(VERIFY_WRITE, (ulong __user *) third,
- sizeof(ulong)) ? 0 : -EFAULT))
- break;
- ret = do_shmat (first, (char __user *) ptr, second, &raddr);
- if (ret)
- break;
- ret = put_user (raddr, (ulong __user *) third);
- break;
- }
- case SHMDT:
- ret = sys_shmdt ((char __user *)ptr);
- break;
- case SHMGET:
- ret = sys_shmget (first, second, third);
- break;
- case SHMCTL:
- ret = sys_shmctl (first, second, (struct shmid_ds __user *) ptr);
- break;
- }
-
- return ret;
-}
-
-/*
- * sys_pipe() is the normal C calling standard for creating
- * a pipe. It's not the way unix traditionally does this, though.
- */
-int sys_pipe(int __user *fildes)
-{
- int fd[2];
- int error;
-
- error = do_pipe(fd);
- if (!error) {
- if (copy_to_user(fildes, fd, 2*sizeof(int)))
- error = -EFAULT;
- }
- return error;
-}
-
-static inline unsigned long
-do_mmap2(unsigned long addr, size_t len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, unsigned long pgoff)
-{
- struct file * file = NULL;
- int ret = -EBADF;
-
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- if (!(flags & MAP_ANONYMOUS)) {
- if (!(file = fget(fd)))
- goto out;
- }
-
- down_write(&current->mm->mmap_sem);
- ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
- up_write(&current->mm->mmap_sem);
- if (file)
- fput(file);
-out:
- return ret;
-}
-
-unsigned long sys_mmap2(unsigned long addr, size_t len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, unsigned long pgoff)
-{
- return do_mmap2(addr, len, prot, flags, fd, pgoff);
-}
-
-unsigned long sys_mmap(unsigned long addr, size_t len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, off_t offset)
-{
- int err = -EINVAL;
-
- if (offset & ~PAGE_MASK)
- goto out;
-
- err = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
-out:
- return err;
-}
-
-/*
- * Due to some executables calling the wrong select we sometimes
- * get wrong args. This determines how the args are being passed
- * (a single ptr to them all args passed) then calls
- * sys_select() with the appropriate args. -- Cort
- */
-int
-ppc_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, struct timeval __user *tvp)
-{
- if ( (unsigned long)n >= 4096 )
- {
- unsigned long __user *buffer = (unsigned long __user *)n;
- if (!access_ok(VERIFY_READ, buffer, 5*sizeof(unsigned long))
- || __get_user(n, buffer)
- || __get_user(inp, ((fd_set __user * __user *)(buffer+1)))
- || __get_user(outp, ((fd_set __user * __user *)(buffer+2)))
- || __get_user(exp, ((fd_set __user * __user *)(buffer+3)))
- || __get_user(tvp, ((struct timeval __user * __user *)(buffer+4))))
- return -EFAULT;
- }
- return sys_select(n, inp, outp, exp, tvp);
-}
-
-int sys_uname(struct old_utsname __user * name)
-{
- int err = -EFAULT;
-
- down_read(&uts_sem);
- if (name && !copy_to_user(name, &system_utsname, sizeof (*name)))
- err = 0;
- up_read(&uts_sem);
- return err;
-}
-
-int sys_olduname(struct oldold_utsname __user * name)
-{
- int error;
-
- if (!name)
- return -EFAULT;
- if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
- return -EFAULT;
-
- down_read(&uts_sem);
- error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
- error -= __put_user(0,name->sysname+__OLD_UTS_LEN);
- error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
- error -= __put_user(0,name->nodename+__OLD_UTS_LEN);
- error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
- error -= __put_user(0,name->release+__OLD_UTS_LEN);
- error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
- error -= __put_user(0,name->version+__OLD_UTS_LEN);
- error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
- error = __put_user(0,name->machine+__OLD_UTS_LEN);
- up_read(&uts_sem);
-
- error = error ? -EFAULT : 0;
- return error;
-}
-
-/*
- * We put the arguments in a different order so we only use 6
- * registers for arguments, rather than 7 as sys_fadvise64_64 needs
- * (because `offset' goes in r5/r6).
- */
-long ppc_fadvise64_64(int fd, int advice, loff_t offset, loff_t len)
-{
- return sys_fadvise64_64(fd, offset, len, advice);
-}
diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c
index 22d7fd1e0aea..53ea723af60a 100644
--- a/arch/ppc/kernel/time.c
+++ b/arch/ppc/kernel/time.c
@@ -66,11 +66,6 @@
#include <asm/time.h>
-/* XXX false sharing with below? */
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
unsigned long disarm_decr[NR_CPUS];
extern struct timezone sys_tz;
@@ -121,6 +116,15 @@ unsigned long profile_pc(struct pt_regs *regs)
EXPORT_SYMBOL(profile_pc);
#endif
+void wakeup_decrementer(void)
+{
+ set_dec(tb_ticks_per_jiffy);
+ /* No currently-supported powerbook has a 601,
+ * so use get_tbl, not native
+ */
+ last_jiffy_stamp(0) = tb_last_stamp = get_tbl();
+}
+
/*
* timer_interrupt - gets called when the decrementer overflows,
* with interrupts disabled.
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
index 961ede87be72..f265b81e7008 100644
--- a/arch/ppc/kernel/traps.c
+++ b/arch/ppc/kernel/traps.c
@@ -41,9 +41,14 @@
#ifdef CONFIG_PMAC_BACKLIGHT
#include <asm/backlight.h>
#endif
-#include <asm/perfmon.h>
+#include <asm/pmc.h>
#ifdef CONFIG_XMON
+extern int xmon_bpt(struct pt_regs *regs);
+extern int xmon_sstep(struct pt_regs *regs);
+extern int xmon_iabr_match(struct pt_regs *regs);
+extern int xmon_dabr_match(struct pt_regs *regs);
+
void (*debugger)(struct pt_regs *regs) = xmon;
int (*debugger_bpt)(struct pt_regs *regs) = xmon_bpt;
int (*debugger_sstep)(struct pt_regs *regs) = xmon_sstep;
@@ -74,7 +79,7 @@ void (*debugger_fault_handler)(struct pt_regs *regs);
DEFINE_SPINLOCK(die_lock);
-void die(const char * str, struct pt_regs * fp, long err)
+int die(const char * str, struct pt_regs * fp, long err)
{
static int die_counter;
int nl = 0;
@@ -232,7 +237,7 @@ platform_machine_check(struct pt_regs *regs)
{
}
-void MachineCheckException(struct pt_regs *regs)
+void machine_check_exception(struct pt_regs *regs)
{
unsigned long reason = get_mc_reason(regs);
@@ -393,14 +398,14 @@ void SMIException(struct pt_regs *regs)
#endif
}
-void UnknownException(struct pt_regs *regs)
+void unknown_exception(struct pt_regs *regs)
{
printk("Bad trap at PC: %lx, MSR: %lx, vector=%lx %s\n",
regs->nip, regs->msr, regs->trap, print_tainted());
_exception(SIGTRAP, regs, 0, 0);
}
-void InstructionBreakpoint(struct pt_regs *regs)
+void instruction_breakpoint_exception(struct pt_regs *regs)
{
if (debugger_iabr_match(regs))
return;
@@ -575,7 +580,7 @@ extern struct bug_entry __start___bug_table[], __stop___bug_table[];
#define module_find_bug(x) NULL
#endif
-static struct bug_entry *find_bug(unsigned long bugaddr)
+struct bug_entry *find_bug(unsigned long bugaddr)
{
struct bug_entry *bug;
@@ -622,7 +627,7 @@ int check_bug_trap(struct pt_regs *regs)
return 0;
}
-void ProgramCheckException(struct pt_regs *regs)
+void program_check_exception(struct pt_regs *regs)
{
unsigned int reason = get_reason(regs);
extern int do_mathemu(struct pt_regs *regs);
@@ -654,7 +659,7 @@ void ProgramCheckException(struct pt_regs *regs)
giveup_fpu(current);
preempt_enable();
- fpscr = current->thread.fpscr;
+ fpscr = current->thread.fpscr.val;
fpscr &= fpscr << 22; /* mask summary bits with enables */
if (fpscr & FPSCR_VX)
code = FPE_FLTINV;
@@ -701,7 +706,7 @@ void ProgramCheckException(struct pt_regs *regs)
_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
}
-void SingleStepException(struct pt_regs *regs)
+void single_step_exception(struct pt_regs *regs)
{
regs->msr &= ~(MSR_SE | MSR_BE); /* Turn off 'trace' bits */
if (debugger_sstep(regs))
@@ -709,7 +714,7 @@ void SingleStepException(struct pt_regs *regs)
_exception(SIGTRAP, regs, TRAP_TRACE, 0);
}
-void AlignmentException(struct pt_regs *regs)
+void alignment_exception(struct pt_regs *regs)
{
int fixed;
@@ -814,7 +819,18 @@ void TAUException(struct pt_regs *regs)
}
#endif /* CONFIG_INT_TAU */
-void AltivecUnavailException(struct pt_regs *regs)
+/*
+ * FP unavailable trap from kernel - print a message, but let
+ * the task use FP in the kernel until it returns to user mode.
+ */
+void kernel_fp_unavailable_exception(struct pt_regs *regs)
+{
+ regs->msr |= MSR_FP;
+ printk(KERN_ERR "floating point used in kernel (task=%p, pc=%lx)\n",
+ current, regs->nip);
+}
+
+void altivec_unavailable_exception(struct pt_regs *regs)
{
static int kernel_altivec_count;
@@ -835,7 +851,7 @@ void AltivecUnavailException(struct pt_regs *regs)
}
#ifdef CONFIG_ALTIVEC
-void AltivecAssistException(struct pt_regs *regs)
+void altivec_assist_exception(struct pt_regs *regs)
{
int err;
@@ -872,7 +888,7 @@ void AltivecAssistException(struct pt_regs *regs)
#endif /* CONFIG_ALTIVEC */
#ifdef CONFIG_E500
-void PerformanceMonitorException(struct pt_regs *regs)
+void performance_monitor_exception(struct pt_regs *regs)
{
perf_irq(regs);
}
diff --git a/arch/ppc/kernel/vector.S b/arch/ppc/kernel/vector.S
deleted file mode 100644
index 82a21346bf80..000000000000
--- a/arch/ppc/kernel/vector.S
+++ /dev/null
@@ -1,217 +0,0 @@
-#include <asm/ppc_asm.h>
-#include <asm/processor.h>
-
-/*
- * The routines below are in assembler so we can closely control the
- * usage of floating-point registers. These routines must be called
- * with preempt disabled.
- */
- .data
-fpzero:
- .long 0
-fpone:
- .long 0x3f800000 /* 1.0 in single-precision FP */
-fphalf:
- .long 0x3f000000 /* 0.5 in single-precision FP */
-
- .text
-/*
- * Internal routine to enable floating point and set FPSCR to 0.
- * Don't call it from C; it doesn't use the normal calling convention.
- */
-fpenable:
- mfmsr r10
- ori r11,r10,MSR_FP
- mtmsr r11
- isync
- stfd fr0,24(r1)
- stfd fr1,16(r1)
- stfd fr31,8(r1)
- lis r11,fpzero@ha
- mffs fr31
- lfs fr1,fpzero@l(r11)
- mtfsf 0xff,fr1
- blr
-
-fpdisable:
- mtfsf 0xff,fr31
- lfd fr31,8(r1)
- lfd fr1,16(r1)
- lfd fr0,24(r1)
- mtmsr r10
- isync
- blr
-
-/*
- * Vector add, floating point.
- */
- .globl vaddfp
-vaddfp:
- stwu r1,-32(r1)
- mflr r0
- stw r0,36(r1)
- bl fpenable
- li r0,4
- mtctr r0
- li r6,0
-1: lfsx fr0,r4,r6
- lfsx fr1,r5,r6
- fadds fr0,fr0,fr1
- stfsx fr0,r3,r6
- addi r6,r6,4
- bdnz 1b
- bl fpdisable
- lwz r0,36(r1)
- mtlr r0
- addi r1,r1,32
- blr
-
-/*
- * Vector subtract, floating point.
- */
- .globl vsubfp
-vsubfp:
- stwu r1,-32(r1)
- mflr r0
- stw r0,36(r1)
- bl fpenable
- li r0,4
- mtctr r0
- li r6,0
-1: lfsx fr0,r4,r6
- lfsx fr1,r5,r6
- fsubs fr0,fr0,fr1
- stfsx fr0,r3,r6
- addi r6,r6,4
- bdnz 1b
- bl fpdisable
- lwz r0,36(r1)
- mtlr r0
- addi r1,r1,32
- blr
-
-/*
- * Vector multiply and add, floating point.
- */
- .globl vmaddfp
-vmaddfp:
- stwu r1,-48(r1)
- mflr r0
- stw r0,52(r1)
- bl fpenable
- stfd fr2,32(r1)
- li r0,4
- mtctr r0
- li r7,0
-1: lfsx fr0,r4,r7
- lfsx fr1,r5,r7
- lfsx fr2,r6,r7
- fmadds fr0,fr0,fr2,fr1
- stfsx fr0,r3,r7
- addi r7,r7,4
- bdnz 1b
- lfd fr2,32(r1)
- bl fpdisable
- lwz r0,52(r1)
- mtlr r0
- addi r1,r1,48
- blr
-
-/*
- * Vector negative multiply and subtract, floating point.
- */
- .globl vnmsubfp
-vnmsubfp:
- stwu r1,-48(r1)
- mflr r0
- stw r0,52(r1)
- bl fpenable
- stfd fr2,32(r1)
- li r0,4
- mtctr r0
- li r7,0
-1: lfsx fr0,r4,r7
- lfsx fr1,r5,r7
- lfsx fr2,r6,r7
- fnmsubs fr0,fr0,fr2,fr1
- stfsx fr0,r3,r7
- addi r7,r7,4
- bdnz 1b
- lfd fr2,32(r1)
- bl fpdisable
- lwz r0,52(r1)
- mtlr r0
- addi r1,r1,48
- blr
-
-/*
- * Vector reciprocal estimate. We just compute 1.0/x.
- * r3 -> destination, r4 -> source.
- */
- .globl vrefp
-vrefp:
- stwu r1,-32(r1)
- mflr r0
- stw r0,36(r1)
- bl fpenable
- lis r9,fpone@ha
- li r0,4
- lfs fr1,fpone@l(r9)
- mtctr r0
- li r6,0
-1: lfsx fr0,r4,r6
- fdivs fr0,fr1,fr0
- stfsx fr0,r3,r6
- addi r6,r6,4
- bdnz 1b
- bl fpdisable
- lwz r0,36(r1)
- mtlr r0
- addi r1,r1,32
- blr
-
-/*
- * Vector reciprocal square-root estimate, floating point.
- * We use the frsqrte instruction for the initial estimate followed
- * by 2 iterations of Newton-Raphson to get sufficient accuracy.
- * r3 -> destination, r4 -> source.
- */
- .globl vrsqrtefp
-vrsqrtefp:
- stwu r1,-48(r1)
- mflr r0
- stw r0,52(r1)
- bl fpenable
- stfd fr2,32(r1)
- stfd fr3,40(r1)
- stfd fr4,48(r1)
- stfd fr5,56(r1)
- lis r9,fpone@ha
- lis r8,fphalf@ha
- li r0,4
- lfs fr4,fpone@l(r9)
- lfs fr5,fphalf@l(r8)
- mtctr r0
- li r6,0
-1: lfsx fr0,r4,r6
- frsqrte fr1,fr0 /* r = frsqrte(s) */
- fmuls fr3,fr1,fr0 /* r * s */
- fmuls fr2,fr1,fr5 /* r * 0.5 */
- fnmsubs fr3,fr1,fr3,fr4 /* 1 - s * r * r */
- fmadds fr1,fr2,fr3,fr1 /* r = r + 0.5 * r * (1 - s * r * r) */
- fmuls fr3,fr1,fr0 /* r * s */
- fmuls fr2,fr1,fr5 /* r * 0.5 */
- fnmsubs fr3,fr1,fr3,fr4 /* 1 - s * r * r */
- fmadds fr1,fr2,fr3,fr1 /* r = r + 0.5 * r * (1 - s * r * r) */
- stfsx fr1,r3,r6
- addi r6,r6,4
- bdnz 1b
- lfd fr5,56(r1)
- lfd fr4,48(r1)
- lfd fr3,40(r1)
- lfd fr2,32(r1)
- bl fpdisable
- lwz r0,36(r1)
- mtlr r0
- addi r1,r1,32
- blr
diff --git a/arch/ppc/kernel/vmlinux.lds.S b/arch/ppc/kernel/vmlinux.lds.S
index 17d2db7e537d..09c6525cfa61 100644
--- a/arch/ppc/kernel/vmlinux.lds.S
+++ b/arch/ppc/kernel/vmlinux.lds.S
@@ -149,32 +149,6 @@ SECTIONS
. = ALIGN(4096);
_sextratext = .;
- __pmac_begin = .;
- .pmac.text : { *(.pmac.text) }
- .pmac.data : { *(.pmac.data) }
- . = ALIGN(4096);
- __pmac_end = .;
-
- . = ALIGN(4096);
- __prep_begin = .;
- .prep.text : { *(.prep.text) }
- .prep.data : { *(.prep.data) }
- . = ALIGN(4096);
- __prep_end = .;
-
- . = ALIGN(4096);
- __chrp_begin = .;
- .chrp.text : { *(.chrp.text) }
- .chrp.data : { *(.chrp.data) }
- . = ALIGN(4096);
- __chrp_end = .;
-
- . = ALIGN(4096);
- __openfirmware_begin = .;
- .openfirmware.text : { *(.openfirmware.text) }
- .openfirmware.data : { *(.openfirmware.data) }
- . = ALIGN(4096);
- __openfirmware_end = .;
_eextratext = .;
__bss_start = .;
diff --git a/arch/ppc/lib/string.S b/arch/ppc/lib/string.S
index 36c9b97fd92a..2e258c49e8be 100644
--- a/arch/ppc/lib/string.S
+++ b/arch/ppc/lib/string.S
@@ -65,9 +65,9 @@
.stabs "arch/ppc/lib/",N_SO,0,0,0f
.stabs "string.S",N_SO,0,0,0f
-CACHELINE_BYTES = L1_CACHE_LINE_SIZE
-LG_CACHELINE_BYTES = LG_L1_CACHE_LINE_SIZE
-CACHELINE_MASK = (L1_CACHE_LINE_SIZE-1)
+CACHELINE_BYTES = L1_CACHE_BYTES
+LG_CACHELINE_BYTES = L1_CACHE_SHIFT
+CACHELINE_MASK = (L1_CACHE_BYTES-1)
_GLOBAL(strcpy)
addi r5,r3,-1
@@ -265,12 +265,12 @@ _GLOBAL(cacheable_memcpy)
dcbz r11,r6
#endif
COPY_16_BYTES
-#if L1_CACHE_LINE_SIZE >= 32
+#if L1_CACHE_BYTES >= 32
COPY_16_BYTES
-#if L1_CACHE_LINE_SIZE >= 64
+#if L1_CACHE_BYTES >= 64
COPY_16_BYTES
COPY_16_BYTES
-#if L1_CACHE_LINE_SIZE >= 128
+#if L1_CACHE_BYTES >= 128
COPY_16_BYTES
COPY_16_BYTES
COPY_16_BYTES
@@ -485,12 +485,12 @@ _GLOBAL(__copy_tofrom_user)
.text
/* the main body of the cacheline loop */
COPY_16_BYTES_WITHEX(0)
-#if L1_CACHE_LINE_SIZE >= 32
+#if L1_CACHE_BYTES >= 32
COPY_16_BYTES_WITHEX(1)
-#if L1_CACHE_LINE_SIZE >= 64
+#if L1_CACHE_BYTES >= 64
COPY_16_BYTES_WITHEX(2)
COPY_16_BYTES_WITHEX(3)
-#if L1_CACHE_LINE_SIZE >= 128
+#if L1_CACHE_BYTES >= 128
COPY_16_BYTES_WITHEX(4)
COPY_16_BYTES_WITHEX(5)
COPY_16_BYTES_WITHEX(6)
@@ -544,12 +544,12 @@ _GLOBAL(__copy_tofrom_user)
* 104f (if in read part) or 105f (if in write part), after updating r5
*/
COPY_16_BYTES_EXCODE(0)
-#if L1_CACHE_LINE_SIZE >= 32
+#if L1_CACHE_BYTES >= 32
COPY_16_BYTES_EXCODE(1)
-#if L1_CACHE_LINE_SIZE >= 64
+#if L1_CACHE_BYTES >= 64
COPY_16_BYTES_EXCODE(2)
COPY_16_BYTES_EXCODE(3)
-#if L1_CACHE_LINE_SIZE >= 128
+#if L1_CACHE_BYTES >= 128
COPY_16_BYTES_EXCODE(4)
COPY_16_BYTES_EXCODE(5)
COPY_16_BYTES_EXCODE(6)
diff --git a/arch/ppc/math-emu/sfp-machine.h b/arch/ppc/math-emu/sfp-machine.h
index 686e06d29186..4b17d83cfcdd 100644
--- a/arch/ppc/math-emu/sfp-machine.h
+++ b/arch/ppc/math-emu/sfp-machine.h
@@ -166,7 +166,7 @@ extern int fp_pack_ds(void *, long, unsigned long, unsigned long, long, long);
#include <linux/kernel.h>
#include <linux/sched.h>
-#define __FPU_FPSCR (current->thread.fpscr)
+#define __FPU_FPSCR (current->thread.fpscr.val)
/* We only actually write to the destination register
* if exceptions signalled (if any) will not trap.
diff --git a/arch/ppc/mm/4xx_mmu.c b/arch/ppc/mm/4xx_mmu.c
index b7bcbc232f39..4d006aa1a0d1 100644
--- a/arch/ppc/mm/4xx_mmu.c
+++ b/arch/ppc/mm/4xx_mmu.c
@@ -110,13 +110,11 @@ unsigned long __init mmu_mapin_ram(void)
pmd_t *pmdp;
unsigned long val = p | _PMD_SIZE_16M | _PAGE_HWEXEC | _PAGE_HWWRITE;
- spin_lock(&init_mm.page_table_lock);
pmdp = pmd_offset(pgd_offset_k(v), v);
pmd_val(*pmdp++) = val;
pmd_val(*pmdp++) = val;
pmd_val(*pmdp++) = val;
pmd_val(*pmdp++) = val;
- spin_unlock(&init_mm.page_table_lock);
v += LARGE_PAGE_SIZE_16M;
p += LARGE_PAGE_SIZE_16M;
@@ -127,10 +125,8 @@ unsigned long __init mmu_mapin_ram(void)
pmd_t *pmdp;
unsigned long val = p | _PMD_SIZE_4M | _PAGE_HWEXEC | _PAGE_HWWRITE;
- spin_lock(&init_mm.page_table_lock);
pmdp = pmd_offset(pgd_offset_k(v), v);
pmd_val(*pmdp) = val;
- spin_unlock(&init_mm.page_table_lock);
v += LARGE_PAGE_SIZE_4M;
p += LARGE_PAGE_SIZE_4M;
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
index f421a4b337f6..99b48abd3296 100644
--- a/arch/ppc/mm/init.c
+++ b/arch/ppc/mm/init.c
@@ -69,15 +69,12 @@ int init_bootmem_done;
int boot_mapsize;
#ifdef CONFIG_PPC_PMAC
unsigned long agp_special_page;
+EXPORT_SYMBOL(agp_special_page);
#endif
extern char _end[];
extern char etext[], _stext[];
extern char __init_begin, __init_end;
-extern char __prep_begin, __prep_end;
-extern char __chrp_begin, __chrp_end;
-extern char __pmac_begin, __pmac_end;
-extern char __openfirmware_begin, __openfirmware_end;
#ifdef CONFIG_HIGHMEM
pte_t *kmap_pte;
@@ -167,14 +164,6 @@ void free_initmem(void)
printk ("Freeing unused kernel memory:");
FREESEC(init);
- if (_machine != _MACH_Pmac)
- FREESEC(pmac);
- if (_machine != _MACH_chrp)
- FREESEC(chrp);
- if (_machine != _MACH_prep)
- FREESEC(prep);
- if (!have_of)
- FREESEC(openfirmware);
printk("\n");
ppc_md.progress = NULL;
#undef FREESEC
@@ -648,18 +637,16 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
*/
int page_is_ram(unsigned long pfn)
{
- unsigned long paddr = (pfn << PAGE_SHIFT);
-
- return paddr < __pa(high_memory);
+ return pfn < max_pfn;
}
-pgprot_t phys_mem_access_prot(struct file *file, unsigned long addr,
+pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
unsigned long size, pgprot_t vma_prot)
{
if (ppc_md.phys_mem_access_prot)
- return ppc_md.phys_mem_access_prot(file, addr, size, vma_prot);
+ return ppc_md.phys_mem_access_prot(file, pfn, size, vma_prot);
- if (!page_is_ram(addr >> PAGE_SHIFT))
+ if (!page_is_ram(pfn))
vma_prot = __pgprot(pgprot_val(vma_prot)
| _PAGE_GUARDED | _PAGE_NO_CACHE);
return vma_prot;
diff --git a/arch/ppc/mm/pgtable.c b/arch/ppc/mm/pgtable.c
index 43505b1fc5d8..6ea9185fd120 100644
--- a/arch/ppc/mm/pgtable.c
+++ b/arch/ppc/mm/pgtable.c
@@ -280,18 +280,16 @@ map_page(unsigned long va, phys_addr_t pa, int flags)
pte_t *pg;
int err = -ENOMEM;
- spin_lock(&init_mm.page_table_lock);
/* Use upper 10 bits of VA to index the first level map */
pd = pmd_offset(pgd_offset_k(va), va);
/* Use middle 10 bits of VA to index the second-level map */
- pg = pte_alloc_kernel(&init_mm, pd, va);
+ pg = pte_alloc_kernel(pd, va);
if (pg != 0) {
err = 0;
set_pte_at(&init_mm, va, pg, pfn_pte(pa >> PAGE_SHIFT, __pgprot(flags)));
if (mem_init_done)
flush_HPTE(0, va, pmd_val(*pd));
}
- spin_unlock(&init_mm.page_table_lock);
return err;
}
diff --git a/arch/ppc/oprofile/common.c b/arch/ppc/oprofile/common.c
deleted file mode 100644
index 3169c67abea7..000000000000
--- a/arch/ppc/oprofile/common.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * PPC 32 oprofile support
- * Based on PPC64 oprofile support
- * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
- *
- * Copyright (C) Freescale Semiconductor, Inc 2004
- *
- * Author: Andy Fleming
- *
- * This program is free software; you can redistribute 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/oprofile.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/smp.h>
-#include <linux/errno.h>
-#include <asm/ptrace.h>
-#include <asm/system.h>
-#include <asm/perfmon.h>
-#include <asm/cputable.h>
-
-#include "op_impl.h"
-
-static struct op_ppc32_model *model;
-
-static struct op_counter_config ctr[OP_MAX_COUNTER];
-static struct op_system_config sys;
-
-static void op_handle_interrupt(struct pt_regs *regs)
-{
- model->handle_interrupt(regs, ctr);
-}
-
-static int op_ppc32_setup(void)
-{
- /* Install our interrupt handler into the existing hook. */
- if(request_perfmon_irq(&op_handle_interrupt))
- return -EBUSY;
-
- mb();
-
- /* Pre-compute the values to stuff in the hardware registers. */
- model->reg_setup(ctr, &sys, model->num_counters);
-
-#if 0
- /* FIXME: Make multi-cpu work */
- /* Configure the registers on all cpus. */
- on_each_cpu(model->reg_setup, NULL, 0, 1);
-#endif
-
- return 0;
-}
-
-static void op_ppc32_shutdown(void)
-{
- mb();
-
- /* Remove our interrupt handler. We may be removing this module. */
- free_perfmon_irq();
-}
-
-static void op_ppc32_cpu_start(void *dummy)
-{
- model->start(ctr);
-}
-
-static int op_ppc32_start(void)
-{
- on_each_cpu(op_ppc32_cpu_start, NULL, 0, 1);
- return 0;
-}
-
-static inline void op_ppc32_cpu_stop(void *dummy)
-{
- model->stop();
-}
-
-static void op_ppc32_stop(void)
-{
- on_each_cpu(op_ppc32_cpu_stop, NULL, 0, 1);
-}
-
-static int op_ppc32_create_files(struct super_block *sb, struct dentry *root)
-{
- int i;
-
- for (i = 0; i < model->num_counters; ++i) {
- struct dentry *dir;
- char buf[3];
-
- snprintf(buf, sizeof buf, "%d", i);
- dir = oprofilefs_mkdir(sb, root, buf);
-
- oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
- oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
- oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
- oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
- oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
-
- /* FIXME: Not sure if this is used */
- oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
- }
-
- oprofilefs_create_ulong(sb, root, "enable_kernel", &sys.enable_kernel);
- oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user);
-
- /* Default to tracing both kernel and user */
- sys.enable_kernel = 1;
- sys.enable_user = 1;
-
- return 0;
-}
-
-static struct oprofile_operations oprof_ppc32_ops = {
- .create_files = op_ppc32_create_files,
- .setup = op_ppc32_setup,
- .shutdown = op_ppc32_shutdown,
- .start = op_ppc32_start,
- .stop = op_ppc32_stop,
- .cpu_type = NULL /* To be filled in below. */
-};
-
-int __init oprofile_arch_init(struct oprofile_operations *ops)
-{
- char *name;
- int cpu_id = smp_processor_id();
-
-#ifdef CONFIG_FSL_BOOKE
- model = &op_model_fsl_booke;
-#else
- return -ENODEV;
-#endif
-
- name = kmalloc(32, GFP_KERNEL);
-
- if (NULL == name)
- return -ENOMEM;
-
- sprintf(name, "ppc/%s", cur_cpu_spec[cpu_id]->cpu_name);
-
- oprof_ppc32_ops.cpu_type = name;
-
- model->num_counters = cur_cpu_spec[cpu_id]->num_pmcs;
-
- *ops = oprof_ppc32_ops;
-
- printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
- oprof_ppc32_ops.cpu_type);
-
- return 0;
-}
-
-void oprofile_arch_exit(void)
-{
- kfree(oprof_ppc32_ops.cpu_type);
- oprof_ppc32_ops.cpu_type = NULL;
-}
diff --git a/arch/ppc/oprofile/op_impl.h b/arch/ppc/oprofile/op_impl.h
deleted file mode 100644
index bc336dc971e3..000000000000
--- a/arch/ppc/oprofile/op_impl.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
- *
- * Based on alpha version.
- *
- * This program is free software; you can redistribute 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 OP_IMPL_H
-#define OP_IMPL_H 1
-
-#define OP_MAX_COUNTER 8
-
-/* Per-counter configuration as set via oprofilefs. */
-struct op_counter_config {
- unsigned long enabled;
- unsigned long event;
- unsigned long count;
- unsigned long kernel;
- unsigned long user;
- unsigned long unit_mask;
-};
-
-/* System-wide configuration as set via oprofilefs. */
-struct op_system_config {
- unsigned long enable_kernel;
- unsigned long enable_user;
-};
-
-/* Per-arch configuration */
-struct op_ppc32_model {
- void (*reg_setup) (struct op_counter_config *,
- struct op_system_config *,
- int num_counters);
- void (*start) (struct op_counter_config *);
- void (*stop) (void);
- void (*handle_interrupt) (struct pt_regs *,
- struct op_counter_config *);
- int num_counters;
-};
-
-#endif /* OP_IMPL_H */
diff --git a/arch/ppc/platforms/4xx/bamboo.c b/arch/ppc/platforms/4xx/bamboo.c
index 78a403b48dba..159b228eca1e 100644
--- a/arch/ppc/platforms/4xx/bamboo.c
+++ b/arch/ppc/platforms/4xx/bamboo.c
@@ -51,7 +51,7 @@
#include <syslib/gen550.h>
#include <syslib/ibm440gx_common.h>
-bd_t __res;
+extern bd_t __res;
static struct ibm44x_clocks clocks __initdata;
@@ -425,17 +425,7 @@ bamboo_setup_arch(void)
void __init platform_init(unsigned long r3, unsigned long r4,
unsigned long r5, unsigned long r6, unsigned long r7)
{
- parse_bootinfo(find_bootinfo());
-
- /*
- * If we were passed in a board information, copy it into the
- * residual data area.
- */
- if (r3)
- __res = *(bd_t *)(r3 + KERNELBASE);
-
-
- ibm44x_platform_init();
+ ibm44x_platform_init(r3, r4, r5, r6, r7);
ppc_md.setup_arch = bamboo_setup_arch;
ppc_md.show_cpuinfo = bamboo_show_cpuinfo;
diff --git a/arch/ppc/platforms/4xx/ebony.c b/arch/ppc/platforms/4xx/ebony.c
index 27b778ab903b..64ebae19cdbb 100644
--- a/arch/ppc/platforms/4xx/ebony.c
+++ b/arch/ppc/platforms/4xx/ebony.c
@@ -54,7 +54,7 @@
#include <syslib/gen550.h>
#include <syslib/ibm440gp_common.h>
-bd_t __res;
+extern bd_t __res;
static struct ibm44x_clocks clocks __initdata;
@@ -90,7 +90,7 @@ ebony_calibrate_decr(void)
* on Rev. C silicon then errata forces us to
* use the internal clock.
*/
- if (strcmp(cur_cpu_spec[0]->cpu_name, "440GP Rev. B") == 0)
+ if (strcmp(cur_cpu_spec->cpu_name, "440GP Rev. B") == 0)
freq = EBONY_440GP_RB_SYSCLK;
else
freq = EBONY_440GP_RC_SYSCLK;
@@ -317,16 +317,7 @@ ebony_setup_arch(void)
void __init platform_init(unsigned long r3, unsigned long r4,
unsigned long r5, unsigned long r6, unsigned long r7)
{
- parse_bootinfo(find_bootinfo());
-
- /*
- * If we were passed in a board information, copy it into the
- * residual data area.
- */
- if (r3)
- __res = *(bd_t *)(r3 + KERNELBASE);
-
- ibm44x_platform_init();
+ ibm44x_platform_init(r3, r4, r5, r6, r7);
ppc_md.setup_arch = ebony_setup_arch;
ppc_md.show_cpuinfo = ebony_show_cpuinfo;
diff --git a/arch/ppc/platforms/4xx/luan.c b/arch/ppc/platforms/4xx/luan.c
index 16d953bda22c..d810b736d9bf 100644
--- a/arch/ppc/platforms/4xx/luan.c
+++ b/arch/ppc/platforms/4xx/luan.c
@@ -52,7 +52,7 @@
#include <syslib/ibm440gx_common.h>
#include <syslib/ibm440sp_common.h>
-bd_t __res;
+extern bd_t __res;
static struct ibm44x_clocks clocks __initdata;
@@ -355,16 +355,7 @@ luan_setup_arch(void)
void __init platform_init(unsigned long r3, unsigned long r4,
unsigned long r5, unsigned long r6, unsigned long r7)
{
- parse_bootinfo(find_bootinfo());
-
- /*
- * If we were passed in a board information, copy it into the
- * residual data area.
- */
- if (r3)
- __res = *(bd_t *)(r3 + KERNELBASE);
-
- ibm44x_platform_init();
+ ibm44x_platform_init(r3, r4, r5, r6, r7);
ppc_md.setup_arch = luan_setup_arch;
ppc_md.show_cpuinfo = luan_show_cpuinfo;
diff --git a/arch/ppc/platforms/4xx/ocotea.c b/arch/ppc/platforms/4xx/ocotea.c
index 506949c5dd29..73b2c98158f6 100644
--- a/arch/ppc/platforms/4xx/ocotea.c
+++ b/arch/ppc/platforms/4xx/ocotea.c
@@ -52,7 +52,7 @@
#include <syslib/gen550.h>
#include <syslib/ibm440gx_common.h>
-bd_t __res;
+extern bd_t __res;
static struct ibm44x_clocks clocks __initdata;
@@ -286,6 +286,15 @@ ocotea_setup_arch(void)
ibm440gx_tah_enable();
+ /*
+ * Determine various clocks.
+ * To be completely correct we should get SysClk
+ * from FPGA, because it can be changed by on-board switches
+ * --ebs
+ */
+ ibm440gx_get_clocks(&clocks, 33333333, 6 * 1843200);
+ ocp_sys_info.opb_bus_freq = clocks.opb;
+
/* Setup TODC access */
TODC_INIT(TODC_TYPE_DS1743,
0,
@@ -324,25 +333,7 @@ static void __init ocotea_init(void)
void __init platform_init(unsigned long r3, unsigned long r4,
unsigned long r5, unsigned long r6, unsigned long r7)
{
- parse_bootinfo(find_bootinfo());
-
- /*
- * If we were passed in a board information, copy it into the
- * residual data area.
- */
- if (r3)
- __res = *(bd_t *)(r3 + KERNELBASE);
-
- /*
- * Determine various clocks.
- * To be completely correct we should get SysClk
- * from FPGA, because it can be changed by on-board switches
- * --ebs
- */
- ibm440gx_get_clocks(&clocks, 33333333, 6 * 1843200);
- ocp_sys_info.opb_bus_freq = clocks.opb;
-
- ibm44x_platform_init();
+ ibm44x_platform_init(r3, r4, r5, r6, r7);
ppc_md.setup_arch = ocotea_setup_arch;
ppc_md.show_cpuinfo = ocotea_show_cpuinfo;
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.h b/arch/ppc/platforms/83xx/mpc834x_sys.h
index 1584cd77a9ef..58e44c042535 100644
--- a/arch/ppc/platforms/83xx/mpc834x_sys.h
+++ b/arch/ppc/platforms/83xx/mpc834x_sys.h
@@ -19,7 +19,6 @@
#include <linux/config.h>
#include <linux/init.h>
-#include <linux/seq_file.h>
#include <syslib/ppc83xx_setup.h>
#include <asm/ppcboot.h>
diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c
index 7dc8a68acfd0..7e952c1228cb 100644
--- a/arch/ppc/platforms/85xx/mpc8540_ads.c
+++ b/arch/ppc/platforms/85xx/mpc8540_ads.c
@@ -52,6 +52,10 @@
#include <syslib/ppc85xx_setup.h>
+static const char *GFAR_PHY_0 = "phy0:0";
+static const char *GFAR_PHY_1 = "phy0:1";
+static const char *GFAR_PHY_3 = "phy0:3";
+
/* ************************************************************************
*
* Setup the architecture
@@ -63,6 +67,7 @@ mpc8540ads_setup_arch(void)
bd_t *binfo = (bd_t *) __res;
unsigned int freq;
struct gianfar_platform_data *pdata;
+ struct gianfar_mdio_data *mdata;
/* get the core frequency */
freq = binfo->bi_intfreq;
@@ -89,34 +94,35 @@ mpc8540ads_setup_arch(void)
invalidate_tlbcam_entry(num_tlbcam_entries - 1);
#endif
+ /* setup the board related info for the MDIO bus */
+ mdata = (struct gianfar_mdio_data *) ppc_sys_get_pdata(MPC85xx_MDIO);
+
+ mdata->irq[0] = MPC85xx_IRQ_EXT5;
+ mdata->irq[1] = MPC85xx_IRQ_EXT5;
+ mdata->irq[2] = -1;
+ mdata->irq[3] = MPC85xx_IRQ_EXT5;
+ mdata->irq[31] = -1;
+ mdata->paddr += binfo->bi_immr_base;
+
/* setup the board related information for the enet controllers */
pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
if (pdata) {
pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
- pdata->interruptPHY = MPC85xx_IRQ_EXT5;
- pdata->phyid = 0;
- /* fixup phy address */
- pdata->phy_reg_addr += binfo->bi_immr_base;
+ pdata->bus_id = GFAR_PHY_0;
memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
}
pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
if (pdata) {
pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
- pdata->interruptPHY = MPC85xx_IRQ_EXT5;
- pdata->phyid = 1;
- /* fixup phy address */
- pdata->phy_reg_addr += binfo->bi_immr_base;
+ pdata->bus_id = GFAR_PHY_1;
memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
}
pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC);
if (pdata) {
pdata->board_flags = 0;
- pdata->interruptPHY = MPC85xx_IRQ_EXT5;
- pdata->phyid = 3;
- /* fixup phy address */
- pdata->phy_reg_addr += binfo->bi_immr_base;
+ pdata->bus_id = GFAR_PHY_3;
memcpy(pdata->mac_addr, binfo->bi_enet2addr, 6);
}
diff --git a/arch/ppc/platforms/85xx/mpc8560_ads.c b/arch/ppc/platforms/85xx/mpc8560_ads.c
index 8841fd7da6ee..208433f1e93a 100644
--- a/arch/ppc/platforms/85xx/mpc8560_ads.c
+++ b/arch/ppc/platforms/85xx/mpc8560_ads.c
@@ -56,6 +56,10 @@
#include <syslib/ppc85xx_setup.h>
+static const char *GFAR_PHY_0 = "phy0:0";
+static const char *GFAR_PHY_1 = "phy0:1";
+static const char *GFAR_PHY_3 = "phy0:3";
+
/* ************************************************************************
*
* Setup the architecture
@@ -68,6 +72,7 @@ mpc8560ads_setup_arch(void)
bd_t *binfo = (bd_t *) __res;
unsigned int freq;
struct gianfar_platform_data *pdata;
+ struct gianfar_mdio_data *mdata;
cpm2_reset();
@@ -86,24 +91,28 @@ mpc8560ads_setup_arch(void)
mpc85xx_setup_hose();
#endif
+ /* setup the board related info for the MDIO bus */
+ mdata = (struct gianfar_mdio_data *) ppc_sys_get_pdata(MPC85xx_MDIO);
+
+ mdata->irq[0] = MPC85xx_IRQ_EXT5;
+ mdata->irq[1] = MPC85xx_IRQ_EXT5;
+ mdata->irq[2] = -1;
+ mdata->irq[3] = MPC85xx_IRQ_EXT5;
+ mdata->irq[31] = -1;
+ mdata->paddr += binfo->bi_immr_base;
+
/* setup the board related information for the enet controllers */
pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
if (pdata) {
pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
- pdata->interruptPHY = MPC85xx_IRQ_EXT5;
- pdata->phyid = 0;
- /* fixup phy address */
- pdata->phy_reg_addr += binfo->bi_immr_base;
+ pdata->bus_id = GFAR_PHY_0;
memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
}
pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
if (pdata) {
pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
- pdata->interruptPHY = MPC85xx_IRQ_EXT5;
- pdata->phyid = 1;
- /* fixup phy address */
- pdata->phy_reg_addr += binfo->bi_immr_base;
+ pdata->bus_id = GFAR_PHY_1;
memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
}
diff --git a/arch/ppc/platforms/85xx/mpc85xx_ads_common.h b/arch/ppc/platforms/85xx/mpc85xx_ads_common.h
index 3875e839cff7..84acf6e8d45e 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_ads_common.h
+++ b/arch/ppc/platforms/85xx/mpc85xx_ads_common.h
@@ -19,7 +19,6 @@
#include <linux/config.h>
#include <linux/init.h>
-#include <linux/seq_file.h>
#include <asm/ppcboot.h>
#define BOARD_CCSRBAR ((uint)0xe0000000)
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
index 9f9039498ae5..a21156967a5e 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
+++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
@@ -173,10 +173,7 @@ mpc85xx_cds_init_IRQ(void)
#ifdef CONFIG_PCI
openpic_hookup_cascade(PIRQ0A, "82c59 cascade", i8259_irq);
- for (i = 0; i < NUM_8259_INTERRUPTS; i++)
- irq_desc[i].handler = &i8259_pic;
-
- i8259_init(0);
+ i8259_init(0, 0);
#endif
#ifdef CONFIG_CPM2
@@ -394,6 +391,9 @@ mpc85xx_cds_pcibios_fixup(void)
TODC_ALLOC();
+static const char *GFAR_PHY_0 = "phy0:0";
+static const char *GFAR_PHY_1 = "phy0:1";
+
/* ************************************************************************
*
* Setup the architecture
@@ -405,6 +405,7 @@ mpc85xx_cds_setup_arch(void)
bd_t *binfo = (bd_t *) __res;
unsigned int freq;
struct gianfar_platform_data *pdata;
+ struct gianfar_mdio_data *mdata;
/* get the core frequency */
freq = binfo->bi_intfreq;
@@ -448,44 +449,42 @@ mpc85xx_cds_setup_arch(void)
invalidate_tlbcam_entry(num_tlbcam_entries - 1);
#endif
+ /* setup the board related info for the MDIO bus */
+ mdata = (struct gianfar_mdio_data *) ppc_sys_get_pdata(MPC85xx_MDIO);
+
+ mdata->irq[0] = MPC85xx_IRQ_EXT5;
+ mdata->irq[1] = MPC85xx_IRQ_EXT5;
+ mdata->irq[2] = -1;
+ mdata->irq[3] = -1;
+ mdata->irq[31] = -1;
+ mdata->paddr += binfo->bi_immr_base;
+
/* setup the board related information for the enet controllers */
pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
if (pdata) {
pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
- pdata->interruptPHY = MPC85xx_IRQ_EXT5;
- pdata->phyid = 0;
- /* fixup phy address */
- pdata->phy_reg_addr += binfo->bi_immr_base;
+ pdata->bus_id = GFAR_PHY_0;
memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
}
pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
if (pdata) {
pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
- pdata->interruptPHY = MPC85xx_IRQ_EXT5;
- pdata->phyid = 1;
- /* fixup phy address */
- pdata->phy_reg_addr += binfo->bi_immr_base;
+ pdata->bus_id = GFAR_PHY_1;
memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
}
pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_eTSEC1);
if (pdata) {
pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
- pdata->interruptPHY = MPC85xx_IRQ_EXT5;
- pdata->phyid = 0;
- /* fixup phy address */
- pdata->phy_reg_addr += binfo->bi_immr_base;
+ pdata->bus_id = GFAR_PHY_0;
memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
}
pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_eTSEC2);
if (pdata) {
pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
- pdata->interruptPHY = MPC85xx_IRQ_EXT5;
- pdata->phyid = 1;
- /* fixup phy address */
- pdata->phy_reg_addr += binfo->bi_immr_base;
+ pdata->bus_id = GFAR_PHY_1;
memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
}
diff --git a/arch/ppc/platforms/85xx/sbc8560.c b/arch/ppc/platforms/85xx/sbc8560.c
index c76760a781c1..b4ee1707a836 100644
--- a/arch/ppc/platforms/85xx/sbc8560.c
+++ b/arch/ppc/platforms/85xx/sbc8560.c
@@ -91,6 +91,9 @@ sbc8560_early_serial_map(void)
}
#endif
+static const char *GFAR_PHY_25 = "phy0:25";
+static const char *GFAR_PHY_26 = "phy0:26";
+
/* ************************************************************************
*
* Setup the architecture
@@ -102,6 +105,7 @@ sbc8560_setup_arch(void)
bd_t *binfo = (bd_t *) __res;
unsigned int freq;
struct gianfar_platform_data *pdata;
+ struct gianfar_mdio_data *mdata;
/* get the core frequency */
freq = binfo->bi_intfreq;
@@ -126,24 +130,26 @@ sbc8560_setup_arch(void)
invalidate_tlbcam_entry(num_tlbcam_entries - 1);
#endif
+ /* setup the board related info for the MDIO bus */
+ mdata = (struct gianfar_mdio_data *) ppc_sys_get_pdata(MPC85xx_MDIO);
+
+ mdata->irq[25] = MPC85xx_IRQ_EXT6;
+ mdata->irq[26] = MPC85xx_IRQ_EXT7;
+ mdata->irq[31] = -1;
+ mdata->paddr += binfo->bi_immr_base;
+
/* setup the board related information for the enet controllers */
pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
if (pdata) {
pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
- pdata->interruptPHY = MPC85xx_IRQ_EXT6;
- pdata->phyid = 25;
- /* fixup phy address */
- pdata->phy_reg_addr += binfo->bi_immr_base;
+ pdata->bus_id = GFAR_PHY_25;
memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
}
pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
if (pdata) {
pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
- pdata->interruptPHY = MPC85xx_IRQ_EXT7;
- pdata->phyid = 26;
- /* fixup phy address */
- pdata->phy_reg_addr += binfo->bi_immr_base;
+ pdata->bus_id = GFAR_PHY_26;
memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
}
diff --git a/arch/ppc/platforms/85xx/stx_gp3.c b/arch/ppc/platforms/85xx/stx_gp3.c
index 20940f4044f4..1e1b85f8193a 100644
--- a/arch/ppc/platforms/85xx/stx_gp3.c
+++ b/arch/ppc/platforms/85xx/stx_gp3.c
@@ -91,6 +91,9 @@ static u8 gp3_openpic_initsenses[] __initdata = {
0x0, /* External 11: */
};
+static const char *GFAR_PHY_2 = "phy0:2";
+static const char *GFAR_PHY_4 = "phy0:4";
+
/*
* Setup the architecture
*/
@@ -100,6 +103,7 @@ gp3_setup_arch(void)
bd_t *binfo = (bd_t *) __res;
unsigned int freq;
struct gianfar_platform_data *pdata;
+ struct gianfar_mdio_data *mdata;
cpm2_reset();
@@ -118,23 +122,26 @@ gp3_setup_arch(void)
mpc85xx_setup_hose();
#endif
+ /* setup the board related info for the MDIO bus */
+ mdata = (struct gianfar_mdio_data *) ppc_sys_get_pdata(MPC85xx_MDIO);
+
+ mdata->irq[2] = MPC85xx_IRQ_EXT5;
+ mdata->irq[4] = MPC85xx_IRQ_EXT5;
+ mdata->irq[31] = -1;
+ mdata->paddr += binfo->bi_immr_base;
+
/* setup the board related information for the enet controllers */
pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
if (pdata) {
/* pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */
- pdata->interruptPHY = MPC85xx_IRQ_EXT5;
- pdata->phyid = 2;
- pdata->phy_reg_addr += binfo->bi_immr_base;
+ pdata->bus_id = GFAR_PHY_2;
memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
}
pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
if (pdata) {
/* pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */
- pdata->interruptPHY = MPC85xx_IRQ_EXT5;
- pdata->phyid = 4;
- /* fixup phy address */
- pdata->phy_reg_addr += binfo->bi_immr_base;
+ pdata->bus_id = GFAR_PHY_4;
memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
}
diff --git a/arch/ppc/platforms/85xx/stx_gp3.h b/arch/ppc/platforms/85xx/stx_gp3.h
index 7bcc6c35a417..95fdf4b0680b 100644
--- a/arch/ppc/platforms/85xx/stx_gp3.h
+++ b/arch/ppc/platforms/85xx/stx_gp3.h
@@ -21,7 +21,6 @@
#include <linux/config.h>
#include <linux/init.h>
-#include <linux/seq_file.h>
#include <asm/ppcboot.h>
#define BOARD_CCSRBAR ((uint)0xe0000000)
diff --git a/arch/ppc/platforms/Makefile b/arch/ppc/platforms/Makefile
index ff7452e5d8e5..7c5cdabf6f3c 100644
--- a/arch/ppc/platforms/Makefile
+++ b/arch/ppc/platforms/Makefile
@@ -14,6 +14,9 @@ obj-$(CONFIG_PPC_PMAC) += pmac_pic.o pmac_setup.o pmac_time.o \
pmac_low_i2c.o pmac_cache.o
obj-$(CONFIG_PPC_CHRP) += chrp_setup.o chrp_time.o chrp_pci.o \
chrp_pegasos_eth.o
+ifeq ($(CONFIG_PPC_CHRP),y)
+obj-$(CONFIG_NVRAM) += chrp_nvram.o
+endif
obj-$(CONFIG_PPC_PREP) += prep_pci.o prep_setup.o
ifeq ($(CONFIG_PPC_PMAC),y)
obj-$(CONFIG_NVRAM) += pmac_nvram.o
diff --git a/arch/ppc/platforms/chestnut.c b/arch/ppc/platforms/chestnut.c
index df6ff98c023a..48a4a510d598 100644
--- a/arch/ppc/platforms/chestnut.c
+++ b/arch/ppc/platforms/chestnut.c
@@ -541,7 +541,6 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.setup_arch = chestnut_setup_arch;
ppc_md.show_cpuinfo = chestnut_show_cpuinfo;
- ppc_md.irq_canonicalize = NULL;
ppc_md.init_IRQ = mv64360_init_irq;
ppc_md.get_irq = mv64360_get_irq;
ppc_md.init = NULL;
diff --git a/arch/ppc/platforms/chrp_nvram.c b/arch/ppc/platforms/chrp_nvram.c
new file mode 100644
index 000000000000..465ba9b090ef
--- /dev/null
+++ b/arch/ppc/platforms/chrp_nvram.c
@@ -0,0 +1,83 @@
+/*
+ * c 2001 PPC 64 Team, IBM Corp
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * /dev/nvram driver for PPC
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <asm/uaccess.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+
+static unsigned int nvram_size;
+static unsigned char nvram_buf[4];
+static DEFINE_SPINLOCK(nvram_lock);
+
+static unsigned char chrp_nvram_read(int addr)
+{
+ unsigned long done, flags;
+ unsigned char ret;
+
+ if (addr >= nvram_size) {
+ printk(KERN_DEBUG "%s: read addr %d > nvram_size %u\n",
+ current->comm, addr, nvram_size);
+ return 0xff;
+ }
+ spin_lock_irqsave(&nvram_lock, flags);
+ if ((call_rtas("nvram-fetch", 3, 2, &done, addr, __pa(nvram_buf), 1) != 0) || 1 != done)
+ ret = 0xff;
+ else
+ ret = nvram_buf[0];
+ spin_unlock_irqrestore(&nvram_lock, flags);
+
+ return ret;
+}
+
+static void chrp_nvram_write(int addr, unsigned char val)
+{
+ unsigned long done, flags;
+
+ if (addr >= nvram_size) {
+ printk(KERN_DEBUG "%s: write addr %d > nvram_size %u\n",
+ current->comm, addr, nvram_size);
+ return;
+ }
+ spin_lock_irqsave(&nvram_lock, flags);
+ nvram_buf[0] = val;
+ if ((call_rtas("nvram-store", 3, 2, &done, addr, __pa(nvram_buf), 1) != 0) || 1 != done)
+ printk(KERN_DEBUG "rtas IO error storing 0x%02x at %d", val, addr);
+ spin_unlock_irqrestore(&nvram_lock, flags);
+}
+
+void __init chrp_nvram_init(void)
+{
+ struct device_node *nvram;
+ unsigned int *nbytes_p, proplen;
+
+ nvram = of_find_node_by_type(NULL, "nvram");
+ if (nvram == NULL)
+ return;
+
+ nbytes_p = (unsigned int *)get_property(nvram, "#bytes", &proplen);
+ if (nbytes_p == NULL || proplen != sizeof(unsigned int))
+ return;
+
+ nvram_size = *nbytes_p;
+
+ printk(KERN_INFO "CHRP nvram contains %u bytes\n", nvram_size);
+ of_node_put(nvram);
+
+ ppc_md.nvram_read_val = chrp_nvram_read;
+ ppc_md.nvram_write_val = chrp_nvram_write;
+
+ return;
+}
diff --git a/arch/ppc/platforms/chrp_pci.c b/arch/ppc/platforms/chrp_pci.c
index 7d3fbb5c5db2..bd047aac01b1 100644
--- a/arch/ppc/platforms/chrp_pci.c
+++ b/arch/ppc/platforms/chrp_pci.c
@@ -29,7 +29,7 @@ void __iomem *gg2_pci_config_base;
* limit the bus number to 3 bits
*/
-int __chrp gg2_read_config(struct pci_bus *bus, unsigned int devfn, int off,
+int gg2_read_config(struct pci_bus *bus, unsigned int devfn, int off,
int len, u32 *val)
{
volatile void __iomem *cfg_data;
@@ -56,7 +56,7 @@ int __chrp gg2_read_config(struct pci_bus *bus, unsigned int devfn, int off,
return PCIBIOS_SUCCESSFUL;
}
-int __chrp gg2_write_config(struct pci_bus *bus, unsigned int devfn, int off,
+int gg2_write_config(struct pci_bus *bus, unsigned int devfn, int off,
int len, u32 val)
{
volatile void __iomem *cfg_data;
@@ -92,7 +92,7 @@ static struct pci_ops gg2_pci_ops =
/*
* Access functions for PCI config space using RTAS calls.
*/
-int __chrp
+int
rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
int len, u32 *val)
{
@@ -108,7 +108,7 @@ rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL;
}
-int __chrp
+int
rtas_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
int len, u32 val)
{
@@ -203,7 +203,7 @@ static void __init setup_peg2(struct pci_controller *hose, struct device_node *d
printk ("RTAS supporting Pegasos OF not found, please upgrade"
" your firmware\n");
}
- pci_assign_all_busses = 1;
+ pci_assign_all_buses = 1;
}
void __init
diff --git a/arch/ppc/platforms/chrp_pegasos_eth.c b/arch/ppc/platforms/chrp_pegasos_eth.c
index d1af11c73ea1..108a6e265185 100644
--- a/arch/ppc/platforms/chrp_pegasos_eth.c
+++ b/arch/ppc/platforms/chrp_pegasos_eth.c
@@ -17,7 +17,20 @@
#include <linux/mv643xx.h>
#include <linux/pci.h>
-/* Pegasos 2 specific Marvell MV 64361 gigabit ethernet port setup */
+#define PEGASOS2_MARVELL_REGBASE (0xf1000000)
+#define PEGASOS2_MARVELL_REGSIZE (0x00004000)
+#define PEGASOS2_SRAM_BASE (0xf2000000)
+#define PEGASOS2_SRAM_SIZE (256*1024)
+
+#define PEGASOS2_SRAM_BASE_ETH0 (PEGASOS2_SRAM_BASE)
+#define PEGASOS2_SRAM_BASE_ETH1 (PEGASOS2_SRAM_BASE_ETH0 + (PEGASOS2_SRAM_SIZE / 2) )
+
+
+#define PEGASOS2_SRAM_RXRING_SIZE (PEGASOS2_SRAM_SIZE/4)
+#define PEGASOS2_SRAM_TXRING_SIZE (PEGASOS2_SRAM_SIZE/4)
+
+#undef BE_VERBOSE
+
static struct resource mv643xx_eth_shared_resources[] = {
[0] = {
.name = "ethernet shared base",
@@ -44,7 +57,16 @@ static struct resource mv643xx_eth0_resources[] = {
},
};
-static struct mv643xx_eth_platform_data eth0_pd;
+
+static struct mv643xx_eth_platform_data eth0_pd = {
+ .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH0,
+ .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE,
+ .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16,
+
+ .rx_sram_addr = PEGASOS2_SRAM_BASE_ETH0 + PEGASOS2_SRAM_TXRING_SIZE,
+ .rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE,
+ .rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16,
+};
static struct platform_device eth0_device = {
.name = MV643XX_ETH_NAME,
@@ -65,7 +87,15 @@ static struct resource mv643xx_eth1_resources[] = {
},
};
-static struct mv643xx_eth_platform_data eth1_pd;
+static struct mv643xx_eth_platform_data eth1_pd = {
+ .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH1,
+ .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE,
+ .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16,
+
+ .rx_sram_addr = PEGASOS2_SRAM_BASE_ETH1 + PEGASOS2_SRAM_TXRING_SIZE,
+ .rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE,
+ .rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16,
+};
static struct platform_device eth1_device = {
.name = MV643XX_ETH_NAME,
@@ -83,9 +113,62 @@ static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
&eth1_device,
};
+/***********/
+/***********/
+#define MV_READ(offset,val) { val = readl(mv643xx_reg_base + offset); }
+#define MV_WRITE(offset,data) writel(data, mv643xx_reg_base + offset)
+
+static void __iomem *mv643xx_reg_base;
+
+static int Enable_SRAM(void)
+{
+ u32 ALong;
+
+ if (mv643xx_reg_base == NULL)
+ mv643xx_reg_base = ioremap(PEGASOS2_MARVELL_REGBASE,
+ PEGASOS2_MARVELL_REGSIZE);
+
+ if (mv643xx_reg_base == NULL)
+ return -ENOMEM;
+
+#ifdef BE_VERBOSE
+ printk("Pegasos II/Marvell MV64361: register remapped from %p to %p\n",
+ (void *)PEGASOS2_MARVELL_REGBASE, (void *)mv643xx_reg_base);
+#endif
+
+ MV_WRITE(MV64340_SRAM_CONFIG, 0);
-int
-mv643xx_eth_add_pds(void)
+ MV_WRITE(MV64340_INTEGRATED_SRAM_BASE_ADDR, PEGASOS2_SRAM_BASE >> 16);
+
+ MV_READ(MV64340_BASE_ADDR_ENABLE, ALong);
+ ALong &= ~(1 << 19);
+ MV_WRITE(MV64340_BASE_ADDR_ENABLE, ALong);
+
+ ALong = 0x02;
+ ALong |= PEGASOS2_SRAM_BASE & 0xffff0000;
+ MV_WRITE(MV643XX_ETH_BAR_4, ALong);
+
+ MV_WRITE(MV643XX_ETH_SIZE_REG_4, (PEGASOS2_SRAM_SIZE-1) & 0xffff0000);
+
+ MV_READ(MV643XX_ETH_BASE_ADDR_ENABLE_REG, ALong);
+ ALong &= ~(1 << 4);
+ MV_WRITE(MV643XX_ETH_BASE_ADDR_ENABLE_REG, ALong);
+
+#ifdef BE_VERBOSE
+ printk("Pegasos II/Marvell MV64361: register unmapped\n");
+ printk("Pegasos II/Marvell MV64361: SRAM at %p, size=%x\n", (void*) PEGASOS2_SRAM_BASE, PEGASOS2_SRAM_SIZE);
+#endif
+
+ iounmap(mv643xx_reg_base);
+ mv643xx_reg_base = NULL;
+
+ return 1;
+}
+
+
+/***********/
+/***********/
+int mv643xx_eth_add_pds(void)
{
int ret = 0;
static struct pci_device_id pci_marvell_mv64360[] = {
@@ -93,9 +176,38 @@ mv643xx_eth_add_pds(void)
{ }
};
+#ifdef BE_VERBOSE
+ printk("Pegasos II/Marvell MV64361: init\n");
+#endif
+
if (pci_dev_present(pci_marvell_mv64360)) {
- ret = platform_add_devices(mv643xx_eth_pd_devs, ARRAY_SIZE(mv643xx_eth_pd_devs));
+ ret = platform_add_devices(mv643xx_eth_pd_devs,
+ ARRAY_SIZE(mv643xx_eth_pd_devs));
+
+ if ( Enable_SRAM() < 0)
+ {
+ eth0_pd.tx_sram_addr = 0;
+ eth0_pd.tx_sram_size = 0;
+ eth0_pd.rx_sram_addr = 0;
+ eth0_pd.rx_sram_size = 0;
+
+ eth1_pd.tx_sram_addr = 0;
+ eth1_pd.tx_sram_size = 0;
+ eth1_pd.rx_sram_addr = 0;
+ eth1_pd.rx_sram_size = 0;
+
+#ifdef BE_VERBOSE
+ printk("Pegasos II/Marvell MV64361: Can't enable the "
+ "SRAM\n");
+#endif
+ }
}
+
+#ifdef BE_VERBOSE
+ printk("Pegasos II/Marvell MV64361: init is over\n");
+#endif
+
return ret;
}
+
device_initcall(mv643xx_eth_add_pds);
diff --git a/arch/ppc/platforms/chrp_setup.c b/arch/ppc/platforms/chrp_setup.c
index 66346f0de7ec..f1b70ab3c6fd 100644
--- a/arch/ppc/platforms/chrp_setup.c
+++ b/arch/ppc/platforms/chrp_setup.c
@@ -104,7 +104,7 @@ static const char *gg2_cachemodes[4] = {
"Disabled", "Write-Through", "Copy-Back", "Transparent Mode"
};
-int __chrp
+int
chrp_show_cpuinfo(struct seq_file *m)
{
int i, sdramen;
@@ -302,7 +302,7 @@ void __init chrp_setup_arch(void)
pci_create_OF_bus_map();
}
-void __chrp
+void
chrp_event_scan(void)
{
unsigned char log[1024];
@@ -313,7 +313,7 @@ chrp_event_scan(void)
ppc_md.heartbeat_count = ppc_md.heartbeat_reset;
}
-void __chrp
+void
chrp_restart(char *cmd)
{
printk("RTAS system-reboot returned %d\n",
@@ -321,7 +321,7 @@ chrp_restart(char *cmd)
for (;;);
}
-void __chrp
+void
chrp_power_off(void)
{
/* allow power on only with power button press */
@@ -330,20 +330,12 @@ chrp_power_off(void)
for (;;);
}
-void __chrp
+void
chrp_halt(void)
{
chrp_power_off();
}
-u_int __chrp
-chrp_irq_canonicalize(u_int irq)
-{
- if (irq == 2)
- return 9;
- return irq;
-}
-
/*
* Finds the open-pic node and sets OpenPIC_Addr based on its reg property.
* Then checks if it has an interrupt-ranges property. If it does then
@@ -444,9 +436,7 @@ void __init chrp_init_IRQ(void)
i8259_irq);
}
- for (i = 0; i < NUM_8259_INTERRUPTS; i++)
- irq_desc[i].handler = &i8259_pic;
- i8259_init(chrp_int_ack);
+ i8259_init(chrp_int_ack, 0);
#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
/* see if there is a keyboard in the device tree
@@ -464,8 +454,7 @@ void __init
chrp_init2(void)
{
#ifdef CONFIG_NVRAM
-// XX replace this in a more saner way
-// pmac_nvram_init();
+ chrp_nvram_init();
#endif
request_region(0x20,0x20,"pic1");
@@ -499,6 +488,7 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
DMA_MODE_READ = 0x44;
DMA_MODE_WRITE = 0x48;
isa_io_base = CHRP_ISA_IO_BASE; /* default value */
+ ppc_do_canonicalize_irqs = 1;
if (root)
machine = get_property(root, "model", NULL);
@@ -517,7 +507,6 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.show_percpuinfo = of_show_percpuinfo;
ppc_md.show_cpuinfo = chrp_show_cpuinfo;
- ppc_md.irq_canonicalize = chrp_irq_canonicalize;
ppc_md.init_IRQ = chrp_init_IRQ;
if (_chrp_type == _CHRP_Pegasos)
ppc_md.get_irq = i8259_irq;
@@ -561,7 +550,7 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
#endif
#ifdef CONFIG_SMP
- ppc_md.smp_ops = &chrp_smp_ops;
+ smp_ops = &chrp_smp_ops;
#endif /* CONFIG_SMP */
/*
@@ -571,7 +560,7 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
if (ppc_md.progress) ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0x0);
}
-void __chrp
+void
rtas_display_progress(char *s, unsigned short hex)
{
int width;
@@ -598,7 +587,7 @@ rtas_display_progress(char *s, unsigned short hex)
call_rtas( "display-character", 1, 1, NULL, ' ' );
}
-void __chrp
+void
rtas_indicator_progress(char *s, unsigned short hex)
{
call_rtas("set-indicator", 3, 1, NULL, 6, 0, hex);
diff --git a/arch/ppc/platforms/chrp_smp.c b/arch/ppc/platforms/chrp_smp.c
index 0ea1f7d9e46a..97e539557ecb 100644
--- a/arch/ppc/platforms/chrp_smp.c
+++ b/arch/ppc/platforms/chrp_smp.c
@@ -31,6 +31,7 @@
#include <asm/residual.h>
#include <asm/time.h>
#include <asm/open_pic.h>
+#include <asm/machdep.h>
extern unsigned long smp_chrp_cpu_nr;
@@ -88,7 +89,7 @@ smp_chrp_take_timebase(void)
}
/* CHRP with openpic */
-struct smp_ops_t chrp_smp_ops __chrpdata = {
+struct smp_ops_t chrp_smp_ops = {
.message_pass = smp_openpic_message_pass,
.probe = smp_chrp_probe,
.kick_cpu = smp_chrp_kick_cpu,
diff --git a/arch/ppc/platforms/chrp_time.c b/arch/ppc/platforms/chrp_time.c
index 6037ce7796f5..29d074c305f0 100644
--- a/arch/ppc/platforms/chrp_time.c
+++ b/arch/ppc/platforms/chrp_time.c
@@ -52,7 +52,7 @@ long __init chrp_time_init(void)
return 0;
}
-int __chrp chrp_cmos_clock_read(int addr)
+int chrp_cmos_clock_read(int addr)
{
if (nvram_as1 != 0)
outb(addr>>8, nvram_as1);
@@ -60,7 +60,7 @@ int __chrp chrp_cmos_clock_read(int addr)
return (inb(nvram_data));
}
-void __chrp chrp_cmos_clock_write(unsigned long val, int addr)
+void chrp_cmos_clock_write(unsigned long val, int addr)
{
if (nvram_as1 != 0)
outb(addr>>8, nvram_as1);
@@ -72,7 +72,7 @@ void __chrp chrp_cmos_clock_write(unsigned long val, int addr)
/*
* Set the hardware clock. -- Cort
*/
-int __chrp chrp_set_rtc_time(unsigned long nowtime)
+int chrp_set_rtc_time(unsigned long nowtime)
{
unsigned char save_control, save_freq_select;
struct rtc_time tm;
@@ -118,7 +118,7 @@ int __chrp chrp_set_rtc_time(unsigned long nowtime)
return 0;
}
-unsigned long __chrp chrp_get_rtc_time(void)
+unsigned long chrp_get_rtc_time(void)
{
unsigned int year, mon, day, hour, min, sec;
int uip, i;
diff --git a/arch/ppc/platforms/ev64360.c b/arch/ppc/platforms/ev64360.c
index 4e6cc64b3efd..b1324564456e 100644
--- a/arch/ppc/platforms/ev64360.c
+++ b/arch/ppc/platforms/ev64360.c
@@ -36,6 +36,7 @@
#include <asm/bootinfo.h>
#include <asm/ppcboot.h>
#include <asm/mv64x60.h>
+#include <asm/machdep.h>
#include <platforms/ev64360.h>
#define BOARD_VENDOR "Marvell"
diff --git a/arch/ppc/platforms/fads.h b/arch/ppc/platforms/fads.h
index b60c56450b67..a48fb8d723e4 100644
--- a/arch/ppc/platforms/fads.h
+++ b/arch/ppc/platforms/fads.h
@@ -25,6 +25,8 @@
#if defined(CONFIG_MPC86XADS)
+#define BOARD_CHIP_NAME "MPC86X"
+
/* U-Boot maps BCSR to 0xff080000 */
#define BCSR_ADDR ((uint)0xff080000)
diff --git a/arch/ppc/platforms/gemini_setup.c b/arch/ppc/platforms/gemini_setup.c
index 3a5ff9fb71d6..729897c59033 100644
--- a/arch/ppc/platforms/gemini_setup.c
+++ b/arch/ppc/platforms/gemini_setup.c
@@ -35,6 +35,7 @@
#include <asm/time.h>
#include <asm/open_pic.h>
#include <asm/bootinfo.h>
+#include <asm/machdep.h>
void gemini_find_bridges(void);
static int gemini_get_clock_speed(void);
@@ -555,7 +556,6 @@ void __init platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.setup_arch = gemini_setup_arch;
ppc_md.show_cpuinfo = gemini_show_cpuinfo;
- ppc_md.irq_canonicalize = NULL;
ppc_md.init_IRQ = gemini_init_IRQ;
ppc_md.get_irq = openpic_get_irq;
ppc_md.init = NULL;
@@ -575,6 +575,6 @@ void __init platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.pcibios_fixup_bus = gemini_pcibios_fixup;
#ifdef CONFIG_SMP
- ppc_md.smp_ops = &gemini_smp_ops;
+ smp_ops = &gemini_smp_ops;
#endif /* CONFIG_SMP */
}
diff --git a/arch/ppc/platforms/hdpu.c b/arch/ppc/platforms/hdpu.c
index 0f07e963de3c..50039a204c24 100644
--- a/arch/ppc/platforms/hdpu.c
+++ b/arch/ppc/platforms/hdpu.c
@@ -610,11 +610,6 @@ static void parse_bootinfo(unsigned long r3,
}
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
-static int hdpu_ide_check_region(ide_ioreg_t from, unsigned int extent)
-{
- return check_region(from, extent);
-}
-
static void
hdpu_ide_request_region(ide_ioreg_t from, unsigned int extent, const char *name)
{
@@ -754,7 +749,7 @@ static int smp_hdpu_probe(void)
}
static void
-smp_hdpu_message_pass(int target, int msg, unsigned long data, int wait)
+smp_hdpu_message_pass(int target, int msg)
{
if (msg > 0x3) {
printk("SMP %d: smp_message_pass: unknown msg %d\n",
@@ -950,7 +945,7 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
#endif /* CONFIG_SERIAL_TEXT_DEBUG */
#ifdef CONFIG_SMP
- ppc_md.smp_ops = &hdpu_smp_ops;
+ smp_ops = &hdpu_smp_ops;
#endif /* CONFIG_SMP */
#if defined(CONFIG_SERIAL_MPSC) || defined(CONFIG_MV643XX_ETH)
diff --git a/arch/ppc/platforms/katana.c b/arch/ppc/platforms/katana.c
index beb617141456..6e58e30ceed1 100644
--- a/arch/ppc/platforms/katana.c
+++ b/arch/ppc/platforms/katana.c
@@ -43,6 +43,7 @@
#include <asm/ppcboot.h>
#include <asm/mv64x60.h>
#include <platforms/katana.h>
+#include <asm/machdep.h>
static struct mv64x60_handle bh;
static katana_id_t katana_id;
@@ -521,7 +522,7 @@ katana_fixup_resources(struct pci_dev *dev)
{
u16 v16;
- pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, L1_CACHE_LINE_SIZE>>2);
+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES>>2);
pci_read_config_word(dev, PCI_COMMAND, &v16);
v16 |= PCI_COMMAND_INVALIDATE | PCI_COMMAND_FAST_BACK;
diff --git a/arch/ppc/platforms/lite5200.c b/arch/ppc/platforms/lite5200.c
index b604cf8b3cae..d44cc991179f 100644
--- a/arch/ppc/platforms/lite5200.c
+++ b/arch/ppc/platforms/lite5200.c
@@ -35,6 +35,7 @@
#include <asm/io.h>
#include <asm/mpc52xx.h>
#include <asm/ppc_sys.h>
+#include <asm/machdep.h>
#include <syslib/mpc52xx_pci.h>
diff --git a/arch/ppc/platforms/lopec.c b/arch/ppc/platforms/lopec.c
index a5569525e0af..06d247c23b82 100644
--- a/arch/ppc/platforms/lopec.c
+++ b/arch/ppc/platforms/lopec.c
@@ -144,15 +144,6 @@ lopec_show_cpuinfo(struct seq_file *m)
return 0;
}
-static u32
-lopec_irq_canonicalize(u32 irq)
-{
- if (irq == 2)
- return 9;
- else
- return irq;
-}
-
static void
lopec_restart(char *cmd)
{
@@ -276,15 +267,11 @@ lopec_init_IRQ(void)
openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
&i8259_irq);
- /* Map i8259 interrupts */
- for(i = 0; i < NUM_8259_INTERRUPTS; i++)
- irq_desc[i].handler = &i8259_pic;
-
/*
* The EPIC allows for a read in the range of 0xFEF00000 ->
* 0xFEFFFFFF to generate a PCI interrupt-acknowledge transaction.
*/
- i8259_init(0xfef00000);
+ i8259_init(0xfef00000, 0);
}
static int __init
@@ -379,10 +366,10 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
ISA_DMA_THRESHOLD = 0x00ffffff;
DMA_MODE_READ = 0x44;
DMA_MODE_WRITE = 0x48;
+ ppc_do_canonicalize_irqs = 1;
ppc_md.setup_arch = lopec_setup_arch;
ppc_md.show_cpuinfo = lopec_show_cpuinfo;
- ppc_md.irq_canonicalize = lopec_irq_canonicalize;
ppc_md.init_IRQ = lopec_init_IRQ;
ppc_md.get_irq = openpic_get_irq;
diff --git a/arch/ppc/platforms/mpc885ads.h b/arch/ppc/platforms/mpc885ads.h
index eb386635b0fd..a80b7d116b49 100644
--- a/arch/ppc/platforms/mpc885ads.h
+++ b/arch/ppc/platforms/mpc885ads.h
@@ -88,5 +88,7 @@
#define SICR_ENET_MASK ((uint)0x00ff0000)
#define SICR_ENET_CLKRT ((uint)0x002c0000)
+#define BOARD_CHIP_NAME "MPC885"
+
#endif /* __ASM_MPC885ADS_H__ */
#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/mvme5100.c b/arch/ppc/platforms/mvme5100.c
index ce2ce88c8033..108eb182dddc 100644
--- a/arch/ppc/platforms/mvme5100.c
+++ b/arch/ppc/platforms/mvme5100.c
@@ -223,11 +223,7 @@ mvme5100_init_IRQ(void)
openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
&i8259_irq);
- /* Map i8259 interrupts. */
- for (i = 0; i < NUM_8259_INTERRUPTS; i++)
- irq_desc[i].handler = &i8259_pic;
-
- i8259_init(0);
+ i8259_init(0, 0);
#else
openpic_init(0);
#endif
diff --git a/arch/ppc/platforms/pal4_setup.c b/arch/ppc/platforms/pal4_setup.c
index 12446b93e38c..f93a3f871932 100644
--- a/arch/ppc/platforms/pal4_setup.c
+++ b/arch/ppc/platforms/pal4_setup.c
@@ -28,6 +28,7 @@
#include <asm/io.h>
#include <asm/todc.h>
#include <asm/bootinfo.h>
+#include <asm/machdep.h>
#include <syslib/cpc700.h>
diff --git a/arch/ppc/platforms/pmac_backlight.c b/arch/ppc/platforms/pmac_backlight.c
index ed2b1cebc19a..8be2f7d071f0 100644
--- a/arch/ppc/platforms/pmac_backlight.c
+++ b/arch/ppc/platforms/pmac_backlight.c
@@ -37,7 +37,7 @@ static int backlight_req_enable = -1;
static void backlight_callback(void *);
static DECLARE_WORK(backlight_work, backlight_callback, NULL);
-void __pmac register_backlight_controller(struct backlight_controller *ctrler,
+void register_backlight_controller(struct backlight_controller *ctrler,
void *data, char *type)
{
struct device_node* bk_node;
@@ -99,7 +99,7 @@ void __pmac register_backlight_controller(struct backlight_controller *ctrler,
}
EXPORT_SYMBOL(register_backlight_controller);
-void __pmac unregister_backlight_controller(struct backlight_controller
+void unregister_backlight_controller(struct backlight_controller
*ctrler, void *data)
{
/* We keep the current backlight level (for now) */
@@ -108,7 +108,7 @@ void __pmac unregister_backlight_controller(struct backlight_controller
}
EXPORT_SYMBOL(unregister_backlight_controller);
-static int __pmac __set_backlight_enable(int enable)
+static int __set_backlight_enable(int enable)
{
int rc;
@@ -122,7 +122,7 @@ static int __pmac __set_backlight_enable(int enable)
release_console_sem();
return rc;
}
-int __pmac set_backlight_enable(int enable)
+int set_backlight_enable(int enable)
{
if (!backlighter)
return -ENODEV;
@@ -133,7 +133,7 @@ int __pmac set_backlight_enable(int enable)
EXPORT_SYMBOL(set_backlight_enable);
-int __pmac get_backlight_enable(void)
+int get_backlight_enable(void)
{
if (!backlighter)
return -ENODEV;
@@ -141,7 +141,7 @@ int __pmac get_backlight_enable(void)
}
EXPORT_SYMBOL(get_backlight_enable);
-static int __pmac __set_backlight_level(int level)
+static int __set_backlight_level(int level)
{
int rc = 0;
@@ -165,7 +165,7 @@ static int __pmac __set_backlight_level(int level)
}
return rc;
}
-int __pmac set_backlight_level(int level)
+int set_backlight_level(int level)
{
if (!backlighter)
return -ENODEV;
@@ -176,7 +176,7 @@ int __pmac set_backlight_level(int level)
EXPORT_SYMBOL(set_backlight_level);
-int __pmac get_backlight_level(void)
+int get_backlight_level(void)
{
if (!backlighter)
return -ENODEV;
diff --git a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c
index d4bc5f67ec53..fba7e4d7c0bf 100644
--- a/arch/ppc/platforms/pmac_cpufreq.c
+++ b/arch/ppc/platforms/pmac_cpufreq.c
@@ -136,7 +136,7 @@ static inline void debug_calc_bogomips(void)
/* Switch CPU speed under 750FX CPU control
*/
-static int __pmac cpu_750fx_cpu_speed(int low_speed)
+static int cpu_750fx_cpu_speed(int low_speed)
{
u32 hid2;
@@ -172,7 +172,7 @@ static int __pmac cpu_750fx_cpu_speed(int low_speed)
return 0;
}
-static unsigned int __pmac cpu_750fx_get_cpu_speed(void)
+static unsigned int cpu_750fx_get_cpu_speed(void)
{
if (mfspr(SPRN_HID1) & HID1_PS)
return low_freq;
@@ -181,7 +181,7 @@ static unsigned int __pmac cpu_750fx_get_cpu_speed(void)
}
/* Switch CPU speed using DFS */
-static int __pmac dfs_set_cpu_speed(int low_speed)
+static int dfs_set_cpu_speed(int low_speed)
{
if (low_speed == 0) {
/* ramping up, set voltage first */
@@ -205,7 +205,7 @@ static int __pmac dfs_set_cpu_speed(int low_speed)
return 0;
}
-static unsigned int __pmac dfs_get_cpu_speed(void)
+static unsigned int dfs_get_cpu_speed(void)
{
if (mfspr(SPRN_HID1) & HID1_DFS)
return low_freq;
@@ -216,7 +216,7 @@ static unsigned int __pmac dfs_get_cpu_speed(void)
/* Switch CPU speed using slewing GPIOs
*/
-static int __pmac gpios_set_cpu_speed(int low_speed)
+static int gpios_set_cpu_speed(int low_speed)
{
int gpio, timeout = 0;
@@ -258,7 +258,7 @@ static int __pmac gpios_set_cpu_speed(int low_speed)
/* Switch CPU speed under PMU control
*/
-static int __pmac pmu_set_cpu_speed(int low_speed)
+static int pmu_set_cpu_speed(int low_speed)
{
struct adb_request req;
unsigned long save_l2cr;
@@ -354,7 +354,7 @@ static int __pmac pmu_set_cpu_speed(int low_speed)
return 0;
}
-static int __pmac do_set_cpu_speed(int speed_mode, int notify)
+static int do_set_cpu_speed(int speed_mode, int notify)
{
struct cpufreq_freqs freqs;
unsigned long l3cr;
@@ -391,17 +391,17 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify)
return 0;
}
-static unsigned int __pmac pmac_cpufreq_get_speed(unsigned int cpu)
+static unsigned int pmac_cpufreq_get_speed(unsigned int cpu)
{
return cur_freq;
}
-static int __pmac pmac_cpufreq_verify(struct cpufreq_policy *policy)
+static int pmac_cpufreq_verify(struct cpufreq_policy *policy)
{
return cpufreq_frequency_table_verify(policy, pmac_cpu_freqs);
}
-static int __pmac pmac_cpufreq_target( struct cpufreq_policy *policy,
+static int pmac_cpufreq_target( struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{
@@ -414,13 +414,13 @@ static int __pmac pmac_cpufreq_target( struct cpufreq_policy *policy,
return do_set_cpu_speed(newstate, 1);
}
-unsigned int __pmac pmac_get_one_cpufreq(int i)
+unsigned int pmac_get_one_cpufreq(int i)
{
/* Supports only one CPU for now */
return (i == 0) ? cur_freq : 0;
}
-static int __pmac pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
+static int pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
{
if (policy->cpu != 0)
return -ENODEV;
@@ -433,7 +433,7 @@ static int __pmac pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
return cpufreq_frequency_table_cpuinfo(policy, pmac_cpu_freqs);
}
-static u32 __pmac read_gpio(struct device_node *np)
+static u32 read_gpio(struct device_node *np)
{
u32 *reg = (u32 *)get_property(np, "reg", NULL);
u32 offset;
@@ -452,7 +452,7 @@ static u32 __pmac read_gpio(struct device_node *np)
return offset;
}
-static int __pmac pmac_cpufreq_suspend(struct cpufreq_policy *policy, pm_message_t pmsg)
+static int pmac_cpufreq_suspend(struct cpufreq_policy *policy, pm_message_t pmsg)
{
/* Ok, this could be made a bit smarter, but let's be robust for now. We
* always force a speed change to high speed before sleep, to make sure
@@ -468,7 +468,7 @@ static int __pmac pmac_cpufreq_suspend(struct cpufreq_policy *policy, pm_message
return 0;
}
-static int __pmac pmac_cpufreq_resume(struct cpufreq_policy *policy)
+static int pmac_cpufreq_resume(struct cpufreq_policy *policy)
{
/* If we resume, first check if we have a get() function */
if (get_speed_proc)
@@ -501,7 +501,7 @@ static struct cpufreq_driver pmac_cpufreq_driver = {
};
-static int __pmac pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
+static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
{
struct device_node *volt_gpio_np = of_find_node_by_name(NULL,
"voltage-gpio");
@@ -593,7 +593,7 @@ static int __pmac pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
return 0;
}
-static int __pmac pmac_cpufreq_init_7447A(struct device_node *cpunode)
+static int pmac_cpufreq_init_7447A(struct device_node *cpunode)
{
struct device_node *volt_gpio_np;
@@ -620,7 +620,7 @@ static int __pmac pmac_cpufreq_init_7447A(struct device_node *cpunode)
return 0;
}
-static int __pmac pmac_cpufreq_init_750FX(struct device_node *cpunode)
+static int pmac_cpufreq_init_750FX(struct device_node *cpunode)
{
struct device_node *volt_gpio_np;
u32 pvr, *value;
diff --git a/arch/ppc/platforms/pmac_feature.c b/arch/ppc/platforms/pmac_feature.c
index dd6d45ae0501..58884a63ebdb 100644
--- a/arch/ppc/platforms/pmac_feature.c
+++ b/arch/ppc/platforms/pmac_feature.c
@@ -63,7 +63,7 @@ extern struct device_node *k2_skiplist[2];
* We use a single global lock to protect accesses. Each driver has
* to take care of its own locking
*/
-static DEFINE_SPINLOCK(feature_lock __pmacdata);
+static DEFINE_SPINLOCK(feature_lock);
#define LOCK(flags) spin_lock_irqsave(&feature_lock, flags);
#define UNLOCK(flags) spin_unlock_irqrestore(&feature_lock, flags);
@@ -72,9 +72,9 @@ static DEFINE_SPINLOCK(feature_lock __pmacdata);
/*
* Instance of some macio stuffs
*/
-struct macio_chip macio_chips[MAX_MACIO_CHIPS] __pmacdata;
+struct macio_chip macio_chips[MAX_MACIO_CHIPS];
-struct macio_chip* __pmac macio_find(struct device_node* child, int type)
+struct macio_chip* macio_find(struct device_node* child, int type)
{
while(child) {
int i;
@@ -89,7 +89,7 @@ struct macio_chip* __pmac macio_find(struct device_node* child, int type)
}
EXPORT_SYMBOL_GPL(macio_find);
-static const char* macio_names[] __pmacdata =
+static const char* macio_names[] =
{
"Unknown",
"Grand Central",
@@ -116,10 +116,10 @@ static const char* macio_names[] __pmacdata =
#define UN_BIS(r,v) (UN_OUT((r), UN_IN(r) | (v)))
#define UN_BIC(r,v) (UN_OUT((r), UN_IN(r) & ~(v)))
-static struct device_node* uninorth_node __pmacdata;
-static u32 __iomem * uninorth_base __pmacdata;
-static u32 uninorth_rev __pmacdata;
-static int uninorth_u3 __pmacdata;
+static struct device_node* uninorth_node;
+static u32 __iomem * uninorth_base;
+static u32 uninorth_rev;
+static int uninorth_u3;
static void __iomem *u3_ht;
/*
@@ -142,13 +142,13 @@ struct pmac_mb_def
struct feature_table_entry* features;
unsigned long board_flags;
};
-static struct pmac_mb_def pmac_mb __pmacdata;
+static struct pmac_mb_def pmac_mb;
/*
* Here are the chip specific feature functions
*/
-static inline int __pmac
+static inline int
simple_feature_tweak(struct device_node* node, int type, int reg, u32 mask, int value)
{
struct macio_chip* macio;
@@ -170,7 +170,7 @@ simple_feature_tweak(struct device_node* node, int type, int reg, u32 mask, int
#ifndef CONFIG_POWER4
-static long __pmac
+static long
ohare_htw_scc_enable(struct device_node* node, long param, long value)
{
struct macio_chip* macio;
@@ -263,21 +263,21 @@ ohare_htw_scc_enable(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
ohare_floppy_enable(struct device_node* node, long param, long value)
{
return simple_feature_tweak(node, macio_ohare,
OHARE_FCR, OH_FLOPPY_ENABLE, value);
}
-static long __pmac
+static long
ohare_mesh_enable(struct device_node* node, long param, long value)
{
return simple_feature_tweak(node, macio_ohare,
OHARE_FCR, OH_MESH_ENABLE, value);
}
-static long __pmac
+static long
ohare_ide_enable(struct device_node* node, long param, long value)
{
switch(param) {
@@ -298,7 +298,7 @@ ohare_ide_enable(struct device_node* node, long param, long value)
}
}
-static long __pmac
+static long
ohare_ide_reset(struct device_node* node, long param, long value)
{
switch(param) {
@@ -313,7 +313,7 @@ ohare_ide_reset(struct device_node* node, long param, long value)
}
}
-static long __pmac
+static long
ohare_sleep_state(struct device_node* node, long param, long value)
{
struct macio_chip* macio = &macio_chips[0];
@@ -329,7 +329,7 @@ ohare_sleep_state(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
heathrow_modem_enable(struct device_node* node, long param, long value)
{
struct macio_chip* macio;
@@ -373,7 +373,7 @@ heathrow_modem_enable(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
heathrow_floppy_enable(struct device_node* node, long param, long value)
{
return simple_feature_tweak(node, macio_unknown,
@@ -382,7 +382,7 @@ heathrow_floppy_enable(struct device_node* node, long param, long value)
value);
}
-static long __pmac
+static long
heathrow_mesh_enable(struct device_node* node, long param, long value)
{
struct macio_chip* macio;
@@ -411,7 +411,7 @@ heathrow_mesh_enable(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
heathrow_ide_enable(struct device_node* node, long param, long value)
{
switch(param) {
@@ -426,7 +426,7 @@ heathrow_ide_enable(struct device_node* node, long param, long value)
}
}
-static long __pmac
+static long
heathrow_ide_reset(struct device_node* node, long param, long value)
{
switch(param) {
@@ -441,7 +441,7 @@ heathrow_ide_reset(struct device_node* node, long param, long value)
}
}
-static long __pmac
+static long
heathrow_bmac_enable(struct device_node* node, long param, long value)
{
struct macio_chip* macio;
@@ -470,7 +470,7 @@ heathrow_bmac_enable(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
heathrow_sound_enable(struct device_node* node, long param, long value)
{
struct macio_chip* macio;
@@ -501,16 +501,16 @@ heathrow_sound_enable(struct device_node* node, long param, long value)
return 0;
}
-static u32 save_fcr[6] __pmacdata;
-static u32 save_mbcr __pmacdata;
-static u32 save_gpio_levels[2] __pmacdata;
-static u8 save_gpio_extint[KEYLARGO_GPIO_EXTINT_CNT] __pmacdata;
-static u8 save_gpio_normal[KEYLARGO_GPIO_CNT] __pmacdata;
-static u32 save_unin_clock_ctl __pmacdata;
-static struct dbdma_regs save_dbdma[13] __pmacdata;
-static struct dbdma_regs save_alt_dbdma[13] __pmacdata;
+static u32 save_fcr[6];
+static u32 save_mbcr;
+static u32 save_gpio_levels[2];
+static u8 save_gpio_extint[KEYLARGO_GPIO_EXTINT_CNT];
+static u8 save_gpio_normal[KEYLARGO_GPIO_CNT];
+static u32 save_unin_clock_ctl;
+static struct dbdma_regs save_dbdma[13];
+static struct dbdma_regs save_alt_dbdma[13];
-static void __pmac
+static void
dbdma_save(struct macio_chip* macio, struct dbdma_regs* save)
{
int i;
@@ -527,7 +527,7 @@ dbdma_save(struct macio_chip* macio, struct dbdma_regs* save)
}
}
-static void __pmac
+static void
dbdma_restore(struct macio_chip* macio, struct dbdma_regs* save)
{
int i;
@@ -547,7 +547,7 @@ dbdma_restore(struct macio_chip* macio, struct dbdma_regs* save)
}
}
-static void __pmac
+static void
heathrow_sleep(struct macio_chip* macio, int secondary)
{
if (secondary) {
@@ -580,7 +580,7 @@ heathrow_sleep(struct macio_chip* macio, int secondary)
(void)MACIO_IN32(HEATHROW_FCR);
}
-static void __pmac
+static void
heathrow_wakeup(struct macio_chip* macio, int secondary)
{
if (secondary) {
@@ -605,7 +605,7 @@ heathrow_wakeup(struct macio_chip* macio, int secondary)
}
}
-static long __pmac
+static long
heathrow_sleep_state(struct device_node* node, long param, long value)
{
if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
@@ -622,7 +622,7 @@ heathrow_sleep_state(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
core99_scc_enable(struct device_node* node, long param, long value)
{
struct macio_chip* macio;
@@ -723,7 +723,7 @@ core99_scc_enable(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
core99_modem_enable(struct device_node* node, long param, long value)
{
struct macio_chip* macio;
@@ -775,7 +775,7 @@ core99_modem_enable(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
pangea_modem_enable(struct device_node* node, long param, long value)
{
struct macio_chip* macio;
@@ -830,7 +830,7 @@ pangea_modem_enable(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
core99_ata100_enable(struct device_node* node, long value)
{
unsigned long flags;
@@ -860,7 +860,7 @@ core99_ata100_enable(struct device_node* node, long value)
return 0;
}
-static long __pmac
+static long
core99_ide_enable(struct device_node* node, long param, long value)
{
/* Bus ID 0 to 2 are KeyLargo based IDE, busID 3 is U2
@@ -883,7 +883,7 @@ core99_ide_enable(struct device_node* node, long param, long value)
}
}
-static long __pmac
+static long
core99_ide_reset(struct device_node* node, long param, long value)
{
switch(param) {
@@ -901,7 +901,7 @@ core99_ide_reset(struct device_node* node, long param, long value)
}
}
-static long __pmac
+static long
core99_gmac_enable(struct device_node* node, long param, long value)
{
unsigned long flags;
@@ -918,7 +918,7 @@ core99_gmac_enable(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
core99_gmac_phy_reset(struct device_node* node, long param, long value)
{
unsigned long flags;
@@ -943,7 +943,7 @@ core99_gmac_phy_reset(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
core99_sound_chip_enable(struct device_node* node, long param, long value)
{
struct macio_chip* macio;
@@ -973,7 +973,7 @@ core99_sound_chip_enable(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
core99_airport_enable(struct device_node* node, long param, long value)
{
struct macio_chip* macio;
@@ -1060,7 +1060,7 @@ core99_airport_enable(struct device_node* node, long param, long value)
}
#ifdef CONFIG_SMP
-static long __pmac
+static long
core99_reset_cpu(struct device_node* node, long param, long value)
{
unsigned int reset_io = 0;
@@ -1104,7 +1104,7 @@ core99_reset_cpu(struct device_node* node, long param, long value)
}
#endif /* CONFIG_SMP */
-static long __pmac
+static long
core99_usb_enable(struct device_node* node, long param, long value)
{
struct macio_chip* macio;
@@ -1257,7 +1257,7 @@ core99_usb_enable(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
core99_firewire_enable(struct device_node* node, long param, long value)
{
unsigned long flags;
@@ -1284,7 +1284,7 @@ core99_firewire_enable(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
core99_firewire_cable_power(struct device_node* node, long param, long value)
{
unsigned long flags;
@@ -1315,7 +1315,7 @@ core99_firewire_cable_power(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
intrepid_aack_delay_enable(struct device_node* node, long param, long value)
{
unsigned long flags;
@@ -1336,7 +1336,7 @@ intrepid_aack_delay_enable(struct device_node* node, long param, long value)
#endif /* CONFIG_POWER4 */
-static long __pmac
+static long
core99_read_gpio(struct device_node* node, long param, long value)
{
struct macio_chip* macio = &macio_chips[0];
@@ -1345,7 +1345,7 @@ core99_read_gpio(struct device_node* node, long param, long value)
}
-static long __pmac
+static long
core99_write_gpio(struct device_node* node, long param, long value)
{
struct macio_chip* macio = &macio_chips[0];
@@ -1356,7 +1356,7 @@ core99_write_gpio(struct device_node* node, long param, long value)
#ifdef CONFIG_POWER4
-static long __pmac
+static long
g5_gmac_enable(struct device_node* node, long param, long value)
{
struct macio_chip* macio = &macio_chips[0];
@@ -1380,7 +1380,7 @@ g5_gmac_enable(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
g5_fw_enable(struct device_node* node, long param, long value)
{
struct macio_chip* macio = &macio_chips[0];
@@ -1403,7 +1403,7 @@ g5_fw_enable(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
g5_mpic_enable(struct device_node* node, long param, long value)
{
unsigned long flags;
@@ -1419,7 +1419,7 @@ g5_mpic_enable(struct device_node* node, long param, long value)
}
#ifdef CONFIG_SMP
-static long __pmac
+static long
g5_reset_cpu(struct device_node* node, long param, long value)
{
unsigned int reset_io = 0;
@@ -1465,7 +1465,7 @@ g5_reset_cpu(struct device_node* node, long param, long value)
* This takes the second CPU off the bus on dual CPU machines
* running UP
*/
-void __pmac g5_phy_disable_cpu1(void)
+void g5_phy_disable_cpu1(void)
{
UN_OUT(U3_API_PHY_CONFIG_1, 0);
}
@@ -1474,7 +1474,7 @@ void __pmac g5_phy_disable_cpu1(void)
#ifndef CONFIG_POWER4
-static void __pmac
+static void
keylargo_shutdown(struct macio_chip* macio, int sleep_mode)
{
u32 temp;
@@ -1528,7 +1528,7 @@ keylargo_shutdown(struct macio_chip* macio, int sleep_mode)
(void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1);
}
-static void __pmac
+static void
pangea_shutdown(struct macio_chip* macio, int sleep_mode)
{
u32 temp;
@@ -1562,7 +1562,7 @@ pangea_shutdown(struct macio_chip* macio, int sleep_mode)
(void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1);
}
-static void __pmac
+static void
intrepid_shutdown(struct macio_chip* macio, int sleep_mode)
{
u32 temp;
@@ -1591,7 +1591,7 @@ intrepid_shutdown(struct macio_chip* macio, int sleep_mode)
}
-void __pmac pmac_tweak_clock_spreading(int enable)
+void pmac_tweak_clock_spreading(int enable)
{
struct macio_chip* macio = &macio_chips[0];
@@ -1698,7 +1698,7 @@ void __pmac pmac_tweak_clock_spreading(int enable)
}
-static int __pmac
+static int
core99_sleep(void)
{
struct macio_chip* macio;
@@ -1791,7 +1791,7 @@ core99_sleep(void)
return 0;
}
-static int __pmac
+static int
core99_wake_up(void)
{
struct macio_chip* macio;
@@ -1854,7 +1854,7 @@ core99_wake_up(void)
return 0;
}
-static long __pmac
+static long
core99_sleep_state(struct device_node* node, long param, long value)
{
/* Param == 1 means to enter the "fake sleep" mode that is
@@ -1884,7 +1884,7 @@ core99_sleep_state(struct device_node* node, long param, long value)
#endif /* CONFIG_POWER4 */
-static long __pmac
+static long
generic_dev_can_wake(struct device_node* node, long param, long value)
{
/* Todo: eventually check we are really dealing with on-board
@@ -1896,7 +1896,7 @@ generic_dev_can_wake(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
generic_get_mb_info(struct device_node* node, long param, long value)
{
switch(param) {
@@ -1919,7 +1919,7 @@ generic_get_mb_info(struct device_node* node, long param, long value)
/* Used on any machine
*/
-static struct feature_table_entry any_features[] __pmacdata = {
+static struct feature_table_entry any_features[] = {
{ PMAC_FTR_GET_MB_INFO, generic_get_mb_info },
{ PMAC_FTR_DEVICE_CAN_WAKE, generic_dev_can_wake },
{ 0, NULL }
@@ -1931,7 +1931,7 @@ static struct feature_table_entry any_features[] __pmacdata = {
* 2400,3400 and 3500 series powerbooks. Some older desktops seem
* to have issues with turning on/off those asic cells
*/
-static struct feature_table_entry ohare_features[] __pmacdata = {
+static struct feature_table_entry ohare_features[] = {
{ PMAC_FTR_SCC_ENABLE, ohare_htw_scc_enable },
{ PMAC_FTR_SWIM3_ENABLE, ohare_floppy_enable },
{ PMAC_FTR_MESH_ENABLE, ohare_mesh_enable },
@@ -1945,7 +1945,7 @@ static struct feature_table_entry ohare_features[] __pmacdata = {
* Separated as some features couldn't be properly tested
* and the serial port control bits appear to confuse it.
*/
-static struct feature_table_entry heathrow_desktop_features[] __pmacdata = {
+static struct feature_table_entry heathrow_desktop_features[] = {
{ PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable },
{ PMAC_FTR_MESH_ENABLE, heathrow_mesh_enable },
{ PMAC_FTR_IDE_ENABLE, heathrow_ide_enable },
@@ -1957,7 +1957,7 @@ static struct feature_table_entry heathrow_desktop_features[] __pmacdata = {
/* Heathrow based laptop, that is the Wallstreet and mainstreet
* powerbooks.
*/
-static struct feature_table_entry heathrow_laptop_features[] __pmacdata = {
+static struct feature_table_entry heathrow_laptop_features[] = {
{ PMAC_FTR_SCC_ENABLE, ohare_htw_scc_enable },
{ PMAC_FTR_MODEM_ENABLE, heathrow_modem_enable },
{ PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable },
@@ -1973,7 +1973,7 @@ static struct feature_table_entry heathrow_laptop_features[] __pmacdata = {
/* Paddington based machines
* The lombard (101) powerbook, first iMac models, B&W G3 and Yikes G4.
*/
-static struct feature_table_entry paddington_features[] __pmacdata = {
+static struct feature_table_entry paddington_features[] = {
{ PMAC_FTR_SCC_ENABLE, ohare_htw_scc_enable },
{ PMAC_FTR_MODEM_ENABLE, heathrow_modem_enable },
{ PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable },
@@ -1991,7 +1991,7 @@ static struct feature_table_entry paddington_features[] __pmacdata = {
* chipset. The pangea chipset is the "combo" UniNorth/KeyLargo
* used on iBook2 & iMac "flow power".
*/
-static struct feature_table_entry core99_features[] __pmacdata = {
+static struct feature_table_entry core99_features[] = {
{ PMAC_FTR_SCC_ENABLE, core99_scc_enable },
{ PMAC_FTR_MODEM_ENABLE, core99_modem_enable },
{ PMAC_FTR_IDE_ENABLE, core99_ide_enable },
@@ -2014,7 +2014,7 @@ static struct feature_table_entry core99_features[] __pmacdata = {
/* RackMac
*/
-static struct feature_table_entry rackmac_features[] __pmacdata = {
+static struct feature_table_entry rackmac_features[] = {
{ PMAC_FTR_SCC_ENABLE, core99_scc_enable },
{ PMAC_FTR_IDE_ENABLE, core99_ide_enable },
{ PMAC_FTR_IDE_RESET, core99_ide_reset },
@@ -2034,7 +2034,7 @@ static struct feature_table_entry rackmac_features[] __pmacdata = {
/* Pangea features
*/
-static struct feature_table_entry pangea_features[] __pmacdata = {
+static struct feature_table_entry pangea_features[] = {
{ PMAC_FTR_SCC_ENABLE, core99_scc_enable },
{ PMAC_FTR_MODEM_ENABLE, pangea_modem_enable },
{ PMAC_FTR_IDE_ENABLE, core99_ide_enable },
@@ -2054,7 +2054,7 @@ static struct feature_table_entry pangea_features[] __pmacdata = {
/* Intrepid features
*/
-static struct feature_table_entry intrepid_features[] __pmacdata = {
+static struct feature_table_entry intrepid_features[] = {
{ PMAC_FTR_SCC_ENABLE, core99_scc_enable },
{ PMAC_FTR_MODEM_ENABLE, pangea_modem_enable },
{ PMAC_FTR_IDE_ENABLE, core99_ide_enable },
@@ -2077,7 +2077,7 @@ static struct feature_table_entry intrepid_features[] __pmacdata = {
/* G5 features
*/
-static struct feature_table_entry g5_features[] __pmacdata = {
+static struct feature_table_entry g5_features[] = {
{ PMAC_FTR_GMAC_ENABLE, g5_gmac_enable },
{ PMAC_FTR_1394_ENABLE, g5_fw_enable },
{ PMAC_FTR_ENABLE_MPIC, g5_mpic_enable },
@@ -2091,7 +2091,7 @@ static struct feature_table_entry g5_features[] __pmacdata = {
#endif /* CONFIG_POWER4 */
-static struct pmac_mb_def pmac_mb_defs[] __pmacdata = {
+static struct pmac_mb_def pmac_mb_defs[] = {
#ifndef CONFIG_POWER4
/*
* Desktops
@@ -2356,7 +2356,7 @@ static struct pmac_mb_def pmac_mb_defs[] __pmacdata = {
/*
* The toplevel feature_call callback
*/
-long __pmac
+long
pmac_do_feature_call(unsigned int selector, ...)
{
struct device_node* node;
@@ -2939,8 +2939,8 @@ void __init pmac_check_ht_link(void)
* Early video resume hook
*/
-static void (*pmac_early_vresume_proc)(void *data) __pmacdata;
-static void *pmac_early_vresume_data __pmacdata;
+static void (*pmac_early_vresume_proc)(void *data);
+static void *pmac_early_vresume_data;
void pmac_set_early_video_resume(void (*proc)(void *data), void *data)
{
@@ -2953,7 +2953,7 @@ void pmac_set_early_video_resume(void (*proc)(void *data), void *data)
}
EXPORT_SYMBOL(pmac_set_early_video_resume);
-void __pmac pmac_call_early_video_resume(void)
+void pmac_call_early_video_resume(void)
{
if (pmac_early_vresume_proc)
pmac_early_vresume_proc(pmac_early_vresume_data);
@@ -2963,11 +2963,11 @@ void __pmac pmac_call_early_video_resume(void)
* AGP related suspend/resume code
*/
-static struct pci_dev *pmac_agp_bridge __pmacdata;
-static int (*pmac_agp_suspend)(struct pci_dev *bridge) __pmacdata;
-static int (*pmac_agp_resume)(struct pci_dev *bridge) __pmacdata;
+static struct pci_dev *pmac_agp_bridge;
+static int (*pmac_agp_suspend)(struct pci_dev *bridge);
+static int (*pmac_agp_resume)(struct pci_dev *bridge);
-void __pmac pmac_register_agp_pm(struct pci_dev *bridge,
+void pmac_register_agp_pm(struct pci_dev *bridge,
int (*suspend)(struct pci_dev *bridge),
int (*resume)(struct pci_dev *bridge))
{
@@ -2984,7 +2984,7 @@ void __pmac pmac_register_agp_pm(struct pci_dev *bridge,
}
EXPORT_SYMBOL(pmac_register_agp_pm);
-void __pmac pmac_suspend_agp_for_card(struct pci_dev *dev)
+void pmac_suspend_agp_for_card(struct pci_dev *dev)
{
if (pmac_agp_bridge == NULL || pmac_agp_suspend == NULL)
return;
@@ -2994,7 +2994,7 @@ void __pmac pmac_suspend_agp_for_card(struct pci_dev *dev)
}
EXPORT_SYMBOL(pmac_suspend_agp_for_card);
-void __pmac pmac_resume_agp_for_card(struct pci_dev *dev)
+void pmac_resume_agp_for_card(struct pci_dev *dev)
{
if (pmac_agp_bridge == NULL || pmac_agp_resume == NULL)
return;
diff --git a/arch/ppc/platforms/pmac_nvram.c b/arch/ppc/platforms/pmac_nvram.c
index c9de64205996..8c9b008c7226 100644
--- a/arch/ppc/platforms/pmac_nvram.c
+++ b/arch/ppc/platforms/pmac_nvram.c
@@ -88,17 +88,17 @@ extern int system_running;
static int (*core99_write_bank)(int bank, u8* datas);
static int (*core99_erase_bank)(int bank);
-static char *nvram_image __pmacdata;
+static char *nvram_image;
-static unsigned char __pmac core99_nvram_read_byte(int addr)
+static unsigned char core99_nvram_read_byte(int addr)
{
if (nvram_image == NULL)
return 0xff;
return nvram_image[addr];
}
-static void __pmac core99_nvram_write_byte(int addr, unsigned char val)
+static void core99_nvram_write_byte(int addr, unsigned char val)
{
if (nvram_image == NULL)
return;
@@ -106,18 +106,18 @@ static void __pmac core99_nvram_write_byte(int addr, unsigned char val)
}
-static unsigned char __openfirmware direct_nvram_read_byte(int addr)
+static unsigned char direct_nvram_read_byte(int addr)
{
return in_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult]);
}
-static void __openfirmware direct_nvram_write_byte(int addr, unsigned char val)
+static void direct_nvram_write_byte(int addr, unsigned char val)
{
out_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult], val);
}
-static unsigned char __pmac indirect_nvram_read_byte(int addr)
+static unsigned char indirect_nvram_read_byte(int addr)
{
unsigned char val;
unsigned long flags;
@@ -130,7 +130,7 @@ static unsigned char __pmac indirect_nvram_read_byte(int addr)
return val;
}
-static void __pmac indirect_nvram_write_byte(int addr, unsigned char val)
+static void indirect_nvram_write_byte(int addr, unsigned char val)
{
unsigned long flags;
@@ -143,13 +143,13 @@ static void __pmac indirect_nvram_write_byte(int addr, unsigned char val)
#ifdef CONFIG_ADB_PMU
-static void __pmac pmu_nvram_complete(struct adb_request *req)
+static void pmu_nvram_complete(struct adb_request *req)
{
if (req->arg)
complete((struct completion *)req->arg);
}
-static unsigned char __pmac pmu_nvram_read_byte(int addr)
+static unsigned char pmu_nvram_read_byte(int addr)
{
struct adb_request req;
DECLARE_COMPLETION(req_complete);
@@ -165,7 +165,7 @@ static unsigned char __pmac pmu_nvram_read_byte(int addr)
return req.reply[0];
}
-static void __pmac pmu_nvram_write_byte(int addr, unsigned char val)
+static void pmu_nvram_write_byte(int addr, unsigned char val)
{
struct adb_request req;
DECLARE_COMPLETION(req_complete);
@@ -183,7 +183,7 @@ static void __pmac pmu_nvram_write_byte(int addr, unsigned char val)
#endif /* CONFIG_ADB_PMU */
-static u8 __pmac chrp_checksum(struct chrp_header* hdr)
+static u8 chrp_checksum(struct chrp_header* hdr)
{
u8 *ptr;
u16 sum = hdr->signature;
@@ -194,7 +194,7 @@ static u8 __pmac chrp_checksum(struct chrp_header* hdr)
return sum;
}
-static u32 __pmac core99_calc_adler(u8 *buffer)
+static u32 core99_calc_adler(u8 *buffer)
{
int cnt;
u32 low, high;
@@ -216,7 +216,7 @@ static u32 __pmac core99_calc_adler(u8 *buffer)
return (high << 16) | low;
}
-static u32 __pmac core99_check(u8* datas)
+static u32 core99_check(u8* datas)
{
struct core99_header* hdr99 = (struct core99_header*)datas;
@@ -235,7 +235,7 @@ static u32 __pmac core99_check(u8* datas)
return hdr99->generation;
}
-static int __pmac sm_erase_bank(int bank)
+static int sm_erase_bank(int bank)
{
int stat, i;
unsigned long timeout;
@@ -267,7 +267,7 @@ static int __pmac sm_erase_bank(int bank)
return 0;
}
-static int __pmac sm_write_bank(int bank, u8* datas)
+static int sm_write_bank(int bank, u8* datas)
{
int i, stat = 0;
unsigned long timeout;
@@ -302,7 +302,7 @@ static int __pmac sm_write_bank(int bank, u8* datas)
return 0;
}
-static int __pmac amd_erase_bank(int bank)
+static int amd_erase_bank(int bank)
{
int i, stat = 0;
unsigned long timeout;
@@ -349,7 +349,7 @@ static int __pmac amd_erase_bank(int bank)
return 0;
}
-static int __pmac amd_write_bank(int bank, u8* datas)
+static int amd_write_bank(int bank, u8* datas)
{
int i, stat = 0;
unsigned long timeout;
@@ -430,7 +430,7 @@ static void __init lookup_partitions(void)
DBG("nvram: NR partition at 0x%x\n", nvram_partitions[pmac_nvram_NR]);
}
-static void __pmac core99_nvram_sync(void)
+static void core99_nvram_sync(void)
{
struct core99_header* hdr99;
unsigned long flags;
@@ -554,12 +554,12 @@ void __init pmac_nvram_init(void)
lookup_partitions();
}
-int __pmac pmac_get_partition(int partition)
+int pmac_get_partition(int partition)
{
return nvram_partitions[partition];
}
-u8 __pmac pmac_xpram_read(int xpaddr)
+u8 pmac_xpram_read(int xpaddr)
{
int offset = nvram_partitions[pmac_nvram_XPRAM];
@@ -569,7 +569,7 @@ u8 __pmac pmac_xpram_read(int xpaddr)
return ppc_md.nvram_read_val(xpaddr + offset);
}
-void __pmac pmac_xpram_write(int xpaddr, u8 data)
+void pmac_xpram_write(int xpaddr, u8 data)
{
int offset = nvram_partitions[pmac_nvram_XPRAM];
diff --git a/arch/ppc/platforms/pmac_pci.c b/arch/ppc/platforms/pmac_pci.c
index 719fb49fe2bc..786295b6ddd0 100644
--- a/arch/ppc/platforms/pmac_pci.c
+++ b/arch/ppc/platforms/pmac_pci.c
@@ -141,7 +141,7 @@ fixup_bus_range(struct device_node *bridge)
|(((unsigned long)(off)) & 0xFCUL) \
|1UL)
-static void volatile __iomem * __pmac
+static void volatile __iomem *
macrisc_cfg_access(struct pci_controller* hose, u8 bus, u8 dev_fn, u8 offset)
{
unsigned int caddr;
@@ -162,7 +162,7 @@ macrisc_cfg_access(struct pci_controller* hose, u8 bus, u8 dev_fn, u8 offset)
return hose->cfg_data + offset;
}
-static int __pmac
+static int
macrisc_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
int len, u32 *val)
{
@@ -190,7 +190,7 @@ macrisc_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
return PCIBIOS_SUCCESSFUL;
}
-static int __pmac
+static int
macrisc_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
int len, u32 val)
{
@@ -230,7 +230,7 @@ static struct pci_ops macrisc_pci_ops =
/*
* Verifiy that a specific (bus, dev_fn) exists on chaos
*/
-static int __pmac
+static int
chaos_validate_dev(struct pci_bus *bus, int devfn, int offset)
{
struct device_node *np;
@@ -252,7 +252,7 @@ chaos_validate_dev(struct pci_bus *bus, int devfn, int offset)
return PCIBIOS_SUCCESSFUL;
}
-static int __pmac
+static int
chaos_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
int len, u32 *val)
{
@@ -264,7 +264,7 @@ chaos_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
return macrisc_read_config(bus, devfn, offset, len, val);
}
-static int __pmac
+static int
chaos_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
int len, u32 val)
{
@@ -294,7 +294,7 @@ static struct pci_ops chaos_pci_ops =
+ (((unsigned long)bus) << 16) \
+ 0x01000000UL)
-static void volatile __iomem * __pmac
+static void volatile __iomem *
u3_ht_cfg_access(struct pci_controller* hose, u8 bus, u8 devfn, u8 offset)
{
if (bus == hose->first_busno) {
@@ -307,7 +307,7 @@ u3_ht_cfg_access(struct pci_controller* hose, u8 bus, u8 devfn, u8 offset)
return hose->cfg_data + U3_HT_CFA1(bus, devfn, offset);
}
-static int __pmac
+static int
u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
int len, u32 *val)
{
@@ -357,7 +357,7 @@ u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
return PCIBIOS_SUCCESSFUL;
}
-static int __pmac
+static int
u3_ht_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
int len, u32 val)
{
@@ -575,7 +575,7 @@ pmac_find_bridges(void)
* some offset between bus number and domains for now when we
* assign all busses should help for now
*/
- if (pci_assign_all_busses)
+ if (pci_assign_all_buses)
pcibios_assign_bus_offset = 0x10;
#ifdef CONFIG_POWER4
@@ -643,7 +643,7 @@ static inline void grackle_set_loop_snoop(struct pci_controller *bp, int enable)
static int __init
setup_uninorth(struct pci_controller* hose, struct reg_property* addr)
{
- pci_assign_all_busses = 1;
+ pci_assign_all_buses = 1;
has_uninorth = 1;
hose->ops = &macrisc_pci_ops;
hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000);
@@ -677,7 +677,7 @@ setup_u3_agp(struct pci_controller* hose, struct reg_property* addr)
{
/* On G5, we move AGP up to high bus number so we don't need
* to reassign bus numbers for HT. If we ever have P2P bridges
- * on AGP, we'll have to move pci_assign_all_busses to the
+ * on AGP, we'll have to move pci_assign_all_buses to the
* pci_controller structure so we enable it for AGP and not for
* HT childs.
* We hard code the address because of the different size of
@@ -899,7 +899,7 @@ pmac_pcibios_fixup(void)
pcibios_fixup_OF_interrupts();
}
-int __pmac
+int
pmac_pci_enable_device_hook(struct pci_dev *dev, int initial)
{
struct device_node* node;
@@ -1096,7 +1096,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pmac_pci_fixup_pciata);
* Disable second function on K2-SATA, it's broken
* and disable IO BARs on first one
*/
-void __pmac pmac_pci_fixup_k2_sata(struct pci_dev* dev)
+void pmac_pci_fixup_k2_sata(struct pci_dev* dev)
{
int i;
u16 cmd;
diff --git a/arch/ppc/platforms/pmac_pic.c b/arch/ppc/platforms/pmac_pic.c
index 2ce058895e03..9f2d95ea8564 100644
--- a/arch/ppc/platforms/pmac_pic.c
+++ b/arch/ppc/platforms/pmac_pic.c
@@ -35,6 +35,7 @@
#include <asm/open_pic.h>
#include <asm/xmon.h>
#include <asm/pmac_feature.h>
+#include <asm/machdep.h>
#include "pmac_pic.h"
@@ -53,7 +54,7 @@ struct pmac_irq_hw {
};
/* Default addresses */
-static volatile struct pmac_irq_hw *pmac_irq_hw[4] __pmacdata = {
+static volatile struct pmac_irq_hw *pmac_irq_hw[4] = {
(struct pmac_irq_hw *) 0xf3000020,
(struct pmac_irq_hw *) 0xf3000010,
(struct pmac_irq_hw *) 0xf4000020,
@@ -64,22 +65,22 @@ static volatile struct pmac_irq_hw *pmac_irq_hw[4] __pmacdata = {
#define OHARE_LEVEL_MASK 0x1ff00000
#define HEATHROW_LEVEL_MASK 0x1ff00000
-static int max_irqs __pmacdata;
-static int max_real_irqs __pmacdata;
-static u32 level_mask[4] __pmacdata;
+static int max_irqs;
+static int max_real_irqs;
+static u32 level_mask[4];
-static DEFINE_SPINLOCK(pmac_pic_lock __pmacdata);
+static DEFINE_SPINLOCK(pmac_pic_lock);
#define GATWICK_IRQ_POOL_SIZE 10
-static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE] __pmacdata;
+static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE];
/*
* Mark an irq as "lost". This is only used on the pmac
* since it can lose interrupts (see pmac_set_irq_mask).
* -- Cort
*/
-void __pmac
+void
__set_lost(unsigned long irq_nr, int nokick)
{
if (!test_and_set_bit(irq_nr, ppc_lost_interrupts)) {
@@ -89,7 +90,7 @@ __set_lost(unsigned long irq_nr, int nokick)
}
}
-static void __pmac
+static void
pmac_mask_and_ack_irq(unsigned int irq_nr)
{
unsigned long bit = 1UL << (irq_nr & 0x1f);
@@ -114,7 +115,7 @@ pmac_mask_and_ack_irq(unsigned int irq_nr)
spin_unlock_irqrestore(&pmac_pic_lock, flags);
}
-static void __pmac pmac_set_irq_mask(unsigned int irq_nr, int nokicklost)
+static void pmac_set_irq_mask(unsigned int irq_nr, int nokicklost)
{
unsigned long bit = 1UL << (irq_nr & 0x1f);
int i = irq_nr >> 5;
@@ -147,7 +148,7 @@ static void __pmac pmac_set_irq_mask(unsigned int irq_nr, int nokicklost)
/* When an irq gets requested for the first client, if it's an
* edge interrupt, we clear any previous one on the controller
*/
-static unsigned int __pmac pmac_startup_irq(unsigned int irq_nr)
+static unsigned int pmac_startup_irq(unsigned int irq_nr)
{
unsigned long bit = 1UL << (irq_nr & 0x1f);
int i = irq_nr >> 5;
@@ -160,20 +161,20 @@ static unsigned int __pmac pmac_startup_irq(unsigned int irq_nr)
return 0;
}
-static void __pmac pmac_mask_irq(unsigned int irq_nr)
+static void pmac_mask_irq(unsigned int irq_nr)
{
clear_bit(irq_nr, ppc_cached_irq_mask);
pmac_set_irq_mask(irq_nr, 0);
mb();
}
-static void __pmac pmac_unmask_irq(unsigned int irq_nr)
+static void pmac_unmask_irq(unsigned int irq_nr)
{
set_bit(irq_nr, ppc_cached_irq_mask);
pmac_set_irq_mask(irq_nr, 0);
}
-static void __pmac pmac_end_irq(unsigned int irq_nr)
+static void pmac_end_irq(unsigned int irq_nr)
{
if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))
&& irq_desc[irq_nr].action) {
diff --git a/arch/ppc/platforms/pmac_setup.c b/arch/ppc/platforms/pmac_setup.c
index d6356f480d90..55d2beffe560 100644
--- a/arch/ppc/platforms/pmac_setup.c
+++ b/arch/ppc/platforms/pmac_setup.c
@@ -122,7 +122,7 @@ extern struct smp_ops_t psurge_smp_ops;
extern struct smp_ops_t core99_smp_ops;
#endif /* CONFIG_SMP */
-static int __pmac
+static int
pmac_show_cpuinfo(struct seq_file *m)
{
struct device_node *np;
@@ -226,7 +226,7 @@ pmac_show_cpuinfo(struct seq_file *m)
return 0;
}
-static int __openfirmware
+static int
pmac_show_percpuinfo(struct seq_file *m, int i)
{
#ifdef CONFIG_CPU_FREQ_PMAC
@@ -330,9 +330,9 @@ pmac_setup_arch(void)
#ifdef CONFIG_SMP
/* Check for Core99 */
if (find_devices("uni-n") || find_devices("u3"))
- ppc_md.smp_ops = &core99_smp_ops;
+ smp_ops = &core99_smp_ops;
else
- ppc_md.smp_ops = &psurge_smp_ops;
+ smp_ops = &psurge_smp_ops;
#endif /* CONFIG_SMP */
pci_create_OF_bus_map();
@@ -447,7 +447,7 @@ static int pmac_pm_enter(suspend_state_t state)
enable_kernel_fp();
#ifdef CONFIG_ALTIVEC
- if (cur_cpu_spec[0]->cpu_features & CPU_FTR_ALTIVEC)
+ if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC)
enable_kernel_altivec();
#endif /* CONFIG_ALTIVEC */
@@ -485,7 +485,7 @@ static int pmac_late_init(void)
late_initcall(pmac_late_init);
/* can't be __init - can be called whenever a disk is first accessed */
-void __pmac
+void
note_bootable_part(dev_t dev, int part, int goodness)
{
static int found_boot = 0;
@@ -511,7 +511,7 @@ note_bootable_part(dev_t dev, int part, int goodness)
}
}
-static void __pmac
+static void
pmac_restart(char *cmd)
{
#ifdef CONFIG_ADB_CUDA
@@ -536,7 +536,7 @@ pmac_restart(char *cmd)
}
}
-static void __pmac
+static void
pmac_power_off(void)
{
#ifdef CONFIG_ADB_CUDA
@@ -561,7 +561,7 @@ pmac_power_off(void)
}
}
-static void __pmac
+static void
pmac_halt(void)
{
pmac_power_off();
@@ -661,7 +661,6 @@ pmac_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.setup_arch = pmac_setup_arch;
ppc_md.show_cpuinfo = pmac_show_cpuinfo;
ppc_md.show_percpuinfo = pmac_show_percpuinfo;
- ppc_md.irq_canonicalize = NULL;
ppc_md.init_IRQ = pmac_pic_init;
ppc_md.get_irq = pmac_get_irq; /* Changed later on ... */
diff --git a/arch/ppc/platforms/pmac_sleep.S b/arch/ppc/platforms/pmac_sleep.S
index 88419c77ac43..22b113d19b24 100644
--- a/arch/ppc/platforms/pmac_sleep.S
+++ b/arch/ppc/platforms/pmac_sleep.S
@@ -387,10 +387,10 @@ turn_on_mmu:
#endif /* defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ) */
.section .data
- .balign L1_CACHE_LINE_SIZE
+ .balign L1_CACHE_BYTES
sleep_storage:
.long 0
- .balign L1_CACHE_LINE_SIZE, 0
+ .balign L1_CACHE_BYTES, 0
#endif /* CONFIG_6xx */
.section .text
diff --git a/arch/ppc/platforms/pmac_smp.c b/arch/ppc/platforms/pmac_smp.c
index 794a23994b82..26ff26238f03 100644
--- a/arch/ppc/platforms/pmac_smp.c
+++ b/arch/ppc/platforms/pmac_smp.c
@@ -186,7 +186,7 @@ static inline void psurge_clr_ipi(int cpu)
*/
static unsigned long psurge_smp_message[NR_CPUS];
-void __pmac psurge_smp_message_recv(struct pt_regs *regs)
+void psurge_smp_message_recv(struct pt_regs *regs)
{
int cpu = smp_processor_id();
int msg;
@@ -203,14 +203,13 @@ void __pmac psurge_smp_message_recv(struct pt_regs *regs)
smp_message_recv(msg, regs);
}
-irqreturn_t __pmac psurge_primary_intr(int irq, void *d, struct pt_regs *regs)
+irqreturn_t psurge_primary_intr(int irq, void *d, struct pt_regs *regs)
{
psurge_smp_message_recv(regs);
return IRQ_HANDLED;
}
-static void __pmac smp_psurge_message_pass(int target, int msg, unsigned long data,
- int wait)
+static void smp_psurge_message_pass(int target, int msg)
{
int i;
@@ -629,7 +628,7 @@ void smp_core99_give_timebase(void)
/* PowerSurge-style Macs */
-struct smp_ops_t psurge_smp_ops __pmacdata = {
+struct smp_ops_t psurge_smp_ops = {
.message_pass = smp_psurge_message_pass,
.probe = smp_psurge_probe,
.kick_cpu = smp_psurge_kick_cpu,
@@ -639,7 +638,7 @@ struct smp_ops_t psurge_smp_ops __pmacdata = {
};
/* Core99 Macs (dual G4s) */
-struct smp_ops_t core99_smp_ops __pmacdata = {
+struct smp_ops_t core99_smp_ops = {
.message_pass = smp_openpic_message_pass,
.probe = smp_core99_probe,
.kick_cpu = smp_core99_kick_cpu,
diff --git a/arch/ppc/platforms/pmac_time.c b/arch/ppc/platforms/pmac_time.c
index efb819f9490d..edb9fcc64790 100644
--- a/arch/ppc/platforms/pmac_time.c
+++ b/arch/ppc/platforms/pmac_time.c
@@ -77,7 +77,7 @@ pmac_time_init(void)
#endif
}
-unsigned long __pmac
+unsigned long
pmac_get_rtc_time(void)
{
#if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU)
@@ -118,7 +118,7 @@ pmac_get_rtc_time(void)
return 0;
}
-int __pmac
+int
pmac_set_rtc_time(unsigned long nowtime)
{
#if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU)
@@ -210,7 +210,7 @@ via_calibrate_decr(void)
/*
* Reset the time after a sleep.
*/
-static int __pmac
+static int
time_sleep_notify(struct pmu_sleep_notifier *self, int when)
{
static unsigned long time_diff;
@@ -235,7 +235,7 @@ time_sleep_notify(struct pmu_sleep_notifier *self, int when)
return PBOOK_SLEEP_OK;
}
-static struct pmu_sleep_notifier time_sleep_notifier __pmacdata = {
+static struct pmu_sleep_notifier time_sleep_notifier = {
time_sleep_notify, SLEEP_LEVEL_MISC,
};
#endif /* CONFIG_PM */
diff --git a/arch/ppc/platforms/pplus.c b/arch/ppc/platforms/pplus.c
index e70aae20d6f9..22bd40cfb092 100644
--- a/arch/ppc/platforms/pplus.c
+++ b/arch/ppc/platforms/pplus.c
@@ -646,14 +646,6 @@ static void pplus_power_off(void)
pplus_halt();
}
-static unsigned int pplus_irq_canonicalize(u_int irq)
-{
- if (irq == 2)
- return 9;
- else
- return irq;
-}
-
static void __init pplus_init_IRQ(void)
{
int i;
@@ -673,10 +665,7 @@ static void __init pplus_init_IRQ(void)
ppc_md.get_irq = openpic_get_irq;
}
- for (i = 0; i < NUM_8259_INTERRUPTS; i++)
- irq_desc[i].handler = &i8259_pic;
-
- i8259_init(0);
+ i8259_init(0, 0);
if (ppc_md.progress)
ppc_md.progress("init_irq: exit", 0);
@@ -872,10 +861,10 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
ISA_DMA_THRESHOLD = 0x00ffffff;
DMA_MODE_READ = 0x44;
DMA_MODE_WRITE = 0x48;
+ ppc_do_canonicalize_irqs = 1;
ppc_md.setup_arch = pplus_setup_arch;
ppc_md.show_cpuinfo = pplus_show_cpuinfo;
- ppc_md.irq_canonicalize = pplus_irq_canonicalize;
ppc_md.init_IRQ = pplus_init_IRQ;
/* this gets changed later on if we have an OpenPIC -- Cort */
ppc_md.get_irq = i8259_irq;
@@ -911,6 +900,6 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.kgdb_map_scc = gen550_kgdb_map_scc;
#endif
#ifdef CONFIG_SMP
- ppc_md.smp_ops = &pplus_smp_ops;
+ smp_ops = &pplus_smp_ops;
#endif /* CONFIG_SMP */
}
diff --git a/arch/ppc/platforms/prep_pci.c b/arch/ppc/platforms/prep_pci.c
index 4760cb64251d..e50b9996848c 100644
--- a/arch/ppc/platforms/prep_pci.c
+++ b/arch/ppc/platforms/prep_pci.c
@@ -43,7 +43,7 @@ static unsigned long *ProcInfo;
/* Tables for known hardware */
/* Motorola PowerStackII - Utah */
-static char Utah_pci_IRQ_map[23] __prepdata =
+static char Utah_pci_IRQ_map[23] =
{
0, /* Slot 0 - unused */
0, /* Slot 1 - unused */
@@ -72,7 +72,7 @@ static char Utah_pci_IRQ_map[23] __prepdata =
0, /* Slot 22 - unused */
};
-static char Utah_pci_IRQ_routes[] __prepdata =
+static char Utah_pci_IRQ_routes[] =
{
0, /* Line 0 - Unused */
9, /* Line 1 */
@@ -84,7 +84,7 @@ static char Utah_pci_IRQ_routes[] __prepdata =
/* Motorola PowerStackII - Omaha */
/* no integrated SCSI or ethernet */
-static char Omaha_pci_IRQ_map[23] __prepdata =
+static char Omaha_pci_IRQ_map[23] =
{
0, /* Slot 0 - unused */
0, /* Slot 1 - unused */
@@ -111,7 +111,7 @@ static char Omaha_pci_IRQ_map[23] __prepdata =
0,
};
-static char Omaha_pci_IRQ_routes[] __prepdata =
+static char Omaha_pci_IRQ_routes[] =
{
0, /* Line 0 - Unused */
9, /* Line 1 */
@@ -121,7 +121,7 @@ static char Omaha_pci_IRQ_routes[] __prepdata =
};
/* Motorola PowerStack */
-static char Blackhawk_pci_IRQ_map[19] __prepdata =
+static char Blackhawk_pci_IRQ_map[19] =
{
0, /* Slot 0 - unused */
0, /* Slot 1 - unused */
@@ -144,7 +144,7 @@ static char Blackhawk_pci_IRQ_map[19] __prepdata =
3, /* Slot P5 */
};
-static char Blackhawk_pci_IRQ_routes[] __prepdata =
+static char Blackhawk_pci_IRQ_routes[] =
{
0, /* Line 0 - Unused */
9, /* Line 1 */
@@ -154,7 +154,7 @@ static char Blackhawk_pci_IRQ_routes[] __prepdata =
};
/* Motorola Mesquite */
-static char Mesquite_pci_IRQ_map[23] __prepdata =
+static char Mesquite_pci_IRQ_map[23] =
{
0, /* Slot 0 - unused */
0, /* Slot 1 - unused */
@@ -182,7 +182,7 @@ static char Mesquite_pci_IRQ_map[23] __prepdata =
};
/* Motorola Sitka */
-static char Sitka_pci_IRQ_map[21] __prepdata =
+static char Sitka_pci_IRQ_map[21] =
{
0, /* Slot 0 - unused */
0, /* Slot 1 - unused */
@@ -208,7 +208,7 @@ static char Sitka_pci_IRQ_map[21] __prepdata =
};
/* Motorola MTX */
-static char MTX_pci_IRQ_map[23] __prepdata =
+static char MTX_pci_IRQ_map[23] =
{
0, /* Slot 0 - unused */
0, /* Slot 1 - unused */
@@ -237,7 +237,7 @@ static char MTX_pci_IRQ_map[23] __prepdata =
/* Motorola MTX Plus */
/* Secondary bus interrupt routing is not supported yet */
-static char MTXplus_pci_IRQ_map[23] __prepdata =
+static char MTXplus_pci_IRQ_map[23] =
{
0, /* Slot 0 - unused */
0, /* Slot 1 - unused */
@@ -264,13 +264,13 @@ static char MTXplus_pci_IRQ_map[23] __prepdata =
0, /* Slot 22 - unused */
};
-static char Raven_pci_IRQ_routes[] __prepdata =
+static char Raven_pci_IRQ_routes[] =
{
0, /* This is a dummy structure */
};
/* Motorola MVME16xx */
-static char Genesis_pci_IRQ_map[16] __prepdata =
+static char Genesis_pci_IRQ_map[16] =
{
0, /* Slot 0 - unused */
0, /* Slot 1 - unused */
@@ -290,7 +290,7 @@ static char Genesis_pci_IRQ_map[16] __prepdata =
0, /* Slot 15 - unused */
};
-static char Genesis_pci_IRQ_routes[] __prepdata =
+static char Genesis_pci_IRQ_routes[] =
{
0, /* Line 0 - Unused */
10, /* Line 1 */
@@ -299,7 +299,7 @@ static char Genesis_pci_IRQ_routes[] __prepdata =
15 /* Line 4 */
};
-static char Genesis2_pci_IRQ_map[23] __prepdata =
+static char Genesis2_pci_IRQ_map[23] =
{
0, /* Slot 0 - unused */
0, /* Slot 1 - unused */
@@ -327,7 +327,7 @@ static char Genesis2_pci_IRQ_map[23] __prepdata =
};
/* Motorola Series-E */
-static char Comet_pci_IRQ_map[23] __prepdata =
+static char Comet_pci_IRQ_map[23] =
{
0, /* Slot 0 - unused */
0, /* Slot 1 - unused */
@@ -354,7 +354,7 @@ static char Comet_pci_IRQ_map[23] __prepdata =
0,
};
-static char Comet_pci_IRQ_routes[] __prepdata =
+static char Comet_pci_IRQ_routes[] =
{
0, /* Line 0 - Unused */
10, /* Line 1 */
@@ -364,7 +364,7 @@ static char Comet_pci_IRQ_routes[] __prepdata =
};
/* Motorola Series-EX */
-static char Comet2_pci_IRQ_map[23] __prepdata =
+static char Comet2_pci_IRQ_map[23] =
{
0, /* Slot 0 - unused */
0, /* Slot 1 - unused */
@@ -391,7 +391,7 @@ static char Comet2_pci_IRQ_map[23] __prepdata =
0,
};
-static char Comet2_pci_IRQ_routes[] __prepdata =
+static char Comet2_pci_IRQ_routes[] =
{
0, /* Line 0 - Unused */
10, /* Line 1 */
@@ -405,7 +405,7 @@ static char Comet2_pci_IRQ_routes[] __prepdata =
* This is actually based on the Carolina motherboard
* -- Cort
*/
-static char ibm8xx_pci_IRQ_map[23] __prepdata = {
+static char ibm8xx_pci_IRQ_map[23] = {
0, /* Slot 0 - unused */
0, /* Slot 1 - unused */
0, /* Slot 2 - unused */
@@ -431,7 +431,7 @@ static char ibm8xx_pci_IRQ_map[23] __prepdata = {
2, /* Slot 22 - PCI slot 1 PCIINTx# (See below) */
};
-static char ibm8xx_pci_IRQ_routes[] __prepdata = {
+static char ibm8xx_pci_IRQ_routes[] = {
0, /* Line 0 - unused */
15, /* Line 1 */
15, /* Line 2 */
@@ -443,7 +443,7 @@ static char ibm8xx_pci_IRQ_routes[] __prepdata = {
* a 6015 ibm board
* -- Cort
*/
-static char ibm6015_pci_IRQ_map[23] __prepdata = {
+static char ibm6015_pci_IRQ_map[23] = {
0, /* Slot 0 - unused */
0, /* Slot 1 - unused */
0, /* Slot 2 - unused */
@@ -469,7 +469,7 @@ static char ibm6015_pci_IRQ_map[23] __prepdata = {
2, /* Slot 22 - */
};
-static char ibm6015_pci_IRQ_routes[] __prepdata = {
+static char ibm6015_pci_IRQ_routes[] = {
0, /* Line 0 - unused */
13, /* Line 1 */
15, /* Line 2 */
@@ -479,7 +479,7 @@ static char ibm6015_pci_IRQ_routes[] __prepdata = {
/* IBM Nobis and Thinkpad 850 */
-static char Nobis_pci_IRQ_map[23] __prepdata ={
+static char Nobis_pci_IRQ_map[23] ={
0, /* Slot 0 - unused */
0, /* Slot 1 - unused */
0, /* Slot 2 - unused */
@@ -498,7 +498,7 @@ static char Nobis_pci_IRQ_map[23] __prepdata ={
0, /* Slot 15 - unused */
};
-static char Nobis_pci_IRQ_routes[] __prepdata = {
+static char Nobis_pci_IRQ_routes[] = {
0, /* Line 0 - Unused */
13, /* Line 1 */
13, /* Line 2 */
@@ -510,7 +510,7 @@ static char Nobis_pci_IRQ_routes[] __prepdata = {
* IBM RS/6000 43p/140 -- paulus
* XXX we should get all this from the residual data
*/
-static char ibm43p_pci_IRQ_map[23] __prepdata = {
+static char ibm43p_pci_IRQ_map[23] = {
0, /* Slot 0 - unused */
0, /* Slot 1 - unused */
0, /* Slot 2 - unused */
@@ -536,7 +536,7 @@ static char ibm43p_pci_IRQ_map[23] __prepdata = {
1, /* Slot 22 - PCI slot 1 PCIINTx# (See below) */
};
-static char ibm43p_pci_IRQ_routes[] __prepdata = {
+static char ibm43p_pci_IRQ_routes[] = {
0, /* Line 0 - unused */
15, /* Line 1 */
15, /* Line 2 */
@@ -559,7 +559,7 @@ struct powerplus_irq_list
* are routed to OpenPIC inputs 5-8. These values are offset by
* 16 in the table to reflect the Linux kernel interrupt value.
*/
-struct powerplus_irq_list Powerplus_pci_IRQ_list __prepdata =
+struct powerplus_irq_list Powerplus_pci_IRQ_list =
{
{25, 26, 27, 28},
{21, 22, 23, 24}
@@ -572,7 +572,7 @@ struct powerplus_irq_list Powerplus_pci_IRQ_list __prepdata =
* are routed to OpenPIC inputs 12-15. These values are offset by
* 16 in the table to reflect the Linux kernel interrupt value.
*/
-struct powerplus_irq_list Mesquite_pci_IRQ_list __prepdata =
+struct powerplus_irq_list Mesquite_pci_IRQ_list =
{
{24, 25, 26, 27},
{28, 29, 30, 31}
@@ -582,7 +582,7 @@ struct powerplus_irq_list Mesquite_pci_IRQ_list __prepdata =
* This table represents the standard PCI swizzle defined in the
* PCI bus specification.
*/
-static unsigned char prep_pci_intpins[4][4] __prepdata =
+static unsigned char prep_pci_intpins[4][4] =
{
{ 1, 2, 3, 4}, /* Buses 0, 4, 8, ... */
{ 2, 3, 4, 1}, /* Buses 1, 5, 9, ... */
@@ -622,7 +622,7 @@ static unsigned char prep_pci_intpins[4][4] __prepdata =
#define MIN_DEVNR 11
#define MAX_DEVNR 22
-static int __prep
+static int
prep_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
int len, u32 *val)
{
@@ -652,7 +652,7 @@ prep_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
return PCIBIOS_SUCCESSFUL;
}
-static int __prep
+static int
prep_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
int len, u32 val)
{
@@ -804,7 +804,7 @@ struct mot_info {
void (*map_non0_bus)(struct pci_dev *); /* For boards with more than bus 0 devices. */
struct powerplus_irq_list *pci_irq_list; /* List of PCI MPIC inputs */
unsigned char secondary_bridge_devfn; /* devfn of secondary bus transparent bridge */
-} mot_info[] __prepdata = {
+} mot_info[] = {
{0x300, 0x00, 0x00, "MVME 2400", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF},
{0x010, 0x00, 0x00, "Genesis", Genesis_pci_IRQ_map, Genesis_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
{0x020, 0x00, 0x00, "Powerstack (Series E)", Comet_pci_IRQ_map, Comet_pci_IRQ_routes, NULL, NULL, 0x00},
diff --git a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c
index bc926be95472..067d7d53b81e 100644
--- a/arch/ppc/platforms/prep_setup.c
+++ b/arch/ppc/platforms/prep_setup.c
@@ -89,9 +89,6 @@ extern void prep_tiger1_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi
#define cached_21 (((char *)(ppc_cached_irq_mask))[3])
#define cached_A1 (((char *)(ppc_cached_irq_mask))[2])
-/* for the mac fs */
-dev_t boot_dev;
-
#ifdef CONFIG_SOUND_CS4232
long ppc_cs4232_dma, ppc_cs4232_dma2;
#endif
@@ -173,7 +170,7 @@ prep_carolina_enable_l2(void)
}
/* cpuinfo code common to all IBM PReP */
-static void __prep
+static void
prep_ibm_cpuinfo(struct seq_file *m)
{
unsigned int equip_reg = inb(PREP_IBM_EQUIPMENT);
@@ -209,14 +206,14 @@ prep_ibm_cpuinfo(struct seq_file *m)
}
}
-static int __prep
+static int
prep_gen_cpuinfo(struct seq_file *m)
{
prep_ibm_cpuinfo(m);
return 0;
}
-static int __prep
+static int
prep_sandalfoot_cpuinfo(struct seq_file *m)
{
unsigned int equip_reg = inb(PREP_IBM_EQUIPMENT);
@@ -243,7 +240,7 @@ prep_sandalfoot_cpuinfo(struct seq_file *m)
return 0;
}
-static int __prep
+static int
prep_thinkpad_cpuinfo(struct seq_file *m)
{
unsigned int equip_reg = inb(PREP_IBM_EQUIPMENT);
@@ -314,7 +311,7 @@ prep_thinkpad_cpuinfo(struct seq_file *m)
return 0;
}
-static int __prep
+static int
prep_carolina_cpuinfo(struct seq_file *m)
{
unsigned int equip_reg = inb(PREP_IBM_EQUIPMENT);
@@ -350,7 +347,7 @@ prep_carolina_cpuinfo(struct seq_file *m)
return 0;
}
-static int __prep
+static int
prep_tiger1_cpuinfo(struct seq_file *m)
{
unsigned int l2_reg = inb(PREP_IBM_L2INFO);
@@ -393,7 +390,7 @@ prep_tiger1_cpuinfo(struct seq_file *m)
/* Used by all Motorola PReP */
-static int __prep
+static int
prep_mot_cpuinfo(struct seq_file *m)
{
unsigned int cachew = *((unsigned char *)CACHECRBA);
@@ -454,7 +451,7 @@ no_l2:
return 0;
}
-static void __prep
+static void
prep_restart(char *cmd)
{
#define PREP_SP92 0x92 /* Special Port 92 */
@@ -473,7 +470,7 @@ prep_restart(char *cmd)
#undef PREP_SP92
}
-static void __prep
+static void
prep_halt(void)
{
local_irq_disable(); /* no interrupts */
@@ -488,7 +485,7 @@ prep_halt(void)
/* Carrera is the power manager in the Thinkpads. Unfortunately not much is
* known about it, so we can't power down.
*/
-static void __prep
+static void
prep_carrera_poweroff(void)
{
prep_halt();
@@ -501,7 +498,7 @@ prep_carrera_poweroff(void)
* somewhat in the IBM Carolina Technical Specification.
* -Hollis
*/
-static void __prep
+static void
utah_sig87c750_setbit(unsigned int bytenum, unsigned int bitnum, int value)
{
/*
@@ -539,7 +536,7 @@ utah_sig87c750_setbit(unsigned int bytenum, unsigned int bitnum, int value)
udelay(100); /* important: let controller recover */
}
-static void __prep
+static void
prep_sig750_poweroff(void)
{
/* tweak the power manager found in most IBM PRePs (except Thinkpads) */
@@ -554,7 +551,7 @@ prep_sig750_poweroff(void)
/* not reached */
}
-static int __prep
+static int
prep_show_percpuinfo(struct seq_file *m, int i)
{
/* PREP's without residual data will give incorrect values here */
@@ -700,12 +697,12 @@ prep_set_bat(void)
/*
* IBM 3-digit status LED
*/
-static unsigned int ibm_statusled_base __prepdata;
+static unsigned int ibm_statusled_base;
-static void __prep
+static void
ibm_statusled_progress(char *s, unsigned short hex);
-static int __prep
+static int
ibm_statusled_panic(struct notifier_block *dummy1, unsigned long dummy2,
void * dummy3)
{
@@ -713,13 +710,13 @@ ibm_statusled_panic(struct notifier_block *dummy1, unsigned long dummy2,
return NOTIFY_DONE;
}
-static struct notifier_block ibm_statusled_block __prepdata = {
+static struct notifier_block ibm_statusled_block = {
ibm_statusled_panic,
NULL,
INT_MAX /* try to do it first */
};
-static void __prep
+static void
ibm_statusled_progress(char *s, unsigned short hex)
{
static int notifier_installed;
@@ -945,19 +942,6 @@ prep_calibrate_decr(void)
todc_calibrate_decr();
}
-static unsigned int __prep
-prep_irq_canonicalize(u_int irq)
-{
- if (irq == 2)
- {
- return 9;
- }
- else
- {
- return irq;
- }
-}
-
static void __init
prep_init_IRQ(void)
{
@@ -970,11 +954,9 @@ prep_init_IRQ(void)
openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
i8259_irq);
}
- for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ )
- irq_desc[i].handler = &i8259_pic;
if (have_residual_data) {
- i8259_init(residual_isapic_addr());
+ i8259_init(residual_isapic_addr(), 0);
return;
}
@@ -985,18 +967,18 @@ prep_init_IRQ(void)
if (((pci_viddid & 0xffff) == PCI_VENDOR_ID_MOTOROLA)
&& ((pci_did == PCI_DEVICE_ID_MOTOROLA_RAVEN)
|| (pci_did == PCI_DEVICE_ID_MOTOROLA_HAWK)))
- i8259_init(0);
+ i8259_init(0, 0);
else
/* PCI interrupt ack address given in section 6.1.8 of the
* PReP specification. */
- i8259_init(MPC10X_MAPA_PCI_INTACK_ADDR);
+ i8259_init(MPC10X_MAPA_PCI_INTACK_ADDR, 0);
}
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
/*
* IDE stuff.
*/
-static int __prep
+static int
prep_ide_default_irq(unsigned long base)
{
switch (base) {
@@ -1010,7 +992,7 @@ prep_ide_default_irq(unsigned long base)
}
}
-static unsigned long __prep
+static unsigned long
prep_ide_default_io_base(int index)
{
switch (index) {
@@ -1055,7 +1037,7 @@ smp_prep_setup_cpu(int cpu_nr)
do_openpic_setup_cpu();
}
-static struct smp_ops_t prep_smp_ops __prepdata = {
+static struct smp_ops_t prep_smp_ops = {
smp_openpic_message_pass,
smp_prep_probe,
smp_prep_kick_cpu,
@@ -1113,6 +1095,7 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5,
ISA_DMA_THRESHOLD = 0x00ffffff;
DMA_MODE_READ = 0x44;
DMA_MODE_WRITE = 0x48;
+ ppc_do_canonicalize_irqs = 1;
/* figure out what kind of prep workstation we are */
if (have_residual_data) {
@@ -1139,7 +1122,6 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.setup_arch = prep_setup_arch;
ppc_md.show_percpuinfo = prep_show_percpuinfo;
ppc_md.show_cpuinfo = NULL; /* set in prep_setup_arch() */
- ppc_md.irq_canonicalize = prep_irq_canonicalize;
ppc_md.init_IRQ = prep_init_IRQ;
/* this gets changed later on if we have an OpenPIC -- Cort */
ppc_md.get_irq = i8259_irq;
@@ -1176,6 +1158,6 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5,
#endif
#ifdef CONFIG_SMP
- ppc_md.smp_ops = &prep_smp_ops;
+ smp_ops = &prep_smp_ops;
#endif /* CONFIG_SMP */
}
diff --git a/arch/ppc/platforms/radstone_ppc7d.c b/arch/ppc/platforms/radstone_ppc7d.c
index 7e65b7f1f626..708b8739ecdd 100644
--- a/arch/ppc/platforms/radstone_ppc7d.c
+++ b/arch/ppc/platforms/radstone_ppc7d.c
@@ -515,13 +515,9 @@ static void __init ppc7d_init_irq(void)
int irq;
pr_debug("%s\n", __FUNCTION__);
- i8259_init(0);
+ i8259_init(0, 0);
mv64360_init_irq();
- /* IRQ 0..15 are handled by the cascaded 8259's of the Ali1535 */
- for (irq = 0; irq < 16; irq++) {
- irq_desc[irq].handler = &i8259_pic;
- }
/* IRQs 5,6,9,10,11,14,15 are level sensitive */
irq_desc[5].status |= IRQ_LEVEL;
irq_desc[6].status |= IRQ_LEVEL;
@@ -1184,18 +1180,18 @@ static void __init ppc7d_setup_arch(void)
ROOT_DEV = Root_HDA1;
#endif
- if ((cur_cpu_spec[0]->cpu_features & CPU_FTR_SPEC7450) ||
- (cur_cpu_spec[0]->cpu_features & CPU_FTR_L3CR))
+ if ((cur_cpu_spec->cpu_features & CPU_FTR_SPEC7450) ||
+ (cur_cpu_spec->cpu_features & CPU_FTR_L3CR))
/* 745x is different. We only want to pass along enable. */
_set_L2CR(L2CR_L2E);
- else if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR)
+ else if (cur_cpu_spec->cpu_features & CPU_FTR_L2CR)
/* All modules have 1MB of L2. We also assume that an
* L2 divisor of 3 will work.
*/
_set_L2CR(L2CR_L2E | L2CR_L2SIZ_1MB | L2CR_L2CLK_DIV3
| L2CR_L2RAM_PIPE | L2CR_L2OH_1_0 | L2CR_L2DF);
- if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L3CR)
+ if (cur_cpu_spec->cpu_features & CPU_FTR_L3CR)
/* No L3 cache */
_set_L3CR(0);
@@ -1425,6 +1421,7 @@ void __init platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.setup_arch = ppc7d_setup_arch;
ppc_md.init = ppc7d_init2;
ppc_md.show_cpuinfo = ppc7d_show_cpuinfo;
+ /* XXX this is broken... */
ppc_md.irq_canonicalize = ppc7d_irq_canonicalize;
ppc_md.init_IRQ = ppc7d_init_irq;
ppc_md.get_irq = ppc7d_get_irq;
diff --git a/arch/ppc/platforms/residual.c b/arch/ppc/platforms/residual.c
index 0f84ca603612..c9911601cfdf 100644
--- a/arch/ppc/platforms/residual.c
+++ b/arch/ppc/platforms/residual.c
@@ -47,7 +47,7 @@
#include <asm/ide.h>
-unsigned char __res[sizeof(RESIDUAL)] __prepdata = {0,};
+unsigned char __res[sizeof(RESIDUAL)] = {0,};
RESIDUAL *res = (RESIDUAL *)&__res;
char * PnP_BASE_TYPES[] __initdata = {
diff --git a/arch/ppc/platforms/sandpoint.c b/arch/ppc/platforms/sandpoint.c
index 5232283c1974..9eeed3572309 100644
--- a/arch/ppc/platforms/sandpoint.c
+++ b/arch/ppc/platforms/sandpoint.c
@@ -494,27 +494,10 @@ sandpoint_init_IRQ(void)
i8259_irq);
/*
- * openpic_init() has set up irq_desc[16-31] to be openpic
- * interrupts. We need to set irq_desc[0-15] to be i8259
- * interrupts.
- */
- for(i=0; i < NUM_8259_INTERRUPTS; i++)
- irq_desc[i].handler = &i8259_pic;
-
- /*
* The EPIC allows for a read in the range of 0xFEF00000 ->
* 0xFEFFFFFF to generate a PCI interrupt-acknowledge transaction.
*/
- i8259_init(0xfef00000);
-}
-
-static u32
-sandpoint_irq_canonicalize(u32 irq)
-{
- if (irq == 2)
- return 9;
- else
- return irq;
+ i8259_init(0xfef00000, 0);
}
static unsigned long __init
@@ -727,10 +710,10 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
ISA_DMA_THRESHOLD = 0x00ffffff;
DMA_MODE_READ = 0x44;
DMA_MODE_WRITE = 0x48;
+ ppc_do_canonicalize_irqs = 1;
ppc_md.setup_arch = sandpoint_setup_arch;
ppc_md.show_cpuinfo = sandpoint_show_cpuinfo;
- ppc_md.irq_canonicalize = sandpoint_irq_canonicalize;
ppc_md.init_IRQ = sandpoint_init_IRQ;
ppc_md.get_irq = openpic_get_irq;
diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile
index b8d08f33f7ee..b4ef15b45c4a 100644
--- a/arch/ppc/syslib/Makefile
+++ b/arch/ppc/syslib/Makefile
@@ -31,52 +31,49 @@ obj-$(CONFIG_GEN_RTC) += todc_time.o
obj-$(CONFIG_PPC4xx_DMA) += ppc4xx_dma.o
obj-$(CONFIG_PPC4xx_EDMA) += ppc4xx_sgdma.o
ifeq ($(CONFIG_40x),y)
-obj-$(CONFIG_PCI) += indirect_pci.o pci_auto.o ppc405_pci.o
+obj-$(CONFIG_PCI) += pci_auto.o ppc405_pci.o
endif
endif
obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o $(wdt-mpc8xx-y) \
ppc_sys.o mpc8xx_devices.o mpc8xx_sys.o
-ifeq ($(CONFIG_8xx),y)
-obj-$(CONFIG_PCI) += qspan_pci.o i8259.o
-endif
-obj-$(CONFIG_PPC_OF) += prom_init.o prom.o of_device.o
-obj-$(CONFIG_PPC_PMAC) += open_pic.o indirect_pci.o
+obj-$(CONFIG_PCI_QSPAN) += qspan_pci.o
+obj-$(CONFIG_PPC_OF) += prom_init.o prom.o
+obj-$(CONFIG_PPC_PMAC) += open_pic.o
obj-$(CONFIG_POWER4) += open_pic2.o
-obj-$(CONFIG_PPC_CHRP) += open_pic.o indirect_pci.o i8259.o
-obj-$(CONFIG_PPC_PREP) += open_pic.o indirect_pci.o i8259.o todc_time.o
-obj-$(CONFIG_BAMBOO) += indirect_pci.o pci_auto.o todc_time.o
+obj-$(CONFIG_PPC_CHRP) += open_pic.o
+obj-$(CONFIG_PPC_PREP) += open_pic.o todc_time.o
+obj-$(CONFIG_BAMBOO) += pci_auto.o todc_time.o
obj-$(CONFIG_CPCI690) += todc_time.o pci_auto.o
-obj-$(CONFIG_EBONY) += indirect_pci.o pci_auto.o todc_time.o
+obj-$(CONFIG_EBONY) += pci_auto.o todc_time.o
obj-$(CONFIG_EV64260) += todc_time.o pci_auto.o
obj-$(CONFIG_CHESTNUT) += mv64360_pic.o pci_auto.o
-obj-$(CONFIG_GEMINI) += open_pic.o indirect_pci.o
+obj-$(CONFIG_GEMINI) += open_pic.o
obj-$(CONFIG_GT64260) += gt64260_pic.o
-obj-$(CONFIG_LOPEC) += i8259.o pci_auto.o todc_time.o
+obj-$(CONFIG_LOPEC) += pci_auto.o todc_time.o
obj-$(CONFIG_HDPU) += pci_auto.o
-obj-$(CONFIG_LUAN) += indirect_pci.o pci_auto.o todc_time.o
+obj-$(CONFIG_LUAN) += pci_auto.o todc_time.o
obj-$(CONFIG_KATANA) += pci_auto.o
obj-$(CONFIG_MV64360) += mv64360_pic.o
-obj-$(CONFIG_MV64X60) += mv64x60.o mv64x60_win.o indirect_pci.o
-obj-$(CONFIG_MVME5100) += open_pic.o todc_time.o indirect_pci.o \
+obj-$(CONFIG_MV64X60) += mv64x60.o mv64x60_win.o
+obj-$(CONFIG_MVME5100) += open_pic.o todc_time.o \
pci_auto.o hawk_common.o
-obj-$(CONFIG_MVME5100_IPMC761_PRESENT) += i8259.o
-obj-$(CONFIG_OCOTEA) += indirect_pci.o pci_auto.o todc_time.o
+obj-$(CONFIG_OCOTEA) += pci_auto.o todc_time.o
obj-$(CONFIG_PAL4) += cpc700_pic.o
obj-$(CONFIG_POWERPMC250) += pci_auto.o
-obj-$(CONFIG_PPLUS) += hawk_common.o open_pic.o i8259.o \
- indirect_pci.o todc_time.o pci_auto.o
-obj-$(CONFIG_PRPMC750) += open_pic.o indirect_pci.o pci_auto.o \
+obj-$(CONFIG_PPLUS) += hawk_common.o open_pic.o \
+ todc_time.o pci_auto.o
+obj-$(CONFIG_PRPMC750) += open_pic.o pci_auto.o \
hawk_common.o
obj-$(CONFIG_HARRIER) += harrier.o
-obj-$(CONFIG_PRPMC800) += open_pic.o indirect_pci.o pci_auto.o
-obj-$(CONFIG_RADSTONE_PPC7D) += i8259.o pci_auto.o
-obj-$(CONFIG_SANDPOINT) += i8259.o pci_auto.o todc_time.o
+obj-$(CONFIG_PRPMC800) += open_pic.o pci_auto.o
+obj-$(CONFIG_RADSTONE_PPC7D) += pci_auto.o
+obj-$(CONFIG_SANDPOINT) += pci_auto.o todc_time.o
obj-$(CONFIG_SBC82xx) += todc_time.o
-obj-$(CONFIG_SPRUCE) += cpc700_pic.o indirect_pci.o pci_auto.o \
+obj-$(CONFIG_SPRUCE) += cpc700_pic.o pci_auto.o \
todc_time.o
obj-$(CONFIG_8260) += m8260_setup.o pq2_devices.o pq2_sys.o \
ppc_sys.o
-obj-$(CONFIG_PCI_8260) += m82xx_pci.o indirect_pci.o pci_auto.o
+obj-$(CONFIG_PCI_8260) += m82xx_pci.o pci_auto.o
obj-$(CONFIG_8260_PCI9) += m8260_pci_erratum9.o
obj-$(CONFIG_CPM2) += cpm2_common.o cpm2_pic.o
ifeq ($(CONFIG_PPC_GEN550),y)
@@ -87,20 +84,18 @@ ifeq ($(CONFIG_SERIAL_MPSC_CONSOLE),y)
obj-$(CONFIG_SERIAL_TEXT_DEBUG) += mv64x60_dbg.o
endif
obj-$(CONFIG_BOOTX_TEXT) += btext.o
-obj-$(CONFIG_MPC10X_BRIDGE) += mpc10x_common.o indirect_pci.o ppc_sys.o
+obj-$(CONFIG_MPC10X_BRIDGE) += mpc10x_common.o ppc_sys.o
obj-$(CONFIG_MPC10X_OPENPIC) += open_pic.o
-obj-$(CONFIG_40x) += dcr.o
-obj-$(CONFIG_BOOKE) += dcr.o
obj-$(CONFIG_85xx) += open_pic.o ppc85xx_common.o ppc85xx_setup.o \
- ppc_sys.o i8259.o mpc85xx_sys.o \
+ ppc_sys.o mpc85xx_sys.o \
mpc85xx_devices.o
ifeq ($(CONFIG_85xx),y)
-obj-$(CONFIG_PCI) += indirect_pci.o pci_auto.o
+obj-$(CONFIG_PCI) += pci_auto.o
endif
obj-$(CONFIG_83xx) += ipic.o ppc83xx_setup.o ppc_sys.o \
mpc83xx_sys.o mpc83xx_devices.o
ifeq ($(CONFIG_83xx),y)
-obj-$(CONFIG_PCI) += indirect_pci.o pci_auto.o
+obj-$(CONFIG_PCI) += pci_auto.o
endif
obj-$(CONFIG_MPC8548_CDS) += todc_time.o
obj-$(CONFIG_MPC8555_CDS) += todc_time.o
diff --git a/arch/ppc/syslib/btext.c b/arch/ppc/syslib/btext.c
index 7734f6836174..12fa83e6774a 100644
--- a/arch/ppc/syslib/btext.c
+++ b/arch/ppc/syslib/btext.c
@@ -53,8 +53,8 @@ extern char *klimit;
* chrp only uses it during early boot.
*/
#ifdef CONFIG_XMON
-#define BTEXT __pmac
-#define BTDATA __pmacdata
+#define BTEXT
+#define BTDATA
#else
#define BTEXT __init
#define BTDATA __initdata
@@ -187,7 +187,7 @@ btext_setup_display(int width, int height, int depth, int pitch,
* changes.
*/
-void __openfirmware
+void
map_boot_text(void)
{
unsigned long base, offset, size;
diff --git a/arch/ppc/syslib/gt64260_pic.c b/arch/ppc/syslib/gt64260_pic.c
index 44aa87385451..f97b3a9abd1e 100644
--- a/arch/ppc/syslib/gt64260_pic.c
+++ b/arch/ppc/syslib/gt64260_pic.c
@@ -45,6 +45,7 @@
#include <asm/system.h>
#include <asm/irq.h>
#include <asm/mv64x60.h>
+#include <asm/machdep.h>
#define CPU_INTR_STR "gt64260 cpu interface error"
#define PCI0_INTR_STR "gt64260 pci 0 error"
diff --git a/arch/ppc/syslib/ibm440gx_common.c b/arch/ppc/syslib/ibm440gx_common.c
index 0bb919859b8b..c36db279b43d 100644
--- a/arch/ppc/syslib/ibm440gx_common.c
+++ b/arch/ppc/syslib/ibm440gx_common.c
@@ -236,9 +236,9 @@ void __init ibm440gx_l2c_setup(struct ibm44x_clocks* p)
/* Disable L2C on rev.A, rev.B and 800MHz version of rev.C,
enable it on all other revisions
*/
- if (strcmp(cur_cpu_spec[0]->cpu_name, "440GX Rev. A") == 0 ||
- strcmp(cur_cpu_spec[0]->cpu_name, "440GX Rev. B") == 0
- || (strcmp(cur_cpu_spec[0]->cpu_name, "440GX Rev. C")
+ if (strcmp(cur_cpu_spec->cpu_name, "440GX Rev. A") == 0 ||
+ strcmp(cur_cpu_spec->cpu_name, "440GX Rev. B") == 0
+ || (strcmp(cur_cpu_spec->cpu_name, "440GX Rev. C")
== 0 && p->cpu > 667000000))
ibm440gx_l2c_disable();
else
diff --git a/arch/ppc/syslib/ibm44x_common.c b/arch/ppc/syslib/ibm44x_common.c
index 7612e0623f99..5152c8e41340 100644
--- a/arch/ppc/syslib/ibm44x_common.c
+++ b/arch/ppc/syslib/ibm44x_common.c
@@ -27,9 +27,14 @@
#include <asm/time.h>
#include <asm/ppc4xx_pic.h>
#include <asm/param.h>
+#include <asm/bootinfo.h>
+#include <asm/ppcboot.h>
#include <syslib/gen550.h>
+/* Global Variables */
+bd_t __res;
+
phys_addr_t fixup_bigphys_addr(phys_addr_t addr, phys_addr_t size)
{
phys_addr_t page_4gb = 0;
@@ -150,8 +155,36 @@ static unsigned long __init ibm44x_find_end_of_memory(void)
return mem_size;
}
-void __init ibm44x_platform_init(void)
+void __init ibm44x_platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7)
{
+ parse_bootinfo(find_bootinfo());
+
+ /*
+ * If we were passed in a board information, copy it into the
+ * residual data area.
+ */
+ if (r3)
+ __res = *(bd_t *)(r3 + KERNELBASE);
+
+#if defined(CONFIG_BLK_DEV_INITRD)
+ /*
+ * If the init RAM disk has been configured in, and there's a valid
+ * starting address for it, set it up.
+ */
+ if (r4) {
+ initrd_start = r4 + KERNELBASE;
+ initrd_end = r5 + KERNELBASE;
+ }
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+ /* Copy the kernel command line arguments to a safe place. */
+
+ if (r6) {
+ *(char *) (r7 + KERNELBASE) = 0;
+ strcpy(cmd_line, (char *) (r6 + KERNELBASE));
+ }
+
ppc_md.init_IRQ = ppc4xx_pic_init;
ppc_md.find_end_of_memory = ibm44x_find_end_of_memory;
ppc_md.restart = ibm44x_restart;
@@ -178,7 +211,7 @@ void __init ibm44x_platform_init(void)
#endif
}
-/* Called from MachineCheckException */
+/* Called from machine_check_exception */
void platform_machine_check(struct pt_regs *regs)
{
printk("PLB0: BEAR=0x%08x%08x ACR= 0x%08x BESR= 0x%08x\n",
diff --git a/arch/ppc/syslib/ibm44x_common.h b/arch/ppc/syslib/ibm44x_common.h
index c16b6a5ac6ab..b25a8995e4e9 100644
--- a/arch/ppc/syslib/ibm44x_common.h
+++ b/arch/ppc/syslib/ibm44x_common.h
@@ -36,7 +36,8 @@ struct ibm44x_clocks {
};
/* common 44x platform init */
-void ibm44x_platform_init(void) __init;
+void ibm44x_platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7) __init;
/* initialize decrementer and tick-related variables */
void ibm44x_calibrate_decr(unsigned int freq) __init;
diff --git a/arch/ppc/syslib/m8260_setup.c b/arch/ppc/syslib/m8260_setup.c
index 8f80a42dfdb7..76a2aa4ce65e 100644
--- a/arch/ppc/syslib/m8260_setup.c
+++ b/arch/ppc/syslib/m8260_setup.c
@@ -62,6 +62,10 @@ m8260_setup_arch(void)
if (initrd_start)
ROOT_DEV = Root_RAM0;
#endif
+
+ identify_ppc_sys_by_name_and_id(BOARD_CHIP_NAME,
+ in_be32(CPM_MAP_ADDR + CPM_IMMR_OFFSET));
+
m82xx_board_setup();
}
diff --git a/arch/ppc/syslib/m82xx_pci.c b/arch/ppc/syslib/m82xx_pci.c
index 9db58c587b46..1d1c3956c1ae 100644
--- a/arch/ppc/syslib/m82xx_pci.c
+++ b/arch/ppc/syslib/m82xx_pci.c
@@ -302,11 +302,11 @@ pq2ads_setup_pci(struct pci_controller *hose)
void __init pq2_find_bridges(void)
{
- extern int pci_assign_all_busses;
+ extern int pci_assign_all_buses;
struct pci_controller * hose;
int host_bridge;
- pci_assign_all_busses = 1;
+ pci_assign_all_buses = 1;
hose = pcibios_alloc_controller();
diff --git a/arch/ppc/syslib/m8xx_setup.c b/arch/ppc/syslib/m8xx_setup.c
index 4c888da89b3c..97ffbc70574f 100644
--- a/arch/ppc/syslib/m8xx_setup.c
+++ b/arch/ppc/syslib/m8xx_setup.c
@@ -144,12 +144,12 @@ void __init m8xx_calibrate_decr(void)
int freq, fp, divisor;
/* Unlock the SCCR. */
- ((volatile immap_t *)IMAP_ADDR)->im_clkrstk.cark_sccrk = ~KAPWR_KEY;
- ((volatile immap_t *)IMAP_ADDR)->im_clkrstk.cark_sccrk = KAPWR_KEY;
+ out_be32(&((immap_t *)IMAP_ADDR)->im_clkrstk.cark_sccrk, ~KAPWR_KEY);
+ out_be32(&((immap_t *)IMAP_ADDR)->im_clkrstk.cark_sccrk, KAPWR_KEY);
/* Force all 8xx processors to use divide by 16 processor clock. */
- ((volatile immap_t *)IMAP_ADDR)->im_clkrst.car_sccr |= 0x02000000;
-
+ out_be32(&((immap_t *)IMAP_ADDR)->im_clkrst.car_sccr,
+ in_be32(&((immap_t *)IMAP_ADDR)->im_clkrst.car_sccr)|0x02000000);
/* Processor frequency is MHz.
* The value 'fp' is the number of decrementer ticks per second.
*/
@@ -175,28 +175,24 @@ void __init m8xx_calibrate_decr(void)
* we guarantee the registers are locked, then we unlock them
* for our use.
*/
- ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk = ~KAPWR_KEY;
- ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck = ~KAPWR_KEY;
- ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk = ~KAPWR_KEY;
- ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk = KAPWR_KEY;
- ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck = KAPWR_KEY;
- ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk = KAPWR_KEY;
+ out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk, ~KAPWR_KEY);
+ out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck, ~KAPWR_KEY);
+ out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk, ~KAPWR_KEY);
+ out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk, KAPWR_KEY);
+ out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck, KAPWR_KEY);
+ out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk, KAPWR_KEY);
/* Disable the RTC one second and alarm interrupts. */
- ((volatile immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc &=
- ~(RTCSC_SIE | RTCSC_ALE);
+ out_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc, in_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc) & ~(RTCSC_SIE | RTCSC_ALE));
/* Enable the RTC */
- ((volatile immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc |=
- (RTCSC_RTF | RTCSC_RTE);
+ out_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc, in_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc) | (RTCSC_RTF | RTCSC_RTE));
/* Enabling the decrementer also enables the timebase interrupts
* (or from the other point of view, to get decrementer interrupts
* we have to enable the timebase). The decrementer interrupt
* is wired into the vector table, nothing to do here for that.
*/
- ((volatile immap_t *)IMAP_ADDR)->im_sit.sit_tbscr =
- ((mk_int_int_mask(DEC_INTERRUPT) << 8) |
- (TBSCR_TBF | TBSCR_TBE));
+ out_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_tbscr, (mk_int_int_mask(DEC_INTERRUPT) << 8) | (TBSCR_TBF | TBSCR_TBE));
if (setup_irq(DEC_INTERRUPT, &tbint_irqaction))
panic("Could not allocate timer IRQ!");
@@ -216,9 +212,9 @@ void __init m8xx_calibrate_decr(void)
static int
m8xx_set_rtc_time(unsigned long time)
{
- ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck = KAPWR_KEY;
- ((volatile immap_t *)IMAP_ADDR)->im_sit.sit_rtc = time;
- ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck = ~KAPWR_KEY;
+ out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck, KAPWR_KEY);
+ out_be32(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtc, time);
+ out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck, ~KAPWR_KEY);
return(0);
}
@@ -226,7 +222,7 @@ static unsigned long
m8xx_get_rtc_time(void)
{
/* Get time from the RTC. */
- return((unsigned long)(((immap_t *)IMAP_ADDR)->im_sit.sit_rtc));
+ return (unsigned long) in_be32(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtc);
}
static void
@@ -235,13 +231,13 @@ m8xx_restart(char *cmd)
__volatile__ unsigned char dummy;
local_irq_disable();
- ((immap_t *)IMAP_ADDR)->im_clkrst.car_plprcr |= 0x00000080;
+ out_be32(&((immap_t *)IMAP_ADDR)->im_clkrst.car_plprcr, in_be32(&((immap_t *)IMAP_ADDR)->im_clkrst.car_plprcr) | 0x00000080);
/* Clear the ME bit in MSR to cause checkstop on machine check
*/
mtmsr(mfmsr() & ~0x1000);
- dummy = ((immap_t *)IMAP_ADDR)->im_clkrst.res[0];
+ dummy = in_8(&((immap_t *)IMAP_ADDR)->im_clkrst.res[0]);
printk("Restart failed\n");
while(1);
}
@@ -306,8 +302,7 @@ m8xx_init_IRQ(void)
i8259_init(0);
/* The i8259 cascade interrupt must be level sensitive. */
- ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel &=
- ~(0x80000000 >> ISA_BRIDGE_INT);
+ out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel, in_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel & ~(0x80000000 >> ISA_BRIDGE_INT)));
if (setup_irq(ISA_BRIDGE_INT, &mbx_i8259_irqaction))
enable_irq(ISA_BRIDGE_INT);
@@ -404,9 +399,10 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
strcpy(cmd_line, (char *)(r6+KERNELBASE));
}
+ identify_ppc_sys_by_name(BOARD_CHIP_NAME);
+
ppc_md.setup_arch = m8xx_setup_arch;
ppc_md.show_percpuinfo = m8xx_show_percpuinfo;
- ppc_md.irq_canonicalize = NULL;
ppc_md.init_IRQ = m8xx_init_IRQ;
ppc_md.get_irq = m8xx_get_irq;
ppc_md.init = NULL;
diff --git a/arch/ppc/syslib/m8xx_wdt.c b/arch/ppc/syslib/m8xx_wdt.c
index 2ddc857e7fc7..c5ac5ce5d7d2 100644
--- a/arch/ppc/syslib/m8xx_wdt.c
+++ b/arch/ppc/syslib/m8xx_wdt.c
@@ -29,8 +29,8 @@ void m8xx_wdt_reset(void)
{
volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR;
- imap->im_siu_conf.sc_swsr = 0x556c; /* write magic1 */
- imap->im_siu_conf.sc_swsr = 0xaa39; /* write magic2 */
+ out_be16(imap->im_siu_conf.sc_swsr, 0x556c); /* write magic1 */
+ out_be16(imap->im_siu_conf.sc_swsr, 0xaa39); /* write magic2 */
}
static irqreturn_t m8xx_wdt_interrupt(int irq, void *dev, struct pt_regs *regs)
@@ -39,7 +39,7 @@ static irqreturn_t m8xx_wdt_interrupt(int irq, void *dev, struct pt_regs *regs)
m8xx_wdt_reset();
- imap->im_sit.sit_piscr |= PISCR_PS; /* clear irq */
+ out_be16(imap->im_sit.sit_piscr, in_be16(imap->im_sit.sit_piscr | PISCR_PS)); /* clear irq */
return IRQ_HANDLED;
}
@@ -51,7 +51,7 @@ void __init m8xx_wdt_handler_install(bd_t * binfo)
u32 sypcr;
u32 pitrtclk;
- sypcr = imap->im_siu_conf.sc_sypcr;
+ sypcr = in_be32(imap->im_siu_conf.sc_sypcr);
if (!(sypcr & 0x04)) {
printk(KERN_NOTICE "m8xx_wdt: wdt disabled (SYPCR: 0x%08X)\n",
@@ -87,9 +87,9 @@ void __init m8xx_wdt_handler_install(bd_t * binfo)
else
pitc = pitrtclk * wdt_timeout / binfo->bi_intfreq / 2;
- imap->im_sit.sit_pitc = pitc << 16;
- imap->im_sit.sit_piscr =
- (mk_int_int_mask(PIT_INTERRUPT) << 8) | PISCR_PIE | PISCR_PTE;
+ out_be32(imap->im_sit.sit_pitc, pitc << 16);
+
+ out_be16(imap->im_sit.sit_piscr, (mk_int_int_mask(PIT_INTERRUPT) << 8) | PISCR_PIE | PISCR_PTE);
if (setup_irq(PIT_INTERRUPT, &m8xx_wdt_irqaction))
panic("m8xx_wdt: error setting up the watchdog irq!");
diff --git a/arch/ppc/syslib/mpc52xx_pci.c b/arch/ppc/syslib/mpc52xx_pci.c
index 59cf3e8bd1a0..4ac19080eb85 100644
--- a/arch/ppc/syslib/mpc52xx_pci.c
+++ b/arch/ppc/syslib/mpc52xx_pci.c
@@ -21,6 +21,7 @@
#include "mpc52xx_pci.h"
#include <asm/delay.h>
+#include <asm/machdep.h>
static int
@@ -181,7 +182,7 @@ mpc52xx_find_bridges(void)
struct mpc52xx_pci __iomem *pci_regs;
struct pci_controller *hose;
- pci_assign_all_busses = 1;
+ pci_assign_all_buses = 1;
pci_regs = ioremap(MPC52xx_PA(MPC52xx_PCI_OFFSET), MPC52xx_PCI_SIZE);
if (!pci_regs)
diff --git a/arch/ppc/syslib/mpc83xx_devices.c b/arch/ppc/syslib/mpc83xx_devices.c
index 95b3b8a7f0ba..dbf8acac507f 100644
--- a/arch/ppc/syslib/mpc83xx_devices.c
+++ b/arch/ppc/syslib/mpc83xx_devices.c
@@ -21,6 +21,7 @@
#include <asm/mpc83xx.h>
#include <asm/irq.h>
#include <asm/ppc_sys.h>
+#include <asm/machdep.h>
/* We use offsets for IORESOURCE_MEM since we do not know at compile time
* what IMMRBAR is, will get fixed up by mach_mpc83xx_fixup
diff --git a/arch/ppc/syslib/mpc85xx_devices.c b/arch/ppc/syslib/mpc85xx_devices.c
index bbc5ac0de878..2ede677a0a53 100644
--- a/arch/ppc/syslib/mpc85xx_devices.c
+++ b/arch/ppc/syslib/mpc85xx_devices.c
@@ -25,19 +25,20 @@
/* We use offsets for IORESOURCE_MEM since we do not know at compile time
* what CCSRBAR is, will get fixed up by mach_mpc85xx_fixup
*/
+struct gianfar_mdio_data mpc85xx_mdio_pdata = {
+ .paddr = MPC85xx_MIIM_OFFSET,
+};
static struct gianfar_platform_data mpc85xx_tsec1_pdata = {
.device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT |
FSL_GIANFAR_DEV_HAS_COALESCE | FSL_GIANFAR_DEV_HAS_RMON |
FSL_GIANFAR_DEV_HAS_MULTI_INTR,
- .phy_reg_addr = MPC85xx_ENET1_OFFSET,
};
static struct gianfar_platform_data mpc85xx_tsec2_pdata = {
.device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT |
FSL_GIANFAR_DEV_HAS_COALESCE | FSL_GIANFAR_DEV_HAS_RMON |
FSL_GIANFAR_DEV_HAS_MULTI_INTR,
- .phy_reg_addr = MPC85xx_ENET1_OFFSET,
};
static struct gianfar_platform_data mpc85xx_etsec1_pdata = {
@@ -46,7 +47,6 @@ static struct gianfar_platform_data mpc85xx_etsec1_pdata = {
FSL_GIANFAR_DEV_HAS_MULTI_INTR |
FSL_GIANFAR_DEV_HAS_CSUM | FSL_GIANFAR_DEV_HAS_VLAN |
FSL_GIANFAR_DEV_HAS_EXTENDED_HASH,
- .phy_reg_addr = MPC85xx_ENET1_OFFSET,
};
static struct gianfar_platform_data mpc85xx_etsec2_pdata = {
@@ -55,7 +55,6 @@ static struct gianfar_platform_data mpc85xx_etsec2_pdata = {
FSL_GIANFAR_DEV_HAS_MULTI_INTR |
FSL_GIANFAR_DEV_HAS_CSUM | FSL_GIANFAR_DEV_HAS_VLAN |
FSL_GIANFAR_DEV_HAS_EXTENDED_HASH,
- .phy_reg_addr = MPC85xx_ENET1_OFFSET,
};
static struct gianfar_platform_data mpc85xx_etsec3_pdata = {
@@ -64,7 +63,6 @@ static struct gianfar_platform_data mpc85xx_etsec3_pdata = {
FSL_GIANFAR_DEV_HAS_MULTI_INTR |
FSL_GIANFAR_DEV_HAS_CSUM | FSL_GIANFAR_DEV_HAS_VLAN |
FSL_GIANFAR_DEV_HAS_EXTENDED_HASH,
- .phy_reg_addr = MPC85xx_ENET1_OFFSET,
};
static struct gianfar_platform_data mpc85xx_etsec4_pdata = {
@@ -73,11 +71,10 @@ static struct gianfar_platform_data mpc85xx_etsec4_pdata = {
FSL_GIANFAR_DEV_HAS_MULTI_INTR |
FSL_GIANFAR_DEV_HAS_CSUM | FSL_GIANFAR_DEV_HAS_VLAN |
FSL_GIANFAR_DEV_HAS_EXTENDED_HASH,
- .phy_reg_addr = MPC85xx_ENET1_OFFSET,
};
static struct gianfar_platform_data mpc85xx_fec_pdata = {
- .phy_reg_addr = MPC85xx_ENET1_OFFSET,
+ .device_flags = 0,
};
static struct fsl_i2c_platform_data mpc85xx_fsl_i2c_pdata = {
@@ -719,6 +716,12 @@ struct platform_device ppc_sys_platform_devices[] = {
},
},
},
+ [MPC85xx_MDIO] = {
+ .name = "fsl-gianfar_mdio",
+ .id = 0,
+ .dev.platform_data = &mpc85xx_mdio_pdata,
+ .num_resources = 0,
+ },
};
static int __init mach_mpc85xx_fixup(struct platform_device *pdev)
diff --git a/arch/ppc/syslib/mpc85xx_sys.c b/arch/ppc/syslib/mpc85xx_sys.c
index 6e3184ab354f..cb68d8c58348 100644
--- a/arch/ppc/syslib/mpc85xx_sys.c
+++ b/arch/ppc/syslib/mpc85xx_sys.c
@@ -24,19 +24,19 @@ struct ppc_sys_spec ppc_sys_specs[] = {
.ppc_sys_name = "8540",
.mask = 0xFFFF0000,
.value = 0x80300000,
- .num_devices = 10,
+ .num_devices = 11,
.device_list = (enum ppc_sys_devices[])
{
MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_FEC, MPC85xx_IIC1,
MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
- MPC85xx_PERFMON, MPC85xx_DUART,
+ MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_MDIO,
},
},
{
.ppc_sys_name = "8560",
.mask = 0xFFFF0000,
.value = 0x80700000,
- .num_devices = 19,
+ .num_devices = 20,
.device_list = (enum ppc_sys_devices[])
{
MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1,
@@ -45,14 +45,14 @@ struct ppc_sys_spec ppc_sys_specs[] = {
MPC85xx_CPM_SPI, MPC85xx_CPM_I2C, MPC85xx_CPM_SCC1,
MPC85xx_CPM_SCC2, MPC85xx_CPM_SCC3, MPC85xx_CPM_SCC4,
MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2, MPC85xx_CPM_FCC3,
- MPC85xx_CPM_MCC1, MPC85xx_CPM_MCC2,
+ MPC85xx_CPM_MCC1, MPC85xx_CPM_MCC2, MPC85xx_MDIO,
},
},
{
.ppc_sys_name = "8541",
.mask = 0xFFFF0000,
.value = 0x80720000,
- .num_devices = 13,
+ .num_devices = 14,
.device_list = (enum ppc_sys_devices[])
{
MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1,
@@ -60,13 +60,14 @@ struct ppc_sys_spec ppc_sys_specs[] = {
MPC85xx_PERFMON, MPC85xx_DUART,
MPC85xx_CPM_SPI, MPC85xx_CPM_I2C,
MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2,
+ MPC85xx_MDIO,
},
},
{
.ppc_sys_name = "8541E",
.mask = 0xFFFF0000,
.value = 0x807A0000,
- .num_devices = 14,
+ .num_devices = 15,
.device_list = (enum ppc_sys_devices[])
{
MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1,
@@ -74,13 +75,14 @@ struct ppc_sys_spec ppc_sys_specs[] = {
MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2,
MPC85xx_CPM_SPI, MPC85xx_CPM_I2C,
MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2,
+ MPC85xx_MDIO,
},
},
{
.ppc_sys_name = "8555",
.mask = 0xFFFF0000,
.value = 0x80710000,
- .num_devices = 19,
+ .num_devices = 20,
.device_list = (enum ppc_sys_devices[])
{
MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1,
@@ -91,13 +93,14 @@ struct ppc_sys_spec ppc_sys_specs[] = {
MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2,
MPC85xx_CPM_SMC1, MPC85xx_CPM_SMC2,
MPC85xx_CPM_USB,
+ MPC85xx_MDIO,
},
},
{
.ppc_sys_name = "8555E",
.mask = 0xFFFF0000,
.value = 0x80790000,
- .num_devices = 20,
+ .num_devices = 21,
.device_list = (enum ppc_sys_devices[])
{
MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1,
@@ -108,6 +111,7 @@ struct ppc_sys_spec ppc_sys_specs[] = {
MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2,
MPC85xx_CPM_SMC1, MPC85xx_CPM_SMC2,
MPC85xx_CPM_USB,
+ MPC85xx_MDIO,
},
},
/* SVRs on 8548 rev1.0 matches for 8548/8547/8545 */
@@ -115,104 +119,112 @@ struct ppc_sys_spec ppc_sys_specs[] = {
.ppc_sys_name = "8548E",
.mask = 0xFFFF00F0,
.value = 0x80390010,
- .num_devices = 13,
+ .num_devices = 14,
.device_list = (enum ppc_sys_devices[])
{
MPC85xx_eTSEC1, MPC85xx_eTSEC2, MPC85xx_eTSEC3,
MPC85xx_eTSEC4, MPC85xx_IIC1, MPC85xx_IIC2,
MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2,
+ MPC85xx_MDIO,
},
},
{
.ppc_sys_name = "8548",
.mask = 0xFFFF00F0,
.value = 0x80310010,
- .num_devices = 12,
+ .num_devices = 13,
.device_list = (enum ppc_sys_devices[])
{
MPC85xx_eTSEC1, MPC85xx_eTSEC2, MPC85xx_eTSEC3,
MPC85xx_eTSEC4, MPC85xx_IIC1, MPC85xx_IIC2,
MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
MPC85xx_PERFMON, MPC85xx_DUART,
+ MPC85xx_MDIO,
},
},
{
.ppc_sys_name = "8547E",
.mask = 0xFFFF00F0,
.value = 0x80390010,
- .num_devices = 13,
+ .num_devices = 14,
.device_list = (enum ppc_sys_devices[])
{
MPC85xx_eTSEC1, MPC85xx_eTSEC2, MPC85xx_eTSEC3,
MPC85xx_eTSEC4, MPC85xx_IIC1, MPC85xx_IIC2,
MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2,
+ MPC85xx_MDIO,
},
},
{
.ppc_sys_name = "8547",
.mask = 0xFFFF00F0,
.value = 0x80310010,
- .num_devices = 12,
+ .num_devices = 13,
.device_list = (enum ppc_sys_devices[])
{
MPC85xx_eTSEC1, MPC85xx_eTSEC2, MPC85xx_eTSEC3,
MPC85xx_eTSEC4, MPC85xx_IIC1, MPC85xx_IIC2,
MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
MPC85xx_PERFMON, MPC85xx_DUART,
+ MPC85xx_MDIO,
},
},
{
.ppc_sys_name = "8545E",
.mask = 0xFFFF00F0,
.value = 0x80390010,
- .num_devices = 11,
+ .num_devices = 12,
.device_list = (enum ppc_sys_devices[])
{
MPC85xx_eTSEC1, MPC85xx_eTSEC2,
MPC85xx_IIC1, MPC85xx_IIC2,
MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2,
+ MPC85xx_MDIO,
},
},
{
.ppc_sys_name = "8545",
.mask = 0xFFFF00F0,
.value = 0x80310010,
- .num_devices = 10,
+ .num_devices = 11,
.device_list = (enum ppc_sys_devices[])
{
MPC85xx_eTSEC1, MPC85xx_eTSEC2,
MPC85xx_IIC1, MPC85xx_IIC2,
MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
MPC85xx_PERFMON, MPC85xx_DUART,
+ MPC85xx_MDIO,
},
},
{
.ppc_sys_name = "8543E",
.mask = 0xFFFF00F0,
.value = 0x803A0010,
- .num_devices = 11,
+ .num_devices = 12,
.device_list = (enum ppc_sys_devices[])
{
MPC85xx_eTSEC1, MPC85xx_eTSEC2,
MPC85xx_IIC1, MPC85xx_IIC2,
MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2,
+ MPC85xx_MDIO,
},
},
{
.ppc_sys_name = "8543",
.mask = 0xFFFF00F0,
.value = 0x80320010,
- .num_devices = 10,
+ .num_devices = 11,
.device_list = (enum ppc_sys_devices[])
{
MPC85xx_eTSEC1, MPC85xx_eTSEC2,
MPC85xx_IIC1, MPC85xx_IIC2,
MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
MPC85xx_PERFMON, MPC85xx_DUART,
+ MPC85xx_MDIO,
},
},
{ /* default match */
diff --git a/arch/ppc/syslib/mpc8xx_sys.c b/arch/ppc/syslib/mpc8xx_sys.c
index a532ccc861c0..3cc27d29e3af 100644
--- a/arch/ppc/syslib/mpc8xx_sys.c
+++ b/arch/ppc/syslib/mpc8xx_sys.c
@@ -24,7 +24,7 @@ struct ppc_sys_spec ppc_sys_specs[] = {
.ppc_sys_name = "MPC86X",
.mask = 0xFFFFFFFF,
.value = 0x00000000,
- .num_devices = 2,
+ .num_devices = 7,
.device_list = (enum ppc_sys_devices[])
{
MPC8xx_CPM_FEC1,
@@ -40,7 +40,7 @@ struct ppc_sys_spec ppc_sys_specs[] = {
.ppc_sys_name = "MPC885",
.mask = 0xFFFFFFFF,
.value = 0x00000000,
- .num_devices = 3,
+ .num_devices = 8,
.device_list = (enum ppc_sys_devices[])
{
MPC8xx_CPM_FEC1,
diff --git a/arch/ppc/syslib/mv64360_pic.c b/arch/ppc/syslib/mv64360_pic.c
index 8356da4678a2..58b0aa813e85 100644
--- a/arch/ppc/syslib/mv64360_pic.c
+++ b/arch/ppc/syslib/mv64360_pic.c
@@ -48,6 +48,7 @@
#include <asm/system.h>
#include <asm/irq.h>
#include <asm/mv64x60.h>
+#include <asm/machdep.h>
#ifdef CONFIG_IRQ_ALL_CPUS
#error "The mv64360 does not support distribution of IRQs on all CPUs"
diff --git a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c
index 1227521c0da2..94ea346b7b4b 100644
--- a/arch/ppc/syslib/mv64x60.c
+++ b/arch/ppc/syslib/mv64x60.c
@@ -1305,7 +1305,7 @@ mv64x60_config_pci_params(struct pci_controller *hose,
early_write_config_word(hose, 0, devfn, PCI_COMMAND, u16_val);
/* Set latency timer, cache line size, clear BIST */
- u16_val = (pi->latency_timer << 8) | (L1_CACHE_LINE_SIZE >> 2);
+ u16_val = (pi->latency_timer << 8) | (L1_CACHE_BYTES >> 2);
early_write_config_word(hose, 0, devfn, PCI_CACHE_LINE_SIZE, u16_val);
mv64x60_pci_exclude_bridge = save_exclude;
diff --git a/arch/ppc/syslib/mv64x60_dbg.c b/arch/ppc/syslib/mv64x60_dbg.c
index 2927c7adf5e5..fa5b2e45e0ca 100644
--- a/arch/ppc/syslib/mv64x60_dbg.c
+++ b/arch/ppc/syslib/mv64x60_dbg.c
@@ -24,6 +24,7 @@
#include <linux/irq.h>
#include <asm/delay.h>
#include <asm/mv64x60.h>
+#include <asm/machdep.h>
#if defined(CONFIG_SERIAL_TEXT_DEBUG)
diff --git a/arch/ppc/syslib/of_device.c b/arch/ppc/syslib/of_device.c
deleted file mode 100644
index 93c7231ea709..000000000000
--- a/arch/ppc/syslib/of_device.c
+++ /dev/null
@@ -1,276 +0,0 @@
-#include <linux/config.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/mod_devicetable.h>
-#include <asm/errno.h>
-#include <asm/of_device.h>
-
-/**
- * of_match_device - Tell if an of_device structure has a matching
- * of_match structure
- * @ids: array of of device match structures to search in
- * @dev: the of device structure to match against
- *
- * Used by a driver to check whether an of_device present in the
- * system is in its list of supported devices.
- */
-const struct of_device_id * of_match_device(const struct of_device_id *matches,
- const struct of_device *dev)
-{
- if (!dev->node)
- return NULL;
- while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
- int match = 1;
- if (matches->name[0])
- match &= dev->node->name
- && !strcmp(matches->name, dev->node->name);
- if (matches->type[0])
- match &= dev->node->type
- && !strcmp(matches->type, dev->node->type);
- if (matches->compatible[0])
- match &= device_is_compatible(dev->node,
- matches->compatible);
- if (match)
- return matches;
- matches++;
- }
- return NULL;
-}
-
-static int of_platform_bus_match(struct device *dev, struct device_driver *drv)
-{
- struct of_device * of_dev = to_of_device(dev);
- struct of_platform_driver * of_drv = to_of_platform_driver(drv);
- const struct of_device_id * matches = of_drv->match_table;
-
- if (!matches)
- return 0;
-
- return of_match_device(matches, of_dev) != NULL;
-}
-
-struct of_device *of_dev_get(struct of_device *dev)
-{
- struct device *tmp;
-
- if (!dev)
- return NULL;
- tmp = get_device(&dev->dev);
- if (tmp)
- return to_of_device(tmp);
- else
- return NULL;
-}
-
-void of_dev_put(struct of_device *dev)
-{
- if (dev)
- put_device(&dev->dev);
-}
-
-
-static int of_device_probe(struct device *dev)
-{
- int error = -ENODEV;
- struct of_platform_driver *drv;
- struct of_device *of_dev;
- const struct of_device_id *match;
-
- drv = to_of_platform_driver(dev->driver);
- of_dev = to_of_device(dev);
-
- if (!drv->probe)
- return error;
-
- of_dev_get(of_dev);
-
- match = of_match_device(drv->match_table, of_dev);
- if (match)
- error = drv->probe(of_dev, match);
- if (error)
- of_dev_put(of_dev);
-
- return error;
-}
-
-static int of_device_remove(struct device *dev)
-{
- struct of_device * of_dev = to_of_device(dev);
- struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
-
- if (dev->driver && drv->remove)
- drv->remove(of_dev);
- return 0;
-}
-
-static int of_device_suspend(struct device *dev, pm_message_t state)
-{
- struct of_device * of_dev = to_of_device(dev);
- struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
- int error = 0;
-
- if (dev->driver && drv->suspend)
- error = drv->suspend(of_dev, state);
- return error;
-}
-
-static int of_device_resume(struct device * dev)
-{
- struct of_device * of_dev = to_of_device(dev);
- struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
- int error = 0;
-
- if (dev->driver && drv->resume)
- error = drv->resume(of_dev);
- return error;
-}
-
-struct bus_type of_platform_bus_type = {
- .name = "of_platform",
- .match = of_platform_bus_match,
- .suspend = of_device_suspend,
- .resume = of_device_resume,
-};
-
-static int __init of_bus_driver_init(void)
-{
- return bus_register(&of_platform_bus_type);
-}
-
-postcore_initcall(of_bus_driver_init);
-
-int of_register_driver(struct of_platform_driver *drv)
-{
- int count = 0;
-
- /* initialize common driver fields */
- drv->driver.name = drv->name;
- drv->driver.bus = &of_platform_bus_type;
- drv->driver.probe = of_device_probe;
- drv->driver.remove = of_device_remove;
-
- /* register with core */
- count = driver_register(&drv->driver);
- return count ? count : 1;
-}
-
-void of_unregister_driver(struct of_platform_driver *drv)
-{
- driver_unregister(&drv->driver);
-}
-
-
-static ssize_t dev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct of_device *ofdev;
-
- ofdev = to_of_device(dev);
- return sprintf(buf, "%s", ofdev->node->full_name);
-}
-
-static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL);
-
-/**
- * of_release_dev - free an of device structure when all users of it are finished.
- * @dev: device that's been disconnected
- *
- * Will be called only by the device core when all users of this of device are
- * done.
- */
-void of_release_dev(struct device *dev)
-{
- struct of_device *ofdev;
-
- ofdev = to_of_device(dev);
- of_node_put(ofdev->node);
- kfree(ofdev);
-}
-
-int of_device_register(struct of_device *ofdev)
-{
- int rc;
- struct of_device **odprop;
-
- BUG_ON(ofdev->node == NULL);
-
- odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL);
- if (!odprop) {
- struct property *new_prop;
-
- new_prop = kmalloc(sizeof(struct property) + sizeof(struct of_device *),
- GFP_KERNEL);
- if (new_prop == NULL)
- return -ENOMEM;
- new_prop->name = "linux,device";
- new_prop->length = sizeof(sizeof(struct of_device *));
- new_prop->value = (unsigned char *)&new_prop[1];
- odprop = (struct of_device **)new_prop->value;
- *odprop = NULL;
- prom_add_property(ofdev->node, new_prop);
- }
- *odprop = ofdev;
-
- rc = device_register(&ofdev->dev);
- if (rc)
- return rc;
-
- device_create_file(&ofdev->dev, &dev_attr_devspec);
-
- return 0;
-}
-
-void of_device_unregister(struct of_device *ofdev)
-{
- struct of_device **odprop;
-
- device_remove_file(&ofdev->dev, &dev_attr_devspec);
-
- odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL);
- if (odprop)
- *odprop = NULL;
-
- device_unregister(&ofdev->dev);
-}
-
-struct of_device* of_platform_device_create(struct device_node *np,
- const char *bus_id,
- struct device *parent)
-{
- struct of_device *dev;
- u32 *reg;
-
- dev = kmalloc(sizeof(*dev), GFP_KERNEL);
- if (!dev)
- return NULL;
- memset(dev, 0, sizeof(*dev));
-
- dev->node = of_node_get(np);
- dev->dma_mask = 0xffffffffUL;
- dev->dev.dma_mask = &dev->dma_mask;
- dev->dev.parent = parent;
- dev->dev.bus = &of_platform_bus_type;
- dev->dev.release = of_release_dev;
-
- reg = (u32 *)get_property(np, "reg", NULL);
- strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE);
-
- if (of_device_register(dev) != 0) {
- kfree(dev);
- return NULL;
- }
-
- return dev;
-}
-
-EXPORT_SYMBOL(of_match_device);
-EXPORT_SYMBOL(of_platform_bus_type);
-EXPORT_SYMBOL(of_register_driver);
-EXPORT_SYMBOL(of_unregister_driver);
-EXPORT_SYMBOL(of_device_register);
-EXPORT_SYMBOL(of_device_unregister);
-EXPORT_SYMBOL(of_dev_get);
-EXPORT_SYMBOL(of_dev_put);
-EXPORT_SYMBOL(of_platform_device_create);
-EXPORT_SYMBOL(of_release_dev);
diff --git a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c
index 1cf5de21a3fd..894779712b46 100644
--- a/arch/ppc/syslib/open_pic.c
+++ b/arch/ppc/syslib/open_pic.c
@@ -23,6 +23,7 @@
#include <asm/sections.h>
#include <asm/open_pic.h>
#include <asm/i8259.h>
+#include <asm/machdep.h>
#include "open_pic_defs.h"
@@ -889,7 +890,7 @@ openpic_get_irq(struct pt_regs *regs)
#ifdef CONFIG_SMP
void
-smp_openpic_message_pass(int target, int msg, unsigned long data, int wait)
+smp_openpic_message_pass(int target, int msg)
{
cpumask_t mask = CPU_MASK_ALL;
/* make sure we're sending something that translates to an IPI */
diff --git a/arch/ppc/syslib/open_pic2.c b/arch/ppc/syslib/open_pic2.c
index 16cff91d9f41..1c40049b9a45 100644
--- a/arch/ppc/syslib/open_pic2.c
+++ b/arch/ppc/syslib/open_pic2.c
@@ -27,6 +27,7 @@
#include <asm/sections.h>
#include <asm/open_pic.h>
#include <asm/i8259.h>
+#include <asm/machdep.h>
#include "open_pic_defs.h"
diff --git a/arch/ppc/syslib/ppc403_pic.c b/arch/ppc/syslib/ppc403_pic.c
index ce4d1deb86e9..c46043c47225 100644
--- a/arch/ppc/syslib/ppc403_pic.c
+++ b/arch/ppc/syslib/ppc403_pic.c
@@ -26,6 +26,7 @@
#include <asm/system.h>
#include <asm/irq.h>
#include <asm/ppc4xx_pic.h>
+#include <asm/machdep.h>
/* Function Prototypes */
diff --git a/arch/ppc/syslib/ppc4xx_pic.c b/arch/ppc/syslib/ppc4xx_pic.c
index 40086212b9c3..0b435633a0d1 100644
--- a/arch/ppc/syslib/ppc4xx_pic.c
+++ b/arch/ppc/syslib/ppc4xx_pic.c
@@ -25,6 +25,7 @@
#include <asm/system.h>
#include <asm/irq.h>
#include <asm/ppc4xx_pic.h>
+#include <asm/machdep.h>
/* See comment in include/arch-ppc/ppc4xx_pic.h
* for more info about these two variables
diff --git a/arch/ppc/syslib/ppc4xx_setup.c b/arch/ppc/syslib/ppc4xx_setup.c
index bf83240689dc..e83a83fd95e1 100644
--- a/arch/ppc/syslib/ppc4xx_setup.c
+++ b/arch/ppc/syslib/ppc4xx_setup.c
@@ -278,7 +278,7 @@ ppc4xx_init(unsigned long r3, unsigned long r4, unsigned long r5,
#endif /* defined(CONFIG_PCI) && defined(CONFIG_IDE) */
}
-/* Called from MachineCheckException */
+/* Called from machine_check_exception */
void platform_machine_check(struct pt_regs *regs)
{
#if defined(DCRN_PLB0_BEAR)
diff --git a/arch/ppc/syslib/ppc83xx_setup.c b/arch/ppc/syslib/ppc83xx_setup.c
index 890484e576e7..4da168a6ad03 100644
--- a/arch/ppc/syslib/ppc83xx_setup.c
+++ b/arch/ppc/syslib/ppc83xx_setup.c
@@ -40,6 +40,7 @@
#include <asm/ppc_sys.h>
#include <asm/kgdb.h>
#include <asm/delay.h>
+#include <asm/machdep.h>
#include <syslib/ppc83xx_setup.h>
#if defined(CONFIG_PCI)
diff --git a/arch/ppc/syslib/ppc85xx_setup.c b/arch/ppc/syslib/ppc85xx_setup.c
index 832b8bf99ae7..de2f90576577 100644
--- a/arch/ppc/syslib/ppc85xx_setup.c
+++ b/arch/ppc/syslib/ppc85xx_setup.c
@@ -29,6 +29,7 @@
#include <asm/mmu.h>
#include <asm/ppc_sys.h>
#include <asm/kgdb.h>
+#include <asm/machdep.h>
#include <syslib/ppc85xx_setup.h>
diff --git a/arch/ppc/syslib/ppc8xx_pic.c b/arch/ppc/syslib/ppc8xx_pic.c
index d3b01c6c97de..3e6f51a61d46 100644
--- a/arch/ppc/syslib/ppc8xx_pic.c
+++ b/arch/ppc/syslib/ppc8xx_pic.c
@@ -6,6 +6,7 @@
#include <linux/signal.h>
#include <linux/interrupt.h>
#include <asm/irq.h>
+#include <asm/io.h>
#include <asm/8xx_immap.h>
#include <asm/mpc8xx.h>
#include "ppc8xx_pic.h"
@@ -29,8 +30,7 @@ static void m8xx_mask_irq(unsigned int irq_nr)
word = irq_nr >> 5;
ppc_cached_irq_mask[word] &= ~(1 << (31-bit));
- ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask =
- ppc_cached_irq_mask[word];
+ out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask, ppc_cached_irq_mask[word]);
}
static void m8xx_unmask_irq(unsigned int irq_nr)
@@ -41,8 +41,7 @@ static void m8xx_unmask_irq(unsigned int irq_nr)
word = irq_nr >> 5;
ppc_cached_irq_mask[word] |= (1 << (31-bit));
- ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask =
- ppc_cached_irq_mask[word];
+ out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask, ppc_cached_irq_mask[word]);
}
static void m8xx_end_irq(unsigned int irq_nr)
@@ -55,8 +54,7 @@ static void m8xx_end_irq(unsigned int irq_nr)
word = irq_nr >> 5;
ppc_cached_irq_mask[word] |= (1 << (31-bit));
- ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask =
- ppc_cached_irq_mask[word];
+ out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask, ppc_cached_irq_mask[word]);
}
}
@@ -69,9 +67,8 @@ static void m8xx_mask_and_ack(unsigned int irq_nr)
word = irq_nr >> 5;
ppc_cached_irq_mask[word] &= ~(1 << (31-bit));
- ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask =
- ppc_cached_irq_mask[word];
- ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sipend = 1 << (31-bit);
+ out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask, ppc_cached_irq_mask[word]);
+ out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sipend, 1 << (31-bit));
}
struct hw_interrupt_type ppc8xx_pic = {
@@ -93,7 +90,7 @@ m8xx_get_irq(struct pt_regs *regs)
/* For MPC8xx, read the SIVEC register and shift the bits down
* to get the irq number.
*/
- irq = ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sivec >> 26;
+ irq = in_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sivec) >> 26;
/*
* When we read the sivec without an interrupt to process, we will
diff --git a/arch/ppc/syslib/ppc_sys.c b/arch/ppc/syslib/ppc_sys.c
index 52ba0c68078d..62ee86e80711 100644
--- a/arch/ppc/syslib/ppc_sys.c
+++ b/arch/ppc/syslib/ppc_sys.c
@@ -69,6 +69,9 @@ static int __init find_chip_by_name_and_id(char *name, u32 id)
matched[j++] = i;
i++;
}
+
+ ret = i;
+
if (j != 0) {
for (i = 0; i < j; i++) {
if ((ppc_sys_specs[matched[i]].mask & id) ==
diff --git a/arch/ppc/syslib/pq2_devices.c b/arch/ppc/syslib/pq2_devices.c
index 61668aad86e2..e960fe935325 100644
--- a/arch/ppc/syslib/pq2_devices.c
+++ b/arch/ppc/syslib/pq2_devices.c
@@ -18,6 +18,7 @@
#include <asm/cpm2.h>
#include <asm/irq.h>
#include <asm/ppc_sys.h>
+#include <asm/machdep.h>
struct platform_device ppc_sys_platform_devices[] = {
[MPC82xx_CPM_FCC1] = {
diff --git a/arch/ppc/syslib/prep_nvram.c b/arch/ppc/syslib/prep_nvram.c
index 8599850ca772..2c6364d9641f 100644
--- a/arch/ppc/syslib/prep_nvram.c
+++ b/arch/ppc/syslib/prep_nvram.c
@@ -22,14 +22,14 @@
static char nvramData[MAX_PREP_NVRAM];
static NVRAM_MAP *nvram=(NVRAM_MAP *)&nvramData[0];
-unsigned char __prep prep_nvram_read_val(int addr)
+unsigned char prep_nvram_read_val(int addr)
{
outb(addr, PREP_NVRAM_AS0);
outb(addr>>8, PREP_NVRAM_AS1);
return inb(PREP_NVRAM_DATA);
}
-void __prep prep_nvram_write_val(int addr,
+void prep_nvram_write_val(int addr,
unsigned char val)
{
outb(addr, PREP_NVRAM_AS0);
@@ -81,8 +81,7 @@ void __init init_prep_nvram(void)
}
}
-__prep
-char __prep *prep_nvram_get_var(const char *name)
+char *prep_nvram_get_var(const char *name)
{
char *cp;
int namelen;
@@ -101,8 +100,7 @@ char __prep *prep_nvram_get_var(const char *name)
return NULL;
}
-__prep
-char __prep *prep_nvram_first_var(void)
+char *prep_nvram_first_var(void)
{
if (nvram->Header.GELength == 0) {
return NULL;
@@ -112,8 +110,7 @@ char __prep *prep_nvram_first_var(void)
}
}
-__prep
-char __prep *prep_nvram_next_var(char *name)
+char *prep_nvram_next_var(char *name)
{
char *cp;
diff --git a/arch/ppc/syslib/prom.c b/arch/ppc/syslib/prom.c
index 2c64ed627475..278da6ee62ea 100644
--- a/arch/ppc/syslib/prom.c
+++ b/arch/ppc/syslib/prom.c
@@ -89,7 +89,7 @@ extern char cmd_line[512]; /* XXX */
extern boot_infos_t *boot_infos;
unsigned long dev_tree_size;
-void __openfirmware
+void
phys_call_rtas(int service, int nargs, int nret, ...)
{
va_list list;
@@ -862,7 +862,7 @@ find_type_devices(const char *type)
/*
* Returns all nodes linked together
*/
-struct device_node * __openfirmware
+struct device_node *
find_all_nodes(void)
{
struct device_node *head, **prevp, *np;
@@ -1165,7 +1165,7 @@ get_property(struct device_node *np, const char *name, int *lenp)
/*
* Add a property to a node
*/
-void __openfirmware
+void
prom_add_property(struct device_node* np, struct property* prop)
{
struct property **next = &np->properties;
@@ -1177,7 +1177,7 @@ prom_add_property(struct device_node* np, struct property* prop)
}
/* I quickly hacked that one, check against spec ! */
-static inline unsigned long __openfirmware
+static inline unsigned long
bus_space_to_resource_flags(unsigned int bus_space)
{
u8 space = (bus_space >> 24) & 0xf;
@@ -1194,7 +1194,7 @@ bus_space_to_resource_flags(unsigned int bus_space)
}
}
-static struct resource* __openfirmware
+static struct resource*
find_parent_pci_resource(struct pci_dev* pdev, struct address_range *range)
{
unsigned long mask;
@@ -1224,7 +1224,7 @@ find_parent_pci_resource(struct pci_dev* pdev, struct address_range *range)
* or other nodes attached to the root node. Ultimately, put some
* link to resources in the OF node.
*/
-struct resource* __openfirmware
+struct resource*
request_OF_resource(struct device_node* node, int index, const char* name_postfix)
{
struct pci_dev* pcidev;
@@ -1280,7 +1280,7 @@ fail:
return NULL;
}
-int __openfirmware
+int
release_OF_resource(struct device_node* node, int index)
{
struct pci_dev* pcidev;
@@ -1346,7 +1346,7 @@ release_OF_resource(struct device_node* node, int index)
}
#if 0
-void __openfirmware
+void
print_properties(struct device_node *np)
{
struct property *pp;
@@ -1400,7 +1400,7 @@ print_properties(struct device_node *np)
static DEFINE_SPINLOCK(rtas_lock);
/* this can be called after setup -- Cort */
-int __openfirmware
+int
call_rtas(const char *service, int nargs, int nret,
unsigned long *outputs, ...)
{
diff --git a/arch/ppc/syslib/xilinx_pic.c b/arch/ppc/syslib/xilinx_pic.c
index 2cbcad278cef..47f04c71fe9c 100644
--- a/arch/ppc/syslib/xilinx_pic.c
+++ b/arch/ppc/syslib/xilinx_pic.c
@@ -17,6 +17,7 @@
#include <asm/io.h>
#include <asm/xparameters.h>
#include <asm/ibm4xx.h>
+#include <asm/machdep.h>
/* No one else should require these constants, so define them locally here. */
#define ISR 0 /* Interrupt Status Register */
diff --git a/arch/ppc/xmon/start.c b/arch/ppc/xmon/start.c
index 507d4eeffe07..98612d420346 100644
--- a/arch/ppc/xmon/start.c
+++ b/arch/ppc/xmon/start.c
@@ -478,8 +478,9 @@ void *xmon_stdout;
void *xmon_stderr;
void
-xmon_init(void)
+xmon_init(int arg)
{
+ xmon_map_scc();
}
int
diff --git a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c
index be7869e39465..66bfaa3211a2 100644
--- a/arch/ppc/xmon/xmon.c
+++ b/arch/ppc/xmon/xmon.c
@@ -148,9 +148,14 @@ Commands:\n\
r print registers\n\
S print special registers\n\
t print backtrace\n\
- la lookup address in system.map\n\
- ls lookup symbol in system.map\n\
+ la lookup address\n\
+ ls lookup symbol\n\
+ C checksum\n\
+ p call function with arguments\n\
+ T print time\n\
x exit monitor\n\
+ zr reboot\n\
+ zh halt\n\
";
static int xmon_trace[NR_CPUS];
diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig
index c658650af429..42677cc96508 100644
--- a/arch/ppc64/Kconfig
+++ b/arch/ppc64/Kconfig
@@ -10,6 +10,9 @@ config MMU
bool
default y
+config PPC_STD_MMU
+ def_bool y
+
config UID16
bool
@@ -120,6 +123,11 @@ config MPIC
bool
default y
+config PPC_I8259
+ depends on PPC_PSERIES
+ bool
+ default y
+
config BPA_IIC
depends on PPC_BPA
bool
@@ -186,6 +194,12 @@ config BOOTX_TEXT
Say Y here to see progress messages from the boot firmware in text
mode. Requires an Open Firmware compatible video card.
+config POWER4
+ def_bool y
+
+config PPC_FPU
+ def_bool y
+
config POWER4_ONLY
bool "Optimize for POWER4"
default n
@@ -234,6 +248,10 @@ config HMT
This option enables hardware multithreading on RS64 cpus.
pSeries systems p620 and p660 have such a cpu type.
+config NUMA
+ bool "NUMA support"
+ default y if SMP && PPC_PSERIES
+
config ARCH_SELECT_MEMORY_MODEL
def_bool y
@@ -249,9 +267,6 @@ config ARCH_DISCONTIGMEM_DEFAULT
def_bool y
depends on ARCH_DISCONTIGMEM_ENABLE
-config ARCH_FLATMEM_ENABLE
- def_bool y
-
config ARCH_SPARSEMEM_ENABLE
def_bool y
depends on ARCH_DISCONTIGMEM_ENABLE
@@ -274,10 +289,6 @@ config NODES_SPAN_OTHER_NODES
def_bool y
depends on NEED_MULTIPLE_NODES
-config NUMA
- bool "NUMA support"
- default y if DISCONTIGMEM || SPARSEMEM
-
config SCHED_SMT
bool "SMT (Hyperthreading) scheduler support"
depends on SMP
@@ -307,6 +318,11 @@ config PPC_RTAS
depends on PPC_PSERIES || PPC_BPA
default y
+config RTAS_ERROR_LOGGING
+ bool
+ depends on PPC_RTAS
+ default y
+
config RTAS_PROC
bool "Proc interface to RTAS"
depends on PPC_RTAS
@@ -357,7 +373,6 @@ config HOTPLUG_CPU
config PROC_DEVICETREE
bool "Support for Open Firmware device tree in /proc"
- depends on !PPC_ISERIES
help
This option adds a device-tree directory under /proc which contains
an image of the device tree that the kernel copies from Open
@@ -461,7 +476,7 @@ config VIOPATH
depends on VIOCONS || VIODASD || VIOCD || VIOTAPE || VETH
default y
-source "arch/ppc64/oprofile/Kconfig"
+source "arch/powerpc/oprofile/Kconfig"
source "arch/ppc64/Kconfig.debug"
diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile
index 521c2a5a2862..fdbd6f44adc0 100644
--- a/arch/ppc64/Makefile
+++ b/arch/ppc64/Makefile
@@ -75,17 +75,25 @@ else
CFLAGS += $(call cc-option,-mtune=power4)
endif
+# No AltiVec instruction when building kernel
+CFLAGS += $(call cc-option, -mno-altivec)
+
# Enable unit-at-a-time mode when possible. It shrinks the
# kernel considerably.
CFLAGS += $(call cc-option,-funit-at-a-time)
head-y := arch/ppc64/kernel/head.o
+head-y += arch/powerpc/kernel/fpu.o
+head-y += arch/powerpc/kernel/entry_64.o
libs-y += arch/ppc64/lib/
-core-y += arch/ppc64/kernel/
-core-y += arch/ppc64/mm/
-core-$(CONFIG_XMON) += arch/ppc64/xmon/
-drivers-$(CONFIG_OPROFILE) += arch/ppc64/oprofile/
+core-y += arch/ppc64/kernel/ arch/powerpc/kernel/
+core-y += arch/powerpc/mm/
+core-y += arch/powerpc/sysdev/
+core-y += arch/powerpc/platforms/
+core-y += arch/powerpc/lib/
+core-$(CONFIG_XMON) += arch/powerpc/xmon/
+drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/
boot := arch/ppc64/boot
@@ -100,7 +108,7 @@ $(boottargets-y): vmlinux
bootimage-$(CONFIG_PPC_PSERIES) := $(boot)/zImage
bootimage-$(CONFIG_PPC_PMAC) := vmlinux
bootimage-$(CONFIG_PPC_MAPLE) := $(boot)/zImage
-bootimage-$(CONFIG_PPC_BPA) := zImage
+bootimage-$(CONFIG_PPC_BPA) := $(boot)/zImage
bootimage-$(CONFIG_PPC_ISERIES) := vmlinux
BOOTIMAGE := $(bootimage-y)
install: vmlinux
diff --git a/arch/ppc64/boot/Makefile b/arch/ppc64/boot/Makefile
index 33fdc8710891..301bc1536c49 100644
--- a/arch/ppc64/boot/Makefile
+++ b/arch/ppc64/boot/Makefile
@@ -22,15 +22,46 @@
HOSTCC := gcc
-BOOTCFLAGS := $(HOSTCFLAGS) -fno-builtin -nostdinc -isystem $(shell $(CROSS32CC) -print-file-name=include)
+BOOTCFLAGS := $(HOSTCFLAGS) -fno-builtin -nostdinc -isystem $(shell $(CROSS32CC) -print-file-name=include) -fPIC
BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc
-BOOTLFLAGS := -Ttext 0x00400000 -e _start -T $(srctree)/$(src)/zImage.lds
+BOOTLFLAGS := -T $(srctree)/$(src)/zImage.lds
OBJCOPYFLAGS := contents,alloc,load,readonly,data
-src-boot := crt0.S string.S prom.c main.c zlib.c imagesize.c div64.S
+zlib := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c
+zlibheader := infblock.h infcodes.h inffast.h inftrees.h infutil.h
+zliblinuxheader := zlib.h zconf.h zutil.h
+
+$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
+#$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h)
+
+src-boot := string.S prom.c main.c div64.S crt0.S
+src-boot += $(zlib)
src-boot := $(addprefix $(obj)/, $(src-boot))
obj-boot := $(addsuffix .o, $(basename $(src-boot)))
+BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj)
+
+quiet_cmd_copy_zlib = COPY $@
+ cmd_copy_zlib = sed "s@__attribute_used__@@;s@<linux/\([^>]\+\).*@\"\1\"@" $< > $@
+
+quiet_cmd_copy_zlibheader = COPY $@
+ cmd_copy_zlibheader = sed "s@<linux/\([^>]\+\).*@\"\1\"@" $< > $@
+# stddef.h for NULL
+quiet_cmd_copy_zliblinuxheader = COPY $@
+ cmd_copy_zliblinuxheader = sed "s@<linux/string.h>@\"string.h\"@;s@<linux/kernel.h>@<stddef.h>@;s@<linux/\([^>]\+\).*@\"\1\"@" $< > $@
+
+$(addprefix $(obj)/,$(zlib)): $(obj)/%: $(srctree)/lib/zlib_inflate/%
+ $(call cmd,copy_zlib)
+
+$(addprefix $(obj)/,$(zlibheader)): $(obj)/%: $(srctree)/lib/zlib_inflate/%
+ $(call cmd,copy_zlibheader)
+
+$(addprefix $(obj)/,$(zliblinuxheader)): $(obj)/%: $(srctree)/include/linux/%
+ $(call cmd,copy_zliblinuxheader)
+
+clean-files := $(zlib) $(zlibheader) $(zliblinuxheader)
+
+
quiet_cmd_bootcc = BOOTCC $@
cmd_bootcc = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $<
@@ -56,7 +87,7 @@ src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(section)))
gz-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section)))
hostprogs-y := addnote addRamDisk
-targets += zImage.vmode zImage.initrd.vmode zImage zImage.initrd imagesize.c \
+targets += zImage.vmode zImage.initrd.vmode zImage zImage.initrd \
$(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \
$(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \
$(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \
@@ -69,9 +100,9 @@ quiet_cmd_ramdisk = RAMDISK $@
quiet_cmd_stripvm = STRIP $@
cmd_stripvm = $(STRIP) -s $< -o $@
-vmlinux.strip: vmlinux FORCE
+vmlinux.strip: vmlinux
$(call if_changed,stripvm)
-$(obj)/vmlinux.initrd: vmlinux.strip $(obj)/addRamDisk $(obj)/ramdisk.image.gz FORCE
+$(obj)/vmlinux.initrd: vmlinux.strip $(obj)/addRamDisk $(obj)/ramdisk.image.gz
$(call if_changed,ramdisk)
quiet_cmd_addsection = ADDSEC $@
@@ -79,48 +110,38 @@ quiet_cmd_addsection = ADDSEC $@
--add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(patsubst %.o,%.gz, $@) \
--set-section-flags=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(OBJCOPYFLAGS)
-quiet_cmd_imagesize = GENSIZE $@
- cmd_imagesize = ls -l vmlinux.strip | \
- awk '{printf "/* generated -- do not edit! */\n" "unsigned long vmlinux_filesize = %d;\n", $$5}' \
- > $(obj)/imagesize.c && \
- $(CROSS_COMPILE)nm -n vmlinux | tail -n 1 | \
- awk '{printf "unsigned long vmlinux_memsize = 0x%s;\n", substr($$1,8)}' >> $(obj)/imagesize.c
-
quiet_cmd_addnote = ADDNOTE $@
cmd_addnote = $(obj)/addnote $@
-$(call gz-sec, $(required)): $(obj)/kernel-%.gz: % FORCE
+$(call gz-sec, $(required)): $(obj)/kernel-%.gz: %
$(call if_changed,gzip)
$(obj)/kernel-initrd.gz: $(obj)/ramdisk.image.gz
cp -f $(obj)/ramdisk.image.gz $@
-$(call src-sec, $(required) $(initrd)): $(obj)/kernel-%.c: $(obj)/kernel-%.gz FORCE
+$(call src-sec, $(required) $(initrd)): $(obj)/kernel-%.c: $(obj)/kernel-%.gz
@touch $@
-$(call obj-sec, $(required) $(initrd)): $(obj)/kernel-%.o: $(obj)/kernel-%.c FORCE
+$(call obj-sec, $(required) $(initrd)): $(obj)/kernel-%.o: $(obj)/kernel-%.c
$(call if_changed_dep,bootcc)
$(call cmd,addsection)
$(obj)/zImage.vmode: obj-boot += $(call obj-sec, $(required))
-$(obj)/zImage.vmode: $(call obj-sec, $(required)) $(obj-boot) FORCE
+$(obj)/zImage.vmode: $(call obj-sec, $(required)) $(obj-boot) $(srctree)/$(src)/zImage.lds
$(call cmd,bootld,$(obj-boot))
$(obj)/zImage.initrd.vmode: obj-boot += $(call obj-sec, $(required) $(initrd))
-$(obj)/zImage.initrd.vmode: $(call obj-sec, $(required) $(initrd)) $(obj-boot) FORCE
+$(obj)/zImage.initrd.vmode: $(call obj-sec, $(required) $(initrd)) $(obj-boot) $(srctree)/$(src)/zImage.lds
$(call cmd,bootld,$(obj-boot))
-$(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote FORCE
+$(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote
@cp -f $< $@
$(call if_changed,addnote)
-$(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote FORCE
+$(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote
@cp -f $< $@
$(call if_changed,addnote)
-$(obj)/imagesize.c: vmlinux.strip
- $(call cmd,imagesize)
-
install: $(CONFIGURE) $(BOOTIMAGE)
sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" "$(BOOTIMAGE)"
diff --git a/arch/ppc64/boot/crt0.S b/arch/ppc64/boot/crt0.S
index 3861e7f9cf19..9cc442263939 100644
--- a/arch/ppc64/boot/crt0.S
+++ b/arch/ppc64/boot/crt0.S
@@ -12,11 +12,40 @@
#include "ppc_asm.h"
.text
- .globl _start
-_start:
+ .globl _zimage_start
+_zimage_start:
+ bl reloc_offset
+
+reloc_offset:
+ mflr r0
+ lis r9,reloc_offset@ha
+ addi r9,r9,reloc_offset@l
+ subf. r0,r9,r0
+ beq clear_caches
+
+reloc_got2:
+ lis r9,__got2_start@ha
+ addi r9,r9,__got2_start@l
+ lis r8,__got2_end@ha
+ addi r8,r8,__got2_end@l
+ subf. r8,r9,r8
+ beq clear_caches
+ srwi. r8,r8,2
+ mtctr r8
+ add r9,r0,r9
+reloc_got2_loop:
+ lwz r8,0(r9)
+ add r8,r8,r0
+ stw r8,0(r9)
+ addi r9,r9,4
+ bdnz reloc_got2_loop
+
+clear_caches:
lis r9,_start@h
+ add r9,r0,r9
lis r8,_etext@ha
addi r8,r8,_etext@l
+ add r8,r0,r8
1: dcbf r0,r9
icbi r0,r9
addi r9,r9,0x20
@@ -25,24 +54,6 @@ _start:
sync
isync
- ## Clear out the BSS as per ANSI C requirements
-
- lis r7,_end@ha
- addi r7,r7,_end@l # r7 = &_end
- lis r8,__bss_start@ha #
- addi r8,r8,__bss_start@l # r8 = &_bss_start
-
- ## Determine how large an area, in number of words, to clear
-
- subf r7,r8,r7 # r7 = &_end - &_bss_start + 1
- addi r7,r7,3 # r7 += 3
- srwi. r7,r7,2 # r7 = size in words.
- beq 3f # If the size is zero, don't bother
- addi r8,r8,-4 # r8 -= 4
- mtctr r7 # SPRN_CTR = number of words to clear
- li r0,0 # r0 = 0
-2: stwu r0,4(r8) # Clear out a word
- bdnz 2b # Keep clearing until done
-3:
+ mr r6,r1
b start
diff --git a/arch/ppc64/boot/install.sh b/arch/ppc64/boot/install.sh
index cb2d6626b555..eacce9590816 100644
--- a/arch/ppc64/boot/install.sh
+++ b/arch/ppc64/boot/install.sh
@@ -28,7 +28,7 @@ if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then exec /sbin/${CROSS_COMPILE}i
# Default install
# this should work for both the pSeries zImage and the iSeries vmlinux.sm
-image_name=`basename $5`
+image_name=`basename $2`
if [ -f $4/$image_name ]; then
mv $4/$image_name $4/$image_name.old
diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c
index f7ec19a2d0b0..c1dc876bccab 100644
--- a/arch/ppc64/boot/main.c
+++ b/arch/ppc64/boot/main.c
@@ -17,7 +17,6 @@
#include "prom.h"
#include "zlib.h"
-static void gunzip(void *, int, unsigned char *, int *);
extern void flush_cache(void *, unsigned long);
@@ -26,31 +25,26 @@ extern void flush_cache(void *, unsigned long);
#define RAM_END (512<<20) // Fixme: use OF */
#define ONE_MB 0x100000
-static char *avail_ram;
-static char *begin_avail, *end_avail;
-static char *avail_high;
-static unsigned int heap_use;
-static unsigned int heap_max;
-
extern char _start[];
+extern char __bss_start[];
extern char _end[];
extern char _vmlinux_start[];
extern char _vmlinux_end[];
extern char _initrd_start[];
extern char _initrd_end[];
-extern unsigned long vmlinux_filesize;
-extern unsigned long vmlinux_memsize;
struct addr_range {
unsigned long addr;
unsigned long size;
unsigned long memsize;
};
-static struct addr_range vmlinux = {0, 0, 0};
-static struct addr_range vmlinuz = {0, 0, 0};
-static struct addr_range initrd = {0, 0, 0};
+static struct addr_range vmlinux;
+static struct addr_range vmlinuz;
+static struct addr_range initrd;
+
+static char scratch[46912]; /* scratch space for gunzip, from zlib_inflate_workspacesize() */
+static char elfheader[256];
-static char scratch[128<<10]; /* 128kB of scratch space for gunzip */
typedef void (*kernel_entry_t)( unsigned long,
unsigned long,
@@ -62,6 +56,63 @@ typedef void (*kernel_entry_t)( unsigned long,
static unsigned long claim_base;
+#define HEAD_CRC 2
+#define EXTRA_FIELD 4
+#define ORIG_NAME 8
+#define COMMENT 0x10
+#define RESERVED 0xe0
+
+static void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
+{
+ z_stream s;
+ int r, i, flags;
+
+ /* skip header */
+ i = 10;
+ flags = src[3];
+ if (src[2] != Z_DEFLATED || (flags & RESERVED) != 0) {
+ printf("bad gzipped data\n\r");
+ exit();
+ }
+ if ((flags & EXTRA_FIELD) != 0)
+ i = 12 + src[10] + (src[11] << 8);
+ if ((flags & ORIG_NAME) != 0)
+ while (src[i++] != 0)
+ ;
+ if ((flags & COMMENT) != 0)
+ while (src[i++] != 0)
+ ;
+ if ((flags & HEAD_CRC) != 0)
+ i += 2;
+ if (i >= *lenp) {
+ printf("gunzip: ran out of data in header\n\r");
+ exit();
+ }
+
+ if (zlib_inflate_workspacesize() > sizeof(scratch)) {
+ printf("gunzip needs more mem\n");
+ exit();
+ }
+ memset(&s, 0, sizeof(s));
+ s.workspace = scratch;
+ r = zlib_inflateInit2(&s, -MAX_WBITS);
+ if (r != Z_OK) {
+ printf("inflateInit2 returned %d\n\r", r);
+ exit();
+ }
+ s.next_in = src + i;
+ s.avail_in = *lenp - i;
+ s.next_out = dst;
+ s.avail_out = dstlen;
+ r = zlib_inflate(&s, Z_FULL_FLUSH);
+ if (r != Z_OK && r != Z_STREAM_END) {
+ printf("inflate returned %d msg: %s\n\r", r, s.msg);
+ exit();
+ }
+ *lenp = s.next_out - (unsigned char *) dst;
+ zlib_inflateEnd(&s);
+}
+
static unsigned long try_claim(unsigned long size)
{
unsigned long addr = 0;
@@ -80,13 +131,16 @@ static unsigned long try_claim(unsigned long size)
return addr;
}
-void start(unsigned long a1, unsigned long a2, void *promptr)
+void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
{
unsigned long i;
+ int len;
kernel_entry_t kernel_entry;
Elf64_Ehdr *elf64;
Elf64_Phdr *elf64ph;
+ memset(__bss_start, 0, _end - __bss_start);
+
prom = (int (*)(void *)) promptr;
chosen_handle = finddevice("/chosen");
if (chosen_handle == (void *) -1)
@@ -97,7 +151,7 @@ void start(unsigned long a1, unsigned long a2, void *promptr)
if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4)
exit();
- printf("\n\rzImage starting: loaded at 0x%lx\n\r", (unsigned long) _start);
+ printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", _start, sp);
/*
* The first available claim_base must be above the end of the
@@ -118,25 +172,45 @@ void start(unsigned long a1, unsigned long a2, void *promptr)
claim_base = PROG_START;
#endif
- /*
- * Now we try to claim some memory for the kernel itself
- * our "vmlinux_memsize" is the memory footprint in RAM, _HOWEVER_, what
- * our Makefile stuffs in is an image containing all sort of junk including
- * an ELF header. We need to do some calculations here to find the right
- * size... In practice we add 1Mb, that is enough, but we should really
- * consider fixing the Makefile to put a _raw_ kernel in there !
- */
- vmlinux_memsize += ONE_MB;
- printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux_memsize);
- vmlinux.addr = try_claim(vmlinux_memsize);
+ vmlinuz.addr = (unsigned long)_vmlinux_start;
+ vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start);
+
+ /* gunzip the ELF header of the kernel */
+ if (*(unsigned short *)vmlinuz.addr == 0x1f8b) {
+ len = vmlinuz.size;
+ gunzip(elfheader, sizeof(elfheader),
+ (unsigned char *)vmlinuz.addr, &len);
+ } else
+ memcpy(elfheader, (const void *)vmlinuz.addr, sizeof(elfheader));
+
+ elf64 = (Elf64_Ehdr *)elfheader;
+ if ( elf64->e_ident[EI_MAG0] != ELFMAG0 ||
+ elf64->e_ident[EI_MAG1] != ELFMAG1 ||
+ elf64->e_ident[EI_MAG2] != ELFMAG2 ||
+ elf64->e_ident[EI_MAG3] != ELFMAG3 ||
+ elf64->e_ident[EI_CLASS] != ELFCLASS64 ||
+ elf64->e_ident[EI_DATA] != ELFDATA2MSB ||
+ elf64->e_type != ET_EXEC ||
+ elf64->e_machine != EM_PPC64 )
+ {
+ printf("Error: not a valid PPC64 ELF file!\n\r");
+ exit();
+ }
+
+ elf64ph = (Elf64_Phdr *)((unsigned long)elf64 +
+ (unsigned long)elf64->e_phoff);
+ for(i=0; i < (unsigned int)elf64->e_phnum ;i++,elf64ph++) {
+ if (elf64ph->p_type == PT_LOAD && elf64ph->p_offset != 0)
+ break;
+ }
+ vmlinux.size = (unsigned long)elf64ph->p_filesz;
+ vmlinux.memsize = (unsigned long)elf64ph->p_memsz;
+ printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux.memsize);
+ vmlinux.addr = try_claim(vmlinux.memsize);
if (vmlinux.addr == 0) {
printf("Can't allocate memory for kernel image !\n\r");
exit();
}
- vmlinuz.addr = (unsigned long)_vmlinux_start;
- vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start);
- vmlinux.size = PAGE_ALIGN(vmlinux_filesize);
- vmlinux.memsize = vmlinux_memsize;
/*
* Now we try to claim memory for the initrd (and copy it there)
@@ -160,49 +234,22 @@ void start(unsigned long a1, unsigned long a2, void *promptr)
/* Eventually gunzip the kernel */
if (*(unsigned short *)vmlinuz.addr == 0x1f8b) {
- int len;
- avail_ram = scratch;
- begin_avail = avail_high = avail_ram;
- end_avail = scratch + sizeof(scratch);
printf("gunzipping (0x%lx <- 0x%lx:0x%0lx)...",
vmlinux.addr, vmlinuz.addr, vmlinuz.addr+vmlinuz.size);
len = vmlinuz.size;
- gunzip((void *)vmlinux.addr, vmlinux.size,
+ gunzip((void *)vmlinux.addr, vmlinux.memsize,
(unsigned char *)vmlinuz.addr, &len);
printf("done 0x%lx bytes\n\r", len);
- printf("0x%x bytes of heap consumed, max in use 0x%x\n\r",
- (unsigned)(avail_high - begin_avail), heap_max);
} else {
memmove((void *)vmlinux.addr,(void *)vmlinuz.addr,vmlinuz.size);
}
/* Skip over the ELF header */
- elf64 = (Elf64_Ehdr *)vmlinux.addr;
- if ( elf64->e_ident[EI_MAG0] != ELFMAG0 ||
- elf64->e_ident[EI_MAG1] != ELFMAG1 ||
- elf64->e_ident[EI_MAG2] != ELFMAG2 ||
- elf64->e_ident[EI_MAG3] != ELFMAG3 ||
- elf64->e_ident[EI_CLASS] != ELFCLASS64 ||
- elf64->e_ident[EI_DATA] != ELFDATA2MSB ||
- elf64->e_type != ET_EXEC ||
- elf64->e_machine != EM_PPC64 )
- {
- printf("Error: not a valid PPC64 ELF file!\n\r");
- exit();
- }
-
- elf64ph = (Elf64_Phdr *)((unsigned long)elf64 +
- (unsigned long)elf64->e_phoff);
- for(i=0; i < (unsigned int)elf64->e_phnum ;i++,elf64ph++) {
- if (elf64ph->p_type == PT_LOAD && elf64ph->p_offset != 0)
- break;
- }
#ifdef DEBUG
printf("... skipping 0x%lx bytes of ELF header\n\r",
(unsigned long)elf64ph->p_offset);
#endif
vmlinux.addr += (unsigned long)elf64ph->p_offset;
- vmlinux.size -= (unsigned long)elf64ph->p_offset;
flush_cache((void *)vmlinux.addr, vmlinux.size);
@@ -225,108 +272,3 @@ void start(unsigned long a1, unsigned long a2, void *promptr)
exit();
}
-struct memchunk {
- unsigned int size;
- unsigned int pad;
- struct memchunk *next;
-};
-
-static struct memchunk *freechunks;
-
-void *zalloc(void *x, unsigned items, unsigned size)
-{
- void *p;
- struct memchunk **mpp, *mp;
-
- size *= items;
- size = _ALIGN(size, sizeof(struct memchunk));
- heap_use += size;
- if (heap_use > heap_max)
- heap_max = heap_use;
- for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) {
- if (mp->size == size) {
- *mpp = mp->next;
- return mp;
- }
- }
- p = avail_ram;
- avail_ram += size;
- if (avail_ram > avail_high)
- avail_high = avail_ram;
- if (avail_ram > end_avail) {
- printf("oops... out of memory\n\r");
- pause();
- }
- return p;
-}
-
-void zfree(void *x, void *addr, unsigned nb)
-{
- struct memchunk *mp = addr;
-
- nb = _ALIGN(nb, sizeof(struct memchunk));
- heap_use -= nb;
- if (avail_ram == addr + nb) {
- avail_ram = addr;
- return;
- }
- mp->size = nb;
- mp->next = freechunks;
- freechunks = mp;
-}
-
-#define HEAD_CRC 2
-#define EXTRA_FIELD 4
-#define ORIG_NAME 8
-#define COMMENT 0x10
-#define RESERVED 0xe0
-
-#define DEFLATED 8
-
-static void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
-{
- z_stream s;
- int r, i, flags;
-
- /* skip header */
- i = 10;
- flags = src[3];
- if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
- printf("bad gzipped data\n\r");
- exit();
- }
- if ((flags & EXTRA_FIELD) != 0)
- i = 12 + src[10] + (src[11] << 8);
- if ((flags & ORIG_NAME) != 0)
- while (src[i++] != 0)
- ;
- if ((flags & COMMENT) != 0)
- while (src[i++] != 0)
- ;
- if ((flags & HEAD_CRC) != 0)
- i += 2;
- if (i >= *lenp) {
- printf("gunzip: ran out of data in header\n\r");
- exit();
- }
-
- s.zalloc = zalloc;
- s.zfree = zfree;
- r = inflateInit2(&s, -MAX_WBITS);
- if (r != Z_OK) {
- printf("inflateInit2 returned %d\n\r", r);
- exit();
- }
- s.next_in = src + i;
- s.avail_in = *lenp - i;
- s.next_out = dst;
- s.avail_out = dstlen;
- r = inflate(&s, Z_FINISH);
- if (r != Z_OK && r != Z_STREAM_END) {
- printf("inflate returned %d msg: %s\n\r", r, s.msg);
- exit();
- }
- *lenp = s.next_out - (unsigned char *) dst;
- inflateEnd(&s);
-}
-
diff --git a/arch/ppc64/boot/string.S b/arch/ppc64/boot/string.S
index 7ade87ae7718..b1eeaed7db17 100644
--- a/arch/ppc64/boot/string.S
+++ b/arch/ppc64/boot/string.S
@@ -104,7 +104,7 @@ memmove:
.globl memcpy
memcpy:
- rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */
+ rlwinm. r7,r5,32-3,3,31 /* r7 = r5 >> 3 */
addi r6,r3,-4
addi r4,r4,-4
beq 2f /* if less than 8 bytes to do */
@@ -146,7 +146,7 @@ memcpy:
.globl backwards_memcpy
backwards_memcpy:
- rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */
+ rlwinm. r7,r5,32-3,3,31 /* r7 = r5 >> 3 */
add r6,r3,r5
add r4,r4,r5
beq 2f
diff --git a/arch/ppc64/boot/string.h b/arch/ppc64/boot/string.h
index 9289258bcbd6..9fdff1cc0d70 100644
--- a/arch/ppc64/boot/string.h
+++ b/arch/ppc64/boot/string.h
@@ -1,5 +1,6 @@
#ifndef _PPC_BOOT_STRING_H_
#define _PPC_BOOT_STRING_H_
+#include <stddef.h>
extern char *strcpy(char *dest, const char *src);
extern char *strncpy(char *dest, const char *src, size_t n);
diff --git a/arch/ppc64/boot/zImage.lds b/arch/ppc64/boot/zImage.lds
index 8fe5e7071f54..4b6bb3ffe3dc 100644
--- a/arch/ppc64/boot/zImage.lds
+++ b/arch/ppc64/boot/zImage.lds
@@ -1,62 +1,24 @@
OUTPUT_ARCH(powerpc:common)
-SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
-/* Do we need any of these for elf?
- __DYNAMIC = 0; */
+ENTRY(_zimage_start)
SECTIONS
{
- /* Read-only sections, merged into text segment: */
- . = + SIZEOF_HEADERS;
- .interp : { *(.interp) }
- .hash : { *(.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .rel.text : { *(.rel.text) }
- .rela.text : { *(.rela.text) }
- .rel.data : { *(.rel.data) }
- .rela.data : { *(.rela.data) }
- .rel.rodata : { *(.rel.rodata) }
- .rela.rodata : { *(.rela.rodata) }
- .rel.got : { *(.rel.got) }
- .rela.got : { *(.rela.got) }
- .rel.ctors : { *(.rel.ctors) }
- .rela.ctors : { *(.rela.ctors) }
- .rel.dtors : { *(.rel.dtors) }
- .rela.dtors : { *(.rela.dtors) }
- .rel.bss : { *(.rel.bss) }
- .rela.bss : { *(.rela.bss) }
- .rel.plt : { *(.rel.plt) }
- .rela.plt : { *(.rela.plt) }
- .plt : { *(.plt) }
+ . = (4*1024*1024);
+ _start = .;
.text :
{
*(.text)
*(.fixup)
- *(.got1)
}
- . = ALIGN(4096);
_etext = .;
- PROVIDE (etext = .);
- .rodata :
- {
- *(.rodata)
- *(.rodata1)
- }
- .kstrtab : { *(.kstrtab) }
- __vermagic : { *(__vermagic) }
- .fini : { *(.fini) } =0
- .ctors : { *(.ctors) }
- .dtors : { *(.dtors) }
- /* Read-write section, merged into data segment: */
. = ALIGN(4096);
.data :
{
- *(.data)
- *(.data1)
- *(.sdata)
- *(.sdata2)
- *(.got.plt) *(.got)
- *(.dynamic)
- CONSTRUCTORS
+ *(.rodata*)
+ *(.data*)
+ *(.sdata*)
+ __got2_start = .;
+ *(.got2)
+ __got2_end = .;
}
. = ALIGN(4096);
@@ -71,20 +33,14 @@ SECTIONS
. = ALIGN(4096);
_edata = .;
- PROVIDE (edata = .);
-
- .fixup : { *(.fixup) }
. = ALIGN(4096);
__bss_start = .;
.bss :
{
- *(.sbss) *(.scommon)
- *(.dynbss)
+ *(.sbss)
*(.bss)
- *(COMMON)
}
. = ALIGN(4096);
_end = . ;
- PROVIDE (end = .);
}
diff --git a/arch/ppc64/boot/zlib.c b/arch/ppc64/boot/zlib.c
deleted file mode 100644
index 0d910cd2079d..000000000000
--- a/arch/ppc64/boot/zlib.c
+++ /dev/null
@@ -1,2195 +0,0 @@
-/*
- * This file is derived from various .h and .c files from the zlib-0.95
- * distribution by Jean-loup Gailly and Mark Adler, with some additions
- * by Paul Mackerras to aid in implementing Deflate compression and
- * decompression for PPP packets. See zlib.h for conditions of
- * distribution and use.
- *
- * Changes that have been made include:
- * - changed functions not used outside this file to "local"
- * - added minCompression parameter to deflateInit2
- * - added Z_PACKET_FLUSH (see zlib.h for details)
- * - added inflateIncomp
- *
- Copyright (C) 1995 Jean-loup Gailly and Mark Adler
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Jean-loup Gailly Mark Adler
- gzip@prep.ai.mit.edu madler@alumni.caltech.edu
-
- *
- *
- */
-
-/*+++++*/
-/* zutil.h -- internal interface and configuration of the compression library
- * Copyright (C) 1995 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* From: zutil.h,v 1.9 1995/05/03 17:27:12 jloup Exp */
-
-#define _Z_UTIL_H
-
-#include "zlib.h"
-
-#ifndef local
-# define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-#define FAR
-
-typedef unsigned char uch;
-typedef uch FAR uchf;
-typedef unsigned short ush;
-typedef ush FAR ushf;
-typedef unsigned long ulg;
-
-extern char *z_errmsg[]; /* indexed by 1-zlib_error */
-
-#define ERR_RETURN(strm,err) return (strm->msg=z_errmsg[1-err], err)
-/* To be used only when the state is known to be valid */
-
-#ifndef NULL
-#define NULL ((void *) 0)
-#endif
-
- /* common constants */
-
-#define DEFLATED 8
-
-#ifndef DEF_WBITS
-# define DEF_WBITS MAX_WBITS
-#endif
-/* default windowBits for decompression. MAX_WBITS is for compression only */
-
-#if MAX_MEM_LEVEL >= 8
-# define DEF_MEM_LEVEL 8
-#else
-# define DEF_MEM_LEVEL MAX_MEM_LEVEL
-#endif
-/* default memLevel */
-
-#define STORED_BLOCK 0
-#define STATIC_TREES 1
-#define DYN_TREES 2
-/* The three kinds of block type */
-
-#define MIN_MATCH 3
-#define MAX_MATCH 258
-/* The minimum and maximum match lengths */
-
- /* functions */
-
-extern void *memcpy(void *, const void *, unsigned long);
-#define zmemcpy memcpy
-
-/* Diagnostic functions */
-#ifdef DEBUG_ZLIB
-# include "stdio.h"
-# ifndef verbose
-# define verbose 0
-# endif
-# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
-# define Trace(x) fprintf x
-# define Tracev(x) {if (verbose) fprintf x ;}
-# define Tracevv(x) {if (verbose>1) fprintf x ;}
-# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
-# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
-#else
-# define Assert(cond,msg)
-# define Trace(x)
-# define Tracev(x)
-# define Tracevv(x)
-# define Tracec(c,x)
-# define Tracecv(c,x)
-#endif
-
-
-typedef uLong (*check_func) OF((uLong check, Bytef *buf, uInt len));
-
-/* voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); */
-/* void zcfree OF((voidpf opaque, voidpf ptr)); */
-
-#define ZALLOC(strm, items, size) \
- (*((strm)->zalloc))((strm)->opaque, (items), (size))
-#define ZFREE(strm, addr, size) \
- (*((strm)->zfree))((strm)->opaque, (voidpf)(addr), (size))
-#define TRY_FREE(s, p, n) {if (p) ZFREE(s, p, n);}
-
-/* deflate.h -- internal compression state
- * Copyright (C) 1995 Jean-loup Gailly
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/*+++++*/
-/* infblock.h -- header to use infblock.c
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-struct inflate_blocks_state;
-typedef struct inflate_blocks_state FAR inflate_blocks_statef;
-
-local inflate_blocks_statef * inflate_blocks_new OF((
- z_stream *z,
- check_func c, /* check function */
- uInt w)); /* window size */
-
-local int inflate_blocks OF((
- inflate_blocks_statef *,
- z_stream *,
- int)); /* initial return code */
-
-local void inflate_blocks_reset OF((
- inflate_blocks_statef *,
- z_stream *,
- uLongf *)); /* check value on output */
-
-local int inflate_blocks_free OF((
- inflate_blocks_statef *,
- z_stream *,
- uLongf *)); /* check value on output */
-
-local int inflate_addhistory OF((
- inflate_blocks_statef *,
- z_stream *));
-
-local int inflate_packet_flush OF((
- inflate_blocks_statef *));
-
-/*+++++*/
-/* inftrees.h -- header to use inftrees.c
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* Huffman code lookup table entry--this entry is four bytes for machines
- that have 16-bit pointers (e.g. PC's in the small or medium model). */
-
-typedef struct inflate_huft_s FAR inflate_huft;
-
-struct inflate_huft_s {
- union {
- struct {
- Byte Exop; /* number of extra bits or operation */
- Byte Bits; /* number of bits in this code or subcode */
- } what;
- uInt Nalloc; /* number of these allocated here */
- Bytef *pad; /* pad structure to a power of 2 (4 bytes for */
- } word; /* 16-bit, 8 bytes for 32-bit machines) */
- union {
- uInt Base; /* literal, length base, or distance base */
- inflate_huft *Next; /* pointer to next level of table */
- } more;
-};
-
-#ifdef DEBUG_ZLIB
- local uInt inflate_hufts;
-#endif
-
-local int inflate_trees_bits OF((
- uIntf *, /* 19 code lengths */
- uIntf *, /* bits tree desired/actual depth */
- inflate_huft * FAR *, /* bits tree result */
- z_stream *)); /* for zalloc, zfree functions */
-
-local int inflate_trees_dynamic OF((
- uInt, /* number of literal/length codes */
- uInt, /* number of distance codes */
- uIntf *, /* that many (total) code lengths */
- uIntf *, /* literal desired/actual bit depth */
- uIntf *, /* distance desired/actual bit depth */
- inflate_huft * FAR *, /* literal/length tree result */
- inflate_huft * FAR *, /* distance tree result */
- z_stream *)); /* for zalloc, zfree functions */
-
-local int inflate_trees_fixed OF((
- uIntf *, /* literal desired/actual bit depth */
- uIntf *, /* distance desired/actual bit depth */
- inflate_huft * FAR *, /* literal/length tree result */
- inflate_huft * FAR *)); /* distance tree result */
-
-local int inflate_trees_free OF((
- inflate_huft *, /* tables to free */
- z_stream *)); /* for zfree function */
-
-
-/*+++++*/
-/* infcodes.h -- header to use infcodes.c
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-struct inflate_codes_state;
-typedef struct inflate_codes_state FAR inflate_codes_statef;
-
-local inflate_codes_statef *inflate_codes_new OF((
- uInt, uInt,
- inflate_huft *, inflate_huft *,
- z_stream *));
-
-local int inflate_codes OF((
- inflate_blocks_statef *,
- z_stream *,
- int));
-
-local void inflate_codes_free OF((
- inflate_codes_statef *,
- z_stream *));
-
-
-/*+++++*/
-/* inflate.c -- zlib interface to inflate modules
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* inflate private state */
-struct internal_state {
-
- /* mode */
- enum {
- METHOD, /* waiting for method byte */
- FLAG, /* waiting for flag byte */
- BLOCKS, /* decompressing blocks */
- CHECK4, /* four check bytes to go */
- CHECK3, /* three check bytes to go */
- CHECK2, /* two check bytes to go */
- CHECK1, /* one check byte to go */
- DONE, /* finished check, done */
- BAD} /* got an error--stay here */
- mode; /* current inflate mode */
-
- /* mode dependent information */
- union {
- uInt method; /* if FLAGS, method byte */
- struct {
- uLong was; /* computed check value */
- uLong need; /* stream check value */
- } check; /* if CHECK, check values to compare */
- uInt marker; /* if BAD, inflateSync's marker bytes count */
- } sub; /* submode */
-
- /* mode independent information */
- int nowrap; /* flag for no wrapper */
- uInt wbits; /* log2(window size) (8..15, defaults to 15) */
- inflate_blocks_statef
- *blocks; /* current inflate_blocks state */
-
-};
-
-
-int inflateReset(
- z_stream *z
-)
-{
- uLong c;
-
- if (z == Z_NULL || z->state == Z_NULL)
- return Z_STREAM_ERROR;
- z->total_in = z->total_out = 0;
- z->msg = Z_NULL;
- z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
- inflate_blocks_reset(z->state->blocks, z, &c);
- Trace((stderr, "inflate: reset\n"));
- return Z_OK;
-}
-
-
-int inflateEnd(
- z_stream *z
-)
-{
- uLong c;
-
- if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
- return Z_STREAM_ERROR;
- if (z->state->blocks != Z_NULL)
- inflate_blocks_free(z->state->blocks, z, &c);
- ZFREE(z, z->state, sizeof(struct internal_state));
- z->state = Z_NULL;
- Trace((stderr, "inflate: end\n"));
- return Z_OK;
-}
-
-
-int inflateInit2(
- z_stream *z,
- int w
-)
-{
- /* initialize state */
- if (z == Z_NULL)
- return Z_STREAM_ERROR;
-/* if (z->zalloc == Z_NULL) z->zalloc = zcalloc; */
-/* if (z->zfree == Z_NULL) z->zfree = zcfree; */
- if ((z->state = (struct internal_state FAR *)
- ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
- return Z_MEM_ERROR;
- z->state->blocks = Z_NULL;
-
- /* handle undocumented nowrap option (no zlib header or check) */
- z->state->nowrap = 0;
- if (w < 0)
- {
- w = - w;
- z->state->nowrap = 1;
- }
-
- /* set window size */
- if (w < 8 || w > 15)
- {
- inflateEnd(z);
- return Z_STREAM_ERROR;
- }
- z->state->wbits = (uInt)w;
-
- /* create inflate_blocks state */
- if ((z->state->blocks =
- inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w))
- == Z_NULL)
- {
- inflateEnd(z);
- return Z_MEM_ERROR;
- }
- Trace((stderr, "inflate: allocated\n"));
-
- /* reset state */
- inflateReset(z);
- return Z_OK;
-}
-
-
-int inflateInit(
- z_stream *z
-)
-{
- return inflateInit2(z, DEF_WBITS);
-}
-
-
-#define NEEDBYTE {if(z->avail_in==0)goto empty;r=Z_OK;}
-#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
-
-int inflate(
- z_stream *z,
- int f
-)
-{
- int r;
- uInt b;
-
- if (z == Z_NULL || z->next_in == Z_NULL)
- return Z_STREAM_ERROR;
- r = Z_BUF_ERROR;
- while (1) switch (z->state->mode)
- {
- case METHOD:
- NEEDBYTE
- if (((z->state->sub.method = NEXTBYTE) & 0xf) != DEFLATED)
- {
- z->state->mode = BAD;
- z->msg = "unknown compression method";
- z->state->sub.marker = 5; /* can't try inflateSync */
- break;
- }
- if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
- {
- z->state->mode = BAD;
- z->msg = "invalid window size";
- z->state->sub.marker = 5; /* can't try inflateSync */
- break;
- }
- z->state->mode = FLAG;
- case FLAG:
- NEEDBYTE
- if ((b = NEXTBYTE) & 0x20)
- {
- z->state->mode = BAD;
- z->msg = "invalid reserved bit";
- z->state->sub.marker = 5; /* can't try inflateSync */
- break;
- }
- if (((z->state->sub.method << 8) + b) % 31)
- {
- z->state->mode = BAD;
- z->msg = "incorrect header check";
- z->state->sub.marker = 5; /* can't try inflateSync */
- break;
- }
- Trace((stderr, "inflate: zlib header ok\n"));
- z->state->mode = BLOCKS;
- case BLOCKS:
- r = inflate_blocks(z->state->blocks, z, r);
- if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0)
- r = inflate_packet_flush(z->state->blocks);
- if (r == Z_DATA_ERROR)
- {
- z->state->mode = BAD;
- z->state->sub.marker = 0; /* can try inflateSync */
- break;
- }
- if (r != Z_STREAM_END)
- return r;
- r = Z_OK;
- inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
- if (z->state->nowrap)
- {
- z->state->mode = DONE;
- break;
- }
- z->state->mode = CHECK4;
- case CHECK4:
- NEEDBYTE
- z->state->sub.check.need = (uLong)NEXTBYTE << 24;
- z->state->mode = CHECK3;
- case CHECK3:
- NEEDBYTE
- z->state->sub.check.need += (uLong)NEXTBYTE << 16;
- z->state->mode = CHECK2;
- case CHECK2:
- NEEDBYTE
- z->state->sub.check.need += (uLong)NEXTBYTE << 8;
- z->state->mode = CHECK1;
- case CHECK1:
- NEEDBYTE
- z->state->sub.check.need += (uLong)NEXTBYTE;
-
- if (z->state->sub.check.was != z->state->sub.check.need)
- {
- z->state->mode = BAD;
- z->msg = "incorrect data check";
- z->state->sub.marker = 5; /* can't try inflateSync */
- break;
- }
- Trace((stderr, "inflate: zlib check ok\n"));
- z->state->mode = DONE;
- case DONE:
- return Z_STREAM_END;
- case BAD:
- return Z_DATA_ERROR;
- default:
- return Z_STREAM_ERROR;
- }
-
- empty:
- if (f != Z_PACKET_FLUSH)
- return r;
- z->state->mode = BAD;
- z->state->sub.marker = 0; /* can try inflateSync */
- return Z_DATA_ERROR;
-}
-
-/*
- * This subroutine adds the data at next_in/avail_in to the output history
- * without performing any output. The output buffer must be "caught up";
- * i.e. no pending output (hence s->read equals s->write), and the state must
- * be BLOCKS (i.e. we should be willing to see the start of a series of
- * BLOCKS). On exit, the output will also be caught up, and the checksum
- * will have been updated if need be.
- */
-
-int inflateIncomp(
- z_stream *z
-)
-{
- if (z->state->mode != BLOCKS)
- return Z_DATA_ERROR;
- return inflate_addhistory(z->state->blocks, z);
-}
-
-
-int inflateSync(
- z_stream *z
-)
-{
- uInt n; /* number of bytes to look at */
- Bytef *p; /* pointer to bytes */
- uInt m; /* number of marker bytes found in a row */
- uLong r, w; /* temporaries to save total_in and total_out */
-
- /* set up */
- if (z == Z_NULL || z->state == Z_NULL)
- return Z_STREAM_ERROR;
- if (z->state->mode != BAD)
- {
- z->state->mode = BAD;
- z->state->sub.marker = 0;
- }
- if ((n = z->avail_in) == 0)
- return Z_BUF_ERROR;
- p = z->next_in;
- m = z->state->sub.marker;
-
- /* search */
- while (n && m < 4)
- {
- if (*p == (Byte)(m < 2 ? 0 : 0xff))
- m++;
- else if (*p)
- m = 0;
- else
- m = 4 - m;
- p++, n--;
- }
-
- /* restore */
- z->total_in += p - z->next_in;
- z->next_in = p;
- z->avail_in = n;
- z->state->sub.marker = m;
-
- /* return no joy or set up to restart on a new block */
- if (m != 4)
- return Z_DATA_ERROR;
- r = z->total_in; w = z->total_out;
- inflateReset(z);
- z->total_in = r; z->total_out = w;
- z->state->mode = BLOCKS;
- return Z_OK;
-}
-
-#undef NEEDBYTE
-#undef NEXTBYTE
-
-/*+++++*/
-/* infutil.h -- types and macros common to blocks and codes
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* inflate blocks semi-private state */
-struct inflate_blocks_state {
-
- /* mode */
- enum {
- TYPE, /* get type bits (3, including end bit) */
- LENS, /* get lengths for stored */
- STORED, /* processing stored block */
- TABLE, /* get table lengths */
- BTREE, /* get bit lengths tree for a dynamic block */
- DTREE, /* get length, distance trees for a dynamic block */
- CODES, /* processing fixed or dynamic block */
- DRY, /* output remaining window bytes */
- DONEB, /* finished last block, done */
- BADB} /* got a data error--stuck here */
- mode; /* current inflate_block mode */
-
- /* mode dependent information */
- union {
- uInt left; /* if STORED, bytes left to copy */
- struct {
- uInt table; /* table lengths (14 bits) */
- uInt index; /* index into blens (or border) */
- uIntf *blens; /* bit lengths of codes */
- uInt bb; /* bit length tree depth */
- inflate_huft *tb; /* bit length decoding tree */
- int nblens; /* # elements allocated at blens */
- } trees; /* if DTREE, decoding info for trees */
- struct {
- inflate_huft *tl, *td; /* trees to free */
- inflate_codes_statef
- *codes;
- } decode; /* if CODES, current state */
- } sub; /* submode */
- uInt last; /* true if this block is the last block */
-
- /* mode independent information */
- uInt bitk; /* bits in bit buffer */
- uLong bitb; /* bit buffer */
- Bytef *window; /* sliding window */
- Bytef *end; /* one byte after sliding window */
- Bytef *read; /* window read pointer */
- Bytef *write; /* window write pointer */
- check_func checkfn; /* check function */
- uLong check; /* check on output */
-
-};
-
-
-/* defines for inflate input/output */
-/* update pointers and return */
-#define UPDBITS {s->bitb=b;s->bitk=k;}
-#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
-#define UPDOUT {s->write=q;}
-#define UPDATE {UPDBITS UPDIN UPDOUT}
-#define LEAVE {UPDATE return inflate_flush(s,z,r);}
-/* get bytes and bits */
-#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
-#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
-#define NEXTBYTE (n--,*p++)
-#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
-#define DUMPBITS(j) {b>>=(j);k-=(j);}
-/* output bytes */
-#define WAVAIL (q<s->read?s->read-q-1:s->end-q)
-#define LOADOUT {q=s->write;m=WAVAIL;}
-#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=WAVAIL;}}
-#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
-#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
-#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
-/* load local pointers */
-#define LOAD {LOADIN LOADOUT}
-
-/* And'ing with mask[n] masks the lower n bits */
-local uInt inflate_mask[] = {
- 0x0000,
- 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
- 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
-};
-
-/* copy as much as possible from the sliding window to the output area */
-local int inflate_flush OF((
- inflate_blocks_statef *,
- z_stream *,
- int));
-
-/*+++++*/
-/* inffast.h -- header to use inffast.c
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-local int inflate_fast OF((
- uInt,
- uInt,
- inflate_huft *,
- inflate_huft *,
- inflate_blocks_statef *,
- z_stream *));
-
-
-/*+++++*/
-/* infblock.c -- interpret and process block types to last block
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* Table for deflate from PKZIP's appnote.txt. */
-local uInt border[] = { /* Order of the bit length code lengths */
- 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-
-/*
- Notes beyond the 1.93a appnote.txt:
-
- 1. Distance pointers never point before the beginning of the output
- stream.
- 2. Distance pointers can point back across blocks, up to 32k away.
- 3. There is an implied maximum of 7 bits for the bit length table and
- 15 bits for the actual data.
- 4. If only one code exists, then it is encoded using one bit. (Zero
- would be more efficient, but perhaps a little confusing.) If two
- codes exist, they are coded using one bit each (0 and 1).
- 5. There is no way of sending zero distance codes--a dummy must be
- sent if there are none. (History: a pre 2.0 version of PKZIP would
- store blocks with no distance codes, but this was discovered to be
- too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
- zero distance codes, which is sent as one code of zero bits in
- length.
- 6. There are up to 286 literal/length codes. Code 256 represents the
- end-of-block. Note however that the static length tree defines
- 288 codes just to fill out the Huffman codes. Codes 286 and 287
- cannot be used though, since there is no length base or extra bits
- defined for them. Similarily, there are up to 30 distance codes.
- However, static trees define 32 codes (all 5 bits) to fill out the
- Huffman codes, but the last two had better not show up in the data.
- 7. Unzip can check dynamic Huffman blocks for complete code sets.
- The exception is that a single code would not be complete (see #4).
- 8. The five bits following the block type is really the number of
- literal codes sent minus 257.
- 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
- (1+6+6). Therefore, to output three times the length, you output
- three codes (1+1+1), whereas to output four times the same length,
- you only need two codes (1+3). Hmm.
- 10. In the tree reconstruction algorithm, Code = Code + Increment
- only if BitLength(i) is not zero. (Pretty obvious.)
- 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
- 12. Note: length code 284 can represent 227-258, but length code 285
- really is 258. The last length deserves its own, short code
- since it gets used a lot in very redundant files. The length
- 258 is special since 258 - 3 (the min match length) is 255.
- 13. The literal/length and distance code bit lengths are read as a
- single stream of lengths. It is possible (and advantageous) for
- a repeat code (16, 17, or 18) to go across the boundary between
- the two sets of lengths.
- */
-
-
-local void inflate_blocks_reset(
- inflate_blocks_statef *s,
- z_stream *z,
- uLongf *c
-)
-{
- if (s->checkfn != Z_NULL)
- *c = s->check;
- if (s->mode == BTREE || s->mode == DTREE)
- ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt));
- if (s->mode == CODES)
- {
- inflate_codes_free(s->sub.decode.codes, z);
- inflate_trees_free(s->sub.decode.td, z);
- inflate_trees_free(s->sub.decode.tl, z);
- }
- s->mode = TYPE;
- s->bitk = 0;
- s->bitb = 0;
- s->read = s->write = s->window;
- if (s->checkfn != Z_NULL)
- s->check = (*s->checkfn)(0L, Z_NULL, 0);
- Trace((stderr, "inflate: blocks reset\n"));
-}
-
-
-local inflate_blocks_statef *inflate_blocks_new(
- z_stream *z,
- check_func c,
- uInt w
-)
-{
- inflate_blocks_statef *s;
-
- if ((s = (inflate_blocks_statef *)ZALLOC
- (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
- return s;
- if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
- {
- ZFREE(z, s, sizeof(struct inflate_blocks_state));
- return Z_NULL;
- }
- s->end = s->window + w;
- s->checkfn = c;
- s->mode = TYPE;
- Trace((stderr, "inflate: blocks allocated\n"));
- inflate_blocks_reset(s, z, &s->check);
- return s;
-}
-
-
-local int inflate_blocks(
- inflate_blocks_statef *s,
- z_stream *z,
- int r
-)
-{
- uInt t; /* temporary storage */
- uLong b; /* bit buffer */
- uInt k; /* bits in bit buffer */
- Bytef *p; /* input data pointer */
- uInt n; /* bytes available there */
- Bytef *q; /* output window write pointer */
- uInt m; /* bytes to end of window or read pointer */
-
- /* copy input/output information to locals (UPDATE macro restores) */
- LOAD
-
- /* process input based on current state */
- while (1) switch (s->mode)
- {
- case TYPE:
- NEEDBITS(3)
- t = (uInt)b & 7;
- s->last = t & 1;
- switch (t >> 1)
- {
- case 0: /* stored */
- Trace((stderr, "inflate: stored block%s\n",
- s->last ? " (last)" : ""));
- DUMPBITS(3)
- t = k & 7; /* go to byte boundary */
- DUMPBITS(t)
- s->mode = LENS; /* get length of stored block */
- break;
- case 1: /* fixed */
- Trace((stderr, "inflate: fixed codes block%s\n",
- s->last ? " (last)" : ""));
- {
- uInt bl, bd;
- inflate_huft *tl, *td;
-
- inflate_trees_fixed(&bl, &bd, &tl, &td);
- s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
- if (s->sub.decode.codes == Z_NULL)
- {
- r = Z_MEM_ERROR;
- LEAVE
- }
- s->sub.decode.tl = Z_NULL; /* don't try to free these */
- s->sub.decode.td = Z_NULL;
- }
- DUMPBITS(3)
- s->mode = CODES;
- break;
- case 2: /* dynamic */
- Trace((stderr, "inflate: dynamic codes block%s\n",
- s->last ? " (last)" : ""));
- DUMPBITS(3)
- s->mode = TABLE;
- break;
- case 3: /* illegal */
- DUMPBITS(3)
- s->mode = BADB;
- z->msg = "invalid block type";
- r = Z_DATA_ERROR;
- LEAVE
- }
- break;
- case LENS:
- NEEDBITS(32)
- if (((~b) >> 16) != (b & 0xffff))
- {
- s->mode = BADB;
- z->msg = "invalid stored block lengths";
- r = Z_DATA_ERROR;
- LEAVE
- }
- s->sub.left = (uInt)b & 0xffff;
- b = k = 0; /* dump bits */
- Tracev((stderr, "inflate: stored length %u\n", s->sub.left));
- s->mode = s->sub.left ? STORED : TYPE;
- break;
- case STORED:
- if (n == 0)
- LEAVE
- NEEDOUT
- t = s->sub.left;
- if (t > n) t = n;
- if (t > m) t = m;
- zmemcpy(q, p, t);
- p += t; n -= t;
- q += t; m -= t;
- if ((s->sub.left -= t) != 0)
- break;
- Tracev((stderr, "inflate: stored end, %lu total out\n",
- z->total_out + (q >= s->read ? q - s->read :
- (s->end - s->read) + (q - s->window))));
- s->mode = s->last ? DRY : TYPE;
- break;
- case TABLE:
- NEEDBITS(14)
- s->sub.trees.table = t = (uInt)b & 0x3fff;
-#ifndef PKZIP_BUG_WORKAROUND
- if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
- {
- s->mode = BADB;
- z->msg = "too many length or distance symbols";
- r = Z_DATA_ERROR;
- LEAVE
- }
-#endif
- t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
- if (t < 19)
- t = 19;
- if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
- {
- r = Z_MEM_ERROR;
- LEAVE
- }
- s->sub.trees.nblens = t;
- DUMPBITS(14)
- s->sub.trees.index = 0;
- Tracev((stderr, "inflate: table sizes ok\n"));
- s->mode = BTREE;
- case BTREE:
- while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
- {
- NEEDBITS(3)
- s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
- DUMPBITS(3)
- }
- while (s->sub.trees.index < 19)
- s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
- s->sub.trees.bb = 7;
- t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
- &s->sub.trees.tb, z);
- if (t != Z_OK)
- {
- r = t;
- if (r == Z_DATA_ERROR)
- s->mode = BADB;
- LEAVE
- }
- s->sub.trees.index = 0;
- Tracev((stderr, "inflate: bits tree ok\n"));
- s->mode = DTREE;
- case DTREE:
- while (t = s->sub.trees.table,
- s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
- {
- inflate_huft *h;
- uInt i, j, c;
-
- t = s->sub.trees.bb;
- NEEDBITS(t)
- h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
- t = h->word.what.Bits;
- c = h->more.Base;
- if (c < 16)
- {
- DUMPBITS(t)
- s->sub.trees.blens[s->sub.trees.index++] = c;
- }
- else /* c == 16..18 */
- {
- i = c == 18 ? 7 : c - 14;
- j = c == 18 ? 11 : 3;
- NEEDBITS(t + i)
- DUMPBITS(t)
- j += (uInt)b & inflate_mask[i];
- DUMPBITS(i)
- i = s->sub.trees.index;
- t = s->sub.trees.table;
- if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
- (c == 16 && i < 1))
- {
- s->mode = BADB;
- z->msg = "invalid bit length repeat";
- r = Z_DATA_ERROR;
- LEAVE
- }
- c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
- do {
- s->sub.trees.blens[i++] = c;
- } while (--j);
- s->sub.trees.index = i;
- }
- }
- inflate_trees_free(s->sub.trees.tb, z);
- s->sub.trees.tb = Z_NULL;
- {
- uInt bl, bd;
- inflate_huft *tl, *td;
- inflate_codes_statef *c;
-
- bl = 9; /* must be <= 9 for lookahead assumptions */
- bd = 6; /* must be <= 9 for lookahead assumptions */
- t = s->sub.trees.table;
- t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
- s->sub.trees.blens, &bl, &bd, &tl, &td, z);
- if (t != Z_OK)
- {
- if (t == (uInt)Z_DATA_ERROR)
- s->mode = BADB;
- r = t;
- LEAVE
- }
- Tracev((stderr, "inflate: trees ok\n"));
- if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
- {
- inflate_trees_free(td, z);
- inflate_trees_free(tl, z);
- r = Z_MEM_ERROR;
- LEAVE
- }
- ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt));
- s->sub.decode.codes = c;
- s->sub.decode.tl = tl;
- s->sub.decode.td = td;
- }
- s->mode = CODES;
- case CODES:
- UPDATE
- if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
- return inflate_flush(s, z, r);
- r = Z_OK;
- inflate_codes_free(s->sub.decode.codes, z);
- inflate_trees_free(s->sub.decode.td, z);
- inflate_trees_free(s->sub.decode.tl, z);
- LOAD
- Tracev((stderr, "inflate: codes end, %lu total out\n",
- z->total_out + (q >= s->read ? q - s->read :
- (s->end - s->read) + (q - s->window))));
- if (!s->last)
- {
- s->mode = TYPE;
- break;
- }
- if (k > 7) /* return unused byte, if any */
- {
- Assert(k < 16, "inflate_codes grabbed too many bytes")
- k -= 8;
- n++;
- p--; /* can always return one */
- }
- s->mode = DRY;
- case DRY:
- FLUSH
- if (s->read != s->write)
- LEAVE
- s->mode = DONEB;
- case DONEB:
- r = Z_STREAM_END;
- LEAVE
- case BADB:
- r = Z_DATA_ERROR;
- LEAVE
- default:
- r = Z_STREAM_ERROR;
- LEAVE
- }
-}
-
-
-local int inflate_blocks_free(
- inflate_blocks_statef *s,
- z_stream *z,
- uLongf *c
-)
-{
- inflate_blocks_reset(s, z, c);
- ZFREE(z, s->window, s->end - s->window);
- ZFREE(z, s, sizeof(struct inflate_blocks_state));
- Trace((stderr, "inflate: blocks freed\n"));
- return Z_OK;
-}
-
-/*
- * This subroutine adds the data at next_in/avail_in to the output history
- * without performing any output. The output buffer must be "caught up";
- * i.e. no pending output (hence s->read equals s->write), and the state must
- * be BLOCKS (i.e. we should be willing to see the start of a series of
- * BLOCKS). On exit, the output will also be caught up, and the checksum
- * will have been updated if need be.
- */
-local int inflate_addhistory(
- inflate_blocks_statef *s,
- z_stream *z
-)
-{
- uLong b; /* bit buffer */ /* NOT USED HERE */
- uInt k; /* bits in bit buffer */ /* NOT USED HERE */
- uInt t; /* temporary storage */
- Bytef *p; /* input data pointer */
- uInt n; /* bytes available there */
- Bytef *q; /* output window write pointer */
- uInt m; /* bytes to end of window or read pointer */
-
- if (s->read != s->write)
- return Z_STREAM_ERROR;
- if (s->mode != TYPE)
- return Z_DATA_ERROR;
-
- /* we're ready to rock */
- LOAD
- /* while there is input ready, copy to output buffer, moving
- * pointers as needed.
- */
- while (n) {
- t = n; /* how many to do */
- /* is there room until end of buffer? */
- if (t > m) t = m;
- /* update check information */
- if (s->checkfn != Z_NULL)
- s->check = (*s->checkfn)(s->check, q, t);
- zmemcpy(q, p, t);
- q += t;
- p += t;
- n -= t;
- z->total_out += t;
- s->read = q; /* drag read pointer forward */
-/* WRAP */ /* expand WRAP macro by hand to handle s->read */
- if (q == s->end) {
- s->read = q = s->window;
- m = WAVAIL;
- }
- }
- UPDATE
- return Z_OK;
-}
-
-
-/*
- * At the end of a Deflate-compressed PPP packet, we expect to have seen
- * a `stored' block type value but not the (zero) length bytes.
- */
-local int inflate_packet_flush(
- inflate_blocks_statef *s
-)
-{
- if (s->mode != LENS)
- return Z_DATA_ERROR;
- s->mode = TYPE;
- return Z_OK;
-}
-
-
-/*+++++*/
-/* inftrees.c -- generate Huffman trees for efficient decoding
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* simplify the use of the inflate_huft type with some defines */
-#define base more.Base
-#define next more.Next
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-
-local int huft_build OF((
- uIntf *, /* code lengths in bits */
- uInt, /* number of codes */
- uInt, /* number of "simple" codes */
- uIntf *, /* list of base values for non-simple codes */
- uIntf *, /* list of extra bits for non-simple codes */
- inflate_huft * FAR*,/* result: starting table */
- uIntf *, /* maximum lookup bits (returns actual) */
- z_stream *)); /* for zalloc function */
-
-local voidpf falloc OF((
- voidpf, /* opaque pointer (not used) */
- uInt, /* number of items */
- uInt)); /* size of item */
-
-local void ffree OF((
- voidpf q, /* opaque pointer (not used) */
- voidpf p, /* what to free (not used) */
- uInt n)); /* number of bytes (not used) */
-
-/* Tables for deflate from PKZIP's appnote.txt. */
-local uInt cplens[] = { /* Copy lengths for literal codes 257..285 */
- 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
- 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
- /* actually lengths - 2; also see note #13 above about 258 */
-local uInt cplext[] = { /* Extra bits for literal codes 257..285 */
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
- 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */
-local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */
- 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
- 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
- 8193, 12289, 16385, 24577};
-local uInt cpdext[] = { /* Extra bits for distance codes */
- 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
- 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
- 12, 12, 13, 13};
-
-/*
- Huffman code decoding is performed using a multi-level table lookup.
- The fastest way to decode is to simply build a lookup table whose
- size is determined by the longest code. However, the time it takes
- to build this table can also be a factor if the data being decoded
- is not very long. The most common codes are necessarily the
- shortest codes, so those codes dominate the decoding time, and hence
- the speed. The idea is you can have a shorter table that decodes the
- shorter, more probable codes, and then point to subsidiary tables for
- the longer codes. The time it costs to decode the longer codes is
- then traded against the time it takes to make longer tables.
-
- This results of this trade are in the variables lbits and dbits
- below. lbits is the number of bits the first level table for literal/
- length codes can decode in one step, and dbits is the same thing for
- the distance codes. Subsequent tables are also less than or equal to
- those sizes. These values may be adjusted either when all of the
- codes are shorter than that, in which case the longest code length in
- bits is used, or when the shortest code is *longer* than the requested
- table size, in which case the length of the shortest code in bits is
- used.
-
- There are two different values for the two tables, since they code a
- different number of possibilities each. The literal/length table
- codes 286 possible values, or in a flat code, a little over eight
- bits. The distance table codes 30 possible values, or a little less
- than five bits, flat. The optimum values for speed end up being
- about one bit more than those, so lbits is 8+1 and dbits is 5+1.
- The optimum values may differ though from machine to machine, and
- possibly even between compilers. Your mileage may vary.
- */
-
-
-/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
-#define BMAX 15 /* maximum bit length of any code */
-#define N_MAX 288 /* maximum number of codes in any set */
-
-#ifdef DEBUG_ZLIB
- uInt inflate_hufts;
-#endif
-
-local int huft_build(
- uIntf *b, /* code lengths in bits (all assumed <= BMAX) */
- uInt n, /* number of codes (assumed <= N_MAX) */
- uInt s, /* number of simple-valued codes (0..s-1) */
- uIntf *d, /* list of base values for non-simple codes */
- uIntf *e, /* list of extra bits for non-simple codes */
- inflate_huft * FAR *t, /* result: starting table */
- uIntf *m, /* maximum lookup bits, returns actual */
- z_stream *zs /* for zalloc function */
-)
-/* Given a list of code lengths and a maximum table size, make a set of
- tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
- if the given code set is incomplete (the tables are still built in this
- case), Z_DATA_ERROR if the input is invalid (all zero length codes or an
- over-subscribed set of lengths), or Z_MEM_ERROR if not enough memory. */
-{
-
- uInt a; /* counter for codes of length k */
- uInt c[BMAX+1]; /* bit length count table */
- uInt f; /* i repeats in table every f entries */
- int g; /* maximum code length */
- int h; /* table level */
- register uInt i; /* counter, current code */
- register uInt j; /* counter */
- register int k; /* number of bits in current code */
- int l; /* bits per table (returned in m) */
- register uIntf *p; /* pointer into c[], b[], or v[] */
- inflate_huft *q; /* points to current table */
- struct inflate_huft_s r; /* table entry for structure assignment */
- inflate_huft *u[BMAX]; /* table stack */
- uInt v[N_MAX]; /* values in order of bit length */
- register int w; /* bits before this table == (l * h) */
- uInt x[BMAX+1]; /* bit offsets, then code stack */
- uIntf *xp; /* pointer into x */
- int y; /* number of dummy codes added */
- uInt z; /* number of entries in current table */
-
-
- /* Generate counts for each bit length */
- p = c;
-#define C0 *p++ = 0;
-#define C2 C0 C0 C0 C0
-#define C4 C2 C2 C2 C2
- C4 /* clear c[]--assume BMAX+1 is 16 */
- p = b; i = n;
- do {
- c[*p++]++; /* assume all entries <= BMAX */
- } while (--i);
- if (c[0] == n) /* null input--all zero length codes */
- {
- *t = (inflate_huft *)Z_NULL;
- *m = 0;
- return Z_DATA_ERROR;
- }
-
-
- /* Find minimum and maximum length, bound *m by those */
- l = *m;
- for (j = 1; j <= BMAX; j++)
- if (c[j])
- break;
- k = j; /* minimum code length */
- if ((uInt)l < j)
- l = j;
- for (i = BMAX; i; i--)
- if (c[i])
- break;
- g = i; /* maximum code length */
- if ((uInt)l > i)
- l = i;
- *m = l;
-
-
- /* Adjust last length count to fill out codes, if needed */
- for (y = 1 << j; j < i; j++, y <<= 1)
- if ((y -= c[j]) < 0)
- return Z_DATA_ERROR;
- if ((y -= c[i]) < 0)
- return Z_DATA_ERROR;
- c[i] += y;
-
-
- /* Generate starting offsets into the value table for each length */
- x[1] = j = 0;
- p = c + 1; xp = x + 2;
- while (--i) { /* note that i == g from above */
- *xp++ = (j += *p++);
- }
-
-
- /* Make a table of values in order of bit lengths */
- p = b; i = 0;
- do {
- if ((j = *p++) != 0)
- v[x[j]++] = i;
- } while (++i < n);
- n = x[g]; /* set n to length of v */
-
-
- /* Generate the Huffman codes and for each, make the table entries */
- x[0] = i = 0; /* first Huffman code is zero */
- p = v; /* grab values in bit order */
- h = -1; /* no tables yet--level -1 */
- w = -l; /* bits decoded == (l * h) */
- u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */
- q = (inflate_huft *)Z_NULL; /* ditto */
- z = 0; /* ditto */
-
- /* go through the bit lengths (k already is bits in shortest code) */
- for (; k <= g; k++)
- {
- a = c[k];
- while (a--)
- {
- /* here i is the Huffman code of length k bits for value *p */
- /* make tables up to required level */
- while (k > w + l)
- {
- h++;
- w += l; /* previous table always l bits */
-
- /* compute minimum size table less than or equal to l bits */
- z = (z = g - w) > (uInt)l ? l : z; /* table size upper limit */
- if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
- { /* too few codes for k-w bit table */
- f -= a + 1; /* deduct codes from patterns left */
- xp = c + k;
- if (j < z)
- while (++j < z) /* try smaller tables up to z bits */
- {
- if ((f <<= 1) <= *++xp)
- break; /* enough codes to use up j bits */
- f -= *xp; /* else deduct codes from patterns */
- }
- }
- z = 1 << j; /* table entries for j-bit table */
-
- /* allocate and link in new table */
- if ((q = (inflate_huft *)ZALLOC
- (zs,z + 1,sizeof(inflate_huft))) == Z_NULL)
- {
- if (h)
- inflate_trees_free(u[0], zs);
- return Z_MEM_ERROR; /* not enough memory */
- }
- q->word.Nalloc = z + 1;
-#ifdef DEBUG_ZLIB
- inflate_hufts += z + 1;
-#endif
- *t = q + 1; /* link to list for huft_free() */
- *(t = &(q->next)) = Z_NULL;
- u[h] = ++q; /* table starts after link */
-
- /* connect to last table, if there is one */
- if (h)
- {
- x[h] = i; /* save pattern for backing up */
- r.bits = (Byte)l; /* bits to dump before this table */
- r.exop = (Byte)j; /* bits in this table */
- r.next = q; /* pointer to this table */
- j = i >> (w - l); /* (get around Turbo C bug) */
- u[h-1][j] = r; /* connect to last table */
- }
- }
-
- /* set up table entry in r */
- r.bits = (Byte)(k - w);
- if (p >= v + n)
- r.exop = 128 + 64; /* out of values--invalid code */
- else if (*p < s)
- {
- r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */
- r.base = *p++; /* simple code is just the value */
- }
- else
- {
- r.exop = (Byte)e[*p - s] + 16 + 64; /* non-simple--look up in lists */
- r.base = d[*p++ - s];
- }
-
- /* fill code-like entries with r */
- f = 1 << (k - w);
- for (j = i >> w; j < z; j += f)
- q[j] = r;
-
- /* backwards increment the k-bit code i */
- for (j = 1 << (k - 1); i & j; j >>= 1)
- i ^= j;
- i ^= j;
-
- /* backup over finished tables */
- while ((i & ((1 << w) - 1)) != x[h])
- {
- h--; /* don't need to update q */
- w -= l;
- }
- }
- }
-
-
- /* Return Z_BUF_ERROR if we were given an incomplete table */
- return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
-}
-
-
-local int inflate_trees_bits(
- uIntf *c, /* 19 code lengths */
- uIntf *bb, /* bits tree desired/actual depth */
- inflate_huft * FAR *tb, /* bits tree result */
- z_stream *z /* for zfree function */
-)
-{
- int r;
-
- r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z);
- if (r == Z_DATA_ERROR)
- z->msg = "oversubscribed dynamic bit lengths tree";
- else if (r == Z_BUF_ERROR)
- {
- inflate_trees_free(*tb, z);
- z->msg = "incomplete dynamic bit lengths tree";
- r = Z_DATA_ERROR;
- }
- return r;
-}
-
-
-local int inflate_trees_dynamic(
- uInt nl, /* number of literal/length codes */
- uInt nd, /* number of distance codes */
- uIntf *c, /* that many (total) code lengths */
- uIntf *bl, /* literal desired/actual bit depth */
- uIntf *bd, /* distance desired/actual bit depth */
- inflate_huft * FAR *tl, /* literal/length tree result */
- inflate_huft * FAR *td, /* distance tree result */
- z_stream *z /* for zfree function */
-)
-{
- int r;
-
- /* build literal/length tree */
- if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK)
- {
- if (r == Z_DATA_ERROR)
- z->msg = "oversubscribed literal/length tree";
- else if (r == Z_BUF_ERROR)
- {
- inflate_trees_free(*tl, z);
- z->msg = "incomplete literal/length tree";
- r = Z_DATA_ERROR;
- }
- return r;
- }
-
- /* build distance tree */
- if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK)
- {
- if (r == Z_DATA_ERROR)
- z->msg = "oversubscribed literal/length tree";
- else if (r == Z_BUF_ERROR) {
-#ifdef PKZIP_BUG_WORKAROUND
- r = Z_OK;
- }
-#else
- inflate_trees_free(*td, z);
- z->msg = "incomplete literal/length tree";
- r = Z_DATA_ERROR;
- }
- inflate_trees_free(*tl, z);
- return r;
-#endif
- }
-
- /* done */
- return Z_OK;
-}
-
-
-/* build fixed tables only once--keep them here */
-local int fixed_lock = 0;
-local int fixed_built = 0;
-#define FIXEDH 530 /* number of hufts used by fixed tables */
-local uInt fixed_left = FIXEDH;
-local inflate_huft fixed_mem[FIXEDH];
-local uInt fixed_bl;
-local uInt fixed_bd;
-local inflate_huft *fixed_tl;
-local inflate_huft *fixed_td;
-
-
-local voidpf falloc(
- voidpf q, /* opaque pointer (not used) */
- uInt n, /* number of items */
- uInt s /* size of item */
-)
-{
- Assert(s == sizeof(inflate_huft) && n <= fixed_left,
- "inflate_trees falloc overflow");
- if (q) s++; /* to make some compilers happy */
- fixed_left -= n;
- return (voidpf)(fixed_mem + fixed_left);
-}
-
-
-local void ffree(
- voidpf q,
- voidpf p,
- uInt n
-)
-{
- Assert(0, "inflate_trees ffree called!");
- if (q) q = p; /* to make some compilers happy */
-}
-
-
-local int inflate_trees_fixed(
- uIntf *bl, /* literal desired/actual bit depth */
- uIntf *bd, /* distance desired/actual bit depth */
- inflate_huft * FAR *tl, /* literal/length tree result */
- inflate_huft * FAR *td /* distance tree result */
-)
-{
- /* build fixed tables if not built already--lock out other instances */
- while (++fixed_lock > 1)
- fixed_lock--;
- if (!fixed_built)
- {
- int k; /* temporary variable */
- unsigned c[288]; /* length list for huft_build */
- z_stream z; /* for falloc function */
-
- /* set up fake z_stream for memory routines */
- z.zalloc = falloc;
- z.zfree = ffree;
- z.opaque = Z_NULL;
-
- /* literal table */
- for (k = 0; k < 144; k++)
- c[k] = 8;
- for (; k < 256; k++)
- c[k] = 9;
- for (; k < 280; k++)
- c[k] = 7;
- for (; k < 288; k++)
- c[k] = 8;
- fixed_bl = 7;
- huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z);
-
- /* distance table */
- for (k = 0; k < 30; k++)
- c[k] = 5;
- fixed_bd = 5;
- huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z);
-
- /* done */
- fixed_built = 1;
- }
- fixed_lock--;
- *bl = fixed_bl;
- *bd = fixed_bd;
- *tl = fixed_tl;
- *td = fixed_td;
- return Z_OK;
-}
-
-
-local int inflate_trees_free(
- inflate_huft *t, /* table to free */
- z_stream *z /* for zfree function */
-)
-/* Free the malloc'ed tables built by huft_build(), which makes a linked
- list of the tables it made, with the links in a dummy first entry of
- each table. */
-{
- register inflate_huft *p, *q;
-
- /* Go through linked list, freeing from the malloced (t[-1]) address. */
- p = t;
- while (p != Z_NULL)
- {
- q = (--p)->next;
- ZFREE(z, p, p->word.Nalloc * sizeof(inflate_huft));
- p = q;
- }
- return Z_OK;
-}
-
-/*+++++*/
-/* infcodes.c -- process literals and length/distance pairs
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* simplify the use of the inflate_huft type with some defines */
-#define base more.Base
-#define next more.Next
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-/* inflate codes private state */
-struct inflate_codes_state {
-
- /* mode */
- enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
- START, /* x: set up for LEN */
- LEN, /* i: get length/literal/eob next */
- LENEXT, /* i: getting length extra (have base) */
- DIST, /* i: get distance next */
- DISTEXT, /* i: getting distance extra */
- COPY, /* o: copying bytes in window, waiting for space */
- LIT, /* o: got literal, waiting for output space */
- WASH, /* o: got eob, possibly still output waiting */
- END, /* x: got eob and all data flushed */
- BADCODE} /* x: got error */
- mode; /* current inflate_codes mode */
-
- /* mode dependent information */
- uInt len;
- union {
- struct {
- inflate_huft *tree; /* pointer into tree */
- uInt need; /* bits needed */
- } code; /* if LEN or DIST, where in tree */
- uInt lit; /* if LIT, literal */
- struct {
- uInt get; /* bits to get for extra */
- uInt dist; /* distance back to copy from */
- } copy; /* if EXT or COPY, where and how much */
- } sub; /* submode */
-
- /* mode independent information */
- Byte lbits; /* ltree bits decoded per branch */
- Byte dbits; /* dtree bits decoder per branch */
- inflate_huft *ltree; /* literal/length/eob tree */
- inflate_huft *dtree; /* distance tree */
-
-};
-
-
-local inflate_codes_statef *inflate_codes_new(
- uInt bl,
- uInt bd,
- inflate_huft *tl,
- inflate_huft *td,
- z_stream *z
-)
-{
- inflate_codes_statef *c;
-
- if ((c = (inflate_codes_statef *)
- ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
- {
- c->mode = START;
- c->lbits = (Byte)bl;
- c->dbits = (Byte)bd;
- c->ltree = tl;
- c->dtree = td;
- Tracev((stderr, "inflate: codes new\n"));
- }
- return c;
-}
-
-
-local int inflate_codes(
- inflate_blocks_statef *s,
- z_stream *z,
- int r
-)
-{
- uInt j; /* temporary storage */
- inflate_huft *t; /* temporary pointer */
- uInt e; /* extra bits or operation */
- uLong b; /* bit buffer */
- uInt k; /* bits in bit buffer */
- Bytef *p; /* input data pointer */
- uInt n; /* bytes available there */
- Bytef *q; /* output window write pointer */
- uInt m; /* bytes to end of window or read pointer */
- Bytef *f; /* pointer to copy strings from */
- inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
-
- /* copy input/output information to locals (UPDATE macro restores) */
- LOAD
-
- /* process input and output based on current state */
- while (1) switch (c->mode)
- { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
- case START: /* x: set up for LEN */
-#ifndef SLOW
- if (m >= 258 && n >= 10)
- {
- UPDATE
- r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
- LOAD
- if (r != Z_OK)
- {
- c->mode = r == Z_STREAM_END ? WASH : BADCODE;
- break;
- }
- }
-#endif /* !SLOW */
- c->sub.code.need = c->lbits;
- c->sub.code.tree = c->ltree;
- c->mode = LEN;
- case LEN: /* i: get length/literal/eob next */
- j = c->sub.code.need;
- NEEDBITS(j)
- t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
- DUMPBITS(t->bits)
- e = (uInt)(t->exop);
- if (e == 0) /* literal */
- {
- c->sub.lit = t->base;
- Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
- "inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", t->base));
- c->mode = LIT;
- break;
- }
- if (e & 16) /* length */
- {
- c->sub.copy.get = e & 15;
- c->len = t->base;
- c->mode = LENEXT;
- break;
- }
- if ((e & 64) == 0) /* next table */
- {
- c->sub.code.need = e;
- c->sub.code.tree = t->next;
- break;
- }
- if (e & 32) /* end of block */
- {
- Tracevv((stderr, "inflate: end of block\n"));
- c->mode = WASH;
- break;
- }
- c->mode = BADCODE; /* invalid code */
- z->msg = "invalid literal/length code";
- r = Z_DATA_ERROR;
- LEAVE
- case LENEXT: /* i: getting length extra (have base) */
- j = c->sub.copy.get;
- NEEDBITS(j)
- c->len += (uInt)b & inflate_mask[j];
- DUMPBITS(j)
- c->sub.code.need = c->dbits;
- c->sub.code.tree = c->dtree;
- Tracevv((stderr, "inflate: length %u\n", c->len));
- c->mode = DIST;
- case DIST: /* i: get distance next */
- j = c->sub.code.need;
- NEEDBITS(j)
- t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
- DUMPBITS(t->bits)
- e = (uInt)(t->exop);
- if (e & 16) /* distance */
- {
- c->sub.copy.get = e & 15;
- c->sub.copy.dist = t->base;
- c->mode = DISTEXT;
- break;
- }
- if ((e & 64) == 0) /* next table */
- {
- c->sub.code.need = e;
- c->sub.code.tree = t->next;
- break;
- }
- c->mode = BADCODE; /* invalid code */
- z->msg = "invalid distance code";
- r = Z_DATA_ERROR;
- LEAVE
- case DISTEXT: /* i: getting distance extra */
- j = c->sub.copy.get;
- NEEDBITS(j)
- c->sub.copy.dist += (uInt)b & inflate_mask[j];
- DUMPBITS(j)
- Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
- c->mode = COPY;
- case COPY: /* o: copying bytes in window, waiting for space */
-#ifndef __TURBOC__ /* Turbo C bug for following expression */
- f = (uInt)(q - s->window) < c->sub.copy.dist ?
- s->end - (c->sub.copy.dist - (q - s->window)) :
- q - c->sub.copy.dist;
-#else
- f = q - c->sub.copy.dist;
- if ((uInt)(q - s->window) < c->sub.copy.dist)
- f = s->end - (c->sub.copy.dist - (q - s->window));
-#endif
- while (c->len)
- {
- NEEDOUT
- OUTBYTE(*f++)
- if (f == s->end)
- f = s->window;
- c->len--;
- }
- c->mode = START;
- break;
- case LIT: /* o: got literal, waiting for output space */
- NEEDOUT
- OUTBYTE(c->sub.lit)
- c->mode = START;
- break;
- case WASH: /* o: got eob, possibly more output */
- FLUSH
- if (s->read != s->write)
- LEAVE
- c->mode = END;
- case END:
- r = Z_STREAM_END;
- LEAVE
- case BADCODE: /* x: got error */
- r = Z_DATA_ERROR;
- LEAVE
- default:
- r = Z_STREAM_ERROR;
- LEAVE
- }
-}
-
-
-local void inflate_codes_free(
- inflate_codes_statef *c,
- z_stream *z
-)
-{
- ZFREE(z, c, sizeof(struct inflate_codes_state));
- Tracev((stderr, "inflate: codes free\n"));
-}
-
-/*+++++*/
-/* inflate_util.c -- data and routines common to blocks and codes
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* copy as much as possible from the sliding window to the output area */
-local int inflate_flush(
- inflate_blocks_statef *s,
- z_stream *z,
- int r
-)
-{
- uInt n;
- Bytef *p, *q;
-
- /* local copies of source and destination pointers */
- p = z->next_out;
- q = s->read;
-
- /* compute number of bytes to copy as far as end of window */
- n = (uInt)((q <= s->write ? s->write : s->end) - q);
- if (n > z->avail_out) n = z->avail_out;
- if (n && r == Z_BUF_ERROR) r = Z_OK;
-
- /* update counters */
- z->avail_out -= n;
- z->total_out += n;
-
- /* update check information */
- if (s->checkfn != Z_NULL)
- s->check = (*s->checkfn)(s->check, q, n);
-
- /* copy as far as end of window */
- zmemcpy(p, q, n);
- p += n;
- q += n;
-
- /* see if more to copy at beginning of window */
- if (q == s->end)
- {
- /* wrap pointers */
- q = s->window;
- if (s->write == s->end)
- s->write = s->window;
-
- /* compute bytes to copy */
- n = (uInt)(s->write - q);
- if (n > z->avail_out) n = z->avail_out;
- if (n && r == Z_BUF_ERROR) r = Z_OK;
-
- /* update counters */
- z->avail_out -= n;
- z->total_out += n;
-
- /* update check information */
- if (s->checkfn != Z_NULL)
- s->check = (*s->checkfn)(s->check, q, n);
-
- /* copy */
- zmemcpy(p, q, n);
- p += n;
- q += n;
- }
-
- /* update pointers */
- z->next_out = p;
- s->read = q;
-
- /* done */
- return r;
-}
-
-
-/*+++++*/
-/* inffast.c -- process literals and length/distance pairs fast
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* simplify the use of the inflate_huft type with some defines */
-#define base more.Base
-#define next more.Next
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-/* macros for bit input with no checking and for returning unused bytes */
-#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
-#define UNGRAB {n+=(c=k>>3);p-=c;k&=7;}
-
-/* Called with number of bytes left to write in window at least 258
- (the maximum string length) and number of input bytes available
- at least ten. The ten bytes are six bytes for the longest length/
- distance pair plus four bytes for overloading the bit buffer. */
-
-local int inflate_fast(
- uInt bl,
- uInt bd,
- inflate_huft *tl,
- inflate_huft *td,
- inflate_blocks_statef *s,
- z_stream *z
-)
-{
- inflate_huft *t; /* temporary pointer */
- uInt e; /* extra bits or operation */
- uLong b; /* bit buffer */
- uInt k; /* bits in bit buffer */
- Bytef *p; /* input data pointer */
- uInt n; /* bytes available there */
- Bytef *q; /* output window write pointer */
- uInt m; /* bytes to end of window or read pointer */
- uInt ml; /* mask for literal/length tree */
- uInt md; /* mask for distance tree */
- uInt c; /* bytes to copy */
- uInt d; /* distance back to copy from */
- Bytef *r; /* copy source pointer */
-
- /* load input, output, bit values */
- LOAD
-
- /* initialize masks */
- ml = inflate_mask[bl];
- md = inflate_mask[bd];
-
- /* do until not enough input or output space for fast loop */
- do { /* assume called with m >= 258 && n >= 10 */
- /* get literal/length code */
- GRABBITS(20) /* max bits for literal/length code */
- if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
- {
- DUMPBITS(t->bits)
- Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
- "inflate: * literal '%c'\n" :
- "inflate: * literal 0x%02x\n", t->base));
- *q++ = (Byte)t->base;
- m--;
- continue;
- }
- do {
- DUMPBITS(t->bits)
- if (e & 16)
- {
- /* get extra bits for length */
- e &= 15;
- c = t->base + ((uInt)b & inflate_mask[e]);
- DUMPBITS(e)
- Tracevv((stderr, "inflate: * length %u\n", c));
-
- /* decode distance base of block to copy */
- GRABBITS(15); /* max bits for distance code */
- e = (t = td + ((uInt)b & md))->exop;
- do {
- DUMPBITS(t->bits)
- if (e & 16)
- {
- /* get extra bits to add to distance base */
- e &= 15;
- GRABBITS(e) /* get extra bits (up to 13) */
- d = t->base + ((uInt)b & inflate_mask[e]);
- DUMPBITS(e)
- Tracevv((stderr, "inflate: * distance %u\n", d));
-
- /* do the copy */
- m -= c;
- if ((uInt)(q - s->window) >= d) /* offset before dest */
- { /* just copy */
- r = q - d;
- *q++ = *r++; c--; /* minimum count is three, */
- *q++ = *r++; c--; /* so unroll loop a little */
- }
- else /* else offset after destination */
- {
- e = d - (q - s->window); /* bytes from offset to end */
- r = s->end - e; /* pointer to offset */
- if (c > e) /* if source crosses, */
- {
- c -= e; /* copy to end of window */
- do {
- *q++ = *r++;
- } while (--e);
- r = s->window; /* copy rest from start of window */
- }
- }
- do { /* copy all or what's left */
- *q++ = *r++;
- } while (--c);
- break;
- }
- else if ((e & 64) == 0)
- e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop;
- else
- {
- z->msg = "invalid distance code";
- UNGRAB
- UPDATE
- return Z_DATA_ERROR;
- }
- } while (1);
- break;
- }
- if ((e & 64) == 0)
- {
- if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0)
- {
- DUMPBITS(t->bits)
- Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
- "inflate: * literal '%c'\n" :
- "inflate: * literal 0x%02x\n", t->base));
- *q++ = (Byte)t->base;
- m--;
- break;
- }
- }
- else if (e & 32)
- {
- Tracevv((stderr, "inflate: * end of block\n"));
- UNGRAB
- UPDATE
- return Z_STREAM_END;
- }
- else
- {
- z->msg = "invalid literal/length code";
- UNGRAB
- UPDATE
- return Z_DATA_ERROR;
- }
- } while (1);
- } while (m >= 258 && n >= 10);
-
- /* not enough input or output--restore pointers and return */
- UNGRAB
- UPDATE
- return Z_OK;
-}
-
-
-/*+++++*/
-/* zutil.c -- target dependent utility functions for the compression library
- * Copyright (C) 1995 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* From: zutil.c,v 1.8 1995/05/03 17:27:12 jloup Exp */
-
-char *zlib_version = ZLIB_VERSION;
-
-char *z_errmsg[] = {
-"stream end", /* Z_STREAM_END 1 */
-"", /* Z_OK 0 */
-"file error", /* Z_ERRNO (-1) */
-"stream error", /* Z_STREAM_ERROR (-2) */
-"data error", /* Z_DATA_ERROR (-3) */
-"insufficient memory", /* Z_MEM_ERROR (-4) */
-"buffer error", /* Z_BUF_ERROR (-5) */
-""};
-
-
-/*+++++*/
-/* adler32.c -- compute the Adler-32 checksum of a data stream
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* From: adler32.c,v 1.6 1995/05/03 17:27:08 jloup Exp */
-
-#define BASE 65521L /* largest prime smaller than 65536 */
-#define NMAX 5552
-/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
-
-#define DO1(buf) {s1 += *buf++; s2 += s1;}
-#define DO2(buf) DO1(buf); DO1(buf);
-#define DO4(buf) DO2(buf); DO2(buf);
-#define DO8(buf) DO4(buf); DO4(buf);
-#define DO16(buf) DO8(buf); DO8(buf);
-
-/* ========================================================================= */
-uLong adler32(
- uLong adler,
- Bytef *buf,
- uInt len
-)
-{
- unsigned long s1 = adler & 0xffff;
- unsigned long s2 = (adler >> 16) & 0xffff;
- int k;
-
- if (buf == Z_NULL) return 1L;
-
- while (len > 0) {
- k = len < NMAX ? len : NMAX;
- len -= k;
- while (k >= 16) {
- DO16(buf);
- k -= 16;
- }
- if (k != 0) do {
- DO1(buf);
- } while (--k);
- s1 %= BASE;
- s2 %= BASE;
- }
- return (s2 << 16) | s1;
-}
diff --git a/arch/ppc64/boot/zlib.h b/arch/ppc64/boot/zlib.h
deleted file mode 100644
index f0b996c6864f..000000000000
--- a/arch/ppc64/boot/zlib.h
+++ /dev/null
@@ -1,432 +0,0 @@
-/* */
-
-/*
- * This file is derived from zlib.h and zconf.h from the zlib-0.95
- * distribution by Jean-loup Gailly and Mark Adler, with some additions
- * by Paul Mackerras to aid in implementing Deflate compression and
- * decompression for PPP packets.
- */
-
-/*
- * ==FILEVERSION 960122==
- *
- * This marker is used by the Linux installation script to determine
- * whether an up-to-date version of this file is already installed.
- */
-
-/* zlib.h -- interface of the 'zlib' general purpose compression library
- version 0.95, Aug 16th, 1995.
-
- Copyright (C) 1995 Jean-loup Gailly and Mark Adler
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Jean-loup Gailly Mark Adler
- gzip@prep.ai.mit.edu madler@alumni.caltech.edu
- */
-
-#ifndef _ZLIB_H
-#define _ZLIB_H
-
-/* #include "zconf.h" */ /* included directly here */
-
-/* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* From: zconf.h,v 1.12 1995/05/03 17:27:12 jloup Exp */
-
-/*
- The library does not install any signal handler. It is recommended to
- add at least a handler for SIGSEGV when decompressing; the library checks
- the consistency of the input data whenever possible but may go nuts
- for some forms of corrupted input.
- */
-
-/*
- * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
- * than 64k bytes at a time (needed on systems with 16-bit int).
- * Compile with -DUNALIGNED_OK if it is OK to access shorts or ints
- * at addresses which are not a multiple of their size.
- * Under DOS, -DFAR=far or -DFAR=__far may be needed.
- */
-
-#ifndef STDC
-# if defined(MSDOS) || defined(__STDC__) || defined(__cplusplus)
-# define STDC
-# endif
-#endif
-
-#ifdef __MWERKS__ /* Metrowerks CodeWarrior declares fileno() in unix.h */
-# include <unix.h>
-#endif
-
-/* Maximum value for memLevel in deflateInit2 */
-#ifndef MAX_MEM_LEVEL
-# ifdef MAXSEG_64K
-# define MAX_MEM_LEVEL 8
-# else
-# define MAX_MEM_LEVEL 9
-# endif
-#endif
-
-#ifndef FAR
-# define FAR
-#endif
-
-/* Maximum value for windowBits in deflateInit2 and inflateInit2 */
-#ifndef MAX_WBITS
-# define MAX_WBITS 15 /* 32K LZ77 window */
-#endif
-
-/* The memory requirements for deflate are (in bytes):
- 1 << (windowBits+2) + 1 << (memLevel+9)
- that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
- plus a few kilobytes for small objects. For example, if you want to reduce
- the default memory requirements from 256K to 128K, compile with
- make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
- Of course this will generally degrade compression (there's no free lunch).
-
- The memory requirements for inflate are (in bytes) 1 << windowBits
- that is, 32K for windowBits=15 (default value) plus a few kilobytes
- for small objects.
-*/
-
- /* Type declarations */
-
-#ifndef OF /* function prototypes */
-# ifdef STDC
-# define OF(args) args
-# else
-# define OF(args) ()
-# endif
-#endif
-
-typedef unsigned char Byte; /* 8 bits */
-typedef unsigned int uInt; /* 16 bits or more */
-typedef unsigned long uLong; /* 32 bits or more */
-
-typedef Byte FAR Bytef;
-typedef char FAR charf;
-typedef int FAR intf;
-typedef uInt FAR uIntf;
-typedef uLong FAR uLongf;
-
-#ifdef STDC
- typedef void FAR *voidpf;
- typedef void *voidp;
-#else
- typedef Byte FAR *voidpf;
- typedef Byte *voidp;
-#endif
-
-/* end of original zconf.h */
-
-#define ZLIB_VERSION "0.95P"
-
-/*
- The 'zlib' compression library provides in-memory compression and
- decompression functions, including integrity checks of the uncompressed
- data. This version of the library supports only one compression method
- (deflation) but other algorithms may be added later and will have the same
- stream interface.
-
- For compression the application must provide the output buffer and
- may optionally provide the input buffer for optimization. For decompression,
- the application must provide the input buffer and may optionally provide
- the output buffer for optimization.
-
- Compression can be done in a single step if the buffers are large
- enough (for example if an input file is mmap'ed), or can be done by
- repeated calls of the compression function. In the latter case, the
- application must provide more input and/or consume the output
- (providing more output space) before each call.
-*/
-
-typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
-typedef void (*free_func) OF((voidpf opaque, voidpf address, uInt nbytes));
-
-struct internal_state;
-
-typedef struct z_stream_s {
- Bytef *next_in; /* next input byte */
- uInt avail_in; /* number of bytes available at next_in */
- uLong total_in; /* total nb of input bytes read so far */
-
- Bytef *next_out; /* next output byte should be put there */
- uInt avail_out; /* remaining free space at next_out */
- uLong total_out; /* total nb of bytes output so far */
-
- char *msg; /* last error message, NULL if no error */
- struct internal_state FAR *state; /* not visible by applications */
-
- alloc_func zalloc; /* used to allocate the internal state */
- free_func zfree; /* used to free the internal state */
- voidp opaque; /* private data object passed to zalloc and zfree */
-
- Byte data_type; /* best guess about the data type: ascii or binary */
-
-} z_stream;
-
-/*
- The application must update next_in and avail_in when avail_in has
- dropped to zero. It must update next_out and avail_out when avail_out
- has dropped to zero. The application must initialize zalloc, zfree and
- opaque before calling the init function. All other fields are set by the
- compression library and must not be updated by the application.
-
- The opaque value provided by the application will be passed as the first
- parameter for calls of zalloc and zfree. This can be useful for custom
- memory management. The compression library attaches no meaning to the
- opaque value.
-
- zalloc must return Z_NULL if there is not enough memory for the object.
- On 16-bit systems, the functions zalloc and zfree must be able to allocate
- exactly 65536 bytes, but will not be required to allocate more than this
- if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
- pointers returned by zalloc for objects of exactly 65536 bytes *must*
- have their offset normalized to zero. The default allocation function
- provided by this library ensures this (see zutil.c). To reduce memory
- requirements and avoid any allocation of 64K objects, at the expense of
- compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
-
- The fields total_in and total_out can be used for statistics or
- progress reports. After compression, total_in holds the total size of
- the uncompressed data and may be saved for use in the decompressor
- (particularly if the decompressor wants to decompress everything in
- a single step).
-*/
-
- /* constants */
-
-#define Z_NO_FLUSH 0
-#define Z_PARTIAL_FLUSH 1
-#define Z_FULL_FLUSH 2
-#define Z_SYNC_FLUSH 3 /* experimental: partial_flush + byte align */
-#define Z_FINISH 4
-#define Z_PACKET_FLUSH 5
-/* See deflate() below for the usage of these constants */
-
-#define Z_OK 0
-#define Z_STREAM_END 1
-#define Z_ERRNO (-1)
-#define Z_STREAM_ERROR (-2)
-#define Z_DATA_ERROR (-3)
-#define Z_MEM_ERROR (-4)
-#define Z_BUF_ERROR (-5)
-/* error codes for the compression/decompression functions */
-
-#define Z_BEST_SPEED 1
-#define Z_BEST_COMPRESSION 9
-#define Z_DEFAULT_COMPRESSION (-1)
-/* compression levels */
-
-#define Z_FILTERED 1
-#define Z_HUFFMAN_ONLY 2
-#define Z_DEFAULT_STRATEGY 0
-
-#define Z_BINARY 0
-#define Z_ASCII 1
-#define Z_UNKNOWN 2
-/* Used to set the data_type field */
-
-#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
-
-extern char *zlib_version;
-/* The application can compare zlib_version and ZLIB_VERSION for consistency.
- If the first character differs, the library code actually used is
- not compatible with the zlib.h header file used by the application.
- */
-
- /* basic functions */
-
-extern int inflateInit OF((z_stream *strm));
-/*
- Initializes the internal stream state for decompression. The fields
- zalloc and zfree must be initialized before by the caller. If zalloc and
- zfree are set to Z_NULL, inflateInit updates them to use default allocation
- functions.
-
- inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory. msg is set to null if there is no error message.
- inflateInit does not perform any decompression: this will be done by
- inflate().
-*/
-
-
-extern int inflate OF((z_stream *strm, int flush));
-/*
- Performs one or both of the following actions:
-
- - Decompress more input starting at next_in and update next_in and avail_in
- accordingly. If not all input can be processed (because there is not
- enough room in the output buffer), next_in is updated and processing
- will resume at this point for the next call of inflate().
-
- - Provide more output starting at next_out and update next_out and avail_out
- accordingly. inflate() always provides as much output as possible
- (until there is no more input data or no more space in the output buffer).
-
- Before the call of inflate(), the application should ensure that at least
- one of the actions is possible, by providing more input and/or consuming
- more output, and updating the next_* and avail_* values accordingly.
- The application can consume the uncompressed output when it wants, for
- example when the output buffer is full (avail_out == 0), or after each
- call of inflate().
-
- If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH,
- inflate flushes as much output as possible to the output buffer. The
- flushing behavior of inflate is not specified for values of the flush
- parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the
- current implementation actually flushes as much output as possible
- anyway. For Z_PACKET_FLUSH, inflate checks that once all the input data
- has been consumed, it is expecting to see the length field of a stored
- block; if not, it returns Z_DATA_ERROR.
-
- inflate() should normally be called until it returns Z_STREAM_END or an
- error. However if all decompression is to be performed in a single step
- (a single call of inflate), the parameter flush should be set to
- Z_FINISH. In this case all pending input is processed and all pending
- output is flushed; avail_out must be large enough to hold all the
- uncompressed data. (The size of the uncompressed data may have been saved
- by the compressor for this purpose.) The next operation on this stream must
- be inflateEnd to deallocate the decompression state. The use of Z_FINISH
- is never required, but can be used to inform inflate that a faster routine
- may be used for the single inflate() call.
-
- inflate() returns Z_OK if some progress has been made (more input
- processed or more output produced), Z_STREAM_END if the end of the
- compressed data has been reached and all uncompressed output has been
- produced, Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if
- the stream structure was inconsistent (for example if next_in or next_out
- was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no
- progress is possible or if there was not enough room in the output buffer
- when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then
- call inflateSync to look for a good compression block. */
-
-
-extern int inflateEnd OF((z_stream *strm));
-/*
- All dynamically allocated data structures for this stream are freed.
- This function discards any unprocessed input and does not flush any
- pending output.
-
- inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
- was inconsistent. In the error case, msg may be set but then points to a
- static string (which must not be deallocated).
-*/
-
- /* advanced functions */
-
-extern int inflateInit2 OF((z_stream *strm,
- int windowBits));
-/*
- This is another version of inflateInit with more compression options. The
- fields next_out, zalloc and zfree must be initialized before by the caller.
-
- The windowBits parameter is the base two logarithm of the maximum window
- size (the size of the history buffer). It should be in the range 8..15 for
- this version of the library (the value 16 will be allowed soon). The
- default value is 15 if inflateInit is used instead. If a compressed stream
- with a larger window size is given as input, inflate() will return with
- the error code Z_DATA_ERROR instead of trying to allocate a larger window.
-
- If next_out is not null, the library will use this buffer for the history
- buffer; the buffer must either be large enough to hold the entire output
- data, or have at least 1<<windowBits bytes. If next_out is null, the
- library will allocate its own buffer (and leave next_out null). next_in
- need not be provided here but must be provided by the application for the
- next call of inflate().
-
- If the history buffer is provided by the application, next_out must
- never be changed by the application since the decompressor maintains
- history information inside this buffer from call to call; the application
- can only reset next_out to the beginning of the history buffer when
- avail_out is zero and all output has been consumed.
-
- inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was
- not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as
- windowBits < 8). msg is set to null if there is no error message.
- inflateInit2 does not perform any decompression: this will be done by
- inflate().
-*/
-
-extern int inflateSync OF((z_stream *strm));
-/*
- Skips invalid compressed data until the special marker (see deflate()
- above) can be found, or until all available input is skipped. No output
- is provided.
-
- inflateSync returns Z_OK if the special marker has been found, Z_BUF_ERROR
- if no more input was provided, Z_DATA_ERROR if no marker has been found,
- or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
- case, the application may save the current current value of total_in which
- indicates where valid compressed data was found. In the error case, the
- application may repeatedly call inflateSync, providing more input each time,
- until success or end of the input data.
-*/
-
-extern int inflateReset OF((z_stream *strm));
-/*
- This function is equivalent to inflateEnd followed by inflateInit,
- but does not free and reallocate all the internal decompression state.
- The stream will keep attributes that may have been set by inflateInit2.
-
- inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent (such as zalloc or state being NULL).
-*/
-
-extern int inflateIncomp OF((z_stream *strm));
-/*
- This function adds the data at next_in (avail_in bytes) to the output
- history without performing any output. There must be no pending output,
- and the decompressor must be expecting to see the start of a block.
- Calling this function is equivalent to decompressing a stored block
- containing the data at next_in (except that the data is not output).
-*/
-
- /* checksum functions */
-
-/*
- This function is not related to compression but is exported
- anyway because it might be useful in applications using the
- compression library.
-*/
-
-extern uLong adler32 OF((uLong adler, Bytef *buf, uInt len));
-
-/*
- Update a running Adler-32 checksum with the bytes buf[0..len-1] and
- return the updated checksum. If buf is NULL, this function returns
- the required initial value for the checksum.
- An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
- much faster. Usage example:
-
- uLong adler = adler32(0L, Z_NULL, 0);
-
- while (read_buffer(buffer, length) != EOF) {
- adler = adler32(adler, buffer, length);
- }
- if (adler != original_adler) error();
-*/
-
-#ifndef _Z_UTIL_H
- struct internal_state {int dummy;}; /* hack for buggy compilers */
-#endif
-
-#endif /* _ZLIB_H */
diff --git a/arch/ppc64/defconfig b/arch/ppc64/defconfig
index 37c157c93cef..e79fd60bc122 100644
--- a/arch/ppc64/defconfig
+++ b/arch/ppc64/defconfig
@@ -1318,7 +1318,7 @@ CONFIG_MSDOS_PARTITION=y
#
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_737=m
CONFIG_NLS_CODEPAGE_775=m
CONFIG_NLS_CODEPAGE_850=m
@@ -1342,7 +1342,7 @@ CONFIG_NLS_ISO8859_8=m
CONFIG_NLS_CODEPAGE_1250=m
CONFIG_NLS_CODEPAGE_1251=m
CONFIG_NLS_ASCII=m
-CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_ISO8859_2=m
CONFIG_NLS_ISO8859_3=m
CONFIG_NLS_ISO8859_4=m
diff --git a/arch/ppc64/kernel/HvLpEvent.c b/arch/ppc64/kernel/HvLpEvent.c
deleted file mode 100644
index 90032b138902..000000000000
--- a/arch/ppc64/kernel/HvLpEvent.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright 2001 Mike Corrigan IBM Corp
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#include <linux/stddef.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <asm/system.h>
-#include <asm/iSeries/HvLpEvent.h>
-#include <asm/iSeries/HvCallEvent.h>
-#include <asm/iSeries/ItLpNaca.h>
-
-/* Array of LpEvent handler functions */
-LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes];
-unsigned lpEventHandlerPaths[HvLpEvent_Type_NumTypes];
-
-/* Register a handler for an LpEvent type */
-
-int HvLpEvent_registerHandler( HvLpEvent_Type eventType, LpEventHandler handler )
-{
- int rc = 1;
- if ( eventType < HvLpEvent_Type_NumTypes ) {
- lpEventHandler[eventType] = handler;
- rc = 0;
- }
- return rc;
-
-}
-
-int HvLpEvent_unregisterHandler( HvLpEvent_Type eventType )
-{
- int rc = 1;
-
- might_sleep();
-
- if ( eventType < HvLpEvent_Type_NumTypes ) {
- if ( !lpEventHandlerPaths[eventType] ) {
- lpEventHandler[eventType] = NULL;
- rc = 0;
-
- /* We now sleep until all other CPUs have scheduled. This ensures that
- * the deletion is seen by all other CPUs, and that the deleted handler
- * isn't still running on another CPU when we return. */
- synchronize_rcu();
- }
- }
- return rc;
-}
-EXPORT_SYMBOL(HvLpEvent_registerHandler);
-EXPORT_SYMBOL(HvLpEvent_unregisterHandler);
-
-/* (lpIndex is the partition index of the target partition.
- * needed only for VirtualIo, VirtualLan and SessionMgr. Zero
- * indicates to use our partition index - for the other types)
- */
-int HvLpEvent_openPath( HvLpEvent_Type eventType, HvLpIndex lpIndex )
-{
- int rc = 1;
- if ( eventType < HvLpEvent_Type_NumTypes &&
- lpEventHandler[eventType] ) {
- if ( lpIndex == 0 )
- lpIndex = itLpNaca.xLpIndex;
- HvCallEvent_openLpEventPath( lpIndex, eventType );
- ++lpEventHandlerPaths[eventType];
- rc = 0;
- }
- return rc;
-}
-
-int HvLpEvent_closePath( HvLpEvent_Type eventType, HvLpIndex lpIndex )
-{
- int rc = 1;
- if ( eventType < HvLpEvent_Type_NumTypes &&
- lpEventHandler[eventType] &&
- lpEventHandlerPaths[eventType] ) {
- if ( lpIndex == 0 )
- lpIndex = itLpNaca.xLpIndex;
- HvCallEvent_closeLpEventPath( lpIndex, eventType );
- --lpEventHandlerPaths[eventType];
- rc = 0;
- }
- return rc;
-}
-
diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile
index ae60eb1193c6..327c08ce4291 100644
--- a/arch/ppc64/kernel/Makefile
+++ b/arch/ppc64/kernel/Makefile
@@ -2,36 +2,34 @@
# Makefile for the linux ppc64 kernel.
#
+ifneq ($(CONFIG_PPC_MERGE),y)
+
EXTRA_CFLAGS += -mno-minimal-toc
extra-y := head.o vmlinux.lds
-obj-y := setup.o entry.o traps.o irq.o idle.o dma.o \
- time.o process.o signal.o syscalls.o misc.o ptrace.o \
- align.o semaphore.o bitops.o pacaData.o \
- udbg.o binfmt_elf32.o sys_ppc32.o ioctl32.o \
- ptrace32.o signal32.o rtc.o init_task.o \
- lmb.o cputable.o cpu_setup_power4.o idle_power4.o \
- iommu.o sysfs.o vdso.o pmc.o firmware.o
-obj-y += vdso32/ vdso64/
+obj-y := misc.o prom.o
+
+endif
-obj-$(CONFIG_PPC_OF) += of_device.o
+obj-y += irq.o idle.o dma.o \
+ signal.o \
+ align.o bitops.o pacaData.o \
+ udbg.o ioctl32.o \
+ rtc.o \
+ cpu_setup_power4.o \
+ iommu.o sysfs.o vdso.o firmware.o
+obj-y += vdso32/ vdso64/
-pci-obj-$(CONFIG_PPC_ISERIES) += iSeries_pci.o iSeries_irq.o \
- iSeries_VpdInfo.o
pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o
obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y)
-obj-$(CONFIG_PPC_ISERIES) += HvCall.o HvLpConfig.o LparData.o \
- iSeries_setup.o ItLpQueue.o hvCall.o \
- mf.o HvLpEvent.o iSeries_proc.o iSeries_htab.o \
- iSeries_iommu.o
-
-obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o prom_init.o prom.o
+obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o
+ifneq ($(CONFIG_PPC_MERGE),y)
+obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o
+endif
-obj-$(CONFIG_PPC_PSERIES) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o \
- pSeries_nvram.o rtasd.o ras.o pSeries_reconfig.o \
- pSeries_setup.o pSeries_iommu.o udbg_16550.o
+obj-$(CONFIG_PPC_PSERIES) += rtasd.o udbg_16550.o
obj-$(CONFIG_PPC_BPA) += bpa_setup.o bpa_iommu.o bpa_nvram.o \
bpa_iic.o spider-pic.o
@@ -41,45 +39,36 @@ obj-$(CONFIG_EEH) += eeh.o
obj-$(CONFIG_PROC_FS) += proc_ppc64.o
obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o
obj-$(CONFIG_SMP) += smp.o
-obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o
-obj-$(CONFIG_PPC_RTAS) += rtas.o rtas_pci.o
+obj-$(CONFIG_MODULES) += module.o
+ifneq ($(CONFIG_PPC_MERGE),y)
+obj-$(CONFIG_MODULES) += ppc_ksyms.o
+endif
+obj-$(CONFIG_PPC_RTAS) += rtas_pci.o
obj-$(CONFIG_RTAS_PROC) += rtas-proc.o
obj-$(CONFIG_SCANLOG) += scanlog.o
-obj-$(CONFIG_VIOPATH) += viopath.o
obj-$(CONFIG_LPARCFG) += lparcfg.o
obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o
+ifneq ($(CONFIG_PPC_MERGE),y)
obj-$(CONFIG_BOOTX_TEXT) += btext.o
+endif
obj-$(CONFIG_HVCS) += hvcserver.o
-vio-obj-$(CONFIG_PPC_PSERIES) += pSeries_vio.o
-vio-obj-$(CONFIG_PPC_ISERIES) += iSeries_vio.o
-obj-$(CONFIG_IBMVIO) += vio.o $(vio-obj-y)
-obj-$(CONFIG_XICS) += xics.o
-obj-$(CONFIG_MPIC) += mpic.o
+obj-$(CONFIG_PPC_PMAC) += udbg_scc.o
-obj-$(CONFIG_PPC_PMAC) += pmac_setup.o pmac_feature.o pmac_pci.o \
- pmac_time.o pmac_nvram.o pmac_low_i2c.o \
- udbg_scc.o
-
-obj-$(CONFIG_PPC_MAPLE) += maple_setup.o maple_pci.o maple_time.o \
- udbg_16550.o
-
-obj-$(CONFIG_U3_DART) += u3_iommu.o
+obj-$(CONFIG_PPC_MAPLE) += udbg_16550.o
ifdef CONFIG_SMP
-obj-$(CONFIG_PPC_PMAC) += pmac_smp.o smp-tbsync.o
-obj-$(CONFIG_PPC_ISERIES) += iSeries_smp.o
-obj-$(CONFIG_PPC_PSERIES) += pSeries_smp.o
-obj-$(CONFIG_PPC_BPA) += pSeries_smp.o
+obj-$(CONFIG_PPC_PMAC) += smp-tbsync.o
obj-$(CONFIG_PPC_MAPLE) += smp-tbsync.o
endif
-obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
obj-$(CONFIG_KPROBES) += kprobes.o
CFLAGS_ioctl32.o += -Ifs/
+ifneq ($(CONFIG_PPC_MERGE),y)
ifeq ($(CONFIG_PPC_ISERIES),y)
-arch/ppc64/kernel/head.o: arch/ppc64/kernel/lparmap.s
-AFLAGS_head.o += -Iarch/ppc64/kernel
+arch/ppc64/kernel/head.o: arch/powerpc/kernel/lparmap.s
+AFLAGS_head.o += -Iarch/powerpc/kernel
+endif
endif
diff --git a/arch/ppc64/kernel/align.c b/arch/ppc64/kernel/align.c
index 330e7ef81427..256d5b592aa1 100644
--- a/arch/ppc64/kernel/align.c
+++ b/arch/ppc64/kernel/align.c
@@ -313,7 +313,7 @@ fix_alignment(struct pt_regs *regs)
/* Doing stfs, have to convert to single */
preempt_disable();
enable_kernel_fp();
- cvt_df(&current->thread.fpr[reg], (float *)&data.v[4], &current->thread.fpscr);
+ cvt_df(&current->thread.fpr[reg], (float *)&data.v[4], &current->thread);
disable_kernel_fp();
preempt_enable();
}
@@ -349,7 +349,7 @@ fix_alignment(struct pt_regs *regs)
/* Doing lfs, have to convert to double */
preempt_disable();
enable_kernel_fp();
- cvt_fd((float *)&data.v[4], &current->thread.fpr[reg], &current->thread.fpscr);
+ cvt_fd((float *)&data.v[4], &current->thread.fpr[reg], &current->thread);
disable_kernel_fp();
preempt_enable();
}
diff --git a/arch/ppc64/kernel/asm-offsets.c b/arch/ppc64/kernel/asm-offsets.c
index 1ff4fa05a973..5e6046cb414e 100644
--- a/arch/ppc64/kernel/asm-offsets.c
+++ b/arch/ppc64/kernel/asm-offsets.c
@@ -46,8 +46,6 @@
int main(void)
{
/* thread struct on stack */
- DEFINE(THREAD_SHIFT, THREAD_SHIFT);
- DEFINE(THREAD_SIZE, THREAD_SIZE);
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
DEFINE(TI_SC_NOERR, offsetof(struct thread_info, syscall_noerror));
@@ -77,6 +75,7 @@ int main(void)
DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size));
DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page));
DEFINE(PLATFORM, offsetof(struct systemcfg, platform));
+ DEFINE(PLATFORM_LPAR, PLATFORM_LPAR);
/* paca */
DEFINE(PACA_SIZE, sizeof(struct paca_struct));
diff --git a/arch/ppc64/kernel/bpa_iommu.c b/arch/ppc64/kernel/bpa_iommu.c
index 5f2460090e03..da1b4b7a3269 100644
--- a/arch/ppc64/kernel/bpa_iommu.c
+++ b/arch/ppc64/kernel/bpa_iommu.c
@@ -39,8 +39,8 @@
#include <asm/pmac_feature.h>
#include <asm/abs_addr.h>
#include <asm/system.h>
+#include <asm/ppc-pci.h>
-#include "pci.h"
#include "bpa_iommu.h"
static inline unsigned long
diff --git a/arch/ppc64/kernel/bpa_setup.c b/arch/ppc64/kernel/bpa_setup.c
index 57b3db66f458..c2dc8f282eb8 100644
--- a/arch/ppc64/kernel/bpa_setup.c
+++ b/arch/ppc64/kernel/bpa_setup.c
@@ -43,8 +43,9 @@
#include <asm/time.h>
#include <asm/nvram.h>
#include <asm/cputable.h>
+#include <asm/ppc-pci.h>
+#include <asm/irq.h>
-#include "pci.h"
#include "bpa_iic.h"
#include "bpa_iommu.h"
@@ -54,7 +55,7 @@
#define DBG(fmt...)
#endif
-void bpa_get_cpuinfo(struct seq_file *m)
+void bpa_show_cpuinfo(struct seq_file *m)
{
struct device_node *root;
const char *model = "";
@@ -128,7 +129,7 @@ struct machdep_calls __initdata bpa_md = {
.probe = bpa_probe,
.setup_arch = bpa_setup_arch,
.init_early = bpa_init_early,
- .get_cpuinfo = bpa_get_cpuinfo,
+ .show_cpuinfo = bpa_show_cpuinfo,
.restart = rtas_restart,
.power_off = rtas_power_off,
.halt = rtas_halt,
diff --git a/arch/ppc64/kernel/btext.c b/arch/ppc64/kernel/btext.c
index b6fbfbe9032d..506a37885c5c 100644
--- a/arch/ppc64/kernel/btext.c
+++ b/arch/ppc64/kernel/btext.c
@@ -18,6 +18,7 @@
#include <asm/io.h>
#include <asm/lmb.h>
#include <asm/processor.h>
+#include <asm/udbg.h>
#undef NO_SCROLL
@@ -131,6 +132,47 @@ int btext_initialize(struct device_node *np)
return 0;
}
+static void btext_putc(unsigned char c)
+{
+ btext_drawchar(c);
+}
+
+void __init init_boot_display(void)
+{
+ char *name;
+ struct device_node *np = NULL;
+ int rc = -ENODEV;
+
+ printk("trying to initialize btext ...\n");
+
+ name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
+ if (name != NULL) {
+ np = of_find_node_by_path(name);
+ if (np != NULL) {
+ if (strcmp(np->type, "display") != 0) {
+ printk("boot stdout isn't a display !\n");
+ of_node_put(np);
+ np = NULL;
+ }
+ }
+ }
+ if (np)
+ rc = btext_initialize(np);
+ if (rc) {
+ for (np = NULL; (np = of_find_node_by_type(np, "display"));) {
+ if (get_property(np, "linux,opened", NULL)) {
+ printk("trying %s ...\n", np->full_name);
+ rc = btext_initialize(np);
+ printk("result: %d\n", rc);
+ }
+ if (rc == 0)
+ break;
+ }
+ }
+ if (rc == 0 && udbg_putc == NULL)
+ udbg_putc = btext_putc;
+}
+
/* Calc the base address of a given point (x,y) */
static unsigned char * calc_base(int x, int y)
diff --git a/arch/ppc64/kernel/cputable.c b/arch/ppc64/kernel/cputable.c
deleted file mode 100644
index 8831a28c3c4e..000000000000
--- a/arch/ppc64/kernel/cputable.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * arch/ppc64/kernel/cputable.c
- *
- * Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org)
- *
- * Modifications for ppc64:
- * Copyright (C) 2003 Dave Engebretsen <engebret@us.ibm.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/config.h>
-#include <linux/string.h>
-#include <linux/sched.h>
-#include <linux/threads.h>
-#include <linux/init.h>
-#include <linux/module.h>
-
-#include <asm/oprofile_impl.h>
-#include <asm/cputable.h>
-
-struct cpu_spec* cur_cpu_spec = NULL;
-EXPORT_SYMBOL(cur_cpu_spec);
-
-/* NOTE:
- * Unlike ppc32, ppc64 will only call this once for the boot CPU, it's
- * the responsibility of the appropriate CPU save/restore functions to
- * eventually copy these settings over. Those save/restore aren't yet
- * part of the cputable though. That has to be fixed for both ppc32
- * and ppc64
- */
-extern void __setup_cpu_power3(unsigned long offset, struct cpu_spec* spec);
-extern void __setup_cpu_power4(unsigned long offset, struct cpu_spec* spec);
-extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
-extern void __setup_cpu_be(unsigned long offset, struct cpu_spec* spec);
-
-
-/* We only set the altivec features if the kernel was compiled with altivec
- * support
- */
-#ifdef CONFIG_ALTIVEC
-#define CPU_FTR_ALTIVEC_COMP CPU_FTR_ALTIVEC
-#define PPC_FEATURE_HAS_ALTIVEC_COMP PPC_FEATURE_HAS_ALTIVEC
-#else
-#define CPU_FTR_ALTIVEC_COMP 0
-#define PPC_FEATURE_HAS_ALTIVEC_COMP 0
-#endif
-
-struct cpu_spec cpu_specs[] = {
- { /* Power3 */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00400000,
- .cpu_name = "POWER3 (630)",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR,
- .cpu_user_features = COMMON_USER_PPC64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_power3,
-#ifdef CONFIG_OPROFILE
- .oprofile_cpu_type = "ppc64/power3",
- .oprofile_model = &op_model_rs64,
-#endif
- },
- { /* Power3+ */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00410000,
- .cpu_name = "POWER3 (630+)",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR,
- .cpu_user_features = COMMON_USER_PPC64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_power3,
-#ifdef CONFIG_OPROFILE
- .oprofile_cpu_type = "ppc64/power3",
- .oprofile_model = &op_model_rs64,
-#endif
- },
- { /* Northstar */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00330000,
- .cpu_name = "RS64-II (northstar)",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
- CPU_FTR_MMCRA | CPU_FTR_CTRL,
- .cpu_user_features = COMMON_USER_PPC64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_power3,
-#ifdef CONFIG_OPROFILE
- .oprofile_cpu_type = "ppc64/rs64",
- .oprofile_model = &op_model_rs64,
-#endif
- },
- { /* Pulsar */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00340000,
- .cpu_name = "RS64-III (pulsar)",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
- CPU_FTR_MMCRA | CPU_FTR_CTRL,
- .cpu_user_features = COMMON_USER_PPC64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_power3,
-#ifdef CONFIG_OPROFILE
- .oprofile_cpu_type = "ppc64/rs64",
- .oprofile_model = &op_model_rs64,
-#endif
- },
- { /* I-star */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00360000,
- .cpu_name = "RS64-III (icestar)",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
- CPU_FTR_MMCRA | CPU_FTR_CTRL,
- .cpu_user_features = COMMON_USER_PPC64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_power3,
-#ifdef CONFIG_OPROFILE
- .oprofile_cpu_type = "ppc64/rs64",
- .oprofile_model = &op_model_rs64,
-#endif
- },
- { /* S-star */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00370000,
- .cpu_name = "RS64-IV (sstar)",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
- CPU_FTR_MMCRA | CPU_FTR_CTRL,
- .cpu_user_features = COMMON_USER_PPC64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_power3,
-#ifdef CONFIG_OPROFILE
- .oprofile_cpu_type = "ppc64/rs64",
- .oprofile_model = &op_model_rs64,
-#endif
- },
- { /* Power4 */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00350000,
- .cpu_name = "POWER4 (gp)",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
- CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA,
- .cpu_user_features = COMMON_USER_PPC64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_power4,
-#ifdef CONFIG_OPROFILE
- .oprofile_cpu_type = "ppc64/power4",
- .oprofile_model = &op_model_rs64,
-#endif
- },
- { /* Power4+ */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00380000,
- .cpu_name = "POWER4+ (gq)",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
- CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA,
- .cpu_user_features = COMMON_USER_PPC64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_power4,
-#ifdef CONFIG_OPROFILE
- .oprofile_cpu_type = "ppc64/power4",
- .oprofile_model = &op_model_power4,
-#endif
- },
- { /* PPC970 */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00390000,
- .cpu_name = "PPC970",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
- CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
- CPU_FTR_CAN_NAP | CPU_FTR_MMCRA,
- .cpu_user_features = COMMON_USER_PPC64 |
- PPC_FEATURE_HAS_ALTIVEC_COMP,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_ppc970,
-#ifdef CONFIG_OPROFILE
- .oprofile_cpu_type = "ppc64/970",
- .oprofile_model = &op_model_power4,
-#endif
- },
- { /* PPC970FX */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x003c0000,
- .cpu_name = "PPC970FX",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
- CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
- CPU_FTR_CAN_NAP | CPU_FTR_MMCRA,
- .cpu_user_features = COMMON_USER_PPC64 |
- PPC_FEATURE_HAS_ALTIVEC_COMP,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_ppc970,
-#ifdef CONFIG_OPROFILE
- .oprofile_cpu_type = "ppc64/970",
- .oprofile_model = &op_model_power4,
-#endif
- },
- { /* PPC970MP */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00440000,
- .cpu_name = "PPC970MP",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
- CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
- CPU_FTR_CAN_NAP | CPU_FTR_MMCRA,
- .cpu_user_features = COMMON_USER_PPC64 |
- PPC_FEATURE_HAS_ALTIVEC_COMP,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .cpu_setup = __setup_cpu_ppc970,
-#ifdef CONFIG_OPROFILE
- .oprofile_cpu_type = "ppc64/970",
- .oprofile_model = &op_model_power4,
-#endif
- },
- { /* Power5 */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x003a0000,
- .cpu_name = "POWER5 (gr)",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
- CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA | CPU_FTR_SMT |
- CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE |
- CPU_FTR_MMCRA_SIHV,
- .cpu_user_features = COMMON_USER_PPC64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 6,
- .cpu_setup = __setup_cpu_power4,
-#ifdef CONFIG_OPROFILE
- .oprofile_cpu_type = "ppc64/power5",
- .oprofile_model = &op_model_power4,
-#endif
- },
- { /* Power5 */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x003b0000,
- .cpu_name = "POWER5 (gs)",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
- CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA | CPU_FTR_SMT |
- CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE |
- CPU_FTR_MMCRA_SIHV,
- .cpu_user_features = COMMON_USER_PPC64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 6,
- .cpu_setup = __setup_cpu_power4,
-#ifdef CONFIG_OPROFILE
- .oprofile_cpu_type = "ppc64/power5",
- .oprofile_model = &op_model_power4,
-#endif
- },
- { /* BE DD1.x */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00700000,
- .cpu_name = "Broadband Engine",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
- CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
- CPU_FTR_SMT,
- .cpu_user_features = COMMON_USER_PPC64 |
- PPC_FEATURE_HAS_ALTIVEC_COMP,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .cpu_setup = __setup_cpu_be,
- },
- { /* default match */
- .pvr_mask = 0x00000000,
- .pvr_value = 0x00000000,
- .cpu_name = "POWER4 (compatible)",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
- CPU_FTR_PPCAS_ARCH_V2,
- .cpu_user_features = COMMON_USER_PPC64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 6,
- .cpu_setup = __setup_cpu_power4,
- }
-};
diff --git a/arch/ppc64/kernel/eeh.c b/arch/ppc64/kernel/eeh.c
index ba93fd731222..035d1b14a207 100644
--- a/arch/ppc64/kernel/eeh.c
+++ b/arch/ppc64/kernel/eeh.c
@@ -33,7 +33,7 @@
#include <asm/rtas.h>
#include <asm/atomic.h>
#include <asm/systemcfg.h>
-#include "pci.h"
+#include <asm/ppc-pci.h>
#undef DEBUG
diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S
index 72c61041151a..929f9f42cf7a 100644
--- a/arch/ppc64/kernel/head.S
+++ b/arch/ppc64/kernel/head.S
@@ -36,6 +36,7 @@
#include <asm/setup.h>
#include <asm/hvcall.h>
#include <asm/iSeries/LparMap.h>
+#include <asm/thread_info.h>
#ifdef CONFIG_PPC_ISERIES
#define DO_SOFT_DISABLE
@@ -80,7 +81,7 @@ _stext:
_GLOBAL(__start)
/* NOP this out unconditionally */
BEGIN_FTR_SECTION
- b .__start_initialization_multiplatform
+ b .__start_initialization_multiplatform
END_FTR_SECTION(0, 1)
#endif /* CONFIG_PPC_MULTIPLATFORM */
@@ -201,22 +202,22 @@ exception_marker:
#define EX_CCR 60
#define EXCEPTION_PROLOG_PSERIES(area, label) \
- mfspr r13,SPRG3; /* get paca address into r13 */ \
+ mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \
std r9,area+EX_R9(r13); /* save r9 - r12 */ \
std r10,area+EX_R10(r13); \
std r11,area+EX_R11(r13); \
std r12,area+EX_R12(r13); \
- mfspr r9,SPRG1; \
+ mfspr r9,SPRN_SPRG1; \
std r9,area+EX_R13(r13); \
mfcr r9; \
clrrdi r12,r13,32; /* get high part of &label */ \
mfmsr r10; \
- mfspr r11,SRR0; /* save SRR0 */ \
+ mfspr r11,SPRN_SRR0; /* save SRR0 */ \
ori r12,r12,(label)@l; /* virt addr of handler */ \
ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \
- mtspr SRR0,r12; \
- mfspr r12,SRR1; /* and SRR1 */ \
- mtspr SRR1,r10; \
+ mtspr SPRN_SRR0,r12; \
+ mfspr r12,SPRN_SRR1; /* and SRR1 */ \
+ mtspr SPRN_SRR1,r10; \
rfid; \
b . /* prevent speculative execution */
@@ -225,12 +226,12 @@ exception_marker:
* This code runs with relocation on.
*/
#define EXCEPTION_PROLOG_ISERIES_1(area) \
- mfspr r13,SPRG3; /* get paca address into r13 */ \
+ mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \
std r9,area+EX_R9(r13); /* save r9 - r12 */ \
std r10,area+EX_R10(r13); \
std r11,area+EX_R11(r13); \
std r12,area+EX_R12(r13); \
- mfspr r9,SPRG1; \
+ mfspr r9,SPRN_SPRG1; \
std r9,area+EX_R13(r13); \
mfcr r9
@@ -283,7 +284,7 @@ exception_marker:
std r9,_LINK(r1); \
mfctr r10; /* save CTR in stackframe */ \
std r10,_CTR(r1); \
- mfspr r11,XER; /* save XER in stackframe */ \
+ mfspr r11,SPRN_XER; /* save XER in stackframe */ \
std r11,_XER(r1); \
li r9,(n)+1; \
std r9,_TRAP(r1); /* set trap number */ \
@@ -300,7 +301,7 @@ exception_marker:
.globl label##_pSeries; \
label##_pSeries: \
HMT_MEDIUM; \
- mtspr SPRG1,r13; /* save r13 */ \
+ mtspr SPRN_SPRG1,r13; /* save r13 */ \
RUNLATCH_ON(r13); \
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
@@ -308,7 +309,7 @@ label##_pSeries: \
.globl label##_iSeries; \
label##_iSeries: \
HMT_MEDIUM; \
- mtspr SPRG1,r13; /* save r13 */ \
+ mtspr SPRN_SPRG1,r13; /* save r13 */ \
RUNLATCH_ON(r13); \
EXCEPTION_PROLOG_ISERIES_1(area); \
EXCEPTION_PROLOG_ISERIES_2; \
@@ -318,7 +319,7 @@ label##_iSeries: \
.globl label##_iSeries; \
label##_iSeries: \
HMT_MEDIUM; \
- mtspr SPRG1,r13; /* save r13 */ \
+ mtspr SPRN_SPRG1,r13; /* save r13 */ \
RUNLATCH_ON(r13); \
EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN); \
lbz r10,PACAPROCENABLED(r13); \
@@ -388,7 +389,7 @@ __start_interrupts:
. = 0x200
_machine_check_pSeries:
HMT_MEDIUM
- mtspr SPRG1,r13 /* save r13 */
+ mtspr SPRN_SPRG1,r13 /* save r13 */
RUNLATCH_ON(r13)
EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
@@ -396,18 +397,18 @@ _machine_check_pSeries:
.globl data_access_pSeries
data_access_pSeries:
HMT_MEDIUM
- mtspr SPRG1,r13
+ mtspr SPRN_SPRG1,r13
BEGIN_FTR_SECTION
- mtspr SPRG2,r12
- mfspr r13,DAR
- mfspr r12,DSISR
+ mtspr SPRN_SPRG2,r12
+ mfspr r13,SPRN_DAR
+ mfspr r12,SPRN_DSISR
srdi r13,r13,60
rlwimi r13,r12,16,0x20
mfcr r12
cmpwi r13,0x2c
beq .do_stab_bolted_pSeries
mtcrf 0x80,r12
- mfspr r12,SPRG2
+ mfspr r12,SPRN_SPRG2
END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common)
@@ -415,19 +416,19 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
.globl data_access_slb_pSeries
data_access_slb_pSeries:
HMT_MEDIUM
- mtspr SPRG1,r13
+ mtspr SPRN_SPRG1,r13
RUNLATCH_ON(r13)
- mfspr r13,SPRG3 /* get paca address into r13 */
+ mfspr r13,SPRN_SPRG3 /* get paca address into r13 */
std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */
std r10,PACA_EXSLB+EX_R10(r13)
std r11,PACA_EXSLB+EX_R11(r13)
std r12,PACA_EXSLB+EX_R12(r13)
std r3,PACA_EXSLB+EX_R3(r13)
- mfspr r9,SPRG1
+ mfspr r9,SPRN_SPRG1
std r9,PACA_EXSLB+EX_R13(r13)
mfcr r9
- mfspr r12,SRR1 /* and SRR1 */
- mfspr r3,DAR
+ mfspr r12,SPRN_SRR1 /* and SRR1 */
+ mfspr r3,SPRN_DAR
b .do_slb_miss /* Rel. branch works in real mode */
STD_EXCEPTION_PSERIES(0x400, instruction_access)
@@ -436,19 +437,19 @@ data_access_slb_pSeries:
.globl instruction_access_slb_pSeries
instruction_access_slb_pSeries:
HMT_MEDIUM
- mtspr SPRG1,r13
+ mtspr SPRN_SPRG1,r13
RUNLATCH_ON(r13)
- mfspr r13,SPRG3 /* get paca address into r13 */
+ mfspr r13,SPRN_SPRG3 /* get paca address into r13 */
std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */
std r10,PACA_EXSLB+EX_R10(r13)
std r11,PACA_EXSLB+EX_R11(r13)
std r12,PACA_EXSLB+EX_R12(r13)
std r3,PACA_EXSLB+EX_R3(r13)
- mfspr r9,SPRG1
+ mfspr r9,SPRN_SPRG1
std r9,PACA_EXSLB+EX_R13(r13)
mfcr r9
- mfspr r12,SRR1 /* and SRR1 */
- mfspr r3,SRR0 /* SRR0 is faulting address */
+ mfspr r12,SPRN_SRR1 /* and SRR1 */
+ mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */
b .do_slb_miss /* Rel. branch works in real mode */
STD_EXCEPTION_PSERIES(0x500, hardware_interrupt)
@@ -466,15 +467,15 @@ system_call_pSeries:
RUNLATCH_ON(r9)
mr r9,r13
mfmsr r10
- mfspr r13,SPRG3
- mfspr r11,SRR0
+ mfspr r13,SPRN_SPRG3
+ mfspr r11,SPRN_SRR0
clrrdi r12,r13,32
oris r12,r12,system_call_common@h
ori r12,r12,system_call_common@l
- mtspr SRR0,r12
+ mtspr SPRN_SRR0,r12
ori r10,r10,MSR_IR|MSR_DR|MSR_RI
- mfspr r12,SRR1
- mtspr SRR1,r10
+ mfspr r12,SPRN_SRR1
+ mtspr SPRN_SRR1,r10
rfid
b . /* prevent speculative execution */
@@ -504,25 +505,25 @@ system_call_pSeries:
.align 7
_GLOBAL(do_stab_bolted_pSeries)
mtcrf 0x80,r12
- mfspr r12,SPRG2
+ mfspr r12,SPRN_SPRG2
EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted)
/*
* Vectors for the FWNMI option. Share common code.
*/
- .globl system_reset_fwnmi
+ .globl system_reset_fwnmi
system_reset_fwnmi:
- HMT_MEDIUM
- mtspr SPRG1,r13 /* save r13 */
- RUNLATCH_ON(r13)
- EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
+ HMT_MEDIUM
+ mtspr SPRN_SPRG1,r13 /* save r13 */
+ RUNLATCH_ON(r13)
+ EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
- .globl machine_check_fwnmi
+ .globl machine_check_fwnmi
machine_check_fwnmi:
- HMT_MEDIUM
- mtspr SPRG1,r13 /* save r13 */
- RUNLATCH_ON(r13)
- EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
+ HMT_MEDIUM
+ mtspr SPRN_SPRG1,r13 /* save r13 */
+ RUNLATCH_ON(r13)
+ EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
#ifdef CONFIG_PPC_ISERIES
/*** ISeries-LPAR interrupt handlers ***/
@@ -531,18 +532,18 @@ machine_check_fwnmi:
.globl data_access_iSeries
data_access_iSeries:
- mtspr SPRG1,r13
+ mtspr SPRN_SPRG1,r13
BEGIN_FTR_SECTION
- mtspr SPRG2,r12
- mfspr r13,DAR
- mfspr r12,DSISR
+ mtspr SPRN_SPRG2,r12
+ mfspr r13,SPRN_DAR
+ mfspr r12,SPRN_DSISR
srdi r13,r13,60
rlwimi r13,r12,16,0x20
mfcr r12
cmpwi r13,0x2c
beq .do_stab_bolted_iSeries
mtcrf 0x80,r12
- mfspr r12,SPRG2
+ mfspr r12,SPRN_SPRG2
END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN)
EXCEPTION_PROLOG_ISERIES_2
@@ -550,25 +551,25 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
.do_stab_bolted_iSeries:
mtcrf 0x80,r12
- mfspr r12,SPRG2
+ mfspr r12,SPRN_SPRG2
EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
EXCEPTION_PROLOG_ISERIES_2
b .do_stab_bolted
.globl data_access_slb_iSeries
data_access_slb_iSeries:
- mtspr SPRG1,r13 /* save r13 */
+ mtspr SPRN_SPRG1,r13 /* save r13 */
EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
std r3,PACA_EXSLB+EX_R3(r13)
ld r12,PACALPPACA+LPPACASRR1(r13)
- mfspr r3,DAR
+ mfspr r3,SPRN_DAR
b .do_slb_miss
STD_EXCEPTION_ISERIES(0x400, instruction_access, PACA_EXGEN)
.globl instruction_access_slb_iSeries
instruction_access_slb_iSeries:
- mtspr SPRG1,r13 /* save r13 */
+ mtspr SPRN_SPRG1,r13 /* save r13 */
EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
std r3,PACA_EXSLB+EX_R3(r13)
ld r12,PACALPPACA+LPPACASRR1(r13)
@@ -586,7 +587,7 @@ instruction_access_slb_iSeries:
.globl system_call_iSeries
system_call_iSeries:
mr r9,r13
- mfspr r13,SPRG3
+ mfspr r13,SPRN_SPRG3
EXCEPTION_PROLOG_ISERIES_2
b system_call_common
@@ -596,7 +597,7 @@ system_call_iSeries:
.globl system_reset_iSeries
system_reset_iSeries:
- mfspr r13,SPRG3 /* Get paca address */
+ mfspr r13,SPRN_SPRG3 /* Get paca address */
mfmsr r24
ori r24,r24,MSR_RI
mtmsrd r24 /* RI on */
@@ -639,7 +640,7 @@ iSeries_secondary_smp_loop:
#endif /* CONFIG_SMP */
li r0,-1 /* r0=-1 indicates a Hypervisor call */
sc /* Invoke the hypervisor via a system call */
- mfspr r13,SPRG3 /* Put r13 back ???? */
+ mfspr r13,SPRN_SPRG3 /* Put r13 back ???? */
b 1b /* If SMP not configured, secondaries
* loop forever */
@@ -656,8 +657,8 @@ hardware_interrupt_iSeries_masked:
mtcrf 0x80,r9 /* Restore regs */
ld r11,PACALPPACA+LPPACASRR0(r13)
ld r12,PACALPPACA+LPPACASRR1(r13)
- mtspr SRR0,r11
- mtspr SRR1,r12
+ mtspr SPRN_SRR0,r11
+ mtspr SPRN_SRR1,r12
ld r9,PACA_EXGEN+EX_R9(r13)
ld r10,PACA_EXGEN+EX_R10(r13)
ld r11,PACA_EXGEN+EX_R11(r13)
@@ -713,8 +714,8 @@ bad_stack:
std r10,GPR1(r1)
std r11,_NIP(r1)
std r12,_MSR(r1)
- mfspr r11,DAR
- mfspr r12,DSISR
+ mfspr r11,SPRN_DAR
+ mfspr r12,SPRN_DSISR
std r11,_DAR(r1)
std r12,_DSISR(r1)
mflr r10
@@ -746,6 +747,7 @@ bad_stack:
* any task or sent any task a signal, you should use
* ret_from_except or ret_from_except_lite instead of this.
*/
+ .globl fast_exception_return
fast_exception_return:
ld r12,_MSR(r1)
ld r11,_NIP(r1)
@@ -766,8 +768,8 @@ fast_exception_return:
clrrdi r10,r10,2 /* clear RI (LE is 0 already) */
mtmsrd r10,1
- mtspr SRR1,r12
- mtspr SRR0,r11
+ mtspr SPRN_SRR1,r12
+ mtspr SPRN_SRR0,r11
REST_4GPRS(10, r1)
ld r1,GPR1(r1)
rfid
@@ -788,9 +790,9 @@ unrecov_fer:
.globl data_access_common
data_access_common:
RUNLATCH_ON(r10) /* It wont fit in the 0x300 handler */
- mfspr r10,DAR
+ mfspr r10,SPRN_DAR
std r10,PACA_EXGEN+EX_DAR(r13)
- mfspr r10,DSISR
+ mfspr r10,SPRN_DSISR
stw r10,PACA_EXGEN+EX_DSISR(r13)
EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN)
ld r3,PACA_EXGEN+EX_DAR(r13)
@@ -821,9 +823,9 @@ hardware_interrupt_entry:
.align 7
.globl alignment_common
alignment_common:
- mfspr r10,DAR
+ mfspr r10,SPRN_DAR
std r10,PACA_EXGEN+EX_DAR(r13)
- mfspr r10,DSISR
+ mfspr r10,SPRN_DSISR
stw r10,PACA_EXGEN+EX_DSISR(r13)
EXCEPTION_PROLOG_COMMON(0x600, PACA_EXGEN)
ld r3,PACA_EXGEN+EX_DAR(r13)
@@ -857,62 +859,6 @@ fp_unavailable_common:
bl .kernel_fp_unavailable_exception
BUG_OPCODE
-/*
- * load_up_fpu(unused, unused, tsk)
- * Disable FP for the task which had the FPU previously,
- * and save its floating-point registers in its thread_struct.
- * Enables the FPU for use in the kernel on return.
- * On SMP we know the fpu is free, since we give it up every
- * switch (ie, no lazy save of the FP registers).
- * On entry: r13 == 'current' && last_task_used_math != 'current'
- */
-_STATIC(load_up_fpu)
- mfmsr r5 /* grab the current MSR */
- ori r5,r5,MSR_FP
- mtmsrd r5 /* enable use of fpu now */
- isync
-/*
- * For SMP, we don't do lazy FPU switching because it just gets too
- * horrendously complex, especially when a task switches from one CPU
- * to another. Instead we call giveup_fpu in switch_to.
- *
- */
-#ifndef CONFIG_SMP
- ld r3,last_task_used_math@got(r2)
- ld r4,0(r3)
- cmpdi 0,r4,0
- beq 1f
- /* Save FP state to last_task_used_math's THREAD struct */
- addi r4,r4,THREAD
- SAVE_32FPRS(0, r4)
- mffs fr0
- stfd fr0,THREAD_FPSCR(r4)
- /* Disable FP for last_task_used_math */
- ld r5,PT_REGS(r4)
- ld r4,_MSR-STACK_FRAME_OVERHEAD(r5)
- li r6,MSR_FP|MSR_FE0|MSR_FE1
- andc r4,r4,r6
- std r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#endif /* CONFIG_SMP */
- /* enable use of FP after return */
- ld r4,PACACURRENT(r13)
- addi r5,r4,THREAD /* Get THREAD */
- ld r4,THREAD_FPEXC_MODE(r5)
- ori r12,r12,MSR_FP
- or r12,r12,r4
- std r12,_MSR(r1)
- lfd fr0,THREAD_FPSCR(r5)
- mtfsf 0xff,fr0
- REST_32FPRS(0, r5)
-#ifndef CONFIG_SMP
- /* Update last_task_used_math to 'current' */
- subi r4,r5,THREAD /* Back to 'current' */
- std r4,0(r3)
-#endif /* CONFIG_SMP */
- /* restore registers and return */
- b fast_exception_return
-
.align 7
.globl altivec_unavailable_common
altivec_unavailable_common:
@@ -1120,7 +1066,7 @@ _GLOBAL(do_stab_bolted)
/* Hash to the primary group */
ld r10,PACASTABVIRT(r13)
- mfspr r11,DAR
+ mfspr r11,SPRN_DAR
srdi r11,r11,28
rldimi r10,r11,7,52 /* r10 = first ste of the group */
@@ -1162,7 +1108,7 @@ _GLOBAL(do_stab_bolted)
2: std r9,8(r10) /* Store the vsid part of the ste */
eieio
- mfspr r11,DAR /* Get the new esid */
+ mfspr r11,SPRN_DAR /* Get the new esid */
clrrdi r11,r11,28 /* Permits a full 32b of ESID */
ori r11,r11,0x90 /* Turn on valid and kp */
std r11,0(r10) /* Put new entry back into the stab */
@@ -1182,8 +1128,8 @@ _GLOBAL(do_stab_bolted)
clrrdi r10,r10,2
mtmsrd r10,1
- mtspr SRR0,r11
- mtspr SRR1,r12
+ mtspr SPRN_SRR0,r11
+ mtspr SPRN_SRR1,r12
ld r9,PACA_EXSLB+EX_R9(r13)
ld r10,PACA_EXSLB+EX_R10(r13)
ld r11,PACA_EXSLB+EX_R11(r13)
@@ -1229,8 +1175,8 @@ _GLOBAL(do_slb_miss)
.machine pop
#ifdef CONFIG_PPC_ISERIES
- mtspr SRR0,r11
- mtspr SRR1,r12
+ mtspr SPRN_SRR0,r11
+ mtspr SPRN_SRR1,r12
#endif /* CONFIG_PPC_ISERIES */
ld r9,PACA_EXSLB+EX_R9(r13)
ld r10,PACA_EXSLB+EX_R10(r13)
@@ -1253,7 +1199,7 @@ unrecov_slb:
*
* On iSeries, the hypervisor must fill in at least one entry before
* we get control (with relocate on). The address is give to the hv
- * as a page number (see xLparMap in LparData.c), so this must be at a
+ * as a page number (see xLparMap in lpardata.c), so this must be at a
* fixed address (the linker can't compute (u64)&initial_stab >>
* PAGE_SHIFT).
*/
@@ -1316,7 +1262,7 @@ _GLOBAL(pSeries_secondary_smp_init)
mr r3,r24 /* not found, copy phys to r3 */
b .kexec_wait /* next kernel might do better */
-2: mtspr SPRG3,r13 /* Save vaddr of paca in SPRG3 */
+2: mtspr SPRN_SPRG3,r13 /* Save vaddr of paca in SPRG3 */
/* From now on, r24 is expected to be logical cpuid */
mr r24,r5
3: HMT_LOW
@@ -1364,6 +1310,7 @@ _STATIC(__start_initialization_iSeries)
addi r2,r2,0x4000
bl .iSeries_early_setup
+ bl .early_setup
/* relocation is on at this point */
@@ -1554,20 +1501,17 @@ copy_to_here:
.section ".text";
.align 2 ;
- .globl pmac_secondary_start_1
-pmac_secondary_start_1:
- li r24, 1
- b .pmac_secondary_start
-
- .globl pmac_secondary_start_2
-pmac_secondary_start_2:
- li r24, 2
- b .pmac_secondary_start
-
- .globl pmac_secondary_start_3
-pmac_secondary_start_3:
- li r24, 3
- b .pmac_secondary_start
+ .globl __secondary_start_pmac_0
+__secondary_start_pmac_0:
+ /* NB the entries for cpus 0, 1, 2 must each occupy 8 bytes. */
+ li r24,0
+ b 1f
+ li r24,1
+ b 1f
+ li r24,2
+ b 1f
+ li r24,3
+1:
_GLOBAL(pmac_secondary_start)
/* turn on 64-bit mode */
@@ -1586,7 +1530,7 @@ _GLOBAL(pmac_secondary_start)
LOADADDR(r4, paca) /* Get base vaddr of paca array */
mulli r13,r24,PACA_SIZE /* Calculate vaddr of right paca */
add r13,r13,r4 /* for this processor. */
- mtspr SPRG3,r13 /* Save vaddr of paca in SPRG3 */
+ mtspr SPRN_SPRG3,r13 /* Save vaddr of paca in SPRG3 */
/* Create a temp kernel stack for use before relocation is on. */
ld r1,PACAEMERGSP(r13)
@@ -1621,7 +1565,7 @@ _GLOBAL(__secondary_start)
/* Initialize the page table pointer register. */
LOADADDR(r6,_SDR1)
ld r6,0(r6) /* get the value of _SDR1 */
- mtspr SDR1,r6 /* set the htab location */
+ mtspr SPRN_SDR1,r6 /* set the htab location */
#endif
/* Initialize the first segment table (or SLB) entry */
ld r3,PACASTABVIRT(r13) /* get addr of segment table */
@@ -1650,7 +1594,7 @@ _GLOBAL(__secondary_start)
lwz r3,PLATFORM(r3) /* r3 = platform flags */
andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */
beq 98f /* branch if result is 0 */
- mfspr r3,PVR
+ mfspr r3,SPRN_PVR
srwi r3,r3,16
cmpwi r3,0x37 /* SStar */
beq 97f
@@ -1674,8 +1618,8 @@ _GLOBAL(__secondary_start)
#ifdef DO_SOFT_DISABLE
ori r4,r4,MSR_EE
#endif
- mtspr SRR0,r3
- mtspr SRR1,r4
+ mtspr SPRN_SRR0,r3
+ mtspr SPRN_SRR1,r4
rfid
b . /* prevent speculative execution */
@@ -1737,7 +1681,7 @@ _STATIC(start_here_multiplatform)
#ifdef CONFIG_HMT
/* Start up the second thread on cpu 0 */
- mfspr r3,PVR
+ mfspr r3,SPRN_PVR
srwi r3,r3,16
cmpwi r3,0x34 /* Pulsar */
beq 90f
@@ -1797,7 +1741,7 @@ _STATIC(start_here_multiplatform)
mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */
add r13,r13,r24 /* for this processor. */
sub r13,r13,r26 /* convert to physical addr */
- mtspr SPRG3,r13 /* PPPBBB: Temp... -Peter */
+ mtspr SPRN_SPRG3,r13 /* PPPBBB: Temp... -Peter */
/* Do very early kernel initializations, including initial hash table,
* stab and slb setup before we turn on relocation. */
@@ -1814,7 +1758,7 @@ _STATIC(start_here_multiplatform)
lwz r3,PLATFORM(r3) /* r3 = platform flags */
andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */
beq 98f /* branch if result is 0 */
- mfspr r3,PVR
+ mfspr r3,SPRN_PVR
srwi r3,r3,16
cmpwi r3,0x37 /* SStar */
beq 97f
@@ -1838,12 +1782,12 @@ _STATIC(start_here_multiplatform)
LOADADDR(r6,_SDR1) /* Only if NOT LPAR */
sub r6,r6,r26
ld r6,0(r6) /* get the value of _SDR1 */
- mtspr SDR1,r6 /* set the htab location */
+ mtspr SPRN_SDR1,r6 /* set the htab location */
98:
LOADADDR(r3,.start_here_common)
SET_REG_TO_CONST(r4, MSR_KERNEL)
- mtspr SRR0,r3
- mtspr SRR1,r4
+ mtspr SPRN_SRR0,r3
+ mtspr SPRN_SRR1,r4
rfid
b . /* prevent speculative execution */
#endif /* CONFIG_PPC_MULTIPLATFORM */
@@ -1874,7 +1818,7 @@ _STATIC(start_here_common)
LOADADDR(r24, paca) /* Get base vaddr of paca array */
mulli r13,r26,PACA_SIZE /* Calculate vaddr of right paca */
add r13,r13,r24 /* for this processor. */
- mtspr SPRG3,r13
+ mtspr SPRN_SPRG3,r13
/* ptr to current */
LOADADDR(r4,init_task)
@@ -1901,7 +1845,7 @@ _STATIC(start_here_common)
_GLOBAL(hmt_init)
#ifdef CONFIG_HMT
LOADADDR(r5, hmt_thread_data)
- mfspr r7,PVR
+ mfspr r7,SPRN_PVR
srwi r7,r7,16
cmpwi r7,0x34 /* Pulsar */
beq 90f
@@ -1910,10 +1854,10 @@ _GLOBAL(hmt_init)
cmpwi r7,0x37 /* SStar */
beq 91f
b 101f
-90: mfspr r6,PIR
+90: mfspr r6,SPRN_PIR
andi. r6,r6,0x1f
b 92f
-91: mfspr r6,PIR
+91: mfspr r6,SPRN_PIR
andi. r6,r6,0x3ff
92: sldi r4,r24,3
stwx r6,r5,r4
@@ -1924,8 +1868,8 @@ __hmt_secondary_hold:
LOADADDR(r5, hmt_thread_data)
clrldi r5,r5,4
li r7,0
- mfspr r6,PIR
- mfspr r8,PVR
+ mfspr r6,SPRN_PIR
+ mfspr r8,SPRN_PVR
srwi r8,r8,16
cmpwi r8,0x34
bne 93f
@@ -1951,39 +1895,41 @@ __hmt_secondary_hold:
_GLOBAL(hmt_start_secondary)
LOADADDR(r4,__hmt_secondary_hold)
clrldi r4,r4,4
- mtspr NIADORM, r4
- mfspr r4, MSRDORM
+ mtspr SPRN_NIADORM, r4
+ mfspr r4, SPRN_MSRDORM
li r5, -65
and r4, r4, r5
- mtspr MSRDORM, r4
+ mtspr SPRN_MSRDORM, r4
lis r4,0xffef
ori r4,r4,0x7403
- mtspr TSC, r4
+ mtspr SPRN_TSC, r4
li r4,0x1f4
- mtspr TST, r4
- mfspr r4, HID0
+ mtspr SPRN_TST, r4
+ mfspr r4, SPRN_HID0
ori r4, r4, 0x1
- mtspr HID0, r4
+ mtspr SPRN_HID0, r4
mfspr r4, SPRN_CTRLF
oris r4, r4, 0x40
mtspr SPRN_CTRLT, r4
blr
#endif
-#if defined(CONFIG_KEXEC) || (defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES))
+#if defined(CONFIG_KEXEC) || defined(CONFIG_SMP)
_GLOBAL(smp_release_cpus)
/* All secondary cpus are spinning on a common
* spinloop, release them all now so they can start
* to spin on their individual paca spinloops.
* For non SMP kernels, the secondary cpus never
* get out of the common spinloop.
+ * XXX This does nothing useful on iSeries, secondaries are
+ * already waiting on their paca.
*/
li r3,1
LOADADDR(r5,__secondary_hold_spinloop)
std r3,0(r5)
sync
blr
-#endif /* CONFIG_SMP && !CONFIG_PPC_ISERIES */
+#endif /* CONFIG_SMP */
/*
@@ -1992,7 +1938,7 @@ _GLOBAL(smp_release_cpus)
*/
.section ".bss"
- .align 12
+ .align PAGE_SHIFT
.globl empty_zero_page
empty_zero_page:
diff --git a/arch/ppc64/kernel/hvcserver.c b/arch/ppc64/kernel/hvcserver.c
index bde8f42da854..4d584172055a 100644
--- a/arch/ppc64/kernel/hvcserver.c
+++ b/arch/ppc64/kernel/hvcserver.c
@@ -22,6 +22,8 @@
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
+#include <linux/slab.h>
+
#include <asm/hvcall.h>
#include <asm/hvcserver.h>
#include <asm/io.h>
diff --git a/arch/ppc64/kernel/i8259.c b/arch/ppc64/kernel/i8259.c
deleted file mode 100644
index 74dcfd68fc75..000000000000
--- a/arch/ppc64/kernel/i8259.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * c 2001 PPC64 Team, IBM Corp
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#include <linux/stddef.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/signal.h>
-#include <linux/cache.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>
-#include <asm/io.h>
-#include <asm/ppcdebug.h>
-#include "i8259.h"
-
-unsigned char cached_8259[2] = { 0xff, 0xff };
-#define cached_A1 (cached_8259[0])
-#define cached_21 (cached_8259[1])
-
-static __cacheline_aligned_in_smp DEFINE_SPINLOCK(i8259_lock);
-
-static int i8259_pic_irq_offset;
-static int i8259_present;
-
-int i8259_irq(int cpu)
-{
- int irq;
-
- spin_lock/*_irqsave*/(&i8259_lock/*, flags*/);
- /*
- * Perform an interrupt acknowledge cycle on controller 1
- */
- outb(0x0C, 0x20);
- irq = inb(0x20) & 7;
- if (irq == 2)
- {
- /*
- * Interrupt is cascaded so perform interrupt
- * acknowledge on controller 2
- */
- outb(0x0C, 0xA0);
- irq = (inb(0xA0) & 7) + 8;
- }
- else if (irq==7)
- {
- /*
- * This may be a spurious interrupt
- *
- * Read the interrupt status register. If the most
- * significant bit is not set then there is no valid
- * interrupt
- */
- outb(0x0b, 0x20);
- if(~inb(0x20)&0x80) {
- spin_unlock/*_irqrestore*/(&i8259_lock/*, flags*/);
- return -1;
- }
- }
- spin_unlock/*_irqrestore*/(&i8259_lock/*, flags*/);
- return irq;
-}
-
-static void i8259_mask_and_ack_irq(unsigned int irq_nr)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&i8259_lock, flags);
- if ( irq_nr >= i8259_pic_irq_offset )
- irq_nr -= i8259_pic_irq_offset;
-
- if (irq_nr > 7) {
- cached_A1 |= 1 << (irq_nr-8);
- inb(0xA1); /* DUMMY */
- outb(cached_A1,0xA1);
- outb(0x20,0xA0); /* Non-specific EOI */
- outb(0x20,0x20); /* Non-specific EOI to cascade */
- } else {
- cached_21 |= 1 << irq_nr;
- inb(0x21); /* DUMMY */
- outb(cached_21,0x21);
- outb(0x20,0x20); /* Non-specific EOI */
- }
- spin_unlock_irqrestore(&i8259_lock, flags);
-}
-
-static void i8259_set_irq_mask(int irq_nr)
-{
- outb(cached_A1,0xA1);
- outb(cached_21,0x21);
-}
-
-static void i8259_mask_irq(unsigned int irq_nr)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&i8259_lock, flags);
- if ( irq_nr >= i8259_pic_irq_offset )
- irq_nr -= i8259_pic_irq_offset;
- if ( irq_nr < 8 )
- cached_21 |= 1 << irq_nr;
- else
- cached_A1 |= 1 << (irq_nr-8);
- i8259_set_irq_mask(irq_nr);
- spin_unlock_irqrestore(&i8259_lock, flags);
-}
-
-static void i8259_unmask_irq(unsigned int irq_nr)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&i8259_lock, flags);
- if ( irq_nr >= i8259_pic_irq_offset )
- irq_nr -= i8259_pic_irq_offset;
- if ( irq_nr < 8 )
- cached_21 &= ~(1 << irq_nr);
- else
- cached_A1 &= ~(1 << (irq_nr-8));
- i8259_set_irq_mask(irq_nr);
- spin_unlock_irqrestore(&i8259_lock, flags);
-}
-
-static void i8259_end_irq(unsigned int irq)
-{
- if (!(get_irq_desc(irq)->status & (IRQ_DISABLED|IRQ_INPROGRESS)) &&
- get_irq_desc(irq)->action)
- i8259_unmask_irq(irq);
-}
-
-struct hw_interrupt_type i8259_pic = {
- .typename = " i8259 ",
- .enable = i8259_unmask_irq,
- .disable = i8259_mask_irq,
- .ack = i8259_mask_and_ack_irq,
- .end = i8259_end_irq,
-};
-
-void __init i8259_init(int offset)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&i8259_lock, flags);
- i8259_pic_irq_offset = offset;
- i8259_present = 1;
- /* init master interrupt controller */
- outb(0x11, 0x20); /* Start init sequence */
- outb(0x00, 0x21); /* Vector base */
- outb(0x04, 0x21); /* edge tiggered, Cascade (slave) on IRQ2 */
- outb(0x01, 0x21); /* Select 8086 mode */
- outb(0xFF, 0x21); /* Mask all */
- /* init slave interrupt controller */
- outb(0x11, 0xA0); /* Start init sequence */
- outb(0x08, 0xA1); /* Vector base */
- outb(0x02, 0xA1); /* edge triggered, Cascade (slave) on IRQ2 */
- outb(0x01, 0xA1); /* Select 8086 mode */
- outb(0xFF, 0xA1); /* Mask all */
- outb(cached_A1, 0xA1);
- outb(cached_21, 0x21);
- spin_unlock_irqrestore(&i8259_lock, flags);
-
-}
-
-static int i8259_request_cascade(void)
-{
- if (!i8259_present)
- return -ENODEV;
-
- request_irq( i8259_pic_irq_offset + 2, no_action, SA_INTERRUPT,
- "82c59 secondary cascade", NULL );
-
- return 0;
-}
-
-arch_initcall(i8259_request_cascade);
diff --git a/arch/ppc64/kernel/i8259.h b/arch/ppc64/kernel/i8259.h
deleted file mode 100644
index f74764ba0bfa..000000000000
--- a/arch/ppc64/kernel/i8259.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * c 2001 PPC 64 Team, IBM Corp
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#ifndef _PPC_KERNEL_i8259_H
-#define _PPC_KERNEL_i8259_H
-
-extern struct hw_interrupt_type i8259_pic;
-
-extern void i8259_init(int offset);
-extern int i8259_irq(int);
-
-#endif /* _PPC_KERNEL_i8259_H */
diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c
index 954395d42636..8abd2ad92832 100644
--- a/arch/ppc64/kernel/idle.c
+++ b/arch/ppc64/kernel/idle.c
@@ -31,7 +31,7 @@
extern void power4_idle(void);
-int default_idle(void)
+void default_idle(void)
{
long oldval;
unsigned int cpu = smp_processor_id();
@@ -64,11 +64,9 @@ int default_idle(void)
if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
cpu_die();
}
-
- return 0;
}
-int native_idle(void)
+void native_idle(void)
{
while (1) {
ppc64_runlatch_off();
@@ -85,8 +83,6 @@ int native_idle(void)
system_state == SYSTEM_RUNNING)
cpu_die();
}
-
- return 0;
}
void cpu_idle(void)
diff --git a/arch/ppc64/kernel/ioctl32.c b/arch/ppc64/kernel/ioctl32.c
index a8005db23ec5..ba4a899045c2 100644
--- a/arch/ppc64/kernel/ioctl32.c
+++ b/arch/ppc64/kernel/ioctl32.c
@@ -39,9 +39,7 @@ IOCTL_TABLE_START
#include <linux/compat_ioctl.h>
#define DECLARES
#include "compat_ioctl.c"
-COMPATIBLE_IOCTL(TIOCSTART)
-COMPATIBLE_IOCTL(TIOCSTOP)
-COMPATIBLE_IOCTL(TIOCSLTC)
+
/* Little p (/dev/rtc, /dev/envctrl, etc.) */
COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */
COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */
diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c
index 9c6facc24f70..ed876a5178ae 100644
--- a/arch/ppc64/kernel/kprobes.c
+++ b/arch/ppc64/kernel/kprobes.c
@@ -395,7 +395,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
if (post_kprobe_handler(args->regs))
ret = NOTIFY_STOP;
break;
- case DIE_GPF:
case DIE_PAGE_FAULT:
if (kprobe_running() &&
kprobe_fault_handler(args->regs, args->trapnr))
diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S
index e7241ad80a08..077507ffbab8 100644
--- a/arch/ppc64/kernel/misc.S
+++ b/arch/ppc64/kernel/misc.S
@@ -28,6 +28,7 @@
#include <asm/ppc_asm.h>
#include <asm/asm-offsets.h>
#include <asm/cputable.h>
+#include <asm/thread_info.h>
.text
@@ -64,44 +65,6 @@ _GLOBAL(get_srr1)
_GLOBAL(get_sp)
mr r3,r1
blr
-
-#ifdef CONFIG_PPC_ISERIES
-/* unsigned long local_save_flags(void) */
-_GLOBAL(local_get_flags)
- lbz r3,PACAPROCENABLED(r13)
- blr
-
-/* unsigned long local_irq_disable(void) */
-_GLOBAL(local_irq_disable)
- lbz r3,PACAPROCENABLED(r13)
- li r4,0
- stb r4,PACAPROCENABLED(r13)
- blr /* Done */
-
-/* void local_irq_restore(unsigned long flags) */
-_GLOBAL(local_irq_restore)
- lbz r5,PACAPROCENABLED(r13)
- /* Check if things are setup the way we want _already_. */
- cmpw 0,r3,r5
- beqlr
- /* are we enabling interrupts? */
- cmpdi 0,r3,0
- stb r3,PACAPROCENABLED(r13)
- beqlr
- /* Check pending interrupts */
- /* A decrementer, IPI or PMC interrupt may have occurred
- * while we were in the hypervisor (which enables) */
- ld r4,PACALPPACA+LPPACAANYINT(r13)
- cmpdi r4,0
- beqlr
-
- /*
- * Handle pending interrupts in interrupt context
- */
- li r0,0x5555
- sc
- blr
-#endif /* CONFIG_PPC_ISERIES */
#ifdef CONFIG_IRQSTACKS
_GLOBAL(call_do_softirq)
@@ -329,7 +292,7 @@ _GLOBAL(__flush_dcache_icache)
/* Flush the dcache */
ld r7,PPC64_CACHES@toc(r2)
- clrrdi r3,r3,12 /* Page align */
+ clrrdi r3,r3,PAGE_SHIFT /* Page align */
lwz r4,DCACHEL1LINESPERPAGE(r7) /* Get # dcache lines per page */
lwz r5,DCACHEL1LINESIZE(r7) /* Get dcache line size */
mr r6,r3
@@ -488,25 +451,6 @@ _GLOBAL(_outsl_ns)
sync
blr
-
-_GLOBAL(cvt_fd)
- lfd 0,0(r5) /* load up fpscr value */
- mtfsf 0xff,0
- lfs 0,0(r3)
- stfd 0,0(r4)
- mffs 0 /* save new fpscr value */
- stfd 0,0(r5)
- blr
-
-_GLOBAL(cvt_df)
- lfd 0,0(r5) /* load up fpscr value */
- mtfsf 0xff,0
- lfd 0,0(r3)
- stfs 0,0(r4)
- mffs 0 /* save new fpscr value */
- stfd 0,0(r5)
- blr
-
/*
* identify_cpu and calls setup_cpu
* In: r3 = base of the cpu_specs array
@@ -692,38 +636,6 @@ _GLOBAL(disable_kernel_fp)
isync
blr
-/*
- * giveup_fpu(tsk)
- * Disable FP for the task given as the argument,
- * and save the floating-point registers in its thread_struct.
- * Enables the FPU for use in the kernel on return.
- */
-_GLOBAL(giveup_fpu)
- mfmsr r5
- ori r5,r5,MSR_FP
- mtmsrd r5 /* enable use of fpu now */
- isync
- cmpdi 0,r3,0
- beqlr- /* if no previous owner, done */
- addi r3,r3,THREAD /* want THREAD of task */
- ld r5,PT_REGS(r3)
- cmpdi 0,r5,0
- SAVE_32FPRS(0, r3)
- mffs fr0
- stfd fr0,THREAD_FPSCR(r3)
- beq 1f
- ld r4,_MSR-STACK_FRAME_OVERHEAD(r5)
- li r3,MSR_FP|MSR_FE0|MSR_FE1
- andc r4,r4,r3 /* disable FP for previous task */
- std r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#ifndef CONFIG_SMP
- li r5,0
- ld r4,last_task_used_math@got(r2)
- std r5,0(r4)
-#endif /* CONFIG_SMP */
- blr
-
#ifdef CONFIG_ALTIVEC
#if 0 /* this has no callers for now */
@@ -778,6 +690,13 @@ _GLOBAL(giveup_altivec)
_GLOBAL(__setup_cpu_power3)
blr
+_GLOBAL(execve)
+ li r0,__NR_execve
+ sc
+ bnslr
+ neg r3,r3
+ blr
+
/* kexec_wait(phys_cpu)
*
* wait for the flag to change, indicating this kernel is going away but
@@ -948,566 +867,3 @@ _GLOBAL(kexec_sequence)
li r5,0
blr /* image->start(physid, image->start, 0); */
#endif /* CONFIG_KEXEC */
-
-/* Why isn't this a) automatic, b) written in 'C'? */
- .balign 8
-_GLOBAL(sys_call_table32)
- .llong .sys_restart_syscall /* 0 */
- .llong .sys_exit
- .llong .ppc_fork
- .llong .sys_read
- .llong .sys_write
- .llong .compat_sys_open /* 5 */
- .llong .sys_close
- .llong .sys32_waitpid
- .llong .sys32_creat
- .llong .sys_link
- .llong .sys_unlink /* 10 */
- .llong .sys32_execve
- .llong .sys_chdir
- .llong .compat_sys_time
- .llong .sys_mknod
- .llong .sys_chmod /* 15 */
- .llong .sys_lchown
- .llong .sys_ni_syscall /* old break syscall */
- .llong .sys_ni_syscall /* old stat syscall */
- .llong .ppc32_lseek
- .llong .sys_getpid /* 20 */
- .llong .compat_sys_mount
- .llong .sys_oldumount
- .llong .sys_setuid
- .llong .sys_getuid
- .llong .compat_sys_stime /* 25 */
- .llong .sys32_ptrace
- .llong .sys_alarm
- .llong .sys_ni_syscall /* old fstat syscall */
- .llong .sys32_pause
- .llong .compat_sys_utime /* 30 */
- .llong .sys_ni_syscall /* old stty syscall */
- .llong .sys_ni_syscall /* old gtty syscall */
- .llong .sys32_access
- .llong .sys32_nice
- .llong .sys_ni_syscall /* 35 - old ftime syscall */
- .llong .sys_sync
- .llong .sys32_kill
- .llong .sys_rename
- .llong .sys32_mkdir
- .llong .sys_rmdir /* 40 */
- .llong .sys_dup
- .llong .sys_pipe
- .llong .compat_sys_times
- .llong .sys_ni_syscall /* old prof syscall */
- .llong .sys_brk /* 45 */
- .llong .sys_setgid
- .llong .sys_getgid
- .llong .sys_signal
- .llong .sys_geteuid
- .llong .sys_getegid /* 50 */
- .llong .sys_acct
- .llong .sys_umount
- .llong .sys_ni_syscall /* old lock syscall */
- .llong .compat_sys_ioctl
- .llong .compat_sys_fcntl /* 55 */
- .llong .sys_ni_syscall /* old mpx syscall */
- .llong .sys32_setpgid
- .llong .sys_ni_syscall /* old ulimit syscall */
- .llong .sys32_olduname
- .llong .sys32_umask /* 60 */
- .llong .sys_chroot
- .llong .sys_ustat
- .llong .sys_dup2
- .llong .sys_getppid
- .llong .sys_getpgrp /* 65 */
- .llong .sys_setsid
- .llong .sys32_sigaction
- .llong .sys_sgetmask
- .llong .sys32_ssetmask
- .llong .sys_setreuid /* 70 */
- .llong .sys_setregid
- .llong .ppc32_sigsuspend
- .llong .compat_sys_sigpending
- .llong .sys32_sethostname
- .llong .compat_sys_setrlimit /* 75 */
- .llong .compat_sys_old_getrlimit
- .llong .compat_sys_getrusage
- .llong .sys32_gettimeofday
- .llong .sys32_settimeofday
- .llong .sys32_getgroups /* 80 */
- .llong .sys32_setgroups
- .llong .sys_ni_syscall /* old select syscall */
- .llong .sys_symlink
- .llong .sys_ni_syscall /* old lstat syscall */
- .llong .sys32_readlink /* 85 */
- .llong .sys_uselib
- .llong .sys_swapon
- .llong .sys_reboot
- .llong .old32_readdir
- .llong .sys_mmap /* 90 */
- .llong .sys_munmap
- .llong .sys_truncate
- .llong .sys_ftruncate
- .llong .sys_fchmod
- .llong .sys_fchown /* 95 */
- .llong .sys32_getpriority
- .llong .sys32_setpriority
- .llong .sys_ni_syscall /* old profil syscall */
- .llong .compat_sys_statfs
- .llong .compat_sys_fstatfs /* 100 */
- .llong .sys_ni_syscall /* old ioperm syscall */
- .llong .compat_sys_socketcall
- .llong .sys32_syslog
- .llong .compat_sys_setitimer
- .llong .compat_sys_getitimer /* 105 */
- .llong .compat_sys_newstat
- .llong .compat_sys_newlstat
- .llong .compat_sys_newfstat
- .llong .sys32_uname
- .llong .sys_ni_syscall /* 110 old iopl syscall */
- .llong .sys_vhangup
- .llong .sys_ni_syscall /* old idle syscall */
- .llong .sys_ni_syscall /* old vm86 syscall */
- .llong .compat_sys_wait4
- .llong .sys_swapoff /* 115 */
- .llong .sys32_sysinfo
- .llong .sys32_ipc
- .llong .sys_fsync
- .llong .ppc32_sigreturn
- .llong .ppc_clone /* 120 */
- .llong .sys32_setdomainname
- .llong .ppc64_newuname
- .llong .sys_ni_syscall /* old modify_ldt syscall */
- .llong .sys32_adjtimex
- .llong .sys_mprotect /* 125 */
- .llong .compat_sys_sigprocmask
- .llong .sys_ni_syscall /* old create_module syscall */
- .llong .sys_init_module
- .llong .sys_delete_module
- .llong .sys_ni_syscall /* 130 old get_kernel_syms syscall */
- .llong .sys_quotactl
- .llong .sys32_getpgid
- .llong .sys_fchdir
- .llong .sys_bdflush
- .llong .sys32_sysfs /* 135 */
- .llong .ppc64_personality
- .llong .sys_ni_syscall /* for afs_syscall */
- .llong .sys_setfsuid
- .llong .sys_setfsgid
- .llong .sys_llseek /* 140 */
- .llong .sys32_getdents
- .llong .ppc32_select
- .llong .sys_flock
- .llong .sys_msync
- .llong .compat_sys_readv /* 145 */
- .llong .compat_sys_writev
- .llong .sys32_getsid
- .llong .sys_fdatasync
- .llong .sys32_sysctl
- .llong .sys_mlock /* 150 */
- .llong .sys_munlock
- .llong .sys_mlockall
- .llong .sys_munlockall
- .llong .sys32_sched_setparam
- .llong .sys32_sched_getparam /* 155 */
- .llong .sys32_sched_setscheduler
- .llong .sys32_sched_getscheduler
- .llong .sys_sched_yield
- .llong .sys32_sched_get_priority_max
- .llong .sys32_sched_get_priority_min /* 160 */
- .llong .sys32_sched_rr_get_interval
- .llong .compat_sys_nanosleep
- .llong .sys_mremap
- .llong .sys_setresuid
- .llong .sys_getresuid /* 165 */
- .llong .sys_ni_syscall /* old query_module syscall */
- .llong .sys_poll
- .llong .compat_sys_nfsservctl
- .llong .sys_setresgid
- .llong .sys_getresgid /* 170 */
- .llong .sys32_prctl
- .llong .ppc32_rt_sigreturn
- .llong .sys32_rt_sigaction
- .llong .sys32_rt_sigprocmask
- .llong .sys32_rt_sigpending /* 175 */
- .llong .compat_sys_rt_sigtimedwait
- .llong .sys32_rt_sigqueueinfo
- .llong .ppc32_rt_sigsuspend
- .llong .sys32_pread64
- .llong .sys32_pwrite64 /* 180 */
- .llong .sys_chown
- .llong .sys_getcwd
- .llong .sys_capget
- .llong .sys_capset
- .llong .sys32_sigaltstack /* 185 */
- .llong .sys32_sendfile
- .llong .sys_ni_syscall /* reserved for streams1 */
- .llong .sys_ni_syscall /* reserved for streams2 */
- .llong .ppc_vfork
- .llong .compat_sys_getrlimit /* 190 */
- .llong .sys32_readahead
- .llong .sys32_mmap2
- .llong .sys32_truncate64
- .llong .sys32_ftruncate64
- .llong .sys_stat64 /* 195 */
- .llong .sys_lstat64
- .llong .sys_fstat64
- .llong .sys32_pciconfig_read
- .llong .sys32_pciconfig_write
- .llong .sys32_pciconfig_iobase /* 200 - pciconfig_iobase */
- .llong .sys_ni_syscall /* reserved for MacOnLinux */
- .llong .sys_getdents64
- .llong .sys_pivot_root
- .llong .compat_sys_fcntl64
- .llong .sys_madvise /* 205 */
- .llong .sys_mincore
- .llong .sys_gettid
- .llong .sys_tkill
- .llong .sys_setxattr
- .llong .sys_lsetxattr /* 210 */
- .llong .sys_fsetxattr
- .llong .sys_getxattr
- .llong .sys_lgetxattr
- .llong .sys_fgetxattr
- .llong .sys_listxattr /* 215 */
- .llong .sys_llistxattr
- .llong .sys_flistxattr
- .llong .sys_removexattr
- .llong .sys_lremovexattr
- .llong .sys_fremovexattr /* 220 */
- .llong .compat_sys_futex
- .llong .compat_sys_sched_setaffinity
- .llong .compat_sys_sched_getaffinity
- .llong .sys_ni_syscall
- .llong .sys_ni_syscall /* 225 - reserved for tux */
- .llong .sys32_sendfile64
- .llong .compat_sys_io_setup
- .llong .sys_io_destroy
- .llong .compat_sys_io_getevents
- .llong .compat_sys_io_submit
- .llong .sys_io_cancel
- .llong .sys_set_tid_address
- .llong .ppc32_fadvise64
- .llong .sys_exit_group
- .llong .ppc32_lookup_dcookie /* 235 */
- .llong .sys_epoll_create
- .llong .sys_epoll_ctl
- .llong .sys_epoll_wait
- .llong .sys_remap_file_pages
- .llong .ppc32_timer_create /* 240 */
- .llong .compat_sys_timer_settime
- .llong .compat_sys_timer_gettime
- .llong .sys_timer_getoverrun
- .llong .sys_timer_delete
- .llong .compat_sys_clock_settime /* 245 */
- .llong .compat_sys_clock_gettime
- .llong .compat_sys_clock_getres
- .llong .compat_sys_clock_nanosleep
- .llong .ppc32_swapcontext
- .llong .sys32_tgkill /* 250 */
- .llong .sys32_utimes
- .llong .compat_sys_statfs64
- .llong .compat_sys_fstatfs64
- .llong .ppc32_fadvise64_64 /* 32bit only fadvise64_64 */
- .llong .ppc_rtas /* 255 */
- .llong .sys_ni_syscall /* 256 reserved for sys_debug_setcontext */
- .llong .sys_ni_syscall /* 257 reserved for vserver */
- .llong .sys_ni_syscall /* 258 reserved for new sys_remap_file_pages */
- .llong .compat_sys_mbind
- .llong .compat_sys_get_mempolicy /* 260 */
- .llong .compat_sys_set_mempolicy
- .llong .compat_sys_mq_open
- .llong .sys_mq_unlink
- .llong .compat_sys_mq_timedsend
- .llong .compat_sys_mq_timedreceive /* 265 */
- .llong .compat_sys_mq_notify
- .llong .compat_sys_mq_getsetattr
- .llong .compat_sys_kexec_load
- .llong .sys32_add_key
- .llong .sys32_request_key /* 270 */
- .llong .compat_sys_keyctl
- .llong .compat_sys_waitid
- .llong .sys32_ioprio_set
- .llong .sys32_ioprio_get
- .llong .sys_inotify_init /* 275 */
- .llong .sys_inotify_add_watch
- .llong .sys_inotify_rm_watch
-
- .balign 8
-_GLOBAL(sys_call_table)
- .llong .sys_restart_syscall /* 0 */
- .llong .sys_exit
- .llong .ppc_fork
- .llong .sys_read
- .llong .sys_write
- .llong .sys_open /* 5 */
- .llong .sys_close
- .llong .sys_waitpid
- .llong .sys_creat
- .llong .sys_link
- .llong .sys_unlink /* 10 */
- .llong .sys_execve
- .llong .sys_chdir
- .llong .sys64_time
- .llong .sys_mknod
- .llong .sys_chmod /* 15 */
- .llong .sys_lchown
- .llong .sys_ni_syscall /* old break syscall */
- .llong .sys_ni_syscall /* old stat syscall */
- .llong .sys_lseek
- .llong .sys_getpid /* 20 */
- .llong .sys_mount
- .llong .sys_ni_syscall /* old umount syscall */
- .llong .sys_setuid
- .llong .sys_getuid
- .llong .sys_stime /* 25 */
- .llong .sys_ptrace
- .llong .sys_alarm
- .llong .sys_ni_syscall /* old fstat syscall */
- .llong .sys_pause
- .llong .sys_utime /* 30 */
- .llong .sys_ni_syscall /* old stty syscall */
- .llong .sys_ni_syscall /* old gtty syscall */
- .llong .sys_access
- .llong .sys_nice
- .llong .sys_ni_syscall /* 35 - old ftime syscall */
- .llong .sys_sync
- .llong .sys_kill
- .llong .sys_rename
- .llong .sys_mkdir
- .llong .sys_rmdir /* 40 */
- .llong .sys_dup
- .llong .sys_pipe
- .llong .sys_times
- .llong .sys_ni_syscall /* old prof syscall */
- .llong .sys_brk /* 45 */
- .llong .sys_setgid
- .llong .sys_getgid
- .llong .sys_signal
- .llong .sys_geteuid
- .llong .sys_getegid /* 50 */
- .llong .sys_acct
- .llong .sys_umount
- .llong .sys_ni_syscall /* old lock syscall */
- .llong .sys_ioctl
- .llong .sys_fcntl /* 55 */
- .llong .sys_ni_syscall /* old mpx syscall */
- .llong .sys_setpgid
- .llong .sys_ni_syscall /* old ulimit syscall */
- .llong .sys_ni_syscall /* old uname syscall */
- .llong .sys_umask /* 60 */
- .llong .sys_chroot
- .llong .sys_ustat
- .llong .sys_dup2
- .llong .sys_getppid
- .llong .sys_getpgrp /* 65 */
- .llong .sys_setsid
- .llong .sys_ni_syscall
- .llong .sys_sgetmask
- .llong .sys_ssetmask
- .llong .sys_setreuid /* 70 */
- .llong .sys_setregid
- .llong .sys_ni_syscall
- .llong .sys_ni_syscall
- .llong .sys_sethostname
- .llong .sys_setrlimit /* 75 */
- .llong .sys_ni_syscall /* old getrlimit syscall */
- .llong .sys_getrusage
- .llong .sys_gettimeofday
- .llong .sys_settimeofday
- .llong .sys_getgroups /* 80 */
- .llong .sys_setgroups
- .llong .sys_ni_syscall /* old select syscall */
- .llong .sys_symlink
- .llong .sys_ni_syscall /* old lstat syscall */
- .llong .sys_readlink /* 85 */
- .llong .sys_uselib
- .llong .sys_swapon
- .llong .sys_reboot
- .llong .sys_ni_syscall /* old readdir syscall */
- .llong .sys_mmap /* 90 */
- .llong .sys_munmap
- .llong .sys_truncate
- .llong .sys_ftruncate
- .llong .sys_fchmod
- .llong .sys_fchown /* 95 */
- .llong .sys_getpriority
- .llong .sys_setpriority
- .llong .sys_ni_syscall /* old profil syscall holder */
- .llong .sys_statfs
- .llong .sys_fstatfs /* 100 */
- .llong .sys_ni_syscall /* old ioperm syscall */
- .llong .sys_socketcall
- .llong .sys_syslog
- .llong .sys_setitimer
- .llong .sys_getitimer /* 105 */
- .llong .sys_newstat
- .llong .sys_newlstat
- .llong .sys_newfstat
- .llong .sys_ni_syscall /* old uname syscall */
- .llong .sys_ni_syscall /* 110 old iopl syscall */
- .llong .sys_vhangup
- .llong .sys_ni_syscall /* old idle syscall */
- .llong .sys_ni_syscall /* old vm86 syscall */
- .llong .sys_wait4
- .llong .sys_swapoff /* 115 */
- .llong .sys_sysinfo
- .llong .sys_ipc
- .llong .sys_fsync
- .llong .sys_ni_syscall
- .llong .ppc_clone /* 120 */
- .llong .sys_setdomainname
- .llong .ppc64_newuname
- .llong .sys_ni_syscall /* old modify_ldt syscall */
- .llong .sys_adjtimex
- .llong .sys_mprotect /* 125 */
- .llong .sys_ni_syscall
- .llong .sys_ni_syscall /* old create_module syscall */
- .llong .sys_init_module
- .llong .sys_delete_module
- .llong .sys_ni_syscall /* 130 old get_kernel_syms syscall */
- .llong .sys_quotactl
- .llong .sys_getpgid
- .llong .sys_fchdir
- .llong .sys_bdflush
- .llong .sys_sysfs /* 135 */
- .llong .ppc64_personality
- .llong .sys_ni_syscall /* for afs_syscall */
- .llong .sys_setfsuid
- .llong .sys_setfsgid
- .llong .sys_llseek /* 140 */
- .llong .sys_getdents
- .llong .sys_select
- .llong .sys_flock
- .llong .sys_msync
- .llong .sys_readv /* 145 */
- .llong .sys_writev
- .llong .sys_getsid
- .llong .sys_fdatasync
- .llong .sys_sysctl
- .llong .sys_mlock /* 150 */
- .llong .sys_munlock
- .llong .sys_mlockall
- .llong .sys_munlockall
- .llong .sys_sched_setparam
- .llong .sys_sched_getparam /* 155 */
- .llong .sys_sched_setscheduler
- .llong .sys_sched_getscheduler
- .llong .sys_sched_yield
- .llong .sys_sched_get_priority_max
- .llong .sys_sched_get_priority_min /* 160 */
- .llong .sys_sched_rr_get_interval
- .llong .sys_nanosleep
- .llong .sys_mremap
- .llong .sys_setresuid
- .llong .sys_getresuid /* 165 */
- .llong .sys_ni_syscall /* old query_module syscall */
- .llong .sys_poll
- .llong .sys_nfsservctl
- .llong .sys_setresgid
- .llong .sys_getresgid /* 170 */
- .llong .sys_prctl
- .llong .ppc64_rt_sigreturn
- .llong .sys_rt_sigaction
- .llong .sys_rt_sigprocmask
- .llong .sys_rt_sigpending /* 175 */
- .llong .sys_rt_sigtimedwait
- .llong .sys_rt_sigqueueinfo
- .llong .ppc64_rt_sigsuspend
- .llong .sys_pread64
- .llong .sys_pwrite64 /* 180 */
- .llong .sys_chown
- .llong .sys_getcwd
- .llong .sys_capget
- .llong .sys_capset
- .llong .sys_sigaltstack /* 185 */
- .llong .sys_sendfile64
- .llong .sys_ni_syscall /* reserved for streams1 */
- .llong .sys_ni_syscall /* reserved for streams2 */
- .llong .ppc_vfork
- .llong .sys_getrlimit /* 190 */
- .llong .sys_readahead
- .llong .sys_ni_syscall /* 32bit only mmap2 */
- .llong .sys_ni_syscall /* 32bit only truncate64 */
- .llong .sys_ni_syscall /* 32bit only ftruncate64 */
- .llong .sys_ni_syscall /* 195 - 32bit only stat64 */
- .llong .sys_ni_syscall /* 32bit only lstat64 */
- .llong .sys_ni_syscall /* 32bit only fstat64 */
- .llong .sys_pciconfig_read
- .llong .sys_pciconfig_write
- .llong .sys_pciconfig_iobase /* 200 - pciconfig_iobase */
- .llong .sys_ni_syscall /* reserved for MacOnLinux */
- .llong .sys_getdents64
- .llong .sys_pivot_root
- .llong .sys_ni_syscall /* 32bit only fcntl64 */
- .llong .sys_madvise /* 205 */
- .llong .sys_mincore
- .llong .sys_gettid
- .llong .sys_tkill
- .llong .sys_setxattr
- .llong .sys_lsetxattr /* 210 */
- .llong .sys_fsetxattr
- .llong .sys_getxattr
- .llong .sys_lgetxattr
- .llong .sys_fgetxattr
- .llong .sys_listxattr /* 215 */
- .llong .sys_llistxattr
- .llong .sys_flistxattr
- .llong .sys_removexattr
- .llong .sys_lremovexattr
- .llong .sys_fremovexattr /* 220 */
- .llong .sys_futex
- .llong .sys_sched_setaffinity
- .llong .sys_sched_getaffinity
- .llong .sys_ni_syscall
- .llong .sys_ni_syscall /* 225 - reserved for tux */
- .llong .sys_ni_syscall /* 32bit only sendfile64 */
- .llong .sys_io_setup
- .llong .sys_io_destroy
- .llong .sys_io_getevents
- .llong .sys_io_submit /* 230 */
- .llong .sys_io_cancel
- .llong .sys_set_tid_address
- .llong .sys_fadvise64
- .llong .sys_exit_group
- .llong .sys_lookup_dcookie /* 235 */
- .llong .sys_epoll_create
- .llong .sys_epoll_ctl
- .llong .sys_epoll_wait
- .llong .sys_remap_file_pages
- .llong .sys_timer_create /* 240 */
- .llong .sys_timer_settime
- .llong .sys_timer_gettime
- .llong .sys_timer_getoverrun
- .llong .sys_timer_delete
- .llong .sys_clock_settime /* 245 */
- .llong .sys_clock_gettime
- .llong .sys_clock_getres
- .llong .sys_clock_nanosleep
- .llong .ppc64_swapcontext
- .llong .sys_tgkill /* 250 */
- .llong .sys_utimes
- .llong .sys_statfs64
- .llong .sys_fstatfs64
- .llong .sys_ni_syscall /* 32bit only fadvise64_64 */
- .llong .ppc_rtas /* 255 */
- .llong .sys_ni_syscall /* 256 reserved for sys_debug_setcontext */
- .llong .sys_ni_syscall /* 257 reserved for vserver */
- .llong .sys_ni_syscall /* 258 reserved for new sys_remap_file_pages */
- .llong .sys_mbind
- .llong .sys_get_mempolicy /* 260 */
- .llong .sys_set_mempolicy
- .llong .sys_mq_open
- .llong .sys_mq_unlink
- .llong .sys_mq_timedsend
- .llong .sys_mq_timedreceive /* 265 */
- .llong .sys_mq_notify
- .llong .sys_mq_getsetattr
- .llong .sys_kexec_load
- .llong .sys_add_key
- .llong .sys_request_key /* 270 */
- .llong .sys_keyctl
- .llong .sys_waitid
- .llong .sys_ioprio_set
- .llong .sys_ioprio_get
- .llong .sys_inotify_init /* 275 */
- .llong .sys_inotify_add_watch
- .llong .sys_inotify_rm_watch
diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c
index ff4be1da69d5..3d2106b022a1 100644
--- a/arch/ppc64/kernel/pci.c
+++ b/arch/ppc64/kernel/pci.c
@@ -31,8 +31,7 @@
#include <asm/irq.h>
#include <asm/machdep.h>
#include <asm/udbg.h>
-
-#include "pci.h"
+#include <asm/ppc-pci.h>
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
@@ -727,16 +726,17 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,
* above routine
*/
pgprot_t pci_phys_mem_access_prot(struct file *file,
- unsigned long offset,
+ unsigned long pfn,
unsigned long size,
pgprot_t protection)
{
struct pci_dev *pdev = NULL;
struct resource *found = NULL;
unsigned long prot = pgprot_val(protection);
+ unsigned long offset = pfn << PAGE_SHIFT;
int i;
- if (page_is_ram(offset >> PAGE_SHIFT))
+ if (page_is_ram(pfn))
return __pgprot(prot);
prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
@@ -881,9 +881,9 @@ static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node,
}
void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
- struct device_node *dev)
+ struct device_node *dev, int prim)
{
- unsigned int *ranges;
+ unsigned int *ranges, pci_space;
unsigned long size;
int rlen = 0;
int memno = 0;
@@ -906,16 +906,39 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
ranges = (unsigned int *) get_property(dev, "ranges", &rlen);
while ((rlen -= np * sizeof(unsigned int)) >= 0) {
res = NULL;
- pci_addr = (unsigned long)ranges[1] << 32 | ranges[2];
+ pci_space = ranges[0];
+ pci_addr = ((unsigned long)ranges[1] << 32) | ranges[2];
cpu_phys_addr = ranges[3];
- if (na == 2)
- cpu_phys_addr = cpu_phys_addr << 32 | ranges[4];
+ if (na >= 2)
+ cpu_phys_addr = (cpu_phys_addr << 32) | ranges[4];
- size = (unsigned long)ranges[na+3] << 32 | ranges[na+4];
+ size = ((unsigned long)ranges[na+3] << 32) | ranges[na+4];
+ ranges += np;
if (size == 0)
continue;
- switch ((ranges[0] >> 24) & 0x3) {
+
+ /* Now consume following elements while they are contiguous */
+ while (rlen >= np * sizeof(unsigned int)) {
+ unsigned long addr, phys;
+
+ if (ranges[0] != pci_space)
+ break;
+ addr = ((unsigned long)ranges[1] << 32) | ranges[2];
+ phys = ranges[3];
+ if (na >= 2)
+ phys = (phys << 32) | ranges[4];
+ if (addr != pci_addr + size ||
+ phys != cpu_phys_addr + size)
+ break;
+
+ size += ((unsigned long)ranges[na+3] << 32)
+ | ranges[na+4];
+ ranges += np;
+ rlen -= np * sizeof(unsigned int);
+ }
+
+ switch ((pci_space >> 24) & 0x3) {
case 1: /* I/O space */
hose->io_base_phys = cpu_phys_addr;
hose->pci_io_size = size;
@@ -949,7 +972,6 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
res->sibling = NULL;
res->child = NULL;
}
- ranges += np;
}
}
diff --git a/arch/ppc64/kernel/pci_direct_iommu.c b/arch/ppc64/kernel/pci_direct_iommu.c
index 54055c81017a..e1a32f802c0b 100644
--- a/arch/ppc64/kernel/pci_direct_iommu.c
+++ b/arch/ppc64/kernel/pci_direct_iommu.c
@@ -27,8 +27,7 @@
#include <asm/machdep.h>
#include <asm/pmac_feature.h>
#include <asm/abs_addr.h>
-
-#include "pci.h"
+#include <asm/ppc-pci.h>
static void *pci_direct_alloc_coherent(struct device *hwdev, size_t size,
dma_addr_t *dma_handle, gfp_t flag)
diff --git a/arch/ppc64/kernel/pci_dn.c b/arch/ppc64/kernel/pci_dn.c
index a86389d07d57..493bbe43f5b4 100644
--- a/arch/ppc64/kernel/pci_dn.c
+++ b/arch/ppc64/kernel/pci_dn.c
@@ -30,8 +30,7 @@
#include <asm/prom.h>
#include <asm/pci-bridge.h>
#include <asm/pSeries_reconfig.h>
-
-#include "pci.h"
+#include <asm/ppc-pci.h>
/*
* Traverse_func that inits the PCI fields of the device node.
diff --git a/arch/ppc64/kernel/pci_iommu.c b/arch/ppc64/kernel/pci_iommu.c
index d9e33b7d4203..bdf15dbbf4f0 100644
--- a/arch/ppc64/kernel/pci_iommu.c
+++ b/arch/ppc64/kernel/pci_iommu.c
@@ -1,8 +1,8 @@
/*
* arch/ppc64/kernel/pci_iommu.c
* Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
- *
- * Rewrite, cleanup, new allocation schemes:
+ *
+ * Rewrite, cleanup, new allocation schemes:
* Copyright (C) 2004 Olof Johansson, IBM Corporation
*
* Dynamic DMA mapping support, platform-independent parts.
@@ -11,19 +11,18 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <linux/config.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/slab.h>
@@ -37,11 +36,7 @@
#include <asm/iommu.h>
#include <asm/pci-bridge.h>
#include <asm/machdep.h>
-#include "pci.h"
-
-#ifdef CONFIG_PPC_ISERIES
-#include <asm/iSeries/iSeries_pci.h>
-#endif /* CONFIG_PPC_ISERIES */
+#include <asm/ppc-pci.h>
/*
* We can use ->sysdata directly and avoid the extra work in
@@ -61,13 +56,7 @@ static inline struct iommu_table *devnode_table(struct device *dev)
} else
pdev = to_pci_dev(dev);
-#ifdef CONFIG_PPC_ISERIES
- return ISERIES_DEVNODE(pdev)->iommu_table;
-#endif /* CONFIG_PPC_ISERIES */
-
-#ifdef CONFIG_PPC_MULTIPLATFORM
return PCI_DN(PCI_GET_DN(pdev))->iommu_table;
-#endif /* CONFIG_PPC_MULTIPLATFORM */
}
diff --git a/arch/ppc64/kernel/pmac.h b/arch/ppc64/kernel/pmac.h
deleted file mode 100644
index 40e1c5030f74..000000000000
--- a/arch/ppc64/kernel/pmac.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef __PMAC_H__
-#define __PMAC_H__
-
-#include <linux/pci.h>
-#include <linux/ide.h>
-
-/*
- * Declaration for the various functions exported by the
- * pmac_* files. Mostly for use by pmac_setup
- */
-
-extern void pmac_get_boot_time(struct rtc_time *tm);
-extern void pmac_get_rtc_time(struct rtc_time *tm);
-extern int pmac_set_rtc_time(struct rtc_time *tm);
-extern void pmac_read_rtc_time(void);
-extern void pmac_calibrate_decr(void);
-
-extern void pmac_pcibios_fixup(void);
-extern void pmac_pci_init(void);
-extern void pmac_setup_pci_dma(void);
-extern void pmac_check_ht_link(void);
-
-extern void pmac_setup_smp(void);
-
-extern unsigned long pmac_ide_get_base(int index);
-extern void pmac_ide_init_hwif_ports(hw_regs_t *hw,
- unsigned long data_port, unsigned long ctrl_port, int *irq);
-
-extern void pmac_nvram_init(void);
-
-#endif /* __PMAC_H__ */
diff --git a/arch/ppc64/kernel/pmac_feature.c b/arch/ppc64/kernel/pmac_feature.c
deleted file mode 100644
index eb4e6c3f694d..000000000000
--- a/arch/ppc64/kernel/pmac_feature.c
+++ /dev/null
@@ -1,767 +0,0 @@
-/*
- * arch/ppc/platforms/pmac_feature.c
- *
- * Copyright (C) 1996-2001 Paul Mackerras (paulus@cs.anu.edu.au)
- * Ben. Herrenschmidt (benh@kernel.crashing.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.
- *
- * TODO:
- *
- * - Replace mdelay with some schedule loop if possible
- * - Shorten some obfuscated delays on some routines (like modem
- * power)
- * - Refcount some clocks (see darwin)
- * - Split split split...
- *
- */
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/adb.h>
-#include <linux/pmu.h>
-#include <linux/ioport.h>
-#include <linux/pci.h>
-#include <asm/sections.h>
-#include <asm/errno.h>
-#include <asm/keylargo.h>
-#include <asm/uninorth.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/machdep.h>
-#include <asm/pmac_feature.h>
-#include <asm/dbdma.h>
-#include <asm/pci-bridge.h>
-#include <asm/pmac_low_i2c.h>
-
-#undef DEBUG_FEATURE
-
-#ifdef DEBUG_FEATURE
-#define DBG(fmt...) printk(KERN_DEBUG fmt)
-#else
-#define DBG(fmt...)
-#endif
-
-/*
- * We use a single global lock to protect accesses. Each driver has
- * to take care of its own locking
- */
-static DEFINE_SPINLOCK(feature_lock __pmacdata);
-
-#define LOCK(flags) spin_lock_irqsave(&feature_lock, flags);
-#define UNLOCK(flags) spin_unlock_irqrestore(&feature_lock, flags);
-
-
-/*
- * Instance of some macio stuffs
- */
-struct macio_chip macio_chips[MAX_MACIO_CHIPS] __pmacdata;
-
-struct macio_chip* __pmac macio_find(struct device_node* child, int type)
-{
- while(child) {
- int i;
-
- for (i=0; i < MAX_MACIO_CHIPS && macio_chips[i].of_node; i++)
- if (child == macio_chips[i].of_node &&
- (!type || macio_chips[i].type == type))
- return &macio_chips[i];
- child = child->parent;
- }
- return NULL;
-}
-EXPORT_SYMBOL_GPL(macio_find);
-
-static const char* macio_names[] __pmacdata =
-{
- "Unknown",
- "Grand Central",
- "OHare",
- "OHareII",
- "Heathrow",
- "Gatwick",
- "Paddington",
- "Keylargo",
- "Pangea",
- "Intrepid",
- "K2"
-};
-
-
-
-/*
- * Uninorth reg. access. Note that Uni-N regs are big endian
- */
-
-#define UN_REG(r) (uninorth_base + ((r) >> 2))
-#define UN_IN(r) (in_be32(UN_REG(r)))
-#define UN_OUT(r,v) (out_be32(UN_REG(r), (v)))
-#define UN_BIS(r,v) (UN_OUT((r), UN_IN(r) | (v)))
-#define UN_BIC(r,v) (UN_OUT((r), UN_IN(r) & ~(v)))
-
-static struct device_node* uninorth_node __pmacdata;
-static u32* uninorth_base __pmacdata;
-static u32 uninorth_rev __pmacdata;
-static void *u3_ht;
-
-extern struct device_node *k2_skiplist[2];
-
-/*
- * For each motherboard family, we have a table of functions pointers
- * that handle the various features.
- */
-
-typedef long (*feature_call)(struct device_node* node, long param, long value);
-
-struct feature_table_entry {
- unsigned int selector;
- feature_call function;
-};
-
-struct pmac_mb_def
-{
- const char* model_string;
- const char* model_name;
- int model_id;
- struct feature_table_entry* features;
- unsigned long board_flags;
-};
-static struct pmac_mb_def pmac_mb __pmacdata;
-
-/*
- * Here are the chip specific feature functions
- */
-
-
-static long __pmac g5_read_gpio(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio = &macio_chips[0];
-
- return MACIO_IN8(param);
-}
-
-
-static long __pmac g5_write_gpio(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio = &macio_chips[0];
-
- MACIO_OUT8(param, (u8)(value & 0xff));
- return 0;
-}
-
-static long __pmac g5_gmac_enable(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio = &macio_chips[0];
- unsigned long flags;
-
- if (node == NULL)
- return -ENODEV;
-
- LOCK(flags);
- if (value) {
- MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);
- mb();
- k2_skiplist[0] = NULL;
- } else {
- k2_skiplist[0] = node;
- mb();
- MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);
- }
-
- UNLOCK(flags);
- mdelay(1);
-
- return 0;
-}
-
-static long __pmac g5_fw_enable(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio = &macio_chips[0];
- unsigned long flags;
-
- if (node == NULL)
- return -ENODEV;
-
- LOCK(flags);
- if (value) {
- MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE);
- mb();
- k2_skiplist[1] = NULL;
- } else {
- k2_skiplist[1] = node;
- mb();
- MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE);
- }
-
- UNLOCK(flags);
- mdelay(1);
-
- return 0;
-}
-
-static long __pmac g5_mpic_enable(struct device_node* node, long param, long value)
-{
- unsigned long flags;
-
- if (node->parent == NULL || strcmp(node->parent->name, "u3"))
- return 0;
-
- LOCK(flags);
- UN_BIS(U3_TOGGLE_REG, U3_MPIC_RESET | U3_MPIC_OUTPUT_ENABLE);
- UNLOCK(flags);
-
- return 0;
-}
-
-static long __pmac g5_eth_phy_reset(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio = &macio_chips[0];
- struct device_node *phy;
- int need_reset;
-
- /*
- * We must not reset the combo PHYs, only the BCM5221 found in
- * the iMac G5.
- */
- phy = of_get_next_child(node, NULL);
- if (!phy)
- return -ENODEV;
- need_reset = device_is_compatible(phy, "B5221");
- of_node_put(phy);
- if (!need_reset)
- return 0;
-
- /* PHY reset is GPIO 29, not in device-tree unfortunately */
- MACIO_OUT8(K2_GPIO_EXTINT_0 + 29,
- KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA);
- /* Thankfully, this is now always called at a time when we can
- * schedule by sungem.
- */
- msleep(10);
- MACIO_OUT8(K2_GPIO_EXTINT_0 + 29, 0);
-
- return 0;
-}
-
-static long __pmac g5_i2s_enable(struct device_node *node, long param, long value)
-{
- /* Very crude implementation for now */
- struct macio_chip* macio = &macio_chips[0];
- unsigned long flags;
-
- if (value == 0)
- return 0; /* don't disable yet */
-
- LOCK(flags);
- MACIO_BIS(KEYLARGO_FCR3, KL3_CLK45_ENABLE | KL3_CLK49_ENABLE |
- KL3_I2S0_CLK18_ENABLE);
- udelay(10);
- MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_I2S0_CELL_ENABLE |
- K2_FCR1_I2S0_CLK_ENABLE_BIT | K2_FCR1_I2S0_ENABLE);
- udelay(10);
- MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_I2S0_RESET);
- UNLOCK(flags);
- udelay(10);
-
- return 0;
-}
-
-
-#ifdef CONFIG_SMP
-static long __pmac g5_reset_cpu(struct device_node* node, long param, long value)
-{
- unsigned int reset_io = 0;
- unsigned long flags;
- struct macio_chip* macio;
- struct device_node* np;
-
- macio = &macio_chips[0];
- if (macio->type != macio_keylargo2)
- return -ENODEV;
-
- np = find_path_device("/cpus");
- if (np == NULL)
- return -ENODEV;
- for (np = np->child; np != NULL; np = np->sibling) {
- u32* num = (u32 *)get_property(np, "reg", NULL);
- u32* rst = (u32 *)get_property(np, "soft-reset", NULL);
- if (num == NULL || rst == NULL)
- continue;
- if (param == *num) {
- reset_io = *rst;
- break;
- }
- }
- if (np == NULL || reset_io == 0)
- return -ENODEV;
-
- LOCK(flags);
- MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE);
- (void)MACIO_IN8(reset_io);
- udelay(1);
- MACIO_OUT8(reset_io, 0);
- (void)MACIO_IN8(reset_io);
- UNLOCK(flags);
-
- return 0;
-}
-#endif /* CONFIG_SMP */
-
-/*
- * This can be called from pmac_smp so isn't static
- *
- * This takes the second CPU off the bus on dual CPU machines
- * running UP
- */
-void __pmac g5_phy_disable_cpu1(void)
-{
- UN_OUT(U3_API_PHY_CONFIG_1, 0);
-}
-
-static long __pmac generic_get_mb_info(struct device_node* node, long param, long value)
-{
- switch(param) {
- case PMAC_MB_INFO_MODEL:
- return pmac_mb.model_id;
- case PMAC_MB_INFO_FLAGS:
- return pmac_mb.board_flags;
- case PMAC_MB_INFO_NAME:
- /* hack hack hack... but should work */
- *((const char **)value) = pmac_mb.model_name;
- return 0;
- }
- return -EINVAL;
-}
-
-
-/*
- * Table definitions
- */
-
-/* Used on any machine
- */
-static struct feature_table_entry any_features[] __pmacdata = {
- { PMAC_FTR_GET_MB_INFO, generic_get_mb_info },
- { 0, NULL }
-};
-
-/* G5 features
- */
-static struct feature_table_entry g5_features[] __pmacdata = {
- { PMAC_FTR_GMAC_ENABLE, g5_gmac_enable },
- { PMAC_FTR_1394_ENABLE, g5_fw_enable },
- { PMAC_FTR_ENABLE_MPIC, g5_mpic_enable },
- { PMAC_FTR_READ_GPIO, g5_read_gpio },
- { PMAC_FTR_WRITE_GPIO, g5_write_gpio },
- { PMAC_FTR_GMAC_PHY_RESET, g5_eth_phy_reset },
- { PMAC_FTR_SOUND_CHIP_ENABLE, g5_i2s_enable },
-#ifdef CONFIG_SMP
- { PMAC_FTR_RESET_CPU, g5_reset_cpu },
-#endif /* CONFIG_SMP */
- { 0, NULL }
-};
-
-static struct pmac_mb_def pmac_mb_defs[] __pmacdata = {
- { "PowerMac7,2", "PowerMac G5",
- PMAC_TYPE_POWERMAC_G5, g5_features,
- 0,
- },
- { "PowerMac7,3", "PowerMac G5",
- PMAC_TYPE_POWERMAC_G5, g5_features,
- 0,
- },
- { "PowerMac8,1", "iMac G5",
- PMAC_TYPE_IMAC_G5, g5_features,
- 0,
- },
- { "PowerMac9,1", "PowerMac G5",
- PMAC_TYPE_POWERMAC_G5_U3L, g5_features,
- 0,
- },
- { "RackMac3,1", "XServe G5",
- PMAC_TYPE_XSERVE_G5, g5_features,
- 0,
- },
-};
-
-/*
- * The toplevel feature_call callback
- */
-long __pmac pmac_do_feature_call(unsigned int selector, ...)
-{
- struct device_node* node;
- long param, value;
- int i;
- feature_call func = NULL;
- va_list args;
-
- if (pmac_mb.features)
- for (i=0; pmac_mb.features[i].function; i++)
- if (pmac_mb.features[i].selector == selector) {
- func = pmac_mb.features[i].function;
- break;
- }
- if (!func)
- for (i=0; any_features[i].function; i++)
- if (any_features[i].selector == selector) {
- func = any_features[i].function;
- break;
- }
- if (!func)
- return -ENODEV;
-
- va_start(args, selector);
- node = (struct device_node*)va_arg(args, void*);
- param = va_arg(args, long);
- value = va_arg(args, long);
- va_end(args);
-
- return func(node, param, value);
-}
-
-static int __init probe_motherboard(void)
-{
- int i;
- struct macio_chip* macio = &macio_chips[0];
- const char* model = NULL;
- struct device_node *dt;
-
- /* Lookup known motherboard type in device-tree. First try an
- * exact match on the "model" property, then try a "compatible"
- * match is none is found.
- */
- dt = find_devices("device-tree");
- if (dt != NULL)
- model = (const char *) get_property(dt, "model", NULL);
- for(i=0; model && i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) {
- if (strcmp(model, pmac_mb_defs[i].model_string) == 0) {
- pmac_mb = pmac_mb_defs[i];
- goto found;
- }
- }
- for(i=0; i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) {
- if (machine_is_compatible(pmac_mb_defs[i].model_string)) {
- pmac_mb = pmac_mb_defs[i];
- goto found;
- }
- }
-
- /* Fallback to selection depending on mac-io chip type */
- switch(macio->type) {
- case macio_keylargo2:
- pmac_mb.model_id = PMAC_TYPE_UNKNOWN_K2;
- pmac_mb.model_name = "Unknown K2-based";
- pmac_mb.features = g5_features;
-
- default:
- return -ENODEV;
- }
-found:
- /* Check for "mobile" machine */
- if (model && (strncmp(model, "PowerBook", 9) == 0
- || strncmp(model, "iBook", 5) == 0))
- pmac_mb.board_flags |= PMAC_MB_MOBILE;
-
-
- printk(KERN_INFO "PowerMac motherboard: %s\n", pmac_mb.model_name);
- return 0;
-}
-
-/* Initialize the Core99 UniNorth host bridge and memory controller
- */
-static void __init probe_uninorth(void)
-{
- uninorth_node = of_find_node_by_name(NULL, "u3");
- if (uninorth_node && uninorth_node->n_addrs > 0) {
- /* Small hack until I figure out if parsing in prom.c is correct. I should
- * get rid of those pre-parsed junk anyway
- */
- unsigned long address = uninorth_node->addrs[0].address;
- uninorth_base = ioremap(address, 0x40000);
- uninorth_rev = in_be32(UN_REG(UNI_N_VERSION));
- u3_ht = ioremap(address + U3_HT_CONFIG_BASE, 0x1000);
- } else
- uninorth_node = NULL;
-
- if (!uninorth_node)
- return;
-
- printk(KERN_INFO "Found U3 memory controller & host bridge, revision: %d\n",
- uninorth_rev);
- printk(KERN_INFO "Mapped at 0x%08lx\n", (unsigned long)uninorth_base);
-
-}
-
-static void __init probe_one_macio(const char* name, const char* compat, int type)
-{
- struct device_node* node;
- int i;
- volatile u32* base;
- u32* revp;
-
- node = find_devices(name);
- if (!node || !node->n_addrs)
- return;
- if (compat)
- do {
- if (device_is_compatible(node, compat))
- break;
- node = node->next;
- } while (node);
- if (!node)
- return;
- for(i=0; i<MAX_MACIO_CHIPS; i++) {
- if (!macio_chips[i].of_node)
- break;
- if (macio_chips[i].of_node == node)
- return;
- }
- if (i >= MAX_MACIO_CHIPS) {
- printk(KERN_ERR "pmac_feature: Please increase MAX_MACIO_CHIPS !\n");
- printk(KERN_ERR "pmac_feature: %s skipped\n", node->full_name);
- return;
- }
- base = (volatile u32*)ioremap(node->addrs[0].address, node->addrs[0].size);
- if (!base) {
- printk(KERN_ERR "pmac_feature: Can't map mac-io chip !\n");
- return;
- }
- if (type == macio_keylargo) {
- u32* did = (u32 *)get_property(node, "device-id", NULL);
- if (*did == 0x00000025)
- type = macio_pangea;
- if (*did == 0x0000003e)
- type = macio_intrepid;
- }
- macio_chips[i].of_node = node;
- macio_chips[i].type = type;
- macio_chips[i].base = base;
- macio_chips[i].flags = MACIO_FLAG_SCCB_ON | MACIO_FLAG_SCCB_ON;
- macio_chips[i].name = macio_names[type];
- revp = (u32 *)get_property(node, "revision-id", NULL);
- if (revp)
- macio_chips[i].rev = *revp;
- printk(KERN_INFO "Found a %s mac-io controller, rev: %d, mapped at 0x%p\n",
- macio_names[type], macio_chips[i].rev, macio_chips[i].base);
-}
-
-static int __init
-probe_macios(void)
-{
- probe_one_macio("mac-io", "K2-Keylargo", macio_keylargo2);
-
- macio_chips[0].lbus.index = 0;
- macio_chips[1].lbus.index = 1;
-
- return (macio_chips[0].of_node == NULL) ? -ENODEV : 0;
-}
-
-static void __init
-set_initial_features(void)
-{
- struct device_node *np;
-
- if (macio_chips[0].type == macio_keylargo2) {
-#ifndef CONFIG_SMP
- /* On SMP machines running UP, we have the second CPU eating
- * bus cycles. We need to take it off the bus. This is done
- * from pmac_smp for SMP kernels running on one CPU
- */
- np = of_find_node_by_type(NULL, "cpu");
- if (np != NULL)
- np = of_find_node_by_type(np, "cpu");
- if (np != NULL) {
- g5_phy_disable_cpu1();
- of_node_put(np);
- }
-#endif /* CONFIG_SMP */
- /* Enable GMAC for now for PCI probing. It will be disabled
- * later on after PCI probe
- */
- np = of_find_node_by_name(NULL, "ethernet");
- while(np) {
- if (device_is_compatible(np, "K2-GMAC"))
- g5_gmac_enable(np, 0, 1);
- np = of_find_node_by_name(np, "ethernet");
- }
-
- /* Enable FW before PCI probe. Will be disabled later on
- * Note: We should have a batter way to check that we are
- * dealing with uninorth internal cell and not a PCI cell
- * on the external PCI. The code below works though.
- */
- np = of_find_node_by_name(NULL, "firewire");
- while(np) {
- if (device_is_compatible(np, "pci106b,5811")) {
- macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED;
- g5_fw_enable(np, 0, 1);
- }
- np = of_find_node_by_name(np, "firewire");
- }
- }
-}
-
-void __init
-pmac_feature_init(void)
-{
- /* Detect the UniNorth memory controller */
- probe_uninorth();
-
- /* Probe mac-io controllers */
- if (probe_macios()) {
- printk(KERN_WARNING "No mac-io chip found\n");
- return;
- }
-
- /* Setup low-level i2c stuffs */
- pmac_init_low_i2c();
-
- /* Probe machine type */
- if (probe_motherboard())
- printk(KERN_WARNING "Unknown PowerMac !\n");
-
- /* Set some initial features (turn off some chips that will
- * be later turned on)
- */
- set_initial_features();
-}
-
-int __init pmac_feature_late_init(void)
-{
-#if 0
- struct device_node* np;
-
- /* Request some resources late */
- if (uninorth_node)
- request_OF_resource(uninorth_node, 0, NULL);
- np = find_devices("hammerhead");
- if (np)
- request_OF_resource(np, 0, NULL);
- np = find_devices("interrupt-controller");
- if (np)
- request_OF_resource(np, 0, NULL);
-#endif
- return 0;
-}
-
-device_initcall(pmac_feature_late_init);
-
-#if 0
-static void dump_HT_speeds(char *name, u32 cfg, u32 frq)
-{
- int freqs[16] = { 200,300,400,500,600,800,1000,0,0,0,0,0,0,0,0,0 };
- int bits[8] = { 8,16,0,32,2,4,0,0 };
- int freq = (frq >> 8) & 0xf;
-
- if (freqs[freq] == 0)
- printk("%s: Unknown HT link frequency %x\n", name, freq);
- else
- printk("%s: %d MHz on main link, (%d in / %d out) bits width\n",
- name, freqs[freq],
- bits[(cfg >> 28) & 0x7], bits[(cfg >> 24) & 0x7]);
-}
-#endif
-
-void __init pmac_check_ht_link(void)
-{
-#if 0 /* Disabled for now */
- u32 ufreq, freq, ucfg, cfg;
- struct device_node *pcix_node;
- struct pci_dn *pdn;
- u8 px_bus, px_devfn;
- struct pci_controller *px_hose;
-
- (void)in_be32(u3_ht + U3_HT_LINK_COMMAND);
- ucfg = cfg = in_be32(u3_ht + U3_HT_LINK_CONFIG);
- ufreq = freq = in_be32(u3_ht + U3_HT_LINK_FREQ);
- dump_HT_speeds("U3 HyperTransport", cfg, freq);
-
- pcix_node = of_find_compatible_node(NULL, "pci", "pci-x");
- if (pcix_node == NULL) {
- printk("No PCI-X bridge found\n");
- return;
- }
- pdn = pcix_node->data;
- px_hose = pdn->phb;
- px_bus = pdn->busno;
- px_devfn = pdn->devfn;
-
- early_read_config_dword(px_hose, px_bus, px_devfn, 0xc4, &cfg);
- early_read_config_dword(px_hose, px_bus, px_devfn, 0xcc, &freq);
- dump_HT_speeds("PCI-X HT Uplink", cfg, freq);
- early_read_config_dword(px_hose, px_bus, px_devfn, 0xc8, &cfg);
- early_read_config_dword(px_hose, px_bus, px_devfn, 0xd0, &freq);
- dump_HT_speeds("PCI-X HT Downlink", cfg, freq);
-#endif
-}
-
-/*
- * Early video resume hook
- */
-
-static void (*pmac_early_vresume_proc)(void *data) __pmacdata;
-static void *pmac_early_vresume_data __pmacdata;
-
-void pmac_set_early_video_resume(void (*proc)(void *data), void *data)
-{
- if (_machine != _MACH_Pmac)
- return;
- preempt_disable();
- pmac_early_vresume_proc = proc;
- pmac_early_vresume_data = data;
- preempt_enable();
-}
-EXPORT_SYMBOL(pmac_set_early_video_resume);
-
-
-/*
- * AGP related suspend/resume code
- */
-
-static struct pci_dev *pmac_agp_bridge __pmacdata;
-static int (*pmac_agp_suspend)(struct pci_dev *bridge) __pmacdata;
-static int (*pmac_agp_resume)(struct pci_dev *bridge) __pmacdata;
-
-void __pmac pmac_register_agp_pm(struct pci_dev *bridge,
- int (*suspend)(struct pci_dev *bridge),
- int (*resume)(struct pci_dev *bridge))
-{
- if (suspend || resume) {
- pmac_agp_bridge = bridge;
- pmac_agp_suspend = suspend;
- pmac_agp_resume = resume;
- return;
- }
- if (bridge != pmac_agp_bridge)
- return;
- pmac_agp_suspend = pmac_agp_resume = NULL;
- return;
-}
-EXPORT_SYMBOL(pmac_register_agp_pm);
-
-void __pmac pmac_suspend_agp_for_card(struct pci_dev *dev)
-{
- if (pmac_agp_bridge == NULL || pmac_agp_suspend == NULL)
- return;
- if (pmac_agp_bridge->bus != dev->bus)
- return;
- pmac_agp_suspend(pmac_agp_bridge);
-}
-EXPORT_SYMBOL(pmac_suspend_agp_for_card);
-
-void __pmac pmac_resume_agp_for_card(struct pci_dev *dev)
-{
- if (pmac_agp_bridge == NULL || pmac_agp_resume == NULL)
- return;
- if (pmac_agp_bridge->bus != dev->bus)
- return;
- pmac_agp_resume(pmac_agp_bridge);
-}
-EXPORT_SYMBOL(pmac_resume_agp_for_card);
diff --git a/arch/ppc64/kernel/pmac_pci.c b/arch/ppc64/kernel/pmac_pci.c
deleted file mode 100644
index dc40a0cad0b4..000000000000
--- a/arch/ppc64/kernel/pmac_pci.c
+++ /dev/null
@@ -1,793 +0,0 @@
-/*
- * Support for PCI bridges found on Power Macintoshes.
- * At present the "bandit" and "chaos" bridges are supported.
- * Fortunately you access configuration space in the same
- * way with either bridge.
- *
- * Copyright (C) 2003 Benjamin Herrenschmuidt (benh@kernel.crashing.org)
- * Copyright (C) 1997 Paul Mackerras (paulus@samba.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/kernel.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/bootmem.h>
-
-#include <asm/sections.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/pci-bridge.h>
-#include <asm/machdep.h>
-#include <asm/pmac_feature.h>
-#include <asm/iommu.h>
-
-#include "pci.h"
-#include "pmac.h"
-
-#define DEBUG
-
-#ifdef DEBUG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-/* XXX Could be per-controller, but I don't think we risk anything by
- * assuming we won't have both UniNorth and Bandit */
-static int has_uninorth;
-static struct pci_controller *u3_agp;
-struct device_node *k2_skiplist[2];
-
-static int __init fixup_one_level_bus_range(struct device_node *node, int higher)
-{
- for (; node != 0;node = node->sibling) {
- int * bus_range;
- unsigned int *class_code;
- int len;
-
- /* For PCI<->PCI bridges or CardBus bridges, we go down */
- class_code = (unsigned int *) get_property(node, "class-code", NULL);
- if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
- (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
- continue;
- bus_range = (int *) get_property(node, "bus-range", &len);
- if (bus_range != NULL && len > 2 * sizeof(int)) {
- if (bus_range[1] > higher)
- higher = bus_range[1];
- }
- higher = fixup_one_level_bus_range(node->child, higher);
- }
- return higher;
-}
-
-/* This routine fixes the "bus-range" property of all bridges in the
- * system since they tend to have their "last" member wrong on macs
- *
- * Note that the bus numbers manipulated here are OF bus numbers, they
- * are not Linux bus numbers.
- */
-static void __init fixup_bus_range(struct device_node *bridge)
-{
- int * bus_range;
- int len;
-
- /* Lookup the "bus-range" property for the hose */
- bus_range = (int *) get_property(bridge, "bus-range", &len);
- if (bus_range == NULL || len < 2 * sizeof(int)) {
- printk(KERN_WARNING "Can't get bus-range for %s\n",
- bridge->full_name);
- return;
- }
- bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]);
-}
-
-/*
- * Apple MacRISC (U3, UniNorth, Bandit, Chaos) PCI controllers.
- *
- * The "Bandit" version is present in all early PCI PowerMacs,
- * and up to the first ones using Grackle. Some machines may
- * have 2 bandit controllers (2 PCI busses).
- *
- * "Chaos" is used in some "Bandit"-type machines as a bridge
- * for the separate display bus. It is accessed the same
- * way as bandit, but cannot be probed for devices. It therefore
- * has its own config access functions.
- *
- * The "UniNorth" version is present in all Core99 machines
- * (iBook, G4, new IMacs, and all the recent Apple machines).
- * It contains 3 controllers in one ASIC.
- *
- * The U3 is the bridge used on G5 machines. It contains on
- * AGP bus which is dealt with the old UniNorth access routines
- * and an HyperTransport bus which uses its own set of access
- * functions.
- */
-
-#define MACRISC_CFA0(devfn, off) \
- ((1 << (unsigned long)PCI_SLOT(dev_fn)) \
- | (((unsigned long)PCI_FUNC(dev_fn)) << 8) \
- | (((unsigned long)(off)) & 0xFCUL))
-
-#define MACRISC_CFA1(bus, devfn, off) \
- ((((unsigned long)(bus)) << 16) \
- |(((unsigned long)(devfn)) << 8) \
- |(((unsigned long)(off)) & 0xFCUL) \
- |1UL)
-
-static unsigned long __pmac macrisc_cfg_access(struct pci_controller* hose,
- u8 bus, u8 dev_fn, u8 offset)
-{
- unsigned int caddr;
-
- if (bus == hose->first_busno) {
- if (dev_fn < (11 << 3))
- return 0;
- caddr = MACRISC_CFA0(dev_fn, offset);
- } else
- caddr = MACRISC_CFA1(bus, dev_fn, offset);
-
- /* Uninorth will return garbage if we don't read back the value ! */
- do {
- out_le32(hose->cfg_addr, caddr);
- } while (in_le32(hose->cfg_addr) != caddr);
-
- offset &= has_uninorth ? 0x07 : 0x03;
- return ((unsigned long)hose->cfg_data) + offset;
-}
-
-static int __pmac macrisc_read_config(struct pci_bus *bus, unsigned int devfn,
- int offset, int len, u32 *val)
-{
- struct pci_controller *hose;
- unsigned long addr;
-
- hose = pci_bus_to_host(bus);
- if (hose == NULL)
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- addr = macrisc_cfg_access(hose, bus->number, devfn, offset);
- if (!addr)
- return PCIBIOS_DEVICE_NOT_FOUND;
- /*
- * Note: the caller has already checked that offset is
- * suitably aligned and that len is 1, 2 or 4.
- */
- switch (len) {
- case 1:
- *val = in_8((u8 *)addr);
- break;
- case 2:
- *val = in_le16((u16 *)addr);
- break;
- default:
- *val = in_le32((u32 *)addr);
- break;
- }
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int __pmac macrisc_write_config(struct pci_bus *bus, unsigned int devfn,
- int offset, int len, u32 val)
-{
- struct pci_controller *hose;
- unsigned long addr;
-
- hose = pci_bus_to_host(bus);
- if (hose == NULL)
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- addr = macrisc_cfg_access(hose, bus->number, devfn, offset);
- if (!addr)
- return PCIBIOS_DEVICE_NOT_FOUND;
- /*
- * Note: the caller has already checked that offset is
- * suitably aligned and that len is 1, 2 or 4.
- */
- switch (len) {
- case 1:
- out_8((u8 *)addr, val);
- (void) in_8((u8 *)addr);
- break;
- case 2:
- out_le16((u16 *)addr, val);
- (void) in_le16((u16 *)addr);
- break;
- default:
- out_le32((u32 *)addr, val);
- (void) in_le32((u32 *)addr);
- break;
- }
- return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops macrisc_pci_ops =
-{
- macrisc_read_config,
- macrisc_write_config
-};
-
-/*
- * These versions of U3 HyperTransport config space access ops do not
- * implement self-view of the HT host yet
- */
-
-/*
- * This function deals with some "special cases" devices.
- *
- * 0 -> No special case
- * 1 -> Skip the device but act as if the access was successfull
- * (return 0xff's on reads, eventually, cache config space
- * accesses in a later version)
- * -1 -> Hide the device (unsuccessful acess)
- */
-static int u3_ht_skip_device(struct pci_controller *hose,
- struct pci_bus *bus, unsigned int devfn)
-{
- struct device_node *busdn, *dn;
- int i;
-
- /* We only allow config cycles to devices that are in OF device-tree
- * as we are apparently having some weird things going on with some
- * revs of K2 on recent G5s
- */
- if (bus->self)
- busdn = pci_device_to_OF_node(bus->self);
- else
- busdn = hose->arch_data;
- for (dn = busdn->child; dn; dn = dn->sibling)
- if (dn->data && PCI_DN(dn)->devfn == devfn)
- break;
- if (dn == NULL)
- return -1;
-
- /*
- * When a device in K2 is powered down, we die on config
- * cycle accesses. Fix that here.
- */
- for (i=0; i<2; i++)
- if (k2_skiplist[i] == dn)
- return 1;
-
- return 0;
-}
-
-#define U3_HT_CFA0(devfn, off) \
- ((((unsigned long)devfn) << 8) | offset)
-#define U3_HT_CFA1(bus, devfn, off) \
- (U3_HT_CFA0(devfn, off) \
- + (((unsigned long)bus) << 16) \
- + 0x01000000UL)
-
-static unsigned long __pmac u3_ht_cfg_access(struct pci_controller* hose,
- u8 bus, u8 devfn, u8 offset)
-{
- if (bus == hose->first_busno) {
- /* For now, we don't self probe U3 HT bridge */
- if (PCI_SLOT(devfn) == 0)
- return 0;
- return ((unsigned long)hose->cfg_data) + U3_HT_CFA0(devfn, offset);
- } else
- return ((unsigned long)hose->cfg_data) + U3_HT_CFA1(bus, devfn, offset);
-}
-
-static int __pmac u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
- int offset, int len, u32 *val)
-{
- struct pci_controller *hose;
- unsigned long addr;
-
-
- hose = pci_bus_to_host(bus);
- if (hose == NULL)
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
- if (!addr)
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- switch (u3_ht_skip_device(hose, bus, devfn)) {
- case 0:
- break;
- case 1:
- switch (len) {
- case 1:
- *val = 0xff; break;
- case 2:
- *val = 0xffff; break;
- default:
- *val = 0xfffffffful; break;
- }
- return PCIBIOS_SUCCESSFUL;
- default:
- return PCIBIOS_DEVICE_NOT_FOUND;
- }
-
- /*
- * Note: the caller has already checked that offset is
- * suitably aligned and that len is 1, 2 or 4.
- */
- switch (len) {
- case 1:
- *val = in_8((u8 *)addr);
- break;
- case 2:
- *val = in_le16((u16 *)addr);
- break;
- default:
- *val = in_le32((u32 *)addr);
- break;
- }
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int __pmac u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
- int offset, int len, u32 val)
-{
- struct pci_controller *hose;
- unsigned long addr;
-
- hose = pci_bus_to_host(bus);
- if (hose == NULL)
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
- if (!addr)
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- switch (u3_ht_skip_device(hose, bus, devfn)) {
- case 0:
- break;
- case 1:
- return PCIBIOS_SUCCESSFUL;
- default:
- return PCIBIOS_DEVICE_NOT_FOUND;
- }
-
- /*
- * Note: the caller has already checked that offset is
- * suitably aligned and that len is 1, 2 or 4.
- */
- switch (len) {
- case 1:
- out_8((u8 *)addr, val);
- (void) in_8((u8 *)addr);
- break;
- case 2:
- out_le16((u16 *)addr, val);
- (void) in_le16((u16 *)addr);
- break;
- default:
- out_le32((u32 *)addr, val);
- (void) in_le32((u32 *)addr);
- break;
- }
- return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops u3_ht_pci_ops =
-{
- u3_ht_read_config,
- u3_ht_write_config
-};
-
-static void __init setup_u3_agp(struct pci_controller* hose)
-{
- /* On G5, we move AGP up to high bus number so we don't need
- * to reassign bus numbers for HT. If we ever have P2P bridges
- * on AGP, we'll have to move pci_assign_all_busses to the
- * pci_controller structure so we enable it for AGP and not for
- * HT childs.
- * We hard code the address because of the different size of
- * the reg address cell, we shall fix that by killing struct
- * reg_property and using some accessor functions instead
- */
- hose->first_busno = 0xf0;
- hose->last_busno = 0xff;
- has_uninorth = 1;
- hose->ops = &macrisc_pci_ops;
- hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000);
- hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000);
-
- u3_agp = hose;
-}
-
-static void __init setup_u3_ht(struct pci_controller* hose)
-{
- struct device_node *np = (struct device_node *)hose->arch_data;
- int i, cur;
-
- hose->ops = &u3_ht_pci_ops;
-
- /* We hard code the address because of the different size of
- * the reg address cell, we shall fix that by killing struct
- * reg_property and using some accessor functions instead
- */
- hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000, 0x02000000);
-
- /*
- * /ht node doesn't expose a "ranges" property, so we "remove" regions that
- * have been allocated to AGP. So far, this version of the code doesn't assign
- * any of the 0xfxxxxxxx "fine" memory regions to /ht.
- * We need to fix that sooner or later by either parsing all child "ranges"
- * properties or figuring out the U3 address space decoding logic and
- * then read it's configuration register (if any).
- */
- hose->io_base_phys = 0xf4000000;
- hose->io_base_virt = ioremap(hose->io_base_phys, 0x00400000);
- isa_io_base = pci_io_base = (unsigned long) hose->io_base_virt;
- hose->io_resource.name = np->full_name;
- hose->io_resource.start = 0;
- hose->io_resource.end = 0x003fffff;
- hose->io_resource.flags = IORESOURCE_IO;
- hose->pci_mem_offset = 0;
- hose->first_busno = 0;
- hose->last_busno = 0xef;
- hose->mem_resources[0].name = np->full_name;
- hose->mem_resources[0].start = 0x80000000;
- hose->mem_resources[0].end = 0xefffffff;
- hose->mem_resources[0].flags = IORESOURCE_MEM;
-
- if (u3_agp == NULL) {
- DBG("U3 has no AGP, using full resource range\n");
- return;
- }
-
- /* We "remove" the AGP resources from the resources allocated to HT, that
- * is we create "holes". However, that code does assumptions that so far
- * happen to be true (cross fingers...), typically that resources in the
- * AGP node are properly ordered
- */
- cur = 0;
- for (i=0; i<3; i++) {
- struct resource *res = &u3_agp->mem_resources[i];
- if (res->flags != IORESOURCE_MEM)
- continue;
- /* We don't care about "fine" resources */
- if (res->start >= 0xf0000000)
- continue;
- /* Check if it's just a matter of "shrinking" us in one direction */
- if (hose->mem_resources[cur].start == res->start) {
- DBG("U3/HT: shrink start of %d, %08lx -> %08lx\n",
- cur, hose->mem_resources[cur].start, res->end + 1);
- hose->mem_resources[cur].start = res->end + 1;
- continue;
- }
- if (hose->mem_resources[cur].end == res->end) {
- DBG("U3/HT: shrink end of %d, %08lx -> %08lx\n",
- cur, hose->mem_resources[cur].end, res->start - 1);
- hose->mem_resources[cur].end = res->start - 1;
- continue;
- }
- /* No, it's not the case, we need a hole */
- if (cur == 2) {
- /* not enough resources for a hole, we drop part of the range */
- printk(KERN_WARNING "Running out of resources for /ht host !\n");
- hose->mem_resources[cur].end = res->start - 1;
- continue;
- }
- cur++;
- DBG("U3/HT: hole, %d end at %08lx, %d start at %08lx\n",
- cur-1, res->start - 1, cur, res->end + 1);
- hose->mem_resources[cur].name = np->full_name;
- hose->mem_resources[cur].flags = IORESOURCE_MEM;
- hose->mem_resources[cur].start = res->end + 1;
- hose->mem_resources[cur].end = hose->mem_resources[cur-1].end;
- hose->mem_resources[cur-1].end = res->start - 1;
- }
-}
-
-static void __init pmac_process_bridge_OF_ranges(struct pci_controller *hose,
- struct device_node *dev, int primary)
-{
- static unsigned int static_lc_ranges[2024];
- unsigned int *dt_ranges, *lc_ranges, *ranges, *prev;
- unsigned int size;
- int rlen = 0, orig_rlen;
- int memno = 0;
- struct resource *res;
- int np, na = prom_n_addr_cells(dev);
-
- np = na + 5;
-
- /* First we try to merge ranges to fix a problem with some pmacs
- * that can have more than 3 ranges, fortunately using contiguous
- * addresses -- BenH
- */
- dt_ranges = (unsigned int *) get_property(dev, "ranges", &rlen);
- if (!dt_ranges)
- return;
- /* lc_ranges = alloc_bootmem(rlen);*/
- lc_ranges = static_lc_ranges;
- if (!lc_ranges)
- return; /* what can we do here ? */
- memcpy(lc_ranges, dt_ranges, rlen);
- orig_rlen = rlen;
-
- /* Let's work on a copy of the "ranges" property instead of damaging
- * the device-tree image in memory
- */
- ranges = lc_ranges;
- prev = NULL;
- while ((rlen -= np * sizeof(unsigned int)) >= 0) {
- if (prev) {
- if (prev[0] == ranges[0] && prev[1] == ranges[1] &&
- (prev[2] + prev[na+4]) == ranges[2] &&
- (prev[na+2] + prev[na+4]) == ranges[na+2]) {
- prev[na+4] += ranges[na+4];
- ranges[0] = 0;
- ranges += np;
- continue;
- }
- }
- prev = ranges;
- ranges += np;
- }
-
- /*
- * The ranges property is laid out as an array of elements,
- * each of which comprises:
- * cells 0 - 2: a PCI address
- * cells 3 or 3+4: a CPU physical address
- * (size depending on dev->n_addr_cells)
- * cells 4+5 or 5+6: the size of the range
- */
- ranges = lc_ranges;
- rlen = orig_rlen;
- while (ranges && (rlen -= np * sizeof(unsigned int)) >= 0) {
- res = NULL;
- size = ranges[na+4];
- switch (ranges[0] >> 24) {
- case 1: /* I/O space */
- if (ranges[2] != 0)
- break;
- hose->io_base_phys = ranges[na+2];
- /* limit I/O space to 16MB */
- if (size > 0x01000000)
- size = 0x01000000;
- hose->io_base_virt = ioremap(ranges[na+2], size);
- if (primary)
- isa_io_base = (unsigned long) hose->io_base_virt;
- res = &hose->io_resource;
- res->flags = IORESOURCE_IO;
- res->start = ranges[2];
- break;
- case 2: /* memory space */
- memno = 0;
- if (ranges[1] == 0 && ranges[2] == 0
- && ranges[na+4] <= (16 << 20)) {
- /* 1st 16MB, i.e. ISA memory area */
-#if 0
- if (primary)
- isa_mem_base = ranges[na+2];
-#endif
- memno = 1;
- }
- while (memno < 3 && hose->mem_resources[memno].flags)
- ++memno;
- if (memno == 0)
- hose->pci_mem_offset = ranges[na+2] - ranges[2];
- if (memno < 3) {
- res = &hose->mem_resources[memno];
- res->flags = IORESOURCE_MEM;
- res->start = ranges[na+2];
- }
- break;
- }
- if (res != NULL) {
- res->name = dev->full_name;
- res->end = res->start + size - 1;
- res->parent = NULL;
- res->sibling = NULL;
- res->child = NULL;
- }
- ranges += np;
- }
-}
-
-/*
- * We assume that if we have a G3 powermac, we have one bridge called
- * "pci" (a MPC106) and no bandit or chaos bridges, and contrariwise,
- * if we have one or more bandit or chaos bridges, we don't have a MPC106.
- */
-static int __init add_bridge(struct device_node *dev)
-{
- int len;
- struct pci_controller *hose;
- char* disp_name;
- int *bus_range;
- int primary = 1;
- struct property *of_prop;
-
- DBG("Adding PCI host bridge %s\n", dev->full_name);
-
- bus_range = (int *) get_property(dev, "bus-range", &len);
- if (bus_range == NULL || len < 2 * sizeof(int)) {
- printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n",
- dev->full_name);
- }
-
- hose = alloc_bootmem(sizeof(struct pci_controller));
- if (hose == NULL)
- return -ENOMEM;
- pci_setup_pci_controller(hose);
-
- hose->arch_data = dev;
- hose->first_busno = bus_range ? bus_range[0] : 0;
- hose->last_busno = bus_range ? bus_range[1] : 0xff;
-
- of_prop = alloc_bootmem(sizeof(struct property) +
- sizeof(hose->global_number));
- if (of_prop) {
- memset(of_prop, 0, sizeof(struct property));
- of_prop->name = "linux,pci-domain";
- of_prop->length = sizeof(hose->global_number);
- of_prop->value = (unsigned char *)&of_prop[1];
- memcpy(of_prop->value, &hose->global_number, sizeof(hose->global_number));
- prom_add_property(dev, of_prop);
- }
-
- disp_name = NULL;
- if (device_is_compatible(dev, "u3-agp")) {
- setup_u3_agp(hose);
- disp_name = "U3-AGP";
- primary = 0;
- } else if (device_is_compatible(dev, "u3-ht")) {
- setup_u3_ht(hose);
- disp_name = "U3-HT";
- primary = 1;
- }
- printk(KERN_INFO "Found %s PCI host bridge. Firmware bus number: %d->%d\n",
- disp_name, hose->first_busno, hose->last_busno);
-
- /* Interpret the "ranges" property */
- /* This also maps the I/O region and sets isa_io/mem_base */
- pmac_process_bridge_OF_ranges(hose, dev, primary);
-
- /* Fixup "bus-range" OF property */
- fixup_bus_range(dev);
-
- return 0;
-}
-
-/*
- * We use our own read_irq_line here because PCI_INTERRUPT_PIN is
- * crap on some of Apple ASICs. We unconditionally use the Open Firmware
- * interrupt number as this is always right.
- */
-static int pmac_pci_read_irq_line(struct pci_dev *pci_dev)
-{
- struct device_node *node;
-
- node = pci_device_to_OF_node(pci_dev);
- if (node == NULL)
- return -1;
- if (node->n_intrs == 0)
- return -1;
- pci_dev->irq = node->intrs[0].line;
- pci_write_config_byte(pci_dev, PCI_INTERRUPT_LINE, pci_dev->irq);
-
- return 0;
-}
-
-void __init pmac_pcibios_fixup(void)
-{
- struct pci_dev *dev = NULL;
-
- for_each_pci_dev(dev)
- pmac_pci_read_irq_line(dev);
-}
-
-static void __init pmac_fixup_phb_resources(void)
-{
- struct pci_controller *hose, *tmp;
-
- list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
- unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base;
- hose->io_resource.start += offset;
- hose->io_resource.end += offset;
- printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n",
- hose->global_number,
- hose->io_resource.start, hose->io_resource.end);
- }
-}
-
-void __init pmac_pci_init(void)
-{
- struct device_node *np, *root;
- struct device_node *ht = NULL;
-
- /* Probe root PCI hosts, that is on U3 the AGP host and the
- * HyperTransport host. That one is actually "kept" around
- * and actually added last as it's resource management relies
- * on the AGP resources to have been setup first
- */
- root = of_find_node_by_path("/");
- if (root == NULL) {
- printk(KERN_CRIT "pmac_find_bridges: can't find root of device tree\n");
- return;
- }
- for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) {
- if (np->name == NULL)
- continue;
- if (strcmp(np->name, "pci") == 0) {
- if (add_bridge(np) == 0)
- of_node_get(np);
- }
- if (strcmp(np->name, "ht") == 0) {
- of_node_get(np);
- ht = np;
- }
- }
- of_node_put(root);
-
- /* Now setup the HyperTransport host if we found any
- */
- if (ht && add_bridge(ht) != 0)
- of_node_put(ht);
-
- /* Fixup the IO resources on our host bridges as the common code
- * does it only for childs of the host bridges
- */
- pmac_fixup_phb_resources();
-
- /* Setup the linkage between OF nodes and PHBs */
- pci_devs_phb_init();
-
- /* Fixup the PCI<->OF mapping for U3 AGP due to bus renumbering. We
- * assume there is no P2P bridge on the AGP bus, which should be a
- * safe assumptions hopefully.
- */
- if (u3_agp) {
- struct device_node *np = u3_agp->arch_data;
- PCI_DN(np)->busno = 0xf0;
- for (np = np->child; np; np = np->sibling)
- PCI_DN(np)->busno = 0xf0;
- }
-
- pmac_check_ht_link();
-
- /* Tell pci.c to not use the common resource allocation mecanism */
- pci_probe_only = 1;
-
- /* Allow all IO */
- io_page_mask = -1;
-}
-
-/*
- * Disable second function on K2-SATA, it's broken
- * and disable IO BARs on first one
- */
-static void fixup_k2_sata(struct pci_dev* dev)
-{
- int i;
- u16 cmd;
-
- if (PCI_FUNC(dev->devfn) > 0) {
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
- pci_write_config_word(dev, PCI_COMMAND, cmd);
- for (i = 0; i < 6; i++) {
- dev->resource[i].start = dev->resource[i].end = 0;
- dev->resource[i].flags = 0;
- pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 0);
- }
- } else {
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- cmd &= ~PCI_COMMAND_IO;
- pci_write_config_word(dev, PCI_COMMAND, cmd);
- for (i = 0; i < 5; i++) {
- dev->resource[i].start = dev->resource[i].end = 0;
- dev->resource[i].flags = 0;
- pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 0);
- }
- }
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, 0x0240, fixup_k2_sata);
-
diff --git a/arch/ppc64/kernel/pmac_setup.c b/arch/ppc64/kernel/pmac_setup.c
deleted file mode 100644
index fa8121d53b89..000000000000
--- a/arch/ppc64/kernel/pmac_setup.c
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- * arch/ppc/platforms/setup.c
- *
- * PowerPC version
- * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
- *
- * Adapted for Power Macintosh by Paul Mackerras
- * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
- *
- * Derived from "arch/alpha/kernel/setup.c"
- * Copyright (C) 1995 Linus Torvalds
- *
- * Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.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.
- *
- */
-
-/*
- * bootup setup stuff..
- */
-
-#undef DEBUG
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/user.h>
-#include <linux/a.out.h>
-#include <linux/tty.h>
-#include <linux/string.h>
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/major.h>
-#include <linux/initrd.h>
-#include <linux/vt_kern.h>
-#include <linux/console.h>
-#include <linux/ide.h>
-#include <linux/pci.h>
-#include <linux/adb.h>
-#include <linux/cuda.h>
-#include <linux/pmu.h>
-#include <linux/irq.h>
-#include <linux/seq_file.h>
-#include <linux/root_dev.h>
-#include <linux/bitops.h>
-
-#include <asm/processor.h>
-#include <asm/sections.h>
-#include <asm/prom.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/pci-bridge.h>
-#include <asm/iommu.h>
-#include <asm/machdep.h>
-#include <asm/dma.h>
-#include <asm/btext.h>
-#include <asm/cputable.h>
-#include <asm/pmac_feature.h>
-#include <asm/time.h>
-#include <asm/of_device.h>
-#include <asm/lmb.h>
-#include <asm/smu.h>
-#include <asm/pmc.h>
-
-#include "pmac.h"
-#include "mpic.h"
-
-#ifdef DEBUG
-#define DBG(fmt...) udbg_printf(fmt)
-#else
-#define DBG(fmt...)
-#endif
-
-static int current_root_goodness = -1;
-#define DEFAULT_ROOT_DEVICE Root_SDA1 /* sda1 - slightly silly choice */
-
-extern int powersave_nap;
-int sccdbg;
-
-sys_ctrler_t sys_ctrler;
-EXPORT_SYMBOL(sys_ctrler);
-
-#ifdef CONFIG_PMAC_SMU
-unsigned long smu_cmdbuf_abs;
-EXPORT_SYMBOL(smu_cmdbuf_abs);
-#endif
-
-extern void udbg_init_scc(struct device_node *np);
-
-static void __pmac pmac_show_cpuinfo(struct seq_file *m)
-{
- struct device_node *np;
- char *pp;
- int plen;
- char* mbname;
- int mbmodel = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL,
- PMAC_MB_INFO_MODEL, 0);
- unsigned int mbflags = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL,
- PMAC_MB_INFO_FLAGS, 0);
-
- if (pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_NAME,
- (long)&mbname) != 0)
- mbname = "Unknown";
-
- /* find motherboard type */
- seq_printf(m, "machine\t\t: ");
- np = of_find_node_by_path("/");
- if (np != NULL) {
- pp = (char *) get_property(np, "model", NULL);
- if (pp != NULL)
- seq_printf(m, "%s\n", pp);
- else
- seq_printf(m, "PowerMac\n");
- pp = (char *) get_property(np, "compatible", &plen);
- if (pp != NULL) {
- seq_printf(m, "motherboard\t:");
- while (plen > 0) {
- int l = strlen(pp) + 1;
- seq_printf(m, " %s", pp);
- plen -= l;
- pp += l;
- }
- seq_printf(m, "\n");
- }
- of_node_put(np);
- } else
- seq_printf(m, "PowerMac\n");
-
- /* print parsed model */
- seq_printf(m, "detected as\t: %d (%s)\n", mbmodel, mbname);
- seq_printf(m, "pmac flags\t: %08x\n", mbflags);
-
- /* Indicate newworld */
- seq_printf(m, "pmac-generation\t: NewWorld\n");
-}
-
-
-static void __init pmac_setup_arch(void)
-{
- /* init to some ~sane value until calibrate_delay() runs */
- loops_per_jiffy = 50000000;
-
- /* Probe motherboard chipset */
- pmac_feature_init();
-#if 0
- /* Lock-enable the SCC channel used for debug */
- if (sccdbg) {
- np = of_find_node_by_name(NULL, "escc");
- if (np)
- pmac_call_feature(PMAC_FTR_SCC_ENABLE, np,
- PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1);
- }
-#endif
- /* We can NAP */
- powersave_nap = 1;
-
-#ifdef CONFIG_ADB_PMU
- /* Initialize the PMU if any */
- find_via_pmu();
-#endif
-#ifdef CONFIG_PMAC_SMU
- /* Initialize the SMU if any */
- smu_init();
-#endif
-
- /* Init NVRAM access */
- pmac_nvram_init();
-
- /* Setup SMP callback */
-#ifdef CONFIG_SMP
- pmac_setup_smp();
-#endif
-
- /* Lookup PCI hosts */
- pmac_pci_init();
-
-#ifdef CONFIG_DUMMY_CONSOLE
- conswitchp = &dummy_con;
-#endif
-
- printk(KERN_INFO "Using native/NAP idle loop\n");
-}
-
-#ifdef CONFIG_SCSI
-void note_scsi_host(struct device_node *node, void *host)
-{
- /* Obsolete */
-}
-#endif
-
-
-static int initializing = 1;
-
-static int pmac_late_init(void)
-{
- initializing = 0;
- return 0;
-}
-
-late_initcall(pmac_late_init);
-
-/* can't be __init - can be called whenever a disk is first accessed */
-void __pmac note_bootable_part(dev_t dev, int part, int goodness)
-{
- extern dev_t boot_dev;
- char *p;
-
- if (!initializing)
- return;
- if ((goodness <= current_root_goodness) &&
- ROOT_DEV != DEFAULT_ROOT_DEVICE)
- return;
- p = strstr(saved_command_line, "root=");
- if (p != NULL && (p == saved_command_line || p[-1] == ' '))
- return;
-
- if (!boot_dev || dev == boot_dev) {
- ROOT_DEV = dev + part;
- boot_dev = 0;
- current_root_goodness = goodness;
- }
-}
-
-static void __pmac pmac_restart(char *cmd)
-{
- switch(sys_ctrler) {
-#ifdef CONFIG_ADB_PMU
- case SYS_CTRLER_PMU:
- pmu_restart();
- break;
-#endif
-
-#ifdef CONFIG_PMAC_SMU
- case SYS_CTRLER_SMU:
- smu_restart();
- break;
-#endif
- default:
- ;
- }
-}
-
-static void __pmac pmac_power_off(void)
-{
- switch(sys_ctrler) {
-#ifdef CONFIG_ADB_PMU
- case SYS_CTRLER_PMU:
- pmu_shutdown();
- break;
-#endif
-#ifdef CONFIG_PMAC_SMU
- case SYS_CTRLER_SMU:
- smu_shutdown();
- break;
-#endif
- default:
- ;
- }
-}
-
-static void __pmac pmac_halt(void)
-{
- pmac_power_off();
-}
-
-#ifdef CONFIG_BOOTX_TEXT
-static void btext_putc(unsigned char c)
-{
- btext_drawchar(c);
-}
-
-static void __init init_boot_display(void)
-{
- char *name;
- struct device_node *np = NULL;
- int rc = -ENODEV;
-
- printk("trying to initialize btext ...\n");
-
- name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
- if (name != NULL) {
- np = of_find_node_by_path(name);
- if (np != NULL) {
- if (strcmp(np->type, "display") != 0) {
- printk("boot stdout isn't a display !\n");
- of_node_put(np);
- np = NULL;
- }
- }
- }
- if (np)
- rc = btext_initialize(np);
- if (rc == 0)
- return;
-
- for (np = NULL; (np = of_find_node_by_type(np, "display"));) {
- if (get_property(np, "linux,opened", NULL)) {
- printk("trying %s ...\n", np->full_name);
- rc = btext_initialize(np);
- printk("result: %d\n", rc);
- }
- if (rc == 0)
- return;
- }
-}
-#endif /* CONFIG_BOOTX_TEXT */
-
-/*
- * Early initialization.
- */
-static void __init pmac_init_early(void)
-{
- DBG(" -> pmac_init_early\n");
-
- /* Initialize hash table, from now on, we can take hash faults
- * and call ioremap
- */
- hpte_init_native();
-
- /* Init SCC */
- if (strstr(cmd_line, "sccdbg")) {
- sccdbg = 1;
- udbg_init_scc(NULL);
- }
-#ifdef CONFIG_BOOTX_TEXT
- else {
- init_boot_display();
-
- udbg_putc = btext_putc;
- }
-#endif /* CONFIG_BOOTX_TEXT */
-
- /* Setup interrupt mapping options */
- ppc64_interrupt_controller = IC_OPEN_PIC;
-
- iommu_init_early_u3();
-
- DBG(" <- pmac_init_early\n");
-}
-
-static int pmac_u3_cascade(struct pt_regs *regs, void *data)
-{
- return mpic_get_one_irq((struct mpic *)data, regs);
-}
-
-static __init void pmac_init_IRQ(void)
-{
- struct device_node *irqctrler = NULL;
- struct device_node *irqctrler2 = NULL;
- struct device_node *np = NULL;
- struct mpic *mpic1, *mpic2;
-
- /* We first try to detect Apple's new Core99 chipset, since mac-io
- * is quite different on those machines and contains an IBM MPIC2.
- */
- while ((np = of_find_node_by_type(np, "open-pic")) != NULL) {
- struct device_node *parent = of_get_parent(np);
- if (parent && !strcmp(parent->name, "u3"))
- irqctrler2 = of_node_get(np);
- else
- irqctrler = of_node_get(np);
- of_node_put(parent);
- }
- if (irqctrler != NULL && irqctrler->n_addrs > 0) {
- unsigned char senses[128];
-
- printk(KERN_INFO "PowerMac using OpenPIC irq controller at 0x%08x\n",
- (unsigned int)irqctrler->addrs[0].address);
-
- prom_get_irq_senses(senses, 0, 128);
- mpic1 = mpic_alloc(irqctrler->addrs[0].address,
- MPIC_PRIMARY | MPIC_WANTS_RESET,
- 0, 0, 128, 256, senses, 128, " K2-MPIC ");
- BUG_ON(mpic1 == NULL);
- mpic_init(mpic1);
-
- if (irqctrler2 != NULL && irqctrler2->n_intrs > 0 &&
- irqctrler2->n_addrs > 0) {
- printk(KERN_INFO "Slave OpenPIC at 0x%08x hooked on IRQ %d\n",
- (u32)irqctrler2->addrs[0].address,
- irqctrler2->intrs[0].line);
-
- pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler2, 0, 0);
- prom_get_irq_senses(senses, 128, 128 + 128);
-
- /* We don't need to set MPIC_BROKEN_U3 here since we don't have
- * hypertransport interrupts routed to it
- */
- mpic2 = mpic_alloc(irqctrler2->addrs[0].address,
- MPIC_BIG_ENDIAN | MPIC_WANTS_RESET,
- 0, 128, 128, 0, senses, 128, " U3-MPIC ");
- BUG_ON(mpic2 == NULL);
- mpic_init(mpic2);
- mpic_setup_cascade(irqctrler2->intrs[0].line,
- pmac_u3_cascade, mpic2);
- }
- }
- of_node_put(irqctrler);
- of_node_put(irqctrler2);
-}
-
-static void __init pmac_progress(char *s, unsigned short hex)
-{
- if (sccdbg) {
- udbg_puts(s);
- udbg_puts("\n");
- }
-#ifdef CONFIG_BOOTX_TEXT
- else if (boot_text_mapped) {
- btext_drawstring(s);
- btext_drawstring("\n");
- }
-#endif /* CONFIG_BOOTX_TEXT */
-}
-
-/*
- * pmac has no legacy IO, anything calling this function has to
- * fail or bad things will happen
- */
-static int pmac_check_legacy_ioport(unsigned int baseport)
-{
- return -ENODEV;
-}
-
-static int __init pmac_declare_of_platform_devices(void)
-{
- struct device_node *np, *npp;
-
- npp = of_find_node_by_name(NULL, "u3");
- if (npp) {
- for (np = NULL; (np = of_get_next_child(npp, np)) != NULL;) {
- if (strncmp(np->name, "i2c", 3) == 0) {
- of_platform_device_create(np, "u3-i2c", NULL);
- of_node_put(np);
- break;
- }
- }
- of_node_put(npp);
- }
- npp = of_find_node_by_type(NULL, "smu");
- if (npp) {
- of_platform_device_create(npp, "smu", NULL);
- of_node_put(npp);
- }
-
- return 0;
-}
-
-device_initcall(pmac_declare_of_platform_devices);
-
-/*
- * Called very early, MMU is off, device-tree isn't unflattened
- */
-static int __init pmac_probe(int platform)
-{
- if (platform != PLATFORM_POWERMAC)
- return 0;
- /*
- * On U3, the DART (iommu) must be allocated now since it
- * has an impact on htab_initialize (due to the large page it
- * occupies having to be broken up so the DART itself is not
- * part of the cacheable linar mapping
- */
- alloc_u3_dart_table();
-
-#ifdef CONFIG_PMAC_SMU
- /*
- * SMU based G5s need some memory below 2Gb, at least the current
- * driver needs that. We have to allocate it now. We allocate 4k
- * (1 small page) for now.
- */
- smu_cmdbuf_abs = lmb_alloc_base(4096, 4096, 0x80000000UL);
-#endif /* CONFIG_PMAC_SMU */
-
- return 1;
-}
-
-static int pmac_probe_mode(struct pci_bus *bus)
-{
- struct device_node *node = bus->sysdata;
-
- /* We need to use normal PCI probing for the AGP bus,
- since the device for the AGP bridge isn't in the tree. */
- if (bus->self == NULL && device_is_compatible(node, "u3-agp"))
- return PCI_PROBE_NORMAL;
-
- return PCI_PROBE_DEVTREE;
-}
-
-struct machdep_calls __initdata pmac_md = {
-#ifdef CONFIG_HOTPLUG_CPU
- .cpu_die = generic_mach_cpu_die,
-#endif
- .probe = pmac_probe,
- .setup_arch = pmac_setup_arch,
- .init_early = pmac_init_early,
- .get_cpuinfo = pmac_show_cpuinfo,
- .init_IRQ = pmac_init_IRQ,
- .get_irq = mpic_get_irq,
- .pcibios_fixup = pmac_pcibios_fixup,
- .pci_probe_mode = pmac_probe_mode,
- .restart = pmac_restart,
- .power_off = pmac_power_off,
- .halt = pmac_halt,
- .get_boot_time = pmac_get_boot_time,
- .set_rtc_time = pmac_set_rtc_time,
- .get_rtc_time = pmac_get_rtc_time,
- .calibrate_decr = pmac_calibrate_decr,
- .feature_call = pmac_do_feature_call,
- .progress = pmac_progress,
- .check_legacy_ioport = pmac_check_legacy_ioport,
- .idle_loop = native_idle,
- .enable_pmcs = power4_enable_pmcs,
-};
diff --git a/arch/ppc64/kernel/pmac_smp.c b/arch/ppc64/kernel/pmac_smp.c
deleted file mode 100644
index a23de37227bf..000000000000
--- a/arch/ppc64/kernel/pmac_smp.c
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
- * SMP support for power macintosh.
- *
- * We support both the old "powersurge" SMP architecture
- * and the current Core99 (G4 PowerMac) machines.
- *
- * Note that we don't support the very first rev. of
- * Apple/DayStar 2 CPUs board, the one with the funky
- * watchdog. Hopefully, none of these should be there except
- * maybe internally to Apple. I should probably still add some
- * code to detect this card though and disable SMP. --BenH.
- *
- * Support Macintosh G4 SMP by Troy Benjegerdes (hozer@drgw.net)
- * and Ben Herrenschmidt <benh@kernel.crashing.org>.
- *
- * Support for DayStar quad CPU cards
- * Copyright (C) XLR8, Inc. 1994-2000
- *
- * This program is free software; you can redistribute 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.
- */
-
-#undef DEBUG
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/errno.h>
-#include <linux/irq.h>
-
-#include <asm/ptrace.h>
-#include <asm/atomic.h>
-#include <asm/irq.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/sections.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/smp.h>
-#include <asm/machdep.h>
-#include <asm/pmac_feature.h>
-#include <asm/time.h>
-#include <asm/cacheflush.h>
-#include <asm/keylargo.h>
-#include <asm/pmac_low_i2c.h>
-
-#include "mpic.h"
-
-#ifdef DEBUG
-#define DBG(fmt...) udbg_printf(fmt)
-#else
-#define DBG(fmt...)
-#endif
-
-extern void pmac_secondary_start_1(void);
-extern void pmac_secondary_start_2(void);
-extern void pmac_secondary_start_3(void);
-
-extern struct smp_ops_t *smp_ops;
-
-static void (*pmac_tb_freeze)(int freeze);
-static struct device_node *pmac_tb_clock_chip_host;
-static u8 pmac_tb_pulsar_addr;
-static DEFINE_SPINLOCK(timebase_lock);
-static unsigned long timebase;
-
-static void smp_core99_cypress_tb_freeze(int freeze)
-{
- u8 data;
- int rc;
-
- /* Strangely, the device-tree says address is 0xd2, but darwin
- * accesses 0xd0 ...
- */
- pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined);
- rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
- 0xd0 | pmac_low_i2c_read,
- 0x81, &data, 1);
- if (rc != 0)
- goto bail;
-
- data = (data & 0xf3) | (freeze ? 0x00 : 0x0c);
-
- pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub);
- rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
- 0xd0 | pmac_low_i2c_write,
- 0x81, &data, 1);
-
- bail:
- if (rc != 0) {
- printk("Cypress Timebase %s rc: %d\n",
- freeze ? "freeze" : "unfreeze", rc);
- panic("Timebase freeze failed !\n");
- }
-}
-
-static void smp_core99_pulsar_tb_freeze(int freeze)
-{
- u8 data;
- int rc;
-
- pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined);
- rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
- pmac_tb_pulsar_addr | pmac_low_i2c_read,
- 0x2e, &data, 1);
- if (rc != 0)
- goto bail;
-
- data = (data & 0x88) | (freeze ? 0x11 : 0x22);
-
- pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub);
- rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
- pmac_tb_pulsar_addr | pmac_low_i2c_write,
- 0x2e, &data, 1);
- bail:
- if (rc != 0) {
- printk(KERN_ERR "Pulsar Timebase %s rc: %d\n",
- freeze ? "freeze" : "unfreeze", rc);
- panic("Timebase freeze failed !\n");
- }
-}
-
-
-static void smp_core99_give_timebase(void)
-{
- /* Open i2c bus for synchronous access */
- if (pmac_low_i2c_open(pmac_tb_clock_chip_host, 0))
- panic("Can't open i2c for TB sync !\n");
-
- spin_lock(&timebase_lock);
- (*pmac_tb_freeze)(1);
- mb();
- timebase = get_tb();
- spin_unlock(&timebase_lock);
-
- while (timebase)
- barrier();
-
- spin_lock(&timebase_lock);
- (*pmac_tb_freeze)(0);
- spin_unlock(&timebase_lock);
-
- /* Close i2c bus */
- pmac_low_i2c_close(pmac_tb_clock_chip_host);
-}
-
-
-static void __devinit smp_core99_take_timebase(void)
-{
- while (!timebase)
- barrier();
- spin_lock(&timebase_lock);
- set_tb(timebase >> 32, timebase & 0xffffffff);
- timebase = 0;
- spin_unlock(&timebase_lock);
-}
-
-
-static int __init smp_core99_probe(void)
-{
- struct device_node *cpus;
- struct device_node *cc;
- int ncpus = 0;
-
- /* Maybe use systemconfiguration here ? */
- if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345);
-
- /* Count CPUs in the device-tree */
- for (cpus = NULL; (cpus = of_find_node_by_type(cpus, "cpu")) != NULL;)
- ++ncpus;
-
- printk(KERN_INFO "PowerMac SMP probe found %d cpus\n", ncpus);
-
- /* Nothing more to do if less than 2 of them */
- if (ncpus <= 1)
- return 1;
-
- /* HW sync only on these platforms */
- if (!machine_is_compatible("PowerMac7,2") &&
- !machine_is_compatible("PowerMac7,3") &&
- !machine_is_compatible("RackMac3,1"))
- goto nohwsync;
-
- /* Look for the clock chip */
- for (cc = NULL; (cc = of_find_node_by_name(cc, "i2c-hwclock")) != NULL;) {
- struct device_node *p = of_get_parent(cc);
- u32 *reg;
- int ok;
- ok = p && device_is_compatible(p, "uni-n-i2c");
- if (!ok)
- goto next;
- reg = (u32 *)get_property(cc, "reg", NULL);
- if (reg == NULL)
- goto next;
- switch (*reg) {
- case 0xd2:
- if (device_is_compatible(cc, "pulsar-legacy-slewing")) {
- pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
- pmac_tb_pulsar_addr = 0xd2;
- printk(KERN_INFO "Timebase clock is Pulsar chip\n");
- } else if (device_is_compatible(cc, "cy28508")) {
- pmac_tb_freeze = smp_core99_cypress_tb_freeze;
- printk(KERN_INFO "Timebase clock is Cypress chip\n");
- }
- break;
- case 0xd4:
- pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
- pmac_tb_pulsar_addr = 0xd4;
- printk(KERN_INFO "Timebase clock is Pulsar chip\n");
- break;
- }
- if (pmac_tb_freeze != NULL) {
- pmac_tb_clock_chip_host = p;
- smp_ops->give_timebase = smp_core99_give_timebase;
- smp_ops->take_timebase = smp_core99_take_timebase;
- of_node_put(cc);
- of_node_put(p);
- break;
- }
- next:
- of_node_put(p);
- }
-
- nohwsync:
- mpic_request_ipis();
-
- return ncpus;
-}
-
-static void __init smp_core99_kick_cpu(int nr)
-{
- int save_vector, j;
- unsigned long new_vector;
- unsigned long flags;
- volatile unsigned int *vector
- = ((volatile unsigned int *)(KERNELBASE+0x100));
-
- if (nr < 1 || nr > 3)
- return;
- if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu", 0x346);
-
- local_irq_save(flags);
- local_irq_disable();
-
- /* Save reset vector */
- save_vector = *vector;
-
- /* Setup fake reset vector that does
- * b .pmac_secondary_start - KERNELBASE
- */
- switch(nr) {
- case 1:
- new_vector = (unsigned long)pmac_secondary_start_1;
- break;
- case 2:
- new_vector = (unsigned long)pmac_secondary_start_2;
- break;
- case 3:
- default:
- new_vector = (unsigned long)pmac_secondary_start_3;
- break;
- }
- *vector = 0x48000002 + (new_vector - KERNELBASE);
-
- /* flush data cache and inval instruction cache */
- flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);
-
- /* Put some life in our friend */
- pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0);
- paca[nr].cpu_start = 1;
-
- /* FIXME: We wait a bit for the CPU to take the exception, I should
- * instead wait for the entry code to set something for me. Well,
- * ideally, all that crap will be done in prom.c and the CPU left
- * in a RAM-based wait loop like CHRP.
- */
- for (j = 1; j < 1000000; j++)
- mb();
-
- /* Restore our exception vector */
- *vector = save_vector;
- flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);
-
- local_irq_restore(flags);
- if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu done", 0x347);
-}
-
-static void __init smp_core99_setup_cpu(int cpu_nr)
-{
- /* Setup MPIC */
- mpic_setup_this_cpu();
-
- if (cpu_nr == 0) {
- extern void g5_phy_disable_cpu1(void);
-
- /* If we didn't start the second CPU, we must take
- * it off the bus
- */
- if (num_online_cpus() < 2)
- g5_phy_disable_cpu1();
- if (ppc_md.progress) ppc_md.progress("smp_core99_setup_cpu 0 done", 0x349);
- }
-}
-
-struct smp_ops_t core99_smp_ops __pmacdata = {
- .message_pass = smp_mpic_message_pass,
- .probe = smp_core99_probe,
- .kick_cpu = smp_core99_kick_cpu,
- .setup_cpu = smp_core99_setup_cpu,
- .give_timebase = smp_generic_give_timebase,
- .take_timebase = smp_generic_take_timebase,
-};
-
-void __init pmac_setup_smp(void)
-{
- smp_ops = &core99_smp_ops;
-#ifdef CONFIG_HOTPLUG_CPU
- smp_ops->cpu_enable = generic_cpu_enable;
- smp_ops->cpu_disable = generic_cpu_disable;
- smp_ops->cpu_die = generic_cpu_die;
-#endif
-}
diff --git a/arch/ppc64/kernel/pmac_time.c b/arch/ppc64/kernel/pmac_time.c
deleted file mode 100644
index 41bbb8c59697..000000000000
--- a/arch/ppc64/kernel/pmac_time.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Support for periodic interrupts (100 per second) and for getting
- * the current time from the RTC on Power Macintoshes.
- *
- * We use the decrementer register for our periodic interrupts.
- *
- * Paul Mackerras August 1996.
- * Copyright (C) 1996 Paul Mackerras.
- * Copyright (C) 2003-2005 Benjamin Herrenschmidt.
- *
- */
-#include <linux/config.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/time.h>
-#include <linux/adb.h>
-#include <linux/pmu.h>
-#include <linux/interrupt.h>
-
-#include <asm/sections.h>
-#include <asm/prom.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/machdep.h>
-#include <asm/time.h>
-#include <asm/nvram.h>
-#include <asm/smu.h>
-
-#undef DEBUG
-
-#ifdef DEBUG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-/* Apparently the RTC stores seconds since 1 Jan 1904 */
-#define RTC_OFFSET 2082844800
-
-/*
- * Calibrate the decrementer frequency with the VIA timer 1.
- */
-#define VIA_TIMER_FREQ_6 4700000 /* time 1 frequency * 6 */
-
-extern struct timezone sys_tz;
-extern void to_tm(int tim, struct rtc_time * tm);
-
-void __pmac pmac_get_rtc_time(struct rtc_time *tm)
-{
- switch(sys_ctrler) {
-#ifdef CONFIG_ADB_PMU
- case SYS_CTRLER_PMU: {
- /* TODO: Move that to a function in the PMU driver */
- struct adb_request req;
- unsigned int now;
-
- if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0)
- return;
- pmu_wait_complete(&req);
- if (req.reply_len != 4)
- printk(KERN_ERR "pmac_get_rtc_time: PMU returned a %d"
- " bytes reply\n", req.reply_len);
- now = (req.reply[0] << 24) + (req.reply[1] << 16)
- + (req.reply[2] << 8) + req.reply[3];
- DBG("get: %u -> %u\n", (int)now, (int)(now - RTC_OFFSET));
- now -= RTC_OFFSET;
-
- to_tm(now, tm);
- tm->tm_year -= 1900;
- tm->tm_mon -= 1;
-
- DBG("-> tm_mday: %d, tm_mon: %d, tm_year: %d, %d:%02d:%02d\n",
- tm->tm_mday, tm->tm_mon, tm->tm_year,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
- break;
- }
-#endif /* CONFIG_ADB_PMU */
-
-#ifdef CONFIG_PMAC_SMU
- case SYS_CTRLER_SMU:
- smu_get_rtc_time(tm, 1);
- break;
-#endif /* CONFIG_PMAC_SMU */
- default:
- ;
- }
-}
-
-int __pmac pmac_set_rtc_time(struct rtc_time *tm)
-{
- switch(sys_ctrler) {
-#ifdef CONFIG_ADB_PMU
- case SYS_CTRLER_PMU: {
- /* TODO: Move that to a function in the PMU driver */
- struct adb_request req;
- unsigned int nowtime;
-
- DBG("set: tm_mday: %d, tm_mon: %d, tm_year: %d,"
- " %d:%02d:%02d\n",
- tm->tm_mday, tm->tm_mon, tm->tm_year,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
-
- nowtime = mktime(tm->tm_year + 1900, tm->tm_mon + 1,
- tm->tm_mday, tm->tm_hour, tm->tm_min,
- tm->tm_sec);
-
- DBG("-> %u -> %u\n", (int)nowtime,
- (int)(nowtime + RTC_OFFSET));
- nowtime += RTC_OFFSET;
-
- if (pmu_request(&req, NULL, 5, PMU_SET_RTC,
- nowtime >> 24, nowtime >> 16,
- nowtime >> 8, nowtime) < 0)
- return -ENXIO;
- pmu_wait_complete(&req);
- if (req.reply_len != 0)
- printk(KERN_ERR "pmac_set_rtc_time: PMU returned a %d"
- " bytes reply\n", req.reply_len);
- return 0;
- }
-#endif /* CONFIG_ADB_PMU */
-
-#ifdef CONFIG_PMAC_SMU
- case SYS_CTRLER_SMU:
- return smu_set_rtc_time(tm, 1);
-#endif /* CONFIG_PMAC_SMU */
- default:
- return -ENODEV;
- }
-}
-
-void __init pmac_get_boot_time(struct rtc_time *tm)
-{
- pmac_get_rtc_time(tm);
-
-#ifdef disabled__CONFIG_NVRAM
- s32 delta = 0;
- int dst;
-
- delta = ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x9)) << 16;
- delta |= ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xa)) << 8;
- delta |= pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xb);
- if (delta & 0x00800000UL)
- delta |= 0xFF000000UL;
- dst = ((pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x8) & 0x80) != 0);
- printk("GMT Delta read from XPRAM: %d minutes, DST: %s\n", delta/60,
- dst ? "on" : "off");
-#endif
-}
-
-/*
- * Query the OF and get the decr frequency.
- * FIXME: merge this with generic_calibrate_decr
- */
-void __init pmac_calibrate_decr(void)
-{
- struct device_node *cpu;
- unsigned int freq, *fp;
- struct div_result divres;
-
- /*
- * The cpu node should have a timebase-frequency property
- * to tell us the rate at which the decrementer counts.
- */
- cpu = find_type_devices("cpu");
- if (cpu == 0)
- panic("can't find cpu node in time_init");
- fp = (unsigned int *) get_property(cpu, "timebase-frequency", NULL);
- if (fp == 0)
- panic("can't get cpu timebase frequency");
- freq = *fp;
- printk("time_init: decrementer frequency = %u.%.6u MHz\n",
- freq/1000000, freq%1000000);
- tb_ticks_per_jiffy = freq / HZ;
- tb_ticks_per_sec = tb_ticks_per_jiffy * HZ;
- tb_ticks_per_usec = freq / 1000000;
- tb_to_us = mulhwu_scale_factor(freq, 1000000);
- div128_by_32( 1024*1024, 0, tb_ticks_per_sec, &divres );
- tb_to_xs = divres.result_low;
- ppc_tb_freq = freq;
-
- fp = (unsigned int *)get_property(cpu, "clock-frequency", NULL);
- if (fp == 0)
- panic("can't get cpu processor frequency");
- ppc_proc_freq = *fp;
-
- setup_default_decr();
-}
-
diff --git a/arch/ppc64/kernel/ppc_ksyms.c b/arch/ppc64/kernel/ppc_ksyms.c
index 705742f4eec6..84006e26342c 100644
--- a/arch/ppc64/kernel/ppc_ksyms.c
+++ b/arch/ppc64/kernel/ppc_ksyms.c
@@ -19,7 +19,6 @@
#include <asm/hw_irq.h>
#include <asm/abs_addr.h>
#include <asm/cacheflush.h>
-#include <asm/iSeries/HvCallSc.h>
EXPORT_SYMBOL(strcpy);
EXPORT_SYMBOL(strncpy);
@@ -46,17 +45,6 @@ EXPORT_SYMBOL(__strnlen_user);
EXPORT_SYMBOL(reloc_offset);
-#ifdef CONFIG_PPC_ISERIES
-EXPORT_SYMBOL(HvCall0);
-EXPORT_SYMBOL(HvCall1);
-EXPORT_SYMBOL(HvCall2);
-EXPORT_SYMBOL(HvCall3);
-EXPORT_SYMBOL(HvCall4);
-EXPORT_SYMBOL(HvCall5);
-EXPORT_SYMBOL(HvCall6);
-EXPORT_SYMBOL(HvCall7);
-#endif
-
EXPORT_SYMBOL(_insb);
EXPORT_SYMBOL(_outsb);
EXPORT_SYMBOL(_insw);
@@ -77,14 +65,6 @@ EXPORT_SYMBOL(giveup_altivec);
EXPORT_SYMBOL(__flush_icache_range);
EXPORT_SYMBOL(flush_dcache_range);
-#ifdef CONFIG_SMP
-#ifdef CONFIG_PPC_ISERIES
-EXPORT_SYMBOL(local_get_flags);
-EXPORT_SYMBOL(local_irq_disable);
-EXPORT_SYMBOL(local_irq_restore);
-#endif
-#endif
-
EXPORT_SYMBOL(memcpy);
EXPORT_SYMBOL(memset);
EXPORT_SYMBOL(memmove);
diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c
index 7035deb6de92..97bfceb5353b 100644
--- a/arch/ppc64/kernel/prom.c
+++ b/arch/ppc64/kernel/prom.c
@@ -46,7 +46,6 @@
#include <asm/pgtable.h>
#include <asm/pci.h>
#include <asm/iommu.h>
-#include <asm/bootinfo.h>
#include <asm/ppcdebug.h>
#include <asm/btext.h>
#include <asm/sections.h>
@@ -78,11 +77,14 @@ typedef int interpret_func(struct device_node *, unsigned long *,
extern struct rtas_t rtas;
extern struct lmb lmb;
extern unsigned long klimit;
+extern unsigned long memory_limit;
static int __initdata dt_root_addr_cells;
static int __initdata dt_root_size_cells;
static int __initdata iommu_is_off;
int __initdata iommu_force_on;
+unsigned long tce_alloc_start, tce_alloc_end;
+
typedef u32 cell_t;
#if 0
@@ -1063,7 +1065,6 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
{
u32 *prop;
u64 *prop64;
- extern unsigned long memory_limit, tce_alloc_start, tce_alloc_end;
DBG("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
@@ -1237,7 +1238,7 @@ void __init early_init_devtree(void *params)
lmb_init();
scan_flat_dt(early_init_dt_scan_root, NULL);
scan_flat_dt(early_init_dt_scan_memory, NULL);
- lmb_enforce_memory_limit();
+ lmb_enforce_memory_limit(memory_limit);
lmb_analyze();
systemcfg->physicalMemorySize = lmb_phys_mem_size();
lmb_reserve(0, __pa(klimit));
diff --git a/arch/ppc64/kernel/prom_init.c b/arch/ppc64/kernel/prom_init.c
index f252670874a4..69924ba4d7d9 100644
--- a/arch/ppc64/kernel/prom_init.c
+++ b/arch/ppc64/kernel/prom_init.c
@@ -44,7 +44,6 @@
#include <asm/pgtable.h>
#include <asm/pci.h>
#include <asm/iommu.h>
-#include <asm/bootinfo.h>
#include <asm/ppcdebug.h>
#include <asm/btext.h>
#include <asm/sections.h>
diff --git a/arch/ppc64/kernel/ptrace.c b/arch/ppc64/kernel/ptrace.c
deleted file mode 100644
index b1c044ca5756..000000000000
--- a/arch/ppc64/kernel/ptrace.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * linux/arch/ppc64/kernel/ptrace.c
- *
- * PowerPC version
- * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
- *
- * Derived from "arch/m68k/kernel/ptrace.c"
- * Copyright (C) 1994 by Hamish Macdonald
- * Taken from linux/kernel/ptrace.c and modified for M680x0.
- * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
- *
- * Modified by Cort Dougan (cort@hq.fsmlabs.com)
- * and Paul Mackerras (paulus@linuxcare.com.au).
- *
- * This file is subject to the terms and conditions of the GNU General
- * Public License. See the file README.legal in the main directory of
- * this archive for more details.
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/errno.h>
-#include <linux/ptrace.h>
-#include <linux/user.h>
-#include <linux/security.h>
-#include <linux/audit.h>
-#include <linux/seccomp.h>
-#include <linux/signal.h>
-
-#include <asm/uaccess.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/system.h>
-#include <asm/ptrace-common.h>
-
-/*
- * does not yet catch signals sent when the child dies.
- * in exit.c or in signal.c.
- */
-
-/*
- * Called by kernel/ptrace.c when detaching..
- *
- * Make sure single step bits etc are not set.
- */
-void ptrace_disable(struct task_struct *child)
-{
- /* make sure the single step bit is not set. */
- clear_single_step(child);
-}
-
-int sys_ptrace(long request, long pid, long addr, long data)
-{
- struct task_struct *child;
- int ret = -EPERM;
-
- lock_kernel();
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED)
- goto out;
- ret = security_ptrace(current->parent, current);
- if (ret)
- goto out;
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- ret = 0;
- goto out;
- }
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
- if (!child)
- goto out;
-
- ret = -EPERM;
- if (pid == 1) /* you may not mess with init */
- goto out_tsk;
-
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
- switch (request) {
- /* when I and D space are separate, these will need to be fixed. */
- case PTRACE_PEEKTEXT: /* read word at location addr. */
- case PTRACE_PEEKDATA: {
- unsigned long tmp;
- int copied;
-
- copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
- ret = -EIO;
- if (copied != sizeof(tmp))
- break;
- ret = put_user(tmp,(unsigned long __user *) data);
- break;
- }
-
- /* read the word at location addr in the USER area. */
- case PTRACE_PEEKUSR: {
- unsigned long index;
- unsigned long tmp;
-
- ret = -EIO;
- /* convert to index and check */
- index = (unsigned long) addr >> 3;
- if ((addr & 7) || (index > PT_FPSCR))
- break;
-
- if (index < PT_FPR0) {
- tmp = get_reg(child, (int)index);
- } else {
- flush_fp_to_thread(child);
- tmp = ((unsigned long *)child->thread.fpr)[index - PT_FPR0];
- }
- ret = put_user(tmp,(unsigned long __user *) data);
- break;
- }
-
- /* If I and D space are separate, this will have to be fixed. */
- case PTRACE_POKETEXT: /* write the word at location addr. */
- case PTRACE_POKEDATA:
- ret = 0;
- if (access_process_vm(child, addr, &data, sizeof(data), 1)
- == sizeof(data))
- break;
- ret = -EIO;
- break;
-
- /* write the word at location addr in the USER area */
- case PTRACE_POKEUSR: {
- unsigned long index;
-
- ret = -EIO;
- /* convert to index and check */
- index = (unsigned long) addr >> 3;
- if ((addr & 7) || (index > PT_FPSCR))
- break;
-
- if (index == PT_ORIG_R3)
- break;
- if (index < PT_FPR0) {
- ret = put_reg(child, index, data);
- } else {
- flush_fp_to_thread(child);
- ((unsigned long *)child->thread.fpr)[index - PT_FPR0] = data;
- ret = 0;
- }
- break;
- }
-
- case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
- case PTRACE_CONT: { /* restart after signal. */
- ret = -EIO;
- if (!valid_signal(data))
- break;
- if (request == PTRACE_SYSCALL)
- set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- else
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- child->exit_code = data;
- /* make sure the single step bit is not set. */
- clear_single_step(child);
- wake_up_process(child);
- ret = 0;
- break;
- }
-
- /*
- * make the child exit. Best I can do is send it a sigkill.
- * perhaps it should be put in the status that it wants to
- * exit.
- */
- case PTRACE_KILL: {
- ret = 0;
- if (child->exit_state == EXIT_ZOMBIE) /* already dead */
- break;
- child->exit_code = SIGKILL;
- /* make sure the single step bit is not set. */
- clear_single_step(child);
- wake_up_process(child);
- break;
- }
-
- case PTRACE_SINGLESTEP: { /* set the trap flag. */
- ret = -EIO;
- if (!valid_signal(data))
- break;
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- set_single_step(child);
- child->exit_code = data;
- /* give it a chance to run. */
- wake_up_process(child);
- ret = 0;
- break;
- }
-
- case PTRACE_GET_DEBUGREG: {
- ret = -EINVAL;
- /* We only support one DABR and no IABRS at the moment */
- if (addr > 0)
- break;
- ret = put_user(child->thread.dabr,
- (unsigned long __user *)data);
- break;
- }
-
- case PTRACE_SET_DEBUGREG:
- ret = ptrace_set_debugreg(child, addr, data);
- break;
-
- case PTRACE_DETACH:
- ret = ptrace_detach(child, data);
- break;
-
- case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */
- int i;
- unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
- unsigned long __user *tmp = (unsigned long __user *)addr;
-
- for (i = 0; i < 32; i++) {
- ret = put_user(*reg, tmp);
- if (ret)
- break;
- reg++;
- tmp++;
- }
- break;
- }
-
- case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */
- int i;
- unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
- unsigned long __user *tmp = (unsigned long __user *)addr;
-
- for (i = 0; i < 32; i++) {
- ret = get_user(*reg, tmp);
- if (ret)
- break;
- reg++;
- tmp++;
- }
- break;
- }
-
- case PPC_PTRACE_GETFPREGS: { /* Get FPRs 0 - 31. */
- int i;
- unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
- unsigned long __user *tmp = (unsigned long __user *)addr;
-
- flush_fp_to_thread(child);
-
- for (i = 0; i < 32; i++) {
- ret = put_user(*reg, tmp);
- if (ret)
- break;
- reg++;
- tmp++;
- }
- break;
- }
-
- case PPC_PTRACE_SETFPREGS: { /* Get FPRs 0 - 31. */
- int i;
- unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
- unsigned long __user *tmp = (unsigned long __user *)addr;
-
- flush_fp_to_thread(child);
-
- for (i = 0; i < 32; i++) {
- ret = get_user(*reg, tmp);
- if (ret)
- break;
- reg++;
- tmp++;
- }
- break;
- }
-
-#ifdef CONFIG_ALTIVEC
- case PTRACE_GETVRREGS:
- /* Get the child altivec register state. */
- flush_altivec_to_thread(child);
- ret = get_vrregs((unsigned long __user *)data, child);
- break;
-
- case PTRACE_SETVRREGS:
- /* Set the child altivec register state. */
- flush_altivec_to_thread(child);
- ret = set_vrregs(child, (unsigned long __user *)data);
- break;
-#endif
-
- default:
- ret = ptrace_request(child, request, addr, data);
- break;
- }
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
- return ret;
-}
-
-static void do_syscall_trace(void)
-{
- /* the 0x80 provides a way for the tracing parent to distinguish
- between a syscall stop and SIGTRAP delivery */
- ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
- ? 0x80 : 0));
-
- /*
- * this isn't the same as continuing with a signal, but it will do
- * for normal use. strace only continues with a signal if the
- * stopping signal is not SIGTRAP. -brl
- */
- if (current->exit_code) {
- send_sig(current->exit_code, current, 1);
- current->exit_code = 0;
- }
-}
-
-void do_syscall_trace_enter(struct pt_regs *regs)
-{
- secure_computing(regs->gpr[0]);
-
- if (test_thread_flag(TIF_SYSCALL_TRACE)
- && (current->ptrace & PT_PTRACED))
- do_syscall_trace();
-
- if (unlikely(current->audit_context))
- audit_syscall_entry(current,
- test_thread_flag(TIF_32BIT)?AUDIT_ARCH_PPC:AUDIT_ARCH_PPC64,
- regs->gpr[0],
- regs->gpr[3], regs->gpr[4],
- regs->gpr[5], regs->gpr[6]);
-
-}
-
-void do_syscall_trace_leave(struct pt_regs *regs)
-{
- if (unlikely(current->audit_context))
- audit_syscall_exit(current,
- (regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
- regs->result);
-
- if ((test_thread_flag(TIF_SYSCALL_TRACE)
- || test_thread_flag(TIF_SINGLESTEP))
- && (current->ptrace & PT_PTRACED))
- do_syscall_trace();
-}
diff --git a/arch/ppc64/kernel/rtas-proc.c b/arch/ppc64/kernel/rtas-proc.c
index 1f3ff860fdf0..5bdd5b079d96 100644
--- a/arch/ppc64/kernel/rtas-proc.c
+++ b/arch/ppc64/kernel/rtas-proc.c
@@ -23,6 +23,7 @@
#include <linux/init.h>
#include <linux/seq_file.h>
#include <linux/bitops.h>
+#include <linux/rtc.h>
#include <asm/uaccess.h>
#include <asm/processor.h>
diff --git a/arch/ppc64/kernel/rtas_pci.c b/arch/ppc64/kernel/rtas_pci.c
index 4a9719b48abe..3ad15c90fbbd 100644
--- a/arch/ppc64/kernel/rtas_pci.c
+++ b/arch/ppc64/kernel/rtas_pci.c
@@ -38,9 +38,8 @@
#include <asm/pci-bridge.h>
#include <asm/iommu.h>
#include <asm/rtas.h>
-
-#include "mpic.h"
-#include "pci.h"
+#include <asm/mpic.h>
+#include <asm/ppc-pci.h>
/* RTAS tokens */
static int read_pci_config;
@@ -401,7 +400,7 @@ unsigned long __init find_and_init_phbs(void)
if (!phb)
continue;
- pci_process_bridge_OF_ranges(phb, node);
+ pci_process_bridge_OF_ranges(phb, node, 0);
pci_setup_phb_io(phb, index == 0);
#ifdef CONFIG_PPC_PSERIES
if (ppc64_interrupt_controller == IC_OPEN_PIC && pSeries_mpic) {
@@ -451,7 +450,7 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
if (!phb)
return NULL;
- pci_process_bridge_OF_ranges(phb, dn);
+ pci_process_bridge_OF_ranges(phb, dn, primary);
pci_setup_phb_io_dynamic(phb, primary);
of_node_put(root);
diff --git a/arch/ppc64/kernel/rtc.c b/arch/ppc64/kernel/rtc.c
index 6ff52bc61325..79e7ed2858dd 100644
--- a/arch/ppc64/kernel/rtc.c
+++ b/arch/ppc64/kernel/rtc.c
@@ -43,11 +43,8 @@
#include <asm/time.h>
#include <asm/rtas.h>
-#include <asm/iSeries/mf.h>
#include <asm/machdep.h>
-extern int piranha_simulator;
-
/*
* We sponge a minor off of the misc major. No need slurping
* up another valuable major dev number for this. If you add
@@ -265,44 +262,10 @@ static int rtc_read_proc(char *page, char **start, off_t off,
return len;
}
-#ifdef CONFIG_PPC_ISERIES
-/*
- * Get the RTC from the virtual service processor
- * This requires flowing LpEvents to the primary partition
- */
-void iSeries_get_rtc_time(struct rtc_time *rtc_tm)
-{
- if (piranha_simulator)
- return;
-
- mf_get_rtc(rtc_tm);
- rtc_tm->tm_mon--;
-}
-
-/*
- * Set the RTC in the virtual service processor
- * This requires flowing LpEvents to the primary partition
- */
-int iSeries_set_rtc_time(struct rtc_time *tm)
-{
- mf_set_rtc(tm);
- return 0;
-}
-
-void iSeries_get_boot_time(struct rtc_time *tm)
-{
- if ( piranha_simulator )
- return;
-
- mf_get_boot_rtc(tm);
- tm->tm_mon -= 1;
-}
-#endif
-
#ifdef CONFIG_PPC_RTAS
#define MAX_RTC_WAIT 5000 /* 5 sec */
#define RTAS_CLOCK_BUSY (-2)
-void rtas_get_boot_time(struct rtc_time *rtc_tm)
+unsigned long rtas_get_boot_time(void)
{
int ret[8];
int error, wait_time;
@@ -322,15 +285,10 @@ void rtas_get_boot_time(struct rtc_time *rtc_tm)
if (error != 0 && printk_ratelimit()) {
printk(KERN_WARNING "error: reading the clock failed (%d)\n",
error);
- return;
+ return 0;
}
- rtc_tm->tm_sec = ret[5];
- rtc_tm->tm_min = ret[4];
- rtc_tm->tm_hour = ret[3];
- rtc_tm->tm_mday = ret[2];
- rtc_tm->tm_mon = ret[1] - 1;
- rtc_tm->tm_year = ret[0] - 1900;
+ return mktime(ret[0], ret[1], ret[2], ret[3], ret[4], ret[5]);
}
/* NOTE: get_rtc_time will get an error if executed in interrupt context
diff --git a/arch/ppc64/kernel/signal.c b/arch/ppc64/kernel/signal.c
index 347112cca3c0..ec9d0984b6a0 100644
--- a/arch/ppc64/kernel/signal.c
+++ b/arch/ppc64/kernel/signal.c
@@ -133,7 +133,7 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
flush_fp_to_thread(current);
/* Make sure signal doesn't get spurrious FP exceptions */
- current->thread.fpscr = 0;
+ current->thread.fpscr.val = 0;
#ifdef CONFIG_ALTIVEC
err |= __put_user(v_regs, &sc->v_regs);
diff --git a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c
index 793b562da653..017c12919832 100644
--- a/arch/ppc64/kernel/smp.c
+++ b/arch/ppc64/kernel/smp.c
@@ -45,8 +45,7 @@
#include <asm/cputable.h>
#include <asm/system.h>
#include <asm/abs_addr.h>
-
-#include "mpic.h"
+#include <asm/mpic.h>
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
@@ -70,28 +69,6 @@ void smp_call_function_interrupt(void);
int smt_enabled_at_boot = 1;
#ifdef CONFIG_MPIC
-void smp_mpic_message_pass(int target, int msg)
-{
- /* make sure we're sending something that translates to an IPI */
- if ( msg > 0x3 ){
- printk("SMP %d: smp_message_pass: unknown msg %d\n",
- smp_processor_id(), msg);
- return;
- }
- switch ( target )
- {
- case MSG_ALL:
- mpic_send_ipi(msg, 0xffffffff);
- break;
- case MSG_ALL_BUT_SELF:
- mpic_send_ipi(msg, 0xffffffff & ~(1 << smp_processor_id()));
- break;
- default:
- mpic_send_ipi(msg, 1 << target);
- break;
- }
-}
-
int __init smp_mpic_probe(void)
{
int nr_cpus;
@@ -128,21 +105,6 @@ void __devinit smp_generic_kick_cpu(int nr)
#endif /* CONFIG_MPIC */
-static void __init smp_space_timers(unsigned int max_cpus)
-{
- int i;
- unsigned long offset = tb_ticks_per_jiffy / max_cpus;
- unsigned long previous_tb = paca[boot_cpuid].next_jiffy_update_tb;
-
- for_each_cpu(i) {
- if (i != boot_cpuid) {
- paca[i].next_jiffy_update_tb =
- previous_tb + offset;
- previous_tb = paca[i].next_jiffy_update_tb;
- }
- }
-}
-
void smp_message_recv(int msg, struct pt_regs *regs)
{
switch(msg) {
diff --git a/arch/ppc64/kernel/traps.c b/arch/ppc64/kernel/traps.c
deleted file mode 100644
index 7467ae508e6e..000000000000
--- a/arch/ppc64/kernel/traps.c
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
- * linux/arch/ppc64/kernel/traps.c
- *
- * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.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.
- *
- * Modified by Cort Dougan (cort@cs.nmt.edu)
- * and Paul Mackerras (paulus@cs.anu.edu.au)
- */
-
-/*
- * This file handles the architecture-dependent parts of hardware exceptions
- */
-
-#include <linux/config.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/slab.h>
-#include <linux/user.h>
-#include <linux/a.out.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/kprobes.h>
-#include <asm/kdebug.h>
-
-#include <asm/pgtable.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/processor.h>
-#include <asm/ppcdebug.h>
-#include <asm/rtas.h>
-#include <asm/systemcfg.h>
-#include <asm/machdep.h>
-#include <asm/pmc.h>
-
-#ifdef CONFIG_DEBUGGER
-int (*__debugger)(struct pt_regs *regs);
-int (*__debugger_ipi)(struct pt_regs *regs);
-int (*__debugger_bpt)(struct pt_regs *regs);
-int (*__debugger_sstep)(struct pt_regs *regs);
-int (*__debugger_iabr_match)(struct pt_regs *regs);
-int (*__debugger_dabr_match)(struct pt_regs *regs);
-int (*__debugger_fault_handler)(struct pt_regs *regs);
-
-EXPORT_SYMBOL(__debugger);
-EXPORT_SYMBOL(__debugger_ipi);
-EXPORT_SYMBOL(__debugger_bpt);
-EXPORT_SYMBOL(__debugger_sstep);
-EXPORT_SYMBOL(__debugger_iabr_match);
-EXPORT_SYMBOL(__debugger_dabr_match);
-EXPORT_SYMBOL(__debugger_fault_handler);
-#endif
-
-struct notifier_block *ppc64_die_chain;
-static DEFINE_SPINLOCK(die_notifier_lock);
-
-int register_die_notifier(struct notifier_block *nb)
-{
- int err = 0;
- unsigned long flags;
-
- spin_lock_irqsave(&die_notifier_lock, flags);
- err = notifier_chain_register(&ppc64_die_chain, nb);
- spin_unlock_irqrestore(&die_notifier_lock, flags);
- return err;
-}
-
-/*
- * Trap & Exception support
- */
-
-static DEFINE_SPINLOCK(die_lock);
-
-int die(const char *str, struct pt_regs *regs, long err)
-{
- static int die_counter;
- int nl = 0;
-
- if (debugger(regs))
- return 1;
-
- console_verbose();
- spin_lock_irq(&die_lock);
- bust_spinlocks(1);
- printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter);
-#ifdef CONFIG_PREEMPT
- printk("PREEMPT ");
- nl = 1;
-#endif
-#ifdef CONFIG_SMP
- printk("SMP NR_CPUS=%d ", NR_CPUS);
- nl = 1;
-#endif
-#ifdef CONFIG_DEBUG_PAGEALLOC
- printk("DEBUG_PAGEALLOC ");
- nl = 1;
-#endif
-#ifdef CONFIG_NUMA
- printk("NUMA ");
- nl = 1;
-#endif
- switch(systemcfg->platform) {
- case PLATFORM_PSERIES:
- printk("PSERIES ");
- nl = 1;
- break;
- case PLATFORM_PSERIES_LPAR:
- printk("PSERIES LPAR ");
- nl = 1;
- break;
- case PLATFORM_ISERIES_LPAR:
- printk("ISERIES LPAR ");
- nl = 1;
- break;
- case PLATFORM_POWERMAC:
- printk("POWERMAC ");
- nl = 1;
- break;
- case PLATFORM_BPA:
- printk("BPA ");
- nl = 1;
- break;
- }
- if (nl)
- printk("\n");
- print_modules();
- show_regs(regs);
- bust_spinlocks(0);
- spin_unlock_irq(&die_lock);
-
- if (in_interrupt())
- panic("Fatal exception in interrupt");
-
- if (panic_on_oops) {
- printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
- ssleep(5);
- panic("Fatal exception");
- }
- do_exit(SIGSEGV);
-
- return 0;
-}
-
-void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
-{
- siginfo_t info;
-
- if (!user_mode(regs)) {
- if (die("Exception in kernel mode", regs, signr))
- return;
- }
-
- memset(&info, 0, sizeof(info));
- info.si_signo = signr;
- info.si_code = code;
- info.si_addr = (void __user *) addr;
- force_sig_info(signr, &info, current);
-}
-
-void system_reset_exception(struct pt_regs *regs)
-{
- /* See if any machine dependent calls */
- if (ppc_md.system_reset_exception)
- ppc_md.system_reset_exception(regs);
-
- die("System Reset", regs, 0);
-
- /* Must die if the interrupt is not recoverable */
- if (!(regs->msr & MSR_RI))
- panic("Unrecoverable System Reset");
-
- /* What should we do here? We could issue a shutdown or hard reset. */
-}
-
-void machine_check_exception(struct pt_regs *regs)
-{
- int recover = 0;
-
- /* See if any machine dependent calls */
- if (ppc_md.machine_check_exception)
- recover = ppc_md.machine_check_exception(regs);
-
- if (recover)
- return;
-
- if (debugger_fault_handler(regs))
- return;
- die("Machine check", regs, 0);
-
- /* Must die if the interrupt is not recoverable */
- if (!(regs->msr & MSR_RI))
- panic("Unrecoverable Machine check");
-}
-
-void unknown_exception(struct pt_regs *regs)
-{
- printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
- regs->nip, regs->msr, regs->trap);
-
- _exception(SIGTRAP, regs, 0, 0);
-}
-
-void instruction_breakpoint_exception(struct pt_regs *regs)
-{
- if (notify_die(DIE_IABR_MATCH, "iabr_match", regs, 5,
- 5, SIGTRAP) == NOTIFY_STOP)
- return;
- if (debugger_iabr_match(regs))
- return;
- _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
-}
-
-void __kprobes single_step_exception(struct pt_regs *regs)
-{
- regs->msr &= ~MSR_SE; /* Turn off 'trace' bit */
-
- if (notify_die(DIE_SSTEP, "single_step", regs, 5,
- 5, SIGTRAP) == NOTIFY_STOP)
- return;
- if (debugger_sstep(regs))
- return;
-
- _exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
-}
-
-/*
- * After we have successfully emulated an instruction, we have to
- * check if the instruction was being single-stepped, and if so,
- * pretend we got a single-step exception. This was pointed out
- * by Kumar Gala. -- paulus
- */
-static inline void emulate_single_step(struct pt_regs *regs)
-{
- if (regs->msr & MSR_SE)
- single_step_exception(regs);
-}
-
-static void parse_fpe(struct pt_regs *regs)
-{
- int code = 0;
- unsigned long fpscr;
-
- flush_fp_to_thread(current);
-
- fpscr = current->thread.fpscr;
-
- /* Invalid operation */
- if ((fpscr & FPSCR_VE) && (fpscr & FPSCR_VX))
- code = FPE_FLTINV;
-
- /* Overflow */
- else if ((fpscr & FPSCR_OE) && (fpscr & FPSCR_OX))
- code = FPE_FLTOVF;
-
- /* Underflow */
- else if ((fpscr & FPSCR_UE) && (fpscr & FPSCR_UX))
- code = FPE_FLTUND;
-
- /* Divide by zero */
- else if ((fpscr & FPSCR_ZE) && (fpscr & FPSCR_ZX))
- code = FPE_FLTDIV;
-
- /* Inexact result */
- else if ((fpscr & FPSCR_XE) && (fpscr & FPSCR_XX))
- code = FPE_FLTRES;
-
- _exception(SIGFPE, regs, code, regs->nip);
-}
-
-/*
- * Illegal instruction emulation support. Return non-zero if we can't
- * emulate, or -EFAULT if the associated memory access caused an access
- * fault. Return zero on success.
- */
-
-#define INST_MFSPR_PVR 0x7c1f42a6
-#define INST_MFSPR_PVR_MASK 0xfc1fffff
-
-#define INST_DCBA 0x7c0005ec
-#define INST_DCBA_MASK 0x7c0007fe
-
-#define INST_MCRXR 0x7c000400
-#define INST_MCRXR_MASK 0x7c0007fe
-
-static int emulate_instruction(struct pt_regs *regs)
-{
- unsigned int instword;
-
- if (!user_mode(regs))
- return -EINVAL;
-
- CHECK_FULL_REGS(regs);
-
- if (get_user(instword, (unsigned int __user *)(regs->nip)))
- return -EFAULT;
-
- /* Emulate the mfspr rD, PVR. */
- if ((instword & INST_MFSPR_PVR_MASK) == INST_MFSPR_PVR) {
- unsigned int rd;
-
- rd = (instword >> 21) & 0x1f;
- regs->gpr[rd] = mfspr(SPRN_PVR);
- return 0;
- }
-
- /* Emulating the dcba insn is just a no-op. */
- if ((instword & INST_DCBA_MASK) == INST_DCBA) {
- static int warned;
-
- if (!warned) {
- printk(KERN_WARNING
- "process %d (%s) uses obsolete 'dcba' insn\n",
- current->pid, current->comm);
- warned = 1;
- }
- return 0;
- }
-
- /* Emulate the mcrxr insn. */
- if ((instword & INST_MCRXR_MASK) == INST_MCRXR) {
- static int warned;
- unsigned int shift;
-
- if (!warned) {
- printk(KERN_WARNING
- "process %d (%s) uses obsolete 'mcrxr' insn\n",
- current->pid, current->comm);
- warned = 1;
- }
-
- shift = (instword >> 21) & 0x1c;
- regs->ccr &= ~(0xf0000000 >> shift);
- regs->ccr |= (regs->xer & 0xf0000000) >> shift;
- regs->xer &= ~0xf0000000;
- return 0;
- }
-
- return -EINVAL;
-}
-
-/*
- * Look through the list of trap instructions that are used for BUG(),
- * BUG_ON() and WARN_ON() and see if we hit one. At this point we know
- * that the exception was caused by a trap instruction of some kind.
- * Returns 1 if we should continue (i.e. it was a WARN_ON) or 0
- * otherwise.
- */
-extern struct bug_entry __start___bug_table[], __stop___bug_table[];
-
-#ifndef CONFIG_MODULES
-#define module_find_bug(x) NULL
-#endif
-
-struct bug_entry *find_bug(unsigned long bugaddr)
-{
- struct bug_entry *bug;
-
- for (bug = __start___bug_table; bug < __stop___bug_table; ++bug)
- if (bugaddr == bug->bug_addr)
- return bug;
- return module_find_bug(bugaddr);
-}
-
-static int
-check_bug_trap(struct pt_regs *regs)
-{
- struct bug_entry *bug;
- unsigned long addr;
-
- if (regs->msr & MSR_PR)
- return 0; /* not in kernel */
- addr = regs->nip; /* address of trap instruction */
- if (addr < PAGE_OFFSET)
- return 0;
- bug = find_bug(regs->nip);
- if (bug == NULL)
- return 0;
- if (bug->line & BUG_WARNING_TRAP) {
- /* this is a WARN_ON rather than BUG/BUG_ON */
- printk(KERN_ERR "Badness in %s at %s:%d\n",
- bug->function, bug->file,
- (unsigned int)bug->line & ~BUG_WARNING_TRAP);
- show_stack(current, (void *)regs->gpr[1]);
- return 1;
- }
- printk(KERN_CRIT "kernel BUG in %s at %s:%d!\n",
- bug->function, bug->file, (unsigned int)bug->line);
- return 0;
-}
-
-void __kprobes program_check_exception(struct pt_regs *regs)
-{
- if (debugger_fault_handler(regs))
- return;
-
- if (regs->msr & 0x100000) {
- /* IEEE FP exception */
- parse_fpe(regs);
- } else if (regs->msr & 0x20000) {
- /* trap exception */
-
- if (notify_die(DIE_BPT, "breakpoint", regs, 5,
- 5, SIGTRAP) == NOTIFY_STOP)
- return;
- if (debugger_bpt(regs))
- return;
-
- if (check_bug_trap(regs)) {
- regs->nip += 4;
- return;
- }
- _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
-
- } else {
- /* Privileged or illegal instruction; try to emulate it. */
- switch (emulate_instruction(regs)) {
- case 0:
- regs->nip += 4;
- emulate_single_step(regs);
- break;
-
- case -EFAULT:
- _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
- break;
-
- default:
- if (regs->msr & 0x40000)
- /* priveleged */
- _exception(SIGILL, regs, ILL_PRVOPC, regs->nip);
- else
- /* illegal */
- _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
- break;
- }
- }
-}
-
-void kernel_fp_unavailable_exception(struct pt_regs *regs)
-{
- printk(KERN_EMERG "Unrecoverable FP Unavailable Exception "
- "%lx at %lx\n", regs->trap, regs->nip);
- die("Unrecoverable FP Unavailable Exception", regs, SIGABRT);
-}
-
-void altivec_unavailable_exception(struct pt_regs *regs)
-{
- if (user_mode(regs)) {
- /* A user program has executed an altivec instruction,
- but this kernel doesn't support altivec. */
- _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
- return;
- }
- printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception "
- "%lx at %lx\n", regs->trap, regs->nip);
- die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT);
-}
-
-extern perf_irq_t perf_irq;
-
-void performance_monitor_exception(struct pt_regs *regs)
-{
- perf_irq(regs);
-}
-
-void alignment_exception(struct pt_regs *regs)
-{
- int fixed;
-
- fixed = fix_alignment(regs);
-
- if (fixed == 1) {
- regs->nip += 4; /* skip over emulated instruction */
- emulate_single_step(regs);
- return;
- }
-
- /* Operand address was bad */
- if (fixed == -EFAULT) {
- if (user_mode(regs)) {
- _exception(SIGSEGV, regs, SEGV_MAPERR, regs->dar);
- } else {
- /* Search exception table */
- bad_page_fault(regs, regs->dar, SIGSEGV);
- }
-
- return;
- }
-
- _exception(SIGBUS, regs, BUS_ADRALN, regs->nip);
-}
-
-#ifdef CONFIG_ALTIVEC
-void altivec_assist_exception(struct pt_regs *regs)
-{
- int err;
- siginfo_t info;
-
- if (!user_mode(regs)) {
- printk(KERN_EMERG "VMX/Altivec assist exception in kernel mode"
- " at %lx\n", regs->nip);
- die("Kernel VMX/Altivec assist exception", regs, SIGILL);
- }
-
- flush_altivec_to_thread(current);
-
- err = emulate_altivec(regs);
- if (err == 0) {
- regs->nip += 4; /* skip emulated instruction */
- emulate_single_step(regs);
- return;
- }
-
- if (err == -EFAULT) {
- /* got an error reading the instruction */
- info.si_signo = SIGSEGV;
- info.si_errno = 0;
- info.si_code = SEGV_MAPERR;
- info.si_addr = (void __user *) regs->nip;
- force_sig_info(SIGSEGV, &info, current);
- } else {
- /* didn't recognize the instruction */
- /* XXX quick hack for now: set the non-Java bit in the VSCR */
- if (printk_ratelimit())
- printk(KERN_ERR "Unrecognized altivec instruction "
- "in %s at %lx\n", current->comm, regs->nip);
- current->thread.vscr.u[3] |= 0x10000;
- }
-}
-#endif /* CONFIG_ALTIVEC */
-
-/*
- * We enter here if we get an unrecoverable exception, that is, one
- * that happened at a point where the RI (recoverable interrupt) bit
- * in the MSR is 0. This indicates that SRR0/1 are live, and that
- * we therefore lost state by taking this exception.
- */
-void unrecoverable_exception(struct pt_regs *regs)
-{
- printk(KERN_EMERG "Unrecoverable exception %lx at %lx\n",
- regs->trap, regs->nip);
- die("Unrecoverable exception", regs, SIGABRT);
-}
-
-/*
- * We enter here if we discover during exception entry that we are
- * running in supervisor mode with a userspace value in the stack pointer.
- */
-void kernel_bad_stack(struct pt_regs *regs)
-{
- printk(KERN_EMERG "Bad kernel stack pointer %lx at %lx\n",
- regs->gpr[1], regs->nip);
- die("Bad kernel stack pointer", regs, SIGABRT);
-}
-
-void __init trap_init(void)
-{
-}
diff --git a/arch/ppc64/kernel/vdso.c b/arch/ppc64/kernel/vdso.c
index efa985f05aca..4aacf521e3e4 100644
--- a/arch/ppc64/kernel/vdso.c
+++ b/arch/ppc64/kernel/vdso.c
@@ -176,13 +176,13 @@ static struct page * vdso_vma_nopage(struct vm_area_struct * vma,
return NOPAGE_SIGBUS;
/*
- * Last page is systemcfg, special handling here, no get_page() a
- * this is a reserved page
+ * Last page is systemcfg.
*/
if ((vma->vm_end - address) <= PAGE_SIZE)
- return virt_to_page(systemcfg);
+ pg = virt_to_page(systemcfg);
+ else
+ pg = virt_to_page(vbase + offset);
- pg = virt_to_page(vbase + offset);
get_page(pg);
DBG(" ->page count: %d\n", page_count(pg));
@@ -259,7 +259,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int executable_stack)
* gettimeofday will be totally dead. It's fine to use that for setting
* breakpoints in the vDSO code pages though
*/
- vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC | VM_RESERVED;
vma->vm_flags |= mm->def_flags;
vma->vm_page_prot = protection_map[vma->vm_flags & 0x7];
vma->vm_ops = &vdso_vmops;
@@ -603,6 +603,8 @@ void __init vdso_init(void)
ClearPageReserved(pg);
get_page(pg);
}
+
+ get_page(virt_to_page(systemcfg));
}
int in_gate_area_no_task(unsigned long addr)
diff --git a/arch/ppc64/kernel/vdso64/sigtramp.S b/arch/ppc64/kernel/vdso64/sigtramp.S
index 8ae8f205e470..31b604ab56de 100644
--- a/arch/ppc64/kernel/vdso64/sigtramp.S
+++ b/arch/ppc64/kernel/vdso64/sigtramp.S
@@ -15,6 +15,7 @@
#include <asm/ppc_asm.h>
#include <asm/unistd.h>
#include <asm/vdso.h>
+#include <asm/ptrace.h> /* XXX for __SIGNAL_FRAMESIZE */
.text
diff --git a/arch/ppc64/kernel/vecemu.c b/arch/ppc64/kernel/vecemu.c
deleted file mode 100644
index cb207629f21f..000000000000
--- a/arch/ppc64/kernel/vecemu.c
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * Routines to emulate some Altivec/VMX instructions, specifically
- * those that can trap when given denormalized operands in Java mode.
- */
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <asm/ptrace.h>
-#include <asm/processor.h>
-#include <asm/uaccess.h>
-
-/* Functions in vector.S */
-extern void vaddfp(vector128 *dst, vector128 *a, vector128 *b);
-extern void vsubfp(vector128 *dst, vector128 *a, vector128 *b);
-extern void vmaddfp(vector128 *dst, vector128 *a, vector128 *b, vector128 *c);
-extern void vnmsubfp(vector128 *dst, vector128 *a, vector128 *b, vector128 *c);
-extern void vrefp(vector128 *dst, vector128 *src);
-extern void vrsqrtefp(vector128 *dst, vector128 *src);
-extern void vexptep(vector128 *dst, vector128 *src);
-
-static unsigned int exp2s[8] = {
- 0x800000,
- 0x8b95c2,
- 0x9837f0,
- 0xa5fed7,
- 0xb504f3,
- 0xc5672a,
- 0xd744fd,
- 0xeac0c7
-};
-
-/*
- * Computes an estimate of 2^x. The `s' argument is the 32-bit
- * single-precision floating-point representation of x.
- */
-static unsigned int eexp2(unsigned int s)
-{
- int exp, pwr;
- unsigned int mant, frac;
-
- /* extract exponent field from input */
- exp = ((s >> 23) & 0xff) - 127;
- if (exp > 7) {
- /* check for NaN input */
- if (exp == 128 && (s & 0x7fffff) != 0)
- return s | 0x400000; /* return QNaN */
- /* 2^-big = 0, 2^+big = +Inf */
- return (s & 0x80000000)? 0: 0x7f800000; /* 0 or +Inf */
- }
- if (exp < -23)
- return 0x3f800000; /* 1.0 */
-
- /* convert to fixed point integer in 9.23 representation */
- pwr = (s & 0x7fffff) | 0x800000;
- if (exp > 0)
- pwr <<= exp;
- else
- pwr >>= -exp;
- if (s & 0x80000000)
- pwr = -pwr;
-
- /* extract integer part, which becomes exponent part of result */
- exp = (pwr >> 23) + 126;
- if (exp >= 254)
- return 0x7f800000;
- if (exp < -23)
- return 0;
-
- /* table lookup on top 3 bits of fraction to get mantissa */
- mant = exp2s[(pwr >> 20) & 7];
-
- /* linear interpolation using remaining 20 bits of fraction */
- asm("mulhwu %0,%1,%2" : "=r" (frac)
- : "r" (pwr << 12), "r" (0x172b83ff));
- asm("mulhwu %0,%1,%2" : "=r" (frac) : "r" (frac), "r" (mant));
- mant += frac;
-
- if (exp >= 0)
- return mant + (exp << 23);
-
- /* denormalized result */
- exp = -exp;
- mant += 1 << (exp - 1);
- return mant >> exp;
-}
-
-/*
- * Computes an estimate of log_2(x). The `s' argument is the 32-bit
- * single-precision floating-point representation of x.
- */
-static unsigned int elog2(unsigned int s)
-{
- int exp, mant, lz, frac;
-
- exp = s & 0x7f800000;
- mant = s & 0x7fffff;
- if (exp == 0x7f800000) { /* Inf or NaN */
- if (mant != 0)
- s |= 0x400000; /* turn NaN into QNaN */
- return s;
- }
- if ((exp | mant) == 0) /* +0 or -0 */
- return 0xff800000; /* return -Inf */
-
- if (exp == 0) {
- /* denormalized */
- asm("cntlzw %0,%1" : "=r" (lz) : "r" (mant));
- mant <<= lz - 8;
- exp = (-118 - lz) << 23;
- } else {
- mant |= 0x800000;
- exp -= 127 << 23;
- }
-
- if (mant >= 0xb504f3) { /* 2^0.5 * 2^23 */
- exp |= 0x400000; /* 0.5 * 2^23 */
- asm("mulhwu %0,%1,%2" : "=r" (mant)
- : "r" (mant), "r" (0xb504f334)); /* 2^-0.5 * 2^32 */
- }
- if (mant >= 0x9837f0) { /* 2^0.25 * 2^23 */
- exp |= 0x200000; /* 0.25 * 2^23 */
- asm("mulhwu %0,%1,%2" : "=r" (mant)
- : "r" (mant), "r" (0xd744fccb)); /* 2^-0.25 * 2^32 */
- }
- if (mant >= 0x8b95c2) { /* 2^0.125 * 2^23 */
- exp |= 0x100000; /* 0.125 * 2^23 */
- asm("mulhwu %0,%1,%2" : "=r" (mant)
- : "r" (mant), "r" (0xeac0c6e8)); /* 2^-0.125 * 2^32 */
- }
- if (mant > 0x800000) { /* 1.0 * 2^23 */
- /* calculate (mant - 1) * 1.381097463 */
- /* 1.381097463 == 0.125 / (2^0.125 - 1) */
- asm("mulhwu %0,%1,%2" : "=r" (frac)
- : "r" ((mant - 0x800000) << 1), "r" (0xb0c7cd3a));
- exp += frac;
- }
- s = exp & 0x80000000;
- if (exp != 0) {
- if (s)
- exp = -exp;
- asm("cntlzw %0,%1" : "=r" (lz) : "r" (exp));
- lz = 8 - lz;
- if (lz > 0)
- exp >>= lz;
- else if (lz < 0)
- exp <<= -lz;
- s += ((lz + 126) << 23) + exp;
- }
- return s;
-}
-
-#define VSCR_SAT 1
-
-static int ctsxs(unsigned int x, int scale, unsigned int *vscrp)
-{
- int exp, mant;
-
- exp = (x >> 23) & 0xff;
- mant = x & 0x7fffff;
- if (exp == 255 && mant != 0)
- return 0; /* NaN -> 0 */
- exp = exp - 127 + scale;
- if (exp < 0)
- return 0; /* round towards zero */
- if (exp >= 31) {
- /* saturate, unless the result would be -2^31 */
- if (x + (scale << 23) != 0xcf000000)
- *vscrp |= VSCR_SAT;
- return (x & 0x80000000)? 0x80000000: 0x7fffffff;
- }
- mant |= 0x800000;
- mant = (mant << 7) >> (30 - exp);
- return (x & 0x80000000)? -mant: mant;
-}
-
-static unsigned int ctuxs(unsigned int x, int scale, unsigned int *vscrp)
-{
- int exp;
- unsigned int mant;
-
- exp = (x >> 23) & 0xff;
- mant = x & 0x7fffff;
- if (exp == 255 && mant != 0)
- return 0; /* NaN -> 0 */
- exp = exp - 127 + scale;
- if (exp < 0)
- return 0; /* round towards zero */
- if (x & 0x80000000) {
- /* negative => saturate to 0 */
- *vscrp |= VSCR_SAT;
- return 0;
- }
- if (exp >= 32) {
- /* saturate */
- *vscrp |= VSCR_SAT;
- return 0xffffffff;
- }
- mant |= 0x800000;
- mant = (mant << 8) >> (31 - exp);
- return mant;
-}
-
-/* Round to floating integer, towards 0 */
-static unsigned int rfiz(unsigned int x)
-{
- int exp;
-
- exp = ((x >> 23) & 0xff) - 127;
- if (exp == 128 && (x & 0x7fffff) != 0)
- return x | 0x400000; /* NaN -> make it a QNaN */
- if (exp >= 23)
- return x; /* it's an integer already (or Inf) */
- if (exp < 0)
- return x & 0x80000000; /* |x| < 1.0 rounds to 0 */
- return x & ~(0x7fffff >> exp);
-}
-
-/* Round to floating integer, towards +/- Inf */
-static unsigned int rfii(unsigned int x)
-{
- int exp, mask;
-
- exp = ((x >> 23) & 0xff) - 127;
- if (exp == 128 && (x & 0x7fffff) != 0)
- return x | 0x400000; /* NaN -> make it a QNaN */
- if (exp >= 23)
- return x; /* it's an integer already (or Inf) */
- if ((x & 0x7fffffff) == 0)
- return x; /* +/-0 -> +/-0 */
- if (exp < 0)
- /* 0 < |x| < 1.0 rounds to +/- 1.0 */
- return (x & 0x80000000) | 0x3f800000;
- mask = 0x7fffff >> exp;
- /* mantissa overflows into exponent - that's OK,
- it can't overflow into the sign bit */
- return (x + mask) & ~mask;
-}
-
-/* Round to floating integer, to nearest */
-static unsigned int rfin(unsigned int x)
-{
- int exp, half;
-
- exp = ((x >> 23) & 0xff) - 127;
- if (exp == 128 && (x & 0x7fffff) != 0)
- return x | 0x400000; /* NaN -> make it a QNaN */
- if (exp >= 23)
- return x; /* it's an integer already (or Inf) */
- if (exp < -1)
- return x & 0x80000000; /* |x| < 0.5 -> +/-0 */
- if (exp == -1)
- /* 0.5 <= |x| < 1.0 rounds to +/- 1.0 */
- return (x & 0x80000000) | 0x3f800000;
- half = 0x400000 >> exp;
- /* add 0.5 to the magnitude and chop off the fraction bits */
- return (x + half) & ~(0x7fffff >> exp);
-}
-
-int
-emulate_altivec(struct pt_regs *regs)
-{
- unsigned int instr, i;
- unsigned int va, vb, vc, vd;
- vector128 *vrs;
-
- if (get_user(instr, (unsigned int __user *) regs->nip))
- return -EFAULT;
- if ((instr >> 26) != 4)
- return -EINVAL; /* not an altivec instruction */
- vd = (instr >> 21) & 0x1f;
- va = (instr >> 16) & 0x1f;
- vb = (instr >> 11) & 0x1f;
- vc = (instr >> 6) & 0x1f;
-
- vrs = current->thread.vr;
- switch (instr & 0x3f) {
- case 10:
- switch (vc) {
- case 0: /* vaddfp */
- vaddfp(&vrs[vd], &vrs[va], &vrs[vb]);
- break;
- case 1: /* vsubfp */
- vsubfp(&vrs[vd], &vrs[va], &vrs[vb]);
- break;
- case 4: /* vrefp */
- vrefp(&vrs[vd], &vrs[vb]);
- break;
- case 5: /* vrsqrtefp */
- vrsqrtefp(&vrs[vd], &vrs[vb]);
- break;
- case 6: /* vexptefp */
- for (i = 0; i < 4; ++i)
- vrs[vd].u[i] = eexp2(vrs[vb].u[i]);
- break;
- case 7: /* vlogefp */
- for (i = 0; i < 4; ++i)
- vrs[vd].u[i] = elog2(vrs[vb].u[i]);
- break;
- case 8: /* vrfin */
- for (i = 0; i < 4; ++i)
- vrs[vd].u[i] = rfin(vrs[vb].u[i]);
- break;
- case 9: /* vrfiz */
- for (i = 0; i < 4; ++i)
- vrs[vd].u[i] = rfiz(vrs[vb].u[i]);
- break;
- case 10: /* vrfip */
- for (i = 0; i < 4; ++i) {
- u32 x = vrs[vb].u[i];
- x = (x & 0x80000000)? rfiz(x): rfii(x);
- vrs[vd].u[i] = x;
- }
- break;
- case 11: /* vrfim */
- for (i = 0; i < 4; ++i) {
- u32 x = vrs[vb].u[i];
- x = (x & 0x80000000)? rfii(x): rfiz(x);
- vrs[vd].u[i] = x;
- }
- break;
- case 14: /* vctuxs */
- for (i = 0; i < 4; ++i)
- vrs[vd].u[i] = ctuxs(vrs[vb].u[i], va,
- &current->thread.vscr.u[3]);
- break;
- case 15: /* vctsxs */
- for (i = 0; i < 4; ++i)
- vrs[vd].u[i] = ctsxs(vrs[vb].u[i], va,
- &current->thread.vscr.u[3]);
- break;
- default:
- return -EINVAL;
- }
- break;
- case 46: /* vmaddfp */
- vmaddfp(&vrs[vd], &vrs[va], &vrs[vb], &vrs[vc]);
- break;
- case 47: /* vnmsubfp */
- vnmsubfp(&vrs[vd], &vrs[va], &vrs[vb], &vrs[vc]);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
diff --git a/arch/ppc64/kernel/vmlinux.lds.S b/arch/ppc64/kernel/vmlinux.lds.S
index 0306510bc4ff..022f220e772f 100644
--- a/arch/ppc64/kernel/vmlinux.lds.S
+++ b/arch/ppc64/kernel/vmlinux.lds.S
@@ -1,3 +1,4 @@
+#include <asm/page.h>
#include <asm-generic/vmlinux.lds.h>
OUTPUT_ARCH(powerpc:common64)
@@ -17,7 +18,7 @@ SECTIONS
LOCK_TEXT
KPROBES_TEXT
*(.fixup)
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
_etext = .;
}
@@ -43,7 +44,7 @@ SECTIONS
/* will be freed after init */
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
__init_begin = .;
.init.text : {
@@ -83,7 +84,7 @@ SECTIONS
SECURITY_INIT
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
.init.ramfs : {
__initramfs_start = .;
*(.init.ramfs)
@@ -96,18 +97,22 @@ SECTIONS
__per_cpu_end = .;
}
+ . = ALIGN(PAGE_SIZE);
. = ALIGN(16384);
__init_end = .;
/* freed after init ends here */
/* Read/write sections */
+ . = ALIGN(PAGE_SIZE);
. = ALIGN(16384);
+ _sdata = .;
/* The initial task and kernel stack */
.data.init_task : {
*(.data.init_task)
}
+ . = ALIGN(PAGE_SIZE);
.data.page_aligned : {
*(.data.page_aligned)
}
@@ -129,18 +134,18 @@ SECTIONS
__toc_start = .;
*(.got)
*(.toc)
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
_edata = .;
}
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
.bss : {
__bss_start = .;
*(.bss)
__bss_stop = .;
}
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
_end = . ;
}
diff --git a/arch/ppc64/lib/Makefile b/arch/ppc64/lib/Makefile
index 0b6e967de948..42d5295bf345 100644
--- a/arch/ppc64/lib/Makefile
+++ b/arch/ppc64/lib/Makefile
@@ -2,17 +2,4 @@
# Makefile for ppc64-specific library files..
#
-lib-y := checksum.o string.o strcase.o
-lib-y += copypage.o memcpy.o copyuser.o usercopy.o
-
-# Lock primitives are defined as no-ops in include/linux/spinlock.h
-# for non-SMP configs. Don't build the real versions.
-
-lib-$(CONFIG_SMP) += locks.o
-
-# e2a provides EBCDIC to ASCII conversions.
-ifdef CONFIG_PPC_ISERIES
-obj-y += e2a.o
-endif
-
-lib-$(CONFIG_DEBUG_KERNEL) += sstep.o
+lib-y := string.o
diff --git a/arch/ppc64/lib/string.S b/arch/ppc64/lib/string.S
index 813587e5c2ec..e21a0038a4d6 100644
--- a/arch/ppc64/lib/string.S
+++ b/arch/ppc64/lib/string.S
@@ -65,112 +65,6 @@ _GLOBAL(strlen)
subf r3,r3,r4
blr
-_GLOBAL(memset)
- neg r0,r3
- rlwimi r4,r4,8,16,23
- andi. r0,r0,7 /* # bytes to be 8-byte aligned */
- rlwimi r4,r4,16,0,15
- cmplw cr1,r5,r0 /* do we get that far? */
- rldimi r4,r4,32,0
- mtcrf 1,r0
- mr r6,r3
- blt cr1,8f
- beq+ 3f /* if already 8-byte aligned */
- subf r5,r0,r5
- bf 31,1f
- stb r4,0(r6)
- addi r6,r6,1
-1: bf 30,2f
- sth r4,0(r6)
- addi r6,r6,2
-2: bf 29,3f
- stw r4,0(r6)
- addi r6,r6,4
-3: srdi. r0,r5,6
- clrldi r5,r5,58
- mtctr r0
- beq 5f
-4: std r4,0(r6)
- std r4,8(r6)
- std r4,16(r6)
- std r4,24(r6)
- std r4,32(r6)
- std r4,40(r6)
- std r4,48(r6)
- std r4,56(r6)
- addi r6,r6,64
- bdnz 4b
-5: srwi. r0,r5,3
- clrlwi r5,r5,29
- mtcrf 1,r0
- beq 8f
- bf 29,6f
- std r4,0(r6)
- std r4,8(r6)
- std r4,16(r6)
- std r4,24(r6)
- addi r6,r6,32
-6: bf 30,7f
- std r4,0(r6)
- std r4,8(r6)
- addi r6,r6,16
-7: bf 31,8f
- std r4,0(r6)
- addi r6,r6,8
-8: cmpwi r5,0
- mtcrf 1,r5
- beqlr+
- bf 29,9f
- stw r4,0(r6)
- addi r6,r6,4
-9: bf 30,10f
- sth r4,0(r6)
- addi r6,r6,2
-10: bflr 31
- stb r4,0(r6)
- blr
-
-_GLOBAL(memmove)
- cmplw 0,r3,r4
- bgt .backwards_memcpy
- b .memcpy
-
-_GLOBAL(backwards_memcpy)
- rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */
- add r6,r3,r5
- add r4,r4,r5
- beq 2f
- andi. r0,r6,3
- mtctr r7
- bne 5f
-1: lwz r7,-4(r4)
- lwzu r8,-8(r4)
- stw r7,-4(r6)
- stwu r8,-8(r6)
- bdnz 1b
- andi. r5,r5,7
-2: cmplwi 0,r5,4
- blt 3f
- lwzu r0,-4(r4)
- subi r5,r5,4
- stwu r0,-4(r6)
-3: cmpwi 0,r5,0
- beqlr
- mtctr r5
-4: lbzu r0,-1(r4)
- stbu r0,-1(r6)
- bdnz 4b
- blr
-5: mtctr r0
-6: lbzu r7,-1(r4)
- stbu r7,-1(r6)
- bdnz 6b
- subf r5,r0,r5
- rlwinm. r7,r5,32-3,3,31
- beq 2b
- mtctr r7
- b 1b
-
_GLOBAL(memcmp)
cmpwi 0,r5,0
ble- 2f
diff --git a/arch/ppc64/mm/Makefile b/arch/ppc64/mm/Makefile
deleted file mode 100644
index 3695d00d347f..000000000000
--- a/arch/ppc64/mm/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# Makefile for the linux ppc-specific parts of the memory manager.
-#
-
-EXTRA_CFLAGS += -mno-minimal-toc
-
-obj-y := fault.o init.o imalloc.o hash_utils.o hash_low.o tlb.o \
- slb_low.o slb.o stab.o mmap.o
-obj-$(CONFIG_NEED_MULTIPLE_NODES) += numa.o
-obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
-obj-$(CONFIG_PPC_MULTIPLATFORM) += hash_native.o
diff --git a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c
deleted file mode 100644
index be64b157afce..000000000000
--- a/arch/ppc64/mm/init.c
+++ /dev/null
@@ -1,869 +0,0 @@
-/*
- * PowerPC version
- * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
- *
- * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
- * and Cort Dougan (PReP) (cort@cs.nmt.edu)
- * Copyright (C) 1996 Paul Mackerras
- * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
- *
- * Derived from "arch/i386/mm/init.c"
- * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
- *
- * Dave Engebretsen <engebret@us.ibm.com>
- * Rework for PPC64 port.
- *
- * This program is free software; you can redistribute 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/config.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/mman.h>
-#include <linux/mm.h>
-#include <linux/swap.h>
-#include <linux/stddef.h>
-#include <linux/vmalloc.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/bootmem.h>
-#include <linux/highmem.h>
-#include <linux/idr.h>
-#include <linux/nodemask.h>
-#include <linux/module.h>
-
-#include <asm/pgalloc.h>
-#include <asm/page.h>
-#include <asm/prom.h>
-#include <asm/lmb.h>
-#include <asm/rtas.h>
-#include <asm/io.h>
-#include <asm/mmu_context.h>
-#include <asm/pgtable.h>
-#include <asm/mmu.h>
-#include <asm/uaccess.h>
-#include <asm/smp.h>
-#include <asm/machdep.h>
-#include <asm/tlb.h>
-#include <asm/eeh.h>
-#include <asm/processor.h>
-#include <asm/mmzone.h>
-#include <asm/cputable.h>
-#include <asm/ppcdebug.h>
-#include <asm/sections.h>
-#include <asm/system.h>
-#include <asm/iommu.h>
-#include <asm/abs_addr.h>
-#include <asm/vdso.h>
-#include <asm/imalloc.h>
-
-#if PGTABLE_RANGE > USER_VSID_RANGE
-#warning Limited user VSID range means pagetable space is wasted
-#endif
-
-#if (TASK_SIZE_USER64 < PGTABLE_RANGE) && (TASK_SIZE_USER64 < USER_VSID_RANGE)
-#warning TASK_SIZE is smaller than it needs to be.
-#endif
-
-int mem_init_done;
-unsigned long ioremap_bot = IMALLOC_BASE;
-static unsigned long phbs_io_bot = PHBS_IO_BASE;
-
-extern pgd_t swapper_pg_dir[];
-extern struct task_struct *current_set[NR_CPUS];
-
-unsigned long klimit = (unsigned long)_end;
-
-unsigned long _SDR1=0;
-unsigned long _ASR=0;
-
-/* max amount of RAM to use */
-unsigned long __max_memory;
-
-/* info on what we think the IO hole is */
-unsigned long io_hole_start;
-unsigned long io_hole_size;
-
-void show_mem(void)
-{
- unsigned long total = 0, reserved = 0;
- unsigned long shared = 0, cached = 0;
- struct page *page;
- pg_data_t *pgdat;
- unsigned long i;
-
- printk("Mem-info:\n");
- show_free_areas();
- printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
- for_each_pgdat(pgdat) {
- for (i = 0; i < pgdat->node_spanned_pages; i++) {
- page = pgdat_page_nr(pgdat, i);
- total++;
- if (PageReserved(page))
- reserved++;
- else if (PageSwapCache(page))
- cached++;
- else if (page_count(page))
- shared += page_count(page) - 1;
- }
- }
- printk("%ld pages of RAM\n", total);
- printk("%ld reserved pages\n", reserved);
- printk("%ld pages shared\n", shared);
- printk("%ld pages swap cached\n", cached);
-}
-
-#ifdef CONFIG_PPC_ISERIES
-
-void __iomem *ioremap(unsigned long addr, unsigned long size)
-{
- return (void __iomem *)addr;
-}
-
-extern void __iomem *__ioremap(unsigned long addr, unsigned long size,
- unsigned long flags)
-{
- return (void __iomem *)addr;
-}
-
-void iounmap(volatile void __iomem *addr)
-{
- return;
-}
-
-#else
-
-/*
- * map_io_page currently only called by __ioremap
- * map_io_page adds an entry to the ioremap page table
- * and adds an entry to the HPT, possibly bolting it
- */
-static int map_io_page(unsigned long ea, unsigned long pa, int flags)
-{
- pgd_t *pgdp;
- pud_t *pudp;
- pmd_t *pmdp;
- pte_t *ptep;
- unsigned long vsid;
-
- if (mem_init_done) {
- spin_lock(&init_mm.page_table_lock);
- pgdp = pgd_offset_k(ea);
- pudp = pud_alloc(&init_mm, pgdp, ea);
- if (!pudp)
- return -ENOMEM;
- pmdp = pmd_alloc(&init_mm, pudp, ea);
- if (!pmdp)
- return -ENOMEM;
- ptep = pte_alloc_kernel(&init_mm, pmdp, ea);
- if (!ptep)
- return -ENOMEM;
- set_pte_at(&init_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT,
- __pgprot(flags)));
- spin_unlock(&init_mm.page_table_lock);
- } else {
- unsigned long va, vpn, hash, hpteg;
-
- /*
- * If the mm subsystem is not fully up, we cannot create a
- * linux page table entry for this mapping. Simply bolt an
- * entry in the hardware page table.
- */
- vsid = get_kernel_vsid(ea);
- va = (vsid << 28) | (ea & 0xFFFFFFF);
- vpn = va >> PAGE_SHIFT;
-
- hash = hpt_hash(vpn, 0);
-
- hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
-
- /* Panic if a pte grpup is full */
- if (ppc_md.hpte_insert(hpteg, va, pa >> PAGE_SHIFT,
- HPTE_V_BOLTED,
- _PAGE_NO_CACHE|_PAGE_GUARDED|PP_RWXX)
- == -1) {
- panic("map_io_page: could not insert mapping");
- }
- }
- return 0;
-}
-
-
-static void __iomem * __ioremap_com(unsigned long addr, unsigned long pa,
- unsigned long ea, unsigned long size,
- unsigned long flags)
-{
- unsigned long i;
-
- if ((flags & _PAGE_PRESENT) == 0)
- flags |= pgprot_val(PAGE_KERNEL);
-
- for (i = 0; i < size; i += PAGE_SIZE)
- if (map_io_page(ea+i, pa+i, flags))
- return NULL;
-
- return (void __iomem *) (ea + (addr & ~PAGE_MASK));
-}
-
-
-void __iomem *
-ioremap(unsigned long addr, unsigned long size)
-{
- return __ioremap(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED);
-}
-
-void __iomem * __ioremap(unsigned long addr, unsigned long size,
- unsigned long flags)
-{
- unsigned long pa, ea;
- void __iomem *ret;
-
- /*
- * Choose an address to map it to.
- * Once the imalloc system is running, we use it.
- * Before that, we map using addresses going
- * up from ioremap_bot. imalloc will use
- * the addresses from ioremap_bot through
- * IMALLOC_END
- *
- */
- pa = addr & PAGE_MASK;
- size = PAGE_ALIGN(addr + size) - pa;
-
- if (size == 0)
- return NULL;
-
- if (mem_init_done) {
- struct vm_struct *area;
- area = im_get_free_area(size);
- if (area == NULL)
- return NULL;
- ea = (unsigned long)(area->addr);
- ret = __ioremap_com(addr, pa, ea, size, flags);
- if (!ret)
- im_free(area->addr);
- } else {
- ea = ioremap_bot;
- ret = __ioremap_com(addr, pa, ea, size, flags);
- if (ret)
- ioremap_bot += size;
- }
- return ret;
-}
-
-#define IS_PAGE_ALIGNED(_val) ((_val) == ((_val) & PAGE_MASK))
-
-int __ioremap_explicit(unsigned long pa, unsigned long ea,
- unsigned long size, unsigned long flags)
-{
- struct vm_struct *area;
- void __iomem *ret;
-
- /* For now, require page-aligned values for pa, ea, and size */
- if (!IS_PAGE_ALIGNED(pa) || !IS_PAGE_ALIGNED(ea) ||
- !IS_PAGE_ALIGNED(size)) {
- printk(KERN_ERR "unaligned value in %s\n", __FUNCTION__);
- return 1;
- }
-
- if (!mem_init_done) {
- /* Two things to consider in this case:
- * 1) No records will be kept (imalloc, etc) that the region
- * has been remapped
- * 2) It won't be easy to iounmap() the region later (because
- * of 1)
- */
- ;
- } else {
- area = im_get_area(ea, size,
- IM_REGION_UNUSED|IM_REGION_SUBSET|IM_REGION_EXISTS);
- if (area == NULL) {
- /* Expected when PHB-dlpar is in play */
- return 1;
- }
- if (ea != (unsigned long) area->addr) {
- printk(KERN_ERR "unexpected addr return from "
- "im_get_area\n");
- return 1;
- }
- }
-
- ret = __ioremap_com(pa, pa, ea, size, flags);
- if (ret == NULL) {
- printk(KERN_ERR "ioremap_explicit() allocation failure !\n");
- return 1;
- }
- if (ret != (void *) ea) {
- printk(KERN_ERR "__ioremap_com() returned unexpected addr\n");
- return 1;
- }
-
- return 0;
-}
-
-/*
- * Unmap an IO region and remove it from imalloc'd list.
- * Access to IO memory should be serialized by driver.
- * This code is modeled after vmalloc code - unmap_vm_area()
- *
- * XXX what about calls before mem_init_done (ie python_countermeasures())
- */
-void iounmap(volatile void __iomem *token)
-{
- void *addr;
-
- if (!mem_init_done)
- return;
-
- addr = (void *) ((unsigned long __force) token & PAGE_MASK);
-
- im_free(addr);
-}
-
-static int iounmap_subset_regions(unsigned long addr, unsigned long size)
-{
- struct vm_struct *area;
-
- /* Check whether subsets of this region exist */
- area = im_get_area(addr, size, IM_REGION_SUPERSET);
- if (area == NULL)
- return 1;
-
- while (area) {
- iounmap((void __iomem *) area->addr);
- area = im_get_area(addr, size,
- IM_REGION_SUPERSET);
- }
-
- return 0;
-}
-
-int iounmap_explicit(volatile void __iomem *start, unsigned long size)
-{
- struct vm_struct *area;
- unsigned long addr;
- int rc;
-
- addr = (unsigned long __force) start & PAGE_MASK;
-
- /* Verify that the region either exists or is a subset of an existing
- * region. In the latter case, split the parent region to create
- * the exact region
- */
- area = im_get_area(addr, size,
- IM_REGION_EXISTS | IM_REGION_SUBSET);
- if (area == NULL) {
- /* Determine whether subset regions exist. If so, unmap */
- rc = iounmap_subset_regions(addr, size);
- if (rc) {
- printk(KERN_ERR
- "%s() cannot unmap nonexistent range 0x%lx\n",
- __FUNCTION__, addr);
- return 1;
- }
- } else {
- iounmap((void __iomem *) area->addr);
- }
- /*
- * FIXME! This can't be right:
- iounmap(area->addr);
- * Maybe it should be "iounmap(area);"
- */
- return 0;
-}
-
-#endif
-
-EXPORT_SYMBOL(ioremap);
-EXPORT_SYMBOL(__ioremap);
-EXPORT_SYMBOL(iounmap);
-
-void free_initmem(void)
-{
- unsigned long addr;
-
- addr = (unsigned long)__init_begin;
- for (; addr < (unsigned long)__init_end; addr += PAGE_SIZE) {
- memset((void *)addr, 0xcc, PAGE_SIZE);
- ClearPageReserved(virt_to_page(addr));
- set_page_count(virt_to_page(addr), 1);
- free_page(addr);
- totalram_pages++;
- }
- printk ("Freeing unused kernel memory: %luk freed\n",
- ((unsigned long)__init_end - (unsigned long)__init_begin) >> 10);
-}
-
-#ifdef CONFIG_BLK_DEV_INITRD
-void free_initrd_mem(unsigned long start, unsigned long end)
-{
- if (start < end)
- printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
- for (; start < end; start += PAGE_SIZE) {
- ClearPageReserved(virt_to_page(start));
- set_page_count(virt_to_page(start), 1);
- free_page(start);
- totalram_pages++;
- }
-}
-#endif
-
-static DEFINE_SPINLOCK(mmu_context_lock);
-static DEFINE_IDR(mmu_context_idr);
-
-int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-{
- int index;
- int err;
-
-again:
- if (!idr_pre_get(&mmu_context_idr, GFP_KERNEL))
- return -ENOMEM;
-
- spin_lock(&mmu_context_lock);
- err = idr_get_new_above(&mmu_context_idr, NULL, 1, &index);
- spin_unlock(&mmu_context_lock);
-
- if (err == -EAGAIN)
- goto again;
- else if (err)
- return err;
-
- if (index > MAX_CONTEXT) {
- idr_remove(&mmu_context_idr, index);
- return -ENOMEM;
- }
-
- mm->context.id = index;
-
- return 0;
-}
-
-void destroy_context(struct mm_struct *mm)
-{
- spin_lock(&mmu_context_lock);
- idr_remove(&mmu_context_idr, mm->context.id);
- spin_unlock(&mmu_context_lock);
-
- mm->context.id = NO_CONTEXT;
-}
-
-/*
- * Do very early mm setup.
- */
-void __init mm_init_ppc64(void)
-{
-#ifndef CONFIG_PPC_ISERIES
- unsigned long i;
-#endif
-
- ppc64_boot_msg(0x100, "MM Init");
-
- /* This is the story of the IO hole... please, keep seated,
- * unfortunately, we are out of oxygen masks at the moment.
- * So we need some rough way to tell where your big IO hole
- * is. On pmac, it's between 2G and 4G, on POWER3, it's around
- * that area as well, on POWER4 we don't have one, etc...
- * We need that as a "hint" when sizing the TCE table on POWER3
- * So far, the simplest way that seem work well enough for us it
- * to just assume that the first discontinuity in our physical
- * RAM layout is the IO hole. That may not be correct in the future
- * (and isn't on iSeries but then we don't care ;)
- */
-
-#ifndef CONFIG_PPC_ISERIES
- for (i = 1; i < lmb.memory.cnt; i++) {
- unsigned long base, prevbase, prevsize;
-
- prevbase = lmb.memory.region[i-1].base;
- prevsize = lmb.memory.region[i-1].size;
- base = lmb.memory.region[i].base;
- if (base > (prevbase + prevsize)) {
- io_hole_start = prevbase + prevsize;
- io_hole_size = base - (prevbase + prevsize);
- break;
- }
- }
-#endif /* CONFIG_PPC_ISERIES */
- if (io_hole_start)
- printk("IO Hole assumed to be %lx -> %lx\n",
- io_hole_start, io_hole_start + io_hole_size - 1);
-
- ppc64_boot_msg(0x100, "MM Init Done");
-}
-
-/*
- * This is called by /dev/mem to know if a given address has to
- * be mapped non-cacheable or not
- */
-int page_is_ram(unsigned long pfn)
-{
- int i;
- unsigned long paddr = (pfn << PAGE_SHIFT);
-
- for (i=0; i < lmb.memory.cnt; i++) {
- unsigned long base;
-
- base = lmb.memory.region[i].base;
-
- if ((paddr >= base) &&
- (paddr < (base + lmb.memory.region[i].size))) {
- return 1;
- }
- }
-
- return 0;
-}
-EXPORT_SYMBOL(page_is_ram);
-
-/*
- * Initialize the bootmem system and give it all the memory we
- * have available.
- */
-#ifndef CONFIG_NEED_MULTIPLE_NODES
-void __init do_init_bootmem(void)
-{
- unsigned long i;
- unsigned long start, bootmap_pages;
- unsigned long total_pages = lmb_end_of_DRAM() >> PAGE_SHIFT;
- int boot_mapsize;
-
- /*
- * Find an area to use for the bootmem bitmap. Calculate the size of
- * bitmap required as (Total Memory) / PAGE_SIZE / BITS_PER_BYTE.
- * Add 1 additional page in case the address isn't page-aligned.
- */
- bootmap_pages = bootmem_bootmap_pages(total_pages);
-
- start = lmb_alloc(bootmap_pages<<PAGE_SHIFT, PAGE_SIZE);
- BUG_ON(!start);
-
- boot_mapsize = init_bootmem(start >> PAGE_SHIFT, total_pages);
-
- max_pfn = max_low_pfn;
-
- /* Add all physical memory to the bootmem map, mark each area
- * present.
- */
- for (i=0; i < lmb.memory.cnt; i++)
- free_bootmem(lmb.memory.region[i].base,
- lmb_size_bytes(&lmb.memory, i));
-
- /* reserve the sections we're already using */
- for (i=0; i < lmb.reserved.cnt; i++)
- reserve_bootmem(lmb.reserved.region[i].base,
- lmb_size_bytes(&lmb.reserved, i));
-
- for (i=0; i < lmb.memory.cnt; i++)
- memory_present(0, lmb_start_pfn(&lmb.memory, i),
- lmb_end_pfn(&lmb.memory, i));
-}
-
-/*
- * paging_init() sets up the page tables - in fact we've already done this.
- */
-void __init paging_init(void)
-{
- unsigned long zones_size[MAX_NR_ZONES];
- unsigned long zholes_size[MAX_NR_ZONES];
- unsigned long total_ram = lmb_phys_mem_size();
- unsigned long top_of_ram = lmb_end_of_DRAM();
-
- printk(KERN_INFO "Top of RAM: 0x%lx, Total RAM: 0x%lx\n",
- top_of_ram, total_ram);
- printk(KERN_INFO "Memory hole size: %ldMB\n",
- (top_of_ram - total_ram) >> 20);
- /*
- * All pages are DMA-able so we put them all in the DMA zone.
- */
- memset(zones_size, 0, sizeof(zones_size));
- memset(zholes_size, 0, sizeof(zholes_size));
-
- zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT;
- zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT;
-
- free_area_init_node(0, NODE_DATA(0), zones_size,
- __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size);
-}
-#endif /* ! CONFIG_NEED_MULTIPLE_NODES */
-
-static struct kcore_list kcore_vmem;
-
-static int __init setup_kcore(void)
-{
- int i;
-
- for (i=0; i < lmb.memory.cnt; i++) {
- unsigned long base, size;
- struct kcore_list *kcore_mem;
-
- base = lmb.memory.region[i].base;
- size = lmb.memory.region[i].size;
-
- /* GFP_ATOMIC to avoid might_sleep warnings during boot */
- kcore_mem = kmalloc(sizeof(struct kcore_list), GFP_ATOMIC);
- if (!kcore_mem)
- panic("mem_init: kmalloc failed\n");
-
- kclist_add(kcore_mem, __va(base), size);
- }
-
- kclist_add(&kcore_vmem, (void *)VMALLOC_START, VMALLOC_END-VMALLOC_START);
-
- return 0;
-}
-module_init(setup_kcore);
-
-void __init mem_init(void)
-{
-#ifdef CONFIG_NEED_MULTIPLE_NODES
- int nid;
-#endif
- pg_data_t *pgdat;
- unsigned long i;
- struct page *page;
- unsigned long reservedpages = 0, codesize, initsize, datasize, bsssize;
-
- num_physpages = max_low_pfn; /* RAM is assumed contiguous */
- high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
-
-#ifdef CONFIG_NEED_MULTIPLE_NODES
- for_each_online_node(nid) {
- if (NODE_DATA(nid)->node_spanned_pages != 0) {
- printk("freeing bootmem node %x\n", nid);
- totalram_pages +=
- free_all_bootmem_node(NODE_DATA(nid));
- }
- }
-#else
- max_mapnr = num_physpages;
- totalram_pages += free_all_bootmem();
-#endif
-
- for_each_pgdat(pgdat) {
- for (i = 0; i < pgdat->node_spanned_pages; i++) {
- page = pgdat_page_nr(pgdat, i);
- if (PageReserved(page))
- reservedpages++;
- }
- }
-
- codesize = (unsigned long)&_etext - (unsigned long)&_stext;
- initsize = (unsigned long)&__init_end - (unsigned long)&__init_begin;
- datasize = (unsigned long)&_edata - (unsigned long)&__init_end;
- bsssize = (unsigned long)&__bss_stop - (unsigned long)&__bss_start;
-
- printk(KERN_INFO "Memory: %luk/%luk available (%luk kernel code, "
- "%luk reserved, %luk data, %luk bss, %luk init)\n",
- (unsigned long)nr_free_pages() << (PAGE_SHIFT-10),
- num_physpages << (PAGE_SHIFT-10),
- codesize >> 10,
- reservedpages << (PAGE_SHIFT-10),
- datasize >> 10,
- bsssize >> 10,
- initsize >> 10);
-
- mem_init_done = 1;
-
- /* Initialize the vDSO */
- vdso_init();
-}
-
-/*
- * This is called when a page has been modified by the kernel.
- * It just marks the page as not i-cache clean. We do the i-cache
- * flush later when the page is given to a user process, if necessary.
- */
-void flush_dcache_page(struct page *page)
-{
- if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
- return;
- /* avoid an atomic op if possible */
- if (test_bit(PG_arch_1, &page->flags))
- clear_bit(PG_arch_1, &page->flags);
-}
-EXPORT_SYMBOL(flush_dcache_page);
-
-void clear_user_page(void *page, unsigned long vaddr, struct page *pg)
-{
- clear_page(page);
-
- if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
- return;
- /*
- * We shouldnt have to do this, but some versions of glibc
- * require it (ld.so assumes zero filled pages are icache clean)
- * - Anton
- */
-
- /* avoid an atomic op if possible */
- if (test_bit(PG_arch_1, &pg->flags))
- clear_bit(PG_arch_1, &pg->flags);
-}
-EXPORT_SYMBOL(clear_user_page);
-
-void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
- struct page *pg)
-{
- copy_page(vto, vfrom);
-
- /*
- * We should be able to use the following optimisation, however
- * there are two problems.
- * Firstly a bug in some versions of binutils meant PLT sections
- * were not marked executable.
- * Secondly the first word in the GOT section is blrl, used
- * to establish the GOT address. Until recently the GOT was
- * not marked executable.
- * - Anton
- */
-#if 0
- if (!vma->vm_file && ((vma->vm_flags & VM_EXEC) == 0))
- return;
-#endif
-
- if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
- return;
-
- /* avoid an atomic op if possible */
- if (test_bit(PG_arch_1, &pg->flags))
- clear_bit(PG_arch_1, &pg->flags);
-}
-
-void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
- unsigned long addr, int len)
-{
- unsigned long maddr;
-
- maddr = (unsigned long)page_address(page) + (addr & ~PAGE_MASK);
- flush_icache_range(maddr, maddr + len);
-}
-EXPORT_SYMBOL(flush_icache_user_range);
-
-/*
- * This is called at the end of handling a user page fault, when the
- * fault has been handled by updating a PTE in the linux page tables.
- * We use it to preload an HPTE into the hash table corresponding to
- * the updated linux PTE.
- *
- * This must always be called with the mm->page_table_lock held
- */
-void update_mmu_cache(struct vm_area_struct *vma, unsigned long ea,
- pte_t pte)
-{
- unsigned long vsid;
- void *pgdir;
- pte_t *ptep;
- int local = 0;
- cpumask_t tmp;
- unsigned long flags;
-
- /* handle i-cache coherency */
- if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE) &&
- !cpu_has_feature(CPU_FTR_NOEXECUTE)) {
- unsigned long pfn = pte_pfn(pte);
- if (pfn_valid(pfn)) {
- struct page *page = pfn_to_page(pfn);
- if (!PageReserved(page)
- && !test_bit(PG_arch_1, &page->flags)) {
- __flush_dcache_icache(page_address(page));
- set_bit(PG_arch_1, &page->flags);
- }
- }
- }
-
- /* We only want HPTEs for linux PTEs that have _PAGE_ACCESSED set */
- if (!pte_young(pte))
- return;
-
- pgdir = vma->vm_mm->pgd;
- if (pgdir == NULL)
- return;
-
- ptep = find_linux_pte(pgdir, ea);
- if (!ptep)
- return;
-
- vsid = get_vsid(vma->vm_mm->context.id, ea);
-
- local_irq_save(flags);
- tmp = cpumask_of_cpu(smp_processor_id());
- if (cpus_equal(vma->vm_mm->cpu_vm_mask, tmp))
- local = 1;
-
- __hash_page(ea, 0, vsid, ptep, 0x300, local);
- local_irq_restore(flags);
-}
-
-void __iomem * reserve_phb_iospace(unsigned long size)
-{
- void __iomem *virt_addr;
-
- if (phbs_io_bot >= IMALLOC_BASE)
- panic("reserve_phb_iospace(): phb io space overflow\n");
-
- virt_addr = (void __iomem *) phbs_io_bot;
- phbs_io_bot += size;
-
- return virt_addr;
-}
-
-static void zero_ctor(void *addr, kmem_cache_t *cache, unsigned long flags)
-{
- memset(addr, 0, kmem_cache_size(cache));
-}
-
-static const int pgtable_cache_size[2] = {
- PTE_TABLE_SIZE, PMD_TABLE_SIZE
-};
-static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = {
- "pgd_pte_cache", "pud_pmd_cache",
-};
-
-kmem_cache_t *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)];
-
-void pgtable_cache_init(void)
-{
- int i;
-
- BUILD_BUG_ON(PTE_TABLE_SIZE != pgtable_cache_size[PTE_CACHE_NUM]);
- BUILD_BUG_ON(PMD_TABLE_SIZE != pgtable_cache_size[PMD_CACHE_NUM]);
- BUILD_BUG_ON(PUD_TABLE_SIZE != pgtable_cache_size[PUD_CACHE_NUM]);
- BUILD_BUG_ON(PGD_TABLE_SIZE != pgtable_cache_size[PGD_CACHE_NUM]);
-
- for (i = 0; i < ARRAY_SIZE(pgtable_cache_size); i++) {
- int size = pgtable_cache_size[i];
- const char *name = pgtable_cache_name[i];
-
- pgtable_cache[i] = kmem_cache_create(name,
- size, size,
- SLAB_HWCACHE_ALIGN
- | SLAB_MUST_HWCACHE_ALIGN,
- zero_ctor,
- NULL);
- if (! pgtable_cache[i])
- panic("pgtable_cache_init(): could not create %s!\n",
- name);
- }
-}
-
-pgprot_t phys_mem_access_prot(struct file *file, unsigned long addr,
- unsigned long size, pgprot_t vma_prot)
-{
- if (ppc_md.phys_mem_access_prot)
- return ppc_md.phys_mem_access_prot(file, addr, size, vma_prot);
-
- if (!page_is_ram(addr >> PAGE_SHIFT))
- vma_prot = __pgprot(pgprot_val(vma_prot)
- | _PAGE_GUARDED | _PAGE_NO_CACHE);
- return vma_prot;
-}
-EXPORT_SYMBOL(phys_mem_access_prot);
diff --git a/arch/ppc64/oprofile/Kconfig b/arch/ppc64/oprofile/Kconfig
deleted file mode 100644
index 5ade19801b97..000000000000
--- a/arch/ppc64/oprofile/Kconfig
+++ /dev/null
@@ -1,23 +0,0 @@
-
-menu "Profiling support"
- depends on EXPERIMENTAL
-
-config PROFILING
- bool "Profiling support (EXPERIMENTAL)"
- help
- Say Y here to enable the extended profiling support mechanisms used
- by profilers such as OProfile.
-
-
-config OPROFILE
- tristate "OProfile system profiling (EXPERIMENTAL)"
- depends on PROFILING
- help
- OProfile is a profiling system capable of profiling the
- whole system, include the kernel, kernel modules, libraries,
- and applications.
-
- If unsure, say N.
-
-endmenu
-
diff --git a/arch/ppc64/oprofile/Makefile b/arch/ppc64/oprofile/Makefile
deleted file mode 100644
index 162dbf06c142..000000000000
--- a/arch/ppc64/oprofile/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-obj-$(CONFIG_OPROFILE) += oprofile.o
-
-DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \
- oprof.o cpu_buffer.o buffer_sync.o \
- event_buffer.o oprofile_files.o \
- oprofilefs.o oprofile_stats.o \
- timer_int.o )
-
-oprofile-y := $(DRIVER_OBJS) common.o op_model_rs64.o op_model_power4.o
diff --git a/arch/ppc64/xmon/Makefile b/arch/ppc64/xmon/Makefile
deleted file mode 100644
index fb21a7088d3e..000000000000
--- a/arch/ppc64/xmon/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-# Makefile for xmon
-
-EXTRA_CFLAGS += -mno-minimal-toc
-
-obj-y := start.o xmon.o ppc-dis.o ppc-opc.o subr_prf.o setjmp.o
diff --git a/arch/ppc64/xmon/setjmp.S b/arch/ppc64/xmon/setjmp.S
deleted file mode 100644
index 30ee643d557c..000000000000
--- a/arch/ppc64/xmon/setjmp.S
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 1996 Paul Mackerras.
- *
- * This program is free software; you can redistribute 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.
- *
- * NOTE: assert(sizeof(buf) > 184)
- */
-#include <asm/processor.h>
-#include <asm/ppc_asm.h>
-
-_GLOBAL(xmon_setjmp)
- mflr r0
- std r0,0(r3)
- std r1,8(r3)
- std r2,16(r3)
- mfcr r0
- std r0,24(r3)
- std r13,32(r3)
- std r14,40(r3)
- std r15,48(r3)
- std r16,56(r3)
- std r17,64(r3)
- std r18,72(r3)
- std r19,80(r3)
- std r20,88(r3)
- std r21,96(r3)
- std r22,104(r3)
- std r23,112(r3)
- std r24,120(r3)
- std r25,128(r3)
- std r26,136(r3)
- std r27,144(r3)
- std r28,152(r3)
- std r29,160(r3)
- std r30,168(r3)
- std r31,176(r3)
- li r3,0
- blr
-
-_GLOBAL(xmon_longjmp)
- cmpdi r4,0
- bne 1f
- li r4,1
-1: ld r13,32(r3)
- ld r14,40(r3)
- ld r15,48(r3)
- ld r16,56(r3)
- ld r17,64(r3)
- ld r18,72(r3)
- ld r19,80(r3)
- ld r20,88(r3)
- ld r21,96(r3)
- ld r22,104(r3)
- ld r23,112(r3)
- ld r24,120(r3)
- ld r25,128(r3)
- ld r26,136(r3)
- ld r27,144(r3)
- ld r28,152(r3)
- ld r29,160(r3)
- ld r30,168(r3)
- ld r31,176(r3)
- ld r0,24(r3)
- mtcrf 56,r0
- ld r0,0(r3)
- ld r1,8(r3)
- ld r2,16(r3)
- mtlr r0
- mr r3,r4
- blr
diff --git a/arch/s390/kernel/compat_ioctl.c b/arch/s390/kernel/compat_ioctl.c
index 24a1e9f069a7..6504c4e69986 100644
--- a/arch/s390/kernel/compat_ioctl.c
+++ b/arch/s390/kernel/compat_ioctl.c
@@ -18,6 +18,8 @@
#include <asm/dasd.h>
#include <asm/cmb.h>
#include <asm/tape390.h>
+#include <asm/ccwdev.h>
+#include "../../../drivers/s390/char/raw3270.h"
static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd,
unsigned long arg, struct file *f)
@@ -62,6 +64,13 @@ COMPATIBLE_IOCTL(BIODASDCMFENABLE)
COMPATIBLE_IOCTL(BIODASDCMFDISABLE)
COMPATIBLE_IOCTL(BIODASDREADALLCMB)
+COMPATIBLE_IOCTL(TUBICMD)
+COMPATIBLE_IOCTL(TUBOCMD)
+COMPATIBLE_IOCTL(TUBGETI)
+COMPATIBLE_IOCTL(TUBGETO)
+COMPATIBLE_IOCTL(TUBSETMOD)
+COMPATIBLE_IOCTL(TUBGETMOD)
+
COMPATIBLE_IOCTL(TAPE390_DISPLAY)
/* s390 doesn't need handlers here */
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index 55654b6e16dc..039354d72348 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -485,7 +485,9 @@ start:
#
.org 0x10000
startup:basr %r13,0 # get base
-.LPG1: lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
+.LPG1: l %r1, .Lget_ipl_device_addr-.LPG1(%r13)
+ basr %r14, %r1
+ lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
la %r12,_pstart-.LPG1(%r13) # pointer to parameter area
# move IPL device to lowcore
mvc __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12)
@@ -560,6 +562,9 @@ startup:basr %r13,0 # get base
mr %r2,%r1 # mem size in bytes in %r3
b .Lfchunk-.LPG1(%r13)
+ .align 4
+.Lget_ipl_device_addr:
+ .long .Lget_ipl_device
.Lpmask:
.byte 0
.align 8
@@ -755,6 +760,63 @@ _pstart:
.global _pend
_pend:
+.Lget_ipl_device:
+ basr %r12,0
+.LPG2: l %r1,0xb8 # get sid
+ sll %r1,15 # test if subchannel is enabled
+ srl %r1,31
+ ltr %r1,%r1
+ bz 0(%r14) # subchannel disabled
+ l %r1,0xb8
+ la %r5,.Lipl_schib-.LPG2(%r12)
+ stsch 0(%r5) # get schib of subchannel
+ bnz 0(%r14) # schib not available
+ tm 5(%r5),0x01 # devno valid?
+ bno 0(%r14)
+ la %r6,ipl_parameter_flags-.LPG2(%r12)
+ oi 3(%r6),0x01 # set flag
+ la %r2,ipl_devno-.LPG2(%r12)
+ mvc 0(2,%r2),6(%r5) # store devno
+ tm 4(%r5),0x80 # qdio capable device?
+ bno 0(%r14)
+ oi 3(%r6),0x02 # set flag
+
+ # copy ipl parameters
+
+ lhi %r0,4096
+ l %r2,20(%r0) # get address of parameter list
+ lhi %r3,IPL_PARMBLOCK_ORIGIN
+ st %r3,20(%r0)
+ lhi %r4,1
+ cr %r2,%r3 # start parameters < destination ?
+ jl 0f
+ lhi %r1,1 # copy direction is upwards
+ j 1f
+0: lhi %r1,-1 # copy direction is downwards
+ ar %r2,%r0
+ ar %r3,%r0
+ ar %r2,%r1
+ ar %r3,%r1
+1: mvc 0(1,%r3),0(%r2) # finally copy ipl parameters
+ ar %r3,%r1
+ ar %r2,%r1
+ sr %r0,%r4
+ jne 1b
+ b 0(%r14)
+
+ .align 4
+.Lipl_schib:
+ .rept 13
+ .long 0
+ .endr
+
+ .globl ipl_parameter_flags
+ipl_parameter_flags:
+ .long 0
+ .globl ipl_devno
+ipl_devno:
+ .word 0
+
#ifdef CONFIG_SHARED_KERNEL
.org 0x100000
#endif
@@ -764,11 +826,11 @@ _pend:
#
.globl _stext
_stext: basr %r13,0 # get base
-.LPG2:
+.LPG3:
#
# Setup stack
#
- l %r15,.Linittu-.LPG2(%r13)
+ l %r15,.Linittu-.LPG3(%r13)
mvc __LC_CURRENT(4),__TI_task(%r15)
ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE
st %r15,__LC_KERNEL_STACK # set end of kernel stack
@@ -782,8 +844,8 @@ _stext: basr %r13,0 # get base
lctl %c0,%c15,0(%r15)
#
- lam 0,15,.Laregs-.LPG2(%r13) # load access regs needed by uaccess
- l %r14,.Lstart-.LPG2(%r13)
+ lam 0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess
+ l %r14,.Lstart-.LPG3(%r13)
basr %r14,%r14 # call start_kernel
#
# We returned from start_kernel ?!? PANIK
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
index c9ff0404c875..193aafa72f54 100644
--- a/arch/s390/kernel/head64.S
+++ b/arch/s390/kernel/head64.S
@@ -484,6 +484,8 @@ start:
startup:basr %r13,0 # get base
.LPG1: sll %r13,1 # remove high order bit
srl %r13,1
+ l %r1,.Lget_ipl_device_addr-.LPG1(%r13)
+ basr %r14,%r1
lhi %r1,1 # mode 1 = esame
slr %r0,%r0 # set cpuid to zero
sigp %r1,%r0,0x12 # switch to esame mode
@@ -556,6 +558,9 @@ startup:basr %r13,0 # get base
mlgr %r2,%r1 # mem size in bytes in %r3
b .Lfchunk-.LPG1(%r13)
+ .align 4
+.Lget_ipl_device_addr:
+ .long .Lget_ipl_device
.Lpmask:
.byte 0
.align 8
@@ -746,6 +751,63 @@ _pstart:
.global _pend
_pend:
+.Lget_ipl_device:
+ basr %r12,0
+.LPG2: l %r1,0xb8 # get sid
+ sll %r1,15 # test if subchannel is enabled
+ srl %r1,31
+ ltr %r1,%r1
+ bz 0(%r14) # subchannel disabled
+ l %r1,0xb8
+ la %r5,.Lipl_schib-.LPG2(%r12)
+ stsch 0(%r5) # get schib of subchannel
+ bnz 0(%r14) # schib not available
+ tm 5(%r5),0x01 # devno valid?
+ bno 0(%r14)
+ la %r6,ipl_parameter_flags-.LPG2(%r12)
+ oi 3(%r6),0x01 # set flag
+ la %r2,ipl_devno-.LPG2(%r12)
+ mvc 0(2,%r2),6(%r5) # store devno
+ tm 4(%r5),0x80 # qdio capable device?
+ bno 0(%r14)
+ oi 3(%r6),0x02 # set flag
+
+ # copy ipl parameters
+
+ lhi %r0,4096
+ l %r2,20(%r0) # get address of parameter list
+ lhi %r3,IPL_PARMBLOCK_ORIGIN
+ st %r3,20(%r0)
+ lhi %r4,1
+ cr %r2,%r3 # start parameters < destination ?
+ jl 0f
+ lhi %r1,1 # copy direction is upwards
+ j 1f
+0: lhi %r1,-1 # copy direction is downwards
+ ar %r2,%r0
+ ar %r3,%r0
+ ar %r2,%r1
+ ar %r3,%r1
+1: mvc 0(1,%r3),0(%r2) # finally copy ipl parameters
+ ar %r3,%r1
+ ar %r2,%r1
+ sr %r0,%r4
+ jne 1b
+ b 0(%r14)
+
+ .align 4
+.Lipl_schib:
+ .rept 13
+ .long 0
+ .endr
+
+ .globl ipl_parameter_flags
+ipl_parameter_flags:
+ .long 0
+ .globl ipl_devno
+ipl_devno:
+ .word 0
+
#ifdef CONFIG_SHARED_KERNEL
.org 0x100000
#endif
@@ -755,7 +817,7 @@ _pend:
#
.globl _stext
_stext: basr %r13,0 # get base
-.LPG2:
+.LPG3:
#
# Setup stack
#
@@ -774,7 +836,7 @@ _stext: basr %r13,0 # get base
lctlg %c0,%c15,0(%r15)
#
- lam 0,15,.Laregs-.LPG2(%r13) # load access regs needed by uaccess
+ lam 0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess
brasl %r14,start_kernel # go to C code
#
# We returned from start_kernel ?!? PANIK
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 5204778b8e5e..31e7b19348b7 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -36,6 +36,7 @@
#include <linux/console.h>
#include <linux/seq_file.h>
#include <linux/kernel_stat.h>
+#include <linux/device.h>
#include <asm/uaccess.h>
#include <asm/system.h>
@@ -685,3 +686,188 @@ struct seq_operations cpuinfo_op = {
.show = show_cpuinfo,
};
+#define DEFINE_IPL_ATTR(_name, _format, _value) \
+static ssize_t ipl_##_name##_show(struct subsystem *subsys, \
+ char *page) \
+{ \
+ return sprintf(page, _format, _value); \
+} \
+static struct subsys_attribute ipl_##_name##_attr = \
+ __ATTR(_name, S_IRUGO, ipl_##_name##_show, NULL);
+
+DEFINE_IPL_ATTR(wwpn, "0x%016llx\n", (unsigned long long)
+ IPL_PARMBLOCK_START->fcp.wwpn);
+DEFINE_IPL_ATTR(lun, "0x%016llx\n", (unsigned long long)
+ IPL_PARMBLOCK_START->fcp.lun);
+DEFINE_IPL_ATTR(bootprog, "%lld\n", (unsigned long long)
+ IPL_PARMBLOCK_START->fcp.bootprog);
+DEFINE_IPL_ATTR(br_lba, "%lld\n", (unsigned long long)
+ IPL_PARMBLOCK_START->fcp.br_lba);
+
+enum ipl_type_type {
+ ipl_type_unknown,
+ ipl_type_ccw,
+ ipl_type_fcp,
+};
+
+static enum ipl_type_type
+get_ipl_type(void)
+{
+ struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
+
+ if (!IPL_DEVNO_VALID)
+ return ipl_type_unknown;
+ if (!IPL_PARMBLOCK_VALID)
+ return ipl_type_ccw;
+ if (ipl->hdr.header.version > IPL_MAX_SUPPORTED_VERSION)
+ return ipl_type_unknown;
+ if (ipl->fcp.pbt != IPL_TYPE_FCP)
+ return ipl_type_unknown;
+ return ipl_type_fcp;
+}
+
+static ssize_t
+ipl_type_show(struct subsystem *subsys, char *page)
+{
+ switch (get_ipl_type()) {
+ case ipl_type_ccw:
+ return sprintf(page, "ccw\n");
+ case ipl_type_fcp:
+ return sprintf(page, "fcp\n");
+ default:
+ return sprintf(page, "unknown\n");
+ }
+}
+
+static struct subsys_attribute ipl_type_attr = __ATTR_RO(ipl_type);
+
+static ssize_t
+ipl_device_show(struct subsystem *subsys, char *page)
+{
+ struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
+
+ switch (get_ipl_type()) {
+ case ipl_type_ccw:
+ return sprintf(page, "0.0.%04x\n", ipl_devno);
+ case ipl_type_fcp:
+ return sprintf(page, "0.0.%04x\n", ipl->fcp.devno);
+ default:
+ return 0;
+ }
+}
+
+static struct subsys_attribute ipl_device_attr =
+ __ATTR(device, S_IRUGO, ipl_device_show, NULL);
+
+static struct attribute *ipl_fcp_attrs[] = {
+ &ipl_type_attr.attr,
+ &ipl_device_attr.attr,
+ &ipl_wwpn_attr.attr,
+ &ipl_lun_attr.attr,
+ &ipl_bootprog_attr.attr,
+ &ipl_br_lba_attr.attr,
+ NULL,
+};
+
+static struct attribute_group ipl_fcp_attr_group = {
+ .attrs = ipl_fcp_attrs,
+};
+
+static struct attribute *ipl_ccw_attrs[] = {
+ &ipl_type_attr.attr,
+ &ipl_device_attr.attr,
+ NULL,
+};
+
+static struct attribute_group ipl_ccw_attr_group = {
+ .attrs = ipl_ccw_attrs,
+};
+
+static struct attribute *ipl_unknown_attrs[] = {
+ &ipl_type_attr.attr,
+ NULL,
+};
+
+static struct attribute_group ipl_unknown_attr_group = {
+ .attrs = ipl_unknown_attrs,
+};
+
+static ssize_t
+ipl_parameter_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+ unsigned int size = IPL_PARMBLOCK_SIZE;
+
+ if (off > size)
+ return 0;
+ if (off + count > size)
+ count = size - off;
+
+ memcpy(buf, (void *) IPL_PARMBLOCK_START + off, count);
+ return count;
+}
+
+static struct bin_attribute ipl_parameter_attr = {
+ .attr = {
+ .name = "binary_parameter",
+ .mode = S_IRUGO,
+ .owner = THIS_MODULE,
+ },
+ .size = PAGE_SIZE,
+ .read = &ipl_parameter_read,
+};
+
+static ssize_t
+ipl_scp_data_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+ unsigned int size = IPL_PARMBLOCK_START->fcp.scp_data_len;
+ void *scp_data = &IPL_PARMBLOCK_START->fcp.scp_data;
+
+ if (off > size)
+ return 0;
+ if (off + count > size)
+ count = size - off;
+
+ memcpy(buf, scp_data + off, count);
+ return count;
+}
+
+static struct bin_attribute ipl_scp_data_attr = {
+ .attr = {
+ .name = "scp_data",
+ .mode = S_IRUGO,
+ .owner = THIS_MODULE,
+ },
+ .size = PAGE_SIZE,
+ .read = &ipl_scp_data_read,
+};
+
+static decl_subsys(ipl, NULL, NULL);
+
+static int __init
+ipl_device_sysfs_register(void) {
+ int rc;
+
+ rc = firmware_register(&ipl_subsys);
+ if (rc)
+ return rc;
+
+ switch (get_ipl_type()) {
+ case ipl_type_ccw:
+ sysfs_create_group(&ipl_subsys.kset.kobj, &ipl_ccw_attr_group);
+ break;
+ case ipl_type_fcp:
+ sysfs_create_group(&ipl_subsys.kset.kobj, &ipl_fcp_attr_group);
+ sysfs_create_bin_file(&ipl_subsys.kset.kobj,
+ &ipl_parameter_attr);
+ sysfs_create_bin_file(&ipl_subsys.kset.kobj,
+ &ipl_scp_data_attr);
+ break;
+ default:
+ sysfs_create_group(&ipl_subsys.kset.kobj,
+ &ipl_unknown_attr_group);
+ break;
+ }
+ return 0;
+}
+
+__initcall(ipl_device_sysfs_register);
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 2fd75da15495..9a1d95894f3d 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -49,10 +49,6 @@
#define TICK_SIZE tick
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
static ext_int_info_t ext_int_info_cc;
static u64 init_timer_cc;
static u64 jiffies_timer_cc;
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index fa0726507b3d..22a895ecb7a4 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -24,7 +24,6 @@
#include <asm/s390_ext.h>
#include <asm/timer.h>
-#define VTIMER_MAGIC (TIMER_MAGIC + 1)
static ext_int_info_t ext_int_info_timer;
DEFINE_PER_CPU(struct vtimer_queue, virt_cpu_timer);
@@ -277,20 +276,12 @@ static void do_cpu_timer_interrupt(struct pt_regs *regs, __u16 error_code)
void init_virt_timer(struct vtimer_list *timer)
{
- timer->magic = VTIMER_MAGIC;
timer->function = NULL;
INIT_LIST_HEAD(&timer->entry);
spin_lock_init(&timer->lock);
}
EXPORT_SYMBOL(init_virt_timer);
-static inline int check_vtimer(struct vtimer_list *timer)
-{
- if (timer->magic != VTIMER_MAGIC)
- return -EINVAL;
- return 0;
-}
-
static inline int vtimer_pending(struct vtimer_list *timer)
{
return (!list_empty(&timer->entry));
@@ -346,7 +337,7 @@ static void internal_add_vtimer(struct vtimer_list *timer)
static inline int prepare_vtimer(struct vtimer_list *timer)
{
- if (check_vtimer(timer) || !timer->function) {
+ if (!timer->function) {
printk("add_virt_timer: uninitialized timer\n");
return -EINVAL;
}
@@ -414,7 +405,7 @@ int mod_virt_timer(struct vtimer_list *timer, __u64 expires)
unsigned long flags;
int cpu;
- if (check_vtimer(timer) || !timer->function) {
+ if (!timer->function) {
printk("mod_virt_timer: uninitialized timer\n");
return -EINVAL;
}
@@ -481,11 +472,6 @@ int del_virt_timer(struct vtimer_list *timer)
unsigned long flags;
struct vtimer_queue *vt_list;
- if (check_vtimer(timer)) {
- printk("del_virt_timer: timer not initialized\n");
- return -EINVAL;
- }
-
/* check if timer is pending */
if (!vtimer_pending(timer))
return 0;
diff --git a/arch/s390/mm/ioremap.c b/arch/s390/mm/ioremap.c
index c6c39d868bc8..0f6e9ecbefe2 100644
--- a/arch/s390/mm/ioremap.c
+++ b/arch/s390/mm/ioremap.c
@@ -58,7 +58,7 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned lo
if (address >= end)
BUG();
do {
- pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
+ pte_t * pte = pte_alloc_kernel(pmd, address);
if (!pte)
return -ENOMEM;
remap_area_pte(pte, address, end - address, address + phys_addr, flags);
@@ -80,7 +80,6 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr,
flush_cache_all();
if (address >= end)
BUG();
- spin_lock(&init_mm.page_table_lock);
do {
pmd_t *pmd;
pmd = pmd_alloc(&init_mm, dir, address);
@@ -94,7 +93,6 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr,
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
} while (address && (address < end));
- spin_unlock(&init_mm.page_table_lock);
flush_tlb_all();
return 0;
}
diff --git a/arch/sh/drivers/dma/dma-sysfs.c b/arch/sh/drivers/dma/dma-sysfs.c
index 71a6d4e7809f..6e3b58bd8795 100644
--- a/arch/sh/drivers/dma/dma-sysfs.c
+++ b/arch/sh/drivers/dma/dma-sysfs.c
@@ -13,6 +13,7 @@
#include <linux/init.h>
#include <linux/sysdev.h>
#include <linux/module.h>
+#include <linux/string.h>
#include <asm/dma.h>
static struct sysdev_class dma_sysclass = {
diff --git a/arch/sh/kernel/cpufreq.c b/arch/sh/kernel/cpufreq.c
index e0b384bef55f..47abf6e49dfb 100644
--- a/arch/sh/kernel/cpufreq.c
+++ b/arch/sh/kernel/cpufreq.c
@@ -20,6 +20,7 @@
#include <linux/delay.h>
#include <linux/cpumask.h>
#include <linux/smp.h>
+#include <linux/sched.h> /* set_cpus_allowed() */
#include <asm/processor.h>
#include <asm/watchdog.h>
diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c
index b28919b65682..1fbe5a428e31 100644
--- a/arch/sh/kernel/ptrace.c
+++ b/arch/sh/kernel/ptrace.c
@@ -80,7 +80,7 @@ void ptrace_disable(struct task_struct *child)
/* nothing to do.. */
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
struct user * dummy = NULL;
diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c
index 02ca69918d7c..671b876416bf 100644
--- a/arch/sh/kernel/time.c
+++ b/arch/sh/kernel/time.c
@@ -56,10 +56,6 @@ extern unsigned long wall_jiffies;
#define TICK_SIZE (tick_nsec / 1000)
DEFINE_SPINLOCK(tmu0_lock);
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
/* XXX: Can we initialize this in a routine somewhere? Dreamcast doesn't want
* these routines anywhere... */
#ifdef CONFIG_SH_RTC
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
index 7abba2161da6..775f86cd3fe8 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -194,10 +194,13 @@ asmlinkage int __do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
unsigned long address)
{
unsigned long addrmax = P4SEG;
- pgd_t *dir;
+ pgd_t *pgd;
pmd_t *pmd;
pte_t *pte;
pte_t entry;
+ struct mm_struct *mm;
+ spinlock_t *ptl;
+ int ret = 1;
#ifdef CONFIG_SH_KGDB
if (kgdb_nofault && kgdb_bus_err_hook)
@@ -208,28 +211,28 @@ asmlinkage int __do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
addrmax = P4SEG_STORE_QUE + 0x04000000;
#endif
- if (address >= P3SEG && address < addrmax)
- dir = pgd_offset_k(address);
- else if (address >= TASK_SIZE)
+ if (address >= P3SEG && address < addrmax) {
+ pgd = pgd_offset_k(address);
+ mm = NULL;
+ } else if (address >= TASK_SIZE)
return 1;
- else if (!current->mm)
+ else if (!(mm = current->mm))
return 1;
else
- dir = pgd_offset(current->mm, address);
+ pgd = pgd_offset(mm, address);
- pmd = pmd_offset(dir, address);
- if (pmd_none(*pmd))
- return 1;
- if (pmd_bad(*pmd)) {
- pmd_ERROR(*pmd);
- pmd_clear(pmd);
+ pmd = pmd_offset(pgd, address);
+ if (pmd_none_or_clear_bad(pmd))
return 1;
- }
- pte = pte_offset_kernel(pmd, address);
+ if (mm)
+ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
+ else
+ pte = pte_offset_kernel(pmd, address);
+
entry = *pte;
if (pte_none(entry) || pte_not_present(entry)
|| (writeaccess && !pte_write(entry)))
- return 1;
+ goto unlock;
if (writeaccess)
entry = pte_mkdirty(entry);
@@ -251,8 +254,11 @@ asmlinkage int __do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
set_pte(pte, entry);
update_mmu_cache(NULL, address, entry);
-
- return 0;
+ ret = 0;
+unlock:
+ if (mm)
+ pte_unmap_unlock(pte, ptl);
+ return ret;
}
void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
diff --git a/arch/sh/mm/hugetlbpage.c b/arch/sh/mm/hugetlbpage.c
index 95bb1a6c6060..6b7a7688c98e 100644
--- a/arch/sh/mm/hugetlbpage.c
+++ b/arch/sh/mm/hugetlbpage.c
@@ -54,8 +54,6 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
return pte;
}
-#define mk_pte_huge(entry) do { pte_val(entry) |= _PAGE_SZHUGE; } while (0)
-
void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t entry)
{
diff --git a/arch/sh/mm/ioremap.c b/arch/sh/mm/ioremap.c
index 9f490c2742f0..e794e27a72f1 100644
--- a/arch/sh/mm/ioremap.c
+++ b/arch/sh/mm/ioremap.c
@@ -57,7 +57,7 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address,
if (address >= end)
BUG();
do {
- pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
+ pte_t * pte = pte_alloc_kernel(pmd, address);
if (!pte)
return -ENOMEM;
remap_area_pte(pte, address, end - address, address + phys_addr, flags);
@@ -79,7 +79,6 @@ int remap_area_pages(unsigned long address, unsigned long phys_addr,
flush_cache_all();
if (address >= end)
BUG();
- spin_lock(&init_mm.page_table_lock);
do {
pmd_t *pmd;
pmd = pmd_alloc(&init_mm, dir, address);
@@ -93,7 +92,6 @@ int remap_area_pages(unsigned long address, unsigned long phys_addr,
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
} while (address && (address < end));
- spin_unlock(&init_mm.page_table_lock);
flush_tlb_all();
return error;
}
diff --git a/arch/sh64/kernel/ptrace.c b/arch/sh64/kernel/ptrace.c
index fd2000956dae..71f2eec00b99 100644
--- a/arch/sh64/kernel/ptrace.c
+++ b/arch/sh64/kernel/ptrace.c
@@ -121,7 +121,7 @@ put_fpu_long(struct task_struct *task, unsigned long addr, unsigned long data)
return 0;
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
extern void poke_real_address_q(unsigned long long addr, unsigned long long data);
diff --git a/arch/sh64/kernel/time.c b/arch/sh64/kernel/time.c
index f4a62a10053c..870fe5327e09 100644
--- a/arch/sh64/kernel/time.c
+++ b/arch/sh64/kernel/time.c
@@ -116,8 +116,6 @@
extern unsigned long wall_jiffies;
-u64 jiffies_64 = INITIAL_JIFFIES;
-
static unsigned long tmu_base, rtc_base;
unsigned long cprc_base;
@@ -253,6 +251,7 @@ int do_settimeofday(struct timespec *tv)
return 0;
}
+EXPORT_SYMBOL(do_settimeofday);
static int set_rtc_time(unsigned long nowtime)
{
diff --git a/arch/sh64/mm/cache.c b/arch/sh64/mm/cache.c
index 3b87e25ea773..c0c1b21350d8 100644
--- a/arch/sh64/mm/cache.c
+++ b/arch/sh64/mm/cache.c
@@ -584,32 +584,36 @@ static void sh64_dcache_purge_phy_page(unsigned long paddr)
}
}
-static void sh64_dcache_purge_user_page(struct mm_struct *mm, unsigned long eaddr)
+static void sh64_dcache_purge_user_pages(struct mm_struct *mm,
+ unsigned long addr, unsigned long end)
{
pgd_t *pgd;
pmd_t *pmd;
pte_t *pte;
pte_t entry;
+ spinlock_t *ptl;
unsigned long paddr;
- /* NOTE : all the callers of this have mm->page_table_lock held, so the
- following page table traversal is safe even on SMP/pre-emptible. */
-
- if (!mm) return; /* No way to find physical address of page */
- pgd = pgd_offset(mm, eaddr);
- if (pgd_bad(*pgd)) return;
-
- pmd = pmd_offset(pgd, eaddr);
- if (pmd_none(*pmd) || pmd_bad(*pmd)) return;
-
- pte = pte_offset_kernel(pmd, eaddr);
- entry = *pte;
- if (pte_none(entry) || !pte_present(entry)) return;
-
- paddr = pte_val(entry) & PAGE_MASK;
-
- sh64_dcache_purge_coloured_phy_page(paddr, eaddr);
-
+ if (!mm)
+ return; /* No way to find physical address of page */
+
+ pgd = pgd_offset(mm, addr);
+ if (pgd_bad(*pgd))
+ return;
+
+ pmd = pmd_offset(pgd, addr);
+ if (pmd_none(*pmd) || pmd_bad(*pmd))
+ return;
+
+ pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
+ do {
+ entry = *pte;
+ if (pte_none(entry) || !pte_present(entry))
+ continue;
+ paddr = pte_val(entry) & PAGE_MASK;
+ sh64_dcache_purge_coloured_phy_page(paddr, addr);
+ } while (pte++, addr += PAGE_SIZE, addr != end);
+ pte_unmap_unlock(pte - 1, ptl);
}
/****************************************************************************/
@@ -668,7 +672,7 @@ static void sh64_dcache_purge_user_range(struct mm_struct *mm,
int n_pages;
n_pages = ((end - start) >> PAGE_SHIFT);
- if (n_pages >= 64) {
+ if (n_pages >= 64 || ((start ^ (end - 1)) & PMD_MASK)) {
#if 1
sh64_dcache_purge_all();
#else
@@ -707,20 +711,10 @@ static void sh64_dcache_purge_user_range(struct mm_struct *mm,
}
#endif
} else {
- /* 'Small' range */
- unsigned long aligned_start;
- unsigned long eaddr;
- unsigned long last_page_start;
-
- aligned_start = start & PAGE_MASK;
- /* 'end' is 1 byte beyond the end of the range */
- last_page_start = (end - 1) & PAGE_MASK;
-
- eaddr = aligned_start;
- while (eaddr <= last_page_start) {
- sh64_dcache_purge_user_page(mm, eaddr);
- eaddr += PAGE_SIZE;
- }
+ /* Small range, covered by a single page table page */
+ start &= PAGE_MASK; /* should already be so */
+ end = PAGE_ALIGN(end); /* should already be so */
+ sh64_dcache_purge_user_pages(mm, start, end);
}
return;
}
@@ -880,9 +874,7 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
addresses from the user address space specified by mm, after writing
back any dirty data.
- Note(1), 'end' is 1 byte beyond the end of the range to flush.
-
- Note(2), this is called with mm->page_table_lock held.*/
+ Note, 'end' is 1 byte beyond the end of the range to flush. */
sh64_dcache_purge_user_range(mm, start, end);
sh64_icache_inv_user_page_range(mm, start, end);
@@ -898,7 +890,7 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long eaddr, unsigned
the I-cache must be searched too in case the page in question is
both writable and being executed from (e.g. stack trampolines.)
- Note(1), this is called with mm->page_table_lock held.
+ Note, this is called with pte lock held.
*/
sh64_dcache_purge_phy_page(pfn << PAGE_SHIFT);
diff --git a/arch/sh64/mm/hugetlbpage.c b/arch/sh64/mm/hugetlbpage.c
index dcd9c8a8baf8..ed6a505b3ee2 100644
--- a/arch/sh64/mm/hugetlbpage.c
+++ b/arch/sh64/mm/hugetlbpage.c
@@ -54,41 +54,31 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
return pte;
}
-#define mk_pte_huge(entry) do { pte_val(entry) |= _PAGE_SZHUGE; } while (0)
-
-static void set_huge_pte(struct mm_struct *mm, struct vm_area_struct *vma,
- struct page *page, pte_t * page_table, int write_access)
+void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t entry)
{
- unsigned long i;
- pte_t entry;
-
- add_mm_counter(mm, rss, HPAGE_SIZE / PAGE_SIZE);
-
- if (write_access)
- entry = pte_mkwrite(pte_mkdirty(mk_pte(page,
- vma->vm_page_prot)));
- else
- entry = pte_wrprotect(mk_pte(page, vma->vm_page_prot));
- entry = pte_mkyoung(entry);
- mk_pte_huge(entry);
+ int i;
for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
- set_pte(page_table, entry);
- page_table++;
-
+ set_pte_at(mm, addr, ptep, entry);
+ ptep++;
+ addr += PAGE_SIZE;
pte_val(entry) += PAGE_SIZE;
}
}
-pte_t huge_ptep_get_and_clear(pte_t *ptep)
+pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep)
{
pte_t entry;
+ int i;
entry = *ptep;
for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
- pte_clear(pte);
- pte++;
+ pte_clear(mm, addr, ptep);
+ addr += PAGE_SIZE;
+ ptep++;
}
return entry;
@@ -106,79 +96,6 @@ int is_aligned_hugepage_range(unsigned long addr, unsigned long len)
return 0;
}
-int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
- struct vm_area_struct *vma)
-{
- pte_t *src_pte, *dst_pte, entry;
- struct page *ptepage;
- unsigned long addr = vma->vm_start;
- unsigned long end = vma->vm_end;
- int i;
-
- while (addr < end) {
- dst_pte = huge_pte_alloc(dst, addr);
- if (!dst_pte)
- goto nomem;
- src_pte = huge_pte_offset(src, addr);
- BUG_ON(!src_pte || pte_none(*src_pte));
- entry = *src_pte;
- ptepage = pte_page(entry);
- get_page(ptepage);
- for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
- set_pte(dst_pte, entry);
- pte_val(entry) += PAGE_SIZE;
- dst_pte++;
- }
- add_mm_counter(dst, rss, HPAGE_SIZE / PAGE_SIZE);
- addr += HPAGE_SIZE;
- }
- return 0;
-
-nomem:
- return -ENOMEM;
-}
-
-int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
- struct page **pages, struct vm_area_struct **vmas,
- unsigned long *position, int *length, int i)
-{
- unsigned long vaddr = *position;
- int remainder = *length;
-
- WARN_ON(!is_vm_hugetlb_page(vma));
-
- while (vaddr < vma->vm_end && remainder) {
- if (pages) {
- pte_t *pte;
- struct page *page;
-
- pte = huge_pte_offset(mm, vaddr);
-
- /* hugetlb should be locked, and hence, prefaulted */
- BUG_ON(!pte || pte_none(*pte));
-
- page = pte_page(*pte);
-
- WARN_ON(!PageCompound(page));
-
- get_page(page);
- pages[i] = page;
- }
-
- if (vmas)
- vmas[i] = vma;
-
- vaddr += PAGE_SIZE;
- --remainder;
- ++i;
- }
-
- *length = remainder;
- *position = vaddr;
-
- return i;
-}
-
struct page *follow_huge_addr(struct mm_struct *mm,
unsigned long address, int write)
{
@@ -195,84 +112,3 @@ struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address,
{
return NULL;
}
-
-void unmap_hugepage_range(struct vm_area_struct *vma,
- unsigned long start, unsigned long end)
-{
- struct mm_struct *mm = vma->vm_mm;
- unsigned long address;
- pte_t *pte;
- struct page *page;
- int i;
-
- BUG_ON(start & (HPAGE_SIZE - 1));
- BUG_ON(end & (HPAGE_SIZE - 1));
-
- for (address = start; address < end; address += HPAGE_SIZE) {
- pte = huge_pte_offset(mm, address);
- BUG_ON(!pte);
- if (pte_none(*pte))
- continue;
- page = pte_page(*pte);
- put_page(page);
- for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
- pte_clear(mm, address+(i*PAGE_SIZE), pte);
- pte++;
- }
- }
- add_mm_counter(mm, rss, -((end - start) >> PAGE_SHIFT));
- flush_tlb_range(vma, start, end);
-}
-
-int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma)
-{
- struct mm_struct *mm = current->mm;
- unsigned long addr;
- int ret = 0;
-
- BUG_ON(vma->vm_start & ~HPAGE_MASK);
- BUG_ON(vma->vm_end & ~HPAGE_MASK);
-
- spin_lock(&mm->page_table_lock);
- for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) {
- unsigned long idx;
- pte_t *pte = huge_pte_alloc(mm, addr);
- struct page *page;
-
- if (!pte) {
- ret = -ENOMEM;
- goto out;
- }
- if (!pte_none(*pte))
- continue;
-
- idx = ((addr - vma->vm_start) >> HPAGE_SHIFT)
- + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
- page = find_get_page(mapping, idx);
- if (!page) {
- /* charge the fs quota first */
- if (hugetlb_get_quota(mapping)) {
- ret = -ENOMEM;
- goto out;
- }
- page = alloc_huge_page();
- if (!page) {
- hugetlb_put_quota(mapping);
- ret = -ENOMEM;
- goto out;
- }
- ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC);
- if (! ret) {
- unlock_page(page);
- } else {
- hugetlb_put_quota(mapping);
- free_huge_page(page);
- goto out;
- }
- }
- set_huge_pte(mm, vma, page, pte, vma->vm_flags & VM_WRITE);
- }
-out:
- spin_unlock(&mm->page_table_lock);
- return ret;
-}
diff --git a/arch/sh64/mm/ioremap.c b/arch/sh64/mm/ioremap.c
index f4003da556bc..fb1866fa2c9d 100644
--- a/arch/sh64/mm/ioremap.c
+++ b/arch/sh64/mm/ioremap.c
@@ -79,7 +79,7 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned lo
BUG();
do {
- pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
+ pte_t * pte = pte_alloc_kernel(pmd, address);
if (!pte)
return -ENOMEM;
remap_area_pte(pte, address, end - address, address + phys_addr, flags);
@@ -101,7 +101,6 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr,
flush_cache_all();
if (address >= end)
BUG();
- spin_lock(&init_mm.page_table_lock);
do {
pmd_t *pmd = pmd_alloc(&init_mm, dir, address);
error = -ENOMEM;
@@ -115,7 +114,6 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr,
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
} while (address && (address < end));
- spin_unlock(&init_mm.page_table_lock);
flush_tlb_all();
return 0;
}
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
index 36a40697b8d6..25e31d5ec99b 100644
--- a/arch/sparc/kernel/pcic.c
+++ b/arch/sparc/kernel/pcic.c
@@ -497,8 +497,8 @@ static void pcic_map_pci_device(struct linux_pcic *pcic,
* CheerIO makes a similar conversion.
* See ebus.c for details.
*
- * Note that check_region()/request_region()
- * work for these devices.
+ * Note that request_region()
+ * works for these devices.
*
* XXX Neat trick, but it's a *bad* idea
* to shit into regions like that.
diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c
index 279a62627c10..24814d58f9e1 100644
--- a/arch/sparc/kernel/time.c
+++ b/arch/sparc/kernel/time.c
@@ -45,10 +45,6 @@
extern unsigned long wall_jiffies;
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
DEFINE_SPINLOCK(rtc_lock);
enum sparc_clock_type sp_clock_typ;
DEFINE_SPINLOCK(mostek_lock);
diff --git a/arch/sparc/mm/generic.c b/arch/sparc/mm/generic.c
index 20ccb957fb77..9604893ffdbd 100644
--- a/arch/sparc/mm/generic.c
+++ b/arch/sparc/mm/generic.c
@@ -73,14 +73,16 @@ int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
int space = GET_IOSPACE(pfn);
unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT;
+ /* See comment in mm/memory.c remap_pfn_range */
+ vma->vm_flags |= VM_IO | VM_RESERVED;
+
prot = __pgprot(pg_iobits);
offset -= from;
dir = pgd_offset(mm, from);
flush_cache_range(vma, beg, end);
- spin_lock(&mm->page_table_lock);
while (from < end) {
- pmd_t *pmd = pmd_alloc(current->mm, dir, from);
+ pmd_t *pmd = pmd_alloc(mm, dir, from);
error = -ENOMEM;
if (!pmd)
break;
@@ -90,7 +92,6 @@ int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
from = (from + PGDIR_SIZE) & PGDIR_MASK;
dir++;
}
- spin_unlock(&mm->page_table_lock);
flush_tlb_range(vma, beg, end);
return error;
diff --git a/arch/sparc64/kernel/binfmt_aout32.c b/arch/sparc64/kernel/binfmt_aout32.c
index b2854ef221d0..edf52d06b280 100644
--- a/arch/sparc64/kernel/binfmt_aout32.c
+++ b/arch/sparc64/kernel/binfmt_aout32.c
@@ -241,7 +241,6 @@ static int load_aout32_binary(struct linux_binprm * bprm, struct pt_regs * regs)
current->mm->brk = ex.a_bss +
(current->mm->start_brk = N_BSSADDR(ex));
- set_mm_counter(current->mm, rss, 0);
current->mm->mmap = NULL;
compute_creds(bprm);
current->flags &= ~PF_FORKNOEXEC;
diff --git a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c
index 43fc3173d480..e6a00325075a 100644
--- a/arch/sparc64/kernel/ioctl32.c
+++ b/arch/sparc64/kernel/ioctl32.c
@@ -475,9 +475,6 @@ IOCTL_TABLE_START
#include <linux/compat_ioctl.h>
#define DECLARES
#include "compat_ioctl.c"
-COMPATIBLE_IOCTL(TIOCSTART)
-COMPATIBLE_IOCTL(TIOCSTOP)
-COMPATIBLE_IOCTL(TIOCSLTC)
COMPATIBLE_IOCTL(FBIOGTYPE)
COMPATIBLE_IOCTL(FBIOSATTR)
COMPATIBLE_IOCTL(FBIOGATTR)
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index 3f08a32f51a1..38c5525087a2 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -55,10 +55,6 @@ unsigned long ds1287_regs = 0UL;
extern unsigned long wall_jiffies;
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
static void __iomem *mstk48t08_regs;
static void __iomem *mstk48t59_regs;
diff --git a/arch/sparc64/mm/generic.c b/arch/sparc64/mm/generic.c
index c954d91f01d0..112c316e7cd2 100644
--- a/arch/sparc64/mm/generic.c
+++ b/arch/sparc64/mm/generic.c
@@ -127,14 +127,16 @@ int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
int space = GET_IOSPACE(pfn);
unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT;
+ /* See comment in mm/memory.c remap_pfn_range */
+ vma->vm_flags |= VM_IO | VM_RESERVED;
+
prot = __pgprot(pg_iobits);
offset -= from;
dir = pgd_offset(mm, from);
flush_cache_range(vma, beg, end);
- spin_lock(&mm->page_table_lock);
while (from < end) {
- pud_t *pud = pud_alloc(current->mm, dir, from);
+ pud_t *pud = pud_alloc(mm, dir, from);
error = -ENOMEM;
if (!pud)
break;
@@ -144,8 +146,7 @@ int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
from = (from + PGDIR_SIZE) & PGDIR_MASK;
dir++;
}
- flush_tlb_range(vma, beg, end);
- spin_unlock(&mm->page_table_lock);
+ flush_tlb_range(vma, beg, end);
return error;
}
diff --git a/arch/sparc64/mm/tlb.c b/arch/sparc64/mm/tlb.c
index 90ca99d0b89c..8b104be4662b 100644
--- a/arch/sparc64/mm/tlb.c
+++ b/arch/sparc64/mm/tlb.c
@@ -18,8 +18,7 @@
/* Heavily inspired by the ppc64 code. */
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers) =
- { NULL, 0, 0, 0, 0, 0, { 0 }, { NULL }, };
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers) = { 0, };
void flush_tlb_pending(void)
{
@@ -72,7 +71,7 @@ void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr, pte_t *ptep, pte_t
no_cache_flush:
- if (mp->tlb_frozen)
+ if (mp->fullmm)
return;
nr = mp->tlb_nr;
@@ -97,7 +96,7 @@ void flush_tlb_pgtables(struct mm_struct *mm, unsigned long start, unsigned long
unsigned long nr = mp->tlb_nr;
long s = start, e = end, vpte_base;
- if (mp->tlb_frozen)
+ if (mp->fullmm)
return;
/* If start is greater than end, that is a real problem. */
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index 684e1f8b2755..cd06ed7d842d 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -27,10 +27,6 @@ config UID16
bool
default y
-config RWSEM_GENERIC_SPINLOCK
- bool
- default y
-
config GENERIC_CALIBRATE_DELAY
bool
default y
@@ -40,6 +36,12 @@ config IRQ_RELEASE_METHOD
bool
default y
+menu "Host processor type and features"
+
+source "arch/i386/Kconfig.cpu"
+
+endmenu
+
menu "UML-specific options"
config MODE_TT
diff --git a/arch/um/Kconfig.x86_64 b/arch/um/Kconfig.x86_64
index bd35e59419c8..aae19bc4b06a 100644
--- a/arch/um/Kconfig.x86_64
+++ b/arch/um/Kconfig.x86_64
@@ -6,6 +6,11 @@ config 64BIT
bool
default y
+#XXX: this is so in the underlying arch, but it's wrong!!!
+config RWSEM_GENERIC_SPINLOCK
+ bool
+ default y
+
config SEMAPHORE_SLEEPERS
bool
default y
diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
index 2ee8a2858117..aef7c50f8e13 100644
--- a/arch/um/Makefile-i386
+++ b/arch/um/Makefile-i386
@@ -29,6 +29,12 @@ endif
CFLAGS += -U__$(SUBARCH)__ -U$(SUBARCH)
-ifneq ($(CONFIG_GPROF),y)
-ARCH_CFLAGS += -DUM_FASTCALL
-endif
+# First of all, tune CFLAGS for the specific CPU. This actually sets cflags-y.
+include $(srctree)/arch/i386/Makefile.cpu
+
+# prevent gcc from keeping the stack 16 byte aligned. Taken from i386.
+cflags-y += $(call cc-option,-mpreferred-stack-boundary=2)
+
+CFLAGS += $(cflags-y)
+USER_CFLAGS += $(cflags-y)
+
diff --git a/arch/um/include/sysdep-i386/syscalls.h b/arch/um/include/sysdep-i386/syscalls.h
index a0d5b74d3731..57bd79efbee3 100644
--- a/arch/um/include/sysdep-i386/syscalls.h
+++ b/arch/um/include/sysdep-i386/syscalls.h
@@ -11,7 +11,6 @@ typedef long syscall_handler_t(struct pt_regs);
/* Not declared on x86, incompatible declarations on x86_64, so these have
* to go here rather than in sys_call_table.c
*/
-extern syscall_handler_t sys_ptrace;
extern syscall_handler_t sys_rt_sigaction;
extern syscall_handler_t old_mmap_i386;
diff --git a/arch/um/include/tlb.h b/arch/um/include/tlb.h
index 45d7da6c3b2c..8efc1e0f1b84 100644
--- a/arch/um/include/tlb.h
+++ b/arch/um/include/tlb.h
@@ -34,7 +34,6 @@ struct host_vm_op {
} u;
};
-extern void mprotect_kernel_vm(int w);
extern void force_flush_all(void);
extern void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
unsigned long end_addr, int force,
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
index 0d73ceeece72..34b54a3e2132 100644
--- a/arch/um/kernel/process_kern.c
+++ b/arch/um/kernel/process_kern.c
@@ -222,6 +222,7 @@ void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
+ pte_t ptent;
if(task->mm == NULL)
return(ERR_PTR(-EINVAL));
@@ -238,12 +239,13 @@ void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
return(ERR_PTR(-EINVAL));
pte = pte_offset_kernel(pmd, addr);
- if(!pte_present(*pte))
+ ptent = *pte;
+ if(!pte_present(ptent))
return(ERR_PTR(-EINVAL));
if(pte_out != NULL)
- *pte_out = *pte;
- return((void *) (pte_val(*pte) & PAGE_MASK) + (addr & ~PAGE_MASK));
+ *pte_out = ptent;
+ return((void *) (pte_val(ptent) & PAGE_MASK) + (addr & ~PAGE_MASK));
}
char *current_cmd(void)
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
index 240143b616a2..9e5e39cea821 100644
--- a/arch/um/kernel/skas/mmu.c
+++ b/arch/um/kernel/skas/mmu.c
@@ -28,7 +28,6 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
pmd_t *pmd;
pte_t *pte;
- spin_lock(&mm->page_table_lock);
pgd = pgd_offset(mm, proc);
pud = pud_alloc(mm, pgd, proc);
if (!pud)
@@ -63,7 +62,6 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
*pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT));
*pte = pte_mkexec(*pte);
*pte = pte_wrprotect(*pte);
- spin_unlock(&mm->page_table_lock);
return(0);
out_pmd:
@@ -71,7 +69,6 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
out_pte:
pmd_free(pmd);
out:
- spin_unlock(&mm->page_table_lock);
return(-ENOMEM);
}
@@ -147,6 +144,7 @@ void destroy_context_skas(struct mm_struct *mm)
if(!proc_mm || !ptrace_faultinfo){
free_page(mmu->id.stack);
+ pte_lock_deinit(virt_to_page(mmu->last_page_table));
pte_free_kernel((pte_t *) mmu->last_page_table);
dec_page_state(nr_page_table_pages);
#ifdef CONFIG_3_LEVEL_PGTABLES
diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c
index 4e08f7545d63..020ca79b8d33 100644
--- a/arch/um/kernel/time_kern.c
+++ b/arch/um/kernel/time_kern.c
@@ -22,10 +22,6 @@
#include "mode.h"
#include "os.h"
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
int hz(void)
{
return(HZ);
diff --git a/arch/um/kernel/tt/tlb.c b/arch/um/kernel/tt/tlb.c
index f1d85dbb45b9..ae6217c86135 100644
--- a/arch/um/kernel/tt/tlb.c
+++ b/arch/um/kernel/tt/tlb.c
@@ -74,42 +74,6 @@ void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end)
atomic_inc(&vmchange_seq);
}
-static void protect_vm_page(unsigned long addr, int w, int must_succeed)
-{
- int err;
-
- err = protect_memory(addr, PAGE_SIZE, 1, w, 1, must_succeed);
- if(err == 0) return;
- else if((err == -EFAULT) || (err == -ENOMEM)){
- flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
- protect_vm_page(addr, w, 1);
- }
- else panic("protect_vm_page : protect failed, errno = %d\n", err);
-}
-
-void mprotect_kernel_vm(int w)
-{
- struct mm_struct *mm;
- pgd_t *pgd;
- pud_t *pud;
- pmd_t *pmd;
- pte_t *pte;
- unsigned long addr;
-
- mm = &init_mm;
- for(addr = start_vm; addr < end_vm;){
- pgd = pgd_offset(mm, addr);
- pud = pud_offset(pgd, addr);
- pmd = pmd_offset(pud, addr);
- if(pmd_present(*pmd)){
- pte = pte_offset_kernel(pmd, addr);
- if(pte_present(*pte)) protect_vm_page(addr, w, 0);
- addr += PAGE_SIZE;
- }
- else addr += PMD_SIZE;
- }
-}
-
void flush_tlb_kernel_vm_tt(void)
{
flush_tlb_kernel_range(start_vm, end_vm);
diff --git a/arch/v850/kernel/ptrace.c b/arch/v850/kernel/ptrace.c
index 4726b87f5e5a..d6077ff47d22 100644
--- a/arch/v850/kernel/ptrace.c
+++ b/arch/v850/kernel/ptrace.c
@@ -113,7 +113,7 @@ static int set_single_step (struct task_struct *t, int val)
return 1;
}
-int sys_ptrace(long request, long pid, long addr, long data)
+long sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
int rval;
diff --git a/arch/v850/kernel/time.c b/arch/v850/kernel/time.c
index ea3fd8844ff0..c1e85c2aef65 100644
--- a/arch/v850/kernel/time.c
+++ b/arch/v850/kernel/time.c
@@ -26,10 +26,6 @@
#include "mach.h"
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
#define TICK_SIZE (tick_nsec / 1000)
/*
diff --git a/arch/x86_64/ia32/ia32_aout.c b/arch/x86_64/ia32/ia32_aout.c
index 3e6780fa0186..93c60f4aa47a 100644
--- a/arch/x86_64/ia32/ia32_aout.c
+++ b/arch/x86_64/ia32/ia32_aout.c
@@ -314,7 +314,6 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
current->mm->free_area_cache = TASK_UNMAPPED_BASE;
current->mm->cached_hole_size = 0;
- set_mm_counter(current->mm, rss, 0);
current->mm->mmap = NULL;
compute_creds(bprm);
current->flags &= ~PF_FORKNOEXEC;
diff --git a/arch/x86_64/ia32/ia32_ioctl.c b/arch/x86_64/ia32/ia32_ioctl.c
index 419758f19ca4..4ba0e293d5e5 100644
--- a/arch/x86_64/ia32/ia32_ioctl.c
+++ b/arch/x86_64/ia32/ia32_ioctl.c
@@ -12,40 +12,11 @@
#define INCLUDES
#include <linux/syscalls.h>
#include "compat_ioctl.c"
-#include <asm/mtrr.h>
#include <asm/ia32.h>
#define CODE
#include "compat_ioctl.c"
-#ifndef TIOCGDEV
-#define TIOCGDEV _IOR('T',0x32, unsigned int)
-#endif
-static int tiocgdev(unsigned fd, unsigned cmd, unsigned int __user *ptr)
-{
-
- struct file *file;
- struct tty_struct *real_tty;
- int fput_needed, ret;
-
- file = fget_light(fd, &fput_needed);
- if (!file)
- return -EBADF;
-
- ret = -EINVAL;
- if (file->f_op->ioctl != tty_ioctl)
- goto out;
- real_tty = (struct tty_struct *)file->private_data;
- if (!real_tty)
- goto out;
-
- ret = put_user(new_encode_dev(tty_devnum(real_tty)), ptr);
-
-out:
- fput_light(file, fput_needed);
- return ret;
-}
-
#define RTC_IRQP_READ32 _IOR('p', 0x0b, unsigned int) /* Read IRQ rate */
#define RTC_IRQP_SET32 _IOW('p', 0x0c, unsigned int) /* Set IRQ rate */
#define RTC_EPOCH_READ32 _IOR('p', 0x0d, unsigned) /* Read epoch */
@@ -85,90 +56,6 @@ static int rtc32_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
return sys_ioctl(fd,cmd,arg);
}
-/* /proc/mtrr ioctls */
-
-
-struct mtrr_sentry32
-{
- compat_ulong_t base; /* Base address */
- compat_uint_t size; /* Size of region */
- compat_uint_t type; /* Type of region */
-};
-
-struct mtrr_gentry32
-{
- compat_ulong_t regnum; /* Register number */
- compat_uint_t base; /* Base address */
- compat_uint_t size; /* Size of region */
- compat_uint_t type; /* Type of region */
-};
-
-#define MTRR_IOCTL_BASE 'M'
-
-#define MTRRIOC32_ADD_ENTRY _IOW(MTRR_IOCTL_BASE, 0, struct mtrr_sentry32)
-#define MTRRIOC32_SET_ENTRY _IOW(MTRR_IOCTL_BASE, 1, struct mtrr_sentry32)
-#define MTRRIOC32_DEL_ENTRY _IOW(MTRR_IOCTL_BASE, 2, struct mtrr_sentry32)
-#define MTRRIOC32_GET_ENTRY _IOWR(MTRR_IOCTL_BASE, 3, struct mtrr_gentry32)
-#define MTRRIOC32_KILL_ENTRY _IOW(MTRR_IOCTL_BASE, 4, struct mtrr_sentry32)
-#define MTRRIOC32_ADD_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 5, struct mtrr_sentry32)
-#define MTRRIOC32_SET_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 6, struct mtrr_sentry32)
-#define MTRRIOC32_DEL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 7, struct mtrr_sentry32)
-#define MTRRIOC32_GET_PAGE_ENTRY _IOWR(MTRR_IOCTL_BASE, 8, struct mtrr_gentry32)
-#define MTRRIOC32_KILL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 9, struct mtrr_sentry32)
-
-
-static int mtrr_ioctl32(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- struct mtrr_gentry g;
- struct mtrr_sentry s;
- int get = 0, err = 0;
- struct mtrr_gentry32 __user *g32 = (struct mtrr_gentry32 __user *)arg;
- mm_segment_t oldfs = get_fs();
-
- switch (cmd) {
-#define SET(x) case MTRRIOC32_ ## x ## _ENTRY: cmd = MTRRIOC_ ## x ## _ENTRY; break
-#define GET(x) case MTRRIOC32_ ## x ## _ENTRY: cmd = MTRRIOC_ ## x ## _ENTRY; get=1; break
- SET(ADD);
- SET(SET);
- SET(DEL);
- GET(GET);
- SET(KILL);
- SET(ADD_PAGE);
- SET(SET_PAGE);
- SET(DEL_PAGE);
- GET(GET_PAGE);
- SET(KILL_PAGE);
- }
-
- if (get) {
- err = get_user(g.regnum, &g32->regnum);
- err |= get_user(g.base, &g32->base);
- err |= get_user(g.size, &g32->size);
- err |= get_user(g.type, &g32->type);
-
- arg = (unsigned long)&g;
- } else {
- struct mtrr_sentry32 __user *s32 = (struct mtrr_sentry32 __user *)arg;
- err = get_user(s.base, &s32->base);
- err |= get_user(s.size, &s32->size);
- err |= get_user(s.type, &s32->type);
-
- arg = (unsigned long)&s;
- }
- if (err) return err;
-
- set_fs(KERNEL_DS);
- err = sys_ioctl(fd, cmd, arg);
- set_fs(oldfs);
-
- if (!err && get) {
- err = put_user(g.base, &g32->base);
- err |= put_user(g.size, &g32->size);
- err |= put_user(g.regnum, &g32->regnum);
- err |= put_user(g.type, &g32->type);
- }
- return err;
-}
#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl_trans_handler_t)(handler) },
#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd,sys_ioctl)
@@ -185,7 +72,6 @@ COMPATIBLE_IOCTL(0x4B51) /* KDSHWCLK - not in the kernel, but don't complain *
COMPATIBLE_IOCTL(FIOQSIZE)
/* And these ioctls need translation */
-HANDLE_IOCTL(TIOCGDEV, tiocgdev)
/* realtime device */
HANDLE_IOCTL(RTC_IRQP_READ, rtc32_ioctl)
HANDLE_IOCTL(RTC_IRQP_READ32,rtc32_ioctl)
@@ -193,17 +79,6 @@ HANDLE_IOCTL(RTC_IRQP_SET32, rtc32_ioctl)
HANDLE_IOCTL(RTC_EPOCH_READ32, rtc32_ioctl)
HANDLE_IOCTL(RTC_EPOCH_SET32, rtc32_ioctl)
/* take care of sizeof(sizeof()) breakage */
-/* mtrr */
-HANDLE_IOCTL(MTRRIOC32_ADD_ENTRY, mtrr_ioctl32)
-HANDLE_IOCTL(MTRRIOC32_SET_ENTRY, mtrr_ioctl32)
-HANDLE_IOCTL(MTRRIOC32_DEL_ENTRY, mtrr_ioctl32)
-HANDLE_IOCTL(MTRRIOC32_GET_ENTRY, mtrr_ioctl32)
-HANDLE_IOCTL(MTRRIOC32_KILL_ENTRY, mtrr_ioctl32)
-HANDLE_IOCTL(MTRRIOC32_ADD_PAGE_ENTRY, mtrr_ioctl32)
-HANDLE_IOCTL(MTRRIOC32_SET_PAGE_ENTRY, mtrr_ioctl32)
-HANDLE_IOCTL(MTRRIOC32_DEL_PAGE_ENTRY, mtrr_ioctl32)
-HANDLE_IOCTL(MTRRIOC32_GET_PAGE_ENTRY, mtrr_ioctl32)
-HANDLE_IOCTL(MTRRIOC32_KILL_PAGE_ENTRY, mtrr_ioctl32)
};
int ioctl_table_size = ARRAY_SIZE(ioctl_start);
diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c
index b2a238b5a17e..c6c9791d77c1 100644
--- a/arch/x86_64/kernel/i8259.c
+++ b/arch/x86_64/kernel/i8259.c
@@ -494,7 +494,7 @@ void invalidate_interrupt7(void);
void thermal_interrupt(void);
void i8254_timer_resume(void);
-static void setup_timer(void)
+static void setup_timer_hardware(void)
{
outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */
udelay(10);
@@ -505,13 +505,13 @@ static void setup_timer(void)
static int timer_resume(struct sys_device *dev)
{
- setup_timer();
+ setup_timer_hardware();
return 0;
}
void i8254_timer_resume(void)
{
- setup_timer();
+ setup_timer_hardware();
}
static struct sysdev_class timer_sysclass = {
@@ -594,7 +594,7 @@ void __init init_IRQ(void)
* Set the clock to HZ Hz, we already have a valid
* vector now:
*/
- setup_timer();
+ setup_timer_hardware();
if (!acpi_ioapic)
setup_irq(2, &irq2);
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index cb28df14ff6f..da0bc3e7bdf5 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -1213,7 +1213,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* Intel-defined (#2) */
- "pni", NULL, NULL, "monitor", "ds_cpl", NULL, NULL, "est",
+ "pni", NULL, NULL, "monitor", "ds_cpl", "vmx", NULL, "est",
"tm2", NULL, "cid", NULL, NULL, "cx16", "xtpr", NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
diff --git a/arch/x86_64/kernel/suspend.c b/arch/x86_64/kernel/suspend.c
index f066c6ab3618..fd2bef780882 100644
--- a/arch/x86_64/kernel/suspend.c
+++ b/arch/x86_64/kernel/suspend.c
@@ -63,13 +63,12 @@ void save_processor_state(void)
__save_processor_state(&saved_context);
}
-static void
-do_fpu_end(void)
+static void do_fpu_end(void)
{
- /* restore FPU regs if necessary */
- /* Do it out of line so that gcc does not move cr0 load to some stupid place */
- kernel_fpu_end();
- mxcsr_feature_mask_init();
+ /*
+ * Restore FPU regs if necessary
+ */
+ kernel_fpu_end();
}
void __restore_processor_state(struct saved_context *ctxt)
@@ -148,57 +147,7 @@ extern int restore_image(void);
pgd_t *temp_level4_pgt;
-static void **pages;
-
-static inline void *__add_page(void)
-{
- void **c;
-
- c = (void **)get_usable_page(GFP_ATOMIC);
- if (c) {
- *c = pages;
- pages = c;
- }
- return c;
-}
-
-static inline void *__next_page(void)
-{
- void **c;
-
- c = pages;
- if (c) {
- pages = *c;
- *c = NULL;
- }
- return c;
-}
-
-/*
- * Try to allocate as many usable pages as needed and daisy chain them.
- * If one allocation fails, free the pages allocated so far
- */
-static int alloc_usable_pages(unsigned long n)
-{
- void *p;
-
- pages = NULL;
- do
- if (!__add_page())
- break;
- while (--n);
- if (n) {
- p = __next_page();
- while (p) {
- free_page((unsigned long)p);
- p = __next_page();
- }
- return -ENOMEM;
- }
- return 0;
-}
-
-static void res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long end)
+static int res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long end)
{
long i, j;
@@ -212,7 +161,9 @@ static void res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long e
if (paddr >= end)
break;
- pmd = (pmd_t *)__next_page();
+ pmd = (pmd_t *)get_safe_page(GFP_ATOMIC);
+ if (!pmd)
+ return -ENOMEM;
set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE));
for (j = 0; j < PTRS_PER_PMD; pmd++, j++, paddr += PMD_SIZE) {
unsigned long pe;
@@ -224,13 +175,17 @@ static void res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long e
set_pmd(pmd, __pmd(pe));
}
}
+ return 0;
}
-static void set_up_temporary_mappings(void)
+static int set_up_temporary_mappings(void)
{
unsigned long start, end, next;
+ int error;
- temp_level4_pgt = (pgd_t *)__next_page();
+ temp_level4_pgt = (pgd_t *)get_safe_page(GFP_ATOMIC);
+ if (!temp_level4_pgt)
+ return -ENOMEM;
/* It is safe to reuse the original kernel mapping */
set_pgd(temp_level4_pgt + pgd_index(__START_KERNEL_map),
@@ -241,29 +196,27 @@ static void set_up_temporary_mappings(void)
end = (unsigned long)pfn_to_kaddr(end_pfn);
for (; start < end; start = next) {
- pud_t *pud = (pud_t *)__next_page();
+ pud_t *pud = (pud_t *)get_safe_page(GFP_ATOMIC);
+ if (!pud)
+ return -ENOMEM;
next = start + PGDIR_SIZE;
if (next > end)
next = end;
- res_phys_pud_init(pud, __pa(start), __pa(next));
+ if ((error = res_phys_pud_init(pud, __pa(start), __pa(next))))
+ return error;
set_pgd(temp_level4_pgt + pgd_index(start),
mk_kernel_pgd(__pa(pud)));
}
+ return 0;
}
int swsusp_arch_resume(void)
{
- unsigned long n;
+ int error;
- n = ((end_pfn << PAGE_SHIFT) + PUD_SIZE - 1) >> PUD_SHIFT;
- n += (n + PTRS_PER_PUD - 1) / PTRS_PER_PUD + 1;
- pr_debug("swsusp_arch_resume(): pages needed = %lu\n", n);
- if (alloc_usable_pages(n)) {
- free_eaten_memory();
- return -ENOMEM;
- }
/* We have got enough memory and from now on we cannot recover */
- set_up_temporary_mappings();
+ if ((error = set_up_temporary_mappings()))
+ return error;
restore_image();
return 0;
}
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index 703acde2a1a5..fdaddc4e5284 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -42,10 +42,6 @@
#include <asm/apic.h>
#endif
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
#ifdef CONFIG_CPU_FREQ
static void cpufreq_delayed_get(void);
#endif
@@ -481,9 +477,9 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static unsigned int cyc2ns_scale;
#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
-static inline void set_cyc2ns_scale(unsigned long cpu_mhz)
+static inline void set_cyc2ns_scale(unsigned long cpu_khz)
{
- cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz;
+ cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz;
}
static inline unsigned long long cycles_2_ns(unsigned long long cyc)
@@ -655,7 +651,7 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
vxtime.tsc_quot = (1000L << 32) / cpu_khz;
}
- set_cyc2ns_scale(cpu_khz_ref / 1000);
+ set_cyc2ns_scale(cpu_khz_ref);
return 0;
}
@@ -939,7 +935,7 @@ void __init time_init(void)
rdtscll_sync(&vxtime.last_tsc);
setup_irq(0, &irq0);
- set_cyc2ns_scale(cpu_khz / 1000);
+ set_cyc2ns_scale(cpu_khz);
#ifndef CONFIG_SMP
time_init_gtod();
@@ -1093,6 +1089,7 @@ static unsigned long PIE_freq = DEFAULT_RTC_INT_FREQ;
static unsigned long PIE_count;
static unsigned long hpet_rtc_int_freq; /* RTC interrupt frequency */
+static unsigned int hpet_t1_cmp; /* cached comparator register */
int is_hpet_enabled(void)
{
@@ -1129,10 +1126,12 @@ int hpet_rtc_timer_init(void)
cnt = hpet_readl(HPET_COUNTER);
cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq);
hpet_writel(cnt, HPET_T1_CMP);
+ hpet_t1_cmp = cnt;
local_irq_restore(flags);
cfg = hpet_readl(HPET_T1_CFG);
- cfg |= HPET_TN_ENABLE | HPET_TN_SETVAL | HPET_TN_32BIT;
+ cfg &= ~HPET_TN_PERIODIC;
+ cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
hpet_writel(cfg, HPET_T1_CFG);
return 1;
@@ -1142,8 +1141,12 @@ static void hpet_rtc_timer_reinit(void)
{
unsigned int cfg, cnt;
- if (!(PIE_on | AIE_on | UIE_on))
+ if (unlikely(!(PIE_on | AIE_on | UIE_on))) {
+ cfg = hpet_readl(HPET_T1_CFG);
+ cfg &= ~HPET_TN_ENABLE;
+ hpet_writel(cfg, HPET_T1_CFG);
return;
+ }
if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ))
hpet_rtc_int_freq = PIE_freq;
@@ -1151,15 +1154,10 @@ static void hpet_rtc_timer_reinit(void)
hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;
/* It is more accurate to use the comparator value than current count.*/
- cnt = hpet_readl(HPET_T1_CMP);
+ cnt = hpet_t1_cmp;
cnt += hpet_tick*HZ/hpet_rtc_int_freq;
hpet_writel(cnt, HPET_T1_CMP);
-
- cfg = hpet_readl(HPET_T1_CFG);
- cfg |= HPET_TN_ENABLE | HPET_TN_SETVAL | HPET_TN_32BIT;
- hpet_writel(cfg, HPET_T1_CFG);
-
- return;
+ hpet_t1_cmp = cnt;
}
/*
diff --git a/arch/x86_64/mm/ioremap.c b/arch/x86_64/mm/ioremap.c
index 6972df480d2b..ecf7acb5db9b 100644
--- a/arch/x86_64/mm/ioremap.c
+++ b/arch/x86_64/mm/ioremap.c
@@ -60,7 +60,7 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned lo
if (address >= end)
BUG();
do {
- pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
+ pte_t * pte = pte_alloc_kernel(pmd, address);
if (!pte)
return -ENOMEM;
remap_area_pte(pte, address, end - address, address + phys_addr, flags);
@@ -105,7 +105,6 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr,
flush_cache_all();
if (address >= end)
BUG();
- spin_lock(&init_mm.page_table_lock);
do {
pud_t *pud;
pud = pud_alloc(&init_mm, pgd, address);
@@ -119,7 +118,6 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr,
address = (address + PGDIR_SIZE) & PGDIR_MASK;
pgd++;
} while (address && (address < end));
- spin_unlock(&init_mm.page_table_lock);
flush_tlb_all();
return error;
}
diff --git a/arch/xtensa/kernel/platform.c b/arch/xtensa/kernel/platform.c
index 03674daabc66..a17930747f20 100644
--- a/arch/xtensa/kernel/platform.c
+++ b/arch/xtensa/kernel/platform.c
@@ -18,6 +18,7 @@
#include <linux/time.h>
#include <asm/platform.h>
#include <asm/timex.h>
+#include <asm/param.h> /* HZ */
#define _F(r,f,a,b) \
r __platform_##f a b; \
diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c
index 2659efdd4e99..14460743de07 100644
--- a/arch/xtensa/kernel/ptrace.c
+++ b/arch/xtensa/kernel/ptrace.c
@@ -45,7 +45,7 @@ void ptrace_disable(struct task_struct *child)
/* Nothing to do.. */
}
-int sys_ptrace(long request, long pid, long addr, long data)
+long sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
int ret = -EPERM;
diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c
index 8e423d1335ce..cb6e38ed2b1d 100644
--- a/arch/xtensa/kernel/time.c
+++ b/arch/xtensa/kernel/time.c
@@ -29,9 +29,6 @@
extern volatile unsigned long wall_jiffies;
-u64 jiffies_64 = INITIAL_JIFFIES;
-EXPORT_SYMBOL(jiffies_64);
-
spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
EXPORT_SYMBOL(rtc_lock);
diff --git a/crypto/api.c b/crypto/api.c
index 959c4e5f264f..40ae42e9b6a6 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -215,7 +215,10 @@ int crypto_register_alg(struct crypto_alg *alg)
if (alg->cra_alignmask & (alg->cra_alignmask + 1))
return -EINVAL;
- if (alg->cra_alignmask > PAGE_SIZE)
+ if (alg->cra_alignmask & alg->cra_blocksize)
+ return -EINVAL;
+
+ if (alg->cra_blocksize > PAGE_SIZE)
return -EINVAL;
down_write(&crypto_alg_sem);
diff --git a/crypto/hmac.c b/crypto/hmac.c
index da0456b37109..46120dee5ada 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -18,18 +18,15 @@
#include <linux/mm.h>
#include <linux/highmem.h>
#include <linux/slab.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
#include "internal.h"
static void hash_key(struct crypto_tfm *tfm, u8 *key, unsigned int keylen)
{
struct scatterlist tmp;
- tmp.page = virt_to_page(key);
- tmp.offset = offset_in_page(key);
- tmp.length = keylen;
+ sg_set_buf(&tmp, key, keylen);
crypto_digest_digest(tfm, &tmp, 1, key);
-
}
int crypto_alloc_hmac_block(struct crypto_tfm *tfm)
@@ -69,9 +66,7 @@ void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen)
for (i = 0; i < crypto_tfm_alg_blocksize(tfm); i++)
ipad[i] ^= 0x36;
- tmp.page = virt_to_page(ipad);
- tmp.offset = offset_in_page(ipad);
- tmp.length = crypto_tfm_alg_blocksize(tfm);
+ sg_set_buf(&tmp, ipad, crypto_tfm_alg_blocksize(tfm));
crypto_digest_init(tfm);
crypto_digest_update(tfm, &tmp, 1);
@@ -103,16 +98,12 @@ void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key,
for (i = 0; i < crypto_tfm_alg_blocksize(tfm); i++)
opad[i] ^= 0x5c;
- tmp.page = virt_to_page(opad);
- tmp.offset = offset_in_page(opad);
- tmp.length = crypto_tfm_alg_blocksize(tfm);
+ sg_set_buf(&tmp, opad, crypto_tfm_alg_blocksize(tfm));
crypto_digest_init(tfm);
crypto_digest_update(tfm, &tmp, 1);
- tmp.page = virt_to_page(out);
- tmp.offset = offset_in_page(out);
- tmp.length = crypto_tfm_alg_digestsize(tfm);
+ sg_set_buf(&tmp, out, crypto_tfm_alg_digestsize(tfm));
crypto_digest_update(tfm, &tmp, 1);
crypto_digest_final(tfm, out);
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 68639419c5bd..53f4ee804bdb 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -21,7 +21,7 @@
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/slab.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
#include <linux/string.h>
#include <linux/crypto.h>
#include <linux/highmem.h>
@@ -86,7 +86,6 @@ static void hexdump(unsigned char *buf, unsigned int len)
static void test_hash(char *algo, struct hash_testvec *template,
unsigned int tcount)
{
- char *p;
unsigned int i, j, k, temp;
struct scatterlist sg[8];
char result[64];
@@ -116,10 +115,7 @@ static void test_hash(char *algo, struct hash_testvec *template,
printk("test %u:\n", i + 1);
memset(result, 0, 64);
- p = hash_tv[i].plaintext;
- sg[0].page = virt_to_page(p);
- sg[0].offset = offset_in_page(p);
- sg[0].length = hash_tv[i].psize;
+ sg_set_buf(&sg[0], hash_tv[i].plaintext, hash_tv[i].psize);
crypto_digest_init(tfm);
if (tfm->crt_u.digest.dit_setkey) {
@@ -154,10 +150,8 @@ static void test_hash(char *algo, struct hash_testvec *template,
hash_tv[i].plaintext + temp,
hash_tv[i].tap[k]);
temp += hash_tv[i].tap[k];
- p = &xbuf[IDX[k]];
- sg[k].page = virt_to_page(p);
- sg[k].offset = offset_in_page(p);
- sg[k].length = hash_tv[i].tap[k];
+ sg_set_buf(&sg[k], &xbuf[IDX[k]],
+ hash_tv[i].tap[k]);
}
crypto_digest_digest(tfm, sg, hash_tv[i].np, result);
@@ -179,7 +173,6 @@ static void test_hash(char *algo, struct hash_testvec *template,
static void test_hmac(char *algo, struct hmac_testvec *template,
unsigned int tcount)
{
- char *p;
unsigned int i, j, k, temp;
struct scatterlist sg[8];
char result[64];
@@ -210,11 +203,8 @@ static void test_hmac(char *algo, struct hmac_testvec *template,
printk("test %u:\n", i + 1);
memset(result, 0, sizeof (result));
- p = hmac_tv[i].plaintext;
klen = hmac_tv[i].ksize;
- sg[0].page = virt_to_page(p);
- sg[0].offset = offset_in_page(p);
- sg[0].length = hmac_tv[i].psize;
+ sg_set_buf(&sg[0], hmac_tv[i].plaintext, hmac_tv[i].psize);
crypto_hmac(tfm, hmac_tv[i].key, &klen, sg, 1, result);
@@ -243,10 +233,8 @@ static void test_hmac(char *algo, struct hmac_testvec *template,
hmac_tv[i].plaintext + temp,
hmac_tv[i].tap[k]);
temp += hmac_tv[i].tap[k];
- p = &xbuf[IDX[k]];
- sg[k].page = virt_to_page(p);
- sg[k].offset = offset_in_page(p);
- sg[k].length = hmac_tv[i].tap[k];
+ sg_set_buf(&sg[k], &xbuf[IDX[k]],
+ hmac_tv[i].tap[k]);
}
crypto_hmac(tfm, hmac_tv[i].key, &klen, sg,
@@ -270,7 +258,7 @@ static void test_cipher(char *algo, int mode, int enc,
{
unsigned int ret, i, j, k, temp;
unsigned int tsize;
- char *p, *q;
+ char *q;
struct crypto_tfm *tfm;
char *key;
struct cipher_testvec *cipher_tv;
@@ -330,10 +318,8 @@ static void test_cipher(char *algo, int mode, int enc,
goto out;
}
- p = cipher_tv[i].input;
- sg[0].page = virt_to_page(p);
- sg[0].offset = offset_in_page(p);
- sg[0].length = cipher_tv[i].ilen;
+ sg_set_buf(&sg[0], cipher_tv[i].input,
+ cipher_tv[i].ilen);
if (!mode) {
crypto_cipher_set_iv(tfm, cipher_tv[i].iv,
@@ -389,10 +375,8 @@ static void test_cipher(char *algo, int mode, int enc,
cipher_tv[i].input + temp,
cipher_tv[i].tap[k]);
temp += cipher_tv[i].tap[k];
- p = &xbuf[IDX[k]];
- sg[k].page = virt_to_page(p);
- sg[k].offset = offset_in_page(p);
- sg[k].length = cipher_tv[i].tap[k];
+ sg_set_buf(&sg[k], &xbuf[IDX[k]],
+ cipher_tv[i].tap[k]);
}
if (!mode) {
@@ -431,14 +415,12 @@ out:
static int test_cipher_jiffies(struct crypto_tfm *tfm, int enc, char *p,
int blen, int sec)
{
- struct scatterlist sg[8];
+ struct scatterlist sg[1];
unsigned long start, end;
int bcount;
int ret;
- sg[0].page = virt_to_page(p);
- sg[0].offset = offset_in_page(p);
- sg[0].length = blen;
+ sg_set_buf(sg, p, blen);
for (start = jiffies, end = start + sec * HZ, bcount = 0;
time_before(jiffies, end); bcount++) {
@@ -459,14 +441,12 @@ static int test_cipher_jiffies(struct crypto_tfm *tfm, int enc, char *p,
static int test_cipher_cycles(struct crypto_tfm *tfm, int enc, char *p,
int blen)
{
- struct scatterlist sg[8];
+ struct scatterlist sg[1];
unsigned long cycles = 0;
int ret = 0;
int i;
- sg[0].page = virt_to_page(p);
- sg[0].offset = offset_in_page(p);
- sg[0].length = blen;
+ sg_set_buf(sg, p, blen);
local_bh_disable();
local_irq_disable();
@@ -709,9 +689,7 @@ static void test_crc32c(void)
for (i = 0; i < NUMVEC; i++) {
for (j = 0; j < VECSIZE; j++)
test_vec[i][j] = ++b;
- sg[i].page = virt_to_page(test_vec[i]);
- sg[i].offset = offset_in_page(test_vec[i]);
- sg[i].length = VECSIZE;
+ sg_set_buf(&sg[i], test_vec[i], VECSIZE);
}
seed = SEEDTESTVAL;
diff --git a/drivers/acorn/char/pcf8583.c b/drivers/acorn/char/pcf8583.c
index 2b850e5860a0..e26f007a1417 100644
--- a/drivers/acorn/char/pcf8583.c
+++ b/drivers/acorn/char/pcf8583.c
@@ -9,6 +9,7 @@
*
* Driver for PCF8583 RTC & RAM chip
*/
+#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/string.h>
@@ -32,7 +33,8 @@ static struct i2c_client_address_data addr_data = {
.forces = forces,
};
-#define DAT(x) ((unsigned int)(x->dev.driver_data))
+#define set_ctrl(x, v) i2c_set_clientdata(x, (void *)(unsigned int)(v))
+#define get_ctrl(x) ((unsigned int)i2c_get_clientdata(x))
static int
pcf8583_attach(struct i2c_adapter *adap, int addr, int kind)
@@ -40,8 +42,17 @@ pcf8583_attach(struct i2c_adapter *adap, int addr, int kind)
struct i2c_client *c;
unsigned char buf[1], ad[1] = { 0 };
struct i2c_msg msgs[2] = {
- { addr, 0, 1, ad },
- { addr, I2C_M_RD, 1, buf }
+ {
+ .addr = addr,
+ .flags = 0,
+ .len = 1,
+ .buf = ad,
+ }, {
+ .addr = addr,
+ .flags = I2C_M_RD,
+ .len = 1,
+ .buf = buf,
+ }
};
c = kmalloc(sizeof(*c), GFP_KERNEL);
@@ -54,7 +65,7 @@ pcf8583_attach(struct i2c_adapter *adap, int addr, int kind)
c->driver = &pcf8583_driver;
if (i2c_transfer(c->adapter, msgs, 2) == 2)
- DAT(c) = buf[0];
+ set_ctrl(c, buf[0]);
return i2c_attach_client(c);
}
@@ -78,8 +89,17 @@ pcf8583_get_datetime(struct i2c_client *client, struct rtc_tm *dt)
{
unsigned char buf[8], addr[1] = { 1 };
struct i2c_msg msgs[2] = {
- { client->addr, 0, 1, addr },
- { client->addr, I2C_M_RD, 6, buf }
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 1,
+ .buf = addr,
+ }, {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = 6,
+ .buf = buf,
+ }
};
int ret = -EIO;
@@ -113,7 +133,7 @@ pcf8583_set_datetime(struct i2c_client *client, struct rtc_tm *dt, int datetoo)
int ret, len = 6;
buf[0] = 0;
- buf[1] = DAT(client) | 0x80;
+ buf[1] = get_ctrl(client) | 0x80;
buf[2] = BIN_TO_BCD(dt->cs);
buf[3] = BIN_TO_BCD(dt->secs);
buf[4] = BIN_TO_BCD(dt->mins);
@@ -129,7 +149,7 @@ pcf8583_set_datetime(struct i2c_client *client, struct rtc_tm *dt, int datetoo)
if (ret == len)
ret = 0;
- buf[1] = DAT(client);
+ buf[1] = get_ctrl(client);
i2c_master_send(client, (char *)buf, 2);
return ret;
@@ -138,7 +158,7 @@ pcf8583_set_datetime(struct i2c_client *client, struct rtc_tm *dt, int datetoo)
static int
pcf8583_get_ctrl(struct i2c_client *client, unsigned char *ctrl)
{
- *ctrl = DAT(client);
+ *ctrl = get_ctrl(client);
return 0;
}
@@ -149,7 +169,7 @@ pcf8583_set_ctrl(struct i2c_client *client, unsigned char *ctrl)
buf[0] = 0;
buf[1] = *ctrl;
- DAT(client) = *ctrl;
+ set_ctrl(client, *ctrl);
return i2c_master_send(client, (char *)buf, 2);
}
@@ -159,15 +179,23 @@ pcf8583_read_mem(struct i2c_client *client, struct mem *mem)
{
unsigned char addr[1];
struct i2c_msg msgs[2] = {
- { client->addr, 0, 1, addr },
- { client->addr, I2C_M_RD, 0, mem->data }
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 1,
+ .buf = addr,
+ }, {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = mem->nr,
+ .buf = mem->data,
+ }
};
if (mem->loc < 8)
return -EINVAL;
addr[0] = mem->loc;
- msgs[1].len = mem->nr;
return i2c_transfer(client->adapter, msgs, 2) == 2 ? 0 : -EIO;
}
@@ -177,15 +205,23 @@ pcf8583_write_mem(struct i2c_client *client, struct mem *mem)
{
unsigned char addr[1];
struct i2c_msg msgs[2] = {
- { client->addr, 0, 1, addr },
- { client->addr, 0, 0, mem->data }
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 1,
+ .buf = addr,
+ }, {
+ .addr = client->addr,
+ .flags = I2C_M_NOSTART,
+ .len = mem->nr,
+ .buf = mem->data,
+ }
};
if (mem->loc < 8)
return -EINVAL;
addr[0] = mem->loc;
- msgs[1].len = mem->nr;
return i2c_transfer(client->adapter, msgs, 2) == 2 ? 0 : -EIO;
}
@@ -234,4 +270,14 @@ static __init int pcf8583_init(void)
return i2c_add_driver(&pcf8583_driver);
}
-__initcall(pcf8583_init);
+static __exit void pcf8583_exit(void)
+{
+ i2c_del_driver(&pcf8583_driver);
+}
+
+module_init(pcf8583_init);
+module_exit(pcf8583_exit);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("PCF8583 I2C RTC driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
index 01a1bd239263..2143609d2936 100644
--- a/drivers/acpi/acpi_memhotplug.c
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -200,8 +200,7 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device)
* Note: Assume that this function returns zero on success
*/
result = add_memory(mem_device->start_addr,
- (mem_device->end_addr - mem_device->start_addr) + 1,
- mem_device->read_write_attribute);
+ (mem_device->end_addr - mem_device->start_addr) + 1);
if (result) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "\nadd_memory failed\n"));
mem_device->state = MEMORY_INVALID_STATE;
@@ -259,7 +258,7 @@ static int acpi_memory_disable_device(struct acpi_memory_device *mem_device)
* Ask the VM to offline this memory range.
* Note: Assume that this function returns zero on success
*/
- result = remove_memory(start, len, attr);
+ result = remove_memory(start, len);
if (result) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Hot-Remove failed.\n"));
return_VALUE(result);
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 26a3a4016115..161db4acfb91 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -37,6 +37,7 @@
#include <linux/acpi.h>
#include <linux/dmi.h>
#include <linux/moduleparam.h>
+#include <linux/sched.h> /* need_resched() */
#include <asm/io.h>
#include <asm/uaccess.h>
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index aee50b453265..930427fc0c4b 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -158,7 +158,15 @@ int acpi_suspend(u32 acpi_state)
return -EINVAL;
}
+static int acpi_pm_state_valid(suspend_state_t pm_state)
+{
+ u32 acpi_state = acpi_suspend_states[pm_state];
+
+ return sleep_states[acpi_state];
+}
+
static struct pm_ops acpi_pm_ops = {
+ .valid = acpi_pm_state_valid,
.prepare = acpi_pm_prepare,
.enter = acpi_pm_enter,
.finish = acpi_pm_finish,
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 66d9c4643fc1..f12898d53078 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -7,6 +7,7 @@ obj-y := core.o sys.o bus.o dd.o \
obj-y += power/
obj-$(CONFIG_FW_LOADER) += firmware_class.o
obj-$(CONFIG_NUMA) += node.o
+obj-$(CONFIG_MEMORY_HOTPLUG) += memory.o
ifeq ($(CONFIG_DEBUG_DRIVER),y)
EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/base/class.c b/drivers/base/class.c
index c3e569730afe..db65fd0babe9 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -17,6 +17,7 @@
#include <linux/string.h>
#include <linux/kdev_t.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include "base.h"
#define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr)
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 081c927b1ed8..a95844790f7b 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -16,6 +16,8 @@ struct sysdev_class cpu_sysdev_class = {
};
EXPORT_SYMBOL(cpu_sysdev_class);
+static struct sys_device *cpu_sys_devices[NR_CPUS];
+
#ifdef CONFIG_HOTPLUG_CPU
int __attribute__((weak)) smp_prepare_cpu (int cpu)
{
@@ -64,6 +66,7 @@ static void __devinit register_cpu_control(struct cpu *cpu)
}
void unregister_cpu(struct cpu *cpu, struct node *root)
{
+ int logical_cpu = cpu->sysdev.id;
if (root)
sysfs_remove_link(&root->sysdev.kobj,
@@ -71,7 +74,7 @@ void unregister_cpu(struct cpu *cpu, struct node *root)
sysdev_remove_file(&cpu->sysdev, &attr_online);
sysdev_unregister(&cpu->sysdev);
-
+ cpu_sys_devices[logical_cpu] = NULL;
return;
}
#else /* ... !CONFIG_HOTPLUG_CPU */
@@ -103,10 +106,19 @@ int __devinit register_cpu(struct cpu *cpu, int num, struct node *root)
kobject_name(&cpu->sysdev.kobj));
if (!error && !cpu->no_control)
register_cpu_control(cpu);
+ if (!error)
+ cpu_sys_devices[num] = &cpu->sysdev;
return error;
}
-
+struct sys_device *get_cpu_sysdev(int cpu)
+{
+ if (cpu < NR_CPUS)
+ return cpu_sys_devices[cpu];
+ else
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(get_cpu_sysdev);
int __init cpu_dev_init(void)
{
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 4acb2c5733c3..98f6c02d6790 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -62,14 +62,16 @@ firmware_timeout_show(struct class *class, char *buf)
}
/**
- * firmware_timeout_store:
- * Description:
+ * firmware_timeout_store - set number of seconds to wait for firmware
+ * @class: device class pointer
+ * @buf: buffer to scan for timeout value
+ * @count: number of bytes in @buf
+ *
* Sets the number of seconds to wait for the firmware. Once
- * this expires an error will be return to the driver and no
+ * this expires an error will be returned to the driver and no
* firmware will be provided.
*
- * Note: zero means 'wait for ever'
- *
+ * Note: zero means 'wait forever'.
**/
static ssize_t
firmware_timeout_store(struct class *class, const char *buf, size_t count)
@@ -123,12 +125,15 @@ firmware_loading_show(struct class_device *class_dev, char *buf)
}
/**
- * firmware_loading_store: - loading control file
- * Description:
+ * firmware_loading_store - set value in the 'loading' control file
+ * @class_dev: class_device pointer
+ * @buf: buffer to scan for loading control value
+ * @count: number of bytes in @buf
+ *
* The relevant values are:
*
* 1: Start a load, discarding any previous partial load.
- * 0: Conclude the load and handle the data to the driver code.
+ * 0: Conclude the load and hand the data to the driver code.
* -1: Conclude the load with an error and discard any written data.
**/
static ssize_t
@@ -201,6 +206,7 @@ out:
up(&fw_lock);
return ret_count;
}
+
static int
fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
{
@@ -227,11 +233,13 @@ fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
}
/**
- * firmware_data_write:
+ * firmware_data_write - write method for firmware
+ * @kobj: kobject for the class_device
+ * @buffer: buffer being written
+ * @offset: buffer offset for write in total data store area
+ * @count: buffer size
*
- * Description:
- *
- * Data written to the 'data' attribute will be later handled to
+ * Data written to the 'data' attribute will be later handed to
* the driver as a firmware image.
**/
static ssize_t
@@ -264,6 +272,7 @@ out:
up(&fw_lock);
return retval;
}
+
static struct bin_attribute firmware_attr_data_tmpl = {
.attr = {.name = "data", .mode = 0644, .owner = THIS_MODULE},
.size = 0,
@@ -448,13 +457,16 @@ out:
/**
* request_firmware: - request firmware to hotplug and wait for it
- * Description:
- * @firmware will be used to return a firmware image by the name
+ * @firmware_p: pointer to firmware image
+ * @name: name of firmware file
+ * @device: device for which firmware is being loaded
+ *
+ * @firmware_p will be used to return a firmware image by the name
* of @name for device @device.
*
* Should be called from user context where sleeping is allowed.
*
- * @name will be use as $FIRMWARE in the hotplug environment and
+ * @name will be used as $FIRMWARE in the hotplug environment and
* should be distinctive enough not to be confused with any other
* firmware image for this or any other device.
**/
@@ -468,6 +480,7 @@ request_firmware(const struct firmware **firmware_p, const char *name,
/**
* release_firmware: - release the resource associated with a firmware image
+ * @fw: firmware resource to release
**/
void
release_firmware(const struct firmware *fw)
@@ -480,8 +493,10 @@ release_firmware(const struct firmware *fw)
/**
* register_firmware: - provide a firmware image for later usage
+ * @name: name of firmware image file
+ * @data: buffer pointer for the firmware image
+ * @size: size of the data buffer area
*
- * Description:
* Make sure that @data will be available by requesting firmware @name.
*
* Note: This will not be possible until some kind of persistence
@@ -526,21 +541,19 @@ request_firmware_work_func(void *arg)
}
/**
- * request_firmware_nowait:
+ * request_firmware_nowait: asynchronous version of request_firmware
+ * @module: module requesting the firmware
+ * @hotplug: invokes hotplug event to copy the firmware image if this flag
+ * is non-zero else the firmware copy must be done manually.
+ * @name: name of firmware file
+ * @device: device for which firmware is being loaded
+ * @context: will be passed over to @cont, and
+ * @fw may be %NULL if firmware request fails.
+ * @cont: function will be called asynchronously when the firmware
+ * request is over.
*
- * Description:
* Asynchronous variant of request_firmware() for contexts where
* it is not possible to sleep.
- *
- * @hotplug invokes hotplug event to copy the firmware image if this flag
- * is non-zero else the firmware copy must be done manually.
- *
- * @cont will be called asynchronously when the firmware request is over.
- *
- * @context will be passed over to @cont.
- *
- * @fw may be %NULL if firmware request fails.
- *
**/
int
request_firmware_nowait(
diff --git a/drivers/base/init.c b/drivers/base/init.c
index 84e604e25c4f..c648914b9cde 100644
--- a/drivers/base/init.c
+++ b/drivers/base/init.c
@@ -9,6 +9,7 @@
#include <linux/device.h>
#include <linux/init.h>
+#include <linux/memory.h>
#include "base.h"
@@ -33,5 +34,6 @@ void __init driver_init(void)
platform_bus_init();
system_bus_init();
cpu_dev_init();
+ memory_dev_init();
attribute_container_init();
}
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
new file mode 100644
index 000000000000..b7ddd651d664
--- /dev/null
+++ b/drivers/base/memory.c
@@ -0,0 +1,452 @@
+/*
+ * drivers/base/memory.c - basic Memory class support
+ *
+ * Written by Matt Tolentino <matthew.e.tolentino@intel.com>
+ * Dave Hansen <haveblue@us.ibm.com>
+ *
+ * This file provides the necessary infrastructure to represent
+ * a SPARSEMEM-memory-model system's physical memory in /sysfs.
+ * All arch-independent code that assumes MEMORY_HOTPLUG requires
+ * SPARSEMEM should be contained here, or in mm/memory_hotplug.c.
+ */
+
+#include <linux/sysdev.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h> /* capable() */
+#include <linux/topology.h>
+#include <linux/device.h>
+#include <linux/memory.h>
+#include <linux/kobject.h>
+#include <linux/memory_hotplug.h>
+#include <linux/mm.h>
+#include <asm/atomic.h>
+#include <asm/uaccess.h>
+
+#define MEMORY_CLASS_NAME "memory"
+
+static struct sysdev_class memory_sysdev_class = {
+ set_kset_name(MEMORY_CLASS_NAME),
+};
+EXPORT_SYMBOL(memory_sysdev_class);
+
+static char *memory_hotplug_name(struct kset *kset, struct kobject *kobj)
+{
+ return MEMORY_CLASS_NAME;
+}
+
+static int memory_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
+ int num_envp, char *buffer, int buffer_size)
+{
+ int retval = 0;
+
+ return retval;
+}
+
+static struct kset_hotplug_ops memory_hotplug_ops = {
+ .name = memory_hotplug_name,
+ .hotplug = memory_hotplug,
+};
+
+static struct notifier_block *memory_chain;
+
+static int register_memory_notifier(struct notifier_block *nb)
+{
+ return notifier_chain_register(&memory_chain, nb);
+}
+
+static void unregister_memory_notifier(struct notifier_block *nb)
+{
+ notifier_chain_unregister(&memory_chain, nb);
+}
+
+/*
+ * register_memory - Setup a sysfs device for a memory block
+ */
+static int
+register_memory(struct memory_block *memory, struct mem_section *section,
+ struct node *root)
+{
+ int error;
+
+ memory->sysdev.cls = &memory_sysdev_class;
+ memory->sysdev.id = __section_nr(section);
+
+ error = sysdev_register(&memory->sysdev);
+
+ if (root && !error)
+ error = sysfs_create_link(&root->sysdev.kobj,
+ &memory->sysdev.kobj,
+ kobject_name(&memory->sysdev.kobj));
+
+ return error;
+}
+
+static void
+unregister_memory(struct memory_block *memory, struct mem_section *section,
+ struct node *root)
+{
+ BUG_ON(memory->sysdev.cls != &memory_sysdev_class);
+ BUG_ON(memory->sysdev.id != __section_nr(section));
+
+ sysdev_unregister(&memory->sysdev);
+ if (root)
+ sysfs_remove_link(&root->sysdev.kobj,
+ kobject_name(&memory->sysdev.kobj));
+}
+
+/*
+ * use this as the physical section index that this memsection
+ * uses.
+ */
+
+static ssize_t show_mem_phys_index(struct sys_device *dev, char *buf)
+{
+ struct memory_block *mem =
+ container_of(dev, struct memory_block, sysdev);
+ return sprintf(buf, "%08lx\n", mem->phys_index);
+}
+
+/*
+ * online, offline, going offline, etc.
+ */
+static ssize_t show_mem_state(struct sys_device *dev, char *buf)
+{
+ struct memory_block *mem =
+ container_of(dev, struct memory_block, sysdev);
+ ssize_t len = 0;
+
+ /*
+ * We can probably put these states in a nice little array
+ * so that they're not open-coded
+ */
+ switch (mem->state) {
+ case MEM_ONLINE:
+ len = sprintf(buf, "online\n");
+ break;
+ case MEM_OFFLINE:
+ len = sprintf(buf, "offline\n");
+ break;
+ case MEM_GOING_OFFLINE:
+ len = sprintf(buf, "going-offline\n");
+ break;
+ default:
+ len = sprintf(buf, "ERROR-UNKNOWN-%ld\n",
+ mem->state);
+ WARN_ON(1);
+ break;
+ }
+
+ return len;
+}
+
+static inline int memory_notify(unsigned long val, void *v)
+{
+ return notifier_call_chain(&memory_chain, val, v);
+}
+
+/*
+ * MEMORY_HOTPLUG depends on SPARSEMEM in mm/Kconfig, so it is
+ * OK to have direct references to sparsemem variables in here.
+ */
+static int
+memory_block_action(struct memory_block *mem, unsigned long action)
+{
+ int i;
+ unsigned long psection;
+ unsigned long start_pfn, start_paddr;
+ struct page *first_page;
+ int ret;
+ int old_state = mem->state;
+
+ psection = mem->phys_index;
+ first_page = pfn_to_page(psection << PFN_SECTION_SHIFT);
+
+ /*
+ * The probe routines leave the pages reserved, just
+ * as the bootmem code does. Make sure they're still
+ * that way.
+ */
+ if (action == MEM_ONLINE) {
+ for (i = 0; i < PAGES_PER_SECTION; i++) {
+ if (PageReserved(first_page+i))
+ continue;
+
+ printk(KERN_WARNING "section number %ld page number %d "
+ "not reserved, was it already online? \n",
+ psection, i);
+ return -EBUSY;
+ }
+ }
+
+ switch (action) {
+ case MEM_ONLINE:
+ start_pfn = page_to_pfn(first_page);
+ ret = online_pages(start_pfn, PAGES_PER_SECTION);
+ break;
+ case MEM_OFFLINE:
+ mem->state = MEM_GOING_OFFLINE;
+ memory_notify(MEM_GOING_OFFLINE, NULL);
+ start_paddr = page_to_pfn(first_page) << PAGE_SHIFT;
+ ret = remove_memory(start_paddr,
+ PAGES_PER_SECTION << PAGE_SHIFT);
+ if (ret) {
+ mem->state = old_state;
+ break;
+ }
+ memory_notify(MEM_MAPPING_INVALID, NULL);
+ break;
+ default:
+ printk(KERN_WARNING "%s(%p, %ld) unknown action: %ld\n",
+ __FUNCTION__, mem, action, action);
+ WARN_ON(1);
+ ret = -EINVAL;
+ }
+ /*
+ * For now, only notify on successful memory operations
+ */
+ if (!ret)
+ memory_notify(action, NULL);
+
+ return ret;
+}
+
+static int memory_block_change_state(struct memory_block *mem,
+ unsigned long to_state, unsigned long from_state_req)
+{
+ int ret = 0;
+ down(&mem->state_sem);
+
+ if (mem->state != from_state_req) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = memory_block_action(mem, to_state);
+ if (!ret)
+ mem->state = to_state;
+
+out:
+ up(&mem->state_sem);
+ return ret;
+}
+
+static ssize_t
+store_mem_state(struct sys_device *dev, const char *buf, size_t count)
+{
+ struct memory_block *mem;
+ unsigned int phys_section_nr;
+ int ret = -EINVAL;
+
+ mem = container_of(dev, struct memory_block, sysdev);
+ phys_section_nr = mem->phys_index;
+
+ if (!valid_section_nr(phys_section_nr))
+ goto out;
+
+ if (!strncmp(buf, "online", min((int)count, 6)))
+ ret = memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE);
+ else if(!strncmp(buf, "offline", min((int)count, 7)))
+ ret = memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE);
+out:
+ if (ret)
+ return ret;
+ return count;
+}
+
+/*
+ * phys_device is a bad name for this. What I really want
+ * is a way to differentiate between memory ranges that
+ * are part of physical devices that constitute
+ * a complete removable unit or fru.
+ * i.e. do these ranges belong to the same physical device,
+ * s.t. if I offline all of these sections I can then
+ * remove the physical device?
+ */
+static ssize_t show_phys_device(struct sys_device *dev, char *buf)
+{
+ struct memory_block *mem =
+ container_of(dev, struct memory_block, sysdev);
+ return sprintf(buf, "%d\n", mem->phys_device);
+}
+
+static SYSDEV_ATTR(phys_index, 0444, show_mem_phys_index, NULL);
+static SYSDEV_ATTR(state, 0644, show_mem_state, store_mem_state);
+static SYSDEV_ATTR(phys_device, 0444, show_phys_device, NULL);
+
+#define mem_create_simple_file(mem, attr_name) \
+ sysdev_create_file(&mem->sysdev, &attr_##attr_name)
+#define mem_remove_simple_file(mem, attr_name) \
+ sysdev_remove_file(&mem->sysdev, &attr_##attr_name)
+
+/*
+ * Block size attribute stuff
+ */
+static ssize_t
+print_block_size(struct class *class, char *buf)
+{
+ return sprintf(buf, "%lx\n", (unsigned long)PAGES_PER_SECTION * PAGE_SIZE);
+}
+
+static CLASS_ATTR(block_size_bytes, 0444, print_block_size, NULL);
+
+static int block_size_init(void)
+{
+ sysfs_create_file(&memory_sysdev_class.kset.kobj,
+ &class_attr_block_size_bytes.attr);
+ return 0;
+}
+
+/*
+ * Some architectures will have custom drivers to do this, and
+ * will not need to do it from userspace. The fake hot-add code
+ * as well as ppc64 will do all of their discovery in userspace
+ * and will require this interface.
+ */
+#ifdef CONFIG_ARCH_MEMORY_PROBE
+static ssize_t
+memory_probe_store(struct class *class, const char __user *buf, size_t count)
+{
+ u64 phys_addr;
+ int ret;
+
+ phys_addr = simple_strtoull(buf, NULL, 0);
+
+ ret = add_memory(phys_addr, PAGES_PER_SECTION << PAGE_SHIFT);
+
+ if (ret)
+ count = ret;
+
+ return count;
+}
+static CLASS_ATTR(probe, 0700, NULL, memory_probe_store);
+
+static int memory_probe_init(void)
+{
+ sysfs_create_file(&memory_sysdev_class.kset.kobj,
+ &class_attr_probe.attr);
+ return 0;
+}
+#else
+#define memory_probe_init(...) do {} while (0)
+#endif
+
+/*
+ * Note that phys_device is optional. It is here to allow for
+ * differentiation between which *physical* devices each
+ * section belongs to...
+ */
+
+static int add_memory_block(unsigned long node_id, struct mem_section *section,
+ unsigned long state, int phys_device)
+{
+ struct memory_block *mem = kzalloc(sizeof(*mem), GFP_KERNEL);
+ int ret = 0;
+
+ if (!mem)
+ return -ENOMEM;
+
+ mem->phys_index = __section_nr(section);
+ mem->state = state;
+ init_MUTEX(&mem->state_sem);
+ mem->phys_device = phys_device;
+
+ ret = register_memory(mem, section, NULL);
+ if (!ret)
+ ret = mem_create_simple_file(mem, phys_index);
+ if (!ret)
+ ret = mem_create_simple_file(mem, state);
+ if (!ret)
+ ret = mem_create_simple_file(mem, phys_device);
+
+ return ret;
+}
+
+/*
+ * For now, we have a linear search to go find the appropriate
+ * memory_block corresponding to a particular phys_index. If
+ * this gets to be a real problem, we can always use a radix
+ * tree or something here.
+ *
+ * This could be made generic for all sysdev classes.
+ */
+static struct memory_block *find_memory_block(struct mem_section *section)
+{
+ struct kobject *kobj;
+ struct sys_device *sysdev;
+ struct memory_block *mem;
+ char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1];
+
+ /*
+ * This only works because we know that section == sysdev->id
+ * slightly redundant with sysdev_register()
+ */
+ sprintf(&name[0], "%s%d", MEMORY_CLASS_NAME, __section_nr(section));
+
+ kobj = kset_find_obj(&memory_sysdev_class.kset, name);
+ if (!kobj)
+ return NULL;
+
+ sysdev = container_of(kobj, struct sys_device, kobj);
+ mem = container_of(sysdev, struct memory_block, sysdev);
+
+ return mem;
+}
+
+int remove_memory_block(unsigned long node_id, struct mem_section *section,
+ int phys_device)
+{
+ struct memory_block *mem;
+
+ mem = find_memory_block(section);
+ mem_remove_simple_file(mem, phys_index);
+ mem_remove_simple_file(mem, state);
+ mem_remove_simple_file(mem, phys_device);
+ unregister_memory(mem, section, NULL);
+
+ return 0;
+}
+
+/*
+ * need an interface for the VM to add new memory regions,
+ * but without onlining it.
+ */
+int register_new_memory(struct mem_section *section)
+{
+ return add_memory_block(0, section, MEM_OFFLINE, 0);
+}
+
+int unregister_memory_section(struct mem_section *section)
+{
+ if (!valid_section(section))
+ return -EINVAL;
+
+ return remove_memory_block(0, section, 0);
+}
+
+/*
+ * Initialize the sysfs support for memory devices...
+ */
+int __init memory_dev_init(void)
+{
+ unsigned int i;
+ int ret;
+
+ memory_sysdev_class.kset.hotplug_ops = &memory_hotplug_ops;
+ ret = sysdev_class_register(&memory_sysdev_class);
+
+ /*
+ * Create entries for memory sections that were found
+ * during boot and have been initialized
+ */
+ for (i = 0; i < NR_MEM_SECTIONS; i++) {
+ if (!valid_section_nr(i))
+ continue;
+ add_memory_block(0, __nr_to_section(i), MEM_ONLINE, 0);
+ }
+
+ memory_probe_init();
+ block_size_init();
+
+ return ret;
+}
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 95f2af322c8f..d597c922af11 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -16,6 +16,7 @@
#include <linux/dma-mapping.h>
#include <linux/bootmem.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include "base.h"
diff --git a/drivers/base/sys.c b/drivers/base/sys.c
index 3431eb6004c3..66ed8f2fece5 100644
--- a/drivers/base/sys.c
+++ b/drivers/base/sys.c
@@ -21,6 +21,7 @@
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/pm.h>
+#include <asm/semaphore.h>
extern struct subsystem devices_subsys;
diff --git a/drivers/block/Kconfig.iosched b/drivers/block/Kconfig.iosched
index 6070a480600b..5b90d2fa63b8 100644
--- a/drivers/block/Kconfig.iosched
+++ b/drivers/block/Kconfig.iosched
@@ -38,4 +38,32 @@ config IOSCHED_CFQ
among all processes in the system. It should provide a fair
working environment, suitable for desktop systems.
+choice
+ prompt "Default I/O scheduler"
+ default DEFAULT_AS
+ help
+ Select the I/O scheduler which will be used by default for all
+ block devices.
+
+ config DEFAULT_AS
+ bool "Anticipatory" if IOSCHED_AS
+
+ config DEFAULT_DEADLINE
+ bool "Deadline" if IOSCHED_DEADLINE
+
+ config DEFAULT_CFQ
+ bool "CFQ" if IOSCHED_CFQ
+
+ config DEFAULT_NOOP
+ bool "No-op"
+
+endchoice
+
+config DEFAULT_IOSCHED
+ string
+ default "anticipatory" if DEFAULT_AS
+ default "deadline" if DEFAULT_DEADLINE
+ default "cfq" if DEFAULT_CFQ
+ default "noop" if DEFAULT_NOOP
+
endmenu
diff --git a/drivers/block/as-iosched.c b/drivers/block/as-iosched.c
index 4081c36c8c19..c6744ff38294 100644
--- a/drivers/block/as-iosched.c
+++ b/drivers/block/as-iosched.c
@@ -1344,6 +1344,7 @@ as_add_aliased_request(struct as_data *ad, struct as_rq *arq, struct as_rq *alia
* Don't want to have to handle merges.
*/
as_del_arq_hash(arq);
+ arq->request->flags |= REQ_NOMERGE;
}
/*
@@ -1972,8 +1973,8 @@ static int __init as_init(void)
static void __exit as_exit(void)
{
- kmem_cache_destroy(arq_pool);
elv_unregister(&iosched_as);
+ kmem_cache_destroy(arq_pool);
}
module_init(as_init);
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
index e183a3ef7839..ec27976a57da 100644
--- a/drivers/block/cciss_scsi.c
+++ b/drivers/block/cciss_scsi.c
@@ -28,13 +28,17 @@
through the array controller. Note in particular, neither
physical nor logical disks are presented through the scsi layer. */
+#include <linux/timer.h>
+#include <linux/completion.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#include <asm/atomic.h>
+
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
-#include <asm/atomic.h>
-#include <linux/timer.h>
-#include <linux/completion.h>
#include "cciss_scsi.h"
diff --git a/drivers/block/cfq-iosched.c b/drivers/block/cfq-iosched.c
index 94690e4d41e0..5281f8e70510 100644
--- a/drivers/block/cfq-iosched.c
+++ b/drivers/block/cfq-iosched.c
@@ -2418,28 +2418,8 @@ static int __init cfq_init(void)
static void __exit cfq_exit(void)
{
- struct task_struct *g, *p;
- unsigned long flags;
-
- read_lock_irqsave(&tasklist_lock, flags);
-
- /*
- * iterate each process in the system, removing our io_context
- */
- do_each_thread(g, p) {
- struct io_context *ioc = p->io_context;
-
- if (ioc && ioc->cic) {
- ioc->cic->exit(ioc->cic);
- cfq_free_io_context(ioc->cic);
- ioc->cic = NULL;
- }
- } while_each_thread(g, p);
-
- read_unlock_irqrestore(&tasklist_lock, flags);
-
- cfq_slab_kill();
elv_unregister(&iosched_cfq);
+ cfq_slab_kill();
}
module_init(cfq_init);
diff --git a/drivers/block/elevator.c b/drivers/block/elevator.c
index 55621d5c5774..36f1057084b0 100644
--- a/drivers/block/elevator.c
+++ b/drivers/block/elevator.c
@@ -147,24 +147,17 @@ static void elevator_setup_default(void)
struct elevator_type *e;
/*
- * check if default is set and exists
+ * If default has not been set, use the compiled-in selection.
*/
- if (chosen_elevator[0] && (e = elevator_get(chosen_elevator))) {
- elevator_put(e);
- return;
- }
+ if (!chosen_elevator[0])
+ strcpy(chosen_elevator, CONFIG_DEFAULT_IOSCHED);
-#if defined(CONFIG_IOSCHED_AS)
- strcpy(chosen_elevator, "anticipatory");
-#elif defined(CONFIG_IOSCHED_DEADLINE)
- strcpy(chosen_elevator, "deadline");
-#elif defined(CONFIG_IOSCHED_CFQ)
- strcpy(chosen_elevator, "cfq");
-#elif defined(CONFIG_IOSCHED_NOOP)
- strcpy(chosen_elevator, "noop");
-#else
-#error "You must build at least 1 IO scheduler into the kernel"
-#endif
+ /*
+ * If the given scheduler is not available, fall back to no-op.
+ */
+ if (!(e = elevator_find(chosen_elevator)))
+ strcpy(chosen_elevator, "noop");
+ elevator_put(e);
}
static int __init elevator_setup(char *str)
@@ -642,6 +635,27 @@ EXPORT_SYMBOL_GPL(elv_register);
void elv_unregister(struct elevator_type *e)
{
+ struct task_struct *g, *p;
+
+ /*
+ * Iterate every thread in the process to remove the io contexts.
+ */
+ read_lock(&tasklist_lock);
+ do_each_thread(g, p) {
+ struct io_context *ioc = p->io_context;
+ if (ioc && ioc->cic) {
+ ioc->cic->exit(ioc->cic);
+ ioc->cic->dtor(ioc->cic);
+ ioc->cic = NULL;
+ }
+ if (ioc && ioc->aic) {
+ ioc->aic->exit(ioc->aic);
+ ioc->aic->dtor(ioc->aic);
+ ioc->aic = NULL;
+ }
+ } while_each_thread(g, p);
+ read_unlock(&tasklist_lock);
+
spin_lock_irq(&elv_list_lock);
list_del_init(&e->list);
spin_unlock_irq(&elv_list_lock);
@@ -739,8 +753,10 @@ ssize_t elv_iosched_store(request_queue_t *q, const char *name, size_t count)
return -EINVAL;
}
- if (!strcmp(elevator_name, q->elevator->elevator_type->elevator_name))
+ if (!strcmp(elevator_name, q->elevator->elevator_type->elevator_name)) {
+ elevator_put(e);
return count;
+ }
elevator_switch(q, e);
return count;
diff --git a/drivers/block/paride/paride.c b/drivers/block/paride/paride.c
index 1fef136c0e41..ce94aa11f6a7 100644
--- a/drivers/block/paride/paride.c
+++ b/drivers/block/paride/paride.c
@@ -29,6 +29,7 @@
#include <linux/string.h>
#include <linux/spinlock.h>
#include <linux/wait.h>
+#include <linux/sched.h> /* TASK_* */
#ifdef CONFIG_PARPORT_MODULE
#define CONFIG_PARPORT
diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c
index 94af920465b5..e9746af29b9f 100644
--- a/drivers/block/paride/pf.c
+++ b/drivers/block/paride/pf.c
@@ -807,10 +807,6 @@ static int pf_next_buf(void)
return 1;
spin_lock_irqsave(&pf_spin_lock, saved_flags);
pf_end_request(1);
- if (pf_req) {
- pf_count = pf_req->current_nr_sectors;
- pf_buf = pf_req->buffer;
- }
spin_unlock_irqrestore(&pf_spin_lock, saved_flags);
return 1;
}
diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c
index 82f2d6d2eeef..6f5df0fad703 100644
--- a/drivers/block/paride/pg.c
+++ b/drivers/block/paride/pg.c
@@ -162,6 +162,8 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_DLY};
#include <linux/mtio.h>
#include <linux/pg.h>
#include <linux/device.h>
+#include <linux/sched.h> /* current, TASK_* */
+#include <linux/jiffies.h>
#include <asm/uaccess.h>
diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c
index 686c95573452..715ae5dc88fb 100644
--- a/drivers/block/paride/pt.c
+++ b/drivers/block/paride/pt.c
@@ -146,6 +146,7 @@ static int (*drives[4])[6] = {&drive0, &drive1, &drive2, &drive3};
#include <linux/slab.h>
#include <linux/mtio.h>
#include <linux/device.h>
+#include <linux/sched.h> /* current, TASK_*, schedule_timeout() */
#include <asm/uaccess.h>
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index e46ecd23b3ac..709f809f79f1 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -778,13 +778,16 @@ static struct vio_device_id viodasd_device_table[] __devinitdata = {
{ "viodasd", "" },
{ "", "" }
};
-
MODULE_DEVICE_TABLE(vio, viodasd_device_table);
+
static struct vio_driver viodasd_driver = {
- .name = "viodasd",
.id_table = viodasd_device_table,
.probe = viodasd_probe,
- .remove = viodasd_remove
+ .remove = viodasd_remove,
+ .driver = {
+ .name = "viodasd",
+ .owner = THIS_MODULE,
+ }
};
/*
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index 0829db58462f..36f31d202223 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -736,13 +736,16 @@ static struct vio_device_id viocd_device_table[] __devinitdata = {
{ "viocd", "" },
{ "", "" }
};
-
MODULE_DEVICE_TABLE(vio, viocd_device_table);
+
static struct vio_driver viocd_driver = {
- .name = "viocd",
.id_table = viocd_device_table,
.probe = viocd_probe,
- .remove = viocd_remove
+ .remove = viocd_remove,
+ .driver = {
+ .name = "viocd",
+ .owner = THIS_MODULE,
+ }
};
static int __init viocd_init(void)
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index c29365d5b524..fdf4370db994 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -661,7 +661,7 @@ config HW_RANDOM
config NVRAM
tristate "/dev/nvram support"
- depends on ATARI || X86 || X86_64 || ARM || GENERIC_NVRAM
+ depends on ATARI || X86 || ARM || GENERIC_NVRAM
---help---
If you say Y here and create a character special file /dev/nvram
with major number 10 and minor number 144 using mknod ("man mknod"),
@@ -985,7 +985,7 @@ config MAX_RAW_DEVS
config HANGCHECK_TIMER
tristate "Hangcheck timer"
- depends on X86_64 || X86 || IA64 || PPC64 || ARCH_S390
+ depends on X86 || IA64 || PPC64 || ARCH_S390
help
The hangcheck-timer module detects when the system has gone
out to lunch past a certain margin. It can reboot the system
@@ -1001,5 +1001,17 @@ config MMTIMER
source "drivers/char/tpm/Kconfig"
+config TELCLOCK
+ tristate "Telecom clock driver for MPBL0010 ATCA SBC"
+ depends on EXPERIMENTAL
+ default n
+ help
+ The telecom clock device is specific to the MPBL0010 ATCA computer and
+ allows direct userspace access to the configuration of the telecom clock
+ configuration settings. This device is used for hardware synchronization
+ across the ATCA backplane fabric. Upon loading, the driver exports a
+ sysfs directory, /sys/devices/platform/telco_clock, with a number of
+ files for controlling the behavior of this hardware.
+
endmenu
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 08f69287ea36..4aeae687e88a 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_NWFLASH) += nwflash.o
obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o
obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o
obj-$(CONFIG_TANBAC_TB0219) += tb0219.o
+obj-$(CONFIG_TELCLOCK) += tlclk.o
obj-$(CONFIG_WATCHDOG) += watchdog/
obj-$(CONFIG_MWAVE) += mwave/
diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig
index 7f8c1b53b754..486ed8a11b59 100644
--- a/drivers/char/agp/Kconfig
+++ b/drivers/char/agp/Kconfig
@@ -27,7 +27,7 @@ config AGP
config AGP_ALI
tristate "ALI chipset support"
- depends on AGP && X86 && !X86_64
+ depends on AGP && X86_32
---help---
This option gives you AGP support for the GLX component of
XFree86 4.x on the following ALi chipsets. The supported chipsets
@@ -45,7 +45,7 @@ config AGP_ALI
config AGP_ATI
tristate "ATI chipset support"
- depends on AGP && X86 && !X86_64
+ depends on AGP && X86_32
---help---
This option gives you AGP support for the GLX component of
XFree86 4.x on the ATI RadeonIGP family of chipsets.
@@ -55,7 +55,7 @@ config AGP_ATI
config AGP_AMD
tristate "AMD Irongate, 761, and 762 chipset support"
- depends on AGP && X86 && !X86_64
+ depends on AGP && X86_32
help
This option gives you AGP support for the GLX component of
XFree86 4.x on AMD Irongate, 761, and 762 chipsets.
@@ -91,7 +91,7 @@ config AGP_INTEL
config AGP_NVIDIA
tristate "NVIDIA nForce/nForce2 chipset support"
- depends on AGP && X86 && !X86_64
+ depends on AGP && X86_32
help
This option gives you AGP support for the GLX component of
XFree86 4.x on the following NVIDIA chipsets. The supported chipsets
@@ -99,7 +99,7 @@ config AGP_NVIDIA
config AGP_SIS
tristate "SiS chipset support"
- depends on AGP && X86 && !X86_64
+ depends on AGP && X86_32
help
This option gives you AGP support for the GLX component of
XFree86 4.x on Silicon Integrated Systems [SiS] chipsets.
@@ -111,14 +111,14 @@ config AGP_SIS
config AGP_SWORKS
tristate "Serverworks LE/HE chipset support"
- depends on AGP && X86 && !X86_64
+ depends on AGP && X86_32
help
Say Y here to support the Serverworks AGP card. See
<http://www.serverworks.com/> for product descriptions and images.
config AGP_VIA
tristate "VIA chipset support"
- depends on AGP && X86 && !X86_64
+ depends on AGP && X86_32
help
This option gives you AGP support for the GLX component of
XFree86 4.x on VIA MVP3/Apollo Pro chipsets.
@@ -154,7 +154,7 @@ config AGP_UNINORTH
config AGP_EFFICEON
tristate "Transmeta Efficeon support"
- depends on AGP && X86 && !X86_64
+ depends on AGP && X86_32
help
This option gives you AGP support for the Transmeta Efficeon
series processors with integrated northbridges.
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c
index 9c9c9c2247ce..b02fc2267159 100644
--- a/drivers/char/agp/ali-agp.c
+++ b/drivers/char/agp/ali-agp.c
@@ -7,6 +7,7 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/agp_backend.h>
+#include <asm/page.h> /* PAGE_SIZE */
#include "agp.h"
#define ALI_AGPCTRL 0xb8
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 0a7624a9b1c1..0e6c3a31d344 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -13,6 +13,7 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/agp_backend.h>
+#include <asm/page.h> /* PAGE_SIZE */
#include "agp.h"
/* Will need to be increased if AMD64 ever goes >8-way. */
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
index e572ced9100a..0b6e72642d6e 100644
--- a/drivers/char/agp/ati-agp.c
+++ b/drivers/char/agp/ati-agp.c
@@ -6,6 +6,8 @@
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <linux/agp_backend.h>
#include <asm/agp.h>
#include "agp.h"
diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c
index 94943298c03e..a2d9e5e48bbe 100644
--- a/drivers/char/agp/i460-agp.c
+++ b/drivers/char/agp/i460-agp.c
@@ -10,6 +10,8 @@
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <linux/agp_backend.h>
#include "agp.h"
diff --git a/drivers/char/agp/isoch.c b/drivers/char/agp/isoch.c
index c9ac731504f2..40083241804e 100644
--- a/drivers/char/agp/isoch.c
+++ b/drivers/char/agp/isoch.c
@@ -6,6 +6,7 @@
#include <linux/pci.h>
#include <linux/agp_backend.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include "agp.h"
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
index a9fb12c20eb7..71ea59a1dbeb 100644
--- a/drivers/char/agp/sworks-agp.c
+++ b/drivers/char/agp/sworks-agp.c
@@ -5,6 +5,8 @@
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <linux/agp_backend.h>
#include "agp.h"
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index cf4c3648463d..c7f818cd7b02 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -281,7 +281,7 @@ static char rcsid[] =
* make sure "cyc" appears in all kernel messages; all soft interrupts
* handled by same routine; recognize out-of-band reception; comment
* out some diagnostic messages; leave RTS/CTS flow control to hardware;
- * fix race condition in -Z buffer management; only -Y needs to explictly
+ * fix race condition in -Z buffer management; only -Y needs to explicitly
* flush chars; tidy up some startup messages;
*
* Revision 1.36.4.18 1996/07/25 18:57:31 bentson
diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c
index 475cc5e555e1..6d3449761914 100644
--- a/drivers/char/drm/drm_sysfs.c
+++ b/drivers/char/drm/drm_sysfs.c
@@ -15,6 +15,8 @@
#include <linux/device.h>
#include <linux/kdev_t.h>
#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/string.h>
#include "drm_core.h"
#include "drmP.h"
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index 407708a001e4..b7a0e4d6b934 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -3113,6 +3113,7 @@ MODULE_DEVICE_TABLE(pci, epca_pci_tbl);
int __init init_PCI (void)
{ /* Begin init_PCI */
memset (&epca_driver, 0, sizeof (epca_driver));
+ epca_driver.owner = THIS_MODULE;
epca_driver.name = "epca";
epca_driver.id_table = epca_pci_tbl;
epca_driver.probe = epca_init_one;
diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c
index a54bc93353af..66e53dd450ff 100644
--- a/drivers/char/hangcheck-timer.c
+++ b/drivers/char/hangcheck-timer.c
@@ -117,7 +117,7 @@ __setup("hcheck_reboot", hangcheck_parse_reboot);
__setup("hcheck_dump_tasks", hangcheck_parse_dump_tasks);
#endif /* not MODULE */
-#if defined(CONFIG_X86) || defined(CONFIG_X86_64)
+#if defined(CONFIG_X86)
# define HAVE_MONOTONIC
# define TIMER_FREQ 1000000000ULL
#elif defined(CONFIG_ARCH_S390)
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index c055bb630ffc..3808d9572619 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -49,7 +49,9 @@
#define HPET_USER_FREQ (64)
#define HPET_DRIFT (500)
-static u32 hpet_ntimer, hpet_nhpet, hpet_max_freq = HPET_USER_FREQ;
+#define HPET_RANGE_SIZE 1024 /* from HPET spec */
+
+static u32 hpet_nhpet, hpet_max_freq = HPET_USER_FREQ;
/* A lock for concurrent access by app and isr hpet activity. */
static DEFINE_SPINLOCK(hpet_lock);
@@ -78,7 +80,7 @@ struct hpets {
struct hpet __iomem *hp_hpet;
unsigned long hp_hpet_phys;
struct time_interpolator *hp_interpolator;
- unsigned long hp_period;
+ unsigned long long hp_tick_freq;
unsigned long hp_delta;
unsigned int hp_ntimer;
unsigned int hp_which;
@@ -90,6 +92,7 @@ static struct hpets *hpets;
#define HPET_OPEN 0x0001
#define HPET_IE 0x0002 /* interrupt enabled */
#define HPET_PERIODIC 0x0004
+#define HPET_SHARED_IRQ 0x0008
#if BITS_PER_LONG == 64
#define write_counter(V, MC) writeq(V, MC)
@@ -120,6 +123,11 @@ static irqreturn_t hpet_interrupt(int irq, void *data, struct pt_regs *regs)
unsigned long isr;
devp = data;
+ isr = 1 << (devp - devp->hd_hpets->hp_dev);
+
+ if ((devp->hd_flags & HPET_SHARED_IRQ) &&
+ !(isr & readl(&devp->hd_hpet->hpet_isr)))
+ return IRQ_NONE;
spin_lock(&hpet_lock);
devp->hd_irqdata++;
@@ -137,8 +145,8 @@ static irqreturn_t hpet_interrupt(int irq, void *data, struct pt_regs *regs)
&devp->hd_timer->hpet_compare);
}
- isr = (1 << (devp - devp->hd_hpets->hp_dev));
- writeq(isr, &devp->hd_hpet->hpet_isr);
+ if (devp->hd_flags & HPET_SHARED_IRQ)
+ writel(isr, &devp->hd_hpet->hpet_isr);
spin_unlock(&hpet_lock);
spin_lock(&hpet_task_lock);
@@ -276,7 +284,8 @@ static int hpet_mmap(struct file *file, struct vm_area_struct *vma)
if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT,
PAGE_SIZE, vma->vm_page_prot)) {
- printk(KERN_ERR "remap_pfn_range failed in hpet.c\n");
+ printk(KERN_ERR "%s: io_remap_pfn_range failed\n",
+ __FUNCTION__);
return -EAGAIN;
}
@@ -364,7 +373,9 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp)
hpet = devp->hd_hpet;
hpetp = devp->hd_hpets;
- v = readq(&timer->hpet_config);
+ if (!devp->hd_ireqfreq)
+ return -EIO;
+
spin_lock_irq(&hpet_lock);
if (devp->hd_flags & HPET_IE) {
@@ -373,16 +384,21 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp)
}
devp->hd_flags |= HPET_IE;
+
+ if (readl(&timer->hpet_config) & Tn_INT_TYPE_CNF_MASK)
+ devp->hd_flags |= HPET_SHARED_IRQ;
spin_unlock_irq(&hpet_lock);
- t = readq(&timer->hpet_config);
irq = devp->hd_hdwirq;
if (irq) {
- sprintf(devp->hd_name, "hpet%d", (int)(devp - hpetp->hp_dev));
+ unsigned long irq_flags;
- if (request_irq
- (irq, hpet_interrupt, SA_INTERRUPT, devp->hd_name, (void *)devp)) {
+ sprintf(devp->hd_name, "hpet%d", (int)(devp - hpetp->hp_dev));
+ irq_flags = devp->hd_flags & HPET_SHARED_IRQ
+ ? SA_SHIRQ : SA_INTERRUPT;
+ if (request_irq(irq, hpet_interrupt, irq_flags,
+ devp->hd_name, (void *)devp)) {
printk(KERN_ERR "hpet: IRQ %d is not free\n", irq);
irq = 0;
}
@@ -416,20 +432,24 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp)
write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare);
}
- isr = (1 << (devp - hpets->hp_dev));
- writeq(isr, &hpet->hpet_isr);
+ if (devp->hd_flags & HPET_SHARED_IRQ) {
+ isr = 1 << (devp - devp->hd_hpets->hp_dev);
+ writel(isr, &hpet->hpet_isr);
+ }
writeq(g, &timer->hpet_config);
local_irq_restore(flags);
return 0;
}
-static inline unsigned long hpet_time_div(unsigned long dis)
+/* converts Hz to number of timer ticks */
+static inline unsigned long hpet_time_div(struct hpets *hpets,
+ unsigned long dis)
{
- unsigned long long m = 1000000000000000ULL;
+ unsigned long long m;
+ m = hpets->hp_tick_freq + (dis >> 1);
do_div(m, dis);
-
return (unsigned long)m;
}
@@ -477,14 +497,21 @@ hpet_ioctl_common(struct hpet_dev *devp, int cmd, unsigned long arg, int kernel)
{
struct hpet_info info;
- info.hi_ireqfreq = hpet_time_div(hpetp->hp_period *
- devp->hd_ireqfreq);
+ if (devp->hd_ireqfreq)
+ info.hi_ireqfreq =
+ hpet_time_div(hpetp, devp->hd_ireqfreq);
+ else
+ info.hi_ireqfreq = 0;
info.hi_flags =
readq(&timer->hpet_config) & Tn_PER_INT_CAP_MASK;
- info.hi_hpet = devp->hd_hpets->hp_which;
- info.hi_timer = devp - devp->hd_hpets->hp_dev;
- if (copy_to_user((void __user *)arg, &info, sizeof(info)))
- err = -EFAULT;
+ info.hi_hpet = hpetp->hp_which;
+ info.hi_timer = devp - hpetp->hp_dev;
+ if (kernel)
+ memcpy((void *)arg, &info, sizeof(info));
+ else
+ if (copy_to_user((void __user *)arg, &info,
+ sizeof(info)))
+ err = -EFAULT;
break;
}
case HPET_EPI:
@@ -516,12 +543,12 @@ hpet_ioctl_common(struct hpet_dev *devp, int cmd, unsigned long arg, int kernel)
break;
}
- if (arg & (arg - 1)) {
+ if (!arg) {
err = -EINVAL;
break;
}
- devp->hd_ireqfreq = hpet_time_div(hpetp->hp_period * arg);
+ devp->hd_ireqfreq = hpet_time_div(hpetp, arg);
}
return err;
@@ -539,6 +566,17 @@ static struct file_operations hpet_fops = {
.mmap = hpet_mmap,
};
+static int hpet_is_known(struct hpet_data *hdp)
+{
+ struct hpets *hpetp;
+
+ for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next)
+ if (hpetp->hp_hpet_phys == hdp->hd_phys_address)
+ return 1;
+
+ return 0;
+}
+
EXPORT_SYMBOL(hpet_alloc);
EXPORT_SYMBOL(hpet_register);
EXPORT_SYMBOL(hpet_unregister);
@@ -563,6 +601,8 @@ int hpet_register(struct hpet_task *tp, int periodic)
return -EINVAL;
}
+ tp->ht_opaque = NULL;
+
spin_lock_irq(&hpet_task_lock);
spin_lock(&hpet_lock);
@@ -702,15 +742,14 @@ static void hpet_register_interpolator(struct hpets *hpetp)
#ifdef CONFIG_TIME_INTERPOLATION
struct time_interpolator *ti;
- ti = kmalloc(sizeof(*ti), GFP_KERNEL);
+ ti = kzalloc(sizeof(*ti), GFP_KERNEL);
if (!ti)
return;
- memset(ti, 0, sizeof(*ti));
ti->source = TIME_SOURCE_MMIO64;
ti->shift = 10;
ti->addr = &hpetp->hp_hpet->hpet_mc;
- ti->frequency = hpet_time_div(hpets->hp_period);
+ ti->frequency = hpetp->hp_tick_freq;
ti->drift = HPET_DRIFT;
ti->mask = -1;
@@ -743,11 +782,11 @@ static unsigned long hpet_calibrate(struct hpets *hpetp)
if (!timer)
return 0;
- hpet = hpets->hp_hpet;
+ hpet = hpetp->hp_hpet;
t = read_counter(&timer->hpet_compare);
i = 0;
- count = hpet_time_div(hpetp->hp_period * TICK_CALIBRATE);
+ count = hpet_time_div(hpetp, TICK_CALIBRATE);
local_irq_save(flags);
@@ -771,28 +810,29 @@ int hpet_alloc(struct hpet_data *hdp)
struct hpets *hpetp;
size_t siz;
struct hpet __iomem *hpet;
- static struct hpets *last = (struct hpets *)0;
- unsigned long ns;
+ static struct hpets *last = NULL;
+ unsigned long period;
+ unsigned long long temp;
/*
* hpet_alloc can be called by platform dependent code.
- * if platform dependent code has allocated the hpet
- * ACPI also reports hpet, then we catch it here.
+ * If platform dependent code has allocated the hpet that
+ * ACPI has also reported, then we catch it here.
*/
- for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next)
- if (hpetp->hp_hpet == hdp->hd_address)
- return 0;
+ if (hpet_is_known(hdp)) {
+ printk(KERN_DEBUG "%s: duplicate HPET ignored\n",
+ __FUNCTION__);
+ return 0;
+ }
siz = sizeof(struct hpets) + ((hdp->hd_nirqs - 1) *
sizeof(struct hpet_dev));
- hpetp = kmalloc(siz, GFP_KERNEL);
+ hpetp = kzalloc(siz, GFP_KERNEL);
if (!hpetp)
return -ENOMEM;
- memset(hpetp, 0, siz);
-
hpetp->hp_which = hpet_nhpet++;
hpetp->hp_hpet = hdp->hd_address;
hpetp->hp_hpet_phys = hdp->hd_phys_address;
@@ -822,21 +862,23 @@ int hpet_alloc(struct hpet_data *hdp)
last = hpetp;
- hpetp->hp_period = (cap & HPET_COUNTER_CLK_PERIOD_MASK) >>
- HPET_COUNTER_CLK_PERIOD_SHIFT;
+ period = (cap & HPET_COUNTER_CLK_PERIOD_MASK) >>
+ HPET_COUNTER_CLK_PERIOD_SHIFT; /* fs, 10^-15 */
+ temp = 1000000000000000uLL; /* 10^15 femtoseconds per second */
+ temp += period >> 1; /* round */
+ do_div(temp, period);
+ hpetp->hp_tick_freq = temp; /* ticks per second */
- printk(KERN_INFO "hpet%d: at MMIO 0x%lx, IRQ%s",
- hpetp->hp_which, hdp->hd_phys_address,
+ printk(KERN_INFO "hpet%d: at MMIO 0x%lx (virtual 0x%p), IRQ%s",
+ hpetp->hp_which, hdp->hd_phys_address, hdp->hd_address,
hpetp->hp_ntimer > 1 ? "s" : "");
for (i = 0; i < hpetp->hp_ntimer; i++)
printk("%s %d", i > 0 ? "," : "", hdp->hd_irq[i]);
printk("\n");
- ns = hpetp->hp_period; /* femptoseconds, 10^-15 */
- ns /= 1000000; /* convert to nanoseconds, 10^-9 */
- printk(KERN_INFO "hpet%d: %ldns tick, %d %d-bit timers\n",
- hpetp->hp_which, ns, hpetp->hp_ntimer,
- cap & HPET_COUNTER_SIZE_MASK ? 64 : 32);
+ printk(KERN_INFO "hpet%u: %u %d-bit timers, %Lu Hz\n",
+ hpetp->hp_which, hpetp->hp_ntimer,
+ cap & HPET_COUNTER_SIZE_MASK ? 64 : 32, hpetp->hp_tick_freq);
mcfg = readq(&hpet->hpet_config);
if ((mcfg & HPET_ENABLE_CNF_MASK) == 0) {
@@ -845,13 +887,10 @@ int hpet_alloc(struct hpet_data *hdp)
writeq(mcfg, &hpet->hpet_config);
}
- for (i = 0, devp = hpetp->hp_dev; i < hpetp->hp_ntimer;
- i++, hpet_ntimer++, devp++) {
- unsigned long v;
+ for (i = 0, devp = hpetp->hp_dev; i < hpetp->hp_ntimer; i++, devp++) {
struct hpet_timer __iomem *timer;
timer = &hpet->hpet_timers[devp - hpetp->hp_dev];
- v = readq(&timer->hpet_config);
devp->hd_hpets = hpetp;
devp->hd_hpet = hpet;
@@ -880,7 +919,6 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data)
struct hpet_data *hdp;
acpi_status status;
struct acpi_resource_address64 addr;
- struct hpets *hpetp;
hdp = data;
@@ -893,9 +931,29 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data)
hdp->hd_phys_address = addr.min_address_range;
hdp->hd_address = ioremap(addr.min_address_range, size);
- for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next)
- if (hpetp->hp_hpet == hdp->hd_address)
- return -EBUSY;
+ if (hpet_is_known(hdp)) {
+ printk(KERN_DEBUG "%s: 0x%lx is busy\n",
+ __FUNCTION__, hdp->hd_phys_address);
+ iounmap(hdp->hd_address);
+ return -EBUSY;
+ }
+ } else if (res->id == ACPI_RSTYPE_FIXED_MEM32) {
+ struct acpi_resource_fixed_mem32 *fixmem32;
+
+ fixmem32 = &res->data.fixed_memory32;
+ if (!fixmem32)
+ return -EINVAL;
+
+ hdp->hd_phys_address = fixmem32->range_base_address;
+ hdp->hd_address = ioremap(fixmem32->range_base_address,
+ HPET_RANGE_SIZE);
+
+ if (hpet_is_known(hdp)) {
+ printk(KERN_DEBUG "%s: 0x%lx is busy\n",
+ __FUNCTION__, hdp->hd_phys_address);
+ iounmap(hdp->hd_address);
+ return -EBUSY;
+ }
} else if (res->id == ACPI_RSTYPE_EXT_IRQ) {
struct acpi_resource_ext_irq *irqp;
int i;
diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c
index 78d681dc35a8..f5212eb2b41d 100644
--- a/drivers/char/hvc_vio.c
+++ b/drivers/char/hvc_vio.c
@@ -95,11 +95,11 @@ static int __devexit hvc_vio_remove(struct vio_dev *vdev)
}
static struct vio_driver hvc_vio_driver = {
- .name = hvc_driver_name,
.id_table = hvc_driver_table,
.probe = hvc_vio_probe,
.remove = hvc_vio_remove,
.driver = {
+ .name = hvc_driver_name,
.owner = THIS_MODULE,
}
};
diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c
index f47f009f9259..53dc77c760fc 100644
--- a/drivers/char/hvcs.c
+++ b/drivers/char/hvcs.c
@@ -720,10 +720,13 @@ static int __devexit hvcs_remove(struct vio_dev *dev)
};
static struct vio_driver hvcs_vio_driver = {
- .name = hvcs_driver_name,
.id_table = hvcs_driver_table,
.probe = hvcs_probe,
.remove = hvcs_remove,
+ .driver = {
+ .name = hvcs_driver_name,
+ .owner = THIS_MODULE,
+ }
};
/* Only called from hvcs_get_pi please */
diff --git a/drivers/char/lcd.c b/drivers/char/lcd.c
index b77161146144..29963d8be667 100644
--- a/drivers/char/lcd.c
+++ b/drivers/char/lcd.c
@@ -575,8 +575,8 @@ static inline int button_pressed(void)
static int lcd_waiters = 0;
-static long lcd_read(struct inode *inode, struct file *file, char *buf,
- unsigned long count)
+static ssize_t lcd_read(struct file *file, char *buf,
+ size_t count, loff_t *ofs)
{
long buttons_now;
diff --git a/drivers/char/lcd.h b/drivers/char/lcd.h
index 878a95280e87..a8d4ae737158 100644
--- a/drivers/char/lcd.h
+++ b/drivers/char/lcd.h
@@ -22,7 +22,7 @@ static int timeout(volatile unsigned long);
#define MAX_IDLE_TIME 120
struct lcd_display {
- unsigned long buttons;
+ unsigned buttons;
int size1;
int size2;
unsigned char line1[LCD_CHARS_PER_LINE];
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 38be4b0dbd1c..91dd669273e0 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -231,9 +231,7 @@ static ssize_t write_mem(struct file * file, const char __user * buf,
static int mmap_mem(struct file * file, struct vm_area_struct * vma)
{
#if defined(__HAVE_PHYS_MEM_ACCESS_PROT)
- unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
-
- vma->vm_page_prot = phys_mem_access_prot(file, offset,
+ vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
vma->vm_end - vma->vm_start,
vma->vm_page_prot);
#elif defined(pgprot_noncached)
diff --git a/drivers/char/mwave/3780i.c b/drivers/char/mwave/3780i.c
index 613aed9e1840..d1fe05e83882 100644
--- a/drivers/char/mwave/3780i.c
+++ b/drivers/char/mwave/3780i.c
@@ -53,6 +53,8 @@
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/bitops.h>
+#include <linux/sched.h> /* cond_resched() */
+
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/system.h>
diff --git a/drivers/char/qtronix.c b/drivers/char/qtronix.c
index 40a3cf62e1a8..601d09baf9d7 100644
--- a/drivers/char/qtronix.c
+++ b/drivers/char/qtronix.c
@@ -591,6 +591,11 @@ static int __init psaux_init(void)
return retval;
queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
+ if (!queue) {
+ misc_deregister(&psaux_mouse);
+ return -ENOMEM;
+ }
+
memset(queue, 0, sizeof(*queue));
queue->head = queue->tail = 0;
init_waitqueue_head(&queue->proc_list);
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index 5b1d3680c8ab..928b850cc679 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -256,7 +256,6 @@ static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
static int sReadAiopID(ByteIO_t io);
static int sReadAiopNumChan(WordIO_t io);
-#ifdef MODULE
MODULE_AUTHOR("Theodore Ts'o");
MODULE_DESCRIPTION("Comtrol RocketPort driver");
module_param(board1, ulong, 0);
@@ -288,17 +287,14 @@ MODULE_PARM_DESC(pc104_3, "set interface types for ISA(PC104) board #3 (e.g. pc1
module_param_array(pc104_4, ulong, NULL, 0);
MODULE_PARM_DESC(pc104_4, "set interface types for ISA(PC104) board #4 (e.g. pc104_4=232,232,485,485,...");
-int rp_init(void);
+static int rp_init(void);
static void rp_cleanup_module(void);
module_init(rp_init);
module_exit(rp_cleanup_module);
-#endif
-#ifdef MODULE_LICENSE
MODULE_LICENSE("Dual BSD/GPL");
-#endif
/*************************************************************************/
/* Module code starts here */
@@ -2378,7 +2374,7 @@ static struct tty_operations rocket_ops = {
/*
* The module "startup" routine; it's run when the module is loaded.
*/
-int __init rp_init(void)
+static int __init rp_init(void)
{
int retval, pci_boards_found, isa_boards_found, i;
@@ -2502,7 +2498,6 @@ int __init rp_init(void)
return 0;
}
-#ifdef MODULE
static void rp_cleanup_module(void)
{
@@ -2530,7 +2525,6 @@ static void rp_cleanup_module(void)
if (controller)
release_region(controller, 4);
}
-#endif
/***************************************************************************
Function: sInitController
diff --git a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c
index 6b4e9d155f50..dda30e42ec79 100644
--- a/drivers/char/ser_a2232.c
+++ b/drivers/char/ser_a2232.c
@@ -790,7 +790,7 @@ static int __init a2232board_init(void)
}
- printk("Total: %d A2232 boards initialized.\n.", nr_a2232); /* Some status report if no card was found */
+ printk("Total: %d A2232 boards initialized.\n", nr_a2232); /* Some status report if no card was found */
a2232_init_portstructs();
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c
index 50e0b612a8a2..352547eabf7b 100644
--- a/drivers/char/specialix.c
+++ b/drivers/char/specialix.c
@@ -38,19 +38,19 @@
*
* Revision 1.0: April 1st 1997.
* Initial release for alpha testing.
- * Revision 1.1: April 14th 1997.
- * Incorporated Richard Hudsons suggestions,
+ * Revision 1.1: April 14th 1997.
+ * Incorporated Richard Hudsons suggestions,
* removed some debugging printk's.
* Revision 1.2: April 15th 1997.
* Ported to 2.1.x kernels.
- * Revision 1.3: April 17th 1997
- * Backported to 2.0. (Compatibility macros).
+ * Revision 1.3: April 17th 1997
+ * Backported to 2.0. (Compatibility macros).
* Revision 1.4: April 18th 1997
- * Fixed DTR/RTS bug that caused the card to indicate
- * "don't send data" to a modem after the password prompt.
+ * Fixed DTR/RTS bug that caused the card to indicate
+ * "don't send data" to a modem after the password prompt.
* Fixed bug for premature (fake) interrupts.
* Revision 1.5: April 19th 1997
- * fixed a minor typo in the header file, cleanup a little.
+ * fixed a minor typo in the header file, cleanup a little.
* performance warnings are now MAXed at once per minute.
* Revision 1.6: May 23 1997
* Changed the specialix=... format to include interrupt.
@@ -60,10 +60,10 @@
* port to linux-2.1.43 kernel.
* Revision 1.9: Oct 9 1998
* Added stuff for the IO8+/PCI version.
- * Revision 1.10: Oct 22 1999 / Jan 21 2000.
- * Added stuff for setserial.
+ * Revision 1.10: Oct 22 1999 / Jan 21 2000.
+ * Added stuff for setserial.
* Nicolas Mailhot (Nicolas.Mailhot@email.enst.fr)
- *
+ *
*/
#define VERSION "1.11"
@@ -154,7 +154,7 @@ static int sx_poll = HZ;
-/*
+/*
* The following defines are mostly for testing purposes. But if you need
* some nice reporting in your syslog, you can define them also.
*/
@@ -188,7 +188,7 @@ static DECLARE_MUTEX(tmp_buf_sem);
static unsigned long baud_table[] = {
0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
- 9600, 19200, 38400, 57600, 115200, 0,
+ 9600, 19200, 38400, 57600, 115200, 0,
};
static struct specialix_board sx_board[SX_NBOARD] = {
@@ -216,7 +216,7 @@ static inline int sx_paranoia_check(struct specialix_port const * port,
KERN_ERR "sx: Warning: bad specialix port magic number for device %s in %s\n";
static const char *badinfo =
KERN_ERR "sx: Warning: null specialix port for device %s in %s\n";
-
+
if (!port) {
printk(badinfo, name, routine);
return 1;
@@ -231,9 +231,9 @@ static inline int sx_paranoia_check(struct specialix_port const * port,
/*
- *
+ *
* Service functions for specialix IO8+ driver.
- *
+ *
*/
/* Get board number from pointer */
@@ -246,7 +246,7 @@ static inline int board_No (struct specialix_board * bp)
/* Get port number from pointer */
static inline int port_No (struct specialix_port const * port)
{
- return SX_PORT(port - sx_port);
+ return SX_PORT(port - sx_port);
}
@@ -309,7 +309,7 @@ static inline void sx_wait_CCR(struct specialix_board * bp)
return;
udelay (1);
}
-
+
printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
}
@@ -329,7 +329,7 @@ static inline void sx_wait_CCR_off(struct specialix_board * bp)
return;
udelay (1);
}
-
+
printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
}
@@ -338,34 +338,28 @@ static inline void sx_wait_CCR_off(struct specialix_board * bp)
* specialix IO8+ IO range functions.
*/
-static inline int sx_check_io_range(struct specialix_board * bp)
+static inline int sx_request_io_range(struct specialix_board * bp)
{
- return check_region (bp->base, SX_IO_SPACE);
-}
-
-
-static inline void sx_request_io_range(struct specialix_board * bp)
-{
- request_region(bp->base,
- bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE,
- "specialix IO8+" );
+ return request_region(bp->base,
+ bp->flags & SX_BOARD_IS_PCI ? SX_PCI_IO_SPACE : SX_IO_SPACE,
+ "specialix IO8+") == NULL;
}
static inline void sx_release_io_range(struct specialix_board * bp)
{
- release_region(bp->base,
+ release_region(bp->base,
bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE);
}
-
+
/* Must be called with enabled interrupts */
-/* Ugly. Very ugly. Don't use this for anything else than initialization
+/* Ugly. Very ugly. Don't use this for anything else than initialization
code */
static inline void sx_long_delay(unsigned long delay)
{
unsigned long i;
-
+
for (i = jiffies + delay; time_after(i, jiffies); ) ;
}
@@ -378,7 +372,7 @@ static int sx_set_irq ( struct specialix_board *bp)
int i;
unsigned long flags;
- if (bp->flags & SX_BOARD_IS_PCI)
+ if (bp->flags & SX_BOARD_IS_PCI)
return 1;
switch (bp->irq) {
/* In the same order as in the docs... */
@@ -420,7 +414,7 @@ static int sx_init_CD186x(struct specialix_board * bp)
sx_out_off(bp, CD186x_PILR3, SX_ACK_RINT); /* Prio for receiver intr */
/* Set RegAckEn */
sx_out_off(bp, CD186x_SRCR, sx_in (bp, CD186x_SRCR) | SRCR_REGACKEN);
-
+
/* Setting up prescaler. We need 4 ticks per 1 ms */
scaler = SX_OSCFREQ/SPECIALIX_TPS;
@@ -448,7 +442,7 @@ static int read_cross_byte (struct specialix_board *bp, int reg, int bit)
spin_lock_irqsave(&bp->lock, flags);
for (i=0, t=0;i<8;i++) {
sx_out_off (bp, CD186x_CAR, i);
- if (sx_in_off (bp, reg) & bit)
+ if (sx_in_off (bp, reg) & bit)
t |= 1 << i;
}
spin_unlock_irqrestore(&bp->lock, flags);
@@ -472,7 +466,7 @@ void missed_irq (unsigned long data)
spin_unlock_irqrestore(&bp->lock, flags);
if (irq) {
printk (KERN_INFO "Missed interrupt... Calling int from timer. \n");
- sx_interrupt (((struct specialix_board *)data)->irq,
+ sx_interrupt (((struct specialix_board *)data)->irq,
(void*)data, NULL);
}
missed_irq_timer.expires = jiffies + sx_poll;
@@ -495,7 +489,7 @@ static int sx_probe(struct specialix_board *bp)
func_enter();
- if (sx_check_io_range(bp)) {
+ if (sx_request_io_range(bp)) {
func_exit();
return 1;
}
@@ -509,15 +503,16 @@ static int sx_probe(struct specialix_board *bp)
short_pause ();
val2 = sx_in_off(bp, CD186x_PPRL);
-
+
if ((val1 != 0x5a) || (val2 != 0xa5)) {
printk(KERN_INFO "sx%d: specialix IO8+ Board at 0x%03x not found.\n",
board_No(bp), bp->base);
+ sx_release_io_range(bp);
func_exit();
return 1;
}
- /* Check the DSR lines that Specialix uses as board
+ /* Check the DSR lines that Specialix uses as board
identification */
val1 = read_cross_byte (bp, CD186x_MSVR, MSVR_DSR);
val2 = read_cross_byte (bp, CD186x_MSVR, MSVR_RTS);
@@ -532,6 +527,7 @@ static int sx_probe(struct specialix_board *bp)
if (val1 != val2) {
printk(KERN_INFO "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n",
board_No(bp), val2, bp->base, val1);
+ sx_release_io_range(bp);
func_exit();
return 1;
}
@@ -546,7 +542,7 @@ static int sx_probe(struct specialix_board *bp)
sx_wait_CCR(bp);
sx_out(bp, CD186x_CCR, CCR_TXEN); /* Enable transmitter */
sx_out(bp, CD186x_IER, IER_TXRDY); /* Enable tx empty intr */
- sx_long_delay(HZ/20);
+ sx_long_delay(HZ/20);
irqs = probe_irq_off(irqs);
dprintk (SX_DEBUG_INIT, "SRSR = %02x, ", sx_in(bp, CD186x_SRSR));
@@ -561,14 +557,15 @@ static int sx_probe(struct specialix_board *bp)
}
dprintk (SX_DEBUG_INIT "val1 = %02x, val2 = %02x, val3 = %02x.\n",
- val1, val2, val3);
-
+ val1, val2, val3);
+
}
-
+
#if 0
if (irqs <= 0) {
printk(KERN_ERR "sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.\n",
board_No(bp), bp->base);
+ sx_release_io_range(bp);
func_exit();
return 1;
}
@@ -579,19 +576,20 @@ static int sx_probe(struct specialix_board *bp)
#endif
/* Reset CD186x again */
if (!sx_init_CD186x(bp)) {
+ sx_release_io_range(bp);
func_exit();
- return -EIO;
+ return 1;
}
sx_request_io_range(bp);
bp->flags |= SX_BOARD_PRESENT;
-
+
/* Chip revcode pkgtype
GFRCR SRCR bit 7
CD180 rev B 0x81 0
CD180 rev C 0x82 0
CD1864 rev A 0x82 1
- CD1865 rev A 0x83 1 -- Do not use!!! Does not work.
+ CD1865 rev A 0x83 1 -- Do not use!!! Does not work.
CD1865 rev B 0x84 1
-- Thanks to Gwen Wang, Cirrus Logic.
*/
@@ -623,8 +621,8 @@ static int sx_probe(struct specialix_board *bp)
return 0;
}
-/*
- *
+/*
+ *
* Interrupt processing routines.
* */
@@ -657,7 +655,7 @@ static inline struct specialix_port * sx_get_port(struct specialix_board * bp,
return port;
}
}
- printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n",
+ printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n",
board_No(bp), what, channel);
return NULL;
}
@@ -681,7 +679,7 @@ static inline void sx_receive_exc(struct specialix_board * bp)
tty = port->tty;
dprintk (SX_DEBUG_RX, "port: %p count: %d BUFF_SIZE: %d\n",
port, tty->flip.count, TTY_FLIPBUF_SIZE);
-
+
status = sx_in(bp, CD186x_RCSR);
dprintk (SX_DEBUG_RX, "status: 0x%x\n", status);
@@ -707,30 +705,30 @@ static inline void sx_receive_exc(struct specialix_board * bp)
return;
}
if (status & RCSR_TOUT) {
- printk(KERN_INFO "sx%d: port %d: Receiver timeout. Hardware problems ?\n",
+ printk(KERN_INFO "sx%d: port %d: Receiver timeout. Hardware problems ?\n",
board_No(bp), port_No(port));
func_exit();
return;
-
+
} else if (status & RCSR_BREAK) {
dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n",
board_No(bp), port_No(port));
*tty->flip.flag_buf_ptr++ = TTY_BREAK;
if (port->flags & ASYNC_SAK)
do_SAK(tty);
-
- } else if (status & RCSR_PE)
+
+ } else if (status & RCSR_PE)
*tty->flip.flag_buf_ptr++ = TTY_PARITY;
-
- else if (status & RCSR_FE)
+
+ else if (status & RCSR_FE)
*tty->flip.flag_buf_ptr++ = TTY_FRAME;
-
+
else if (status & RCSR_OE)
*tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
-
+
else
*tty->flip.flag_buf_ptr++ = 0;
-
+
*tty->flip.char_buf_ptr++ = ch;
tty->flip.count++;
schedule_delayed_work(&tty->flip.work, 1);
@@ -746,18 +744,18 @@ static inline void sx_receive(struct specialix_board * bp)
unsigned char count;
func_enter();
-
+
if (!(port = sx_get_port(bp, "Receive"))) {
dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n");
func_exit();
return;
}
tty = port->tty;
-
+
count = sx_in(bp, CD186x_RDCR);
dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count);
port->hits[count > 8 ? 9 : count]++;
-
+
while (count--) {
if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
printk(KERN_INFO "sx%d: port %d: Working around flip buffer overflow.\n",
@@ -787,7 +785,7 @@ static inline void sx_transmit(struct specialix_board * bp)
}
dprintk (SX_DEBUG_TX, "port: %p\n", port);
tty = port->tty;
-
+
if (port->IER & IER_TXEMPTY) {
/* FIFO drained */
sx_out(bp, CD186x_CAR, port_No(port));
@@ -796,7 +794,7 @@ static inline void sx_transmit(struct specialix_board * bp)
func_exit();
return;
}
-
+
if ((port->xmit_cnt <= 0 && !port->break_length)
|| tty->stopped || tty->hw_stopped) {
sx_out(bp, CD186x_CAR, port_No(port));
@@ -805,7 +803,7 @@ static inline void sx_transmit(struct specialix_board * bp)
func_exit();
return;
}
-
+
if (port->break_length) {
if (port->break_length > 0) {
if (port->COR2 & COR2_ETC) {
@@ -831,7 +829,7 @@ static inline void sx_transmit(struct specialix_board * bp)
func_exit();
return;
}
-
+
count = CD186x_NFIFO;
do {
sx_out(bp, CD186x_TDR, port->xmit_buf[port->xmit_tail++]);
@@ -839,7 +837,7 @@ static inline void sx_transmit(struct specialix_board * bp)
if (--port->xmit_cnt <= 0)
break;
} while (--count > 0);
-
+
if (port->xmit_cnt <= 0) {
sx_out(bp, CD186x_CAR, port_No(port));
port->IER &= ~IER_TXRDY;
@@ -862,9 +860,9 @@ static inline void sx_check_modem(struct specialix_board * bp)
dprintk (SX_DEBUG_SIGNALS, "Modem intr. ");
if (!(port = sx_get_port(bp, "Modem")))
return;
-
+
tty = port->tty;
-
+
mcr = sx_in(bp, CD186x_MCR);
printk ("mcr = %02x.\n", mcr);
@@ -879,7 +877,7 @@ static inline void sx_check_modem(struct specialix_board * bp)
schedule_work(&port->tqueue_hangup);
}
}
-
+
#ifdef SPECIALIX_BRAIN_DAMAGED_CTS
if (mcr & MCR_CTSCHG) {
if (sx_in(bp, CD186x_MSVR) & MSVR_CTS) {
@@ -906,7 +904,7 @@ static inline void sx_check_modem(struct specialix_board * bp)
sx_out(bp, CD186x_IER, port->IER);
}
#endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
-
+
/* Clear change bits */
sx_out(bp, CD186x_MCR, 0);
}
@@ -940,7 +938,7 @@ static irqreturn_t sx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
while ((++loop < 16) && (status = (sx_in(bp, CD186x_SRSR) &
(SRSR_RREQint |
SRSR_TREQint |
- SRSR_MREQint)))) {
+ SRSR_MREQint)))) {
if (status & SRSR_RREQint) {
ack = sx_in(bp, CD186x_RRAR);
@@ -951,7 +949,7 @@ static irqreturn_t sx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
else
printk(KERN_ERR "sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
board_No(bp), status, ack);
-
+
} else if (status & SRSR_TREQint) {
ack = sx_in(bp, CD186x_TRAR);
@@ -963,13 +961,13 @@ static irqreturn_t sx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
} else if (status & SRSR_MREQint) {
ack = sx_in(bp, CD186x_MRAR);
- if (ack == (SX_ID | GIVR_IT_MODEM))
+ if (ack == (SX_ID | GIVR_IT_MODEM))
sx_check_modem(bp);
else
printk(KERN_ERR "sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
board_No(bp), status, ack);
-
- }
+
+ }
sx_out(bp, CD186x_EOIR, 0); /* Mark end of interrupt */
}
@@ -1026,7 +1024,7 @@ static inline int sx_setup_board(struct specialix_board * bp)
{
int error;
- if (bp->flags & SX_BOARD_ACTIVE)
+ if (bp->flags & SX_BOARD_ACTIVE)
return 0;
if (bp->flags & SX_BOARD_IS_PCI)
@@ -1034,7 +1032,7 @@ static inline int sx_setup_board(struct specialix_board * bp)
else
error = request_irq(bp->irq, sx_interrupt, SA_INTERRUPT, "specialix IO8+", bp);
- if (error)
+ if (error)
return error;
turn_ints_on (bp);
@@ -1055,7 +1053,7 @@ static inline void sx_shutdown_board(struct specialix_board *bp)
}
bp->flags &= ~SX_BOARD_ACTIVE;
-
+
dprintk (SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n",
bp->irq, board_No (bp));
free_irq(bp->irq, bp);
@@ -1068,7 +1066,7 @@ static inline void sx_shutdown_board(struct specialix_board *bp)
/*
- * Setting up port characteristics.
+ * Setting up port characteristics.
* Must be called with disabled interrupts
*/
static void sx_change_speed(struct specialix_board *bp, struct specialix_port *port)
@@ -1103,10 +1101,10 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
spin_unlock_irqrestore(&bp->lock, flags);
dprintk (SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR);
baud = C_BAUD(tty);
-
+
if (baud & CBAUDEX) {
baud &= ~CBAUDEX;
- if (baud < 1 || baud > 2)
+ if (baud < 1 || baud > 2)
port->tty->termios->c_cflag &= ~CBAUDEX;
else
baud += 15;
@@ -1117,8 +1115,8 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
baud += 2;
}
-
-
+
+
if (!baud_table[baud]) {
/* Drop DTR & exit */
dprintk (SX_DEBUG_TERMIOS, "Dropping DTR... Hmm....\n");
@@ -1127,7 +1125,7 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
spin_lock_irqsave(&bp->lock, flags);
sx_out(bp, CD186x_MSVR, port->MSVR );
spin_unlock_irqrestore(&bp->lock, flags);
- }
+ }
else
dprintk (SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n");
return;
@@ -1137,9 +1135,9 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
port ->MSVR |= MSVR_DTR;
}
}
-
+
/*
- * Now we must calculate some speed depended things
+ * Now we must calculate some speed depended things
*/
/* Set baud rate for port */
@@ -1152,7 +1150,7 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
tmp = (((SX_OSCFREQ + baud_table[baud]/2) / baud_table[baud] +
CD186x_TPC/2) / CD186x_TPC);
- if ((tmp < 0x10) && time_before(again, jiffies)) {
+ if ((tmp < 0x10) && time_before(again, jiffies)) {
again = jiffies + HZ * 60;
/* Page 48 of version 2.0 of the CL-CD1865 databook */
if (tmp >= 12) {
@@ -1164,27 +1162,27 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
"Warning: overstressing Cirrus chip. "
"This might not work.\n"
- "Read specialix.txt for more info.\n",
+ "Read specialix.txt for more info.\n",
port_No (port), tmp);
}
}
spin_lock_irqsave(&bp->lock, flags);
- sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff);
- sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff);
- sx_out(bp, CD186x_RBPRL, tmp & 0xff);
+ sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff);
+ sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff);
+ sx_out(bp, CD186x_RBPRL, tmp & 0xff);
sx_out(bp, CD186x_TBPRL, tmp & 0xff);
spin_unlock_irqrestore(&bp->lock, flags);
if (port->custom_divisor) {
baud = (SX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor;
baud = ( baud + 5 ) / 10;
- } else
+ } else
baud = (baud_table[baud] + 5) / 10; /* Estimated CPS */
/* Two timer ticks seems enough to wakeup something like SLIP driver */
- tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;
+ tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;
port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
SERIAL_XMIT_SIZE - 1 : tmp);
-
+
/* Receiver timeout will be transmission time for 1.5 chars */
tmp = (SPECIALIX_TPS + SPECIALIX_TPS/2 + baud/2) / baud;
tmp = (tmp > 0xff) ? 0xff : tmp;
@@ -1205,29 +1203,29 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
cor1 |= COR1_8BITS;
break;
}
-
- if (C_CSTOPB(tty))
+
+ if (C_CSTOPB(tty))
cor1 |= COR1_2SB;
-
+
cor1 |= COR1_IGNORE;
if (C_PARENB(tty)) {
cor1 |= COR1_NORMPAR;
- if (C_PARODD(tty))
+ if (C_PARODD(tty))
cor1 |= COR1_ODDP;
- if (I_INPCK(tty))
+ if (I_INPCK(tty))
cor1 &= ~COR1_IGNORE;
}
/* Set marking of some errors */
port->mark_mask = RCSR_OE | RCSR_TOUT;
- if (I_INPCK(tty))
+ if (I_INPCK(tty))
port->mark_mask |= RCSR_FE | RCSR_PE;
- if (I_BRKINT(tty) || I_PARMRK(tty))
+ if (I_BRKINT(tty) || I_PARMRK(tty))
port->mark_mask |= RCSR_BREAK;
- if (I_IGNPAR(tty))
+ if (I_IGNPAR(tty))
port->mark_mask &= ~(RCSR_FE | RCSR_PE);
if (I_IGNBRK(tty)) {
port->mark_mask &= ~RCSR_BREAK;
- if (I_IGNPAR(tty))
+ if (I_IGNPAR(tty))
/* Real raw mode. Ignore all */
port->mark_mask &= ~RCSR_OE;
}
@@ -1241,7 +1239,7 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) & (MSVR_CTS|MSVR_DSR));
spin_unlock_irqrestore(&bp->lock, flags);
#else
- port->COR2 |= COR2_CTSAE;
+ port->COR2 |= COR2_CTSAE;
#endif
}
/* Enable Software Flow Control. FIXME: I'm not sure about this */
@@ -1264,11 +1262,11 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
mcor1 |= MCOR1_CDZD;
mcor2 |= MCOR2_CDOD;
}
-
- if (C_CREAD(tty))
+
+ if (C_CREAD(tty))
/* Enable receiver */
port->IER |= IER_RXD;
-
+
/* Set input FIFO size (1-8 bytes) */
cor3 |= sx_rxfifo;
/* Setting up CD186x channel registers */
@@ -1311,11 +1309,11 @@ static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port
func_exit();
return 0;
}
-
+
if (!port->xmit_buf) {
/* We may sleep in get_zeroed_page() */
unsigned long tmp;
-
+
if (!(tmp = get_zeroed_page(GFP_KERNEL))) {
func_exit();
return -ENOMEM;
@@ -1328,10 +1326,10 @@ static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port
}
port->xmit_buf = (unsigned char *) tmp;
}
-
+
spin_lock_irqsave(&port->lock, flags);
- if (port->tty)
+ if (port->tty)
clear_bit(TTY_IO_ERROR, &port->tty->flags);
port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
@@ -1340,7 +1338,7 @@ static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port
spin_unlock_irqrestore(&port->lock, flags);
-
+
func_exit();
return 0;
}
@@ -1352,14 +1350,14 @@ static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *
struct tty_struct *tty;
int i;
unsigned long flags;
-
+
func_enter();
if (!(port->flags & ASYNC_INITIALIZED)) {
func_exit();
return;
}
-
+
if (sx_debug & SX_DEBUG_FIFO) {
dprintk(SX_DEBUG_FIFO, "sx%d: port %d: %ld overruns, FIFO hits [ ",
board_No(bp), port_No(port), port->overrun);
@@ -1394,13 +1392,13 @@ static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *
if (tty)
set_bit(TTY_IO_ERROR, &tty->flags);
port->flags &= ~ASYNC_INITIALIZED;
-
- if (!bp->count)
+
+ if (!bp->count)
sx_shutdown_board(bp);
func_exit();
}
-
+
static int block_til_ready(struct tty_struct *tty, struct file * filp,
struct specialix_port *port)
{
@@ -1427,7 +1425,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
return -ERESTARTSYS;
}
}
-
+
/*
* If non-blocking mode is set, or the port is not enabled,
* then make the check up front and then exit.
@@ -1477,7 +1475,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
if (port->flags & ASYNC_HUP_NOTIFY)
retval = -EAGAIN;
else
- retval = -ERESTARTSYS;
+ retval = -ERESTARTSYS;
break;
}
if (!(port->flags & ASYNC_CLOSING) &&
@@ -1506,7 +1504,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
port->flags |= ASYNC_NORMAL_ACTIVE;
func_exit();
return 0;
-}
+}
static int sx_open(struct tty_struct * tty, struct file * filp)
@@ -1526,7 +1524,7 @@ static int sx_open(struct tty_struct * tty, struct file * filp)
func_exit();
return -ENODEV;
}
-
+
bp = &sx_board[board];
port = sx_port + board * SX_NPORT + SX_PORT(tty->index);
port->overrun = 0;
@@ -1557,7 +1555,7 @@ static int sx_open(struct tty_struct * tty, struct file * filp)
func_enter();
return error;
}
-
+
if ((error = block_til_ready(tty, filp, port))) {
func_enter();
return error;
@@ -1574,7 +1572,7 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
struct specialix_board *bp;
unsigned long flags;
unsigned long timeout;
-
+
func_enter();
if (!port || sx_paranoia_check(port, tty->name, "close")) {
func_exit();
@@ -1587,7 +1585,7 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
func_exit();
return;
}
-
+
bp = port_Board(port);
if ((tty->count == 1) && (port->count != 1)) {
printk(KERN_ERR "sx%d: sx_close: bad port count;"
@@ -1607,7 +1605,7 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
}
port->flags |= ASYNC_CLOSING;
/*
- * Now we wait for the transmit buffer to clear; and we notify
+ * Now we wait for the transmit buffer to clear; and we notify
* the line discipline to only process XON/XOFF characters.
*/
tty->closing = 1;
@@ -1681,7 +1679,7 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
}
-static int sx_write(struct tty_struct * tty,
+static int sx_write(struct tty_struct * tty,
const unsigned char *buf, int count)
{
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
@@ -1694,7 +1692,7 @@ static int sx_write(struct tty_struct * tty,
func_exit();
return 0;
}
-
+
bp = port_Board(port);
if (!tty || !port->xmit_buf || !tmp_buf) {
@@ -1824,7 +1822,7 @@ static int sx_chars_in_buffer(struct tty_struct *tty)
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
func_enter();
-
+
if (sx_paranoia_check(port, tty->name, "sx_chars_in_buffer")) {
func_exit();
return 0;
@@ -1881,13 +1879,13 @@ static int sx_tiocmget(struct tty_struct *tty, struct file *file)
port_No(port), status, sx_in (bp, CD186x_CAR));
dprintk (SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port);
if (SX_CRTSCTS(port->tty)) {
- result = /* (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */
+ result = /* (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */
| ((status & MSVR_DTR) ? TIOCM_RTS : 0)
| ((status & MSVR_CD) ? TIOCM_CAR : 0)
|/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
| ((status & MSVR_CTS) ? TIOCM_CTS : 0);
} else {
- result = /* (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */
+ result = /* (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */
| ((status & MSVR_DTR) ? TIOCM_DTR : 0)
| ((status & MSVR_CD) ? TIOCM_CAR : 0)
|/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
@@ -1955,7 +1953,7 @@ static inline void sx_send_break(struct specialix_port * port, unsigned long len
{
struct specialix_board *bp = port_Board(port);
unsigned long flags;
-
+
func_enter();
spin_lock_irqsave (&port->lock, flags);
@@ -1996,8 +1994,8 @@ static inline int sx_set_serial_info(struct specialix_port * port,
func_enter();
return -EFAULT;
}
-
-#if 0
+
+#if 0
if ((tmp.irq != bp->irq) ||
(tmp.port != bp->base) ||
(tmp.type != PORT_CIRRUS) ||
@@ -2008,12 +2006,12 @@ static inline int sx_set_serial_info(struct specialix_port * port,
func_exit();
return -EINVAL;
}
-#endif
+#endif
change_speed = ((port->flags & ASYNC_SPD_MASK) !=
(tmp.flags & ASYNC_SPD_MASK));
change_speed |= (tmp.custom_divisor != port->custom_divisor);
-
+
if (!capable(CAP_SYS_ADMIN)) {
if ((tmp.close_delay != port->close_delay) ||
(tmp.closing_wait != port->closing_wait) ||
@@ -2045,7 +2043,7 @@ static inline int sx_get_serial_info(struct specialix_port * port,
{
struct serial_struct tmp;
struct specialix_board *bp = port_Board(port);
-
+
func_enter();
/*
@@ -2074,7 +2072,7 @@ static inline int sx_get_serial_info(struct specialix_port * port,
}
-static int sx_ioctl(struct tty_struct * tty, struct file * filp,
+static int sx_ioctl(struct tty_struct * tty, struct file * filp,
unsigned int cmd, unsigned long arg)
{
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
@@ -2087,7 +2085,7 @@ static int sx_ioctl(struct tty_struct * tty, struct file * filp,
func_exit();
return -ENODEV;
}
-
+
switch (cmd) {
case TCSBRK: /* SVID version: non-zero arg --> no break */
retval = tty_check_change(tty);
@@ -2129,7 +2127,7 @@ static int sx_ioctl(struct tty_struct * tty, struct file * filp,
case TIOCGSERIAL:
func_exit();
return sx_get_serial_info(port, argp);
- case TIOCSSERIAL:
+ case TIOCSSERIAL:
func_exit();
return sx_set_serial_info(port, argp);
default:
@@ -2153,16 +2151,16 @@ static void sx_throttle(struct tty_struct * tty)
func_exit();
return;
}
-
+
bp = port_Board(port);
-
+
/* Use DTR instead of RTS ! */
- if (SX_CRTSCTS (tty))
+ if (SX_CRTSCTS (tty))
port->MSVR &= ~MSVR_DTR;
else {
/* Auch!!! I think the system shouldn't call this then. */
/* Or maybe we're supposed (allowed?) to do our side of hw
- handshake anyway, even when hardware handshake is off.
+ handshake anyway, even when hardware handshake is off.
When you see this in your logs, please report.... */
printk (KERN_ERR "sx%d: Need to throttle, but can't (hardware hs is off)\n",
port_No (port));
@@ -2193,14 +2191,14 @@ static void sx_unthrottle(struct tty_struct * tty)
unsigned long flags;
func_enter();
-
+
if (sx_paranoia_check(port, tty->name, "sx_unthrottle")) {
func_exit();
return;
}
-
+
bp = port_Board(port);
-
+
spin_lock_irqsave(&port->lock, flags);
/* XXXX Use DTR INSTEAD???? */
if (SX_CRTSCTS(tty)) {
@@ -2234,14 +2232,14 @@ static void sx_stop(struct tty_struct * tty)
unsigned long flags;
func_enter();
-
+
if (sx_paranoia_check(port, tty->name, "sx_stop")) {
func_exit();
return;
}
bp = port_Board(port);
-
+
spin_lock_irqsave(&port->lock, flags);
port->IER &= ~IER_TXRDY;
spin_lock_irqsave(&bp->lock, flags);
@@ -2261,14 +2259,14 @@ static void sx_start(struct tty_struct * tty)
unsigned long flags;
func_enter();
-
+
if (sx_paranoia_check(port, tty->name, "sx_start")) {
func_exit();
return;
}
-
+
bp = port_Board(port);
-
+
spin_lock_irqsave(&port->lock, flags);
if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
port->IER |= IER_TXRDY;
@@ -2290,13 +2288,13 @@ static void sx_start(struct tty_struct * tty)
*
* serial interrupt routine -> (workqueue) ->
* do_sx_hangup() -> tty->hangup() -> sx_hangup()
- *
+ *
*/
static void do_sx_hangup(void *private_)
{
struct specialix_port *port = (struct specialix_port *) private_;
struct tty_struct *tty;
-
+
func_enter();
tty = port->tty;
@@ -2319,9 +2317,9 @@ static void sx_hangup(struct tty_struct * tty)
func_exit();
return;
}
-
+
bp = port_Board(port);
-
+
sx_shutdown_port(bp, port);
spin_lock_irqsave(&port->lock, flags);
port->event = 0;
@@ -2346,10 +2344,10 @@ static void sx_set_termios(struct tty_struct * tty, struct termios * old_termios
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
unsigned long flags;
struct specialix_board * bp;
-
+
if (sx_paranoia_check(port, tty->name, "sx_set_termios"))
return;
-
+
if (tty->termios->c_cflag == old_termios->c_cflag &&
tty->termios->c_iflag == old_termios->c_iflag)
return;
@@ -2420,7 +2418,7 @@ static int sx_init_drivers(void)
func_exit();
return 1;
}
-
+
if (!(tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL))) {
printk(KERN_ERR "sx: Couldn't get free page.\n");
put_tty_driver(specialix_driver);
@@ -2457,7 +2455,7 @@ static int sx_init_drivers(void)
init_waitqueue_head(&sx_port[i].close_wait);
spin_lock_init(&sx_port[i].lock);
}
-
+
func_exit();
return 0;
}
@@ -2472,8 +2470,8 @@ static void sx_release_drivers(void)
func_exit();
}
-/*
- * This routine must be called by kernel at boot time
+/*
+ * This routine must be called by kernel at boot time
*/
static int __init specialix_init(void)
{
@@ -2489,7 +2487,7 @@ static int __init specialix_init(void)
#else
printk (KERN_INFO "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
#endif
-
+
for (i = 0; i < SX_NBOARD; i++)
sx_board[i].lock = SPIN_LOCK_UNLOCKED;
@@ -2498,7 +2496,7 @@ static int __init specialix_init(void)
return -EIO;
}
- for (i = 0; i < SX_NBOARD; i++)
+ for (i = 0; i < SX_NBOARD; i++)
if (sx_board[i].base && !sx_probe(&sx_board[i]))
found++;
@@ -2512,8 +2510,8 @@ static int __init specialix_init(void)
i++;
continue;
}
- pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX,
- PCI_DEVICE_ID_SPECIALIX_IO8,
+ pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX,
+ PCI_DEVICE_ID_SPECIALIX_IO8,
pdev);
if (!pdev) break;
@@ -2557,10 +2555,10 @@ module_param(sx_poll, int, 0);
/*
* You can setup up to 4 boards.
* by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter.
- * You should specify the IRQs too in that case "irq=....,...".
- *
+ * You should specify the IRQs too in that case "irq=....,...".
+ *
* More than 4 boards in one computer is not possible, as the card can
- * only use 4 different interrupts.
+ * only use 4 different interrupts.
*
*/
static int __init specialix_init_module(void)
@@ -2583,16 +2581,16 @@ static int __init specialix_init_module(void)
return specialix_init();
}
-
+
static void __exit specialix_exit_module(void)
{
int i;
-
+
func_enter();
sx_release_drivers();
for (i = 0; i < SX_NBOARD; i++)
- if (sx_board[i].flags & SX_BOARD_PRESENT)
+ if (sx_board[i].flags & SX_BOARD_PRESENT)
sx_release_io_range(&sx_board[i]);
#ifdef SPECIALIX_TIMER
del_timer (&missed_irq_timer);
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index ea2d54be4843..0133dc0e25d0 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -912,6 +912,7 @@ MODULE_DEVICE_TABLE(pci, synclink_pci_tbl);
MODULE_LICENSE("GPL");
static struct pci_driver synclink_pci_driver = {
+ .owner = THIS_MODULE,
.name = "synclink",
.id_table = synclink_pci_tbl,
.probe = synclink_init_one,
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index 6fb165cf8a61..f185724448b1 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -500,6 +500,7 @@ MODULE_DEVICE_TABLE(pci, synclinkmp_pci_tbl);
MODULE_LICENSE("GPL");
static struct pci_driver synclinkmp_pci_driver = {
+ .owner = THIS_MODULE,
.name = "synclinkmp",
.id_table = synclinkmp_pci_tbl,
.probe = synclinkmp_init_one,
diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c
new file mode 100644
index 000000000000..18cdd4361dc6
--- /dev/null
+++ b/drivers/char/tlclk.c
@@ -0,0 +1,896 @@
+/*
+ * Telecom Clock driver for Intel NetStructure(tm) MPCBL0010
+ *
+ * Copyright (C) 2005 Kontron Canada
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. 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.
+ *
+ * Send feedback to <sebastien.bouchard@ca.kontron.com> and the current
+ * Maintainer <mark.gross@intel.com>
+ *
+ * Description : This is the TELECOM CLOCK module driver for the ATCA
+ * MPCBL0010 ATCA computer.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/kernel.h> /* printk() */
+#include <linux/fs.h> /* everything... */
+#include <linux/errno.h> /* error codes */
+#include <linux/delay.h> /* udelay */
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/timer.h>
+#include <linux/sysfs.h>
+#include <linux/device.h>
+#include <linux/miscdevice.h>
+#include <asm/io.h> /* inb/outb */
+#include <asm/uaccess.h>
+
+MODULE_AUTHOR("Sebastien Bouchard <sebastien.bouchard@ca.kontron.com>");
+MODULE_LICENSE("GPL");
+
+/*Hardware Reset of the PLL */
+#define RESET_ON 0x00
+#define RESET_OFF 0x01
+
+/* MODE SELECT */
+#define NORMAL_MODE 0x00
+#define HOLDOVER_MODE 0x10
+#define FREERUN_MODE 0x20
+
+/* FILTER SELECT */
+#define FILTER_6HZ 0x04
+#define FILTER_12HZ 0x00
+
+/* SELECT REFERENCE FREQUENCY */
+#define REF_CLK1_8kHz 0x00
+#define REF_CLK2_19_44MHz 0x02
+
+/* Select primary or secondary redundant clock */
+#define PRIMARY_CLOCK 0x00
+#define SECONDARY_CLOCK 0x01
+
+/* CLOCK TRANSMISSION DEFINE */
+#define CLK_8kHz 0xff
+#define CLK_16_384MHz 0xfb
+
+#define CLK_1_544MHz 0x00
+#define CLK_2_048MHz 0x01
+#define CLK_4_096MHz 0x02
+#define CLK_6_312MHz 0x03
+#define CLK_8_192MHz 0x04
+#define CLK_19_440MHz 0x06
+
+#define CLK_8_592MHz 0x08
+#define CLK_11_184MHz 0x09
+#define CLK_34_368MHz 0x0b
+#define CLK_44_736MHz 0x0a
+
+/* RECEIVED REFERENCE */
+#define AMC_B1 0
+#define AMC_B2 1
+
+/* HARDWARE SWITCHING DEFINE */
+#define HW_ENABLE 0x80
+#define HW_DISABLE 0x00
+
+/* HARDWARE SWITCHING MODE DEFINE */
+#define PLL_HOLDOVER 0x40
+#define LOST_CLOCK 0x00
+
+/* ALARMS DEFINE */
+#define UNLOCK_MASK 0x10
+#define HOLDOVER_MASK 0x20
+#define SEC_LOST_MASK 0x40
+#define PRI_LOST_MASK 0x80
+
+/* INTERRUPT CAUSE DEFINE */
+
+#define PRI_LOS_01_MASK 0x01
+#define PRI_LOS_10_MASK 0x02
+
+#define SEC_LOS_01_MASK 0x04
+#define SEC_LOS_10_MASK 0x08
+
+#define HOLDOVER_01_MASK 0x10
+#define HOLDOVER_10_MASK 0x20
+
+#define UNLOCK_01_MASK 0x40
+#define UNLOCK_10_MASK 0x80
+
+struct tlclk_alarms {
+ __u32 lost_clocks;
+ __u32 lost_primary_clock;
+ __u32 lost_secondary_clock;
+ __u32 primary_clock_back;
+ __u32 secondary_clock_back;
+ __u32 switchover_primary;
+ __u32 switchover_secondary;
+ __u32 pll_holdover;
+ __u32 pll_end_holdover;
+ __u32 pll_lost_sync;
+ __u32 pll_sync;
+};
+/* Telecom clock I/O register definition */
+#define TLCLK_BASE 0xa08
+#define TLCLK_REG0 TLCLK_BASE
+#define TLCLK_REG1 (TLCLK_BASE+1)
+#define TLCLK_REG2 (TLCLK_BASE+2)
+#define TLCLK_REG3 (TLCLK_BASE+3)
+#define TLCLK_REG4 (TLCLK_BASE+4)
+#define TLCLK_REG5 (TLCLK_BASE+5)
+#define TLCLK_REG6 (TLCLK_BASE+6)
+#define TLCLK_REG7 (TLCLK_BASE+7)
+
+#define SET_PORT_BITS(port, mask, val) outb(((inb(port) & mask) | val), port)
+
+/* 0 = Dynamic allocation of the major device number */
+#define TLCLK_MAJOR 0
+
+/* sysfs interface definition:
+Upon loading the driver will create a sysfs directory under
+/sys/devices/platform/telco_clock.
+
+This directory exports the following interfaces. There operation is
+documented in the MCPBL0010 TPS under the Telecom Clock API section, 11.4.
+alarms :
+current_ref :
+enable_clk3a_output :
+enable_clk3b_output :
+enable_clka0_output :
+enable_clka1_output :
+enable_clkb0_output :
+enable_clkb1_output :
+filter_select :
+hardware_switching :
+hardware_switching_mode :
+interrupt_switch :
+mode_select :
+refalign :
+reset :
+select_amcb1_transmit_clock :
+select_amcb2_transmit_clock :
+select_redundant_clock :
+select_ref_frequency :
+test_mode :
+
+All sysfs interfaces are integers in hex format, i.e echo 99 > refalign
+has the same effect as echo 0x99 > refalign.
+*/
+
+static unsigned int telclk_interrupt;
+
+static int int_events; /* Event that generate a interrupt */
+static int got_event; /* if events processing have been done */
+
+static void switchover_timeout(unsigned long data);
+static struct timer_list switchover_timer =
+ TIMER_INITIALIZER(switchover_timeout , 0, 0);
+
+static struct tlclk_alarms *alarm_events;
+
+static DEFINE_SPINLOCK(event_lock);
+
+static int tlclk_major = TLCLK_MAJOR;
+
+static irqreturn_t tlclk_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+static DECLARE_WAIT_QUEUE_HEAD(wq);
+
+static int tlclk_open(struct inode *inode, struct file *filp)
+{
+ int result;
+
+ /* Make sure there is no interrupt pending while
+ * initialising interrupt handler */
+ inb(TLCLK_REG6);
+
+ /* This device is wired through the FPGA IO space of the ATCA blade
+ * we can't share this IRQ */
+ result = request_irq(telclk_interrupt, &tlclk_interrupt,
+ SA_INTERRUPT, "telco_clock", tlclk_interrupt);
+ if (result == -EBUSY) {
+ printk(KERN_ERR "telco_clock: Interrupt can't be reserved!\n");
+ return -EBUSY;
+ }
+ inb(TLCLK_REG6); /* Clear interrupt events */
+
+ return 0;
+}
+
+static int tlclk_release(struct inode *inode, struct file *filp)
+{
+ free_irq(telclk_interrupt, tlclk_interrupt);
+
+ return 0;
+}
+
+ssize_t tlclk_read(struct file *filp, char __user *buf, size_t count,
+ loff_t *f_pos)
+{
+ if (count < sizeof(struct tlclk_alarms))
+ return -EIO;
+
+ wait_event_interruptible(wq, got_event);
+ if (copy_to_user(buf, alarm_events, sizeof(struct tlclk_alarms)))
+ return -EFAULT;
+
+ memset(alarm_events, 0, sizeof(struct tlclk_alarms));
+ got_event = 0;
+
+ return sizeof(struct tlclk_alarms);
+}
+
+ssize_t tlclk_write(struct file *filp, const char __user *buf, size_t count,
+ loff_t *f_pos)
+{
+ return 0;
+}
+
+static struct file_operations tlclk_fops = {
+ .read = tlclk_read,
+ .write = tlclk_write,
+ .open = tlclk_open,
+ .release = tlclk_release,
+
+};
+
+static struct miscdevice tlclk_miscdev = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "telco_clock",
+ .fops = &tlclk_fops,
+};
+
+static ssize_t show_current_ref(struct device *d,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long ret_val;
+ unsigned long flags;
+
+ spin_lock_irqsave(&event_lock, flags);
+ ret_val = ((inb(TLCLK_REG1) & 0x08) >> 3);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return sprintf(buf, "0x%lX\n", ret_val);
+}
+
+static DEVICE_ATTR(current_ref, S_IRUGO, show_current_ref, NULL);
+
+
+static ssize_t show_interrupt_switch(struct device *d,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long ret_val;
+ unsigned long flags;
+
+ spin_lock_irqsave(&event_lock, flags);
+ ret_val = inb(TLCLK_REG6);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return sprintf(buf, "0x%lX\n", ret_val);
+}
+
+static DEVICE_ATTR(interrupt_switch, S_IRUGO,
+ show_interrupt_switch, NULL);
+
+static ssize_t show_alarms(struct device *d,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long ret_val;
+ unsigned long flags;
+
+ spin_lock_irqsave(&event_lock, flags);
+ ret_val = (inb(TLCLK_REG2) & 0xf0);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return sprintf(buf, "0x%lX\n", ret_val);
+}
+
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+
+static ssize_t store_enable_clk3b_output(struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long tmp;
+ unsigned char val;
+ unsigned long flags;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, ": tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ SET_PORT_BITS(TLCLK_REG3, 0x7f, val << 7);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(enable_clk3b_output, S_IWUGO, NULL,
+ store_enable_clk3b_output);
+
+static ssize_t store_enable_clk3a_output(struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long flags;
+ unsigned long tmp;
+ unsigned char val;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ SET_PORT_BITS(TLCLK_REG3, 0xbf, val << 6);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(enable_clk3a_output, S_IWUGO, NULL,
+ store_enable_clk3a_output);
+
+static ssize_t store_enable_clkb1_output(struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long flags;
+ unsigned long tmp;
+ unsigned char val;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ SET_PORT_BITS(TLCLK_REG2, 0xf7, val << 3);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(enable_clkb1_output, S_IWUGO, NULL,
+ store_enable_clkb1_output);
+
+
+static ssize_t store_enable_clka1_output(struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long flags;
+ unsigned long tmp;
+ unsigned char val;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ SET_PORT_BITS(TLCLK_REG2, 0xfb, val << 2);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(enable_clka1_output, S_IWUGO, NULL,
+ store_enable_clka1_output);
+
+static ssize_t store_enable_clkb0_output(struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long flags;
+ unsigned long tmp;
+ unsigned char val;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ SET_PORT_BITS(TLCLK_REG2, 0xfd, val << 1);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(enable_clkb0_output, S_IWUGO, NULL,
+ store_enable_clkb0_output);
+
+static ssize_t store_enable_clka0_output(struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long flags;
+ unsigned long tmp;
+ unsigned char val;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ SET_PORT_BITS(TLCLK_REG2, 0xfe, val);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(enable_clka0_output, S_IWUGO, NULL,
+ store_enable_clka0_output);
+
+static ssize_t store_test_mode(struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long flags;
+ unsigned long tmp;
+ unsigned char val;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ SET_PORT_BITS(TLCLK_REG4, 0xfd, 2);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(test_mode, S_IWUGO, NULL, store_test_mode);
+
+static ssize_t store_select_amcb2_transmit_clock(struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long flags;
+ unsigned long tmp;
+ unsigned char val;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ if ((val == CLK_8kHz) || (val == CLK_16_384MHz)) {
+ SET_PORT_BITS(TLCLK_REG3, 0xc7, 0x28);
+ SET_PORT_BITS(TLCLK_REG1, 0xfb, ~val);
+ } else if (val >= CLK_8_592MHz) {
+ SET_PORT_BITS(TLCLK_REG3, 0xc7, 0x38);
+ switch (val) {
+ case CLK_8_592MHz:
+ SET_PORT_BITS(TLCLK_REG0, 0xfc, 1);
+ break;
+ case CLK_11_184MHz:
+ SET_PORT_BITS(TLCLK_REG0, 0xfc, 0);
+ break;
+ case CLK_34_368MHz:
+ SET_PORT_BITS(TLCLK_REG0, 0xfc, 3);
+ break;
+ case CLK_44_736MHz:
+ SET_PORT_BITS(TLCLK_REG0, 0xfc, 2);
+ break;
+ }
+ } else
+ SET_PORT_BITS(TLCLK_REG3, 0xc7, val << 3);
+
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(select_amcb2_transmit_clock, S_IWUGO, NULL,
+ store_select_amcb2_transmit_clock);
+
+static ssize_t store_select_amcb1_transmit_clock(struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long tmp;
+ unsigned char val;
+ unsigned long flags;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ if ((val == CLK_8kHz) || (val == CLK_16_384MHz)) {
+ SET_PORT_BITS(TLCLK_REG3, 0xf8, 0x5);
+ SET_PORT_BITS(TLCLK_REG1, 0xfb, ~val);
+ } else if (val >= CLK_8_592MHz) {
+ SET_PORT_BITS(TLCLK_REG3, 0xf8, 0x7);
+ switch (val) {
+ case CLK_8_592MHz:
+ SET_PORT_BITS(TLCLK_REG0, 0xfc, 1);
+ break;
+ case CLK_11_184MHz:
+ SET_PORT_BITS(TLCLK_REG0, 0xfc, 0);
+ break;
+ case CLK_34_368MHz:
+ SET_PORT_BITS(TLCLK_REG0, 0xfc, 3);
+ break;
+ case CLK_44_736MHz:
+ SET_PORT_BITS(TLCLK_REG0, 0xfc, 2);
+ break;
+ }
+ } else
+ SET_PORT_BITS(TLCLK_REG3, 0xf8, val);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(select_amcb1_transmit_clock, S_IWUGO, NULL,
+ store_select_amcb1_transmit_clock);
+
+static ssize_t store_select_redundant_clock(struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long tmp;
+ unsigned char val;
+ unsigned long flags;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ SET_PORT_BITS(TLCLK_REG1, 0xfe, val);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(select_redundant_clock, S_IWUGO, NULL,
+ store_select_redundant_clock);
+
+static ssize_t store_select_ref_frequency(struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long tmp;
+ unsigned char val;
+ unsigned long flags;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ SET_PORT_BITS(TLCLK_REG1, 0xfd, val);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(select_ref_frequency, S_IWUGO, NULL,
+ store_select_ref_frequency);
+
+static ssize_t store_filter_select(struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long tmp;
+ unsigned char val;
+ unsigned long flags;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ SET_PORT_BITS(TLCLK_REG0, 0xfb, val);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(filter_select, S_IWUGO, NULL, store_filter_select);
+
+static ssize_t store_hardware_switching_mode(struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long tmp;
+ unsigned char val;
+ unsigned long flags;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ SET_PORT_BITS(TLCLK_REG0, 0xbf, val);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(hardware_switching_mode, S_IWUGO, NULL,
+ store_hardware_switching_mode);
+
+static ssize_t store_hardware_switching(struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long tmp;
+ unsigned char val;
+ unsigned long flags;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ SET_PORT_BITS(TLCLK_REG0, 0x7f, val);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(hardware_switching, S_IWUGO, NULL,
+ store_hardware_switching);
+
+static ssize_t store_refalign (struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long tmp;
+ unsigned long flags;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+ spin_lock_irqsave(&event_lock, flags);
+ SET_PORT_BITS(TLCLK_REG0, 0xf7, 0);
+ udelay(2);
+ SET_PORT_BITS(TLCLK_REG0, 0xf7, 0x08);
+ udelay(2);
+ SET_PORT_BITS(TLCLK_REG0, 0xf7, 0);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(refalign, S_IWUGO, NULL, store_refalign);
+
+static ssize_t store_mode_select (struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long tmp;
+ unsigned char val;
+ unsigned long flags;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ SET_PORT_BITS(TLCLK_REG0, 0xcf, val);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(mode_select, S_IWUGO, NULL, store_mode_select);
+
+static ssize_t store_reset (struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long tmp;
+ unsigned char val;
+ unsigned long flags;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ SET_PORT_BITS(TLCLK_REG4, 0xfd, val);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(reset, S_IWUGO, NULL, store_reset);
+
+static struct attribute *tlclk_sysfs_entries[] = {
+ &dev_attr_current_ref.attr,
+ &dev_attr_interrupt_switch.attr,
+ &dev_attr_alarms.attr,
+ &dev_attr_enable_clk3a_output.attr,
+ &dev_attr_enable_clk3b_output.attr,
+ &dev_attr_enable_clkb1_output.attr,
+ &dev_attr_enable_clka1_output.attr,
+ &dev_attr_enable_clkb0_output.attr,
+ &dev_attr_enable_clka0_output.attr,
+ &dev_attr_test_mode.attr,
+ &dev_attr_select_amcb1_transmit_clock.attr,
+ &dev_attr_select_amcb2_transmit_clock.attr,
+ &dev_attr_select_redundant_clock.attr,
+ &dev_attr_select_ref_frequency.attr,
+ &dev_attr_filter_select.attr,
+ &dev_attr_hardware_switching_mode.attr,
+ &dev_attr_hardware_switching.attr,
+ &dev_attr_refalign.attr,
+ &dev_attr_mode_select.attr,
+ &dev_attr_reset.attr,
+ NULL
+};
+
+static struct attribute_group tlclk_attribute_group = {
+ .name = NULL, /* put in device directory */
+ .attrs = tlclk_sysfs_entries,
+};
+
+static struct platform_device *tlclk_device;
+
+static int __init tlclk_init(void)
+{
+ int ret;
+
+ ret = register_chrdev(tlclk_major, "telco_clock", &tlclk_fops);
+ if (ret < 0) {
+ printk(KERN_ERR "telco_clock: can't get major! %d\n", tlclk_major);
+ return ret;
+ }
+ alarm_events = kzalloc( sizeof(struct tlclk_alarms), GFP_KERNEL);
+ if (!alarm_events)
+ goto out1;
+
+ /* Read telecom clock IRQ number (Set by BIOS) */
+ if (!request_region(TLCLK_BASE, 8, "telco_clock")) {
+ printk(KERN_ERR "tlclk: request_region failed! 0x%X\n",
+ TLCLK_BASE);
+ ret = -EBUSY;
+ goto out2;
+ }
+ telclk_interrupt = (inb(TLCLK_REG7) & 0x0f);
+
+ if (0x0F == telclk_interrupt ) { /* not MCPBL0010 ? */
+ printk(KERN_ERR "telclk_interrup = 0x%x non-mcpbl0010 hw\n",
+ telclk_interrupt);
+ ret = -ENXIO;
+ goto out3;
+ }
+
+ init_timer(&switchover_timer);
+
+ ret = misc_register(&tlclk_miscdev);
+ if (ret < 0) {
+ printk(KERN_ERR " misc_register retruns %d\n", ret);
+ ret = -EBUSY;
+ goto out3;
+ }
+
+ tlclk_device = platform_device_register_simple("telco_clock",
+ -1, NULL, 0);
+ if (!tlclk_device) {
+ printk(KERN_ERR " platform_device_register retruns 0x%X\n",
+ (unsigned int) tlclk_device);
+ ret = -EBUSY;
+ goto out4;
+ }
+
+ ret = sysfs_create_group(&tlclk_device->dev.kobj,
+ &tlclk_attribute_group);
+ if (ret) {
+ printk(KERN_ERR "failed to create sysfs device attributes\n");
+ sysfs_remove_group(&tlclk_device->dev.kobj,
+ &tlclk_attribute_group);
+ goto out5;
+ }
+
+ return 0;
+out5:
+ platform_device_unregister(tlclk_device);
+out4:
+ misc_deregister(&tlclk_miscdev);
+out3:
+ release_region(TLCLK_BASE, 8);
+out2:
+ kfree(alarm_events);
+out1:
+ unregister_chrdev(tlclk_major, "telco_clock");
+ return ret;
+}
+
+static void __exit tlclk_cleanup(void)
+{
+ sysfs_remove_group(&tlclk_device->dev.kobj, &tlclk_attribute_group);
+ platform_device_unregister(tlclk_device);
+ misc_deregister(&tlclk_miscdev);
+ unregister_chrdev(tlclk_major, "telco_clock");
+
+ release_region(TLCLK_BASE, 8);
+ del_timer_sync(&switchover_timer);
+ kfree(alarm_events);
+
+}
+
+static void switchover_timeout(unsigned long data)
+{
+ if ((data & 1)) {
+ if ((inb(TLCLK_REG1) & 0x08) != (data & 0x08))
+ alarm_events->switchover_primary++;
+ } else {
+ if ((inb(TLCLK_REG1) & 0x08) != (data & 0x08))
+ alarm_events->switchover_secondary++;
+ }
+
+ /* Alarm processing is done, wake up read task */
+ del_timer(&switchover_timer);
+ got_event = 1;
+ wake_up(&wq);
+}
+
+static irqreturn_t tlclk_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&event_lock, flags);
+ /* Read and clear interrupt events */
+ int_events = inb(TLCLK_REG6);
+
+ /* Primary_Los changed from 0 to 1 ? */
+ if (int_events & PRI_LOS_01_MASK) {
+ if (inb(TLCLK_REG2) & SEC_LOST_MASK)
+ alarm_events->lost_clocks++;
+ else
+ alarm_events->lost_primary_clock++;
+ }
+
+ /* Primary_Los changed from 1 to 0 ? */
+ if (int_events & PRI_LOS_10_MASK) {
+ alarm_events->primary_clock_back++;
+ SET_PORT_BITS(TLCLK_REG1, 0xFE, 1);
+ }
+ /* Secondary_Los changed from 0 to 1 ? */
+ if (int_events & SEC_LOS_01_MASK) {
+ if (inb(TLCLK_REG2) & PRI_LOST_MASK)
+ alarm_events->lost_clocks++;
+ else
+ alarm_events->lost_secondary_clock++;
+ }
+ /* Secondary_Los changed from 1 to 0 ? */
+ if (int_events & SEC_LOS_10_MASK) {
+ alarm_events->secondary_clock_back++;
+ SET_PORT_BITS(TLCLK_REG1, 0xFE, 0);
+ }
+ if (int_events & HOLDOVER_10_MASK)
+ alarm_events->pll_end_holdover++;
+
+ if (int_events & UNLOCK_01_MASK)
+ alarm_events->pll_lost_sync++;
+
+ if (int_events & UNLOCK_10_MASK)
+ alarm_events->pll_sync++;
+
+ /* Holdover changed from 0 to 1 ? */
+ if (int_events & HOLDOVER_01_MASK) {
+ alarm_events->pll_holdover++;
+
+ /* TIMEOUT in ~10ms */
+ switchover_timer.expires = jiffies + msecs_to_jiffies(10);
+ switchover_timer.data = inb(TLCLK_REG1);
+ add_timer(&switchover_timer);
+ } else {
+ got_event = 1;
+ wake_up(&wq);
+ }
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return IRQ_HANDLED;
+}
+
+module_init(tlclk_init);
+module_exit(tlclk_cleanup);
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 049d128ae7f0..303f15880466 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -64,7 +64,7 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
if (count == 0)
return -ENODATA;
if (count > bufsiz) {
- dev_err(&chip->pci_dev->dev,
+ dev_err(chip->dev,
"invalid count value %x %zx \n", count, bufsiz);
return -E2BIG;
}
@@ -72,21 +72,21 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
down(&chip->tpm_mutex);
if ((rc = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
- dev_err(&chip->pci_dev->dev,
+ dev_err(chip->dev,
"tpm_transmit: tpm_send: error %zd\n", rc);
goto out;
}
stop = jiffies + 2 * 60 * HZ;
do {
- u8 status = inb(chip->vendor->base + 1);
+ u8 status = chip->vendor->status(chip);
if ((status & chip->vendor->req_complete_mask) ==
chip->vendor->req_complete_val) {
goto out_recv;
}
if ((status == chip->vendor->req_canceled)) {
- dev_err(&chip->pci_dev->dev, "Operation Canceled\n");
+ dev_err(chip->dev, "Operation Canceled\n");
rc = -ECANCELED;
goto out;
}
@@ -97,14 +97,14 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
chip->vendor->cancel(chip);
- dev_err(&chip->pci_dev->dev, "Operation Timed out\n");
+ dev_err(chip->dev, "Operation Timed out\n");
rc = -ETIME;
goto out;
out_recv:
rc = chip->vendor->recv(chip, (u8 *) buf, bufsiz);
if (rc < 0)
- dev_err(&chip->pci_dev->dev,
+ dev_err(chip->dev,
"tpm_transmit: tpm_recv: error %zd\n", rc);
out:
up(&chip->tpm_mutex);
@@ -139,15 +139,14 @@ ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
__be32 index;
char *str = buf;
- struct tpm_chip *chip =
- pci_get_drvdata(to_pci_dev(dev));
+ struct tpm_chip *chip = dev_get_drvdata(dev);
if (chip == NULL)
return -ENODEV;
memcpy(data, cap_pcr, sizeof(cap_pcr));
if ((len = tpm_transmit(chip, data, sizeof(data)))
< CAP_PCR_RESULT_SIZE) {
- dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred "
+ dev_dbg(chip->dev, "A TPM error (%d) occurred "
"attempting to determine the number of PCRS\n",
be32_to_cpu(*((__be32 *) (data + 6))));
return 0;
@@ -161,9 +160,10 @@ ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
memcpy(data + 10, &index, 4);
if ((len = tpm_transmit(chip, data, sizeof(data)))
< READ_PCR_RESULT_SIZE){
- dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred"
+ dev_dbg(chip->dev, "A TPM error (%d) occurred"
" attempting to read PCR %d of %d\n",
- be32_to_cpu(*((__be32 *) (data + 6))), i, num_pcrs);
+ be32_to_cpu(*((__be32 *) (data + 6))),
+ i, num_pcrs);
goto out;
}
str += sprintf(str, "PCR-%02d: ", i);
@@ -191,21 +191,19 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
int i, rc;
char *str = buf;
- struct tpm_chip *chip =
- pci_get_drvdata(to_pci_dev(dev));
+ struct tpm_chip *chip = dev_get_drvdata(dev);
if (chip == NULL)
return -ENODEV;
- data = kmalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL);
+ data = kzalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL);
if (!data)
return -ENOMEM;
memcpy(data, readpubek, sizeof(readpubek));
- memset(data + sizeof(readpubek), 0, 20); /* zero nonce */
if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) <
READ_PUBEK_RESULT_SIZE) {
- dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred "
+ dev_dbg(chip->dev, "A TPM error (%d) occurred "
"attempting to read the PUBEK\n",
be32_to_cpu(*((__be32 *) (data + 6))));
rc = 0;
@@ -245,7 +243,6 @@ out:
kfree(data);
return rc;
}
-
EXPORT_SYMBOL_GPL(tpm_show_pubek);
#define CAP_VER_RESULT_SIZE 18
@@ -274,8 +271,7 @@ ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
ssize_t len;
char *str = buf;
- struct tpm_chip *chip =
- pci_get_drvdata(to_pci_dev(dev));
+ struct tpm_chip *chip = dev_get_drvdata(dev);
if (chip == NULL)
return -ENODEV;
@@ -315,7 +311,6 @@ ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
}
EXPORT_SYMBOL_GPL(tpm_store_cancel);
-
/*
* Device file system interface to the TPM
*/
@@ -339,21 +334,20 @@ int tpm_open(struct inode *inode, struct file *file)
}
if (chip->num_opens) {
- dev_dbg(&chip->pci_dev->dev,
- "Another process owns this TPM\n");
+ dev_dbg(chip->dev, "Another process owns this TPM\n");
rc = -EBUSY;
goto err_out;
}
chip->num_opens++;
- pci_dev_get(chip->pci_dev);
+ get_device(chip->dev);
spin_unlock(&driver_lock);
chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
if (chip->data_buffer == NULL) {
chip->num_opens--;
- pci_dev_put(chip->pci_dev);
+ put_device(chip->dev);
return -ENOMEM;
}
@@ -366,7 +360,6 @@ err_out:
spin_unlock(&driver_lock);
return rc;
}
-
EXPORT_SYMBOL_GPL(tpm_open);
int tpm_release(struct inode *inode, struct file *file)
@@ -378,15 +371,14 @@ int tpm_release(struct inode *inode, struct file *file)
chip->num_opens--;
del_singleshot_timer_sync(&chip->user_read_timer);
atomic_set(&chip->data_pending, 0);
- pci_dev_put(chip->pci_dev);
+ put_device(chip->dev);
kfree(chip->data_buffer);
spin_unlock(&driver_lock);
return 0;
}
-
EXPORT_SYMBOL_GPL(tpm_release);
-ssize_t tpm_write(struct file * file, const char __user * buf,
+ssize_t tpm_write(struct file *file, const char __user *buf,
size_t size, loff_t * off)
{
struct tpm_chip *chip = file->private_data;
@@ -422,7 +414,7 @@ ssize_t tpm_write(struct file * file, const char __user * buf,
EXPORT_SYMBOL_GPL(tpm_write);
-ssize_t tpm_read(struct file * file, char __user * buf,
+ssize_t tpm_read(struct file * file, char __user *buf,
size_t size, loff_t * off)
{
struct tpm_chip *chip = file->private_data;
@@ -444,15 +436,14 @@ ssize_t tpm_read(struct file * file, char __user * buf,
return ret_size;
}
-
EXPORT_SYMBOL_GPL(tpm_read);
-void __devexit tpm_remove(struct pci_dev *pci_dev)
+void tpm_remove_hardware(struct device *dev)
{
- struct tpm_chip *chip = pci_get_drvdata(pci_dev);
+ struct tpm_chip *chip = dev_get_drvdata(dev);
if (chip == NULL) {
- dev_err(&pci_dev->dev, "No device data found\n");
+ dev_err(dev, "No device data found\n");
return;
}
@@ -462,22 +453,20 @@ void __devexit tpm_remove(struct pci_dev *pci_dev)
spin_unlock(&driver_lock);
- pci_set_drvdata(pci_dev, NULL);
+ dev_set_drvdata(dev, NULL);
misc_deregister(&chip->vendor->miscdev);
kfree(chip->vendor->miscdev.name);
- sysfs_remove_group(&pci_dev->dev.kobj, chip->vendor->attr_group);
+ sysfs_remove_group(&dev->kobj, chip->vendor->attr_group);
- pci_disable_device(pci_dev);
-
- dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &= !(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
+ dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &=
+ !(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
kfree(chip);
- pci_dev_put(pci_dev);
+ put_device(dev);
}
-
-EXPORT_SYMBOL_GPL(tpm_remove);
+EXPORT_SYMBOL_GPL(tpm_remove_hardware);
static u8 savestate[] = {
0, 193, /* TPM_TAG_RQU_COMMAND */
@@ -489,32 +478,30 @@ static u8 savestate[] = {
* We are about to suspend. Save the TPM state
* so that it can be restored.
*/
-int tpm_pm_suspend(struct pci_dev *pci_dev, pm_message_t pm_state)
+int tpm_pm_suspend(struct device *dev, pm_message_t pm_state)
{
- struct tpm_chip *chip = pci_get_drvdata(pci_dev);
+ struct tpm_chip *chip = dev_get_drvdata(dev);
if (chip == NULL)
return -ENODEV;
tpm_transmit(chip, savestate, sizeof(savestate));
return 0;
}
-
EXPORT_SYMBOL_GPL(tpm_pm_suspend);
/*
* Resume from a power safe. The BIOS already restored
* the TPM state.
*/
-int tpm_pm_resume(struct pci_dev *pci_dev)
+int tpm_pm_resume(struct device *dev)
{
- struct tpm_chip *chip = pci_get_drvdata(pci_dev);
+ struct tpm_chip *chip = dev_get_drvdata(dev);
if (chip == NULL)
return -ENODEV;
return 0;
}
-
EXPORT_SYMBOL_GPL(tpm_pm_resume);
/*
@@ -524,8 +511,7 @@ EXPORT_SYMBOL_GPL(tpm_pm_resume);
* upon errant exit from this function specific probe function should call
* pci_disable_device
*/
-int tpm_register_hardware(struct pci_dev *pci_dev,
- struct tpm_vendor_specific *entry)
+int tpm_register_hardware(struct device *dev, struct tpm_vendor_specific *entry)
{
#define DEVNAME_SIZE 7
@@ -534,12 +520,10 @@ int tpm_register_hardware(struct pci_dev *pci_dev,
int i, j;
/* Driver specific per-device data */
- chip = kmalloc(sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL)
return -ENOMEM;
- memset(chip, 0, sizeof(struct tpm_chip));
-
init_MUTEX(&chip->buffer_mutex);
init_MUTEX(&chip->tpm_mutex);
INIT_LIST_HEAD(&chip->list);
@@ -563,8 +547,7 @@ int tpm_register_hardware(struct pci_dev *pci_dev,
dev_num_search_complete:
if (chip->dev_num < 0) {
- dev_err(&pci_dev->dev,
- "No available tpm device numbers\n");
+ dev_err(dev, "No available tpm device numbers\n");
kfree(chip);
return -ENODEV;
} else if (chip->dev_num == 0)
@@ -576,15 +559,15 @@ dev_num_search_complete:
scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num);
chip->vendor->miscdev.name = devname;
- chip->vendor->miscdev.dev = &(pci_dev->dev);
- chip->pci_dev = pci_dev_get(pci_dev);
+ chip->vendor->miscdev.dev = dev;
+ chip->dev = get_device(dev);
if (misc_register(&chip->vendor->miscdev)) {
- dev_err(&chip->pci_dev->dev,
+ dev_err(chip->dev,
"unable to misc_register %s, minor %d\n",
chip->vendor->miscdev.name,
chip->vendor->miscdev.minor);
- pci_dev_put(pci_dev);
+ put_device(dev);
kfree(chip);
dev_mask[i] &= !(1 << j);
return -ENODEV;
@@ -592,17 +575,16 @@ dev_num_search_complete:
spin_lock(&driver_lock);
- pci_set_drvdata(pci_dev, chip);
+ dev_set_drvdata(dev, chip);
list_add(&chip->list, &tpm_chip_list);
spin_unlock(&driver_lock);
- sysfs_create_group(&pci_dev->dev.kobj, chip->vendor->attr_group);
+ sysfs_create_group(&dev->kobj, chip->vendor->attr_group);
return 0;
}
-
EXPORT_SYMBOL_GPL(tpm_register_hardware);
MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 373b41f6b460..024814b50c3c 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -55,12 +55,13 @@ struct tpm_vendor_specific {
int (*recv) (struct tpm_chip *, u8 *, size_t);
int (*send) (struct tpm_chip *, u8 *, size_t);
void (*cancel) (struct tpm_chip *);
+ u8 (*status) (struct tpm_chip *);
struct miscdevice miscdev;
struct attribute_group *attr_group;
};
struct tpm_chip {
- struct pci_dev *pci_dev; /* PCI device stuff */
+ struct device *dev; /* Device stuff */
int dev_num; /* /dev/tpm# */
int num_opens; /* only one allowed */
@@ -91,13 +92,13 @@ static inline void tpm_write_index(int base, int index, int value)
outb(value & 0xFF, base+1);
}
-extern int tpm_register_hardware(struct pci_dev *,
+extern int tpm_register_hardware(struct device *,
struct tpm_vendor_specific *);
extern int tpm_open(struct inode *, struct file *);
extern int tpm_release(struct inode *, struct file *);
extern ssize_t tpm_write(struct file *, const char __user *, size_t,
loff_t *);
extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *);
-extern void __devexit tpm_remove(struct pci_dev *);
-extern int tpm_pm_suspend(struct pci_dev *, pm_message_t);
-extern int tpm_pm_resume(struct pci_dev *);
+extern void tpm_remove_hardware(struct device *);
+extern int tpm_pm_suspend(struct device *, pm_message_t);
+extern int tpm_pm_resume(struct device *);
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c
index c0d64914595f..8cb42e84723c 100644
--- a/drivers/char/tpm/tpm_atmel.c
+++ b/drivers/char/tpm/tpm_atmel.c
@@ -40,7 +40,7 @@ enum tpm_atmel_read_status {
ATML_STATUS_READY = 0x08
};
-static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count)
+static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count)
{
u8 status, *hdr = buf;
u32 size;
@@ -54,7 +54,7 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count)
for (i = 0; i < 6; i++) {
status = inb(chip->vendor->base + 1);
if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
- dev_err(&chip->pci_dev->dev,
+ dev_err(chip->dev,
"error reading header\n");
return -EIO;
}
@@ -66,12 +66,12 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count)
size = be32_to_cpu(*native_size);
if (count < size) {
- dev_err(&chip->pci_dev->dev,
+ dev_err(chip->dev,
"Recv size(%d) less than available space\n", size);
for (; i < size; i++) { /* clear the waiting data anyway */
status = inb(chip->vendor->base + 1);
if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
- dev_err(&chip->pci_dev->dev,
+ dev_err(chip->dev,
"error reading data\n");
return -EIO;
}
@@ -83,7 +83,7 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count)
for (; i < size; i++) {
status = inb(chip->vendor->base + 1);
if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
- dev_err(&chip->pci_dev->dev,
+ dev_err(chip->dev,
"error reading data\n");
return -EIO;
}
@@ -93,20 +93,20 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count)
/* make sure data available is gone */
status = inb(chip->vendor->base + 1);
if (status & ATML_STATUS_DATA_AVAIL) {
- dev_err(&chip->pci_dev->dev, "data available is stuck\n");
+ dev_err(chip->dev, "data available is stuck\n");
return -EIO;
}
return size;
}
-static int tpm_atml_send(struct tpm_chip *chip, u8 * buf, size_t count)
+static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t count)
{
int i;
- dev_dbg(&chip->pci_dev->dev, "tpm_atml_send: ");
+ dev_dbg(chip->dev, "tpm_atml_send:\n");
for (i = 0; i < count; i++) {
- dev_dbg(&chip->pci_dev->dev, "0x%x(%d) ", buf[i], buf[i]);
+ dev_dbg(chip->dev, "%d 0x%x(%d)\n", i, buf[i], buf[i]);
outb(buf[i], chip->vendor->base);
}
@@ -118,6 +118,11 @@ static void tpm_atml_cancel(struct tpm_chip *chip)
outb(ATML_STATUS_ABORT, chip->vendor->base + 1);
}
+static u8 tpm_atml_status(struct tpm_chip *chip)
+{
+ return inb(chip->vendor->base + 1);
+}
+
static struct file_operations atmel_ops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
@@ -137,7 +142,7 @@ static struct attribute* atmel_attrs[] = {
&dev_attr_pcrs.attr,
&dev_attr_caps.attr,
&dev_attr_cancel.attr,
- 0,
+ NULL,
};
static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs };
@@ -146,6 +151,7 @@ static struct tpm_vendor_specific tpm_atmel = {
.recv = tpm_atml_recv,
.send = tpm_atml_send,
.cancel = tpm_atml_cancel,
+ .status = tpm_atml_status,
.req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL,
.req_complete_val = ATML_STATUS_DATA_AVAIL,
.req_canceled = ATML_STATUS_READY,
@@ -153,86 +159,94 @@ static struct tpm_vendor_specific tpm_atmel = {
.miscdev = { .fops = &atmel_ops, },
};
-static int __devinit tpm_atml_init(struct pci_dev *pci_dev,
- const struct pci_device_id *pci_id)
+static struct platform_device *pdev;
+
+static void __devexit tpm_atml_remove(struct device *dev)
+{
+ struct tpm_chip *chip = dev_get_drvdata(dev);
+ if (chip) {
+ release_region(chip->vendor->base, 2);
+ tpm_remove_hardware(chip->dev);
+ }
+}
+
+static struct device_driver atml_drv = {
+ .name = "tpm_atmel",
+ .bus = &platform_bus_type,
+ .owner = THIS_MODULE,
+ .suspend = tpm_pm_suspend,
+ .resume = tpm_pm_resume,
+};
+
+static int __init init_atmel(void)
{
- u8 version[4];
int rc = 0;
int lo, hi;
- if (pci_enable_device(pci_dev))
- return -EIO;
+ driver_register(&atml_drv);
lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
tpm_atmel.base = (hi<<8)|lo;
- dev_dbg( &pci_dev->dev, "Operating with base: 0x%x\n", tpm_atmel.base);
/* verify that it is an Atmel part */
if (tpm_read_index(TPM_ADDR, 4) != 'A' || tpm_read_index(TPM_ADDR, 5) != 'T'
|| tpm_read_index(TPM_ADDR, 6) != 'M' || tpm_read_index(TPM_ADDR, 7) != 'L') {
- rc = -ENODEV;
- goto out_err;
+ return -ENODEV;
}
- /* query chip for its version number */
- if ((version[0] = tpm_read_index(TPM_ADDR, 0x00)) != 0xFF) {
- version[1] = tpm_read_index(TPM_ADDR, 0x01);
- version[2] = tpm_read_index(TPM_ADDR, 0x02);
- version[3] = tpm_read_index(TPM_ADDR, 0x03);
- } else {
- dev_info(&pci_dev->dev, "version query failed\n");
- rc = -ENODEV;
- goto out_err;
+ /* verify chip version number is 1.1 */
+ if ( (tpm_read_index(TPM_ADDR, 0x00) != 0x01) ||
+ (tpm_read_index(TPM_ADDR, 0x01) != 0x01 ))
+ return -ENODEV;
+
+ pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
+ if ( !pdev )
+ return -ENOMEM;
+
+ pdev->name = "tpm_atmel0";
+ pdev->id = -1;
+ pdev->num_resources = 0;
+ pdev->dev.release = tpm_atml_remove;
+ pdev->dev.driver = &atml_drv;
+
+ if ((rc = platform_device_register(pdev)) < 0) {
+ kfree(pdev);
+ pdev = NULL;
+ return rc;
}
- if ((rc = tpm_register_hardware(pci_dev, &tpm_atmel)) < 0)
- goto out_err;
+ if (request_region(tpm_atmel.base, 2, "tpm_atmel0") == NULL ) {
+ platform_device_unregister(pdev);
+ kfree(pdev);
+ pdev = NULL;
+ return -EBUSY;
+ }
- dev_info(&pci_dev->dev,
- "Atmel TPM version %d.%d.%d.%d\n", version[0], version[1],
- version[2], version[3]);
+ if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0) {
+ release_region(tpm_atmel.base, 2);
+ platform_device_unregister(pdev);
+ kfree(pdev);
+ pdev = NULL;
+ return rc;
+ }
+ dev_info(&pdev->dev, "Atmel TPM 1.1, Base Address: 0x%x\n",
+ tpm_atmel.base);
return 0;
-out_err:
- pci_disable_device(pci_dev);
- return rc;
-}
-
-static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0)},
- {PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)},
- {PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6LPC)},
- {0,}
-};
-
-MODULE_DEVICE_TABLE(pci, tpm_pci_tbl);
-
-static struct pci_driver atmel_pci_driver = {
- .name = "tpm_atmel",
- .id_table = tpm_pci_tbl,
- .probe = tpm_atml_init,
- .remove = __devexit_p(tpm_remove),
- .suspend = tpm_pm_suspend,
- .resume = tpm_pm_resume,
-};
-
-static int __init init_atmel(void)
-{
- return pci_register_driver(&atmel_pci_driver);
}
static void __exit cleanup_atmel(void)
{
- pci_unregister_driver(&atmel_pci_driver);
+ if (pdev) {
+ tpm_atml_remove(&pdev->dev);
+ platform_device_unregister(pdev);
+ kfree(pdev);
+ pdev = NULL;
+ }
+
+ driver_unregister(&atml_drv);
}
module_init(init_atmel);
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c
index 939e51e119e6..8198dbb7370f 100644
--- a/drivers/char/tpm/tpm_infineon.c
+++ b/drivers/char/tpm/tpm_infineon.c
@@ -5,6 +5,7 @@
* Specifications at www.trustedcomputinggroup.org
*
* Copyright (C) 2005, Marcel Selhorst <selhorst@crypto.rub.de>
+ * Sirrix AG - security technologies, http://www.sirrix.com and
* Applied Data Security Group, Ruhr-University Bochum, Germany
* Project-Homepage: http://www.prosec.rub.de/tpm
*
@@ -29,9 +30,10 @@
#define TPM_INFINEON_DEV_VEN_VALUE 0x15D1
/* These values will be filled after PnP-call */
-static int TPM_INF_DATA = 0;
-static int TPM_INF_ADDR = 0;
-static int pnp_registered = 0;
+static int TPM_INF_DATA;
+static int TPM_INF_ADDR;
+static int TPM_INF_BASE;
+static int TPM_INF_PORT_LEN;
/* TPM header definitions */
enum infineon_tpm_header {
@@ -143,11 +145,9 @@ static int wait(struct tpm_chip *chip, int wait_for_bit)
}
if (i == TPM_MAX_TRIES) { /* timeout occurs */
if (wait_for_bit == STAT_XFE)
- dev_err(&chip->pci_dev->dev,
- "Timeout in wait(STAT_XFE)\n");
+ dev_err(chip->dev, "Timeout in wait(STAT_XFE)\n");
if (wait_for_bit == STAT_RDA)
- dev_err(&chip->pci_dev->dev,
- "Timeout in wait(STAT_RDA)\n");
+ dev_err(chip->dev, "Timeout in wait(STAT_RDA)\n");
return -EIO;
}
return 0;
@@ -170,7 +170,7 @@ static void wait_and_send(struct tpm_chip *chip, u8 sendbyte)
static void tpm_wtx(struct tpm_chip *chip)
{
number_of_wtx++;
- dev_info(&chip->pci_dev->dev, "Granting WTX (%02d / %02d)\n",
+ dev_info(chip->dev, "Granting WTX (%02d / %02d)\n",
number_of_wtx, TPM_MAX_WTX_PACKAGES);
wait_and_send(chip, TPM_VL_VER);
wait_and_send(chip, TPM_CTRL_WTX);
@@ -181,7 +181,7 @@ static void tpm_wtx(struct tpm_chip *chip)
static void tpm_wtx_abort(struct tpm_chip *chip)
{
- dev_info(&chip->pci_dev->dev, "Aborting WTX\n");
+ dev_info(chip->dev, "Aborting WTX\n");
wait_and_send(chip, TPM_VL_VER);
wait_and_send(chip, TPM_CTRL_WTX_ABORT);
wait_and_send(chip, 0x00);
@@ -206,7 +206,7 @@ recv_begin:
}
if (buf[0] != TPM_VL_VER) {
- dev_err(&chip->pci_dev->dev,
+ dev_err(chip->dev,
"Wrong transport protocol implementation!\n");
return -EIO;
}
@@ -221,8 +221,7 @@ recv_begin:
}
if ((size == 0x6D00) && (buf[1] == 0x80)) {
- dev_err(&chip->pci_dev->dev,
- "Error handling on vendor layer!\n");
+ dev_err(chip->dev, "Error handling on vendor layer!\n");
return -EIO;
}
@@ -234,7 +233,7 @@ recv_begin:
}
if (buf[1] == TPM_CTRL_WTX) {
- dev_info(&chip->pci_dev->dev, "WTX-package received\n");
+ dev_info(chip->dev, "WTX-package received\n");
if (number_of_wtx < TPM_MAX_WTX_PACKAGES) {
tpm_wtx(chip);
goto recv_begin;
@@ -245,14 +244,14 @@ recv_begin:
}
if (buf[1] == TPM_CTRL_WTX_ABORT_ACK) {
- dev_info(&chip->pci_dev->dev, "WTX-abort acknowledged\n");
+ dev_info(chip->dev, "WTX-abort acknowledged\n");
return size;
}
if (buf[1] == TPM_CTRL_ERROR) {
- dev_err(&chip->pci_dev->dev, "ERROR-package received:\n");
+ dev_err(chip->dev, "ERROR-package received:\n");
if (buf[4] == TPM_INF_NAK)
- dev_err(&chip->pci_dev->dev,
+ dev_err(chip->dev,
"-> Negative acknowledgement"
" - retransmit command!\n");
return -EIO;
@@ -271,7 +270,7 @@ static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count)
ret = empty_fifo(chip, 1);
if (ret) {
- dev_err(&chip->pci_dev->dev, "Timeout while clearing FIFO\n");
+ dev_err(chip->dev, "Timeout while clearing FIFO\n");
return -EIO;
}
@@ -316,6 +315,11 @@ static void tpm_inf_cancel(struct tpm_chip *chip)
*/
}
+static u8 tpm_inf_status(struct tpm_chip *chip)
+{
+ return inb(chip->vendor->base + STAT);
+}
+
static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
@@ -344,6 +348,7 @@ static struct tpm_vendor_specific tpm_inf = {
.recv = tpm_inf_recv,
.send = tpm_inf_send,
.cancel = tpm_inf_cancel,
+ .status = tpm_inf_status,
.req_complete_mask = 0,
.req_complete_val = 0,
.attr_group = &inf_attr_grp,
@@ -356,30 +361,11 @@ static const struct pnp_device_id tpm_pnp_tbl[] = {
{"IFX0102", 0},
{"", 0}
};
+
MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl);
static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
- const struct pnp_device_id *dev_id)
-{
- if (pnp_port_valid(dev, 0)) {
- TPM_INF_ADDR = (pnp_port_start(dev, 0) & 0xff);
- TPM_INF_DATA = ((TPM_INF_ADDR + 1) & 0xff);
- tpm_inf.base = pnp_port_start(dev, 1);
- dev_info(&dev->dev, "Found %s with ID %s\n",
- dev->name, dev_id->id);
- return 0;
- }
- return -ENODEV;
-}
-
-static struct pnp_driver tpm_inf_pnp = {
- .name = "tpm_inf_pnp",
- .id_table = tpm_pnp_tbl,
- .probe = tpm_inf_pnp_probe,
-};
-
-static int __devinit tpm_inf_probe(struct pci_dev *pci_dev,
- const struct pci_device_id *pci_id)
+ const struct pnp_device_id *dev_id)
{
int rc = 0;
u8 iol, ioh;
@@ -388,30 +374,28 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev,
int productid[2];
char chipname[20];
- rc = pci_enable_device(pci_dev);
- if (rc)
- return rc;
-
- dev_info(&pci_dev->dev, "LPC-bus found at 0x%x\n", pci_id->device);
-
- /* read IO-ports from PnP */
- rc = pnp_register_driver(&tpm_inf_pnp);
- if (rc < 0) {
- dev_err(&pci_dev->dev,
- "Error %x from pnp_register_driver!\n",rc);
- goto error2;
- }
- if (!rc) {
- dev_info(&pci_dev->dev, "No Infineon TPM found!\n");
- goto error;
+ /* read IO-ports through PnP */
+ if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
+ !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) {
+ TPM_INF_ADDR = pnp_port_start(dev, 0);
+ TPM_INF_DATA = (TPM_INF_ADDR + 1);
+ TPM_INF_BASE = pnp_port_start(dev, 1);
+ TPM_INF_PORT_LEN = pnp_port_len(dev, 1);
+ if (!TPM_INF_PORT_LEN)
+ return -EINVAL;
+ dev_info(&dev->dev, "Found %s with ID %s\n",
+ dev->name, dev_id->id);
+ if (!((TPM_INF_BASE >> 8) & 0xff))
+ return -EINVAL;
+ /* publish my base address and request region */
+ tpm_inf.base = TPM_INF_BASE;
+ if (request_region
+ (tpm_inf.base, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {
+ release_region(tpm_inf.base, TPM_INF_PORT_LEN);
+ return -EINVAL;
+ }
} else {
- pnp_registered = 1;
- }
-
- /* Make sure, we have received valid config ports */
- if (!TPM_INF_ADDR) {
- dev_err(&pci_dev->dev, "No valid IO-ports received!\n");
- goto error;
+ return -EINVAL;
}
/* query chip for its vendor, its version number a.s.o. */
@@ -443,10 +427,6 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev,
if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) {
- if (tpm_inf.base == 0) {
- dev_err(&pci_dev->dev, "No IO-ports found!\n");
- goto error;
- }
/* configure TPM with IO-ports */
outb(IOLIMH, TPM_INF_ADDR);
outb(((tpm_inf.base >> 8) & 0xff), TPM_INF_DATA);
@@ -460,10 +440,11 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev,
iol = inb(TPM_INF_DATA);
if ((ioh << 8 | iol) != tpm_inf.base) {
- dev_err(&pci_dev->dev,
+ dev_err(&dev->dev,
"Could not set IO-ports to %04x\n",
tpm_inf.base);
- goto error;
+ release_region(tpm_inf.base, TPM_INF_PORT_LEN);
+ return -EIO;
}
/* activate register */
@@ -475,7 +456,7 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev,
outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD);
/* Finally, we're done, print some infos */
- dev_info(&pci_dev->dev, "TPM found: "
+ dev_info(&dev->dev, "TPM found: "
"config base 0x%x, "
"io base 0x%x, "
"chip version %02x%02x, "
@@ -483,59 +464,53 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev,
"product id %02x%02x"
"%s\n",
TPM_INF_ADDR,
- tpm_inf.base,
+ TPM_INF_BASE,
version[0], version[1],
vendorid[0], vendorid[1],
productid[0], productid[1], chipname);
- rc = tpm_register_hardware(pci_dev, &tpm_inf);
- if (rc < 0)
- goto error;
+ rc = tpm_register_hardware(&dev->dev, &tpm_inf);
+ if (rc < 0) {
+ release_region(tpm_inf.base, TPM_INF_PORT_LEN);
+ return -ENODEV;
+ }
return 0;
} else {
- dev_info(&pci_dev->dev, "No Infineon TPM found!\n");
-error:
- pnp_unregister_driver(&tpm_inf_pnp);
-error2:
- pci_disable_device(pci_dev);
- pnp_registered = 0;
+ dev_info(&dev->dev, "No Infineon TPM found!\n");
return -ENODEV;
}
}
-static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_2)},
- {0,}
-};
+static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev)
+{
+ struct tpm_chip *chip = pnp_get_drvdata(dev);
-MODULE_DEVICE_TABLE(pci, tpm_pci_tbl);
+ if (chip) {
+ release_region(chip->vendor->base, TPM_INF_PORT_LEN);
+ tpm_remove_hardware(chip->dev);
+ }
+}
-static struct pci_driver inf_pci_driver = {
- .name = "tpm_inf",
- .id_table = tpm_pci_tbl,
- .probe = tpm_inf_probe,
- .remove = __devexit_p(tpm_remove),
- .suspend = tpm_pm_suspend,
- .resume = tpm_pm_resume,
+static struct pnp_driver tpm_inf_pnp = {
+ .name = "tpm_inf_pnp",
+ .driver = {
+ .owner = THIS_MODULE,
+ .suspend = tpm_pm_suspend,
+ .resume = tpm_pm_resume,
+ },
+ .id_table = tpm_pnp_tbl,
+ .probe = tpm_inf_pnp_probe,
+ .remove = tpm_inf_pnp_remove,
};
static int __init init_inf(void)
{
- return pci_register_driver(&inf_pci_driver);
+ return pnp_register_driver(&tpm_inf_pnp);
}
static void __exit cleanup_inf(void)
{
- if (pnp_registered)
- pnp_unregister_driver(&tpm_inf_pnp);
- pci_unregister_driver(&inf_pci_driver);
+ pnp_unregister_driver(&tpm_inf_pnp);
}
module_init(init_inf);
@@ -543,5 +518,5 @@ module_exit(cleanup_inf);
MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>");
MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
-MODULE_VERSION("1.5");
+MODULE_VERSION("1.6");
MODULE_LICENSE("GPL");
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c
index b4127348c063..253871b5b1e2 100644
--- a/drivers/char/tpm/tpm_nsc.c
+++ b/drivers/char/tpm/tpm_nsc.c
@@ -111,7 +111,7 @@ static int nsc_wait_for_ready(struct tpm_chip *chip)
}
while (time_before(jiffies, stop));
- dev_info(&chip->pci_dev->dev, "wait for ready failed\n");
+ dev_info(chip->dev, "wait for ready failed\n");
return -EBUSY;
}
@@ -127,12 +127,12 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
return -EIO;
if (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0) {
- dev_err(&chip->pci_dev->dev, "F0 timeout\n");
+ dev_err(chip->dev, "F0 timeout\n");
return -EIO;
}
if ((data =
inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
- dev_err(&chip->pci_dev->dev, "not in normal mode (0x%x)\n",
+ dev_err(chip->dev, "not in normal mode (0x%x)\n",
data);
return -EIO;
}
@@ -141,7 +141,7 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
for (p = buffer; p < &buffer[count]; p++) {
if (wait_for_stat
(chip, NSC_STATUS_OBF, NSC_STATUS_OBF, &data) < 0) {
- dev_err(&chip->pci_dev->dev,
+ dev_err(chip->dev,
"OBF timeout (while reading data)\n");
return -EIO;
}
@@ -152,11 +152,11 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
if ((data & NSC_STATUS_F0) == 0 &&
(wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0)) {
- dev_err(&chip->pci_dev->dev, "F0 not set\n");
+ dev_err(chip->dev, "F0 not set\n");
return -EIO;
}
if ((data = inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_EOC) {
- dev_err(&chip->pci_dev->dev,
+ dev_err(chip->dev,
"expected end of command(0x%x)\n", data);
return -EIO;
}
@@ -187,19 +187,19 @@ static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count)
return -EIO;
if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
- dev_err(&chip->pci_dev->dev, "IBF timeout\n");
+ dev_err(chip->dev, "IBF timeout\n");
return -EIO;
}
outb(NSC_COMMAND_NORMAL, chip->vendor->base + NSC_COMMAND);
if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) {
- dev_err(&chip->pci_dev->dev, "IBR timeout\n");
+ dev_err(chip->dev, "IBR timeout\n");
return -EIO;
}
for (i = 0; i < count; i++) {
if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
- dev_err(&chip->pci_dev->dev,
+ dev_err(chip->dev,
"IBF timeout (while writing data)\n");
return -EIO;
}
@@ -207,7 +207,7 @@ static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count)
}
if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
- dev_err(&chip->pci_dev->dev, "IBF timeout\n");
+ dev_err(chip->dev, "IBF timeout\n");
return -EIO;
}
outb(NSC_COMMAND_EOC, chip->vendor->base + NSC_COMMAND);
@@ -220,6 +220,11 @@ static void tpm_nsc_cancel(struct tpm_chip *chip)
outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
}
+static u8 tpm_nsc_status(struct tpm_chip *chip)
+{
+ return inb(chip->vendor->base + NSC_STATUS);
+}
+
static struct file_operations nsc_ops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
@@ -239,7 +244,7 @@ static struct attribute * nsc_attrs[] = {
&dev_attr_pcrs.attr,
&dev_attr_caps.attr,
&dev_attr_cancel.attr,
- 0,
+ NULL,
};
static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs };
@@ -248,6 +253,7 @@ static struct tpm_vendor_specific tpm_nsc = {
.recv = tpm_nsc_recv,
.send = tpm_nsc_send,
.cancel = tpm_nsc_cancel,
+ .status = tpm_nsc_status,
.req_complete_mask = NSC_STATUS_OBF,
.req_complete_val = NSC_STATUS_OBF,
.req_canceled = NSC_STATUS_RDY,
@@ -255,16 +261,32 @@ static struct tpm_vendor_specific tpm_nsc = {
.miscdev = { .fops = &nsc_ops, },
};
-static int __devinit tpm_nsc_init(struct pci_dev *pci_dev,
- const struct pci_device_id *pci_id)
+static struct platform_device *pdev = NULL;
+
+static void __devexit tpm_nsc_remove(struct device *dev)
+{
+ struct tpm_chip *chip = dev_get_drvdata(dev);
+ if ( chip ) {
+ release_region(chip->vendor->base, 2);
+ tpm_remove_hardware(chip->dev);
+ }
+}
+
+static struct device_driver nsc_drv = {
+ .name = "tpm_nsc",
+ .bus = &platform_bus_type,
+ .owner = THIS_MODULE,
+ .suspend = tpm_pm_suspend,
+ .resume = tpm_pm_resume,
+};
+
+static int __init init_nsc(void)
{
int rc = 0;
int lo, hi;
int nscAddrBase = TPM_ADDR;
-
- if (pci_enable_device(pci_dev))
- return -EIO;
+ driver_register(&nsc_drv);
/* select PM channel 1 */
tpm_write_index(nscAddrBase,NSC_LDN_INDEX, 0x12);
@@ -273,37 +295,71 @@ static int __devinit tpm_nsc_init(struct pci_dev *pci_dev,
if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) {
nscAddrBase = (tpm_read_index(TPM_SUPERIO_ADDR, 0x2C)<<8)|
(tpm_read_index(TPM_SUPERIO_ADDR, 0x2B)&0xFE);
- if (tpm_read_index(nscAddrBase, NSC_SID_INDEX) != 0xF6) {
- rc = -ENODEV;
- goto out_err;
- }
+ if (tpm_read_index(nscAddrBase, NSC_SID_INDEX) != 0xF6)
+ return -ENODEV;
}
hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI);
lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO);
tpm_nsc.base = (hi<<8) | lo;
- dev_dbg(&pci_dev->dev, "NSC TPM detected\n");
- dev_dbg(&pci_dev->dev,
+ /* enable the DPM module */
+ tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);
+
+ pdev = kmalloc(sizeof(struct platform_device), GFP_KERNEL);
+ if ( !pdev )
+ return -ENOMEM;
+
+ memset(pdev, 0, sizeof(struct platform_device));
+
+ pdev->name = "tpm_nscl0";
+ pdev->id = -1;
+ pdev->num_resources = 0;
+ pdev->dev.release = tpm_nsc_remove;
+ pdev->dev.driver = &nsc_drv;
+
+ if ((rc=platform_device_register(pdev)) < 0) {
+ kfree(pdev);
+ pdev = NULL;
+ return rc;
+ }
+
+ if (request_region(tpm_nsc.base, 2, "tpm_nsc0") == NULL ) {
+ platform_device_unregister(pdev);
+ kfree(pdev);
+ pdev = NULL;
+ return -EBUSY;
+ }
+
+ if ((rc = tpm_register_hardware(&pdev->dev, &tpm_nsc)) < 0) {
+ release_region(tpm_nsc.base, 2);
+ platform_device_unregister(pdev);
+ kfree(pdev);
+ pdev = NULL;
+ return rc;
+ }
+
+ dev_dbg(&pdev->dev, "NSC TPM detected\n");
+ dev_dbg(&pdev->dev,
"NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n",
tpm_read_index(nscAddrBase,0x07), tpm_read_index(nscAddrBase,0x20),
tpm_read_index(nscAddrBase,0x27));
- dev_dbg(&pci_dev->dev,
+ dev_dbg(&pdev->dev,
"NSC SIOCF1 0x%x SIOCF5 0x%x SIOCF6 0x%x SIOCF8 0x%x\n",
tpm_read_index(nscAddrBase,0x21), tpm_read_index(nscAddrBase,0x25),
tpm_read_index(nscAddrBase,0x26), tpm_read_index(nscAddrBase,0x28));
- dev_dbg(&pci_dev->dev, "NSC IO Base0 0x%x\n",
+ dev_dbg(&pdev->dev, "NSC IO Base0 0x%x\n",
(tpm_read_index(nscAddrBase,0x60) << 8) | tpm_read_index(nscAddrBase,0x61));
- dev_dbg(&pci_dev->dev, "NSC IO Base1 0x%x\n",
+ dev_dbg(&pdev->dev, "NSC IO Base1 0x%x\n",
(tpm_read_index(nscAddrBase,0x62) << 8) | tpm_read_index(nscAddrBase,0x63));
- dev_dbg(&pci_dev->dev, "NSC Interrupt number and wakeup 0x%x\n",
+ dev_dbg(&pdev->dev, "NSC Interrupt number and wakeup 0x%x\n",
tpm_read_index(nscAddrBase,0x70));
- dev_dbg(&pci_dev->dev, "NSC IRQ type select 0x%x\n",
+ dev_dbg(&pdev->dev, "NSC IRQ type select 0x%x\n",
tpm_read_index(nscAddrBase,0x71));
- dev_dbg(&pci_dev->dev,
+ dev_dbg(&pdev->dev,
"NSC DMA channel select0 0x%x, select1 0x%x\n",
tpm_read_index(nscAddrBase,0x74), tpm_read_index(nscAddrBase,0x75));
- dev_dbg(&pci_dev->dev,
+ dev_dbg(&pdev->dev,
"NSC Config "
"0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
tpm_read_index(nscAddrBase,0xF0), tpm_read_index(nscAddrBase,0xF1),
@@ -312,55 +368,23 @@ static int __devinit tpm_nsc_init(struct pci_dev *pci_dev,
tpm_read_index(nscAddrBase,0xF6), tpm_read_index(nscAddrBase,0xF7),
tpm_read_index(nscAddrBase,0xF8), tpm_read_index(nscAddrBase,0xF9));
- dev_info(&pci_dev->dev,
+ dev_info(&pdev->dev,
"NSC TPM revision %d\n",
tpm_read_index(nscAddrBase, 0x27) & 0x1F);
- /* enable the DPM module */
- tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);
-
- if ((rc = tpm_register_hardware(pci_dev, &tpm_nsc)) < 0)
- goto out_err;
-
return 0;
-
-out_err:
- pci_disable_device(pci_dev);
- return rc;
-}
-
-static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0)},
- {PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)},
- {0,}
-};
-
-MODULE_DEVICE_TABLE(pci, tpm_pci_tbl);
-
-static struct pci_driver nsc_pci_driver = {
- .name = "tpm_nsc",
- .id_table = tpm_pci_tbl,
- .probe = tpm_nsc_init,
- .remove = __devexit_p(tpm_remove),
- .suspend = tpm_pm_suspend,
- .resume = tpm_pm_resume,
-};
-
-static int __init init_nsc(void)
-{
- return pci_register_driver(&nsc_pci_driver);
}
static void __exit cleanup_nsc(void)
{
- pci_unregister_driver(&nsc_pci_driver);
+ if (pdev) {
+ tpm_nsc_remove(&pdev->dev);
+ platform_device_unregister(pdev);
+ kfree(pdev);
+ pdev = NULL;
+ }
+
+ driver_unregister(&nsc_drv);
}
module_init(init_nsc);
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index f5649a337743..c586bfa852ee 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -809,7 +809,7 @@ static void do_tty_hangup(void *data)
check_tty_count(tty, "do_tty_hangup");
file_list_lock();
/* This breaks for file handles being sent over AF_UNIX sockets ? */
- list_for_each_entry(filp, &tty->tty_files, f_list) {
+ list_for_each_entry(filp, &tty->tty_files, f_u.fu_list) {
if (filp->f_op->write == redirected_tty_write)
cons_filp = filp;
if (filp->f_op->write != tty_write)
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index a5e104f428f8..51abd3defc1c 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -993,13 +993,16 @@ static struct vio_device_id viotape_device_table[] __devinitdata = {
{ "viotape", "" },
{ "", "" }
};
-
MODULE_DEVICE_TABLE(vio, viotape_device_table);
+
static struct vio_driver viotape_driver = {
- .name = "viotape",
.id_table = viotape_device_table,
.probe = viotape_probe,
- .remove = viotape_remove
+ .remove = viotape_remove,
+ .driver = {
+ .name = "viotape",
+ .owner = THIS_MODULE,
+ }
};
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index 1d44f69e1fda..003dda147cd0 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -192,6 +192,9 @@ do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
int i, j, k;
int ret;
+ if (!capable(CAP_SYS_TTY_CONFIG))
+ return -EPERM;
+
kbs = kmalloc(sizeof(*kbs), GFP_KERNEL);
if (!kbs) {
ret = -ENOMEM;
diff --git a/drivers/char/watchdog/cpu5wdt.c b/drivers/char/watchdog/cpu5wdt.c
index 2865dac0a813..e75045fe2641 100644
--- a/drivers/char/watchdog/cpu5wdt.c
+++ b/drivers/char/watchdog/cpu5wdt.c
@@ -28,6 +28,7 @@
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/timer.h>
+#include <linux/jiffies.h>
#include <asm/io.h>
#include <asm/uaccess.h>
diff --git a/drivers/char/watchdog/mixcomwd.c b/drivers/char/watchdog/mixcomwd.c
index 7fc2188386d9..d8dede575402 100644
--- a/drivers/char/watchdog/mixcomwd.c
+++ b/drivers/char/watchdog/mixcomwd.c
@@ -45,6 +45,8 @@
#include <linux/fs.h>
#include <linux/reboot.h>
#include <linux/init.h>
+#include <linux/jiffies.h>
+#include <linux/timer.h>
#include <asm/uaccess.h>
#include <asm/io.h>
diff --git a/drivers/char/watchdog/pcwd.c b/drivers/char/watchdog/pcwd.c
index 427ad51b7a35..37c9e13ad3ac 100644
--- a/drivers/char/watchdog/pcwd.c
+++ b/drivers/char/watchdog/pcwd.c
@@ -66,7 +66,7 @@
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/reboot.h>
-
+#include <linux/sched.h> /* TASK_INTERRUPTIBLE, set_current_state() and friends */
#include <asm/uaccess.h>
#include <asm/io.h>
diff --git a/drivers/char/watchdog/pcwd_pci.c b/drivers/char/watchdog/pcwd_pci.c
index 0b8e493be045..5308e5c8f29a 100644
--- a/drivers/char/watchdog/pcwd_pci.c
+++ b/drivers/char/watchdog/pcwd_pci.c
@@ -753,6 +753,7 @@ static struct pci_device_id pcipcwd_pci_tbl[] = {
MODULE_DEVICE_TABLE(pci, pcipcwd_pci_tbl);
static struct pci_driver pcipcwd_driver = {
+ .owner = THIS_MODULE,
.name = WATCHDOG_NAME,
.id_table = pcipcwd_pci_tbl,
.probe = pcipcwd_card_init,
diff --git a/drivers/char/watchdog/sc520_wdt.c b/drivers/char/watchdog/sc520_wdt.c
index 72501be79b0c..4ee9974ad8cb 100644
--- a/drivers/char/watchdog/sc520_wdt.c
+++ b/drivers/char/watchdog/sc520_wdt.c
@@ -63,6 +63,7 @@
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/init.h>
+#include <linux/jiffies.h>
#include <asm/io.h>
#include <asm/uaccess.h>
diff --git a/drivers/char/watchdog/softdog.c b/drivers/char/watchdog/softdog.c
index 20e5eb8667f2..a91edaf3a350 100644
--- a/drivers/char/watchdog/softdog.c
+++ b/drivers/char/watchdog/softdog.c
@@ -47,6 +47,8 @@
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/init.h>
+#include <linux/jiffies.h>
+
#include <asm/uaccess.h>
#define PFX "SoftDog: "
diff --git a/drivers/char/watchdog/wdt_pci.c b/drivers/char/watchdog/wdt_pci.c
index 4b3311993d48..dc9370f6c348 100644
--- a/drivers/char/watchdog/wdt_pci.c
+++ b/drivers/char/watchdog/wdt_pci.c
@@ -711,6 +711,7 @@ MODULE_DEVICE_TABLE(pci, wdtpci_pci_tbl);
static struct pci_driver wdtpci_driver = {
+ .owner = THIS_MODULE,
.name = "wdt_pci",
.id_table = wdtpci_pci_tbl,
.probe = wdtpci_init_one,
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 109d62ccf651..6c6121b85a54 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -4,6 +4,9 @@
* Copyright (C) 2001 Russell King
* (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
*
+ * Oct 2005 - Ashok Raj <ashok.raj@intel.com>
+ * Added handling for CPU hotplug
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
@@ -36,13 +39,6 @@ static struct cpufreq_policy *cpufreq_cpu_data[NR_CPUS];
static DEFINE_SPINLOCK(cpufreq_driver_lock);
-/* we keep a copy of all ->add'ed CPU's struct sys_device here;
- * as it is only accessed in ->add and ->remove, no lock or reference
- * count is necessary.
- */
-static struct sys_device *cpu_sys_devices[NR_CPUS];
-
-
/* internal prototypes */
static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event);
static void handle_update(void *data);
@@ -574,6 +570,9 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
unsigned long flags;
unsigned int j;
+ if (cpu_is_offline(cpu))
+ return 0;
+
cpufreq_debug_disable_ratelimit();
dprintk("adding CPU %u\n", cpu);
@@ -582,7 +581,6 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
* CPU because it is in the same boat. */
policy = cpufreq_cpu_get(cpu);
if (unlikely(policy)) {
- cpu_sys_devices[cpu] = sys_dev;
dprintk("CPU already managed, adding link\n");
sysfs_create_link(&sys_dev->kobj, &policy->kobj, "cpufreq");
cpufreq_debug_enable_ratelimit();
@@ -657,7 +655,6 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
}
module_put(cpufreq_driver->owner);
- cpu_sys_devices[cpu] = sys_dev;
dprintk("initialization complete\n");
cpufreq_debug_enable_ratelimit();
@@ -682,7 +679,7 @@ err_out:
nomem_out:
module_put(cpufreq_driver->owner);
- module_out:
+module_out:
cpufreq_debug_enable_ratelimit();
return ret;
}
@@ -698,6 +695,7 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
unsigned int cpu = sys_dev->id;
unsigned long flags;
struct cpufreq_policy *data;
+ struct sys_device *cpu_sys_dev;
#ifdef CONFIG_SMP
unsigned int j;
#endif
@@ -710,7 +708,6 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
if (!data) {
spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
- cpu_sys_devices[cpu] = NULL;
cpufreq_debug_enable_ratelimit();
return -EINVAL;
}
@@ -725,14 +722,12 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
dprintk("removing link\n");
spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
sysfs_remove_link(&sys_dev->kobj, "cpufreq");
- cpu_sys_devices[cpu] = NULL;
cpufreq_cpu_put(data);
cpufreq_debug_enable_ratelimit();
return 0;
}
#endif
- cpu_sys_devices[cpu] = NULL;
if (!kobject_get(&data->kobj)) {
spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
@@ -761,7 +756,8 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
if (j == cpu)
continue;
dprintk("removing link for cpu %u\n", j);
- sysfs_remove_link(&cpu_sys_devices[j]->kobj, "cpufreq");
+ cpu_sys_dev = get_cpu_sysdev(j);
+ sysfs_remove_link(&cpu_sys_dev->kobj, "cpufreq");
cpufreq_cpu_put(data);
}
}
@@ -772,7 +768,6 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
down(&data->lock);
if (cpufreq_driver->target)
__cpufreq_governor(data, CPUFREQ_GOV_STOP);
- cpufreq_driver->target = NULL;
up(&data->lock);
kobject_unregister(&data->kobj);
@@ -1119,17 +1114,30 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
unsigned int relation)
{
int retval = -EINVAL;
- lock_cpu_hotplug();
+
+ /*
+ * Converted the lock_cpu_hotplug to preempt_disable()
+ * and preempt_enable(). This is a bit kludgy and relies on how cpu
+ * hotplug works. All we need is a guarantee that cpu hotplug won't make
+ * progress on any cpu. Once we do preempt_disable(), this would ensure
+ * that hotplug threads don't get onto this cpu, thereby delaying
+ * the cpu remove process.
+ *
+ * We removed the lock_cpu_hotplug since we need to call this function
+ * via cpu hotplug callbacks, which result in locking the cpu hotplug
+ * thread itself. Agree this is not very clean, cpufreq community
+ * could improve this if required. - Ashok Raj <ashok.raj@intel.com>
+ */
+ preempt_disable();
dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu,
target_freq, relation);
if (cpu_online(policy->cpu) && cpufreq_driver->target)
retval = cpufreq_driver->target(policy, target_freq, relation);
- unlock_cpu_hotplug();
+ preempt_enable();
return retval;
}
EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
-
int cpufreq_driver_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
@@ -1416,6 +1424,45 @@ int cpufreq_update_policy(unsigned int cpu)
}
EXPORT_SYMBOL(cpufreq_update_policy);
+static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
+ unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (unsigned long)hcpu;
+ struct cpufreq_policy *policy;
+ struct sys_device *sys_dev;
+
+ sys_dev = get_cpu_sysdev(cpu);
+
+ if (sys_dev) {
+ switch (action) {
+ case CPU_ONLINE:
+ cpufreq_add_dev(sys_dev);
+ break;
+ case CPU_DOWN_PREPARE:
+ /*
+ * We attempt to put this cpu in lowest frequency
+ * possible before going down. This will permit
+ * hardware-managed P-State to switch other related
+ * threads to min or higher speeds if possible.
+ */
+ policy = cpufreq_cpu_data[cpu];
+ if (policy) {
+ cpufreq_driver_target(policy, policy->min,
+ CPUFREQ_RELATION_H);
+ }
+ break;
+ case CPU_DEAD:
+ cpufreq_remove_dev(sys_dev);
+ break;
+ }
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block cpufreq_cpu_notifier =
+{
+ .notifier_call = cpufreq_cpu_callback,
+};
/*********************************************************************
* REGISTER / UNREGISTER CPUFREQ DRIVER *
@@ -1476,6 +1523,7 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
}
if (!ret) {
+ register_cpu_notifier(&cpufreq_cpu_notifier);
dprintk("driver %s up and running\n", driver_data->name);
cpufreq_debug_enable_ratelimit();
}
@@ -1507,6 +1555,7 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver)
dprintk("unregistering driver %s\n", driver->name);
sysdev_driver_unregister(&cpu_sysdev_class, &cpufreq_sysdev_driver);
+ unregister_cpu_notifier(&cpufreq_cpu_notifier);
spin_lock_irqsave(&cpufreq_driver_lock, flags);
cpufreq_driver = NULL;
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
index 741b6b191e6a..3597f25d5efa 100644
--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -19,6 +19,7 @@
#include <linux/percpu.h>
#include <linux/kobject.h>
#include <linux/spinlock.h>
+#include <linux/notifier.h>
#include <asm/cputime.h>
static spinlock_t cpufreq_stats_lock;
@@ -298,6 +299,27 @@ cpufreq_stat_notifier_trans (struct notifier_block *nb, unsigned long val,
return 0;
}
+static int __cpuinit cpufreq_stat_cpu_callback(struct notifier_block *nfb,
+ unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (unsigned long)hcpu;
+
+ switch (action) {
+ case CPU_ONLINE:
+ cpufreq_update_policy(cpu);
+ break;
+ case CPU_DEAD:
+ cpufreq_stats_free_table(cpu);
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block cpufreq_stat_cpu_notifier =
+{
+ .notifier_call = cpufreq_stat_cpu_callback,
+};
+
static struct notifier_block notifier_policy_block = {
.notifier_call = cpufreq_stat_notifier_policy
};
@@ -311,6 +333,7 @@ __init cpufreq_stats_init(void)
{
int ret;
unsigned int cpu;
+
spin_lock_init(&cpufreq_stats_lock);
if ((ret = cpufreq_register_notifier(&notifier_policy_block,
CPUFREQ_POLICY_NOTIFIER)))
@@ -323,20 +346,31 @@ __init cpufreq_stats_init(void)
return ret;
}
- for_each_cpu(cpu)
- cpufreq_update_policy(cpu);
+ register_cpu_notifier(&cpufreq_stat_cpu_notifier);
+ lock_cpu_hotplug();
+ for_each_online_cpu(cpu) {
+ cpufreq_stat_cpu_callback(&cpufreq_stat_cpu_notifier, CPU_ONLINE,
+ (void *)(long)cpu);
+ }
+ unlock_cpu_hotplug();
return 0;
}
static void
__exit cpufreq_stats_exit(void)
{
unsigned int cpu;
+
cpufreq_unregister_notifier(&notifier_policy_block,
CPUFREQ_POLICY_NOTIFIER);
cpufreq_unregister_notifier(&notifier_trans_block,
CPUFREQ_TRANSITION_NOTIFIER);
- for_each_cpu(cpu)
- cpufreq_stats_free_table(cpu);
+ unregister_cpu_notifier(&cpufreq_stat_cpu_notifier);
+ lock_cpu_hotplug();
+ for_each_online_cpu(cpu) {
+ cpufreq_stat_cpu_callback(&cpufreq_stat_cpu_notifier, CPU_DEAD,
+ (void *)(long)cpu);
+ }
+ unlock_cpu_hotplug();
}
MODULE_AUTHOR ("Zou Nan hai <nanhai.zou@intel.com>");
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 094835cce321..4263935443cc 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -2,7 +2,7 @@ menu "Hardware crypto devices"
config CRYPTO_DEV_PADLOCK
tristate "Support for VIA PadLock ACE"
- depends on CRYPTO && X86 && !X86_64
+ depends on CRYPTO && X86_32
help
Some VIA processors come with an integrated crypto engine
(so called VIA PadLock ACE, Advanced Cryptography Engine)
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 327b58e64875..b6815c6c29a2 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -70,8 +70,7 @@ config DELL_RBU
config DCDBAS
tristate "Dell Systems Management Base Driver"
- depends on X86 || X86_64
- default m
+ depends on X86
help
The Dell Systems Management Base Driver provides a sysfs interface
for systems management software to perform System Management
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 1cadd2c3cadd..a737886e39d1 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -778,6 +778,35 @@ config BLK_DEV_IDE_PMAC_BLINK
This option enables the use of the sleep LED as a hard drive
activity LED.
+config BLK_DEV_IDE_AU1XXX
+ bool "IDE for AMD Alchemy Au1200"
+ depends on SOC_AU1200
+choice
+ prompt "IDE Mode for AMD Alchemy Au1200"
+ default CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA
+ depends on SOC_AU1200 && BLK_DEV_IDE_AU1XXX
+
+config BLK_DEV_IDE_AU1XXX_PIO_DBDMA
+ bool "PIO+DbDMA IDE for AMD Alchemy Au1200"
+
+config BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+ bool "MDMA2+DbDMA IDE for AMD Alchemy Au1200"
+ depends on SOC_AU1200 && BLK_DEV_IDE_AU1XXX
+endchoice
+
+config BLK_DEV_IDE_AU1XXX_BURSTABLE_ON
+ bool "Enable burstable Mode on DbDMA"
+ default false
+ depends BLK_DEV_IDE_AU1XXX
+ help
+ This option enable the burstable Flag on DbDMA controller
+ (cf. "AMD Alchemy 'Au1200' Processor Data Book - PRELIMINARY").
+
+config BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ
+ int "Maximum transfer size (KB) per request (up to 128)"
+ default "128"
+ depends BLK_DEV_IDE_AU1XXX
+
config IDE_ARM
def_bool ARM && (ARCH_A5K || ARCH_CLPS7500 || ARCH_RPC || ARCH_SHARK)
@@ -1013,7 +1042,7 @@ config BLK_DEV_UMC8672
endif
config BLK_DEV_IDEDMA
- def_bool BLK_DEV_IDEDMA_PCI || BLK_DEV_IDEDMA_PMAC || BLK_DEV_IDEDMA_ICS
+ def_bool BLK_DEV_IDEDMA_PCI || BLK_DEV_IDEDMA_PMAC || BLK_DEV_IDEDMA_ICS || BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
config IDEDMA_IVB
bool "IGNORE word93 Validation BITS"
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 74af7e074868..8b9d85526596 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -2211,13 +2211,12 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
if (toc == NULL) {
/* Try to allocate space. */
- toc = (struct atapi_toc *) kmalloc (sizeof (struct atapi_toc),
- GFP_KERNEL);
- info->toc = toc;
+ toc = kmalloc(sizeof(struct atapi_toc), GFP_KERNEL);
if (toc == NULL) {
printk (KERN_ERR "%s: No cdrom TOC buffer!\n", drive->name);
return -ENOMEM;
}
+ info->toc = toc;
}
/* Check to see if the existing data is still valid.
@@ -2240,7 +2239,8 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
/* First read just the header, so we know how long the TOC is. */
stat = cdrom_read_tocentry(drive, 0, 1, 0, (char *) &toc->hdr,
sizeof(struct atapi_toc_header), sense);
- if (stat) return stat;
+ if (stat)
+ return stat;
#if ! STANDARD_ATAPI
if (CDROM_CONFIG_FLAGS(drive)->toctracks_as_bcd) {
@@ -2324,7 +2324,8 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
/* Read the multisession information. */
stat = cdrom_read_tocentry(drive, 0, 0, 1, (char *)&ms_tmp,
sizeof(ms_tmp), sense);
- if (stat) return stat;
+ if (stat)
+ return stat;
toc->last_session_lba = be32_to_cpu(ms_tmp.ent.addr.lba);
} else {
@@ -2460,7 +2461,7 @@ static int ide_cdrom_packet(struct cdrom_device_info *cdi,
struct packet_command *cgc)
{
struct request req;
- ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+ ide_drive_t *drive = cdi->handle;
if (cgc->timeout <= 0)
cgc->timeout = ATAPI_WAIT_PC;
@@ -2537,7 +2538,7 @@ int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi,
unsigned int cmd, void *arg)
{
- ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+ ide_drive_t *drive = cdi->handle;
struct cdrom_info *info = drive->driver_data;
int stat;
@@ -2548,7 +2549,7 @@ int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi,
*/
case CDROMPLAYTRKIND: {
unsigned long lba_start, lba_end;
- struct cdrom_ti *ti = (struct cdrom_ti *)arg;
+ struct cdrom_ti *ti = arg;
struct atapi_toc_entry *first_toc, *last_toc;
stat = cdrom_get_toc_entry(drive, ti->cdti_trk0, &first_toc);
@@ -2571,12 +2572,13 @@ int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi,
}
case CDROMREADTOCHDR: {
- struct cdrom_tochdr *tochdr = (struct cdrom_tochdr *) arg;
+ struct cdrom_tochdr *tochdr = arg;
struct atapi_toc *toc;
/* Make sure our saved TOC is valid. */
stat = cdrom_read_toc(drive, NULL);
- if (stat) return stat;
+ if (stat)
+ return stat;
toc = info->toc;
tochdr->cdth_trk0 = toc->hdr.first_track;
@@ -2586,11 +2588,12 @@ int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi,
}
case CDROMREADTOCENTRY: {
- struct cdrom_tocentry *tocentry = (struct cdrom_tocentry*) arg;
+ struct cdrom_tocentry *tocentry = arg;
struct atapi_toc_entry *toce;
stat = cdrom_get_toc_entry(drive, tocentry->cdte_track, &toce);
- if (stat) return stat;
+ if (stat)
+ return stat;
tocentry->cdte_ctrl = toce->control;
tocentry->cdte_adr = toce->adr;
@@ -2613,7 +2616,7 @@ int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi,
static
int ide_cdrom_reset (struct cdrom_device_info *cdi)
{
- ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+ ide_drive_t *drive = cdi->handle;
struct request_sense sense;
struct request req;
int ret;
@@ -2636,12 +2639,13 @@ int ide_cdrom_reset (struct cdrom_device_info *cdi)
static
int ide_cdrom_tray_move (struct cdrom_device_info *cdi, int position)
{
- ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+ ide_drive_t *drive = cdi->handle;
struct request_sense sense;
if (position) {
int stat = cdrom_lockdoor(drive, 0, &sense);
- if (stat) return stat;
+ if (stat)
+ return stat;
}
return cdrom_eject(drive, !position, &sense);
@@ -2650,7 +2654,7 @@ int ide_cdrom_tray_move (struct cdrom_device_info *cdi, int position)
static
int ide_cdrom_lock_door (struct cdrom_device_info *cdi, int lock)
{
- ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+ ide_drive_t *drive = cdi->handle;
return cdrom_lockdoor(drive, lock, NULL);
}
@@ -2700,7 +2704,7 @@ void ide_cdrom_update_speed (ide_drive_t *drive, struct atapi_capabilities_page
static
int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed)
{
- ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+ ide_drive_t *drive = cdi->handle;
struct request_sense sense;
struct atapi_capabilities_page cap;
int stat;
@@ -2723,7 +2727,7 @@ int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed)
static
int ide_cdrom_drive_status (struct cdrom_device_info *cdi, int slot_nr)
{
- ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+ ide_drive_t *drive = cdi->handle;
struct media_event_desc med;
struct request_sense sense;
int stat;
@@ -2769,7 +2773,7 @@ int ide_cdrom_get_last_session (struct cdrom_device_info *cdi,
struct cdrom_multisession *ms_info)
{
struct atapi_toc *toc;
- ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+ ide_drive_t *drive = cdi->handle;
struct cdrom_info *info = drive->driver_data;
struct request_sense sense;
int ret;
@@ -2791,7 +2795,7 @@ int ide_cdrom_get_mcn (struct cdrom_device_info *cdi,
{
int stat;
char mcnbuf[24];
- ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+ ide_drive_t *drive = cdi->handle;
/* get MCN */
if ((stat = cdrom_read_subchannel(drive, 2, mcnbuf, sizeof (mcnbuf), NULL)))
@@ -2815,7 +2819,7 @@ static
int ide_cdrom_check_media_change_real (struct cdrom_device_info *cdi,
int slot_nr)
{
- ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+ ide_drive_t *drive = cdi->handle;
int retval;
if (slot_nr == CDSL_CURRENT) {
@@ -2886,7 +2890,7 @@ static int ide_cdrom_register (ide_drive_t *drive, int nslots)
devinfo->mask = 0;
devinfo->speed = CDROM_STATE_FLAGS(drive)->current_speed;
devinfo->capacity = nslots;
- devinfo->handle = (void *) drive;
+ devinfo->handle = drive;
strcpy(devinfo->name, drive->name);
/* set capability mask to match the probe. */
@@ -2942,7 +2946,7 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
* registered with the Uniform layer yet, it can't do this.
* Same goes for cdi->ops.
*/
- cdi->handle = (ide_drive_t *) drive;
+ cdi->handle = drive;
cdi->ops = &ide_cdrom_dops;
if (ide_cdrom_get_capabilities(drive, &cap))
@@ -3254,6 +3258,7 @@ int ide_cdrom_setup (ide_drive_t *drive)
return 0;
}
+#ifdef CONFIG_PROC_FS
static
sector_t ide_cdrom_capacity (ide_drive_t *drive)
{
@@ -3264,6 +3269,7 @@ sector_t ide_cdrom_capacity (ide_drive_t *drive)
return capacity * sectors_per_frame;
}
+#endif
static int ide_cd_remove(struct device *dev)
{
@@ -3309,7 +3315,7 @@ static int ide_cd_probe(struct device *);
static int proc_idecd_read_capacity
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
- ide_drive_t*drive = (ide_drive_t *)data;
+ ide_drive_t *drive = data;
int len;
len = sprintf(page,"%llu\n", (long long)ide_cdrom_capacity(drive));
@@ -3449,7 +3455,7 @@ static int ide_cd_probe(struct device *dev)
printk(KERN_INFO "ide-cd: passing drive %s to ide-scsi emulation.\n", drive->name);
goto failed;
}
- info = (struct cdrom_info *) kmalloc (sizeof (struct cdrom_info), GFP_KERNEL);
+ info = kmalloc(sizeof(struct cdrom_info), GFP_KERNEL);
if (info == NULL) {
printk(KERN_ERR "%s: Can't allocate a cdrom structure\n", drive->name);
goto failed;
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index 4063d2c34e3d..84665e2ba3c8 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -64,6 +64,7 @@ static int proc_ide_read_imodel
case ide_cy82c693: name = "cy82c693"; break;
case ide_4drives: name = "4drives"; break;
case ide_pmac: name = "mac-io"; break;
+ case ide_au1xxx: name = "au1xxx"; break;
default: name = "(unknown)"; break;
}
len = sprintf(page, "%s\n", name);
diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c
new file mode 100644
index 000000000000..2b6327c576b9
--- /dev/null
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -0,0 +1,1250 @@
+/*
+ * linux/drivers/ide/mips/au1xxx-ide.c version 01.30.00 Aug. 02 2005
+ *
+ * BRIEF MODULE DESCRIPTION
+ * AMD Alchemy Au1xxx IDE interface routines over the Static Bus
+ *
+ * Copyright (c) 2003-2005 AMD, Personal Connectivity Solutions
+ *
+ * This program is free software; you can redistribute 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.
+ *
+ * Note: for more information, please refer "AMD Alchemy Au1200/Au1550 IDE
+ * Interface and Linux Device Driver" Application Note.
+ */
+#undef REALLY_SLOW_IO /* most systems can safely undef this */
+
+#include <linux/config.h> /* for CONFIG_BLK_DEV_IDEPCI */
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/ioport.h>
+#include <linux/hdreg.h>
+#include <linux/init.h>
+#include <linux/ide.h>
+#include <linux/sysdev.h>
+
+#include <linux/dma-mapping.h>
+
+#include <asm/io.h>
+#include <asm/mach-au1x00/au1xxx.h>
+#include <asm/mach-au1x00/au1xxx_dbdma.h>
+
+#if CONFIG_PM
+#include <asm/mach-au1x00/au1xxx_pm.h>
+#endif
+
+#include <asm/mach-au1x00/au1xxx_ide.h>
+
+#define DRV_NAME "au1200-ide"
+#define DRV_VERSION "1.0"
+#define DRV_AUTHOR "AMD PCS / Pete Popov <ppopov@embeddedalley.com>"
+#define DRV_DESC "Au1200 IDE"
+
+static _auide_hwif auide_hwif;
+static spinlock_t ide_tune_drive_spin_lock = SPIN_LOCK_UNLOCKED;
+static spinlock_t ide_tune_chipset_spin_lock = SPIN_LOCK_UNLOCKED;
+static int dbdma_init_done = 0;
+
+/*
+ * local I/O functions
+ */
+u8 auide_inb(unsigned long port)
+{
+ return (au_readb(port));
+}
+
+u16 auide_inw(unsigned long port)
+{
+ return (au_readw(port));
+}
+
+u32 auide_inl(unsigned long port)
+{
+ return (au_readl(port));
+}
+
+void auide_insw(unsigned long port, void *addr, u32 count)
+{
+#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
+
+ _auide_hwif *ahwif = &auide_hwif;
+ chan_tab_t *ctp;
+ au1x_ddma_desc_t *dp;
+
+ if(!put_dest_flags(ahwif->rx_chan, (void*)addr, count << 1,
+ DDMA_FLAGS_NOIE)) {
+ printk(KERN_ERR "%s failed %d\n", __FUNCTION__, __LINE__);
+ return;
+ }
+ ctp = *((chan_tab_t **)ahwif->rx_chan);
+ dp = ctp->cur_ptr;
+ while (dp->dscr_cmd0 & DSCR_CMD0_V)
+ ;
+ ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
+#else
+ while (count--)
+ {
+ *(u16 *)addr = au_readw(port);
+ addr +=2 ;
+ }
+#endif
+}
+
+void auide_insl(unsigned long port, void *addr, u32 count)
+{
+ while (count--)
+ {
+ *(u32 *)addr = au_readl(port);
+ /* NOTE: For IDE interfaces over PCMCIA,
+ * 32-bit access does not work
+ */
+ addr += 4;
+ }
+}
+
+void auide_outb(u8 addr, unsigned long port)
+{
+ return (au_writeb(addr, port));
+}
+
+void auide_outbsync(ide_drive_t *drive, u8 addr, unsigned long port)
+{
+ return (au_writeb(addr, port));
+}
+
+void auide_outw(u16 addr, unsigned long port)
+{
+ return (au_writew(addr, port));
+}
+
+void auide_outl(u32 addr, unsigned long port)
+{
+ return (au_writel(addr, port));
+}
+
+void auide_outsw(unsigned long port, void *addr, u32 count)
+{
+#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
+ _auide_hwif *ahwif = &auide_hwif;
+ chan_tab_t *ctp;
+ au1x_ddma_desc_t *dp;
+
+ if(!put_source_flags(ahwif->tx_chan, (void*)addr,
+ count << 1, DDMA_FLAGS_NOIE)) {
+ printk(KERN_ERR "%s failed %d\n", __FUNCTION__, __LINE__);
+ return;
+ }
+ ctp = *((chan_tab_t **)ahwif->tx_chan);
+ dp = ctp->cur_ptr;
+ while (dp->dscr_cmd0 & DSCR_CMD0_V)
+ ;
+ ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
+#else
+ while (count--)
+ {
+ au_writew(*(u16 *)addr, port);
+ addr += 2;
+ }
+#endif
+}
+
+void auide_outsl(unsigned long port, void *addr, u32 count)
+{
+ while (count--)
+ {
+ au_writel(*(u32 *)addr, port);
+ /* NOTE: For IDE interfaces over PCMCIA,
+ * 32-bit access does not work
+ */
+ addr += 4;
+ }
+}
+
+static void auide_tune_drive(ide_drive_t *drive, byte pio)
+{
+ int mem_sttime;
+ int mem_stcfg;
+ unsigned long flags;
+ u8 speed;
+
+ /* get the best pio mode for the drive */
+ pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
+
+ printk("%s: setting Au1XXX IDE to PIO mode%d\n",
+ drive->name, pio);
+
+ spin_lock_irqsave(&ide_tune_drive_spin_lock, flags);
+
+ mem_sttime = 0;
+ mem_stcfg = au_readl(MEM_STCFG2);
+
+ /* set pio mode! */
+ switch(pio) {
+ case 0:
+ /* set timing parameters for RCS2# */
+ mem_sttime = SBC_IDE_PIO0_TWCS
+ | SBC_IDE_PIO0_TCSH
+ | SBC_IDE_PIO0_TCSOFF
+ | SBC_IDE_PIO0_TWP
+ | SBC_IDE_PIO0_TCSW
+ | SBC_IDE_PIO0_TPM
+ | SBC_IDE_PIO0_TA;
+ /* set configuration for RCS2# */
+ mem_stcfg |= TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_PIO0_TCSOE | SBC_IDE_PIO0_TOECS;
+
+ au_writel(mem_sttime,MEM_STTIME2);
+ au_writel(mem_stcfg,MEM_STCFG2);
+ break;
+
+ case 1:
+ /* set timing parameters for RCS2# */
+ mem_sttime = SBC_IDE_PIO1_TWCS
+ | SBC_IDE_PIO1_TCSH
+ | SBC_IDE_PIO1_TCSOFF
+ | SBC_IDE_PIO1_TWP
+ | SBC_IDE_PIO1_TCSW
+ | SBC_IDE_PIO1_TPM
+ | SBC_IDE_PIO1_TA;
+ /* set configuration for RCS2# */
+ mem_stcfg |= TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_PIO1_TCSOE | SBC_IDE_PIO1_TOECS;
+ break;
+
+ case 2:
+ /* set timing parameters for RCS2# */
+ mem_sttime = SBC_IDE_PIO2_TWCS
+ | SBC_IDE_PIO2_TCSH
+ | SBC_IDE_PIO2_TCSOFF
+ | SBC_IDE_PIO2_TWP
+ | SBC_IDE_PIO2_TCSW
+ | SBC_IDE_PIO2_TPM
+ | SBC_IDE_PIO2_TA;
+ /* set configuration for RCS2# */
+ mem_stcfg &= ~TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_PIO2_TCSOE | SBC_IDE_PIO2_TOECS;
+ break;
+
+ case 3:
+ /* set timing parameters for RCS2# */
+ mem_sttime = SBC_IDE_PIO3_TWCS
+ | SBC_IDE_PIO3_TCSH
+ | SBC_IDE_PIO3_TCSOFF
+ | SBC_IDE_PIO3_TWP
+ | SBC_IDE_PIO3_TCSW
+ | SBC_IDE_PIO3_TPM
+ | SBC_IDE_PIO3_TA;
+ /* set configuration for RCS2# */
+ mem_stcfg |= TS_MASK;
+ mem_stcfg &= ~TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_PIO3_TCSOE | SBC_IDE_PIO3_TOECS;
+
+ break;
+
+ case 4:
+ /* set timing parameters for RCS2# */
+ mem_sttime = SBC_IDE_PIO4_TWCS
+ | SBC_IDE_PIO4_TCSH
+ | SBC_IDE_PIO4_TCSOFF
+ | SBC_IDE_PIO4_TWP
+ | SBC_IDE_PIO4_TCSW
+ | SBC_IDE_PIO4_TPM
+ | SBC_IDE_PIO4_TA;
+ /* set configuration for RCS2# */
+ mem_stcfg &= ~TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_PIO4_TCSOE | SBC_IDE_PIO4_TOECS;
+ break;
+ }
+
+ au_writel(mem_sttime,MEM_STTIME2);
+ au_writel(mem_stcfg,MEM_STCFG2);
+
+ spin_unlock_irqrestore(&ide_tune_drive_spin_lock, flags);
+
+ speed = pio + XFER_PIO_0;
+ ide_config_drive_speed(drive, speed);
+}
+
+static int auide_tune_chipset (ide_drive_t *drive, u8 speed)
+{
+ u8 mode = 0;
+ int mem_sttime;
+ int mem_stcfg;
+ unsigned long flags;
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+ struct hd_driveid *id = drive->id;
+
+ /*
+ * Now see what the current drive is capable of,
+ * selecting UDMA only if the mate said it was ok.
+ */
+ if (id && (id->capability & 1) && drive->autodma &&
+ !__ide_dma_bad_drive(drive)) {
+ if (!mode && (id->field_valid & 2) && (id->dma_mword & 7)) {
+ if (id->dma_mword & 4)
+ mode = XFER_MW_DMA_2;
+ else if (id->dma_mword & 2)
+ mode = XFER_MW_DMA_1;
+ else if (id->dma_mword & 1)
+ mode = XFER_MW_DMA_0;
+ }
+ }
+#endif
+
+ spin_lock_irqsave(&ide_tune_chipset_spin_lock, flags);
+
+ mem_sttime = 0;
+ mem_stcfg = au_readl(MEM_STCFG2);
+
+ switch(speed) {
+ case XFER_PIO_4:
+ case XFER_PIO_3:
+ case XFER_PIO_2:
+ case XFER_PIO_1:
+ case XFER_PIO_0:
+ auide_tune_drive(drive, (speed - XFER_PIO_0));
+ break;
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+ case XFER_MW_DMA_2:
+ /* set timing parameters for RCS2# */
+ mem_sttime = SBC_IDE_MDMA2_TWCS
+ | SBC_IDE_MDMA2_TCSH
+ | SBC_IDE_MDMA2_TCSOFF
+ | SBC_IDE_MDMA2_TWP
+ | SBC_IDE_MDMA2_TCSW
+ | SBC_IDE_MDMA2_TPM
+ | SBC_IDE_MDMA2_TA;
+ /* set configuration for RCS2# */
+ mem_stcfg &= ~TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_MDMA2_TCSOE | SBC_IDE_MDMA2_TOECS;
+
+ mode = XFER_MW_DMA_2;
+ break;
+ case XFER_MW_DMA_1:
+ /* set timing parameters for RCS2# */
+ mem_sttime = SBC_IDE_MDMA1_TWCS
+ | SBC_IDE_MDMA1_TCSH
+ | SBC_IDE_MDMA1_TCSOFF
+ | SBC_IDE_MDMA1_TWP
+ | SBC_IDE_MDMA1_TCSW
+ | SBC_IDE_MDMA1_TPM
+ | SBC_IDE_MDMA1_TA;
+ /* set configuration for RCS2# */
+ mem_stcfg &= ~TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_MDMA1_TCSOE | SBC_IDE_MDMA1_TOECS;
+
+ mode = XFER_MW_DMA_1;
+ break;
+ case XFER_MW_DMA_0:
+ /* set timing parameters for RCS2# */
+ mem_sttime = SBC_IDE_MDMA0_TWCS
+ | SBC_IDE_MDMA0_TCSH
+ | SBC_IDE_MDMA0_TCSOFF
+ | SBC_IDE_MDMA0_TWP
+ | SBC_IDE_MDMA0_TCSW
+ | SBC_IDE_MDMA0_TPM
+ | SBC_IDE_MDMA0_TA;
+ /* set configuration for RCS2# */
+ mem_stcfg |= TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_MDMA0_TCSOE | SBC_IDE_MDMA0_TOECS;
+
+ mode = XFER_MW_DMA_0;
+ break;
+#endif
+ default:
+ return 1;
+ }
+
+ /*
+ * Tell the drive to switch to the new mode; abort on failure.
+ */
+ if (!mode || ide_config_drive_speed(drive, mode))
+ {
+ return 1; /* failure */
+ }
+
+
+ au_writel(mem_sttime,MEM_STTIME2);
+ au_writel(mem_stcfg,MEM_STCFG2);
+
+ spin_unlock_irqrestore(&ide_tune_chipset_spin_lock, flags);
+
+ return 0;
+}
+
+/*
+ * Multi-Word DMA + DbDMA functions
+ */
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+
+static int in_drive_list(struct hd_driveid *id,
+ const struct drive_list_entry *drive_table)
+{
+ for ( ; drive_table->id_model ; drive_table++){
+ if ((!strcmp(drive_table->id_model, id->model)) &&
+ ((strstr(drive_table->id_firmware, id->fw_rev)) ||
+ (!strcmp(drive_table->id_firmware, "ALL")))
+ )
+ return 1;
+ }
+ return 0;
+}
+
+static int auide_build_sglist(ide_drive_t *drive, struct request *rq)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
+ struct scatterlist *sg = hwif->sg_table;
+
+ ide_map_sg(drive, rq);
+
+ if (rq_data_dir(rq) == READ)
+ hwif->sg_dma_direction = DMA_FROM_DEVICE;
+ else
+ hwif->sg_dma_direction = DMA_TO_DEVICE;
+
+ return dma_map_sg(ahwif->dev, sg, hwif->sg_nents,
+ hwif->sg_dma_direction);
+}
+
+static int auide_build_dmatable(ide_drive_t *drive)
+{
+ int i, iswrite, count = 0;
+ ide_hwif_t *hwif = HWIF(drive);
+
+ struct request *rq = HWGROUP(drive)->rq;
+
+ _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
+ struct scatterlist *sg;
+
+ iswrite = (rq_data_dir(rq) == WRITE);
+ /* Save for interrupt context */
+ ahwif->drive = drive;
+
+ /* Build sglist */
+ hwif->sg_nents = i = auide_build_sglist(drive, rq);
+
+ if (!i)
+ return 0;
+
+ /* fill the descriptors */
+ sg = hwif->sg_table;
+ while (i && sg_dma_len(sg)) {
+ u32 cur_addr;
+ u32 cur_len;
+
+ cur_addr = sg_dma_address(sg);
+ cur_len = sg_dma_len(sg);
+
+ while (cur_len) {
+ u32 flags = DDMA_FLAGS_NOIE;
+ unsigned int tc = (cur_len < 0xfe00)? cur_len: 0xfe00;
+
+ if (++count >= PRD_ENTRIES) {
+ printk(KERN_WARNING "%s: DMA table too small\n",
+ drive->name);
+ goto use_pio_instead;
+ }
+
+ /* Lets enable intr for the last descriptor only */
+ if (1==i)
+ flags = DDMA_FLAGS_IE;
+ else
+ flags = DDMA_FLAGS_NOIE;
+
+ if (iswrite) {
+ if(!put_source_flags(ahwif->tx_chan,
+ (void*)(page_address(sg->page)
+ + sg->offset),
+ tc, flags)) {
+ printk(KERN_ERR "%s failed %d\n",
+ __FUNCTION__, __LINE__);
+ }
+ } else
+ {
+ if(!put_dest_flags(ahwif->rx_chan,
+ (void*)(page_address(sg->page)
+ + sg->offset),
+ tc, flags)) {
+ printk(KERN_ERR "%s failed %d\n",
+ __FUNCTION__, __LINE__);
+ }
+ }
+
+ cur_addr += tc;
+ cur_len -= tc;
+ }
+ sg++;
+ i--;
+ }
+
+ if (count)
+ return 1;
+
+use_pio_instead:
+ dma_unmap_sg(ahwif->dev,
+ hwif->sg_table,
+ hwif->sg_nents,
+ hwif->sg_dma_direction);
+
+ return 0; /* revert to PIO for this request */
+}
+
+static int auide_dma_end(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = HWIF(drive);
+ _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
+
+ if (hwif->sg_nents) {
+ dma_unmap_sg(ahwif->dev, hwif->sg_table, hwif->sg_nents,
+ hwif->sg_dma_direction);
+ hwif->sg_nents = 0;
+ }
+
+ return 0;
+}
+
+static void auide_dma_start(ide_drive_t *drive )
+{
+// printk("%s\n", __FUNCTION__);
+}
+
+ide_startstop_t auide_dma_intr(ide_drive_t *drive)
+{
+ //printk("%s\n", __FUNCTION__);
+
+ u8 stat = 0, dma_stat = 0;
+
+ dma_stat = HWIF(drive)->ide_dma_end(drive);
+ stat = HWIF(drive)->INB(IDE_STATUS_REG); /* get drive status */
+ if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
+ if (!dma_stat) {
+ struct request *rq = HWGROUP(drive)->rq;
+
+ ide_end_request(drive, 1, rq->nr_sectors);
+ return ide_stopped;
+ }
+ printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n",
+ drive->name, dma_stat);
+ }
+ return ide_error(drive, "dma_intr", stat);
+}
+
+static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command)
+{
+ //printk("%s\n", __FUNCTION__);
+
+ /* issue cmd to drive */
+ ide_execute_command(drive, command, &auide_dma_intr,
+ (2*WAIT_CMD), NULL);
+}
+
+static int auide_dma_setup(ide_drive_t *drive)
+{
+// printk("%s\n", __FUNCTION__);
+
+ if (drive->media != ide_disk)
+ return 1;
+
+ if (!auide_build_dmatable(drive))
+ /* try PIO instead of DMA */
+ return 1;
+
+ drive->waiting_for_dma = 1;
+
+ return 0;
+}
+
+static int auide_dma_check(ide_drive_t *drive)
+{
+// printk("%s\n", __FUNCTION__);
+
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+ if( !dbdma_init_done ){
+ auide_hwif.white_list = in_drive_list(drive->id,
+ dma_white_list);
+ auide_hwif.black_list = in_drive_list(drive->id,
+ dma_black_list);
+ auide_hwif.drive = drive;
+ auide_ddma_init(&auide_hwif);
+ dbdma_init_done = 1;
+ }
+#endif
+
+ /* Is the drive in our DMA black list? */
+ if ( auide_hwif.black_list ) {
+ drive->using_dma = 0;
+ printk("%s found in dma_blacklist[]! Disabling DMA.\n",
+ drive->id->model);
+ }
+ else
+ drive->using_dma = 1;
+
+ return HWIF(drive)->ide_dma_host_on(drive);
+}
+
+static int auide_dma_test_irq(ide_drive_t *drive)
+{
+// printk("%s\n", __FUNCTION__);
+
+ if (!drive->waiting_for_dma)
+ printk(KERN_WARNING "%s: ide_dma_test_irq \
+ called while not waiting\n", drive->name);
+
+ /* If dbdma didn't execute the STOP command yet, the
+ * active bit is still set
+ */
+ drive->waiting_for_dma++;
+ if (drive->waiting_for_dma >= DMA_WAIT_TIMEOUT) {
+ printk(KERN_WARNING "%s: timeout waiting for ddma to \
+ complete\n", drive->name);
+ return 1;
+ }
+ udelay(10);
+ return 0;
+}
+
+static int auide_dma_host_on(ide_drive_t *drive)
+{
+// printk("%s\n", __FUNCTION__);
+ return 0;
+}
+
+static int auide_dma_on(ide_drive_t *drive)
+{
+// printk("%s\n", __FUNCTION__);
+ drive->using_dma = 1;
+ return auide_dma_host_on(drive);
+}
+
+
+static int auide_dma_host_off(ide_drive_t *drive)
+{
+// printk("%s\n", __FUNCTION__);
+ return 0;
+}
+
+static int auide_dma_off_quietly(ide_drive_t *drive)
+{
+// printk("%s\n", __FUNCTION__);
+ drive->using_dma = 0;
+ return auide_dma_host_off(drive);
+}
+
+static int auide_dma_lostirq(ide_drive_t *drive)
+{
+// printk("%s\n", __FUNCTION__);
+
+ printk(KERN_ERR "%s: IRQ lost\n", drive->name);
+ return 0;
+}
+
+static void auide_ddma_tx_callback(int irq, void *param, struct pt_regs *regs)
+{
+// printk("%s\n", __FUNCTION__);
+
+ _auide_hwif *ahwif = (_auide_hwif*)param;
+ ahwif->drive->waiting_for_dma = 0;
+ return;
+}
+
+static void auide_ddma_rx_callback(int irq, void *param, struct pt_regs *regs)
+{
+// printk("%s\n", __FUNCTION__);
+
+ _auide_hwif *ahwif = (_auide_hwif*)param;
+ ahwif->drive->waiting_for_dma = 0;
+ return;
+}
+
+static int auide_dma_timeout(ide_drive_t *drive)
+{
+// printk("%s\n", __FUNCTION__);
+
+ printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name);
+
+ if (HWIF(drive)->ide_dma_test_irq(drive))
+ return 0;
+
+ return HWIF(drive)->ide_dma_end(drive);
+}
+#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
+
+
+static int auide_ddma_init( _auide_hwif *auide )
+{
+// printk("%s\n", __FUNCTION__);
+
+ dbdev_tab_t source_dev_tab;
+#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
+ dbdev_tab_t target_dev_tab;
+ ide_hwif_t *hwif = auide->hwif;
+ char warning_output [2][80];
+ int i;
+#endif
+
+ /* Add our custom device to DDMA device table */
+ /* Create our new device entries in the table */
+#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
+ source_dev_tab.dev_id = AU1XXX_ATA_DDMA_REQ;
+
+ if( auide->white_list || auide->black_list ){
+ source_dev_tab.dev_tsize = 8;
+ source_dev_tab.dev_devwidth = 32;
+ source_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR;
+ source_dev_tab.dev_intlevel = 0;
+ source_dev_tab.dev_intpolarity = 0;
+
+ /* init device table for target - static bus controller - */
+ target_dev_tab.dev_id = DSCR_CMD0_ALWAYS;
+ target_dev_tab.dev_tsize = 8;
+ target_dev_tab.dev_devwidth = 32;
+ target_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR;
+ target_dev_tab.dev_intlevel = 0;
+ target_dev_tab.dev_intpolarity = 0;
+ target_dev_tab.dev_flags = DEV_FLAGS_ANYUSE;
+ }
+ else{
+ source_dev_tab.dev_tsize = 1;
+ source_dev_tab.dev_devwidth = 16;
+ source_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR;
+ source_dev_tab.dev_intlevel = 0;
+ source_dev_tab.dev_intpolarity = 0;
+
+ /* init device table for target - static bus controller - */
+ target_dev_tab.dev_id = DSCR_CMD0_ALWAYS;
+ target_dev_tab.dev_tsize = 1;
+ target_dev_tab.dev_devwidth = 16;
+ target_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR;
+ target_dev_tab.dev_intlevel = 0;
+ target_dev_tab.dev_intpolarity = 0;
+ target_dev_tab.dev_flags = DEV_FLAGS_ANYUSE;
+
+ sprintf(&warning_output[0][0],
+ "%s is not on ide driver white list.",
+ auide_hwif.drive->id->model);
+ for ( i=strlen(&warning_output[0][0]) ; i<76; i++ ){
+ sprintf(&warning_output[0][i]," ");
+ }
+
+ sprintf(&warning_output[1][0],
+ "To add %s please read 'Documentation/mips/AU1xxx_IDE.README'.",
+ auide_hwif.drive->id->model);
+ for ( i=strlen(&warning_output[1][0]) ; i<76; i++ ){
+ sprintf(&warning_output[1][i]," ");
+ }
+
+ printk("\n****************************************");
+ printk("****************************************\n");
+ printk("* %s *\n",&warning_output[0][0]);
+ printk("* Switch to safe MWDMA Mode! ");
+ printk(" *\n");
+ printk("* %s *\n",&warning_output[1][0]);
+ printk("****************************************");
+ printk("****************************************\n\n");
+ }
+#else
+ source_dev_tab.dev_id = DSCR_CMD0_ALWAYS;
+ source_dev_tab.dev_tsize = 8;
+ source_dev_tab.dev_devwidth = 32;
+ source_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR;
+ source_dev_tab.dev_intlevel = 0;
+ source_dev_tab.dev_intpolarity = 0;
+#endif
+
+#if CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON
+ /* set flags for tx channel */
+ source_dev_tab.dev_flags = DEV_FLAGS_OUT
+ | DEV_FLAGS_SYNC
+ | DEV_FLAGS_BURSTABLE;
+ auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
+ /* set flags for rx channel */
+ source_dev_tab.dev_flags = DEV_FLAGS_IN
+ | DEV_FLAGS_SYNC
+ | DEV_FLAGS_BURSTABLE;
+ auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
+#else
+ /* set flags for tx channel */
+ source_dev_tab.dev_flags = DEV_FLAGS_OUT | DEV_FLAGS_SYNC;
+ auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
+ /* set flags for rx channel */
+ source_dev_tab.dev_flags = DEV_FLAGS_IN | DEV_FLAGS_SYNC;
+ auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
+#endif
+
+#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
+
+ auide->target_dev_id = au1xxx_ddma_add_device(&target_dev_tab);
+
+ /* Get a channel for TX */
+ auide->tx_chan = au1xxx_dbdma_chan_alloc(auide->target_dev_id,
+ auide->tx_dev_id,
+ auide_ddma_tx_callback,
+ (void*)auide);
+ /* Get a channel for RX */
+ auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id,
+ auide->target_dev_id,
+ auide_ddma_rx_callback,
+ (void*)auide);
+#else /* CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA */
+ /*
+ * Note: if call back is not enabled, update ctp->cur_ptr manually
+ */
+ auide->tx_chan = au1xxx_dbdma_chan_alloc(DSCR_CMD0_ALWAYS,
+ auide->tx_dev_id,
+ NULL,
+ (void*)auide);
+ auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id,
+ DSCR_CMD0_ALWAYS,
+ NULL,
+ (void*)auide);
+#endif
+ auide->tx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->tx_chan,
+ NUM_DESCRIPTORS);
+ auide->rx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->rx_chan,
+ NUM_DESCRIPTORS);
+
+#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
+ hwif->dmatable_cpu = dma_alloc_coherent(auide->dev,
+ PRD_ENTRIES * PRD_BYTES, /* 1 Page */
+ &hwif->dmatable_dma, GFP_KERNEL);
+
+ auide->sg_table = kmalloc(sizeof(struct scatterlist) * PRD_ENTRIES,
+ GFP_KERNEL|GFP_DMA);
+ if (auide->sg_table == NULL) {
+ return -ENOMEM;
+ }
+#endif
+ au1xxx_dbdma_start( auide->tx_chan );
+ au1xxx_dbdma_start( auide->rx_chan );
+ return 0;
+}
+
+static void auide_setup_ports(hw_regs_t *hw, _auide_hwif *ahwif)
+{
+ int i;
+#define ide_ioreg_t unsigned long
+ ide_ioreg_t *ata_regs = hw->io_ports;
+
+ /* fixme */
+ for (i = 0; i < IDE_CONTROL_OFFSET; i++) {
+ *ata_regs++ = (ide_ioreg_t) ahwif->regbase
+ + (ide_ioreg_t)(i << AU1XXX_ATA_REG_OFFSET);
+ }
+
+ /* set the Alternative Status register */
+ *ata_regs = (ide_ioreg_t) ahwif->regbase
+ + (ide_ioreg_t)(14 << AU1XXX_ATA_REG_OFFSET);
+}
+
+static int au_ide_probe(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ _auide_hwif *ahwif = &auide_hwif;
+ ide_hwif_t *hwif;
+ struct resource *res;
+ int ret = 0;
+
+#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
+ char *mode = "MWDMA2";
+#elif defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
+ char *mode = "PIO+DDMA(offload)";
+#endif
+
+ memset(&auide_hwif, 0, sizeof(_auide_hwif));
+ auide_hwif.dev = 0;
+
+ ahwif->dev = dev;
+ ahwif->irq = platform_get_irq(pdev, 0);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ if (res == NULL) {
+ pr_debug("%s %d: no base address\n", DRV_NAME, pdev->id);
+ ret = -ENODEV;
+ goto out;
+ }
+
+ if (!request_mem_region (res->start, res->end-res->start, pdev->name)) {
+ pr_debug("%s: request_mem_region failed\n", DRV_NAME);
+ ret = -EBUSY;
+ goto out;
+ }
+
+ ahwif->regbase = (u32)ioremap(res->start, res->end-res->start);
+ if (ahwif->regbase == 0) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ hwif = &ide_hwifs[pdev->id];
+ hw_regs_t *hw = &hwif->hw;
+ hwif->irq = hw->irq = ahwif->irq;
+ hwif->chipset = ide_au1xxx;
+
+ auide_setup_ports(hw, ahwif);
+ memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports));
+
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ
+ hwif->rqsize = CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ;
+ hwif->rqsize = ((hwif->rqsize > AU1XXX_ATA_RQSIZE)
+ || (hwif->rqsize < 32)) ? AU1XXX_ATA_RQSIZE : hwif->rqsize;
+#else /* if kernel config is not set */
+ hwif->rqsize = AU1XXX_ATA_RQSIZE;
+#endif
+
+ hwif->ultra_mask = 0x0; /* Disable Ultra DMA */
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+ hwif->mwdma_mask = 0x07; /* Multimode-2 DMA */
+ hwif->swdma_mask = 0x07;
+#else
+ hwif->mwdma_mask = 0x0;
+ hwif->swdma_mask = 0x0;
+#endif
+ //hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
+ hwif->noprobe = 0;
+ hwif->drives[0].unmask = 1;
+ hwif->drives[1].unmask = 1;
+
+ /* hold should be on in all cases */
+ hwif->hold = 1;
+ hwif->mmio = 2;
+
+ /* set up local I/O function entry points */
+ hwif->INB = auide_inb;
+ hwif->INW = auide_inw;
+ hwif->INL = auide_inl;
+ hwif->INSW = auide_insw;
+ hwif->INSL = auide_insl;
+ hwif->OUTB = auide_outb;
+ hwif->OUTBSYNC = auide_outbsync;
+ hwif->OUTW = auide_outw;
+ hwif->OUTL = auide_outl;
+ hwif->OUTSW = auide_outsw;
+ hwif->OUTSL = auide_outsl;
+
+ hwif->tuneproc = &auide_tune_drive;
+ hwif->speedproc = &auide_tune_chipset;
+
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+ hwif->ide_dma_off_quietly = &auide_dma_off_quietly;
+ hwif->ide_dma_timeout = &auide_dma_timeout;
+
+ hwif->ide_dma_check = &auide_dma_check;
+ hwif->dma_exec_cmd = &auide_dma_exec_cmd;
+ hwif->dma_start = &auide_dma_start;
+ hwif->ide_dma_end = &auide_dma_end;
+ hwif->dma_setup = &auide_dma_setup;
+ hwif->ide_dma_test_irq = &auide_dma_test_irq;
+ hwif->ide_dma_host_off = &auide_dma_host_off;
+ hwif->ide_dma_host_on = &auide_dma_host_on;
+ hwif->ide_dma_lostirq = &auide_dma_lostirq;
+ hwif->ide_dma_on = &auide_dma_on;
+
+ hwif->autodma = 1;
+ hwif->drives[0].autodma = hwif->autodma;
+ hwif->drives[1].autodma = hwif->autodma;
+ hwif->atapi_dma = 1;
+ hwif->drives[0].using_dma = 1;
+ hwif->drives[1].using_dma = 1;
+#else /* !CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
+ hwif->autodma = 0;
+ hwif->channel = 0;
+ hwif->hold = 1;
+ hwif->select_data = 0; /* no chipset-specific code */
+ hwif->config_data = 0; /* no chipset-specific code */
+
+ hwif->drives[0].autodma = 0;
+ hwif->drives[0].drive_data = 0; /* no drive data */
+ hwif->drives[0].using_dma = 0;
+ hwif->drives[0].waiting_for_dma = 0;
+ hwif->drives[0].autotune = 1; /* 1=autotune, 2=noautotune, 0=default */
+ /* secondary hdd not supported */
+ hwif->drives[1].autodma = 0;
+
+ hwif->drives[1].drive_data = 0;
+ hwif->drives[1].using_dma = 0;
+ hwif->drives[1].waiting_for_dma = 0;
+ hwif->drives[1].autotune = 2; /* 1=autotune, 2=noautotune, 0=default */
+#endif
+ hwif->drives[0].io_32bit = 0; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */
+ hwif->drives[1].io_32bit = 0; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */
+
+ /*Register Driver with PM Framework*/
+#ifdef CONFIG_PM
+ auide_hwif.pm.lock = SPIN_LOCK_UNLOCKED;
+ auide_hwif.pm.stopped = 0;
+
+ auide_hwif.pm.dev = new_au1xxx_power_device( "ide",
+ &au1200ide_pm_callback,
+ NULL);
+ if ( auide_hwif.pm.dev == NULL )
+ printk(KERN_INFO "Unable to create a power management \
+ device entry for the au1200-IDE.\n");
+ else
+ printk(KERN_INFO "Power management device entry for the \
+ au1200-IDE loaded.\n");
+#endif
+
+ auide_hwif.hwif = hwif;
+ hwif->hwif_data = &auide_hwif;
+
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA
+ auide_ddma_init(&auide_hwif);
+ dbdma_init_done = 1;
+#endif
+
+ probe_hwif_init(hwif);
+ dev_set_drvdata(dev, hwif);
+
+ printk(KERN_INFO "Au1xxx IDE(builtin) configured for %s\n", mode );
+
+out:
+ return ret;
+}
+
+static int au_ide_remove(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct resource *res;
+ ide_hwif_t *hwif = dev_get_drvdata(dev);
+ _auide_hwif *ahwif = &auide_hwif;
+
+ ide_unregister(hwif - ide_hwifs);
+
+ iounmap((void *)ahwif->regbase);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(res->start, res->end - res->start);
+
+ return 0;
+}
+
+static struct device_driver au1200_ide_driver = {
+ .name = "au1200-ide",
+ .bus = &platform_bus_type,
+ .probe = au_ide_probe,
+ .remove = au_ide_remove,
+};
+
+static int __init au_ide_init(void)
+{
+ return driver_register(&au1200_ide_driver);
+}
+
+static void __init au_ide_exit(void)
+{
+ driver_unregister(&au1200_ide_driver);
+}
+
+#ifdef CONFIG_PM
+int au1200ide_pm_callback( au1xxx_power_dev_t *dev,\
+ au1xxx_request_t request, void *data) {
+
+ unsigned int d, err = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(auide_hwif.pm.lock, flags);
+
+ switch (request){
+ case AU1XXX_PM_SLEEP:
+ err = au1xxxide_pm_sleep(dev);
+ break;
+ case AU1XXX_PM_WAKEUP:
+ d = *((unsigned int*)data);
+ if ( d > 0 && d <= 99) {
+ err = au1xxxide_pm_standby(dev);
+ }
+ else {
+ err = au1xxxide_pm_resume(dev);
+ }
+ break;
+ case AU1XXX_PM_GETSTATUS:
+ err = au1xxxide_pm_getstatus(dev);
+ break;
+ case AU1XXX_PM_ACCESS:
+ err = au1xxxide_pm_access(dev);
+ break;
+ case AU1XXX_PM_IDLE:
+ err = au1xxxide_pm_idle(dev);
+ break;
+ case AU1XXX_PM_CLEANUP:
+ err = au1xxxide_pm_cleanup(dev);
+ break;
+ default:
+ err = -1;
+ break;
+ }
+
+ spin_unlock_irqrestore(auide_hwif.pm.lock, flags);
+
+ return err;
+}
+
+static int au1xxxide_pm_standby( au1xxx_power_dev_t *dev ) {
+ return 0;
+}
+
+static int au1xxxide_pm_sleep( au1xxx_power_dev_t *dev ) {
+
+ int retval;
+ ide_hwif_t *hwif = auide_hwif.hwif;
+ struct request rq;
+ struct request_pm_state rqpm;
+ ide_task_t args;
+
+ if(auide_hwif.pm.stopped)
+ return -1;
+
+ /*
+ * wait until hard disc is ready
+ */
+ if ( wait_for_ready(&hwif->drives[0], 35000) ) {
+ printk("Wait for drive sleep timeout!\n");
+ retval = -1;
+ }
+
+ /*
+ * sequenz to tell the high level ide driver that pm is resuming
+ */
+ memset(&rq, 0, sizeof(rq));
+ memset(&rqpm, 0, sizeof(rqpm));
+ memset(&args, 0, sizeof(args));
+ rq.flags = REQ_PM_SUSPEND;
+ rq.special = &args;
+ rq.pm = &rqpm;
+ rqpm.pm_step = ide_pm_state_start_suspend;
+ rqpm.pm_state = PMSG_SUSPEND;
+
+ retval = ide_do_drive_cmd(&hwif->drives[0], &rq, ide_wait);
+
+ if (wait_for_ready (&hwif->drives[0], 35000)) {
+ printk("Wait for drive sleep timeout!\n");
+ retval = -1;
+ }
+
+ /*
+ * stop dbdma channels
+ */
+ au1xxx_dbdma_reset(auide_hwif.tx_chan);
+ au1xxx_dbdma_reset(auide_hwif.rx_chan);
+
+ auide_hwif.pm.stopped = 1;
+
+ return retval;
+}
+
+static int au1xxxide_pm_resume( au1xxx_power_dev_t *dev ) {
+
+ int retval;
+ ide_hwif_t *hwif = auide_hwif.hwif;
+ struct request rq;
+ struct request_pm_state rqpm;
+ ide_task_t args;
+
+ if(!auide_hwif.pm.stopped)
+ return -1;
+
+ /*
+ * start dbdma channels
+ */
+ au1xxx_dbdma_start(auide_hwif.tx_chan);
+ au1xxx_dbdma_start(auide_hwif.rx_chan);
+
+ /*
+ * wait until hard disc is ready
+ */
+ if (wait_for_ready ( &hwif->drives[0], 35000)) {
+ printk("Wait for drive wake up timeout!\n");
+ retval = -1;
+ }
+
+ /*
+ * sequenz to tell the high level ide driver that pm is resuming
+ */
+ memset(&rq, 0, sizeof(rq));
+ memset(&rqpm, 0, sizeof(rqpm));
+ memset(&args, 0, sizeof(args));
+ rq.flags = REQ_PM_RESUME;
+ rq.special = &args;
+ rq.pm = &rqpm;
+ rqpm.pm_step = ide_pm_state_start_resume;
+ rqpm.pm_state = PMSG_ON;
+
+ retval = ide_do_drive_cmd(&hwif->drives[0], &rq, ide_head_wait);
+
+ /*
+ * wait for hard disc
+ */
+ if ( wait_for_ready(&hwif->drives[0], 35000) ) {
+ printk("Wait for drive wake up timeout!\n");
+ retval = -1;
+ }
+
+ auide_hwif.pm.stopped = 0;
+
+ return retval;
+}
+
+static int au1xxxide_pm_getstatus( au1xxx_power_dev_t *dev ) {
+ return dev->cur_state;
+}
+
+static int au1xxxide_pm_access( au1xxx_power_dev_t *dev ) {
+ if (dev->cur_state != AWAKE_STATE)
+ return 0;
+ else
+ return -1;
+}
+
+static int au1xxxide_pm_idle( au1xxx_power_dev_t *dev ) {
+ return 0;
+}
+
+static int au1xxxide_pm_cleanup( au1xxx_power_dev_t *dev ) {
+ return 0;
+}
+#endif /* CONFIG_PM */
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("AU1200 IDE driver");
+
+module_init(au_ide_init);
+module_exit(au_ide_exit);
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index 87d1f8a1f41e..d8c3d8ebad30 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -81,7 +81,7 @@ typedef struct pmac_ide_hwif {
} pmac_ide_hwif_t;
-static pmac_ide_hwif_t pmac_ide[MAX_HWIFS] __pmacdata;
+static pmac_ide_hwif_t pmac_ide[MAX_HWIFS];
static int pmac_ide_count;
enum {
@@ -242,7 +242,7 @@ struct mdma_timings_t {
int cycleTime;
};
-struct mdma_timings_t mdma_timings_33[] __pmacdata =
+struct mdma_timings_t mdma_timings_33[] =
{
{ 240, 240, 480 },
{ 180, 180, 360 },
@@ -255,7 +255,7 @@ struct mdma_timings_t mdma_timings_33[] __pmacdata =
{ 0, 0, 0 }
};
-struct mdma_timings_t mdma_timings_33k[] __pmacdata =
+struct mdma_timings_t mdma_timings_33k[] =
{
{ 240, 240, 480 },
{ 180, 180, 360 },
@@ -268,7 +268,7 @@ struct mdma_timings_t mdma_timings_33k[] __pmacdata =
{ 0, 0, 0 }
};
-struct mdma_timings_t mdma_timings_66[] __pmacdata =
+struct mdma_timings_t mdma_timings_66[] =
{
{ 240, 240, 480 },
{ 180, 180, 360 },
@@ -286,7 +286,7 @@ struct {
int addrSetup; /* ??? */
int rdy2pause;
int wrDataSetup;
-} kl66_udma_timings[] __pmacdata =
+} kl66_udma_timings[] =
{
{ 0, 180, 120 }, /* Mode 0 */
{ 0, 150, 90 }, /* 1 */
@@ -301,7 +301,7 @@ struct kauai_timing {
u32 timing_reg;
};
-static struct kauai_timing kauai_pio_timings[] __pmacdata =
+static struct kauai_timing kauai_pio_timings[] =
{
{ 930 , 0x08000fff },
{ 600 , 0x08000a92 },
@@ -316,7 +316,7 @@ static struct kauai_timing kauai_pio_timings[] __pmacdata =
{ 120 , 0x04000148 }
};
-static struct kauai_timing kauai_mdma_timings[] __pmacdata =
+static struct kauai_timing kauai_mdma_timings[] =
{
{ 1260 , 0x00fff000 },
{ 480 , 0x00618000 },
@@ -330,7 +330,7 @@ static struct kauai_timing kauai_mdma_timings[] __pmacdata =
{ 0 , 0 },
};
-static struct kauai_timing kauai_udma_timings[] __pmacdata =
+static struct kauai_timing kauai_udma_timings[] =
{
{ 120 , 0x000070c0 },
{ 90 , 0x00005d80 },
@@ -341,7 +341,7 @@ static struct kauai_timing kauai_udma_timings[] __pmacdata =
{ 0 , 0 },
};
-static struct kauai_timing shasta_pio_timings[] __pmacdata =
+static struct kauai_timing shasta_pio_timings[] =
{
{ 930 , 0x08000fff },
{ 600 , 0x0A000c97 },
@@ -356,7 +356,7 @@ static struct kauai_timing shasta_pio_timings[] __pmacdata =
{ 120 , 0x0400010a }
};
-static struct kauai_timing shasta_mdma_timings[] __pmacdata =
+static struct kauai_timing shasta_mdma_timings[] =
{
{ 1260 , 0x00fff000 },
{ 480 , 0x00820800 },
@@ -370,7 +370,7 @@ static struct kauai_timing shasta_mdma_timings[] __pmacdata =
{ 0 , 0 },
};
-static struct kauai_timing shasta_udma133_timings[] __pmacdata =
+static struct kauai_timing shasta_udma133_timings[] =
{
{ 120 , 0x00035901, },
{ 90 , 0x000348b1, },
@@ -522,7 +522,7 @@ pmu_hd_blink_init(void)
* N.B. this can't be an initfunc, because the media-bay task can
* call ide_[un]register at any time.
*/
-void __pmac
+void
pmac_ide_init_hwif_ports(hw_regs_t *hw,
unsigned long data_port, unsigned long ctrl_port,
int *irq)
@@ -559,7 +559,7 @@ pmac_ide_init_hwif_ports(hw_regs_t *hw,
* timing register when selecting that unit. This version is for
* ASICs with a single timing register
*/
-static void __pmac
+static void
pmac_ide_selectproc(ide_drive_t *drive)
{
pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
@@ -579,7 +579,7 @@ pmac_ide_selectproc(ide_drive_t *drive)
* timing register when selecting that unit. This version is for
* ASICs with a dual timing register (Kauai)
*/
-static void __pmac
+static void
pmac_ide_kauai_selectproc(ide_drive_t *drive)
{
pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
@@ -600,7 +600,7 @@ pmac_ide_kauai_selectproc(ide_drive_t *drive)
/*
* Force an update of controller timing values for a given drive
*/
-static void __pmac
+static void
pmac_ide_do_update_timings(ide_drive_t *drive)
{
pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
@@ -633,7 +633,7 @@ pmac_outbsync(ide_drive_t *drive, u8 value, unsigned long port)
* to sort that out sooner or later and see if I can finally get the
* common version to work properly in all cases
*/
-static int __pmac
+static int
pmac_ide_do_setfeature(ide_drive_t *drive, u8 command)
{
ide_hwif_t *hwif = HWIF(drive);
@@ -710,7 +710,7 @@ out:
/*
* Old tuning functions (called on hdparm -p), sets up drive PIO timings
*/
-static void __pmac
+static void
pmac_ide_tuneproc(ide_drive_t *drive, u8 pio)
{
ide_pio_data_t d;
@@ -801,7 +801,7 @@ pmac_ide_tuneproc(ide_drive_t *drive, u8 pio)
/*
* Calculate KeyLargo ATA/66 UDMA timings
*/
-static int __pmac
+static int
set_timings_udma_ata4(u32 *timings, u8 speed)
{
unsigned rdyToPauseTicks, wrDataSetupTicks, addrTicks;
@@ -829,7 +829,7 @@ set_timings_udma_ata4(u32 *timings, u8 speed)
/*
* Calculate Kauai ATA/100 UDMA timings
*/
-static int __pmac
+static int
set_timings_udma_ata6(u32 *pio_timings, u32 *ultra_timings, u8 speed)
{
struct ide_timing *t = ide_timing_find_mode(speed);
@@ -849,7 +849,7 @@ set_timings_udma_ata6(u32 *pio_timings, u32 *ultra_timings, u8 speed)
/*
* Calculate Shasta ATA/133 UDMA timings
*/
-static int __pmac
+static int
set_timings_udma_shasta(u32 *pio_timings, u32 *ultra_timings, u8 speed)
{
struct ide_timing *t = ide_timing_find_mode(speed);
@@ -869,7 +869,7 @@ set_timings_udma_shasta(u32 *pio_timings, u32 *ultra_timings, u8 speed)
/*
* Calculate MDMA timings for all cells
*/
-static int __pmac
+static int
set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2,
u8 speed, int drive_cycle_time)
{
@@ -1014,7 +1014,7 @@ set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2,
* our dedicated function is more precise as it uses the drive provided
* cycle time value. We should probably fix this one to deal with that too...
*/
-static int __pmac
+static int
pmac_ide_tune_chipset (ide_drive_t *drive, byte speed)
{
int unit = (drive->select.b.unit & 0x01);
@@ -1092,7 +1092,7 @@ pmac_ide_tune_chipset (ide_drive_t *drive, byte speed)
* Blast some well known "safe" values to the timing registers at init or
* wakeup from sleep time, before we do real calculation
*/
-static void __pmac
+static void
sanitize_timings(pmac_ide_hwif_t *pmif)
{
unsigned int value, value2 = 0;
@@ -1123,13 +1123,13 @@ sanitize_timings(pmac_ide_hwif_t *pmif)
pmif->timings[2] = pmif->timings[3] = value2;
}
-unsigned long __pmac
+unsigned long
pmac_ide_get_base(int index)
{
return pmac_ide[index].regbase;
}
-int __pmac
+int
pmac_ide_check_base(unsigned long base)
{
int ix;
@@ -1140,7 +1140,7 @@ pmac_ide_check_base(unsigned long base)
return -1;
}
-int __pmac
+int
pmac_ide_get_irq(unsigned long base)
{
int ix;
@@ -1151,7 +1151,7 @@ pmac_ide_get_irq(unsigned long base)
return 0;
}
-static int ide_majors[] __pmacdata = { 3, 22, 33, 34, 56, 57 };
+static int ide_majors[] = { 3, 22, 33, 34, 56, 57 };
dev_t __init
pmac_find_ide_boot(char *bootdevice, int n)
@@ -1701,7 +1701,7 @@ pmac_ide_probe(void)
* pmac_ide_build_dmatable builds the DBDMA command list
* for a transfer and sets the DBDMA channel to point to it.
*/
-static int __pmac
+static int
pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
{
struct dbdma_cmd *table;
@@ -1785,7 +1785,7 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
}
/* Teardown mappings after DMA has completed. */
-static void __pmac
+static void
pmac_ide_destroy_dmatable (ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
@@ -1802,7 +1802,7 @@ pmac_ide_destroy_dmatable (ide_drive_t *drive)
/*
* Pick up best MDMA timing for the drive and apply it
*/
-static int __pmac
+static int
pmac_ide_mdma_enable(ide_drive_t *drive, u16 mode)
{
ide_hwif_t *hwif = HWIF(drive);
@@ -1859,7 +1859,7 @@ pmac_ide_mdma_enable(ide_drive_t *drive, u16 mode)
/*
* Pick up best UDMA timing for the drive and apply it
*/
-static int __pmac
+static int
pmac_ide_udma_enable(ide_drive_t *drive, u16 mode)
{
ide_hwif_t *hwif = HWIF(drive);
@@ -1915,7 +1915,7 @@ pmac_ide_udma_enable(ide_drive_t *drive, u16 mode)
* Check what is the best DMA timing setting for the drive and
* call appropriate functions to apply it.
*/
-static int __pmac
+static int
pmac_ide_dma_check(ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
@@ -1967,7 +1967,7 @@ pmac_ide_dma_check(ide_drive_t *drive)
* Prepare a DMA transfer. We build the DMA table, adjust the timings for
* a read on KeyLargo ATA/66 and mark us as waiting for DMA completion
*/
-static int __pmac
+static int
pmac_ide_dma_setup(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
@@ -1997,7 +1997,7 @@ pmac_ide_dma_setup(ide_drive_t *drive)
return 0;
}
-static void __pmac
+static void
pmac_ide_dma_exec_cmd(ide_drive_t *drive, u8 command)
{
/* issue cmd to drive */
@@ -2008,7 +2008,7 @@ pmac_ide_dma_exec_cmd(ide_drive_t *drive, u8 command)
* Kick the DMA controller into life after the DMA command has been issued
* to the drive.
*/
-static void __pmac
+static void
pmac_ide_dma_start(ide_drive_t *drive)
{
pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
@@ -2024,7 +2024,7 @@ pmac_ide_dma_start(ide_drive_t *drive)
/*
* After a DMA transfer, make sure the controller is stopped
*/
-static int __pmac
+static int
pmac_ide_dma_end (ide_drive_t *drive)
{
pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
@@ -2052,7 +2052,7 @@ pmac_ide_dma_end (ide_drive_t *drive)
* that's not implemented yet), on the other hand, we don't have shared interrupts
* so it's not really a problem
*/
-static int __pmac
+static int
pmac_ide_dma_test_irq (ide_drive_t *drive)
{
pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
@@ -2108,19 +2108,19 @@ pmac_ide_dma_test_irq (ide_drive_t *drive)
return 1;
}
-static int __pmac
+static int
pmac_ide_dma_host_off (ide_drive_t *drive)
{
return 0;
}
-static int __pmac
+static int
pmac_ide_dma_host_on (ide_drive_t *drive)
{
return 0;
}
-static int __pmac
+static int
pmac_ide_dma_lostirq (ide_drive_t *drive)
{
pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
diff --git a/drivers/infiniband/core/agent.h b/drivers/infiniband/core/agent.h
index c5f3cfec942a..86d72fab37b0 100644
--- a/drivers/infiniband/core/agent.h
+++ b/drivers/infiniband/core/agent.h
@@ -39,6 +39,7 @@
#ifndef __AGENT_H_
#define __AGENT_H_
+#include <linux/err.h>
#include <rdma/ib_mad.h>
extern int ib_agent_port_open(struct ib_device *device, int port_num);
diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c
index f014e639088c..c57a3871184c 100644
--- a/drivers/infiniband/core/cache.c
+++ b/drivers/infiniband/core/cache.c
@@ -38,6 +38,7 @@
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/slab.h>
+#include <linux/sched.h> /* INIT_WORK, schedule_work(), flush_scheduled_work() */
#include <rdma/ib_cache.h>
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
index 89ce9dc210d4..acda7d63d6fe 100644
--- a/drivers/infiniband/core/sa_query.c
+++ b/drivers/infiniband/core/sa_query.c
@@ -43,6 +43,7 @@
#include <linux/dma-mapping.h>
#include <linux/kref.h>
#include <linux/idr.h>
+#include <linux/workqueue.h>
#include <rdma/ib_pack.h>
#include <rdma/ib_sa.h>
diff --git a/drivers/infiniband/hw/mthca/mthca_av.c b/drivers/infiniband/hw/mthca/mthca_av.c
index 889e85096736..22fdc446f25c 100644
--- a/drivers/infiniband/hw/mthca/mthca_av.c
+++ b/drivers/infiniband/hw/mthca/mthca_av.c
@@ -34,6 +34,8 @@
*/
#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <rdma/ib_verbs.h>
#include <rdma/ib_cache.h>
diff --git a/drivers/infiniband/hw/mthca/mthca_mad.c b/drivers/infiniband/hw/mthca/mthca_mad.c
index 8561b297a19b..1229c604c6e0 100644
--- a/drivers/infiniband/hw/mthca/mthca_mad.c
+++ b/drivers/infiniband/hw/mthca/mthca_mad.c
@@ -34,6 +34,9 @@
* $Id: mthca_mad.c 1349 2004-12-16 21:09:43Z roland $
*/
+#include <linux/string.h>
+#include <linux/slab.h>
+
#include <rdma/ib_verbs.h>
#include <rdma/ib_mad.h>
#include <rdma/ib_smi.h>
diff --git a/drivers/infiniband/hw/mthca/mthca_mcg.c b/drivers/infiniband/hw/mthca/mthca_mcg.c
index b47ea7daf088..2fc449da418d 100644
--- a/drivers/infiniband/hw/mthca/mthca_mcg.c
+++ b/drivers/infiniband/hw/mthca/mthca_mcg.c
@@ -33,6 +33,8 @@
*/
#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "mthca_dev.h"
#include "mthca_cmd.h"
diff --git a/drivers/infiniband/hw/mthca/mthca_profile.c b/drivers/infiniband/hw/mthca/mthca_profile.c
index 0576056b34f4..bd1338682074 100644
--- a/drivers/infiniband/hw/mthca/mthca_profile.c
+++ b/drivers/infiniband/hw/mthca/mthca_profile.c
@@ -35,6 +35,8 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "mthca_profile.h"
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index 62ff091505da..7c9afde5ace5 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -36,6 +36,8 @@
*/
#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <rdma/ib_verbs.h>
#include <rdma/ib_cache.h>
diff --git a/drivers/infiniband/hw/mthca/mthca_reset.c b/drivers/infiniband/hw/mthca/mthca_reset.c
index 4f995391dd1d..df5e494a9d38 100644
--- a/drivers/infiniband/hw/mthca/mthca_reset.c
+++ b/drivers/infiniband/hw/mthca/mthca_reset.c
@@ -37,6 +37,7 @@
#include <linux/errno.h>
#include <linux/pci.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include "mthca_dev.h"
#include "mthca_cmd.h"
diff --git a/drivers/infiniband/hw/mthca/mthca_uar.c b/drivers/infiniband/hw/mthca/mthca_uar.c
index 1c8791ded6ff..8e9219842be4 100644
--- a/drivers/infiniband/hw/mthca/mthca_uar.c
+++ b/drivers/infiniband/hw/mthca/mthca_uar.c
@@ -32,6 +32,8 @@
* $Id$
*/
+#include <asm/page.h> /* PAGE_SHIFT */
+
#include "mthca_dev.h"
#include "mthca_memfree.h"
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index a4696cd0978c..9f2352bd8348 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -565,6 +565,7 @@ static long evdev_ioctl_compat(struct file *file, unsigned int cmd, unsigned lon
case EV_LED: bits = dev->ledbit; max = LED_MAX; break;
case EV_SND: bits = dev->sndbit; max = SND_MAX; break;
case EV_FF: bits = dev->ffbit; max = FF_MAX; break;
+ case EV_SW: bits = dev->swbit; max = SW_MAX; break;
default: return -EINVAL;
}
bit_to_user(bits, max);
@@ -579,6 +580,9 @@ static long evdev_ioctl_compat(struct file *file, unsigned int cmd, unsigned lon
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0)))
bit_to_user(dev->snd, SND_MAX);
+ if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0)))
+ bit_to_user(dev->sw, SW_MAX);
+
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) {
int len;
if (!dev->name) return -ENOENT;
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
index ab09cf4093e3..0506934244f0 100644
--- a/drivers/input/gameport/gameport.c
+++ b/drivers/input/gameport/gameport.c
@@ -21,6 +21,7 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/kthread.h>
+#include <linux/sched.h> /* HZ */
/*#include <asm/io.h>*/
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 3b1685ff9d10..1a1654caedd5 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -730,7 +730,7 @@ static void input_register_classdevice(struct input_dev *dev)
"input%ld", (unsigned long) atomic_inc_return(&input_no) - 1);
path = kobject_get_path(&dev->cdev.class->subsys.kset.kobj, GFP_KERNEL);
- printk(KERN_INFO "input: %s/%s as %s\n",
+ printk(KERN_INFO "input: %s as %s/%s\n",
dev->name ? dev->name : "Unspecified device",
path ? path : "", dev->cdev.class_id);
kfree(path);
diff --git a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c
index bf65430181fa..4571ea3a4b92 100644
--- a/drivers/input/joystick/a3d.c
+++ b/drivers/input/joystick/a3d.c
@@ -34,6 +34,7 @@
#include <linux/init.h>
#include <linux/gameport.h>
#include <linux/input.h>
+#include <linux/jiffies.h>
#define DRIVER_DESC "FP-Gaming Assasin 3D joystick driver"
diff --git a/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c
index 9d95459f4bcb..704bf70f1db7 100644
--- a/drivers/input/joystick/adi.c
+++ b/drivers/input/joystick/adi.c
@@ -34,6 +34,7 @@
#include <linux/input.h>
#include <linux/gameport.h>
#include <linux/init.h>
+#include <linux/jiffies.h>
#define DRIVER_DESC "Logitech ADI joystick family driver"
diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c
index c75ac6eb1ffb..3121961e3e7c 100644
--- a/drivers/input/joystick/analog.c
+++ b/drivers/input/joystick/analog.c
@@ -38,6 +38,7 @@
#include <linux/init.h>
#include <linux/input.h>
#include <linux/gameport.h>
+#include <linux/jiffies.h>
#include <asm/timex.h>
#define DRIVER_DESC "Analog joystick and gamepad driver"
diff --git a/drivers/input/joystick/cobra.c b/drivers/input/joystick/cobra.c
index 9a3dfc724a41..1909f7ef340c 100644
--- a/drivers/input/joystick/cobra.c
+++ b/drivers/input/joystick/cobra.c
@@ -34,6 +34,7 @@
#include <linux/init.h>
#include <linux/gameport.h>
#include <linux/input.h>
+#include <linux/jiffies.h>
#define DRIVER_DESC "Creative Labs Blaster GamePad Cobra driver"
diff --git a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c
index e151f8c5bcb9..8a3ad455eb38 100644
--- a/drivers/input/joystick/gf2k.c
+++ b/drivers/input/joystick/gf2k.c
@@ -35,6 +35,7 @@
#include <linux/init.h>
#include <linux/input.h>
#include <linux/gameport.h>
+#include <linux/jiffies.h>
#define DRIVER_DESC "Genius Flight 2000 joystick driver"
diff --git a/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c
index e206bb56e53c..a936e7aedb10 100644
--- a/drivers/input/joystick/grip.c
+++ b/drivers/input/joystick/grip.c
@@ -34,6 +34,7 @@
#include <linux/slab.h>
#include <linux/gameport.h>
#include <linux/input.h>
+#include <linux/jiffies.h>
#define DRIVER_DESC "Gravis GrIP protocol joystick driver"
diff --git a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c
index a0ba93ccac72..51a912222e85 100644
--- a/drivers/input/joystick/grip_mp.c
+++ b/drivers/input/joystick/grip_mp.c
@@ -19,6 +19,7 @@
#include <linux/input.h>
#include <linux/delay.h>
#include <linux/proc_fs.h>
+#include <linux/jiffies.h>
#define DRIVER_DESC "Gravis Grip Multiport driver"
diff --git a/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c
index c528473c09d8..6e2c721c26ba 100644
--- a/drivers/input/joystick/guillemot.c
+++ b/drivers/input/joystick/guillemot.c
@@ -35,6 +35,7 @@
#include <linux/init.h>
#include <linux/gameport.h>
#include <linux/input.h>
+#include <linux/jiffies.h>
#define DRIVER_DESC "Guillemot Digital joystick driver"
diff --git a/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c
index 8511ee7bb263..c4ed01758226 100644
--- a/drivers/input/joystick/interact.c
+++ b/drivers/input/joystick/interact.c
@@ -38,6 +38,7 @@
#include <linux/init.h>
#include <linux/gameport.h>
#include <linux/input.h>
+#include <linux/jiffies.h>
#define DRIVER_DESC "InterAct digital joystick driver"
diff --git a/drivers/input/joystick/joydump.c b/drivers/input/joystick/joydump.c
index 4234ccaf9146..88ec5a918f2e 100644
--- a/drivers/input/joystick/joydump.c
+++ b/drivers/input/joystick/joydump.c
@@ -34,6 +34,7 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/init.h>
+#include <linux/slab.h>
#define DRIVER_DESC "Gameport data dumper module"
diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c
index eaaad45cc750..78dd163cd702 100644
--- a/drivers/input/joystick/sidewinder.c
+++ b/drivers/input/joystick/sidewinder.c
@@ -33,6 +33,7 @@
#include <linux/init.h>
#include <linux/input.h>
#include <linux/gameport.h>
+#include <linux/jiffies.h>
#define DRIVER_DESC "Microsoft SideWinder joystick family driver"
diff --git a/drivers/input/joystick/tmdc.c b/drivers/input/joystick/tmdc.c
index 3a7d1bb46472..60e2aac7d06e 100644
--- a/drivers/input/joystick/tmdc.c
+++ b/drivers/input/joystick/tmdc.c
@@ -38,6 +38,7 @@
#include <linux/init.h>
#include <linux/gameport.h>
#include <linux/input.h>
+#include <linux/jiffies.h>
#define DRIVER_DESC "ThrustMaster DirectConnect joystick driver"
diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c
index 3d63bc1ad322..4c8fb1f8631f 100644
--- a/drivers/input/keyboard/amikbd.c
+++ b/drivers/input/keyboard/amikbd.c
@@ -199,7 +199,7 @@ static int __init amikbd_init(void)
if (!request_mem_region(CIAA_PHYSADDR-1+0xb00, 0x100, "amikeyb"))
return -EBUSY;
- amikbd_dev = input_dev_allocate();
+ amikbd_dev = input_allocate_device();
if (!amikbd_dev) {
printk(KERN_ERR "amikbd: not enough memory for input device\n");
release_mem_region(CIAA_PHYSADDR - 1 + 0xb00, 0x100);
diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c
index 7f06780a437f..9481132532d0 100644
--- a/drivers/input/keyboard/lkkbd.c
+++ b/drivers/input/keyboard/lkkbd.c
@@ -441,7 +441,7 @@ lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags,
input_sync (lk->dev);
break;
case LK_METRONOME:
- DBG (KERN_INFO "Got %#d and don't "
+ DBG (KERN_INFO "Got LK_METRONOME and don't "
"know how to handle...\n");
break;
case LK_OUTPUT_ERROR:
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index bb934e6d9636..b3eaac1b35b6 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -14,7 +14,7 @@ if INPUT_MISC
config INPUT_PCSPKR
tristate "PC Speaker support"
- depends on ALPHA || X86 || X86_64 || MIPS || PPC_PREP || PPC_CHRP || PPC_PSERIES
+ depends on ALPHA || X86 || MIPS || PPC_PREP || PPC_CHRP || PPC_PSERIES
help
Say Y here if you want the standard PC Speaker to be used for
bells and whistles.
diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c
index e34633c37fdd..68ac97f101b0 100644
--- a/drivers/input/misc/pcspkr.c
+++ b/drivers/input/misc/pcspkr.c
@@ -71,7 +71,7 @@ static int __init pcspkr_init(void)
return -ENOMEM;
pcspkr_dev->name = "PC Speaker";
- pcspkr_dev->name = "isa0061/input0";
+ pcspkr_dev->phys = "isa0061/input0";
pcspkr_dev->id.bustype = BUS_ISA;
pcspkr_dev->id.vendor = 0x001f;
pcspkr_dev->id.product = 0x0001;
diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c
index 5778220a18d2..29d97b12be7a 100644
--- a/drivers/input/misc/sparcspkr.c
+++ b/drivers/input/misc/sparcspkr.c
@@ -143,7 +143,7 @@ static int __init init_isa_beep(struct sparc_isa_device *isa_dev)
sparcspkr_dev->name = "Sparc ISA Speaker";
sparcspkr_dev->event = isa_spkr_event;
- input_register_device(&sparcspkr_dev);
+ input_register_device(sparcspkr_dev);
return 0;
}
diff --git a/drivers/input/serio/hp_sdc_mlc.c b/drivers/input/serio/hp_sdc_mlc.c
index e3c44ffae674..1c9426fd5205 100644
--- a/drivers/input/serio/hp_sdc_mlc.c
+++ b/drivers/input/serio/hp_sdc_mlc.c
@@ -40,6 +40,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/string.h>
+#include <asm/semaphore.h>
#define PREFIX "HP SDC MLC: "
diff --git a/drivers/isdn/capi/capifs.c b/drivers/isdn/capi/capifs.c
index 3abd7fc6e5ef..7b564c0dd996 100644
--- a/drivers/isdn/capi/capifs.c
+++ b/drivers/isdn/capi/capifs.c
@@ -15,6 +15,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/ctype.h>
+#include <linux/sched.h> /* current */
MODULE_DESCRIPTION("CAPI4Linux: /dev/capi/ filesystem");
MODULE_AUTHOR("Carsten Paeth");
diff --git a/drivers/isdn/hisax/hfc4s8s_l1.c b/drivers/isdn/hisax/hfc4s8s_l1.c
index 7333377ab31d..e3866b0a97fd 100644
--- a/drivers/isdn/hisax/hfc4s8s_l1.c
+++ b/drivers/isdn/hisax/hfc4s8s_l1.c
@@ -1063,7 +1063,7 @@ tx_b_frame(struct hfc4s8s_btype *bch)
Write_hfc8(l1->hw, A_INC_RES_FIFO, 1);
}
ack_len += skb->truesize;
- bch->tx_skb = 0;
+ bch->tx_skb = NULL;
bch->tx_cnt = 0;
dev_kfree_skb(skb);
} else
@@ -1659,10 +1659,10 @@ hfc4s8s_remove(struct pci_dev *pdev)
}
static struct pci_driver hfc4s8s_driver = {
- name:"hfc4s8s_l1",
- probe:hfc4s8s_probe,
- remove:__devexit_p(hfc4s8s_remove),
- id_table:hfc4s8s_ids,
+ .name = "hfc4s8s_l1",
+ .probe = hfc4s8s_probe,
+ .remove = __devexit_p(hfc4s8s_remove),
+ .id_table = hfc4s8s_ids,
};
/**********************/
diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c
index cdb6d0283195..8f02c155fdc0 100644
--- a/drivers/macintosh/adbhid.c
+++ b/drivers/macintosh/adbhid.c
@@ -723,6 +723,7 @@ adbhid_input_register(int id, int default_id, int original_handler_id,
sprintf(hid->phys, "adb%d:%d.%02x/input", id, default_id, original_handler_id);
+ hid->input = input_dev;
hid->id = default_id;
hid->original_handler_id = original_handler_id;
hid->current_handler_id = current_handler_id;
diff --git a/drivers/macintosh/ans-lcd.c b/drivers/macintosh/ans-lcd.c
index 5e0811dc6536..2b8a6e821d44 100644
--- a/drivers/macintosh/ans-lcd.c
+++ b/drivers/macintosh/ans-lcd.c
@@ -27,7 +27,7 @@ static volatile unsigned char __iomem *anslcd_ptr;
#undef DEBUG
-static void __pmac
+static void
anslcd_write_byte_ctrl ( unsigned char c )
{
#ifdef DEBUG
@@ -43,14 +43,14 @@ anslcd_write_byte_ctrl ( unsigned char c )
}
}
-static void __pmac
+static void
anslcd_write_byte_data ( unsigned char c )
{
out_8(anslcd_ptr + ANSLCD_DATA_IX, c);
udelay(anslcd_short_delay);
}
-static ssize_t __pmac
+static ssize_t
anslcd_write( struct file * file, const char __user * buf,
size_t count, loff_t *ppos )
{
@@ -73,7 +73,7 @@ anslcd_write( struct file * file, const char __user * buf,
return p - buf;
}
-static int __pmac
+static int
anslcd_ioctl( struct inode * inode, struct file * file,
unsigned int cmd, unsigned long arg )
{
@@ -115,7 +115,7 @@ anslcd_ioctl( struct inode * inode, struct file * file,
}
}
-static int __pmac
+static int
anslcd_open( struct inode * inode, struct file * file )
{
return 0;
diff --git a/drivers/macintosh/apm_emu.c b/drivers/macintosh/apm_emu.c
index 19d3e05d6825..e5a2bbf99399 100644
--- a/drivers/macintosh/apm_emu.c
+++ b/drivers/macintosh/apm_emu.c
@@ -430,8 +430,8 @@ static int apm_emu_get_info(char *buf, char **start, off_t fpos, int length)
-1: Unknown
8) min = minutes; sec = seconds */
- unsigned short ac_line_status = 0xff;
- unsigned short battery_status = 0xff;
+ unsigned short ac_line_status;
+ unsigned short battery_status = 0;
unsigned short battery_flag = 0xff;
int percentage = -1;
int time_units = -1;
@@ -446,6 +446,7 @@ static int apm_emu_get_info(char *buf, char **start, off_t fpos, int length)
ac_line_status = ((pmu_power_flags & PMU_PWR_AC_PRESENT) != 0);
for (i=0; i<pmu_battery_count; i++) {
if (pmu_batteries[i].flags & PMU_BATT_PRESENT) {
+ battery_status++;
if (percentage < 0)
percentage = 0;
if (charge < 0)
@@ -461,6 +462,9 @@ static int apm_emu_get_info(char *buf, char **start, off_t fpos, int length)
charging++;
}
}
+ if (0 == battery_status)
+ ac_line_status = 1;
+ battery_status = 0xff;
if (real_count) {
if (amperage < 0) {
if (btype == PMU_BATT_TYPE_SMART)
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
index 1ee003346923..c34c96d18907 100644
--- a/drivers/macintosh/macio_asic.c
+++ b/drivers/macintosh/macio_asic.c
@@ -17,6 +17,8 @@
#include <linux/pci_ids.h>
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/slab.h>
+
#include <asm/machdep.h>
#include <asm/macio.h>
#include <asm/pmac_feature.h>
diff --git a/drivers/macintosh/macio_sysfs.c b/drivers/macintosh/macio_sysfs.c
index 97d22bb4516a..7f7d4eaca870 100644
--- a/drivers/macintosh/macio_sysfs.c
+++ b/drivers/macintosh/macio_sysfs.c
@@ -39,6 +39,31 @@ compatible_show (struct device *dev, struct device_attribute *attr, char *buf)
return length;
}
+static ssize_t modalias_show (struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct of_device *of;
+ char *compat;
+ int cplen;
+ int length;
+
+ of = &to_macio_device (dev)->ofdev;
+ compat = (char *) get_property (of->node, "compatible", &cplen);
+ if (!compat) compat = "", cplen = 1;
+ length = sprintf (buf, "of:N%sT%s", of->node->name, of->node->type);
+ buf += length;
+ while (cplen > 0) {
+ int l;
+ length += sprintf (buf, "C%s", compat);
+ buf += length;
+ l = strlen (compat) + 1;
+ compat += l;
+ cplen -= l;
+ }
+
+ return length;
+}
+
macio_config_of_attr (name, "%s\n");
macio_config_of_attr (type, "%s\n");
@@ -46,5 +71,6 @@ struct device_attribute macio_dev_attrs[] = {
__ATTR_RO(name),
__ATTR_RO(type),
__ATTR_RO(compatible),
+ __ATTR_RO(modalias),
__ATTR_NULL
};
diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c
index c0712a1ea5af..b856bb67169c 100644
--- a/drivers/macintosh/mediabay.c
+++ b/drivers/macintosh/mediabay.c
@@ -167,19 +167,19 @@ enum {
* Functions for polling content of media bay
*/
-static u8 __pmac
+static u8
ohare_mb_content(struct media_bay_info *bay)
{
return (MB_IN32(bay, OHARE_MBCR) >> 12) & 7;
}
-static u8 __pmac
+static u8
heathrow_mb_content(struct media_bay_info *bay)
{
return (MB_IN32(bay, HEATHROW_MBCR) >> 12) & 7;
}
-static u8 __pmac
+static u8
keylargo_mb_content(struct media_bay_info *bay)
{
int new_gpio;
@@ -205,7 +205,7 @@ keylargo_mb_content(struct media_bay_info *bay)
* into reset state as well
*/
-static void __pmac
+static void
ohare_mb_power(struct media_bay_info* bay, int on_off)
{
if (on_off) {
@@ -224,7 +224,7 @@ ohare_mb_power(struct media_bay_info* bay, int on_off)
MB_BIC(bay, OHARE_MBCR, 0x00000F00);
}
-static void __pmac
+static void
heathrow_mb_power(struct media_bay_info* bay, int on_off)
{
if (on_off) {
@@ -243,7 +243,7 @@ heathrow_mb_power(struct media_bay_info* bay, int on_off)
MB_BIC(bay, HEATHROW_MBCR, 0x00000F00);
}
-static void __pmac
+static void
keylargo_mb_power(struct media_bay_info* bay, int on_off)
{
if (on_off) {
@@ -267,7 +267,7 @@ keylargo_mb_power(struct media_bay_info* bay, int on_off)
* enable the related busses
*/
-static int __pmac
+static int
ohare_mb_setup_bus(struct media_bay_info* bay, u8 device_id)
{
switch(device_id) {
@@ -287,7 +287,7 @@ ohare_mb_setup_bus(struct media_bay_info* bay, u8 device_id)
return -ENODEV;
}
-static int __pmac
+static int
heathrow_mb_setup_bus(struct media_bay_info* bay, u8 device_id)
{
switch(device_id) {
@@ -307,7 +307,7 @@ heathrow_mb_setup_bus(struct media_bay_info* bay, u8 device_id)
return -ENODEV;
}
-static int __pmac
+static int
keylargo_mb_setup_bus(struct media_bay_info* bay, u8 device_id)
{
switch(device_id) {
@@ -330,43 +330,43 @@ keylargo_mb_setup_bus(struct media_bay_info* bay, u8 device_id)
* Functions for tweaking resets
*/
-static void __pmac
+static void
ohare_mb_un_reset(struct media_bay_info* bay)
{
MB_BIS(bay, OHARE_FCR, OH_BAY_RESET_N);
}
-static void __pmac keylargo_mb_init(struct media_bay_info *bay)
+static void keylargo_mb_init(struct media_bay_info *bay)
{
MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_ENABLE);
}
-static void __pmac heathrow_mb_un_reset(struct media_bay_info* bay)
+static void heathrow_mb_un_reset(struct media_bay_info* bay)
{
MB_BIS(bay, HEATHROW_FCR, HRW_BAY_RESET_N);
}
-static void __pmac keylargo_mb_un_reset(struct media_bay_info* bay)
+static void keylargo_mb_un_reset(struct media_bay_info* bay)
{
MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_DEV_RESET);
}
-static void __pmac ohare_mb_un_reset_ide(struct media_bay_info* bay)
+static void ohare_mb_un_reset_ide(struct media_bay_info* bay)
{
MB_BIS(bay, OHARE_FCR, OH_IDE1_RESET_N);
}
-static void __pmac heathrow_mb_un_reset_ide(struct media_bay_info* bay)
+static void heathrow_mb_un_reset_ide(struct media_bay_info* bay)
{
MB_BIS(bay, HEATHROW_FCR, HRW_IDE1_RESET_N);
}
-static void __pmac keylargo_mb_un_reset_ide(struct media_bay_info* bay)
+static void keylargo_mb_un_reset_ide(struct media_bay_info* bay)
{
MB_BIS(bay, KEYLARGO_FCR1, KL1_EIDE0_RESET_N);
}
-static inline void __pmac set_mb_power(struct media_bay_info* bay, int onoff)
+static inline void set_mb_power(struct media_bay_info* bay, int onoff)
{
/* Power up up and assert the bay reset line */
if (onoff) {
@@ -382,7 +382,7 @@ static inline void __pmac set_mb_power(struct media_bay_info* bay, int onoff)
bay->timer = msecs_to_jiffies(MB_POWER_DELAY);
}
-static void __pmac poll_media_bay(struct media_bay_info* bay)
+static void poll_media_bay(struct media_bay_info* bay)
{
int id = bay->ops->content(bay);
@@ -415,7 +415,7 @@ static void __pmac poll_media_bay(struct media_bay_info* bay)
}
}
-int __pmac check_media_bay(struct device_node *which_bay, int what)
+int check_media_bay(struct device_node *which_bay, int what)
{
#ifdef CONFIG_BLK_DEV_IDE
int i;
@@ -432,7 +432,7 @@ int __pmac check_media_bay(struct device_node *which_bay, int what)
}
EXPORT_SYMBOL(check_media_bay);
-int __pmac check_media_bay_by_base(unsigned long base, int what)
+int check_media_bay_by_base(unsigned long base, int what)
{
#ifdef CONFIG_BLK_DEV_IDE
int i;
@@ -449,7 +449,7 @@ int __pmac check_media_bay_by_base(unsigned long base, int what)
return -ENODEV;
}
-int __pmac media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base,
+int media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base,
int irq, int index)
{
#ifdef CONFIG_BLK_DEV_IDE
@@ -489,7 +489,7 @@ int __pmac media_bay_set_ide_infos(struct device_node* which_bay, unsigned long
return -ENODEV;
}
-static void __pmac media_bay_step(int i)
+static void media_bay_step(int i)
{
struct media_bay_info* bay = &media_bays[i];
@@ -619,7 +619,7 @@ static void __pmac media_bay_step(int i)
* with the IDE driver. It needs to be a thread because
* ide_register can't be called from interrupt context.
*/
-static int __pmac media_bay_task(void *x)
+static int media_bay_task(void *x)
{
int i;
@@ -704,7 +704,7 @@ static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_de
}
-static int __pmac media_bay_suspend(struct macio_dev *mdev, pm_message_t state)
+static int media_bay_suspend(struct macio_dev *mdev, pm_message_t state)
{
struct media_bay_info *bay = macio_get_drvdata(mdev);
@@ -719,7 +719,7 @@ static int __pmac media_bay_suspend(struct macio_dev *mdev, pm_message_t state)
return 0;
}
-static int __pmac media_bay_resume(struct macio_dev *mdev)
+static int media_bay_resume(struct macio_dev *mdev)
{
struct media_bay_info *bay = macio_get_drvdata(mdev);
@@ -760,7 +760,7 @@ static int __pmac media_bay_resume(struct macio_dev *mdev)
/* Definitions of "ops" structures.
*/
-static struct mb_ops ohare_mb_ops __pmacdata = {
+static struct mb_ops ohare_mb_ops = {
.name = "Ohare",
.content = ohare_mb_content,
.power = ohare_mb_power,
@@ -769,7 +769,7 @@ static struct mb_ops ohare_mb_ops __pmacdata = {
.un_reset_ide = ohare_mb_un_reset_ide,
};
-static struct mb_ops heathrow_mb_ops __pmacdata = {
+static struct mb_ops heathrow_mb_ops = {
.name = "Heathrow",
.content = heathrow_mb_content,
.power = heathrow_mb_power,
@@ -778,7 +778,7 @@ static struct mb_ops heathrow_mb_ops __pmacdata = {
.un_reset_ide = heathrow_mb_un_reset_ide,
};
-static struct mb_ops keylargo_mb_ops __pmacdata = {
+static struct mb_ops keylargo_mb_ops = {
.name = "KeyLargo",
.init = keylargo_mb_init,
.content = keylargo_mb_content,
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
index 9b38674fbf75..34f3c7e2d832 100644
--- a/drivers/macintosh/smu.c
+++ b/drivers/macintosh/smu.c
@@ -1094,7 +1094,7 @@ static int smu_release(struct inode *inode, struct file *file)
}
-static struct file_operations smu_device_fops __pmacdata = {
+static struct file_operations smu_device_fops = {
.llseek = no_llseek,
.read = smu_read,
.write = smu_write,
@@ -1103,7 +1103,7 @@ static struct file_operations smu_device_fops __pmacdata = {
.release = smu_release,
};
-static struct miscdevice pmu_device __pmacdata = {
+static struct miscdevice pmu_device = {
MISC_DYNAMIC_MINOR, "smu", &smu_device_fops
};
diff --git a/drivers/macintosh/via-cuda.c b/drivers/macintosh/via-cuda.c
index 417deb5de108..d843a6c9c6df 100644
--- a/drivers/macintosh/via-cuda.c
+++ b/drivers/macintosh/via-cuda.c
@@ -37,7 +37,6 @@ static DEFINE_SPINLOCK(cuda_lock);
#ifdef CONFIG_MAC
#define CUDA_IRQ IRQ_MAC_ADB
-#define __openfirmware
#define eieio()
#else
#define CUDA_IRQ vias->intrs[0].line
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index 645a2e5c70ab..91920a1140fa 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -244,7 +244,7 @@ int pmu_wink(struct adb_request *req);
* - the number of response bytes which the PMU will return, or
* -1 if it will send a length byte.
*/
-static const s8 pmu_data_len[256][2] __openfirmwaredata = {
+static const s8 pmu_data_len[256][2] = {
/* 0 1 2 3 4 5 6 7 */
/*00*/ {-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
/*08*/ {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
@@ -295,7 +295,7 @@ static struct backlight_controller pmu_backlight_controller = {
};
#endif /* CONFIG_PMAC_BACKLIGHT */
-int __openfirmware
+int
find_via_pmu(void)
{
if (via != 0)
@@ -374,7 +374,7 @@ find_via_pmu(void)
}
#ifdef CONFIG_ADB
-static int __openfirmware
+static int
pmu_probe(void)
{
return vias == NULL? -ENODEV: 0;
@@ -405,7 +405,7 @@ static int __init via_pmu_start(void)
bright_req_2.complete = 1;
batt_req.complete = 1;
-#ifdef CONFIG_PPC32
+#if defined(CONFIG_PPC32) && !defined(CONFIG_PPC_MERGE)
if (pmu_kind == PMU_KEYLARGO_BASED)
openpic_set_irq_priority(vias->intrs[0].line,
OPENPIC_PRIORITY_DEFAULT + 1);
@@ -520,7 +520,7 @@ static int __init via_pmu_dev_init(void)
device_initcall(via_pmu_dev_init);
-static int __openfirmware
+static int
init_pmu(void)
{
int timeout;
@@ -588,17 +588,6 @@ pmu_get_model(void)
return pmu_kind;
}
-#ifndef CONFIG_PPC64
-static inline void wakeup_decrementer(void)
-{
- set_dec(tb_ticks_per_jiffy);
- /* No currently-supported powerbook has a 601,
- * so use get_tbl, not native
- */
- last_jiffy_stamp(0) = tb_last_stamp = get_tbl();
-}
-#endif
-
static void pmu_set_server_mode(int server_mode)
{
struct adb_request req;
@@ -625,7 +614,7 @@ static void pmu_set_server_mode(int server_mode)
/* This new version of the code for 2400/3400/3500 powerbooks
* is inspired from the implementation in gkrellm-pmu
*/
-static void __pmac
+static void
done_battery_state_ohare(struct adb_request* req)
{
/* format:
@@ -713,7 +702,7 @@ done_battery_state_ohare(struct adb_request* req)
clear_bit(0, &async_req_locks);
}
-static void __pmac
+static void
done_battery_state_smart(struct adb_request* req)
{
/* format:
@@ -791,7 +780,7 @@ done_battery_state_smart(struct adb_request* req)
clear_bit(0, &async_req_locks);
}
-static void __pmac
+static void
query_battery_state(void)
{
if (test_and_set_bit(0, &async_req_locks))
@@ -804,7 +793,7 @@ query_battery_state(void)
2, PMU_SMART_BATTERY_STATE, pmu_cur_battery+1);
}
-static int __pmac
+static int
proc_get_info(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
@@ -819,7 +808,7 @@ proc_get_info(char *page, char **start, off_t off,
return p - page;
}
-static int __pmac
+static int
proc_get_irqstats(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
@@ -846,7 +835,7 @@ proc_get_irqstats(char *page, char **start, off_t off,
return p - page;
}
-static int __pmac
+static int
proc_get_batt(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
@@ -870,7 +859,7 @@ proc_get_batt(char *page, char **start, off_t off,
return p - page;
}
-static int __pmac
+static int
proc_read_options(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
@@ -887,7 +876,7 @@ proc_read_options(char *page, char **start, off_t off,
return p - page;
}
-static int __pmac
+static int
proc_write_options(struct file *file, const char __user *buffer,
unsigned long count, void *data)
{
@@ -934,7 +923,7 @@ proc_write_options(struct file *file, const char __user *buffer,
#ifdef CONFIG_ADB
/* Send an ADB command */
-static int __pmac
+static int
pmu_send_request(struct adb_request *req, int sync)
{
int i, ret;
@@ -1014,7 +1003,7 @@ pmu_send_request(struct adb_request *req, int sync)
}
/* Enable/disable autopolling */
-static int __pmac
+static int
pmu_adb_autopoll(int devs)
{
struct adb_request req;
@@ -1037,7 +1026,7 @@ pmu_adb_autopoll(int devs)
}
/* Reset the ADB bus */
-static int __pmac
+static int
pmu_adb_reset_bus(void)
{
struct adb_request req;
@@ -1072,7 +1061,7 @@ pmu_adb_reset_bus(void)
#endif /* CONFIG_ADB */
/* Construct and send a pmu request */
-int __openfirmware
+int
pmu_request(struct adb_request *req, void (*done)(struct adb_request *),
int nbytes, ...)
{
@@ -1098,7 +1087,7 @@ pmu_request(struct adb_request *req, void (*done)(struct adb_request *),
return pmu_queue_request(req);
}
-int __pmac
+int
pmu_queue_request(struct adb_request *req)
{
unsigned long flags;
@@ -1190,7 +1179,7 @@ pmu_done(struct adb_request *req)
(*done)(req);
}
-static void __pmac
+static void
pmu_start(void)
{
struct adb_request *req;
@@ -1214,7 +1203,7 @@ pmu_start(void)
send_byte(req->data[0]);
}
-void __openfirmware
+void
pmu_poll(void)
{
if (!via)
@@ -1224,7 +1213,7 @@ pmu_poll(void)
via_pmu_interrupt(0, NULL, NULL);
}
-void __openfirmware
+void
pmu_poll_adb(void)
{
if (!via)
@@ -1239,7 +1228,7 @@ pmu_poll_adb(void)
|| req_awaiting_reply));
}
-void __openfirmware
+void
pmu_wait_complete(struct adb_request *req)
{
if (!via)
@@ -1253,7 +1242,7 @@ pmu_wait_complete(struct adb_request *req)
* This is done to avoid spurrious shutdowns when we know we'll have
* interrupts switched off for a long time
*/
-void __openfirmware
+void
pmu_suspend(void)
{
unsigned long flags;
@@ -1293,7 +1282,7 @@ pmu_suspend(void)
} while (1);
}
-void __openfirmware
+void
pmu_resume(void)
{
unsigned long flags;
@@ -1323,7 +1312,7 @@ pmu_resume(void)
}
/* Interrupt data could be the result data from an ADB cmd */
-static void __pmac
+static void
pmu_handle_data(unsigned char *data, int len, struct pt_regs *regs)
{
unsigned char ints, pirq;
@@ -1435,7 +1424,7 @@ next:
goto next;
}
-static struct adb_request* __pmac
+static struct adb_request*
pmu_sr_intr(struct pt_regs *regs)
{
struct adb_request *req;
@@ -1541,7 +1530,7 @@ pmu_sr_intr(struct pt_regs *regs)
return NULL;
}
-static irqreturn_t __pmac
+static irqreturn_t
via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs)
{
unsigned long flags;
@@ -1629,7 +1618,7 @@ no_free_slot:
return IRQ_RETVAL(handled);
}
-void __pmac
+void
pmu_unlock(void)
{
unsigned long flags;
@@ -1642,7 +1631,7 @@ pmu_unlock(void)
}
-static irqreturn_t __pmac
+static irqreturn_t
gpio1_interrupt(int irq, void *arg, struct pt_regs *regs)
{
unsigned long flags;
@@ -1663,12 +1652,12 @@ gpio1_interrupt(int irq, void *arg, struct pt_regs *regs)
}
#ifdef CONFIG_PMAC_BACKLIGHT
-static int backlight_to_bright[] __pmacdata = {
+static int backlight_to_bright[] = {
0x7f, 0x46, 0x42, 0x3e, 0x3a, 0x36, 0x32, 0x2e,
0x2a, 0x26, 0x22, 0x1e, 0x1a, 0x16, 0x12, 0x0e
};
-static int __openfirmware
+static int
pmu_set_backlight_enable(int on, int level, void* data)
{
struct adb_request req;
@@ -1688,7 +1677,7 @@ pmu_set_backlight_enable(int on, int level, void* data)
return 0;
}
-static void __openfirmware
+static void
pmu_bright_complete(struct adb_request *req)
{
if (req == &bright_req_1)
@@ -1697,7 +1686,7 @@ pmu_bright_complete(struct adb_request *req)
clear_bit(2, &async_req_locks);
}
-static int __openfirmware
+static int
pmu_set_backlight_level(int level, void* data)
{
if (vias == NULL)
@@ -1717,7 +1706,7 @@ pmu_set_backlight_level(int level, void* data)
}
#endif /* CONFIG_PMAC_BACKLIGHT */
-void __pmac
+void
pmu_enable_irled(int on)
{
struct adb_request req;
@@ -1732,7 +1721,7 @@ pmu_enable_irled(int on)
pmu_wait_complete(&req);
}
-void __pmac
+void
pmu_restart(void)
{
struct adb_request req;
@@ -1757,7 +1746,7 @@ pmu_restart(void)
;
}
-void __pmac
+void
pmu_shutdown(void)
{
struct adb_request req;
@@ -2076,7 +2065,7 @@ pmu_unregister_sleep_notifier(struct pmu_sleep_notifier* n)
}
/* Sleep is broadcast last-to-first */
-static int __pmac
+static int
broadcast_sleep(int when, int fallback)
{
int ret = PBOOK_SLEEP_OK;
@@ -2101,7 +2090,7 @@ broadcast_sleep(int when, int fallback)
}
/* Wake is broadcast first-to-last */
-static int __pmac
+static int
broadcast_wake(void)
{
int ret = PBOOK_SLEEP_OK;
@@ -2132,7 +2121,7 @@ static struct pci_save {
} *pbook_pci_saves;
static int pbook_npci_saves;
-static void __pmac
+static void
pbook_alloc_pci_save(void)
{
int npci;
@@ -2149,7 +2138,7 @@ pbook_alloc_pci_save(void)
pbook_npci_saves = npci;
}
-static void __pmac
+static void
pbook_free_pci_save(void)
{
if (pbook_pci_saves == NULL)
@@ -2159,7 +2148,7 @@ pbook_free_pci_save(void)
pbook_npci_saves = 0;
}
-static void __pmac
+static void
pbook_pci_save(void)
{
struct pci_save *ps = pbook_pci_saves;
@@ -2190,7 +2179,7 @@ pbook_pci_save(void)
* during boot, it will be in the pci dev list. If it's disabled at this point
* (and it will probably be), then you can't access it's config space.
*/
-static void __pmac
+static void
pbook_pci_restore(void)
{
u16 cmd;
@@ -2238,7 +2227,7 @@ pbook_pci_restore(void)
#ifdef DEBUG_SLEEP
/* N.B. This doesn't work on the 3400 */
-void __pmac
+void
pmu_blink(int n)
{
struct adb_request req;
@@ -2277,9 +2266,9 @@ pmu_blink(int n)
* Put the powerbook to sleep.
*/
-static u32 save_via[8] __pmacdata;
+static u32 save_via[8];
-static void __pmac
+static void
save_via_state(void)
{
save_via[0] = in_8(&via[ANH]);
@@ -2291,7 +2280,7 @@ save_via_state(void)
save_via[6] = in_8(&via[T1CL]);
save_via[7] = in_8(&via[T1CH]);
}
-static void __pmac
+static void
restore_via_state(void)
{
out_8(&via[ANH], save_via[0]);
@@ -2307,7 +2296,7 @@ restore_via_state(void)
out_8(&via[IER], IER_SET | SR_INT | CB1_INT);
}
-static int __pmac
+static int
pmac_suspend_devices(void)
{
int ret;
@@ -2397,7 +2386,7 @@ pmac_suspend_devices(void)
return 0;
}
-static int __pmac
+static int
pmac_wakeup_devices(void)
{
mdelay(100);
@@ -2436,7 +2425,7 @@ pmac_wakeup_devices(void)
#define GRACKLE_NAP (1<<4)
#define GRACKLE_SLEEP (1<<3)
-int __pmac
+int
powerbook_sleep_grackle(void)
{
unsigned long save_l2cr;
@@ -2520,7 +2509,7 @@ powerbook_sleep_grackle(void)
return 0;
}
-static int __pmac
+static int
powerbook_sleep_Core99(void)
{
unsigned long save_l2cr;
@@ -2620,7 +2609,7 @@ powerbook_sleep_Core99(void)
#define PB3400_MEM_CTRL 0xf8000000
#define PB3400_MEM_CTRL_SLEEP 0x70
-static int __pmac
+static int
powerbook_sleep_3400(void)
{
int ret, i, x;
@@ -2720,9 +2709,9 @@ struct pmu_private {
};
static LIST_HEAD(all_pmu_pvt);
-static DEFINE_SPINLOCK(all_pvt_lock __pmacdata);
+static DEFINE_SPINLOCK(all_pvt_lock);
-static void __pmac
+static void
pmu_pass_intr(unsigned char *data, int len)
{
struct pmu_private *pp;
@@ -2751,7 +2740,7 @@ pmu_pass_intr(unsigned char *data, int len)
spin_unlock_irqrestore(&all_pvt_lock, flags);
}
-static int __pmac
+static int
pmu_open(struct inode *inode, struct file *file)
{
struct pmu_private *pp;
@@ -2773,7 +2762,7 @@ pmu_open(struct inode *inode, struct file *file)
return 0;
}
-static ssize_t __pmac
+static ssize_t
pmu_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
@@ -2825,14 +2814,14 @@ pmu_read(struct file *file, char __user *buf,
return ret;
}
-static ssize_t __pmac
+static ssize_t
pmu_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
return 0;
}
-static unsigned int __pmac
+static unsigned int
pmu_fpoll(struct file *filp, poll_table *wait)
{
struct pmu_private *pp = filp->private_data;
@@ -2849,7 +2838,7 @@ pmu_fpoll(struct file *filp, poll_table *wait)
return mask;
}
-static int __pmac
+static int
pmu_release(struct inode *inode, struct file *file)
{
struct pmu_private *pp = file->private_data;
@@ -2874,8 +2863,7 @@ pmu_release(struct inode *inode, struct file *file)
return 0;
}
-/* Note: removed __openfirmware here since it causes link errors */
-static int __pmac
+static int
pmu_ioctl(struct inode * inode, struct file *filp,
u_int cmd, u_long arg)
{
@@ -2957,7 +2945,7 @@ pmu_ioctl(struct inode * inode, struct file *filp,
return error;
}
-static struct file_operations pmu_device_fops __pmacdata = {
+static struct file_operations pmu_device_fops = {
.read = pmu_read,
.write = pmu_write,
.poll = pmu_fpoll,
@@ -2966,7 +2954,7 @@ static struct file_operations pmu_device_fops __pmacdata = {
.release = pmu_release,
};
-static struct miscdevice pmu_device __pmacdata = {
+static struct miscdevice pmu_device = {
PMU_MINOR, "pmu", &pmu_device_fops
};
@@ -2982,7 +2970,7 @@ device_initcall(pmu_device_init);
#ifdef DEBUG_SLEEP
-static inline void __pmac
+static inline void
polled_handshake(volatile unsigned char __iomem *via)
{
via[B] &= ~TREQ; eieio();
@@ -2993,7 +2981,7 @@ polled_handshake(volatile unsigned char __iomem *via)
;
}
-static inline void __pmac
+static inline void
polled_send_byte(volatile unsigned char __iomem *via, int x)
{
via[ACR] |= SR_OUT | SR_EXT; eieio();
@@ -3001,7 +2989,7 @@ polled_send_byte(volatile unsigned char __iomem *via, int x)
polled_handshake(via);
}
-static inline int __pmac
+static inline int
polled_recv_byte(volatile unsigned char __iomem *via)
{
int x;
@@ -3013,7 +3001,7 @@ polled_recv_byte(volatile unsigned char __iomem *via)
return x;
}
-int __pmac
+int
pmu_polled_request(struct adb_request *req)
{
unsigned long flags;
diff --git a/drivers/macintosh/via-pmu68k.c b/drivers/macintosh/via-pmu68k.c
index 820dc52e30bc..6f80d76ac17c 100644
--- a/drivers/macintosh/via-pmu68k.c
+++ b/drivers/macintosh/via-pmu68k.c
@@ -835,7 +835,7 @@ static struct pci_save {
} *pbook_pci_saves;
static int n_pbook_pci_saves;
-static inline void __openfirmware
+static inline void
pbook_pci_save(void)
{
int npci;
@@ -863,7 +863,7 @@ pbook_pci_save(void)
}
}
-static inline void __openfirmware
+static inline void
pbook_pci_restore(void)
{
u16 cmd;
@@ -902,7 +902,7 @@ pbook_pci_restore(void)
#define IRQ_ENABLE ((unsigned int *)0xf3000024)
#define MEM_CTRL ((unsigned int *)0xf8000070)
-int __openfirmware powerbook_sleep(void)
+int powerbook_sleep(void)
{
int ret, i, x;
static int save_backlight;
@@ -1001,25 +1001,24 @@ int __openfirmware powerbook_sleep(void)
/*
* Support for /dev/pmu device
*/
-static int __openfirmware pmu_open(struct inode *inode, struct file *file)
+static int pmu_open(struct inode *inode, struct file *file)
{
return 0;
}
-static ssize_t __openfirmware pmu_read(struct file *file, char *buf,
+static ssize_t pmu_read(struct file *file, char *buf,
size_t count, loff_t *ppos)
{
return 0;
}
-static ssize_t __openfirmware pmu_write(struct file *file, const char *buf,
+static ssize_t pmu_write(struct file *file, const char *buf,
size_t count, loff_t *ppos)
{
return 0;
}
-/* Note: removed __openfirmware here since it causes link errors */
-static int /*__openfirmware*/ pmu_ioctl(struct inode * inode, struct file *filp,
+static int pmu_ioctl(struct inode * inode, struct file *filp,
u_int cmd, u_long arg)
{
int error;
diff --git a/drivers/mca/mca-device.c b/drivers/mca/mca-device.c
index 76d430aa243f..e7adf89fae41 100644
--- a/drivers/mca/mca-device.c
+++ b/drivers/mca/mca-device.c
@@ -29,6 +29,7 @@
#include <linux/module.h>
#include <linux/device.h>
#include <linux/mca.h>
+#include <linux/string.h>
/**
* mca_device_read_stored_pos - read POS register from stored data
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 28c1a628621f..cf6631056683 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -15,7 +15,7 @@
#include <linux/crypto.h>
#include <linux/workqueue.h>
#include <asm/atomic.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
#include <asm/page.h>
#include "dm.h"
@@ -164,9 +164,7 @@ static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti,
return -ENOMEM;
}
- sg.page = virt_to_page(cc->key);
- sg.offset = offset_in_page(cc->key);
- sg.length = cc->key_size;
+ sg_set_buf(&sg, cc->key, cc->key_size);
crypto_digest_digest(hash_tfm, &sg, 1, salt);
crypto_free_tfm(hash_tfm);
@@ -207,14 +205,12 @@ static void crypt_iv_essiv_dtr(struct crypt_config *cc)
static int crypt_iv_essiv_gen(struct crypt_config *cc, u8 *iv, sector_t sector)
{
- struct scatterlist sg = { NULL, };
+ struct scatterlist sg;
memset(iv, 0, cc->iv_size);
*(u64 *)iv = cpu_to_le64(sector);
- sg.page = virt_to_page(iv);
- sg.offset = offset_in_page(iv);
- sg.length = cc->iv_size;
+ sg_set_buf(&sg, iv, cc->iv_size);
crypto_cipher_encrypt((struct crypto_tfm *)cc->iv_gen_private,
&sg, &sg, cc->iv_size);
diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c
index 06f4d4686a6c..31fccb4f05d6 100644
--- a/drivers/media/common/ir-common.c
+++ b/drivers/media/common/ir-common.c
@@ -22,6 +22,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
+#include <linux/string.h>
#include <media/ir-common.h>
/* -------------------------------------------------------------------------- */
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
index 88757e2634e5..2aa767f9bd7d 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -36,6 +36,7 @@
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/rwsem.h>
+#include <linux/sched.h>
#include "dvb_ca_en50221.h"
#include "dvb_ringbuffer.h"
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c
index 5aa12ebab34f..b595476332cd 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u.c
+++ b/drivers/media/dvb/dvb-usb/dtt200u.c
@@ -151,7 +151,7 @@ static struct dvb_usb_properties dtt200u_properties = {
.cold_ids = { &dtt200u_usb_table[0], NULL },
.warm_ids = { &dtt200u_usb_table[1], NULL },
},
- { 0 },
+ { NULL },
}
};
@@ -192,7 +192,7 @@ static struct dvb_usb_properties wt220u_properties = {
.cold_ids = { &dtt200u_usb_table[2], NULL },
.warm_ids = { &dtt200u_usb_table[3], NULL },
},
- { 0 },
+ { NULL },
}
};
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c
index 0f57abeb6d6b..75765e3a569c 100644
--- a/drivers/media/dvb/dvb-usb/vp7045.c
+++ b/drivers/media/dvb/dvb-usb/vp7045.c
@@ -247,7 +247,7 @@ static struct dvb_usb_properties vp7045_properties = {
.cold_ids = { &vp7045_usb_table[2], NULL },
.warm_ids = { &vp7045_usb_table[3], NULL },
},
- { 0 },
+ { NULL },
}
};
diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb/frontends/bcm3510.c
index f5fdc5c3e605..f6d4ee78bdd4 100644
--- a/drivers/media/dvb/frontends/bcm3510.c
+++ b/drivers/media/dvb/frontends/bcm3510.c
@@ -36,6 +36,9 @@
#include <linux/moduleparam.h>
#include <linux/device.h>
#include <linux/firmware.h>
+#include <linux/jiffies.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
#include "bcm3510.h"
diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c
index 21433e1831e7..6b0553608610 100644
--- a/drivers/media/dvb/frontends/dib3000mb.c
+++ b/drivers/media/dvb/frontends/dib3000mb.c
@@ -27,6 +27,8 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "dib3000-common.h"
#include "dib3000mb_priv.h"
diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c
index 441de665fec3..c024fad17337 100644
--- a/drivers/media/dvb/frontends/dib3000mc.c
+++ b/drivers/media/dvb/frontends/dib3000mc.c
@@ -26,6 +26,8 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "dib3000-common.h"
#include "dib3000mc_priv.h"
diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.c b/drivers/media/dvb/frontends/dvb_dummy_fe.c
index cff93b9d8ab2..794be520d590 100644
--- a/drivers/media/dvb/frontends/dvb_dummy_fe.c
+++ b/drivers/media/dvb/frontends/dvb_dummy_fe.c
@@ -22,6 +22,8 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
#include "dvb_dummy_fe.h"
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c
index 7142b9c51dd2..8dde72bd1046 100644
--- a/drivers/media/dvb/frontends/lgdt330x.c
+++ b/drivers/media/dvb/frontends/lgdt330x.c
@@ -37,6 +37,8 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <asm/byteorder.h>
#include "dvb_frontend.h"
diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c
index e455aecd76b2..e38454901dd1 100644
--- a/drivers/media/dvb/frontends/mt312.c
+++ b/drivers/media/dvb/frontends/mt312.c
@@ -29,6 +29,8 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
#include "mt312_priv.h"
diff --git a/drivers/media/dvb/frontends/mt352.c b/drivers/media/dvb/frontends/mt352.c
index cc1bc0edd65e..f0c610f2c2df 100644
--- a/drivers/media/dvb/frontends/mt352.c
+++ b/drivers/media/dvb/frontends/mt352.c
@@ -35,6 +35,8 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
#include "mt352_priv.h"
diff --git a/drivers/media/dvb/frontends/nxt2002.c b/drivers/media/dvb/frontends/nxt2002.c
index 35a1d60f1927..30786b1911bd 100644
--- a/drivers/media/dvb/frontends/nxt2002.c
+++ b/drivers/media/dvb/frontends/nxt2002.c
@@ -32,6 +32,8 @@
#include <linux/moduleparam.h>
#include <linux/device.h>
#include <linux/firmware.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
#include "nxt2002.h"
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c
index b6d0eecc59eb..817b044c7fd1 100644
--- a/drivers/media/dvb/frontends/or51132.c
+++ b/drivers/media/dvb/frontends/or51132.c
@@ -36,6 +36,8 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <asm/byteorder.h>
#include "dvb_frontend.h"
diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c
index ad56a9958404..8a9db23dd1b7 100644
--- a/drivers/media/dvb/frontends/or51211.c
+++ b/drivers/media/dvb/frontends/or51211.c
@@ -34,6 +34,8 @@
#include <linux/moduleparam.h>
#include <linux/device.h>
#include <linux/firmware.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <asm/byteorder.h>
#include "dvb_frontend.h"
diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c
index c7fe27fd530c..f265418e3261 100644
--- a/drivers/media/dvb/frontends/s5h1420.c
+++ b/drivers/media/dvb/frontends/s5h1420.c
@@ -26,6 +26,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <asm/div64.h>
#include "dvb_frontend.h"
#include "s5h1420.h"
diff --git a/drivers/media/dvb/frontends/sp8870.c b/drivers/media/dvb/frontends/sp8870.c
index 764a95a2e212..1c6b2e9264bc 100644
--- a/drivers/media/dvb/frontends/sp8870.c
+++ b/drivers/media/dvb/frontends/sp8870.c
@@ -32,6 +32,8 @@
#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
#include "sp8870.h"
diff --git a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c
index d868a6927a16..73384e75625e 100644
--- a/drivers/media/dvb/frontends/sp887x.c
+++ b/drivers/media/dvb/frontends/sp887x.c
@@ -14,6 +14,8 @@
#include <linux/moduleparam.h>
#include <linux/device.h>
#include <linux/firmware.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
#include "sp887x.h"
diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c
index 8d09afd7545d..6122ba754bc5 100644
--- a/drivers/media/dvb/frontends/stv0297.c
+++ b/drivers/media/dvb/frontends/stv0297.c
@@ -24,6 +24,8 @@
#include <linux/module.h>
#include <linux/string.h>
#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
#include "stv0297.h"
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c
index 2d62931f20b5..889d9257215d 100644
--- a/drivers/media/dvb/frontends/stv0299.c
+++ b/drivers/media/dvb/frontends/stv0299.c
@@ -48,6 +48,7 @@
#include <linux/moduleparam.h>
#include <linux/string.h>
#include <linux/slab.h>
+#include <linux/jiffies.h>
#include <asm/div64.h>
#include "dvb_frontend.h"
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
index 74cea9f8d721..3529c618f828 100644
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -32,6 +32,10 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
#include "dvb_frontend.h"
#include "tda1004x.h"
diff --git a/drivers/media/dvb/frontends/tda8083.c b/drivers/media/dvb/frontends/tda8083.c
index 168e013d23bd..c05cf1861051 100644
--- a/drivers/media/dvb/frontends/tda8083.c
+++ b/drivers/media/dvb/frontends/tda8083.c
@@ -30,6 +30,7 @@
#include <linux/moduleparam.h>
#include <linux/string.h>
#include <linux/slab.h>
+#include <linux/jiffies.h>
#include "dvb_frontend.h"
#include "tda8083.h"
diff --git a/drivers/media/radio/miropcm20-rds.c b/drivers/media/radio/miropcm20-rds.c
index df79d5e0aaed..e09214082e01 100644
--- a/drivers/media/radio/miropcm20-rds.c
+++ b/drivers/media/radio/miropcm20-rds.c
@@ -14,6 +14,7 @@
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
+#include <linux/sched.h> /* current, TASK_*, schedule_timeout() */
#include <linux/delay.h>
#include <asm/uaccess.h>
#include "miropcm20-rds-core.h"
diff --git a/drivers/media/video/indycam.c b/drivers/media/video/indycam.c
index b2b0384cd4b9..26dd06ec89a2 100644
--- a/drivers/media/video/indycam.c
+++ b/drivers/media/video/indycam.c
@@ -9,16 +9,16 @@
* published by the Free Software Foundation.
*/
-#include <linux/module.h>
-#include <linux/init.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/fs.h>
+#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/major.h>
-#include <linux/slab.h>
+#include <linux/module.h>
#include <linux/mm.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/videodev.h>
/* IndyCam decodes stream of photons into digital image representation ;-) */
@@ -44,8 +44,6 @@ MODULE_LICENSE("GPL");
#define indycam_regdump(client)
#endif
-#define VINO_ADAPTER (I2C_ALGO_SGI | I2C_HW_SGI_VINO)
-
struct indycam {
struct i2c_client *client;
int version;
@@ -300,7 +298,7 @@ out_free_client:
static int indycam_probe(struct i2c_adapter *adap)
{
/* Indy specific crap */
- if (adap->id == VINO_ADAPTER)
+ if (adap->id == I2C_HW_SGI_VINO)
return indycam_attach(adap, INDYCAM_ADDR, 0);
/* Feel free to add probe here :-) */
return -ENODEV;
diff --git a/drivers/media/video/saa7191.c b/drivers/media/video/saa7191.c
index 454f5c1199b4..3ddbb62312be 100644
--- a/drivers/media/video/saa7191.c
+++ b/drivers/media/video/saa7191.c
@@ -9,16 +9,16 @@
* published by the Free Software Foundation.
*/
-#include <linux/module.h>
-#include <linux/init.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/fs.h>
+#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/major.h>
-#include <linux/slab.h>
+#include <linux/module.h>
#include <linux/mm.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/videodev.h>
#include <linux/video_decoder.h>
@@ -33,8 +33,6 @@ MODULE_VERSION(SAA7191_MODULE_VERSION);
MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
MODULE_LICENSE("GPL");
-#define VINO_ADAPTER (I2C_ALGO_SGI | I2C_HW_SGI_VINO)
-
struct saa7191 {
struct i2c_client *client;
@@ -337,7 +335,7 @@ out_free_client:
static int saa7191_probe(struct i2c_adapter *adap)
{
/* Always connected to VINO */
- if (adap->id == VINO_ADAPTER)
+ if (adap->id == I2C_HW_SGI_VINO)
return saa7191_attach(adap, SAA7191_ADDR, 0);
/* Feel free to add probe here :-) */
return -ENODEV;
@@ -364,7 +362,7 @@ static int saa7191_command(struct i2c_client *client, unsigned int cmd,
cap->flags = VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC |
VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO;
- cap->inputs = (client->adapter->id == VINO_ADAPTER) ? 2 : 1;
+ cap->inputs = (client->adapter->id == I2C_HW_SGI_VINO) ? 2 : 1;
cap->outputs = 1;
break;
}
@@ -422,7 +420,7 @@ static int saa7191_command(struct i2c_client *client, unsigned int cmd,
int *iarg = arg;
switch (client->adapter->id) {
- case VINO_ADAPTER:
+ case I2C_HW_SGI_VINO:
return saa7191_set_input(client, *iarg);
default:
if (*iarg != 0)
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index d8a0f763ca10..ed4394e854ab 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -26,14 +26,15 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/delay.h>
+#include <linux/dma-mapping.h>
#include <linux/errno.h>
#include <linux/fs.h>
+#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/dma-mapping.h>
-#include <linux/time.h>
#include <linux/moduleparam.h>
+#include <linux/time.h>
+#include <linux/version.h>
#ifdef CONFIG_KMOD
#include <linux/kmod.h>
diff --git a/drivers/message/i2o/debug.c b/drivers/message/i2o/debug.c
index 018ca887ca85..40d4ea898dbc 100644
--- a/drivers/message/i2o/debug.c
+++ b/drivers/message/i2o/debug.c
@@ -90,7 +90,7 @@ static void i2o_report_fail_status(u8 req_status, u32 * msg)
};
if (req_status == I2O_FSC_TRANSPORT_UNKNOWN_FAILURE)
- printk(KERN_DEBUG "TRANSPORT_UNKNOWN_FAILURE (%0#2x)\n.",
+ printk(KERN_DEBUG "TRANSPORT_UNKNOWN_FAILURE (%0#2x).\n",
req_status);
else
printk(KERN_DEBUG "TRANSPORT_%s.\n",
diff --git a/drivers/message/i2o/device.c b/drivers/message/i2o/device.c
index d9879965eb50..8eb50cdb8ae1 100644
--- a/drivers/message/i2o/device.c
+++ b/drivers/message/i2o/device.c
@@ -16,6 +16,8 @@
#include <linux/module.h>
#include <linux/i2o.h>
#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "core.h"
/**
diff --git a/drivers/message/i2o/driver.c b/drivers/message/i2o/driver.c
index 0079a4be0af2..0fb9c4e2ad4c 100644
--- a/drivers/message/i2o/driver.c
+++ b/drivers/message/i2o/driver.c
@@ -17,6 +17,9 @@
#include <linux/module.h>
#include <linux/rwsem.h>
#include <linux/i2o.h>
+#include <linux/workqueue.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "core.h"
#define OSM_NAME "i2o"
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c
index bda2c62648ba..b675b4ebbebd 100644
--- a/drivers/message/i2o/exec-osm.c
+++ b/drivers/message/i2o/exec-osm.c
@@ -30,6 +30,10 @@
#include <linux/module.h>
#include <linux/i2o.h>
#include <linux/delay.h>
+#include <linux/workqueue.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <asm/param.h> /* HZ */
#include "core.h"
#define OSM_NAME "exec-osm"
diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c
index 361da8d1d5e7..61b837de4b6a 100644
--- a/drivers/message/i2o/iop.c
+++ b/drivers/message/i2o/iop.c
@@ -28,6 +28,7 @@
#include <linux/module.h>
#include <linux/i2o.h>
#include <linux/delay.h>
+#include <linux/sched.h>
#include "core.h"
#define OSM_NAME "i2o"
diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c
index 585cded3d365..a984c0efabf0 100644
--- a/drivers/mfd/ucb1x00-ts.c
+++ b/drivers/mfd/ucb1x00-ts.c
@@ -32,9 +32,12 @@
#include <linux/suspend.h>
#include <linux/slab.h>
#include <linux/kthread.h>
+#include <linux/delay.h>
#include <asm/dma.h>
#include <asm/semaphore.h>
+#include <asm/arch/collie.h>
+#include <asm/mach-types.h>
#include "ucb1x00.h"
@@ -85,12 +88,23 @@ static inline void ucb1x00_ts_mode_int(struct ucb1x00_ts *ts)
*/
static inline unsigned int ucb1x00_ts_read_pressure(struct ucb1x00_ts *ts)
{
- ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
- UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
- UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
- UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
+ if (machine_is_collie()) {
+ ucb1x00_io_write(ts->ucb, COLLIE_TC35143_GPIO_TBL_CHK, 0);
+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
+ UCB_TS_CR_TSPX_POW | UCB_TS_CR_TSMX_POW |
+ UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
- return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
+ udelay(55);
+
+ return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_AD2, ts->adcsync);
+ } else {
+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
+ UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
+
+ return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
+ }
}
/*
@@ -101,12 +115,16 @@ static inline unsigned int ucb1x00_ts_read_pressure(struct ucb1x00_ts *ts)
*/
static inline unsigned int ucb1x00_ts_read_xpos(struct ucb1x00_ts *ts)
{
- ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
- UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
- UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
- ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
- UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
- UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
+ if (machine_is_collie())
+ ucb1x00_io_write(ts->ucb, 0, COLLIE_TC35143_GPIO_TBL_CHK);
+ else {
+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
+ UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
+ UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
+ }
ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
@@ -124,12 +142,17 @@ static inline unsigned int ucb1x00_ts_read_xpos(struct ucb1x00_ts *ts)
*/
static inline unsigned int ucb1x00_ts_read_ypos(struct ucb1x00_ts *ts)
{
- ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
- UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
- UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
- ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
- UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
- UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
+ if (machine_is_collie())
+ ucb1x00_io_write(ts->ucb, 0, COLLIE_TC35143_GPIO_TBL_CHK);
+ else {
+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
+ }
+
ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
@@ -163,6 +186,15 @@ static inline unsigned int ucb1x00_ts_read_yres(struct ucb1x00_ts *ts)
return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync);
}
+static inline int ucb1x00_ts_pen_down(struct ucb1x00_ts *ts)
+{
+ unsigned int val = ucb1x00_reg_read(ts->ucb, UCB_TS_CR);
+ if (machine_is_collie())
+ return (!(val & (UCB_TS_CR_TSPX_LOW)));
+ else
+ return (val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW));
+}
+
/*
* This is a RT kernel thread that handles the ADC accesses
* (mainly so we can use semaphores in the UCB1200 core code
@@ -186,7 +218,7 @@ static int ucb1x00_thread(void *_ts)
add_wait_queue(&ts->irq_wait, &wait);
while (!kthread_should_stop()) {
- unsigned int x, y, p, val;
+ unsigned int x, y, p;
signed long timeout;
ts->restart = 0;
@@ -206,12 +238,12 @@ static int ucb1x00_thread(void *_ts)
msleep(10);
ucb1x00_enable(ts->ucb);
- val = ucb1x00_reg_read(ts->ucb, UCB_TS_CR);
- if (val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW)) {
+
+ if (ucb1x00_ts_pen_down(ts)) {
set_task_state(tsk, TASK_INTERRUPTIBLE);
- ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING);
+ ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, machine_is_collie() ? UCB_RISING : UCB_FALLING);
ucb1x00_disable(ts->ucb);
/*
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 4991bbd054f3..c483a863b116 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -60,4 +60,13 @@ config MMC_WBSD
If unsure, say N.
+config MMC_AU1X
+ tristate "Alchemy AU1XX0 MMC Card Interface support"
+ depends on SOC_AU1X00 && MMC
+ help
+ This selects the AMD Alchemy(R) Multimedia card interface.
+ iIf you have a Alchemy platform with a MMC slot, say Y or M here.
+
+ If unsure, say N.
+
endmenu
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 89510c2086c7..e351e71146e9 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -18,5 +18,6 @@ obj-$(CONFIG_MMC_BLOCK) += mmc_block.o
obj-$(CONFIG_MMC_ARMMMCI) += mmci.o
obj-$(CONFIG_MMC_PXA) += pxamci.o
obj-$(CONFIG_MMC_WBSD) += wbsd.o
+obj-$(CONFIG_MMC_AU1X) += au1xmmc.o
mmc_core-y := mmc.o mmc_queue.o mmc_sysfs.o
diff --git a/drivers/mmc/au1xmmc.c b/drivers/mmc/au1xmmc.c
new file mode 100644
index 000000000000..aaf04638054e
--- /dev/null
+++ b/drivers/mmc/au1xmmc.c
@@ -0,0 +1,1026 @@
+/*
+ * linux/drivers/mmc/au1xmmc.c - AU1XX0 MMC driver
+ *
+ * Copyright (c) 2005, Advanced Micro Devices, Inc.
+ *
+ * Developed with help from the 2.4.30 MMC AU1XXX controller including
+ * the following copyright notices:
+ * Copyright (c) 2003-2004 Embedded Edge, LLC.
+ * Portions Copyright (C) 2002 Embedix, Inc
+ * Copyright 2002 Hewlett-Packard Company
+
+ * 2.6 version of this driver inspired by:
+ * (drivers/mmc/wbsd.c) Copyright (C) 2004-2005 Pierre Ossman,
+ * All Rights Reserved.
+ * (drivers/mmc/pxa.c) Copyright (C) 2003 Russell King,
+ * All Rights Reserved.
+ *
+
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/* Why is a timer used to detect insert events?
+ *
+ * From the AU1100 MMC application guide:
+ * If the Au1100-based design is intended to support both MultiMediaCards
+ * and 1- or 4-data bit SecureDigital cards, then the solution is to
+ * connect a weak (560KOhm) pull-up resistor to connector pin 1.
+ * In doing so, a MMC card never enters SPI-mode communications,
+ * but now the SecureDigital card-detect feature of CD/DAT3 is ineffective
+ * (the low to high transition will not occur).
+ *
+ * So we use the timer to check the status manually.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+
+#include <linux/mmc/host.h>
+#include <linux/mmc/protocol.h>
+#include <asm/io.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/au1xxx_dbdma.h>
+#include <asm/mach-au1x00/au1100_mmc.h>
+#include <asm/scatterlist.h>
+
+#include <au1xxx.h>
+#include "au1xmmc.h"
+
+#define DRIVER_NAME "au1xxx-mmc"
+
+/* Set this to enable special debugging macros */
+/* #define MMC_DEBUG */
+
+#ifdef MMC_DEBUG
+#define DEBUG(fmt, idx, args...) printk("au1xx(%d): DEBUG: " fmt, idx, ##args)
+#else
+#define DEBUG(fmt, idx, args...)
+#endif
+
+const struct {
+ u32 iobase;
+ u32 tx_devid, rx_devid;
+ u16 bcsrpwr;
+ u16 bcsrstatus;
+ u16 wpstatus;
+} au1xmmc_card_table[] = {
+ { SD0_BASE, DSCR_CMD0_SDMS_TX0, DSCR_CMD0_SDMS_RX0,
+ BCSR_BOARD_SD0PWR, BCSR_INT_SD0INSERT, BCSR_STATUS_SD0WP },
+#ifndef CONFIG_MIPS_DB1200
+ { SD1_BASE, DSCR_CMD0_SDMS_TX1, DSCR_CMD0_SDMS_RX1,
+ BCSR_BOARD_DS1PWR, BCSR_INT_SD1INSERT, BCSR_STATUS_SD1WP }
+#endif
+};
+
+#define AU1XMMC_CONTROLLER_COUNT \
+ (sizeof(au1xmmc_card_table) / sizeof(au1xmmc_card_table[0]))
+
+/* This array stores pointers for the hosts (used by the IRQ handler) */
+struct au1xmmc_host *au1xmmc_hosts[AU1XMMC_CONTROLLER_COUNT];
+static int dma = 1;
+
+#ifdef MODULE
+MODULE_PARM(dma, "i");
+MODULE_PARM_DESC(dma, "Use DMA engine for data transfers (0 = disabled)");
+#endif
+
+static inline void IRQ_ON(struct au1xmmc_host *host, u32 mask)
+{
+ u32 val = au_readl(HOST_CONFIG(host));
+ val |= mask;
+ au_writel(val, HOST_CONFIG(host));
+ au_sync();
+}
+
+static inline void FLUSH_FIFO(struct au1xmmc_host *host)
+{
+ u32 val = au_readl(HOST_CONFIG2(host));
+
+ au_writel(val | SD_CONFIG2_FF, HOST_CONFIG2(host));
+ au_sync_delay(1);
+
+ /* SEND_STOP will turn off clock control - this re-enables it */
+ val &= ~SD_CONFIG2_DF;
+
+ au_writel(val, HOST_CONFIG2(host));
+ au_sync();
+}
+
+static inline void IRQ_OFF(struct au1xmmc_host *host, u32 mask)
+{
+ u32 val = au_readl(HOST_CONFIG(host));
+ val &= ~mask;
+ au_writel(val, HOST_CONFIG(host));
+ au_sync();
+}
+
+static inline void SEND_STOP(struct au1xmmc_host *host)
+{
+
+ /* We know the value of CONFIG2, so avoid a read we don't need */
+ u32 mask = SD_CONFIG2_EN;
+
+ WARN_ON(host->status != HOST_S_DATA);
+ host->status = HOST_S_STOP;
+
+ au_writel(mask | SD_CONFIG2_DF, HOST_CONFIG2(host));
+ au_sync();
+
+ /* Send the stop commmand */
+ au_writel(STOP_CMD, HOST_CMD(host));
+}
+
+static void au1xmmc_set_power(struct au1xmmc_host *host, int state)
+{
+
+ u32 val = au1xmmc_card_table[host->id].bcsrpwr;
+
+ bcsr->board &= ~val;
+ if (state) bcsr->board |= val;
+
+ au_sync_delay(1);
+}
+
+static inline int au1xmmc_card_inserted(struct au1xmmc_host *host)
+{
+ return (bcsr->sig_status & au1xmmc_card_table[host->id].bcsrstatus)
+ ? 1 : 0;
+}
+
+static inline int au1xmmc_card_readonly(struct au1xmmc_host *host)
+{
+ return (bcsr->status & au1xmmc_card_table[host->id].wpstatus)
+ ? 1 : 0;
+}
+
+static void au1xmmc_finish_request(struct au1xmmc_host *host)
+{
+
+ struct mmc_request *mrq = host->mrq;
+
+ host->mrq = NULL;
+ host->flags &= HOST_F_ACTIVE;
+
+ host->dma.len = 0;
+ host->dma.dir = 0;
+
+ host->pio.index = 0;
+ host->pio.offset = 0;
+ host->pio.len = 0;
+
+ host->status = HOST_S_IDLE;
+
+ bcsr->disk_leds |= (1 << 8);
+
+ mmc_request_done(host->mmc, mrq);
+}
+
+static void au1xmmc_tasklet_finish(unsigned long param)
+{
+ struct au1xmmc_host *host = (struct au1xmmc_host *) param;
+ au1xmmc_finish_request(host);
+}
+
+static int au1xmmc_send_command(struct au1xmmc_host *host, int wait,
+ struct mmc_command *cmd)
+{
+
+ u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT);
+
+ switch(cmd->flags) {
+ case MMC_RSP_R1:
+ mmccmd |= SD_CMD_RT_1;
+ break;
+ case MMC_RSP_R1B:
+ mmccmd |= SD_CMD_RT_1B;
+ break;
+ case MMC_RSP_R2:
+ mmccmd |= SD_CMD_RT_2;
+ break;
+ case MMC_RSP_R3:
+ mmccmd |= SD_CMD_RT_3;
+ break;
+ }
+
+ switch(cmd->opcode) {
+ case MMC_READ_SINGLE_BLOCK:
+ case SD_APP_SEND_SCR:
+ mmccmd |= SD_CMD_CT_2;
+ break;
+ case MMC_READ_MULTIPLE_BLOCK:
+ mmccmd |= SD_CMD_CT_4;
+ break;
+ case MMC_WRITE_BLOCK:
+ mmccmd |= SD_CMD_CT_1;
+ break;
+
+ case MMC_WRITE_MULTIPLE_BLOCK:
+ mmccmd |= SD_CMD_CT_3;
+ break;
+ case MMC_STOP_TRANSMISSION:
+ mmccmd |= SD_CMD_CT_7;
+ break;
+ }
+
+ au_writel(cmd->arg, HOST_CMDARG(host));
+ au_sync();
+
+ if (wait)
+ IRQ_OFF(host, SD_CONFIG_CR);
+
+ au_writel((mmccmd | SD_CMD_GO), HOST_CMD(host));
+ au_sync();
+
+ /* Wait for the command to go on the line */
+
+ while(1) {
+ if (!(au_readl(HOST_CMD(host)) & SD_CMD_GO))
+ break;
+ }
+
+ /* Wait for the command to come back */
+
+ if (wait) {
+ u32 status = au_readl(HOST_STATUS(host));
+
+ while(!(status & SD_STATUS_CR))
+ status = au_readl(HOST_STATUS(host));
+
+ /* Clear the CR status */
+ au_writel(SD_STATUS_CR, HOST_STATUS(host));
+
+ IRQ_ON(host, SD_CONFIG_CR);
+ }
+
+ return MMC_ERR_NONE;
+}
+
+static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status)
+{
+
+ struct mmc_request *mrq = host->mrq;
+ struct mmc_data *data;
+ u32 crc;
+
+ WARN_ON(host->status != HOST_S_DATA && host->status != HOST_S_STOP);
+
+ if (host->mrq == NULL)
+ return;
+
+ data = mrq->cmd->data;
+
+ if (status == 0)
+ status = au_readl(HOST_STATUS(host));
+
+ /* The transaction is really over when the SD_STATUS_DB bit is clear */
+
+ while((host->flags & HOST_F_XMIT) && (status & SD_STATUS_DB))
+ status = au_readl(HOST_STATUS(host));
+
+ data->error = MMC_ERR_NONE;
+ dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma.dir);
+
+ /* Process any errors */
+
+ crc = (status & (SD_STATUS_WC | SD_STATUS_RC));
+ if (host->flags & HOST_F_XMIT)
+ crc |= ((status & 0x07) == 0x02) ? 0 : 1;
+
+ if (crc)
+ data->error = MMC_ERR_BADCRC;
+
+ /* Clear the CRC bits */
+ au_writel(SD_STATUS_WC | SD_STATUS_RC, HOST_STATUS(host));
+
+ data->bytes_xfered = 0;
+
+ if (data->error == MMC_ERR_NONE) {
+ if (host->flags & HOST_F_DMA) {
+ u32 chan = DMA_CHANNEL(host);
+
+ chan_tab_t *c = *((chan_tab_t **) chan);
+ au1x_dma_chan_t *cp = c->chan_ptr;
+ data->bytes_xfered = cp->ddma_bytecnt;
+ }
+ else
+ data->bytes_xfered =
+ (data->blocks * (1 << data->blksz_bits)) -
+ host->pio.len;
+ }
+
+ au1xmmc_finish_request(host);
+}
+
+static void au1xmmc_tasklet_data(unsigned long param)
+{
+ struct au1xmmc_host *host = (struct au1xmmc_host *) param;
+
+ u32 status = au_readl(HOST_STATUS(host));
+ au1xmmc_data_complete(host, status);
+}
+
+#define AU1XMMC_MAX_TRANSFER 8
+
+static void au1xmmc_send_pio(struct au1xmmc_host *host)
+{
+
+ struct mmc_data *data = 0;
+ int sg_len, max, count = 0;
+ unsigned char *sg_ptr;
+ u32 status = 0;
+ struct scatterlist *sg;
+
+ data = host->mrq->data;
+
+ if (!(host->flags & HOST_F_XMIT))
+ return;
+
+ /* This is the pointer to the data buffer */
+ sg = &data->sg[host->pio.index];
+ sg_ptr = page_address(sg->page) + sg->offset + host->pio.offset;
+
+ /* This is the space left inside the buffer */
+ sg_len = data->sg[host->pio.index].length - host->pio.offset;
+
+ /* Check to if we need less then the size of the sg_buffer */
+
+ max = (sg_len > host->pio.len) ? host->pio.len : sg_len;
+ if (max > AU1XMMC_MAX_TRANSFER) max = AU1XMMC_MAX_TRANSFER;
+
+ for(count = 0; count < max; count++ ) {
+ unsigned char val;
+
+ status = au_readl(HOST_STATUS(host));
+
+ if (!(status & SD_STATUS_TH))
+ break;
+
+ val = *sg_ptr++;
+
+ au_writel((unsigned long) val, HOST_TXPORT(host));
+ au_sync();
+ }
+
+ host->pio.len -= count;
+ host->pio.offset += count;
+
+ if (count == sg_len) {
+ host->pio.index++;
+ host->pio.offset = 0;
+ }
+
+ if (host->pio.len == 0) {
+ IRQ_OFF(host, SD_CONFIG_TH);
+
+ if (host->flags & HOST_F_STOP)
+ SEND_STOP(host);
+
+ tasklet_schedule(&host->data_task);
+ }
+}
+
+static void au1xmmc_receive_pio(struct au1xmmc_host *host)
+{
+
+ struct mmc_data *data = 0;
+ int sg_len = 0, max = 0, count = 0;
+ unsigned char *sg_ptr = 0;
+ u32 status = 0;
+ struct scatterlist *sg;
+
+ data = host->mrq->data;
+
+ if (!(host->flags & HOST_F_RECV))
+ return;
+
+ max = host->pio.len;
+
+ if (host->pio.index < host->dma.len) {
+ sg = &data->sg[host->pio.index];
+ sg_ptr = page_address(sg->page) + sg->offset + host->pio.offset;
+
+ /* This is the space left inside the buffer */
+ sg_len = sg_dma_len(&data->sg[host->pio.index]) - host->pio.offset;
+
+ /* Check to if we need less then the size of the sg_buffer */
+ if (sg_len < max) max = sg_len;
+ }
+
+ if (max > AU1XMMC_MAX_TRANSFER)
+ max = AU1XMMC_MAX_TRANSFER;
+
+ for(count = 0; count < max; count++ ) {
+ u32 val;
+ status = au_readl(HOST_STATUS(host));
+
+ if (!(status & SD_STATUS_NE))
+ break;
+
+ if (status & SD_STATUS_RC) {
+ DEBUG("RX CRC Error [%d + %d].\n", host->id,
+ host->pio.len, count);
+ break;
+ }
+
+ if (status & SD_STATUS_RO) {
+ DEBUG("RX Overrun [%d + %d]\n", host->id,
+ host->pio.len, count);
+ break;
+ }
+ else if (status & SD_STATUS_RU) {
+ DEBUG("RX Underrun [%d + %d]\n", host->id,
+ host->pio.len, count);
+ break;
+ }
+
+ val = au_readl(HOST_RXPORT(host));
+
+ if (sg_ptr)
+ *sg_ptr++ = (unsigned char) (val & 0xFF);
+ }
+
+ host->pio.len -= count;
+ host->pio.offset += count;
+
+ if (sg_len && count == sg_len) {
+ host->pio.index++;
+ host->pio.offset = 0;
+ }
+
+ if (host->pio.len == 0) {
+ //IRQ_OFF(host, SD_CONFIG_RA | SD_CONFIG_RF);
+ IRQ_OFF(host, SD_CONFIG_NE);
+
+ if (host->flags & HOST_F_STOP)
+ SEND_STOP(host);
+
+ tasklet_schedule(&host->data_task);
+ }
+}
+
+/* static void au1xmmc_cmd_complete
+ This is called when a command has been completed - grab the response
+ and check for errors. Then start the data transfer if it is indicated.
+*/
+
+static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status)
+{
+
+ struct mmc_request *mrq = host->mrq;
+ struct mmc_command *cmd;
+ int trans;
+
+ if (!host->mrq)
+ return;
+
+ cmd = mrq->cmd;
+ cmd->error = MMC_ERR_NONE;
+
+ if ((cmd->flags & MMC_RSP_MASK) == MMC_RSP_SHORT) {
+
+ /* Techincally, we should be getting all 48 bits of the response
+ * (SD_RESP1 + SD_RESP2), but because our response omits the CRC,
+ * our data ends up being shifted 8 bits to the right. In this case,
+ * that means that the OSR data starts at bit 31, so we can just
+ * read RESP0 and return that
+ */
+
+ cmd->resp[0] = au_readl(host->iobase + SD_RESP0);
+ }
+ else if ((cmd->flags & MMC_RSP_MASK) == MMC_RSP_LONG) {
+ u32 r[4];
+ int i;
+
+ r[0] = au_readl(host->iobase + SD_RESP3);
+ r[1] = au_readl(host->iobase + SD_RESP2);
+ r[2] = au_readl(host->iobase + SD_RESP1);
+ r[3] = au_readl(host->iobase + SD_RESP0);
+
+ /* The CRC is omitted from the response, so really we only got
+ * 120 bytes, but the engine expects 128 bits, so we have to shift
+ * things up
+ */
+
+ for(i = 0; i < 4; i++) {
+ cmd->resp[i] = (r[i] & 0x00FFFFFF) << 8;
+ if (i != 3) cmd->resp[i] |= (r[i + 1] & 0xFF000000) >> 24;
+ }
+ }
+
+ /* Figure out errors */
+
+ if (status & (SD_STATUS_SC | SD_STATUS_WC | SD_STATUS_RC))
+ cmd->error = MMC_ERR_BADCRC;
+
+ trans = host->flags & (HOST_F_XMIT | HOST_F_RECV);
+
+ if (!trans || cmd->error != MMC_ERR_NONE) {
+
+ IRQ_OFF(host, SD_CONFIG_TH | SD_CONFIG_RA|SD_CONFIG_RF);
+ tasklet_schedule(&host->finish_task);
+ return;
+ }
+
+ host->status = HOST_S_DATA;
+
+ if (host->flags & HOST_F_DMA) {
+ u32 channel = DMA_CHANNEL(host);
+
+ /* Start the DMA as soon as the buffer gets something in it */
+
+ if (host->flags & HOST_F_RECV) {
+ u32 mask = SD_STATUS_DB | SD_STATUS_NE;
+
+ while((status & mask) != mask)
+ status = au_readl(HOST_STATUS(host));
+ }
+
+ au1xxx_dbdma_start(channel);
+ }
+}
+
+static void au1xmmc_set_clock(struct au1xmmc_host *host, int rate)
+{
+
+ unsigned int pbus = get_au1x00_speed();
+ unsigned int divisor;
+ u32 config;
+
+ /* From databook:
+ divisor = ((((cpuclock / sbus_divisor) / 2) / mmcclock) / 2) - 1
+ */
+
+ pbus /= ((au_readl(SYS_POWERCTRL) & 0x3) + 2);
+ pbus /= 2;
+
+ divisor = ((pbus / rate) / 2) - 1;
+
+ config = au_readl(HOST_CONFIG(host));
+
+ config &= ~(SD_CONFIG_DIV);
+ config |= (divisor & SD_CONFIG_DIV) | SD_CONFIG_DE;
+
+ au_writel(config, HOST_CONFIG(host));
+ au_sync();
+}
+
+static int
+au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data)
+{
+
+ int datalen = data->blocks * (1 << data->blksz_bits);
+
+ if (dma != 0)
+ host->flags |= HOST_F_DMA;
+
+ if (data->flags & MMC_DATA_READ)
+ host->flags |= HOST_F_RECV;
+ else
+ host->flags |= HOST_F_XMIT;
+
+ if (host->mrq->stop)
+ host->flags |= HOST_F_STOP;
+
+ host->dma.dir = DMA_BIDIRECTIONAL;
+
+ host->dma.len = dma_map_sg(mmc_dev(host->mmc), data->sg,
+ data->sg_len, host->dma.dir);
+
+ if (host->dma.len == 0)
+ return MMC_ERR_TIMEOUT;
+
+ au_writel((1 << data->blksz_bits) - 1, HOST_BLKSIZE(host));
+
+ if (host->flags & HOST_F_DMA) {
+ int i;
+ u32 channel = DMA_CHANNEL(host);
+
+ au1xxx_dbdma_stop(channel);
+
+ for(i = 0; i < host->dma.len; i++) {
+ u32 ret = 0, flags = DDMA_FLAGS_NOIE;
+ struct scatterlist *sg = &data->sg[i];
+ int sg_len = sg->length;
+
+ int len = (datalen > sg_len) ? sg_len : datalen;
+
+ if (i == host->dma.len - 1)
+ flags = DDMA_FLAGS_IE;
+
+ if (host->flags & HOST_F_XMIT){
+ ret = au1xxx_dbdma_put_source_flags(channel,
+ (void *) (page_address(sg->page) +
+ sg->offset),
+ len, flags);
+ }
+ else {
+ ret = au1xxx_dbdma_put_dest_flags(channel,
+ (void *) (page_address(sg->page) +
+ sg->offset),
+ len, flags);
+ }
+
+ if (!ret)
+ goto dataerr;
+
+ datalen -= len;
+ }
+ }
+ else {
+ host->pio.index = 0;
+ host->pio.offset = 0;
+ host->pio.len = datalen;
+
+ if (host->flags & HOST_F_XMIT)
+ IRQ_ON(host, SD_CONFIG_TH);
+ else
+ IRQ_ON(host, SD_CONFIG_NE);
+ //IRQ_ON(host, SD_CONFIG_RA|SD_CONFIG_RF);
+ }
+
+ return MMC_ERR_NONE;
+
+ dataerr:
+ dma_unmap_sg(mmc_dev(host->mmc),data->sg,data->sg_len,host->dma.dir);
+ return MMC_ERR_TIMEOUT;
+}
+
+/* static void au1xmmc_request
+ This actually starts a command or data transaction
+*/
+
+static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq)
+{
+
+ struct au1xmmc_host *host = mmc_priv(mmc);
+ int ret = MMC_ERR_NONE;
+
+ WARN_ON(irqs_disabled());
+ WARN_ON(host->status != HOST_S_IDLE);
+
+ host->mrq = mrq;
+ host->status = HOST_S_CMD;
+
+ bcsr->disk_leds &= ~(1 << 8);
+
+ if (mrq->data) {
+ FLUSH_FIFO(host);
+ ret = au1xmmc_prepare_data(host, mrq->data);
+ }
+
+ if (ret == MMC_ERR_NONE)
+ ret = au1xmmc_send_command(host, 0, mrq->cmd);
+
+ if (ret != MMC_ERR_NONE) {
+ mrq->cmd->error = ret;
+ au1xmmc_finish_request(host);
+ }
+}
+
+static void au1xmmc_reset_controller(struct au1xmmc_host *host)
+{
+
+ /* Apply the clock */
+ au_writel(SD_ENABLE_CE, HOST_ENABLE(host));
+ au_sync_delay(1);
+
+ au_writel(SD_ENABLE_R | SD_ENABLE_CE, HOST_ENABLE(host));
+ au_sync_delay(5);
+
+ au_writel(~0, HOST_STATUS(host));
+ au_sync();
+
+ au_writel(0, HOST_BLKSIZE(host));
+ au_writel(0x001fffff, HOST_TIMEOUT(host));
+ au_sync();
+
+ au_writel(SD_CONFIG2_EN, HOST_CONFIG2(host));
+ au_sync();
+
+ au_writel(SD_CONFIG2_EN | SD_CONFIG2_FF, HOST_CONFIG2(host));
+ au_sync_delay(1);
+
+ au_writel(SD_CONFIG2_EN, HOST_CONFIG2(host));
+ au_sync();
+
+ /* Configure interrupts */
+ au_writel(AU1XMMC_INTERRUPTS, HOST_CONFIG(host));
+ au_sync();
+}
+
+
+static void au1xmmc_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
+{
+ struct au1xmmc_host *host = mmc_priv(mmc);
+
+ DEBUG("set_ios (power=%u, clock=%uHz, vdd=%u, mode=%u)\n",
+ host->id, ios->power_mode, ios->clock, ios->vdd,
+ ios->bus_mode);
+
+ if (ios->power_mode == MMC_POWER_OFF)
+ au1xmmc_set_power(host, 0);
+ else if (ios->power_mode == MMC_POWER_ON) {
+ au1xmmc_set_power(host, 1);
+ }
+
+ if (ios->clock && ios->clock != host->clock) {
+ au1xmmc_set_clock(host, ios->clock);
+ host->clock = ios->clock;
+ }
+}
+
+static void au1xmmc_dma_callback(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct au1xmmc_host *host = (struct au1xmmc_host *) dev_id;
+ u32 status;
+
+ /* Avoid spurious interrupts */
+
+ if (!host->mrq)
+ return;
+
+ if (host->flags & HOST_F_STOP)
+ SEND_STOP(host);
+
+ tasklet_schedule(&host->data_task);
+}
+
+#define STATUS_TIMEOUT (SD_STATUS_RAT | SD_STATUS_DT)
+#define STATUS_DATA_IN (SD_STATUS_NE)
+#define STATUS_DATA_OUT (SD_STATUS_TH)
+
+static irqreturn_t au1xmmc_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+
+ u32 status;
+ int i, ret = 0;
+
+ disable_irq(AU1100_SD_IRQ);
+
+ for(i = 0; i < AU1XMMC_CONTROLLER_COUNT; i++) {
+ struct au1xmmc_host * host = au1xmmc_hosts[i];
+ u32 handled = 1;
+
+ status = au_readl(HOST_STATUS(host));
+
+ if (host->mrq && (status & STATUS_TIMEOUT)) {
+ if (status & SD_STATUS_RAT)
+ host->mrq->cmd->error = MMC_ERR_TIMEOUT;
+
+ else if (status & SD_STATUS_DT)
+ host->mrq->data->error = MMC_ERR_TIMEOUT;
+
+ /* In PIO mode, interrupts might still be enabled */
+ IRQ_OFF(host, SD_CONFIG_NE | SD_CONFIG_TH);
+
+ //IRQ_OFF(host, SD_CONFIG_TH|SD_CONFIG_RA|SD_CONFIG_RF);
+ tasklet_schedule(&host->finish_task);
+ }
+#if 0
+ else if (status & SD_STATUS_DD) {
+
+ /* Sometimes we get a DD before a NE in PIO mode */
+
+ if (!(host->flags & HOST_F_DMA) &&
+ (status & SD_STATUS_NE))
+ au1xmmc_receive_pio(host);
+ else {
+ au1xmmc_data_complete(host, status);
+ //tasklet_schedule(&host->data_task);
+ }
+ }
+#endif
+ else if (status & (SD_STATUS_CR)) {
+ if (host->status == HOST_S_CMD)
+ au1xmmc_cmd_complete(host,status);
+ }
+ else if (!(host->flags & HOST_F_DMA)) {
+ if ((host->flags & HOST_F_XMIT) &&
+ (status & STATUS_DATA_OUT))
+ au1xmmc_send_pio(host);
+ else if ((host->flags & HOST_F_RECV) &&
+ (status & STATUS_DATA_IN))
+ au1xmmc_receive_pio(host);
+ }
+ else if (status & 0x203FBC70) {
+ DEBUG("Unhandled status %8.8x\n", host->id, status);
+ handled = 0;
+ }
+
+ au_writel(status, HOST_STATUS(host));
+ au_sync();
+
+ ret |= handled;
+ }
+
+ enable_irq(AU1100_SD_IRQ);
+ return ret;
+}
+
+static void au1xmmc_poll_event(unsigned long arg)
+{
+ struct au1xmmc_host *host = (struct au1xmmc_host *) arg;
+
+ int card = au1xmmc_card_inserted(host);
+ int controller = (host->flags & HOST_F_ACTIVE) ? 1 : 0;
+
+ if (card != controller) {
+ host->flags &= ~HOST_F_ACTIVE;
+ if (card) host->flags |= HOST_F_ACTIVE;
+ mmc_detect_change(host->mmc, 0);
+ }
+
+ if (host->mrq != NULL) {
+ u32 status = au_readl(HOST_STATUS(host));
+ DEBUG("PENDING - %8.8x\n", host->id, status);
+ }
+
+ mod_timer(&host->timer, jiffies + AU1XMMC_DETECT_TIMEOUT);
+}
+
+static dbdev_tab_t au1xmmc_mem_dbdev =
+{
+ DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 8, 0x00000000, 0, 0
+};
+
+static void au1xmmc_init_dma(struct au1xmmc_host *host)
+{
+
+ u32 rxchan, txchan;
+
+ int txid = au1xmmc_card_table[host->id].tx_devid;
+ int rxid = au1xmmc_card_table[host->id].rx_devid;
+
+ /* DSCR_CMD0_ALWAYS has a stride of 32 bits, we need a stride
+ of 8 bits. And since devices are shared, we need to create
+ our own to avoid freaking out other devices
+ */
+
+ int memid = au1xxx_ddma_add_device(&au1xmmc_mem_dbdev);
+
+ txchan = au1xxx_dbdma_chan_alloc(memid, txid,
+ au1xmmc_dma_callback, (void *) host);
+
+ rxchan = au1xxx_dbdma_chan_alloc(rxid, memid,
+ au1xmmc_dma_callback, (void *) host);
+
+ au1xxx_dbdma_set_devwidth(txchan, 8);
+ au1xxx_dbdma_set_devwidth(rxchan, 8);
+
+ au1xxx_dbdma_ring_alloc(txchan, AU1XMMC_DESCRIPTOR_COUNT);
+ au1xxx_dbdma_ring_alloc(rxchan, AU1XMMC_DESCRIPTOR_COUNT);
+
+ host->tx_chan = txchan;
+ host->rx_chan = rxchan;
+}
+
+struct mmc_host_ops au1xmmc_ops = {
+ .request = au1xmmc_request,
+ .set_ios = au1xmmc_set_ios,
+};
+
+static int au1xmmc_probe(struct device *dev)
+{
+
+ int i, ret = 0;
+
+ /* THe interrupt is shared among all controllers */
+ ret = request_irq(AU1100_SD_IRQ, au1xmmc_irq, SA_INTERRUPT, "MMC", 0);
+
+ if (ret) {
+ printk(DRIVER_NAME "ERROR: Couldn't get int %d: %d\n",
+ AU1100_SD_IRQ, ret);
+ return -ENXIO;
+ }
+
+ disable_irq(AU1100_SD_IRQ);
+
+ for(i = 0; i < AU1XMMC_CONTROLLER_COUNT; i++) {
+ struct mmc_host *mmc = mmc_alloc_host(sizeof(struct au1xmmc_host), dev);
+ struct au1xmmc_host *host = 0;
+
+ if (!mmc) {
+ printk(DRIVER_NAME "ERROR: no mem for host %d\n", i);
+ au1xmmc_hosts[i] = 0;
+ continue;
+ }
+
+ mmc->ops = &au1xmmc_ops;
+
+ mmc->f_min = 450000;
+ mmc->f_max = 24000000;
+
+ mmc->max_seg_size = AU1XMMC_DESCRIPTOR_SIZE;
+ mmc->max_phys_segs = AU1XMMC_DESCRIPTOR_COUNT;
+
+ mmc->ocr_avail = AU1XMMC_OCR;
+
+ host = mmc_priv(mmc);
+ host->mmc = mmc;
+
+ host->id = i;
+ host->iobase = au1xmmc_card_table[host->id].iobase;
+ host->clock = 0;
+ host->power_mode = MMC_POWER_OFF;
+
+ host->flags = au1xmmc_card_inserted(host) ? HOST_F_ACTIVE : 0;
+ host->status = HOST_S_IDLE;
+
+ init_timer(&host->timer);
+
+ host->timer.function = au1xmmc_poll_event;
+ host->timer.data = (unsigned long) host;
+ host->timer.expires = jiffies + AU1XMMC_DETECT_TIMEOUT;
+
+ tasklet_init(&host->data_task, au1xmmc_tasklet_data,
+ (unsigned long) host);
+
+ tasklet_init(&host->finish_task, au1xmmc_tasklet_finish,
+ (unsigned long) host);
+
+ spin_lock_init(&host->lock);
+
+ if (dma != 0)
+ au1xmmc_init_dma(host);
+
+ au1xmmc_reset_controller(host);
+
+ mmc_add_host(mmc);
+ au1xmmc_hosts[i] = host;
+
+ add_timer(&host->timer);
+
+ printk(KERN_INFO DRIVER_NAME ": MMC Controller %d set up at %8.8X (mode=%s)\n",
+ host->id, host->iobase, dma ? "dma" : "pio");
+ }
+
+ enable_irq(AU1100_SD_IRQ);
+
+ return 0;
+}
+
+static int au1xmmc_remove(struct device *dev)
+{
+
+ int i;
+
+ disable_irq(AU1100_SD_IRQ);
+
+ for(i = 0; i < AU1XMMC_CONTROLLER_COUNT; i++) {
+ struct au1xmmc_host *host = au1xmmc_hosts[i];
+ if (!host) continue;
+
+ tasklet_kill(&host->data_task);
+ tasklet_kill(&host->finish_task);
+
+ del_timer_sync(&host->timer);
+ au1xmmc_set_power(host, 0);
+
+ mmc_remove_host(host->mmc);
+
+ au1xxx_dbdma_chan_free(host->tx_chan);
+ au1xxx_dbdma_chan_free(host->rx_chan);
+
+ au_writel(0x0, HOST_ENABLE(host));
+ au_sync();
+ }
+
+ free_irq(AU1100_SD_IRQ, 0);
+ return 0;
+}
+
+static struct device_driver au1xmmc_driver = {
+ .name = DRIVER_NAME,
+ .bus = &platform_bus_type,
+ .probe = au1xmmc_probe,
+ .remove = au1xmmc_remove,
+ .suspend = NULL,
+ .resume = NULL
+};
+
+static int __init au1xmmc_init(void)
+{
+ return driver_register(&au1xmmc_driver);
+}
+
+static void __exit au1xmmc_exit(void)
+{
+ driver_unregister(&au1xmmc_driver);
+}
+
+module_init(au1xmmc_init);
+module_exit(au1xmmc_exit);
+
+#ifdef MODULE
+MODULE_AUTHOR("Advanced Micro Devices, Inc");
+MODULE_DESCRIPTION("MMC/SD driver for the Alchemy Au1XXX");
+MODULE_LICENSE("GPL");
+#endif
+
diff --git a/drivers/mmc/au1xmmc.h b/drivers/mmc/au1xmmc.h
new file mode 100644
index 000000000000..341cbdf0baca
--- /dev/null
+++ b/drivers/mmc/au1xmmc.h
@@ -0,0 +1,96 @@
+#ifndef _AU1XMMC_H_
+#define _AU1XMMC_H_
+
+/* Hardware definitions */
+
+#define AU1XMMC_DESCRIPTOR_COUNT 1
+#define AU1XMMC_DESCRIPTOR_SIZE 2048
+
+#define AU1XMMC_OCR ( MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30 | \
+ MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33 | \
+ MMC_VDD_33_34 | MMC_VDD_34_35 | MMC_VDD_35_36)
+
+/* Easy access macros */
+
+#define HOST_STATUS(h) ((h)->iobase + SD_STATUS)
+#define HOST_CONFIG(h) ((h)->iobase + SD_CONFIG)
+#define HOST_ENABLE(h) ((h)->iobase + SD_ENABLE)
+#define HOST_TXPORT(h) ((h)->iobase + SD_TXPORT)
+#define HOST_RXPORT(h) ((h)->iobase + SD_RXPORT)
+#define HOST_CMDARG(h) ((h)->iobase + SD_CMDARG)
+#define HOST_BLKSIZE(h) ((h)->iobase + SD_BLKSIZE)
+#define HOST_CMD(h) ((h)->iobase + SD_CMD)
+#define HOST_CONFIG2(h) ((h)->iobase + SD_CONFIG2)
+#define HOST_TIMEOUT(h) ((h)->iobase + SD_TIMEOUT)
+#define HOST_DEBUG(h) ((h)->iobase + SD_DEBUG)
+
+#define DMA_CHANNEL(h) \
+ ( ((h)->flags & HOST_F_XMIT) ? (h)->tx_chan : (h)->rx_chan)
+
+/* This gives us a hard value for the stop command that we can write directly
+ * to the command register
+ */
+
+#define STOP_CMD (SD_CMD_RT_1B|SD_CMD_CT_7|(0xC << SD_CMD_CI_SHIFT)|SD_CMD_GO)
+
+/* This is the set of interrupts that we configure by default */
+
+#if 0
+#define AU1XMMC_INTERRUPTS (SD_CONFIG_SC | SD_CONFIG_DT | SD_CONFIG_DD | \
+ SD_CONFIG_RAT | SD_CONFIG_CR | SD_CONFIG_I)
+#endif
+
+#define AU1XMMC_INTERRUPTS (SD_CONFIG_SC | SD_CONFIG_DT | \
+ SD_CONFIG_RAT | SD_CONFIG_CR | SD_CONFIG_I)
+/* The poll event (looking for insert/remove events runs twice a second */
+#define AU1XMMC_DETECT_TIMEOUT (HZ/2)
+
+struct au1xmmc_host {
+ struct mmc_host *mmc;
+ struct mmc_request *mrq;
+
+ u32 id;
+
+ u32 flags;
+ u32 iobase;
+ u32 clock;
+ u32 bus_width;
+ u32 power_mode;
+
+ int status;
+
+ struct {
+ int len;
+ int dir;
+ } dma;
+
+ struct {
+ int index;
+ int offset;
+ int len;
+ } pio;
+
+ u32 tx_chan;
+ u32 rx_chan;
+
+ struct timer_list timer;
+ struct tasklet_struct finish_task;
+ struct tasklet_struct data_task;
+
+ spinlock_t lock;
+};
+
+/* Status flags used by the host structure */
+
+#define HOST_F_XMIT 0x0001
+#define HOST_F_RECV 0x0002
+#define HOST_F_DMA 0x0010
+#define HOST_F_ACTIVE 0x0100
+#define HOST_F_STOP 0x1000
+
+#define HOST_S_IDLE 0x0001
+#define HOST_S_CMD 0x0002
+#define HOST_S_DATA 0x0003
+#define HOST_S_STOP 0x0004
+
+#endif
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c
index fa83f15fdf16..9b629856c735 100644
--- a/drivers/mmc/mmc_block.c
+++ b/drivers/mmc/mmc_block.c
@@ -85,6 +85,12 @@ static void mmc_blk_put(struct mmc_blk_data *md)
up(&open_lock);
}
+static inline int mmc_blk_readonly(struct mmc_card *card)
+{
+ return mmc_card_readonly(card) ||
+ !(card->csd.cmdclass & CCC_BLOCK_WRITE);
+}
+
static int mmc_blk_open(struct inode *inode, struct file *filp)
{
struct mmc_blk_data *md;
@@ -97,7 +103,7 @@ static int mmc_blk_open(struct inode *inode, struct file *filp)
ret = 0;
if ((filp->f_mode & FMODE_WRITE) &&
- mmc_card_readonly(md->queue.card))
+ mmc_blk_readonly(md->queue.card))
ret = -EROFS;
}
@@ -410,7 +416,7 @@ static int mmc_blk_probe(struct mmc_card *card)
printk(KERN_INFO "%s: %s %s %dKiB %s\n",
md->disk->disk_name, mmc_card_id(card), mmc_card_name(card),
(card->csd.capacity << card->csd.read_blkbits) / 1024,
- mmc_card_readonly(card)?"(ro)":"");
+ mmc_blk_readonly(card)?"(ro)":"");
mmc_set_drvdata(card, md);
add_disk(md->disk);
diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c
index 4da4a98bd590..f31e247b2cbe 100644
--- a/drivers/mmc/pxamci.c
+++ b/drivers/mmc/pxamci.c
@@ -29,7 +29,6 @@
#include <asm/dma.h>
#include <asm/io.h>
-#include <asm/irq.h>
#include <asm/scatterlist.h>
#include <asm/sizes.h>
diff --git a/drivers/mtd/chips/jedec.c b/drivers/mtd/chips/jedec.c
index 62d235a9a4e2..4f6778f3ee3e 100644
--- a/drivers/mtd/chips/jedec.c
+++ b/drivers/mtd/chips/jedec.c
@@ -17,6 +17,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/mtd/jedec.h>
#include <linux/mtd/map.h>
#include <linux/mtd/mtd.h>
diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c
index dfd335e4a2a8..df987a53ed9c 100644
--- a/drivers/mtd/devices/lart.c
+++ b/drivers/mtd/devices/lart.c
@@ -44,6 +44,7 @@
#include <linux/types.h>
#include <linux/init.h>
#include <linux/errno.h>
+#include <linux/string.h>
#include <linux/mtd/mtd.h>
#ifdef HAVE_PARTITIONS
#include <linux/mtd/partitions.h>
diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c
index a423a382095a..765c0179c8df 100644
--- a/drivers/mtd/devices/phram.c
+++ b/drivers/mtd/devices/phram.c
@@ -22,6 +22,7 @@
#include <linux/list.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
+#include <linux/slab.h>
#include <linux/mtd/mtd.h>
#define ERROR(fmt, args...) printk(KERN_ERR "phram: " fmt , ## args)
diff --git a/drivers/mtd/maps/bast-flash.c b/drivers/mtd/maps/bast-flash.c
index 5f248ebe68e0..bfe994e59265 100644
--- a/drivers/mtd/maps/bast-flash.c
+++ b/drivers/mtd/maps/bast-flash.c
@@ -32,8 +32,9 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/slab.h>
#include <linux/platform_device.h>
-
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
diff --git a/drivers/mtd/maps/ceiva.c b/drivers/mtd/maps/ceiva.c
index da8584a662f4..c68b31dc7e6d 100644
--- a/drivers/mtd/maps/ceiva.c
+++ b/drivers/mtd/maps/ceiva.c
@@ -20,6 +20,7 @@
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
diff --git a/drivers/mtd/maps/dc21285.c b/drivers/mtd/maps/dc21285.c
index 938c41f2f056..e5b74169fde6 100644
--- a/drivers/mtd/maps/dc21285.c
+++ b/drivers/mtd/maps/dc21285.c
@@ -13,6 +13,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
diff --git a/drivers/mtd/maps/dilnetpc.c b/drivers/mtd/maps/dilnetpc.c
index 0bc79c93a584..f99519692cb7 100644
--- a/drivers/mtd/maps/dilnetpc.c
+++ b/drivers/mtd/maps/dilnetpc.c
@@ -30,12 +30,15 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <asm/io.h>
+#include <linux/string.h>
+
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/concat.h>
+#include <asm/io.h>
+
/*
** The DIL/NetPC keeps its BIOS in two distinct flash blocks.
** Destroying any of these blocks transforms the DNPC into
diff --git a/drivers/mtd/maps/epxa10db-flash.c b/drivers/mtd/maps/epxa10db-flash.c
index ab6dbe2b8cce..1df6188926b3 100644
--- a/drivers/mtd/maps/epxa10db-flash.c
+++ b/drivers/mtd/maps/epxa10db-flash.c
@@ -27,12 +27,15 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <asm/io.h>
+#include <linux/slab.h>
+
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
+#include <asm/io.h>
#include <asm/hardware.h>
+
#ifdef CONFIG_EPXA10DB
#define BOARD_NAME "EPXA10DB"
#else
diff --git a/drivers/mtd/maps/fortunet.c b/drivers/mtd/maps/fortunet.c
index 068bb6a54520..00f7bbe5479e 100644
--- a/drivers/mtd/maps/fortunet.c
+++ b/drivers/mtd/maps/fortunet.c
@@ -7,11 +7,14 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <asm/io.h>
+#include <linux/string.h>
+
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
+#include <asm/io.h>
+
#define MAX_NUM_REGIONS 4
#define MAX_NUM_PARTITIONS 8
diff --git a/drivers/mtd/maps/ixp2000.c b/drivers/mtd/maps/ixp2000.c
index 6815baee89d7..00b9f67580f1 100644
--- a/drivers/mtd/maps/ixp2000.c
+++ b/drivers/mtd/maps/ixp2000.c
@@ -22,11 +22,14 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
-#include <linux/ioport.h>
-#include <linux/platform_device.h>
#include <asm/io.h>
#include <asm/hardware.h>
diff --git a/drivers/mtd/maps/ixp4xx.c b/drivers/mtd/maps/ixp4xx.c
index 06e1c7fffed3..733a9297a562 100644
--- a/drivers/mtd/maps/ixp4xx.c
+++ b/drivers/mtd/maps/ixp4xx.c
@@ -20,11 +20,15 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
-#include <linux/ioport.h>
-#include <linux/platform_device.h>
+
#include <asm/io.h>
#include <asm/mach/flash.h>
diff --git a/drivers/mtd/maps/lubbock-flash.c b/drivers/mtd/maps/lubbock-flash.c
index 1298de475c9a..2337e0c46750 100644
--- a/drivers/mtd/maps/lubbock-flash.c
+++ b/drivers/mtd/maps/lubbock-flash.c
@@ -15,10 +15,13 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/slab.h>
+
#include <linux/dma-mapping.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
+
#include <asm/io.h>
#include <asm/hardware.h>
#include <asm/arch/pxa-regs.h>
diff --git a/drivers/mtd/maps/mainstone-flash.c b/drivers/mtd/maps/mainstone-flash.c
index 87e93fa60588..da0f8a692628 100644
--- a/drivers/mtd/maps/mainstone-flash.c
+++ b/drivers/mtd/maps/mainstone-flash.c
@@ -16,9 +16,12 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
+
#include <asm/io.h>
#include <asm/hardware.h>
#include <asm/arch/pxa-regs.h>
diff --git a/drivers/mtd/maps/omap-toto-flash.c b/drivers/mtd/maps/omap-toto-flash.c
index 496109071cb1..da36e8dddd17 100644
--- a/drivers/mtd/maps/omap-toto-flash.c
+++ b/drivers/mtd/maps/omap-toto-flash.c
@@ -12,9 +12,9 @@
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
-
#include <linux/errno.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
diff --git a/drivers/mtd/maps/omap_nor.c b/drivers/mtd/maps/omap_nor.c
index 9c9f4116e50a..7f370bb794fe 100644
--- a/drivers/mtd/maps/omap_nor.c
+++ b/drivers/mtd/maps/omap_nor.c
@@ -36,6 +36,8 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/ioport.h>
+#include <linux/slab.h>
+
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
diff --git a/drivers/mtd/maps/pci.c b/drivers/mtd/maps/pci.c
index 18dbd3af1eaa..d9c64e99ee32 100644
--- a/drivers/mtd/maps/pci.c
+++ b/drivers/mtd/maps/pci.c
@@ -17,6 +17,7 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c
index e751e05fcc65..104576b5be34 100644
--- a/drivers/mtd/maps/plat-ram.c
+++ b/drivers/mtd/maps/plat-ram.c
@@ -29,6 +29,8 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c
index 66b4c2780adc..c8d0da19d897 100644
--- a/drivers/mtd/maps/sa1100-flash.c
+++ b/drivers/mtd/maps/sa1100-flash.c
@@ -130,20 +130,21 @@ struct sa_subdev_info {
char name[16];
struct map_info map;
struct mtd_info *mtd;
- struct flash_platform_data *data;
+ struct flash_platform_data *plat;
};
struct sa_info {
struct mtd_partition *parts;
struct mtd_info *mtd;
int num_subdev;
+ unsigned int nr_parts;
struct sa_subdev_info subdev[0];
};
static void sa1100_set_vpp(struct map_info *map, int on)
{
struct sa_subdev_info *subdev = container_of(map, struct sa_subdev_info, map);
- subdev->data->set_vpp(on);
+ subdev->plat->set_vpp(on);
}
static void sa1100_destroy_subdev(struct sa_subdev_info *subdev)
@@ -187,7 +188,7 @@ static int sa1100_probe_subdev(struct sa_subdev_info *subdev, struct resource *r
goto out;
}
- if (subdev->data->set_vpp)
+ if (subdev->plat->set_vpp)
subdev->map.set_vpp = sa1100_set_vpp;
subdev->map.phys = phys;
@@ -204,7 +205,7 @@ static int sa1100_probe_subdev(struct sa_subdev_info *subdev, struct resource *r
* Now let's probe for the actual flash. Do it here since
* specific machine settings might have been set above.
*/
- subdev->mtd = do_map_probe(subdev->data->map_name, &subdev->map);
+ subdev->mtd = do_map_probe(subdev->plat->map_name, &subdev->map);
if (subdev->mtd == NULL) {
ret = -ENXIO;
goto err;
@@ -223,13 +224,17 @@ static int sa1100_probe_subdev(struct sa_subdev_info *subdev, struct resource *r
return ret;
}
-static void sa1100_destroy(struct sa_info *info)
+static void sa1100_destroy(struct sa_info *info, struct flash_platform_data *plat)
{
int i;
if (info->mtd) {
- del_mtd_partitions(info->mtd);
-
+ if (info->nr_parts == 0)
+ del_mtd_device(info->mtd);
+#ifdef CONFIG_MTD_PARTITIONS
+ else
+ del_mtd_partitions(info->mtd);
+#endif
#ifdef CONFIG_MTD_CONCAT
if (info->mtd != info->subdev[0].mtd)
mtd_concat_destroy(info->mtd);
@@ -242,10 +247,13 @@ static void sa1100_destroy(struct sa_info *info)
for (i = info->num_subdev - 1; i >= 0; i--)
sa1100_destroy_subdev(&info->subdev[i]);
kfree(info);
+
+ if (plat->exit)
+ plat->exit();
}
static struct sa_info *__init
-sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *flash)
+sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *plat)
{
struct sa_info *info;
int nr, size, i, ret = 0;
@@ -275,6 +283,12 @@ sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *flash
memset(info, 0, size);
+ if (plat->init) {
+ ret = plat->init();
+ if (ret)
+ goto err;
+ }
+
/*
* Claim and then map the memory regions.
*/
@@ -287,8 +301,8 @@ sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *flash
break;
subdev->map.name = subdev->name;
- sprintf(subdev->name, "sa1100-%d", i);
- subdev->data = flash;
+ sprintf(subdev->name, "%s-%d", plat->name, i);
+ subdev->plat = plat;
ret = sa1100_probe_subdev(subdev, res);
if (ret)
@@ -309,7 +323,7 @@ sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *flash
* otherwise fail. Either way, it'll be called "sa1100".
*/
if (info->num_subdev == 1) {
- strcpy(info->subdev[0].name, "sa1100");
+ strcpy(info->subdev[0].name, plat->name);
info->mtd = info->subdev[0].mtd;
ret = 0;
} else if (info->num_subdev > 1) {
@@ -322,7 +336,7 @@ sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *flash
cdev[i] = info->subdev[i].mtd;
info->mtd = mtd_concat_create(cdev, info->num_subdev,
- "sa1100");
+ plat->name);
if (info->mtd == NULL)
ret = -ENXIO;
#else
@@ -336,7 +350,7 @@ sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *flash
return info;
err:
- sa1100_destroy(info);
+ sa1100_destroy(info, plat);
out:
return ERR_PTR(ret);
}
@@ -346,16 +360,16 @@ static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
static int __init sa1100_mtd_probe(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
- struct flash_platform_data *flash = pdev->dev.platform_data;
+ struct flash_platform_data *plat = pdev->dev.platform_data;
struct mtd_partition *parts;
const char *part_type = NULL;
struct sa_info *info;
int err, nr_parts = 0;
- if (!flash)
+ if (!plat)
return -ENODEV;
- info = sa1100_setup_mtd(pdev, flash);
+ info = sa1100_setup_mtd(pdev, plat);
if (IS_ERR(info)) {
err = PTR_ERR(info);
goto out;
@@ -372,8 +386,8 @@ static int __init sa1100_mtd_probe(struct device *dev)
} else
#endif
{
- parts = flash->parts;
- nr_parts = flash->nr_parts;
+ parts = plat->parts;
+ nr_parts = plat->nr_parts;
part_type = "static";
}
@@ -387,6 +401,8 @@ static int __init sa1100_mtd_probe(struct device *dev)
add_mtd_partitions(info->mtd, parts, nr_parts);
}
+ info->nr_parts = nr_parts;
+
dev_set_drvdata(dev, info);
err = 0;
@@ -397,8 +413,11 @@ static int __init sa1100_mtd_probe(struct device *dev)
static int __exit sa1100_mtd_remove(struct device *dev)
{
struct sa_info *info = dev_get_drvdata(dev);
+ struct flash_platform_data *plat = dev->platform_data;
+
dev_set_drvdata(dev, NULL);
- sa1100_destroy(info);
+ sa1100_destroy(info, plat);
+
return 0;
}
@@ -421,9 +440,17 @@ static int sa1100_mtd_resume(struct device *dev)
info->mtd->resume(info->mtd);
return 0;
}
+
+static void sa1100_mtd_shutdown(struct device *dev)
+{
+ struct sa_info *info = dev_get_drvdata(dev);
+ if (info && info->mtd->suspend(info->mtd) == 0)
+ info->mtd->resume(info->mtd);
+}
#else
#define sa1100_mtd_suspend NULL
#define sa1100_mtd_resume NULL
+#define sa1100_mtd_shutdown NULL
#endif
static struct device_driver sa1100_mtd_driver = {
@@ -433,6 +460,7 @@ static struct device_driver sa1100_mtd_driver = {
.remove = __exit_p(sa1100_mtd_remove),
.suspend = sa1100_mtd_suspend,
.resume = sa1100_mtd_resume,
+ .shutdown = sa1100_mtd_shutdown,
};
static int __init sa1100_mtd_init(void)
diff --git a/drivers/mtd/maps/tqm8xxl.c b/drivers/mtd/maps/tqm8xxl.c
index 995e9991cb8d..4e28b977f224 100644
--- a/drivers/mtd/maps/tqm8xxl.c
+++ b/drivers/mtd/maps/tqm8xxl.c
@@ -27,12 +27,14 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <asm/io.h>
+#include <linux/slab.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
+#include <asm/io.h>
+
#define FLASH_ADDR 0x40000000
#define FLASH_SIZE 0x00800000
#define FLASH_BANK_MAX 4
diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
index b7c32c242bc7..400dd9c89883 100644
--- a/drivers/mtd/mtdblock.c
+++ b/drivers/mtd/mtdblock.c
@@ -15,6 +15,7 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
+#include <linux/sched.h> /* TASK_* */
#include <linux/mtd/mtd.h>
#include <linux/mtd/blktrans.h>
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index c534fd5d95cb..16df1e4fb0e9 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -13,6 +13,7 @@
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/fs.h>
+#include <linux/sched.h> /* TASK_* */
#include <asm/uaccess.h>
#include <linux/device.h>
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index 8f66d093c80d..f3e65af33a9c 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -14,7 +14,7 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/slab.h>
-
+#include <linux/sched.h> /* TASK_* */
#include <linux/mtd/mtd.h>
#include <linux/mtd/concat.h>
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
index bf2325df80c7..2df5e47d1f5c 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -51,6 +51,7 @@
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index fee8c5cf1f3a..6d4f9ceb0a32 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1163,38 +1163,74 @@ config IBMVETH
be called ibmveth.
config IBM_EMAC
- bool "IBM PPC4xx EMAC driver support"
+ tristate "PowerPC 4xx on-chip Ethernet support"
depends on 4xx
- select CRC32
- ---help---
- This driver supports the IBM PPC4xx EMAC family of on-chip
- Ethernet controllers.
-
-config IBM_EMAC_ERRMSG
- bool "Verbose error messages"
- depends on IBM_EMAC && BROKEN
+ help
+ This driver supports the PowerPC 4xx EMAC family of on-chip
+ Ethernet controllers.
config IBM_EMAC_RXB
int "Number of receive buffers"
depends on IBM_EMAC
- default "128" if IBM_EMAC4
- default "64"
+ default "128"
config IBM_EMAC_TXB
int "Number of transmit buffers"
depends on IBM_EMAC
- default "128" if IBM_EMAC4
- default "8"
+ default "64"
+
+config IBM_EMAC_POLL_WEIGHT
+ int "MAL NAPI polling weight"
+ depends on IBM_EMAC
+ default "32"
-config IBM_EMAC_FGAP
- int "Frame gap"
+config IBM_EMAC_RX_COPY_THRESHOLD
+ int "RX skb copy threshold (bytes)"
depends on IBM_EMAC
- default "8"
+ default "256"
-config IBM_EMAC_SKBRES
- int "Skb reserve amount"
+config IBM_EMAC_RX_SKB_HEADROOM
+ int "Additional RX skb headroom (bytes)"
depends on IBM_EMAC
default "0"
+ help
+ Additional receive skb headroom. Note, that driver
+ will always reserve at least 2 bytes to make IP header
+ aligned, so usualy there is no need to add any additional
+ headroom.
+
+ If unsure, set to 0.
+
+config IBM_EMAC_PHY_RX_CLK_FIX
+ bool "PHY Rx clock workaround"
+ depends on IBM_EMAC && (405EP || 440GX || 440EP)
+ help
+ Enable this if EMAC attached to a PHY which doesn't generate
+ RX clock if there is no link, if this is the case, you will
+ see "TX disable timeout" or "RX disable timeout" in the system
+ log.
+
+ If unsure, say N.
+
+config IBM_EMAC_DEBUG
+ bool "Debugging"
+ depends on IBM_EMAC
+ default n
+
+config IBM_EMAC_ZMII
+ bool
+ depends on IBM_EMAC && (NP405H || NP405L || 44x)
+ default y
+
+config IBM_EMAC_RGMII
+ bool
+ depends on IBM_EMAC && 440GX
+ default y
+
+config IBM_EMAC_TAH
+ bool
+ depends on IBM_EMAC && 440GX
+ default y
config NET_PCI
bool "EISA, VLB, PCI and on board controllers"
@@ -1775,6 +1811,7 @@ config NE_H8300
controller on the Renesas H8/300 processor.
source "drivers/net/fec_8xx/Kconfig"
+source "drivers/net/fs_enet/Kconfig"
endmenu
@@ -2201,8 +2238,8 @@ config S2IO
depends on PCI
---help---
This driver supports the 10Gbe XFrame NIC of S2IO.
- For help regarding driver compilation, installation and
- tuning please look into ~/drivers/net/s2io/README.txt.
+ More specific information on configuring the driver is in
+ <file:Documentation/networking/s2io.txt>.
config S2IO_NAPI
bool "Use Rx Polling (NAPI) (EXPERIMENTAL)"
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 1a84e0435f64..7c313cb341b8 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -203,3 +203,6 @@ obj-$(CONFIG_IRDA) += irda/
obj-$(CONFIG_ETRAX_ETHERNET) += cris/
obj-$(CONFIG_NETCONSOLE) += netconsole.o
+
+obj-$(CONFIG_FS_ENET) += fs_enet/
+
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index dbecc6bf7851..b8953de5664a 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -871,10 +871,8 @@ static void ace_init_cleanup(struct net_device *dev)
if (ap->info)
pci_free_consistent(ap->pdev, sizeof(struct ace_info),
ap->info, ap->info_dma);
- if (ap->skb)
- kfree(ap->skb);
- if (ap->trace_buf)
- kfree(ap->trace_buf);
+ kfree(ap->skb);
+ kfree(ap->trace_buf);
if (dev->irq)
free_irq(dev->irq, dev);
diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
index d9ba8be72af8..d9ba8be72af8 100755..100644
--- a/drivers/net/amd8111e.c
+++ b/drivers/net/amd8111e.c
diff --git a/drivers/net/amd8111e.h b/drivers/net/amd8111e.h
index cfe3a4298822..cfe3a4298822 100755..100644
--- a/drivers/net/amd8111e.h
+++ b/drivers/net/amd8111e.h
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 78506911d656..332e9953c55c 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -1606,8 +1606,7 @@ err_out:
/* here we should have a valid dev plus aup-> register addresses
* so we can reset the mac properly.*/
reset_mac(dev);
- if (aup->mii)
- kfree(aup->mii);
+ kfree(aup->mii);
for (i = 0; i < NUM_RX_DMA; i++) {
if (aup->rx_db_inuse[i])
ReleaseDB(aup, aup->rx_db_inuse[i]);
@@ -1806,8 +1805,7 @@ static void __exit au1000_cleanup_module(void)
if (dev) {
aup = (struct au1000_private *) dev->priv;
unregister_netdev(dev);
- if (aup->mii)
- kfree(aup->mii);
+ kfree(aup->mii);
for (j = 0; j < NUM_RX_DMA; j++) {
if (aup->rx_db_inuse[j])
ReleaseDB(aup, aup->rx_db_inuse[j]);
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 282ebd15f011..0ee3e27969c6 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -19,6 +19,7 @@
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/version.h>
+#include <linux/dma-mapping.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -1130,14 +1131,10 @@ static void b44_init_rings(struct b44 *bp)
*/
static void b44_free_consistent(struct b44 *bp)
{
- if (bp->rx_buffers) {
- kfree(bp->rx_buffers);
- bp->rx_buffers = NULL;
- }
- if (bp->tx_buffers) {
- kfree(bp->tx_buffers);
- bp->tx_buffers = NULL;
- }
+ kfree(bp->rx_buffers);
+ bp->rx_buffers = NULL;
+ kfree(bp->tx_buffers);
+ bp->tx_buffers = NULL;
if (bp->rx_ring) {
if (bp->flags & B44_FLAG_RX_RING_HACK) {
dma_unmap_single(&bp->pdev->dev, bp->rx_ring_dma,
@@ -1619,14 +1616,14 @@ static int b44_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
cmd->advertising = 0;
if (bp->flags & B44_FLAG_ADV_10HALF)
- cmd->advertising |= ADVERTISE_10HALF;
+ cmd->advertising |= ADVERTISED_10baseT_Half;
if (bp->flags & B44_FLAG_ADV_10FULL)
- cmd->advertising |= ADVERTISE_10FULL;
+ cmd->advertising |= ADVERTISED_10baseT_Full;
if (bp->flags & B44_FLAG_ADV_100HALF)
- cmd->advertising |= ADVERTISE_100HALF;
+ cmd->advertising |= ADVERTISED_100baseT_Half;
if (bp->flags & B44_FLAG_ADV_100FULL)
- cmd->advertising |= ADVERTISE_100FULL;
- cmd->advertising |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
+ cmd->advertising |= ADVERTISED_100baseT_Full;
+ cmd->advertising |= ADVERTISED_Pause | ADVERTISED_Asym_Pause;
cmd->speed = (bp->flags & B44_FLAG_100_BASE_T) ?
SPEED_100 : SPEED_10;
cmd->duplex = (bp->flags & B44_FLAG_FULL_DUPLEX) ?
@@ -2044,6 +2041,8 @@ static int b44_suspend(struct pci_dev *pdev, pm_message_t state)
b44_free_rings(bp);
spin_unlock_irq(&bp->lock);
+
+ free_irq(dev->irq, dev);
pci_disable_device(pdev);
return 0;
}
@@ -2060,6 +2059,9 @@ static int b44_resume(struct pci_dev *pdev)
if (!netif_running(dev))
return 0;
+ if (request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev))
+ printk(KERN_ERR PFX "%s: request_irq failed\n", dev->name);
+
spin_lock_irq(&bp->lock);
b44_init_rings(bp);
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c
index 60dba4a1ca5c..bbca8ae8018c 100644
--- a/drivers/net/bmac.c
+++ b/drivers/net/bmac.c
@@ -1658,6 +1658,7 @@ static struct of_device_id bmac_match[] =
},
{},
};
+MODULE_DEVICE_TABLE (of, bmac_match);
static struct macio_driver bmac_driver =
{
@@ -1689,10 +1690,8 @@ static void __exit bmac_exit(void)
{
macio_unregister_driver(&bmac_driver);
- if (bmac_emergency_rxbuf != NULL) {
- kfree(bmac_emergency_rxbuf);
- bmac_emergency_rxbuf = NULL;
- }
+ kfree(bmac_emergency_rxbuf);
+ bmac_emergency_rxbuf = NULL;
}
MODULE_AUTHOR("Randy Gobbel/Paul Mackerras");
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 3a2ace01e444..11d252318221 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -314,20 +314,16 @@ bnx2_free_mem(struct bnx2 *bp)
bp->tx_desc_ring, bp->tx_desc_mapping);
bp->tx_desc_ring = NULL;
}
- if (bp->tx_buf_ring) {
- kfree(bp->tx_buf_ring);
- bp->tx_buf_ring = NULL;
- }
+ kfree(bp->tx_buf_ring);
+ bp->tx_buf_ring = NULL;
if (bp->rx_desc_ring) {
pci_free_consistent(bp->pdev,
sizeof(struct rx_bd) * RX_DESC_CNT,
bp->rx_desc_ring, bp->rx_desc_mapping);
bp->rx_desc_ring = NULL;
}
- if (bp->rx_buf_ring) {
- kfree(bp->rx_buf_ring);
- bp->rx_buf_ring = NULL;
- }
+ kfree(bp->rx_buf_ring);
+ bp->rx_buf_ring = NULL;
}
static int
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index 6b9acc7f94a3..9c7feaeaa6a4 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -965,11 +965,8 @@ e1000_free_desc_rings(struct e1000_adapter *adapter)
if(rxdr->desc)
pci_free_consistent(pdev, rxdr->size, rxdr->desc, rxdr->dma);
- if(txdr->buffer_info)
- kfree(txdr->buffer_info);
- if(rxdr->buffer_info)
- kfree(rxdr->buffer_info);
-
+ kfree(txdr->buffer_info);
+ kfree(rxdr->buffer_info);
return;
}
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 6b72f6acdd54..efbbda7cbcbf 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -191,8 +191,8 @@ static void e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid);
static void e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
static void e1000_restore_vlan(struct e1000_adapter *adapter);
-static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
#ifdef CONFIG_PM
+static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
static int e1000_resume(struct pci_dev *pdev);
#endif
@@ -1149,7 +1149,8 @@ e1000_setup_tx_resources(struct e1000_adapter *adapter,
int size;
size = sizeof(struct e1000_buffer) * txdr->count;
- txdr->buffer_info = vmalloc(size);
+
+ txdr->buffer_info = vmalloc_node(size, pcibus_to_node(pdev->bus));
if(!txdr->buffer_info) {
DPRINTK(PROBE, ERR,
"Unable to allocate memory for the transmit descriptor ring\n");
@@ -1366,7 +1367,7 @@ e1000_setup_rx_resources(struct e1000_adapter *adapter,
int size, desc_len;
size = sizeof(struct e1000_buffer) * rxdr->count;
- rxdr->buffer_info = vmalloc(size);
+ rxdr->buffer_info = vmalloc_node(size, pcibus_to_node(pdev->bus));
if (!rxdr->buffer_info) {
DPRINTK(PROBE, ERR,
"Unable to allocate memory for the receive descriptor ring\n");
@@ -4193,6 +4194,7 @@ e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx)
return 0;
}
+#ifdef CONFIG_PM
static int
e1000_suspend(struct pci_dev *pdev, pm_message_t state)
{
@@ -4289,7 +4291,6 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state)
return 0;
}
-#ifdef CONFIG_PM
static int
e1000_resume(struct pci_dev *pdev)
{
diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c
index dcb3028bb60f..a806dfe54d23 100644
--- a/drivers/net/eepro.c
+++ b/drivers/net/eepro.c
@@ -552,8 +552,7 @@ static int __init do_eepro_probe(struct net_device *dev)
{
unsigned short int WS[32]=WakeupSeq;
- if (check_region(WakeupPort, 2)==0) {
-
+ if (request_region(WakeupPort, 2, "eepro wakeup")) {
if (net_debug>5)
printk(KERN_DEBUG "Waking UP\n");
@@ -563,7 +562,10 @@ static int __init do_eepro_probe(struct net_device *dev)
outb_p(WS[i],WakeupPort);
if (net_debug>5) printk(KERN_DEBUG ": %#x ",WS[i]);
}
- } else printk(KERN_WARNING "Checkregion Failed!\n");
+
+ release_region(WakeupPort, 2);
+ } else
+ printk(KERN_WARNING "PnP wakeup region busy!\n");
}
#endif
@@ -705,7 +707,7 @@ static void __init eepro_print_info (struct net_device *dev)
dev->name, (unsigned)dev->base_addr);
break;
case LAN595FX:
- printk("%s: Intel EtherExpress Pro/10+ ISA\n at %#x,",
+ printk("%s: Intel EtherExpress Pro/10+ ISA\n at %#x,",
dev->name, (unsigned)dev->base_addr);
break;
case LAN595TX:
@@ -713,7 +715,7 @@ static void __init eepro_print_info (struct net_device *dev)
dev->name, (unsigned)dev->base_addr);
break;
case LAN595:
- printk("%s: Intel 82595-based lan card at %#x,",
+ printk("%s: Intel 82595-based lan card at %#x,",
dev->name, (unsigned)dev->base_addr);
}
@@ -726,7 +728,7 @@ static void __init eepro_print_info (struct net_device *dev)
if (dev->irq > 2)
printk(", IRQ %d, %s.\n", dev->irq, ifmap[dev->if_port]);
- else
+ else
printk(", %s.\n", ifmap[dev->if_port]);
if (net_debug > 3) {
@@ -756,7 +758,7 @@ static int __init eepro_probe1(struct net_device *dev, int autoprobe)
int err;
/* Grab the region so we can find another board if autoIRQ fails. */
- if (!request_region(ioaddr, EEPRO_IO_EXTENT, DRV_NAME)) {
+ if (!request_region(ioaddr, EEPRO_IO_EXTENT, DRV_NAME)) {
if (!autoprobe)
printk(KERN_WARNING "EEPRO: io-port 0x%04x in use \n",
ioaddr);
@@ -838,15 +840,15 @@ static int __init eepro_probe1(struct net_device *dev, int autoprobe)
/* Mask off INT number */
int count = lp->word[1] & 7;
unsigned irqMask = lp->word[7];
-
+
while (count--)
irqMask &= irqMask - 1;
-
+
count = ffs(irqMask);
-
+
if (count)
dev->irq = count - 1;
-
+
if (dev->irq < 2) {
printk(KERN_ERR " Duh! illegal interrupt vector stored in EEPROM.\n");
goto exit;
@@ -854,7 +856,7 @@ static int __init eepro_probe1(struct net_device *dev, int autoprobe)
dev->irq = 9;
}
}
-
+
dev->open = eepro_open;
dev->stop = eepro_close;
dev->hard_start_xmit = eepro_send_packet;
@@ -863,7 +865,7 @@ static int __init eepro_probe1(struct net_device *dev, int autoprobe)
dev->tx_timeout = eepro_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
dev->ethtool_ops = &eepro_ethtool_ops;
-
+
/* print boot time info */
eepro_print_info(dev);
@@ -1047,8 +1049,8 @@ static int eepro_open(struct net_device *dev)
/* Initialize the RCV and XMT upper and lower limits */
- outb(lp->rcv_lower_limit >> 8, ioaddr + RCV_LOWER_LIMIT_REG);
- outb(lp->rcv_upper_limit >> 8, ioaddr + RCV_UPPER_LIMIT_REG);
+ outb(lp->rcv_lower_limit >> 8, ioaddr + RCV_LOWER_LIMIT_REG);
+ outb(lp->rcv_upper_limit >> 8, ioaddr + RCV_UPPER_LIMIT_REG);
outb(lp->xmt_lower_limit >> 8, ioaddr + lp->xmt_lower_limit_reg);
outb(lp->xmt_upper_limit >> 8, ioaddr + lp->xmt_upper_limit_reg);
@@ -1065,12 +1067,12 @@ static int eepro_open(struct net_device *dev)
eepro_clear_int(ioaddr);
/* Initialize RCV */
- outw(lp->rcv_lower_limit, ioaddr + RCV_BAR);
+ outw(lp->rcv_lower_limit, ioaddr + RCV_BAR);
lp->rx_start = lp->rcv_lower_limit;
- outw(lp->rcv_upper_limit | 0xfe, ioaddr + RCV_STOP);
+ outw(lp->rcv_upper_limit | 0xfe, ioaddr + RCV_STOP);
/* Initialize XMT */
- outw(lp->xmt_lower_limit, ioaddr + lp->xmt_bar);
+ outw(lp->xmt_lower_limit, ioaddr + lp->xmt_bar);
lp->tx_start = lp->tx_end = lp->xmt_lower_limit;
lp->tx_last = 0;
@@ -1411,7 +1413,7 @@ set_multicast_list(struct net_device *dev)
outb(0x08, ioaddr + STATUS_REG);
if (i & 0x20) { /* command ABORTed */
- printk(KERN_NOTICE "%s: multicast setup failed.\n",
+ printk(KERN_NOTICE "%s: multicast setup failed.\n",
dev->name);
break;
} else if ((i & 0x0f) == 0x03) { /* MC-Done */
@@ -1512,7 +1514,7 @@ hardware_send_packet(struct net_device *dev, void *buf, short length)
end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
if (end >= lp->xmt_upper_limit + 2) { /* the transmit buffer is wrapped around */
- if ((lp->xmt_upper_limit + 2 - last) <= XMT_HEADER) {
+ if ((lp->xmt_upper_limit + 2 - last) <= XMT_HEADER) {
/* Arrrr!!!, must keep the xmt header together,
several days were lost to chase this one down. */
last = lp->xmt_lower_limit;
@@ -1643,7 +1645,7 @@ eepro_rx(struct net_device *dev)
else if (rcv_status & 0x0800)
lp->stats.rx_crc_errors++;
- printk(KERN_DEBUG "%s: event = %#x, status = %#x, next = %#x, size = %#x\n",
+ printk(KERN_DEBUG "%s: event = %#x, status = %#x, next = %#x, size = %#x\n",
dev->name, rcv_event, rcv_status, rcv_next_frame, rcv_size);
}
@@ -1674,10 +1676,10 @@ eepro_transmit_interrupt(struct net_device *dev)
{
struct eepro_local *lp = netdev_priv(dev);
short ioaddr = dev->base_addr;
- short boguscount = 25;
+ short boguscount = 25;
short xmt_status;
- while ((lp->tx_start != lp->tx_end) && boguscount--) {
+ while ((lp->tx_start != lp->tx_end) && boguscount--) {
outw(lp->tx_start, ioaddr + HOST_ADDRESS_REG);
xmt_status = inw(ioaddr+IO_PORT);
@@ -1723,7 +1725,7 @@ static int eepro_ethtool_get_settings(struct net_device *dev,
{
struct eepro_local *lp = (struct eepro_local *)dev->priv;
- cmd->supported = SUPPORTED_10baseT_Half |
+ cmd->supported = SUPPORTED_10baseT_Half |
SUPPORTED_10baseT_Full |
SUPPORTED_Autoneg;
cmd->advertising = ADVERTISED_10baseT_Half |
@@ -1797,10 +1799,9 @@ MODULE_AUTHOR("Pascal Dupuis and others");
MODULE_DESCRIPTION("Intel i82595 ISA EtherExpressPro10/10+ driver");
MODULE_LICENSE("GPL");
-static int num_params;
-module_param_array(io, int, &num_params, 0);
-module_param_array(irq, int, &num_params, 0);
-module_param_array(mem, int, &num_params, 0);
+module_param_array(io, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
+module_param_array(mem, int, NULL, 0);
module_param(autodetect, int, 0);
MODULE_PARM_DESC(io, "EtherExpress Pro/10 I/O base addres(es)");
MODULE_PARM_DESC(irq, "EtherExpress Pro/10 IRQ number(s)");
diff --git a/drivers/net/fs_enet/Kconfig b/drivers/net/fs_enet/Kconfig
new file mode 100644
index 000000000000..6aaee67dd4b7
--- /dev/null
+++ b/drivers/net/fs_enet/Kconfig
@@ -0,0 +1,20 @@
+config FS_ENET
+ tristate "Freescale Ethernet Driver"
+ depends on NET_ETHERNET && (CPM1 || CPM2)
+ select MII
+
+config FS_ENET_HAS_SCC
+ bool "Chip has an SCC usable for ethernet"
+ depends on FS_ENET && (CPM1 || CPM2)
+ default y
+
+config FS_ENET_HAS_FCC
+ bool "Chip has an FCC usable for ethernet"
+ depends on FS_ENET && CPM2
+ default y
+
+config FS_ENET_HAS_FEC
+ bool "Chip has an FEC usable for ethernet"
+ depends on FS_ENET && CPM1
+ default y
+
diff --git a/drivers/net/fs_enet/Makefile b/drivers/net/fs_enet/Makefile
new file mode 100644
index 000000000000..d6dd3f2fb43e
--- /dev/null
+++ b/drivers/net/fs_enet/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the Freescale Ethernet controllers
+#
+
+obj-$(CONFIG_FS_ENET) += fs_enet.o
+
+obj-$(CONFIG_8xx) += mac-fec.o mac-scc.o
+obj-$(CONFIG_8260) += mac-fcc.o
+
+fs_enet-objs := fs_enet-main.o fs_enet-mii.o mii-bitbang.o mii-fixed.o
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
new file mode 100644
index 000000000000..44fac7373289
--- /dev/null
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -0,0 +1,1226 @@
+/*
+ * Combined Ethernet driver for Motorola MPC8xx and MPC82xx.
+ *
+ * Copyright (c) 2003 Intracom S.A.
+ * by Pantelis Antoniou <panto@intracom.gr>
+ *
+ * 2005 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * Heavily based on original FEC driver by Dan Malek <dan@embeddededge.com>
+ * and modifications by Joakim Tjernlund <joakim.tjernlund@lumentis.se>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/bitops.h>
+#include <linux/fs.h>
+
+#include <linux/vmalloc.h>
+#include <asm/pgtable.h>
+
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#include "fs_enet.h"
+
+/*************************************************/
+
+static char version[] __devinitdata =
+ DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")" "\n";
+
+MODULE_AUTHOR("Pantelis Antoniou <panto@intracom.gr>");
+MODULE_DESCRIPTION("Freescale Ethernet Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_MODULE_VERSION);
+
+MODULE_PARM(fs_enet_debug, "i");
+MODULE_PARM_DESC(fs_enet_debug,
+ "Freescale bitmapped debugging message enable value");
+
+int fs_enet_debug = -1; /* -1 == use FS_ENET_DEF_MSG_ENABLE as value */
+
+static void fs_set_multicast_list(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ (*fep->ops->set_multicast_list)(dev);
+}
+
+/* NAPI receive function */
+static int fs_enet_rx_napi(struct net_device *dev, int *budget)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ const struct fs_platform_info *fpi = fep->fpi;
+ cbd_t *bdp;
+ struct sk_buff *skb, *skbn, *skbt;
+ int received = 0;
+ u16 pkt_len, sc;
+ int curidx;
+ int rx_work_limit = 0; /* pacify gcc */
+
+ rx_work_limit = min(dev->quota, *budget);
+
+ if (!netif_running(dev))
+ return 0;
+
+ /*
+ * First, grab all of the stats for the incoming packet.
+ * These get messed up if we get called due to a busy condition.
+ */
+ bdp = fep->cur_rx;
+
+ /* clear RX status bits for napi*/
+ (*fep->ops->napi_clear_rx_event)(dev);
+
+ while (((sc = CBDR_SC(bdp)) & BD_ENET_RX_EMPTY) == 0) {
+
+ curidx = bdp - fep->rx_bd_base;
+
+ /*
+ * Since we have allocated space to hold a complete frame,
+ * the last indicator should be set.
+ */
+ if ((sc & BD_ENET_RX_LAST) == 0)
+ printk(KERN_WARNING DRV_MODULE_NAME
+ ": %s rcv is not +last\n",
+ dev->name);
+
+ /*
+ * Check for errors.
+ */
+ if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_CL |
+ BD_ENET_RX_NO | BD_ENET_RX_CR | BD_ENET_RX_OV)) {
+ fep->stats.rx_errors++;
+ /* Frame too long or too short. */
+ if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH))
+ fep->stats.rx_length_errors++;
+ /* Frame alignment */
+ if (sc & (BD_ENET_RX_NO | BD_ENET_RX_CL))
+ fep->stats.rx_frame_errors++;
+ /* CRC Error */
+ if (sc & BD_ENET_RX_CR)
+ fep->stats.rx_crc_errors++;
+ /* FIFO overrun */
+ if (sc & BD_ENET_RX_OV)
+ fep->stats.rx_crc_errors++;
+
+ skb = fep->rx_skbuff[curidx];
+
+ dma_unmap_single(fep->dev, skb->data,
+ L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
+ DMA_FROM_DEVICE);
+
+ skbn = skb;
+
+ } else {
+
+ /* napi, got packet but no quota */
+ if (--rx_work_limit < 0)
+ break;
+
+ skb = fep->rx_skbuff[curidx];
+
+ dma_unmap_single(fep->dev, skb->data,
+ L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
+ DMA_FROM_DEVICE);
+
+ /*
+ * Process the incoming frame.
+ */
+ fep->stats.rx_packets++;
+ pkt_len = CBDR_DATLEN(bdp) - 4; /* remove CRC */
+ fep->stats.rx_bytes += pkt_len + 4;
+
+ if (pkt_len <= fpi->rx_copybreak) {
+ /* +2 to make IP header L1 cache aligned */
+ skbn = dev_alloc_skb(pkt_len + 2);
+ if (skbn != NULL) {
+ skb_reserve(skbn, 2); /* align IP header */
+ memcpy(skbn->data, skb->data, pkt_len);
+ /* swap */
+ skbt = skb;
+ skb = skbn;
+ skbn = skbt;
+ }
+ } else
+ skbn = dev_alloc_skb(ENET_RX_FRSIZE);
+
+ if (skbn != NULL) {
+ skb->dev = dev;
+ skb_put(skb, pkt_len); /* Make room */
+ skb->protocol = eth_type_trans(skb, dev);
+ received++;
+ netif_receive_skb(skb);
+ } else {
+ printk(KERN_WARNING DRV_MODULE_NAME
+ ": %s Memory squeeze, dropping packet.\n",
+ dev->name);
+ fep->stats.rx_dropped++;
+ skbn = skb;
+ }
+ }
+
+ fep->rx_skbuff[curidx] = skbn;
+ CBDW_BUFADDR(bdp, dma_map_single(fep->dev, skbn->data,
+ L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
+ DMA_FROM_DEVICE));
+ CBDW_DATLEN(bdp, 0);
+ CBDW_SC(bdp, (sc & ~BD_ENET_RX_STATS) | BD_ENET_RX_EMPTY);
+
+ /*
+ * Update BD pointer to next entry.
+ */
+ if ((sc & BD_ENET_RX_WRAP) == 0)
+ bdp++;
+ else
+ bdp = fep->rx_bd_base;
+
+ (*fep->ops->rx_bd_done)(dev);
+ }
+
+ fep->cur_rx = bdp;
+
+ dev->quota -= received;
+ *budget -= received;
+
+ if (rx_work_limit < 0)
+ return 1; /* not done */
+
+ /* done */
+ netif_rx_complete(dev);
+
+ (*fep->ops->napi_enable_rx)(dev);
+
+ return 0;
+}
+
+/* non NAPI receive function */
+static int fs_enet_rx_non_napi(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ const struct fs_platform_info *fpi = fep->fpi;
+ cbd_t *bdp;
+ struct sk_buff *skb, *skbn, *skbt;
+ int received = 0;
+ u16 pkt_len, sc;
+ int curidx;
+ /*
+ * First, grab all of the stats for the incoming packet.
+ * These get messed up if we get called due to a busy condition.
+ */
+ bdp = fep->cur_rx;
+
+ while (((sc = CBDR_SC(bdp)) & BD_ENET_RX_EMPTY) == 0) {
+
+ curidx = bdp - fep->rx_bd_base;
+
+ /*
+ * Since we have allocated space to hold a complete frame,
+ * the last indicator should be set.
+ */
+ if ((sc & BD_ENET_RX_LAST) == 0)
+ printk(KERN_WARNING DRV_MODULE_NAME
+ ": %s rcv is not +last\n",
+ dev->name);
+
+ /*
+ * Check for errors.
+ */
+ if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_CL |
+ BD_ENET_RX_NO | BD_ENET_RX_CR | BD_ENET_RX_OV)) {
+ fep->stats.rx_errors++;
+ /* Frame too long or too short. */
+ if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH))
+ fep->stats.rx_length_errors++;
+ /* Frame alignment */
+ if (sc & (BD_ENET_RX_NO | BD_ENET_RX_CL))
+ fep->stats.rx_frame_errors++;
+ /* CRC Error */
+ if (sc & BD_ENET_RX_CR)
+ fep->stats.rx_crc_errors++;
+ /* FIFO overrun */
+ if (sc & BD_ENET_RX_OV)
+ fep->stats.rx_crc_errors++;
+
+ skb = fep->rx_skbuff[curidx];
+
+ dma_unmap_single(fep->dev, skb->data,
+ L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
+ DMA_FROM_DEVICE);
+
+ skbn = skb;
+
+ } else {
+
+ skb = fep->rx_skbuff[curidx];
+
+ dma_unmap_single(fep->dev, skb->data,
+ L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
+ DMA_FROM_DEVICE);
+
+ /*
+ * Process the incoming frame.
+ */
+ fep->stats.rx_packets++;
+ pkt_len = CBDR_DATLEN(bdp) - 4; /* remove CRC */
+ fep->stats.rx_bytes += pkt_len + 4;
+
+ if (pkt_len <= fpi->rx_copybreak) {
+ /* +2 to make IP header L1 cache aligned */
+ skbn = dev_alloc_skb(pkt_len + 2);
+ if (skbn != NULL) {
+ skb_reserve(skbn, 2); /* align IP header */
+ memcpy(skbn->data, skb->data, pkt_len);
+ /* swap */
+ skbt = skb;
+ skb = skbn;
+ skbn = skbt;
+ }
+ } else
+ skbn = dev_alloc_skb(ENET_RX_FRSIZE);
+
+ if (skbn != NULL) {
+ skb->dev = dev;
+ skb_put(skb, pkt_len); /* Make room */
+ skb->protocol = eth_type_trans(skb, dev);
+ received++;
+ netif_rx(skb);
+ } else {
+ printk(KERN_WARNING DRV_MODULE_NAME
+ ": %s Memory squeeze, dropping packet.\n",
+ dev->name);
+ fep->stats.rx_dropped++;
+ skbn = skb;
+ }
+ }
+
+ fep->rx_skbuff[curidx] = skbn;
+ CBDW_BUFADDR(bdp, dma_map_single(fep->dev, skbn->data,
+ L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
+ DMA_FROM_DEVICE));
+ CBDW_DATLEN(bdp, 0);
+ CBDW_SC(bdp, (sc & ~BD_ENET_RX_STATS) | BD_ENET_RX_EMPTY);
+
+ /*
+ * Update BD pointer to next entry.
+ */
+ if ((sc & BD_ENET_RX_WRAP) == 0)
+ bdp++;
+ else
+ bdp = fep->rx_bd_base;
+
+ (*fep->ops->rx_bd_done)(dev);
+ }
+
+ fep->cur_rx = bdp;
+
+ return 0;
+}
+
+static void fs_enet_tx(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ cbd_t *bdp;
+ struct sk_buff *skb;
+ int dirtyidx, do_wake, do_restart;
+ u16 sc;
+
+ spin_lock(&fep->lock);
+ bdp = fep->dirty_tx;
+
+ do_wake = do_restart = 0;
+ while (((sc = CBDR_SC(bdp)) & BD_ENET_TX_READY) == 0) {
+
+ dirtyidx = bdp - fep->tx_bd_base;
+
+ if (fep->tx_free == fep->tx_ring)
+ break;
+
+ skb = fep->tx_skbuff[dirtyidx];
+
+ /*
+ * Check for errors.
+ */
+ if (sc & (BD_ENET_TX_HB | BD_ENET_TX_LC |
+ BD_ENET_TX_RL | BD_ENET_TX_UN | BD_ENET_TX_CSL)) {
+
+ if (sc & BD_ENET_TX_HB) /* No heartbeat */
+ fep->stats.tx_heartbeat_errors++;
+ if (sc & BD_ENET_TX_LC) /* Late collision */
+ fep->stats.tx_window_errors++;
+ if (sc & BD_ENET_TX_RL) /* Retrans limit */
+ fep->stats.tx_aborted_errors++;
+ if (sc & BD_ENET_TX_UN) /* Underrun */
+ fep->stats.tx_fifo_errors++;
+ if (sc & BD_ENET_TX_CSL) /* Carrier lost */
+ fep->stats.tx_carrier_errors++;
+
+ if (sc & (BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN)) {
+ fep->stats.tx_errors++;
+ do_restart = 1;
+ }
+ } else
+ fep->stats.tx_packets++;
+
+ if (sc & BD_ENET_TX_READY)
+ printk(KERN_WARNING DRV_MODULE_NAME
+ ": %s HEY! Enet xmit interrupt and TX_READY.\n",
+ dev->name);
+
+ /*
+ * Deferred means some collisions occurred during transmit,
+ * but we eventually sent the packet OK.
+ */
+ if (sc & BD_ENET_TX_DEF)
+ fep->stats.collisions++;
+
+ /* unmap */
+ dma_unmap_single(fep->dev, skb->data, skb->len, DMA_TO_DEVICE);
+
+ /*
+ * Free the sk buffer associated with this last transmit.
+ */
+ dev_kfree_skb_irq(skb);
+ fep->tx_skbuff[dirtyidx] = NULL;
+
+ /*
+ * Update pointer to next buffer descriptor to be transmitted.
+ */
+ if ((sc & BD_ENET_TX_WRAP) == 0)
+ bdp++;
+ else
+ bdp = fep->tx_bd_base;
+
+ /*
+ * Since we have freed up a buffer, the ring is no longer
+ * full.
+ */
+ if (!fep->tx_free++)
+ do_wake = 1;
+ }
+
+ fep->dirty_tx = bdp;
+
+ if (do_restart)
+ (*fep->ops->tx_restart)(dev);
+
+ spin_unlock(&fep->lock);
+
+ if (do_wake)
+ netif_wake_queue(dev);
+}
+
+/*
+ * The interrupt handler.
+ * This is called from the MPC core interrupt.
+ */
+static irqreturn_t
+fs_enet_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct net_device *dev = dev_id;
+ struct fs_enet_private *fep;
+ const struct fs_platform_info *fpi;
+ u32 int_events;
+ u32 int_clr_events;
+ int nr, napi_ok;
+ int handled;
+
+ fep = netdev_priv(dev);
+ fpi = fep->fpi;
+
+ nr = 0;
+ while ((int_events = (*fep->ops->get_int_events)(dev)) != 0) {
+
+ nr++;
+
+ int_clr_events = int_events;
+ if (fpi->use_napi)
+ int_clr_events &= ~fep->ev_napi_rx;
+
+ (*fep->ops->clear_int_events)(dev, int_clr_events);
+
+ if (int_events & fep->ev_err)
+ (*fep->ops->ev_error)(dev, int_events);
+
+ if (int_events & fep->ev_rx) {
+ if (!fpi->use_napi)
+ fs_enet_rx_non_napi(dev);
+ else {
+ napi_ok = netif_rx_schedule_prep(dev);
+
+ (*fep->ops->napi_disable_rx)(dev);
+ (*fep->ops->clear_int_events)(dev, fep->ev_napi_rx);
+
+ /* NOTE: it is possible for FCCs in NAPI mode */
+ /* to submit a spurious interrupt while in poll */
+ if (napi_ok)
+ __netif_rx_schedule(dev);
+ }
+ }
+
+ if (int_events & fep->ev_tx)
+ fs_enet_tx(dev);
+ }
+
+ handled = nr > 0;
+ return IRQ_RETVAL(handled);
+}
+
+void fs_init_bds(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ cbd_t *bdp;
+ struct sk_buff *skb;
+ int i;
+
+ fs_cleanup_bds(dev);
+
+ fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
+ fep->tx_free = fep->tx_ring;
+ fep->cur_rx = fep->rx_bd_base;
+
+ /*
+ * Initialize the receive buffer descriptors.
+ */
+ for (i = 0, bdp = fep->rx_bd_base; i < fep->rx_ring; i++, bdp++) {
+ skb = dev_alloc_skb(ENET_RX_FRSIZE);
+ if (skb == NULL) {
+ printk(KERN_WARNING DRV_MODULE_NAME
+ ": %s Memory squeeze, unable to allocate skb\n",
+ dev->name);
+ break;
+ }
+ fep->rx_skbuff[i] = skb;
+ skb->dev = dev;
+ CBDW_BUFADDR(bdp,
+ dma_map_single(fep->dev, skb->data,
+ L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
+ DMA_FROM_DEVICE));
+ CBDW_DATLEN(bdp, 0); /* zero */
+ CBDW_SC(bdp, BD_ENET_RX_EMPTY |
+ ((i < fep->rx_ring - 1) ? 0 : BD_SC_WRAP));
+ }
+ /*
+ * if we failed, fillup remainder
+ */
+ for (; i < fep->rx_ring; i++, bdp++) {
+ fep->rx_skbuff[i] = NULL;
+ CBDW_SC(bdp, (i < fep->rx_ring - 1) ? 0 : BD_SC_WRAP);
+ }
+
+ /*
+ * ...and the same for transmit.
+ */
+ for (i = 0, bdp = fep->tx_bd_base; i < fep->tx_ring; i++, bdp++) {
+ fep->tx_skbuff[i] = NULL;
+ CBDW_BUFADDR(bdp, 0);
+ CBDW_DATLEN(bdp, 0);
+ CBDW_SC(bdp, (i < fep->tx_ring - 1) ? 0 : BD_SC_WRAP);
+ }
+}
+
+void fs_cleanup_bds(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ struct sk_buff *skb;
+ int i;
+
+ /*
+ * Reset SKB transmit buffers.
+ */
+ for (i = 0; i < fep->tx_ring; i++) {
+ if ((skb = fep->tx_skbuff[i]) == NULL)
+ continue;
+
+ /* unmap */
+ dma_unmap_single(fep->dev, skb->data, skb->len, DMA_TO_DEVICE);
+
+ fep->tx_skbuff[i] = NULL;
+ dev_kfree_skb(skb);
+ }
+
+ /*
+ * Reset SKB receive buffers
+ */
+ for (i = 0; i < fep->rx_ring; i++) {
+ if ((skb = fep->rx_skbuff[i]) == NULL)
+ continue;
+
+ /* unmap */
+ dma_unmap_single(fep->dev, skb->data,
+ L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
+ DMA_FROM_DEVICE);
+
+ fep->rx_skbuff[i] = NULL;
+
+ dev_kfree_skb(skb);
+ }
+}
+
+/**********************************************************************************/
+
+static int fs_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ cbd_t *bdp;
+ int curidx;
+ u16 sc;
+ unsigned long flags;
+
+ spin_lock_irqsave(&fep->tx_lock, flags);
+
+ /*
+ * Fill in a Tx ring entry
+ */
+ bdp = fep->cur_tx;
+
+ if (!fep->tx_free || (CBDR_SC(bdp) & BD_ENET_TX_READY)) {
+ netif_stop_queue(dev);
+ spin_unlock_irqrestore(&fep->tx_lock, flags);
+
+ /*
+ * Ooops. All transmit buffers are full. Bail out.
+ * This should not happen, since the tx queue should be stopped.
+ */
+ printk(KERN_WARNING DRV_MODULE_NAME
+ ": %s tx queue full!.\n", dev->name);
+ return NETDEV_TX_BUSY;
+ }
+
+ curidx = bdp - fep->tx_bd_base;
+ /*
+ * Clear all of the status flags.
+ */
+ CBDC_SC(bdp, BD_ENET_TX_STATS);
+
+ /*
+ * Save skb pointer.
+ */
+ fep->tx_skbuff[curidx] = skb;
+
+ fep->stats.tx_bytes += skb->len;
+
+ /*
+ * Push the data cache so the CPM does not get stale memory data.
+ */
+ CBDW_BUFADDR(bdp, dma_map_single(fep->dev,
+ skb->data, skb->len, DMA_TO_DEVICE));
+ CBDW_DATLEN(bdp, skb->len);
+
+ dev->trans_start = jiffies;
+
+ /*
+ * If this was the last BD in the ring, start at the beginning again.
+ */
+ if ((CBDR_SC(bdp) & BD_ENET_TX_WRAP) == 0)
+ fep->cur_tx++;
+ else
+ fep->cur_tx = fep->tx_bd_base;
+
+ if (!--fep->tx_free)
+ netif_stop_queue(dev);
+
+ /* Trigger transmission start */
+ sc = BD_ENET_TX_READY | BD_ENET_TX_INTR |
+ BD_ENET_TX_LAST | BD_ENET_TX_TC;
+
+ /* note that while FEC does not have this bit
+ * it marks it as available for software use
+ * yay for hw reuse :) */
+ if (skb->len <= 60)
+ sc |= BD_ENET_TX_PAD;
+ CBDS_SC(bdp, sc);
+
+ (*fep->ops->tx_kickstart)(dev);
+
+ spin_unlock_irqrestore(&fep->tx_lock, flags);
+
+ return NETDEV_TX_OK;
+}
+
+static int fs_request_irq(struct net_device *dev, int irq, const char *name,
+ irqreturn_t (*irqf)(int irq, void *dev_id, struct pt_regs *regs))
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ (*fep->ops->pre_request_irq)(dev, irq);
+ return request_irq(irq, irqf, SA_SHIRQ, name, dev);
+}
+
+static void fs_free_irq(struct net_device *dev, int irq)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ free_irq(irq, dev);
+ (*fep->ops->post_free_irq)(dev, irq);
+}
+
+/**********************************************************************************/
+
+/* This interrupt occurs when the PHY detects a link change. */
+static irqreturn_t
+fs_mii_link_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct net_device *dev = dev_id;
+ struct fs_enet_private *fep;
+ const struct fs_platform_info *fpi;
+
+ fep = netdev_priv(dev);
+ fpi = fep->fpi;
+
+ /*
+ * Acknowledge the interrupt if possible. If we have not
+ * found the PHY yet we can't process or acknowledge the
+ * interrupt now. Instead we ignore this interrupt for now,
+ * which we can do since it is edge triggered. It will be
+ * acknowledged later by fs_enet_open().
+ */
+ if (!fep->phy)
+ return IRQ_NONE;
+
+ fs_mii_ack_int(dev);
+ fs_mii_link_status_change_check(dev, 0);
+
+ return IRQ_HANDLED;
+}
+
+static void fs_timeout(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ unsigned long flags;
+ int wake = 0;
+
+ fep->stats.tx_errors++;
+
+ spin_lock_irqsave(&fep->lock, flags);
+
+ if (dev->flags & IFF_UP) {
+ (*fep->ops->stop)(dev);
+ (*fep->ops->restart)(dev);
+ }
+
+ wake = fep->tx_free && !(CBDR_SC(fep->cur_tx) & BD_ENET_TX_READY);
+ spin_unlock_irqrestore(&fep->lock, flags);
+
+ if (wake)
+ netif_wake_queue(dev);
+}
+
+static int fs_enet_open(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ const struct fs_platform_info *fpi = fep->fpi;
+ int r;
+
+ /* Install our interrupt handler. */
+ r = fs_request_irq(dev, fep->interrupt, "fs_enet-mac", fs_enet_interrupt);
+ if (r != 0) {
+ printk(KERN_ERR DRV_MODULE_NAME
+ ": %s Could not allocate FEC IRQ!", dev->name);
+ return -EINVAL;
+ }
+
+ /* Install our phy interrupt handler */
+ if (fpi->phy_irq != -1) {
+
+ r = fs_request_irq(dev, fpi->phy_irq, "fs_enet-phy", fs_mii_link_interrupt);
+ if (r != 0) {
+ printk(KERN_ERR DRV_MODULE_NAME
+ ": %s Could not allocate PHY IRQ!", dev->name);
+ fs_free_irq(dev, fep->interrupt);
+ return -EINVAL;
+ }
+ }
+
+ fs_mii_startup(dev);
+ netif_carrier_off(dev);
+ fs_mii_link_status_change_check(dev, 1);
+
+ return 0;
+}
+
+static int fs_enet_close(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ const struct fs_platform_info *fpi = fep->fpi;
+ unsigned long flags;
+
+ netif_stop_queue(dev);
+ netif_carrier_off(dev);
+ fs_mii_shutdown(dev);
+
+ spin_lock_irqsave(&fep->lock, flags);
+ (*fep->ops->stop)(dev);
+ spin_unlock_irqrestore(&fep->lock, flags);
+
+ /* release any irqs */
+ if (fpi->phy_irq != -1)
+ fs_free_irq(dev, fpi->phy_irq);
+ fs_free_irq(dev, fep->interrupt);
+
+ return 0;
+}
+
+static struct net_device_stats *fs_enet_get_stats(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ return &fep->stats;
+}
+
+/*************************************************************************/
+
+static void fs_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+{
+ strcpy(info->driver, DRV_MODULE_NAME);
+ strcpy(info->version, DRV_MODULE_VERSION);
+}
+
+static int fs_get_regs_len(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ return (*fep->ops->get_regs_len)(dev);
+}
+
+static void fs_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+ void *p)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ unsigned long flags;
+ int r, len;
+
+ len = regs->len;
+
+ spin_lock_irqsave(&fep->lock, flags);
+ r = (*fep->ops->get_regs)(dev, p, &len);
+ spin_unlock_irqrestore(&fep->lock, flags);
+
+ if (r == 0)
+ regs->version = 0;
+}
+
+static int fs_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ unsigned long flags;
+ int rc;
+
+ spin_lock_irqsave(&fep->lock, flags);
+ rc = mii_ethtool_gset(&fep->mii_if, cmd);
+ spin_unlock_irqrestore(&fep->lock, flags);
+
+ return rc;
+}
+
+static int fs_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ unsigned long flags;
+ int rc;
+
+ spin_lock_irqsave(&fep->lock, flags);
+ rc = mii_ethtool_sset(&fep->mii_if, cmd);
+ spin_unlock_irqrestore(&fep->lock, flags);
+
+ return rc;
+}
+
+static int fs_nway_reset(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ return mii_nway_restart(&fep->mii_if);
+}
+
+static u32 fs_get_msglevel(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ return fep->msg_enable;
+}
+
+static void fs_set_msglevel(struct net_device *dev, u32 value)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fep->msg_enable = value;
+}
+
+static struct ethtool_ops fs_ethtool_ops = {
+ .get_drvinfo = fs_get_drvinfo,
+ .get_regs_len = fs_get_regs_len,
+ .get_settings = fs_get_settings,
+ .set_settings = fs_set_settings,
+ .nway_reset = fs_nway_reset,
+ .get_link = ethtool_op_get_link,
+ .get_msglevel = fs_get_msglevel,
+ .set_msglevel = fs_set_msglevel,
+ .get_tx_csum = ethtool_op_get_tx_csum,
+ .set_tx_csum = ethtool_op_set_tx_csum, /* local! */
+ .get_sg = ethtool_op_get_sg,
+ .set_sg = ethtool_op_set_sg,
+ .get_regs = fs_get_regs,
+};
+
+static int fs_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&rq->ifr_data;
+ unsigned long flags;
+ int rc;
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ spin_lock_irqsave(&fep->lock, flags);
+ rc = generic_mii_ioctl(&fep->mii_if, mii, cmd, NULL);
+ spin_unlock_irqrestore(&fep->lock, flags);
+ return rc;
+}
+
+extern int fs_mii_connect(struct net_device *dev);
+extern void fs_mii_disconnect(struct net_device *dev);
+
+static struct net_device *fs_init_instance(struct device *dev,
+ const struct fs_platform_info *fpi)
+{
+ struct net_device *ndev = NULL;
+ struct fs_enet_private *fep = NULL;
+ int privsize, i, r, err = 0, registered = 0;
+
+ /* guard */
+ if ((unsigned int)fpi->fs_no >= FS_MAX_INDEX)
+ return ERR_PTR(-EINVAL);
+
+ privsize = sizeof(*fep) + (sizeof(struct sk_buff **) *
+ (fpi->rx_ring + fpi->tx_ring));
+
+ ndev = alloc_etherdev(privsize);
+ if (!ndev) {
+ err = -ENOMEM;
+ goto err;
+ }
+ SET_MODULE_OWNER(ndev);
+
+ fep = netdev_priv(ndev);
+ memset(fep, 0, privsize); /* clear everything */
+
+ fep->dev = dev;
+ dev_set_drvdata(dev, ndev);
+ fep->fpi = fpi;
+ if (fpi->init_ioports)
+ fpi->init_ioports();
+
+#ifdef CONFIG_FS_ENET_HAS_FEC
+ if (fs_get_fec_index(fpi->fs_no) >= 0)
+ fep->ops = &fs_fec_ops;
+#endif
+
+#ifdef CONFIG_FS_ENET_HAS_SCC
+ if (fs_get_scc_index(fpi->fs_no) >=0 )
+ fep->ops = &fs_scc_ops;
+#endif
+
+#ifdef CONFIG_FS_ENET_HAS_FCC
+ if (fs_get_fcc_index(fpi->fs_no) >= 0)
+ fep->ops = &fs_fcc_ops;
+#endif
+
+ if (fep->ops == NULL) {
+ printk(KERN_ERR DRV_MODULE_NAME
+ ": %s No matching ops found (%d).\n",
+ ndev->name, fpi->fs_no);
+ err = -EINVAL;
+ goto err;
+ }
+
+ r = (*fep->ops->setup_data)(ndev);
+ if (r != 0) {
+ printk(KERN_ERR DRV_MODULE_NAME
+ ": %s setup_data failed\n",
+ ndev->name);
+ err = r;
+ goto err;
+ }
+
+ /* point rx_skbuff, tx_skbuff */
+ fep->rx_skbuff = (struct sk_buff **)&fep[1];
+ fep->tx_skbuff = fep->rx_skbuff + fpi->rx_ring;
+
+ /* init locks */
+ spin_lock_init(&fep->lock);
+ spin_lock_init(&fep->tx_lock);
+
+ /*
+ * Set the Ethernet address.
+ */
+ for (i = 0; i < 6; i++)
+ ndev->dev_addr[i] = fpi->macaddr[i];
+
+ r = (*fep->ops->allocate_bd)(ndev);
+
+ if (fep->ring_base == NULL) {
+ printk(KERN_ERR DRV_MODULE_NAME
+ ": %s buffer descriptor alloc failed (%d).\n", ndev->name, r);
+ err = r;
+ goto err;
+ }
+
+ /*
+ * Set receive and transmit descriptor base.
+ */
+ fep->rx_bd_base = fep->ring_base;
+ fep->tx_bd_base = fep->rx_bd_base + fpi->rx_ring;
+
+ /* initialize ring size variables */
+ fep->tx_ring = fpi->tx_ring;
+ fep->rx_ring = fpi->rx_ring;
+
+ /*
+ * The FEC Ethernet specific entries in the device structure.
+ */
+ ndev->open = fs_enet_open;
+ ndev->hard_start_xmit = fs_enet_start_xmit;
+ ndev->tx_timeout = fs_timeout;
+ ndev->watchdog_timeo = 2 * HZ;
+ ndev->stop = fs_enet_close;
+ ndev->get_stats = fs_enet_get_stats;
+ ndev->set_multicast_list = fs_set_multicast_list;
+ if (fpi->use_napi) {
+ ndev->poll = fs_enet_rx_napi;
+ ndev->weight = fpi->napi_weight;
+ }
+ ndev->ethtool_ops = &fs_ethtool_ops;
+ ndev->do_ioctl = fs_ioctl;
+
+ init_timer(&fep->phy_timer_list);
+
+ netif_carrier_off(ndev);
+
+ err = register_netdev(ndev);
+ if (err != 0) {
+ printk(KERN_ERR DRV_MODULE_NAME
+ ": %s register_netdev failed.\n", ndev->name);
+ goto err;
+ }
+ registered = 1;
+
+ err = fs_mii_connect(ndev);
+ if (err != 0) {
+ printk(KERN_ERR DRV_MODULE_NAME
+ ": %s fs_mii_connect failed.\n", ndev->name);
+ goto err;
+ }
+
+ return ndev;
+
+ err:
+ if (ndev != NULL) {
+
+ if (registered)
+ unregister_netdev(ndev);
+
+ if (fep != NULL) {
+ (*fep->ops->free_bd)(ndev);
+ (*fep->ops->cleanup_data)(ndev);
+ }
+
+ free_netdev(ndev);
+ }
+
+ dev_set_drvdata(dev, NULL);
+
+ return ERR_PTR(err);
+}
+
+static int fs_cleanup_instance(struct net_device *ndev)
+{
+ struct fs_enet_private *fep;
+ const struct fs_platform_info *fpi;
+ struct device *dev;
+
+ if (ndev == NULL)
+ return -EINVAL;
+
+ fep = netdev_priv(ndev);
+ if (fep == NULL)
+ return -EINVAL;
+
+ fpi = fep->fpi;
+
+ fs_mii_disconnect(ndev);
+
+ unregister_netdev(ndev);
+
+ dma_free_coherent(fep->dev, (fpi->tx_ring + fpi->rx_ring) * sizeof(cbd_t),
+ fep->ring_base, fep->ring_mem_addr);
+
+ /* reset it */
+ (*fep->ops->cleanup_data)(ndev);
+
+ dev = fep->dev;
+ if (dev != NULL) {
+ dev_set_drvdata(dev, NULL);
+ fep->dev = NULL;
+ }
+
+ free_netdev(ndev);
+
+ return 0;
+}
+
+/**************************************************************************************/
+
+/* handy pointer to the immap */
+void *fs_enet_immap = NULL;
+
+static int setup_immap(void)
+{
+ phys_addr_t paddr = 0;
+ unsigned long size = 0;
+
+#ifdef CONFIG_CPM1
+ paddr = IMAP_ADDR;
+ size = 0x10000; /* map 64K */
+#endif
+
+#ifdef CONFIG_CPM2
+ paddr = CPM_MAP_ADDR;
+ size = 0x40000; /* map 256 K */
+#endif
+ fs_enet_immap = ioremap(paddr, size);
+ if (fs_enet_immap == NULL)
+ return -EBADF; /* XXX ahem; maybe just BUG_ON? */
+
+ return 0;
+}
+
+static void cleanup_immap(void)
+{
+ if (fs_enet_immap != NULL) {
+ iounmap(fs_enet_immap);
+ fs_enet_immap = NULL;
+ }
+}
+
+/**************************************************************************************/
+
+static int __devinit fs_enet_probe(struct device *dev)
+{
+ struct net_device *ndev;
+
+ /* no fixup - no device */
+ if (dev->platform_data == NULL) {
+ printk(KERN_INFO "fs_enet: "
+ "probe called with no platform data; "
+ "remove unused devices\n");
+ return -ENODEV;
+ }
+
+ ndev = fs_init_instance(dev, dev->platform_data);
+ if (IS_ERR(ndev))
+ return PTR_ERR(ndev);
+ return 0;
+}
+
+static int fs_enet_remove(struct device *dev)
+{
+ return fs_cleanup_instance(dev_get_drvdata(dev));
+}
+
+static struct device_driver fs_enet_fec_driver = {
+ .name = "fsl-cpm-fec",
+ .bus = &platform_bus_type,
+ .probe = fs_enet_probe,
+ .remove = fs_enet_remove,
+#ifdef CONFIG_PM
+/* .suspend = fs_enet_suspend, TODO */
+/* .resume = fs_enet_resume, TODO */
+#endif
+};
+
+static struct device_driver fs_enet_scc_driver = {
+ .name = "fsl-cpm-scc",
+ .bus = &platform_bus_type,
+ .probe = fs_enet_probe,
+ .remove = fs_enet_remove,
+#ifdef CONFIG_PM
+/* .suspend = fs_enet_suspend, TODO */
+/* .resume = fs_enet_resume, TODO */
+#endif
+};
+
+static struct device_driver fs_enet_fcc_driver = {
+ .name = "fsl-cpm-fcc",
+ .bus = &platform_bus_type,
+ .probe = fs_enet_probe,
+ .remove = fs_enet_remove,
+#ifdef CONFIG_PM
+/* .suspend = fs_enet_suspend, TODO */
+/* .resume = fs_enet_resume, TODO */
+#endif
+};
+
+static int __init fs_init(void)
+{
+ int r;
+
+ printk(KERN_INFO
+ "%s", version);
+
+ r = setup_immap();
+ if (r != 0)
+ return r;
+ r = driver_register(&fs_enet_fec_driver);
+ if (r != 0)
+ goto err;
+
+ r = driver_register(&fs_enet_fcc_driver);
+ if (r != 0)
+ goto err;
+
+ r = driver_register(&fs_enet_scc_driver);
+ if (r != 0)
+ goto err;
+
+ return 0;
+err:
+ cleanup_immap();
+ return r;
+
+}
+
+static void __exit fs_cleanup(void)
+{
+ driver_unregister(&fs_enet_fec_driver);
+ driver_unregister(&fs_enet_fcc_driver);
+ driver_unregister(&fs_enet_scc_driver);
+ cleanup_immap();
+}
+
+/**************************************************************************************/
+
+module_init(fs_init);
+module_exit(fs_cleanup);
diff --git a/drivers/net/fs_enet/fs_enet-mii.c b/drivers/net/fs_enet/fs_enet-mii.c
new file mode 100644
index 000000000000..c6770377ef87
--- /dev/null
+++ b/drivers/net/fs_enet/fs_enet-mii.c
@@ -0,0 +1,507 @@
+/*
+ * Combined Ethernet driver for Motorola MPC8xx and MPC82xx.
+ *
+ * Copyright (c) 2003 Intracom S.A.
+ * by Pantelis Antoniou <panto@intracom.gr>
+ *
+ * 2005 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * Heavily based on original FEC driver by Dan Malek <dan@embeddededge.com>
+ * and modifications by Joakim Tjernlund <joakim.tjernlund@lumentis.se>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/bitops.h>
+
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#include "fs_enet.h"
+
+/*************************************************/
+
+/*
+ * Generic PHY support.
+ * Should work for all PHYs, but link change is detected by polling
+ */
+
+static void generic_timer_callback(unsigned long data)
+{
+ struct net_device *dev = (struct net_device *)data;
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ fep->phy_timer_list.expires = jiffies + HZ / 2;
+
+ add_timer(&fep->phy_timer_list);
+
+ fs_mii_link_status_change_check(dev, 0);
+}
+
+static void generic_startup(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ fep->phy_timer_list.expires = jiffies + HZ / 2; /* every 500ms */
+ fep->phy_timer_list.data = (unsigned long)dev;
+ fep->phy_timer_list.function = generic_timer_callback;
+ add_timer(&fep->phy_timer_list);
+}
+
+static void generic_shutdown(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ del_timer_sync(&fep->phy_timer_list);
+}
+
+/* ------------------------------------------------------------------------- */
+/* The Davicom DM9161 is used on the NETTA board */
+
+/* register definitions */
+
+#define MII_DM9161_ANAR 4 /* Aux. Config Register */
+#define MII_DM9161_ACR 16 /* Aux. Config Register */
+#define MII_DM9161_ACSR 17 /* Aux. Config/Status Register */
+#define MII_DM9161_10TCSR 18 /* 10BaseT Config/Status Reg. */
+#define MII_DM9161_INTR 21 /* Interrupt Register */
+#define MII_DM9161_RECR 22 /* Receive Error Counter Reg. */
+#define MII_DM9161_DISCR 23 /* Disconnect Counter Register */
+
+static void dm9161_startup(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ fs_mii_write(dev, fep->mii_if.phy_id, MII_DM9161_INTR, 0x0000);
+ /* Start autonegotiation */
+ fs_mii_write(dev, fep->mii_if.phy_id, MII_BMCR, 0x1200);
+
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(HZ*8);
+}
+
+static void dm9161_ack_int(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ fs_mii_read(dev, fep->mii_if.phy_id, MII_DM9161_INTR);
+}
+
+static void dm9161_shutdown(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ fs_mii_write(dev, fep->mii_if.phy_id, MII_DM9161_INTR, 0x0f00);
+}
+
+/**********************************************************************************/
+
+static const struct phy_info phy_info[] = {
+ {
+ .id = 0x00181b88,
+ .name = "DM9161",
+ .startup = dm9161_startup,
+ .ack_int = dm9161_ack_int,
+ .shutdown = dm9161_shutdown,
+ }, {
+ .id = 0,
+ .name = "GENERIC",
+ .startup = generic_startup,
+ .shutdown = generic_shutdown,
+ },
+};
+
+/**********************************************************************************/
+
+static int phy_id_detect(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ const struct fs_platform_info *fpi = fep->fpi;
+ struct fs_enet_mii_bus *bus = fep->mii_bus;
+ int i, r, start, end, phytype, physubtype;
+ const struct phy_info *phy;
+ int phy_hwid, phy_id;
+
+ phy_hwid = -1;
+ fep->phy = NULL;
+
+ /* auto-detect? */
+ if (fpi->phy_addr == -1) {
+ start = 1;
+ end = 32;
+ } else { /* direct */
+ start = fpi->phy_addr;
+ end = start + 1;
+ }
+
+ for (phy_id = start; phy_id < end; phy_id++) {
+ /* skip already used phy addresses on this bus */
+ if (bus->usage_map & (1 << phy_id))
+ continue;
+ r = fs_mii_read(dev, phy_id, MII_PHYSID1);
+ if (r == -1 || (phytype = (r & 0xffff)) == 0xffff)
+ continue;
+ r = fs_mii_read(dev, phy_id, MII_PHYSID2);
+ if (r == -1 || (physubtype = (r & 0xffff)) == 0xffff)
+ continue;
+ phy_hwid = (phytype << 16) | physubtype;
+ if (phy_hwid != -1)
+ break;
+ }
+
+ if (phy_hwid == -1) {
+ printk(KERN_ERR DRV_MODULE_NAME
+ ": %s No PHY detected! range=0x%02x-0x%02x\n",
+ dev->name, start, end);
+ return -1;
+ }
+
+ for (i = 0, phy = phy_info; i < ARRAY_SIZE(phy_info); i++, phy++)
+ if (phy->id == (phy_hwid >> 4) || phy->id == 0)
+ break;
+
+ if (i >= ARRAY_SIZE(phy_info)) {
+ printk(KERN_ERR DRV_MODULE_NAME
+ ": %s PHY id 0x%08x is not supported!\n",
+ dev->name, phy_hwid);
+ return -1;
+ }
+
+ fep->phy = phy;
+
+ /* mark this address as used */
+ bus->usage_map |= (1 << phy_id);
+
+ printk(KERN_INFO DRV_MODULE_NAME
+ ": %s Phy @ 0x%x, type %s (0x%08x)%s\n",
+ dev->name, phy_id, fep->phy->name, phy_hwid,
+ fpi->phy_addr == -1 ? " (auto-detected)" : "");
+
+ return phy_id;
+}
+
+void fs_mii_startup(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ if (fep->phy->startup)
+ (*fep->phy->startup) (dev);
+}
+
+void fs_mii_shutdown(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ if (fep->phy->shutdown)
+ (*fep->phy->shutdown) (dev);
+}
+
+void fs_mii_ack_int(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ if (fep->phy->ack_int)
+ (*fep->phy->ack_int) (dev);
+}
+
+#define MII_LINK 0x0001
+#define MII_HALF 0x0002
+#define MII_FULL 0x0004
+#define MII_BASE4 0x0008
+#define MII_10M 0x0010
+#define MII_100M 0x0020
+#define MII_1G 0x0040
+#define MII_10G 0x0080
+
+/* return full mii info at one gulp, with a usable form */
+static unsigned int mii_full_status(struct mii_if_info *mii)
+{
+ unsigned int status;
+ int bmsr, adv, lpa, neg;
+ struct fs_enet_private* fep = netdev_priv(mii->dev);
+
+ /* first, a dummy read, needed to latch some MII phys */
+ (void)mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR);
+ bmsr = mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR);
+
+ /* no link */
+ if ((bmsr & BMSR_LSTATUS) == 0)
+ return 0;
+
+ status = MII_LINK;
+
+ /* Lets look what ANEG says if it's supported - otherwize we shall
+ take the right values from the platform info*/
+ if(!mii->force_media) {
+ /* autoneg not completed; don't bother */
+ if ((bmsr & BMSR_ANEGCOMPLETE) == 0)
+ return 0;
+
+ adv = (*mii->mdio_read)(mii->dev, mii->phy_id, MII_ADVERTISE);
+ lpa = (*mii->mdio_read)(mii->dev, mii->phy_id, MII_LPA);
+
+ neg = lpa & adv;
+ } else {
+ neg = fep->fpi->bus_info->lpa;
+ }
+
+ if (neg & LPA_100FULL)
+ status |= MII_FULL | MII_100M;
+ else if (neg & LPA_100BASE4)
+ status |= MII_FULL | MII_BASE4 | MII_100M;
+ else if (neg & LPA_100HALF)
+ status |= MII_HALF | MII_100M;
+ else if (neg & LPA_10FULL)
+ status |= MII_FULL | MII_10M;
+ else
+ status |= MII_HALF | MII_10M;
+
+ return status;
+}
+
+void fs_mii_link_status_change_check(struct net_device *dev, int init_media)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ struct mii_if_info *mii = &fep->mii_if;
+ unsigned int mii_status;
+ int ok_to_print, link, duplex, speed;
+ unsigned long flags;
+
+ ok_to_print = netif_msg_link(fep);
+
+ mii_status = mii_full_status(mii);
+
+ if (!init_media && mii_status == fep->last_mii_status)
+ return;
+
+ fep->last_mii_status = mii_status;
+
+ link = !!(mii_status & MII_LINK);
+ duplex = !!(mii_status & MII_FULL);
+ speed = (mii_status & MII_100M) ? 100 : 10;
+
+ if (link == 0) {
+ netif_carrier_off(mii->dev);
+ netif_stop_queue(dev);
+ if (!init_media) {
+ spin_lock_irqsave(&fep->lock, flags);
+ (*fep->ops->stop)(dev);
+ spin_unlock_irqrestore(&fep->lock, flags);
+ }
+
+ if (ok_to_print)
+ printk(KERN_INFO "%s: link down\n", mii->dev->name);
+
+ } else {
+
+ mii->full_duplex = duplex;
+
+ netif_carrier_on(mii->dev);
+
+ spin_lock_irqsave(&fep->lock, flags);
+ fep->duplex = duplex;
+ fep->speed = speed;
+ (*fep->ops->restart)(dev);
+ spin_unlock_irqrestore(&fep->lock, flags);
+
+ netif_start_queue(dev);
+
+ if (ok_to_print)
+ printk(KERN_INFO "%s: link up, %dMbps, %s-duplex\n",
+ dev->name, speed, duplex ? "full" : "half");
+ }
+}
+
+/**********************************************************************************/
+
+int fs_mii_read(struct net_device *dev, int phy_id, int location)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ struct fs_enet_mii_bus *bus = fep->mii_bus;
+
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&bus->mii_lock, flags);
+ ret = (*bus->mii_read)(bus, phy_id, location);
+ spin_unlock_irqrestore(&bus->mii_lock, flags);
+
+ return ret;
+}
+
+void fs_mii_write(struct net_device *dev, int phy_id, int location, int value)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ struct fs_enet_mii_bus *bus = fep->mii_bus;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bus->mii_lock, flags);
+ (*bus->mii_write)(bus, phy_id, location, value);
+ spin_unlock_irqrestore(&bus->mii_lock, flags);
+}
+
+/*****************************************************************************/
+
+/* list of all registered mii buses */
+static LIST_HEAD(fs_mii_bus_list);
+
+static struct fs_enet_mii_bus *lookup_bus(int method, int id)
+{
+ struct list_head *ptr;
+ struct fs_enet_mii_bus *bus;
+
+ list_for_each(ptr, &fs_mii_bus_list) {
+ bus = list_entry(ptr, struct fs_enet_mii_bus, list);
+ if (bus->bus_info->method == method &&
+ bus->bus_info->id == id)
+ return bus;
+ }
+ return NULL;
+}
+
+static struct fs_enet_mii_bus *create_bus(const struct fs_mii_bus_info *bi)
+{
+ struct fs_enet_mii_bus *bus;
+ int ret = 0;
+
+ bus = kmalloc(sizeof(*bus), GFP_KERNEL);
+ if (bus == NULL) {
+ ret = -ENOMEM;
+ goto err;
+ }
+ memset(bus, 0, sizeof(*bus));
+ spin_lock_init(&bus->mii_lock);
+ bus->bus_info = bi;
+ bus->refs = 0;
+ bus->usage_map = 0;
+
+ /* perform initialization */
+ switch (bi->method) {
+
+ case fsmii_fixed:
+ ret = fs_mii_fixed_init(bus);
+ if (ret != 0)
+ goto err;
+ break;
+
+ case fsmii_bitbang:
+ ret = fs_mii_bitbang_init(bus);
+ if (ret != 0)
+ goto err;
+ break;
+#ifdef CONFIG_FS_ENET_HAS_FEC
+ case fsmii_fec:
+ ret = fs_mii_fec_init(bus);
+ if (ret != 0)
+ goto err;
+ break;
+#endif
+ default:
+ ret = -EINVAL;
+ goto err;
+ }
+
+ list_add(&bus->list, &fs_mii_bus_list);
+
+ return bus;
+
+err:
+ if (bus)
+ kfree(bus);
+ return ERR_PTR(ret);
+}
+
+static void destroy_bus(struct fs_enet_mii_bus *bus)
+{
+ /* remove from bus list */
+ list_del(&bus->list);
+
+ /* nothing more needed */
+ kfree(bus);
+}
+
+int fs_mii_connect(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ const struct fs_platform_info *fpi = fep->fpi;
+ struct fs_enet_mii_bus *bus = NULL;
+
+ /* check method validity */
+ switch (fpi->bus_info->method) {
+ case fsmii_fixed:
+ case fsmii_bitbang:
+ break;
+#ifdef CONFIG_FS_ENET_HAS_FEC
+ case fsmii_fec:
+ break;
+#endif
+ default:
+ printk(KERN_ERR DRV_MODULE_NAME
+ ": %s Unknown MII bus method (%d)!\n",
+ dev->name, fpi->bus_info->method);
+ return -EINVAL;
+ }
+
+ bus = lookup_bus(fpi->bus_info->method, fpi->bus_info->id);
+
+ /* if not found create new bus */
+ if (bus == NULL) {
+ bus = create_bus(fpi->bus_info);
+ if (IS_ERR(bus)) {
+ printk(KERN_ERR DRV_MODULE_NAME
+ ": %s MII bus creation failure!\n", dev->name);
+ return PTR_ERR(bus);
+ }
+ }
+
+ bus->refs++;
+
+ fep->mii_bus = bus;
+
+ fep->mii_if.dev = dev;
+ fep->mii_if.phy_id_mask = 0x1f;
+ fep->mii_if.reg_num_mask = 0x1f;
+ fep->mii_if.mdio_read = fs_mii_read;
+ fep->mii_if.mdio_write = fs_mii_write;
+ fep->mii_if.force_media = fpi->bus_info->disable_aneg;
+ fep->mii_if.phy_id = phy_id_detect(dev);
+
+ return 0;
+}
+
+void fs_mii_disconnect(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ struct fs_enet_mii_bus *bus = NULL;
+
+ bus = fep->mii_bus;
+ fep->mii_bus = NULL;
+
+ if (--bus->refs <= 0)
+ destroy_bus(bus);
+}
diff --git a/drivers/net/fs_enet/fs_enet.h b/drivers/net/fs_enet/fs_enet.h
new file mode 100644
index 000000000000..1105543b9d88
--- /dev/null
+++ b/drivers/net/fs_enet/fs_enet.h
@@ -0,0 +1,245 @@
+#ifndef FS_ENET_H
+#define FS_ENET_H
+
+#include <linux/mii.h>
+#include <linux/netdevice.h>
+#include <linux/types.h>
+#include <linux/version.h>
+#include <linux/list.h>
+
+#include <linux/fs_enet_pd.h>
+
+#include <asm/dma-mapping.h>
+
+#ifdef CONFIG_CPM1
+#include <asm/commproc.h>
+#endif
+
+#ifdef CONFIG_CPM2
+#include <asm/cpm2.h>
+#endif
+
+/* hw driver ops */
+struct fs_ops {
+ int (*setup_data)(struct net_device *dev);
+ int (*allocate_bd)(struct net_device *dev);
+ void (*free_bd)(struct net_device *dev);
+ void (*cleanup_data)(struct net_device *dev);
+ void (*set_multicast_list)(struct net_device *dev);
+ void (*restart)(struct net_device *dev);
+ void (*stop)(struct net_device *dev);
+ void (*pre_request_irq)(struct net_device *dev, int irq);
+ void (*post_free_irq)(struct net_device *dev, int irq);
+ void (*napi_clear_rx_event)(struct net_device *dev);
+ void (*napi_enable_rx)(struct net_device *dev);
+ void (*napi_disable_rx)(struct net_device *dev);
+ void (*rx_bd_done)(struct net_device *dev);
+ void (*tx_kickstart)(struct net_device *dev);
+ u32 (*get_int_events)(struct net_device *dev);
+ void (*clear_int_events)(struct net_device *dev, u32 int_events);
+ void (*ev_error)(struct net_device *dev, u32 int_events);
+ int (*get_regs)(struct net_device *dev, void *p, int *sizep);
+ int (*get_regs_len)(struct net_device *dev);
+ void (*tx_restart)(struct net_device *dev);
+};
+
+struct phy_info {
+ unsigned int id;
+ const char *name;
+ void (*startup) (struct net_device * dev);
+ void (*shutdown) (struct net_device * dev);
+ void (*ack_int) (struct net_device * dev);
+};
+
+/* The FEC stores dest/src/type, data, and checksum for receive packets.
+ */
+#define MAX_MTU 1508 /* Allow fullsized pppoe packets over VLAN */
+#define MIN_MTU 46 /* this is data size */
+#define CRC_LEN 4
+
+#define PKT_MAXBUF_SIZE (MAX_MTU+ETH_HLEN+CRC_LEN)
+#define PKT_MINBUF_SIZE (MIN_MTU+ETH_HLEN+CRC_LEN)
+
+/* Must be a multiple of 32 (to cover both FEC & FCC) */
+#define PKT_MAXBLR_SIZE ((PKT_MAXBUF_SIZE + 31) & ~31)
+/* This is needed so that invalidate_xxx wont invalidate too much */
+#define ENET_RX_FRSIZE L1_CACHE_ALIGN(PKT_MAXBUF_SIZE)
+
+struct fs_enet_mii_bus {
+ struct list_head list;
+ spinlock_t mii_lock;
+ const struct fs_mii_bus_info *bus_info;
+ int refs;
+ u32 usage_map;
+
+ int (*mii_read)(struct fs_enet_mii_bus *bus,
+ int phy_id, int location);
+
+ void (*mii_write)(struct fs_enet_mii_bus *bus,
+ int phy_id, int location, int value);
+
+ union {
+ struct {
+ unsigned int mii_speed;
+ void *fecp;
+ } fec;
+
+ struct {
+ /* note that the actual port size may */
+ /* be different; cpm(s) handle it OK */
+ u8 mdio_msk;
+ u8 *mdio_dir;
+ u8 *mdio_dat;
+ u8 mdc_msk;
+ u8 *mdc_dir;
+ u8 *mdc_dat;
+ } bitbang;
+
+ struct {
+ u16 lpa;
+ } fixed;
+ };
+};
+
+int fs_mii_bitbang_init(struct fs_enet_mii_bus *bus);
+int fs_mii_fixed_init(struct fs_enet_mii_bus *bus);
+int fs_mii_fec_init(struct fs_enet_mii_bus *bus);
+
+struct fs_enet_private {
+ struct device *dev; /* pointer back to the device (must be initialized first) */
+ spinlock_t lock; /* during all ops except TX pckt processing */
+ spinlock_t tx_lock; /* during fs_start_xmit and fs_tx */
+ const struct fs_platform_info *fpi;
+ const struct fs_ops *ops;
+ int rx_ring, tx_ring;
+ dma_addr_t ring_mem_addr;
+ void *ring_base;
+ struct sk_buff **rx_skbuff;
+ struct sk_buff **tx_skbuff;
+ cbd_t *rx_bd_base; /* Address of Rx and Tx buffers. */
+ cbd_t *tx_bd_base;
+ cbd_t *dirty_tx; /* ring entries to be free()ed. */
+ cbd_t *cur_rx;
+ cbd_t *cur_tx;
+ int tx_free;
+ struct net_device_stats stats;
+ struct timer_list phy_timer_list;
+ const struct phy_info *phy;
+ u32 msg_enable;
+ struct mii_if_info mii_if;
+ unsigned int last_mii_status;
+ struct fs_enet_mii_bus *mii_bus;
+ int interrupt;
+
+ int duplex, speed; /* current settings */
+
+ /* event masks */
+ u32 ev_napi_rx; /* mask of NAPI rx events */
+ u32 ev_rx; /* rx event mask */
+ u32 ev_tx; /* tx event mask */
+ u32 ev_err; /* error event mask */
+
+ u16 bd_rx_empty; /* mask of BD rx empty */
+ u16 bd_rx_err; /* mask of BD rx errors */
+
+ union {
+ struct {
+ int idx; /* FEC1 = 0, FEC2 = 1 */
+ void *fecp; /* hw registers */
+ u32 hthi, htlo; /* state for multicast */
+ } fec;
+
+ struct {
+ int idx; /* FCC1-3 = 0-2 */
+ void *fccp; /* hw registers */
+ void *ep; /* parameter ram */
+ void *fcccp; /* hw registers cont. */
+ void *mem; /* FCC DPRAM */
+ u32 gaddrh, gaddrl; /* group address */
+ } fcc;
+
+ struct {
+ int idx; /* FEC1 = 0, FEC2 = 1 */
+ void *sccp; /* hw registers */
+ void *ep; /* parameter ram */
+ u32 hthi, htlo; /* state for multicast */
+ } scc;
+
+ };
+};
+
+/***************************************************************************/
+
+int fs_mii_read(struct net_device *dev, int phy_id, int location);
+void fs_mii_write(struct net_device *dev, int phy_id, int location, int value);
+
+void fs_mii_startup(struct net_device *dev);
+void fs_mii_shutdown(struct net_device *dev);
+void fs_mii_ack_int(struct net_device *dev);
+
+void fs_mii_link_status_change_check(struct net_device *dev, int init_media);
+
+void fs_init_bds(struct net_device *dev);
+void fs_cleanup_bds(struct net_device *dev);
+
+/***************************************************************************/
+
+#define DRV_MODULE_NAME "fs_enet"
+#define PFX DRV_MODULE_NAME ": "
+#define DRV_MODULE_VERSION "1.0"
+#define DRV_MODULE_RELDATE "Aug 8, 2005"
+
+/***************************************************************************/
+
+int fs_enet_platform_init(void);
+void fs_enet_platform_cleanup(void);
+
+/***************************************************************************/
+
+/* buffer descriptor access macros */
+
+/* access macros */
+#if defined(CONFIG_CPM1)
+/* for a a CPM1 __raw_xxx's are sufficient */
+#define __cbd_out32(addr, x) __raw_writel(x, addr)
+#define __cbd_out16(addr, x) __raw_writew(x, addr)
+#define __cbd_in32(addr) __raw_readl(addr)
+#define __cbd_in16(addr) __raw_readw(addr)
+#else
+/* for others play it safe */
+#define __cbd_out32(addr, x) out_be32(addr, x)
+#define __cbd_out16(addr, x) out_be16(addr, x)
+#define __cbd_in32(addr) in_be32(addr)
+#define __cbd_in16(addr) in_be16(addr)
+#endif
+
+/* write */
+#define CBDW_SC(_cbd, _sc) __cbd_out16(&(_cbd)->cbd_sc, (_sc))
+#define CBDW_DATLEN(_cbd, _datlen) __cbd_out16(&(_cbd)->cbd_datlen, (_datlen))
+#define CBDW_BUFADDR(_cbd, _bufaddr) __cbd_out32(&(_cbd)->cbd_bufaddr, (_bufaddr))
+
+/* read */
+#define CBDR_SC(_cbd) __cbd_in16(&(_cbd)->cbd_sc)
+#define CBDR_DATLEN(_cbd) __cbd_in16(&(_cbd)->cbd_datlen)
+#define CBDR_BUFADDR(_cbd) __cbd_in32(&(_cbd)->cbd_bufaddr)
+
+/* set bits */
+#define CBDS_SC(_cbd, _sc) CBDW_SC(_cbd, CBDR_SC(_cbd) | (_sc))
+
+/* clear bits */
+#define CBDC_SC(_cbd, _sc) CBDW_SC(_cbd, CBDR_SC(_cbd) & ~(_sc))
+
+/*******************************************************************/
+
+extern const struct fs_ops fs_fec_ops;
+extern const struct fs_ops fs_fcc_ops;
+extern const struct fs_ops fs_scc_ops;
+
+/*******************************************************************/
+
+/* handy pointer to the immap */
+extern void *fs_enet_immap;
+
+/*******************************************************************/
+
+#endif
diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c
new file mode 100644
index 000000000000..a940b96433c7
--- /dev/null
+++ b/drivers/net/fs_enet/mac-fcc.c
@@ -0,0 +1,578 @@
+/*
+ * FCC driver for Motorola MPC82xx (PQ2).
+ *
+ * Copyright (c) 2003 Intracom S.A.
+ * by Pantelis Antoniou <panto@intracom.gr>
+ *
+ * 2005 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/bitops.h>
+#include <linux/fs.h>
+
+#include <asm/immap_cpm2.h>
+#include <asm/mpc8260.h>
+#include <asm/cpm2.h>
+
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#include "fs_enet.h"
+
+/*************************************************/
+
+/* FCC access macros */
+
+#define __fcc_out32(addr, x) out_be32((unsigned *)addr, x)
+#define __fcc_out16(addr, x) out_be16((unsigned short *)addr, x)
+#define __fcc_out8(addr, x) out_8((unsigned char *)addr, x)
+#define __fcc_in32(addr) in_be32((unsigned *)addr)
+#define __fcc_in16(addr) in_be16((unsigned short *)addr)
+#define __fcc_in8(addr) in_8((unsigned char *)addr)
+
+/* parameter space */
+
+/* write, read, set bits, clear bits */
+#define W32(_p, _m, _v) __fcc_out32(&(_p)->_m, (_v))
+#define R32(_p, _m) __fcc_in32(&(_p)->_m)
+#define S32(_p, _m, _v) W32(_p, _m, R32(_p, _m) | (_v))
+#define C32(_p, _m, _v) W32(_p, _m, R32(_p, _m) & ~(_v))
+
+#define W16(_p, _m, _v) __fcc_out16(&(_p)->_m, (_v))
+#define R16(_p, _m) __fcc_in16(&(_p)->_m)
+#define S16(_p, _m, _v) W16(_p, _m, R16(_p, _m) | (_v))
+#define C16(_p, _m, _v) W16(_p, _m, R16(_p, _m) & ~(_v))
+
+#define W8(_p, _m, _v) __fcc_out8(&(_p)->_m, (_v))
+#define R8(_p, _m) __fcc_in8(&(_p)->_m)
+#define S8(_p, _m, _v) W8(_p, _m, R8(_p, _m) | (_v))
+#define C8(_p, _m, _v) W8(_p, _m, R8(_p, _m) & ~(_v))
+
+/*************************************************/
+
+#define FCC_MAX_MULTICAST_ADDRS 64
+
+#define mk_mii_read(REG) (0x60020000 | ((REG & 0x1f) << 18))
+#define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | (VAL & 0xffff))
+#define mk_mii_end 0
+
+#define MAX_CR_CMD_LOOPS 10000
+
+static inline int fcc_cr_cmd(struct fs_enet_private *fep, u32 mcn, u32 op)
+{
+ const struct fs_platform_info *fpi = fep->fpi;
+
+ cpm2_map_t *immap = fs_enet_immap;
+ cpm_cpm2_t *cpmp = &immap->im_cpm;
+ u32 v;
+ int i;
+
+ /* Currently I don't know what feature call will look like. But
+ I guess there'd be something like do_cpm_cmd() which will require page & sblock */
+ v = mk_cr_cmd(fpi->cp_page, fpi->cp_block, mcn, op);
+ W32(cpmp, cp_cpcr, v | CPM_CR_FLG);
+ for (i = 0; i < MAX_CR_CMD_LOOPS; i++)
+ if ((R32(cpmp, cp_cpcr) & CPM_CR_FLG) == 0)
+ break;
+
+ if (i >= MAX_CR_CMD_LOOPS) {
+ printk(KERN_ERR "%s(): Not able to issue CPM command\n",
+ __FUNCTION__);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int do_pd_setup(struct fs_enet_private *fep)
+{
+ struct platform_device *pdev = to_platform_device(fep->dev);
+ struct resource *r;
+
+ /* Fill out IRQ field */
+ fep->interrupt = platform_get_irq(pdev, 0);
+
+ /* Attach the memory for the FCC Parameter RAM */
+ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_pram");
+ fep->fcc.ep = (void *)r->start;
+
+ if (fep->fcc.ep == NULL)
+ return -EINVAL;
+
+ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_regs");
+ fep->fcc.fccp = (void *)r->start;
+
+ if (fep->fcc.fccp == NULL)
+ return -EINVAL;
+
+ fep->fcc.fcccp = (void *)fep->fpi->fcc_regs_c;
+
+ if (fep->fcc.fcccp == NULL)
+ return -EINVAL;
+
+ return 0;
+}
+
+#define FCC_NAPI_RX_EVENT_MSK (FCC_ENET_RXF | FCC_ENET_RXB)
+#define FCC_RX_EVENT (FCC_ENET_RXF)
+#define FCC_TX_EVENT (FCC_ENET_TXB)
+#define FCC_ERR_EVENT_MSK (FCC_ENET_TXE | FCC_ENET_BSY)
+
+static int setup_data(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ const struct fs_platform_info *fpi = fep->fpi;
+
+ fep->fcc.idx = fs_get_fcc_index(fpi->fs_no);
+ if ((unsigned int)fep->fcc.idx >= 3) /* max 3 FCCs */
+ return -EINVAL;
+
+ fep->fcc.mem = (void *)fpi->mem_offset;
+
+ if (do_pd_setup(fep) != 0)
+ return -EINVAL;
+
+ fep->ev_napi_rx = FCC_NAPI_RX_EVENT_MSK;
+ fep->ev_rx = FCC_RX_EVENT;
+ fep->ev_tx = FCC_TX_EVENT;
+ fep->ev_err = FCC_ERR_EVENT_MSK;
+
+ return 0;
+}
+
+static int allocate_bd(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ const struct fs_platform_info *fpi = fep->fpi;
+
+ fep->ring_base = dma_alloc_coherent(fep->dev,
+ (fpi->tx_ring + fpi->rx_ring) *
+ sizeof(cbd_t), &fep->ring_mem_addr,
+ GFP_KERNEL);
+ if (fep->ring_base == NULL)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static void free_bd(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ const struct fs_platform_info *fpi = fep->fpi;
+
+ if (fep->ring_base)
+ dma_free_coherent(fep->dev,
+ (fpi->tx_ring + fpi->rx_ring) * sizeof(cbd_t),
+ fep->ring_base, fep->ring_mem_addr);
+}
+
+static void cleanup_data(struct net_device *dev)
+{
+ /* nothing */
+}
+
+static void set_promiscuous_mode(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fcc_t *fccp = fep->fcc.fccp;
+
+ S32(fccp, fcc_fpsmr, FCC_PSMR_PRO);
+}
+
+static void set_multicast_start(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fcc_enet_t *ep = fep->fcc.ep;
+
+ W32(ep, fen_gaddrh, 0);
+ W32(ep, fen_gaddrl, 0);
+}
+
+static void set_multicast_one(struct net_device *dev, const u8 *mac)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fcc_enet_t *ep = fep->fcc.ep;
+ u16 taddrh, taddrm, taddrl;
+
+ taddrh = ((u16)mac[5] << 8) | mac[4];
+ taddrm = ((u16)mac[3] << 8) | mac[2];
+ taddrl = ((u16)mac[1] << 8) | mac[0];
+
+ W16(ep, fen_taddrh, taddrh);
+ W16(ep, fen_taddrm, taddrm);
+ W16(ep, fen_taddrl, taddrl);
+ fcc_cr_cmd(fep, 0x0C, CPM_CR_SET_GADDR);
+}
+
+static void set_multicast_finish(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fcc_t *fccp = fep->fcc.fccp;
+ fcc_enet_t *ep = fep->fcc.ep;
+
+ /* clear promiscuous always */
+ C32(fccp, fcc_fpsmr, FCC_PSMR_PRO);
+
+ /* if all multi or too many multicasts; just enable all */
+ if ((dev->flags & IFF_ALLMULTI) != 0 ||
+ dev->mc_count > FCC_MAX_MULTICAST_ADDRS) {
+
+ W32(ep, fen_gaddrh, 0xffffffff);
+ W32(ep, fen_gaddrl, 0xffffffff);
+ }
+
+ /* read back */
+ fep->fcc.gaddrh = R32(ep, fen_gaddrh);
+ fep->fcc.gaddrl = R32(ep, fen_gaddrl);
+}
+
+static void set_multicast_list(struct net_device *dev)
+{
+ struct dev_mc_list *pmc;
+
+ if ((dev->flags & IFF_PROMISC) == 0) {
+ set_multicast_start(dev);
+ for (pmc = dev->mc_list; pmc != NULL; pmc = pmc->next)
+ set_multicast_one(dev, pmc->dmi_addr);
+ set_multicast_finish(dev);
+ } else
+ set_promiscuous_mode(dev);
+}
+
+static void restart(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ const struct fs_platform_info *fpi = fep->fpi;
+ fcc_t *fccp = fep->fcc.fccp;
+ fcc_c_t *fcccp = fep->fcc.fcccp;
+ fcc_enet_t *ep = fep->fcc.ep;
+ dma_addr_t rx_bd_base_phys, tx_bd_base_phys;
+ u16 paddrh, paddrm, paddrl;
+ u16 mem_addr;
+ const unsigned char *mac;
+ int i;
+
+ C32(fccp, fcc_gfmr, FCC_GFMR_ENR | FCC_GFMR_ENT);
+
+ /* clear everything (slow & steady does it) */
+ for (i = 0; i < sizeof(*ep); i++)
+ __fcc_out8((char *)ep + i, 0);
+
+ /* get physical address */
+ rx_bd_base_phys = fep->ring_mem_addr;
+ tx_bd_base_phys = rx_bd_base_phys + sizeof(cbd_t) * fpi->rx_ring;
+
+ /* point to bds */
+ W32(ep, fen_genfcc.fcc_rbase, rx_bd_base_phys);
+ W32(ep, fen_genfcc.fcc_tbase, tx_bd_base_phys);
+
+ /* Set maximum bytes per receive buffer.
+ * It must be a multiple of 32.
+ */
+ W16(ep, fen_genfcc.fcc_mrblr, PKT_MAXBLR_SIZE);
+
+ W32(ep, fen_genfcc.fcc_rstate, (CPMFCR_GBL | CPMFCR_EB) << 24);
+ W32(ep, fen_genfcc.fcc_tstate, (CPMFCR_GBL | CPMFCR_EB) << 24);
+
+ /* Allocate space in the reserved FCC area of DPRAM for the
+ * internal buffers. No one uses this space (yet), so we
+ * can do this. Later, we will add resource management for
+ * this area.
+ */
+
+ mem_addr = (u32) fep->fcc.mem; /* de-fixup dpram offset */
+
+ W16(ep, fen_genfcc.fcc_riptr, (mem_addr & 0xffff));
+ W16(ep, fen_genfcc.fcc_tiptr, ((mem_addr + 32) & 0xffff));
+ W16(ep, fen_padptr, mem_addr + 64);
+
+ /* fill with special symbol... */
+ memset(fep->fcc.mem + fpi->dpram_offset + 64, 0x88, 32);
+
+ W32(ep, fen_genfcc.fcc_rbptr, 0);
+ W32(ep, fen_genfcc.fcc_tbptr, 0);
+ W32(ep, fen_genfcc.fcc_rcrc, 0);
+ W32(ep, fen_genfcc.fcc_tcrc, 0);
+ W16(ep, fen_genfcc.fcc_res1, 0);
+ W32(ep, fen_genfcc.fcc_res2, 0);
+
+ /* no CAM */
+ W32(ep, fen_camptr, 0);
+
+ /* Set CRC preset and mask */
+ W32(ep, fen_cmask, 0xdebb20e3);
+ W32(ep, fen_cpres, 0xffffffff);
+
+ W32(ep, fen_crcec, 0); /* CRC Error counter */
+ W32(ep, fen_alec, 0); /* alignment error counter */
+ W32(ep, fen_disfc, 0); /* discard frame counter */
+ W16(ep, fen_retlim, 15); /* Retry limit threshold */
+ W16(ep, fen_pper, 0); /* Normal persistence */
+
+ /* set group address */
+ W32(ep, fen_gaddrh, fep->fcc.gaddrh);
+ W32(ep, fen_gaddrl, fep->fcc.gaddrh);
+
+ /* Clear hash filter tables */
+ W32(ep, fen_iaddrh, 0);
+ W32(ep, fen_iaddrl, 0);
+
+ /* Clear the Out-of-sequence TxBD */
+ W16(ep, fen_tfcstat, 0);
+ W16(ep, fen_tfclen, 0);
+ W32(ep, fen_tfcptr, 0);
+
+ W16(ep, fen_mflr, PKT_MAXBUF_SIZE); /* maximum frame length register */
+ W16(ep, fen_minflr, PKT_MINBUF_SIZE); /* minimum frame length register */
+
+ /* set address */
+ mac = dev->dev_addr;
+ paddrh = ((u16)mac[5] << 8) | mac[4];
+ paddrm = ((u16)mac[3] << 8) | mac[2];
+ paddrl = ((u16)mac[1] << 8) | mac[0];
+
+ W16(ep, fen_paddrh, paddrh);
+ W16(ep, fen_paddrm, paddrm);
+ W16(ep, fen_paddrl, paddrl);
+
+ W16(ep, fen_taddrh, 0);
+ W16(ep, fen_taddrm, 0);
+ W16(ep, fen_taddrl, 0);
+
+ W16(ep, fen_maxd1, 1520); /* maximum DMA1 length */
+ W16(ep, fen_maxd2, 1520); /* maximum DMA2 length */
+
+ /* Clear stat counters, in case we ever enable RMON */
+ W32(ep, fen_octc, 0);
+ W32(ep, fen_colc, 0);
+ W32(ep, fen_broc, 0);
+ W32(ep, fen_mulc, 0);
+ W32(ep, fen_uspc, 0);
+ W32(ep, fen_frgc, 0);
+ W32(ep, fen_ospc, 0);
+ W32(ep, fen_jbrc, 0);
+ W32(ep, fen_p64c, 0);
+ W32(ep, fen_p65c, 0);
+ W32(ep, fen_p128c, 0);
+ W32(ep, fen_p256c, 0);
+ W32(ep, fen_p512c, 0);
+ W32(ep, fen_p1024c, 0);
+
+ W16(ep, fen_rfthr, 0); /* Suggested by manual */
+ W16(ep, fen_rfcnt, 0);
+ W16(ep, fen_cftype, 0);
+
+ fs_init_bds(dev);
+
+ /* adjust to speed (for RMII mode) */
+ if (fpi->use_rmii) {
+ if (fep->speed == 100)
+ C8(fcccp, fcc_gfemr, 0x20);
+ else
+ S8(fcccp, fcc_gfemr, 0x20);
+ }
+
+ fcc_cr_cmd(fep, 0x0c, CPM_CR_INIT_TRX);
+
+ /* clear events */
+ W16(fccp, fcc_fcce, 0xffff);
+
+ /* Enable interrupts we wish to service */
+ W16(fccp, fcc_fccm, FCC_ENET_TXE | FCC_ENET_RXF | FCC_ENET_TXB);
+
+ /* Set GFMR to enable Ethernet operating mode */
+ W32(fccp, fcc_gfmr, FCC_GFMR_TCI | FCC_GFMR_MODE_ENET);
+
+ /* set sync/delimiters */
+ W16(fccp, fcc_fdsr, 0xd555);
+
+ W32(fccp, fcc_fpsmr, FCC_PSMR_ENCRC);
+
+ if (fpi->use_rmii)
+ S32(fccp, fcc_fpsmr, FCC_PSMR_RMII);
+
+ /* adjust to duplex mode */
+ if (fep->duplex)
+ S32(fccp, fcc_fpsmr, FCC_PSMR_FDE | FCC_PSMR_LPB);
+ else
+ C32(fccp, fcc_fpsmr, FCC_PSMR_FDE | FCC_PSMR_LPB);
+
+ S32(fccp, fcc_gfmr, FCC_GFMR_ENR | FCC_GFMR_ENT);
+}
+
+static void stop(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fcc_t *fccp = fep->fcc.fccp;
+
+ /* stop ethernet */
+ C32(fccp, fcc_gfmr, FCC_GFMR_ENR | FCC_GFMR_ENT);
+
+ /* clear events */
+ W16(fccp, fcc_fcce, 0xffff);
+
+ /* clear interrupt mask */
+ W16(fccp, fcc_fccm, 0);
+
+ fs_cleanup_bds(dev);
+}
+
+static void pre_request_irq(struct net_device *dev, int irq)
+{
+ /* nothing */
+}
+
+static void post_free_irq(struct net_device *dev, int irq)
+{
+ /* nothing */
+}
+
+static void napi_clear_rx_event(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fcc_t *fccp = fep->fcc.fccp;
+
+ W16(fccp, fcc_fcce, FCC_NAPI_RX_EVENT_MSK);
+}
+
+static void napi_enable_rx(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fcc_t *fccp = fep->fcc.fccp;
+
+ S16(fccp, fcc_fccm, FCC_NAPI_RX_EVENT_MSK);
+}
+
+static void napi_disable_rx(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fcc_t *fccp = fep->fcc.fccp;
+
+ C16(fccp, fcc_fccm, FCC_NAPI_RX_EVENT_MSK);
+}
+
+static void rx_bd_done(struct net_device *dev)
+{
+ /* nothing */
+}
+
+static void tx_kickstart(struct net_device *dev)
+{
+ /* nothing */
+}
+
+static u32 get_int_events(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fcc_t *fccp = fep->fcc.fccp;
+
+ return (u32)R16(fccp, fcc_fcce);
+}
+
+static void clear_int_events(struct net_device *dev, u32 int_events)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fcc_t *fccp = fep->fcc.fccp;
+
+ W16(fccp, fcc_fcce, int_events & 0xffff);
+}
+
+static void ev_error(struct net_device *dev, u32 int_events)
+{
+ printk(KERN_WARNING DRV_MODULE_NAME
+ ": %s FS_ENET ERROR(s) 0x%x\n", dev->name, int_events);
+}
+
+int get_regs(struct net_device *dev, void *p, int *sizep)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ if (*sizep < sizeof(fcc_t) + sizeof(fcc_c_t) + sizeof(fcc_enet_t))
+ return -EINVAL;
+
+ memcpy_fromio(p, fep->fcc.fccp, sizeof(fcc_t));
+ p = (char *)p + sizeof(fcc_t);
+
+ memcpy_fromio(p, fep->fcc.fcccp, sizeof(fcc_c_t));
+ p = (char *)p + sizeof(fcc_c_t);
+
+ memcpy_fromio(p, fep->fcc.ep, sizeof(fcc_enet_t));
+
+ return 0;
+}
+
+int get_regs_len(struct net_device *dev)
+{
+ return sizeof(fcc_t) + sizeof(fcc_c_t) + sizeof(fcc_enet_t);
+}
+
+/* Some transmit errors cause the transmitter to shut
+ * down. We now issue a restart transmit. Since the
+ * errors close the BD and update the pointers, the restart
+ * _should_ pick up without having to reset any of our
+ * pointers either. Also, To workaround 8260 device erratum
+ * CPM37, we must disable and then re-enable the transmitter
+ * following a Late Collision, Underrun, or Retry Limit error.
+ */
+void tx_restart(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fcc_t *fccp = fep->fcc.fccp;
+
+ C32(fccp, fcc_gfmr, FCC_GFMR_ENT);
+ udelay(10);
+ S32(fccp, fcc_gfmr, FCC_GFMR_ENT);
+
+ fcc_cr_cmd(fep, 0x0C, CPM_CR_RESTART_TX);
+}
+
+/*************************************************************************/
+
+const struct fs_ops fs_fcc_ops = {
+ .setup_data = setup_data,
+ .cleanup_data = cleanup_data,
+ .set_multicast_list = set_multicast_list,
+ .restart = restart,
+ .stop = stop,
+ .pre_request_irq = pre_request_irq,
+ .post_free_irq = post_free_irq,
+ .napi_clear_rx_event = napi_clear_rx_event,
+ .napi_enable_rx = napi_enable_rx,
+ .napi_disable_rx = napi_disable_rx,
+ .rx_bd_done = rx_bd_done,
+ .tx_kickstart = tx_kickstart,
+ .get_int_events = get_int_events,
+ .clear_int_events = clear_int_events,
+ .ev_error = ev_error,
+ .get_regs = get_regs,
+ .get_regs_len = get_regs_len,
+ .tx_restart = tx_restart,
+ .allocate_bd = allocate_bd,
+ .free_bd = free_bd,
+};
diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c
new file mode 100644
index 000000000000..5ef4e845a387
--- /dev/null
+++ b/drivers/net/fs_enet/mac-fec.c
@@ -0,0 +1,653 @@
+/*
+ * Freescale Ethernet controllers
+ *
+ * Copyright (c) 2005 Intracom S.A.
+ * by Pantelis Antoniou <panto@intracom.gr>
+ *
+ * 2005 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/bitops.h>
+#include <linux/fs.h>
+
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#ifdef CONFIG_8xx
+#include <asm/8xx_immap.h>
+#include <asm/pgtable.h>
+#include <asm/mpc8xx.h>
+#include <asm/commproc.h>
+#endif
+
+#include "fs_enet.h"
+
+/*************************************************/
+
+#if defined(CONFIG_CPM1)
+/* for a CPM1 __raw_xxx's are sufficient */
+#define __fs_out32(addr, x) __raw_writel(x, addr)
+#define __fs_out16(addr, x) __raw_writew(x, addr)
+#define __fs_in32(addr) __raw_readl(addr)
+#define __fs_in16(addr) __raw_readw(addr)
+#else
+/* for others play it safe */
+#define __fs_out32(addr, x) out_be32(addr, x)
+#define __fs_out16(addr, x) out_be16(addr, x)
+#define __fs_in32(addr) in_be32(addr)
+#define __fs_in16(addr) in_be16(addr)
+#endif
+
+/* write */
+#define FW(_fecp, _reg, _v) __fs_out32(&(_fecp)->fec_ ## _reg, (_v))
+
+/* read */
+#define FR(_fecp, _reg) __fs_in32(&(_fecp)->fec_ ## _reg)
+
+/* set bits */
+#define FS(_fecp, _reg, _v) FW(_fecp, _reg, FR(_fecp, _reg) | (_v))
+
+/* clear bits */
+#define FC(_fecp, _reg, _v) FW(_fecp, _reg, FR(_fecp, _reg) & ~(_v))
+
+
+/* CRC polynomium used by the FEC for the multicast group filtering */
+#define FEC_CRC_POLY 0x04C11DB7
+
+#define FEC_MAX_MULTICAST_ADDRS 64
+
+/* Interrupt events/masks.
+*/
+#define FEC_ENET_HBERR 0x80000000U /* Heartbeat error */
+#define FEC_ENET_BABR 0x40000000U /* Babbling receiver */
+#define FEC_ENET_BABT 0x20000000U /* Babbling transmitter */
+#define FEC_ENET_GRA 0x10000000U /* Graceful stop complete */
+#define FEC_ENET_TXF 0x08000000U /* Full frame transmitted */
+#define FEC_ENET_TXB 0x04000000U /* A buffer was transmitted */
+#define FEC_ENET_RXF 0x02000000U /* Full frame received */
+#define FEC_ENET_RXB 0x01000000U /* A buffer was received */
+#define FEC_ENET_MII 0x00800000U /* MII interrupt */
+#define FEC_ENET_EBERR 0x00400000U /* SDMA bus error */
+
+#define FEC_ECNTRL_PINMUX 0x00000004
+#define FEC_ECNTRL_ETHER_EN 0x00000002
+#define FEC_ECNTRL_RESET 0x00000001
+
+#define FEC_RCNTRL_BC_REJ 0x00000010
+#define FEC_RCNTRL_PROM 0x00000008
+#define FEC_RCNTRL_MII_MODE 0x00000004
+#define FEC_RCNTRL_DRT 0x00000002
+#define FEC_RCNTRL_LOOP 0x00000001
+
+#define FEC_TCNTRL_FDEN 0x00000004
+#define FEC_TCNTRL_HBC 0x00000002
+#define FEC_TCNTRL_GTS 0x00000001
+
+
+/* Make MII read/write commands for the FEC.
+*/
+#define mk_mii_read(REG) (0x60020000 | ((REG & 0x1f) << 18))
+#define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | (VAL & 0xffff))
+#define mk_mii_end 0
+
+#define FEC_MII_LOOPS 10000
+
+/*
+ * Delay to wait for FEC reset command to complete (in us)
+ */
+#define FEC_RESET_DELAY 50
+
+static int whack_reset(fec_t * fecp)
+{
+ int i;
+
+ FW(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET);
+ for (i = 0; i < FEC_RESET_DELAY; i++) {
+ if ((FR(fecp, ecntrl) & FEC_ECNTRL_RESET) == 0)
+ return 0; /* OK */
+ udelay(1);
+ }
+
+ return -1;
+}
+
+static int do_pd_setup(struct fs_enet_private *fep)
+{
+ struct platform_device *pdev = to_platform_device(fep->dev);
+ struct resource *r;
+
+ /* Fill out IRQ field */
+ fep->interrupt = platform_get_irq_byname(pdev,"interrupt");
+
+ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
+ fep->fec.fecp =(void*)r->start;
+
+ if(fep->fec.fecp == NULL)
+ return -EINVAL;
+
+ return 0;
+
+}
+
+#define FEC_NAPI_RX_EVENT_MSK (FEC_ENET_RXF | FEC_ENET_RXB)
+#define FEC_RX_EVENT (FEC_ENET_RXF)
+#define FEC_TX_EVENT (FEC_ENET_TXF)
+#define FEC_ERR_EVENT_MSK (FEC_ENET_HBERR | FEC_ENET_BABR | \
+ FEC_ENET_BABT | FEC_ENET_EBERR)
+
+static int setup_data(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ if (do_pd_setup(fep) != 0)
+ return -EINVAL;
+
+ fep->fec.hthi = 0;
+ fep->fec.htlo = 0;
+
+ fep->ev_napi_rx = FEC_NAPI_RX_EVENT_MSK;
+ fep->ev_rx = FEC_RX_EVENT;
+ fep->ev_tx = FEC_TX_EVENT;
+ fep->ev_err = FEC_ERR_EVENT_MSK;
+
+ return 0;
+}
+
+static int allocate_bd(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ const struct fs_platform_info *fpi = fep->fpi;
+
+ fep->ring_base = dma_alloc_coherent(fep->dev,
+ (fpi->tx_ring + fpi->rx_ring) *
+ sizeof(cbd_t), &fep->ring_mem_addr,
+ GFP_KERNEL);
+ if (fep->ring_base == NULL)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static void free_bd(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ const struct fs_platform_info *fpi = fep->fpi;
+
+ if(fep->ring_base)
+ dma_free_coherent(fep->dev, (fpi->tx_ring + fpi->rx_ring)
+ * sizeof(cbd_t),
+ fep->ring_base,
+ fep->ring_mem_addr);
+}
+
+static void cleanup_data(struct net_device *dev)
+{
+ /* nothing */
+}
+
+static void set_promiscuous_mode(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fec_t *fecp = fep->fec.fecp;
+
+ FS(fecp, r_cntrl, FEC_RCNTRL_PROM);
+}
+
+static void set_multicast_start(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ fep->fec.hthi = 0;
+ fep->fec.htlo = 0;
+}
+
+static void set_multicast_one(struct net_device *dev, const u8 *mac)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ int temp, hash_index, i, j;
+ u32 crc, csrVal;
+ u8 byte, msb;
+
+ crc = 0xffffffff;
+ for (i = 0; i < 6; i++) {
+ byte = mac[i];
+ for (j = 0; j < 8; j++) {
+ msb = crc >> 31;
+ crc <<= 1;
+ if (msb ^ (byte & 0x1))
+ crc ^= FEC_CRC_POLY;
+ byte >>= 1;
+ }
+ }
+
+ temp = (crc & 0x3f) >> 1;
+ hash_index = ((temp & 0x01) << 4) |
+ ((temp & 0x02) << 2) |
+ ((temp & 0x04)) |
+ ((temp & 0x08) >> 2) |
+ ((temp & 0x10) >> 4);
+ csrVal = 1 << hash_index;
+ if (crc & 1)
+ fep->fec.hthi |= csrVal;
+ else
+ fep->fec.htlo |= csrVal;
+}
+
+static void set_multicast_finish(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fec_t *fecp = fep->fec.fecp;
+
+ /* if all multi or too many multicasts; just enable all */
+ if ((dev->flags & IFF_ALLMULTI) != 0 ||
+ dev->mc_count > FEC_MAX_MULTICAST_ADDRS) {
+ fep->fec.hthi = 0xffffffffU;
+ fep->fec.htlo = 0xffffffffU;
+ }
+
+ FC(fecp, r_cntrl, FEC_RCNTRL_PROM);
+ FW(fecp, hash_table_high, fep->fec.hthi);
+ FW(fecp, hash_table_low, fep->fec.htlo);
+}
+
+static void set_multicast_list(struct net_device *dev)
+{
+ struct dev_mc_list *pmc;
+
+ if ((dev->flags & IFF_PROMISC) == 0) {
+ set_multicast_start(dev);
+ for (pmc = dev->mc_list; pmc != NULL; pmc = pmc->next)
+ set_multicast_one(dev, pmc->dmi_addr);
+ set_multicast_finish(dev);
+ } else
+ set_promiscuous_mode(dev);
+}
+
+static void restart(struct net_device *dev)
+{
+#ifdef CONFIG_DUET
+ immap_t *immap = fs_enet_immap;
+ u32 cptr;
+#endif
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fec_t *fecp = fep->fec.fecp;
+ const struct fs_platform_info *fpi = fep->fpi;
+ dma_addr_t rx_bd_base_phys, tx_bd_base_phys;
+ int r;
+ u32 addrhi, addrlo;
+
+ r = whack_reset(fep->fec.fecp);
+ if (r != 0)
+ printk(KERN_ERR DRV_MODULE_NAME
+ ": %s FEC Reset FAILED!\n", dev->name);
+
+ /*
+ * Set station address.
+ */
+ addrhi = ((u32) dev->dev_addr[0] << 24) |
+ ((u32) dev->dev_addr[1] << 16) |
+ ((u32) dev->dev_addr[2] << 8) |
+ (u32) dev->dev_addr[3];
+ addrlo = ((u32) dev->dev_addr[4] << 24) |
+ ((u32) dev->dev_addr[5] << 16);
+ FW(fecp, addr_low, addrhi);
+ FW(fecp, addr_high, addrlo);
+
+ /*
+ * Reset all multicast.
+ */
+ FW(fecp, hash_table_high, fep->fec.hthi);
+ FW(fecp, hash_table_low, fep->fec.htlo);
+
+ /*
+ * Set maximum receive buffer size.
+ */
+ FW(fecp, r_buff_size, PKT_MAXBLR_SIZE);
+ FW(fecp, r_hash, PKT_MAXBUF_SIZE);
+
+ /* get physical address */
+ rx_bd_base_phys = fep->ring_mem_addr;
+ tx_bd_base_phys = rx_bd_base_phys + sizeof(cbd_t) * fpi->rx_ring;
+
+ /*
+ * Set receive and transmit descriptor base.
+ */
+ FW(fecp, r_des_start, rx_bd_base_phys);
+ FW(fecp, x_des_start, tx_bd_base_phys);
+
+ fs_init_bds(dev);
+
+ /*
+ * Enable big endian and don't care about SDMA FC.
+ */
+ FW(fecp, fun_code, 0x78000000);
+
+ /*
+ * Set MII speed.
+ */
+ FW(fecp, mii_speed, fep->mii_bus->fec.mii_speed);
+
+ /*
+ * Clear any outstanding interrupt.
+ */
+ FW(fecp, ievent, 0xffc0);
+ FW(fecp, ivec, (fep->interrupt / 2) << 29);
+
+
+ /*
+ * adjust to speed (only for DUET & RMII)
+ */
+#ifdef CONFIG_DUET
+ if (fpi->use_rmii) {
+ cptr = in_be32(&immap->im_cpm.cp_cptr);
+ switch (fs_get_fec_index(fpi->fs_no)) {
+ case 0:
+ cptr |= 0x100;
+ if (fep->speed == 10)
+ cptr |= 0x0000010;
+ else if (fep->speed == 100)
+ cptr &= ~0x0000010;
+ break;
+ case 1:
+ cptr |= 0x80;
+ if (fep->speed == 10)
+ cptr |= 0x0000008;
+ else if (fep->speed == 100)
+ cptr &= ~0x0000008;
+ break;
+ default:
+ BUG(); /* should never happen */
+ break;
+ }
+ out_be32(&immap->im_cpm.cp_cptr, cptr);
+ }
+#endif
+
+ FW(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */
+ /*
+ * adjust to duplex mode
+ */
+ if (fep->duplex) {
+ FC(fecp, r_cntrl, FEC_RCNTRL_DRT);
+ FS(fecp, x_cntrl, FEC_TCNTRL_FDEN); /* FD enable */
+ } else {
+ FS(fecp, r_cntrl, FEC_RCNTRL_DRT);
+ FC(fecp, x_cntrl, FEC_TCNTRL_FDEN); /* FD disable */
+ }
+
+ /*
+ * Enable interrupts we wish to service.
+ */
+ FW(fecp, imask, FEC_ENET_TXF | FEC_ENET_TXB |
+ FEC_ENET_RXF | FEC_ENET_RXB);
+
+ /*
+ * And last, enable the transmit and receive processing.
+ */
+ FW(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN);
+ FW(fecp, r_des_active, 0x01000000);
+}
+
+static void stop(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fec_t *fecp = fep->fec.fecp;
+ struct fs_enet_mii_bus *bus = fep->mii_bus;
+ const struct fs_mii_bus_info *bi = bus->bus_info;
+ int i;
+
+ if ((FR(fecp, ecntrl) & FEC_ECNTRL_ETHER_EN) == 0)
+ return; /* already down */
+
+ FW(fecp, x_cntrl, 0x01); /* Graceful transmit stop */
+ for (i = 0; ((FR(fecp, ievent) & 0x10000000) == 0) &&
+ i < FEC_RESET_DELAY; i++)
+ udelay(1);
+
+ if (i == FEC_RESET_DELAY)
+ printk(KERN_WARNING DRV_MODULE_NAME
+ ": %s FEC timeout on graceful transmit stop\n",
+ dev->name);
+ /*
+ * Disable FEC. Let only MII interrupts.
+ */
+ FW(fecp, imask, 0);
+ FC(fecp, ecntrl, FEC_ECNTRL_ETHER_EN);
+
+ fs_cleanup_bds(dev);
+
+ /* shut down FEC1? that's where the mii bus is */
+ if (fep->fec.idx == 0 && bus->refs > 1 && bi->method == fsmii_fec) {
+ FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */
+ FS(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN);
+ FW(fecp, ievent, FEC_ENET_MII);
+ FW(fecp, mii_speed, bus->fec.mii_speed);
+ }
+}
+
+static void pre_request_irq(struct net_device *dev, int irq)
+{
+ immap_t *immap = fs_enet_immap;
+ u32 siel;
+
+ /* SIU interrupt */
+ if (irq >= SIU_IRQ0 && irq < SIU_LEVEL7) {
+
+ siel = in_be32(&immap->im_siu_conf.sc_siel);
+ if ((irq & 1) == 0)
+ siel |= (0x80000000 >> irq);
+ else
+ siel &= ~(0x80000000 >> (irq & ~1));
+ out_be32(&immap->im_siu_conf.sc_siel, siel);
+ }
+}
+
+static void post_free_irq(struct net_device *dev, int irq)
+{
+ /* nothing */
+}
+
+static void napi_clear_rx_event(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fec_t *fecp = fep->fec.fecp;
+
+ FW(fecp, ievent, FEC_NAPI_RX_EVENT_MSK);
+}
+
+static void napi_enable_rx(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fec_t *fecp = fep->fec.fecp;
+
+ FS(fecp, imask, FEC_NAPI_RX_EVENT_MSK);
+}
+
+static void napi_disable_rx(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fec_t *fecp = fep->fec.fecp;
+
+ FC(fecp, imask, FEC_NAPI_RX_EVENT_MSK);
+}
+
+static void rx_bd_done(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fec_t *fecp = fep->fec.fecp;
+
+ FW(fecp, r_des_active, 0x01000000);
+}
+
+static void tx_kickstart(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fec_t *fecp = fep->fec.fecp;
+
+ FW(fecp, x_des_active, 0x01000000);
+}
+
+static u32 get_int_events(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fec_t *fecp = fep->fec.fecp;
+
+ return FR(fecp, ievent) & FR(fecp, imask);
+}
+
+static void clear_int_events(struct net_device *dev, u32 int_events)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fec_t *fecp = fep->fec.fecp;
+
+ FW(fecp, ievent, int_events);
+}
+
+static void ev_error(struct net_device *dev, u32 int_events)
+{
+ printk(KERN_WARNING DRV_MODULE_NAME
+ ": %s FEC ERROR(s) 0x%x\n", dev->name, int_events);
+}
+
+int get_regs(struct net_device *dev, void *p, int *sizep)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ if (*sizep < sizeof(fec_t))
+ return -EINVAL;
+
+ memcpy_fromio(p, fep->fec.fecp, sizeof(fec_t));
+
+ return 0;
+}
+
+int get_regs_len(struct net_device *dev)
+{
+ return sizeof(fec_t);
+}
+
+void tx_restart(struct net_device *dev)
+{
+ /* nothing */
+}
+
+/*************************************************************************/
+
+const struct fs_ops fs_fec_ops = {
+ .setup_data = setup_data,
+ .cleanup_data = cleanup_data,
+ .set_multicast_list = set_multicast_list,
+ .restart = restart,
+ .stop = stop,
+ .pre_request_irq = pre_request_irq,
+ .post_free_irq = post_free_irq,
+ .napi_clear_rx_event = napi_clear_rx_event,
+ .napi_enable_rx = napi_enable_rx,
+ .napi_disable_rx = napi_disable_rx,
+ .rx_bd_done = rx_bd_done,
+ .tx_kickstart = tx_kickstart,
+ .get_int_events = get_int_events,
+ .clear_int_events = clear_int_events,
+ .ev_error = ev_error,
+ .get_regs = get_regs,
+ .get_regs_len = get_regs_len,
+ .tx_restart = tx_restart,
+ .allocate_bd = allocate_bd,
+ .free_bd = free_bd,
+};
+
+/***********************************************************************/
+
+static int mii_read(struct fs_enet_mii_bus *bus, int phy_id, int location)
+{
+ fec_t *fecp = bus->fec.fecp;
+ int i, ret = -1;
+
+ if ((FR(fecp, r_cntrl) & FEC_RCNTRL_MII_MODE) == 0)
+ BUG();
+
+ /* Add PHY address to register command. */
+ FW(fecp, mii_data, (phy_id << 23) | mk_mii_read(location));
+
+ for (i = 0; i < FEC_MII_LOOPS; i++)
+ if ((FR(fecp, ievent) & FEC_ENET_MII) != 0)
+ break;
+
+ if (i < FEC_MII_LOOPS) {
+ FW(fecp, ievent, FEC_ENET_MII);
+ ret = FR(fecp, mii_data) & 0xffff;
+ }
+
+ return ret;
+}
+
+static void mii_write(struct fs_enet_mii_bus *bus, int phy_id, int location, int value)
+{
+ fec_t *fecp = bus->fec.fecp;
+ int i;
+
+ /* this must never happen */
+ if ((FR(fecp, r_cntrl) & FEC_RCNTRL_MII_MODE) == 0)
+ BUG();
+
+ /* Add PHY address to register command. */
+ FW(fecp, mii_data, (phy_id << 23) | mk_mii_write(location, value));
+
+ for (i = 0; i < FEC_MII_LOOPS; i++)
+ if ((FR(fecp, ievent) & FEC_ENET_MII) != 0)
+ break;
+
+ if (i < FEC_MII_LOOPS)
+ FW(fecp, ievent, FEC_ENET_MII);
+}
+
+int fs_mii_fec_init(struct fs_enet_mii_bus *bus)
+{
+ bd_t *bd = (bd_t *)__res;
+ const struct fs_mii_bus_info *bi = bus->bus_info;
+ fec_t *fecp;
+
+ if (bi->id != 0)
+ return -1;
+
+ bus->fec.fecp = &((immap_t *)fs_enet_immap)->im_cpm.cp_fec;
+ bus->fec.mii_speed = ((((bd->bi_intfreq + 4999999) / 2500000) / 2)
+ & 0x3F) << 1;
+
+ fecp = bus->fec.fecp;
+
+ FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */
+ FS(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN);
+ FW(fecp, ievent, FEC_ENET_MII);
+ FW(fecp, mii_speed, bus->fec.mii_speed);
+
+ bus->mii_read = mii_read;
+ bus->mii_write = mii_write;
+
+ return 0;
+}
diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c
new file mode 100644
index 000000000000..d8c6e9cadcf5
--- /dev/null
+++ b/drivers/net/fs_enet/mac-scc.c
@@ -0,0 +1,524 @@
+/*
+ * Ethernet on Serial Communications Controller (SCC) driver for Motorola MPC8xx and MPC82xx.
+ *
+ * Copyright (c) 2003 Intracom S.A.
+ * by Pantelis Antoniou <panto@intracom.gr>
+ *
+ * 2005 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/bitops.h>
+#include <linux/fs.h>
+
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#ifdef CONFIG_8xx
+#include <asm/8xx_immap.h>
+#include <asm/pgtable.h>
+#include <asm/mpc8xx.h>
+#include <asm/commproc.h>
+#endif
+
+#include "fs_enet.h"
+
+/*************************************************/
+
+#if defined(CONFIG_CPM1)
+/* for a 8xx __raw_xxx's are sufficient */
+#define __fs_out32(addr, x) __raw_writel(x, addr)
+#define __fs_out16(addr, x) __raw_writew(x, addr)
+#define __fs_out8(addr, x) __raw_writeb(x, addr)
+#define __fs_in32(addr) __raw_readl(addr)
+#define __fs_in16(addr) __raw_readw(addr)
+#define __fs_in8(addr) __raw_readb(addr)
+#else
+/* for others play it safe */
+#define __fs_out32(addr, x) out_be32(addr, x)
+#define __fs_out16(addr, x) out_be16(addr, x)
+#define __fs_in32(addr) in_be32(addr)
+#define __fs_in16(addr) in_be16(addr)
+#endif
+
+/* write, read, set bits, clear bits */
+#define W32(_p, _m, _v) __fs_out32(&(_p)->_m, (_v))
+#define R32(_p, _m) __fs_in32(&(_p)->_m)
+#define S32(_p, _m, _v) W32(_p, _m, R32(_p, _m) | (_v))
+#define C32(_p, _m, _v) W32(_p, _m, R32(_p, _m) & ~(_v))
+
+#define W16(_p, _m, _v) __fs_out16(&(_p)->_m, (_v))
+#define R16(_p, _m) __fs_in16(&(_p)->_m)
+#define S16(_p, _m, _v) W16(_p, _m, R16(_p, _m) | (_v))
+#define C16(_p, _m, _v) W16(_p, _m, R16(_p, _m) & ~(_v))
+
+#define W8(_p, _m, _v) __fs_out8(&(_p)->_m, (_v))
+#define R8(_p, _m) __fs_in8(&(_p)->_m)
+#define S8(_p, _m, _v) W8(_p, _m, R8(_p, _m) | (_v))
+#define C8(_p, _m, _v) W8(_p, _m, R8(_p, _m) & ~(_v))
+
+#define SCC_MAX_MULTICAST_ADDRS 64
+
+/*
+ * Delay to wait for SCC reset command to complete (in us)
+ */
+#define SCC_RESET_DELAY 50
+#define MAX_CR_CMD_LOOPS 10000
+
+static inline int scc_cr_cmd(struct fs_enet_private *fep, u32 op)
+{
+ cpm8xx_t *cpmp = &((immap_t *)fs_enet_immap)->im_cpm;
+ u32 v, ch;
+ int i = 0;
+
+ ch = fep->scc.idx << 2;
+ v = mk_cr_cmd(ch, op);
+ W16(cpmp, cp_cpcr, v | CPM_CR_FLG);
+ for (i = 0; i < MAX_CR_CMD_LOOPS; i++)
+ if ((R16(cpmp, cp_cpcr) & CPM_CR_FLG) == 0)
+ break;
+
+ if (i >= MAX_CR_CMD_LOOPS) {
+ printk(KERN_ERR "%s(): Not able to issue CPM command\n",
+ __FUNCTION__);
+ return 1;
+ }
+ return 0;
+}
+
+static int do_pd_setup(struct fs_enet_private *fep)
+{
+ struct platform_device *pdev = to_platform_device(fep->dev);
+ struct resource *r;
+
+ /* Fill out IRQ field */
+ fep->interrupt = platform_get_irq_byname(pdev, "interrupt");
+
+ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
+ fep->scc.sccp = (void *)r->start;
+
+ if (fep->scc.sccp == NULL)
+ return -EINVAL;
+
+ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pram");
+ fep->scc.ep = (void *)r->start;
+
+ if (fep->scc.ep == NULL)
+ return -EINVAL;
+
+ return 0;
+}
+
+#define SCC_NAPI_RX_EVENT_MSK (SCCE_ENET_RXF | SCCE_ENET_RXB)
+#define SCC_RX_EVENT (SCCE_ENET_RXF)
+#define SCC_TX_EVENT (SCCE_ENET_TXB)
+#define SCC_ERR_EVENT_MSK (SCCE_ENET_TXE | SCCE_ENET_BSY)
+
+static int setup_data(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ const struct fs_platform_info *fpi = fep->fpi;
+
+ fep->scc.idx = fs_get_scc_index(fpi->fs_no);
+ if ((unsigned int)fep->fcc.idx > 4) /* max 4 SCCs */
+ return -EINVAL;
+
+ do_pd_setup(fep);
+
+ fep->scc.hthi = 0;
+ fep->scc.htlo = 0;
+
+ fep->ev_napi_rx = SCC_NAPI_RX_EVENT_MSK;
+ fep->ev_rx = SCC_RX_EVENT;
+ fep->ev_tx = SCC_TX_EVENT;
+ fep->ev_err = SCC_ERR_EVENT_MSK;
+
+ return 0;
+}
+
+static int allocate_bd(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ const struct fs_platform_info *fpi = fep->fpi;
+
+ fep->ring_mem_addr = cpm_dpalloc((fpi->tx_ring + fpi->rx_ring) *
+ sizeof(cbd_t), 8);
+ if (IS_DPERR(fep->ring_mem_addr))
+ return -ENOMEM;
+
+ fep->ring_base = cpm_dpram_addr(fep->ring_mem_addr);
+
+ return 0;
+}
+
+static void free_bd(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ if (fep->ring_base)
+ cpm_dpfree(fep->ring_mem_addr);
+}
+
+static void cleanup_data(struct net_device *dev)
+{
+ /* nothing */
+}
+
+static void set_promiscuous_mode(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ scc_t *sccp = fep->scc.sccp;
+
+ S16(sccp, scc_psmr, SCC_PSMR_PRO);
+}
+
+static void set_multicast_start(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ scc_enet_t *ep = fep->scc.ep;
+
+ W16(ep, sen_gaddr1, 0);
+ W16(ep, sen_gaddr2, 0);
+ W16(ep, sen_gaddr3, 0);
+ W16(ep, sen_gaddr4, 0);
+}
+
+static void set_multicast_one(struct net_device *dev, const u8 * mac)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ scc_enet_t *ep = fep->scc.ep;
+ u16 taddrh, taddrm, taddrl;
+
+ taddrh = ((u16) mac[5] << 8) | mac[4];
+ taddrm = ((u16) mac[3] << 8) | mac[2];
+ taddrl = ((u16) mac[1] << 8) | mac[0];
+
+ W16(ep, sen_taddrh, taddrh);
+ W16(ep, sen_taddrm, taddrm);
+ W16(ep, sen_taddrl, taddrl);
+ scc_cr_cmd(fep, CPM_CR_SET_GADDR);
+}
+
+static void set_multicast_finish(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ scc_t *sccp = fep->scc.sccp;
+ scc_enet_t *ep = fep->scc.ep;
+
+ /* clear promiscuous always */
+ C16(sccp, scc_psmr, SCC_PSMR_PRO);
+
+ /* if all multi or too many multicasts; just enable all */
+ if ((dev->flags & IFF_ALLMULTI) != 0 ||
+ dev->mc_count > SCC_MAX_MULTICAST_ADDRS) {
+
+ W16(ep, sen_gaddr1, 0xffff);
+ W16(ep, sen_gaddr2, 0xffff);
+ W16(ep, sen_gaddr3, 0xffff);
+ W16(ep, sen_gaddr4, 0xffff);
+ }
+}
+
+static void set_multicast_list(struct net_device *dev)
+{
+ struct dev_mc_list *pmc;
+
+ if ((dev->flags & IFF_PROMISC) == 0) {
+ set_multicast_start(dev);
+ for (pmc = dev->mc_list; pmc != NULL; pmc = pmc->next)
+ set_multicast_one(dev, pmc->dmi_addr);
+ set_multicast_finish(dev);
+ } else
+ set_promiscuous_mode(dev);
+}
+
+/*
+ * This function is called to start or restart the FEC during a link
+ * change. This only happens when switching between half and full
+ * duplex.
+ */
+static void restart(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ scc_t *sccp = fep->scc.sccp;
+ scc_enet_t *ep = fep->scc.ep;
+ const struct fs_platform_info *fpi = fep->fpi;
+ u16 paddrh, paddrm, paddrl;
+ const unsigned char *mac;
+ int i;
+
+ C32(sccp, scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+
+ /* clear everything (slow & steady does it) */
+ for (i = 0; i < sizeof(*ep); i++)
+ __fs_out8((char *)ep + i, 0);
+
+ /* point to bds */
+ W16(ep, sen_genscc.scc_rbase, fep->ring_mem_addr);
+ W16(ep, sen_genscc.scc_tbase,
+ fep->ring_mem_addr + sizeof(cbd_t) * fpi->rx_ring);
+
+ /* Initialize function code registers for big-endian.
+ */
+ W8(ep, sen_genscc.scc_rfcr, SCC_EB);
+ W8(ep, sen_genscc.scc_tfcr, SCC_EB);
+
+ /* Set maximum bytes per receive buffer.
+ * This appears to be an Ethernet frame size, not the buffer
+ * fragment size. It must be a multiple of four.
+ */
+ W16(ep, sen_genscc.scc_mrblr, 0x5f0);
+
+ /* Set CRC preset and mask.
+ */
+ W32(ep, sen_cpres, 0xffffffff);
+ W32(ep, sen_cmask, 0xdebb20e3);
+
+ W32(ep, sen_crcec, 0); /* CRC Error counter */
+ W32(ep, sen_alec, 0); /* alignment error counter */
+ W32(ep, sen_disfc, 0); /* discard frame counter */
+
+ W16(ep, sen_pads, 0x8888); /* Tx short frame pad character */
+ W16(ep, sen_retlim, 15); /* Retry limit threshold */
+
+ W16(ep, sen_maxflr, 0x5ee); /* maximum frame length register */
+
+ W16(ep, sen_minflr, PKT_MINBUF_SIZE); /* minimum frame length register */
+
+ W16(ep, sen_maxd1, 0x000005f0); /* maximum DMA1 length */
+ W16(ep, sen_maxd2, 0x000005f0); /* maximum DMA2 length */
+
+ /* Clear hash tables.
+ */
+ W16(ep, sen_gaddr1, 0);
+ W16(ep, sen_gaddr2, 0);
+ W16(ep, sen_gaddr3, 0);
+ W16(ep, sen_gaddr4, 0);
+ W16(ep, sen_iaddr1, 0);
+ W16(ep, sen_iaddr2, 0);
+ W16(ep, sen_iaddr3, 0);
+ W16(ep, sen_iaddr4, 0);
+
+ /* set address
+ */
+ mac = dev->dev_addr;
+ paddrh = ((u16) mac[5] << 8) | mac[4];
+ paddrm = ((u16) mac[3] << 8) | mac[2];
+ paddrl = ((u16) mac[1] << 8) | mac[0];
+
+ W16(ep, sen_paddrh, paddrh);
+ W16(ep, sen_paddrm, paddrm);
+ W16(ep, sen_paddrl, paddrl);
+
+ W16(ep, sen_pper, 0);
+ W16(ep, sen_taddrl, 0);
+ W16(ep, sen_taddrm, 0);
+ W16(ep, sen_taddrh, 0);
+
+ fs_init_bds(dev);
+
+ scc_cr_cmd(fep, CPM_CR_INIT_TRX);
+
+ W16(sccp, scc_scce, 0xffff);
+
+ /* Enable interrupts we wish to service.
+ */
+ W16(sccp, scc_sccm, SCCE_ENET_TXE | SCCE_ENET_RXF | SCCE_ENET_TXB);
+
+ /* Set GSMR_H to enable all normal operating modes.
+ * Set GSMR_L to enable Ethernet to MC68160.
+ */
+ W32(sccp, scc_gsmrh, 0);
+ W32(sccp, scc_gsmrl,
+ SCC_GSMRL_TCI | SCC_GSMRL_TPL_48 | SCC_GSMRL_TPP_10 |
+ SCC_GSMRL_MODE_ENET);
+
+ /* Set sync/delimiters.
+ */
+ W16(sccp, scc_dsr, 0xd555);
+
+ /* Set processing mode. Use Ethernet CRC, catch broadcast, and
+ * start frame search 22 bit times after RENA.
+ */
+ W16(sccp, scc_psmr, SCC_PSMR_ENCRC | SCC_PSMR_NIB22);
+
+ /* Set full duplex mode if needed */
+ if (fep->duplex)
+ S16(sccp, scc_psmr, SCC_PSMR_LPB | SCC_PSMR_FDE);
+
+ S32(sccp, scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+}
+
+static void stop(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ scc_t *sccp = fep->scc.sccp;
+ int i;
+
+ for (i = 0; (R16(sccp, scc_sccm) == 0) && i < SCC_RESET_DELAY; i++)
+ udelay(1);
+
+ if (i == SCC_RESET_DELAY)
+ printk(KERN_WARNING DRV_MODULE_NAME
+ ": %s SCC timeout on graceful transmit stop\n",
+ dev->name);
+
+ W16(sccp, scc_sccm, 0);
+ C32(sccp, scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+
+ fs_cleanup_bds(dev);
+}
+
+static void pre_request_irq(struct net_device *dev, int irq)
+{
+ immap_t *immap = fs_enet_immap;
+ u32 siel;
+
+ /* SIU interrupt */
+ if (irq >= SIU_IRQ0 && irq < SIU_LEVEL7) {
+
+ siel = in_be32(&immap->im_siu_conf.sc_siel);
+ if ((irq & 1) == 0)
+ siel |= (0x80000000 >> irq);
+ else
+ siel &= ~(0x80000000 >> (irq & ~1));
+ out_be32(&immap->im_siu_conf.sc_siel, siel);
+ }
+}
+
+static void post_free_irq(struct net_device *dev, int irq)
+{
+ /* nothing */
+}
+
+static void napi_clear_rx_event(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ scc_t *sccp = fep->scc.sccp;
+
+ W16(sccp, scc_scce, SCC_NAPI_RX_EVENT_MSK);
+}
+
+static void napi_enable_rx(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ scc_t *sccp = fep->scc.sccp;
+
+ S16(sccp, scc_sccm, SCC_NAPI_RX_EVENT_MSK);
+}
+
+static void napi_disable_rx(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ scc_t *sccp = fep->scc.sccp;
+
+ C16(sccp, scc_sccm, SCC_NAPI_RX_EVENT_MSK);
+}
+
+static void rx_bd_done(struct net_device *dev)
+{
+ /* nothing */
+}
+
+static void tx_kickstart(struct net_device *dev)
+{
+ /* nothing */
+}
+
+static u32 get_int_events(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ scc_t *sccp = fep->scc.sccp;
+
+ return (u32) R16(sccp, scc_scce);
+}
+
+static void clear_int_events(struct net_device *dev, u32 int_events)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ scc_t *sccp = fep->scc.sccp;
+
+ W16(sccp, scc_scce, int_events & 0xffff);
+}
+
+static void ev_error(struct net_device *dev, u32 int_events)
+{
+ printk(KERN_WARNING DRV_MODULE_NAME
+ ": %s SCC ERROR(s) 0x%x\n", dev->name, int_events);
+}
+
+static int get_regs(struct net_device *dev, void *p, int *sizep)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ if (*sizep < sizeof(scc_t) + sizeof(scc_enet_t))
+ return -EINVAL;
+
+ memcpy_fromio(p, fep->scc.sccp, sizeof(scc_t));
+ p = (char *)p + sizeof(scc_t);
+
+ memcpy_fromio(p, fep->scc.ep, sizeof(scc_enet_t));
+
+ return 0;
+}
+
+static int get_regs_len(struct net_device *dev)
+{
+ return sizeof(scc_t) + sizeof(scc_enet_t);
+}
+
+static void tx_restart(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ scc_cr_cmd(fep, CPM_CR_RESTART_TX);
+}
+
+/*************************************************************************/
+
+const struct fs_ops fs_scc_ops = {
+ .setup_data = setup_data,
+ .cleanup_data = cleanup_data,
+ .set_multicast_list = set_multicast_list,
+ .restart = restart,
+ .stop = stop,
+ .pre_request_irq = pre_request_irq,
+ .post_free_irq = post_free_irq,
+ .napi_clear_rx_event = napi_clear_rx_event,
+ .napi_enable_rx = napi_enable_rx,
+ .napi_disable_rx = napi_disable_rx,
+ .rx_bd_done = rx_bd_done,
+ .tx_kickstart = tx_kickstart,
+ .get_int_events = get_int_events,
+ .clear_int_events = clear_int_events,
+ .ev_error = ev_error,
+ .get_regs = get_regs,
+ .get_regs_len = get_regs_len,
+ .tx_restart = tx_restart,
+ .allocate_bd = allocate_bd,
+ .free_bd = free_bd,
+};
diff --git a/drivers/net/fs_enet/mii-bitbang.c b/drivers/net/fs_enet/mii-bitbang.c
new file mode 100644
index 000000000000..24a5e2e23d18
--- /dev/null
+++ b/drivers/net/fs_enet/mii-bitbang.c
@@ -0,0 +1,405 @@
+/*
+ * Combined Ethernet driver for Motorola MPC8xx and MPC82xx.
+ *
+ * Copyright (c) 2003 Intracom S.A.
+ * by Pantelis Antoniou <panto@intracom.gr>
+ *
+ * 2005 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/bitops.h>
+
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#include "fs_enet.h"
+
+#ifdef CONFIG_8xx
+static int bitbang_prep_bit(u8 **dirp, u8 **datp, u8 *mskp, int port, int bit)
+{
+ immap_t *im = (immap_t *)fs_enet_immap;
+ void *dir, *dat, *ppar;
+ int adv;
+ u8 msk;
+
+ switch (port) {
+ case fsiop_porta:
+ dir = &im->im_ioport.iop_padir;
+ dat = &im->im_ioport.iop_padat;
+ ppar = &im->im_ioport.iop_papar;
+ break;
+
+ case fsiop_portb:
+ dir = &im->im_cpm.cp_pbdir;
+ dat = &im->im_cpm.cp_pbdat;
+ ppar = &im->im_cpm.cp_pbpar;
+ break;
+
+ case fsiop_portc:
+ dir = &im->im_ioport.iop_pcdir;
+ dat = &im->im_ioport.iop_pcdat;
+ ppar = &im->im_ioport.iop_pcpar;
+ break;
+
+ case fsiop_portd:
+ dir = &im->im_ioport.iop_pddir;
+ dat = &im->im_ioport.iop_pddat;
+ ppar = &im->im_ioport.iop_pdpar;
+ break;
+
+ case fsiop_porte:
+ dir = &im->im_cpm.cp_pedir;
+ dat = &im->im_cpm.cp_pedat;
+ ppar = &im->im_cpm.cp_pepar;
+ break;
+
+ default:
+ printk(KERN_ERR DRV_MODULE_NAME
+ "Illegal port value %d!\n", port);
+ return -EINVAL;
+ }
+
+ adv = bit >> 3;
+ dir = (char *)dir + adv;
+ dat = (char *)dat + adv;
+ ppar = (char *)ppar + adv;
+
+ msk = 1 << (7 - (bit & 7));
+ if ((in_8(ppar) & msk) != 0) {
+ printk(KERN_ERR DRV_MODULE_NAME
+ "pin %d on port %d is not general purpose!\n", bit, port);
+ return -EINVAL;
+ }
+
+ *dirp = dir;
+ *datp = dat;
+ *mskp = msk;
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_8260
+static int bitbang_prep_bit(u8 **dirp, u8 **datp, u8 *mskp, int port, int bit)
+{
+ iop_cpm2_t *io = &((cpm2_map_t *)fs_enet_immap)->im_ioport;
+ void *dir, *dat, *ppar;
+ int adv;
+ u8 msk;
+
+ switch (port) {
+ case fsiop_porta:
+ dir = &io->iop_pdira;
+ dat = &io->iop_pdata;
+ ppar = &io->iop_ppara;
+ break;
+
+ case fsiop_portb:
+ dir = &io->iop_pdirb;
+ dat = &io->iop_pdatb;
+ ppar = &io->iop_pparb;
+ break;
+
+ case fsiop_portc:
+ dir = &io->iop_pdirc;
+ dat = &io->iop_pdatc;
+ ppar = &io->iop_pparc;
+ break;
+
+ case fsiop_portd:
+ dir = &io->iop_pdird;
+ dat = &io->iop_pdatd;
+ ppar = &io->iop_ppard;
+ break;
+
+ default:
+ printk(KERN_ERR DRV_MODULE_NAME
+ "Illegal port value %d!\n", port);
+ return -EINVAL;
+ }
+
+ adv = bit >> 3;
+ dir = (char *)dir + adv;
+ dat = (char *)dat + adv;
+ ppar = (char *)ppar + adv;
+
+ msk = 1 << (7 - (bit & 7));
+ if ((in_8(ppar) & msk) != 0) {
+ printk(KERN_ERR DRV_MODULE_NAME
+ "pin %d on port %d is not general purpose!\n", bit, port);
+ return -EINVAL;
+ }
+
+ *dirp = dir;
+ *datp = dat;
+ *mskp = msk;
+
+ return 0;
+}
+#endif
+
+static inline void bb_set(u8 *p, u8 m)
+{
+ out_8(p, in_8(p) | m);
+}
+
+static inline void bb_clr(u8 *p, u8 m)
+{
+ out_8(p, in_8(p) & ~m);
+}
+
+static inline int bb_read(u8 *p, u8 m)
+{
+ return (in_8(p) & m) != 0;
+}
+
+static inline void mdio_active(struct fs_enet_mii_bus *bus)
+{
+ bb_set(bus->bitbang.mdio_dir, bus->bitbang.mdio_msk);
+}
+
+static inline void mdio_tristate(struct fs_enet_mii_bus *bus)
+{
+ bb_clr(bus->bitbang.mdio_dir, bus->bitbang.mdio_msk);
+}
+
+static inline int mdio_read(struct fs_enet_mii_bus *bus)
+{
+ return bb_read(bus->bitbang.mdio_dat, bus->bitbang.mdio_msk);
+}
+
+static inline void mdio(struct fs_enet_mii_bus *bus, int what)
+{
+ if (what)
+ bb_set(bus->bitbang.mdio_dat, bus->bitbang.mdio_msk);
+ else
+ bb_clr(bus->bitbang.mdio_dat, bus->bitbang.mdio_msk);
+}
+
+static inline void mdc(struct fs_enet_mii_bus *bus, int what)
+{
+ if (what)
+ bb_set(bus->bitbang.mdc_dat, bus->bitbang.mdc_msk);
+ else
+ bb_clr(bus->bitbang.mdc_dat, bus->bitbang.mdc_msk);
+}
+
+static inline void mii_delay(struct fs_enet_mii_bus *bus)
+{
+ udelay(bus->bus_info->i.bitbang.delay);
+}
+
+/* Utility to send the preamble, address, and register (common to read and write). */
+static void bitbang_pre(struct fs_enet_mii_bus *bus, int read, u8 addr, u8 reg)
+{
+ int j;
+
+ /*
+ * Send a 32 bit preamble ('1's) with an extra '1' bit for good measure.
+ * The IEEE spec says this is a PHY optional requirement. The AMD
+ * 79C874 requires one after power up and one after a MII communications
+ * error. This means that we are doing more preambles than we need,
+ * but it is safer and will be much more robust.
+ */
+
+ mdio_active(bus);
+ mdio(bus, 1);
+ for (j = 0; j < 32; j++) {
+ mdc(bus, 0);
+ mii_delay(bus);
+ mdc(bus, 1);
+ mii_delay(bus);
+ }
+
+ /* send the start bit (01) and the read opcode (10) or write (10) */
+ mdc(bus, 0);
+ mdio(bus, 0);
+ mii_delay(bus);
+ mdc(bus, 1);
+ mii_delay(bus);
+ mdc(bus, 0);
+ mdio(bus, 1);
+ mii_delay(bus);
+ mdc(bus, 1);
+ mii_delay(bus);
+ mdc(bus, 0);
+ mdio(bus, read);
+ mii_delay(bus);
+ mdc(bus, 1);
+ mii_delay(bus);
+ mdc(bus, 0);
+ mdio(bus, !read);
+ mii_delay(bus);
+ mdc(bus, 1);
+ mii_delay(bus);
+
+ /* send the PHY address */
+ for (j = 0; j < 5; j++) {
+ mdc(bus, 0);
+ mdio(bus, (addr & 0x10) != 0);
+ mii_delay(bus);
+ mdc(bus, 1);
+ mii_delay(bus);
+ addr <<= 1;
+ }
+
+ /* send the register address */
+ for (j = 0; j < 5; j++) {
+ mdc(bus, 0);
+ mdio(bus, (reg & 0x10) != 0);
+ mii_delay(bus);
+ mdc(bus, 1);
+ mii_delay(bus);
+ reg <<= 1;
+ }
+}
+
+static int mii_read(struct fs_enet_mii_bus *bus, int phy_id, int location)
+{
+ u16 rdreg;
+ int ret, j;
+ u8 addr = phy_id & 0xff;
+ u8 reg = location & 0xff;
+
+ bitbang_pre(bus, 1, addr, reg);
+
+ /* tri-state our MDIO I/O pin so we can read */
+ mdc(bus, 0);
+ mdio_tristate(bus);
+ mii_delay(bus);
+ mdc(bus, 1);
+ mii_delay(bus);
+
+ /* check the turnaround bit: the PHY should be driving it to zero */
+ if (mdio_read(bus) != 0) {
+ /* PHY didn't drive TA low */
+ for (j = 0; j < 32; j++) {
+ mdc(bus, 0);
+ mii_delay(bus);
+ mdc(bus, 1);
+ mii_delay(bus);
+ }
+ ret = -1;
+ goto out;
+ }
+
+ mdc(bus, 0);
+ mii_delay(bus);
+
+ /* read 16 bits of register data, MSB first */
+ rdreg = 0;
+ for (j = 0; j < 16; j++) {
+ mdc(bus, 1);
+ mii_delay(bus);
+ rdreg <<= 1;
+ rdreg |= mdio_read(bus);
+ mdc(bus, 0);
+ mii_delay(bus);
+ }
+
+ mdc(bus, 1);
+ mii_delay(bus);
+ mdc(bus, 0);
+ mii_delay(bus);
+ mdc(bus, 1);
+ mii_delay(bus);
+
+ ret = rdreg;
+out:
+ return ret;
+}
+
+static void mii_write(struct fs_enet_mii_bus *bus, int phy_id, int location, int val)
+{
+ int j;
+ u8 addr = phy_id & 0xff;
+ u8 reg = location & 0xff;
+ u16 value = val & 0xffff;
+
+ bitbang_pre(bus, 0, addr, reg);
+
+ /* send the turnaround (10) */
+ mdc(bus, 0);
+ mdio(bus, 1);
+ mii_delay(bus);
+ mdc(bus, 1);
+ mii_delay(bus);
+ mdc(bus, 0);
+ mdio(bus, 0);
+ mii_delay(bus);
+ mdc(bus, 1);
+ mii_delay(bus);
+
+ /* write 16 bits of register data, MSB first */
+ for (j = 0; j < 16; j++) {
+ mdc(bus, 0);
+ mdio(bus, (value & 0x8000) != 0);
+ mii_delay(bus);
+ mdc(bus, 1);
+ mii_delay(bus);
+ value <<= 1;
+ }
+
+ /*
+ * Tri-state the MDIO line.
+ */
+ mdio_tristate(bus);
+ mdc(bus, 0);
+ mii_delay(bus);
+ mdc(bus, 1);
+ mii_delay(bus);
+}
+
+int fs_mii_bitbang_init(struct fs_enet_mii_bus *bus)
+{
+ const struct fs_mii_bus_info *bi = bus->bus_info;
+ int r;
+
+ r = bitbang_prep_bit(&bus->bitbang.mdio_dir,
+ &bus->bitbang.mdio_dat,
+ &bus->bitbang.mdio_msk,
+ bi->i.bitbang.mdio_port,
+ bi->i.bitbang.mdio_bit);
+ if (r != 0)
+ return r;
+
+ r = bitbang_prep_bit(&bus->bitbang.mdc_dir,
+ &bus->bitbang.mdc_dat,
+ &bus->bitbang.mdc_msk,
+ bi->i.bitbang.mdc_port,
+ bi->i.bitbang.mdc_bit);
+ if (r != 0)
+ return r;
+
+ bus->mii_read = mii_read;
+ bus->mii_write = mii_write;
+
+ return 0;
+}
diff --git a/drivers/net/fs_enet/mii-fixed.c b/drivers/net/fs_enet/mii-fixed.c
new file mode 100644
index 000000000000..b3e192d612e5
--- /dev/null
+++ b/drivers/net/fs_enet/mii-fixed.c
@@ -0,0 +1,92 @@
+/*
+ * Combined Ethernet driver for Motorola MPC8xx and MPC82xx.
+ *
+ * Copyright (c) 2003 Intracom S.A.
+ * by Pantelis Antoniou <panto@intracom.gr>
+ *
+ * 2005 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/bitops.h>
+
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#include "fs_enet.h"
+
+static const u16 mii_regs[7] = {
+ 0x3100,
+ 0x786d,
+ 0x0fff,
+ 0x0fff,
+ 0x01e1,
+ 0x45e1,
+ 0x0003,
+};
+
+static int mii_read(struct fs_enet_mii_bus *bus, int phy_id, int location)
+{
+ int ret = 0;
+
+ if ((unsigned int)location >= ARRAY_SIZE(mii_regs))
+ return -1;
+
+ if (location != 5)
+ ret = mii_regs[location];
+ else
+ ret = bus->fixed.lpa;
+
+ return ret;
+}
+
+static void mii_write(struct fs_enet_mii_bus *bus, int phy_id, int location, int val)
+{
+ /* do nothing */
+}
+
+int fs_mii_fixed_init(struct fs_enet_mii_bus *bus)
+{
+ const struct fs_mii_bus_info *bi = bus->bus_info;
+
+ bus->fixed.lpa = 0x45e1; /* default 100Mb, full duplex */
+
+ /* if speed is fixed at 10Mb, remove 100Mb modes */
+ if (bi->i.fixed.speed == 10)
+ bus->fixed.lpa &= ~LPA_100;
+
+ /* if duplex is half, remove full duplex modes */
+ if (bi->i.fixed.duplex == 0)
+ bus->fixed.lpa &= ~LPA_DUPLEX;
+
+ bus->mii_read = mii_read;
+ bus->mii_write = mii_write;
+
+ return 0;
+}
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index 85d6dc005be0..3e9accf137e7 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -390,10 +390,8 @@ static void ax_changedmtu(struct mkiss *ax)
"MTU change cancelled.\n",
ax->dev->name);
dev->mtu = ax->mtu;
- if (xbuff != NULL)
- kfree(xbuff);
- if (rbuff != NULL)
- kfree(rbuff);
+ kfree(xbuff);
+ kfree(rbuff);
return;
}
diff --git a/drivers/net/ibm_emac/Makefile b/drivers/net/ibm_emac/Makefile
index 7f583a333c24..f98ddf0e807a 100644
--- a/drivers/net/ibm_emac/Makefile
+++ b/drivers/net/ibm_emac/Makefile
@@ -1,12 +1,11 @@
#
-# Makefile for the IBM PPC4xx EMAC controllers
+# Makefile for the PowerPC 4xx on-chip ethernet driver
#
obj-$(CONFIG_IBM_EMAC) += ibm_emac.o
-ibm_emac-objs := ibm_emac_mal.o ibm_emac_core.o ibm_emac_phy.o
-
-# Only need this if you want to see additional debug messages
-ifeq ($(CONFIG_IBM_EMAC_ERRMSG), y)
-ibm_emac-objs += ibm_emac_debug.o
-endif
+ibm_emac-objs := ibm_emac_mal.o ibm_emac_core.o ibm_emac_phy.o
+ibm_emac-$(CONFIG_IBM_EMAC_ZMII) += ibm_emac_zmii.o
+ibm_emac-$(CONFIG_IBM_EMAC_RGMII) += ibm_emac_rgmii.o
+ibm_emac-$(CONFIG_IBM_EMAC_TAH) += ibm_emac_tah.o
+ibm_emac-$(CONFIG_IBM_EMAC_DEBUG) += ibm_emac_debug.o
diff --git a/drivers/net/ibm_emac/ibm_emac.h b/drivers/net/ibm_emac/ibm_emac.h
index 15d5a0e82862..28c476f28c20 100644
--- a/drivers/net/ibm_emac/ibm_emac.h
+++ b/drivers/net/ibm_emac/ibm_emac.h
@@ -1,110 +1,142 @@
/*
- * ibm_emac.h
+ * drivers/net/ibm_emac/ibm_emac.h
*
+ * Register definitions for PowerPC 4xx on-chip ethernet contoller
*
- * Armin Kuster akuster@mvista.com
- * June, 2002
+ * Copyright (c) 2004, 2005 Zultys Technologies.
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
*
- * Copyright 2002 MontaVista Softare Inc.
+ * Based on original work by
+ * Matt Porter <mporter@kernel.crashing.org>
+ * Armin Kuster <akuster@mvista.com>
+ * Copyright 2002-2004 MontaVista Software 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.
+ *
*/
+#ifndef __IBM_EMAC_H_
+#define __IBM_EMAC_H_
+
+#include <linux/config.h>
+#include <linux/types.h>
+
+/* This is a simple check to prevent use of this driver on non-tested SoCs */
+#if !defined(CONFIG_405GP) && !defined(CONFIG_405GPR) && !defined(CONFIG_405EP) && \
+ !defined(CONFIG_440GP) && !defined(CONFIG_440GX) && !defined(CONFIG_440SP) && \
+ !defined(CONFIG_440EP) && !defined(CONFIG_NP405H)
+#error "Unknown SoC. Please, check chip user manual and make sure EMAC defines are OK"
+#endif
+
+/* EMAC registers Write Access rules */
+struct emac_regs {
+ u32 mr0; /* special */
+ u32 mr1; /* Reset */
+ u32 tmr0; /* special */
+ u32 tmr1; /* special */
+ u32 rmr; /* Reset */
+ u32 isr; /* Always */
+ u32 iser; /* Reset */
+ u32 iahr; /* Reset, R, T */
+ u32 ialr; /* Reset, R, T */
+ u32 vtpid; /* Reset, R, T */
+ u32 vtci; /* Reset, R, T */
+ u32 ptr; /* Reset, T */
+ u32 iaht1; /* Reset, R */
+ u32 iaht2; /* Reset, R */
+ u32 iaht3; /* Reset, R */
+ u32 iaht4; /* Reset, R */
+ u32 gaht1; /* Reset, R */
+ u32 gaht2; /* Reset, R */
+ u32 gaht3; /* Reset, R */
+ u32 gaht4; /* Reset, R */
+ u32 lsah;
+ u32 lsal;
+ u32 ipgvr; /* Reset, T */
+ u32 stacr; /* special */
+ u32 trtr; /* special */
+ u32 rwmr; /* Reset */
+ u32 octx;
+ u32 ocrx;
+ u32 ipcr;
+};
+
+#if !defined(CONFIG_IBM_EMAC4)
+#define EMAC_ETHTOOL_REGS_VER 0
+#define EMAC_ETHTOOL_REGS_SIZE (sizeof(struct emac_regs) - sizeof(u32))
+#else
+#define EMAC_ETHTOOL_REGS_VER 1
+#define EMAC_ETHTOOL_REGS_SIZE sizeof(struct emac_regs)
+#endif
-#ifndef _IBM_EMAC_H_
-#define _IBM_EMAC_H_
-/* General defines needed for the driver */
+/* EMACx_MR0 */
+#define EMAC_MR0_RXI 0x80000000
+#define EMAC_MR0_TXI 0x40000000
+#define EMAC_MR0_SRST 0x20000000
+#define EMAC_MR0_TXE 0x10000000
+#define EMAC_MR0_RXE 0x08000000
+#define EMAC_MR0_WKE 0x04000000
-/* Emac */
-typedef struct emac_regs {
- u32 em0mr0;
- u32 em0mr1;
- u32 em0tmr0;
- u32 em0tmr1;
- u32 em0rmr;
- u32 em0isr;
- u32 em0iser;
- u32 em0iahr;
- u32 em0ialr;
- u32 em0vtpid;
- u32 em0vtci;
- u32 em0ptr;
- u32 em0iaht1;
- u32 em0iaht2;
- u32 em0iaht3;
- u32 em0iaht4;
- u32 em0gaht1;
- u32 em0gaht2;
- u32 em0gaht3;
- u32 em0gaht4;
- u32 em0lsah;
- u32 em0lsal;
- u32 em0ipgvr;
- u32 em0stacr;
- u32 em0trtr;
- u32 em0rwmr;
-} emac_t;
+/* EMACx_MR1 */
+#define EMAC_MR1_FDE 0x80000000
+#define EMAC_MR1_ILE 0x40000000
+#define EMAC_MR1_VLE 0x20000000
+#define EMAC_MR1_EIFC 0x10000000
+#define EMAC_MR1_APP 0x08000000
+#define EMAC_MR1_IST 0x01000000
-/* MODE REG 0 */
-#define EMAC_M0_RXI 0x80000000
-#define EMAC_M0_TXI 0x40000000
-#define EMAC_M0_SRST 0x20000000
-#define EMAC_M0_TXE 0x10000000
-#define EMAC_M0_RXE 0x08000000
-#define EMAC_M0_WKE 0x04000000
+#define EMAC_MR1_MF_MASK 0x00c00000
+#define EMAC_MR1_MF_10 0x00000000
+#define EMAC_MR1_MF_100 0x00400000
+#if !defined(CONFIG_IBM_EMAC4)
+#define EMAC_MR1_MF_1000 0x00000000
+#define EMAC_MR1_MF_1000GPCS 0x00000000
+#define EMAC_MR1_MF_IPPA(id) 0x00000000
+#else
+#define EMAC_MR1_MF_1000 0x00800000
+#define EMAC_MR1_MF_1000GPCS 0x00c00000
+#define EMAC_MR1_MF_IPPA(id) (((id) & 0x1f) << 6)
+#endif
-/* MODE Reg 1 */
-#define EMAC_M1_FDE 0x80000000
-#define EMAC_M1_ILE 0x40000000
-#define EMAC_M1_VLE 0x20000000
-#define EMAC_M1_EIFC 0x10000000
-#define EMAC_M1_APP 0x08000000
-#define EMAC_M1_AEMI 0x02000000
-#define EMAC_M1_IST 0x01000000
-#define EMAC_M1_MF_1000GPCS 0x00c00000 /* Internal GPCS */
-#define EMAC_M1_MF_1000MBPS 0x00800000 /* External GPCS */
-#define EMAC_M1_MF_100MBPS 0x00400000
-#define EMAC_M1_RFS_16K 0x00280000 /* 000 for 512 byte */
-#define EMAC_M1_TR 0x00008000
-#ifdef CONFIG_IBM_EMAC4
-#define EMAC_M1_RFS_8K 0x00200000
-#define EMAC_M1_RFS_4K 0x00180000
-#define EMAC_M1_RFS_2K 0x00100000
-#define EMAC_M1_RFS_1K 0x00080000
-#define EMAC_M1_TX_FIFO_16K 0x00050000 /* 0's for 512 byte */
-#define EMAC_M1_TX_FIFO_8K 0x00040000
-#define EMAC_M1_TX_FIFO_4K 0x00030000
-#define EMAC_M1_TX_FIFO_2K 0x00020000
-#define EMAC_M1_TX_FIFO_1K 0x00010000
-#define EMAC_M1_TX_TR 0x00008000
-#define EMAC_M1_TX_MWSW 0x00001000 /* 0 wait for status */
-#define EMAC_M1_JUMBO_ENABLE 0x00000800 /* Upt to 9Kr status */
-#define EMAC_M1_OPB_CLK_66 0x00000008 /* 66Mhz */
-#define EMAC_M1_OPB_CLK_83 0x00000010 /* 83Mhz */
-#define EMAC_M1_OPB_CLK_100 0x00000018 /* 100Mhz */
-#define EMAC_M1_OPB_CLK_100P 0x00000020 /* 100Mhz+ */
-#else /* CONFIG_IBM_EMAC4 */
-#define EMAC_M1_RFS_4K 0x00300000 /* ~4k for 512 byte */
-#define EMAC_M1_RFS_2K 0x00200000
-#define EMAC_M1_RFS_1K 0x00100000
-#define EMAC_M1_TX_FIFO_2K 0x00080000 /* 0's for 512 byte */
-#define EMAC_M1_TX_FIFO_1K 0x00040000
-#define EMAC_M1_TR0_DEPEND 0x00010000 /* 0'x for single packet */
-#define EMAC_M1_TR1_DEPEND 0x00004000
-#define EMAC_M1_TR1_MULTI 0x00002000
-#define EMAC_M1_JUMBO_ENABLE 0x00001000
-#endif /* CONFIG_IBM_EMAC4 */
-#define EMAC_M1_BASE (EMAC_M1_TX_FIFO_2K | \
- EMAC_M1_APP | \
- EMAC_M1_TR | EMAC_M1_VLE)
+#define EMAC_TX_FIFO_SIZE 2048
-/* Transmit Mode Register 0 */
-#define EMAC_TMR0_GNP0 0x80000000
-#define EMAC_TMR0_GNP1 0x40000000
-#define EMAC_TMR0_GNPD 0x20000000
-#define EMAC_TMR0_FC 0x10000000
+#if !defined(CONFIG_IBM_EMAC4)
+#define EMAC_MR1_RFS_4K 0x00300000
+#define EMAC_MR1_RFS_16K 0x00000000
+#define EMAC_RX_FIFO_SIZE(gige) 4096
+#define EMAC_MR1_TFS_2K 0x00080000
+#define EMAC_MR1_TR0_MULT 0x00008000
+#define EMAC_MR1_JPSM 0x00000000
+#define EMAC_MR1_BASE(opb) (EMAC_MR1_TFS_2K | EMAC_MR1_TR0_MULT)
+#else
+#define EMAC_MR1_RFS_4K 0x00180000
+#define EMAC_MR1_RFS_16K 0x00280000
+#define EMAC_RX_FIFO_SIZE(gige) ((gige) ? 16384 : 4096)
+#define EMAC_MR1_TFS_2K 0x00020000
+#define EMAC_MR1_TR 0x00008000
+#define EMAC_MR1_MWSW_001 0x00001000
+#define EMAC_MR1_JPSM 0x00000800
+#define EMAC_MR1_OBCI_MASK 0x00000038
+#define EMAC_MR1_OBCI_50 0x00000000
+#define EMAC_MR1_OBCI_66 0x00000008
+#define EMAC_MR1_OBCI_83 0x00000010
+#define EMAC_MR1_OBCI_100 0x00000018
+#define EMAC_MR1_OBCI_100P 0x00000020
+#define EMAC_MR1_OBCI(freq) ((freq) <= 50 ? EMAC_MR1_OBCI_50 : \
+ (freq) <= 66 ? EMAC_MR1_OBCI_66 : \
+ (freq) <= 83 ? EMAC_MR1_OBCI_83 : \
+ (freq) <= 100 ? EMAC_MR1_OBCI_100 : EMAC_MR1_OBCI_100P)
+#define EMAC_MR1_BASE(opb) (EMAC_MR1_TFS_2K | EMAC_MR1_TR | \
+ EMAC_MR1_MWSW_001 | EMAC_MR1_OBCI(opb))
+#endif
+
+/* EMACx_TMR0 */
+#define EMAC_TMR0_GNP 0x80000000
+#if !defined(CONFIG_IBM_EMAC4)
+#define EMAC_TMR0_DEFAULT 0x00000000
+#else
#define EMAC_TMR0_TFAE_2_32 0x00000001
#define EMAC_TMR0_TFAE_4_64 0x00000002
#define EMAC_TMR0_TFAE_8_128 0x00000003
@@ -112,14 +144,36 @@ typedef struct emac_regs {
#define EMAC_TMR0_TFAE_32_512 0x00000005
#define EMAC_TMR0_TFAE_64_1024 0x00000006
#define EMAC_TMR0_TFAE_128_2048 0x00000007
+#define EMAC_TMR0_DEFAULT EMAC_TMR0_TFAE_2_32
+#endif
+#define EMAC_TMR0_XMIT (EMAC_TMR0_GNP | EMAC_TMR0_DEFAULT)
+
+/* EMACx_TMR1 */
+
+/* IBM manuals are not very clear here.
+ * This is my interpretation of how things are. --ebs
+ */
+#if defined(CONFIG_40x)
+#define EMAC_FIFO_ENTRY_SIZE 8
+#define EMAC_MAL_BURST_SIZE (16 * 4)
+#else
+#define EMAC_FIFO_ENTRY_SIZE 16
+#define EMAC_MAL_BURST_SIZE (64 * 4)
+#endif
+
+#if !defined(CONFIG_IBM_EMAC4)
+#define EMAC_TMR1(l,h) (((l) << 27) | (((h) & 0xff) << 16))
+#else
+#define EMAC_TMR1(l,h) (((l) << 27) | (((h) & 0x3ff) << 14))
+#endif
-/* Receive Mode Register */
+/* EMACx_RMR */
#define EMAC_RMR_SP 0x80000000
#define EMAC_RMR_SFCS 0x40000000
-#define EMAC_RMR_ARRP 0x20000000
-#define EMAC_RMR_ARP 0x10000000
-#define EMAC_RMR_AROP 0x08000000
-#define EMAC_RMR_ARPI 0x04000000
+#define EMAC_RMR_RRP 0x20000000
+#define EMAC_RMR_RFP 0x10000000
+#define EMAC_RMR_ROP 0x08000000
+#define EMAC_RMR_RPIR 0x04000000
#define EMAC_RMR_PPP 0x02000000
#define EMAC_RMR_PME 0x01000000
#define EMAC_RMR_PMME 0x00800000
@@ -127,6 +181,9 @@ typedef struct emac_regs {
#define EMAC_RMR_MIAE 0x00200000
#define EMAC_RMR_BAE 0x00100000
#define EMAC_RMR_MAE 0x00080000
+#if !defined(CONFIG_IBM_EMAC4)
+#define EMAC_RMR_BASE 0x00000000
+#else
#define EMAC_RMR_RFAF_2_32 0x00000001
#define EMAC_RMR_RFAF_4_64 0x00000002
#define EMAC_RMR_RFAF_8_128 0x00000003
@@ -134,9 +191,21 @@ typedef struct emac_regs {
#define EMAC_RMR_RFAF_32_512 0x00000005
#define EMAC_RMR_RFAF_64_1024 0x00000006
#define EMAC_RMR_RFAF_128_2048 0x00000007
-#define EMAC_RMR_BASE (EMAC_RMR_IAE | EMAC_RMR_BAE)
+#define EMAC_RMR_BASE EMAC_RMR_RFAF_128_2048
+#endif
-/* Interrupt Status & enable Regs */
+/* EMACx_ISR & EMACx_ISER */
+#if !defined(CONFIG_IBM_EMAC4)
+#define EMAC_ISR_TXPE 0x00000000
+#define EMAC_ISR_RXPE 0x00000000
+#define EMAC_ISR_TXUE 0x00000000
+#define EMAC_ISR_RXOE 0x00000000
+#else
+#define EMAC_ISR_TXPE 0x20000000
+#define EMAC_ISR_RXPE 0x10000000
+#define EMAC_ISR_TXUE 0x08000000
+#define EMAC_ISR_RXOE 0x04000000
+#endif
#define EMAC_ISR_OVR 0x02000000
#define EMAC_ISR_PP 0x01000000
#define EMAC_ISR_BP 0x00800000
@@ -147,53 +216,62 @@ typedef struct emac_regs {
#define EMAC_ISR_PTLE 0x00040000
#define EMAC_ISR_ORE 0x00020000
#define EMAC_ISR_IRE 0x00010000
-#define EMAC_ISR_DBDM 0x00000200
-#define EMAC_ISR_DB0 0x00000100
-#define EMAC_ISR_SE0 0x00000080
-#define EMAC_ISR_TE0 0x00000040
-#define EMAC_ISR_DB1 0x00000020
-#define EMAC_ISR_SE1 0x00000010
-#define EMAC_ISR_TE1 0x00000008
+#define EMAC_ISR_SQE 0x00000080
+#define EMAC_ISR_TE 0x00000040
#define EMAC_ISR_MOS 0x00000002
#define EMAC_ISR_MOF 0x00000001
-/* STA CONTROL REG */
+/* EMACx_STACR */
+#define EMAC_STACR_PHYD_MASK 0xffff
+#define EMAC_STACR_PHYD_SHIFT 16
#define EMAC_STACR_OC 0x00008000
#define EMAC_STACR_PHYE 0x00004000
-#define EMAC_STACR_WRITE 0x00002000
-#define EMAC_STACR_READ 0x00001000
-#define EMAC_STACR_CLK_83MHZ 0x00000800 /* 0's for 50Mhz */
-#define EMAC_STACR_CLK_66MHZ 0x00000400
-#define EMAC_STACR_CLK_100MHZ 0x00000C00
+#define EMAC_STACR_STAC_MASK 0x00003000
+#define EMAC_STACR_STAC_READ 0x00001000
+#define EMAC_STACR_STAC_WRITE 0x00002000
+#if !defined(CONFIG_IBM_EMAC4)
+#define EMAC_STACR_OPBC_MASK 0x00000C00
+#define EMAC_STACR_OPBC_50 0x00000000
+#define EMAC_STACR_OPBC_66 0x00000400
+#define EMAC_STACR_OPBC_83 0x00000800
+#define EMAC_STACR_OPBC_100 0x00000C00
+#define EMAC_STACR_OPBC(freq) ((freq) <= 50 ? EMAC_STACR_OPBC_50 : \
+ (freq) <= 66 ? EMAC_STACR_OPBC_66 : \
+ (freq) <= 83 ? EMAC_STACR_OPBC_83 : EMAC_STACR_OPBC_100)
+#define EMAC_STACR_BASE(opb) EMAC_STACR_OPBC(opb)
+#else
+#define EMAC_STACR_BASE(opb) 0x00000000
+#endif
+#define EMAC_STACR_PCDA_MASK 0x1f
+#define EMAC_STACR_PCDA_SHIFT 5
+#define EMAC_STACR_PRA_MASK 0x1f
+
+/* EMACx_TRTR */
+#if !defined(CONFIG_IBM_EMAC4)
+#define EMAC_TRTR_SHIFT 27
+#else
+#define EMAC_TRTR_SHIFT 24
+#endif
+#define EMAC_TRTR(size) ((((size) >> 6) - 1) << EMAC_TRTR_SHIFT)
-/* Transmit Request Threshold Register */
-#define EMAC_TRTR_1600 0x18000000 /* 0's for 64 Bytes */
-#define EMAC_TRTR_1024 0x0f000000
-#define EMAC_TRTR_512 0x07000000
-#define EMAC_TRTR_256 0x03000000
-#define EMAC_TRTR_192 0x10000000
-#define EMAC_TRTR_128 0x01000000
+/* EMACx_RWMR */
+#if !defined(CONFIG_IBM_EMAC4)
+#define EMAC_RWMR(l,h) (((l) << 23) | ( ((h) & 0x1ff) << 7))
+#else
+#define EMAC_RWMR(l,h) (((l) << 22) | ( ((h) & 0x3ff) << 6))
+#endif
+/* EMAC specific TX descriptor control fields (write access) */
#define EMAC_TX_CTRL_GFCS 0x0200
#define EMAC_TX_CTRL_GP 0x0100
#define EMAC_TX_CTRL_ISA 0x0080
#define EMAC_TX_CTRL_RSA 0x0040
#define EMAC_TX_CTRL_IVT 0x0020
#define EMAC_TX_CTRL_RVT 0x0010
-#define EMAC_TX_CTRL_TAH_CSUM 0x000e /* TAH only */
-#define EMAC_TX_CTRL_TAH_SEG4 0x000a /* TAH only */
-#define EMAC_TX_CTRL_TAH_SEG3 0x0008 /* TAH only */
-#define EMAC_TX_CTRL_TAH_SEG2 0x0006 /* TAH only */
-#define EMAC_TX_CTRL_TAH_SEG1 0x0004 /* TAH only */
-#define EMAC_TX_CTRL_TAH_SEG0 0x0002 /* TAH only */
-#define EMAC_TX_CTRL_TAH_DIS 0x0000 /* TAH only */
+#define EMAC_TX_CTRL_TAH_CSUM 0x000e
-#define EMAC_TX_CTRL_DFLT ( \
- MAL_TX_CTRL_INTR | EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP )
-
-/* madmal transmit status / Control bits */
+/* EMAC specific TX descriptor status fields (read access) */
#define EMAC_TX_ST_BFCS 0x0200
-#define EMAC_TX_ST_BPP 0x0100
#define EMAC_TX_ST_LCS 0x0080
#define EMAC_TX_ST_ED 0x0040
#define EMAC_TX_ST_EC 0x0020
@@ -202,8 +280,16 @@ typedef struct emac_regs {
#define EMAC_TX_ST_SC 0x0004
#define EMAC_TX_ST_UR 0x0002
#define EMAC_TX_ST_SQE 0x0001
+#if !defined(CONFIG_IBM_EMAC_TAH)
+#define EMAC_IS_BAD_TX(v) ((v) & (EMAC_TX_ST_LCS | EMAC_TX_ST_ED | \
+ EMAC_TX_ST_EC | EMAC_TX_ST_LC | \
+ EMAC_TX_ST_MC | EMAC_TX_ST_UR))
+#else
+#define EMAC_IS_BAD_TX(v) ((v) & (EMAC_TX_ST_LCS | EMAC_TX_ST_ED | \
+ EMAC_TX_ST_EC | EMAC_TX_ST_LC))
+#endif
-/* madmal receive status / Control bits */
+/* EMAC specific RX descriptor status fields (read access) */
#define EMAC_RX_ST_OE 0x0200
#define EMAC_RX_ST_PP 0x0100
#define EMAC_RX_ST_BP 0x0080
@@ -214,54 +300,10 @@ typedef struct emac_regs {
#define EMAC_RX_ST_PTL 0x0004
#define EMAC_RX_ST_ORE 0x0002
#define EMAC_RX_ST_IRE 0x0001
-#define EMAC_BAD_RX_PACKET 0x02ff
-#define EMAC_CSUM_VER_ERROR 0x0003
-
-/* identify a bad rx packet dependent on emac features */
-#ifdef CONFIG_IBM_EMAC4
-#define EMAC_IS_BAD_RX_PACKET(desc) \
- (((desc & (EMAC_BAD_RX_PACKET & ~EMAC_CSUM_VER_ERROR)) || \
- ((desc & EMAC_CSUM_VER_ERROR) == EMAC_RX_ST_ORE) || \
- ((desc & EMAC_CSUM_VER_ERROR) == EMAC_RX_ST_IRE)))
-#else
-#define EMAC_IS_BAD_RX_PACKET(desc) \
- (desc & EMAC_BAD_RX_PACKET)
-#endif
-
-/* SoC implementation specific EMAC register defaults */
-#if defined(CONFIG_440GP)
-#define EMAC_RWMR_DEFAULT 0x80009000
-#define EMAC_TMR0_DEFAULT 0x00000000
-#define EMAC_TMR1_DEFAULT 0xf8640000
-#elif defined(CONFIG_440GX)
-#define EMAC_RWMR_DEFAULT 0x1000a200
-#define EMAC_TMR0_DEFAULT EMAC_TMR0_TFAE_2_32
-#define EMAC_TMR1_DEFAULT 0xa00f0000
-#elif defined(CONFIG_440SP)
-#define EMAC_RWMR_DEFAULT 0x08002000
-#define EMAC_TMR0_DEFAULT EMAC_TMR0_TFAE_128_2048
-#define EMAC_TMR1_DEFAULT 0xf8200000
-#else
-#define EMAC_RWMR_DEFAULT 0x0f002000
-#define EMAC_TMR0_DEFAULT 0x00000000
-#define EMAC_TMR1_DEFAULT 0x380f0000
-#endif /* CONFIG_440GP */
-
-/* Revision specific EMAC register defaults */
-#ifdef CONFIG_IBM_EMAC4
-#define EMAC_M1_DEFAULT (EMAC_M1_BASE | \
- EMAC_M1_OPB_CLK_83 | \
- EMAC_M1_TX_MWSW)
-#define EMAC_RMR_DEFAULT (EMAC_RMR_BASE | \
- EMAC_RMR_RFAF_128_2048)
-#define EMAC_TMR0_XMIT (EMAC_TMR0_GNP0 | \
- EMAC_TMR0_DEFAULT)
-#define EMAC_TRTR_DEFAULT EMAC_TRTR_1024
-#else /* !CONFIG_IBM_EMAC4 */
-#define EMAC_M1_DEFAULT EMAC_M1_BASE
-#define EMAC_RMR_DEFAULT EMAC_RMR_BASE
-#define EMAC_TMR0_XMIT EMAC_TMR0_GNP0
-#define EMAC_TRTR_DEFAULT EMAC_TRTR_1600
-#endif /* CONFIG_IBM_EMAC4 */
-
-#endif
+#define EMAC_RX_TAH_BAD_CSUM 0x0003
+#define EMAC_BAD_RX_MASK (EMAC_RX_ST_OE | EMAC_RX_ST_BP | \
+ EMAC_RX_ST_RP | EMAC_RX_ST_SE | \
+ EMAC_RX_ST_AE | EMAC_RX_ST_BFCS | \
+ EMAC_RX_ST_PTL | EMAC_RX_ST_ORE | \
+ EMAC_RX_ST_IRE )
+#endif /* __IBM_EMAC_H_ */
diff --git a/drivers/net/ibm_emac/ibm_emac_core.c b/drivers/net/ibm_emac/ibm_emac_core.c
index 14e9b6315f20..943fbd1546ff 100644
--- a/drivers/net/ibm_emac/ibm_emac_core.c
+++ b/drivers/net/ibm_emac/ibm_emac_core.c
@@ -1,13 +1,14 @@
/*
- * ibm_emac_core.c
+ * drivers/net/ibm_emac/ibm_emac_core.c
*
- * Ethernet driver for the built in ethernet on the IBM 4xx PowerPC
- * processors.
- *
- * (c) 2003 Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ * Driver for PowerPC 4xx on-chip ethernet controller.
*
- * Based on original work by
+ * Copyright (c) 2004, 2005 Zultys Technologies.
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
*
+ * Based on original work by
+ * Matt Porter <mporter@kernel.crashing.org>
+ * (c) 2003 Benjamin Herrenschmidt <benh@kernel.crashing.org>
* Armin Kuster <akuster@mvista.com>
* Johnnie Peters <jpeters@mvista.com>
*
@@ -15,29 +16,24 @@
* 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.
- * TODO
- * - Check for races in the "remove" code path
- * - Add some Power Management to the MAC and the PHY
- * - Audit remaining of non-rewritten code (--BenH)
- * - Cleanup message display using msglevel mecanism
- * - Address all errata
- * - Audit all register update paths to ensure they
- * are being written post soft reset if required.
+ *
*/
+
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/ptrace.h>
#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/types.h>
-#include <linux/dma-mapping.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/crc32.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/bitops.h>
@@ -45,1691 +41,1893 @@
#include <asm/processor.h>
#include <asm/io.h>
#include <asm/dma.h>
-#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/ocp.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/crc32.h>
-
#include "ibm_emac_core.h"
-
-//#define MDIO_DEBUG(fmt) printk fmt
-#define MDIO_DEBUG(fmt)
-
-//#define LINK_DEBUG(fmt) printk fmt
-#define LINK_DEBUG(fmt)
-
-//#define PKT_DEBUG(fmt) printk fmt
-#define PKT_DEBUG(fmt)
-
-#define DRV_NAME "emac"
-#define DRV_VERSION "2.0"
-#define DRV_AUTHOR "Benjamin Herrenschmidt <benh@kernel.crashing.org>"
-#define DRV_DESC "IBM EMAC Ethernet driver"
+#include "ibm_emac_debug.h"
/*
- * When mdio_idx >= 0, contains a list of emac ocp_devs
- * that have had their initialization deferred until the
- * common MDIO controller has been initialized.
+ * Lack of dma_unmap_???? calls is intentional.
+ *
+ * API-correct usage requires additional support state information to be
+ * maintained for every RX and TX buffer descriptor (BD). Unfortunately, due to
+ * EMAC design (e.g. TX buffer passed from network stack can be split into
+ * several BDs, dma_map_single/dma_map_page can be used to map particular BD),
+ * maintaining such information will add additional overhead.
+ * Current DMA API implementation for 4xx processors only ensures cache coherency
+ * and dma_unmap_???? routines are empty and are likely to stay this way.
+ * I decided to omit dma_unmap_??? calls because I don't want to add additional
+ * complexity just for the sake of following some abstract API, when it doesn't
+ * add any real benefit to the driver. I understand that this decision maybe
+ * controversial, but I really tried to make code API-correct and efficient
+ * at the same time and didn't come up with code I liked :(. --ebs
*/
-LIST_HEAD(emac_init_list);
-MODULE_AUTHOR(DRV_AUTHOR);
+#define DRV_NAME "emac"
+#define DRV_VERSION "3.53"
+#define DRV_DESC "PPC 4xx OCP EMAC driver"
+
MODULE_DESCRIPTION(DRV_DESC);
+MODULE_AUTHOR
+ ("Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>");
MODULE_LICENSE("GPL");
-static int skb_res = SKB_RES;
-module_param(skb_res, int, 0444);
-MODULE_PARM_DESC(skb_res, "Amount of data to reserve on skb buffs\n"
- "The 405 handles a misaligned IP header fine but\n"
- "this can help if you are routing to a tunnel or a\n"
- "device that needs aligned data. 0..2");
-
-#define RGMII_PRIV(ocpdev) ((struct ibm_ocp_rgmii*)ocp_get_drvdata(ocpdev))
+/* minimum number of free TX descriptors required to wake up TX process */
+#define EMAC_TX_WAKEUP_THRESH (NUM_TX_BUFF / 4)
-static unsigned int rgmii_enable[] = {
- RGMII_RTBI,
- RGMII_RGMII,
- RGMII_TBI,
- RGMII_GMII
-};
+/* If packet size is less than this number, we allocate small skb and copy packet
+ * contents into it instead of just sending original big skb up
+ */
+#define EMAC_RX_COPY_THRESH CONFIG_IBM_EMAC_RX_COPY_THRESHOLD
-static unsigned int rgmii_speed_mask[] = {
- RGMII_MII2_SPDMASK,
- RGMII_MII3_SPDMASK
-};
+/* Since multiple EMACs share MDIO lines in various ways, we need
+ * to avoid re-using the same PHY ID in cases where the arch didn't
+ * setup precise phy_map entries
+ */
+static u32 busy_phy_map;
-static unsigned int rgmii_speed100[] = {
- RGMII_MII2_100MB,
- RGMII_MII3_100MB
-};
+#if defined(CONFIG_IBM_EMAC_PHY_RX_CLK_FIX) && (defined(CONFIG_405EP) || defined(CONFIG_440EP))
+/* 405EP has "EMAC to PHY Control Register" (CPC0_EPCTL) which can help us
+ * with PHY RX clock problem.
+ * 440EP has more sane SDR0_MFR register implementation than 440GX, which
+ * also allows controlling each EMAC clock
+ */
+static inline void EMAC_RX_CLK_TX(int idx)
+{
+ unsigned long flags;
+ local_irq_save(flags);
-static unsigned int rgmii_speed1000[] = {
- RGMII_MII2_1000MB,
- RGMII_MII3_1000MB
-};
+#if defined(CONFIG_405EP)
+ mtdcr(0xf3, mfdcr(0xf3) | (1 << idx));
+#else /* CONFIG_440EP */
+ SDR_WRITE(DCRN_SDR_MFR, SDR_READ(DCRN_SDR_MFR) | (0x08000000 >> idx));
+#endif
-#define ZMII_PRIV(ocpdev) ((struct ibm_ocp_zmii*)ocp_get_drvdata(ocpdev))
+ local_irq_restore(flags);
+}
-static unsigned int zmii_enable[][4] = {
- {ZMII_SMII0, ZMII_RMII0, ZMII_MII0,
- ~(ZMII_MDI1 | ZMII_MDI2 | ZMII_MDI3)},
- {ZMII_SMII1, ZMII_RMII1, ZMII_MII1,
- ~(ZMII_MDI0 | ZMII_MDI2 | ZMII_MDI3)},
- {ZMII_SMII2, ZMII_RMII2, ZMII_MII2,
- ~(ZMII_MDI0 | ZMII_MDI1 | ZMII_MDI3)},
- {ZMII_SMII3, ZMII_RMII3, ZMII_MII3, ~(ZMII_MDI0 | ZMII_MDI1 | ZMII_MDI2)}
-};
+static inline void EMAC_RX_CLK_DEFAULT(int idx)
+{
+ unsigned long flags;
+ local_irq_save(flags);
-static unsigned int mdi_enable[] = {
- ZMII_MDI0,
- ZMII_MDI1,
- ZMII_MDI2,
- ZMII_MDI3
-};
+#if defined(CONFIG_405EP)
+ mtdcr(0xf3, mfdcr(0xf3) & ~(1 << idx));
+#else /* CONFIG_440EP */
+ SDR_WRITE(DCRN_SDR_MFR, SDR_READ(DCRN_SDR_MFR) & ~(0x08000000 >> idx));
+#endif
-static unsigned int zmii_speed = 0x0;
-static unsigned int zmii_speed100[] = {
- ZMII_MII0_100MB,
- ZMII_MII1_100MB,
- ZMII_MII2_100MB,
- ZMII_MII3_100MB
-};
+ local_irq_restore(flags);
+}
+#else
+#define EMAC_RX_CLK_TX(idx) ((void)0)
+#define EMAC_RX_CLK_DEFAULT(idx) ((void)0)
+#endif
-/* Since multiple EMACs share MDIO lines in various ways, we need
- * to avoid re-using the same PHY ID in cases where the arch didn't
- * setup precise phy_map entries
+#if defined(CONFIG_IBM_EMAC_PHY_RX_CLK_FIX) && defined(CONFIG_440GX)
+/* We can switch Ethernet clock to the internal source through SDR0_MFR[ECS],
+ * unfortunately this is less flexible than 440EP case, because it's a global
+ * setting for all EMACs, therefore we do this clock trick only during probe.
*/
-static u32 busy_phy_map = 0;
+#define EMAC_CLK_INTERNAL SDR_WRITE(DCRN_SDR_MFR, \
+ SDR_READ(DCRN_SDR_MFR) | 0x08000000)
+#define EMAC_CLK_EXTERNAL SDR_WRITE(DCRN_SDR_MFR, \
+ SDR_READ(DCRN_SDR_MFR) & ~0x08000000)
+#else
+#define EMAC_CLK_INTERNAL ((void)0)
+#define EMAC_CLK_EXTERNAL ((void)0)
+#endif
-/* If EMACs share a common MDIO device, this points to it */
-static struct net_device *mdio_ndev = NULL;
+/* I don't want to litter system log with timeout errors
+ * when we have brain-damaged PHY.
+ */
+static inline void emac_report_timeout_error(struct ocp_enet_private *dev,
+ const char *error)
+{
+#if defined(CONFIG_IBM_EMAC_PHY_RX_CLK_FIX)
+ DBG("%d: %s" NL, dev->def->index, error);
+#else
+ if (net_ratelimit())
+ printk(KERN_ERR "emac%d: %s\n", dev->def->index, error);
+#endif
+}
-struct emac_def_dev {
- struct list_head link;
- struct ocp_device *ocpdev;
- struct ibm_ocp_mal *mal;
+/* PHY polling intervals */
+#define PHY_POLL_LINK_ON HZ
+#define PHY_POLL_LINK_OFF (HZ / 5)
+
+/* Please, keep in sync with struct ibm_emac_stats/ibm_emac_error_stats */
+static const char emac_stats_keys[EMAC_ETHTOOL_STATS_COUNT][ETH_GSTRING_LEN] = {
+ "rx_packets", "rx_bytes", "tx_packets", "tx_bytes", "rx_packets_csum",
+ "tx_packets_csum", "tx_undo", "rx_dropped_stack", "rx_dropped_oom",
+ "rx_dropped_error", "rx_dropped_resize", "rx_dropped_mtu",
+ "rx_stopped", "rx_bd_errors", "rx_bd_overrun", "rx_bd_bad_packet",
+ "rx_bd_runt_packet", "rx_bd_short_event", "rx_bd_alignment_error",
+ "rx_bd_bad_fcs", "rx_bd_packet_too_long", "rx_bd_out_of_range",
+ "rx_bd_in_range", "rx_parity", "rx_fifo_overrun", "rx_overrun",
+ "rx_bad_packet", "rx_runt_packet", "rx_short_event",
+ "rx_alignment_error", "rx_bad_fcs", "rx_packet_too_long",
+ "rx_out_of_range", "rx_in_range", "tx_dropped", "tx_bd_errors",
+ "tx_bd_bad_fcs", "tx_bd_carrier_loss", "tx_bd_excessive_deferral",
+ "tx_bd_excessive_collisions", "tx_bd_late_collision",
+ "tx_bd_multple_collisions", "tx_bd_single_collision",
+ "tx_bd_underrun", "tx_bd_sqe", "tx_parity", "tx_underrun", "tx_sqe",
+ "tx_errors"
};
-static struct net_device_stats *emac_stats(struct net_device *dev)
+static irqreturn_t emac_irq(int irq, void *dev_instance, struct pt_regs *regs);
+static void emac_clean_tx_ring(struct ocp_enet_private *dev);
+
+static inline int emac_phy_supports_gige(int phy_mode)
{
- struct ocp_enet_private *fep = dev->priv;
- return &fep->stats;
-};
+ return phy_mode == PHY_MODE_GMII ||
+ phy_mode == PHY_MODE_RGMII ||
+ phy_mode == PHY_MODE_TBI ||
+ phy_mode == PHY_MODE_RTBI;
+}
-static int
-emac_init_rgmii(struct ocp_device *rgmii_dev, int input, int phy_mode)
+static inline int emac_phy_gpcs(int phy_mode)
{
- struct ibm_ocp_rgmii *rgmii = RGMII_PRIV(rgmii_dev);
- const char *mode_name[] = { "RTBI", "RGMII", "TBI", "GMII" };
- int mode = -1;
+ return phy_mode == PHY_MODE_TBI ||
+ phy_mode == PHY_MODE_RTBI;
+}
- if (!rgmii) {
- rgmii = kmalloc(sizeof(struct ibm_ocp_rgmii), GFP_KERNEL);
+static inline void emac_tx_enable(struct ocp_enet_private *dev)
+{
+ struct emac_regs *p = dev->emacp;
+ unsigned long flags;
+ u32 r;
- if (rgmii == NULL) {
- printk(KERN_ERR
- "rgmii%d: Out of memory allocating RGMII structure!\n",
- rgmii_dev->def->index);
- return -ENOMEM;
- }
+ local_irq_save(flags);
- memset(rgmii, 0, sizeof(*rgmii));
+ DBG("%d: tx_enable" NL, dev->def->index);
- rgmii->base =
- (struct rgmii_regs *)ioremap(rgmii_dev->def->paddr,
- sizeof(*rgmii->base));
- if (rgmii->base == NULL) {
- printk(KERN_ERR
- "rgmii%d: Cannot ioremap bridge registers!\n",
- rgmii_dev->def->index);
+ r = in_be32(&p->mr0);
+ if (!(r & EMAC_MR0_TXE))
+ out_be32(&p->mr0, r | EMAC_MR0_TXE);
+ local_irq_restore(flags);
+}
- kfree(rgmii);
- return -ENOMEM;
- }
- ocp_set_drvdata(rgmii_dev, rgmii);
- }
+static void emac_tx_disable(struct ocp_enet_private *dev)
+{
+ struct emac_regs *p = dev->emacp;
+ unsigned long flags;
+ u32 r;
- if (phy_mode) {
- switch (phy_mode) {
- case PHY_MODE_GMII:
- mode = GMII;
- break;
- case PHY_MODE_TBI:
- mode = TBI;
- break;
- case PHY_MODE_RTBI:
- mode = RTBI;
- break;
- case PHY_MODE_RGMII:
- default:
- mode = RGMII;
- }
- rgmii->base->fer &= ~RGMII_FER_MASK(input);
- rgmii->base->fer |= rgmii_enable[mode] << (4 * input);
- } else {
- switch ((rgmii->base->fer & RGMII_FER_MASK(input)) >> (4 *
- input)) {
- case RGMII_RTBI:
- mode = RTBI;
- break;
- case RGMII_RGMII:
- mode = RGMII;
- break;
- case RGMII_TBI:
- mode = TBI;
- break;
- case RGMII_GMII:
- mode = GMII;
- }
- }
+ local_irq_save(flags);
+
+ DBG("%d: tx_disable" NL, dev->def->index);
- /* Set mode to RGMII if nothing valid is detected */
- if (mode < 0)
- mode = RGMII;
+ r = in_be32(&p->mr0);
+ if (r & EMAC_MR0_TXE) {
+ int n = 300;
+ out_be32(&p->mr0, r & ~EMAC_MR0_TXE);
+ while (!(in_be32(&p->mr0) & EMAC_MR0_TXI) && n)
+ --n;
+ if (unlikely(!n))
+ emac_report_timeout_error(dev, "TX disable timeout");
+ }
+ local_irq_restore(flags);
+}
- printk(KERN_NOTICE "rgmii%d: input %d in %s mode\n",
- rgmii_dev->def->index, input, mode_name[mode]);
+static void emac_rx_enable(struct ocp_enet_private *dev)
+{
+ struct emac_regs *p = dev->emacp;
+ unsigned long flags;
+ u32 r;
- rgmii->mode[input] = mode;
- rgmii->users++;
+ local_irq_save(flags);
+ if (unlikely(dev->commac.rx_stopped))
+ goto out;
- return 0;
+ DBG("%d: rx_enable" NL, dev->def->index);
+
+ r = in_be32(&p->mr0);
+ if (!(r & EMAC_MR0_RXE)) {
+ if (unlikely(!(r & EMAC_MR0_RXI))) {
+ /* Wait if previous async disable is still in progress */
+ int n = 100;
+ while (!(r = in_be32(&p->mr0) & EMAC_MR0_RXI) && n)
+ --n;
+ if (unlikely(!n))
+ emac_report_timeout_error(dev,
+ "RX disable timeout");
+ }
+ out_be32(&p->mr0, r | EMAC_MR0_RXE);
+ }
+ out:
+ local_irq_restore(flags);
}
-static void
-emac_rgmii_port_speed(struct ocp_device *ocpdev, int input, int speed)
+static void emac_rx_disable(struct ocp_enet_private *dev)
{
- struct ibm_ocp_rgmii *rgmii = RGMII_PRIV(ocpdev);
- unsigned int rgmii_speed;
-
- rgmii_speed = in_be32(&rgmii->base->ssr);
+ struct emac_regs *p = dev->emacp;
+ unsigned long flags;
+ u32 r;
- rgmii_speed &= ~rgmii_speed_mask[input];
+ local_irq_save(flags);
- if (speed == 1000)
- rgmii_speed |= rgmii_speed1000[input];
- else if (speed == 100)
- rgmii_speed |= rgmii_speed100[input];
+ DBG("%d: rx_disable" NL, dev->def->index);
- out_be32(&rgmii->base->ssr, rgmii_speed);
+ r = in_be32(&p->mr0);
+ if (r & EMAC_MR0_RXE) {
+ int n = 300;
+ out_be32(&p->mr0, r & ~EMAC_MR0_RXE);
+ while (!(in_be32(&p->mr0) & EMAC_MR0_RXI) && n)
+ --n;
+ if (unlikely(!n))
+ emac_report_timeout_error(dev, "RX disable timeout");
+ }
+ local_irq_restore(flags);
}
-static void emac_close_rgmii(struct ocp_device *ocpdev)
+static inline void emac_rx_disable_async(struct ocp_enet_private *dev)
{
- struct ibm_ocp_rgmii *rgmii = RGMII_PRIV(ocpdev);
- BUG_ON(!rgmii || rgmii->users == 0);
+ struct emac_regs *p = dev->emacp;
+ unsigned long flags;
+ u32 r;
- if (!--rgmii->users) {
- ocp_set_drvdata(ocpdev, NULL);
- iounmap((void *)rgmii->base);
- kfree(rgmii);
- }
+ local_irq_save(flags);
+
+ DBG("%d: rx_disable_async" NL, dev->def->index);
+
+ r = in_be32(&p->mr0);
+ if (r & EMAC_MR0_RXE)
+ out_be32(&p->mr0, r & ~EMAC_MR0_RXE);
+ local_irq_restore(flags);
}
-static int emac_init_zmii(struct ocp_device *zmii_dev, int input, int phy_mode)
+static int emac_reset(struct ocp_enet_private *dev)
{
- struct ibm_ocp_zmii *zmii = ZMII_PRIV(zmii_dev);
- const char *mode_name[] = { "SMII", "RMII", "MII" };
- int mode = -1;
+ struct emac_regs *p = dev->emacp;
+ unsigned long flags;
+ int n = 20;
- if (!zmii) {
- zmii = kmalloc(sizeof(struct ibm_ocp_zmii), GFP_KERNEL);
- if (zmii == NULL) {
- printk(KERN_ERR
- "zmii%d: Out of memory allocating ZMII structure!\n",
- zmii_dev->def->index);
- return -ENOMEM;
- }
- memset(zmii, 0, sizeof(*zmii));
+ DBG("%d: reset" NL, dev->def->index);
- zmii->base =
- (struct zmii_regs *)ioremap(zmii_dev->def->paddr,
- sizeof(*zmii->base));
- if (zmii->base == NULL) {
- printk(KERN_ERR
- "zmii%d: Cannot ioremap bridge registers!\n",
- zmii_dev->def->index);
+ local_irq_save(flags);
- kfree(zmii);
- return -ENOMEM;
- }
- ocp_set_drvdata(zmii_dev, zmii);
+ if (!dev->reset_failed) {
+ /* 40x erratum suggests stopping RX channel before reset,
+ * we stop TX as well
+ */
+ emac_rx_disable(dev);
+ emac_tx_disable(dev);
}
- if (phy_mode) {
- switch (phy_mode) {
- case PHY_MODE_MII:
- mode = MII;
- break;
- case PHY_MODE_RMII:
- mode = RMII;
- break;
- case PHY_MODE_SMII:
- default:
- mode = SMII;
- }
- zmii->base->fer &= ~ZMII_FER_MASK(input);
- zmii->base->fer |= zmii_enable[input][mode];
+ out_be32(&p->mr0, EMAC_MR0_SRST);
+ while ((in_be32(&p->mr0) & EMAC_MR0_SRST) && n)
+ --n;
+ local_irq_restore(flags);
+
+ if (n) {
+ dev->reset_failed = 0;
+ return 0;
} else {
- switch ((zmii->base->fer & ZMII_FER_MASK(input)) << (4 * input)) {
- case ZMII_MII0:
- mode = MII;
- break;
- case ZMII_RMII0:
- mode = RMII;
- break;
- case ZMII_SMII0:
- mode = SMII;
- }
+ emac_report_timeout_error(dev, "reset timeout");
+ dev->reset_failed = 1;
+ return -ETIMEDOUT;
}
+}
- /* Set mode to SMII if nothing valid is detected */
- if (mode < 0)
- mode = SMII;
+static void emac_hash_mc(struct ocp_enet_private *dev)
+{
+ struct emac_regs *p = dev->emacp;
+ u16 gaht[4] = { 0 };
+ struct dev_mc_list *dmi;
- printk(KERN_NOTICE "zmii%d: input %d in %s mode\n",
- zmii_dev->def->index, input, mode_name[mode]);
+ DBG("%d: hash_mc %d" NL, dev->def->index, dev->ndev->mc_count);
- zmii->mode[input] = mode;
- zmii->users++;
+ for (dmi = dev->ndev->mc_list; dmi; dmi = dmi->next) {
+ int bit;
+ DBG2("%d: mc %02x:%02x:%02x:%02x:%02x:%02x" NL,
+ dev->def->index,
+ dmi->dmi_addr[0], dmi->dmi_addr[1], dmi->dmi_addr[2],
+ dmi->dmi_addr[3], dmi->dmi_addr[4], dmi->dmi_addr[5]);
- return 0;
+ bit = 63 - (ether_crc(ETH_ALEN, dmi->dmi_addr) >> 26);
+ gaht[bit >> 4] |= 0x8000 >> (bit & 0x0f);
+ }
+ out_be32(&p->gaht1, gaht[0]);
+ out_be32(&p->gaht2, gaht[1]);
+ out_be32(&p->gaht3, gaht[2]);
+ out_be32(&p->gaht4, gaht[3]);
}
-static void emac_enable_zmii_port(struct ocp_device *ocpdev, int input)
+static inline u32 emac_iff2rmr(struct net_device *ndev)
{
- u32 mask;
- struct ibm_ocp_zmii *zmii = ZMII_PRIV(ocpdev);
+ u32 r = EMAC_RMR_SP | EMAC_RMR_SFCS | EMAC_RMR_IAE | EMAC_RMR_BAE |
+ EMAC_RMR_BASE;
- mask = in_be32(&zmii->base->fer);
- mask &= zmii_enable[input][MDI]; /* turn all non enabled MDI's off */
- mask |= zmii_enable[input][zmii->mode[input]] | mdi_enable[input];
- out_be32(&zmii->base->fer, mask);
+ if (ndev->flags & IFF_PROMISC)
+ r |= EMAC_RMR_PME;
+ else if (ndev->flags & IFF_ALLMULTI || ndev->mc_count > 32)
+ r |= EMAC_RMR_PMME;
+ else if (ndev->mc_count > 0)
+ r |= EMAC_RMR_MAE;
+
+ return r;
}
-static void
-emac_zmii_port_speed(struct ocp_device *ocpdev, int input, int speed)
+static inline int emac_opb_mhz(void)
{
- struct ibm_ocp_zmii *zmii = ZMII_PRIV(ocpdev);
-
- if (speed == 100)
- zmii_speed |= zmii_speed100[input];
- else
- zmii_speed &= ~zmii_speed100[input];
-
- out_be32(&zmii->base->ssr, zmii_speed);
+ return (ocp_sys_info.opb_bus_freq + 500000) / 1000000;
}
-static void emac_close_zmii(struct ocp_device *ocpdev)
+/* BHs disabled */
+static int emac_configure(struct ocp_enet_private *dev)
{
- struct ibm_ocp_zmii *zmii = ZMII_PRIV(ocpdev);
- BUG_ON(!zmii || zmii->users == 0);
+ struct emac_regs *p = dev->emacp;
+ struct net_device *ndev = dev->ndev;
+ int gige;
+ u32 r;
- if (!--zmii->users) {
- ocp_set_drvdata(ocpdev, NULL);
- iounmap((void *)zmii->base);
- kfree(zmii);
- }
-}
+ DBG("%d: configure" NL, dev->def->index);
-int emac_phy_read(struct net_device *dev, int mii_id, int reg)
-{
- int count;
- uint32_t stacr;
- struct ocp_enet_private *fep = dev->priv;
- emac_t *emacp = fep->emacp;
+ if (emac_reset(dev) < 0)
+ return -ETIMEDOUT;
- MDIO_DEBUG(("%s: phy_read, id: 0x%x, reg: 0x%x\n", dev->name, mii_id,
- reg));
+ tah_reset(dev->tah_dev);
- /* Enable proper ZMII port */
- if (fep->zmii_dev)
- emac_enable_zmii_port(fep->zmii_dev, fep->zmii_input);
+ /* Mode register */
+ r = EMAC_MR1_BASE(emac_opb_mhz()) | EMAC_MR1_VLE | EMAC_MR1_IST;
+ if (dev->phy.duplex == DUPLEX_FULL)
+ r |= EMAC_MR1_FDE;
+ switch (dev->phy.speed) {
+ case SPEED_1000:
+ if (emac_phy_gpcs(dev->phy.mode)) {
+ r |= EMAC_MR1_MF_1000GPCS |
+ EMAC_MR1_MF_IPPA(dev->phy.address);
- /* Use the EMAC that has the MDIO port */
- if (fep->mdio_dev) {
- dev = fep->mdio_dev;
- fep = dev->priv;
- emacp = fep->emacp;
+ /* Put some arbitrary OUI, Manuf & Rev IDs so we can
+ * identify this GPCS PHY later.
+ */
+ out_be32(&p->ipcr, 0xdeadbeef);
+ } else
+ r |= EMAC_MR1_MF_1000;
+ r |= EMAC_MR1_RFS_16K;
+ gige = 1;
+
+ if (dev->ndev->mtu > ETH_DATA_LEN)
+ r |= EMAC_MR1_JPSM;
+ break;
+ case SPEED_100:
+ r |= EMAC_MR1_MF_100;
+ /* Fall through */
+ default:
+ r |= EMAC_MR1_RFS_4K;
+ gige = 0;
+ break;
}
- count = 0;
- while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0)
- && (count++ < MDIO_DELAY))
- udelay(1);
- MDIO_DEBUG((" (count was %d)\n", count));
+ if (dev->rgmii_dev)
+ rgmii_set_speed(dev->rgmii_dev, dev->rgmii_input,
+ dev->phy.speed);
+ else
+ zmii_set_speed(dev->zmii_dev, dev->zmii_input, dev->phy.speed);
- if ((stacr & EMAC_STACR_OC) == 0) {
- printk(KERN_WARNING "%s: PHY read timeout #1!\n", dev->name);
- return -1;
+#if !defined(CONFIG_40x)
+ /* on 40x erratum forces us to NOT use integrated flow control,
+ * let's hope it works on 44x ;)
+ */
+ if (dev->phy.duplex == DUPLEX_FULL) {
+ if (dev->phy.pause)
+ r |= EMAC_MR1_EIFC | EMAC_MR1_APP;
+ else if (dev->phy.asym_pause)
+ r |= EMAC_MR1_APP;
}
+#endif
+ out_be32(&p->mr1, r);
+
+ /* Set individual MAC address */
+ out_be32(&p->iahr, (ndev->dev_addr[0] << 8) | ndev->dev_addr[1]);
+ out_be32(&p->ialr, (ndev->dev_addr[2] << 24) |
+ (ndev->dev_addr[3] << 16) | (ndev->dev_addr[4] << 8) |
+ ndev->dev_addr[5]);
+
+ /* VLAN Tag Protocol ID */
+ out_be32(&p->vtpid, 0x8100);
+
+ /* Receive mode register */
+ r = emac_iff2rmr(ndev);
+ if (r & EMAC_RMR_MAE)
+ emac_hash_mc(dev);
+ out_be32(&p->rmr, r);
+
+ /* FIFOs thresholds */
+ r = EMAC_TMR1((EMAC_MAL_BURST_SIZE / EMAC_FIFO_ENTRY_SIZE) + 1,
+ EMAC_TX_FIFO_SIZE / 2 / EMAC_FIFO_ENTRY_SIZE);
+ out_be32(&p->tmr1, r);
+ out_be32(&p->trtr, EMAC_TRTR(EMAC_TX_FIFO_SIZE / 2));
+
+ /* PAUSE frame is sent when RX FIFO reaches its high-water mark,
+ there should be still enough space in FIFO to allow the our link
+ partner time to process this frame and also time to send PAUSE
+ frame itself.
+
+ Here is the worst case scenario for the RX FIFO "headroom"
+ (from "The Switch Book") (100Mbps, without preamble, inter-frame gap):
+
+ 1) One maximum-length frame on TX 1522 bytes
+ 2) One PAUSE frame time 64 bytes
+ 3) PAUSE frame decode time allowance 64 bytes
+ 4) One maximum-length frame on RX 1522 bytes
+ 5) Round-trip propagation delay of the link (100Mb) 15 bytes
+ ----------
+ 3187 bytes
+
+ I chose to set high-water mark to RX_FIFO_SIZE / 4 (1024 bytes)
+ low-water mark to RX_FIFO_SIZE / 8 (512 bytes)
+ */
+ r = EMAC_RWMR(EMAC_RX_FIFO_SIZE(gige) / 8 / EMAC_FIFO_ENTRY_SIZE,
+ EMAC_RX_FIFO_SIZE(gige) / 4 / EMAC_FIFO_ENTRY_SIZE);
+ out_be32(&p->rwmr, r);
+
+ /* Set PAUSE timer to the maximum */
+ out_be32(&p->ptr, 0xffff);
+
+ /* IRQ sources */
+ out_be32(&p->iser, EMAC_ISR_TXPE | EMAC_ISR_RXPE | /* EMAC_ISR_TXUE |
+ EMAC_ISR_RXOE | */ EMAC_ISR_OVR | EMAC_ISR_BP | EMAC_ISR_SE |
+ EMAC_ISR_ALE | EMAC_ISR_BFCS | EMAC_ISR_PTLE | EMAC_ISR_ORE |
+ EMAC_ISR_IRE | EMAC_ISR_TE);
+
+ /* We need to take GPCS PHY out of isolate mode after EMAC reset */
+ if (emac_phy_gpcs(dev->phy.mode))
+ mii_reset_phy(&dev->phy);
+
+ return 0;
+}
- /* Clear the speed bits and make a read request to the PHY */
- stacr = ((EMAC_STACR_READ | (reg & 0x1f)) & ~EMAC_STACR_CLK_100MHZ);
- stacr |= ((mii_id & 0x1F) << 5);
+/* BHs disabled */
+static void emac_reinitialize(struct ocp_enet_private *dev)
+{
+ DBG("%d: reinitialize" NL, dev->def->index);
- out_be32(&emacp->em0stacr, stacr);
+ if (!emac_configure(dev)) {
+ emac_tx_enable(dev);
+ emac_rx_enable(dev);
+ }
+}
- count = 0;
- while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0)
- && (count++ < MDIO_DELAY))
- udelay(1);
- MDIO_DEBUG((" (count was %d)\n", count));
+/* BHs disabled */
+static void emac_full_tx_reset(struct net_device *ndev)
+{
+ struct ocp_enet_private *dev = ndev->priv;
+ struct ocp_func_emac_data *emacdata = dev->def->additions;
- if ((stacr & EMAC_STACR_OC) == 0) {
- printk(KERN_WARNING "%s: PHY read timeout #2!\n", dev->name);
- return -1;
- }
+ DBG("%d: full_tx_reset" NL, dev->def->index);
- /* Check for a read error */
- if (stacr & EMAC_STACR_PHYE) {
- MDIO_DEBUG(("EMAC MDIO PHY error !\n"));
- return -1;
- }
+ emac_tx_disable(dev);
+ mal_disable_tx_channel(dev->mal, emacdata->mal_tx_chan);
+ emac_clean_tx_ring(dev);
+ dev->tx_cnt = dev->tx_slot = dev->ack_slot = 0;
- MDIO_DEBUG((" -> 0x%x\n", stacr >> 16));
+ emac_configure(dev);
- return (stacr >> 16);
+ mal_enable_tx_channel(dev->mal, emacdata->mal_tx_chan);
+ emac_tx_enable(dev);
+ emac_rx_enable(dev);
+
+ netif_wake_queue(ndev);
}
-void emac_phy_write(struct net_device *dev, int mii_id, int reg, int data)
+static int __emac_mdio_read(struct ocp_enet_private *dev, u8 id, u8 reg)
{
- int count;
- uint32_t stacr;
- struct ocp_enet_private *fep = dev->priv;
- emac_t *emacp = fep->emacp;
+ struct emac_regs *p = dev->emacp;
+ u32 r;
+ int n;
- MDIO_DEBUG(("%s phy_write, id: 0x%x, reg: 0x%x, data: 0x%x\n",
- dev->name, mii_id, reg, data));
+ DBG2("%d: mdio_read(%02x,%02x)" NL, dev->def->index, id, reg);
- /* Enable proper ZMII port */
- if (fep->zmii_dev)
- emac_enable_zmii_port(fep->zmii_dev, fep->zmii_input);
+ /* Enable proper MDIO port */
+ zmii_enable_mdio(dev->zmii_dev, dev->zmii_input);
- /* Use the EMAC that has the MDIO port */
- if (fep->mdio_dev) {
- dev = fep->mdio_dev;
- fep = dev->priv;
- emacp = fep->emacp;
+ /* Wait for management interface to become idle */
+ n = 10;
+ while (!(in_be32(&p->stacr) & EMAC_STACR_OC)) {
+ udelay(1);
+ if (!--n)
+ goto to;
}
- count = 0;
- while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0)
- && (count++ < MDIO_DELAY))
+ /* Issue read command */
+ out_be32(&p->stacr,
+ EMAC_STACR_BASE(emac_opb_mhz()) | EMAC_STACR_STAC_READ |
+ (reg & EMAC_STACR_PRA_MASK)
+ | ((id & EMAC_STACR_PCDA_MASK) << EMAC_STACR_PCDA_SHIFT));
+
+ /* Wait for read to complete */
+ n = 100;
+ while (!((r = in_be32(&p->stacr)) & EMAC_STACR_OC)) {
udelay(1);
- MDIO_DEBUG((" (count was %d)\n", count));
+ if (!--n)
+ goto to;
+ }
- if ((stacr & EMAC_STACR_OC) == 0) {
- printk(KERN_WARNING "%s: PHY write timeout #2!\n", dev->name);
- return;
+ if (unlikely(r & EMAC_STACR_PHYE)) {
+ DBG("%d: mdio_read(%02x, %02x) failed" NL, dev->def->index,
+ id, reg);
+ return -EREMOTEIO;
}
- /* Clear the speed bits and make a read request to the PHY */
+ r = ((r >> EMAC_STACR_PHYD_SHIFT) & EMAC_STACR_PHYD_MASK);
+ DBG2("%d: mdio_read -> %04x" NL, dev->def->index, r);
+ return r;
+ to:
+ DBG("%d: MII management interface timeout (read)" NL, dev->def->index);
+ return -ETIMEDOUT;
+}
- stacr = ((EMAC_STACR_WRITE | (reg & 0x1f)) & ~EMAC_STACR_CLK_100MHZ);
- stacr |= ((mii_id & 0x1f) << 5) | ((data & 0xffff) << 16);
+static void __emac_mdio_write(struct ocp_enet_private *dev, u8 id, u8 reg,
+ u16 val)
+{
+ struct emac_regs *p = dev->emacp;
+ int n;
- out_be32(&emacp->em0stacr, stacr);
+ DBG2("%d: mdio_write(%02x,%02x,%04x)" NL, dev->def->index, id, reg,
+ val);
- count = 0;
- while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0)
- && (count++ < MDIO_DELAY))
+ /* Enable proper MDIO port */
+ zmii_enable_mdio(dev->zmii_dev, dev->zmii_input);
+
+ /* Wait for management interface to be idle */
+ n = 10;
+ while (!(in_be32(&p->stacr) & EMAC_STACR_OC)) {
udelay(1);
- MDIO_DEBUG((" (count was %d)\n", count));
+ if (!--n)
+ goto to;
+ }
- if ((stacr & EMAC_STACR_OC) == 0)
- printk(KERN_WARNING "%s: PHY write timeout #2!\n", dev->name);
+ /* Issue write command */
+ out_be32(&p->stacr,
+ EMAC_STACR_BASE(emac_opb_mhz()) | EMAC_STACR_STAC_WRITE |
+ (reg & EMAC_STACR_PRA_MASK) |
+ ((id & EMAC_STACR_PCDA_MASK) << EMAC_STACR_PCDA_SHIFT) |
+ (val << EMAC_STACR_PHYD_SHIFT));
- /* Check for a write error */
- if ((stacr & EMAC_STACR_PHYE) != 0) {
- MDIO_DEBUG(("EMAC MDIO PHY error !\n"));
+ /* Wait for write to complete */
+ n = 100;
+ while (!(in_be32(&p->stacr) & EMAC_STACR_OC)) {
+ udelay(1);
+ if (!--n)
+ goto to;
}
+ return;
+ to:
+ DBG("%d: MII management interface timeout (write)" NL, dev->def->index);
}
-static void emac_txeob_dev(void *param, u32 chanmask)
+static int emac_mdio_read(struct net_device *ndev, int id, int reg)
{
- struct net_device *dev = param;
- struct ocp_enet_private *fep = dev->priv;
- unsigned long flags;
-
- spin_lock_irqsave(&fep->lock, flags);
-
- PKT_DEBUG(("emac_txeob_dev() entry, tx_cnt: %d\n", fep->tx_cnt));
-
- while (fep->tx_cnt &&
- !(fep->tx_desc[fep->ack_slot].ctrl & MAL_TX_CTRL_READY)) {
+ struct ocp_enet_private *dev = ndev->priv;
+ int res;
+
+ local_bh_disable();
+ res = __emac_mdio_read(dev->mdio_dev ? dev->mdio_dev : dev, (u8) id,
+ (u8) reg);
+ local_bh_enable();
+ return res;
+}
- if (fep->tx_desc[fep->ack_slot].ctrl & MAL_TX_CTRL_LAST) {
- /* Tell the system the transmit completed. */
- dma_unmap_single(&fep->ocpdev->dev,
- fep->tx_desc[fep->ack_slot].data_ptr,
- fep->tx_desc[fep->ack_slot].data_len,
- DMA_TO_DEVICE);
- dev_kfree_skb_irq(fep->tx_skb[fep->ack_slot]);
+static void emac_mdio_write(struct net_device *ndev, int id, int reg, int val)
+{
+ struct ocp_enet_private *dev = ndev->priv;
- if (fep->tx_desc[fep->ack_slot].ctrl &
- (EMAC_TX_ST_EC | EMAC_TX_ST_MC | EMAC_TX_ST_SC))
- fep->stats.collisions++;
- }
+ local_bh_disable();
+ __emac_mdio_write(dev->mdio_dev ? dev->mdio_dev : dev, (u8) id,
+ (u8) reg, (u16) val);
+ local_bh_enable();
+}
- fep->tx_skb[fep->ack_slot] = (struct sk_buff *)NULL;
- if (++fep->ack_slot == NUM_TX_BUFF)
- fep->ack_slot = 0;
+/* BHs disabled */
+static void emac_set_multicast_list(struct net_device *ndev)
+{
+ struct ocp_enet_private *dev = ndev->priv;
+ struct emac_regs *p = dev->emacp;
+ u32 rmr = emac_iff2rmr(ndev);
+
+ DBG("%d: multicast %08x" NL, dev->def->index, rmr);
+ BUG_ON(!netif_running(dev->ndev));
+
+ /* I decided to relax register access rules here to avoid
+ * full EMAC reset.
+ *
+ * There is a real problem with EMAC4 core if we use MWSW_001 bit
+ * in MR1 register and do a full EMAC reset.
+ * One TX BD status update is delayed and, after EMAC reset, it
+ * never happens, resulting in TX hung (it'll be recovered by TX
+ * timeout handler eventually, but this is just gross).
+ * So we either have to do full TX reset or try to cheat here :)
+ *
+ * The only required change is to RX mode register, so I *think* all
+ * we need is just to stop RX channel. This seems to work on all
+ * tested SoCs. --ebs
+ */
+ emac_rx_disable(dev);
+ if (rmr & EMAC_RMR_MAE)
+ emac_hash_mc(dev);
+ out_be32(&p->rmr, rmr);
+ emac_rx_enable(dev);
+}
- fep->tx_cnt--;
+/* BHs disabled */
+static int emac_resize_rx_ring(struct ocp_enet_private *dev, int new_mtu)
+{
+ struct ocp_func_emac_data *emacdata = dev->def->additions;
+ int rx_sync_size = emac_rx_sync_size(new_mtu);
+ int rx_skb_size = emac_rx_skb_size(new_mtu);
+ int i, ret = 0;
+
+ emac_rx_disable(dev);
+ mal_disable_rx_channel(dev->mal, emacdata->mal_rx_chan);
+
+ if (dev->rx_sg_skb) {
+ ++dev->estats.rx_dropped_resize;
+ dev_kfree_skb(dev->rx_sg_skb);
+ dev->rx_sg_skb = NULL;
}
- if (fep->tx_cnt < NUM_TX_BUFF)
- netif_wake_queue(dev);
- PKT_DEBUG(("emac_txeob_dev() exit, tx_cnt: %d\n", fep->tx_cnt));
+ /* Make a first pass over RX ring and mark BDs ready, dropping
+ * non-processed packets on the way. We need this as a separate pass
+ * to simplify error recovery in the case of allocation failure later.
+ */
+ for (i = 0; i < NUM_RX_BUFF; ++i) {
+ if (dev->rx_desc[i].ctrl & MAL_RX_CTRL_FIRST)
+ ++dev->estats.rx_dropped_resize;
- spin_unlock_irqrestore(&fep->lock, flags);
-}
+ dev->rx_desc[i].data_len = 0;
+ dev->rx_desc[i].ctrl = MAL_RX_CTRL_EMPTY |
+ (i == (NUM_RX_BUFF - 1) ? MAL_RX_CTRL_WRAP : 0);
+ }
-/*
- Fill/Re-fill the rx chain with valid ctrl/ptrs.
- This function will fill from rx_slot up to the parm end.
- So to completely fill the chain pre-set rx_slot to 0 and
- pass in an end of 0.
- */
-static void emac_rx_fill(struct net_device *dev, int end)
-{
- int i;
- struct ocp_enet_private *fep = dev->priv;
-
- i = fep->rx_slot;
- do {
- /* We don't want the 16 bytes skb_reserve done by dev_alloc_skb,
- * it breaks our cache line alignement. However, we still allocate
- * +16 so that we end up allocating the exact same size as
- * dev_alloc_skb() would do.
- * Also, because of the skb_res, the max DMA size we give to EMAC
- * is slighly wrong, causing it to potentially DMA 2 more bytes
- * from a broken/oversized packet. These 16 bytes will take care
- * that we don't walk on somebody else toes with that.
- */
- fep->rx_skb[i] =
- alloc_skb(fep->rx_buffer_size + 16, GFP_ATOMIC);
-
- if (fep->rx_skb[i] == NULL) {
- /* Keep rx_slot here, the next time clean/fill is called
- * we will try again before the MAL wraps back here
- * If the MAL tries to use this descriptor with
- * the EMPTY bit off it will cause the
- * rxde interrupt. That is where we will
- * try again to allocate an sk_buff.
- */
- break;
+ /* Reallocate RX ring only if bigger skb buffers are required */
+ if (rx_skb_size <= dev->rx_skb_size)
+ goto skip;
+ /* Second pass, allocate new skbs */
+ for (i = 0; i < NUM_RX_BUFF; ++i) {
+ struct sk_buff *skb = alloc_skb(rx_skb_size, GFP_ATOMIC);
+ if (!skb) {
+ ret = -ENOMEM;
+ goto oom;
}
- if (skb_res)
- skb_reserve(fep->rx_skb[i], skb_res);
+ BUG_ON(!dev->rx_skb[i]);
+ dev_kfree_skb(dev->rx_skb[i]);
- /* We must NOT dma_map_single the cache line right after the
- * buffer, so we must crop our sync size to account for the
- * reserved space
- */
- fep->rx_desc[i].data_ptr =
- (unsigned char *)dma_map_single(&fep->ocpdev->dev,
- (void *)fep->rx_skb[i]->
- data,
- fep->rx_buffer_size -
- skb_res, DMA_FROM_DEVICE);
-
- /*
- * Some 4xx implementations use the previously
- * reserved bits in data_len to encode the MS
- * 4-bits of a 36-bit physical address (ERPN)
- * This must be initialized.
- */
- fep->rx_desc[i].data_len = 0;
- fep->rx_desc[i].ctrl = MAL_RX_CTRL_EMPTY | MAL_RX_CTRL_INTR |
- (i == (NUM_RX_BUFF - 1) ? MAL_RX_CTRL_WRAP : 0);
+ skb_reserve(skb, EMAC_RX_SKB_HEADROOM + 2);
+ dev->rx_desc[i].data_ptr =
+ dma_map_single(dev->ldev, skb->data - 2, rx_sync_size,
+ DMA_FROM_DEVICE) + 2;
+ dev->rx_skb[i] = skb;
+ }
+ skip:
+ /* Check if we need to change "Jumbo" bit in MR1 */
+ if ((new_mtu > ETH_DATA_LEN) ^ (dev->ndev->mtu > ETH_DATA_LEN)) {
+ /* This is to prevent starting RX channel in emac_rx_enable() */
+ dev->commac.rx_stopped = 1;
+
+ dev->ndev->mtu = new_mtu;
+ emac_full_tx_reset(dev->ndev);
+ }
- } while ((i = (i + 1) % NUM_RX_BUFF) != end);
+ mal_set_rcbs(dev->mal, emacdata->mal_rx_chan, emac_rx_size(new_mtu));
+ oom:
+ /* Restart RX */
+ dev->commac.rx_stopped = dev->rx_slot = 0;
+ mal_enable_rx_channel(dev->mal, emacdata->mal_rx_chan);
+ emac_rx_enable(dev);
- fep->rx_slot = i;
+ return ret;
}
-static void
-emac_rx_csum(struct net_device *dev, unsigned short ctrl, struct sk_buff *skb)
+/* Process ctx, rtnl_lock semaphore */
+static int emac_change_mtu(struct net_device *ndev, int new_mtu)
{
- struct ocp_enet_private *fep = dev->priv;
+ struct ocp_enet_private *dev = ndev->priv;
+ int ret = 0;
- /* Exit if interface has no TAH engine */
- if (!fep->tah_dev) {
- skb->ip_summed = CHECKSUM_NONE;
- return;
- }
+ if (new_mtu < EMAC_MIN_MTU || new_mtu > EMAC_MAX_MTU)
+ return -EINVAL;
- /* Check for TCP/UDP/IP csum error */
- if (ctrl & EMAC_CSUM_VER_ERROR) {
- /* Let the stack verify checksum errors */
- skb->ip_summed = CHECKSUM_NONE;
-/* adapter->hw_csum_err++; */
- } else {
- /* Csum is good */
- skb->ip_summed = CHECKSUM_UNNECESSARY;
-/* adapter->hw_csum_good++; */
- }
-}
+ DBG("%d: change_mtu(%d)" NL, dev->def->index, new_mtu);
-static int emac_rx_clean(struct net_device *dev)
-{
- int i, b, bnum = 0, buf[6];
- int error, frame_length;
- struct ocp_enet_private *fep = dev->priv;
- unsigned short ctrl;
+ local_bh_disable();
+ if (netif_running(ndev)) {
+ /* Check if we really need to reinitalize RX ring */
+ if (emac_rx_skb_size(ndev->mtu) != emac_rx_skb_size(new_mtu))
+ ret = emac_resize_rx_ring(dev, new_mtu);
+ }
- i = fep->rx_slot;
+ if (!ret) {
+ ndev->mtu = new_mtu;
+ dev->rx_skb_size = emac_rx_skb_size(new_mtu);
+ dev->rx_sync_size = emac_rx_sync_size(new_mtu);
+ }
+ local_bh_enable();
- PKT_DEBUG(("emac_rx_clean() entry, rx_slot: %d\n", fep->rx_slot));
+ return ret;
+}
- do {
- if (fep->rx_skb[i] == NULL)
- continue; /*we have already handled the packet but haved failed to alloc */
- /*
- since rx_desc is in uncached mem we don't keep reading it directly
- we pull out a local copy of ctrl and do the checks on the copy.
- */
- ctrl = fep->rx_desc[i].ctrl;
- if (ctrl & MAL_RX_CTRL_EMPTY)
- break; /*we don't have any more ready packets */
-
- if (EMAC_IS_BAD_RX_PACKET(ctrl)) {
- fep->stats.rx_errors++;
- fep->stats.rx_dropped++;
-
- if (ctrl & EMAC_RX_ST_OE)
- fep->stats.rx_fifo_errors++;
- if (ctrl & EMAC_RX_ST_AE)
- fep->stats.rx_frame_errors++;
- if (ctrl & EMAC_RX_ST_BFCS)
- fep->stats.rx_crc_errors++;
- if (ctrl & (EMAC_RX_ST_RP | EMAC_RX_ST_PTL |
- EMAC_RX_ST_ORE | EMAC_RX_ST_IRE))
- fep->stats.rx_length_errors++;
- } else {
- if ((ctrl & (MAL_RX_CTRL_FIRST | MAL_RX_CTRL_LAST)) ==
- (MAL_RX_CTRL_FIRST | MAL_RX_CTRL_LAST)) {
- /* Single descriptor packet */
- emac_rx_csum(dev, ctrl, fep->rx_skb[i]);
- /* Send the skb up the chain. */
- frame_length = fep->rx_desc[i].data_len - 4;
- skb_put(fep->rx_skb[i], frame_length);
- fep->rx_skb[i]->dev = dev;
- fep->rx_skb[i]->protocol =
- eth_type_trans(fep->rx_skb[i], dev);
- error = netif_rx(fep->rx_skb[i]);
-
- if ((error == NET_RX_DROP) ||
- (error == NET_RX_BAD)) {
- fep->stats.rx_dropped++;
- } else {
- fep->stats.rx_packets++;
- fep->stats.rx_bytes += frame_length;
- }
- fep->rx_skb[i] = NULL;
- } else {
- /* Multiple descriptor packet */
- if (ctrl & MAL_RX_CTRL_FIRST) {
- if (fep->rx_desc[(i + 1) % NUM_RX_BUFF].
- ctrl & MAL_RX_CTRL_EMPTY)
- break;
- bnum = 0;
- buf[bnum] = i;
- ++bnum;
- continue;
- }
- if (((ctrl & MAL_RX_CTRL_FIRST) !=
- MAL_RX_CTRL_FIRST) &&
- ((ctrl & MAL_RX_CTRL_LAST) !=
- MAL_RX_CTRL_LAST)) {
- if (fep->rx_desc[(i + 1) %
- NUM_RX_BUFF].ctrl &
- MAL_RX_CTRL_EMPTY) {
- i = buf[0];
- break;
- }
- buf[bnum] = i;
- ++bnum;
- continue;
- }
- if (ctrl & MAL_RX_CTRL_LAST) {
- buf[bnum] = i;
- ++bnum;
- skb_put(fep->rx_skb[buf[0]],
- fep->rx_desc[buf[0]].data_len);
- for (b = 1; b < bnum; b++) {
- /*
- * MAL is braindead, we need
- * to copy the remainder
- * of the packet from the
- * latter descriptor buffers
- * to the first skb. Then
- * dispose of the source
- * skbs.
- *
- * Once the stack is fixed
- * to handle frags on most
- * protocols we can generate
- * a fragmented skb with
- * no copies.
- */
- memcpy(fep->rx_skb[buf[0]]->
- data +
- fep->rx_skb[buf[0]]->len,
- fep->rx_skb[buf[b]]->
- data,
- fep->rx_desc[buf[b]].
- data_len);
- skb_put(fep->rx_skb[buf[0]],
- fep->rx_desc[buf[b]].
- data_len);
- dma_unmap_single(&fep->ocpdev->
- dev,
- fep->
- rx_desc[buf
- [b]].
- data_ptr,
- fep->
- rx_desc[buf
- [b]].
- data_len,
- DMA_FROM_DEVICE);
- dev_kfree_skb(fep->
- rx_skb[buf[b]]);
- }
- emac_rx_csum(dev, ctrl,
- fep->rx_skb[buf[0]]);
-
- fep->rx_skb[buf[0]]->dev = dev;
- fep->rx_skb[buf[0]]->protocol =
- eth_type_trans(fep->rx_skb[buf[0]],
- dev);
- error = netif_rx(fep->rx_skb[buf[0]]);
-
- if ((error == NET_RX_DROP)
- || (error == NET_RX_BAD)) {
- fep->stats.rx_dropped++;
- } else {
- fep->stats.rx_packets++;
- fep->stats.rx_bytes +=
- fep->rx_skb[buf[0]]->len;
- }
- for (b = 0; b < bnum; b++)
- fep->rx_skb[buf[b]] = NULL;
- }
- }
+static void emac_clean_tx_ring(struct ocp_enet_private *dev)
+{
+ int i;
+ for (i = 0; i < NUM_TX_BUFF; ++i) {
+ if (dev->tx_skb[i]) {
+ dev_kfree_skb(dev->tx_skb[i]);
+ dev->tx_skb[i] = NULL;
+ if (dev->tx_desc[i].ctrl & MAL_TX_CTRL_READY)
+ ++dev->estats.tx_dropped;
}
- } while ((i = (i + 1) % NUM_RX_BUFF) != fep->rx_slot);
-
- PKT_DEBUG(("emac_rx_clean() exit, rx_slot: %d\n", fep->rx_slot));
-
- return i;
+ dev->tx_desc[i].ctrl = 0;
+ dev->tx_desc[i].data_ptr = 0;
+ }
}
-static void emac_rxeob_dev(void *param, u32 chanmask)
+static void emac_clean_rx_ring(struct ocp_enet_private *dev)
{
- struct net_device *dev = param;
- struct ocp_enet_private *fep = dev->priv;
- unsigned long flags;
- int n;
+ int i;
+ for (i = 0; i < NUM_RX_BUFF; ++i)
+ if (dev->rx_skb[i]) {
+ dev->rx_desc[i].ctrl = 0;
+ dev_kfree_skb(dev->rx_skb[i]);
+ dev->rx_skb[i] = NULL;
+ dev->rx_desc[i].data_ptr = 0;
+ }
- spin_lock_irqsave(&fep->lock, flags);
- if ((n = emac_rx_clean(dev)) != fep->rx_slot)
- emac_rx_fill(dev, n);
- spin_unlock_irqrestore(&fep->lock, flags);
+ if (dev->rx_sg_skb) {
+ dev_kfree_skb(dev->rx_sg_skb);
+ dev->rx_sg_skb = NULL;
+ }
}
-/*
- * This interrupt should never occurr, we don't program
- * the MAL for contiunous mode.
- */
-static void emac_txde_dev(void *param, u32 chanmask)
+static inline int emac_alloc_rx_skb(struct ocp_enet_private *dev, int slot,
+ int flags)
{
- struct net_device *dev = param;
- struct ocp_enet_private *fep = dev->priv;
+ struct sk_buff *skb = alloc_skb(dev->rx_skb_size, flags);
+ if (unlikely(!skb))
+ return -ENOMEM;
- printk(KERN_WARNING "%s: transmit descriptor error\n", dev->name);
+ dev->rx_skb[slot] = skb;
+ dev->rx_desc[slot].data_len = 0;
- emac_mac_dump(dev);
- emac_mal_dump(dev);
+ skb_reserve(skb, EMAC_RX_SKB_HEADROOM + 2);
+ dev->rx_desc[slot].data_ptr =
+ dma_map_single(dev->ldev, skb->data - 2, dev->rx_sync_size,
+ DMA_FROM_DEVICE) + 2;
+ barrier();
+ dev->rx_desc[slot].ctrl = MAL_RX_CTRL_EMPTY |
+ (slot == (NUM_RX_BUFF - 1) ? MAL_RX_CTRL_WRAP : 0);
- /* Reenable the transmit channel */
- mal_enable_tx_channels(fep->mal, fep->commac.tx_chan_mask);
+ return 0;
}
-/*
- * This interrupt should be very rare at best. This occurs when
- * the hardware has a problem with the receive descriptors. The manual
- * states that it occurs when the hardware cannot the receive descriptor
- * empty bit is not set. The recovery mechanism will be to
- * traverse through the descriptors, handle any that are marked to be
- * handled and reinitialize each along the way. At that point the driver
- * will be restarted.
- */
-static void emac_rxde_dev(void *param, u32 chanmask)
+static void emac_print_link_status(struct ocp_enet_private *dev)
{
- struct net_device *dev = param;
- struct ocp_enet_private *fep = dev->priv;
- unsigned long flags;
-
- if (net_ratelimit()) {
- printk(KERN_WARNING "%s: receive descriptor error\n",
- fep->ndev->name);
+ if (netif_carrier_ok(dev->ndev))
+ printk(KERN_INFO "%s: link is up, %d %s%s\n",
+ dev->ndev->name, dev->phy.speed,
+ dev->phy.duplex == DUPLEX_FULL ? "FDX" : "HDX",
+ dev->phy.pause ? ", pause enabled" :
+ dev->phy.asym_pause ? ", assymetric pause enabled" : "");
+ else
+ printk(KERN_INFO "%s: link is down\n", dev->ndev->name);
+}
- emac_mac_dump(dev);
- emac_mal_dump(dev);
- emac_desc_dump(dev);
+/* Process ctx, rtnl_lock semaphore */
+static int emac_open(struct net_device *ndev)
+{
+ struct ocp_enet_private *dev = ndev->priv;
+ struct ocp_func_emac_data *emacdata = dev->def->additions;
+ int err, i;
+
+ DBG("%d: open" NL, dev->def->index);
+
+ /* Setup error IRQ handler */
+ err = request_irq(dev->def->irq, emac_irq, 0, "EMAC", dev);
+ if (err) {
+ printk(KERN_ERR "%s: failed to request IRQ %d\n",
+ ndev->name, dev->def->irq);
+ return err;
}
- /* Disable RX channel */
- spin_lock_irqsave(&fep->lock, flags);
- mal_disable_rx_channels(fep->mal, fep->commac.rx_chan_mask);
-
- /* For now, charge the error against all emacs */
- fep->stats.rx_errors++;
-
- /* so do we have any good packets still? */
- emac_rx_clean(dev);
-
- /* When the interface is restarted it resets processing to the
- * first descriptor in the table.
- */
-
- fep->rx_slot = 0;
- emac_rx_fill(dev, 0);
+ /* Allocate RX ring */
+ for (i = 0; i < NUM_RX_BUFF; ++i)
+ if (emac_alloc_rx_skb(dev, i, GFP_KERNEL)) {
+ printk(KERN_ERR "%s: failed to allocate RX ring\n",
+ ndev->name);
+ goto oom;
+ }
- set_mal_dcrn(fep->mal, DCRN_MALRXEOBISR, fep->commac.rx_chan_mask);
- set_mal_dcrn(fep->mal, DCRN_MALRXDEIR, fep->commac.rx_chan_mask);
+ local_bh_disable();
+ dev->tx_cnt = dev->tx_slot = dev->ack_slot = dev->rx_slot =
+ dev->commac.rx_stopped = 0;
+ dev->rx_sg_skb = NULL;
+
+ if (dev->phy.address >= 0) {
+ int link_poll_interval;
+ if (dev->phy.def->ops->poll_link(&dev->phy)) {
+ dev->phy.def->ops->read_link(&dev->phy);
+ EMAC_RX_CLK_DEFAULT(dev->def->index);
+ netif_carrier_on(dev->ndev);
+ link_poll_interval = PHY_POLL_LINK_ON;
+ } else {
+ EMAC_RX_CLK_TX(dev->def->index);
+ netif_carrier_off(dev->ndev);
+ link_poll_interval = PHY_POLL_LINK_OFF;
+ }
+ mod_timer(&dev->link_timer, jiffies + link_poll_interval);
+ emac_print_link_status(dev);
+ } else
+ netif_carrier_on(dev->ndev);
+
+ emac_configure(dev);
+ mal_poll_add(dev->mal, &dev->commac);
+ mal_enable_tx_channel(dev->mal, emacdata->mal_tx_chan);
+ mal_set_rcbs(dev->mal, emacdata->mal_rx_chan, emac_rx_size(ndev->mtu));
+ mal_enable_rx_channel(dev->mal, emacdata->mal_rx_chan);
+ emac_tx_enable(dev);
+ emac_rx_enable(dev);
+ netif_start_queue(ndev);
+ local_bh_enable();
- /* Reenable the receive channels */
- mal_enable_rx_channels(fep->mal, fep->commac.rx_chan_mask);
- spin_unlock_irqrestore(&fep->lock, flags);
+ return 0;
+ oom:
+ emac_clean_rx_ring(dev);
+ free_irq(dev->def->irq, dev);
+ return -ENOMEM;
}
-static irqreturn_t
-emac_mac_irq(int irq, void *dev_instance, struct pt_regs *regs)
+/* BHs disabled */
+static int emac_link_differs(struct ocp_enet_private *dev)
{
- struct net_device *dev = dev_instance;
- struct ocp_enet_private *fep = dev->priv;
- emac_t *emacp = fep->emacp;
- unsigned long tmp_em0isr;
+ u32 r = in_be32(&dev->emacp->mr1);
- /* EMAC interrupt */
- tmp_em0isr = in_be32(&emacp->em0isr);
- if (tmp_em0isr & (EMAC_ISR_TE0 | EMAC_ISR_TE1)) {
- /* This error is a hard transmit error - could retransmit */
- fep->stats.tx_errors++;
+ int duplex = r & EMAC_MR1_FDE ? DUPLEX_FULL : DUPLEX_HALF;
+ int speed, pause, asym_pause;
- /* Reenable the transmit channel */
- mal_enable_tx_channels(fep->mal, fep->commac.tx_chan_mask);
+ if (r & (EMAC_MR1_MF_1000 | EMAC_MR1_MF_1000GPCS))
+ speed = SPEED_1000;
+ else if (r & EMAC_MR1_MF_100)
+ speed = SPEED_100;
+ else
+ speed = SPEED_10;
- } else {
- fep->stats.rx_errors++;
+ switch (r & (EMAC_MR1_EIFC | EMAC_MR1_APP)) {
+ case (EMAC_MR1_EIFC | EMAC_MR1_APP):
+ pause = 1;
+ asym_pause = 0;
+ break;
+ case EMAC_MR1_APP:
+ pause = 0;
+ asym_pause = 1;
+ break;
+ default:
+ pause = asym_pause = 0;
}
-
- if (tmp_em0isr & EMAC_ISR_RP)
- fep->stats.rx_length_errors++;
- if (tmp_em0isr & EMAC_ISR_ALE)
- fep->stats.rx_frame_errors++;
- if (tmp_em0isr & EMAC_ISR_BFCS)
- fep->stats.rx_crc_errors++;
- if (tmp_em0isr & EMAC_ISR_PTLE)
- fep->stats.rx_length_errors++;
- if (tmp_em0isr & EMAC_ISR_ORE)
- fep->stats.rx_length_errors++;
- if (tmp_em0isr & EMAC_ISR_TE0)
- fep->stats.tx_aborted_errors++;
-
- emac_err_dump(dev, tmp_em0isr);
-
- out_be32(&emacp->em0isr, tmp_em0isr);
-
- return IRQ_HANDLED;
+ return speed != dev->phy.speed || duplex != dev->phy.duplex ||
+ pause != dev->phy.pause || asym_pause != dev->phy.asym_pause;
}
-static int emac_start_xmit(struct sk_buff *skb, struct net_device *dev)
+/* BHs disabled */
+static void emac_link_timer(unsigned long data)
{
- unsigned short ctrl;
- unsigned long flags;
- struct ocp_enet_private *fep = dev->priv;
- emac_t *emacp = fep->emacp;
- int len = skb->len;
- unsigned int offset = 0, size, f, tx_slot_first;
- unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
+ struct ocp_enet_private *dev = (struct ocp_enet_private *)data;
+ int link_poll_interval;
- spin_lock_irqsave(&fep->lock, flags);
+ DBG2("%d: link timer" NL, dev->def->index);
- len -= skb->data_len;
+ if (dev->phy.def->ops->poll_link(&dev->phy)) {
+ if (!netif_carrier_ok(dev->ndev)) {
+ EMAC_RX_CLK_DEFAULT(dev->def->index);
- if ((fep->tx_cnt + nr_frags + len / DESC_BUF_SIZE + 1) > NUM_TX_BUFF) {
- PKT_DEBUG(("emac_start_xmit() stopping queue\n"));
- netif_stop_queue(dev);
- spin_unlock_irqrestore(&fep->lock, flags);
- return -EBUSY;
- }
+ /* Get new link parameters */
+ dev->phy.def->ops->read_link(&dev->phy);
- tx_slot_first = fep->tx_slot;
+ if (dev->tah_dev || emac_link_differs(dev))
+ emac_full_tx_reset(dev->ndev);
- while (len) {
- size = min(len, DESC_BUF_SIZE);
-
- fep->tx_desc[fep->tx_slot].data_len = (short)size;
- fep->tx_desc[fep->tx_slot].data_ptr =
- (unsigned char *)dma_map_single(&fep->ocpdev->dev,
- (void *)((unsigned int)skb->
- data + offset),
- size, DMA_TO_DEVICE);
-
- ctrl = EMAC_TX_CTRL_DFLT;
- if (fep->tx_slot != tx_slot_first)
- ctrl |= MAL_TX_CTRL_READY;
- if ((NUM_TX_BUFF - 1) == fep->tx_slot)
- ctrl |= MAL_TX_CTRL_WRAP;
- if (!nr_frags && (len == size)) {
- ctrl |= MAL_TX_CTRL_LAST;
- fep->tx_skb[fep->tx_slot] = skb;
+ netif_carrier_on(dev->ndev);
+ emac_print_link_status(dev);
+ }
+ link_poll_interval = PHY_POLL_LINK_ON;
+ } else {
+ if (netif_carrier_ok(dev->ndev)) {
+ EMAC_RX_CLK_TX(dev->def->index);
+#if defined(CONFIG_IBM_EMAC_PHY_RX_CLK_FIX)
+ emac_reinitialize(dev);
+#endif
+ netif_carrier_off(dev->ndev);
+ emac_print_link_status(dev);
}
- if (skb->ip_summed == CHECKSUM_HW)
- ctrl |= EMAC_TX_CTRL_TAH_CSUM;
- fep->tx_desc[fep->tx_slot].ctrl = ctrl;
+ /* Retry reset if the previous attempt failed.
+ * This is needed mostly for CONFIG_IBM_EMAC_PHY_RX_CLK_FIX
+ * case, but I left it here because it shouldn't trigger for
+ * sane PHYs anyway.
+ */
+ if (unlikely(dev->reset_failed))
+ emac_reinitialize(dev);
- len -= size;
- offset += size;
+ link_poll_interval = PHY_POLL_LINK_OFF;
+ }
+ mod_timer(&dev->link_timer, jiffies + link_poll_interval);
+}
- /* Bump tx count */
- if (++fep->tx_cnt == NUM_TX_BUFF)
- netif_stop_queue(dev);
+/* BHs disabled */
+static void emac_force_link_update(struct ocp_enet_private *dev)
+{
+ netif_carrier_off(dev->ndev);
+ if (timer_pending(&dev->link_timer))
+ mod_timer(&dev->link_timer, jiffies + PHY_POLL_LINK_OFF);
+}
- /* Next descriptor */
- if (++fep->tx_slot == NUM_TX_BUFF)
- fep->tx_slot = 0;
- }
+/* Process ctx, rtnl_lock semaphore */
+static int emac_close(struct net_device *ndev)
+{
+ struct ocp_enet_private *dev = ndev->priv;
+ struct ocp_func_emac_data *emacdata = dev->def->additions;
- for (f = 0; f < nr_frags; f++) {
- struct skb_frag_struct *frag;
+ DBG("%d: close" NL, dev->def->index);
- frag = &skb_shinfo(skb)->frags[f];
- len = frag->size;
- offset = 0;
-
- while (len) {
- size = min(len, DESC_BUF_SIZE);
-
- dma_map_page(&fep->ocpdev->dev,
- frag->page,
- frag->page_offset + offset,
- size, DMA_TO_DEVICE);
-
- ctrl = EMAC_TX_CTRL_DFLT | MAL_TX_CTRL_READY;
- if ((NUM_TX_BUFF - 1) == fep->tx_slot)
- ctrl |= MAL_TX_CTRL_WRAP;
- if ((f == (nr_frags - 1)) && (len == size)) {
- ctrl |= MAL_TX_CTRL_LAST;
- fep->tx_skb[fep->tx_slot] = skb;
- }
+ local_bh_disable();
- if (skb->ip_summed == CHECKSUM_HW)
- ctrl |= EMAC_TX_CTRL_TAH_CSUM;
+ if (dev->phy.address >= 0)
+ del_timer_sync(&dev->link_timer);
- fep->tx_desc[fep->tx_slot].data_len = (short)size;
- fep->tx_desc[fep->tx_slot].data_ptr =
- (char *)((page_to_pfn(frag->page) << PAGE_SHIFT) +
- frag->page_offset + offset);
- fep->tx_desc[fep->tx_slot].ctrl = ctrl;
+ netif_stop_queue(ndev);
+ emac_rx_disable(dev);
+ emac_tx_disable(dev);
+ mal_disable_rx_channel(dev->mal, emacdata->mal_rx_chan);
+ mal_disable_tx_channel(dev->mal, emacdata->mal_tx_chan);
+ mal_poll_del(dev->mal, &dev->commac);
+ local_bh_enable();
- len -= size;
- offset += size;
+ emac_clean_tx_ring(dev);
+ emac_clean_rx_ring(dev);
+ free_irq(dev->def->irq, dev);
- /* Bump tx count */
- if (++fep->tx_cnt == NUM_TX_BUFF)
- netif_stop_queue(dev);
+ return 0;
+}
- /* Next descriptor */
- if (++fep->tx_slot == NUM_TX_BUFF)
- fep->tx_slot = 0;
- }
+static inline u16 emac_tx_csum(struct ocp_enet_private *dev,
+ struct sk_buff *skb)
+{
+#if defined(CONFIG_IBM_EMAC_TAH)
+ if (skb->ip_summed == CHECKSUM_HW) {
+ ++dev->stats.tx_packets_csum;
+ return EMAC_TX_CTRL_TAH_CSUM;
}
+#endif
+ return 0;
+}
- /*
- * Deferred set READY on first descriptor of packet to
- * avoid TX MAL race.
- */
- fep->tx_desc[tx_slot_first].ctrl |= MAL_TX_CTRL_READY;
-
- /* Send the packet out. */
- out_be32(&emacp->em0tmr0, EMAC_TMR0_XMIT);
+static inline int emac_xmit_finish(struct ocp_enet_private *dev, int len)
+{
+ struct emac_regs *p = dev->emacp;
+ struct net_device *ndev = dev->ndev;
- fep->stats.tx_packets++;
- fep->stats.tx_bytes += skb->len;
+ /* Send the packet out */
+ out_be32(&p->tmr0, EMAC_TMR0_XMIT);
- PKT_DEBUG(("emac_start_xmit() exitn"));
+ if (unlikely(++dev->tx_cnt == NUM_TX_BUFF)) {
+ netif_stop_queue(ndev);
+ DBG2("%d: stopped TX queue" NL, dev->def->index);
+ }
- spin_unlock_irqrestore(&fep->lock, flags);
+ ndev->trans_start = jiffies;
+ ++dev->stats.tx_packets;
+ dev->stats.tx_bytes += len;
return 0;
}
-static int emac_adjust_to_link(struct ocp_enet_private *fep)
+/* BHs disabled */
+static int emac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
{
- emac_t *emacp = fep->emacp;
- unsigned long mode_reg;
- int full_duplex, speed;
+ struct ocp_enet_private *dev = ndev->priv;
+ unsigned int len = skb->len;
+ int slot;
- full_duplex = 0;
- speed = SPEED_10;
+ u16 ctrl = EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP | MAL_TX_CTRL_READY |
+ MAL_TX_CTRL_LAST | emac_tx_csum(dev, skb);
- /* set mode register 1 defaults */
- mode_reg = EMAC_M1_DEFAULT;
-
- /* Read link mode on PHY */
- if (fep->phy_mii.def->ops->read_link(&fep->phy_mii) == 0) {
- /* If an error occurred, we don't deal with it yet */
- full_duplex = (fep->phy_mii.duplex == DUPLEX_FULL);
- speed = fep->phy_mii.speed;
+ slot = dev->tx_slot++;
+ if (dev->tx_slot == NUM_TX_BUFF) {
+ dev->tx_slot = 0;
+ ctrl |= MAL_TX_CTRL_WRAP;
}
+ DBG2("%d: xmit(%u) %d" NL, dev->def->index, len, slot);
- /* set speed (default is 10Mb) */
- switch (speed) {
- case SPEED_1000:
- mode_reg |= EMAC_M1_RFS_16K;
- if (fep->rgmii_dev) {
- struct ibm_ocp_rgmii *rgmii = RGMII_PRIV(fep->rgmii_dev);
-
- if ((rgmii->mode[fep->rgmii_input] == RTBI)
- || (rgmii->mode[fep->rgmii_input] == TBI))
- mode_reg |= EMAC_M1_MF_1000GPCS;
- else
- mode_reg |= EMAC_M1_MF_1000MBPS;
-
- emac_rgmii_port_speed(fep->rgmii_dev, fep->rgmii_input,
- 1000);
- }
- break;
- case SPEED_100:
- mode_reg |= EMAC_M1_MF_100MBPS | EMAC_M1_RFS_4K;
- if (fep->rgmii_dev)
- emac_rgmii_port_speed(fep->rgmii_dev, fep->rgmii_input,
- 100);
- if (fep->zmii_dev)
- emac_zmii_port_speed(fep->zmii_dev, fep->zmii_input,
- 100);
- break;
- case SPEED_10:
- default:
- mode_reg = (mode_reg & ~EMAC_M1_MF_100MBPS) | EMAC_M1_RFS_4K;
- if (fep->rgmii_dev)
- emac_rgmii_port_speed(fep->rgmii_dev, fep->rgmii_input,
- 10);
- if (fep->zmii_dev)
- emac_zmii_port_speed(fep->zmii_dev, fep->zmii_input,
- 10);
- }
-
- if (full_duplex)
- mode_reg |= EMAC_M1_FDE | EMAC_M1_EIFC | EMAC_M1_IST;
- else
- mode_reg &= ~(EMAC_M1_FDE | EMAC_M1_EIFC | EMAC_M1_ILE);
+ dev->tx_skb[slot] = skb;
+ dev->tx_desc[slot].data_ptr = dma_map_single(dev->ldev, skb->data, len,
+ DMA_TO_DEVICE);
+ dev->tx_desc[slot].data_len = (u16) len;
+ barrier();
+ dev->tx_desc[slot].ctrl = ctrl;
- LINK_DEBUG(("%s: adjust to link, speed: %d, duplex: %d, opened: %d\n",
- fep->ndev->name, speed, full_duplex, fep->opened));
-
- printk(KERN_INFO "%s: Speed: %d, %s duplex.\n",
- fep->ndev->name, speed, full_duplex ? "Full" : "Half");
- if (fep->opened)
- out_be32(&emacp->em0mr1, mode_reg);
-
- return 0;
+ return emac_xmit_finish(dev, len);
}
-static int emac_set_mac_address(struct net_device *ndev, void *p)
+#if defined(CONFIG_IBM_EMAC_TAH)
+static inline int emac_xmit_split(struct ocp_enet_private *dev, int slot,
+ u32 pd, int len, int last, u16 base_ctrl)
{
- struct ocp_enet_private *fep = ndev->priv;
- emac_t *emacp = fep->emacp;
- struct sockaddr *addr = p;
+ while (1) {
+ u16 ctrl = base_ctrl;
+ int chunk = min(len, MAL_MAX_TX_SIZE);
+ len -= chunk;
- if (!is_valid_ether_addr(addr->sa_data))
- return -EADDRNOTAVAIL;
+ slot = (slot + 1) % NUM_TX_BUFF;
- memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len);
+ if (last && !len)
+ ctrl |= MAL_TX_CTRL_LAST;
+ if (slot == NUM_TX_BUFF - 1)
+ ctrl |= MAL_TX_CTRL_WRAP;
- /* set the high address */
- out_be32(&emacp->em0iahr,
- (fep->ndev->dev_addr[0] << 8) | fep->ndev->dev_addr[1]);
+ dev->tx_skb[slot] = NULL;
+ dev->tx_desc[slot].data_ptr = pd;
+ dev->tx_desc[slot].data_len = (u16) chunk;
+ dev->tx_desc[slot].ctrl = ctrl;
+ ++dev->tx_cnt;
- /* set the low address */
- out_be32(&emacp->em0ialr,
- (fep->ndev->dev_addr[2] << 24) | (fep->ndev->dev_addr[3] << 16)
- | (fep->ndev->dev_addr[4] << 8) | fep->ndev->dev_addr[5]);
+ if (!len)
+ break;
- return 0;
+ pd += chunk;
+ }
+ return slot;
}
-static int emac_change_mtu(struct net_device *dev, int new_mtu)
+/* BHs disabled (SG version for TAH equipped EMACs) */
+static int emac_start_xmit_sg(struct sk_buff *skb, struct net_device *ndev)
{
- struct ocp_enet_private *fep = dev->priv;
- int old_mtu = dev->mtu;
- unsigned long mode_reg;
- emac_t *emacp = fep->emacp;
- u32 em0mr0;
- int i, full;
- unsigned long flags;
+ struct ocp_enet_private *dev = ndev->priv;
+ int nr_frags = skb_shinfo(skb)->nr_frags;
+ int len = skb->len, chunk;
+ int slot, i;
+ u16 ctrl;
+ u32 pd;
- if ((new_mtu < EMAC_MIN_MTU) || (new_mtu > EMAC_MAX_MTU)) {
- printk(KERN_ERR
- "emac: Invalid MTU setting, MTU must be between %d and %d\n",
- EMAC_MIN_MTU, EMAC_MAX_MTU);
- return -EINVAL;
- }
+ /* This is common "fast" path */
+ if (likely(!nr_frags && len <= MAL_MAX_TX_SIZE))
+ return emac_start_xmit(skb, ndev);
- if (old_mtu != new_mtu && netif_running(dev)) {
- /* Stop rx engine */
- em0mr0 = in_be32(&emacp->em0mr0);
- out_be32(&emacp->em0mr0, em0mr0 & ~EMAC_M0_RXE);
-
- /* Wait for descriptors to be empty */
- do {
- full = 0;
- for (i = 0; i < NUM_RX_BUFF; i++)
- if (!(fep->rx_desc[i].ctrl & MAL_RX_CTRL_EMPTY)) {
- printk(KERN_NOTICE
- "emac: RX ring is still full\n");
- full = 1;
- }
- } while (full);
-
- spin_lock_irqsave(&fep->lock, flags);
-
- mal_disable_rx_channels(fep->mal, fep->commac.rx_chan_mask);
-
- /* Destroy all old rx skbs */
- for (i = 0; i < NUM_RX_BUFF; i++) {
- dma_unmap_single(&fep->ocpdev->dev,
- fep->rx_desc[i].data_ptr,
- fep->rx_desc[i].data_len,
- DMA_FROM_DEVICE);
- dev_kfree_skb(fep->rx_skb[i]);
- fep->rx_skb[i] = NULL;
- }
+ len -= skb->data_len;
- /* Set new rx_buffer_size, jumbo cap, and advertise new mtu */
- mode_reg = in_be32(&emacp->em0mr1);
- if (new_mtu > ENET_DEF_MTU_SIZE) {
- mode_reg |= EMAC_M1_JUMBO_ENABLE;
- fep->rx_buffer_size = EMAC_MAX_FRAME;
- } else {
- mode_reg &= ~EMAC_M1_JUMBO_ENABLE;
- fep->rx_buffer_size = ENET_DEF_BUF_SIZE;
- }
- dev->mtu = new_mtu;
- out_be32(&emacp->em0mr1, mode_reg);
+ /* Note, this is only an *estimation*, we can still run out of empty
+ * slots because of the additional fragmentation into
+ * MAL_MAX_TX_SIZE-sized chunks
+ */
+ if (unlikely(dev->tx_cnt + nr_frags + mal_tx_chunks(len) > NUM_TX_BUFF))
+ goto stop_queue;
+
+ ctrl = EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP | MAL_TX_CTRL_READY |
+ emac_tx_csum(dev, skb);
+ slot = dev->tx_slot;
+
+ /* skb data */
+ dev->tx_skb[slot] = NULL;
+ chunk = min(len, MAL_MAX_TX_SIZE);
+ dev->tx_desc[slot].data_ptr = pd =
+ dma_map_single(dev->ldev, skb->data, len, DMA_TO_DEVICE);
+ dev->tx_desc[slot].data_len = (u16) chunk;
+ len -= chunk;
+ if (unlikely(len))
+ slot = emac_xmit_split(dev, slot, pd + chunk, len, !nr_frags,
+ ctrl);
+ /* skb fragments */
+ for (i = 0; i < nr_frags; ++i) {
+ struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i];
+ len = frag->size;
- /* Re-init rx skbs */
- fep->rx_slot = 0;
- emac_rx_fill(dev, 0);
+ if (unlikely(dev->tx_cnt + mal_tx_chunks(len) >= NUM_TX_BUFF))
+ goto undo_frame;
- /* Restart the rx engine */
- mal_enable_rx_channels(fep->mal, fep->commac.rx_chan_mask);
- out_be32(&emacp->em0mr0, em0mr0 | EMAC_M0_RXE);
+ pd = dma_map_page(dev->ldev, frag->page, frag->page_offset, len,
+ DMA_TO_DEVICE);
- spin_unlock_irqrestore(&fep->lock, flags);
+ slot = emac_xmit_split(dev, slot, pd, len, i == nr_frags - 1,
+ ctrl);
}
- return 0;
-}
+ DBG2("%d: xmit_sg(%u) %d - %d" NL, dev->def->index, skb->len,
+ dev->tx_slot, slot);
-static void __emac_set_multicast_list(struct net_device *dev)
-{
- struct ocp_enet_private *fep = dev->priv;
- emac_t *emacp = fep->emacp;
- u32 rmr = in_be32(&emacp->em0rmr);
+ /* Attach skb to the last slot so we don't release it too early */
+ dev->tx_skb[slot] = skb;
- /* First clear all special bits, they can be set later */
- rmr &= ~(EMAC_RMR_PME | EMAC_RMR_PMME | EMAC_RMR_MAE);
+ /* Send the packet out */
+ if (dev->tx_slot == NUM_TX_BUFF - 1)
+ ctrl |= MAL_TX_CTRL_WRAP;
+ barrier();
+ dev->tx_desc[dev->tx_slot].ctrl = ctrl;
+ dev->tx_slot = (slot + 1) % NUM_TX_BUFF;
- if (dev->flags & IFF_PROMISC) {
- rmr |= EMAC_RMR_PME;
- } else if (dev->flags & IFF_ALLMULTI || 32 < dev->mc_count) {
- /*
- * Must be setting up to use multicast
- * Now check for promiscuous multicast
- */
- rmr |= EMAC_RMR_PMME;
- } else if (dev->flags & IFF_MULTICAST && 0 < dev->mc_count) {
- unsigned short em0gaht[4] = { 0, 0, 0, 0 };
- struct dev_mc_list *dmi;
-
- /* Need to hash on the multicast address. */
- for (dmi = dev->mc_list; dmi; dmi = dmi->next) {
- unsigned long mc_crc;
- unsigned int bit_number;
-
- mc_crc = ether_crc(6, (char *)dmi->dmi_addr);
- bit_number = 63 - (mc_crc >> 26); /* MSB: 0 LSB: 63 */
- em0gaht[bit_number >> 4] |=
- 0x8000 >> (bit_number & 0x0f);
- }
- emacp->em0gaht1 = em0gaht[0];
- emacp->em0gaht2 = em0gaht[1];
- emacp->em0gaht3 = em0gaht[2];
- emacp->em0gaht4 = em0gaht[3];
+ return emac_xmit_finish(dev, skb->len);
- /* Turn on multicast addressing */
- rmr |= EMAC_RMR_MAE;
+ undo_frame:
+ /* Well, too bad. Our previous estimation was overly optimistic.
+ * Undo everything.
+ */
+ while (slot != dev->tx_slot) {
+ dev->tx_desc[slot].ctrl = 0;
+ --dev->tx_cnt;
+ if (--slot < 0)
+ slot = NUM_TX_BUFF - 1;
}
- out_be32(&emacp->em0rmr, rmr);
+ ++dev->estats.tx_undo;
+
+ stop_queue:
+ netif_stop_queue(ndev);
+ DBG2("%d: stopped TX queue" NL, dev->def->index);
+ return 1;
}
+#else
+# define emac_start_xmit_sg emac_start_xmit
+#endif /* !defined(CONFIG_IBM_EMAC_TAH) */
-static int emac_init_tah(struct ocp_enet_private *fep)
+/* BHs disabled */
+static void emac_parse_tx_error(struct ocp_enet_private *dev, u16 ctrl)
{
- tah_t *tahp;
+ struct ibm_emac_error_stats *st = &dev->estats;
+ DBG("%d: BD TX error %04x" NL, dev->def->index, ctrl);
+
+ ++st->tx_bd_errors;
+ if (ctrl & EMAC_TX_ST_BFCS)
+ ++st->tx_bd_bad_fcs;
+ if (ctrl & EMAC_TX_ST_LCS)
+ ++st->tx_bd_carrier_loss;
+ if (ctrl & EMAC_TX_ST_ED)
+ ++st->tx_bd_excessive_deferral;
+ if (ctrl & EMAC_TX_ST_EC)
+ ++st->tx_bd_excessive_collisions;
+ if (ctrl & EMAC_TX_ST_LC)
+ ++st->tx_bd_late_collision;
+ if (ctrl & EMAC_TX_ST_MC)
+ ++st->tx_bd_multple_collisions;
+ if (ctrl & EMAC_TX_ST_SC)
+ ++st->tx_bd_single_collision;
+ if (ctrl & EMAC_TX_ST_UR)
+ ++st->tx_bd_underrun;
+ if (ctrl & EMAC_TX_ST_SQE)
+ ++st->tx_bd_sqe;
+}
- /* Initialize TAH and enable checksum verification */
- tahp = (tah_t *) ioremap(fep->tah_dev->def->paddr, sizeof(*tahp));
+static void emac_poll_tx(void *param)
+{
+ struct ocp_enet_private *dev = param;
+ DBG2("%d: poll_tx, %d %d" NL, dev->def->index, dev->tx_cnt,
+ dev->ack_slot);
+
+ if (dev->tx_cnt) {
+ u16 ctrl;
+ int slot = dev->ack_slot, n = 0;
+ again:
+ ctrl = dev->tx_desc[slot].ctrl;
+ if (!(ctrl & MAL_TX_CTRL_READY)) {
+ struct sk_buff *skb = dev->tx_skb[slot];
+ ++n;
+
+ if (skb) {
+ dev_kfree_skb(skb);
+ dev->tx_skb[slot] = NULL;
+ }
+ slot = (slot + 1) % NUM_TX_BUFF;
- if (tahp == NULL) {
- printk(KERN_ERR "tah%d: Cannot ioremap TAH registers!\n",
- fep->tah_dev->def->index);
+ if (unlikely(EMAC_IS_BAD_TX(ctrl)))
+ emac_parse_tx_error(dev, ctrl);
- return -ENOMEM;
- }
-
- out_be32(&tahp->tah_mr, TAH_MR_SR);
+ if (--dev->tx_cnt)
+ goto again;
+ }
+ if (n) {
+ dev->ack_slot = slot;
+ if (netif_queue_stopped(dev->ndev) &&
+ dev->tx_cnt < EMAC_TX_WAKEUP_THRESH)
+ netif_wake_queue(dev->ndev);
- /* wait for reset to complete */
- while (in_be32(&tahp->tah_mr) & TAH_MR_SR) ;
+ DBG2("%d: tx %d pkts" NL, dev->def->index, n);
+ }
+ }
+}
- /* 10KB TAH TX FIFO accomodates the max MTU of 9000 */
- out_be32(&tahp->tah_mr,
- TAH_MR_CVR | TAH_MR_ST_768 | TAH_MR_TFS_10KB | TAH_MR_DTFP |
- TAH_MR_DIG);
+static inline void emac_recycle_rx_skb(struct ocp_enet_private *dev, int slot,
+ int len)
+{
+ struct sk_buff *skb = dev->rx_skb[slot];
+ DBG2("%d: recycle %d %d" NL, dev->def->index, slot, len);
- iounmap(tahp);
+ if (len)
+ dma_map_single(dev->ldev, skb->data - 2,
+ EMAC_DMA_ALIGN(len + 2), DMA_FROM_DEVICE);
- return 0;
+ dev->rx_desc[slot].data_len = 0;
+ barrier();
+ dev->rx_desc[slot].ctrl = MAL_RX_CTRL_EMPTY |
+ (slot == (NUM_RX_BUFF - 1) ? MAL_RX_CTRL_WRAP : 0);
}
-static void emac_init_rings(struct net_device *dev)
+static void emac_parse_rx_error(struct ocp_enet_private *dev, u16 ctrl)
{
- struct ocp_enet_private *ep = dev->priv;
- int loop;
+ struct ibm_emac_error_stats *st = &dev->estats;
+ DBG("%d: BD RX error %04x" NL, dev->def->index, ctrl);
+
+ ++st->rx_bd_errors;
+ if (ctrl & EMAC_RX_ST_OE)
+ ++st->rx_bd_overrun;
+ if (ctrl & EMAC_RX_ST_BP)
+ ++st->rx_bd_bad_packet;
+ if (ctrl & EMAC_RX_ST_RP)
+ ++st->rx_bd_runt_packet;
+ if (ctrl & EMAC_RX_ST_SE)
+ ++st->rx_bd_short_event;
+ if (ctrl & EMAC_RX_ST_AE)
+ ++st->rx_bd_alignment_error;
+ if (ctrl & EMAC_RX_ST_BFCS)
+ ++st->rx_bd_bad_fcs;
+ if (ctrl & EMAC_RX_ST_PTL)
+ ++st->rx_bd_packet_too_long;
+ if (ctrl & EMAC_RX_ST_ORE)
+ ++st->rx_bd_out_of_range;
+ if (ctrl & EMAC_RX_ST_IRE)
+ ++st->rx_bd_in_range;
+}
- ep->tx_desc = (struct mal_descriptor *)((char *)ep->mal->tx_virt_addr +
- (ep->mal_tx_chan *
- MAL_DT_ALIGN));
- ep->rx_desc =
- (struct mal_descriptor *)((char *)ep->mal->rx_virt_addr +
- (ep->mal_rx_chan * MAL_DT_ALIGN));
+static inline void emac_rx_csum(struct ocp_enet_private *dev,
+ struct sk_buff *skb, u16 ctrl)
+{
+#if defined(CONFIG_IBM_EMAC_TAH)
+ if (!ctrl && dev->tah_dev) {
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ ++dev->stats.rx_packets_csum;
+ }
+#endif
+}
- /* Fill in the transmit descriptor ring. */
- for (loop = 0; loop < NUM_TX_BUFF; loop++) {
- if (ep->tx_skb[loop]) {
- dma_unmap_single(&ep->ocpdev->dev,
- ep->tx_desc[loop].data_ptr,
- ep->tx_desc[loop].data_len,
- DMA_TO_DEVICE);
- dev_kfree_skb_irq(ep->tx_skb[loop]);
+static inline int emac_rx_sg_append(struct ocp_enet_private *dev, int slot)
+{
+ if (likely(dev->rx_sg_skb != NULL)) {
+ int len = dev->rx_desc[slot].data_len;
+ int tot_len = dev->rx_sg_skb->len + len;
+
+ if (unlikely(tot_len + 2 > dev->rx_skb_size)) {
+ ++dev->estats.rx_dropped_mtu;
+ dev_kfree_skb(dev->rx_sg_skb);
+ dev->rx_sg_skb = NULL;
+ } else {
+ cacheable_memcpy(dev->rx_sg_skb->tail,
+ dev->rx_skb[slot]->data, len);
+ skb_put(dev->rx_sg_skb, len);
+ emac_recycle_rx_skb(dev, slot, len);
+ return 0;
}
- ep->tx_skb[loop] = NULL;
- ep->tx_desc[loop].ctrl = 0;
- ep->tx_desc[loop].data_len = 0;
- ep->tx_desc[loop].data_ptr = NULL;
- }
- ep->tx_desc[loop - 1].ctrl |= MAL_TX_CTRL_WRAP;
-
- /* Format the receive descriptor ring. */
- ep->rx_slot = 0;
- /* Default is MTU=1500 + Ethernet overhead */
- ep->rx_buffer_size = dev->mtu + ENET_HEADER_SIZE + ENET_FCS_SIZE;
- emac_rx_fill(dev, 0);
- if (ep->rx_slot != 0) {
- printk(KERN_ERR
- "%s: Not enough mem for RxChain durning Open?\n",
- dev->name);
- /*We couldn't fill the ring at startup?
- *We could clean up and fail to open but right now we will try to
- *carry on. It may be a sign of a bad NUM_RX_BUFF value
- */
}
-
- ep->tx_cnt = 0;
- ep->tx_slot = 0;
- ep->ack_slot = 0;
+ emac_recycle_rx_skb(dev, slot, 0);
+ return -1;
}
-static void emac_reset_configure(struct ocp_enet_private *fep)
+/* BHs disabled */
+static int emac_poll_rx(void *param, int budget)
{
- emac_t *emacp = fep->emacp;
- int i;
-
- mal_disable_tx_channels(fep->mal, fep->commac.tx_chan_mask);
- mal_disable_rx_channels(fep->mal, fep->commac.rx_chan_mask);
+ struct ocp_enet_private *dev = param;
+ int slot = dev->rx_slot, received = 0;
- /*
- * Check for a link, some PHYs don't provide a clock if
- * no link is present. Some EMACs will not come out of
- * soft reset without a PHY clock present.
- */
- if (fep->phy_mii.def->ops->poll_link(&fep->phy_mii)) {
- /* Reset the EMAC */
- out_be32(&emacp->em0mr0, EMAC_M0_SRST);
- udelay(20);
- for (i = 0; i < 100; i++) {
- if ((in_be32(&emacp->em0mr0) & EMAC_M0_SRST) == 0)
- break;
- udelay(10);
- }
-
- if (i >= 100) {
- printk(KERN_ERR "%s: Cannot reset EMAC\n",
- fep->ndev->name);
- return;
- }
- }
+ DBG2("%d: poll_rx(%d)" NL, dev->def->index, budget);
- /* Switch IRQs off for now */
- out_be32(&emacp->em0iser, 0);
+ again:
+ while (budget > 0) {
+ int len;
+ struct sk_buff *skb;
+ u16 ctrl = dev->rx_desc[slot].ctrl;
- /* Configure MAL rx channel */
- mal_set_rcbs(fep->mal, fep->mal_rx_chan, DESC_BUF_SIZE_REG);
+ if (ctrl & MAL_RX_CTRL_EMPTY)
+ break;
- /* set the high address */
- out_be32(&emacp->em0iahr,
- (fep->ndev->dev_addr[0] << 8) | fep->ndev->dev_addr[1]);
+ skb = dev->rx_skb[slot];
+ barrier();
+ len = dev->rx_desc[slot].data_len;
- /* set the low address */
- out_be32(&emacp->em0ialr,
- (fep->ndev->dev_addr[2] << 24) | (fep->ndev->dev_addr[3] << 16)
- | (fep->ndev->dev_addr[4] << 8) | fep->ndev->dev_addr[5]);
+ if (unlikely(!MAL_IS_SINGLE_RX(ctrl)))
+ goto sg;
- /* Adjust to link */
- if (netif_carrier_ok(fep->ndev))
- emac_adjust_to_link(fep);
+ ctrl &= EMAC_BAD_RX_MASK;
+ if (unlikely(ctrl && ctrl != EMAC_RX_TAH_BAD_CSUM)) {
+ emac_parse_rx_error(dev, ctrl);
+ ++dev->estats.rx_dropped_error;
+ emac_recycle_rx_skb(dev, slot, 0);
+ len = 0;
+ goto next;
+ }
- /* enable broadcast/individual address and RX FIFO defaults */
- out_be32(&emacp->em0rmr, EMAC_RMR_DEFAULT);
+ if (len && len < EMAC_RX_COPY_THRESH) {
+ struct sk_buff *copy_skb =
+ alloc_skb(len + EMAC_RX_SKB_HEADROOM + 2, GFP_ATOMIC);
+ if (unlikely(!copy_skb))
+ goto oom;
+
+ skb_reserve(copy_skb, EMAC_RX_SKB_HEADROOM + 2);
+ cacheable_memcpy(copy_skb->data - 2, skb->data - 2,
+ len + 2);
+ emac_recycle_rx_skb(dev, slot, len);
+ skb = copy_skb;
+ } else if (unlikely(emac_alloc_rx_skb(dev, slot, GFP_ATOMIC)))
+ goto oom;
+
+ skb_put(skb, len);
+ push_packet:
+ skb->dev = dev->ndev;
+ skb->protocol = eth_type_trans(skb, dev->ndev);
+ emac_rx_csum(dev, skb, ctrl);
+
+ if (unlikely(netif_receive_skb(skb) == NET_RX_DROP))
+ ++dev->estats.rx_dropped_stack;
+ next:
+ ++dev->stats.rx_packets;
+ skip:
+ dev->stats.rx_bytes += len;
+ slot = (slot + 1) % NUM_RX_BUFF;
+ --budget;
+ ++received;
+ continue;
+ sg:
+ if (ctrl & MAL_RX_CTRL_FIRST) {
+ BUG_ON(dev->rx_sg_skb);
+ if (unlikely(emac_alloc_rx_skb(dev, slot, GFP_ATOMIC))) {
+ DBG("%d: rx OOM %d" NL, dev->def->index, slot);
+ ++dev->estats.rx_dropped_oom;
+ emac_recycle_rx_skb(dev, slot, 0);
+ } else {
+ dev->rx_sg_skb = skb;
+ skb_put(skb, len);
+ }
+ } else if (!emac_rx_sg_append(dev, slot) &&
+ (ctrl & MAL_RX_CTRL_LAST)) {
+
+ skb = dev->rx_sg_skb;
+ dev->rx_sg_skb = NULL;
+
+ ctrl &= EMAC_BAD_RX_MASK;
+ if (unlikely(ctrl && ctrl != EMAC_RX_TAH_BAD_CSUM)) {
+ emac_parse_rx_error(dev, ctrl);
+ ++dev->estats.rx_dropped_error;
+ dev_kfree_skb(skb);
+ len = 0;
+ } else
+ goto push_packet;
+ }
+ goto skip;
+ oom:
+ DBG("%d: rx OOM %d" NL, dev->def->index, slot);
+ /* Drop the packet and recycle skb */
+ ++dev->estats.rx_dropped_oom;
+ emac_recycle_rx_skb(dev, slot, 0);
+ goto next;
+ }
- /* set transmit request threshold register */
- out_be32(&emacp->em0trtr, EMAC_TRTR_DEFAULT);
+ if (received) {
+ DBG2("%d: rx %d BDs" NL, dev->def->index, received);
+ dev->rx_slot = slot;
+ }
- /* Reconfigure multicast */
- __emac_set_multicast_list(fep->ndev);
+ if (unlikely(budget && dev->commac.rx_stopped)) {
+ struct ocp_func_emac_data *emacdata = dev->def->additions;
- /* Set receiver/transmitter defaults */
- out_be32(&emacp->em0rwmr, EMAC_RWMR_DEFAULT);
- out_be32(&emacp->em0tmr0, EMAC_TMR0_DEFAULT);
- out_be32(&emacp->em0tmr1, EMAC_TMR1_DEFAULT);
+ barrier();
+ if (!(dev->rx_desc[slot].ctrl & MAL_RX_CTRL_EMPTY)) {
+ DBG2("%d: rx restart" NL, dev->def->index);
+ received = 0;
+ goto again;
+ }
- /* set frame gap */
- out_be32(&emacp->em0ipgvr, CONFIG_IBM_EMAC_FGAP);
-
- /* set VLAN Tag Protocol Identifier */
- out_be32(&emacp->em0vtpid, 0x8100);
+ if (dev->rx_sg_skb) {
+ DBG2("%d: dropping partial rx packet" NL,
+ dev->def->index);
+ ++dev->estats.rx_dropped_error;
+ dev_kfree_skb(dev->rx_sg_skb);
+ dev->rx_sg_skb = NULL;
+ }
- /* Init ring buffers */
- emac_init_rings(fep->ndev);
+ dev->commac.rx_stopped = 0;
+ mal_enable_rx_channel(dev->mal, emacdata->mal_rx_chan);
+ emac_rx_enable(dev);
+ dev->rx_slot = 0;
+ }
+ return received;
}
-static void emac_kick(struct ocp_enet_private *fep)
+/* BHs disabled */
+static int emac_peek_rx(void *param)
{
- emac_t *emacp = fep->emacp;
- unsigned long emac_ier;
-
- emac_ier = EMAC_ISR_PP | EMAC_ISR_BP | EMAC_ISR_RP |
- EMAC_ISR_SE | EMAC_ISR_PTLE | EMAC_ISR_ALE |
- EMAC_ISR_BFCS | EMAC_ISR_ORE | EMAC_ISR_IRE;
+ struct ocp_enet_private *dev = param;
+ return !(dev->rx_desc[dev->rx_slot].ctrl & MAL_RX_CTRL_EMPTY);
+}
- out_be32(&emacp->em0iser, emac_ier);
+/* BHs disabled */
+static int emac_peek_rx_sg(void *param)
+{
+ struct ocp_enet_private *dev = param;
+ int slot = dev->rx_slot;
+ while (1) {
+ u16 ctrl = dev->rx_desc[slot].ctrl;
+ if (ctrl & MAL_RX_CTRL_EMPTY)
+ return 0;
+ else if (ctrl & MAL_RX_CTRL_LAST)
+ return 1;
- /* enable all MAL transmit and receive channels */
- mal_enable_tx_channels(fep->mal, fep->commac.tx_chan_mask);
- mal_enable_rx_channels(fep->mal, fep->commac.rx_chan_mask);
+ slot = (slot + 1) % NUM_RX_BUFF;
- /* set transmit and receive enable */
- out_be32(&emacp->em0mr0, EMAC_M0_TXE | EMAC_M0_RXE);
+ /* I'm just being paranoid here :) */
+ if (unlikely(slot == dev->rx_slot))
+ return 0;
+ }
}
-static void
-emac_start_link(struct ocp_enet_private *fep, struct ethtool_cmd *ep)
+/* Hard IRQ */
+static void emac_rxde(void *param)
{
- u32 advertise;
- int autoneg;
- int forced_speed;
- int forced_duplex;
+ struct ocp_enet_private *dev = param;
+ ++dev->estats.rx_stopped;
+ emac_rx_disable_async(dev);
+}
- /* Default advertise */
- advertise = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
- ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full |
- ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full;
- autoneg = fep->want_autoneg;
- forced_speed = fep->phy_mii.speed;
- forced_duplex = fep->phy_mii.duplex;
+/* Hard IRQ */
+static irqreturn_t emac_irq(int irq, void *dev_instance, struct pt_regs *regs)
+{
+ struct ocp_enet_private *dev = dev_instance;
+ struct emac_regs *p = dev->emacp;
+ struct ibm_emac_error_stats *st = &dev->estats;
+
+ u32 isr = in_be32(&p->isr);
+ out_be32(&p->isr, isr);
+
+ DBG("%d: isr = %08x" NL, dev->def->index, isr);
+
+ if (isr & EMAC_ISR_TXPE)
+ ++st->tx_parity;
+ if (isr & EMAC_ISR_RXPE)
+ ++st->rx_parity;
+ if (isr & EMAC_ISR_TXUE)
+ ++st->tx_underrun;
+ if (isr & EMAC_ISR_RXOE)
+ ++st->rx_fifo_overrun;
+ if (isr & EMAC_ISR_OVR)
+ ++st->rx_overrun;
+ if (isr & EMAC_ISR_BP)
+ ++st->rx_bad_packet;
+ if (isr & EMAC_ISR_RP)
+ ++st->rx_runt_packet;
+ if (isr & EMAC_ISR_SE)
+ ++st->rx_short_event;
+ if (isr & EMAC_ISR_ALE)
+ ++st->rx_alignment_error;
+ if (isr & EMAC_ISR_BFCS)
+ ++st->rx_bad_fcs;
+ if (isr & EMAC_ISR_PTLE)
+ ++st->rx_packet_too_long;
+ if (isr & EMAC_ISR_ORE)
+ ++st->rx_out_of_range;
+ if (isr & EMAC_ISR_IRE)
+ ++st->rx_in_range;
+ if (isr & EMAC_ISR_SQE)
+ ++st->tx_sqe;
+ if (isr & EMAC_ISR_TE)
+ ++st->tx_errors;
- /* Setup link parameters */
- if (ep) {
- if (ep->autoneg == AUTONEG_ENABLE) {
- advertise = ep->advertising;
- autoneg = 1;
- } else {
- autoneg = 0;
- forced_speed = ep->speed;
- forced_duplex = ep->duplex;
- }
- }
+ return IRQ_HANDLED;
+}
- /* Configure PHY & start aneg */
- fep->want_autoneg = autoneg;
- if (autoneg) {
- LINK_DEBUG(("%s: start link aneg, advertise: 0x%x\n",
- fep->ndev->name, advertise));
- fep->phy_mii.def->ops->setup_aneg(&fep->phy_mii, advertise);
- } else {
- LINK_DEBUG(("%s: start link forced, speed: %d, duplex: %d\n",
- fep->ndev->name, forced_speed, forced_duplex));
- fep->phy_mii.def->ops->setup_forced(&fep->phy_mii, forced_speed,
- forced_duplex);
- }
- fep->timer_ticks = 0;
- mod_timer(&fep->link_timer, jiffies + HZ);
+static struct net_device_stats *emac_stats(struct net_device *ndev)
+{
+ struct ocp_enet_private *dev = ndev->priv;
+ struct ibm_emac_stats *st = &dev->stats;
+ struct ibm_emac_error_stats *est = &dev->estats;
+ struct net_device_stats *nst = &dev->nstats;
+
+ DBG2("%d: stats" NL, dev->def->index);
+
+ /* Compute "legacy" statistics */
+ local_irq_disable();
+ nst->rx_packets = (unsigned long)st->rx_packets;
+ nst->rx_bytes = (unsigned long)st->rx_bytes;
+ nst->tx_packets = (unsigned long)st->tx_packets;
+ nst->tx_bytes = (unsigned long)st->tx_bytes;
+ nst->rx_dropped = (unsigned long)(est->rx_dropped_oom +
+ est->rx_dropped_error +
+ est->rx_dropped_resize +
+ est->rx_dropped_mtu);
+ nst->tx_dropped = (unsigned long)est->tx_dropped;
+
+ nst->rx_errors = (unsigned long)est->rx_bd_errors;
+ nst->rx_fifo_errors = (unsigned long)(est->rx_bd_overrun +
+ est->rx_fifo_overrun +
+ est->rx_overrun);
+ nst->rx_frame_errors = (unsigned long)(est->rx_bd_alignment_error +
+ est->rx_alignment_error);
+ nst->rx_crc_errors = (unsigned long)(est->rx_bd_bad_fcs +
+ est->rx_bad_fcs);
+ nst->rx_length_errors = (unsigned long)(est->rx_bd_runt_packet +
+ est->rx_bd_short_event +
+ est->rx_bd_packet_too_long +
+ est->rx_bd_out_of_range +
+ est->rx_bd_in_range +
+ est->rx_runt_packet +
+ est->rx_short_event +
+ est->rx_packet_too_long +
+ est->rx_out_of_range +
+ est->rx_in_range);
+
+ nst->tx_errors = (unsigned long)(est->tx_bd_errors + est->tx_errors);
+ nst->tx_fifo_errors = (unsigned long)(est->tx_bd_underrun +
+ est->tx_underrun);
+ nst->tx_carrier_errors = (unsigned long)est->tx_bd_carrier_loss;
+ nst->collisions = (unsigned long)(est->tx_bd_excessive_deferral +
+ est->tx_bd_excessive_collisions +
+ est->tx_bd_late_collision +
+ est->tx_bd_multple_collisions);
+ local_irq_enable();
+ return nst;
}
-static void emac_link_timer(unsigned long data)
+static void emac_remove(struct ocp_device *ocpdev)
{
- struct ocp_enet_private *fep = (struct ocp_enet_private *)data;
- int link;
+ struct ocp_enet_private *dev = ocp_get_drvdata(ocpdev);
- if (fep->going_away)
- return;
+ DBG("%d: remove" NL, dev->def->index);
- spin_lock_irq(&fep->lock);
+ ocp_set_drvdata(ocpdev, 0);
+ unregister_netdev(dev->ndev);
- link = fep->phy_mii.def->ops->poll_link(&fep->phy_mii);
- LINK_DEBUG(("%s: poll_link: %d\n", fep->ndev->name, link));
+ tah_fini(dev->tah_dev);
+ rgmii_fini(dev->rgmii_dev, dev->rgmii_input);
+ zmii_fini(dev->zmii_dev, dev->zmii_input);
- if (link == netif_carrier_ok(fep->ndev)) {
- if (!link && fep->want_autoneg && (++fep->timer_ticks) > 10)
- emac_start_link(fep, NULL);
- goto out;
- }
- printk(KERN_INFO "%s: Link is %s\n", fep->ndev->name,
- link ? "Up" : "Down");
- if (link) {
- netif_carrier_on(fep->ndev);
- /* Chip needs a full reset on config change. That sucks, so I
- * should ultimately move that to some tasklet to limit
- * latency peaks caused by this code
- */
- emac_reset_configure(fep);
- if (fep->opened)
- emac_kick(fep);
- } else {
- fep->timer_ticks = 0;
- netif_carrier_off(fep->ndev);
- }
- out:
- mod_timer(&fep->link_timer, jiffies + HZ);
- spin_unlock_irq(&fep->lock);
+ emac_dbg_register(dev->def->index, 0);
+
+ mal_unregister_commac(dev->mal, &dev->commac);
+ iounmap((void *)dev->emacp);
+ kfree(dev->ndev);
}
-static void emac_set_multicast_list(struct net_device *dev)
-{
- struct ocp_enet_private *fep = dev->priv;
+static struct mal_commac_ops emac_commac_ops = {
+ .poll_tx = &emac_poll_tx,
+ .poll_rx = &emac_poll_rx,
+ .peek_rx = &emac_peek_rx,
+ .rxde = &emac_rxde,
+};
- spin_lock_irq(&fep->lock);
- __emac_set_multicast_list(dev);
- spin_unlock_irq(&fep->lock);
-}
+static struct mal_commac_ops emac_commac_sg_ops = {
+ .poll_tx = &emac_poll_tx,
+ .poll_rx = &emac_poll_rx,
+ .peek_rx = &emac_peek_rx_sg,
+ .rxde = &emac_rxde,
+};
-static int emac_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
+/* Ethtool support */
+static int emac_ethtool_get_settings(struct net_device *ndev,
+ struct ethtool_cmd *cmd)
{
- struct ocp_enet_private *fep = ndev->priv;
+ struct ocp_enet_private *dev = ndev->priv;
- cmd->supported = fep->phy_mii.def->features;
+ cmd->supported = dev->phy.features;
cmd->port = PORT_MII;
- cmd->transceiver = XCVR_EXTERNAL;
- cmd->phy_address = fep->mii_phy_addr;
- spin_lock_irq(&fep->lock);
- cmd->autoneg = fep->want_autoneg;
- cmd->speed = fep->phy_mii.speed;
- cmd->duplex = fep->phy_mii.duplex;
- spin_unlock_irq(&fep->lock);
+ cmd->phy_address = dev->phy.address;
+ cmd->transceiver =
+ dev->phy.address >= 0 ? XCVR_EXTERNAL : XCVR_INTERNAL;
+
+ local_bh_disable();
+ cmd->advertising = dev->phy.advertising;
+ cmd->autoneg = dev->phy.autoneg;
+ cmd->speed = dev->phy.speed;
+ cmd->duplex = dev->phy.duplex;
+ local_bh_enable();
+
return 0;
}
-static int emac_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
+static int emac_ethtool_set_settings(struct net_device *ndev,
+ struct ethtool_cmd *cmd)
{
- struct ocp_enet_private *fep = ndev->priv;
- unsigned long features = fep->phy_mii.def->features;
+ struct ocp_enet_private *dev = ndev->priv;
+ u32 f = dev->phy.features;
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
+ DBG("%d: set_settings(%d, %d, %d, 0x%08x)" NL, dev->def->index,
+ cmd->autoneg, cmd->speed, cmd->duplex, cmd->advertising);
+ /* Basic sanity checks */
+ if (dev->phy.address < 0)
+ return -EOPNOTSUPP;
if (cmd->autoneg != AUTONEG_ENABLE && cmd->autoneg != AUTONEG_DISABLE)
return -EINVAL;
if (cmd->autoneg == AUTONEG_ENABLE && cmd->advertising == 0)
return -EINVAL;
if (cmd->duplex != DUPLEX_HALF && cmd->duplex != DUPLEX_FULL)
return -EINVAL;
- if (cmd->autoneg == AUTONEG_DISABLE)
+
+ if (cmd->autoneg == AUTONEG_DISABLE) {
switch (cmd->speed) {
case SPEED_10:
- if (cmd->duplex == DUPLEX_HALF &&
- (features & SUPPORTED_10baseT_Half) == 0)
+ if (cmd->duplex == DUPLEX_HALF
+ && !(f & SUPPORTED_10baseT_Half))
return -EINVAL;
- if (cmd->duplex == DUPLEX_FULL &&
- (features & SUPPORTED_10baseT_Full) == 0)
+ if (cmd->duplex == DUPLEX_FULL
+ && !(f & SUPPORTED_10baseT_Full))
return -EINVAL;
break;
case SPEED_100:
- if (cmd->duplex == DUPLEX_HALF &&
- (features & SUPPORTED_100baseT_Half) == 0)
+ if (cmd->duplex == DUPLEX_HALF
+ && !(f & SUPPORTED_100baseT_Half))
return -EINVAL;
- if (cmd->duplex == DUPLEX_FULL &&
- (features & SUPPORTED_100baseT_Full) == 0)
+ if (cmd->duplex == DUPLEX_FULL
+ && !(f & SUPPORTED_100baseT_Full))
return -EINVAL;
break;
case SPEED_1000:
- if (cmd->duplex == DUPLEX_HALF &&
- (features & SUPPORTED_1000baseT_Half) == 0)
+ if (cmd->duplex == DUPLEX_HALF
+ && !(f & SUPPORTED_1000baseT_Half))
return -EINVAL;
- if (cmd->duplex == DUPLEX_FULL &&
- (features & SUPPORTED_1000baseT_Full) == 0)
+ if (cmd->duplex == DUPLEX_FULL
+ && !(f & SUPPORTED_1000baseT_Full))
return -EINVAL;
break;
default:
return -EINVAL;
- } else if ((features & SUPPORTED_Autoneg) == 0)
- return -EINVAL;
- spin_lock_irq(&fep->lock);
- emac_start_link(fep, cmd);
- spin_unlock_irq(&fep->lock);
+ }
+
+ local_bh_disable();
+ dev->phy.def->ops->setup_forced(&dev->phy, cmd->speed,
+ cmd->duplex);
+
+ } else {
+ if (!(f & SUPPORTED_Autoneg))
+ return -EINVAL;
+
+ local_bh_disable();
+ dev->phy.def->ops->setup_aneg(&dev->phy,
+ (cmd->advertising & f) |
+ (dev->phy.advertising &
+ (ADVERTISED_Pause |
+ ADVERTISED_Asym_Pause)));
+ }
+ emac_force_link_update(dev);
+ local_bh_enable();
+
return 0;
}
-static void
-emac_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info)
+static void emac_ethtool_get_ringparam(struct net_device *ndev,
+ struct ethtool_ringparam *rp)
{
- struct ocp_enet_private *fep = ndev->priv;
-
- strcpy(info->driver, DRV_NAME);
- strcpy(info->version, DRV_VERSION);
- info->fw_version[0] = '\0';
- sprintf(info->bus_info, "IBM EMAC %d", fep->ocpdev->def->index);
- info->regdump_len = 0;
+ rp->rx_max_pending = rp->rx_pending = NUM_RX_BUFF;
+ rp->tx_max_pending = rp->tx_pending = NUM_TX_BUFF;
}
-static int emac_nway_reset(struct net_device *ndev)
+static void emac_ethtool_get_pauseparam(struct net_device *ndev,
+ struct ethtool_pauseparam *pp)
{
- struct ocp_enet_private *fep = ndev->priv;
+ struct ocp_enet_private *dev = ndev->priv;
+
+ local_bh_disable();
+ if ((dev->phy.features & SUPPORTED_Autoneg) &&
+ (dev->phy.advertising & (ADVERTISED_Pause | ADVERTISED_Asym_Pause)))
+ pp->autoneg = 1;
+
+ if (dev->phy.duplex == DUPLEX_FULL) {
+ if (dev->phy.pause)
+ pp->rx_pause = pp->tx_pause = 1;
+ else if (dev->phy.asym_pause)
+ pp->tx_pause = 1;
+ }
+ local_bh_enable();
+}
- if (!fep->want_autoneg)
- return -EINVAL;
- spin_lock_irq(&fep->lock);
- emac_start_link(fep, NULL);
- spin_unlock_irq(&fep->lock);
- return 0;
+static u32 emac_ethtool_get_rx_csum(struct net_device *ndev)
+{
+ struct ocp_enet_private *dev = ndev->priv;
+ return dev->tah_dev != 0;
}
-static u32 emac_get_link(struct net_device *ndev)
+static int emac_get_regs_len(struct ocp_enet_private *dev)
{
- return netif_carrier_ok(ndev);
+ return sizeof(struct emac_ethtool_regs_subhdr) + EMAC_ETHTOOL_REGS_SIZE;
}
-static struct ethtool_ops emac_ethtool_ops = {
- .get_settings = emac_get_settings,
- .set_settings = emac_set_settings,
- .get_drvinfo = emac_get_drvinfo,
- .nway_reset = emac_nway_reset,
- .get_link = emac_get_link
-};
+static int emac_ethtool_get_regs_len(struct net_device *ndev)
+{
+ struct ocp_enet_private *dev = ndev->priv;
+ return sizeof(struct emac_ethtool_regs_hdr) +
+ emac_get_regs_len(dev) + mal_get_regs_len(dev->mal) +
+ zmii_get_regs_len(dev->zmii_dev) +
+ rgmii_get_regs_len(dev->rgmii_dev) +
+ tah_get_regs_len(dev->tah_dev);
+}
-static int emac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+static void *emac_dump_regs(struct ocp_enet_private *dev, void *buf)
{
- struct ocp_enet_private *fep = dev->priv;
- uint16_t *data = (uint16_t *) & rq->ifr_ifru;
+ struct emac_ethtool_regs_subhdr *hdr = buf;
- switch (cmd) {
- case SIOCGMIIPHY:
- data[0] = fep->mii_phy_addr;
- /* Fall through */
- case SIOCGMIIREG:
- data[3] = emac_phy_read(dev, fep->mii_phy_addr, data[1]);
- return 0;
- case SIOCSMIIREG:
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
+ hdr->version = EMAC_ETHTOOL_REGS_VER;
+ hdr->index = dev->def->index;
+ memcpy_fromio(hdr + 1, dev->emacp, EMAC_ETHTOOL_REGS_SIZE);
+ return ((void *)(hdr + 1) + EMAC_ETHTOOL_REGS_SIZE);
+}
- emac_phy_write(dev, fep->mii_phy_addr, data[1], data[2]);
- return 0;
- default:
- return -EOPNOTSUPP;
+static void emac_ethtool_get_regs(struct net_device *ndev,
+ struct ethtool_regs *regs, void *buf)
+{
+ struct ocp_enet_private *dev = ndev->priv;
+ struct emac_ethtool_regs_hdr *hdr = buf;
+
+ hdr->components = 0;
+ buf = hdr + 1;
+
+ local_irq_disable();
+ buf = mal_dump_regs(dev->mal, buf);
+ buf = emac_dump_regs(dev, buf);
+ if (dev->zmii_dev) {
+ hdr->components |= EMAC_ETHTOOL_REGS_ZMII;
+ buf = zmii_dump_regs(dev->zmii_dev, buf);
}
+ if (dev->rgmii_dev) {
+ hdr->components |= EMAC_ETHTOOL_REGS_RGMII;
+ buf = rgmii_dump_regs(dev->rgmii_dev, buf);
+ }
+ if (dev->tah_dev) {
+ hdr->components |= EMAC_ETHTOOL_REGS_TAH;
+ buf = tah_dump_regs(dev->tah_dev, buf);
+ }
+ local_irq_enable();
}
-static int emac_open(struct net_device *dev)
+static int emac_ethtool_nway_reset(struct net_device *ndev)
{
- struct ocp_enet_private *fep = dev->priv;
- int rc;
+ struct ocp_enet_private *dev = ndev->priv;
+ int res = 0;
- spin_lock_irq(&fep->lock);
+ DBG("%d: nway_reset" NL, dev->def->index);
- fep->opened = 1;
- netif_carrier_off(dev);
+ if (dev->phy.address < 0)
+ return -EOPNOTSUPP;
- /* Reset & configure the chip */
- emac_reset_configure(fep);
+ local_bh_disable();
+ if (!dev->phy.autoneg) {
+ res = -EINVAL;
+ goto out;
+ }
- spin_unlock_irq(&fep->lock);
+ dev->phy.def->ops->setup_aneg(&dev->phy, dev->phy.advertising);
+ emac_force_link_update(dev);
- /* Request our interrupt lines */
- rc = request_irq(dev->irq, emac_mac_irq, 0, "IBM EMAC MAC", dev);
- if (rc != 0) {
- printk("dev->irq %d failed\n", dev->irq);
- goto bail;
- }
- /* Kick the chip rx & tx channels into life */
- spin_lock_irq(&fep->lock);
- emac_kick(fep);
- spin_unlock_irq(&fep->lock);
+ out:
+ local_bh_enable();
+ return res;
+}
- netif_start_queue(dev);
- bail:
- return rc;
+static int emac_ethtool_get_stats_count(struct net_device *ndev)
+{
+ return EMAC_ETHTOOL_STATS_COUNT;
}
-static int emac_close(struct net_device *dev)
+static void emac_ethtool_get_strings(struct net_device *ndev, u32 stringset,
+ u8 * buf)
{
- struct ocp_enet_private *fep = dev->priv;
- emac_t *emacp = fep->emacp;
+ if (stringset == ETH_SS_STATS)
+ memcpy(buf, &emac_stats_keys, sizeof(emac_stats_keys));
+}
- /* XXX Stop IRQ emitting here */
- spin_lock_irq(&fep->lock);
- fep->opened = 0;
- mal_disable_tx_channels(fep->mal, fep->commac.tx_chan_mask);
- mal_disable_rx_channels(fep->mal, fep->commac.rx_chan_mask);
- netif_carrier_off(dev);
- netif_stop_queue(dev);
+static void emac_ethtool_get_ethtool_stats(struct net_device *ndev,
+ struct ethtool_stats *estats,
+ u64 * tmp_stats)
+{
+ struct ocp_enet_private *dev = ndev->priv;
+ local_irq_disable();
+ memcpy(tmp_stats, &dev->stats, sizeof(dev->stats));
+ tmp_stats += sizeof(dev->stats) / sizeof(u64);
+ memcpy(tmp_stats, &dev->estats, sizeof(dev->estats));
+ local_irq_enable();
+}
- /*
- * Check for a link, some PHYs don't provide a clock if
- * no link is present. Some EMACs will not come out of
- * soft reset without a PHY clock present.
- */
- if (fep->phy_mii.def->ops->poll_link(&fep->phy_mii)) {
- out_be32(&emacp->em0mr0, EMAC_M0_SRST);
- udelay(10);
+static void emac_ethtool_get_drvinfo(struct net_device *ndev,
+ struct ethtool_drvinfo *info)
+{
+ struct ocp_enet_private *dev = ndev->priv;
- if (emacp->em0mr0 & EMAC_M0_SRST) {
- /*not sure what to do here hopefully it clears before another open */
- printk(KERN_ERR
- "%s: Phy SoftReset didn't clear, no link?\n",
- dev->name);
- }
- }
+ strcpy(info->driver, "ibm_emac");
+ strcpy(info->version, DRV_VERSION);
+ info->fw_version[0] = '\0';
+ sprintf(info->bus_info, "PPC 4xx EMAC %d", dev->def->index);
+ info->n_stats = emac_ethtool_get_stats_count(ndev);
+ info->regdump_len = emac_ethtool_get_regs_len(ndev);
+}
- /* Free the irq's */
- free_irq(dev->irq, dev);
+static struct ethtool_ops emac_ethtool_ops = {
+ .get_settings = emac_ethtool_get_settings,
+ .set_settings = emac_ethtool_set_settings,
+ .get_drvinfo = emac_ethtool_get_drvinfo,
- spin_unlock_irq(&fep->lock);
+ .get_regs_len = emac_ethtool_get_regs_len,
+ .get_regs = emac_ethtool_get_regs,
- return 0;
-}
+ .nway_reset = emac_ethtool_nway_reset,
-static void emac_remove(struct ocp_device *ocpdev)
-{
- struct net_device *dev = ocp_get_drvdata(ocpdev);
- struct ocp_enet_private *ep = dev->priv;
-
- /* FIXME: locking, races, ... */
- ep->going_away = 1;
- ocp_set_drvdata(ocpdev, NULL);
- if (ep->rgmii_dev)
- emac_close_rgmii(ep->rgmii_dev);
- if (ep->zmii_dev)
- emac_close_zmii(ep->zmii_dev);
-
- unregister_netdev(dev);
- del_timer_sync(&ep->link_timer);
- mal_unregister_commac(ep->mal, &ep->commac);
- iounmap((void *)ep->emacp);
- kfree(dev);
-}
-
-struct mal_commac_ops emac_commac_ops = {
- .txeob = &emac_txeob_dev,
- .txde = &emac_txde_dev,
- .rxeob = &emac_rxeob_dev,
- .rxde = &emac_rxde_dev,
+ .get_ringparam = emac_ethtool_get_ringparam,
+ .get_pauseparam = emac_ethtool_get_pauseparam,
+
+ .get_rx_csum = emac_ethtool_get_rx_csum,
+
+ .get_strings = emac_ethtool_get_strings,
+ .get_stats_count = emac_ethtool_get_stats_count,
+ .get_ethtool_stats = emac_ethtool_get_ethtool_stats,
+
+ .get_link = ethtool_op_get_link,
+ .get_tx_csum = ethtool_op_get_tx_csum,
+ .get_sg = ethtool_op_get_sg,
};
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void emac_netpoll(struct net_device *ndev)
+static int emac_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
{
- emac_rxeob_dev((void *)ndev, 0);
- emac_txeob_dev((void *)ndev, 0);
+ struct ocp_enet_private *dev = ndev->priv;
+ uint16_t *data = (uint16_t *) & rq->ifr_ifru;
+
+ DBG("%d: ioctl %08x" NL, dev->def->index, cmd);
+
+ if (dev->phy.address < 0)
+ return -EOPNOTSUPP;
+
+ switch (cmd) {
+ case SIOCGMIIPHY:
+ case SIOCDEVPRIVATE:
+ data[0] = dev->phy.address;
+ /* Fall through */
+ case SIOCGMIIREG:
+ case SIOCDEVPRIVATE + 1:
+ data[3] = emac_mdio_read(ndev, dev->phy.address, data[1]);
+ return 0;
+
+ case SIOCSMIIREG:
+ case SIOCDEVPRIVATE + 2:
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+ emac_mdio_write(ndev, dev->phy.address, data[1], data[2]);
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
}
-#endif
-static int emac_init_device(struct ocp_device *ocpdev, struct ibm_ocp_mal *mal)
+static int __init emac_probe(struct ocp_device *ocpdev)
{
- int deferred_init = 0;
- int rc = 0, i;
+ struct ocp_func_emac_data *emacdata = ocpdev->def->additions;
struct net_device *ndev;
- struct ocp_enet_private *ep;
- struct ocp_func_emac_data *emacdata;
- int commac_reg = 0;
- u32 phy_map;
+ struct ocp_device *maldev;
+ struct ocp_enet_private *dev;
+ int err, i;
+
+ DBG("%d: probe" NL, ocpdev->def->index);
- emacdata = (struct ocp_func_emac_data *)ocpdev->def->additions;
if (!emacdata) {
printk(KERN_ERR "emac%d: Missing additional data!\n",
ocpdev->def->index);
@@ -1738,304 +1936,312 @@ static int emac_init_device(struct ocp_device *ocpdev, struct ibm_ocp_mal *mal)
/* Allocate our net_device structure */
ndev = alloc_etherdev(sizeof(struct ocp_enet_private));
- if (ndev == NULL) {
- printk(KERN_ERR
- "emac%d: Could not allocate ethernet device.\n",
+ if (!ndev) {
+ printk(KERN_ERR "emac%d: could not allocate ethernet device!\n",
ocpdev->def->index);
return -ENOMEM;
}
- ep = ndev->priv;
- ep->ndev = ndev;
- ep->ocpdev = ocpdev;
- ndev->irq = ocpdev->def->irq;
- ep->wol_irq = emacdata->wol_irq;
- if (emacdata->mdio_idx >= 0) {
- if (emacdata->mdio_idx == ocpdev->def->index) {
- /* Set the common MDIO net_device */
- mdio_ndev = ndev;
- deferred_init = 1;
- }
- ep->mdio_dev = mdio_ndev;
- } else {
- ep->mdio_dev = ndev;
- }
+ dev = ndev->priv;
+ dev->ndev = ndev;
+ dev->ldev = &ocpdev->dev;
+ dev->def = ocpdev->def;
+ SET_MODULE_OWNER(ndev);
- ocp_set_drvdata(ocpdev, ndev);
-
- spin_lock_init(&ep->lock);
-
- /* Fill out MAL informations and register commac */
- ep->mal = mal;
- ep->mal_tx_chan = emacdata->mal_tx_chan;
- ep->mal_rx_chan = emacdata->mal_rx_chan;
- ep->commac.ops = &emac_commac_ops;
- ep->commac.dev = ndev;
- ep->commac.tx_chan_mask = MAL_CHAN_MASK(ep->mal_tx_chan);
- ep->commac.rx_chan_mask = MAL_CHAN_MASK(ep->mal_rx_chan);
- rc = mal_register_commac(ep->mal, &ep->commac);
- if (rc != 0)
- goto bail;
- commac_reg = 1;
-
- /* Map our MMIOs */
- ep->emacp = (emac_t *) ioremap(ocpdev->def->paddr, sizeof(emac_t));
-
- /* Check if we need to attach to a ZMII */
- if (emacdata->zmii_idx >= 0) {
- ep->zmii_input = emacdata->zmii_mux;
- ep->zmii_dev =
- ocp_find_device(OCP_ANY_ID, OCP_FUNC_ZMII,
- emacdata->zmii_idx);
- if (ep->zmii_dev == NULL)
- printk(KERN_WARNING
- "emac%d: ZMII %d requested but not found !\n",
- ocpdev->def->index, emacdata->zmii_idx);
- else if ((rc =
- emac_init_zmii(ep->zmii_dev, ep->zmii_input,
- emacdata->phy_mode)) != 0)
- goto bail;
+ /* Find MAL device we are connected to */
+ maldev =
+ ocp_find_device(OCP_VENDOR_IBM, OCP_FUNC_MAL, emacdata->mal_idx);
+ if (!maldev) {
+ printk(KERN_ERR "emac%d: unknown mal%d device!\n",
+ dev->def->index, emacdata->mal_idx);
+ err = -ENODEV;
+ goto out;
+ }
+ dev->mal = ocp_get_drvdata(maldev);
+ if (!dev->mal) {
+ printk(KERN_ERR "emac%d: mal%d hasn't been initialized yet!\n",
+ dev->def->index, emacdata->mal_idx);
+ err = -ENODEV;
+ goto out;
}
- /* Check if we need to attach to a RGMII */
- if (emacdata->rgmii_idx >= 0) {
- ep->rgmii_input = emacdata->rgmii_mux;
- ep->rgmii_dev =
- ocp_find_device(OCP_ANY_ID, OCP_FUNC_RGMII,
- emacdata->rgmii_idx);
- if (ep->rgmii_dev == NULL)
- printk(KERN_WARNING
- "emac%d: RGMII %d requested but not found !\n",
- ocpdev->def->index, emacdata->rgmii_idx);
- else if ((rc =
- emac_init_rgmii(ep->rgmii_dev, ep->rgmii_input,
- emacdata->phy_mode)) != 0)
- goto bail;
+ /* Register with MAL */
+ dev->commac.ops = &emac_commac_ops;
+ dev->commac.dev = dev;
+ dev->commac.tx_chan_mask = MAL_CHAN_MASK(emacdata->mal_tx_chan);
+ dev->commac.rx_chan_mask = MAL_CHAN_MASK(emacdata->mal_rx_chan);
+ err = mal_register_commac(dev->mal, &dev->commac);
+ if (err) {
+ printk(KERN_ERR "emac%d: failed to register with mal%d!\n",
+ dev->def->index, emacdata->mal_idx);
+ goto out;
+ }
+ dev->rx_skb_size = emac_rx_skb_size(ndev->mtu);
+ dev->rx_sync_size = emac_rx_sync_size(ndev->mtu);
+
+ /* Get pointers to BD rings */
+ dev->tx_desc =
+ dev->mal->bd_virt + mal_tx_bd_offset(dev->mal,
+ emacdata->mal_tx_chan);
+ dev->rx_desc =
+ dev->mal->bd_virt + mal_rx_bd_offset(dev->mal,
+ emacdata->mal_rx_chan);
+
+ DBG("%d: tx_desc %p" NL, ocpdev->def->index, dev->tx_desc);
+ DBG("%d: rx_desc %p" NL, ocpdev->def->index, dev->rx_desc);
+
+ /* Clean rings */
+ memset(dev->tx_desc, 0, NUM_TX_BUFF * sizeof(struct mal_descriptor));
+ memset(dev->rx_desc, 0, NUM_RX_BUFF * sizeof(struct mal_descriptor));
+
+ /* If we depend on another EMAC for MDIO, check whether it was probed already */
+ if (emacdata->mdio_idx >= 0 && emacdata->mdio_idx != ocpdev->def->index) {
+ struct ocp_device *mdiodev =
+ ocp_find_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC,
+ emacdata->mdio_idx);
+ if (!mdiodev) {
+ printk(KERN_ERR "emac%d: unknown emac%d device!\n",
+ dev->def->index, emacdata->mdio_idx);
+ err = -ENODEV;
+ goto out2;
+ }
+ dev->mdio_dev = ocp_get_drvdata(mdiodev);
+ if (!dev->mdio_dev) {
+ printk(KERN_ERR
+ "emac%d: emac%d hasn't been initialized yet!\n",
+ dev->def->index, emacdata->mdio_idx);
+ err = -ENODEV;
+ goto out2;
+ }
}
- /* Check if we need to attach to a TAH */
- if (emacdata->tah_idx >= 0) {
- ep->tah_dev =
- ocp_find_device(OCP_ANY_ID, OCP_FUNC_TAH,
- emacdata->tah_idx);
- if (ep->tah_dev == NULL)
- printk(KERN_WARNING
- "emac%d: TAH %d requested but not found !\n",
- ocpdev->def->index, emacdata->tah_idx);
- else if ((rc = emac_init_tah(ep)) != 0)
- goto bail;
+ /* Attach to ZMII, if needed */
+ if ((err = zmii_attach(dev)) != 0)
+ goto out2;
+
+ /* Attach to RGMII, if needed */
+ if ((err = rgmii_attach(dev)) != 0)
+ goto out3;
+
+ /* Attach to TAH, if needed */
+ if ((err = tah_attach(dev)) != 0)
+ goto out4;
+
+ /* Map EMAC regs */
+ dev->emacp =
+ (struct emac_regs *)ioremap(dev->def->paddr,
+ sizeof(struct emac_regs));
+ if (!dev->emacp) {
+ printk(KERN_ERR "emac%d: could not ioremap device registers!\n",
+ dev->def->index);
+ err = -ENOMEM;
+ goto out5;
}
- if (deferred_init) {
- if (!list_empty(&emac_init_list)) {
- struct list_head *entry;
- struct emac_def_dev *ddev;
+ /* Fill in MAC address */
+ for (i = 0; i < 6; ++i)
+ ndev->dev_addr[i] = emacdata->mac_addr[i];
- list_for_each(entry, &emac_init_list) {
- ddev =
- list_entry(entry, struct emac_def_dev,
- link);
- emac_init_device(ddev->ocpdev, ddev->mal);
- }
+ /* Set some link defaults before we can find out real parameters */
+ dev->phy.speed = SPEED_100;
+ dev->phy.duplex = DUPLEX_FULL;
+ dev->phy.autoneg = AUTONEG_DISABLE;
+ dev->phy.pause = dev->phy.asym_pause = 0;
+ init_timer(&dev->link_timer);
+ dev->link_timer.function = emac_link_timer;
+ dev->link_timer.data = (unsigned long)dev;
+
+ /* Find PHY if any */
+ dev->phy.dev = ndev;
+ dev->phy.mode = emacdata->phy_mode;
+ if (emacdata->phy_map != 0xffffffff) {
+ u32 phy_map = emacdata->phy_map | busy_phy_map;
+ u32 adv;
+
+ DBG("%d: PHY maps %08x %08x" NL, dev->def->index,
+ emacdata->phy_map, busy_phy_map);
+
+ EMAC_RX_CLK_TX(dev->def->index);
+
+ dev->phy.mdio_read = emac_mdio_read;
+ dev->phy.mdio_write = emac_mdio_write;
+
+ /* Configure EMAC with defaults so we can at least use MDIO
+ * This is needed mostly for 440GX
+ */
+ if (emac_phy_gpcs(dev->phy.mode)) {
+ /* XXX
+ * Make GPCS PHY address equal to EMAC index.
+ * We probably should take into account busy_phy_map
+ * and/or phy_map here.
+ */
+ dev->phy.address = dev->def->index;
}
- }
+
+ emac_configure(dev);
- /* Init link monitoring timer */
- init_timer(&ep->link_timer);
- ep->link_timer.function = emac_link_timer;
- ep->link_timer.data = (unsigned long)ep;
- ep->timer_ticks = 0;
-
- /* Fill up the mii_phy structure */
- ep->phy_mii.dev = ndev;
- ep->phy_mii.mdio_read = emac_phy_read;
- ep->phy_mii.mdio_write = emac_phy_write;
- ep->phy_mii.mode = emacdata->phy_mode;
-
- /* Find PHY */
- phy_map = emacdata->phy_map | busy_phy_map;
- for (i = 0; i <= 0x1f; i++, phy_map >>= 1) {
- if ((phy_map & 0x1) == 0) {
- int val = emac_phy_read(ndev, i, MII_BMCR);
- if (val != 0xffff && val != -1)
- break;
+ for (i = 0; i < 0x20; phy_map >>= 1, ++i)
+ if (!(phy_map & 1)) {
+ int r;
+ busy_phy_map |= 1 << i;
+
+ /* Quick check if there is a PHY at the address */
+ r = emac_mdio_read(dev->ndev, i, MII_BMCR);
+ if (r == 0xffff || r < 0)
+ continue;
+ if (!mii_phy_probe(&dev->phy, i))
+ break;
+ }
+ if (i == 0x20) {
+ printk(KERN_WARNING "emac%d: can't find PHY!\n",
+ dev->def->index);
+ goto out6;
}
- }
- if (i == 0x20) {
- printk(KERN_WARNING "emac%d: Can't find PHY.\n",
- ocpdev->def->index);
- rc = -ENODEV;
- goto bail;
- }
- busy_phy_map |= 1 << i;
- ep->mii_phy_addr = i;
- rc = mii_phy_probe(&ep->phy_mii, i);
- if (rc) {
- printk(KERN_WARNING "emac%d: Failed to probe PHY type.\n",
- ocpdev->def->index);
- rc = -ENODEV;
- goto bail;
- }
-
- /* Disable any PHY features not supported by the platform */
- ep->phy_mii.def->features &= ~emacdata->phy_feat_exc;
- /* Setup initial PHY config & startup aneg */
- if (ep->phy_mii.def->ops->init)
- ep->phy_mii.def->ops->init(&ep->phy_mii);
- netif_carrier_off(ndev);
- if (ep->phy_mii.def->features & SUPPORTED_Autoneg)
- ep->want_autoneg = 1;
- else {
- ep->want_autoneg = 0;
+ /* Init PHY */
+ if (dev->phy.def->ops->init)
+ dev->phy.def->ops->init(&dev->phy);
- /* Select highest supported speed/duplex */
- if (ep->phy_mii.def->features & SUPPORTED_1000baseT_Full) {
- ep->phy_mii.speed = SPEED_1000;
- ep->phy_mii.duplex = DUPLEX_FULL;
- } else if (ep->phy_mii.def->features &
- SUPPORTED_1000baseT_Half) {
- ep->phy_mii.speed = SPEED_1000;
- ep->phy_mii.duplex = DUPLEX_HALF;
- } else if (ep->phy_mii.def->features &
- SUPPORTED_100baseT_Full) {
- ep->phy_mii.speed = SPEED_100;
- ep->phy_mii.duplex = DUPLEX_FULL;
- } else if (ep->phy_mii.def->features &
- SUPPORTED_100baseT_Half) {
- ep->phy_mii.speed = SPEED_100;
- ep->phy_mii.duplex = DUPLEX_HALF;
- } else if (ep->phy_mii.def->features &
- SUPPORTED_10baseT_Full) {
- ep->phy_mii.speed = SPEED_10;
- ep->phy_mii.duplex = DUPLEX_FULL;
+ /* Disable any PHY features not supported by the platform */
+ dev->phy.def->features &= ~emacdata->phy_feat_exc;
+
+ /* Setup initial link parameters */
+ if (dev->phy.features & SUPPORTED_Autoneg) {
+ adv = dev->phy.features;
+#if !defined(CONFIG_40x)
+ adv |= ADVERTISED_Pause | ADVERTISED_Asym_Pause;
+#endif
+ /* Restart autonegotiation */
+ dev->phy.def->ops->setup_aneg(&dev->phy, adv);
} else {
- ep->phy_mii.speed = SPEED_10;
- ep->phy_mii.duplex = DUPLEX_HALF;
+ u32 f = dev->phy.def->features;
+ int speed = SPEED_10, fd = DUPLEX_HALF;
+
+ /* Select highest supported speed/duplex */
+ if (f & SUPPORTED_1000baseT_Full) {
+ speed = SPEED_1000;
+ fd = DUPLEX_FULL;
+ } else if (f & SUPPORTED_1000baseT_Half)
+ speed = SPEED_1000;
+ else if (f & SUPPORTED_100baseT_Full) {
+ speed = SPEED_100;
+ fd = DUPLEX_FULL;
+ } else if (f & SUPPORTED_100baseT_Half)
+ speed = SPEED_100;
+ else if (f & SUPPORTED_10baseT_Full)
+ fd = DUPLEX_FULL;
+
+ /* Force link parameters */
+ dev->phy.def->ops->setup_forced(&dev->phy, speed, fd);
}
- }
- emac_start_link(ep, NULL);
+ } else {
+ emac_reset(dev);
- /* read the MAC Address */
- for (i = 0; i < 6; i++)
- ndev->dev_addr[i] = emacdata->mac_addr[i];
+ /* PHY-less configuration.
+ * XXX I probably should move these settings to emacdata
+ */
+ dev->phy.address = -1;
+ dev->phy.features = SUPPORTED_100baseT_Full | SUPPORTED_MII;
+ dev->phy.pause = 1;
+ }
/* Fill in the driver function table */
ndev->open = &emac_open;
- ndev->hard_start_xmit = &emac_start_xmit;
+ if (dev->tah_dev) {
+ ndev->hard_start_xmit = &emac_start_xmit_sg;
+ ndev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
+ } else
+ ndev->hard_start_xmit = &emac_start_xmit;
+ ndev->tx_timeout = &emac_full_tx_reset;
+ ndev->watchdog_timeo = 5 * HZ;
ndev->stop = &emac_close;
ndev->get_stats = &emac_stats;
- if (emacdata->jumbo)
- ndev->change_mtu = &emac_change_mtu;
- ndev->set_mac_address = &emac_set_mac_address;
ndev->set_multicast_list = &emac_set_multicast_list;
ndev->do_ioctl = &emac_ioctl;
+ if (emac_phy_supports_gige(emacdata->phy_mode)) {
+ ndev->change_mtu = &emac_change_mtu;
+ dev->commac.ops = &emac_commac_sg_ops;
+ }
SET_ETHTOOL_OPS(ndev, &emac_ethtool_ops);
- if (emacdata->tah_idx >= 0)
- ndev->features = NETIF_F_IP_CSUM | NETIF_F_SG;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- ndev->poll_controller = emac_netpoll;
-#endif
- SET_MODULE_OWNER(ndev);
+ netif_carrier_off(ndev);
+ netif_stop_queue(ndev);
+
+ err = register_netdev(ndev);
+ if (err) {
+ printk(KERN_ERR "emac%d: failed to register net device (%d)!\n",
+ dev->def->index, err);
+ goto out6;
+ }
- rc = register_netdev(ndev);
- if (rc != 0)
- goto bail;
+ ocp_set_drvdata(ocpdev, dev);
- printk("%s: IBM emac, MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
- ndev->name,
+ printk("%s: emac%d, MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
+ ndev->name, dev->def->index,
ndev->dev_addr[0], ndev->dev_addr[1], ndev->dev_addr[2],
ndev->dev_addr[3], ndev->dev_addr[4], ndev->dev_addr[5]);
- printk(KERN_INFO "%s: Found %s PHY (0x%02x)\n",
- ndev->name, ep->phy_mii.def->name, ep->mii_phy_addr);
- bail:
- if (rc && commac_reg)
- mal_unregister_commac(ep->mal, &ep->commac);
- if (rc && ndev)
- kfree(ndev);
+ if (dev->phy.address >= 0)
+ printk("%s: found %s PHY (0x%02x)\n", ndev->name,
+ dev->phy.def->name, dev->phy.address);
- return rc;
-}
-
-static int emac_probe(struct ocp_device *ocpdev)
-{
- struct ocp_device *maldev;
- struct ibm_ocp_mal *mal;
- struct ocp_func_emac_data *emacdata;
-
- emacdata = (struct ocp_func_emac_data *)ocpdev->def->additions;
- if (emacdata == NULL) {
- printk(KERN_ERR "emac%d: Missing additional datas !\n",
- ocpdev->def->index);
- return -ENODEV;
- }
-
- /* Get the MAL device */
- maldev = ocp_find_device(OCP_ANY_ID, OCP_FUNC_MAL, emacdata->mal_idx);
- if (maldev == NULL) {
- printk("No maldev\n");
- return -ENODEV;
- }
- /*
- * Get MAL driver data, it must be here due to link order.
- * When the driver is modularized, symbol dependencies will
- * ensure the MAL driver is already present if built as a
- * module.
- */
- mal = (struct ibm_ocp_mal *)ocp_get_drvdata(maldev);
- if (mal == NULL) {
- printk("No maldrv\n");
- return -ENODEV;
- }
-
- /* If we depend on another EMAC for MDIO, wait for it to show up */
- if (emacdata->mdio_idx >= 0 &&
- (emacdata->mdio_idx != ocpdev->def->index) && !mdio_ndev) {
- struct emac_def_dev *ddev;
- /* Add this index to the deferred init table */
- ddev = kmalloc(sizeof(struct emac_def_dev), GFP_KERNEL);
- ddev->ocpdev = ocpdev;
- ddev->mal = mal;
- list_add_tail(&ddev->link, &emac_init_list);
- } else {
- emac_init_device(ocpdev, mal);
- }
+ emac_dbg_register(dev->def->index, dev);
return 0;
+ out6:
+ iounmap((void *)dev->emacp);
+ out5:
+ tah_fini(dev->tah_dev);
+ out4:
+ rgmii_fini(dev->rgmii_dev, dev->rgmii_input);
+ out3:
+ zmii_fini(dev->zmii_dev, dev->zmii_input);
+ out2:
+ mal_unregister_commac(dev->mal, &dev->commac);
+ out:
+ kfree(ndev);
+ return err;
}
-/* Structure for a device driver */
static struct ocp_device_id emac_ids[] = {
- {.vendor = OCP_ANY_ID,.function = OCP_FUNC_EMAC},
- {.vendor = OCP_VENDOR_INVALID}
+ { .vendor = OCP_VENDOR_IBM, .function = OCP_FUNC_EMAC },
+ { .vendor = OCP_VENDOR_INVALID}
};
static struct ocp_driver emac_driver = {
.name = "emac",
.id_table = emac_ids,
-
.probe = emac_probe,
.remove = emac_remove,
};
static int __init emac_init(void)
{
- printk(KERN_INFO DRV_NAME ": " DRV_DESC ", version " DRV_VERSION "\n");
- printk(KERN_INFO "Maintained by " DRV_AUTHOR "\n");
+ printk(KERN_INFO DRV_DESC ", version " DRV_VERSION "\n");
+
+ DBG(": init" NL);
- if (skb_res > 2) {
- printk(KERN_WARNING "Invalid skb_res: %d, cropping to 2\n",
- skb_res);
- skb_res = 2;
+ if (mal_init())
+ return -ENODEV;
+
+ EMAC_CLK_INTERNAL;
+ if (ocp_register_driver(&emac_driver)) {
+ EMAC_CLK_EXTERNAL;
+ ocp_unregister_driver(&emac_driver);
+ mal_exit();
+ return -ENODEV;
}
+ EMAC_CLK_EXTERNAL;
- return ocp_register_driver(&emac_driver);
+ emac_init_debug();
+ return 0;
}
static void __exit emac_exit(void)
{
+ DBG(": exit" NL);
ocp_unregister_driver(&emac_driver);
+ mal_exit();
+ emac_fini_debug();
}
module_init(emac_init);
diff --git a/drivers/net/ibm_emac/ibm_emac_core.h b/drivers/net/ibm_emac/ibm_emac_core.h
index 97e6e1ea8c89..e9b44d030ac3 100644
--- a/drivers/net/ibm_emac/ibm_emac_core.h
+++ b/drivers/net/ibm_emac/ibm_emac_core.h
@@ -1,146 +1,221 @@
/*
- * ibm_emac_core.h
+ * drivers/net/ibm_emac/ibm_emac_core.h
*
- * Ethernet driver for the built in ethernet on the IBM 405 PowerPC
- * processor.
+ * Driver for PowerPC 4xx on-chip ethernet controller.
*
- * Armin Kuster akuster@mvista.com
- * Sept, 2001
+ * Copyright (c) 2004, 2005 Zultys Technologies.
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
*
- * Orignial driver
- * Johnnie Peters
- * jpeters@mvista.com
- *
- * Copyright 2000 MontaVista Softare Inc.
+ * Based on original work by
+ * Armin Kuster <akuster@mvista.com>
+ * Johnnie Peters <jpeters@mvista.com>
+ * Copyright 2000, 2001 MontaVista Softare 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.
+ *
*/
+#ifndef __IBM_EMAC_CORE_H_
+#define __IBM_EMAC_CORE_H_
-#ifndef _IBM_EMAC_CORE_H_
-#define _IBM_EMAC_CORE_H_
-
+#include <linux/config.h>
#include <linux/netdevice.h>
+#include <linux/dma-mapping.h>
#include <asm/ocp.h>
-#include <asm/mmu.h> /* For phys_addr_t */
#include "ibm_emac.h"
#include "ibm_emac_phy.h"
-#include "ibm_emac_rgmii.h"
#include "ibm_emac_zmii.h"
+#include "ibm_emac_rgmii.h"
#include "ibm_emac_mal.h"
#include "ibm_emac_tah.h"
-#ifndef CONFIG_IBM_EMAC_TXB
-#define NUM_TX_BUFF 64
-#define NUM_RX_BUFF 64
-#else
-#define NUM_TX_BUFF CONFIG_IBM_EMAC_TXB
-#define NUM_RX_BUFF CONFIG_IBM_EMAC_RXB
-#endif
+#define NUM_TX_BUFF CONFIG_IBM_EMAC_TXB
+#define NUM_RX_BUFF CONFIG_IBM_EMAC_RXB
-/* This does 16 byte alignment, exactly what we need.
- * The packet length includes FCS, but we don't want to
- * include that when passing upstream as it messes up
- * bridging applications.
- */
-#ifndef CONFIG_IBM_EMAC_SKBRES
-#define SKB_RES 2
-#else
-#define SKB_RES CONFIG_IBM_EMAC_SKBRES
+/* Simple sanity check */
+#if NUM_TX_BUFF > 256 || NUM_RX_BUFF > 256
+#error Invalid number of buffer descriptors (greater than 256)
#endif
-/* Note about alignement. alloc_skb() returns a cache line
- * aligned buffer. However, dev_alloc_skb() will add 16 more
- * bytes and "reserve" them, so our buffer will actually end
- * on a half cache line. What we do is to use directly
- * alloc_skb, allocate 16 more bytes to match the total amount
- * allocated by dev_alloc_skb(), but we don't reserve.
+// XXX
+#define EMAC_MIN_MTU 46
+#define EMAC_MAX_MTU 9000
+
+/* Maximum L2 header length (VLAN tagged, no FCS) */
+#define EMAC_MTU_OVERHEAD (6 * 2 + 2 + 4)
+
+/* RX BD size for the given MTU */
+static inline int emac_rx_size(int mtu)
+{
+ if (mtu > ETH_DATA_LEN)
+ return MAL_MAX_RX_SIZE;
+ else
+ return mal_rx_size(ETH_DATA_LEN + EMAC_MTU_OVERHEAD);
+}
+
+#define EMAC_DMA_ALIGN(x) ALIGN((x), dma_get_cache_alignment())
+
+#define EMAC_RX_SKB_HEADROOM \
+ EMAC_DMA_ALIGN(CONFIG_IBM_EMAC_RX_SKB_HEADROOM)
+
+/* Size of RX skb for the given MTU */
+static inline int emac_rx_skb_size(int mtu)
+{
+ int size = max(mtu + EMAC_MTU_OVERHEAD, emac_rx_size(mtu));
+ return EMAC_DMA_ALIGN(size + 2) + EMAC_RX_SKB_HEADROOM;
+}
+
+/* RX DMA sync size */
+static inline int emac_rx_sync_size(int mtu)
+{
+ return EMAC_DMA_ALIGN(emac_rx_size(mtu) + 2);
+}
+
+/* Driver statistcs is split into two parts to make it more cache friendly:
+ * - normal statistics (packet count, etc)
+ * - error statistics
+ *
+ * When statistics is requested by ethtool, these parts are concatenated,
+ * normal one goes first.
+ *
+ * Please, keep these structures in sync with emac_stats_keys.
*/
-#define MAX_NUM_BUF_DESC 255
-#define DESC_BUF_SIZE 4080 /* max 4096-16 */
-#define DESC_BUF_SIZE_REG (DESC_BUF_SIZE / 16)
-
-/* Transmitter timeout. */
-#define TX_TIMEOUT (2*HZ)
-
-/* MDIO latency delay */
-#define MDIO_DELAY 250
-
-/* Power managment shift registers */
-#define IBM_CPM_EMMII 0 /* Shift value for MII */
-#define IBM_CPM_EMRX 1 /* Shift value for recv */
-#define IBM_CPM_EMTX 2 /* Shift value for MAC */
-#define IBM_CPM_EMAC(x) (((x)>>IBM_CPM_EMMII) | ((x)>>IBM_CPM_EMRX) | ((x)>>IBM_CPM_EMTX))
-
-#define ENET_HEADER_SIZE 14
-#define ENET_FCS_SIZE 4
-#define ENET_DEF_MTU_SIZE 1500
-#define ENET_DEF_BUF_SIZE (ENET_DEF_MTU_SIZE + ENET_HEADER_SIZE + ENET_FCS_SIZE)
-#define EMAC_MIN_FRAME 64
-#define EMAC_MAX_FRAME 9018
-#define EMAC_MIN_MTU (EMAC_MIN_FRAME - ENET_HEADER_SIZE - ENET_FCS_SIZE)
-#define EMAC_MAX_MTU (EMAC_MAX_FRAME - ENET_HEADER_SIZE - ENET_FCS_SIZE)
-
-#ifdef CONFIG_IBM_EMAC_ERRMSG
-void emac_serr_dump_0(struct net_device *dev);
-void emac_serr_dump_1(struct net_device *dev);
-void emac_err_dump(struct net_device *dev, int em0isr);
-void emac_phy_dump(struct net_device *);
-void emac_desc_dump(struct net_device *);
-void emac_mac_dump(struct net_device *);
-void emac_mal_dump(struct net_device *);
-#else
-#define emac_serr_dump_0(dev) do { } while (0)
-#define emac_serr_dump_1(dev) do { } while (0)
-#define emac_err_dump(dev,x) do { } while (0)
-#define emac_phy_dump(dev) do { } while (0)
-#define emac_desc_dump(dev) do { } while (0)
-#define emac_mac_dump(dev) do { } while (0)
-#define emac_mal_dump(dev) do { } while (0)
-#endif
+
+/* Normal TX/RX Statistics */
+struct ibm_emac_stats {
+ u64 rx_packets;
+ u64 rx_bytes;
+ u64 tx_packets;
+ u64 tx_bytes;
+ u64 rx_packets_csum;
+ u64 tx_packets_csum;
+};
+
+/* Error statistics */
+struct ibm_emac_error_stats {
+ u64 tx_undo;
+
+ /* Software RX Errors */
+ u64 rx_dropped_stack;
+ u64 rx_dropped_oom;
+ u64 rx_dropped_error;
+ u64 rx_dropped_resize;
+ u64 rx_dropped_mtu;
+ u64 rx_stopped;
+ /* BD reported RX errors */
+ u64 rx_bd_errors;
+ u64 rx_bd_overrun;
+ u64 rx_bd_bad_packet;
+ u64 rx_bd_runt_packet;
+ u64 rx_bd_short_event;
+ u64 rx_bd_alignment_error;
+ u64 rx_bd_bad_fcs;
+ u64 rx_bd_packet_too_long;
+ u64 rx_bd_out_of_range;
+ u64 rx_bd_in_range;
+ /* EMAC IRQ reported RX errors */
+ u64 rx_parity;
+ u64 rx_fifo_overrun;
+ u64 rx_overrun;
+ u64 rx_bad_packet;
+ u64 rx_runt_packet;
+ u64 rx_short_event;
+ u64 rx_alignment_error;
+ u64 rx_bad_fcs;
+ u64 rx_packet_too_long;
+ u64 rx_out_of_range;
+ u64 rx_in_range;
+
+ /* Software TX Errors */
+ u64 tx_dropped;
+ /* BD reported TX errors */
+ u64 tx_bd_errors;
+ u64 tx_bd_bad_fcs;
+ u64 tx_bd_carrier_loss;
+ u64 tx_bd_excessive_deferral;
+ u64 tx_bd_excessive_collisions;
+ u64 tx_bd_late_collision;
+ u64 tx_bd_multple_collisions;
+ u64 tx_bd_single_collision;
+ u64 tx_bd_underrun;
+ u64 tx_bd_sqe;
+ /* EMAC IRQ reported TX errors */
+ u64 tx_parity;
+ u64 tx_underrun;
+ u64 tx_sqe;
+ u64 tx_errors;
+};
+
+#define EMAC_ETHTOOL_STATS_COUNT ((sizeof(struct ibm_emac_stats) + \
+ sizeof(struct ibm_emac_error_stats)) \
+ / sizeof(u64))
struct ocp_enet_private {
- struct sk_buff *tx_skb[NUM_TX_BUFF];
- struct sk_buff *rx_skb[NUM_RX_BUFF];
- struct mal_descriptor *tx_desc;
- struct mal_descriptor *rx_desc;
- struct mal_descriptor *rx_dirty;
- struct net_device_stats stats;
- int tx_cnt;
- int rx_slot;
- int dirty_rx;
- int tx_slot;
- int ack_slot;
- int rx_buffer_size;
-
- struct mii_phy phy_mii;
- int mii_phy_addr;
- int want_autoneg;
- int timer_ticks;
- struct timer_list link_timer;
- struct net_device *mdio_dev;
-
- struct ocp_device *rgmii_dev;
- int rgmii_input;
-
- struct ocp_device *zmii_dev;
- int zmii_input;
-
- struct ibm_ocp_mal *mal;
- int mal_tx_chan, mal_rx_chan;
- struct mal_commac commac;
-
- struct ocp_device *tah_dev;
-
- int opened;
- int going_away;
- int wol_irq;
- emac_t *emacp;
- struct ocp_device *ocpdev;
- struct net_device *ndev;
- spinlock_t lock;
+ struct net_device *ndev; /* 0 */
+ struct emac_regs *emacp;
+
+ struct mal_descriptor *tx_desc;
+ int tx_cnt;
+ int tx_slot;
+ int ack_slot;
+
+ struct mal_descriptor *rx_desc;
+ int rx_slot;
+ struct sk_buff *rx_sg_skb; /* 1 */
+ int rx_skb_size;
+ int rx_sync_size;
+
+ struct ibm_emac_stats stats;
+ struct ocp_device *tah_dev;
+
+ struct ibm_ocp_mal *mal;
+ struct mal_commac commac;
+
+ struct sk_buff *tx_skb[NUM_TX_BUFF];
+ struct sk_buff *rx_skb[NUM_RX_BUFF];
+
+ struct ocp_device *zmii_dev;
+ int zmii_input;
+ struct ocp_enet_private *mdio_dev;
+ struct ocp_device *rgmii_dev;
+ int rgmii_input;
+
+ struct ocp_def *def;
+
+ struct mii_phy phy;
+ struct timer_list link_timer;
+ int reset_failed;
+
+ struct ibm_emac_error_stats estats;
+ struct net_device_stats nstats;
+
+ struct device* ldev;
};
-#endif /* _IBM_EMAC_CORE_H_ */
+
+/* Ethtool get_regs complex data.
+ * We want to get not just EMAC registers, but also MAL, ZMII, RGMII, TAH
+ * when available.
+ *
+ * Returned BLOB consists of the ibm_emac_ethtool_regs_hdr,
+ * MAL registers, EMAC registers and optional ZMII, RGMII, TAH registers.
+ * Each register component is preceded with emac_ethtool_regs_subhdr.
+ * Order of the optional headers follows their relative bit posititions
+ * in emac_ethtool_regs_hdr.components
+ */
+#define EMAC_ETHTOOL_REGS_ZMII 0x00000001
+#define EMAC_ETHTOOL_REGS_RGMII 0x00000002
+#define EMAC_ETHTOOL_REGS_TAH 0x00000004
+
+struct emac_ethtool_regs_hdr {
+ u32 components;
+};
+
+struct emac_ethtool_regs_subhdr {
+ u32 version;
+ u32 index;
+};
+
+#endif /* __IBM_EMAC_CORE_H_ */
diff --git a/drivers/net/ibm_emac/ibm_emac_debug.c b/drivers/net/ibm_emac/ibm_emac_debug.c
index c8512046cf84..75d3b8639041 100644
--- a/drivers/net/ibm_emac/ibm_emac_debug.c
+++ b/drivers/net/ibm_emac/ibm_emac_debug.c
@@ -1,224 +1,213 @@
/*
- * ibm_ocp_debug.c
+ * drivers/net/ibm_emac/ibm_emac_debug.c
*
- * This has all the debug routines that where in *_enet.c
+ * Driver for PowerPC 4xx on-chip ethernet controller, debug print routines.
*
- * Armin Kuster akuster@mvista.com
- * April , 2002
- *
- * Copyright 2002 MontaVista Softare Inc.
+ * Copyright (c) 2004, 2005 Zultys Technologies
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
+ *
*/
-
#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
+#include <linux/sysrq.h>
#include <asm/io.h>
-#include "ibm_ocp_mal.h"
-#include "ibm_ocp_zmii.h"
-#include "ibm_ocp_enet.h"
-extern int emac_phy_read(struct net_device *dev, int mii_id, int reg);
+#include "ibm_emac_core.h"
+
+static void emac_desc_dump(int idx, struct ocp_enet_private *p)
+{
+ int i;
+ printk("** EMAC%d TX BDs **\n"
+ " tx_cnt = %d tx_slot = %d ack_slot = %d\n",
+ idx, p->tx_cnt, p->tx_slot, p->ack_slot);
+ for (i = 0; i < NUM_TX_BUFF / 2; ++i)
+ printk
+ ("bd[%2d] 0x%08x %c 0x%04x %4u - bd[%2d] 0x%08x %c 0x%04x %4u\n",
+ i, p->tx_desc[i].data_ptr, p->tx_skb[i] ? 'V' : ' ',
+ p->tx_desc[i].ctrl, p->tx_desc[i].data_len,
+ NUM_TX_BUFF / 2 + i,
+ p->tx_desc[NUM_TX_BUFF / 2 + i].data_ptr,
+ p->tx_skb[NUM_TX_BUFF / 2 + i] ? 'V' : ' ',
+ p->tx_desc[NUM_TX_BUFF / 2 + i].ctrl,
+ p->tx_desc[NUM_TX_BUFF / 2 + i].data_len);
+
+ printk("** EMAC%d RX BDs **\n"
+ " rx_slot = %d rx_stopped = %d rx_skb_size = %d rx_sync_size = %d\n"
+ " rx_sg_skb = 0x%p\n",
+ idx, p->rx_slot, p->commac.rx_stopped, p->rx_skb_size,
+ p->rx_sync_size, p->rx_sg_skb);
+ for (i = 0; i < NUM_RX_BUFF / 2; ++i)
+ printk
+ ("bd[%2d] 0x%08x %c 0x%04x %4u - bd[%2d] 0x%08x %c 0x%04x %4u\n",
+ i, p->rx_desc[i].data_ptr, p->rx_skb[i] ? 'V' : ' ',
+ p->rx_desc[i].ctrl, p->rx_desc[i].data_len,
+ NUM_RX_BUFF / 2 + i,
+ p->rx_desc[NUM_RX_BUFF / 2 + i].data_ptr,
+ p->rx_skb[NUM_RX_BUFF / 2 + i] ? 'V' : ' ',
+ p->rx_desc[NUM_RX_BUFF / 2 + i].ctrl,
+ p->rx_desc[NUM_RX_BUFF / 2 + i].data_len);
+}
+
+static void emac_mac_dump(int idx, struct ocp_enet_private *dev)
+{
+ struct emac_regs *p = dev->emacp;
+
+ printk("** EMAC%d registers **\n"
+ "MR0 = 0x%08x MR1 = 0x%08x TMR0 = 0x%08x TMR1 = 0x%08x\n"
+ "RMR = 0x%08x ISR = 0x%08x ISER = 0x%08x\n"
+ "IAR = %04x%08x VTPID = 0x%04x VTCI = 0x%04x\n"
+ "IAHT: 0x%04x 0x%04x 0x%04x 0x%04x "
+ "GAHT: 0x%04x 0x%04x 0x%04x 0x%04x\n"
+ "LSA = %04x%08x IPGVR = 0x%04x\n"
+ "STACR = 0x%08x TRTR = 0x%08x RWMR = 0x%08x\n"
+ "OCTX = 0x%08x OCRX = 0x%08x IPCR = 0x%08x\n",
+ idx, in_be32(&p->mr0), in_be32(&p->mr1),
+ in_be32(&p->tmr0), in_be32(&p->tmr1),
+ in_be32(&p->rmr), in_be32(&p->isr), in_be32(&p->iser),
+ in_be32(&p->iahr), in_be32(&p->ialr), in_be32(&p->vtpid),
+ in_be32(&p->vtci),
+ in_be32(&p->iaht1), in_be32(&p->iaht2), in_be32(&p->iaht3),
+ in_be32(&p->iaht4),
+ in_be32(&p->gaht1), in_be32(&p->gaht2), in_be32(&p->gaht3),
+ in_be32(&p->gaht4),
+ in_be32(&p->lsah), in_be32(&p->lsal), in_be32(&p->ipgvr),
+ in_be32(&p->stacr), in_be32(&p->trtr), in_be32(&p->rwmr),
+ in_be32(&p->octx), in_be32(&p->ocrx), in_be32(&p->ipcr)
+ );
+
+ emac_desc_dump(idx, dev);
+}
+
+static void emac_mal_dump(struct ibm_ocp_mal *mal)
+{
+ struct ocp_func_mal_data *maldata = mal->def->additions;
+ int i;
+
+ printk("** MAL%d Registers **\n"
+ "CFG = 0x%08x ESR = 0x%08x IER = 0x%08x\n"
+ "TX|CASR = 0x%08x CARR = 0x%08x EOBISR = 0x%08x DEIR = 0x%08x\n"
+ "RX|CASR = 0x%08x CARR = 0x%08x EOBISR = 0x%08x DEIR = 0x%08x\n",
+ mal->def->index,
+ get_mal_dcrn(mal, MAL_CFG), get_mal_dcrn(mal, MAL_ESR),
+ get_mal_dcrn(mal, MAL_IER),
+ get_mal_dcrn(mal, MAL_TXCASR), get_mal_dcrn(mal, MAL_TXCARR),
+ get_mal_dcrn(mal, MAL_TXEOBISR), get_mal_dcrn(mal, MAL_TXDEIR),
+ get_mal_dcrn(mal, MAL_RXCASR), get_mal_dcrn(mal, MAL_RXCARR),
+ get_mal_dcrn(mal, MAL_RXEOBISR), get_mal_dcrn(mal, MAL_RXDEIR)
+ );
+
+ printk("TX|");
+ for (i = 0; i < maldata->num_tx_chans; ++i) {
+ if (i && !(i % 4))
+ printk("\n ");
+ printk("CTP%d = 0x%08x ", i, get_mal_dcrn(mal, MAL_TXCTPR(i)));
+ }
+ printk("\nRX|");
+ for (i = 0; i < maldata->num_rx_chans; ++i) {
+ if (i && !(i % 4))
+ printk("\n ");
+ printk("CTP%d = 0x%08x ", i, get_mal_dcrn(mal, MAL_RXCTPR(i)));
+ }
+ printk("\n ");
+ for (i = 0; i < maldata->num_rx_chans; ++i) {
+ u32 r = get_mal_dcrn(mal, MAL_RCBS(i));
+ if (i && !(i % 3))
+ printk("\n ");
+ printk("RCBS%d = 0x%08x (%d) ", i, r, r * 16);
+ }
+ printk("\n");
+}
+
+static struct ocp_enet_private *__emacs[4];
+static struct ibm_ocp_mal *__mals[1];
-void emac_phy_dump(struct net_device *dev)
+void emac_dbg_register(int idx, struct ocp_enet_private *dev)
{
- struct ocp_enet_private *fep = dev->priv;
- unsigned long i;
- uint data;
-
- printk(KERN_DEBUG " Prepare for Phy dump....\n");
- for (i = 0; i < 0x1A; i++) {
- data = emac_phy_read(dev, fep->mii_phy_addr, i);
- printk(KERN_DEBUG "Phy reg 0x%lx ==> %4x\n", i, data);
- if (i == 0x07)
- i = 0x0f;
+ unsigned long flags;
+
+ if (idx >= sizeof(__emacs) / sizeof(__emacs[0])) {
+ printk(KERN_WARNING
+ "invalid index %d when registering EMAC for debugging\n",
+ idx);
+ return;
}
+
+ local_irq_save(flags);
+ __emacs[idx] = dev;
+ local_irq_restore(flags);
}
-void emac_desc_dump(struct net_device *dev)
+void mal_dbg_register(int idx, struct ibm_ocp_mal *mal)
{
- struct ocp_enet_private *fep = dev->priv;
- int curr_slot;
-
- printk(KERN_DEBUG
- "dumping the receive descriptors: current slot is %d\n",
- fep->rx_slot);
- for (curr_slot = 0; curr_slot < NUM_RX_BUFF; curr_slot++) {
- printk(KERN_DEBUG
- "Desc %02d: status 0x%04x, length %3d, addr 0x%x\n",
- curr_slot, fep->rx_desc[curr_slot].ctrl,
- fep->rx_desc[curr_slot].data_len,
- (unsigned int)fep->rx_desc[curr_slot].data_ptr);
+ unsigned long flags;
+
+ if (idx >= sizeof(__mals) / sizeof(__mals[0])) {
+ printk(KERN_WARNING
+ "invalid index %d when registering MAL for debugging\n",
+ idx);
+ return;
}
+
+ local_irq_save(flags);
+ __mals[idx] = mal;
+ local_irq_restore(flags);
}
-void emac_mac_dump(struct net_device *dev)
+void emac_dbg_dump_all(void)
{
- struct ocp_enet_private *fep = dev->priv;
- volatile emac_t *emacp = fep->emacp;
-
- printk(KERN_DEBUG "EMAC DEBUG ********** \n");
- printk(KERN_DEBUG "EMAC_M0 ==> 0x%x\n", in_be32(&emacp->em0mr0));
- printk(KERN_DEBUG "EMAC_M1 ==> 0x%x\n", in_be32(&emacp->em0mr1));
- printk(KERN_DEBUG "EMAC_TXM0==> 0x%x\n", in_be32(&emacp->em0tmr0));
- printk(KERN_DEBUG "EMAC_TXM1==> 0x%x\n", in_be32(&emacp->em0tmr1));
- printk(KERN_DEBUG "EMAC_RXM ==> 0x%x\n", in_be32(&emacp->em0rmr));
- printk(KERN_DEBUG "EMAC_ISR ==> 0x%x\n", in_be32(&emacp->em0isr));
- printk(KERN_DEBUG "EMAC_IER ==> 0x%x\n", in_be32(&emacp->em0iser));
- printk(KERN_DEBUG "EMAC_IAH ==> 0x%x\n", in_be32(&emacp->em0iahr));
- printk(KERN_DEBUG "EMAC_IAL ==> 0x%x\n", in_be32(&emacp->em0ialr));
- printk(KERN_DEBUG "EMAC_VLAN_TPID_REG ==> 0x%x\n",
- in_be32(&emacp->em0vtpid));
+ unsigned int i;
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ for (i = 0; i < sizeof(__mals) / sizeof(__mals[0]); ++i)
+ if (__mals[i])
+ emac_mal_dump(__mals[i]);
+
+ for (i = 0; i < sizeof(__emacs) / sizeof(__emacs[0]); ++i)
+ if (__emacs[i])
+ emac_mac_dump(i, __emacs[i]);
+
+ local_irq_restore(flags);
}
-void emac_mal_dump(struct net_device *dev)
+#if defined(CONFIG_MAGIC_SYSRQ)
+static void emac_sysrq_handler(int key, struct pt_regs *pt_regs,
+ struct tty_struct *tty)
{
- struct ibm_ocp_mal *mal = ((struct ocp_enet_private *)dev->priv)->mal;
-
- printk(KERN_DEBUG " MAL DEBUG ********** \n");
- printk(KERN_DEBUG " MCR ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALCR));
- printk(KERN_DEBUG " ESR ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALESR));
- printk(KERN_DEBUG " IER ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALIER));
-#ifdef CONFIG_40x
- printk(KERN_DEBUG " DBR ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALDBR));
-#endif /* CONFIG_40x */
- printk(KERN_DEBUG " TXCASR ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALTXCASR));
- printk(KERN_DEBUG " TXCARR ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALTXCARR));
- printk(KERN_DEBUG " TXEOBISR ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALTXEOBISR));
- printk(KERN_DEBUG " TXDEIR ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALTXDEIR));
- printk(KERN_DEBUG " RXCASR ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALRXCASR));
- printk(KERN_DEBUG " RXCARR ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALRXCARR));
- printk(KERN_DEBUG " RXEOBISR ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALRXEOBISR));
- printk(KERN_DEBUG " RXDEIR ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALRXDEIR));
- printk(KERN_DEBUG " TXCTP0R ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALTXCTP0R));
- printk(KERN_DEBUG " TXCTP1R ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALTXCTP1R));
- printk(KERN_DEBUG " TXCTP2R ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALTXCTP2R));
- printk(KERN_DEBUG " TXCTP3R ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALTXCTP3R));
- printk(KERN_DEBUG " RXCTP0R ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALRXCTP0R));
- printk(KERN_DEBUG " RXCTP1R ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALRXCTP1R));
- printk(KERN_DEBUG " RCBS0 ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALRCBS0));
- printk(KERN_DEBUG " RCBS1 ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALRCBS1));
+ emac_dbg_dump_all();
}
-void emac_serr_dump_0(struct net_device *dev)
+static struct sysrq_key_op emac_sysrq_op = {
+ .handler = emac_sysrq_handler,
+ .help_msg = "emaC",
+ .action_msg = "Show EMAC(s) status",
+};
+
+int __init emac_init_debug(void)
{
- struct ibm_ocp_mal *mal = ((struct ocp_enet_private *)dev->priv)->mal;
- unsigned long int mal_error, plb_error, plb_addr;
-
- mal_error = get_mal_dcrn(mal, DCRN_MALESR);
- printk(KERN_DEBUG "ppc405_eth_serr: %s channel %ld \n",
- (mal_error & 0x40000000) ? "Receive" :
- "Transmit", (mal_error & 0x3e000000) >> 25);
- printk(KERN_DEBUG " ----- latched error -----\n");
- if (mal_error & MALESR_DE)
- printk(KERN_DEBUG " DE: descriptor error\n");
- if (mal_error & MALESR_OEN)
- printk(KERN_DEBUG " ONE: OPB non-fullword error\n");
- if (mal_error & MALESR_OTE)
- printk(KERN_DEBUG " OTE: OPB timeout error\n");
- if (mal_error & MALESR_OSE)
- printk(KERN_DEBUG " OSE: OPB slave error\n");
-
- if (mal_error & MALESR_PEIN) {
- plb_error = mfdcr(DCRN_PLB0_BESR);
- printk(KERN_DEBUG
- " PEIN: PLB error, PLB0_BESR is 0x%x\n",
- (unsigned int)plb_error);
- plb_addr = mfdcr(DCRN_PLB0_BEAR);
- printk(KERN_DEBUG
- " PEIN: PLB error, PLB0_BEAR is 0x%x\n",
- (unsigned int)plb_addr);
- }
+ return register_sysrq_key('c', &emac_sysrq_op);
}
-void emac_serr_dump_1(struct net_device *dev)
+void __exit emac_fini_debug(void)
{
- struct ibm_ocp_mal *mal = ((struct ocp_enet_private *)dev->priv)->mal;
- int mal_error = get_mal_dcrn(mal, DCRN_MALESR);
-
- printk(KERN_DEBUG " ----- cumulative errors -----\n");
- if (mal_error & MALESR_DEI)
- printk(KERN_DEBUG " DEI: descriptor error interrupt\n");
- if (mal_error & MALESR_ONEI)
- printk(KERN_DEBUG " OPB non-fullword error interrupt\n");
- if (mal_error & MALESR_OTEI)
- printk(KERN_DEBUG " OTEI: timeout error interrupt\n");
- if (mal_error & MALESR_OSEI)
- printk(KERN_DEBUG " OSEI: slave error interrupt\n");
- if (mal_error & MALESR_PBEI)
- printk(KERN_DEBUG " PBEI: PLB bus error interrupt\n");
+ unregister_sysrq_key('c', &emac_sysrq_op);
}
-void emac_err_dump(struct net_device *dev, int em0isr)
+#else
+int __init emac_init_debug(void)
+{
+ return 0;
+}
+void __exit emac_fini_debug(void)
{
- printk(KERN_DEBUG "%s: on-chip ethernet error:\n", dev->name);
-
- if (em0isr & EMAC_ISR_OVR)
- printk(KERN_DEBUG " OVR: overrun\n");
- if (em0isr & EMAC_ISR_PP)
- printk(KERN_DEBUG " PP: control pause packet\n");
- if (em0isr & EMAC_ISR_BP)
- printk(KERN_DEBUG " BP: packet error\n");
- if (em0isr & EMAC_ISR_RP)
- printk(KERN_DEBUG " RP: runt packet\n");
- if (em0isr & EMAC_ISR_SE)
- printk(KERN_DEBUG " SE: short event\n");
- if (em0isr & EMAC_ISR_ALE)
- printk(KERN_DEBUG " ALE: odd number of nibbles in packet\n");
- if (em0isr & EMAC_ISR_BFCS)
- printk(KERN_DEBUG " BFCS: bad FCS\n");
- if (em0isr & EMAC_ISR_PTLE)
- printk(KERN_DEBUG " PTLE: oversized packet\n");
- if (em0isr & EMAC_ISR_ORE)
- printk(KERN_DEBUG
- " ORE: packet length field > max allowed LLC\n");
- if (em0isr & EMAC_ISR_IRE)
- printk(KERN_DEBUG " IRE: In Range error\n");
- if (em0isr & EMAC_ISR_DBDM)
- printk(KERN_DEBUG " DBDM: xmit error or SQE\n");
- if (em0isr & EMAC_ISR_DB0)
- printk(KERN_DEBUG " DB0: xmit error or SQE on TX channel 0\n");
- if (em0isr & EMAC_ISR_SE0)
- printk(KERN_DEBUG
- " SE0: Signal Quality Error test failure from TX channel 0\n");
- if (em0isr & EMAC_ISR_TE0)
- printk(KERN_DEBUG " TE0: xmit channel 0 aborted\n");
- if (em0isr & EMAC_ISR_DB1)
- printk(KERN_DEBUG " DB1: xmit error or SQE on TX channel \n");
- if (em0isr & EMAC_ISR_SE1)
- printk(KERN_DEBUG
- " SE1: Signal Quality Error test failure from TX channel 1\n");
- if (em0isr & EMAC_ISR_TE1)
- printk(KERN_DEBUG " TE1: xmit channel 1 aborted\n");
- if (em0isr & EMAC_ISR_MOS)
- printk(KERN_DEBUG " MOS\n");
- if (em0isr & EMAC_ISR_MOF)
- printk(KERN_DEBUG " MOF\n");
-
- emac_mac_dump(dev);
- emac_mal_dump(dev);
}
+#endif /* CONFIG_MAGIC_SYSRQ */
diff --git a/drivers/net/ibm_emac/ibm_emac_debug.h b/drivers/net/ibm_emac/ibm_emac_debug.h
new file mode 100644
index 000000000000..e85fbe0a8da9
--- /dev/null
+++ b/drivers/net/ibm_emac/ibm_emac_debug.h
@@ -0,0 +1,63 @@
+/*
+ * drivers/net/ibm_emac/ibm_ocp_debug.h
+ *
+ * Driver for PowerPC 4xx on-chip ethernet controller, debug print routines.
+ *
+ * Copyright (c) 2004, 2005 Zultys Technologies
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+#ifndef __IBM_EMAC_DEBUG_H_
+#define __IBM_EMAC_DEBUG_H_
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include "ibm_emac_core.h"
+#include "ibm_emac_mal.h"
+
+#if defined(CONFIG_IBM_EMAC_DEBUG)
+void emac_dbg_register(int idx, struct ocp_enet_private *dev);
+void mal_dbg_register(int idx, struct ibm_ocp_mal *mal);
+int emac_init_debug(void) __init;
+void emac_fini_debug(void) __exit;
+void emac_dbg_dump_all(void);
+# define DBG_LEVEL 1
+#else
+# define emac_dbg_register(x,y) ((void)0)
+# define mal_dbg_register(x,y) ((void)0)
+# define emac_init_debug() ((void)0)
+# define emac_fini_debug() ((void)0)
+# define emac_dbg_dump_all() ((void)0)
+# define DBG_LEVEL 0
+#endif
+
+#if DBG_LEVEL > 0
+# define DBG(f,x...) printk("emac" f, ##x)
+# define MAL_DBG(f,x...) printk("mal" f, ##x)
+# define ZMII_DBG(f,x...) printk("zmii" f, ##x)
+# define RGMII_DBG(f,x...) printk("rgmii" f, ##x)
+# define NL "\n"
+#else
+# define DBG(f,x...) ((void)0)
+# define MAL_DBG(f,x...) ((void)0)
+# define ZMII_DBG(f,x...) ((void)0)
+# define RGMII_DBG(f,x...) ((void)0)
+#endif
+#if DBG_LEVEL > 1
+# define DBG2(f,x...) DBG(f, ##x)
+# define MAL_DBG2(f,x...) MAL_DBG(f, ##x)
+# define ZMII_DBG2(f,x...) ZMII_DBG(f, ##x)
+# define RGMII_DBG2(f,x...) RGMII_DBG(f, ##x)
+#else
+# define DBG2(f,x...) ((void)0)
+# define MAL_DBG2(f,x...) ((void)0)
+# define ZMII_DBG2(f,x...) ((void)0)
+# define RGMII_DBG2(f,x...) ((void)0)
+#endif
+
+#endif /* __IBM_EMAC_DEBUG_H_ */
diff --git a/drivers/net/ibm_emac/ibm_emac_mal.c b/drivers/net/ibm_emac/ibm_emac_mal.c
index e59f57f363ca..da88d43081cc 100644
--- a/drivers/net/ibm_emac/ibm_emac_mal.c
+++ b/drivers/net/ibm_emac/ibm_emac_mal.c
@@ -1,436 +1,565 @@
/*
- * ibm_ocp_mal.c
+ * drivers/net/ibm_emac/ibm_emac_mal.c
*
- * Armin Kuster akuster@mvista.com
- * Juen, 2002
+ * Memory Access Layer (MAL) support
+ *
+ * Copyright (c) 2004, 2005 Zultys Technologies.
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
*
- * Copyright 2002 MontaVista Softare Inc.
+ * Based on original work by
+ * Benjamin Herrenschmidt <benh@kernel.crashing.org>,
+ * David Gibson <hermes@gibson.dropbear.id.au>,
+ *
+ * Armin Kuster <akuster@mvista.com>
+ * Copyright 2002 MontaVista Softare 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.
+ *
*/
-
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
-#include <asm/io.h>
-#include <asm/irq.h>
#include <asm/ocp.h>
+#include "ibm_emac_core.h"
#include "ibm_emac_mal.h"
+#include "ibm_emac_debug.h"
-// Locking: Should we share a lock with the client ? The client could provide
-// a lock pointer (optionally) in the commac structure... I don't think this is
-// really necessary though
-
-/* This lock protects the commac list. On today UP implementations, it's
- * really only used as IRQ protection in mal_{register,unregister}_commac()
- */
-static DEFINE_RWLOCK(mal_list_lock);
-
-int mal_register_commac(struct ibm_ocp_mal *mal, struct mal_commac *commac)
+int __init mal_register_commac(struct ibm_ocp_mal *mal,
+ struct mal_commac *commac)
{
unsigned long flags;
+ local_irq_save(flags);
- write_lock_irqsave(&mal_list_lock, flags);
+ MAL_DBG("%d: reg(%08x, %08x)" NL, mal->def->index,
+ commac->tx_chan_mask, commac->rx_chan_mask);
- /* Don't let multiple commacs claim the same channel */
+ /* Don't let multiple commacs claim the same channel(s) */
if ((mal->tx_chan_mask & commac->tx_chan_mask) ||
(mal->rx_chan_mask & commac->rx_chan_mask)) {
- write_unlock_irqrestore(&mal_list_lock, flags);
+ local_irq_restore(flags);
+ printk(KERN_WARNING "mal%d: COMMAC channels conflict!\n",
+ mal->def->index);
return -EBUSY;
}
mal->tx_chan_mask |= commac->tx_chan_mask;
mal->rx_chan_mask |= commac->rx_chan_mask;
+ list_add(&commac->list, &mal->list);
- list_add(&commac->list, &mal->commac);
-
- write_unlock_irqrestore(&mal_list_lock, flags);
-
+ local_irq_restore(flags);
return 0;
}
-int mal_unregister_commac(struct ibm_ocp_mal *mal, struct mal_commac *commac)
+void __exit mal_unregister_commac(struct ibm_ocp_mal *mal,
+ struct mal_commac *commac)
{
unsigned long flags;
+ local_irq_save(flags);
- write_lock_irqsave(&mal_list_lock, flags);
+ MAL_DBG("%d: unreg(%08x, %08x)" NL, mal->def->index,
+ commac->tx_chan_mask, commac->rx_chan_mask);
mal->tx_chan_mask &= ~commac->tx_chan_mask;
mal->rx_chan_mask &= ~commac->rx_chan_mask;
-
list_del_init(&commac->list);
- write_unlock_irqrestore(&mal_list_lock, flags);
-
- return 0;
+ local_irq_restore(flags);
}
int mal_set_rcbs(struct ibm_ocp_mal *mal, int channel, unsigned long size)
{
- switch (channel) {
- case 0:
- set_mal_dcrn(mal, DCRN_MALRCBS0, size);
- break;
-#ifdef DCRN_MALRCBS1
- case 1:
- set_mal_dcrn(mal, DCRN_MALRCBS1, size);
- break;
-#endif
-#ifdef DCRN_MALRCBS2
- case 2:
- set_mal_dcrn(mal, DCRN_MALRCBS2, size);
- break;
-#endif
-#ifdef DCRN_MALRCBS3
- case 3:
- set_mal_dcrn(mal, DCRN_MALRCBS3, size);
- break;
-#endif
- default:
+ struct ocp_func_mal_data *maldata = mal->def->additions;
+ BUG_ON(channel < 0 || channel >= maldata->num_rx_chans ||
+ size > MAL_MAX_RX_SIZE);
+
+ MAL_DBG("%d: set_rbcs(%d, %lu)" NL, mal->def->index, channel, size);
+
+ if (size & 0xf) {
+ printk(KERN_WARNING
+ "mal%d: incorrect RX size %lu for the channel %d\n",
+ mal->def->index, size, channel);
return -EINVAL;
}
+ set_mal_dcrn(mal, MAL_RCBS(channel), size >> 4);
return 0;
}
-static irqreturn_t mal_serr(int irq, void *dev_instance, struct pt_regs *regs)
+int mal_tx_bd_offset(struct ibm_ocp_mal *mal, int channel)
{
- struct ibm_ocp_mal *mal = dev_instance;
- unsigned long mal_error;
+ struct ocp_func_mal_data *maldata = mal->def->additions;
+ BUG_ON(channel < 0 || channel >= maldata->num_tx_chans);
+ return channel * NUM_TX_BUFF;
+}
- /*
- * This SERR applies to one of the devices on the MAL, here we charge
- * it against the first EMAC registered for the MAL.
- */
+int mal_rx_bd_offset(struct ibm_ocp_mal *mal, int channel)
+{
+ struct ocp_func_mal_data *maldata = mal->def->additions;
+ BUG_ON(channel < 0 || channel >= maldata->num_rx_chans);
+ return maldata->num_tx_chans * NUM_TX_BUFF + channel * NUM_RX_BUFF;
+}
- mal_error = get_mal_dcrn(mal, DCRN_MALESR);
+void mal_enable_tx_channel(struct ibm_ocp_mal *mal, int channel)
+{
+ local_bh_disable();
+ MAL_DBG("%d: enable_tx(%d)" NL, mal->def->index, channel);
+ set_mal_dcrn(mal, MAL_TXCASR,
+ get_mal_dcrn(mal, MAL_TXCASR) | MAL_CHAN_MASK(channel));
+ local_bh_enable();
+}
- printk(KERN_ERR "%s: System Error (MALESR=%lx)\n",
- "MAL" /* FIXME: get the name right */ , mal_error);
+void mal_disable_tx_channel(struct ibm_ocp_mal *mal, int channel)
+{
+ set_mal_dcrn(mal, MAL_TXCARR, MAL_CHAN_MASK(channel));
+ MAL_DBG("%d: disable_tx(%d)" NL, mal->def->index, channel);
+}
- /* FIXME: decipher error */
- /* DIXME: distribute to commacs, if possible */
+void mal_enable_rx_channel(struct ibm_ocp_mal *mal, int channel)
+{
+ local_bh_disable();
+ MAL_DBG("%d: enable_rx(%d)" NL, mal->def->index, channel);
+ set_mal_dcrn(mal, MAL_RXCASR,
+ get_mal_dcrn(mal, MAL_RXCASR) | MAL_CHAN_MASK(channel));
+ local_bh_enable();
+}
- /* Clear the error status register */
- set_mal_dcrn(mal, DCRN_MALESR, mal_error);
+void mal_disable_rx_channel(struct ibm_ocp_mal *mal, int channel)
+{
+ set_mal_dcrn(mal, MAL_RXCARR, MAL_CHAN_MASK(channel));
+ MAL_DBG("%d: disable_rx(%d)" NL, mal->def->index, channel);
+}
- return IRQ_HANDLED;
+void mal_poll_add(struct ibm_ocp_mal *mal, struct mal_commac *commac)
+{
+ local_bh_disable();
+ MAL_DBG("%d: poll_add(%p)" NL, mal->def->index, commac);
+ list_add_tail(&commac->poll_list, &mal->poll_list);
+ local_bh_enable();
}
-static irqreturn_t mal_txeob(int irq, void *dev_instance, struct pt_regs *regs)
+void mal_poll_del(struct ibm_ocp_mal *mal, struct mal_commac *commac)
+{
+ local_bh_disable();
+ MAL_DBG("%d: poll_del(%p)" NL, mal->def->index, commac);
+ list_del(&commac->poll_list);
+ local_bh_enable();
+}
+
+/* synchronized by mal_poll() */
+static inline void mal_enable_eob_irq(struct ibm_ocp_mal *mal)
+{
+ MAL_DBG2("%d: enable_irq" NL, mal->def->index);
+ set_mal_dcrn(mal, MAL_CFG, get_mal_dcrn(mal, MAL_CFG) | MAL_CFG_EOPIE);
+}
+
+/* synchronized by __LINK_STATE_RX_SCHED bit in ndev->state */
+static inline void mal_disable_eob_irq(struct ibm_ocp_mal *mal)
+{
+ set_mal_dcrn(mal, MAL_CFG, get_mal_dcrn(mal, MAL_CFG) & ~MAL_CFG_EOPIE);
+ MAL_DBG2("%d: disable_irq" NL, mal->def->index);
+}
+
+static irqreturn_t mal_serr(int irq, void *dev_instance, struct pt_regs *regs)
{
struct ibm_ocp_mal *mal = dev_instance;
- struct list_head *l;
- unsigned long isr;
+ u32 esr = get_mal_dcrn(mal, MAL_ESR);
- isr = get_mal_dcrn(mal, DCRN_MALTXEOBISR);
- set_mal_dcrn(mal, DCRN_MALTXEOBISR, isr);
+ /* Clear the error status register */
+ set_mal_dcrn(mal, MAL_ESR, esr);
- read_lock(&mal_list_lock);
- list_for_each(l, &mal->commac) {
- struct mal_commac *mc = list_entry(l, struct mal_commac, list);
+ MAL_DBG("%d: SERR %08x" NL, mal->def->index, esr);
- if (isr & mc->tx_chan_mask) {
- mc->ops->txeob(mc->dev, isr & mc->tx_chan_mask);
+ if (esr & MAL_ESR_EVB) {
+ if (esr & MAL_ESR_DE) {
+ /* We ignore Descriptor error,
+ * TXDE or RXDE interrupt will be generated anyway.
+ */
+ return IRQ_HANDLED;
}
+
+ if (esr & MAL_ESR_PEIN) {
+ /* PLB error, it's probably buggy hardware or
+ * incorrect physical address in BD (i.e. bug)
+ */
+ if (net_ratelimit())
+ printk(KERN_ERR
+ "mal%d: system error, PLB (ESR = 0x%08x)\n",
+ mal->def->index, esr);
+ return IRQ_HANDLED;
+ }
+
+ /* OPB error, it's probably buggy hardware or incorrect EBC setup */
+ if (net_ratelimit())
+ printk(KERN_ERR
+ "mal%d: system error, OPB (ESR = 0x%08x)\n",
+ mal->def->index, esr);
}
- read_unlock(&mal_list_lock);
+ return IRQ_HANDLED;
+}
+
+static inline void mal_schedule_poll(struct ibm_ocp_mal *mal)
+{
+ if (likely(netif_rx_schedule_prep(&mal->poll_dev))) {
+ MAL_DBG2("%d: schedule_poll" NL, mal->def->index);
+ mal_disable_eob_irq(mal);
+ __netif_rx_schedule(&mal->poll_dev);
+ } else
+ MAL_DBG2("%d: already in poll" NL, mal->def->index);
+}
+static irqreturn_t mal_txeob(int irq, void *dev_instance, struct pt_regs *regs)
+{
+ struct ibm_ocp_mal *mal = dev_instance;
+ u32 r = get_mal_dcrn(mal, MAL_TXEOBISR);
+ MAL_DBG2("%d: txeob %08x" NL, mal->def->index, r);
+ mal_schedule_poll(mal);
+ set_mal_dcrn(mal, MAL_TXEOBISR, r);
return IRQ_HANDLED;
}
static irqreturn_t mal_rxeob(int irq, void *dev_instance, struct pt_regs *regs)
{
struct ibm_ocp_mal *mal = dev_instance;
- struct list_head *l;
- unsigned long isr;
+ u32 r = get_mal_dcrn(mal, MAL_RXEOBISR);
+ MAL_DBG2("%d: rxeob %08x" NL, mal->def->index, r);
+ mal_schedule_poll(mal);
+ set_mal_dcrn(mal, MAL_RXEOBISR, r);
+ return IRQ_HANDLED;
+}
- isr = get_mal_dcrn(mal, DCRN_MALRXEOBISR);
- set_mal_dcrn(mal, DCRN_MALRXEOBISR, isr);
+static irqreturn_t mal_txde(int irq, void *dev_instance, struct pt_regs *regs)
+{
+ struct ibm_ocp_mal *mal = dev_instance;
+ u32 deir = get_mal_dcrn(mal, MAL_TXDEIR);
+ set_mal_dcrn(mal, MAL_TXDEIR, deir);
- read_lock(&mal_list_lock);
- list_for_each(l, &mal->commac) {
- struct mal_commac *mc = list_entry(l, struct mal_commac, list);
+ MAL_DBG("%d: txde %08x" NL, mal->def->index, deir);
- if (isr & mc->rx_chan_mask) {
- mc->ops->rxeob(mc->dev, isr & mc->rx_chan_mask);
- }
- }
- read_unlock(&mal_list_lock);
+ if (net_ratelimit())
+ printk(KERN_ERR
+ "mal%d: TX descriptor error (TXDEIR = 0x%08x)\n",
+ mal->def->index, deir);
return IRQ_HANDLED;
}
-static irqreturn_t mal_txde(int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t mal_rxde(int irq, void *dev_instance, struct pt_regs *regs)
{
struct ibm_ocp_mal *mal = dev_instance;
struct list_head *l;
- unsigned long deir;
+ u32 deir = get_mal_dcrn(mal, MAL_RXDEIR);
- deir = get_mal_dcrn(mal, DCRN_MALTXDEIR);
+ MAL_DBG("%d: rxde %08x" NL, mal->def->index, deir);
- /* FIXME: print which MAL correctly */
- printk(KERN_WARNING "%s: Tx descriptor error (MALTXDEIR=%lx)\n",
- "MAL", deir);
-
- read_lock(&mal_list_lock);
- list_for_each(l, &mal->commac) {
+ list_for_each(l, &mal->list) {
struct mal_commac *mc = list_entry(l, struct mal_commac, list);
-
- if (deir & mc->tx_chan_mask) {
- mc->ops->txde(mc->dev, deir & mc->tx_chan_mask);
+ if (deir & mc->rx_chan_mask) {
+ mc->rx_stopped = 1;
+ mc->ops->rxde(mc->dev);
}
}
- read_unlock(&mal_list_lock);
+
+ mal_schedule_poll(mal);
+ set_mal_dcrn(mal, MAL_RXDEIR, deir);
return IRQ_HANDLED;
}
-/*
- * This interrupt should be very rare at best. This occurs when
- * the hardware has a problem with the receive descriptors. The manual
- * states that it occurs when the hardware cannot the receive descriptor
- * empty bit is not set. The recovery mechanism will be to
- * traverse through the descriptors, handle any that are marked to be
- * handled and reinitialize each along the way. At that point the driver
- * will be restarted.
- */
-static irqreturn_t mal_rxde(int irq, void *dev_instance, struct pt_regs *regs)
+static int mal_poll(struct net_device *ndev, int *budget)
{
- struct ibm_ocp_mal *mal = dev_instance;
+ struct ibm_ocp_mal *mal = ndev->priv;
struct list_head *l;
- unsigned long deir;
-
- deir = get_mal_dcrn(mal, DCRN_MALRXDEIR);
+ int rx_work_limit = min(ndev->quota, *budget), received = 0, done;
+
+ MAL_DBG2("%d: poll(%d) %d ->" NL, mal->def->index, *budget,
+ rx_work_limit);
+ again:
+ /* Process TX skbs */
+ list_for_each(l, &mal->poll_list) {
+ struct mal_commac *mc =
+ list_entry(l, struct mal_commac, poll_list);
+ mc->ops->poll_tx(mc->dev);
+ }
- /*
- * This really is needed. This case encountered in stress testing.
+ /* Process RX skbs.
+ * We _might_ need something more smart here to enforce polling fairness.
*/
- if (deir == 0)
- return IRQ_HANDLED;
-
- /* FIXME: print which MAL correctly */
- printk(KERN_WARNING "%s: Rx descriptor error (MALRXDEIR=%lx)\n",
- "MAL", deir);
-
- read_lock(&mal_list_lock);
- list_for_each(l, &mal->commac) {
- struct mal_commac *mc = list_entry(l, struct mal_commac, list);
+ list_for_each(l, &mal->poll_list) {
+ struct mal_commac *mc =
+ list_entry(l, struct mal_commac, poll_list);
+ int n = mc->ops->poll_rx(mc->dev, rx_work_limit);
+ if (n) {
+ received += n;
+ rx_work_limit -= n;
+ if (rx_work_limit <= 0) {
+ done = 0;
+ goto more_work; // XXX What if this is the last one ?
+ }
+ }
+ }
- if (deir & mc->rx_chan_mask) {
- mc->ops->rxde(mc->dev, deir & mc->rx_chan_mask);
+ /* We need to disable IRQs to protect from RXDE IRQ here */
+ local_irq_disable();
+ __netif_rx_complete(ndev);
+ mal_enable_eob_irq(mal);
+ local_irq_enable();
+
+ done = 1;
+
+ /* Check for "rotting" packet(s) */
+ list_for_each(l, &mal->poll_list) {
+ struct mal_commac *mc =
+ list_entry(l, struct mal_commac, poll_list);
+ if (unlikely(mc->ops->peek_rx(mc->dev) || mc->rx_stopped)) {
+ MAL_DBG2("%d: rotting packet" NL, mal->def->index);
+ if (netif_rx_reschedule(ndev, received))
+ mal_disable_eob_irq(mal);
+ else
+ MAL_DBG2("%d: already in poll list" NL,
+ mal->def->index);
+
+ if (rx_work_limit > 0)
+ goto again;
+ else
+ goto more_work;
}
+ mc->ops->poll_tx(mc->dev);
}
- read_unlock(&mal_list_lock);
- return IRQ_HANDLED;
+ more_work:
+ ndev->quota -= received;
+ *budget -= received;
+
+ MAL_DBG2("%d: poll() %d <- %d" NL, mal->def->index, *budget,
+ done ? 0 : 1);
+ return done ? 0 : 1;
+}
+
+static void mal_reset(struct ibm_ocp_mal *mal)
+{
+ int n = 10;
+ MAL_DBG("%d: reset" NL, mal->def->index);
+
+ set_mal_dcrn(mal, MAL_CFG, MAL_CFG_SR);
+
+ /* Wait for reset to complete (1 system clock) */
+ while ((get_mal_dcrn(mal, MAL_CFG) & MAL_CFG_SR) && n)
+ --n;
+
+ if (unlikely(!n))
+ printk(KERN_ERR "mal%d: reset timeout\n", mal->def->index);
+}
+
+int mal_get_regs_len(struct ibm_ocp_mal *mal)
+{
+ return sizeof(struct emac_ethtool_regs_subhdr) +
+ sizeof(struct ibm_mal_regs);
+}
+
+void *mal_dump_regs(struct ibm_ocp_mal *mal, void *buf)
+{
+ struct emac_ethtool_regs_subhdr *hdr = buf;
+ struct ibm_mal_regs *regs = (struct ibm_mal_regs *)(hdr + 1);
+ struct ocp_func_mal_data *maldata = mal->def->additions;
+ int i;
+
+ hdr->version = MAL_VERSION;
+ hdr->index = mal->def->index;
+
+ regs->tx_count = maldata->num_tx_chans;
+ regs->rx_count = maldata->num_rx_chans;
+
+ regs->cfg = get_mal_dcrn(mal, MAL_CFG);
+ regs->esr = get_mal_dcrn(mal, MAL_ESR);
+ regs->ier = get_mal_dcrn(mal, MAL_IER);
+ regs->tx_casr = get_mal_dcrn(mal, MAL_TXCASR);
+ regs->tx_carr = get_mal_dcrn(mal, MAL_TXCARR);
+ regs->tx_eobisr = get_mal_dcrn(mal, MAL_TXEOBISR);
+ regs->tx_deir = get_mal_dcrn(mal, MAL_TXDEIR);
+ regs->rx_casr = get_mal_dcrn(mal, MAL_RXCASR);
+ regs->rx_carr = get_mal_dcrn(mal, MAL_RXCARR);
+ regs->rx_eobisr = get_mal_dcrn(mal, MAL_RXEOBISR);
+ regs->rx_deir = get_mal_dcrn(mal, MAL_RXDEIR);
+
+ for (i = 0; i < regs->tx_count; ++i)
+ regs->tx_ctpr[i] = get_mal_dcrn(mal, MAL_TXCTPR(i));
+
+ for (i = 0; i < regs->rx_count; ++i) {
+ regs->rx_ctpr[i] = get_mal_dcrn(mal, MAL_RXCTPR(i));
+ regs->rcbs[i] = get_mal_dcrn(mal, MAL_RCBS(i));
+ }
+ return regs + 1;
}
static int __init mal_probe(struct ocp_device *ocpdev)
{
- struct ibm_ocp_mal *mal = NULL;
+ struct ibm_ocp_mal *mal;
struct ocp_func_mal_data *maldata;
- int err = 0;
+ int err = 0, i, bd_size;
+
+ MAL_DBG("%d: probe" NL, ocpdev->def->index);
- maldata = (struct ocp_func_mal_data *)ocpdev->def->additions;
+ maldata = ocpdev->def->additions;
if (maldata == NULL) {
- printk(KERN_ERR "mal%d: Missing additional datas !\n",
+ printk(KERN_ERR "mal%d: missing additional data!\n",
ocpdev->def->index);
return -ENODEV;
}
- mal = kmalloc(sizeof(struct ibm_ocp_mal), GFP_KERNEL);
- if (mal == NULL) {
+ mal = kzalloc(sizeof(struct ibm_ocp_mal), GFP_KERNEL);
+ if (!mal) {
printk(KERN_ERR
- "mal%d: Out of memory allocating MAL structure !\n",
+ "mal%d: out of memory allocating MAL structure!\n",
ocpdev->def->index);
return -ENOMEM;
}
- memset(mal, 0, sizeof(*mal));
-
- switch (ocpdev->def->index) {
- case 0:
- mal->dcrbase = DCRN_MAL_BASE;
- break;
-#ifdef DCRN_MAL1_BASE
- case 1:
- mal->dcrbase = DCRN_MAL1_BASE;
- break;
-#endif
- default:
- BUG();
- }
-
- /**************************/
+ mal->dcrbase = maldata->dcr_base;
+ mal->def = ocpdev->def;
- INIT_LIST_HEAD(&mal->commac);
+ INIT_LIST_HEAD(&mal->poll_list);
+ set_bit(__LINK_STATE_START, &mal->poll_dev.state);
+ mal->poll_dev.weight = CONFIG_IBM_EMAC_POLL_WEIGHT;
+ mal->poll_dev.poll = mal_poll;
+ mal->poll_dev.priv = mal;
+ atomic_set(&mal->poll_dev.refcnt, 1);
- set_mal_dcrn(mal, DCRN_MALRXCARR, 0xFFFFFFFF);
- set_mal_dcrn(mal, DCRN_MALTXCARR, 0xFFFFFFFF);
+ INIT_LIST_HEAD(&mal->list);
- set_mal_dcrn(mal, DCRN_MALCR, MALCR_MMSR); /* 384 */
- /* FIXME: Add delay */
+ /* Load power-on reset defaults */
+ mal_reset(mal);
/* Set the MAL configuration register */
- set_mal_dcrn(mal, DCRN_MALCR,
- MALCR_PLBB | MALCR_OPBBL | MALCR_LEA |
- MALCR_PLBLT_DEFAULT);
-
- /* It would be nice to allocate buffers separately for each
- * channel, but we can't because the channels share the upper
- * 13 bits of address lines. Each channels buffer must also
- * be 4k aligned, so we allocate 4k for each channel. This is
- * inefficient FIXME: do better, if possible */
- mal->tx_virt_addr = dma_alloc_coherent(&ocpdev->dev,
- MAL_DT_ALIGN *
- maldata->num_tx_chans,
- &mal->tx_phys_addr, GFP_KERNEL);
- if (mal->tx_virt_addr == NULL) {
+ set_mal_dcrn(mal, MAL_CFG, MAL_CFG_DEFAULT | MAL_CFG_PLBB |
+ MAL_CFG_OPBBL | MAL_CFG_LEA);
+
+ mal_enable_eob_irq(mal);
+
+ /* Allocate space for BD rings */
+ BUG_ON(maldata->num_tx_chans <= 0 || maldata->num_tx_chans > 32);
+ BUG_ON(maldata->num_rx_chans <= 0 || maldata->num_rx_chans > 32);
+ bd_size = sizeof(struct mal_descriptor) *
+ (NUM_TX_BUFF * maldata->num_tx_chans +
+ NUM_RX_BUFF * maldata->num_rx_chans);
+ mal->bd_virt =
+ dma_alloc_coherent(&ocpdev->dev, bd_size, &mal->bd_dma, GFP_KERNEL);
+
+ if (!mal->bd_virt) {
printk(KERN_ERR
- "mal%d: Out of memory allocating MAL descriptors !\n",
- ocpdev->def->index);
+ "mal%d: out of memory allocating RX/TX descriptors!\n",
+ mal->def->index);
err = -ENOMEM;
goto fail;
}
+ memset(mal->bd_virt, 0, bd_size);
- /* God, oh, god, I hate DCRs */
- set_mal_dcrn(mal, DCRN_MALTXCTP0R, mal->tx_phys_addr);
-#ifdef DCRN_MALTXCTP1R
- if (maldata->num_tx_chans > 1)
- set_mal_dcrn(mal, DCRN_MALTXCTP1R,
- mal->tx_phys_addr + MAL_DT_ALIGN);
-#endif /* DCRN_MALTXCTP1R */
-#ifdef DCRN_MALTXCTP2R
- if (maldata->num_tx_chans > 2)
- set_mal_dcrn(mal, DCRN_MALTXCTP2R,
- mal->tx_phys_addr + 2 * MAL_DT_ALIGN);
-#endif /* DCRN_MALTXCTP2R */
-#ifdef DCRN_MALTXCTP3R
- if (maldata->num_tx_chans > 3)
- set_mal_dcrn(mal, DCRN_MALTXCTP3R,
- mal->tx_phys_addr + 3 * MAL_DT_ALIGN);
-#endif /* DCRN_MALTXCTP3R */
-#ifdef DCRN_MALTXCTP4R
- if (maldata->num_tx_chans > 4)
- set_mal_dcrn(mal, DCRN_MALTXCTP4R,
- mal->tx_phys_addr + 4 * MAL_DT_ALIGN);
-#endif /* DCRN_MALTXCTP4R */
-#ifdef DCRN_MALTXCTP5R
- if (maldata->num_tx_chans > 5)
- set_mal_dcrn(mal, DCRN_MALTXCTP5R,
- mal->tx_phys_addr + 5 * MAL_DT_ALIGN);
-#endif /* DCRN_MALTXCTP5R */
-#ifdef DCRN_MALTXCTP6R
- if (maldata->num_tx_chans > 6)
- set_mal_dcrn(mal, DCRN_MALTXCTP6R,
- mal->tx_phys_addr + 6 * MAL_DT_ALIGN);
-#endif /* DCRN_MALTXCTP6R */
-#ifdef DCRN_MALTXCTP7R
- if (maldata->num_tx_chans > 7)
- set_mal_dcrn(mal, DCRN_MALTXCTP7R,
- mal->tx_phys_addr + 7 * MAL_DT_ALIGN);
-#endif /* DCRN_MALTXCTP7R */
-
- mal->rx_virt_addr = dma_alloc_coherent(&ocpdev->dev,
- MAL_DT_ALIGN *
- maldata->num_rx_chans,
- &mal->rx_phys_addr, GFP_KERNEL);
-
- set_mal_dcrn(mal, DCRN_MALRXCTP0R, mal->rx_phys_addr);
-#ifdef DCRN_MALRXCTP1R
- if (maldata->num_rx_chans > 1)
- set_mal_dcrn(mal, DCRN_MALRXCTP1R,
- mal->rx_phys_addr + MAL_DT_ALIGN);
-#endif /* DCRN_MALRXCTP1R */
-#ifdef DCRN_MALRXCTP2R
- if (maldata->num_rx_chans > 2)
- set_mal_dcrn(mal, DCRN_MALRXCTP2R,
- mal->rx_phys_addr + 2 * MAL_DT_ALIGN);
-#endif /* DCRN_MALRXCTP2R */
-#ifdef DCRN_MALRXCTP3R
- if (maldata->num_rx_chans > 3)
- set_mal_dcrn(mal, DCRN_MALRXCTP3R,
- mal->rx_phys_addr + 3 * MAL_DT_ALIGN);
-#endif /* DCRN_MALRXCTP3R */
+ for (i = 0; i < maldata->num_tx_chans; ++i)
+ set_mal_dcrn(mal, MAL_TXCTPR(i), mal->bd_dma +
+ sizeof(struct mal_descriptor) *
+ mal_tx_bd_offset(mal, i));
+
+ for (i = 0; i < maldata->num_rx_chans; ++i)
+ set_mal_dcrn(mal, MAL_RXCTPR(i), mal->bd_dma +
+ sizeof(struct mal_descriptor) *
+ mal_rx_bd_offset(mal, i));
err = request_irq(maldata->serr_irq, mal_serr, 0, "MAL SERR", mal);
if (err)
- goto fail;
- err = request_irq(maldata->txde_irq, mal_txde, 0, "MAL TX DE ", mal);
+ goto fail2;
+ err = request_irq(maldata->txde_irq, mal_txde, 0, "MAL TX DE", mal);
if (err)
- goto fail;
+ goto fail3;
err = request_irq(maldata->txeob_irq, mal_txeob, 0, "MAL TX EOB", mal);
if (err)
- goto fail;
+ goto fail4;
err = request_irq(maldata->rxde_irq, mal_rxde, 0, "MAL RX DE", mal);
if (err)
- goto fail;
+ goto fail5;
err = request_irq(maldata->rxeob_irq, mal_rxeob, 0, "MAL RX EOB", mal);
if (err)
- goto fail;
+ goto fail6;
- set_mal_dcrn(mal, DCRN_MALIER,
- MALIER_DE | MALIER_NE | MALIER_TE |
- MALIER_OPBE | MALIER_PLBE);
+ /* Enable all MAL SERR interrupt sources */
+ set_mal_dcrn(mal, MAL_IER, MAL_IER_EVENTS);
- /* Advertise me to the rest of the world */
+ /* Advertise this instance to the rest of the world */
ocp_set_drvdata(ocpdev, mal);
- printk(KERN_INFO "mal%d: Initialized, %d tx channels, %d rx channels\n",
- ocpdev->def->index, maldata->num_tx_chans,
- maldata->num_rx_chans);
+ mal_dbg_register(mal->def->index, mal);
+ printk(KERN_INFO "mal%d: initialized, %d TX channels, %d RX channels\n",
+ mal->def->index, maldata->num_tx_chans, maldata->num_rx_chans);
return 0;
+ fail6:
+ free_irq(maldata->rxde_irq, mal);
+ fail5:
+ free_irq(maldata->txeob_irq, mal);
+ fail4:
+ free_irq(maldata->txde_irq, mal);
+ fail3:
+ free_irq(maldata->serr_irq, mal);
+ fail2:
+ dma_free_coherent(&ocpdev->dev, bd_size, mal->bd_virt, mal->bd_dma);
fail:
- /* FIXME: dispose requested IRQs ! */
- if (err && mal)
- kfree(mal);
+ kfree(mal);
return err;
}
static void __exit mal_remove(struct ocp_device *ocpdev)
{
struct ibm_ocp_mal *mal = ocp_get_drvdata(ocpdev);
- struct ocp_func_mal_data *maldata = ocpdev->def->additions;
+ struct ocp_func_mal_data *maldata = mal->def->additions;
+
+ MAL_DBG("%d: remove" NL, mal->def->index);
- BUG_ON(!maldata);
+ /* Syncronize with scheduled polling,
+ stolen from net/core/dev.c:dev_close()
+ */
+ clear_bit(__LINK_STATE_START, &mal->poll_dev.state);
+ netif_poll_disable(&mal->poll_dev);
+
+ if (!list_empty(&mal->list)) {
+ /* This is *very* bad */
+ printk(KERN_EMERG
+ "mal%d: commac list is not empty on remove!\n",
+ mal->def->index);
+ }
ocp_set_drvdata(ocpdev, NULL);
- /* FIXME: shut down the MAL, deal with dependency with emac */
free_irq(maldata->serr_irq, mal);
free_irq(maldata->txde_irq, mal);
free_irq(maldata->txeob_irq, mal);
free_irq(maldata->rxde_irq, mal);
free_irq(maldata->rxeob_irq, mal);
- if (mal->tx_virt_addr)
- dma_free_coherent(&ocpdev->dev,
- MAL_DT_ALIGN * maldata->num_tx_chans,
- mal->tx_virt_addr, mal->tx_phys_addr);
+ mal_reset(mal);
- if (mal->rx_virt_addr)
- dma_free_coherent(&ocpdev->dev,
- MAL_DT_ALIGN * maldata->num_rx_chans,
- mal->rx_virt_addr, mal->rx_phys_addr);
+ mal_dbg_register(mal->def->index, NULL);
+
+ dma_free_coherent(&ocpdev->dev,
+ sizeof(struct mal_descriptor) *
+ (NUM_TX_BUFF * maldata->num_tx_chans +
+ NUM_RX_BUFF * maldata->num_rx_chans), mal->bd_virt,
+ mal->bd_dma);
kfree(mal);
}
/* Structure for a device driver */
static struct ocp_device_id mal_ids[] = {
- {.vendor = OCP_ANY_ID,.function = OCP_FUNC_MAL},
- {.vendor = OCP_VENDOR_INVALID}
+ { .vendor = OCP_VENDOR_IBM, .function = OCP_FUNC_MAL },
+ { .vendor = OCP_VENDOR_INVALID}
};
static struct ocp_driver mal_driver = {
@@ -441,23 +570,14 @@ static struct ocp_driver mal_driver = {
.remove = mal_remove,
};
-static int __init init_mals(void)
+int __init mal_init(void)
{
- int rc;
-
- rc = ocp_register_driver(&mal_driver);
- if (rc < 0) {
- ocp_unregister_driver(&mal_driver);
- return -ENODEV;
- }
-
- return 0;
+ MAL_DBG(": init" NL);
+ return ocp_register_driver(&mal_driver);
}
-static void __exit exit_mals(void)
+void __exit mal_exit(void)
{
+ MAL_DBG(": exit" NL);
ocp_unregister_driver(&mal_driver);
}
-
-module_init(init_mals);
-module_exit(exit_mals);
diff --git a/drivers/net/ibm_emac/ibm_emac_mal.h b/drivers/net/ibm_emac/ibm_emac_mal.h
index dd9f0dabc6e0..15b0bdae26ac 100644
--- a/drivers/net/ibm_emac/ibm_emac_mal.h
+++ b/drivers/net/ibm_emac/ibm_emac_mal.h
@@ -1,131 +1,267 @@
-#ifndef _IBM_EMAC_MAL_H
-#define _IBM_EMAC_MAL_H
+/*
+ * drivers/net/ibm_emac/ibm_emac_mal.h
+ *
+ * Memory Access Layer (MAL) support
+ *
+ * Copyright (c) 2004, 2005 Zultys Technologies.
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ *
+ * Based on original work by
+ * Armin Kuster <akuster@mvista.com>
+ * Copyright 2002 MontaVista Softare 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.
+ *
+ */
+#ifndef __IBM_EMAC_MAL_H_
+#define __IBM_EMAC_MAL_H_
+#include <linux/config.h>
+#include <linux/init.h>
#include <linux/list.h>
+#include <linux/netdevice.h>
-#define MAL_DT_ALIGN (4096) /* Alignment for each channel's descriptor table */
+#include <asm/io.h>
-#define MAL_CHAN_MASK(chan) (0x80000000 >> (chan))
+/*
+ * These MAL "versions" probably aren't the real versions IBM uses for these
+ * MAL cores, I assigned them just to make #ifdefs in this file nicer and
+ * reflect the fact that 40x and 44x have slightly different MALs. --ebs
+ */
+#if defined(CONFIG_405GP) || defined(CONFIG_405GPR) || defined(CONFIG_405EP) || \
+ defined(CONFIG_440EP) || defined(CONFIG_NP405H)
+#define MAL_VERSION 1
+#elif defined(CONFIG_440GP) || defined(CONFIG_440GX) || defined(CONFIG_440SP)
+#define MAL_VERSION 2
+#else
+#error "Unknown SoC, please check chip manual and choose MAL 'version'"
+#endif
+
+/* MALx DCR registers */
+#define MAL_CFG 0x00
+#define MAL_CFG_SR 0x80000000
+#define MAL_CFG_PLBB 0x00004000
+#define MAL_CFG_OPBBL 0x00000080
+#define MAL_CFG_EOPIE 0x00000004
+#define MAL_CFG_LEA 0x00000002
+#define MAL_CFG_SD 0x00000001
+#if MAL_VERSION == 1
+#define MAL_CFG_PLBP_MASK 0x00c00000
+#define MAL_CFG_PLBP_10 0x00800000
+#define MAL_CFG_GA 0x00200000
+#define MAL_CFG_OA 0x00100000
+#define MAL_CFG_PLBLE 0x00080000
+#define MAL_CFG_PLBT_MASK 0x00078000
+#define MAL_CFG_DEFAULT (MAL_CFG_PLBP_10 | MAL_CFG_PLBT_MASK)
+#elif MAL_VERSION == 2
+#define MAL_CFG_RPP_MASK 0x00c00000
+#define MAL_CFG_RPP_10 0x00800000
+#define MAL_CFG_RMBS_MASK 0x00300000
+#define MAL_CFG_WPP_MASK 0x000c0000
+#define MAL_CFG_WPP_10 0x00080000
+#define MAL_CFG_WMBS_MASK 0x00030000
+#define MAL_CFG_PLBLE 0x00008000
+#define MAL_CFG_DEFAULT (MAL_CFG_RMBS_MASK | MAL_CFG_WMBS_MASK | \
+ MAL_CFG_RPP_10 | MAL_CFG_WPP_10)
+#else
+#error "Unknown MAL version"
+#endif
+
+#define MAL_ESR 0x01
+#define MAL_ESR_EVB 0x80000000
+#define MAL_ESR_CIDT 0x40000000
+#define MAL_ESR_CID_MASK 0x3e000000
+#define MAL_ESR_CID_SHIFT 25
+#define MAL_ESR_DE 0x00100000
+#define MAL_ESR_OTE 0x00040000
+#define MAL_ESR_OSE 0x00020000
+#define MAL_ESR_PEIN 0x00010000
+#define MAL_ESR_DEI 0x00000010
+#define MAL_ESR_OTEI 0x00000004
+#define MAL_ESR_OSEI 0x00000002
+#define MAL_ESR_PBEI 0x00000001
+#if MAL_VERSION == 1
+#define MAL_ESR_ONE 0x00080000
+#define MAL_ESR_ONEI 0x00000008
+#elif MAL_VERSION == 2
+#define MAL_ESR_PTE 0x00800000
+#define MAL_ESR_PRE 0x00400000
+#define MAL_ESR_PWE 0x00200000
+#define MAL_ESR_PTEI 0x00000080
+#define MAL_ESR_PREI 0x00000040
+#define MAL_ESR_PWEI 0x00000020
+#else
+#error "Unknown MAL version"
+#endif
+
+#define MAL_IER 0x02
+#define MAL_IER_DE 0x00000010
+#define MAL_IER_OTE 0x00000004
+#define MAL_IER_OE 0x00000002
+#define MAL_IER_PE 0x00000001
+#if MAL_VERSION == 1
+#define MAL_IER_NWE 0x00000008
+#define MAL_IER_SOC_EVENTS MAL_IER_NWE
+#elif MAL_VERSION == 2
+#define MAL_IER_PT 0x00000080
+#define MAL_IER_PRE 0x00000040
+#define MAL_IER_PWE 0x00000020
+#define MAL_IER_SOC_EVENTS (MAL_IER_PT | MAL_IER_PRE | MAL_IER_PWE)
+#else
+#error "Unknown MAL version"
+#endif
+#define MAL_IER_EVENTS (MAL_IER_SOC_EVENTS | MAL_IER_OTE | \
+ MAL_IER_OTE | MAL_IER_OE | MAL_IER_PE)
+
+#define MAL_TXCASR 0x04
+#define MAL_TXCARR 0x05
+#define MAL_TXEOBISR 0x06
+#define MAL_TXDEIR 0x07
+#define MAL_RXCASR 0x10
+#define MAL_RXCARR 0x11
+#define MAL_RXEOBISR 0x12
+#define MAL_RXDEIR 0x13
+#define MAL_TXCTPR(n) ((n) + 0x20)
+#define MAL_RXCTPR(n) ((n) + 0x40)
+#define MAL_RCBS(n) ((n) + 0x60)
+
+/* In reality MAL can handle TX buffers up to 4095 bytes long,
+ * but this isn't a good round number :) --ebs
+ */
+#define MAL_MAX_TX_SIZE 4080
+#define MAL_MAX_RX_SIZE 4080
+
+static inline int mal_rx_size(int len)
+{
+ len = (len + 0xf) & ~0xf;
+ return len > MAL_MAX_RX_SIZE ? MAL_MAX_RX_SIZE : len;
+}
+
+static inline int mal_tx_chunks(int len)
+{
+ return (len + MAL_MAX_TX_SIZE - 1) / MAL_MAX_TX_SIZE;
+}
+
+#define MAL_CHAN_MASK(n) (0x80000000 >> (n))
/* MAL Buffer Descriptor structure */
struct mal_descriptor {
- unsigned short ctrl; /* MAL / Commac status control bits */
- short data_len; /* Max length is 4K-1 (12 bits) */
- unsigned char *data_ptr; /* pointer to actual data buffer */
-} __attribute__ ((packed));
+ u16 ctrl; /* MAL / Commac status control bits */
+ u16 data_len; /* Max length is 4K-1 (12 bits) */
+ u32 data_ptr; /* pointer to actual data buffer */
+};
/* the following defines are for the MadMAL status and control registers. */
/* MADMAL transmit and receive status/control bits */
-#define MAL_RX_CTRL_EMPTY 0x8000
-#define MAL_RX_CTRL_WRAP 0x4000
-#define MAL_RX_CTRL_CM 0x2000
-#define MAL_RX_CTRL_LAST 0x1000
-#define MAL_RX_CTRL_FIRST 0x0800
-#define MAL_RX_CTRL_INTR 0x0400
-
-#define MAL_TX_CTRL_READY 0x8000
-#define MAL_TX_CTRL_WRAP 0x4000
-#define MAL_TX_CTRL_CM 0x2000
-#define MAL_TX_CTRL_LAST 0x1000
-#define MAL_TX_CTRL_INTR 0x0400
+#define MAL_RX_CTRL_EMPTY 0x8000
+#define MAL_RX_CTRL_WRAP 0x4000
+#define MAL_RX_CTRL_CM 0x2000
+#define MAL_RX_CTRL_LAST 0x1000
+#define MAL_RX_CTRL_FIRST 0x0800
+#define MAL_RX_CTRL_INTR 0x0400
+#define MAL_RX_CTRL_SINGLE (MAL_RX_CTRL_LAST | MAL_RX_CTRL_FIRST)
+#define MAL_IS_SINGLE_RX(ctrl) (((ctrl) & MAL_RX_CTRL_SINGLE) == MAL_RX_CTRL_SINGLE)
+
+#define MAL_TX_CTRL_READY 0x8000
+#define MAL_TX_CTRL_WRAP 0x4000
+#define MAL_TX_CTRL_CM 0x2000
+#define MAL_TX_CTRL_LAST 0x1000
+#define MAL_TX_CTRL_INTR 0x0400
struct mal_commac_ops {
- void (*txeob) (void *dev, u32 chanmask);
- void (*txde) (void *dev, u32 chanmask);
- void (*rxeob) (void *dev, u32 chanmask);
- void (*rxde) (void *dev, u32 chanmask);
+ void (*poll_tx) (void *dev);
+ int (*poll_rx) (void *dev, int budget);
+ int (*peek_rx) (void *dev);
+ void (*rxde) (void *dev);
};
struct mal_commac {
- struct mal_commac_ops *ops;
- void *dev;
- u32 tx_chan_mask, rx_chan_mask;
- struct list_head list;
+ struct mal_commac_ops *ops;
+ void *dev;
+ struct list_head poll_list;
+ int rx_stopped;
+
+ u32 tx_chan_mask;
+ u32 rx_chan_mask;
+ struct list_head list;
};
struct ibm_ocp_mal {
- int dcrbase;
+ int dcrbase;
- struct list_head commac;
- u32 tx_chan_mask, rx_chan_mask;
+ struct list_head poll_list;
+ struct net_device poll_dev;
- dma_addr_t tx_phys_addr;
- struct mal_descriptor *tx_virt_addr;
+ struct list_head list;
+ u32 tx_chan_mask;
+ u32 rx_chan_mask;
- dma_addr_t rx_phys_addr;
- struct mal_descriptor *rx_virt_addr;
-};
+ dma_addr_t bd_dma;
+ struct mal_descriptor *bd_virt;
-#define GET_MAL_STANZA(base,dcrn) \
- case base: \
- x = mfdcr(dcrn(base)); \
- break;
-
-#define SET_MAL_STANZA(base,dcrn, val) \
- case base: \
- mtdcr(dcrn(base), (val)); \
- break;
-
-#define GET_MAL0_STANZA(dcrn) GET_MAL_STANZA(DCRN_MAL_BASE,dcrn)
-#define SET_MAL0_STANZA(dcrn,val) SET_MAL_STANZA(DCRN_MAL_BASE,dcrn,val)
-
-#ifdef DCRN_MAL1_BASE
-#define GET_MAL1_STANZA(dcrn) GET_MAL_STANZA(DCRN_MAL1_BASE,dcrn)
-#define SET_MAL1_STANZA(dcrn,val) SET_MAL_STANZA(DCRN_MAL1_BASE,dcrn,val)
-#else /* ! DCRN_MAL1_BASE */
-#define GET_MAL1_STANZA(dcrn)
-#define SET_MAL1_STANZA(dcrn,val)
-#endif
+ struct ocp_def *def;
+};
-#define get_mal_dcrn(mal, dcrn) ({ \
- u32 x; \
- switch ((mal)->dcrbase) { \
- GET_MAL0_STANZA(dcrn) \
- GET_MAL1_STANZA(dcrn) \
- default: \
- x = 0; \
- BUG(); \
- } \
-x; })
-
-#define set_mal_dcrn(mal, dcrn, val) do { \
- switch ((mal)->dcrbase) { \
- SET_MAL0_STANZA(dcrn,val) \
- SET_MAL1_STANZA(dcrn,val) \
- default: \
- BUG(); \
- } } while (0)
-
-static inline void mal_enable_tx_channels(struct ibm_ocp_mal *mal, u32 chanmask)
+static inline u32 get_mal_dcrn(struct ibm_ocp_mal *mal, int reg)
{
- set_mal_dcrn(mal, DCRN_MALTXCASR,
- get_mal_dcrn(mal, DCRN_MALTXCASR) | chanmask);
+ return mfdcr(mal->dcrbase + reg);
}
-static inline void mal_disable_tx_channels(struct ibm_ocp_mal *mal,
- u32 chanmask)
+static inline void set_mal_dcrn(struct ibm_ocp_mal *mal, int reg, u32 val)
{
- set_mal_dcrn(mal, DCRN_MALTXCARR, chanmask);
+ mtdcr(mal->dcrbase + reg, val);
}
-static inline void mal_enable_rx_channels(struct ibm_ocp_mal *mal, u32 chanmask)
-{
- set_mal_dcrn(mal, DCRN_MALRXCASR,
- get_mal_dcrn(mal, DCRN_MALRXCASR) | chanmask);
-}
+/* Register MAL devices */
+int mal_init(void) __init;
+void mal_exit(void) __exit;
-static inline void mal_disable_rx_channels(struct ibm_ocp_mal *mal,
- u32 chanmask)
-{
- set_mal_dcrn(mal, DCRN_MALRXCARR, chanmask);
-}
+int mal_register_commac(struct ibm_ocp_mal *mal,
+ struct mal_commac *commac) __init;
+void mal_unregister_commac(struct ibm_ocp_mal *mal,
+ struct mal_commac *commac) __exit;
+int mal_set_rcbs(struct ibm_ocp_mal *mal, int channel, unsigned long size);
+
+/* Returns BD ring offset for a particular channel
+ (in 'struct mal_descriptor' elements)
+*/
+int mal_tx_bd_offset(struct ibm_ocp_mal *mal, int channel);
+int mal_rx_bd_offset(struct ibm_ocp_mal *mal, int channel);
+
+void mal_enable_tx_channel(struct ibm_ocp_mal *mal, int channel);
+void mal_disable_tx_channel(struct ibm_ocp_mal *mal, int channel);
+void mal_enable_rx_channel(struct ibm_ocp_mal *mal, int channel);
+void mal_disable_rx_channel(struct ibm_ocp_mal *mal, int channel);
-extern int mal_register_commac(struct ibm_ocp_mal *mal,
- struct mal_commac *commac);
-extern int mal_unregister_commac(struct ibm_ocp_mal *mal,
- struct mal_commac *commac);
+/* Add/remove EMAC to/from MAL polling list */
+void mal_poll_add(struct ibm_ocp_mal *mal, struct mal_commac *commac);
+void mal_poll_del(struct ibm_ocp_mal *mal, struct mal_commac *commac);
+
+/* Ethtool MAL registers */
+struct ibm_mal_regs {
+ u32 tx_count;
+ u32 rx_count;
+
+ u32 cfg;
+ u32 esr;
+ u32 ier;
+ u32 tx_casr;
+ u32 tx_carr;
+ u32 tx_eobisr;
+ u32 tx_deir;
+ u32 rx_casr;
+ u32 rx_carr;
+ u32 rx_eobisr;
+ u32 rx_deir;
+ u32 tx_ctpr[32];
+ u32 rx_ctpr[32];
+ u32 rcbs[32];
+};
-extern int mal_set_rcbs(struct ibm_ocp_mal *mal, int channel,
- unsigned long size);
+int mal_get_regs_len(struct ibm_ocp_mal *mal);
+void *mal_dump_regs(struct ibm_ocp_mal *mal, void *buf);
-#endif /* _IBM_EMAC_MAL_H */
+#endif /* __IBM_EMAC_MAL_H_ */
diff --git a/drivers/net/ibm_emac/ibm_emac_phy.c b/drivers/net/ibm_emac/ibm_emac_phy.c
index 14213f090e91..a27e49cfe43b 100644
--- a/drivers/net/ibm_emac/ibm_emac_phy.c
+++ b/drivers/net/ibm_emac/ibm_emac_phy.c
@@ -1,96 +1,80 @@
/*
- * ibm_ocp_phy.c
+ * drivers/net/ibm_emac/ibm_emac_phy.c
*
- * PHY drivers for the ibm ocp ethernet driver. Borrowed
- * from sungem_phy.c, though I only kept the generic MII
+ * Driver for PowerPC 4xx on-chip ethernet controller, PHY support.
+ * Borrowed from sungem_phy.c, though I only kept the generic MII
* driver for now.
*
* This file should be shared with other drivers or eventually
* merged as the "low level" part of miilib
*
* (c) 2003, Benjamin Herrenscmidt (benh@kernel.crashing.org)
+ * (c) 2004-2005, Eugene Surovegin <ebs@ebshome.net>
*
*/
-
#include <linux/config.h>
-
#include <linux/module.h>
-
#include <linux/kernel.h>
-#include <linux/sched.h>
#include <linux/types.h>
#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/delay.h>
+#include <asm/ocp.h>
+
#include "ibm_emac_phy.h"
-static int reset_one_mii_phy(struct mii_phy *phy, int phy_id)
+static inline int phy_read(struct mii_phy *phy, int reg)
+{
+ return phy->mdio_read(phy->dev, phy->address, reg);
+}
+
+static inline void phy_write(struct mii_phy *phy, int reg, int val)
{
- u16 val;
+ phy->mdio_write(phy->dev, phy->address, reg, val);
+}
+
+int mii_reset_phy(struct mii_phy *phy)
+{
+ int val;
int limit = 10000;
- val = __phy_read(phy, phy_id, MII_BMCR);
+ val = phy_read(phy, MII_BMCR);
val &= ~BMCR_ISOLATE;
val |= BMCR_RESET;
- __phy_write(phy, phy_id, MII_BMCR, val);
+ phy_write(phy, MII_BMCR, val);
- udelay(100);
+ udelay(300);
while (limit--) {
- val = __phy_read(phy, phy_id, MII_BMCR);
- if ((val & BMCR_RESET) == 0)
+ val = phy_read(phy, MII_BMCR);
+ if (val >= 0 && (val & BMCR_RESET) == 0)
break;
udelay(10);
}
if ((val & BMCR_ISOLATE) && limit > 0)
- __phy_write(phy, phy_id, MII_BMCR, val & ~BMCR_ISOLATE);
-
- return (limit <= 0);
-}
-
-static int cis8201_init(struct mii_phy *phy)
-{
- u16 epcr;
-
- epcr = phy_read(phy, MII_CIS8201_EPCR);
- epcr &= ~EPCR_MODE_MASK;
-
- switch (phy->mode) {
- case PHY_MODE_TBI:
- epcr |= EPCR_TBI_MODE;
- break;
- case PHY_MODE_RTBI:
- epcr |= EPCR_RTBI_MODE;
- break;
- case PHY_MODE_GMII:
- epcr |= EPCR_GMII_MODE;
- break;
- case PHY_MODE_RGMII:
- default:
- epcr |= EPCR_RGMII_MODE;
- }
+ phy_write(phy, MII_BMCR, val & ~BMCR_ISOLATE);
- phy_write(phy, MII_CIS8201_EPCR, epcr);
-
- return 0;
+ return limit <= 0;
}
static int genmii_setup_aneg(struct mii_phy *phy, u32 advertise)
{
- u16 ctl, adv;
+ int ctl, adv;
- phy->autoneg = 1;
+ phy->autoneg = AUTONEG_ENABLE;
phy->speed = SPEED_10;
phy->duplex = DUPLEX_HALF;
- phy->pause = 0;
+ phy->pause = phy->asym_pause = 0;
phy->advertising = advertise;
/* Setup standard advertise */
adv = phy_read(phy, MII_ADVERTISE);
- adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
+ if (adv < 0)
+ return adv;
+ adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP |
+ ADVERTISE_PAUSE_ASYM);
if (advertise & ADVERTISED_10baseT_Half)
adv |= ADVERTISE_10HALF;
if (advertise & ADVERTISED_10baseT_Full)
@@ -99,8 +83,25 @@ static int genmii_setup_aneg(struct mii_phy *phy, u32 advertise)
adv |= ADVERTISE_100HALF;
if (advertise & ADVERTISED_100baseT_Full)
adv |= ADVERTISE_100FULL;
+ if (advertise & ADVERTISED_Pause)
+ adv |= ADVERTISE_PAUSE_CAP;
+ if (advertise & ADVERTISED_Asym_Pause)
+ adv |= ADVERTISE_PAUSE_ASYM;
phy_write(phy, MII_ADVERTISE, adv);
+ if (phy->features &
+ (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)) {
+ adv = phy_read(phy, MII_CTRL1000);
+ if (adv < 0)
+ return adv;
+ adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
+ if (advertise & ADVERTISED_1000baseT_Full)
+ adv |= ADVERTISE_1000FULL;
+ if (advertise & ADVERTISED_1000baseT_Half)
+ adv |= ADVERTISE_1000HALF;
+ phy_write(phy, MII_CTRL1000, adv);
+ }
+
/* Start/Restart aneg */
ctl = phy_read(phy, MII_BMCR);
ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
@@ -111,14 +112,16 @@ static int genmii_setup_aneg(struct mii_phy *phy, u32 advertise)
static int genmii_setup_forced(struct mii_phy *phy, int speed, int fd)
{
- u16 ctl;
+ int ctl;
- phy->autoneg = 0;
+ phy->autoneg = AUTONEG_DISABLE;
phy->speed = speed;
phy->duplex = fd;
- phy->pause = 0;
+ phy->pause = phy->asym_pause = 0;
ctl = phy_read(phy, MII_BMCR);
+ if (ctl < 0)
+ return ctl;
ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_ANENABLE);
/* First reset the PHY */
@@ -132,6 +135,8 @@ static int genmii_setup_forced(struct mii_phy *phy, int speed, int fd)
ctl |= BMCR_SPEED100;
break;
case SPEED_1000:
+ ctl |= BMCR_SPEED1000;
+ break;
default:
return -EINVAL;
}
@@ -144,112 +149,143 @@ static int genmii_setup_forced(struct mii_phy *phy, int speed, int fd)
static int genmii_poll_link(struct mii_phy *phy)
{
- u16 status;
+ int status;
- (void)phy_read(phy, MII_BMSR);
+ /* Clear latched value with dummy read */
+ phy_read(phy, MII_BMSR);
status = phy_read(phy, MII_BMSR);
- if ((status & BMSR_LSTATUS) == 0)
+ if (status < 0 || (status & BMSR_LSTATUS) == 0)
return 0;
- if (phy->autoneg && !(status & BMSR_ANEGCOMPLETE))
+ if (phy->autoneg == AUTONEG_ENABLE && !(status & BMSR_ANEGCOMPLETE))
return 0;
return 1;
}
-#define MII_CIS8201_ACSR 0x1c
-#define ACSR_DUPLEX_STATUS 0x0020
-#define ACSR_SPEED_1000BASET 0x0010
-#define ACSR_SPEED_100BASET 0x0008
-
-static int cis8201_read_link(struct mii_phy *phy)
+static int genmii_read_link(struct mii_phy *phy)
{
- u16 acsr;
+ if (phy->autoneg == AUTONEG_ENABLE) {
+ int glpa = 0;
+ int lpa = phy_read(phy, MII_LPA) & phy_read(phy, MII_ADVERTISE);
+ if (lpa < 0)
+ return lpa;
+
+ if (phy->features &
+ (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)) {
+ int adv = phy_read(phy, MII_CTRL1000);
+ glpa = phy_read(phy, MII_STAT1000);
+
+ if (glpa < 0 || adv < 0)
+ return adv;
+
+ glpa &= adv << 2;
+ }
+
+ phy->speed = SPEED_10;
+ phy->duplex = DUPLEX_HALF;
+ phy->pause = phy->asym_pause = 0;
+
+ if (glpa & (LPA_1000FULL | LPA_1000HALF)) {
+ phy->speed = SPEED_1000;
+ if (glpa & LPA_1000FULL)
+ phy->duplex = DUPLEX_FULL;
+ } else if (lpa & (LPA_100FULL | LPA_100HALF)) {
+ phy->speed = SPEED_100;
+ if (lpa & LPA_100FULL)
+ phy->duplex = DUPLEX_FULL;
+ } else if (lpa & LPA_10FULL)
+ phy->duplex = DUPLEX_FULL;
- if (phy->autoneg) {
- acsr = phy_read(phy, MII_CIS8201_ACSR);
+ if (phy->duplex == DUPLEX_FULL) {
+ phy->pause = lpa & LPA_PAUSE_CAP ? 1 : 0;
+ phy->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0;
+ }
+ } else {
+ int bmcr = phy_read(phy, MII_BMCR);
+ if (bmcr < 0)
+ return bmcr;
- if (acsr & ACSR_DUPLEX_STATUS)
+ if (bmcr & BMCR_FULLDPLX)
phy->duplex = DUPLEX_FULL;
else
phy->duplex = DUPLEX_HALF;
- if (acsr & ACSR_SPEED_1000BASET) {
+ if (bmcr & BMCR_SPEED1000)
phy->speed = SPEED_1000;
- } else if (acsr & ACSR_SPEED_100BASET)
+ else if (bmcr & BMCR_SPEED100)
phy->speed = SPEED_100;
else
phy->speed = SPEED_10;
- phy->pause = 0;
- }
- /* On non-aneg, we assume what we put in BMCR is the speed,
- * though magic-aneg shouldn't prevent this case from occurring
- */
+ phy->pause = phy->asym_pause = 0;
+ }
return 0;
}
-static int genmii_read_link(struct mii_phy *phy)
+/* Generic implementation for most 10/100/1000 PHYs */
+static struct mii_phy_ops generic_phy_ops = {
+ .setup_aneg = genmii_setup_aneg,
+ .setup_forced = genmii_setup_forced,
+ .poll_link = genmii_poll_link,
+ .read_link = genmii_read_link
+};
+
+static struct mii_phy_def genmii_phy_def = {
+ .phy_id = 0x00000000,
+ .phy_id_mask = 0x00000000,
+ .name = "Generic MII",
+ .ops = &generic_phy_ops
+};
+
+/* CIS8201 */
+#define MII_CIS8201_EPCR 0x17
+#define EPCR_MODE_MASK 0x3000
+#define EPCR_GMII_MODE 0x0000
+#define EPCR_RGMII_MODE 0x1000
+#define EPCR_TBI_MODE 0x2000
+#define EPCR_RTBI_MODE 0x3000
+
+static int cis8201_init(struct mii_phy *phy)
{
- u16 lpa;
+ int epcr;
- if (phy->autoneg) {
- lpa = phy_read(phy, MII_LPA) & phy_read(phy, MII_ADVERTISE);
+ epcr = phy_read(phy, MII_CIS8201_EPCR);
+ if (epcr < 0)
+ return epcr;
- phy->speed = SPEED_10;
- phy->duplex = DUPLEX_HALF;
- phy->pause = 0;
+ epcr &= ~EPCR_MODE_MASK;
- if (lpa & (LPA_100FULL | LPA_100HALF)) {
- phy->speed = SPEED_100;
- if (lpa & LPA_100FULL)
- phy->duplex = DUPLEX_FULL;
- } else if (lpa & LPA_10FULL)
- phy->duplex = DUPLEX_FULL;
+ switch (phy->mode) {
+ case PHY_MODE_TBI:
+ epcr |= EPCR_TBI_MODE;
+ break;
+ case PHY_MODE_RTBI:
+ epcr |= EPCR_RTBI_MODE;
+ break;
+ case PHY_MODE_GMII:
+ epcr |= EPCR_GMII_MODE;
+ break;
+ case PHY_MODE_RGMII:
+ default:
+ epcr |= EPCR_RGMII_MODE;
}
- /* On non-aneg, we assume what we put in BMCR is the speed,
- * though magic-aneg shouldn't prevent this case from occurring
- */
+
+ phy_write(phy, MII_CIS8201_EPCR, epcr);
return 0;
}
-#define MII_BASIC_FEATURES (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \
- SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \
- SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII)
-#define MII_GBIT_FEATURES (MII_BASIC_FEATURES | \
- SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full)
-
-/* CIS8201 phy ops */
static struct mii_phy_ops cis8201_phy_ops = {
- init:cis8201_init,
- setup_aneg:genmii_setup_aneg,
- setup_forced:genmii_setup_forced,
- poll_link:genmii_poll_link,
- read_link:cis8201_read_link
-};
-
-/* Generic implementation for most 10/100 PHYs */
-static struct mii_phy_ops generic_phy_ops = {
- setup_aneg:genmii_setup_aneg,
- setup_forced:genmii_setup_forced,
- poll_link:genmii_poll_link,
- read_link:genmii_read_link
+ .init = cis8201_init,
+ .setup_aneg = genmii_setup_aneg,
+ .setup_forced = genmii_setup_forced,
+ .poll_link = genmii_poll_link,
+ .read_link = genmii_read_link
};
static struct mii_phy_def cis8201_phy_def = {
- phy_id:0x000fc410,
- phy_id_mask:0x000ffff0,
- name:"CIS8201 Gigabit Ethernet",
- features:MII_GBIT_FEATURES,
- magic_aneg:0,
- ops:&cis8201_phy_ops
-};
-
-static struct mii_phy_def genmii_phy_def = {
- phy_id:0x00000000,
- phy_id_mask:0x00000000,
- name:"Generic MII",
- features:MII_BASIC_FEATURES,
- magic_aneg:0,
- ops:&generic_phy_ops
+ .phy_id = 0x000fc410,
+ .phy_id_mask = 0x000ffff0,
+ .name = "CIS8201 Gigabit Ethernet",
+ .ops = &cis8201_phy_ops
};
static struct mii_phy_def *mii_phy_table[] = {
@@ -258,39 +294,60 @@ static struct mii_phy_def *mii_phy_table[] = {
NULL
};
-int mii_phy_probe(struct mii_phy *phy, int mii_id)
+int mii_phy_probe(struct mii_phy *phy, int address)
{
- int rc;
- u32 id;
struct mii_phy_def *def;
int i;
+ u32 id;
- phy->autoneg = 0;
+ phy->autoneg = AUTONEG_DISABLE;
phy->advertising = 0;
- phy->mii_id = mii_id;
- phy->speed = 0;
- phy->duplex = 0;
- phy->pause = 0;
-
- /* Take PHY out of isloate mode and reset it. */
- rc = reset_one_mii_phy(phy, mii_id);
- if (rc)
+ phy->address = address;
+ phy->speed = SPEED_10;
+ phy->duplex = DUPLEX_HALF;
+ phy->pause = phy->asym_pause = 0;
+
+ /* Take PHY out of isolate mode and reset it. */
+ if (mii_reset_phy(phy))
return -ENODEV;
/* Read ID and find matching entry */
- id = (phy_read(phy, MII_PHYSID1) << 16 | phy_read(phy, MII_PHYSID2))
- & 0xfffffff0;
+ id = (phy_read(phy, MII_PHYSID1) << 16) | phy_read(phy, MII_PHYSID2);
for (i = 0; (def = mii_phy_table[i]) != NULL; i++)
if ((id & def->phy_id_mask) == def->phy_id)
break;
/* Should never be NULL (we have a generic entry), but... */
- if (def == NULL)
+ if (!def)
return -ENODEV;
phy->def = def;
+ /* Determine PHY features if needed */
+ phy->features = def->features;
+ if (!phy->features) {
+ u16 bmsr = phy_read(phy, MII_BMSR);
+ if (bmsr & BMSR_ANEGCAPABLE)
+ phy->features |= SUPPORTED_Autoneg;
+ if (bmsr & BMSR_10HALF)
+ phy->features |= SUPPORTED_10baseT_Half;
+ if (bmsr & BMSR_10FULL)
+ phy->features |= SUPPORTED_10baseT_Full;
+ if (bmsr & BMSR_100HALF)
+ phy->features |= SUPPORTED_100baseT_Half;
+ if (bmsr & BMSR_100FULL)
+ phy->features |= SUPPORTED_100baseT_Full;
+ if (bmsr & BMSR_ESTATEN) {
+ u16 esr = phy_read(phy, MII_ESTATUS);
+ if (esr & ESTATUS_1000_TFULL)
+ phy->features |= SUPPORTED_1000baseT_Full;
+ if (esr & ESTATUS_1000_THALF)
+ phy->features |= SUPPORTED_1000baseT_Half;
+ }
+ phy->features |= SUPPORTED_MII;
+ }
+
/* Setup default advertising */
- phy->advertising = def->features;
+ phy->advertising = phy->features;
return 0;
}
diff --git a/drivers/net/ibm_emac/ibm_emac_phy.h b/drivers/net/ibm_emac/ibm_emac_phy.h
index 61afbea96563..a70e0fea54c4 100644
--- a/drivers/net/ibm_emac/ibm_emac_phy.h
+++ b/drivers/net/ibm_emac/ibm_emac_phy.h
@@ -1,65 +1,25 @@
-
/*
- * ibm_emac_phy.h
- *
+ * drivers/net/ibm_emac/ibm_emac_phy.h
*
- * Benjamin Herrenschmidt <benh@kernel.crashing.org>
- * February 2003
+ * Driver for PowerPC 4xx on-chip ethernet controller, PHY support
*
- * This program is free software; you can redistribute 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.
+ * Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ * February 2003
*
- * 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.
+ * Minor additions by Eugene Surovegin <ebs@ebshome.net>, 2004
*
+ * This program is free software; you can redistribute 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 file basically duplicates sungem_phy.{c,h} with different PHYs
* supported. I'm looking into merging that in a single mii layer more
* flexible than mii.c
*/
-#ifndef _IBM_EMAC_PHY_H_
-#define _IBM_EMAC_PHY_H_
-
-/*
- * PHY mode settings
- * Used for multi-mode capable PHYs
- */
-#define PHY_MODE_NA 0
-#define PHY_MODE_MII 1
-#define PHY_MODE_RMII 2
-#define PHY_MODE_SMII 3
-#define PHY_MODE_RGMII 4
-#define PHY_MODE_TBI 5
-#define PHY_MODE_GMII 6
-#define PHY_MODE_RTBI 7
-#define PHY_MODE_SGMII 8
-
-/*
- * PHY specific registers/values
- */
-
-/* CIS8201 */
-#define MII_CIS8201_EPCR 0x17
-#define EPCR_MODE_MASK 0x3000
-#define EPCR_GMII_MODE 0x0000
-#define EPCR_RGMII_MODE 0x1000
-#define EPCR_TBI_MODE 0x2000
-#define EPCR_RTBI_MODE 0x3000
+#ifndef _IBM_OCP_PHY_H_
+#define _IBM_OCP_PHY_H_
struct mii_phy;
@@ -77,7 +37,8 @@ struct mii_phy_ops {
struct mii_phy_def {
u32 phy_id; /* Concatenated ID1 << 16 | ID2 */
u32 phy_id_mask; /* Significant bits */
- u32 features; /* Ethtool SUPPORTED_* defines */
+ u32 features; /* Ethtool SUPPORTED_* defines or
+ 0 for autodetect */
int magic_aneg; /* Autoneg does all speed test for us */
const char *name;
const struct mii_phy_ops *ops;
@@ -86,8 +47,11 @@ struct mii_phy_def {
/* An instance of a PHY, partially borrowed from mii_if_info */
struct mii_phy {
struct mii_phy_def *def;
- int advertising;
- int mii_id;
+ u32 advertising; /* Ethtool ADVERTISED_* defines */
+ u32 features; /* Copied from mii_phy_def.features
+ or determined automaticaly */
+ int address; /* PHY address */
+ int mode; /* PHY mode */
/* 1: autoneg enabled, 0: disabled */
int autoneg;
@@ -98,40 +62,19 @@ struct mii_phy {
int speed;
int duplex;
int pause;
-
- /* PHY mode - if needed */
- int mode;
+ int asym_pause;
/* Provided by host chip */
struct net_device *dev;
- int (*mdio_read) (struct net_device * dev, int mii_id, int reg);
- void (*mdio_write) (struct net_device * dev, int mii_id, int reg,
+ int (*mdio_read) (struct net_device * dev, int addr, int reg);
+ void (*mdio_write) (struct net_device * dev, int addr, int reg,
int val);
};
/* Pass in a struct mii_phy with dev, mdio_read and mdio_write
* filled, the remaining fields will be filled on return
*/
-extern int mii_phy_probe(struct mii_phy *phy, int mii_id);
-
-static inline int __phy_read(struct mii_phy *phy, int id, int reg)
-{
- return phy->mdio_read(phy->dev, id, reg);
-}
-
-static inline void __phy_write(struct mii_phy *phy, int id, int reg, int val)
-{
- phy->mdio_write(phy->dev, id, reg, val);
-}
-
-static inline int phy_read(struct mii_phy *phy, int reg)
-{
- return phy->mdio_read(phy->dev, phy->mii_id, reg);
-}
-
-static inline void phy_write(struct mii_phy *phy, int reg, int val)
-{
- phy->mdio_write(phy->dev, phy->mii_id, reg, val);
-}
+int mii_phy_probe(struct mii_phy *phy, int address);
+int mii_reset_phy(struct mii_phy *phy);
-#endif /* _IBM_EMAC_PHY_H_ */
+#endif /* _IBM_OCP_PHY_H_ */
diff --git a/drivers/net/ibm_emac/ibm_emac_rgmii.c b/drivers/net/ibm_emac/ibm_emac_rgmii.c
new file mode 100644
index 000000000000..f0b1ffb2dbbf
--- /dev/null
+++ b/drivers/net/ibm_emac/ibm_emac_rgmii.c
@@ -0,0 +1,201 @@
+/*
+ * drivers/net/ibm_emac/ibm_emac_rgmii.c
+ *
+ * Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge support.
+ *
+ * Copyright (c) 2004, 2005 Zultys Technologies.
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ *
+ * Based on original work by
+ * Matt Porter <mporter@kernel.crashing.org>
+ * Copyright 2004 MontaVista Software, 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.
+ *
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/ethtool.h>
+#include <asm/io.h>
+
+#include "ibm_emac_core.h"
+#include "ibm_emac_debug.h"
+
+/* RGMIIx_FER */
+#define RGMII_FER_MASK(idx) (0x7 << ((idx) * 4))
+#define RGMII_FER_RTBI(idx) (0x4 << ((idx) * 4))
+#define RGMII_FER_RGMII(idx) (0x5 << ((idx) * 4))
+#define RGMII_FER_TBI(idx) (0x6 << ((idx) * 4))
+#define RGMII_FER_GMII(idx) (0x7 << ((idx) * 4))
+
+/* RGMIIx_SSR */
+#define RGMII_SSR_MASK(idx) (0x7 << ((idx) * 8))
+#define RGMII_SSR_100(idx) (0x2 << ((idx) * 8))
+#define RGMII_SSR_1000(idx) (0x4 << ((idx) * 8))
+
+/* RGMII bridge supports only GMII/TBI and RGMII/RTBI PHYs */
+static inline int rgmii_valid_mode(int phy_mode)
+{
+ return phy_mode == PHY_MODE_GMII ||
+ phy_mode == PHY_MODE_RGMII ||
+ phy_mode == PHY_MODE_TBI ||
+ phy_mode == PHY_MODE_RTBI;
+}
+
+static inline const char *rgmii_mode_name(int mode)
+{
+ switch (mode) {
+ case PHY_MODE_RGMII:
+ return "RGMII";
+ case PHY_MODE_TBI:
+ return "TBI";
+ case PHY_MODE_GMII:
+ return "GMII";
+ case PHY_MODE_RTBI:
+ return "RTBI";
+ default:
+ BUG();
+ }
+}
+
+static inline u32 rgmii_mode_mask(int mode, int input)
+{
+ switch (mode) {
+ case PHY_MODE_RGMII:
+ return RGMII_FER_RGMII(input);
+ case PHY_MODE_TBI:
+ return RGMII_FER_TBI(input);
+ case PHY_MODE_GMII:
+ return RGMII_FER_GMII(input);
+ case PHY_MODE_RTBI:
+ return RGMII_FER_RTBI(input);
+ default:
+ BUG();
+ }
+}
+
+static int __init rgmii_init(struct ocp_device *ocpdev, int input, int mode)
+{
+ struct ibm_ocp_rgmii *dev = ocp_get_drvdata(ocpdev);
+ struct rgmii_regs *p;
+
+ RGMII_DBG("%d: init(%d, %d)" NL, ocpdev->def->index, input, mode);
+
+ if (!dev) {
+ dev = kzalloc(sizeof(struct ibm_ocp_rgmii), GFP_KERNEL);
+ if (!dev) {
+ printk(KERN_ERR
+ "rgmii%d: couldn't allocate device structure!\n",
+ ocpdev->def->index);
+ return -ENOMEM;
+ }
+
+ p = (struct rgmii_regs *)ioremap(ocpdev->def->paddr,
+ sizeof(struct rgmii_regs));
+ if (!p) {
+ printk(KERN_ERR
+ "rgmii%d: could not ioremap device registers!\n",
+ ocpdev->def->index);
+ kfree(dev);
+ return -ENOMEM;
+ }
+
+ dev->base = p;
+ ocp_set_drvdata(ocpdev, dev);
+
+ /* Disable all inputs by default */
+ out_be32(&p->fer, 0);
+ } else
+ p = dev->base;
+
+ /* Enable this input */
+ out_be32(&p->fer, in_be32(&p->fer) | rgmii_mode_mask(mode, input));
+
+ printk(KERN_NOTICE "rgmii%d: input %d in %s mode\n",
+ ocpdev->def->index, input, rgmii_mode_name(mode));
+
+ ++dev->users;
+ return 0;
+}
+
+int __init rgmii_attach(void *emac)
+{
+ struct ocp_enet_private *dev = emac;
+ struct ocp_func_emac_data *emacdata = dev->def->additions;
+
+ /* Check if we need to attach to a RGMII */
+ if (emacdata->rgmii_idx >= 0 && rgmii_valid_mode(emacdata->phy_mode)) {
+ dev->rgmii_input = emacdata->rgmii_mux;
+ dev->rgmii_dev =
+ ocp_find_device(OCP_VENDOR_IBM, OCP_FUNC_RGMII,
+ emacdata->rgmii_idx);
+ if (!dev->rgmii_dev) {
+ printk(KERN_ERR "emac%d: unknown rgmii%d!\n",
+ dev->def->index, emacdata->rgmii_idx);
+ return -ENODEV;
+ }
+ if (rgmii_init
+ (dev->rgmii_dev, dev->rgmii_input, emacdata->phy_mode)) {
+ printk(KERN_ERR
+ "emac%d: rgmii%d initialization failed!\n",
+ dev->def->index, emacdata->rgmii_idx);
+ return -ENODEV;
+ }
+ }
+ return 0;
+}
+
+void rgmii_set_speed(struct ocp_device *ocpdev, int input, int speed)
+{
+ struct ibm_ocp_rgmii *dev = ocp_get_drvdata(ocpdev);
+ u32 ssr = in_be32(&dev->base->ssr) & ~RGMII_SSR_MASK(input);
+
+ RGMII_DBG("%d: speed(%d, %d)" NL, ocpdev->def->index, input, speed);
+
+ if (speed == SPEED_1000)
+ ssr |= RGMII_SSR_1000(input);
+ else if (speed == SPEED_100)
+ ssr |= RGMII_SSR_100(input);
+
+ out_be32(&dev->base->ssr, ssr);
+}
+
+void __exit __rgmii_fini(struct ocp_device *ocpdev, int input)
+{
+ struct ibm_ocp_rgmii *dev = ocp_get_drvdata(ocpdev);
+ BUG_ON(!dev || dev->users == 0);
+
+ RGMII_DBG("%d: fini(%d)" NL, ocpdev->def->index, input);
+
+ /* Disable this input */
+ out_be32(&dev->base->fer,
+ in_be32(&dev->base->fer) & ~RGMII_FER_MASK(input));
+
+ if (!--dev->users) {
+ /* Free everything if this is the last user */
+ ocp_set_drvdata(ocpdev, NULL);
+ iounmap((void *)dev->base);
+ kfree(dev);
+ }
+}
+
+int __rgmii_get_regs_len(struct ocp_device *ocpdev)
+{
+ return sizeof(struct emac_ethtool_regs_subhdr) +
+ sizeof(struct rgmii_regs);
+}
+
+void *rgmii_dump_regs(struct ocp_device *ocpdev, void *buf)
+{
+ struct ibm_ocp_rgmii *dev = ocp_get_drvdata(ocpdev);
+ struct emac_ethtool_regs_subhdr *hdr = buf;
+ struct rgmii_regs *regs = (struct rgmii_regs *)(hdr + 1);
+
+ hdr->version = 0;
+ hdr->index = ocpdev->def->index;
+ memcpy_fromio(regs, dev->base, sizeof(struct rgmii_regs));
+ return regs + 1;
+}
diff --git a/drivers/net/ibm_emac/ibm_emac_rgmii.h b/drivers/net/ibm_emac/ibm_emac_rgmii.h
index 49f188f4ea6e..a1ffb8a44fff 100644
--- a/drivers/net/ibm_emac/ibm_emac_rgmii.h
+++ b/drivers/net/ibm_emac/ibm_emac_rgmii.h
@@ -1,5 +1,7 @@
/*
- * Defines for the IBM RGMII bridge
+ * drivers/net/ibm_emac/ibm_emac_rgmii.c
+ *
+ * Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge support.
*
* Based on ocp_zmii.h/ibm_emac_zmii.h
* Armin Kuster akuster@mvista.com
@@ -7,6 +9,9 @@
* Copyright 2004 MontaVista Software, Inc.
* Matt Porter <mporter@kernel.crashing.org>
*
+ * Copyright (c) 2004, 2005 Zultys Technologies.
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ *
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
@@ -19,47 +24,42 @@
#include <linux/config.h>
/* RGMII bridge */
-typedef struct rgmii_regs {
+struct rgmii_regs {
u32 fer; /* Function enable register */
u32 ssr; /* Speed select register */
-} rgmii_t;
-
-#define RGMII_INPUTS 4
+};
/* RGMII device */
struct ibm_ocp_rgmii {
struct rgmii_regs *base;
- int mode[RGMII_INPUTS];
int users; /* number of EMACs using this RGMII bridge */
};
-/* Fuctional Enable Reg */
-#define RGMII_FER_MASK(x) (0x00000007 << (4*x))
-#define RGMII_RTBI 0x00000004
-#define RGMII_RGMII 0x00000005
-#define RGMII_TBI 0x00000006
-#define RGMII_GMII 0x00000007
-
-/* Speed Selection reg */
+#ifdef CONFIG_IBM_EMAC_RGMII
+int rgmii_attach(void *emac) __init;
-#define RGMII_SP2_100 0x00000002
-#define RGMII_SP2_1000 0x00000004
-#define RGMII_SP3_100 0x00000200
-#define RGMII_SP3_1000 0x00000400
+void __rgmii_fini(struct ocp_device *ocpdev, int input) __exit;
+static inline void rgmii_fini(struct ocp_device *ocpdev, int input)
+{
+ if (ocpdev)
+ __rgmii_fini(ocpdev, input);
+}
-#define RGMII_MII2_SPDMASK 0x00000007
-#define RGMII_MII3_SPDMASK 0x00000700
+void rgmii_set_speed(struct ocp_device *ocpdev, int input, int speed);
-#define RGMII_MII2_100MB RGMII_SP2_100 & ~RGMII_SP2_1000
-#define RGMII_MII2_1000MB RGMII_SP2_1000 & ~RGMII_SP2_100
-#define RGMII_MII2_10MB ~(RGMII_SP2_100 | RGMII_SP2_1000)
-#define RGMII_MII3_100MB RGMII_SP3_100 & ~RGMII_SP3_1000
-#define RGMII_MII3_1000MB RGMII_SP3_1000 & ~RGMII_SP3_100
-#define RGMII_MII3_10MB ~(RGMII_SP3_100 | RGMII_SP3_1000)
+int __rgmii_get_regs_len(struct ocp_device *ocpdev);
+static inline int rgmii_get_regs_len(struct ocp_device *ocpdev)
+{
+ return ocpdev ? __rgmii_get_regs_len(ocpdev) : 0;
+}
-#define RTBI 0
-#define RGMII 1
-#define TBI 2
-#define GMII 3
+void *rgmii_dump_regs(struct ocp_device *ocpdev, void *buf);
+#else
+# define rgmii_attach(x) 0
+# define rgmii_fini(x,y) ((void)0)
+# define rgmii_set_speed(x,y,z) ((void)0)
+# define rgmii_get_regs_len(x) 0
+# define rgmii_dump_regs(x,buf) (buf)
+#endif /* !CONFIG_IBM_EMAC_RGMII */
#endif /* _IBM_EMAC_RGMII_H_ */
diff --git a/drivers/net/ibm_emac/ibm_emac_tah.c b/drivers/net/ibm_emac/ibm_emac_tah.c
new file mode 100644
index 000000000000..af08afc22f9f
--- /dev/null
+++ b/drivers/net/ibm_emac/ibm_emac_tah.c
@@ -0,0 +1,111 @@
+/*
+ * drivers/net/ibm_emac/ibm_emac_tah.c
+ *
+ * Driver for PowerPC 4xx on-chip ethernet controller, TAH support.
+ *
+ * Copyright 2004 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.org>
+ *
+ * Copyright (c) 2005 Eugene Surovegin <ebs@ebshome.net>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include <linux/config.h>
+#include <asm/io.h>
+
+#include "ibm_emac_core.h"
+
+static int __init tah_init(struct ocp_device *ocpdev)
+{
+ struct tah_regs *p;
+
+ if (ocp_get_drvdata(ocpdev)) {
+ printk(KERN_ERR "tah%d: already in use!\n", ocpdev->def->index);
+ return -EBUSY;
+ }
+
+ /* Initialize TAH and enable IPv4 checksum verification, no TSO yet */
+ p = (struct tah_regs *)ioremap(ocpdev->def->paddr, sizeof(*p));
+ if (!p) {
+ printk(KERN_ERR "tah%d: could not ioremap device registers!\n",
+ ocpdev->def->index);
+ return -ENOMEM;
+ }
+ ocp_set_drvdata(ocpdev, p);
+ __tah_reset(ocpdev);
+
+ return 0;
+}
+
+int __init tah_attach(void *emac)
+{
+ struct ocp_enet_private *dev = emac;
+ struct ocp_func_emac_data *emacdata = dev->def->additions;
+
+ /* Check if we need to attach to a TAH */
+ if (emacdata->tah_idx >= 0) {
+ dev->tah_dev = ocp_find_device(OCP_ANY_ID, OCP_FUNC_TAH,
+ emacdata->tah_idx);
+ if (!dev->tah_dev) {
+ printk(KERN_ERR "emac%d: unknown tah%d!\n",
+ dev->def->index, emacdata->tah_idx);
+ return -ENODEV;
+ }
+ if (tah_init(dev->tah_dev)) {
+ printk(KERN_ERR
+ "emac%d: tah%d initialization failed!\n",
+ dev->def->index, emacdata->tah_idx);
+ return -ENODEV;
+ }
+ }
+ return 0;
+}
+
+void __exit __tah_fini(struct ocp_device *ocpdev)
+{
+ struct tah_regs *p = ocp_get_drvdata(ocpdev);
+ BUG_ON(!p);
+ ocp_set_drvdata(ocpdev, NULL);
+ iounmap((void *)p);
+}
+
+void __tah_reset(struct ocp_device *ocpdev)
+{
+ struct tah_regs *p = ocp_get_drvdata(ocpdev);
+ int n;
+
+ /* Reset TAH */
+ out_be32(&p->mr, TAH_MR_SR);
+ n = 100;
+ while ((in_be32(&p->mr) & TAH_MR_SR) && n)
+ --n;
+
+ if (unlikely(!n))
+ printk(KERN_ERR "tah%d: reset timeout\n", ocpdev->def->index);
+
+ /* 10KB TAH TX FIFO accomodates the max MTU of 9000 */
+ out_be32(&p->mr,
+ TAH_MR_CVR | TAH_MR_ST_768 | TAH_MR_TFS_10KB | TAH_MR_DTFP |
+ TAH_MR_DIG);
+}
+
+int __tah_get_regs_len(struct ocp_device *ocpdev)
+{
+ return sizeof(struct emac_ethtool_regs_subhdr) +
+ sizeof(struct tah_regs);
+}
+
+void *tah_dump_regs(struct ocp_device *ocpdev, void *buf)
+{
+ struct tah_regs *dev = ocp_get_drvdata(ocpdev);
+ struct emac_ethtool_regs_subhdr *hdr = buf;
+ struct tah_regs *regs = (struct tah_regs *)(hdr + 1);
+
+ hdr->version = 0;
+ hdr->index = ocpdev->def->index;
+ memcpy_fromio(regs, dev, sizeof(struct tah_regs));
+ return regs + 1;
+}
diff --git a/drivers/net/ibm_emac/ibm_emac_tah.h b/drivers/net/ibm_emac/ibm_emac_tah.h
index ecfc69805521..9299b5dd7eb1 100644
--- a/drivers/net/ibm_emac/ibm_emac_tah.h
+++ b/drivers/net/ibm_emac/ibm_emac_tah.h
@@ -1,9 +1,13 @@
/*
- * Defines for the IBM TAH
+ * drivers/net/ibm_emac/ibm_emac_tah.h
+ *
+ * Driver for PowerPC 4xx on-chip ethernet controller, TAH support.
*
* Copyright 2004 MontaVista Software, Inc.
* Matt Porter <mporter@kernel.crashing.org>
*
+ * Copyright (c) 2005 Eugene Surovegin <ebs@ebshome.net>
+ *
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
@@ -13,36 +17,72 @@
#ifndef _IBM_EMAC_TAH_H
#define _IBM_EMAC_TAH_H
+#include <linux/config.h>
+#include <linux/init.h>
+#include <asm/ocp.h>
+
/* TAH */
-typedef struct tah_regs {
- u32 tah_revid;
+struct tah_regs {
+ u32 revid;
u32 pad[3];
- u32 tah_mr;
- u32 tah_ssr0;
- u32 tah_ssr1;
- u32 tah_ssr2;
- u32 tah_ssr3;
- u32 tah_ssr4;
- u32 tah_ssr5;
- u32 tah_tsr;
-} tah_t;
+ u32 mr;
+ u32 ssr0;
+ u32 ssr1;
+ u32 ssr2;
+ u32 ssr3;
+ u32 ssr4;
+ u32 ssr5;
+ u32 tsr;
+};
/* TAH engine */
-#define TAH_MR_CVR 0x80000000
-#define TAH_MR_SR 0x40000000
-#define TAH_MR_ST_256 0x01000000
-#define TAH_MR_ST_512 0x02000000
-#define TAH_MR_ST_768 0x03000000
-#define TAH_MR_ST_1024 0x04000000
-#define TAH_MR_ST_1280 0x05000000
-#define TAH_MR_ST_1536 0x06000000
-#define TAH_MR_TFS_16KB 0x00000000
-#define TAH_MR_TFS_2KB 0x00200000
-#define TAH_MR_TFS_4KB 0x00400000
-#define TAH_MR_TFS_6KB 0x00600000
-#define TAH_MR_TFS_8KB 0x00800000
-#define TAH_MR_TFS_10KB 0x00a00000
-#define TAH_MR_DTFP 0x00100000
-#define TAH_MR_DIG 0x00080000
+#define TAH_MR_CVR 0x80000000
+#define TAH_MR_SR 0x40000000
+#define TAH_MR_ST_256 0x01000000
+#define TAH_MR_ST_512 0x02000000
+#define TAH_MR_ST_768 0x03000000
+#define TAH_MR_ST_1024 0x04000000
+#define TAH_MR_ST_1280 0x05000000
+#define TAH_MR_ST_1536 0x06000000
+#define TAH_MR_TFS_16KB 0x00000000
+#define TAH_MR_TFS_2KB 0x00200000
+#define TAH_MR_TFS_4KB 0x00400000
+#define TAH_MR_TFS_6KB 0x00600000
+#define TAH_MR_TFS_8KB 0x00800000
+#define TAH_MR_TFS_10KB 0x00a00000
+#define TAH_MR_DTFP 0x00100000
+#define TAH_MR_DIG 0x00080000
+
+#ifdef CONFIG_IBM_EMAC_TAH
+int tah_attach(void *emac) __init;
+
+void __tah_fini(struct ocp_device *ocpdev) __exit;
+static inline void tah_fini(struct ocp_device *ocpdev)
+{
+ if (ocpdev)
+ __tah_fini(ocpdev);
+}
+
+void __tah_reset(struct ocp_device *ocpdev);
+static inline void tah_reset(struct ocp_device *ocpdev)
+{
+ if (ocpdev)
+ __tah_reset(ocpdev);
+}
+
+int __tah_get_regs_len(struct ocp_device *ocpdev);
+static inline int tah_get_regs_len(struct ocp_device *ocpdev)
+{
+ return ocpdev ? __tah_get_regs_len(ocpdev) : 0;
+}
+
+void *tah_dump_regs(struct ocp_device *ocpdev, void *buf);
+#else
+# define tah_attach(x) 0
+# define tah_fini(x) ((void)0)
+# define tah_reset(x) ((void)0)
+# define tah_get_regs_len(x) 0
+# define tah_dump_regs(x,buf) (buf)
+#endif /* !CONFIG_IBM_EMAC_TAH */
#endif /* _IBM_EMAC_TAH_H */
diff --git a/drivers/net/ibm_emac/ibm_emac_zmii.c b/drivers/net/ibm_emac/ibm_emac_zmii.c
new file mode 100644
index 000000000000..35c1185079ed
--- /dev/null
+++ b/drivers/net/ibm_emac/ibm_emac_zmii.c
@@ -0,0 +1,255 @@
+/*
+ * drivers/net/ibm_emac/ibm_emac_zmii.c
+ *
+ * Driver for PowerPC 4xx on-chip ethernet controller, ZMII bridge support.
+ *
+ * Copyright (c) 2004, 2005 Zultys Technologies.
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ *
+ * Based on original work by
+ * Armin Kuster <akuster@mvista.com>
+ * Copyright 2001 MontaVista Softare 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.
+ *
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/ethtool.h>
+#include <asm/io.h>
+
+#include "ibm_emac_core.h"
+#include "ibm_emac_debug.h"
+
+/* ZMIIx_FER */
+#define ZMII_FER_MDI(idx) (0x80000000 >> ((idx) * 4))
+#define ZMII_FER_MDI_ALL (ZMII_FER_MDI(0) | ZMII_FER_MDI(1) | \
+ ZMII_FER_MDI(2) | ZMII_FER_MDI(3))
+
+#define ZMII_FER_SMII(idx) (0x40000000 >> ((idx) * 4))
+#define ZMII_FER_RMII(idx) (0x20000000 >> ((idx) * 4))
+#define ZMII_FER_MII(idx) (0x10000000 >> ((idx) * 4))
+
+/* ZMIIx_SSR */
+#define ZMII_SSR_SCI(idx) (0x40000000 >> ((idx) * 4))
+#define ZMII_SSR_FSS(idx) (0x20000000 >> ((idx) * 4))
+#define ZMII_SSR_SP(idx) (0x10000000 >> ((idx) * 4))
+
+/* ZMII only supports MII, RMII and SMII
+ * we also support autodetection for backward compatibility
+ */
+static inline int zmii_valid_mode(int mode)
+{
+ return mode == PHY_MODE_MII ||
+ mode == PHY_MODE_RMII ||
+ mode == PHY_MODE_SMII ||
+ mode == PHY_MODE_NA;
+}
+
+static inline const char *zmii_mode_name(int mode)
+{
+ switch (mode) {
+ case PHY_MODE_MII:
+ return "MII";
+ case PHY_MODE_RMII:
+ return "RMII";
+ case PHY_MODE_SMII:
+ return "SMII";
+ default:
+ BUG();
+ }
+}
+
+static inline u32 zmii_mode_mask(int mode, int input)
+{
+ switch (mode) {
+ case PHY_MODE_MII:
+ return ZMII_FER_MII(input);
+ case PHY_MODE_RMII:
+ return ZMII_FER_RMII(input);
+ case PHY_MODE_SMII:
+ return ZMII_FER_SMII(input);
+ default:
+ return 0;
+ }
+}
+
+static int __init zmii_init(struct ocp_device *ocpdev, int input, int *mode)
+{
+ struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev);
+ struct zmii_regs *p;
+
+ ZMII_DBG("%d: init(%d, %d)" NL, ocpdev->def->index, input, *mode);
+
+ if (!dev) {
+ dev = kzalloc(sizeof(struct ibm_ocp_zmii), GFP_KERNEL);
+ if (!dev) {
+ printk(KERN_ERR
+ "zmii%d: couldn't allocate device structure!\n",
+ ocpdev->def->index);
+ return -ENOMEM;
+ }
+ dev->mode = PHY_MODE_NA;
+
+ p = (struct zmii_regs *)ioremap(ocpdev->def->paddr,
+ sizeof(struct zmii_regs));
+ if (!p) {
+ printk(KERN_ERR
+ "zmii%d: could not ioremap device registers!\n",
+ ocpdev->def->index);
+ kfree(dev);
+ return -ENOMEM;
+ }
+ dev->base = p;
+ ocp_set_drvdata(ocpdev, dev);
+
+ /* We may need FER value for autodetection later */
+ dev->fer_save = in_be32(&p->fer);
+
+ /* Disable all inputs by default */
+ out_be32(&p->fer, 0);
+ } else
+ p = dev->base;
+
+ if (!zmii_valid_mode(*mode)) {
+ /* Probably an EMAC connected to RGMII,
+ * but it still may need ZMII for MDIO
+ */
+ goto out;
+ }
+
+ /* Autodetect ZMII mode if not specified.
+ * This is only for backward compatibility with the old driver.
+ * Please, always specify PHY mode in your board port to avoid
+ * any surprises.
+ */
+ if (dev->mode == PHY_MODE_NA) {
+ if (*mode == PHY_MODE_NA) {
+ u32 r = dev->fer_save;
+
+ ZMII_DBG("%d: autodetecting mode, FER = 0x%08x" NL,
+ ocpdev->def->index, r);
+
+ if (r & (ZMII_FER_MII(0) | ZMII_FER_MII(1)))
+ dev->mode = PHY_MODE_MII;
+ else if (r & (ZMII_FER_RMII(0) | ZMII_FER_RMII(1)))
+ dev->mode = PHY_MODE_RMII;
+ else
+ dev->mode = PHY_MODE_SMII;
+ } else
+ dev->mode = *mode;
+
+ printk(KERN_NOTICE "zmii%d: bridge in %s mode\n",
+ ocpdev->def->index, zmii_mode_name(dev->mode));
+ } else {
+ /* All inputs must use the same mode */
+ if (*mode != PHY_MODE_NA && *mode != dev->mode) {
+ printk(KERN_ERR
+ "zmii%d: invalid mode %d specified for input %d\n",
+ ocpdev->def->index, *mode, input);
+ return -EINVAL;
+ }
+ }
+
+ /* Report back correct PHY mode,
+ * it may be used during PHY initialization.
+ */
+ *mode = dev->mode;
+
+ /* Enable this input */
+ out_be32(&p->fer, in_be32(&p->fer) | zmii_mode_mask(dev->mode, input));
+ out:
+ ++dev->users;
+ return 0;
+}
+
+int __init zmii_attach(void *emac)
+{
+ struct ocp_enet_private *dev = emac;
+ struct ocp_func_emac_data *emacdata = dev->def->additions;
+
+ if (emacdata->zmii_idx >= 0) {
+ dev->zmii_input = emacdata->zmii_mux;
+ dev->zmii_dev =
+ ocp_find_device(OCP_VENDOR_IBM, OCP_FUNC_ZMII,
+ emacdata->zmii_idx);
+ if (!dev->zmii_dev) {
+ printk(KERN_ERR "emac%d: unknown zmii%d!\n",
+ dev->def->index, emacdata->zmii_idx);
+ return -ENODEV;
+ }
+ if (zmii_init
+ (dev->zmii_dev, dev->zmii_input, &emacdata->phy_mode)) {
+ printk(KERN_ERR
+ "emac%d: zmii%d initialization failed!\n",
+ dev->def->index, emacdata->zmii_idx);
+ return -ENODEV;
+ }
+ }
+ return 0;
+}
+
+void __zmii_enable_mdio(struct ocp_device *ocpdev, int input)
+{
+ struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev);
+ u32 fer = in_be32(&dev->base->fer) & ~ZMII_FER_MDI_ALL;
+
+ ZMII_DBG2("%d: mdio(%d)" NL, ocpdev->def->index, input);
+
+ out_be32(&dev->base->fer, fer | ZMII_FER_MDI(input));
+}
+
+void __zmii_set_speed(struct ocp_device *ocpdev, int input, int speed)
+{
+ struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev);
+ u32 ssr = in_be32(&dev->base->ssr);
+
+ ZMII_DBG("%d: speed(%d, %d)" NL, ocpdev->def->index, input, speed);
+
+ if (speed == SPEED_100)
+ ssr |= ZMII_SSR_SP(input);
+ else
+ ssr &= ~ZMII_SSR_SP(input);
+
+ out_be32(&dev->base->ssr, ssr);
+}
+
+void __exit __zmii_fini(struct ocp_device *ocpdev, int input)
+{
+ struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev);
+ BUG_ON(!dev || dev->users == 0);
+
+ ZMII_DBG("%d: fini(%d)" NL, ocpdev->def->index, input);
+
+ /* Disable this input */
+ out_be32(&dev->base->fer,
+ in_be32(&dev->base->fer) & ~zmii_mode_mask(dev->mode, input));
+
+ if (!--dev->users) {
+ /* Free everything if this is the last user */
+ ocp_set_drvdata(ocpdev, NULL);
+ iounmap((void *)dev->base);
+ kfree(dev);
+ }
+}
+
+int __zmii_get_regs_len(struct ocp_device *ocpdev)
+{
+ return sizeof(struct emac_ethtool_regs_subhdr) +
+ sizeof(struct zmii_regs);
+}
+
+void *zmii_dump_regs(struct ocp_device *ocpdev, void *buf)
+{
+ struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev);
+ struct emac_ethtool_regs_subhdr *hdr = buf;
+ struct zmii_regs *regs = (struct zmii_regs *)(hdr + 1);
+
+ hdr->version = 0;
+ hdr->index = ocpdev->def->index;
+ memcpy_fromio(regs, dev->base, sizeof(struct zmii_regs));
+ return regs + 1;
+}
diff --git a/drivers/net/ibm_emac/ibm_emac_zmii.h b/drivers/net/ibm_emac/ibm_emac_zmii.h
index 6f6cd2a39e38..0bb26062c0ad 100644
--- a/drivers/net/ibm_emac/ibm_emac_zmii.h
+++ b/drivers/net/ibm_emac/ibm_emac_zmii.h
@@ -1,23 +1,27 @@
/*
- * ocp_zmii.h
+ * drivers/net/ibm_emac/ibm_emac_zmii.h
*
- * Defines for the IBM ZMII bridge
+ * Driver for PowerPC 4xx on-chip ethernet controller, ZMII bridge support.
*
- * Armin Kuster akuster@mvista.com
- * Dec, 2001
+ * Copyright (c) 2004, 2005 Zultys Technologies.
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
*
- * Copyright 2001 MontaVista Softare Inc.
+ * Based on original work by
+ * Armin Kuster <akuster@mvista.com>
+ * Copyright 2001 MontaVista Softare 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.
+ *
*/
-
#ifndef _IBM_EMAC_ZMII_H_
#define _IBM_EMAC_ZMII_H_
#include <linux/config.h>
+#include <linux/init.h>
+#include <asm/ocp.h>
/* ZMII bridge registers */
struct zmii_regs {
@@ -26,68 +30,54 @@ struct zmii_regs {
u32 smiirs; /* SMII status reg */
};
-#define ZMII_INPUTS 4
-
/* ZMII device */
struct ibm_ocp_zmii {
struct zmii_regs *base;
- int mode[ZMII_INPUTS];
+ int mode; /* subset of PHY_MODE_XXXX */
int users; /* number of EMACs using this ZMII bridge */
+ u32 fer_save; /* FER value left by firmware */
};
-/* Fuctional Enable Reg */
-
-#define ZMII_FER_MASK(x) (0xf0000000 >> (4*x))
-
-#define ZMII_MDI0 0x80000000
-#define ZMII_SMII0 0x40000000
-#define ZMII_RMII0 0x20000000
-#define ZMII_MII0 0x10000000
-#define ZMII_MDI1 0x08000000
-#define ZMII_SMII1 0x04000000
-#define ZMII_RMII1 0x02000000
-#define ZMII_MII1 0x01000000
-#define ZMII_MDI2 0x00800000
-#define ZMII_SMII2 0x00400000
-#define ZMII_RMII2 0x00200000
-#define ZMII_MII2 0x00100000
-#define ZMII_MDI3 0x00080000
-#define ZMII_SMII3 0x00040000
-#define ZMII_RMII3 0x00020000
-#define ZMII_MII3 0x00010000
+#ifdef CONFIG_IBM_EMAC_ZMII
+int zmii_attach(void *emac) __init;
-/* Speed Selection reg */
+void __zmii_fini(struct ocp_device *ocpdev, int input) __exit;
+static inline void zmii_fini(struct ocp_device *ocpdev, int input)
+{
+ if (ocpdev)
+ __zmii_fini(ocpdev, input);
+}
-#define ZMII_SCI0 0x40000000
-#define ZMII_FSS0 0x20000000
-#define ZMII_SP0 0x10000000
-#define ZMII_SCI1 0x04000000
-#define ZMII_FSS1 0x02000000
-#define ZMII_SP1 0x01000000
-#define ZMII_SCI2 0x00400000
-#define ZMII_FSS2 0x00200000
-#define ZMII_SP2 0x00100000
-#define ZMII_SCI3 0x00040000
-#define ZMII_FSS3 0x00020000
-#define ZMII_SP3 0x00010000
+void __zmii_enable_mdio(struct ocp_device *ocpdev, int input);
+static inline void zmii_enable_mdio(struct ocp_device *ocpdev, int input)
+{
+ if (ocpdev)
+ __zmii_enable_mdio(ocpdev, input);
+}
-#define ZMII_MII0_100MB ZMII_SP0
-#define ZMII_MII0_10MB ~ZMII_SP0
-#define ZMII_MII1_100MB ZMII_SP1
-#define ZMII_MII1_10MB ~ZMII_SP1
-#define ZMII_MII2_100MB ZMII_SP2
-#define ZMII_MII2_10MB ~ZMII_SP2
-#define ZMII_MII3_100MB ZMII_SP3
-#define ZMII_MII3_10MB ~ZMII_SP3
+void __zmii_set_speed(struct ocp_device *ocpdev, int input, int speed);
+static inline void zmii_set_speed(struct ocp_device *ocpdev, int input,
+ int speed)
+{
+ if (ocpdev)
+ __zmii_set_speed(ocpdev, input, speed);
+}
-/* SMII Status reg */
+int __zmii_get_regs_len(struct ocp_device *ocpdev);
+static inline int zmii_get_regs_len(struct ocp_device *ocpdev)
+{
+ return ocpdev ? __zmii_get_regs_len(ocpdev) : 0;
+}
-#define ZMII_STS0 0xFF000000 /* EMAC0 smii status mask */
-#define ZMII_STS1 0x00FF0000 /* EMAC1 smii status mask */
+void *zmii_dump_regs(struct ocp_device *ocpdev, void *buf);
-#define SMII 0
-#define RMII 1
-#define MII 2
-#define MDI 3
+#else
+# define zmii_attach(x) 0
+# define zmii_fini(x,y) ((void)0)
+# define zmii_enable_mdio(x,y) ((void)0)
+# define zmii_set_speed(x,y,z) ((void)0)
+# define zmii_get_regs_len(x) 0
+# define zmii_dump_regs(x,buf) (buf)
+#endif /* !CONFIG_IBM_EMAC_ZMII */
#endif /* _IBM_EMAC_ZMII_H_ */
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index a2c4dd4fb221..e5246f227c98 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -96,7 +96,7 @@ static void ibmveth_proc_unregister_driver(void);
static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter);
static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter);
static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
-static inline void ibmveth_schedule_replenishing(struct ibmveth_adapter*);
+static inline void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter);
#ifdef CONFIG_PROC_FS
#define IBMVETH_PROC_DIR "net/ibmveth"
@@ -181,6 +181,7 @@ static int ibmveth_alloc_buffer_pool(struct ibmveth_buff_pool *pool)
atomic_set(&pool->available, 0);
pool->producer_index = 0;
pool->consumer_index = 0;
+ pool->active = 0;
return 0;
}
@@ -236,7 +237,7 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc
lpar_rc = h_add_logical_lan_buffer(adapter->vdev->unit_address, desc.desc);
if(lpar_rc != H_Success) {
- pool->free_map[free_index] = IBM_VETH_INVALID_MAP;
+ pool->free_map[free_index] = index;
pool->skbuff[index] = NULL;
pool->consumer_index--;
dma_unmap_single(&adapter->vdev->dev,
@@ -255,37 +256,19 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc
atomic_add(buffers_added, &(pool->available));
}
-/* check if replenishing is needed. */
-static inline int ibmveth_is_replenishing_needed(struct ibmveth_adapter *adapter)
-{
- return ((atomic_read(&adapter->rx_buff_pool[0].available) < adapter->rx_buff_pool[0].threshold) ||
- (atomic_read(&adapter->rx_buff_pool[1].available) < adapter->rx_buff_pool[1].threshold) ||
- (atomic_read(&adapter->rx_buff_pool[2].available) < adapter->rx_buff_pool[2].threshold));
-}
-
-/* kick the replenish tasklet if we need replenishing and it isn't already running */
-static inline void ibmveth_schedule_replenishing(struct ibmveth_adapter *adapter)
-{
- if(ibmveth_is_replenishing_needed(adapter) &&
- (atomic_dec_if_positive(&adapter->not_replenishing) == 0)) {
- schedule_work(&adapter->replenish_task);
- }
-}
-
-/* replenish tasklet routine */
+/* replenish routine */
static void ibmveth_replenish_task(struct ibmveth_adapter *adapter)
{
+ int i;
+
adapter->replenish_task_cycles++;
- ibmveth_replenish_buffer_pool(adapter, &adapter->rx_buff_pool[0]);
- ibmveth_replenish_buffer_pool(adapter, &adapter->rx_buff_pool[1]);
- ibmveth_replenish_buffer_pool(adapter, &adapter->rx_buff_pool[2]);
+ for(i = 0; i < IbmVethNumBufferPools; i++)
+ if(adapter->rx_buff_pool[i].active)
+ ibmveth_replenish_buffer_pool(adapter,
+ &adapter->rx_buff_pool[i]);
adapter->rx_no_buffer = *(u64*)(((char*)adapter->buffer_list_addr) + 4096 - 8);
-
- atomic_inc(&adapter->not_replenishing);
-
- ibmveth_schedule_replenishing(adapter);
}
/* empty and free ana buffer pool - also used to do cleanup in error paths */
@@ -293,10 +276,8 @@ static void ibmveth_free_buffer_pool(struct ibmveth_adapter *adapter, struct ibm
{
int i;
- if(pool->free_map) {
- kfree(pool->free_map);
- pool->free_map = NULL;
- }
+ kfree(pool->free_map);
+ pool->free_map = NULL;
if(pool->skbuff && pool->dma_addr) {
for(i = 0; i < pool->size; ++i) {
@@ -321,6 +302,7 @@ static void ibmveth_free_buffer_pool(struct ibmveth_adapter *adapter, struct ibm
kfree(pool->skbuff);
pool->skbuff = NULL;
}
+ pool->active = 0;
}
/* remove a buffer from a pool */
@@ -379,6 +361,12 @@ static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter)
ibmveth_assert(pool < IbmVethNumBufferPools);
ibmveth_assert(index < adapter->rx_buff_pool[pool].size);
+ if(!adapter->rx_buff_pool[pool].active) {
+ ibmveth_rxq_harvest_buffer(adapter);
+ ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[pool]);
+ return;
+ }
+
desc.desc = 0;
desc.fields.valid = 1;
desc.fields.length = adapter->rx_buff_pool[pool].buff_size;
@@ -409,6 +397,8 @@ static inline void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter)
static void ibmveth_cleanup(struct ibmveth_adapter *adapter)
{
+ int i;
+
if(adapter->buffer_list_addr != NULL) {
if(!dma_mapping_error(adapter->buffer_list_dma)) {
dma_unmap_single(&adapter->vdev->dev,
@@ -443,26 +433,24 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter)
adapter->rx_queue.queue_addr = NULL;
}
- ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[0]);
- ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[1]);
- ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[2]);
+ for(i = 0; i<IbmVethNumBufferPools; i++)
+ ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[i]);
}
static int ibmveth_open(struct net_device *netdev)
{
struct ibmveth_adapter *adapter = netdev->priv;
u64 mac_address = 0;
- int rxq_entries;
+ int rxq_entries = 1;
unsigned long lpar_rc;
int rc;
union ibmveth_buf_desc rxq_desc;
+ int i;
ibmveth_debug_printk("open starting\n");
- rxq_entries =
- adapter->rx_buff_pool[0].size +
- adapter->rx_buff_pool[1].size +
- adapter->rx_buff_pool[2].size + 1;
+ for(i = 0; i<IbmVethNumBufferPools; i++)
+ rxq_entries += adapter->rx_buff_pool[i].size;
adapter->buffer_list_addr = (void*) get_zeroed_page(GFP_KERNEL);
adapter->filter_list_addr = (void*) get_zeroed_page(GFP_KERNEL);
@@ -502,14 +490,8 @@ static int ibmveth_open(struct net_device *netdev)
adapter->rx_queue.num_slots = rxq_entries;
adapter->rx_queue.toggle = 1;
- if(ibmveth_alloc_buffer_pool(&adapter->rx_buff_pool[0]) ||
- ibmveth_alloc_buffer_pool(&adapter->rx_buff_pool[1]) ||
- ibmveth_alloc_buffer_pool(&adapter->rx_buff_pool[2]))
- {
- ibmveth_error_printk("unable to allocate buffer pools\n");
- ibmveth_cleanup(adapter);
- return -ENOMEM;
- }
+ /* call change_mtu to init the buffer pools based in initial mtu */
+ ibmveth_change_mtu(netdev, netdev->mtu);
memcpy(&mac_address, netdev->dev_addr, netdev->addr_len);
mac_address = mac_address >> 16;
@@ -532,7 +514,7 @@ static int ibmveth_open(struct net_device *netdev)
if(lpar_rc != H_Success) {
ibmveth_error_printk("h_register_logical_lan failed with %ld\n", lpar_rc);
- ibmveth_error_printk("buffer TCE:0x%x filter TCE:0x%x rxq desc:0x%lx MAC:0x%lx\n",
+ ibmveth_error_printk("buffer TCE:0x%lx filter TCE:0x%lx rxq desc:0x%lx MAC:0x%lx\n",
adapter->buffer_list_dma,
adapter->filter_list_dma,
rxq_desc.desc,
@@ -552,10 +534,10 @@ static int ibmveth_open(struct net_device *netdev)
return rc;
}
- netif_start_queue(netdev);
+ ibmveth_debug_printk("initial replenish cycle\n");
+ ibmveth_replenish_task(adapter);
- ibmveth_debug_printk("scheduling initial replenish cycle\n");
- ibmveth_schedule_replenishing(adapter);
+ netif_start_queue(netdev);
ibmveth_debug_printk("open complete\n");
@@ -573,9 +555,6 @@ static int ibmveth_close(struct net_device *netdev)
free_irq(netdev->irq, netdev);
- cancel_delayed_work(&adapter->replenish_task);
- flush_scheduled_work();
-
do {
lpar_rc = h_free_logical_lan(adapter->vdev->unit_address);
} while (H_isLongBusy(lpar_rc) || (lpar_rc == H_Busy));
@@ -640,12 +619,18 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
unsigned long lpar_rc;
int nfrags = 0, curfrag;
unsigned long correlator;
+ unsigned long flags;
unsigned int retry_count;
+ unsigned int tx_dropped = 0;
+ unsigned int tx_bytes = 0;
+ unsigned int tx_packets = 0;
+ unsigned int tx_send_failed = 0;
+ unsigned int tx_map_failed = 0;
+
if ((skb_shinfo(skb)->nr_frags + 1) > IbmVethMaxSendFrags) {
- adapter->stats.tx_dropped++;
- dev_kfree_skb(skb);
- return 0;
+ tx_dropped++;
+ goto out;
}
memset(&desc, 0, sizeof(desc));
@@ -664,10 +649,9 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
if(dma_mapping_error(desc[0].fields.address)) {
ibmveth_error_printk("tx: unable to map initial fragment\n");
- adapter->tx_map_failed++;
- adapter->stats.tx_dropped++;
- dev_kfree_skb(skb);
- return 0;
+ tx_map_failed++;
+ tx_dropped++;
+ goto out;
}
curfrag = nfrags;
@@ -684,8 +668,8 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
if(dma_mapping_error(desc[curfrag+1].fields.address)) {
ibmveth_error_printk("tx: unable to map fragment %d\n", curfrag);
- adapter->tx_map_failed++;
- adapter->stats.tx_dropped++;
+ tx_map_failed++;
+ tx_dropped++;
/* Free all the mappings we just created */
while(curfrag < nfrags) {
dma_unmap_single(&adapter->vdev->dev,
@@ -694,8 +678,7 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
DMA_TO_DEVICE);
curfrag++;
}
- dev_kfree_skb(skb);
- return 0;
+ goto out;
}
}
@@ -720,11 +703,12 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
ibmveth_error_printk("tx: desc[%i] valid=%d, len=%d, address=0x%d\n", i,
desc[i].fields.valid, desc[i].fields.length, desc[i].fields.address);
}
- adapter->tx_send_failed++;
- adapter->stats.tx_dropped++;
+ tx_send_failed++;
+ tx_dropped++;
} else {
- adapter->stats.tx_packets++;
- adapter->stats.tx_bytes += skb->len;
+ tx_packets++;
+ tx_bytes += skb->len;
+ netdev->trans_start = jiffies;
}
do {
@@ -733,6 +717,14 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
desc[nfrags].fields.length, DMA_TO_DEVICE);
} while(--nfrags >= 0);
+out: spin_lock_irqsave(&adapter->stats_lock, flags);
+ adapter->stats.tx_dropped += tx_dropped;
+ adapter->stats.tx_bytes += tx_bytes;
+ adapter->stats.tx_packets += tx_packets;
+ adapter->tx_send_failed += tx_send_failed;
+ adapter->tx_map_failed += tx_map_failed;
+ spin_unlock_irqrestore(&adapter->stats_lock, flags);
+
dev_kfree_skb(skb);
return 0;
}
@@ -776,13 +768,14 @@ static int ibmveth_poll(struct net_device *netdev, int *budget)
adapter->stats.rx_packets++;
adapter->stats.rx_bytes += length;
frames_processed++;
+ netdev->last_rx = jiffies;
}
} else {
more_work = 0;
}
} while(more_work && (frames_processed < max_frames_to_process));
- ibmveth_schedule_replenishing(adapter);
+ ibmveth_replenish_task(adapter);
if(more_work) {
/* more work to do - return that we are not done yet */
@@ -883,17 +876,54 @@ static void ibmveth_set_multicast_list(struct net_device *netdev)
static int ibmveth_change_mtu(struct net_device *dev, int new_mtu)
{
- if ((new_mtu < 68) || (new_mtu > (1<<20)))
+ struct ibmveth_adapter *adapter = dev->priv;
+ int i;
+ int prev_smaller = 1;
+
+ if ((new_mtu < 68) ||
+ (new_mtu > (pool_size[IbmVethNumBufferPools-1]) - IBMVETH_BUFF_OH))
return -EINVAL;
+
+ for(i = 0; i<IbmVethNumBufferPools; i++) {
+ int activate = 0;
+ if (new_mtu > (pool_size[i] - IBMVETH_BUFF_OH)) {
+ activate = 1;
+ prev_smaller= 1;
+ } else {
+ if (prev_smaller)
+ activate = 1;
+ prev_smaller= 0;
+ }
+
+ if (activate && !adapter->rx_buff_pool[i].active) {
+ struct ibmveth_buff_pool *pool =
+ &adapter->rx_buff_pool[i];
+ if(ibmveth_alloc_buffer_pool(pool)) {
+ ibmveth_error_printk("unable to alloc pool\n");
+ return -ENOMEM;
+ }
+ adapter->rx_buff_pool[i].active = 1;
+ } else if (!activate && adapter->rx_buff_pool[i].active) {
+ adapter->rx_buff_pool[i].active = 0;
+ h_free_logical_lan_buffer(adapter->vdev->unit_address,
+ (u64)pool_size[i]);
+ }
+
+ }
+
+ /* kick the interrupt handler so that the new buffer pools get
+ replenished or deallocated */
+ ibmveth_interrupt(dev->irq, dev, NULL);
+
dev->mtu = new_mtu;
return 0;
}
static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
{
- int rc;
+ int rc, i;
struct net_device *netdev;
- struct ibmveth_adapter *adapter;
+ struct ibmveth_adapter *adapter = NULL;
unsigned char *mac_addr_p;
unsigned int *mcastFilterSize_p;
@@ -960,23 +990,21 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
netdev->ethtool_ops = &netdev_ethtool_ops;
netdev->change_mtu = ibmveth_change_mtu;
SET_NETDEV_DEV(netdev, &dev->dev);
+ netdev->features |= NETIF_F_LLTX;
+ spin_lock_init(&adapter->stats_lock);
memcpy(&netdev->dev_addr, &adapter->mac_addr, netdev->addr_len);
- ibmveth_init_buffer_pool(&adapter->rx_buff_pool[0], 0, IbmVethPool0DftCnt, IbmVethPool0DftSize);
- ibmveth_init_buffer_pool(&adapter->rx_buff_pool[1], 1, IbmVethPool1DftCnt, IbmVethPool1DftSize);
- ibmveth_init_buffer_pool(&adapter->rx_buff_pool[2], 2, IbmVethPool2DftCnt, IbmVethPool2DftSize);
+ for(i = 0; i<IbmVethNumBufferPools; i++)
+ ibmveth_init_buffer_pool(&adapter->rx_buff_pool[i], i,
+ pool_count[i], pool_size[i]);
ibmveth_debug_printk("adapter @ 0x%p\n", adapter);
- INIT_WORK(&adapter->replenish_task, (void*)ibmveth_replenish_task, (void*)adapter);
-
adapter->buffer_list_dma = DMA_ERROR_CODE;
adapter->filter_list_dma = DMA_ERROR_CODE;
adapter->rx_queue.queue_dma = DMA_ERROR_CODE;
- atomic_set(&adapter->not_replenishing, 1);
-
ibmveth_debug_printk("registering netdev...\n");
rc = register_netdev(netdev);
@@ -1146,14 +1174,16 @@ static struct vio_device_id ibmveth_device_table[] __devinitdata= {
{ "network", "IBM,l-lan"},
{ "", "" }
};
-
MODULE_DEVICE_TABLE(vio, ibmveth_device_table);
static struct vio_driver ibmveth_driver = {
- .name = (char *)ibmveth_driver_name,
- .id_table = ibmveth_device_table,
- .probe = ibmveth_probe,
- .remove = ibmveth_remove
+ .id_table = ibmveth_device_table,
+ .probe = ibmveth_probe,
+ .remove = ibmveth_remove,
+ .driver = {
+ .name = ibmveth_driver_name,
+ .owner = THIS_MODULE,
+ }
};
static int __init ibmveth_module_init(void)
diff --git a/drivers/net/ibmveth.h b/drivers/net/ibmveth.h
index 51a470da9686..46919a814fca 100644
--- a/drivers/net/ibmveth.h
+++ b/drivers/net/ibmveth.h
@@ -49,6 +49,7 @@
#define H_SEND_LOGICAL_LAN 0x120
#define H_MULTICAST_CTRL 0x130
#define H_CHANGE_LOGICAL_LAN_MAC 0x14C
+#define H_FREE_LOGICAL_LAN_BUFFER 0x1D4
/* hcall macros */
#define h_register_logical_lan(ua, buflst, rxq, fltlst, mac) \
@@ -69,13 +70,15 @@
#define h_change_logical_lan_mac(ua, mac) \
plpar_hcall_norets(H_CHANGE_LOGICAL_LAN_MAC, ua, mac)
-#define IbmVethNumBufferPools 3
-#define IbmVethPool0DftSize (1024 * 2)
-#define IbmVethPool1DftSize (1024 * 4)
-#define IbmVethPool2DftSize (1024 * 10)
-#define IbmVethPool0DftCnt 256
-#define IbmVethPool1DftCnt 256
-#define IbmVethPool2DftCnt 256
+#define h_free_logical_lan_buffer(ua, bufsize) \
+ plpar_hcall_norets(H_FREE_LOGICAL_LAN_BUFFER, ua, bufsize)
+
+#define IbmVethNumBufferPools 5
+#define IBMVETH_BUFF_OH 22 /* Overhead: 14 ethernet header + 8 opaque handle */
+
+/* pool_size should be sorted */
+static int pool_size[] = { 512, 1024 * 2, 1024 * 16, 1024 * 32, 1024 * 64 };
+static int pool_count[] = { 256, 768, 256, 256, 256 };
#define IBM_VETH_INVALID_MAP ((u16)0xffff)
@@ -90,6 +93,7 @@ struct ibmveth_buff_pool {
u16 *free_map;
dma_addr_t *dma_addr;
struct sk_buff **skbuff;
+ int active;
};
struct ibmveth_rx_q {
@@ -114,10 +118,6 @@ struct ibmveth_adapter {
dma_addr_t filter_list_dma;
struct ibmveth_buff_pool rx_buff_pool[IbmVethNumBufferPools];
struct ibmveth_rx_q rx_queue;
- atomic_t not_replenishing;
-
- /* helper tasks */
- struct work_struct replenish_task;
/* adapter specific stats */
u64 replenish_task_cycles;
@@ -131,6 +131,7 @@ struct ibmveth_adapter {
u64 tx_linearize_failed;
u64 tx_map_failed;
u64 tx_send_failed;
+ spinlock_t stats_lock;
};
struct ibmveth_buf_desc_fields {
diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c
index 0a08c539c051..0282771b1cbb 100644
--- a/drivers/net/irda/donauboe.c
+++ b/drivers/net/irda/donauboe.c
@@ -1695,11 +1695,9 @@ toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid)
freebufs:
for (i = 0; i < TX_SLOTS; ++i)
- if (self->tx_bufs[i])
- kfree (self->tx_bufs[i]);
+ kfree (self->tx_bufs[i]);
for (i = 0; i < RX_SLOTS; ++i)
- if (self->rx_bufs[i])
- kfree (self->rx_bufs[i]);
+ kfree (self->rx_bufs[i]);
kfree(self->ringbuf);
freeregion:
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
index 6c766fdc51a6..c22c0517883c 100644
--- a/drivers/net/irda/irda-usb.c
+++ b/drivers/net/irda/irda-usb.c
@@ -1168,10 +1168,8 @@ static inline void irda_usb_close(struct irda_usb_cb *self)
unregister_netdev(self->netdev);
/* Remove the speed buffer */
- if (self->speed_buff != NULL) {
- kfree(self->speed_buff);
- self->speed_buff = NULL;
- }
+ kfree(self->speed_buff);
+ self->speed_buff = NULL;
}
/********************** USB CONFIG SUBROUTINES **********************/
diff --git a/drivers/net/irda/irport.c b/drivers/net/irda/irport.c
index 5971315f3fa0..3d016a498e1d 100644
--- a/drivers/net/irda/irport.c
+++ b/drivers/net/irda/irport.c
@@ -235,8 +235,7 @@ static int irport_close(struct irport_cb *self)
__FUNCTION__, self->io.sir_base);
release_region(self->io.sir_base, self->io.sir_ext);
- if (self->tx_buff.head)
- kfree(self->tx_buff.head);
+ kfree(self->tx_buff.head);
if (self->rx_buff.skb)
kfree_skb(self->rx_buff.skb);
diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
index 9571145c2090..e1aa9910503b 100644
--- a/drivers/net/irda/pxaficp_ir.c
+++ b/drivers/net/irda/pxaficp_ir.c
@@ -705,15 +705,12 @@ static int pxa_irda_stop(struct net_device *dev)
return 0;
}
-static int pxa_irda_suspend(struct device *_dev, pm_message_t state, u32 level)
+static int pxa_irda_suspend(struct device *_dev, pm_message_t state)
{
struct net_device *dev = dev_get_drvdata(_dev);
struct pxa_irda *si;
- if (!dev || level != SUSPEND_DISABLE)
- return 0;
-
- if (netif_running(dev)) {
+ if (dev && netif_running(dev)) {
si = netdev_priv(dev);
netif_device_detach(dev);
pxa_irda_shutdown(si);
@@ -722,15 +719,12 @@ static int pxa_irda_suspend(struct device *_dev, pm_message_t state, u32 level)
return 0;
}
-static int pxa_irda_resume(struct device *_dev, u32 level)
+static int pxa_irda_resume(struct device *_dev)
{
struct net_device *dev = dev_get_drvdata(_dev);
struct pxa_irda *si;
- if (!dev || level != RESUME_ENABLE)
- return 0;
-
- if (netif_running(dev)) {
+ if (dev && netif_running(dev)) {
si = netdev_priv(dev);
pxa_irda_startup(si);
netif_device_attach(dev);
diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c
index efc5a8870565..df22b8b532e7 100644
--- a/drivers/net/irda/sir_dev.c
+++ b/drivers/net/irda/sir_dev.c
@@ -490,8 +490,7 @@ static void sirdev_free_buffers(struct sir_dev *dev)
{
if (dev->rx_buff.skb)
kfree_skb(dev->rx_buff.skb);
- if (dev->tx_buff.head)
- kfree(dev->tx_buff.head);
+ kfree(dev->tx_buff.head);
dev->rx_buff.head = dev->tx_buff.head = NULL;
dev->rx_buff.skb = NULL;
}
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c
index 424515d35932..a1d207f2fa68 100644
--- a/drivers/net/irda/smsc-ircc2.c
+++ b/drivers/net/irda/smsc-ircc2.c
@@ -639,21 +639,14 @@ static void smsc_ircc_setup_qos(struct smsc_ircc_cb *self)
*/
static void smsc_ircc_init_chip(struct smsc_ircc_cb *self)
{
- int iobase, ir_mode, ctrl, fast;
-
- IRDA_ASSERT(self != NULL, return;);
-
- iobase = self->io.fir_base;
- ir_mode = IRCC_CFGA_IRDA_SIR_A;
- ctrl = 0;
- fast = 0;
+ int iobase = self->io.fir_base;
register_bank(iobase, 0);
outb(IRCC_MASTER_RESET, iobase + IRCC_MASTER);
outb(0x00, iobase + IRCC_MASTER);
register_bank(iobase, 1);
- outb(((inb(iobase + IRCC_SCE_CFGA) & 0x87) | ir_mode),
+ outb(((inb(iobase + IRCC_SCE_CFGA) & 0x87) | IRCC_CFGA_IRDA_SIR_A),
iobase + IRCC_SCE_CFGA);
#ifdef smsc_669 /* Uses pin 88/89 for Rx/Tx */
@@ -667,10 +660,10 @@ static void smsc_ircc_init_chip(struct smsc_ircc_cb *self)
outb(SMSC_IRCC2_FIFO_THRESHOLD, iobase + IRCC_FIFO_THRESHOLD);
register_bank(iobase, 4);
- outb((inb(iobase + IRCC_CONTROL) & 0x30) | ctrl, iobase + IRCC_CONTROL);
+ outb((inb(iobase + IRCC_CONTROL) & 0x30), iobase + IRCC_CONTROL);
register_bank(iobase, 0);
- outb(fast, iobase + IRCC_LCR_A);
+ outb(0, iobase + IRCC_LCR_A);
smsc_ircc_set_sir_speed(self, SMSC_IRCC2_C_IRDA_FALLBACK_SPEED);
@@ -1557,6 +1550,46 @@ static int ircc_is_receiving(struct smsc_ircc_cb *self)
}
#endif /* unused */
+static int smsc_ircc_request_irq(struct smsc_ircc_cb *self)
+{
+ int error;
+
+ error = request_irq(self->io.irq, smsc_ircc_interrupt, 0,
+ self->netdev->name, self->netdev);
+ if (error)
+ IRDA_DEBUG(0, "%s(), unable to allocate irq=%d, err=%d\n",
+ __FUNCTION__, self->io.irq, error);
+
+ return error;
+}
+
+static void smsc_ircc_start_interrupts(struct smsc_ircc_cb *self)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&self->lock, flags);
+
+ self->io.speed = 0;
+ smsc_ircc_change_speed(self, SMSC_IRCC2_C_IRDA_FALLBACK_SPEED);
+
+ spin_unlock_irqrestore(&self->lock, flags);
+}
+
+static void smsc_ircc_stop_interrupts(struct smsc_ircc_cb *self)
+{
+ int iobase = self->io.fir_base;
+ unsigned long flags;
+
+ spin_lock_irqsave(&self->lock, flags);
+
+ register_bank(iobase, 0);
+ outb(0, iobase + IRCC_IER);
+ outb(IRCC_MASTER_RESET, iobase + IRCC_MASTER);
+ outb(0x00, iobase + IRCC_MASTER);
+
+ spin_unlock_irqrestore(&self->lock, flags);
+}
+
/*
* Function smsc_ircc_net_open (dev)
@@ -1568,7 +1601,6 @@ static int smsc_ircc_net_open(struct net_device *dev)
{
struct smsc_ircc_cb *self;
char hwname[16];
- unsigned long flags;
IRDA_DEBUG(1, "%s\n", __FUNCTION__);
@@ -1576,6 +1608,11 @@ static int smsc_ircc_net_open(struct net_device *dev)
self = netdev_priv(dev);
IRDA_ASSERT(self != NULL, return 0;);
+ if (self->io.suspended) {
+ IRDA_DEBUG(0, "%s(), device is suspended\n", __FUNCTION__);
+ return -EAGAIN;
+ }
+
if (request_irq(self->io.irq, smsc_ircc_interrupt, 0, dev->name,
(void *) dev)) {
IRDA_DEBUG(0, "%s(), unable to allocate irq=%d\n",
@@ -1583,11 +1620,7 @@ static int smsc_ircc_net_open(struct net_device *dev)
return -EAGAIN;
}
- spin_lock_irqsave(&self->lock, flags);
- /*smsc_ircc_sir_start(self);*/
- self->io.speed = 0;
- smsc_ircc_change_speed(self, SMSC_IRCC2_C_IRDA_FALLBACK_SPEED);
- spin_unlock_irqrestore(&self->lock, flags);
+ smsc_ircc_start_interrupts(self);
/* Give self a hardware name */
/* It would be cool to offer the chip revision here - Jean II */
@@ -1640,7 +1673,12 @@ static int smsc_ircc_net_close(struct net_device *dev)
irlap_close(self->irlap);
self->irlap = NULL;
- free_irq(self->io.irq, dev);
+ smsc_ircc_stop_interrupts(self);
+
+ /* if we are called from smsc_ircc_resume we don't have IRQ reserved */
+ if (!self->io.suspended)
+ free_irq(self->io.irq, dev);
+
disable_dma(self->io.dma);
free_dma(self->io.dma);
@@ -1651,11 +1689,18 @@ static int smsc_ircc_suspend(struct device *dev, pm_message_t state)
{
struct smsc_ircc_cb *self = dev_get_drvdata(dev);
- IRDA_MESSAGE("%s, Suspending\n", driver_name);
-
if (!self->io.suspended) {
- smsc_ircc_net_close(self->netdev);
+ IRDA_DEBUG(1, "%s, Suspending\n", driver_name);
+
+ rtnl_lock();
+ if (netif_running(self->netdev)) {
+ netif_device_detach(self->netdev);
+ smsc_ircc_stop_interrupts(self);
+ free_irq(self->io.irq, self->netdev);
+ disable_dma(self->io.dma);
+ }
self->io.suspended = 1;
+ rtnl_unlock();
}
return 0;
@@ -1666,11 +1711,25 @@ static int smsc_ircc_resume(struct device *dev)
struct smsc_ircc_cb *self = dev_get_drvdata(dev);
if (self->io.suspended) {
-
- smsc_ircc_net_open(self->netdev);
+ IRDA_DEBUG(1, "%s, Waking up\n", driver_name);
+
+ rtnl_lock();
+ smsc_ircc_init_chip(self);
+ if (netif_running(self->netdev)) {
+ if (smsc_ircc_request_irq(self)) {
+ /*
+ * Don't fail resume process, just kill this
+ * network interface
+ */
+ unregister_netdevice(self->netdev);
+ } else {
+ enable_dma(self->io.dma);
+ smsc_ircc_start_interrupts(self);
+ netif_device_attach(self->netdev);
+ }
+ }
self->io.suspended = 0;
-
- IRDA_MESSAGE("%s, Waking up\n", driver_name);
+ rtnl_unlock();
}
return 0;
}
@@ -1683,9 +1742,6 @@ static int smsc_ircc_resume(struct device *dev)
*/
static int __exit smsc_ircc_close(struct smsc_ircc_cb *self)
{
- int iobase;
- unsigned long flags;
-
IRDA_DEBUG(1, "%s\n", __FUNCTION__);
IRDA_ASSERT(self != NULL, return -1;);
@@ -1695,22 +1751,7 @@ static int __exit smsc_ircc_close(struct smsc_ircc_cb *self)
/* Remove netdevice */
unregister_netdev(self->netdev);
- /* Make sure the irq handler is not exectuting */
- spin_lock_irqsave(&self->lock, flags);
-
- /* Stop interrupts */
- iobase = self->io.fir_base;
- register_bank(iobase, 0);
- outb(0, iobase + IRCC_IER);
- outb(IRCC_MASTER_RESET, iobase + IRCC_MASTER);
- outb(0x00, iobase + IRCC_MASTER);
-#if 0
- /* Reset to SIR mode */
- register_bank(iobase, 1);
- outb(IRCC_CFGA_IRDA_SIR_A|IRCC_CFGA_TX_POLARITY, iobase + IRCC_SCE_CFGA);
- outb(IRCC_CFGB_IR, iobase + IRCC_SCE_CFGB);
-#endif
- spin_unlock_irqrestore(&self->lock, flags);
+ smsc_ircc_stop_interrupts(self);
/* Release the PORTS that this driver is using */
IRDA_DEBUG(0, "%s(), releasing 0x%03x\n", __FUNCTION__,
diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c
index 651c5a6578fd..a9f49f058cfb 100644
--- a/drivers/net/irda/vlsi_ir.c
+++ b/drivers/net/irda/vlsi_ir.c
@@ -473,8 +473,7 @@ static int vlsi_free_ring(struct vlsi_ring *r)
rd_set_addr_status(rd, 0, 0);
if (busaddr)
pci_unmap_single(r->pdev, busaddr, r->len, r->dir);
- if (rd->buf)
- kfree(rd->buf);
+ kfree(rd->buf);
}
kfree(r);
return 0;
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index 3d56cf5a4e23..f5ea39ff1017 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -70,8 +70,9 @@
#include <linux/delay.h>
#include <linux/mm.h>
#include <linux/ethtool.h>
+
+#include <asm/abs_addr.h>
#include <asm/iSeries/mf.h>
-#include <asm/iSeries/iSeries_pci.h>
#include <asm/uaccess.h>
#include <asm/iSeries/HvLpConfig.h>
@@ -1397,13 +1398,13 @@ static inline void veth_build_dma_list(struct dma_chunk *list,
* it just at the granularity of iSeries real->absolute
* mapping? Indeed, given the way the allocator works, can we
* count on them being absolutely contiguous? */
- list[0].addr = ISERIES_HV_ADDR(p);
+ list[0].addr = iseries_hv_addr(p);
list[0].size = min(length,
PAGE_SIZE - ((unsigned long)p & ~PAGE_MASK));
done = list[0].size;
while (done < length) {
- list[i].addr = ISERIES_HV_ADDR(p + done);
+ list[i].addr = iseries_hv_addr(p + done);
list[i].size = min(length-done, PAGE_SIZE);
done += list[i].size;
i++;
@@ -1496,8 +1497,8 @@ static void veth_receive(struct veth_lpar_connection *cnx,
cnx->dst_inst,
HvLpDma_AddressType_RealAddress,
HvLpDma_AddressType_TceIndex,
- ISERIES_HV_ADDR(&local_list),
- ISERIES_HV_ADDR(&remote_list),
+ iseries_hv_addr(&local_list),
+ iseries_hv_addr(&remote_list),
length);
if (rc != HvLpDma_Rc_Good) {
dev_kfree_skb_irq(skb);
@@ -1647,10 +1648,13 @@ static struct vio_device_id veth_device_table[] __devinitdata = {
MODULE_DEVICE_TABLE(vio, veth_device_table);
static struct vio_driver veth_driver = {
- .name = DRV_NAME,
.id_table = veth_device_table,
.probe = veth_probe,
- .remove = veth_remove
+ .remove = veth_remove,
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ }
};
/*
diff --git a/drivers/net/mace.c b/drivers/net/mace.c
index 81d0a26e4f41..2a5add257b8f 100644
--- a/drivers/net/mace.c
+++ b/drivers/net/mace.c
@@ -1016,6 +1016,7 @@ static struct of_device_id mace_match[] =
},
{},
};
+MODULE_DEVICE_TABLE (of, mace_match);
static struct macio_driver mace_driver =
{
@@ -1035,10 +1036,8 @@ static void __exit mace_cleanup(void)
{
macio_unregister_driver(&mace_driver);
- if (dummy_buf) {
- kfree(dummy_buf);
- dummy_buf = NULL;
- }
+ kfree(dummy_buf);
+ dummy_buf = NULL;
}
MODULE_AUTHOR("Paul Mackerras");
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 6fe948c10e72..71f2c6705bc3 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -1535,6 +1535,9 @@ static int mv643xx_eth_probe(struct device *ddev)
printk(KERN_NOTICE "%s: RX NAPI Enabled \n", dev->name);
#endif
+ if (mp->tx_sram_size > 0)
+ printk(KERN_NOTICE "%s: Using SRAM\n", dev->name);
+
return 0;
out:
diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c
index e531a4eedfee..d11821dd86ed 100644
--- a/drivers/net/ne2k-pci.c
+++ b/drivers/net/ne2k-pci.c
@@ -675,7 +675,6 @@ static int ne2k_pci_resume (struct pci_dev *pdev)
pci_set_power_state(pdev, 0);
pci_restore_state(pdev);
pci_enable_device(pdev);
- pci_set_master(pdev);
NS8390_init(dev, 1);
netif_device_attach(dev);
diff --git a/drivers/net/ni65.c b/drivers/net/ni65.c
index 925d1dfcc4dc..bb42ff218484 100644
--- a/drivers/net/ni65.c
+++ b/drivers/net/ni65.c
@@ -696,8 +696,7 @@ static void ni65_free_buffer(struct priv *p)
return;
for(i=0;i<TMDNUM;i++) {
- if(p->tmdbounce[i])
- kfree(p->tmdbounce[i]);
+ kfree(p->tmdbounce[i]);
#ifdef XMT_VIA_SKB
if(p->tmd_skb[i])
dev_kfree_skb(p->tmd_skb[i]);
@@ -710,12 +709,10 @@ static void ni65_free_buffer(struct priv *p)
if(p->recv_skb[i])
dev_kfree_skb(p->recv_skb[i]);
#else
- if(p->recvbounce[i])
- kfree(p->recvbounce[i]);
+ kfree(p->recvbounce[i]);
#endif
}
- if(p->self)
- kfree(p->self);
+ kfree(p->self);
}
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 9f22d138e3ad..818c185d6438 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -1020,6 +1020,12 @@ static void set_misc_reg(struct net_device *dev)
} else {
outb(full_duplex ? 4 : 0, nic_base + DLINK_DIAG);
}
+ } else if (info->flags & IS_DL10019) {
+ /* Advertise 100F, 100H, 10F, 10H */
+ mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 4, 0x01e1);
+ /* Restart MII autonegotiation */
+ mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 0, 0x0000);
+ mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 0, 0x1200);
}
}
diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c
index ec1a18d189a1..19c2df9c86fe 100644
--- a/drivers/net/rrunner.c
+++ b/drivers/net/rrunner.c
@@ -1710,10 +1710,8 @@ static int rr_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
error = -EFAULT;
}
wf_out:
- if (oldimage)
- kfree(oldimage);
- if (image)
- kfree(image);
+ kfree(oldimage);
+ kfree(image);
return error;
case SIOCRRID:
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index d303d162974f..3f5e93aad5c7 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -705,8 +705,7 @@ static void free_shared_mem(struct s2io_nic *nic)
}
kfree(mac_control->rings[i].ba[j]);
}
- if (mac_control->rings[i].ba)
- kfree(mac_control->rings[i].ba);
+ kfree(mac_control->rings[i].ba);
}
#endif
@@ -3045,7 +3044,7 @@ int s2io_set_swapper(nic_t * sp)
int wait_for_msix_trans(nic_t *nic, int i)
{
- XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+ XENA_dev_config_t __iomem *bar0 = nic->bar0;
u64 val64;
int ret = 0, cnt = 0;
@@ -3066,7 +3065,7 @@ int wait_for_msix_trans(nic_t *nic, int i)
void restore_xmsi_data(nic_t *nic)
{
- XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+ XENA_dev_config_t __iomem *bar0 = nic->bar0;
u64 val64;
int i;
@@ -3084,7 +3083,7 @@ void restore_xmsi_data(nic_t *nic)
void store_xmsi_data(nic_t *nic)
{
- XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+ XENA_dev_config_t __iomem *bar0 = nic->bar0;
u64 val64, addr, data;
int i;
@@ -3107,7 +3106,7 @@ void store_xmsi_data(nic_t *nic)
int s2io_enable_msi(nic_t *nic)
{
- XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+ XENA_dev_config_t __iomem *bar0 = nic->bar0;
u16 msi_ctrl, msg_val;
struct config_param *config = &nic->config;
struct net_device *dev = nic->dev;
@@ -3157,7 +3156,7 @@ int s2io_enable_msi(nic_t *nic)
int s2io_enable_msi_x(nic_t *nic)
{
- XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+ XENA_dev_config_t __iomem *bar0 = nic->bar0;
u64 tx_mat, rx_mat;
u16 msi_control; /* Temp variable */
int ret, i, j, msix_indx = 1;
diff --git a/drivers/net/saa9730.c b/drivers/net/saa9730.c
index fd0167077fbe..110e777f206e 100644
--- a/drivers/net/saa9730.c
+++ b/drivers/net/saa9730.c
@@ -997,10 +997,7 @@ static void __devexit saa9730_remove_one(struct pci_dev *pdev)
if (dev) {
unregister_netdev(dev);
-
- if (dev->priv)
- kfree(dev->priv);
-
+ kfree(dev->priv);
free_netdev(dev);
pci_release_regions(pdev);
pci_disable_device(pdev);
@@ -1096,8 +1093,7 @@ static int lan_saa9730_init(struct net_device *dev, int ioaddr, int irq)
return 0;
out:
- if (dev->priv)
- kfree(dev->priv);
+ kfree(dev->priv);
return ret;
}
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index 92f75529eff8..478791e09bf7 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -842,7 +842,7 @@ static void sis190_set_rx_mode(struct net_device *dev)
for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
i++, mclist = mclist->next) {
int bit_nr =
- ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
+ ether_crc(ETH_ALEN, mclist->dmi_addr) & 0x3f;
mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
rx_mode |= AcceptMulticast;
}
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index 23b713c700b3..1d4d88680db1 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -1696,15 +1696,20 @@ static int sis900_rx(struct net_device *net_dev)
long ioaddr = net_dev->base_addr;
unsigned int entry = sis_priv->cur_rx % NUM_RX_DESC;
u32 rx_status = sis_priv->rx_ring[entry].cmdsts;
+ int rx_work_limit;
if (netif_msg_rx_status(sis_priv))
printk(KERN_DEBUG "sis900_rx, cur_rx:%4.4d, dirty_rx:%4.4d "
"status:0x%8.8x\n",
sis_priv->cur_rx, sis_priv->dirty_rx, rx_status);
+ rx_work_limit = sis_priv->dirty_rx + NUM_RX_DESC - sis_priv->cur_rx;
while (rx_status & OWN) {
unsigned int rx_size;
+ if (--rx_work_limit < 0)
+ break;
+
rx_size = (rx_status & DSIZE) - CRC_SIZE;
if (rx_status & (ABORT|OVERRUN|TOOLONG|RUNT|RXISERR|CRCERR|FAERR)) {
@@ -1732,9 +1737,11 @@ static int sis900_rx(struct net_device *net_dev)
we are working on NULL sk_buff :-( */
if (sis_priv->rx_skbuff[entry] == NULL) {
if (netif_msg_rx_err(sis_priv))
- printk(KERN_INFO "%s: NULL pointer "
- "encountered in Rx ring, skipping\n",
- net_dev->name);
+ printk(KERN_WARNING "%s: NULL pointer "
+ "encountered in Rx ring\n"
+ "cur_rx:%4.4d, dirty_rx:%4.4d\n",
+ net_dev->name, sis_priv->cur_rx,
+ sis_priv->dirty_rx);
break;
}
@@ -1770,6 +1777,7 @@ static int sis900_rx(struct net_device *net_dev)
sis_priv->rx_ring[entry].cmdsts = 0;
sis_priv->rx_ring[entry].bufptr = 0;
sis_priv->stats.rx_dropped++;
+ sis_priv->cur_rx++;
break;
}
skb->dev = net_dev;
@@ -1787,7 +1795,7 @@ static int sis900_rx(struct net_device *net_dev)
/* refill the Rx buffer, what if the rate of refilling is slower
* than consuming ?? */
- for (;sis_priv->cur_rx - sis_priv->dirty_rx > 0; sis_priv->dirty_rx++) {
+ for (; sis_priv->cur_rx != sis_priv->dirty_rx; sis_priv->dirty_rx++) {
struct sk_buff *skb;
entry = sis_priv->dirty_rx % NUM_RX_DESC;
diff --git a/drivers/net/skfp/smt.c b/drivers/net/skfp/smt.c
index f17c05cbe44b..99a776a51fb5 100644
--- a/drivers/net/skfp/smt.c
+++ b/drivers/net/skfp/smt.c
@@ -1896,7 +1896,7 @@ void smt_swap_para(struct smt_header *sm, int len, int direction)
static void smt_string_swap(char *data, const char *format, int len)
{
- const char *open_paren = 0 ;
+ const char *open_paren = NULL ;
int x ;
while (len > 0 && *format) {
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index 901c960d342a..74d5f1a6fdea 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -1983,6 +1983,10 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr)
if (lp->version >= (CHIP_91100 << 4))
smc_phy_detect(dev);
+ /* then shut everything down to save power */
+ smc_shutdown(dev);
+ smc_phy_powerdown(dev);
+
/* Set default parameters */
lp->msg_enable = NETIF_MSG_LINK;
lp->ctl_rfduplx = 0;
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index ac9ce6509eee..817f200742c3 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -230,12 +230,12 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
#define SMC_CAN_USE_16BIT 1
#define SMC_CAN_USE_32BIT 0
-#define SMC_inb(a, r) inb((a) + (r) - 0xa0000000)
-#define SMC_inw(a, r) inw((a) + (r) - 0xa0000000)
-#define SMC_outb(v, a, r) outb(v, (a) + (r) - 0xa0000000)
-#define SMC_outw(v, a, r) outw(v, (a) + (r) - 0xa0000000)
-#define SMC_insw(a, r, p, l) insw((a) + (r) - 0xa0000000, p, l)
-#define SMC_outsw(a, r, p, l) outsw((a) + (r) - 0xa0000000, p, l)
+#define SMC_inb(a, r) inb((u32)a) + (r))
+#define SMC_inw(a, r) inw(((u32)a) + (r))
+#define SMC_outb(v, a, r) outb(v, ((u32)a) + (r))
+#define SMC_outw(v, a, r) outw(v, ((u32)a) + (r))
+#define SMC_insw(a, r, p, l) insw(((u32)a) + (r), p, l)
+#define SMC_outsw(a, r, p, l) outsw(((u32)a) + (r), p, l)
#define set_irq_type(irq, type) do {} while(0)
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
index efdb179ecc8c..38b2b0a3ce96 100644
--- a/drivers/net/starfire.c
+++ b/drivers/net/starfire.c
@@ -1091,8 +1091,10 @@ static int netdev_open(struct net_device *dev)
rx_ring_size = sizeof(struct starfire_rx_desc) * RX_RING_SIZE;
np->queue_mem_size = tx_done_q_size + rx_done_q_size + tx_ring_size + rx_ring_size;
np->queue_mem = pci_alloc_consistent(np->pci_dev, np->queue_mem_size, &np->queue_mem_dma);
- if (np->queue_mem == 0)
+ if (np->queue_mem == NULL) {
+ free_irq(dev->irq, dev);
return -ENOMEM;
+ }
np->tx_done_q = np->queue_mem;
np->tx_done_q_dma = np->queue_mem_dma;
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index 5de0554fd7c6..0ab9c38b4a34 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -80,7 +80,7 @@
I/O access could affect performance in ARM-based system
- Add Linux software VLAN support
- Version LK1.08 (D-Link):
+ Version LK1.08 (Philippe De Muyter phdm@macqel.be):
- Fix bug of custom mac address
(StationAddr register only accept word write)
@@ -91,11 +91,14 @@
Version LK1.09a (ICPlus):
- Add the delay time in reading the contents of EEPROM
+ Version LK1.10 (Philippe De Muyter phdm@macqel.be):
+ - Make 'unblock interface after Tx underrun' work
+
*/
#define DRV_NAME "sundance"
-#define DRV_VERSION "1.01+LK1.09a"
-#define DRV_RELDATE "10-Jul-2003"
+#define DRV_VERSION "1.01+LK1.10"
+#define DRV_RELDATE "28-Oct-2005"
/* The user-configurable values.
@@ -263,8 +266,10 @@ IV. Notes
IVb. References
The Sundance ST201 datasheet, preliminary version.
-http://cesdis.gsfc.nasa.gov/linux/misc/100mbps.html
-http://cesdis.gsfc.nasa.gov/linux/misc/NWay.html
+The Kendin KS8723 datasheet, preliminary version.
+The ICplus IP100 datasheet, preliminary version.
+http://www.scyld.com/expert/100mbps.html
+http://www.scyld.com/expert/NWay.html
IVc. Errata
@@ -500,6 +505,25 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
static int netdev_close(struct net_device *dev);
static struct ethtool_ops ethtool_ops;
+static void sundance_reset(struct net_device *dev, unsigned long reset_cmd)
+{
+ struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->base + ASICCtrl;
+ int countdown;
+
+ /* ST201 documentation states ASICCtrl is a 32bit register */
+ iowrite32 (reset_cmd | ioread32 (ioaddr), ioaddr);
+ /* ST201 documentation states reset can take up to 1 ms */
+ countdown = 10 + 1;
+ while (ioread32 (ioaddr) & (ResetBusy << 16)) {
+ if (--countdown == 0) {
+ printk(KERN_WARNING "%s : reset not completed !!\n", dev->name);
+ break;
+ }
+ udelay(100);
+ }
+}
+
static int __devinit sundance_probe1 (struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -1190,23 +1214,33 @@ static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs
("%s: Transmit status is %2.2x.\n",
dev->name, tx_status);
if (tx_status & 0x1e) {
+ if (netif_msg_tx_err(np))
+ printk("%s: Transmit error status %4.4x.\n",
+ dev->name, tx_status);
np->stats.tx_errors++;
if (tx_status & 0x10)
np->stats.tx_fifo_errors++;
if (tx_status & 0x08)
np->stats.collisions++;
+ if (tx_status & 0x04)
+ np->stats.tx_fifo_errors++;
if (tx_status & 0x02)
np->stats.tx_window_errors++;
- /* This reset has not been verified!. */
- if (tx_status & 0x10) { /* Reset the Tx. */
- np->stats.tx_fifo_errors++;
- spin_lock(&np->lock);
- reset_tx(dev);
- spin_unlock(&np->lock);
+ /*
+ ** This reset has been verified on
+ ** DFE-580TX boards ! phdm@macqel.be.
+ */
+ if (tx_status & 0x10) { /* TxUnderrun */
+ unsigned short txthreshold;
+
+ txthreshold = ioread16 (ioaddr + TxStartThresh);
+ /* Restart Tx FIFO and transmitter */
+ sundance_reset(dev, (NetworkReset|FIFOReset|TxReset) << 16);
+ iowrite16 (txthreshold, ioaddr + TxStartThresh);
+ /* No need to reset the Tx pointer here */
}
- if (tx_status & 0x1e) /* Restart the Tx. */
- iowrite16 (TxEnable,
- ioaddr + MACCtrl1);
+ /* Restart the Tx. */
+ iowrite16 (TxEnable, ioaddr + MACCtrl1);
}
/* Yup, this is a documentation bug. It cost me *hours*. */
iowrite16 (0, ioaddr + TxStatus);
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 1802c3b48799..1828a6bf8458 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -37,6 +37,7 @@
#include <linux/tcp.h>
#include <linux/workqueue.h>
#include <linux/prefetch.h>
+#include <linux/dma-mapping.h>
#include <net/checksum.h>
@@ -67,8 +68,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "3.42"
-#define DRV_MODULE_RELDATE "Oct 3, 2005"
+#define DRV_MODULE_VERSION "3.43"
+#define DRV_MODULE_RELDATE "Oct 24, 2005"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -219,6 +220,10 @@ static struct pci_device_id tg3_pci_tbl[] = {
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5753F,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5714,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5715,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780S,
@@ -466,6 +471,15 @@ static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val)
spin_unlock_irqrestore(&tp->indirect_lock, flags);
}
+static void tg3_write_mem_fast(struct tg3 *tp, u32 off, u32 val)
+{
+ /* If no workaround is needed, write to mem space directly */
+ if (tp->write32 != tg3_write_indirect_reg32)
+ tw32(NIC_SRAM_WIN_BASE + off, val);
+ else
+ tg3_write_mem(tp, off, val);
+}
+
static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val)
{
unsigned long flags;
@@ -570,7 +584,7 @@ static void tg3_switch_clocks(struct tg3 *tp)
u32 clock_ctrl = tr32(TG3PCI_CLOCK_CTRL);
u32 orig_clock_ctrl;
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
+ if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)
return;
orig_clock_ctrl = clock_ctrl;
@@ -1210,7 +1224,7 @@ static int tg3_set_power_state(struct tg3 *tp, int state)
CLOCK_CTRL_ALTCLK |
CLOCK_CTRL_PWRDOWN_PLL133);
udelay(40);
- } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) {
+ } else if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) {
/* do nothing */
} else if (!((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
(tp->tg3_flags & TG3_FLAG_ENABLE_ASF))) {
@@ -3712,14 +3726,14 @@ static inline void tg3_set_mtu(struct net_device *dev, struct tg3 *tp,
dev->mtu = new_mtu;
if (new_mtu > ETH_DATA_LEN) {
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) {
+ if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) {
tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE;
ethtool_op_set_tso(dev, 0);
}
else
tp->tg3_flags |= TG3_FLAG_JUMBO_RING_ENABLE;
} else {
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
+ if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)
tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
tp->tg3_flags &= ~TG3_FLAG_JUMBO_RING_ENABLE;
}
@@ -3850,7 +3864,7 @@ static void tg3_init_rings(struct tg3 *tp)
memset(tp->tx_ring, 0, TG3_TX_RING_BYTES);
tp->rx_pkt_buf_sz = RX_PKT_BUF_SZ;
- if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) &&
+ if ((tp->tg3_flags2 & TG3_FLG2_5780_CLASS) &&
(tp->dev->mtu > ETH_DATA_LEN))
tp->rx_pkt_buf_sz = RX_JUMBO_PKT_BUF_SZ;
@@ -3905,10 +3919,8 @@ static void tg3_init_rings(struct tg3 *tp)
*/
static void tg3_free_consistent(struct tg3 *tp)
{
- if (tp->rx_std_buffers) {
- kfree(tp->rx_std_buffers);
- tp->rx_std_buffers = NULL;
- }
+ kfree(tp->rx_std_buffers);
+ tp->rx_std_buffers = NULL;
if (tp->rx_std) {
pci_free_consistent(tp->pdev, TG3_RX_RING_BYTES,
tp->rx_std, tp->rx_std_mapping);
@@ -4347,7 +4359,7 @@ static int tg3_chip_reset(struct tg3 *tp)
val &= ~PCIX_CAPS_RELAXED_ORDERING;
pci_write_config_dword(tp->pdev, TG3PCI_X_CAPS, val);
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) {
+ if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) {
u32 val;
/* Chip reset on 5780 will reset MSI enable bit,
@@ -6003,7 +6015,7 @@ static int tg3_reset_hw(struct tg3 *tp)
tw32(MAC_RCV_VALUE_1, 0xffffffff & RCV_RULE_DISABLE_MASK);
if ((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
- (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5780))
+ !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
limit = 8;
else
limit = 16;
@@ -6191,14 +6203,16 @@ static void tg3_timer(unsigned long __opaque)
tp->timer_counter = tp->timer_multiplier;
}
- /* Heartbeat is only sent once every 120 seconds. */
+ /* Heartbeat is only sent once every 2 seconds. */
if (!--tp->asf_counter) {
if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
u32 val;
- tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_ALIVE);
- tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
- tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 3);
+ tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_MBOX,
+ FWCMD_NICDRV_ALIVE2);
+ tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
+ /* 5 seconds timeout */
+ tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5);
val = tr32(GRC_RX_CPU_EVENT);
val |= (1 << 14);
tw32(GRC_RX_CPU_EVENT, val);
@@ -6409,7 +6423,7 @@ static int tg3_open(struct net_device *dev)
tp->timer_counter = tp->timer_multiplier =
(HZ / tp->timer_offset);
tp->asf_counter = tp->asf_multiplier =
- ((HZ / tp->timer_offset) * 120);
+ ((HZ / tp->timer_offset) * 2);
init_timer(&tp->timer);
tp->timer.expires = jiffies + tp->timer_offset;
@@ -7237,7 +7251,7 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
cmd->supported |= (SUPPORTED_1000baseT_Half |
SUPPORTED_1000baseT_Full);
- if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES))
+ if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES))
cmd->supported |= (SUPPORTED_100baseT_Half |
SUPPORTED_100baseT_Full |
SUPPORTED_10baseT_Half |
@@ -7264,7 +7278,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct tg3 *tp = netdev_priv(dev);
- if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) {
+ if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) {
/* These are the only valid advertisement bits allowed. */
if (cmd->autoneg == AUTONEG_ENABLE &&
(cmd->advertising & ~(ADVERTISED_1000baseT_Half |
@@ -7272,7 +7286,17 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
ADVERTISED_Autoneg |
ADVERTISED_FIBRE)))
return -EINVAL;
- }
+ /* Fiber can only do SPEED_1000. */
+ else if ((cmd->autoneg != AUTONEG_ENABLE) &&
+ (cmd->speed != SPEED_1000))
+ return -EINVAL;
+ /* Copper cannot force SPEED_1000. */
+ } else if ((cmd->autoneg != AUTONEG_ENABLE) &&
+ (cmd->speed == SPEED_1000))
+ return -EINVAL;
+ else if ((cmd->speed == SPEED_1000) &&
+ (tp->tg3_flags2 & TG3_FLAG_10_100_ONLY))
+ return -EINVAL;
tg3_full_lock(tp, 0);
@@ -8380,7 +8404,7 @@ static void __devinit tg3_get_nvram_info(struct tg3 *tp)
}
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) ||
- (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)) {
+ (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
switch (nvcfg1 & NVRAM_CFG1_VENDOR_MASK) {
case FLASH_VENDOR_ATMEL_FLASH_BUFFERED:
tp->nvram_jedecnum = JEDEC_ATMEL;
@@ -8980,7 +9004,7 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
tp->phy_id = eeprom_phy_id;
if (eeprom_phy_serdes) {
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
+ if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)
tp->tg3_flags2 |= TG3_FLG2_MII_SERDES;
else
tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES;
@@ -9393,8 +9417,11 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
}
/* Find msi capability. */
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) {
+ tp->tg3_flags2 |= TG3_FLG2_5780_CLASS;
tp->msi_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_MSI);
+ }
/* Initialize misc host control in PCI block. */
tp->misc_host_ctrl |= (misc_ctrl_reg &
@@ -9412,7 +9439,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
+ (tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
tp->tg3_flags2 |= TG3_FLG2_5750_PLUS;
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) ||
@@ -9607,7 +9634,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
* ether_setup() via the alloc_etherdev() call
*/
if (tp->dev->mtu > ETH_DATA_LEN &&
- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5780)
+ !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
tp->tg3_flags |= TG3_FLAG_JUMBO_RING_ENABLE;
/* Determine WakeOnLan speed to use. */
@@ -9830,7 +9857,7 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
mac_offset = 0x7c;
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 &&
!(tp->tg3_flags & TG3_FLG2_SUN_570X)) ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) {
+ (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
if (tr32(TG3PCI_DUAL_MAC_CTRL) & DUAL_MAC_CTRL_ID)
mac_offset = 0xcc;
if (tg3_nvram_lock(tp))
@@ -10148,6 +10175,9 @@ static int __devinit tg3_test_dma(struct tg3 *tp)
} else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) {
/* 5780 always in PCIX mode */
tp->dma_rwctrl |= 0x00144000;
+ } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) {
+ /* 5714 always in PCIX mode */
+ tp->dma_rwctrl |= 0x00148000;
} else {
tp->dma_rwctrl |= 0x001b000f;
}
@@ -10347,6 +10377,7 @@ static char * __devinit tg3_phy_string(struct tg3 *tp)
case PHY_ID_BCM5705: return "5705";
case PHY_ID_BCM5750: return "5750";
case PHY_ID_BCM5752: return "5752";
+ case PHY_ID_BCM5714: return "5714";
case PHY_ID_BCM5780: return "5780";
case PHY_ID_BCM8002: return "8002/serdes";
case 0: return "serdes";
@@ -10492,17 +10523,17 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
}
/* Configure DMA attributes. */
- err = pci_set_dma_mask(pdev, 0xffffffffffffffffULL);
+ err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
if (!err) {
pci_using_dac = 1;
- err = pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL);
+ err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
if (err < 0) {
printk(KERN_ERR PFX "Unable to obtain 64 bit DMA "
"for consistent allocations\n");
goto err_out_free_res;
}
} else {
- err = pci_set_dma_mask(pdev, 0xffffffffULL);
+ err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
if (err) {
printk(KERN_ERR PFX "No usable DMA configuration, "
"aborting.\n");
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 2e733c60bfa4..fb7e2a5f4a08 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -137,6 +137,7 @@
#define ASIC_REV_5750 0x04
#define ASIC_REV_5752 0x06
#define ASIC_REV_5780 0x08
+#define ASIC_REV_5714 0x09
#define GET_CHIP_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 8)
#define CHIPREV_5700_AX 0x70
#define CHIPREV_5700_BX 0x71
@@ -531,6 +532,8 @@
#define MAC_SERDES_CFG_EDGE_SELECT 0x00001000
#define MAC_SERDES_STAT 0x00000594
/* 0x598 --> 0x5b0 unused */
+#define SERDES_RX_CTRL 0x000005b0 /* 5780/5714 only */
+#define SERDES_RX_SIG_DETECT 0x00000400
#define SG_DIG_CTRL 0x000005b0
#define SG_DIG_USING_HW_AUTONEG 0x80000000
#define SG_DIG_SOFT_RESET 0x40000000
@@ -1329,6 +1332,8 @@
#define GRC_LCLCTRL_CLEARINT 0x00000002
#define GRC_LCLCTRL_SETINT 0x00000004
#define GRC_LCLCTRL_INT_ON_ATTN 0x00000008
+#define GRC_LCLCTRL_USE_SIG_DETECT 0x00000010 /* 5714/5780 only */
+#define GRC_LCLCTRL_USE_EXT_SIG_DETECT 0x00000020 /* 5714/5780 only */
#define GRC_LCLCTRL_GPIO_INPUT3 0x00000020
#define GRC_LCLCTRL_GPIO_OE3 0x00000040
#define GRC_LCLCTRL_GPIO_OUTPUT3 0x00000080
@@ -1507,6 +1512,7 @@
#define FWCMD_NICDRV_IPV6ADDR_CHG 0x00000004
#define FWCMD_NICDRV_FIX_DMAR 0x00000005
#define FWCMD_NICDRV_FIX_DMAW 0x00000006
+#define FWCMD_NICDRV_ALIVE2 0x0000000d
#define NIC_SRAM_FW_CMD_LEN_MBOX 0x00000b7c
#define NIC_SRAM_FW_CMD_DATA_MBOX 0x00000b80
#define NIC_SRAM_FW_ASF_STATUS_MBOX 0x00000c00
@@ -2175,6 +2181,7 @@ struct tg3 {
TG3_FLG2_MII_SERDES)
#define TG3_FLG2_PARALLEL_DETECT 0x01000000
#define TG3_FLG2_ICH_WORKAROUND 0x02000000
+#define TG3_FLG2_5780_CLASS 0x04000000
u32 split_mode_max_reqs;
#define SPLIT_MODE_5704_MAX_REQ 3
@@ -2222,6 +2229,7 @@ struct tg3 {
#define PHY_ID_BCM5705 0x600081a0
#define PHY_ID_BCM5750 0x60008180
#define PHY_ID_BCM5752 0x60008100
+#define PHY_ID_BCM5714 0x60008340
#define PHY_ID_BCM5780 0x60008350
#define PHY_ID_BCM8002 0x60010140
#define PHY_ID_INVALID 0xffffffff
@@ -2246,8 +2254,8 @@ struct tg3 {
(X) == PHY_ID_BCM5411 || (X) == PHY_ID_BCM5701 || \
(X) == PHY_ID_BCM5703 || (X) == PHY_ID_BCM5704 || \
(X) == PHY_ID_BCM5705 || (X) == PHY_ID_BCM5750 || \
- (X) == PHY_ID_BCM5752 || (X) == PHY_ID_BCM5780 || \
- (X) == PHY_ID_BCM8002)
+ (X) == PHY_ID_BCM5752 || (X) == PHY_ID_BCM5714 || \
+ (X) == PHY_ID_BCM5780 || (X) == PHY_ID_BCM8002)
struct tg3_hw_stats *hw_stats;
dma_addr_t stats_mapping;
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
index 6b8eee8f7bfd..d7fb3ffe06ac 100644
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -2076,8 +2076,7 @@ static int __init de_init_one (struct pci_dev *pdev,
return 0;
err_out_iomap:
- if (de->ee_data)
- kfree(de->ee_data);
+ kfree(de->ee_data);
iounmap(regs);
err_out_res:
pci_release_regions(pdev);
@@ -2096,8 +2095,7 @@ static void __exit de_remove_one (struct pci_dev *pdev)
if (!dev)
BUG();
unregister_netdev(dev);
- if (de->ee_data)
- kfree(de->ee_data);
+ kfree(de->ee_data);
iounmap(de->regs);
pci_release_regions(pdev);
pci_disable_device(pdev);
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index 6266a9a7e6e3..125ed00e95a5 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -1727,8 +1727,7 @@ err_out_free_ring:
tp->rx_ring, tp->rx_ring_dma);
err_out_mtable:
- if (tp->mtable)
- kfree (tp->mtable);
+ kfree (tp->mtable);
pci_iounmap(pdev, ioaddr);
err_out_free_res:
@@ -1806,8 +1805,7 @@ static void __devexit tulip_remove_one (struct pci_dev *pdev)
sizeof (struct tulip_rx_desc) * RX_RING_SIZE +
sizeof (struct tulip_tx_desc) * TX_RING_SIZE,
tp->rx_ring, tp->rx_ring_dma);
- if (tp->mtable)
- kfree (tp->mtable);
+ kfree (tp->mtable);
pci_iounmap(pdev, tp->base_addr);
free_netdev (dev);
pci_release_regions (pdev);
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index abc5cee6eedc..a368d08e7d19 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -1212,10 +1212,8 @@ static void velocity_free_td_ring(struct velocity_info *vptr)
velocity_free_td_ring_entry(vptr, j, i);
}
- if (vptr->td_infos[j]) {
- kfree(vptr->td_infos[j]);
- vptr->td_infos[j] = NULL;
- }
+ kfree(vptr->td_infos[j]);
+ vptr->td_infos[j] = NULL;
}
}
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index cb429e783749..750c0167539c 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -35,6 +35,7 @@
#include <linux/interrupt.h>
#include <linux/in.h>
#include <linux/bitops.h>
+#include <linux/scatterlist.h>
#include <asm/io.h>
#include <asm/system.h>
@@ -1590,11 +1591,9 @@ static void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct
aes_counter[12] = (u8)(counter >> 24);
counter++;
memcpy (plain, aes_counter, 16);
- sg[0].page = virt_to_page(plain);
- sg[0].offset = ((long) plain & ~PAGE_MASK);
- sg[0].length = 16;
+ sg_set_buf(sg, plain, 16);
crypto_cipher_encrypt(tfm, sg, sg, 16);
- cipher = kmap(sg[0].page) + sg[0].offset;
+ cipher = kmap(sg->page) + sg->offset;
for (j=0; (j<16) && (i< (sizeof(context->coeff)/sizeof(context->coeff[0]))); ) {
context->coeff[i++] = ntohl(*(u32 *)&cipher[j]);
j += 4;
@@ -2381,14 +2380,10 @@ void stop_airo_card( struct net_device *dev, int freeres )
dev_kfree_skb(skb);
}
- if (ai->flash)
- kfree(ai->flash);
- if (ai->rssi)
- kfree(ai->rssi);
- if (ai->APList)
- kfree(ai->APList);
- if (ai->SSID)
- kfree(ai->SSID);
+ kfree(ai->flash);
+ kfree(ai->rssi);
+ kfree(ai->APList);
+ kfree(ai->SSID);
if (freeres) {
/* PCMCIA frees this stuff, so only for PCI and ISA */
release_region( dev->base_addr, 64 );
@@ -3626,10 +3621,8 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
int rc;
memset( &mySsid, 0, sizeof( mySsid ) );
- if (ai->flash) {
- kfree (ai->flash);
- ai->flash = NULL;
- }
+ kfree (ai->flash);
+ ai->flash = NULL;
/* The NOP is the first step in getting the card going */
cmd.cmd = NOP;
@@ -3666,14 +3659,10 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
tdsRssiRid rssi_rid;
CapabilityRid cap_rid;
- if (ai->APList) {
- kfree(ai->APList);
- ai->APList = NULL;
- }
- if (ai->SSID) {
- kfree(ai->SSID);
- ai->SSID = NULL;
- }
+ kfree(ai->APList);
+ ai->APList = NULL;
+ kfree(ai->SSID);
+ ai->SSID = NULL;
// general configuration (read/modify/write)
status = readConfigRid(ai, lock);
if ( status != SUCCESS ) return ERROR;
@@ -3687,10 +3676,8 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
memcpy(ai->rssi, (u8*)&rssi_rid + 2, 512); /* Skip RID length member */
}
else {
- if (ai->rssi) {
- kfree(ai->rssi);
- ai->rssi = NULL;
- }
+ kfree(ai->rssi);
+ ai->rssi = NULL;
if (cap_rid.softCap & 8)
ai->config.rmode |= RXMODE_NORMALIZED_RSSI;
else
@@ -5369,11 +5356,13 @@ static int proc_BSSList_open( struct inode *inode, struct file *file ) {
static int proc_close( struct inode *inode, struct file *file )
{
- struct proc_data *data = (struct proc_data *)file->private_data;
- if ( data->on_close != NULL ) data->on_close( inode, file );
- if ( data->rbuffer ) kfree( data->rbuffer );
- if ( data->wbuffer ) kfree( data->wbuffer );
- kfree( data );
+ struct proc_data *data = file->private_data;
+
+ if (data->on_close != NULL)
+ data->on_close(inode, file);
+ kfree(data->rbuffer);
+ kfree(data->wbuffer);
+ kfree(data);
return 0;
}
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index bf25584d68d3..784de9109113 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -258,9 +258,7 @@ static void airo_detach(dev_link_t *link)
/* Unlink device structure, free pieces */
*linkp = link->next;
- if (link->priv) {
- kfree(link->priv);
- }
+ kfree(link->priv);
kfree(link);
} /* airo_detach */
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index d57011028b72..1fbe027d26b6 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -1653,8 +1653,7 @@ void stop_atmel_card(struct net_device *dev, int freeres)
unregister_netdev(dev);
remove_proc_entry("driver/atmel", NULL);
free_irq(dev->irq, dev);
- if (priv->firmware)
- kfree(priv->firmware);
+ kfree(priv->firmware);
if (freeres) {
/* PCMCIA frees this stuff, so only for PCI */
release_region(dev->base_addr, 64);
@@ -2450,8 +2449,7 @@ static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
break;
}
- if (priv->firmware)
- kfree(priv->firmware);
+ kfree(priv->firmware);
priv->firmware = new_firmware;
priv->firmware_length = com.len;
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index ff031a3985b3..195cb36619e8 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -259,8 +259,7 @@ static void atmel_detach(dev_link_t *link)
/* Unlink device structure, free pieces */
*linkp = link->next;
- if (link->priv)
- kfree(link->priv);
+ kfree(link->priv);
kfree(link);
}
diff --git a/drivers/net/wireless/hermes.c b/drivers/net/wireless/hermes.c
index eba0d9d2b7c5..579480dad374 100644
--- a/drivers/net/wireless/hermes.c
+++ b/drivers/net/wireless/hermes.c
@@ -444,6 +444,43 @@ int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, unsigned len,
return err;
}
+/* Write a block of data to the chip's buffer with padding if
+ * neccessary, via the BAP. Synchronization/serialization is the
+ * caller's problem. len must be even.
+ *
+ * Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
+ */
+int hermes_bap_pwrite_pad(hermes_t *hw, int bap, const void *buf, unsigned data_len, unsigned len,
+ u16 id, u16 offset)
+{
+ int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
+ int err = 0;
+
+ if (len < 0 || len % 2 || data_len > len)
+ return -EINVAL;
+
+ err = hermes_bap_seek(hw, bap, id, offset);
+ if (err)
+ goto out;
+
+ /* Transfer all the complete words of data */
+ hermes_write_words(hw, dreg, buf, data_len/2);
+ /* If there is an odd byte left over pad and transfer it */
+ if (data_len & 1) {
+ u8 end[2];
+ end[1] = 0;
+ end[0] = ((unsigned char *)buf)[data_len - 1];
+ hermes_write_words(hw, dreg, end, 1);
+ data_len ++;
+ }
+ /* Now send zeros for the padding */
+ if (data_len < len)
+ hermes_clear_words(hw, dreg, (len - data_len) / 2);
+ /* Complete */
+ out:
+ return err;
+}
+
/* Read a Length-Type-Value record from the card.
*
* If length is NULL, we ignore the length read from the card, and
@@ -531,6 +568,7 @@ EXPORT_SYMBOL(hermes_allocate);
EXPORT_SYMBOL(hermes_bap_pread);
EXPORT_SYMBOL(hermes_bap_pwrite);
+EXPORT_SYMBOL(hermes_bap_pwrite_pad);
EXPORT_SYMBOL(hermes_read_ltv);
EXPORT_SYMBOL(hermes_write_ltv);
diff --git a/drivers/net/wireless/hermes.h b/drivers/net/wireless/hermes.h
index ad28e3294360..a6bd472d75d4 100644
--- a/drivers/net/wireless/hermes.h
+++ b/drivers/net/wireless/hermes.h
@@ -376,6 +376,8 @@ int hermes_bap_pread(hermes_t *hw, int bap, void *buf, unsigned len,
u16 id, u16 offset);
int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, unsigned len,
u16 id, u16 offset);
+int hermes_bap_pwrite_pad(hermes_t *hw, int bap, const void *buf,
+ unsigned data_len, unsigned len, u16 id, u16 offset);
int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned buflen,
u16 *length, void *buf);
int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index 53f5246c40aa..2617d70bcda9 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -552,7 +552,6 @@ static int prism2_ioctl_giwaplist(struct net_device *dev,
kfree(addr);
kfree(qual);
-
return 0;
}
@@ -3081,9 +3080,7 @@ static int prism2_ioctl_priv_download(local_info_t *local, struct iw_point *p)
ret = local->func->download(local, param);
out:
- if (param != NULL)
- kfree(param);
-
+ kfree(param);
return ret;
}
#endif /* PRISM2_DOWNLOAD_SUPPORT */
@@ -3890,9 +3887,7 @@ static int prism2_ioctl_priv_hostapd(local_info_t *local, struct iw_point *p)
}
out:
- if (param != NULL)
- kfree(param);
-
+ kfree(param);
return ret;
}
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index de4e6c23e4b8..3db0c32afe82 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -4030,6 +4030,10 @@ static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *priv)
int i;
rxq = (struct ipw_rx_queue *)kmalloc(sizeof(*rxq), GFP_KERNEL);
+ if (unlikely(!rxq)) {
+ IPW_ERROR("memory allocation failed\n");
+ return NULL;
+ }
memset(rxq, 0, sizeof(*rxq));
spin_lock_init(&rxq->lock);
INIT_LIST_HEAD(&rxq->rx_free);
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index d3d4ec9e242e..488ab06fb79f 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -490,7 +490,8 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
return 0;
}
- /* Check packet length, pad short packets, round up odd length */
+ /* Length of the packet body */
+ /* FIXME: what if the skb is smaller than this? */
len = max_t(int, ALIGN(skb->len, 2), ETH_ZLEN);
skb = skb_padto(skb, len);
if (skb == NULL)
@@ -541,13 +542,21 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
stats->tx_errors++;
goto fail;
}
+ /* Actual xfer length - allow for padding */
+ len = ALIGN(data_len, 2);
+ if (len < ETH_ZLEN - ETH_HLEN)
+ len = ETH_ZLEN - ETH_HLEN;
} else { /* IEEE 802.3 frame */
data_len = len + ETH_HLEN;
data_off = HERMES_802_3_OFFSET;
p = skb->data;
+ /* Actual xfer length - round up for odd length packets */
+ len = ALIGN(data_len, 2);
+ if (len < ETH_ZLEN)
+ len = ETH_ZLEN;
}
- err = hermes_bap_pwrite(hw, USER_BAP, p, data_len,
+ err = hermes_bap_pwrite_pad(hw, USER_BAP, p, data_len, len,
txfid, data_off);
if (err) {
printk(KERN_ERR "%s: Error %d writing packet to BAP\n",
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
index 6c9584a9f284..78bdb359835e 100644
--- a/drivers/net/wireless/prism54/islpci_dev.c
+++ b/drivers/net/wireless/prism54/islpci_dev.c
@@ -754,8 +754,7 @@ islpci_free_memory(islpci_private *priv)
pci_unmap_single(priv->pdev, buf->pci_addr,
buf->size, PCI_DMA_FROMDEVICE);
buf->pci_addr = 0;
- if (buf->mem)
- kfree(buf->mem);
+ kfree(buf->mem);
buf->size = 0;
buf->mem = NULL;
}
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index 5952e9960499..3b49efa37ee5 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -97,12 +97,6 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
/* lock the driver code */
spin_lock_irqsave(&priv->slock, flags);
- /* determine the amount of fragments needed to store the frame */
-
- frame_size = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
- if (init_wds)
- frame_size += 6;
-
/* check whether the destination queue has enough fragments for the frame */
curr_frag = le32_to_cpu(cb->driver_curr_frag[ISL38XX_CB_TX_DATA_LQ]);
if (unlikely(curr_frag - priv->free_data_tx >= ISL38XX_CB_TX_QSIZE)) {
@@ -213,6 +207,7 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
/* store the skb address for future freeing */
priv->data_low_tx[index] = skb;
/* set the proper fragment start address and size information */
+ frame_size = skb->len;
fragment->size = cpu_to_le16(frame_size);
fragment->flags = cpu_to_le16(0); /* set to 1 if more fragments */
fragment->address = cpu_to_le32(pci_map_address);
@@ -246,12 +241,10 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
return 0;
drop_free:
- /* free the skbuf structure before aborting */
- dev_kfree_skb(skb);
- skb = NULL;
-
priv->statistics.tx_dropped++;
spin_unlock_irqrestore(&priv->slock, flags);
+ dev_kfree_skb(skb);
+ skb = NULL;
return err;
}
diff --git a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c
index 4937a5ad4b2c..6a60c5970cb5 100644
--- a/drivers/net/wireless/prism54/islpci_mgt.c
+++ b/drivers/net/wireless/prism54/islpci_mgt.c
@@ -137,7 +137,7 @@ islpci_mgmt_rx_fill(struct net_device *ndev)
PCI_DMA_FROMDEVICE);
if (!buf->pci_addr) {
printk(KERN_WARNING
- "Failed to make memory DMA'able\n.");
+ "Failed to make memory DMA'able.\n");
return -ENOMEM;
}
}
diff --git a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c
index 12123e24b113..eea2f04c8c6d 100644
--- a/drivers/net/wireless/prism54/oid_mgt.c
+++ b/drivers/net/wireless/prism54/oid_mgt.c
@@ -268,11 +268,10 @@ mgt_clean(islpci_private *priv)
if (!priv->mib)
return;
- for (i = 0; i < OID_NUM_LAST; i++)
- if (priv->mib[i]) {
- kfree(priv->mib[i]);
- priv->mib[i] = NULL;
- }
+ for (i = 0; i < OID_NUM_LAST; i++) {
+ kfree(priv->mib[i]);
+ priv->mib[i] = NULL;
+ }
kfree(priv->mib);
priv->mib = NULL;
}
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
index 7bc7fc823128..d25264ba0c0e 100644
--- a/drivers/net/wireless/strip.c
+++ b/drivers/net/wireless/strip.c
@@ -860,12 +860,9 @@ static int allocate_buffers(struct strip *strip_info, int mtu)
strip_info->mtu = dev->mtu = mtu;
return (1);
}
- if (r)
- kfree(r);
- if (s)
- kfree(s);
- if (t)
- kfree(t);
+ kfree(r);
+ kfree(s);
+ kfree(t);
return (0);
}
@@ -922,13 +919,9 @@ static int strip_change_mtu(struct net_device *dev, int new_mtu)
printk(KERN_NOTICE "%s: strip MTU changed fom %d to %d.\n",
strip_info->dev->name, old_mtu, strip_info->mtu);
- if (orbuff)
- kfree(orbuff);
- if (osbuff)
- kfree(osbuff);
- if (otbuff)
- kfree(otbuff);
-
+ kfree(orbuff);
+ kfree(osbuff);
+ kfree(otbuff);
return 0;
}
@@ -2498,18 +2491,13 @@ static int strip_close_low(struct net_device *dev)
/*
* Free all STRIP frame buffers.
*/
- if (strip_info->rx_buff) {
- kfree(strip_info->rx_buff);
- strip_info->rx_buff = NULL;
- }
- if (strip_info->sx_buff) {
- kfree(strip_info->sx_buff);
- strip_info->sx_buff = NULL;
- }
- if (strip_info->tx_buff) {
- kfree(strip_info->tx_buff);
- strip_info->tx_buff = NULL;
- }
+ kfree(strip_info->rx_buff);
+ strip_info->rx_buff = NULL;
+ kfree(strip_info->sx_buff);
+ strip_info->sx_buff = NULL;
+ kfree(strip_info->tx_buff);
+ strip_info->tx_buff = NULL;
+
del_timer(&strip_info->idle_timer);
return 0;
}
diff --git a/drivers/pci/hotplug/cpcihp_generic.c b/drivers/pci/hotplug/cpcihp_generic.c
index a62a4345b466..2d4639d6841f 100644
--- a/drivers/pci/hotplug/cpcihp_generic.c
+++ b/drivers/pci/hotplug/cpcihp_generic.c
@@ -39,6 +39,7 @@
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/pci.h>
+#include <linux/string.h>
#include "cpci_hotplug.h"
#define DRIVER_VERSION "0.1"
diff --git a/drivers/pci/hotplug/cpcihp_zt5550.c b/drivers/pci/hotplug/cpcihp_zt5550.c
index 790abadd816c..f7cb00da38df 100644
--- a/drivers/pci/hotplug/cpcihp_zt5550.c
+++ b/drivers/pci/hotplug/cpcihp_zt5550.c
@@ -36,6 +36,7 @@
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/pci.h>
+#include <linux/signal.h> /* SA_SHIRQ */
#include "cpci_hotplug.h"
#include "cpcihp_zt5550.h"
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c
index 8e47fa66e25e..060d74775d7b 100644
--- a/drivers/pci/hotplug/fakephp.c
+++ b/drivers/pci/hotplug/fakephp.c
@@ -37,6 +37,8 @@
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "pci_hotplug.h"
#include "../pci.h"
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c
index 0392e004258f..aabf1e70b528 100644
--- a/drivers/pci/hotplug/ibmphp_core.c
+++ b/drivers/pci/hotplug/ibmphp_core.c
@@ -1077,7 +1077,7 @@ static int enable_slot(struct hotplug_slot *hs)
if (rc) {
err("Adding this card exceeds the limitations of this bus.\n");
err("(i.e., >1 133MHz cards running on same bus, or "
- ">2 66 PCI cards running on same bus\n.");
+ ">2 66 PCI cards running on same bus.\n");
err("Try hot-adding into another bus\n");
rc = -EINVAL;
goto error_nopower;
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
index 33b539b34f7e..ff17d8e07e94 100644
--- a/drivers/pci/hotplug/pciehp_pci.c
+++ b/drivers/pci/hotplug/pciehp_pci.c
@@ -113,7 +113,7 @@ int pciehp_unconfigure_device(struct pci_func* func)
*/
int pciehp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)
{
-#if defined(CONFIG_X86) && !defined(CONFIG_X86_IO_APIC) && !defined(CONFIG_X86_64)
+#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_IO_APIC)
int rc;
u16 temp_word;
struct pci_dev fakedev;
diff --git a/drivers/pci/hotplug/pciehprm_nonacpi.c b/drivers/pci/hotplug/pciehprm_nonacpi.c
index 3622965f8961..33b2c69a0829 100644
--- a/drivers/pci/hotplug/pciehprm_nonacpi.c
+++ b/drivers/pci/hotplug/pciehprm_nonacpi.c
@@ -33,10 +33,13 @@
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/slab.h>
+
#include <asm/uaccess.h>
#ifdef CONFIG_IA64
#include <asm/iosapic.h>
#endif
+
#include "pciehp.h"
#include "pciehprm.h"
#include "pciehprm_nonacpi.h"
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c
index ad1017da8656..fcb66b9a0e28 100644
--- a/drivers/pci/hotplug/rpadlpar_core.c
+++ b/drivers/pci/hotplug/rpadlpar_core.c
@@ -16,10 +16,13 @@
*/
#include <linux/init.h>
#include <linux/pci.h>
+#include <linux/string.h>
+
#include <asm/pci-bridge.h>
#include <asm/semaphore.h>
#include <asm/rtas.h>
#include <asm/vio.h>
+
#include "../pci.h"
#include "rpaphp.h"
#include "rpadlpar.h"
diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c
index 46c157d26a2f..f7c12d7dfcfc 100644
--- a/drivers/pci/hotplug/rpaphp_pci.c
+++ b/drivers/pci/hotplug/rpaphp_pci.c
@@ -23,11 +23,13 @@
*
*/
#include <linux/pci.h>
+#include <linux/string.h>
+
#include <asm/pci-bridge.h>
#include <asm/rtas.h>
#include <asm/machdep.h>
-#include "../pci.h" /* for pci_add_new_bus */
+#include "../pci.h" /* for pci_add_new_bus */
#include "rpaphp.h"
static struct pci_bus *find_bus_among_children(struct pci_bus *bus,
diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c
index 0e8815495083..daa89ae57123 100644
--- a/drivers/pci/hotplug/rpaphp_slot.c
+++ b/drivers/pci/hotplug/rpaphp_slot.c
@@ -27,6 +27,9 @@
#include <linux/kobject.h>
#include <linux/sysfs.h>
#include <linux/pci.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
#include <asm/rtas.h>
#include "rpaphp.h"
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
index abe2cf411e68..08ad26a0cae7 100644
--- a/drivers/pci/hotplug/shpchp.h
+++ b/drivers/pci/hotplug/shpchp.h
@@ -32,6 +32,8 @@
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/delay.h>
+#include <linux/sched.h> /* signal_pending(), struct timer_list */
+
#include "pci_hotplug.h"
#if !defined(MODULE)
diff --git a/drivers/pci/hotplug/shpchprm_nonacpi.c b/drivers/pci/hotplug/shpchprm_nonacpi.c
index d70fe5408417..c6b40998eeb3 100644
--- a/drivers/pci/hotplug/shpchprm_nonacpi.c
+++ b/drivers/pci/hotplug/shpchprm_nonacpi.c
@@ -32,6 +32,8 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/pci.h>
+#include <linux/slab.h>
+
#include "shpchp.h"
int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 8972e6a3aac0..ae986e590b48 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -8,6 +8,8 @@
#include <linux/init.h>
#include <linux/device.h>
#include <linux/mempolicy.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "pci.h"
/*
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 61b855c99e39..e74d75843047 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -15,6 +15,7 @@
#include <linux/pci.h>
#include <linux/module.h>
#include <linux/spinlock.h>
+#include <linux/string.h>
#include <asm/dma.h> /* isa_dma_bridge_buggy */
#include "pci.h"
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index 14f05d22bb70..467a4ceccf10 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -11,6 +11,8 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/pm.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <linux/pcieport_if.h>
#include "portdrv.h"
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index 3c565ce7f77b..02260141dc81 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -12,6 +12,7 @@
#include <linux/errno.h>
#include <linux/pm.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/pcieport_if.h>
#include "portdrv.h"
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index bbd9c2323d8c..5627ce1d2b32 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -356,7 +356,7 @@ static void piix4_mem_quirk(struct pci_dev *dev, const char *name, unsigned int
/*
* PIIX4 ACPI: Two IO regions pointed to by longwords at
* 0x40 (64 bytes of ACPI registers)
- * 0x90 (32 bytes of SMB registers)
+ * 0x90 (16 bytes of SMB registers)
* and a few strange programmable PIIX4 device resources.
*/
static void __devinit quirk_piix4_acpi(struct pci_dev *dev)
@@ -366,7 +366,7 @@ static void __devinit quirk_piix4_acpi(struct pci_dev *dev)
pci_read_config_dword(dev, 0x40, &region);
quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES, "PIIX4 ACPI");
pci_read_config_dword(dev, 0x90, &region);
- quirk_io_region(dev, region, 32, PCI_BRIDGE_RESOURCES+1, "PIIX4 SMB");
+ quirk_io_region(dev, region, 16, PCI_BRIDGE_RESOURCES+1, "PIIX4 SMB");
/* Device resource A has enables for some of the other ones */
pci_read_config_dword(dev, 0x5c, &res_a);
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c
index 49bd21702314..598a115cd00e 100644
--- a/drivers/pci/rom.c
+++ b/drivers/pci/rom.c
@@ -9,6 +9,7 @@
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include "pci.h"
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 36cc9a96a338..ccf20039e909 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -154,6 +154,16 @@ config TCIC
"Bridge" is the name used for the hardware inside your computer that
PCMCIA cards are plugged into. If unsure, say N.
+config PCMCIA_M8XX
+ tristate "MPC8xx PCMCIA support"
+ depends on PCMCIA && PPC
+ select PCCARD_NONSTATIC
+ help
+ Say Y here to include support for PowerPC 8xx series PCMCIA
+ controller.
+
+ This driver is also available as a module called m8xx_pcmcia.
+
config HD64465_PCMCIA
tristate "HD64465 host bridge support"
depends on HD64465 && PCMCIA
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index a41fbb38fdcb..fe37541abbfe 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_PD6729) += pd6729.o
obj-$(CONFIG_I82365) += i82365.o
obj-$(CONFIG_I82092) += i82092.o
obj-$(CONFIG_TCIC) += tcic.o
+obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o
obj-$(CONFIG_HD64465_PCMCIA) += hd64465_ss.o
obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_core.o sa1100_cs.o
obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_core.o sa1111_cs.o
@@ -42,9 +43,11 @@ pxa2xx_core-y += soc_common.o pxa2xx_base.o
au1x00_ss-y += au1000_generic.o
au1x00_ss-$(CONFIG_MIPS_PB1000) += au1000_pb1x00.o
au1x00_ss-$(CONFIG_MIPS_PB1100) += au1000_pb1x00.o
+au1x00_ss-$(CONFIG_MIPS_PB1200) += au1000_db1x00.o
au1x00_ss-$(CONFIG_MIPS_PB1500) += au1000_pb1x00.o
au1x00_ss-$(CONFIG_MIPS_DB1000) += au1000_db1x00.o
au1x00_ss-$(CONFIG_MIPS_DB1100) += au1000_db1x00.o
+au1x00_ss-$(CONFIG_MIPS_DB1200) += au1000_db1x00.o
au1x00_ss-$(CONFIG_MIPS_DB1500) += au1000_db1x00.o
au1x00_ss-$(CONFIG_MIPS_DB1550) += au1000_db1x00.o
au1x00_ss-$(CONFIG_MIPS_XXS1500) += au1000_xxs1500.o
@@ -57,6 +60,7 @@ sa1111_cs-$(CONFIG_SA1100_JORNADA720) += sa1100_jornada720.o
sa1100_cs-y += sa1100_generic.o
sa1100_cs-$(CONFIG_SA1100_ASSABET) += sa1100_assabet.o
sa1100_cs-$(CONFIG_SA1100_CERF) += sa1100_cerf.o
+sa1100_cs-$(CONFIG_SA1100_COLLIE) += pxa2xx_sharpsl.o
sa1100_cs-$(CONFIG_SA1100_H3600) += sa1100_h3600.o
sa1100_cs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o
sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o
diff --git a/drivers/pcmcia/au1000_db1x00.c b/drivers/pcmcia/au1000_db1x00.c
index 42cf8bfbcc98..24cfee1a412c 100644
--- a/drivers/pcmcia/au1000_db1x00.c
+++ b/drivers/pcmcia/au1000_db1x00.c
@@ -40,7 +40,15 @@
#include <asm/irq.h>
#include <asm/signal.h>
#include <asm/mach-au1x00/au1000.h>
-#include <asm/mach-db1x00/db1x00.h>
+
+#if defined(CONFIG_MIPS_DB1200)
+ #include <db1200.h>
+#elif defined(CONFIG_MIPS_PB1200)
+ #include <pb1200.h>
+#else
+ #include <asm/mach-db1x00/db1x00.h>
+ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+#endif
#include "au1000_generic.h"
@@ -50,7 +58,6 @@
#define debug(x,args...)
#endif
-static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
struct au1000_pcmcia_socket au1000_pcmcia_socket[PCMCIA_NUM_SOCKS];
extern int au1x00_pcmcia_socket_probe(struct device *, struct pcmcia_low_level *, int, int);
@@ -59,6 +66,8 @@ static int db1x00_pcmcia_hw_init(struct au1000_pcmcia_socket *skt)
{
#ifdef CONFIG_MIPS_DB1550
skt->irq = skt->nr ? AU1000_GPIO_5 : AU1000_GPIO_3;
+#elif defined(CONFIG_MIPS_DB1200) || defined(CONFIG_MIPS_PB1200)
+ skt->irq = skt->nr ? BOARD_PC1_INT : BOARD_PC0_INT;
#else
skt->irq = skt->nr ? AU1000_GPIO_5 : AU1000_GPIO_2;
#endif
@@ -85,11 +94,19 @@ db1x00_pcmcia_socket_state(struct au1000_pcmcia_socket *skt, struct pcmcia_state
switch (skt->nr) {
case 0:
vs = bcsr->status & 0x3;
+#if defined(CONFIG_MIPS_DB1200) || defined(CONFIG_MIPS_PB1200)
+ inserted = BOARD_CARD_INSERTED(0);
+#else
inserted = !(bcsr->status & (1<<4));
+#endif
break;
case 1:
vs = (bcsr->status & 0xC)>>2;
+#if defined(CONFIG_MIPS_DB1200) || defined(CONFIG_MIPS_PB1200)
+ inserted = BOARD_CARD_INSERTED(1);
+#else
inserted = !(bcsr->status & (1<<5));
+#endif
break;
default:/* should never happen */
return;
diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c
index f591839ab9cd..87302c548c24 100644
--- a/drivers/pcmcia/au1000_generic.c
+++ b/drivers/pcmcia/au1000_generic.c
@@ -490,7 +490,7 @@ int au1x00_drv_pcmcia_remove(struct device *dev)
flush_scheduled_work();
skt->ops->hw_shutdown(skt);
au1x00_pcmcia_config_skt(skt, &dead_socket);
- iounmap(skt->virt_io);
+ iounmap(skt->virt_io + (u32)mips_io_port_base);
skt->virt_io = NULL;
}
@@ -528,10 +528,6 @@ static struct device_driver au1x00_pcmcia_driver = {
.resume = pcmcia_socket_dev_resume,
};
-static struct platform_device au1x00_device = {
- .name = "au1x00-pcmcia",
- .id = 0,
-};
/* au1x00_pcmcia_init()
*
@@ -545,7 +541,6 @@ static int __init au1x00_pcmcia_init(void)
int error = 0;
if ((error = driver_register(&au1x00_pcmcia_driver)))
return error;
- platform_device_register(&au1x00_device);
return error;
}
@@ -556,7 +551,6 @@ static int __init au1x00_pcmcia_init(void)
static void __exit au1x00_pcmcia_exit(void)
{
driver_unregister(&au1x00_pcmcia_driver);
- platform_device_unregister(&au1x00_device);
}
module_init(au1x00_pcmcia_init);
diff --git a/drivers/pcmcia/au1000_generic.h b/drivers/pcmcia/au1000_generic.h
index d5122b1ea94b..b0e7908392a7 100644
--- a/drivers/pcmcia/au1000_generic.h
+++ b/drivers/pcmcia/au1000_generic.h
@@ -44,13 +44,13 @@
/* pcmcia socket 1 needs external glue logic so the memory map
* differs from board to board.
*/
-#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1550)
+#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1550) || defined(CONFIG_MIPS_PB1200)
#define AU1X_SOCK1_IO 0xF08000000
#define AU1X_SOCK1_PHYS_ATTR 0xF48000000
#define AU1X_SOCK1_PHYS_MEM 0xF88000000
#define AU1X_SOCK1_PSEUDO_PHYS_ATTR 0xF4800000
#define AU1X_SOCK1_PSEUDO_PHYS_MEM 0xF8800000
-#elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550)
+#elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550) || defined(CONFIG_MIPS_DB1200)
#define AU1X_SOCK1_IO 0xF04000000
#define AU1X_SOCK1_PHYS_ATTR 0xF44000000
#define AU1X_SOCK1_PHYS_MEM 0xF84000000
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c
new file mode 100644
index 000000000000..f8bed87cf2f1
--- /dev/null
+++ b/drivers/pcmcia/m8xx_pcmcia.c
@@ -0,0 +1,1290 @@
+/*
+ * m8xx_pcmcia.c - Linux PCMCIA socket driver for the mpc8xx series.
+ *
+ * (C) 1999-2000 Magnus Damm <damm@bitsmart.com>
+ * (C) 2001-2002 Montavista Software, Inc.
+ * <mlocke@mvista.com>
+ *
+ * Support for two slots by Cyclades Corporation
+ * <oliver.kurth@cyclades.de>
+ * Further fixes, v2.6 kernel port
+ * <marcelo.tosatti@cyclades.com>
+ *
+ * "The ExCA standard specifies that socket controllers should provide
+ * two IO and five memory windows per socket, which can be independently
+ * configured and positioned in the host address space and mapped to
+ * arbitrary segments of card address space. " - David A Hinds. 1999
+ *
+ * This controller does _not_ meet the ExCA standard.
+ *
+ * m8xx pcmcia controller brief info:
+ * + 8 windows (attrib, mem, i/o)
+ * + up to two slots (SLOT_A and SLOT_B)
+ * + inputpins, outputpins, event and mask registers.
+ * - no offset register. sigh.
+ *
+ * Because of the lacking offset register we must map the whole card.
+ * We assign each memory window PCMCIA_MEM_WIN_SIZE address space.
+ * Make sure there is (PCMCIA_MEM_WIN_SIZE * PCMCIA_MEM_WIN_NO
+ * * PCMCIA_SOCKETS_NO) bytes at PCMCIA_MEM_WIN_BASE.
+ * The i/o windows are dynamically allocated at PCMCIA_IO_WIN_BASE.
+ * They are maximum 64KByte each...
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/string.h>
+
+#include <asm/io.h>
+#include <asm/bitops.h>
+#include <asm/segment.h>
+#include <asm/system.h>
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/timer.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+
+#include <asm/mpc8xx.h>
+#include <asm/8xx_immap.h>
+#include <asm/irq.h>
+
+#include <pcmcia/version.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/ss.h>
+
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+module_param(pc_debug, int, 0);
+#define dprintk(args...) printk(KERN_DEBUG "m8xx_pcmcia: " args);
+#else
+#define dprintk(args...)
+#endif
+
+#define pcmcia_info(args...) printk(KERN_INFO "m8xx_pcmcia: "args)
+#define pcmcia_error(args...) printk(KERN_ERR "m8xx_pcmcia: "args)
+
+static const char *version = "Version 0.06, Aug 2005";
+MODULE_LICENSE("Dual MPL/GPL");
+
+#if !defined(CONFIG_PCMCIA_SLOT_A) && !defined(CONFIG_PCMCIA_SLOT_B)
+
+/* The RPX series use SLOT_B */
+#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
+#define CONFIG_PCMCIA_SLOT_B
+#define CONFIG_BD_IS_MHZ
+#endif
+
+/* The ADS board use SLOT_A */
+#ifdef CONFIG_ADS
+#define CONFIG_PCMCIA_SLOT_A
+#define CONFIG_BD_IS_MHZ
+#endif
+
+/* The FADS series are a mess */
+#ifdef CONFIG_FADS
+#if defined(CONFIG_MPC860T) || defined(CONFIG_MPC860) || defined(CONFIG_MPC821)
+#define CONFIG_PCMCIA_SLOT_A
+#else
+#define CONFIG_PCMCIA_SLOT_B
+#endif
+#endif
+
+/* Cyclades ACS uses both slots */
+#ifdef CONFIG_PRxK
+#define CONFIG_PCMCIA_SLOT_A
+#define CONFIG_PCMCIA_SLOT_B
+#endif
+
+#endif /* !defined(CONFIG_PCMCIA_SLOT_A) && !defined(CONFIG_PCMCIA_SLOT_B) */
+
+#if defined(CONFIG_PCMCIA_SLOT_A) && defined(CONFIG_PCMCIA_SLOT_B)
+
+#define PCMCIA_SOCKETS_NO 2
+/* We have only 8 windows, dualsocket support will be limited. */
+#define PCMCIA_MEM_WIN_NO 2
+#define PCMCIA_IO_WIN_NO 2
+#define PCMCIA_SLOT_MSG "SLOT_A and SLOT_B"
+
+#elif defined(CONFIG_PCMCIA_SLOT_A) || defined(CONFIG_PCMCIA_SLOT_B)
+
+#define PCMCIA_SOCKETS_NO 1
+/* full support for one slot */
+#define PCMCIA_MEM_WIN_NO 5
+#define PCMCIA_IO_WIN_NO 2
+
+/* define _slot_ to be able to optimize macros */
+
+#ifdef CONFIG_PCMCIA_SLOT_A
+#define _slot_ 0
+#define PCMCIA_SLOT_MSG "SLOT_A"
+#else
+#define _slot_ 1
+#define PCMCIA_SLOT_MSG "SLOT_B"
+#endif
+
+#else
+#error m8xx_pcmcia: Bad configuration!
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+#define PCMCIA_MEM_WIN_BASE 0xe0000000 /* base address for memory window 0 */
+#define PCMCIA_MEM_WIN_SIZE 0x04000000 /* each memory window is 64 MByte */
+#define PCMCIA_IO_WIN_BASE _IO_BASE /* base address for io window 0 */
+
+#define PCMCIA_SCHLVL PCMCIA_INTERRUPT /* Status Change Interrupt Level */
+
+/* ------------------------------------------------------------------------- */
+
+/* 2.4.x and newer has this always in HZ */
+#define M8XX_BUSFREQ ((((bd_t *)&(__res))->bi_busfreq))
+
+static int pcmcia_schlvl = PCMCIA_SCHLVL;
+
+static spinlock_t events_lock = SPIN_LOCK_UNLOCKED;
+
+
+#define PCMCIA_SOCKET_KEY_5V 1
+#define PCMCIA_SOCKET_KEY_LV 2
+
+/* look up table for pgcrx registers */
+static u32 *m8xx_pgcrx[2] = {
+ &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pgcra,
+ &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pgcrb
+};
+
+/*
+ * This structure is used to address each window in the PCMCIA controller.
+ *
+ * Keep in mind that we assume that pcmcia_win[n+1] is mapped directly
+ * after pcmcia_win[n]...
+ */
+
+struct pcmcia_win {
+ u32 br;
+ u32 or;
+};
+
+/*
+ * For some reason the hardware guys decided to make both slots share
+ * some registers.
+ *
+ * Could someone invent object oriented hardware ?
+ *
+ * The macros are used to get the right bit from the registers.
+ * SLOT_A : slot = 0
+ * SLOT_B : slot = 1
+ */
+
+#define M8XX_PCMCIA_VS1(slot) (0x80000000 >> (slot << 4))
+#define M8XX_PCMCIA_VS2(slot) (0x40000000 >> (slot << 4))
+#define M8XX_PCMCIA_VS_MASK(slot) (0xc0000000 >> (slot << 4))
+#define M8XX_PCMCIA_VS_SHIFT(slot) (30 - (slot << 4))
+
+#define M8XX_PCMCIA_WP(slot) (0x20000000 >> (slot << 4))
+#define M8XX_PCMCIA_CD2(slot) (0x10000000 >> (slot << 4))
+#define M8XX_PCMCIA_CD1(slot) (0x08000000 >> (slot << 4))
+#define M8XX_PCMCIA_BVD2(slot) (0x04000000 >> (slot << 4))
+#define M8XX_PCMCIA_BVD1(slot) (0x02000000 >> (slot << 4))
+#define M8XX_PCMCIA_RDY(slot) (0x01000000 >> (slot << 4))
+#define M8XX_PCMCIA_RDY_L(slot) (0x00800000 >> (slot << 4))
+#define M8XX_PCMCIA_RDY_H(slot) (0x00400000 >> (slot << 4))
+#define M8XX_PCMCIA_RDY_R(slot) (0x00200000 >> (slot << 4))
+#define M8XX_PCMCIA_RDY_F(slot) (0x00100000 >> (slot << 4))
+#define M8XX_PCMCIA_MASK(slot) (0xFFFF0000 >> (slot << 4))
+
+#define M8XX_PCMCIA_POR_VALID 0x00000001
+#define M8XX_PCMCIA_POR_WRPROT 0x00000002
+#define M8XX_PCMCIA_POR_ATTRMEM 0x00000010
+#define M8XX_PCMCIA_POR_IO 0x00000018
+#define M8XX_PCMCIA_POR_16BIT 0x00000040
+
+#define M8XX_PGCRX(slot) m8xx_pgcrx[slot]
+
+#define M8XX_PGCRX_CXOE 0x00000080
+#define M8XX_PGCRX_CXRESET 0x00000040
+
+/* we keep one lookup table per socket to check flags */
+
+#define PCMCIA_EVENTS_MAX 5 /* 4 max at a time + termination */
+
+struct event_table {
+ u32 regbit;
+ u32 eventbit;
+};
+
+struct socket_info {
+ void (*handler)(void *info, u32 events);
+ void *info;
+
+ u32 slot;
+
+ socket_state_t state;
+ struct pccard_mem_map mem_win[PCMCIA_MEM_WIN_NO];
+ struct pccard_io_map io_win[PCMCIA_IO_WIN_NO];
+ struct event_table events[PCMCIA_EVENTS_MAX];
+ struct pcmcia_socket socket;
+};
+
+static struct socket_info socket[PCMCIA_SOCKETS_NO];
+
+/*
+ * Search this table to see if the windowsize is
+ * supported...
+ */
+
+#define M8XX_SIZES_NO 32
+
+static const u32 m8xx_size_to_gray[M8XX_SIZES_NO] =
+{
+ 0x00000001, 0x00000002, 0x00000008, 0x00000004,
+ 0x00000080, 0x00000040, 0x00000010, 0x00000020,
+ 0x00008000, 0x00004000, 0x00001000, 0x00002000,
+ 0x00000100, 0x00000200, 0x00000800, 0x00000400,
+
+ 0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x01000000, 0x02000000, 0xffffffff, 0x04000000,
+ 0x00010000, 0x00020000, 0x00080000, 0x00040000,
+ 0x00800000, 0x00400000, 0x00100000, 0x00200000
+};
+
+/* ------------------------------------------------------------------------- */
+
+static irqreturn_t m8xx_interrupt(int irq, void *dev, struct pt_regs *regs);
+
+#define PCMCIA_BMT_LIMIT (15*4) /* Bus Monitor Timeout value */
+
+/* ------------------------------------------------------------------------- */
+/* board specific stuff: */
+/* voltage_set(), hardware_enable() and hardware_disable() */
+/* ------------------------------------------------------------------------- */
+/* RPX Boards from Embedded Planet */
+
+#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
+
+/* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
+ * SYPCR is write once only, therefore must the slowest memory be faster
+ * than the bus monitor or we will get a machine check due to the bus timeout.
+ */
+
+#define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE"
+
+#undef PCMCIA_BMT_LIMIT
+#define PCMCIA_BMT_LIMIT (6*8)
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+ u32 reg = 0;
+
+ switch(vcc) {
+ case 0: break;
+ case 33:
+ reg |= BCSR1_PCVCTL4;
+ break;
+ case 50:
+ reg |= BCSR1_PCVCTL5;
+ break;
+ default:
+ return 1;
+ }
+
+ switch(vpp) {
+ case 0: break;
+ case 33:
+ case 50:
+ if(vcc == vpp)
+ reg |= BCSR1_PCVCTL6;
+ else
+ return 1;
+ break;
+ case 120:
+ reg |= BCSR1_PCVCTL7;
+ default:
+ return 1;
+ }
+
+ if(!((vcc == 50) || (vcc == 0)))
+ return 1;
+
+ /* first, turn off all power */
+
+ out_be32(((u32 *)RPX_CSR_ADDR), in_be32(((u32 *)RPX_CSR_ADDR)) & ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5 | BCSR1_PCVCTL6 | BCSR1_PCVCTL7));
+
+ /* enable new powersettings */
+
+ out_be32(((u32 *)RPX_CSR_ADDR), in_be32(((u32 *)RPX_CSR_ADDR)) | reg);
+
+ return 0;
+}
+
+#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
+#define hardware_enable(_slot_) /* No hardware to enable */
+#define hardware_disable(_slot_) /* No hardware to disable */
+
+#endif /* CONFIG_RPXCLASSIC */
+
+/* FADS Boards from Motorola */
+
+#if defined(CONFIG_FADS)
+
+#define PCMCIA_BOARD_MSG "FADS"
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+ u32 reg = 0;
+
+ switch(vcc) {
+ case 0:
+ break;
+ case 33:
+ reg |= BCSR1_PCCVCC0;
+ break;
+ case 50:
+ reg |= BCSR1_PCCVCC1;
+ break;
+ default:
+ return 1;
+ }
+
+ switch(vpp) {
+ case 0:
+ break;
+ case 33:
+ case 50:
+ if(vcc == vpp)
+ reg |= BCSR1_PCCVPP1;
+ else
+ return 1;
+ break;
+ case 120:
+ if ((vcc == 33) || (vcc == 50))
+ reg |= BCSR1_PCCVPP0;
+ else
+ return 1;
+ default:
+ return 1;
+ }
+
+ /* first, turn off all power */
+ out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) & ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK));
+
+ /* enable new powersettings */
+ out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) | reg);
+
+ return 0;
+}
+
+#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
+
+static void hardware_enable(int slot)
+{
+ out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) & ~BCSR1_PCCEN);
+}
+
+static void hardware_disable(int slot)
+{
+ out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) | BCSR1_PCCEN);
+}
+
+#endif
+
+/* ------------------------------------------------------------------------- */
+/* Motorola MBX860 */
+
+#if defined(CONFIG_MBX)
+
+#define PCMCIA_BOARD_MSG "MBX"
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+ u8 reg = 0;
+
+ switch(vcc) {
+ case 0:
+ break;
+ case 33:
+ reg |= CSR2_VCC_33;
+ break;
+ case 50:
+ reg |= CSR2_VCC_50;
+ break;
+ default:
+ return 1;
+ }
+
+ switch(vpp) {
+ case 0:
+ break;
+ case 33:
+ case 50:
+ if(vcc == vpp)
+ reg |= CSR2_VPP_VCC;
+ else
+ return 1;
+ break;
+ case 120:
+ if ((vcc == 33) || (vcc == 50))
+ reg |= CSR2_VPP_12;
+ else
+ return 1;
+ default:
+ return 1;
+ }
+
+ /* first, turn off all power */
+ out_8(&((u8 *)MBX_CSR2_ADDR), in_8(&((u8 *)MBX_CSR2_ADDR)) & ~(CSR2_VCC_MASK | CSR2_VPP_MASK));
+
+ /* enable new powersettings */
+ out_8(&((u8 *)MBX_CSR2_ADDR), in_8(&((u8 *)MBX_CSR2_ADDR)) | reg);
+
+ return 0;
+}
+
+#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
+#define hardware_enable(_slot_) /* No hardware to enable */
+#define hardware_disable(_slot_) /* No hardware to disable */
+
+#endif /* CONFIG_MBX */
+
+#if defined(CONFIG_PRxK)
+#include <asm/cpld.h>
+extern volatile fpga_pc_regs *fpga_pc;
+
+#define PCMCIA_BOARD_MSG "MPC855T"
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+ u8 reg = 0;
+ u8 regread;
+ cpld_regs *ccpld = get_cpld();
+
+ switch(vcc) {
+ case 0:
+ break;
+ case 33:
+ reg |= PCMCIA_VCC_33;
+ break;
+ case 50:
+ reg |= PCMCIA_VCC_50;
+ break;
+ default:
+ return 1;
+ }
+
+ switch(vpp) {
+ case 0:
+ break;
+ case 33:
+ case 50:
+ if(vcc == vpp)
+ reg |= PCMCIA_VPP_VCC;
+ else
+ return 1;
+ break;
+ case 120:
+ if ((vcc == 33) || (vcc == 50))
+ reg |= PCMCIA_VPP_12;
+ else
+ return 1;
+ default:
+ return 1;
+ }
+
+ reg = reg >> (slot << 2);
+ regread = in_8(&ccpld->fpga_pc_ctl);
+ if (reg != (regread & ((PCMCIA_VCC_MASK | PCMCIA_VPP_MASK) >> (slot << 2)))) {
+ /* enable new powersettings */
+ regread = regread & ~((PCMCIA_VCC_MASK | PCMCIA_VPP_MASK) >> (slot << 2));
+ out_8(&ccpld->fpga_pc_ctl, reg | regread);
+ msleep(100);
+ }
+
+ return 0;
+}
+
+#define socket_get(_slot_) PCMCIA_SOCKET_KEY_LV
+#define hardware_enable(_slot_) /* No hardware to enable */
+#define hardware_disable(_slot_) /* No hardware to disable */
+
+#endif /* CONFIG_PRxK */
+
+static void m8xx_shutdown(void)
+{
+ u32 m, i;
+ struct pcmcia_win *w;
+
+ for(i = 0; i < PCMCIA_SOCKETS_NO; i++){
+ w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
+
+ out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr, M8XX_PCMCIA_MASK(i));
+ out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per, in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per) & ~M8XX_PCMCIA_MASK(i));
+
+ /* turn off interrupt and disable CxOE */
+ out_be32(M8XX_PGCRX(i), M8XX_PGCRX_CXOE);
+
+ /* turn off memory windows */
+ for(m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
+ out_be32(&w->or, 0); /* set to not valid */
+ w++;
+ }
+
+ /* turn off voltage */
+ voltage_set(i, 0, 0);
+
+ /* disable external hardware */
+ hardware_disable(i);
+ }
+
+ free_irq(pcmcia_schlvl, NULL);
+}
+
+/* copied from tcic.c */
+
+static int m8xx_drv_suspend(struct device *dev, pm_message_t state, u32 level)
+{
+ int ret = 0;
+ if (level == SUSPEND_SAVE_STATE)
+ ret = pcmcia_socket_dev_suspend(dev, state);
+ return ret;
+}
+
+static int m8xx_drv_resume(struct device *dev, u32 level)
+{
+ int ret = 0;
+ if (level == RESUME_RESTORE_STATE)
+ ret = pcmcia_socket_dev_resume(dev);
+ return ret;
+}
+
+static struct device_driver m8xx_driver = {
+ .name = "m8xx-pcmcia",
+ .bus = &platform_bus_type,
+ .suspend = m8xx_drv_suspend,
+ .resume = m8xx_drv_resume,
+};
+
+static struct platform_device m8xx_device = {
+ .name = "m8xx-pcmcia",
+ .id = 0,
+};
+
+static u32 pending_events[PCMCIA_SOCKETS_NO];
+static spinlock_t pending_event_lock = SPIN_LOCK_UNLOCKED;
+
+static irqreturn_t m8xx_interrupt(int irq, void *dev, struct pt_regs *regs)
+{
+ struct socket_info *s;
+ struct event_table *e;
+ unsigned int i, events, pscr, pipr, per;
+
+ dprintk("Interrupt!\n");
+ /* get interrupt sources */
+
+ pscr = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr);
+ pipr = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr);
+ per = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per);
+
+ for(i = 0; i < PCMCIA_SOCKETS_NO; i++) {
+ s = &socket[i];
+ e = &s->events[0];
+ events = 0;
+
+ while(e->regbit) {
+ if(pscr & e->regbit)
+ events |= e->eventbit;
+
+ e++;
+ }
+
+ /*
+ * report only if both card detect signals are the same
+ * not too nice done,
+ * we depend on that CD2 is the bit to the left of CD1...
+ */
+ if(events & SS_DETECT)
+ if(((pipr & M8XX_PCMCIA_CD2(i)) >> 1) ^
+ (pipr & M8XX_PCMCIA_CD1(i)))
+ {
+ events &= ~SS_DETECT;
+ }
+
+#ifdef PCMCIA_GLITCHY_CD
+ /*
+ * I've experienced CD problems with my ADS board.
+ * We make an extra check to see if there was a
+ * real change of Card detection.
+ */
+
+ if((events & SS_DETECT) &&
+ ((pipr &
+ (M8XX_PCMCIA_CD2(i) | M8XX_PCMCIA_CD1(i))) == 0) &&
+ (s->state.Vcc | s->state.Vpp)) {
+ events &= ~SS_DETECT;
+ /*printk( "CD glitch workaround - CD = 0x%08x!\n",
+ (pipr & (M8XX_PCMCIA_CD2(i)
+ | M8XX_PCMCIA_CD1(i))));*/
+ }
+#endif
+
+ /* call the handler */
+
+ dprintk("slot %u: events = 0x%02x, pscr = 0x%08x, "
+ "pipr = 0x%08x\n",
+ i, events, pscr, pipr);
+
+ if(events) {
+ spin_lock(&pending_event_lock);
+ pending_events[i] |= events;
+ spin_unlock(&pending_event_lock);
+ /*
+ * Turn off RDY_L bits in the PER mask on
+ * CD interrupt receival.
+ *
+ * They can generate bad interrupts on the
+ * ACS4,8,16,32. - marcelo
+ */
+ per &= ~M8XX_PCMCIA_RDY_L(0);
+ per &= ~M8XX_PCMCIA_RDY_L(1);
+
+ out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per, per);
+
+ if (events)
+ pcmcia_parse_events(&socket[i].socket, events);
+ }
+ }
+
+ /* clear the interrupt sources */
+ out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr, pscr);
+
+ dprintk("Interrupt done.\n");
+
+ return IRQ_HANDLED;
+}
+
+static u32 m8xx_get_graycode(u32 size)
+{
+ u32 k;
+
+ for(k = 0; k < M8XX_SIZES_NO; k++)
+ if(m8xx_size_to_gray[k] == size)
+ break;
+
+ if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
+ k = -1;
+
+ return k;
+}
+
+static u32 m8xx_get_speed(u32 ns, u32 is_io)
+{
+ u32 reg, clocks, psst, psl, psht;
+
+ if(!ns) {
+
+ /*
+ * We get called with IO maps setup to 0ns
+ * if not specified by the user.
+ * They should be 255ns.
+ */
+
+ if(is_io)
+ ns = 255;
+ else
+ ns = 100; /* fast memory if 0 */
+ }
+
+ /*
+ * In PSST, PSL, PSHT fields we tell the controller
+ * timing parameters in CLKOUT clock cycles.
+ * CLKOUT is the same as GCLK2_50.
+ */
+
+/* how we want to adjust the timing - in percent */
+
+#define ADJ 180 /* 80 % longer accesstime - to be sure */
+
+ clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
+ clocks = (clocks * ADJ) / (100*1000);
+ if(clocks >= PCMCIA_BMT_LIMIT) {
+ printk( "Max access time limit reached\n");
+ clocks = PCMCIA_BMT_LIMIT-1;
+ }
+
+ psst = clocks / 7; /* setup time */
+ psht = clocks / 7; /* hold time */
+ psl = (clocks * 5) / 7; /* strobe length */
+
+ psst += clocks - (psst + psht + psl);
+
+ reg = psst << 12;
+ reg |= psl << 7;
+ reg |= psht << 16;
+
+ return reg;
+}
+
+static int m8xx_get_status(struct pcmcia_socket *sock, unsigned int *value)
+{
+ int lsock = container_of(sock, struct socket_info, socket)->slot;
+ struct socket_info *s = &socket[lsock];
+ unsigned int pipr, reg;
+
+ pipr = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr);
+
+ *value = ((pipr & (M8XX_PCMCIA_CD1(lsock)
+ | M8XX_PCMCIA_CD2(lsock))) == 0) ? SS_DETECT : 0;
+ *value |= (pipr & M8XX_PCMCIA_WP(lsock)) ? SS_WRPROT : 0;
+
+ if (s->state.flags & SS_IOCARD)
+ *value |= (pipr & M8XX_PCMCIA_BVD1(lsock)) ? SS_STSCHG : 0;
+ else {
+ *value |= (pipr & M8XX_PCMCIA_RDY(lsock)) ? SS_READY : 0;
+ *value |= (pipr & M8XX_PCMCIA_BVD1(lsock)) ? SS_BATDEAD : 0;
+ *value |= (pipr & M8XX_PCMCIA_BVD2(lsock)) ? SS_BATWARN : 0;
+ }
+
+ if (s->state.Vcc | s->state.Vpp)
+ *value |= SS_POWERON;
+
+ /*
+ * Voltage detection:
+ * This driver only supports 16-Bit pc-cards.
+ * Cardbus is not handled here.
+ *
+ * To determine what voltage to use we must read the VS1 and VS2 pin.
+ * Depending on what socket type is present,
+ * different combinations mean different things.
+ *
+ * Card Key Socket Key VS1 VS2 Card Vcc for CIS parse
+ *
+ * 5V 5V, LV* NC NC 5V only 5V (if available)
+ *
+ * 5V 5V, LV* GND NC 5 or 3.3V as low as possible
+ *
+ * 5V 5V, LV* GND GND 5, 3.3, x.xV as low as possible
+ *
+ * LV* 5V - - shall not fit into socket
+ *
+ * LV* LV* GND NC 3.3V only 3.3V
+ *
+ * LV* LV* NC GND x.xV x.xV (if avail.)
+ *
+ * LV* LV* GND GND 3.3 or x.xV as low as possible
+ *
+ * *LV means Low Voltage
+ *
+ *
+ * That gives us the following table:
+ *
+ * Socket VS1 VS2 Voltage
+ *
+ * 5V NC NC 5V
+ * 5V NC GND none (should not be possible)
+ * 5V GND NC >= 3.3V
+ * 5V GND GND >= x.xV
+ *
+ * LV NC NC 5V (if available)
+ * LV NC GND x.xV (if available)
+ * LV GND NC 3.3V
+ * LV GND GND >= x.xV
+ *
+ * So, how do I determine if I have a 5V or a LV
+ * socket on my board? Look at the socket!
+ *
+ *
+ * Socket with 5V key:
+ * ++--------------------------------------------+
+ * || |
+ * || ||
+ * || ||
+ * | |
+ * +---------------------------------------------+
+ *
+ * Socket with LV key:
+ * ++--------------------------------------------+
+ * || |
+ * | ||
+ * | ||
+ * | |
+ * +---------------------------------------------+
+ *
+ *
+ * With other words - LV only cards does not fit
+ * into the 5V socket!
+ */
+
+ /* read out VS1 and VS2 */
+
+ reg = (pipr & M8XX_PCMCIA_VS_MASK(lsock))
+ >> M8XX_PCMCIA_VS_SHIFT(lsock);
+
+ if(socket_get(lsock) == PCMCIA_SOCKET_KEY_LV) {
+ switch(reg) {
+ case 1:
+ *value |= SS_3VCARD;
+ break; /* GND, NC - 3.3V only */
+ case 2:
+ *value |= SS_XVCARD;
+ break; /* NC. GND - x.xV only */
+ };
+ }
+
+ dprintk("GetStatus(%d) = %#2.2x\n", lsock, *value);
+ return 0;
+}
+
+static int m8xx_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
+{
+ int lsock = container_of(sock, struct socket_info, socket)->slot;
+ *state = socket[lsock].state; /* copy the whole structure */
+
+ dprintk("GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
+ "io_irq %d, csc_mask %#2.2x\n", lsock, state->flags,
+ state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
+ return 0;
+}
+
+static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
+{
+ int lsock = container_of(sock, struct socket_info, socket)->slot;
+ struct socket_info *s = &socket[lsock];
+ struct event_table *e;
+ unsigned int reg;
+ unsigned long flags;
+
+ dprintk( "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
+ "io_irq %d, csc_mask %#2.2x)\n", lsock, state->flags,
+ state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
+
+ /* First, set voltage - bail out if invalid */
+ if(voltage_set(lsock, state->Vcc, state->Vpp))
+ return -EINVAL;
+
+ /* Take care of reset... */
+ if(state->flags & SS_RESET)
+ out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) | M8XX_PGCRX_CXRESET); /* active high */
+ else
+ out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) & ~M8XX_PGCRX_CXRESET);
+
+ /* ... and output enable. */
+
+ /* The CxOE signal is connected to a 74541 on the ADS.
+ I guess most other boards used the ADS as a reference.
+ I tried to control the CxOE signal with SS_OUTPUT_ENA,
+ but the reset signal seems connected via the 541.
+ If the CxOE is left high are some signals tristated and
+ no pullups are present -> the cards act wierd.
+ So right now the buffers are enabled if the power is on. */
+
+ if(state->Vcc || state->Vpp)
+ out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) & ~M8XX_PGCRX_CXOE); /* active low */
+ else
+ out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) | M8XX_PGCRX_CXOE);
+
+ /*
+ * We'd better turn off interrupts before
+ * we mess with the events-table..
+ */
+
+ spin_lock_irqsave(&events_lock, flags);
+
+ /*
+ * Play around with the interrupt mask to be able to
+ * give the events the generic pcmcia driver wants us to.
+ */
+
+ e = &s->events[0];
+ reg = 0;
+
+ if(state->csc_mask & SS_DETECT) {
+ e->eventbit = SS_DETECT;
+ reg |= e->regbit = (M8XX_PCMCIA_CD2(lsock)
+ | M8XX_PCMCIA_CD1(lsock));
+ e++;
+ }
+ if(state->flags & SS_IOCARD) {
+ /*
+ * I/O card
+ */
+ if(state->csc_mask & SS_STSCHG) {
+ e->eventbit = SS_STSCHG;
+ reg |= e->regbit = M8XX_PCMCIA_BVD1(lsock);
+ e++;
+ }
+ /*
+ * If io_irq is non-zero we should enable irq.
+ */
+ if(state->io_irq) {
+ out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) | mk_int_int_mask(state->io_irq) << 24);
+ /*
+ * Strange thing here:
+ * The manual does not tell us which interrupt
+ * the sources generate.
+ * Anyhow, I found out that RDY_L generates IREQLVL.
+ *
+ * We use level triggerd interrupts, and they don't
+ * have to be cleared in PSCR in the interrupt handler.
+ */
+ reg |= M8XX_PCMCIA_RDY_L(lsock);
+ }
+ else
+ out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) & 0x00ffffff);
+ }
+ else {
+ /*
+ * Memory card
+ */
+ if(state->csc_mask & SS_BATDEAD) {
+ e->eventbit = SS_BATDEAD;
+ reg |= e->regbit = M8XX_PCMCIA_BVD1(lsock);
+ e++;
+ }
+ if(state->csc_mask & SS_BATWARN) {
+ e->eventbit = SS_BATWARN;
+ reg |= e->regbit = M8XX_PCMCIA_BVD2(lsock);
+ e++;
+ }
+ /* What should I trigger on - low/high,raise,fall? */
+ if(state->csc_mask & SS_READY) {
+ e->eventbit = SS_READY;
+ reg |= e->regbit = 0; //??
+ e++;
+ }
+ }
+
+ e->regbit = 0; /* terminate list */
+
+ /*
+ * Clear the status changed .
+ * Port A and Port B share the same port.
+ * Writing ones will clear the bits.
+ */
+
+ out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr, reg);
+
+ /*
+ * Write the mask.
+ * Port A and Port B share the same port.
+ * Need for read-modify-write.
+ * Ones will enable the interrupt.
+ */
+
+ /*
+ reg |= ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per
+ & M8XX_PCMCIA_MASK(lsock);
+ */
+
+ reg |= in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per) &
+ (M8XX_PCMCIA_MASK(0) | M8XX_PCMCIA_MASK(1));
+
+ out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per, reg);
+
+ spin_unlock_irqrestore(&events_lock, flags);
+
+ /* copy the struct and modify the copy */
+
+ s->state = *state;
+
+ return 0;
+}
+
+static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
+{
+ int lsock = container_of(sock, struct socket_info, socket)->slot;
+
+ struct socket_info *s = &socket[lsock];
+ struct pcmcia_win *w;
+ unsigned int reg, winnr;
+
+#define M8XX_SIZE (io->stop - io->start + 1)
+#define M8XX_BASE (PCMCIA_IO_WIN_BASE + io->start)
+
+ dprintk( "SetIOMap(%d, %d, %#2.2x, %d ns, "
+ "%#4.4x-%#4.4x)\n", lsock, io->map, io->flags,
+ io->speed, io->start, io->stop);
+
+ if ((io->map >= PCMCIA_IO_WIN_NO) || (io->start > 0xffff)
+ || (io->stop > 0xffff) || (io->stop < io->start))
+ return -EINVAL;
+
+ if((reg = m8xx_get_graycode(M8XX_SIZE)) == -1)
+ return -EINVAL;
+
+ if(io->flags & MAP_ACTIVE) {
+
+ dprintk( "io->flags & MAP_ACTIVE\n");
+
+ winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO)
+ + (lsock * PCMCIA_IO_WIN_NO) + io->map;
+
+ /* setup registers */
+
+ w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
+ w += winnr;
+
+ out_be32(&w->or, 0); /* turn off window first */
+ out_be32(&w->br, M8XX_BASE);
+
+ reg <<= 27;
+ reg |= M8XX_PCMCIA_POR_IO |(lsock << 2);
+
+ reg |= m8xx_get_speed(io->speed, 1);
+
+ if(io->flags & MAP_WRPROT)
+ reg |= M8XX_PCMCIA_POR_WRPROT;
+
+ /*if(io->flags & (MAP_16BIT | MAP_AUTOSZ))*/
+ if(io->flags & MAP_16BIT)
+ reg |= M8XX_PCMCIA_POR_16BIT;
+
+ if(io->flags & MAP_ACTIVE)
+ reg |= M8XX_PCMCIA_POR_VALID;
+
+ out_be32(&w->or, reg);
+
+ dprintk("Socket %u: Mapped io window %u at %#8.8x, "
+ "OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
+ } else {
+ /* shutdown IO window */
+ winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO)
+ + (lsock * PCMCIA_IO_WIN_NO) + io->map;
+
+ /* setup registers */
+
+ w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
+ w += winnr;
+
+ out_be32(&w->or, 0); /* turn off window */
+ out_be32(&w->br, 0); /* turn off base address */
+
+ dprintk("Socket %u: Unmapped io window %u at %#8.8x, "
+ "OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
+ }
+
+ /* copy the struct and modify the copy */
+ s->io_win[io->map] = *io;
+ s->io_win[io->map].flags &= (MAP_WRPROT
+ | MAP_16BIT
+ | MAP_ACTIVE);
+ dprintk("SetIOMap exit\n");
+
+ return 0;
+}
+
+static int m8xx_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem)
+{
+ int lsock = container_of(sock, struct socket_info, socket)->slot;
+ struct socket_info *s = &socket[lsock];
+ struct pcmcia_win *w;
+ struct pccard_mem_map *old;
+ unsigned int reg, winnr;
+
+ dprintk( "SetMemMap(%d, %d, %#2.2x, %d ns, "
+ "%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
+ mem->speed, mem->static_start, mem->card_start);
+
+ if ((mem->map >= PCMCIA_MEM_WIN_NO)
+// || ((mem->s) >= PCMCIA_MEM_WIN_SIZE)
+ || (mem->card_start >= 0x04000000)
+ || (mem->static_start & 0xfff) /* 4KByte resolution */
+ || (mem->card_start & 0xfff))
+ return -EINVAL;
+
+ if((reg = m8xx_get_graycode(PCMCIA_MEM_WIN_SIZE)) == -1) {
+ printk( "Cannot set size to 0x%08x.\n", PCMCIA_MEM_WIN_SIZE);
+ return -EINVAL;
+ }
+ reg <<= 27;
+
+ winnr = (lsock * PCMCIA_MEM_WIN_NO) + mem->map;
+
+ /* Setup the window in the pcmcia controller */
+
+ w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
+ w += winnr;
+
+ reg |= lsock << 2;
+
+ reg |= m8xx_get_speed(mem->speed, 0);
+
+ if(mem->flags & MAP_ATTRIB)
+ reg |= M8XX_PCMCIA_POR_ATTRMEM;
+
+ if(mem->flags & MAP_WRPROT)
+ reg |= M8XX_PCMCIA_POR_WRPROT;
+
+ if(mem->flags & MAP_16BIT)
+ reg |= M8XX_PCMCIA_POR_16BIT;
+
+ if(mem->flags & MAP_ACTIVE)
+ reg |= M8XX_PCMCIA_POR_VALID;
+
+ out_be32(&w->or, reg);
+
+ dprintk("Socket %u: Mapped memory window %u at %#8.8x, "
+ "OR = %#8.8x.\n", lsock, mem->map, w->br, w->or);
+
+ if(mem->flags & MAP_ACTIVE) {
+ /* get the new base address */
+ mem->static_start = PCMCIA_MEM_WIN_BASE +
+ (PCMCIA_MEM_WIN_SIZE * winnr)
+ + mem->card_start;
+ }
+
+ dprintk("SetMemMap(%d, %d, %#2.2x, %d ns, "
+ "%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
+ mem->speed, mem->static_start, mem->card_start);
+
+ /* copy the struct and modify the copy */
+
+ old = &s->mem_win[mem->map];
+
+ *old = *mem;
+ old->flags &= (MAP_ATTRIB
+ | MAP_WRPROT
+ | MAP_16BIT
+ | MAP_ACTIVE);
+
+ return 0;
+}
+
+static int m8xx_sock_init(struct pcmcia_socket *sock)
+{
+ int i;
+ pccard_io_map io = { 0, 0, 0, 0, 1 };
+ pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
+
+ dprintk( "sock_init(%d)\n", s);
+
+ m8xx_set_socket(sock, &dead_socket);
+ for (i = 0; i < PCMCIA_IO_WIN_NO; i++) {
+ io.map = i;
+ m8xx_set_io_map(sock, &io);
+ }
+ for (i = 0; i < PCMCIA_MEM_WIN_NO; i++) {
+ mem.map = i;
+ m8xx_set_mem_map(sock, &mem);
+ }
+
+ return 0;
+
+}
+
+static int m8xx_suspend(struct pcmcia_socket *sock)
+{
+ return m8xx_set_socket(sock, &dead_socket);
+}
+
+static struct pccard_operations m8xx_services = {
+ .init = m8xx_sock_init,
+ .suspend = m8xx_suspend,
+ .get_status = m8xx_get_status,
+ .get_socket = m8xx_get_socket,
+ .set_socket = m8xx_set_socket,
+ .set_io_map = m8xx_set_io_map,
+ .set_mem_map = m8xx_set_mem_map,
+};
+
+static int __init m8xx_init(void)
+{
+ struct pcmcia_win *w;
+ unsigned int i,m;
+
+ pcmcia_info("%s\n", version);
+
+ if (driver_register(&m8xx_driver))
+ return -1;
+
+ pcmcia_info(PCMCIA_BOARD_MSG " using " PCMCIA_SLOT_MSG
+ " with IRQ %u.\n", pcmcia_schlvl);
+
+ /* Configure Status change interrupt */
+
+ if(request_irq(pcmcia_schlvl, m8xx_interrupt, 0,
+ "m8xx_pcmcia", NULL)) {
+ pcmcia_error("Cannot allocate IRQ %u for SCHLVL!\n",
+ pcmcia_schlvl);
+ return -1;
+ }
+
+ w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
+
+ out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr,
+ M8XX_PCMCIA_MASK(0)| M8XX_PCMCIA_MASK(1));
+
+ out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per,
+ in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per) &
+ ~(M8XX_PCMCIA_MASK(0)| M8XX_PCMCIA_MASK(1)));
+
+/* connect interrupt and disable CxOE */
+
+ out_be32(M8XX_PGCRX(0), M8XX_PGCRX_CXOE | (mk_int_int_mask(pcmcia_schlvl) << 16));
+ out_be32(M8XX_PGCRX(1), M8XX_PGCRX_CXOE | (mk_int_int_mask(pcmcia_schlvl) << 16));
+
+/* intialize the fixed memory windows */
+
+ for(i = 0; i < PCMCIA_SOCKETS_NO; i++){
+ for(m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
+ out_be32(&w->br, PCMCIA_MEM_WIN_BASE +
+ (PCMCIA_MEM_WIN_SIZE
+ * (m + i * PCMCIA_MEM_WIN_NO)));
+
+ out_be32(&w->or, 0); /* set to not valid */
+
+ w++;
+ }
+ }
+
+/* turn off voltage */
+ voltage_set(0, 0, 0);
+ voltage_set(1, 0, 0);
+
+/* Enable external hardware */
+ hardware_enable(0);
+ hardware_enable(1);
+
+ platform_device_register(&m8xx_device);
+
+ for (i = 0 ; i < PCMCIA_SOCKETS_NO; i++) {
+ socket[i].slot = i;
+ socket[i].socket.owner = THIS_MODULE;
+ socket[i].socket.features = SS_CAP_PCCARD | SS_CAP_MEM_ALIGN | SS_CAP_STATIC_MAP;
+ socket[i].socket.irq_mask = 0x000;
+ socket[i].socket.map_size = 0x1000;
+ socket[i].socket.io_offset = 0;
+ socket[i].socket.pci_irq = i ? 7 : 9;
+ socket[i].socket.ops = &m8xx_services;
+ socket[i].socket.resource_ops = &pccard_nonstatic_ops;
+ socket[i].socket.cb_dev = NULL;
+ socket[i].socket.dev.dev = &m8xx_device.dev;
+ }
+
+ for (i = 0; i < PCMCIA_SOCKETS_NO; i++)
+ pcmcia_register_socket(&socket[i].socket);
+
+ return 0;
+}
+
+static void __exit m8xx_exit(void)
+{
+ int i;
+
+ for (i = 0; i < PCMCIA_SOCKETS_NO; i++)
+ pcmcia_unregister_socket(&socket[i].socket);
+
+ m8xx_shutdown();
+
+ platform_device_unregister(&m8xx_device);
+ driver_unregister(&m8xx_driver);
+}
+
+module_init(m8xx_init);
+module_exit(m8xx_exit);
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c
index b54a8b8c0fca..fe5ea36e7de3 100644
--- a/drivers/pcmcia/pxa2xx_sharpsl.c
+++ b/drivers/pcmcia/pxa2xx_sharpsl.c
@@ -18,10 +18,15 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
+#include <asm/mach-types.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/hardware/scoop.h>
-#include <asm/arch/pxa-regs.h>
+#ifdef CONFIG_SA1100_COLLIE
+#include <asm/arch-sa1100/collie.h>
+#else
+#include <asm/arch-pxa/pxa-regs.h>
+#endif
#include "soc_common.h"
@@ -38,6 +43,7 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
int ret;
+#ifndef CONFIG_SA1100_COLLIE
/*
* Setup default state of GPIO outputs
* before we enable them as outputs.
@@ -60,6 +66,7 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
pxa_gpio_mode(GPIO55_nPREG_MD);
pxa_gpio_mode(GPIO56_nPWAIT_MD);
pxa_gpio_mode(GPIO57_nIOIS16_MD);
+#endif
/* Register interrupts */
if (scoop_devs[skt->nr].cd_irq >= 0) {
@@ -213,12 +220,20 @@ static void sharpsl_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_IMR, 0x00C0);
write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_MCR, 0x0101);
scoop_devs[skt->nr].keep_vs = NO_KEEP_VS;
+
+ if (machine_is_collie())
+ /* We need to disable SS_OUTPUT_ENA here. */
+ write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR, read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR) & ~0x0080);
}
static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
/* CF_BUS_OFF */
sharpsl_pcmcia_init_reset(&scoop_devs[skt->nr]);
+
+ if (machine_is_collie())
+ /* We need to disable SS_OUTPUT_ENA here. */
+ write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR, read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR) & ~0x0080);
}
static struct pcmcia_low_level sharpsl_pcmcia_ops = {
@@ -235,6 +250,19 @@ static struct pcmcia_low_level sharpsl_pcmcia_ops = {
static struct platform_device *sharpsl_pcmcia_device;
+#ifdef CONFIG_SA1100_COLLIE
+int __init pcmcia_collie_init(struct device *dev)
+{
+ int ret = -ENODEV;
+
+ if (machine_is_collie())
+ ret = sa11xx_drv_pcmcia_probe(dev, &sharpsl_pcmcia_ops, 0, 1);
+
+ return ret;
+}
+
+#else
+
static int __init sharpsl_pcmcia_init(void)
{
int ret;
@@ -269,6 +297,7 @@ static void __exit sharpsl_pcmcia_exit(void)
fs_initcall(sharpsl_pcmcia_init);
module_exit(sharpsl_pcmcia_exit);
+#endif
MODULE_DESCRIPTION("Sharp SL Series PCMCIA Support");
MODULE_LICENSE("GPL");
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
index fc87e7e2b6b8..00960a379b9c 100644
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -779,7 +779,7 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
if (!s->cb_dev || !s->cb_dev->bus)
return -ENODEV;
-#if defined(CONFIG_X86) || defined(CONFIG_X86_64)
+#if defined(CONFIG_X86)
/* If this is the root bus, the risk of hitting
* some strange system devices which aren't protected
* by either ACPI resource tables or properly requested
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
index 122fb29b1e34..6d441ec75c6a 100644
--- a/drivers/pcmcia/sa1100_generic.c
+++ b/drivers/pcmcia/sa1100_generic.c
@@ -39,8 +39,12 @@
#include <pcmcia/cs.h>
#include <pcmcia/ss.h>
+#include <asm/hardware/scoop.h>
+
#include "sa1100_generic.h"
+int __init pcmcia_collie_init(struct device *dev);
+
static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = {
#ifdef CONFIG_SA1100_ASSABET
pcmcia_assabet_init,
@@ -57,6 +61,9 @@ static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = {
#ifdef CONFIG_SA1100_SIMPAD
pcmcia_simpad_init,
#endif
+#ifdef CONFIG_SA1100_COLLIE
+ pcmcia_collie_init,
+#endif
};
static int sa11x0_drv_pcmcia_probe(struct device *dev)
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
index 94442ffd4aed..cbb2749db178 100644
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -12,6 +12,8 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/pnp.h>
+#include <linux/slab.h>
+#include <linux/bitmap.h>
#include "base.h"
DECLARE_MUTEX(pnp_res_mutex);
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c
index b0ca65b68645..5e38cd7335f7 100644
--- a/drivers/pnp/pnpbios/rsparser.c
+++ b/drivers/pnp/pnpbios/rsparser.c
@@ -7,6 +7,8 @@
#include <linux/ctype.h>
#include <linux/pnp.h>
#include <linux/pnpbios.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#ifdef CONFIG_PCI
#include <linux/pci.h>
diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c
index fc7a213e591f..c570a9f6ce9c 100644
--- a/drivers/s390/char/con3270.c
+++ b/drivers/s390/char/con3270.c
@@ -213,6 +213,9 @@ con3270_update(struct con3270 *cp)
struct string *s, *n;
int rc;
+ if (cp->view.dev)
+ raw3270_activate_view(&cp->view);
+
wrq = xchg(&cp->write, 0);
if (!wrq) {
con3270_set_timer(cp, 1);
@@ -489,8 +492,6 @@ con3270_write(struct console *co, const char *str, unsigned int count)
unsigned char c;
cp = condev;
- if (cp->view.dev)
- raw3270_activate_view(&cp->view);
spin_lock_irqsave(&cp->view.lock, flags);
while (count-- > 0) {
c = *str++;
@@ -620,7 +621,7 @@ con3270_init(void)
(void (*)(unsigned long)) con3270_read_tasklet,
(unsigned long) condev->read);
- raw3270_add_view(&condev->view, &con3270_fn, 0);
+ raw3270_add_view(&condev->view, &con3270_fn, 1);
INIT_LIST_HEAD(&condev->freemem);
for (i = 0; i < CON3270_STRING_PAGES; i++) {
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c
index 60afcdcf91c2..735a7fcdeff5 100644
--- a/drivers/s390/char/fs3270.c
+++ b/drivers/s390/char/fs3270.c
@@ -33,8 +33,11 @@ struct fs3270 {
int read_command; /* ccw command to use for reads. */
int write_command; /* ccw command to use for writes. */
int attention; /* Got attention. */
- struct raw3270_request *clear; /* single clear request. */
- wait_queue_head_t attn_wait; /* Attention wait queue. */
+ int active; /* Fullscreen view is active. */
+ struct raw3270_request *init; /* single init request. */
+ wait_queue_head_t wait; /* Init & attention wait queue. */
+ struct idal_buffer *rdbuf; /* full-screen-deactivate buffer */
+ size_t rdbuf_size; /* size of data returned by RDBUF */
};
static void
@@ -43,58 +46,172 @@ fs3270_wake_up(struct raw3270_request *rq, void *data)
wake_up((wait_queue_head_t *) data);
}
+static inline int
+fs3270_working(struct fs3270 *fp)
+{
+ /*
+ * The fullscreen view is in working order if the view
+ * has been activated AND the initial request is finished.
+ */
+ return fp->active && raw3270_request_final(fp->init);
+}
+
static int
fs3270_do_io(struct raw3270_view *view, struct raw3270_request *rq)
{
- wait_queue_head_t wq;
+ struct fs3270 *fp;
int rc;
- init_waitqueue_head(&wq);
+ fp = (struct fs3270 *) view;
rq->callback = fs3270_wake_up;
- rq->callback_data = &wq;
- rc = raw3270_start(view, rq);
- if (rc)
- return rc;
- /* Started sucessfully. Now wait for completion. */
- wait_event(wq, raw3270_request_final(rq));
- return rq->rc;
+ rq->callback_data = &fp->wait;
+
+ do {
+ if (!fs3270_working(fp)) {
+ /* Fullscreen view isn't ready yet. */
+ rc = wait_event_interruptible(fp->wait,
+ fs3270_working(fp));
+ if (rc != 0)
+ break;
+ }
+ rc = raw3270_start(view, rq);
+ if (rc == 0) {
+ /* Started sucessfully. Now wait for completion. */
+ wait_event(fp->wait, raw3270_request_final(rq));
+ }
+ } while (rc == -EACCES);
+ return rc;
}
+/*
+ * Switch to the fullscreen view.
+ */
static void
fs3270_reset_callback(struct raw3270_request *rq, void *data)
{
+ struct fs3270 *fp;
+
+ fp = (struct fs3270 *) rq->view;
raw3270_request_reset(rq);
+ wake_up(&fp->wait);
+}
+
+static void
+fs3270_restore_callback(struct raw3270_request *rq, void *data)
+{
+ struct fs3270 *fp;
+
+ fp = (struct fs3270 *) rq->view;
+ if (rq->rc != 0 || rq->rescnt != 0) {
+ if (fp->fs_pid)
+ kill_proc(fp->fs_pid, SIGHUP, 1);
+ }
+ fp->rdbuf_size = 0;
+ raw3270_request_reset(rq);
+ wake_up(&fp->wait);
}
-/*
- * Switch to the fullscreen view.
- */
static int
fs3270_activate(struct raw3270_view *view)
{
struct fs3270 *fp;
+ char *cp;
+ int rc;
fp = (struct fs3270 *) view;
- raw3270_request_set_cmd(fp->clear, TC_EWRITEA);
- fp->clear->callback = fs3270_reset_callback;
- return raw3270_start(view, fp->clear);
+
+ /* If an old init command is still running just return. */
+ if (!raw3270_request_final(fp->init))
+ return 0;
+
+ if (fp->rdbuf_size == 0) {
+ /* No saved buffer. Just clear the screen. */
+ raw3270_request_set_cmd(fp->init, TC_EWRITEA);
+ fp->init->callback = fs3270_reset_callback;
+ } else {
+ /* Restore fullscreen buffer saved by fs3270_deactivate. */
+ raw3270_request_set_cmd(fp->init, TC_EWRITEA);
+ raw3270_request_set_idal(fp->init, fp->rdbuf);
+ fp->init->ccw.count = fp->rdbuf_size;
+ cp = fp->rdbuf->data[0];
+ cp[0] = TW_KR;
+ cp[1] = TO_SBA;
+ cp[2] = cp[6];
+ cp[3] = cp[7];
+ cp[4] = TO_IC;
+ cp[5] = TO_SBA;
+ cp[6] = 0x40;
+ cp[7] = 0x40;
+ fp->init->rescnt = 0;
+ fp->init->callback = fs3270_restore_callback;
+ }
+ rc = fp->init->rc = raw3270_start_locked(view, fp->init);
+ if (rc)
+ fp->init->callback(fp->init, NULL);
+ else
+ fp->active = 1;
+ return rc;
}
/*
* Shutdown fullscreen view.
*/
static void
+fs3270_save_callback(struct raw3270_request *rq, void *data)
+{
+ struct fs3270 *fp;
+
+ fp = (struct fs3270 *) rq->view;
+
+ /* Correct idal buffer element 0 address. */
+ fp->rdbuf->data[0] -= 5;
+ fp->rdbuf->size += 5;
+
+ /*
+ * If the rdbuf command failed or the idal buffer is
+ * to small for the amount of data returned by the
+ * rdbuf command, then we have no choice but to send
+ * a SIGHUP to the application.
+ */
+ if (rq->rc != 0 || rq->rescnt == 0) {
+ if (fp->fs_pid)
+ kill_proc(fp->fs_pid, SIGHUP, 1);
+ fp->rdbuf_size = 0;
+ } else
+ fp->rdbuf_size = fp->rdbuf->size - rq->rescnt;
+ raw3270_request_reset(rq);
+ wake_up(&fp->wait);
+}
+
+static void
fs3270_deactivate(struct raw3270_view *view)
{
- // FIXME: is this a good idea? The user program using fullscreen 3270
- // will die just because a console message appeared. On the other
- // hand the fullscreen device is unoperational now.
struct fs3270 *fp;
fp = (struct fs3270 *) view;
- if (fp->fs_pid != 0)
- kill_proc(fp->fs_pid, SIGHUP, 1);
- fp->fs_pid = 0;
+ fp->active = 0;
+
+ /* If an old init command is still running just return. */
+ if (!raw3270_request_final(fp->init))
+ return;
+
+ /* Prepare read-buffer request. */
+ raw3270_request_set_cmd(fp->init, TC_RDBUF);
+ /*
+ * Hackish: skip first 5 bytes of the idal buffer to make
+ * room for the TW_KR/TO_SBA/<address>/<address>/TO_IC sequence
+ * in the activation command.
+ */
+ fp->rdbuf->data[0] += 5;
+ fp->rdbuf->size -= 5;
+ raw3270_request_set_idal(fp->init, fp->rdbuf);
+ fp->init->rescnt = 0;
+ fp->init->callback = fs3270_save_callback;
+
+ /* Start I/O to read in the 3270 buffer. */
+ fp->init->rc = raw3270_start_locked(view, fp->init);
+ if (fp->init->rc)
+ fp->init->callback(fp->init, NULL);
}
static int
@@ -103,7 +220,7 @@ fs3270_irq(struct fs3270 *fp, struct raw3270_request *rq, struct irb *irb)
/* Handle ATTN. Set indication and wake waiters for attention. */
if (irb->scsw.dstat & DEV_STAT_ATTENTION) {
fp->attention = 1;
- wake_up(&fp->attn_wait);
+ wake_up(&fp->wait);
}
if (rq) {
@@ -125,7 +242,7 @@ fs3270_read(struct file *filp, char *data, size_t count, loff_t *off)
struct fs3270 *fp;
struct raw3270_request *rq;
struct idal_buffer *ib;
- int rc;
+ ssize_t rc;
if (count == 0 || count > 65535)
return -EINVAL;
@@ -133,7 +250,7 @@ fs3270_read(struct file *filp, char *data, size_t count, loff_t *off)
if (!fp)
return -ENODEV;
ib = idal_buffer_alloc(count, 0);
- if (!ib)
+ if (IS_ERR(ib))
return -ENOMEM;
rq = raw3270_request_alloc(0);
if (!IS_ERR(rq)) {
@@ -141,10 +258,19 @@ fs3270_read(struct file *filp, char *data, size_t count, loff_t *off)
fp->read_command = 6;
raw3270_request_set_cmd(rq, fp->read_command ? : 2);
raw3270_request_set_idal(rq, ib);
- wait_event(fp->attn_wait, fp->attention);
- rc = fs3270_do_io(&fp->view, rq);
- if (rc == 0 && idal_buffer_to_user(ib, data, count))
- rc = -EFAULT;
+ rc = wait_event_interruptible(fp->wait, fp->attention);
+ fp->attention = 0;
+ if (rc == 0) {
+ rc = fs3270_do_io(&fp->view, rq);
+ if (rc == 0) {
+ count -= rq->rescnt;
+ if (idal_buffer_to_user(ib, data, count) != 0)
+ rc = -EFAULT;
+ else
+ rc = count;
+
+ }
+ }
raw3270_request_free(rq);
} else
rc = PTR_ERR(rq);
@@ -162,13 +288,13 @@ fs3270_write(struct file *filp, const char *data, size_t count, loff_t *off)
struct raw3270_request *rq;
struct idal_buffer *ib;
int write_command;
- int rc;
+ ssize_t rc;
fp = filp->private_data;
if (!fp)
return -ENODEV;
ib = idal_buffer_alloc(count, 0);
- if (!ib)
+ if (IS_ERR(ib))
return -ENOMEM;
rq = raw3270_request_alloc(0);
if (!IS_ERR(rq)) {
@@ -179,6 +305,8 @@ fs3270_write(struct file *filp, const char *data, size_t count, loff_t *off)
raw3270_request_set_cmd(rq, write_command);
raw3270_request_set_idal(rq, ib);
rc = fs3270_do_io(&fp->view, rq);
+ if (rc == 0)
+ rc = count - rq->rescnt;
} else
rc = -EFAULT;
raw3270_request_free(rq);
@@ -232,7 +360,7 @@ fs3270_ioctl(struct inode *inode, struct file *filp,
}
/*
- * Allocate tty3270 structure.
+ * Allocate fs3270 structure.
*/
static struct fs3270 *
fs3270_alloc_view(void)
@@ -243,8 +371,8 @@ fs3270_alloc_view(void)
if (!fp)
return ERR_PTR(-ENOMEM);
memset(fp, 0, sizeof(struct fs3270));
- fp->clear = raw3270_request_alloc(0);
- if (!IS_ERR(fp->clear)) {
+ fp->init = raw3270_request_alloc(0);
+ if (IS_ERR(fp->init)) {
kfree(fp);
return ERR_PTR(-ENOMEM);
}
@@ -252,12 +380,17 @@ fs3270_alloc_view(void)
}
/*
- * Free tty3270 structure.
+ * Free fs3270 structure.
*/
static void
fs3270_free_view(struct raw3270_view *view)
{
- raw3270_request_free(((struct fs3270 *) view)->clear);
+ struct fs3270 *fp;
+
+ fp = (struct fs3270 *) view;
+ if (fp->rdbuf)
+ idal_buffer_free(fp->rdbuf);
+ raw3270_request_free(((struct fs3270 *) view)->init);
kfree(view);
}
@@ -285,11 +418,20 @@ static int
fs3270_open(struct inode *inode, struct file *filp)
{
struct fs3270 *fp;
+ struct idal_buffer *ib;
int minor, rc;
if (imajor(filp->f_dentry->d_inode) != IBM_FS3270_MAJOR)
return -ENODEV;
minor = iminor(filp->f_dentry->d_inode);
+ /* Check for minor 0 multiplexer. */
+ if (minor == 0) {
+ if (!current->signal->tty)
+ return -ENODEV;
+ if (current->signal->tty->driver->major != IBM_TTY3270_MAJOR)
+ return -ENODEV;
+ minor = current->signal->tty->index + RAW3270_FIRSTMINOR;
+ }
/* Check if some other program is already using fullscreen mode. */
fp = (struct fs3270 *) raw3270_find_view(&fs3270_fn, minor);
if (!IS_ERR(fp)) {
@@ -301,7 +443,7 @@ fs3270_open(struct inode *inode, struct file *filp)
if (IS_ERR(fp))
return PTR_ERR(fp);
- init_waitqueue_head(&fp->attn_wait);
+ init_waitqueue_head(&fp->wait);
fp->fs_pid = current->pid;
rc = raw3270_add_view(&fp->view, &fs3270_fn, minor);
if (rc) {
@@ -309,8 +451,18 @@ fs3270_open(struct inode *inode, struct file *filp)
return rc;
}
+ /* Allocate idal-buffer. */
+ ib = idal_buffer_alloc(2*fp->view.rows*fp->view.cols + 5, 0);
+ if (IS_ERR(ib)) {
+ raw3270_put_view(&fp->view);
+ raw3270_del_view(&fp->view);
+ return PTR_ERR(fp);
+ }
+ fp->rdbuf = ib;
+
rc = raw3270_activate_view(&fp->view);
if (rc) {
+ raw3270_put_view(&fp->view);
raw3270_del_view(&fp->view);
return rc;
}
@@ -329,8 +481,12 @@ fs3270_close(struct inode *inode, struct file *filp)
fp = filp->private_data;
filp->private_data = 0;
- if (fp)
+ if (fp) {
+ fp->fs_pid = 0;
+ raw3270_reset(&fp->view);
+ raw3270_put_view(&fp->view);
raw3270_del_view(&fp->view);
+ }
return 0;
}
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index 328d9cbc56a3..d66946443dfc 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -25,6 +25,12 @@
#include "raw3270.h"
+#include <linux/major.h>
+#include <linux/kdev_t.h>
+#include <linux/device.h>
+
+struct class *class3270;
+
/* The main 3270 data structure. */
struct raw3270 {
struct list_head list;
@@ -41,6 +47,8 @@ struct raw3270 {
struct timer_list timer; /* Device timer. */
unsigned char *ascebc; /* ascii -> ebcdic table */
+ struct class_device *clttydev; /* 3270-class tty device ptr */
+ struct class_device *cltubdev; /* 3270-class tub device ptr */
};
/* raw3270->flags */
@@ -317,6 +325,22 @@ raw3270_start(struct raw3270_view *view, struct raw3270_request *rq)
}
int
+raw3270_start_locked(struct raw3270_view *view, struct raw3270_request *rq)
+{
+ struct raw3270 *rp;
+ int rc;
+
+ rp = view->dev;
+ if (!rp || rp->view != view)
+ rc = -EACCES;
+ else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))
+ rc = -ENODEV;
+ else
+ rc = __raw3270_start(rp, view, rq);
+ return rc;
+}
+
+int
raw3270_start_irq(struct raw3270_view *view, struct raw3270_request *rq)
{
struct raw3270 *rp;
@@ -744,6 +768,22 @@ raw3270_reset_device(struct raw3270 *rp)
return rc;
}
+int
+raw3270_reset(struct raw3270_view *view)
+{
+ struct raw3270 *rp;
+ int rc;
+
+ rp = view->dev;
+ if (!rp || rp->view != view)
+ rc = -EACCES;
+ else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))
+ rc = -ENODEV;
+ else
+ rc = raw3270_reset_device(view->dev);
+ return rc;
+}
+
/*
* Setup new 3270 device.
*/
@@ -774,11 +814,12 @@ raw3270_setup_device(struct ccw_device *cdev, struct raw3270 *rp, char *ascebc)
/*
* Add device to list and find the smallest unused minor
- * number for it.
+ * number for it. Note: there is no device with minor 0,
+ * see special case for fs3270.c:fs3270_open().
*/
down(&raw3270_sem);
/* Keep the list sorted. */
- minor = 0;
+ minor = RAW3270_FIRSTMINOR;
rp->minor = -1;
list_for_each(l, &raw3270_devices) {
tmp = list_entry(l, struct raw3270, list);
@@ -789,7 +830,7 @@ raw3270_setup_device(struct ccw_device *cdev, struct raw3270 *rp, char *ascebc)
}
minor++;
}
- if (rp->minor == -1 && minor < RAW3270_MAXDEVS) {
+ if (rp->minor == -1 && minor < RAW3270_MAXDEVS + RAW3270_FIRSTMINOR) {
rp->minor = minor;
list_add_tail(&rp->list, &raw3270_devices);
}
@@ -941,11 +982,12 @@ raw3270_deactivate_view(struct raw3270_view *view)
list_add_tail(&view->list, &rp->view_list);
/* Try to activate another view. */
if (test_bit(RAW3270_FLAGS_READY, &rp->flags)) {
- list_for_each_entry(view, &rp->view_list, list)
- if (view->fn->activate(view) == 0) {
- rp->view = view;
+ list_for_each_entry(view, &rp->view_list, list) {
+ rp->view = view;
+ if (view->fn->activate(view) == 0)
break;
- }
+ rp->view = 0;
+ }
}
}
spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
@@ -961,6 +1003,8 @@ raw3270_add_view(struct raw3270_view *view, struct raw3270_fn *fn, int minor)
struct raw3270 *rp;
int rc;
+ if (minor <= 0)
+ return -ENODEV;
down(&raw3270_sem);
rc = -ENODEV;
list_for_each_entry(rp, &raw3270_devices, list) {
@@ -976,7 +1020,7 @@ raw3270_add_view(struct raw3270_view *view, struct raw3270_fn *fn, int minor)
view->cols = rp->cols;
view->ascebc = rp->ascebc;
spin_lock_init(&view->lock);
- list_add_tail(&view->list, &rp->view_list);
+ list_add(&view->list, &rp->view_list);
rc = 0;
}
spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
@@ -1039,7 +1083,7 @@ raw3270_del_view(struct raw3270_view *view)
if (!rp->view && test_bit(RAW3270_FLAGS_READY, &rp->flags)) {
/* Try to activate another view. */
list_for_each_entry(nv, &rp->view_list, list) {
- if (nv->fn->activate(view) == 0) {
+ if (nv->fn->activate(nv) == 0) {
rp->view = nv;
break;
}
@@ -1063,6 +1107,12 @@ raw3270_delete_device(struct raw3270 *rp)
/* Remove from device chain. */
down(&raw3270_sem);
+ if (rp->clttydev)
+ class_device_destroy(class3270,
+ MKDEV(IBM_TTY3270_MAJOR, rp->minor));
+ if (rp->cltubdev)
+ class_device_destroy(class3270,
+ MKDEV(IBM_FS3270_MAJOR, rp->minor));
list_del_init(&rp->list);
up(&raw3270_sem);
@@ -1129,6 +1179,16 @@ raw3270_create_attributes(struct raw3270 *rp)
{
//FIXME: check return code
sysfs_create_group(&rp->cdev->dev.kobj, &raw3270_attr_group);
+ rp->clttydev =
+ class_device_create(class3270,
+ MKDEV(IBM_TTY3270_MAJOR, rp->minor),
+ &rp->cdev->dev, "tty%s",
+ rp->cdev->dev.bus_id);
+ rp->cltubdev =
+ class_device_create(class3270,
+ MKDEV(IBM_FS3270_MAJOR, rp->minor),
+ &rp->cdev->dev, "tub%s",
+ rp->cdev->dev.bus_id);
}
/*
@@ -1189,13 +1249,13 @@ raw3270_set_online (struct ccw_device *cdev)
return PTR_ERR(rp);
rc = raw3270_reset_device(rp);
if (rc)
- return rc;
+ goto failure;
rc = raw3270_size_device(rp);
if (rc)
- return rc;
+ goto failure;
rc = raw3270_reset_device(rp);
if (rc)
- return rc;
+ goto failure;
raw3270_create_attributes(rp);
set_bit(RAW3270_FLAGS_READY, &rp->flags);
down(&raw3270_sem);
@@ -1203,6 +1263,10 @@ raw3270_set_online (struct ccw_device *cdev)
np->notifier(rp->minor, 1);
up(&raw3270_sem);
return 0;
+
+failure:
+ raw3270_delete_device(rp);
+ return rc;
}
/*
@@ -1217,6 +1281,14 @@ raw3270_remove (struct ccw_device *cdev)
struct raw3270_notifier *np;
rp = cdev->dev.driver_data;
+ /*
+ * _remove is the opposite of _probe; it's probe that
+ * should set up rp. raw3270_remove gets entered for
+ * devices even if they haven't been varied online.
+ * Thus, rp may validly be NULL here.
+ */
+ if (rp == NULL)
+ return;
clear_bit(RAW3270_FLAGS_READY, &rp->flags);
sysfs_remove_group(&cdev->dev.kobj, &raw3270_attr_group);
@@ -1301,6 +1373,7 @@ raw3270_init(void)
if (rc == 0) {
/* Create attributes for early (= console) device. */
down(&raw3270_sem);
+ class3270 = class_create(THIS_MODULE, "3270");
list_for_each_entry(rp, &raw3270_devices, list) {
get_device(&rp->cdev->dev);
raw3270_create_attributes(rp);
@@ -1314,6 +1387,7 @@ static void
raw3270_exit(void)
{
ccw_driver_unregister(&raw3270_ccw_driver);
+ class_destroy(class3270);
}
MODULE_LICENSE("GPL");
@@ -1335,7 +1409,9 @@ EXPORT_SYMBOL(raw3270_find_view);
EXPORT_SYMBOL(raw3270_activate_view);
EXPORT_SYMBOL(raw3270_deactivate_view);
EXPORT_SYMBOL(raw3270_start);
+EXPORT_SYMBOL(raw3270_start_locked);
EXPORT_SYMBOL(raw3270_start_irq);
+EXPORT_SYMBOL(raw3270_reset);
EXPORT_SYMBOL(raw3270_register_notifier);
EXPORT_SYMBOL(raw3270_unregister_notifier);
EXPORT_SYMBOL(raw3270_wait_queue);
diff --git a/drivers/s390/char/raw3270.h b/drivers/s390/char/raw3270.h
index ed5d4eb9f623..b635bf8e7775 100644
--- a/drivers/s390/char/raw3270.h
+++ b/drivers/s390/char/raw3270.h
@@ -21,6 +21,7 @@
/* Local Channel Commands */
#define TC_WRITE 0x01 /* Write */
+#define TC_RDBUF 0x02 /* Read Buffer */
#define TC_EWRITE 0x05 /* Erase write */
#define TC_READMOD 0x06 /* Read modified */
#define TC_EWRITEA 0x0d /* Erase write alternate */
@@ -76,7 +77,8 @@
#define TW_KR 0xc2 /* Keyboard restore */
#define TW_PLUSALARM 0x04 /* Add this bit for alarm */
-#define RAW3270_MAXDEVS 256
+#define RAW3270_FIRSTMINOR 1 /* First minor number */
+#define RAW3270_MAXDEVS 255 /* Max number of 3270 devices */
/* For TUBGETMOD and TUBSETMOD. Should include. */
struct raw3270_iocb {
@@ -166,7 +168,10 @@ void raw3270_del_view(struct raw3270_view *);
void raw3270_deactivate_view(struct raw3270_view *);
struct raw3270_view *raw3270_find_view(struct raw3270_fn *, int);
int raw3270_start(struct raw3270_view *, struct raw3270_request *);
+int raw3270_start_locked(struct raw3270_view *, struct raw3270_request *);
int raw3270_start_irq(struct raw3270_view *, struct raw3270_request *);
+int raw3270_reset(struct raw3270_view *);
+struct raw3270_view *raw3270_view(struct raw3270_view *);
/* Reference count inliner for view structures. */
static inline void
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
index 7db5ebce7f0f..4b9069370388 100644
--- a/drivers/s390/char/tty3270.c
+++ b/drivers/s390/char/tty3270.c
@@ -653,18 +653,12 @@ tty3270_activate(struct raw3270_view *view)
tp->update_flags = TTY_UPDATE_ALL;
tty3270_set_timer(tp, 1);
spin_unlock_irqrestore(&tp->view.lock, flags);
- start_tty(tp->tty);
return 0;
}
static void
tty3270_deactivate(struct raw3270_view *view)
{
- struct tty3270 *tp;
-
- tp = (struct tty3270 *) view;
- if (tp && tp->tty)
- stop_tty(tp->tty);
}
static int
@@ -716,13 +710,13 @@ tty3270_alloc_view(void)
tp->freemem_pages[pages], PAGE_SIZE);
}
tp->write = raw3270_request_alloc(TTY3270_OUTPUT_BUFFER_SIZE);
- if (!tp->write)
+ if (IS_ERR(tp->write))
goto out_pages;
tp->read = raw3270_request_alloc(0);
- if (!tp->read)
+ if (IS_ERR(tp->read))
goto out_write;
tp->kreset = raw3270_request_alloc(1);
- if (!tp->kreset)
+ if (IS_ERR(tp->kreset))
goto out_read;
tp->kbd = kbd_alloc();
if (!tp->kbd)
@@ -845,7 +839,8 @@ tty3270_del_views(void)
int i;
for (i = 0; i < tty3270_max_index; i++) {
- tp = (struct tty3270 *) raw3270_find_view(&tty3270_fn, i);
+ tp = (struct tty3270 *)
+ raw3270_find_view(&tty3270_fn, i + RAW3270_FIRSTMINOR);
if (!IS_ERR(tp))
raw3270_del_view(&tp->view);
}
@@ -871,7 +866,9 @@ tty3270_open(struct tty_struct *tty, struct file * filp)
if (tty->count > 1)
return 0;
/* Check if the tty3270 is already there. */
- tp = (struct tty3270 *) raw3270_find_view(&tty3270_fn, tty->index);
+ tp = (struct tty3270 *)
+ raw3270_find_view(&tty3270_fn,
+ tty->index + RAW3270_FIRSTMINOR);
if (!IS_ERR(tp)) {
tty->driver_data = tp;
tty->winsize.ws_row = tp->view.rows - 2;
@@ -903,7 +900,8 @@ tty3270_open(struct tty_struct *tty, struct file * filp)
(void (*)(unsigned long)) tty3270_read_tasklet,
(unsigned long) tp->read);
- rc = raw3270_add_view(&tp->view, &tty3270_fn, tty->index);
+ rc = raw3270_add_view(&tp->view, &tty3270_fn,
+ tty->index + RAW3270_FIRSTMINOR);
if (rc) {
tty3270_free_view(tp);
return rc;
@@ -911,8 +909,8 @@ tty3270_open(struct tty_struct *tty, struct file * filp)
rc = tty3270_alloc_screen(tp);
if (rc) {
- raw3270_del_view(&tp->view);
raw3270_put_view(&tp->view);
+ raw3270_del_view(&tp->view);
return rc;
}
@@ -1780,7 +1778,7 @@ tty3270_init(void)
struct tty_driver *driver;
int ret;
- driver = alloc_tty_driver(256);
+ driver = alloc_tty_driver(RAW3270_MAXDEVS);
if (!driver)
return -ENOMEM;
@@ -1794,6 +1792,7 @@ tty3270_init(void)
driver->driver_name = "ttyTUB";
driver->name = "ttyTUB";
driver->major = IBM_TTY3270_MAJOR;
+ driver->minor_start = RAW3270_FIRSTMINOR;
driver->type = TTY_DRIVER_TYPE_SYSTEM;
driver->subtype = SYSTEM_TYPE_TTY;
driver->init_termios = tty_std_termios;
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
index a107fec4457a..b2d75de144c6 100644
--- a/drivers/s390/char/vmlogrdr.c
+++ b/drivers/s390/char/vmlogrdr.c
@@ -787,8 +787,8 @@ vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) {
return ret;
}
priv->class_device = class_device_create(
- NULL,
vmlogrdr_class,
+ NULL,
MKDEV(vmlogrdr_major, priv->minor_num),
dev,
"%s", dev->bus_id );
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c
index 8cc4f1a940dc..c05b069c2996 100644
--- a/drivers/s390/cio/cmf.c
+++ b/drivers/s390/cio/cmf.c
@@ -30,10 +30,13 @@
#include <linux/list.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
+#include <linux/slab.h>
+#include <linux/timex.h> /* get_clock() */
#include <asm/ccwdev.h>
#include <asm/cio.h>
#include <asm/cmb.h>
+#include <asm/div64.h>
#include "cio.h"
#include "css.h"
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 9adc11e8b8bc..811c9d150637 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -22,6 +22,7 @@
#include <asm/ccwdev.h>
#include <asm/cio.h>
+#include <asm/param.h> /* HZ */
#include "cio.h"
#include "css.h"
@@ -252,6 +253,23 @@ cutype_show (struct device *dev, struct device_attribute *attr, char *buf)
}
static ssize_t
+modalias_show (struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct ccw_device *cdev = to_ccwdev(dev);
+ struct ccw_device_id *id = &(cdev->id);
+ int ret;
+
+ ret = sprintf(buf, "ccw:t%04Xm%02x",
+ id->cu_type, id->cu_model);
+ if (id->dev_type != 0)
+ ret += sprintf(buf + ret, "dt%04Xdm%02X\n",
+ id->dev_type, id->dev_model);
+ else
+ ret += sprintf(buf + ret, "dtdm\n");
+ return ret;
+}
+
+static ssize_t
online_show (struct device *dev, struct device_attribute *attr, char *buf)
{
struct ccw_device *cdev = to_ccwdev(dev);
@@ -448,6 +466,7 @@ static DEVICE_ATTR(chpids, 0444, chpids_show, NULL);
static DEVICE_ATTR(pimpampom, 0444, pimpampom_show, NULL);
static DEVICE_ATTR(devtype, 0444, devtype_show, NULL);
static DEVICE_ATTR(cutype, 0444, cutype_show, NULL);
+static DEVICE_ATTR(modalias, 0444, modalias_show, NULL);
static DEVICE_ATTR(online, 0644, online_show, online_store);
extern struct device_attribute dev_attr_cmb_enable;
static DEVICE_ATTR(availability, 0444, available_show, NULL);
@@ -471,6 +490,7 @@ subchannel_add_files (struct device *dev)
static struct attribute * ccwdev_attrs[] = {
&dev_attr_devtype.attr,
&dev_attr_cutype.attr,
+ &dev_attr_modalias.attr,
&dev_attr_online.attr,
&dev_attr_cmb_enable.attr,
&dev_attr_availability.attr,
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index fbe4202a3f6f..c1c89f4fd4e3 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -11,6 +11,8 @@
#include <linux/module.h>
#include <linux/config.h>
#include <linux/init.h>
+#include <linux/jiffies.h>
+#include <linux/string.h>
#include <asm/ccwdev.h>
#include <asm/cio.h>
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index fe8187d6f58b..e2a5657d5fdb 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -41,6 +41,7 @@
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/dma-mapping.h>
+#include <linux/device.h>
#include "scsi.h"
#include <scsi/scsi_host.h>
#include <linux/libata.h>
@@ -192,7 +193,6 @@ static void ahci_port_stop(struct ata_port *ap);
static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
static void ahci_qc_prep(struct ata_queued_cmd *qc);
static u8 ahci_check_status(struct ata_port *ap);
-static u8 ahci_check_err(struct ata_port *ap);
static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
static void ahci_remove_one (struct pci_dev *pdev);
@@ -221,7 +221,6 @@ static const struct ata_port_operations ahci_ops = {
.check_status = ahci_check_status,
.check_altstatus = ahci_check_status,
- .check_err = ahci_check_err,
.dev_select = ata_noop_dev_select,
.tf_read = ahci_tf_read,
@@ -458,13 +457,6 @@ static u8 ahci_check_status(struct ata_port *ap)
return readl(mmio + PORT_TFDATA) & 0xFF;
}
-static u8 ahci_check_err(struct ata_port *ap)
-{
- void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr;
-
- return (readl(mmio + PORT_TFDATA) >> 8) & 0xFF;
-}
-
static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
{
struct ahci_port_priv *pp = ap->private_data;
@@ -609,7 +601,7 @@ static void ahci_eng_timeout(struct ata_port *ap)
* not being called from the SCSI EH.
*/
qc->scsidone = scsi_finish_command;
- ata_qc_complete(qc, ATA_ERR);
+ ata_qc_complete(qc, AC_ERR_OTHER);
}
spin_unlock_irqrestore(&host_set->lock, flags);
@@ -638,7 +630,7 @@ static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
if (status & PORT_IRQ_FATAL) {
ahci_intr_error(ap, status);
if (qc)
- ata_qc_complete(qc, ATA_ERR);
+ ata_qc_complete(qc, AC_ERR_OTHER);
}
return 1;
@@ -683,10 +675,10 @@ static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *
if (!ahci_host_intr(ap, qc))
if (ata_ratelimit()) {
struct pci_dev *pdev =
- to_pci_dev(ap->host_set->dev);
- printk(KERN_WARNING
- "ahci(%s): unhandled interrupt on port %u\n",
- pci_name(pdev), i);
+ to_pci_dev(ap->host_set->dev);
+ dev_printk(KERN_WARNING, &pdev->dev,
+ "unhandled interrupt on port %u\n",
+ i);
}
VPRINTK("port %u\n", i);
@@ -694,10 +686,9 @@ static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *
VPRINTK("port %u (no irq)\n", i);
if (ata_ratelimit()) {
struct pci_dev *pdev =
- to_pci_dev(ap->host_set->dev);
- printk(KERN_WARNING
- "ahci(%s): interrupt on disabled port %u\n",
- pci_name(pdev), i);
+ to_pci_dev(ap->host_set->dev);
+ dev_printk(KERN_WARNING, &pdev->dev,
+ "interrupt on disabled port %u\n", i);
}
}
@@ -769,8 +760,8 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
tmp = readl(mmio + HOST_CTL);
if (tmp & HOST_RESET) {
- printk(KERN_ERR DRV_NAME "(%s): controller reset failed (0x%x)\n",
- pci_name(pdev), tmp);
+ dev_printk(KERN_ERR, &pdev->dev,
+ "controller reset failed (0x%x)\n", tmp);
return -EIO;
}
@@ -798,22 +789,22 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
if (rc) {
rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
if (rc) {
- printk(KERN_ERR DRV_NAME "(%s): 64-bit DMA enable failed\n",
- pci_name(pdev));
+ dev_printk(KERN_ERR, &pdev->dev,
+ "64-bit DMA enable failed\n");
return rc;
}
}
} else {
rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
if (rc) {
- printk(KERN_ERR DRV_NAME "(%s): 32-bit DMA enable failed\n",
- pci_name(pdev));
+ dev_printk(KERN_ERR, &pdev->dev,
+ "32-bit DMA enable failed\n");
return rc;
}
rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
if (rc) {
- printk(KERN_ERR DRV_NAME "(%s): 32-bit consistent DMA enable failed\n",
- pci_name(pdev));
+ dev_printk(KERN_ERR, &pdev->dev,
+ "32-bit consistent DMA enable failed\n");
return rc;
}
}
@@ -916,10 +907,10 @@ static void ahci_print_info(struct ata_probe_ent *probe_ent)
else
scc_s = "unknown";
- printk(KERN_INFO DRV_NAME "(%s) AHCI %02x%02x.%02x%02x "
+ dev_printk(KERN_INFO, &pdev->dev,
+ "AHCI %02x%02x.%02x%02x "
"%u slots %u ports %s Gbps 0x%x impl %s mode\n"
,
- pci_name(pdev),
(vers >> 24) & 0xff,
(vers >> 16) & 0xff,
@@ -932,11 +923,11 @@ static void ahci_print_info(struct ata_probe_ent *probe_ent)
impl,
scc_s);
- printk(KERN_INFO DRV_NAME "(%s) flags: "
+ dev_printk(KERN_INFO, &pdev->dev,
+ "flags: "
"%s%s%s%s%s%s"
"%s%s%s%s%s%s%s\n"
,
- pci_name(pdev),
cap & (1 << 31) ? "64bit " : "",
cap & (1 << 30) ? "ncq " : "",
@@ -969,7 +960,7 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
VPRINTK("ENTER\n");
if (!printed_version++)
- printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
rc = pci_enable_device(pdev);
if (rc)
diff --git a/drivers/scsi/arm/scsi.h b/drivers/scsi/arm/scsi.h
index 48e1c4d9738b..19937640e2e7 100644
--- a/drivers/scsi/arm/scsi.h
+++ b/drivers/scsi/arm/scsi.h
@@ -10,6 +10,8 @@
* Commonly used scsi driver functions.
*/
+#include <linux/scatterlist.h>
+
#define BELT_AND_BRACES
/*
@@ -22,9 +24,7 @@ static inline int copy_SCp_to_sg(struct scatterlist *sg, Scsi_Pointer *SCp, int
BUG_ON(bufs + 1 > max);
- sg->page = virt_to_page(SCp->ptr);
- sg->offset = offset_in_page(SCp->ptr);
- sg->length = SCp->this_residual;
+ sg_set_buf(sg, SCp->ptr, SCp->this_residual);
if (bufs)
memcpy(sg + 1, SCp->buffer + 1,
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index be021478f416..7f8aa1b552ce 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -45,6 +45,7 @@
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
+#include <linux/device.h>
#include "scsi.h"
#include <scsi/scsi_host.h>
#include <linux/libata.h>
@@ -621,18 +622,19 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
struct ata_port_info *port_info[2];
- unsigned int combined = 0, n_ports = 1;
+ unsigned int combined = 0;
unsigned int pata_chan = 0, sata_chan = 0;
if (!printed_version++)
- printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+ dev_printk(KERN_DEBUG, &pdev->dev,
+ "version " DRV_VERSION "\n");
/* no hotplugging support (FIXME) */
if (!in_module_init)
return -ENODEV;
port_info[0] = &piix_port_info[ent->driver_data];
- port_info[1] = NULL;
+ port_info[1] = &piix_port_info[ent->driver_data];
if (port_info[0]->host_flags & PIIX_FLAG_AHCI) {
u8 tmp;
@@ -670,12 +672,13 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
port_info[sata_chan] = &piix_port_info[ent->driver_data];
port_info[sata_chan]->host_flags |= ATA_FLAG_SLAVE_POSS;
port_info[pata_chan] = &piix_port_info[ich5_pata];
- n_ports++;
- printk(KERN_WARNING DRV_NAME ": combined mode detected\n");
+ dev_printk(KERN_WARNING, &pdev->dev,
+ "combined mode detected (p=%u, s=%u)\n",
+ pata_chan, sata_chan);
}
- return ata_pci_init_one(pdev, port_info, n_ports);
+ return ata_pci_init_one(pdev, port_info, 2);
}
static int __init piix_init(void)
diff --git a/drivers/scsi/dec_esp.c b/drivers/scsi/dec_esp.c
index 315f95a0d6c0..4f39890b44ac 100644
--- a/drivers/scsi/dec_esp.c
+++ b/drivers/scsi/dec_esp.c
@@ -228,7 +228,7 @@ static int dec_esp_detect(Scsi_Host_Template * tpnt)
mem_start = get_tc_base_addr(slot);
/* Store base addr into esp struct */
- esp->slot = PHYSADDR(mem_start);
+ esp->slot = CPHYSADDR(mem_start);
esp->dregs = 0;
esp->eregs = (struct ESP_regs *) (mem_start + DEC_SCSI_SREG);
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index ff25210b00ba..822b9fa706f3 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -1543,13 +1543,16 @@ static struct vio_device_id ibmvscsi_device_table[] __devinitdata = {
{"vscsi", "IBM,v-scsi"},
{ "", "" }
};
-
MODULE_DEVICE_TABLE(vio, ibmvscsi_device_table);
+
static struct vio_driver ibmvscsi_driver = {
- .name = "ibmvscsi",
.id_table = ibmvscsi_device_table,
.probe = ibmvscsi_probe,
- .remove = ibmvscsi_remove
+ .remove = ibmvscsi_remove,
+ .driver = {
+ .name = "ibmvscsi",
+ .owner = THIS_MODULE,
+ }
};
int __init ibmvscsi_module_init(void)
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 3d62c9bcbff7..00d6a6657ebc 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -180,19 +180,12 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne
return;
}
count = min(pc->sg->length - pc->b_count, bcount);
- if (PageHighMem(pc->sg->page)) {
- unsigned long flags;
-
- local_irq_save(flags);
- buf = kmap_atomic(pc->sg->page, KM_IRQ0) + pc->sg->offset;
- drive->hwif->atapi_input_bytes(drive, buf + pc->b_count, count);
- kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
- local_irq_restore(flags);
- } else {
- buf = page_address(pc->sg->page) + pc->sg->offset;
- drive->hwif->atapi_input_bytes(drive, buf + pc->b_count, count);
- }
- bcount -= count; pc->b_count += count;
+ buf = kmap_atomic(pc->sg->page, KM_IRQ0);
+ drive->hwif->atapi_input_bytes(drive,
+ buf + pc->b_count + pc->sg->offset, count);
+ kunmap_atomic(buf, KM_IRQ0);
+ bcount -= count;
+ pc->b_count += count;
if (pc->b_count == pc->sg->length) {
pc->sg++;
pc->b_count = 0;
@@ -212,19 +205,12 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign
return;
}
count = min(pc->sg->length - pc->b_count, bcount);
- if (PageHighMem(pc->sg->page)) {
- unsigned long flags;
-
- local_irq_save(flags);
- buf = kmap_atomic(pc->sg->page, KM_IRQ0) + pc->sg->offset;
- drive->hwif->atapi_output_bytes(drive, buf + pc->b_count, count);
- kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
- local_irq_restore(flags);
- } else {
- buf = page_address(pc->sg->page) + pc->sg->offset;
- drive->hwif->atapi_output_bytes(drive, buf + pc->b_count, count);
- }
- bcount -= count; pc->b_count += count;
+ buf = kmap_atomic(pc->sg->page, KM_IRQ0);
+ drive->hwif->atapi_output_bytes(drive,
+ buf + pc->b_count + pc->sg->offset, count);
+ kunmap_atomic(buf, KM_IRQ0);
+ bcount -= count;
+ pc->b_count += count;
if (pc->b_count == pc->sg->length) {
pc->sg++;
pc->b_count = 0;
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index f53d7b8ac33f..8be7dc0b47b8 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -49,6 +49,7 @@
#include <linux/suspend.h>
#include <linux/workqueue.h>
#include <linux/jiffies.h>
+#include <linux/scatterlist.h>
#include <scsi/scsi.h>
#include "scsi.h"
#include "scsi_priv.h"
@@ -370,6 +371,8 @@ static void ata_tf_read_pio(struct ata_port *ap, struct ata_taskfile *tf)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
+ tf->command = ata_check_status(ap);
+ tf->feature = inb(ioaddr->error_addr);
tf->nsect = inb(ioaddr->nsect_addr);
tf->lbal = inb(ioaddr->lbal_addr);
tf->lbam = inb(ioaddr->lbam_addr);
@@ -402,6 +405,8 @@ static void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
+ tf->command = ata_check_status(ap);
+ tf->feature = readb((void __iomem *)ioaddr->error_addr);
tf->nsect = readb((void __iomem *)ioaddr->nsect_addr);
tf->lbal = readb((void __iomem *)ioaddr->lbal_addr);
tf->lbam = readb((void __iomem *)ioaddr->lbam_addr);
@@ -522,30 +527,6 @@ u8 ata_altstatus(struct ata_port *ap)
/**
- * ata_chk_err - Read device error reg
- * @ap: port where the device is
- *
- * Reads ATA taskfile error register for
- * currently-selected device and return its value.
- *
- * Note: may NOT be used as the check_err() entry in
- * ata_port_operations.
- *
- * LOCKING:
- * Inherited from caller.
- */
-u8 ata_chk_err(struct ata_port *ap)
-{
- if (ap->ops->check_err)
- return ap->ops->check_err(ap);
-
- if (ap->flags & ATA_FLAG_MMIO) {
- return readb((void __iomem *) ap->ioaddr.error_addr);
- }
- return inb(ap->ioaddr.error_addr);
-}
-
-/**
* ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure
* @tf: Taskfile to convert
* @fis: Buffer into which data will output
@@ -897,8 +878,8 @@ static u8 ata_dev_try_classify(struct ata_port *ap, unsigned int device)
memset(&tf, 0, sizeof(tf));
- err = ata_chk_err(ap);
ap->ops->tf_read(ap, &tf);
+ err = tf.feature;
dev->class = ATA_DEV_NONE;
@@ -1135,7 +1116,6 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device)
unsigned int major_version;
u16 tmp;
unsigned long xfer_modes;
- u8 status;
unsigned int using_edd;
DECLARE_COMPLETION(wait);
struct ata_queued_cmd *qc;
@@ -1189,8 +1169,11 @@ retry:
else
wait_for_completion(&wait);
- status = ata_chk_status(ap);
- if (status & ATA_ERR) {
+ spin_lock_irqsave(&ap->host_set->lock, flags);
+ ap->ops->tf_read(ap, &qc->tf);
+ spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+ if (qc->tf.command & ATA_ERR) {
/*
* arg! EDD works for all test cases, but seems to return
* the ATA signature for some ATAPI devices. Until the
@@ -1203,7 +1186,7 @@ retry:
* to have this problem.
*/
if ((using_edd) && (qc->tf.command == ATA_CMD_ID_ATA)) {
- u8 err = ata_chk_err(ap);
+ u8 err = qc->tf.feature;
if (err & ATA_ABORTED) {
dev->class = ATA_DEV_ATAPI;
qc->cursg = 0;
@@ -2572,19 +2555,12 @@ void ata_qc_prep(struct ata_queued_cmd *qc)
void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
{
- struct scatterlist *sg;
-
qc->flags |= ATA_QCFLAG_SINGLE;
- memset(&qc->sgent, 0, sizeof(qc->sgent));
qc->sg = &qc->sgent;
qc->n_elem = 1;
qc->buf_virt = buf;
-
- sg = qc->sg;
- sg->page = virt_to_page(buf);
- sg->offset = (unsigned long) buf & ~PAGE_MASK;
- sg->length = buflen;
+ sg_init_one(qc->sg, buf, buflen);
}
/**
@@ -2687,7 +2663,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
* None. (grabs host lock)
*/
-void ata_poll_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
+void ata_poll_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
{
struct ata_port *ap = qc->ap;
unsigned long flags;
@@ -2695,7 +2671,7 @@ void ata_poll_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
spin_lock_irqsave(&ap->host_set->lock, flags);
ap->flags &= ~ATA_FLAG_NOINTR;
ata_irq_on(ap);
- ata_qc_complete(qc, drv_stat);
+ ata_qc_complete(qc, err_mask);
spin_unlock_irqrestore(&ap->host_set->lock, flags);
}
@@ -2792,7 +2768,7 @@ static int ata_pio_complete (struct ata_port *ap)
ap->hsm_task_state = HSM_ST_IDLE;
- ata_poll_qc_complete(qc, drv_stat);
+ ata_poll_qc_complete(qc, 0);
/* another command may start at this point */
@@ -3160,18 +3136,15 @@ static void ata_pio_block(struct ata_port *ap)
static void ata_pio_error(struct ata_port *ap)
{
struct ata_queued_cmd *qc;
- u8 drv_stat;
+
+ printk(KERN_WARNING "ata%u: PIO error\n", ap->id);
qc = ata_qc_from_tag(ap, ap->active_tag);
assert(qc != NULL);
- drv_stat = ata_chk_status(ap);
- printk(KERN_WARNING "ata%u: PIO error, drv_stat 0x%x\n",
- ap->id, drv_stat);
-
ap->hsm_task_state = HSM_ST_IDLE;
- ata_poll_qc_complete(qc, drv_stat | ATA_ERR);
+ ata_poll_qc_complete(qc, AC_ERR_ATA_BUS);
}
static void ata_pio_task(void *_data)
@@ -3294,7 +3267,7 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc)
ap->id, qc->tf.command, drv_stat, host_stat);
/* complete taskfile transaction */
- ata_qc_complete(qc, drv_stat);
+ ata_qc_complete(qc, ac_err_mask(drv_stat));
break;
}
@@ -3399,7 +3372,7 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
return qc;
}
-int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat)
+int ata_qc_complete_noop(struct ata_queued_cmd *qc, unsigned int err_mask)
{
return 0;
}
@@ -3458,7 +3431,7 @@ void ata_qc_free(struct ata_queued_cmd *qc)
* spin_lock_irqsave(host_set lock)
*/
-void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
+void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
{
int rc;
@@ -3475,7 +3448,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
qc->flags &= ~ATA_QCFLAG_ACTIVE;
/* call completion callback */
- rc = qc->complete_fn(qc, drv_stat);
+ rc = qc->complete_fn(qc, err_mask);
/* if callback indicates not to complete command (non-zero),
* return immediately
@@ -3913,7 +3886,7 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
ap->ops->irq_clear(ap);
/* complete taskfile transaction */
- ata_qc_complete(qc, status);
+ ata_qc_complete(qc, ac_err_mask(status));
break;
default:
@@ -4008,7 +3981,7 @@ static void atapi_packet_task(void *_data)
/* sleep-wait for BSY to clear */
DPRINTK("busy wait\n");
if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB))
- goto err_out;
+ goto err_out_status;
/* make sure DRQ is set */
status = ata_chk_status(ap);
@@ -4045,8 +4018,10 @@ static void atapi_packet_task(void *_data)
return;
+err_out_status:
+ status = ata_chk_status(ap);
err_out:
- ata_poll_qc_complete(qc, ATA_ERR);
+ ata_poll_qc_complete(qc, __ac_err_mask(status));
}
@@ -4254,11 +4229,10 @@ int ata_device_add(const struct ata_probe_ent *ent)
DPRINTK("ENTER\n");
/* alloc a container for our list of ATA ports (buses) */
- host_set = kmalloc(sizeof(struct ata_host_set) +
+ host_set = kzalloc(sizeof(struct ata_host_set) +
(ent->n_ports * sizeof(void *)), GFP_KERNEL);
if (!host_set)
return 0;
- memset(host_set, 0, sizeof(struct ata_host_set) + (ent->n_ports * sizeof(void *)));
spin_lock_init(&host_set->lock);
host_set->dev = dev;
@@ -4298,10 +4272,8 @@ int ata_device_add(const struct ata_probe_ent *ent)
count++;
}
- if (!count) {
- kfree(host_set);
- return 0;
- }
+ if (!count)
+ goto err_free_ret;
/* obtain irq, that is shared between channels */
if (request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags,
@@ -4359,6 +4331,7 @@ err_out:
ata_host_remove(host_set->ports[i], 1);
scsi_host_put(host_set->ports[i]->host);
}
+err_free_ret:
kfree(host_set);
VPRINTK("EXIT, returning 0\n");
return 0;
@@ -4468,15 +4441,13 @@ ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port)
{
struct ata_probe_ent *probe_ent;
- probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
+ probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
if (!probe_ent) {
printk(KERN_ERR DRV_NAME "(%s): out of memory\n",
kobject_name(&(dev->kobj)));
return NULL;
}
- memset(probe_ent, 0, sizeof(*probe_ent));
-
INIT_LIST_HEAD(&probe_ent->node);
probe_ent->dev = dev;
@@ -4556,11 +4527,11 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int
return probe_ent;
}
-static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, struct ata_port_info **port, int port_num)
+static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, struct ata_port_info *port, int port_num)
{
struct ata_probe_ent *probe_ent;
- probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
+ probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port);
if (!probe_ent)
return NULL;
@@ -4707,9 +4678,9 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
if (legacy_mode) {
if (legacy_mode & (1 << 0))
- probe_ent = ata_pci_init_legacy_port(pdev, port, 0);
+ probe_ent = ata_pci_init_legacy_port(pdev, port[0], 0);
if (legacy_mode & (1 << 1))
- probe_ent2 = ata_pci_init_legacy_port(pdev, port, 1);
+ probe_ent2 = ata_pci_init_legacy_port(pdev, port[1], 1);
} else {
if (n_ports == 2)
probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
@@ -4873,7 +4844,6 @@ EXPORT_SYMBOL_GPL(ata_tf_to_fis);
EXPORT_SYMBOL_GPL(ata_tf_from_fis);
EXPORT_SYMBOL_GPL(ata_check_status);
EXPORT_SYMBOL_GPL(ata_altstatus);
-EXPORT_SYMBOL_GPL(ata_chk_err);
EXPORT_SYMBOL_GPL(ata_exec_command);
EXPORT_SYMBOL_GPL(ata_port_start);
EXPORT_SYMBOL_GPL(ata_port_stop);
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index 58858886d751..1e3792f86fcf 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -40,14 +40,56 @@
#include "scsi.h"
#include <scsi/scsi_host.h>
#include <linux/libata.h>
+#include <linux/hdreg.h>
#include <asm/uaccess.h>
#include "libata.h"
+#define SECTOR_SIZE 512
+
typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, const u8 *scsicmd);
static struct ata_device *
ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev);
+#define RW_RECOVERY_MPAGE 0x1
+#define RW_RECOVERY_MPAGE_LEN 12
+#define CACHE_MPAGE 0x8
+#define CACHE_MPAGE_LEN 20
+#define CONTROL_MPAGE 0xa
+#define CONTROL_MPAGE_LEN 12
+#define ALL_MPAGES 0x3f
+#define ALL_SUB_MPAGES 0xff
+
+
+static const u8 def_rw_recovery_mpage[] = {
+ RW_RECOVERY_MPAGE,
+ RW_RECOVERY_MPAGE_LEN - 2,
+ (1 << 7) | /* AWRE, sat-r06 say it shall be 0 */
+ (1 << 6), /* ARRE (auto read reallocation) */
+ 0, /* read retry count */
+ 0, 0, 0, 0,
+ 0, /* write retry count */
+ 0, 0, 0
+};
+
+static const u8 def_cache_mpage[CACHE_MPAGE_LEN] = {
+ CACHE_MPAGE,
+ CACHE_MPAGE_LEN - 2,
+ 0, /* contains WCE, needs to be 0 for logic */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, /* contains DRA, needs to be 0 for logic */
+ 0, 0, 0, 0, 0, 0, 0
+};
+
+static const u8 def_control_mpage[CONTROL_MPAGE_LEN] = {
+ CONTROL_MPAGE,
+ CONTROL_MPAGE_LEN - 2,
+ 2, /* DSENSE=0, GLTSD=1 */
+ 0, /* [QAM+QERR may be 1, see 05-359r1] */
+ 0, 0, 0, 0, 0xff, 0xff,
+ 0, 30 /* extended self test time, see 05-359r1 */
+};
+
static void ata_scsi_invalid_field(struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *))
@@ -86,6 +128,150 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
return 0;
}
+/**
+ * ata_cmd_ioctl - Handler for HDIO_DRIVE_CMD ioctl
+ * @dev: Device to whom we are issuing command
+ * @arg: User provided data for issuing command
+ *
+ * LOCKING:
+ * Defined by the SCSI layer. We don't really care.
+ *
+ * RETURNS:
+ * Zero on success, negative errno on error.
+ */
+
+int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
+{
+ int rc = 0;
+ u8 scsi_cmd[MAX_COMMAND_SIZE];
+ u8 args[4], *argbuf = NULL;
+ int argsize = 0;
+ struct scsi_request *sreq;
+
+ if (NULL == (void *)arg)
+ return -EINVAL;
+
+ if (copy_from_user(args, arg, sizeof(args)))
+ return -EFAULT;
+
+ sreq = scsi_allocate_request(scsidev, GFP_KERNEL);
+ if (!sreq)
+ return -EINTR;
+
+ memset(scsi_cmd, 0, sizeof(scsi_cmd));
+
+ if (args[3]) {
+ argsize = SECTOR_SIZE * args[3];
+ argbuf = kmalloc(argsize, GFP_KERNEL);
+ if (argbuf == NULL) {
+ rc = -ENOMEM;
+ goto error;
+ }
+
+ scsi_cmd[1] = (4 << 1); /* PIO Data-in */
+ scsi_cmd[2] = 0x0e; /* no off.line or cc, read from dev,
+ block count in sector count field */
+ sreq->sr_data_direction = DMA_FROM_DEVICE;
+ } else {
+ scsi_cmd[1] = (3 << 1); /* Non-data */
+ /* scsi_cmd[2] is already 0 -- no off.line, cc, or data xfer */
+ sreq->sr_data_direction = DMA_NONE;
+ }
+
+ scsi_cmd[0] = ATA_16;
+
+ scsi_cmd[4] = args[2];
+ if (args[0] == WIN_SMART) { /* hack -- ide driver does this too... */
+ scsi_cmd[6] = args[3];
+ scsi_cmd[8] = args[1];
+ scsi_cmd[10] = 0x4f;
+ scsi_cmd[12] = 0xc2;
+ } else {
+ scsi_cmd[6] = args[1];
+ }
+ scsi_cmd[14] = args[0];
+
+ /* Good values for timeout and retries? Values below
+ from scsi_ioctl_send_command() for default case... */
+ scsi_wait_req(sreq, scsi_cmd, argbuf, argsize, (10*HZ), 5);
+
+ if (sreq->sr_result) {
+ rc = -EIO;
+ goto error;
+ }
+
+ /* Need code to retrieve data from check condition? */
+
+ if ((argbuf)
+ && copy_to_user((void *)(arg + sizeof(args)), argbuf, argsize))
+ rc = -EFAULT;
+error:
+ scsi_release_request(sreq);
+
+ if (argbuf)
+ kfree(argbuf);
+
+ return rc;
+}
+
+/**
+ * ata_task_ioctl - Handler for HDIO_DRIVE_TASK ioctl
+ * @dev: Device to whom we are issuing command
+ * @arg: User provided data for issuing command
+ *
+ * LOCKING:
+ * Defined by the SCSI layer. We don't really care.
+ *
+ * RETURNS:
+ * Zero on success, negative errno on error.
+ */
+int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
+{
+ int rc = 0;
+ u8 scsi_cmd[MAX_COMMAND_SIZE];
+ u8 args[7];
+ struct scsi_request *sreq;
+
+ if (NULL == (void *)arg)
+ return -EINVAL;
+
+ if (copy_from_user(args, arg, sizeof(args)))
+ return -EFAULT;
+
+ memset(scsi_cmd, 0, sizeof(scsi_cmd));
+ scsi_cmd[0] = ATA_16;
+ scsi_cmd[1] = (3 << 1); /* Non-data */
+ /* scsi_cmd[2] is already 0 -- no off.line, cc, or data xfer */
+ scsi_cmd[4] = args[1];
+ scsi_cmd[6] = args[2];
+ scsi_cmd[8] = args[3];
+ scsi_cmd[10] = args[4];
+ scsi_cmd[12] = args[5];
+ scsi_cmd[14] = args[0];
+
+ sreq = scsi_allocate_request(scsidev, GFP_KERNEL);
+ if (!sreq) {
+ rc = -EINTR;
+ goto error;
+ }
+
+ sreq->sr_data_direction = DMA_NONE;
+ /* Good values for timeout and retries? Values below
+ from scsi_ioctl_send_command() for default case... */
+ scsi_wait_req(sreq, scsi_cmd, NULL, 0, (10*HZ), 5);
+
+ if (sreq->sr_result) {
+ rc = -EIO;
+ goto error;
+ }
+
+ /* Need code to retrieve data from check condition? */
+
+error:
+ scsi_release_request(sreq);
+ return rc;
+}
+
int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg)
{
struct ata_port *ap;
@@ -115,6 +301,16 @@ int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg)
return -EINVAL;
return 0;
+ case HDIO_DRIVE_CMD:
+ if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
+ return -EACCES;
+ return ata_cmd_ioctl(scsidev, arg);
+
+ case HDIO_DRIVE_TASK:
+ if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
+ return -EACCES;
+ return ata_task_ioctl(scsidev, arg);
+
default:
rc = -ENOTTY;
break;
@@ -173,23 +369,70 @@ struct ata_queued_cmd *ata_scsi_qc_new(struct ata_port *ap,
}
/**
+ * ata_dump_status - user friendly display of error info
+ * @id: id of the port in question
+ * @tf: ptr to filled out taskfile
+ *
+ * Decode and dump the ATA error/status registers for the user so
+ * that they have some idea what really happened at the non
+ * make-believe layer.
+ *
+ * LOCKING:
+ * inherited from caller
+ */
+void ata_dump_status(unsigned id, struct ata_taskfile *tf)
+{
+ u8 stat = tf->command, err = tf->feature;
+
+ printk(KERN_WARNING "ata%u: status=0x%02x { ", id, stat);
+ if (stat & ATA_BUSY) {
+ printk("Busy }\n"); /* Data is not valid in this case */
+ } else {
+ if (stat & 0x40) printk("DriveReady ");
+ if (stat & 0x20) printk("DeviceFault ");
+ if (stat & 0x10) printk("SeekComplete ");
+ if (stat & 0x08) printk("DataRequest ");
+ if (stat & 0x04) printk("CorrectedError ");
+ if (stat & 0x02) printk("Index ");
+ if (stat & 0x01) printk("Error ");
+ printk("}\n");
+
+ if (err) {
+ printk(KERN_WARNING "ata%u: error=0x%02x { ", id, err);
+ if (err & 0x04) printk("DriveStatusError ");
+ if (err & 0x80) {
+ if (err & 0x04) printk("BadCRC ");
+ else printk("Sector ");
+ }
+ if (err & 0x40) printk("UncorrectableError ");
+ if (err & 0x10) printk("SectorIdNotFound ");
+ if (err & 0x02) printk("TrackZeroNotFound ");
+ if (err & 0x01) printk("AddrMarkNotFound ");
+ printk("}\n");
+ }
+ }
+}
+
+/**
* ata_to_sense_error - convert ATA error to SCSI error
- * @qc: Command that we are erroring out
* @drv_stat: value contained in ATA status register
+ * @drv_err: value contained in ATA error register
+ * @sk: the sense key we'll fill out
+ * @asc: the additional sense code we'll fill out
+ * @ascq: the additional sense code qualifier we'll fill out
*
- * Converts an ATA error into a SCSI error. While we are at it
- * we decode and dump the ATA error for the user so that they
- * have some idea what really happened at the non make-believe
- * layer.
+ * Converts an ATA error into a SCSI error. Fill out pointers to
+ * SK, ASC, and ASCQ bytes for later use in fixed or descriptor
+ * format sense blocks.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
*/
-
-void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat)
+void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc,
+ u8 *ascq)
{
- struct scsi_cmnd *cmd = qc->scsicmd;
- u8 err = 0;
+ int i;
+
/* Based on the 3ware driver translation table */
static unsigned char sense_table[][4] = {
/* BBD|ECC|ID|MAR */
@@ -230,96 +473,192 @@ void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat)
{0x04, RECOVERED_ERROR, 0x11, 0x00}, // Recovered ECC error Medium error, recovered
{0xFF, 0xFF, 0xFF, 0xFF}, // END mark
};
- int i = 0;
/*
* Is this an error we can process/parse
*/
+ if (drv_stat & ATA_BUSY) {
+ drv_err = 0; /* Ignore the err bits, they're invalid */
+ }
- if(drv_stat & ATA_ERR)
- /* Read the err bits */
- err = ata_chk_err(qc->ap);
+ if (drv_err) {
+ /* Look for drv_err */
+ for (i = 0; sense_table[i][0] != 0xFF; i++) {
+ /* Look for best matches first */
+ if ((sense_table[i][0] & drv_err) ==
+ sense_table[i][0]) {
+ *sk = sense_table[i][1];
+ *asc = sense_table[i][2];
+ *ascq = sense_table[i][3];
+ goto translate_done;
+ }
+ }
+ /* No immediate match */
+ printk(KERN_WARNING "ata%u: no sense translation for "
+ "error 0x%02x\n", id, drv_err);
+ }
- /* Display the ATA level error info */
+ /* Fall back to interpreting status bits */
+ for (i = 0; stat_table[i][0] != 0xFF; i++) {
+ if (stat_table[i][0] & drv_stat) {
+ *sk = stat_table[i][1];
+ *asc = stat_table[i][2];
+ *ascq = stat_table[i][3];
+ goto translate_done;
+ }
+ }
+ /* No error? Undecoded? */
+ printk(KERN_WARNING "ata%u: no sense translation for status: 0x%02x\n",
+ id, drv_stat);
- printk(KERN_WARNING "ata%u: status=0x%02x { ", qc->ap->id, drv_stat);
- if(drv_stat & 0x80)
- {
- printk("Busy ");
- err = 0; /* Data is not valid in this case */
+ /* For our last chance pick, use medium read error because
+ * it's much more common than an ATA drive telling you a write
+ * has failed.
+ */
+ *sk = MEDIUM_ERROR;
+ *asc = 0x11; /* "unrecovered read error" */
+ *ascq = 0x04; /* "auto-reallocation failed" */
+
+ translate_done:
+ printk(KERN_ERR "ata%u: translated ATA stat/err 0x%02x/%02x to "
+ "SCSI SK/ASC/ASCQ 0x%x/%02x/%02x\n", id, drv_stat, drv_err,
+ *sk, *asc, *ascq);
+ return;
+}
+
+/*
+ * ata_gen_ata_desc_sense - Generate check condition sense block.
+ * @qc: Command that completed.
+ *
+ * This function is specific to the ATA descriptor format sense
+ * block specified for the ATA pass through commands. Regardless
+ * of whether the command errored or not, return a sense
+ * block. Copy all controller registers into the sense
+ * block. Clear sense key, ASC & ASCQ if there is no error.
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host_set lock)
+ */
+void ata_gen_ata_desc_sense(struct ata_queued_cmd *qc)
+{
+ struct scsi_cmnd *cmd = qc->scsicmd;
+ struct ata_taskfile *tf = &qc->tf;
+ unsigned char *sb = cmd->sense_buffer;
+ unsigned char *desc = sb + 8;
+
+ memset(sb, 0, SCSI_SENSE_BUFFERSIZE);
+
+ cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
+
+ /*
+ * Read the controller registers.
+ */
+ assert(NULL != qc->ap->ops->tf_read);
+ qc->ap->ops->tf_read(qc->ap, tf);
+
+ /*
+ * Use ata_to_sense_error() to map status register bits
+ * onto sense key, asc & ascq.
+ */
+ if (tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
+ ata_to_sense_error(qc->ap->id, tf->command, tf->feature,
+ &sb[1], &sb[2], &sb[3]);
+ sb[1] &= 0x0f;
}
- else {
- if(drv_stat & 0x40) printk("DriveReady ");
- if(drv_stat & 0x20) printk("DeviceFault ");
- if(drv_stat & 0x10) printk("SeekComplete ");
- if(drv_stat & 0x08) printk("DataRequest ");
- if(drv_stat & 0x04) printk("CorrectedError ");
- if(drv_stat & 0x02) printk("Index ");
- if(drv_stat & 0x01) printk("Error ");
+
+ /*
+ * Sense data is current and format is descriptor.
+ */
+ sb[0] = 0x72;
+
+ desc[0] = 0x09;
+
+ /*
+ * Set length of additional sense data.
+ * Since we only populate descriptor 0, the total
+ * length is the same (fixed) length as descriptor 0.
+ */
+ desc[1] = sb[7] = 14;
+
+ /*
+ * Copy registers into sense buffer.
+ */
+ desc[2] = 0x00;
+ desc[3] = tf->feature; /* == error reg */
+ desc[5] = tf->nsect;
+ desc[7] = tf->lbal;
+ desc[9] = tf->lbam;
+ desc[11] = tf->lbah;
+ desc[12] = tf->device;
+ desc[13] = tf->command; /* == status reg */
+
+ /*
+ * Fill in Extend bit, and the high order bytes
+ * if applicable.
+ */
+ if (tf->flags & ATA_TFLAG_LBA48) {
+ desc[2] |= 0x01;
+ desc[4] = tf->hob_nsect;
+ desc[6] = tf->hob_lbal;
+ desc[8] = tf->hob_lbam;
+ desc[10] = tf->hob_lbah;
}
- printk("}\n");
-
- if(err)
- {
- printk(KERN_WARNING "ata%u: error=0x%02x { ", qc->ap->id, err);
- if(err & 0x04) printk("DriveStatusError ");
- if(err & 0x80)
- {
- if(err & 0x04)
- printk("BadCRC ");
- else
- printk("Sector ");
- }
- if(err & 0x40) printk("UncorrectableError ");
- if(err & 0x10) printk("SectorIdNotFound ");
- if(err & 0x02) printk("TrackZeroNotFound ");
- if(err & 0x01) printk("AddrMarkNotFound ");
- printk("}\n");
+}
- /* Should we dump sector info here too ?? */
+/**
+ * ata_gen_fixed_sense - generate a SCSI fixed sense block
+ * @qc: Command that we are erroring out
+ *
+ * Leverage ata_to_sense_error() to give us the codes. Fit our
+ * LBA in here if there's room.
+ *
+ * LOCKING:
+ * inherited from caller
+ */
+void ata_gen_fixed_sense(struct ata_queued_cmd *qc)
+{
+ struct scsi_cmnd *cmd = qc->scsicmd;
+ struct ata_taskfile *tf = &qc->tf;
+ unsigned char *sb = cmd->sense_buffer;
+
+ memset(sb, 0, SCSI_SENSE_BUFFERSIZE);
+
+ cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
+
+ /*
+ * Read the controller registers.
+ */
+ assert(NULL != qc->ap->ops->tf_read);
+ qc->ap->ops->tf_read(qc->ap, tf);
+
+ /*
+ * Use ata_to_sense_error() to map status register bits
+ * onto sense key, asc & ascq.
+ */
+ if (tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
+ ata_to_sense_error(qc->ap->id, tf->command, tf->feature,
+ &sb[2], &sb[12], &sb[13]);
+ sb[2] &= 0x0f;
}
+ sb[0] = 0x70;
+ sb[7] = 0x0a;
- /* Look for err */
- while(sense_table[i][0] != 0xFF)
- {
- /* Look for best matches first */
- if((sense_table[i][0] & err) == sense_table[i][0])
- {
- ata_scsi_set_sense(cmd, sense_table[i][1] /* sk */,
- sense_table[i][2] /* asc */,
- sense_table[i][3] /* ascq */ );
- return;
- }
- i++;
+ if (tf->flags & ATA_TFLAG_LBA48) {
+ /* TODO: find solution for LBA48 descriptors */
}
- /* No immediate match */
- if(err)
- printk(KERN_DEBUG "ata%u: no sense translation for 0x%02x\n", qc->ap->id, err);
- i = 0;
- /* Fall back to interpreting status bits */
- while(stat_table[i][0] != 0xFF)
- {
- if(stat_table[i][0] & drv_stat)
- {
- ata_scsi_set_sense(cmd, sense_table[i][1] /* sk */,
- sense_table[i][2] /* asc */,
- sense_table[i][3] /* ascq */ );
- return;
- }
- i++;
+ else if (tf->flags & ATA_TFLAG_LBA) {
+ /* A small (28b) LBA will fit in the 32b info field */
+ sb[0] |= 0x80; /* set valid bit */
+ sb[3] = tf->device & 0x0f;
+ sb[4] = tf->lbah;
+ sb[5] = tf->lbam;
+ sb[6] = tf->lbal;
}
- /* No error ?? */
- printk(KERN_ERR "ata%u: called with no error (%02X)!\n", qc->ap->id, drv_stat);
- /* additional-sense-code[-qualifier] */
- if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
- ata_scsi_set_sense(cmd, MEDIUM_ERROR, 0x11, 0x4);
- /* "unrecovered read error" */
- } else {
- ata_scsi_set_sense(cmd, MEDIUM_ERROR, 0xc, 0x2);
- /* "write error - auto-reallocation failed" */
+ else {
+ /* TODO: C/H/S */
}
}
@@ -868,14 +1207,41 @@ nothing_to_do:
return 1;
}
-static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
+static int ata_scsi_qc_complete(struct ata_queued_cmd *qc,
+ unsigned int err_mask)
{
struct scsi_cmnd *cmd = qc->scsicmd;
+ u8 *cdb = cmd->cmnd;
+ int need_sense = (err_mask != 0);
+
+ /* For ATA pass thru (SAT) commands, generate a sense block if
+ * user mandated it or if there's an error. Note that if we
+ * generate because the user forced us to, a check condition
+ * is generated and the ATA register values are returned
+ * whether the command completed successfully or not. If there
+ * was no error, SK, ASC and ASCQ will all be zero.
+ */
+ if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) &&
+ ((cdb[2] & 0x20) || need_sense)) {
+ ata_gen_ata_desc_sense(qc);
+ } else {
+ if (!need_sense) {
+ cmd->result = SAM_STAT_GOOD;
+ } else {
+ /* TODO: decide which descriptor format to use
+ * for 48b LBA devices and call that here
+ * instead of the fixed desc, which is only
+ * good for smaller LBA (and maybe CHS?)
+ * devices.
+ */
+ ata_gen_fixed_sense(qc);
+ }
+ }
- if (unlikely(drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ)))
- ata_to_sense_error(qc, drv_stat);
- else
- cmd->result = SAM_STAT_GOOD;
+ if (need_sense) {
+ /* The ata_gen_..._sense routines fill in tf */
+ ata_dump_status(qc->ap->id, &qc->tf);
+ }
qc->scsidone(cmd);
@@ -1266,13 +1632,9 @@ static void ata_msense_push(u8 **ptr_io, const u8 *last,
static unsigned int ata_msense_caching(u16 *id, u8 **ptr_io,
const u8 *last)
{
- u8 page[] = {
- 0x8, /* page code */
- 0x12, /* page length */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 zeroes */
- 0, 0, 0, 0, 0, 0, 0, 0 /* 8 zeroes */
- };
+ u8 page[CACHE_MPAGE_LEN];
+ memcpy(page, def_cache_mpage, sizeof(page));
if (ata_id_wcache_enabled(id))
page[2] |= (1 << 2); /* write cache enable */
if (!ata_id_rahead_enabled(id))
@@ -1296,15 +1658,9 @@ static unsigned int ata_msense_caching(u16 *id, u8 **ptr_io,
static unsigned int ata_msense_ctl_mode(u8 **ptr_io, const u8 *last)
{
- const u8 page[] = {0xa, 0xa, 6, 0, 0, 0, 0, 0, 0xff, 0xff, 0, 30};
-
- /* byte 2: set the descriptor format sense data bit (bit 2)
- * since we need to support returning this format for SAT
- * commands and any SCSI commands against a 48b LBA device.
- */
-
- ata_msense_push(ptr_io, last, page, sizeof(page));
- return sizeof(page);
+ ata_msense_push(ptr_io, last, def_control_mpage,
+ sizeof(def_control_mpage));
+ return sizeof(def_control_mpage);
}
/**
@@ -1321,15 +1677,10 @@ static unsigned int ata_msense_ctl_mode(u8 **ptr_io, const u8 *last)
static unsigned int ata_msense_rw_recovery(u8 **ptr_io, const u8 *last)
{
- const u8 page[] = {
- 0x1, /* page code */
- 0xa, /* page length */
- (1 << 7) | (1 << 6), /* note auto r/w reallocation */
- 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 9 zeroes */
- };
- ata_msense_push(ptr_io, last, page, sizeof(page));
- return sizeof(page);
+ ata_msense_push(ptr_io, last, def_rw_recovery_mpage,
+ sizeof(def_rw_recovery_mpage));
+ return sizeof(def_rw_recovery_mpage);
}
/**
@@ -1338,7 +1689,9 @@ static unsigned int ata_msense_rw_recovery(u8 **ptr_io, const u8 *last)
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
* @buflen: Response buffer length.
*
- * Simulate MODE SENSE commands.
+ * Simulate MODE SENSE commands. Assume this is invoked for direct
+ * access devices (e.g. disks) only. There should be no block
+ * descriptor for other device types.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
@@ -1348,15 +1701,22 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf,
unsigned int buflen)
{
u8 *scsicmd = args->cmd->cmnd, *p, *last;
- unsigned int page_control, six_byte, output_len;
+ const u8 sat_blk_desc[] = {
+ 0, 0, 0, 0, /* number of blocks: sat unspecified */
+ 0,
+ 0, 0x2, 0x0 /* block length: 512 bytes */
+ };
+ u8 pg, spg;
+ unsigned int ebd, page_control, six_byte, output_len, alloc_len, minlen;
VPRINTK("ENTER\n");
six_byte = (scsicmd[0] == MODE_SENSE);
-
- /* we only support saved and current values (which we treat
- * in the same manner)
+ ebd = !(scsicmd[1] & 0x8); /* dbd bit inverted == edb */
+ /*
+ * LLBA bit in msense(10) ignored (compliant)
*/
+
page_control = scsicmd[2] >> 6;
switch (page_control) {
case 0: /* current */
@@ -1369,29 +1729,42 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf,
goto invalid_fld;
}
- if (six_byte)
- output_len = 4;
- else
- output_len = 8;
+ if (six_byte) {
+ output_len = 4 + (ebd ? 8 : 0);
+ alloc_len = scsicmd[4];
+ } else {
+ output_len = 8 + (ebd ? 8 : 0);
+ alloc_len = (scsicmd[7] << 8) + scsicmd[8];
+ }
+ minlen = (alloc_len < buflen) ? alloc_len : buflen;
p = rbuf + output_len;
- last = rbuf + buflen - 1;
+ last = rbuf + minlen - 1;
- switch(scsicmd[2] & 0x3f) {
- case 0x01: /* r/w error recovery */
+ pg = scsicmd[2] & 0x3f;
+ spg = scsicmd[3];
+ /*
+ * No mode subpages supported (yet) but asking for _all_
+ * subpages may be valid
+ */
+ if (spg && (spg != ALL_SUB_MPAGES))
+ goto invalid_fld;
+
+ switch(pg) {
+ case RW_RECOVERY_MPAGE:
output_len += ata_msense_rw_recovery(&p, last);
break;
- case 0x08: /* caching */
+ case CACHE_MPAGE:
output_len += ata_msense_caching(args->id, &p, last);
break;
- case 0x0a: { /* control mode */
+ case CONTROL_MPAGE: {
output_len += ata_msense_ctl_mode(&p, last);
break;
}
- case 0x3f: /* all pages */
+ case ALL_MPAGES:
output_len += ata_msense_rw_recovery(&p, last);
output_len += ata_msense_caching(args->id, &p, last);
output_len += ata_msense_ctl_mode(&p, last);
@@ -1401,15 +1774,31 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf,
goto invalid_fld;
}
+ if (minlen < 1)
+ return 0;
if (six_byte) {
output_len--;
rbuf[0] = output_len;
+ if (ebd) {
+ if (minlen > 3)
+ rbuf[3] = sizeof(sat_blk_desc);
+ if (minlen > 11)
+ memcpy(rbuf + 4, sat_blk_desc,
+ sizeof(sat_blk_desc));
+ }
} else {
output_len -= 2;
rbuf[0] = output_len >> 8;
- rbuf[1] = output_len;
+ if (minlen > 1)
+ rbuf[1] = output_len;
+ if (ebd) {
+ if (minlen > 7)
+ rbuf[7] = sizeof(sat_blk_desc);
+ if (minlen > 15)
+ memcpy(rbuf + 8, sat_blk_desc,
+ sizeof(sat_blk_desc));
+ }
}
-
return 0;
invalid_fld:
@@ -1616,16 +2005,13 @@ void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
DPRINTK("EXIT\n");
}
-static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
+static int atapi_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
{
struct scsi_cmnd *cmd = qc->scsicmd;
- VPRINTK("ENTER, drv_stat == 0x%x\n", drv_stat);
-
- if (unlikely(drv_stat & (ATA_BUSY | ATA_DRQ)))
- ata_to_sense_error(qc, drv_stat);
+ VPRINTK("ENTER, err_mask 0x%X\n", err_mask);
- else if (unlikely(drv_stat & ATA_ERR)) {
+ if (unlikely(err_mask & AC_ERR_DEV)) {
DPRINTK("request check condition\n");
/* FIXME: command completion with check condition
@@ -1642,6 +2028,14 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
return 1;
}
+ else if (unlikely(err_mask))
+ /* FIXME: not quite right; we don't want the
+ * translation of taskfile registers into
+ * a sense descriptors, since that's only
+ * correct for ATA, not ATAPI
+ */
+ ata_gen_ata_desc_sense(qc);
+
else {
u8 *scsicmd = cmd->cmnd;
@@ -1782,6 +2176,143 @@ ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev)
return dev;
}
+/*
+ * ata_scsi_map_proto - Map pass-thru protocol value to taskfile value.
+ * @byte1: Byte 1 from pass-thru CDB.
+ *
+ * RETURNS:
+ * ATA_PROT_UNKNOWN if mapping failed/unimplemented, protocol otherwise.
+ */
+static u8
+ata_scsi_map_proto(u8 byte1)
+{
+ switch((byte1 & 0x1e) >> 1) {
+ case 3: /* Non-data */
+ return ATA_PROT_NODATA;
+
+ case 6: /* DMA */
+ return ATA_PROT_DMA;
+
+ case 4: /* PIO Data-in */
+ case 5: /* PIO Data-out */
+ if (byte1 & 0xe0) {
+ return ATA_PROT_PIO_MULT;
+ }
+ return ATA_PROT_PIO;
+
+ case 10: /* Device Reset */
+ case 0: /* Hard Reset */
+ case 1: /* SRST */
+ case 2: /* Bus Idle */
+ case 7: /* Packet */
+ case 8: /* DMA Queued */
+ case 9: /* Device Diagnostic */
+ case 11: /* UDMA Data-in */
+ case 12: /* UDMA Data-Out */
+ case 13: /* FPDMA */
+ default: /* Reserved */
+ break;
+ }
+
+ return ATA_PROT_UNKNOWN;
+}
+
+/**
+ * ata_scsi_pass_thru - convert ATA pass-thru CDB to taskfile
+ * @qc: command structure to be initialized
+ * @cmd: SCSI command to convert
+ *
+ * Handles either 12 or 16-byte versions of the CDB.
+ *
+ * RETURNS:
+ * Zero on success, non-zero on failure.
+ */
+static unsigned int
+ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
+{
+ struct ata_taskfile *tf = &(qc->tf);
+ struct scsi_cmnd *cmd = qc->scsicmd;
+
+ if ((tf->protocol = ata_scsi_map_proto(scsicmd[1])) == ATA_PROT_UNKNOWN)
+ return 1;
+
+ /*
+ * 12 and 16 byte CDBs use different offsets to
+ * provide the various register values.
+ */
+ if (scsicmd[0] == ATA_16) {
+ /*
+ * 16-byte CDB - may contain extended commands.
+ *
+ * If that is the case, copy the upper byte register values.
+ */
+ if (scsicmd[1] & 0x01) {
+ tf->hob_feature = scsicmd[3];
+ tf->hob_nsect = scsicmd[5];
+ tf->hob_lbal = scsicmd[7];
+ tf->hob_lbam = scsicmd[9];
+ tf->hob_lbah = scsicmd[11];
+ tf->flags |= ATA_TFLAG_LBA48;
+ } else
+ tf->flags &= ~ATA_TFLAG_LBA48;
+
+ /*
+ * Always copy low byte, device and command registers.
+ */
+ tf->feature = scsicmd[4];
+ tf->nsect = scsicmd[6];
+ tf->lbal = scsicmd[8];
+ tf->lbam = scsicmd[10];
+ tf->lbah = scsicmd[12];
+ tf->device = scsicmd[13];
+ tf->command = scsicmd[14];
+ } else {
+ /*
+ * 12-byte CDB - incapable of extended commands.
+ */
+ tf->flags &= ~ATA_TFLAG_LBA48;
+
+ tf->feature = scsicmd[3];
+ tf->nsect = scsicmd[4];
+ tf->lbal = scsicmd[5];
+ tf->lbam = scsicmd[6];
+ tf->lbah = scsicmd[7];
+ tf->device = scsicmd[8];
+ tf->command = scsicmd[9];
+ }
+
+ /*
+ * Filter SET_FEATURES - XFER MODE command -- otherwise,
+ * SET_FEATURES - XFER MODE must be preceded/succeeded
+ * by an update to hardware-specific registers for each
+ * controller (i.e. the reason for ->set_piomode(),
+ * ->set_dmamode(), and ->post_set_mode() hooks).
+ */
+ if ((tf->command == ATA_CMD_SET_FEATURES)
+ && (tf->feature == SETFEATURES_XFER))
+ return 1;
+
+ /*
+ * Set flags so that all registers will be written,
+ * and pass on write indication (used for PIO/DMA
+ * setup.)
+ */
+ tf->flags |= (ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE);
+
+ if (cmd->sc_data_direction == DMA_TO_DEVICE)
+ tf->flags |= ATA_TFLAG_WRITE;
+
+ /*
+ * Set transfer length.
+ *
+ * TODO: find out if we need to do more here to
+ * cover scatter/gather case.
+ */
+ qc->nsect = cmd->bufflen / ATA_SECT_SIZE;
+
+ return 0;
+}
+
/**
* ata_get_xlat_func - check if SCSI to ATA translation is possible
* @dev: ATA device
@@ -1814,6 +2345,11 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd)
case VERIFY:
case VERIFY_16:
return ata_scsi_verify_xlat;
+
+ case ATA_12:
+ case ATA_16:
+ return ata_scsi_pass_thru;
+
case START_STOP:
return ata_scsi_start_stop_xlat;
}
@@ -1972,7 +2508,7 @@ void ata_scsi_simulate(u16 *id,
ata_scsi_rbuf_fill(&args, ata_scsiop_report_luns);
break;
- /* mandantory commands we haven't implemented yet */
+ /* mandatory commands we haven't implemented yet */
case REQUEST_SENSE:
/* all other commands */
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h
index 3d60190584ba..10ecd9e15e4f 100644
--- a/drivers/scsi/libata.h
+++ b/drivers/scsi/libata.h
@@ -39,7 +39,7 @@ struct ata_scsi_args {
/* libata-core.c */
extern int atapi_enabled;
-extern int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat);
+extern int ata_qc_complete_noop(struct ata_queued_cmd *qc, unsigned int err_mask);
extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
struct ata_device *dev);
extern void ata_rwcmd_protocol(struct ata_queued_cmd *qc);
@@ -50,13 +50,14 @@ extern void ata_dev_select(struct ata_port *ap, unsigned int device,
unsigned int wait, unsigned int can_sleep);
extern void ata_tf_to_host_nolock(struct ata_port *ap, const struct ata_taskfile *tf);
extern void swap_buf_le16(u16 *buf, unsigned int buf_words);
+extern int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg);
+extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg);
/* libata-scsi.c */
extern void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
struct scsi_cmnd *cmd);
extern void ata_scsi_scan_host(struct ata_port *ap);
-extern void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat);
extern int ata_scsi_error(struct Scsi_Host *host);
extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
unsigned int buflen);
diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c
index b235556b7b65..bdccf73cf9fe 100644
--- a/drivers/scsi/mesh.c
+++ b/drivers/scsi/mesh.c
@@ -730,7 +730,7 @@ static void start_phase(struct mesh_state *ms)
* issue a SEQ_MSGOUT to get the mesh to drop ACK.
*/
if ((in_8(&mr->bus_status0) & BS0_ATN) == 0) {
- dlog(ms, "bus0 was %.2x explictly asserting ATN", mr->bus_status0);
+ dlog(ms, "bus0 was %.2x explicitly asserting ATN", mr->bus_status0);
out_8(&mr->bus_status0, BS0_ATN); /* explicit ATN */
mesh_flush_io(mr);
udelay(1);
diff --git a/drivers/scsi/pdc_adma.c b/drivers/scsi/pdc_adma.c
index 9820f272f889..665017eda8a6 100644
--- a/drivers/scsi/pdc_adma.c
+++ b/drivers/scsi/pdc_adma.c
@@ -40,13 +40,14 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
+#include <linux/device.h>
#include "scsi.h"
#include <scsi/scsi_host.h>
#include <asm/io.h>
#include <linux/libata.h>
#define DRV_NAME "pdc_adma"
-#define DRV_VERSION "0.01"
+#define DRV_VERSION "0.03"
/* macro to calculate base address for ATA regs */
#define ADMA_ATA_REGS(base,port_no) ((base) + ((port_no) * 0x40))
@@ -79,7 +80,6 @@ enum {
aNIEN = (1 << 8), /* irq mask: 1==masked */
aGO = (1 << 7), /* packet trigger ("Go!") */
aRSTADM = (1 << 5), /* ADMA logic reset */
- aRSTA = (1 << 2), /* ATA hard reset */
aPIOMD4 = 0x0003, /* PIO mode 4 */
/* ADMA_STATUS register bits */
@@ -452,24 +452,28 @@ static inline unsigned int adma_intr_pkt(struct ata_host_set *host_set)
struct adma_port_priv *pp;
struct ata_queued_cmd *qc;
void __iomem *chan = ADMA_REGS(mmio_base, port_no);
- u8 drv_stat, status = readb(chan + ADMA_STATUS);
+ u8 status = readb(chan + ADMA_STATUS);
if (status == 0)
continue;
handled = 1;
adma_enter_reg_mode(ap);
- if ((ap->flags & ATA_FLAG_PORT_DISABLED))
+ if (ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))
continue;
pp = ap->private_data;
if (!pp || pp->state != adma_state_pkt)
continue;
qc = ata_qc_from_tag(ap, ap->active_tag);
- drv_stat = 0;
- if ((status & (aPERR | aPSD | aUIRQ)))
- drv_stat = ATA_ERR;
- else if (pp->pkt[0] != cDONE)
- drv_stat = ATA_ERR;
- ata_qc_complete(qc, drv_stat);
+ if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
+ unsigned int err_mask = 0;
+
+ if ((status & (aPERR | aPSD | aUIRQ)))
+ err_mask = AC_ERR_OTHER;
+ else if (pp->pkt[0] != cDONE)
+ err_mask = AC_ERR_OTHER;
+
+ ata_qc_complete(qc, err_mask);
+ }
}
return handled;
}
@@ -490,7 +494,7 @@ static inline unsigned int adma_intr_mmio(struct ata_host_set *host_set)
if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
/* check main status, clearing INTRQ */
- u8 status = ata_chk_status(ap);
+ u8 status = ata_check_status(ap);
if ((status & ATA_BUSY))
continue;
DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n",
@@ -498,7 +502,7 @@ static inline unsigned int adma_intr_mmio(struct ata_host_set *host_set)
/* complete taskfile transaction */
pp->state = adma_state_idle;
- ata_qc_complete(qc, status);
+ ata_qc_complete(qc, ac_err_mask(status));
handled = 1;
}
}
@@ -561,15 +565,15 @@ static int adma_port_start(struct ata_port *ap)
if ((pp->pkt_dma & 7) != 0) {
printk("bad alignment for pp->pkt_dma: %08x\n",
(u32)pp->pkt_dma);
- goto err_out_kfree2;
+ dma_free_coherent(dev, ADMA_PKT_BYTES,
+ pp->pkt, pp->pkt_dma);
+ goto err_out_kfree;
}
memset(pp->pkt, 0, ADMA_PKT_BYTES);
ap->private_data = pp;
adma_reinit_engine(ap);
return 0;
-err_out_kfree2:
- kfree(pp);
err_out_kfree:
kfree(pp);
err_out:
@@ -623,16 +627,14 @@ static int adma_set_dma_masks(struct pci_dev *pdev, void __iomem *mmio_base)
rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
if (rc) {
- printk(KERN_ERR DRV_NAME
- "(%s): 32-bit DMA enable failed\n",
- pci_name(pdev));
+ dev_printk(KERN_ERR, &pdev->dev,
+ "32-bit DMA enable failed\n");
return rc;
}
rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
if (rc) {
- printk(KERN_ERR DRV_NAME
- "(%s): 32-bit consistent DMA enable failed\n",
- pci_name(pdev));
+ dev_printk(KERN_ERR, &pdev->dev,
+ "32-bit consistent DMA enable failed\n");
return rc;
}
return 0;
@@ -648,7 +650,7 @@ static int adma_ata_init_one(struct pci_dev *pdev,
int rc, port_no;
if (!printed_version++)
- printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
rc = pci_enable_device(pdev);
if (rc)
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c
index 422e0b6f603a..46dbdee79f77 100644
--- a/drivers/scsi/sata_mv.c
+++ b/drivers/scsi/sata_mv.c
@@ -29,6 +29,7 @@
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/dma-mapping.h>
+#include <linux/device.h>
#include "scsi.h"
#include <scsi/scsi_host.h>
#include <linux/libata.h>
@@ -258,7 +259,6 @@ struct mv_host_priv {
static void mv_irq_clear(struct ata_port *ap);
static u32 mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in);
static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val);
-static u8 mv_check_err(struct ata_port *ap);
static void mv_phy_reset(struct ata_port *ap);
static void mv_host_stop(struct ata_host_set *host_set);
static int mv_port_start(struct ata_port *ap);
@@ -296,7 +296,6 @@ static const struct ata_port_operations mv_ops = {
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
.check_status = ata_check_status,
- .check_err = mv_check_err,
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
@@ -1067,6 +1066,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
struct ata_queued_cmd *qc;
u32 hc_irq_cause;
int shift, port, port0, hard_port, handled;
+ unsigned int err_mask;
u8 ata_status = 0;
if (hc == 0) {
@@ -1102,15 +1102,15 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
handled++;
}
+ err_mask = ac_err_mask(ata_status);
+
shift = port << 1; /* (port * 2) */
if (port >= MV_PORTS_PER_HC) {
shift++; /* skip bit 8 in the HC Main IRQ reg */
}
if ((PORT0_ERR << shift) & relevant) {
mv_err_intr(ap);
- /* OR in ATA_ERR to ensure libata knows we took one */
- ata_status = readb((void __iomem *)
- ap->ioaddr.status_addr) | ATA_ERR;
+ err_mask |= AC_ERR_OTHER;
handled++;
}
@@ -1120,7 +1120,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
VPRINTK("port %u IRQ found for qc, "
"ata_status 0x%x\n", port,ata_status);
/* mark qc status appropriately */
- ata_qc_complete(qc, ata_status);
+ ata_qc_complete(qc, err_mask);
}
}
}
@@ -1185,22 +1185,6 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance,
}
/**
- * mv_check_err - Return the error shadow register to caller.
- * @ap: ATA channel to manipulate
- *
- * Marvell requires DMA to be stopped before accessing shadow
- * registers. So we do that, then return the needed register.
- *
- * LOCKING:
- * Inherited from caller. FIXME: protect mv_stop_dma with lock?
- */
-static u8 mv_check_err(struct ata_port *ap)
-{
- mv_stop_dma(ap); /* can't read shadow regs if DMA on */
- return readb((void __iomem *) ap->ioaddr.error_addr);
-}
-
-/**
* mv_phy_reset - Perform eDMA reset followed by COMRESET
* @ap: ATA channel to manipulate
*
@@ -1312,7 +1296,7 @@ static void mv_eng_timeout(struct ata_port *ap)
*/
spin_lock_irqsave(&ap->host_set->lock, flags);
qc->scsidone = scsi_finish_command;
- ata_qc_complete(qc, ATA_ERR);
+ ata_qc_complete(qc, AC_ERR_OTHER);
spin_unlock_irqrestore(&ap->host_set->lock, flags);
}
}
@@ -1454,9 +1438,9 @@ static void mv_print_info(struct ata_probe_ent *probe_ent)
else
scc_s = "unknown";
- printk(KERN_INFO DRV_NAME
- "(%s) %u slots %u ports %s mode IRQ via %s\n",
- pci_name(pdev), (unsigned)MV_MAX_Q_DEPTH, probe_ent->n_ports,
+ dev_printk(KERN_INFO, &pdev->dev,
+ "%u slots %u ports %s mode IRQ via %s\n",
+ (unsigned)MV_MAX_Q_DEPTH, probe_ent->n_ports,
scc_s, (MV_HP_FLAG_MSI & hpriv->hp_flags) ? "MSI" : "INTx");
}
@@ -1477,9 +1461,8 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
void __iomem *mmio_base;
int pci_dev_busy = 0, rc;
- if (!printed_version++) {
- printk(KERN_INFO DRV_NAME " version " DRV_VERSION "\n");
- }
+ if (!printed_version++)
+ dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
rc = pci_enable_device(pdev);
if (rc) {
diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c
index 1a56d6c79ddd..d573888eda76 100644
--- a/drivers/scsi/sata_nv.c
+++ b/drivers/scsi/sata_nv.c
@@ -61,6 +61,7 @@
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
+#include <linux/device.h>
#include "scsi.h"
#include <scsi/scsi_host.h>
#include <linux/libata.h>
@@ -383,7 +384,7 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
return -ENODEV;
if (!printed_version++)
- printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
rc = pci_enable_device(pdev);
if (rc)
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
index eee93b0016df..b41c977d6fab 100644
--- a/drivers/scsi/sata_promise.c
+++ b/drivers/scsi/sata_promise.c
@@ -38,6 +38,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
+#include <linux/device.h>
#include "scsi.h"
#include <scsi/scsi_host.h>
#include <linux/libata.h>
@@ -195,6 +196,8 @@ static struct ata_port_info pdc_port_info[] = {
static struct pci_device_id pdc_ata_pci_tbl[] = {
{ PCI_VENDOR_ID_PROMISE, 0x3371, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_2037x },
+ { PCI_VENDOR_ID_PROMISE, 0x3570, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ board_2037x },
{ PCI_VENDOR_ID_PROMISE, 0x3571, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_2037x },
{ PCI_VENDOR_ID_PROMISE, 0x3373, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
@@ -207,6 +210,8 @@ static struct pci_device_id pdc_ata_pci_tbl[] = {
board_2037x },
{ PCI_VENDOR_ID_PROMISE, 0x3d75, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_2037x },
+ { PCI_VENDOR_ID_PROMISE, 0x3d73, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ board_2037x },
{ PCI_VENDOR_ID_PROMISE, 0x3318, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_20319 },
@@ -395,7 +400,8 @@ static void pdc_eng_timeout(struct ata_port *ap)
case ATA_PROT_DMA:
case ATA_PROT_NODATA:
printk(KERN_ERR "ata%u: command timeout\n", ap->id);
- ata_qc_complete(qc, ata_wait_idle(ap) | ATA_ERR);
+ drv_stat = ata_wait_idle(ap);
+ ata_qc_complete(qc, __ac_err_mask(drv_stat));
break;
default:
@@ -404,7 +410,7 @@ static void pdc_eng_timeout(struct ata_port *ap)
printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n",
ap->id, qc->tf.command, drv_stat);
- ata_qc_complete(qc, drv_stat);
+ ata_qc_complete(qc, ac_err_mask(drv_stat));
break;
}
@@ -416,24 +422,21 @@ out:
static inline unsigned int pdc_host_intr( struct ata_port *ap,
struct ata_queued_cmd *qc)
{
- u8 status;
- unsigned int handled = 0, have_err = 0;
+ unsigned int handled = 0, err_mask = 0;
u32 tmp;
void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_GLOBAL_CTL;
tmp = readl(mmio);
if (tmp & PDC_ERR_MASK) {
- have_err = 1;
+ err_mask = AC_ERR_DEV;
pdc_reset_port(ap);
}
switch (qc->tf.protocol) {
case ATA_PROT_DMA:
case ATA_PROT_NODATA:
- status = ata_wait_idle(ap);
- if (have_err)
- status |= ATA_ERR;
- ata_qc_complete(qc, status);
+ err_mask |= ac_err_mask(ata_wait_idle(ap));
+ ata_qc_complete(qc, err_mask);
handled = 1;
break;
@@ -631,7 +634,7 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
int rc;
if (!printed_version++)
- printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
/*
* If this driver happens to only be useful on Apple's K2, then
diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c
index 250dafa6bc36..9938dae782b6 100644
--- a/drivers/scsi/sata_qstor.c
+++ b/drivers/scsi/sata_qstor.c
@@ -35,6 +35,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
+#include <linux/device.h>
#include "scsi.h"
#include <scsi/scsi_host.h>
#include <asm/io.h>
@@ -400,11 +401,12 @@ static inline unsigned int qs_intr_pkt(struct ata_host_set *host_set)
qc = ata_qc_from_tag(ap, ap->active_tag);
if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
switch (sHST) {
- case 0: /* sucessful CPB */
+ case 0: /* successful CPB */
case 3: /* device error */
pp->state = qs_state_idle;
qs_enter_reg_mode(qc->ap);
- ata_qc_complete(qc, sDST);
+ ata_qc_complete(qc,
+ ac_err_mask(sDST));
break;
default:
break;
@@ -433,7 +435,7 @@ static inline unsigned int qs_intr_mmio(struct ata_host_set *host_set)
if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
/* check main status, clearing INTRQ */
- u8 status = ata_chk_status(ap);
+ u8 status = ata_check_status(ap);
if ((status & ATA_BUSY))
continue;
DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n",
@@ -441,7 +443,7 @@ static inline unsigned int qs_intr_mmio(struct ata_host_set *host_set)
/* complete taskfile transaction */
pp->state = qs_state_idle;
- ata_qc_complete(qc, status);
+ ata_qc_complete(qc, ac_err_mask(status));
handled = 1;
}
}
@@ -599,25 +601,22 @@ static int qs_set_dma_masks(struct pci_dev *pdev, void __iomem *mmio_base)
if (rc) {
rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
if (rc) {
- printk(KERN_ERR DRV_NAME
- "(%s): 64-bit DMA enable failed\n",
- pci_name(pdev));
+ dev_printk(KERN_ERR, &pdev->dev,
+ "64-bit DMA enable failed\n");
return rc;
}
}
} else {
rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
if (rc) {
- printk(KERN_ERR DRV_NAME
- "(%s): 32-bit DMA enable failed\n",
- pci_name(pdev));
+ dev_printk(KERN_ERR, &pdev->dev,
+ "32-bit DMA enable failed\n");
return rc;
}
rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
if (rc) {
- printk(KERN_ERR DRV_NAME
- "(%s): 32-bit consistent DMA enable failed\n",
- pci_name(pdev));
+ dev_printk(KERN_ERR, &pdev->dev,
+ "32-bit consistent DMA enable failed\n");
return rc;
}
}
@@ -634,7 +633,7 @@ static int qs_ata_init_one(struct pci_dev *pdev,
int rc, port_no;
if (!printed_version++)
- printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
rc = pci_enable_device(pdev);
if (rc)
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c
index 3a056173fb95..435f7e0085ec 100644
--- a/drivers/scsi/sata_sil.c
+++ b/drivers/scsi/sata_sil.c
@@ -41,6 +41,7 @@
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
+#include <linux/device.h>
#include "scsi.h"
#include <scsi/scsi_host.h>
#include <linux/libata.h>
@@ -386,7 +387,7 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
u8 cls;
if (!printed_version++)
- printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
/*
* If this driver happens to only be useful on Apple's K2, then
@@ -463,8 +464,8 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
writeb(cls, mmio_base + SIL_FIFO_W3);
}
} else
- printk(KERN_WARNING DRV_NAME "(%s): cache line size not set. Driver may not function\n",
- pci_name(pdev));
+ dev_printk(KERN_WARNING, &pdev->dev,
+ "cache line size not set. Driver may not function\n");
if (ent->driver_data == sil_3114) {
irq_mask = SIL_MASK_4PORT;
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
index 32d730bd5bb6..c66548025657 100644
--- a/drivers/scsi/sata_sil24.c
+++ b/drivers/scsi/sata_sil24.c
@@ -35,6 +35,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
+#include <linux/device.h>
#include <scsi/scsi_host.h>
#include "scsi.h"
#include <linux/libata.h>
@@ -220,12 +221,11 @@ struct sil24_port_priv {
/* ap->host_set->private_data */
struct sil24_host_priv {
- void *host_base; /* global controller control (128 bytes @BAR0) */
- void *port_base; /* port registers (4 * 8192 bytes @BAR2) */
+ void __iomem *host_base; /* global controller control (128 bytes @BAR0) */
+ void __iomem *port_base; /* port registers (4 * 8192 bytes @BAR2) */
};
static u8 sil24_check_status(struct ata_port *ap);
-static u8 sil24_check_err(struct ata_port *ap);
static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg);
static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val);
static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
@@ -280,7 +280,6 @@ static const struct ata_port_operations sil24_ops = {
.check_status = sil24_check_status,
.check_altstatus = sil24_check_status,
- .check_err = sil24_check_err,
.dev_select = ata_noop_dev_select,
.tf_read = sil24_tf_read,
@@ -349,10 +348,12 @@ static struct ata_port_info sil24_port_info[] = {
static inline void sil24_update_tf(struct ata_port *ap)
{
struct sil24_port_priv *pp = ap->private_data;
- void *port = (void *)ap->ioaddr.cmd_addr;
- struct sil24_prb *prb = port;
+ void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+ struct sil24_prb __iomem *prb = port;
+ u8 fis[6 * 4];
- ata_tf_from_fis(prb->fis, &pp->tf);
+ memcpy_fromio(fis, prb->fis, 6 * 4);
+ ata_tf_from_fis(fis, &pp->tf);
}
static u8 sil24_check_status(struct ata_port *ap)
@@ -361,12 +362,6 @@ static u8 sil24_check_status(struct ata_port *ap)
return pp->tf.command;
}
-static u8 sil24_check_err(struct ata_port *ap)
-{
- struct sil24_port_priv *pp = ap->private_data;
- return pp->tf.feature;
-}
-
static int sil24_scr_map[] = {
[SCR_CONTROL] = 0,
[SCR_STATUS] = 1,
@@ -376,9 +371,9 @@ static int sil24_scr_map[] = {
static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg)
{
- void *scr_addr = (void *)ap->ioaddr.scr_addr;
+ void __iomem *scr_addr = (void __iomem *)ap->ioaddr.scr_addr;
if (sc_reg < ARRAY_SIZE(sil24_scr_map)) {
- void *addr;
+ void __iomem *addr;
addr = scr_addr + sil24_scr_map[sc_reg] * 4;
return readl(scr_addr + sil24_scr_map[sc_reg] * 4);
}
@@ -387,9 +382,9 @@ static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg)
static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val)
{
- void *scr_addr = (void *)ap->ioaddr.scr_addr;
+ void __iomem *scr_addr = (void __iomem *)ap->ioaddr.scr_addr;
if (sc_reg < ARRAY_SIZE(sil24_scr_map)) {
- void *addr;
+ void __iomem *addr;
addr = scr_addr + sil24_scr_map[sc_reg] * 4;
writel(val, scr_addr + sil24_scr_map[sc_reg] * 4);
}
@@ -454,7 +449,7 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc)
static int sil24_qc_issue(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
- void *port = (void *)ap->ioaddr.cmd_addr;
+ void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
struct sil24_port_priv *pp = ap->private_data;
dma_addr_t paddr = pp->cmd_block_dma + qc->tag * sizeof(*pp->cmd_block);
@@ -467,7 +462,7 @@ static void sil24_irq_clear(struct ata_port *ap)
/* unused */
}
-static int __sil24_reset_controller(void *port)
+static int __sil24_reset_controller(void __iomem *port)
{
int cnt;
u32 tmp;
@@ -493,7 +488,7 @@ static void sil24_reset_controller(struct ata_port *ap)
{
printk(KERN_NOTICE DRV_NAME
" ata%u: resetting controller...\n", ap->id);
- if (__sil24_reset_controller((void *)ap->ioaddr.cmd_addr))
+ if (__sil24_reset_controller((void __iomem *)ap->ioaddr.cmd_addr))
printk(KERN_ERR DRV_NAME
" ata%u: failed to reset controller\n", ap->id);
}
@@ -504,7 +499,7 @@ static void sil24_eng_timeout(struct ata_port *ap)
qc = ata_qc_from_tag(ap, ap->active_tag);
if (!qc) {
- printk(KERN_ERR "ata%u: BUG: tiemout without command\n",
+ printk(KERN_ERR "ata%u: BUG: timeout without command\n",
ap->id);
return;
}
@@ -518,7 +513,7 @@ static void sil24_eng_timeout(struct ata_port *ap)
*/
printk(KERN_ERR "ata%u: command timeout\n", ap->id);
qc->scsidone = scsi_finish_command;
- ata_qc_complete(qc, ATA_ERR);
+ ata_qc_complete(qc, AC_ERR_OTHER);
sil24_reset_controller(ap);
}
@@ -527,8 +522,9 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
{
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
struct sil24_port_priv *pp = ap->private_data;
- void *port = (void *)ap->ioaddr.cmd_addr;
+ void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
u32 irq_stat, cmd_err, sstatus, serror;
+ unsigned int err_mask;
irq_stat = readl(port + PORT_IRQ_STAT);
writel(irq_stat, port + PORT_IRQ_STAT); /* clear irq */
@@ -556,17 +552,18 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
* Device is reporting error, tf registers are valid.
*/
sil24_update_tf(ap);
+ err_mask = ac_err_mask(pp->tf.command);
} else {
/*
* Other errors. libata currently doesn't have any
* mechanism to report these errors. Just turn on
* ATA_ERR.
*/
- pp->tf.command = ATA_ERR;
+ err_mask = AC_ERR_OTHER;
}
if (qc)
- ata_qc_complete(qc, pp->tf.command);
+ ata_qc_complete(qc, err_mask);
sil24_reset_controller(ap);
}
@@ -574,7 +571,7 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
static inline void sil24_host_intr(struct ata_port *ap)
{
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
- void *port = (void *)ap->ioaddr.cmd_addr;
+ void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
u32 slot_stat;
slot_stat = readl(port + PORT_SLOT_STAT);
@@ -591,7 +588,7 @@ static inline void sil24_host_intr(struct ata_port *ap)
sil24_update_tf(ap);
if (qc)
- ata_qc_complete(qc, pp->tf.command);
+ ata_qc_complete(qc, ac_err_mask(pp->tf.command));
} else
sil24_error_intr(ap, slot_stat);
}
@@ -689,11 +686,12 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
struct ata_port_info *pinfo = &sil24_port_info[board_id];
struct ata_probe_ent *probe_ent = NULL;
struct sil24_host_priv *hpriv = NULL;
- void *host_base = NULL, *port_base = NULL;
+ void __iomem *host_base = NULL;
+ void __iomem *port_base = NULL;
int i, rc;
if (!printed_version++)
- printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
rc = pci_enable_device(pdev);
if (rc)
@@ -753,14 +751,14 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
*/
rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
if (rc) {
- printk(KERN_ERR DRV_NAME "(%s): 32-bit DMA enable failed\n",
- pci_name(pdev));
+ dev_printk(KERN_ERR, &pdev->dev,
+ "32-bit DMA enable failed\n");
goto out_free;
}
rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
if (rc) {
- printk(KERN_ERR DRV_NAME "(%s): 32-bit consistent DMA enable failed\n",
- pci_name(pdev));
+ dev_printk(KERN_ERR, &pdev->dev,
+ "32-bit consistent DMA enable failed\n");
goto out_free;
}
@@ -771,7 +769,7 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
writel(0, host_base + HOST_CTRL);
for (i = 0; i < probe_ent->n_ports; i++) {
- void *port = port_base + i * PORT_REGS_SIZE;
+ void __iomem *port = port_base + i * PORT_REGS_SIZE;
unsigned long portu = (unsigned long)port;
u32 tmp;
int cnt;
@@ -796,9 +794,8 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
break;
}
if (tmp & PORT_CS_PORT_RST)
- printk(KERN_ERR DRV_NAME
- "(%s): failed to clear port RST\n",
- pci_name(pdev));
+ dev_printk(KERN_ERR, &pdev->dev,
+ "failed to clear port RST\n");
}
/* Zero error counters. */
@@ -827,9 +824,8 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
/* Reset itself */
if (__sil24_reset_controller(port))
- printk(KERN_ERR DRV_NAME
- "(%s): failed to reset controller\n",
- pci_name(pdev));
+ dev_printk(KERN_ERR, &pdev->dev,
+ "failed to reset controller\n");
}
/* Turn on interrupts */
diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c
index 057f7b98b6c4..42288be0e561 100644
--- a/drivers/scsi/sata_sis.c
+++ b/drivers/scsi/sata_sis.c
@@ -38,6 +38,7 @@
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
+#include <linux/device.h>
#include "scsi.h"
#include <scsi/scsi_host.h>
#include <linux/libata.h>
@@ -237,6 +238,7 @@ static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
+ static int printed_version;
struct ata_probe_ent *probe_ent = NULL;
int rc;
u32 genctl;
@@ -245,6 +247,9 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
u8 pmr;
u8 port2_start;
+ if (!printed_version++)
+ dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
+
rc = pci_enable_device(pdev);
if (rc)
return rc;
@@ -288,16 +293,18 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
pci_read_config_byte(pdev, SIS_PMR, &pmr);
if (ent->device != 0x182) {
if ((pmr & SIS_PMR_COMBINED) == 0) {
- printk(KERN_INFO "sata_sis: Detected SiS 180/181 chipset in SATA mode\n");
+ dev_printk(KERN_INFO, &pdev->dev,
+ "Detected SiS 180/181 chipset in SATA mode\n");
port2_start = 64;
}
else {
- printk(KERN_INFO "sata_sis: Detected SiS 180/181 chipset in combined mode\n");
+ dev_printk(KERN_INFO, &pdev->dev,
+ "Detected SiS 180/181 chipset in combined mode\n");
port2_start=0;
}
}
else {
- printk(KERN_INFO "sata_sis: Detected SiS 182 chipset\n");
+ dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 182 chipset\n");
port2_start = 0x20;
}
diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c
index e0f9570bc6dd..db615ff794d8 100644
--- a/drivers/scsi/sata_svw.c
+++ b/drivers/scsi/sata_svw.c
@@ -44,6 +44,7 @@
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
+#include <linux/device.h>
#include "scsi.h"
#include <scsi/scsi_host.h>
#include <linux/libata.h>
@@ -84,6 +85,8 @@
/* Port stride */
#define K2_SATA_PORT_OFFSET 0x100
+static u8 k2_stat_check_status(struct ata_port *ap);
+
static u32 k2_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
@@ -136,16 +139,24 @@ static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
static void k2_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
- u16 nsect, lbal, lbam, lbah;
+ u16 nsect, lbal, lbam, lbah, feature;
- nsect = tf->nsect = readw(ioaddr->nsect_addr);
- lbal = tf->lbal = readw(ioaddr->lbal_addr);
- lbam = tf->lbam = readw(ioaddr->lbam_addr);
- lbah = tf->lbah = readw(ioaddr->lbah_addr);
+ tf->command = k2_stat_check_status(ap);
tf->device = readw(ioaddr->device_addr);
+ feature = readw(ioaddr->error_addr);
+ nsect = readw(ioaddr->nsect_addr);
+ lbal = readw(ioaddr->lbal_addr);
+ lbam = readw(ioaddr->lbam_addr);
+ lbah = readw(ioaddr->lbah_addr);
+
+ tf->feature = feature;
+ tf->nsect = nsect;
+ tf->lbal = lbal;
+ tf->lbam = lbam;
+ tf->lbah = lbah;
if (tf->flags & ATA_TFLAG_LBA48) {
- tf->hob_feature = readw(ioaddr->error_addr) >> 8;
+ tf->hob_feature = feature >> 8;
tf->hob_nsect = nsect >> 8;
tf->hob_lbal = lbal >> 8;
tf->hob_lbam = lbam >> 8;
@@ -352,7 +363,7 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
int i;
if (!printed_version++)
- printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
/*
* If this driver happens to only be useful on Apple's K2, then
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c
index af08f4f650c1..0ec21e09f5d8 100644
--- a/drivers/scsi/sata_sx4.c
+++ b/drivers/scsi/sata_sx4.c
@@ -38,6 +38,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
+#include <linux/device.h>
#include "scsi.h"
#include <scsi/scsi_host.h>
#include <linux/libata.h>
@@ -718,7 +719,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
VPRINTK("ata%u: read hdma, 0x%x 0x%x\n", ap->id,
readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT));
/* get drive status; clear intr; complete txn */
- ata_qc_complete(qc, ata_wait_idle(ap));
+ ata_qc_complete(qc, ac_err_mask(ata_wait_idle(ap)));
pdc20621_pop_hdma(qc);
}
@@ -756,7 +757,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
VPRINTK("ata%u: write ata, 0x%x 0x%x\n", ap->id,
readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT));
/* get drive status; clear intr; complete txn */
- ata_qc_complete(qc, ata_wait_idle(ap));
+ ata_qc_complete(qc, ac_err_mask(ata_wait_idle(ap)));
pdc20621_pop_hdma(qc);
}
handled = 1;
@@ -766,7 +767,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
DPRINTK("BUS_NODATA (drv_stat 0x%X)\n", status);
- ata_qc_complete(qc, status);
+ ata_qc_complete(qc, ac_err_mask(status));
handled = 1;
} else {
@@ -881,7 +882,7 @@ static void pdc_eng_timeout(struct ata_port *ap)
case ATA_PROT_DMA:
case ATA_PROT_NODATA:
printk(KERN_ERR "ata%u: command timeout\n", ap->id);
- ata_qc_complete(qc, ata_wait_idle(ap) | ATA_ERR);
+ ata_qc_complete(qc, __ac_err_mask(ata_wait_idle(ap)));
break;
default:
@@ -890,7 +891,7 @@ static void pdc_eng_timeout(struct ata_port *ap)
printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n",
ap->id, qc->tf.command, drv_stat);
- ata_qc_complete(qc, drv_stat);
+ ata_qc_complete(qc, ac_err_mask(drv_stat));
break;
}
@@ -1385,7 +1386,7 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
int rc;
if (!printed_version++)
- printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
/*
* If this driver happens to only be useful on Apple's K2, then
diff --git a/drivers/scsi/sata_uli.c b/drivers/scsi/sata_uli.c
index d68dc7d3422c..a5e245c098e1 100644
--- a/drivers/scsi/sata_uli.c
+++ b/drivers/scsi/sata_uli.c
@@ -32,6 +32,7 @@
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
+#include <linux/device.h>
#include "scsi.h"
#include <scsi/scsi_host.h>
#include <linux/libata.h>
@@ -178,12 +179,16 @@ static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
+ static int printed_version;
struct ata_probe_ent *probe_ent;
struct ata_port_info *ppi;
int rc;
unsigned int board_idx = (unsigned int) ent->driver_data;
int pci_dev_busy = 0;
+ if (!printed_version++)
+ dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
+
rc = pci_enable_device(pdev);
if (rc)
return rc;
diff --git a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c
index 80e291a909a9..b3ecdbe400e9 100644
--- a/drivers/scsi/sata_via.c
+++ b/drivers/scsi/sata_via.c
@@ -41,6 +41,7 @@
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
+#include <linux/device.h>
#include "scsi.h"
#include <scsi/scsi_host.h>
#include <linux/libata.h>
@@ -259,15 +260,15 @@ static void svia_configure(struct pci_dev *pdev)
u8 tmp8;
pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &tmp8);
- printk(KERN_INFO DRV_NAME "(%s): routed to hard irq line %d\n",
- pci_name(pdev),
+ dev_printk(KERN_INFO, &pdev->dev, "routed to hard irq line %d\n",
(int) (tmp8 & 0xf0) == 0xf0 ? 0 : tmp8 & 0x0f);
/* make sure SATA channels are enabled */
pci_read_config_byte(pdev, SATA_CHAN_ENAB, &tmp8);
if ((tmp8 & ALL_PORTS) != ALL_PORTS) {
- printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channels (0x%x)\n",
- pci_name(pdev), (int) tmp8);
+ dev_printk(KERN_DEBUG, &pdev->dev,
+ "enabling SATA channels (0x%x)\n",
+ (int) tmp8);
tmp8 |= ALL_PORTS;
pci_write_config_byte(pdev, SATA_CHAN_ENAB, tmp8);
}
@@ -275,8 +276,9 @@ static void svia_configure(struct pci_dev *pdev)
/* make sure interrupts for each channel sent to us */
pci_read_config_byte(pdev, SATA_INT_GATE, &tmp8);
if ((tmp8 & ALL_PORTS) != ALL_PORTS) {
- printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channel interrupts (0x%x)\n",
- pci_name(pdev), (int) tmp8);
+ dev_printk(KERN_DEBUG, &pdev->dev,
+ "enabling SATA channel interrupts (0x%x)\n",
+ (int) tmp8);
tmp8 |= ALL_PORTS;
pci_write_config_byte(pdev, SATA_INT_GATE, tmp8);
}
@@ -284,8 +286,9 @@ static void svia_configure(struct pci_dev *pdev)
/* make sure native mode is enabled */
pci_read_config_byte(pdev, SATA_NATIVE_MODE, &tmp8);
if ((tmp8 & NATIVE_MODE_ALL) != NATIVE_MODE_ALL) {
- printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channel native mode (0x%x)\n",
- pci_name(pdev), (int) tmp8);
+ dev_printk(KERN_DEBUG, &pdev->dev,
+ "enabling SATA channel native mode (0x%x)\n",
+ (int) tmp8);
tmp8 |= NATIVE_MODE_ALL;
pci_write_config_byte(pdev, SATA_NATIVE_MODE, tmp8);
}
@@ -303,7 +306,7 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
u8 tmp8;
if (!printed_version++)
- printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
rc = pci_enable_device(pdev);
if (rc)
@@ -318,8 +321,9 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (board_id == vt6420) {
pci_read_config_byte(pdev, SATA_PATA_SHARING, &tmp8);
if (tmp8 & SATA_2DEV) {
- printk(KERN_ERR DRV_NAME "(%s): SATA master/slave not supported (0x%x)\n",
- pci_name(pdev), (int) tmp8);
+ dev_printk(KERN_ERR, &pdev->dev,
+ "SATA master/slave not supported (0x%x)\n",
+ (int) tmp8);
rc = -EIO;
goto err_out_regions;
}
@@ -332,10 +336,11 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
for (i = 0; i < ARRAY_SIZE(svia_bar_sizes); i++)
if ((pci_resource_start(pdev, i) == 0) ||
(pci_resource_len(pdev, i) < bar_sizes[i])) {
- printk(KERN_ERR DRV_NAME "(%s): invalid PCI BAR %u (sz 0x%lx, val 0x%lx)\n",
- pci_name(pdev), i,
- pci_resource_start(pdev, i),
- pci_resource_len(pdev, i));
+ dev_printk(KERN_ERR, &pdev->dev,
+ "invalid PCI BAR %u (sz 0x%lx, val 0x%lx)\n",
+ i,
+ pci_resource_start(pdev, i),
+ pci_resource_len(pdev, i));
rc = -ENODEV;
goto err_out_regions;
}
@@ -353,8 +358,7 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
probe_ent = vt6421_init_probe_ent(pdev);
if (!probe_ent) {
- printk(KERN_ERR DRV_NAME "(%s): out of memory\n",
- pci_name(pdev));
+ dev_printk(KERN_ERR, &pdev->dev, "out of memory\n");
rc = -ENOMEM;
goto err_out_regions;
}
diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c
index 5af05fdf8544..bb84ba0c7e83 100644
--- a/drivers/scsi/sata_vsc.c
+++ b/drivers/scsi/sata_vsc.c
@@ -42,6 +42,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
+#include <linux/device.h>
#include "scsi.h"
#include <scsi/scsi_host.h>
#include <linux/libata.h>
@@ -153,16 +154,24 @@ static void vsc_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
static void vsc_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
- u16 nsect, lbal, lbam, lbah;
+ u16 nsect, lbal, lbam, lbah, feature;
- nsect = tf->nsect = readw(ioaddr->nsect_addr);
- lbal = tf->lbal = readw(ioaddr->lbal_addr);
- lbam = tf->lbam = readw(ioaddr->lbam_addr);
- lbah = tf->lbah = readw(ioaddr->lbah_addr);
+ tf->command = ata_check_status(ap);
tf->device = readw(ioaddr->device_addr);
+ feature = readw(ioaddr->error_addr);
+ nsect = readw(ioaddr->nsect_addr);
+ lbal = readw(ioaddr->lbal_addr);
+ lbam = readw(ioaddr->lbam_addr);
+ lbah = readw(ioaddr->lbah_addr);
+
+ tf->feature = feature;
+ tf->nsect = nsect;
+ tf->lbal = lbal;
+ tf->lbam = lbam;
+ tf->lbah = lbah;
if (tf->flags & ATA_TFLAG_LBA48) {
- tf->hob_feature = readb(ioaddr->error_addr);
+ tf->hob_feature = feature >> 8;
tf->hob_nsect = nsect >> 8;
tf->hob_lbal = lbal >> 8;
tf->hob_lbam = lbam >> 8;
@@ -287,7 +296,7 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
int rc;
if (!printed_version++)
- printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
rc = pci_enable_device(pdev);
if (rc)
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 771e97ef136e..b856e140e65f 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -26,6 +26,7 @@
*/
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/sched.h> /* workqueue stuff, HZ */
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_transport.h>
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 8bb8222ea589..d2caa35059d9 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -19,6 +19,9 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
#include <scsi/scsi.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_device.h>
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 861e51375d70..d86d5c26061d 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -49,6 +49,7 @@ static int sg_version_num = 30533; /* 2 digits for each component */
#include <linux/seq_file.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
+#include <linux/scatterlist.h>
#include "scsi.h"
#include <scsi/scsi_dbg.h>
@@ -1886,13 +1887,17 @@ st_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_pages,
int i;
for (i=0; i < nr_pages; i++) {
- if (dirtied && !PageReserved(sgl[i].page))
- SetPageDirty(sgl[i].page);
- /* unlock_page(sgl[i].page); */
+ struct page *page = sgl[i].page;
+
+ /* XXX: just for debug. Remove when PageReserved is removed */
+ BUG_ON(PageReserved(page));
+ if (dirtied)
+ SetPageDirty(page);
+ /* unlock_page(page); */
/* FIXME: cache flush missing for rw==READ
* FIXME: call the correct reference counting function
*/
- page_cache_release(sgl[i].page);
+ page_cache_release(page);
}
return 0;
@@ -1992,9 +1997,7 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
if (!p)
break;
}
- sclp->page = virt_to_page(p);
- sclp->offset = offset_in_page(p);
- sclp->length = ret_sz;
+ sg_set_buf(sclp, p, ret_sz);
SCSI_LOG_TIMEOUT(5, printk("sg_build_build: k=%d, a=0x%p, len=%d\n",
k, sg_scatg2virt(sclp), ret_sz));
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 5eb54d8019b4..da9766283bd7 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -4526,12 +4526,16 @@ static int sgl_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_p
int i;
for (i=0; i < nr_pages; i++) {
- if (dirtied && !PageReserved(sgl[i].page))
- SetPageDirty(sgl[i].page);
+ struct page *page = sgl[i].page;
+
+ /* XXX: just for debug. Remove when PageReserved is removed */
+ BUG_ON(PageReserved(page));
+ if (dirtied)
+ SetPageDirty(page);
/* FIXME: cache flush missing for rw==READ
* FIXME: call the correct reference counting function
*/
- page_cache_release(sgl[i].page);
+ page_cache_release(page);
}
return 0;
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c
index e753ba27dc59..a1a58e1d5ad3 100644
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.c
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c
@@ -37,6 +37,9 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+
+#include <linux/slab.h>
+
#include "sym_glue.h"
#include "sym_nvram.h"
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.h b/drivers/scsi/sym53c8xx_2/sym_hipd.h
index 3131a6bf7ab7..3a264a408216 100644
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.h
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.h
@@ -37,6 +37,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <linux/gfp.h>
+
#ifndef SYM_HIPD_H
#define SYM_HIPD_H
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c
index f88fdd480685..771676abee60 100644
--- a/drivers/serial/ioc4_serial.c
+++ b/drivers/serial/ioc4_serial.c
@@ -308,6 +308,8 @@ struct ioc4_serial {
typedef void ioc4_intr_func_f(void *, uint32_t);
typedef ioc4_intr_func_f *ioc4_intr_func_t;
+static unsigned int Num_of_ioc4_cards;
+
/* defining this will get you LOTS of great debug info */
//#define DEBUG_INTERRUPTS
#define DPRINT_CONFIG(_x...) ;
@@ -317,7 +319,8 @@ typedef ioc4_intr_func_f *ioc4_intr_func_t;
#define WAKEUP_CHARS 256
/* number of characters we want to transmit to the lower level at a time */
-#define IOC4_MAX_CHARS 128
+#define IOC4_MAX_CHARS 256
+#define IOC4_FIFO_CHARS 255
/* Device name we're using */
#define DEVICE_NAME "ttyIOC"
@@ -1038,6 +1041,7 @@ static int inline ioc4_attach_local(struct ioc4_driver_data *idd)
return -ENOMEM;
}
memset(port, 0, sizeof(struct ioc4_port));
+ spin_lock_init(&port->ip_lock);
/* we need to remember the previous ones, to point back to
* them farther down - setting up the ring buffers.
@@ -1691,12 +1695,14 @@ ioc4_change_speed(struct uart_port *the_port,
baud = 9600;
if (!the_port->fifosize)
- the_port->fifosize = IOC4_MAX_CHARS;
+ the_port->fifosize = IOC4_FIFO_CHARS;
the_port->timeout = ((the_port->fifosize * HZ * bits) / (baud / 10));
the_port->timeout += HZ / 50; /* Add .02 seconds of slop */
the_port->ignore_status_mask = N_ALL_INPUT;
+ info->tty->low_latency = 1;
+
if (I_IGNPAR(info->tty))
the_port->ignore_status_mask &= ~(N_PARITY_ERROR
| N_FRAMING_ERROR);
@@ -1742,7 +1748,6 @@ ioc4_change_speed(struct uart_port *the_port,
*/
static inline int ic4_startup_local(struct uart_port *the_port)
{
- int retval = 0;
struct ioc4_port *port;
struct uart_info *info;
@@ -1754,9 +1759,6 @@ static inline int ic4_startup_local(struct uart_port *the_port)
return -1;
info = the_port->info;
- if (info->flags & UIF_INITIALIZED) {
- return retval;
- }
if (info->tty) {
set_bit(TTY_IO_ERROR, &info->tty->flags);
@@ -1775,7 +1777,6 @@ static inline int ic4_startup_local(struct uart_port *the_port)
/* set the speed of the serial port */
ioc4_change_speed(the_port, info->tty->termios, (struct termios *)0);
- info->flags |= UIF_INITIALIZED;
return 0;
}
@@ -1785,9 +1786,13 @@ static inline int ic4_startup_local(struct uart_port *the_port)
*/
static void ioc4_cb_output_lowat(struct ioc4_port *port)
{
+ unsigned long pflags;
+
/* ip_lock is set on the call here */
if (port->ip_port) {
+ spin_lock_irqsave(&port->ip_port->lock, pflags);
transmit_chars(port->ip_port);
+ spin_unlock_irqrestore(&port->ip_port->lock, pflags);
}
}
@@ -2064,8 +2069,7 @@ static inline int do_read(struct uart_port *the_port, unsigned char *buf,
* available data as long as it returns some.
*/
/* Re-arm the timer */
- writel(port->ip_rx_cons | IOC4_SRCIR_ARM,
- &port->ip_serial_regs->srcir);
+ writel(port->ip_rx_cons | IOC4_SRCIR_ARM, &port->ip_serial_regs->srcir);
prod_ptr = readl(&port->ip_serial_regs->srpir) & PROD_CONS_MASK;
cons_ptr = port->ip_rx_cons;
@@ -2299,6 +2303,7 @@ static inline int do_read(struct uart_port *the_port, unsigned char *buf,
}
return total;
}
+
/**
* receive_chars - upper level read. Called with ip_lock.
* @the_port: port to read from
@@ -2307,9 +2312,11 @@ static void receive_chars(struct uart_port *the_port)
{
struct tty_struct *tty;
unsigned char ch[IOC4_MAX_CHARS];
- int read_count, request_count;
+ int read_count, request_count = IOC4_MAX_CHARS;
struct uart_icount *icount;
struct uart_info *info = the_port->info;
+ int flip = 0;
+ unsigned long pflags;
/* Make sure all the pointers are "good" ones */
if (!info)
@@ -2317,16 +2324,17 @@ static void receive_chars(struct uart_port *the_port)
if (!info->tty)
return;
+ spin_lock_irqsave(&the_port->lock, pflags);
tty = info->tty;
- request_count = TTY_FLIPBUF_SIZE - tty->flip.count - 1;
+ if (request_count > TTY_FLIPBUF_SIZE - tty->flip.count)
+ request_count = TTY_FLIPBUF_SIZE - tty->flip.count;
if (request_count > 0) {
- if (request_count > IOC4_MAX_CHARS - 2)
- request_count = IOC4_MAX_CHARS - 2;
icount = &the_port->icount;
read_count = do_read(the_port, ch, request_count);
if (read_count > 0) {
+ flip = 1;
memcpy(tty->flip.char_buf_ptr, ch, read_count);
memset(tty->flip.flag_buf_ptr, TTY_NORMAL, read_count);
tty->flip.char_buf_ptr += read_count;
@@ -2335,7 +2343,11 @@ static void receive_chars(struct uart_port *the_port)
icount->rx += read_count;
}
}
- tty_flip_buffer_push(tty);
+
+ spin_unlock_irqrestore(&the_port->lock, pflags);
+
+ if (flip)
+ tty_flip_buffer_push(tty);
}
/**
@@ -2393,18 +2405,14 @@ static void ic4_shutdown(struct uart_port *the_port)
info = the_port->info;
- if (!(info->flags & UIF_INITIALIZED))
- return;
-
wake_up_interruptible(&info->delta_msr_wait);
if (info->tty)
set_bit(TTY_IO_ERROR, &info->tty->flags);
- spin_lock_irqsave(&port->ip_lock, port_flags);
+ spin_lock_irqsave(&the_port->lock, port_flags);
set_notification(port, N_ALL, 0);
- info->flags &= ~UIF_INITIALIZED;
- spin_unlock_irqrestore(&port->ip_lock, port_flags);
+ spin_unlock_irqrestore(&the_port->lock, port_flags);
}
/**
@@ -2463,12 +2471,10 @@ static unsigned int ic4_get_mctrl(struct uart_port *the_port)
static void ic4_start_tx(struct uart_port *the_port)
{
struct ioc4_port *port = get_ioc4_port(the_port);
- unsigned long flags;
if (port) {
- spin_lock_irqsave(&port->ip_lock, flags);
- transmit_chars(the_port);
- spin_unlock_irqrestore(&port->ip_lock, flags);
+ set_notification(port, N_OUTPUT_LOWAT, 1);
+ enable_intrs(port, port->ip_hooks->intr_tx_mt);
}
}
@@ -2510,9 +2516,9 @@ static int ic4_startup(struct uart_port *the_port)
}
/* Start up the serial port */
- spin_lock_irqsave(&port->ip_lock, port_flags);
+ spin_lock_irqsave(&the_port->lock, port_flags);
retval = ic4_startup_local(the_port);
- spin_unlock_irqrestore(&port->ip_lock, port_flags);
+ spin_unlock_irqrestore(&the_port->lock, port_flags);
return retval;
}
@@ -2527,12 +2533,11 @@ static void
ic4_set_termios(struct uart_port *the_port,
struct termios *termios, struct termios *old_termios)
{
- struct ioc4_port *port = get_ioc4_port(the_port);
unsigned long port_flags;
- spin_lock_irqsave(&port->ip_lock, port_flags);
+ spin_lock_irqsave(&the_port->lock, port_flags);
ioc4_change_speed(the_port, termios, old_termios);
- spin_unlock_irqrestore(&port->ip_lock, port_flags);
+ spin_unlock_irqrestore(&the_port->lock, port_flags);
}
/**
@@ -2607,24 +2612,25 @@ ioc4_serial_core_attach(struct pci_dev *pdev)
__FUNCTION__, (void *)the_port,
(void *)port));
- spin_lock_init(&the_port->lock);
/* membase, iobase and mapbase just need to be non-0 */
the_port->membase = (unsigned char __iomem *)1;
- the_port->line = the_port->iobase = ii;
+ the_port->iobase = (pdev->bus->number << 16) | ii;
+ the_port->line = (Num_of_ioc4_cards << 2) | ii;
the_port->mapbase = 1;
the_port->type = PORT_16550A;
- the_port->fifosize = IOC4_MAX_CHARS;
+ the_port->fifosize = IOC4_FIFO_CHARS;
the_port->ops = &ioc4_ops;
the_port->irq = control->ic_irq;
the_port->dev = &pdev->dev;
+ spin_lock_init(&the_port->lock);
if (uart_add_one_port(&ioc4_uart, the_port) < 0) {
printk(KERN_WARNING
- "%s: unable to add port %d\n",
- __FUNCTION__, the_port->line);
+ "%s: unable to add port %d bus %d\n",
+ __FUNCTION__, the_port->line, pdev->bus->number);
} else {
DPRINT_CONFIG(
- ("IOC4 serial driver port %d irq = %d\n",
- the_port->line, the_port->irq));
+ ("IOC4 serial port %d irq = %d, bus %d\n",
+ the_port->line, the_port->irq, pdev->bus->number));
}
/* all ports are rs232 for now */
ioc4_set_proto(port, PROTO_RS232);
@@ -2734,6 +2740,8 @@ ioc4_serial_attach_one(struct ioc4_driver_data *idd)
if ((ret = ioc4_serial_core_attach(idd->idd_pdev)))
goto out4;
+ Num_of_ioc4_cards++;
+
return ret;
/* error exits that give back resources */
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c
index f4c709bc464b..ba8838b234da 100644
--- a/drivers/serial/mpsc.c
+++ b/drivers/serial/mpsc.c
@@ -1102,6 +1102,8 @@ mpsc_start_rx(struct mpsc_port_info *pi)
{
pr_debug("mpsc_start_rx[%d]: Starting...\n", pi->port.line);
+ /* Issue a Receive Abort to clear any receive errors */
+ writel(MPSC_CHR_2_RA, pi->mpsc_base + MPSC_CHR_2);
if (pi->rcv_data) {
mpsc_enter_hunt(pi);
mpsc_sdma_cmd(pi, SDMA_SDCM_ERD);
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 2d8622eef701..401d94a7fe2e 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -147,8 +147,7 @@ static int uart_startup(struct uart_state *state, int init_hw)
* once we have successfully opened the port. Also set
* up the tty->alt_speed kludge
*/
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ set_bit(TTY_IO_ERROR, &info->tty->flags);
if (port->type == PORT_UNKNOWN)
return 0;
diff --git a/drivers/sh/superhyway/superhyway.c b/drivers/sh/superhyway/superhyway.c
index f056276b08a1..28757cb9d246 100644
--- a/drivers/sh/superhyway/superhyway.c
+++ b/drivers/sh/superhyway/superhyway.c
@@ -16,6 +16,8 @@
#include <linux/types.h>
#include <linux/list.h>
#include <linux/superhyway.h>
+#include <linux/string.h>
+#include <linux/slab.h>
static int superhyway_devices;
diff --git a/drivers/tc/tc.c b/drivers/tc/tc.c
index a89ef4df80c3..a0e5af638e0e 100644
--- a/drivers/tc/tc.c
+++ b/drivers/tc/tc.c
@@ -8,33 +8,31 @@
* for more details.
*
* Copyright (c) Harald Koerfgen, 1998
- * Copyright (c) 2001, 2003 Maciej W. Rozycki
+ * Copyright (c) 2001, 2003, 2005 Maciej W. Rozycki
*/
-#include <linux/string.h>
#include <linux/init.h>
-#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/types.h>
#include <asm/addrspace.h>
+#include <asm/bug.h>
#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/paccess.h>
+
#include <asm/dec/machtype.h>
#include <asm/dec/prom.h>
#include <asm/dec/tcinfo.h>
#include <asm/dec/tcmodule.h>
#include <asm/dec/interrupts.h>
-#include <asm/paccess.h>
-#include <asm/ptrace.h>
-
-#define TC_DEBUG
MODULE_LICENSE("GPL");
slot_info tc_bus[MAX_SLOT];
static int num_tcslots;
static tcinfo *info;
-unsigned long system_base;
-
/*
* Interface to the world. Read comment in include/asm-mips/tc.h.
*/
@@ -97,13 +95,16 @@ unsigned long get_tc_speed(void)
static void __init tc_probe(unsigned long startaddr, unsigned long size,
int slots)
{
+ unsigned long slotaddr;
int i, slot, err;
long offset;
- unsigned char pattern[4];
- unsigned char *module;
+ u8 pattern[4];
+ volatile u8 *module;
for (slot = 0; slot < slots; slot++) {
- module = (char *)(startaddr + slot * size);
+ slotaddr = startaddr + slot * size;
+ module = ioremap_nocache(slotaddr, size);
+ BUG_ON(!module);
offset = OLDCARD;
@@ -112,8 +113,10 @@ static void __init tc_probe(unsigned long startaddr, unsigned long size,
err |= get_dbe(pattern[1], module + OLDCARD + TC_PATTERN1);
err |= get_dbe(pattern[2], module + OLDCARD + TC_PATTERN2);
err |= get_dbe(pattern[3], module + OLDCARD + TC_PATTERN3);
- if (err)
+ if (err) {
+ iounmap(module);
continue;
+ }
if (pattern[0] != 0x55 || pattern[1] != 0x00 ||
pattern[2] != 0xaa || pattern[3] != 0xff) {
@@ -124,16 +127,20 @@ static void __init tc_probe(unsigned long startaddr, unsigned long size,
err |= get_dbe(pattern[1], module + TC_PATTERN1);
err |= get_dbe(pattern[2], module + TC_PATTERN2);
err |= get_dbe(pattern[3], module + TC_PATTERN3);
- if (err)
+ if (err) {
+ iounmap(module);
continue;
+ }
}
if (pattern[0] != 0x55 || pattern[1] != 0x00 ||
- pattern[2] != 0xaa || pattern[3] != 0xff)
+ pattern[2] != 0xaa || pattern[3] != 0xff) {
+ iounmap(module);
continue;
+ }
- tc_bus[slot].base_addr = (unsigned long)module;
- for(i = 0; i < 8; i++) {
+ tc_bus[slot].base_addr = slotaddr;
+ for (i = 0; i < 8; i++) {
tc_bus[slot].firmware[i] =
module[TC_FIRM_VER + offset + 4 * i];
tc_bus[slot].vendor[i] =
@@ -171,13 +178,15 @@ static void __init tc_probe(unsigned long startaddr, unsigned long size,
tc_bus[slot].interrupt = -1;
break;
}
+
+ iounmap(module);
}
}
/*
* the main entry
*/
-void __init tc_init(void)
+static int __init tc_init(void)
{
int tc_clock;
int i;
@@ -185,7 +194,7 @@ void __init tc_init(void)
unsigned long slot_size;
if (!TURBOCHANNEL)
- return;
+ return 0;
for (i = 0; i < MAX_SLOT; i++) {
tc_bus[i].base_addr = 0;
@@ -196,8 +205,8 @@ void __init tc_init(void)
tc_bus[i].flags = FREE;
}
- info = (tcinfo *) rex_gettcinfo();
- slot0addr = (unsigned long)KSEG1ADDR(rex_slot_address(0));
+ info = rex_gettcinfo();
+ slot0addr = CPHYSADDR((long)rex_slot_address(0));
switch (mips_machtype) {
case MACH_DS5000_200:
@@ -216,37 +225,24 @@ void __init tc_init(void)
tc_clock = 10000 / info->clk_period;
- if (TURBOCHANNEL && info->slot_size && slot0addr) {
- printk("TURBOchannel rev. %1d at %2d.%1d MHz ", info->revision,
- tc_clock / 10, tc_clock % 10);
- printk("(with%s parity)\n", info->parity ? "" : "out");
+ if (info->slot_size && slot0addr) {
+ pr_info("TURBOchannel rev. %d at %d.%d MHz (with%s parity)\n",
+ info->revision, tc_clock / 10, tc_clock % 10,
+ info->parity ? "" : "out");
slot_size = info->slot_size << 20;
tc_probe(slot0addr, slot_size, num_tcslots);
- /*
- * All TURBOchannel DECstations have the onboard devices
- * where the (num_tcslots + 0 or 1 on DS5k/xx) Option Module
- * would be.
- */
- if(mips_machtype == MACH_DS5000_XX)
- i = 1;
- else
- i = 0;
-
- system_base = slot0addr + slot_size * (num_tcslots + i);
-
-#ifdef TC_DEBUG
- for (i = 0; i < num_tcslots; i++)
- if (tc_bus[i].base_addr) {
- printk(" slot %d: ", i);
- printk("%s %s %s\n", tc_bus[i].vendor,
- tc_bus[i].name, tc_bus[i].firmware);
- }
-#endif
- ioport_resource.end = KSEG2 - 1;
+ for (i = 0; i < num_tcslots; i++) {
+ if (!tc_bus[i].base_addr)
+ continue;
+ pr_info(" slot %d: %s %s %s\n", i, tc_bus[i].vendor,
+ tc_bus[i].name, tc_bus[i].firmware);
+ }
}
+
+ return 0;
}
subsys_initcall(tc_init);
@@ -257,4 +253,3 @@ EXPORT_SYMBOL(release_tc_card);
EXPORT_SYMBOL(get_tc_base_addr);
EXPORT_SYMBOL(get_tc_irq_nr);
EXPORT_SYMBOL(get_tc_speed);
-EXPORT_SYMBOL(system_base);
diff --git a/drivers/tc/zs.c b/drivers/tc/zs.c
index 6bed8713897e..c52af73a251b 100644
--- a/drivers/tc/zs.c
+++ b/drivers/tc/zs.c
@@ -65,14 +65,14 @@
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/bootinfo.h>
-#include <asm/dec/serial.h>
-#ifdef CONFIG_MACH_DECSTATION
#include <asm/dec/interrupts.h>
+#include <asm/dec/ioasic_addrs.h>
#include <asm/dec/machtype.h>
+#include <asm/dec/serial.h>
+#include <asm/dec/system.h>
#include <asm/dec/tc.h>
-#include <asm/dec/ioasic_addrs.h>
-#endif
+
#ifdef CONFIG_KGDB
#include <asm/kgdb.h>
#endif
@@ -192,18 +192,6 @@ static void probe_sccs(void);
static void change_speed(struct dec_serial *info);
static void rs_wait_until_sent(struct tty_struct *tty, int timeout);
-/*
- * tmp_buf is used as a temporary buffer by serial_write. We need to
- * lock it in case the copy_from_user blocks while swapping in a page,
- * and some other program tries to do a serial write at the same time.
- * Since the lock will only come under contention when the system is
- * swapping and available memory is low, it makes sense to share one
- * buffer across all the serial ports, since it significantly saves
- * memory if large numbers of serial ports are open.
- */
-static unsigned char tmp_buf[4096]; /* This is cheating */
-static DECLARE_MUTEX(tmp_buf_sem);
-
static inline int serial_paranoia_check(struct dec_serial *info,
char *name, const char *routine)
{
@@ -1628,30 +1616,22 @@ static void __init probe_sccs(void)
return;
}
- /*
- * When serial console is activated, tc_init has not been called yet
- * and system_base is undefined. Unfortunately we have to hardcode
- * system_base for this case :-(. HK
- */
switch(mips_machtype) {
#ifdef CONFIG_MACH_DECSTATION
case MACH_DS5000_2X0:
case MACH_DS5900:
- system_base = KSEG1ADDR(0x1f800000);
n_chips = 2;
zs_parms = &ds_parms;
zs_parms->irq0 = dec_interrupt[DEC_IRQ_SCC0];
zs_parms->irq1 = dec_interrupt[DEC_IRQ_SCC1];
break;
case MACH_DS5000_1XX:
- system_base = KSEG1ADDR(0x1c000000);
n_chips = 2;
zs_parms = &ds_parms;
zs_parms->irq0 = dec_interrupt[DEC_IRQ_SCC0];
zs_parms->irq1 = dec_interrupt[DEC_IRQ_SCC1];
break;
case MACH_DS5000_XX:
- system_base = KSEG1ADDR(0x1c000000);
n_chips = 1;
zs_parms = &ds_parms;
zs_parms->irq0 = dec_interrupt[DEC_IRQ_SCC0];
@@ -1673,10 +1653,10 @@ static void __init probe_sccs(void)
* The sccs reside on the high byte of the 16 bit IOBUS
*/
zs_channels[n_channels].control =
- (volatile unsigned char *)system_base +
+ (volatile void *)CKSEG1ADDR(dec_kn_slot_base +
(0 == chip ? zs_parms->scc0 : zs_parms->scc1) +
(0 == channel ? zs_parms->channel_a_offset :
- zs_parms->channel_b_offset);
+ zs_parms->channel_b_offset));
zs_channels[n_channels].data =
zs_channels[n_channels].control + 4;
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index 277bcb902d3b..e46cc540cf4d 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -14,6 +14,8 @@
* This file is licenced under the GPL.
*/
+#include <linux/signal.h> /* SA_INTERRUPT */
+#include <linux/jiffies.h>
#include <linux/platform_device.h>
#include <asm/hardware.h>
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
index bf1d5ab4aa3a..7ce1d9ef0289 100644
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -14,6 +14,8 @@
* This file is licenced under the GPL.
*/
+#include <linux/jiffies.h>
+
#ifdef CONFIG_PPC_PMAC
#include <asm/machdep.h>
#include <asm/pmac_feature.h>
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
index 5181999c56c9..59e20568e8f9 100644
--- a/drivers/usb/host/ohci-pxa27x.c
+++ b/drivers/usb/host/ohci-pxa27x.c
@@ -19,7 +19,10 @@
* This file is licenced under the GPL.
*/
+#include <linux/device.h>
+#include <linux/signal.h>
#include <linux/platform_device.h>
+
#include <asm/mach-types.h>
#include <asm/hardware.h>
#include <asm/arch/pxa-regs.h>
diff --git a/drivers/usb/input/pid.c b/drivers/usb/input/pid.c
index a00672c96644..dca5ee93a4ef 100644
--- a/drivers/usb/input/pid.c
+++ b/drivers/usb/input/pid.c
@@ -198,7 +198,7 @@ static int hid_pid_upload_effect(struct input_dev *dev,
}
effect->id = id;
- dev_dbg(&pid_private->hid->dev->dev, "effect ID is %d\n.", id);
+ dev_dbg(&pid_private->hid->dev->dev, "effect ID is %d.\n", id);
pid_private->effects[id].owner = current->pid;
pid_private->effects[id].flags = (1 << FF_PID_FLAGS_USED);
spin_unlock_irqrestore(&pid_private->lock, flags);
diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c
index 3944a55ed74c..1dc3e0f73014 100644
--- a/drivers/usb/misc/idmouse.c
+++ b/drivers/usb/misc/idmouse.c
@@ -319,20 +319,8 @@ static ssize_t idmouse_read(struct file *file, char __user *buffer, size_t count
return -ENODEV;
}
- if (*ppos >= IMGSIZE) {
- up (&dev->sem);
- return 0;
- }
-
- count = min ((loff_t)count, IMGSIZE - (*ppos));
-
- if (copy_to_user (buffer, dev->bulk_in_buffer + *ppos, count)) {
- result = -EFAULT;
- } else {
- result = count;
- *ppos += count;
- }
-
+ result = simple_read_from_buffer(buffer, count, ppos,
+ dev->bulk_in_buffer, IMGSIZE);
/* unlock the device */
up(&dev->sem);
return result;
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index 90a96257d6ce..2997f558159b 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -9,7 +9,7 @@
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
#include <linux/usb.h>
@@ -381,7 +381,6 @@ alloc_sglist (int nents, int max, int vary)
sg = kmalloc (nents * sizeof *sg, SLAB_KERNEL);
if (!sg)
return NULL;
- memset (sg, 0, nents * sizeof *sg);
for (i = 0; i < nents; i++) {
char *buf;
@@ -394,9 +393,7 @@ alloc_sglist (int nents, int max, int vary)
memset (buf, 0, size);
/* kmalloc pages are always physically contiguous! */
- sg [i].page = virt_to_page (buf);
- sg [i].offset = offset_in_page (buf);
- sg [i].length = size;
+ sg_init_one(&sg[i], buf, size);
if (vary) {
size += vary;
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 1cd942abb580..7192b770bfb6 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -494,7 +494,7 @@ config FB_TGA
config FB_VESA
bool "VESA VGA graphics support"
- depends on (FB = y) && (X86 || X86_64)
+ depends on (FB = y) && X86
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
@@ -712,7 +712,7 @@ config FB_RIVA_DEBUG
config FB_I810
tristate "Intel 810/815 support (EXPERIMENTAL)"
- depends on FB && EXPERIMENTAL && PCI && X86 && !X86_64
+ depends on FB && EXPERIMENTAL && PCI && X86_32
select AGP
select AGP_INTEL
select FB_MODE_HELPERS
@@ -761,7 +761,7 @@ config FB_I810_I2C
config FB_INTEL
tristate "Intel 830M/845G/852GM/855GM/865G support (EXPERIMENTAL)"
- depends on FB && EXPERIMENTAL && PCI && X86 && !X86_64
+ depends on FB && EXPERIMENTAL && PCI && X86_32
select AGP
select AGP_INTEL
select FB_MODE_HELPERS
@@ -1376,7 +1376,7 @@ config FB_HIT
config FB_PMAG_AA
bool "PMAG-AA TURBOchannel framebuffer support"
- depends on (FB = y) && MACH_DECSTATION && TC
+ depends on (FB = y) && TC
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
@@ -1387,7 +1387,7 @@ config FB_PMAG_AA
config FB_PMAG_BA
bool "PMAG-BA TURBOchannel framebuffer support"
- depends on (FB = y) && MACH_DECSTATION && TC
+ depends on (FB = y) && TC
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
@@ -1398,7 +1398,7 @@ config FB_PMAG_BA
config FB_PMAGB_B
bool "PMAGB-B TURBOchannel framebuffer support"
- depends on (FB = y) && MACH_DECSTATION && TC
+ depends on (FB = y) && TC
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
@@ -1410,7 +1410,7 @@ config FB_PMAGB_B
config FB_MAXINE
bool "Maxine (Personal DECstation) onboard framebuffer support"
- depends on (FB = y) && MACH_DECSTATION && TC
+ depends on (FB = y) && MACH_DECSTATION
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 1fff29f48ca8..97c5d03ac8d9 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -86,7 +86,7 @@ obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o
obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o
obj-$(CONFIG_FB_PXA) += pxafb.o
obj-$(CONFIG_FB_W100) += w100fb.o
-obj-$(CONFIG_FB_AU1100) += au1100fb.o fbgen.o
+obj-$(CONFIG_FB_AU1100) += au1100fb.o
obj-$(CONFIG_FB_PMAG_AA) += pmag-aa-fb.o
obj-$(CONFIG_FB_PMAG_BA) += pmag-ba-fb.o
obj-$(CONFIG_FB_PMAGB_B) += pmagb-b-fb.o
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
index b6fe30c3ad62..a5129806172f 100644
--- a/drivers/video/au1100fb.c
+++ b/drivers/video/au1100fb.c
@@ -2,6 +2,11 @@
* BRIEF MODULE DESCRIPTION
* Au1100 LCD Driver.
*
+ * Rewritten for 2.6 by Embedded Alley Solutions
+ * <source@embeddedalley.com>, based on submissions by
+ * Karl Lessard <klessard@sunrisetelecom.com>
+ * <c.pellegrin@exadron.com>
+ *
* Copyright 2002 MontaVista Software
* Author: MontaVista Software, Inc.
* ppopov@mvista.com or source@mvista.com
@@ -33,298 +38,253 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/init.h>
-#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/ctype.h>
+#include <linux/dma-mapping.h>
-#include <asm/au1000.h>
-#include <asm/pb1100.h>
-#include "au1100fb.h"
+#include <asm/mach-au1x00/au1000.h>
-#include <video/fbcon.h>
-#include <video/fbcon-mfb.h>
-#include <video/fbcon-cfb2.h>
-#include <video/fbcon-cfb4.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
+#define DEBUG 0
+
+#include "au1100fb.h"
/*
* Sanity check. If this is a new Au1100 based board, search for
* the PB1100 ifdefs to make sure you modify the code accordingly.
*/
-#if defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_HYDROGEN3)
+#if defined(CONFIG_MIPS_PB1100)
+ #include <asm/mach-pb1x00/pb1100.h>
+#elif defined(CONFIG_MIPS_DB1100)
+ #include <asm/mach-db1x00/db1x00.h>
#else
-error Unknown Au1100 board
+ #error "Unknown Au1100 board, Au1100 FB driver not supported"
#endif
-#define CMAPSIZE 16
-
-static int my_lcd_index; /* default is zero */
-struct known_lcd_panels *p_lcd;
-AU1100_LCD *p_lcd_reg = (AU1100_LCD *)AU1100_LCD_ADDR;
-
-struct au1100fb_info {
- struct fb_info_gen gen;
- unsigned long fb_virt_start;
- unsigned long fb_size;
- unsigned long fb_phys;
- int mmaped;
- int nohwcursor;
+#define DRIVER_NAME "au1100fb"
+#define DRIVER_DESC "LCD controller driver for AU1100 processors"
- struct { unsigned red, green, blue, pad; } palette[256];
+#define to_au1100fb_device(_info) \
+ (_info ? container_of(_info, struct au1100fb_device, info) : NULL);
-#if defined(FBCON_HAS_CFB16)
- u16 fbcon_cmap16[16];
-#endif
+/* Bitfields format supported by the controller. Note that the order of formats
+ * SHOULD be the same as in the LCD_CONTROL_SBPPF field, so we can retrieve the
+ * right pixel format by doing rgb_bitfields[LCD_CONTROL_SBPPF_XXX >> LCD_CONTROL_SBPPF]
+ */
+struct fb_bitfield rgb_bitfields[][4] =
+{
+ /* Red, Green, Blue, Transp */
+ { { 10, 6, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 0, 0, 0 } },
+ { { 11, 5, 0 }, { 5, 6, 0 }, { 0, 5, 0 }, { 0, 0, 0 } },
+ { { 11, 5, 0 }, { 6, 5, 0 }, { 0, 6, 0 }, { 0, 0, 0 } },
+ { { 10, 5, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 15, 1, 0 } },
+ { { 11, 5, 0 }, { 6, 5, 0 }, { 1, 5, 0 }, { 0, 1, 0 } },
+
+ /* The last is used to describe 12bpp format */
+ { { 8, 4, 0 }, { 4, 4, 0 }, { 0, 4, 0 }, { 0, 0, 0 } },
};
-
-struct au1100fb_par {
- struct fb_var_screeninfo var;
-
- int line_length; // in bytes
- int cmap_len; // color-map length
+static struct fb_fix_screeninfo au1100fb_fix __initdata = {
+ .id = "AU1100 FB",
+ .xpanstep = 1,
+ .ypanstep = 1,
+ .type = FB_TYPE_PACKED_PIXELS,
+ .accel = FB_ACCEL_NONE,
};
-
-static struct au1100fb_info fb_info;
-static struct au1100fb_par current_par;
-static struct display disp;
-
-int au1100fb_init(void);
-void au1100fb_setup(char *options, int *ints);
-static int au1100fb_mmap(struct fb_info *fb, struct file *file,
- struct vm_area_struct *vma);
-static int au1100_blank(int blank_mode, struct fb_info_gen *info);
-static int au1100fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
- u_long arg, int con, struct fb_info *info);
-
-void au1100_nocursor(struct display *p, int mode, int xx, int yy){};
-
-static struct fb_ops au1100fb_ops = {
- .owner = THIS_MODULE,
- .fb_get_fix = fbgen_get_fix,
- .fb_get_var = fbgen_get_var,
- .fb_set_var = fbgen_set_var,
- .fb_get_cmap = fbgen_get_cmap,
- .fb_set_cmap = fbgen_set_cmap,
- .fb_pan_display = fbgen_pan_display,
- .fb_ioctl = au1100fb_ioctl,
- .fb_mmap = au1100fb_mmap,
+static struct fb_var_screeninfo au1100fb_var __initdata = {
+ .activate = FB_ACTIVATE_NOW,
+ .height = -1,
+ .width = -1,
+ .vmode = FB_VMODE_NONINTERLACED,
};
-static void au1100_detect(void)
-{
- /*
- * This function should detect the current video mode settings
- * and store it as the default video mode
- */
+static struct au1100fb_drv_info drv_info;
- /*
- * Yeh, well, we're not going to change any settings so we're
- * always stuck with the default ...
+/*
+ * Set hardware with var settings. This will enable the controller with a specific
+ * mode, normally validated with the fb_check_var method
*/
-
-}
-
-static int au1100_encode_fix(struct fb_fix_screeninfo *fix,
- const void *_par, struct fb_info_gen *_info)
+int au1100fb_setmode(struct au1100fb_device *fbdev)
{
- struct au1100fb_info *info = (struct au1100fb_info *) _info;
- struct au1100fb_par *par = (struct au1100fb_par *) _par;
- struct fb_var_screeninfo *var = &par->var;
-
- memset(fix, 0, sizeof(struct fb_fix_screeninfo));
-
- fix->smem_start = info->fb_phys;
- fix->smem_len = info->fb_size;
- fix->type = FB_TYPE_PACKED_PIXELS;
- fix->type_aux = 0;
- fix->visual = (var->bits_per_pixel == 8) ?
- FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
- fix->ywrapstep = 0;
- fix->xpanstep = 1;
- fix->ypanstep = 1;
- fix->line_length = current_par.line_length;
- return 0;
-}
+ struct fb_info *info = &fbdev->info;
+ u32 words;
+ int index;
-static void set_color_bitfields(struct fb_var_screeninfo *var)
-{
- switch (var->bits_per_pixel) {
- case 8:
- var->red.offset = 0;
- var->red.length = 8;
- var->green.offset = 0;
- var->green.length = 8;
- var->blue.offset = 0;
- var->blue.length = 8;
- var->transp.offset = 0;
- var->transp.length = 0;
- break;
- case 16: /* RGB 565 */
- var->red.offset = 11;
- var->red.length = 5;
- var->green.offset = 5;
- var->green.length = 6;
- var->blue.offset = 0;
- var->blue.length = 5;
- var->transp.offset = 0;
- var->transp.length = 0;
- break;
+ if (!fbdev)
+ return -EINVAL;
+
+ /* Update var-dependent FB info */
+ if (panel_is_active(fbdev->panel) || panel_is_color(fbdev->panel)) {
+ if (info->var.bits_per_pixel <= 8) {
+ /* palettized */
+ info->var.red.offset = 0;
+ info->var.red.length = info->var.bits_per_pixel;
+ info->var.red.msb_right = 0;
+
+ info->var.green.offset = 0;
+ info->var.green.length = info->var.bits_per_pixel;
+ info->var.green.msb_right = 0;
+
+ info->var.blue.offset = 0;
+ info->var.blue.length = info->var.bits_per_pixel;
+ info->var.blue.msb_right = 0;
+
+ info->var.transp.offset = 0;
+ info->var.transp.length = 0;
+ info->var.transp.msb_right = 0;
+
+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+ info->fix.line_length = info->var.xres_virtual /
+ (8/info->var.bits_per_pixel);
+ } else {
+ /* non-palettized */
+ index = (fbdev->panel->control_base & LCD_CONTROL_SBPPF_MASK) >> LCD_CONTROL_SBPPF_BIT;
+ info->var.red = rgb_bitfields[index][0];
+ info->var.green = rgb_bitfields[index][1];
+ info->var.blue = rgb_bitfields[index][2];
+ info->var.transp = rgb_bitfields[index][3];
+
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+ info->fix.line_length = info->var.xres_virtual << 1; /* depth=16 */
+ }
+ } else {
+ /* mono */
+ info->fix.visual = FB_VISUAL_MONO10;
+ info->fix.line_length = info->var.xres_virtual / 8;
}
- var->red.msb_right = 0;
- var->green.msb_right = 0;
- var->blue.msb_right = 0;
- var->transp.msb_right = 0;
-}
+ info->screen_size = info->fix.line_length * info->var.yres_virtual;
-static int au1100_decode_var(const struct fb_var_screeninfo *var,
- void *_par, struct fb_info_gen *_info)
-{
+ /* Determine BPP mode and format */
+ fbdev->regs->lcd_control = fbdev->panel->control_base |
+ ((info->var.rotate/90) << LCD_CONTROL_SM_BIT);
- struct au1100fb_par *par = (struct au1100fb_par *)_par;
+ fbdev->regs->lcd_intenable = 0;
+ fbdev->regs->lcd_intstatus = 0;
- /*
- * Don't allow setting any of these yet: xres and yres don't
- * make sense for LCD panels.
- */
- if (var->xres != p_lcd->xres ||
- var->yres != p_lcd->yres ||
- var->xres != p_lcd->xres ||
- var->yres != p_lcd->yres) {
- return -EINVAL;
- }
- if(var->bits_per_pixel != p_lcd->bpp) {
- return -EINVAL;
- }
+ fbdev->regs->lcd_horztiming = fbdev->panel->horztiming;
- memset(par, 0, sizeof(struct au1100fb_par));
- par->var = *var;
-
- /* FIXME */
- switch (var->bits_per_pixel) {
- case 8:
- par->var.bits_per_pixel = 8;
- break;
- case 16:
- par->var.bits_per_pixel = 16;
- break;
- default:
- printk("color depth %d bpp not supported\n",
- var->bits_per_pixel);
- return -EINVAL;
+ fbdev->regs->lcd_verttiming = fbdev->panel->verttiming;
+
+ fbdev->regs->lcd_clkcontrol = fbdev->panel->clkcontrol_base;
+ fbdev->regs->lcd_dmaaddr0 = LCD_DMA_SA_N(fbdev->fb_phys);
+
+ if (panel_is_dual(fbdev->panel)) {
+ /* Second panel display seconf half of screen if possible,
+ * otherwise display the same as the first panel */
+ if (info->var.yres_virtual >= (info->var.yres << 1)) {
+ fbdev->regs->lcd_dmaaddr1 = LCD_DMA_SA_N(fbdev->fb_phys +
+ (info->fix.line_length *
+ (info->var.yres_virtual >> 1)));
+ } else {
+ fbdev->regs->lcd_dmaaddr1 = LCD_DMA_SA_N(fbdev->fb_phys);
+ }
}
- set_color_bitfields(&par->var);
- par->cmap_len = (par->var.bits_per_pixel == 8) ? 256 : 16;
- return 0;
-}
-static int au1100_encode_var(struct fb_var_screeninfo *var,
- const void *par, struct fb_info_gen *_info)
-{
+ words = info->fix.line_length / sizeof(u32);
+ if (!info->var.rotate || (info->var.rotate == 180)) {
+ words *= info->var.yres_virtual;
+ if (info->var.rotate /* 180 */) {
+ words -= (words % 8); /* should be divisable by 8 */
+ }
+ }
+ fbdev->regs->lcd_words = LCD_WRD_WRDS_N(words);
- *var = ((struct au1100fb_par *)par)->var;
- return 0;
-}
+ fbdev->regs->lcd_pwmdiv = 0;
+ fbdev->regs->lcd_pwmhi = 0;
-static void
-au1100_get_par(void *_par, struct fb_info_gen *_info)
-{
- *(struct au1100fb_par *)_par = current_par;
-}
+ /* Resume controller */
+ fbdev->regs->lcd_control |= LCD_CONTROL_GO;
-static void au1100_set_par(const void *par, struct fb_info_gen *info)
-{
- /* nothing to do: we don't change any settings */
+ return 0;
}
-static int au1100_getcolreg(unsigned regno, unsigned *red, unsigned *green,
- unsigned *blue, unsigned *transp,
- struct fb_info *info)
+/* fb_setcolreg
+ * Set color in LCD palette.
+ */
+int au1100fb_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *fbi)
{
+ struct au1100fb_device *fbdev = to_au1100fb_device(fbi);
+ u32 *palette = fbdev->regs->lcd_pallettebase;
+ u32 value;
- struct au1100fb_info* i = (struct au1100fb_info*)info;
-
- if (regno > 255)
- return 1;
+ if (regno > (AU1100_LCD_NBR_PALETTE_ENTRIES - 1))
+ return -EINVAL;
- *red = i->palette[regno].red;
- *green = i->palette[regno].green;
- *blue = i->palette[regno].blue;
- *transp = 0;
+ if (fbi->var.grayscale) {
+ /* Convert color to grayscale */
+ red = green = blue =
+ (19595 * red + 38470 * green + 7471 * blue) >> 16;
+ }
- return 0;
-}
+ if (fbi->fix.visual == FB_VISUAL_TRUECOLOR) {
+ /* Place color in the pseudopalette */
+ if (regno > 16)
+ return -EINVAL;
-static int au1100_setcolreg(unsigned regno, unsigned red, unsigned green,
- unsigned blue, unsigned transp,
- struct fb_info *info)
-{
- struct au1100fb_info* i = (struct au1100fb_info *)info;
- u32 rgbcol;
-
- if (regno > 255)
- return 1;
-
- i->palette[regno].red = red;
- i->palette[regno].green = green;
- i->palette[regno].blue = blue;
-
- switch(p_lcd->bpp) {
-#ifdef FBCON_HAS_CFB8
- case 8:
- red >>= 10;
- green >>= 10;
- blue >>= 10;
- p_lcd_reg->lcd_pallettebase[regno] = (blue&0x1f) |
- ((green&0x3f)<<5) | ((red&0x1f)<<11);
- break;
-#endif
-#ifdef FBCON_HAS_CFB16
- case 16:
- i->fbcon_cmap16[regno] =
- ((red & 0xf800) >> 0) |
- ((green & 0xfc00) >> 5) |
- ((blue & 0xf800) >> 11);
- break;
-#endif
- default:
- break;
+ palette = (u32*)fbi->pseudo_palette;
+
+ red >>= (16 - fbi->var.red.length);
+ green >>= (16 - fbi->var.green.length);
+ blue >>= (16 - fbi->var.blue.length);
+
+ value = (red << fbi->var.red.offset) |
+ (green << fbi->var.green.offset)|
+ (blue << fbi->var.blue.offset);
+ value &= 0xFFFF;
+
+ } else if (panel_is_active(fbdev->panel)) {
+ /* COLOR TFT PALLETTIZED (use RGB 565) */
+ value = (red & 0xF800)|((green >> 5) & 0x07E0)|((blue >> 11) & 0x001F);
+ value &= 0xFFFF;
+
+ } else if (panel_is_color(fbdev->panel)) {
+ /* COLOR STN MODE */
+ value = (((panel_swap_rgb(fbdev->panel) ? blue : red) >> 12) & 0x000F) |
+ ((green >> 8) & 0x00F0) |
+ (((panel_swap_rgb(fbdev->panel) ? red : blue) >> 4) & 0x0F00);
+ value &= 0xFFF;
+ } else {
+ /* MONOCHROME MODE */
+ value = (green >> 12) & 0x000F;
+ value &= 0xF;
}
+ palette[regno] = value;
+
return 0;
}
-
-static int au1100_blank(int blank_mode, struct fb_info_gen *_info)
+/* fb_blank
+ * Blank the screen. Depending on the mode, the screen will be
+ * activated with the backlight color, or desactivated
+ */
+int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi)
{
+ struct au1100fb_device *fbdev = to_au1100fb_device(fbi);
+
+ print_dbg("fb_blank %d %p", blank_mode, fbi);
switch (blank_mode) {
+
case VESA_NO_BLANKING:
- /* turn on panel */
- //printk("turn on panel\n");
+ /* Turn on panel */
+ fbdev->regs->lcd_control |= LCD_CONTROL_GO;
#ifdef CONFIG_MIPS_PB1100
- p_lcd_reg->lcd_control |= LCD_CONTROL_GO;
- au_writew(au_readw(PB1100_G_CONTROL) | p_lcd->mode_backlight,
+ if (drv_info.panel_idx == 1) {
+ au_writew(au_readw(PB1100_G_CONTROL)
+ | (PB1100_G_CONTROL_BL | PB1100_G_CONTROL_VDD),
PB1100_G_CONTROL);
-#endif
-#ifdef CONFIG_MIPS_HYDROGEN3
- /* Turn controller & power supply on, GPIO213 */
- au_writel(0x20002000, 0xB1700008);
- au_writel(0x00040000, 0xB1900108);
- au_writel(0x01000100, 0xB1700008);
+ }
#endif
au_sync();
break;
@@ -332,12 +292,14 @@ static int au1100_blank(int blank_mode, struct fb_info_gen *_info)
case VESA_VSYNC_SUSPEND:
case VESA_HSYNC_SUSPEND:
case VESA_POWERDOWN:
- /* turn off panel */
- //printk("turn off panel\n");
+ /* Turn off panel */
+ fbdev->regs->lcd_control &= ~LCD_CONTROL_GO;
#ifdef CONFIG_MIPS_PB1100
- au_writew(au_readw(PB1100_G_CONTROL) & ~p_lcd->mode_backlight,
+ if (drv_info.panel_idx == 1) {
+ au_writew(au_readw(PB1100_G_CONTROL)
+ & ~(PB1100_G_CONTROL_BL | PB1100_G_CONTROL_VDD),
PB1100_G_CONTROL);
- p_lcd_reg->lcd_control &= ~LCD_CONTROL_GO;
+ }
#endif
au_sync();
break;
@@ -348,49 +310,87 @@ static int au1100_blank(int blank_mode, struct fb_info_gen *_info)
return 0;
}
-static void au1100_set_disp(const void *unused, struct display *disp,
- struct fb_info_gen *info)
+/* fb_pan_display
+ * Pan display in x and/or y as specified
+ */
+int au1100fb_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fbi)
{
- disp->screen_base = (char *)fb_info.fb_virt_start;
-
- switch (disp->var.bits_per_pixel) {
-#ifdef FBCON_HAS_CFB8
- case 8:
- disp->dispsw = &fbcon_cfb8;
- if (fb_info.nohwcursor)
- fbcon_cfb8.cursor = au1100_nocursor;
- break;
-#endif
-#ifdef FBCON_HAS_CFB16
- case 16:
- disp->dispsw = &fbcon_cfb16;
- disp->dispsw_data = fb_info.fbcon_cmap16;
- if (fb_info.nohwcursor)
- fbcon_cfb16.cursor = au1100_nocursor;
- break;
-#endif
- default:
- disp->dispsw = &fbcon_dummy;
- disp->dispsw_data = NULL;
- break;
+ struct au1100fb_device *fbdev = to_au1100fb_device(fbi);
+ int dy;
+
+ print_dbg("fb_pan_display %p %p", var, fbi);
+
+ if (!var || !fbdev) {
+ return -EINVAL;
+ }
+
+ if (var->xoffset - fbi->var.xoffset) {
+ /* No support for X panning for now! */
+ return -EINVAL;
+ }
+
+ print_dbg("fb_pan_display 2 %p %p", var, fbi);
+ dy = var->yoffset - fbi->var.yoffset;
+ if (dy) {
+
+ u32 dmaaddr;
+
+ print_dbg("Panning screen of %d lines", dy);
+
+ dmaaddr = fbdev->regs->lcd_dmaaddr0;
+ dmaaddr += (fbi->fix.line_length * dy);
+
+ /* TODO: Wait for current frame to finished */
+ fbdev->regs->lcd_dmaaddr0 = LCD_DMA_SA_N(dmaaddr);
+
+ if (panel_is_dual(fbdev->panel)) {
+ dmaaddr = fbdev->regs->lcd_dmaaddr1;
+ dmaaddr += (fbi->fix.line_length * dy);
+ fbdev->regs->lcd_dmaaddr0 = LCD_DMA_SA_N(dmaaddr);
+ }
+ }
+ print_dbg("fb_pan_display 3 %p %p", var, fbi);
+
+ return 0;
+}
+
+/* fb_rotate
+ * Rotate the display of this angle. This doesn't seems to be used by the core,
+ * but as our hardware supports it, so why not implementing it...
+ */
+void au1100fb_fb_rotate(struct fb_info *fbi, int angle)
+{
+ struct au1100fb_device *fbdev = to_au1100fb_device(fbi);
+
+ print_dbg("fb_rotate %p %d", fbi, angle);
+
+ if (fbdev && (angle > 0) && !(angle % 90)) {
+
+ fbdev->regs->lcd_control &= ~LCD_CONTROL_GO;
+
+ fbdev->regs->lcd_control &= ~(LCD_CONTROL_SM_MASK);
+ fbdev->regs->lcd_control |= ((angle/90) << LCD_CONTROL_SM_BIT);
+
+ fbdev->regs->lcd_control |= LCD_CONTROL_GO;
}
}
-static int
-au1100fb_mmap(struct fb_info *_fb,
- struct file *file,
- struct vm_area_struct *vma)
+/* fb_mmap
+ * Map video memory in user space. We don't use the generic fb_mmap method mainly
+ * to allow the use of the TLB streaming flag (CCA=6)
+ */
+int au1100fb_fb_mmap(struct fb_info *fbi, struct file *file, struct vm_area_struct *vma)
{
+ struct au1100fb_device *fbdev = to_au1100fb_device(fbi);
unsigned int len;
unsigned long start=0, off;
- struct au1100fb_info *fb = (struct au1100fb_info *)_fb;
if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
return -EINVAL;
}
- start = fb_info.fb_phys & PAGE_MASK;
- len = PAGE_ALIGN((start & ~PAGE_MASK) + fb_info.fb_size);
+ start = fbdev->fb_phys & PAGE_MASK;
+ len = PAGE_ALIGN((start & ~PAGE_MASK) + fbdev->fb_len);
off = vma->vm_pgoff << PAGE_SHIFT;
@@ -401,276 +401,309 @@ au1100fb_mmap(struct fb_info *_fb,
off += start;
vma->vm_pgoff = off >> PAGE_SHIFT;
- pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK;
- //pgprot_val(vma->vm_page_prot) |= _CACHE_CACHABLE_NONCOHERENT;
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
pgprot_val(vma->vm_page_prot) |= (6 << 9); //CCA=6
- /* This is an IO map - tell maydump to skip this VMA */
vma->vm_flags |= VM_IO;
- if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
+ if (io_remap_page_range(vma, vma->vm_start, off,
vma->vm_end - vma->vm_start,
vma->vm_page_prot)) {
return -EAGAIN;
}
- fb->mmaped = 1;
return 0;
}
-int au1100_pan_display(const struct fb_var_screeninfo *var,
- struct fb_info_gen *info)
+static struct fb_ops au1100fb_ops =
{
- return 0;
-}
+ .owner = THIS_MODULE,
+ .fb_setcolreg = au1100fb_fb_setcolreg,
+ .fb_blank = au1100fb_fb_blank,
+ .fb_pan_display = au1100fb_fb_pan_display,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+ .fb_rotate = au1100fb_fb_rotate,
+ .fb_mmap = au1100fb_fb_mmap,
+};
-static int au1100fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
- u_long arg, int con, struct fb_info *info)
-{
- /* nothing to do yet */
- return -EINVAL;
-}
-static struct fbgen_hwswitch au1100_switch = {
- au1100_detect,
- au1100_encode_fix,
- au1100_decode_var,
- au1100_encode_var,
- au1100_get_par,
- au1100_set_par,
- au1100_getcolreg,
- au1100_setcolreg,
- au1100_pan_display,
- au1100_blank,
- au1100_set_disp
-};
+/*-------------------------------------------------------------------------*/
+/* AU1100 LCD controller device driver */
-int au1100_setmode(void)
+int au1100fb_drv_probe(struct device *dev)
{
- int words;
-
- /* FIXME Need to accomodate for swivel mode and 12bpp, <8bpp*/
- switch (p_lcd->mode_control & LCD_CONTROL_SM)
- {
- case LCD_CONTROL_SM_0:
- case LCD_CONTROL_SM_180:
- words = (p_lcd->xres * p_lcd->yres * p_lcd->bpp) / 32;
- break;
- case LCD_CONTROL_SM_90:
- case LCD_CONTROL_SM_270:
- /* is this correct? */
- words = (p_lcd->xres * p_lcd->bpp) / 8;
- break;
- default:
- printk("mode_control reg not initialized\n");
+ struct au1100fb_device *fbdev = NULL;
+ struct resource *regs_res;
+ unsigned long page;
+ u32 sys_clksrc;
+
+ if (!dev)
return -EINVAL;
+
+ /* Allocate new device private */
+ if (!(fbdev = kmalloc(sizeof(struct au1100fb_device), GFP_KERNEL))) {
+ print_err("fail to allocate device private record");
+ return -ENOMEM;
}
+ memset((void*)fbdev, 0, sizeof(struct au1100fb_device));
- /*
- * Setup LCD controller
- */
+ fbdev->panel = &known_lcd_panels[drv_info.panel_idx];
- p_lcd_reg->lcd_control = p_lcd->mode_control;
- p_lcd_reg->lcd_intstatus = 0;
- p_lcd_reg->lcd_intenable = 0;
- p_lcd_reg->lcd_horztiming = p_lcd->mode_horztiming;
- p_lcd_reg->lcd_verttiming = p_lcd->mode_verttiming;
- p_lcd_reg->lcd_clkcontrol = p_lcd->mode_clkcontrol;
- p_lcd_reg->lcd_words = words - 1;
- p_lcd_reg->lcd_dmaaddr0 = fb_info.fb_phys;
+ dev_set_drvdata(dev, (void*)fbdev);
- /* turn on panel */
-#ifdef CONFIG_MIPS_PB1100
- au_writew(au_readw(PB1100_G_CONTROL) | p_lcd->mode_backlight,
- PB1100_G_CONTROL);
-#endif
-#ifdef CONFIG_MIPS_HYDROGEN3
- /* Turn controller & power supply on, GPIO213 */
- au_writel(0x20002000, 0xB1700008);
- au_writel(0x00040000, 0xB1900108);
- au_writel(0x01000100, 0xB1700008);
-#endif
+ /* Allocate region for our registers and map them */
+ if (!(regs_res = platform_get_resource(to_platform_device(dev),
+ IORESOURCE_MEM, 0))) {
+ print_err("fail to retrieve registers resource");
+ return -EFAULT;
+ }
- p_lcd_reg->lcd_control |= LCD_CONTROL_GO;
+ au1100fb_fix.mmio_start = regs_res->start;
+ au1100fb_fix.mmio_len = regs_res->end - regs_res->start + 1;
- return 0;
-}
+ if (!request_mem_region(au1100fb_fix.mmio_start, au1100fb_fix.mmio_len,
+ DRIVER_NAME)) {
+ print_err("fail to lock memory region at 0x%08x",
+ au1100fb_fix.mmio_start);
+ return -EBUSY;
+ }
+ fbdev->regs = (struct au1100fb_regs*)KSEG1ADDR(au1100fb_fix.mmio_start);
-int __init au1100fb_init(void)
-{
- uint32 sys_clksrc;
- unsigned long page;
+ print_dbg("Register memory map at %p", fbdev->regs);
+ print_dbg("phys=0x%08x, size=%d", fbdev->regs_phys, fbdev->regs_len);
- /*
- * Get the panel information/display mode and update the registry
- */
- p_lcd = &panels[my_lcd_index];
-
- switch (p_lcd->mode_control & LCD_CONTROL_SM)
- {
- case LCD_CONTROL_SM_0:
- case LCD_CONTROL_SM_180:
- p_lcd->xres =
- (p_lcd->mode_horztiming & LCD_HORZTIMING_PPL) + 1;
- p_lcd->yres =
- (p_lcd->mode_verttiming & LCD_VERTTIMING_LPP) + 1;
- break;
- case LCD_CONTROL_SM_90:
- case LCD_CONTROL_SM_270:
- p_lcd->yres =
- (p_lcd->mode_horztiming & LCD_HORZTIMING_PPL) + 1;
- p_lcd->xres =
- (p_lcd->mode_verttiming & LCD_VERTTIMING_LPP) + 1;
- break;
- }
- /*
- * Panel dimensions x bpp must be divisible by 32
- */
- if (((p_lcd->yres * p_lcd->bpp) % 32) != 0)
- printk("VERT %% 32\n");
- if (((p_lcd->xres * p_lcd->bpp) % 32) != 0)
- printk("HORZ %% 32\n");
- /*
- * Allocate LCD framebuffer from system memory
- */
- fb_info.fb_size = (p_lcd->xres * p_lcd->yres * p_lcd->bpp) / 8;
-
- current_par.var.xres = p_lcd->xres;
- current_par.var.xres_virtual = p_lcd->xres;
- current_par.var.yres = p_lcd->yres;
- current_par.var.yres_virtual = p_lcd->yres;
- current_par.var.bits_per_pixel = p_lcd->bpp;
-
- /* FIX!!! only works for 8/16 bpp */
- current_par.line_length = p_lcd->xres * p_lcd->bpp / 8; /* in bytes */
- fb_info.fb_virt_start = (unsigned long )
- __get_free_pages(GFP_ATOMIC | GFP_DMA,
- get_order(fb_info.fb_size + 0x1000));
- if (!fb_info.fb_virt_start) {
- printk("Unable to allocate fb memory\n");
+ /* Allocate the framebuffer to the maximum screen size * nbr of video buffers */
+ fbdev->fb_len = fbdev->panel->xres * fbdev->panel->yres *
+ (fbdev->panel->bpp >> 3) * AU1100FB_NBR_VIDEO_BUFFERS;
+
+ fbdev->fb_mem = dma_alloc_coherent(dev, PAGE_ALIGN(fbdev->fb_len),
+ &fbdev->fb_phys, GFP_KERNEL);
+ if (!fbdev->fb_mem) {
+ print_err("fail to allocate frambuffer (size: %dK))",
+ fbdev->fb_len / 1024);
return -ENOMEM;
}
- fb_info.fb_phys = virt_to_bus((void *)fb_info.fb_virt_start);
+
+ au1100fb_fix.smem_start = fbdev->fb_phys;
+ au1100fb_fix.smem_len = fbdev->fb_len;
/*
* Set page reserved so that mmap will work. This is necessary
* since we'll be remapping normal memory.
*/
- for (page = fb_info.fb_virt_start;
- page < PAGE_ALIGN(fb_info.fb_virt_start + fb_info.fb_size);
+ for (page = (unsigned long)fbdev->fb_mem;
+ page < PAGE_ALIGN((unsigned long)fbdev->fb_mem + fbdev->fb_len);
page += PAGE_SIZE) {
+#if CONFIG_DMA_NONCOHERENT
+ SetPageReserved(virt_to_page(CAC_ADDR(page)));
+#else
SetPageReserved(virt_to_page(page));
+#endif
}
- memset((void *)fb_info.fb_virt_start, 0, fb_info.fb_size);
-
- /* set freqctrl now to allow more time to stabilize */
- /* zero-out out LCD bits */
- sys_clksrc = au_readl(SYS_CLKSRC) & ~0x000003e0;
- sys_clksrc |= p_lcd->mode_toyclksrc;
- au_writel(sys_clksrc, SYS_CLKSRC);
-
- /* FIXME add check to make sure auxpll is what is expected! */
- au1100_setmode();
-
- fb_info.gen.parsize = sizeof(struct au1100fb_par);
- fb_info.gen.fbhw = &au1100_switch;
-
- strcpy(fb_info.gen.info.modename, "Au1100 LCD");
- fb_info.gen.info.changevar = NULL;
- fb_info.gen.info.node = -1;
-
- fb_info.gen.info.fbops = &au1100fb_ops;
- fb_info.gen.info.disp = &disp;
- fb_info.gen.info.switch_con = &fbgen_switch;
- fb_info.gen.info.updatevar = &fbgen_update_var;
- fb_info.gen.info.blank = &fbgen_blank;
- fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;
-
- /* This should give a reasonable default video mode */
- fbgen_get_var(&disp.var, -1, &fb_info.gen.info);
- fbgen_do_set_var(&disp.var, 1, &fb_info.gen);
- fbgen_set_disp(-1, &fb_info.gen);
- fbgen_install_cmap(0, &fb_info.gen);
- if (register_framebuffer(&fb_info.gen.info) < 0)
- return -EINVAL;
- printk(KERN_INFO "fb%d: %s frame buffer device\n",
- GET_FB_IDX(fb_info.gen.info.node),
- fb_info.gen.info.modename);
+ print_dbg("Framebuffer memory map at %p", fbdev->fb_mem);
+ print_dbg("phys=0x%08x, size=%dK", fbdev->fb_phys, fbdev->fb_len / 1024);
+
+ /* Setup LCD clock to AUX (48 MHz) */
+ sys_clksrc = au_readl(SYS_CLKSRC) & ~(SYS_CS_ML_MASK | SYS_CS_DL | SYS_CS_CL);
+ au_writel((sys_clksrc | (1 << SYS_CS_ML_BIT)), SYS_CLKSRC);
+
+ /* load the panel info into the var struct */
+ au1100fb_var.bits_per_pixel = fbdev->panel->bpp;
+ au1100fb_var.xres = fbdev->panel->xres;
+ au1100fb_var.xres_virtual = au1100fb_var.xres;
+ au1100fb_var.yres = fbdev->panel->yres;
+ au1100fb_var.yres_virtual = au1100fb_var.yres;
+
+ fbdev->info.screen_base = fbdev->fb_mem;
+ fbdev->info.fbops = &au1100fb_ops;
+ fbdev->info.fix = au1100fb_fix;
+
+ if (!(fbdev->info.pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL))) {
+ return -ENOMEM;
+ }
+ memset(fbdev->info.pseudo_palette, 0, sizeof(u32) * 16);
+
+ if (fb_alloc_cmap(&fbdev->info.cmap, AU1100_LCD_NBR_PALETTE_ENTRIES, 0) < 0) {
+ print_err("Fail to allocate colormap (%d entries)",
+ AU1100_LCD_NBR_PALETTE_ENTRIES);
+ kfree(fbdev->info.pseudo_palette);
+ return -EFAULT;
+ }
+
+ fbdev->info.var = au1100fb_var;
+
+ /* Set h/w registers */
+ au1100fb_setmode(fbdev);
+
+ /* Register new framebuffer */
+ if (register_framebuffer(&fbdev->info) < 0) {
+ print_err("cannot register new framebuffer");
+ goto failed;
+ }
+
+ return 0;
+
+failed:
+ if (fbdev->regs) {
+ release_mem_region(fbdev->regs_phys, fbdev->regs_len);
+ }
+ if (fbdev->fb_mem) {
+ dma_free_noncoherent(dev, fbdev->fb_len, fbdev->fb_mem, fbdev->fb_phys);
+ }
+ if (fbdev->info.cmap.len != 0) {
+ fb_dealloc_cmap(&fbdev->info.cmap);
+ }
+ kfree(fbdev);
+ dev_set_drvdata(dev, NULL);
return 0;
}
+int au1100fb_drv_remove(struct device *dev)
+{
+ struct au1100fb_device *fbdev = NULL;
+
+ if (!dev)
+ return -ENODEV;
+
+ fbdev = (struct au1100fb_device*) dev_get_drvdata(dev);
+
+#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
+ au1100fb_fb_blank(VESA_POWERDOWN, &fbdev->info);
+#endif
+ fbdev->regs->lcd_control &= ~LCD_CONTROL_GO;
-void au1100fb_cleanup(struct fb_info *info)
+ /* Clean up all probe data */
+ unregister_framebuffer(&fbdev->info);
+
+ release_mem_region(fbdev->regs_phys, fbdev->regs_len);
+
+ dma_free_coherent(dev, PAGE_ALIGN(fbdev->fb_len), fbdev->fb_mem, fbdev->fb_phys);
+
+ fb_dealloc_cmap(&fbdev->info.cmap);
+ kfree(fbdev->info.pseudo_palette);
+ kfree((void*)fbdev);
+
+ return 0;
+}
+
+int au1100fb_drv_suspend(struct device *dev, u32 state, u32 level)
+{
+ /* TODO */
+ return 0;
+}
+
+int au1100fb_drv_resume(struct device *dev, u32 level)
{
- unregister_framebuffer(info);
+ /* TODO */
+ return 0;
}
+static struct device_driver au1100fb_driver = {
+ .name = "au1100-lcd",
+ .bus = &platform_bus_type,
-void au1100fb_setup(char *options, int *ints)
+ .probe = au1100fb_drv_probe,
+ .remove = au1100fb_drv_remove,
+ .suspend = au1100fb_drv_suspend,
+ .resume = au1100fb_drv_resume,
+};
+
+/*-------------------------------------------------------------------------*/
+
+/* Kernel driver */
+
+int au1100fb_setup(char *options)
{
char* this_opt;
- int i;
- int num_panels = sizeof(panels)/sizeof(struct known_lcd_panels);
+ int num_panels = ARRAY_SIZE(known_lcd_panels);
+ char* mode = NULL;
+ int panel_idx = 0;
+ if (num_panels <= 0) {
+ print_err("No LCD panels supported by driver!");
+ return -EFAULT;
+ }
- if (!options || !*options)
- return;
-
- for(this_opt=strtok(options, ","); this_opt;
- this_opt=strtok(NULL, ",")) {
+ if (options) {
+ while ((this_opt = strsep(&options,",")) != NULL) {
+ /* Panel option */
if (!strncmp(this_opt, "panel:", 6)) {
-#if defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_DB1100)
- /* Read Pb1100 Switch S10 ? */
- if (!strncmp(this_opt+6, "s10", 3))
- {
- int panel;
- panel = *(volatile int *)0xAE000008; /* BCSR SWITCHES */
- panel >>= 8;
- panel &= 0x0F;
- if (panel >= num_panels) panel = 0;
- my_lcd_index = panel;
- }
- else
-#endif
- /* Get the panel name, everything else if fixed */
- for (i=0; i<num_panels; i++) {
- if (!strncmp(this_opt+6, panels[i].panel_name,
+ int i;
+ this_opt += 6;
+ for (i = 0; i < num_panels; i++) {
+ if (!strncmp(this_opt,
+ known_lcd_panels[i].name,
strlen(this_opt))) {
- my_lcd_index = i;
+ panel_idx = i;
break;
}
}
+ if (i >= num_panels) {
+ print_warn("Panel %s not supported!", this_opt);
+ }
+ }
+ /* Mode option (only option that start with digit) */
+ else if (isdigit(this_opt[0])) {
+ mode = kmalloc(strlen(this_opt) + 1, GFP_KERNEL);
+ strncpy(mode, this_opt, strlen(this_opt) + 1);
+ }
+ /* Unsupported option */
+ else {
+ print_warn("Unsupported option \"%s\"", this_opt);
}
- else if (!strncmp(this_opt, "nohwcursor", 10)) {
- printk("nohwcursor\n");
- fb_info.nohwcursor = 1;
}
}
- printk("au1100fb: Panel %d %s\n", my_lcd_index,
- panels[my_lcd_index].panel_name);
-}
+ drv_info.panel_idx = panel_idx;
+ drv_info.opt_mode = mode;
+ print_info("Panel=%s Mode=%s",
+ known_lcd_panels[drv_info.panel_idx].name,
+ drv_info.opt_mode ? drv_info.opt_mode : "default");
+ return 0;
+}
-#ifdef MODULE
-MODULE_LICENSE("GPL");
-int init_module(void)
+int __init au1100fb_init(void)
{
- return au1100fb_init();
+ char* options;
+ int ret;
+
+ print_info("" DRIVER_DESC "");
+
+ memset(&drv_info, 0, sizeof(drv_info));
+
+ if (fb_get_options(DRIVER_NAME, &options))
+ return -ENODEV;
+
+ /* Setup driver with options */
+ ret = au1100fb_setup(options);
+ if (ret < 0) {
+ print_err("Fail to setup driver");
+ return ret;
+ }
+
+ return driver_register(&au1100fb_driver);
}
-void cleanup_module(void)
+void __exit au1100fb_cleanup(void)
{
- au1100fb_cleanup(void);
+ driver_unregister(&au1100fb_driver);
+
+ if (drv_info.opt_mode)
+ kfree(drv_info.opt_mode);
}
-MODULE_AUTHOR("Pete Popov <ppopov@mvista.com>");
-MODULE_DESCRIPTION("Au1100 LCD framebuffer device driver");
-#endif /* MODULE */
+module_init(au1100fb_init);
+module_exit(au1100fb_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/au1100fb.h b/drivers/video/au1100fb.h
index 657c560ab73c..2855534dc235 100644
--- a/drivers/video/au1100fb.h
+++ b/drivers/video/au1100fb.h
@@ -30,352 +30,352 @@
#ifndef _AU1100LCD_H
#define _AU1100LCD_H
+#include <asm/mach-au1x00/au1000.h>
+
+#define print_err(f, arg...) printk(KERN_ERR DRIVER_NAME ": " f "\n", ## arg)
+#define print_warn(f, arg...) printk(KERN_WARNING DRIVER_NAME ": " f "\n", ## arg)
+#define print_info(f, arg...) printk(KERN_INFO DRIVER_NAME ": " f "\n", ## arg)
+
+#if DEBUG
+#define print_dbg(f, arg...) printk(__FILE__ ": " f "\n", ## arg)
+#else
+#define print_dbg(f, arg...) do {} while (0)
+#endif
+
+#if defined(__BIG_ENDIAN)
+#define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_11
+#else
+#define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_00
+#endif
+#define LCD_CONTROL_DEFAULT_SBPPF LCD_CONTROL_SBPPF_565
+
/********************************************************************/
-#define uint32 unsigned long
-typedef volatile struct
-{
- uint32 lcd_control;
- uint32 lcd_intstatus;
- uint32 lcd_intenable;
- uint32 lcd_horztiming;
- uint32 lcd_verttiming;
- uint32 lcd_clkcontrol;
- uint32 lcd_dmaaddr0;
- uint32 lcd_dmaaddr1;
- uint32 lcd_words;
- uint32 lcd_pwmdiv;
- uint32 lcd_pwmhi;
- uint32 reserved[(0x0400-0x002C)/4];
- uint32 lcd_pallettebase[256];
-
-} AU1100_LCD;
+
+/* LCD controller restrictions */
+#define AU1100_LCD_MAX_XRES 800
+#define AU1100_LCD_MAX_YRES 600
+#define AU1100_LCD_MAX_BPP 16
+#define AU1100_LCD_MAX_CLK 48000000
+#define AU1100_LCD_NBR_PALETTE_ENTRIES 256
+
+/* Default number of visible screen buffer to allocate */
+#define AU1100FB_NBR_VIDEO_BUFFERS 4
/********************************************************************/
-#define AU1100_LCD_ADDR 0xB5000000
+struct au1100fb_panel
+{
+ const char name[25]; /* Full name <vendor>_<model> */
-/*
- * Register bit definitions
- */
+ u32 control_base; /* Mode-independent control values */
+ u32 clkcontrol_base; /* Panel pixclock preferences */
-/* lcd_control */
-#define LCD_CONTROL_SBPPF (7<<18)
-#define LCD_CONTROL_SBPPF_655 (0<<18)
-#define LCD_CONTROL_SBPPF_565 (1<<18)
-#define LCD_CONTROL_SBPPF_556 (2<<18)
-#define LCD_CONTROL_SBPPF_1555 (3<<18)
-#define LCD_CONTROL_SBPPF_5551 (4<<18)
-#define LCD_CONTROL_WP (1<<17)
-#define LCD_CONTROL_WD (1<<16)
-#define LCD_CONTROL_C (1<<15)
-#define LCD_CONTROL_SM (3<<13)
-#define LCD_CONTROL_SM_0 (0<<13)
-#define LCD_CONTROL_SM_90 (1<<13)
-#define LCD_CONTROL_SM_180 (2<<13)
-#define LCD_CONTROL_SM_270 (3<<13)
-#define LCD_CONTROL_DB (1<<12)
-#define LCD_CONTROL_CCO (1<<11)
-#define LCD_CONTROL_DP (1<<10)
-#define LCD_CONTROL_PO (3<<8)
-#define LCD_CONTROL_PO_00 (0<<8)
-#define LCD_CONTROL_PO_01 (1<<8)
-#define LCD_CONTROL_PO_10 (2<<8)
-#define LCD_CONTROL_PO_11 (3<<8)
-#define LCD_CONTROL_MPI (1<<7)
-#define LCD_CONTROL_PT (1<<6)
-#define LCD_CONTROL_PC (1<<5)
-#define LCD_CONTROL_BPP (7<<1)
-#define LCD_CONTROL_BPP_1 (0<<1)
-#define LCD_CONTROL_BPP_2 (1<<1)
-#define LCD_CONTROL_BPP_4 (2<<1)
-#define LCD_CONTROL_BPP_8 (3<<1)
-#define LCD_CONTROL_BPP_12 (4<<1)
-#define LCD_CONTROL_BPP_16 (5<<1)
-#define LCD_CONTROL_GO (1<<0)
-
-/* lcd_intstatus, lcd_intenable */
-#define LCD_INT_SD (1<<7)
-#define LCD_INT_OF (1<<6)
-#define LCD_INT_UF (1<<5)
-#define LCD_INT_SA (1<<3)
-#define LCD_INT_SS (1<<2)
-#define LCD_INT_S1 (1<<1)
-#define LCD_INT_S0 (1<<0)
-
-/* lcd_horztiming */
-#define LCD_HORZTIMING_HN2 (255<<24)
-#define LCD_HORZTIMING_HN2_N(N) (((N)-1)<<24)
-#define LCD_HORZTIMING_HN1 (255<<16)
-#define LCD_HORZTIMING_HN1_N(N) (((N)-1)<<16)
-#define LCD_HORZTIMING_HPW (63<<10)
-#define LCD_HORZTIMING_HPW_N(N) (((N)-1)<<10)
-#define LCD_HORZTIMING_PPL (1023<<0)
-#define LCD_HORZTIMING_PPL_N(N) (((N)-1)<<0)
-
-/* lcd_verttiming */
-#define LCD_VERTTIMING_VN2 (255<<24)
-#define LCD_VERTTIMING_VN2_N(N) (((N)-1)<<24)
-#define LCD_VERTTIMING_VN1 (255<<16)
-#define LCD_VERTTIMING_VN1_N(N) (((N)-1)<<16)
-#define LCD_VERTTIMING_VPW (63<<10)
-#define LCD_VERTTIMING_VPW_N(N) (((N)-1)<<10)
-#define LCD_VERTTIMING_LPP (1023<<0)
-#define LCD_VERTTIMING_LPP_N(N) (((N)-1)<<0)
-
-/* lcd_clkcontrol */
-#define LCD_CLKCONTROL_IB (1<<18)
-#define LCD_CLKCONTROL_IC (1<<17)
-#define LCD_CLKCONTROL_IH (1<<16)
-#define LCD_CLKCONTROL_IV (1<<15)
-#define LCD_CLKCONTROL_BF (31<<10)
-#define LCD_CLKCONTROL_BF_N(N) (((N)-1)<<10)
-#define LCD_CLKCONTROL_PCD (1023<<0)
-#define LCD_CLKCONTROL_PCD_N(N) ((N)<<0)
-
-/* lcd_pwmdiv */
-#define LCD_PWMDIV_EN (1<<12)
-#define LCD_PWMDIV_PWMDIV (2047<<0)
-#define LCD_PWMDIV_PWMDIV_N(N) (((N)-1)<<0)
-
-/* lcd_pwmhi */
-#define LCD_PWMHI_PWMHI1 (2047<<12)
-#define LCD_PWMHI_PWMHI1_N(N) ((N)<<12)
-#define LCD_PWMHI_PWMHI0 (2047<<0)
-#define LCD_PWMHI_PWMHI0_N(N) ((N)<<0)
-
-/* lcd_pallettebase - MONOCHROME */
-#define LCD_PALLETTE_MONO_MI (15<<0)
-#define LCD_PALLETTE_MONO_MI_N(N) ((N)<<0)
-
-/* lcd_pallettebase - COLOR */
-#define LCD_PALLETTE_COLOR_BI (15<<8)
-#define LCD_PALLETTE_COLOR_BI_N(N) ((N)<<8)
-#define LCD_PALLETTE_COLOR_GI (15<<4)
-#define LCD_PALLETTE_COLOR_GI_N(N) ((N)<<4)
-#define LCD_PALLETTE_COLOR_RI (15<<0)
-#define LCD_PALLETTE_COLOR_RI_N(N) ((N)<<0)
-
-/* lcd_palletebase - COLOR TFT PALLETIZED */
-#define LCD_PALLETTE_TFT_DC (65535<<0)
-#define LCD_PALLETTE_TFT_DC_N(N) ((N)<<0)
+ u32 horztiming;
+ u32 verttiming;
-/********************************************************************/
+ u32 xres; /* Maximum horizontal resolution */
+ u32 yres; /* Maximum vertical resolution */
+ u32 bpp; /* Maximum depth supported */
+};
-struct known_lcd_panels
+struct au1100fb_regs
{
- uint32 xres;
- uint32 yres;
- uint32 bpp;
- unsigned char panel_name[256];
- uint32 mode_control;
- uint32 mode_horztiming;
- uint32 mode_verttiming;
- uint32 mode_clkcontrol;
- uint32 mode_pwmdiv;
- uint32 mode_pwmhi;
- uint32 mode_toyclksrc;
- uint32 mode_backlight;
+ u32 lcd_control;
+ u32 lcd_intstatus;
+ u32 lcd_intenable;
+ u32 lcd_horztiming;
+ u32 lcd_verttiming;
+ u32 lcd_clkcontrol;
+ u32 lcd_dmaaddr0;
+ u32 lcd_dmaaddr1;
+ u32 lcd_words;
+ u32 lcd_pwmdiv;
+ u32 lcd_pwmhi;
+ u32 reserved[(0x0400-0x002C)/4];
+ u32 lcd_pallettebase[256];
+};
+
+struct au1100fb_device {
+
+ struct fb_info info; /* FB driver info record */
+ struct au1100fb_panel *panel; /* Panel connected to this device */
+
+ struct au1100fb_regs* regs; /* Registers memory map */
+ size_t regs_len;
+ unsigned int regs_phys;
+
+ unsigned char* fb_mem; /* FrameBuffer memory map */
+ size_t fb_len;
+ dma_addr_t fb_phys;
};
-#if defined(__BIG_ENDIAN)
-#define LCD_DEFAULT_PIX_FORMAT LCD_CONTROL_PO_11
-#else
-#define LCD_DEFAULT_PIX_FORMAT LCD_CONTROL_PO_00
-#endif
+/********************************************************************/
-/*
- * The fb driver assumes that AUX PLL is at 48MHz. That can
- * cover up to 800x600 resolution; if you need higher resolution,
- * you should modify the driver as needed, not just this structure.
+#define LCD_CONTROL (AU1100_LCD_BASE + 0x0)
+ #define LCD_CONTROL_SBB_BIT 21
+ #define LCD_CONTROL_SBB_MASK (0x3 << LCD_CONTROL_SBB_BIT)
+ #define LCD_CONTROL_SBB_1 (0 << LCD_CONTROL_SBB_BIT)
+ #define LCD_CONTROL_SBB_2 (1 << LCD_CONTROL_SBB_BIT)
+ #define LCD_CONTROL_SBB_3 (2 << LCD_CONTROL_SBB_BIT)
+ #define LCD_CONTROL_SBB_4 (3 << LCD_CONTROL_SBB_BIT)
+ #define LCD_CONTROL_SBPPF_BIT 18
+ #define LCD_CONTROL_SBPPF_MASK (0x7 << LCD_CONTROL_SBPPF_BIT)
+ #define LCD_CONTROL_SBPPF_655 (0 << LCD_CONTROL_SBPPF_BIT)
+ #define LCD_CONTROL_SBPPF_565 (1 << LCD_CONTROL_SBPPF_BIT)
+ #define LCD_CONTROL_SBPPF_556 (2 << LCD_CONTROL_SBPPF_BIT)
+ #define LCD_CONTROL_SBPPF_1555 (3 << LCD_CONTROL_SBPPF_BIT)
+ #define LCD_CONTROL_SBPPF_5551 (4 << LCD_CONTROL_SBPPF_BIT)
+ #define LCD_CONTROL_WP (1<<17)
+ #define LCD_CONTROL_WD (1<<16)
+ #define LCD_CONTROL_C (1<<15)
+ #define LCD_CONTROL_SM_BIT 13
+ #define LCD_CONTROL_SM_MASK (0x3 << LCD_CONTROL_SM_BIT)
+ #define LCD_CONTROL_SM_0 (0 << LCD_CONTROL_SM_BIT)
+ #define LCD_CONTROL_SM_90 (1 << LCD_CONTROL_SM_BIT)
+ #define LCD_CONTROL_SM_180 (2 << LCD_CONTROL_SM_BIT)
+ #define LCD_CONTROL_SM_270 (3 << LCD_CONTROL_SM_BIT)
+ #define LCD_CONTROL_DB (1<<12)
+ #define LCD_CONTROL_CCO (1<<11)
+ #define LCD_CONTROL_DP (1<<10)
+ #define LCD_CONTROL_PO_BIT 8
+ #define LCD_CONTROL_PO_MASK (0x3 << LCD_CONTROL_PO_BIT)
+ #define LCD_CONTROL_PO_00 (0 << LCD_CONTROL_PO_BIT)
+ #define LCD_CONTROL_PO_01 (1 << LCD_CONTROL_PO_BIT)
+ #define LCD_CONTROL_PO_10 (2 << LCD_CONTROL_PO_BIT)
+ #define LCD_CONTROL_PO_11 (3 << LCD_CONTROL_PO_BIT)
+ #define LCD_CONTROL_MPI (1<<7)
+ #define LCD_CONTROL_PT (1<<6)
+ #define LCD_CONTROL_PC (1<<5)
+ #define LCD_CONTROL_BPP_BIT 1
+ #define LCD_CONTROL_BPP_MASK (0x7 << LCD_CONTROL_BPP_BIT)
+ #define LCD_CONTROL_BPP_1 (0 << LCD_CONTROL_BPP_BIT)
+ #define LCD_CONTROL_BPP_2 (1 << LCD_CONTROL_BPP_BIT)
+ #define LCD_CONTROL_BPP_4 (2 << LCD_CONTROL_BPP_BIT)
+ #define LCD_CONTROL_BPP_8 (3 << LCD_CONTROL_BPP_BIT)
+ #define LCD_CONTROL_BPP_12 (4 << LCD_CONTROL_BPP_BIT)
+ #define LCD_CONTROL_BPP_16 (5 << LCD_CONTROL_BPP_BIT)
+ #define LCD_CONTROL_GO (1<<0)
+
+#define LCD_INTSTATUS (AU1100_LCD_BASE + 0x4)
+#define LCD_INTENABLE (AU1100_LCD_BASE + 0x8)
+ #define LCD_INT_SD (1<<7)
+ #define LCD_INT_OF (1<<6)
+ #define LCD_INT_UF (1<<5)
+ #define LCD_INT_SA (1<<3)
+ #define LCD_INT_SS (1<<2)
+ #define LCD_INT_S1 (1<<1)
+ #define LCD_INT_S0 (1<<0)
+
+#define LCD_HORZTIMING (AU1100_LCD_BASE + 0xC)
+ #define LCD_HORZTIMING_HN2_BIT 24
+ #define LCD_HORZTIMING_HN2_MASK (0xFF << LCD_HORZTIMING_HN2_BIT)
+ #define LCD_HORZTIMING_HN2_N(N) ((((N)-1) << LCD_HORZTIMING_HN2_BIT) & LCD_HORZTIMING_HN2_MASK)
+ #define LCD_HORZTIMING_HN1_BIT 16
+ #define LCD_HORZTIMING_HN1_MASK (0xFF << LCD_HORZTIMING_HN1_BIT)
+ #define LCD_HORZTIMING_HN1_N(N) ((((N)-1) << LCD_HORZTIMING_HN1_BIT) & LCD_HORZTIMING_HN1_MASK)
+ #define LCD_HORZTIMING_HPW_BIT 10
+ #define LCD_HORZTIMING_HPW_MASK (0x3F << LCD_HORZTIMING_HPW_BIT)
+ #define LCD_HORZTIMING_HPW_N(N) ((((N)-1) << LCD_HORZTIMING_HPW_BIT) & LCD_HORZTIMING_HPW_MASK)
+ #define LCD_HORZTIMING_PPL_BIT 0
+ #define LCD_HORZTIMING_PPL_MASK (0x3FF << LCD_HORZTIMING_PPL_BIT)
+ #define LCD_HORZTIMING_PPL_N(N) ((((N)-1) << LCD_HORZTIMING_PPL_BIT) & LCD_HORZTIMING_PPL_MASK)
+
+#define LCD_VERTTIMING (AU1100_LCD_BASE + 0x10)
+ #define LCD_VERTTIMING_VN2_BIT 24
+ #define LCD_VERTTIMING_VN2_MASK (0xFF << LCD_VERTTIMING_VN2_BIT)
+ #define LCD_VERTTIMING_VN2_N(N) ((((N)-1) << LCD_VERTTIMING_VN2_BIT) & LCD_VERTTIMING_VN2_MASK)
+ #define LCD_VERTTIMING_VN1_BIT 16
+ #define LCD_VERTTIMING_VN1_MASK (0xFF << LCD_VERTTIMING_VN1_BIT)
+ #define LCD_VERTTIMING_VN1_N(N) ((((N)-1) << LCD_VERTTIMING_VN1_BIT) & LCD_VERTTIMING_VN1_MASK)
+ #define LCD_VERTTIMING_VPW_BIT 10
+ #define LCD_VERTTIMING_VPW_MASK (0x3F << LCD_VERTTIMING_VPW_BIT)
+ #define LCD_VERTTIMING_VPW_N(N) ((((N)-1) << LCD_VERTTIMING_VPW_BIT) & LCD_VERTTIMING_VPW_MASK)
+ #define LCD_VERTTIMING_LPP_BIT 0
+ #define LCD_VERTTIMING_LPP_MASK (0x3FF << LCD_VERTTIMING_LPP_BIT)
+ #define LCD_VERTTIMING_LPP_N(N) ((((N)-1) << LCD_VERTTIMING_LPP_BIT) & LCD_VERTTIMING_LPP_MASK)
+
+#define LCD_CLKCONTROL (AU1100_LCD_BASE + 0x14)
+ #define LCD_CLKCONTROL_IB (1<<18)
+ #define LCD_CLKCONTROL_IC (1<<17)
+ #define LCD_CLKCONTROL_IH (1<<16)
+ #define LCD_CLKCONTROL_IV (1<<15)
+ #define LCD_CLKCONTROL_BF_BIT 10
+ #define LCD_CLKCONTROL_BF_MASK (0x1F << LCD_CLKCONTROL_BF_BIT)
+ #define LCD_CLKCONTROL_BF_N(N) ((((N)-1) << LCD_CLKCONTROL_BF_BIT) & LCD_CLKCONTROL_BF_MASK)
+ #define LCD_CLKCONTROL_PCD_BIT 0
+ #define LCD_CLKCONTROL_PCD_MASK (0x3FF << LCD_CLKCONTROL_PCD_BIT)
+ #define LCD_CLKCONTROL_PCD_N(N) (((N) << LCD_CLKCONTROL_PCD_BIT) & LCD_CLKCONTROL_PCD_MASK)
+
+#define LCD_DMAADDR0 (AU1100_LCD_BASE + 0x18)
+#define LCD_DMAADDR1 (AU1100_LCD_BASE + 0x1C)
+ #define LCD_DMA_SA_BIT 5
+ #define LCD_DMA_SA_MASK (0x7FFFFFF << LCD_DMA_SA_BIT)
+ #define LCD_DMA_SA_N(N) ((N) & LCD_DMA_SA_MASK)
+
+#define LCD_WORDS (AU1100_LCD_BASE + 0x20)
+ #define LCD_WRD_WRDS_BIT 0
+ #define LCD_WRD_WRDS_MASK (0xFFFFFFFF << LCD_WRD_WRDS_BIT)
+ #define LCD_WRD_WRDS_N(N) ((((N)-1) << LCD_WRD_WRDS_BIT) & LCD_WRD_WRDS_MASK)
+
+#define LCD_PWMDIV (AU1100_LCD_BASE + 0x24)
+ #define LCD_PWMDIV_EN (1<<12)
+ #define LCD_PWMDIV_PWMDIV_BIT 0
+ #define LCD_PWMDIV_PWMDIV_MASK (0xFFF << LCD_PWMDIV_PWMDIV_BIT)
+ #define LCD_PWMDIV_PWMDIV_N(N) ((((N)-1) << LCD_PWMDIV_PWMDIV_BIT) & LCD_PWMDIV_PWMDIV_MASK)
+
+#define LCD_PWMHI (AU1100_LCD_BASE + 0x28)
+ #define LCD_PWMHI_PWMHI1_BIT 12
+ #define LCD_PWMHI_PWMHI1_MASK (0xFFF << LCD_PWMHI_PWMHI1_BIT)
+ #define LCD_PWMHI_PWMHI1_N(N) (((N) << LCD_PWMHI_PWMHI1_BIT) & LCD_PWMHI_PWMHI1_MASK)
+ #define LCD_PWMHI_PWMHI0_BIT 0
+ #define LCD_PWMHI_PWMHI0_MASK (0xFFF << LCD_PWMHI_PWMHI0_BIT)
+ #define LCD_PWMHI_PWMHI0_N(N) (((N) << LCD_PWMHI_PWMHI0_BIT) & LCD_PWMHI_PWMHI0_MASK)
+
+#define LCD_PALLETTEBASE (AU1100_LCD_BASE + 0x400)
+ #define LCD_PALLETTE_MONO_MI_BIT 0
+ #define LCD_PALLETTE_MONO_MI_MASK (0xF << LCD_PALLETTE_MONO_MI_BIT)
+ #define LCD_PALLETTE_MONO_MI_N(N) (((N)<< LCD_PALLETTE_MONO_MI_BIT) & LCD_PALLETTE_MONO_MI_MASK)
+
+ #define LCD_PALLETTE_COLOR_RI_BIT 8
+ #define LCD_PALLETTE_COLOR_RI_MASK (0xF << LCD_PALLETTE_COLOR_RI_BIT)
+ #define LCD_PALLETTE_COLOR_RI_N(N) (((N)<< LCD_PALLETTE_COLOR_RI_BIT) & LCD_PALLETTE_COLOR_RI_MASK)
+ #define LCD_PALLETTE_COLOR_GI_BIT 4
+ #define LCD_PALLETTE_COLOR_GI_MASK (0xF << LCD_PALLETTE_COLOR_GI_BIT)
+ #define LCD_PALLETTE_COLOR_GI_N(N) (((N)<< LCD_PALLETTE_COLOR_GI_BIT) & LCD_PALLETTE_COLOR_GI_MASK)
+ #define LCD_PALLETTE_COLOR_BI_BIT 0
+ #define LCD_PALLETTE_COLOR_BI_MASK (0xF << LCD_PALLETTE_COLOR_BI_BIT)
+ #define LCD_PALLETTE_COLOR_BI_N(N) (((N)<< LCD_PALLETTE_COLOR_BI_BIT) & LCD_PALLETTE_COLOR_BI_MASK)
+
+ #define LCD_PALLETTE_TFT_DC_BIT 0
+ #define LCD_PALLETTE_TFT_DC_MASK (0xFFFF << LCD_PALLETTE_TFT_DC_BIT)
+ #define LCD_PALLETTE_TFT_DC_N(N) (((N)<< LCD_PALLETTE_TFT_DC_BIT) & LCD_PALLETTE_TFT_DC_MASK)
+
+/********************************************************************/
+
+/* List of panels known to work with the AU1100 LCD controller.
+ * To add a new panel, enter the same specifications as the
+ * Generic_TFT one, and MAKE SURE that it doesn't conflicts
+ * with the controller restrictions. Restrictions are:
+ *
+ * STN color panels: max_bpp <= 12
+ * STN mono panels: max_bpp <= 4
+ * TFT panels: max_bpp <= 16
+ * max_xres <= 800
+ * max_yres <= 600
*/
-struct known_lcd_panels panels[] =
+static struct au1100fb_panel known_lcd_panels[] =
{
- { /* 0: Pb1100 LCDA: Sharp 320x240 TFT panel */
- 320, /* xres */
- 240, /* yres */
- 16, /* bpp */
-
- "Sharp_320x240_16",
- /* mode_control */
+ /* 800x600x16bpp CRT */
+ [0] = {
+ .name = "CRT_800x600_16",
+ .xres = 800,
+ .yres = 600,
+ .bpp = 16,
+ .control_base = 0x0004886A |
+ LCD_CONTROL_DEFAULT_PO | LCD_CONTROL_DEFAULT_SBPPF |
+ LCD_CONTROL_BPP_16,
+ .clkcontrol_base = 0x00020000,
+ .horztiming = 0x005aff1f,
+ .verttiming = 0x16000e57,
+ },
+ /* just the standard LCD */
+ [1] = {
+ .name = "WWPC LCD",
+ .xres = 240,
+ .yres = 320,
+ .bpp = 16,
+ .control_base = 0x0006806A,
+ .horztiming = 0x0A1010EF,
+ .verttiming = 0x0301013F,
+ .clkcontrol_base = 0x00018001,
+ },
+ /* Sharp 320x240 TFT panel */
+ [2] = {
+ .name = "Sharp_LQ038Q5DR01",
+ .xres = 320,
+ .yres = 240,
+ .bpp = 16,
+ .control_base =
( LCD_CONTROL_SBPPF_565
- /*LCD_CONTROL_WP*/
- /*LCD_CONTROL_WD*/
| LCD_CONTROL_C
| LCD_CONTROL_SM_0
- /*LCD_CONTROL_DB*/
- /*LCD_CONTROL_CCO*/
- /*LCD_CONTROL_DP*/
- | LCD_DEFAULT_PIX_FORMAT
- /*LCD_CONTROL_MPI*/
+ | LCD_CONTROL_DEFAULT_PO
| LCD_CONTROL_PT
| LCD_CONTROL_PC
| LCD_CONTROL_BPP_16 ),
-
- /* mode_horztiming */
+ .horztiming =
( LCD_HORZTIMING_HN2_N(8)
| LCD_HORZTIMING_HN1_N(60)
| LCD_HORZTIMING_HPW_N(12)
| LCD_HORZTIMING_PPL_N(320) ),
-
- /* mode_verttiming */
+ .verttiming =
( LCD_VERTTIMING_VN2_N(5)
| LCD_VERTTIMING_VN1_N(17)
| LCD_VERTTIMING_VPW_N(1)
| LCD_VERTTIMING_LPP_N(240) ),
-
- /* mode_clkcontrol */
- ( 0
- /*LCD_CLKCONTROL_IB*/
- /*LCD_CLKCONTROL_IC*/
- /*LCD_CLKCONTROL_IH*/
- /*LCD_CLKCONTROL_IV*/
- | LCD_CLKCONTROL_PCD_N(1) ),
-
- /* mode_pwmdiv */
- 0,
-
- /* mode_pwmhi */
- 0,
-
- /* mode_toyclksrc */
- ((1<<7) | (1<<6) | (1<<5)),
-
- /* mode_backlight */
- 6
+ .clkcontrol_base = LCD_CLKCONTROL_PCD_N(1),
},
- { /* 1: Pb1100 LCDC 640x480 TFT panel */
- 640, /* xres */
- 480, /* yres */
- 16, /* bpp */
-
- "Generic_640x480_16",
-
- /* mode_control */
- 0x004806a | LCD_DEFAULT_PIX_FORMAT,
-
- /* mode_horztiming */
- 0x3434d67f,
-
- /* mode_verttiming */
- 0x0e0e39df,
-
- /* mode_clkcontrol */
- ( 0
- /*LCD_CLKCONTROL_IB*/
- /*LCD_CLKCONTROL_IC*/
- /*LCD_CLKCONTROL_IH*/
- /*LCD_CLKCONTROL_IV*/
- | LCD_CLKCONTROL_PCD_N(1) ),
-
- /* mode_pwmdiv */
- 0,
-
- /* mode_pwmhi */
- 0,
-
- /* mode_toyclksrc */
- ((1<<7) | (1<<6) | (0<<5)),
-
- /* mode_backlight */
- 7
+ /* Hitachi SP14Q005 and possibly others */
+ [3] = {
+ .name = "Hitachi_SP14Qxxx",
+ .xres = 320,
+ .yres = 240,
+ .bpp = 4,
+ .control_base =
+ ( LCD_CONTROL_C
+ | LCD_CONTROL_BPP_4 ),
+ .horztiming =
+ ( LCD_HORZTIMING_HN2_N(1)
+ | LCD_HORZTIMING_HN1_N(1)
+ | LCD_HORZTIMING_HPW_N(1)
+ | LCD_HORZTIMING_PPL_N(320) ),
+ .verttiming =
+ ( LCD_VERTTIMING_VN2_N(1)
+ | LCD_VERTTIMING_VN1_N(1)
+ | LCD_VERTTIMING_VPW_N(1)
+ | LCD_VERTTIMING_LPP_N(240) ),
+ .clkcontrol_base = LCD_CLKCONTROL_PCD_N(4),
},
- { /* 2: Pb1100 LCDB 640x480 PrimeView TFT panel */
- 640, /* xres */
- 480, /* yres */
- 16, /* bpp */
-
- "PrimeView_640x480_16",
-
- /* mode_control */
- 0x0004886a | LCD_DEFAULT_PIX_FORMAT,
-
- /* mode_horztiming */
- 0x0e4bfe7f,
-
- /* mode_verttiming */
- 0x210805df,
-
- /* mode_clkcontrol */
- 0x00038001,
-
- /* mode_pwmdiv */
- 0,
-
- /* mode_pwmhi */
- 0,
-
- /* mode_toyclksrc */
- ((1<<7) | (1<<6) | (0<<5)),
-
- /* mode_backlight */
- 7
+ /* Generic 640x480 TFT panel */
+ [4] = {
+ .name = "TFT_640x480_16",
+ .xres = 640,
+ .yres = 480,
+ .bpp = 16,
+ .control_base = 0x004806a | LCD_CONTROL_DEFAULT_PO,
+ .horztiming = 0x3434d67f,
+ .verttiming = 0x0e0e39df,
+ .clkcontrol_base = LCD_CLKCONTROL_PCD_N(1),
},
- { /* 3: Pb1100 800x600x16bpp NEON CRT */
- 800, /* xres */
- 600, /* yres */
- 16, /* bpp */
-
- "NEON_800x600_16",
-
- /* mode_control */
- 0x0004886A | LCD_DEFAULT_PIX_FORMAT,
-
- /* mode_horztiming */
- 0x005AFF1F,
-
- /* mode_verttiming */
- 0x16000E57,
-
- /* mode_clkcontrol */
- 0x00020000,
-
- /* mode_pwmdiv */
- 0,
-
- /* mode_pwmhi */
- 0,
-
- /* mode_toyclksrc */
- ((1<<7) | (1<<6) | (0<<5)),
-
- /* mode_backlight */
- 7
+ /* Pb1100 LCDB 640x480 PrimeView TFT panel */
+ [5] = {
+ .name = "PrimeView_640x480_16",
+ .xres = 640,
+ .yres = 480,
+ .bpp = 16,
+ .control_base = 0x0004886a | LCD_CONTROL_DEFAULT_PO,
+ .horztiming = 0x0e4bfe7f,
+ .verttiming = 0x210805df,
+ .clkcontrol_base = 0x00038001,
},
+};
- { /* 4: Pb1100 640x480x16bpp NEON CRT */
- 640, /* xres */
- 480, /* yres */
- 16, /* bpp */
-
- "NEON_640x480_16",
-
- /* mode_control */
- 0x0004886A | LCD_DEFAULT_PIX_FORMAT,
-
- /* mode_horztiming */
- 0x0052E27F,
-
- /* mode_verttiming */
- 0x18000DDF,
-
- /* mode_clkcontrol */
- 0x00020000,
+struct au1100fb_drv_info {
+ int panel_idx;
+ char *opt_mode;
+};
- /* mode_pwmdiv */
- 0,
+/********************************************************************/
- /* mode_pwmhi */
- 0,
+/* Inline helpers */
- /* mode_toyclksrc */
- ((1<<7) | (1<<6) | (0<<5)),
+#define panel_is_dual(panel) (panel->control_base & LCD_CONTROL_DP)
+#define panel_is_active(panel)(panel->control_base & LCD_CONTROL_PT)
+#define panel_is_color(panel) (panel->control_base & LCD_CONTROL_PC)
+#define panel_swap_rgb(panel) (panel->control_base & LCD_CONTROL_CCO)
- /* mode_backlight */
- 7
- },
-};
#endif /* _AU1100LCD_H */
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index 7e731691e2a9..6a9ae2b3d1ab 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -28,7 +28,7 @@ config VGA_CONSOLE
config VIDEO_SELECT
bool "Video mode selection support"
- depends on (X86 || X86_64) && VGA_CONSOLE
+ depends on X86 && VGA_CONSOLE
---help---
This enables support for text mode selection on kernel startup. If
you want to take advantage of some high-resolution text mode your
diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c
index e793ffd39db5..762c7a593141 100644
--- a/drivers/video/console/newport_con.c
+++ b/drivers/video/console/newport_con.c
@@ -32,7 +32,6 @@
#include <linux/font.h>
-extern struct font_desc font_vga_8x16;
extern unsigned long sgi_gfxaddr;
#define FONT_DATA ((unsigned char *)font_vga_8x16.data)
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 809fee2140ac..56cd199605f4 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -579,6 +579,7 @@ static void vga_set_palette(struct vc_data *vc, unsigned char *table)
{
int i, j;
+ vga_w(state.vgabase, VGA_PEL_MSK, 0xff);
for (i = j = 0; i < 16; i++) {
vga_w(state.vgabase, VGA_PEL_IW, table[i]);
vga_w(state.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2);
@@ -721,6 +722,7 @@ static void vga_pal_blank(struct vgastate *state)
{
int i;
+ vga_w(state->vgabase, VGA_PEL_MSK, 0xff);
for (i = 0; i < 16; i++) {
vga_w(state->vgabase, VGA_PEL_IW, i);
vga_w(state->vgabase, VGA_PEL_D, 0);
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 9073be4221a8..e2667ddab3f1 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -918,7 +918,7 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
}
#endif
#elif defined(__powerpc__)
- vma->vm_page_prot = phys_mem_access_prot(file, off,
+ vma->vm_page_prot = phys_mem_access_prot(file, off >> PAGE_SHIFT,
vma->vm_end - vma->vm_start,
vma->vm_page_prot);
#elif defined(__alpha__)
diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c
index fc0a1beef968..316bfe994811 100644
--- a/drivers/video/gbefb.c
+++ b/drivers/video/gbefb.c
@@ -1126,7 +1126,7 @@ static int __init gbefb_probe(struct device *dev)
gbefb_setup(options);
#endif
- if (!request_mem_region(GBE_BASE, sizeof(struct sgi_gbe), "GBE")) {
+ if (!request_region(GBE_BASE, sizeof(struct sgi_gbe), "GBE")) {
printk(KERN_ERR "gbefb: couldn't reserve mmio region\n");
ret = -EBUSY;
goto out_release_framebuffer;
@@ -1152,12 +1152,24 @@ static int __init gbefb_probe(struct device *dev)
if (gbe_mem_phys) {
/* memory was allocated at boot time */
gbe_mem = ioremap_nocache(gbe_mem_phys, gbe_mem_size);
+ if (!gbe_mem) {
+ printk(KERN_ERR "gbefb: couldn't map framebuffer\n");
+ ret = -ENOMEM;
+ goto out_tiles_free;
+ }
+
gbe_dma_addr = 0;
} else {
/* try to allocate memory with the classical allocator
* this has high chance to fail on low memory machines */
gbe_mem = dma_alloc_coherent(NULL, gbe_mem_size, &gbe_dma_addr,
GFP_KERNEL);
+ if (!gbe_mem) {
+ printk(KERN_ERR "gbefb: couldn't allocate framebuffer memory\n");
+ ret = -ENOMEM;
+ goto out_tiles_free;
+ }
+
gbe_mem_phys = (unsigned long) gbe_dma_addr;
}
@@ -1165,12 +1177,6 @@ static int __init gbefb_probe(struct device *dev)
mtrr_add(gbe_mem_phys, gbe_mem_size, MTRR_TYPE_WRCOMB, 1);
#endif
- if (!gbe_mem) {
- printk(KERN_ERR "gbefb: couldn't map framebuffer\n");
- ret = -ENXIO;
- goto out_tiles_free;
- }
-
/* map framebuffer memory into tiles table */
for (i = 0; i < (gbe_mem_size >> TILE_SHIFT); i++)
gbe_tiles.cpu[i] = (gbe_mem_phys >> TILE_SHIFT) + i;
diff --git a/drivers/w1/w1_family.c b/drivers/w1/w1_family.c
index 88c517a4c178..9e293e139a0e 100644
--- a/drivers/w1/w1_family.c
+++ b/drivers/w1/w1_family.c
@@ -21,6 +21,7 @@
#include <linux/spinlock.h>
#include <linux/list.h>
+#include <linux/sched.h> /* schedule_timeout() */
#include <linux/delay.h>
#include "w1_family.h"
diff --git a/drivers/zorro/zorro-sysfs.c b/drivers/zorro/zorro-sysfs.c
index 04ca8840acf1..87c29d7b6c17 100644
--- a/drivers/zorro/zorro-sysfs.c
+++ b/drivers/zorro/zorro-sysfs.c
@@ -14,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/zorro.h>
#include <linux/stat.h>
+#include <linux/string.h>
#include "zorro.h"
diff --git a/drivers/zorro/zorro.c b/drivers/zorro/zorro.c
index d3c05dfe20d2..0f2b40605b06 100644
--- a/drivers/zorro/zorro.c
+++ b/drivers/zorro/zorro.c
@@ -16,6 +16,8 @@
#include <linux/init.h>
#include <linux/zorro.h>
#include <linux/bitops.h>
+#include <linux/string.h>
+
#include <asm/setup.h>
#include <asm/amigahw.h>
diff --git a/fs/Kconfig b/fs/Kconfig
index 48f5422cb19a..01a295232f75 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -810,7 +810,7 @@ config TMPFS
config HUGETLBFS
bool "HugeTLB file system support"
- depends X86 || IA64 || PPC64 || SPARC64 || SUPERH || X86_64 || BROKEN
+ depends X86 || IA64 || PPC64 || SPARC64 || SUPERH || BROKEN
config HUGETLB_PAGE
def_bool HUGETLBFS
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
index 434c19d076ac..175b2e8177c1 100644
--- a/fs/Kconfig.binfmt
+++ b/fs/Kconfig.binfmt
@@ -57,7 +57,7 @@ config BINFMT_SHARED_FLAT
config BINFMT_AOUT
tristate "Kernel support for a.out and ECOFF binaries"
- depends on (X86 && !X86_64) || ALPHA || ARM || M68K || SPARC32
+ depends on X86_32 || ALPHA || ARM || M68K || SPARC32
---help---
A.out (Assembler.OUTput) is a set of formats for libraries and
executables used in the earliest versions of UNIX. Linux used
diff --git a/fs/afs/file.c b/fs/afs/file.c
index 0d576987ec67..4975c9c193dd 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -291,8 +291,8 @@ static int afs_file_releasepage(struct page *page, gfp_t gfp_flags)
cachefs_uncache_page(vnode->cache, page);
#endif
- pageio = (struct cachefs_page *) page->private;
- page->private = 0;
+ pageio = (struct cachefs_page *) page_private(page);
+ set_page_private(page, 0);
ClearPagePrivate(page);
if (pageio)
diff --git a/fs/attr.c b/fs/attr.c
index b1796fb9e524..67bcd9b14ea5 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -117,9 +117,6 @@ int notify_change(struct dentry * dentry, struct iattr * attr)
struct timespec now;
unsigned int ia_valid = attr->ia_valid;
- if (!inode)
- BUG();
-
mode = inode->i_mode;
now = current_fs_time(inode->i_sb);
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c
index dd9baabaf016..72011826f0cb 100644
--- a/fs/binfmt_aout.c
+++ b/fs/binfmt_aout.c
@@ -318,7 +318,6 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
current->mm->free_area_cache = current->mm->mmap_base;
current->mm->cached_hole_size = 0;
- set_mm_counter(current->mm, rss, 0);
current->mm->mmap = NULL;
compute_creds(bprm);
current->flags &= ~PF_FORKNOEXEC;
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index d4b15576e584..6fa6adc40972 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -773,7 +773,6 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
/* Do this so that we can load the interpreter, if need be. We will
change some of these later */
- set_mm_counter(current->mm, rss, 0);
current->mm->free_area_cache = current->mm->mmap_base;
current->mm->cached_hole_size = 0;
retval = setup_arg_pages(bprm, randomize_stack_top(STACK_TOP),
@@ -1503,9 +1502,7 @@ static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file)
fill_psinfo(psinfo, current->group_leader, current->mm);
fill_note(notes +1, "CORE", NT_PRPSINFO, sizeof(*psinfo), psinfo);
- fill_note(notes +2, "CORE", NT_TASKSTRUCT, sizeof(*current), current);
-
- numnote = 3;
+ numnote = 2;
auxv = (elf_addr_t *) current->mm->saved_auxv;
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 134c9c0d1f54..dda87c4c82a3 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -294,14 +294,7 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, struct pt_regs *regs
&interp_params,
&current->mm->start_stack,
&current->mm->start_brk);
-#endif
-
- /* do this so that we can load the interpreter, if need be
- * - we will change some of these later
- */
- set_mm_counter(current->mm, rss, 0);
-#ifdef CONFIG_MMU
retval = setup_arg_pages(bprm, current->mm->start_stack, executable_stack);
if (retval < 0) {
send_sig(SIGKILL, current, 0);
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index 7974efa107bc..9d6625829b99 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -650,7 +650,6 @@ static int load_flat_file(struct linux_binprm * bprm,
current->mm->start_brk = datapos + data_len + bss_len;
current->mm->brk = (current->mm->start_brk + 3) & ~3;
current->mm->context.end_brk = memp + ksize((void *) memp) - stack_len;
- set_mm_counter(current->mm, rss, 0);
}
if (flags & FLAT_FLAG_KTRACE)
diff --git a/fs/binfmt_som.c b/fs/binfmt_som.c
index 227a2682d2bf..00a91dc25d16 100644
--- a/fs/binfmt_som.c
+++ b/fs/binfmt_som.c
@@ -259,7 +259,6 @@ load_som_binary(struct linux_binprm * bprm, struct pt_regs * regs)
create_som_tables(bprm);
current->mm->start_stack = bprm->p;
- set_mm_counter(current->mm, rss, 0);
#if 0
printk("(start_brk) %08lx\n" , (unsigned long) current->mm->start_brk);
diff --git a/fs/buffer.c b/fs/buffer.c
index b1667986442f..35fa34977e81 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -96,7 +96,7 @@ static void
__clear_page_buffers(struct page *page)
{
ClearPagePrivate(page);
- page->private = 0;
+ set_page_private(page, 0);
page_cache_release(page);
}
@@ -1478,8 +1478,10 @@ EXPORT_SYMBOL(__getblk);
void __breadahead(struct block_device *bdev, sector_t block, int size)
{
struct buffer_head *bh = __getblk(bdev, block, size);
- ll_rw_block(READA, 1, &bh);
- brelse(bh);
+ if (likely(bh)) {
+ ll_rw_block(READA, 1, &bh);
+ brelse(bh);
+ }
}
EXPORT_SYMBOL(__breadahead);
@@ -1497,7 +1499,7 @@ __bread(struct block_device *bdev, sector_t block, int size)
{
struct buffer_head *bh = __getblk(bdev, block, size);
- if (!buffer_uptodate(bh))
+ if (likely(bh) && !buffer_uptodate(bh))
bh = __bread_slow(bh);
return bh;
}
@@ -1637,6 +1639,15 @@ out:
}
EXPORT_SYMBOL(block_invalidatepage);
+int do_invalidatepage(struct page *page, unsigned long offset)
+{
+ int (*invalidatepage)(struct page *, unsigned long);
+ invalidatepage = page->mapping->a_ops->invalidatepage;
+ if (invalidatepage == NULL)
+ invalidatepage = block_invalidatepage;
+ return (*invalidatepage)(page, offset);
+}
+
/*
* We attach and possibly dirty the buffers atomically wrt
* __set_page_dirty_buffers() via private_lock. try_to_free_buffers
@@ -2696,7 +2707,7 @@ int block_write_full_page(struct page *page, get_block_t *get_block,
* they may have been added in ext3_writepage(). Make them
* freeable here, so the page does not leak.
*/
- block_invalidatepage(page, 0);
+ do_invalidatepage(page, 0);
unlock_page(page);
return 0; /* don't care */
}
diff --git a/fs/compat.c b/fs/compat.c
index a719e158e002..8e71cdbecc7c 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -1490,7 +1490,6 @@ int compat_do_execve(char * filename,
/* execve success */
security_bprm_free(bprm);
acct_update_integrals(current);
- update_mem_hiwater(current);
kfree(bprm);
return retval;
}
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index a327e03753ac..43dbcb0b21eb 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -3046,6 +3046,10 @@ HANDLE_IOCTL(RAW_GETBIND, raw_ioctl)
/* Serial */
HANDLE_IOCTL(TIOCGSERIAL, serial_struct_ioctl)
HANDLE_IOCTL(TIOCSSERIAL, serial_struct_ioctl)
+#ifdef TIOCGLTC
+COMPATIBLE_IOCTL(TIOCGLTC)
+COMPATIBLE_IOCTL(TIOCSLTC)
+#endif
/* Usbdevfs */
HANDLE_IOCTL(USBDEVFS_CONTROL32, do_usbdevfs_control)
HANDLE_IOCTL(USBDEVFS_BULK32, do_usbdevfs_bulk)
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 0d06097bc995..3931e7f1e6bf 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -162,6 +162,7 @@ static int dio_refill_pages(struct dio *dio)
up_read(&current->mm->mmap_sem);
if (ret < 0 && dio->blocks_available && (dio->rw == WRITE)) {
+ struct page *page = ZERO_PAGE(dio->curr_user_address);
/*
* A memory fault, but the filesystem has some outstanding
* mapped blocks. We need to use those blocks up to avoid
@@ -169,7 +170,8 @@ static int dio_refill_pages(struct dio *dio)
*/
if (dio->page_errors == 0)
dio->page_errors = ret;
- dio->pages[0] = ZERO_PAGE(dio->curr_user_address);
+ page_cache_get(page);
+ dio->pages[0] = page;
dio->head = 0;
dio->tail = 1;
ret = 0;
diff --git a/fs/dquot.c b/fs/dquot.c
index 05f3327d64a3..ea7644227a65 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -662,7 +662,7 @@ static void add_dquot_ref(struct super_block *sb, int type)
restart:
file_list_lock();
list_for_each(p, &sb->s_files) {
- struct file *filp = list_entry(p, struct file, f_list);
+ struct file *filp = list_entry(p, struct file, f_u.fu_list);
struct inode *inode = filp->f_dentry->d_inode;
if (filp->f_mode & FMODE_WRITE && dqinit_needed(inode, type)) {
struct dentry *dentry = dget(filp->f_dentry);
diff --git a/fs/exec.c b/fs/exec.c
index d2208f7c87db..10d493fea7ce 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -309,40 +309,36 @@ void install_arg_page(struct vm_area_struct *vma,
pud_t * pud;
pmd_t * pmd;
pte_t * pte;
+ spinlock_t *ptl;
if (unlikely(anon_vma_prepare(vma)))
- goto out_sig;
+ goto out;
flush_dcache_page(page);
pgd = pgd_offset(mm, address);
-
- spin_lock(&mm->page_table_lock);
pud = pud_alloc(mm, pgd, address);
if (!pud)
goto out;
pmd = pmd_alloc(mm, pud, address);
if (!pmd)
goto out;
- pte = pte_alloc_map(mm, pmd, address);
+ pte = pte_alloc_map_lock(mm, pmd, address, &ptl);
if (!pte)
goto out;
if (!pte_none(*pte)) {
- pte_unmap(pte);
+ pte_unmap_unlock(pte, ptl);
goto out;
}
- inc_mm_counter(mm, rss);
+ inc_mm_counter(mm, anon_rss);
lru_cache_add_active(page);
set_pte_at(mm, address, pte, pte_mkdirty(pte_mkwrite(mk_pte(
page, vma->vm_page_prot))));
page_add_anon_rmap(page, vma, address);
- pte_unmap(pte);
- spin_unlock(&mm->page_table_lock);
+ pte_unmap_unlock(pte, ptl);
/* no need for flush_tlb */
return;
out:
- spin_unlock(&mm->page_table_lock);
-out_sig:
__free_page(page);
force_sig(SIGKILL, current);
}
@@ -634,10 +630,9 @@ static inline int de_thread(struct task_struct *tsk)
/*
* Account for the thread group leader hanging around:
*/
- count = 2;
- if (thread_group_leader(current))
- count = 1;
- else {
+ count = 1;
+ if (!thread_group_leader(current)) {
+ count = 2;
/*
* The SIGALRM timer survives the exec, but needs to point
* at us as the new group leader now. We have a race with
@@ -646,8 +641,10 @@ static inline int de_thread(struct task_struct *tsk)
* before we can safely let the old group leader die.
*/
sig->real_timer.data = (unsigned long)current;
+ spin_unlock_irq(lock);
if (del_timer_sync(&sig->real_timer))
add_timer(&sig->real_timer);
+ spin_lock_irq(lock);
}
while (atomic_read(&sig->count) > count) {
sig->group_exit_task = current;
@@ -659,7 +656,6 @@ static inline int de_thread(struct task_struct *tsk)
}
sig->group_exit_task = NULL;
sig->notify_count = 0;
- sig->real_timer.data = (unsigned long)current;
spin_unlock_irq(lock);
/*
@@ -1207,7 +1203,6 @@ int do_execve(char * filename,
/* execve success */
security_bprm_free(bprm);
acct_update_integrals(current);
- update_mem_hiwater(current);
kfree(bprm);
return retval;
}
@@ -1422,19 +1417,16 @@ static void zap_threads (struct mm_struct *mm)
static void coredump_wait(struct mm_struct *mm)
{
DECLARE_COMPLETION(startup_done);
+ int core_waiters;
- mm->core_waiters++; /* let other threads block */
mm->core_startup_done = &startup_done;
- /* give other threads a chance to run: */
- yield();
-
zap_threads(mm);
- if (--mm->core_waiters) {
- up_write(&mm->mmap_sem);
+ core_waiters = mm->core_waiters;
+ up_write(&mm->mmap_sem);
+
+ if (core_waiters)
wait_for_completion(&startup_done);
- } else
- up_write(&mm->mmap_sem);
BUG_ON(mm->core_waiters);
}
@@ -1468,11 +1460,21 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
current->fsuid = 0; /* Dump root private */
}
mm->dumpable = 0;
- init_completion(&mm->core_done);
+
+ retval = -EAGAIN;
spin_lock_irq(&current->sighand->siglock);
- current->signal->flags = SIGNAL_GROUP_EXIT;
- current->signal->group_exit_code = exit_code;
+ if (!(current->signal->flags & SIGNAL_GROUP_EXIT)) {
+ current->signal->flags = SIGNAL_GROUP_EXIT;
+ current->signal->group_exit_code = exit_code;
+ retval = 0;
+ }
spin_unlock_irq(&current->sighand->siglock);
+ if (retval) {
+ up_write(&mm->mmap_sem);
+ goto fail;
+ }
+
+ init_completion(&mm->core_done);
coredump_wait(mm);
/*
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index fdba4d1d3c60..e7d3f0522d01 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -440,6 +440,10 @@ static int ext2_alloc_branch(struct inode *inode,
* the pointer to new one, then send parent to disk.
*/
bh = sb_getblk(inode->i_sb, parent);
+ if (!bh) {
+ err = -EIO;
+ break;
+ }
lock_buffer(bh);
memset(bh->b_data, 0, blocksize);
branch[n].bh = bh;
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c
index 0213db4911a2..7992d21e0e09 100644
--- a/fs/ext3/balloc.c
+++ b/fs/ext3/balloc.c
@@ -20,6 +20,8 @@
#include <linux/quotaops.h>
#include <linux/buffer_head.h>
+#include "bitmap.h"
+
/*
* balloc.c contains the blocks allocation and deallocation routines
*/
@@ -1010,7 +1012,7 @@ retry:
* allocation within the reservation window.
*
* This will avoid keeping on searching the reservation list again and
- * again when someboday is looking for a free block (without
+ * again when somebody is looking for a free block (without
* reservation), and there are lots of free blocks, but they are all
* being reserved.
*
@@ -1416,12 +1418,12 @@ unsigned long ext3_count_free_blocks(struct super_block *sb)
unsigned long bitmap_count, x;
struct buffer_head *bitmap_bh = NULL;
- lock_super(sb);
es = EXT3_SB(sb)->s_es;
desc_count = 0;
bitmap_count = 0;
gdp = NULL;
+ smp_rmb();
for (i = 0; i < ngroups; i++) {
gdp = ext3_get_group_desc(sb, i, NULL);
if (!gdp)
@@ -1440,7 +1442,6 @@ unsigned long ext3_count_free_blocks(struct super_block *sb)
brelse(bitmap_bh);
printk("ext3_count_free_blocks: stored = %u, computed = %lu, %lu\n",
le32_to_cpu(es->s_free_blocks_count), desc_count, bitmap_count);
- unlock_super(sb);
return bitmap_count;
#else
desc_count = 0;
diff --git a/fs/ext3/bitmap.c b/fs/ext3/bitmap.c
index 6c419b9ab0e8..5b4ba3e246e6 100644
--- a/fs/ext3/bitmap.c
+++ b/fs/ext3/bitmap.c
@@ -8,7 +8,7 @@
*/
#include <linux/buffer_head.h>
-
+#include "bitmap.h"
static int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0};
diff --git a/fs/ext3/bitmap.h b/fs/ext3/bitmap.h
new file mode 100644
index 000000000000..6ee503a6bb4e
--- /dev/null
+++ b/fs/ext3/bitmap.h
@@ -0,0 +1,8 @@
+/* linux/fs/ext3/bitmap.c
+ *
+ * Copyright (C) 2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+*/
+
+extern unsigned long ext3_count_free (struct buffer_head *, unsigned int );
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
index 6549945f9ac1..df3f517c54ac 100644
--- a/fs/ext3/ialloc.c
+++ b/fs/ext3/ialloc.c
@@ -26,6 +26,7 @@
#include <asm/byteorder.h>
+#include "bitmap.h"
#include "xattr.h"
#include "acl.h"
@@ -704,7 +705,6 @@ unsigned long ext3_count_free_inodes (struct super_block * sb)
unsigned long bitmap_count, x;
struct buffer_head *bitmap_bh = NULL;
- lock_super (sb);
es = EXT3_SB(sb)->s_es;
desc_count = 0;
bitmap_count = 0;
@@ -727,7 +727,6 @@ unsigned long ext3_count_free_inodes (struct super_block * sb)
brelse(bitmap_bh);
printk("ext3_count_free_inodes: stored = %u, computed = %lu, %lu\n",
le32_to_cpu(es->s_free_inodes_count), desc_count, bitmap_count);
- unlock_super(sb);
return desc_count;
#else
desc_count = 0;
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 8b38f2232796..5d9b00e28837 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -491,7 +491,7 @@ static unsigned long ext3_find_goal(struct inode *inode, long block,
* the same format as ext3_get_branch() would do. We are calling it after
* we had read the existing part of chain and partial points to the last
* triple of that (one with zero ->key). Upon the exit we have the same
- * picture as after the successful ext3_get_block(), excpet that in one
+ * picture as after the successful ext3_get_block(), except that in one
* place chain is disconnected - *branch->p is still zero (we did not
* set the last link), but branch->key contains the number that should
* be placed into *branch->p to fill that gap.
@@ -523,7 +523,6 @@ static int ext3_alloc_branch(handle_t *handle, struct inode *inode,
if (!nr)
break;
branch[n].key = cpu_to_le32(nr);
- keys = n+1;
/*
* Get buffer_head for parent block, zero it out
@@ -531,6 +530,9 @@ static int ext3_alloc_branch(handle_t *handle, struct inode *inode,
* parent to disk.
*/
bh = sb_getblk(inode->i_sb, parent);
+ if (!bh)
+ break;
+ keys = n+1;
branch[n].bh = bh;
lock_buffer(bh);
BUFFER_TRACE(bh, "call get_create_access");
@@ -864,6 +866,10 @@ struct buffer_head *ext3_getblk(handle_t *handle, struct inode * inode,
if (!*errp && buffer_mapped(&dummy)) {
struct buffer_head *bh;
bh = sb_getblk(inode->i_sb, dummy.b_blocknr);
+ if (!bh) {
+ *errp = -EIO;
+ goto err;
+ }
if (buffer_new(&dummy)) {
J_ASSERT(create != 0);
J_ASSERT(handle != 0);
@@ -896,6 +902,7 @@ struct buffer_head *ext3_getblk(handle_t *handle, struct inode * inode,
}
return bh;
}
+err:
return NULL;
}
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index 50378d8ff84b..b3c690a3b54a 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -36,6 +36,8 @@
#include <linux/quotaops.h>
#include <linux/buffer_head.h>
#include <linux/smp_lock.h>
+
+#include "namei.h"
#include "xattr.h"
#include "acl.h"
diff --git a/fs/ext3/namei.h b/fs/ext3/namei.h
new file mode 100644
index 000000000000..f2ce2b0065c9
--- /dev/null
+++ b/fs/ext3/namei.h
@@ -0,0 +1,8 @@
+/* linux/fs/ext3/namei.h
+ *
+ * Copyright (C) 2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+*/
+
+extern struct dentry *ext3_get_parent(struct dentry *child);
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c
index 57f79106267d..1be78b4b4de9 100644
--- a/fs/ext3/resize.c
+++ b/fs/ext3/resize.c
@@ -118,6 +118,8 @@ static struct buffer_head *bclean(handle_t *handle, struct super_block *sb,
int err;
bh = sb_getblk(sb, blk);
+ if (!bh)
+ return ERR_PTR(-EIO);
if ((err = ext3_journal_get_write_access(handle, bh))) {
brelse(bh);
bh = ERR_PTR(err);
@@ -202,6 +204,10 @@ static int setup_new_group_blocks(struct super_block *sb,
ext3_debug("update backup group %#04lx (+%d)\n", block, bit);
gdb = sb_getblk(sb, block);
+ if (!gdb) {
+ err = -EIO;
+ goto exit_bh;
+ }
if ((err = ext3_journal_get_write_access(handle, gdb))) {
brelse(gdb);
goto exit_bh;
@@ -643,6 +649,10 @@ static void update_backups(struct super_block *sb,
break;
bh = sb_getblk(sb, group * bpg + blk_off);
+ if (!bh) {
+ err = -EIO;
+ break;
+ }
ext3_debug("update metadata backup %#04lx\n",
(unsigned long)bh->b_blocknr);
if ((err = ext3_journal_get_write_access(handle, bh)))
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 097383c11154..f594989ccb7a 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -36,9 +36,12 @@
#include <linux/namei.h>
#include <linux/quotaops.h>
#include <linux/seq_file.h>
+
#include <asm/uaccess.h>
+
#include "xattr.h"
#include "acl.h"
+#include "namei.h"
static int ext3_load_journal(struct super_block *, struct ext3_super_block *);
static int ext3_create_journal(struct super_block *, struct ext3_super_block *,
@@ -615,7 +618,6 @@ static struct super_operations ext3_sops = {
#endif
};
-struct dentry *ext3_get_parent(struct dentry *child);
static struct export_operations ext3_export_ops = {
.get_parent = ext3_get_parent,
};
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c
index 269c7b92db9a..430de9f63be3 100644
--- a/fs/ext3/xattr.c
+++ b/fs/ext3/xattr.c
@@ -210,7 +210,7 @@ ext3_xattr_find_entry(struct ext3_xattr_entry **pentry, int name_index,
return cmp ? -ENODATA : 0;
}
-int
+static int
ext3_xattr_block_get(struct inode *inode, int name_index, const char *name,
void *buffer, size_t buffer_size)
{
@@ -354,7 +354,7 @@ ext3_xattr_list_entries(struct inode *inode, struct ext3_xattr_entry *entry,
return buffer_size - rest;
}
-int
+static int
ext3_xattr_block_list(struct inode *inode, char *buffer, size_t buffer_size)
{
struct buffer_head *bh = NULL;
@@ -626,7 +626,7 @@ struct ext3_xattr_block_find {
struct buffer_head *bh;
};
-int
+static int
ext3_xattr_block_find(struct inode *inode, struct ext3_xattr_info *i,
struct ext3_xattr_block_find *bs)
{
@@ -859,7 +859,7 @@ struct ext3_xattr_ibody_find {
struct ext3_iloc iloc;
};
-int
+static int
ext3_xattr_ibody_find(struct inode *inode, struct ext3_xattr_info *i,
struct ext3_xattr_ibody_find *is)
{
diff --git a/fs/fat/dir.c b/fs/fat/dir.c
index 895049b2ac9c..ba824964b9bb 100644
--- a/fs/fat/dir.c
+++ b/fs/fat/dir.c
@@ -222,6 +222,80 @@ fat_shortname2uni(struct nls_table *nls, unsigned char *buf, int buf_size,
return len;
}
+enum { PARSE_INVALID = 1, PARSE_NOT_LONGNAME, PARSE_EOF, };
+
+/**
+ * fat_parse_long - Parse extended directory entry.
+ *
+ * This function returns zero on success, negative value on error, or one of
+ * the following:
+ *
+ * %PARSE_INVALID - Directory entry is invalid.
+ * %PARSE_NOT_LONGNAME - Directory entry does not contain longname.
+ * %PARSE_EOF - Directory has no more entries.
+ */
+static int fat_parse_long(struct inode *dir, loff_t *pos,
+ struct buffer_head **bh, struct msdos_dir_entry **de,
+ wchar_t **unicode, unsigned char *nr_slots)
+{
+ struct msdos_dir_slot *ds;
+ unsigned char id, slot, slots, alias_checksum;
+
+ if (!*unicode) {
+ *unicode = (wchar_t *)__get_free_page(GFP_KERNEL);
+ if (!*unicode) {
+ brelse(*bh);
+ return -ENOMEM;
+ }
+ }
+parse_long:
+ slots = 0;
+ ds = (struct msdos_dir_slot *)*de;
+ id = ds->id;
+ if (!(id & 0x40))
+ return PARSE_INVALID;
+ slots = id & ~0x40;
+ if (slots > 20 || !slots) /* ceil(256 * 2 / 26) */
+ return PARSE_INVALID;
+ *nr_slots = slots;
+ alias_checksum = ds->alias_checksum;
+
+ slot = slots;
+ while (1) {
+ int offset;
+
+ slot--;
+ offset = slot * 13;
+ fat16_towchar(*unicode + offset, ds->name0_4, 5);
+ fat16_towchar(*unicode + offset + 5, ds->name5_10, 6);
+ fat16_towchar(*unicode + offset + 11, ds->name11_12, 2);
+
+ if (ds->id & 0x40)
+ (*unicode)[offset + 13] = 0;
+ if (fat_get_entry(dir, pos, bh, de) < 0)
+ return PARSE_EOF;
+ if (slot == 0)
+ break;
+ ds = (struct msdos_dir_slot *)*de;
+ if (ds->attr != ATTR_EXT)
+ return PARSE_NOT_LONGNAME;
+ if ((ds->id & ~0x40) != slot)
+ goto parse_long;
+ if (ds->alias_checksum != alias_checksum)
+ goto parse_long;
+ }
+ if ((*de)->name[0] == DELETED_FLAG)
+ return PARSE_INVALID;
+ if ((*de)->attr == ATTR_EXT)
+ goto parse_long;
+ if (IS_FREE((*de)->name) || ((*de)->attr & ATTR_VOLUME))
+ return PARSE_INVALID;
+ if (fat_checksum((*de)->name) != alias_checksum)
+ *nr_slots = 0;
+
+ return 0;
+}
+
/*
* Return values: negative -> error, 0 -> not found, positive -> found,
* value is the total amount of slots, including the shortname entry.
@@ -259,68 +333,16 @@ parse_record:
if (de->attr != ATTR_EXT && IS_FREE(de->name))
continue;
if (de->attr == ATTR_EXT) {
- struct msdos_dir_slot *ds;
- unsigned char id;
- unsigned char slot;
- unsigned char slots;
- unsigned char sum;
- unsigned char alias_checksum;
-
- if (!unicode) {
- unicode = (wchar_t *)
- __get_free_page(GFP_KERNEL);
- if (!unicode) {
- brelse(bh);
- return -ENOMEM;
- }
- }
-parse_long:
- slots = 0;
- ds = (struct msdos_dir_slot *) de;
- id = ds->id;
- if (!(id & 0x40))
- continue;
- slots = id & ~0x40;
- if (slots > 20 || !slots) /* ceil(256 * 2 / 26) */
- continue;
- nr_slots = slots;
- alias_checksum = ds->alias_checksum;
-
- slot = slots;
- while (1) {
- int offset;
-
- slot--;
- offset = slot * 13;
- fat16_towchar(unicode + offset, ds->name0_4, 5);
- fat16_towchar(unicode + offset + 5, ds->name5_10, 6);
- fat16_towchar(unicode + offset + 11, ds->name11_12, 2);
-
- if (ds->id & 0x40) {
- unicode[offset + 13] = 0;
- }
- if (fat_get_entry(inode, &cpos, &bh, &de) < 0)
- goto EODir;
- if (slot == 0)
- break;
- ds = (struct msdos_dir_slot *) de;
- if (ds->attr != ATTR_EXT)
- goto parse_record;
- if ((ds->id & ~0x40) != slot)
- goto parse_long;
- if (ds->alias_checksum != alias_checksum)
- goto parse_long;
- }
- if (de->name[0] == DELETED_FLAG)
- continue;
- if (de->attr == ATTR_EXT)
- goto parse_long;
- if (IS_FREE(de->name) || (de->attr & ATTR_VOLUME))
+ int status = fat_parse_long(inode, &cpos, &bh, &de,
+ &unicode, &nr_slots);
+ if (status < 0)
+ return status;
+ else if (status == PARSE_INVALID)
continue;
- for (sum = 0, i = 0; i < 11; i++)
- sum = (((sum&1)<<7)|((sum&0xfe)>>1)) + de->name[i];
- if (sum != alias_checksum)
- nr_slots = 0;
+ else if (status == PARSE_NOT_LONGNAME)
+ goto parse_record;
+ else if (status == PARSE_EOF)
+ goto EODir;
}
memcpy(work, de->name, sizeof(de->name));
@@ -408,8 +430,8 @@ struct fat_ioctl_filldir_callback {
int short_len;
};
-static int fat_readdirx(struct inode *inode, struct file *filp, void *dirent,
- filldir_t filldir, int short_only, int both)
+static int __fat_readdir(struct inode *inode, struct file *filp, void *dirent,
+ filldir_t filldir, int short_only, int both)
{
struct super_block *sb = inode->i_sb;
struct msdos_sb_info *sbi = MSDOS_SB(sb);
@@ -458,9 +480,10 @@ static int fat_readdirx(struct inode *inode, struct file *filp, void *dirent,
bh = NULL;
GetNew:
- long_slots = 0;
if (fat_get_entry(inode, &cpos, &bh, &de) == -1)
goto EODir;
+parse_record:
+ long_slots = 0;
/* Check for long filename entry */
if (isvfat) {
if (de->name[0] == DELETED_FLAG)
@@ -475,69 +498,18 @@ GetNew:
}
if (isvfat && de->attr == ATTR_EXT) {
- struct msdos_dir_slot *ds;
- unsigned char id;
- unsigned char slot;
- unsigned char slots;
- unsigned char sum;
- unsigned char alias_checksum;
-
- if (!unicode) {
- unicode = (wchar_t *)__get_free_page(GFP_KERNEL);
- if (!unicode) {
- filp->f_pos = cpos;
- brelse(bh);
- ret = -ENOMEM;
- goto out;
- }
- }
-ParseLong:
- slots = 0;
- ds = (struct msdos_dir_slot *) de;
- id = ds->id;
- if (!(id & 0x40))
- goto RecEnd;
- slots = id & ~0x40;
- if (slots > 20 || !slots) /* ceil(256 * 2 / 26) */
+ int status = fat_parse_long(inode, &cpos, &bh, &de,
+ &unicode, &long_slots);
+ if (status < 0) {
+ filp->f_pos = cpos;
+ ret = status;
+ goto out;
+ } else if (status == PARSE_INVALID)
goto RecEnd;
- long_slots = slots;
- alias_checksum = ds->alias_checksum;
-
- slot = slots;
- while (1) {
- int offset;
-
- slot--;
- offset = slot * 13;
- fat16_towchar(unicode + offset, ds->name0_4, 5);
- fat16_towchar(unicode + offset + 5, ds->name5_10, 6);
- fat16_towchar(unicode + offset + 11, ds->name11_12, 2);
-
- if (ds->id & 0x40) {
- unicode[offset + 13] = 0;
- }
- if (fat_get_entry(inode, &cpos, &bh, &de) == -1)
- goto EODir;
- if (slot == 0)
- break;
- ds = (struct msdos_dir_slot *) de;
- if (ds->attr != ATTR_EXT)
- goto RecEnd; /* XXX */
- if ((ds->id & ~0x40) != slot)
- goto ParseLong;
- if (ds->alias_checksum != alias_checksum)
- goto ParseLong;
- }
- if (de->name[0] == DELETED_FLAG)
- goto RecEnd;
- if (de->attr == ATTR_EXT)
- goto ParseLong;
- if (IS_FREE(de->name) || (de->attr & ATTR_VOLUME))
- goto RecEnd;
- for (sum = 0, i = 0; i < 11; i++)
- sum = (((sum&1)<<7)|((sum&0xfe)>>1)) + de->name[i];
- if (sum != alias_checksum)
- long_slots = 0;
+ else if (status == PARSE_NOT_LONGNAME)
+ goto parse_record;
+ else if (status == PARSE_EOF)
+ goto EODir;
}
if (sbi->options.dotsOK) {
@@ -671,7 +643,7 @@ out:
static int fat_readdir(struct file *filp, void *dirent, filldir_t filldir)
{
struct inode *inode = filp->f_dentry->d_inode;
- return fat_readdirx(inode, filp, dirent, filldir, 0, 0);
+ return __fat_readdir(inode, filp, dirent, filldir, 0, 0);
}
static int fat_ioctl_filldir(void *__buf, const char *name, int name_len,
@@ -760,8 +732,8 @@ static int fat_dir_ioctl(struct inode * inode, struct file * filp,
down(&inode->i_sem);
ret = -ENOENT;
if (!IS_DEADDIR(inode)) {
- ret = fat_readdirx(inode, filp, &buf, fat_ioctl_filldir,
- short_only, both);
+ ret = __fat_readdir(inode, filp, &buf, fat_ioctl_filldir,
+ short_only, both);
}
up(&inode->i_sem);
if (ret >= 0)
diff --git a/fs/file_table.c b/fs/file_table.c
index 86ec8ae985b4..4dc205546547 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -56,13 +56,13 @@ void filp_dtor(void * objp, struct kmem_cache_s *cachep, unsigned long dflags)
static inline void file_free_rcu(struct rcu_head *head)
{
- struct file *f = container_of(head, struct file, f_rcuhead);
+ struct file *f = container_of(head, struct file, f_u.fu_rcuhead);
kmem_cache_free(filp_cachep, f);
}
static inline void file_free(struct file *f)
{
- call_rcu(&f->f_rcuhead, file_free_rcu);
+ call_rcu(&f->f_u.fu_rcuhead, file_free_rcu);
}
/* Find an unused file structure and return a pointer to it.
@@ -95,7 +95,7 @@ struct file *get_empty_filp(void)
f->f_gid = current->fsgid;
rwlock_init(&f->f_owner.lock);
/* f->f_version: 0 */
- INIT_LIST_HEAD(&f->f_list);
+ INIT_LIST_HEAD(&f->f_u.fu_list);
return f;
over:
@@ -225,15 +225,15 @@ void file_move(struct file *file, struct list_head *list)
if (!list)
return;
file_list_lock();
- list_move(&file->f_list, list);
+ list_move(&file->f_u.fu_list, list);
file_list_unlock();
}
void file_kill(struct file *file)
{
- if (!list_empty(&file->f_list)) {
+ if (!list_empty(&file->f_u.fu_list)) {
file_list_lock();
- list_del_init(&file->f_list);
+ list_del_init(&file->f_u.fu_list);
file_list_unlock();
}
}
@@ -245,7 +245,7 @@ int fs_may_remount_ro(struct super_block *sb)
/* Check that no files are currently opened for writing. */
file_list_lock();
list_for_each(p, &sb->s_files) {
- struct file *file = list_entry(p, struct file, f_list);
+ struct file *file = list_entry(p, struct file, f_u.fu_list);
struct inode *inode = file->f_dentry->d_inode;
/* File with pending delete? */
diff --git a/fs/filesystems.c b/fs/filesystems.c
index 44082bfdfec9..9f1072836c8e 100644
--- a/fs/filesystems.c
+++ b/fs/filesystems.c
@@ -12,6 +12,7 @@
#include <linux/kmod.h>
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/sched.h> /* for 'current' */
#include <asm/uaccess.h>
/*
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index e94ab398b717..ffab4783ac64 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -230,7 +230,6 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc)
* The inode is clean, unused
*/
list_move(&inode->i_list, &inode_unused);
- inodes_stat.nr_unused++;
}
}
wake_up_inode(inode);
@@ -238,14 +237,20 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc)
}
/*
- * Write out an inode's dirty pages. Called under inode_lock.
+ * Write out an inode's dirty pages. Called under inode_lock. Either the
+ * caller has ref on the inode (either via __iget or via syscall against an fd)
+ * or the inode has I_WILL_FREE set (via generic_forget_inode)
*/
static int
-__writeback_single_inode(struct inode *inode,
- struct writeback_control *wbc)
+__writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
{
wait_queue_head_t *wqh;
+ if (!atomic_read(&inode->i_count))
+ WARN_ON(!(inode->i_state & I_WILL_FREE));
+ else
+ WARN_ON(inode->i_state & I_WILL_FREE);
+
if ((wbc->sync_mode != WB_SYNC_ALL) && (inode->i_state & I_LOCK)) {
list_move(&inode->i_list, &inode->i_sb->s_dirty);
return 0;
@@ -259,11 +264,9 @@ __writeback_single_inode(struct inode *inode,
wqh = bit_waitqueue(&inode->i_state, __I_LOCK);
do {
- __iget(inode);
spin_unlock(&inode_lock);
__wait_on_bit(wqh, &wq, inode_wait,
TASK_UNINTERRUPTIBLE);
- iput(inode);
spin_lock(&inode_lock);
} while (inode->i_state & I_LOCK);
}
@@ -541,14 +544,15 @@ void sync_inodes(int wait)
}
/**
- * write_inode_now - write an inode to disk
- * @inode: inode to write to disk
- * @sync: whether the write should be synchronous or not
+ * write_inode_now - write an inode to disk
+ * @inode: inode to write to disk
+ * @sync: whether the write should be synchronous or not
+ *
+ * This function commits an inode to disk immediately if it is dirty. This is
+ * primarily needed by knfsd.
*
- * This function commits an inode to disk immediately if it is
- * dirty. This is primarily needed by knfsd.
+ * The caller must either have a ref on the inode or must have set I_WILL_FREE.
*/
-
int write_inode_now(struct inode *inode, int sync)
{
int ret;
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index d4c869c6d01b..a6f90a6c754a 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -151,9 +151,9 @@ void fuse_release_background(struct fuse_req *req)
/*
* This function is called when a request is finished. Either a reply
* has arrived or it was interrupted (and not yet sent) or some error
- * occured during communication with userspace, or the device file was
- * closed. It decreases the referece count for the request. In case
- * of a background request the referece to the stored objects are
+ * occurred during communication with userspace, or the device file was
+ * closed. It decreases the reference count for the request. In case
+ * of a background request the reference to the stored objects are
* released. The requester thread is woken up (if still waiting), and
* finally the request is either freed or put on the unused_list
*
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 29f1e9f6e85c..70dba721acab 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -741,13 +741,14 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
if (inode && S_ISDIR(inode->i_mode)) {
/* Don't allow creating an alias to a directory */
struct dentry *alias = d_find_alias(inode);
- if (alias && !(alias->d_flags & DCACHE_DISCONNECTED)) {
+ if (alias) {
dput(alias);
iput(inode);
return ERR_PTR(-EIO);
}
}
- return d_splice_alias(inode, entry);
+ d_add(entry, inode);
+ return NULL;
}
static int fuse_setxattr(struct dentry *entry, const char *name,
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 24d761518d86..5cb456f572c1 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -349,22 +349,22 @@ int fuse_fsync_common(struct file *file, struct dentry *de, int datasync,
int isdir);
/**
- * Initialise file operations on a regular file
+ * Initialize file operations on a regular file
*/
void fuse_init_file_inode(struct inode *inode);
/**
- * Initialise inode operations on regular files and special files
+ * Initialize inode operations on regular files and special files
*/
void fuse_init_common(struct inode *inode);
/**
- * Initialise inode and file operations on a directory
+ * Initialize inode and file operations on a directory
*/
void fuse_init_dir(struct inode *inode);
/**
- * Initialise inode operations on a symlink
+ * Initialize inode operations on a symlink
*/
void fuse_init_symlink(struct inode *inode);
@@ -411,7 +411,7 @@ struct fuse_req *fuse_get_request(struct fuse_conn *fc);
/**
* Decrement reference count of a request. If count goes to zero put
- * on unused list (preallocated) or free reqest (not preallocated).
+ * on unused list (preallocated) or free request (not preallocated).
*/
void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req);
@@ -431,7 +431,7 @@ void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req);
void request_send_background(struct fuse_conn *fc, struct fuse_req *req);
/**
- * Release inodes and file assiciated with background request
+ * Release inodes and file associated with background request
*/
void fuse_release_background(struct fuse_req *req);
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 3a9b6d179cbd..e026c807e6b3 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -45,10 +45,58 @@ static struct backing_dev_info hugetlbfs_backing_dev_info = {
int sysctl_hugetlb_shm_group;
+static void huge_pagevec_release(struct pagevec *pvec)
+{
+ int i;
+
+ for (i = 0; i < pagevec_count(pvec); ++i)
+ put_page(pvec->pages[i]);
+
+ pagevec_reinit(pvec);
+}
+
+/*
+ * huge_pages_needed tries to determine the number of new huge pages that
+ * will be required to fully populate this VMA. This will be equal to
+ * the size of the VMA in huge pages minus the number of huge pages
+ * (covered by this VMA) that are found in the page cache.
+ *
+ * Result is in bytes to be compatible with is_hugepage_mem_enough()
+ */
+unsigned long
+huge_pages_needed(struct address_space *mapping, struct vm_area_struct *vma)
+{
+ int i;
+ struct pagevec pvec;
+ unsigned long start = vma->vm_start;
+ unsigned long end = vma->vm_end;
+ unsigned long hugepages = (end - start) >> HPAGE_SHIFT;
+ pgoff_t next = vma->vm_pgoff;
+ pgoff_t endpg = next + ((end - start) >> PAGE_SHIFT);
+
+ pagevec_init(&pvec, 0);
+ while (next < endpg) {
+ if (!pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE))
+ break;
+ for (i = 0; i < pagevec_count(&pvec); i++) {
+ struct page *page = pvec.pages[i];
+ if (page->index > next)
+ next = page->index;
+ if (page->index >= endpg)
+ break;
+ next++;
+ hugepages--;
+ }
+ huge_pagevec_release(&pvec);
+ }
+ return hugepages << HPAGE_SHIFT;
+}
+
static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
{
struct inode *inode = file->f_dentry->d_inode;
struct address_space *mapping = inode->i_mapping;
+ unsigned long bytes;
loff_t len, vma_len;
int ret;
@@ -67,6 +115,10 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
if (vma->vm_end - vma->vm_start < HPAGE_SIZE)
return -EINVAL;
+ bytes = huge_pages_needed(mapping, vma);
+ if (!is_hugepage_mem_enough(bytes))
+ return -ENOMEM;
+
vma_len = (loff_t)(vma->vm_end - vma->vm_start);
down(&inode->i_sem);
@@ -79,10 +131,8 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
if (!(vma->vm_flags & VM_WRITE) && len > inode->i_size)
goto out;
- ret = hugetlb_prefault(mapping, vma);
- if (ret)
- goto out;
-
+ ret = 0;
+ hugetlb_prefault_arch_hook(vma->vm_mm);
if (inode->i_size < len)
inode->i_size = len;
out:
@@ -92,7 +142,7 @@ out:
}
/*
- * Called under down_write(mmap_sem), page_table_lock is not held
+ * Called under down_write(mmap_sem).
*/
#ifdef HAVE_ARCH_HUGETLB_UNMAPPED_AREA
@@ -171,16 +221,6 @@ static int hugetlbfs_commit_write(struct file *file,
return -EINVAL;
}
-static void huge_pagevec_release(struct pagevec *pvec)
-{
- int i;
-
- for (i = 0; i < pagevec_count(pvec); ++i)
- put_page(pvec->pages[i]);
-
- pagevec_reinit(pvec);
-}
-
static void truncate_huge_page(struct page *page)
{
clear_page_dirty(page);
@@ -224,52 +264,35 @@ static void truncate_hugepages(struct address_space *mapping, loff_t lstart)
static void hugetlbfs_delete_inode(struct inode *inode)
{
- struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(inode->i_sb);
-
- hlist_del_init(&inode->i_hash);
- list_del_init(&inode->i_list);
- list_del_init(&inode->i_sb_list);
- inode->i_state |= I_FREEING;
- inodes_stat.nr_inodes--;
- spin_unlock(&inode_lock);
-
if (inode->i_data.nrpages)
truncate_hugepages(&inode->i_data, 0);
-
- security_inode_delete(inode);
-
- if (sbinfo->free_inodes >= 0) {
- spin_lock(&sbinfo->stat_lock);
- sbinfo->free_inodes++;
- spin_unlock(&sbinfo->stat_lock);
- }
-
clear_inode(inode);
- destroy_inode(inode);
}
static void hugetlbfs_forget_inode(struct inode *inode)
{
- struct super_block *super_block = inode->i_sb;
- struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(super_block);
+ struct super_block *sb = inode->i_sb;
- if (hlist_unhashed(&inode->i_hash))
- goto out_truncate;
-
- if (!(inode->i_state & (I_DIRTY|I_LOCK))) {
- list_del(&inode->i_list);
- list_add(&inode->i_list, &inode_unused);
- }
- inodes_stat.nr_unused++;
- if (!super_block || (super_block->s_flags & MS_ACTIVE)) {
+ if (!hlist_unhashed(&inode->i_hash)) {
+ if (!(inode->i_state & (I_DIRTY|I_LOCK)))
+ list_move(&inode->i_list, &inode_unused);
+ inodes_stat.nr_unused++;
+ if (!sb || (sb->s_flags & MS_ACTIVE)) {
+ spin_unlock(&inode_lock);
+ return;
+ }
+ inode->i_state |= I_WILL_FREE;
spin_unlock(&inode_lock);
- return;
+ /*
+ * write_inode_now is a noop as we set BDI_CAP_NO_WRITEBACK
+ * in our backing_dev_info.
+ */
+ write_inode_now(inode, 1);
+ spin_lock(&inode_lock);
+ inode->i_state &= ~I_WILL_FREE;
+ inodes_stat.nr_unused--;
+ hlist_del_init(&inode->i_hash);
}
-
- /* write_inode_now() ? */
- inodes_stat.nr_unused--;
- hlist_del_init(&inode->i_hash);
-out_truncate:
list_del_init(&inode->i_list);
list_del_init(&inode->i_sb_list);
inode->i_state |= I_FREEING;
@@ -277,13 +300,6 @@ out_truncate:
spin_unlock(&inode_lock);
if (inode->i_data.nrpages)
truncate_hugepages(&inode->i_data, 0);
-
- if (sbinfo->free_inodes >= 0) {
- spin_lock(&sbinfo->stat_lock);
- sbinfo->free_inodes++;
- spin_unlock(&sbinfo->stat_lock);
- }
-
clear_inode(inode);
destroy_inode(inode);
}
@@ -291,7 +307,7 @@ out_truncate:
static void hugetlbfs_drop_inode(struct inode *inode)
{
if (!inode->i_nlink)
- hugetlbfs_delete_inode(inode);
+ generic_delete_inode(inode);
else
hugetlbfs_forget_inode(inode);
}
@@ -308,7 +324,6 @@ hugetlb_vmtruncate_list(struct prio_tree_root *root, unsigned long h_pgoff)
vma_prio_tree_foreach(vma, &iter, root, h_pgoff, ULONG_MAX) {
unsigned long h_vm_pgoff;
- unsigned long v_length;
unsigned long v_offset;
h_vm_pgoff = vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT);
@@ -319,11 +334,8 @@ hugetlb_vmtruncate_list(struct prio_tree_root *root, unsigned long h_pgoff)
if (h_vm_pgoff >= h_pgoff)
v_offset = 0;
- v_length = vma->vm_end - vma->vm_start;
-
- zap_hugepage_range(vma,
- vma->vm_start + v_offset,
- v_length - v_offset);
+ unmap_hugepage_range(vma,
+ vma->vm_start + v_offset, vma->vm_end);
}
}
@@ -379,17 +391,6 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb, uid_t uid,
gid_t gid, int mode, dev_t dev)
{
struct inode *inode;
- struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(sb);
-
- if (sbinfo->free_inodes >= 0) {
- spin_lock(&sbinfo->stat_lock);
- if (!sbinfo->free_inodes) {
- spin_unlock(&sbinfo->stat_lock);
- return NULL;
- }
- sbinfo->free_inodes--;
- spin_unlock(&sbinfo->stat_lock);
- }
inode = new_inode(sb);
if (inode) {
@@ -531,29 +532,51 @@ static void hugetlbfs_put_super(struct super_block *sb)
}
}
+static inline int hugetlbfs_dec_free_inodes(struct hugetlbfs_sb_info *sbinfo)
+{
+ if (sbinfo->free_inodes >= 0) {
+ spin_lock(&sbinfo->stat_lock);
+ if (unlikely(!sbinfo->free_inodes)) {
+ spin_unlock(&sbinfo->stat_lock);
+ return 0;
+ }
+ sbinfo->free_inodes--;
+ spin_unlock(&sbinfo->stat_lock);
+ }
+
+ return 1;
+}
+
+static void hugetlbfs_inc_free_inodes(struct hugetlbfs_sb_info *sbinfo)
+{
+ if (sbinfo->free_inodes >= 0) {
+ spin_lock(&sbinfo->stat_lock);
+ sbinfo->free_inodes++;
+ spin_unlock(&sbinfo->stat_lock);
+ }
+}
+
+
static kmem_cache_t *hugetlbfs_inode_cachep;
static struct inode *hugetlbfs_alloc_inode(struct super_block *sb)
{
+ struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(sb);
struct hugetlbfs_inode_info *p;
+ if (unlikely(!hugetlbfs_dec_free_inodes(sbinfo)))
+ return NULL;
p = kmem_cache_alloc(hugetlbfs_inode_cachep, SLAB_KERNEL);
- if (!p)
+ if (unlikely(!p)) {
+ hugetlbfs_inc_free_inodes(sbinfo);
return NULL;
+ }
return &p->vfs_inode;
}
-static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags)
-{
- struct hugetlbfs_inode_info *ei = (struct hugetlbfs_inode_info *)foo;
-
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR)
- inode_init_once(&ei->vfs_inode);
-}
-
static void hugetlbfs_destroy_inode(struct inode *inode)
{
+ hugetlbfs_inc_free_inodes(HUGETLBFS_SB(inode->i_sb));
mpol_free_shared_policy(&HUGETLBFS_I(inode)->policy);
kmem_cache_free(hugetlbfs_inode_cachep, HUGETLBFS_I(inode));
}
@@ -565,6 +588,16 @@ static struct address_space_operations hugetlbfs_aops = {
.set_page_dirty = hugetlbfs_set_page_dirty,
};
+
+static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags)
+{
+ struct hugetlbfs_inode_info *ei = (struct hugetlbfs_inode_info *)foo;
+
+ if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
+ SLAB_CTOR_CONSTRUCTOR)
+ inode_init_once(&ei->vfs_inode);
+}
+
struct file_operations hugetlbfs_file_operations = {
.mmap = hugetlbfs_file_mmap,
.fsync = simple_sync_file,
@@ -592,6 +625,7 @@ static struct super_operations hugetlbfs_ops = {
.alloc_inode = hugetlbfs_alloc_inode,
.destroy_inode = hugetlbfs_destroy_inode,
.statfs = hugetlbfs_statfs,
+ .delete_inode = hugetlbfs_delete_inode,
.drop_inode = hugetlbfs_drop_inode,
.put_super = hugetlbfs_put_super,
};
diff --git a/fs/inode.c b/fs/inode.c
index 7d3316527767..d8d04bd72b59 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1088,6 +1088,7 @@ static void generic_forget_inode(struct inode *inode)
if (inode->i_data.nrpages)
truncate_inode_pages(&inode->i_data, 0);
clear_inode(inode);
+ wake_up_inode(inode);
destroy_inode(inode);
}
diff --git a/fs/jffs2/background.c b/fs/jffs2/background.c
index 0f224384f176..8210ac16a368 100644
--- a/fs/jffs2/background.c
+++ b/fs/jffs2/background.c
@@ -15,6 +15,7 @@
#include <linux/jffs2.h>
#include <linux/mtd/mtd.h>
#include <linux/completion.h>
+#include <linux/sched.h>
#include "nodelist.h"
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index 996d922e503e..316133c626b7 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -18,6 +18,8 @@
#include <linux/mtd/mtd.h>
#include <linux/crc32.h>
#include <linux/mtd/nand.h>
+#include <linux/jiffies.h>
+
#include "nodelist.h"
/* For testing write failures */
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
index 26091a5f88d4..8a53981f9f27 100644
--- a/fs/jfs/jfs_metapage.c
+++ b/fs/jfs/jfs_metapage.c
@@ -86,7 +86,7 @@ struct meta_anchor {
atomic_t io_count;
struct metapage *mp[MPS_PER_PAGE];
};
-#define mp_anchor(page) ((struct meta_anchor *)page->private)
+#define mp_anchor(page) ((struct meta_anchor *)page_private(page))
static inline struct metapage *page_to_mp(struct page *page, uint offset)
{
@@ -108,7 +108,7 @@ static inline int insert_metapage(struct page *page, struct metapage *mp)
if (!a)
return -ENOMEM;
memset(a, 0, sizeof(struct meta_anchor));
- page->private = (unsigned long)a;
+ set_page_private(page, (unsigned long)a);
SetPagePrivate(page);
kmap(page);
}
@@ -136,7 +136,7 @@ static inline void remove_metapage(struct page *page, struct metapage *mp)
a->mp[index] = NULL;
if (--a->mp_count == 0) {
kfree(a);
- page->private = 0;
+ set_page_private(page, 0);
ClearPagePrivate(page);
kunmap(page);
}
@@ -156,13 +156,13 @@ static inline void dec_io(struct page *page, void (*handler) (struct page *))
#else
static inline struct metapage *page_to_mp(struct page *page, uint offset)
{
- return PagePrivate(page) ? (struct metapage *)page->private : NULL;
+ return PagePrivate(page) ? (struct metapage *)page_private(page) : NULL;
}
static inline int insert_metapage(struct page *page, struct metapage *mp)
{
if (mp) {
- page->private = (unsigned long)mp;
+ set_page_private(page, (unsigned long)mp);
SetPagePrivate(page);
kmap(page);
}
@@ -171,7 +171,7 @@ static inline int insert_metapage(struct page *page, struct metapage *mp)
static inline void remove_metapage(struct page *page, struct metapage *mp)
{
- page->private = 0;
+ set_page_private(page, 0);
ClearPagePrivate(page);
kunmap(page);
}
diff --git a/fs/msdos/namei.c b/fs/msdos/namei.c
index 154f511c7245..626a367bcd81 100644
--- a/fs/msdos/namei.c
+++ b/fs/msdos/namei.c
@@ -454,10 +454,10 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
{
struct buffer_head *dotdot_bh;
struct msdos_dir_entry *dotdot_de;
- loff_t dotdot_i_pos;
struct inode *old_inode, *new_inode;
struct fat_slot_info old_sinfo, sinfo;
struct timespec ts;
+ loff_t dotdot_i_pos, new_i_pos;
int err, old_attrs, is_dir, update_dotdot, corrupt = 0;
old_sinfo.bh = sinfo.bh = dotdot_bh = NULL;
@@ -516,28 +516,24 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
if (new_inode) {
if (err)
goto out;
- if (MSDOS_I(new_inode)->i_pos != sinfo.i_pos) {
- /* WTF??? Cry and fail. */
- printk(KERN_WARNING "msdos_rename: fs corrupted\n");
- goto out;
- }
-
if (is_dir) {
err = fat_dir_empty(new_inode);
if (err)
goto out;
}
+ new_i_pos = MSDOS_I(new_inode)->i_pos;
fat_detach(new_inode);
} else {
err = msdos_add_entry(new_dir, new_name, is_dir, is_hid, 0,
&ts, &sinfo);
if (err)
goto out;
+ new_i_pos = sinfo.i_pos;
}
new_dir->i_version++;
fat_detach(old_inode);
- fat_attach(old_inode, sinfo.i_pos);
+ fat_attach(old_inode, new_i_pos);
if (is_hid)
MSDOS_I(old_inode)->i_attrs |= ATTR_HIDDEN;
else
@@ -604,7 +600,7 @@ error_inode:
fat_attach(old_inode, old_sinfo.i_pos);
MSDOS_I(old_inode)->i_attrs = old_attrs;
if (new_inode) {
- fat_attach(new_inode, sinfo.i_pos);
+ fat_attach(new_inode, new_i_pos);
if (corrupt)
corrupt |= fat_sync_inode(new_inode);
} else {
diff --git a/fs/namei.c b/fs/namei.c
index aaaa81036234..c5769c4fcab1 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1311,9 +1311,6 @@ static inline int may_create(struct inode *dir, struct dentry *child,
}
/*
- * Special case: O_CREAT|O_EXCL implies O_NOFOLLOW for security
- * reasons.
- *
* O_DIRECTORY translates into forcing a directory lookup.
*/
static inline int lookup_flags(unsigned int f)
@@ -1323,9 +1320,6 @@ static inline int lookup_flags(unsigned int f)
if (f & O_NOFOLLOW)
retval &= ~LOOKUP_FOLLOW;
- if ((f & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL))
- retval &= ~LOOKUP_FOLLOW;
-
if (f & O_DIRECTORY)
retval |= LOOKUP_DIRECTORY;
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index f2781ca42761..fc0f12ba89cc 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -1274,14 +1274,12 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
}
if ((fattr->valid & NFS_ATTR_FATTR) == 0) {
- spin_unlock(&inode->i_lock);
return 0;
}
/* Has the inode gone and changed behind our back? */
if (nfsi->fileid != fattr->fileid
|| (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) {
- spin_unlock(&inode->i_lock);
return -EIO;
}
diff --git a/fs/proc/array.c b/fs/proc/array.c
index d84eecacbeaf..3e1239e4b303 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -438,7 +438,7 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
jiffies_to_clock_t(it_real_value),
start_time,
vsize,
- mm ? get_mm_counter(mm, rss) : 0, /* you might want to shift this left 3 */
+ mm ? get_mm_rss(mm) : 0,
rsslim,
mm ? mm->start_code : 0,
mm ? mm->end_code : 0,
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 8a8c34461d48..b638fb500743 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -533,7 +533,7 @@ static void proc_kill_inodes(struct proc_dir_entry *de)
*/
file_list_lock();
list_for_each(p, &sb->s_files) {
- struct file * filp = list_entry(p, struct file, f_list);
+ struct file * filp = list_entry(p, struct file, f_u.fu_list);
struct dentry * dentry = filp->f_dentry;
struct inode * inode;
struct file_operations *fops;
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index effa6c0c467a..e6a818a93f3d 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -156,10 +156,13 @@ struct inode *proc_get_inode(struct super_block *sb, unsigned int ino,
WARN_ON(de && de->deleted);
+ if (de != NULL && !try_module_get(de->owner))
+ goto out_mod;
+
inode = iget(sb, ino);
if (!inode)
- goto out_fail;
-
+ goto out_ino;
+
PROC_I(inode)->pde = de;
if (de) {
if (de->mode) {
@@ -171,20 +174,20 @@ struct inode *proc_get_inode(struct super_block *sb, unsigned int ino,
inode->i_size = de->size;
if (de->nlink)
inode->i_nlink = de->nlink;
- if (!try_module_get(de->owner))
- goto out_fail;
if (de->proc_iops)
inode->i_op = de->proc_iops;
if (de->proc_fops)
inode->i_fop = de->proc_fops;
}
-out:
return inode;
-out_fail:
+out_ino:
+ if (de != NULL)
+ module_put(de->owner);
+out_mod:
de_put(de);
- goto out;
+ return NULL;
}
int proc_fill_super(struct super_block *s, void *data, int silent)
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index a3453555a94e..5b6b0b6038a7 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -629,12 +629,4 @@ void __init proc_misc_init(void)
if (entry)
entry->proc_fops = &proc_sysrq_trigger_operations;
#endif
-#ifdef CONFIG_PPC32
- {
- extern struct file_operations ppc_htab_operations;
- entry = create_proc_entry("ppc_htab", S_IRUGO|S_IWUSR, NULL);
- if (entry)
- entry->proc_fops = &ppc_htab_operations;
- }
-#endif
}
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index c7ef3e48e35b..d2fa42006d8f 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -14,22 +14,41 @@
char *task_mem(struct mm_struct *mm, char *buffer)
{
unsigned long data, text, lib;
+ unsigned long hiwater_vm, total_vm, hiwater_rss, total_rss;
+
+ /*
+ * Note: to minimize their overhead, mm maintains hiwater_vm and
+ * hiwater_rss only when about to *lower* total_vm or rss. Any
+ * collector of these hiwater stats must therefore get total_vm
+ * and rss too, which will usually be the higher. Barriers? not
+ * worth the effort, such snapshots can always be inconsistent.
+ */
+ hiwater_vm = total_vm = mm->total_vm;
+ if (hiwater_vm < mm->hiwater_vm)
+ hiwater_vm = mm->hiwater_vm;
+ hiwater_rss = total_rss = get_mm_rss(mm);
+ if (hiwater_rss < mm->hiwater_rss)
+ hiwater_rss = mm->hiwater_rss;
data = mm->total_vm - mm->shared_vm - mm->stack_vm;
text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) >> 10;
lib = (mm->exec_vm << (PAGE_SHIFT-10)) - text;
buffer += sprintf(buffer,
+ "VmPeak:\t%8lu kB\n"
"VmSize:\t%8lu kB\n"
"VmLck:\t%8lu kB\n"
+ "VmHWM:\t%8lu kB\n"
"VmRSS:\t%8lu kB\n"
"VmData:\t%8lu kB\n"
"VmStk:\t%8lu kB\n"
"VmExe:\t%8lu kB\n"
"VmLib:\t%8lu kB\n"
"VmPTE:\t%8lu kB\n",
- (mm->total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
+ hiwater_vm << (PAGE_SHIFT-10),
+ (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
mm->locked_vm << (PAGE_SHIFT-10),
- get_mm_counter(mm, rss) << (PAGE_SHIFT-10),
+ hiwater_rss << (PAGE_SHIFT-10),
+ total_rss << (PAGE_SHIFT-10),
data << (PAGE_SHIFT-10),
mm->stack_vm << (PAGE_SHIFT-10), text, lib,
(PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
@@ -44,13 +63,11 @@ unsigned long task_vsize(struct mm_struct *mm)
int task_statm(struct mm_struct *mm, int *shared, int *text,
int *data, int *resident)
{
- int rss = get_mm_counter(mm, rss);
-
- *shared = rss - get_mm_counter(mm, anon_rss);
+ *shared = get_mm_counter(mm, file_rss);
*text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK))
>> PAGE_SHIFT;
*data = mm->total_vm - mm->shared_vm;
- *resident = rss;
+ *resident = *shared + get_mm_counter(mm, anon_rss);
return mm->total_vm;
}
@@ -186,13 +203,14 @@ static void smaps_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
struct mem_size_stats *mss)
{
pte_t *pte, ptent;
+ spinlock_t *ptl;
unsigned long pfn;
struct page *page;
- pte = pte_offset_map(pmd, addr);
+ pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
do {
ptent = *pte;
- if (pte_none(ptent) || !pte_present(ptent))
+ if (!pte_present(ptent))
continue;
mss->resident += PAGE_SIZE;
@@ -213,8 +231,8 @@ static void smaps_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
mss->private_clean += PAGE_SIZE;
}
} while (pte++, addr += PAGE_SIZE, addr != end);
- pte_unmap(pte - 1);
- cond_resched_lock(&vma->vm_mm->page_table_lock);
+ pte_unmap_unlock(pte - 1, ptl);
+ cond_resched();
}
static inline void smaps_pmd_range(struct vm_area_struct *vma, pud_t *pud,
@@ -268,17 +286,11 @@ static inline void smaps_pgd_range(struct vm_area_struct *vma,
static int show_smap(struct seq_file *m, void *v)
{
struct vm_area_struct *vma = v;
- struct mm_struct *mm = vma->vm_mm;
struct mem_size_stats mss;
memset(&mss, 0, sizeof mss);
-
- if (mm) {
- spin_lock(&mm->page_table_lock);
+ if (vma->vm_mm)
smaps_pgd_range(vma, vma->vm_start, vma->vm_end, &mss);
- spin_unlock(&mm->page_table_lock);
- }
-
return show_map_internal(m, v, &mss);
}
@@ -407,7 +419,6 @@ static struct numa_maps *get_numa_maps(const struct vm_area_struct *vma)
for_each_node(i)
md->node[i] =0;
- spin_lock(&mm->page_table_lock);
for (vaddr = vma->vm_start; vaddr < vma->vm_end; vaddr += PAGE_SIZE) {
page = follow_page(mm, vaddr, 0);
if (page) {
@@ -422,8 +433,8 @@ static struct numa_maps *get_numa_maps(const struct vm_area_struct *vma)
md->anon++;
md->node[page_to_nid(page)]++;
}
+ cond_resched();
}
- spin_unlock(&mm->page_table_lock);
return md;
}
@@ -469,7 +480,7 @@ static int show_numa_map(struct seq_file *m, void *v)
seq_printf(m, " interleave={");
first = 1;
for_each_node(n) {
- if (test_bit(n, pol->v.nodes)) {
+ if (node_isset(n, pol->v.nodes)) {
if (!first)
seq_putc(m,',');
else
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 44b02fc02ebe..42afb5bef111 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -1024,12 +1024,8 @@ static int reiserfs_parse_options(struct super_block *s, char *options, /* strin
strcpy(REISERFS_SB(s)->s_qf_names[qtype], arg);
*mount_options |= 1 << REISERFS_QUOTA;
} else {
- if (REISERFS_SB(s)->s_qf_names[qtype]) {
- kfree(REISERFS_SB(s)->
- s_qf_names[qtype]);
- REISERFS_SB(s)->s_qf_names[qtype] =
- NULL;
- }
+ kfree(REISERFS_SB(s)->s_qf_names[qtype]);
+ REISERFS_SB(s)->s_qf_names[qtype] = NULL;
}
}
if (c == 'f') {
@@ -1158,11 +1154,10 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
if (!reiserfs_parse_options
(s, arg, &mount_options, &blocks, NULL, &commit_max_age)) {
#ifdef CONFIG_QUOTA
- for (i = 0; i < MAXQUOTAS; i++)
- if (REISERFS_SB(s)->s_qf_names[i]) {
- kfree(REISERFS_SB(s)->s_qf_names[i]);
- REISERFS_SB(s)->s_qf_names[i] = NULL;
- }
+ for (i = 0; i < MAXQUOTAS; i++) {
+ kfree(REISERFS_SB(s)->s_qf_names[i]);
+ REISERFS_SB(s)->s_qf_names[i] = NULL;
+ }
#endif
return -EINVAL;
}
@@ -1940,13 +1935,11 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
brelse(SB_BUFFER_WITH_SB(s));
#ifdef CONFIG_QUOTA
for (j = 0; j < MAXQUOTAS; j++) {
- if (sbi->s_qf_names[j])
- kfree(sbi->s_qf_names[j]);
+ kfree(sbi->s_qf_names[j]);
+ sbi->s_qf_names[j] = NULL;
}
#endif
- if (sbi != NULL) {
- kfree(sbi);
- }
+ kfree(sbi);
s->s_fs_info = NULL;
return errval;
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c
index 6703efa3c430..a47ac9aac8b2 100644
--- a/fs/reiserfs/xattr_acl.c
+++ b/fs/reiserfs/xattr_acl.c
@@ -296,8 +296,7 @@ reiserfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
}
}
- if (value)
- kfree(value);
+ kfree(value);
if (!error) {
/* Release the old one */
diff --git a/fs/super.c b/fs/super.c
index 6e57ee252e14..f60155ec7780 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -513,7 +513,7 @@ static void mark_files_ro(struct super_block *sb)
struct file *f;
file_list_lock();
- list_for_each_entry(f, &sb->s_files, f_list) {
+ list_for_each_entry(f, &sb->s_files, f_u.fu_list) {
if (S_ISREG(f->f_dentry->d_inode->i_mode) && file_count(f))
f->f_mode &= ~FMODE_WRITE;
}
diff --git a/fs/vfat/namei.c b/fs/vfat/namei.c
index 1c6f6b57ef1c..ef46939c0c1a 100644
--- a/fs/vfat/namei.c
+++ b/fs/vfat/namei.c
@@ -621,8 +621,7 @@ static int vfat_build_slots(struct inode *dir, const unsigned char *name,
}
/* build the entry of long file name */
- for (cksum = i = 0; i < 11; i++)
- cksum = (((cksum&1)<<7)|((cksum&0xfe)>>1)) + msdos_name[i];
+ cksum = fat_checksum(msdos_name);
*nr_slots = usize / 13;
for (ps = slots, i = *nr_slots; i > 0; i--, ps++) {
@@ -888,10 +887,10 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
{
struct buffer_head *dotdot_bh;
struct msdos_dir_entry *dotdot_de;
- loff_t dotdot_i_pos;
struct inode *old_inode, *new_inode;
struct fat_slot_info old_sinfo, sinfo;
struct timespec ts;
+ loff_t dotdot_i_pos, new_i_pos;
int err, is_dir, update_dotdot, corrupt = 0;
old_sinfo.bh = sinfo.bh = dotdot_bh = NULL;
@@ -914,31 +913,24 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
ts = CURRENT_TIME_SEC;
if (new_inode) {
- err = vfat_find(new_dir, &new_dentry->d_name, &sinfo);
- if (err)
- goto out;
- if (MSDOS_I(new_inode)->i_pos != sinfo.i_pos) {
- /* WTF??? Cry and fail. */
- printk(KERN_WARNING "vfat_rename: fs corrupted\n");
- goto out;
- }
-
if (is_dir) {
err = fat_dir_empty(new_inode);
if (err)
goto out;
}
+ new_i_pos = MSDOS_I(new_inode)->i_pos;
fat_detach(new_inode);
} else {
err = vfat_add_entry(new_dir, &new_dentry->d_name, is_dir, 0,
&ts, &sinfo);
if (err)
goto out;
+ new_i_pos = sinfo.i_pos;
}
new_dir->i_version++;
fat_detach(old_inode);
- fat_attach(old_inode, sinfo.i_pos);
+ fat_attach(old_inode, new_i_pos);
if (IS_DIRSYNC(new_dir)) {
err = fat_sync_inode(old_inode);
if (err)
@@ -1002,7 +994,7 @@ error_inode:
fat_detach(old_inode);
fat_attach(old_inode, old_sinfo.i_pos);
if (new_inode) {
- fat_attach(new_inode, sinfo.i_pos);
+ fat_attach(new_inode, new_i_pos);
if (corrupt)
corrupt |= fat_sync_inode(new_inode);
} else {
diff --git a/fs/xattr.c b/fs/xattr.c
index 3f9c64bea151..f6e00c0e114f 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -143,7 +143,7 @@ getxattr(struct dentry *d, char __user *name, void __user *value, size_t size)
if (size) {
if (size > XATTR_SIZE_MAX)
size = XATTR_SIZE_MAX;
- kvalue = kmalloc(size, GFP_KERNEL);
+ kvalue = kzalloc(size, GFP_KERNEL);
if (!kvalue)
return -ENOMEM;
}
@@ -154,11 +154,15 @@ getxattr(struct dentry *d, char __user *name, void __user *value, size_t size)
error = -EOPNOTSUPP;
if (d->d_inode->i_op && d->d_inode->i_op->getxattr)
error = d->d_inode->i_op->getxattr(d, kname, kvalue, size);
- else if (!strncmp(kname, XATTR_SECURITY_PREFIX,
- sizeof XATTR_SECURITY_PREFIX - 1)) {
+
+ if (!strncmp(kname, XATTR_SECURITY_PREFIX,
+ sizeof XATTR_SECURITY_PREFIX - 1)) {
const char *suffix = kname + sizeof XATTR_SECURITY_PREFIX - 1;
- error = security_inode_getsecurity(d->d_inode, suffix, kvalue,
- size);
+ int rv = security_inode_getsecurity(d->d_inode, suffix, kvalue,
+ size, error);
+ /* Security module active: overwrite error value */
+ if (rv != -EOPNOTSUPP)
+ error = rv;
}
if (error > 0) {
if (size && copy_to_user(value, kvalue, error))
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index ba4767c04adf..4cd46abe8434 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -181,8 +181,9 @@ set_page_region(
size_t offset,
size_t length)
{
- page->private |= page_region_mask(offset, length);
- if (page->private == ~0UL)
+ set_page_private(page,
+ page_private(page) | page_region_mask(offset, length));
+ if (page_private(page) == ~0UL)
SetPageUptodate(page);
}
@@ -194,7 +195,7 @@ test_page_region(
{
unsigned long mask = page_region_mask(offset, length);
- return (mask && (page->private & mask) == mask);
+ return (mask && (page_private(page) & mask) == mask);
}
/*
diff --git a/include/asm-alpha/barrier.h b/include/asm-alpha/barrier.h
index 229c83fe77cb..681ff581afa5 100644
--- a/include/asm-alpha/barrier.h
+++ b/include/asm-alpha/barrier.h
@@ -1,6 +1,8 @@
#ifndef __BARRIER_H
#define __BARRIER_H
+#include <asm/compiler.h>
+
#define mb() \
__asm__ __volatile__("mb": : :"memory")
diff --git a/include/asm-alpha/rwsem.h b/include/asm-alpha/rwsem.h
index 8e058a67c9a4..fafdd4f7010a 100644
--- a/include/asm-alpha/rwsem.h
+++ b/include/asm-alpha/rwsem.h
@@ -262,5 +262,10 @@ static inline long rwsem_atomic_update(long val, struct rw_semaphore *sem)
#endif
}
+static inline int rwsem_is_locked(struct rw_semaphore *sem)
+{
+ return (sem->count != 0);
+}
+
#endif /* __KERNEL__ */
#endif /* _ALPHA_RWSEM_H */
diff --git a/include/asm-alpha/semaphore.h b/include/asm-alpha/semaphore.h
index eb2cbd97d404..1a6295f2c2d4 100644
--- a/include/asm-alpha/semaphore.h
+++ b/include/asm-alpha/semaphore.h
@@ -26,9 +26,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/asm-arm/arch-aaec2000/memory.h b/include/asm-arm/arch-aaec2000/memory.h
index 79c90813bc3e..d8209f8911d6 100644
--- a/include/asm-arm/arch-aaec2000/memory.h
+++ b/include/asm-arm/arch-aaec2000/memory.h
@@ -13,7 +13,7 @@
#include <linux/config.h>
-#define PHYS_OFFSET (0xf0000000UL)
+#define PHYS_OFFSET UL(0xf0000000)
#define __virt_to_bus(x) __virt_to_phys(x)
#define __bus_to_virt(x) __phys_to_virt(x)
diff --git a/include/asm-arm/arch-cl7500/memory.h b/include/asm-arm/arch-cl7500/memory.h
index 9776bba8e585..34f40a6cec30 100644
--- a/include/asm-arm/arch-cl7500/memory.h
+++ b/include/asm-arm/arch-cl7500/memory.h
@@ -17,7 +17,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET (0x10000000UL)
+#define PHYS_OFFSET UL(0x10000000)
/*
* These are exactly the same on the RiscPC as the
diff --git a/include/asm-arm/arch-clps711x/memory.h b/include/asm-arm/arch-clps711x/memory.h
index bd978947db42..61d8717406ce 100644
--- a/include/asm-arm/arch-clps711x/memory.h
+++ b/include/asm-arm/arch-clps711x/memory.h
@@ -25,7 +25,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET (0xc0000000UL)
+#define PHYS_OFFSET UL(0xc0000000)
/*
* Virtual view <-> DMA view memory address translations
diff --git a/include/asm-arm/arch-ebsa110/memory.h b/include/asm-arm/arch-ebsa110/memory.h
index 5a9493e12275..02f144520c10 100644
--- a/include/asm-arm/arch-ebsa110/memory.h
+++ b/include/asm-arm/arch-ebsa110/memory.h
@@ -19,7 +19,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET (0x00000000UL)
+#define PHYS_OFFSET UL(0x00000000)
/*
* We keep this 1:1 so that we don't interfere
diff --git a/include/asm-arm/arch-ebsa285/memory.h b/include/asm-arm/arch-ebsa285/memory.h
index d0466f9987d3..09e335cd687d 100644
--- a/include/asm-arm/arch-ebsa285/memory.h
+++ b/include/asm-arm/arch-ebsa285/memory.h
@@ -46,14 +46,14 @@ extern unsigned long __bus_to_virt(unsigned long);
#if defined(CONFIG_ARCH_FOOTBRIDGE)
/* Task size and page offset at 3GB */
-#define TASK_SIZE (0xbf000000UL)
-#define PAGE_OFFSET (0xc0000000UL)
+#define TASK_SIZE UL(0xbf000000)
+#define PAGE_OFFSET UL(0xc0000000)
#elif defined(CONFIG_ARCH_CO285)
/* Task size and page offset at 1.5GB */
-#define TASK_SIZE (0x5f000000UL)
-#define PAGE_OFFSET (0x60000000UL)
+#define TASK_SIZE UL(0x5f000000)
+#define PAGE_OFFSET UL(0x60000000)
#else
@@ -64,7 +64,7 @@ extern unsigned long __bus_to_virt(unsigned long);
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET (0x00000000UL)
+#define PHYS_OFFSET UL(0x00000000)
/*
* This decides where the kernel will search for a free chunk of vm
diff --git a/include/asm-arm/arch-epxa10db/memory.h b/include/asm-arm/arch-epxa10db/memory.h
index 3f86bf7f67f0..999541b6a9f5 100644
--- a/include/asm-arm/arch-epxa10db/memory.h
+++ b/include/asm-arm/arch-epxa10db/memory.h
@@ -23,7 +23,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET (0x00000000UL)
+#define PHYS_OFFSET UL(0x00000000)
/*
* Virtual view <-> DMA view memory address translations
diff --git a/include/asm-arm/arch-h720x/memory.h b/include/asm-arm/arch-h720x/memory.h
index 5633447af268..4a1bfd78a0fe 100644
--- a/include/asm-arm/arch-h720x/memory.h
+++ b/include/asm-arm/arch-h720x/memory.h
@@ -11,7 +11,7 @@
* Page offset:
* ( 0xc0000000UL )
*/
-#define PHYS_OFFSET (0x40000000UL)
+#define PHYS_OFFSET UL(0x40000000)
/*
* Virtual view <-> DMA view memory address translations
diff --git a/include/asm-arm/arch-imx/memory.h b/include/asm-arm/arch-imx/memory.h
index 116a91fa14f1..d09ae32cd2f4 100644
--- a/include/asm-arm/arch-imx/memory.h
+++ b/include/asm-arm/arch-imx/memory.h
@@ -21,7 +21,7 @@
#ifndef __ASM_ARCH_MMU_H
#define __ASM_ARCH_MMU_H
-#define PHYS_OFFSET (0x08000000UL)
+#define PHYS_OFFSET UL(0x08000000)
/*
* Virtual view <-> DMA view memory address translations
diff --git a/include/asm-arm/arch-integrator/memory.h b/include/asm-arm/arch-integrator/memory.h
index 2087ea7d28a9..1ab56d783e7c 100644
--- a/include/asm-arm/arch-integrator/memory.h
+++ b/include/asm-arm/arch-integrator/memory.h
@@ -23,8 +23,8 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET (0x00000000UL)
-#define BUS_OFFSET (0x80000000UL)
+#define PHYS_OFFSET UL(0x00000000)
+#define BUS_OFFSET UL(0x80000000)
/*
* Virtual view <-> DMA view memory address translations
diff --git a/include/asm-arm/arch-iop3xx/memory.h b/include/asm-arm/arch-iop3xx/memory.h
index 45351f5cd904..bc62f4b13235 100644
--- a/include/asm-arm/arch-iop3xx/memory.h
+++ b/include/asm-arm/arch-iop3xx/memory.h
@@ -12,9 +12,9 @@
* Physical DRAM offset.
*/
#ifndef CONFIG_ARCH_IOP331
-#define PHYS_OFFSET (0xa0000000UL)
+#define PHYS_OFFSET UL(0xa0000000)
#else
-#define PHYS_OFFSET (0x00000000UL)
+#define PHYS_OFFSET UL(0x00000000)
#endif
/*
diff --git a/include/asm-arm/arch-ixp2000/ixdp2x01.h b/include/asm-arm/arch-ixp2000/ixdp2x01.h
index b768009c3a51..c6d51426e98f 100644
--- a/include/asm-arm/arch-ixp2000/ixdp2x01.h
+++ b/include/asm-arm/arch-ixp2000/ixdp2x01.h
@@ -22,7 +22,7 @@
#define IXDP2X01_CPLD_REGION_SIZE 0x00100000
#define IXDP2X01_CPLD_VIRT_REG(reg) (volatile unsigned long*)(IXDP2X01_VIRT_CPLD_BASE | reg)
-#define IXDP2X01_CPLD_PHYS_REG(reg) (volatile u32*)(IXDP2X01_PHYS_CPLD_BASE | reg)
+#define IXDP2X01_CPLD_PHYS_REG(reg) (IXDP2X01_PHYS_CPLD_BASE | reg)
#define IXDP2X01_UART1_VIRT_BASE IXDP2X01_CPLD_VIRT_REG(0x40)
#define IXDP2X01_UART1_PHYS_BASE IXDP2X01_CPLD_PHYS_REG(0x40)
diff --git a/include/asm-arm/arch-ixp2000/memory.h b/include/asm-arm/arch-ixp2000/memory.h
index d0f415c6dae9..21e1de51e3f6 100644
--- a/include/asm-arm/arch-ixp2000/memory.h
+++ b/include/asm-arm/arch-ixp2000/memory.h
@@ -13,7 +13,7 @@
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
-#define PHYS_OFFSET (0x00000000UL)
+#define PHYS_OFFSET UL(0x00000000)
/*
* Virtual view <-> DMA view memory address translations
diff --git a/include/asm-arm/arch-ixp2000/platform.h b/include/asm-arm/arch-ixp2000/platform.h
index abdcf51bd283..a66317ab2071 100644
--- a/include/asm-arm/arch-ixp2000/platform.h
+++ b/include/asm-arm/arch-ixp2000/platform.h
@@ -15,40 +15,40 @@
#ifndef __ASSEMBLY__
+static inline unsigned long ixp2000_reg_read(volatile void *reg)
+{
+ return *((volatile unsigned long *)reg);
+}
+
+static inline void ixp2000_reg_write(volatile void *reg, unsigned long val)
+{
+ *((volatile unsigned long *)reg) = val;
+}
+
/*
- * The IXP2400 B0 silicon contains an erratum (#66) that causes writes
- * to on-chip I/O register to not complete fully. What this means is
- * that if you have a write to on-chip I/O followed by a back-to-back
- * read or write, the first write will happen twice. OR...if it's
- * not a back-to-back transaction, the read or write will generate
- * incorrect data.
- *
- * The official work around for this is to set the on-chip I/O regions
- * as XCB=101 and then force a read-back from the register.
+ * On the IXP2400, we can't use XCB=000 due to chip bugs. We use
+ * XCB=101 instead, but that makes all I/O accesses bufferable. This
+ * is not a problem in general, but we do have to be slightly more
+ * careful because I/O writes are no longer automatically flushed out
+ * of the write buffer.
*
+ * In cases where we want to make sure that a write has been flushed
+ * out of the write buffer before we proceed, for example when masking
+ * a device interrupt before re-enabling IRQs in CPSR, we can use this
+ * function, ixp2000_reg_wrb, which performs a write, a readback, and
+ * issues a dummy instruction dependent on the value of the readback
+ * (mov rX, rX) to make sure that the readback has completed before we
+ * continue.
*/
-#if defined(CONFIG_ARCH_ENP2611) || defined(CONFIG_ARCH_IXDP2400) || defined(CONFIG_ARCH_IXDP2401)
-
-#include <asm/system.h> /* Pickup local_irq_ functions */
-
-static inline void ixp2000_reg_write(volatile void *reg, unsigned long val)
+static inline void ixp2000_reg_wrb(volatile void *reg, unsigned long val)
{
unsigned long dummy;
- unsigned long flags;
- local_irq_save(flags);
*((volatile unsigned long *)reg) = val;
- barrier();
+
dummy = *((volatile unsigned long *)reg);
- local_irq_restore(flags);
-}
-#else
-static inline void ixp2000_reg_write(volatile void *reg, unsigned long val)
-{
- *((volatile unsigned long *)reg) = val;
+ __asm__ __volatile__("mov %0, %0" : "+r" (dummy));
}
-#endif /* IXDP2400 || IXDP2401 */
-#define ixp2000_reg_read(reg) (*((volatile unsigned long *)reg))
/*
* Boards may multiplex different devices on the 2nd channel of
diff --git a/include/asm-arm/arch-ixp4xx/io.h b/include/asm-arm/arch-ixp4xx/io.h
index e350dcb544e8..80d05ecad2f0 100644
--- a/include/asm-arm/arch-ixp4xx/io.h
+++ b/include/asm-arm/arch-ixp4xx/io.h
@@ -113,7 +113,7 @@ __ixp4xx_writeb(u8 value, u32 addr)
}
static inline void
-__ixp4xx_writesb(u32 bus_addr, u8 *vaddr, int count)
+__ixp4xx_writesb(u32 bus_addr, const u8 *vaddr, int count)
{
while (count--)
writeb(*vaddr++, bus_addr);
@@ -136,7 +136,7 @@ __ixp4xx_writew(u16 value, u32 addr)
}
static inline void
-__ixp4xx_writesw(u32 bus_addr, u16 *vaddr, int count)
+__ixp4xx_writesw(u32 bus_addr, const u16 *vaddr, int count)
{
while (count--)
writew(*vaddr++, bus_addr);
@@ -154,7 +154,7 @@ __ixp4xx_writel(u32 value, u32 addr)
}
static inline void
-__ixp4xx_writesl(u32 bus_addr, u32 *vaddr, int count)
+__ixp4xx_writesl(u32 bus_addr, const u32 *vaddr, int count)
{
while (count--)
writel(*vaddr++, bus_addr);
diff --git a/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h b/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h
index 004696a95bdb..2b149ed59149 100644
--- a/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h
+++ b/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h
@@ -36,11 +36,11 @@
*
* 0x6000000 0x00004000 ioremap'd QMgr
*
- * 0xC0000000 0x00001000 0xffbfe000 PCI CFG
+ * 0xC0000000 0x00001000 0xffbff000 PCI CFG
*
- * 0xC4000000 0x00001000 0xffbfd000 EXP CFG
+ * 0xC4000000 0x00001000 0xffbfe000 EXP CFG
*
- * 0xC8000000 0x0000C000 0xffbf2000 On-Chip Peripherals
+ * 0xC8000000 0x00013000 0xffbeb000 On-Chip Peripherals
*/
/*
@@ -52,22 +52,22 @@
* Expansion BUS Configuration registers
*/
#define IXP4XX_EXP_CFG_BASE_PHYS (0xC4000000)
-#define IXP4XX_EXP_CFG_BASE_VIRT (0xFFBFD000)
+#define IXP4XX_EXP_CFG_BASE_VIRT (0xFFBFE000)
#define IXP4XX_EXP_CFG_REGION_SIZE (0x00001000)
/*
* PCI Config registers
*/
#define IXP4XX_PCI_CFG_BASE_PHYS (0xC0000000)
-#define IXP4XX_PCI_CFG_BASE_VIRT (0xFFBFE000)
+#define IXP4XX_PCI_CFG_BASE_VIRT (0xFFBFF000)
#define IXP4XX_PCI_CFG_REGION_SIZE (0x00001000)
/*
* Peripheral space
*/
#define IXP4XX_PERIPHERAL_BASE_PHYS (0xC8000000)
-#define IXP4XX_PERIPHERAL_BASE_VIRT (0xFFBF2000)
-#define IXP4XX_PERIPHERAL_REGION_SIZE (0x0000C000)
+#define IXP4XX_PERIPHERAL_BASE_VIRT (0xFFBEB000)
+#define IXP4XX_PERIPHERAL_REGION_SIZE (0x00013000)
/*
* Debug UART
@@ -115,25 +115,48 @@
/*
* Peripheral Space Register Region Base Addresses
*/
-#define IXP4XX_UART1_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x0000)
-#define IXP4XX_UART2_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x1000)
-#define IXP4XX_PMU_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x2000)
-#define IXP4XX_INTC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x3000)
-#define IXP4XX_GPIO_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x4000)
-#define IXP4XX_TIMER_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x5000)
-#define IXP4XX_EthA_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x9000)
-#define IXP4XX_EthB_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xA000)
-#define IXP4XX_USB_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xB000)
-
-#define IXP4XX_UART1_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x0000)
-#define IXP4XX_UART2_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x1000)
-#define IXP4XX_PMU_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x2000)
-#define IXP4XX_INTC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x3000)
-#define IXP4XX_GPIO_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x4000)
-#define IXP4XX_TIMER_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x5000)
-#define IXP4XX_EthA_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x9000)
-#define IXP4XX_EthB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xA000)
-#define IXP4XX_USB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xB000)
+#define IXP4XX_UART1_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x0000)
+#define IXP4XX_UART2_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x1000)
+#define IXP4XX_PMU_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x2000)
+#define IXP4XX_INTC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x3000)
+#define IXP4XX_GPIO_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x4000)
+#define IXP4XX_TIMER_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x5000)
+#define IXP4XX_NPEA_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x6000)
+#define IXP4XX_NPEB_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x7000)
+#define IXP4XX_NPEC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x8000)
+#define IXP4XX_EthB_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x9000)
+#define IXP4XX_EthC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xA000)
+#define IXP4XX_USB_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xB000)
+/* ixp46X only */
+#define IXP4XX_EthA_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xC000)
+#define IXP4XX_EthB1_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xD000)
+#define IXP4XX_EthB2_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xE000)
+#define IXP4XX_EthB3_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xF000)
+#define IXP4XX_TIMESYNC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x10000)
+#define IXP4XX_I2C_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x11000)
+#define IXP4XX_SSP_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x12000)
+
+
+#define IXP4XX_UART1_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x0000)
+#define IXP4XX_UART2_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x1000)
+#define IXP4XX_PMU_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x2000)
+#define IXP4XX_INTC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x3000)
+#define IXP4XX_GPIO_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x4000)
+#define IXP4XX_TIMER_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x5000)
+#define IXP4XX_NPEA_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_PHYS + 0x6000)
+#define IXP4XX_NPEB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_PHYS + 0x7000)
+#define IXP4XX_NPEC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_PHYS + 0x8000)
+#define IXP4XX_EthB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x9000)
+#define IXP4XX_EthC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xA000)
+#define IXP4XX_USB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xB000)
+/* ixp46X only */
+#define IXP4XX_EthA_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xC000)
+#define IXP4XX_EthB1_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xD000)
+#define IXP4XX_EthB2_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xE000)
+#define IXP4XX_EthB3_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xF000)
+#define IXP4XX_TIMESYNC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x10000)
+#define IXP4XX_I2C_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x11000)
+#define IXP4XX_SSP_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x12000)
/*
* Constants to make it easy to access Interrupt Controller registers
diff --git a/include/asm-arm/arch-ixp4xx/memory.h b/include/asm-arm/arch-ixp4xx/memory.h
index d348548b592b..e024d0a1a669 100644
--- a/include/asm-arm/arch-ixp4xx/memory.h
+++ b/include/asm-arm/arch-ixp4xx/memory.h
@@ -12,7 +12,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET (0x00000000UL)
+#define PHYS_OFFSET UL(0x00000000)
#ifndef __ASSEMBLY__
diff --git a/include/asm-arm/arch-l7200/memory.h b/include/asm-arm/arch-l7200/memory.h
index c5b9608cb137..9e50a171f78a 100644
--- a/include/asm-arm/arch-l7200/memory.h
+++ b/include/asm-arm/arch-l7200/memory.h
@@ -15,7 +15,7 @@
/*
* Physical DRAM offset on the L7200 SDB.
*/
-#define PHYS_OFFSET (0xf0000000UL)
+#define PHYS_OFFSET UL(0xf0000000)
#define __virt_to_bus(x) __virt_to_phys(x)
#define __bus_to_virt(x) __phys_to_virt(x)
diff --git a/include/asm-arm/arch-lh7a40x/memory.h b/include/asm-arm/arch-lh7a40x/memory.h
index c650e6feb9d5..c92bcb837629 100644
--- a/include/asm-arm/arch-lh7a40x/memory.h
+++ b/include/asm-arm/arch-lh7a40x/memory.h
@@ -17,7 +17,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET (0xc0000000UL)
+#define PHYS_OFFSET UL(0xc0000000)
/*
* Virtual view <-> DMA view memory address translations
diff --git a/include/asm-arm/arch-omap/memory.h b/include/asm-arm/arch-omap/memory.h
index ef32d61eec7a..bf545b6e0a26 100644
--- a/include/asm-arm/arch-omap/memory.h
+++ b/include/asm-arm/arch-omap/memory.h
@@ -37,9 +37,9 @@
* Physical DRAM offset.
*/
#if defined(CONFIG_ARCH_OMAP1)
-#define PHYS_OFFSET (0x10000000UL)
+#define PHYS_OFFSET UL(0x10000000)
#elif defined(CONFIG_ARCH_OMAP2)
-#define PHYS_OFFSET (0x80000000UL)
+#define PHYS_OFFSET UL(0x80000000)
#endif
/*
@@ -66,7 +66,7 @@
/*
* OMAP-1510 Local Bus address offset
*/
-#define OMAP1510_LB_OFFSET (0x30000000UL)
+#define OMAP1510_LB_OFFSET UL(0x30000000)
#define virt_to_lbus(x) ((x) - PAGE_OFFSET + OMAP1510_LB_OFFSET)
#define lbus_to_virt(x) ((x) - OMAP1510_LB_OFFSET + PAGE_OFFSET)
diff --git a/include/asm-arm/arch-pxa/memory.h b/include/asm-arm/arch-pxa/memory.h
index 58bad9748b5c..eaf6d43939e9 100644
--- a/include/asm-arm/arch-pxa/memory.h
+++ b/include/asm-arm/arch-pxa/memory.h
@@ -15,7 +15,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET (0xa0000000UL)
+#define PHYS_OFFSET UL(0xa0000000)
/*
* Virtual view <-> DMA view memory address translations
diff --git a/include/asm-arm/arch-rpc/memory.h b/include/asm-arm/arch-rpc/memory.h
index 33fc75cdead0..0592cb3f0c74 100644
--- a/include/asm-arm/arch-rpc/memory.h
+++ b/include/asm-arm/arch-rpc/memory.h
@@ -21,7 +21,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET (0x10000000UL)
+#define PHYS_OFFSET UL(0x10000000)
/*
* These are exactly the same on the RiscPC as the
diff --git a/include/asm-arm/arch-s3c2410/memory.h b/include/asm-arm/arch-s3c2410/memory.h
index 3380ab1d0749..6ab834a14c8e 100644
--- a/include/asm-arm/arch-s3c2410/memory.h
+++ b/include/asm-arm/arch-s3c2410/memory.h
@@ -28,9 +28,9 @@
* and at 0x0C000000 for S3C2400
*/
#ifdef CONFIG_CPU_S3C2400
-#define PHYS_OFFSET (0x0C000000UL)
+#define PHYS_OFFSET UL(0x0C000000)
#else
-#define PHYS_OFFSET (0x30000000UL)
+#define PHYS_OFFSET UL(0x30000000)
#endif
/*
diff --git a/include/asm-arm/arch-sa1100/memory.h b/include/asm-arm/arch-sa1100/memory.h
index 8743ff5c1b23..0fc555b4c912 100644
--- a/include/asm-arm/arch-sa1100/memory.h
+++ b/include/asm-arm/arch-sa1100/memory.h
@@ -13,7 +13,7 @@
/*
* Physical DRAM offset is 0xc0000000 on the SA1100
*/
-#define PHYS_OFFSET (0xc0000000UL)
+#define PHYS_OFFSET UL(0xc0000000)
#ifndef __ASSEMBLY__
diff --git a/include/asm-arm/arch-shark/memory.h b/include/asm-arm/arch-shark/memory.h
index 8ff956d25463..95a29b4bc5d0 100644
--- a/include/asm-arm/arch-shark/memory.h
+++ b/include/asm-arm/arch-shark/memory.h
@@ -15,7 +15,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET (0x08000000UL)
+#define PHYS_OFFSET UL(0x08000000)
#ifndef __ASSEMBLY__
diff --git a/include/asm-arm/arch-versatile/memory.h b/include/asm-arm/arch-versatile/memory.h
index 7b8b7cc422fa..a9370976cc5e 100644
--- a/include/asm-arm/arch-versatile/memory.h
+++ b/include/asm-arm/arch-versatile/memory.h
@@ -23,7 +23,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET (0x00000000UL)
+#define PHYS_OFFSET UL(0x00000000)
/*
* Virtual view <-> DMA view memory address translations
diff --git a/include/asm-arm/mach/arch.h b/include/asm-arm/mach/arch.h
index 7273c6fd95b5..eb262e078c46 100644
--- a/include/asm-arm/mach/arch.h
+++ b/include/asm-arm/mach/arch.h
@@ -50,6 +50,7 @@ struct machine_desc {
*/
#define MACHINE_START(_type,_name) \
static const struct machine_desc __mach_desc_##_type \
+ __attribute_used__ \
__attribute__((__section__(".arch.info.init"))) = { \
.nr = MACH_TYPE_##_type, \
.name = _name,
diff --git a/include/asm-arm/mach/flash.h b/include/asm-arm/mach/flash.h
index a92887d4b2cb..cd57436d9874 100644
--- a/include/asm-arm/mach/flash.h
+++ b/include/asm-arm/mach/flash.h
@@ -14,6 +14,7 @@ struct mtd_partition;
/*
* map_name: the map probe function name
+ * name: flash device name (eg, as used with mtdparts=)
* width: width of mapped device
* init: method called at driver/device initialisation
* exit: method called at driver/device removal
@@ -23,6 +24,7 @@ struct mtd_partition;
*/
struct flash_platform_data {
const char *map_name;
+ const char *name;
unsigned int width;
int (*init)(void);
void (*exit)(void);
diff --git a/include/asm-arm/mach/map.h b/include/asm-arm/mach/map.h
index 0619522bd926..b338936bde4f 100644
--- a/include/asm-arm/mach/map.h
+++ b/include/asm-arm/mach/map.h
@@ -27,8 +27,8 @@ struct meminfo;
#define MT_ROM 6
#define MT_IXP2000_DEVICE 7
-#define __phys_to_pfn(paddr) (paddr >> PAGE_SHIFT)
-#define __pfn_to_phys(pfn) (pfn << PAGE_SHIFT)
+#define __phys_to_pfn(paddr) ((paddr) >> PAGE_SHIFT)
+#define __pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT)
extern void create_memmap_holes(struct meminfo *);
extern void memtable_init(struct meminfo *);
diff --git a/include/asm-arm/memory.h b/include/asm-arm/memory.h
index a8a933a775db..a547ee598c6c 100644
--- a/include/asm-arm/memory.h
+++ b/include/asm-arm/memory.h
@@ -12,6 +12,16 @@
#ifndef __ASM_ARM_MEMORY_H
#define __ASM_ARM_MEMORY_H
+/*
+ * Allow for constants defined here to be used from assembly code
+ * by prepending the UL suffix only with actual C code compilation.
+ */
+#ifndef __ASSEMBLY__
+#define UL(x) (x##UL)
+#else
+#define UL(x) (x)
+#endif
+
#include <linux/config.h>
#include <linux/compiler.h>
#include <asm/arch/memory.h>
@@ -21,20 +31,20 @@
* TASK_SIZE - the maximum size of a user space task.
* TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area
*/
-#define TASK_SIZE (0xbf000000UL)
-#define TASK_UNMAPPED_BASE (0x40000000UL)
+#define TASK_SIZE UL(0xbf000000)
+#define TASK_UNMAPPED_BASE UL(0x40000000)
#endif
/*
* The maximum size of a 26-bit user space task.
*/
-#define TASK_SIZE_26 (0x04000000UL)
+#define TASK_SIZE_26 UL(0x04000000)
/*
* Page offset: 3GB
*/
#ifndef PAGE_OFFSET
-#define PAGE_OFFSET (0xc0000000UL)
+#define PAGE_OFFSET UL(0xc0000000)
#endif
/*
@@ -58,6 +68,13 @@
#error Top of user space clashes with start of module space
#endif
+/*
+ * The XIP kernel gets mapped at the bottom of the module vm area.
+ * Since we use sections to map it, this macro replaces the physical address
+ * with its virtual address while keeping offset from the base section.
+ */
+#define XIP_VIRT_ADDR(physaddr) (MODULE_START + ((physaddr) & 0x000fffff))
+
#ifndef __ASSEMBLY__
/*
diff --git a/include/asm-arm/pgtable.h b/include/asm-arm/pgtable.h
index 366bafbdfbb1..5a0d19b466b0 100644
--- a/include/asm-arm/pgtable.h
+++ b/include/asm-arm/pgtable.h
@@ -397,9 +397,6 @@ static inline pte_t *pmd_page_kernel(pmd_t pmd)
#define pgd_clear(pgdp) do { } while (0)
#define set_pgd(pgd,pgdp) do { } while (0)
-#define page_pte_prot(page,prot) mk_pte(page, prot)
-#define page_pte(page) mk_pte(page, __pgprot(0))
-
/* to find an entry in a page-table-directory */
#define pgd_index(addr) ((addr) >> PGDIR_SHIFT)
diff --git a/include/asm-arm/semaphore.h b/include/asm-arm/semaphore.h
index 60f33e6eb800..71ca7d412687 100644
--- a/include/asm-arm/semaphore.h
+++ b/include/asm-arm/semaphore.h
@@ -24,8 +24,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \
}
-#define __MUTEX_INITIALIZER(name) __SEMAPHORE_INIT(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INIT(name,count)
diff --git a/include/asm-arm/tlb.h b/include/asm-arm/tlb.h
index 9bb325c54645..f49bfb78c221 100644
--- a/include/asm-arm/tlb.h
+++ b/include/asm-arm/tlb.h
@@ -27,11 +27,7 @@
*/
struct mmu_gather {
struct mm_struct *mm;
- unsigned int freed;
unsigned int fullmm;
-
- unsigned int flushes;
- unsigned int avoided_flushes;
};
DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
@@ -39,11 +35,9 @@ DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
static inline struct mmu_gather *
tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
{
- int cpu = smp_processor_id();
- struct mmu_gather *tlb = &per_cpu(mmu_gathers, cpu);
+ struct mmu_gather *tlb = &get_cpu_var(mmu_gathers);
tlb->mm = mm;
- tlb->freed = 0;
tlb->fullmm = full_mm_flush;
return tlb;
@@ -52,24 +46,13 @@ tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
static inline void
tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
{
- struct mm_struct *mm = tlb->mm;
- unsigned long freed = tlb->freed;
- int rss = get_mm_counter(mm, rss);
-
- if (rss < freed)
- freed = rss;
- add_mm_counter(mm, rss, -freed);
-
if (tlb->fullmm)
- flush_tlb_mm(mm);
+ flush_tlb_mm(tlb->mm);
/* keep the page table cache within bounds */
check_pgt_cache();
-}
-static inline unsigned int tlb_is_full_mm(struct mmu_gather *tlb)
-{
- return tlb->fullmm;
+ put_cpu_var(mmu_gathers);
}
#define tlb_remove_tlb_entry(tlb,ptep,address) do { } while (0)
diff --git a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h
index c49df635a80f..d626e70faded 100644
--- a/include/asm-arm/unistd.h
+++ b/include/asm-arm/unistd.h
@@ -544,7 +544,6 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
asmlinkage int sys_fork(struct pt_regs *regs);
asmlinkage int sys_vfork(struct pt_regs *regs);
asmlinkage int sys_pipe(unsigned long *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
diff --git a/include/asm-arm26/pgtable.h b/include/asm-arm26/pgtable.h
index f602cf572411..a590250277f8 100644
--- a/include/asm-arm26/pgtable.h
+++ b/include/asm-arm26/pgtable.h
@@ -98,8 +98,6 @@ extern struct page *empty_zero_page;
#define pfn_pte(pfn,prot) (__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)))
#define pages_to_mb(x) ((x) >> (20 - PAGE_SHIFT))
#define mk_pte(page,prot) pfn_pte(page_to_pfn(page),prot)
-#define page_pte_prot(page,prot) mk_pte(page, prot)
-#define page_pte(page) mk_pte(page, __pgprot(0))
/*
* Terminology: PGD = Page Directory, PMD = Page Middle Directory,
diff --git a/include/asm-arm26/semaphore.h b/include/asm-arm26/semaphore.h
index c1b6a1edad92..ccf15e704109 100644
--- a/include/asm-arm26/semaphore.h
+++ b/include/asm-arm26/semaphore.h
@@ -25,9 +25,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INIT(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INIT(name,count)
diff --git a/include/asm-arm26/tlb.h b/include/asm-arm26/tlb.h
index 1316352a58f3..08ddd85b8d35 100644
--- a/include/asm-arm26/tlb.h
+++ b/include/asm-arm26/tlb.h
@@ -10,24 +10,20 @@
*/
struct mmu_gather {
struct mm_struct *mm;
- unsigned int freed;
- unsigned int fullmm;
-
- unsigned int flushes;
- unsigned int avoided_flushes;
+ unsigned int need_flush;
+ unsigned int fullmm;
};
-extern struct mmu_gather mmu_gathers[NR_CPUS];
+DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
static inline struct mmu_gather *
tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
{
- int cpu = smp_processor_id();
- struct mmu_gather *tlb = &mmu_gathers[cpu];
+ struct mmu_gather *tlb = &get_cpu_var(mmu_gathers);
tlb->mm = mm;
- tlb->freed = 0;
- tlb->fullmm = full_mm_flush;
+ tlb->need_flush = 0;
+ tlb->fullmm = full_mm_flush;
return tlb;
}
@@ -35,30 +31,13 @@ tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
static inline void
tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
{
- struct mm_struct *mm = tlb->mm;
- unsigned long freed = tlb->freed;
- int rss = get_mm_counter(mm, rss);
-
- if (rss < freed)
- freed = rss;
- add_mm_counter(mm, rss, -freed);
-
- if (freed) {
- flush_tlb_mm(mm);
- tlb->flushes++;
- } else {
- tlb->avoided_flushes++;
- }
+ if (tlb->need_flush)
+ flush_tlb_mm(tlb->mm);
/* keep the page table cache within bounds */
check_pgt_cache();
-}
-
-static inline unsigned int
-tlb_is_full_mm(struct mmu_gather *tlb)
-{
- return tlb->fullmm;
+ put_cpu_var(mmu_gathers);
}
#define tlb_remove_tlb_entry(tlb,ptep,address) do { } while (0)
@@ -71,7 +50,13 @@ tlb_is_full_mm(struct mmu_gather *tlb)
} while (0)
#define tlb_end_vma(tlb,vma) do { } while (0)
-#define tlb_remove_page(tlb,page) free_page_and_swap_cache(page)
+static inline void
+tlb_remove_page(struct mmu_gather *tlb, struct page *page)
+{
+ tlb->need_flush = 1;
+ free_page_and_swap_cache(page);
+}
+
#define pte_free_tlb(tlb,ptep) pte_free(ptep)
#define pmd_free_tlb(tlb,pmdp) pmd_free(pmdp)
diff --git a/include/asm-arm26/unistd.h b/include/asm-arm26/unistd.h
index dfa0b0c30aa3..be4c2fb9c049 100644
--- a/include/asm-arm26/unistd.h
+++ b/include/asm-arm26/unistd.h
@@ -480,7 +480,6 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
asmlinkage int sys_fork(struct pt_regs *regs);
asmlinkage int sys_vfork(struct pt_regs *regs);
asmlinkage int sys_pipe(unsigned long *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
diff --git a/include/asm-cris/semaphore.h b/include/asm-cris/semaphore.h
index 8ed7636ab311..39faf69bcf76 100644
--- a/include/asm-cris/semaphore.h
+++ b/include/asm-cris/semaphore.h
@@ -33,9 +33,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/asm-cris/unistd.h b/include/asm-cris/unistd.h
index 28232ad2ff34..156a34bfc583 100644
--- a/include/asm-cris/unistd.h
+++ b/include/asm-cris/unistd.h
@@ -367,7 +367,6 @@ asmlinkage int sys_fork(long r10, long r11, long r12, long r13,
asmlinkage int sys_vfork(long r10, long r11, long r12, long r13,
long mof, long srp, struct pt_regs *regs);
asmlinkage int sys_pipe(unsigned long __user *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
diff --git a/include/asm-frv/pgtable.h b/include/asm-frv/pgtable.h
index 473fb4bb6329..b247e99dff49 100644
--- a/include/asm-frv/pgtable.h
+++ b/include/asm-frv/pgtable.h
@@ -436,8 +436,6 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
return pte;
}
-#define page_pte(page) page_pte_prot((page), __pgprot(0))
-
/* to find an entry in a page-table-directory. */
#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
#define pgd_index_k(addr) pgd_index(addr)
diff --git a/include/asm-frv/semaphore.h b/include/asm-frv/semaphore.h
index 393545630806..b18396288df1 100644
--- a/include/asm-frv/semaphore.h
+++ b/include/asm-frv/semaphore.h
@@ -47,9 +47,6 @@ struct semaphore {
#define __SEMAPHORE_INITIALIZER(name,count) \
{ count, SPIN_LOCK_UNLOCKED, LIST_HEAD_INIT((name).wait_list) __SEM_DEBUG_INIT(name) }
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/asm-generic/4level-fixup.h b/include/asm-generic/4level-fixup.h
index c20ec257ecc0..68c6fea994d9 100644
--- a/include/asm-generic/4level-fixup.h
+++ b/include/asm-generic/4level-fixup.h
@@ -10,14 +10,9 @@
#define pud_t pgd_t
-#define pmd_alloc(mm, pud, address) \
-({ pmd_t *ret; \
- if (pgd_none(*pud)) \
- ret = __pmd_alloc(mm, pud, address); \
- else \
- ret = pmd_offset(pud, address); \
- ret; \
-})
+#define pmd_alloc(mm, pud, address) \
+ ((unlikely(pgd_none(*(pud))) && __pmd_alloc(mm, pud, address))? \
+ NULL: pmd_offset(pud, address))
#define pud_alloc(mm, pgd, address) (pgd)
#define pud_offset(pgd, start) (pgd)
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index ff28c8b31f58..7dca30a26c53 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -8,7 +8,7 @@
* - update the page tables
* - inform the TLB about the new one
*
- * We hold the mm semaphore for reading and vma->vm_mm->page_table_lock.
+ * We hold the mm semaphore for reading, and the pte lock.
*
* Note: the old pte is known to not be writable, so we don't need to
* worry about dirty bits etc getting lost.
diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
index 7d0298347ee7..cdd4145243cd 100644
--- a/include/asm-generic/tlb.h
+++ b/include/asm-generic/tlb.h
@@ -35,16 +35,13 @@
#endif
/* struct mmu_gather is an opaque type used by the mm code for passing around
- * any data needed by arch specific code for tlb_remove_page. This structure
- * can be per-CPU or per-MM as the page table lock is held for the duration of
- * TLB shootdown.
+ * any data needed by arch specific code for tlb_remove_page.
*/
struct mmu_gather {
struct mm_struct *mm;
unsigned int nr; /* set to ~0U means fast mode */
unsigned int need_flush;/* Really unmapped some ptes? */
unsigned int fullmm; /* non-zero means full mm flush */
- unsigned long freed;
struct page * pages[FREE_PTE_NR];
};
@@ -57,7 +54,7 @@ DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
static inline struct mmu_gather *
tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
{
- struct mmu_gather *tlb = &per_cpu(mmu_gathers, smp_processor_id());
+ struct mmu_gather *tlb = &get_cpu_var(mmu_gathers);
tlb->mm = mm;
@@ -65,7 +62,6 @@ tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
tlb->nr = num_online_cpus() > 1 ? 0U : ~0U;
tlb->fullmm = full_mm_flush;
- tlb->freed = 0;
return tlb;
}
@@ -85,28 +81,17 @@ tlb_flush_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
/* tlb_finish_mmu
* Called at the end of the shootdown operation to free up any resources
- * that were required. The page table lock is still held at this point.
+ * that were required.
*/
static inline void
tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
{
- int freed = tlb->freed;
- struct mm_struct *mm = tlb->mm;
- int rss = get_mm_counter(mm, rss);
-
- if (rss < freed)
- freed = rss;
- add_mm_counter(mm, rss, -freed);
tlb_flush_mmu(tlb, start, end);
/* keep the page table cache within bounds */
check_pgt_cache();
-}
-static inline unsigned int
-tlb_is_full_mm(struct mmu_gather *tlb)
-{
- return tlb->fullmm;
+ put_cpu_var(mmu_gathers);
}
/* tlb_remove_page
diff --git a/include/asm-h8300/semaphore.h b/include/asm-h8300/semaphore.h
index fe6ef3774297..81bae2a99192 100644
--- a/include/asm-h8300/semaphore.h
+++ b/include/asm-h8300/semaphore.h
@@ -35,9 +35,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/asm-h8300/unistd.h b/include/asm-h8300/unistd.h
index 56a6401886fa..56a4a5686c88 100644
--- a/include/asm-h8300/unistd.h
+++ b/include/asm-h8300/unistd.h
@@ -528,7 +528,6 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
asmlinkage int sys_execve(char *name, char **argv, char **envp,
int dummy, ...);
asmlinkage int sys_pipe(unsigned long *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
diff --git a/include/asm-i386/apic.h b/include/asm-i386/apic.h
index 8c454aa58ac6..a515e2aed829 100644
--- a/include/asm-i386/apic.h
+++ b/include/asm-i386/apic.h
@@ -118,7 +118,8 @@ extern void release_lapic_nmi(void);
extern void disable_timer_nmi_watchdog(void);
extern void enable_timer_nmi_watchdog(void);
extern void nmi_watchdog_tick (struct pt_regs * regs);
-extern int APIC_init_uniprocessor (void);
+extern int APIC_init(void);
+extern void APIC_late_time_init(void);
extern void disable_APIC_timer(void);
extern void enable_APIC_timer(void);
diff --git a/include/asm-i386/desc.h b/include/asm-i386/desc.h
index 6df1a53c190e..29b851a18c6e 100644
--- a/include/asm-i386/desc.h
+++ b/include/asm-i386/desc.h
@@ -17,6 +17,8 @@
extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
DECLARE_PER_CPU(struct desc_struct, cpu_gdt_table[GDT_ENTRIES]);
+#define get_cpu_gdt_table(_cpu) (per_cpu(cpu_gdt_table,_cpu))
+
DECLARE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
struct Xgt_desc_struct {
@@ -60,7 +62,7 @@ __asm__ __volatile__ ("movw %w3,0(%2)\n\t" \
static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, void *addr)
{
- _set_tssldt_desc(&per_cpu(cpu_gdt_table, cpu)[entry], (int)addr,
+ _set_tssldt_desc(&get_cpu_gdt_table(cpu)[entry], (int)addr,
offsetof(struct tss_struct, __cacheline_filler) - 1, 0x89);
}
@@ -68,7 +70,7 @@ static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, void *ad
static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int size)
{
- _set_tssldt_desc(&per_cpu(cpu_gdt_table, cpu)[GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
+ _set_tssldt_desc(&get_cpu_gdt_table(cpu)[GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
}
#define LDT_entry_a(info) \
@@ -109,7 +111,7 @@ static inline void write_ldt_entry(void *ldt, int entry, __u32 entry_a, __u32 en
static inline void load_TLS(struct thread_struct *t, unsigned int cpu)
{
-#define C(i) per_cpu(cpu_gdt_table, cpu)[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]
+#define C(i) get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]
C(0); C(1); C(2);
#undef C
}
diff --git a/include/asm-i386/hw_irq.h b/include/asm-i386/hw_irq.h
index 622815bf3243..9139b89497a1 100644
--- a/include/asm-i386/hw_irq.h
+++ b/include/asm-i386/hw_irq.h
@@ -55,6 +55,7 @@ void init_8259A(int aeoi);
void FASTCALL(send_IPI_self(int vector));
void init_VISWS_APIC_irqs(void);
void setup_IO_APIC(void);
+void IO_APIC_late_time_init(void);
void disable_IO_APIC(void);
void print_IO_APIC(void);
int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn);
diff --git a/include/asm-i386/mach-default/smpboot_hooks.h b/include/asm-i386/mach-default/smpboot_hooks.h
index 7f45f6311059..d7c70c144f9f 100644
--- a/include/asm-i386/mach-default/smpboot_hooks.h
+++ b/include/asm-i386/mach-default/smpboot_hooks.h
@@ -1,11 +1,6 @@
/* two abstractions specific to kernel/smpboot.c, mainly to cater to visws
* which needs to alter them. */
-static inline void smpboot_clear_io_apic_irqs(void)
-{
- io_apic_irqs = 0;
-}
-
static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
{
CMOS_WRITE(0xa, 0xf);
@@ -32,13 +27,3 @@ static inline void smpboot_restore_warm_reset_vector(void)
*((volatile long *) phys_to_virt(0x467)) = 0;
}
-
-static inline void smpboot_setup_io_apic(void)
-{
- /*
- * Here we can be sure that there is an IO-APIC in the system. Let's
- * go and set it up:
- */
- if (!skip_ioapic_setup && nr_ioapics)
- setup_IO_APIC();
-}
diff --git a/include/asm-i386/mach-es7000/mach_mpparse.h b/include/asm-i386/mach-es7000/mach_mpparse.h
index 28a84f6185a7..4a0637a3e208 100644
--- a/include/asm-i386/mach-es7000/mach_mpparse.h
+++ b/include/asm-i386/mach-es7000/mach_mpparse.h
@@ -16,7 +16,7 @@ static inline void mpc_oem_pci_bus(struct mpc_config_bus *m,
extern int parse_unisys_oem (char *oemptr);
extern int find_unisys_acpi_oem_table(unsigned long *oem_addr);
-extern void setup_unisys();
+extern void setup_unisys(void);
static inline int mps_oem_check(struct mp_config_table *mpc, char *oem,
char *productid)
diff --git a/include/asm-i386/mach-visws/smpboot_hooks.h b/include/asm-i386/mach-visws/smpboot_hooks.h
index d926471fa359..14d8e0375f7a 100644
--- a/include/asm-i386/mach-visws/smpboot_hooks.h
+++ b/include/asm-i386/mach-visws/smpboot_hooks.h
@@ -11,14 +11,7 @@ static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
/* for visws do nothing for any of these */
-static inline void smpboot_clear_io_apic_irqs(void)
-{
-}
-
static inline void smpboot_restore_warm_reset_vector(void)
{
}
-static inline void smpboot_setup_io_apic(void)
-{
-}
diff --git a/include/asm-i386/mmzone.h b/include/asm-i386/mmzone.h
index 348fe3a4879d..620a90641ea8 100644
--- a/include/asm-i386/mmzone.h
+++ b/include/asm-i386/mmzone.h
@@ -88,12 +88,6 @@ static inline int pfn_to_nid(unsigned long pfn)
__pgdat->node_start_pfn + __pgdat->node_spanned_pages; \
})
-#define local_mapnr(kvaddr) \
-({ \
- unsigned long __pfn = __pa(kvaddr) >> PAGE_SHIFT; \
- (__pfn - node_start_pfn(pfn_to_nid(__pfn))); \
-})
-
/* XXX: FIXME -- wli */
#define kern_addr_valid(kaddr) (0)
diff --git a/include/asm-i386/pgtable-2level.h b/include/asm-i386/pgtable-2level.h
index fa07bd6c7529..74ef721b534d 100644
--- a/include/asm-i386/pgtable-2level.h
+++ b/include/asm-i386/pgtable-2level.h
@@ -26,11 +26,6 @@
#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
#define pfn_pmd(pfn, prot) __pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
-#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
-
-#define pmd_page_kernel(pmd) \
-((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
-
/*
* All present user pages are user-executable:
*/
diff --git a/include/asm-i386/pgtable-3level.h b/include/asm-i386/pgtable-3level.h
index 2e3f4a344a2d..f1a8b454920a 100644
--- a/include/asm-i386/pgtable-3level.h
+++ b/include/asm-i386/pgtable-3level.h
@@ -74,11 +74,6 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
*/
static inline void pud_clear (pud_t * pud) { }
-#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
-
-#define pmd_page_kernel(pmd) \
-((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
-
#define pud_page(pud) \
((struct page *) __va(pud_val(pud) & PAGE_MASK))
diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h
index d101ac414f07..03f3c8ac6383 100644
--- a/include/asm-i386/pgtable.h
+++ b/include/asm-i386/pgtable.h
@@ -203,7 +203,8 @@ extern unsigned long pg0[];
#define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0)
-#define pmd_none(x) (!pmd_val(x))
+/* To avoid harmful races, pmd_none(x) should check only the lower when PAE */
+#define pmd_none(x) (!(unsigned long)pmd_val(x))
#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT)
#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0)
#define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
@@ -322,8 +323,6 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
return pte;
}
-#define page_pte(page) page_pte_prot(page, __pgprot(0))
-
#define pmd_large(pmd) \
((pmd_val(pmd) & (_PAGE_PSE|_PAGE_PRESENT)) == (_PAGE_PSE|_PAGE_PRESENT))
@@ -368,6 +367,11 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
#define pte_offset_kernel(dir, address) \
((pte_t *) pmd_page_kernel(*(dir)) + pte_index(address))
+#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
+
+#define pmd_page_kernel(pmd) \
+ ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
+
/*
* Helper function that returns the kernel pagetable entry controlling
* the virtual address 'address'. NULL means no pagetable entry present.
diff --git a/include/asm-i386/rwsem.h b/include/asm-i386/rwsem.h
index 7625a675852f..be4ab859238e 100644
--- a/include/asm-i386/rwsem.h
+++ b/include/asm-i386/rwsem.h
@@ -284,5 +284,10 @@ LOCK_PREFIX "xadd %0,(%2)"
return tmp+delta;
}
+static inline int rwsem_is_locked(struct rw_semaphore *sem)
+{
+ return (sem->count != 0);
+}
+
#endif /* __KERNEL__ */
#endif /* _I386_RWSEM_H */
diff --git a/include/asm-i386/semaphore.h b/include/asm-i386/semaphore.h
index ea563da63e24..6a42b2142fd6 100644
--- a/include/asm-i386/semaphore.h
+++ b/include/asm-i386/semaphore.h
@@ -55,9 +55,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/asm-i386/system.h b/include/asm-i386/system.h
index acd5c26b69ba..97d52ac49e46 100644
--- a/include/asm-i386/system.h
+++ b/include/asm-i386/system.h
@@ -167,6 +167,8 @@ struct __xchg_dummy { unsigned long a[100]; };
#define __xg(x) ((struct __xchg_dummy *)(x))
+#ifdef CONFIG_X86_CMPXCHG64
+
/*
* The semantics of XCHGCMP8B are a bit strange, this is why
* there is a loop and the loading of %%eax and %%edx has to
@@ -221,6 +223,8 @@ static inline void __set_64bit_var (unsigned long long *ptr,
__set_64bit(ptr, (unsigned int)(value), (unsigned int)((value)>>32ULL) ) : \
__set_64bit(ptr, ll_low(value), ll_high(value)) )
+#endif
+
/*
* Note: no "lock" prefix even on SMP: xchg always implies lock anyway
* Note 2: xchg has side effect, so that attribute volatile is necessary,
@@ -259,7 +263,6 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz
#ifdef CONFIG_X86_CMPXCHG
#define __HAVE_ARCH_CMPXCHG 1
-#endif
static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
unsigned long new, int size)
@@ -275,13 +278,13 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
case 2:
__asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
: "=a"(prev)
- : "q"(new), "m"(*__xg(ptr)), "0"(old)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
: "memory");
return prev;
case 4:
__asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
: "=a"(prev)
- : "q"(new), "m"(*__xg(ptr)), "0"(old)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
: "memory");
return prev;
}
@@ -291,6 +294,30 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
#define cmpxchg(ptr,o,n)\
((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
(unsigned long)(n),sizeof(*(ptr))))
+
+#endif
+
+#ifdef CONFIG_X86_CMPXCHG64
+
+static inline unsigned long long __cmpxchg64(volatile void *ptr, unsigned long long old,
+ unsigned long long new)
+{
+ unsigned long long prev;
+ __asm__ __volatile__(LOCK_PREFIX "cmpxchg8b %3"
+ : "=A"(prev)
+ : "b"((unsigned long)new),
+ "c"((unsigned long)(new >> 32)),
+ "m"(*__xg(ptr)),
+ "0"(old)
+ : "memory");
+ return prev;
+}
+
+#define cmpxchg64(ptr,o,n)\
+ ((__typeof__(*(ptr)))__cmpxchg64((ptr),(unsigned long long)(o),\
+ (unsigned long long)(n)))
+
+#endif
#ifdef __KERNEL__
struct alt_instr {
diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h
index fbaf90a3968c..0f92e78dfea1 100644
--- a/include/asm-i386/unistd.h
+++ b/include/asm-i386/unistd.h
@@ -448,7 +448,6 @@ asmlinkage int sys_clone(struct pt_regs regs);
asmlinkage int sys_fork(struct pt_regs regs);
asmlinkage int sys_vfork(struct pt_regs regs);
asmlinkage int sys_pipe(unsigned long __user *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
asmlinkage long sys_iopl(unsigned long unused);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
diff --git a/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h
index 3339c7b55a6f..21e32a06bc82 100644
--- a/include/asm-ia64/pgtable.h
+++ b/include/asm-ia64/pgtable.h
@@ -236,9 +236,6 @@ ia64_phys_addr_valid (unsigned long addr)
#define pte_modify(_pte, newprot) \
(__pte((pte_val(_pte) & ~_PAGE_CHG_MASK) | (pgprot_val(newprot) & _PAGE_CHG_MASK)))
-#define page_pte_prot(page,prot) mk_pte(page, prot)
-#define page_pte(page) page_pte_prot(page, __pgprot(0))
-
#define pte_none(pte) (!pte_val(pte))
#define pte_present(pte) (pte_val(pte) & (_PAGE_P | _PAGE_PROTNONE))
#define pte_clear(mm,addr,pte) (pte_val(*(pte)) = 0UL)
diff --git a/include/asm-ia64/rwsem.h b/include/asm-ia64/rwsem.h
index e18b5ab0cb75..1327c91ea39c 100644
--- a/include/asm-ia64/rwsem.h
+++ b/include/asm-ia64/rwsem.h
@@ -186,4 +186,9 @@ __downgrade_write (struct rw_semaphore *sem)
#define rwsem_atomic_add(delta, sem) atomic64_add(delta, (atomic64_t *)(&(sem)->count))
#define rwsem_atomic_update(delta, sem) atomic64_add_return(delta, (atomic64_t *)(&(sem)->count))
+static inline int rwsem_is_locked(struct rw_semaphore *sem)
+{
+ return (sem->count != 0);
+}
+
#endif /* _ASM_IA64_RWSEM_H */
diff --git a/include/asm-ia64/semaphore.h b/include/asm-ia64/semaphore.h
index 3a2f0f3f78f3..bb8906285fab 100644
--- a/include/asm-ia64/semaphore.h
+++ b/include/asm-ia64/semaphore.h
@@ -24,8 +24,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
}
-#define __MUTEX_INITIALIZER(name) __SEMAPHORE_INITIALIZER(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name, count)
diff --git a/include/asm-ia64/tlb.h b/include/asm-ia64/tlb.h
index 3a9a6d1be75c..834370b9dea1 100644
--- a/include/asm-ia64/tlb.h
+++ b/include/asm-ia64/tlb.h
@@ -60,7 +60,6 @@ struct mmu_gather {
unsigned int nr; /* == ~0U => fast mode */
unsigned char fullmm; /* non-zero means full mm flush */
unsigned char need_flush; /* really unmapped some PTEs? */
- unsigned long freed; /* number of pages freed */
unsigned long start_addr;
unsigned long end_addr;
struct page *pages[FREE_PTE_NR];
@@ -129,7 +128,7 @@ ia64_tlb_flush_mmu (struct mmu_gather *tlb, unsigned long start, unsigned long e
static inline struct mmu_gather *
tlb_gather_mmu (struct mm_struct *mm, unsigned int full_mm_flush)
{
- struct mmu_gather *tlb = &__get_cpu_var(mmu_gathers);
+ struct mmu_gather *tlb = &get_cpu_var(mmu_gathers);
tlb->mm = mm;
/*
@@ -147,25 +146,17 @@ tlb_gather_mmu (struct mm_struct *mm, unsigned int full_mm_flush)
*/
tlb->nr = (num_online_cpus() == 1) ? ~0U : 0;
tlb->fullmm = full_mm_flush;
- tlb->freed = 0;
tlb->start_addr = ~0UL;
return tlb;
}
/*
* Called at the end of the shootdown operation to free up any resources that were
- * collected. The page table lock is still held at this point.
+ * collected.
*/
static inline void
tlb_finish_mmu (struct mmu_gather *tlb, unsigned long start, unsigned long end)
{
- unsigned long freed = tlb->freed;
- struct mm_struct *mm = tlb->mm;
- unsigned long rss = get_mm_counter(mm, rss);
-
- if (rss < freed)
- freed = rss;
- add_mm_counter(mm, rss, -freed);
/*
* Note: tlb->nr may be 0 at this point, so we can't rely on tlb->start_addr and
* tlb->end_addr.
@@ -174,12 +165,8 @@ tlb_finish_mmu (struct mmu_gather *tlb, unsigned long start, unsigned long end)
/* keep the page table cache within bounds */
check_pgt_cache();
-}
-static inline unsigned int
-tlb_is_full_mm(struct mmu_gather *tlb)
-{
- return tlb->fullmm;
+ put_cpu_var(mmu_gathers);
}
/*
diff --git a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h
index 3a0c69524656..6d96a67439be 100644
--- a/include/asm-ia64/unistd.h
+++ b/include/asm-ia64/unistd.h
@@ -383,8 +383,6 @@ struct sigaction;
long sys_execve(char __user *filename, char __user * __user *argv,
char __user * __user *envp, struct pt_regs *regs);
asmlinkage long sys_pipe(void);
-asmlinkage long sys_ptrace(long request, pid_t pid,
- unsigned long addr, unsigned long data);
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
struct sigaction __user *oact,
diff --git a/include/asm-m32r/mmzone.h b/include/asm-m32r/mmzone.h
index d58878ec899e..adc7970a77ec 100644
--- a/include/asm-m32r/mmzone.h
+++ b/include/asm-m32r/mmzone.h
@@ -21,12 +21,6 @@ extern struct pglist_data *node_data[];
__pgdat->node_start_pfn + __pgdat->node_spanned_pages - 1; \
})
-#define local_mapnr(kvaddr) \
-({ \
- unsigned long __pfn = __pa(kvaddr) >> PAGE_SHIFT; \
- (__pfn - node_start_pfn(pfn_to_nid(__pfn))); \
-})
-
#define pfn_to_page(pfn) \
({ \
unsigned long __pfn = pfn; \
diff --git a/include/asm-m32r/pgtable.h b/include/asm-m32r/pgtable.h
index 388e5ee9fa27..1cd5fd4a5b2c 100644
--- a/include/asm-m32r/pgtable.h
+++ b/include/asm-m32r/pgtable.h
@@ -324,8 +324,6 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
return pte;
}
-#define page_pte(page) page_pte_prot(page, __pgprot(0))
-
/*
* Conversion functions: convert a page and protection to a page entry,
* and a page entry and page directory to the page they refer to.
diff --git a/include/asm-m32r/semaphore.h b/include/asm-m32r/semaphore.h
index 53e3c60f21ec..bf447c52a0a1 100644
--- a/include/asm-m32r/semaphore.h
+++ b/include/asm-m32r/semaphore.h
@@ -32,9 +32,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/asm-m32r/thread_info.h b/include/asm-m32r/thread_info.h
index 7a6be7727a92..0f589363f619 100644
--- a/include/asm-m32r/thread_info.h
+++ b/include/asm-m32r/thread_info.h
@@ -95,7 +95,7 @@ static inline struct thread_info *current_thread_info(void)
}
/* thread information allocation */
-#if CONFIG_DEBUG_STACK_USAGE
+#ifdef CONFIG_DEBUG_STACK_USAGE
#define alloc_thread_info(tsk) \
({ \
struct thread_info *ret; \
diff --git a/include/asm-m32r/unistd.h b/include/asm-m32r/unistd.h
index 8552d8f45ab1..ac399e1f7bc0 100644
--- a/include/asm-m32r/unistd.h
+++ b/include/asm-m32r/unistd.h
@@ -452,7 +452,6 @@ asmlinkage int sys_clone(struct pt_regs regs);
asmlinkage int sys_fork(struct pt_regs regs);
asmlinkage int sys_vfork(struct pt_regs regs);
asmlinkage int sys_pipe(unsigned long __user *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
diff --git a/include/asm-m68k/semaphore.h b/include/asm-m68k/semaphore.h
index ab94cf3ed447..fd4c7cc3d3be 100644
--- a/include/asm-m68k/semaphore.h
+++ b/include/asm-m68k/semaphore.h
@@ -36,9 +36,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/asm-m68k/sun3xflop.h b/include/asm-m68k/sun3xflop.h
index 1ed3b787ee05..fda1eccf10aa 100644
--- a/include/asm-m68k/sun3xflop.h
+++ b/include/asm-m68k/sun3xflop.h
@@ -27,10 +27,8 @@
/* We don't need no stinkin' I/O port allocation crap. */
#undef release_region
-#undef check_region
#undef request_region
#define release_region(X, Y) do { } while(0)
-#define check_region(X, Y) (0)
#define request_region(X, Y, Z) (1)
struct sun3xflop_private {
diff --git a/include/asm-m68k/unistd.h b/include/asm-m68k/unistd.h
index cbabde4f8a45..c2554bcd1747 100644
--- a/include/asm-m68k/unistd.h
+++ b/include/asm-m68k/unistd.h
@@ -444,7 +444,6 @@ asmlinkage long sys_mmap2(
unsigned long fd, unsigned long pgoff);
asmlinkage int sys_execve(char *name, char **argv, char **envp);
asmlinkage int sys_pipe(unsigned long *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
struct pt_regs;
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
diff --git a/include/asm-m68knommu/ide.h b/include/asm-m68knommu/ide.h
index b1cbf8bb9232..836f0721ecf9 100644
--- a/include/asm-m68knommu/ide.h
+++ b/include/asm-m68knommu/ide.h
@@ -163,13 +163,6 @@ ide_free_irq(unsigned int irq, void *dev_id)
}
-static IDE_INLINE int
-ide_check_region(ide_ioreg_t from, unsigned int extent)
-{
- return 0;
-}
-
-
static IDE_INLINE void
ide_request_region(ide_ioreg_t from, unsigned int extent, const char *name)
{
diff --git a/include/asm-m68knommu/semaphore.h b/include/asm-m68knommu/semaphore.h
index febe85add509..17aee15906a6 100644
--- a/include/asm-m68knommu/semaphore.h
+++ b/include/asm-m68knommu/semaphore.h
@@ -35,9 +35,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/asm-m68knommu/unistd.h b/include/asm-m68knommu/unistd.h
index 84b6fa14459f..5373988a7e51 100644
--- a/include/asm-m68knommu/unistd.h
+++ b/include/asm-m68knommu/unistd.h
@@ -504,7 +504,6 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
unsigned long fd, unsigned long pgoff);
asmlinkage int sys_execve(char *name, char **argv, char **envp);
asmlinkage int sys_pipe(unsigned long *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
struct pt_regs;
int sys_request_irq(unsigned int,
irqreturn_t (*)(int, void *, struct pt_regs *),
diff --git a/include/asm-mips/abi.h b/include/asm-mips/abi.h
new file mode 100644
index 000000000000..2e7e651c3e3f
--- /dev/null
+++ b/include/asm-mips/abi.h
@@ -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) 2005 by Ralf Baechle
+ * Copyright (C) 2005 MIPS Technologies, Inc.
+ */
+#ifndef _ASM_ABI_H
+#define _ASM_ABI_H
+
+#include <asm/signal.h>
+#include <asm/siginfo.h>
+
+struct mips_abi {
+ int (* const do_signal)(sigset_t *oldset, struct pt_regs *regs);
+ int (* const setup_frame)(struct k_sigaction * ka,
+ struct pt_regs *regs, int signr,
+ sigset_t *set);
+ int (* const setup_rt_frame)(struct k_sigaction * ka,
+ struct pt_regs *regs, int signr,
+ sigset_t *set, siginfo_t *info);
+};
+
+#endif /* _ASM_ABI_H */
diff --git a/include/asm-mips/addrspace.h b/include/asm-mips/addrspace.h
index 7dc2619f5006..42520cc84b0f 100644
--- a/include/asm-mips/addrspace.h
+++ b/include/asm-mips/addrspace.h
@@ -20,10 +20,12 @@
#define _ATYPE_
#define _ATYPE32_
#define _ATYPE64_
+#define _LLCONST_(x) x
#else
#define _ATYPE_ __PTRDIFF_TYPE__
#define _ATYPE32_ int
#define _ATYPE64_ long long
+#define _LLCONST_(x) x ## LL
#endif
/*
@@ -45,8 +47,9 @@
/*
* Returns the physical address of a CKSEGx / XKPHYS address
*/
-#define CPHYSADDR(a) ((_ACAST32_ (a)) & 0x1fffffff)
-#define XPHYSADDR(a) ((_ACAST64_ (a)) & 0x000000ffffffffff)
+#define CPHYSADDR(a) ((_ACAST32_(a)) & 0x1fffffff)
+#define XPHYSADDR(a) ((_ACAST64_(a)) & \
+ _LLCONST_(0x000000ffffffffff))
#ifdef CONFIG_64BIT
@@ -55,14 +58,14 @@
* The compatibility segments use the full 64-bit sign extended value. Note
* the R8000 doesn't have them so don't reference these in generic MIPS code.
*/
-#define XKUSEG 0x0000000000000000
-#define XKSSEG 0x4000000000000000
-#define XKPHYS 0x8000000000000000
-#define XKSEG 0xc000000000000000
-#define CKSEG0 0xffffffff80000000
-#define CKSEG1 0xffffffffa0000000
-#define CKSSEG 0xffffffffc0000000
-#define CKSEG3 0xffffffffe0000000
+#define XKUSEG _LLCONST_(0x0000000000000000)
+#define XKSSEG _LLCONST_(0x4000000000000000)
+#define XKPHYS _LLCONST_(0x8000000000000000)
+#define XKSEG _LLCONST_(0xc000000000000000)
+#define CKSEG0 _LLCONST_(0xffffffff80000000)
+#define CKSEG1 _LLCONST_(0xffffffffa0000000)
+#define CKSSEG _LLCONST_(0xffffffffc0000000)
+#define CKSEG3 _LLCONST_(0xffffffffe0000000)
#define CKSEG0ADDR(a) (CPHYSADDR(a) | CKSEG0)
#define CKSEG1ADDR(a) (CPHYSADDR(a) | CKSEG1)
@@ -120,7 +123,8 @@
#define PHYS_TO_XKSEG_UNCACHED(p) PHYS_TO_XKPHYS(K_CALG_UNCACHED,(p))
#define PHYS_TO_XKSEG_CACHED(p) PHYS_TO_XKPHYS(K_CALG_COH_SHAREABLE,(p))
#define XKPHYS_TO_PHYS(p) ((p) & TO_PHYS_MASK)
-#define PHYS_TO_XKPHYS(cm,a) (0x8000000000000000 | ((cm)<<59) | (a))
+#define PHYS_TO_XKPHYS(cm,a) (_LLCONST_(0x8000000000000000) | \
+ ((cm)<<59) | (a))
#if defined (CONFIG_CPU_R4300) \
|| defined (CONFIG_CPU_R4X00) \
@@ -128,46 +132,56 @@
|| defined (CONFIG_CPU_NEVADA) \
|| defined (CONFIG_CPU_TX49XX) \
|| defined (CONFIG_CPU_MIPS64)
-#define KUSIZE 0x0000010000000000 /* 2^^40 */
-#define KUSIZE_64 0x0000010000000000 /* 2^^40 */
-#define K0SIZE 0x0000001000000000 /* 2^^36 */
-#define K1SIZE 0x0000001000000000 /* 2^^36 */
-#define K2SIZE 0x000000ff80000000
-#define KSEGSIZE 0x000000ff80000000 /* max syssegsz */
-#define TO_PHYS_MASK 0x0000000fffffffff /* 2^^36 - 1 */
+#define KUSIZE _LLCONST_(0x0000010000000000) /* 2^^40 */
+#define KUSIZE_64 _LLCONST_(0x0000010000000000) /* 2^^40 */
+#define K0SIZE _LLCONST_(0x0000001000000000) /* 2^^36 */
+#define K1SIZE _LLCONST_(0x0000001000000000) /* 2^^36 */
+#define K2SIZE _LLCONST_(0x000000ff80000000)
+#define KSEGSIZE _LLCONST_(0x000000ff80000000) /* max syssegsz */
+#define TO_PHYS_MASK _LLCONST_(0x0000000fffffffff) /* 2^^36 - 1 */
#endif
#if defined (CONFIG_CPU_R8000)
/* We keep KUSIZE consistent with R4000 for now (2^^40) instead of (2^^48) */
-#define KUSIZE 0x0000010000000000 /* 2^^40 */
-#define KUSIZE_64 0x0000010000000000 /* 2^^40 */
-#define K0SIZE 0x0000010000000000 /* 2^^40 */
-#define K1SIZE 0x0000010000000000 /* 2^^40 */
-#define K2SIZE 0x0001000000000000
-#define KSEGSIZE 0x0000010000000000 /* max syssegsz */
-#define TO_PHYS_MASK 0x000000ffffffffff /* 2^^40 - 1 */
+#define KUSIZE _LLCONST_(0x0000010000000000) /* 2^^40 */
+#define KUSIZE_64 _LLCONST_(0x0000010000000000) /* 2^^40 */
+#define K0SIZE _LLCONST_(0x0000010000000000) /* 2^^40 */
+#define K1SIZE _LLCONST_(0x0000010000000000) /* 2^^40 */
+#define K2SIZE _LLCONST_(0x0001000000000000)
+#define KSEGSIZE _LLCONST_(0x0000010000000000) /* max syssegsz */
+#define TO_PHYS_MASK _LLCONST_(0x000000ffffffffff) /* 2^^40 - 1 */
#endif
#if defined (CONFIG_CPU_R10000)
-#define KUSIZE 0x0000010000000000 /* 2^^40 */
-#define KUSIZE_64 0x0000010000000000 /* 2^^40 */
-#define K0SIZE 0x0000010000000000 /* 2^^40 */
-#define K1SIZE 0x0000010000000000 /* 2^^40 */
-#define K2SIZE 0x00000fff80000000
-#define KSEGSIZE 0x00000fff80000000 /* max syssegsz */
-#define TO_PHYS_MASK 0x000000ffffffffff /* 2^^40 - 1 */
+#define KUSIZE _LLCONST_(0x0000010000000000) /* 2^^40 */
+#define KUSIZE_64 _LLCONST_(0x0000010000000000) /* 2^^40 */
+#define K0SIZE _LLCONST_(0x0000010000000000) /* 2^^40 */
+#define K1SIZE _LLCONST_(0x0000010000000000) /* 2^^40 */
+#define K2SIZE _LLCONST_(0x00000fff80000000)
+#define KSEGSIZE _LLCONST_(0x00000fff80000000) /* max syssegsz */
+#define TO_PHYS_MASK _LLCONST_(0x000000ffffffffff) /* 2^^40 - 1 */
+#endif
+
+#if defined(CONFIG_CPU_SB1) || defined(CONFIG_CPU_SB1A)
+#define KUSIZE _LLCONST_(0x0000100000000000) /* 2^^44 */
+#define KUSIZE_64 _LLCONST_(0x0000100000000000) /* 2^^44 */
+#define K0SIZE _LLCONST_(0x0000100000000000) /* 2^^44 */
+#define K1SIZE _LLCONST_(0x0000100000000000) /* 2^^44 */
+#define K2SIZE _LLCONST_(0x0000ffff80000000)
+#define KSEGSIZE _LLCONST_(0x0000ffff80000000) /* max syssegsz */
+#define TO_PHYS_MASK _LLCONST_(0x00000fffffffffff) /* 2^^44 - 1 */
#endif
/*
* Further names for SGI source compatibility. These are stolen from
* IRIX's <sys/mips_addrspace.h>.
*/
-#define KUBASE 0
-#define KUSIZE_32 0x0000000080000000 /* KUSIZE
+#define KUBASE _LLCONST_(0)
+#define KUSIZE_32 _LLCONST_(0x0000000080000000) /* KUSIZE
for a 32 bit proc */
-#define K0BASE_EXL_WR 0xa800000000000000 /* exclusive on write */
-#define K0BASE_NONCOH 0x9800000000000000 /* noncoherent */
-#define K0BASE_EXL 0xa000000000000000 /* exclusive */
+#define K0BASE_EXL_WR _LLCONST_(0xa800000000000000) /* exclusive on write */
+#define K0BASE_NONCOH _LLCONST_(0x9800000000000000) /* noncoherent */
+#define K0BASE_EXL _LLCONST_(0xa000000000000000) /* exclusive */
#ifndef CONFIG_CPU_R8000
@@ -176,7 +190,7 @@
* in order to catch bugs in the source code.
*/
-#define COMPAT_K1BASE32 0xffffffffa0000000
+#define COMPAT_K1BASE32 _LLCONST_(0xffffffffa0000000)
#define PHYS_TO_COMPATK1(x) ((x) | COMPAT_K1BASE32) /* 32-bit compat k1 */
#endif
diff --git a/include/asm-mips/asm.h b/include/asm-mips/asm.h
index f53237772985..4b090f3142e0 100644
--- a/include/asm-mips/asm.h
+++ b/include/asm-mips/asm.h
@@ -107,6 +107,7 @@ symbol = value
/*
* Print formatted string
*/
+#ifdef CONFIG_PRINTK
#define PRINT(string) \
.set push; \
.set reorder; \
@@ -114,6 +115,9 @@ symbol = value
jal printk; \
.set pop; \
TEXT(string)
+#else
+#define PRINT(string)
+#endif
#define TEXT(msg) \
.pushsection .data; \
diff --git a/include/asm-mips/atomic.h b/include/asm-mips/atomic.h
index c0bd8d014e14..6202eb8a14b7 100644
--- a/include/asm-mips/atomic.h
+++ b/include/asm-mips/atomic.h
@@ -62,20 +62,24 @@ static __inline__ void atomic_add(int i, atomic_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: ll %0, %1 # atomic_add \n"
" addu %0, %2 \n"
" sc %0, %1 \n"
" beqzl %0, 1b \n"
+ " .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));
} else if (cpu_has_llsc) {
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: ll %0, %1 # atomic_add \n"
" addu %0, %2 \n"
" sc %0, %1 \n"
" beqz %0, 1b \n"
+ " .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));
} else {
@@ -100,20 +104,24 @@ static __inline__ void atomic_sub(int i, atomic_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: ll %0, %1 # atomic_sub \n"
" subu %0, %2 \n"
" sc %0, %1 \n"
" beqzl %0, 1b \n"
+ " .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));
} else if (cpu_has_llsc) {
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: ll %0, %1 # atomic_sub \n"
" subu %0, %2 \n"
" sc %0, %1 \n"
" beqz %0, 1b \n"
+ " .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));
} else {
@@ -136,12 +144,14 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: ll %1, %2 # atomic_add_return \n"
" addu %0, %1, %3 \n"
" sc %0, %2 \n"
" beqzl %0, 1b \n"
" addu %0, %1, %3 \n"
" sync \n"
+ " .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
@@ -149,12 +159,14 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: ll %1, %2 # atomic_add_return \n"
" addu %0, %1, %3 \n"
" sc %0, %2 \n"
" beqz %0, 1b \n"
" addu %0, %1, %3 \n"
" sync \n"
+ " .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
@@ -179,12 +191,14 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: ll %1, %2 # atomic_sub_return \n"
" subu %0, %1, %3 \n"
" sc %0, %2 \n"
" beqzl %0, 1b \n"
" subu %0, %1, %3 \n"
" sync \n"
+ " .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
@@ -192,12 +206,14 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: ll %1, %2 # atomic_sub_return \n"
" subu %0, %1, %3 \n"
" sc %0, %2 \n"
" beqz %0, 1b \n"
" subu %0, %1, %3 \n"
" sync \n"
+ " .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
@@ -229,6 +245,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: ll %1, %2 # atomic_sub_if_positive\n"
" subu %0, %1, %3 \n"
" bltz %0, 1f \n"
@@ -236,6 +253,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
" beqzl %0, 1b \n"
" sync \n"
"1: \n"
+ " .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
@@ -243,6 +261,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: ll %1, %2 # atomic_sub_if_positive\n"
" subu %0, %1, %3 \n"
" bltz %0, 1f \n"
@@ -250,6 +269,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
" beqz %0, 1b \n"
" sync \n"
"1: \n"
+ " .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
@@ -367,20 +387,24 @@ static __inline__ void atomic64_add(long i, atomic64_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: lld %0, %1 # atomic64_add \n"
" addu %0, %2 \n"
" scd %0, %1 \n"
" beqzl %0, 1b \n"
+ " .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));
} else if (cpu_has_llsc) {
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: lld %0, %1 # atomic64_add \n"
" addu %0, %2 \n"
" scd %0, %1 \n"
" beqz %0, 1b \n"
+ " .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));
} else {
@@ -405,20 +429,24 @@ static __inline__ void atomic64_sub(long i, atomic64_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: lld %0, %1 # atomic64_sub \n"
" subu %0, %2 \n"
" scd %0, %1 \n"
" beqzl %0, 1b \n"
+ " .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));
} else if (cpu_has_llsc) {
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: lld %0, %1 # atomic64_sub \n"
" subu %0, %2 \n"
" scd %0, %1 \n"
" beqz %0, 1b \n"
+ " .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));
} else {
@@ -441,12 +469,14 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: lld %1, %2 # atomic64_add_return \n"
" addu %0, %1, %3 \n"
" scd %0, %2 \n"
" beqzl %0, 1b \n"
" addu %0, %1, %3 \n"
" sync \n"
+ " .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
@@ -454,12 +484,14 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: lld %1, %2 # atomic64_add_return \n"
" addu %0, %1, %3 \n"
" scd %0, %2 \n"
" beqz %0, 1b \n"
" addu %0, %1, %3 \n"
" sync \n"
+ " .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
@@ -484,12 +516,14 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: lld %1, %2 # atomic64_sub_return \n"
" subu %0, %1, %3 \n"
" scd %0, %2 \n"
" beqzl %0, 1b \n"
" subu %0, %1, %3 \n"
" sync \n"
+ " .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
@@ -497,12 +531,14 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: lld %1, %2 # atomic64_sub_return \n"
" subu %0, %1, %3 \n"
" scd %0, %2 \n"
" beqz %0, 1b \n"
" subu %0, %1, %3 \n"
" sync \n"
+ " .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
@@ -534,6 +570,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: lld %1, %2 # atomic64_sub_if_positive\n"
" dsubu %0, %1, %3 \n"
" bltz %0, 1f \n"
@@ -541,6 +578,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
" beqzl %0, 1b \n"
" sync \n"
"1: \n"
+ " .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
@@ -548,6 +586,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: lld %1, %2 # atomic64_sub_if_positive\n"
" dsubu %0, %1, %3 \n"
" bltz %0, 1f \n"
@@ -555,6 +594,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
" beqz %0, 1b \n"
" sync \n"
"1: \n"
+ " .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h
index eb8d79dba11c..5496f9064a6a 100644
--- a/include/asm-mips/bitops.h
+++ b/include/asm-mips/bitops.h
@@ -12,20 +12,21 @@
#include <linux/config.h>
#include <linux/compiler.h>
#include <linux/types.h>
+#include <asm/bug.h>
#include <asm/byteorder.h> /* sigh ... */
#include <asm/cpu-features.h>
#if (_MIPS_SZLONG == 32)
#define SZLONG_LOG 5
#define SZLONG_MASK 31UL
-#define __LL "ll "
-#define __SC "sc "
+#define __LL "ll "
+#define __SC "sc "
#define cpu_to_lelongp(x) cpu_to_le32p((__u32 *) (x))
#elif (_MIPS_SZLONG == 64)
#define SZLONG_LOG 6
#define SZLONG_MASK 63UL
-#define __LL "lld "
-#define __SC "scd "
+#define __LL "lld "
+#define __SC "scd "
#define cpu_to_lelongp(x) cpu_to_le64p((__u64 *) (x))
#endif
@@ -72,18 +73,22 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
if (cpu_has_llsc && R10000_LLSC_WAR) {
__asm__ __volatile__(
+ " .set mips3 \n"
"1: " __LL "%0, %1 # set_bit \n"
" or %0, %2 \n"
- " "__SC "%0, %1 \n"
+ " " __SC "%0, %1 \n"
" beqzl %0, 1b \n"
+ " .set mips0 \n"
: "=&r" (temp), "=m" (*m)
: "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m));
} else if (cpu_has_llsc) {
__asm__ __volatile__(
+ " .set mips3 \n"
"1: " __LL "%0, %1 # set_bit \n"
" or %0, %2 \n"
- " "__SC "%0, %1 \n"
+ " " __SC "%0, %1 \n"
" beqz %0, 1b \n"
+ " .set mips0 \n"
: "=&r" (temp), "=m" (*m)
: "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m));
} else {
@@ -132,18 +137,22 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
if (cpu_has_llsc && R10000_LLSC_WAR) {
__asm__ __volatile__(
+ " .set mips3 \n"
"1: " __LL "%0, %1 # clear_bit \n"
" and %0, %2 \n"
" " __SC "%0, %1 \n"
" beqzl %0, 1b \n"
+ " .set mips0 \n"
: "=&r" (temp), "=m" (*m)
: "ir" (~(1UL << (nr & SZLONG_MASK))), "m" (*m));
} else if (cpu_has_llsc) {
__asm__ __volatile__(
+ " .set mips3 \n"
"1: " __LL "%0, %1 # clear_bit \n"
" and %0, %2 \n"
" " __SC "%0, %1 \n"
" beqz %0, 1b \n"
+ " .set mips0 \n"
: "=&r" (temp), "=m" (*m)
: "ir" (~(1UL << (nr & SZLONG_MASK))), "m" (*m));
} else {
@@ -191,10 +200,12 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: " __LL "%0, %1 # change_bit \n"
" xor %0, %2 \n"
- " "__SC "%0, %1 \n"
+ " " __SC "%0, %1 \n"
" beqzl %0, 1b \n"
+ " .set mips0 \n"
: "=&r" (temp), "=m" (*m)
: "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m));
} else if (cpu_has_llsc) {
@@ -202,10 +213,12 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: " __LL "%0, %1 # change_bit \n"
" xor %0, %2 \n"
- " "__SC "%0, %1 \n"
+ " " __SC "%0, %1 \n"
" beqz %0, 1b \n"
+ " .set mips0 \n"
: "=&r" (temp), "=m" (*m)
: "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m));
} else {
@@ -253,14 +266,16 @@ static inline int test_and_set_bit(unsigned long nr,
unsigned long temp, res;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: " __LL "%0, %1 # test_and_set_bit \n"
" or %2, %0, %3 \n"
" " __SC "%2, %1 \n"
" beqzl %2, 1b \n"
" and %2, %0, %3 \n"
#ifdef CONFIG_SMP
- "sync \n"
+ " sync \n"
#endif
+ " .set mips0 \n"
: "=&r" (temp), "=m" (*m), "=&r" (res)
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
: "memory");
@@ -271,16 +286,18 @@ static inline int test_and_set_bit(unsigned long nr,
unsigned long temp, res;
__asm__ __volatile__(
- " .set noreorder # test_and_set_bit \n"
- "1: " __LL "%0, %1 \n"
+ " .set push \n"
+ " .set noreorder \n"
+ " .set mips3 \n"
+ "1: " __LL "%0, %1 # test_and_set_bit \n"
" or %2, %0, %3 \n"
" " __SC "%2, %1 \n"
" beqz %2, 1b \n"
" and %2, %0, %3 \n"
#ifdef CONFIG_SMP
- "sync \n"
+ " sync \n"
#endif
- ".set\treorder"
+ " .set pop \n"
: "=&r" (temp), "=m" (*m), "=&r" (res)
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
: "memory");
@@ -343,15 +360,17 @@ static inline int test_and_clear_bit(unsigned long nr,
unsigned long temp, res;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: " __LL "%0, %1 # test_and_clear_bit \n"
" or %2, %0, %3 \n"
" xor %2, %3 \n"
- __SC "%2, %1 \n"
+ " " __SC "%2, %1 \n"
" beqzl %2, 1b \n"
" and %2, %0, %3 \n"
#ifdef CONFIG_SMP
" sync \n"
#endif
+ " .set mips0 \n"
: "=&r" (temp), "=m" (*m), "=&r" (res)
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
: "memory");
@@ -362,17 +381,19 @@ static inline int test_and_clear_bit(unsigned long nr,
unsigned long temp, res;
__asm__ __volatile__(
- " .set noreorder # test_and_clear_bit \n"
- "1: " __LL "%0, %1 \n"
+ " .set push \n"
+ " .set noreorder \n"
+ " .set mips3 \n"
+ "1: " __LL "%0, %1 # test_and_clear_bit \n"
" or %2, %0, %3 \n"
" xor %2, %3 \n"
- __SC "%2, %1 \n"
+ " " __SC "%2, %1 \n"
" beqz %2, 1b \n"
" and %2, %0, %3 \n"
#ifdef CONFIG_SMP
" sync \n"
#endif
- " .set reorder \n"
+ " .set pop \n"
: "=&r" (temp), "=m" (*m), "=&r" (res)
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
: "memory");
@@ -435,14 +456,16 @@ static inline int test_and_change_bit(unsigned long nr,
unsigned long temp, res;
__asm__ __volatile__(
- "1: " __LL " %0, %1 # test_and_change_bit \n"
+ " .set mips3 \n"
+ "1: " __LL "%0, %1 # test_and_change_bit \n"
" xor %2, %0, %3 \n"
- " "__SC "%2, %1 \n"
+ " " __SC "%2, %1 \n"
" beqzl %2, 1b \n"
" and %2, %0, %3 \n"
#ifdef CONFIG_SMP
" sync \n"
#endif
+ " .set mips0 \n"
: "=&r" (temp), "=m" (*m), "=&r" (res)
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
: "memory");
@@ -453,16 +476,18 @@ static inline int test_and_change_bit(unsigned long nr,
unsigned long temp, res;
__asm__ __volatile__(
- " .set noreorder # test_and_change_bit \n"
- "1: " __LL " %0, %1 \n"
+ " .set push \n"
+ " .set noreorder \n"
+ " .set mips3 \n"
+ "1: " __LL "%0, %1 # test_and_change_bit \n"
" xor %2, %0, %3 \n"
- " "__SC "\t%2, %1 \n"
+ " " __SC "\t%2, %1 \n"
" beqz %2, 1b \n"
" and %2, %0, %3 \n"
#ifdef CONFIG_SMP
" sync \n"
#endif
- " .set reorder \n"
+ " .set pop \n"
: "=&r" (temp), "=m" (*m), "=&r" (res)
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
: "memory");
@@ -523,22 +548,60 @@ static inline int test_bit(unsigned long nr, const volatile unsigned long *addr)
}
/*
- * ffz - find first zero in word.
+ * Return the bit position (0..63) of the most significant 1 bit in a word
+ * Returns -1 if no 1 bit exists
+ */
+static inline int __ilog2(unsigned long x)
+{
+ int lz;
+
+ if (sizeof(x) == 4) {
+ __asm__ (
+ " .set push \n"
+ " .set mips32 \n"
+ " clz %0, %1 \n"
+ " .set pop \n"
+ : "=r" (lz)
+ : "r" (x));
+
+ return 31 - lz;
+ }
+
+ BUG_ON(sizeof(x) != 8);
+
+ __asm__ (
+ " .set push \n"
+ " .set mips64 \n"
+ " dclz %0, %1 \n"
+ " .set pop \n"
+ : "=r" (lz)
+ : "r" (x));
+
+ return 63 - lz;
+}
+
+/*
+ * __ffs - find first bit in word.
* @word: The word to search
*
- * Undefined if no zero exists, so code should check against ~0UL first.
+ * Returns 0..SZLONG-1
+ * Undefined if no bit exists, so code should check against 0 first.
*/
-static inline unsigned long ffz(unsigned long word)
+static inline unsigned long __ffs(unsigned long word)
{
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
+ return __ilog2(word & -word);
+#else
int b = 0, s;
- word = ~word;
#ifdef CONFIG_32BIT
s = 16; if (word << 16 != 0) s = 0; b += s; word >>= s;
s = 8; if (word << 24 != 0) s = 0; b += s; word >>= s;
s = 4; if (word << 28 != 0) s = 0; b += s; word >>= s;
s = 2; if (word << 30 != 0) s = 0; b += s; word >>= s;
s = 1; if (word << 31 != 0) s = 0; b += s;
+
+ return b;
#endif
#ifdef CONFIG_64BIT
s = 32; if (word << 32 != 0) s = 0; b += s; word >>= s;
@@ -547,27 +610,92 @@ static inline unsigned long ffz(unsigned long word)
s = 4; if (word << 60 != 0) s = 0; b += s; word >>= s;
s = 2; if (word << 62 != 0) s = 0; b += s; word >>= s;
s = 1; if (word << 63 != 0) s = 0; b += s;
-#endif
return b;
+#endif
+#endif
}
/*
- * __ffs - find first bit in word.
+ * ffs - find first bit set.
* @word: The word to search
*
- * Undefined if no bit exists, so code should check against 0 first.
+ * Returns 1..SZLONG
+ * Returns 0 if no bit exists
*/
-static inline unsigned long __ffs(unsigned long word)
+
+static inline unsigned long ffs(unsigned long word)
{
- return ffz(~word);
+ if (!word)
+ return 0;
+
+ return __ffs(word) + 1;
}
/*
- * fls: find last bit set.
+ * ffz - find first zero in word.
+ * @word: The word to search
+ *
+ * Undefined if no zero exists, so code should check against ~0UL first.
+ */
+static inline unsigned long ffz(unsigned long word)
+{
+ return __ffs (~word);
+}
+
+/*
+ * flz - find last zero in word.
+ * @word: The word to search
+ *
+ * Returns 0..SZLONG-1
+ * Undefined if no zero exists, so code should check against ~0UL first.
+ */
+static inline unsigned long flz(unsigned long word)
+{
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
+ return __ilog2(~word);
+#else
+#ifdef CONFIG_32BIT
+ int r = 31, s;
+ word = ~word;
+ s = 16; if ((word & 0xffff0000)) s = 0; r -= s; word <<= s;
+ s = 8; if ((word & 0xff000000)) s = 0; r -= s; word <<= s;
+ s = 4; if ((word & 0xf0000000)) s = 0; r -= s; word <<= s;
+ s = 2; if ((word & 0xc0000000)) s = 0; r -= s; word <<= s;
+ s = 1; if ((word & 0x80000000)) s = 0; r -= s;
+
+ return r;
+#endif
+#ifdef CONFIG_64BIT
+ int r = 63, s;
+ word = ~word;
+ s = 32; if ((word & 0xffffffff00000000UL)) s = 0; r -= s; word <<= s;
+ s = 16; if ((word & 0xffff000000000000UL)) s = 0; r -= s; word <<= s;
+ s = 8; if ((word & 0xff00000000000000UL)) s = 0; r -= s; word <<= s;
+ s = 4; if ((word & 0xf000000000000000UL)) s = 0; r -= s; word <<= s;
+ s = 2; if ((word & 0xc000000000000000UL)) s = 0; r -= s; word <<= s;
+ s = 1; if ((word & 0x8000000000000000UL)) s = 0; r -= s;
+
+ return r;
+#endif
+#endif
+}
+
+/*
+ * fls - find last bit set.
+ * @word: The word to search
+ *
+ * Returns 1..SZLONG
+ * Returns 0 if no bit exists
*/
+static inline unsigned long fls(unsigned long word)
+{
+ if (word == 0)
+ return 0;
+
+ return flz(~word) + 1;
+}
-#define fls(x) generic_fls(x)
/*
* find_next_zero_bit - find the first zero bit in a memory region
@@ -704,17 +832,6 @@ static inline int sched_find_first_bit(const unsigned long *b)
}
/*
- * ffs - find first bit set
- * @x: the word to search
- *
- * This is defined the same way as
- * the libc and compiler builtin ffs routines, therefore
- * differs in spirit from the above ffz (man ffs).
- */
-
-#define ffs(x) generic_ffs(x)
-
-/*
* hweightN - returns the hamming weight of a N-bit word
* @x: the word to weigh
*
diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h
index b1e57d783604..14fc88f27226 100644
--- a/include/asm-mips/bootinfo.h
+++ b/include/asm-mips/bootinfo.h
@@ -77,6 +77,7 @@
#define MACH_SGI_IP27 1 /* Origin 200, Origin 2000, Onyx 2 */
#define MACH_SGI_IP28 2 /* Indigo2 Impact */
#define MACH_SGI_IP32 3 /* O2 */
+#define MACH_SGI_IP30 4 /* Octane, Octane2 */
/*
* Valid machtype for group COBALT
@@ -136,6 +137,7 @@
#define MACH_GROUP_PHILIPS 14
#define MACH_PHILIPS_NINO 0 /* Nino */
#define MACH_PHILIPS_VELO 1 /* Velo */
+#define MACH_PHILIPS_JBS 2 /* JBS */
/*
* Valid machtype for group Globespan
@@ -159,6 +161,7 @@
#define MACH_TOSHIBA_JMR3927 3 /* JMR-TX3927 CPU/IO board */
#define MACH_TOSHIBA_RBTX4927 4
#define MACH_TOSHIBA_RBTX4937 5
+#define MACH_TOSHIBA_RBTX4938 6
#define GROUP_TOSHIBA_NAMES { "Pallas", "TopasCE", "JMR", "JMR TX3927", \
"RBTX4927", "RBTX4937" }
@@ -177,6 +180,8 @@
#define MACH_MTX1 7 /* 4G MTX-1 Au1500-based board */
#define MACH_PB1550 8 /* Au1550-based eval board */
#define MACH_DB1550 9 /* Au1550-based eval board */
+#define MACH_PB1200 10 /* Au1200-based eval board */
+#define MACH_DB1200 11 /* Au1200-based eval board */
/*
* Valid machtype for group NEC_VR41XX
diff --git a/include/asm-mips/break.h b/include/asm-mips/break.h
index 2e6de788f207..25b980c91e7e 100644
--- a/include/asm-mips/break.h
+++ b/include/asm-mips/break.h
@@ -28,6 +28,7 @@
#define BRK_NORLD 10 /* No rld found - not used by Linux/MIPS */
#define _BRK_THREADBP 11 /* For threads, user bp (used by debuggers) */
#define BRK_BUG 512 /* Used by BUG() */
+#define BRK_KDB 513 /* Used in KDB_ENTER() */
#define BRK_MULOVF 1023 /* Multiply overflow */
#endif /* __ASM_BREAK_H */
diff --git a/include/asm-mips/bug.h b/include/asm-mips/bug.h
index 3f594b440abc..87d49a5bdc63 100644
--- a/include/asm-mips/bug.h
+++ b/include/asm-mips/bug.h
@@ -1,16 +1,21 @@
#ifndef __ASM_BUG_H
#define __ASM_BUG_H
-#include <asm/break.h>
+#include <linux/config.h>
#ifdef CONFIG_BUG
-#define HAVE_ARCH_BUG
+
+#include <asm/break.h>
+
#define BUG() \
do { \
__asm__ __volatile__("break %0" : : "i" (BRK_BUG)); \
} while (0)
+
+#define HAVE_ARCH_BUG
+
#endif
#include <asm-generic/bug.h>
-#endif
+#endif /* __ASM_BUG_H */
diff --git a/include/asm-mips/bugs.h b/include/asm-mips/bugs.h
index b14b961c2100..cb2ea7c15c7a 100644
--- a/include/asm-mips/bugs.h
+++ b/include/asm-mips/bugs.h
@@ -8,12 +8,18 @@
#define _ASM_BUGS_H
#include <linux/config.h>
+#include <linux/delay.h>
+#include <asm/cpu.h>
+#include <asm/cpu-info.h>
extern void check_bugs32(void);
extern void check_bugs64(void);
static inline void check_bugs(void)
{
+ unsigned int cpu = smp_processor_id();
+
+ cpu_data[cpu].udelay_val = loops_per_jiffy;
check_bugs32();
#ifdef CONFIG_64BIT
check_bugs64();
diff --git a/include/asm-mips/cache.h b/include/asm-mips/cache.h
index 4517bdf20953..1a5d1a669db3 100644
--- a/include/asm-mips/cache.h
+++ b/include/asm-mips/cache.h
@@ -10,6 +10,7 @@
#define _ASM_CACHE_H
#include <linux/config.h>
+#include <kmalloc.h>
#define L1_CACHE_SHIFT CONFIG_MIPS_L1_CACHE_SHIFT
#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
@@ -18,6 +19,4 @@
#define SMP_CACHE_SHIFT L1_CACHE_SHIFT
#define SMP_CACHE_BYTES L1_CACHE_BYTES
-#define ARCH_KMALLOC_MINALIGN 8
-
#endif /* _ASM_CACHE_H */
diff --git a/include/asm-mips/cacheflush.h b/include/asm-mips/cacheflush.h
index 635f1bfb403e..a18ba2edc0b6 100644
--- a/include/asm-mips/cacheflush.h
+++ b/include/asm-mips/cacheflush.h
@@ -49,17 +49,29 @@ static inline void flush_dcache_page(struct page *page)
extern void (*flush_icache_page)(struct vm_area_struct *vma,
struct page *page);
-extern void (*flush_icache_range)(unsigned long start, unsigned long end);
+extern void (*flush_icache_range)(unsigned long __user start,
+ unsigned long __user end);
#define flush_cache_vmap(start, end) flush_cache_all()
#define flush_cache_vunmap(start, end) flush_cache_all()
-#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
-do { \
- memcpy(dst, (void *) src, len); \
- flush_icache_page(vma, page); \
-} while (0)
-#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
- memcpy(dst, src, len)
+static inline void copy_to_user_page(struct vm_area_struct *vma,
+ struct page *page, unsigned long vaddr, void *dst, const void *src,
+ unsigned long len)
+{
+ if (cpu_has_dc_aliases)
+ flush_cache_page(vma, vaddr, page_to_pfn(page));
+ memcpy(dst, src, len);
+ flush_icache_page(vma, page);
+}
+
+static inline void copy_from_user_page(struct vm_area_struct *vma,
+ struct page *page, unsigned long vaddr, void *dst, const void *src,
+ unsigned long len)
+{
+ if (cpu_has_dc_aliases)
+ flush_cache_page(vma, vaddr, page_to_pfn(page));
+ memcpy(dst, src, len);
+}
extern void (*flush_cache_sigtramp)(unsigned long addr);
extern void (*flush_icache_all)(void);
@@ -78,4 +90,7 @@ extern void (*flush_data_cache_page)(unsigned long addr);
#define ClearPageDcacheDirty(page) \
clear_bit(PG_dcache_dirty, &(page)->flags)
+/* Run kernel code uncached, useful for cache probing functions. */
+unsigned long __init run_uncached(void *func);
+
#endif /* _ASM_CACHEFLUSH_H */
diff --git a/include/asm-mips/checksum.h b/include/asm-mips/checksum.h
index c1ea5a8714f3..b09f8971e95d 100644
--- a/include/asm-mips/checksum.h
+++ b/include/asm-mips/checksum.h
@@ -34,8 +34,9 @@ unsigned int csum_partial(const unsigned char *buff, int len, unsigned int sum);
* this is a new version of the above that records errors it finds in *errp,
* but continues and zeros the rest of the buffer.
*/
-unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, int len,
- unsigned int sum, int *errp);
+unsigned int csum_partial_copy_from_user(const unsigned char __user *src,
+ unsigned char *dst, int len,
+ unsigned int sum, int *errp);
/*
* Copy and checksum to user
@@ -70,14 +71,15 @@ unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *
static inline unsigned short int csum_fold(unsigned int sum)
{
__asm__(
- ".set\tnoat\t\t\t# csum_fold\n\t"
- "sll\t$1,%0,16\n\t"
- "addu\t%0,$1\n\t"
- "sltu\t$1,%0,$1\n\t"
- "srl\t%0,%0,16\n\t"
- "addu\t%0,$1\n\t"
- "xori\t%0,0xffff\n\t"
- ".set\tat"
+ " .set push # csum_fold\n"
+ " .set noat \n"
+ " sll $1, %0, 16 \n"
+ " addu %0, $1 \n"
+ " sltu $1, %0, $1 \n"
+ " srl %0, %0, 16 \n"
+ " addu %0, $1 \n"
+ " xori %0, 0xffff \n"
+ " .set pop"
: "=r" (sum)
: "0" (sum));
@@ -127,29 +129,30 @@ static inline unsigned int csum_tcpudp_nofold(unsigned long saddr,
unsigned int sum)
{
__asm__(
- ".set\tnoat\t\t\t# csum_tcpudp_nofold\n\t"
+ " .set push # csum_tcpudp_nofold\n"
+ " .set noat \n"
#ifdef CONFIG_32BIT
- "addu\t%0, %2\n\t"
- "sltu\t$1, %0, %2\n\t"
- "addu\t%0, $1\n\t"
+ " addu %0, %2 \n"
+ " sltu $1, %0, %2 \n"
+ " addu %0, $1 \n"
- "addu\t%0, %3\n\t"
- "sltu\t$1, %0, %3\n\t"
- "addu\t%0, $1\n\t"
+ " addu %0, %3 \n"
+ " sltu $1, %0, %3 \n"
+ " addu %0, $1 \n"
- "addu\t%0, %4\n\t"
- "sltu\t$1, %0, %4\n\t"
- "addu\t%0, $1\n\t"
+ " addu %0, %4 \n"
+ " sltu $1, %0, %4 \n"
+ " addu %0, $1 \n"
#endif
#ifdef CONFIG_64BIT
- "daddu\t%0, %2\n\t"
- "daddu\t%0, %3\n\t"
- "daddu\t%0, %4\n\t"
- "dsll32\t$1, %0, 0\n\t"
- "daddu\t%0, $1\n\t"
- "dsrl32\t%0, %0, 0\n\t"
+ " daddu %0, %2 \n"
+ " daddu %0, %3 \n"
+ " daddu %0, %4 \n"
+ " dsll32 $1, %0, 0 \n"
+ " daddu %0, $1 \n"
+ " dsra32 %0, %0, 0 \n"
#endif
- ".set\tat"
+ " .set pop"
: "=r" (sum)
: "0" (daddr), "r"(saddr),
#ifdef __MIPSEL__
@@ -192,57 +195,57 @@ static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
unsigned int sum)
{
__asm__(
- ".set\tpush\t\t\t# csum_ipv6_magic\n\t"
- ".set\tnoreorder\n\t"
- ".set\tnoat\n\t"
- "addu\t%0, %5\t\t\t# proto (long in network byte order)\n\t"
- "sltu\t$1, %0, %5\n\t"
- "addu\t%0, $1\n\t"
-
- "addu\t%0, %6\t\t\t# csum\n\t"
- "sltu\t$1, %0, %6\n\t"
- "lw\t%1, 0(%2)\t\t\t# four words source address\n\t"
- "addu\t%0, $1\n\t"
- "addu\t%0, %1\n\t"
- "sltu\t$1, %0, %1\n\t"
-
- "lw\t%1, 4(%2)\n\t"
- "addu\t%0, $1\n\t"
- "addu\t%0, %1\n\t"
- "sltu\t$1, %0, %1\n\t"
-
- "lw\t%1, 8(%2)\n\t"
- "addu\t%0, $1\n\t"
- "addu\t%0, %1\n\t"
- "sltu\t$1, %0, %1\n\t"
-
- "lw\t%1, 12(%2)\n\t"
- "addu\t%0, $1\n\t"
- "addu\t%0, %1\n\t"
- "sltu\t$1, %0, %1\n\t"
-
- "lw\t%1, 0(%3)\n\t"
- "addu\t%0, $1\n\t"
- "addu\t%0, %1\n\t"
- "sltu\t$1, %0, %1\n\t"
-
- "lw\t%1, 4(%3)\n\t"
- "addu\t%0, $1\n\t"
- "addu\t%0, %1\n\t"
- "sltu\t$1, %0, %1\n\t"
-
- "lw\t%1, 8(%3)\n\t"
- "addu\t%0, $1\n\t"
- "addu\t%0, %1\n\t"
- "sltu\t$1, %0, %1\n\t"
-
- "lw\t%1, 12(%3)\n\t"
- "addu\t%0, $1\n\t"
- "addu\t%0, %1\n\t"
- "sltu\t$1, %0, %1\n\t"
-
- "addu\t%0, $1\t\t\t# Add final carry\n\t"
- ".set\tpop"
+ " .set push # csum_ipv6_magic\n"
+ " .set noreorder \n"
+ " .set noat \n"
+ " addu %0, %5 # proto (long in network byte order)\n"
+ " sltu $1, %0, %5 \n"
+ " addu %0, $1 \n"
+
+ " addu %0, %6 # csum\n"
+ " sltu $1, %0, %6 \n"
+ " lw %1, 0(%2) # four words source address\n"
+ " addu %0, $1 \n"
+ " addu %0, %1 \n"
+ " sltu $1, %0, %1 \n"
+
+ " lw %1, 4(%2) \n"
+ " addu %0, $1 \n"
+ " addu %0, %1 \n"
+ " sltu $1, %0, %1 \n"
+
+ " lw %1, 8(%2) \n"
+ " addu %0, $1 \n"
+ " addu %0, %1 \n"
+ " sltu $1, %0, %1 \n"
+
+ " lw %1, 12(%2) \n"
+ " addu %0, $1 \n"
+ " addu %0, %1 \n"
+ " sltu $1, %0, %1 \n"
+
+ " lw %1, 0(%3) \n"
+ " addu %0, $1 \n"
+ " addu %0, %1 \n"
+ " sltu $1, %0, %1 \n"
+
+ " lw %1, 4(%3) \n"
+ " addu %0, $1 \n"
+ " addu %0, %1 \n"
+ " sltu $1, %0, %1 \n"
+
+ " lw %1, 8(%3) \n"
+ " addu %0, $1 \n"
+ " addu %0, %1 \n"
+ " sltu $1, %0, %1 \n"
+
+ " lw %1, 12(%3) \n"
+ " addu %0, $1 \n"
+ " addu %0, %1 \n"
+ " sltu $1, %0, %1 \n"
+
+ " addu %0, $1 # Add final carry\n"
+ " .set pop"
: "=r" (sum), "=r" (proto)
: "r" (saddr), "r" (daddr),
"0" (htonl(len)), "1" (htonl(proto)), "r" (sum));
diff --git a/include/asm-mips/cobalt/cobalt.h b/include/asm-mips/cobalt/cobalt.h
index ca1fbc0579fe..78e1df2095fb 100644
--- a/include/asm-mips/cobalt/cobalt.h
+++ b/include/asm-mips/cobalt/cobalt.h
@@ -19,18 +19,23 @@
* 9 - PCI
* 14 - IDE0
* 15 - IDE1
- *
+ */
+#define COBALT_QUBE_SLOT_IRQ 9
+
+/*
* CPU IRQs are 16 ... 23
*/
-#define COBALT_TIMER_IRQ 18
-#define COBALT_SCC_IRQ 19 /* pre-production has 85C30 */
-#define COBALT_RAQ_SCSI_IRQ 19
-#define COBALT_ETH0_IRQ 19
-#define COBALT_ETH1_IRQ 20
-#define COBALT_SERIAL_IRQ 21
-#define COBALT_SCSI_IRQ 21
-#define COBALT_VIA_IRQ 22 /* Chained to VIA ISA bridge */
-#define COBALT_QUBE_SLOT_IRQ 23
+#define COBALT_CPU_IRQ 16
+
+#define COBALT_GALILEO_IRQ (COBALT_CPU_IRQ + 2)
+#define COBALT_SCC_IRQ (COBALT_CPU_IRQ + 3) /* pre-production has 85C30 */
+#define COBALT_RAQ_SCSI_IRQ (COBALT_CPU_IRQ + 3)
+#define COBALT_ETH0_IRQ (COBALT_CPU_IRQ + 3)
+#define COBALT_QUBE1_ETH0_IRQ (COBALT_CPU_IRQ + 4)
+#define COBALT_ETH1_IRQ (COBALT_CPU_IRQ + 4)
+#define COBALT_SERIAL_IRQ (COBALT_CPU_IRQ + 5)
+#define COBALT_SCSI_IRQ (COBALT_CPU_IRQ + 5)
+#define COBALT_VIA_IRQ (COBALT_CPU_IRQ + 6) /* Chained to VIA ISA bridge */
/*
* PCI configuration space manifest constants. These are wired into
@@ -69,16 +74,21 @@
* Most of this really should go into a separate GT64111 header file.
*/
#define GT64111_IO_BASE 0x10000000UL
+#define GT64111_IO_END 0x11ffffffUL
+#define GT64111_MEM_BASE 0x12000000UL
+#define GT64111_MEM_END 0x13ffffffUL
#define GT64111_BASE 0x14000000UL
-#define GALILEO_REG(ofs) (KSEG0 + GT64111_BASE + (unsigned long)(ofs))
+#define GALILEO_REG(ofs) CKSEG1ADDR(GT64111_BASE + (unsigned long)(ofs))
#define GALILEO_INL(port) (*(volatile unsigned int *) GALILEO_REG(port))
#define GALILEO_OUTL(val, port) \
do { \
- *(volatile unsigned int *) GALILEO_REG(port) = (port); \
+ *(volatile unsigned int *) GALILEO_REG(port) = (val); \
} while (0)
-#define GALILEO_T0EXP 0x0100
+#define GALILEO_INTR_T0EXP (1 << 8)
+#define GALILEO_INTR_RETRY_CTR (1 << 20)
+
#define GALILEO_ENTC0 0x01
#define GALILEO_SELTC0 0x02
@@ -86,5 +96,21 @@ do { \
GALILEO_OUTL((0x80000000 | (PCI_SLOT (devfn) << 11) | \
(PCI_FUNC (devfn) << 8) | (where)), GT_PCI0_CFGADDR_OFS)
+#define COBALT_LED_PORT (*(volatile unsigned char *) CKSEG1ADDR(0x1c000000))
+# define COBALT_LED_BAR_LEFT (1 << 0) /* Qube */
+# define COBALT_LED_BAR_RIGHT (1 << 1) /* Qube */
+# define COBALT_LED_WEB (1 << 2) /* RaQ */
+# define COBALT_LED_POWER_OFF (1 << 3) /* RaQ */
+# define COBALT_LED_RESET 0x0f
+
+#define COBALT_KEY_PORT ((~*(volatile unsigned int *) CKSEG1ADDR(0x1d000000) >> 24) & COBALT_KEY_MASK)
+# define COBALT_KEY_CLEAR (1 << 1)
+# define COBALT_KEY_LEFT (1 << 2)
+# define COBALT_KEY_UP (1 << 3)
+# define COBALT_KEY_DOWN (1 << 4)
+# define COBALT_KEY_RIGHT (1 << 5)
+# define COBALT_KEY_ENTER (1 << 6)
+# define COBALT_KEY_SELECT (1 << 7)
+# define COBALT_KEY_MASK 0xfe
#endif /* __ASM_COBALT_H */
diff --git a/include/asm-mips/cobalt/mach-gt64120.h b/include/asm-mips/cobalt/mach-gt64120.h
new file mode 100644
index 000000000000..587fc4378f44
--- /dev/null
+++ b/include/asm-mips/cobalt/mach-gt64120.h
@@ -0,0 +1 @@
+/* there's something here ... in the dark */
diff --git a/include/asm-mips/compat.h b/include/asm-mips/compat.h
index 2c084cd4bc0a..35d2604fe69c 100644
--- a/include/asm-mips/compat.h
+++ b/include/asm-mips/compat.h
@@ -15,10 +15,10 @@ typedef s32 compat_clock_t;
typedef s32 compat_suseconds_t;
typedef s32 compat_pid_t;
-typedef u32 __compat_uid_t;
-typedef u32 __compat_gid_t;
-typedef u32 __compat_uid32_t;
-typedef u32 __compat_gid32_t;
+typedef s32 __compat_uid_t;
+typedef s32 __compat_gid_t;
+typedef __compat_uid_t __compat_uid32_t;
+typedef __compat_gid_t __compat_gid32_t;
typedef u32 compat_mode_t;
typedef u32 compat_ino_t;
typedef u32 compat_dev_t;
@@ -54,8 +54,8 @@ struct compat_stat {
compat_ino_t st_ino;
compat_mode_t st_mode;
compat_nlink_t st_nlink;
- __compat_uid32_t st_uid;
- __compat_gid32_t st_gid;
+ __compat_uid_t st_uid;
+ __compat_gid_t st_gid;
compat_dev_t st_rdev;
s32 st_pad2[2];
compat_off_t st_size;
diff --git a/include/asm-mips/cpu-features.h b/include/asm-mips/cpu-features.h
index 9a2de642eee6..03627cfb3e45 100644
--- a/include/asm-mips/cpu-features.h
+++ b/include/asm-mips/cpu-features.h
@@ -4,6 +4,7 @@
* for more details.
*
* Copyright (C) 2003, 2004 Ralf Baechle
+ * Copyright (C) 2004 Maciej W. Rozycki
*/
#ifndef __ASM_CPU_FEATURES_H
#define __ASM_CPU_FEATURES_H
@@ -24,8 +25,19 @@
#ifndef cpu_has_4kex
#define cpu_has_4kex (cpu_data[0].options & MIPS_CPU_4KEX)
#endif
-#ifndef cpu_has_4ktlb
-#define cpu_has_4ktlb (cpu_data[0].options & MIPS_CPU_4KTLB)
+#ifndef cpu_has_3k_cache
+#define cpu_has_3k_cache (cpu_data[0].options & MIPS_CPU_3K_CACHE)
+#endif
+#define cpu_has_6k_cache 0
+#define cpu_has_8k_cache 0
+#ifndef cpu_has_4k_cache
+#define cpu_has_4k_cache (cpu_data[0].options & MIPS_CPU_4K_CACHE)
+#endif
+#ifndef cpu_has_tx39_cache
+#define cpu_has_tx39_cache (cpu_data[0].options & MIPS_CPU_TX39_CACHE)
+#endif
+#ifndef cpu_has_sb1_cache
+#define cpu_has_sb1_cache (cpu_data[0].options & MIPS_CPU_SB1_CACHE)
#endif
#ifndef cpu_has_fpu
#define cpu_has_fpu (cpu_data[0].options & MIPS_CPU_FPU)
@@ -39,9 +51,6 @@
#ifndef cpu_has_watch
#define cpu_has_watch (cpu_data[0].options & MIPS_CPU_WATCH)
#endif
-#ifndef cpu_has_mips16
-#define cpu_has_mips16 (cpu_data[0].options & MIPS_CPU_MIPS16)
-#endif
#ifndef cpu_has_divec
#define cpu_has_divec (cpu_data[0].options & MIPS_CPU_DIVEC)
#endif
@@ -66,6 +75,18 @@
#ifndef cpu_has_llsc
#define cpu_has_llsc (cpu_data[0].options & MIPS_CPU_LLSC)
#endif
+#ifndef cpu_has_mips16
+#define cpu_has_mips16 (cpu_data[0].ases & MIPS_ASE_MIPS16)
+#endif
+#ifndef cpu_has_mdmx
+#define cpu_has_mdmx (cpu_data[0].ases & MIPS_ASE_MDMX)
+#endif
+#ifndef cpu_has_mips3d
+#define cpu_has_mips3d (cpu_data[0].ases & MIPS_ASE_MIPS3D)
+#endif
+#ifndef cpu_has_smartmips
+#define cpu_has_smartmips (cpu_data[0].ases & MIPS_ASE_SMARTMIPS)
+#endif
#ifndef cpu_has_vtag_icache
#define cpu_has_vtag_icache (cpu_data[0].icache.flags & MIPS_CACHE_VTAG)
#endif
@@ -95,15 +116,16 @@
#endif
#endif
-/*
- * Certain CPUs may throw bizarre exceptions if not the whole cacheline
- * contains valid instructions. For these we ensure proper alignment of
- * signal trampolines and pad them to the size of a full cache lines with
- * nops. This is also used in structure definitions so can't be a test macro
- * like the others.
- */
-#ifndef PLAT_TRAMPOLINE_STUFF_LINE
-#define PLAT_TRAMPOLINE_STUFF_LINE 0UL
+#ifndef cpu_has_dsp
+#define cpu_has_dsp (cpu_data[0].ases & MIPS_ASE_DSP)
+#endif
+
+#ifdef CONFIG_MIPS_MT
+#ifndef cpu_has_mipsmt
+# define cpu_has_mipsmt (cpu_data[0].ases & MIPS_ASE_MIPSMT)
+#endif
+#else
+# define cpu_has_mipsmt 0
#endif
#ifdef CONFIG_32BIT
@@ -142,6 +164,22 @@
# endif
#endif
+#ifdef CONFIG_CPU_MIPSR2
+# if defined(CONFIG_CPU_MIPSR2_IRQ_VI) && !defined(cpu_has_vint)
+# define cpu_has_vint (cpu_data[0].options & MIPS_CPU_VINT)
+# else
+# define cpu_has_vint 0
+# endif
+# if defined(CONFIG_CPU_MIPSR2_IRQ_EI) && !defined(cpu_has_veic)
+# define cpu_has_veic (cpu_data[0].options & MIPS_CPU_VEIC)
+# else
+# define cpu_has_veic 0
+# endif
+#else
+# define cpu_has_vint 0
+# define cpu_has_veic 0
+#endif
+
#ifndef cpu_has_subset_pcaches
#define cpu_has_subset_pcaches (cpu_data[0].options & MIPS_CPU_SUBSET_CACHES)
#endif
diff --git a/include/asm-mips/cpu-info.h b/include/asm-mips/cpu-info.h
index 20a35b15a31d..d5cf519f8fcc 100644
--- a/include/asm-mips/cpu-info.h
+++ b/include/asm-mips/cpu-info.h
@@ -7,6 +7,7 @@
* Copyright (C) 1995, 1996, 1997, 1998, 1999, 2001, 2002, 2003 Ralf Baechle
* Copyright (C) 1996 Paul M. Antoine
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2004 Maciej W. Rozycki
*/
#ifndef __ASM_CPU_INFO_H
#define __ASM_CPU_INFO_H
@@ -61,6 +62,7 @@ struct cpuinfo_mips {
* Capability and feature descriptor structure for MIPS CPU
*/
unsigned long options;
+ unsigned long ases;
unsigned int processor_id;
unsigned int fpu_id;
unsigned int cputype;
diff --git a/include/asm-mips/cpu.h b/include/asm-mips/cpu.h
index dec060b49556..48eac296060f 100644
--- a/include/asm-mips/cpu.h
+++ b/include/asm-mips/cpu.h
@@ -3,6 +3,7 @@
* various MIPS cpu types.
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 2004 Maciej W. Rozycki
*/
#ifndef _ASM_CPU_H
#define _ASM_CPU_H
@@ -22,12 +23,17 @@
spec.
*/
-#define PRID_COMP_LEGACY 0x000000
-#define PRID_COMP_MIPS 0x010000
-#define PRID_COMP_BROADCOM 0x020000
-#define PRID_COMP_ALCHEMY 0x030000
-#define PRID_COMP_SIBYTE 0x040000
-#define PRID_COMP_SANDCRAFT 0x050000
+#define PRID_COMP_LEGACY 0x000000
+#define PRID_COMP_MIPS 0x010000
+#define PRID_COMP_BROADCOM 0x020000
+#define PRID_COMP_ALCHEMY 0x030000
+#define PRID_COMP_SIBYTE 0x040000
+#define PRID_COMP_SANDCRAFT 0x050000
+#define PRID_COMP_PHILIPS 0x060000
+#define PRID_COMP_TOSHIBA 0x070000
+#define PRID_COMP_LSI 0x080000
+#define PRID_COMP_LEXRA 0x0b0000
+
/*
* Assigned values for the product ID register. In order to detect a
@@ -46,6 +52,7 @@
#define PRID_IMP_VR41XX 0x0c00
#define PRID_IMP_R12000 0x0e00
#define PRID_IMP_R8000 0x1000
+#define PRID_IMP_PR4450 0x1200
#define PRID_IMP_R4600 0x2000
#define PRID_IMP_R4700 0x2100
#define PRID_IMP_TX39 0x2200
@@ -60,6 +67,13 @@
#define PRID_IMP_RM9000 0x3400
#define PRID_IMP_R5432 0x5400
#define PRID_IMP_R5500 0x5500
+
+#define PRID_IMP_UNKNOWN 0xff00
+
+/*
+ * These are the PRID's for when 23:16 == PRID_COMP_MIPS
+ */
+
#define PRID_IMP_4KC 0x8000
#define PRID_IMP_5KC 0x8100
#define PRID_IMP_20KC 0x8200
@@ -71,14 +85,15 @@
#define PRID_IMP_4KEMPR2 0x9100
#define PRID_IMP_4KSD 0x9200
#define PRID_IMP_24K 0x9300
-
-#define PRID_IMP_UNKNOWN 0xff00
+#define PRID_IMP_34K 0x9500
+#define PRID_IMP_24KE 0x9600
/*
* These are the PRID's for when 23:16 == PRID_COMP_SIBYTE
*/
#define PRID_IMP_SB1 0x0100
+#define PRID_IMP_SB1A 0x1100
/*
* These are the PRID's for when 23:16 == PRID_COMP_SANDCRAFT
@@ -177,7 +192,11 @@
#define CPU_VR4133 56
#define CPU_AU1550 57
#define CPU_24K 58
-#define CPU_LAST 58
+#define CPU_AU1200 59
+#define CPU_34K 60
+#define CPU_PR4450 61
+#define CPU_SB1A 62
+#define CPU_LAST 62
/*
* ISA Level encodings
@@ -200,23 +219,37 @@
* CPU Option encodings
*/
#define MIPS_CPU_TLB 0x00000001 /* CPU has TLB */
-/* Leave a spare bit for variant MMU types... */
-#define MIPS_CPU_4KEX 0x00000004 /* "R4K" exception model */
-#define MIPS_CPU_4KTLB 0x00000008 /* "R4K" TLB handler */
-#define MIPS_CPU_FPU 0x00000010 /* CPU has FPU */
-#define MIPS_CPU_32FPR 0x00000020 /* 32 dbl. prec. FP registers */
-#define MIPS_CPU_COUNTER 0x00000040 /* Cycle count/compare */
-#define MIPS_CPU_WATCH 0x00000080 /* watchpoint registers */
-#define MIPS_CPU_MIPS16 0x00000100 /* code compression */
-#define MIPS_CPU_DIVEC 0x00000200 /* dedicated interrupt vector */
-#define MIPS_CPU_VCE 0x00000400 /* virt. coherence conflict possible */
-#define MIPS_CPU_CACHE_CDEX_P 0x00000800 /* Create_Dirty_Exclusive CACHE op */
-#define MIPS_CPU_CACHE_CDEX_S 0x00001000 /* ... same for seconary cache ... */
-#define MIPS_CPU_MCHECK 0x00002000 /* Machine check exception */
-#define MIPS_CPU_EJTAG 0x00004000 /* EJTAG exception */
-#define MIPS_CPU_NOFPUEX 0x00008000 /* no FPU exception */
-#define MIPS_CPU_LLSC 0x00010000 /* CPU has ll/sc instructions */
-#define MIPS_CPU_SUBSET_CACHES 0x00020000 /* P-cache subset enforced */
-#define MIPS_CPU_PREFETCH 0x00040000 /* CPU has usable prefetch */
+#define MIPS_CPU_4KEX 0x00000002 /* "R4K" exception model */
+#define MIPS_CPU_3K_CACHE 0x00000004 /* R3000-style caches */
+#define MIPS_CPU_4K_CACHE 0x00000008 /* R4000-style caches */
+#define MIPS_CPU_TX39_CACHE 0x00000010 /* TX3900-style caches */
+#define MIPS_CPU_SB1_CACHE 0x00000020 /* SB1-style caches */
+#define MIPS_CPU_FPU 0x00000040 /* CPU has FPU */
+#define MIPS_CPU_32FPR 0x00000080 /* 32 dbl. prec. FP registers */
+#define MIPS_CPU_COUNTER 0x00000100 /* Cycle count/compare */
+#define MIPS_CPU_WATCH 0x00000200 /* watchpoint registers */
+#define MIPS_CPU_DIVEC 0x00000400 /* dedicated interrupt vector */
+#define MIPS_CPU_VCE 0x00000800 /* virt. coherence conflict possible */
+#define MIPS_CPU_CACHE_CDEX_P 0x00001000 /* Create_Dirty_Exclusive CACHE op */
+#define MIPS_CPU_CACHE_CDEX_S 0x00002000 /* ... same for seconary cache ... */
+#define MIPS_CPU_MCHECK 0x00004000 /* Machine check exception */
+#define MIPS_CPU_EJTAG 0x00008000 /* EJTAG exception */
+#define MIPS_CPU_NOFPUEX 0x00010000 /* no FPU exception */
+#define MIPS_CPU_LLSC 0x00020000 /* CPU has ll/sc instructions */
+#define MIPS_CPU_SUBSET_CACHES 0x00040000 /* P-cache subset enforced */
+#define MIPS_CPU_PREFETCH 0x00080000 /* CPU has usable prefetch */
+#define MIPS_CPU_VINT 0x00100000 /* CPU supports MIPSR2 vectored interrupts */
+#define MIPS_CPU_VEIC 0x00200000 /* CPU supports MIPSR2 external interrupt controller mode */
+
+/*
+ * CPU ASE encodings
+ */
+#define MIPS_ASE_MIPS16 0x00000001 /* code compression */
+#define MIPS_ASE_MDMX 0x00000002 /* MIPS digital media extension */
+#define MIPS_ASE_MIPS3D 0x00000004 /* MIPS-3D */
+#define MIPS_ASE_SMARTMIPS 0x00000008 /* SmartMIPS */
+#define MIPS_ASE_DSP 0x00000010 /* Signal Processing ASE */
+#define MIPS_ASE_MIPSMT 0x00000020 /* CPU supports MIPS MT */
+
#endif /* _ASM_CPU_H */
diff --git a/include/asm-mips/dec/ecc.h b/include/asm-mips/dec/ecc.h
index 724908b0bf13..19495a490e72 100644
--- a/include/asm-mips/dec/ecc.h
+++ b/include/asm-mips/dec/ecc.h
@@ -49,7 +49,8 @@ struct pt_regs;
extern void dec_ecc_be_init(void);
extern int dec_ecc_be_handler(struct pt_regs *regs, int is_fixup);
-extern irqreturn_t dec_ecc_be_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+extern irqreturn_t dec_ecc_be_interrupt(int irq, void *dev_id,
+ struct pt_regs *regs);
#endif
#endif /* __ASM_MIPS_DEC_ECC_H */
diff --git a/include/asm-mips/dec/ioasic_addrs.h b/include/asm-mips/dec/ioasic_addrs.h
index 5e18a7510592..4cbc1f8a1129 100644
--- a/include/asm-mips/dec/ioasic_addrs.h
+++ b/include/asm-mips/dec/ioasic_addrs.h
@@ -45,7 +45,8 @@
/*
- * Offsets for I/O ASIC registers (relative to (system_base + IOASIC_IOCTL)).
+ * Offsets for I/O ASIC registers
+ * (relative to (dec_kn_slot_base + IOASIC_IOCTL)).
*/
/* all systems */
#define IO_REG_SCSI_DMA_P 0x00 /* SCSI DMA Pointer */
diff --git a/include/asm-mips/dec/kn01.h b/include/asm-mips/dec/kn01.h
index 946943502f83..eb522aa1e226 100644
--- a/include/asm-mips/dec/kn01.h
+++ b/include/asm-mips/dec/kn01.h
@@ -8,14 +8,12 @@
*
* Copyright (C) 1995,1996 by Paul M. Antoine, some code and definitions
* are by courtesy of Chris Fraser.
- * Copyright (C) 2002, 2003 Maciej W. Rozycki
+ * Copyright (C) 2002, 2003, 2005 Maciej W. Rozycki
*/
#ifndef __ASM_MIPS_DEC_KN01_H
#define __ASM_MIPS_DEC_KN01_H
-#include <asm/addrspace.h>
-
-#define KN01_SLOT_BASE KSEG1ADDR(0x10000000)
+#define KN01_SLOT_BASE 0x10000000
#define KN01_SLOT_SIZE 0x01000000
/*
@@ -41,17 +39,9 @@
/*
- * Some port addresses...
- */
-#define KN01_LANCE_BASE (KN01_SLOT_BASE + KN01_LANCE) /* 0xB8000000 */
-#define KN01_DZ11_BASE (KN01_SLOT_BASE + KN01_DZ11) /* 0xBC000000 */
-#define KN01_RTC_BASE (KN01_SLOT_BASE + KN01_RTC) /* 0xBD000000 */
-
-
-/*
* Frame buffer memory address.
*/
-#define KN01_VFB_MEM KSEG1ADDR(0x0fc00000)
+#define KN01_VFB_MEM 0x0fc00000
/*
* CPU interrupt bits.
@@ -80,4 +70,22 @@
#define KN01_CSR_VRGTRB (1<<0) /* red DAC voltage over blue (r/o) */
#define KN01_CSR_LEDS (0xff<<0) /* ~diagnostic LEDs (w/o) */
+
+#ifndef __ASSEMBLY__
+
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+struct pt_regs;
+
+extern u16 cached_kn01_csr;
+extern spinlock_t kn01_lock;
+
+extern void dec_kn01_be_init(void);
+extern int dec_kn01_be_handler(struct pt_regs *regs, int is_fixup);
+extern irqreturn_t dec_kn01_be_interrupt(int irq, void *dev_id,
+ struct pt_regs *regs);
+#endif
+
#endif /* __ASM_MIPS_DEC_KN01_H */
diff --git a/include/asm-mips/dec/kn02.h b/include/asm-mips/dec/kn02.h
index f797f7045920..8319ad77b250 100644
--- a/include/asm-mips/dec/kn02.h
+++ b/include/asm-mips/dec/kn02.h
@@ -8,21 +8,12 @@
*
* Copyright (C) 1995,1996 by Paul M. Antoine, some code and definitions
* are by courtesy of Chris Fraser.
- * Copyright (C) 2002, 2003 Maciej W. Rozycki
+ * Copyright (C) 2002, 2003, 2005 Maciej W. Rozycki
*/
#ifndef __ASM_MIPS_DEC_KN02_H
#define __ASM_MIPS_DEC_KN02_H
-#ifndef __ASSEMBLY__
-#include <linux/spinlock.h>
-#include <linux/types.h>
-#endif
-
-#include <asm/addrspace.h>
-#include <asm/dec/ecc.h>
-
-
-#define KN02_SLOT_BASE KSEG1ADDR(0x1fc00000)
+#define KN02_SLOT_BASE 0x1fc00000
#define KN02_SLOT_SIZE 0x00080000
/*
@@ -39,22 +30,14 @@
/*
- * Some port addresses...
- */
-#define KN02_DZ11_BASE (KN02_SLOT_BASE + KN02_DZ11) /* DZ11 */
-#define KN02_RTC_BASE (KN02_SLOT_BASE + KN02_RTC) /* RTC */
-#define KN02_CSR_BASE (KN02_SLOT_BASE + KN02_CSR) /* CSR */
-
-
-/*
* System Control & Status Register bits.
*/
#define KN02_CSR_RES_28 (0xf<<28) /* unused */
#define KN02_CSR_PSU (1<<27) /* power supply unit warning */
#define KN02_CSR_NVRAM (1<<26) /* ~NVRAM clear jumper */
#define KN02_CSR_REFEVEN (1<<25) /* mem refresh bank toggle */
-#define KN03_CSR_NRMOD (1<<24) /* ~NRMOD manufact. jumper */
-#define KN03_CSR_IOINTEN (0xff<<16) /* IRQ mask bits */
+#define KN02_CSR_NRMOD (1<<24) /* ~NRMOD manufact. jumper */
+#define KN02_CSR_IOINTEN (0xff<<16) /* IRQ mask bits */
#define KN02_CSR_DIAGCHK (1<<15) /* diagn/norml ECC reads */
#define KN02_CSR_DIAGGEN (1<<14) /* diagn/norml ECC writes */
#define KN02_CSR_CORRECT (1<<13) /* ECC correct/check */
@@ -63,8 +46,8 @@
#define KN02_CSR_BNK32M (1<<10) /* 32M/8M stride */
#define KN02_CSR_DIAGDN (1<<9) /* DIAGDN manufact. jumper */
#define KN02_CSR_BAUD38 (1<<8) /* DZ11 38/19kbps ext. rate */
-#define KN03_CSR_IOINT (0xff<<0) /* IRQ status bits (r/o) */
-#define KN03_CSR_LEDS (0xff<<0) /* ~diagnostic LEDs (w/o) */
+#define KN02_CSR_IOINT (0xff<<0) /* IRQ status bits (r/o) */
+#define KN02_CSR_LEDS (0xff<<0) /* ~diagnostic LEDs (w/o) */
/*
@@ -98,6 +81,10 @@
#ifndef __ASSEMBLY__
+
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
extern u32 cached_kn02_csr;
extern spinlock_t kn02_lock;
extern void init_kn02_irqs(int base);
diff --git a/include/asm-mips/dec/kn02xa.h b/include/asm-mips/dec/kn02xa.h
index 648c4dcbba1d..a25f3d7da7f7 100644
--- a/include/asm-mips/dec/kn02xa.h
+++ b/include/asm-mips/dec/kn02xa.h
@@ -9,7 +9,7 @@
*
* Copyright (C) 1995,1996 by Paul M. Antoine, some code and definitions
* are by courtesy of Chris Fraser.
- * Copyright (C) 2000, 2002, 2003 Maciej W. Rozycki
+ * Copyright (C) 2000, 2002, 2003, 2005 Maciej W. Rozycki
*
* These are addresses which have to be known early in the boot process.
* For other addresses refer to tc.h, ioasic_addrs.h and friends.
@@ -17,31 +17,23 @@
#ifndef __ASM_MIPS_DEC_KN02XA_H
#define __ASM_MIPS_DEC_KN02XA_H
-#include <asm/addrspace.h>
#include <asm/dec/ioasic_addrs.h>
-#define KN02XA_SLOT_BASE KSEG1ADDR(0x1c000000)
-
-/*
- * Some port addresses...
- */
-#define KN02XA_IOASIC_BASE (KN02XA_SLOT_BASE + IOASIC_IOCTL) /* I/O ASIC */
-#define KN02XA_RTC_BASE (KN02XA_SLOT_BASE + IOASIC_TOY) /* RTC */
-
+#define KN02XA_SLOT_BASE 0x1c000000
/*
* Memory control ASIC registers.
*/
-#define KN02XA_MER KSEG1ADDR(0x0c400000) /* memory error register */
-#define KN02XA_MSR KSEG1ADDR(0x0c800000) /* memory size register */
+#define KN02XA_MER 0x0c400000 /* memory error register */
+#define KN02XA_MSR 0x0c800000 /* memory size register */
/*
* CPU control ASIC registers.
*/
-#define KN02XA_MEM_CONF KSEG1ADDR(0x0e000000) /* write timeout config */
-#define KN02XA_EAR KSEG1ADDR(0x0e000004) /* error address register */
-#define KN02XA_BOOT0 KSEG1ADDR(0x0e000008) /* boot 0 register */
-#define KN02XA_MEM_INTR KSEG1ADDR(0x0e00000c) /* write err IRQ stat & ack */
+#define KN02XA_MEM_CONF 0x0e000000 /* write timeout config */
+#define KN02XA_EAR 0x0e000004 /* error address register */
+#define KN02XA_BOOT0 0x0e000008 /* boot 0 register */
+#define KN02XA_MEM_INTR 0x0e00000c /* write err IRQ stat & ack */
/*
* Memory Error Register bits, common definitions.
@@ -52,8 +44,13 @@
#define KN02XA_MER_PAGERR (1<<16) /* 2k page boundary error */
#define KN02XA_MER_TRANSERR (1<<15) /* transfer length error */
#define KN02XA_MER_PARDIS (1<<14) /* parity error disable */
-#define KN02XA_MER_RES_12 (0x3<<12) /* unused */
-#define KN02XA_MER_BYTERR (0xf<<8) /* byte lane error bitmask */
+#define KN02XA_MER_SIZE (1<<13) /* r/o mirror of MSR_SIZE */
+#define KN02XA_MER_RES_12 (1<<12) /* unused */
+#define KN02XA_MER_BYTERR (0xf<<8) /* byte lane error bitmask: */
+#define KN02XA_MER_BYTERR_3 (0x8<<8) /* byte lane #3 */
+#define KN02XA_MER_BYTERR_2 (0x4<<8) /* byte lane #2 */
+#define KN02XA_MER_BYTERR_1 (0x2<<8) /* byte lane #1 */
+#define KN02XA_MER_BYTERR_0 (0x1<<8) /* byte lane #0 */
#define KN02XA_MER_RES_0 (0xff<<0) /* unused */
/*
@@ -72,4 +69,17 @@
#define KN02XA_EAR_ADDRESS (0x7ffffff<<2) /* address involved */
#define KN02XA_EAR_RES_0 (0x3<<0) /* unused */
+
+#ifndef __ASSEMBLY__
+
+#include <linux/interrupt.h>
+
+struct pt_regs;
+
+extern void dec_kn02xa_be_init(void);
+extern int dec_kn02xa_be_handler(struct pt_regs *regs, int is_fixup);
+extern irqreturn_t dec_kn02xa_be_interrupt(int irq, void *dev_id,
+ struct pt_regs *regs);
+#endif
+
#endif /* __ASM_MIPS_DEC_KN02XA_H */
diff --git a/include/asm-mips/dec/kn03.h b/include/asm-mips/dec/kn03.h
index 676abd17c6a4..edede923ffb8 100644
--- a/include/asm-mips/dec/kn03.h
+++ b/include/asm-mips/dec/kn03.h
@@ -10,24 +10,15 @@
*
* Copyright (C) 1995,1996 by Paul M. Antoine, some code and definitions
* are by courtesy of Chris Fraser.
- * Copyright (C) 2000, 2002, 2003 Maciej W. Rozycki
+ * Copyright (C) 2000, 2002, 2003, 2005 Maciej W. Rozycki
*/
#ifndef __ASM_MIPS_DEC_KN03_H
#define __ASM_MIPS_DEC_KN03_H
-#include <asm/addrspace.h>
#include <asm/dec/ecc.h>
#include <asm/dec/ioasic_addrs.h>
-#define KN03_SLOT_BASE KSEG1ADDR(0x1f800000)
-
-/*
- * Some port addresses...
- */
-#define KN03_IOASIC_BASE (KN03_SLOT_BASE + IOASIC_IOCTL) /* I/O ASIC */
-#define KN03_RTC_BASE (KN03_SLOT_BASE + IOASIC_TOY) /* RTC */
-#define KN03_MCR_BASE (KN03_SLOT_BASE + IOASIC_MCR) /* MCR */
-
+#define KN03_SLOT_BASE 0x1f800000
/*
* CPU interrupt bits.
diff --git a/include/asm-mips/dec/kn05.h b/include/asm-mips/dec/kn05.h
index b120362b8f13..15fe8f881e60 100644
--- a/include/asm-mips/dec/kn05.h
+++ b/include/asm-mips/dec/kn05.h
@@ -1,10 +1,12 @@
/*
* include/asm-mips/dec/kn05.h
*
- * DECstation 5000/260 (4max+ or KN05) and DECsystem 5900/260
+ * DECstation/DECsystem 5000/260 (4max+ or KN05), 5000/150 (4min
+ * or KN04-BA), Personal DECstation/DECsystem 5000/50 (4maxine or
+ * KN04-CA) and DECsystem 5900/260 (KN05) R4k CPU card MB ASIC
* definitions.
*
- * Copyright (C) 2002, 2003 Maciej W. Rozycki
+ * Copyright (C) 2002, 2003, 2005 Maciej W. Rozycki
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -13,8 +15,8 @@
*
* WARNING! All this information is pure guesswork based on the
* ROM. It is provided here in hope it will give someone some
- * food for thought. No documentation for the KN05 module has
- * been located so far.
+ * food for thought. No documentation for the KN05 nor the KN04
+ * module has been located so far.
*/
#ifndef __ASM_MIPS_DEC_KN05_H
#define __ASM_MIPS_DEC_KN05_H
@@ -24,48 +26,50 @@
/*
* The oncard MB (Memory Buffer) ASIC provides an additional address
* decoder. Certain address ranges within the "high" 16 slots are
- * passed to the I/O ASIC's decoder like with the KN03. Others are
- * handled locally. "Low" slots are always passed.
+ * passed to the I/O ASIC's decoder like with the KN03 or KN02-BA/CA.
+ * Others are handled locally. "Low" slots are always passed.
*/
-#define KN05_MB_ROM (16*IOASIC_SLOT_SIZE) /* KN05 card ROM */
-#define KN05_IOCTL (17*IOASIC_SLOT_SIZE) /* I/O ASIC */
-#define KN05_ESAR (18*IOASIC_SLOT_SIZE) /* LANCE MAC address chip */
-#define KN05_LANCE (19*IOASIC_SLOT_SIZE) /* LANCE Ethernet */
-#define KN05_MB_INT (20*IOASIC_SLOT_SIZE) /* MB interrupt register */
-#define KN05_MB_EA (21*IOASIC_SLOT_SIZE) /* MB error address? */
-#define KN05_MB_EC (22*IOASIC_SLOT_SIZE) /* MB error ??? */
-#define KN05_MB_CSR (23*IOASIC_SLOT_SIZE) /* MB control & status */
-#define KN05_RES_24 (24*IOASIC_SLOT_SIZE) /* unused? */
-#define KN05_RES_25 (25*IOASIC_SLOT_SIZE) /* unused? */
-#define KN05_RES_26 (26*IOASIC_SLOT_SIZE) /* unused? */
-#define KN05_RES_27 (27*IOASIC_SLOT_SIZE) /* unused? */
-#define KN05_SCSI (28*IOASIC_SLOT_SIZE) /* ASC SCSI */
-#define KN05_RES_29 (29*IOASIC_SLOT_SIZE) /* unused? */
-#define KN05_RES_30 (30*IOASIC_SLOT_SIZE) /* unused? */
-#define KN05_RES_31 (31*IOASIC_SLOT_SIZE) /* unused? */
+#define KN4K_SLOT_BASE 0x1fc00000
+
+#define KN4K_MB_ROM (0*IOASIC_SLOT_SIZE) /* KN05/KN04 card ROM */
+#define KN4K_IOCTL (1*IOASIC_SLOT_SIZE) /* I/O ASIC */
+#define KN4K_ESAR (2*IOASIC_SLOT_SIZE) /* LANCE MAC address chip */
+#define KN4K_LANCE (3*IOASIC_SLOT_SIZE) /* LANCE Ethernet */
+#define KN4K_MB_INT (4*IOASIC_SLOT_SIZE) /* MB interrupt register */
+#define KN4K_MB_EA (5*IOASIC_SLOT_SIZE) /* MB error address? */
+#define KN4K_MB_EC (6*IOASIC_SLOT_SIZE) /* MB error ??? */
+#define KN4K_MB_CSR (7*IOASIC_SLOT_SIZE) /* MB control & status */
+#define KN4K_RES_08 (8*IOASIC_SLOT_SIZE) /* unused? */
+#define KN4K_RES_09 (9*IOASIC_SLOT_SIZE) /* unused? */
+#define KN4K_RES_10 (10*IOASIC_SLOT_SIZE) /* unused? */
+#define KN4K_RES_11 (11*IOASIC_SLOT_SIZE) /* unused? */
+#define KN4K_SCSI (12*IOASIC_SLOT_SIZE) /* ASC SCSI */
+#define KN4K_RES_13 (13*IOASIC_SLOT_SIZE) /* unused? */
+#define KN4K_RES_14 (14*IOASIC_SLOT_SIZE) /* unused? */
+#define KN4K_RES_15 (15*IOASIC_SLOT_SIZE) /* unused? */
/*
* Bits for the MB interrupt register.
* The register appears read-only.
*/
-#define KN05_MB_INT_TC (1<<0) /* TURBOchannel? */
-#define KN05_MB_INT_RTC (1<<1) /* RTC? */
-#define KN05_MB_INT_MT (1<<3) /* ??? */
+#define KN4K_MB_INT_TC (1<<0) /* TURBOchannel? */
+#define KN4K_MB_INT_RTC (1<<1) /* RTC? */
+#define KN4K_MB_INT_MT (1<<3) /* ??? */
/*
* Bits for the MB control & status register.
* Set to 0x00bf8001 on my system by the ROM.
*/
-#define KN05_MB_CSR_PF (1<<0) /* PreFetching enable? */
-#define KN05_MB_CSR_F (1<<1) /* ??? */
-#define KN05_MB_CSR_ECC (0xff<<2) /* ??? */
-#define KN05_MB_CSR_OD (1<<10) /* ??? */
-#define KN05_MB_CSR_CP (1<<11) /* ??? */
-#define KN05_MB_CSR_UNC (1<<12) /* ??? */
-#define KN05_MB_CSR_IM (1<<13) /* ??? */
-#define KN05_MB_CSR_NC (1<<14) /* ??? */
-#define KN05_MB_CSR_EE (1<<15) /* (bus) Exception Enable? */
-#define KN05_MB_CSR_MSK (0x1f<<16) /* ??? */
-#define KN05_MB_CSR_FW (1<<21) /* ??? */
+#define KN4K_MB_CSR_PF (1<<0) /* PreFetching enable? */
+#define KN4K_MB_CSR_F (1<<1) /* ??? */
+#define KN4K_MB_CSR_ECC (0xff<<2) /* ??? */
+#define KN4K_MB_CSR_OD (1<<10) /* ??? */
+#define KN4K_MB_CSR_CP (1<<11) /* ??? */
+#define KN4K_MB_CSR_UNC (1<<12) /* ??? */
+#define KN4K_MB_CSR_IM (1<<13) /* ??? */
+#define KN4K_MB_CSR_NC (1<<14) /* ??? */
+#define KN4K_MB_CSR_EE (1<<15) /* (bus) Exception Enable? */
+#define KN4K_MB_CSR_MSK (0x1f<<16) /* ??? */
+#define KN4K_MB_CSR_FW (1<<21) /* ??? */
#endif /* __ASM_MIPS_DEC_KN05_H */
diff --git a/include/asm-mips/dec/prom.h b/include/asm-mips/dec/prom.h
index a05d6d3395fe..1384dd0964b9 100644
--- a/include/asm-mips/dec/prom.h
+++ b/include/asm-mips/dec/prom.h
@@ -24,7 +24,7 @@
* PMAX/3MAX PROM entry points for DS2100/3100's and DS5000/2xx's.
* Many of these will work for MIPSen as well!
*/
-#define VEC_RESET (u64 *)KSEG1ADDR(0x1fc00000)
+#define VEC_RESET (u64 *)CKSEG1ADDR(0x1fc00000)
/* Prom base address */
#define PMAX_PROM_ENTRY(x) (VEC_RESET + (x)) /* Prom jump table */
@@ -111,19 +111,21 @@ extern int (*__pmax_close)(int);
* On MIPS64 we have to call PROM functions via a helper
* dispatcher to accomodate ABI incompatibilities.
*/
-#define __DEC_PROM_O32 __attribute__((alias("call_o32")))
-
-int _rex_bootinit(int (*)(void)) __DEC_PROM_O32;
-int _rex_bootread(int (*)(void)) __DEC_PROM_O32;
-int _rex_getbitmap(int (*)(memmap *), memmap *) __DEC_PROM_O32;
-unsigned long *_rex_slot_address(unsigned long *(*)(int), int) __DEC_PROM_O32;
-void *_rex_gettcinfo(void *(*)(void)) __DEC_PROM_O32;
-int _rex_getsysid(int (*)(void)) __DEC_PROM_O32;
-void _rex_clear_cache(void (*)(void)) __DEC_PROM_O32;
-
-int _prom_getchar(int (*)(void)) __DEC_PROM_O32;
-char *_prom_getenv(char *(*)(char *), char *) __DEC_PROM_O32;
-int _prom_printf(int (*)(char *, ...), char *, ...) __DEC_PROM_O32;
+#define __DEC_PROM_O32(fun, arg) fun arg __asm__(#fun); \
+ __asm__(#fun " = call_o32")
+
+int __DEC_PROM_O32(_rex_bootinit, (int (*)(void)));
+int __DEC_PROM_O32(_rex_bootread, (int (*)(void)));
+int __DEC_PROM_O32(_rex_getbitmap, (int (*)(memmap *), memmap *));
+unsigned long *__DEC_PROM_O32(_rex_slot_address,
+ (unsigned long *(*)(int), int));
+void *__DEC_PROM_O32(_rex_gettcinfo, (void *(*)(void)));
+int __DEC_PROM_O32(_rex_getsysid, (int (*)(void)));
+void __DEC_PROM_O32(_rex_clear_cache, (void (*)(void)));
+
+int __DEC_PROM_O32(_prom_getchar, (int (*)(void)));
+char *__DEC_PROM_O32(_prom_getenv, (char *(*)(char *), char *));
+int __DEC_PROM_O32(_prom_printf, (int (*)(char *, ...), char *, ...));
#define rex_bootinit() _rex_bootinit(__rex_bootinit)
diff --git a/include/asm-mips/dec/system.h b/include/asm-mips/dec/system.h
new file mode 100644
index 000000000000..78af51fbc797
--- /dev/null
+++ b/include/asm-mips/dec/system.h
@@ -0,0 +1,18 @@
+/*
+ * include/asm-mips/dec/system.h
+ *
+ * Generic DECstation/DECsystem bits.
+ *
+ * Copyright (C) 2005 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute 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_DEC_SYSTEM_H
+#define __ASM_DEC_SYSTEM_H
+
+extern unsigned long dec_kn_slot_base, dec_kn_slot_size;
+
+#endif /* __ASM_DEC_SYSTEM_H */
diff --git a/include/asm-mips/dec/tc.h b/include/asm-mips/dec/tc.h
index d7bba43f863a..9cb51f24d42c 100644
--- a/include/asm-mips/dec/tc.h
+++ b/include/asm-mips/dec/tc.h
@@ -7,10 +7,8 @@
*
* Copyright (c) 1998 Harald Koerfgen
*/
-#ifndef ASM_TC_H
-#define ASM_TC_H
-
-extern unsigned long system_base;
+#ifndef __ASM_DEC_TC_H
+#define __ASM_DEC_TC_H
/*
* Search for a TURBOchannel Option Module
@@ -36,8 +34,8 @@ extern unsigned long get_tc_base_addr(int);
*/
extern unsigned long get_tc_irq_nr(int);
/*
- * Return TURBOchannel clock frequency in hz
+ * Return TURBOchannel clock frequency in Hz
*/
extern unsigned long get_tc_speed(void);
-#endif
+#endif /* __ASM_DEC_TC_H */
diff --git a/include/asm-mips/delay.h b/include/asm-mips/delay.h
index a606dbee0412..85435a8d4e52 100644
--- a/include/asm-mips/delay.h
+++ b/include/asm-mips/delay.h
@@ -12,11 +12,9 @@
#include <linux/config.h>
#include <linux/param.h>
-
+#include <linux/smp.h>
#include <asm/compiler.h>
-extern unsigned long loops_per_jiffy;
-
static inline void __delay(unsigned long loops)
{
if (sizeof(long) == 4)
@@ -82,11 +80,7 @@ static inline void __udelay(unsigned long usecs, unsigned long lpj)
__delay(usecs);
}
-#ifdef CONFIG_SMP
#define __udelay_val cpu_data[smp_processor_id()].udelay_val
-#else
-#define __udelay_val loops_per_jiffy
-#endif
#define udelay(usecs) __udelay((usecs),__udelay_val)
diff --git a/include/asm-mips/dsp.h b/include/asm-mips/dsp.h
new file mode 100644
index 000000000000..50f556bb4978
--- /dev/null
+++ b/include/asm-mips/dsp.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2005 Mips Technologies
+ * Author: Chris Dearman, chris@mips.com derived from fpu.h
+ *
+ * This program is free software; you can redistribute 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_DSP_H
+#define _ASM_DSP_H
+
+#include <asm/cpu.h>
+#include <asm/cpu-features.h>
+#include <asm/hazards.h>
+#include <asm/mipsregs.h>
+
+#define DSP_DEFAULT 0x00000000
+#define DSP_MASK 0x1f
+
+#define __enable_dsp_hazard() \
+do { \
+ asm("_ehb"); \
+} while (0)
+
+static inline void __init_dsp(void)
+{
+ mthi1(0);
+ mtlo1(0);
+ mthi2(0);
+ mtlo2(0);
+ mthi3(0);
+ mtlo3(0);
+ wrdsp(DSP_DEFAULT, DSP_MASK);
+}
+
+static inline void init_dsp(void)
+{
+ if (cpu_has_dsp)
+ __init_dsp();
+}
+
+#define __save_dsp(tsk) \
+do { \
+ tsk->thread.dsp.dspr[0] = mfhi1(); \
+ tsk->thread.dsp.dspr[1] = mflo1(); \
+ tsk->thread.dsp.dspr[2] = mfhi2(); \
+ tsk->thread.dsp.dspr[3] = mflo2(); \
+ tsk->thread.dsp.dspr[4] = mfhi3(); \
+ tsk->thread.dsp.dspr[5] = mflo3(); \
+} while (0)
+
+#define save_dsp(tsk) \
+do { \
+ if (cpu_has_dsp) \
+ __save_dsp(tsk); \
+} while (0)
+
+#define __restore_dsp(tsk) \
+do { \
+ mthi1(tsk->thread.dsp.dspr[0]); \
+ mtlo1(tsk->thread.dsp.dspr[1]); \
+ mthi2(tsk->thread.dsp.dspr[2]); \
+ mtlo2(tsk->thread.dsp.dspr[3]); \
+ mthi3(tsk->thread.dsp.dspr[4]); \
+ mtlo3(tsk->thread.dsp.dspr[5]); \
+} while (0)
+
+#define restore_dsp(tsk) \
+do { \
+ if (cpu_has_dsp) \
+ __restore_dsp(tsk); \
+} while (0)
+
+#define __get_dsp_regs(tsk) \
+({ \
+ if (tsk == current) \
+ __save_dsp(current); \
+ \
+ tsk->thread.dsp.dspr; \
+})
+
+#endif /* _ASM_DSP_H */
diff --git a/include/asm-mips/elf.h b/include/asm-mips/elf.h
index e48811440015..7420f12742bb 100644
--- a/include/asm-mips/elf.h
+++ b/include/asm-mips/elf.h
@@ -2,6 +2,8 @@
* 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.
+ *
+ * Much of this is taken from binutils and GNU libc ...
*/
#ifndef _ASM_ELF_H
#define _ASM_ELF_H
@@ -17,6 +19,8 @@
#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */
#define EF_MIPS_ARCH_32 0x50000000 /* MIPS32 code. */
#define EF_MIPS_ARCH_64 0x60000000 /* MIPS64 code. */
+#define EF_MIPS_ARCH_32R2 0x70000000 /* MIPS32 R2 code. */
+#define EF_MIPS_ARCH_64R2 0x80000000 /* MIPS64 R2 code. */
/* The ABI of a file. */
#define EF_MIPS_ABI_O32 0x00001000 /* O32 ABI. */
@@ -105,7 +109,11 @@
#define R_MIPS_LOVENDOR 100
#define R_MIPS_HIVENDOR 127
-#define SHN_MIPS_ACCOMON 0xff00
+#define SHN_MIPS_ACCOMON 0xff00 /* Allocated common symbols */
+#define SHN_MIPS_TEXT 0xff01 /* Allocated test symbols. */
+#define SHN_MIPS_DATA 0xff02 /* Allocated data symbols. */
+#define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols */
+#define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols */
#define SHT_MIPS_LIST 0x70000000
#define SHT_MIPS_CONFLICT 0x70000002
@@ -193,50 +201,92 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
#ifdef __KERNEL__
+struct mips_abi;
+
+extern struct mips_abi mips_abi;
+extern struct mips_abi mips_abi_32;
+extern struct mips_abi mips_abi_n32;
+
#ifdef CONFIG_32BIT
-#define SET_PERSONALITY(ex, ibcs2) \
-do { \
- if (ibcs2) \
- set_personality(PER_SVR4); \
- set_personality(PER_LINUX); \
+#define SET_PERSONALITY(ex, ibcs2) \
+do { \
+ if (ibcs2) \
+ set_personality(PER_SVR4); \
+ set_personality(PER_LINUX); \
+ \
+ current->thread.abi = &mips_abi; \
} while (0)
#endif /* CONFIG_32BIT */
#ifdef CONFIG_64BIT
-#define SET_PERSONALITY(ex, ibcs2) \
-do { current->thread.mflags &= ~MF_ABI_MASK; \
- if ((ex).e_ident[EI_CLASS] == ELFCLASS32) { \
- if ((((ex).e_flags & EF_MIPS_ABI2) != 0) && \
- ((ex).e_flags & EF_MIPS_ABI) == 0) \
- current->thread.mflags |= MF_N32; \
- else \
- current->thread.mflags |= MF_O32; \
- } else \
- current->thread.mflags |= MF_N64; \
- if (ibcs2) \
- set_personality(PER_SVR4); \
- else if (current->personality != PER_LINUX32) \
- set_personality(PER_LINUX); \
+#ifdef CONFIG_MIPS32_N32
+#define __SET_PERSONALITY32_N32() \
+ do { \
+ current->thread.mflags |= MF_N32; \
+ current->thread.abi = &mips_abi_n32; \
+ } while (0)
+#else
+#define __SET_PERSONALITY32_N32() \
+ do { } while (0)
+#endif
+
+#ifdef CONFIG_MIPS32_O32
+#define __SET_PERSONALITY32_O32() \
+ do { \
+ current->thread.mflags |= MF_O32; \
+ current->thread.abi = &mips_abi_32; \
+ } while (0)
+#else
+#define __SET_PERSONALITY32_O32() \
+ do { } while (0)
+#endif
+
+#ifdef CONFIG_MIPS32_COMPAT
+#define __SET_PERSONALITY32(ex) \
+do { \
+ if ((((ex).e_flags & EF_MIPS_ABI2) != 0) && \
+ ((ex).e_flags & EF_MIPS_ABI) == 0) \
+ __SET_PERSONALITY32_N32(); \
+ else \
+ __SET_PERSONALITY32_O32(); \
+} while (0)
+#else
+#define __SET_PERSONALITY32(ex) do { } while (0)
+#endif
+
+#define SET_PERSONALITY(ex, ibcs2) \
+do { \
+ current->thread.mflags &= ~MF_ABI_MASK; \
+ if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
+ __SET_PERSONALITY32(ex); \
+ else { \
+ current->thread.mflags |= MF_N64; \
+ current->thread.abi = &mips_abi; \
+ } \
+ \
+ if (ibcs2) \
+ set_personality(PER_SVR4); \
+ else if (current->personality != PER_LINUX32) \
+ set_personality(PER_LINUX); \
} while (0)
#endif /* CONFIG_64BIT */
extern void dump_regs(elf_greg_t *, struct pt_regs *regs);
+extern int dump_task_regs (struct task_struct *, elf_gregset_t *);
extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *);
#define ELF_CORE_COPY_REGS(elf_regs, regs) \
dump_regs((elf_greg_t *)&(elf_regs), regs);
+#define ELF_CORE_COPY_TASK_REGS(tsk, elf_regs) dump_task_regs(tsk, elf_regs)
#define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) \
dump_task_fpu(tsk, elf_fpregs)
#endif /* __KERNEL__ */
-/* This one accepts IRIX binaries. */
-#define irix_elf_check_arch(hdr) ((hdr)->e_flags & RHF_SGI_ONLY)
-
#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE PAGE_SIZE
diff --git a/include/asm-mips/errno.h b/include/asm-mips/errno.h
index 3c0d840e4577..9d3e6e7cdb92 100644
--- a/include/asm-mips/errno.h
+++ b/include/asm-mips/errno.h
@@ -119,6 +119,10 @@
#define EOWNERDEAD 165 /* Owner died */
#define ENOTRECOVERABLE 166 /* State not recoverable */
+/* for robust mutexes */
+#define EOWNERDEAD 165 /* Owner died */
+#define ENOTRECOVERABLE 166 /* State not recoverable */
+
#define EDQUOT 1133 /* Quota exceeded */
#ifdef __KERNEL__
diff --git a/include/asm-mips/fcntl.h b/include/asm-mips/fcntl.h
index 06c5d13faf66..43d047a9a6af 100644
--- a/include/asm-mips/fcntl.h
+++ b/include/asm-mips/fcntl.h
@@ -3,11 +3,13 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 1995, 96, 97, 98, 99, 2003 Ralf Baechle
+ * Copyright (C) 1995, 96, 97, 98, 99, 2003, 05 Ralf Baechle
*/
#ifndef _ASM_FCNTL_H
#define _ASM_FCNTL_H
+#include <linux/config.h>
+
#define O_APPEND 0x0008
#define O_SYNC 0x0010
#define O_NONBLOCK 0x0080
@@ -40,13 +42,13 @@
* contain all the same fields as struct flock.
*/
-#ifndef __mips64
+#ifdef CONFIG_32BIT
struct flock {
short l_type;
short l_whence;
- __kernel_off_t l_start;
- __kernel_off_t l_len;
+ off_t l_start;
+ off_t l_len;
long l_sysid;
__kernel_pid_t l_pid;
long pad[4];
@@ -54,13 +56,8 @@ struct flock {
#define HAVE_ARCH_STRUCT_FLOCK
-#endif
+#endif /* CONFIG_32BIT */
#include <asm-generic/fcntl.h>
-typedef struct flock flock_t;
-#ifndef __mips64
-typedef struct flock64 flock64_t;
-#endif
-
#endif /* _ASM_FCNTL_H */
diff --git a/include/asm-mips/fixmap.h b/include/asm-mips/fixmap.h
index 26b6a90a690b..73a3028dd9f9 100644
--- a/include/asm-mips/fixmap.h
+++ b/include/asm-mips/fixmap.h
@@ -107,4 +107,11 @@ static inline unsigned long virt_to_fix(const unsigned long vaddr)
return __virt_to_fix(vaddr);
}
+/*
+ * Called from pgtable_init()
+ */
+extern void fixrange_init(unsigned long start, unsigned long end,
+ pgd_t *pgd_base);
+
+
#endif
diff --git a/include/asm-mips/fpu.h b/include/asm-mips/fpu.h
index ea24e733b1bc..9c828b1f8218 100644
--- a/include/asm-mips/fpu.h
+++ b/include/asm-mips/fpu.h
@@ -80,9 +80,14 @@ do { \
#define clear_fpu_owner() clear_thread_flag(TIF_USEDFPU)
+static inline int __is_fpu_owner(void)
+{
+ return test_thread_flag(TIF_USEDFPU);
+}
+
static inline int is_fpu_owner(void)
{
- return cpu_has_fpu && test_thread_flag(TIF_USEDFPU);
+ return cpu_has_fpu && __is_fpu_owner();
}
static inline void own_fpu(void)
@@ -127,7 +132,7 @@ static inline void restore_fp(struct task_struct *tsk)
static inline fpureg_t *get_fpu_regs(struct task_struct *tsk)
{
if (cpu_has_fpu) {
- if ((tsk == current) && is_fpu_owner())
+ if ((tsk == current) && __is_fpu_owner())
_save_fp(current);
return tsk->thread.fpu.hard.fpr;
}
diff --git a/include/asm-mips/fpu_emulator.h b/include/asm-mips/fpu_emulator.h
index 46972ae2b95d..16cb4d11dd0b 100644
--- a/include/asm-mips/fpu_emulator.h
+++ b/include/asm-mips/fpu_emulator.h
@@ -23,16 +23,15 @@
#ifndef _ASM_FPU_EMULATOR_H
#define _ASM_FPU_EMULATOR_H
-struct mips_fpu_emulator_private {
- unsigned int eir;
- struct {
- unsigned int emulated;
- unsigned int loads;
- unsigned int stores;
- unsigned int cp1ops;
- unsigned int cp1xops;
- unsigned int errors;
- } stats;
+struct mips_fpu_emulator_stats {
+ unsigned int emulated;
+ unsigned int loads;
+ unsigned int stores;
+ unsigned int cp1ops;
+ unsigned int cp1xops;
+ unsigned int errors;
};
+extern struct mips_fpu_emulator_stats fpuemustats;
+
#endif /* _ASM_FPU_EMULATOR_H */
diff --git a/include/asm-mips/futex.h b/include/asm-mips/futex.h
index 9feff4ce1424..2454c44a8f54 100644
--- a/include/asm-mips/futex.h
+++ b/include/asm-mips/futex.h
@@ -3,10 +3,45 @@
#ifdef __KERNEL__
+#include <linux/config.h>
#include <linux/futex.h>
#include <asm/errno.h>
#include <asm/uaccess.h>
+#ifdef CONFIG_SMP
+#define __FUTEX_SMP_SYNC " sync \n"
+#else
+#define __FUTEX_SMP_SYNC
+#endif
+
+#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
+{ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " .set mips3 \n" \
+ "1: ll %1, (%3) # __futex_atomic_op1 \n" \
+ " .set mips0 \n" \
+ " " insn " \n" \
+ " .set mips3 \n" \
+ "2: sc $1, (%3) \n" \
+ " beqzl $1, 1b \n" \
+ __FUTEX_SMP_SYNC \
+ "3: \n" \
+ " .set pop \n" \
+ " .set mips0 \n" \
+ " .section .fixup,\"ax\" \n" \
+ "4: li %0, %5 \n" \
+ " j 2b \n" \
+ " .previous \n" \
+ " .section __ex_table,\"a\" \n" \
+ " "__UA_ADDR "\t1b, 4b \n" \
+ " "__UA_ADDR "\t2b, 4b \n" \
+ " .previous \n" \
+ : "=r" (ret), "=r" (oldval) \
+ : "0" (0), "r" (uaddr), "Jr" (oparg), "i" (-EFAULT)); \
+}
+
static inline int
futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
{
@@ -25,10 +60,25 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
switch (op) {
case FUTEX_OP_SET:
+ __futex_atomic_op("move $1, %z4", ret, oldval, uaddr, oparg);
+ break;
+
case FUTEX_OP_ADD:
+ __futex_atomic_op("addu $1, %1, %z4",
+ ret, oldval, uaddr, oparg);
+ break;
case FUTEX_OP_OR:
+ __futex_atomic_op("or $1, %1, %z4",
+ ret, oldval, uaddr, oparg);
+ break;
case FUTEX_OP_ANDN:
+ __futex_atomic_op("and $1, %1, %z4",
+ ret, oldval, uaddr, ~oparg);
+ break;
case FUTEX_OP_XOR:
+ __futex_atomic_op("xor $1, %1, %z4",
+ ret, oldval, uaddr, oparg);
+ break;
default:
ret = -ENOSYS;
}
diff --git a/include/asm-mips/hazards.h b/include/asm-mips/hazards.h
index f524eaccd5f1..7517189e469f 100644
--- a/include/asm-mips/hazards.h
+++ b/include/asm-mips/hazards.h
@@ -74,7 +74,8 @@
#define irq_disable_hazard
_ehb
-#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000)
+#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000) || \
+ defined(CONFIG_CPU_SB1)
/*
* R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer.
@@ -107,6 +108,7 @@ __asm__(
" .endm \n\t");
#ifdef CONFIG_CPU_RM9000
+
/*
* RM9000 hazards. When the JTLB is updated by tlbwi or tlbwr, a subsequent
* use of the JTLB for instructions should not occur for 4 cpu cycles and use
@@ -124,6 +126,9 @@ __asm__(
".set\tmips32\n\t" \
"_ssnop; _ssnop; _ssnop; _ssnop\n\t" \
".set\tmips0")
+
+#define back_to_back_c0_hazard() do { } while (0)
+
#else
/*
@@ -144,15 +149,13 @@ __asm__(
#endif
/*
- * mtc0->mfc0 hazard
- * The 24K has a 2 cycle mtc0/mfc0 execution hazard.
- * It is a MIPS32R2 processor so ehb will clear the hazard.
+ * Interrupt enable/disable hazards
+ * Some processors have hazards when modifying
+ * the status register to change the interrupt state
*/
#ifdef CONFIG_CPU_MIPSR2
-/*
- * Use a macro for ehb unless explicit support for MIPSR2 is enabled
- */
+
__asm__(
" .macro\tirq_enable_hazard \n\t"
" _ehb \n\t"
@@ -160,17 +163,26 @@ __asm__(
" \n\t"
" .macro\tirq_disable_hazard \n\t"
" _ehb \n\t"
+ " .endm \n\t"
+ " \n\t"
+ " .macro\tback_to_back_c0_hazard \n\t"
+ " _ehb \n\t"
" .endm");
#define irq_enable_hazard() \
__asm__ __volatile__( \
- "_ehb\t\t\t\t# irq_enable_hazard")
+ "irq_enable_hazard")
#define irq_disable_hazard() \
__asm__ __volatile__( \
- "_ehb\t\t\t\t# irq_disable_hazard")
+ "irq_disable_hazard")
+
+#define back_to_back_c0_hazard() \
+ __asm__ __volatile__( \
+ "back_to_back_c0_hazard")
-#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000)
+#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000) || \
+ defined(CONFIG_CPU_SB1)
/*
* R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer.
@@ -186,6 +198,8 @@ __asm__(
#define irq_enable_hazard() do { } while (0)
#define irq_disable_hazard() do { } while (0)
+#define back_to_back_c0_hazard() do { } while (0)
+
#else
/*
@@ -208,10 +222,32 @@ __asm__(
#define irq_enable_hazard() do { } while (0)
#define irq_disable_hazard() \
__asm__ __volatile__( \
- "_ssnop; _ssnop; _ssnop;\t\t# irq_disable_hazard")
+ "irq_disable_hazard")
+
+#define back_to_back_c0_hazard() \
+ __asm__ __volatile__( \
+ " .set noreorder \n" \
+ " nop; nop; nop \n" \
+ " .set reorder \n")
#endif
+#ifdef CONFIG_CPU_MIPSR2
+#define instruction_hazard() \
+do { \
+__label__ __next; \
+ __asm__ __volatile__( \
+ " jr.hb %0 \n" \
+ : \
+ : "r" (&&__next)); \
+__next: \
+ ; \
+} while (0)
+
+#else
+#define instruction_hazard() do { } while (0)
+#endif
+
#endif /* __ASSEMBLY__ */
#endif /* _ASM_HAZARDS_H */
diff --git a/include/asm-mips/highmem.h b/include/asm-mips/highmem.h
index f49930d947d4..8cf598402492 100644
--- a/include/asm-mips/highmem.h
+++ b/include/asm-mips/highmem.h
@@ -75,6 +75,7 @@ static inline void *kmap_atomic(struct page *page, enum km_type type)
}
static inline void kunmap_atomic(void *kvaddr, enum km_type type) { }
+#define kmap_atomic_pfn(pfn, idx) page_address(pfn_to_page(pfn))
#define kmap_atomic_to_page(ptr) virt_to_page(ptr)
@@ -86,6 +87,7 @@ extern void *__kmap(struct page *page);
extern void __kunmap(struct page *page);
extern void *__kmap_atomic(struct page *page, enum km_type type);
extern void __kunmap_atomic(void *kvaddr, enum km_type type);
+extern void *kmap_atomic_pfn(unsigned long pfn, enum km_type type);
extern struct page *__kmap_atomic_to_page(void *ptr);
#define kmap __kmap
diff --git a/include/asm-mips/inst.h b/include/asm-mips/inst.h
index 6ad517241768..e0745f4ff624 100644
--- a/include/asm-mips/inst.h
+++ b/include/asm-mips/inst.h
@@ -28,7 +28,7 @@ enum major_op {
sdl_op, sdr_op, swr_op, cache_op,
ll_op, lwc1_op, lwc2_op, pref_op,
lld_op, ldc1_op, ldc2_op, ld_op,
- sc_op, swc1_op, swc2_op, major_3b_op, /* Opcode 0x3b is unused */
+ sc_op, swc1_op, swc2_op, rdhwr_op,
scd_op, sdc1_op, sdc2_op, sd_op
};
@@ -62,10 +62,10 @@ enum rt_op {
spimi_op, unused_rt_op_0x05, unused_rt_op_0x06, unused_rt_op_0x07,
tgei_op, tgeiu_op, tlti_op, tltiu_op,
teqi_op, unused_0x0d_rt_op, tnei_op, unused_0x0f_rt_op,
- bltzal_op, bgezal_op, bltzall_op, bgezall_op
- /*
- * The others (0x14 - 0x1f) are unused.
- */
+ bltzal_op, bgezal_op, bltzall_op, bgezall_op,
+ rt_op_0x14, rt_op_0x15, rt_op_0x16, rt_op_0x17,
+ rt_op_0x18, rt_op_0x19, rt_op_0x1a, rt_op_0x1b,
+ bposge32_op, rt_op_0x1d, rt_op_0x1e, rt_op_0x1f
};
/*
diff --git a/include/asm-mips/interrupt.h b/include/asm-mips/interrupt.h
index e8357f5379fa..a5735761f5e5 100644
--- a/include/asm-mips/interrupt.h
+++ b/include/asm-mips/interrupt.h
@@ -11,20 +11,25 @@
#ifndef _ASM_INTERRUPT_H
#define _ASM_INTERRUPT_H
+#include <linux/config.h>
#include <asm/hazards.h>
__asm__ (
- ".macro\tlocal_irq_enable\n\t"
- ".set\tpush\n\t"
- ".set\treorder\n\t"
- ".set\tnoat\n\t"
- "mfc0\t$1,$12\n\t"
- "ori\t$1,0x1f\n\t"
- "xori\t$1,0x1e\n\t"
- "mtc0\t$1,$12\n\t"
- "irq_enable_hazard\n\t"
- ".set\tpop\n\t"
- ".endm");
+ " .macro local_irq_enable \n"
+ " .set push \n"
+ " .set reorder \n"
+ " .set noat \n"
+#ifdef CONFIG_CPU_MIPSR2
+ " ei \n"
+#else
+ " mfc0 $1,$12 \n"
+ " ori $1,0x1f \n"
+ " xori $1,0x1e \n"
+ " mtc0 $1,$12 \n"
+#endif
+ " irq_enable_hazard \n"
+ " .set pop \n"
+ " .endm");
static inline void local_irq_enable(void)
{
@@ -43,17 +48,21 @@ static inline void local_irq_enable(void)
* no nops at all.
*/
__asm__ (
- ".macro\tlocal_irq_disable\n\t"
- ".set\tpush\n\t"
- ".set\tnoat\n\t"
- "mfc0\t$1,$12\n\t"
- "ori\t$1,1\n\t"
- "xori\t$1,1\n\t"
- ".set\tnoreorder\n\t"
- "mtc0\t$1,$12\n\t"
- "irq_disable_hazard\n\t"
- ".set\tpop\n\t"
- ".endm");
+ " .macro local_irq_disable\n"
+ " .set push \n"
+ " .set noat \n"
+#ifdef CONFIG_CPU_MIPSR2
+ " di \n"
+#else
+ " mfc0 $1,$12 \n"
+ " ori $1,1 \n"
+ " xori $1,1 \n"
+ " .set noreorder \n"
+ " mtc0 $1,$12 \n"
+#endif
+ " irq_disable_hazard \n"
+ " .set pop \n"
+ " .endm \n");
static inline void local_irq_disable(void)
{
@@ -65,12 +74,12 @@ static inline void local_irq_disable(void)
}
__asm__ (
- ".macro\tlocal_save_flags flags\n\t"
- ".set\tpush\n\t"
- ".set\treorder\n\t"
- "mfc0\t\\flags, $12\n\t"
- ".set\tpop\n\t"
- ".endm");
+ " .macro local_save_flags flags \n"
+ " .set push \n"
+ " .set reorder \n"
+ " mfc0 \\flags, $12 \n"
+ " .set pop \n"
+ " .endm \n");
#define local_save_flags(x) \
__asm__ __volatile__( \
@@ -78,18 +87,22 @@ __asm__ __volatile__( \
: "=r" (x))
__asm__ (
- ".macro\tlocal_irq_save result\n\t"
- ".set\tpush\n\t"
- ".set\treorder\n\t"
- ".set\tnoat\n\t"
- "mfc0\t\\result, $12\n\t"
- "ori\t$1, \\result, 1\n\t"
- "xori\t$1, 1\n\t"
- ".set\tnoreorder\n\t"
- "mtc0\t$1, $12\n\t"
- "irq_disable_hazard\n\t"
- ".set\tpop\n\t"
- ".endm");
+ " .macro local_irq_save result \n"
+ " .set push \n"
+ " .set reorder \n"
+ " .set noat \n"
+#ifdef CONFIG_CPU_MIPSR2
+ " di \\result \n"
+#else
+ " mfc0 \\result, $12 \n"
+ " ori $1, \\result, 1 \n"
+ " xori $1, 1 \n"
+ " .set noreorder \n"
+ " mtc0 $1, $12 \n"
+#endif
+ " irq_disable_hazard \n"
+ " .set pop \n"
+ " .endm \n");
#define local_irq_save(x) \
__asm__ __volatile__( \
@@ -99,19 +112,37 @@ __asm__ __volatile__( \
: "memory")
__asm__ (
- ".macro\tlocal_irq_restore flags\n\t"
- ".set\tnoreorder\n\t"
- ".set\tnoat\n\t"
- "mfc0\t$1, $12\n\t"
- "andi\t\\flags, 1\n\t"
- "ori\t$1, 1\n\t"
- "xori\t$1, 1\n\t"
- "or\t\\flags, $1\n\t"
- "mtc0\t\\flags, $12\n\t"
- "irq_disable_hazard\n\t"
- ".set\tat\n\t"
- ".set\treorder\n\t"
- ".endm");
+ " .macro local_irq_restore flags \n"
+ " .set noreorder \n"
+ " .set noat \n"
+#if defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU)
+ /*
+ * Slow, but doesn't suffer from a relativly unlikely race
+ * condition we're having since days 1.
+ */
+ " beqz \\flags, 1f \n"
+ " di \n"
+ " ei \n"
+ "1: \n"
+#elif defined(CONFIG_CPU_MIPSR2)
+ /*
+ * Fast, dangerous. Life is fun, life is good.
+ */
+ " mfc0 $1, $12 \n"
+ " ins $1, \\flags, 0, 1 \n"
+ " mtc0 $1, $12 \n"
+#else
+ " mfc0 $1, $12 \n"
+ " andi \\flags, 1 \n"
+ " ori $1, 1 \n"
+ " xori $1, 1 \n"
+ " or \\flags, $1 \n"
+ " mtc0 \\flags, $12 \n"
+#endif
+ " irq_disable_hazard \n"
+ " .set at \n"
+ " .set reorder \n"
+ " .endm \n");
#define local_irq_restore(flags) \
do { \
diff --git a/include/asm-mips/inventory.h b/include/asm-mips/inventory.h
index 4cd36fe98173..92d90f75a636 100644
--- a/include/asm-mips/inventory.h
+++ b/include/asm-mips/inventory.h
@@ -4,6 +4,8 @@
#ifndef __ASM_INVENTORY_H
#define __ASM_INVENTORY_H
+#include <linux/compiler.h>
+
typedef struct inventory_s {
struct inventory_s *inv_next;
int inv_class;
@@ -14,7 +16,9 @@ typedef struct inventory_s {
} inventory_t;
extern int inventory_items;
-void add_to_inventory (int class, int type, int controller, int unit, int state);
-int dump_inventory_to_user (void *userbuf, int size);
+
+extern void add_to_inventory (int class, int type, int controller, int unit, int state);
+extern int dump_inventory_to_user (void __user *userbuf, int size);
+extern int __init init_inventory(void);
#endif /* __ASM_INVENTORY_H */
diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h
index 039845f2e6b0..3061870b7f6c 100644
--- a/include/asm-mips/io.h
+++ b/include/asm-mips/io.h
@@ -25,7 +25,9 @@
#include <asm/page.h>
#include <asm/pgtable-bits.h>
#include <asm/processor.h>
+#include <asm/string.h>
+#include <ioremap.h>
#include <mangle-port.h>
/*
@@ -34,7 +36,7 @@
#undef CONF_SLOWDOWN_IO
/*
- * Raw operations are never swapped in software. Otoh values that raw
+ * Raw operations are never swapped in software. OTOH values that raw
* operations are working on may or may not have been swapped by the bus
* hardware. An example use would be for flash memory that's used for
* execute in place.
@@ -43,45 +45,53 @@
# define __raw_ioswabw(x) (x)
# define __raw_ioswabl(x) (x)
# define __raw_ioswabq(x) (x)
+# define ____raw_ioswabq(x) (x)
/*
* Sane hardware offers swapping of PCI/ISA I/O space accesses in hardware;
* less sane hardware forces software to fiddle with this...
+ *
+ * Regardless, if the host bus endianness mismatches that of PCI/ISA, then
+ * you can't have the numerical value of data and byte addresses within
+ * multibyte quantities both preserved at the same time. Hence two
+ * variations of functions: non-prefixed ones that preserve the value
+ * and prefixed ones that preserve byte addresses. The latters are
+ * typically used for moving raw data between a peripheral and memory (cf.
+ * string I/O functions), hence the "mem_" prefix.
*/
#if defined(CONFIG_SWAP_IO_SPACE)
# define ioswabb(x) (x)
+# define mem_ioswabb(x) (x)
# ifdef CONFIG_SGI_IP22
/*
* IP22 seems braindead enough to swap 16bits values in hardware, but
* not 32bits. Go figure... Can't tell without documentation.
*/
# define ioswabw(x) (x)
+# define mem_ioswabw(x) le16_to_cpu(x)
# else
# define ioswabw(x) le16_to_cpu(x)
+# define mem_ioswabw(x) (x)
# endif
# define ioswabl(x) le32_to_cpu(x)
+# define mem_ioswabl(x) (x)
# define ioswabq(x) le64_to_cpu(x)
+# define mem_ioswabq(x) (x)
#else
# define ioswabb(x) (x)
+# define mem_ioswabb(x) (x)
# define ioswabw(x) (x)
+# define mem_ioswabw(x) cpu_to_le16(x)
# define ioswabl(x) (x)
+# define mem_ioswabl(x) cpu_to_le32(x)
# define ioswabq(x) (x)
+# define mem_ioswabq(x) cpu_to_le32(x)
#endif
-/*
- * Native bus accesses never swapped.
- */
-#define bus_ioswabb(x) (x)
-#define bus_ioswabw(x) (x)
-#define bus_ioswabl(x) (x)
-#define bus_ioswabq(x) (x)
-
-#define __bus_ioswabq bus_ioswabq
-
#define IO_SPACE_LIMIT 0xffff
/*
@@ -194,12 +204,14 @@ extern unsigned long isa_slot_offset;
*/
#define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
-extern void * __ioremap(phys_t offset, phys_t size, unsigned long flags);
+extern void __iomem * __ioremap(phys_t offset, phys_t size, unsigned long flags);
extern void __iounmap(volatile void __iomem *addr);
-static inline void * __ioremap_mode(phys_t offset, unsigned long size,
+static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size,
unsigned long flags)
{
+#define __IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL))
+
if (cpu_has_64bit_addresses) {
u64 base = UNCAC_BASE;
@@ -209,10 +221,30 @@ static inline void * __ioremap_mode(phys_t offset, unsigned long size,
*/
if (flags == _CACHE_UNCACHED)
base = (u64) IO_BASE;
- return (void *) (unsigned long) (base + offset);
+ return (void __iomem *) (unsigned long) (base + offset);
+ } else if (__builtin_constant_p(offset) &&
+ __builtin_constant_p(size) && __builtin_constant_p(flags)) {
+ phys_t phys_addr, last_addr;
+
+ phys_addr = fixup_bigphys_addr(offset, size);
+
+ /* Don't allow wraparound or zero size. */
+ last_addr = phys_addr + size - 1;
+ if (!size || last_addr < phys_addr)
+ return NULL;
+
+ /*
+ * Map uncached objects in the low 512MB of address
+ * space using KSEG1.
+ */
+ if (__IS_LOW512(phys_addr) && __IS_LOW512(last_addr) &&
+ flags == _CACHE_UNCACHED)
+ return (void __iomem *)CKSEG1ADDR(phys_addr);
}
return __ioremap(offset, size, flags);
+
+#undef __IS_LOW512
}
/*
@@ -264,12 +296,16 @@ static inline void * __ioremap_mode(phys_t offset, unsigned long size,
static inline void iounmap(volatile void __iomem *addr)
{
- if (cpu_has_64bit_addresses)
+#define __IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1)
+
+ if (cpu_has_64bit_addresses ||
+ (__builtin_constant_p(addr) && __IS_KSEG1(addr)))
return;
__iounmap(addr);
-}
+#undef __IS_KSEG1
+}
#define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq) \
\
@@ -319,7 +355,8 @@ static inline type pfx##read##bwlq(volatile void __iomem *mem) \
else if (cpu_has_64bits) { \
unsigned long __flags; \
\
- local_irq_save(__flags); \
+ if (irq) \
+ local_irq_save(__flags); \
__asm__ __volatile__( \
".set mips3" "\t\t# __readq" "\n\t" \
"ld %L0, %1" "\n\t" \
@@ -328,7 +365,8 @@ static inline type pfx##read##bwlq(volatile void __iomem *mem) \
".set mips0" "\n" \
: "=r" (__val) \
: "m" (*__mem)); \
- local_irq_restore(__flags); \
+ if (irq) \
+ local_irq_restore(__flags); \
} else { \
__val = 0; \
BUG(); \
@@ -349,11 +387,11 @@ static inline void pfx##out##bwlq##p(type val, unsigned long port) \
\
__val = pfx##ioswab##bwlq(val); \
\
- if (sizeof(type) != sizeof(u64)) { \
- *__addr = __val; \
- slow; \
- } else \
- BUILD_BUG(); \
+ /* Really, we want this to be atomic */ \
+ BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long)); \
+ \
+ *__addr = __val; \
+ slow; \
} \
\
static inline type pfx##in##bwlq##p(unsigned long port) \
@@ -364,13 +402,10 @@ static inline type pfx##in##bwlq##p(unsigned long port) \
port = __swizzle_addr_##bwlq(port); \
__addr = (void *)(mips_io_port_base + port); \
\
- if (sizeof(type) != sizeof(u64)) { \
- __val = *__addr; \
- slow; \
- } else { \
- __val = 0; \
- BUILD_BUG(); \
- } \
+ BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long)); \
+ \
+ __val = *__addr; \
+ slow; \
\
return pfx##ioswab##bwlq(__val); \
}
@@ -379,27 +414,35 @@ static inline type pfx##in##bwlq##p(unsigned long port) \
\
__BUILD_MEMORY_SINGLE(bus, bwlq, type, 1)
-#define __BUILD_IOPORT_PFX(bus, bwlq, type) \
- \
-__BUILD_IOPORT_SINGLE(bus, bwlq, type, ,) \
-__BUILD_IOPORT_SINGLE(bus, bwlq, type, _p, SLOW_DOWN_IO)
-
-#define BUILDIO(bwlq, type) \
+#define BUILDIO_MEM(bwlq, type) \
\
-__BUILD_MEMORY_PFX(, bwlq, type) \
__BUILD_MEMORY_PFX(__raw_, bwlq, type) \
-__BUILD_MEMORY_PFX(bus_, bwlq, type) \
-__BUILD_IOPORT_PFX(, bwlq, type) \
-__BUILD_IOPORT_PFX(__raw_, bwlq, type)
+__BUILD_MEMORY_PFX(, bwlq, type) \
+__BUILD_MEMORY_PFX(mem_, bwlq, type) \
+
+BUILDIO_MEM(b, u8)
+BUILDIO_MEM(w, u16)
+BUILDIO_MEM(l, u32)
+BUILDIO_MEM(q, u64)
+
+#define __BUILD_IOPORT_PFX(bus, bwlq, type) \
+ __BUILD_IOPORT_SINGLE(bus, bwlq, type, ,) \
+ __BUILD_IOPORT_SINGLE(bus, bwlq, type, _p, SLOW_DOWN_IO)
+
+#define BUILDIO_IOPORT(bwlq, type) \
+ __BUILD_IOPORT_PFX(, bwlq, type) \
+ __BUILD_IOPORT_PFX(mem_, bwlq, type)
+
+BUILDIO_IOPORT(b, u8)
+BUILDIO_IOPORT(w, u16)
+BUILDIO_IOPORT(l, u32)
+#ifdef CONFIG_64BIT
+BUILDIO_IOPORT(q, u64)
+#endif
#define __BUILDIO(bwlq, type) \
\
-__BUILD_MEMORY_SINGLE(__bus_, bwlq, type, 0)
-
-BUILDIO(b, u8)
-BUILDIO(w, u16)
-BUILDIO(l, u32)
-BUILDIO(q, u64)
+__BUILD_MEMORY_SINGLE(____raw_, bwlq, type, 0)
__BUILDIO(q, u64)
@@ -422,7 +465,7 @@ static inline void writes##bwlq(volatile void __iomem *mem, void *addr, \
volatile type *__addr = addr; \
\
while (count--) { \
- __raw_write##bwlq(*__addr, mem); \
+ mem_write##bwlq(*__addr, mem); \
__addr++; \
} \
} \
@@ -433,20 +476,20 @@ static inline void reads##bwlq(volatile void __iomem *mem, void *addr, \
volatile type *__addr = addr; \
\
while (count--) { \
- *__addr = __raw_read##bwlq(mem); \
+ *__addr = mem_read##bwlq(mem); \
__addr++; \
} \
}
#define __BUILD_IOPORT_STRING(bwlq, type) \
\
-static inline void outs##bwlq(unsigned long port, void *addr, \
+static inline void outs##bwlq(unsigned long port, const void *addr, \
unsigned int count) \
{ \
- volatile type *__addr = addr; \
+ const volatile type *__addr = addr; \
\
while (count--) { \
- __raw_out##bwlq(*__addr, port); \
+ mem_out##bwlq(*__addr, port); \
__addr++; \
} \
} \
@@ -457,7 +500,7 @@ static inline void ins##bwlq(unsigned long port, void *addr, \
volatile type *__addr = addr; \
\
while (count--) { \
- *__addr = __raw_in##bwlq(port); \
+ *__addr = mem_in##bwlq(port); \
__addr++; \
} \
}
@@ -470,15 +513,26 @@ __BUILD_IOPORT_STRING(bwlq, type)
BUILDSTRING(b, u8)
BUILDSTRING(w, u16)
BUILDSTRING(l, u32)
+#ifdef CONFIG_64BIT
BUILDSTRING(q, u64)
+#endif
/* Depends on MIPS II instruction set */
#define mmiowb() asm volatile ("sync" ::: "memory")
-#define memset_io(a,b,c) memset((void *)(a),(b),(c))
-#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c))
-#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c))
+static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count)
+{
+ memset((void __force *) addr, val, count);
+}
+static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, int count)
+{
+ memcpy(dst, (void __force *) src, count);
+}
+static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int count)
+{
+ memcpy((void __force *) dst, src, count);
+}
/*
* Memory Mapped I/O
diff --git a/include/asm-mips/irq.h b/include/asm-mips/irq.h
index 3f2470e9e678..8a342ccb34a8 100644
--- a/include/asm-mips/irq.h
+++ b/include/asm-mips/irq.h
@@ -24,11 +24,9 @@ static inline int irq_canonicalize(int irq)
struct pt_regs;
-#ifdef CONFIG_PREEMPT
-
extern asmlinkage unsigned int do_IRQ(unsigned int irq, struct pt_regs *regs);
-#else
+#ifdef CONFIG_PREEMPT
/*
* do_IRQ handles all normal device IRQ's (the special
diff --git a/include/asm-mips/jmr3927/jmr3927.h b/include/asm-mips/jmr3927/jmr3927.h
index 86df317b4078..baf412967afa 100644
--- a/include/asm-mips/jmr3927/jmr3927.h
+++ b/include/asm-mips/jmr3927/jmr3927.h
@@ -202,20 +202,6 @@ static inline int jmr3927_have_isac(void)
#endif /* !__ASSEMBLY__ */
/*
- * UART defines for serial.h
- */
-
-/* use Pre-scaler T0 (1/2) */
-#define JMR3927_BASE_BAUD (JMR3927_IMCLK / 2 / 16)
-
-#define UART0_ADDR 0xfffef300
-#define UART1_ADDR 0xfffef400
-#define UART0_INT JMR3927_IRQ_IRC_SIO0
-#define UART1_INT JMR3927_IRQ_IRC_SIO1
-#define UART0_FLAGS ASYNC_BOOT_AUTOCONF
-#define UART1_FLAGS 0
-
-/*
* IRQ mappings
*/
diff --git a/include/asm-mips/mach-au1x00/au1000.h b/include/asm-mips/mach-au1x00/au1000.h
index 148bae2fa7d3..8327ec341c18 100644
--- a/include/asm-mips/mach-au1x00/au1000.h
+++ b/include/asm-mips/mach-au1x00/au1000.h
@@ -60,59 +60,36 @@ void static inline au_sync_delay(int ms)
mdelay(ms);
}
-void static inline au_writeb(u8 val, int reg)
+void static inline au_writeb(u8 val, unsigned long reg)
{
*(volatile u8 *)(reg) = val;
}
-void static inline au_writew(u16 val, int reg)
+void static inline au_writew(u16 val, unsigned long reg)
{
*(volatile u16 *)(reg) = val;
}
-void static inline au_writel(u32 val, int reg)
+void static inline au_writel(u32 val, unsigned long reg)
{
*(volatile u32 *)(reg) = val;
}
-static inline u8 au_readb(unsigned long port)
+static inline u8 au_readb(unsigned long reg)
{
- return (*(volatile u8 *)port);
+ return (*(volatile u8 *)reg);
}
-static inline u16 au_readw(unsigned long port)
+static inline u16 au_readw(unsigned long reg)
{
- return (*(volatile u16 *)port);
+ return (*(volatile u16 *)reg);
}
-static inline u32 au_readl(unsigned long port)
+static inline u32 au_readl(unsigned long reg)
{
- return (*(volatile u32 *)port);
+ return (*(volatile u32 *)reg);
}
-/* These next three functions should be a generic part of the MIPS
- * kernel (with the 'au_' removed from the name) and selected for
- * processors that support the instructions.
- * Taken from PPC tree. -- Dan
- */
-/* Return the bit position of the most significant 1 bit in a word */
-static __inline__ int __ilog2(unsigned int x)
-{
- int lz;
-
- asm volatile (
- ".set\tnoreorder\n\t"
- ".set\tnoat\n\t"
- ".set\tmips32\n\t"
- "clz\t%0,%1\n\t"
- ".set\tmips0\n\t"
- ".set\tat\n\t"
- ".set\treorder"
- : "=r" (lz)
- : "r" (x));
-
- return 31 - lz;
-}
static __inline__ int au_ffz(unsigned int x)
{
@@ -162,28 +139,293 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
#endif
-/* SDRAM Controller */
+/*
+ * SDRAM Register Offsets
+ */
#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1100)
-#define MEM_SDMODE0 0xB4000000
-#define MEM_SDMODE1 0xB4000004
-#define MEM_SDMODE2 0xB4000008
+#define MEM_SDMODE0 (0x0000)
+#define MEM_SDMODE1 (0x0004)
+#define MEM_SDMODE2 (0x0008)
+#define MEM_SDADDR0 (0x000C)
+#define MEM_SDADDR1 (0x0010)
+#define MEM_SDADDR2 (0x0014)
+#define MEM_SDREFCFG (0x0018)
+#define MEM_SDPRECMD (0x001C)
+#define MEM_SDAUTOREF (0x0020)
+#define MEM_SDWRMD0 (0x0024)
+#define MEM_SDWRMD1 (0x0028)
+#define MEM_SDWRMD2 (0x002C)
+#define MEM_SDSLEEP (0x0030)
+#define MEM_SDSMCKE (0x0034)
-#define MEM_SDADDR0 0xB400000C
-#define MEM_SDADDR1 0xB4000010
-#define MEM_SDADDR2 0xB4000014
+/*
+ * MEM_SDMODE register content definitions
+ */
+#define MEM_SDMODE_F (1<<22)
+#define MEM_SDMODE_SR (1<<21)
+#define MEM_SDMODE_BS (1<<20)
+#define MEM_SDMODE_RS (3<<18)
+#define MEM_SDMODE_CS (7<<15)
+#define MEM_SDMODE_TRAS (15<<11)
+#define MEM_SDMODE_TMRD (3<<9)
+#define MEM_SDMODE_TWR (3<<7)
+#define MEM_SDMODE_TRP (3<<5)
+#define MEM_SDMODE_TRCD (3<<3)
+#define MEM_SDMODE_TCL (7<<0)
+
+#define MEM_SDMODE_BS_2Bank (0<<20)
+#define MEM_SDMODE_BS_4Bank (1<<20)
+#define MEM_SDMODE_RS_11Row (0<<18)
+#define MEM_SDMODE_RS_12Row (1<<18)
+#define MEM_SDMODE_RS_13Row (2<<18)
+#define MEM_SDMODE_RS_N(N) ((N)<<18)
+#define MEM_SDMODE_CS_7Col (0<<15)
+#define MEM_SDMODE_CS_8Col (1<<15)
+#define MEM_SDMODE_CS_9Col (2<<15)
+#define MEM_SDMODE_CS_10Col (3<<15)
+#define MEM_SDMODE_CS_11Col (4<<15)
+#define MEM_SDMODE_CS_N(N) ((N)<<15)
+#define MEM_SDMODE_TRAS_N(N) ((N)<<11)
+#define MEM_SDMODE_TMRD_N(N) ((N)<<9)
+#define MEM_SDMODE_TWR_N(N) ((N)<<7)
+#define MEM_SDMODE_TRP_N(N) ((N)<<5)
+#define MEM_SDMODE_TRCD_N(N) ((N)<<3)
+#define MEM_SDMODE_TCL_N(N) ((N)<<0)
-#define MEM_SDREFCFG 0xB4000018
-#define MEM_SDPRECMD 0xB400001C
-#define MEM_SDAUTOREF 0xB4000020
+/*
+ * MEM_SDADDR register contents definitions
+ */
+#define MEM_SDADDR_E (1<<20)
+#define MEM_SDADDR_CSBA (0x03FF<<10)
+#define MEM_SDADDR_CSMASK (0x03FF<<0)
+#define MEM_SDADDR_CSBA_N(N) ((N)&(0x03FF<<22)>>12)
+#define MEM_SDADDR_CSMASK_N(N) ((N)&(0x03FF<<22)>>22)
+
+/*
+ * MEM_SDREFCFG register content definitions
+ */
+#define MEM_SDREFCFG_TRC (15<<28)
+#define MEM_SDREFCFG_TRPM (3<<26)
+#define MEM_SDREFCFG_E (1<<25)
+#define MEM_SDREFCFG_RE (0x1ffffff<<0)
+#define MEM_SDREFCFG_TRC_N(N) ((N)<<MEM_SDREFCFG_TRC)
+#define MEM_SDREFCFG_TRPM_N(N) ((N)<<MEM_SDREFCFG_TRPM)
+#define MEM_SDREFCFG_REF_N(N) (N)
+#endif
-#define MEM_SDWRMD0 0xB4000024
-#define MEM_SDWRMD1 0xB4000028
-#define MEM_SDWRMD2 0xB400002C
+/***********************************************************************/
-#define MEM_SDSLEEP 0xB4000030
-#define MEM_SDSMCKE 0xB4000034
+/*
+ * Au1550 SDRAM Register Offsets
+ */
+
+/***********************************************************************/
+
+#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
+#define MEM_SDMODE0 (0x0800)
+#define MEM_SDMODE1 (0x0808)
+#define MEM_SDMODE2 (0x0810)
+#define MEM_SDADDR0 (0x0820)
+#define MEM_SDADDR1 (0x0828)
+#define MEM_SDADDR2 (0x0830)
+#define MEM_SDCONFIGA (0x0840)
+#define MEM_SDCONFIGB (0x0848)
+#define MEM_SDSTAT (0x0850)
+#define MEM_SDERRADDR (0x0858)
+#define MEM_SDSTRIDE0 (0x0860)
+#define MEM_SDSTRIDE1 (0x0868)
+#define MEM_SDSTRIDE2 (0x0870)
+#define MEM_SDWRMD0 (0x0880)
+#define MEM_SDWRMD1 (0x0888)
+#define MEM_SDWRMD2 (0x0890)
+#define MEM_SDPRECMD (0x08C0)
+#define MEM_SDAUTOREF (0x08C8)
+#define MEM_SDSREF (0x08D0)
+#define MEM_SDSLEEP MEM_SDSREF
+
+#endif
+
+/*
+ * Physical base addresses for integrated peripherals
+ */
+
+#ifdef CONFIG_SOC_AU1000
+#define MEM_PHYS_ADDR 0x14000000
+#define STATIC_MEM_PHYS_ADDR 0x14001000
+#define DMA0_PHYS_ADDR 0x14002000
+#define DMA1_PHYS_ADDR 0x14002100
+#define DMA2_PHYS_ADDR 0x14002200
+#define DMA3_PHYS_ADDR 0x14002300
+#define DMA4_PHYS_ADDR 0x14002400
+#define DMA5_PHYS_ADDR 0x14002500
+#define DMA6_PHYS_ADDR 0x14002600
+#define DMA7_PHYS_ADDR 0x14002700
+#define IC0_PHYS_ADDR 0x10400000
+#define IC1_PHYS_ADDR 0x11800000
+#define AC97_PHYS_ADDR 0x10000000
+#define USBH_PHYS_ADDR 0x10100000
+#define USBD_PHYS_ADDR 0x10200000
+#define IRDA_PHYS_ADDR 0x10300000
+#define MAC0_PHYS_ADDR 0x10500000
+#define MAC1_PHYS_ADDR 0x10510000
+#define MACEN_PHYS_ADDR 0x10520000
+#define MACDMA0_PHYS_ADDR 0x14004000
+#define MACDMA1_PHYS_ADDR 0x14004200
+#define I2S_PHYS_ADDR 0x11000000
+#define UART0_PHYS_ADDR 0x11100000
+#define UART1_PHYS_ADDR 0x11200000
+#define UART2_PHYS_ADDR 0x11300000
+#define UART3_PHYS_ADDR 0x11400000
+#define SSI0_PHYS_ADDR 0x11600000
+#define SSI1_PHYS_ADDR 0x11680000
+#define SYS_PHYS_ADDR 0x11900000
+#define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL
+#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
+#define PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL
#endif
+/********************************************************************/
+
+#ifdef CONFIG_SOC_AU1500
+#define MEM_PHYS_ADDR 0x14000000
+#define STATIC_MEM_PHYS_ADDR 0x14001000
+#define DMA0_PHYS_ADDR 0x14002000
+#define DMA1_PHYS_ADDR 0x14002100
+#define DMA2_PHYS_ADDR 0x14002200
+#define DMA3_PHYS_ADDR 0x14002300
+#define DMA4_PHYS_ADDR 0x14002400
+#define DMA5_PHYS_ADDR 0x14002500
+#define DMA6_PHYS_ADDR 0x14002600
+#define DMA7_PHYS_ADDR 0x14002700
+#define IC0_PHYS_ADDR 0x10400000
+#define IC1_PHYS_ADDR 0x11800000
+#define AC97_PHYS_ADDR 0x10000000
+#define USBH_PHYS_ADDR 0x10100000
+#define USBD_PHYS_ADDR 0x10200000
+#define PCI_PHYS_ADDR 0x14005000
+#define MAC0_PHYS_ADDR 0x11500000
+#define MAC1_PHYS_ADDR 0x11510000
+#define MACEN_PHYS_ADDR 0x11520000
+#define MACDMA0_PHYS_ADDR 0x14004000
+#define MACDMA1_PHYS_ADDR 0x14004200
+#define I2S_PHYS_ADDR 0x11000000
+#define UART0_PHYS_ADDR 0x11100000
+#define UART3_PHYS_ADDR 0x11400000
+#define GPIO2_PHYS_ADDR 0x11700000
+#define SYS_PHYS_ADDR 0x11900000
+#define PCI_MEM_PHYS_ADDR 0x400000000ULL
+#define PCI_IO_PHYS_ADDR 0x500000000ULL
+#define PCI_CONFIG0_PHYS_ADDR 0x600000000ULL
+#define PCI_CONFIG1_PHYS_ADDR 0x680000000ULL
+#define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL
+#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
+#define PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL
+#endif
+
+/********************************************************************/
+
+#ifdef CONFIG_SOC_AU1100
+#define MEM_PHYS_ADDR 0x14000000
+#define STATIC_MEM_PHYS_ADDR 0x14001000
+#define DMA0_PHYS_ADDR 0x14002000
+#define DMA1_PHYS_ADDR 0x14002100
+#define DMA2_PHYS_ADDR 0x14002200
+#define DMA3_PHYS_ADDR 0x14002300
+#define DMA4_PHYS_ADDR 0x14002400
+#define DMA5_PHYS_ADDR 0x14002500
+#define DMA6_PHYS_ADDR 0x14002600
+#define DMA7_PHYS_ADDR 0x14002700
+#define IC0_PHYS_ADDR 0x10400000
+#define SD0_PHYS_ADDR 0x10600000
+#define SD1_PHYS_ADDR 0x10680000
+#define IC1_PHYS_ADDR 0x11800000
+#define AC97_PHYS_ADDR 0x10000000
+#define USBH_PHYS_ADDR 0x10100000
+#define USBD_PHYS_ADDR 0x10200000
+#define IRDA_PHYS_ADDR 0x10300000
+#define MAC0_PHYS_ADDR 0x10500000
+#define MACEN_PHYS_ADDR 0x10520000
+#define MACDMA0_PHYS_ADDR 0x14004000
+#define MACDMA1_PHYS_ADDR 0x14004200
+#define I2S_PHYS_ADDR 0x11000000
+#define UART0_PHYS_ADDR 0x11100000
+#define UART1_PHYS_ADDR 0x11200000
+#define UART3_PHYS_ADDR 0x11400000
+#define SSI0_PHYS_ADDR 0x11600000
+#define SSI1_PHYS_ADDR 0x11680000
+#define GPIO2_PHYS_ADDR 0x11700000
+#define SYS_PHYS_ADDR 0x11900000
+#define LCD_PHYS_ADDR 0x15000000
+#define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL
+#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
+#define PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL
+#endif
+
+/***********************************************************************/
+
+#ifdef CONFIG_SOC_AU1550
+#define MEM_PHYS_ADDR 0x14000000
+#define STATIC_MEM_PHYS_ADDR 0x14001000
+#define IC0_PHYS_ADDR 0x10400000
+#define IC1_PHYS_ADDR 0x11800000
+#define USBH_PHYS_ADDR 0x14020000
+#define USBD_PHYS_ADDR 0x10200000
+#define PCI_PHYS_ADDR 0x14005000
+#define MAC0_PHYS_ADDR 0x10500000
+#define MAC1_PHYS_ADDR 0x10510000
+#define MACEN_PHYS_ADDR 0x10520000
+#define MACDMA0_PHYS_ADDR 0x14004000
+#define MACDMA1_PHYS_ADDR 0x14004200
+#define UART0_PHYS_ADDR 0x11100000
+#define UART1_PHYS_ADDR 0x11200000
+#define UART3_PHYS_ADDR 0x11400000
+#define GPIO2_PHYS_ADDR 0x11700000
+#define SYS_PHYS_ADDR 0x11900000
+#define DDMA_PHYS_ADDR 0x14002000
+#define PE_PHYS_ADDR 0x14008000
+#define PSC0_PHYS_ADDR 0x11A00000
+#define PSC1_PHYS_ADDR 0x11B00000
+#define PSC2_PHYS_ADDR 0x10A00000
+#define PSC3_PHYS_ADDR 0x10B00000
+#define PCI_MEM_PHYS_ADDR 0x400000000ULL
+#define PCI_IO_PHYS_ADDR 0x500000000ULL
+#define PCI_CONFIG0_PHYS_ADDR 0x600000000ULL
+#define PCI_CONFIG1_PHYS_ADDR 0x680000000ULL
+#define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL
+#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
+#define PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL
+#endif
+
+/***********************************************************************/
+
+#ifdef CONFIG_SOC_AU1200
+#define MEM_PHYS_ADDR 0x14000000
+#define STATIC_MEM_PHYS_ADDR 0x14001000
+#define AES_PHYS_ADDR 0x10300000
+#define CIM_PHYS_ADDR 0x14004000
+#define IC0_PHYS_ADDR 0x10400000
+#define IC1_PHYS_ADDR 0x11800000
+#define USBM_PHYS_ADDR 0x14020000
+#define USBH_PHYS_ADDR 0x14020100
+#define UART0_PHYS_ADDR 0x11100000
+#define UART1_PHYS_ADDR 0x11200000
+#define GPIO2_PHYS_ADDR 0x11700000
+#define SYS_PHYS_ADDR 0x11900000
+#define DDMA_PHYS_ADDR 0x14002000
+#define PSC0_PHYS_ADDR 0x11A00000
+#define PSC1_PHYS_ADDR 0x11B00000
+#define SD0_PHYS_ADDR 0x10600000
+#define SD1_PHYS_ADDR 0x10680000
+#define LCD_PHYS_ADDR 0x15000000
+#define SWCNT_PHYS_ADDR 0x1110010C
+#define MAEFE_PHYS_ADDR 0x14012000
+#define MAEBE_PHYS_ADDR 0x14010000
+#define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL
+#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
+#define PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL
+#endif
+
+
/* Static Bus Controller */
#define MEM_STCFG0 0xB4001000
#define MEM_STTIME0 0xB4001004
@@ -369,7 +611,7 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define AU1000_MAC0_ENABLE 0xB0520000
#define AU1000_MAC1_ENABLE 0xB0520004
#define NUM_ETH_INTERFACES 2
-#endif // CONFIG_SOC_AU1000
+#endif /* CONFIG_SOC_AU1000 */
/* Au1500 */
#ifdef CONFIG_SOC_AU1500
@@ -429,6 +671,12 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define AU1500_GPIO_207 62
#define AU1500_GPIO_208_215 63
+/* shortcuts */
+#define INTA AU1000_PCI_INTA
+#define INTB AU1000_PCI_INTB
+#define INTC AU1000_PCI_INTC
+#define INTD AU1000_PCI_INTD
+
#define UART0_ADDR 0xB1100000
#define UART3_ADDR 0xB1400000
@@ -440,7 +688,7 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define AU1500_MAC0_ENABLE 0xB1520000
#define AU1500_MAC1_ENABLE 0xB1520004
#define NUM_ETH_INTERFACES 2
-#endif // CONFIG_SOC_AU1500
+#endif /* CONFIG_SOC_AU1500 */
/* Au1100 */
#ifdef CONFIG_SOC_AU1100
@@ -485,6 +733,22 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define AU1000_GPIO_13 45
#define AU1000_GPIO_14 46
#define AU1000_GPIO_15 47
+#define AU1000_GPIO_16 48
+#define AU1000_GPIO_17 49
+#define AU1000_GPIO_18 50
+#define AU1000_GPIO_19 51
+#define AU1000_GPIO_20 52
+#define AU1000_GPIO_21 53
+#define AU1000_GPIO_22 54
+#define AU1000_GPIO_23 55
+#define AU1000_GPIO_24 56
+#define AU1000_GPIO_25 57
+#define AU1000_GPIO_26 58
+#define AU1000_GPIO_27 59
+#define AU1000_GPIO_28 60
+#define AU1000_GPIO_29 61
+#define AU1000_GPIO_30 62
+#define AU1000_GPIO_31 63
#define UART0_ADDR 0xB1100000
#define UART1_ADDR 0xB1200000
@@ -496,7 +760,7 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define AU1100_ETH0_BASE 0xB0500000
#define AU1100_MAC0_ENABLE 0xB0520000
#define NUM_ETH_INTERFACES 1
-#endif // CONFIG_SOC_AU1100
+#endif /* CONFIG_SOC_AU1100 */
#ifdef CONFIG_SOC_AU1550
#define AU1550_UART0_INT 0
@@ -513,14 +777,14 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define AU1550_PSC1_INT 11
#define AU1550_PSC2_INT 12
#define AU1550_PSC3_INT 13
-#define AU1550_TOY_INT 14
-#define AU1550_TOY_MATCH0_INT 15
-#define AU1550_TOY_MATCH1_INT 16
-#define AU1550_TOY_MATCH2_INT 17
-#define AU1550_RTC_INT 18
-#define AU1550_RTC_MATCH0_INT 19
-#define AU1550_RTC_MATCH1_INT 20
-#define AU1550_RTC_MATCH2_INT 21
+#define AU1000_TOY_INT 14
+#define AU1000_TOY_MATCH0_INT 15
+#define AU1000_TOY_MATCH1_INT 16
+#define AU1000_TOY_MATCH2_INT 17
+#define AU1000_RTC_INT 18
+#define AU1000_RTC_MATCH0_INT 19
+#define AU1000_RTC_MATCH1_INT 20
+#define AU1000_RTC_MATCH2_INT 21
#define AU1550_NAND_INT 23
#define AU1550_USB_DEV_REQ_INT 24
#define AU1550_USB_DEV_SUS_INT 25
@@ -563,6 +827,12 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define AU1500_GPIO_207 62
#define AU1500_GPIO_208_218 63 // Logical or of GPIO208:218
+/* shortcuts */
+#define INTA AU1550_PCI_INTA
+#define INTB AU1550_PCI_INTB
+#define INTC AU1550_PCI_INTC
+#define INTD AU1550_PCI_INTD
+
#define UART0_ADDR 0xB1100000
#define UART1_ADDR 0xB1200000
#define UART3_ADDR 0xB1400000
@@ -575,7 +845,7 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define AU1550_MAC0_ENABLE 0xB0520000
#define AU1550_MAC1_ENABLE 0xB0520004
#define NUM_ETH_INTERFACES 2
-#endif // CONFIG_SOC_AU1550
+#endif /* CONFIG_SOC_AU1550 */
#ifdef CONFIG_SOC_AU1200
#define AU1200_UART0_INT 0
@@ -592,14 +862,14 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define AU1200_PSC1_INT 11
#define AU1200_AES_INT 12
#define AU1200_CAMERA_INT 13
-#define AU1200_TOY_INT 14
-#define AU1200_TOY_MATCH0_INT 15
-#define AU1200_TOY_MATCH1_INT 16
-#define AU1200_TOY_MATCH2_INT 17
-#define AU1200_RTC_INT 18
-#define AU1200_RTC_MATCH0_INT 19
-#define AU1200_RTC_MATCH1_INT 20
-#define AU1200_RTC_MATCH2_INT 21
+#define AU1000_TOY_INT 14
+#define AU1000_TOY_MATCH0_INT 15
+#define AU1000_TOY_MATCH1_INT 16
+#define AU1000_TOY_MATCH2_INT 17
+#define AU1000_RTC_INT 18
+#define AU1000_RTC_MATCH0_INT 19
+#define AU1000_RTC_MATCH1_INT 20
+#define AU1000_RTC_MATCH2_INT 21
#define AU1200_NAND_INT 23
#define AU1200_GPIO_204 24
#define AU1200_GPIO_205 25
@@ -607,6 +877,7 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define AU1200_GPIO_207 27
#define AU1200_GPIO_208_215 28 // Logical OR of 208:215
#define AU1200_USB_INT 29
+#define AU1000_USB_HOST_INT AU1200_USB_INT
#define AU1200_LCD_INT 30
#define AU1200_MAE_BOTH_INT 31
#define AU1000_GPIO_0 32
@@ -645,20 +916,36 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define UART0_ADDR 0xB1100000
#define UART1_ADDR 0xB1200000
-#define USB_OHCI_BASE 0x14020000 // phys addr for ioremap
-#define USB_HOST_CONFIG 0xB4027ffc
-
-// these are here for prototyping on au1550 (do not exist on au1200)
-#define AU1200_ETH0_BASE 0xB0500000
-#define AU1200_ETH1_BASE 0xB0510000
-#define AU1200_MAC0_ENABLE 0xB0520000
-#define AU1200_MAC1_ENABLE 0xB0520004
-#define NUM_ETH_INTERFACES 2
-#endif // CONFIG_SOC_AU1200
+#define USB_UOC_BASE 0x14020020
+#define USB_UOC_LEN 0x20
+#define USB_OHCI_BASE 0x14020100
+#define USB_OHCI_LEN 0x100
+#define USB_EHCI_BASE 0x14020200
+#define USB_EHCI_LEN 0x100
+#define USB_UDC_BASE 0x14022000
+#define USB_UDC_LEN 0x2000
+#define USB_MSR_BASE 0xB4020000
+#define USB_MSR_MCFG 4
+#define USBMSRMCFG_OMEMEN 0
+#define USBMSRMCFG_OBMEN 1
+#define USBMSRMCFG_EMEMEN 2
+#define USBMSRMCFG_EBMEN 3
+#define USBMSRMCFG_DMEMEN 4
+#define USBMSRMCFG_DBMEN 5
+#define USBMSRMCFG_GMEMEN 6
+#define USBMSRMCFG_OHCCLKEN 16
+#define USBMSRMCFG_EHCCLKEN 17
+#define USBMSRMCFG_UDCCLKEN 18
+#define USBMSRMCFG_PHYPLLEN 19
+#define USBMSRMCFG_RDCOMB 30
+#define USBMSRMCFG_PFEN 31
+
+#endif /* CONFIG_SOC_AU1200 */
#define AU1000_LAST_INTC0_INT 31
+#define AU1000_LAST_INTC1_INT 63
#define AU1000_MAX_INTR 63
-
+#define INTX 0xFF /* not valid */
/* Programmable Counters 0 and 1 */
#define SYS_BASE 0xB1900000
@@ -730,6 +1017,8 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define I2S_CONTROL_D (1<<1)
#define I2S_CONTROL_CE (1<<0)
+#ifndef CONFIG_SOC_AU1200
+
/* USB Host Controller */
#define USB_OHCI_LEN 0x00100000
@@ -775,6 +1064,8 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define USBDEV_ENABLE (1<<1)
#define USBDEV_CE (1<<0)
+#endif /* !CONFIG_SOC_AU1200 */
+
/* Ethernet Controllers */
/* 4 byte offsets from AU1000_ETH_BASE */
@@ -1173,6 +1464,37 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define SYS_PF_PSC1_S1 (1 << 1)
#define SYS_PF_MUST_BE_SET ((1 << 5) | (1 << 2))
+/* Au1200 Only */
+#ifdef CONFIG_SOC_AU1200
+#define SYS_PINFUNC_DMA (1<<31)
+#define SYS_PINFUNC_S0A (1<<30)
+#define SYS_PINFUNC_S1A (1<<29)
+#define SYS_PINFUNC_LP0 (1<<28)
+#define SYS_PINFUNC_LP1 (1<<27)
+#define SYS_PINFUNC_LD16 (1<<26)
+#define SYS_PINFUNC_LD8 (1<<25)
+#define SYS_PINFUNC_LD1 (1<<24)
+#define SYS_PINFUNC_LD0 (1<<23)
+#define SYS_PINFUNC_P1A (3<<21)
+#define SYS_PINFUNC_P1B (1<<20)
+#define SYS_PINFUNC_FS3 (1<<19)
+#define SYS_PINFUNC_P0A (3<<17)
+#define SYS_PINFUNC_CS (1<<16)
+#define SYS_PINFUNC_CIM (1<<15)
+#define SYS_PINFUNC_P1C (1<<14)
+#define SYS_PINFUNC_U1T (1<<12)
+#define SYS_PINFUNC_U1R (1<<11)
+#define SYS_PINFUNC_EX1 (1<<10)
+#define SYS_PINFUNC_EX0 (1<<9)
+#define SYS_PINFUNC_U0R (1<<8)
+#define SYS_PINFUNC_MC (1<<7)
+#define SYS_PINFUNC_S0B (1<<6)
+#define SYS_PINFUNC_S0C (1<<5)
+#define SYS_PINFUNC_P0B (1<<4)
+#define SYS_PINFUNC_U0T (1<<3)
+#define SYS_PINFUNC_S1B (1<<2)
+#endif
+
#define SYS_TRIOUTRD 0xB1900100
#define SYS_TRIOUTCLR 0xB1900100
#define SYS_OUTPUTRD 0xB1900108
@@ -1239,6 +1561,12 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define SYS_CS_MI2_MASK (0x7<<SYS_CS_MI2_BIT)
#define SYS_CS_DI2 (1<<16)
#define SYS_CS_CI2 (1<<15)
+#ifdef CONFIG_SOC_AU1100
+ #define SYS_CS_ML_BIT 7
+ #define SYS_CS_ML_MASK (0x7<<SYS_CS_ML_BIT)
+ #define SYS_CS_DL (1<<6)
+ #define SYS_CS_CL (1<<5)
+#else
#define SYS_CS_MUH_BIT 12
#define SYS_CS_MUH_MASK (0x7<<SYS_CS_MUH_BIT)
#define SYS_CS_DUH (1<<11)
@@ -1247,6 +1575,7 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define SYS_CS_MUD_MASK (0x7<<SYS_CS_MUD_BIT)
#define SYS_CS_DUD (1<<6)
#define SYS_CS_CUD (1<<5)
+#endif
#define SYS_CS_MIR_BIT 2
#define SYS_CS_MIR_MASK (0x7<<SYS_CS_MIR_BIT)
#define SYS_CS_DIR (1<<1)
@@ -1300,7 +1629,6 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define SD1_XMIT_FIFO 0xB0680000
#define SD1_RECV_FIFO 0xB0680004
-
#if defined (CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550)
/* Au1500 PCI Controller */
#define Au1500_CFG_BASE 0xB4005000 // virtual, kseg0 addr
@@ -1363,36 +1691,77 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
_ctl_; })
-#else /* Au1000 and Au1100 */
+#else /* Au1000 and Au1100 and Au1200 */
/* don't allow any legacy ports probing */
-#define IOPORT_RESOURCE_START 0x10000000;
+#define IOPORT_RESOURCE_START 0x10000000
#define IOPORT_RESOURCE_END 0xffffffff
#define IOMEM_RESOURCE_START 0x10000000
#define IOMEM_RESOURCE_END 0xffffffff
-#ifdef CONFIG_MIPS_PB1000
-#define PCI_IO_START 0x10000000
-#define PCI_IO_END 0x1000ffff
-#define PCI_MEM_START 0x18000000
-#define PCI_MEM_END 0x18ffffff
-#define PCI_FIRST_DEVFN 0
-#define PCI_LAST_DEVFN 1
-#else
-/* no PCI bus controller */
#define PCI_IO_START 0
#define PCI_IO_END 0
#define PCI_MEM_START 0
#define PCI_MEM_END 0
#define PCI_FIRST_DEVFN 0
#define PCI_LAST_DEVFN 0
-#endif
#endif
+#ifndef _LANGUAGE_ASSEMBLY
+typedef volatile struct
+{
+ /* 0x0000 */ u32 toytrim;
+ /* 0x0004 */ u32 toywrite;
+ /* 0x0008 */ u32 toymatch0;
+ /* 0x000C */ u32 toymatch1;
+ /* 0x0010 */ u32 toymatch2;
+ /* 0x0014 */ u32 cntrctrl;
+ /* 0x0018 */ u32 scratch0;
+ /* 0x001C */ u32 scratch1;
+ /* 0x0020 */ u32 freqctrl0;
+ /* 0x0024 */ u32 freqctrl1;
+ /* 0x0028 */ u32 clksrc;
+ /* 0x002C */ u32 pinfunc;
+ /* 0x0030 */ u32 reserved0;
+ /* 0x0034 */ u32 wakemsk;
+ /* 0x0038 */ u32 endian;
+ /* 0x003C */ u32 powerctrl;
+ /* 0x0040 */ u32 toyread;
+ /* 0x0044 */ u32 rtctrim;
+ /* 0x0048 */ u32 rtcwrite;
+ /* 0x004C */ u32 rtcmatch0;
+ /* 0x0050 */ u32 rtcmatch1;
+ /* 0x0054 */ u32 rtcmatch2;
+ /* 0x0058 */ u32 rtcread;
+ /* 0x005C */ u32 wakesrc;
+ /* 0x0060 */ u32 cpupll;
+ /* 0x0064 */ u32 auxpll;
+ /* 0x0068 */ u32 reserved1;
+ /* 0x006C */ u32 reserved2;
+ /* 0x0070 */ u32 reserved3;
+ /* 0x0074 */ u32 reserved4;
+ /* 0x0078 */ u32 slppwr;
+ /* 0x007C */ u32 sleep;
+ /* 0x0080 */ u32 reserved5[32];
+ /* 0x0100 */ u32 trioutrd;
+#define trioutclr trioutrd
+ /* 0x0104 */ u32 reserved6;
+ /* 0x0108 */ u32 outputrd;
+#define outputset outputrd
+ /* 0x010C */ u32 outputclr;
+ /* 0x0110 */ u32 pinstaterd;
+#define pininputen pinstaterd
+
+} AU1X00_SYS;
+
+static AU1X00_SYS* const sys = (AU1X00_SYS *)SYS_BASE;
+
+#endif
/* Processor information base on prid.
* Copied from PowerPC.
*/
+#ifndef _LANGUAGE_ASSEMBLY
struct cpu_spec {
/* CPU is matched via (PRID & prid_mask) == prid_value */
unsigned int prid_mask;
@@ -1406,3 +1775,6 @@ struct cpu_spec {
extern struct cpu_spec cpu_specs[];
extern struct cpu_spec *cur_cpu_spec[];
#endif
+
+#endif
+
diff --git a/include/asm-mips/mach-au1x00/au1xxx.h b/include/asm-mips/mach-au1x00/au1xxx.h
new file mode 100644
index 000000000000..b7b46dd9b929
--- /dev/null
+++ b/include/asm-mips/mach-au1x00/au1xxx.h
@@ -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.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _AU1XXX_H_
+#define _AU1XXX_H_
+
+#include <linux/config.h>
+
+#include <asm/mach-au1x00/au1000.h>
+
+#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550)
+#include <asm/mach-db1x00/db1x00.h>
+
+#elif defined(CONFIG_MIPS_PB1550)
+#include <asm/mach-pb1x00/pb1550.h>
+
+#elif defined(CONFIG_MIPS_PB1200)
+#include <asm/mach-pb1x00/pb1200.h>
+
+#elif defined(CONFIG_MIPS_DB1200)
+#include <asm/mach-db1x00/db1200.h>
+
+#endif
+
+#endif /* _AU1XXX_H_ */
diff --git a/include/asm-mips/mach-au1x00/au1xxx_dbdma.h b/include/asm-mips/mach-au1x00/au1xxx_dbdma.h
index d5eb88cd7d51..b327bcd3fee1 100644
--- a/include/asm-mips/mach-au1x00/au1xxx_dbdma.h
+++ b/include/asm-mips/mach-au1x00/au1xxx_dbdma.h
@@ -45,7 +45,7 @@
#define DDMA_GLOBAL_BASE 0xb4003000
#define DDMA_CHANNEL_BASE 0xb4002000
-typedef struct dbdma_global {
+typedef volatile struct dbdma_global {
u32 ddma_config;
u32 ddma_intstat;
u32 ddma_throttle;
@@ -62,7 +62,7 @@ typedef struct dbdma_global {
/* The structure of a DMA Channel.
*/
-typedef struct au1xxx_dma_channel {
+typedef volatile struct au1xxx_dma_channel {
u32 ddma_cfg; /* See below */
u32 ddma_desptr; /* 32-byte aligned pointer to descriptor */
u32 ddma_statptr; /* word aligned pointer to status word */
@@ -98,7 +98,7 @@ typedef struct au1xxx_dma_channel {
/* "Standard" DDMA Descriptor.
* Must be 32-byte aligned.
*/
-typedef struct au1xxx_ddma_desc {
+typedef volatile struct au1xxx_ddma_desc {
u32 dscr_cmd0; /* See below */
u32 dscr_cmd1; /* See below */
u32 dscr_source0; /* source phys address */
@@ -107,6 +107,12 @@ typedef struct au1xxx_ddma_desc {
u32 dscr_dest1; /* See below */
u32 dscr_stat; /* completion status */
u32 dscr_nxtptr; /* Next descriptor pointer (mostly) */
+ /* First 32bytes are HW specific!!!
+ Lets have some SW data following.. make sure its 32bytes
+ */
+ u32 sw_status;
+ u32 sw_context;
+ u32 sw_reserved[6];
} au1x_ddma_desc_t;
#define DSCR_CMD0_V (1 << 31) /* Descriptor valid */
@@ -125,8 +131,11 @@ typedef struct au1xxx_ddma_desc {
#define DSCR_CMD0_CV (0x1 << 2) /* Clear Valid when done */
#define DSCR_CMD0_ST_MASK (0x3 << 0) /* Status instruction */
+#define SW_STATUS_INUSE (1<<0)
+
/* Command 0 device IDs.
*/
+#ifdef CONFIG_SOC_AU1550
#define DSCR_CMD0_UART0_TX 0
#define DSCR_CMD0_UART0_RX 1
#define DSCR_CMD0_UART3_TX 2
@@ -155,9 +164,45 @@ typedef struct au1xxx_ddma_desc {
#define DSCR_CMD0_MAC0_TX 25
#define DSCR_CMD0_MAC1_RX 26
#define DSCR_CMD0_MAC1_TX 27
+#endif /* CONFIG_SOC_AU1550 */
+
+#ifdef CONFIG_SOC_AU1200
+#define DSCR_CMD0_UART0_TX 0
+#define DSCR_CMD0_UART0_RX 1
+#define DSCR_CMD0_UART1_TX 2
+#define DSCR_CMD0_UART1_RX 3
+#define DSCR_CMD0_DMA_REQ0 4
+#define DSCR_CMD0_DMA_REQ1 5
+#define DSCR_CMD0_MAE_BE 6
+#define DSCR_CMD0_MAE_FE 7
+#define DSCR_CMD0_SDMS_TX0 8
+#define DSCR_CMD0_SDMS_RX0 9
+#define DSCR_CMD0_SDMS_TX1 10
+#define DSCR_CMD0_SDMS_RX1 11
+#define DSCR_CMD0_AES_TX 13
+#define DSCR_CMD0_AES_RX 12
+#define DSCR_CMD0_PSC0_TX 14
+#define DSCR_CMD0_PSC0_RX 15
+#define DSCR_CMD0_PSC1_TX 16
+#define DSCR_CMD0_PSC1_RX 17
+#define DSCR_CMD0_CIM_RXA 18
+#define DSCR_CMD0_CIM_RXB 19
+#define DSCR_CMD0_CIM_RXC 20
+#define DSCR_CMD0_MAE_BOTH 21
+#define DSCR_CMD0_LCD 22
+#define DSCR_CMD0_NAND_FLASH 23
+#define DSCR_CMD0_PSC0_SYNC 24
+#define DSCR_CMD0_PSC1_SYNC 25
+#define DSCR_CMD0_CIM_SYNC 26
+#endif /* CONFIG_SOC_AU1200 */
+
#define DSCR_CMD0_THROTTLE 30
#define DSCR_CMD0_ALWAYS 31
#define DSCR_NDEV_IDS 32
+/* THis macro is used to find/create custom device types */
+#define DSCR_DEV2CUSTOM_ID(x,d) (((((x)&0xFFFF)<<8)|0x32000000)|((d)&0xFF))
+#define DSCR_CUSTOM2DEV_ID(x) ((x)&0xFF)
+
#define DSCR_CMD0_SID(x) (((x) & 0x1f) << 25)
#define DSCR_CMD0_DID(x) (((x) & 0x1f) << 20)
@@ -246,6 +291,43 @@ typedef struct au1xxx_ddma_desc {
*/
#define NUM_DBDMA_CHANS 16
+/*
+ * Ddma API definitions
+ * FIXME: may not fit to this header file
+ */
+typedef struct dbdma_device_table {
+ u32 dev_id;
+ u32 dev_flags;
+ u32 dev_tsize;
+ u32 dev_devwidth;
+ u32 dev_physaddr; /* If FIFO */
+ u32 dev_intlevel;
+ u32 dev_intpolarity;
+} dbdev_tab_t;
+
+
+typedef struct dbdma_chan_config {
+ spinlock_t lock;
+
+ u32 chan_flags;
+ u32 chan_index;
+ dbdev_tab_t *chan_src;
+ dbdev_tab_t *chan_dest;
+ au1x_dma_chan_t *chan_ptr;
+ au1x_ddma_desc_t *chan_desc_base;
+ au1x_ddma_desc_t *get_ptr, *put_ptr, *cur_ptr;
+ void *chan_callparam;
+ void (*chan_callback)(int, void *, struct pt_regs *);
+} chan_tab_t;
+
+#define DEV_FLAGS_INUSE (1 << 0)
+#define DEV_FLAGS_ANYUSE (1 << 1)
+#define DEV_FLAGS_OUT (1 << 2)
+#define DEV_FLAGS_IN (1 << 3)
+#define DEV_FLAGS_BURSTABLE (1 << 4)
+#define DEV_FLAGS_SYNC (1 << 5)
+/* end Ddma API definitions */
+
/* External functions for drivers to use.
*/
/* Use this to allocate a dbdma channel. The device ids are one of the
@@ -258,18 +340,6 @@ u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
#define DBDMA_MEM_CHAN DSCR_CMD0_ALWAYS
-/* ACK! These should be in a board specific description file.
-*/
-#ifdef CONFIG_MIPS_PB1550
-#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
-#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
-#endif
-#ifdef CONFIG_MIPS_DB1550
-#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
-#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
-#endif
-
-
/* Set the device width of a in/out fifo.
*/
u32 au1xxx_dbdma_set_devwidth(u32 chanid, int bits);
@@ -280,8 +350,8 @@ u32 au1xxx_dbdma_ring_alloc(u32 chanid, int entries);
/* Put buffers on source/destination descriptors.
*/
-u32 au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes);
-u32 au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes);
+u32 _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags);
+u32 _au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags);
/* Get a buffer from the destination descriptor.
*/
@@ -295,5 +365,29 @@ u32 au1xxx_get_dma_residue(u32 chanid);
void au1xxx_dbdma_chan_free(u32 chanid);
void au1xxx_dbdma_dump(u32 chanid);
+u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr );
+
+u32 au1xxx_ddma_add_device( dbdev_tab_t *dev );
+void * au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp);
+
+/*
+ Some compatibilty macros --
+ Needed to make changes to API without breaking existing drivers
+*/
+#define au1xxx_dbdma_put_source(chanid,buf,nbytes)_au1xxx_dbdma_put_source(chanid, buf, nbytes, DDMA_FLAGS_IE)
+#define au1xxx_dbdma_put_source_flags(chanid,buf,nbytes,flags) _au1xxx_dbdma_put_source(chanid, buf, nbytes, flags)
+#define put_source_flags(chanid,buf,nbytes,flags) au1xxx_dbdma_put_source_flags(chanid,buf,nbytes,flags)
+
+
+#define au1xxx_dbdma_put_dest(chanid,buf,nbytes) _au1xxx_dbdma_put_dest(chanid, buf, nbytes, DDMA_FLAGS_IE)
+#define au1xxx_dbdma_put_dest_flags(chanid,buf,nbytes,flags) _au1xxx_dbdma_put_dest(chanid, buf, nbytes, flags)
+#define put_dest_flags(chanid,buf,nbytes,flags) au1xxx_dbdma_put_dest_flags(chanid,buf,nbytes,flags)
+
+/*
+ * Flags for the put_source/put_dest functions.
+ */
+#define DDMA_FLAGS_IE (1<<0)
+#define DDMA_FLAGS_NOIE (1<<1)
+
#endif /* _LANGUAGE_ASSEMBLY */
#endif /* _AU1000_DBDMA_H_ */
diff --git a/include/asm-mips/mach-au1x00/au1xxx_gpio.h b/include/asm-mips/mach-au1x00/au1xxx_gpio.h
new file mode 100644
index 000000000000..27911e054ffc
--- /dev/null
+++ b/include/asm-mips/mach-au1x00/au1xxx_gpio.h
@@ -0,0 +1,20 @@
+#ifndef __AU1XXX_GPIO_H
+#define __AU1XXX_GPIO_H
+
+void au1xxx_gpio1_set_inputs(void);
+void au1xxx_gpio_tristate(int signal);
+void au1xxx_gpio_write(int signal, int value);
+int au1xxx_gpio_read(int signal);
+
+typedef volatile struct
+{
+ u32 dir;
+ u32 reserved;
+ u32 output;
+ u32 pinstate;
+ u32 inten;
+ u32 enable;
+
+} AU1X00_GPIO2;
+
+#endif //__AU1XXX_GPIO_H
diff --git a/include/asm-mips/mach-au1x00/au1xxx_ide.h b/include/asm-mips/mach-au1x00/au1xxx_ide.h
new file mode 100644
index 000000000000..33d275c3b84c
--- /dev/null
+++ b/include/asm-mips/mach-au1x00/au1xxx_ide.h
@@ -0,0 +1,301 @@
+/*
+ * include/asm-mips/mach-au1x00/au1xxx_ide.h version 01.30.00 Aug. 02 2005
+ *
+ * BRIEF MODULE DESCRIPTION
+ * AMD Alchemy Au1xxx IDE interface routines over the Static Bus
+ *
+ * Copyright (c) 2003-2005 AMD, Personal Connectivity Solutions
+ *
+ * This program is free software; you can redistribute 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.
+ *
+ * Note: for more information, please refer "AMD Alchemy Au1200/Au1550 IDE
+ * Interface and Linux Device Driver" Application Note.
+ */
+#include <linux/config.h>
+
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+ #define DMA_WAIT_TIMEOUT 100
+ #define NUM_DESCRIPTORS PRD_ENTRIES
+#else /* CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA */
+ #define NUM_DESCRIPTORS 2
+#endif
+
+#ifndef AU1XXX_ATA_RQSIZE
+ #define AU1XXX_ATA_RQSIZE 128
+#endif
+
+/* Disable Burstable-Support for DBDMA */
+#ifndef CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON
+ #define CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON 0
+#endif
+
+#ifdef CONFIG_PM
+/*
+* This will enable the device to be powered up when write() or read()
+* is called. If this is not defined, the driver will return -EBUSY.
+*/
+#define WAKE_ON_ACCESS 1
+
+typedef struct
+{
+ spinlock_t lock; /* Used to block on state transitions */
+ au1xxx_power_dev_t *dev; /* Power Managers device structure */
+ unsigned stopped; /* USed to signaling device is stopped */
+} pm_state;
+#endif
+
+
+typedef struct
+{
+ u32 tx_dev_id, rx_dev_id, target_dev_id;
+ u32 tx_chan, rx_chan;
+ void *tx_desc_head, *rx_desc_head;
+ ide_hwif_t *hwif;
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+ ide_drive_t *drive;
+ u8 white_list, black_list;
+ struct dbdma_cmd *dma_table_cpu;
+ dma_addr_t dma_table_dma;
+ struct scatterlist *sg_table;
+ int sg_nents;
+ int sg_dma_direction;
+#endif
+ struct device *dev;
+ int irq;
+ u32 regbase;
+#ifdef CONFIG_PM
+ pm_state pm;
+#endif
+} _auide_hwif;
+
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+struct drive_list_entry {
+ const char * id_model;
+ const char * id_firmware;
+};
+
+/* HD white list */
+static const struct drive_list_entry dma_white_list [] = {
+/*
+ * Hitachi
+ */
+ { "HITACHI_DK14FA-20" , "ALL" },
+ { "HTS726060M9AT00" , "ALL" },
+/*
+ * Maxtor
+ */
+ { "Maxtor 6E040L0" , "ALL" },
+ { "Maxtor 6Y080P0" , "ALL" },
+ { "Maxtor 6Y160P0" , "ALL" },
+/*
+ * Seagate
+ */
+ { "ST3120026A" , "ALL" },
+ { "ST320014A" , "ALL" },
+ { "ST94011A" , "ALL" },
+ { "ST340016A" , "ALL" },
+/*
+ * Western Digital
+ */
+ { "WDC WD400UE-00HCT0" , "ALL" },
+ { "WDC WD400JB-00JJC0" , "ALL" },
+ { NULL , NULL }
+};
+
+/* HD black list */
+static const struct drive_list_entry dma_black_list [] = {
+/*
+ * Western Digital
+ */
+ { "WDC WD100EB-00CGH0" , "ALL" },
+ { "WDC WD200BB-00AUA1" , "ALL" },
+ { "WDC AC24300L" , "ALL" },
+ { NULL , NULL }
+};
+#endif
+
+/* function prototyping */
+u8 auide_inb(unsigned long port);
+u16 auide_inw(unsigned long port);
+u32 auide_inl(unsigned long port);
+void auide_insw(unsigned long port, void *addr, u32 count);
+void auide_insl(unsigned long port, void *addr, u32 count);
+void auide_outb(u8 addr, unsigned long port);
+void auide_outbsync(ide_drive_t *drive, u8 addr, unsigned long port);
+void auide_outw(u16 addr, unsigned long port);
+void auide_outl(u32 addr, unsigned long port);
+void auide_outsw(unsigned long port, void *addr, u32 count);
+void auide_outsl(unsigned long port, void *addr, u32 count);
+static void auide_tune_drive(ide_drive_t *drive, byte pio);
+static int auide_tune_chipset (ide_drive_t *drive, u8 speed);
+static int auide_ddma_init( _auide_hwif *auide );
+static void auide_setup_ports(hw_regs_t *hw, _auide_hwif *ahwif);
+int __init auide_probe(void);
+
+#ifdef CONFIG_PM
+ int au1200ide_pm_callback( au1xxx_power_dev_t *dev,
+ au1xxx_request_t request, void *data);
+ static int au1xxxide_pm_standby( au1xxx_power_dev_t *dev );
+ static int au1xxxide_pm_sleep( au1xxx_power_dev_t *dev );
+ static int au1xxxide_pm_resume( au1xxx_power_dev_t *dev );
+ static int au1xxxide_pm_getstatus( au1xxx_power_dev_t *dev );
+ static int au1xxxide_pm_access( au1xxx_power_dev_t *dev );
+ static int au1xxxide_pm_idle( au1xxx_power_dev_t *dev );
+ static int au1xxxide_pm_cleanup( au1xxx_power_dev_t *dev );
+#endif
+
+
+/*
+ * Multi-Word DMA + DbDMA functions
+ */
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+
+ static int in_drive_list(struct hd_driveid *id,
+ const struct drive_list_entry *drive_table);
+ static int auide_build_sglist(ide_drive_t *drive, struct request *rq);
+ static int auide_build_dmatable(ide_drive_t *drive);
+ static int auide_dma_end(ide_drive_t *drive);
+ static void auide_dma_start(ide_drive_t *drive );
+ ide_startstop_t auide_dma_intr (ide_drive_t *drive);
+ static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command);
+ static int auide_dma_setup(ide_drive_t *drive);
+ static int auide_dma_check(ide_drive_t *drive);
+ static int auide_dma_test_irq(ide_drive_t *drive);
+ static int auide_dma_host_off(ide_drive_t *drive);
+ static int auide_dma_host_on(ide_drive_t *drive);
+ static int auide_dma_lostirq(ide_drive_t *drive);
+ static int auide_dma_on(ide_drive_t *drive);
+ static void auide_ddma_tx_callback(int irq, void *param,
+ struct pt_regs *regs);
+ static void auide_ddma_rx_callback(int irq, void *param,
+ struct pt_regs *regs);
+ static int auide_dma_off_quietly(ide_drive_t *drive);
+ static int auide_dma_timeout(ide_drive_t *drive);
+
+#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
+
+/*******************************************************************************
+* PIO Mode timing calculation : *
+* *
+* Static Bus Spec ATA Spec *
+* Tcsoe = t1 *
+* Toecs = t9 *
+* Twcs = t9 *
+* Tcsh = t2i | t2 *
+* Tcsoff = t2i | t2 *
+* Twp = t2 *
+* Tcsw = t1 *
+* Tpm = 0 *
+* Ta = t1+t2 *
+*******************************************************************************/
+
+#define TCSOE_MASK (0x07<<29)
+#define TOECS_MASK (0x07<<26)
+#define TWCS_MASK (0x07<<28)
+#define TCSH_MASK (0x0F<<24)
+#define TCSOFF_MASK (0x07<<20)
+#define TWP_MASK (0x3F<<14)
+#define TCSW_MASK (0x0F<<10)
+#define TPM_MASK (0x0F<<6)
+#define TA_MASK (0x3F<<0)
+#define TS_MASK (1<<8)
+
+/* Timing parameters PIO mode 0 */
+#define SBC_IDE_PIO0_TCSOE (0x04<<29)
+#define SBC_IDE_PIO0_TOECS (0x01<<26)
+#define SBC_IDE_PIO0_TWCS (0x02<<28)
+#define SBC_IDE_PIO0_TCSH (0x08<<24)
+#define SBC_IDE_PIO0_TCSOFF (0x07<<20)
+#define SBC_IDE_PIO0_TWP (0x10<<14)
+#define SBC_IDE_PIO0_TCSW (0x04<<10)
+#define SBC_IDE_PIO0_TPM (0x0<<6)
+#define SBC_IDE_PIO0_TA (0x15<<0)
+/* Timing parameters PIO mode 1 */
+#define SBC_IDE_PIO1_TCSOE (0x03<<29)
+#define SBC_IDE_PIO1_TOECS (0x01<<26)
+#define SBC_IDE_PIO1_TWCS (0x01<<28)
+#define SBC_IDE_PIO1_TCSH (0x06<<24)
+#define SBC_IDE_PIO1_TCSOFF (0x06<<20)
+#define SBC_IDE_PIO1_TWP (0x08<<14)
+#define SBC_IDE_PIO1_TCSW (0x03<<10)
+#define SBC_IDE_PIO1_TPM (0x00<<6)
+#define SBC_IDE_PIO1_TA (0x0B<<0)
+/* Timing parameters PIO mode 2 */
+#define SBC_IDE_PIO2_TCSOE (0x05<<29)
+#define SBC_IDE_PIO2_TOECS (0x01<<26)
+#define SBC_IDE_PIO2_TWCS (0x01<<28)
+#define SBC_IDE_PIO2_TCSH (0x07<<24)
+#define SBC_IDE_PIO2_TCSOFF (0x07<<20)
+#define SBC_IDE_PIO2_TWP (0x1F<<14)
+#define SBC_IDE_PIO2_TCSW (0x05<<10)
+#define SBC_IDE_PIO2_TPM (0x00<<6)
+#define SBC_IDE_PIO2_TA (0x22<<0)
+/* Timing parameters PIO mode 3 */
+#define SBC_IDE_PIO3_TCSOE (0x05<<29)
+#define SBC_IDE_PIO3_TOECS (0x01<<26)
+#define SBC_IDE_PIO3_TWCS (0x01<<28)
+#define SBC_IDE_PIO3_TCSH (0x0D<<24)
+#define SBC_IDE_PIO3_TCSOFF (0x0D<<20)
+#define SBC_IDE_PIO3_TWP (0x15<<14)
+#define SBC_IDE_PIO3_TCSW (0x05<<10)
+#define SBC_IDE_PIO3_TPM (0x00<<6)
+#define SBC_IDE_PIO3_TA (0x1A<<0)
+/* Timing parameters PIO mode 4 */
+#define SBC_IDE_PIO4_TCSOE (0x04<<29)
+#define SBC_IDE_PIO4_TOECS (0x01<<26)
+#define SBC_IDE_PIO4_TWCS (0x01<<28)
+#define SBC_IDE_PIO4_TCSH (0x04<<24)
+#define SBC_IDE_PIO4_TCSOFF (0x04<<20)
+#define SBC_IDE_PIO4_TWP (0x0D<<14)
+#define SBC_IDE_PIO4_TCSW (0x03<<10)
+#define SBC_IDE_PIO4_TPM (0x00<<6)
+#define SBC_IDE_PIO4_TA (0x12<<0)
+/* Timing parameters MDMA mode 0 */
+#define SBC_IDE_MDMA0_TCSOE (0x03<<29)
+#define SBC_IDE_MDMA0_TOECS (0x01<<26)
+#define SBC_IDE_MDMA0_TWCS (0x01<<28)
+#define SBC_IDE_MDMA0_TCSH (0x07<<24)
+#define SBC_IDE_MDMA0_TCSOFF (0x07<<20)
+#define SBC_IDE_MDMA0_TWP (0x0C<<14)
+#define SBC_IDE_MDMA0_TCSW (0x03<<10)
+#define SBC_IDE_MDMA0_TPM (0x00<<6)
+#define SBC_IDE_MDMA0_TA (0x0F<<0)
+/* Timing parameters MDMA mode 1 */
+#define SBC_IDE_MDMA1_TCSOE (0x05<<29)
+#define SBC_IDE_MDMA1_TOECS (0x01<<26)
+#define SBC_IDE_MDMA1_TWCS (0x01<<28)
+#define SBC_IDE_MDMA1_TCSH (0x05<<24)
+#define SBC_IDE_MDMA1_TCSOFF (0x05<<20)
+#define SBC_IDE_MDMA1_TWP (0x0F<<14)
+#define SBC_IDE_MDMA1_TCSW (0x05<<10)
+#define SBC_IDE_MDMA1_TPM (0x00<<6)
+#define SBC_IDE_MDMA1_TA (0x15<<0)
+/* Timing parameters MDMA mode 2 */
+#define SBC_IDE_MDMA2_TCSOE (0x04<<29)
+#define SBC_IDE_MDMA2_TOECS (0x01<<26)
+#define SBC_IDE_MDMA2_TWCS (0x01<<28)
+#define SBC_IDE_MDMA2_TCSH (0x04<<24)
+#define SBC_IDE_MDMA2_TCSOFF (0x04<<20)
+#define SBC_IDE_MDMA2_TWP (0x0D<<14)
+#define SBC_IDE_MDMA2_TCSW (0x04<<10)
+#define SBC_IDE_MDMA2_TPM (0x00<<6)
+#define SBC_IDE_MDMA2_TA (0x12<<0)
+
diff --git a/include/asm-mips/mach-au1x00/au1xxx_psc.h b/include/asm-mips/mach-au1x00/au1xxx_psc.h
index 283519dfdec4..8e5fb3c7da4d 100644
--- a/include/asm-mips/mach-au1x00/au1xxx_psc.h
+++ b/include/asm-mips/mach-au1x00/au1xxx_psc.h
@@ -33,6 +33,8 @@
#ifndef _AU1000_PSC_H_
#define _AU1000_PSC_H_
+#include <linux/config.h>
+
/* The PSC base addresses. */
#ifdef CONFIG_SOC_AU1550
#define PSC0_BASE_ADDR 0xb1a00000
diff --git a/include/asm-mips/mach-au1x00/ioremap.h b/include/asm-mips/mach-au1x00/ioremap.h
new file mode 100644
index 000000000000..d3ec6274575a
--- /dev/null
+++ b/include/asm-mips/mach-au1x00/ioremap.h
@@ -0,0 +1,32 @@
+/*
+ * include/asm-mips/mach-au1x00/ioremap.h
+ *
+ * This program is free software; you can redistribute 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_AU1X00_IOREMAP_H
+#define __ASM_MACH_AU1X00_IOREMAP_H
+
+#include <linux/config.h>
+#include <linux/types.h>
+
+#ifdef CONFIG_64BIT_PHYS_ADDR
+extern phys_t __fixup_bigphys_addr(phys_t, phys_t);
+#else
+static inline phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+{
+ return phys_addr;
+}
+#endif
+
+/*
+ * Allow physical addresses to be fixed up to help 36-bit peripherals.
+ */
+static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+{
+ return __fixup_bigphys_addr(phys_addr, size);
+}
+
+#endif /* __ASM_MACH_AU1X00_IOREMAP_H */
diff --git a/include/asm-mips/mach-db1x00/db1200.h b/include/asm-mips/mach-db1x00/db1200.h
new file mode 100644
index 000000000000..5d894376fc1a
--- /dev/null
+++ b/include/asm-mips/mach-db1x00/db1200.h
@@ -0,0 +1,224 @@
+/*
+ * AMD Alchemy DB1200 Referrence Board
+ * Board Registers defines.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ *
+ */
+#ifndef __ASM_DB1200_H
+#define __ASM_DB1200_H
+
+#include <linux/types.h>
+
+// This is defined in au1000.h with bogus value
+#undef AU1X00_EXTERNAL_INT
+
+#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
+#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
+#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC1_TX
+#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC1_RX
+
+/* SPI and SMB are muxed on the Pb1200 board.
+ Refer to board documentation.
+ */
+#define SPI_PSC_BASE PSC0_BASE_ADDR
+#define SMBUS_PSC_BASE PSC0_BASE_ADDR
+/* AC97 and I2S are muxed on the Pb1200 board.
+ Refer to board documentation.
+ */
+#define AC97_PSC_BASE PSC1_BASE_ADDR
+#define I2S_PSC_BASE PSC1_BASE_ADDR
+
+#define BCSR_KSEG1_ADDR 0xB9800000
+
+typedef volatile struct
+{
+ /*00*/ u16 whoami;
+ u16 reserved0;
+ /*04*/ u16 status;
+ u16 reserved1;
+ /*08*/ u16 switches;
+ u16 reserved2;
+ /*0C*/ u16 resets;
+ u16 reserved3;
+
+ /*10*/ u16 pcmcia;
+ u16 reserved4;
+ /*14*/ u16 board;
+ u16 reserved5;
+ /*18*/ u16 disk_leds;
+ u16 reserved6;
+ /*1C*/ u16 system;
+ u16 reserved7;
+
+ /*20*/ u16 intclr;
+ u16 reserved8;
+ /*24*/ u16 intset;
+ u16 reserved9;
+ /*28*/ u16 intclr_mask;
+ u16 reserved10;
+ /*2C*/ u16 intset_mask;
+ u16 reserved11;
+
+ /*30*/ u16 sig_status;
+ u16 reserved12;
+ /*34*/ u16 int_status;
+ u16 reserved13;
+ /*38*/ u16 reserved14;
+ u16 reserved15;
+ /*3C*/ u16 reserved16;
+ u16 reserved17;
+
+} BCSR;
+
+static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+
+/*
+ * Register bit definitions for the BCSRs
+ */
+#define BCSR_WHOAMI_DCID 0x000F
+#define BCSR_WHOAMI_CPLD 0x00F0
+#define BCSR_WHOAMI_BOARD 0x0F00
+
+#define BCSR_STATUS_PCMCIA0VS 0x0003
+#define BCSR_STATUS_PCMCIA1VS 0x000C
+#define BCSR_STATUS_SWAPBOOT 0x0040
+#define BCSR_STATUS_FLASHBUSY 0x0100
+#define BCSR_STATUS_IDECBLID 0x0200
+#define BCSR_STATUS_SD0WP 0x0400
+#define BCSR_STATUS_U0RXD 0x1000
+#define BCSR_STATUS_U1RXD 0x2000
+
+#define BCSR_SWITCHES_OCTAL 0x00FF
+#define BCSR_SWITCHES_DIP_1 0x0080
+#define BCSR_SWITCHES_DIP_2 0x0040
+#define BCSR_SWITCHES_DIP_3 0x0020
+#define BCSR_SWITCHES_DIP_4 0x0010
+#define BCSR_SWITCHES_DIP_5 0x0008
+#define BCSR_SWITCHES_DIP_6 0x0004
+#define BCSR_SWITCHES_DIP_7 0x0002
+#define BCSR_SWITCHES_DIP_8 0x0001
+#define BCSR_SWITCHES_ROTARY 0x0F00
+
+#define BCSR_RESETS_ETH 0x0001
+#define BCSR_RESETS_CAMERA 0x0002
+#define BCSR_RESETS_DC 0x0004
+#define BCSR_RESETS_IDE 0x0008
+#define BCSR_RESETS_TV 0x0010
+/* not resets but in the same register */
+#define BCSR_RESETS_PWMR1mUX 0x0800
+#define BCSR_RESETS_PCS0MUX 0x1000
+#define BCSR_RESETS_PCS1MUX 0x2000
+#define BCSR_RESETS_SPISEL 0x4000
+
+#define BCSR_PCMCIA_PC0VPP 0x0003
+#define BCSR_PCMCIA_PC0VCC 0x000C
+#define BCSR_PCMCIA_PC0DRVEN 0x0010
+#define BCSR_PCMCIA_PC0RST 0x0080
+#define BCSR_PCMCIA_PC1VPP 0x0300
+#define BCSR_PCMCIA_PC1VCC 0x0C00
+#define BCSR_PCMCIA_PC1DRVEN 0x1000
+#define BCSR_PCMCIA_PC1RST 0x8000
+
+#define BCSR_BOARD_LCDVEE 0x0001
+#define BCSR_BOARD_LCDVDD 0x0002
+#define BCSR_BOARD_LCDBL 0x0004
+#define BCSR_BOARD_CAMSNAP 0x0010
+#define BCSR_BOARD_CAMPWR 0x0020
+#define BCSR_BOARD_SD0PWR 0x0040
+
+#define BCSR_LEDS_DECIMALS 0x0003
+#define BCSR_LEDS_LED0 0x0100
+#define BCSR_LEDS_LED1 0x0200
+#define BCSR_LEDS_LED2 0x0400
+#define BCSR_LEDS_LED3 0x0800
+
+#define BCSR_SYSTEM_POWEROFF 0x4000
+#define BCSR_SYSTEM_RESET 0x8000
+
+/* Bit positions for the different interrupt sources */
+#define BCSR_INT_IDE 0x0001
+#define BCSR_INT_ETH 0x0002
+#define BCSR_INT_PC0 0x0004
+#define BCSR_INT_PC0STSCHG 0x0008
+#define BCSR_INT_PC1 0x0010
+#define BCSR_INT_PC1STSCHG 0x0020
+#define BCSR_INT_DC 0x0040
+#define BCSR_INT_FLASHBUSY 0x0080
+#define BCSR_INT_PC0INSERT 0x0100
+#define BCSR_INT_PC0EJECT 0x0200
+#define BCSR_INT_PC1INSERT 0x0400
+#define BCSR_INT_PC1EJECT 0x0800
+#define BCSR_INT_SD0INSERT 0x1000
+#define BCSR_INT_SD0EJECT 0x2000
+
+#define AU1XXX_SMC91111_PHYS_ADDR (0x19000300)
+#define AU1XXX_SMC91111_IRQ DB1200_ETH_INT
+
+#define AU1XXX_ATA_PHYS_ADDR (0x18800000)
+#define AU1XXX_ATA_PHYS_LEN (0x100)
+#define AU1XXX_ATA_REG_OFFSET (5)
+#define AU1XXX_ATA_INT DB1200_IDE_INT
+#define AU1XXX_ATA_DDMA_REQ DSCR_CMD0_DMA_REQ1;
+#define AU1XXX_ATA_RQSIZE 128
+
+#define NAND_PHYS_ADDR 0x20000000
+
+/*
+ * External Interrupts for Pb1200 as of 8/6/2004.
+ * Bit positions in the CPLD registers can be calculated by taking
+ * the interrupt define and subtracting the DB1200_INT_BEGIN value.
+ * *example: IDE bis pos is = 64 - 64
+ ETH bit pos is = 65 - 64
+ */
+#define DB1200_INT_BEGIN (AU1000_LAST_INTC1_INT + 1)
+#define DB1200_IDE_INT (DB1200_INT_BEGIN + 0)
+#define DB1200_ETH_INT (DB1200_INT_BEGIN + 1)
+#define DB1200_PC0_INT (DB1200_INT_BEGIN + 2)
+#define DB1200_PC0_STSCHG_INT (DB1200_INT_BEGIN + 3)
+#define DB1200_PC1_INT (DB1200_INT_BEGIN + 4)
+#define DB1200_PC1_STSCHG_INT (DB1200_INT_BEGIN + 5)
+#define DB1200_DC_INT (DB1200_INT_BEGIN + 6)
+#define DB1200_FLASHBUSY_INT (DB1200_INT_BEGIN + 7)
+#define DB1200_PC0_INSERT_INT (DB1200_INT_BEGIN + 8)
+#define DB1200_PC0_EJECT_INT (DB1200_INT_BEGIN + 9)
+#define DB1200_PC1_INSERT_INT (DB1200_INT_BEGIN + 10)
+#define DB1200_PC1_EJECT_INT (DB1200_INT_BEGIN + 11)
+#define DB1200_SD0_INSERT_INT (DB1200_INT_BEGIN + 12)
+#define DB1200_SD0_EJECT_INT (DB1200_INT_BEGIN + 13)
+
+#define DB1200_INT_END (DB1200_INT_BEGIN + 15)
+
+/* For drivers/pcmcia/au1000_db1x00.c */
+
+/* PCMCIA Db1x00 specific defines */
+
+#define PCMCIA_MAX_SOCK 1
+#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
+
+/* VPP/VCC */
+#define SET_VCC_VPP(VCC, VPP, SLOT)\
+ ((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8))
+
+#define BOARD_PC0_INT DB1200_PC0_INT
+#define BOARD_PC1_INT DB1200_PC1_INT
+#define BOARD_CARD_INSERTED(SOCKET) bcsr->sig_status & (1<<(8+(2*SOCKET)))
+
+#endif /* __ASM_DB1200_H */
+
diff --git a/include/asm-mips/mach-dec/mc146818rtc.h b/include/asm-mips/mach-dec/mc146818rtc.h
index a326f451253b..6d37a5675803 100644
--- a/include/asm-mips/mach-dec/mc146818rtc.h
+++ b/include/asm-mips/mach-dec/mc146818rtc.h
@@ -3,7 +3,7 @@
*
* Copyright (C) 1998, 2001 by Ralf Baechle
* Copyright (C) 1998 by Harald Koerfgen
- * Copyright (C) 2002 Maciej W. Rozycki
+ * Copyright (C) 2002, 2005 Maciej W. Rozycki
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -14,23 +14,18 @@
#define __ASM_MIPS_DEC_RTC_DEC_H
#include <linux/types.h>
-
#include <asm/addrspace.h>
+#include <asm/dec/system.h>
extern volatile u8 *dec_rtc_base;
-extern unsigned long dec_kn_slot_size;
-#define RTC_PORT(x) CPHYSADDR(dec_rtc_base)
+#define RTC_PORT(x) CPHYSADDR((long)dec_rtc_base)
#define RTC_IO_EXTENT dec_kn_slot_size
#define RTC_IOMAPPED 0
#undef RTC_IRQ
#define RTC_DEC_YEAR 0x3f /* Where we store the real year on DECs. */
-#include <linux/mc146818rtc.h>
-#include <linux/module.h>
-#include <linux/types.h>
-
static inline unsigned char CMOS_READ(unsigned long addr)
{
return dec_rtc_base[addr * 4];
diff --git a/include/asm-mips/mach-generic/cpu-feature-overrides.h b/include/asm-mips/mach-generic/cpu-feature-overrides.h
index 0aecfd08e39a..7c185bb06f13 100644
--- a/include/asm-mips/mach-generic/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-generic/cpu-feature-overrides.h
@@ -8,6 +8,6 @@
#ifndef __ASM_MACH_GENERIC_CPU_FEATURE_OVERRIDES_H
#define __ASM_MACH_GENERIC_CPU_FEATURE_OVERRIDES_H
-/* Intensionally empty file ... */
+/* Intentionally empty file ... */
#endif /* __ASM_MACH_GENERIC_CPU_FEATURE_OVERRIDES_H */
diff --git a/include/asm-mips/mach-generic/ide.h b/include/asm-mips/mach-generic/ide.h
index cb2edd018ad6..961006948c7c 100644
--- a/include/asm-mips/mach-generic/ide.h
+++ b/include/asm-mips/mach-generic/ide.h
@@ -18,6 +18,7 @@
#include <linux/config.h>
#include <linux/pci.h>
#include <linux/stddef.h>
+#include <asm/processor.h>
#ifndef MAX_HWIFS
# ifdef CONFIG_BLK_DEV_IDEPCI
@@ -104,15 +105,71 @@ static __inline__ unsigned long ide_default_io_base(int index)
/* MIPS port and memory-mapped I/O string operations. */
-#define __ide_insw insw
-#define __ide_insl insl
-#define __ide_outsw outsw
-#define __ide_outsl outsl
+static inline void __ide_flush_dcache_range(unsigned long addr, unsigned long size)
+{
+ if (cpu_has_dc_aliases) {
+ unsigned long end = addr + size;
+ for (; addr < end; addr += PAGE_SIZE)
+ flush_dcache_page(virt_to_page(addr));
+ }
+}
+
+static inline void __ide_insw(unsigned long port, void *addr,
+ unsigned int count)
+{
+ insw(port, addr, count);
+ __ide_flush_dcache_range((unsigned long)addr, count * 2);
+}
+
+static inline void __ide_insl(unsigned long port, void *addr, unsigned int count)
+{
+ insl(port, addr, count);
+ __ide_flush_dcache_range((unsigned long)addr, count * 4);
+}
+
+static inline void __ide_outsw(unsigned long port, const void *addr,
+ unsigned long count)
+{
+ outsw(port, addr, count);
+ __ide_flush_dcache_range((unsigned long)addr, count * 2);
+}
+
+static inline void __ide_outsl(unsigned long port, const void *addr,
+ unsigned long count)
+{
+ outsl(port, addr, count);
+ __ide_flush_dcache_range((unsigned long)addr, count * 4);
+}
+
+static inline void __ide_mm_insw(void __iomem *port, void *addr, u32 count)
+{
+ readsw(port, addr, count);
+ __ide_flush_dcache_range((unsigned long)addr, count * 2);
+}
+
+static inline void __ide_mm_insl(void __iomem *port, void *addr, u32 count)
+{
+ readsl(port, addr, count);
+ __ide_flush_dcache_range((unsigned long)addr, count * 4);
+}
+
+static inline void __ide_mm_outsw(void __iomem *port, void *addr, u32 count)
+{
+ writesw(port, addr, count);
+ __ide_flush_dcache_range((unsigned long)addr, count * 2);
+}
+
+static inline void __ide_mm_outsl(void __iomem * port, void *addr, u32 count)
+{
+ writesl(port, addr, count);
+ __ide_flush_dcache_range((unsigned long)addr, count * 4);
+}
-#define __ide_mm_insw readsw
-#define __ide_mm_insl readsl
-#define __ide_mm_outsw writesw
-#define __ide_mm_outsl writesl
+/* ide_insw calls insw, not __ide_insw. Why? */
+#undef insw
+#undef insl
+#define insw(port, addr, count) __ide_insw(port, addr, count)
+#define insl(port, addr, count) __ide_insl(port, addr, count)
#endif /* __KERNEL__ */
diff --git a/include/asm-mips/mach-generic/ioremap.h b/include/asm-mips/mach-generic/ioremap.h
new file mode 100644
index 000000000000..9b64ff6e485d
--- /dev/null
+++ b/include/asm-mips/mach-generic/ioremap.h
@@ -0,0 +1,23 @@
+/*
+ * include/asm-mips/mach-generic/ioremap.h
+ *
+ * This program is free software; you can redistribute 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_GENERIC_IOREMAP_H
+#define __ASM_MACH_GENERIC_IOREMAP_H
+
+#include <linux/types.h>
+
+/*
+ * Allow physical addresses to be fixed up to help peripherals located
+ * outside the low 32-bit range -- generic pass-through version.
+ */
+static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+{
+ return phys_addr;
+}
+
+#endif /* __ASM_MACH_GENERIC_IOREMAP_H */
diff --git a/include/asm-mips/mach-generic/kernel-entry-init.h b/include/asm-mips/mach-generic/kernel-entry-init.h
new file mode 100644
index 000000000000..7e66505fa574
--- /dev/null
+++ b/include/asm-mips/mach-generic/kernel-entry-init.h
@@ -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) 2005 Embedded Alley Solutions, Inc
+ * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
+ */
+#ifndef __ASM_MACH_GENERIC_KERNEL_ENTRY_H
+#define __ASM_MACH_GENERIC_KERNEL_ENTRY_H
+
+/* Intentionally empty macro, used in head.S. Override in
+ * arch/mips/mach-xxx/kernel-entry-init.h when necessary.
+ */
+.macro kernel_entry_setup
+.endm
+
+/*
+ * Do SMP slave processor setup necessary before we can savely execute C code.
+ */
+ .macro smp_slave_setup
+ .endm
+
+
+#endif /* __ASM_MACH_GENERIC_KERNEL_ENTRY_H */
diff --git a/include/asm-mips/mach-generic/kmalloc.h b/include/asm-mips/mach-generic/kmalloc.h
new file mode 100644
index 000000000000..373d66dee9d7
--- /dev/null
+++ b/include/asm-mips/mach-generic/kmalloc.h
@@ -0,0 +1,13 @@
+#ifndef __ASM_MACH_GENERIC_KMALLOC_H
+#define __ASM_MACH_GENERIC_KMALLOC_H
+
+#include <linux/config.h>
+
+#ifndef CONFIG_DMA_COHERENT
+/*
+ * Total overkill for most systems but need as a safe default.
+ */
+#define ARCH_KMALLOC_MINALIGN 128
+#endif
+
+#endif /* __ASM_MACH_GENERIC_KMALLOC_H */
diff --git a/include/asm-mips/mach-generic/spaces.h b/include/asm-mips/mach-generic/spaces.h
index 5a2c1efb4eb7..b849d8dd7e78 100644
--- a/include/asm-mips/mach-generic/spaces.h
+++ b/include/asm-mips/mach-generic/spaces.h
@@ -55,13 +55,13 @@
#endif
#ifdef CONFIG_DMA_NONCOHERENT
-#define CAC_BASE 0x9800000000000000
+#define CAC_BASE 0x9800000000000000UL
#else
-#define CAC_BASE 0xa800000000000000
+#define CAC_BASE 0xa800000000000000UL
#endif
-#define IO_BASE 0x9000000000000000
-#define UNCAC_BASE 0x9000000000000000
-#define MAP_BASE 0xc000000000000000
+#define IO_BASE 0x9000000000000000UL
+#define UNCAC_BASE 0x9000000000000000UL
+#define MAP_BASE 0xc000000000000000UL
#define TO_PHYS(x) ( ((x) & TO_PHYS_MASK))
#define TO_CAC(x) (CAC_BASE | ((x) & TO_PHYS_MASK))
diff --git a/include/asm-mips/mach-ip22/cpu-feature-overrides.h b/include/asm-mips/mach-ip22/cpu-feature-overrides.h
index 3c8896d9b133..ab9714668177 100644
--- a/include/asm-mips/mach-ip22/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-ip22/cpu-feature-overrides.h
@@ -11,6 +11,12 @@
/*
* IP22 with a variety of processors so we can't use defaults for everything.
*/
+#define cpu_has_tlb 1
+#define cpu_has_4kex 1
+#define cpu_has_4kcache 1
+#define cpu_has_fpu 1
+#define cpu_has_32fpr 1
+#define cpu_has_counter 1
#define cpu_has_mips16 0
#define cpu_has_divec 0
#define cpu_has_cache_cdex_p 1
@@ -23,6 +29,8 @@
#define cpu_has_dc_aliases (PAGE_SIZE < 0x4000)
#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_dsp 0
+
#define cpu_has_nofpuex 0
#define cpu_has_64bits 1
diff --git a/include/asm-mips/mach-ip22/spaces.h b/include/asm-mips/mach-ip22/spaces.h
index e96166f27c49..8385f716798d 100644
--- a/include/asm-mips/mach-ip22/spaces.h
+++ b/include/asm-mips/mach-ip22/spaces.h
@@ -44,7 +44,7 @@
#define CAC_BASE 0xffffffff80000000
#define IO_BASE 0xffffffffa0000000
#define UNCAC_BASE 0xffffffffa0000000
-#define MAP_BASE 0xffffffffc0000000
+#define MAP_BASE 0xc000000000000000
#define TO_PHYS(x) ( ((x) & TO_PHYS_MASK))
#define TO_CAC(x) (CAC_BASE | ((x) & TO_PHYS_MASK))
diff --git a/include/asm-mips/mach-ip27/cpu-feature-overrides.h b/include/asm-mips/mach-ip27/cpu-feature-overrides.h
index fe96d7358517..4c8a90051fd0 100644
--- a/include/asm-mips/mach-ip27/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-ip27/cpu-feature-overrides.h
@@ -25,6 +25,7 @@
#define cpu_has_vtag_icache 0
#define cpu_has_dc_aliases 0
#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_dsp 0
#define cpu_icache_snoops_remote_store 1
#define cpu_has_nofpuex 0
diff --git a/include/asm-mips/mach-ip27/kernel-entry-init.h b/include/asm-mips/mach-ip27/kernel-entry-init.h
new file mode 100644
index 000000000000..c1a10314b317
--- /dev/null
+++ b/include/asm-mips/mach-ip27/kernel-entry-init.h
@@ -0,0 +1,52 @@
+/*
+ * 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) 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2005 Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MACH_IP27_KERNEL_ENTRY_H
+#define __ASM_MACH_IP27_KERNEL_ENTRY_H
+
+#include <asm/sn/addrs.h>
+#include <asm/sn/sn0/hubni.h>
+#include <asm/sn/klkernvars.h>
+
+/*
+ * Returns the local nasid into res.
+ */
+ .macro GET_NASID_ASM res
+ dli \res, LOCAL_HUB_ADDR(NI_STATUS_REV_ID)
+ ld \res, (\res)
+ and \res, NSRI_NODEID_MASK
+ dsrl \res, NSRI_NODEID_SHFT
+ .endm
+
+/*
+ * Intentionally empty macro, used in head.S. Override in
+ * arch/mips/mach-xxx/kernel-entry-init.h when necessary.
+ */
+ .macro kernel_entry_setup
+ GET_NASID_ASM t1
+ move t2, t1 # text and data are here
+ MAPPED_KERNEL_SETUP_TLB
+ .endm
+
+/*
+ * Do SMP slave processor setup necessary before we can savely execute C code.
+ */
+ .macro smp_slave_setup
+ GET_NASID_ASM t1
+ dli t0, KLDIR_OFFSET + (KLI_KERN_VARS * KLDIR_ENT_SIZE) + \
+ KLDIR_OFF_POINTER + CAC_BASE
+ dsll t1, NASID_SHFT
+ or t0, t0, t1
+ ld t0, 0(t0) # t0 points to kern_vars struct
+ lh t1, KV_RO_NASID_OFFSET(t0)
+ lh t2, KV_RW_NASID_OFFSET(t0)
+ MAPPED_KERNEL_SETUP_TLB
+ ARC64_TWIDDLE_PC
+ .endm
+
+#endif /* __ASM_MACH_IP27_KERNEL_ENTRY_H */
diff --git a/include/asm-mips/mach-ip27/kmalloc.h b/include/asm-mips/mach-ip27/kmalloc.h
new file mode 100644
index 000000000000..426bd049b2d7
--- /dev/null
+++ b/include/asm-mips/mach-ip27/kmalloc.h
@@ -0,0 +1,8 @@
+#ifndef __ASM_MACH_IP27_KMALLOC_H
+#define __ASM_MACH_IP27_KMALLOC_H
+
+/*
+ * All happy, no need to define ARCH_KMALLOC_MINALIGN
+ */
+
+#endif /* __ASM_MACH_IP27_KMALLOC_H */
diff --git a/include/asm-mips/mach-ip27/mmzone.h b/include/asm-mips/mach-ip27/mmzone.h
index d3f566362e9d..986a3b9b59a7 100644
--- a/include/asm-mips/mach-ip27/mmzone.h
+++ b/include/asm-mips/mach-ip27/mmzone.h
@@ -10,7 +10,6 @@
#define LEVELS_PER_SLICE 128
struct slice_data {
- unsigned long irq_alloc_mask[2];
unsigned long irq_enable_mask[2];
int level_to_irq[LEVELS_PER_SLICE];
};
@@ -20,6 +19,7 @@ struct hub_data {
DECLARE_BITMAP(h_bigwin_used, HUB_NUM_BIG_WINDOW);
cpumask_t h_cpus;
unsigned long slice_map;
+ unsigned long irq_alloc_mask[2];
struct slice_data slice[2];
};
diff --git a/include/asm-mips/mach-ip27/spaces.h b/include/asm-mips/mach-ip27/spaces.h
index e3b3fe32eeb1..45e61785ef42 100644
--- a/include/asm-mips/mach-ip27/spaces.h
+++ b/include/asm-mips/mach-ip27/spaces.h
@@ -20,6 +20,7 @@
#define IO_BASE 0x9200000000000000
#define MSPEC_BASE 0x9400000000000000
#define UNCAC_BASE 0x9600000000000000
+#define MAP_BASE 0xc000000000000000
#define TO_PHYS(x) ( ((x) & TO_PHYS_MASK))
#define TO_CAC(x) (CAC_BASE | ((x) & TO_PHYS_MASK))
diff --git a/include/asm-mips/mach-ip27/topology.h b/include/asm-mips/mach-ip27/topology.h
index a70a81257c3d..82141c711c33 100644
--- a/include/asm-mips/mach-ip27/topology.h
+++ b/include/asm-mips/mach-ip27/topology.h
@@ -9,6 +9,9 @@
#define parent_node(node) (node)
#define node_to_cpumask(node) (hub_data(node)->h_cpus)
#define node_to_first_cpu(node) (first_cpu(node_to_cpumask(node)))
+struct pci_bus;
+extern int pcibus_to_node(struct pci_bus *);
+
#define pcibus_to_cpumask(bus) (cpu_online_map)
extern unsigned char __node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES];
diff --git a/include/asm-mips/mach-ip32/cpu-feature-overrides.h b/include/asm-mips/mach-ip32/cpu-feature-overrides.h
index 04713973c6c3..ab37fc1842ba 100644
--- a/include/asm-mips/mach-ip32/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-ip32/cpu-feature-overrides.h
@@ -37,5 +37,6 @@
#define cpu_has_ejtag 0
#define cpu_has_vtag_icache 0
#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_dsp 0
#endif /* __ASM_MACH_IP32_CPU_FEATURE_OVERRIDES_H */
diff --git a/include/asm-mips/mach-ip32/kmalloc.h b/include/asm-mips/mach-ip32/kmalloc.h
new file mode 100644
index 000000000000..9d2d4d9ac036
--- /dev/null
+++ b/include/asm-mips/mach-ip32/kmalloc.h
@@ -0,0 +1,12 @@
+#ifndef __ASM_MACH_IP32_KMALLOC_H
+#define __ASM_MACH_IP32_KMALLOC_H
+
+#include <linux/config.h>
+
+#if defined(CONFIG_CPU_R5000) || defined (CONFIG_CPU_RM7000)
+#define ARCH_KMALLOC_MINALIGN 32
+#else
+#define ARCH_KMALLOC_MINALIGN 128
+#endif
+
+#endif /* __ASM_MACH_IP32_KMALLOC_H */
diff --git a/include/asm-mips/mach-ip32/spaces.h b/include/asm-mips/mach-ip32/spaces.h
index c7839f85c68d..44abe5c02389 100644
--- a/include/asm-mips/mach-ip32/spaces.h
+++ b/include/asm-mips/mach-ip32/spaces.h
@@ -19,10 +19,10 @@
#define HIGHMEM_START (1UL << 59UL)
#endif
-#define CAC_BASE 0x9800000000000000
-#define IO_BASE 0x9000000000000000
-#define UNCAC_BASE 0x9000000000000000
-#define MAP_BASE 0xc000000000000000
+#define CAC_BASE 0x9800000000000000UL
+#define IO_BASE 0x9000000000000000UL
+#define UNCAC_BASE 0x9000000000000000UL
+#define MAP_BASE 0xc000000000000000UL
#define TO_PHYS(x) ( ((x) & TO_PHYS_MASK))
#define TO_CAC(x) (CAC_BASE | ((x) & TO_PHYS_MASK))
diff --git a/include/asm-mips/mach-ja/cpu-feature-overrides.h b/include/asm-mips/mach-ja/cpu-feature-overrides.h
index ca57e7db98bb..a0fde405d4c4 100644
--- a/include/asm-mips/mach-ja/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-ja/cpu-feature-overrides.h
@@ -25,6 +25,7 @@
#define cpu_has_vtag_icache 0
#define cpu_has_dc_aliases 0
#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_dsp 0
#define cpu_icache_snoops_remote_store 0
#define cpu_has_nofpuex 0
@@ -36,10 +37,4 @@
#define cpu_icache_line_size() 32
#define cpu_scache_line_size() 32
-/*
- * On the RM9000 we need to ensure that I-cache lines being fetches only
- * contain valid instructions are funny things will happen.
- */
-#define PLAT_TRAMPOLINE_STUFF_LINE 32UL
-
#endif /* __ASM_MACH_JA_CPU_FEATURE_OVERRIDES_H */
diff --git a/include/asm-mips/mach-mips/cpu-feature-overrides.h b/include/asm-mips/mach-mips/cpu-feature-overrides.h
index 6f51be571bf0..9f92aed17754 100644
--- a/include/asm-mips/mach-mips/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-mips/cpu-feature-overrides.h
@@ -17,7 +17,7 @@
#ifdef CONFIG_CPU_MIPS32
#define cpu_has_tlb 1
#define cpu_has_4kex 1
-#define cpu_has_4ktlb 1
+#define cpu_has_4kcache 1
/* #define cpu_has_fpu ? */
/* #define cpu_has_32fpr ? */
#define cpu_has_counter 1
@@ -37,12 +37,13 @@
/* #define cpu_has_64bits ? */
/* #define cpu_has_64bit_zero_reg ? */
/* #define cpu_has_subset_pcaches ? */
+#define cpu_icache_snoops_remote_store 1
#endif
#ifdef CONFIG_CPU_MIPS64
#define cpu_has_tlb 1
#define cpu_has_4kex 1
-#define cpu_has_4ktlb 1
+#define cpu_has_4kcache 1
/* #define cpu_has_fpu ? */
/* #define cpu_has_32fpr ? */
#define cpu_has_counter 1
@@ -62,6 +63,7 @@
/* #define cpu_has_64bits ? */
/* #define cpu_has_64bit_zero_reg ? */
/* #define cpu_has_subset_pcaches ? */
+#define cpu_icache_snoops_remote_store 1
#endif
#endif /* __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H */
diff --git a/include/asm-mips/mach-mips/irq.h b/include/asm-mips/mach-mips/irq.h
new file mode 100644
index 000000000000..f8579696ca54
--- /dev/null
+++ b/include/asm-mips/mach-mips/irq.h
@@ -0,0 +1,14 @@
+#ifndef __ASM_MACH_MIPS_IRQ_H
+#define __ASM_MACH_MIPS_IRQ_H
+
+#include <linux/config.h>
+
+#define NR_IRQS 256
+
+#ifdef CONFIG_SMP
+
+#define ARCH_HAS_IRQ_PER_CPU
+
+#endif
+
+#endif /* __ASM_MACH_MIPS_IRQ_H */
diff --git a/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h b/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h
index 7473512384bc..825c5f674dfc 100644
--- a/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h
@@ -28,6 +28,7 @@
#define cpu_has_vtag_icache 0
#define cpu_has_dc_aliases 0
#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_dsp 0
#define cpu_icache_snoops_remote_store 0
#define cpu_has_nofpuex 0
@@ -39,10 +40,4 @@
#define cpu_icache_line_size() 32
#define cpu_scache_line_size() 32
-/*
- * On the RM9000 we need to ensure that I-cache lines being fetches only
- * contain valid instructions are funny things will happen.
- */
-#define PLAT_TRAMPOLINE_STUFF_LINE 32UL
-
#endif /* __ASM_MACH_JA_CPU_FEATURE_OVERRIDES_H */
diff --git a/include/asm-mips/mach-pb1x00/pb1200.h b/include/asm-mips/mach-pb1x00/pb1200.h
new file mode 100644
index 000000000000..9a3088b19bf3
--- /dev/null
+++ b/include/asm-mips/mach-pb1x00/pb1200.h
@@ -0,0 +1,252 @@
+/*
+ * AMD Alchemy PB1200 Referrence Board
+ * Board Registers defines.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ *
+ */
+#ifndef __ASM_PB1200_H
+#define __ASM_PB1200_H
+
+#include <linux/types.h>
+
+// This is defined in au1000.h with bogus value
+#undef AU1X00_EXTERNAL_INT
+
+#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
+#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
+#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC1_TX
+#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC1_RX
+
+/* SPI and SMB are muxed on the Pb1200 board.
+ Refer to board documentation.
+ */
+#define SPI_PSC_BASE PSC0_BASE_ADDR
+#define SMBUS_PSC_BASE PSC0_BASE_ADDR
+/* AC97 and I2S are muxed on the Pb1200 board.
+ Refer to board documentation.
+ */
+#define AC97_PSC_BASE PSC1_BASE_ADDR
+#define I2S_PSC_BASE PSC1_BASE_ADDR
+
+#define BCSR_KSEG1_ADDR 0xAD800000
+
+typedef volatile struct
+{
+ /*00*/ u16 whoami;
+ u16 reserved0;
+ /*04*/ u16 status;
+ u16 reserved1;
+ /*08*/ u16 switches;
+ u16 reserved2;
+ /*0C*/ u16 resets;
+ u16 reserved3;
+
+ /*10*/ u16 pcmcia;
+ u16 reserved4;
+ /*14*/ u16 board;
+ u16 reserved5;
+ /*18*/ u16 disk_leds;
+ u16 reserved6;
+ /*1C*/ u16 system;
+ u16 reserved7;
+
+ /*20*/ u16 intclr;
+ u16 reserved8;
+ /*24*/ u16 intset;
+ u16 reserved9;
+ /*28*/ u16 intclr_mask;
+ u16 reserved10;
+ /*2C*/ u16 intset_mask;
+ u16 reserved11;
+
+ /*30*/ u16 sig_status;
+ u16 reserved12;
+ /*34*/ u16 int_status;
+ u16 reserved13;
+ /*38*/ u16 reserved14;
+ u16 reserved15;
+ /*3C*/ u16 reserved16;
+ u16 reserved17;
+
+} BCSR;
+
+static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+
+/*
+ * Register bit definitions for the BCSRs
+ */
+#define BCSR_WHOAMI_DCID 0x000F
+#define BCSR_WHOAMI_CPLD 0x00F0
+#define BCSR_WHOAMI_BOARD 0x0F00
+
+#define BCSR_STATUS_PCMCIA0VS 0x0003
+#define BCSR_STATUS_PCMCIA1VS 0x000C
+#define BCSR_STATUS_SWAPBOOT 0x0040
+#define BCSR_STATUS_FLASHBUSY 0x0100
+#define BCSR_STATUS_IDECBLID 0x0200
+#define BCSR_STATUS_SD0WP 0x0400
+#define BCSR_STATUS_SD1WP 0x0800
+#define BCSR_STATUS_U0RXD 0x1000
+#define BCSR_STATUS_U1RXD 0x2000
+
+#define BCSR_SWITCHES_OCTAL 0x00FF
+#define BCSR_SWITCHES_DIP_1 0x0080
+#define BCSR_SWITCHES_DIP_2 0x0040
+#define BCSR_SWITCHES_DIP_3 0x0020
+#define BCSR_SWITCHES_DIP_4 0x0010
+#define BCSR_SWITCHES_DIP_5 0x0008
+#define BCSR_SWITCHES_DIP_6 0x0004
+#define BCSR_SWITCHES_DIP_7 0x0002
+#define BCSR_SWITCHES_DIP_8 0x0001
+#define BCSR_SWITCHES_ROTARY 0x0F00
+
+#define BCSR_RESETS_ETH 0x0001
+#define BCSR_RESETS_CAMERA 0x0002
+#define BCSR_RESETS_DC 0x0004
+#define BCSR_RESETS_IDE 0x0008
+/* not resets but in the same register */
+#define BCSR_RESETS_WSCFSM 0x0800
+#define BCSR_RESETS_PCS0MUX 0x1000
+#define BCSR_RESETS_PCS1MUX 0x2000
+#define BCSR_RESETS_SPISEL 0x4000
+#define BCSR_RESETS_SD1MUX 0x8000
+
+#define BCSR_PCMCIA_PC0VPP 0x0003
+#define BCSR_PCMCIA_PC0VCC 0x000C
+#define BCSR_PCMCIA_PC0DRVEN 0x0010
+#define BCSR_PCMCIA_PC0RST 0x0080
+#define BCSR_PCMCIA_PC1VPP 0x0300
+#define BCSR_PCMCIA_PC1VCC 0x0C00
+#define BCSR_PCMCIA_PC1DRVEN 0x1000
+#define BCSR_PCMCIA_PC1RST 0x8000
+
+#define BCSR_BOARD_LCDVEE 0x0001
+#define BCSR_BOARD_LCDVDD 0x0002
+#define BCSR_BOARD_LCDBL 0x0004
+#define BCSR_BOARD_CAMSNAP 0x0010
+#define BCSR_BOARD_CAMPWR 0x0020
+#define BCSR_BOARD_SD0PWR 0x0040
+#define BCSR_BOARD_SD1PWR 0x0080
+
+#define BCSR_LEDS_DECIMALS 0x00FF
+#define BCSR_LEDS_LED0 0x0100
+#define BCSR_LEDS_LED1 0x0200
+#define BCSR_LEDS_LED2 0x0400
+#define BCSR_LEDS_LED3 0x0800
+
+#define BCSR_SYSTEM_VDDI 0x001F
+#define BCSR_SYSTEM_POWEROFF 0x4000
+#define BCSR_SYSTEM_RESET 0x8000
+
+/* Bit positions for the different interrupt sources */
+#define BCSR_INT_IDE 0x0001
+#define BCSR_INT_ETH 0x0002
+#define BCSR_INT_PC0 0x0004
+#define BCSR_INT_PC0STSCHG 0x0008
+#define BCSR_INT_PC1 0x0010
+#define BCSR_INT_PC1STSCHG 0x0020
+#define BCSR_INT_DC 0x0040
+#define BCSR_INT_FLASHBUSY 0x0080
+#define BCSR_INT_PC0INSERT 0x0100
+#define BCSR_INT_PC0EJECT 0x0200
+#define BCSR_INT_PC1INSERT 0x0400
+#define BCSR_INT_PC1EJECT 0x0800
+#define BCSR_INT_SD0INSERT 0x1000
+#define BCSR_INT_SD0EJECT 0x2000
+#define BCSR_INT_SD1INSERT 0x4000
+#define BCSR_INT_SD1EJECT 0x8000
+
+/* PCMCIA Db1x00 specific defines */
+#define PCMCIA_MAX_SOCK 1
+#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
+
+/* VPP/VCC */
+#define SET_VCC_VPP(VCC, VPP, SLOT)\
+ ((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8))
+
+#define AU1XXX_SMC91111_PHYS_ADDR (0x0D000300)
+#define AU1XXX_SMC91111_IRQ PB1200_ETH_INT
+
+#define AU1XXX_ATA_PHYS_ADDR (0x0C800000)
+#define AU1XXX_ATA_PHYS_LEN (0x100)
+#define AU1XXX_ATA_REG_OFFSET (5)
+#define AU1XXX_ATA_INT PB1200_IDE_INT
+#define AU1XXX_ATA_DDMA_REQ DSCR_CMD0_DMA_REQ1;
+#define AU1XXX_ATA_RQSIZE 128
+
+#define NAND_PHYS_ADDR 0x1C000000
+
+/* Timing values as described in databook, * ns value stripped of
+ * lower 2 bits.
+ * These defines are here rather than an SOC1200 generic file because
+ * the parts chosen on another board may be different and may require
+ * different timings.
+ */
+#define NAND_T_H (18 >> 2)
+#define NAND_T_PUL (30 >> 2)
+#define NAND_T_SU (30 >> 2)
+#define NAND_T_WH (30 >> 2)
+
+/* Bitfield shift amounts */
+#define NAND_T_H_SHIFT 0
+#define NAND_T_PUL_SHIFT 4
+#define NAND_T_SU_SHIFT 8
+#define NAND_T_WH_SHIFT 12
+
+#define NAND_TIMING ((NAND_T_H & 0xF) << NAND_T_H_SHIFT) | \
+ ((NAND_T_PUL & 0xF) << NAND_T_PUL_SHIFT) | \
+ ((NAND_T_SU & 0xF) << NAND_T_SU_SHIFT) | \
+ ((NAND_T_WH & 0xF) << NAND_T_WH_SHIFT)
+
+
+/*
+ * External Interrupts for Pb1200 as of 8/6/2004.
+ * Bit positions in the CPLD registers can be calculated by taking
+ * the interrupt define and subtracting the PB1200_INT_BEGIN value.
+ * *example: IDE bis pos is = 64 - 64
+ ETH bit pos is = 65 - 64
+ */
+#define PB1200_INT_BEGIN (AU1000_LAST_INTC1_INT + 1)
+#define PB1200_IDE_INT (PB1200_INT_BEGIN + 0)
+#define PB1200_ETH_INT (PB1200_INT_BEGIN + 1)
+#define PB1200_PC0_INT (PB1200_INT_BEGIN + 2)
+#define PB1200_PC0_STSCHG_INT (PB1200_INT_BEGIN + 3)
+#define PB1200_PC1_INT (PB1200_INT_BEGIN + 4)
+#define PB1200_PC1_STSCHG_INT (PB1200_INT_BEGIN + 5)
+#define PB1200_DC_INT (PB1200_INT_BEGIN + 6)
+#define PB1200_FLASHBUSY_INT (PB1200_INT_BEGIN + 7)
+#define PB1200_PC0_INSERT_INT (PB1200_INT_BEGIN + 8)
+#define PB1200_PC0_EJECT_INT (PB1200_INT_BEGIN + 9)
+#define PB1200_PC1_INSERT_INT (PB1200_INT_BEGIN + 10)
+#define PB1200_PC1_EJECT_INT (PB1200_INT_BEGIN + 11)
+#define PB1200_SD0_INSERT_INT (PB1200_INT_BEGIN + 12)
+#define PB1200_SD0_EJECT_INT (PB1200_INT_BEGIN + 13)
+#define PB1200_SD1_INSERT_INT (PB1200_INT_BEGIN + 14)
+#define PB1200_SD1_EJECT_INT (PB1200_INT_BEGIN + 15)
+
+#define PB1200_INT_END (PB1200_INT_BEGIN + 15)
+
+/* For drivers/pcmcia/au1000_db1x00.c */
+#define BOARD_PC0_INT PB1200_PC0_INT
+#define BOARD_PC1_INT PB1200_PC1_INT
+#define BOARD_CARD_INSERTED(SOCKET) bcsr->sig_status & (1<<(8+(2*SOCKET)))
+
+#endif /* __ASM_PB1200_H */
+
diff --git a/include/asm-mips/mach-pnx8550/cm.h b/include/asm-mips/mach-pnx8550/cm.h
new file mode 100644
index 000000000000..bb0a56c7d011
--- /dev/null
+++ b/include/asm-mips/mach-pnx8550/cm.h
@@ -0,0 +1,43 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * Clock module specific definitions
+ *
+ * Author: source@mvista.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#ifndef __PNX8550_CM_H
+#define __PNX8550_CM_H
+
+#define PNX8550_CM_BASE 0xBBE47000
+
+#define PNX8550_CM_PLL0_CTL *(volatile unsigned long *)(PNX8550_CM_BASE + 0x000)
+#define PNX8550_CM_PLL1_CTL *(volatile unsigned long *)(PNX8550_CM_BASE + 0x004)
+#define PNX8550_CM_PLL2_CTL *(volatile unsigned long *)(PNX8550_CM_BASE + 0x008)
+#define PNX8550_CM_PLL3_CTL *(volatile unsigned long *)(PNX8550_CM_BASE + 0x00C)
+
+// Table not complete.....
+
+#define PNX8550_CM_PLL_BLOCKED_MASK 0x80000000
+#define PNX8550_CM_PLL_LOCK_MASK 0x40000000
+#define PNX8550_CM_PLL_CURRENT_ADJ_MASK 0x3c000000
+#define PNX8550_CM_PLL_N_MASK 0x01ff0000
+#define PNX8550_CM_PLL_M_MASK 0x00003f00
+#define PNX8550_CM_PLL_P_MASK 0x0000000c
+#define PNX8550_CM_PLL_PD_MASK 0x00000002
+
+
+#endif
diff --git a/include/asm-mips/mach-pnx8550/glb.h b/include/asm-mips/mach-pnx8550/glb.h
new file mode 100644
index 000000000000..07aa85e609bc
--- /dev/null
+++ b/include/asm-mips/mach-pnx8550/glb.h
@@ -0,0 +1,86 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * PNX8550 global definitions
+ *
+ * Author: source@mvista.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#ifndef __PNX8550_GLB_H
+#define __PNX8550_GLB_H
+
+#define PNX8550_GLB1_BASE 0xBBE63000
+#define PNX8550_GLB2_BASE 0xBBE4d000
+#define PNX8550_RESET_BASE 0xBBE60000
+
+/* PCI Inta Output Enable Registers */
+#define PNX8550_GLB2_ENAB_INTA_O *(volatile unsigned long *)(PNX8550_GLB2_BASE + 0x050)
+
+/* Bit 1:Enable DAC Powerdown
+ 0:DACs are enabled and are working normally
+ 1:DACs are powerdown
+*/
+#define PNX8550_GLB_DAC_PD 0x2
+/* Bit 0:Enable of PCI inta output
+ 0 = Disable PCI inta output
+ 1 = Enable PCI inta output
+*/
+#define PNX8550_GLB_ENABLE_INTA_O 0x1
+
+/* PCI Direct Mappings */
+#define PNX8550_PCIMEM 0x12000000
+#define PNX8550_PCIMEM_SIZE 0x08000000
+#define PNX8550_PCIIO 0x1c000000
+#define PNX8550_PCIIO_SIZE 0x02000000 /* 32M */
+
+#define PNX8550_PORT_BASE KSEG1
+
+// GPIO def
+#define PNX8550_GPIO_BASE 0x1Be00000
+
+#define PNX8550_GPIO_DIRQ0 (PNX8550_GPIO_BASE + 0x104500)
+#define PNX8550_GPIO_MC1 (PNX8550_GPIO_BASE + 0x104004)
+#define PNX8550_GPIO_MC_31_BIT 30
+#define PNX8550_GPIO_MC_30_BIT 28
+#define PNX8550_GPIO_MC_29_BIT 26
+#define PNX8550_GPIO_MC_28_BIT 24
+#define PNX8550_GPIO_MC_27_BIT 22
+#define PNX8550_GPIO_MC_26_BIT 20
+#define PNX8550_GPIO_MC_25_BIT 18
+#define PNX8550_GPIO_MC_24_BIT 16
+#define PNX8550_GPIO_MC_23_BIT 14
+#define PNX8550_GPIO_MC_22_BIT 12
+#define PNX8550_GPIO_MC_21_BIT 10
+#define PNX8550_GPIO_MC_20_BIT 8
+#define PNX8550_GPIO_MC_19_BIT 6
+#define PNX8550_GPIO_MC_18_BIT 4
+#define PNX8550_GPIO_MC_17_BIT 2
+#define PNX8550_GPIO_MC_16_BIT 0
+
+#define PNX8550_GPIO_MODE_PRIMOP 0x1
+#define PNX8550_GPIO_MODE_NO_OPENDR 0x2
+#define PNX8550_GPIO_MODE_OPENDR 0x3
+
+// RESET module
+#define PNX8550_RST_CTL *(volatile unsigned long *)(PNX8550_RESET_BASE + 0x0)
+#define PNX8550_RST_CAUSE *(volatile unsigned long *)(PNX8550_RESET_BASE + 0x4)
+#define PNX8550_RST_EN_WATCHDOG *(volatile unsigned long *)(PNX8550_RESET_BASE + 0x8)
+
+#define PNX8550_RST_REL_MIPS_RST_N 0x8
+#define PNX8550_RST_DO_SW_RST 0x4
+#define PNX8550_RST_REL_SYS_RST_OUT 0x2
+#define PNX8550_RST_ASSERT_SYS_RST_OUT 0x1
+#endif
diff --git a/include/asm-mips/mach-pnx8550/int.h b/include/asm-mips/mach-pnx8550/int.h
new file mode 100644
index 000000000000..0e0668b524f4
--- /dev/null
+++ b/include/asm-mips/mach-pnx8550/int.h
@@ -0,0 +1,140 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * Interrupt specific definitions
+ *
+ * Author: source@mvista.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#ifndef __PNX8550_INT_H
+#define __PNX8550_INT_H
+
+#define PNX8550_GIC_BASE 0xBBE3E000
+
+#define PNX8550_GIC_PRIMASK_0 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x000)
+#define PNX8550_GIC_PRIMASK_1 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x004)
+#define PNX8550_GIC_VECTOR_0 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x100)
+#define PNX8550_GIC_VECTOR_1 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x104)
+#define PNX8550_GIC_PEND_1_31 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x200)
+#define PNX8550_GIC_PEND_32_63 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x204)
+#define PNX8550_GIC_PEND_64_70 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x208)
+#define PNX8550_GIC_FEATURES *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x300)
+#define PNX8550_GIC_REQ(x) *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x400 + (x)*4)
+#define PNX8550_GIC_MOD_ID *(volatile unsigned long *)(PNX8550_GIC_BASE + 0xFFC)
+
+// cp0 is two software + six hw exceptions
+#define PNX8550_INT_CP0_TOTINT 8
+#define PNX8550_INT_CP0_MIN 0
+#define PNX8550_INT_CP0_MAX (PNX8550_INT_CP0_MIN + PNX8550_INT_CP0_TOTINT - 1)
+
+#define MIPS_CPU_GIC_IRQ 2
+#define MIPS_CPU_TIMER_IRQ 7
+
+// GIC are 71 exceptions connected to cp0's first hardware exception
+#define PNX8550_INT_GIC_TOTINT 71
+#define PNX8550_INT_GIC_MIN (PNX8550_INT_CP0_MAX+1)
+#define PNX8550_INT_GIC_MAX (PNX8550_INT_GIC_MIN + PNX8550_INT_GIC_TOTINT - 1)
+
+#define PNX8550_INT_UNDEF (PNX8550_INT_GIC_MIN+0)
+#define PNX8550_INT_IPC_TARGET0_MIPS (PNX8550_INT_GIC_MIN+1)
+#define PNX8550_INT_IPC_TARGET1_TM32_1 (PNX8550_INT_GIC_MIN+2)
+#define PNX8550_INT_IPC_TARGET1_TM32_2 (PNX8550_INT_GIC_MIN+3)
+#define PNX8550_INT_RESERVED_4 (PNX8550_INT_GIC_MIN+4)
+#define PNX8550_INT_USB (PNX8550_INT_GIC_MIN+5)
+#define PNX8550_INT_GPIO_EQ1 (PNX8550_INT_GIC_MIN+6)
+#define PNX8550_INT_GPIO_EQ2 (PNX8550_INT_GIC_MIN+7)
+#define PNX8550_INT_GPIO_EQ3 (PNX8550_INT_GIC_MIN+8)
+#define PNX8550_INT_GPIO_EQ4 (PNX8550_INT_GIC_MIN+9)
+
+#define PNX8550_INT_GPIO_EQ5 (PNX8550_INT_GIC_MIN+10)
+#define PNX8550_INT_GPIO_EQ6 (PNX8550_INT_GIC_MIN+11)
+#define PNX8550_INT_RESERVED_12 (PNX8550_INT_GIC_MIN+12)
+#define PNX8550_INT_QVCP1 (PNX8550_INT_GIC_MIN+13)
+#define PNX8550_INT_QVCP2 (PNX8550_INT_GIC_MIN+14)
+#define PNX8550_INT_I2C1 (PNX8550_INT_GIC_MIN+15)
+#define PNX8550_INT_I2C2 (PNX8550_INT_GIC_MIN+16)
+#define PNX8550_INT_ISO_UART1 (PNX8550_INT_GIC_MIN+17)
+#define PNX8550_INT_ISO_UART2 (PNX8550_INT_GIC_MIN+18)
+#define PNX8550_INT_UART1 (PNX8550_INT_GIC_MIN+19)
+
+#define PNX8550_INT_UART2 (PNX8550_INT_GIC_MIN+20)
+#define PNX8550_INT_QNTR (PNX8550_INT_GIC_MIN+21)
+#define PNX8550_INT_RESERVED22 (PNX8550_INT_GIC_MIN+22)
+#define PNX8550_INT_T_DSC (PNX8550_INT_GIC_MIN+23)
+#define PNX8550_INT_M_DSC (PNX8550_INT_GIC_MIN+24)
+#define PNX8550_INT_RESERVED25 (PNX8550_INT_GIC_MIN+25)
+#define PNX8550_INT_2D_DRAW_ENG (PNX8550_INT_GIC_MIN+26)
+#define PNX8550_INT_MEM_BASED_SCALAR1 (PNX8550_INT_GIC_MIN+27)
+#define PNX8550_INT_VIDEO_MPEG (PNX8550_INT_GIC_MIN+28)
+#define PNX8550_INT_VIDEO_INPUT_P1 (PNX8550_INT_GIC_MIN+29)
+
+#define PNX8550_INT_VIDEO_INPUT_P2 (PNX8550_INT_GIC_MIN+30)
+#define PNX8550_INT_SPDI1 (PNX8550_INT_GIC_MIN+31)
+#define PNX8550_INT_SPDO (PNX8550_INT_GIC_MIN+32)
+#define PNX8550_INT_AUDIO_INPUT1 (PNX8550_INT_GIC_MIN+33)
+#define PNX8550_INT_AUDIO_OUTPUT1 (PNX8550_INT_GIC_MIN+34)
+#define PNX8550_INT_AUDIO_INPUT2 (PNX8550_INT_GIC_MIN+35)
+#define PNX8550_INT_AUDIO_OUTPUT2 (PNX8550_INT_GIC_MIN+36)
+#define PNX8550_INT_MEMBASED_SCALAR2 (PNX8550_INT_GIC_MIN+37)
+#define PNX8550_INT_VPK (PNX8550_INT_GIC_MIN+38)
+#define PNX8550_INT_MPEG1_MIPS (PNX8550_INT_GIC_MIN+39)
+
+#define PNX8550_INT_MPEG1_TM (PNX8550_INT_GIC_MIN+40)
+#define PNX8550_INT_MPEG2_MIPS (PNX8550_INT_GIC_MIN+41)
+#define PNX8550_INT_MPEG2_TM (PNX8550_INT_GIC_MIN+42)
+#define PNX8550_INT_TS_DMA (PNX8550_INT_GIC_MIN+43)
+#define PNX8550_INT_EDMA (PNX8550_INT_GIC_MIN+44)
+#define PNX8550_INT_TM_DEBUG1 (PNX8550_INT_GIC_MIN+45)
+#define PNX8550_INT_TM_DEBUG2 (PNX8550_INT_GIC_MIN+46)
+#define PNX8550_INT_PCI_INTA (PNX8550_INT_GIC_MIN+47)
+#define PNX8550_INT_CLOCK_MODULE (PNX8550_INT_GIC_MIN+48)
+#define PNX8550_INT_PCI_XIO_INTA_PCI (PNX8550_INT_GIC_MIN+49)
+
+#define PNX8550_INT_PCI_XIO_INTB_DMA (PNX8550_INT_GIC_MIN+50)
+#define PNX8550_INT_PCI_XIO_INTC_GPPM (PNX8550_INT_GIC_MIN+51)
+#define PNX8550_INT_PCI_XIO_INTD_GPXIO (PNX8550_INT_GIC_MIN+52)
+#define PNX8550_INT_DVD_CSS (PNX8550_INT_GIC_MIN+53)
+#define PNX8550_INT_VLD (PNX8550_INT_GIC_MIN+54)
+#define PNX8550_INT_GPIO_TSU_7_0 (PNX8550_INT_GIC_MIN+55)
+#define PNX8550_INT_GPIO_TSU_15_8 (PNX8550_INT_GIC_MIN+56)
+#define PNX8550_INT_GPIO_CTU_IR (PNX8550_INT_GIC_MIN+57)
+#define PNX8550_INT_GPIO0 (PNX8550_INT_GIC_MIN+58)
+#define PNX8550_INT_GPIO1 (PNX8550_INT_GIC_MIN+59)
+
+#define PNX8550_INT_GPIO2 (PNX8550_INT_GIC_MIN+60)
+#define PNX8550_INT_GPIO3 (PNX8550_INT_GIC_MIN+61)
+#define PNX8550_INT_GPIO4 (PNX8550_INT_GIC_MIN+62)
+#define PNX8550_INT_GPIO5 (PNX8550_INT_GIC_MIN+63)
+#define PNX8550_INT_GPIO6 (PNX8550_INT_GIC_MIN+64)
+#define PNX8550_INT_GPIO7 (PNX8550_INT_GIC_MIN+65)
+#define PNX8550_INT_PMAN_SECURITY (PNX8550_INT_GIC_MIN+66)
+#define PNX8550_INT_I2C3 (PNX8550_INT_GIC_MIN+67)
+#define PNX8550_INT_RESERVED_68 (PNX8550_INT_GIC_MIN+68)
+#define PNX8550_INT_SPDI2 (PNX8550_INT_GIC_MIN+69)
+
+#define PNX8550_INT_I2C4 (PNX8550_INT_GIC_MIN+70)
+
+// Timer are 3 exceptions connected to cp0's 7th hardware exception
+#define PNX8550_INT_TIMER_TOTINT 3
+#define PNX8550_INT_TIMER_MIN (PNX8550_INT_GIC_MAX+1)
+#define PNX8550_INT_TIMER_MAX (PNX8550_INT_TIMER_MIN + PNX8550_INT_TIMER_TOTINT - 1)
+
+#define PNX8550_INT_TIMER1 (PNX8550_INT_TIMER_MIN+0)
+#define PNX8550_INT_TIMER2 (PNX8550_INT_TIMER_MIN+1)
+#define PNX8550_INT_TIMER3 (PNX8550_INT_TIMER_MIN+2)
+#define PNX8550_INT_WATCHDOG PNX8550_INT_TIMER3
+
+#endif
diff --git a/include/asm-mips/mach-pnx8550/kernel-entry-init.h b/include/asm-mips/mach-pnx8550/kernel-entry-init.h
new file mode 100644
index 000000000000..57102fa9da51
--- /dev/null
+++ b/include/asm-mips/mach-pnx8550/kernel-entry-init.h
@@ -0,0 +1,262 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005 Embedded Alley Solutions, Inc
+ */
+#ifndef __ASM_MACH_KERNEL_ENTRY_INIT_H
+#define __ASM_MACH_KERNEL_ENTRY_INIT_H
+
+#include <asm/cacheops.h>
+#include <asm/addrspace.h>
+
+#define CO_CONFIGPR_VALID 0x3F1F41FF /* valid bits to write to ConfigPR */
+#define HAZARD_CP0 nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;
+#define CACHE_OPC 0xBC000000 /* MIPS cache instruction opcode */
+#define ICACHE_LINE_SIZE 32 /* Instruction cache line size bytes */
+#define DCACHE_LINE_SIZE 32 /* Data cache line size in bytes */
+
+#define ICACHE_SET_COUNT 256 /* Instruction cache set count */
+#define DCACHE_SET_COUNT 128 /* Data cache set count */
+
+#define ICACHE_SET_SIZE (ICACHE_SET_COUNT * ICACHE_LINE_SIZE)
+#define DCACHE_SET_SIZE (DCACHE_SET_COUNT * DCACHE_LINE_SIZE)
+
+ .macro kernel_entry_setup
+ .set push
+ .set noreorder
+ /*
+ * PNX8550 entry point, when running a non compressed
+ * kernel. When loading a zImage, the head.S code in
+ * arch/mips/zboot/pnx8550 will init the caches and,
+ * decompress the kernel, and branch to kernel_entry.
+ */
+cache_begin: li t0, (1<<28)
+ mtc0 t0, CP0_STATUS /* cp0 usable */
+ HAZARD_CP0
+
+ mtc0 zero, CP0_CAUSE
+ HAZARD_CP0
+
+
+ /* Set static virtual to phys address translation and TLB disabled */
+ mfc0 t0, CP0_CONFIG, 7
+ HAZARD_CP0
+
+ and t0,~((1<<19) | (1<<20)) /* TLB/MAP cleared */
+ mtc0 t0, CP0_CONFIG, 7
+ HAZARD_CP0
+
+ /* CPU boots with kseg0 cache algo set to 0x2 -- uncached */
+
+ init_icache
+ nop
+ init_dcache
+ nop
+
+ cachePr4450ICReset
+ nop
+
+ cachePr4450DCReset
+ nop
+
+ /* read ConfigPR into t0 */
+ mfc0 t0, CP0_CONFIG, 7
+ HAZARD_CP0
+
+ /* enable the TLB */
+ or t0, (1<<19)
+
+ /* disable the ICACHE: at least 10x slower */
+ /* or t0, (1<<26) */
+
+ /* disable the DCACHE; CONFIG_CPU_HAS_LLSC should not be set */
+ /* or t0, (1<<27) */
+
+ and t0, CO_CONFIGPR_VALID
+
+ /* enable TLB. */
+ mtc0 t0, CP0_CONFIG, 7
+ HAZARD_CP0
+cache_end:
+ /* Setup CMEM_0 to MMIO address space, 2MB */
+ lui t0, 0x1BE0
+ addi t0, t0, 0x3
+ mtc0 $8, $22, 4
+ nop
+
+ /* Setup CMEM_1, 128MB */
+ lui t0, 0x1000
+ addi t0, t0, 0xf
+ mtc0 $8, $22, 5
+ nop
+
+
+ /* Setup CMEM_2, 32MB */
+ lui t0, 0x1C00
+ addi t0, t0, 0xb
+ mtc0 $8, $22, 6
+ nop
+
+ /* Setup CMEM_3, 0MB */
+ lui t0, 0x0
+ addi t0, t0, 0x0
+ mtc0 $8, $22, 7
+ nop
+
+ /* Enable cache */
+ mfc0 t0, CP0_CONFIG
+ HAZARD_CP0
+ and t0, t0, 0xFFFFFFF8
+ or t0, t0, 3
+ mtc0 t0, CP0_CONFIG
+ HAZARD_CP0
+ .set pop
+ .endm
+
+ .macro init_icache
+ .set push
+ .set noreorder
+
+ /* Get Cache Configuration */
+ mfc0 t3, CP0_CONFIG, 1
+ HAZARD_CP0
+
+ /* get cache Line size */
+
+ srl t1, t3, 19 /* C0_CONFIGPR_IL_SHIFT */
+ andi t1, t1, 0x7 /* C0_CONFIGPR_IL_MASK */
+ beq t1, zero, pr4450_instr_cache_invalidated /* if zero instruction cache is absent */
+ nop
+ addiu t0, t1, 1
+ ori t1, zero, 1
+ sllv t1, t1, t0
+
+ /* get max cache Index */
+ srl t2, t3, 22 /* C0_CONFIGPR_IS_SHIFT */
+ andi t2, t2, 0x7 /* C0_CONFIGPR_IS_MASK */
+ addiu t0, t2, 6
+ ori t2, zero, 1
+ sllv t2, t2, t0
+
+ /* get max cache way */
+ srl t3, t3, 16 /* C0_CONFIGPR_IA_SHIFT */
+ andi t3, t3, 0x7 /* C0_CONFIGPR_IA_MASK */
+ addiu t3, t3, 1
+
+ /* total no of cache lines */
+ multu t2, t3 /* max index * max way */
+ mflo t2
+ addiu t2, t2, -1
+
+ move t0, zero
+pr4450_next_instruction_cache_set:
+ cache Index_Invalidate_I, 0(t0)
+ addu t0, t0, t1 /* add bytes in a line */
+ bne t2, zero, pr4450_next_instruction_cache_set
+ addiu t2, t2, -1 /* reduce no of lines to invalidate by one */
+pr4450_instr_cache_invalidated:
+ .set pop
+ .endm
+
+ .macro init_dcache
+ .set push
+ .set noreorder
+ move t1, zero
+
+ /* Store Tag Information */
+ mtc0 zero, CP0_TAGLO, 0
+ HAZARD_CP0
+
+ mtc0 zero, CP0_TAGHI, 0
+ HAZARD_CP0
+
+ /* Cache size is 16384 = 512 lines x 32 bytes per line */
+ or t2, zero, (128*4)-1 /* 512 lines */
+ /* Invalidate all lines */
+2:
+ cache Index_Store_Tag_D, 0(t1)
+ addiu t2, t2, -1
+ bne t2, zero, 2b
+ addiu t1, t1, 32 /* 32 bytes in a line */
+ .set pop
+ .endm
+
+ .macro cachePr4450ICReset
+ .set push
+ .set noreorder
+
+ /* Save CP0 status reg on entry; */
+ /* disable interrupts during cache reset */
+ mfc0 t0, CP0_STATUS /* T0 = interrupt status on entry */
+ HAZARD_CP0
+
+ mtc0 zero, CP0_STATUS /* disable CPU interrupts */
+ HAZARD_CP0
+
+ or t1, zero, zero /* T1 = starting cache index (0) */
+ ori t2, zero, (256 - 1) /* T2 = inst cache set cnt - 1 */
+
+ icache_invd_loop:
+ /* 9 == register t1 */
+ .word (CACHE_OPC | (9 << 21) | (Index_Invalidate_I << 16) | \
+ (0 * ICACHE_SET_SIZE)) /* invalidate inst cache WAY0 */
+ .word (CACHE_OPC | (9 << 21) | (Index_Invalidate_I << 16) | \
+ (1 * ICACHE_SET_SIZE)) /* invalidate inst cache WAY1 */
+
+ addiu t1, t1, ICACHE_LINE_SIZE /* T1 = next cache line index */
+ bne t2, zero, icache_invd_loop /* T2 = 0 if all sets invalidated */
+ addiu t2, t2, -1 /* decrement T2 set cnt (delay slot) */
+
+ /* Initialize the latches in the instruction cache tag */
+ /* that drive the way selection tri-state bus drivers, by doing a */
+ /* dummy load while the instruction cache is still disabled. */
+ /* TODO: Is this needed ? */
+ la t1, KSEG0 /* T1 = cached memory base address */
+ lw zero, 0x0000(t1) /* (dummy read of first memory word) */
+
+ mtc0 t0, CP0_STATUS /* restore interrupt status on entry */
+ HAZARD_CP0
+ .set pop
+ .endm
+
+ .macro cachePr4450DCReset
+ .set push
+ .set noreorder
+ mfc0 t0, CP0_STATUS /* T0 = interrupt status on entry */
+ HAZARD_CP0
+ mtc0 zero, CP0_STATUS /* disable CPU interrupts */
+ HAZARD_CP0
+
+ /* Writeback/invalidate entire data cache sets/ways/lines */
+ or t1, zero, zero /* T1 = starting cache index (0) */
+ ori t2, zero, (DCACHE_SET_COUNT - 1) /* T2 = data cache set cnt - 1 */
+
+ dcache_wbinvd_loop:
+ /* 9 == register t1 */
+ .word (CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \
+ (0 * DCACHE_SET_SIZE)) /* writeback/invalidate WAY0 */
+ .word (CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \
+ (1 * DCACHE_SET_SIZE)) /* writeback/invalidate WAY1 */
+ .word (CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \
+ (2 * DCACHE_SET_SIZE)) /* writeback/invalidate WAY2 */
+ .word (CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \
+ (3 * DCACHE_SET_SIZE)) /* writeback/invalidate WAY3 */
+
+ addiu t1, t1, DCACHE_LINE_SIZE /* T1 = next data cache line index */
+ bne t2, zero, dcache_wbinvd_loop /* T2 = 0 when wbinvd entire cache */
+ addiu t2, t2, -1 /* decrement T2 set cnt (delay slot) */
+
+ /* Initialize the latches in the data cache tag that drive the way
+ selection tri-state bus drivers, by doing a dummy load while the
+ data cache is still in the disabled mode. TODO: Is this needed ? */
+ la t1, KSEG0 /* T1 = cached memory base address */
+ lw zero, 0x0000(t1) /* (dummy read of first memory word) */
+
+ mtc0 t0, CP0_STATUS /* restore interrupt status on entry */
+ HAZARD_CP0
+ .set pop
+ .endm
+
+#endif /* __ASM_MACH_KERNEL_ENTRY_INIT_H */
diff --git a/include/asm-mips/mach-pnx8550/nand.h b/include/asm-mips/mach-pnx8550/nand.h
new file mode 100644
index 000000000000..aefbc514ab09
--- /dev/null
+++ b/include/asm-mips/mach-pnx8550/nand.h
@@ -0,0 +1,121 @@
+#ifndef __PNX8550_NAND_H
+#define __PNX8550_NAND_H
+
+#define PNX8550_NAND_BASE_ADDR 0x10000000
+#define PNX8550_PCIXIO_BASE 0xBBE40000
+
+#define PNX8550_DMA_EXT_ADDR *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x800)
+#define PNX8550_DMA_INT_ADDR *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x804)
+#define PNX8550_DMA_TRANS_SIZE *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x808)
+#define PNX8550_DMA_CTRL *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x80c)
+#define PNX8550_XIO_SEL0 *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x814)
+#define PNX8550_GPXIO_ADDR *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x820)
+#define PNX8550_GPXIO_WR *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x824)
+#define PNX8550_GPXIO_RD *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x828)
+#define PNX8550_GPXIO_CTRL *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x82C)
+#define PNX8550_XIO_FLASH_CTRL *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x830)
+#define PNX8550_GPXIO_INT_STATUS *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfb0)
+#define PNX8550_GPXIO_INT_ENABLE *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfb4)
+#define PNX8550_GPXIO_INT_CLEAR *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfb8)
+#define PNX8550_DMA_INT_STATUS *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfd0)
+#define PNX8550_DMA_INT_ENABLE *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfd4)
+#define PNX8550_DMA_INT_CLEAR *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfd8)
+
+#define PNX8550_XIO_SEL0_EN_16BIT 0x00800000
+#define PNX8550_XIO_SEL0_USE_ACK 0x00400000
+#define PNX8550_XIO_SEL0_REN_HIGH 0x00100000
+#define PNX8550_XIO_SEL0_REN_LOW 0x00040000
+#define PNX8550_XIO_SEL0_WEN_HIGH 0x00010000
+#define PNX8550_XIO_SEL0_WEN_LOW 0x00004000
+#define PNX8550_XIO_SEL0_WAIT 0x00000200
+#define PNX8550_XIO_SEL0_OFFSET 0x00000020
+#define PNX8550_XIO_SEL0_TYPE_68360 0x00000000
+#define PNX8550_XIO_SEL0_TYPE_NOR 0x00000008
+#define PNX8550_XIO_SEL0_TYPE_NAND 0x00000010
+#define PNX8550_XIO_SEL0_TYPE_IDE 0x00000018
+#define PNX8550_XIO_SEL0_SIZE_8MB 0x00000000
+#define PNX8550_XIO_SEL0_SIZE_16MB 0x00000002
+#define PNX8550_XIO_SEL0_SIZE_32MB 0x00000004
+#define PNX8550_XIO_SEL0_SIZE_64MB 0x00000006
+#define PNX8550_XIO_SEL0_ENAB 0x00000001
+
+#define PNX8550_SEL0_DEFAULT ((PNX8550_XIO_SEL0_EN_16BIT) | \
+ (PNX8550_XIO_SEL0_REN_HIGH*0)| \
+ (PNX8550_XIO_SEL0_REN_LOW*2) | \
+ (PNX8550_XIO_SEL0_WEN_HIGH*0)| \
+ (PNX8550_XIO_SEL0_WEN_LOW*2) | \
+ (PNX8550_XIO_SEL0_WAIT*4) | \
+ (PNX8550_XIO_SEL0_OFFSET*0) | \
+ (PNX8550_XIO_SEL0_TYPE_NAND) | \
+ (PNX8550_XIO_SEL0_SIZE_32MB) | \
+ (PNX8550_XIO_SEL0_ENAB))
+
+#define PNX8550_GPXIO_PENDING 0x00000200
+#define PNX8550_GPXIO_DONE 0x00000100
+#define PNX8550_GPXIO_CLR_DONE 0x00000080
+#define PNX8550_GPXIO_INIT 0x00000040
+#define PNX8550_GPXIO_READ_CMD 0x00000010
+#define PNX8550_GPXIO_BEN 0x0000000F
+
+#define PNX8550_XIO_FLASH_64MB 0x00200000
+#define PNX8550_XIO_FLASH_INC_DATA 0x00100000
+#define PNX8550_XIO_FLASH_CMD_PH 0x000C0000
+#define PNX8550_XIO_FLASH_CMD_PH2 0x00080000
+#define PNX8550_XIO_FLASH_CMD_PH1 0x00040000
+#define PNX8550_XIO_FLASH_CMD_PH0 0x00000000
+#define PNX8550_XIO_FLASH_ADR_PH 0x00030000
+#define PNX8550_XIO_FLASH_ADR_PH3 0x00030000
+#define PNX8550_XIO_FLASH_ADR_PH2 0x00020000
+#define PNX8550_XIO_FLASH_ADR_PH1 0x00010000
+#define PNX8550_XIO_FLASH_ADR_PH0 0x00000000
+#define PNX8550_XIO_FLASH_CMD_B(x) ((x<<8) & 0x0000FF00)
+#define PNX8550_XIO_FLASH_CMD_A(x) (x & 0x000000FF)
+
+#define PNX8550_XIO_INT_ACK 0x00004000
+#define PNX8550_XIO_INT_COMPL 0x00002000
+#define PNX8550_XIO_INT_NONSUP 0x00000200
+#define PNX8550_XIO_INT_ABORT 0x00000004
+
+#define PNX8550_DMA_CTRL_SINGLE_DATA 0x00000400
+#define PNX8550_DMA_CTRL_SND2XIO 0x00000200
+#define PNX8550_DMA_CTRL_FIX_ADDR 0x00000100
+#define PNX8550_DMA_CTRL_BURST_8 0x00000000
+#define PNX8550_DMA_CTRL_BURST_16 0x00000020
+#define PNX8550_DMA_CTRL_BURST_32 0x00000040
+#define PNX8550_DMA_CTRL_BURST_64 0x00000060
+#define PNX8550_DMA_CTRL_BURST_128 0x00000080
+#define PNX8550_DMA_CTRL_BURST_256 0x000000A0
+#define PNX8550_DMA_CTRL_BURST_512 0x000000C0
+#define PNX8550_DMA_CTRL_BURST_NORES 0x000000E0
+#define PNX8550_DMA_CTRL_INIT_DMA 0x00000010
+#define PNX8550_DMA_CTRL_CMD_TYPE 0x0000000F
+
+/* see PCI system arch, page 100 for the full list: */
+#define PNX8550_DMA_CTRL_PCI_CMD_READ 0x00000006
+#define PNX8550_DMA_CTRL_PCI_CMD_WRITE 0x00000007
+
+#define PNX8550_DMA_INT_STAT_ACK_DONE (1<<14)
+#define PNX8550_DMA_INT_STAT_DMA_DONE (1<<12)
+#define PNX8550_DMA_INT_STAT_DMA_ERR (1<<9)
+#define PNX8550_DMA_INT_STAT_PERR5 (1<<5)
+#define PNX8550_DMA_INT_STAT_PERR4 (1<<4)
+#define PNX8550_DMA_INT_STAT_M_ABORT (1<<2)
+#define PNX8550_DMA_INT_STAT_T_ABORT (1<<1)
+
+#define PNX8550_DMA_INT_EN_ACK_DONE (1<<14)
+#define PNX8550_DMA_INT_EN_DMA_DONE (1<<12)
+#define PNX8550_DMA_INT_EN_DMA_ERR (1<<9)
+#define PNX8550_DMA_INT_EN_PERR5 (1<<5)
+#define PNX8550_DMA_INT_EN_PERR4 (1<<4)
+#define PNX8550_DMA_INT_EN_M_ABORT (1<<2)
+#define PNX8550_DMA_INT_EN_T_ABORT (1<<1)
+
+#define PNX8550_DMA_INT_CLR_ACK_DONE (1<<14)
+#define PNX8550_DMA_INT_CLR_DMA_DONE (1<<12)
+#define PNX8550_DMA_INT_CLR_DMA_ERR (1<<9)
+#define PNX8550_DMA_INT_CLR_PERR5 (1<<5)
+#define PNX8550_DMA_INT_CLR_PERR4 (1<<4)
+#define PNX8550_DMA_INT_CLR_M_ABORT (1<<2)
+#define PNX8550_DMA_INT_CLR_T_ABORT (1<<1)
+
+#endif
diff --git a/include/asm-mips/mach-pnx8550/pci.h b/include/asm-mips/mach-pnx8550/pci.h
new file mode 100644
index 000000000000..b921508d701b
--- /dev/null
+++ b/include/asm-mips/mach-pnx8550/pci.h
@@ -0,0 +1,185 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * PCI specific definitions
+ *
+ * Author: source@mvista.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#ifndef __PNX8550_PCI_H
+#define __PNX8550_PCI_H
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#define PCI_ACCESS_READ 0
+#define PCI_ACCESS_WRITE 1
+
+#define PCI_CMD_IOR 0x20
+#define PCI_CMD_IOW 0x30
+#define PCI_CMD_CONFIG_READ 0xa0
+#define PCI_CMD_CONFIG_WRITE 0xb0
+
+#define PCI_IO_TIMEOUT 1000
+#define PCI_IO_RETRY 5
+/* Timeout for IO and CFG accesses.
+ This is in 1/1024 th of a jiffie(=10ms)
+ i.e. approx 10us */
+#define PCI_IO_JIFFIES_TIMEOUT 40
+#define PCI_IO_JIFFIES_SHIFT 10
+
+#define PCI_BYTE_ENABLE_MASK 0x0000000f
+#define PCI_CFG_BUS_SHIFT 16
+#define PCI_CFG_FUNC_SHIFT 8
+#define PCI_CFG_REG_SHIFT 2
+
+#define PCI_BASE 0x1be00000
+#define PCI_SETUP 0x00040010
+#define PCI_DIS_REQGNT (1<<30)
+#define PCI_DIS_REQGNTA (1<<29)
+#define PCI_DIS_REQGNTB (1<<28)
+#define PCI_D2_SUPPORT (1<<27)
+#define PCI_D1_SUPPORT (1<<26)
+#define PCI_EN_TA (1<<24)
+#define PCI_EN_PCI2MMI (1<<23)
+#define PCI_EN_XIO (1<<22)
+#define PCI_BASE18_PREF (1<<21)
+#define SIZE_16M 0x3
+#define SIZE_32M 0x4
+#define SIZE_64M 0x5
+#define SIZE_128M 0x6
+#define PCI_SETUP_BASE18_SIZE(X) (X<<18)
+#define PCI_SETUP_BASE18_EN (1<<17)
+#define PCI_SETUP_BASE14_PREF (1<<16)
+#define PCI_SETUP_BASE14_SIZE(X) (X<<12)
+#define PCI_SETUP_BASE14_EN (1<<11)
+#define PCI_SETUP_BASE10_PREF (1<<10)
+#define PCI_SETUP_BASE10_SIZE(X) (X<<7)
+#define PCI_SETUP_CFGMANAGE_EN (1<<1)
+#define PCI_SETUP_PCIARB_EN (1<<0)
+
+#define PCI_CTRL 0x040014
+#define PCI_SWPB_DCS_PCI (1<<16)
+#define PCI_SWPB_PCI_PCI (1<<15)
+#define PCI_SWPB_PCI_DCS (1<<14)
+#define PCI_REG_WR_POST (1<<13)
+#define PCI_XIO_WR_POST (1<<12)
+#define PCI_PCI2_WR_POST (1<<13)
+#define PCI_PCI1_WR_POST (1<<12)
+#define PCI_SERR_SEEN (1<<11)
+#define PCI_B10_SPEC_RD (1<<6)
+#define PCI_B14_SPEC_RD (1<<5)
+#define PCI_B18_SPEC_RD (1<<4)
+#define PCI_B10_NOSUBWORD (1<<3)
+#define PCI_B14_NOSUBWORD (1<<2)
+#define PCI_B18_NOSUBWORD (1<<1)
+#define PCI_RETRY_TMREN (1<<0)
+
+#define PCI_BASE1_LO 0x040018
+#define PCI_BASE1_HI 0x04001C
+#define PCI_BASE2_LO 0x040020
+#define PCI_BASE2_HI 0x040024
+#define PCI_RDLIFETIM 0x040028
+#define PCI_GPPM_ADDR 0x04002C
+#define PCI_GPPM_WDAT 0x040030
+#define PCI_GPPM_RDAT 0x040034
+#define PCI_GPPM_CTRL 0x040038
+#define GPPM_DONE (1<<10)
+#define INIT_PCI_CYCLE (1<<9)
+#define GPPM_CMD(X) (((X)&0xf)<<4)
+#define GPPM_BYTEEN(X) ((X)&0xf)
+#define PCI_UNLOCKREG 0x04003C
+#define UNLOCK_SSID(X) (((X)&0xff)<<8)
+#define UNLOCK_SETUP(X) (((X)&0xff)<<0)
+#define UNLOCK_MAGIC 0xCA
+#define PCI_DEV_VEND_ID 0x040040
+#define DEVICE_ID(X) (((X)>>16)&0xffff)
+#define VENDOR_ID(X) (((X)&0xffff))
+#define PCI_CFG_CMDSTAT 0x040044
+#define PCI_CFG_STATUS(X) (((X)>>16)&0xffff)
+#define PCI_CFG_COMMAND(X) ((X)&0xffff)
+#define PCI_CLASS_REV 0x040048
+#define PCI_CLASSCODE(X) (((X)>>8)&0xffffff)
+#define PCI_REVID(X) ((X)&0xff)
+#define PCI_LAT_TMR 0x04004c
+#define PCI_BASE10 0x040050
+#define PCI_BASE14 0x040054
+#define PCI_BASE18 0x040058
+#define PCI_SUBSYS_ID 0x04006c
+#define PCI_CAP_PTR 0x040074
+#define PCI_CFG_MISC 0x04007c
+#define PCI_PMC 0x040080
+#define PCI_PWR_STATE 0x040084
+#define PCI_IO 0x040088
+#define PCI_SLVTUNING 0x04008C
+#define PCI_DMATUNING 0x040090
+#define PCI_DMAEADDR 0x040800
+#define PCI_DMAIADDR 0x040804
+#define PCI_DMALEN 0x040808
+#define PCI_DMACTRL 0x04080C
+#define PCI_XIOCTRL 0x040810
+#define PCI_SEL0PROF 0x040814
+#define PCI_SEL1PROF 0x040818
+#define PCI_SEL2PROF 0x04081C
+#define PCI_GPXIOADDR 0x040820
+#define PCI_NANDCTRLS 0x400830
+#define PCI_SEL3PROF 0x040834
+#define PCI_SEL4PROF 0x040838
+#define PCI_GPXIO_STAT 0x040FB0
+#define PCI_GPXIO_IMASK 0x040FB4
+#define PCI_GPXIO_ICLR 0x040FB8
+#define PCI_GPXIO_ISET 0x040FBC
+#define PCI_GPPM_STATUS 0x040FC0
+#define GPPM_DONE (1<<10)
+#define GPPM_ERR (1<<9)
+#define GPPM_MPAR_ERR (1<<8)
+#define GPPM_PAR_ERR (1<<7)
+#define GPPM_R_MABORT (1<<2)
+#define GPPM_R_TABORT (1<<1)
+#define PCI_GPPM_IMASK 0x040FC4
+#define PCI_GPPM_ICLR 0x040FC8
+#define PCI_GPPM_ISET 0x040FCC
+#define PCI_DMA_STATUS 0x040FD0
+#define PCI_DMA_IMASK 0x040FD4
+#define PCI_DMA_ICLR 0x040FD8
+#define PCI_DMA_ISET 0x040FDC
+#define PCI_ISTATUS 0x040FE0
+#define PCI_IMASK 0x040FE4
+#define PCI_ICLR 0x040FE8
+#define PCI_ISET 0x040FEC
+#define PCI_MOD_ID 0x040FFC
+
+/*
+ * PCI configuration cycle AD bus definition
+ */
+/* Type 0 */
+#define PCI_CFG_TYPE0_REG_SHF 0
+#define PCI_CFG_TYPE0_FUNC_SHF 8
+
+/* Type 1 */
+#define PCI_CFG_TYPE1_REG_SHF 0
+#define PCI_CFG_TYPE1_FUNC_SHF 8
+#define PCI_CFG_TYPE1_DEV_SHF 11
+#define PCI_CFG_TYPE1_BUS_SHF 16
+
+/*
+ * Ethernet device DP83816 definition
+ */
+#define DP83816_IRQ_ETHER 66
+
+#endif
diff --git a/include/asm-mips/mach-pnx8550/uart.h b/include/asm-mips/mach-pnx8550/uart.h
new file mode 100644
index 000000000000..e32b9a23d70e
--- /dev/null
+++ b/include/asm-mips/mach-pnx8550/uart.h
@@ -0,0 +1,16 @@
+#ifndef __IP3106_UART_H
+#define __IP3106_UART_H
+
+#include <int.h>
+
+/* early macros for kgdb use. fixme: clean this up */
+
+#define UART_BASE 0xbbe4a000 /* PNX8550 */
+
+#define PNX8550_UART_PORT0 (UART_BASE)
+#define PNX8550_UART_PORT1 (UART_BASE + 0x1000)
+
+#define PNX8550_UART_INT(x) (PNX8550_INT_GIC_MIN+19+x)
+#define IRQ_TO_UART(x) (x-PNX8550_INT_GIC_MIN-19)
+
+#endif
diff --git a/include/asm-mips/mach-pnx8550/usb.h b/include/asm-mips/mach-pnx8550/usb.h
new file mode 100644
index 000000000000..483b7fc65d41
--- /dev/null
+++ b/include/asm-mips/mach-pnx8550/usb.h
@@ -0,0 +1,32 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * USB specific definitions
+ *
+ * Author: source@mvista.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#ifndef __PNX8550_USB_H
+#define __PNX8550_USB_H
+
+/*
+ * USB Host controller
+ */
+
+#define PNX8550_USB_OHCI_OP_BASE 0x1be48000
+#define PNX8550_USB_OHCI_OP_LEN 0x1000
+
+#endif
diff --git a/include/asm-mips/mach-rm200/cpu-feature-overrides.h b/include/asm-mips/mach-rm200/cpu-feature-overrides.h
index f48736032b2a..79f9b064c864 100644
--- a/include/asm-mips/mach-rm200/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-rm200/cpu-feature-overrides.h
@@ -14,7 +14,7 @@
#define cpu_has_tlb 1
#define cpu_has_4kex 1
-#define cpu_has_4ktlb 1
+#define cpu_has_4kcache 1
#define cpu_has_fpu 1
#define cpu_has_32fpr 1
#define cpu_has_counter 1
@@ -31,6 +31,7 @@
#define cpu_has_vtag_icache 0
#define cpu_has_dc_aliases (PAGE_SIZE < 0x4000)
#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_dsp 0
#define cpu_has_nofpuex 0
#define cpu_has_64bits 1
diff --git a/include/asm-mips/mach-sibyte/cpu-feature-overrides.h b/include/asm-mips/mach-sibyte/cpu-feature-overrides.h
index a3a2cc6014b2..193a666cd131 100644
--- a/include/asm-mips/mach-sibyte/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-sibyte/cpu-feature-overrides.h
@@ -25,6 +25,7 @@
#define cpu_has_vtag_icache 1
#define cpu_has_dc_aliases 0
#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_dsp 0
#define cpu_icache_snoops_remote_store 0
#define cpu_has_nofpuex 0
diff --git a/include/asm-mips/mach-sim/cpu-feature-overrides.h b/include/asm-mips/mach-sim/cpu-feature-overrides.h
new file mode 100644
index 000000000000..cadbe8eda79c
--- /dev/null
+++ b/include/asm-mips/mach-sim/cpu-feature-overrides.h
@@ -0,0 +1,66 @@
+/*
+ * 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) 2003, 2004 Chris Dearman
+ */
+#ifndef __ASM_MACH_SIM_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_SIM_CPU_FEATURE_OVERRIDES_H
+
+#include <linux/config.h>
+
+/*
+ * CPU feature overrides for MIPS boards
+ */
+#ifdef CONFIG_CPU_MIPS32
+#define cpu_has_tlb 1
+#define cpu_has_4kex 1
+#define cpu_has_4kcache 1
+#define cpu_has_fpu 0
+/* #define cpu_has_32fpr ? */
+#define cpu_has_counter 1
+/* #define cpu_has_watch ? */
+#define cpu_has_divec 1
+#define cpu_has_vce 0
+/* #define cpu_has_cache_cdex_p ? */
+/* #define cpu_has_cache_cdex_s ? */
+/* #define cpu_has_prefetch ? */
+#define cpu_has_mcheck 1
+/* #define cpu_has_ejtag ? */
+#define cpu_has_llsc 1
+/* #define cpu_has_vtag_icache ? */
+/* #define cpu_has_dc_aliases ? */
+/* #define cpu_has_ic_fills_f_dc ? */
+#define cpu_has_nofpuex 0
+/* #define cpu_has_64bits ? */
+/* #define cpu_has_64bit_zero_reg ? */
+/* #define cpu_has_subset_pcaches ? */
+#endif
+
+#ifdef CONFIG_CPU_MIPS64
+#define cpu_has_tlb 1
+#define cpu_has_4kex 1
+#define cpu_has_4kcache 1
+/* #define cpu_has_fpu ? */
+/* #define cpu_has_32fpr ? */
+#define cpu_has_counter 1
+/* #define cpu_has_watch ? */
+#define cpu_has_divec 1
+#define cpu_has_vce 0
+/* #define cpu_has_cache_cdex_p ? */
+/* #define cpu_has_cache_cdex_s ? */
+/* #define cpu_has_prefetch ? */
+#define cpu_has_mcheck 1
+/* #define cpu_has_ejtag ? */
+#define cpu_has_llsc 1
+/* #define cpu_has_vtag_icache ? */
+/* #define cpu_has_dc_aliases ? */
+/* #define cpu_has_ic_fills_f_dc ? */
+#define cpu_has_nofpuex 0
+/* #define cpu_has_64bits ? */
+/* #define cpu_has_64bit_zero_reg ? */
+/* #define cpu_has_subset_pcaches ? */
+#endif
+
+#endif /* __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H */
diff --git a/include/asm-mips/mach-yosemite/cpu-feature-overrides.h b/include/asm-mips/mach-yosemite/cpu-feature-overrides.h
index 58603e3daca6..463d051f4683 100644
--- a/include/asm-mips/mach-yosemite/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-yosemite/cpu-feature-overrides.h
@@ -25,6 +25,7 @@
#define cpu_has_vtag_icache 0
#define cpu_has_dc_aliases 0
#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_dsp 0
#define cpu_icache_snoops_remote_store 0
#define cpu_has_nofpuex 0
@@ -36,10 +37,4 @@
#define cpu_icache_line_size() 32
#define cpu_scache_line_size() 32
-/*
- * On the RM9000 we need to ensure that I-cache lines being fetches only
- * contain valid instructions are funny things will happen.
- */
-#define PLAT_TRAMPOLINE_STUFF_LINE 32UL
-
#endif /* __ASM_MACH_YOSEMITE_CPU_FEATURE_OVERRIDES_H */
diff --git a/include/asm-mips/mips-boards/generic.h b/include/asm-mips/mips-boards/generic.h
index 65d1d16eab16..25b6ffc26623 100644
--- a/include/asm-mips/mips-boards/generic.h
+++ b/include/asm-mips/mips-boards/generic.h
@@ -66,6 +66,7 @@
#define MIPS_REVISION_CORID_CORE_EMUL 6
#define MIPS_REVISION_CORID_CORE_FPGA2 7
#define MIPS_REVISION_CORID_CORE_FPGAR2 8
+#define MIPS_REVISION_CORID_CORE_FPGA3 9
/**** Artificial corid defines ****/
/*
@@ -79,4 +80,10 @@
extern unsigned int mips_revision_corid;
+#ifdef CONFIG_PCI
+extern void mips_pcibios_init(void);
+#else
+#define mips_pcibios_init() do { } while (0)
+#endif
+
#endif /* __ASM_MIPS_BOARDS_GENERIC_H */
diff --git a/include/asm-mips/mips-boards/maltaint.h b/include/asm-mips/mips-boards/maltaint.h
index 376181882e81..da6cc2fbbc78 100644
--- a/include/asm-mips/mips-boards/maltaint.h
+++ b/include/asm-mips/mips-boards/maltaint.h
@@ -25,9 +25,63 @@
#ifndef _MIPS_MALTAINT_H
#define _MIPS_MALTAINT_H
-/* Number of IRQ supported on hw interrupt 0. */
-#define MALTAINT_END 16
+/*
+ * Interrupts 0..15 are used for Malta ISA compatible interrupts
+ */
+#define MALTA_INT_BASE 0
+
+/*
+ * Interrupts 16..23 are used for Malta CPU interrupts (nonEIC mode)
+ */
+#define MIPSCPU_INT_BASE 16
+
+/* CPU interrupt offsets */
+#define MIPSCPU_INT_SW0 0
+#define MIPSCPU_INT_SW1 1
+#define MIPSCPU_INT_MB0 2
+#define MIPSCPU_INT_I8259A MIPSCPU_INT_MB0
+#define MIPSCPU_INT_MB1 3
+#define MIPSCPU_INT_SMI MIPSCPU_INT_MB1
+#define MIPSCPU_INT_MB2 4
+#define MIPSCPU_INT_MB3 5
+#define MIPSCPU_INT_COREHI MIPSCPU_INT_MB3
+#define MIPSCPU_INT_MB4 6
+#define MIPSCPU_INT_CORELO MIPSCPU_INT_MB4
+#define MIPSCPU_INT_CPUCTR 7
+
+/*
+ * Interrupts 64..127 are used for Soc-it Classic interrupts
+ */
+#define MSC01C_INT_BASE 64
+
+/* SOC-it Classic interrupt offsets */
+#define MSC01C_INT_TMR 0
+#define MSC01C_INT_PCI 1
+
+/*
+ * Interrupts 64..127 are used for Soc-it EIC interrupts
+ */
+#define MSC01E_INT_BASE 64
+
+/* SOC-it EIC interrupt offsets */
+#define MSC01E_INT_SW0 1
+#define MSC01E_INT_SW1 2
+#define MSC01E_INT_MB0 3
+#define MSC01E_INT_I8259A MSC01E_INT_MB0
+#define MSC01E_INT_MB1 4
+#define MSC01E_INT_SMI MSC01E_INT_MB1
+#define MSC01E_INT_MB2 5
+#define MSC01E_INT_MB3 6
+#define MSC01E_INT_COREHI MSC01E_INT_MB3
+#define MSC01E_INT_MB4 7
+#define MSC01E_INT_CORELO MSC01E_INT_MB4
+#define MSC01E_INT_TMR 8
+#define MSC01E_INT_PCI 9
+#define MSC01E_INT_PERFCTR 10
+#define MSC01E_INT_CPUCTR 11
+#ifndef __ASSEMBLY__
extern void maltaint_init(void);
+#endif
#endif /* !(_MIPS_MALTAINT_H) */
diff --git a/include/asm-mips/mips-boards/msc01_pci.h b/include/asm-mips/mips-boards/msc01_pci.h
index 6b2a87a38f4b..8eaefb837b9d 100644
--- a/include/asm-mips/mips-boards/msc01_pci.h
+++ b/include/asm-mips/mips-boards/msc01_pci.h
@@ -1,8 +1,9 @@
/*
* PCI Register definitions for the MIPS System Controller.
*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved.
+ * Copyright (C) 2002, 2005 MIPS Technologies, Inc. All rights reserved.
+ * Authors: Carsten Langgaard <carstenl@mips.com>
+ * Maciej W. Rozycki <macro@mips.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
@@ -29,22 +30,22 @@
#define MSC01_PCI_CFGADDR_OFS 0x0610
#define MSC01_PCI_CFGDATA_OFS 0x0618
#define MSC01_PCI_IACK_OFS 0x0620
-#define MSC01_PCI_HEAD0_OFS 0x2000 /* DevID, VendorID */
-#define MSC01_PCI_HEAD1_OFS 0x2008 /* Status, Command */
-#define MSC01_PCI_HEAD2_OFS 0x2010 /* Class code, RevID */
-#define MSC01_PCI_HEAD3_OFS 0x2018 /* bist, header, latency */
-#define MSC01_PCI_HEAD4_OFS 0x2020 /* BAR 0 */
-#define MSC01_PCI_HEAD5_OFS 0x2028 /* BAR 1 */
-#define MSC01_PCI_HEAD6_OFS 0x2030 /* BAR 2 */
-#define MSC01_PCI_HEAD7_OFS 0x2038 /* BAR 3 */
-#define MSC01_PCI_HEAD8_OFS 0x2040 /* BAR 4 */
-#define MSC01_PCI_HEAD9_OFS 0x2048 /* BAR 5 */
-#define MSC01_PCI_HEAD10_OFS 0x2050 /* CardBus CIS Ptr */
-#define MSC01_PCI_HEAD11_OFS 0x2058 /* SubSystem ID, -VendorID */
-#define MSC01_PCI_HEAD12_OFS 0x2060 /* ROM BAR */
-#define MSC01_PCI_HEAD13_OFS 0x2068 /* Capabilities ptr */
-#define MSC01_PCI_HEAD14_OFS 0x2070 /* reserved */
-#define MSC01_PCI_HEAD15_OFS 0x2078 /* Maxl, ming, intpin, int */
+#define MSC01_PCI_HEAD0_OFS 0x2000 /* DevID, VendorID */
+#define MSC01_PCI_HEAD1_OFS 0x2008 /* Status, Command */
+#define MSC01_PCI_HEAD2_OFS 0x2010 /* Class code, RevID */
+#define MSC01_PCI_HEAD3_OFS 0x2018 /* bist, header, latency */
+#define MSC01_PCI_HEAD4_OFS 0x2020 /* BAR 0 */
+#define MSC01_PCI_HEAD5_OFS 0x2028 /* BAR 1 */
+#define MSC01_PCI_HEAD6_OFS 0x2030 /* BAR 2 */
+#define MSC01_PCI_HEAD7_OFS 0x2038 /* BAR 3 */
+#define MSC01_PCI_HEAD8_OFS 0x2040 /* BAR 4 */
+#define MSC01_PCI_HEAD9_OFS 0x2048 /* BAR 5 */
+#define MSC01_PCI_HEAD10_OFS 0x2050 /* CardBus CIS Ptr */
+#define MSC01_PCI_HEAD11_OFS 0x2058 /* SubSystem ID, -VendorID */
+#define MSC01_PCI_HEAD12_OFS 0x2060 /* ROM BAR */
+#define MSC01_PCI_HEAD13_OFS 0x2068 /* Capabilities ptr */
+#define MSC01_PCI_HEAD14_OFS 0x2070 /* reserved */
+#define MSC01_PCI_HEAD15_OFS 0x2078 /* Maxl, ming, intpin, int */
#define MSC01_PCI_BAR0_OFS 0x2220
#define MSC01_PCI_CFG_OFS 0x2380
#define MSC01_PCI_SWAP_OFS 0x2388
@@ -86,73 +87,73 @@
#define MSC01_PCI_P2SCMAPL_MAP_SHF 24
#define MSC01_PCI_P2SCMAPL_MAP_MSK 0xff000000
-#define MSC01_PCI_INTCFG_RST_SHF 10
-#define MSC01_PCI_INTCFG_RST_MSK 0x00000400
-#define MSC01_PCI_INTCFG_RST_BIT 0x00000400
-#define MSC01_PCI_INTCFG_MWE_SHF 9
-#define MSC01_PCI_INTCFG_MWE_MSK 0x00000200
-#define MSC01_PCI_INTCFG_MWE_BIT 0x00000200
-#define MSC01_PCI_INTCFG_DTO_SHF 8
-#define MSC01_PCI_INTCFG_DTO_MSK 0x00000100
-#define MSC01_PCI_INTCFG_DTO_BIT 0x00000100
-#define MSC01_PCI_INTCFG_MA_SHF 7
-#define MSC01_PCI_INTCFG_MA_MSK 0x00000080
-#define MSC01_PCI_INTCFG_MA_BIT 0x00000080
-#define MSC01_PCI_INTCFG_TA_SHF 6
-#define MSC01_PCI_INTCFG_TA_MSK 0x00000040
-#define MSC01_PCI_INTCFG_TA_BIT 0x00000040
-#define MSC01_PCI_INTCFG_RTY_SHF 5
-#define MSC01_PCI_INTCFG_RTY_MSK 0x00000020
-#define MSC01_PCI_INTCFG_RTY_BIT 0x00000020
-#define MSC01_PCI_INTCFG_MWP_SHF 4
-#define MSC01_PCI_INTCFG_MWP_MSK 0x00000010
-#define MSC01_PCI_INTCFG_MWP_BIT 0x00000010
-#define MSC01_PCI_INTCFG_MRP_SHF 3
-#define MSC01_PCI_INTCFG_MRP_MSK 0x00000008
-#define MSC01_PCI_INTCFG_MRP_BIT 0x00000008
-#define MSC01_PCI_INTCFG_SWP_SHF 2
-#define MSC01_PCI_INTCFG_SWP_MSK 0x00000004
-#define MSC01_PCI_INTCFG_SWP_BIT 0x00000004
-#define MSC01_PCI_INTCFG_SRP_SHF 1
-#define MSC01_PCI_INTCFG_SRP_MSK 0x00000002
-#define MSC01_PCI_INTCFG_SRP_BIT 0x00000002
-#define MSC01_PCI_INTCFG_SE_SHF 0
-#define MSC01_PCI_INTCFG_SE_MSK 0x00000001
-#define MSC01_PCI_INTCFG_SE_BIT 0x00000001
+#define MSC01_PCI_INTCFG_RST_SHF 10
+#define MSC01_PCI_INTCFG_RST_MSK 0x00000400
+#define MSC01_PCI_INTCFG_RST_BIT 0x00000400
+#define MSC01_PCI_INTCFG_MWE_SHF 9
+#define MSC01_PCI_INTCFG_MWE_MSK 0x00000200
+#define MSC01_PCI_INTCFG_MWE_BIT 0x00000200
+#define MSC01_PCI_INTCFG_DTO_SHF 8
+#define MSC01_PCI_INTCFG_DTO_MSK 0x00000100
+#define MSC01_PCI_INTCFG_DTO_BIT 0x00000100
+#define MSC01_PCI_INTCFG_MA_SHF 7
+#define MSC01_PCI_INTCFG_MA_MSK 0x00000080
+#define MSC01_PCI_INTCFG_MA_BIT 0x00000080
+#define MSC01_PCI_INTCFG_TA_SHF 6
+#define MSC01_PCI_INTCFG_TA_MSK 0x00000040
+#define MSC01_PCI_INTCFG_TA_BIT 0x00000040
+#define MSC01_PCI_INTCFG_RTY_SHF 5
+#define MSC01_PCI_INTCFG_RTY_MSK 0x00000020
+#define MSC01_PCI_INTCFG_RTY_BIT 0x00000020
+#define MSC01_PCI_INTCFG_MWP_SHF 4
+#define MSC01_PCI_INTCFG_MWP_MSK 0x00000010
+#define MSC01_PCI_INTCFG_MWP_BIT 0x00000010
+#define MSC01_PCI_INTCFG_MRP_SHF 3
+#define MSC01_PCI_INTCFG_MRP_MSK 0x00000008
+#define MSC01_PCI_INTCFG_MRP_BIT 0x00000008
+#define MSC01_PCI_INTCFG_SWP_SHF 2
+#define MSC01_PCI_INTCFG_SWP_MSK 0x00000004
+#define MSC01_PCI_INTCFG_SWP_BIT 0x00000004
+#define MSC01_PCI_INTCFG_SRP_SHF 1
+#define MSC01_PCI_INTCFG_SRP_MSK 0x00000002
+#define MSC01_PCI_INTCFG_SRP_BIT 0x00000002
+#define MSC01_PCI_INTCFG_SE_SHF 0
+#define MSC01_PCI_INTCFG_SE_MSK 0x00000001
+#define MSC01_PCI_INTCFG_SE_BIT 0x00000001
-#define MSC01_PCI_INTSTAT_RST_SHF 10
-#define MSC01_PCI_INTSTAT_RST_MSK 0x00000400
-#define MSC01_PCI_INTSTAT_RST_BIT 0x00000400
-#define MSC01_PCI_INTSTAT_MWE_SHF 9
-#define MSC01_PCI_INTSTAT_MWE_MSK 0x00000200
-#define MSC01_PCI_INTSTAT_MWE_BIT 0x00000200
-#define MSC01_PCI_INTSTAT_DTO_SHF 8
-#define MSC01_PCI_INTSTAT_DTO_MSK 0x00000100
-#define MSC01_PCI_INTSTAT_DTO_BIT 0x00000100
-#define MSC01_PCI_INTSTAT_MA_SHF 7
-#define MSC01_PCI_INTSTAT_MA_MSK 0x00000080
-#define MSC01_PCI_INTSTAT_MA_BIT 0x00000080
-#define MSC01_PCI_INTSTAT_TA_SHF 6
-#define MSC01_PCI_INTSTAT_TA_MSK 0x00000040
-#define MSC01_PCI_INTSTAT_TA_BIT 0x00000040
-#define MSC01_PCI_INTSTAT_RTY_SHF 5
-#define MSC01_PCI_INTSTAT_RTY_MSK 0x00000020
-#define MSC01_PCI_INTSTAT_RTY_BIT 0x00000020
-#define MSC01_PCI_INTSTAT_MWP_SHF 4
-#define MSC01_PCI_INTSTAT_MWP_MSK 0x00000010
-#define MSC01_PCI_INTSTAT_MWP_BIT 0x00000010
-#define MSC01_PCI_INTSTAT_MRP_SHF 3
-#define MSC01_PCI_INTSTAT_MRP_MSK 0x00000008
-#define MSC01_PCI_INTSTAT_MRP_BIT 0x00000008
-#define MSC01_PCI_INTSTAT_SWP_SHF 2
-#define MSC01_PCI_INTSTAT_SWP_MSK 0x00000004
-#define MSC01_PCI_INTSTAT_SWP_BIT 0x00000004
-#define MSC01_PCI_INTSTAT_SRP_SHF 1
-#define MSC01_PCI_INTSTAT_SRP_MSK 0x00000002
-#define MSC01_PCI_INTSTAT_SRP_BIT 0x00000002
-#define MSC01_PCI_INTSTAT_SE_SHF 0
-#define MSC01_PCI_INTSTAT_SE_MSK 0x00000001
-#define MSC01_PCI_INTSTAT_SE_BIT 0x00000001
+#define MSC01_PCI_INTSTAT_RST_SHF 10
+#define MSC01_PCI_INTSTAT_RST_MSK 0x00000400
+#define MSC01_PCI_INTSTAT_RST_BIT 0x00000400
+#define MSC01_PCI_INTSTAT_MWE_SHF 9
+#define MSC01_PCI_INTSTAT_MWE_MSK 0x00000200
+#define MSC01_PCI_INTSTAT_MWE_BIT 0x00000200
+#define MSC01_PCI_INTSTAT_DTO_SHF 8
+#define MSC01_PCI_INTSTAT_DTO_MSK 0x00000100
+#define MSC01_PCI_INTSTAT_DTO_BIT 0x00000100
+#define MSC01_PCI_INTSTAT_MA_SHF 7
+#define MSC01_PCI_INTSTAT_MA_MSK 0x00000080
+#define MSC01_PCI_INTSTAT_MA_BIT 0x00000080
+#define MSC01_PCI_INTSTAT_TA_SHF 6
+#define MSC01_PCI_INTSTAT_TA_MSK 0x00000040
+#define MSC01_PCI_INTSTAT_TA_BIT 0x00000040
+#define MSC01_PCI_INTSTAT_RTY_SHF 5
+#define MSC01_PCI_INTSTAT_RTY_MSK 0x00000020
+#define MSC01_PCI_INTSTAT_RTY_BIT 0x00000020
+#define MSC01_PCI_INTSTAT_MWP_SHF 4
+#define MSC01_PCI_INTSTAT_MWP_MSK 0x00000010
+#define MSC01_PCI_INTSTAT_MWP_BIT 0x00000010
+#define MSC01_PCI_INTSTAT_MRP_SHF 3
+#define MSC01_PCI_INTSTAT_MRP_MSK 0x00000008
+#define MSC01_PCI_INTSTAT_MRP_BIT 0x00000008
+#define MSC01_PCI_INTSTAT_SWP_SHF 2
+#define MSC01_PCI_INTSTAT_SWP_MSK 0x00000004
+#define MSC01_PCI_INTSTAT_SWP_BIT 0x00000004
+#define MSC01_PCI_INTSTAT_SRP_SHF 1
+#define MSC01_PCI_INTSTAT_SRP_MSK 0x00000002
+#define MSC01_PCI_INTSTAT_SRP_BIT 0x00000002
+#define MSC01_PCI_INTSTAT_SE_SHF 0
+#define MSC01_PCI_INTSTAT_SE_MSK 0x00000001
+#define MSC01_PCI_INTSTAT_SE_BIT 0x00000001
#define MSC01_PCI_CFGADDR_BNUM_SHF 16
#define MSC01_PCI_CFGADDR_BNUM_MSK 0x00ff0000
@@ -167,29 +168,29 @@
#define MSC01_PCI_CFGDATA_DATA_MSK 0xffffffff
/* The defines below are ONLY valid for a MEM bar! */
-#define MSC01_PCI_BAR0_SIZE_SHF 4
-#define MSC01_PCI_BAR0_SIZE_MSK 0xfffffff0
-#define MSC01_PCI_BAR0_P_SHF 3
-#define MSC01_PCI_BAR0_P_MSK 0x00000008
-#define MSC01_PCI_BAR0_P_BIT MSC01_PCI_BAR0_P_MSK
-#define MSC01_PCI_BAR0_D_SHF 1
-#define MSC01_PCI_BAR0_D_MSK 0x00000006
-#define MSC01_PCI_BAR0_T_SHF 0
-#define MSC01_PCI_BAR0_T_MSK 0x00000001
-#define MSC01_PCI_BAR0_T_BIT MSC01_PCI_BAR0_T_MSK
+#define MSC01_PCI_BAR0_SIZE_SHF 4
+#define MSC01_PCI_BAR0_SIZE_MSK 0xfffffff0
+#define MSC01_PCI_BAR0_P_SHF 3
+#define MSC01_PCI_BAR0_P_MSK 0x00000008
+#define MSC01_PCI_BAR0_P_BIT MSC01_PCI_BAR0_P_MSK
+#define MSC01_PCI_BAR0_D_SHF 1
+#define MSC01_PCI_BAR0_D_MSK 0x00000006
+#define MSC01_PCI_BAR0_T_SHF 0
+#define MSC01_PCI_BAR0_T_MSK 0x00000001
+#define MSC01_PCI_BAR0_T_BIT MSC01_PCI_BAR0_T_MSK
-#define MSC01_PCI_CFG_RA_SHF 17
-#define MSC01_PCI_CFG_RA_MSK 0x00020000
-#define MSC01_PCI_CFG_RA_BIT MSC01_PCI_CFG_RA_MSK
-#define MSC01_PCI_CFG_G_SHF 16
-#define MSC01_PCI_CFG_G_MSK 0x00010000
-#define MSC01_PCI_CFG_G_BIT MSC01_PCI_CFG_G_MSK
-#define MSC01_PCI_CFG_EN_SHF 15
-#define MSC01_PCI_CFG_EN_MSK 0x00008000
-#define MSC01_PCI_CFG_EN_BIT MSC01_PCI_CFG_EN_MSK
-#define MSC01_PCI_CFG_MAXRTRY_SHF 0
-#define MSC01_PCI_CFG_MAXRTRY_MSK 0x000000ff
+#define MSC01_PCI_CFG_RA_SHF 17
+#define MSC01_PCI_CFG_RA_MSK 0x00020000
+#define MSC01_PCI_CFG_RA_BIT MSC01_PCI_CFG_RA_MSK
+#define MSC01_PCI_CFG_G_SHF 16
+#define MSC01_PCI_CFG_G_MSK 0x00010000
+#define MSC01_PCI_CFG_G_BIT MSC01_PCI_CFG_G_MSK
+#define MSC01_PCI_CFG_EN_SHF 15
+#define MSC01_PCI_CFG_EN_MSK 0x00008000
+#define MSC01_PCI_CFG_EN_BIT MSC01_PCI_CFG_EN_MSK
+#define MSC01_PCI_CFG_MAXRTRY_SHF 0
+#define MSC01_PCI_CFG_MAXRTRY_MSK 0x00000fff
#define MSC01_PCI_SWAP_IO_SHF 18
#define MSC01_PCI_SWAP_IO_MSK 0x000c0000
@@ -206,7 +207,7 @@
* FIXME - are these macros specific to Malta and co or to the MSC? If the
* latter, they should be moved elsewhere.
*/
-#define MIPS_MSC01_PCI_REG_BASE 0x1bd00000
+#define MIPS_MSC01_PCI_REG_BASE 0x1bd00000
extern unsigned long _pcictrl_msc;
@@ -219,19 +220,19 @@ extern unsigned long _pcictrl_msc;
* Registers absolute addresses
*/
-#define MSC01_PCI_ID (MSC01_PCI_REG_BASE + MSC01_PCI_ID_OFS)
-#define MSC01_PCI_SC2PMBASL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMBASL_OFS)
-#define MSC01_PCI_SC2PMMSKL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMMSKL_OFS)
-#define MSC01_PCI_SC2PMMAPL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMMAPL_OFS)
-#define MSC01_PCI_SC2PIOBASL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOBASL_OFS)
-#define MSC01_PCI_SC2PIOMSKL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOMSKL_OFS)
-#define MSC01_PCI_SC2PIOMAPL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOMAPL_OFS)
-#define MSC01_PCI_P2SCMSKL (MSC01_PCI_REG_BASE + MSC01_PCI_P2SCMSKL_OFS)
-#define MSC01_PCI_P2SCMAPL (MSC01_PCI_REG_BASE + MSC01_PCI_P2SCMAPL_OFS)
-#define MSC01_PCI_INTCFG (MSC01_PCI_REG_BASE + MSC01_PCI_INTCFG_OFS)
-#define MSC01_PCI_INTSTAT (MSC01_PCI_REG_BASE + MSC01_PCI_INTSTAT_OFS)
-#define MSC01_PCI_CFGADDR (MSC01_PCI_REG_BASE + MSC01_PCI_CFGADDR_OFS)
-#define MSC01_PCI_CFGDATA (MSC01_PCI_REG_BASE + MSC01_PCI_CFGDATA_OFS)
+#define MSC01_PCI_ID (MSC01_PCI_REG_BASE + MSC01_PCI_ID_OFS)
+#define MSC01_PCI_SC2PMBASL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMBASL_OFS)
+#define MSC01_PCI_SC2PMMSKL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMMSKL_OFS)
+#define MSC01_PCI_SC2PMMAPL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMMAPL_OFS)
+#define MSC01_PCI_SC2PIOBASL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOBASL_OFS)
+#define MSC01_PCI_SC2PIOMSKL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOMSKL_OFS)
+#define MSC01_PCI_SC2PIOMAPL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOMAPL_OFS)
+#define MSC01_PCI_P2SCMSKL (MSC01_PCI_REG_BASE + MSC01_PCI_P2SCMSKL_OFS)
+#define MSC01_PCI_P2SCMAPL (MSC01_PCI_REG_BASE + MSC01_PCI_P2SCMAPL_OFS)
+#define MSC01_PCI_INTCFG (MSC01_PCI_REG_BASE + MSC01_PCI_INTCFG_OFS)
+#define MSC01_PCI_INTSTAT (MSC01_PCI_REG_BASE + MSC01_PCI_INTSTAT_OFS)
+#define MSC01_PCI_CFGADDR (MSC01_PCI_REG_BASE + MSC01_PCI_CFGADDR_OFS)
+#define MSC01_PCI_CFGDATA (MSC01_PCI_REG_BASE + MSC01_PCI_CFGDATA_OFS)
#define MSC01_PCI_IACK (MSC01_PCI_REG_BASE + MSC01_PCI_IACK_OFS)
#define MSC01_PCI_HEAD0 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD0_OFS)
#define MSC01_PCI_HEAD1 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD1_OFS)
@@ -248,7 +249,7 @@ extern unsigned long _pcictrl_msc;
#define MSC01_PCI_HEAD12 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS)
#define MSC01_PCI_HEAD13 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS)
#define MSC01_PCI_HEAD14 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS)
-#define MSC01_PCI_HEAD15 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS)
+#define MSC01_PCI_HEAD15 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS)
#define MSC01_PCI_BAR0 (MSC01_PCI_REG_BASE + MSC01_PCI_BAR0_OFS)
#define MSC01_PCI_CFG (MSC01_PCI_REG_BASE + MSC01_PCI_CFG_OFS)
#define MSC01_PCI_SWAP (MSC01_PCI_REG_BASE + MSC01_PCI_SWAP_OFS)
diff --git a/include/asm-mips/mips-boards/sim.h b/include/asm-mips/mips-boards/sim.h
new file mode 100644
index 000000000000..acb7c2331d98
--- /dev/null
+++ b/include/asm-mips/mips-boards/sim.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _ASM_MIPS_BOARDS_SIM_H
+#define _ASM_MIPS_BOARDS_SIM_H
+
+#define STATS_ON 1
+#define STATS_OFF 2
+#define STATS_CLEAR 3
+#define STATS_DUMP 4
+#define TRACE_ON 5
+#define TRACE_OFF 6
+
+
+#define simcfg(code) \
+({ \
+ __asm__ __volatile__( \
+ "sltiu $0,$0, %0" \
+ ::"i"(code) \
+ ); \
+})
+
+
+
+#endif
diff --git a/include/asm-mips/mips-boards/simint.h b/include/asm-mips/mips-boards/simint.h
new file mode 100644
index 000000000000..4952e0b3bf11
--- /dev/null
+++ b/include/asm-mips/mips-boards/simint.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#ifndef _MIPS_SIMINT_H
+#define _MIPS_SIMINT_H
+
+
+#define SIM_INT_BASE 0
+#define MIPSCPU_INT_MB0 2
+#define MIPSCPU_INT_BASE 16
+#define MIPS_CPU_TIMER_IRQ 7
+
+
+#define MIPSCPU_INT_CPUCTR 7
+
+#define MSC01E_INT_BASE 64
+
+#define MIPSCPU_INT_CPUCTR 7
+#define MSC01E_INT_CPUCTR 11
+
+#endif
diff --git a/include/asm-mips/mipsmtregs.h b/include/asm-mips/mipsmtregs.h
new file mode 100644
index 000000000000..a669c0702c66
--- /dev/null
+++ b/include/asm-mips/mipsmtregs.h
@@ -0,0 +1,391 @@
+/*
+ * MT regs definitions, follows on from mipsregs.h
+ * Copyright (C) 2004 - 2005 MIPS Technologies, Inc. All rights reserved.
+ * Elizabeth Clarke et. al.
+ *
+ */
+#ifndef _ASM_MIPSMTREGS_H
+#define _ASM_MIPSMTREGS_H
+
+#include <asm/mipsregs.h>
+#include <asm/war.h>
+
+#ifndef __ASSEMBLY__
+
+/*
+ * C macros
+ */
+
+#define read_c0_mvpcontrol() __read_32bit_c0_register($0, 1)
+#define write_c0_mvpcontrol(val) __write_32bit_c0_register($0, 1, val)
+
+#define read_c0_mvpconf0() __read_32bit_c0_register($0, 2)
+#define read_c0_mvpconf1() __read_32bit_c0_register($0, 3)
+
+#define read_c0_vpecontrol() __read_32bit_c0_register($1, 1)
+#define write_c0_vpecontrol(val) __write_32bit_c0_register($1, 1, val)
+
+#define read_c0_vpeconf0() __read_32bit_c0_register($1, 2)
+#define write_c0_vpeconf0(val) __write_32bit_c0_register($1, 2, val)
+
+#define read_c0_tcstatus() __read_32bit_c0_register($2, 1)
+#define write_c0_tcstatus(val) __write_32bit_c0_register($2, 1, val)
+
+#define read_c0_tcbind() __read_32bit_c0_register($2, 2)
+
+#define read_c0_tccontext() __read_32bit_c0_register($2, 5)
+#define write_c0_tccontext(val) __write_32bit_c0_register($2, 5, val)
+
+#else /* Assembly */
+/*
+ * Macros for use in assembly language code
+ */
+
+#define CP0_MVPCONTROL $0,1
+#define CP0_MVPCONF0 $0,2
+#define CP0_MVPCONF1 $0,3
+#define CP0_VPECONTROL $1,1
+#define CP0_VPECONF0 $1,2
+#define CP0_VPECONF1 $1,3
+#define CP0_YQMASK $1,4
+#define CP0_VPESCHEDULE $1,5
+#define CP0_VPESCHEFBK $1,6
+#define CP0_TCSTATUS $2,1
+#define CP0_TCBIND $2,2
+#define CP0_TCRESTART $2,3
+#define CP0_TCHALT $2,4
+#define CP0_TCCONTEXT $2,5
+#define CP0_TCSCHEDULE $2,6
+#define CP0_TCSCHEFBK $2,7
+#define CP0_SRSCONF0 $6,1
+#define CP0_SRSCONF1 $6,2
+#define CP0_SRSCONF2 $6,3
+#define CP0_SRSCONF3 $6,4
+#define CP0_SRSCONF4 $6,5
+
+#endif
+
+/* MVPControl fields */
+#define MVPCONTROL_EVP (_ULCAST_(1))
+
+#define MVPCONTROL_VPC_SHIFT 1
+#define MVPCONTROL_VPC (_ULCAST_(1) << MVPCONTROL_VPC_SHIFT)
+
+#define MVPCONTROL_STLB_SHIFT 2
+#define MVPCONTROL_STLB (_ULCAST_(1) << MVPCONTROL_STLB_SHIFT)
+
+
+/* MVPConf0 fields */
+#define MVPCONF0_PTC_SHIFT 0
+#define MVPCONF0_PTC ( _ULCAST_(0xff))
+#define MVPCONF0_PVPE_SHIFT 10
+#define MVPCONF0_PVPE ( _ULCAST_(0xf) << MVPCONF0_PVPE_SHIFT)
+#define MVPCONF0_TCA_SHIFT 15
+#define MVPCONF0_TCA ( _ULCAST_(1) << MVPCONF0_TCA_SHIFT)
+#define MVPCONF0_PTLBE_SHIFT 16
+#define MVPCONF0_PTLBE (_ULCAST_(0x3ff) << MVPCONF0_PTLBE_SHIFT)
+#define MVPCONF0_TLBS_SHIFT 29
+#define MVPCONF0_TLBS (_ULCAST_(1) << MVPCONF0_TLBS_SHIFT)
+#define MVPCONF0_M_SHIFT 31
+#define MVPCONF0_M (_ULCAST_(0x1) << MVPCONF0_M_SHIFT)
+
+
+/* config3 fields */
+#define CONFIG3_MT_SHIFT 2
+#define CONFIG3_MT (_ULCAST_(1) << CONFIG3_MT_SHIFT)
+
+
+/* VPEControl fields (per VPE) */
+#define VPECONTROL_TARGTC (_ULCAST_(0xff))
+
+#define VPECONTROL_TE_SHIFT 15
+#define VPECONTROL_TE (_ULCAST_(1) << VPECONTROL_TE_SHIFT)
+#define VPECONTROL_EXCPT_SHIFT 16
+#define VPECONTROL_EXCPT (_ULCAST_(0x7) << VPECONTROL_EXCPT_SHIFT)
+
+/* Thread Exception Codes for EXCPT field */
+#define THREX_TU 0
+#define THREX_TO 1
+#define THREX_IYQ 2
+#define THREX_GSX 3
+#define THREX_YSCH 4
+#define THREX_GSSCH 5
+
+#define VPECONTROL_GSI_SHIFT 20
+#define VPECONTROL_GSI (_ULCAST_(1) << VPECONTROL_GSI_SHIFT)
+#define VPECONTROL_YSI_SHIFT 21
+#define VPECONTROL_YSI (_ULCAST_(1) << VPECONTROL_YSI_SHIFT)
+
+/* VPEConf0 fields (per VPE) */
+#define VPECONF0_VPA_SHIFT 0
+#define VPECONF0_VPA (_ULCAST_(1) << VPECONF0_VPA_SHIFT)
+#define VPECONF0_MVP_SHIFT 1
+#define VPECONF0_MVP (_ULCAST_(1) << VPECONF0_MVP_SHIFT)
+#define VPECONF0_XTC_SHIFT 21
+#define VPECONF0_XTC (_ULCAST_(0xff) << VPECONF0_XTC_SHIFT)
+
+/* TCStatus fields (per TC) */
+#define TCSTATUS_TASID (_ULCAST_(0xff))
+#define TCSTATUS_IXMT_SHIFT 10
+#define TCSTATUS_IXMT (_ULCAST_(1) << TCSTATUS_IXMT_SHIFT)
+#define TCSTATUS_TKSU_SHIFT 11
+#define TCSTATUS_TKSU (_ULCAST_(3) << TCSTATUS_TKSU_SHIFT)
+#define TCSTATUS_A_SHIFT 13
+#define TCSTATUS_A (_ULCAST_(1) << TCSTATUS_A_SHIFT)
+#define TCSTATUS_DA_SHIFT 15
+#define TCSTATUS_DA (_ULCAST_(1) << TCSTATUS_DA_SHIFT)
+#define TCSTATUS_DT_SHIFT 20
+#define TCSTATUS_DT (_ULCAST_(1) << TCSTATUS_DT_SHIFT)
+#define TCSTATUS_TDS_SHIFT 21
+#define TCSTATUS_TDS (_ULCAST_(1) << TCSTATUS_TDS_SHIFT)
+#define TCSTATUS_TSST_SHIFT 22
+#define TCSTATUS_TSST (_ULCAST_(1) << TCSTATUS_TSST_SHIFT)
+#define TCSTATUS_RNST_SHIFT 23
+#define TCSTATUS_RNST (_ULCAST_(3) << TCSTATUS_RNST_SHIFT)
+/* Codes for RNST */
+#define TC_RUNNING 0
+#define TC_WAITING 1
+#define TC_YIELDING 2
+#define TC_GATED 3
+
+#define TCSTATUS_TMX_SHIFT 27
+#define TCSTATUS_TMX (_ULCAST_(1) << TCSTATUS_TMX_SHIFT)
+/* TCStatus TCU bits can use same definitions/offsets as CU bits in Status */
+
+/* TCBind */
+#define TCBIND_CURVPE_SHIFT 0
+#define TCBIND_CURVPE (_ULCAST_(0xf))
+
+#define TCBIND_CURTC_SHIFT 21
+
+#define TCBIND_CURTC (_ULCAST_(0xff) << TCBIND_CURTC_SHIFT)
+
+/* TCHalt */
+#define TCHALT_H (_ULCAST_(1))
+
+#ifndef __ASSEMBLY__
+
+extern void mips_mt_regdump(void);
+
+static inline unsigned int dvpe(void)
+{
+ int res = 0;
+
+ __asm__ __volatile__(
+ " .set push \n"
+ " .set noreorder \n"
+ " .set noat \n"
+ " .set mips32r2 \n"
+ " .word 0x41610001 # dvpe $1 \n"
+ " move %0, $1 \n"
+ " ehb \n"
+ " .set pop \n"
+ : "=r" (res));
+
+ instruction_hazard();
+
+ return res;
+}
+
+static inline void __raw_evpe(void)
+{
+ __asm__ __volatile__(
+ " .set push \n"
+ " .set noreorder \n"
+ " .set noat \n"
+ " .set mips32r2 \n"
+ " .word 0x41600021 # evpe \n"
+ " ehb \n"
+ " .set pop \n");
+}
+
+/* Enable multiMT if previous suggested it should be.
+ EMT_ENABLE to force */
+
+#define EVPE_ENABLE MVPCONTROL_EVP
+
+static inline void evpe(int previous)
+{
+ if ((previous & MVPCONTROL_EVP))
+ __raw_evpe();
+}
+
+static inline unsigned int dmt(void)
+{
+ int res;
+
+ __asm__ __volatile__(
+ " .set push \n"
+ " .set mips32r2 \n"
+ " .set noat \n"
+ " .word 0x41610BC1 # dmt $1 \n"
+ " ehb \n"
+ " move %0, $1 \n"
+ " .set pop \n"
+ : "=r" (res));
+
+ instruction_hazard();
+
+ return res;
+}
+
+static inline void __raw_emt(void)
+{
+ __asm__ __volatile__(
+ " .set noreorder \n"
+ " .set mips32r2 \n"
+ " emt \n"
+ " ehb \n"
+ " .set mips0 \n"
+ " .set reorder");
+}
+
+/* enable multiVPE if previous suggested it should be.
+ EVPE_ENABLE to force */
+
+#define EMT_ENABLE VPECONTROL_TE
+
+static inline void emt(int previous)
+{
+ if ((previous & EMT_ENABLE))
+ __raw_emt();
+}
+
+static inline void ehb(void)
+{
+ __asm__ __volatile__(
+ " .set mips32r2 \n"
+ " ehb \n"
+ " .set mips0 \n");
+}
+
+#define mftc0(rt,sel) \
+({ \
+ unsigned long __res; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set mips32r2 \n" \
+ " .set noat \n" \
+ " # mftc0 $1, $" #rt ", " #sel " \n" \
+ " .word 0x41000800 | (" #rt " << 16) | " #sel " \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__res)); \
+ \
+ __res; \
+})
+
+#define mftgpr(rt) \
+({ \
+ unsigned long __res; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set mips32r2 \n" \
+ " mftgpr %0," #rt " \n" \
+ " .set pop \n" \
+ : "=r" (__res)); \
+ \
+ __res; \
+})
+
+#define mftr(rt,u,sel) \
+({ \
+ unsigned long __res; \
+ \
+ __asm__ __volatile__( \
+ ".set noat\n\t" \
+ "mftr\t%0, " #rt ", " #u ", " #sel "\n\t" \
+ ".set at\n\t" \
+ : "=r" (__res)); \
+ \
+ __res; \
+})
+
+#define mttgpr(rd,v) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set mips32r2 \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mttgpr $1, " #rd " \n" \
+ " .word 0x41810020 | (" #rd " << 11) \n" \
+ " .set pop \n" \
+ : : "r" (v)); \
+} while (0)
+
+#define mttc0(rd,sel,v) \
+({ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set mips32r2 \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mttc0 %0," #rd ", " #sel " \n" \
+ " .word 0x41810000 | (" #rd " << 11) | " #sel " \n" \
+ " .set pop \n" \
+ : \
+ : "r" (v)); \
+})
+
+
+#define mttr(rd,u,sel,v) \
+({ \
+ __asm__ __volatile__( \
+ "mttr %0," #rd ", " #u ", " #sel \
+ : : "r" (v)); \
+})
+
+
+#define settc(tc) \
+do { \
+ write_c0_vpecontrol((read_c0_vpecontrol()&~VPECONTROL_TARGTC) | (tc)); \
+ ehb(); \
+} while (0)
+
+
+/* you *must* set the target tc (settc) before trying to use these */
+#define read_vpe_c0_vpecontrol() mftc0(1, 1)
+#define write_vpe_c0_vpecontrol(val) mttc0(1, 1, val)
+#define read_vpe_c0_vpeconf0() mftc0(1, 2)
+#define write_vpe_c0_vpeconf0(val) mttc0(1, 2, val)
+#define read_vpe_c0_status() mftc0(12, 0)
+#define write_vpe_c0_status(val) mttc0(12, 0, val)
+#define read_vpe_c0_cause() mftc0(13, 0)
+#define write_vpe_c0_cause(val) mttc0(13, 0, val)
+#define read_vpe_c0_config() mftc0(16, 0)
+#define write_vpe_c0_config(val) mttc0(16, 0, val)
+#define read_vpe_c0_config1() mftc0(16, 1)
+#define write_vpe_c0_config1(val) mttc0(16, 1, val)
+#define read_vpe_c0_config7() mftc0(16, 7)
+#define write_vpe_c0_config7(val) mttc0(16, 7, val)
+#define read_vpe_c0_ebase() mftc0(15,1)
+#define write_vpe_c0_ebase(val) mttc0(15, 1, val)
+#define write_vpe_c0_compare(val) mttc0(11, 0, val)
+
+
+/* TC */
+#define read_tc_c0_tcstatus() mftc0(2, 1)
+#define write_tc_c0_tcstatus(val) mttc0(2,1,val)
+#define read_tc_c0_tcbind() mftc0(2, 2)
+#define write_tc_c0_tcbind(val) mttc0(2,2,val)
+#define read_tc_c0_tcrestart() mftc0(2, 3)
+#define write_tc_c0_tcrestart(val) mttc0(2,3,val)
+#define read_tc_c0_tchalt() mftc0(2, 4)
+#define write_tc_c0_tchalt(val) mttc0(2,4,val)
+#define read_tc_c0_tccontext() mftc0(2, 5)
+#define write_tc_c0_tccontext(val) mttc0(2,5,val)
+
+/* GPR */
+#define read_tc_gpr_sp() mftgpr(29)
+#define write_tc_gpr_sp(val) mttgpr(29, val)
+#define read_tc_gpr_gp() mftgpr(28)
+#define write_tc_gpr_gp(val) mttgpr(28, val)
+
+__BUILD_SET_C0(mvpcontrol)
+
+#endif /* Not __ASSEMBLY__ */
+
+#endif
diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h
index 2197aa4ce456..80370e0a5589 100644
--- a/include/asm-mips/mipsregs.h
+++ b/include/asm-mips/mipsregs.h
@@ -8,7 +8,7 @@
* Modified for further R[236]000 support by Paul M. Antoine, 1996.
* Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
* Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
- * Copyright (C) 2003 Maciej W. Rozycki
+ * Copyright (C) 2003, 2004 Maciej W. Rozycki
*/
#ifndef _ASM_MIPSREGS_H
#define _ASM_MIPSREGS_H
@@ -96,6 +96,16 @@
#define CP0_S1_INTCONTROL $20
/*
+ * Coprocessor 0 Set 2 register names
+ */
+#define CP0_S2_SRSCTL $12 /* MIPSR2 */
+
+/*
+ * Coprocessor 0 Set 3 register names
+ */
+#define CP0_S3_SRSMAP $12 /* MIPSR2 */
+
+/*
* TX39 Series
*/
#define CP0_TX39_CACHE $7
@@ -281,6 +291,11 @@
#define ST0_DL (_ULCAST_(1) << 24)
/*
+ * Enable the MIPS DSP ASE
+ */
+#define ST0_MX 0x01000000
+
+/*
* Bitfields in the TX39 family CP0 Configuration Register 3
*/
#define TX39_CONF_ICS_SHIFT 19
@@ -433,6 +448,14 @@
#define R5K_CONF_SE (_ULCAST_(1) << 12)
#define R5K_CONF_SS (_ULCAST_(3) << 20)
+/* Bits specific to the RM7000. */
+#define RM7K_CONF_SE (_ULCAST_(1) << 3)
+#define RM7K_CONF_TE (_ULCAST_(1) << 12)
+#define RM7K_CONF_CLK (_ULCAST_(1) << 16)
+#define RM7K_CONF_TC (_ULCAST_(1) << 17)
+#define RM7K_CONF_SI (_ULCAST_(3) << 20)
+#define RM7K_CONF_SC (_ULCAST_(1) << 31)
+
/* Bits specific to the R10000. */
#define R10K_CONF_DN (_ULCAST_(3) << 3)
#define R10K_CONF_CT (_ULCAST_(1) << 5)
@@ -475,6 +498,53 @@
#define MIPS_CONF_M (_ULCAST_(1) << 31)
/*
+ * Bits in the MIPS32/64 PRA coprocessor 0 config registers 1 and above.
+ */
+#define MIPS_CONF1_FP (_ULCAST_(1) << 0)
+#define MIPS_CONF1_EP (_ULCAST_(1) << 1)
+#define MIPS_CONF1_CA (_ULCAST_(1) << 2)
+#define MIPS_CONF1_WR (_ULCAST_(1) << 3)
+#define MIPS_CONF1_PC (_ULCAST_(1) << 4)
+#define MIPS_CONF1_MD (_ULCAST_(1) << 5)
+#define MIPS_CONF1_C2 (_ULCAST_(1) << 6)
+#define MIPS_CONF1_DA (_ULCAST_(7) << 7)
+#define MIPS_CONF1_DL (_ULCAST_(7) << 10)
+#define MIPS_CONF1_DS (_ULCAST_(7) << 13)
+#define MIPS_CONF1_IA (_ULCAST_(7) << 16)
+#define MIPS_CONF1_IL (_ULCAST_(7) << 19)
+#define MIPS_CONF1_IS (_ULCAST_(7) << 22)
+#define MIPS_CONF1_TLBS (_ULCAST_(63)<< 25)
+
+#define MIPS_CONF2_SA (_ULCAST_(15)<< 0)
+#define MIPS_CONF2_SL (_ULCAST_(15)<< 4)
+#define MIPS_CONF2_SS (_ULCAST_(15)<< 8)
+#define MIPS_CONF2_SU (_ULCAST_(15)<< 12)
+#define MIPS_CONF2_TA (_ULCAST_(15)<< 16)
+#define MIPS_CONF2_TL (_ULCAST_(15)<< 20)
+#define MIPS_CONF2_TS (_ULCAST_(15)<< 24)
+#define MIPS_CONF2_TU (_ULCAST_(7) << 28)
+
+#define MIPS_CONF3_TL (_ULCAST_(1) << 0)
+#define MIPS_CONF3_SM (_ULCAST_(1) << 1)
+#define MIPS_CONF3_MT (_ULCAST_(1) << 2)
+#define MIPS_CONF3_SP (_ULCAST_(1) << 4)
+#define MIPS_CONF3_VINT (_ULCAST_(1) << 5)
+#define MIPS_CONF3_VEIC (_ULCAST_(1) << 6)
+#define MIPS_CONF3_LPA (_ULCAST_(1) << 7)
+#define MIPS_CONF3_DSP (_ULCAST_(1) << 10)
+
+/*
+ * Bits in the MIPS32/64 coprocessor 1 (FPU) revision register.
+ */
+#define MIPS_FPIR_S (_ULCAST_(1) << 16)
+#define MIPS_FPIR_D (_ULCAST_(1) << 17)
+#define MIPS_FPIR_PS (_ULCAST_(1) << 18)
+#define MIPS_FPIR_3D (_ULCAST_(1) << 19)
+#define MIPS_FPIR_W (_ULCAST_(1) << 20)
+#define MIPS_FPIR_L (_ULCAST_(1) << 21)
+#define MIPS_FPIR_F64 (_ULCAST_(1) << 22)
+
+/*
* R10000 performance counter definitions.
*
* FIXME: The R10000 performance counter opens a nice way to implement CPU
@@ -621,13 +691,13 @@ do { \
if (sel == 0) \
__asm__ __volatile__( \
"mtc0\t%z0, " #register "\n\t" \
- : : "Jr" ((unsigned int)value)); \
+ : : "Jr" ((unsigned int)(value))); \
else \
__asm__ __volatile__( \
".set\tmips32\n\t" \
"mtc0\t%z0, " #register ", " #sel "\n\t" \
".set\tmips0" \
- : : "Jr" ((unsigned int)value)); \
+ : : "Jr" ((unsigned int)(value))); \
} while (0)
#define __write_64bit_c0_register(register, sel, value) \
@@ -676,7 +746,7 @@ do { \
do { \
__asm__ __volatile__( \
"ctc0\t%z0, " #register "\n\t" \
- : : "Jr" ((unsigned int)value)); \
+ : : "Jr" ((unsigned int)(value))); \
} while (0)
/*
@@ -769,12 +839,24 @@ do { \
#define read_c0_count() __read_32bit_c0_register($9, 0)
#define write_c0_count(val) __write_32bit_c0_register($9, 0, val)
+#define read_c0_count2() __read_32bit_c0_register($9, 6) /* pnx8550 */
+#define write_c0_count2(val) __write_32bit_c0_register($9, 6, val)
+
+#define read_c0_count3() __read_32bit_c0_register($9, 7) /* pnx8550 */
+#define write_c0_count3(val) __write_32bit_c0_register($9, 7, val)
+
#define read_c0_entryhi() __read_ulong_c0_register($10, 0)
#define write_c0_entryhi(val) __write_ulong_c0_register($10, 0, val)
#define read_c0_compare() __read_32bit_c0_register($11, 0)
#define write_c0_compare(val) __write_32bit_c0_register($11, 0, val)
+#define read_c0_compare2() __read_32bit_c0_register($11, 6) /* pnx8550 */
+#define write_c0_compare2(val) __write_32bit_c0_register($11, 6, val)
+
+#define read_c0_compare3() __read_32bit_c0_register($11, 7) /* pnx8550 */
+#define write_c0_compare3(val) __write_32bit_c0_register($11, 7, val)
+
#define read_c0_status() __read_32bit_c0_register($12, 0)
#define write_c0_status(val) __write_32bit_c0_register($12, 0, val)
@@ -790,10 +872,18 @@ do { \
#define read_c0_config1() __read_32bit_c0_register($16, 1)
#define read_c0_config2() __read_32bit_c0_register($16, 2)
#define read_c0_config3() __read_32bit_c0_register($16, 3)
+#define read_c0_config4() __read_32bit_c0_register($16, 4)
+#define read_c0_config5() __read_32bit_c0_register($16, 5)
+#define read_c0_config6() __read_32bit_c0_register($16, 6)
+#define read_c0_config7() __read_32bit_c0_register($16, 7)
#define write_c0_config(val) __write_32bit_c0_register($16, 0, val)
#define write_c0_config1(val) __write_32bit_c0_register($16, 1, val)
#define write_c0_config2(val) __write_32bit_c0_register($16, 2, val)
#define write_c0_config3(val) __write_32bit_c0_register($16, 3, val)
+#define write_c0_config4(val) __write_32bit_c0_register($16, 4, val)
+#define write_c0_config5(val) __write_32bit_c0_register($16, 5, val)
+#define write_c0_config6(val) __write_32bit_c0_register($16, 6, val)
+#define write_c0_config7(val) __write_32bit_c0_register($16, 7, val)
/*
* The WatchLo register. There may be upto 8 of them.
@@ -917,6 +1007,22 @@ do { \
#define read_c0_errorepc() __read_ulong_c0_register($30, 0)
#define write_c0_errorepc(val) __write_ulong_c0_register($30, 0, val)
+/* MIPSR2 */
+#define read_c0_hwrena() __read_32bit_c0_register($7,0)
+#define write_c0_hwrena(val) __write_32bit_c0_register($7, 0, val)
+
+#define read_c0_intctl() __read_32bit_c0_register($12, 1)
+#define write_c0_intctl(val) __write_32bit_c0_register($12, 1, val)
+
+#define read_c0_srsctl() __read_32bit_c0_register($12, 2)
+#define write_c0_srsctl(val) __write_32bit_c0_register($12, 2, val)
+
+#define read_c0_srsmap() __read_32bit_c0_register($12, 3)
+#define write_c0_srsmap(val) __write_32bit_c0_register($12, 3, val)
+
+#define read_c0_ebase() __read_32bit_c0_register($15,1)
+#define write_c0_ebase(val) __write_32bit_c0_register($15, 1, val)
+
/*
* Macros to access the floating point coprocessor control registers
*/
@@ -930,6 +1036,284 @@ do { \
: "=r" (__res)); \
__res;})
+#define rddsp(mask) \
+({ \
+ unsigned int __res; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # rddsp $1, %x1 \n" \
+ " .word 0x7c000cb8 | (%x1 << 16) \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__res) \
+ : "i" (mask)); \
+ __res; \
+})
+
+#define wrdsp(val, mask) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # wrdsp $1, %x1 \n" \
+ " .word 0x7c2004f8 | (%x1 << 15) \n" \
+ " .set pop \n" \
+ : \
+ : "r" (val), "i" (mask)); \
+} while (0)
+
+#if 0 /* Need DSP ASE capable assembler ... */
+#define mflo0() ({ long mflo0; __asm__("mflo %0, $ac0" : "=r" (mflo0)); mflo0;})
+#define mflo1() ({ long mflo1; __asm__("mflo %0, $ac1" : "=r" (mflo1)); mflo1;})
+#define mflo2() ({ long mflo2; __asm__("mflo %0, $ac2" : "=r" (mflo2)); mflo2;})
+#define mflo3() ({ long mflo3; __asm__("mflo %0, $ac3" : "=r" (mflo3)); mflo3;})
+
+#define mfhi0() ({ long mfhi0; __asm__("mfhi %0, $ac0" : "=r" (mfhi0)); mfhi0;})
+#define mfhi1() ({ long mfhi1; __asm__("mfhi %0, $ac1" : "=r" (mfhi1)); mfhi1;})
+#define mfhi2() ({ long mfhi2; __asm__("mfhi %0, $ac2" : "=r" (mfhi2)); mfhi2;})
+#define mfhi3() ({ long mfhi3; __asm__("mfhi %0, $ac3" : "=r" (mfhi3)); mfhi3;})
+
+#define mtlo0(x) __asm__("mtlo %0, $ac0" ::"r" (x))
+#define mtlo1(x) __asm__("mtlo %0, $ac1" ::"r" (x))
+#define mtlo2(x) __asm__("mtlo %0, $ac2" ::"r" (x))
+#define mtlo3(x) __asm__("mtlo %0, $ac3" ::"r" (x))
+
+#define mthi0(x) __asm__("mthi %0, $ac0" ::"r" (x))
+#define mthi1(x) __asm__("mthi %0, $ac1" ::"r" (x))
+#define mthi2(x) __asm__("mthi %0, $ac2" ::"r" (x))
+#define mthi3(x) __asm__("mthi %0, $ac3" ::"r" (x))
+
+#else
+
+#define mfhi0() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mfhi %0, $ac0 \n" \
+ " .word 0x00000810 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mfhi1() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mfhi %0, $ac1 \n" \
+ " .word 0x00200810 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mfhi2() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mfhi %0, $ac2 \n" \
+ " .word 0x00400810 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mfhi3() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mfhi %0, $ac3 \n" \
+ " .word 0x00600810 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mflo0() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mflo %0, $ac0 \n" \
+ " .word 0x00000812 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mflo1() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mflo %0, $ac1 \n" \
+ " .word 0x00200812 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mflo2() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mflo %0, $ac2 \n" \
+ " .word 0x00400812 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mflo3() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mflo %0, $ac3 \n" \
+ " .word 0x00600812 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mthi0(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mthi $1, $ac0 \n" \
+ " .word 0x00200011 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#define mthi1(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mthi $1, $ac1 \n" \
+ " .word 0x00200811 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#define mthi2(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mthi $1, $ac2 \n" \
+ " .word 0x00201011 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#define mthi3(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mthi $1, $ac3 \n" \
+ " .word 0x00201811 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#define mtlo0(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mtlo $1, $ac0 \n" \
+ " .word 0x00200013 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#define mtlo1(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mtlo $1, $ac1 \n" \
+ " .word 0x00200813 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#define mtlo2(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mtlo $1, $ac2 \n" \
+ " .word 0x00201013 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#define mtlo3(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mtlo $1, $ac3 \n" \
+ " .word 0x00201813 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#endif
+
/*
* TLB operations.
*
@@ -1012,6 +1396,8 @@ __BUILD_SET_C0(status)
__BUILD_SET_C0(cause)
__BUILD_SET_C0(config)
__BUILD_SET_C0(intcontrol)
+__BUILD_SET_C0(intctl)
+__BUILD_SET_C0(srsmap)
#endif /* !__ASSEMBLY__ */
diff --git a/include/asm-mips/mmu_context.h b/include/asm-mips/mmu_context.h
index 45cd72d172e8..19cdf7642e66 100644
--- a/include/asm-mips/mmu_context.h
+++ b/include/asm-mips/mmu_context.h
@@ -30,7 +30,7 @@ extern unsigned long pgd_current[];
#ifdef CONFIG_32BIT
#define TLBMISS_HANDLER_SETUP() \
- write_c0_context((unsigned long) smp_processor_id() << 23); \
+ write_c0_context((unsigned long) smp_processor_id() << 25); \
TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
#endif
#if defined(CONFIG_64BIT) && !defined(CONFIG_BUILD_ELF64)
@@ -40,7 +40,7 @@ extern unsigned long pgd_current[];
#endif
#if defined(CONFIG_64BIT) && defined(CONFIG_BUILD_ELF64)
#define TLBMISS_HANDLER_SETUP() \
- write_c0_context((unsigned long) smp_processor_id() << 23); \
+ write_c0_context((unsigned long) smp_processor_id() << 26); \
TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
#endif
diff --git a/include/asm-mips/mmzone.h b/include/asm-mips/mmzone.h
index d721143dbd47..011caebac369 100644
--- a/include/asm-mips/mmzone.h
+++ b/include/asm-mips/mmzone.h
@@ -5,6 +5,7 @@
#ifndef _ASM_MMZONE_H_
#define _ASM_MMZONE_H_
+#include <linux/config.h>
#include <asm/page.h>
#include <mmzone.h>
diff --git a/include/asm-mips/module.h b/include/asm-mips/module.h
index 0be58b2aeb9f..2be399311eec 100644
--- a/include/asm-mips/module.h
+++ b/include/asm-mips/module.h
@@ -14,15 +14,23 @@ struct mod_arch_specific {
typedef uint8_t Elf64_Byte; /* Type for a 8-bit quantity. */
-typedef struct
-{
- Elf64_Addr r_offset; /* Address of relocation. */
- Elf64_Word r_sym; /* Symbol index. */
- Elf64_Byte r_ssym; /* Special symbol. */
- Elf64_Byte r_type3; /* Third relocation. */
- Elf64_Byte r_type2; /* Second relocation. */
- Elf64_Byte r_type; /* First relocation. */
- Elf64_Sxword r_addend; /* Addend. */
+typedef struct {
+ Elf64_Addr r_offset; /* Address of relocation. */
+ Elf64_Word r_sym; /* Symbol index. */
+ Elf64_Byte r_ssym; /* Special symbol. */
+ Elf64_Byte r_type3; /* Third relocation. */
+ Elf64_Byte r_type2; /* Second relocation. */
+ Elf64_Byte r_type; /* First relocation. */
+} Elf64_Mips_Rel;
+
+typedef struct {
+ Elf64_Addr r_offset; /* Address of relocation. */
+ Elf64_Word r_sym; /* Symbol index. */
+ Elf64_Byte r_ssym; /* Special symbol. */
+ Elf64_Byte r_type3; /* Third relocation. */
+ Elf64_Byte r_type2; /* Second relocation. */
+ Elf64_Byte r_type; /* First relocation. */
+ Elf64_Sxword r_addend; /* Addend. */
} Elf64_Mips_Rela;
#ifdef CONFIG_32BIT
@@ -30,6 +38,13 @@ typedef struct
#define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym
#define Elf_Ehdr Elf32_Ehdr
+#define Elf_Addr Elf32_Addr
+
+#define Elf_Mips_Rel Elf32_Rel
+#define Elf_Mips_Rela Elf32_Rela
+
+#define ELF_MIPS_R_SYM(rel) ELF32_R_SYM(rel.r_info)
+#define ELF_MIPS_R_TYPE(rel) ELF32_R_TYPE(rel.r_info)
#endif
@@ -38,6 +53,13 @@ typedef struct
#define Elf_Shdr Elf64_Shdr
#define Elf_Sym Elf64_Sym
#define Elf_Ehdr Elf64_Ehdr
+#define Elf_Addr Elf64_Addr
+
+#define Elf_Mips_Rel Elf64_Mips_Rel
+#define Elf_Mips_Rela Elf64_Mips_Rela
+
+#define ELF_MIPS_R_SYM(rel) (rel.r_sym)
+#define ELF_MIPS_R_TYPE(rel) (rel.r_type)
#endif
@@ -53,4 +75,54 @@ search_module_dbetables(unsigned long addr)
}
#endif
+#ifdef CONFIG_CPU_MIPS32_R1
+#define MODULE_PROC_FAMILY "MIPS32_R1"
+#elif defined CONFIG_CPU_MIPS32_R2
+#define MODULE_PROC_FAMILY "MIPS32_R2"
+#elif defined CONFIG_CPU_MIPS64_R1
+#define MODULE_PROC_FAMILY "MIPS64_R1"
+#elif defined CONFIG_CPU_MIPS64_R2
+#define MODULE_PROC_FAMILY "MIPS64_R2"
+#elif defined CONFIG_CPU_R3000
+#define MODULE_PROC_FAMILY "R3000"
+#elif defined CONFIG_CPU_TX39XX
+#define MODULE_PROC_FAMILY "TX39XX"
+#elif defined CONFIG_CPU_VR41XX
+#define MODULE_PROC_FAMILY "VR41XX"
+#elif defined CONFIG_CPU_R4300
+#define MODULE_PROC_FAMILY "R4300"
+#elif defined CONFIG_CPU_R4X00
+#define MODULE_PROC_FAMILY "R4X00"
+#elif defined CONFIG_CPU_TX49XX
+#define MODULE_PROC_FAMILY "TX49XX"
+#elif defined CONFIG_CPU_R5000
+#define MODULE_PROC_FAMILY "R5000"
+#elif defined CONFIG_CPU_R5432
+#define MODULE_PROC_FAMILY "R5432"
+#elif defined CONFIG_CPU_R6000
+#define MODULE_PROC_FAMILY "R6000"
+#elif defined CONFIG_CPU_NEVADA
+#define MODULE_PROC_FAMILY "NEVADA"
+#elif defined CONFIG_CPU_R8000
+#define MODULE_PROC_FAMILY "R8000"
+#elif defined CONFIG_CPU_R10000
+#define MODULE_PROC_FAMILY "R10000"
+#elif defined CONFIG_CPU_RM7000
+#define MODULE_PROC_FAMILY "RM7000"
+#elif defined CONFIG_CPU_RM9000
+#define MODULE_PROC_FAMILY "RM9000"
+#elif defined CONFIG_CPU_SB1
+#define MODULE_PROC_FAMILY "SB1"
+#else
+#error MODULE_PROC_FAMILY undefined for your processor configuration
+#endif
+
+#ifdef CONFIG_32BIT
+#define MODULE_KERNEL_TYPE "32BIT "
+#elif defined CONFIG_64BIT
+#define MODULE_KERNEL_TYPE "64BIT "
+#endif
+
+#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_KERNEL_TYPE
+
#endif /* _ASM_MODULE_H */
diff --git a/include/asm-mips/paccess.h b/include/asm-mips/paccess.h
index 309bc3099f68..46f2d23d2697 100644
--- a/include/asm-mips/paccess.h
+++ b/include/asm-mips/paccess.h
@@ -52,7 +52,7 @@ struct __large_pstruct { unsigned long buf[100]; };
})
#define __get_dbe_asm(insn) \
-({ \
+{ \
__asm__ __volatile__( \
"1:\t" insn "\t%1,%2\n\t" \
"move\t%0,$0\n" \
@@ -67,7 +67,7 @@ struct __large_pstruct { unsigned long buf[100]; };
".previous" \
:"=r" (__gu_err), "=r" (__gu_val) \
:"o" (__mp(__gu_addr)), "i" (-EFAULT)); \
-})
+}
extern void __get_dbe_unknown(void);
@@ -90,7 +90,7 @@ extern void __get_dbe_unknown(void);
})
#define __put_dbe_asm(insn) \
-({ \
+{ \
__asm__ __volatile__( \
"1:\t" insn "\t%1,%2\n\t" \
"move\t%0,$0\n" \
@@ -104,7 +104,7 @@ extern void __get_dbe_unknown(void);
".previous" \
: "=r" (__pu_err) \
: "r" (__pu_val), "o" (__mp(__pu_addr)), "i" (-EFAULT)); \
-})
+}
extern void __put_dbe_unknown(void);
diff --git a/include/asm-mips/page.h b/include/asm-mips/page.h
index 652b6d67a571..ee25a779bf49 100644
--- a/include/asm-mips/page.h
+++ b/include/asm-mips/page.h
@@ -87,22 +87,48 @@ static inline void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
typedef struct { unsigned long pte; } pte_t;
#define pte_val(x) ((x).pte)
#endif
+#define __pte(x) ((pte_t) { (x) } )
-typedef struct { unsigned long pmd; } pmd_t;
-typedef struct { unsigned long pgd; } pgd_t;
-typedef struct { unsigned long pgprot; } pgprot_t;
+/*
+ * For 3-level pagetables we defines these ourselves, for 2-level the
+ * definitions are supplied by <asm-generic/pgtable-nopmd.h>.
+ */
+#ifdef CONFIG_64BIT
+typedef struct { unsigned long pmd; } pmd_t;
#define pmd_val(x) ((x).pmd)
-#define pgd_val(x) ((x).pgd)
-#define pgprot_val(x) ((x).pgprot)
+#define __pmd(x) ((pmd_t) { (x) } )
-#define ptep_buddy(x) ((pte_t *)((unsigned long)(x) ^ sizeof(pte_t)))
+#endif
-#define __pte(x) ((pte_t) { (x) } )
-#define __pmd(x) ((pmd_t) { (x) } )
+/*
+ * Right now we don't support 4-level pagetables, so all pud-related
+ * definitions come from <asm-generic/pgtable-nopud.h>.
+ */
+
+/*
+ * Finall the top of the hierarchy, the pgd
+ */
+typedef struct { unsigned long pgd; } pgd_t;
+#define pgd_val(x) ((x).pgd)
#define __pgd(x) ((pgd_t) { (x) } )
+
+/*
+ * Manipulate page protection bits
+ */
+typedef struct { unsigned long pgprot; } pgprot_t;
+#define pgprot_val(x) ((x).pgprot)
#define __pgprot(x) ((pgprot_t) { (x) } )
+/*
+ * On R4000-style MMUs where a TLB entry is mapping a adjacent even / odd
+ * pair of pages we only have a single global bit per pair of pages. When
+ * writing to the TLB make sure we always have the bit set for both pages
+ * or none. This macro is used to access the `buddy' of the pte we're just
+ * working on.
+ */
+#define ptep_buddy(x) ((pte_t *)((unsigned long)(x) ^ sizeof(pte_t)))
+
#endif /* !__ASSEMBLY__ */
/* to align the pointer to the (next) page boundary */
diff --git a/include/asm-mips/pci.h b/include/asm-mips/pci.h
index c9a00ca1c012..6c9ad8171a77 100644
--- a/include/asm-mips/pci.h
+++ b/include/asm-mips/pci.h
@@ -40,6 +40,11 @@ struct pci_controller {
unsigned int need_domain_info;
int iommu;
+
+ /* Optional access methods for reading/writing the bus number
+ of the PCI controller */
+ int (*get_busno)(void);
+ void (*set_busno)(int busno);
};
/*
@@ -142,8 +147,22 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
extern void pcibios_resource_to_bus(struct pci_dev *dev,
struct pci_bus_region *region, struct resource *res);
-extern void pcibios_bus_to_resource(struct pci_dev *dev,
- struct resource *res, struct pci_bus_region *region);
+
+extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+ struct pci_bus_region *region);
+
+static inline struct resource *
+pcibios_select_root(struct pci_dev *pdev, struct resource *res)
+{
+ struct resource *root = NULL;
+
+ if (res->flags & IORESOURCE_IO)
+ root = &ioport_resource;
+ if (res->flags & IORESOURCE_MEM)
+ root = &iomem_resource;
+
+ return root;
+}
#ifdef CONFIG_PCI_DOMAINS
@@ -169,17 +188,4 @@ static inline void pcibios_add_platform_entries(struct pci_dev *dev)
/* Do platform specific device initialization at pci_enable_device() time */
extern int pcibios_plat_dev_init(struct pci_dev *dev);
-static inline struct resource *
-pcibios_select_root(struct pci_dev *pdev, struct resource *res)
-{
- struct resource *root = NULL;
-
- if (res->flags & IORESOURCE_IO)
- root = &ioport_resource;
- if (res->flags & IORESOURCE_MEM)
- root = &iomem_resource;
-
- return root;
-}
-
#endif /* _ASM_PCI_H */
diff --git a/include/asm-mips/pgalloc.h b/include/asm-mips/pgalloc.h
index ce57288d43bd..fe1df572318b 100644
--- a/include/asm-mips/pgalloc.h
+++ b/include/asm-mips/pgalloc.h
@@ -26,10 +26,22 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
}
/*
+ * Initialize a new pmd table with invalid pointers.
+ */
+extern void pmd_init(unsigned long page, unsigned long pagetable);
+
+#ifdef CONFIG_64BIT
+
+static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
+{
+ set_pud(pud, __pud((unsigned long)pmd));
+}
+#endif
+
+/*
* Initialize a new pgd / pmd table with invalid pointers.
*/
extern void pgd_init(unsigned long page);
-extern void pmd_init(unsigned long page, unsigned long pagetable);
static inline pgd_t *pgd_alloc(struct mm_struct *mm)
{
@@ -86,21 +98,18 @@ static inline void pte_free(struct page *pte)
#define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte))
#ifdef CONFIG_32BIT
-#define pgd_populate(mm, pmd, pte) BUG()
/*
* allocating and freeing a pmd is trivial: the 1-entry pmd is
* inside the pgd, so has no extra memory associated with it.
*/
-#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); })
#define pmd_free(x) do { } while (0)
#define __pmd_free_tlb(tlb,x) do { } while (0)
+
#endif
#ifdef CONFIG_64BIT
-#define pgd_populate(mm, pgd, pmd) set_pgd(pgd, __pgd(pmd))
-
static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
{
pmd_t *pmd;
diff --git a/include/asm-mips/pgtable-32.h b/include/asm-mips/pgtable-32.h
index 7fec93b76da9..0cff64ce0fb8 100644
--- a/include/asm-mips/pgtable-32.h
+++ b/include/asm-mips/pgtable-32.h
@@ -17,6 +17,8 @@
#include <asm/cachectl.h>
#include <asm/fixmap.h>
+#include <asm-generic/pgtable-nopmd.h>
+
/*
* - add_wired_entry() add a fixed TLB entry, and move wired register
*/
@@ -41,42 +43,38 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
* works even with the cache aliasing problem the R4k and above have.
*/
-/* PMD_SHIFT determines the size of the area a second-level page table can map */
+/* PGDIR_SHIFT determines what a third-level page table entry can map */
#ifdef CONFIG_64BIT_PHYS_ADDR
-#define PMD_SHIFT 21
+#define PGDIR_SHIFT 21
#else
-#define PMD_SHIFT 22
+#define PGDIR_SHIFT 22
#endif
-#define PMD_SIZE (1UL << PMD_SHIFT)
-#define PMD_MASK (~(PMD_SIZE-1))
-
-/* PGDIR_SHIFT determines what a third-level page table entry can map */
-#define PGDIR_SHIFT PMD_SHIFT
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
#define PGDIR_MASK (~(PGDIR_SIZE-1))
/*
* Entries per page directory level: we use two-level, so
- * we don't really have any PMD directory physically.
+ * we don't really have any PUD/PMD directory physically.
*/
#ifdef CONFIG_64BIT_PHYS_ADDR
#define PGD_ORDER 1
-#define PMD_ORDER 0
+#define PUD_ORDER aieeee_attempt_to_allocate_pud
+#define PMD_ORDER 1
#define PTE_ORDER 0
#else
#define PGD_ORDER 0
-#define PMD_ORDER 0
+#define PUD_ORDER aieeee_attempt_to_allocate_pud
+#define PMD_ORDER 1
#define PTE_ORDER 0
#endif
#define PTRS_PER_PGD ((PAGE_SIZE << PGD_ORDER) / sizeof(pgd_t))
-#define PTRS_PER_PMD 1
#define PTRS_PER_PTE ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t))
#define USER_PTRS_PER_PGD (0x80000000UL/PGDIR_SIZE)
#define FIRST_USER_ADDRESS 0
-#define VMALLOC_START KSEG2
+#define VMALLOC_START MAP_BASE
#ifdef CONFIG_HIGHMEM
# define VMALLOC_END (PKMAP_BASE-2*PAGE_SIZE)
@@ -91,8 +89,6 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
#define pte_ERROR(e) \
printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
#endif
-#define pmd_ERROR(e) \
- printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
#define pgd_ERROR(e) \
printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
@@ -120,17 +116,7 @@ static inline void pmd_clear(pmd_t *pmdp)
pmd_val(*pmdp) = ((unsigned long) invalid_pte_table);
}
-/*
- * The "pgd_xxx()" functions here are trivial for a folded two-level
- * setup: the pgd is never bad, and a pmd always exists (as it's folded
- * into the pgd entry)
- */
-static inline int pgd_none(pgd_t pgd) { return 0; }
-static inline int pgd_bad(pgd_t pgd) { return 0; }
-static inline int pgd_present(pgd_t pgd) { return 1; }
-static inline void pgd_clear(pgd_t *pgdp) { }
-
-#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
#define pte_page(x) pfn_to_page(pte_pfn(x))
#define pte_pfn(x) ((unsigned long)((x).pte_high >> 6))
static inline pte_t
@@ -151,27 +137,22 @@ pfn_pte(unsigned long pfn, pgprot_t prot)
#define pfn_pte(pfn, prot) __pte(((pfn) << (PAGE_SHIFT + 2)) | pgprot_val(prot))
#else
#define pte_pfn(x) ((unsigned long)((x).pte >> PAGE_SHIFT))
-#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
+#define pfn_pte(pfn, prot) __pte(((unsigned long long)(pfn) << PAGE_SHIFT) | pgprot_val(prot))
#endif
-#endif /* defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) */
+#endif /* defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1) */
#define __pgd_offset(address) pgd_index(address)
+#define __pud_offset(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
#define __pmd_offset(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
/* to find an entry in a kernel page-table-directory */
#define pgd_offset_k(address) pgd_offset(&init_mm, address)
-#define pgd_index(address) ((address) >> PGDIR_SHIFT)
+#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
/* to find an entry in a page-table-directory */
#define pgd_offset(mm,addr) ((mm)->pgd + pgd_index(addr))
-/* Find an entry in the second-level page table.. */
-static inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address)
-{
- return (pmd_t *) dir;
-}
-
/* Find an entry in the third-level page table.. */
#define __pte_offset(address) \
(((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
@@ -221,7 +202,7 @@ static inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address)
*/
#define PTE_FILE_MAX_BITS 27
-#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
/* fixme */
#define pte_to_pgoff(_pte) (((_pte).pte_high >> 6) + ((_pte).pte_high & 0x3f))
#define pgoff_to_pte(off) \
diff --git a/include/asm-mips/pgtable-64.h b/include/asm-mips/pgtable-64.h
index 1011e0635f56..82166b254b27 100644
--- a/include/asm-mips/pgtable-64.h
+++ b/include/asm-mips/pgtable-64.h
@@ -16,13 +16,15 @@
#include <asm/page.h>
#include <asm/cachectl.h>
+#include <asm-generic/pgtable-nopud.h>
+
/*
* Each address space has 2 4K pages as its page directory, giving 1024
* (== PTRS_PER_PGD) 8 byte pointers to pmd tables. Each pmd table is a
- * pair of 4K pages, giving 1024 (== PTRS_PER_PMD) 8 byte pointers to
- * page tables. Each page table is a single 4K page, giving 512 (==
- * PTRS_PER_PTE) 8 byte ptes. Each pgde is initialized to point to
- * invalid_pmd_table, each pmde is initialized to point to
+ * single 4K page, giving 512 (== PTRS_PER_PMD) 8 byte pointers to page
+ * tables. Each page table is also a single 4K page, giving 512 (==
+ * PTRS_PER_PTE) 8 byte ptes. Each pud entry is initialized to point to
+ * invalid_pmd_table, each pmd entry is initialized to point to
* invalid_pte_table, each pte is initialized to 0. When memory is low,
* and a pmd table or a page table allocation fails, empty_bad_pmd_table
* and empty_bad_page_table is returned back to higher layer code, so
@@ -36,17 +38,17 @@
*/
/* PMD_SHIFT determines the size of the area a second-level page table can map */
-#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT - 3))
+#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT + PTE_ORDER - 3))
#define PMD_SIZE (1UL << PMD_SHIFT)
#define PMD_MASK (~(PMD_SIZE-1))
/* PGDIR_SHIFT determines what a third-level page table entry can map */
-#define PGDIR_SHIFT (PMD_SHIFT + (PAGE_SHIFT + 1 - 3))
+#define PGDIR_SHIFT (PMD_SHIFT + (PAGE_SHIFT + PMD_ORDER - 3))
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
#define PGDIR_MASK (~(PGDIR_SIZE-1))
/*
- * For 4kB page size we use a 3 level page tree and a 8kB pmd and pgds which
+ * For 4kB page size we use a 3 level page tree and an 8kB pud, which
* permits us mapping 40 bits of virtual address space.
*
* We used to implement 41 bits by having an order 1 pmd level but that seemed
@@ -57,7 +59,7 @@
* two levels would be easy to implement.
*
* For 16kB page size we use a 2 level page tree which permits a total of
- * 36 bits of virtual address space. We could add a third leve. but it seems
+ * 36 bits of virtual address space. We could add a third level but it seems
* like at the moment there's no need for this.
*
* For 64kB page size we use a 2 level page table tree for a total of 42 bits
@@ -65,21 +67,25 @@
*/
#ifdef CONFIG_PAGE_SIZE_4KB
#define PGD_ORDER 1
+#define PUD_ORDER aieeee_attempt_to_allocate_pud
#define PMD_ORDER 0
#define PTE_ORDER 0
#endif
#ifdef CONFIG_PAGE_SIZE_8KB
#define PGD_ORDER 0
+#define PUD_ORDER aieeee_attempt_to_allocate_pud
#define PMD_ORDER 0
#define PTE_ORDER 0
#endif
#ifdef CONFIG_PAGE_SIZE_16KB
#define PGD_ORDER 0
+#define PUD_ORDER aieeee_attempt_to_allocate_pud
#define PMD_ORDER 0
#define PTE_ORDER 0
#endif
#ifdef CONFIG_PAGE_SIZE_64KB
#define PGD_ORDER 0
+#define PUD_ORDER aieeee_attempt_to_allocate_pud
#define PMD_ORDER 0
#define PTE_ORDER 0
#endif
@@ -91,7 +97,7 @@
#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE)
#define FIRST_USER_ADDRESS 0
-#define VMALLOC_START XKSEG
+#define VMALLOC_START MAP_BASE
#define VMALLOC_END \
(VMALLOC_START + PTRS_PER_PGD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE)
@@ -102,13 +108,13 @@
#define pgd_ERROR(e) \
printk("%s:%d: bad pgd %016lx.\n", __FILE__, __LINE__, pgd_val(e))
-extern pte_t invalid_pte_table[PAGE_SIZE/sizeof(pte_t)];
-extern pte_t empty_bad_page_table[PAGE_SIZE/sizeof(pte_t)];
-extern pmd_t invalid_pmd_table[2*PAGE_SIZE/sizeof(pmd_t)];
-extern pmd_t empty_bad_pmd_table[2*PAGE_SIZE/sizeof(pmd_t)];
+extern pte_t invalid_pte_table[PTRS_PER_PTE];
+extern pte_t empty_bad_page_table[PTRS_PER_PTE];
+extern pmd_t invalid_pmd_table[PTRS_PER_PMD];
+extern pmd_t empty_bad_pmd_table[PTRS_PER_PMD];
/*
- * Empty pmd entries point to the invalid_pte_table.
+ * Empty pgd/pmd entries point to the invalid_pte_table.
*/
static inline int pmd_none(pmd_t pmd)
{
@@ -128,26 +134,30 @@ static inline void pmd_clear(pmd_t *pmdp)
}
/*
- * Empty pgd entries point to the invalid_pmd_table.
+ * Empty pud entries point to the invalid_pmd_table.
*/
-static inline int pgd_none(pgd_t pgd)
+static inline int pud_none(pud_t pud)
{
- return pgd_val(pgd) == (unsigned long) invalid_pmd_table;
+ return pud_val(pud) == (unsigned long) invalid_pmd_table;
}
-#define pgd_bad(pgd) (pgd_val(pgd) &~ PAGE_MASK)
+static inline int pud_bad(pud_t pud)
+{
+ return pud_val(pud) & ~PAGE_MASK;
+}
-static inline int pgd_present(pgd_t pgd)
+static inline int pud_present(pud_t pud)
{
- return pgd_val(pgd) != (unsigned long) invalid_pmd_table;
+ return pud_val(pud) != (unsigned long) invalid_pmd_table;
}
-static inline void pgd_clear(pgd_t *pgdp)
+static inline void pud_clear(pud_t *pudp)
{
- pgd_val(*pgdp) = ((unsigned long) invalid_pmd_table);
+ pud_val(*pudp) = ((unsigned long) invalid_pmd_table);
}
-#define pte_page(x) pfn_to_page((unsigned long)((pte_val(x) >> PAGE_SHIFT)))
+#define pte_page(x) pfn_to_page(pte_pfn(x))
+
#ifdef CONFIG_CPU_VR41XX
#define pte_pfn(x) ((unsigned long)((x).pte >> (PAGE_SHIFT + 2)))
#define pfn_pte(pfn, prot) __pte(((pfn) << (PAGE_SHIFT + 2)) | pgprot_val(prot))
@@ -157,26 +167,27 @@ static inline void pgd_clear(pgd_t *pgdp)
#endif
#define __pgd_offset(address) pgd_index(address)
-#define page_pte(page) page_pte_prot(page, __pgprot(0))
+#define __pud_offset(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
+#define __pmd_offset(address) pmd_index(address)
/* to find an entry in a kernel page-table-directory */
#define pgd_offset_k(address) pgd_offset(&init_mm, 0)
-#define pgd_index(address) ((address) >> PGDIR_SHIFT)
+#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
+#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
/* to find an entry in a page-table-directory */
#define pgd_offset(mm,addr) ((mm)->pgd + pgd_index(addr))
-static inline unsigned long pgd_page(pgd_t pgd)
+static inline unsigned long pud_page(pud_t pud)
{
- return pgd_val(pgd);
+ return pud_val(pud);
}
/* Find an entry in the second-level page table.. */
-static inline pmd_t *pmd_offset(pgd_t * dir, unsigned long address)
+static inline pmd_t *pmd_offset(pud_t * pud, unsigned long address)
{
- return (pmd_t *) pgd_page(*dir) +
- ((address >> PMD_SHIFT) & (PTRS_PER_PMD - 1));
+ return (pmd_t *) pud_page(*pud) + pmd_index(address);
}
/* Find an entry in the third-level page table.. */
diff --git a/include/asm-mips/pgtable-bits.h b/include/asm-mips/pgtable-bits.h
index 3aad751ccd5f..01e76e932e3f 100644
--- a/include/asm-mips/pgtable-bits.h
+++ b/include/asm-mips/pgtable-bits.h
@@ -33,7 +33,7 @@
* unpredictable things. The code (when it is written) to deal with
* this problem will be in the update_mmu_cache() code for the r4k.
*/
-#if defined(CONFIG_CPU_MIPS32) && defined(CONFIG_64BIT_PHYS_ADDR)
+#if defined(CONFIG_CPU_MIPS32_R1) && defined(CONFIG_64BIT_PHYS_ADDR)
#define _PAGE_PRESENT (1<<6) /* implemented in software */
#define _PAGE_READ (1<<7) /* implemented in software */
@@ -123,7 +123,7 @@
#endif
#endif
-#endif /* defined(CONFIG_CPU_MIPS32) && defined(CONFIG_64BIT_PHYS_ADDR) */
+#endif /* defined(CONFIG_CPU_MIPS32_R1) && defined(CONFIG_64BIT_PHYS_ADDR) */
#define __READABLE (_PAGE_READ | _PAGE_SILENT_READ | _PAGE_ACCESSED)
#define __WRITEABLE (_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED)
@@ -140,7 +140,7 @@
#define PAGE_CACHABLE_DEFAULT _CACHE_CACHABLE_COW
#endif
-#if defined(CONFIG_CPU_MIPS32) && defined(CONFIG_64BIT_PHYS_ADDR)
+#if defined(CONFIG_CPU_MIPS32_R1) && defined(CONFIG_64BIT_PHYS_ADDR)
#define CONF_CM_DEFAULT (PAGE_CACHABLE_DEFAULT >> 3)
#else
#define CONF_CM_DEFAULT (PAGE_CACHABLE_DEFAULT >> 9)
diff --git a/include/asm-mips/pgtable.h b/include/asm-mips/pgtable.h
index eaf5d9b3a0e1..34facd996503 100644
--- a/include/asm-mips/pgtable.h
+++ b/include/asm-mips/pgtable.h
@@ -8,8 +8,6 @@
#ifndef _ASM_PGTABLE_H
#define _ASM_PGTABLE_H
-#include <asm-generic/4level-fixup.h>
-
#include <linux/config.h>
#ifdef CONFIG_32BIT
#include <asm/pgtable-32.h>
@@ -18,6 +16,7 @@
#include <asm/pgtable-64.h>
#endif
+#include <asm/io.h>
#include <asm/pgtable-bits.h>
#define PAGE_NONE __pgprot(_PAGE_PRESENT | _CACHE_CACHABLE_NONCOHERENT)
@@ -76,7 +75,6 @@ extern void paging_init(void);
* Conversion functions: convert a page and protection to a page entry,
* and a page entry and page directory to the page they refer to.
*/
-#define page_pte(page) page_pte_prot(page, __pgprot(0))
#define pmd_phys(pmd) (pmd_val(pmd) - PAGE_OFFSET)
#define pmd_page(pmd) (pfn_to_page(pmd_phys(pmd) >> PAGE_SHIFT))
#define pmd_page_kernel(pmd) pmd_val(pmd)
@@ -84,7 +82,7 @@ extern void paging_init(void);
#define pte_none(pte) (!(pte_val(pte) & ~_PAGE_GLOBAL))
#define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT)
-#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
static inline void set_pte(pte_t *ptep, pte_t pte)
{
ptep->pte_high = pte.pte_high;
@@ -148,11 +146,18 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt
#endif
/*
- * (pmds are folded into pgds so this doesn't get actually called,
+ * (pmds are folded into puds so this doesn't get actually called,
* but the define is needed for a generic inline function.)
*/
#define set_pmd(pmdptr, pmdval) do { *(pmdptr) = (pmdval); } while(0)
-#define set_pgd(pgdptr, pgdval) do { *(pgdptr) = (pgdval); } while(0)
+
+#ifdef CONFIG_64BIT
+/*
+ * (puds are folded into pgds so this doesn't get actually called,
+ * but the define is needed for a generic inline function.)
+ */
+#define set_pud(pudptr, pudval) do { *(pudptr) = (pudval); } while(0)
+#endif
#define PGD_T_LOG2 ffz(~sizeof(pgd_t))
#define PMD_T_LOG2 ffz(~sizeof(pmd_t))
@@ -165,7 +170,7 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
* Undefined behaviour if not..
*/
static inline int pte_user(pte_t pte) { BUG(); return 0; }
-#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
static inline int pte_read(pte_t pte) { return (pte).pte_low & _PAGE_READ; }
static inline int pte_write(pte_t pte) { return (pte).pte_low & _PAGE_WRITE; }
static inline int pte_dirty(pte_t pte) { return (pte).pte_low & _PAGE_MODIFIED; }
@@ -324,7 +329,7 @@ static inline pgprot_t pgprot_noncached(pgprot_t _prot)
*/
#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
-#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{
pte.pte_low &= _PAGE_CHG_MASK;
@@ -357,7 +362,6 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
#endif
#ifdef CONFIG_64BIT_PHYS_ADDR
-extern phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size);
extern int remap_pfn_range(struct vm_area_struct *vma, unsigned long from, unsigned long pfn, unsigned long size, pgprot_t prot);
static inline int io_remap_pfn_range(struct vm_area_struct *vma,
@@ -367,7 +371,7 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma,
pgprot_t prot)
{
phys_t phys_addr_high = fixup_bigphys_addr(pfn << PAGE_SHIFT, size);
- return remap_pfn_range(vma, vaddr, pfn, size, prot);
+ return remap_pfn_range(vma, vaddr, phys_addr_high >> PAGE_SHIFT, size, prot);
}
#else
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
diff --git a/include/asm-mips/processor.h b/include/asm-mips/processor.h
index d6466aa09fb7..f1980c6c3bcc 100644
--- a/include/asm-mips/processor.h
+++ b/include/asm-mips/processor.h
@@ -96,12 +96,26 @@ union mips_fpu_union {
{{0,},} \
}
+#define NUM_DSP_REGS 6
+
+typedef __u32 dspreg_t;
+
+struct mips_dsp_state {
+ dspreg_t dspr[NUM_DSP_REGS];
+ unsigned int dspcontrol;
+ unsigned short used_dsp;
+};
+
+#define INIT_DSP {{0,},}
+
typedef struct {
unsigned long seg;
} mm_segment_t;
#define ARCH_MIN_TASKALIGN 8
+struct mips_abi;
+
/*
* If you change thread_struct remember to change the #defines below too!
*/
@@ -117,6 +131,9 @@ struct thread_struct {
/* Saved fpu/fpu emulator stuff. */
union mips_fpu_union fpu;
+ /* Saved state of the DSP ASE, if available. */
+ struct mips_dsp_state dsp;
+
/* Other stuff associated with the thread. */
unsigned long cp0_badvaddr; /* Last user fault */
unsigned long cp0_baduaddr; /* Last kernel fault accessing USEG */
@@ -129,6 +146,7 @@ struct thread_struct {
unsigned long mflags;
unsigned long irix_trampoline; /* Wheee... */
unsigned long irix_oldctx;
+ struct mips_abi *abi;
};
#define MF_ABI_MASK (MF_32BIT_REGS | MF_32BIT_ADDR)
@@ -151,6 +169,10 @@ struct thread_struct {
*/ \
INIT_FPU, \
/* \
+ * saved dsp/dsp emulator stuff \
+ */ \
+ INIT_DSP, \
+ /* \
* Other stuff associated with the process \
*/ \
0, 0, 0, 0, \
diff --git a/include/asm-mips/ptrace.h b/include/asm-mips/ptrace.h
index 2b5c624c3d4f..95c5839ac465 100644
--- a/include/asm-mips/ptrace.h
+++ b/include/asm-mips/ptrace.h
@@ -22,6 +22,8 @@
#define MMLO 68
#define FPC_CSR 69
#define FPC_EIR 70
+#define DSP_BASE 71 /* 3 more hi / lo register pairs */
+#define DSP_CONTROL 77
/*
* This struct defines the way the registers are stored on the stack during a
@@ -38,18 +40,18 @@ struct pt_regs {
/* Saved special registers. */
unsigned long cp0_status;
- unsigned long lo;
unsigned long hi;
+ unsigned long lo;
unsigned long cp0_badvaddr;
unsigned long cp0_cause;
unsigned long cp0_epc;
};
/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
-/* #define PTRACE_GETREGS 12 */
-/* #define PTRACE_SETREGS 13 */
-/* #define PTRACE_GETFPREGS 14 */
-/* #define PTRACE_SETFPREGS 15 */
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13
+#define PTRACE_GETFPREGS 14
+#define PTRACE_SETFPREGS 15
/* #define PTRACE_GETFPXREGS 18 */
/* #define PTRACE_SETFPXREGS 19 */
@@ -58,6 +60,13 @@ struct pt_regs {
#define PTRACE_GET_THREAD_AREA 25
#define PTRACE_SET_THREAD_AREA 26
+/* Calls to trace a 64bit program from a 32bit program. */
+#define PTRACE_PEEKTEXT_3264 0xc0
+#define PTRACE_PEEKDATA_3264 0xc1
+#define PTRACE_POKETEXT_3264 0xc2
+#define PTRACE_POKEDATA_3264 0xc3
+#define PTRACE_GET_THREAD_AREA_3264 0xc4
+
#ifdef __KERNEL__
#include <linux/linkage.h>
diff --git a/include/asm-mips/r4kcache.h b/include/asm-mips/r4kcache.h
index 5bea49feec66..a5ea9d828aee 100644
--- a/include/asm-mips/r4kcache.h
+++ b/include/asm-mips/r4kcache.h
@@ -21,7 +21,7 @@
*
* - The MIPS32 and MIPS64 specs permit an implementation to directly derive
* the index bits from the virtual address. This breaks with tradition
- * set by the R4000. To keep unpleassant surprises from happening we pick
+ * set by the R4000. To keep unpleasant surprises from happening we pick
* an address in KSEG0 / CKSEG0.
* - We need a properly sign extended address for 64-bit code. To get away
* without ifdefs we let the compiler do it by a type cast.
@@ -30,11 +30,11 @@
#define cache_op(op,addr) \
__asm__ __volatile__( \
+ " .set push \n" \
" .set noreorder \n" \
" .set mips3\n\t \n" \
" cache %0, %1 \n" \
- " .set mips0 \n" \
- " .set reorder" \
+ " .set pop \n" \
: \
: "i" (op), "m" (*(unsigned char *)(addr)))
@@ -84,14 +84,14 @@ static inline void flush_scache_line(unsigned long addr)
static inline void protected_flush_icache_line(unsigned long addr)
{
__asm__ __volatile__(
- ".set noreorder\n\t"
- ".set mips3\n"
- "1:\tcache %0,(%1)\n"
- "2:\t.set mips0\n\t"
- ".set reorder\n\t"
- ".section\t__ex_table,\"a\"\n\t"
- STR(PTR)"\t1b,2b\n\t"
- ".previous"
+ " .set push \n"
+ " .set noreorder \n"
+ " .set mips3 \n"
+ "1: cache %0, (%1) \n"
+ "2: .set pop \n"
+ " .section __ex_table,\"a\" \n"
+ " "STR(PTR)" 1b, 2b \n"
+ " .previous"
:
: "i" (Hit_Invalidate_I), "r" (addr));
}
@@ -100,19 +100,19 @@ static inline void protected_flush_icache_line(unsigned long addr)
* R10000 / R12000 hazard - these processors don't support the Hit_Writeback_D
* cacheop so we use Hit_Writeback_Inv_D which is supported by all R4000-style
* caches. We're talking about one cacheline unnecessarily getting invalidated
- * here so the penaltiy isn't overly hard.
+ * here so the penalty isn't overly hard.
*/
static inline void protected_writeback_dcache_line(unsigned long addr)
{
__asm__ __volatile__(
- ".set noreorder\n\t"
- ".set mips3\n"
- "1:\tcache %0,(%1)\n"
- "2:\t.set mips0\n\t"
- ".set reorder\n\t"
- ".section\t__ex_table,\"a\"\n\t"
- STR(PTR)"\t1b,2b\n\t"
- ".previous"
+ " .set push \n"
+ " .set noreorder \n"
+ " .set mips3 \n"
+ "1: cache %0, (%1) \n"
+ "2: .set pop \n"
+ " .section __ex_table,\"a\" \n"
+ " "STR(PTR)" 1b, 2b \n"
+ " .previous"
:
: "i" (Hit_Writeback_Inv_D), "r" (addr));
}
@@ -120,14 +120,14 @@ static inline void protected_writeback_dcache_line(unsigned long addr)
static inline void protected_writeback_scache_line(unsigned long addr)
{
__asm__ __volatile__(
- ".set noreorder\n\t"
- ".set mips3\n"
- "1:\tcache %0,(%1)\n"
- "2:\t.set mips0\n\t"
- ".set reorder\n\t"
- ".section\t__ex_table,\"a\"\n\t"
- STR(PTR)"\t1b,2b\n\t"
- ".previous"
+ " .set push \n"
+ " .set noreorder \n"
+ " .set mips3 \n"
+ "1: cache %0, (%1) \n"
+ "2: .set pop \n"
+ " .section __ex_table,\"a\" \n"
+ " "STR(PTR)" 1b, 2b \n"
+ " .previous"
:
: "i" (Hit_Writeback_Inv_SD), "r" (addr));
}
@@ -142,6 +142,7 @@ static inline void invalidate_tcache_page(unsigned long addr)
#define cache16_unroll32(base,op) \
__asm__ __volatile__( \
+ " .set push \n" \
" .set noreorder \n" \
" .set mips3 \n" \
" cache %1, 0x000(%0); cache %1, 0x010(%0) \n" \
@@ -160,8 +161,7 @@ static inline void invalidate_tcache_page(unsigned long addr)
" cache %1, 0x1a0(%0); cache %1, 0x1b0(%0) \n" \
" cache %1, 0x1c0(%0); cache %1, 0x1d0(%0) \n" \
" cache %1, 0x1e0(%0); cache %1, 0x1f0(%0) \n" \
- " .set mips0 \n" \
- " .set reorder \n" \
+ " .set pop \n" \
: \
: "r" (base), \
"i" (op));
@@ -285,6 +285,7 @@ static inline void blast_scache16_page_indexed(unsigned long page)
#define cache32_unroll32(base,op) \
__asm__ __volatile__( \
+ " .set push \n" \
" .set noreorder \n" \
" .set mips3 \n" \
" cache %1, 0x000(%0); cache %1, 0x020(%0) \n" \
@@ -303,8 +304,7 @@ static inline void blast_scache16_page_indexed(unsigned long page)
" cache %1, 0x340(%0); cache %1, 0x360(%0) \n" \
" cache %1, 0x380(%0); cache %1, 0x3a0(%0) \n" \
" cache %1, 0x3c0(%0); cache %1, 0x3e0(%0) \n" \
- " .set mips0 \n" \
- " .set reorder \n" \
+ " .set pop \n" \
: \
: "r" (base), \
"i" (op));
@@ -428,6 +428,7 @@ static inline void blast_scache32_page_indexed(unsigned long page)
#define cache64_unroll32(base,op) \
__asm__ __volatile__( \
+ " .set push \n" \
" .set noreorder \n" \
" .set mips3 \n" \
" cache %1, 0x000(%0); cache %1, 0x040(%0) \n" \
@@ -446,8 +447,7 @@ static inline void blast_scache32_page_indexed(unsigned long page)
" cache %1, 0x680(%0); cache %1, 0x6c0(%0) \n" \
" cache %1, 0x700(%0); cache %1, 0x740(%0) \n" \
" cache %1, 0x780(%0); cache %1, 0x7c0(%0) \n" \
- " .set mips0 \n" \
- " .set reorder \n" \
+ " .set pop \n" \
: \
: "r" (base), \
"i" (op));
@@ -532,6 +532,7 @@ static inline void blast_scache64_page_indexed(unsigned long page)
#define cache128_unroll32(base,op) \
__asm__ __volatile__( \
+ " .set push \n" \
" .set noreorder \n" \
" .set mips3 \n" \
" cache %1, 0x000(%0); cache %1, 0x080(%0) \n" \
@@ -550,8 +551,7 @@ static inline void blast_scache64_page_indexed(unsigned long page)
" cache %1, 0xd00(%0); cache %1, 0xd80(%0) \n" \
" cache %1, 0xe00(%0); cache %1, 0xe80(%0) \n" \
" cache %1, 0xf00(%0); cache %1, 0xf80(%0) \n" \
- " .set mips0 \n" \
- " .set reorder \n" \
+ " .set pop \n" \
: \
: "r" (base), \
"i" (op));
diff --git a/include/asm-mips/rtc.h b/include/asm-mips/rtc.h
index 3c4b637fd925..a60e0dc7c9b9 100644
--- a/include/asm-mips/rtc.h
+++ b/include/asm-mips/rtc.h
@@ -14,7 +14,9 @@
#ifdef __KERNEL__
+#include <linux/spinlock.h>
#include <linux/rtc.h>
+#include <asm/time.h>
#define RTC_PIE 0x40 /* periodic interrupt enable */
#define RTC_AIE 0x20 /* alarm interrupt enable */
@@ -27,11 +29,52 @@
#define RTC_24H 0x02 /* 24 hour mode - else hours bit 7 means pm */
#define RTC_DST_EN 0x01 /* auto switch DST - works f. USA only */
-unsigned int get_rtc_time(struct rtc_time *time);
-int set_rtc_time(struct rtc_time *time);
-unsigned int get_rtc_ss(void);
-int get_rtc_pll(struct rtc_pll_info *pll);
-int set_rtc_pll(struct rtc_pll_info *pll);
+static DEFINE_SPINLOCK(mips_rtc_lock);
+static inline unsigned int get_rtc_time(struct rtc_time *time)
+{
+ unsigned long nowtime;
+
+ spin_lock(&mips_rtc_lock);
+ nowtime = rtc_get_time();
+ to_tm(nowtime, time);
+ time->tm_year -= 1900;
+ spin_unlock(&mips_rtc_lock);
+
+ return RTC_24H;
+}
+
+static inline int set_rtc_time(struct rtc_time *time)
+{
+ unsigned long nowtime;
+ int ret;
+
+ spin_lock(&mips_rtc_lock);
+ nowtime = mktime(time->tm_year+1900, time->tm_mon+1,
+ time->tm_mday, time->tm_hour, time->tm_min,
+ time->tm_sec);
+ ret = rtc_set_time(nowtime);
+ spin_unlock(&mips_rtc_lock);
+
+ return ret;
+}
+
+static inline unsigned int get_rtc_ss(void)
+{
+ struct rtc_time h;
+
+ get_rtc_time(&h);
+ return h.tm_sec;
+}
+
+static inline int get_rtc_pll(struct rtc_pll_info *pll)
+{
+ return -EINVAL;
+}
+
+static inline int set_rtc_pll(struct rtc_pll_info *pll)
+{
+ return -EINVAL;
+}
#endif
#endif
diff --git a/include/asm-mips/rtlx.h b/include/asm-mips/rtlx.h
new file mode 100644
index 000000000000..83cdf6ab0d1f
--- /dev/null
+++ b/include/asm-mips/rtlx.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2004, 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ */
+
+#ifndef _RTLX_H
+#define _RTLX_H_
+
+#define LX_NODE_BASE 10
+
+#define MIPSCPU_INT_BASE 16
+#define MIPS_CPU_RTLX_IRQ 0
+
+#define RTLX_VERSION 1
+#define RTLX_xID 0x12345600
+#define RTLX_ID (RTLX_xID | RTLX_VERSION)
+#define RTLX_CHANNELS 8
+
+enum rtlx_state {
+ RTLX_STATE_UNUSED = 0,
+ RTLX_STATE_INITIALISED,
+ RTLX_STATE_REMOTE_READY,
+ RTLX_STATE_OPENED
+};
+
+#define RTLX_BUFFER_SIZE 1024
+/* each channel supports read and write.
+ linux (vpe0) reads lx_buffer and writes rt_buffer
+ SP (vpe1) reads rt_buffer and writes lx_buffer
+*/
+typedef struct rtlx_channel {
+ enum rtlx_state rt_state;
+ enum rtlx_state lx_state;
+
+ int buffer_size;
+
+ /* read and write indexes per buffer */
+ int rt_write, rt_read;
+ char *rt_buffer;
+
+ int lx_write, lx_read;
+ char *lx_buffer;
+
+ void *queues;
+
+} rtlx_channel_t;
+
+typedef struct rtlx_info {
+ unsigned long id;
+ enum rtlx_state state;
+
+ struct rtlx_channel channel[RTLX_CHANNELS];
+
+} rtlx_info_t;
+
+#endif
diff --git a/include/asm-mips/semaphore.h b/include/asm-mips/semaphore.h
index c2c97dec661b..3d6aa7c7ea81 100644
--- a/include/asm-mips/semaphore.h
+++ b/include/asm-mips/semaphore.h
@@ -45,9 +45,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name, 1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name, count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/asm-mips/serial.h b/include/asm-mips/serial.h
index 4eed8e2acdc3..e796d75f027e 100644
--- a/include/asm-mips/serial.h
+++ b/include/asm-mips/serial.h
@@ -52,16 +52,6 @@
#define JAZZ_SERIAL_PORT_DEFNS
#endif
-#ifdef CONFIG_MIPS_COBALT
-#include <asm/cobalt/cobalt.h>
-#define COBALT_BASE_BAUD (18432000 / 16)
-#define COBALT_SERIAL_PORT_DEFNS \
- /* UART CLK PORT IRQ FLAGS */ \
- { 0, COBALT_BASE_BAUD, 0xc800000, COBALT_SERIAL_IRQ, STD_COM_FLAGS }, /* ttyS0 */
-#else
-#define COBALT_SERIAL_PORT_DEFNS
-#endif
-
/*
* Both Galileo boards have the same UART mappings.
*/
@@ -113,17 +103,6 @@
#define IVR_SERIAL_PORT_DEFNS
#endif
-#ifdef CONFIG_TOSHIBA_JMR3927
-#include <asm/jmr3927/jmr3927.h>
-#define TXX927_SERIAL_PORT_DEFNS \
- { .baud_base = JMR3927_BASE_BAUD, .port = UART0_ADDR, .irq = UART0_INT, \
- .flags = UART0_FLAGS, .type = 1 }, \
- { .baud_base = JMR3927_BASE_BAUD, .port = UART1_ADDR, .irq = UART1_INT, \
- .flags = UART1_FLAGS, .type = 1 },
-#else
-#define TXX927_SERIAL_PORT_DEFNS
-#endif
-
#ifdef CONFIG_SERIAL_AU1X00
#include <asm/mach-au1x00/au1000.h>
#ifdef CONFIG_SOC_AU1000
@@ -227,9 +206,9 @@
#define JAGUAR_ATX_SERIAL1_BASE 0xfd000023L
#define _JAGUAR_ATX_SERIAL_INIT(int, base) \
- { baud_base: JAGUAR_ATX_BASE_BAUD, irq: int, \
- flags: (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \
- iomem_base: (u8 *) base, iomem_reg_shift: 2, \
+ { .baud_base = JAGUAR_ATX_BASE_BAUD, irq: int, \
+ .flags = (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \
+ .iomem_base = (u8 *) base, iomem_reg_shift: 2, \
io_type: SERIAL_IO_MEM }
#define MOMENCO_JAGUAR_ATX_SERIAL_PORT_DEFNS \
_JAGUAR_ATX_SERIAL_INIT(JAGUAR_ATX_SERIAL1_IRQ, JAGUAR_ATX_SERIAL1_BASE)
@@ -243,9 +222,9 @@
#define OCELOT_3_SERIAL_BASE (signed)0xfd000020
#define _OCELOT_3_SERIAL_INIT(int, base) \
- { baud_base: OCELOT_3_BASE_BAUD, irq: int, \
- flags: STD_COM_FLAGS, \
- iomem_base: (u8 *) base, iomem_reg_shift: 2, \
+ { .baud_base = OCELOT_3_BASE_BAUD, irq: int, \
+ .flags = STD_COM_FLAGS, \
+ .iomem_base = (u8 *) base, iomem_reg_shift: 2, \
io_type: SERIAL_IO_MEM }
#define MOMENCO_OCELOT_3_SERIAL_PORT_DEFNS \
@@ -342,7 +321,6 @@
#endif /* CONFIG_SGI_IP32 */
#define SERIAL_PORT_DFNS \
- COBALT_SERIAL_PORT_DEFNS \
DDB5477_SERIAL_PORT_DEFNS \
EV96100_SERIAL_PORT_DEFNS \
IP32_SERIAL_PORT_DEFNS \
@@ -354,7 +332,6 @@
MOMENCO_OCELOT_C_SERIAL_PORT_DEFNS \
MOMENCO_OCELOT_SERIAL_PORT_DEFNS \
MOMENCO_OCELOT_3_SERIAL_PORT_DEFNS \
- TXX927_SERIAL_PORT_DEFNS \
AU1000_SERIAL_PORT_DEFNS
#endif /* _ASM_SERIAL_H */
diff --git a/include/asm-mips/sibyte/bcm1480_int.h b/include/asm-mips/sibyte/bcm1480_int.h
new file mode 100644
index 000000000000..42d4cf00efd3
--- /dev/null
+++ b/include/asm-mips/sibyte/bcm1480_int.h
@@ -0,0 +1,310 @@
+/* *********************************************************************
+ * BCM1280/BCM1480 Board Support Package
+ *
+ * Interrupt Mapper definitions File: bcm1480_int.h
+ *
+ * This module contains constants for manipulating the
+ * BCM1255/BCM1280/BCM1455/BCM1480's interrupt mapper and
+ * definitions for the interrupt sources.
+ *
+ * BCM1480 specification level: 1X55_1X80-UM100-D4 (11/24/03)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ ********************************************************************* */
+
+
+#ifndef _BCM1480_INT_H
+#define _BCM1480_INT_H
+
+#include "sb1250_defs.h"
+
+/* *********************************************************************
+ * Interrupt Mapper Constants
+ ********************************************************************* */
+
+/*
+ * The interrupt mapper deals with 128-bit logical registers that are
+ * implemented as pairs of 64-bit registers, with the "low" 64 bits in
+ * a register that has an address 0x1000 higher(!) than the
+ * corresponding "high" register.
+ *
+ * For appropriate registers, bit 0 of the "high" register is a
+ * cascade bit that summarizes (as a bit-OR) the 64 bits of the "low"
+ * register.
+ */
+
+/*
+ * This entire file uses _BCM1480_ in all the symbols because it is
+ * entirely BCM1480 specific.
+ */
+
+/*
+ * Interrupt sources (Table 22)
+ */
+
+#define K_BCM1480_INT_SOURCES 128
+
+#define _BCM1480_INT_HIGH(k) (k)
+#define _BCM1480_INT_LOW(k) ((k)+64)
+
+#define K_BCM1480_INT_ADDR_TRAP _BCM1480_INT_HIGH(1)
+#define K_BCM1480_INT_GPIO_0 _BCM1480_INT_HIGH(4)
+#define K_BCM1480_INT_GPIO_1 _BCM1480_INT_HIGH(5)
+#define K_BCM1480_INT_GPIO_2 _BCM1480_INT_HIGH(6)
+#define K_BCM1480_INT_GPIO_3 _BCM1480_INT_HIGH(7)
+#define K_BCM1480_INT_PCI_INTA _BCM1480_INT_HIGH(8)
+#define K_BCM1480_INT_PCI_INTB _BCM1480_INT_HIGH(9)
+#define K_BCM1480_INT_PCI_INTC _BCM1480_INT_HIGH(10)
+#define K_BCM1480_INT_PCI_INTD _BCM1480_INT_HIGH(11)
+#define K_BCM1480_INT_CYCLE_CP0 _BCM1480_INT_HIGH(12)
+#define K_BCM1480_INT_CYCLE_CP1 _BCM1480_INT_HIGH(13)
+#define K_BCM1480_INT_CYCLE_CP2 _BCM1480_INT_HIGH(14)
+#define K_BCM1480_INT_CYCLE_CP3 _BCM1480_INT_HIGH(15)
+#define K_BCM1480_INT_TIMER_0 _BCM1480_INT_HIGH(20)
+#define K_BCM1480_INT_TIMER_1 _BCM1480_INT_HIGH(21)
+#define K_BCM1480_INT_TIMER_2 _BCM1480_INT_HIGH(22)
+#define K_BCM1480_INT_TIMER_3 _BCM1480_INT_HIGH(23)
+#define K_BCM1480_INT_DM_CH_0 _BCM1480_INT_HIGH(28)
+#define K_BCM1480_INT_DM_CH_1 _BCM1480_INT_HIGH(29)
+#define K_BCM1480_INT_DM_CH_2 _BCM1480_INT_HIGH(30)
+#define K_BCM1480_INT_DM_CH_3 _BCM1480_INT_HIGH(31)
+#define K_BCM1480_INT_MAC_0 _BCM1480_INT_HIGH(36)
+#define K_BCM1480_INT_MAC_0_CH1 _BCM1480_INT_HIGH(37)
+#define K_BCM1480_INT_MAC_1 _BCM1480_INT_HIGH(38)
+#define K_BCM1480_INT_MAC_1_CH1 _BCM1480_INT_HIGH(39)
+#define K_BCM1480_INT_MAC_2 _BCM1480_INT_HIGH(40)
+#define K_BCM1480_INT_MAC_2_CH1 _BCM1480_INT_HIGH(41)
+#define K_BCM1480_INT_MAC_3 _BCM1480_INT_HIGH(42)
+#define K_BCM1480_INT_MAC_3_CH1 _BCM1480_INT_HIGH(43)
+#define K_BCM1480_INT_PMI_LOW _BCM1480_INT_HIGH(52)
+#define K_BCM1480_INT_PMI_HIGH _BCM1480_INT_HIGH(53)
+#define K_BCM1480_INT_PMO_LOW _BCM1480_INT_HIGH(54)
+#define K_BCM1480_INT_PMO_HIGH _BCM1480_INT_HIGH(55)
+#define K_BCM1480_INT_MBOX_0_0 _BCM1480_INT_HIGH(56)
+#define K_BCM1480_INT_MBOX_0_1 _BCM1480_INT_HIGH(57)
+#define K_BCM1480_INT_MBOX_0_2 _BCM1480_INT_HIGH(58)
+#define K_BCM1480_INT_MBOX_0_3 _BCM1480_INT_HIGH(59)
+#define K_BCM1480_INT_MBOX_1_0 _BCM1480_INT_HIGH(60)
+#define K_BCM1480_INT_MBOX_1_1 _BCM1480_INT_HIGH(61)
+#define K_BCM1480_INT_MBOX_1_2 _BCM1480_INT_HIGH(62)
+#define K_BCM1480_INT_MBOX_1_3 _BCM1480_INT_HIGH(63)
+
+#define K_BCM1480_INT_BAD_ECC _BCM1480_INT_LOW(1)
+#define K_BCM1480_INT_COR_ECC _BCM1480_INT_LOW(2)
+#define K_BCM1480_INT_IO_BUS _BCM1480_INT_LOW(3)
+#define K_BCM1480_INT_PERF_CNT _BCM1480_INT_LOW(4)
+#define K_BCM1480_INT_SW_PERF_CNT _BCM1480_INT_LOW(5)
+#define K_BCM1480_INT_TRACE_FREEZE _BCM1480_INT_LOW(6)
+#define K_BCM1480_INT_SW_TRACE_FREEZE _BCM1480_INT_LOW(7)
+#define K_BCM1480_INT_WATCHDOG_TIMER_0 _BCM1480_INT_LOW(8)
+#define K_BCM1480_INT_WATCHDOG_TIMER_1 _BCM1480_INT_LOW(9)
+#define K_BCM1480_INT_WATCHDOG_TIMER_2 _BCM1480_INT_LOW(10)
+#define K_BCM1480_INT_WATCHDOG_TIMER_3 _BCM1480_INT_LOW(11)
+#define K_BCM1480_INT_PCI_ERROR _BCM1480_INT_LOW(16)
+#define K_BCM1480_INT_PCI_RESET _BCM1480_INT_LOW(17)
+#define K_BCM1480_INT_NODE_CONTROLLER _BCM1480_INT_LOW(18)
+#define K_BCM1480_INT_HOST_BRIDGE _BCM1480_INT_LOW(19)
+#define K_BCM1480_INT_PORT_0_FATAL _BCM1480_INT_LOW(20)
+#define K_BCM1480_INT_PORT_0_NONFATAL _BCM1480_INT_LOW(21)
+#define K_BCM1480_INT_PORT_1_FATAL _BCM1480_INT_LOW(22)
+#define K_BCM1480_INT_PORT_1_NONFATAL _BCM1480_INT_LOW(23)
+#define K_BCM1480_INT_PORT_2_FATAL _BCM1480_INT_LOW(24)
+#define K_BCM1480_INT_PORT_2_NONFATAL _BCM1480_INT_LOW(25)
+#define K_BCM1480_INT_LDT_SMI _BCM1480_INT_LOW(32)
+#define K_BCM1480_INT_LDT_NMI _BCM1480_INT_LOW(33)
+#define K_BCM1480_INT_LDT_INIT _BCM1480_INT_LOW(34)
+#define K_BCM1480_INT_LDT_STARTUP _BCM1480_INT_LOW(35)
+#define K_BCM1480_INT_LDT_EXT _BCM1480_INT_LOW(36)
+#define K_BCM1480_INT_SMB_0 _BCM1480_INT_LOW(40)
+#define K_BCM1480_INT_SMB_1 _BCM1480_INT_LOW(41)
+#define K_BCM1480_INT_PCMCIA _BCM1480_INT_LOW(42)
+#define K_BCM1480_INT_UART_0 _BCM1480_INT_LOW(44)
+#define K_BCM1480_INT_UART_1 _BCM1480_INT_LOW(45)
+#define K_BCM1480_INT_UART_2 _BCM1480_INT_LOW(46)
+#define K_BCM1480_INT_UART_3 _BCM1480_INT_LOW(47)
+#define K_BCM1480_INT_GPIO_4 _BCM1480_INT_LOW(52)
+#define K_BCM1480_INT_GPIO_5 _BCM1480_INT_LOW(53)
+#define K_BCM1480_INT_GPIO_6 _BCM1480_INT_LOW(54)
+#define K_BCM1480_INT_GPIO_7 _BCM1480_INT_LOW(55)
+#define K_BCM1480_INT_GPIO_8 _BCM1480_INT_LOW(56)
+#define K_BCM1480_INT_GPIO_9 _BCM1480_INT_LOW(57)
+#define K_BCM1480_INT_GPIO_10 _BCM1480_INT_LOW(58)
+#define K_BCM1480_INT_GPIO_11 _BCM1480_INT_LOW(59)
+#define K_BCM1480_INT_GPIO_12 _BCM1480_INT_LOW(60)
+#define K_BCM1480_INT_GPIO_13 _BCM1480_INT_LOW(61)
+#define K_BCM1480_INT_GPIO_14 _BCM1480_INT_LOW(62)
+#define K_BCM1480_INT_GPIO_15 _BCM1480_INT_LOW(63)
+
+/*
+ * Mask values for each interrupt
+ */
+
+#define _BCM1480_INT_MASK1(n) _SB_MAKEMASK1(((n) & 0x3F))
+#define _BCM1480_INT_OFFSET(n) (((n) & 0x40) << 6)
+
+#define M_BCM1480_INT_CASCADE _BCM1480_INT_MASK1(_BCM1480_INT_HIGH(0))
+
+#define M_BCM1480_INT_ADDR_TRAP _BCM1480_INT_MASK1(K_BCM1480_INT_ADDR_TRAP)
+#define M_BCM1480_INT_GPIO_0 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_0)
+#define M_BCM1480_INT_GPIO_1 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_1)
+#define M_BCM1480_INT_GPIO_2 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_2)
+#define M_BCM1480_INT_GPIO_3 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_3)
+#define M_BCM1480_INT_PCI_INTA _BCM1480_INT_MASK1(K_BCM1480_INT_PCI_INTA)
+#define M_BCM1480_INT_PCI_INTB _BCM1480_INT_MASK1(K_BCM1480_INT_PCI_INTB)
+#define M_BCM1480_INT_PCI_INTC _BCM1480_INT_MASK1(K_BCM1480_INT_PCI_INTC)
+#define M_BCM1480_INT_PCI_INTD _BCM1480_INT_MASK1(K_BCM1480_INT_PCI_INTD)
+#define M_BCM1480_INT_CYCLE_CP0 _BCM1480_INT_MASK1(K_BCM1480_INT_CYCLE_CP0)
+#define M_BCM1480_INT_CYCLE_CP1 _BCM1480_INT_MASK1(K_BCM1480_INT_CYCLE_CP1)
+#define M_BCM1480_INT_CYCLE_CP2 _BCM1480_INT_MASK1(K_BCM1480_INT_CYCLE_CP2)
+#define M_BCM1480_INT_CYCLE_CP3 _BCM1480_INT_MASK1(K_BCM1480_INT_CYCLE_CP3)
+#define M_BCM1480_INT_TIMER_0 _BCM1480_INT_MASK1(K_BCM1480_INT_TIMER_0)
+#define M_BCM1480_INT_TIMER_1 _BCM1480_INT_MASK1(K_BCM1480_INT_TIMER_1)
+#define M_BCM1480_INT_TIMER_2 _BCM1480_INT_MASK1(K_BCM1480_INT_TIMER_2)
+#define M_BCM1480_INT_TIMER_3 _BCM1480_INT_MASK1(K_BCM1480_INT_TIMER_3)
+#define M_BCM1480_INT_DM_CH_0 _BCM1480_INT_MASK1(K_BCM1480_INT_DM_CH_0)
+#define M_BCM1480_INT_DM_CH_1 _BCM1480_INT_MASK1(K_BCM1480_INT_DM_CH_1)
+#define M_BCM1480_INT_DM_CH_2 _BCM1480_INT_MASK1(K_BCM1480_INT_DM_CH_2)
+#define M_BCM1480_INT_DM_CH_3 _BCM1480_INT_MASK1(K_BCM1480_INT_DM_CH_3)
+#define M_BCM1480_INT_MAC_0 _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_0)
+#define M_BCM1480_INT_MAC_0_CH1 _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_0_CH1)
+#define M_BCM1480_INT_MAC_1 _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_1)
+#define M_BCM1480_INT_MAC_1_CH1 _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_1_CH1)
+#define M_BCM1480_INT_MAC_2 _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_2)
+#define M_BCM1480_INT_MAC_2_CH1 _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_2_CH1)
+#define M_BCM1480_INT_MAC_3 _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_3)
+#define M_BCM1480_INT_MAC_3_CH1 _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_3_CH1)
+#define M_BCM1480_INT_PMI_LOW _BCM1480_INT_MASK1(K_BCM1480_INT_PMI_LOW)
+#define M_BCM1480_INT_PMI_HIGH _BCM1480_INT_MASK1(K_BCM1480_INT_PMI_HIGH)
+#define M_BCM1480_INT_PMO_LOW _BCM1480_INT_MASK1(K_BCM1480_INT_PMO_LOW)
+#define M_BCM1480_INT_PMO_HIGH _BCM1480_INT_MASK1(K_BCM1480_INT_PMO_HIGH)
+#define M_BCM1480_INT_MBOX_0_0 _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_0_0)
+#define M_BCM1480_INT_MBOX_0_1 _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_0_1)
+#define M_BCM1480_INT_MBOX_0_2 _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_0_2)
+#define M_BCM1480_INT_MBOX_0_3 _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_0_3)
+#define M_BCM1480_INT_MBOX_1_0 _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_1_0)
+#define M_BCM1480_INT_MBOX_1_1 _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_1_1)
+#define M_BCM1480_INT_MBOX_1_2 _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_1_2)
+#define M_BCM1480_INT_MBOX_1_3 _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_1_3)
+#define M_BCM1480_INT_BAD_ECC _BCM1480_INT_MASK1(K_BCM1480_INT_BAD_ECC)
+#define M_BCM1480_INT_COR_ECC _BCM1480_INT_MASK1(K_BCM1480_INT_COR_ECC)
+#define M_BCM1480_INT_IO_BUS _BCM1480_INT_MASK1(K_BCM1480_INT_IO_BUS)
+#define M_BCM1480_INT_PERF_CNT _BCM1480_INT_MASK1(K_BCM1480_INT_PERF_CNT)
+#define M_BCM1480_INT_SW_PERF_CNT _BCM1480_INT_MASK1(K_BCM1480_INT_SW_PERF_CNT)
+#define M_BCM1480_INT_TRACE_FREEZE _BCM1480_INT_MASK1(K_BCM1480_INT_TRACE_FREEZE)
+#define M_BCM1480_INT_SW_TRACE_FREEZE _BCM1480_INT_MASK1(K_BCM1480_INT_SW_TRACE_FREEZE)
+#define M_BCM1480_INT_WATCHDOG_TIMER_0 _BCM1480_INT_MASK1(K_BCM1480_INT_WATCHDOG_TIMER_0)
+#define M_BCM1480_INT_WATCHDOG_TIMER_1 _BCM1480_INT_MASK1(K_BCM1480_INT_WATCHDOG_TIMER_1)
+#define M_BCM1480_INT_WATCHDOG_TIMER_2 _BCM1480_INT_MASK1(K_BCM1480_INT_WATCHDOG_TIMER_2)
+#define M_BCM1480_INT_WATCHDOG_TIMER_3 _BCM1480_INT_MASK1(K_BCM1480_INT_WATCHDOG_TIMER_3)
+#define M_BCM1480_INT_PCI_ERROR _BCM1480_INT_MASK1(K_BCM1480_INT_PCI_ERROR)
+#define M_BCM1480_INT_PCI_RESET _BCM1480_INT_MASK1(K_BCM1480_INT_PCI_RESET)
+#define M_BCM1480_INT_NODE_CONTROLLER _BCM1480_INT_MASK1(K_BCM1480_INT_NODE_CONTROLLER)
+#define M_BCM1480_INT_HOST_BRIDGE _BCM1480_INT_MASK1(K_BCM1480_INT_HOST_BRIDGE)
+#define M_BCM1480_INT_PORT_0_FATAL _BCM1480_INT_MASK1(K_BCM1480_INT_PORT_0_FATAL)
+#define M_BCM1480_INT_PORT_0_NONFATAL _BCM1480_INT_MASK1(K_BCM1480_INT_PORT_0_NONFATAL)
+#define M_BCM1480_INT_PORT_1_FATAL _BCM1480_INT_MASK1(K_BCM1480_INT_PORT_1_FATAL)
+#define M_BCM1480_INT_PORT_1_NONFATAL _BCM1480_INT_MASK1(K_BCM1480_INT_PORT_1_NONFATAL)
+#define M_BCM1480_INT_PORT_2_FATAL _BCM1480_INT_MASK1(K_BCM1480_INT_PORT_2_FATAL)
+#define M_BCM1480_INT_PORT_2_NONFATAL _BCM1480_INT_MASK1(K_BCM1480_INT_PORT_2_NONFATAL)
+#define M_BCM1480_INT_LDT_SMI _BCM1480_INT_MASK1(K_BCM1480_INT_LDT_SMI)
+#define M_BCM1480_INT_LDT_NMI _BCM1480_INT_MASK1(K_BCM1480_INT_LDT_NMI)
+#define M_BCM1480_INT_LDT_INIT _BCM1480_INT_MASK1(K_BCM1480_INT_LDT_INIT)
+#define M_BCM1480_INT_LDT_STARTUP _BCM1480_INT_MASK1(K_BCM1480_INT_LDT_STARTUP)
+#define M_BCM1480_INT_LDT_EXT _BCM1480_INT_MASK1(K_BCM1480_INT_LDT_EXT)
+#define M_BCM1480_INT_SMB_0 _BCM1480_INT_MASK1(K_BCM1480_INT_SMB_0)
+#define M_BCM1480_INT_SMB_1 _BCM1480_INT_MASK1(K_BCM1480_INT_SMB_1)
+#define M_BCM1480_INT_PCMCIA _BCM1480_INT_MASK1(K_BCM1480_INT_PCMCIA)
+#define M_BCM1480_INT_UART_0 _BCM1480_INT_MASK1(K_BCM1480_INT_UART_0)
+#define M_BCM1480_INT_UART_1 _BCM1480_INT_MASK1(K_BCM1480_INT_UART_1)
+#define M_BCM1480_INT_UART_2 _BCM1480_INT_MASK1(K_BCM1480_INT_UART_2)
+#define M_BCM1480_INT_UART_3 _BCM1480_INT_MASK1(K_BCM1480_INT_UART_3)
+#define M_BCM1480_INT_GPIO_4 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_4)
+#define M_BCM1480_INT_GPIO_5 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_5)
+#define M_BCM1480_INT_GPIO_6 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_6)
+#define M_BCM1480_INT_GPIO_7 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_7)
+#define M_BCM1480_INT_GPIO_8 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_8)
+#define M_BCM1480_INT_GPIO_9 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_9)
+#define M_BCM1480_INT_GPIO_10 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_10)
+#define M_BCM1480_INT_GPIO_11 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_11)
+#define M_BCM1480_INT_GPIO_12 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_12)
+#define M_BCM1480_INT_GPIO_13 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_13)
+#define M_BCM1480_INT_GPIO_14 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_14)
+#define M_BCM1480_INT_GPIO_15 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_15)
+
+/*
+ * Interrupt mappings (Table 18)
+ */
+
+#define K_BCM1480_INT_MAP_I0 0 /* interrupt pins on processor */
+#define K_BCM1480_INT_MAP_I1 1
+#define K_BCM1480_INT_MAP_I2 2
+#define K_BCM1480_INT_MAP_I3 3
+#define K_BCM1480_INT_MAP_I4 4
+#define K_BCM1480_INT_MAP_I5 5
+#define K_BCM1480_INT_MAP_NMI 6 /* nonmaskable */
+#define K_BCM1480_INT_MAP_DINT 7 /* debug interrupt */
+
+/*
+ * Interrupt LDT Set Register (Table 19)
+ */
+
+#define S_BCM1480_INT_HT_INTMSG 0
+#define M_BCM1480_INT_HT_INTMSG _SB_MAKEMASK(3,S_BCM1480_INT_HT_INTMSG)
+#define V_BCM1480_INT_HT_INTMSG(x) _SB_MAKEVALUE(x,S_BCM1480_INT_HT_INTMSG)
+#define G_BCM1480_INT_HT_INTMSG(x) _SB_GETVALUE(x,S_BCM1480_INT_HT_INTMSG,M_BCM1480_INT_HT_INTMSG)
+
+#define K_BCM1480_INT_HT_INTMSG_FIXED 0
+#define K_BCM1480_INT_HT_INTMSG_ARBITRATED 1
+#define K_BCM1480_INT_HT_INTMSG_SMI 2
+#define K_BCM1480_INT_HT_INTMSG_NMI 3
+#define K_BCM1480_INT_HT_INTMSG_INIT 4
+#define K_BCM1480_INT_HT_INTMSG_STARTUP 5
+#define K_BCM1480_INT_HT_INTMSG_EXTINT 6
+#define K_BCM1480_INT_HT_INTMSG_RESERVED 7
+
+#define M_BCM1480_INT_HT_TRIGGERMODE _SB_MAKEMASK1(3)
+#define V_BCM1480_INT_HT_EDGETRIGGER 0
+#define V_BCM1480_INT_HT_LEVELTRIGGER M_BCM1480_INT_HT_TRIGGERMODE
+
+#define M_BCM1480_INT_HT_DESTMODE _SB_MAKEMASK1(4)
+#define V_BCM1480_INT_HT_PHYSICALDEST 0
+#define V_BCM1480_INT_HT_LOGICALDEST M_BCM1480_INT_HT_DESTMODE
+
+#define S_BCM1480_INT_HT_INTDEST 5
+#define M_BCM1480_INT_HT_INTDEST _SB_MAKEMASK(8,S_BCM1480_INT_HT_INTDEST)
+#define V_BCM1480_INT_HT_INTDEST(x) _SB_MAKEVALUE(x,S_BCM1480_INT_HT_INTDEST)
+#define G_BCM1480_INT_HT_INTDEST(x) _SB_GETVALUE(x,S_BCM1480_INT_HT_INTDEST,M_BCM1480_INT_HT_INTDEST)
+
+#define S_BCM1480_INT_HT_VECTOR 13
+#define M_BCM1480_INT_HT_VECTOR _SB_MAKEMASK(8,S_BCM1480_INT_HT_VECTOR)
+#define V_BCM1480_INT_HT_VECTOR(x) _SB_MAKEVALUE(x,S_BCM1480_INT_HT_VECTOR)
+#define G_BCM1480_INT_HT_VECTOR(x) _SB_GETVALUE(x,S_BCM1480_INT_HT_VECTOR,M_BCM1480_INT_HT_VECTOR)
+
+/*
+ * Vector prefix (Table 4-7)
+ */
+
+#define M_BCM1480_HTVECT_RAISE_INTLDT_HIGH 0x00
+#define M_BCM1480_HTVECT_RAISE_MBOX_0 0x40
+#define M_BCM1480_HTVECT_RAISE_INTLDT_LO 0x80
+#define M_BCM1480_HTVECT_RAISE_MBOX_1 0xC0
+
+#endif /* _BCM1480_INT_H */
diff --git a/include/asm-mips/sibyte/bcm1480_l2c.h b/include/asm-mips/sibyte/bcm1480_l2c.h
new file mode 100644
index 000000000000..886b099565e6
--- /dev/null
+++ b/include/asm-mips/sibyte/bcm1480_l2c.h
@@ -0,0 +1,176 @@
+/* *********************************************************************
+ * BCM1280/BCM1480 Board Support Package
+ *
+ * L2 Cache constants and macros File: bcm1480_l2c.h
+ *
+ * This module contains constants useful for manipulating the
+ * level 2 cache.
+ *
+ * BCM1400 specification level: 1280-UM100-D2 (11/14/03)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ ********************************************************************* */
+
+
+#ifndef _BCM1480_L2C_H
+#define _BCM1480_L2C_H
+
+#include "sb1250_defs.h"
+
+/*
+ * Format of level 2 cache management address (Table 55)
+ */
+
+#define S_BCM1480_L2C_MGMT_INDEX 5
+#define M_BCM1480_L2C_MGMT_INDEX _SB_MAKEMASK(12,S_BCM1480_L2C_MGMT_INDEX)
+#define V_BCM1480_L2C_MGMT_INDEX(x) _SB_MAKEVALUE(x,S_BCM1480_L2C_MGMT_INDEX)
+#define G_BCM1480_L2C_MGMT_INDEX(x) _SB_GETVALUE(x,S_BCM1480_L2C_MGMT_INDEX,M_BCM1480_L2C_MGMT_INDEX)
+
+#define S_BCM1480_L2C_MGMT_WAY 17
+#define M_BCM1480_L2C_MGMT_WAY _SB_MAKEMASK(3,S_BCM1480_L2C_MGMT_WAY)
+#define V_BCM1480_L2C_MGMT_WAY(x) _SB_MAKEVALUE(x,S_BCM1480_L2C_MGMT_WAY)
+#define G_BCM1480_L2C_MGMT_WAY(x) _SB_GETVALUE(x,S_BCM1480_L2C_MGMT_WAY,M_BCM1480_L2C_MGMT_WAY)
+
+#define M_BCM1480_L2C_MGMT_DIRTY _SB_MAKEMASK1(20)
+#define M_BCM1480_L2C_MGMT_VALID _SB_MAKEMASK1(21)
+
+#define S_BCM1480_L2C_MGMT_ECC_DIAG 22
+#define M_BCM1480_L2C_MGMT_ECC_DIAG _SB_MAKEMASK(2,S_BCM1480_L2C_MGMT_ECC_DIAG)
+#define V_BCM1480_L2C_MGMT_ECC_DIAG(x) _SB_MAKEVALUE(x,S_BCM1480_L2C_MGMT_ECC_DIAG)
+#define G_BCM1480_L2C_MGMT_ECC_DIAG(x) _SB_GETVALUE(x,S_BCM1480_L2C_MGMT_ECC_DIAG,M_BCM1480_L2C_MGMT_ECC_DIAG)
+
+#define A_BCM1480_L2C_MGMT_TAG_BASE 0x00D0000000
+
+#define BCM1480_L2C_ENTRIES_PER_WAY 4096
+#define BCM1480_L2C_NUM_WAYS 8
+
+
+/*
+ * Level 2 Cache Tag register (Table 59)
+ */
+
+#define S_BCM1480_L2C_TAG_MBZ 0
+#define M_BCM1480_L2C_TAG_MBZ _SB_MAKEMASK(5,S_BCM1480_L2C_TAG_MBZ)
+
+#define S_BCM1480_L2C_TAG_INDEX 5
+#define M_BCM1480_L2C_TAG_INDEX _SB_MAKEMASK(12,S_BCM1480_L2C_TAG_INDEX)
+#define V_BCM1480_L2C_TAG_INDEX(x) _SB_MAKEVALUE(x,S_BCM1480_L2C_TAG_INDEX)
+#define G_BCM1480_L2C_TAG_INDEX(x) _SB_GETVALUE(x,S_BCM1480_L2C_TAG_INDEX,M_BCM1480_L2C_TAG_INDEX)
+
+/* Note that index bit 16 is also tag bit 40 */
+#define S_BCM1480_L2C_TAG_TAG 17
+#define M_BCM1480_L2C_TAG_TAG _SB_MAKEMASK(23,S_BCM1480_L2C_TAG_TAG)
+#define V_BCM1480_L2C_TAG_TAG(x) _SB_MAKEVALUE(x,S_BCM1480_L2C_TAG_TAG)
+#define G_BCM1480_L2C_TAG_TAG(x) _SB_GETVALUE(x,S_BCM1480_L2C_TAG_TAG,M_BCM1480_L2C_TAG_TAG)
+
+#define S_BCM1480_L2C_TAG_ECC 40
+#define M_BCM1480_L2C_TAG_ECC _SB_MAKEMASK(6,S_BCM1480_L2C_TAG_ECC)
+#define V_BCM1480_L2C_TAG_ECC(x) _SB_MAKEVALUE(x,S_BCM1480_L2C_TAG_ECC)
+#define G_BCM1480_L2C_TAG_ECC(x) _SB_GETVALUE(x,S_BCM1480_L2C_TAG_ECC,M_BCM1480_L2C_TAG_ECC)
+
+#define S_BCM1480_L2C_TAG_WAY 46
+#define M_BCM1480_L2C_TAG_WAY _SB_MAKEMASK(3,S_BCM1480_L2C_TAG_WAY)
+#define V_BCM1480_L2C_TAG_WAY(x) _SB_MAKEVALUE(x,S_BCM1480_L2C_TAG_WAY)
+#define G_BCM1480_L2C_TAG_WAY(x) _SB_GETVALUE(x,S_BCM1480_L2C_TAG_WAY,M_BCM1480_L2C_TAG_WAY)
+
+#define M_BCM1480_L2C_TAG_DIRTY _SB_MAKEMASK1(49)
+#define M_BCM1480_L2C_TAG_VALID _SB_MAKEMASK1(50)
+
+#define S_BCM1480_L2C_DATA_ECC 51
+#define M_BCM1480_L2C_DATA_ECC _SB_MAKEMASK(10,S_BCM1480_L2C_DATA_ECC)
+#define V_BCM1480_L2C_DATA_ECC(x) _SB_MAKEVALUE(x,S_BCM1480_L2C_DATA_ECC)
+#define G_BCM1480_L2C_DATA_ECC(x) _SB_GETVALUE(x,S_BCM1480_L2C_DATA_ECC,M_BCM1480_L2C_DATA_ECC)
+
+
+/*
+ * L2 Misc0 Value Register (Table 60)
+ */
+
+#define S_BCM1480_L2C_MISC0_WAY_REMOTE 0
+#define M_BCM1480_L2C_MISC0_WAY_REMOTE _SB_MAKEMASK(8,S_BCM1480_L2C_MISC0_WAY_REMOTE)
+#define G_BCM1480_L2C_MISC0_WAY_REMOTE(x) _SB_GETVALUE(x,S_BCM1480_L2C_MISC0_WAY_REMOTE,M_BCM1480_L2C_MISC0_WAY_REMOTE)
+
+#define S_BCM1480_L2C_MISC0_WAY_LOCAL 8
+#define M_BCM1480_L2C_MISC0_WAY_LOCAL _SB_MAKEMASK(8,S_BCM1480_L2C_MISC0_WAY_LOCAL)
+#define G_BCM1480_L2C_MISC0_WAY_LOCAL(x) _SB_GETVALUE(x,S_BCM1480_L2C_MISC0_WAY_LOCAL,M_BCM1480_L2C_MISC0_WAY_LOCAL)
+
+#define S_BCM1480_L2C_MISC0_WAY_ENABLE 16
+#define M_BCM1480_L2C_MISC0_WAY_ENABLE _SB_MAKEMASK(8,S_BCM1480_L2C_MISC0_WAY_ENABLE)
+#define G_BCM1480_L2C_MISC0_WAY_ENABLE(x) _SB_GETVALUE(x,S_BCM1480_L2C_MISC0_WAY_ENABLE,M_BCM1480_L2C_MISC0_WAY_ENABLE)
+
+#define S_BCM1480_L2C_MISC0_CACHE_DISABLE 24
+#define M_BCM1480_L2C_MISC0_CACHE_DISABLE _SB_MAKEMASK(2,S_BCM1480_L2C_MISC0_CACHE_DISABLE)
+#define G_BCM1480_L2C_MISC0_CACHE_DISABLE(x) _SB_GETVALUE(x,S_BCM1480_L2C_MISC0_CACHE_DISABLE,M_BCM1480_L2C_MISC0_CACHE_DISABLE)
+
+#define S_BCM1480_L2C_MISC0_CACHE_QUAD 26
+#define M_BCM1480_L2C_MISC0_CACHE_QUAD _SB_MAKEMASK(2,S_BCM1480_L2C_MISC0_CACHE_QUAD)
+#define G_BCM1480_L2C_MISC0_CACHE_QUAD(x) _SB_GETVALUE(x,S_BCM1480_L2C_MISC0_CACHE_QUAD,M_BCM1480_L2C_MISC0_CACHE_QUAD)
+
+#define S_BCM1480_L2C_MISC0_MC_PRIORITY 30
+#define M_BCM1480_L2C_MISC0_MC_PRIORITY _SB_MAKEMASK1(S_BCM1480_L2C_MISC0_MC_PRIORITY)
+
+#define S_BCM1480_L2C_MISC0_ECC_CLEANUP 31
+#define M_BCM1480_L2C_MISC0_ECC_CLEANUP _SB_MAKEMASK1(S_BCM1480_L2C_MISC0_ECC_CLEANUP)
+
+
+/*
+ * L2 Misc1 Value Register (Table 60)
+ */
+
+#define S_BCM1480_L2C_MISC1_WAY_AGENT_0 0
+#define M_BCM1480_L2C_MISC1_WAY_AGENT_0 _SB_MAKEMASK(8,S_BCM1480_L2C_MISC1_WAY_AGENT_0)
+#define G_BCM1480_L2C_MISC1_WAY_AGENT_0(x) _SB_GETVALUE(x,S_BCM1480_L2C_MISC1_WAY_AGENT_0,M_BCM1480_L2C_MISC1_WAY_AGENT_0)
+
+#define S_BCM1480_L2C_MISC1_WAY_AGENT_1 8
+#define M_BCM1480_L2C_MISC1_WAY_AGENT_1 _SB_MAKEMASK(8,S_BCM1480_L2C_MISC1_WAY_AGENT_1)
+#define G_BCM1480_L2C_MISC1_WAY_AGENT_1(x) _SB_GETVALUE(x,S_BCM1480_L2C_MISC1_WAY_AGENT_1,M_BCM1480_L2C_MISC1_WAY_AGENT_1)
+
+#define S_BCM1480_L2C_MISC1_WAY_AGENT_2 16
+#define M_BCM1480_L2C_MISC1_WAY_AGENT_2 _SB_MAKEMASK(8,S_BCM1480_L2C_MISC1_WAY_AGENT_2)
+#define G_BCM1480_L2C_MISC1_WAY_AGENT_2(x) _SB_GETVALUE(x,S_BCM1480_L2C_MISC1_WAY_AGENT_2,M_BCM1480_L2C_MISC1_WAY_AGENT_2)
+
+#define S_BCM1480_L2C_MISC1_WAY_AGENT_3 24
+#define M_BCM1480_L2C_MISC1_WAY_AGENT_3 _SB_MAKEMASK(8,S_BCM1480_L2C_MISC1_WAY_AGENT_3)
+#define G_BCM1480_L2C_MISC1_WAY_AGENT_3(x) _SB_GETVALUE(x,S_BCM1480_L2C_MISC1_WAY_AGENT_3,M_BCM1480_L2C_MISC1_WAY_AGENT_3)
+
+#define S_BCM1480_L2C_MISC1_WAY_AGENT_4 32
+#define M_BCM1480_L2C_MISC1_WAY_AGENT_4 _SB_MAKEMASK(8,S_BCM1480_L2C_MISC1_WAY_AGENT_4)
+#define G_BCM1480_L2C_MISC1_WAY_AGENT_4(x) _SB_GETVALUE(x,S_BCM1480_L2C_MISC1_WAY_AGENT_4,M_BCM1480_L2C_MISC1_WAY_AGENT_4)
+
+
+/*
+ * L2 Misc2 Value Register (Table 60)
+ */
+
+#define S_BCM1480_L2C_MISC2_WAY_AGENT_8 0
+#define M_BCM1480_L2C_MISC2_WAY_AGENT_8 _SB_MAKEMASK(8,S_BCM1480_L2C_MISC2_WAY_AGENT_8)
+#define G_BCM1480_L2C_MISC2_WAY_AGENT_8(x) _SB_GETVALUE(x,S_BCM1480_L2C_MISC2_WAY_AGENT_8,M_BCM1480_L2C_MISC2_WAY_AGENT_8)
+
+#define S_BCM1480_L2C_MISC2_WAY_AGENT_9 8
+#define M_BCM1480_L2C_MISC2_WAY_AGENT_9 _SB_MAKEMASK(8,S_BCM1480_L2C_MISC2_WAY_AGENT_9)
+#define G_BCM1480_L2C_MISC2_WAY_AGENT_9(x) _SB_GETVALUE(x,S_BCM1480_L2C_MISC2_WAY_AGENT_9,M_BCM1480_L2C_MISC2_WAY_AGENT_9)
+
+#define S_BCM1480_L2C_MISC2_WAY_AGENT_A 16
+#define M_BCM1480_L2C_MISC2_WAY_AGENT_A _SB_MAKEMASK(8,S_BCM1480_L2C_MISC2_WAY_AGENT_A)
+#define G_BCM1480_L2C_MISC2_WAY_AGENT_A(x) _SB_GETVALUE(x,S_BCM1480_L2C_MISC2_WAY_AGENT_A,M_BCM1480_L2C_MISC2_WAY_AGENT_A)
+
+
+#endif /* _BCM1480_L2C_H */
diff --git a/include/asm-mips/sibyte/bcm1480_mc.h b/include/asm-mips/sibyte/bcm1480_mc.h
new file mode 100644
index 000000000000..6bdc941afc91
--- /dev/null
+++ b/include/asm-mips/sibyte/bcm1480_mc.h
@@ -0,0 +1,962 @@
+/* *********************************************************************
+ * BCM1280/BCM1480 Board Support Package
+ *
+ * Memory Controller constants File: bcm1480_mc.h
+ *
+ * This module contains constants and macros useful for
+ * programming the memory controller.
+ *
+ * BCM1400 specification level: 1280-UM100-D1 (11/14/03 Review Copy)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ ********************************************************************* */
+
+
+#ifndef _BCM1480_MC_H
+#define _BCM1480_MC_H
+
+#include "sb1250_defs.h"
+
+/*
+ * Memory Channel Configuration Register (Table 81)
+ */
+
+#define S_BCM1480_MC_INTLV0 0
+#define M_BCM1480_MC_INTLV0 _SB_MAKEMASK(6,S_BCM1480_MC_INTLV0)
+#define V_BCM1480_MC_INTLV0(x) _SB_MAKEVALUE(x,S_BCM1480_MC_INTLV0)
+#define G_BCM1480_MC_INTLV0(x) _SB_GETVALUE(x,S_BCM1480_MC_INTLV0,M_BCM1480_MC_INTLV0)
+#define V_BCM1480_MC_INTLV0_DEFAULT V_BCM1480_MC_INTLV0(0)
+
+#define S_BCM1480_MC_INTLV1 8
+#define M_BCM1480_MC_INTLV1 _SB_MAKEMASK(6,S_BCM1480_MC_INTLV1)
+#define V_BCM1480_MC_INTLV1(x) _SB_MAKEVALUE(x,S_BCM1480_MC_INTLV1)
+#define G_BCM1480_MC_INTLV1(x) _SB_GETVALUE(x,S_BCM1480_MC_INTLV1,M_BCM1480_MC_INTLV1)
+#define V_BCM1480_MC_INTLV1_DEFAULT V_BCM1480_MC_INTLV1(0)
+
+#define S_BCM1480_MC_INTLV2 16
+#define M_BCM1480_MC_INTLV2 _SB_MAKEMASK(6,S_BCM1480_MC_INTLV2)
+#define V_BCM1480_MC_INTLV2(x) _SB_MAKEVALUE(x,S_BCM1480_MC_INTLV2)
+#define G_BCM1480_MC_INTLV2(x) _SB_GETVALUE(x,S_BCM1480_MC_INTLV2,M_BCM1480_MC_INTLV2)
+#define V_BCM1480_MC_INTLV2_DEFAULT V_BCM1480_MC_INTLV2(0)
+
+#define S_BCM1480_MC_CS_MODE 32
+#define M_BCM1480_MC_CS_MODE _SB_MAKEMASK(8,S_BCM1480_MC_CS_MODE)
+#define V_BCM1480_MC_CS_MODE(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CS_MODE)
+#define G_BCM1480_MC_CS_MODE(x) _SB_GETVALUE(x,S_BCM1480_MC_CS_MODE,M_BCM1480_MC_CS_MODE)
+#define V_BCM1480_MC_CS_MODE_DEFAULT V_BCM1480_MC_CS_MODE(0)
+
+#define V_BCM1480_MC_CONFIG_DEFAULT (V_BCM1480_MC_INTLV0_DEFAULT | \
+ V_BCM1480_MC_INTLV1_DEFAULT | \
+ V_BCM1480_MC_INTLV2_DEFAULT | \
+ V_BCM1480_MC_CS_MODE_DEFAULT)
+
+#define K_BCM1480_MC_CS01_MODE 0x03
+#define K_BCM1480_MC_CS02_MODE 0x05
+#define K_BCM1480_MC_CS0123_MODE 0x0F
+#define K_BCM1480_MC_CS0246_MODE 0x55
+#define K_BCM1480_MC_CS0145_MODE 0x33
+#define K_BCM1480_MC_CS0167_MODE 0xC3
+#define K_BCM1480_MC_CSFULL_MODE 0xFF
+
+/*
+ * Chip Select Start Address Register (Table 82)
+ */
+
+#define S_BCM1480_MC_CS0_START 0
+#define M_BCM1480_MC_CS0_START _SB_MAKEMASK(12,S_BCM1480_MC_CS0_START)
+#define V_BCM1480_MC_CS0_START(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CS0_START)
+#define G_BCM1480_MC_CS0_START(x) _SB_GETVALUE(x,S_BCM1480_MC_CS0_START,M_BCM1480_MC_CS0_START)
+
+#define S_BCM1480_MC_CS1_START 16
+#define M_BCM1480_MC_CS1_START _SB_MAKEMASK(12,S_BCM1480_MC_CS1_START)
+#define V_BCM1480_MC_CS1_START(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CS1_START)
+#define G_BCM1480_MC_CS1_START(x) _SB_GETVALUE(x,S_BCM1480_MC_CS1_START,M_BCM1480_MC_CS1_START)
+
+#define S_BCM1480_MC_CS2_START 32
+#define M_BCM1480_MC_CS2_START _SB_MAKEMASK(12,S_BCM1480_MC_CS2_START)
+#define V_BCM1480_MC_CS2_START(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CS2_START)
+#define G_BCM1480_MC_CS2_START(x) _SB_GETVALUE(x,S_BCM1480_MC_CS2_START,M_BCM1480_MC_CS2_START)
+
+#define S_BCM1480_MC_CS3_START 48
+#define M_BCM1480_MC_CS3_START _SB_MAKEMASK(12,S_BCM1480_MC_CS3_START)
+#define V_BCM1480_MC_CS3_START(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CS3_START)
+#define G_BCM1480_MC_CS3_START(x) _SB_GETVALUE(x,S_BCM1480_MC_CS3_START,M_BCM1480_MC_CS3_START)
+
+/*
+ * Chip Select End Address Register (Table 83)
+ */
+
+#define S_BCM1480_MC_CS0_END 0
+#define M_BCM1480_MC_CS0_END _SB_MAKEMASK(12,S_BCM1480_MC_CS0_END)
+#define V_BCM1480_MC_CS0_END(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CS0_END)
+#define G_BCM1480_MC_CS0_END(x) _SB_GETVALUE(x,S_BCM1480_MC_CS0_END,M_BCM1480_MC_CS0_END)
+
+#define S_BCM1480_MC_CS1_END 16
+#define M_BCM1480_MC_CS1_END _SB_MAKEMASK(12,S_BCM1480_MC_CS1_END)
+#define V_BCM1480_MC_CS1_END(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CS1_END)
+#define G_BCM1480_MC_CS1_END(x) _SB_GETVALUE(x,S_BCM1480_MC_CS1_END,M_BCM1480_MC_CS1_END)
+
+#define S_BCM1480_MC_CS2_END 32
+#define M_BCM1480_MC_CS2_END _SB_MAKEMASK(12,S_BCM1480_MC_CS2_END)
+#define V_BCM1480_MC_CS2_END(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CS2_END)
+#define G_BCM1480_MC_CS2_END(x) _SB_GETVALUE(x,S_BCM1480_MC_CS2_END,M_BCM1480_MC_CS2_END)
+
+#define S_BCM1480_MC_CS3_END 48
+#define M_BCM1480_MC_CS3_END _SB_MAKEMASK(12,S_BCM1480_MC_CS3_END)
+#define V_BCM1480_MC_CS3_END(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CS3_END)
+#define G_BCM1480_MC_CS3_END(x) _SB_GETVALUE(x,S_BCM1480_MC_CS3_END,M_BCM1480_MC_CS3_END)
+
+/*
+ * Row Address Bit Select Register 0 (Table 84)
+ */
+
+#define S_BCM1480_MC_ROW00 0
+#define M_BCM1480_MC_ROW00 _SB_MAKEMASK(6,S_BCM1480_MC_ROW00)
+#define V_BCM1480_MC_ROW00(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ROW00)
+#define G_BCM1480_MC_ROW00(x) _SB_GETVALUE(x,S_BCM1480_MC_ROW00,M_BCM1480_MC_ROW00)
+
+#define S_BCM1480_MC_ROW01 8
+#define M_BCM1480_MC_ROW01 _SB_MAKEMASK(6,S_BCM1480_MC_ROW01)
+#define V_BCM1480_MC_ROW01(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ROW01)
+#define G_BCM1480_MC_ROW01(x) _SB_GETVALUE(x,S_BCM1480_MC_ROW01,M_BCM1480_MC_ROW01)
+
+#define S_BCM1480_MC_ROW02 16
+#define M_BCM1480_MC_ROW02 _SB_MAKEMASK(6,S_BCM1480_MC_ROW02)
+#define V_BCM1480_MC_ROW02(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ROW02)
+#define G_BCM1480_MC_ROW02(x) _SB_GETVALUE(x,S_BCM1480_MC_ROW02,M_BCM1480_MC_ROW02)
+
+#define S_BCM1480_MC_ROW03 24
+#define M_BCM1480_MC_ROW03 _SB_MAKEMASK(6,S_BCM1480_MC_ROW03)
+#define V_BCM1480_MC_ROW03(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ROW03)
+#define G_BCM1480_MC_ROW03(x) _SB_GETVALUE(x,S_BCM1480_MC_ROW03,M_BCM1480_MC_ROW03)
+
+#define S_BCM1480_MC_ROW04 32
+#define M_BCM1480_MC_ROW04 _SB_MAKEMASK(6,S_BCM1480_MC_ROW04)
+#define V_BCM1480_MC_ROW04(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ROW04)
+#define G_BCM1480_MC_ROW04(x) _SB_GETVALUE(x,S_BCM1480_MC_ROW04,M_BCM1480_MC_ROW04)
+
+#define S_BCM1480_MC_ROW05 40
+#define M_BCM1480_MC_ROW05 _SB_MAKEMASK(6,S_BCM1480_MC_ROW05)
+#define V_BCM1480_MC_ROW05(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ROW05)
+#define G_BCM1480_MC_ROW05(x) _SB_GETVALUE(x,S_BCM1480_MC_ROW05,M_BCM1480_MC_ROW05)
+
+#define S_BCM1480_MC_ROW06 48
+#define M_BCM1480_MC_ROW06 _SB_MAKEMASK(6,S_BCM1480_MC_ROW06)
+#define V_BCM1480_MC_ROW06(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ROW06)
+#define G_BCM1480_MC_ROW06(x) _SB_GETVALUE(x,S_BCM1480_MC_ROW06,M_BCM1480_MC_ROW06)
+
+#define S_BCM1480_MC_ROW07 56
+#define M_BCM1480_MC_ROW07 _SB_MAKEMASK(6,S_BCM1480_MC_ROW07)
+#define V_BCM1480_MC_ROW07(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ROW07)
+#define G_BCM1480_MC_ROW07(x) _SB_GETVALUE(x,S_BCM1480_MC_ROW07,M_BCM1480_MC_ROW07)
+
+/*
+ * Row Address Bit Select Register 1 (Table 85)
+ */
+
+#define S_BCM1480_MC_ROW08 0
+#define M_BCM1480_MC_ROW08 _SB_MAKEMASK(6,S_BCM1480_MC_ROW08)
+#define V_BCM1480_MC_ROW08(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ROW08)
+#define G_BCM1480_MC_ROW08(x) _SB_GETVALUE(x,S_BCM1480_MC_ROW08,M_BCM1480_MC_ROW08)
+
+#define S_BCM1480_MC_ROW09 8
+#define M_BCM1480_MC_ROW09 _SB_MAKEMASK(6,S_BCM1480_MC_ROW09)
+#define V_BCM1480_MC_ROW09(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ROW09)
+#define G_BCM1480_MC_ROW09(x) _SB_GETVALUE(x,S_BCM1480_MC_ROW09,M_BCM1480_MC_ROW09)
+
+#define S_BCM1480_MC_ROW10 16
+#define M_BCM1480_MC_ROW10 _SB_MAKEMASK(6,S_BCM1480_MC_ROW10)
+#define V_BCM1480_MC_ROW10(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ROW10)
+#define G_BCM1480_MC_ROW10(x) _SB_GETVALUE(x,S_BCM1480_MC_ROW10,M_BCM1480_MC_ROW10)
+
+#define S_BCM1480_MC_ROW11 24
+#define M_BCM1480_MC_ROW11 _SB_MAKEMASK(6,S_BCM1480_MC_ROW11)
+#define V_BCM1480_MC_ROW11(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ROW11)
+#define G_BCM1480_MC_ROW11(x) _SB_GETVALUE(x,S_BCM1480_MC_ROW11,M_BCM1480_MC_ROW11)
+
+#define S_BCM1480_MC_ROW12 32
+#define M_BCM1480_MC_ROW12 _SB_MAKEMASK(6,S_BCM1480_MC_ROW12)
+#define V_BCM1480_MC_ROW12(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ROW12)
+#define G_BCM1480_MC_ROW12(x) _SB_GETVALUE(x,S_BCM1480_MC_ROW12,M_BCM1480_MC_ROW12)
+
+#define S_BCM1480_MC_ROW13 40
+#define M_BCM1480_MC_ROW13 _SB_MAKEMASK(6,S_BCM1480_MC_ROW13)
+#define V_BCM1480_MC_ROW13(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ROW13)
+#define G_BCM1480_MC_ROW13(x) _SB_GETVALUE(x,S_BCM1480_MC_ROW13,M_BCM1480_MC_ROW13)
+
+#define S_BCM1480_MC_ROW14 48
+#define M_BCM1480_MC_ROW14 _SB_MAKEMASK(6,S_BCM1480_MC_ROW14)
+#define V_BCM1480_MC_ROW14(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ROW14)
+#define G_BCM1480_MC_ROW14(x) _SB_GETVALUE(x,S_BCM1480_MC_ROW14,M_BCM1480_MC_ROW14)
+
+#define K_BCM1480_MC_ROWX_BIT_SPACING 8
+
+/*
+ * Column Address Bit Select Register 0 (Table 86)
+ */
+
+#define S_BCM1480_MC_COL00 0
+#define M_BCM1480_MC_COL00 _SB_MAKEMASK(6,S_BCM1480_MC_COL00)
+#define V_BCM1480_MC_COL00(x) _SB_MAKEVALUE(x,S_BCM1480_MC_COL00)
+#define G_BCM1480_MC_COL00(x) _SB_GETVALUE(x,S_BCM1480_MC_COL00,M_BCM1480_MC_COL00)
+
+#define S_BCM1480_MC_COL01 8
+#define M_BCM1480_MC_COL01 _SB_MAKEMASK(6,S_BCM1480_MC_COL01)
+#define V_BCM1480_MC_COL01(x) _SB_MAKEVALUE(x,S_BCM1480_MC_COL01)
+#define G_BCM1480_MC_COL01(x) _SB_GETVALUE(x,S_BCM1480_MC_COL01,M_BCM1480_MC_COL01)
+
+#define S_BCM1480_MC_COL02 16
+#define M_BCM1480_MC_COL02 _SB_MAKEMASK(6,S_BCM1480_MC_COL02)
+#define V_BCM1480_MC_COL02(x) _SB_MAKEVALUE(x,S_BCM1480_MC_COL02)
+#define G_BCM1480_MC_COL02(x) _SB_GETVALUE(x,S_BCM1480_MC_COL02,M_BCM1480_MC_COL02)
+
+#define S_BCM1480_MC_COL03 24
+#define M_BCM1480_MC_COL03 _SB_MAKEMASK(6,S_BCM1480_MC_COL03)
+#define V_BCM1480_MC_COL03(x) _SB_MAKEVALUE(x,S_BCM1480_MC_COL03)
+#define G_BCM1480_MC_COL03(x) _SB_GETVALUE(x,S_BCM1480_MC_COL03,M_BCM1480_MC_COL03)
+
+#define S_BCM1480_MC_COL04 32
+#define M_BCM1480_MC_COL04 _SB_MAKEMASK(6,S_BCM1480_MC_COL04)
+#define V_BCM1480_MC_COL04(x) _SB_MAKEVALUE(x,S_BCM1480_MC_COL04)
+#define G_BCM1480_MC_COL04(x) _SB_GETVALUE(x,S_BCM1480_MC_COL04,M_BCM1480_MC_COL04)
+
+#define S_BCM1480_MC_COL05 40
+#define M_BCM1480_MC_COL05 _SB_MAKEMASK(6,S_BCM1480_MC_COL05)
+#define V_BCM1480_MC_COL05(x) _SB_MAKEVALUE(x,S_BCM1480_MC_COL05)
+#define G_BCM1480_MC_COL05(x) _SB_GETVALUE(x,S_BCM1480_MC_COL05,M_BCM1480_MC_COL05)
+
+#define S_BCM1480_MC_COL06 48
+#define M_BCM1480_MC_COL06 _SB_MAKEMASK(6,S_BCM1480_MC_COL06)
+#define V_BCM1480_MC_COL06(x) _SB_MAKEVALUE(x,S_BCM1480_MC_COL06)
+#define G_BCM1480_MC_COL06(x) _SB_GETVALUE(x,S_BCM1480_MC_COL06,M_BCM1480_MC_COL06)
+
+#define S_BCM1480_MC_COL07 56
+#define M_BCM1480_MC_COL07 _SB_MAKEMASK(6,S_BCM1480_MC_COL07)
+#define V_BCM1480_MC_COL07(x) _SB_MAKEVALUE(x,S_BCM1480_MC_COL07)
+#define G_BCM1480_MC_COL07(x) _SB_GETVALUE(x,S_BCM1480_MC_COL07,M_BCM1480_MC_COL07)
+
+/*
+ * Column Address Bit Select Register 1 (Table 87)
+ */
+
+#define S_BCM1480_MC_COL08 0
+#define M_BCM1480_MC_COL08 _SB_MAKEMASK(6,S_BCM1480_MC_COL08)
+#define V_BCM1480_MC_COL08(x) _SB_MAKEVALUE(x,S_BCM1480_MC_COL08)
+#define G_BCM1480_MC_COL08(x) _SB_GETVALUE(x,S_BCM1480_MC_COL08,M_BCM1480_MC_COL08)
+
+#define S_BCM1480_MC_COL09 8
+#define M_BCM1480_MC_COL09 _SB_MAKEMASK(6,S_BCM1480_MC_COL09)
+#define V_BCM1480_MC_COL09(x) _SB_MAKEVALUE(x,S_BCM1480_MC_COL09)
+#define G_BCM1480_MC_COL09(x) _SB_GETVALUE(x,S_BCM1480_MC_COL09,M_BCM1480_MC_COL09)
+
+#define S_BCM1480_MC_COL10 16 /* not a valid position, must be prog as 0 */
+
+#define S_BCM1480_MC_COL11 24
+#define M_BCM1480_MC_COL11 _SB_MAKEMASK(6,S_BCM1480_MC_COL11)
+#define V_BCM1480_MC_COL11(x) _SB_MAKEVALUE(x,S_BCM1480_MC_COL11)
+#define G_BCM1480_MC_COL11(x) _SB_GETVALUE(x,S_BCM1480_MC_COL11,M_BCM1480_MC_COL11)
+
+#define S_BCM1480_MC_COL12 32
+#define M_BCM1480_MC_COL12 _SB_MAKEMASK(6,S_BCM1480_MC_COL12)
+#define V_BCM1480_MC_COL12(x) _SB_MAKEVALUE(x,S_BCM1480_MC_COL12)
+#define G_BCM1480_MC_COL12(x) _SB_GETVALUE(x,S_BCM1480_MC_COL12,M_BCM1480_MC_COL12)
+
+#define S_BCM1480_MC_COL13 40
+#define M_BCM1480_MC_COL13 _SB_MAKEMASK(6,S_BCM1480_MC_COL13)
+#define V_BCM1480_MC_COL13(x) _SB_MAKEVALUE(x,S_BCM1480_MC_COL13)
+#define G_BCM1480_MC_COL13(x) _SB_GETVALUE(x,S_BCM1480_MC_COL13,M_BCM1480_MC_COL13)
+
+#define S_BCM1480_MC_COL14 48
+#define M_BCM1480_MC_COL14 _SB_MAKEMASK(6,S_BCM1480_MC_COL14)
+#define V_BCM1480_MC_COL14(x) _SB_MAKEVALUE(x,S_BCM1480_MC_COL14)
+#define G_BCM1480_MC_COL14(x) _SB_GETVALUE(x,S_BCM1480_MC_COL14,M_BCM1480_MC_COL14)
+
+#define K_BCM1480_MC_COLX_BIT_SPACING 8
+
+/*
+ * CS0 and CS1 Bank Address Bit Select Register (Table 88)
+ */
+
+#define S_BCM1480_MC_CS01_BANK0 0
+#define M_BCM1480_MC_CS01_BANK0 _SB_MAKEMASK(6,S_BCM1480_MC_CS01_BANK0)
+#define V_BCM1480_MC_CS01_BANK0(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CS01_BANK0)
+#define G_BCM1480_MC_CS01_BANK0(x) _SB_GETVALUE(x,S_BCM1480_MC_CS01_BANK0,M_BCM1480_MC_CS01_BANK0)
+
+#define S_BCM1480_MC_CS01_BANK1 8
+#define M_BCM1480_MC_CS01_BANK1 _SB_MAKEMASK(6,S_BCM1480_MC_CS01_BANK1)
+#define V_BCM1480_MC_CS01_BANK1(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CS01_BANK1)
+#define G_BCM1480_MC_CS01_BANK1(x) _SB_GETVALUE(x,S_BCM1480_MC_CS01_BANK1,M_BCM1480_MC_CS01_BANK1)
+
+#define S_BCM1480_MC_CS01_BANK2 16
+#define M_BCM1480_MC_CS01_BANK2 _SB_MAKEMASK(6,S_BCM1480_MC_CS01_BANK2)
+#define V_BCM1480_MC_CS01_BANK2(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CS01_BANK2)
+#define G_BCM1480_MC_CS01_BANK2(x) _SB_GETVALUE(x,S_BCM1480_MC_CS01_BANK2,M_BCM1480_MC_CS01_BANK2)
+
+/*
+ * CS2 and CS3 Bank Address Bit Select Register (Table 89)
+ */
+
+#define S_BCM1480_MC_CS23_BANK0 0
+#define M_BCM1480_MC_CS23_BANK0 _SB_MAKEMASK(6,S_BCM1480_MC_CS23_BANK0)
+#define V_BCM1480_MC_CS23_BANK0(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CS23_BANK0)
+#define G_BCM1480_MC_CS23_BANK0(x) _SB_GETVALUE(x,S_BCM1480_MC_CS23_BANK0,M_BCM1480_MC_CS23_BANK0)
+
+#define S_BCM1480_MC_CS23_BANK1 8
+#define M_BCM1480_MC_CS23_BANK1 _SB_MAKEMASK(6,S_BCM1480_MC_CS23_BANK1)
+#define V_BCM1480_MC_CS23_BANK1(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CS23_BANK1)
+#define G_BCM1480_MC_CS23_BANK1(x) _SB_GETVALUE(x,S_BCM1480_MC_CS23_BANK1,M_BCM1480_MC_CS23_BANK1)
+
+#define S_BCM1480_MC_CS23_BANK2 16
+#define M_BCM1480_MC_CS23_BANK2 _SB_MAKEMASK(6,S_BCM1480_MC_CS23_BANK2)
+#define V_BCM1480_MC_CS23_BANK2(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CS23_BANK2)
+#define G_BCM1480_MC_CS23_BANK2(x) _SB_GETVALUE(x,S_BCM1480_MC_CS23_BANK2,M_BCM1480_MC_CS23_BANK2)
+
+#define K_BCM1480_MC_CSXX_BANKX_BIT_SPACING 8
+
+/*
+ * DRAM Command Register (Table 90)
+ */
+
+#define S_BCM1480_MC_COMMAND 0
+#define M_BCM1480_MC_COMMAND _SB_MAKEMASK(4,S_BCM1480_MC_COMMAND)
+#define V_BCM1480_MC_COMMAND(x) _SB_MAKEVALUE(x,S_BCM1480_MC_COMMAND)
+#define G_BCM1480_MC_COMMAND(x) _SB_GETVALUE(x,S_BCM1480_MC_COMMAND,M_BCM1480_MC_COMMAND)
+
+#define K_BCM1480_MC_COMMAND_EMRS 0
+#define K_BCM1480_MC_COMMAND_MRS 1
+#define K_BCM1480_MC_COMMAND_PRE 2
+#define K_BCM1480_MC_COMMAND_AR 3
+#define K_BCM1480_MC_COMMAND_SETRFSH 4
+#define K_BCM1480_MC_COMMAND_CLRRFSH 5
+#define K_BCM1480_MC_COMMAND_SETPWRDN 6
+#define K_BCM1480_MC_COMMAND_CLRPWRDN 7
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define K_BCM1480_MC_COMMAND_EMRS2 8
+#define K_BCM1480_MC_COMMAND_EMRS3 9
+#define K_BCM1480_MC_COMMAND_ENABLE_MCLK 10
+#define K_BCM1480_MC_COMMAND_DISABLE_MCLK 11
+#endif
+
+#define V_BCM1480_MC_COMMAND_EMRS V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_EMRS)
+#define V_BCM1480_MC_COMMAND_MRS V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_MRS)
+#define V_BCM1480_MC_COMMAND_PRE V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_PRE)
+#define V_BCM1480_MC_COMMAND_AR V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_AR)
+#define V_BCM1480_MC_COMMAND_SETRFSH V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_SETRFSH)
+#define V_BCM1480_MC_COMMAND_CLRRFSH V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_CLRRFSH)
+#define V_BCM1480_MC_COMMAND_SETPWRDN V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_SETPWRDN)
+#define V_BCM1480_MC_COMMAND_CLRPWRDN V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_CLRPWRDN)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define V_BCM1480_MC_COMMAND_EMRS2 V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_EMRS2)
+#define V_BCM1480_MC_COMMAND_EMRS3 V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_EMRS3)
+#define V_BCM1480_MC_COMMAND_ENABLE_MCLK V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_ENABLE_MCLK)
+#define V_BCM1480_MC_COMMAND_DISABLE_MCLK V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_DISABLE_MCLK)
+#endif
+
+#define S_BCM1480_MC_CS0 4
+#define M_BCM1480_MC_CS0 _SB_MAKEMASK1(4)
+#define M_BCM1480_MC_CS1 _SB_MAKEMASK1(5)
+#define M_BCM1480_MC_CS2 _SB_MAKEMASK1(6)
+#define M_BCM1480_MC_CS3 _SB_MAKEMASK1(7)
+#define M_BCM1480_MC_CS4 _SB_MAKEMASK1(8)
+#define M_BCM1480_MC_CS5 _SB_MAKEMASK1(9)
+#define M_BCM1480_MC_CS6 _SB_MAKEMASK1(10)
+#define M_BCM1480_MC_CS7 _SB_MAKEMASK1(11)
+
+#define M_BCM1480_MC_CMD_ACTIVE _SB_MAKEMASK1(16)
+
+/*
+ * DRAM Mode Register (Table 91)
+ */
+
+#define S_BCM1480_MC_EMODE 0
+#define M_BCM1480_MC_EMODE _SB_MAKEMASK(15,S_BCM1480_MC_EMODE)
+#define V_BCM1480_MC_EMODE(x) _SB_MAKEVALUE(x,S_BCM1480_MC_EMODE)
+#define G_BCM1480_MC_EMODE(x) _SB_GETVALUE(x,S_BCM1480_MC_EMODE,M_BCM1480_MC_EMODE)
+#define V_BCM1480_MC_EMODE_DEFAULT V_BCM1480_MC_EMODE(0)
+
+#define S_BCM1480_MC_MODE 16
+#define M_BCM1480_MC_MODE _SB_MAKEMASK(15,S_BCM1480_MC_MODE)
+#define V_BCM1480_MC_MODE(x) _SB_MAKEVALUE(x,S_BCM1480_MC_MODE)
+#define G_BCM1480_MC_MODE(x) _SB_GETVALUE(x,S_BCM1480_MC_MODE,M_BCM1480_MC_MODE)
+#define V_BCM1480_MC_MODE_DEFAULT V_BCM1480_MC_MODE(0)
+
+#define S_BCM1480_MC_DRAM_TYPE 32
+#define M_BCM1480_MC_DRAM_TYPE _SB_MAKEMASK(4,S_BCM1480_MC_DRAM_TYPE)
+#define V_BCM1480_MC_DRAM_TYPE(x) _SB_MAKEVALUE(x,S_BCM1480_MC_DRAM_TYPE)
+#define G_BCM1480_MC_DRAM_TYPE(x) _SB_GETVALUE(x,S_BCM1480_MC_DRAM_TYPE,M_BCM1480_MC_DRAM_TYPE)
+
+#define K_BCM1480_MC_DRAM_TYPE_JEDEC 0
+#define K_BCM1480_MC_DRAM_TYPE_FCRAM 1
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define K_BCM1480_MC_DRAM_TYPE_DDR2 2
+#endif
+
+#define V_BCM1480_MC_DRAM_TYPE_JEDEC V_BCM1480_MC_DRAM_TYPE(K_BCM1480_MC_DRAM_TYPE_JEDEC)
+#define V_BCM1480_MC_DRAM_TYPE_FCRAM V_BCM1480_MC_DRAM_TYPE(K_BCM1480_MC_DRAM_TYPE_FCRAM)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define V_BCM1480_MC_DRAM_TYPE_DDR2 V_BCM1480_MC_DRAM_TYPE(K_BCM1480_MC_DRAM_TYPE_DDR2)
+#endif
+
+#define M_BCM1480_MC_GANGED _SB_MAKEMASK1(36)
+#define M_BCM1480_MC_BY9_INTF _SB_MAKEMASK1(37)
+#define M_BCM1480_MC_FORCE_ECC64 _SB_MAKEMASK1(38)
+#define M_BCM1480_MC_ECC_DISABLE _SB_MAKEMASK1(39)
+
+#define S_BCM1480_MC_PG_POLICY 40
+#define M_BCM1480_MC_PG_POLICY _SB_MAKEMASK(2,S_BCM1480_MC_PG_POLICY)
+#define V_BCM1480_MC_PG_POLICY(x) _SB_MAKEVALUE(x,S_BCM1480_MC_PG_POLICY)
+#define G_BCM1480_MC_PG_POLICY(x) _SB_GETVALUE(x,S_BCM1480_MC_PG_POLICY,M_BCM1480_MC_PG_POLICY)
+
+#define K_BCM1480_MC_PG_POLICY_CLOSED 0
+#define K_BCM1480_MC_PG_POLICY_CAS_TIME_CHK 1
+
+#define V_BCM1480_MC_PG_POLICY_CLOSED V_BCM1480_MC_PG_POLICY(K_BCM1480_MC_PG_POLICY_CLOSED)
+#define V_BCM1480_MC_PG_POLICY_CAS_TIME_CHK V_BCM1480_MC_PG_POLICY(K_BCM1480_MC_PG_POLICY_CAS_TIME_CHK)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define M_BCM1480_MC_2T_CMD _SB_MAKEMASK1(42)
+#define M_BCM1480_MC_ECC_COR_DIS _SB_MAKEMASK1(43)
+#endif
+
+#define V_BCM1480_MC_DRAMMODE_DEFAULT V_BCM1480_MC_EMODE_DEFAULT | V_BCM1480_MC_MODE_DEFAULT | V_BCM1480_MC_DRAM_TYPE_JEDEC | \
+ V_BCM1480_MC_PG_POLICY(K_BCM1480_MC_PG_POLICY_CAS_TIME_CHK)
+
+/*
+ * Memory Clock Configuration Register (Table 92)
+ */
+
+#define S_BCM1480_MC_CLK_RATIO 0
+#define M_BCM1480_MC_CLK_RATIO _SB_MAKEMASK(6,S_BCM1480_MC_CLK_RATIO)
+#define V_BCM1480_MC_CLK_RATIO(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CLK_RATIO)
+#define G_BCM1480_MC_CLK_RATIO(x) _SB_GETVALUE(x,S_BCM1480_MC_CLK_RATIO,M_BCM1480_MC_CLK_RATIO)
+
+#define V_BCM1480_MC_CLK_RATIO_DEFAULT V_BCM1480_MC_CLK_RATIO(10)
+
+#define S_BCM1480_MC_REF_RATE 8
+#define M_BCM1480_MC_REF_RATE _SB_MAKEMASK(8,S_BCM1480_MC_REF_RATE)
+#define V_BCM1480_MC_REF_RATE(x) _SB_MAKEVALUE(x,S_BCM1480_MC_REF_RATE)
+#define G_BCM1480_MC_REF_RATE(x) _SB_GETVALUE(x,S_BCM1480_MC_REF_RATE,M_BCM1480_MC_REF_RATE)
+
+#define K_BCM1480_MC_REF_RATE_100MHz 0x31
+#define K_BCM1480_MC_REF_RATE_200MHz 0x62
+#define K_BCM1480_MC_REF_RATE_400MHz 0xC4
+
+#define V_BCM1480_MC_REF_RATE_100MHz V_BCM1480_MC_REF_RATE(K_BCM1480_MC_REF_RATE_100MHz)
+#define V_BCM1480_MC_REF_RATE_200MHz V_BCM1480_MC_REF_RATE(K_BCM1480_MC_REF_RATE_200MHz)
+#define V_BCM1480_MC_REF_RATE_400MHz V_BCM1480_MC_REF_RATE(K_BCM1480_MC_REF_RATE_400MHz)
+#define V_BCM1480_MC_REF_RATE_DEFAULT V_BCM1480_MC_REF_RATE_400MHz
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define M_BCM1480_MC_AUTO_REF_DIS _SB_MAKEMASK1(16)
+#endif
+
+/*
+ * ODT Register (Table 99)
+ */
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define M_BCM1480_MC_RD_ODT0_CS0 _SB_MAKEMASK1(0)
+#define M_BCM1480_MC_RD_ODT0_CS2 _SB_MAKEMASK1(1)
+#define M_BCM1480_MC_RD_ODT0_CS4 _SB_MAKEMASK1(2)
+#define M_BCM1480_MC_RD_ODT0_CS6 _SB_MAKEMASK1(3)
+#define M_BCM1480_MC_WR_ODT0_CS0 _SB_MAKEMASK1(4)
+#define M_BCM1480_MC_WR_ODT0_CS2 _SB_MAKEMASK1(5)
+#define M_BCM1480_MC_WR_ODT0_CS4 _SB_MAKEMASK1(6)
+#define M_BCM1480_MC_WR_ODT0_CS6 _SB_MAKEMASK1(7)
+#define M_BCM1480_MC_RD_ODT2_CS0 _SB_MAKEMASK1(8)
+#define M_BCM1480_MC_RD_ODT2_CS2 _SB_MAKEMASK1(9)
+#define M_BCM1480_MC_RD_ODT2_CS4 _SB_MAKEMASK1(10)
+#define M_BCM1480_MC_RD_ODT2_CS6 _SB_MAKEMASK1(11)
+#define M_BCM1480_MC_WR_ODT2_CS0 _SB_MAKEMASK1(12)
+#define M_BCM1480_MC_WR_ODT2_CS2 _SB_MAKEMASK1(13)
+#define M_BCM1480_MC_WR_ODT2_CS4 _SB_MAKEMASK1(14)
+#define M_BCM1480_MC_WR_ODT2_CS6 _SB_MAKEMASK1(15)
+#define M_BCM1480_MC_RD_ODT4_CS0 _SB_MAKEMASK1(16)
+#define M_BCM1480_MC_RD_ODT4_CS2 _SB_MAKEMASK1(17)
+#define M_BCM1480_MC_RD_ODT4_CS4 _SB_MAKEMASK1(18)
+#define M_BCM1480_MC_RD_ODT4_CS6 _SB_MAKEMASK1(19)
+#define M_BCM1480_MC_WR_ODT4_CS0 _SB_MAKEMASK1(20)
+#define M_BCM1480_MC_WR_ODT4_CS2 _SB_MAKEMASK1(21)
+#define M_BCM1480_MC_WR_ODT4_CS4 _SB_MAKEMASK1(22)
+#define M_BCM1480_MC_WR_ODT4_CS6 _SB_MAKEMASK1(23)
+#define M_BCM1480_MC_RD_ODT6_CS0 _SB_MAKEMASK1(24)
+#define M_BCM1480_MC_RD_ODT6_CS2 _SB_MAKEMASK1(25)
+#define M_BCM1480_MC_RD_ODT6_CS4 _SB_MAKEMASK1(26)
+#define M_BCM1480_MC_RD_ODT6_CS6 _SB_MAKEMASK1(27)
+#define M_BCM1480_MC_WR_ODT6_CS0 _SB_MAKEMASK1(28)
+#define M_BCM1480_MC_WR_ODT6_CS2 _SB_MAKEMASK1(29)
+#define M_BCM1480_MC_WR_ODT6_CS4 _SB_MAKEMASK1(30)
+#define M_BCM1480_MC_WR_ODT6_CS6 _SB_MAKEMASK1(31)
+
+#define M_BCM1480_MC_CS_ODD_ODT_EN _SB_MAKEMASK1(32)
+#endif
+
+/*
+ * Memory DLL Configuration Register (Table 93)
+ */
+
+#define S_BCM1480_MC_ADDR_COARSE_ADJ 0
+#define M_BCM1480_MC_ADDR_COARSE_ADJ _SB_MAKEMASK(6,S_BCM1480_MC_ADDR_COARSE_ADJ)
+#define V_BCM1480_MC_ADDR_COARSE_ADJ(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ADDR_COARSE_ADJ)
+#define G_BCM1480_MC_ADDR_COARSE_ADJ(x) _SB_GETVALUE(x,S_BCM1480_MC_ADDR_COARSE_ADJ,M_BCM1480_MC_ADDR_COARSE_ADJ)
+#define V_BCM1480_MC_ADDR_COARSE_ADJ_DEFAULT V_BCM1480_MC_ADDR_COARSE_ADJ(0x0)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define S_BCM1480_MC_ADDR_FREQ_RANGE 8
+#define M_BCM1480_MC_ADDR_FREQ_RANGE _SB_MAKEMASK(4,S_BCM1480_MC_ADDR_FREQ_RANGE)
+#define V_BCM1480_MC_ADDR_FREQ_RANGE(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ADDR_FREQ_RANGE)
+#define G_BCM1480_MC_ADDR_FREQ_RANGE(x) _SB_GETVALUE(x,S_BCM1480_MC_ADDR_FREQ_RANGE,M_BCM1480_MC_ADDR_FREQ_RANGE)
+#define V_BCM1480_MC_ADDR_FREQ_RANGE_DEFAULT V_BCM1480_MC_ADDR_FREQ_RANGE(0x4)
+#endif
+
+#define S_BCM1480_MC_ADDR_FINE_ADJ 8
+#define M_BCM1480_MC_ADDR_FINE_ADJ _SB_MAKEMASK(4,S_BCM1480_MC_ADDR_FINE_ADJ)
+#define V_BCM1480_MC_ADDR_FINE_ADJ(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ADDR_FINE_ADJ)
+#define G_BCM1480_MC_ADDR_FINE_ADJ(x) _SB_GETVALUE(x,S_BCM1480_MC_ADDR_FINE_ADJ,M_BCM1480_MC_ADDR_FINE_ADJ)
+#define V_BCM1480_MC_ADDR_FINE_ADJ_DEFAULT V_BCM1480_MC_ADDR_FINE_ADJ(0x8)
+
+#define S_BCM1480_MC_DQI_COARSE_ADJ 16
+#define M_BCM1480_MC_DQI_COARSE_ADJ _SB_MAKEMASK(6,S_BCM1480_MC_DQI_COARSE_ADJ)
+#define V_BCM1480_MC_DQI_COARSE_ADJ(x) _SB_MAKEVALUE(x,S_BCM1480_MC_DQI_COARSE_ADJ)
+#define G_BCM1480_MC_DQI_COARSE_ADJ(x) _SB_GETVALUE(x,S_BCM1480_MC_DQI_COARSE_ADJ,M_BCM1480_MC_DQI_COARSE_ADJ)
+#define V_BCM1480_MC_DQI_COARSE_ADJ_DEFAULT V_BCM1480_MC_DQI_COARSE_ADJ(0x0)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define S_BCM1480_MC_DQI_FREQ_RANGE 24
+#define M_BCM1480_MC_DQI_FREQ_RANGE _SB_MAKEMASK(4,S_BCM1480_MC_DQI_FREQ_RANGE)
+#define V_BCM1480_MC_DQI_FREQ_RANGE(x) _SB_MAKEVALUE(x,S_BCM1480_MC_DQI_FREQ_RANGE)
+#define G_BCM1480_MC_DQI_FREQ_RANGE(x) _SB_GETVALUE(x,S_BCM1480_MC_DQI_FREQ_RANGE,M_BCM1480_MC_DQI_FREQ_RANGE)
+#define V_BCM1480_MC_DQI_FREQ_RANGE_DEFAULT V_BCM1480_MC_DQI_FREQ_RANGE(0x4)
+#endif
+
+#define S_BCM1480_MC_DQI_FINE_ADJ 24
+#define M_BCM1480_MC_DQI_FINE_ADJ _SB_MAKEMASK(4,S_BCM1480_MC_DQI_FINE_ADJ)
+#define V_BCM1480_MC_DQI_FINE_ADJ(x) _SB_MAKEVALUE(x,S_BCM1480_MC_DQI_FINE_ADJ)
+#define G_BCM1480_MC_DQI_FINE_ADJ(x) _SB_GETVALUE(x,S_BCM1480_MC_DQI_FINE_ADJ,M_BCM1480_MC_DQI_FINE_ADJ)
+#define V_BCM1480_MC_DQI_FINE_ADJ_DEFAULT V_BCM1480_MC_DQI_FINE_ADJ(0x8)
+
+#define S_BCM1480_MC_DQO_COARSE_ADJ 32
+#define M_BCM1480_MC_DQO_COARSE_ADJ _SB_MAKEMASK(6,S_BCM1480_MC_DQO_COARSE_ADJ)
+#define V_BCM1480_MC_DQO_COARSE_ADJ(x) _SB_MAKEVALUE(x,S_BCM1480_MC_DQO_COARSE_ADJ)
+#define G_BCM1480_MC_DQO_COARSE_ADJ(x) _SB_GETVALUE(x,S_BCM1480_MC_DQO_COARSE_ADJ,M_BCM1480_MC_DQO_COARSE_ADJ)
+#define V_BCM1480_MC_DQO_COARSE_ADJ_DEFAULT V_BCM1480_MC_DQO_COARSE_ADJ(0x0)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define S_BCM1480_MC_DQO_FREQ_RANGE 40
+#define M_BCM1480_MC_DQO_FREQ_RANGE _SB_MAKEMASK(4,S_BCM1480_MC_DQO_FREQ_RANGE)
+#define V_BCM1480_MC_DQO_FREQ_RANGE(x) _SB_MAKEVALUE(x,S_BCM1480_MC_DQO_FREQ_RANGE)
+#define G_BCM1480_MC_DQO_FREQ_RANGE(x) _SB_GETVALUE(x,S_BCM1480_MC_DQO_FREQ_RANGE,M_BCM1480_MC_DQO_FREQ_RANGE)
+#define V_BCM1480_MC_DQO_FREQ_RANGE_DEFAULT V_BCM1480_MC_DQO_FREQ_RANGE(0x4)
+#endif
+
+#define S_BCM1480_MC_DQO_FINE_ADJ 40
+#define M_BCM1480_MC_DQO_FINE_ADJ _SB_MAKEMASK(4,S_BCM1480_MC_DQO_FINE_ADJ)
+#define V_BCM1480_MC_DQO_FINE_ADJ(x) _SB_MAKEVALUE(x,S_BCM1480_MC_DQO_FINE_ADJ)
+#define G_BCM1480_MC_DQO_FINE_ADJ(x) _SB_GETVALUE(x,S_BCM1480_MC_DQO_FINE_ADJ,M_BCM1480_MC_DQO_FINE_ADJ)
+#define V_BCM1480_MC_DQO_FINE_ADJ_DEFAULT V_BCM1480_MC_DQO_FINE_ADJ(0x8)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define S_BCM1480_MC_DLL_PDSEL 44
+#define M_BCM1480_MC_DLL_PDSEL _SB_MAKEMASK(2,S_BCM1480_MC_DLL_PDSEL)
+#define V_BCM1480_MC_DLL_PDSEL(x) _SB_MAKEVALUE(x,S_BCM1480_MC_DLL_PDSEL)
+#define G_BCM1480_MC_DLL_PDSEL(x) _SB_GETVALUE(x,S_BCM1480_MC_DLL_PDSEL,M_BCM1480_MC_DLL_PDSEL)
+#define V_BCM1480_MC_DLL_DEFAULT_PDSEL V_BCM1480_MC_DLL_PDSEL(0x0)
+
+#define M_BCM1480_MC_DLL_REGBYPASS _SB_MAKEMASK1(46)
+#define M_BCM1480_MC_DQO_SHIFT _SB_MAKEMASK1(47)
+#endif
+
+#define S_BCM1480_MC_DLL_DEFAULT 48
+#define M_BCM1480_MC_DLL_DEFAULT _SB_MAKEMASK(6,S_BCM1480_MC_DLL_DEFAULT)
+#define V_BCM1480_MC_DLL_DEFAULT(x) _SB_MAKEVALUE(x,S_BCM1480_MC_DLL_DEFAULT)
+#define G_BCM1480_MC_DLL_DEFAULT(x) _SB_GETVALUE(x,S_BCM1480_MC_DLL_DEFAULT,M_BCM1480_MC_DLL_DEFAULT)
+#define V_BCM1480_MC_DLL_DEFAULT_DEFAULT V_BCM1480_MC_DLL_DEFAULT(0x10)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define S_BCM1480_MC_DLL_REGCTRL 54
+#define M_BCM1480_MC_DLL_REGCTRL _SB_MAKEMASK(2,S_BCM1480_MC_DLL_REGCTRL)
+#define V_BCM1480_MC_DLL_REGCTRL(x) _SB_MAKEVALUE(x,S_BCM1480_MC_DLL_REGCTRL)
+#define G_BCM1480_MC_DLL_REGCTRL(x) _SB_GETVALUE(x,S_BCM1480_MC_DLL_REGCTRL,M_BCM1480_MC_DLL_REGCTRL)
+#define V_BCM1480_MC_DLL_DEFAULT_REGCTRL V_BCM1480_MC_DLL_REGCTRL(0x0)
+#endif
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define S_BCM1480_MC_DLL_FREQ_RANGE 56
+#define M_BCM1480_MC_DLL_FREQ_RANGE _SB_MAKEMASK(4,S_BCM1480_MC_DLL_FREQ_RANGE)
+#define V_BCM1480_MC_DLL_FREQ_RANGE(x) _SB_MAKEVALUE(x,S_BCM1480_MC_DLL_FREQ_RANGE)
+#define G_BCM1480_MC_DLL_FREQ_RANGE(x) _SB_GETVALUE(x,S_BCM1480_MC_DLL_FREQ_RANGE,M_BCM1480_MC_DLL_FREQ_RANGE)
+#define V_BCM1480_MC_DLL_FREQ_RANGE_DEFAULT V_BCM1480_MC_DLL_FREQ_RANGE(0x4)
+#endif
+
+#define S_BCM1480_MC_DLL_STEP_SIZE 56
+#define M_BCM1480_MC_DLL_STEP_SIZE _SB_MAKEMASK(4,S_BCM1480_MC_DLL_STEP_SIZE)
+#define V_BCM1480_MC_DLL_STEP_SIZE(x) _SB_MAKEVALUE(x,S_BCM1480_MC_DLL_STEP_SIZE)
+#define G_BCM1480_MC_DLL_STEP_SIZE(x) _SB_GETVALUE(x,S_BCM1480_MC_DLL_STEP_SIZE,M_BCM1480_MC_DLL_STEP_SIZE)
+#define V_BCM1480_MC_DLL_STEP_SIZE_DEFAULT V_BCM1480_MC_DLL_STEP_SIZE(0x8)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define S_BCM1480_MC_DLL_BGCTRL 60
+#define M_BCM1480_MC_DLL_BGCTRL _SB_MAKEMASK(2,S_BCM1480_MC_DLL_BGCTRL)
+#define V_BCM1480_MC_DLL_BGCTRL(x) _SB_MAKEVALUE(x,S_BCM1480_MC_DLL_BGCTRL)
+#define G_BCM1480_MC_DLL_BGCTRL(x) _SB_GETVALUE(x,S_BCM1480_MC_DLL_BGCTRL,M_BCM1480_MC_DLL_BGCTRL)
+#define V_BCM1480_MC_DLL_DEFAULT_BGCTRL V_BCM1480_MC_DLL_BGCTRL(0x0)
+#endif
+
+#define M_BCM1480_MC_DLL_BYPASS _SB_MAKEMASK1(63)
+
+/*
+ * Memory Drive Configuration Register (Table 94)
+ */
+
+#define S_BCM1480_MC_RTT_BYP_PULLDOWN 0
+#define M_BCM1480_MC_RTT_BYP_PULLDOWN _SB_MAKEMASK(3,S_BCM1480_MC_RTT_BYP_PULLDOWN)
+#define V_BCM1480_MC_RTT_BYP_PULLDOWN(x) _SB_MAKEVALUE(x,S_BCM1480_MC_RTT_BYP_PULLDOWN)
+#define G_BCM1480_MC_RTT_BYP_PULLDOWN(x) _SB_GETVALUE(x,S_BCM1480_MC_RTT_BYP_PULLDOWN,M_BCM1480_MC_RTT_BYP_PULLDOWN)
+
+#define S_BCM1480_MC_RTT_BYP_PULLUP 6
+#define M_BCM1480_MC_RTT_BYP_PULLUP _SB_MAKEMASK(3,S_BCM1480_MC_RTT_BYP_PULLUP)
+#define V_BCM1480_MC_RTT_BYP_PULLUP(x) _SB_MAKEVALUE(x,S_BCM1480_MC_RTT_BYP_PULLUP)
+#define G_BCM1480_MC_RTT_BYP_PULLUP(x) _SB_GETVALUE(x,S_BCM1480_MC_RTT_BYP_PULLUP,M_BCM1480_MC_RTT_BYP_PULLUP)
+
+#define M_BCM1480_MC_RTT_BYPASS _SB_MAKEMASK1(8)
+#define M_BCM1480_MC_RTT_COMP_MOV_AVG _SB_MAKEMASK1(9)
+
+#define S_BCM1480_MC_PVT_BYP_C1_PULLDOWN 10
+#define M_BCM1480_MC_PVT_BYP_C1_PULLDOWN _SB_MAKEMASK(4,S_BCM1480_MC_PVT_BYP_C1_PULLDOWN)
+#define V_BCM1480_MC_PVT_BYP_C1_PULLDOWN(x) _SB_MAKEVALUE(x,S_BCM1480_MC_PVT_BYP_C1_PULLDOWN)
+#define G_BCM1480_MC_PVT_BYP_C1_PULLDOWN(x) _SB_GETVALUE(x,S_BCM1480_MC_PVT_BYP_C1_PULLDOWN,M_BCM1480_MC_PVT_BYP_C1_PULLDOWN)
+
+#define S_BCM1480_MC_PVT_BYP_C1_PULLUP 15
+#define M_BCM1480_MC_PVT_BYP_C1_PULLUP _SB_MAKEMASK(4,S_BCM1480_MC_PVT_BYP_C1_PULLUP)
+#define V_BCM1480_MC_PVT_BYP_C1_PULLUP(x) _SB_MAKEVALUE(x,S_BCM1480_MC_PVT_BYP_C1_PULLUP)
+#define G_BCM1480_MC_PVT_BYP_C1_PULLUP(x) _SB_GETVALUE(x,S_BCM1480_MC_PVT_BYP_C1_PULLUP,M_BCM1480_MC_PVT_BYP_C1_PULLUP)
+
+#define S_BCM1480_MC_PVT_BYP_C2_PULLDOWN 20
+#define M_BCM1480_MC_PVT_BYP_C2_PULLDOWN _SB_MAKEMASK(4,S_BCM1480_MC_PVT_BYP_C2_PULLDOWN)
+#define V_BCM1480_MC_PVT_BYP_C2_PULLDOWN(x) _SB_MAKEVALUE(x,S_BCM1480_MC_PVT_BYP_C2_PULLDOWN)
+#define G_BCM1480_MC_PVT_BYP_C2_PULLDOWN(x) _SB_GETVALUE(x,S_BCM1480_MC_PVT_BYP_C2_PULLDOWN,M_BCM1480_MC_PVT_BYP_C2_PULLDOWN)
+
+#define S_BCM1480_MC_PVT_BYP_C2_PULLUP 25
+#define M_BCM1480_MC_PVT_BYP_C2_PULLUP _SB_MAKEMASK(4,S_BCM1480_MC_PVT_BYP_C2_PULLUP)
+#define V_BCM1480_MC_PVT_BYP_C2_PULLUP(x) _SB_MAKEVALUE(x,S_BCM1480_MC_PVT_BYP_C2_PULLUP)
+#define G_BCM1480_MC_PVT_BYP_C2_PULLUP(x) _SB_GETVALUE(x,S_BCM1480_MC_PVT_BYP_C2_PULLUP,M_BCM1480_MC_PVT_BYP_C2_PULLUP)
+
+#define M_BCM1480_MC_PVT_BYPASS _SB_MAKEMASK1(30)
+#define M_BCM1480_MC_PVT_COMP_MOV_AVG _SB_MAKEMASK1(31)
+
+#define M_BCM1480_MC_CLK_CLASS _SB_MAKEMASK1(34)
+#define M_BCM1480_MC_DATA_CLASS _SB_MAKEMASK1(35)
+#define M_BCM1480_MC_ADDR_CLASS _SB_MAKEMASK1(36)
+
+#define M_BCM1480_MC_DQ_ODT_75 _SB_MAKEMASK1(37)
+#define M_BCM1480_MC_DQ_ODT_150 _SB_MAKEMASK1(38)
+#define M_BCM1480_MC_DQS_ODT_75 _SB_MAKEMASK1(39)
+#define M_BCM1480_MC_DQS_ODT_150 _SB_MAKEMASK1(40)
+#define M_BCM1480_MC_DQS_DIFF _SB_MAKEMASK1(41)
+
+/*
+ * ECC Test Data Register (Table 95)
+ */
+
+#define S_BCM1480_MC_DATA_INVERT 0
+#define M_DATA_ECC_INVERT _SB_MAKEMASK(64,S_BCM1480_MC_ECC_INVERT)
+
+/*
+ * ECC Test ECC Register (Table 96)
+ */
+
+#define S_BCM1480_MC_ECC_INVERT 0
+#define M_BCM1480_MC_ECC_INVERT _SB_MAKEMASK(8,S_BCM1480_MC_ECC_INVERT)
+
+/*
+ * SDRAM Timing Register (Table 97)
+ */
+
+#define S_BCM1480_MC_tRCD 0
+#define M_BCM1480_MC_tRCD _SB_MAKEMASK(4,S_BCM1480_MC_tRCD)
+#define V_BCM1480_MC_tRCD(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tRCD)
+#define G_BCM1480_MC_tRCD(x) _SB_GETVALUE(x,S_BCM1480_MC_tRCD,M_BCM1480_MC_tRCD)
+#define K_BCM1480_MC_tRCD_DEFAULT 3
+#define V_BCM1480_MC_tRCD_DEFAULT V_BCM1480_MC_tRCD(K_BCM1480_MC_tRCD_DEFAULT)
+
+#define S_BCM1480_MC_tCL 4
+#define M_BCM1480_MC_tCL _SB_MAKEMASK(4,S_BCM1480_MC_tCL)
+#define V_BCM1480_MC_tCL(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tCL)
+#define G_BCM1480_MC_tCL(x) _SB_GETVALUE(x,S_BCM1480_MC_tCL,M_BCM1480_MC_tCL)
+#define K_BCM1480_MC_tCL_DEFAULT 2
+#define V_BCM1480_MC_tCL_DEFAULT V_BCM1480_MC_tCL(K_BCM1480_MC_tCL_DEFAULT)
+
+#define M_BCM1480_MC_tCrDh _SB_MAKEMASK1(8)
+
+#define S_BCM1480_MC_tWR 9
+#define M_BCM1480_MC_tWR _SB_MAKEMASK(3,S_BCM1480_MC_tWR)
+#define V_BCM1480_MC_tWR(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tWR)
+#define G_BCM1480_MC_tWR(x) _SB_GETVALUE(x,S_BCM1480_MC_tWR,M_BCM1480_MC_tWR)
+#define K_BCM1480_MC_tWR_DEFAULT 2
+#define V_BCM1480_MC_tWR_DEFAULT V_BCM1480_MC_tWR(K_BCM1480_MC_tWR_DEFAULT)
+
+#define S_BCM1480_MC_tCwD 12
+#define M_BCM1480_MC_tCwD _SB_MAKEMASK(4,S_BCM1480_MC_tCwD)
+#define V_BCM1480_MC_tCwD(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tCwD)
+#define G_BCM1480_MC_tCwD(x) _SB_GETVALUE(x,S_BCM1480_MC_tCwD,M_BCM1480_MC_tCwD)
+#define K_BCM1480_MC_tCwD_DEFAULT 1
+#define V_BCM1480_MC_tCwD_DEFAULT V_BCM1480_MC_tCwD(K_BCM1480_MC_tCwD_DEFAULT)
+
+#define S_BCM1480_MC_tRP 16
+#define M_BCM1480_MC_tRP _SB_MAKEMASK(4,S_BCM1480_MC_tRP)
+#define V_BCM1480_MC_tRP(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tRP)
+#define G_BCM1480_MC_tRP(x) _SB_GETVALUE(x,S_BCM1480_MC_tRP,M_BCM1480_MC_tRP)
+#define K_BCM1480_MC_tRP_DEFAULT 4
+#define V_BCM1480_MC_tRP_DEFAULT V_BCM1480_MC_tRP(K_BCM1480_MC_tRP_DEFAULT)
+
+#define S_BCM1480_MC_tRRD 20
+#define M_BCM1480_MC_tRRD _SB_MAKEMASK(4,S_BCM1480_MC_tRRD)
+#define V_BCM1480_MC_tRRD(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tRRD)
+#define G_BCM1480_MC_tRRD(x) _SB_GETVALUE(x,S_BCM1480_MC_tRRD,M_BCM1480_MC_tRRD)
+#define K_BCM1480_MC_tRRD_DEFAULT 2
+#define V_BCM1480_MC_tRRD_DEFAULT V_BCM1480_MC_tRRD(K_BCM1480_MC_tRRD_DEFAULT)
+
+#define S_BCM1480_MC_tRCw 24
+#define M_BCM1480_MC_tRCw _SB_MAKEMASK(5,S_BCM1480_MC_tRCw)
+#define V_BCM1480_MC_tRCw(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tRCw)
+#define G_BCM1480_MC_tRCw(x) _SB_GETVALUE(x,S_BCM1480_MC_tRCw,M_BCM1480_MC_tRCw)
+#define K_BCM1480_MC_tRCw_DEFAULT 10
+#define V_BCM1480_MC_tRCw_DEFAULT V_BCM1480_MC_tRCw(K_BCM1480_MC_tRCw_DEFAULT)
+
+#define S_BCM1480_MC_tRCr 32
+#define M_BCM1480_MC_tRCr _SB_MAKEMASK(5,S_BCM1480_MC_tRCr)
+#define V_BCM1480_MC_tRCr(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tRCr)
+#define G_BCM1480_MC_tRCr(x) _SB_GETVALUE(x,S_BCM1480_MC_tRCr,M_BCM1480_MC_tRCr)
+#define K_BCM1480_MC_tRCr_DEFAULT 9
+#define V_BCM1480_MC_tRCr_DEFAULT V_BCM1480_MC_tRCr(K_BCM1480_MC_tRCr_DEFAULT)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define S_BCM1480_MC_tFAW 40
+#define M_BCM1480_MC_tFAW _SB_MAKEMASK(6,S_BCM1480_MC_tFAW)
+#define V_BCM1480_MC_tFAW(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tFAW)
+#define G_BCM1480_MC_tFAW(x) _SB_GETVALUE(x,S_BCM1480_MC_tFAW,M_BCM1480_MC_tFAW)
+#define K_BCM1480_MC_tFAW_DEFAULT 0
+#define V_BCM1480_MC_tFAW_DEFAULT V_BCM1480_MC_tFAW(K_BCM1480_MC_tFAW_DEFAULT)
+#endif
+
+#define S_BCM1480_MC_tRFC 48
+#define M_BCM1480_MC_tRFC _SB_MAKEMASK(7,S_BCM1480_MC_tRFC)
+#define V_BCM1480_MC_tRFC(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tRFC)
+#define G_BCM1480_MC_tRFC(x) _SB_GETVALUE(x,S_BCM1480_MC_tRFC,M_BCM1480_MC_tRFC)
+#define K_BCM1480_MC_tRFC_DEFAULT 12
+#define V_BCM1480_MC_tRFC_DEFAULT V_BCM1480_MC_tRFC(K_BCM1480_MC_tRFC_DEFAULT)
+
+#define S_BCM1480_MC_tFIFO 56
+#define M_BCM1480_MC_tFIFO _SB_MAKEMASK(2,S_BCM1480_MC_tFIFO)
+#define V_BCM1480_MC_tFIFO(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tFIFO)
+#define G_BCM1480_MC_tFIFO(x) _SB_GETVALUE(x,S_BCM1480_MC_tFIFO,M_BCM1480_MC_tFIFO)
+#define K_BCM1480_MC_tFIFO_DEFAULT 0
+#define V_BCM1480_MC_tFIFO_DEFAULT V_BCM1480_MC_tFIFO(K_BCM1480_MC_tFIFO_DEFAULT)
+
+#define S_BCM1480_MC_tW2R 58
+#define M_BCM1480_MC_tW2R _SB_MAKEMASK(2,S_BCM1480_MC_tW2R)
+#define V_BCM1480_MC_tW2R(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tW2R)
+#define G_BCM1480_MC_tW2R(x) _SB_GETVALUE(x,S_BCM1480_MC_tW2R,M_BCM1480_MC_tW2R)
+#define K_BCM1480_MC_tW2R_DEFAULT 1
+#define V_BCM1480_MC_tW2R_DEFAULT V_BCM1480_MC_tW2R(K_BCM1480_MC_tW2R_DEFAULT)
+
+#define S_BCM1480_MC_tR2W 60
+#define M_BCM1480_MC_tR2W _SB_MAKEMASK(2,S_BCM1480_MC_tR2W)
+#define V_BCM1480_MC_tR2W(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tR2W)
+#define G_BCM1480_MC_tR2W(x) _SB_GETVALUE(x,S_BCM1480_MC_tR2W,M_BCM1480_MC_tR2W)
+#define K_BCM1480_MC_tR2W_DEFAULT 0
+#define V_BCM1480_MC_tR2W_DEFAULT V_BCM1480_MC_tR2W(K_BCM1480_MC_tR2W_DEFAULT)
+
+#define M_BCM1480_MC_tR2R _SB_MAKEMASK1(62)
+
+#define V_BCM1480_MC_TIMING_DEFAULT (M_BCM1480_MC_tR2R | \
+ V_BCM1480_MC_tFIFO_DEFAULT | \
+ V_BCM1480_MC_tR2W_DEFAULT | \
+ V_BCM1480_MC_tW2R_DEFAULT | \
+ V_BCM1480_MC_tRFC_DEFAULT | \
+ V_BCM1480_MC_tRCr_DEFAULT | \
+ V_BCM1480_MC_tRCw_DEFAULT | \
+ V_BCM1480_MC_tRRD_DEFAULT | \
+ V_BCM1480_MC_tRP_DEFAULT | \
+ V_BCM1480_MC_tCwD_DEFAULT | \
+ V_BCM1480_MC_tWR_DEFAULT | \
+ M_BCM1480_MC_tCrDh | \
+ V_BCM1480_MC_tCL_DEFAULT | \
+ V_BCM1480_MC_tRCD_DEFAULT)
+
+/*
+ * SDRAM Timing Register 2
+ */
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+
+#define S_BCM1480_MC_tAL 0
+#define M_BCM1480_MC_tAL _SB_MAKEMASK(4,S_BCM1480_MC_tAL)
+#define V_BCM1480_MC_tAL(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tAL)
+#define G_BCM1480_MC_tAL(x) _SB_GETVALUE(x,S_BCM1480_MC_tAL,M_BCM1480_MC_tAL)
+#define K_BCM1480_MC_tAL_DEFAULT 0
+#define V_BCM1480_MC_tAL_DEFAULT V_BCM1480_MC_tAL(K_BCM1480_MC_tAL_DEFAULT)
+
+#define S_BCM1480_MC_tRTP 4
+#define M_BCM1480_MC_tRTP _SB_MAKEMASK(3,S_BCM1480_MC_tRTP)
+#define V_BCM1480_MC_tRTP(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tRTP)
+#define G_BCM1480_MC_tRTP(x) _SB_GETVALUE(x,S_BCM1480_MC_tRTP,M_BCM1480_MC_tRTP)
+#define K_BCM1480_MC_tRTP_DEFAULT 2
+#define V_BCM1480_MC_tRTP_DEFAULT V_BCM1480_MC_tRTP(K_BCM1480_MC_tRTP_DEFAULT)
+
+#define S_BCM1480_MC_tW2W 8
+#define M_BCM1480_MC_tW2W _SB_MAKEMASK(2,S_BCM1480_MC_tW2W)
+#define V_BCM1480_MC_tW2W(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tW2W)
+#define G_BCM1480_MC_tW2W(x) _SB_GETVALUE(x,S_BCM1480_MC_tW2W,M_BCM1480_MC_tW2W)
+#define K_BCM1480_MC_tW2W_DEFAULT 0
+#define V_BCM1480_MC_tW2W_DEFAULT V_BCM1480_MC_tW2W(K_BCM1480_MC_tW2W_DEFAULT)
+
+#define S_BCM1480_MC_tRAP 12
+#define M_BCM1480_MC_tRAP _SB_MAKEMASK(4,S_BCM1480_MC_tRAP)
+#define V_BCM1480_MC_tRAP(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tRAP)
+#define G_BCM1480_MC_tRAP(x) _SB_GETVALUE(x,S_BCM1480_MC_tRAP,M_BCM1480_MC_tRAP)
+#define K_BCM1480_MC_tRAP_DEFAULT 0
+#define V_BCM1480_MC_tRAP_DEFAULT V_BCM1480_MC_tRAP(K_BCM1480_MC_tRAP_DEFAULT)
+
+#endif
+
+
+
+/*
+ * Global Registers: single instances per BCM1480
+ */
+
+/*
+ * Global Configuration Register (Table 99)
+ */
+
+#define S_BCM1480_MC_BLK_SET_MARK 8
+#define M_BCM1480_MC_BLK_SET_MARK _SB_MAKEMASK(4,S_BCM1480_MC_BLK_SET_MARK)
+#define V_BCM1480_MC_BLK_SET_MARK(x) _SB_MAKEVALUE(x,S_BCM1480_MC_BLK_SET_MARK)
+#define G_BCM1480_MC_BLK_SET_MARK(x) _SB_GETVALUE(x,S_BCM1480_MC_BLK_SET_MARK,M_BCM1480_MC_BLK_SET_MARK)
+
+#define S_BCM1480_MC_BLK_CLR_MARK 12
+#define M_BCM1480_MC_BLK_CLR_MARK _SB_MAKEMASK(4,S_BCM1480_MC_BLK_CLR_MARK)
+#define V_BCM1480_MC_BLK_CLR_MARK(x) _SB_MAKEVALUE(x,S_BCM1480_MC_BLK_CLR_MARK)
+#define G_BCM1480_MC_BLK_CLR_MARK(x) _SB_GETVALUE(x,S_BCM1480_MC_BLK_CLR_MARK,M_BCM1480_MC_BLK_CLR_MARK)
+
+#define M_BCM1480_MC_PKT_PRIORITY _SB_MAKEMASK1(16)
+
+#define S_BCM1480_MC_MAX_AGE 20
+#define M_BCM1480_MC_MAX_AGE _SB_MAKEMASK(4,S_BCM1480_MC_MAX_AGE)
+#define V_BCM1480_MC_MAX_AGE(x) _SB_MAKEVALUE(x,S_BCM1480_MC_MAX_AGE)
+#define G_BCM1480_MC_MAX_AGE(x) _SB_GETVALUE(x,S_BCM1480_MC_MAX_AGE,M_BCM1480_MC_MAX_AGE)
+
+#define M_BCM1480_MC_BERR_DISABLE _SB_MAKEMASK1(29)
+#define M_BCM1480_MC_FORCE_SEQ _SB_MAKEMASK1(30)
+#define M_BCM1480_MC_VGEN _SB_MAKEMASK1(32)
+
+#define S_BCM1480_MC_SLEW 33
+#define M_BCM1480_MC_SLEW _SB_MAKEMASK(2,S_BCM1480_MC_SLEW)
+#define V_BCM1480_MC_SLEW(x) _SB_MAKEVALUE(x,S_BCM1480_MC_SLEW)
+#define G_BCM1480_MC_SLEW(x) _SB_GETVALUE(x,S_BCM1480_MC_SLEW,M_BCM1480_MC_SLEW)
+
+#define M_BCM1480_MC_SSTL_VOLTAGE _SB_MAKEMASK1(35)
+
+/*
+ * Global Channel Interleave Register (Table 100)
+ */
+
+#define S_BCM1480_MC_INTLV0 0
+#define M_BCM1480_MC_INTLV0 _SB_MAKEMASK(6,S_BCM1480_MC_INTLV0)
+#define V_BCM1480_MC_INTLV0(x) _SB_MAKEVALUE(x,S_BCM1480_MC_INTLV0)
+#define G_BCM1480_MC_INTLV0(x) _SB_GETVALUE(x,S_BCM1480_MC_INTLV0,M_BCM1480_MC_INTLV0)
+
+#define S_BCM1480_MC_INTLV1 8
+#define M_BCM1480_MC_INTLV1 _SB_MAKEMASK(6,S_BCM1480_MC_INTLV1)
+#define V_BCM1480_MC_INTLV1(x) _SB_MAKEVALUE(x,S_BCM1480_MC_INTLV1)
+#define G_BCM1480_MC_INTLV1(x) _SB_GETVALUE(x,S_BCM1480_MC_INTLV1,M_BCM1480_MC_INTLV1)
+
+#define S_BCM1480_MC_INTLV_MODE 16
+#define M_BCM1480_MC_INTLV_MODE _SB_MAKEMASK(3,S_BCM1480_MC_INTLV_MODE)
+#define V_BCM1480_MC_INTLV_MODE(x) _SB_MAKEVALUE(x,S_BCM1480_MC_INTLV_MODE)
+#define G_BCM1480_MC_INTLV_MODE(x) _SB_GETVALUE(x,S_BCM1480_MC_INTLV_MODE,M_BCM1480_MC_INTLV_MODE)
+
+#define K_BCM1480_MC_INTLV_MODE_NONE 0x0
+#define K_BCM1480_MC_INTLV_MODE_01 0x1
+#define K_BCM1480_MC_INTLV_MODE_23 0x2
+#define K_BCM1480_MC_INTLV_MODE_01_23 0x3
+#define K_BCM1480_MC_INTLV_MODE_0123 0x4
+
+#define V_BCM1480_MC_INTLV_MODE_NONE V_BCM1480_MC_INTLV_MODE(K_BCM1480_MC_INTLV_MODE_NONE)
+#define V_BCM1480_MC_INTLV_MODE_01 V_BCM1480_MC_INTLV_MODE(K_BCM1480_MC_INTLV_MODE_01)
+#define V_BCM1480_MC_INTLV_MODE_23 V_BCM1480_MC_INTLV_MODE(K_BCM1480_MC_INTLV_MODE_23)
+#define V_BCM1480_MC_INTLV_MODE_01_23 V_BCM1480_MC_INTLV_MODE(K_BCM1480_MC_INTLV_MODE_01_23)
+#define V_BCM1480_MC_INTLV_MODE_0123 V_BCM1480_MC_INTLV_MODE(K_BCM1480_MC_INTLV_MODE_0123)
+
+/*
+ * ECC Status Register
+ */
+
+#define S_BCM1480_MC_ECC_ERR_ADDR 0
+#define M_BCM1480_MC_ECC_ERR_ADDR _SB_MAKEMASK(37,S_BCM1480_MC_ECC_ERR_ADDR)
+#define V_BCM1480_MC_ECC_ERR_ADDR(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ECC_ERR_ADDR)
+#define G_BCM1480_MC_ECC_ERR_ADDR(x) _SB_GETVALUE(x,S_BCM1480_MC_ECC_ERR_ADDR,M_BCM1480_MC_ECC_ERR_ADDR)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define M_BCM1480_MC_ECC_ERR_RMW _SB_MAKEMASK1(60)
+#endif
+
+#define M_BCM1480_MC_ECC_MULT_ERR_DET _SB_MAKEMASK1(61)
+#define M_BCM1480_MC_ECC_UERR_DET _SB_MAKEMASK1(62)
+#define M_BCM1480_MC_ECC_CERR_DET _SB_MAKEMASK1(63)
+
+/*
+ * Global ECC Address Register (Table 102)
+ */
+
+#define S_BCM1480_MC_ECC_CORR_ADDR 0
+#define M_BCM1480_MC_ECC_CORR_ADDR _SB_MAKEMASK(37,S_BCM1480_MC_ECC_CORR_ADDR)
+#define V_BCM1480_MC_ECC_CORR_ADDR(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ECC_CORR_ADDR)
+#define G_BCM1480_MC_ECC_CORR_ADDR(x) _SB_GETVALUE(x,S_BCM1480_MC_ECC_CORR_ADDR,M_BCM1480_MC_ECC_CORR_ADDR)
+
+/*
+ * Global ECC Correction Register (Table 103)
+ */
+
+#define S_BCM1480_MC_ECC_CORRECT 0
+#define M_BCM1480_MC_ECC_CORRECT _SB_MAKEMASK(64,S_BCM1480_MC_ECC_CORRECT)
+#define V_BCM1480_MC_ECC_CORRECT(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ECC_CORRECT)
+#define G_BCM1480_MC_ECC_CORRECT(x) _SB_GETVALUE(x,S_BCM1480_MC_ECC_CORRECT,M_BCM1480_MC_ECC_CORRECT)
+
+/*
+ * Global ECC Performance Counters Control Register (Table 104)
+ */
+
+#define S_BCM1480_MC_CHANNEL_SELECT 0
+#define M_BCM1480_MC_CHANNEL_SELECT _SB_MAKEMASK(4,S_BCM1480_MC_CHANNEL_SELECT)
+#define V_BCM1480_MC_CHANNEL_SELECT(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CHANNEL_SELECT)
+#define G_BCM1480_MC_CHANNEL_SELECT(x) _SB_GETVALUE(x,S_BCM1480_MC_CHANNEL_SELECT,M_BCM1480_MC_CHANNEL_SELECT)
+#define K_BCM1480_MC_CHANNEL_SELECT_0 0x1
+#define K_BCM1480_MC_CHANNEL_SELECT_1 0x2
+#define K_BCM1480_MC_CHANNEL_SELECT_2 0x4
+#define K_BCM1480_MC_CHANNEL_SELECT_3 0x8
+
+#endif /* _BCM1480_MC_H */
diff --git a/include/asm-mips/sibyte/bcm1480_regs.h b/include/asm-mips/sibyte/bcm1480_regs.h
new file mode 100644
index 000000000000..c2dd2fe3047c
--- /dev/null
+++ b/include/asm-mips/sibyte/bcm1480_regs.h
@@ -0,0 +1,869 @@
+/* *********************************************************************
+ * BCM1255/BCM1280/BCM1455/BCM1480 Board Support Package
+ *
+ * Register Definitions File: bcm1480_regs.h
+ *
+ * This module contains the addresses of the on-chip peripherals
+ * on the BCM1280 and BCM1480.
+ *
+ * BCM1480 specification level: 1X55_1X80-UM100-D4 (11/24/03)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ ********************************************************************* */
+
+#ifndef _BCM1480_REGS_H
+#define _BCM1480_REGS_H
+
+#include "sb1250_defs.h"
+
+/* *********************************************************************
+ * Pull in the BCM1250's registers since a great deal of the 1480's
+ * functions are the same as the BCM1250.
+ ********************************************************************* */
+
+#include "sb1250_regs.h"
+
+
+/* *********************************************************************
+ * Some general notes:
+ *
+ * Register addresses are grouped by function and follow the order
+ * of the User Manual.
+ *
+ * For the most part, when there is more than one peripheral
+ * of the same type on the SOC, the constants below will be
+ * offsets from the base of each peripheral. For example,
+ * the MAC registers are described as offsets from the first
+ * MAC register, and there will be a MAC_REGISTER() macro
+ * to calculate the base address of a given MAC.
+ *
+ * The information in this file is based on the BCM1X55/BCM1X80
+ * User Manual, Document 1X55_1X80-UM100-R, 22/12/03.
+ *
+ * This file is basically a "what's new" header file. Since the
+ * BCM1250 and the new BCM1480 (and derivatives) share many common
+ * features, this file contains only what's new or changed from
+ * the 1250. (above, you can see that we include the 1250 symbols
+ * to get the base functionality).
+ *
+ * In software, be sure to use the correct symbols, particularly
+ * for blocks that are different between the two chip families.
+ * All BCM1480-specific symbols have _BCM1480_ in their names,
+ * and all BCM1250-specific and "base" functions that are common in
+ * both chips have no special names (this is for compatibility with
+ * older include files). Therefore, if you're working with the
+ * SCD, which is very different on each chip, A_SCD_xxx implies
+ * the BCM1250 version and A_BCM1480_SCD_xxx implies the BCM1480
+ * version.
+ ********************************************************************* */
+
+
+/* *********************************************************************
+ * Memory Controller Registers (Section 6)
+ ********************************************************************* */
+
+#define A_BCM1480_MC_BASE_0 0x0010050000
+#define A_BCM1480_MC_BASE_1 0x0010051000
+#define A_BCM1480_MC_BASE_2 0x0010052000
+#define A_BCM1480_MC_BASE_3 0x0010053000
+#define BCM1480_MC_REGISTER_SPACING 0x1000
+
+#define A_BCM1480_MC_BASE(ctlid) (A_BCM1480_MC_BASE_0+(ctlid)*BCM1480_MC_REGISTER_SPACING)
+#define A_BCM1480_MC_REGISTER(ctlid,reg) (A_BCM1480_MC_BASE(ctlid)+(reg))
+
+#define R_BCM1480_MC_CONFIG 0x0000000100
+#define R_BCM1480_MC_CS_START 0x0000000120
+#define R_BCM1480_MC_CS_END 0x0000000140
+#define S_BCM1480_MC_CS_STARTEND 24
+
+#define R_BCM1480_MC_CS01_ROW0 0x0000000180
+#define R_BCM1480_MC_CS01_ROW1 0x00000001A0
+#define R_BCM1480_MC_CS23_ROW0 0x0000000200
+#define R_BCM1480_MC_CS23_ROW1 0x0000000220
+#define R_BCM1480_MC_CS01_COL0 0x0000000280
+#define R_BCM1480_MC_CS01_COL1 0x00000002A0
+#define R_BCM1480_MC_CS23_COL0 0x0000000300
+#define R_BCM1480_MC_CS23_COL1 0x0000000320
+
+#define R_BCM1480_MC_CSX_BASE 0x0000000180
+#define R_BCM1480_MC_CSX_ROW0 0x0000000000 /* relative to CSX_BASE */
+#define R_BCM1480_MC_CSX_ROW1 0x0000000020 /* relative to CSX_BASE */
+#define R_BCM1480_MC_CSX_COL0 0x0000000100 /* relative to CSX_BASE */
+#define R_BCM1480_MC_CSX_COL1 0x0000000120 /* relative to CSX_BASE */
+#define BCM1480_MC_CSX_SPACING 0x0000000080 /* CS23 relative to CS01 */
+
+#define R_BCM1480_MC_CS01_BA 0x0000000380
+#define R_BCM1480_MC_CS23_BA 0x00000003A0
+#define R_BCM1480_MC_DRAMCMD 0x0000000400
+#define R_BCM1480_MC_DRAMMODE 0x0000000420
+#define R_BCM1480_MC_CLOCK_CFG 0x0000000440
+#define R_BCM1480_MC_MCLK_CFG R_BCM1480_MC_CLOCK_CFG
+#define R_BCM1480_MC_TEST_DATA 0x0000000480
+#define R_BCM1480_MC_TEST_ECC 0x00000004A0
+#define R_BCM1480_MC_TIMING1 0x00000004C0
+#define R_BCM1480_MC_TIMING2 0x00000004E0
+#define R_BCM1480_MC_DLL_CFG 0x0000000500
+#define R_BCM1480_MC_DRIVE_CFG 0x0000000520
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define R_BCM1480_MC_ODT 0x0000000460
+#define R_BCM1480_MC_ECC_STATUS 0x0000000540
+#endif
+
+/* Global registers (single instance) */
+#define A_BCM1480_MC_GLB_CONFIG 0x0010054100
+#define A_BCM1480_MC_GLB_INTLV 0x0010054120
+#define A_BCM1480_MC_GLB_ECC_STATUS 0x0010054140
+#define A_BCM1480_MC_GLB_ECC_ADDR 0x0010054160
+#define A_BCM1480_MC_GLB_ECC_CORRECT 0x0010054180
+#define A_BCM1480_MC_GLB_PERF_CNT_CONTROL 0x00100541A0
+
+/* *********************************************************************
+ * L2 Cache Control Registers (Section 5)
+ ********************************************************************* */
+
+#define A_BCM1480_L2_BASE 0x0010040000
+
+#define A_BCM1480_L2_READ_TAG 0x0010040018
+#define A_BCM1480_L2_ECC_TAG 0x0010040038
+#define A_BCM1480_L2_MISC0_VALUE 0x0010040058
+#define A_BCM1480_L2_MISC1_VALUE 0x0010040078
+#define A_BCM1480_L2_MISC2_VALUE 0x0010040098
+#define A_BCM1480_L2_MISC_CONFIG 0x0010040040 /* x040 */
+#define A_BCM1480_L2_CACHE_DISABLE 0x0010040060 /* x060 */
+#define A_BCM1480_L2_MAKECACHEDISABLE(x) (A_BCM1480_L2_CACHE_DISABLE | (((x)&0xF) << 12))
+#define A_BCM1480_L2_WAY_ENABLE_3_0 0x0010040080 /* x080 */
+#define A_BCM1480_L2_WAY_ENABLE_7_4 0x00100400A0 /* x0A0 */
+#define A_BCM1480_L2_MAKE_WAY_ENABLE_LO(x) (A_BCM1480_L2_WAY_ENABLE_3_0 | (((x)&0xF) << 12))
+#define A_BCM1480_L2_MAKE_WAY_ENABLE_HI(x) (A_BCM1480_L2_WAY_ENABLE_7_4 | (((x)&0xF) << 12))
+#define A_BCM1480_L2_MAKE_WAY_DISABLE_LO(x) (A_BCM1480_L2_WAY_ENABLE_3_0 | (((~x)&0xF) << 12))
+#define A_BCM1480_L2_MAKE_WAY_DISABLE_HI(x) (A_BCM1480_L2_WAY_ENABLE_7_4 | (((~x)&0xF) << 12))
+#define A_BCM1480_L2_WAY_LOCAL_3_0 0x0010040100 /* x100 */
+#define A_BCM1480_L2_WAY_LOCAL_7_4 0x0010040120 /* x120 */
+#define A_BCM1480_L2_WAY_REMOTE_3_0 0x0010040140 /* x140 */
+#define A_BCM1480_L2_WAY_REMOTE_7_4 0x0010040160 /* x160 */
+#define A_BCM1480_L2_WAY_AGENT_3_0 0x00100400C0 /* xxC0 */
+#define A_BCM1480_L2_WAY_AGENT_7_4 0x00100400E0 /* xxE0 */
+#define A_BCM1480_L2_WAY_ENABLE(A, banks) (A | (((~(banks))&0x0F) << 8))
+#define A_BCM1480_L2_BANK_BASE 0x00D0300000
+#define A_BCM1480_L2_BANK_ADDRESS(b) (A_BCM1480_L2_BANK_BASE | (((b)&0x7)<<17))
+#define A_BCM1480_L2_MGMT_TAG_BASE 0x00D0000000
+
+
+/* *********************************************************************
+ * PCI-X Interface Registers (Section 7)
+ ********************************************************************* */
+
+#define A_BCM1480_PCI_BASE 0x0010061400
+
+#define A_BCM1480_PCI_RESET 0x0010061400
+#define A_BCM1480_PCI_DLL 0x0010061500
+
+#define A_BCM1480_PCI_TYPE00_HEADER 0x002E000000
+
+/* *********************************************************************
+ * Ethernet MAC Registers (Section 11) and DMA Registers (Section 10.6)
+ ********************************************************************* */
+
+/* No register changes with Rev.C BCM1250, but one additional MAC */
+
+#define A_BCM1480_MAC_BASE_2 0x0010066000
+
+#ifndef A_MAC_BASE_2
+#define A_MAC_BASE_2 A_BCM1480_MAC_BASE_2
+#endif
+
+#define A_BCM1480_MAC_BASE_3 0x0010067000
+#define A_MAC_BASE_3 A_BCM1480_MAC_BASE_3
+
+#define R_BCM1480_MAC_DMA_OODPKTLOST 0x00000038
+
+#ifndef R_MAC_DMA_OODPKTLOST
+#define R_MAC_DMA_OODPKTLOST R_BCM1480_MAC_DMA_OODPKTLOST
+#endif
+
+
+/* *********************************************************************
+ * DUART Registers (Section 14)
+ ********************************************************************* */
+
+/* No significant differences from BCM1250, two DUARTs */
+
+/* Conventions, per user manual:
+ * DUART generic, channels A,B,C,D
+ * DUART0 implementing channels A,B
+ * DUART1 inplementing channels C,D
+ */
+
+#define BCM1480_DUART_NUM_PORTS 4
+
+#define A_BCM1480_DUART0 0x0010060000
+#define A_BCM1480_DUART1 0x0010060400
+#define A_BCM1480_DUART(chan) ((((chan)&2) == 0)? A_BCM1480_DUART0 : A_BCM1480_DUART1)
+
+#define BCM1480_DUART_CHANREG_SPACING 0x100
+#define A_BCM1480_DUART_CHANREG(chan,reg) (A_BCM1480_DUART(chan) \
+ + BCM1480_DUART_CHANREG_SPACING*((chan)&1) \
+ + (reg))
+#define R_BCM1480_DUART_CHANREG(chan,reg) (BCM1480_DUART_CHANREG_SPACING*((chan)&1) + (reg))
+
+#define R_BCM1480_DUART_IMRREG(chan) (R_DUART_IMR_A + ((chan)&1)*DUART_IMRISR_SPACING)
+#define R_BCM1480_DUART_ISRREG(chan) (R_DUART_ISR_A + ((chan)&1)*DUART_IMRISR_SPACING)
+
+#define A_BCM1480_DUART_IMRREG(chan) (A_BCM1480_DUART(chan) + R_BCM1480_DUART_IMRREG(chan))
+#define A_BCM1480_DUART_ISRREG(chan) (A_BCM1480_DUART(chan) + R_BCM1480_DUART_ISRREG(chan))
+
+/*
+ * These constants are the absolute addresses.
+ */
+
+#define A_BCM1480_DUART_MODE_REG_1_C 0x0010060400
+#define A_BCM1480_DUART_MODE_REG_2_C 0x0010060410
+#define A_BCM1480_DUART_STATUS_C 0x0010060420
+#define A_BCM1480_DUART_CLK_SEL_C 0x0010060430
+#define A_BCM1480_DUART_FULL_CTL_C 0x0010060440
+#define A_BCM1480_DUART_CMD_C 0x0010060450
+#define A_BCM1480_DUART_RX_HOLD_C 0x0010060460
+#define A_BCM1480_DUART_TX_HOLD_C 0x0010060470
+#define A_BCM1480_DUART_OPCR_C 0x0010060480
+#define A_BCM1480_DUART_AUX_CTRL_C 0x0010060490
+
+#define A_BCM1480_DUART_MODE_REG_1_D 0x0010060500
+#define A_BCM1480_DUART_MODE_REG_2_D 0x0010060510
+#define A_BCM1480_DUART_STATUS_D 0x0010060520
+#define A_BCM1480_DUART_CLK_SEL_D 0x0010060530
+#define A_BCM1480_DUART_FULL_CTL_D 0x0010060540
+#define A_BCM1480_DUART_CMD_D 0x0010060550
+#define A_BCM1480_DUART_RX_HOLD_D 0x0010060560
+#define A_BCM1480_DUART_TX_HOLD_D 0x0010060570
+#define A_BCM1480_DUART_OPCR_D 0x0010060580
+#define A_BCM1480_DUART_AUX_CTRL_D 0x0010060590
+
+#define A_BCM1480_DUART_INPORT_CHNG_CD 0x0010060600
+#define A_BCM1480_DUART_AUX_CTRL_CD 0x0010060610
+#define A_BCM1480_DUART_ISR_C 0x0010060620
+#define A_BCM1480_DUART_IMR_C 0x0010060630
+#define A_BCM1480_DUART_ISR_D 0x0010060640
+#define A_BCM1480_DUART_IMR_D 0x0010060650
+#define A_BCM1480_DUART_OUT_PORT_CD 0x0010060660
+#define A_BCM1480_DUART_OPCR_CD 0x0010060670
+#define A_BCM1480_DUART_IN_PORT_CD 0x0010060680
+#define A_BCM1480_DUART_ISR_CD 0x0010060690
+#define A_BCM1480_DUART_IMR_CD 0x00100606A0
+#define A_BCM1480_DUART_SET_OPR_CD 0x00100606B0
+#define A_BCM1480_DUART_CLEAR_OPR_CD 0x00100606C0
+#define A_BCM1480_DUART_INPORT_CHNG_C 0x00100606D0
+#define A_BCM1480_DUART_INPORT_CHNG_D 0x00100606E0
+
+
+/* *********************************************************************
+ * Generic Bus Registers (Section 15) and PCMCIA Registers (Section 16)
+ ********************************************************************* */
+
+#define A_BCM1480_IO_PCMCIA_CFG_B 0x0010061A58
+#define A_BCM1480_IO_PCMCIA_STATUS_B 0x0010061A68
+
+/* *********************************************************************
+ * GPIO Registers (Section 17)
+ ********************************************************************* */
+
+/* One additional GPIO register, placed _before_ the BCM1250's GPIO block base */
+
+#define A_BCM1480_GPIO_INT_ADD_TYPE 0x0010061A78
+#define R_BCM1480_GPIO_INT_ADD_TYPE (-8)
+
+#define A_GPIO_INT_ADD_TYPE A_BCM1480_GPIO_INT_ADD_TYPE
+#define R_GPIO_INT_ADD_TYPE R_BCM1480_GPIO_INT_ADD_TYPE
+
+/* *********************************************************************
+ * SMBus Registers (Section 18)
+ ********************************************************************* */
+
+/* No changes from BCM1250 */
+
+/* *********************************************************************
+ * Timer Registers (Sections 4.6)
+ ********************************************************************* */
+
+/* BCM1480 has two additional watchdogs */
+
+/* Watchdog timers */
+
+#define A_BCM1480_SCD_WDOG_2 0x0010022050
+#define A_BCM1480_SCD_WDOG_3 0x0010022150
+
+#define BCM1480_SCD_NUM_WDOGS 4
+
+#define A_BCM1480_SCD_WDOG_BASE(w) (A_BCM1480_SCD_WDOG_0+((w)&2)*0x1000 + ((w)&1)*0x100)
+#define A_BCM1480_SCD_WDOG_REGISTER(w,r) (A_BCM1480_SCD_WDOG_BASE(w) + (r))
+
+#define A_BCM1480_SCD_WDOG_INIT_2 0x0010022050
+#define A_BCM1480_SCD_WDOG_CNT_2 0x0010022058
+#define A_BCM1480_SCD_WDOG_CFG_2 0x0010022060
+
+#define A_BCM1480_SCD_WDOG_INIT_3 0x0010022150
+#define A_BCM1480_SCD_WDOG_CNT_3 0x0010022158
+#define A_BCM1480_SCD_WDOG_CFG_3 0x0010022160
+
+/* BCM1480 has two additional compare registers */
+
+#define A_BCM1480_SCD_ZBBUS_CYCLE_COUNT A_SCD_ZBBUS_CYCLE_COUNT
+#define A_BCM1480_SCD_ZBBUS_CYCLE_CP_BASE 0x0010020C00
+#define A_BCM1480_SCD_ZBBUS_CYCLE_CP0 A_SCD_ZBBUS_CYCLE_CP0
+#define A_BCM1480_SCD_ZBBUS_CYCLE_CP1 A_SCD_ZBBUS_CYCLE_CP1
+#define A_BCM1480_SCD_ZBBUS_CYCLE_CP2 0x0010020C10
+#define A_BCM1480_SCD_ZBBUS_CYCLE_CP3 0x0010020C18
+
+/* *********************************************************************
+ * System Control Registers (Section 4.2)
+ ********************************************************************* */
+
+/* Scratch register in different place */
+
+#define A_BCM1480_SCD_SCRATCH 0x100200A0
+
+/* *********************************************************************
+ * System Address Trap Registers (Section 4.9)
+ ********************************************************************* */
+
+/* No changes from BCM1250 */
+
+/* *********************************************************************
+ * System Interrupt Mapper Registers (Sections 4.3-4.5)
+ ********************************************************************* */
+
+#define A_BCM1480_IMR_CPU0_BASE 0x0010020000
+#define A_BCM1480_IMR_CPU1_BASE 0x0010022000
+#define A_BCM1480_IMR_CPU2_BASE 0x0010024000
+#define A_BCM1480_IMR_CPU3_BASE 0x0010026000
+#define BCM1480_IMR_REGISTER_SPACING 0x2000
+#define BCM1480_IMR_REGISTER_SPACING_SHIFT 13
+
+#define A_BCM1480_IMR_MAPPER(cpu) (A_BCM1480_IMR_CPU0_BASE+(cpu)*BCM1480_IMR_REGISTER_SPACING)
+#define A_BCM1480_IMR_REGISTER(cpu,reg) (A_BCM1480_IMR_MAPPER(cpu)+(reg))
+
+/* Most IMR registers are 128 bits, implemented as non-contiguous
+ 64-bit registers high (_H) and low (_L) */
+#define BCM1480_IMR_HL_SPACING 0x1000
+
+#define R_BCM1480_IMR_INTERRUPT_DIAG_H 0x0010
+#define R_BCM1480_IMR_LDT_INTERRUPT_H 0x0018
+#define R_BCM1480_IMR_LDT_INTERRUPT_CLR_H 0x0020
+#define R_BCM1480_IMR_INTERRUPT_MASK_H 0x0028
+#define R_BCM1480_IMR_INTERRUPT_TRACE_H 0x0038
+#define R_BCM1480_IMR_INTERRUPT_SOURCE_STATUS_H 0x0040
+#define R_BCM1480_IMR_LDT_INTERRUPT_SET 0x0048
+#define R_BCM1480_IMR_MAILBOX_0_CPU 0x00C0
+#define R_BCM1480_IMR_MAILBOX_0_SET_CPU 0x00C8
+#define R_BCM1480_IMR_MAILBOX_0_CLR_CPU 0x00D0
+#define R_BCM1480_IMR_MAILBOX_1_CPU 0x00E0
+#define R_BCM1480_IMR_MAILBOX_1_SET_CPU 0x00E8
+#define R_BCM1480_IMR_MAILBOX_1_CLR_CPU 0x00F0
+#define R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H 0x0100
+#define BCM1480_IMR_INTERRUPT_STATUS_COUNT 8
+#define R_BCM1480_IMR_INTERRUPT_MAP_BASE_H 0x0200
+#define BCM1480_IMR_INTERRUPT_MAP_COUNT 64
+
+#define R_BCM1480_IMR_INTERRUPT_DIAG_L 0x1010
+#define R_BCM1480_IMR_LDT_INTERRUPT_L 0x1018
+#define R_BCM1480_IMR_LDT_INTERRUPT_CLR_L 0x1020
+#define R_BCM1480_IMR_INTERRUPT_MASK_L 0x1028
+#define R_BCM1480_IMR_INTERRUPT_TRACE_L 0x1038
+#define R_BCM1480_IMR_INTERRUPT_SOURCE_STATUS_L 0x1040
+#define R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L 0x1100
+#define R_BCM1480_IMR_INTERRUPT_MAP_BASE_L 0x1200
+
+#define A_BCM1480_IMR_ALIAS_MAILBOX_CPU0_BASE 0x0010028000
+#define A_BCM1480_IMR_ALIAS_MAILBOX_CPU1_BASE 0x0010028100
+#define A_BCM1480_IMR_ALIAS_MAILBOX_CPU2_BASE 0x0010028200
+#define A_BCM1480_IMR_ALIAS_MAILBOX_CPU3_BASE 0x0010028300
+#define BCM1480_IMR_ALIAS_MAILBOX_SPACING 0100
+
+#define A_BCM1480_IMR_ALIAS_MAILBOX(cpu) (A_BCM1480_IMR_ALIAS_MAILBOX_CPU0_BASE + \
+ (cpu)*BCM1480_IMR_ALIAS_MAILBOX_SPACING)
+#define A_BCM1480_IMR_ALIAS_MAILBOX_REGISTER(cpu,reg) (A_BCM1480_IMR_ALIAS_MAILBOX(cpu)+(reg))
+
+#define R_BCM1480_IMR_ALIAS_MAILBOX_0 0x0000 /* 0x0x0 */
+#define R_BCM1480_IMR_ALIAS_MAILBOX_0_SET 0x0008 /* 0x0x8 */
+
+/* *********************************************************************
+ * System Performance Counter Registers (Section 4.7)
+ ********************************************************************* */
+
+/* BCM1480 has four more performance counter registers, and two control
+ registers. */
+
+#define A_BCM1480_SCD_PERF_CNT_BASE 0x00100204C0
+
+#define A_BCM1480_SCD_PERF_CNT_CFG0 0x00100204C0
+#define A_BCM1480_SCD_PERF_CNT_CFG_0 A_BCM1480_SCD_PERF_CNT_CFG0
+#define A_BCM1480_SCD_PERF_CNT_CFG1 0x00100204C8
+#define A_BCM1480_SCD_PERF_CNT_CFG_1 A_BCM1480_SCD_PERF_CNT_CFG1
+
+#define A_BCM1480_SCD_PERF_CNT_0 A_SCD_PERF_CNT_0
+#define A_BCM1480_SCD_PERF_CNT_1 A_SCD_PERF_CNT_1
+#define A_BCM1480_SCD_PERF_CNT_2 A_SCD_PERF_CNT_2
+#define A_BCM1480_SCD_PERF_CNT_3 A_SCD_PERF_CNT_3
+
+#define A_BCM1480_SCD_PERF_CNT_4 0x00100204F0
+#define A_BCM1480_SCD_PERF_CNT_5 0x00100204F8
+#define A_BCM1480_SCD_PERF_CNT_6 0x0010020500
+#define A_BCM1480_SCD_PERF_CNT_7 0x0010020508
+
+/* *********************************************************************
+ * System Bus Watcher Registers (Section 4.8)
+ ********************************************************************* */
+
+
+/* Same as 1250 except BUS_ERR_STATUS_DEBUG is in a different place. */
+
+#define A_BCM1480_BUS_ERR_STATUS_DEBUG 0x00100208D8
+
+/* *********************************************************************
+ * System Debug Controller Registers (Section 19)
+ ********************************************************************* */
+
+/* Same as 1250 */
+
+/* *********************************************************************
+ * System Trace Unit Registers (Sections 4.10)
+ ********************************************************************* */
+
+/* Same as 1250 */
+
+/* *********************************************************************
+ * Data Mover DMA Registers (Section 10.7)
+ ********************************************************************* */
+
+/* Same as 1250 */
+
+
+/* *********************************************************************
+ * HyperTransport Interface Registers (Section 8)
+ ********************************************************************* */
+
+#define BCM1480_HT_NUM_PORTS 3
+#define BCM1480_HT_PORT_SPACING 0x800
+#define A_BCM1480_HT_PORT_HEADER(x) (A_BCM1480_HT_PORT0_HEADER + ((x)*BCM1480_HT_PORT_SPACING))
+
+#define A_BCM1480_HT_PORT0_HEADER 0x00FE000000
+#define A_BCM1480_HT_PORT1_HEADER 0x00FE000800
+#define A_BCM1480_HT_PORT2_HEADER 0x00FE001000
+#define A_BCM1480_HT_TYPE00_HEADER 0x00FE002000
+
+
+/* *********************************************************************
+ * Node Controller Registers (Section 9)
+ ********************************************************************* */
+
+#define A_BCM1480_NC_BASE 0x00DFBD0000
+
+#define A_BCM1480_NC_RLD_FIELD 0x00DFBD0000
+#define A_BCM1480_NC_RLD_TRIGGER 0x00DFBD0020
+#define A_BCM1480_NC_RLD_BAD_ERROR 0x00DFBD0040
+#define A_BCM1480_NC_RLD_COR_ERROR 0x00DFBD0060
+#define A_BCM1480_NC_RLD_ECC_STATUS 0x00DFBD0080
+#define A_BCM1480_NC_RLD_WAY_ENABLE 0x00DFBD00A0
+#define A_BCM1480_NC_RLD_RANDOM_LFSR 0x00DFBD00C0
+
+#define A_BCM1480_NC_INTERRUPT_STATUS 0x00DFBD00E0
+#define A_BCM1480_NC_INTERRUPT_ENABLE 0x00DFBD0100
+#define A_BCM1480_NC_TIMEOUT_COUNTER 0x00DFBD0120
+#define A_BCM1480_NC_TIMEOUT_COUNTER_SEL 0x00DFBD0140
+
+#define A_BCM1480_NC_CREDIT_STATUS_REG0 0x00DFBD0200
+#define A_BCM1480_NC_CREDIT_STATUS_REG1 0x00DFBD0220
+#define A_BCM1480_NC_CREDIT_STATUS_REG2 0x00DFBD0240
+#define A_BCM1480_NC_CREDIT_STATUS_REG3 0x00DFBD0260
+#define A_BCM1480_NC_CREDIT_STATUS_REG4 0x00DFBD0280
+#define A_BCM1480_NC_CREDIT_STATUS_REG5 0x00DFBD02A0
+#define A_BCM1480_NC_CREDIT_STATUS_REG6 0x00DFBD02C0
+#define A_BCM1480_NC_CREDIT_STATUS_REG7 0x00DFBD02E0
+#define A_BCM1480_NC_CREDIT_STATUS_REG8 0x00DFBD0300
+#define A_BCM1480_NC_CREDIT_STATUS_REG9 0x00DFBD0320
+#define A_BCM1480_NC_CREDIT_STATUS_REG10 0x00DFBE0000
+#define A_BCM1480_NC_CREDIT_STATUS_REG11 0x00DFBE0020
+#define A_BCM1480_NC_CREDIT_STATUS_REG12 0x00DFBE0040
+
+#define A_BCM1480_NC_SR_TIMEOUT_COUNTER 0x00DFBE0060
+#define A_BCM1480_NC_SR_TIMEOUT_COUNTER_SEL 0x00DFBE0080
+
+
+/* *********************************************************************
+ * H&R Block Configuration Registers (Section 12.4)
+ ********************************************************************* */
+
+#define A_BCM1480_HR_BASE_0 0x00DF820000
+#define A_BCM1480_HR_BASE_1 0x00DF8A0000
+#define A_BCM1480_HR_BASE_2 0x00DF920000
+#define BCM1480_HR_REGISTER_SPACING 0x80000
+
+#define A_BCM1480_HR_BASE(idx) (A_BCM1480_HR_BASE_0 + ((idx)*BCM1480_HR_REGISTER_SPACING))
+#define A_BCM1480_HR_REGISTER(idx,reg) (A_BCM1480_HR_BASE(idx) + (reg))
+
+#define R_BCM1480_HR_CFG 0x0000000000
+
+#define R_BCM1480_HR_MAPPING 0x0000010010
+
+#define BCM1480_HR_RULE_SPACING 0x0000000010
+#define BCM1480_HR_NUM_RULES 16
+#define BCM1480_HR_OP_OFFSET 0x0000000100
+#define BCM1480_HR_TYPE_OFFSET 0x0000000108
+#define R_BCM1480_HR_RULE_OP(idx) (BCM1480_HR_OP_OFFSET + ((idx)*BCM1480_HR_RULE_SPACING))
+#define R_BCM1480_HR_RULE_TYPE(idx) (BCM1480_HR_TYPE_OFFSET + ((idx)*BCM1480_HR_RULE_SPACING))
+
+#define BCM1480_HR_LEAF_SPACING 0x0000000010
+#define BCM1480_HR_NUM_LEAVES 10
+#define BCM1480_HR_LEAF_OFFSET 0x0000000300
+#define R_BCM1480_HR_HA_LEAF0(idx) (BCM1480_HR_LEAF_OFFSET + ((idx)*BCM1480_HR_LEAF_SPACING))
+
+#define R_BCM1480_HR_EX_LEAF0 0x00000003A0
+
+#define BCM1480_HR_PATH_SPACING 0x0000000010
+#define BCM1480_HR_NUM_PATHS 16
+#define BCM1480_HR_PATH_OFFSET 0x0000000600
+#define R_BCM1480_HR_PATH(idx) (BCM1480_HR_PATH_OFFSET + ((idx)*BCM1480_HR_PATH_SPACING))
+
+#define R_BCM1480_HR_PATH_DEFAULT 0x0000000700
+
+#define BCM1480_HR_ROUTE_SPACING 8
+#define BCM1480_HR_NUM_ROUTES 512
+#define BCM1480_HR_ROUTE_OFFSET 0x0000001000
+#define R_BCM1480_HR_RT_WORD(idx) (BCM1480_HR_ROUTE_OFFSET + ((idx)*BCM1480_HR_ROUTE_SPACING))
+
+
+/* checked to here - ehs */
+/* *********************************************************************
+ * Packet Manager DMA Registers (Section 12.5)
+ ********************************************************************* */
+
+#define A_BCM1480_PM_BASE 0x0010056000
+
+#define A_BCM1480_PMI_LCL_0 0x0010058000
+#define A_BCM1480_PMO_LCL_0 0x001005C000
+#define A_BCM1480_PMI_OFFSET_0 (A_BCM1480_PMI_LCL_0 - A_BCM1480_PM_BASE)
+#define A_BCM1480_PMO_OFFSET_0 (A_BCM1480_PMO_LCL_0 - A_BCM1480_PM_BASE)
+
+#define BCM1480_PM_LCL_REGISTER_SPACING 0x100
+#define BCM1480_PM_NUM_CHANNELS 32
+
+#define A_BCM1480_PMI_LCL_BASE(idx) (A_BCM1480_PMI_LCL_0 + ((idx)*BCM1480_PM_LCL_REGISTER_SPACING))
+#define A_BCM1480_PMI_LCL_REGISTER(idx,reg) (A_BCM1480_PMI_LCL_BASE(idx) + (reg))
+#define A_BCM1480_PMO_LCL_BASE(idx) (A_BCM1480_PMO_LCL_0 + ((idx)*BCM1480_PM_LCL_REGISTER_SPACING))
+#define A_BCM1480_PMO_LCL_REGISTER(idx,reg) (A_BCM1480_PMO_LCL_BASE(idx) + (reg))
+
+#define BCM1480_PM_INT_PACKING 8
+#define BCM1480_PM_INT_FUNCTION_SPACING 0x40
+#define BCM1480_PM_INT_NUM_FUNCTIONS 3
+
+/*
+ * DMA channel registers relative to A_BCM1480_PMI_LCL_BASE(n) and A_BCM1480_PMO_LCL_BASE(n)
+ */
+
+#define R_BCM1480_PM_BASE_SIZE 0x0000000000
+#define R_BCM1480_PM_CNT 0x0000000008
+#define R_BCM1480_PM_PFCNT 0x0000000010
+#define R_BCM1480_PM_LAST 0x0000000018
+#define R_BCM1480_PM_PFINDX 0x0000000020
+#define R_BCM1480_PM_INT_WMK 0x0000000028
+#define R_BCM1480_PM_CONFIG0 0x0000000030
+#define R_BCM1480_PM_LOCALDEBUG 0x0000000078
+#define R_BCM1480_PM_CACHEABILITY 0x0000000080 /* PMI only */
+#define R_BCM1480_PM_INT_CNFG 0x0000000088
+#define R_BCM1480_PM_DESC_MERGE_TIMER 0x0000000090
+#define R_BCM1480_PM_LOCALDEBUG_PIB 0x00000000F8 /* PMI only */
+#define R_BCM1480_PM_LOCALDEBUG_POB 0x00000000F8 /* PMO only */
+
+/*
+ * Global Registers (Not Channelized)
+ */
+
+#define A_BCM1480_PMI_GLB_0 0x0010056000
+#define A_BCM1480_PMO_GLB_0 0x0010057000
+
+/*
+ * PM to TX Mapping Register relative to A_BCM1480_PMI_GLB_0 and A_BCM1480_PMO_GLB_0
+ */
+
+#define R_BCM1480_PM_PMO_MAPPING 0x00000008C8 /* PMO only */
+
+#define A_BCM1480_PM_PMO_MAPPING (A_BCM1480_PMO_GLB_0 + R_BCM1480_PM_PMO_MAPPING)
+
+/*
+ * Interrupt mapping registers
+ */
+
+
+#define A_BCM1480_PMI_INT_0 0x0010056800
+#define A_BCM1480_PMI_INT(q) (A_BCM1480_PMI_INT_0 + ((q>>8)<<8))
+#define A_BCM1480_PMI_INT_OFFSET_0 (A_BCM1480_PMI_INT_0 - A_BCM1480_PM_BASE)
+#define A_BCM1480_PMO_INT_0 0x0010057800
+#define A_BCM1480_PMO_INT(q) (A_BCM1480_PMO_INT_0 + ((q>>8)<<8))
+#define A_BCM1480_PMO_INT_OFFSET_0 (A_BCM1480_PMO_INT_0 - A_BCM1480_PM_BASE)
+
+/*
+ * Interrupt registers relative to A_BCM1480_PMI_INT_0 and A_BCM1480_PMO_INT_0
+ */
+
+#define R_BCM1480_PM_INT_ST 0x0000000000
+#define R_BCM1480_PM_INT_MSK 0x0000000040
+#define R_BCM1480_PM_INT_CLR 0x0000000080
+#define R_BCM1480_PM_MRGD_INT 0x00000000C0
+
+/*
+ * Debug registers (global)
+ */
+
+#define A_BCM1480_PM_GLOBALDEBUGMODE_PMI 0x0010056000
+#define A_BCM1480_PM_GLOBALDEBUG_PID 0x00100567F8
+#define A_BCM1480_PM_GLOBALDEBUG_PIB 0x0010056FF8
+#define A_BCM1480_PM_GLOBALDEBUGMODE_PMO 0x0010057000
+#define A_BCM1480_PM_GLOBALDEBUG_POD 0x00100577F8
+#define A_BCM1480_PM_GLOBALDEBUG_POB 0x0010057FF8
+
+/* *********************************************************************
+ * Switch performance counters
+ ********************************************************************* */
+
+#define A_BCM1480_SWPERF_CFG 0xdfb91800
+#define A_BCM1480_SWPERF_CNT0 0xdfb91880
+#define A_BCM1480_SWPERF_CNT1 0xdfb91888
+#define A_BCM1480_SWPERF_CNT2 0xdfb91890
+#define A_BCM1480_SWPERF_CNT3 0xdfb91898
+
+
+/* *********************************************************************
+ * Switch Trace Unit
+ ********************************************************************* */
+
+#define A_BCM1480_SWTRC_MATCH_CONTROL_0 0xDFB91000
+#define A_BCM1480_SWTRC_MATCH_DATA_VALUE_0 0xDFB91100
+#define A_BCM1480_SWTRC_MATCH_DATA_MASK_0 0xDFB91108
+#define A_BCM1480_SWTRC_MATCH_TAG_VALUE_0 0xDFB91200
+#define A_BCM1480_SWTRC_MATCH_TAG_MAKS_0 0xDFB91208
+#define A_BCM1480_SWTRC_EVENT_0 0xDFB91300
+#define A_BCM1480_SWTRC_SEQUENCE_0 0xDFB91400
+
+#define A_BCM1480_SWTRC_CFG 0xDFB91500
+#define A_BCM1480_SWTRC_READ 0xDFB91508
+
+#define A_BCM1480_SWDEBUG_SCHEDSTOP 0xDFB92000
+
+#define A_BCM1480_SWTRC_MATCH_CONTROL(x) (A_BCM1480_SWTRC_MATCH_CONTROL_0 + ((x)*8))
+#define A_BCM1480_SWTRC_EVENT(x) (A_BCM1480_SWTRC_EVENT_0 + ((x)*8))
+#define A_BCM1480_SWTRC_SEQUENCE(x) (A_BCM1480_SWTRC_SEQUENCE_0 + ((x)*8))
+
+#define A_BCM1480_SWTRC_MATCH_DATA_VALUE(x) (A_BCM1480_SWTRC_MATCH_DATA_VALUE_0 + ((x)*16))
+#define A_BCM1480_SWTRC_MATCH_DATA_MASK(x) (A_BCM1480_SWTRC_MATCH_DATA_MASK_0 + ((x)*16))
+#define A_BCM1480_SWTRC_MATCH_TAG_VALUE(x) (A_BCM1480_SWTRC_MATCH_TAG_VALUE_0 + ((x)*16))
+#define A_BCM1480_SWTRC_MATCH_TAG_MASK(x) (A_BCM1480_SWTRC_MATCH_TAG_MASK_0 + ((x)*16))
+
+
+
+/* *********************************************************************
+ * High-Speed Port Registers (Section 13)
+ ********************************************************************* */
+
+#define A_BCM1480_HSP_BASE_0 0x00DF810000
+#define A_BCM1480_HSP_BASE_1 0x00DF890000
+#define A_BCM1480_HSP_BASE_2 0x00DF910000
+#define BCM1480_HSP_REGISTER_SPACING 0x80000
+
+#define A_BCM1480_HSP_BASE(idx) (A_BCM1480_HSP_BASE_0 + ((idx)*BCM1480_HSP_REGISTER_SPACING))
+#define A_BCM1480_HSP_REGISTER(idx,reg) (A_BCM1480_HSP_BASE(idx) + (reg))
+
+#define R_BCM1480_HSP_RX_SPI4_CFG_0 0x0000000000
+#define R_BCM1480_HSP_RX_SPI4_CFG_1 0x0000000008
+#define R_BCM1480_HSP_RX_SPI4_DESKEW_OVERRIDE 0x0000000010
+#define R_BCM1480_HSP_RX_SPI4_DESKEW_DATAPATH 0x0000000018
+#define R_BCM1480_HSP_RX_SPI4_PORT_INT_EN 0x0000000020
+#define R_BCM1480_HSP_RX_SPI4_PORT_INT_STATUS 0x0000000028
+
+#define R_BCM1480_HSP_RX_SPI4_CALENDAR_0 0x0000000200
+#define R_BCM1480_HSP_RX_SPI4_CALENDAR_1 0x0000000208
+
+#define R_BCM1480_HSP_RX_PLL_CNFG 0x0000000800
+#define R_BCM1480_HSP_RX_CALIBRATION 0x0000000808
+#define R_BCM1480_HSP_RX_TEST 0x0000000810
+#define R_BCM1480_HSP_RX_DIAG_DETAILS 0x0000000818
+#define R_BCM1480_HSP_RX_DIAG_CRC_0 0x0000000820
+#define R_BCM1480_HSP_RX_DIAG_CRC_1 0x0000000828
+#define R_BCM1480_HSP_RX_DIAG_HTCMD 0x0000000830
+#define R_BCM1480_HSP_RX_DIAG_PKTCTL 0x0000000838
+
+#define R_BCM1480_HSP_RX_VIS_FLCTRL_COUNTER 0x0000000870
+
+#define R_BCM1480_HSP_RX_PKT_RAMALLOC_0 0x0000020020
+#define R_BCM1480_HSP_RX_PKT_RAMALLOC_1 0x0000020028
+#define R_BCM1480_HSP_RX_PKT_RAMALLOC_2 0x0000020030
+#define R_BCM1480_HSP_RX_PKT_RAMALLOC_3 0x0000020038
+#define R_BCM1480_HSP_RX_PKT_RAMALLOC_4 0x0000020040
+#define R_BCM1480_HSP_RX_PKT_RAMALLOC_5 0x0000020048
+#define R_BCM1480_HSP_RX_PKT_RAMALLOC_6 0x0000020050
+#define R_BCM1480_HSP_RX_PKT_RAMALLOC_7 0x0000020058
+#define R_BCM1480_HSP_RX_PKT_RAMALLOC(idx) (R_BCM1480_HSP_RX_PKT_RAMALLOC_0 + 8*(idx))
+
+/* XXX Following registers were shuffled. Renamed/renumbered per errata. */
+#define R_BCM1480_HSP_RX_HT_RAMALLOC_0 0x0000020078
+#define R_BCM1480_HSP_RX_HT_RAMALLOC_1 0x0000020080
+#define R_BCM1480_HSP_RX_HT_RAMALLOC_2 0x0000020088
+#define R_BCM1480_HSP_RX_HT_RAMALLOC_3 0x0000020090
+#define R_BCM1480_HSP_RX_HT_RAMALLOC_4 0x0000020098
+#define R_BCM1480_HSP_RX_HT_RAMALLOC_5 0x00000200A0
+
+#define R_BCM1480_HSP_RX_SPI_WATERMARK_0 0x00000200B0
+#define R_BCM1480_HSP_RX_SPI_WATERMARK_1 0x00000200B8
+#define R_BCM1480_HSP_RX_SPI_WATERMARK_2 0x00000200C0
+#define R_BCM1480_HSP_RX_SPI_WATERMARK_3 0x00000200C8
+#define R_BCM1480_HSP_RX_SPI_WATERMARK_4 0x00000200D0
+#define R_BCM1480_HSP_RX_SPI_WATERMARK_5 0x00000200D8
+#define R_BCM1480_HSP_RX_SPI_WATERMARK_6 0x00000200E0
+#define R_BCM1480_HSP_RX_SPI_WATERMARK_7 0x00000200E8
+#define R_BCM1480_HSP_RX_SPI_WATERMARK(idx) (R_BCM1480_HSP_RX_SPI_WATERMARK_0 + 8*(idx))
+
+#define R_BCM1480_HSP_RX_VIS_CMDQ_0 0x00000200F0
+#define R_BCM1480_HSP_RX_VIS_CMDQ_1 0x00000200F8
+#define R_BCM1480_HSP_RX_VIS_CMDQ_2 0x0000020100
+#define R_BCM1480_HSP_RX_RAM_READCTL 0x0000020108
+#define R_BCM1480_HSP_RX_RAM_READWINDOW 0x0000020110
+#define R_BCM1480_HSP_RX_RF_READCTL 0x0000020118
+#define R_BCM1480_HSP_RX_RF_READWINDOW 0x0000020120
+
+#define R_BCM1480_HSP_TX_SPI4_CFG_0 0x0000040000
+#define R_BCM1480_HSP_TX_SPI4_CFG_1 0x0000040008
+#define R_BCM1480_HSP_TX_SPI4_TRAINING_FMT 0x0000040010
+
+#define R_BCM1480_HSP_TX_PKT_RAMALLOC_0 0x0000040020
+#define R_BCM1480_HSP_TX_PKT_RAMALLOC_1 0x0000040028
+#define R_BCM1480_HSP_TX_PKT_RAMALLOC_2 0x0000040030
+#define R_BCM1480_HSP_TX_PKT_RAMALLOC_3 0x0000040038
+#define R_BCM1480_HSP_TX_PKT_RAMALLOC_4 0x0000040040
+#define R_BCM1480_HSP_TX_PKT_RAMALLOC_5 0x0000040048
+#define R_BCM1480_HSP_TX_PKT_RAMALLOC_6 0x0000040050
+#define R_BCM1480_HSP_TX_PKT_RAMALLOC_7 0x0000040058
+#define R_BCM1480_HSP_TX_PKT_RAMALLOC(idx) (R_BCM1480_HSP_TX_PKT_RAMALLOC_0 + 8*(idx))
+#define R_BCM1480_HSP_TX_NPC_RAMALLOC 0x0000040078
+#define R_BCM1480_HSP_TX_RSP_RAMALLOC 0x0000040080
+#define R_BCM1480_HSP_TX_PC_RAMALLOC 0x0000040088
+#define R_BCM1480_HSP_TX_HTCC_RAMALLOC_0 0x0000040090
+#define R_BCM1480_HSP_TX_HTCC_RAMALLOC_1 0x0000040098
+#define R_BCM1480_HSP_TX_HTCC_RAMALLOC_2 0x00000400A0
+
+#define R_BCM1480_HSP_TX_PKT_RXPHITCNT_0 0x00000400B0
+#define R_BCM1480_HSP_TX_PKT_RXPHITCNT_1 0x00000400B8
+#define R_BCM1480_HSP_TX_PKT_RXPHITCNT_2 0x00000400C0
+#define R_BCM1480_HSP_TX_PKT_RXPHITCNT_3 0x00000400C8
+#define R_BCM1480_HSP_TX_PKT_RXPHITCNT(idx) (R_BCM1480_HSP_TX_PKT_RXPHITCNT_0 + 8*(idx))
+#define R_BCM1480_HSP_TX_HTIO_RXPHITCNT 0x00000400D0
+#define R_BCM1480_HSP_TX_HTCC_RXPHITCNT 0x00000400D8
+
+#define R_BCM1480_HSP_TX_PKT_TXPHITCNT_0 0x00000400E0
+#define R_BCM1480_HSP_TX_PKT_TXPHITCNT_1 0x00000400E8
+#define R_BCM1480_HSP_TX_PKT_TXPHITCNT_2 0x00000400F0
+#define R_BCM1480_HSP_TX_PKT_TXPHITCNT_3 0x00000400F8
+#define R_BCM1480_HSP_TX_PKT_TXPHITCNT(idx) (R_BCM1480_HSP_TX_PKT_TXPHITCNT_0 + 8*(idx))
+#define R_BCM1480_HSP_TX_HTIO_TXPHITCNT 0x0000040100
+#define R_BCM1480_HSP_TX_HTCC_TXPHITCNT 0x0000040108
+
+#define R_BCM1480_HSP_TX_SPI4_CALENDAR_0 0x0000040200
+#define R_BCM1480_HSP_TX_SPI4_CALENDAR_1 0x0000040208
+
+#define R_BCM1480_HSP_TX_PLL_CNFG 0x0000040800
+#define R_BCM1480_HSP_TX_CALIBRATION 0x0000040808
+#define R_BCM1480_HSP_TX_TEST 0x0000040810
+
+#define R_BCM1480_HSP_TX_VIS_CMDQ_0 0x0000040840
+#define R_BCM1480_HSP_TX_VIS_CMDQ_1 0x0000040848
+#define R_BCM1480_HSP_TX_VIS_CMDQ_2 0x0000040850
+#define R_BCM1480_HSP_TX_RAM_READCTL 0x0000040860
+#define R_BCM1480_HSP_TX_RAM_READWINDOW 0x0000040868
+#define R_BCM1480_HSP_TX_RF_READCTL 0x0000040870
+#define R_BCM1480_HSP_TX_RF_READWINDOW 0x0000040878
+
+#define R_BCM1480_HSP_TX_SPI4_PORT_INT_STATUS 0x0000040880
+#define R_BCM1480_HSP_TX_SPI4_PORT_INT_EN 0x0000040888
+
+#define R_BCM1480_HSP_TX_NEXT_ADDR_BASE 0x000040400
+#define R_BCM1480_HSP_TX_NEXT_ADDR_REGISTER(x) (R_BCM1480_HSP_TX_NEXT_ADDR_BASE+ 8*(x))
+
+
+
+/* *********************************************************************
+ * Physical Address Map (Table 10 and Figure 7)
+ ********************************************************************* */
+
+#define A_BCM1480_PHYS_MEMORY_0 _SB_MAKE64(0x0000000000)
+#define A_BCM1480_PHYS_MEMORY_SIZE _SB_MAKE64((256*1024*1024))
+#define A_BCM1480_PHYS_SYSTEM_CTL _SB_MAKE64(0x0010000000)
+#define A_BCM1480_PHYS_IO_SYSTEM _SB_MAKE64(0x0010060000)
+#define A_BCM1480_PHYS_GENBUS _SB_MAKE64(0x0010090000)
+#define A_BCM1480_PHYS_GENBUS_END _SB_MAKE64(0x0028000000)
+#define A_BCM1480_PHYS_PCI_MISC_MATCH_BYTES _SB_MAKE64(0x0028000000)
+#define A_BCM1480_PHYS_PCI_IACK_MATCH_BYTES _SB_MAKE64(0x0029000000)
+#define A_BCM1480_PHYS_PCI_IO_MATCH_BYTES _SB_MAKE64(0x002C000000)
+#define A_BCM1480_PHYS_PCI_CFG_MATCH_BYTES _SB_MAKE64(0x002E000000)
+#define A_BCM1480_PHYS_PCI_OMAP_MATCH_BYTES _SB_MAKE64(0x002F000000)
+#define A_BCM1480_PHYS_PCI_MEM_MATCH_BYTES _SB_MAKE64(0x0030000000)
+#define A_BCM1480_PHYS_HT_MEM_MATCH_BYTES _SB_MAKE64(0x0040000000)
+#define A_BCM1480_PHYS_HT_MEM_MATCH_BITS _SB_MAKE64(0x0060000000)
+#define A_BCM1480_PHYS_MEMORY_1 _SB_MAKE64(0x0080000000)
+#define A_BCM1480_PHYS_MEMORY_2 _SB_MAKE64(0x0090000000)
+#define A_BCM1480_PHYS_PCI_MISC_MATCH_BITS _SB_MAKE64(0x00A8000000)
+#define A_BCM1480_PHYS_PCI_IACK_MATCH_BITS _SB_MAKE64(0x00A9000000)
+#define A_BCM1480_PHYS_PCI_IO_MATCH_BITS _SB_MAKE64(0x00AC000000)
+#define A_BCM1480_PHYS_PCI_CFG_MATCH_BITS _SB_MAKE64(0x00AE000000)
+#define A_BCM1480_PHYS_PCI_OMAP_MATCH_BITS _SB_MAKE64(0x00AF000000)
+#define A_BCM1480_PHYS_PCI_MEM_MATCH_BITS _SB_MAKE64(0x00B0000000)
+#define A_BCM1480_PHYS_MEMORY_3 _SB_MAKE64(0x00C0000000)
+#define A_BCM1480_PHYS_L2_CACHE_TEST _SB_MAKE64(0x00D0000000)
+#define A_BCM1480_PHYS_HT_SPECIAL_MATCH_BYTES _SB_MAKE64(0x00D8000000)
+#define A_BCM1480_PHYS_HT_IO_MATCH_BYTES _SB_MAKE64(0x00DC000000)
+#define A_BCM1480_PHYS_HT_CFG_MATCH_BYTES _SB_MAKE64(0x00DE000000)
+#define A_BCM1480_PHYS_HS_SUBSYS _SB_MAKE64(0x00DF000000)
+#define A_BCM1480_PHYS_HT_SPECIAL_MATCH_BITS _SB_MAKE64(0x00F8000000)
+#define A_BCM1480_PHYS_HT_IO_MATCH_BITS _SB_MAKE64(0x00FC000000)
+#define A_BCM1480_PHYS_HT_CFG_MATCH_BITS _SB_MAKE64(0x00FE000000)
+#define A_BCM1480_PHYS_MEMORY_EXP _SB_MAKE64(0x0100000000)
+#define A_BCM1480_PHYS_MEMORY_EXP_SIZE _SB_MAKE64((508*1024*1024*1024))
+#define A_BCM1480_PHYS_PCI_UPPER _SB_MAKE64(0x1000000000)
+#define A_BCM1480_PHYS_HT_UPPER_MATCH_BYTES _SB_MAKE64(0x2000000000)
+#define A_BCM1480_PHYS_HT_UPPER_MATCH_BITS _SB_MAKE64(0x3000000000)
+#define A_BCM1480_PHYS_HT_NODE_ALIAS _SB_MAKE64(0x4000000000)
+#define A_BCM1480_PHYS_HT_FULLACCESS _SB_MAKE64(0xF000000000)
+
+
+/* *********************************************************************
+ * L2 Cache as RAM (Table 54)
+ ********************************************************************* */
+
+#define A_BCM1480_PHYS_L2CACHE_WAY_SIZE _SB_MAKE64(0x0000020000)
+#define BCM1480_PHYS_L2CACHE_NUM_WAYS 8
+#define A_BCM1480_PHYS_L2CACHE_TOTAL_SIZE _SB_MAKE64(0x0000100000)
+#define A_BCM1480_PHYS_L2CACHE_WAY0 _SB_MAKE64(0x00D0300000)
+#define A_BCM1480_PHYS_L2CACHE_WAY1 _SB_MAKE64(0x00D0320000)
+#define A_BCM1480_PHYS_L2CACHE_WAY2 _SB_MAKE64(0x00D0340000)
+#define A_BCM1480_PHYS_L2CACHE_WAY3 _SB_MAKE64(0x00D0360000)
+#define A_BCM1480_PHYS_L2CACHE_WAY4 _SB_MAKE64(0x00D0380000)
+#define A_BCM1480_PHYS_L2CACHE_WAY5 _SB_MAKE64(0x00D03A0000)
+#define A_BCM1480_PHYS_L2CACHE_WAY6 _SB_MAKE64(0x00D03C0000)
+#define A_BCM1480_PHYS_L2CACHE_WAY7 _SB_MAKE64(0x00D03E0000)
+
+#endif /* _BCM1480_REGS_H */
diff --git a/include/asm-mips/sibyte/bcm1480_scd.h b/include/asm-mips/sibyte/bcm1480_scd.h
new file mode 100644
index 000000000000..648bed96780f
--- /dev/null
+++ b/include/asm-mips/sibyte/bcm1480_scd.h
@@ -0,0 +1,436 @@
+/* *********************************************************************
+ * BCM1280/BCM1400 Board Support Package
+ *
+ * SCD Constants and Macros File: bcm1480_scd.h
+ *
+ * This module contains constants and macros useful for
+ * manipulating the System Control and Debug module.
+ *
+ * BCM1400 specification level: 1X55_1X80-UM100-R (12/18/03)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ ********************************************************************* */
+
+#ifndef _BCM1480_SCD_H
+#define _BCM1480_SCD_H
+
+#include "sb1250_defs.h"
+
+/* *********************************************************************
+ * Pull in the BCM1250's SCD since lots of stuff is the same.
+ ********************************************************************* */
+
+#include "sb1250_scd.h"
+
+/* *********************************************************************
+ * Some general notes:
+ *
+ * This file is basically a "what's new" header file. Since the
+ * BCM1250 and the new BCM1480 (and derivatives) share many common
+ * features, this file contains only what's new or changed from
+ * the 1250. (above, you can see that we include the 1250 symbols
+ * to get the base functionality).
+ *
+ * In software, be sure to use the correct symbols, particularly
+ * for blocks that are different between the two chip families.
+ * All BCM1480-specific symbols have _BCM1480_ in their names,
+ * and all BCM1250-specific and "base" functions that are common in
+ * both chips have no special names (this is for compatibility with
+ * older include files). Therefore, if you're working with the
+ * SCD, which is very different on each chip, A_SCD_xxx implies
+ * the BCM1250 version and A_BCM1480_SCD_xxx implies the BCM1480
+ * version.
+ ********************************************************************* */
+
+/* *********************************************************************
+ * System control/debug registers
+ ********************************************************************* */
+
+/*
+ * System Identification and Revision Register (Table 12)
+ * Register: SCD_SYSTEM_REVISION
+ * This register is field compatible with the 1250.
+ */
+
+/*
+ * New part definitions
+ */
+
+#define K_SYS_PART_BCM1480 0x1406
+#define K_SYS_PART_BCM1280 0x1206
+#define K_SYS_PART_BCM1455 0x1407
+#define K_SYS_PART_BCM1255 0x1257
+
+/*
+ * Manufacturing Information Register (Table 14)
+ * Register: SCD_SYSTEM_MANUF
+ */
+
+/*
+ * System Configuration Register (Table 15)
+ * Register: SCD_SYSTEM_CFG
+ * Entire register is different from 1250, all new constants below
+ */
+
+#define M_BCM1480_SYS_RESERVED0 _SB_MAKEMASK1(0)
+#define M_BCM1480_SYS_HT_MINRSTCNT _SB_MAKEMASK1(1)
+#define M_BCM1480_SYS_RESERVED2 _SB_MAKEMASK1(2)
+#define M_BCM1480_SYS_RESERVED3 _SB_MAKEMASK1(3)
+#define M_BCM1480_SYS_RESERVED4 _SB_MAKEMASK1(4)
+#define M_BCM1480_SYS_IOB_DIV _SB_MAKEMASK1(5)
+
+#define S_BCM1480_SYS_PLL_DIV _SB_MAKE64(6)
+#define M_BCM1480_SYS_PLL_DIV _SB_MAKEMASK(5,S_BCM1480_SYS_PLL_DIV)
+#define V_BCM1480_SYS_PLL_DIV(x) _SB_MAKEVALUE(x,S_BCM1480_SYS_PLL_DIV)
+#define G_BCM1480_SYS_PLL_DIV(x) _SB_GETVALUE(x,S_BCM1480_SYS_PLL_DIV,M_BCM1480_SYS_PLL_DIV)
+
+#define S_BCM1480_SYS_SW_DIV _SB_MAKE64(11)
+#define M_BCM1480_SYS_SW_DIV _SB_MAKEMASK(5,S_BCM1480_SYS_SW_DIV)
+#define V_BCM1480_SYS_SW_DIV(x) _SB_MAKEVALUE(x,S_BCM1480_SYS_SW_DIV)
+#define G_BCM1480_SYS_SW_DIV(x) _SB_GETVALUE(x,S_BCM1480_SYS_SW_DIV,M_BCM1480_SYS_SW_DIV)
+
+#define M_BCM1480_SYS_PCMCIA_ENABLE _SB_MAKEMASK1(16)
+#define M_BCM1480_SYS_DUART1_ENABLE _SB_MAKEMASK1(17)
+
+#define S_BCM1480_SYS_BOOT_MODE _SB_MAKE64(18)
+#define M_BCM1480_SYS_BOOT_MODE _SB_MAKEMASK(2,S_BCM1480_SYS_BOOT_MODE)
+#define V_BCM1480_SYS_BOOT_MODE(x) _SB_MAKEVALUE(x,S_BCM1480_SYS_BOOT_MODE)
+#define G_BCM1480_SYS_BOOT_MODE(x) _SB_GETVALUE(x,S_BCM1480_SYS_BOOT_MODE,M_BCM1480_SYS_BOOT_MODE)
+#define K_BCM1480_SYS_BOOT_MODE_ROM32 0
+#define K_BCM1480_SYS_BOOT_MODE_ROM8 1
+#define K_BCM1480_SYS_BOOT_MODE_SMBUS_SMALL 2
+#define K_BCM1480_SYS_BOOT_MODE_SMBUS_BIG 3
+#define M_BCM1480_SYS_BOOT_MODE_SMBUS _SB_MAKEMASK1(19)
+
+#define M_BCM1480_SYS_PCI_HOST _SB_MAKEMASK1(20)
+#define M_BCM1480_SYS_PCI_ARBITER _SB_MAKEMASK1(21)
+#define M_BCM1480_SYS_BIG_ENDIAN _SB_MAKEMASK1(22)
+#define M_BCM1480_SYS_GENCLK_EN _SB_MAKEMASK1(23)
+#define M_BCM1480_SYS_GEN_PARITY_EN _SB_MAKEMASK1(24)
+#define M_BCM1480_SYS_RESERVED25 _SB_MAKEMASK1(25)
+
+#define S_BCM1480_SYS_CONFIG 26
+#define M_BCM1480_SYS_CONFIG _SB_MAKEMASK(6,S_BCM1480_SYS_CONFIG)
+#define V_BCM1480_SYS_CONFIG(x) _SB_MAKEVALUE(x,S_BCM1480_SYS_CONFIG)
+#define G_BCM1480_SYS_CONFIG(x) _SB_GETVALUE(x,S_BCM1480_SYS_CONFIG,M_BCM1480_SYS_CONFIG)
+
+#define M_BCM1480_SYS_RESERVED32 _SB_MAKEMASK(32,15)
+
+#define S_BCM1480_SYS_NODEID 47
+#define M_BCM1480_SYS_NODEID _SB_MAKEMASK(4,S_BCM1480_SYS_NODEID)
+#define V_BCM1480_SYS_NODEID(x) _SB_MAKEVALUE(x,S_BCM1480_SYS_NODEID)
+#define G_BCM1480_SYS_NODEID(x) _SB_GETVALUE(x,S_BCM1480_SYS_NODEID,M_BCM1480_SYS_NODEID)
+
+#define M_BCM1480_SYS_CCNUMA_EN _SB_MAKEMASK1(51)
+#define M_BCM1480_SYS_CPU_RESET_0 _SB_MAKEMASK1(52)
+#define M_BCM1480_SYS_CPU_RESET_1 _SB_MAKEMASK1(53)
+#define M_BCM1480_SYS_CPU_RESET_2 _SB_MAKEMASK1(54)
+#define M_BCM1480_SYS_CPU_RESET_3 _SB_MAKEMASK1(55)
+#define S_BCM1480_SYS_DISABLECPU0 56
+#define M_BCM1480_SYS_DISABLECPU0 _SB_MAKEMASK1(S_BCM1480_SYS_DISABLECPU0)
+#define S_BCM1480_SYS_DISABLECPU1 57
+#define M_BCM1480_SYS_DISABLECPU1 _SB_MAKEMASK1(S_BCM1480_SYS_DISABLECPU1)
+#define S_BCM1480_SYS_DISABLECPU2 58
+#define M_BCM1480_SYS_DISABLECPU2 _SB_MAKEMASK1(S_BCM1480_SYS_DISABLECPU2)
+#define S_BCM1480_SYS_DISABLECPU3 59
+#define M_BCM1480_SYS_DISABLECPU3 _SB_MAKEMASK1(S_BCM1480_SYS_DISABLECPU3)
+
+#define M_BCM1480_SYS_SB_SOFTRES _SB_MAKEMASK1(60)
+#define M_BCM1480_SYS_EXT_RESET _SB_MAKEMASK1(61)
+#define M_BCM1480_SYS_SYSTEM_RESET _SB_MAKEMASK1(62)
+#define M_BCM1480_SYS_SW_FLAG _SB_MAKEMASK1(63)
+
+/*
+ * Scratch Register (Table 16)
+ * Register: SCD_SYSTEM_SCRATCH
+ * Same as BCM1250
+ */
+
+
+/*
+ * Mailbox Registers (Table 17)
+ * Registers: SCD_MBOX_{0,1}_CPU_x
+ * Same as BCM1250
+ */
+
+
+/*
+ * See bcm1480_int.h for interrupt mapper registers.
+ */
+
+
+/*
+ * Watchdog Timer Initial Count Registers (Table 23)
+ * Registers: SCD_WDOG_INIT_CNT_x
+ *
+ * The watchdogs are almost the same as the 1250, except
+ * the configuration register has more bits to control the
+ * other CPUs.
+ */
+
+
+/*
+ * Watchdog Timer Configuration Registers (Table 25)
+ * Registers: SCD_WDOG_CFG_x
+ */
+
+#define M_BCM1480_SCD_WDOG_ENABLE _SB_MAKEMASK1(0)
+
+#define S_BCM1480_SCD_WDOG_RESET_TYPE 2
+#define M_BCM1480_SCD_WDOG_RESET_TYPE _SB_MAKEMASK(5,S_BCM1480_SCD_WDOG_RESET_TYPE)
+#define V_BCM1480_SCD_WDOG_RESET_TYPE(x) _SB_MAKEVALUE(x,S_BCM1480_SCD_WDOG_RESET_TYPE)
+#define G_BCM1480_SCD_WDOG_RESET_TYPE(x) _SB_GETVALUE(x,S_BCM1480_SCD_WDOG_RESET_TYPE,M_BCM1480_SCD_WDOG_RESET_TYPE)
+
+#define K_BCM1480_SCD_WDOG_RESET_FULL 0 /* actually, (x & 1) == 0 */
+#define K_BCM1480_SCD_WDOG_RESET_SOFT 1
+#define K_BCM1480_SCD_WDOG_RESET_CPU0 3
+#define K_BCM1480_SCD_WDOG_RESET_CPU1 5
+#define K_BCM1480_SCD_WDOG_RESET_CPU2 9
+#define K_BCM1480_SCD_WDOG_RESET_CPU3 17
+#define K_BCM1480_SCD_WDOG_RESET_ALL_CPUS 31
+
+
+#define M_BCM1480_SCD_WDOG_HAS_RESET _SB_MAKEMASK1(8)
+
+/*
+ * General Timer Initial Count Registers (Table 26)
+ * Registers: SCD_TIMER_INIT_x
+ *
+ * The timer registers are the same as the BCM1250
+ */
+
+
+/*
+ * ZBbus Count Register (Table 29)
+ * Register: ZBBUS_CYCLE_COUNT
+ *
+ * Same as BCM1250
+ */
+
+/*
+ * ZBbus Compare Registers (Table 30)
+ * Registers: ZBBUS_CYCLE_CPx
+ *
+ * Same as BCM1250
+ */
+
+
+/*
+ * System Performance Counter Configuration Register (Table 31)
+ * Register: PERF_CNT_CFG_0
+ *
+ * Since the clear/enable bits are moved compared to the
+ * 1250 and there are more fields, this register will be BCM1480 specific.
+ */
+
+#define S_BCM1480_SPC_CFG_SRC0 0
+#define M_BCM1480_SPC_CFG_SRC0 _SB_MAKEMASK(8,S_BCM1480_SPC_CFG_SRC0)
+#define V_BCM1480_SPC_CFG_SRC0(x) _SB_MAKEVALUE(x,S_BCM1480_SPC_CFG_SRC0)
+#define G_BCM1480_SPC_CFG_SRC0(x) _SB_GETVALUE(x,S_BCM1480_SPC_CFG_SRC0,M_BCM1480_SPC_CFG_SRC0)
+
+#define S_BCM1480_SPC_CFG_SRC1 8
+#define M_BCM1480_SPC_CFG_SRC1 _SB_MAKEMASK(8,S_BCM1480_SPC_CFG_SRC1)
+#define V_BCM1480_SPC_CFG_SRC1(x) _SB_MAKEVALUE(x,S_BCM1480_SPC_CFG_SRC1)
+#define G_BCM1480_SPC_CFG_SRC1(x) _SB_GETVALUE(x,S_BCM1480_SPC_CFG_SRC1,M_BCM1480_SPC_CFG_SRC1)
+
+#define S_BCM1480_SPC_CFG_SRC2 16
+#define M_BCM1480_SPC_CFG_SRC2 _SB_MAKEMASK(8,S_BCM1480_SPC_CFG_SRC2)
+#define V_BCM1480_SPC_CFG_SRC2(x) _SB_MAKEVALUE(x,S_BCM1480_SPC_CFG_SRC2)
+#define G_BCM1480_SPC_CFG_SRC2(x) _SB_GETVALUE(x,S_BCM1480_SPC_CFG_SRC2,M_BCM1480_SPC_CFG_SRC2)
+
+#define S_BCM1480_SPC_CFG_SRC3 24
+#define M_BCM1480_SPC_CFG_SRC3 _SB_MAKEMASK(8,S_BCM1480_SPC_CFG_SRC3)
+#define V_BCM1480_SPC_CFG_SRC3(x) _SB_MAKEVALUE(x,S_BCM1480_SPC_CFG_SRC3)
+#define G_BCM1480_SPC_CFG_SRC3(x) _SB_GETVALUE(x,S_BCM1480_SPC_CFG_SRC3,M_BCM1480_SPC_CFG_SRC3)
+
+#define S_BCM1480_SPC_CFG_SRC4 32
+#define M_BCM1480_SPC_CFG_SRC4 _SB_MAKEMASK(8,S_BCM1480_SPC_CFG_SRC4)
+#define V_BCM1480_SPC_CFG_SRC4(x) _SB_MAKEVALUE(x,S_BCM1480_SPC_CFG_SRC4)
+#define G_BCM1480_SPC_CFG_SRC4(x) _SB_GETVALUE(x,S_BCM1480_SPC_CFG_SRC4,M_BCM1480_SPC_CFG_SRC4)
+
+#define S_BCM1480_SPC_CFG_SRC5 40
+#define M_BCM1480_SPC_CFG_SRC5 _SB_MAKEMASK(8,S_BCM1480_SPC_CFG_SRC5)
+#define V_BCM1480_SPC_CFG_SRC5(x) _SB_MAKEVALUE(x,S_BCM1480_SPC_CFG_SRC5)
+#define G_BCM1480_SPC_CFG_SRC5(x) _SB_GETVALUE(x,S_BCM1480_SPC_CFG_SRC5,M_BCM1480_SPC_CFG_SRC5)
+
+#define S_BCM1480_SPC_CFG_SRC6 48
+#define M_BCM1480_SPC_CFG_SRC6 _SB_MAKEMASK(8,S_BCM1480_SPC_CFG_SRC6)
+#define V_BCM1480_SPC_CFG_SRC6(x) _SB_MAKEVALUE(x,S_BCM1480_SPC_CFG_SRC6)
+#define G_BCM1480_SPC_CFG_SRC6(x) _SB_GETVALUE(x,S_BCM1480_SPC_CFG_SRC6,M_BCM1480_SPC_CFG_SRC6)
+
+#define S_BCM1480_SPC_CFG_SRC7 56
+#define M_BCM1480_SPC_CFG_SRC7 _SB_MAKEMASK(8,S_BCM1480_SPC_CFG_SRC7)
+#define V_BCM1480_SPC_CFG_SRC7(x) _SB_MAKEVALUE(x,S_BCM1480_SPC_CFG_SRC7)
+#define G_BCM1480_SPC_CFG_SRC7(x) _SB_GETVALUE(x,S_BCM1480_SPC_CFG_SRC7,M_BCM1480_SPC_CFG_SRC7)
+
+/*
+ * System Performance Counter Control Register (Table 32)
+ * Register: PERF_CNT_CFG_1
+ * BCM1480 specific
+ */
+
+#define M_BCM1480_SPC_CFG_CLEAR _SB_MAKEMASK1(0)
+#define M_BCM1480_SPC_CFG_ENABLE _SB_MAKEMASK1(1)
+
+/*
+ * System Performance Counters (Table 33)
+ * Registers: PERF_CNT_x
+ */
+
+#define S_BCM1480_SPC_CNT_COUNT 0
+#define M_BCM1480_SPC_CNT_COUNT _SB_MAKEMASK(40,S_BCM1480_SPC_CNT_COUNT)
+#define V_BCM1480_SPC_CNT_COUNT(x) _SB_MAKEVALUE(x,S_BCM1480_SPC_CNT_COUNT)
+#define G_BCM1480_SPC_CNT_COUNT(x) _SB_GETVALUE(x,S_BCM1480_SPC_CNT_COUNT,M_BCM1480_SPC_CNT_COUNT)
+
+#define M_BCM1480_SPC_CNT_OFLOW _SB_MAKEMASK1(40)
+
+
+/*
+ * Bus Watcher Error Status Register (Tables 36, 37)
+ * Registers: BUS_ERR_STATUS, BUS_ERR_STATUS_DEBUG
+ * Same as BCM1250.
+ */
+
+/*
+ * Bus Watcher Error Data Registers (Table 38)
+ * Registers: BUS_ERR_DATA_x
+ * Same as BCM1250.
+ */
+
+/*
+ * Bus Watcher L2 ECC Counter Register (Table 39)
+ * Register: BUS_L2_ERRORS
+ * Same as BCM1250.
+ */
+
+
+/*
+ * Bus Watcher Memory and I/O Error Counter Register (Table 40)
+ * Register: BUS_MEM_IO_ERRORS
+ * Same as BCM1250.
+ */
+
+
+/*
+ * Address Trap Registers
+ *
+ * Register layout same as BCM1250, almost. The bus agents
+ * are different, and the address trap configuration bits are
+ * slightly different.
+ */
+
+#define M_BCM1480_ATRAP_INDEX _SB_MAKEMASK(4,0)
+#define M_BCM1480_ATRAP_ADDRESS _SB_MAKEMASK(40,0)
+
+#define S_BCM1480_ATRAP_CFG_CNT 0
+#define M_BCM1480_ATRAP_CFG_CNT _SB_MAKEMASK(3,S_BCM1480_ATRAP_CFG_CNT)
+#define V_BCM1480_ATRAP_CFG_CNT(x) _SB_MAKEVALUE(x,S_BCM1480_ATRAP_CFG_CNT)
+#define G_BCM1480_ATRAP_CFG_CNT(x) _SB_GETVALUE(x,S_BCM1480_ATRAP_CFG_CNT,M_BCM1480_ATRAP_CFG_CNT)
+
+#define M_BCM1480_ATRAP_CFG_WRITE _SB_MAKEMASK1(3)
+#define M_BCM1480_ATRAP_CFG_ALL _SB_MAKEMASK1(4)
+#define M_BCM1480_ATRAP_CFG_INV _SB_MAKEMASK1(5)
+#define M_BCM1480_ATRAP_CFG_USESRC _SB_MAKEMASK1(6)
+#define M_BCM1480_ATRAP_CFG_SRCINV _SB_MAKEMASK1(7)
+
+#define S_BCM1480_ATRAP_CFG_AGENTID 8
+#define M_BCM1480_ATRAP_CFG_AGENTID _SB_MAKEMASK(4,S_BCM1480_ATRAP_CFG_AGENTID)
+#define V_BCM1480_ATRAP_CFG_AGENTID(x) _SB_MAKEVALUE(x,S_BCM1480_ATRAP_CFG_AGENTID)
+#define G_BCM1480_ATRAP_CFG_AGENTID(x) _SB_GETVALUE(x,S_BCM1480_ATRAP_CFG_AGENTID,M_BCM1480_ATRAP_CFG_AGENTID)
+
+
+#define K_BCM1480_BUS_AGENT_CPU0 0
+#define K_BCM1480_BUS_AGENT_CPU1 1
+#define K_BCM1480_BUS_AGENT_NC 2
+#define K_BCM1480_BUS_AGENT_IOB 3
+#define K_BCM1480_BUS_AGENT_SCD 4
+#define K_BCM1480_BUS_AGENT_L2C 6
+#define K_BCM1480_BUS_AGENT_MC 7
+#define K_BCM1480_BUS_AGENT_CPU2 8
+#define K_BCM1480_BUS_AGENT_CPU3 9
+#define K_BCM1480_BUS_AGENT_PM 10
+
+#define S_BCM1480_ATRAP_CFG_CATTR 12
+#define M_BCM1480_ATRAP_CFG_CATTR _SB_MAKEMASK(2,S_BCM1480_ATRAP_CFG_CATTR)
+#define V_BCM1480_ATRAP_CFG_CATTR(x) _SB_MAKEVALUE(x,S_BCM1480_ATRAP_CFG_CATTR)
+#define G_BCM1480_ATRAP_CFG_CATTR(x) _SB_GETVALUE(x,S_BCM1480_ATRAP_CFG_CATTR,M_BCM1480_ATRAP_CFG_CATTR)
+
+#define K_BCM1480_ATRAP_CFG_CATTR_IGNORE 0
+#define K_BCM1480_ATRAP_CFG_CATTR_UNC 1
+#define K_BCM1480_ATRAP_CFG_CATTR_NONCOH 2
+#define K_BCM1480_ATRAP_CFG_CATTR_COHERENT 3
+
+#define M_BCM1480_ATRAP_CFG_CATTRINV _SB_MAKEMASK1(14)
+
+
+/*
+ * Trace Event Registers (Table 47)
+ * Same as BCM1250.
+ */
+
+/*
+ * Trace Sequence Control Registers (Table 48)
+ * Registers: TRACE_SEQUENCE_x
+ *
+ * Same as BCM1250 except for two new fields.
+ */
+
+
+#define M_BCM1480_SCD_TRSEQ_TID_MATCH_EN _SB_MAKEMASK1(25)
+
+#define S_BCM1480_SCD_TRSEQ_SWFUNC 26
+#define M_BCM1480_SCD_TRSEQ_SWFUNC _SB_MAKEMASK(2,S_BCM1480_SCD_TRSEQ_SWFUNC)
+#define V_BCM1480_SCD_TRSEQ_SWFUNC(x) _SB_MAKEVALUE(x,S_BCM1480_SCD_TRSEQ_SWFUNC)
+#define G_BCM1480_SCD_TRSEQ_SWFUNC(x) _SB_GETVALUE(x,S_BCM1480_SCD_TRSEQ_SWFUNC,M_BCM1480_SCD_TRSEQ_SWFUNC)
+
+/*
+ * Trace Control Register (Table 49)
+ * Register: TRACE_CFG
+ *
+ * Bits 0..8 are the same as the BCM1250, rest are different.
+ * Entire register is redefined below.
+ */
+
+#define M_BCM1480_SCD_TRACE_CFG_RESET _SB_MAKEMASK1(0)
+#define M_BCM1480_SCD_TRACE_CFG_START_READ _SB_MAKEMASK1(1)
+#define M_BCM1480_SCD_TRACE_CFG_START _SB_MAKEMASK1(2)
+#define M_BCM1480_SCD_TRACE_CFG_STOP _SB_MAKEMASK1(3)
+#define M_BCM1480_SCD_TRACE_CFG_FREEZE _SB_MAKEMASK1(4)
+#define M_BCM1480_SCD_TRACE_CFG_FREEZE_FULL _SB_MAKEMASK1(5)
+#define M_BCM1480_SCD_TRACE_CFG_DEBUG_FULL _SB_MAKEMASK1(6)
+#define M_BCM1480_SCD_TRACE_CFG_FULL _SB_MAKEMASK1(7)
+#define M_BCM1480_SCD_TRACE_CFG_FORCE_CNT _SB_MAKEMASK1(8)
+
+#define S_BCM1480_SCD_TRACE_CFG_MODE 16
+#define M_BCM1480_SCD_TRACE_CFG_MODE _SB_MAKEMASK(2,S_BCM1480_SCD_TRACE_CFG_MODE)
+#define V_BCM1480_SCD_TRACE_CFG_MODE(x) _SB_MAKEVALUE(x,S_BCM1480_SCD_TRACE_CFG_MODE)
+#define G_BCM1480_SCD_TRACE_CFG_MODE(x) _SB_GETVALUE(x,S_BCM1480_SCD_TRACE_CFG_MODE,M_BCM1480_SCD_TRACE_CFG_MODE)
+
+#define K_BCM1480_SCD_TRACE_CFG_MODE_BLOCKERS 0
+#define K_BCM1480_SCD_TRACE_CFG_MODE_BYTEEN_INT 1
+#define K_BCM1480_SCD_TRACE_CFG_MODE_FLOW_ID 2
+
+#define S_BCM1480_SCD_TRACE_CFG_CUR_ADDR 24
+#define M_BCM1480_SCD_TRACE_CFG_CUR_ADDR _SB_MAKEMASK(8,S_BCM1480_SCD_TRACE_CFG_CUR_ADDR)
+#define V_BCM1480_SCD_TRACE_CFG_CUR_ADDR(x) _SB_MAKEVALUE(x,S_BCM1480_SCD_TRACE_CFG_CUR_ADDR)
+#define G_BCM1480_SCD_TRACE_CFG_CUR_ADDR(x) _SB_GETVALUE(x,S_BCM1480_SCD_TRACE_CFG_CUR_ADDR,M_BCM1480_SCD_TRACE_CFG_CUR_ADDR)
+
+#endif /* _BCM1480_SCD_H */
diff --git a/include/asm-mips/sibyte/bigsur.h b/include/asm-mips/sibyte/bigsur.h
new file mode 100644
index 000000000000..ebefe797fc1d
--- /dev/null
+++ b/include/asm-mips/sibyte/bigsur.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2000,2001,2002,2003,2004 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef __ASM_SIBYTE_BIGSUR_H
+#define __ASM_SIBYTE_BIGSUR_H
+
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/bcm1480_int.h>
+
+#ifdef CONFIG_SIBYTE_BIGSUR
+#define SIBYTE_BOARD_NAME "BCM91x80A/B (BigSur)"
+#define SIBYTE_HAVE_PCMCIA 1
+#define SIBYTE_HAVE_IDE 1
+#endif
+
+/* Generic bus chip selects */
+#define LEDS_CS 3
+#define LEDS_PHYS 0x100a0000
+
+#ifdef SIBYTE_HAVE_IDE
+#define IDE_CS 4
+#define IDE_PHYS 0x100b0000
+#define K_GPIO_GB_IDE 4
+#define K_INT_GB_IDE (K_INT_GPIO_0 + K_GPIO_GB_IDE)
+#endif
+
+#ifdef SIBYTE_HAVE_PCMCIA
+#define PCMCIA_CS 6
+#define PCMCIA_PHYS 0x11000000
+#define K_GPIO_PC_READY 9
+#define K_INT_PC_READY (K_INT_GPIO_0 + K_GPIO_PC_READY)
+#endif
+
+#endif /* __ASM_SIBYTE_BIGSUR_H */
+
diff --git a/include/asm-mips/sibyte/board.h b/include/asm-mips/sibyte/board.h
index d7b11b6c7c32..900edcbeec37 100644
--- a/include/asm-mips/sibyte/board.h
+++ b/include/asm-mips/sibyte/board.h
@@ -21,8 +21,6 @@
#include <linux/config.h>
-#ifdef CONFIG_SIBYTE_BOARD
-
#if defined(CONFIG_SIBYTE_SWARM) || defined(CONFIG_SIBYTE_PTSWARM) || \
defined(CONFIG_SIBYTE_CRHONE) || defined(CONFIG_SIBYTE_CRHINE) || \
defined(CONFIG_SIBYTE_LITTLESUR)
@@ -37,6 +35,10 @@
#include <asm/sibyte/carmel.h>
#endif
+#ifdef CONFIG_SIBYTE_BIGSUR
+#include <asm/sibyte/bigsur.h>
+#endif
+
#ifdef __ASSEMBLY__
#ifdef LEDS_PHYS
@@ -54,16 +56,6 @@
#define setleds(t0,t1,c0,c1,c2,c3)
#endif /* LEDS_PHYS */
-#else
-
-#ifdef LEDS_PHYS
-extern void setleds(char *str);
-#else
-#define setleds(s) do { } while (0)
-#endif /* LEDS_PHYS */
-
#endif /* __ASSEMBLY__ */
-#endif /* CONFIG_SIBYTE_BOARD */
-
#endif /* _SIBYTE_BOARD_H */
diff --git a/include/asm-mips/sibyte/sb1250.h b/include/asm-mips/sibyte/sb1250.h
index d62da4e2dd36..a474c29cd701 100644
--- a/include/asm-mips/sibyte/sb1250.h
+++ b/include/asm-mips/sibyte/sb1250.h
@@ -27,6 +27,9 @@
#define SB1250_NR_IRQS 64
+#define BCM1480_NR_IRQS 128
+#define BCM1480_NR_IRQS_HALF 64
+
#define SB1250_DUART_MINOR_BASE 64
#ifndef __ASSEMBLY__
@@ -35,6 +38,7 @@
/* For revision/pass information */
#include <asm/sibyte/sb1250_scd.h>
+#include <asm/sibyte/bcm1480_scd.h>
extern unsigned int sb1_pass;
extern unsigned int soc_pass;
extern unsigned int soc_type;
@@ -46,6 +50,13 @@ extern unsigned long sb1250_gettimeoffset(void);
extern void sb1250_mask_irq(int cpu, int irq);
extern void sb1250_unmask_irq(int cpu, int irq);
extern void sb1250_smp_finish(void);
+
+extern void bcm1480_time_init(void);
+extern unsigned long bcm1480_gettimeoffset(void);
+extern void bcm1480_mask_irq(int cpu, int irq);
+extern void bcm1480_unmask_irq(int cpu, int irq);
+extern void bcm1480_smp_finish(void);
+
extern void prom_printf(char *fmt, ...);
#define AT_spin \
@@ -58,6 +69,6 @@ extern void prom_printf(char *fmt, ...);
#endif
-#define IOADDR(a) (IO_BASE + (a))
+#define IOADDR(a) ((volatile void __iomem *)(IO_BASE + (a)))
#endif
diff --git a/include/asm-mips/sibyte/sb1250_defs.h b/include/asm-mips/sibyte/sb1250_defs.h
index 40ef97c76c8b..335dbaf1d831 100644
--- a/include/asm-mips/sibyte/sb1250_defs.h
+++ b/include/asm-mips/sibyte/sb1250_defs.h
@@ -8,8 +8,6 @@
*
* SB1250 specification level: User's manual 1/02/02
*
- * Author: Mitch Lichtenberg
- *
*********************************************************************
*
* Copyright 2000,2001,2002,2003
@@ -97,13 +95,17 @@
* ordering, so be careful when adding support for new minor revs.
********************************************************************* */
-#define SIBYTE_HDR_FMASK_1250_ALL 0x00000ff
-#define SIBYTE_HDR_FMASK_1250_PASS1 0x0000001
-#define SIBYTE_HDR_FMASK_1250_PASS2 0x0000002
-#define SIBYTE_HDR_FMASK_1250_PASS3 0x0000004
+#define SIBYTE_HDR_FMASK_1250_ALL 0x000000ff
+#define SIBYTE_HDR_FMASK_1250_PASS1 0x00000001
+#define SIBYTE_HDR_FMASK_1250_PASS2 0x00000002
+#define SIBYTE_HDR_FMASK_1250_PASS3 0x00000004
+
+#define SIBYTE_HDR_FMASK_112x_ALL 0x00000f00
+#define SIBYTE_HDR_FMASK_112x_PASS1 0x00000100
-#define SIBYTE_HDR_FMASK_112x_ALL 0x0000f00
-#define SIBYTE_HDR_FMASK_112x_PASS1 0x0000100
+#define SIBYTE_HDR_FMASK_1480_ALL 0x0000f000
+#define SIBYTE_HDR_FMASK_1480_PASS1 0x00001000
+#define SIBYTE_HDR_FMASK_1480_PASS2 0x00002000
/* Bit mask for chip/revision. (use _ALL for all revisions of a chip). */
#define SIBYTE_HDR_FMASK(chip, pass) \
@@ -111,8 +113,17 @@
#define SIBYTE_HDR_FMASK_ALLREVS(chip) \
(SIBYTE_HDR_FMASK_ ## chip ## _ALL)
+/* Default constant value for all chips, all revisions */
#define SIBYTE_HDR_FMASK_ALL \
+ (SIBYTE_HDR_FMASK_1250_ALL | SIBYTE_HDR_FMASK_112x_ALL \
+ | SIBYTE_HDR_FMASK_1480_ALL)
+
+/* This one is used for the "original" BCM1250/BCM112x chips. We use this
+ to weed out constants and macros that do not exist on later chips like
+ the BCM1480 */
+#define SIBYTE_HDR_FMASK_1250_112x_ALL \
(SIBYTE_HDR_FMASK_1250_ALL | SIBYTE_HDR_FMASK_112x_ALL)
+#define SIBYTE_HDR_FMASK_1250_112x SIBYTE_HDR_FMASK_1250_112x_ALL
#ifndef SIBYTE_HDR_FEATURES
#define SIBYTE_HDR_FEATURES SIBYTE_HDR_FMASK_ALL
@@ -133,6 +144,12 @@
#define SIBYTE_HDR_FEATURE_CHIP(chip) \
(!! (SIBYTE_HDR_FMASK_ALLREVS(chip) & SIBYTE_HDR_FEATURES))
+/* True for all versions of the BCM1250 and BCM1125, but not true for
+ anything else */
+#define SIBYTE_HDR_FEATURE_1250_112x \
+ (SIBYTE_HDR_FEATURE_CHIP(1250) || SIBYTE_HDR_FEATURE_CHIP(112x))
+/* (!! (SIBYTE_HDR_FEATURES & SIBYHTE_HDR_FMASK_1250_112x)) */
+
/* True if header features enabled for that rev or later, inclusive. */
#define SIBYTE_HDR_FEATURE(chip, pass) \
(!! ((SIBYTE_HDR_FMASK(chip, pass) \
diff --git a/include/asm-mips/sibyte/sb1250_dma.h b/include/asm-mips/sibyte/sb1250_dma.h
index 3cdb48f50ed0..e6145f524fbd 100644
--- a/include/asm-mips/sibyte/sb1250_dma.h
+++ b/include/asm-mips/sibyte/sb1250_dma.h
@@ -7,9 +7,8 @@
* programming the SB1250's DMA controllers, both the data mover
* and the Ethernet DMA.
*
- * SB1250 specification level: User's manual 1/02/02
- *
- * Author: Mitch Lichtenberg
+ * SB1250 specification level: User's manual 10/21/02
+ * BCM1280 specification level: User's manual 11/24/03
*
*********************************************************************
*
@@ -58,17 +57,17 @@
#define M_DMA_RESERVED1 _SB_MAKEMASK1(2)
#define S_DMA_DESC_TYPE _SB_MAKE64(1)
-#define M_DMA_DESC_TYPE _SB_MAKE64(2,S_DMA_DESC_TYPE)
+#define M_DMA_DESC_TYPE _SB_MAKEMASK(2,S_DMA_DESC_TYPE)
#define V_DMA_DESC_TYPE(x) _SB_MAKEVALUE(x,S_DMA_DESC_TYPE)
#define G_DMA_DESC_TYPE(x) _SB_GETVALUE(x,S_DMA_DESC_TYPE,M_DMA_DESC_TYPE)
#define K_DMA_DESC_TYPE_RING_AL 0
#define K_DMA_DESC_TYPE_CHAIN_AL 1
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define K_DMA_DESC_TYPE_RING_UAL_WI 2
#define K_DMA_DESC_TYPE_RING_UAL_RMW 3
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
#define M_DMA_EOP_INT_EN _SB_MAKEMASK1(3)
#define M_DMA_HWM_INT_EN _SB_MAKEMASK1(4)
@@ -111,11 +110,11 @@
#define M_DMA_NO_DSCR_UPDT _SB_MAKEMASK1(4)
#define M_DMA_L2CA _SB_MAKEMASK1(5)
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define M_DMA_RX_XTRA_STATUS _SB_MAKEMASK1(6)
#define M_DMA_TX_CPU_PAUSE _SB_MAKEMASK1(6)
#define M_DMA_TX_FC_PAUSE_EN _SB_MAKEMASK1(7)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
#define M_DMA_MBZ1 _SB_MAKEMASK(6,15)
@@ -165,14 +164,14 @@
#define S_DMA_CURDSCR_COUNT _SB_MAKE64(40)
#define M_DMA_CURDSCR_COUNT _SB_MAKEMASK(16,S_DMA_CURDSCR_COUNT)
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define M_DMA_TX_CH_PAUSE_ON _SB_MAKEMASK1(56)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
/*
* Receive Packet Drop Registers
*/
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define S_DMA_OODLOST_RX _SB_MAKE64(0)
#define M_DMA_OODLOST_RX _SB_MAKEMASK(16,S_DMA_OODLOST_RX)
#define G_DMA_OODLOST_RX(x) _SB_GETVALUE(x,S_DMA_OODLOST_RX,M_DMA_OODLOST_RX)
@@ -180,7 +179,7 @@
#define S_DMA_EOP_COUNT_RX _SB_MAKE64(16)
#define M_DMA_EOP_COUNT_RX _SB_MAKEMASK(8,S_DMA_EOP_COUNT_RX)
#define G_DMA_EOP_COUNT_RX(x) _SB_GETVALUE(x,S_DMA_EOP_COUNT_RX,M_DMA_EOP_COUNT_RX)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
/* *********************************************************************
* DMA Descriptors
@@ -201,21 +200,21 @@
#define M_DMA_DSCRA_A_ADDR_OFFSET (M_DMA_DSCRA_OFFSET | M_DMA_DSCRA_A_ADDR)
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define S_DMA_DSCRA_A_ADDR_UA _SB_MAKE64(0)
#define M_DMA_DSCRA_A_ADDR_UA _SB_MAKEMASK(40,S_DMA_DSCRA_A_ADDR_UA)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
#define S_DMA_DSCRA_A_SIZE _SB_MAKE64(40)
#define M_DMA_DSCRA_A_SIZE _SB_MAKEMASK(9,S_DMA_DSCRA_A_SIZE)
#define V_DMA_DSCRA_A_SIZE(x) _SB_MAKEVALUE(x,S_DMA_DSCRA_A_SIZE)
#define G_DMA_DSCRA_A_SIZE(x) _SB_GETVALUE(x,S_DMA_DSCRA_A_SIZE,M_DMA_DSCRA_A_SIZE)
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define S_DMA_DSCRA_DSCR_CNT _SB_MAKE64(40)
#define M_DMA_DSCRA_DSCR_CNT _SB_MAKEMASK(8,S_DMA_DSCRA_DSCR_CNT)
#define G_DMA_DSCRA_DSCR_CNT(x) _SB_GETVALUE(x,S_DMA_DSCRA_DSCR_CNT,M_DMA_DSCRA_DSCR_CNT)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
#define M_DMA_DSCRA_INTERRUPT _SB_MAKEMASK1(49)
#define M_DMA_DSCRA_OFFSETB _SB_MAKEMASK1(50)
@@ -235,12 +234,12 @@
#define V_DMA_DSCRB_OPTIONS(x) _SB_MAKEVALUE(x,S_DMA_DSCRB_OPTIONS)
#define G_DMA_DSCRB_OPTIONS(x) _SB_GETVALUE(x,S_DMA_DSCRB_OPTIONS,M_DMA_DSCRB_OPTIONS)
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define S_DMA_DSCRB_A_SIZE _SB_MAKE64(8)
#define M_DMA_DSCRB_A_SIZE _SB_MAKEMASK(14,S_DMA_DSCRB_A_SIZE)
#define V_DMA_DSCRB_A_SIZE(x) _SB_MAKEVALUE(x,S_DMA_DSCRB_A_SIZE)
#define G_DMA_DSCRB_A_SIZE(x) _SB_GETVALUE(x,S_DMA_DSCRB_A_SIZE,M_DMA_DSCRB_A_SIZE)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
#define R_DMA_DSCRB_ADDR _SB_MAKE64(0x10)
@@ -255,12 +254,12 @@
#define M_DMA_DSCRB_B_VALID _SB_MAKEMASK1(49)
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define S_DMA_DSCRB_PKT_SIZE_MSB _SB_MAKE64(48)
#define M_DMA_DSCRB_PKT_SIZE_MSB _SB_MAKEMASK(2,S_DMA_DSCRB_PKT_SIZE_MSB)
#define V_DMA_DSCRB_PKT_SIZE_MSB(x) _SB_MAKEVALUE(x,S_DMA_DSCRB_PKT_SIZE_MSB)
#define G_DMA_DSCRB_PKT_SIZE_MSB(x) _SB_GETVALUE(x,S_DMA_DSCRB_PKT_SIZE_MSB,M_DMA_DSCRB_PKT_SIZE_MSB)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
#define S_DMA_DSCRB_PKT_SIZE _SB_MAKE64(50)
#define M_DMA_DSCRB_PKT_SIZE _SB_MAKEMASK(14,S_DMA_DSCRB_PKT_SIZE)
@@ -282,15 +281,16 @@
#define M_DMA_ETHRX_BADIP4CS _SB_MAKEMASK1(51)
#define M_DMA_ETHRX_DSCRERR _SB_MAKEMASK1(52)
-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
-/* Note: BADTCPCS is actually in DSCR_B options field */
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+/* Note: This bit is in the DSCR_B options field */
#define M_DMA_ETHRX_BADTCPCS _SB_MAKEMASK1(0)
-#endif /* 1250 PASS2 || 112x PASS1 */
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+/* Note: These bits are in the DSCR_B options field */
#define M_DMA_ETH_VLAN_FLAG _SB_MAKEMASK1(1)
#define M_DMA_ETH_CRC_FLAG _SB_MAKEMASK1(2)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
#define S_DMA_ETHRX_RXCH 53
#define M_DMA_ETHRX_RXCH _SB_MAKEMASK(2,S_DMA_ETHRX_RXCH)
@@ -438,7 +438,7 @@
M_DM_CUR_DSCR_DSCR_COUNT)
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
/*
* Data Mover Channel Partial Result Registers
* Register: DM_PARTIAL_0
@@ -459,10 +459,10 @@
M_DM_PARTIAL_TCPCS_PARTIAL)
#define M_DM_PARTIAL_ODD_BYTE _SB_MAKEMASK1(48)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
/*
* Data Mover CRC Definition Registers
* Register: CRC_DEF_0
@@ -479,10 +479,10 @@
#define V_CRC_DEF_CRC_POLY(r) _SB_MAKEVALUE(r,S_CRC_DEF_CRC_POLY)
#define G_CRC_DEF_CRC_POLY(r) _SB_GETVALUE(r,S_CRC_DEF_CRC_POLY,\
M_CRC_DEF_CRC_POLY)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
/*
* Data Mover CRC/Checksum Definition Registers
* Register: CTCP_DEF_0
@@ -511,7 +511,7 @@
#define K_CTCP_DEF_CRC_WIDTH_1 2
#define M_CTCP_DEF_CRC_BIT_ORDER _SB_MAKEMASK1(50)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
/*
@@ -560,12 +560,12 @@
#define M_DM_DSCRA_L2C_DEST _SB_MAKEMASK1(50)
#define M_DM_DSCRA_L2C_SRC _SB_MAKEMASK1(51)
-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define M_DM_DSCRA_RD_BKOFF _SB_MAKEMASK1(52)
#define M_DM_DSCRA_WR_BKOFF _SB_MAKEMASK1(53)
-#endif /* 1250 PASS2 || 112x PASS1 */
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define M_DM_DSCRA_TCPCS_EN _SB_MAKEMASK1(54)
#define M_DM_DSCRA_TCPCS_RES _SB_MAKEMASK1(55)
#define M_DM_DSCRA_TCPCS_AP _SB_MAKEMASK1(56)
@@ -574,7 +574,7 @@
#define M_DM_DSCRA_CRC_AP _SB_MAKEMASK1(59)
#define M_DM_DSCRA_CRC_DFN _SB_MAKEMASK1(60)
#define M_DM_DSCRA_CRC_XBIT _SB_MAKEMASK1(61)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
#define M_DM_DSCRA_RESERVED2 _SB_MAKEMASK(3,61)
diff --git a/include/asm-mips/sibyte/sb1250_genbus.h b/include/asm-mips/sibyte/sb1250_genbus.h
index f1f509f295c4..1b5cbc5c6454 100644
--- a/include/asm-mips/sibyte/sb1250_genbus.h
+++ b/include/asm-mips/sibyte/sb1250_genbus.h
@@ -6,9 +6,8 @@
* This module contains constants and macros useful for
* manipulating the SB1250's Generic Bus interface
*
- * SB1250 specification level: User's manual 1/02/02
- *
- * Author: Mitch Lichtenberg
+ * SB1250 specification level: User's manual 10/21/02
+ * BCM1280 specification level: User's Manual 11/14/03
*
*********************************************************************
*
@@ -51,19 +50,21 @@
#define M_IO_WIDTH_SEL _SB_MAKEMASK(2,S_IO_WIDTH_SEL)
#define K_IO_WIDTH_SEL_1 0
#define K_IO_WIDTH_SEL_2 1
-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) \
+ || SIBYTE_HDR_FEATURE_CHIP(1480)
#define K_IO_WIDTH_SEL_1L 2
-#endif /* 1250 PASS2 || 112x PASS1 */
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
#define K_IO_WIDTH_SEL_4 3
#define V_IO_WIDTH_SEL(x) _SB_MAKEVALUE(x,S_IO_WIDTH_SEL)
#define G_IO_WIDTH_SEL(x) _SB_GETVALUE(x,S_IO_WIDTH_SEL,M_IO_WIDTH_SEL)
#define S_IO_PARITY_ENA 4
#define M_IO_PARITY_ENA _SB_MAKEMASK1(S_IO_PARITY_ENA)
-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) \
+ || SIBYTE_HDR_FEATURE_CHIP(1480)
#define S_IO_BURST_EN 5
#define M_IO_BURST_EN _SB_MAKEMASK1(S_IO_BURST_EN)
-#endif /* 1250 PASS2 || 112x PASS1 */
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
#define S_IO_PARITY_ODD 6
#define M_IO_PARITY_ODD _SB_MAKEMASK1(S_IO_PARITY_ODD)
#define S_IO_NONMUX 7
@@ -96,8 +97,11 @@
#define S_IO_ADDRBASE 16 /* # bits to shift addr for this reg */
+#define M_IO_BLK_CACHE _SB_MAKEMASK1(15)
+
+
/*
- * Generic Bus Region 0 Timing Registers (Table 11-7)
+ * Generic Bus Timing 0 Registers (Table 11-7)
*/
#define S_IO_ALE_WIDTH 0
@@ -105,21 +109,23 @@
#define V_IO_ALE_WIDTH(x) _SB_MAKEVALUE(x,S_IO_ALE_WIDTH)
#define G_IO_ALE_WIDTH(x) _SB_GETVALUE(x,S_IO_ALE_WIDTH,M_IO_ALE_WIDTH)
-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) \
+ || SIBYTE_HDR_FEATURE_CHIP(1480)
#define M_IO_EARLY_CS _SB_MAKEMASK1(3)
-#endif /* 1250 PASS2 || 112x PASS1 */
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
#define S_IO_ALE_TO_CS 4
#define M_IO_ALE_TO_CS _SB_MAKEMASK(2,S_IO_ALE_TO_CS)
#define V_IO_ALE_TO_CS(x) _SB_MAKEVALUE(x,S_IO_ALE_TO_CS)
#define G_IO_ALE_TO_CS(x) _SB_GETVALUE(x,S_IO_ALE_TO_CS,M_IO_ALE_TO_CS)
-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) \
+ || SIBYTE_HDR_FEATURE_CHIP(1480)
#define S_IO_BURST_WIDTH _SB_MAKE64(6)
#define M_IO_BURST_WIDTH _SB_MAKEMASK(2,S_IO_BURST_WIDTH)
#define V_IO_BURST_WIDTH(x) _SB_MAKEVALUE(x,S_IO_BURST_WIDTH)
#define G_IO_BURST_WIDTH(x) _SB_GETVALUE(x,S_IO_BURST_WIDTH,M_IO_BURST_WIDTH)
-#endif /* 1250 PASS2 || 112x PASS1 */
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
#define S_IO_CS_WIDTH 8
#define M_IO_CS_WIDTH _SB_MAKEMASK(5,S_IO_CS_WIDTH)
@@ -141,9 +147,10 @@
#define V_IO_ALE_TO_WRITE(x) _SB_MAKEVALUE(x,S_IO_ALE_TO_WRITE)
#define G_IO_ALE_TO_WRITE(x) _SB_GETVALUE(x,S_IO_ALE_TO_WRITE,M_IO_ALE_TO_WRITE)
-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) \
+ || SIBYTE_HDR_FEATURE_CHIP(1480)
#define M_IO_RDY_SYNC _SB_MAKEMASK1(3)
-#endif /* 1250 PASS2 || 112x PASS1 */
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
#define S_IO_WRITE_WIDTH 4
#define M_IO_WRITE_WIDTH _SB_MAKEMASK(4,S_IO_WRITE_WIDTH)
@@ -183,9 +190,127 @@
#define M_IO_TIMEOUT_INT _SB_MAKEMASK1(10)
#define M_IO_ILL_ADDR_INT _SB_MAKEMASK1(11)
#define M_IO_MULT_CS_INT _SB_MAKEMASK1(12)
-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define M_IO_COH_ERR _SB_MAKEMASK1(14)
-#endif /* 1250 PASS2 || 112x PASS1 */
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+
+
+/*
+ * Generic Bus Output Drive Control Register 0 (Table 14-18)
+ */
+
+#define S_IO_SLEW0 0
+#define M_IO_SLEW0 _SB_MAKEMASK(2,S_IO_SLEW0)
+#define V_IO_SLEW0(x) _SB_MAKEVALUE(x,S_IO_SLEW0)
+#define G_IO_SLEW0(x) _SB_GETVALUE(x,S_IO_SLEW0,M_IO_SLEW0)
+
+#define S_IO_DRV_A 2
+#define M_IO_DRV_A _SB_MAKEMASK(2,S_IO_DRV_A)
+#define V_IO_DRV_A(x) _SB_MAKEVALUE(x,S_IO_DRV_A)
+#define G_IO_DRV_A(x) _SB_GETVALUE(x,S_IO_DRV_A,M_IO_DRV_A)
+
+#define S_IO_DRV_B 6
+#define M_IO_DRV_B _SB_MAKEMASK(2,S_IO_DRV_B)
+#define V_IO_DRV_B(x) _SB_MAKEVALUE(x,S_IO_DRV_B)
+#define G_IO_DRV_B(x) _SB_GETVALUE(x,S_IO_DRV_B,M_IO_DRV_B)
+
+#define S_IO_DRV_C 10
+#define M_IO_DRV_C _SB_MAKEMASK(2,S_IO_DRV_C)
+#define V_IO_DRV_C(x) _SB_MAKEVALUE(x,S_IO_DRV_C)
+#define G_IO_DRV_C(x) _SB_GETVALUE(x,S_IO_DRV_C,M_IO_DRV_C)
+
+#define S_IO_DRV_D 14
+#define M_IO_DRV_D _SB_MAKEMASK(2,S_IO_DRV_D)
+#define V_IO_DRV_D(x) _SB_MAKEVALUE(x,S_IO_DRV_D)
+#define G_IO_DRV_D(x) _SB_GETVALUE(x,S_IO_DRV_D,M_IO_DRV_D)
+
+/*
+ * Generic Bus Output Drive Control Register 1 (Table 14-19)
+ */
+
+#define S_IO_DRV_E 2
+#define M_IO_DRV_E _SB_MAKEMASK(2,S_IO_DRV_E)
+#define V_IO_DRV_E(x) _SB_MAKEVALUE(x,S_IO_DRV_E)
+#define G_IO_DRV_E(x) _SB_GETVALUE(x,S_IO_DRV_E,M_IO_DRV_E)
+
+#define S_IO_DRV_F 6
+#define M_IO_DRV_F _SB_MAKEMASK(2,S_IO_DRV_F)
+#define V_IO_DRV_F(x) _SB_MAKEVALUE(x,S_IO_DRV_F)
+#define G_IO_DRV_F(x) _SB_GETVALUE(x,S_IO_DRV_F,M_IO_DRV_F)
+
+#define S_IO_SLEW1 8
+#define M_IO_SLEW1 _SB_MAKEMASK(2,S_IO_SLEW1)
+#define V_IO_SLEW1(x) _SB_MAKEVALUE(x,S_IO_SLEW1)
+#define G_IO_SLEW1(x) _SB_GETVALUE(x,S_IO_SLEW1,M_IO_SLEW1)
+
+#define S_IO_DRV_G 10
+#define M_IO_DRV_G _SB_MAKEMASK(2,S_IO_DRV_G)
+#define V_IO_DRV_G(x) _SB_MAKEVALUE(x,S_IO_DRV_G)
+#define G_IO_DRV_G(x) _SB_GETVALUE(x,S_IO_DRV_G,M_IO_DRV_G)
+
+#define S_IO_SLEW2 12
+#define M_IO_SLEW2 _SB_MAKEMASK(2,S_IO_SLEW2)
+#define V_IO_SLEW2(x) _SB_MAKEVALUE(x,S_IO_SLEW2)
+#define G_IO_SLEW2(x) _SB_GETVALUE(x,S_IO_SLEW2,M_IO_SLEW2)
+
+#define S_IO_DRV_H 14
+#define M_IO_DRV_H _SB_MAKEMASK(2,S_IO_DRV_H)
+#define V_IO_DRV_H(x) _SB_MAKEVALUE(x,S_IO_DRV_H)
+#define G_IO_DRV_H(x) _SB_GETVALUE(x,S_IO_DRV_H,M_IO_DRV_H)
+
+/*
+ * Generic Bus Output Drive Control Register 2 (Table 14-20)
+ */
+
+#define S_IO_DRV_J 2
+#define M_IO_DRV_J _SB_MAKEMASK(2,S_IO_DRV_J)
+#define V_IO_DRV_J(x) _SB_MAKEVALUE(x,S_IO_DRV_J)
+#define G_IO_DRV_J(x) _SB_GETVALUE(x,S_IO_DRV_J,M_IO_DRV_J)
+
+#define S_IO_DRV_K 6
+#define M_IO_DRV_K _SB_MAKEMASK(2,S_IO_DRV_K)
+#define V_IO_DRV_K(x) _SB_MAKEVALUE(x,S_IO_DRV_K)
+#define G_IO_DRV_K(x) _SB_GETVALUE(x,S_IO_DRV_K,M_IO_DRV_K)
+
+#define S_IO_DRV_L 10
+#define M_IO_DRV_L _SB_MAKEMASK(2,S_IO_DRV_L)
+#define V_IO_DRV_L(x) _SB_MAKEVALUE(x,S_IO_DRV_L)
+#define G_IO_DRV_L(x) _SB_GETVALUE(x,S_IO_DRV_L,M_IO_DRV_L)
+
+#define S_IO_DRV_M 14
+#define M_IO_DRV_M _SB_MAKEMASK(2,S_IO_DRV_M)
+#define V_IO_DRV_M(x) _SB_MAKEVALUE(x,S_IO_DRV_M)
+#define G_IO_DRV_M(x) _SB_GETVALUE(x,S_IO_DRV_M,M_IO_DRV_M)
+
+/*
+ * Generic Bus Output Drive Control Register 3 (Table 14-21)
+ */
+
+#define S_IO_SLEW3 0
+#define M_IO_SLEW3 _SB_MAKEMASK(2,S_IO_SLEW3)
+#define V_IO_SLEW3(x) _SB_MAKEVALUE(x,S_IO_SLEW3)
+#define G_IO_SLEW3(x) _SB_GETVALUE(x,S_IO_SLEW3,M_IO_SLEW3)
+
+#define S_IO_DRV_N 2
+#define M_IO_DRV_N _SB_MAKEMASK(2,S_IO_DRV_N)
+#define V_IO_DRV_N(x) _SB_MAKEVALUE(x,S_IO_DRV_N)
+#define G_IO_DRV_N(x) _SB_GETVALUE(x,S_IO_DRV_N,M_IO_DRV_N)
+
+#define S_IO_DRV_P 6
+#define M_IO_DRV_P _SB_MAKEMASK(2,S_IO_DRV_P)
+#define V_IO_DRV_P(x) _SB_MAKEVALUE(x,S_IO_DRV_P)
+#define G_IO_DRV_P(x) _SB_GETVALUE(x,S_IO_DRV_P,M_IO_DRV_P)
+
+#define S_IO_DRV_Q 10
+#define M_IO_DRV_Q _SB_MAKEMASK(2,S_IO_DRV_Q)
+#define V_IO_DRV_Q(x) _SB_MAKEVALUE(x,S_IO_DRV_Q)
+#define G_IO_DRV_Q(x) _SB_GETVALUE(x,S_IO_DRV_Q,M_IO_DRV_Q)
+
+#define S_IO_DRV_R 14
+#define M_IO_DRV_R _SB_MAKEMASK(2,S_IO_DRV_R)
+#define V_IO_DRV_R(x) _SB_MAKEVALUE(x,S_IO_DRV_R)
+#define G_IO_DRV_R(x) _SB_GETVALUE(x,S_IO_DRV_R,M_IO_DRV_R)
+
/*
* PCMCIA configuration register (Table 12-6)
@@ -202,6 +327,22 @@
#define M_PCMCIA_CFG_RDYMASK _SB_MAKEMASK1(8)
#define M_PCMCIA_CFG_PWRCTL _SB_MAKEMASK1(9)
+#if SIBYTE_HDR_FEATURE_CHIP(1480)
+#define S_PCMCIA_MODE 16
+#define M_PCMCIA_MODE _SB_MAKEMASK(3,S_PCMCIA_MODE)
+#define V_PCMCIA_MODE(x) _SB_MAKEVALUE(x,S_PCMCIA_MODE)
+#define G_PCMCIA_MODE(x) _SB_GETVALUE(x,S_PCMCIA_MODE,M_PCMCIA_MODE)
+
+#define K_PCMCIA_MODE_PCMA_NOB 0 /* standard PCMCIA "A", no "B" */
+#define K_PCMCIA_MODE_IDEA_NOB 1 /* IDE "A", no "B" */
+#define K_PCMCIA_MODE_PCMIOA_NOB 2 /* PCMCIA with I/O "A", no "B" */
+#define K_PCMCIA_MODE_PCMA_PCMB 4 /* standard PCMCIA "A", standard PCMCIA "B" */
+#define K_PCMCIA_MODE_IDEA_PCMB 5 /* IDE "A", standard PCMCIA "B" */
+#define K_PCMCIA_MODE_PCMA_IDEB 6 /* standard PCMCIA "A", IDE "B" */
+#define K_PCMCIA_MODE_IDEA_IDEB 7 /* IDE "A", IDE "B" */
+#endif
+
+
/*
* PCMCIA status register (Table 12-7)
*/
@@ -272,5 +413,62 @@
#define V_GPIO_INTR_TYPE14(x) _SB_MAKEVALUE(x,S_GPIO_INTR_TYPE14)
#define G_GPIO_INTR_TYPE14(x) _SB_GETVALUE(x,S_GPIO_INTR_TYPE14,M_GPIO_INTR_TYPE14)
+#if SIBYTE_HDR_FEATURE_CHIP(1480)
+
+/*
+ * GPIO Interrupt Additional Type Register
+ */
+
+#define K_GPIO_INTR_BOTHEDGE 0
+#define K_GPIO_INTR_RISEEDGE 1
+#define K_GPIO_INTR_UNPRED1 2
+#define K_GPIO_INTR_UNPRED2 3
+
+#define S_GPIO_INTR_ATYPEX(n) (((n)/2)*2)
+#define M_GPIO_INTR_ATYPEX(n) _SB_MAKEMASK(2,S_GPIO_INTR_ATYPEX(n))
+#define V_GPIO_INTR_ATYPEX(n,x) _SB_MAKEVALUE(x,S_GPIO_INTR_ATYPEX(n))
+#define G_GPIO_INTR_ATYPEX(n,x) _SB_GETVALUE(x,S_GPIO_INTR_ATYPEX(n),M_GPIO_INTR_ATYPEX(n))
+
+#define S_GPIO_INTR_ATYPE0 0
+#define M_GPIO_INTR_ATYPE0 _SB_MAKEMASK(2,S_GPIO_INTR_ATYPE0)
+#define V_GPIO_INTR_ATYPE0(x) _SB_MAKEVALUE(x,S_GPIO_INTR_ATYPE0)
+#define G_GPIO_INTR_ATYPE0(x) _SB_GETVALUE(x,S_GPIO_INTR_ATYPE0,M_GPIO_INTR_ATYPE0)
+
+#define S_GPIO_INTR_ATYPE2 2
+#define M_GPIO_INTR_ATYPE2 _SB_MAKEMASK(2,S_GPIO_INTR_ATYPE2)
+#define V_GPIO_INTR_ATYPE2(x) _SB_MAKEVALUE(x,S_GPIO_INTR_ATYPE2)
+#define G_GPIO_INTR_ATYPE2(x) _SB_GETVALUE(x,S_GPIO_INTR_ATYPE2,M_GPIO_INTR_ATYPE2)
+
+#define S_GPIO_INTR_ATYPE4 4
+#define M_GPIO_INTR_ATYPE4 _SB_MAKEMASK(2,S_GPIO_INTR_ATYPE4)
+#define V_GPIO_INTR_ATYPE4(x) _SB_MAKEVALUE(x,S_GPIO_INTR_ATYPE4)
+#define G_GPIO_INTR_ATYPE4(x) _SB_GETVALUE(x,S_GPIO_INTR_ATYPE4,M_GPIO_INTR_ATYPE4)
+
+#define S_GPIO_INTR_ATYPE6 6
+#define M_GPIO_INTR_ATYPE6 _SB_MAKEMASK(2,S_GPIO_INTR_ATYPE6)
+#define V_GPIO_INTR_ATYPE6(x) _SB_MAKEVALUE(x,S_GPIO_INTR_ATYPE6)
+#define G_GPIO_INTR_ATYPE6(x) _SB_GETVALUE(x,S_GPIO_INTR_ATYPE6,M_GPIO_INTR_ATYPE6)
+
+#define S_GPIO_INTR_ATYPE8 8
+#define M_GPIO_INTR_ATYPE8 _SB_MAKEMASK(2,S_GPIO_INTR_ATYPE8)
+#define V_GPIO_INTR_ATYPE8(x) _SB_MAKEVALUE(x,S_GPIO_INTR_ATYPE8)
+#define G_GPIO_INTR_ATYPE8(x) _SB_GETVALUE(x,S_GPIO_INTR_ATYPE8,M_GPIO_INTR_ATYPE8)
+
+#define S_GPIO_INTR_ATYPE10 10
+#define M_GPIO_INTR_ATYPE10 _SB_MAKEMASK(2,S_GPIO_INTR_ATYPE10)
+#define V_GPIO_INTR_ATYPE10(x) _SB_MAKEVALUE(x,S_GPIO_INTR_ATYPE10)
+#define G_GPIO_INTR_ATYPE10(x) _SB_GETVALUE(x,S_GPIO_INTR_ATYPE10,M_GPIO_INTR_ATYPE10)
+
+#define S_GPIO_INTR_ATYPE12 12
+#define M_GPIO_INTR_ATYPE12 _SB_MAKEMASK(2,S_GPIO_INTR_ATYPE12)
+#define V_GPIO_INTR_ATYPE12(x) _SB_MAKEVALUE(x,S_GPIO_INTR_ATYPE12)
+#define G_GPIO_INTR_ATYPE12(x) _SB_GETVALUE(x,S_GPIO_INTR_ATYPE12,M_GPIO_INTR_ATYPE12)
+
+#define S_GPIO_INTR_ATYPE14 14
+#define M_GPIO_INTR_ATYPE14 _SB_MAKEMASK(2,S_GPIO_INTR_ATYPE14)
+#define V_GPIO_INTR_ATYPE14(x) _SB_MAKEVALUE(x,S_GPIO_INTR_ATYPE14)
+#define G_GPIO_INTR_ATYPE14(x) _SB_GETVALUE(x,S_GPIO_INTR_ATYPE14,M_GPIO_INTR_ATYPE14)
+#endif
+
#endif
diff --git a/include/asm-mips/sibyte/sb1250_int.h b/include/asm-mips/sibyte/sb1250_int.h
index e173e2ea4c98..05c7b39f1b02 100644
--- a/include/asm-mips/sibyte/sb1250_int.h
+++ b/include/asm-mips/sibyte/sb1250_int.h
@@ -8,8 +8,6 @@
*
* SB1250 specification level: User's manual 1/02/02
*
- * Author: Mitch Lichtenberg
- *
*********************************************************************
*
* Copyright 2000,2001,2002,2003
@@ -47,6 +45,10 @@
* First, the interrupt numbers.
*/
+#if SIBYTE_HDR_FEATURE_1250_112x
+
+#define K_INT_SOURCES 64
+
#define K_INT_WATCHDOG_TIMER_0 0
#define K_INT_WATCHDOG_TIMER_1 1
#define K_INT_TIMER_0 2
@@ -244,4 +246,6 @@
#define M_LDTVECT_RAISEMBOX 0x40
+#endif /* 1250/112x */
+
#endif
diff --git a/include/asm-mips/sibyte/sb1250_l2c.h b/include/asm-mips/sibyte/sb1250_l2c.h
index 8afe8e01581b..842f205094af 100644
--- a/include/asm-mips/sibyte/sb1250_l2c.h
+++ b/include/asm-mips/sibyte/sb1250_l2c.h
@@ -8,8 +8,6 @@
*
* SB1250 specification level: User's manual 1/02/02
*
- * Author: Mitch Lichtenberg
- *
*********************************************************************
*
* Copyright 2000,2001,2002,2003
@@ -89,8 +87,13 @@
#define V_L2C_MGMT_WAY(x) _SB_MAKEVALUE(x,S_L2C_MGMT_WAY)
#define G_L2C_MGMT_WAY(x) _SB_GETVALUE(x,S_L2C_MGMT_WAY,M_L2C_MGMT_WAY)
-#define S_L2C_MGMT_TAG 21
-#define M_L2C_MGMT_TAG _SB_MAKEMASK(6,S_L2C_MGMT_TAG)
+#define S_L2C_MGMT_ECC_DIAG 21
+#define M_L2C_MGMT_ECC_DIAG _SB_MAKEMASK(2,S_L2C_MGMT_ECC_DIAG)
+#define V_L2C_MGMT_ECC_DIAG(x) _SB_MAKEVALUE(x,S_L2C_MGMT_ECC_DIAG)
+#define G_L2C_MGMT_ECC_DIAG(x) _SB_GETVALUE(x,S_L2C_MGMT_ECC_DIAG,M_L2C_MGMT_ECC_DIAG)
+
+#define S_L2C_MGMT_TAG 23
+#define M_L2C_MGMT_TAG _SB_MAKEMASK(4,S_L2C_MGMT_TAG)
#define V_L2C_MGMT_TAG(x) _SB_MAKEVALUE(x,S_L2C_MGMT_TAG)
#define G_L2C_MGMT_TAG(x) _SB_GETVALUE(x,S_L2C_MGMT_TAG,M_L2C_MGMT_TAG)
diff --git a/include/asm-mips/sibyte/sb1250_ldt.h b/include/asm-mips/sibyte/sb1250_ldt.h
index f2617ded0a8f..7092535d1108 100644
--- a/include/asm-mips/sibyte/sb1250_ldt.h
+++ b/include/asm-mips/sibyte/sb1250_ldt.h
@@ -8,8 +8,6 @@
*
* SB1250 specification level: User's manual 1/02/02
*
- * Author: Mitch Lichtenberg
- *
*********************************************************************
*
* Copyright 2000,2001,2002,2003
diff --git a/include/asm-mips/sibyte/sb1250_mac.h b/include/asm-mips/sibyte/sb1250_mac.h
index 18e74e43f4a2..adfc688fa559 100644
--- a/include/asm-mips/sibyte/sb1250_mac.h
+++ b/include/asm-mips/sibyte/sb1250_mac.h
@@ -8,8 +8,6 @@
*
* SB1250 specification level: User's manual 1/02/02
*
- * Author: Mitch Lichtenberg
- *
*********************************************************************
*
* Copyright 2000,2001,2002,2003
@@ -81,7 +79,10 @@
#define M_MAC_RESERVED1 _SB_MAKEMASK(8,9)
#define M_MAC_AP_STAT_EN _SB_MAKEMASK1(17)
-#define M_MAC_RESERVED2 _SB_MAKEMASK1(18)
+
+#if SIBYTE_HDR_FEATURE_CHIP(1480)
+#define M_MAC_TIMESTAMP _SB_MAKEMASK1(18)
+#endif
#define M_MAC_DRP_ERRPKT_EN _SB_MAKEMASK1(19)
#define M_MAC_DRP_FCSERRPKT_EN _SB_MAKEMASK1(20)
#define M_MAC_DRP_CODEERRPKT_EN _SB_MAKEMASK1(21)
@@ -132,9 +133,9 @@
#define M_MAC_RX_CH_SEL_MSB _SB_MAKEMASK1(44)
#endif /* 1250 PASS2 || 112x PASS1 */
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define M_MAC_SPLIT_CH_SEL _SB_MAKEMASK1(45)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
#define S_MAC_BYPASS_IFG _SB_MAKE64(46)
#define M_MAC_BYPASS_IFG _SB_MAKEMASK(8,S_MAC_BYPASS_IFG)
@@ -176,10 +177,22 @@
#define M_MAC_PORT_RESET _SB_MAKEMASK1(8)
+#if (SIBYTE_HDR_FEATURE_CHIP(1250) || SIBYTE_HDR_FEATURE_CHIP(112x))
#define M_MAC_RX_ENABLE _SB_MAKEMASK1(10)
#define M_MAC_TX_ENABLE _SB_MAKEMASK1(11)
#define M_MAC_BYP_RX_ENABLE _SB_MAKEMASK1(12)
#define M_MAC_BYP_TX_ENABLE _SB_MAKEMASK1(13)
+#endif
+
+/*
+ * MAC reset information register (1280/1255)
+ */
+#if SIBYTE_HDR_FEATURE_CHIP(1480)
+#define M_MAC_RX_CH0_PAUSE_ON _SB_MAKEMASK1(8)
+#define M_MAC_RX_CH1_PAUSE_ON _SB_MAKEMASK1(16)
+#define M_MAC_TX_CH0_PAUSE_ON _SB_MAKEMASK1(24)
+#define M_MAC_TX_CH1_PAUSE_ON _SB_MAKEMASK1(32)
+#endif
/*
* MAC DMA Control Register
@@ -267,12 +280,12 @@
#define V_MAC_IFG_RX(x) _SB_MAKEVALUE(x,S_MAC_IFG_RX)
#define G_MAC_IFG_RX(x) _SB_GETVALUE(x,S_MAC_IFG_RX,M_MAC_IFG_RX)
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define S_MAC_PRE_LEN _SB_MAKE64(0)
#define M_MAC_PRE_LEN _SB_MAKEMASK(6,S_MAC_PRE_LEN)
#define V_MAC_PRE_LEN(x) _SB_MAKEVALUE(x,S_MAC_PRE_LEN)
#define G_MAC_PRE_LEN(x) _SB_GETVALUE(x,S_MAC_PRE_LEN,M_MAC_PRE_LEN)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
#define S_MAC_IFG_TX _SB_MAKE64(6)
#define M_MAC_IFG_TX _SB_MAKEMASK(6,S_MAC_IFG_TX)
@@ -458,9 +471,9 @@
#define V_MAC_COUNTER_ADDR(x) _SB_MAKEVALUE(x,S_MAC_COUNTER_ADDR)
#define G_MAC_COUNTER_ADDR(x) _SB_GETVALUE(x,S_MAC_COUNTER_ADDR,M_MAC_COUNTER_ADDR)
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define M_MAC_TX_PAUSE_ON _SB_MAKEMASK1(52)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
/*
* MAC Fifo Pointer Registers (Table 9-19) [Debug register]
@@ -594,7 +607,7 @@
#define V_MAC_IPHDR_OFFSET(x) _SB_MAKEVALUE(x,S_MAC_IPHDR_OFFSET)
#define G_MAC_IPHDR_OFFSET(x) _SB_GETVALUE(x,S_MAC_IPHDR_OFFSET,M_MAC_IPHDR_OFFSET)
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define S_MAC_RX_CRC_OFFSET _SB_MAKE64(16)
#define M_MAC_RX_CRC_OFFSET _SB_MAKEMASK(8,S_MAC_RX_CRC_OFFSET)
#define V_MAC_RX_CRC_OFFSET(x) _SB_MAKEVALUE(x,S_MAC_RX_CRC_OFFSET)
@@ -612,7 +625,7 @@
#define M_MAC_RX_CH_MSN_SEL _SB_MAKEMASK(8,S_MAC_RX_CH_MSN_SEL)
#define V_MAC_RX_CH_MSN_SEL(x) _SB_MAKEVALUE(x,S_MAC_RX_CH_MSN_SEL)
#define G_MAC_RX_CH_MSN_SEL(x) _SB_GETVALUE(x,S_MAC_RX_CH_MSN_SEL,M_MAC_RX_CH_MSN_SEL)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
/*
* MAC Receive Channel Select Registers (Table 9-25)
diff --git a/include/asm-mips/sibyte/sb1250_mc.h b/include/asm-mips/sibyte/sb1250_mc.h
index 1dd41c927996..26e421498c97 100644
--- a/include/asm-mips/sibyte/sb1250_mc.h
+++ b/include/asm-mips/sibyte/sb1250_mc.h
@@ -8,8 +8,6 @@
*
* SB1250 specification level: User's manual 1/02/02
*
- * Author: Mitch Lichtenberg
- *
*********************************************************************
*
* Copyright 2000,2001,2002,2003
@@ -324,6 +322,10 @@
#define K_MC_tRFC_DEFAULT 12
#define V_MC_tRFC_DEFAULT V_MC_tRFC(K_MC_tRFC_DEFAULT)
+#if SIBYTE_HDR_FEATURE(1250, PASS3)
+#define M_MC_tRFC_PLUS16 _SB_MAKEMASK1(51) /* 1250C3 and later. */
+#endif
+
#define S_MC_tCwCr 40
#define M_MC_tCwCr _SB_MAKEMASK(4,S_MC_tCwCr)
#define V_MC_tCwCr(x) _SB_MAKEVALUE(x,S_MC_tCwCr)
diff --git a/include/asm-mips/sibyte/sb1250_regs.h b/include/asm-mips/sibyte/sb1250_regs.h
index 9db80cd13a79..bab3a4580a36 100644
--- a/include/asm-mips/sibyte/sb1250_regs.h
+++ b/include/asm-mips/sibyte/sb1250_regs.h
@@ -8,8 +8,6 @@
*
* SB1250 specification level: 01/02/2002
*
- * Author: Mitch Lichtenberg
- *
*********************************************************************
*
* Copyright 2000,2001,2002,2003
@@ -61,6 +59,8 @@
* XXX: can't remove MC base 0 if 112x, since it's used by other macros,
* since there is one reg there (but it could get its addr/offset constant).
*/
+
+#if SIBYTE_HDR_FEATURE_1250_112x /* This MC only on 1250 & 112x */
#define A_MC_BASE_0 0x0010051000
#define A_MC_BASE_1 0x0010052000
#define MC_REGISTER_SPACING 0x1000
@@ -101,10 +101,14 @@
#define R_MC_TEST_ECC 0x0000000420
#define R_MC_MCLK_CFG 0x0000000500
+#endif /* 1250 & 112x */
+
/* *********************************************************************
* L2 Cache Control Registers
********************************************************************* */
+#if SIBYTE_HDR_FEATURE_1250_112x /* This L2C only on 1250/112x */
+
#define A_L2_READ_TAG 0x0010040018
#define A_L2_ECC_TAG 0x0010040038
#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
@@ -125,13 +129,16 @@
#define A_L2_READ_ADDRESS A_L2_READ_TAG
#define A_L2_EEC_ADDRESS A_L2_ECC_TAG
+#endif
/* *********************************************************************
* PCI Interface Registers
********************************************************************* */
+#if SIBYTE_HDR_FEATURE_1250_112x /* This PCI/HT only on 1250/112x */
#define A_PCI_TYPE00_HEADER 0x00DE000000
#define A_PCI_TYPE01_HEADER 0x00DE000800
+#endif
/* *********************************************************************
@@ -264,15 +271,15 @@
********************************************************************* */
+#if SIBYTE_HDR_FEATURE_1250_112x /* This MC only on 1250 & 112x */
#define R_DUART_NUM_PORTS 2
#define A_DUART 0x0010060000
-#define A_DUART_REG(r)
-
#define DUART_CHANREG_SPACING 0x100
#define A_DUART_CHANREG(chan,reg) (A_DUART + DUART_CHANREG_SPACING*(chan) + (reg))
#define R_DUART_CHANREG(chan,reg) (DUART_CHANREG_SPACING*(chan) + (reg))
+#endif /* 1250 & 112x */
#define R_DUART_MODE_REG_1 0x100
#define R_DUART_MODE_REG_2 0x110
@@ -307,11 +314,13 @@
#define DUART_IMRISR_SPACING 0x20
+#if SIBYTE_HDR_FEATURE_1250_112x /* This MC only on 1250 & 112x */
#define R_DUART_IMRREG(chan) (R_DUART_IMR_A + (chan)*DUART_IMRISR_SPACING)
#define R_DUART_ISRREG(chan) (R_DUART_ISR_A + (chan)*DUART_IMRISR_SPACING)
#define A_DUART_IMRREG(chan) (A_DUART + R_DUART_IMRREG(chan))
#define A_DUART_ISRREG(chan) (A_DUART + R_DUART_ISRREG(chan))
+#endif /* 1250 & 112x */
@@ -368,6 +377,8 @@
********************************************************************* */
+#if SIBYTE_HDR_FEATURE_1250_112x /* sync serial only on 1250/112x */
+
#define A_SER_BASE_0 0x0010060400
#define A_SER_BASE_1 0x0010060800
#define SER_SPACING 0x400
@@ -457,6 +468,8 @@
#define R_SER_RMON_RX_ERRORS 0x000001F0
#define R_SER_RMON_RX_BADADDR 0x000001F8
+#endif /* 1250/112x */
+
/* *********************************************************************
* Generic Bus Registers
********************************************************************* */
@@ -634,12 +647,13 @@
#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
#define A_SCD_SCRATCH 0x0010020C10
+#endif /* 1250 PASS2 || 112x PASS1 */
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define A_SCD_ZBBUS_CYCLE_COUNT 0x0010030000
#define A_SCD_ZBBUS_CYCLE_CP0 0x0010020C00
#define A_SCD_ZBBUS_CYCLE_CP1 0x0010020C08
-#endif /* 1250 PASS2 || 112x PASS1 */
-
+#endif
/* *********************************************************************
* System Control Registers
@@ -667,15 +681,16 @@
#define A_ADDR_TRAP_CFG_1 0x0010020448
#define A_ADDR_TRAP_CFG_2 0x0010020450
#define A_ADDR_TRAP_CFG_3 0x0010020458
-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define A_ADDR_TRAP_REG_DEBUG 0x0010020460
-#endif /* 1250 PASS2 || 112x PASS1 */
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
/* *********************************************************************
* System Interrupt Mapper Registers
********************************************************************* */
+#if SIBYTE_HDR_FEATURE_1250_112x
#define A_IMR_CPU0_BASE 0x0010020000
#define A_IMR_CPU1_BASE 0x0010022000
#define IMR_REGISTER_SPACING 0x2000
@@ -700,6 +715,7 @@
#define R_IMR_INTERRUPT_STATUS_COUNT 7
#define R_IMR_INTERRUPT_MAP_BASE 0x0200
#define R_IMR_INTERRUPT_MAP_COUNT 64
+#endif /* 1250/112x */
/* *********************************************************************
* System Performance Counter Registers
@@ -718,6 +734,7 @@
#define A_SCD_BUS_ERR_STATUS 0x0010020880
#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
#define A_SCD_BUS_ERR_STATUS_DEBUG 0x00100208D0
+#define A_BUS_ERR_STATUS_DEBUG 0x00100208D0
#endif /* 1250 PASS2 || 112x PASS1 */
#define A_BUS_ERR_DATA_0 0x00100208A0
#define A_BUS_ERR_DATA_1 0x00100208A8
@@ -798,6 +815,7 @@
* Physical Address Map
********************************************************************* */
+#if SIBYTE_HDR_FEATURE_1250_112x
#define A_PHYS_MEMORY_0 _SB_MAKE64(0x0000000000)
#define A_PHYS_MEMORY_SIZE _SB_MAKE64((256*1024*1024))
#define A_PHYS_SYSTEM_CTL _SB_MAKE64(0x0010000000)
@@ -831,6 +849,7 @@
#define A_PHYS_L2CACHE_WAY1 _SB_MAKE64(0x00D01A0000)
#define A_PHYS_L2CACHE_WAY2 _SB_MAKE64(0x00D01C0000)
#define A_PHYS_L2CACHE_WAY3 _SB_MAKE64(0x00D01E0000)
+#endif
#endif
diff --git a/include/asm-mips/sibyte/sb1250_scd.h b/include/asm-mips/sibyte/sb1250_scd.h
index dbbd682fb47e..a667bc14a7cd 100644
--- a/include/asm-mips/sibyte/sb1250_scd.h
+++ b/include/asm-mips/sibyte/sb1250_scd.h
@@ -8,8 +8,6 @@
*
* SB1250 specification level: User's manual 1/02/02
*
- * Author: Mitch Lichtenberg
- *
*********************************************************************
*
* Copyright 2000,2001,2002,2003
@@ -51,26 +49,70 @@
#define V_SYS_REVISION(x) _SB_MAKEVALUE(x,S_SYS_REVISION)
#define G_SYS_REVISION(x) _SB_GETVALUE(x,S_SYS_REVISION,M_SYS_REVISION)
-#if SIBYTE_HDR_FEATURE_CHIP(1250)
-#define K_SYS_REVISION_BCM1250_PASS1 1
-#define K_SYS_REVISION_BCM1250_PASS2 3
-#define K_SYS_REVISION_BCM1250_A10 11
-#define K_SYS_REVISION_BCM1250_PASS2_2 16
-#define K_SYS_REVISION_BCM1250_B2 17
-#define K_SYS_REVISION_BCM1250_PASS3 32
-#define K_SYS_REVISION_BCM1250_C1 33
+#define K_SYS_REVISION_BCM1250_PASS1 0x01
+
+#define K_SYS_REVISION_BCM1250_PASS2 0x03
+#define K_SYS_REVISION_BCM1250_A1 0x03 /* Pass 2.0 WB */
+#define K_SYS_REVISION_BCM1250_A2 0x04 /* Pass 2.0 FC */
+#define K_SYS_REVISION_BCM1250_A3 0x05 /* Pass 2.1 FC */
+#define K_SYS_REVISION_BCM1250_A4 0x06 /* Pass 2.1 WB */
+#define K_SYS_REVISION_BCM1250_A6 0x07 /* OR 0x04 (A2) w/WID != 0 */
+#define K_SYS_REVISION_BCM1250_A8 0x0b /* A8/A10 */
+#define K_SYS_REVISION_BCM1250_A9 0x08
+#define K_SYS_REVISION_BCM1250_A10 K_SYS_REVISION_BCM1250_A8
+#define K_SYS_REVISION_BCM1250_PASS2_2 0x10
+#define K_SYS_REVISION_BCM1250_B0 K_SYS_REVISION_BCM1250_B1
+#define K_SYS_REVISION_BCM1250_B1 0x10
+#define K_SYS_REVISION_BCM1250_B2 0x11
+
+#define K_SYS_REVISION_BCM1250_C0 0x20
+#define K_SYS_REVISION_BCM1250_C1 0x21
+#define K_SYS_REVISION_BCM1250_C2 0x22
+#define K_SYS_REVISION_BCM1250_C3 0x23
+
+#if SIBYTE_HDR_FEATURE_CHIP(1250)
/* XXX: discourage people from using these constants. */
#define K_SYS_REVISION_PASS1 K_SYS_REVISION_BCM1250_PASS1
#define K_SYS_REVISION_PASS2 K_SYS_REVISION_BCM1250_PASS2
#define K_SYS_REVISION_PASS2_2 K_SYS_REVISION_BCM1250_PASS2_2
#define K_SYS_REVISION_PASS3 K_SYS_REVISION_BCM1250_PASS3
+#define K_SYS_REVISION_BCM1250_PASS3 K_SYS_REVISION_BCM1250_C0
#endif /* 1250 */
-#if SIBYTE_HDR_FEATURE_CHIP(112x)
-#define K_SYS_REVISION_BCM112x_A1 32
-#define K_SYS_REVISION_BCM112x_A2 33
-#endif /* 112x */
+#define K_SYS_REVISION_BCM112x_A1 0x20
+#define K_SYS_REVISION_BCM112x_A2 0x21
+#define K_SYS_REVISION_BCM112x_A3 0x22
+#define K_SYS_REVISION_BCM112x_A4 0x23
+
+#define K_SYS_REVISION_BCM1480_S0 0x01
+#define K_SYS_REVISION_BCM1480_A1 0x02
+#define K_SYS_REVISION_BCM1480_A2 0x03
+#define K_SYS_REVISION_BCM1480_A3 0x04
+#define K_SYS_REVISION_BCM1480_B0 0x11
+
+/*Cache size - 23:20 of revision register*/
+#define S_SYS_L2C_SIZE _SB_MAKE64(20)
+#define M_SYS_L2C_SIZE _SB_MAKEMASK(4,S_SYS_L2C_SIZE)
+#define V_SYS_L2C_SIZE(x) _SB_MAKEVALUE(x,S_SYS_L2C_SIZE)
+#define G_SYS_L2C_SIZE(x) _SB_GETVALUE(x,S_SYS_L2C_SIZE,M_SYS_L2C_SIZE)
+
+#define K_SYS_L2C_SIZE_1MB 0
+#define K_SYS_L2C_SIZE_512KB 5
+#define K_SYS_L2C_SIZE_256KB 2
+#define K_SYS_L2C_SIZE_128KB 1
+
+#define K_SYS_L2C_SIZE_BCM1250 K_SYS_L2C_SIZE_512KB
+#define K_SYS_L2C_SIZE_BCM1125 K_SYS_L2C_SIZE_256KB
+#define K_SYS_L2C_SIZE_BCM1122 K_SYS_L2C_SIZE_128KB
+
+
+/* Number of CPU cores, bits 27:24 of revision register*/
+#define S_SYS_NUM_CPUS _SB_MAKE64(24)
+#define M_SYS_NUM_CPUS _SB_MAKEMASK(4,S_SYS_NUM_CPUS)
+#define V_SYS_NUM_CPUS(x) _SB_MAKEVALUE(x,S_SYS_NUM_CPUS)
+#define G_SYS_NUM_CPUS(x) _SB_GETVALUE(x,S_SYS_NUM_CPUS,M_SYS_NUM_CPUS)
+
/* XXX: discourage people from using these constants. */
#define S_SYS_PART _SB_MAKE64(16)
@@ -83,6 +125,8 @@
#define K_SYS_PART_BCM1120 0x1121
#define K_SYS_PART_BCM1125 0x1123
#define K_SYS_PART_BCM1125H 0x1124
+#define K_SYS_PART_BCM1122 0x1113
+
/* The "peripheral set" (SOC type) is the low 4 bits of the "part" field. */
#define S_SYS_SOC_TYPE _SB_MAKE64(16)
@@ -96,6 +140,8 @@
#define K_SYS_SOC_TYPE_BCM1125 0x3
#define K_SYS_SOC_TYPE_BCM1125H 0x4
#define K_SYS_SOC_TYPE_BCM1250_ALT2 0x5 /* 1250pass2 w/ 1/2 L2. */
+#define K_SYS_SOC_TYPE_BCM1x80 0x6
+#define K_SYS_SOC_TYPE_BCM1x55 0x7
/*
* Calculate correct SOC type given a copy of system revision register.
@@ -127,10 +173,12 @@
#define V_SYS_WID(x) _SB_MAKEVALUE(x,S_SYS_WID)
#define G_SYS_WID(x) _SB_GETVALUE(x,S_SYS_WID,M_SYS_WID)
-/* System Manufacturing Register
-* Register: SCD_SYSTEM_MANUF
-*/
+/*
+ * System Manufacturing Register
+ * Register: SCD_SYSTEM_MANUF
+ */
+#if SIBYTE_HDR_FEATURE_1250_112x
/* Wafer ID: bits 31:0 */
#define S_SYS_WAFERID1_200 _SB_MAKE64(0)
#define M_SYS_WAFERID1_200 _SB_MAKEMASK(32,S_SYS_WAFERID1_200)
@@ -139,8 +187,8 @@
#define S_SYS_BIN _SB_MAKE64(32)
#define M_SYS_BIN _SB_MAKEMASK(4,S_SYS_BIN)
-#define V_SYS_BIN _SB_MAKEVALUE(x,S_SYS_BIN)
-#define G_SYS_BIN _SB_GETVALUE(x,S_SYS_BIN,M_SYS_BIN)
+#define V_SYS_BIN(x) _SB_MAKEVALUE(x,S_SYS_BIN)
+#define G_SYS_BIN(x) _SB_GETVALUE(x,S_SYS_BIN,M_SYS_BIN)
/* Wafer ID: bits 39:36 */
#define S_SYS_WAFERID2_200 _SB_MAKE64(36)
@@ -163,12 +211,14 @@
#define M_SYS_YPOS _SB_MAKEMASK(6,S_SYS_YPOS)
#define V_SYS_YPOS(x) _SB_MAKEVALUE(x,S_SYS_YPOS)
#define G_SYS_YPOS(x) _SB_GETVALUE(x,S_SYS_YPOS,M_SYS_YPOS)
+#endif
/*
* System Config Register (Table 4-2)
* Register: SCD_SYSTEM_CFG
*/
+#if SIBYTE_HDR_FEATURE_1250_112x
#define M_SYS_LDT_PLL_BYP _SB_MAKEMASK1(3)
#define M_SYS_PCI_SYNC_TEST_MODE _SB_MAKEMASK1(4)
#define M_SYS_IOB0_DIV _SB_MAKEMASK1(5)
@@ -253,6 +303,8 @@
#define M_SYS_SW_FLAG _SB_MAKEMASK1(63)
#endif /* 1250 PASS2 || 112x PASS1 */
+#endif
+
/*
* Mailbox Registers (Table 4-3)
@@ -326,6 +378,7 @@
* System Performance Counters
*/
+#if SIBYTE_HDR_FEATURE_1250_112x
#define S_SPC_CFG_SRC0 0
#define M_SPC_CFG_SRC0 _SB_MAKEMASK(8,S_SPC_CFG_SRC0)
#define V_SPC_CFG_SRC0(x) _SB_MAKEVALUE(x,S_SPC_CFG_SRC0)
@@ -348,6 +401,7 @@
#define M_SPC_CFG_CLEAR _SB_MAKEMASK1(32)
#define M_SPC_CFG_ENABLE _SB_MAKEMASK1(33)
+#endif
/*
@@ -412,6 +466,7 @@
* Address Trap Registers
*/
+#if SIBYTE_HDR_FEATURE_1250_112x
#define M_ATRAP_INDEX _SB_MAKEMASK(4,0)
#define M_ATRAP_ADDRESS _SB_MAKEMASK(40,0)
@@ -436,7 +491,6 @@
#define K_BUS_AGENT_IOB0 2
#define K_BUS_AGENT_IOB1 3
#define K_BUS_AGENT_SCD 4
-#define K_BUS_AGENT_RESERVED 5
#define K_BUS_AGENT_L2C 6
#define K_BUS_AGENT_MC 7
@@ -454,10 +508,14 @@
#define K_ATRAP_CFG_CATTR_NOTNONCOH 6
#define K_ATRAP_CFG_CATTR_NOTCOHERENT 7
+#endif /* 1250/112x */
+
/*
* Trace Buffer Config register
*/
+#if SIBYTE_HDR_FEATURE_1250_112x
+
#define M_SCD_TRACE_CFG_RESET _SB_MAKEMASK1(0)
#define M_SCD_TRACE_CFG_START_READ _SB_MAKEMASK1(1)
#define M_SCD_TRACE_CFG_START _SB_MAKEMASK1(2)
@@ -475,6 +533,8 @@
#define V_SCD_TRACE_CFG_CUR_ADDR(x) _SB_MAKEVALUE(x,S_SCD_TRACE_CFG_CUR_ADDR)
#define G_SCD_TRACE_CFG_CUR_ADDR(x) _SB_GETVALUE(x,S_SCD_TRACE_CFG_CUR_ADDR,M_SCD_TRACE_CFG_CUR_ADDR)
+#endif /* 1250/112x */
+
/*
* Trace Event registers
*/
@@ -578,5 +638,7 @@
#define M_SCD_TRSEQ_DEBUGPIN _SB_MAKEMASK1(20)
#define M_SCD_TRSEQ_DEBUGCPU _SB_MAKEMASK1(21)
#define M_SCD_TRSEQ_CLEARUSE _SB_MAKEMASK1(22)
+#define M_SCD_TRSEQ_ALLD_A _SB_MAKEMASK1(23)
+#define M_SCD_TRSEQ_ALL_A _SB_MAKEMASK1(24)
#endif
diff --git a/include/asm-mips/sibyte/sb1250_smbus.h b/include/asm-mips/sibyte/sb1250_smbus.h
index 335c53e92936..279a912213cd 100644
--- a/include/asm-mips/sibyte/sb1250_smbus.h
+++ b/include/asm-mips/sibyte/sb1250_smbus.h
@@ -6,9 +6,8 @@
* This module contains constants and macros useful for
* manipulating the SB1250's SMbus devices.
*
- * SB1250 specification level: 01/02/2002
- *
- * Author: Mitch Lichtenberg
+ * SB1250 specification level: 10/21/02
+ * BCM1280 specification level: 11/24/03
*
*********************************************************************
*
@@ -47,6 +46,7 @@
#define K_SMB_FREQ_400KHZ 0x1F
#define K_SMB_FREQ_100KHZ 0x7D
+#define K_SMB_FREQ_10KHZ 1250
#define S_SMB_CMD 0
#define M_SMB_CMD _SB_MAKEMASK(8,S_SMB_CMD)
@@ -58,7 +58,11 @@
#define M_SMB_ERR_INTR _SB_MAKEMASK1(0)
#define M_SMB_FINISH_INTR _SB_MAKEMASK1(1)
-#define M_SMB_DATA_OUT _SB_MAKEMASK1(4)
+
+#define S_SMB_DATA_OUT 4
+#define M_SMB_DATA_OUT _SB_MAKEMASK1(S_SMB_DATA_OUT)
+#define V_SMB_DATA_OUT(x) _SB_MAKEVALUE(x,S_SMB_DATA_OUT)
+
#define M_SMB_DATA_DIR _SB_MAKEMASK1(5)
#define M_SMB_DATA_DIR_OUTPUT M_SMB_DATA_DIR
#define M_SMB_CLK_OUT _SB_MAKEMASK1(6)
@@ -71,8 +75,23 @@
#define M_SMB_BUSY _SB_MAKEMASK1(0)
#define M_SMB_ERROR _SB_MAKEMASK1(1)
#define M_SMB_ERROR_TYPE _SB_MAKEMASK1(2)
-#define M_SMB_REF _SB_MAKEMASK1(6)
-#define M_SMB_DATA_IN _SB_MAKEMASK1(7)
+
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define S_SMB_SCL_IN 5
+#define M_SMB_SCL_IN _SB_MAKEMASK1(S_SMB_SCL_IN)
+#define V_SMB_SCL_IN(x) _SB_MAKEVALUE(x,S_SMB_SCL_IN)
+#define G_SMB_SCL_IN(x) _SB_GETVALUE(x,S_SMB_SCL_IN,M_SMB_SCL_IN)
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+
+#define S_SMB_REF 6
+#define M_SMB_REF _SB_MAKEMASK1(S_SMB_REF)
+#define V_SMB_REF(x) _SB_MAKEVALUE(x,S_SMB_REF)
+#define G_SMB_REF(x) _SB_GETVALUE(x,S_SMB_REF,M_SMB_REF)
+
+#define S_SMB_DATA_IN 7
+#define M_SMB_DATA_IN _SB_MAKEMASK1(S_SMB_DATA_IN)
+#define V_SMB_DATA_IN(x) _SB_MAKEVALUE(x,S_SMB_DATA_IN)
+#define G_SMB_DATA_IN(x) _SB_GETVALUE(x,S_SMB_DATA_IN,M_SMB_DATA_IN)
/*
* SMBus Start/Command registers (Table 14-9)
@@ -132,16 +151,14 @@
#define V_SPEC_MB(x) _SB_MAKEVALUE(x,S_SPEC_PEC)
-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define S_SMB_CMDH 8
-#define M_SMB_CMDH _SB_MAKEMASK(8,S_SMBH_CMD)
-#define V_SMB_CMDH(x) _SB_MAKEVALUE(x,S_SMBH_CMD)
+#define M_SMB_CMDH _SB_MAKEMASK(8,S_SMB_CMDH)
+#define V_SMB_CMDH(x) _SB_MAKEVALUE(x,S_SMB_CMDH)
#define M_SMB_EXTEND _SB_MAKEMASK1(14)
-#define M_SMB_DIR _SB_MAKEMASK1(13)
-
#define S_SMB_DFMT 8
#define M_SMB_DFMT _SB_MAKEMASK(3,S_SMB_DFMT)
#define V_SMB_DFMT(x) _SB_MAKEVALUE(x,S_SMB_DFMT)
@@ -165,6 +182,23 @@
#define V_SMB_DFMT_CMD5BYTE V_SMB_DFMT(K_SMB_DFMT_CMD5BYTE)
#define V_SMB_DFMT_RESERVED V_SMB_DFMT(K_SMB_DFMT_RESERVED)
-#endif /* 1250 PASS2 || 112x PASS1 */
+#define S_SMB_AFMT 11
+#define M_SMB_AFMT _SB_MAKEMASK(2,S_SMB_AFMT)
+#define V_SMB_AFMT(x) _SB_MAKEVALUE(x,S_SMB_AFMT)
+#define G_SMB_AFMT(x) _SB_GETVALUE(x,S_SMB_AFMT,M_SMB_AFMT)
+
+#define K_SMB_AFMT_NONE 0
+#define K_SMB_AFMT_ADDR 1
+#define K_SMB_AFMT_ADDR_CMD1BYTE 2
+#define K_SMB_AFMT_ADDR_CMD2BYTE 3
+
+#define V_SMB_AFMT_NONE V_SMB_AFMT(K_SMB_AFMT_NONE)
+#define V_SMB_AFMT_ADDR V_SMB_AFMT(K_SMB_AFMT_ADDR)
+#define V_SMB_AFMT_ADDR_CMD1BYTE V_SMB_AFMT(K_SMB_AFMT_ADDR_CMD1BYTE)
+#define V_SMB_AFMT_ADDR_CMD2BYTE V_SMB_AFMT(K_SMB_AFMT_ADDR_CMD2BYTE)
+
+#define M_SMB_DIR _SB_MAKEMASK1(13)
+
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
#endif
diff --git a/include/asm-mips/sibyte/sb1250_syncser.h b/include/asm-mips/sibyte/sb1250_syncser.h
index fa2760d38b8b..dd154ac505d8 100644
--- a/include/asm-mips/sibyte/sb1250_syncser.h
+++ b/include/asm-mips/sibyte/sb1250_syncser.h
@@ -8,8 +8,6 @@
*
* SB1250 specification level: User's manual 1/02/02
*
- * Author: Mitch Lichtenberg
- *
*********************************************************************
*
* Copyright 2000,2001,2002,2003
diff --git a/include/asm-mips/sibyte/sb1250_uart.h b/include/asm-mips/sibyte/sb1250_uart.h
index 923ea4f44e0f..e87045e62bf0 100644
--- a/include/asm-mips/sibyte/sb1250_uart.h
+++ b/include/asm-mips/sibyte/sb1250_uart.h
@@ -8,8 +8,6 @@
*
* SB1250 specification level: User's manual 1/02/02
*
- * Author: Mitch Lichtenberg
- *
*********************************************************************
*
* Copyright 2000,2001,2002,2003
@@ -240,7 +238,12 @@
*/
#define M_DUART_ISR_TX_A _SB_MAKEMASK1(0)
-#define M_DUART_ISR_RX_A _SB_MAKEMASK1(1)
+
+#define S_DUART_ISR_RX_A 1
+#define M_DUART_ISR_RX_A _SB_MAKEMASK1(S_DUART_ISR_RX_A)
+#define V_DUART_ISR_RX_A(x) _SB_MAKEVALUE(x,S_DUART_ISR_RX_A)
+#define G_DUART_ISR_RX_A(x) _SB_GETVALUE(x,S_DUART_ISR_RX_A,M_DUART_ISR_RX_A)
+
#define M_DUART_ISR_BRK_A _SB_MAKEMASK1(2)
#define M_DUART_ISR_IN_A _SB_MAKEMASK1(3)
#define M_DUART_ISR_TX_B _SB_MAKEMASK1(4)
@@ -331,7 +334,7 @@
#define M_DUART_OUT_PIN_CLR(chan) \
(chan == 0 ? M_DUART_OUT_PIN_CLR0 : M_DUART_OUT_PIN_CLR1)
-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
/*
* Full Interrupt Control Register
*/
@@ -345,7 +348,7 @@
#define M_DUART_INT_TIME _SB_MAKEMASK(4,S_DUART_INT_TIME)
#define V_DUART_INT_TIME(x) _SB_MAKEVALUE(x,S_DUART_INT_TIME)
#define G_DUART_INT_TIME(x) _SB_GETVALUE(x,S_DUART_INT_TIME,M_DUART_INT_TIME)
-#endif /* 1250 PASS2 || 112x PASS1 */
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
/* ********************************************************************** */
diff --git a/include/asm-mips/sibyte/swarm.h b/include/asm-mips/sibyte/swarm.h
index 97fa0494c30c..06e1d528e03a 100644
--- a/include/asm-mips/sibyte/swarm.h
+++ b/include/asm-mips/sibyte/swarm.h
@@ -34,7 +34,7 @@
#define SIBYTE_DEFAULT_CONSOLE "ttyS0,115200"
#endif
#ifdef CONFIG_SIBYTE_LITTLESUR
-#define SIBYTE_BOARD_NAME "BCM1250C2 (LittleSur)"
+#define SIBYTE_BOARD_NAME "BCM91250C2 (LittleSur)"
#define SIBYTE_HAVE_PCMCIA 0
#define SIBYTE_HAVE_IDE 1
#define SIBYTE_DEFAULT_CONSOLE "cfe0"
diff --git a/include/asm-mips/sigcontext.h b/include/asm-mips/sigcontext.h
index f7fbebaa0744..8edabb0be23f 100644
--- a/include/asm-mips/sigcontext.h
+++ b/include/asm-mips/sigcontext.h
@@ -27,14 +27,15 @@ struct sigcontext {
unsigned int sc_fpc_csr;
unsigned int sc_fpc_eir; /* Unused */
unsigned int sc_used_math;
- unsigned int sc_ssflags; /* Unused */
+ unsigned int sc_dsp; /* dsp status, was sc_ssflags */
unsigned long long sc_mdhi;
unsigned long long sc_mdlo;
-
- unsigned int sc_cause; /* Unused */
- unsigned int sc_badvaddr; /* Unused */
-
- unsigned long sc_sigset[4]; /* kernel's sigset_t */
+ unsigned long sc_hi1; /* Was sc_cause */
+ unsigned long sc_lo1; /* Was sc_badvaddr */
+ unsigned long sc_hi2; /* Was sc_sigset[4] */
+ unsigned long sc_lo2;
+ unsigned long sc_hi3;
+ unsigned long sc_lo3;
};
#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
@@ -48,19 +49,19 @@ struct sigcontext {
* Warning: this structure illdefined with sc_badvaddr being just an unsigned
* int so it was changed to unsigned long in 2.6.0-test1. This may break
* binary compatibility - no prisoners.
+ * DSP ASE in 2.6.12-rc4. Turn sc_mdhi and sc_mdlo into an array of four
+ * entries, add sc_dsp and sc_reserved for padding. No prisoners.
*/
struct sigcontext {
unsigned long sc_regs[32];
unsigned long sc_fpregs[32];
- unsigned long sc_mdhi;
- unsigned long sc_mdlo;
+ unsigned long sc_hi[4];
+ unsigned long sc_lo[4];
unsigned long sc_pc;
- unsigned long sc_badvaddr;
- unsigned int sc_status;
unsigned int sc_fpc_csr;
- unsigned int sc_fpc_eir;
unsigned int sc_used_math;
- unsigned int sc_cause;
+ unsigned int sc_dsp;
+ unsigned int sc_reserved;
};
#ifdef __KERNEL__
@@ -68,23 +69,24 @@ struct sigcontext {
#include <linux/posix_types.h>
struct sigcontext32 {
- __u32 sc_regmask; /* Unused */
- __u32 sc_status;
- __u64 sc_pc;
- __u64 sc_regs[32];
- __u64 sc_fpregs[32];
- __u32 sc_ownedfp; /* Unused */
- __u32 sc_fpc_csr;
- __u32 sc_fpc_eir; /* Unused */
- __u32 sc_used_math;
- __u32 sc_ssflags; /* Unused */
- __u64 sc_mdhi;
- __u64 sc_mdlo;
-
- __u32 sc_cause; /* Unused */
- __u32 sc_badvaddr; /* Unused */
-
- __u32 sc_sigset[4]; /* kernel's sigset_t */
+ __u32 sc_regmask; /* Unused */
+ __u32 sc_status;
+ __u64 sc_pc;
+ __u64 sc_regs[32];
+ __u64 sc_fpregs[32];
+ __u32 sc_ownedfp; /* Unused */
+ __u32 sc_fpc_csr;
+ __u32 sc_fpc_eir; /* Unused */
+ __u32 sc_used_math;
+ __u32 sc_dsp; /* dsp status, was sc_ssflags */
+ __u64 sc_mdhi;
+ __u64 sc_mdlo;
+ __u32 sc_hi1; /* Was sc_cause */
+ __u32 sc_lo1; /* Was sc_badvaddr */
+ __u32 sc_hi2; /* Was sc_sigset[4] */
+ __u32 sc_lo2;
+ __u32 sc_hi3;
+ __u32 sc_lo3;
};
#endif /* __KERNEL__ */
diff --git a/include/asm-mips/siginfo.h b/include/asm-mips/siginfo.h
index 698becab5a9e..2ba313d94a78 100644
--- a/include/asm-mips/siginfo.h
+++ b/include/asm-mips/siginfo.h
@@ -11,6 +11,7 @@
#include <linux/config.h>
+#define __ARCH_SIGEV_PREAMBLE_SIZE (sizeof(long) + 2*sizeof(int))
#undef __ARCH_SI_TRAPNO /* exception code needs to fill this ... */
#define HAVE_ARCH_SIGINFO_T
diff --git a/include/asm-mips/signal.h b/include/asm-mips/signal.h
index f2c470f1d369..8ca539e80d87 100644
--- a/include/asm-mips/signal.h
+++ b/include/asm-mips/signal.h
@@ -98,12 +98,39 @@ typedef unsigned long old_sigset_t; /* at least 32 bits */
#define MINSIGSTKSZ 2048
#define SIGSTKSZ 8192
+#ifdef __KERNEL__
+
+/*
+ * These values of sa_flags are used only by the kernel as part of the
+ * irq handling routines.
+ *
+ * SA_INTERRUPT is also used by the irq handling routines.
+ * SA_SHIRQ flag is for shared interrupt support on PCI and EISA.
+ */
+#define SA_SAMPLE_RANDOM SA_RESTART
+
+#ifdef CONFIG_TRAD_SIGNALS
+#define sig_uses_siginfo(ka) ((ka)->sa.sa_flags & SA_SIGINFO)
+#else
+#define sig_uses_siginfo(ka) (1)
+#endif
+
+#endif /* __KERNEL__ */
+
#define SIG_BLOCK 1 /* for blocking signals */
#define SIG_UNBLOCK 2 /* for unblocking signals */
#define SIG_SETMASK 3 /* for setting the signal mask */
#define SIG_SETMASK32 256 /* Goodie from SGI for BSD compatibility:
set only the low 32 bit of the sigset. */
-#include <asm-generic/signal.h>
+
+/* Type of a signal handler. */
+typedef void __signalfn_t(int);
+typedef __signalfn_t __user *__sighandler_t;
+
+/* Fake signal functions */
+#define SIG_DFL ((__sighandler_t)0) /* default signal handling */
+#define SIG_IGN ((__sighandler_t)1) /* ignore signal */
+#define SIG_ERR ((__sighandler_t)-1) /* error return from signal */
struct sigaction {
unsigned int sa_flags;
diff --git a/include/asm-mips/sn/sn0/arch.h b/include/asm-mips/sn/sn0/arch.h
index 0e00dd474afc..fb78773a5efe 100644
--- a/include/asm-mips/sn/sn0/arch.h
+++ b/include/asm-mips/sn/sn0/arch.h
@@ -74,13 +74,8 @@
#define MAX_MEM_SLOTS 32 /* max slots per node */
#endif /* defined(N_MODE) */
-#if SABLE_RTL
-#define SLOT_SHIFT (28)
-#define SLOT_MIN_MEM_SIZE (16*1024*1024)
-#else
#define SLOT_SHIFT (27)
#define SLOT_MIN_MEM_SIZE (32*1024*1024)
-#endif
#define CPUS_PER_NODE 2 /* CPUs on a single hub */
#define CPUS_PER_NODE_SHFT 1 /* Bits to shift in the node number */
diff --git a/include/asm-mips/socket.h b/include/asm-mips/socket.h
index 753b6620e6fa..0bb31e5aaca6 100644
--- a/include/asm-mips/socket.h
+++ b/include/asm-mips/socket.h
@@ -37,8 +37,6 @@ To add: #define SO_REUSEPORT 0x0200 /* Allow local address and port reuse. */
#define SO_ERROR 0x1007 /* get error status and clear */
#define SO_SNDBUF 0x1001 /* Send buffer size. */
#define SO_RCVBUF 0x1002 /* Receive buffer. */
-#define SO_SNDBUFFORCE 0x100a
-#define SO_RCVBUFFORCE 0x100b
#define SO_SNDLOWAT 0x1003 /* send low-water mark */
#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
#define SO_SNDTIMEO 0x1005 /* send timeout */
@@ -69,6 +67,8 @@ To add: #define SO_REUSEPORT 0x0200 /* Allow local address and port reuse. */
#define SCM_TIMESTAMP SO_TIMESTAMP
#define SO_PEERSEC 30
+#define SO_SNDBUFFORCE 31
+#define SO_RCVBUFFORCE 33
#ifdef __KERNEL__
@@ -92,6 +92,7 @@ enum sock_type {
SOCK_RAW = 3,
SOCK_RDM = 4,
SOCK_SEQPACKET = 5,
+ SOCK_DCCP = 6,
SOCK_PACKET = 10,
};
diff --git a/include/asm-mips/spinlock.h b/include/asm-mips/spinlock.h
index 4d0135b11156..669b8e349ff2 100644
--- a/include/asm-mips/spinlock.h
+++ b/include/asm-mips/spinlock.h
@@ -9,17 +9,16 @@
#ifndef _ASM_SPINLOCK_H
#define _ASM_SPINLOCK_H
-#include <linux/config.h>
#include <asm/war.h>
/*
* Your basic SMP spinlocks, allowing only a single CPU anywhere
*/
-#define __raw_spin_is_locked(x) ((x)->lock != 0)
+#define __raw_spin_is_locked(x) ((x)->lock != 0)
#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
#define __raw_spin_unlock_wait(x) \
- do { cpu_relax(); } while ((x)->lock)
+ do { cpu_relax(); } while ((x)->lock)
/*
* Simple spin lock operations. There are two variants, one clears IRQ's
@@ -119,6 +118,18 @@ static inline unsigned int __raw_spin_trylock(raw_spinlock_t *lock)
* read-locks.
*/
+/*
+ * read_can_lock - would read_trylock() succeed?
+ * @lock: the rwlock in question.
+ */
+#define __raw_read_can_lock(rw) ((rw)->lock >= 0)
+
+/*
+ * write_can_lock - would write_trylock() succeed?
+ * @lock: the rwlock in question.
+ */
+#define __raw_write_can_lock(rw) (!(rw)->lock)
+
static inline void __raw_read_lock(raw_rwlock_t *rw)
{
unsigned int tmp;
@@ -197,8 +208,7 @@ static inline void __raw_write_lock(raw_rwlock_t *rw)
" lui %1, 0x8000 \n"
" sc %1, %0 \n"
" beqzl %1, 1b \n"
- " nop \n"
- " sync \n"
+ " sync \n"
" .set reorder \n"
: "=m" (rw->lock), "=&r" (tmp)
: "m" (rw->lock)
@@ -211,8 +221,7 @@ static inline void __raw_write_lock(raw_rwlock_t *rw)
" lui %1, 0x8000 \n"
" sc %1, %0 \n"
" beqz %1, 1b \n"
- " nop \n"
- " sync \n"
+ " sync \n"
" .set reorder \n"
: "=m" (rw->lock), "=&r" (tmp)
: "m" (rw->lock)
@@ -246,8 +255,7 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw)
" lui %1, 0x8000 \n"
" sc %1, %0 \n"
" beqzl %1, 1b \n"
- " nop \n"
- " sync \n"
+ " sync \n"
" li %2, 1 \n"
" .set reorder \n"
"2: \n"
diff --git a/include/asm-mips/stackframe.h b/include/asm-mips/stackframe.h
index 7b5e64600bc8..a8919dcc93c8 100644
--- a/include/asm-mips/stackframe.h
+++ b/include/asm-mips/stackframe.h
@@ -60,7 +60,6 @@
mfc0 k0, CP0_CONTEXT
lui k1, %hi(kernelsp)
srl k0, k0, 23
- sll k0, k0, 2
addu k1, k0
LONG_L k1, %lo(kernelsp)(k1)
#endif
@@ -76,9 +75,14 @@
#endif
#if defined(CONFIG_64BIT) && defined(CONFIG_BUILD_ELF64)
MFC0 k1, CP0_CONTEXT
+ lui k0, %highest(kernelsp)
dsrl k1, 23
- dsll k1, k1, 3
- LONG_L k1, kernelsp(k1)
+ daddiu k0, %higher(kernelsp)
+ dsll k0, k0, 16
+ daddiu k0, %hi(kernelsp)
+ dsll k0, k0, 16
+ daddu k1, k1, k0
+ LONG_L k1, %lo(kernelsp)(k1)
#endif
.endm
@@ -86,25 +90,28 @@
#ifdef CONFIG_32BIT
mfc0 \temp, CP0_CONTEXT
srl \temp, 23
- sll \temp, 2
- LONG_S \stackp, kernelsp(\temp)
#endif
#if defined(CONFIG_64BIT) && !defined(CONFIG_BUILD_ELF64)
lw \temp, TI_CPU(gp)
dsll \temp, 3
- lui \temp2, %hi(kernelsp)
- daddu \temp, \temp2
- LONG_S \stackp, %lo(kernelsp)(\temp)
#endif
#if defined(CONFIG_64BIT) && defined(CONFIG_BUILD_ELF64)
- lw \temp, TI_CPU(gp)
- dsll \temp, 3
- LONG_S \stackp, kernelsp(\temp)
+ MFC0 \temp, CP0_CONTEXT
+ dsrl \temp, 23
#endif
+ LONG_S \stackp, kernelsp(\temp)
.endm
#else
.macro get_saved_sp /* Uniprocessor variation */
+#if defined(CONFIG_64BIT) && defined(CONFIG_BUILD_ELF64)
+ lui k1, %highest(kernelsp)
+ daddiu k1, %higher(kernelsp)
+ dsll k1, k1, 16
+ daddiu k1, %hi(kernelsp)
+ dsll k1, k1, 16
+#else
lui k1, %hi(kernelsp)
+#endif
LONG_L k1, %lo(kernelsp)(k1)
.endm
diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h
index 6663efd49b27..330c4e497af3 100644
--- a/include/asm-mips/system.h
+++ b/include/asm-mips/system.h
@@ -17,6 +17,7 @@
#include <asm/addrspace.h>
#include <asm/cpu-features.h>
+#include <asm/dsp.h>
#include <asm/ptrace.h>
#include <asm/war.h>
#include <asm/interrupt.h>
@@ -70,7 +71,7 @@
* does not enforce ordering, since there is no data dependency between
* the read of "a" and the read of "b". Therefore, on some CPUs, such
* as Alpha, "y" could be set to 3 and "x" to 0. Use rmb()
- * in cases like thiswhere there are no data dependencies.
+ * in cases like this where there are no data dependencies.
*/
#define read_barrier_depends() do { } while(0)
@@ -154,15 +155,15 @@ extern asmlinkage void *resume(void *last, void *next, void *next_ti);
struct task_struct;
-#define switch_to(prev,next,last) \
-do { \
- (last) = resume(prev, next, next->thread_info); \
+#define switch_to(prev,next,last) \
+do { \
+ if (cpu_has_dsp) \
+ __save_dsp(prev); \
+ (last) = resume(prev, next, next->thread_info); \
+ if (cpu_has_dsp) \
+ __restore_dsp(current); \
} while(0)
-#define ROT_IN_PIECES \
- " .set noreorder \n" \
- " .set reorder \n"
-
static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
{
__u32 retval;
@@ -171,14 +172,17 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
unsigned long dummy;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: ll %0, %3 # xchg_u32 \n"
+ " .set mips0 \n"
" move %2, %z4 \n"
+ " .set mips3 \n"
" sc %2, %1 \n"
" beqzl %2, 1b \n"
- ROT_IN_PIECES
#ifdef CONFIG_SMP
" sync \n"
#endif
+ " .set mips0 \n"
: "=&r" (retval), "=m" (*m), "=&r" (dummy)
: "R" (*m), "Jr" (val)
: "memory");
@@ -186,13 +190,17 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
unsigned long dummy;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: ll %0, %3 # xchg_u32 \n"
+ " .set mips0 \n"
" move %2, %z4 \n"
+ " .set mips3 \n"
" sc %2, %1 \n"
" beqz %2, 1b \n"
#ifdef CONFIG_SMP
" sync \n"
#endif
+ " .set mips0 \n"
: "=&r" (retval), "=m" (*m), "=&r" (dummy)
: "R" (*m), "Jr" (val)
: "memory");
@@ -217,14 +225,15 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
unsigned long dummy;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: lld %0, %3 # xchg_u64 \n"
" move %2, %z4 \n"
" scd %2, %1 \n"
" beqzl %2, 1b \n"
- ROT_IN_PIECES
#ifdef CONFIG_SMP
" sync \n"
#endif
+ " .set mips0 \n"
: "=&r" (retval), "=m" (*m), "=&r" (dummy)
: "R" (*m), "Jr" (val)
: "memory");
@@ -232,6 +241,7 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
unsigned long dummy;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: lld %0, %3 # xchg_u64 \n"
" move %2, %z4 \n"
" scd %2, %1 \n"
@@ -239,6 +249,7 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
#ifdef CONFIG_SMP
" sync \n"
#endif
+ " .set mips0 \n"
: "=&r" (retval), "=m" (*m), "=&r" (dummy)
: "R" (*m), "Jr" (val)
: "memory");
@@ -286,34 +297,41 @@ static inline unsigned long __cmpxchg_u32(volatile int * m, unsigned long old,
if (cpu_has_llsc && R10000_LLSC_WAR) {
__asm__ __volatile__(
+ " .set push \n"
" .set noat \n"
+ " .set mips3 \n"
"1: ll %0, %2 # __cmpxchg_u32 \n"
" bne %0, %z3, 2f \n"
+ " .set mips0 \n"
" move $1, %z4 \n"
+ " .set mips3 \n"
" sc $1, %1 \n"
" beqzl $1, 1b \n"
- ROT_IN_PIECES
#ifdef CONFIG_SMP
" sync \n"
#endif
"2: \n"
- " .set at \n"
+ " .set pop \n"
: "=&r" (retval), "=m" (*m)
: "R" (*m), "Jr" (old), "Jr" (new)
: "memory");
} else if (cpu_has_llsc) {
__asm__ __volatile__(
+ " .set push \n"
" .set noat \n"
+ " .set mips3 \n"
"1: ll %0, %2 # __cmpxchg_u32 \n"
" bne %0, %z3, 2f \n"
+ " .set mips0 \n"
" move $1, %z4 \n"
+ " .set mips3 \n"
" sc $1, %1 \n"
" beqz $1, 1b \n"
#ifdef CONFIG_SMP
" sync \n"
#endif
"2: \n"
- " .set at \n"
+ " .set pop \n"
: "=&r" (retval), "=m" (*m)
: "R" (*m), "Jr" (old), "Jr" (new)
: "memory");
@@ -338,24 +356,27 @@ static inline unsigned long __cmpxchg_u64(volatile int * m, unsigned long old,
if (cpu_has_llsc) {
__asm__ __volatile__(
+ " .set push \n"
" .set noat \n"
+ " .set mips3 \n"
"1: lld %0, %2 # __cmpxchg_u64 \n"
" bne %0, %z3, 2f \n"
" move $1, %z4 \n"
" scd $1, %1 \n"
" beqzl $1, 1b \n"
- ROT_IN_PIECES
#ifdef CONFIG_SMP
" sync \n"
#endif
"2: \n"
- " .set at \n"
+ " .set pop \n"
: "=&r" (retval), "=m" (*m)
: "R" (*m), "Jr" (old), "Jr" (new)
: "memory");
} else if (cpu_has_llsc) {
__asm__ __volatile__(
+ " .set push \n"
" .set noat \n"
+ " .set mips3 \n"
"1: lld %0, %2 # __cmpxchg_u64 \n"
" bne %0, %z3, 2f \n"
" move $1, %z4 \n"
@@ -365,7 +386,7 @@ static inline unsigned long __cmpxchg_u64(volatile int * m, unsigned long old,
" sync \n"
#endif
"2: \n"
- " .set at \n"
+ " .set pop \n"
: "=&r" (retval), "=m" (*m)
: "R" (*m), "Jr" (old), "Jr" (new)
: "memory");
@@ -406,18 +427,20 @@ static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old,
#define cmpxchg(ptr,old,new) ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(old), (unsigned long)(new),sizeof(*(ptr))))
+extern void set_handler (unsigned long offset, void *addr, unsigned long len);
+extern void set_uncached_handler (unsigned long offset, void *addr, unsigned long len);
+extern void *set_vi_handler (int n, void *addr);
+extern void *set_vi_srs_handler (int n, void *addr, int regset);
extern void *set_except_vector(int n, void *addr);
extern void per_cpu_trap_init(void);
-extern NORET_TYPE void __die(const char *, struct pt_regs *, const char *file,
- const char *func, unsigned long line);
-extern void __die_if_kernel(const char *, struct pt_regs *, const char *file,
- const char *func, unsigned long line);
+extern NORET_TYPE void die(const char *, struct pt_regs *);
-#define die(msg, regs) \
- __die(msg, regs, __FILE__ ":", __FUNCTION__, __LINE__)
-#define die_if_kernel(msg, regs) \
- __die_if_kernel(msg, regs, __FILE__ ":", __FUNCTION__, __LINE__)
+static inline void die_if_kernel(const char *str, struct pt_regs *regs)
+{
+ if (unlikely(!user_mode(regs)))
+ die(str, regs);
+}
extern int stop_a_enabled;
diff --git a/include/asm-mips/thread_info.h b/include/asm-mips/thread_info.h
index a70cb0854c8a..e6c24472e03f 100644
--- a/include/asm-mips/thread_info.h
+++ b/include/asm-mips/thread_info.h
@@ -26,6 +26,7 @@ struct thread_info {
struct task_struct *task; /* main task structure */
struct exec_domain *exec_domain; /* execution domain */
unsigned long flags; /* low level flags */
+ unsigned long tp_value; /* thread pointer */
__u32 cpu; /* current CPU */
int preempt_count; /* 0 => preemptable, <0 => BUG */
@@ -114,6 +115,7 @@ register struct thread_info *__current_thread_info __asm__("$28");
#define TIF_SIGPENDING 2 /* signal pending */
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_SYSCALL_AUDIT 4 /* syscall auditing active */
+#define TIF_SECCOMP 5 /* secure computing */
#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */
#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define TIF_MEMDIE 18
@@ -124,13 +126,14 @@ register struct thread_info *__current_thread_info __asm__("$28");
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
+#define _TIF_SECCOMP (1<<TIF_SECCOMP)
#define _TIF_USEDFPU (1<<TIF_USEDFPU)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
-#define _TIF_WORK_MASK 0x0000ffef /* work to do on
- interrupt/exception return */
-#define _TIF_ALLWORK_MASK 0x8000ffff /* work to do on any return to
- u-space */
+/* work to do on interrupt/exception return */
+#define _TIF_WORK_MASK (0x0000ffef & ~_TIF_SECCOMP)
+/* work to do on any return to u-space */
+#define _TIF_ALLWORK_MASK (0x8000ffff & ~_TIF_SECCOMP)
#endif /* __KERNEL__ */
diff --git a/include/asm-mips/traps.h b/include/asm-mips/traps.h
index 179012263007..d02e019b0127 100644
--- a/include/asm-mips/traps.h
+++ b/include/asm-mips/traps.h
@@ -21,4 +21,7 @@
extern void (*board_be_init)(void);
extern int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
+extern void (*board_nmi_handler_setup)(void);
+extern void (*board_ejtag_handler_setup)(void);
+
#endif /* _ASM_TRAPS_H */
diff --git a/include/asm-mips/tx4938/rbtx4938.h b/include/asm-mips/tx4938/rbtx4938.h
new file mode 100644
index 000000000000..0fbedafdcea8
--- /dev/null
+++ b/include/asm-mips/tx4938/rbtx4938.h
@@ -0,0 +1,207 @@
+/*
+ * linux/include/asm-mips/tx4938/rbtx4938.h
+ * Definitions for TX4937/TX4938
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#ifndef __ASM_TX_BOARDS_RBTX4938_H
+#define __ASM_TX_BOARDS_RBTX4938_H
+
+#include <asm/addrspace.h>
+#include <asm/tx4938/tx4938.h>
+
+/* CS */
+#define RBTX4938_CE0 0x1c000000 /* 64M */
+#define RBTX4938_CE2 0x17f00000 /* 1M */
+
+/* Address map */
+#define RBTX4938_FPGA_REG_ADDR (KSEG1 + RBTX4938_CE2 + 0x00000000)
+#define RBTX4938_FPGA_REV_ADDR (KSEG1 + RBTX4938_CE2 + 0x00000002)
+#define RBTX4938_CONFIG1_ADDR (KSEG1 + RBTX4938_CE2 + 0x00000004)
+#define RBTX4938_CONFIG2_ADDR (KSEG1 + RBTX4938_CE2 + 0x00000006)
+#define RBTX4938_CONFIG3_ADDR (KSEG1 + RBTX4938_CE2 + 0x00000008)
+#define RBTX4938_LED_ADDR (KSEG1 + RBTX4938_CE2 + 0x00001000)
+#define RBTX4938_DIPSW_ADDR (KSEG1 + RBTX4938_CE2 + 0x00001002)
+#define RBTX4938_BDIPSW_ADDR (KSEG1 + RBTX4938_CE2 + 0x00001004)
+#define RBTX4938_IMASK_ADDR (KSEG1 + RBTX4938_CE2 + 0x00002000)
+#define RBTX4938_IMASK2_ADDR (KSEG1 + RBTX4938_CE2 + 0x00002002)
+#define RBTX4938_INTPOL_ADDR (KSEG1 + RBTX4938_CE2 + 0x00002004)
+#define RBTX4938_ISTAT_ADDR (KSEG1 + RBTX4938_CE2 + 0x00002006)
+#define RBTX4938_ISTAT2_ADDR (KSEG1 + RBTX4938_CE2 + 0x00002008)
+#define RBTX4938_IMSTAT_ADDR (KSEG1 + RBTX4938_CE2 + 0x0000200a)
+#define RBTX4938_IMSTAT2_ADDR (KSEG1 + RBTX4938_CE2 + 0x0000200c)
+#define RBTX4938_SOFTINT_ADDR (KSEG1 + RBTX4938_CE2 + 0x00003000)
+#define RBTX4938_PIOSEL_ADDR (KSEG1 + RBTX4938_CE2 + 0x00005000)
+#define RBTX4938_SPICS_ADDR (KSEG1 + RBTX4938_CE2 + 0x00005002)
+#define RBTX4938_SFPWR_ADDR (KSEG1 + RBTX4938_CE2 + 0x00005008)
+#define RBTX4938_SFVOL_ADDR (KSEG1 + RBTX4938_CE2 + 0x0000500a)
+#define RBTX4938_SOFTRESET_ADDR (KSEG1 + RBTX4938_CE2 + 0x00007000)
+#define RBTX4938_SOFTRESETLOCK_ADDR (KSEG1 + RBTX4938_CE2 + 0x00007002)
+#define RBTX4938_PCIRESET_ADDR (KSEG1 + RBTX4938_CE2 + 0x00007004)
+#define RBTX4938_ETHER_BASE (KSEG1 + RBTX4938_CE2 + 0x00020000)
+
+/* Ethernet port address (Jumperless Mode (W12:Open)) */
+#define RBTX4938_ETHER_ADDR (RBTX4938_ETHER_BASE + 0x280)
+
+/* bits for ISTAT/IMASK/IMSTAT */
+#define RBTX4938_INTB_PCID 0
+#define RBTX4938_INTB_PCIC 1
+#define RBTX4938_INTB_PCIB 2
+#define RBTX4938_INTB_PCIA 3
+#define RBTX4938_INTB_RTC 4
+#define RBTX4938_INTB_ATA 5
+#define RBTX4938_INTB_MODEM 6
+#define RBTX4938_INTB_SWINT 7
+#define RBTX4938_INTF_PCID (1 << RBTX4938_INTB_PCID)
+#define RBTX4938_INTF_PCIC (1 << RBTX4938_INTB_PCIC)
+#define RBTX4938_INTF_PCIB (1 << RBTX4938_INTB_PCIB)
+#define RBTX4938_INTF_PCIA (1 << RBTX4938_INTB_PCIA)
+#define RBTX4938_INTF_RTC (1 << RBTX4938_INTB_RTC)
+#define RBTX4938_INTF_ATA (1 << RBTX4938_INTB_ATA)
+#define RBTX4938_INTF_MODEM (1 << RBTX4938_INTB_MODEM)
+#define RBTX4938_INTF_SWINT (1 << RBTX4938_INTB_SWINT)
+
+#define rbtx4938_fpga_rev_ptr \
+ ((volatile unsigned char *)RBTX4938_FPGA_REV_ADDR)
+#define rbtx4938_led_ptr \
+ ((volatile unsigned char *)RBTX4938_LED_ADDR)
+#define rbtx4938_dipsw_ptr \
+ ((volatile unsigned char *)RBTX4938_DIPSW_ADDR)
+#define rbtx4938_bdipsw_ptr \
+ ((volatile unsigned char *)RBTX4938_BDIPSW_ADDR)
+#define rbtx4938_imask_ptr \
+ ((volatile unsigned char *)RBTX4938_IMASK_ADDR)
+#define rbtx4938_imask2_ptr \
+ ((volatile unsigned char *)RBTX4938_IMASK2_ADDR)
+#define rbtx4938_intpol_ptr \
+ ((volatile unsigned char *)RBTX4938_INTPOL_ADDR)
+#define rbtx4938_istat_ptr \
+ ((volatile unsigned char *)RBTX4938_ISTAT_ADDR)
+#define rbtx4938_istat2_ptr \
+ ((volatile unsigned char *)RBTX4938_ISTAT2_ADDR)
+#define rbtx4938_imstat_ptr \
+ ((volatile unsigned char *)RBTX4938_IMSTAT_ADDR)
+#define rbtx4938_imstat2_ptr \
+ ((volatile unsigned char *)RBTX4938_IMSTAT2_ADDR)
+#define rbtx4938_softint_ptr \
+ ((volatile unsigned char *)RBTX4938_SOFTINT_ADDR)
+#define rbtx4938_piosel_ptr \
+ ((volatile unsigned char *)RBTX4938_PIOSEL_ADDR)
+#define rbtx4938_spics_ptr \
+ ((volatile unsigned char *)RBTX4938_SPICS_ADDR)
+#define rbtx4938_sfpwr_ptr \
+ ((volatile unsigned char *)RBTX4938_SFPWR_ADDR)
+#define rbtx4938_sfvol_ptr \
+ ((volatile unsigned char *)RBTX4938_SFVOL_ADDR)
+#define rbtx4938_softreset_ptr \
+ ((volatile unsigned char *)RBTX4938_SOFTRESET_ADDR)
+#define rbtx4938_softresetlock_ptr \
+ ((volatile unsigned char *)RBTX4938_SOFTRESETLOCK_ADDR)
+#define rbtx4938_pcireset_ptr \
+ ((volatile unsigned char *)RBTX4938_PCIRESET_ADDR)
+
+/* SPI */
+#define RBTX4938_SEEPROM1_CHIPID 0
+#define RBTX4938_SEEPROM2_CHIPID 1
+#define RBTX4938_SEEPROM3_CHIPID 2
+#define RBTX4938_SRTC_CHIPID 3
+
+/*
+ * IRQ mappings
+ */
+
+#define RBTX4938_SOFT_INT0 0 /* not used */
+#define RBTX4938_SOFT_INT1 1 /* not used */
+#define RBTX4938_IRC_INT 2
+#define RBTX4938_TIMER_INT 7
+
+/* These are the virtual IRQ numbers, we divide all IRQ's into
+ * 'spaces', the 'space' determines where and how to enable/disable
+ * that particular IRQ on an RBTX4938 machine. Add new 'spaces' as new
+ * IRQ hardware is supported.
+ */
+#define RBTX4938_NR_IRQ_LOCAL 8
+#define RBTX4938_NR_IRQ_IRC 32 /* On-Chip IRC */
+#define RBTX4938_NR_IRQ_IOC 8
+
+#define MI8259_IRQ_ISA_RAW_BEG 0 /* optional backplane i8259 */
+#define MI8259_IRQ_ISA_RAW_END 15
+#define TX4938_IRQ_CP0_RAW_BEG 0 /* tx4938 cpu built-in cp0 */
+#define TX4938_IRQ_CP0_RAW_END 7
+#define TX4938_IRQ_PIC_RAW_BEG 0 /* tx4938 cpu build-in pic */
+#define TX4938_IRQ_PIC_RAW_END 31
+
+#define MI8259_IRQ_ISA_BEG MI8259_IRQ_ISA_RAW_BEG /* 0 */
+#define MI8259_IRQ_ISA_END MI8259_IRQ_ISA_RAW_END /* 15 */
+
+#define TX4938_IRQ_CP0_BEG ((MI8259_IRQ_ISA_END+1)+TX4938_IRQ_CP0_RAW_BEG) /* 16 */
+#define TX4938_IRQ_CP0_END ((MI8259_IRQ_ISA_END+1)+TX4938_IRQ_CP0_RAW_END) /* 23 */
+
+#define TX4938_IRQ_PIC_BEG ((TX4938_IRQ_CP0_END+1)+TX4938_IRQ_PIC_RAW_BEG) /* 24 */
+#define TX4938_IRQ_PIC_END ((TX4938_IRQ_CP0_END+1)+TX4938_IRQ_PIC_RAW_END) /* 55 */
+#define TX4938_IRQ_NEST_EXT_ON_PIC (TX4938_IRQ_PIC_BEG+2)
+#define TX4938_IRQ_NEST_PIC_ON_CP0 (TX4938_IRQ_CP0_BEG+2)
+#define TX4938_IRQ_USER0 (TX4938_IRQ_CP0_BEG+0)
+#define TX4938_IRQ_USER1 (TX4938_IRQ_CP0_BEG+1)
+#define TX4938_IRQ_CPU_TIMER (TX4938_IRQ_CP0_BEG+7)
+
+#define TOSHIBA_RBTX4938_IRQ_IOC_RAW_BEG 0
+#define TOSHIBA_RBTX4938_IRQ_IOC_RAW_END 7
+
+#define TOSHIBA_RBTX4938_IRQ_IOC_BEG ((TX4938_IRQ_PIC_END+1)+TOSHIBA_RBTX4938_IRQ_IOC_RAW_BEG) /* 56 */
+#define TOSHIBA_RBTX4938_IRQ_IOC_END ((TX4938_IRQ_PIC_END+1)+TOSHIBA_RBTX4938_IRQ_IOC_RAW_END) /* 63 */
+#define RBTX4938_IRQ_LOCAL TX4938_IRQ_CP0_BEG
+#define RBTX4938_IRQ_IRC (RBTX4938_IRQ_LOCAL + RBTX4938_NR_IRQ_LOCAL)
+#define RBTX4938_IRQ_IOC (RBTX4938_IRQ_IRC + RBTX4938_NR_IRQ_IRC)
+#define RBTX4938_IRQ_END (RBTX4938_IRQ_IOC + RBTX4938_NR_IRQ_IOC)
+
+#define RBTX4938_IRQ_LOCAL_SOFT0 (RBTX4938_IRQ_LOCAL + RBTX4938_SOFT_INT0)
+#define RBTX4938_IRQ_LOCAL_SOFT1 (RBTX4938_IRQ_LOCAL + RBTX4938_SOFT_INT1)
+#define RBTX4938_IRQ_LOCAL_IRC (RBTX4938_IRQ_LOCAL + RBTX4938_IRC_INT)
+#define RBTX4938_IRQ_LOCAL_TIMER (RBTX4938_IRQ_LOCAL + RBTX4938_TIMER_INT)
+#define RBTX4938_IRQ_IRC_ECCERR (RBTX4938_IRQ_IRC + TX4938_IR_ECCERR)
+#define RBTX4938_IRQ_IRC_WTOERR (RBTX4938_IRQ_IRC + TX4938_IR_WTOERR)
+#define RBTX4938_IRQ_IRC_INT(n) (RBTX4938_IRQ_IRC + TX4938_IR_INT(n))
+#define RBTX4938_IRQ_IRC_SIO(n) (RBTX4938_IRQ_IRC + TX4938_IR_SIO(n))
+#define RBTX4938_IRQ_IRC_DMA(ch,n) (RBTX4938_IRQ_IRC + TX4938_IR_DMA(ch,n))
+#define RBTX4938_IRQ_IRC_PIO (RBTX4938_IRQ_IRC + TX4938_IR_PIO)
+#define RBTX4938_IRQ_IRC_PDMAC (RBTX4938_IRQ_IRC + TX4938_IR_PDMAC)
+#define RBTX4938_IRQ_IRC_PCIC (RBTX4938_IRQ_IRC + TX4938_IR_PCIC)
+#define RBTX4938_IRQ_IRC_TMR(n) (RBTX4938_IRQ_IRC + TX4938_IR_TMR(n))
+#define RBTX4938_IRQ_IRC_NDFMC (RBTX4938_IRQ_IRC + TX4938_IR_NDFMC)
+#define RBTX4938_IRQ_IRC_PCIERR (RBTX4938_IRQ_IRC + TX4938_IR_PCIERR)
+#define RBTX4938_IRQ_IRC_PCIPME (RBTX4938_IRQ_IRC + TX4938_IR_PCIPME)
+#define RBTX4938_IRQ_IRC_ACLC (RBTX4938_IRQ_IRC + TX4938_IR_ACLC)
+#define RBTX4938_IRQ_IRC_ACLCPME (RBTX4938_IRQ_IRC + TX4938_IR_ACLCPME)
+#define RBTX4938_IRQ_IRC_PCIC1 (RBTX4938_IRQ_IRC + TX4938_IR_PCIC1)
+#define RBTX4938_IRQ_IRC_SPI (RBTX4938_IRQ_IRC + TX4938_IR_SPI)
+#define RBTX4938_IRQ_IOC_PCID (RBTX4938_IRQ_IOC + RBTX4938_INTB_PCID)
+#define RBTX4938_IRQ_IOC_PCIC (RBTX4938_IRQ_IOC + RBTX4938_INTB_PCIC)
+#define RBTX4938_IRQ_IOC_PCIB (RBTX4938_IRQ_IOC + RBTX4938_INTB_PCIB)
+#define RBTX4938_IRQ_IOC_PCIA (RBTX4938_IRQ_IOC + RBTX4938_INTB_PCIA)
+#define RBTX4938_IRQ_IOC_RTC (RBTX4938_IRQ_IOC + RBTX4938_INTB_RTC)
+#define RBTX4938_IRQ_IOC_ATA (RBTX4938_IRQ_IOC + RBTX4938_INTB_ATA)
+#define RBTX4938_IRQ_IOC_MODEM (RBTX4938_IRQ_IOC + RBTX4938_INTB_MODEM)
+#define RBTX4938_IRQ_IOC_SWINT (RBTX4938_IRQ_IOC + RBTX4938_INTB_SWINT)
+
+
+/* IOC (PCI, etc) */
+#define RBTX4938_IRQ_IOCINT (TX4938_IRQ_NEST_EXT_ON_PIC)
+/* Onboard 10M Ether */
+#define RBTX4938_IRQ_ETHER (TX4938_IRQ_NEST_EXT_ON_PIC + 1)
+
+#define RBTX4938_RTL_8019_BASE (RBTX4938_ETHER_ADDR - mips_io_port_base)
+#define RBTX4938_RTL_8019_IRQ (RBTX4938_IRQ_ETHER)
+
+/* IRCR : Int. Control */
+#define TX4938_IRCR_LOW 0x00000000
+#define TX4938_IRCR_HIGH 0x00000001
+#define TX4938_IRCR_DOWN 0x00000002
+#define TX4938_IRCR_UP 0x00000003
+
+#endif /* __ASM_TX_BOARDS_RBTX4938_H */
diff --git a/include/asm-mips/tx4938/spi.h b/include/asm-mips/tx4938/spi.h
new file mode 100644
index 000000000000..0dbbab820a5a
--- /dev/null
+++ b/include/asm-mips/tx4938/spi.h
@@ -0,0 +1,74 @@
+/*
+ * linux/include/asm-mips/tx4938/spi.h
+ * Definitions for TX4937/TX4938 SPI
+ *
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#ifndef __ASM_TX_BOARDS_TX4938_SPI_H
+#define __ASM_TX_BOARDS_TX4938_SPI_H
+
+/* SPI */
+struct spi_dev_desc {
+ unsigned int baud;
+ unsigned short tcss, tcsh, tcsr; /* CS setup/hold/recovery time */
+ unsigned int byteorder:1; /* 0:LSB-First, 1:MSB-First */
+ unsigned int polarity:1; /* 0:High-Active */
+ unsigned int phase:1; /* 0:Sample-Then-Shift */
+};
+
+extern void txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on)) __init;
+extern void txx9_spi_irqinit(int irc_irq) __init;
+extern int txx9_spi_io(int chipid, struct spi_dev_desc *desc,
+ unsigned char **inbufs, unsigned int *incounts,
+ unsigned char **outbufs, unsigned int *outcounts,
+ int cansleep);
+extern int spi_eeprom_write_enable(int chipid, int enable);
+extern int spi_eeprom_read_status(int chipid);
+extern int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len);
+extern int spi_eeprom_write(int chipid, int address, unsigned char *buf, int len);
+extern void spi_eeprom_proc_create(struct proc_dir_entry *dir, int chipid) __init;
+
+#define TXX9_IMCLK (txx9_gbus_clock / 2)
+
+/*
+* SPI
+*/
+
+/* SPMCR : SPI Master Control */
+#define TXx9_SPMCR_OPMODE 0xc0
+#define TXx9_SPMCR_CONFIG 0x40
+#define TXx9_SPMCR_ACTIVE 0x80
+#define TXx9_SPMCR_SPSTP 0x02
+#define TXx9_SPMCR_BCLR 0x01
+
+/* SPCR0 : SPI Status */
+#define TXx9_SPCR0_TXIFL_MASK 0xc000
+#define TXx9_SPCR0_RXIFL_MASK 0x3000
+#define TXx9_SPCR0_SIDIE 0x0800
+#define TXx9_SPCR0_SOEIE 0x0400
+#define TXx9_SPCR0_RBSIE 0x0200
+#define TXx9_SPCR0_TBSIE 0x0100
+#define TXx9_SPCR0_IFSPSE 0x0010
+#define TXx9_SPCR0_SBOS 0x0004
+#define TXx9_SPCR0_SPHA 0x0002
+#define TXx9_SPCR0_SPOL 0x0001
+
+/* SPSR : SPI Status */
+#define TXx9_SPSR_TBSI 0x8000
+#define TXx9_SPSR_RBSI 0x4000
+#define TXx9_SPSR_TBS_MASK 0x3800
+#define TXx9_SPSR_RBS_MASK 0x0700
+#define TXx9_SPSR_SPOE 0x0080
+#define TXx9_SPSR_IFSD 0x0008
+#define TXx9_SPSR_SIDLE 0x0004
+#define TXx9_SPSR_STRDY 0x0002
+#define TXx9_SPSR_SRRDY 0x0001
+
+#endif /* __ASM_TX_BOARDS_TX4938_SPI_H */
diff --git a/include/asm-mips/tx4938/tx4938.h b/include/asm-mips/tx4938/tx4938.h
new file mode 100644
index 000000000000..e25b1a0975cb
--- /dev/null
+++ b/include/asm-mips/tx4938/tx4938.h
@@ -0,0 +1,706 @@
+/*
+ * linux/include/asm-mips/tx4938/tx4938.h
+ * Definitions for TX4937/TX4938
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#ifndef __ASM_TX_BOARDS_TX4938_H
+#define __ASM_TX_BOARDS_TX4938_H
+
+#include <asm/tx4938/tx4938_mips.h>
+
+#define tx4938_read_nfmc(addr) (*(volatile unsigned int *)(addr))
+#define tx4938_write_nfmc(b,addr) (*(volatile unsigned int *)(addr)) = (b)
+
+#define TX4938_NR_IRQ_LOCAL TX4938_IRQ_PIC_BEG
+
+#define TX4938_IRQ_IRC_PCIC (TX4938_NR_IRQ_LOCAL + TX4938_IR_PCIC)
+#define TX4938_IRQ_IRC_PCIERR (TX4938_NR_IRQ_LOCAL + TX4938_IR_PCIERR)
+
+#define TX4938_PCIIO_0 0x10000000
+#define TX4938_PCIIO_1 0x01010000
+#define TX4938_PCIMEM_0 0x08000000
+#define TX4938_PCIMEM_1 0x11000000
+
+#define TX4938_PCIIO_SIZE_0 0x01000000
+#define TX4938_PCIIO_SIZE_1 0x00010000
+#define TX4938_PCIMEM_SIZE_0 0x08000000
+#define TX4938_PCIMEM_SIZE_1 0x00010000
+
+#define TX4938_REG_BASE 0xff1f0000 /* == TX4937_REG_BASE */
+#define TX4938_REG_SIZE 0x00010000 /* == TX4937_REG_SIZE */
+
+/* NDFMC, SRAMC, PCIC1, SPIC: TX4938 only */
+#define TX4938_NDFMC_REG (TX4938_REG_BASE + 0x5000)
+#define TX4938_SRAMC_REG (TX4938_REG_BASE + 0x6000)
+#define TX4938_PCIC1_REG (TX4938_REG_BASE + 0x7000)
+#define TX4938_SDRAMC_REG (TX4938_REG_BASE + 0x8000)
+#define TX4938_EBUSC_REG (TX4938_REG_BASE + 0x9000)
+#define TX4938_DMA_REG(ch) (TX4938_REG_BASE + 0xb000 + (ch) * 0x800)
+#define TX4938_PCIC_REG (TX4938_REG_BASE + 0xd000)
+#define TX4938_CCFG_REG (TX4938_REG_BASE + 0xe000)
+#define TX4938_NR_TMR 3
+#define TX4938_TMR_REG(ch) ((TX4938_REG_BASE + 0xf000) + (ch) * 0x100)
+#define TX4938_NR_SIO 2
+#define TX4938_SIO_REG(ch) ((TX4938_REG_BASE + 0xf300) + (ch) * 0x100)
+#define TX4938_PIO_REG (TX4938_REG_BASE + 0xf500)
+#define TX4938_IRC_REG (TX4938_REG_BASE + 0xf600)
+#define TX4938_ACLC_REG (TX4938_REG_BASE + 0xf700)
+#define TX4938_SPI_REG (TX4938_REG_BASE + 0xf800)
+
+#ifndef _LANGUAGE_ASSEMBLY
+#include <asm/byteorder.h>
+
+#define TX4938_MKA(x) ((u32)( ((u32)(TX4938_REG_BASE)) | ((u32)(x)) ))
+
+#define TX4938_RD08( reg ) (*(vu08*)(reg))
+#define TX4938_WR08( reg, val ) ((*(vu08*)(reg))=(val))
+
+#define TX4938_RD16( reg ) (*(vu16*)(reg))
+#define TX4938_WR16( reg, val ) ((*(vu16*)(reg))=(val))
+
+#define TX4938_RD32( reg ) (*(vu32*)(reg))
+#define TX4938_WR32( reg, val ) ((*(vu32*)(reg))=(val))
+
+#define TX4938_RD64( reg ) (*(vu64*)(reg))
+#define TX4938_WR64( reg, val ) ((*(vu64*)(reg))=(val))
+
+#define TX4938_RD( reg ) TX4938_RD32( reg )
+#define TX4938_WR( reg, val ) TX4938_WR32( reg, val )
+
+#endif /* !__ASSEMBLY__ */
+
+#ifdef __ASSEMBLY__
+#define _CONST64(c) c
+#else
+#define _CONST64(c) c##ull
+
+#include <asm/byteorder.h>
+
+#ifdef __BIG_ENDIAN
+#define endian_def_l2(e1,e2) \
+ volatile unsigned long e1,e2
+#define endian_def_s2(e1,e2) \
+ volatile unsigned short e1,e2
+#define endian_def_sb2(e1,e2,e3) \
+ volatile unsigned short e1;volatile unsigned char e2,e3
+#define endian_def_b2s(e1,e2,e3) \
+ volatile unsigned char e1,e2;volatile unsigned short e3
+#define endian_def_b4(e1,e2,e3,e4) \
+ volatile unsigned char e1,e2,e3,e4
+#else
+#define endian_def_l2(e1,e2) \
+ volatile unsigned long e2,e1
+#define endian_def_s2(e1,e2) \
+ volatile unsigned short e2,e1
+#define endian_def_sb2(e1,e2,e3) \
+ volatile unsigned char e3,e2;volatile unsigned short e1
+#define endian_def_b2s(e1,e2,e3) \
+ volatile unsigned short e3;volatile unsigned char e2,e1
+#define endian_def_b4(e1,e2,e3,e4) \
+ volatile unsigned char e4,e3,e2,e1
+#endif
+
+
+struct tx4938_sdramc_reg {
+ volatile unsigned long long cr[4];
+ volatile unsigned long long unused0[4];
+ volatile unsigned long long tr;
+ volatile unsigned long long unused1[2];
+ volatile unsigned long long cmd;
+ volatile unsigned long long sfcmd;
+};
+
+struct tx4938_ebusc_reg {
+ volatile unsigned long long cr[8];
+};
+
+struct tx4938_dma_reg {
+ struct tx4938_dma_ch_reg {
+ volatile unsigned long long cha;
+ volatile unsigned long long sar;
+ volatile unsigned long long dar;
+ endian_def_l2(unused0, cntr);
+ endian_def_l2(unused1, sair);
+ endian_def_l2(unused2, dair);
+ endian_def_l2(unused3, ccr);
+ endian_def_l2(unused4, csr);
+ } ch[4];
+ volatile unsigned long long dbr[8];
+ volatile unsigned long long tdhr;
+ volatile unsigned long long midr;
+ endian_def_l2(unused0, mcr);
+};
+
+struct tx4938_pcic_reg {
+ volatile unsigned long pciid;
+ volatile unsigned long pcistatus;
+ volatile unsigned long pciccrev;
+ volatile unsigned long pcicfg1;
+ volatile unsigned long p2gm0plbase; /* +10 */
+ volatile unsigned long p2gm0pubase;
+ volatile unsigned long p2gm1plbase;
+ volatile unsigned long p2gm1pubase;
+ volatile unsigned long p2gm2pbase; /* +20 */
+ volatile unsigned long p2giopbase;
+ volatile unsigned long unused0;
+ volatile unsigned long pcisid;
+ volatile unsigned long unused1; /* +30 */
+ volatile unsigned long pcicapptr;
+ volatile unsigned long unused2;
+ volatile unsigned long pcicfg2;
+ volatile unsigned long g2ptocnt; /* +40 */
+ volatile unsigned long unused3[15];
+ volatile unsigned long g2pstatus; /* +80 */
+ volatile unsigned long g2pmask;
+ volatile unsigned long pcisstatus;
+ volatile unsigned long pcimask;
+ volatile unsigned long p2gcfg; /* +90 */
+ volatile unsigned long p2gstatus;
+ volatile unsigned long p2gmask;
+ volatile unsigned long p2gccmd;
+ volatile unsigned long unused4[24]; /* +a0 */
+ volatile unsigned long pbareqport; /* +100 */
+ volatile unsigned long pbacfg;
+ volatile unsigned long pbastatus;
+ volatile unsigned long pbamask;
+ volatile unsigned long pbabm; /* +110 */
+ volatile unsigned long pbacreq;
+ volatile unsigned long pbacgnt;
+ volatile unsigned long pbacstate;
+ volatile unsigned long long g2pmgbase[3]; /* +120 */
+ volatile unsigned long long g2piogbase;
+ volatile unsigned long g2pmmask[3]; /* +140 */
+ volatile unsigned long g2piomask;
+ volatile unsigned long long g2pmpbase[3]; /* +150 */
+ volatile unsigned long long g2piopbase;
+ volatile unsigned long pciccfg; /* +170 */
+ volatile unsigned long pcicstatus;
+ volatile unsigned long pcicmask;
+ volatile unsigned long unused5;
+ volatile unsigned long long p2gmgbase[3]; /* +180 */
+ volatile unsigned long long p2giogbase;
+ volatile unsigned long g2pcfgadrs; /* +1a0 */
+ volatile unsigned long g2pcfgdata;
+ volatile unsigned long unused6[8];
+ volatile unsigned long g2pintack;
+ volatile unsigned long g2pspc;
+ volatile unsigned long unused7[12]; /* +1d0 */
+ volatile unsigned long long pdmca; /* +200 */
+ volatile unsigned long long pdmga;
+ volatile unsigned long long pdmpa;
+ volatile unsigned long long pdmctr;
+ volatile unsigned long long pdmcfg; /* +220 */
+ volatile unsigned long long pdmsts;
+};
+
+struct tx4938_aclc_reg {
+ volatile unsigned long acctlen;
+ volatile unsigned long acctldis;
+ volatile unsigned long acregacc;
+ volatile unsigned long unused0;
+ volatile unsigned long acintsts;
+ volatile unsigned long acintmsts;
+ volatile unsigned long acinten;
+ volatile unsigned long acintdis;
+ volatile unsigned long acsemaph;
+ volatile unsigned long unused1[7];
+ volatile unsigned long acgpidat;
+ volatile unsigned long acgpodat;
+ volatile unsigned long acslten;
+ volatile unsigned long acsltdis;
+ volatile unsigned long acfifosts;
+ volatile unsigned long unused2[11];
+ volatile unsigned long acdmasts;
+ volatile unsigned long acdmasel;
+ volatile unsigned long unused3[6];
+ volatile unsigned long acaudodat;
+ volatile unsigned long acsurrdat;
+ volatile unsigned long accentdat;
+ volatile unsigned long aclfedat;
+ volatile unsigned long acaudiat;
+ volatile unsigned long unused4;
+ volatile unsigned long acmodoat;
+ volatile unsigned long acmodidat;
+ volatile unsigned long unused5[15];
+ volatile unsigned long acrevid;
+};
+
+
+struct tx4938_tmr_reg {
+ volatile unsigned long tcr;
+ volatile unsigned long tisr;
+ volatile unsigned long cpra;
+ volatile unsigned long cprb;
+ volatile unsigned long itmr;
+ volatile unsigned long unused0[3];
+ volatile unsigned long ccdr;
+ volatile unsigned long unused1[3];
+ volatile unsigned long pgmr;
+ volatile unsigned long unused2[3];
+ volatile unsigned long wtmr;
+ volatile unsigned long unused3[43];
+ volatile unsigned long trr;
+};
+
+struct tx4938_sio_reg {
+ volatile unsigned long lcr;
+ volatile unsigned long dicr;
+ volatile unsigned long disr;
+ volatile unsigned long cisr;
+ volatile unsigned long fcr;
+ volatile unsigned long flcr;
+ volatile unsigned long bgr;
+ volatile unsigned long tfifo;
+ volatile unsigned long rfifo;
+};
+
+struct tx4938_pio_reg {
+ volatile unsigned long dout;
+ volatile unsigned long din;
+ volatile unsigned long dir;
+ volatile unsigned long od;
+ volatile unsigned long flag[2];
+ volatile unsigned long pol;
+ volatile unsigned long intc;
+ volatile unsigned long maskcpu;
+ volatile unsigned long maskext;
+};
+struct tx4938_irc_reg {
+ volatile unsigned long cer;
+ volatile unsigned long cr[2];
+ volatile unsigned long unused0;
+ volatile unsigned long ilr[8];
+ volatile unsigned long unused1[4];
+ volatile unsigned long imr;
+ volatile unsigned long unused2[7];
+ volatile unsigned long scr;
+ volatile unsigned long unused3[7];
+ volatile unsigned long ssr;
+ volatile unsigned long unused4[7];
+ volatile unsigned long csr;
+};
+
+struct tx4938_ndfmc_reg {
+ endian_def_l2(unused0, dtr);
+ endian_def_l2(unused1, mcr);
+ endian_def_l2(unused2, sr);
+ endian_def_l2(unused3, isr);
+ endian_def_l2(unused4, imr);
+ endian_def_l2(unused5, spr);
+ endian_def_l2(unused6, rstr);
+};
+
+struct tx4938_spi_reg {
+ volatile unsigned long mcr;
+ volatile unsigned long cr0;
+ volatile unsigned long cr1;
+ volatile unsigned long fs;
+ volatile unsigned long unused1;
+ volatile unsigned long sr;
+ volatile unsigned long dr;
+ volatile unsigned long unused2;
+};
+
+struct tx4938_sramc_reg {
+ volatile unsigned long long cr;
+};
+
+struct tx4938_ccfg_reg {
+ volatile unsigned long long ccfg;
+ volatile unsigned long long crir;
+ volatile unsigned long long pcfg;
+ volatile unsigned long long tear;
+ volatile unsigned long long clkctr;
+ volatile unsigned long long unused0;
+ volatile unsigned long long garbc;
+ volatile unsigned long long unused1;
+ volatile unsigned long long unused2;
+ volatile unsigned long long ramp;
+ volatile unsigned long long unused3;
+ volatile unsigned long long jmpadr;
+};
+
+#undef endian_def_l2
+#undef endian_def_s2
+#undef endian_def_sb2
+#undef endian_def_b2s
+#undef endian_def_b4
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * NDFMC
+ */
+
+/* NDFMCR : NDFMC Mode Control */
+#define TX4938_NDFMCR_WE 0x80
+#define TX4938_NDFMCR_ECC_ALL 0x60
+#define TX4938_NDFMCR_ECC_RESET 0x60
+#define TX4938_NDFMCR_ECC_READ 0x40
+#define TX4938_NDFMCR_ECC_ON 0x20
+#define TX4938_NDFMCR_ECC_OFF 0x00
+#define TX4938_NDFMCR_CE 0x10
+#define TX4938_NDFMCR_BSPRT 0x04
+#define TX4938_NDFMCR_ALE 0x02
+#define TX4938_NDFMCR_CLE 0x01
+
+/* NDFMCR : NDFMC Status */
+#define TX4938_NDFSR_BUSY 0x80
+
+/* NDFMCR : NDFMC Reset */
+#define TX4938_NDFRSTR_RST 0x01
+
+/*
+ * IRC
+ */
+
+#define TX4938_IR_ECCERR 0
+#define TX4938_IR_WTOERR 1
+#define TX4938_NUM_IR_INT 6
+#define TX4938_IR_INT(n) (2 + (n))
+#define TX4938_NUM_IR_SIO 2
+#define TX4938_IR_SIO(n) (8 + (n))
+#define TX4938_NUM_IR_DMA 4
+#define TX4938_IR_DMA(ch,n) ((ch ? 27 : 10) + (n)) /* 10-13,27-30 */
+#define TX4938_IR_PIO 14
+#define TX4938_IR_PDMAC 15
+#define TX4938_IR_PCIC 16
+#define TX4938_NUM_IR_TMR 3
+#define TX4938_IR_TMR(n) (17 + (n))
+#define TX4938_IR_NDFMC 21
+#define TX4938_IR_PCIERR 22
+#define TX4938_IR_PCIPME 23
+#define TX4938_IR_ACLC 24
+#define TX4938_IR_ACLCPME 25
+#define TX4938_IR_PCIC1 26
+#define TX4938_IR_SPI 31
+#define TX4938_NUM_IR 32
+/* multiplex */
+#define TX4938_IR_ETH0 TX4938_IR_INT(4)
+#define TX4938_IR_ETH1 TX4938_IR_INT(3)
+
+/*
+ * CCFG
+ */
+/* CCFG : Chip Configuration */
+#define TX4938_CCFG_WDRST _CONST64(0x0000020000000000)
+#define TX4938_CCFG_WDREXEN _CONST64(0x0000010000000000)
+#define TX4938_CCFG_BCFG_MASK _CONST64(0x000000ff00000000)
+#define TX4938_CCFG_TINTDIS 0x01000000
+#define TX4938_CCFG_PCI66 0x00800000
+#define TX4938_CCFG_PCIMODE 0x00400000
+#define TX4938_CCFG_PCI1_66 0x00200000
+#define TX4938_CCFG_DIVMODE_MASK 0x001e0000
+#define TX4938_CCFG_DIVMODE_2 (0x4 << 17)
+#define TX4938_CCFG_DIVMODE_2_5 (0xf << 17)
+#define TX4938_CCFG_DIVMODE_3 (0x5 << 17)
+#define TX4938_CCFG_DIVMODE_4 (0x6 << 17)
+#define TX4938_CCFG_DIVMODE_4_5 (0xd << 17)
+#define TX4938_CCFG_DIVMODE_8 (0x0 << 17)
+#define TX4938_CCFG_DIVMODE_10 (0xb << 17)
+#define TX4938_CCFG_DIVMODE_12 (0x1 << 17)
+#define TX4938_CCFG_DIVMODE_16 (0x2 << 17)
+#define TX4938_CCFG_DIVMODE_18 (0x9 << 17)
+#define TX4938_CCFG_BEOW 0x00010000
+#define TX4938_CCFG_WR 0x00008000
+#define TX4938_CCFG_TOE 0x00004000
+#define TX4938_CCFG_PCIXARB 0x00002000
+#define TX4938_CCFG_PCIDIVMODE_MASK 0x00001c00
+#define TX4938_CCFG_PCIDIVMODE_4 (0x1 << 10)
+#define TX4938_CCFG_PCIDIVMODE_4_5 (0x3 << 10)
+#define TX4938_CCFG_PCIDIVMODE_5 (0x5 << 10)
+#define TX4938_CCFG_PCIDIVMODE_5_5 (0x7 << 10)
+#define TX4938_CCFG_PCIDIVMODE_8 (0x0 << 10)
+#define TX4938_CCFG_PCIDIVMODE_9 (0x2 << 10)
+#define TX4938_CCFG_PCIDIVMODE_10 (0x4 << 10)
+#define TX4938_CCFG_PCIDIVMODE_11 (0x6 << 10)
+#define TX4938_CCFG_PCI1DMD 0x00000100
+#define TX4938_CCFG_SYSSP_MASK 0x000000c0
+#define TX4938_CCFG_ENDIAN 0x00000004
+#define TX4938_CCFG_HALT 0x00000002
+#define TX4938_CCFG_ACEHOLD 0x00000001
+
+/* PCFG : Pin Configuration */
+#define TX4938_PCFG_ETH0_SEL _CONST64(0x8000000000000000)
+#define TX4938_PCFG_ETH1_SEL _CONST64(0x4000000000000000)
+#define TX4938_PCFG_ATA_SEL _CONST64(0x2000000000000000)
+#define TX4938_PCFG_ISA_SEL _CONST64(0x1000000000000000)
+#define TX4938_PCFG_SPI_SEL _CONST64(0x0800000000000000)
+#define TX4938_PCFG_NDF_SEL _CONST64(0x0400000000000000)
+#define TX4938_PCFG_SDCLKDLY_MASK 0x30000000
+#define TX4938_PCFG_SDCLKDLY(d) ((d)<<28)
+#define TX4938_PCFG_SYSCLKEN 0x08000000
+#define TX4938_PCFG_SDCLKEN_ALL 0x07800000
+#define TX4938_PCFG_SDCLKEN(ch) (0x00800000<<(ch))
+#define TX4938_PCFG_PCICLKEN_ALL 0x003f0000
+#define TX4938_PCFG_PCICLKEN(ch) (0x00010000<<(ch))
+#define TX4938_PCFG_SEL2 0x00000200
+#define TX4938_PCFG_SEL1 0x00000100
+#define TX4938_PCFG_DMASEL_ALL 0x0000000f
+#define TX4938_PCFG_DMASEL0_DRQ0 0x00000000
+#define TX4938_PCFG_DMASEL0_SIO1 0x00000001
+#define TX4938_PCFG_DMASEL1_DRQ1 0x00000000
+#define TX4938_PCFG_DMASEL1_SIO1 0x00000002
+#define TX4938_PCFG_DMASEL2_DRQ2 0x00000000
+#define TX4938_PCFG_DMASEL2_SIO0 0x00000004
+#define TX4938_PCFG_DMASEL3_DRQ3 0x00000000
+#define TX4938_PCFG_DMASEL3_SIO0 0x00000008
+
+/* CLKCTR : Clock Control */
+#define TX4938_CLKCTR_NDFCKD _CONST64(0x0001000000000000)
+#define TX4938_CLKCTR_NDFRST _CONST64(0x0000000100000000)
+#define TX4938_CLKCTR_ETH1CKD 0x80000000
+#define TX4938_CLKCTR_ETH0CKD 0x40000000
+#define TX4938_CLKCTR_SPICKD 0x20000000
+#define TX4938_CLKCTR_SRAMCKD 0x10000000
+#define TX4938_CLKCTR_PCIC1CKD 0x08000000
+#define TX4938_CLKCTR_DMA1CKD 0x04000000
+#define TX4938_CLKCTR_ACLCKD 0x02000000
+#define TX4938_CLKCTR_PIOCKD 0x01000000
+#define TX4938_CLKCTR_DMACKD 0x00800000
+#define TX4938_CLKCTR_PCICKD 0x00400000
+#define TX4938_CLKCTR_TM0CKD 0x00100000
+#define TX4938_CLKCTR_TM1CKD 0x00080000
+#define TX4938_CLKCTR_TM2CKD 0x00040000
+#define TX4938_CLKCTR_SIO0CKD 0x00020000
+#define TX4938_CLKCTR_SIO1CKD 0x00010000
+#define TX4938_CLKCTR_ETH1RST 0x00008000
+#define TX4938_CLKCTR_ETH0RST 0x00004000
+#define TX4938_CLKCTR_SPIRST 0x00002000
+#define TX4938_CLKCTR_SRAMRST 0x00001000
+#define TX4938_CLKCTR_PCIC1RST 0x00000800
+#define TX4938_CLKCTR_DMA1RST 0x00000400
+#define TX4938_CLKCTR_ACLRST 0x00000200
+#define TX4938_CLKCTR_PIORST 0x00000100
+#define TX4938_CLKCTR_DMARST 0x00000080
+#define TX4938_CLKCTR_PCIRST 0x00000040
+#define TX4938_CLKCTR_TM0RST 0x00000010
+#define TX4938_CLKCTR_TM1RST 0x00000008
+#define TX4938_CLKCTR_TM2RST 0x00000004
+#define TX4938_CLKCTR_SIO0RST 0x00000002
+#define TX4938_CLKCTR_SIO1RST 0x00000001
+
+/* bits for G2PSTATUS/G2PMASK */
+#define TX4938_PCIC_G2PSTATUS_ALL 0x00000003
+#define TX4938_PCIC_G2PSTATUS_TTOE 0x00000002
+#define TX4938_PCIC_G2PSTATUS_RTOE 0x00000001
+
+/* bits for PCIMASK (see also PCI_STATUS_XXX in linux/pci.h */
+#define TX4938_PCIC_PCISTATUS_ALL 0x0000f900
+
+/* bits for PBACFG */
+#define TX4938_PCIC_PBACFG_FIXPA 0x00000008
+#define TX4938_PCIC_PBACFG_RPBA 0x00000004
+#define TX4938_PCIC_PBACFG_PBAEN 0x00000002
+#define TX4938_PCIC_PBACFG_BMCEN 0x00000001
+
+/* bits for G2PMnGBASE */
+#define TX4938_PCIC_G2PMnGBASE_BSDIS _CONST64(0x0000002000000000)
+#define TX4938_PCIC_G2PMnGBASE_ECHG _CONST64(0x0000001000000000)
+
+/* bits for G2PIOGBASE */
+#define TX4938_PCIC_G2PIOGBASE_BSDIS _CONST64(0x0000002000000000)
+#define TX4938_PCIC_G2PIOGBASE_ECHG _CONST64(0x0000001000000000)
+
+/* bits for PCICSTATUS/PCICMASK */
+#define TX4938_PCIC_PCICSTATUS_ALL 0x000007b8
+#define TX4938_PCIC_PCICSTATUS_PME 0x00000400
+#define TX4938_PCIC_PCICSTATUS_TLB 0x00000200
+#define TX4938_PCIC_PCICSTATUS_NIB 0x00000100
+#define TX4938_PCIC_PCICSTATUS_ZIB 0x00000080
+#define TX4938_PCIC_PCICSTATUS_PERR 0x00000020
+#define TX4938_PCIC_PCICSTATUS_SERR 0x00000010
+#define TX4938_PCIC_PCICSTATUS_GBE 0x00000008
+#define TX4938_PCIC_PCICSTATUS_IWB 0x00000002
+#define TX4938_PCIC_PCICSTATUS_E2PDONE 0x00000001
+
+/* bits for PCICCFG */
+#define TX4938_PCIC_PCICCFG_GBWC_MASK 0x0fff0000
+#define TX4938_PCIC_PCICCFG_HRST 0x00000800
+#define TX4938_PCIC_PCICCFG_SRST 0x00000400
+#define TX4938_PCIC_PCICCFG_IRBER 0x00000200
+#define TX4938_PCIC_PCICCFG_G2PMEN(ch) (0x00000100>>(ch))
+#define TX4938_PCIC_PCICCFG_G2PM0EN 0x00000100
+#define TX4938_PCIC_PCICCFG_G2PM1EN 0x00000080
+#define TX4938_PCIC_PCICCFG_G2PM2EN 0x00000040
+#define TX4938_PCIC_PCICCFG_G2PIOEN 0x00000020
+#define TX4938_PCIC_PCICCFG_TCAR 0x00000010
+#define TX4938_PCIC_PCICCFG_ICAEN 0x00000008
+
+/* bits for P2GMnGBASE */
+#define TX4938_PCIC_P2GMnGBASE_TMEMEN _CONST64(0x0000004000000000)
+#define TX4938_PCIC_P2GMnGBASE_TBSDIS _CONST64(0x0000002000000000)
+#define TX4938_PCIC_P2GMnGBASE_TECHG _CONST64(0x0000001000000000)
+
+/* bits for P2GIOGBASE */
+#define TX4938_PCIC_P2GIOGBASE_TIOEN _CONST64(0x0000004000000000)
+#define TX4938_PCIC_P2GIOGBASE_TBSDIS _CONST64(0x0000002000000000)
+#define TX4938_PCIC_P2GIOGBASE_TECHG _CONST64(0x0000001000000000)
+
+#define TX4938_PCIC_IDSEL_AD_TO_SLOT(ad) ((ad) - 11)
+#define TX4938_PCIC_MAX_DEVNU TX4938_PCIC_IDSEL_AD_TO_SLOT(32)
+
+/* bits for PDMCFG */
+#define TX4938_PCIC_PDMCFG_RSTFIFO 0x00200000
+#define TX4938_PCIC_PDMCFG_EXFER 0x00100000
+#define TX4938_PCIC_PDMCFG_REQDLY_MASK 0x00003800
+#define TX4938_PCIC_PDMCFG_REQDLY_NONE (0 << 11)
+#define TX4938_PCIC_PDMCFG_REQDLY_16 (1 << 11)
+#define TX4938_PCIC_PDMCFG_REQDLY_32 (2 << 11)
+#define TX4938_PCIC_PDMCFG_REQDLY_64 (3 << 11)
+#define TX4938_PCIC_PDMCFG_REQDLY_128 (4 << 11)
+#define TX4938_PCIC_PDMCFG_REQDLY_256 (5 << 11)
+#define TX4938_PCIC_PDMCFG_REQDLY_512 (6 << 11)
+#define TX4938_PCIC_PDMCFG_REQDLY_1024 (7 << 11)
+#define TX4938_PCIC_PDMCFG_ERRIE 0x00000400
+#define TX4938_PCIC_PDMCFG_NCCMPIE 0x00000200
+#define TX4938_PCIC_PDMCFG_NTCMPIE 0x00000100
+#define TX4938_PCIC_PDMCFG_CHNEN 0x00000080
+#define TX4938_PCIC_PDMCFG_XFRACT 0x00000040
+#define TX4938_PCIC_PDMCFG_BSWAP 0x00000020
+#define TX4938_PCIC_PDMCFG_XFRSIZE_MASK 0x0000000c
+#define TX4938_PCIC_PDMCFG_XFRSIZE_1DW 0x00000000
+#define TX4938_PCIC_PDMCFG_XFRSIZE_1QW 0x00000004
+#define TX4938_PCIC_PDMCFG_XFRSIZE_4QW 0x00000008
+#define TX4938_PCIC_PDMCFG_XFRDIRC 0x00000002
+#define TX4938_PCIC_PDMCFG_CHRST 0x00000001
+
+/* bits for PDMSTS */
+#define TX4938_PCIC_PDMSTS_REQCNT_MASK 0x3f000000
+#define TX4938_PCIC_PDMSTS_FIFOCNT_MASK 0x00f00000
+#define TX4938_PCIC_PDMSTS_FIFOWP_MASK 0x000c0000
+#define TX4938_PCIC_PDMSTS_FIFORP_MASK 0x00030000
+#define TX4938_PCIC_PDMSTS_ERRINT 0x00000800
+#define TX4938_PCIC_PDMSTS_DONEINT 0x00000400
+#define TX4938_PCIC_PDMSTS_CHNEN 0x00000200
+#define TX4938_PCIC_PDMSTS_XFRACT 0x00000100
+#define TX4938_PCIC_PDMSTS_ACCMP 0x00000080
+#define TX4938_PCIC_PDMSTS_NCCMP 0x00000040
+#define TX4938_PCIC_PDMSTS_NTCMP 0x00000020
+#define TX4938_PCIC_PDMSTS_CFGERR 0x00000008
+#define TX4938_PCIC_PDMSTS_PCIERR 0x00000004
+#define TX4938_PCIC_PDMSTS_CHNERR 0x00000002
+#define TX4938_PCIC_PDMSTS_DATAERR 0x00000001
+#define TX4938_PCIC_PDMSTS_ALL_CMP 0x000000e0
+#define TX4938_PCIC_PDMSTS_ALL_ERR 0x0000000f
+
+/*
+ * DMA
+ */
+/* bits for MCR */
+#define TX4938_DMA_MCR_EIS(ch) (0x10000000<<(ch))
+#define TX4938_DMA_MCR_DIS(ch) (0x01000000<<(ch))
+#define TX4938_DMA_MCR_RSFIF 0x00000080
+#define TX4938_DMA_MCR_FIFUM(ch) (0x00000008<<(ch))
+#define TX4938_DMA_MCR_RPRT 0x00000002
+#define TX4938_DMA_MCR_MSTEN 0x00000001
+
+/* bits for CCRn */
+#define TX4938_DMA_CCR_IMMCHN 0x20000000
+#define TX4938_DMA_CCR_USEXFSZ 0x10000000
+#define TX4938_DMA_CCR_LE 0x08000000
+#define TX4938_DMA_CCR_DBINH 0x04000000
+#define TX4938_DMA_CCR_SBINH 0x02000000
+#define TX4938_DMA_CCR_CHRST 0x01000000
+#define TX4938_DMA_CCR_RVBYTE 0x00800000
+#define TX4938_DMA_CCR_ACKPOL 0x00400000
+#define TX4938_DMA_CCR_REQPL 0x00200000
+#define TX4938_DMA_CCR_EGREQ 0x00100000
+#define TX4938_DMA_CCR_CHDN 0x00080000
+#define TX4938_DMA_CCR_DNCTL 0x00060000
+#define TX4938_DMA_CCR_EXTRQ 0x00010000
+#define TX4938_DMA_CCR_INTRQD 0x0000e000
+#define TX4938_DMA_CCR_INTENE 0x00001000
+#define TX4938_DMA_CCR_INTENC 0x00000800
+#define TX4938_DMA_CCR_INTENT 0x00000400
+#define TX4938_DMA_CCR_CHNEN 0x00000200
+#define TX4938_DMA_CCR_XFACT 0x00000100
+#define TX4938_DMA_CCR_SMPCHN 0x00000020
+#define TX4938_DMA_CCR_XFSZ(order) (((order) << 2) & 0x0000001c)
+#define TX4938_DMA_CCR_XFSZ_1W TX4938_DMA_CCR_XFSZ(2)
+#define TX4938_DMA_CCR_XFSZ_2W TX4938_DMA_CCR_XFSZ(3)
+#define TX4938_DMA_CCR_XFSZ_4W TX4938_DMA_CCR_XFSZ(4)
+#define TX4938_DMA_CCR_XFSZ_8W TX4938_DMA_CCR_XFSZ(5)
+#define TX4938_DMA_CCR_XFSZ_16W TX4938_DMA_CCR_XFSZ(6)
+#define TX4938_DMA_CCR_XFSZ_32W TX4938_DMA_CCR_XFSZ(7)
+#define TX4938_DMA_CCR_MEMIO 0x00000002
+#define TX4938_DMA_CCR_SNGAD 0x00000001
+
+/* bits for CSRn */
+#define TX4938_DMA_CSR_CHNEN 0x00000400
+#define TX4938_DMA_CSR_STLXFER 0x00000200
+#define TX4938_DMA_CSR_CHNACT 0x00000100
+#define TX4938_DMA_CSR_ABCHC 0x00000080
+#define TX4938_DMA_CSR_NCHNC 0x00000040
+#define TX4938_DMA_CSR_NTRNFC 0x00000020
+#define TX4938_DMA_CSR_EXTDN 0x00000010
+#define TX4938_DMA_CSR_CFERR 0x00000008
+#define TX4938_DMA_CSR_CHERR 0x00000004
+#define TX4938_DMA_CSR_DESERR 0x00000002
+#define TX4938_DMA_CSR_SORERR 0x00000001
+
+/* TX4938 Interrupt Controller (32-bit registers) */
+#define TX4938_IRC_BASE 0xf510
+#define TX4938_IRC_IRFLAG0 0xf510
+#define TX4938_IRC_IRFLAG1 0xf514
+#define TX4938_IRC_IRPOL 0xf518
+#define TX4938_IRC_IRRCNT 0xf51c
+#define TX4938_IRC_IRMASKINT 0xf520
+#define TX4938_IRC_IRMASKEXT 0xf524
+#define TX4938_IRC_IRDEN 0xf600
+#define TX4938_IRC_IRDM0 0xf604
+#define TX4938_IRC_IRDM1 0xf608
+#define TX4938_IRC_IRLVL0 0xf610
+#define TX4938_IRC_IRLVL1 0xf614
+#define TX4938_IRC_IRLVL2 0xf618
+#define TX4938_IRC_IRLVL3 0xf61c
+#define TX4938_IRC_IRLVL4 0xf620
+#define TX4938_IRC_IRLVL5 0xf624
+#define TX4938_IRC_IRLVL6 0xf628
+#define TX4938_IRC_IRLVL7 0xf62c
+#define TX4938_IRC_IRMSK 0xf640
+#define TX4938_IRC_IREDC 0xf660
+#define TX4938_IRC_IRPND 0xf680
+#define TX4938_IRC_IRCS 0xf6a0
+#define TX4938_IRC_LIMIT 0xf6ff
+
+
+#ifndef __ASSEMBLY__
+
+#define tx4938_sdramcptr ((struct tx4938_sdramc_reg *)TX4938_SDRAMC_REG)
+#define tx4938_ebuscptr ((struct tx4938_ebusc_reg *)TX4938_EBUSC_REG)
+#define tx4938_dmaptr(ch) ((struct tx4938_dma_reg *)TX4938_DMA_REG(ch))
+#define tx4938_ndfmcptr ((struct tx4938_ndfmc_reg *)TX4938_NDFMC_REG)
+#define tx4938_ircptr ((struct tx4938_irc_reg *)TX4938_IRC_REG)
+#define tx4938_pcicptr ((struct tx4938_pcic_reg *)TX4938_PCIC_REG)
+#define tx4938_pcic1ptr ((struct tx4938_pcic_reg *)TX4938_PCIC1_REG)
+#define tx4938_ccfgptr ((struct tx4938_ccfg_reg *)TX4938_CCFG_REG)
+#define tx4938_tmrptr(ch) ((struct tx4938_tmr_reg *)TX4938_TMR_REG(ch))
+#define tx4938_sioptr(ch) ((struct tx4938_sio_reg *)TX4938_SIO_REG(ch))
+#define tx4938_pioptr ((struct tx4938_pio_reg *)TX4938_PIO_REG)
+#define tx4938_aclcptr ((struct tx4938_aclc_reg *)TX4938_ACLC_REG)
+#define tx4938_spiptr ((struct tx4938_spi_reg *)TX4938_SPI_REG)
+#define tx4938_sramcptr ((struct tx4938_sramc_reg *)TX4938_SRAMC_REG)
+
+
+#define TX4938_REV_MAJ_MIN() ((unsigned long)tx4938_ccfgptr->crir & 0x00ff)
+#define TX4938_REV_PCODE() ((unsigned long)tx4938_ccfgptr->crir >> 16)
+
+#define TX4938_SDRAMC_BA(ch) ((tx4938_sdramcptr->cr[ch] >> 49) << 21)
+#define TX4938_SDRAMC_SIZE(ch) (((tx4938_sdramcptr->cr[ch] >> 33) + 1) << 21)
+
+#define TX4938_EBUSC_BA(ch) ((tx4938_ebuscptr->cr[ch] >> 48) << 20)
+#define TX4938_EBUSC_SIZE(ch) \
+ (0x00100000 << ((unsigned long)(tx4938_ebuscptr->cr[ch] >> 8) & 0xf))
+
+
+#endif /* !__ASSEMBLY__ */
+
+#endif
diff --git a/include/asm-mips/tx4938/tx4938_mips.h b/include/asm-mips/tx4938/tx4938_mips.h
new file mode 100644
index 000000000000..cf89b205f103
--- /dev/null
+++ b/include/asm-mips/tx4938/tx4938_mips.h
@@ -0,0 +1,54 @@
+/*
+ * linux/include/asm-mips/tx4938/tx4938_bitmask.h
+ * Generic bitmask definitions
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+
+#ifndef TX4938_TX4938_MIPS_H
+#define TX4938_TX4938_MIPS_H
+#ifndef __ASSEMBLY__
+
+#define reg_rd08(r) ((u8 )(*((vu8 *)(r))))
+#define reg_rd16(r) ((u16)(*((vu16*)(r))))
+#define reg_rd32(r) ((u32)(*((vu32*)(r))))
+#define reg_rd64(r) ((u64)(*((vu64*)(r))))
+
+#define reg_wr08(r,v) ((*((vu8 *)(r)))=((u8 )(v)))
+#define reg_wr16(r,v) ((*((vu16*)(r)))=((u16)(v)))
+#define reg_wr32(r,v) ((*((vu32*)(r)))=((u32)(v)))
+#define reg_wr64(r,v) ((*((vu64*)(r)))=((u64)(v)))
+
+typedef volatile __signed char vs8;
+typedef volatile unsigned char vu8;
+
+typedef volatile __signed short vs16;
+typedef volatile unsigned short vu16;
+
+typedef volatile __signed int vs32;
+typedef volatile unsigned int vu32;
+
+typedef s8 s08;
+typedef vs8 vs08;
+
+typedef u8 u08;
+typedef vu8 vu08;
+
+#if (_MIPS_SZLONG == 64)
+
+typedef volatile __signed__ long vs64;
+typedef volatile unsigned long vu64;
+
+#else
+
+typedef volatile __signed__ long long vs64;
+typedef volatile unsigned long long vu64;
+
+#endif
+#endif
+#endif
diff --git a/include/asm-mips/uaccess.h b/include/asm-mips/uaccess.h
index 5c2c98329012..41bb96bb2120 100644
--- a/include/asm-mips/uaccess.h
+++ b/include/asm-mips/uaccess.h
@@ -196,63 +196,55 @@
__get_user_nocheck((x),(ptr),sizeof(*(ptr)))
struct __large_struct { unsigned long buf[100]; };
-#define __m(x) (*(struct __large_struct *)(x))
+#define __m(x) (*(struct __large_struct __user *)(x))
/*
* Yuck. We need two variants, one for 64bit operation and one
* for 32 bit mode and old iron.
*/
#ifdef __mips64
-#define __GET_USER_DW(__gu_err) __get_user_asm("ld", __gu_err)
+#define __GET_USER_DW(ptr) __get_user_asm("ld", ptr)
#else
-#define __GET_USER_DW(__gu_err) __get_user_asm_ll32(__gu_err)
+#define __GET_USER_DW(ptr) __get_user_asm_ll32(ptr)
#endif
#define __get_user_nocheck(x,ptr,size) \
({ \
- __typeof(*(ptr)) __gu_val = 0; \
- long __gu_addr; \
+ __typeof(*(ptr)) __gu_val = (__typeof(*(ptr))) 0; \
long __gu_err = 0; \
\
- might_sleep(); \
- __gu_addr = (long) (ptr); \
switch (size) { \
- case 1: __get_user_asm("lb", __gu_err); break; \
- case 2: __get_user_asm("lh", __gu_err); break; \
- case 4: __get_user_asm("lw", __gu_err); break; \
- case 8: __GET_USER_DW(__gu_err); break; \
+ case 1: __get_user_asm("lb", ptr); break; \
+ case 2: __get_user_asm("lh", ptr); break; \
+ case 4: __get_user_asm("lw", ptr); break; \
+ case 8: __GET_USER_DW(ptr); break; \
default: __get_user_unknown(); break; \
} \
- x = (__typeof__(*(ptr))) __gu_val; \
+ (x) = (__typeof__(*(ptr))) __gu_val; \
__gu_err; \
})
#define __get_user_check(x,ptr,size) \
({ \
+ const __typeof__(*(ptr)) __user * __gu_addr = (ptr); \
__typeof__(*(ptr)) __gu_val = 0; \
- long __gu_addr; \
- long __gu_err; \
- \
- might_sleep(); \
- __gu_addr = (long) (ptr); \
- __gu_err = access_ok(VERIFY_READ, (void *) __gu_addr, size) \
- ? 0 : -EFAULT; \
+ long __gu_err = -EFAULT; \
\
- if (likely(!__gu_err)) { \
+ if (likely(access_ok(VERIFY_READ, __gu_addr, size))) { \
switch (size) { \
- case 1: __get_user_asm("lb", __gu_err); break; \
- case 2: __get_user_asm("lh", __gu_err); break; \
- case 4: __get_user_asm("lw", __gu_err); break; \
- case 8: __GET_USER_DW(__gu_err); break; \
+ case 1: __get_user_asm("lb", __gu_addr); break; \
+ case 2: __get_user_asm("lh", __gu_addr); break; \
+ case 4: __get_user_asm("lw", __gu_addr); break; \
+ case 8: __GET_USER_DW(__gu_addr); break; \
default: __get_user_unknown(); break; \
} \
} \
- x = (__typeof__(*(ptr))) __gu_val; \
+ (x) = (__typeof__(*(ptr))) __gu_val; \
__gu_err; \
})
-#define __get_user_asm(insn,__gu_err) \
-({ \
+#define __get_user_asm(insn, addr) \
+{ \
__asm__ __volatile__( \
"1: " insn " %1, %3 \n" \
"2: \n" \
@@ -264,20 +256,20 @@ struct __large_struct { unsigned long buf[100]; };
" "__UA_ADDR "\t1b, 3b \n" \
" .previous \n" \
: "=r" (__gu_err), "=r" (__gu_val) \
- : "0" (__gu_err), "o" (__m(__gu_addr)), "i" (-EFAULT)); \
-})
+ : "0" (0), "o" (__m(addr)), "i" (-EFAULT)); \
+}
/*
* Get a long long 64 using 32 bit registers.
*/
-#define __get_user_asm_ll32(__gu_err) \
-({ \
+#define __get_user_asm_ll32(addr) \
+{ \
__asm__ __volatile__( \
- "1: lw %1, %3 \n" \
- "2: lw %D1, %4 \n" \
+ "1: lw %1, (%3) \n" \
+ "2: lw %D1, 4(%3) \n" \
" move %0, $0 \n" \
"3: .section .fixup,\"ax\" \n" \
- "4: li %0, %5 \n" \
+ "4: li %0, %4 \n" \
" move %1, $0 \n" \
" move %D1, $0 \n" \
" j 3b \n" \
@@ -287,9 +279,8 @@ struct __large_struct { unsigned long buf[100]; };
" " __UA_ADDR " 2b, 4b \n" \
" .previous \n" \
: "=r" (__gu_err), "=&r" (__gu_val) \
- : "0" (__gu_err), "o" (__m(__gu_addr)), \
- "o" (__m(__gu_addr + 4)), "i" (-EFAULT)); \
-})
+ : "0" (0), "r" (addr), "i" (-EFAULT)); \
+}
extern void __get_user_unknown(void);
@@ -298,25 +289,22 @@ extern void __get_user_unknown(void);
* for 32 bit mode and old iron.
*/
#ifdef __mips64
-#define __PUT_USER_DW(__pu_val) __put_user_asm("sd", __pu_val)
+#define __PUT_USER_DW(ptr) __put_user_asm("sd", ptr)
#else
-#define __PUT_USER_DW(__pu_val) __put_user_asm_ll32(__pu_val)
+#define __PUT_USER_DW(ptr) __put_user_asm_ll32(ptr)
#endif
#define __put_user_nocheck(x,ptr,size) \
({ \
__typeof__(*(ptr)) __pu_val; \
- long __pu_addr; \
long __pu_err = 0; \
\
- might_sleep(); \
__pu_val = (x); \
- __pu_addr = (long) (ptr); \
switch (size) { \
- case 1: __put_user_asm("sb", __pu_val); break; \
- case 2: __put_user_asm("sh", __pu_val); break; \
- case 4: __put_user_asm("sw", __pu_val); break; \
- case 8: __PUT_USER_DW(__pu_val); break; \
+ case 1: __put_user_asm("sb", ptr); break; \
+ case 2: __put_user_asm("sh", ptr); break; \
+ case 4: __put_user_asm("sw", ptr); break; \
+ case 8: __PUT_USER_DW(ptr); break; \
default: __put_user_unknown(); break; \
} \
__pu_err; \
@@ -324,30 +312,24 @@ extern void __get_user_unknown(void);
#define __put_user_check(x,ptr,size) \
({ \
- __typeof__(*(ptr)) __pu_val; \
- long __pu_addr; \
- long __pu_err; \
+ __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
+ __typeof__(*(ptr)) __pu_val = (x); \
+ long __pu_err = -EFAULT; \
\
- might_sleep(); \
- __pu_val = (x); \
- __pu_addr = (long) (ptr); \
- __pu_err = access_ok(VERIFY_WRITE, (void *) __pu_addr, size) \
- ? 0 : -EFAULT; \
- \
- if (likely(!__pu_err)) { \
+ if (likely(access_ok(VERIFY_WRITE, __pu_addr, size))) { \
switch (size) { \
- case 1: __put_user_asm("sb", __pu_val); break; \
- case 2: __put_user_asm("sh", __pu_val); break; \
- case 4: __put_user_asm("sw", __pu_val); break; \
- case 8: __PUT_USER_DW(__pu_val); break; \
+ case 1: __put_user_asm("sb", __pu_addr); break; \
+ case 2: __put_user_asm("sh", __pu_addr); break; \
+ case 4: __put_user_asm("sw", __pu_addr); break; \
+ case 8: __PUT_USER_DW(__pu_addr); break; \
default: __put_user_unknown(); break; \
} \
} \
__pu_err; \
})
-#define __put_user_asm(insn, __pu_val) \
-({ \
+#define __put_user_asm(insn, ptr) \
+{ \
__asm__ __volatile__( \
"1: " insn " %z2, %3 # __put_user_asm\n" \
"2: \n" \
@@ -359,18 +341,18 @@ extern void __get_user_unknown(void);
" " __UA_ADDR " 1b, 3b \n" \
" .previous \n" \
: "=r" (__pu_err) \
- : "0" (__pu_err), "Jr" (__pu_val), "o" (__m(__pu_addr)), \
+ : "0" (0), "Jr" (__pu_val), "o" (__m(ptr)), \
"i" (-EFAULT)); \
-})
+}
-#define __put_user_asm_ll32(__pu_val) \
-({ \
+#define __put_user_asm_ll32(ptr) \
+{ \
__asm__ __volatile__( \
- "1: sw %2, %3 # __put_user_asm_ll32 \n" \
- "2: sw %D2, %4 \n" \
+ "1: sw %2, (%3) # __put_user_asm_ll32 \n" \
+ "2: sw %D2, 4(%3) \n" \
"3: \n" \
" .section .fixup,\"ax\" \n" \
- "4: li %0, %5 \n" \
+ "4: li %0, %4 \n" \
" j 3b \n" \
" .previous \n" \
" .section __ex_table,\"a\" \n" \
@@ -378,9 +360,9 @@ extern void __get_user_unknown(void);
" " __UA_ADDR " 2b, 4b \n" \
" .previous" \
: "=r" (__pu_err) \
- : "0" (__pu_err), "r" (__pu_val), "o" (__m(__pu_addr)), \
- "o" (__m(__pu_addr + 4)), "i" (-EFAULT)); \
-})
+ : "0" (0), "r" (__pu_val), "r" (ptr), \
+ "i" (-EFAULT)); \
+}
extern void __put_user_unknown(void);
@@ -403,7 +385,7 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n);
#define __invoke_copy_to_user(to,from,n) \
({ \
- register void *__cu_to_r __asm__ ("$4"); \
+ register void __user *__cu_to_r __asm__ ("$4"); \
register const void *__cu_from_r __asm__ ("$5"); \
register long __cu_len_r __asm__ ("$6"); \
\
@@ -435,7 +417,7 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n);
*/
#define __copy_to_user(to,from,n) \
({ \
- void *__cu_to; \
+ void __user *__cu_to; \
const void *__cu_from; \
long __cu_len; \
\
@@ -465,7 +447,7 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n);
*/
#define copy_to_user(to,from,n) \
({ \
- void *__cu_to; \
+ void __user *__cu_to; \
const void *__cu_from; \
long __cu_len; \
\
@@ -482,7 +464,7 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n);
#define __invoke_copy_from_user(to,from,n) \
({ \
register void *__cu_to_r __asm__ ("$4"); \
- register const void *__cu_from_r __asm__ ("$5"); \
+ register const void __user *__cu_from_r __asm__ ("$5"); \
register long __cu_len_r __asm__ ("$6"); \
\
__cu_to_r = (to); \
@@ -521,7 +503,7 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n);
#define __copy_from_user(to,from,n) \
({ \
void *__cu_to; \
- const void *__cu_from; \
+ const void __user *__cu_from; \
long __cu_len; \
\
might_sleep(); \
@@ -552,7 +534,7 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n);
#define copy_from_user(to,from,n) \
({ \
void *__cu_to; \
- const void *__cu_from; \
+ const void __user *__cu_from; \
long __cu_len; \
\
might_sleep(); \
@@ -569,8 +551,8 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n);
#define copy_in_user(to,from,n) \
({ \
- void *__cu_to; \
- const void *__cu_from; \
+ void __user *__cu_to; \
+ const void __user *__cu_from; \
long __cu_len; \
\
might_sleep(); \
@@ -596,7 +578,7 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n);
* On success, this will be zero.
*/
static inline __kernel_size_t
-__clear_user(void *addr, __kernel_size_t size)
+__clear_user(void __user *addr, __kernel_size_t size)
{
__kernel_size_t res;
@@ -616,7 +598,7 @@ __clear_user(void *addr, __kernel_size_t size)
#define clear_user(addr,n) \
({ \
- void * __cl_addr = (addr); \
+ void __user * __cl_addr = (addr); \
unsigned long __cl_size = (n); \
if (__cl_size && access_ok(VERIFY_WRITE, \
((unsigned long)(__cl_addr)), __cl_size)) \
@@ -645,7 +627,7 @@ __clear_user(void *addr, __kernel_size_t size)
* and returns @count.
*/
static inline long
-__strncpy_from_user(char *__to, const char *__from, long __len)
+__strncpy_from_user(char *__to, const char __user *__from, long __len)
{
long res;
@@ -682,7 +664,7 @@ __strncpy_from_user(char *__to, const char *__from, long __len)
* and returns @count.
*/
static inline long
-strncpy_from_user(char *__to, const char *__from, long __len)
+strncpy_from_user(char *__to, const char __user *__from, long __len)
{
long res;
@@ -701,7 +683,7 @@ strncpy_from_user(char *__to, const char *__from, long __len)
}
/* Returns: 0 if bad, string length+1 (memory size) of string if ok */
-static inline long __strlen_user(const char *s)
+static inline long __strlen_user(const char __user *s)
{
long res;
@@ -731,7 +713,7 @@ static inline long __strlen_user(const char *s)
* If there is a limit on the length of a valid string, you may wish to
* consider using strnlen_user() instead.
*/
-static inline long strlen_user(const char *s)
+static inline long strlen_user(const char __user *s)
{
long res;
@@ -748,7 +730,7 @@ static inline long strlen_user(const char *s)
}
/* Returns: 0 if bad, string length+1 (memory size) of string if ok */
-static inline long __strnlen_user(const char *s, long n)
+static inline long __strnlen_user(const char __user *s, long n)
{
long res;
@@ -779,7 +761,7 @@ static inline long __strnlen_user(const char *s, long n)
* If there is a limit on the length of a valid string, you may wish to
* consider using strnlen_user() instead.
*/
-static inline long strnlen_user(const char *s, long n)
+static inline long strnlen_user(const char __user *s, long n)
{
long res;
diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h
index ad4d48056307..89ea8b60e945 100644
--- a/include/asm-mips/unistd.h
+++ b/include/asm-mips/unistd.h
@@ -303,16 +303,21 @@
#define __NR_add_key (__NR_Linux + 280)
#define __NR_request_key (__NR_Linux + 281)
#define __NR_keyctl (__NR_Linux + 282)
+#define __NR_set_thread_area (__NR_Linux + 283)
+#define __NR_inotify_init (__NR_Linux + 284)
+#define __NR_inotify_add_watch (__NR_Linux + 285)
+#define __NR_inotify_rm_watch (__NR_Linux + 286)
+
/*
* Offset of the last Linux o32 flavoured syscall
*/
-#define __NR_Linux_syscalls 282
+#define __NR_Linux_syscalls 286
#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
#define __NR_O32_Linux 4000
-#define __NR_O32_Linux_syscalls 282
+#define __NR_O32_Linux_syscalls 283
#if _MIPS_SIM == _MIPS_SIM_ABI64
@@ -562,16 +567,20 @@
#define __NR_add_key (__NR_Linux + 239)
#define __NR_request_key (__NR_Linux + 240)
#define __NR_keyctl (__NR_Linux + 241)
+#define __NR_set_thread_area (__NR_Linux + 242)
+#define __NR_inotify_init (__NR_Linux + 243)
+#define __NR_inotify_add_watch (__NR_Linux + 244)
+#define __NR_inotify_rm_watch (__NR_Linux + 245)
/*
* Offset of the last Linux 64-bit flavoured syscall
*/
-#define __NR_Linux_syscalls 241
+#define __NR_Linux_syscalls 245
#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
#define __NR_64_Linux 5000
-#define __NR_64_Linux_syscalls 241
+#define __NR_64_Linux_syscalls 242
#if _MIPS_SIM == _MIPS_SIM_NABI32
@@ -825,16 +834,20 @@
#define __NR_add_key (__NR_Linux + 243)
#define __NR_request_key (__NR_Linux + 244)
#define __NR_keyctl (__NR_Linux + 245)
+#define __NR_set_thread_area (__NR_Linux + 246)
+#define __NR_inotify_init (__NR_Linux + 247)
+#define __NR_inotify_add_watch (__NR_Linux + 248)
+#define __NR_inotify_rm_watch (__NR_Linux + 249)
/*
* Offset of the last N32 flavoured syscall
*/
-#define __NR_Linux_syscalls 245
+#define __NR_Linux_syscalls 249
#endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
#define __NR_N32_Linux 6000
-#define __NR_N32_Linux_syscalls 245
+#define __NR_N32_Linux_syscalls 246
#ifndef __ASSEMBLY__
@@ -1164,7 +1177,6 @@ asmlinkage long sys_mmap2(
unsigned long fd, unsigned long pgoff);
asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs);
asmlinkage int sys_pipe(nabi_no_regargs struct pt_regs regs);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
diff --git a/include/asm-mips/vga.h b/include/asm-mips/vga.h
index 6b35cf054c79..ca5cec97e167 100644
--- a/include/asm-mips/vga.h
+++ b/include/asm-mips/vga.h
@@ -6,6 +6,8 @@
#ifndef _ASM_VGA_H
#define _ASM_VGA_H
+#include <asm/byteorder.h>
+
/*
* On the PC, we can just recalculate addresses and then
* access the videoram directly without any black magic.
@@ -16,4 +18,27 @@
#define vga_readb(x) (*(x))
#define vga_writeb(x,y) (*(y) = (x))
+#define VT_BUF_HAVE_RW
+/*
+ * These are only needed for supporting VGA or MDA text mode, which use little
+ * endian byte ordering.
+ * In other cases, we can optimize by using native byte ordering and
+ * <linux/vt_buffer.h> has already done the right job for us.
+ */
+
+static inline void scr_writew(u16 val, volatile u16 *addr)
+{
+ *addr = cpu_to_le16(val);
+}
+
+static inline u16 scr_readw(volatile const u16 *addr)
+{
+ return le16_to_cpu(*addr);
+}
+
+#define scr_memcpyw(d, s, c) memcpy(d, s, c)
+#define scr_memmovew(d, s, c) memmove(d, s, c)
+#define VT_BUF_HAVE_MEMCPYW
+#define VT_BUF_HAVE_MEMMOVEW
+
#endif /* _ASM_VGA_H */
diff --git a/include/asm-mips/war.h b/include/asm-mips/war.h
index 04ee53b34c2e..ad374bd3f130 100644
--- a/include/asm-mips/war.h
+++ b/include/asm-mips/war.h
@@ -177,6 +177,17 @@
#endif
/*
+ * The RM9000 has a bug (though PMC-Sierra opposes it being called that)
+ * where invalid instructions in the same I-cache line worth of instructions
+ * being fetched may case spurious exceptions.
+ */
+#if defined(CONFIG_MOMENCO_JAGUAR_ATX) || defined(CONFIG_MOMENCO_OCELOT_3) || \
+ defined(CONFIG_PMC_YOSEMITE)
+#define ICACHE_REFILLS_WORKAROUND_WAR 1
+#endif
+
+
+/*
* ON the R10000 upto version 2.6 (not sure about 2.7) there is a bug that
* may cause ll / sc and lld / scd sequences to execute non-atomically.
*/
@@ -187,6 +198,9 @@
/*
* Workarounds default to off
*/
+#ifndef ICACHE_REFILLS_WORKAROUND_WAR
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#endif
#ifndef R4600_V1_INDEX_ICACHEOP_WAR
#define R4600_V1_INDEX_ICACHEOP_WAR 0
#endif
diff --git a/include/asm-parisc/cacheflush.h b/include/asm-parisc/cacheflush.h
index aa592d8c0e39..1bc3c83ee74b 100644
--- a/include/asm-parisc/cacheflush.h
+++ b/include/asm-parisc/cacheflush.h
@@ -100,30 +100,34 @@ static inline void flush_cache_range(struct vm_area_struct *vma,
/* Simple function to work out if we have an existing address translation
* for a user space vma. */
-static inline pte_t *__translation_exists(struct mm_struct *mm,
- unsigned long addr)
+static inline int translation_exists(struct vm_area_struct *vma,
+ unsigned long addr, unsigned long pfn)
{
- pgd_t *pgd = pgd_offset(mm, addr);
+ pgd_t *pgd = pgd_offset(vma->vm_mm, addr);
pmd_t *pmd;
- pte_t *pte;
+ pte_t pte;
if(pgd_none(*pgd))
- return NULL;
+ return 0;
pmd = pmd_offset(pgd, addr);
if(pmd_none(*pmd) || pmd_bad(*pmd))
- return NULL;
+ return 0;
- pte = pte_offset_map(pmd, addr);
+ /* We cannot take the pte lock here: flush_cache_page is usually
+ * called with pte lock already held. Whereas flush_dcache_page
+ * takes flush_dcache_mmap_lock, which is lower in the hierarchy:
+ * the vma itself is secure, but the pte might come or go racily.
+ */
+ pte = *pte_offset_map(pmd, addr);
+ /* But pte_unmap() does nothing on this architecture */
- /* The PA flush mappings show up as pte_none, but they're
- * valid none the less */
- if(pte_none(*pte) && ((pte_val(*pte) & _PAGE_FLUSH) == 0))
- return NULL;
- return pte;
-}
-#define translation_exists(vma, addr) __translation_exists((vma)->vm_mm, addr)
+ /* Filter out coincidental file entries and swap entries */
+ if (!(pte_val(pte) & (_PAGE_FLUSH|_PAGE_PRESENT)))
+ return 0;
+ return pte_pfn(pte) == pfn;
+}
/* Private function to flush a page from the cache of a non-current
* process. cr25 contains the Page Directory of the current user
@@ -175,9 +179,8 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long
{
BUG_ON(!vma->vm_mm->context);
- if(likely(translation_exists(vma, vmaddr)))
+ if (likely(translation_exists(vma, vmaddr, pfn)))
__flush_cache_page(vma, vmaddr);
}
#endif
-
diff --git a/include/asm-parisc/ide.h b/include/asm-parisc/ide.h
index 3243cf2cd227..b27bf7aeb256 100644
--- a/include/asm-parisc/ide.h
+++ b/include/asm-parisc/ide.h
@@ -22,7 +22,6 @@
#define ide_request_irq(irq,hand,flg,dev,id) request_irq((irq),(hand),(flg),(dev),(id))
#define ide_free_irq(irq,dev_id) free_irq((irq), (dev_id))
-#define ide_check_region(from,extent) check_region((from), (extent))
#define ide_request_region(from,extent,name) request_region((from), (extent), (name))
#define ide_release_region(from,extent) release_region((from), (extent))
/* Generic I/O and MEMIO string operations. */
diff --git a/include/asm-parisc/mmzone.h b/include/asm-parisc/mmzone.h
index 595d3dce120a..ae039f4fd711 100644
--- a/include/asm-parisc/mmzone.h
+++ b/include/asm-parisc/mmzone.h
@@ -27,12 +27,6 @@ extern struct node_map_data node_data[];
})
#define node_localnr(pfn, nid) ((pfn) - node_start_pfn(nid))
-#define local_mapnr(kvaddr) \
-({ \
- unsigned long __pfn = __pa(kvaddr) >> PAGE_SHIFT; \
- (__pfn - node_start_pfn(pfn_to_nid(__pfn))); \
-})
-
#define pfn_to_page(pfn) \
({ \
unsigned long __pfn = (pfn); \
diff --git a/include/asm-parisc/semaphore.h b/include/asm-parisc/semaphore.h
index f78bb2e34538..c9ee41cd0707 100644
--- a/include/asm-parisc/semaphore.h
+++ b/include/asm-parisc/semaphore.h
@@ -49,9 +49,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/asm-parisc/tlbflush.h b/include/asm-parisc/tlbflush.h
index 84af4ab1fe51..e97aa8d1eff5 100644
--- a/include/asm-parisc/tlbflush.h
+++ b/include/asm-parisc/tlbflush.h
@@ -88,7 +88,7 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,
if (npages >= 512) /* 2MB of space: arbitrary, should be tuned */
flush_tlb_all();
else {
-
+ preempt_disable();
mtsp(vma->vm_mm->context,1);
purge_tlb_start();
if (split_tlb) {
@@ -102,6 +102,7 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,
pdtlb(start);
start += PAGE_SIZE;
}
+ preempt_enable();
}
purge_tlb_end();
}
diff --git a/include/asm-parisc/unistd.h b/include/asm-parisc/unistd.h
index e7a620c5c5e6..80b7b98c70a1 100644
--- a/include/asm-parisc/unistd.h
+++ b/include/asm-parisc/unistd.h
@@ -1011,7 +1011,6 @@ int sys_clone(unsigned long clone_flags, unsigned long usp,
struct pt_regs *regs);
int sys_vfork(struct pt_regs *regs);
int sys_pipe(int *fildes);
-long sys_ptrace(long request, pid_t pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
diff --git a/include/asm-ppc64/a.out.h b/include/asm-powerpc/a.out.h
index 3871e252a6f1..c7393a977364 100644
--- a/include/asm-ppc64/a.out.h
+++ b/include/asm-powerpc/a.out.h
@@ -1,14 +1,5 @@
-#ifndef __PPC64_A_OUT_H__
-#define __PPC64_A_OUT_H__
-
-/*
- * c 2001 PPC 64 Team, IBM Corp
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
+#ifndef _ASM_POWERPC_A_OUT_H
+#define _ASM_POWERPC_A_OUT_H
struct exec
{
@@ -27,6 +18,7 @@ struct exec
#define N_SYMSIZE(a) ((a).a_syms)
#ifdef __KERNEL__
+#ifdef __powerpc64__
#define STACK_TOP_USER64 TASK_SIZE_USER64
#define STACK_TOP_USER32 TASK_SIZE_USER32
@@ -34,6 +26,11 @@ struct exec
#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
STACK_TOP_USER32 : STACK_TOP_USER64)
+#else /* __powerpc64__ */
+
+#define STACK_TOP TASK_SIZE
+
+#endif /* __powerpc64__ */
#endif /* __KERNEL__ */
-#endif /* __PPC64_A_OUT_H__ */
+#endif /* _ASM_POWERPC_A_OUT_H */
diff --git a/include/asm-ppc/atomic.h b/include/asm-powerpc/atomic.h
index eeafd505836e..ed4b345ed75d 100644
--- a/include/asm-ppc/atomic.h
+++ b/include/asm-powerpc/atomic.h
@@ -1,29 +1,20 @@
+#ifndef _ASM_POWERPC_ATOMIC_H_
+#define _ASM_POWERPC_ATOMIC_H_
+
/*
* PowerPC atomic operations
*/
-#ifndef _ASM_PPC_ATOMIC_H_
-#define _ASM_PPC_ATOMIC_H_
-
typedef struct { volatile int counter; } atomic_t;
#ifdef __KERNEL__
+#include <asm/synch.h>
-#define ATOMIC_INIT(i) { (i) }
+#define ATOMIC_INIT(i) { (i) }
#define atomic_read(v) ((v)->counter)
#define atomic_set(v,i) (((v)->counter) = (i))
-extern void atomic_clear_mask(unsigned long mask, unsigned long *addr);
-
-#ifdef CONFIG_SMP
-#define SMP_SYNC "sync"
-#define SMP_ISYNC "\n\tisync"
-#else
-#define SMP_SYNC ""
-#define SMP_ISYNC
-#endif
-
/* Erratum #77 on the 405 means we need a sync or dcbt before every stwcx.
* The old ATOMIC_SYNC_FIX covered some but not all of this.
*/
@@ -53,12 +44,13 @@ static __inline__ int atomic_add_return(int a, atomic_t *v)
int t;
__asm__ __volatile__(
+ EIEIO_ON_SMP
"1: lwarx %0,0,%2 # atomic_add_return\n\
add %0,%1,%0\n"
PPC405_ERR77(0,%2)
" stwcx. %0,0,%2 \n\
bne- 1b"
- SMP_ISYNC
+ ISYNC_ON_SMP
: "=&r" (t)
: "r" (a), "r" (&v->counter)
: "cc", "memory");
@@ -88,12 +80,13 @@ static __inline__ int atomic_sub_return(int a, atomic_t *v)
int t;
__asm__ __volatile__(
+ EIEIO_ON_SMP
"1: lwarx %0,0,%2 # atomic_sub_return\n\
subf %0,%1,%0\n"
PPC405_ERR77(0,%2)
" stwcx. %0,0,%2 \n\
bne- 1b"
- SMP_ISYNC
+ ISYNC_ON_SMP
: "=&r" (t)
: "r" (a), "r" (&v->counter)
: "cc", "memory");
@@ -121,12 +114,13 @@ static __inline__ int atomic_inc_return(atomic_t *v)
int t;
__asm__ __volatile__(
+ EIEIO_ON_SMP
"1: lwarx %0,0,%1 # atomic_inc_return\n\
addic %0,%0,1\n"
PPC405_ERR77(0,%1)
" stwcx. %0,0,%1 \n\
bne- 1b"
- SMP_ISYNC
+ ISYNC_ON_SMP
: "=&r" (t)
: "r" (&v->counter)
: "cc", "memory");
@@ -164,12 +158,13 @@ static __inline__ int atomic_dec_return(atomic_t *v)
int t;
__asm__ __volatile__(
+ EIEIO_ON_SMP
"1: lwarx %0,0,%1 # atomic_dec_return\n\
addic %0,%0,-1\n"
PPC405_ERR77(0,%1)
" stwcx. %0,0,%1\n\
bne- 1b"
- SMP_ISYNC
+ ISYNC_ON_SMP
: "=&r" (t)
: "r" (&v->counter)
: "cc", "memory");
@@ -189,13 +184,14 @@ static __inline__ int atomic_dec_if_positive(atomic_t *v)
int t;
__asm__ __volatile__(
+ EIEIO_ON_SMP
"1: lwarx %0,0,%1 # atomic_dec_if_positive\n\
addic. %0,%0,-1\n\
blt- 2f\n"
PPC405_ERR77(0,%1)
" stwcx. %0,0,%1\n\
bne- 1b"
- SMP_ISYNC
+ ISYNC_ON_SMP
"\n\
2:" : "=&r" (t)
: "r" (&v->counter)
@@ -204,11 +200,10 @@ static __inline__ int atomic_dec_if_positive(atomic_t *v)
return t;
}
-#define __MB __asm__ __volatile__ (SMP_SYNC : : : "memory")
-#define smp_mb__before_atomic_dec() __MB
-#define smp_mb__after_atomic_dec() __MB
-#define smp_mb__before_atomic_inc() __MB
-#define smp_mb__after_atomic_inc() __MB
+#define smp_mb__before_atomic_dec() smp_mb()
+#define smp_mb__after_atomic_dec() smp_mb()
+#define smp_mb__before_atomic_inc() smp_mb()
+#define smp_mb__after_atomic_inc() smp_mb()
#endif /* __KERNEL__ */
-#endif /* _ASM_PPC_ATOMIC_H_ */
+#endif /* _ASM_POWERPC_ATOMIC_H_ */
diff --git a/include/asm-ppc64/auxvec.h b/include/asm-powerpc/auxvec.h
index ac6381a106e1..79d8c4732309 100644
--- a/include/asm-ppc64/auxvec.h
+++ b/include/asm-powerpc/auxvec.h
@@ -1,5 +1,5 @@
-#ifndef __PPC64_AUXVEC_H
-#define __PPC64_AUXVEC_H
+#ifndef _ASM_POWERPC_AUXVEC_H
+#define _ASM_POWERPC_AUXVEC_H
/*
* We need to put in some extra aux table entries to tell glibc what
@@ -14,6 +14,8 @@
/* The vDSO location. We have to use the same value as x86 for glibc's
* sake :-)
*/
+#ifdef __powerpc64__
#define AT_SYSINFO_EHDR 33
+#endif
-#endif /* __PPC64_AUXVEC_H */
+#endif
diff --git a/include/asm-ppc/backlight.h b/include/asm-powerpc/backlight.h
index 3a1c3dede2a0..1ba1f27a0b63 100644
--- a/include/asm-ppc/backlight.h
+++ b/include/asm-powerpc/backlight.h
@@ -1,12 +1,13 @@
/*
* Routines for handling backlight control on PowerBooks
*
- * For now, implementation resides in arch/ppc/kernel/pmac_support.c
+ * For now, implementation resides in
+ * arch/powerpc/platforms/powermac/pmac_support.c
*
*/
+#ifndef __ASM_POWERPC_BACKLIGHT_H
+#define __ASM_POWERPC_BACKLIGHT_H
#ifdef __KERNEL__
-#ifndef __ASM_PPC_BACKLIGHT_H
-#define __ASM_PPC_BACKLIGHT_H
/* Abstract values */
#define BACKLIGHT_OFF 0
@@ -26,5 +27,5 @@ extern int get_backlight_enable(void);
extern int set_backlight_level(int level);
extern int get_backlight_level(void);
-#endif
#endif /* __KERNEL__ */
+#endif
diff --git a/include/asm-ppc64/bug.h b/include/asm-powerpc/bug.h
index 160178278861..e4d028e87020 100644
--- a/include/asm-ppc64/bug.h
+++ b/include/asm-powerpc/bug.h
@@ -1,5 +1,5 @@
-#ifndef _PPC64_BUG_H
-#define _PPC64_BUG_H
+#ifndef _ASM_POWERPC_BUG_H
+#define _ASM_POWERPC_BUG_H
/*
* Define an illegal instr to trap on the bug.
@@ -11,9 +11,21 @@
#ifndef __ASSEMBLY__
+#ifdef __powerpc64__
+#define BUG_TABLE_ENTRY(label, line, file, func) \
+ ".llong " #label "\n .long " #line "\n .llong " #file ", " #func "\n"
+#define TRAP_OP(ra, rb) "1: tdnei " #ra ", " #rb "\n"
+#define DATA_TYPE long long
+#else
+#define BUG_TABLE_ENTRY(label, line, file, func) \
+ ".long " #label ", " #line ", " #file ", " #func "\n"
+#define TRAP_OP(ra, rb) "1: twnei " #ra ", " #rb "\n"
+#define DATA_TYPE int
+#endif /* __powerpc64__ */
+
struct bug_entry {
unsigned long bug_addr;
- long line;
+ int line;
const char *file;
const char *function;
};
@@ -32,28 +44,28 @@ struct bug_entry *find_bug(unsigned long bugaddr);
__asm__ __volatile__( \
"1: twi 31,0,0\n" \
".section __bug_table,\"a\"\n\t" \
- " .llong 1b,%0,%1,%2\n" \
+ BUG_TABLE_ENTRY(1b,%0,%1,%2) \
".previous" \
: : "i" (__LINE__), "i" (__FILE__), "i" (__FUNCTION__)); \
} while (0)
#define BUG_ON(x) do { \
__asm__ __volatile__( \
- "1: tdnei %0,0\n" \
+ TRAP_OP(%0,0) \
".section __bug_table,\"a\"\n\t" \
- " .llong 1b,%1,%2,%3\n" \
+ BUG_TABLE_ENTRY(1b,%1,%2,%3) \
".previous" \
- : : "r" ((long long)(x)), "i" (__LINE__), \
+ : : "r" ((DATA_TYPE)(x)), "i" (__LINE__), \
"i" (__FILE__), "i" (__FUNCTION__)); \
} while (0)
#define WARN_ON(x) do { \
__asm__ __volatile__( \
- "1: tdnei %0,0\n" \
+ TRAP_OP(%0,0) \
".section __bug_table,\"a\"\n\t" \
- " .llong 1b,%1,%2,%3\n" \
+ BUG_TABLE_ENTRY(1b,%1,%2,%3) \
".previous" \
- : : "r" ((long long)(x)), \
+ : : "r" ((DATA_TYPE)(x)), \
"i" (__LINE__ + BUG_WARNING_TRAP), \
"i" (__FILE__), "i" (__FUNCTION__)); \
} while (0)
@@ -61,9 +73,9 @@ struct bug_entry *find_bug(unsigned long bugaddr);
#define HAVE_ARCH_BUG
#define HAVE_ARCH_BUG_ON
#define HAVE_ARCH_WARN_ON
-#endif
-#endif
+#endif /* CONFIG_BUG */
+#endif /* __ASSEMBLY __ */
#include <asm-generic/bug.h>
-#endif
+#endif /* _ASM_POWERPC_BUG_H */
diff --git a/include/asm-ppc64/byteorder.h b/include/asm-powerpc/byteorder.h
index 8b57da62b674..b37752214a16 100644
--- a/include/asm-ppc64/byteorder.h
+++ b/include/asm-powerpc/byteorder.h
@@ -1,5 +1,5 @@
-#ifndef _PPC64_BYTEORDER_H
-#define _PPC64_BYTEORDER_H
+#ifndef _ASM_POWERPC_BYTEORDER_H
+#define _ASM_POWERPC_BYTEORDER_H
/*
* This program is free software; you can redistribute it and/or
@@ -77,10 +77,13 @@ static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 value)
#ifndef __STRICT_ANSI__
#define __BYTEORDER_HAS_U64__
-#endif
+#ifndef __powerpc64__
+#define __SWAB_64_THRU_32__
+#endif /* __powerpc64__ */
+#endif /* __STRICT_ANSI__ */
#endif /* __GNUC__ */
#include <linux/byteorder/big_endian.h>
-#endif /* _PPC64_BYTEORDER_H */
+#endif /* _ASM_POWERPC_BYTEORDER_H */
diff --git a/include/asm-ppc64/checksum.h b/include/asm-powerpc/checksum.h
index d22d4469de43..d8354d8a49ce 100644
--- a/include/asm-ppc64/checksum.h
+++ b/include/asm-powerpc/checksum.h
@@ -1,5 +1,5 @@
-#ifndef _PPC64_CHECKSUM_H
-#define _PPC64_CHECKSUM_H
+#ifndef _ASM_POWERPC_CHECKSUM_H
+#define _ASM_POWERPC_CHECKSUM_H
/*
* This program is free software; you can redistribute it and/or
@@ -41,8 +41,14 @@ extern unsigned int csum_partial(const unsigned char * buff, int len,
unsigned int sum);
/*
- * the same as csum_partial, but copies from src to dst while it
- * checksums
+ * Computes the checksum of a memory block at src, length len,
+ * and adds in "sum" (32-bit), while copying the block to dst.
+ * If an access exception occurs on src or dst, it stores -EFAULT
+ * to *src_err or *dst_err respectively (if that pointer is not
+ * NULL), and, for an error on src, zeroes the rest of dst.
+ *
+ * Like csum_partial, this must be called with even lengths,
+ * except for the last fragment.
*/
extern unsigned int csum_partial_copy_generic(const char *src, char *dst,
int len, unsigned int sum,
@@ -51,12 +57,18 @@ extern unsigned int csum_partial_copy_generic(const char *src, char *dst,
* the same as csum_partial, but copies from src to dst while it
* checksums.
*/
-
unsigned int csum_partial_copy_nocheck(const char *src,
char *dst,
int len,
unsigned int sum);
+#define csum_partial_copy_from_user(src, dst, len, sum, errp) \
+ csum_partial_copy_generic((src), (dst), (len), (sum), (errp), NULL)
+
+#define csum_partial_copy_nocheck(src, dst, len, sum) \
+ csum_partial_copy_generic((src), (dst), (len), (sum), NULL, NULL)
+
+
/*
* turns a 32-bit partial checksum (e.g. from csum_partial) into a
* 1's complement 16-bit checksum.
@@ -83,12 +95,7 @@ static inline unsigned short ip_compute_csum(unsigned char * buff, int len)
return csum_fold(csum_partial(buff, len, 0));
}
-#define csum_partial_copy_from_user(src, dst, len, sum, errp) \
- csum_partial_copy_generic((src), (dst), (len), (sum), (errp), NULL)
-
-#define csum_partial_copy_nocheck(src, dst, len, sum) \
- csum_partial_copy_generic((src), (dst), (len), (sum), NULL, NULL)
-
+#ifdef __powerpc64__
static inline u32 csum_tcpudp_nofold(u32 saddr,
u32 daddr,
unsigned short len,
@@ -103,5 +110,23 @@ static inline u32 csum_tcpudp_nofold(u32 saddr,
s += (s >> 32);
return (u32) s;
}
+#else
+static inline unsigned long csum_tcpudp_nofold(unsigned long saddr,
+ unsigned long daddr,
+ unsigned short len,
+ unsigned short proto,
+ unsigned int sum)
+{
+ __asm__("\n\
+ addc %0,%0,%1 \n\
+ adde %0,%0,%2 \n\
+ adde %0,%0,%3 \n\
+ addze %0,%0 \n\
+ "
+ : "=r" (sum)
+ : "r" (daddr), "r"(saddr), "r"((proto<<16)+len), "0"(sum));
+ return sum;
+}
#endif
+#endif
diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h
new file mode 100644
index 000000000000..c019501daceb
--- /dev/null
+++ b/include/asm-powerpc/cputable.h
@@ -0,0 +1,427 @@
+#ifndef __ASM_POWERPC_CPUTABLE_H
+#define __ASM_POWERPC_CPUTABLE_H
+
+#include <linux/config.h>
+#include <asm/ppc_asm.h> /* for ASM_CONST */
+
+#define PPC_FEATURE_32 0x80000000
+#define PPC_FEATURE_64 0x40000000
+#define PPC_FEATURE_601_INSTR 0x20000000
+#define PPC_FEATURE_HAS_ALTIVEC 0x10000000
+#define PPC_FEATURE_HAS_FPU 0x08000000
+#define PPC_FEATURE_HAS_MMU 0x04000000
+#define PPC_FEATURE_HAS_4xxMAC 0x02000000
+#define PPC_FEATURE_UNIFIED_CACHE 0x01000000
+#define PPC_FEATURE_HAS_SPE 0x00800000
+#define PPC_FEATURE_HAS_EFP_SINGLE 0x00400000
+#define PPC_FEATURE_HAS_EFP_DOUBLE 0x00200000
+#define PPC_FEATURE_NO_TB 0x00100000
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+
+/* This structure can grow, it's real size is used by head.S code
+ * via the mkdefs mechanism.
+ */
+struct cpu_spec;
+struct op_powerpc_model;
+
+typedef void (*cpu_setup_t)(unsigned long offset, struct cpu_spec* spec);
+
+struct cpu_spec {
+ /* CPU is matched via (PVR & pvr_mask) == pvr_value */
+ unsigned int pvr_mask;
+ unsigned int pvr_value;
+
+ char *cpu_name;
+ unsigned long cpu_features; /* Kernel features */
+ unsigned int cpu_user_features; /* Userland features */
+
+ /* cache line sizes */
+ unsigned int icache_bsize;
+ unsigned int dcache_bsize;
+
+ /* number of performance monitor counters */
+ unsigned int num_pmcs;
+
+ /* this is called to initialize various CPU bits like L1 cache,
+ * BHT, SPD, etc... from head.S before branching to identify_machine
+ */
+ cpu_setup_t cpu_setup;
+
+ /* Used by oprofile userspace to select the right counters */
+ char *oprofile_cpu_type;
+
+ /* Processor specific oprofile operations */
+ struct op_powerpc_model *oprofile_model;
+};
+
+extern struct cpu_spec *cur_cpu_spec;
+
+extern void identify_cpu(unsigned long offset, unsigned long cpu);
+extern void do_cpu_ftr_fixups(unsigned long offset);
+
+#endif /* __ASSEMBLY__ */
+
+/* CPU kernel features */
+
+/* Retain the 32b definitions all use bottom half of word */
+#define CPU_FTR_SPLIT_ID_CACHE ASM_CONST(0x0000000000000001)
+#define CPU_FTR_L2CR ASM_CONST(0x0000000000000002)
+#define CPU_FTR_SPEC7450 ASM_CONST(0x0000000000000004)
+#define CPU_FTR_ALTIVEC ASM_CONST(0x0000000000000008)
+#define CPU_FTR_TAU ASM_CONST(0x0000000000000010)
+#define CPU_FTR_CAN_DOZE ASM_CONST(0x0000000000000020)
+#define CPU_FTR_USE_TB ASM_CONST(0x0000000000000040)
+#define CPU_FTR_604_PERF_MON ASM_CONST(0x0000000000000080)
+#define CPU_FTR_601 ASM_CONST(0x0000000000000100)
+#define CPU_FTR_HPTE_TABLE ASM_CONST(0x0000000000000200)
+#define CPU_FTR_CAN_NAP ASM_CONST(0x0000000000000400)
+#define CPU_FTR_L3CR ASM_CONST(0x0000000000000800)
+#define CPU_FTR_L3_DISABLE_NAP ASM_CONST(0x0000000000001000)
+#define CPU_FTR_NAP_DISABLE_L2_PR ASM_CONST(0x0000000000002000)
+#define CPU_FTR_DUAL_PLL_750FX ASM_CONST(0x0000000000004000)
+#define CPU_FTR_NO_DPM ASM_CONST(0x0000000000008000)
+#define CPU_FTR_HAS_HIGH_BATS ASM_CONST(0x0000000000010000)
+#define CPU_FTR_NEED_COHERENT ASM_CONST(0x0000000000020000)
+#define CPU_FTR_NO_BTIC ASM_CONST(0x0000000000040000)
+#define CPU_FTR_BIG_PHYS ASM_CONST(0x0000000000080000)
+
+#ifdef __powerpc64__
+/* Add the 64b processor unique features in the top half of the word */
+#define CPU_FTR_SLB ASM_CONST(0x0000000100000000)
+#define CPU_FTR_16M_PAGE ASM_CONST(0x0000000200000000)
+#define CPU_FTR_TLBIEL ASM_CONST(0x0000000400000000)
+#define CPU_FTR_NOEXECUTE ASM_CONST(0x0000000800000000)
+#define CPU_FTR_NODSISRALIGN ASM_CONST(0x0000001000000000)
+#define CPU_FTR_IABR ASM_CONST(0x0000002000000000)
+#define CPU_FTR_MMCRA ASM_CONST(0x0000004000000000)
+#define CPU_FTR_CTRL ASM_CONST(0x0000008000000000)
+#define CPU_FTR_SMT ASM_CONST(0x0000010000000000)
+#define CPU_FTR_COHERENT_ICACHE ASM_CONST(0x0000020000000000)
+#define CPU_FTR_LOCKLESS_TLBIE ASM_CONST(0x0000040000000000)
+#define CPU_FTR_MMCRA_SIHV ASM_CONST(0x0000080000000000)
+#else
+/* ensure on 32b processors the flags are available for compiling but
+ * don't do anything */
+#define CPU_FTR_SLB ASM_CONST(0x0)
+#define CPU_FTR_16M_PAGE ASM_CONST(0x0)
+#define CPU_FTR_TLBIEL ASM_CONST(0x0)
+#define CPU_FTR_NOEXECUTE ASM_CONST(0x0)
+#define CPU_FTR_NODSISRALIGN ASM_CONST(0x0)
+#define CPU_FTR_IABR ASM_CONST(0x0)
+#define CPU_FTR_MMCRA ASM_CONST(0x0)
+#define CPU_FTR_CTRL ASM_CONST(0x0)
+#define CPU_FTR_SMT ASM_CONST(0x0)
+#define CPU_FTR_COHERENT_ICACHE ASM_CONST(0x0)
+#define CPU_FTR_LOCKLESS_TLBIE ASM_CONST(0x0)
+#define CPU_FTR_MMCRA_SIHV ASM_CONST(0x0)
+#endif
+
+#ifndef __ASSEMBLY__
+
+#define CPU_FTR_PPCAS_ARCH_V2_BASE (CPU_FTR_SLB | \
+ CPU_FTR_TLBIEL | CPU_FTR_NOEXECUTE | \
+ CPU_FTR_NODSISRALIGN | CPU_FTR_CTRL)
+
+/* iSeries doesn't support large pages */
+#ifdef CONFIG_PPC_ISERIES
+#define CPU_FTR_PPCAS_ARCH_V2 (CPU_FTR_PPCAS_ARCH_V2_BASE)
+#else
+#define CPU_FTR_PPCAS_ARCH_V2 (CPU_FTR_PPCAS_ARCH_V2_BASE | CPU_FTR_16M_PAGE)
+#endif /* CONFIG_PPC_ISERIES */
+
+/* We only set the altivec features if the kernel was compiled with altivec
+ * support
+ */
+#ifdef CONFIG_ALTIVEC
+#define CPU_FTR_ALTIVEC_COMP CPU_FTR_ALTIVEC
+#define PPC_FEATURE_HAS_ALTIVEC_COMP PPC_FEATURE_HAS_ALTIVEC
+#else
+#define CPU_FTR_ALTIVEC_COMP 0
+#define PPC_FEATURE_HAS_ALTIVEC_COMP 0
+#endif
+
+/* We need to mark all pages as being coherent if we're SMP or we
+ * have a 74[45]x and an MPC107 host bridge.
+ */
+#if defined(CONFIG_SMP) || defined(CONFIG_MPC10X_BRIDGE)
+#define CPU_FTR_COMMON CPU_FTR_NEED_COHERENT
+#else
+#define CPU_FTR_COMMON 0
+#endif
+
+/* The powersave features NAP & DOZE seems to confuse BDI when
+ debugging. So if a BDI is used, disable theses
+ */
+#ifndef CONFIG_BDI_SWITCH
+#define CPU_FTR_MAYBE_CAN_DOZE CPU_FTR_CAN_DOZE
+#define CPU_FTR_MAYBE_CAN_NAP CPU_FTR_CAN_NAP
+#else
+#define CPU_FTR_MAYBE_CAN_DOZE 0
+#define CPU_FTR_MAYBE_CAN_NAP 0
+#endif
+
+#define CLASSIC_PPC (!defined(CONFIG_8xx) && !defined(CONFIG_4xx) && \
+ !defined(CONFIG_POWER3) && !defined(CONFIG_POWER4) && \
+ !defined(CONFIG_BOOKE))
+
+enum {
+ CPU_FTRS_PPC601 = CPU_FTR_COMMON | CPU_FTR_601 | CPU_FTR_HPTE_TABLE,
+ CPU_FTRS_603 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB |
+ CPU_FTR_MAYBE_CAN_NAP,
+ CPU_FTRS_604 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_USE_TB | CPU_FTR_604_PERF_MON | CPU_FTR_HPTE_TABLE,
+ CPU_FTRS_740_NOTAU = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR |
+ CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
+ CPU_FTRS_740 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR |
+ CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
+ CPU_FTRS_750 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR |
+ CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
+ CPU_FTRS_750FX1 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR |
+ CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP |
+ CPU_FTR_DUAL_PLL_750FX | CPU_FTR_NO_DPM,
+ CPU_FTRS_750FX2 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR |
+ CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP |
+ CPU_FTR_NO_DPM,
+ CPU_FTRS_750FX = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR |
+ CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP |
+ CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS,
+ CPU_FTRS_750GX = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
+ CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
+ CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP |
+ CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS,
+ CPU_FTRS_7400_NOTAU = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR |
+ CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
+ CPU_FTR_MAYBE_CAN_NAP,
+ CPU_FTRS_7400 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR |
+ CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
+ CPU_FTR_MAYBE_CAN_NAP,
+ CPU_FTRS_7450_20 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP |
+ CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
+ CPU_FTR_NEED_COHERENT,
+ CPU_FTRS_7450_21 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_USE_TB |
+ CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP |
+ CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
+ CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP |
+ CPU_FTR_NEED_COHERENT,
+ CPU_FTRS_7450_23 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_USE_TB |
+ CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP |
+ CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
+ CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_NEED_COHERENT,
+ CPU_FTRS_7455_1 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_USE_TB |
+ CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
+ CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_HAS_HIGH_BATS |
+ CPU_FTR_NEED_COHERENT,
+ CPU_FTRS_7455_20 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_USE_TB |
+ CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP |
+ CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
+ CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP |
+ CPU_FTR_NEED_COHERENT | CPU_FTR_HAS_HIGH_BATS,
+ CPU_FTRS_7455 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_USE_TB |
+ CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP |
+ CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
+ CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS |
+ CPU_FTR_NEED_COHERENT,
+ CPU_FTRS_7447_10 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_USE_TB |
+ CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP |
+ CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
+ CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS |
+ CPU_FTR_NEED_COHERENT | CPU_FTR_NO_BTIC,
+ CPU_FTRS_7447 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_USE_TB |
+ CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP |
+ CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
+ CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS |
+ CPU_FTR_NEED_COHERENT,
+ CPU_FTRS_7447A = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_USE_TB |
+ CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP |
+ CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
+ CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS |
+ CPU_FTR_NEED_COHERENT,
+ CPU_FTRS_82XX = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB,
+ CPU_FTRS_G2_LE = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
+ CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS,
+ CPU_FTRS_E300 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
+ CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS,
+ CPU_FTRS_CLASSIC32 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
+ CPU_FTRS_POWER3_32 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
+ CPU_FTRS_POWER4_32 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
+ CPU_FTRS_970_32 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_ALTIVEC_COMP |
+ CPU_FTR_MAYBE_CAN_NAP,
+ CPU_FTRS_8XX = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
+ CPU_FTRS_40X = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
+ CPU_FTRS_44X = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
+ CPU_FTRS_E200 = CPU_FTR_USE_TB,
+ CPU_FTRS_E500 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
+ CPU_FTRS_E500_2 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+ CPU_FTR_BIG_PHYS,
+ CPU_FTRS_GENERIC_32 = CPU_FTR_COMMON,
+#ifdef __powerpc64__
+ CPU_FTRS_POWER3 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+ CPU_FTR_HPTE_TABLE | CPU_FTR_IABR,
+ CPU_FTRS_RS64 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+ CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
+ CPU_FTR_MMCRA | CPU_FTR_CTRL,
+ CPU_FTRS_POWER4 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+ CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA,
+ CPU_FTRS_PPC970 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+ CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 |
+ CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP | CPU_FTR_MMCRA,
+ CPU_FTRS_POWER5 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+ CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 |
+ CPU_FTR_MMCRA | CPU_FTR_SMT |
+ CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE |
+ CPU_FTR_MMCRA_SIHV,
+ CPU_FTRS_CELL = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+ CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 |
+ CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT,
+ CPU_FTRS_COMPATIBLE = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+ CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2,
+#endif
+
+ CPU_FTRS_POSSIBLE =
+#if CLASSIC_PPC
+ CPU_FTRS_PPC601 | CPU_FTRS_603 | CPU_FTRS_604 | CPU_FTRS_740_NOTAU |
+ CPU_FTRS_740 | CPU_FTRS_750 | CPU_FTRS_750FX1 |
+ CPU_FTRS_750FX2 | CPU_FTRS_750FX | CPU_FTRS_750GX |
+ CPU_FTRS_7400_NOTAU | CPU_FTRS_7400 | CPU_FTRS_7450_20 |
+ CPU_FTRS_7450_21 | CPU_FTRS_7450_23 | CPU_FTRS_7455_1 |
+ CPU_FTRS_7455_20 | CPU_FTRS_7455 | CPU_FTRS_7447_10 |
+ CPU_FTRS_7447 | CPU_FTRS_7447A | CPU_FTRS_82XX |
+ CPU_FTRS_G2_LE | CPU_FTRS_E300 | CPU_FTRS_CLASSIC32 |
+#else
+ CPU_FTRS_GENERIC_32 |
+#endif
+#ifdef CONFIG_PPC64BRIDGE
+ CPU_FTRS_POWER3_32 |
+#endif
+#ifdef CONFIG_POWER4
+ CPU_FTRS_POWER4_32 | CPU_FTRS_970_32 |
+#endif
+#ifdef CONFIG_8xx
+ CPU_FTRS_8XX |
+#endif
+#ifdef CONFIG_40x
+ CPU_FTRS_40X |
+#endif
+#ifdef CONFIG_44x
+ CPU_FTRS_44X |
+#endif
+#ifdef CONFIG_E200
+ CPU_FTRS_E200 |
+#endif
+#ifdef CONFIG_E500
+ CPU_FTRS_E500 | CPU_FTRS_E500_2 |
+#endif
+#ifdef __powerpc64__
+ CPU_FTRS_POWER3 | CPU_FTRS_RS64 | CPU_FTRS_POWER4 |
+ CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_CELL |
+#endif
+ 0,
+
+ CPU_FTRS_ALWAYS =
+#if CLASSIC_PPC
+ CPU_FTRS_PPC601 & CPU_FTRS_603 & CPU_FTRS_604 & CPU_FTRS_740_NOTAU &
+ CPU_FTRS_740 & CPU_FTRS_750 & CPU_FTRS_750FX1 &
+ CPU_FTRS_750FX2 & CPU_FTRS_750FX & CPU_FTRS_750GX &
+ CPU_FTRS_7400_NOTAU & CPU_FTRS_7400 & CPU_FTRS_7450_20 &
+ CPU_FTRS_7450_21 & CPU_FTRS_7450_23 & CPU_FTRS_7455_1 &
+ CPU_FTRS_7455_20 & CPU_FTRS_7455 & CPU_FTRS_7447_10 &
+ CPU_FTRS_7447 & CPU_FTRS_7447A & CPU_FTRS_82XX &
+ CPU_FTRS_G2_LE & CPU_FTRS_E300 & CPU_FTRS_CLASSIC32 &
+#else
+ CPU_FTRS_GENERIC_32 &
+#endif
+#ifdef CONFIG_PPC64BRIDGE
+ CPU_FTRS_POWER3_32 &
+#endif
+#ifdef CONFIG_POWER4
+ CPU_FTRS_POWER4_32 & CPU_FTRS_970_32 &
+#endif
+#ifdef CONFIG_8xx
+ CPU_FTRS_8XX &
+#endif
+#ifdef CONFIG_40x
+ CPU_FTRS_40X &
+#endif
+#ifdef CONFIG_44x
+ CPU_FTRS_44X &
+#endif
+#ifdef CONFIG_E200
+ CPU_FTRS_E200 &
+#endif
+#ifdef CONFIG_E500
+ CPU_FTRS_E500 & CPU_FTRS_E500_2 &
+#endif
+#ifdef __powerpc64__
+ CPU_FTRS_POWER3 & CPU_FTRS_RS64 & CPU_FTRS_POWER4 &
+ CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & CPU_FTRS_CELL &
+#endif
+ CPU_FTRS_POSSIBLE,
+};
+
+static inline int cpu_has_feature(unsigned long feature)
+{
+ return (CPU_FTRS_ALWAYS & feature) ||
+ (CPU_FTRS_POSSIBLE
+ & cur_cpu_spec->cpu_features
+ & feature);
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#ifdef __ASSEMBLY__
+
+#define BEGIN_FTR_SECTION 98:
+
+#ifndef __powerpc64__
+#define END_FTR_SECTION(msk, val) \
+99: \
+ .section __ftr_fixup,"a"; \
+ .align 2; \
+ .long msk; \
+ .long val; \
+ .long 98b; \
+ .long 99b; \
+ .previous
+#else /* __powerpc64__ */
+#define END_FTR_SECTION(msk, val) \
+99: \
+ .section __ftr_fixup,"a"; \
+ .align 3; \
+ .llong msk; \
+ .llong val; \
+ .llong 98b; \
+ .llong 99b; \
+ .previous
+#endif /* __powerpc64__ */
+
+#define END_FTR_SECTION_IFSET(msk) END_FTR_SECTION((msk), (msk))
+#define END_FTR_SECTION_IFCLR(msk) END_FTR_SECTION((msk), 0)
+#endif /* __ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+#endif /* __ASM_POWERPC_CPUTABLE_H */
diff --git a/include/asm-ppc/dbdma.h b/include/asm-powerpc/dbdma.h
index 8973565f95d3..8973565f95d3 100644
--- a/include/asm-ppc/dbdma.h
+++ b/include/asm-powerpc/dbdma.h
diff --git a/include/asm-ppc/dma.h b/include/asm-powerpc/dma.h
index cc8e5cd8c9d2..926378d2cd94 100644
--- a/include/asm-ppc/dma.h
+++ b/include/asm-powerpc/dma.h
@@ -1,18 +1,14 @@
+#ifndef _ASM_POWERPC_DMA_H
+#define _ASM_POWERPC_DMA_H
+
/*
- * include/asm-ppc/dma.h: Defines for using and allocating dma channels.
+ * Defines for using and allocating dma channels.
* Written by Hennus Bergman, 1992.
* High DMA channel support & info by Hannu Savolainen
* and John Boyd, Nov. 1992.
* Changes for ppc sound by Christoph Nadig
*/
-#ifdef __KERNEL__
-
-#include <linux/config.h>
-#include <asm/io.h>
-#include <linux/spinlock.h>
-#include <asm/system.h>
-
/*
* Note: Adapted for PowerPC by Gary Thomas
* Modified by Cort Dougan <cort@cs.nmt.edu>
@@ -25,8 +21,10 @@
* with a grain of salt.
*/
-#ifndef _ASM_DMA_H
-#define _ASM_DMA_H
+#include <linux/config.h>
+#include <asm/io.h>
+#include <linux/spinlock.h>
+#include <asm/system.h>
#ifndef MAX_DMA_CHANNELS
#define MAX_DMA_CHANNELS 8
@@ -34,11 +32,9 @@
/* The maximum address that we can perform a DMA transfer to on this platform */
/* Doesn't really apply... */
-#define MAX_DMA_ADDRESS 0xFFFFFFFF
+#define MAX_DMA_ADDRESS (~0UL)
-/* in arch/ppc/kernel/setup.c -- Cort */
-extern unsigned long DMA_MODE_WRITE, DMA_MODE_READ;
-extern unsigned long ISA_DMA_THRESHOLD;
+#if !defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI)
#ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER
#define dma_outb outb_p
@@ -171,7 +167,18 @@ extern long ppc_cs4232_dma, ppc_cs4232_dma2;
#define DMA1_EXT_REG 0x40B
#define DMA2_EXT_REG 0x4D6
+#ifndef __powerpc64__
+ /* in arch/ppc/kernel/setup.c -- Cort */
+ extern unsigned int DMA_MODE_WRITE;
+ extern unsigned int DMA_MODE_READ;
+ extern unsigned long ISA_DMA_THRESHOLD;
+#else
+ #define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */
+ #define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */
+#endif
+
#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */
+
#define DMA_AUTOINIT 0x10
extern spinlock_t dma_spin_lock;
@@ -200,8 +207,9 @@ static __inline__ void enable_dma(unsigned int dmanr)
if (dmanr <= 3) {
dma_outb(dmanr, DMA1_MASK_REG);
dma_outb(ucDmaCmd, DMA1_CMD_REG); /* Enable group */
- } else
+ } else {
dma_outb(dmanr & 3, DMA2_MASK_REG);
+ }
}
static __inline__ void disable_dma(unsigned int dmanr)
@@ -290,19 +298,26 @@ static __inline__ void set_dma_page(unsigned int dmanr, int pagenr)
static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int phys)
{
if (dmanr <= 3) {
- dma_outb(phys & 0xff, ((dmanr & 3) << 1) + IO_DMA1_BASE);
- dma_outb((phys >> 8) & 0xff, ((dmanr & 3) << 1) + IO_DMA1_BASE);
+ dma_outb(phys & 0xff,
+ ((dmanr & 3) << 1) + IO_DMA1_BASE);
+ dma_outb((phys >> 8) & 0xff,
+ ((dmanr & 3) << 1) + IO_DMA1_BASE);
} else if (dmanr == SND_DMA1 || dmanr == SND_DMA2) {
- dma_outb(phys & 0xff, ((dmanr & 3) << 2) + IO_DMA2_BASE);
- dma_outb((phys >> 8) & 0xff, ((dmanr & 3) << 2) + IO_DMA2_BASE);
+ dma_outb(phys & 0xff,
+ ((dmanr & 3) << 2) + IO_DMA2_BASE);
+ dma_outb((phys >> 8) & 0xff,
+ ((dmanr & 3) << 2) + IO_DMA2_BASE);
dma_outb((dmanr & 3), DMA2_EXT_REG);
} else {
- dma_outb((phys >> 1) & 0xff, ((dmanr & 3) << 2) + IO_DMA2_BASE);
- dma_outb((phys >> 9) & 0xff, ((dmanr & 3) << 2) + IO_DMA2_BASE);
+ dma_outb((phys >> 1) & 0xff,
+ ((dmanr & 3) << 2) + IO_DMA2_BASE);
+ dma_outb((phys >> 9) & 0xff,
+ ((dmanr & 3) << 2) + IO_DMA2_BASE);
}
set_dma_page(dmanr, phys >> 16);
}
+
/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for
* a specific DMA channel.
* You must ensure the parameters are valid.
@@ -315,21 +330,24 @@ static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
{
count--;
if (dmanr <= 3) {
- dma_outb(count & 0xff, ((dmanr & 3) << 1) + 1 + IO_DMA1_BASE);
- dma_outb((count >> 8) & 0xff, ((dmanr & 3) << 1) + 1 +
- IO_DMA1_BASE);
+ dma_outb(count & 0xff,
+ ((dmanr & 3) << 1) + 1 + IO_DMA1_BASE);
+ dma_outb((count >> 8) & 0xff,
+ ((dmanr & 3) << 1) + 1 + IO_DMA1_BASE);
} else if (dmanr == SND_DMA1 || dmanr == SND_DMA2) {
- dma_outb(count & 0xff, ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE);
- dma_outb((count >> 8) & 0xff, ((dmanr & 3) << 2) + 2 +
- IO_DMA2_BASE);
+ dma_outb(count & 0xff,
+ ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE);
+ dma_outb((count >> 8) & 0xff,
+ ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE);
} else {
- dma_outb((count >> 1) & 0xff, ((dmanr & 3) << 2) + 2 +
- IO_DMA2_BASE);
- dma_outb((count >> 9) & 0xff, ((dmanr & 3) << 2) + 2 +
- IO_DMA2_BASE);
+ dma_outb((count >> 1) & 0xff,
+ ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE);
+ dma_outb((count >> 9) & 0xff,
+ ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE);
}
}
+
/* 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.
@@ -340,8 +358,8 @@ static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
*/
static __inline__ int get_dma_residue(unsigned int dmanr)
{
- unsigned int io_port = (dmanr <= 3) ?
- ((dmanr & 3) << 1) + 1 + IO_DMA1_BASE
+ unsigned int io_port = (dmanr <= 3)
+ ? ((dmanr & 3) << 1) + 1 + IO_DMA1_BASE
: ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE;
/* using short to get 16-bit wrap around */
@@ -352,7 +370,6 @@ static __inline__ int get_dma_residue(unsigned int dmanr)
return (dmanr <= 3 || dmanr == SND_DMA1 || dmanr == SND_DMA2)
? count : (count << 1);
-
}
/* These are in kernel/dma.c: */
@@ -367,5 +384,7 @@ extern int isa_dma_bridge_buggy;
#else
#define isa_dma_bridge_buggy (0)
#endif
-#endif /* _ASM_DMA_H */
-#endif /* __KERNEL__ */
+
+#endif /* !defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI) */
+
+#endif /* _ASM_POWERPC_DMA_H */
diff --git a/include/asm-ppc64/elf.h b/include/asm-powerpc/elf.h
index c919a89343db..d22b10021b5d 100644
--- a/include/asm-ppc64/elf.h
+++ b/include/asm-powerpc/elf.h
@@ -1,10 +1,11 @@
-#ifndef __PPC64_ELF_H
-#define __PPC64_ELF_H
+#ifndef _ASM_POWERPC_ELF_H
+#define _ASM_POWERPC_ELF_H
#include <asm/types.h>
#include <asm/ptrace.h>
#include <asm/cputable.h>
#include <asm/auxvec.h>
+#include <asm/page.h>
/* PowerPC relocations defined by the ABIs */
#define R_PPC_NONE 0
@@ -75,7 +76,7 @@
#define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */
#define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */
-/* Keep this the last entry. */
+/* keep this the last entry. */
#define R_PPC_NUM 95
/*
@@ -90,8 +91,6 @@
#define ELF_NGREG 48 /* includes nip, msr, lr, etc. */
#define ELF_NFPREG 33 /* includes fpscr */
-#define ELF_NVRREG32 33 /* includes vscr & vrsave stuffed together */
-#define ELF_NVRREG 34 /* includes vscr & vrsave in split vectors */
typedef unsigned long elf_greg_t64;
typedef elf_greg_t64 elf_gregset_t64[ELF_NGREG];
@@ -100,8 +99,21 @@ typedef unsigned int elf_greg_t32;
typedef elf_greg_t32 elf_gregset_t32[ELF_NGREG];
/*
- * These are used to set parameters in the core dumps.
+ * ELF_ARCH, CLASS, and DATA are used to set parameters in the core dumps.
*/
+#ifdef __powerpc64__
+# define ELF_NVRREG32 33 /* includes vscr & vrsave stuffed together */
+# define ELF_NVRREG 34 /* includes vscr & vrsave in split vectors */
+# define ELF_GREG_TYPE elf_greg_t64
+#else
+# define ELF_NEVRREG 34 /* includes acc (as 2) */
+# define ELF_NVRREG 33 /* includes vscr */
+# define ELF_GREG_TYPE elf_greg_t32
+# define ELF_ARCH EM_PPC
+# define ELF_CLASS ELFCLASS32
+# define ELF_DATA ELFDATA2MSB
+#endif /* __powerpc64__ */
+
#ifndef ELF_ARCH
# define ELF_ARCH EM_PPC64
# define ELF_CLASS ELFCLASS64
@@ -114,8 +126,9 @@ typedef elf_greg_t32 elf_gregset_t32[ELF_NGREG];
typedef elf_greg_t32 elf_greg_t;
typedef elf_gregset_t32 elf_gregset_t;
# define elf_addr_t u32
-#endif
+#endif /* ELF_ARCH */
+/* Floating point registers */
typedef double elf_fpreg_t;
typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
@@ -125,7 +138,9 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
* The entry with index 32 contains the vscr as the last word (offset 12)
* within the quadword. This allows the vscr to be stored as either a
* quadword (since it must be copied via a vector register to/from storage)
- * or as a word. The entry with index 33 contains the vrsave as the first
+ * or as a word.
+ *
+ * 64-bit kernel notes: The entry at index 33 contains the vrsave as the first
* word (offset 0) within the quadword.
*
* This definition of the VMX state is compatible with the current PPC32
@@ -138,7 +153,9 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
*/
typedef __vector128 elf_vrreg_t;
typedef elf_vrreg_t elf_vrregset_t[ELF_NVRREG];
+#ifdef __powerpc64__
typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
+#endif
/*
* This is used to ensure we don't load something for the wrong architecture.
@@ -146,7 +163,7 @@ typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
#define elf_check_arch(x) ((x)->e_machine == ELF_ARCH)
#define USE_ELF_CORE_DUMP
-#define ELF_EXEC_PAGESIZE 4096
+#define ELF_EXEC_PAGESIZE PAGE_SIZE
/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
use of this is to invoke "./ld.so someprog" to test out a new version of
@@ -158,26 +175,30 @@ typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
#ifdef __KERNEL__
/* Common routine for both 32-bit and 64-bit processes */
-static inline void ppc64_elf_core_copy_regs(elf_gregset_t elf_regs,
+static inline void ppc_elf_core_copy_regs(elf_gregset_t elf_regs,
struct pt_regs *regs)
{
int i;
- int gprs = sizeof(struct pt_regs)/sizeof(elf_greg_t64);
+ int gprs = sizeof(struct pt_regs)/sizeof(ELF_GREG_TYPE);
if (gprs > ELF_NGREG)
gprs = ELF_NGREG;
for (i=0; i < gprs; i++)
- elf_regs[i] = (elf_greg_t)((elf_greg_t64 *)regs)[i];
+ elf_regs[i] = (elf_greg_t)((ELF_GREG_TYPE *)regs)[i];
+
+ memset((char *)(elf_regs) + sizeof(struct pt_regs), 0, \
+ sizeof(elf_gregset_t) - sizeof(struct pt_regs));
+
}
-#define ELF_CORE_COPY_REGS(gregs, regs) ppc64_elf_core_copy_regs(gregs, regs);
+#define ELF_CORE_COPY_REGS(gregs, regs) ppc_elf_core_copy_regs(gregs, regs);
static inline int dump_task_regs(struct task_struct *tsk,
elf_gregset_t *elf_regs)
{
struct pt_regs *regs = tsk->thread.regs;
if (regs)
- ppc64_elf_core_copy_regs(*elf_regs, regs);
+ ppc_elf_core_copy_regs(*elf_regs, regs);
return 1;
}
@@ -186,15 +207,17 @@ static inline int dump_task_regs(struct task_struct *tsk,
extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *);
#define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
-/* XXX Should we define the XFPREGS using altivec ??? */
-
-#endif
+#endif /* __KERNEL__ */
-/* This yields a mask that user programs can use to figure out what
+/* ELF_HWCAP yields a mask that user programs can use to figure out what
instruction set this cpu supports. This could be done in userspace,
but it's not easy, and we've already done it here. */
-
-#define ELF_HWCAP (cur_cpu_spec->cpu_user_features)
+# define ELF_HWCAP (cur_cpu_spec->cpu_user_features)
+#ifdef __powerpc64__
+# define ELF_PLAT_INIT(_r, load_addr) do { \
+ _r->gpr[2] = load_addr; \
+} while (0)
+#endif /* __powerpc64__ */
/* This yields a string that ld.so will use to load implementation
specific libraries for optimization. This is more specific in
@@ -205,14 +228,10 @@ extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *);
#define ELF_PLATFORM (NULL)
-#define ELF_PLAT_INIT(_r, load_addr) do { \
- memset(_r->gpr, 0, sizeof(_r->gpr)); \
- _r->ctr = _r->link = _r->xer = _r->ccr = 0; \
- _r->gpr[2] = load_addr; \
-} while (0)
-
#ifdef __KERNEL__
-#define SET_PERSONALITY(ex, ibcs2) \
+
+#ifdef __powerpc64__
+# define SET_PERSONALITY(ex, ibcs2) \
do { \
unsigned long new_flags = 0; \
if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
@@ -225,7 +244,6 @@ do { \
if (personality(current->personality) != PER_LINUX32) \
set_personality(PER_LINUX); \
} while (0)
-
/*
* An executable for which elf_read_implies_exec() returns TRUE will
* have the READ_IMPLIES_EXEC personality flag set automatically. This
@@ -233,19 +251,26 @@ do { \
* the 64bit ABI has never had these issues dont enable the workaround
* even if we have an executable stack.
*/
-#define elf_read_implies_exec(ex, exec_stk) (test_thread_flag(TIF_32BIT) ? \
+# define elf_read_implies_exec(ex, exec_stk) (test_thread_flag(TIF_32BIT) ? \
(exec_stk != EXSTACK_DISABLE_X) : 0)
+#else
+# define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+#endif /* __powerpc64__ */
-#endif
+#endif /* __KERNEL__ */
extern int dcache_bsize;
extern int icache_bsize;
extern int ucache_bsize;
-/* We do have an arch_setup_additional_pages for vDSO matters */
-#define ARCH_HAS_SETUP_ADDITIONAL_PAGES
+#ifdef __powerpc64__
struct linux_binprm;
+#define ARCH_HAS_SETUP_ADDITIONAL_PAGES /* vDSO has arch_setup_additional_pages */
extern int arch_setup_additional_pages(struct linux_binprm *bprm, int executable_stack);
+#define VDSO_AUX_ENT(a,b) NEW_AUX_ENT(a,b);
+#else
+#define VDSO_AUX_ENT(a,b)
+#endif /* __powerpc64__ */
/*
* The requirements here are:
@@ -265,9 +290,8 @@ do { \
NEW_AUX_ENT(AT_DCACHEBSIZE, dcache_bsize); \
NEW_AUX_ENT(AT_ICACHEBSIZE, icache_bsize); \
NEW_AUX_ENT(AT_UCACHEBSIZE, ucache_bsize); \
- /* vDSO base */ \
- NEW_AUX_ENT(AT_SYSINFO_EHDR, current->thread.vdso_base); \
- } while (0)
+ VDSO_AUX_ENT(AT_SYSINFO_EHDR, current->thread.vdso_base) \
+} while (0)
/* PowerPC64 relocations defined by the ABIs */
#define R_PPC64_NONE R_PPC_NONE
@@ -384,4 +408,4 @@ do { \
/* Keep this the last entry. */
#define R_PPC64_NUM 107
-#endif /* __PPC64_ELF_H */
+#endif /* _ASM_POWERPC_ELF_H */
diff --git a/include/asm-ppc64/firmware.h b/include/asm-powerpc/firmware.h
index 22bb85cf60af..806c142ae9ea 100644
--- a/include/asm-ppc64/firmware.h
+++ b/include/asm-powerpc/firmware.h
@@ -1,8 +1,4 @@
/*
- * include/asm-ppc64/firmware.h
- *
- * Extracted from include/asm-ppc64/cputable.h
- *
* Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org)
*
* Modifications for ppc64:
@@ -13,8 +9,8 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
-#ifndef __ASM_PPC_FIRMWARE_H
-#define __ASM_PPC_FIRMWARE_H
+#ifndef __ASM_POWERPC_FIRMWARE_H
+#define __ASM_POWERPC_FIRMWARE_H
#ifdef __KERNEL__
@@ -98,4 +94,4 @@ extern firmware_feature_t firmware_features_table[];
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
-#endif /* __ASM_PPC_FIRMWARE_H */
+#endif /* __ASM_POWERPC_FIRMWARE_H */
diff --git a/include/asm-powerpc/grackle.h b/include/asm-powerpc/grackle.h
new file mode 100644
index 000000000000..563c7a5e64c9
--- /dev/null
+++ b/include/asm-powerpc/grackle.h
@@ -0,0 +1,7 @@
+/*
+ * Functions for setting up and using a MPC106 northbridge
+ */
+
+#include <asm/pci-bridge.h>
+
+extern void setup_grackle(struct pci_controller *hose);
diff --git a/include/asm-ppc/hardirq.h b/include/asm-powerpc/hardirq.h
index 94f1411b1a93..3b3e3b49ec12 100644
--- a/include/asm-ppc/hardirq.h
+++ b/include/asm-powerpc/hardirq.h
@@ -1,11 +1,8 @@
-#ifdef __KERNEL__
-#ifndef __ASM_HARDIRQ_H
-#define __ASM_HARDIRQ_H
+#ifndef _ASM_POWERPC_HARDIRQ_H
+#define _ASM_POWERPC_HARDIRQ_H
-#include <linux/config.h>
-#include <linux/cache.h>
-#include <linux/smp_lock.h>
#include <asm/irq.h>
+#include <asm/bug.h>
/* The __last_jiffy_stamp field is needed to ensure that no decrementer
* interrupt is lost on SMP machines. Since on most CPUs it is in the same
@@ -13,7 +10,7 @@
* for uniformity.
*/
typedef struct {
- unsigned long __softirq_pending; /* set_bit is used on this */
+ unsigned int __softirq_pending; /* set_bit is used on this */
unsigned int __last_jiffy_stamp;
} ____cacheline_aligned irq_cpustat_t;
@@ -27,5 +24,4 @@ static inline void ack_bad_irq(int irq)
BUG();
}
-#endif /* __ASM_HARDIRQ_H */
-#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_HARDIRQ_H */
diff --git a/include/asm-ppc/heathrow.h b/include/asm-powerpc/heathrow.h
index 22ac179856b9..22ac179856b9 100644
--- a/include/asm-ppc/heathrow.h
+++ b/include/asm-powerpc/heathrow.h
diff --git a/include/asm-ppc64/hw_irq.h b/include/asm-powerpc/hw_irq.h
index baea40e695ec..c37b31b96337 100644
--- a/include/asm-ppc64/hw_irq.h
+++ b/include/asm-powerpc/hw_irq.h
@@ -1,22 +1,17 @@
/*
* Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu>
- *
- * Use inline IRQs where possible - Anton Blanchard <anton@au.ibm.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_POWERPC_HW_IRQ_H
+#define _ASM_POWERPC_HW_IRQ_H
+
#ifdef __KERNEL__
-#ifndef _PPC64_HW_IRQ_H
-#define _PPC64_HW_IRQ_H
#include <linux/config.h>
#include <linux/errno.h>
-#include <asm/irq.h>
+#include <asm/ptrace.h>
+#include <asm/processor.h>
-int timer_interrupt(struct pt_regs *);
+extern void timer_interrupt(struct pt_regs *);
extern void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq);
#ifdef CONFIG_PPC_ISERIES
@@ -33,45 +28,60 @@ extern void local_irq_restore(unsigned long);
#else
-#define local_save_flags(flags) ((flags) = mfmsr())
+#if defined(CONFIG_BOOKE)
+#define SET_MSR_EE(x) mtmsr(x)
+#define local_irq_restore(flags) __asm__ __volatile__("wrtee %0" : : "r" (flags) : "memory")
+#elif defined(__powerpc64__)
+#define SET_MSR_EE(x) __mtmsrd(x, 1)
#define local_irq_restore(flags) do { \
__asm__ __volatile__("": : :"memory"); \
__mtmsrd((flags), 1); \
} while(0)
+#else
+#define SET_MSR_EE(x) mtmsr(x)
+#define local_irq_restore(flags) mtmsr(flags)
+#endif
static inline void local_irq_disable(void)
{
+#ifdef CONFIG_BOOKE
+ __asm__ __volatile__("wrteei 0": : :"memory");
+#else
unsigned long msr;
- msr = mfmsr();
- __mtmsrd(msr & ~MSR_EE, 1);
__asm__ __volatile__("": : :"memory");
+ msr = mfmsr();
+ SET_MSR_EE(msr & ~MSR_EE);
+#endif
}
static inline void local_irq_enable(void)
{
+#ifdef CONFIG_BOOKE
+ __asm__ __volatile__("wrteei 1": : :"memory");
+#else
unsigned long msr;
__asm__ __volatile__("": : :"memory");
msr = mfmsr();
- __mtmsrd(msr | MSR_EE, 1);
+ SET_MSR_EE(msr | MSR_EE);
+#endif
}
-static inline void __do_save_and_cli(unsigned long *flags)
+static inline void local_irq_save_ptr(unsigned long *flags)
{
unsigned long msr;
msr = mfmsr();
*flags = msr;
- __mtmsrd(msr & ~MSR_EE, 1);
+#ifdef CONFIG_BOOKE
+ __asm__ __volatile__("wrteei 0": : :"memory");
+#else
+ SET_MSR_EE(msr & ~MSR_EE);
+#endif
__asm__ __volatile__("": : :"memory");
}
-#define local_irq_save(flags) __do_save_and_cli(&flags)
-
-#define irqs_disabled() \
-({ \
- unsigned long flags; \
- local_save_flags(flags); \
- !(flags & MSR_EE); \
-})
+#define local_save_flags(flags) ((flags) = mfmsr())
+#define local_irq_save(flags) local_irq_save_ptr(&flags)
+#define irqs_disabled() ((mfmsr() & MSR_EE) == 0)
#endif /* CONFIG_PPC_ISERIES */
@@ -99,6 +109,6 @@ static inline void __do_save_and_cli(unsigned long *flags)
*/
struct hw_interrupt_type;
static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
-
-#endif /* _PPC64_HW_IRQ_H */
-#endif /* __KERNEL__ */
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_HW_IRQ_H */
diff --git a/include/asm-powerpc/i8259.h b/include/asm-powerpc/i8259.h
new file mode 100644
index 000000000000..fc4bfee124d7
--- /dev/null
+++ b/include/asm-powerpc/i8259.h
@@ -0,0 +1,12 @@
+#ifndef _ASM_POWERPC_I8259_H
+#define _ASM_POWERPC_I8259_H
+
+#include <linux/irq.h>
+
+extern struct hw_interrupt_type i8259_pic;
+
+extern void i8259_init(unsigned long intack_addr, int offset);
+extern int i8259_irq(struct pt_regs *regs);
+extern int i8259_irq_cascade(struct pt_regs *regs, void *unused);
+
+#endif /* _ASM_POWERPC_I8259_H */
diff --git a/include/asm-ppc64/iommu.h b/include/asm-powerpc/iommu.h
index c2f3b6e8a42f..9d91bdd667ae 100644
--- a/include/asm-ppc64/iommu.h
+++ b/include/asm-powerpc/iommu.h
@@ -1,5 +1,4 @@
/*
- * iommu.h
* Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
* Rewrite, cleanup:
* Copyright (C) 2004 Olof Johansson <olof@austin.ibm.com>, IBM Corporation
@@ -22,6 +21,7 @@
#ifndef _ASM_IOMMU_H
#define _ASM_IOMMU_H
+#include <linux/config.h>
#include <asm/types.h>
#include <linux/spinlock.h>
#include <linux/device.h>
@@ -29,44 +29,11 @@
/*
* IOMAP_MAX_ORDER defines the largest contiguous block
- * of dma (tce) space we can get. IOMAP_MAX_ORDER = 13
+ * of dma space we can get. IOMAP_MAX_ORDER = 13
* allows up to 2**12 pages (4096 * 4096) = 16 MB
*/
#define IOMAP_MAX_ORDER 13
-/*
- * Tces come in two formats, one for the virtual bus and a different
- * format for PCI
- */
-#define TCE_VB 0
-#define TCE_PCI 1
-
-/* tce_entry
- * Used by pSeries (SMP) and iSeries/pSeries LPAR, but there it's
- * abstracted so layout is irrelevant.
- */
-union tce_entry {
- unsigned long te_word;
- struct {
- unsigned int tb_cacheBits :6; /* Cache hash bits - not used */
- unsigned int tb_rsvd :6;
- unsigned long tb_rpn :40; /* Real page number */
- unsigned int tb_valid :1; /* Tce is valid (vb only) */
- unsigned int tb_allio :1; /* Tce is valid for all lps (vb only) */
- unsigned int tb_lpindex :8; /* LpIndex for user of TCE (vb only) */
- unsigned int tb_pciwr :1; /* Write allowed (pci only) */
- unsigned int tb_rdwr :1; /* Read allowed (pci), Write allowed (vb) */
- } te_bits;
-#define te_cacheBits te_bits.tb_cacheBits
-#define te_rpn te_bits.tb_rpn
-#define te_valid te_bits.tb_valid
-#define te_allio te_bits.tb_allio
-#define te_lpindex te_bits.tb_lpindex
-#define te_pciwr te_bits.tb_pciwr
-#define te_rdwr te_bits.tb_rdwr
-};
-
-
struct iommu_table {
unsigned long it_busno; /* Bus number this table belongs to */
unsigned long it_size; /* Size of iommu table in entries */
@@ -83,6 +50,7 @@ struct iommu_table {
};
struct scatterlist;
+struct device_node;
#ifdef CONFIG_PPC_MULTIPLATFORM
@@ -104,9 +72,8 @@ extern void iommu_devnode_init_pSeries(struct device_node *dn);
#ifdef CONFIG_PPC_ISERIES
-struct iSeries_Device_Node;
/* Creates table for an individual device node */
-extern void iommu_devnode_init_iSeries(struct iSeries_Device_Node *dn);
+extern void iommu_devnode_init_iSeries(struct device_node *dn);
#endif /* CONFIG_PPC_ISERIES */
diff --git a/include/asm-ppc/irq.h b/include/asm-powerpc/irq.h
index bd9674807f05..c7c3f912a3c2 100644
--- a/include/asm-ppc/irq.h
+++ b/include/asm-powerpc/irq.h
@@ -1,11 +1,23 @@
#ifdef __KERNEL__
-#ifndef _ASM_IRQ_H
-#define _ASM_IRQ_H
+#ifndef _ASM_POWERPC_IRQ_H
+#define _ASM_POWERPC_IRQ_H
+
+/*
+ * This program is free software; you can redistribute 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/config.h>
-#include <asm/machdep.h> /* ppc_md */
+#include <linux/threads.h>
+
+#include <asm/types.h>
#include <asm/atomic.h>
+/* this number is used when no interrupt has been assigned */
+#define NO_IRQ (-1)
+
/*
* These constants are used for passing information about interrupt
* signal polarity and level/edge sensing to the low-level PIC chip
@@ -24,6 +36,50 @@
*/
#define ARCH_HAS_IRQ_PER_CPU
+#define get_irq_desc(irq) (&irq_desc[(irq)])
+
+/* Define a way to iterate across irqs. */
+#define for_each_irq(i) \
+ for ((i) = 0; (i) < NR_IRQS; ++(i))
+
+#ifdef CONFIG_PPC64
+
+/*
+ * Maximum number of interrupt sources that we can handle.
+ */
+#define NR_IRQS 512
+
+/* Interrupt numbers are virtual in case they are sparsely
+ * distributed by the hardware.
+ */
+extern unsigned int virt_irq_to_real_map[NR_IRQS];
+
+/* Create a mapping for a real_irq if it doesn't already exist.
+ * Return the virtual irq as a convenience.
+ */
+int virt_irq_create_mapping(unsigned int real_irq);
+void virt_irq_init(void);
+
+static inline unsigned int virt_irq_to_real(unsigned int virt_irq)
+{
+ return virt_irq_to_real_map[virt_irq];
+}
+
+extern unsigned int real_irq_to_virt_slowpath(unsigned int real_irq);
+
+/*
+ * List of interrupt controllers.
+ */
+#define IC_INVALID 0
+#define IC_OPEN_PIC 1
+#define IC_PPC_XIC 2
+#define IC_BPA_IIC 3
+#define IC_ISERIES 4
+
+extern u64 ppc64_interrupt_controller;
+
+#else /* 32-bit */
+
#if defined(CONFIG_40x)
#include <asm/ibm4xx.h>
@@ -66,11 +122,6 @@
#define NR_UIC_IRQS UIC_WIDTH
#define NR_IRQS ((NR_UIC_IRQS * NR_UICS) + NR_BOARD_IRQS)
#endif
-static __inline__ int
-irq_canonicalize(int irq)
-{
- return (irq);
-}
#elif defined(CONFIG_44x)
#include <asm/ibm44x.h>
@@ -78,12 +129,6 @@ irq_canonicalize(int irq)
#define NR_UIC_IRQS 32
#define NR_IRQS ((NR_UIC_IRQS * NR_UICS) + NR_BOARD_IRQS)
-static __inline__ int
-irq_canonicalize(int irq)
-{
- return (irq);
-}
-
#elif defined(CONFIG_8xx)
/* Now include the board configuration specific associations.
@@ -170,20 +215,9 @@ irq_canonicalize(int irq)
*/
#define mk_int_int_mask(IL) (1 << (7 - (IL/2)))
-/* always the same on 8xx -- Cort */
-static __inline__ int irq_canonicalize(int irq)
-{
- return irq;
-}
-
#elif defined(CONFIG_83xx)
#include <asm/mpc83xx.h>
-static __inline__ int irq_canonicalize(int irq)
-{
- return irq;
-}
-
#define NR_IRQS (NR_IPIC_INTS)
#elif defined(CONFIG_85xx)
@@ -307,17 +341,13 @@ static __inline__ int irq_canonicalize(int irq)
#define SIU_INT_PC1 ((uint)0x3e+CPM_IRQ_OFFSET)
#define SIU_INT_PC0 ((uint)0x3f+CPM_IRQ_OFFSET)
-static __inline__ int irq_canonicalize(int irq)
-{
- return irq;
-}
-
#else /* CONFIG_40x + CONFIG_8xx */
/*
* this is the # irq's for all ppc arch's (pmac/chrp/prep)
* so it is the max of them all
*/
#define NR_IRQS 256
+#define __DO_IRQ_CANON 1
#ifndef CONFIG_8260
@@ -394,25 +424,81 @@ static __inline__ int irq_canonicalize(int irq)
#endif /* CONFIG_8260 */
+#endif
+
+#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
+/* pedantic: these are long because they are used with set_bit --RR */
+extern unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
+extern unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
+extern atomic_t ppc_n_lost_interrupts;
+
+#define virt_irq_create_mapping(x) (x)
+
+#endif
+
/*
- * This gets called from serial.c, which is now used on
- * powermacs as well as prep/chrp boxes.
- * Prep and chrp both have cascaded 8259 PICs.
+ * Because many systems have two overlapping names spaces for
+ * interrupts (ISA and XICS for example), and the ISA interrupts
+ * have historically not been easy to renumber, we allow ISA
+ * interrupts to take values 0 - 15, and shift up the remaining
+ * interrupts by 0x10.
*/
+#define NUM_ISA_INTERRUPTS 0x10
+extern int __irq_offset_value;
+
+static inline int irq_offset_up(int irq)
+{
+ return(irq + __irq_offset_value);
+}
+
+static inline int irq_offset_down(int irq)
+{
+ return(irq - __irq_offset_value);
+}
+
+static inline int irq_offset_value(void)
+{
+ return __irq_offset_value;
+}
+
+#ifdef __DO_IRQ_CANON
+extern int ppc_do_canonicalize_irqs;
+#else
+#define ppc_do_canonicalize_irqs 0
+#endif
+
static __inline__ int irq_canonicalize(int irq)
{
- if (ppc_md.irq_canonicalize)
- return ppc_md.irq_canonicalize(irq);
+ if (ppc_do_canonicalize_irqs && irq == 2)
+ irq = 9;
return irq;
}
-#endif
+extern int distribute_irqs;
-#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
-/* pedantic: these are long because they are used with set_bit --RR */
-extern unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
-extern unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
-extern atomic_t ppc_n_lost_interrupts;
+struct irqaction;
+struct pt_regs;
+
+#ifdef CONFIG_IRQSTACKS
+/*
+ * Per-cpu stacks for handling hard and soft interrupts.
+ */
+extern struct thread_info *hardirq_ctx[NR_CPUS];
+extern struct thread_info *softirq_ctx[NR_CPUS];
+
+extern void irq_ctx_init(void);
+extern void call_do_softirq(struct thread_info *tp);
+extern int call_handle_IRQ_event(int irq, struct pt_regs *regs,
+ struct irqaction *action, struct thread_info *tp);
+
+#define __ARCH_HAS_DO_SOFTIRQ
+
+#else
+#define irq_ctx_init()
+
+#endif /* CONFIG_IRQSTACKS */
+
+extern void do_IRQ(struct pt_regs *regs);
#endif /* _ASM_IRQ_H */
#endif /* __KERNEL__ */
diff --git a/include/asm-ppc64/kdebug.h b/include/asm-powerpc/kdebug.h
index d383d161cf8d..9dcbac674811 100644
--- a/include/asm-ppc64/kdebug.h
+++ b/include/asm-powerpc/kdebug.h
@@ -1,5 +1,5 @@
-#ifndef _PPC64_KDEBUG_H
-#define _PPC64_KDEBUG_H 1
+#ifndef _ASM_POWERPC_KDEBUG_H
+#define _ASM_POWERPC_KDEBUG_H
/* nearly identical to x86_64/i386 code */
@@ -21,7 +21,7 @@ struct die_args {
then free.
*/
int register_die_notifier(struct notifier_block *nb);
-extern struct notifier_block *ppc64_die_chain;
+extern struct notifier_block *powerpc_die_chain;
/* Grossly misnamed. */
enum die_val {
@@ -30,14 +30,13 @@ enum die_val {
DIE_DABR_MATCH,
DIE_BPT,
DIE_SSTEP,
- DIE_GPF,
DIE_PAGE_FAULT,
};
static inline int notify_die(enum die_val val,char *str,struct pt_regs *regs,long err,int trap, int sig)
{
struct die_args args = { .regs=regs, .str=str, .err=err, .trapnr=trap,.signr=sig };
- return notifier_call_chain(&ppc64_die_chain, val, &args);
+ return notifier_call_chain(&powerpc_die_chain, val, &args);
}
-#endif
+#endif /* _ASM_POWERPC_KDEBUG_H */
diff --git a/include/asm-ppc/keylargo.h b/include/asm-powerpc/keylargo.h
index a669a3f0f5a2..a669a3f0f5a2 100644
--- a/include/asm-ppc/keylargo.h
+++ b/include/asm-powerpc/keylargo.h
diff --git a/include/asm-powerpc/kmap_types.h b/include/asm-powerpc/kmap_types.h
new file mode 100644
index 000000000000..b6bac6f61c16
--- /dev/null
+++ b/include/asm-powerpc/kmap_types.h
@@ -0,0 +1,33 @@
+#ifndef _ASM_POWERPC_KMAP_TYPES_H
+#define _ASM_POWERPC_KMAP_TYPES_H
+
+#ifdef __KERNEL__
+
+/*
+ * This program is free software; you can redistribute 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.
+ */
+
+enum km_type {
+ KM_BOUNCE_READ,
+ KM_SKB_SUNRPC_DATA,
+ KM_SKB_DATA_SOFTIRQ,
+ KM_USER0,
+ KM_USER1,
+ KM_BIO_SRC_IRQ,
+ KM_BIO_DST_IRQ,
+ KM_PTE0,
+ KM_PTE1,
+ KM_IRQ0,
+ KM_IRQ1,
+ KM_SOFTIRQ0,
+ KM_SOFTIRQ1,
+ KM_PPC_SYNC_PAGE,
+ KM_PPC_SYNC_ICACHE,
+ KM_TYPE_NR
+};
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_KMAP_TYPES_H */
diff --git a/include/asm-ppc64/kprobes.h b/include/asm-powerpc/kprobes.h
index d9129d2b038e..b2f09f17fbe0 100644
--- a/include/asm-ppc64/kprobes.h
+++ b/include/asm-powerpc/kprobes.h
@@ -1,8 +1,7 @@
-#ifndef _ASM_KPROBES_H
-#define _ASM_KPROBES_H
+#ifndef _ASM_POWERPC_KPROBES_H
+#define _ASM_POWERPC_KPROBES_H
/*
* Kernel Probes (KProbes)
- * include/asm-ppc64/kprobes.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -64,4 +63,4 @@ static inline int kprobe_exceptions_notify(struct notifier_block *self,
return 0;
}
#endif
-#endif /* _ASM_KPROBES_H */
+#endif /* _ASM_POWERPC_KPROBES_H */
diff --git a/include/asm-ppc64/lmb.h b/include/asm-powerpc/lmb.h
index de91e034bd98..ea0afe343545 100644
--- a/include/asm-ppc64/lmb.h
+++ b/include/asm-powerpc/lmb.h
@@ -50,7 +50,7 @@ extern unsigned long __init lmb_alloc_base(unsigned long, unsigned long,
extern unsigned long __init lmb_phys_mem_size(void);
extern unsigned long __init lmb_end_of_DRAM(void);
extern unsigned long __init lmb_abs_to_phys(unsigned long);
-extern void __init lmb_enforce_memory_limit(void);
+extern void __init lmb_enforce_memory_limit(unsigned long);
extern void lmb_dump_all(void);
diff --git a/include/asm-ppc64/machdep.h b/include/asm-powerpc/machdep.h
index 8027160ec96d..451b345cfc78 100644
--- a/include/asm-ppc64/machdep.h
+++ b/include/asm-powerpc/machdep.h
@@ -1,6 +1,6 @@
+#ifndef _ASM_POWERPC_MACHDEP_H
+#define _ASM_POWERPC_MACHDEP_H
#ifdef __KERNEL__
-#ifndef _PPC64_MACHDEP_H
-#define _PPC64_MACHDEP_H
/*
* This program is free software; you can redistribute it and/or
@@ -16,6 +16,11 @@
#include <asm/setup.h>
+/* We export this macro for external modules like Alsa to know if
+ * ppc_md.feature_call is implemented or not
+ */
+#define CONFIG_PPC_HAS_FEATURE_CALLS
+
struct pt_regs;
struct pci_bus;
struct device_node;
@@ -39,6 +44,7 @@ struct smp_ops_t {
#endif
struct machdep_calls {
+#ifdef CONFIG_PPC64
void (*hpte_invalidate)(unsigned long slot,
unsigned long va,
int large,
@@ -56,9 +62,8 @@ struct machdep_calls {
unsigned long vflags,
unsigned long rflags);
long (*hpte_remove)(unsigned long hpte_group);
- void (*flush_hash_range)(unsigned long context,
- unsigned long number,
- int local);
+ void (*flush_hash_range)(unsigned long number, int local);
+
/* special for kexec, to be called in real mode, linar mapping is
* destroyed as well */
void (*hpte_clear_all)(void);
@@ -75,18 +80,21 @@ struct machdep_calls {
void (*iommu_dev_setup)(struct pci_dev *dev);
void (*iommu_bus_setup)(struct pci_bus *bus);
void (*irq_bus_setup)(struct pci_bus *bus);
+#endif
int (*probe)(int platform);
void (*setup_arch)(void);
void (*init_early)(void);
/* Optional, may be NULL. */
- void (*get_cpuinfo)(struct seq_file *m);
+ void (*show_cpuinfo)(struct seq_file *m);
+ void (*show_percpuinfo)(struct seq_file *m, int i);
void (*init_IRQ)(void);
int (*get_irq)(struct pt_regs *);
void (*cpu_irq_down)(int secondary);
/* PCI stuff */
+ /* Called after scanning the bus, before allocating resources */
void (*pcibios_fixup)(void);
int (*pci_probe_mode)(struct pci_bus *);
@@ -96,9 +104,13 @@ struct machdep_calls {
void (*panic)(char *str);
void (*cpu_die)(void);
+ long (*time_init)(void); /* Optional, may be NULL */
+
int (*set_rtc_time)(struct rtc_time *);
void (*get_rtc_time)(struct rtc_time *);
- void (*get_boot_time)(struct rtc_time *);
+ unsigned long (*get_boot_time)(void);
+ unsigned char (*rtc_read_val)(int addr);
+ void (*rtc_write_val)(int addr, unsigned char val);
void (*calibrate_decr)(void);
@@ -107,10 +119,12 @@ struct machdep_calls {
/* Interface for platform error logging */
void (*log_error)(char *buf, unsigned int err_type, int fatal);
+ unsigned char (*nvram_read_val)(int addr);
+ void (*nvram_write_val)(int addr, unsigned char val);
ssize_t (*nvram_write)(char *buf, size_t count, loff_t *index);
ssize_t (*nvram_read)(char *buf, size_t count, loff_t *index);
ssize_t (*nvram_size)(void);
- int (*nvram_sync)(void);
+ void (*nvram_sync)(void);
/* Exception handlers */
void (*system_reset_exception)(struct pt_regs *regs);
@@ -130,19 +144,97 @@ struct machdep_calls {
/* Get access protection for /dev/mem */
pgprot_t (*phys_mem_access_prot)(struct file *file,
- unsigned long offset,
+ unsigned long pfn,
unsigned long size,
pgprot_t vma_prot);
/* Idle loop for this platform, leave empty for default idle loop */
- int (*idle_loop)(void);
+ void (*idle_loop)(void);
- /* Function to enable pmcs for this platform, called once per cpu. */
+ /* Function to enable performance monitor counters for this
+ platform, called once per cpu. */
void (*enable_pmcs)(void);
+
+#ifdef CONFIG_PPC32 /* XXX for now */
+ /* A general init function, called by ppc_init in init/main.c.
+ May be NULL. */
+ void (*init)(void);
+
+ void (*idle)(void);
+ void (*power_save)(void);
+
+ void (*heartbeat)(void);
+ unsigned long heartbeat_reset;
+ unsigned long heartbeat_count;
+
+ void (*setup_io_mappings)(void);
+
+ void (*early_serial_map)(void);
+ void (*kgdb_map_scc)(void);
+
+ /*
+ * optional PCI "hooks"
+ */
+
+ /* Called after PPC generic resource fixup to perform
+ machine specific fixups */
+ void (*pcibios_fixup_resources)(struct pci_dev *);
+
+ /* Called for each PCI bus in the system when it's probed */
+ void (*pcibios_fixup_bus)(struct pci_bus *);
+
+ /* Called when pci_enable_device() is called (initial=0) or
+ * when a device with no assigned resource is found (initial=1).
+ * Returns 0 to allow assignment/enabling of the device. */
+ int (*pcibios_enable_device_hook)(struct pci_dev *, int initial);
+
+ /* For interrupt routing */
+ unsigned char (*pci_swizzle)(struct pci_dev *, unsigned char *);
+ int (*pci_map_irq)(struct pci_dev *, unsigned char, unsigned char);
+
+ /* Called in indirect_* to avoid touching devices */
+ int (*pci_exclude_device)(unsigned char, unsigned char);
+
+ /* Called at then very end of pcibios_init() */
+ void (*pcibios_after_init)(void);
+
+ /* this is for modules, since _machine can be a define -- Cort */
+ int ppc_machine;
+
+#ifdef CONFIG_KEXEC
+ /* Called to shutdown machine specific hardware not already controlled
+ * by other drivers.
+ * XXX Should we move this one out of kexec scope?
+ */
+ void (*machine_shutdown)(void);
+
+ /* Called to do the minimal shutdown needed to run a kexec'd kernel
+ * to run successfully.
+ * XXX Should we move this one out of kexec scope?
+ */
+ void (*machine_crash_shutdown)(void);
+
+ /* Called to do what every setup is needed on image and the
+ * reboot code buffer. Returns 0 on success.
+ * Provide your own (maybe dummy) implementation if your platform
+ * claims to support kexec.
+ */
+ int (*machine_kexec_prepare)(struct kimage *image);
+
+ /* Called to handle any machine specific cleanup on image */
+ void (*machine_kexec_cleanup)(struct kimage *image);
+
+ /* Called to perform the _real_ kexec.
+ * Do NOT allocate memory or fail here. We are past the point of
+ * no return.
+ */
+ void (*machine_kexec)(struct kimage *image);
+#endif /* CONFIG_KEXEC */
+#endif /* CONFIG_PPC32 */
};
-extern int default_idle(void);
-extern int native_idle(void);
+extern void default_idle(void);
+extern void native_idle(void);
extern struct machdep_calls ppc_md;
extern char cmd_line[COMMAND_LINE_SIZE];
@@ -162,6 +254,13 @@ extern sys_ctrler_t sys_ctrler;
#endif /* CONFIG_PPC_PMAC */
+extern void setup_pci_ptrs(void);
+
+#ifdef CONFIG_SMP
+/* Poor default implementations */
+extern void __devinit smp_generic_give_timebase(void);
+extern void __devinit smp_generic_take_timebase(void);
+#endif /* CONFIG_SMP */
/* Functions to produce codes on the leds.
@@ -181,5 +280,5 @@ static inline void log_error(char *buf, unsigned int err_type, int fatal)
ppc_md.log_error(buf, err_type, fatal);
}
-#endif /* _PPC64_MACHDEP_H */
#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_MACHDEP_H */
diff --git a/include/asm-ppc/macio.h b/include/asm-powerpc/macio.h
index b553dd4b139e..b553dd4b139e 100644
--- a/include/asm-ppc/macio.h
+++ b/include/asm-powerpc/macio.h
diff --git a/include/asm-ppc/mediabay.h b/include/asm-powerpc/mediabay.h
index 9daa3252d7b6..9daa3252d7b6 100644
--- a/include/asm-ppc/mediabay.h
+++ b/include/asm-powerpc/mediabay.h
diff --git a/arch/ppc64/kernel/mpic.h b/include/asm-powerpc/mpic.h
index ca78a7f10528..7083d1f74260 100644
--- a/arch/ppc64/kernel/mpic.h
+++ b/include/asm-powerpc/mpic.h
@@ -1,3 +1,6 @@
+#ifndef _ASM_POWERPC_MPIC_H
+#define _ASM_POWERPC_MPIC_H
+
#include <linux/irq.h>
/*
@@ -258,12 +261,21 @@ extern void mpic_setup_this_cpu(void);
/* Clean up for kexec (or cpu offline or ...) */
extern void mpic_teardown_this_cpu(int secondary);
+/* Get the current cpu priority for this cpu (0..15) */
+extern int mpic_cpu_get_priority(void);
+
+/* Set the current cpu priority for this cpu */
+extern void mpic_cpu_set_priority(int prio);
+
/* Request IPIs on primary mpic */
extern void mpic_request_ipis(void);
/* Send an IPI (non offseted number 0..3) */
extern void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask);
+/* Send a message (IPI) to a given target (cpu number or MSG_*) */
+void smp_mpic_message_pass(int target, int msg);
+
/* Fetch interrupt from a given mpic */
extern int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs);
/* This one gets to the primary mpic */
@@ -271,3 +283,5 @@ extern int mpic_get_irq(struct pt_regs *regs);
/* global mpic for pSeries */
extern struct mpic *pSeries_mpic;
+
+#endif /* _ASM_POWERPC_MPIC_H */
diff --git a/include/asm-ppc/of_device.h b/include/asm-powerpc/of_device.h
index 575bce418f80..ddb16aae0bd6 100644
--- a/include/asm-ppc/of_device.h
+++ b/include/asm-powerpc/of_device.h
@@ -1,5 +1,5 @@
-#ifndef __OF_DEVICE_H__
-#define __OF_DEVICE_H__
+#ifndef _ASM_POWERPC_OF_DEVICE_H
+#define _ASM_POWERPC_OF_DEVICE_H
#include <linux/device.h>
#include <linux/mod_devicetable.h>
@@ -61,5 +61,4 @@ extern struct of_device *of_platform_device_create(struct device_node *np,
struct device *parent);
extern void of_release_dev(struct device *dev);
-#endif /* __OF_DEVICE_H__ */
-
+#endif /* _ASM_POWERPC_OF_DEVICE_H */
diff --git a/include/asm-ppc/ohare.h b/include/asm-powerpc/ohare.h
index 023b59772231..023b59772231 100644
--- a/include/asm-ppc/ohare.h
+++ b/include/asm-powerpc/ohare.h
diff --git a/include/asm-ppc64/oprofile_impl.h b/include/asm-powerpc/oprofile_impl.h
index b04f1dfb1421..8013cd273ced 100644
--- a/include/asm-ppc64/oprofile_impl.h
+++ b/include/asm-powerpc/oprofile_impl.h
@@ -9,39 +9,49 @@
* 2 of the License, or (at your option) any later version.
*/
-#ifndef OP_IMPL_H
-#define OP_IMPL_H 1
+#ifndef _ASM_POWERPC_OPROFILE_IMPL_H
+#define _ASM_POWERPC_OPROFILE_IMPL_H
#define OP_MAX_COUNTER 8
/* Per-counter configuration as set via oprofilefs. */
struct op_counter_config {
+#ifdef __powerpc64__
unsigned long valid;
+#endif
unsigned long enabled;
unsigned long event;
unsigned long count;
unsigned long kernel;
+#ifdef __powerpc64__
/* We dont support per counter user/kernel selection */
+#endif
unsigned long user;
unsigned long unit_mask;
};
/* System-wide configuration as set via oprofilefs. */
struct op_system_config {
+#ifdef __powerpc64__
unsigned long mmcr0;
unsigned long mmcr1;
unsigned long mmcra;
+#endif
unsigned long enable_kernel;
unsigned long enable_user;
+#ifdef __powerpc64__
unsigned long backtrace_spinlocks;
+#endif
};
/* Per-arch configuration */
-struct op_ppc64_model {
+struct op_powerpc_model {
void (*reg_setup) (struct op_counter_config *,
struct op_system_config *,
int num_counters);
+#ifdef __powerpc64__
void (*cpu_setup) (void *);
+#endif
void (*start) (struct op_counter_config *);
void (*stop) (void);
void (*handle_interrupt) (struct pt_regs *,
@@ -49,8 +59,9 @@ struct op_ppc64_model {
int num_counters;
};
-extern struct op_ppc64_model op_model_rs64;
-extern struct op_ppc64_model op_model_power4;
+#ifdef __powerpc64__
+extern struct op_powerpc_model op_model_rs64;
+extern struct op_powerpc_model op_model_power4;
static inline unsigned int ctr_read(unsigned int i)
{
@@ -107,5 +118,6 @@ static inline void ctr_write(unsigned int i, unsigned int val)
break;
}
}
+#endif /* __powerpc64__ */
-#endif
+#endif /* _ASM_POWERPC_OPROFILE_IMPL_H */
diff --git a/include/asm-ppc64/pSeries_reconfig.h b/include/asm-powerpc/pSeries_reconfig.h
index c0db1ea7f7d1..c0db1ea7f7d1 100644
--- a/include/asm-ppc64/pSeries_reconfig.h
+++ b/include/asm-powerpc/pSeries_reconfig.h
diff --git a/include/asm-ppc/parport.h b/include/asm-powerpc/parport.h
index 11f96d3de5b6..d86b410a6f8b 100644
--- a/include/asm-ppc/parport.h
+++ b/include/asm-powerpc/parport.h
@@ -6,8 +6,8 @@
* This file should only be included by drivers/parport/parport_pc.c.
*/
-#ifndef _ASM_PPC_PARPORT_H
-#define _ASM_PPC_PARPORT_H
+#ifndef _ASM_POWERPC_PARPORT_H
+#define _ASM_POWERPC_PARPORT_H
static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma);
static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma)
@@ -15,4 +15,4 @@ static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma)
return parport_pc_find_isa_ports (autoirq, autodma);
}
-#endif /* !(_ASM_PPC_PARPORT_H) */
+#endif /* !(_ASM_POWERPC_PARPORT_H) */
diff --git a/include/asm-ppc/pmac_feature.h b/include/asm-powerpc/pmac_feature.h
index e9683bcff19b..e9683bcff19b 100644
--- a/include/asm-ppc/pmac_feature.h
+++ b/include/asm-powerpc/pmac_feature.h
diff --git a/include/asm-ppc/pmac_low_i2c.h b/include/asm-powerpc/pmac_low_i2c.h
index 809a5963d5e7..809a5963d5e7 100644
--- a/include/asm-ppc/pmac_low_i2c.h
+++ b/include/asm-powerpc/pmac_low_i2c.h
diff --git a/include/asm-ppc64/pmc.h b/include/asm-powerpc/pmc.h
index d1d297dbccfe..2f3c3fc2b796 100644
--- a/include/asm-ppc64/pmc.h
+++ b/include/asm-powerpc/pmc.h
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _PPC64_PMC_H
-#define _PPC64_PMC_H
+#ifndef _POWERPC_PMC_H
+#define _POWERPC_PMC_H
#include <asm/ptrace.h>
@@ -26,6 +26,21 @@ typedef void (*perf_irq_t)(struct pt_regs *);
int reserve_pmc_hardware(perf_irq_t new_perf_irq);
void release_pmc_hardware(void);
+#ifdef CONFIG_PPC64
void power4_enable_pmcs(void);
+#endif
-#endif /* _PPC64_PMC_H */
+#ifdef CONFIG_FSL_BOOKE
+void init_pmc_stop(int ctr);
+void set_pmc_event(int ctr, int event);
+void set_pmc_user_kernel(int ctr, int user, int kernel);
+void set_pmc_marked(int ctr, int mark0, int mark1);
+void pmc_start_ctr(int ctr, int enable);
+void pmc_start_ctrs(int enable);
+void pmc_stop_ctrs(void);
+void dump_pmcs(void);
+
+extern struct op_powerpc_model op_model_fsl_booke;
+#endif
+
+#endif /* _POWERPC_PMC_H */
diff --git a/include/asm-ppc64/posix_types.h b/include/asm-powerpc/posix_types.h
index 516de7201b5d..c6391077224f 100644
--- a/include/asm-ppc64/posix_types.h
+++ b/include/asm-powerpc/posix_types.h
@@ -1,44 +1,54 @@
-#ifndef _PPC64_POSIX_TYPES_H
-#define _PPC64_POSIX_TYPES_H
+#ifndef _ASM_POWERPC_POSIX_TYPES_H
+#define _ASM_POWERPC_POSIX_TYPES_H
/*
* This file is generally used by user-level software, so you need to
* be a little careful about namespace pollution etc. Also, we cannot
* assume GCC is being used.
- *
- * This program is free software; you can redistribute 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.
*/
typedef unsigned long __kernel_ino_t;
-typedef unsigned long __kernel_nlink_t;
typedef unsigned int __kernel_mode_t;
typedef long __kernel_off_t;
-typedef long long __kernel_loff_t;
typedef int __kernel_pid_t;
-typedef int __kernel_ipc_pid_t;
typedef unsigned int __kernel_uid_t;
typedef unsigned int __kernel_gid_t;
-typedef unsigned long __kernel_size_t;
-typedef long __kernel_ssize_t;
typedef long __kernel_ptrdiff_t;
typedef long __kernel_time_t;
+typedef long __kernel_clock_t;
typedef int __kernel_timer_t;
typedef int __kernel_clockid_t;
typedef long __kernel_suseconds_t;
-typedef long __kernel_clock_t;
typedef int __kernel_daddr_t;
typedef char * __kernel_caddr_t;
typedef unsigned short __kernel_uid16_t;
typedef unsigned short __kernel_gid16_t;
typedef unsigned int __kernel_uid32_t;
typedef unsigned int __kernel_gid32_t;
-
typedef unsigned int __kernel_old_uid_t;
typedef unsigned int __kernel_old_gid_t;
+
+#ifdef __powerpc64__
+typedef unsigned long __kernel_nlink_t;
+typedef int __kernel_ipc_pid_t;
+typedef unsigned long __kernel_size_t;
+typedef long __kernel_ssize_t;
typedef unsigned long __kernel_old_dev_t;
+#else
+typedef unsigned short __kernel_nlink_t;
+typedef short __kernel_ipc_pid_t;
+typedef unsigned int __kernel_size_t;
+typedef int __kernel_ssize_t;
+typedef unsigned int __kernel_old_dev_t;
+#endif
+
+#ifdef __powerpc64__
+typedef long long __kernel_loff_t;
+#else
+#ifdef __GNUC__
+typedef long long __kernel_loff_t;
+#endif
+#endif
typedef struct {
int val[2];
@@ -116,4 +126,4 @@ static __inline__ void __FD_ZERO(__kernel_fd_set *p)
#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
#endif /* __GNUC__ */
-#endif /* _PPC64_POSIX_TYPES_H */
+#endif /* _ASM_POWERPC_POSIX_TYPES_H */
diff --git a/arch/ppc64/kernel/pci.h b/include/asm-powerpc/ppc-pci.h
index 5eb2cc320566..a88728fba8f6 100644
--- a/arch/ppc64/kernel/pci.h
+++ b/include/asm-powerpc/ppc-pci.h
@@ -6,8 +6,8 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
-#ifndef __PPC_KERNEL_PCI_H__
-#define __PPC_KERNEL_PCI_H__
+#ifndef _ASM_POWERPC_PPC_PCI_H
+#define _ASM_POWERPC_PPC_PCI_H
#include <linux/pci.h>
#include <asm/pci-bridge.h>
@@ -51,4 +51,4 @@ extern unsigned long pci_probe_only;
extern unsigned long pci_assign_all_buses;
extern int pci_read_irq_line(struct pci_dev *pci_dev);
-#endif /* __PPC_KERNEL_PCI_H__ */
+#endif /* _ASM_POWERPC_PPC_PCI_H */
diff --git a/include/asm-ppc/ppc_asm.h b/include/asm-powerpc/ppc_asm.h
index bb53e2def363..f99f2af82ca5 100644
--- a/include/asm-ppc/ppc_asm.h
+++ b/include/asm-powerpc/ppc_asm.h
@@ -1,38 +1,42 @@
/*
- * include/asm-ppc/ppc_asm.h
- *
- * Definitions used by various bits of low-level assembly code on PowerPC.
- *
* Copyright (C) 1995-1999 Gary Thomas, Paul Mackerras, Cort Dougan.
- *
- * This program is free software; you can redistribute 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_POWERPC_PPC_ASM_H
+#define _ASM_POWERPC_PPC_ASM_H
+#include <linux/stringify.h>
#include <linux/config.h>
+#ifdef __ASSEMBLY__
+
/*
* Macros for storing registers into and loading registers from
* exception frames.
*/
+#ifdef __powerpc64__
+#define SAVE_GPR(n, base) std n,GPR0+8*(n)(base)
+#define REST_GPR(n, base) ld n,GPR0+8*(n)(base)
+#define SAVE_NVGPRS(base) SAVE_8GPRS(14, base); SAVE_10GPRS(22, base)
+#define REST_NVGPRS(base) REST_8GPRS(14, base); REST_10GPRS(22, base)
+#else
#define SAVE_GPR(n, base) stw n,GPR0+4*(n)(base)
+#define REST_GPR(n, base) lwz n,GPR0+4*(n)(base)
+#define SAVE_NVGPRS(base) SAVE_GPR(13, base); SAVE_8GPRS(14, base); \
+ SAVE_10GPRS(22, base)
+#define REST_NVGPRS(base) REST_GPR(13, base); REST_8GPRS(14, base); \
+ REST_10GPRS(22, base)
+#endif
+
+
#define SAVE_2GPRS(n, base) SAVE_GPR(n, base); SAVE_GPR(n+1, base)
#define SAVE_4GPRS(n, base) SAVE_2GPRS(n, base); SAVE_2GPRS(n+2, base)
#define SAVE_8GPRS(n, base) SAVE_4GPRS(n, base); SAVE_4GPRS(n+4, base)
#define SAVE_10GPRS(n, base) SAVE_8GPRS(n, base); SAVE_2GPRS(n+8, base)
-#define REST_GPR(n, base) lwz n,GPR0+4*(n)(base)
#define REST_2GPRS(n, base) REST_GPR(n, base); REST_GPR(n+1, base)
#define REST_4GPRS(n, base) REST_2GPRS(n, base); REST_2GPRS(n+2, base)
#define REST_8GPRS(n, base) REST_4GPRS(n, base); REST_4GPRS(n+4, base)
#define REST_10GPRS(n, base) REST_8GPRS(n, base); REST_2GPRS(n+8, base)
-#define SAVE_NVGPRS(base) SAVE_GPR(13, base); SAVE_8GPRS(14, base); \
- SAVE_10GPRS(22, base)
-#define REST_NVGPRS(base) REST_GPR(13, base); REST_8GPRS(14, base); \
- REST_10GPRS(22, base)
-
#define SAVE_FPR(n, base) stfd n,THREAD_FPR0+8*(n)(base)
#define SAVE_2FPRS(n, base) SAVE_FPR(n, base); SAVE_FPR(n+1, base)
#define SAVE_4FPRS(n, base) SAVE_2FPRS(n, base); SAVE_2FPRS(n+2, base)
@@ -47,32 +51,170 @@
#define REST_32FPRS(n, base) REST_16FPRS(n, base); REST_16FPRS(n+16, base)
#define SAVE_VR(n,b,base) li b,THREAD_VR0+(16*(n)); stvx n,b,base
-#define SAVE_2VR(n,b,base) SAVE_VR(n,b,base); SAVE_VR(n+1,b,base)
-#define SAVE_4VR(n,b,base) SAVE_2VR(n,b,base); SAVE_2VR(n+2,b,base)
-#define SAVE_8VR(n,b,base) SAVE_4VR(n,b,base); SAVE_4VR(n+4,b,base)
-#define SAVE_16VR(n,b,base) SAVE_8VR(n,b,base); SAVE_8VR(n+8,b,base)
-#define SAVE_32VR(n,b,base) SAVE_16VR(n,b,base); SAVE_16VR(n+16,b,base)
+#define SAVE_2VRS(n,b,base) SAVE_VR(n,b,base); SAVE_VR(n+1,b,base)
+#define SAVE_4VRS(n,b,base) SAVE_2VRS(n,b,base); SAVE_2VRS(n+2,b,base)
+#define SAVE_8VRS(n,b,base) SAVE_4VRS(n,b,base); SAVE_4VRS(n+4,b,base)
+#define SAVE_16VRS(n,b,base) SAVE_8VRS(n,b,base); SAVE_8VRS(n+8,b,base)
+#define SAVE_32VRS(n,b,base) SAVE_16VRS(n,b,base); SAVE_16VRS(n+16,b,base)
#define REST_VR(n,b,base) li b,THREAD_VR0+(16*(n)); lvx n,b,base
-#define REST_2VR(n,b,base) REST_VR(n,b,base); REST_VR(n+1,b,base)
-#define REST_4VR(n,b,base) REST_2VR(n,b,base); REST_2VR(n+2,b,base)
-#define REST_8VR(n,b,base) REST_4VR(n,b,base); REST_4VR(n+4,b,base)
-#define REST_16VR(n,b,base) REST_8VR(n,b,base); REST_8VR(n+8,b,base)
-#define REST_32VR(n,b,base) REST_16VR(n,b,base); REST_16VR(n+16,b,base)
+#define REST_2VRS(n,b,base) REST_VR(n,b,base); REST_VR(n+1,b,base)
+#define REST_4VRS(n,b,base) REST_2VRS(n,b,base); REST_2VRS(n+2,b,base)
+#define REST_8VRS(n,b,base) REST_4VRS(n,b,base); REST_4VRS(n+4,b,base)
+#define REST_16VRS(n,b,base) REST_8VRS(n,b,base); REST_8VRS(n+8,b,base)
+#define REST_32VRS(n,b,base) REST_16VRS(n,b,base); REST_16VRS(n+16,b,base)
#define SAVE_EVR(n,s,base) evmergehi s,s,n; stw s,THREAD_EVR0+4*(n)(base)
-#define SAVE_2EVR(n,s,base) SAVE_EVR(n,s,base); SAVE_EVR(n+1,s,base)
-#define SAVE_4EVR(n,s,base) SAVE_2EVR(n,s,base); SAVE_2EVR(n+2,s,base)
-#define SAVE_8EVR(n,s,base) SAVE_4EVR(n,s,base); SAVE_4EVR(n+4,s,base)
-#define SAVE_16EVR(n,s,base) SAVE_8EVR(n,s,base); SAVE_8EVR(n+8,s,base)
-#define SAVE_32EVR(n,s,base) SAVE_16EVR(n,s,base); SAVE_16EVR(n+16,s,base)
-
+#define SAVE_2EVRS(n,s,base) SAVE_EVR(n,s,base); SAVE_EVR(n+1,s,base)
+#define SAVE_4EVRS(n,s,base) SAVE_2EVRS(n,s,base); SAVE_2EVRS(n+2,s,base)
+#define SAVE_8EVRS(n,s,base) SAVE_4EVRS(n,s,base); SAVE_4EVRS(n+4,s,base)
+#define SAVE_16EVRS(n,s,base) SAVE_8EVRS(n,s,base); SAVE_8EVRS(n+8,s,base)
+#define SAVE_32EVRS(n,s,base) SAVE_16EVRS(n,s,base); SAVE_16EVRS(n+16,s,base)
#define REST_EVR(n,s,base) lwz s,THREAD_EVR0+4*(n)(base); evmergelo n,s,n
-#define REST_2EVR(n,s,base) REST_EVR(n,s,base); REST_EVR(n+1,s,base)
-#define REST_4EVR(n,s,base) REST_2EVR(n,s,base); REST_2EVR(n+2,s,base)
-#define REST_8EVR(n,s,base) REST_4EVR(n,s,base); REST_4EVR(n+4,s,base)
-#define REST_16EVR(n,s,base) REST_8EVR(n,s,base); REST_8EVR(n+8,s,base)
-#define REST_32EVR(n,s,base) REST_16EVR(n,s,base); REST_16EVR(n+16,s,base)
+#define REST_2EVRS(n,s,base) REST_EVR(n,s,base); REST_EVR(n+1,s,base)
+#define REST_4EVRS(n,s,base) REST_2EVRS(n,s,base); REST_2EVRS(n+2,s,base)
+#define REST_8EVRS(n,s,base) REST_4EVRS(n,s,base); REST_4EVRS(n+4,s,base)
+#define REST_16EVRS(n,s,base) REST_8EVRS(n,s,base); REST_8EVRS(n+8,s,base)
+#define REST_32EVRS(n,s,base) REST_16EVRS(n,s,base); REST_16EVRS(n+16,s,base)
+
+/* Macros to adjust thread priority for hardware multithreading */
+#define HMT_VERY_LOW or 31,31,31 # very low priority
+#define HMT_LOW or 1,1,1
+#define HMT_MEDIUM_LOW or 6,6,6 # medium low priority
+#define HMT_MEDIUM or 2,2,2
+#define HMT_MEDIUM_HIGH or 5,5,5 # medium high priority
+#define HMT_HIGH or 3,3,3
+
+/* handle instructions that older assemblers may not know */
+#define RFCI .long 0x4c000066 /* rfci instruction */
+#define RFDI .long 0x4c00004e /* rfdi instruction */
+#define RFMCI .long 0x4c00004c /* rfmci instruction */
+
+#ifdef CONFIG_PPC64
+
+#define XGLUE(a,b) a##b
+#define GLUE(a,b) XGLUE(a,b)
+
+#define _GLOBAL(name) \
+ .section ".text"; \
+ .align 2 ; \
+ .globl name; \
+ .globl GLUE(.,name); \
+ .section ".opd","aw"; \
+name: \
+ .quad GLUE(.,name); \
+ .quad .TOC.@tocbase; \
+ .quad 0; \
+ .previous; \
+ .type GLUE(.,name),@function; \
+GLUE(.,name):
+
+#define _KPROBE(name) \
+ .section ".kprobes.text","a"; \
+ .align 2 ; \
+ .globl name; \
+ .globl GLUE(.,name); \
+ .section ".opd","aw"; \
+name: \
+ .quad GLUE(.,name); \
+ .quad .TOC.@tocbase; \
+ .quad 0; \
+ .previous; \
+ .type GLUE(.,name),@function; \
+GLUE(.,name):
+
+#define _STATIC(name) \
+ .section ".text"; \
+ .align 2 ; \
+ .section ".opd","aw"; \
+name: \
+ .quad GLUE(.,name); \
+ .quad .TOC.@tocbase; \
+ .quad 0; \
+ .previous; \
+ .type GLUE(.,name),@function; \
+GLUE(.,name):
+
+#else /* 32-bit */
+
+#define _GLOBAL(n) \
+ .text; \
+ .stabs __stringify(n:F-1),N_FUN,0,0,n;\
+ .globl n; \
+n:
+
+#define _KPROBE(n) \
+ .section ".kprobes.text","a"; \
+ .globl n; \
+n:
+
+#endif
+
+/*
+ * LOADADDR( rn, name )
+ * loads the address of 'name' into 'rn'
+ *
+ * LOADBASE( rn, name )
+ * loads the address (possibly without the low 16 bits) of 'name' into 'rn'
+ * suitable for base+disp addressing
+ */
+#ifdef __powerpc64__
+#define LOADADDR(rn,name) \
+ lis rn,name##@highest; \
+ ori rn,rn,name##@higher; \
+ rldicr rn,rn,32,31; \
+ oris rn,rn,name##@h; \
+ ori rn,rn,name##@l
+
+#define LOADBASE(rn,name) \
+ ld rn,name@got(r2)
+
+#define OFF(name) 0
+
+#define SET_REG_TO_CONST(reg, value) \
+ lis reg,(((value)>>48)&0xFFFF); \
+ ori reg,reg,(((value)>>32)&0xFFFF); \
+ rldicr reg,reg,32,31; \
+ oris reg,reg,(((value)>>16)&0xFFFF); \
+ ori reg,reg,((value)&0xFFFF);
+
+#define SET_REG_TO_LABEL(reg, label) \
+ lis reg,(label)@highest; \
+ ori reg,reg,(label)@higher; \
+ rldicr reg,reg,32,31; \
+ oris reg,reg,(label)@h; \
+ ori reg,reg,(label)@l;
+
+/* operations for longs and pointers */
+#define LDL ld
+#define STL std
+#define CMPI cmpdi
+#define SZL 8
+
+/* offsets for stack frame layout */
+#define LRSAVE 16
+
+#else /* 32-bit */
+#define LOADADDR(rn,name) \
+ lis rn,name@ha; \
+ addi rn,rn,name@l
+
+#define LOADBASE(rn,name) \
+ lis rn,name@ha
+
+#define OFF(name) name@l
+
+/* operations for longs and pointers */
+#define LDL lwz
+#define STL stw
+#define CMPI cmpwi
+#define SZL 4
+
+/* offsets for stack frame layout */
+#define LRSAVE 4
+
+#endif
+/* various errata or part fixups */
#ifdef CONFIG_PPC601_SYNC_FIX
#define SYNC \
BEGIN_FTR_SECTION \
@@ -93,6 +235,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_601)
#define ISYNC_601
#endif
+
#ifndef CONFIG_SMP
#define TLBSYNC
#else /* CONFIG_SMP */
@@ -104,6 +247,7 @@ BEGIN_FTR_SECTION \
END_FTR_SECTION_IFCLR(CPU_FTR_601)
#endif
+
/*
* This instruction is not implemented on the PPC 603 or 601; however, on
* the 403GCX and 405GP tlbia IS defined and tlbie is not.
@@ -121,18 +265,52 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
bdnz 0b
#endif
-#ifdef CONFIG_BOOKE
+
+#ifdef CONFIG_IBM405_ERR77
+#define PPC405_ERR77(ra,rb) dcbt ra, rb;
+#define PPC405_ERR77_SYNC sync;
+#else
+#define PPC405_ERR77(ra,rb)
+#define PPC405_ERR77_SYNC
+#endif
+
+
+#ifdef CONFIG_IBM440EP_ERR42
+#define PPC440EP_ERR42 isync
+#else
+#define PPC440EP_ERR42
+#endif
+
+
+#if defined(CONFIG_BOOKE)
+#define toreal(rd)
+#define fromreal(rd)
+
#define tophys(rd,rs) \
addis rd,rs,0
#define tovirt(rd,rs) \
addis rd,rs,0
-#else /* CONFIG_BOOKE */
+#elif defined(CONFIG_PPC64)
+#define toreal(rd) /* we can access c000... in real mode */
+#define fromreal(rd)
+
+#define tophys(rd,rs) \
+ clrldi rd,rs,2
+
+#define tovirt(rd,rs) \
+ rotldi rd,rs,16; \
+ ori rd,rd,((KERNELBASE>>48)&0xFFFF);\
+ rotldi rd,rd,48
+#else
/*
* On APUS (Amiga PowerPC cpu upgrade board), we don't know the
* physical base address of RAM at compile time.
*/
+#define toreal(rd) tophys(rd,rd)
+#define fromreal(rd) tovirt(rd,rd)
+
#define tophys(rd,rs) \
0: addis rd,rs,-KERNELBASE@h; \
.section ".vtop_fixup","aw"; \
@@ -146,22 +324,11 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
.align 1; \
.long 0b; \
.previous
-#endif /* CONFIG_BOOKE */
+#endif
-/*
- * On 64-bit cpus, we use the rfid instruction instead of rfi, but
- * we then have to make sure we preserve the top 32 bits except for
- * the 64-bit mode bit, which we clear.
- */
-#ifdef CONFIG_PPC64BRIDGE
-#define FIX_SRR1(ra, rb) \
- mr rb,ra; \
- mfmsr ra; \
- clrldi ra,ra,1; /* turn off 64-bit mode */ \
- rldimi ra,rb,0,32
-#define RFI .long 0x4c000024 /* rfid instruction */
-#define MTMSRD(r) .long (0x7c000164 + ((r) << 21)) /* mtmsrd */
-#define CLR_TOP32(r) rlwinm (r),(r),0,0,31 /* clear top 32 bits */
+#ifdef CONFIG_PPC64
+#define RFI rfid
+#define MTMSRD(r) mtmsrd r
#else
#define FIX_SRR1(ra, rb)
@@ -172,24 +339,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
#endif
#define MTMSRD(r) mtmsr r
#define CLR_TOP32(r)
-#endif /* CONFIG_PPC64BRIDGE */
-
-#define RFCI .long 0x4c000066 /* rfci instruction */
-#define RFDI .long 0x4c00004e /* rfdi instruction */
-#define RFMCI .long 0x4c00004c /* rfmci instruction */
-
-#ifdef CONFIG_IBM405_ERR77
-#define PPC405_ERR77(ra,rb) dcbt ra, rb;
-#define PPC405_ERR77_SYNC sync;
-#else
-#define PPC405_ERR77(ra,rb)
-#define PPC405_ERR77_SYNC
-#endif
-
-#ifdef CONFIG_IBM440EP_ERR42
-#define PPC440EP_ERR42 isync
-#else
-#define PPC440EP_ERR42
#endif
/* The boring bits... */
@@ -277,6 +426,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
#define fr30 30
#define fr31 31
+/* AltiVec Registers (VPRs) */
+
#define vr0 0
#define vr1 1
#define vr2 2
@@ -310,6 +461,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
#define vr30 30
#define vr31 31
+/* SPE Registers (EVPRs) */
+
#define evr0 0
#define evr1 1
#define evr2 2
@@ -348,3 +501,11 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
#define N_RSYM 64
#define N_SLINE 68
#define N_SO 100
+
+#define ASM_CONST(x) x
+#else
+ #define __ASM_CONST(x) x##UL
+ #define ASM_CONST(x) __ASM_CONST(x)
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_POWERPC_PPC_ASM_H */
diff --git a/include/asm-ppc/processor.h b/include/asm-powerpc/processor.h
index b05b5d9cae20..eee954a001fd 100644
--- a/include/asm-ppc/processor.h
+++ b/include/asm-powerpc/processor.h
@@ -1,21 +1,28 @@
-#ifdef __KERNEL__
-#ifndef __ASM_PPC_PROCESSOR_H
-#define __ASM_PPC_PROCESSOR_H
+#ifndef _ASM_POWERPC_PROCESSOR_H
+#define _ASM_POWERPC_PROCESSOR_H
/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
+ * Copyright (C) 2001 PPC 64 Team, IBM Corp
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
*/
-#define current_text_addr() ({ __label__ _l; _l: &&_l;})
#include <linux/config.h>
-#include <linux/stringify.h>
+#include <asm/reg.h>
+#ifndef __ASSEMBLY__
+#include <linux/compiler.h>
#include <asm/ptrace.h>
#include <asm/types.h>
-#include <asm/mpc8xx.h>
-#include <asm/reg.h>
+#ifdef CONFIG_PPC64
+#include <asm/systemcfg.h>
+#endif
+#ifdef CONFIG_PPC32
+/* 32-bit platform types */
/* We only need to define a new _MACH_xxx for machines which are part of
* a configuration which supports more than one type of different machine.
* This is currently limited to CONFIG_PPC_MULTIPLATFORM and CHRP/PReP/PMac.
@@ -36,20 +43,6 @@
#define _CHRP_IBM 0x05 /* IBM chrp, the longtrail and longtrail 2 */
#define _CHRP_Pegasos 0x06 /* Genesi/bplan's Pegasos and Pegasos2 */
-#define _GLOBAL(n)\
- .stabs __stringify(n:F-1),N_FUN,0,0,n;\
- .globl n;\
-n:
-
-/*
- * this is the minimum allowable io space due to the location
- * of the io areas on prep (first one at 0x80000000) but
- * as soon as I get around to remapping the io areas with the BATs
- * to match the mac we can raise this. -- Cort
- */
-#define TASK_SIZE (CONFIG_TASK_SIZE)
-
-#ifndef __ASSEMBLY__
#ifdef CONFIG_PPC_MULTIPLATFORM
extern int _machine;
@@ -67,17 +60,49 @@ extern unsigned char ucBoardRevMaj, ucBoardRevMin;
#else
#define _machine 0
#endif /* CONFIG_PPC_MULTIPLATFORM */
+#endif /* CONFIG_PPC32 */
+
+#ifdef CONFIG_PPC64
+/* Platforms supported by PPC64 */
+#define PLATFORM_PSERIES 0x0100
+#define PLATFORM_PSERIES_LPAR 0x0101
+#define PLATFORM_ISERIES_LPAR 0x0201
+#define PLATFORM_LPAR 0x0001
+#define PLATFORM_POWERMAC 0x0400
+#define PLATFORM_MAPLE 0x0500
+#define PLATFORM_BPA 0x1000
+
+/* Compatibility with drivers coming from PPC32 world */
+#define _machine (systemcfg->platform)
+#define _MACH_Pmac PLATFORM_POWERMAC
+#endif
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l;})
+
+/* Macros for adjusting thread priority (hardware multi-threading) */
+#define HMT_very_low() asm volatile("or 31,31,31 # very low priority")
+#define HMT_low() asm volatile("or 1,1,1 # low priority")
+#define HMT_medium_low() asm volatile("or 6,6,6 # medium low priority")
+#define HMT_medium() asm volatile("or 2,2,2 # medium priority")
+#define HMT_medium_high() asm volatile("or 5,5,5 # medium high priority")
+#define HMT_high() asm volatile("or 3,3,3 # high priority")
+
+#ifdef __KERNEL__
+
+extern int have_of;
struct task_struct;
-void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp);
+void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp);
void release_thread(struct task_struct *);
/* Prepare to copy thread state - unlazy all lazy status */
extern void prepare_to_copy(struct task_struct *tsk);
-/*
- * Create a new kernel thread.
- */
+/* Create a new kernel thread. */
extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
/* Lazy FPU handling on uni-processor */
@@ -85,10 +110,37 @@ extern struct task_struct *last_task_used_math;
extern struct task_struct *last_task_used_altivec;
extern struct task_struct *last_task_used_spe;
+#ifdef CONFIG_PPC32
+#define TASK_SIZE (CONFIG_TASK_SIZE)
+
/* This decides where the kernel will search for a free chunk of vm
* space during mmap's.
*/
#define TASK_UNMAPPED_BASE (TASK_SIZE / 8 * 3)
+#endif
+
+#ifdef CONFIG_PPC64
+/* 64-bit user address space is 44-bits (16TB user VM) */
+#define TASK_SIZE_USER64 (0x0000100000000000UL)
+
+/*
+ * 32-bit user address space is 4GB - 1 page
+ * (this 1 page is needed so referencing of 0xFFFFFFFF generates EFAULT
+ */
+#define TASK_SIZE_USER32 (0x0000000100000000UL - (1*PAGE_SIZE))
+
+#define TASK_SIZE (test_thread_flag(TIF_32BIT) ? \
+ TASK_SIZE_USER32 : TASK_SIZE_USER64)
+
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE_USER32 (PAGE_ALIGN(TASK_SIZE_USER32 / 4))
+#define TASK_UNMAPPED_BASE_USER64 (PAGE_ALIGN(TASK_SIZE_USER64 / 4))
+
+#define TASK_UNMAPPED_BASE ((test_thread_flag(TIF_32BIT)) ? \
+ TASK_UNMAPPED_BASE_USER32 : TASK_UNMAPPED_BASE_USER64 )
+#endif
typedef struct {
unsigned long seg;
@@ -96,18 +148,32 @@ typedef struct {
struct thread_struct {
unsigned long ksp; /* Kernel stack pointer */
+#ifdef CONFIG_PPC64
+ unsigned long ksp_vsid;
+#endif
struct pt_regs *regs; /* Pointer to saved register state */
mm_segment_t fs; /* for get_fs() validation */
+#ifdef CONFIG_PPC32
void *pgdir; /* root of page-table tree */
- int fpexc_mode; /* floating-point exception mode */
signed long last_syscall;
+#endif
#if defined(CONFIG_4xx) || defined (CONFIG_BOOKE)
unsigned long dbcr0; /* debug control register values */
unsigned long dbcr1;
#endif
double fpr[32]; /* Complete floating point set */
- unsigned long fpscr_pad; /* fpr ... fpscr must be contiguous */
- unsigned long fpscr; /* Floating point status */
+ struct { /* fpr ... fpscr must be contiguous */
+
+ unsigned int pad;
+ unsigned int val; /* Floating point status */
+ } fpscr;
+ int fpexc_mode; /* floating-point exception mode */
+#ifdef CONFIG_PPC64
+ unsigned long start_tb; /* Start purr when proc switched in */
+ unsigned long accum_tb; /* Total accumilated purr for process */
+ unsigned long vdso_base; /* base of the vDSO library */
+#endif
+ unsigned long dabr; /* Data address breakpoint register */
#ifdef CONFIG_ALTIVEC
/* Complete AltiVec register set */
vector128 vr[32] __attribute((aligned(16)));
@@ -128,51 +194,58 @@ struct thread_struct {
#define INIT_SP (sizeof(init_stack) + (unsigned long) &init_stack)
+
+#ifdef CONFIG_PPC32
#define INIT_THREAD { \
.ksp = INIT_SP, \
.fs = KERNEL_DS, \
.pgdir = swapper_pg_dir, \
.fpexc_mode = MSR_FE0 | MSR_FE1, \
}
+#else
+#define INIT_THREAD { \
+ .ksp = INIT_SP, \
+ .regs = (struct pt_regs *)INIT_SP - 1, /* XXX bogus, I think */ \
+ .fs = KERNEL_DS, \
+ .fpr = {0}, \
+ .fpscr = { .val = 0, }, \
+ .fpexc_mode = MSR_FE0|MSR_FE1, \
+}
+#endif
/*
* Return saved PC of a blocked thread. For now, this is the "user" PC
*/
-#define thread_saved_pc(tsk) \
- ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0)
+#define thread_saved_pc(tsk) \
+ ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0)
unsigned long get_wchan(struct task_struct *p);
-#define KSTK_EIP(tsk) ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0)
-#define KSTK_ESP(tsk) ((tsk)->thread.regs? (tsk)->thread.regs->gpr[1]: 0)
+#define KSTK_EIP(tsk) ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0)
+#define KSTK_ESP(tsk) ((tsk)->thread.regs? (tsk)->thread.regs->gpr[1]: 0)
/* Get/set floating-point exception mode */
-#define GET_FPEXC_CTL(tsk, adr) get_fpexc_mode((tsk), (adr))
-#define SET_FPEXC_CTL(tsk, val) set_fpexc_mode((tsk), (val))
+#define GET_FPEXC_CTL(tsk, adr) get_fpexc_mode((tsk), (adr))
+#define SET_FPEXC_CTL(tsk, val) set_fpexc_mode((tsk), (val))
extern int get_fpexc_mode(struct task_struct *tsk, unsigned long adr);
extern int set_fpexc_mode(struct task_struct *tsk, unsigned int val);
-static inline unsigned int __unpack_fe01(unsigned int msr_bits)
+static inline unsigned int __unpack_fe01(unsigned long msr_bits)
{
return ((msr_bits & MSR_FE0) >> 10) | ((msr_bits & MSR_FE1) >> 8);
}
-static inline unsigned int __pack_fe01(unsigned int fpmode)
+static inline unsigned long __pack_fe01(unsigned int fpmode)
{
return ((fpmode << 10) & MSR_FE0) | ((fpmode << 8) & MSR_FE1);
}
-/* in process.c - for early bootup debug -- Cort */
-int ll_printk(const char *, ...);
-void ll_puts(const char *);
-
-/* In misc.c */
-void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
-
-#define have_of (_machine == _MACH_chrp || _machine == _MACH_Pmac)
-
+#ifdef CONFIG_PPC64
+#define cpu_relax() do { HMT_low(); HMT_medium(); barrier(); } while (0)
+#else
#define cpu_relax() barrier()
+#endif
/*
* Prefetch macros.
@@ -181,21 +254,28 @@ void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
#define ARCH_HAS_PREFETCHW
#define ARCH_HAS_SPINLOCK_PREFETCH
-extern inline void prefetch(const void *x)
+static inline void prefetch(const void *x)
{
- __asm__ __volatile__ ("dcbt 0,%0" : : "r" (x));
+ if (unlikely(!x))
+ return;
+
+ __asm__ __volatile__ ("dcbt 0,%0" : : "r" (x));
}
-extern inline void prefetchw(const void *x)
+static inline void prefetchw(const void *x)
{
- __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (x));
+ if (unlikely(!x))
+ return;
+
+ __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (x));
}
#define spin_lock_prefetch(x) prefetchw(x)
-extern int emulate_altivec(struct pt_regs *regs);
-
-#endif /* !__ASSEMBLY__ */
+#ifdef CONFIG_PPC64
+#define HAVE_ARCH_PICK_MMAP_LAYOUT
+#endif
-#endif /* __ASM_PPC_PROCESSOR_H */
#endif /* __KERNEL__ */
+#endif /* __ASSEMBLY__ */
+#endif /* _ASM_POWERPC_PROCESSOR_H */
diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h
new file mode 100644
index 000000000000..3a0104fa0462
--- /dev/null
+++ b/include/asm-powerpc/prom.h
@@ -0,0 +1,219 @@
+#ifndef _POWERPC_PROM_H
+#define _POWERPC_PROM_H
+#ifdef __KERNEL__
+
+/*
+ * Definitions for talking to the Open Firmware PROM on
+ * Power Macintosh computers.
+ *
+ * Copyright (C) 1996-2005 Paul Mackerras.
+ *
+ * Updates for PPC64 by Peter Bergner & David Engebretsen, IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <asm/atomic.h>
+
+/* Definitions used by the flattened device tree */
+#define OF_DT_HEADER 0xd00dfeed /* marker */
+#define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */
+#define OF_DT_END_NODE 0x2 /* End node */
+#define OF_DT_PROP 0x3 /* Property: name off, size,
+ * content */
+#define OF_DT_NOP 0x4 /* nop */
+#define OF_DT_END 0x9
+
+#define OF_DT_VERSION 0x10
+
+/*
+ * This is what gets passed to the kernel by prom_init or kexec
+ *
+ * The dt struct contains the device tree structure, full pathes and
+ * property contents. The dt strings contain a separate block with just
+ * the strings for the property names, and is fully page aligned and
+ * self contained in a page, so that it can be kept around by the kernel,
+ * each property name appears only once in this page (cheap compression)
+ *
+ * the mem_rsvmap contains a map of reserved ranges of physical memory,
+ * passing it here instead of in the device-tree itself greatly simplifies
+ * the job of everybody. It's just a list of u64 pairs (base/size) that
+ * ends when size is 0
+ */
+struct boot_param_header
+{
+ u32 magic; /* magic word OF_DT_HEADER */
+ u32 totalsize; /* total size of DT block */
+ u32 off_dt_struct; /* offset to structure */
+ u32 off_dt_strings; /* offset to strings */
+ u32 off_mem_rsvmap; /* offset to memory reserve map */
+ u32 version; /* format version */
+ u32 last_comp_version; /* last compatible version */
+ /* version 2 fields below */
+ u32 boot_cpuid_phys; /* Physical CPU id we're booting on */
+ /* version 3 fields below */
+ u32 dt_strings_size; /* size of the DT strings block */
+};
+
+
+
+typedef u32 phandle;
+typedef u32 ihandle;
+
+struct address_range {
+ unsigned long space;
+ unsigned long address;
+ unsigned long size;
+};
+
+struct interrupt_info {
+ int line;
+ int sense; /* +ve/-ve logic, edge or level, etc. */
+};
+
+struct pci_address {
+ u32 a_hi;
+ u32 a_mid;
+ u32 a_lo;
+};
+
+struct isa_address {
+ u32 a_hi;
+ u32 a_lo;
+};
+
+struct isa_range {
+ struct isa_address isa_addr;
+ struct pci_address pci_addr;
+ unsigned int size;
+};
+
+struct reg_property {
+ unsigned long address;
+ unsigned long size;
+};
+
+struct reg_property32 {
+ unsigned int address;
+ unsigned int size;
+};
+
+struct reg_property64 {
+ u64 address;
+ u64 size;
+};
+
+struct property {
+ char *name;
+ int length;
+ unsigned char *value;
+ struct property *next;
+};
+
+struct device_node {
+ char *name;
+ char *type;
+ phandle node;
+ phandle linux_phandle;
+ int n_addrs;
+ struct address_range *addrs;
+ int n_intrs;
+ struct interrupt_info *intrs;
+ char *full_name;
+
+ struct property *properties;
+ struct device_node *parent;
+ struct device_node *child;
+ struct device_node *sibling;
+ struct device_node *next; /* next device of same type */
+ struct device_node *allnext; /* next in list of all nodes */
+ struct proc_dir_entry *pde; /* this node's proc directory */
+ struct kref kref;
+ unsigned long _flags;
+ void *data;
+};
+
+extern struct device_node *of_chosen;
+
+/* flag descriptions */
+#define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */
+
+#define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags)
+#define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags)
+
+#define HAVE_ARCH_DEVTREE_FIXUPS
+
+static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_entry *de)
+{
+ dn->pde = de;
+}
+
+
+/* OBSOLETE: Old style node lookup */
+extern struct device_node *find_devices(const char *name);
+extern struct device_node *find_type_devices(const char *type);
+extern struct device_node *find_path_device(const char *path);
+extern struct device_node *find_compatible_devices(const char *type,
+ const char *compat);
+extern struct device_node *find_all_nodes(void);
+
+/* New style node lookup */
+extern struct device_node *of_find_node_by_name(struct device_node *from,
+ const char *name);
+extern struct device_node *of_find_node_by_type(struct device_node *from,
+ const char *type);
+extern struct device_node *of_find_compatible_node(struct device_node *from,
+ const char *type, const char *compat);
+extern struct device_node *of_find_node_by_path(const char *path);
+extern struct device_node *of_find_node_by_phandle(phandle handle);
+extern struct device_node *of_find_all_nodes(struct device_node *prev);
+extern struct device_node *of_get_parent(const struct device_node *node);
+extern struct device_node *of_get_next_child(const struct device_node *node,
+ struct device_node *prev);
+extern struct device_node *of_node_get(struct device_node *node);
+extern void of_node_put(struct device_node *node);
+
+/* For updating the device tree at runtime */
+extern void of_attach_node(struct device_node *);
+extern void of_detach_node(const struct device_node *);
+
+/* Other Prototypes */
+extern void finish_device_tree(void);
+extern void unflatten_device_tree(void);
+extern void early_init_devtree(void *);
+extern int device_is_compatible(struct device_node *device, const char *);
+extern int machine_is_compatible(const char *compat);
+extern unsigned char *get_property(struct device_node *node, const char *name,
+ int *lenp);
+extern void print_properties(struct device_node *node);
+extern int prom_n_addr_cells(struct device_node* np);
+extern int prom_n_size_cells(struct device_node* np);
+extern int prom_n_intr_cells(struct device_node* np);
+extern void prom_get_irq_senses(unsigned char *senses, int off, int max);
+extern void prom_add_property(struct device_node* np, struct property* prop);
+
+#ifdef CONFIG_PPC32
+/*
+ * PCI <-> OF matching functions
+ * (XXX should these be here?)
+ */
+struct pci_bus;
+struct pci_dev;
+extern int pci_device_from_OF_node(struct device_node *node,
+ u8* bus, u8* devfn);
+extern struct device_node* pci_busdev_to_OF_node(struct pci_bus *, int);
+extern struct device_node* pci_device_to_OF_node(struct pci_dev *);
+extern void pci_create_OF_bus_map(void);
+#endif
+
+extern struct resource *request_OF_resource(struct device_node* node,
+ int index, const char* name_postfix);
+extern int release_OF_resource(struct device_node* node, int index);
+
+#endif /* __KERNEL__ */
+#endif /* _POWERPC_PROM_H */
diff --git a/include/asm-ppc/reg.h b/include/asm-powerpc/reg.h
index 73c33e3ef9c6..da848412f11b 100644
--- a/include/asm-ppc/reg.h
+++ b/include/asm-powerpc/reg.h
@@ -6,53 +6,107 @@
* Implementations of the PowerPC Architecture (a.k.a. Green Book) here.
*/
+#ifndef _ASM_POWERPC_REG_H
+#define _ASM_POWERPC_REG_H
#ifdef __KERNEL__
-#ifndef __ASM_PPC_REGS_H__
-#define __ASM_PPC_REGS_H__
#include <linux/stringify.h>
+#include <asm/cputable.h>
/* Pickup Book E specific registers. */
#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
#include <asm/reg_booke.h>
#endif
-/* Machine State Register (MSR) Fields */
-#define MSR_SF (1<<63)
-#define MSR_ISF (1<<61)
-#define MSR_VEC (1<<25) /* Enable AltiVec */
-#define MSR_POW (1<<18) /* Enable Power Management */
-#define MSR_WE (1<<18) /* Wait State Enable */
-#define MSR_TGPR (1<<17) /* TLB Update registers in use */
-#define MSR_CE (1<<17) /* Critical Interrupt Enable */
-#define MSR_ILE (1<<16) /* Interrupt Little Endian */
-#define MSR_EE (1<<15) /* External Interrupt Enable */
-#define MSR_PR (1<<14) /* Problem State / Privilege Level */
-#define MSR_FP (1<<13) /* Floating Point enable */
-#define MSR_ME (1<<12) /* Machine Check Enable */
-#define MSR_FE0 (1<<11) /* Floating Exception mode 0 */
-#define MSR_SE (1<<10) /* Single Step */
-#define MSR_BE (1<<9) /* Branch Trace */
-#define MSR_DE (1<<9) /* Debug Exception Enable */
-#define MSR_FE1 (1<<8) /* Floating Exception mode 1 */
-#define MSR_IP (1<<6) /* Exception prefix 0x000/0xFFF */
-#define MSR_IR (1<<5) /* Instruction Relocate */
-#define MSR_DR (1<<4) /* Data Relocate */
-#define MSR_PE (1<<3) /* Protection Enable */
-#define MSR_PX (1<<2) /* Protection Exclusive Mode */
-#define MSR_RI (1<<1) /* Recoverable Exception */
-#define MSR_LE (1<<0) /* Little Endian */
+#define MSR_SF_LG 63 /* Enable 64 bit mode */
+#define MSR_ISF_LG 61 /* Interrupt 64b mode valid on 630 */
+#define MSR_HV_LG 60 /* Hypervisor state */
+#define MSR_VEC_LG 25 /* Enable AltiVec */
+#define MSR_POW_LG 18 /* Enable Power Management */
+#define MSR_WE_LG 18 /* Wait State Enable */
+#define MSR_TGPR_LG 17 /* TLB Update registers in use */
+#define MSR_CE_LG 17 /* Critical Interrupt Enable */
+#define MSR_ILE_LG 16 /* Interrupt Little Endian */
+#define MSR_EE_LG 15 /* External Interrupt Enable */
+#define MSR_PR_LG 14 /* Problem State / Privilege Level */
+#define MSR_FP_LG 13 /* Floating Point enable */
+#define MSR_ME_LG 12 /* Machine Check Enable */
+#define MSR_FE0_LG 11 /* Floating Exception mode 0 */
+#define MSR_SE_LG 10 /* Single Step */
+#define MSR_BE_LG 9 /* Branch Trace */
+#define MSR_DE_LG 9 /* Debug Exception Enable */
+#define MSR_FE1_LG 8 /* Floating Exception mode 1 */
+#define MSR_IP_LG 6 /* Exception prefix 0x000/0xFFF */
+#define MSR_IR_LG 5 /* Instruction Relocate */
+#define MSR_DR_LG 4 /* Data Relocate */
+#define MSR_PE_LG 3 /* Protection Enable */
+#define MSR_PX_LG 2 /* Protection Exclusive Mode */
+#define MSR_PMM_LG 2 /* Performance monitor */
+#define MSR_RI_LG 1 /* Recoverable Exception */
+#define MSR_LE_LG 0 /* Little Endian */
+#ifdef __ASSEMBLY__
+#define __MASK(X) (1<<(X))
+#else
+#define __MASK(X) (1UL<<(X))
+#endif
+
+#ifdef CONFIG_PPC64
+#define MSR_SF __MASK(MSR_SF_LG) /* Enable 64 bit mode */
+#define MSR_ISF __MASK(MSR_ISF_LG) /* Interrupt 64b mode valid on 630 */
+#define MSR_HV __MASK(MSR_HV_LG) /* Hypervisor state */
+#else
+/* so tests for these bits fail on 32-bit */
+#define MSR_SF 0
+#define MSR_ISF 0
+#define MSR_HV 0
+#endif
+
+#define MSR_VEC __MASK(MSR_VEC_LG) /* Enable AltiVec */
+#define MSR_POW __MASK(MSR_POW_LG) /* Enable Power Management */
+#define MSR_WE __MASK(MSR_WE_LG) /* Wait State Enable */
+#define MSR_TGPR __MASK(MSR_TGPR_LG) /* TLB Update registers in use */
+#define MSR_CE __MASK(MSR_CE_LG) /* Critical Interrupt Enable */
+#define MSR_ILE __MASK(MSR_ILE_LG) /* Interrupt Little Endian */
+#define MSR_EE __MASK(MSR_EE_LG) /* External Interrupt Enable */
+#define MSR_PR __MASK(MSR_PR_LG) /* Problem State / Privilege Level */
+#define MSR_FP __MASK(MSR_FP_LG) /* Floating Point enable */
+#define MSR_ME __MASK(MSR_ME_LG) /* Machine Check Enable */
+#define MSR_FE0 __MASK(MSR_FE0_LG) /* Floating Exception mode 0 */
+#define MSR_SE __MASK(MSR_SE_LG) /* Single Step */
+#define MSR_BE __MASK(MSR_BE_LG) /* Branch Trace */
+#define MSR_DE __MASK(MSR_DE_LG) /* Debug Exception Enable */
+#define MSR_FE1 __MASK(MSR_FE1_LG) /* Floating Exception mode 1 */
+#define MSR_IP __MASK(MSR_IP_LG) /* Exception prefix 0x000/0xFFF */
+#define MSR_IR __MASK(MSR_IR_LG) /* Instruction Relocate */
+#define MSR_DR __MASK(MSR_DR_LG) /* Data Relocate */
+#define MSR_PE __MASK(MSR_PE_LG) /* Protection Enable */
+#define MSR_PX __MASK(MSR_PX_LG) /* Protection Exclusive Mode */
+#ifndef MSR_PMM
+#define MSR_PMM __MASK(MSR_PMM_LG) /* Performance monitor */
+#endif
+#define MSR_RI __MASK(MSR_RI_LG) /* Recoverable Exception */
+#define MSR_LE __MASK(MSR_LE_LG) /* Little Endian */
+
+#ifdef CONFIG_PPC64
+#define MSR_ MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_ISF
+#define MSR_KERNEL MSR_ | MSR_SF | MSR_HV
+
+#define MSR_USER32 MSR_ | MSR_PR | MSR_EE
+#define MSR_USER64 MSR_USER32 | MSR_SF
+
+#else /* 32-bit */
/* Default MSR for kernel mode. */
+#ifndef MSR_KERNEL /* reg_booke.h also defines this */
#ifdef CONFIG_APUS_FAST_EXCEPT
#define MSR_KERNEL (MSR_ME|MSR_IP|MSR_RI|MSR_IR|MSR_DR)
-#endif
-
-#ifndef MSR_KERNEL
+#else
#define MSR_KERNEL (MSR_ME|MSR_RI|MSR_IR|MSR_DR)
#endif
+#endif
#define MSR_USER (MSR_KERNEL|MSR_PR|MSR_EE)
+#endif
/* Floating Point Status and Control Register (FPSCR) Fields */
#define FPSCR_FX 0x80000000 /* FPU exception summary */
@@ -60,7 +114,7 @@
#define FPSCR_VX 0x20000000 /* Invalid operation summary */
#define FPSCR_OX 0x10000000 /* Overflow exception summary */
#define FPSCR_UX 0x08000000 /* Underflow exception summary */
-#define FPSCR_ZX 0x04000000 /* Zero-devide exception summary */
+#define FPSCR_ZX 0x04000000 /* Zero-divide exception summary */
#define FPSCR_XX 0x02000000 /* Inexact exception summary */
#define FPSCR_VXSNAN 0x01000000 /* Invalid op for SNaN */
#define FPSCR_VXISI 0x00800000 /* Invalid op for Inv - Inv */
@@ -85,8 +139,18 @@
/* Special Purpose Registers (SPRNs)*/
#define SPRN_CTR 0x009 /* Count Register */
+#define SPRN_CTRLF 0x088
+#define SPRN_CTRLT 0x098
+#define CTRL_RUNLATCH 0x1
#define SPRN_DABR 0x3F5 /* Data Address Breakpoint Register */
+#define DABR_TRANSLATION (1UL << 2)
#define SPRN_DAR 0x013 /* Data Address Register */
+#define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */
+#define DSISR_NOHPTE 0x40000000 /* no translation found */
+#define DSISR_PROTFAULT 0x08000000 /* protection fault */
+#define DSISR_ISSTORE 0x02000000 /* access was a store */
+#define DSISR_DABRMATCH 0x00400000 /* hit data breakpoint */
+#define DSISR_NOSEGMENT 0x00200000 /* STAB/SLB miss */
#define SPRN_TBRL 0x10C /* Time Base Read Lower Register (user, R/O) */
#define SPRN_TBRU 0x10D /* Time Base Read Upper Register (user, R/O) */
#define SPRN_TBWL 0x11C /* Time Base Lower Register (super, R/W) */
@@ -131,7 +195,6 @@
#define DER_EBRKE 0x00000002 /* External Breakpoint Interrupt */
#define DER_DPIE 0x00000001 /* Dev. Port Nonmaskable Request */
#define SPRN_DMISS 0x3D0 /* Data TLB Miss Register */
-#define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */
#define SPRN_EAR 0x11A /* External Address Register */
#define SPRN_HASH1 0x3D2 /* Primary Hash Address Register */
#define SPRN_HASH2 0x3D3 /* Secondary Hash Address Resgister */
@@ -187,6 +250,16 @@
#define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */
#define SPRN_HID4 0x3F4 /* 970 HID4 */
#define SPRN_HID5 0x3F6 /* 970 HID5 */
+#define SPRN_HID6 0x3F9 /* BE HID 6 */
+#define HID6_LB (0x0F<<12) /* Concurrent Large Page Modes */
+#define HID6_DLP (1<<20) /* Disable all large page modes (4K only) */
+#define SPRN_TSCR 0x399 /* Thread switch control on BE */
+#define SPRN_TTR 0x39A /* Thread switch timeout on BE */
+#define TSCR_DEC_ENABLE 0x200000 /* Decrementer Interrupt */
+#define TSCR_EE_ENABLE 0x100000 /* External Interrupt */
+#define TSCR_EE_BOOST 0x080000 /* External Interrupt Boost */
+#define SPRN_TSC 0x3FD /* Thread switch control on others */
+#define SPRN_TST 0x3FC /* Thread switch timeout on others */
#if !defined(SPRN_IAC1) && !defined(SPRN_IAC2)
#define SPRN_IAC1 0x3F4 /* Instruction Address Compare 1 */
#define SPRN_IAC2 0x3F5 /* Instruction Address Compare 2 */
@@ -270,22 +343,18 @@
#define L3CR_L3DO 0x00000040 /* L3 data only mode */
#define L3CR_PMEN 0x00000004 /* L3 private memory enable */
#define L3CR_PMSIZ 0x00000001 /* L3 private memory size */
+
#define SPRN_MSSCR0 0x3f6 /* Memory Subsystem Control Register 0 */
#define SPRN_MSSSR0 0x3f7 /* Memory Subsystem Status Register 1 */
#define SPRN_LDSTCR 0x3f8 /* Load/Store control register */
#define SPRN_LDSTDB 0x3f4 /* */
#define SPRN_LR 0x008 /* Link Register */
-#define SPRN_MMCR0 0x3B8 /* Monitor Mode Control Register 0 */
-#define SPRN_MMCR1 0x3BC /* Monitor Mode Control Register 1 */
#ifndef SPRN_PIR
#define SPRN_PIR 0x3FF /* Processor Identification Register */
#endif
-#define SPRN_PMC1 0x3B9 /* Performance Counter Register 1 */
-#define SPRN_PMC2 0x3BA /* Performance Counter Register 2 */
-#define SPRN_PMC3 0x3BD /* Performance Counter Register 3 */
-#define SPRN_PMC4 0x3BE /* Performance Counter Register 4 */
#define SPRN_PTEHI 0x3D5 /* 981 7450 PTE HI word (S/W TLB load) */
#define SPRN_PTELO 0x3D6 /* 982 7450 PTE LO word (S/W TLB load) */
+#define SPRN_PURR 0x135 /* Processor Utilization of Resources Reg */
#define SPRN_PVR 0x11F /* Processor Version Register */
#define SPRN_RPA 0x3D6 /* Required Physical Address Register */
#define SPRN_SDA 0x3BF /* Sampled Data Address Register */
@@ -327,6 +396,52 @@
#define SPRN_VRSAVE 0x100 /* Vector Register Save Register */
#define SPRN_XER 0x001 /* Fixed Point Exception Register */
+/* Performance monitor SPRs */
+#ifdef CONFIG_PPC64
+#define SPRN_MMCR0 795
+#define MMCR0_FC 0x80000000UL /* freeze counters */
+#define MMCR0_FCS 0x40000000UL /* freeze in supervisor state */
+#define MMCR0_KERNEL_DISABLE MMCR0_FCS
+#define MMCR0_FCP 0x20000000UL /* freeze in problem state */
+#define MMCR0_PROBLEM_DISABLE MMCR0_FCP
+#define MMCR0_FCM1 0x10000000UL /* freeze counters while MSR mark = 1 */
+#define MMCR0_FCM0 0x08000000UL /* freeze counters while MSR mark = 0 */
+#define MMCR0_PMXE 0x04000000UL /* performance monitor exception enable */
+#define MMCR0_FCECE 0x02000000UL /* freeze ctrs on enabled cond or event */
+#define MMCR0_TBEE 0x00400000UL /* time base exception enable */
+#define MMCR0_PMC1CE 0x00008000UL /* PMC1 count enable*/
+#define MMCR0_PMCjCE 0x00004000UL /* PMCj count enable*/
+#define MMCR0_TRIGGER 0x00002000UL /* TRIGGER enable */
+#define MMCR0_PMAO 0x00000080UL /* performance monitor alert has occurred, set to 0 after handling exception */
+#define MMCR0_SHRFC 0x00000040UL /* SHRre freeze conditions between threads */
+#define MMCR0_FCTI 0x00000008UL /* freeze counters in tags inactive mode */
+#define MMCR0_FCTA 0x00000004UL /* freeze counters in tags active mode */
+#define MMCR0_FCWAIT 0x00000002UL /* freeze counter in WAIT state */
+#define MMCR0_FCHV 0x00000001UL /* freeze conditions in hypervisor mode */
+#define SPRN_MMCR1 798
+#define SPRN_MMCRA 0x312
+#define MMCRA_SIHV 0x10000000UL /* state of MSR HV when SIAR set */
+#define MMCRA_SIPR 0x08000000UL /* state of MSR PR when SIAR set */
+#define MMCRA_SAMPLE_ENABLE 0x00000001UL /* enable sampling */
+#define SPRN_PMC1 787
+#define SPRN_PMC2 788
+#define SPRN_PMC3 789
+#define SPRN_PMC4 790
+#define SPRN_PMC5 791
+#define SPRN_PMC6 792
+#define SPRN_PMC7 793
+#define SPRN_PMC8 794
+#define SPRN_SIAR 780
+#define SPRN_SDAR 781
+
+#else /* 32-bit */
+#define SPRN_MMCR0 0x3B8 /* Monitor Mode Control Register 0 */
+#define SPRN_MMCR1 0x3BC /* Monitor Mode Control Register 1 */
+#define SPRN_PMC1 0x3B9 /* Performance Counter Register 1 */
+#define SPRN_PMC2 0x3BA /* Performance Counter Register 2 */
+#define SPRN_PMC3 0x3BD /* Performance Counter Register 3 */
+#define SPRN_PMC4 0x3BE /* Performance Counter Register 4 */
+
/* Bit definitions for MMCR0 and PMC1 / PMC2. */
#define MMCR0_PMC1_CYCLES (1 << 7)
#define MMCR0_PMC1_ICACHEMISS (5 << 7)
@@ -336,14 +451,15 @@
#define MMCR0_PMC2_ITLB 0x7
#define MMCR0_PMC2_LOADMISSTIME 0x5
#define MMCR0_PMXE (1 << 26)
-
-/* Processor Version Register */
+#endif
/* Processor Version Register (PVR) field extraction */
#define PVR_VER(pvr) (((pvr) >> 16) & 0xFFFF) /* Version field */
#define PVR_REV(pvr) (((pvr) >> 0) & 0xFFFF) /* Revison field */
+#define __is_processor(pv) (PVR_VER(mfspr(SPRN_PVR)) == (pv))
+
/*
* IBM has further subdivided the standard PowerPC 16-bit version and
* revision subfields of the PVR for the PowerPC 403s into the following:
@@ -399,42 +515,99 @@
#define PVR_8245 0x80811014
#define PVR_8260 PVR_8240
-#if 0
-/* Segment Registers */
-#define SR0 0
-#define SR1 1
-#define SR2 2
-#define SR3 3
-#define SR4 4
-#define SR5 5
-#define SR6 6
-#define SR7 7
-#define SR8 8
-#define SR9 9
-#define SR10 10
-#define SR11 11
-#define SR12 12
-#define SR13 13
-#define SR14 14
-#define SR15 15
-#endif
+/* 64-bit processors */
+/* XXX the prefix should be PVR_, we'll do a global sweep to fix it one day */
+#define PV_NORTHSTAR 0x0033
+#define PV_PULSAR 0x0034
+#define PV_POWER4 0x0035
+#define PV_ICESTAR 0x0036
+#define PV_SSTAR 0x0037
+#define PV_POWER4p 0x0038
+#define PV_970 0x0039
+#define PV_POWER5 0x003A
+#define PV_POWER5p 0x003B
+#define PV_970FX 0x003C
+#define PV_630 0x0040
+#define PV_630p 0x0041
+#define PV_970MP 0x0044
+#define PV_BE 0x0070
+
+/*
+ * Number of entries in the SLB. If this ever changes we should handle
+ * it with a use a cpu feature fixup.
+ */
+#define SLB_NUM_ENTRIES 64
/* Macros for setting and retrieving special purpose registers */
#ifndef __ASSEMBLY__
-#define mfmsr() ({unsigned int rval; \
+#define mfmsr() ({unsigned long rval; \
asm volatile("mfmsr %0" : "=r" (rval)); rval;})
+#ifdef CONFIG_PPC64
+#define __mtmsrd(v, l) asm volatile("mtmsrd %0," __stringify(l) \
+ : : "r" (v))
+#define mtmsrd(v) __mtmsrd((v), 0)
+#define mtmsr(v) mtmsrd(v)
+#else
#define mtmsr(v) asm volatile("mtmsr %0" : : "r" (v))
+#endif
-#define mfspr(rn) ({unsigned int rval; \
+#define mfspr(rn) ({unsigned long rval; \
asm volatile("mfspr %0," __stringify(rn) \
: "=r" (rval)); rval;})
#define mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : : "r" (v))
+#define mftb() ({unsigned long rval; \
+ asm volatile("mftb %0" : "=r" (rval)); rval;})
+#define mftbl() ({unsigned long rval; \
+ asm volatile("mftbl %0" : "=r" (rval)); rval;})
+
+#define mttbl(v) asm volatile("mttbl %0":: "r"(v))
+#define mttbu(v) asm volatile("mttbu %0":: "r"(v))
+
+#ifdef CONFIG_PPC32
#define mfsrin(v) ({unsigned int rval; \
asm volatile("mfsrin %0,%1" : "=r" (rval) : "r" (v)); \
rval;})
+#endif
#define proc_trap() asm volatile("trap")
+
+#ifdef CONFIG_PPC64
+static inline void ppc64_runlatch_on(void)
+{
+ unsigned long ctrl;
+
+ if (cpu_has_feature(CPU_FTR_CTRL)) {
+ ctrl = mfspr(SPRN_CTRLF);
+ ctrl |= CTRL_RUNLATCH;
+ mtspr(SPRN_CTRLT, ctrl);
+ }
+}
+
+static inline void ppc64_runlatch_off(void)
+{
+ unsigned long ctrl;
+
+ if (cpu_has_feature(CPU_FTR_CTRL)) {
+ ctrl = mfspr(SPRN_CTRLF);
+ ctrl &= ~CTRL_RUNLATCH;
+ mtspr(SPRN_CTRLT, ctrl);
+ }
+}
+#endif
+
+#define __get_SP() ({unsigned long sp; \
+ asm volatile("mr %0,1": "=r" (sp)); sp;})
+
+#else /* __ASSEMBLY__ */
+
+#define RUNLATCH_ON(REG) \
+BEGIN_FTR_SECTION \
+ mfspr (REG),SPRN_CTRLF; \
+ ori (REG),(REG),CTRL_RUNLATCH; \
+ mtspr SPRN_CTRLT,(REG); \
+END_FTR_SECTION_IFSET(CPU_FTR_CTRL)
+
#endif /* __ASSEMBLY__ */
-#endif /* __ASM_PPC_REGS_H__ */
#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_REG_H */
diff --git a/include/asm-ppc64/rtas.h b/include/asm-powerpc/rtas.h
index e7d1b5222802..2c050332471d 100644
--- a/include/asm-ppc64/rtas.h
+++ b/include/asm-powerpc/rtas.h
@@ -1,5 +1,5 @@
-#ifndef _PPC64_RTAS_H
-#define _PPC64_RTAS_H
+#ifndef _POWERPC_RTAS_H
+#define _POWERPC_RTAS_H
#include <linux/spinlock.h>
#include <asm/page.h>
@@ -190,7 +190,7 @@ extern void rtas_progress(char *s, unsigned short hex);
extern void rtas_initialize(void);
struct rtc_time;
-extern void rtas_get_boot_time(struct rtc_time *rtc_time);
+extern unsigned long rtas_get_boot_time(void);
extern void rtas_get_rtc_time(struct rtc_time *rtc_time);
extern int rtas_set_rtc_time(struct rtc_time *rtc_time);
@@ -246,4 +246,4 @@ extern unsigned long rtas_rmo_buf;
#define GLOBAL_INTERRUPT_QUEUE 9005
-#endif /* _PPC64_RTAS_H */
+#endif /* _POWERPC_RTAS_H */
diff --git a/include/asm-powerpc/rtc.h b/include/asm-powerpc/rtc.h
new file mode 100644
index 000000000000..f5802926b6c0
--- /dev/null
+++ b/include/asm-powerpc/rtc.h
@@ -0,0 +1,78 @@
+/*
+ * Real-time clock definitions and interfaces
+ *
+ * Author: Tom Rini <trini@mvista.com>
+ *
+ * 2002 (c) MontaVista, Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Based on:
+ * include/asm-m68k/rtc.h
+ *
+ * Copyright Richard Zidlicky
+ * implementation details for genrtc/q40rtc driver
+ *
+ * And the old drivers/macintosh/rtc.c which was heavily based on:
+ * Linux/SPARC Real Time Clock Driver
+ * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
+ *
+ * With additional work by Paul Mackerras and Franz Sirl.
+ */
+
+#ifndef __ASM_POWERPC_RTC_H__
+#define __ASM_POWERPC_RTC_H__
+
+#ifdef __KERNEL__
+
+#include <linux/rtc.h>
+
+#include <asm/machdep.h>
+#include <asm/time.h>
+
+#define RTC_PIE 0x40 /* periodic interrupt enable */
+#define RTC_AIE 0x20 /* alarm interrupt enable */
+#define RTC_UIE 0x10 /* update-finished interrupt enable */
+
+/* some dummy definitions */
+#define RTC_BATT_BAD 0x100 /* battery bad */
+#define RTC_SQWE 0x08 /* enable square-wave output */
+#define RTC_DM_BINARY 0x04 /* all time/date values are BCD if clear */
+#define RTC_24H 0x02 /* 24 hour mode - else hours bit 7 means pm */
+#define RTC_DST_EN 0x01 /* auto switch DST - works f. USA only */
+
+static inline unsigned int get_rtc_time(struct rtc_time *time)
+{
+ if (ppc_md.get_rtc_time)
+ ppc_md.get_rtc_time(time);
+ return RTC_24H;
+}
+
+/* Set the current date and time in the real time clock. */
+static inline int set_rtc_time(struct rtc_time *time)
+{
+ if (ppc_md.set_rtc_time)
+ return ppc_md.set_rtc_time(time);
+ return -EINVAL;
+}
+
+static inline unsigned int get_rtc_ss(void)
+{
+ struct rtc_time h;
+
+ get_rtc_time(&h);
+ return h.tm_sec;
+}
+
+static inline int get_rtc_pll(struct rtc_pll_info *pll)
+{
+ return -EINVAL;
+}
+static inline int set_rtc_pll(struct rtc_pll_info *pll)
+{
+ return -EINVAL;
+}
+
+#endif /* __KERNEL__ */
+#endif /* __ASM_POWERPC_RTC_H__ */
diff --git a/include/asm-ppc64/rwsem.h b/include/asm-powerpc/rwsem.h
index bd5c2f093575..79bae4933b73 100644
--- a/include/asm-ppc64/rwsem.h
+++ b/include/asm-powerpc/rwsem.h
@@ -1,18 +1,14 @@
+#ifndef _ASM_POWERPC_RWSEM_H
+#define _ASM_POWERPC_RWSEM_H
+
+#ifdef __KERNEL__
+
/*
* include/asm-ppc64/rwsem.h: R/W semaphores for PPC using the stuff
* in lib/rwsem.c. Adapted largely from include/asm-i386/rwsem.h
* by Paul Mackerras <paulus@samba.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.
*/
-#ifndef _PPC64_RWSEM_H
-#define _PPC64_RWSEM_H
-
-#ifdef __KERNEL__
#include <linux/list.h>
#include <linux/spinlock.h>
#include <asm/atomic.h>
@@ -163,5 +159,10 @@ static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
return atomic_add_return(delta, (atomic_t *)(&sem->count));
}
-#endif /* __KERNEL__ */
-#endif /* _PPC_RWSEM_XADD_H */
+static inline int rwsem_is_locked(struct rw_semaphore *sem)
+{
+ return (sem->count != 0);
+}
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_RWSEM_H */
diff --git a/include/asm-ppc64/scatterlist.h b/include/asm-powerpc/scatterlist.h
index cecce6c6dfbb..8c992d1491d4 100644
--- a/include/asm-ppc64/scatterlist.h
+++ b/include/asm-powerpc/scatterlist.h
@@ -1,6 +1,5 @@
-#ifndef _PPC64_SCATTERLIST_H
-#define _PPC64_SCATTERLIST_H
-
+#ifndef _ASM_POWERPC_SCATTERLIST_H
+#define _ASM_POWERPC_SCATTERLIST_H
/*
* Copyright (C) 2001 PPC64 Team, IBM Corp
*
@@ -10,6 +9,7 @@
* 2 of the License, or (at your option) any later version.
*/
+#ifdef __KERNEL__
#include <linux/types.h>
#include <asm/dma.h>
@@ -19,13 +19,27 @@ struct scatterlist {
unsigned int length;
/* For TCE support */
- u32 dma_address;
+ dma_addr_t dma_address;
u32 dma_length;
};
+/*
+ * These macros should be used after a dma_map_sg call has been done
+ * to get bus addresses of each of the SG entries and their lengths.
+ * You should only work with the number of sg entries pci_map_sg
+ * returns, or alternatively stop on the first sg_dma_len(sg) which
+ * is 0.
+ */
#define sg_dma_address(sg) ((sg)->dma_address)
+#ifdef __powerpc64__
#define sg_dma_len(sg) ((sg)->dma_length)
+#else
+#define sg_dma_len(sg) ((sg)->length)
+#endif
+#ifdef __powerpc64__
#define ISA_DMA_THRESHOLD (~0UL)
+#endif
-#endif /* !(_PPC64_SCATTERLIST_H) */
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_SCATTERLIST_H */
diff --git a/include/asm-ppc64/seccomp.h b/include/asm-powerpc/seccomp.h
index c130c334bda1..1e1cfe12882b 100644
--- a/include/asm-ppc64/seccomp.h
+++ b/include/asm-powerpc/seccomp.h
@@ -1,11 +1,6 @@
-#ifndef _ASM_SECCOMP_H
-
-#include <linux/thread_info.h> /* already defines TIF_32BIT */
-
-#ifndef TIF_32BIT
-#error "unexpected TIF_32BIT on ppc64"
-#endif
+#ifndef _ASM_POWERPC_SECCOMP_H
+#include <linux/thread_info.h>
#include <linux/unistd.h>
#define __NR_seccomp_read __NR_read
@@ -18,4 +13,4 @@
#define __NR_seccomp_exit_32 __NR_exit
#define __NR_seccomp_sigreturn_32 __NR_sigreturn
-#endif /* _ASM_SECCOMP_H */
+#endif /* _ASM_POWERPC_SECCOMP_H */
diff --git a/include/asm-ppc64/sections.h b/include/asm-powerpc/sections.h
index 308ca6f5ced2..47be2ac2a925 100644
--- a/include/asm-ppc64/sections.h
+++ b/include/asm-powerpc/sections.h
@@ -1,22 +1,11 @@
-#ifndef _PPC64_SECTIONS_H
-#define _PPC64_SECTIONS_H
-
-extern char _end[];
+#ifndef _ASM_POWERPC_SECTIONS_H
+#define _ASM_POWERPC_SECTIONS_H
#include <asm-generic/sections.h>
-#define __pmac
-#define __pmacdata
-
-#define __prep
-#define __prepdata
-
-#define __chrp
-#define __chrpdata
-
-#define __openfirmware
-#define __openfirmwaredata
+#ifdef __powerpc64__
+extern char _end[];
static inline int in_kernel_text(unsigned long addr)
{
@@ -27,3 +16,5 @@ static inline int in_kernel_text(unsigned long addr)
}
#endif
+
+#endif /* _ASM_POWERPC_SECTIONS_H */
diff --git a/include/asm-ppc64/semaphore.h b/include/asm-powerpc/semaphore.h
index aefe7753ea41..57369d2cadef 100644
--- a/include/asm-ppc64/semaphore.h
+++ b/include/asm-powerpc/semaphore.h
@@ -1,5 +1,5 @@
-#ifndef _PPC64_SEMAPHORE_H
-#define _PPC64_SEMAPHORE_H
+#ifndef _ASM_POWERPC_SEMAPHORE_H
+#define _ASM_POWERPC_SEMAPHORE_H
/*
* Remove spinlock-based RW semaphores; RW semaphore definitions are
@@ -31,9 +31,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name, 1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name, count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
@@ -95,4 +92,4 @@ static inline void up(struct semaphore * sem)
#endif /* __KERNEL__ */
-#endif /* !(_PPC64_SEMAPHORE_H) */
+#endif /* _ASM_POWERPC_SEMAPHORE_H */
diff --git a/include/asm-ppc64/smu.h b/include/asm-powerpc/smu.h
index dee8eefe47bc..dee8eefe47bc 100644
--- a/include/asm-ppc64/smu.h
+++ b/include/asm-powerpc/smu.h
diff --git a/include/asm-ppc64/spinlock_types.h b/include/asm-powerpc/spinlock_types.h
index a37c8eabb9f2..74236c9f05b1 100644
--- a/include/asm-ppc64/spinlock_types.h
+++ b/include/asm-powerpc/spinlock_types.h
@@ -1,5 +1,5 @@
-#ifndef __ASM_SPINLOCK_TYPES_H
-#define __ASM_SPINLOCK_TYPES_H
+#ifndef _ASM_POWERPC_SPINLOCK_TYPES_H
+#define _ASM_POWERPC_SPINLOCK_TYPES_H
#ifndef __LINUX_SPINLOCK_TYPES_H
# error "please don't include this file directly"
diff --git a/include/asm-ppc64/sstep.h b/include/asm-powerpc/sstep.h
index 4a68db50ee6f..630a9889c07c 100644
--- a/include/asm-ppc64/sstep.h
+++ b/include/asm-powerpc/sstep.h
@@ -16,8 +16,10 @@ struct pt_regs;
* we don't allow putting a breakpoint on an mtmsrd instruction.
* Similarly we don't allow breakpoints on rfid instructions.
* These macros tell us if an instruction is a mtmsrd or rfid.
+ * Note that IS_MTMSRD returns true for both an mtmsr (32-bit)
+ * and an mtmsrd (64-bit).
*/
-#define IS_MTMSRD(instr) (((instr) & 0xfc0007fe) == 0x7c000164)
+#define IS_MTMSRD(instr) (((instr) & 0xfc0007be) == 0x7c000124)
#define IS_RFID(instr) (((instr) & 0xfc0007fe) == 0x4c000024)
/* Emulate instructions that cause a transfer of control. */
diff --git a/include/asm-ppc64/statfs.h b/include/asm-powerpc/statfs.h
index 3c985e5246a7..67024026c10d 100644
--- a/include/asm-ppc64/statfs.h
+++ b/include/asm-powerpc/statfs.h
@@ -1,12 +1,11 @@
-#ifndef _PPC64_STATFS_H
-#define _PPC64_STATFS_H
+#ifndef _ASM_POWERPC_STATFS_H
+#define _ASM_POWERPC_STATFS_H
-/*
- * This program is free software; you can redistribute 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.
- */
+/* For ppc32 we just use the generic definitions, not so simple on ppc64 */
+
+#ifndef __powerpc64__
+#include <asm-generic/statfs.h>
+#else
#ifndef __KERNEL_STRICT_NAMES
#include <linux/types.h>
@@ -57,5 +56,5 @@ struct compat_statfs64 {
__u32 f_frsize;
__u32 f_spare[5];
};
-
-#endif /* _PPC64_STATFS_H */
+#endif /* ! __powerpc64__ */
+#endif
diff --git a/include/asm-powerpc/synch.h b/include/asm-powerpc/synch.h
new file mode 100644
index 000000000000..4660c0394a77
--- /dev/null
+++ b/include/asm-powerpc/synch.h
@@ -0,0 +1,51 @@
+#ifndef _ASM_POWERPC_SYNCH_H
+#define _ASM_POWERPC_SYNCH_H
+
+#include <linux/config.h>
+
+#ifdef __powerpc64__
+#define __SUBARCH_HAS_LWSYNC
+#endif
+
+#ifdef __SUBARCH_HAS_LWSYNC
+# define LWSYNC lwsync
+#else
+# define LWSYNC sync
+#endif
+
+
+/*
+ * Arguably the bitops and *xchg operations don't imply any memory barrier
+ * or SMP ordering, but in fact a lot of drivers expect them to imply
+ * both, since they do on x86 cpus.
+ */
+#ifdef CONFIG_SMP
+#define EIEIO_ON_SMP "eieio\n"
+#define ISYNC_ON_SMP "\n\tisync"
+#define SYNC_ON_SMP __stringify(LWSYNC) "\n"
+#else
+#define EIEIO_ON_SMP
+#define ISYNC_ON_SMP
+#define SYNC_ON_SMP
+#endif
+
+static inline void eieio(void)
+{
+ __asm__ __volatile__ ("eieio" : : : "memory");
+}
+
+static inline void isync(void)
+{
+ __asm__ __volatile__ ("isync" : : : "memory");
+}
+
+#ifdef CONFIG_SMP
+#define eieio_on_smp() eieio()
+#define isync_on_smp() isync()
+#else
+#define eieio_on_smp() __asm__ __volatile__("": : :"memory")
+#define isync_on_smp() __asm__ __volatile__("": : :"memory")
+#endif
+
+#endif /* _ASM_POWERPC_SYNCH_H */
+
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
new file mode 100644
index 000000000000..5b2ecbc47907
--- /dev/null
+++ b/include/asm-powerpc/system.h
@@ -0,0 +1,363 @@
+/*
+ * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu>
+ */
+#ifndef _ASM_POWERPC_SYSTEM_H
+#define _ASM_POWERPC_SYSTEM_H
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+
+#include <asm/hw_irq.h>
+#include <asm/ppc_asm.h>
+#include <asm/atomic.h>
+
+/*
+ * Memory barrier.
+ * The sync instruction guarantees that all memory accesses initiated
+ * by this processor have been performed (with respect to all other
+ * mechanisms that access memory). The eieio instruction is a barrier
+ * providing an ordering (separately) for (a) cacheable stores and (b)
+ * loads and stores to non-cacheable memory (e.g. I/O devices).
+ *
+ * mb() prevents loads and stores being reordered across this point.
+ * rmb() prevents loads being reordered across this point.
+ * wmb() prevents stores being reordered across this point.
+ * read_barrier_depends() prevents data-dependent loads being reordered
+ * across this point (nop on PPC).
+ *
+ * We have to use the sync instructions for mb(), since lwsync doesn't
+ * order loads with respect to previous stores. Lwsync is fine for
+ * rmb(), though. Note that lwsync is interpreted as sync by
+ * 32-bit and older 64-bit CPUs.
+ *
+ * For wmb(), we use sync since wmb is used in drivers to order
+ * stores to system memory with respect to writes to the device.
+ * However, smp_wmb() can be a lighter-weight eieio barrier on
+ * SMP since it is only used to order updates to system memory.
+ */
+#define mb() __asm__ __volatile__ ("sync" : : : "memory")
+#define rmb() __asm__ __volatile__ ("lwsync" : : : "memory")
+#define wmb() __asm__ __volatile__ ("sync" : : : "memory")
+#define read_barrier_depends() do { } while(0)
+
+#define set_mb(var, value) do { var = value; mb(); } while (0)
+#define set_wmb(var, value) do { var = value; wmb(); } while (0)
+
+#ifdef CONFIG_SMP
+#define smp_mb() mb()
+#define smp_rmb() rmb()
+#define smp_wmb() __asm__ __volatile__ ("eieio" : : : "memory")
+#define smp_read_barrier_depends() read_barrier_depends()
+#else
+#define smp_mb() barrier()
+#define smp_rmb() barrier()
+#define smp_wmb() barrier()
+#define smp_read_barrier_depends() do { } while(0)
+#endif /* CONFIG_SMP */
+
+#ifdef __KERNEL__
+struct task_struct;
+struct pt_regs;
+
+#ifdef CONFIG_DEBUGGER
+
+extern int (*__debugger)(struct pt_regs *regs);
+extern int (*__debugger_ipi)(struct pt_regs *regs);
+extern int (*__debugger_bpt)(struct pt_regs *regs);
+extern int (*__debugger_sstep)(struct pt_regs *regs);
+extern int (*__debugger_iabr_match)(struct pt_regs *regs);
+extern int (*__debugger_dabr_match)(struct pt_regs *regs);
+extern int (*__debugger_fault_handler)(struct pt_regs *regs);
+
+#define DEBUGGER_BOILERPLATE(__NAME) \
+static inline int __NAME(struct pt_regs *regs) \
+{ \
+ if (unlikely(__ ## __NAME)) \
+ return __ ## __NAME(regs); \
+ return 0; \
+}
+
+DEBUGGER_BOILERPLATE(debugger)
+DEBUGGER_BOILERPLATE(debugger_ipi)
+DEBUGGER_BOILERPLATE(debugger_bpt)
+DEBUGGER_BOILERPLATE(debugger_sstep)
+DEBUGGER_BOILERPLATE(debugger_iabr_match)
+DEBUGGER_BOILERPLATE(debugger_dabr_match)
+DEBUGGER_BOILERPLATE(debugger_fault_handler)
+
+#ifdef CONFIG_XMON
+extern void xmon_init(int enable);
+#endif
+
+#else
+static inline int debugger(struct pt_regs *regs) { return 0; }
+static inline int debugger_ipi(struct pt_regs *regs) { return 0; }
+static inline int debugger_bpt(struct pt_regs *regs) { return 0; }
+static inline int debugger_sstep(struct pt_regs *regs) { return 0; }
+static inline int debugger_iabr_match(struct pt_regs *regs) { return 0; }
+static inline int debugger_dabr_match(struct pt_regs *regs) { return 0; }
+static inline int debugger_fault_handler(struct pt_regs *regs) { return 0; }
+#endif
+
+extern int set_dabr(unsigned long dabr);
+extern void print_backtrace(unsigned long *);
+extern void show_regs(struct pt_regs * regs);
+extern void flush_instruction_cache(void);
+extern void hard_reset_now(void);
+extern void poweroff_now(void);
+
+#ifdef CONFIG_6xx
+extern long _get_L2CR(void);
+extern long _get_L3CR(void);
+extern void _set_L2CR(unsigned long);
+extern void _set_L3CR(unsigned long);
+#else
+#define _get_L2CR() 0L
+#define _get_L3CR() 0L
+#define _set_L2CR(val) do { } while(0)
+#define _set_L3CR(val) do { } while(0)
+#endif
+
+extern void via_cuda_init(void);
+extern void read_rtc_time(void);
+extern void pmac_find_display(void);
+extern void giveup_fpu(struct task_struct *);
+extern void disable_kernel_fp(void);
+extern void enable_kernel_fp(void);
+extern void flush_fp_to_thread(struct task_struct *);
+extern void enable_kernel_altivec(void);
+extern void giveup_altivec(struct task_struct *);
+extern void load_up_altivec(struct task_struct *);
+extern int emulate_altivec(struct pt_regs *);
+extern void giveup_spe(struct task_struct *);
+extern void load_up_spe(struct task_struct *);
+extern int fix_alignment(struct pt_regs *);
+extern void cvt_fd(float *from, double *to, struct thread_struct *thread);
+extern void cvt_df(double *from, float *to, struct thread_struct *thread);
+
+#ifdef CONFIG_ALTIVEC
+extern void flush_altivec_to_thread(struct task_struct *);
+#else
+static inline void flush_altivec_to_thread(struct task_struct *t)
+{
+}
+#endif
+
+#ifdef CONFIG_SPE
+extern void flush_spe_to_thread(struct task_struct *);
+#else
+static inline void flush_spe_to_thread(struct task_struct *t)
+{
+}
+#endif
+
+extern int call_rtas(const char *, int, int, unsigned long *, ...);
+extern void cacheable_memzero(void *p, unsigned int nb);
+extern void *cacheable_memcpy(void *, const void *, unsigned int);
+extern int do_page_fault(struct pt_regs *, unsigned long, unsigned long);
+extern void bad_page_fault(struct pt_regs *, unsigned long, int);
+extern int die(const char *, struct pt_regs *, long);
+extern void _exception(int, struct pt_regs *, int, unsigned long);
+#ifdef CONFIG_BOOKE_WDT
+extern u32 booke_wdt_enabled;
+extern u32 booke_wdt_period;
+#endif /* CONFIG_BOOKE_WDT */
+
+/* EBCDIC -> ASCII conversion for [0-9A-Z] on iSeries */
+extern unsigned char e2a(unsigned char);
+
+struct device_node;
+extern void note_scsi_host(struct device_node *, void *);
+
+extern struct task_struct *__switch_to(struct task_struct *,
+ struct task_struct *);
+#define switch_to(prev, next, last) ((last) = __switch_to((prev), (next)))
+
+struct thread_struct;
+extern struct task_struct *_switch(struct thread_struct *prev,
+ struct thread_struct *next);
+
+extern unsigned int rtas_data;
+extern int mem_init_done; /* set on boot once kmalloc can be called */
+extern unsigned long memory_limit;
+
+extern int powersave_nap; /* set if nap mode can be used in idle loop */
+
+/*
+ * Atomic exchange
+ *
+ * Changes the memory location '*ptr' to be val and returns
+ * the previous value stored there.
+ */
+static __inline__ unsigned long
+__xchg_u32(volatile void *p, unsigned long val)
+{
+ unsigned long prev;
+
+ __asm__ __volatile__(
+ EIEIO_ON_SMP
+"1: lwarx %0,0,%2 \n"
+ PPC405_ERR77(0,%2)
+" stwcx. %3,0,%2 \n\
+ bne- 1b"
+ ISYNC_ON_SMP
+ : "=&r" (prev), "=m" (*(volatile unsigned int *)p)
+ : "r" (p), "r" (val), "m" (*(volatile unsigned int *)p)
+ : "cc", "memory");
+
+ return prev;
+}
+
+#ifdef CONFIG_PPC64
+static __inline__ unsigned long
+__xchg_u64(volatile void *p, unsigned long val)
+{
+ unsigned long prev;
+
+ __asm__ __volatile__(
+ EIEIO_ON_SMP
+"1: ldarx %0,0,%2 \n"
+ PPC405_ERR77(0,%2)
+" stdcx. %3,0,%2 \n\
+ bne- 1b"
+ ISYNC_ON_SMP
+ : "=&r" (prev), "=m" (*(volatile unsigned long *)p)
+ : "r" (p), "r" (val), "m" (*(volatile unsigned long *)p)
+ : "cc", "memory");
+
+ return prev;
+}
+#endif
+
+/*
+ * This function doesn't exist, so you'll get a linker error
+ * if something tries to do an invalid xchg().
+ */
+extern void __xchg_called_with_bad_pointer(void);
+
+static __inline__ unsigned long
+__xchg(volatile void *ptr, unsigned long x, unsigned int size)
+{
+ switch (size) {
+ case 4:
+ return __xchg_u32(ptr, x);
+#ifdef CONFIG_PPC64
+ case 8:
+ return __xchg_u64(ptr, x);
+#endif
+ }
+ __xchg_called_with_bad_pointer();
+ return x;
+}
+
+#define xchg(ptr,x) \
+ ({ \
+ __typeof__(*(ptr)) _x_ = (x); \
+ (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \
+ })
+
+#define tas(ptr) (xchg((ptr),1))
+
+/*
+ * Compare and exchange - if *p == old, set it to new,
+ * and return the old value of *p.
+ */
+#define __HAVE_ARCH_CMPXCHG 1
+
+static __inline__ unsigned long
+__cmpxchg_u32(volatile unsigned int *p, unsigned long old, unsigned long new)
+{
+ unsigned int prev;
+
+ __asm__ __volatile__ (
+ EIEIO_ON_SMP
+"1: lwarx %0,0,%2 # __cmpxchg_u32\n\
+ cmpw 0,%0,%3\n\
+ bne- 2f\n"
+ PPC405_ERR77(0,%2)
+" stwcx. %4,0,%2\n\
+ bne- 1b"
+ ISYNC_ON_SMP
+ "\n\
+2:"
+ : "=&r" (prev), "=m" (*p)
+ : "r" (p), "r" (old), "r" (new), "m" (*p)
+ : "cc", "memory");
+
+ return prev;
+}
+
+#ifdef CONFIG_PPC64
+static __inline__ unsigned long
+__cmpxchg_u64(volatile long *p, unsigned long old, unsigned long new)
+{
+ unsigned long prev;
+
+ __asm__ __volatile__ (
+ EIEIO_ON_SMP
+"1: ldarx %0,0,%2 # __cmpxchg_u64\n\
+ cmpd 0,%0,%3\n\
+ bne- 2f\n\
+ stdcx. %4,0,%2\n\
+ bne- 1b"
+ ISYNC_ON_SMP
+ "\n\
+2:"
+ : "=&r" (prev), "=m" (*p)
+ : "r" (p), "r" (old), "r" (new), "m" (*p)
+ : "cc", "memory");
+
+ return prev;
+}
+#endif
+
+/* This function doesn't exist, so you'll get a linker error
+ if something tries to do an invalid cmpxchg(). */
+extern void __cmpxchg_called_with_bad_pointer(void);
+
+static __inline__ unsigned long
+__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new,
+ unsigned int size)
+{
+ switch (size) {
+ case 4:
+ return __cmpxchg_u32(ptr, old, new);
+#ifdef CONFIG_PPC64
+ case 8:
+ return __cmpxchg_u64(ptr, old, new);
+#endif
+ }
+ __cmpxchg_called_with_bad_pointer();
+ return old;
+}
+
+#define cmpxchg(ptr,o,n) \
+ ({ \
+ __typeof__(*(ptr)) _o_ = (o); \
+ __typeof__(*(ptr)) _n_ = (n); \
+ (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \
+ (unsigned long)_n_, sizeof(*(ptr))); \
+ })
+
+#ifdef CONFIG_PPC64
+/*
+ * We handle most unaligned accesses in hardware. On the other hand
+ * unaligned DMA can be very expensive on some ppc64 IO chips (it does
+ * powers of 2 writes until it reaches sufficient alignment).
+ *
+ * Based on this we disable the IP header alignment in network drivers.
+ */
+#define NET_IP_ALIGN 0
+#endif
+
+#define arch_align_stack(x) (x)
+
+/* Used in very early kernel initialization. */
+extern unsigned long reloc_offset(void);
+extern unsigned long add_reloc_offset(unsigned long);
+extern void reloc_got2(unsigned long);
+
+#define PTRRELOC(x) ((typeof(x)) add_reloc_offset((unsigned long)(x)))
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_SYSTEM_H */
diff --git a/include/asm-ppc64/thread_info.h b/include/asm-powerpc/thread_info.h
index 0494df6fca74..ab17db79f69d 100644
--- a/include/asm-ppc64/thread_info.h
+++ b/include/asm-powerpc/thread_info.h
@@ -1,15 +1,25 @@
-/* thread_info.h: PPC low-level thread information
+/* thread_info.h: PowerPC low-level thread information
* adapted from the i386 version by Paul Mackerras
*
* Copyright (C) 2002 David Howells (dhowells@redhat.com)
* - Incorporating suggestions made by Linus Torvalds and Dave Miller
*/
-#ifndef _ASM_THREAD_INFO_H
-#define _ASM_THREAD_INFO_H
+#ifndef _ASM_POWERPC_THREAD_INFO_H
+#define _ASM_POWERPC_THREAD_INFO_H
#ifdef __KERNEL__
+/* We have 8k stacks on ppc32 and 16k on ppc64 */
+
+#ifdef CONFIG_PPC64
+#define THREAD_SHIFT 14
+#else
+#define THREAD_SHIFT 13
+#endif
+
+#define THREAD_SIZE (1 << THREAD_SHIFT)
+
#ifndef __ASSEMBLY__
#include <linux/config.h>
#include <linux/cache.h>
@@ -24,7 +34,8 @@ struct thread_info {
struct task_struct *task; /* main task structure */
struct exec_domain *exec_domain; /* execution domain */
int cpu; /* cpu we're on */
- int preempt_count; /* 0 => preemptable, <0 => BUG */
+ int preempt_count; /* 0 => preemptable,
+ <0 => BUG */
struct restart_block restart_block;
/* set by force_successful_syscall_return */
unsigned char syscall_noerror;
@@ -54,32 +65,38 @@ struct thread_info {
/* thread information allocation */
-#define THREAD_ORDER 2
-#define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER)
-#define THREAD_SHIFT (PAGE_SHIFT + THREAD_ORDER)
#ifdef CONFIG_DEBUG_STACK_USAGE
-#define alloc_thread_info(tsk) \
- ({ \
- struct thread_info *ret; \
- \
- ret = kmalloc(THREAD_SIZE, GFP_KERNEL); \
- if (ret) \
- memset(ret, 0, THREAD_SIZE); \
- ret; \
- })
+#define THREAD_INFO_GFP GFP_KERNEL | __GFP_ZERO
#else
-#define alloc_thread_info(tsk) kmalloc(THREAD_SIZE, GFP_KERNEL)
+#define THREAD_INFO_GFP GFP_KERNEL
#endif
+
+#if THREAD_SHIFT >= PAGE_SHIFT
+
+#define THREAD_ORDER (THREAD_SHIFT - PAGE_SHIFT)
+
+#define alloc_thread_info(tsk) \
+ ((struct thread_info *)__get_free_pages(THREAD_INFO_GFP, THREAD_ORDER))
+#define free_thread_info(ti) free_pages((unsigned long)ti, THREAD_ORDER)
+
+#else /* THREAD_SHIFT < PAGE_SHIFT */
+
+#define alloc_thread_info(tsk) kmalloc(THREAD_SIZE, THREAD_INFO_GFP)
#define free_thread_info(ti) kfree(ti)
+
+#endif /* THREAD_SHIFT < PAGE_SHIFT */
+
#define get_thread_info(ti) get_task_struct((ti)->task)
#define put_thread_info(ti) put_task_struct((ti)->task)
/* how to get the thread information struct from C */
static inline struct thread_info *current_thread_info(void)
{
- struct thread_info *ti;
- __asm__("clrrdi %0,1,%1" : "=r"(ti) : "i" (THREAD_SHIFT));
- return ti;
+ register unsigned long sp asm("r1");
+
+ /* gcc4, at least, is smart enough to turn this into a single
+ * rlwinm for ppc32 and clrrdi for ppc64 */
+ return (struct thread_info *)(sp & ~(THREAD_SIZE-1));
}
#endif /* __ASSEMBLY__ */
@@ -122,4 +139,4 @@ static inline struct thread_info *current_thread_info(void)
#endif /* __KERNEL__ */
-#endif /* _ASM_THREAD_INFO_H */
+#endif /* _ASM_POWERPC_THREAD_INFO_H */
diff --git a/include/asm-powerpc/time.h b/include/asm-powerpc/time.h
new file mode 100644
index 000000000000..410e795f7d43
--- /dev/null
+++ b/include/asm-powerpc/time.h
@@ -0,0 +1,226 @@
+/*
+ * Common time prototypes and such for all ppc machines.
+ *
+ * Written by Cort Dougan (cort@cs.nmt.edu) to merge
+ * Paul Mackerras' version and mine for PReP and Pmac.
+ *
+ * This program is free software; you can redistribute 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 __POWERPC_TIME_H
+#define __POWERPC_TIME_H
+
+#ifdef __KERNEL__
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/percpu.h>
+
+#include <asm/processor.h>
+#ifdef CONFIG_PPC64
+#include <asm/paca.h>
+#include <asm/iSeries/HvCall.h>
+#endif
+
+/* time.c */
+extern unsigned long tb_ticks_per_jiffy;
+extern unsigned long tb_ticks_per_usec;
+extern unsigned long tb_ticks_per_sec;
+extern u64 tb_to_xs;
+extern unsigned tb_to_us;
+extern unsigned long tb_last_stamp;
+extern u64 tb_last_jiffy;
+
+DECLARE_PER_CPU(unsigned long, last_jiffy);
+
+struct rtc_time;
+extern void to_tm(int tim, struct rtc_time * tm);
+extern time_t last_rtc_update;
+
+extern void generic_calibrate_decr(void);
+extern void wakeup_decrementer(void);
+
+/* Some sane defaults: 125 MHz timebase, 1GHz processor */
+extern unsigned long ppc_proc_freq;
+#define DEFAULT_PROC_FREQ (DEFAULT_TB_FREQ * 8)
+extern unsigned long ppc_tb_freq;
+#define DEFAULT_TB_FREQ 125000000UL
+
+/*
+ * By putting all of this stuff into a single struct we
+ * reduce the number of cache lines touched by do_gettimeofday.
+ * Both by collecting all of the data in one cache line and
+ * by touching only one TOC entry on ppc64.
+ */
+struct gettimeofday_vars {
+ u64 tb_to_xs;
+ u64 stamp_xsec;
+ u64 tb_orig_stamp;
+};
+
+struct gettimeofday_struct {
+ unsigned long tb_ticks_per_sec;
+ struct gettimeofday_vars vars[2];
+ struct gettimeofday_vars * volatile varp;
+ unsigned var_idx;
+ unsigned tb_to_us;
+};
+
+struct div_result {
+ u64 result_high;
+ u64 result_low;
+};
+
+/* Accessor functions for the timebase (RTC on 601) registers. */
+/* If one day CONFIG_POWER is added just define __USE_RTC as 1 */
+#ifdef CONFIG_6xx
+#define __USE_RTC() (!cpu_has_feature(CPU_FTR_USE_TB))
+#else
+#define __USE_RTC() 0
+#endif
+
+/* On ppc64 this gets us the whole timebase; on ppc32 just the lower half */
+static inline unsigned long get_tbl(void)
+{
+ unsigned long tbl;
+
+#if defined(CONFIG_403GCX)
+ asm volatile("mfspr %0, 0x3dd" : "=r" (tbl));
+#else
+ asm volatile("mftb %0" : "=r" (tbl));
+#endif
+ return tbl;
+}
+
+static inline unsigned int get_tbu(void)
+{
+ unsigned int tbu;
+
+#if defined(CONFIG_403GCX)
+ asm volatile("mfspr %0, 0x3dc" : "=r" (tbu));
+#else
+ asm volatile("mftbu %0" : "=r" (tbu));
+#endif
+ return tbu;
+}
+
+static inline unsigned int get_rtcl(void)
+{
+ unsigned int rtcl;
+
+ asm volatile("mfrtcl %0" : "=r" (rtcl));
+ return rtcl;
+}
+
+static inline u64 get_rtc(void)
+{
+ unsigned int hi, lo, hi2;
+
+ do {
+ asm volatile("mfrtcu %0; mfrtcl %1; mfrtcu %2"
+ : "=r" (hi), "=r" (lo), "=r" (hi2));
+ } while (hi2 != hi);
+ return (u64)hi * 1000000000 + lo;
+}
+
+#ifdef CONFIG_PPC64
+static inline u64 get_tb(void)
+{
+ return mftb();
+}
+#else
+static inline u64 get_tb(void)
+{
+ unsigned int tbhi, tblo, tbhi2;
+
+ do {
+ tbhi = get_tbu();
+ tblo = get_tbl();
+ tbhi2 = get_tbu();
+ } while (tbhi != tbhi2);
+
+ return ((u64)tbhi << 32) | tblo;
+}
+#endif
+
+static inline void set_tb(unsigned int upper, unsigned int lower)
+{
+ mtspr(SPRN_TBWL, 0);
+ mtspr(SPRN_TBWU, upper);
+ mtspr(SPRN_TBWL, lower);
+}
+
+/* Accessor functions for the decrementer register.
+ * The 4xx doesn't even have a decrementer. I tried to use the
+ * generic timer interrupt code, which seems OK, with the 4xx PIT
+ * in auto-reload mode. The problem is PIT stops counting when it
+ * hits zero. If it would wrap, we could use it just like a decrementer.
+ */
+static inline unsigned int get_dec(void)
+{
+#if defined(CONFIG_40x)
+ return (mfspr(SPRN_PIT));
+#else
+ return (mfspr(SPRN_DEC));
+#endif
+}
+
+static inline void set_dec(int val)
+{
+#if defined(CONFIG_40x)
+ return; /* Have to let it auto-reload */
+#elif defined(CONFIG_8xx_CPU6)
+ set_dec_cpu6(val);
+#else
+#ifdef CONFIG_PPC_ISERIES
+ struct paca_struct *lpaca = get_paca();
+ int cur_dec;
+
+ if (lpaca->lppaca.shared_proc) {
+ lpaca->lppaca.virtual_decr = val;
+ cur_dec = get_dec();
+ if (cur_dec > val)
+ HvCall_setVirtualDecr();
+ } else
+#endif
+ mtspr(SPRN_DEC, val);
+#endif /* not 40x or 8xx_CPU6 */
+}
+
+static inline unsigned long tb_ticks_since(unsigned long tstamp)
+{
+ if (__USE_RTC()) {
+ int delta = get_rtcl() - (unsigned int) tstamp;
+ return delta < 0 ? delta + 1000000000 : delta;
+ }
+ return get_tbl() - tstamp;
+}
+
+#define mulhwu(x,y) \
+({unsigned z; asm ("mulhwu %0,%1,%2" : "=r" (z) : "r" (x), "r" (y)); z;})
+
+#ifdef CONFIG_PPC64
+#define mulhdu(x,y) \
+({unsigned long z; asm ("mulhdu %0,%1,%2" : "=r" (z) : "r" (x), "r" (y)); z;})
+#else
+extern u64 mulhdu(u64, u64);
+#endif
+
+extern void smp_space_timers(unsigned int);
+
+extern unsigned mulhwu_scale_factor(unsigned, unsigned);
+extern void div128_by_32(u64 dividend_high, u64 dividend_low,
+ unsigned divisor, struct div_result *dr);
+
+/* Used to store Processor Utilization register (purr) values */
+
+struct cpu_usage {
+ u64 current_tb; /* Holds the current purr register values */
+};
+
+DECLARE_PER_CPU(struct cpu_usage, cpu_usage_array);
+
+#endif /* __KERNEL__ */
+#endif /* __PPC64_TIME_H */
diff --git a/include/asm-ppc64/types.h b/include/asm-powerpc/types.h
index bf294c1761b2..ec3c2ee8bf86 100644
--- a/include/asm-ppc64/types.h
+++ b/include/asm-powerpc/types.h
@@ -1,5 +1,5 @@
-#ifndef _PPC64_TYPES_H
-#define _PPC64_TYPES_H
+#ifndef _ASM_POWERPC_TYPES_H
+#define _ASM_POWERPC_TYPES_H
#ifndef __ASSEMBLY__
@@ -16,7 +16,11 @@
* 2 of the License, or (at your option) any later version.
*/
+#ifdef __powerpc64__
typedef unsigned int umode_t;
+#else
+typedef unsigned short umode_t;
+#endif
/*
* __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
@@ -32,8 +36,15 @@ typedef unsigned short __u16;
typedef __signed__ int __s32;
typedef unsigned int __u32;
+#ifdef __powerpc64__
typedef __signed__ long __s64;
typedef unsigned long __u64;
+#else
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+#endif /* __powerpc64__ */
typedef struct {
__u32 u[4];
@@ -45,10 +56,16 @@ typedef struct {
/*
* These aren't exported outside the kernel to avoid name space clashes
*/
+#ifdef __powerpc64__
#define BITS_PER_LONG 64
+#else
+#define BITS_PER_LONG 32
+#endif
#ifndef __ASSEMBLY__
+#include <linux/config.h>
+
typedef signed char s8;
typedef unsigned char u8;
@@ -58,12 +75,21 @@ typedef unsigned short u16;
typedef signed int s32;
typedef unsigned int u32;
+#ifdef __powerpc64__
typedef signed long s64;
typedef unsigned long u64;
+#else
+typedef signed long long s64;
+typedef unsigned long long u64;
+#endif
typedef __vector128 vector128;
+#ifdef __powerpc64__
+typedef u64 dma_addr_t;
+#else
typedef u32 dma_addr_t;
+#endif
typedef u64 dma64_addr_t;
typedef struct {
@@ -72,8 +98,13 @@ typedef struct {
unsigned long env;
} func_descr_t;
+#ifdef CONFIG_LBD
+typedef u64 sector_t;
+#define HAVE_SECTOR_T
+#endif
+
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
-#endif /* _PPC64_TYPES_H */
+#endif /* _ASM_POWERPC_TYPES_H */
diff --git a/include/asm-ppc/uninorth.h b/include/asm-powerpc/uninorth.h
index f737732c3861..f737732c3861 100644
--- a/include/asm-ppc/uninorth.h
+++ b/include/asm-powerpc/uninorth.h
diff --git a/include/asm-ppc/unistd.h b/include/asm-powerpc/unistd.h
index 3173ab3d2eb9..0991dfceef1d 100644
--- a/include/asm-ppc/unistd.h
+++ b/include/asm-powerpc/unistd.h
@@ -3,7 +3,13 @@
/*
* This file contains the system call numbers.
+ *
+ * This program is free software; you can redistribute 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.
*/
+
#define __NR_restart_syscall 0
#define __NR_exit 1
#define __NR_fork 2
@@ -196,19 +202,23 @@
#define __NR_vfork 189
#define __NR_ugetrlimit 190 /* SuS compliant getrlimit */
#define __NR_readahead 191
+#ifndef __powerpc64__ /* these are 32-bit only */
#define __NR_mmap2 192
#define __NR_truncate64 193
#define __NR_ftruncate64 194
#define __NR_stat64 195
#define __NR_lstat64 196
#define __NR_fstat64 197
+#endif
#define __NR_pciconfig_read 198
#define __NR_pciconfig_write 199
#define __NR_pciconfig_iobase 200
#define __NR_multiplexer 201
#define __NR_getdents64 202
#define __NR_pivot_root 203
+#ifndef __powerpc64__
#define __NR_fcntl64 204
+#endif
#define __NR_madvise 205
#define __NR_mincore 206
#define __NR_gettid 207
@@ -230,7 +240,9 @@
#define __NR_sched_getaffinity 223
/* 224 currently unused */
#define __NR_tuxcall 225
+#ifndef __powerpc64__
#define __NR_sendfile64 226
+#endif
#define __NR_io_setup 227
#define __NR_io_destroy 228
#define __NR_io_getevents 229
@@ -258,14 +270,16 @@
#define __NR_utimes 251
#define __NR_statfs64 252
#define __NR_fstatfs64 253
+#ifndef __powerpc64__
#define __NR_fadvise64_64 254
+#endif
#define __NR_rtas 255
#define __NR_sys_debug_setcontext 256
/* Number 257 is reserved for vserver */
/* 258 currently unused */
-/* Number 259 is reserved for new sys_mbind */
-/* Number 260 is reserved for new sys_get_mempolicy */
-/* Number 261 is reserved for new sys_set_mempolicy */
+#define __NR_mbind 259
+#define __NR_get_mempolicy 260
+#define __NR_set_mempolicy 261
#define __NR_mq_open 262
#define __NR_mq_unlink 263
#define __NR_mq_timedsend 264
@@ -285,7 +299,12 @@
#define __NR_syscalls 278
-#define __NR(n) #n
+#ifdef __KERNEL__
+#define __NR__exit __NR_exit
+#define NR_syscalls __NR_syscalls
+#endif
+
+#ifndef __ASSEMBLY__
/* On powerpc a system call basically clobbers the same registers like a
* function call, with the exception of LR (which is needed for the
@@ -389,7 +408,6 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
{ \
__syscall_nr(5, type, name, arg1, arg2, arg3, arg4, arg5); \
}
-
#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \
type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \
{ \
@@ -398,12 +416,13 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6
#ifdef __KERNEL__
-#define __NR__exit __NR_exit
-#define NR_syscalls __NR_syscalls
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/compiler.h>
+#include <linux/linkage.h>
#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
-#define __ARCH_WANT_OLD_STAT
#define __ARCH_WANT_STAT64
#define __ARCH_WANT_SYS_ALARM
#define __ARCH_WANT_SYS_GETHOSTNAME
@@ -423,23 +442,17 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_RT_SIGACTION
-
-/*
- * Forking from kernel space will result in the child getting a new,
- * empty kernel stack area. Thus the child cannot access automatic
- * variables set in the parent unless they are in registers, and the
- * procedure where the fork was done cannot return to its caller in
- * the child.
- */
-
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
+#ifdef CONFIG_PPC32
+#define __ARCH_WANT_OLD_STAT
+#endif
+#ifdef CONFIG_PPC64
+#define __ARCH_WANT_COMPAT_SYS_TIME
+#endif
/*
* System call prototypes.
*/
+#ifdef __KERNEL_SYSCALLS__
extern pid_t setsid(void);
extern int write(int fd, const char *buf, off_t count);
extern int read(int fd, char *buf, off_t count);
@@ -449,10 +462,13 @@ extern int execve(const char *file, char **argv, char **envp);
extern int open(const char *file, int flag, int mode);
extern int close(int fd);
extern pid_t waitpid(pid_t pid, int *wait_stat, int options);
+#endif /* __KERNEL_SYSCALLS__ */
-unsigned long sys_mmap(unsigned long addr, size_t len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, off_t offset);
+/*
+ * Functions that implement syscalls.
+ */
+unsigned long sys_mmap(unsigned long addr, size_t len, unsigned long prot,
+ unsigned long flags, unsigned long fd, off_t offset);
unsigned long sys_mmap2(unsigned long addr, size_t len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff);
@@ -461,22 +477,18 @@ int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
unsigned long a3, unsigned long a4, unsigned long a5,
struct pt_regs *regs);
int sys_clone(unsigned long clone_flags, unsigned long usp,
- int __user *parent_tidp, void __user *child_threadptr,
- int __user *child_tidp, int p6,
- struct pt_regs *regs);
-int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6,
+ int __user *parent_tidp, void __user *child_threadptr,
+ int __user *child_tidp, int p6, struct pt_regs *regs);
+int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3,
+ unsigned long p4, unsigned long p5, unsigned long p6,
struct pt_regs *regs);
-int sys_vfork(int p1, int p2, int p3, int p4, int p5, int p6,
+int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,
+ unsigned long p4, unsigned long p5, unsigned long p6,
struct pt_regs *regs);
int sys_pipe(int __user *fildes);
-int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
-long sys_rt_sigaction(int sig,
- const struct sigaction __user *act,
- struct sigaction __user *oact,
- size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
+long sys_rt_sigaction(int sig, const struct sigaction __user *act,
+ struct sigaction __user *oact, size_t sigsetsize);
/*
* "Conditional" syscalls
@@ -484,10 +496,14 @@ long sys_rt_sigaction(int sig,
* What we want is __attribute__((weak,alias("sys_ni_syscall"))),
* but it doesn't work on all toolchains, so we just do it by hand
*/
-#ifndef cond_syscall
+#ifdef CONFIG_PPC32
#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
+#else
+#define cond_syscall(x) asm(".weak\t." #x "\n\t.set\t." #x ",.sys_ni_syscall")
#endif
-#endif /* __KERNEL__ */
+#endif /* __KERNEL__ */
+
+#endif /* __ASSEMBLY__ */
#endif /* _ASM_PPC_UNISTD_H_ */
diff --git a/include/asm-ppc64/vga.h b/include/asm-powerpc/vga.h
index c09849743f45..f8d350aabf1a 100644
--- a/include/asm-ppc64/vga.h
+++ b/include/asm-powerpc/vga.h
@@ -1,16 +1,14 @@
+#ifndef _ASM_POWERPC_VGA_H_
+#define _ASM_POWERPC_VGA_H_
+
+#ifdef __KERNEL__
+
/*
* Access to VGA videoram
*
* (c) 1998 Martin Mares <mj@ucw.cz>
- *
- * This program is free software; you can redistribute 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 _LINUX_ASM_VGA_H_
-#define _LINUX_ASM_VGA_H_
#include <asm/io.h>
@@ -42,9 +40,15 @@ static inline u16 scr_readw(volatile const u16 *addr)
#endif /* !CONFIG_VGA_CONSOLE && !CONFIG_MDA_CONSOLE */
extern unsigned long vgacon_remap_base;
+
+#ifdef __powerpc64__
#define VGA_MAP_MEM(x) ((unsigned long) ioremap((x), 0))
+#else
+#define VGA_MAP_MEM(x) (x + vgacon_remap_base)
+#endif
#define vga_readb(x) (*(x))
#define vga_writeb(x,y) (*(y) = (x))
-#endif
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_VGA_H_ */
diff --git a/include/asm-ppc64/vio.h b/include/asm-powerpc/vio.h
index 03f1b95f433b..e0ccf108277c 100644
--- a/include/asm-ppc64/vio.h
+++ b/include/asm-powerpc/vio.h
@@ -1,18 +1,18 @@
/*
* IBM PowerPC Virtual I/O Infrastructure Support.
*
- * Copyright (c) 2003 IBM Corp.
- * Dave Engebretsen engebret@us.ibm.com
- * Santiago Leon santil@us.ibm.com
+ * Copyright (c) 2003 IBM Corp.
+ * Dave Engebretsen engebret@us.ibm.com
+ * Santiago Leon santil@us.ibm.com
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
+ * This program is free software; you can redistribute 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_VIO_H
-#define _ASM_VIO_H
+#ifndef _ASM_POWERPC_VIO_H
+#define _ASM_POWERPC_VIO_H
#include <linux/config.h>
#include <linux/init.h>
@@ -55,10 +55,10 @@ struct vio_dev {
struct vio_driver {
struct list_head node;
- char *name;
const struct vio_device_id *id_table;
int (*probe)(struct vio_dev *dev, const struct vio_device_id *id);
int (*remove)(struct vio_dev *dev);
+ void (*shutdown)(struct vio_dev *dev);
unsigned long driver_data;
struct device_driver driver;
};
@@ -103,4 +103,4 @@ static inline struct vio_dev *to_vio_dev(struct device *dev)
return container_of(dev, struct vio_dev, dev);
}
-#endif /* _ASM_VIO_H */
+#endif /* _ASM_POWERPC_VIO_H */
diff --git a/include/asm-powerpc/xmon.h b/include/asm-powerpc/xmon.h
new file mode 100644
index 000000000000..43f7129984c7
--- /dev/null
+++ b/include/asm-powerpc/xmon.h
@@ -0,0 +1,12 @@
+#ifndef __PPC_XMON_H
+#define __PPC_XMON_H
+#ifdef __KERNEL__
+
+struct pt_regs;
+
+extern int xmon(struct pt_regs *excp);
+extern void xmon_printf(const char *fmt, ...);
+extern void xmon_init(int);
+
+#endif
+#endif
diff --git a/include/asm-ppc/a.out.h b/include/asm-ppc/a.out.h
deleted file mode 100644
index 8979a94c4a81..000000000000
--- a/include/asm-ppc/a.out.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef __PPC_A_OUT_H__
-#define __PPC_A_OUT_H__
-
-/* grabbed from the intel stuff */
-#define STACK_TOP TASK_SIZE
-
-
-struct exec
-{
- unsigned long a_info; /* Use macros N_MAGIC, etc for access */
- unsigned a_text; /* length of text, in bytes */
- unsigned a_data; /* length of data, in bytes */
- unsigned a_bss; /* length of uninitialized data area for file, in bytes */
- unsigned a_syms; /* length of symbol table data in file, in bytes */
- unsigned a_entry; /* start address */
- unsigned a_trsize; /* length of relocation info for text, in bytes */
- unsigned a_drsize; /* length of relocation info for data, in bytes */
-};
-
-
-#define N_TRSIZE(a) ((a).a_trsize)
-#define N_DRSIZE(a) ((a).a_drsize)
-#define N_SYMSIZE(a) ((a).a_syms)
-
-
-#endif
diff --git a/include/asm-ppc/auxvec.h b/include/asm-ppc/auxvec.h
deleted file mode 100644
index 172358df29c8..000000000000
--- a/include/asm-ppc/auxvec.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef __PPC_AUXVEC_H
-#define __PPC_AUXVEC_H
-
-/*
- * We need to put in some extra aux table entries to tell glibc what
- * the cache block size is, so it can use the dcbz instruction safely.
- */
-#define AT_DCACHEBSIZE 19
-#define AT_ICACHEBSIZE 20
-#define AT_UCACHEBSIZE 21
-/* A special ignored type value for PPC, for glibc compatibility. */
-#define AT_IGNOREPPC 22
-
-#endif
diff --git a/include/asm-ppc/bug.h b/include/asm-ppc/bug.h
deleted file mode 100644
index 8b34fd682b0d..000000000000
--- a/include/asm-ppc/bug.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#ifndef _PPC_BUG_H
-#define _PPC_BUG_H
-
-struct bug_entry {
- unsigned long bug_addr;
- int line;
- const char *file;
- const char *function;
-};
-
-/*
- * If this bit is set in the line number it means that the trap
- * is for WARN_ON rather than BUG or BUG_ON.
- */
-#define BUG_WARNING_TRAP 0x1000000
-
-#ifdef CONFIG_BUG
-#define BUG() do { \
- __asm__ __volatile__( \
- "1: twi 31,0,0\n" \
- ".section __bug_table,\"a\"\n\t" \
- " .long 1b,%0,%1,%2\n" \
- ".previous" \
- : : "i" (__LINE__), "i" (__FILE__), "i" (__FUNCTION__)); \
-} while (0)
-
-#define BUG_ON(x) do { \
- if (!__builtin_constant_p(x) || (x)) { \
- __asm__ __volatile__( \
- "1: twnei %0,0\n" \
- ".section __bug_table,\"a\"\n\t" \
- " .long 1b,%1,%2,%3\n" \
- ".previous" \
- : : "r" (x), "i" (__LINE__), "i" (__FILE__), \
- "i" (__FUNCTION__)); \
- } \
-} while (0)
-
-#define WARN_ON(x) do { \
- if (!__builtin_constant_p(x) || (x)) { \
- __asm__ __volatile__( \
- "1: twnei %0,0\n" \
- ".section __bug_table,\"a\"\n\t" \
- " .long 1b,%1,%2,%3\n" \
- ".previous" \
- : : "r" (x), "i" (__LINE__ + BUG_WARNING_TRAP), \
- "i" (__FILE__), "i" (__FUNCTION__)); \
- } \
-} while (0)
-
-#define HAVE_ARCH_BUG
-#define HAVE_ARCH_BUG_ON
-#define HAVE_ARCH_WARN_ON
-#endif
-
-#include <asm-generic/bug.h>
-
-#endif
diff --git a/include/asm-ppc/byteorder.h b/include/asm-ppc/byteorder.h
deleted file mode 100644
index c63c81ec7968..000000000000
--- a/include/asm-ppc/byteorder.h
+++ /dev/null
@@ -1,76 +0,0 @@
-#ifndef _PPC_BYTEORDER_H
-#define _PPC_BYTEORDER_H
-
-#include <asm/types.h>
-#include <linux/compiler.h>
-
-#ifdef __GNUC__
-#ifdef __KERNEL__
-
-extern __inline__ unsigned ld_le16(const volatile unsigned short *addr)
-{
- unsigned val;
-
- __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr));
- return val;
-}
-
-extern __inline__ void st_le16(volatile unsigned short *addr, const unsigned val)
-{
- __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
-}
-
-extern __inline__ unsigned ld_le32(const volatile unsigned *addr)
-{
- unsigned val;
-
- __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr));
- return val;
-}
-
-extern __inline__ void st_le32(volatile unsigned *addr, const unsigned val)
-{
- __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
-}
-
-static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 value)
-{
- __u16 result;
-
- __asm__("rlwimi %0,%2,8,16,23" : "=&r" (result) : "0" (value >> 8), "r" (value));
- return result;
-}
-
-static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 value)
-{
- __u32 result;
-
- __asm__("rlwimi %0,%2,24,16,23" : "=&r" (result) : "0" (value>>24), "r" (value));
- __asm__("rlwimi %0,%2,8,8,15" : "=&r" (result) : "0" (result), "r" (value));
- __asm__("rlwimi %0,%2,24,0,7" : "=&r" (result) : "0" (result), "r" (value));
-
- return result;
-}
-#define __arch__swab32(x) ___arch__swab32(x)
-#define __arch__swab16(x) ___arch__swab16(x)
-
-/* The same, but returns converted value from the location pointer by addr. */
-#define __arch__swab16p(addr) ld_le16(addr)
-#define __arch__swab32p(addr) ld_le32(addr)
-
-/* The same, but do the conversion in situ, ie. put the value back to addr. */
-#define __arch__swab16s(addr) st_le16(addr,*addr)
-#define __arch__swab32s(addr) st_le32(addr,*addr)
-
-#endif /* __KERNEL__ */
-
-#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
-# define __BYTEORDER_HAS_U64__
-# define __SWAB_64_THRU_32__
-#endif
-
-#endif /* __GNUC__ */
-
-#include <linux/byteorder/big_endian.h>
-
-#endif /* _PPC_BYTEORDER_H */
diff --git a/include/asm-ppc/cache.h b/include/asm-ppc/cache.h
index 38f2f1be4a87..7a157d0f4b5f 100644
--- a/include/asm-ppc/cache.h
+++ b/include/asm-ppc/cache.h
@@ -9,21 +9,18 @@
/* bytes per L1 cache line */
#if defined(CONFIG_8xx) || defined(CONFIG_403GCX)
-#define L1_CACHE_LINE_SIZE 16
-#define LG_L1_CACHE_LINE_SIZE 4
+#define L1_CACHE_SHIFT 4
#define MAX_COPY_PREFETCH 1
#elif defined(CONFIG_PPC64BRIDGE)
-#define L1_CACHE_LINE_SIZE 128
-#define LG_L1_CACHE_LINE_SIZE 7
+#define L1_CACHE_SHIFT 7
#define MAX_COPY_PREFETCH 1
#else
-#define L1_CACHE_LINE_SIZE 32
-#define LG_L1_CACHE_LINE_SIZE 5
+#define L1_CACHE_SHIFT 5
#define MAX_COPY_PREFETCH 4
#endif
-#define L1_CACHE_BYTES L1_CACHE_LINE_SIZE
-#define L1_CACHE_SHIFT LG_L1_CACHE_LINE_SIZE
+#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
+
#define SMP_CACHE_BYTES L1_CACHE_BYTES
#define L1_CACHE_SHIFT_MAX 7 /* largest L1 which this arch supports */
diff --git a/include/asm-ppc/checksum.h b/include/asm-ppc/checksum.h
deleted file mode 100644
index cf953a92c7ab..000000000000
--- a/include/asm-ppc/checksum.h
+++ /dev/null
@@ -1,107 +0,0 @@
-#ifdef __KERNEL__
-#ifndef _PPC_CHECKSUM_H
-#define _PPC_CHECKSUM_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
- */
-extern unsigned int csum_partial(const unsigned char * buff, int len,
- unsigned int sum);
-
-/*
- * Computes the checksum of a memory block at src, length len,
- * and adds in "sum" (32-bit), while copying the block to dst.
- * If an access exception occurs on src or dst, it stores -EFAULT
- * to *src_err or *dst_err respectively (if that pointer is not
- * NULL), and, for an error on src, zeroes the rest of dst.
- *
- * Like csum_partial, this must be called with even lengths,
- * except for the last fragment.
- */
-extern unsigned int csum_partial_copy_generic(const char *src, char *dst,
- int len, unsigned int sum,
- int *src_err, int *dst_err);
-
-#define csum_partial_copy_from_user(src, dst, len, sum, errp) \
- csum_partial_copy_generic((__force void *)(src), (dst), (len), (sum), (errp), NULL)
-
-/* FIXME: this needs to be written to really do no check -- Cort */
-#define csum_partial_copy_nocheck(src, dst, len, sum) \
- csum_partial_copy_generic((src), (dst), (len), (sum), NULL, NULL)
-
-/*
- * turns a 32-bit partial checksum (e.g. from csum_partial) into a
- * 1's complement 16-bit checksum.
- */
-static inline unsigned int csum_fold(unsigned int sum)
-{
- unsigned int tmp;
-
- /* swap the two 16-bit halves of sum */
- __asm__("rlwinm %0,%1,16,0,31" : "=r" (tmp) : "r" (sum));
- /* if there is a carry from adding the two 16-bit halves,
- it will carry from the lower half into the upper half,
- giving us the correct sum in the upper half. */
- sum = ~(sum + tmp) >> 16;
- return sum;
-}
-
-/*
- * this routine is used for miscellaneous IP-like checksums, mainly
- * in icmp.c
- */
-static inline unsigned short ip_compute_csum(unsigned char * buff, int len)
-{
- return csum_fold(csum_partial(buff, len, 0));
-}
-
-/*
- * FIXME: I swiped this one from the sparc and made minor modifications.
- * It may not be correct. -- Cort
- */
-static inline unsigned long csum_tcpudp_nofold(unsigned long saddr,
- unsigned long daddr,
- unsigned short len,
- unsigned short proto,
- unsigned int sum)
-{
- __asm__("\n\
- addc %0,%0,%1 \n\
- adde %0,%0,%2 \n\
- adde %0,%0,%3 \n\
- addze %0,%0 \n\
- "
- : "=r" (sum)
- : "r" (daddr), "r"(saddr), "r"((proto<<16)+len), "0"(sum));
- return sum;
-}
-
-/*
- * This is a version of ip_compute_csum() optimized for IP headers,
- * which always checksum on 4 octet boundaries. ihl is the number
- * of 32-bit words and is always >= 5.
- */
-extern unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl);
-
-/*
- * computes the checksum of the TCP/UDP pseudo-header
- * returns a 16-bit checksum, already complemented
- */
-extern unsigned short csum_tcpudp_magic(unsigned long saddr,
- unsigned long daddr,
- unsigned short len,
- unsigned short proto,
- unsigned int sum);
-
-#endif
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/cpm2.h b/include/asm-ppc/cpm2.h
index 9483d4bfacf7..43d2ebbc7748 100644
--- a/include/asm-ppc/cpm2.h
+++ b/include/asm-ppc/cpm2.h
@@ -1087,6 +1087,9 @@ typedef struct im_idma {
#define SCCR_PCIDF_MSK 0x00000078 /* PCI division factor */
#define SCCR_PCIDF_SHIFT 3
+#ifndef CPM_IMMR_OFFSET
+#define CPM_IMMR_OFFSET 0x101a8
+#endif
#endif /* __CPM2__ */
#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/cputable.h b/include/asm-ppc/cputable.h
deleted file mode 100644
index e17c492c870b..000000000000
--- a/include/asm-ppc/cputable.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * include/asm-ppc/cputable.h
- *
- * Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.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.
- */
-
-#ifndef __ASM_PPC_CPUTABLE_H
-#define __ASM_PPC_CPUTABLE_H
-
-/* Exposed to userland CPU features */
-#define PPC_FEATURE_32 0x80000000
-#define PPC_FEATURE_64 0x40000000
-#define PPC_FEATURE_601_INSTR 0x20000000
-#define PPC_FEATURE_HAS_ALTIVEC 0x10000000
-#define PPC_FEATURE_HAS_FPU 0x08000000
-#define PPC_FEATURE_HAS_MMU 0x04000000
-#define PPC_FEATURE_HAS_4xxMAC 0x02000000
-#define PPC_FEATURE_UNIFIED_CACHE 0x01000000
-#define PPC_FEATURE_HAS_SPE 0x00800000
-#define PPC_FEATURE_HAS_EFP_SINGLE 0x00400000
-#define PPC_FEATURE_HAS_EFP_DOUBLE 0x00200000
-#define PPC_FEATURE_NO_TB 0x00100000
-
-#ifdef __KERNEL__
-
-#ifndef __ASSEMBLY__
-
-/* This structure can grow, it's real size is used by head.S code
- * via the mkdefs mecanism.
- */
-struct cpu_spec;
-
-typedef void (*cpu_setup_t)(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
-
-struct cpu_spec {
- /* CPU is matched via (PVR & pvr_mask) == pvr_value */
- unsigned int pvr_mask;
- unsigned int pvr_value;
-
- char *cpu_name;
- unsigned int cpu_features; /* Kernel features */
- unsigned int cpu_user_features; /* Userland features */
-
- /* cache line sizes */
- unsigned int icache_bsize;
- unsigned int dcache_bsize;
-
- /* number of performance monitor counters */
- unsigned int num_pmcs;
-
- /* this is called to initialize various CPU bits like L1 cache,
- * BHT, SPD, etc... from head.S before branching to identify_machine
- */
- cpu_setup_t cpu_setup;
-};
-
-extern struct cpu_spec cpu_specs[];
-extern struct cpu_spec *cur_cpu_spec[];
-
-static inline unsigned int cpu_has_feature(unsigned int feature)
-{
- return cur_cpu_spec[0]->cpu_features & feature;
-}
-
-#endif /* __ASSEMBLY__ */
-
-/* CPU kernel features */
-#define CPU_FTR_SPLIT_ID_CACHE 0x00000001
-#define CPU_FTR_L2CR 0x00000002
-#define CPU_FTR_SPEC7450 0x00000004
-#define CPU_FTR_ALTIVEC 0x00000008
-#define CPU_FTR_TAU 0x00000010
-#define CPU_FTR_CAN_DOZE 0x00000020
-#define CPU_FTR_USE_TB 0x00000040
-#define CPU_FTR_604_PERF_MON 0x00000080
-#define CPU_FTR_601 0x00000100
-#define CPU_FTR_HPTE_TABLE 0x00000200
-#define CPU_FTR_CAN_NAP 0x00000400
-#define CPU_FTR_L3CR 0x00000800
-#define CPU_FTR_L3_DISABLE_NAP 0x00001000
-#define CPU_FTR_NAP_DISABLE_L2_PR 0x00002000
-#define CPU_FTR_DUAL_PLL_750FX 0x00004000
-#define CPU_FTR_NO_DPM 0x00008000
-#define CPU_FTR_HAS_HIGH_BATS 0x00010000
-#define CPU_FTR_NEED_COHERENT 0x00020000
-#define CPU_FTR_NO_BTIC 0x00040000
-#define CPU_FTR_BIG_PHYS 0x00080000
-
-#ifdef __ASSEMBLY__
-
-#define BEGIN_FTR_SECTION 98:
-
-#define END_FTR_SECTION(msk, val) \
-99: \
- .section __ftr_fixup,"a"; \
- .align 2; \
- .long msk; \
- .long val; \
- .long 98b; \
- .long 99b; \
- .previous
-
-#else
-
-#define BEGIN_FTR_SECTION "98:\n"
-#define END_FTR_SECTION(msk, val) \
-"99:\n" \
-" .section __ftr_fixup,\"a\";\n" \
-" .align 2;\n" \
-" .long "#msk";\n" \
-" .long "#val";\n" \
-" .long 98b;\n" \
-" .long 99b;\n" \
-" .previous\n"
-
-
-#endif /* __ASSEMBLY__ */
-
-#define END_FTR_SECTION_IFSET(msk) END_FTR_SECTION((msk), (msk))
-#define END_FTR_SECTION_IFCLR(msk) END_FTR_SECTION((msk), 0)
-
-#endif /* __ASM_PPC_CPUTABLE_H */
-#endif /* __KERNEL__ */
-
diff --git a/include/asm-ppc/elf.h b/include/asm-ppc/elf.h
deleted file mode 100644
index c25cc35e6ab5..000000000000
--- a/include/asm-ppc/elf.h
+++ /dev/null
@@ -1,151 +0,0 @@
-#ifndef __PPC_ELF_H
-#define __PPC_ELF_H
-
-/*
- * ELF register definitions..
- */
-#include <asm/types.h>
-#include <asm/ptrace.h>
-#include <asm/cputable.h>
-#include <asm/auxvec.h>
-
-/* PowerPC relocations defined by the ABIs */
-#define R_PPC_NONE 0
-#define R_PPC_ADDR32 1 /* 32bit absolute address */
-#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */
-#define R_PPC_ADDR16 3 /* 16bit absolute address */
-#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */
-#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */
-#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */
-#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */
-#define R_PPC_ADDR14_BRTAKEN 8
-#define R_PPC_ADDR14_BRNTAKEN 9
-#define R_PPC_REL24 10 /* PC relative 26 bit */
-#define R_PPC_REL14 11 /* PC relative 16 bit */
-#define R_PPC_REL14_BRTAKEN 12
-#define R_PPC_REL14_BRNTAKEN 13
-#define R_PPC_GOT16 14
-#define R_PPC_GOT16_LO 15
-#define R_PPC_GOT16_HI 16
-#define R_PPC_GOT16_HA 17
-#define R_PPC_PLTREL24 18
-#define R_PPC_COPY 19
-#define R_PPC_GLOB_DAT 20
-#define R_PPC_JMP_SLOT 21
-#define R_PPC_RELATIVE 22
-#define R_PPC_LOCAL24PC 23
-#define R_PPC_UADDR32 24
-#define R_PPC_UADDR16 25
-#define R_PPC_REL32 26
-#define R_PPC_PLT32 27
-#define R_PPC_PLTREL32 28
-#define R_PPC_PLT16_LO 29
-#define R_PPC_PLT16_HI 30
-#define R_PPC_PLT16_HA 31
-#define R_PPC_SDAREL16 32
-#define R_PPC_SECTOFF 33
-#define R_PPC_SECTOFF_LO 34
-#define R_PPC_SECTOFF_HI 35
-#define R_PPC_SECTOFF_HA 36
-/* Keep this the last entry. */
-#define R_PPC_NUM 37
-
-#define ELF_NGREG 48 /* includes nip, msr, lr, etc. */
-#define ELF_NFPREG 33 /* includes fpscr */
-#define ELF_NVRREG 33 /* includes vscr */
-#define ELF_NEVRREG 34 /* includes acc (as 2) */
-
-/*
- * These are used to set parameters in the core dumps.
- */
-#define ELF_ARCH EM_PPC
-#define ELF_CLASS ELFCLASS32
-#define ELF_DATA ELFDATA2MSB
-
-/* General registers */
-typedef unsigned long elf_greg_t;
-typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-
-/* Floating point registers */
-typedef double elf_fpreg_t;
-typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
-
-/* Altivec registers */
-typedef __vector128 elf_vrreg_t;
-typedef elf_vrreg_t elf_vrregset_t[ELF_NVRREG];
-
-#ifdef __KERNEL__
-
-struct task_struct;
-
-/*
- * This is used to ensure we don't load something for the wrong architecture.
- */
-
-#define elf_check_arch(x) ((x)->e_machine == EM_PPC)
-
-/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
- use of this is to invoke "./ld.so someprog" to test out a new version of
- the loader. We need to make sure that it is out of the way of the program
- that it will "exec", and that there is sufficient room for the brk. */
-
-#define ELF_ET_DYN_BASE (0x08000000)
-
-#define USE_ELF_CORE_DUMP
-#define ELF_EXEC_PAGESIZE 4096
-
-#define ELF_CORE_COPY_REGS(gregs, regs) \
- memcpy((gregs), (regs), sizeof(struct pt_regs)); \
- memset((char *)(gregs) + sizeof(struct pt_regs), 0, \
- sizeof(elf_gregset_t) - sizeof(struct pt_regs));
-
-#define ELF_CORE_COPY_TASK_REGS(t, elfregs) \
- ((t)->thread.regs? \
- ({ ELF_CORE_COPY_REGS((elfregs), (t)->thread.regs); 1; }): 0)
-
-extern int dump_task_fpu(struct task_struct *t, elf_fpregset_t *fpu);
-#define ELF_CORE_COPY_FPREGS(t, fpu) dump_task_fpu((t), (fpu))
-
-/* This yields a mask that user programs can use to figure out what
- instruction set this cpu supports. This could be done in userspace,
- but it's not easy, and we've already done it here. */
-
-#define ELF_HWCAP (cur_cpu_spec[0]->cpu_user_features)
-
-/* This yields a string that ld.so will use to load implementation
- specific libraries for optimization. This is more specific in
- intent than poking at uname or /proc/cpuinfo.
-
- For the moment, we have only optimizations for the Intel generations,
- but that could change... */
-
-#define ELF_PLATFORM (NULL)
-
-#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
-
-extern int dcache_bsize;
-extern int icache_bsize;
-extern int ucache_bsize;
-
-/*
- * The requirements here are:
- * - keep the final alignment of sp (sp & 0xf)
- * - make sure the 32-bit value at the first 16 byte aligned position of
- * AUXV is greater than 16 for glibc compatibility.
- * AT_IGNOREPPC is used for that.
- * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
- * even if DLINFO_ARCH_ITEMS goes to zero or is undefined.
- */
-#define ARCH_DLINFO \
-do { \
- /* Handle glibc compatibility. */ \
- NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \
- NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \
- /* Cache size items */ \
- NEW_AUX_ENT(AT_DCACHEBSIZE, dcache_bsize); \
- NEW_AUX_ENT(AT_ICACHEBSIZE, icache_bsize); \
- NEW_AUX_ENT(AT_UCACHEBSIZE, ucache_bsize); \
- } while (0)
-
-#endif /* __KERNEL__ */
-#endif
diff --git a/include/asm-ppc/hw_irq.h b/include/asm-ppc/hw_irq.h
deleted file mode 100644
index 47dc7990fb26..000000000000
--- a/include/asm-ppc/hw_irq.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu>
- */
-#ifdef __KERNEL__
-#ifndef _PPC_HW_IRQ_H
-#define _PPC_HW_IRQ_H
-
-#include <asm/ptrace.h>
-#include <asm/reg.h>
-
-extern void timer_interrupt(struct pt_regs *);
-
-#define INLINE_IRQS
-
-#define irqs_disabled() ((mfmsr() & MSR_EE) == 0)
-
-#ifdef INLINE_IRQS
-
-static inline void local_irq_disable(void)
-{
- unsigned long msr;
- msr = mfmsr();
- mtmsr(msr & ~MSR_EE);
- __asm__ __volatile__("": : :"memory");
-}
-
-static inline void local_irq_enable(void)
-{
- unsigned long msr;
- __asm__ __volatile__("": : :"memory");
- msr = mfmsr();
- mtmsr(msr | MSR_EE);
-}
-
-static inline void local_irq_save_ptr(unsigned long *flags)
-{
- unsigned long msr;
- msr = mfmsr();
- *flags = msr;
- mtmsr(msr & ~MSR_EE);
- __asm__ __volatile__("": : :"memory");
-}
-
-#define local_save_flags(flags) ((flags) = mfmsr())
-#define local_irq_save(flags) local_irq_save_ptr(&flags)
-#define local_irq_restore(flags) mtmsr(flags)
-
-#else
-
-extern void local_irq_enable(void);
-extern void local_irq_disable(void);
-extern void local_irq_restore(unsigned long);
-extern void local_save_flags_ptr(unsigned long *);
-
-#define local_save_flags(flags) local_save_flags_ptr(&flags)
-#define local_irq_save(flags) ({local_save_flags(flags);local_irq_disable();})
-
-#endif
-
-extern void do_lost_interrupts(unsigned long);
-
-#define mask_irq(irq) ({if (irq_desc[irq].handler && irq_desc[irq].handler->disable) irq_desc[irq].handler->disable(irq);})
-#define unmask_irq(irq) ({if (irq_desc[irq].handler && irq_desc[irq].handler->enable) irq_desc[irq].handler->enable(irq);})
-#define ack_irq(irq) ({if (irq_desc[irq].handler && irq_desc[irq].handler->ack) irq_desc[irq].handler->ack(irq);})
-
-/* Should we handle this via lost interrupts and IPIs or should we don't care like
- * we do now ? --BenH.
- */
-struct hw_interrupt_type;
-static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
-
-
-#endif /* _PPC_HW_IRQ_H */
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/i8259.h b/include/asm-ppc/i8259.h
deleted file mode 100644
index 091b71295de4..000000000000
--- a/include/asm-ppc/i8259.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef _PPC_KERNEL_i8259_H
-#define _PPC_KERNEL_i8259_H
-
-#include <linux/irq.h>
-
-extern struct hw_interrupt_type i8259_pic;
-
-extern void i8259_init(long intack_addr);
-extern int i8259_irq(struct pt_regs *regs);
-
-#endif /* _PPC_KERNEL_i8259_H */
diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h
index 94d83998a759..f7f614dfc648 100644
--- a/include/asm-ppc/io.h
+++ b/include/asm-ppc/io.h
@@ -8,6 +8,7 @@
#include <asm/page.h>
#include <asm/byteorder.h>
+#include <asm/synch.h>
#include <asm/mmu.h>
#define SIO_CONFIG_RA 0x398
@@ -440,16 +441,6 @@ extern inline void * phys_to_virt(unsigned long address)
#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
#define page_to_bus(page) (page_to_phys(page) + PCI_DRAM_OFFSET)
-/*
- * Enforce In-order Execution of I/O:
- * Acts as a barrier to ensure all previous I/O accesses have
- * completed before any further ones are issued.
- */
-extern inline void eieio(void)
-{
- __asm__ __volatile__ ("eieio" : : : "memory");
-}
-
/* Enforce in-order execution of data I/O.
* No distinction between read/write on PPC; use eieio for all three.
*/
diff --git a/include/asm-ppc/kmap_types.h b/include/asm-ppc/kmap_types.h
deleted file mode 100644
index 6d6fc78731e5..000000000000
--- a/include/asm-ppc/kmap_types.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifdef __KERNEL__
-#ifndef _ASM_KMAP_TYPES_H
-#define _ASM_KMAP_TYPES_H
-
-enum km_type {
- KM_BOUNCE_READ,
- KM_SKB_SUNRPC_DATA,
- KM_SKB_DATA_SOFTIRQ,
- KM_USER0,
- KM_USER1,
- KM_BIO_SRC_IRQ,
- KM_BIO_DST_IRQ,
- KM_PTE0,
- KM_PTE1,
- KM_IRQ0,
- KM_IRQ1,
- KM_SOFTIRQ0,
- KM_SOFTIRQ1,
- KM_PPC_SYNC_PAGE,
- KM_PPC_SYNC_ICACHE,
- KM_TYPE_NR
-};
-
-#endif
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/machdep.h b/include/asm-ppc/machdep.h
index 1d4ab70a56f3..f01255bd1dc3 100644
--- a/include/asm-ppc/machdep.h
+++ b/include/asm-ppc/machdep.h
@@ -98,7 +98,7 @@ struct machdep_calls {
/* Get access protection for /dev/mem */
pgprot_t (*phys_mem_access_prot)(struct file *file,
- unsigned long offset,
+ unsigned long pfn,
unsigned long size,
pgprot_t vma_prot);
@@ -167,7 +167,7 @@ extern sys_ctrler_t sys_ctrler;
#ifdef CONFIG_SMP
struct smp_ops_t {
- void (*message_pass)(int target, int msg, unsigned long data, int wait);
+ void (*message_pass)(int target, int msg);
int (*probe)(void);
void (*kick_cpu)(int nr);
void (*setup_cpu)(int nr);
diff --git a/include/asm-ppc/mmu_context.h b/include/asm-ppc/mmu_context.h
index afe26ffc2e2d..4f152cca13c1 100644
--- a/include/asm-ppc/mmu_context.h
+++ b/include/asm-ppc/mmu_context.h
@@ -164,13 +164,11 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
struct task_struct *tsk)
{
#ifdef CONFIG_ALTIVEC
- asm volatile (
- BEGIN_FTR_SECTION
- "dssall;\n"
+ if (cpu_has_feature(CPU_FTR_ALTIVEC))
+ asm volatile ("dssall;\n"
#ifndef CONFIG_POWER4
"sync;\n" /* G4 needs a sync here, G5 apparently not */
#endif
- END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
: : );
#endif /* CONFIG_ALTIVEC */
diff --git a/include/asm-ppc/mpc8260.h b/include/asm-ppc/mpc8260.h
index 9694eca16e92..321452695039 100644
--- a/include/asm-ppc/mpc8260.h
+++ b/include/asm-ppc/mpc8260.h
@@ -92,6 +92,10 @@ enum ppc_sys_devices {
extern unsigned char __res[];
#endif
+#ifndef BOARD_CHIP_NAME
+#define BOARD_CHIP_NAME ""
+#endif
+
#endif /* CONFIG_8260 */
#endif /* !__ASM_PPC_MPC8260_H__ */
#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/mpc85xx.h b/include/asm-ppc/mpc85xx.h
index 516984ee14b5..d98db980cd49 100644
--- a/include/asm-ppc/mpc85xx.h
+++ b/include/asm-ppc/mpc85xx.h
@@ -67,6 +67,8 @@ extern unsigned char __res[];
#define MPC85xx_DMA3_SIZE (0x00080)
#define MPC85xx_ENET1_OFFSET (0x24000)
#define MPC85xx_ENET1_SIZE (0x01000)
+#define MPC85xx_MIIM_OFFSET (0x24520)
+#define MPC85xx_MIIM_SIZE (0x00018)
#define MPC85xx_ENET2_OFFSET (0x25000)
#define MPC85xx_ENET2_SIZE (0x01000)
#define MPC85xx_ENET3_OFFSET (0x26000)
@@ -132,6 +134,7 @@ enum ppc_sys_devices {
MPC85xx_eTSEC3,
MPC85xx_eTSEC4,
MPC85xx_IIC2,
+ MPC85xx_MDIO,
};
/* Internal interrupts are all Level Sensitive, and Positive Polarity */
diff --git a/include/asm-ppc/mpc8xx.h b/include/asm-ppc/mpc8xx.h
index 208a2e11daee..46f159cf589e 100644
--- a/include/asm-ppc/mpc8xx.h
+++ b/include/asm-ppc/mpc8xx.h
@@ -113,6 +113,10 @@ enum ppc_sys_devices {
MPC8xx_CPM_USB,
};
+#ifndef BOARD_CHIP_NAME
+#define BOARD_CHIP_NAME ""
+#endif
+
#endif /* !__ASSEMBLY__ */
#endif /* CONFIG_8xx */
#endif /* __CONFIG_8xx_DEFS */
diff --git a/include/asm-ppc/open_pic.h b/include/asm-ppc/open_pic.h
index 7848aa610c05..ec2f46629ca2 100644
--- a/include/asm-ppc/open_pic.h
+++ b/include/asm-ppc/open_pic.h
@@ -58,8 +58,7 @@ extern int openpic_get_irq(struct pt_regs *regs);
extern void openpic_reset_processor_phys(u_int cpumask);
extern void openpic_setup_ISU(int isu_num, unsigned long addr);
extern void openpic_cause_IPI(u_int ipi, cpumask_t cpumask);
-extern void smp_openpic_message_pass(int target, int msg, unsigned long data,
- int wait);
+extern void smp_openpic_message_pass(int target, int msg);
extern void openpic_set_k2_cascade(int irq);
extern void openpic_set_priority(u_int pri);
extern u_int openpic_get_priority(void);
diff --git a/include/asm-ppc/page.h b/include/asm-ppc/page.h
index 4789dc024240..fc44f7ca62d7 100644
--- a/include/asm-ppc/page.h
+++ b/include/asm-ppc/page.h
@@ -34,6 +34,17 @@ typedef unsigned long pte_basic_t;
#define PTE_FMT "%.8lx"
#endif
+/* align addr on a size boundary - adjust address up/down if needed */
+#define _ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
+#define _ALIGN_DOWN(addr,size) ((addr)&(~((size)-1)))
+
+/* align addr on a size boundary - adjust address up if needed */
+#define _ALIGN(addr,size) _ALIGN_UP(addr,size)
+
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr) _ALIGN(addr, PAGE_SIZE)
+
+
#undef STRICT_MM_TYPECHECKS
#ifdef STRICT_MM_TYPECHECKS
@@ -76,13 +87,6 @@ typedef unsigned long pgprot_t;
#endif
-
-/* align addr on a size boundary - adjust address up if needed -- Cort */
-#define _ALIGN(addr,size) (((addr)+(size)-1)&(~((size)-1)))
-
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
struct page;
extern void clear_pages(void *page, int order);
static inline void clear_page(void *page) { clear_pages(page, 0); }
diff --git a/include/asm-ppc/pci-bridge.h b/include/asm-ppc/pci-bridge.h
index ffa423456c2b..e58c78f90a5a 100644
--- a/include/asm-ppc/pci-bridge.h
+++ b/include/asm-ppc/pci-bridge.h
@@ -79,6 +79,11 @@ struct pci_controller {
struct resource mem_space;
};
+static inline struct pci_controller *pci_bus_to_host(struct pci_bus *bus)
+{
+ return bus->sysdata;
+}
+
/* These are used for config access before all the PCI probing
has been done. */
int early_read_config_byte(struct pci_controller *hose, int bus, int dev_fn,
diff --git a/include/asm-ppc/pci.h b/include/asm-ppc/pci.h
index 9dd06cd40096..61434edbad7b 100644
--- a/include/asm-ppc/pci.h
+++ b/include/asm-ppc/pci.h
@@ -24,9 +24,9 @@ struct pci_dev;
* Set this to 1 if you want the kernel to re-assign all PCI
* bus numbers
*/
-extern int pci_assign_all_busses;
+extern int pci_assign_all_buses;
-#define pcibios_assign_all_busses() (pci_assign_all_busses)
+#define pcibios_assign_all_busses() (pci_assign_all_buses)
#define pcibios_scan_all_fns(a, b) 0
#define PCIBIOS_MIN_IO 0x1000
@@ -126,7 +126,7 @@ extern void pcibios_add_platform_entries(struct pci_dev *dev);
struct file;
extern pgprot_t pci_phys_mem_access_prot(struct file *file,
- unsigned long offset,
+ unsigned long pfn,
unsigned long size,
pgprot_t prot);
diff --git a/include/asm-ppc/perfmon.h b/include/asm-ppc/perfmon.h
deleted file mode 100644
index 5e7a89c47b5b..000000000000
--- a/include/asm-ppc/perfmon.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef __PERFMON_H
-#define __PERFMON_H
-
-extern void (*perf_irq)(struct pt_regs *);
-
-int request_perfmon_irq(void (*handler)(struct pt_regs *));
-void free_perfmon_irq(void);
-
-#ifdef CONFIG_FSL_BOOKE
-void init_pmc_stop(int ctr);
-void set_pmc_event(int ctr, int event);
-void set_pmc_user_kernel(int ctr, int user, int kernel);
-void set_pmc_marked(int ctr, int mark0, int mark1);
-void pmc_start_ctr(int ctr, int enable);
-void pmc_start_ctrs(int enable);
-void pmc_stop_ctrs(void);
-void dump_pmcs(void);
-
-extern struct op_ppc32_model op_model_fsl_booke;
-#endif
-
-#endif /* __PERFMON_H */
diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h
index eee601bb9ada..b28a713ba862 100644
--- a/include/asm-ppc/pgtable.h
+++ b/include/asm-ppc/pgtable.h
@@ -705,7 +705,7 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry, int dirty)
#define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | _PAGE_NO_CACHE | _PAGE_GUARDED))
struct file;
-extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long addr,
+extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
unsigned long size, pgprot_t vma_prot);
#define __HAVE_PHYS_MEM_ACCESS_PROT
diff --git a/include/asm-ppc/posix_types.h b/include/asm-ppc/posix_types.h
deleted file mode 100644
index a14a82abe8d2..000000000000
--- a/include/asm-ppc/posix_types.h
+++ /dev/null
@@ -1,111 +0,0 @@
-#ifndef _PPC_POSIX_TYPES_H
-#define _PPC_POSIX_TYPES_H
-
-/*
- * This file is generally used by user-level software, so you need to
- * be a little careful about namespace pollution etc. Also, we cannot
- * assume GCC is being used.
- */
-
-typedef unsigned long __kernel_ino_t;
-typedef unsigned int __kernel_mode_t;
-typedef unsigned short __kernel_nlink_t;
-typedef long __kernel_off_t;
-typedef int __kernel_pid_t;
-typedef unsigned int __kernel_uid_t;
-typedef unsigned int __kernel_gid_t;
-typedef unsigned int __kernel_size_t;
-typedef int __kernel_ssize_t;
-typedef long __kernel_ptrdiff_t;
-typedef long __kernel_time_t;
-typedef long __kernel_suseconds_t;
-typedef long __kernel_clock_t;
-typedef int __kernel_timer_t;
-typedef int __kernel_clockid_t;
-typedef int __kernel_daddr_t;
-typedef char * __kernel_caddr_t;
-typedef short __kernel_ipc_pid_t;
-typedef unsigned short __kernel_uid16_t;
-typedef unsigned short __kernel_gid16_t;
-typedef unsigned int __kernel_uid32_t;
-typedef unsigned int __kernel_gid32_t;
-
-typedef unsigned int __kernel_old_uid_t;
-typedef unsigned int __kernel_old_gid_t;
-typedef unsigned int __kernel_old_dev_t;
-
-#ifdef __GNUC__
-typedef long long __kernel_loff_t;
-#endif
-
-typedef struct {
- int val[2];
-} __kernel_fsid_t;
-
-#ifndef __GNUC__
-
-#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
-#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
-#define __FD_ISSET(d, set) ((set)->fds_bits[__FDELT(d)] & __FDMASK(d))
-#define __FD_ZERO(set) \
- ((void) memset ((__ptr_t) (set), 0, sizeof (__kernel_fd_set)))
-
-#else /* __GNUC__ */
-
-#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) \
- || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
-/* With GNU C, use inline functions instead so args are evaluated only once: */
-
-#undef __FD_SET
-static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
-{
- unsigned long _tmp = fd / __NFDBITS;
- unsigned long _rem = fd % __NFDBITS;
- fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
-}
-
-#undef __FD_CLR
-static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
-{
- unsigned long _tmp = fd / __NFDBITS;
- unsigned long _rem = fd % __NFDBITS;
- fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
-}
-
-#undef __FD_ISSET
-static __inline__ int __FD_ISSET(unsigned long fd, __kernel_fd_set *p)
-{
- unsigned long _tmp = fd / __NFDBITS;
- unsigned long _rem = fd % __NFDBITS;
- return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
-}
-
-/*
- * This will unroll the loop for the normal constant case (8 ints,
- * for a 256-bit fd_set)
- */
-#undef __FD_ZERO
-static __inline__ void __FD_ZERO(__kernel_fd_set *p)
-{
- unsigned int *tmp = (unsigned int *)p->fds_bits;
- int i;
-
- if (__builtin_constant_p(__FDSET_LONGS)) {
- switch (__FDSET_LONGS) {
- case 8:
- tmp[0] = 0; tmp[1] = 0; tmp[2] = 0; tmp[3] = 0;
- tmp[4] = 0; tmp[5] = 0; tmp[6] = 0; tmp[7] = 0;
- return;
- }
- }
- i = __FDSET_LONGS;
- while (i) {
- i--;
- *tmp = 0;
- tmp++;
- }
-}
-
-#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
-#endif /* __GNUC__ */
-#endif /* _PPC_POSIX_TYPES_H */
diff --git a/include/asm-ppc/ptrace.h b/include/asm-ppc/ptrace.h
index 7043c164b537..c34fb4e37a97 100644
--- a/include/asm-ppc/ptrace.h
+++ b/include/asm-ppc/ptrace.h
@@ -57,7 +57,7 @@ extern unsigned long profile_pc(struct pt_regs *regs);
#define force_successful_syscall_return() \
do { \
- current_thread_info()->local_flags |= _TIFL_FORCE_NOERROR; \
+ current_thread_info()->syscall_noerror = 1; \
} while(0)
/*
diff --git a/include/asm-ppc/rwsem.h b/include/asm-ppc/rwsem.h
deleted file mode 100644
index 3e738f483c11..000000000000
--- a/include/asm-ppc/rwsem.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * include/asm-ppc/rwsem.h: R/W semaphores for PPC using the stuff
- * in lib/rwsem.c. Adapted largely from include/asm-i386/rwsem.h
- * by Paul Mackerras <paulus@samba.org>.
- */
-
-#ifndef _PPC_RWSEM_H
-#define _PPC_RWSEM_H
-
-#ifdef __KERNEL__
-#include <linux/list.h>
-#include <linux/spinlock.h>
-#include <asm/atomic.h>
-#include <asm/system.h>
-
-/*
- * the semaphore definition
- */
-struct rw_semaphore {
- /* XXX this should be able to be an atomic_t -- paulus */
- signed long count;
-#define RWSEM_UNLOCKED_VALUE 0x00000000
-#define RWSEM_ACTIVE_BIAS 0x00000001
-#define RWSEM_ACTIVE_MASK 0x0000ffff
-#define RWSEM_WAITING_BIAS (-0x00010000)
-#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS
-#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
- spinlock_t wait_lock;
- struct list_head wait_list;
-#if RWSEM_DEBUG
- int debug;
-#endif
-};
-
-/*
- * initialisation
- */
-#if RWSEM_DEBUG
-#define __RWSEM_DEBUG_INIT , 0
-#else
-#define __RWSEM_DEBUG_INIT /* */
-#endif
-
-#define __RWSEM_INITIALIZER(name) \
- { RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, \
- LIST_HEAD_INIT((name).wait_list) \
- __RWSEM_DEBUG_INIT }
-
-#define DECLARE_RWSEM(name) \
- struct rw_semaphore name = __RWSEM_INITIALIZER(name)
-
-extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem);
-extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem);
-extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem);
-extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem);
-
-static inline void init_rwsem(struct rw_semaphore *sem)
-{
- sem->count = RWSEM_UNLOCKED_VALUE;
- spin_lock_init(&sem->wait_lock);
- INIT_LIST_HEAD(&sem->wait_list);
-#if RWSEM_DEBUG
- sem->debug = 0;
-#endif
-}
-
-/*
- * lock for reading
- */
-static inline void __down_read(struct rw_semaphore *sem)
-{
- if (atomic_inc_return((atomic_t *)(&sem->count)) > 0)
- smp_wmb();
- else
- rwsem_down_read_failed(sem);
-}
-
-static inline int __down_read_trylock(struct rw_semaphore *sem)
-{
- int tmp;
-
- while ((tmp = sem->count) >= 0) {
- if (tmp == cmpxchg(&sem->count, tmp,
- tmp + RWSEM_ACTIVE_READ_BIAS)) {
- smp_wmb();
- return 1;
- }
- }
- return 0;
-}
-
-/*
- * lock for writing
- */
-static inline void __down_write(struct rw_semaphore *sem)
-{
- int tmp;
-
- tmp = atomic_add_return(RWSEM_ACTIVE_WRITE_BIAS,
- (atomic_t *)(&sem->count));
- if (tmp == RWSEM_ACTIVE_WRITE_BIAS)
- smp_wmb();
- else
- rwsem_down_write_failed(sem);
-}
-
-static inline int __down_write_trylock(struct rw_semaphore *sem)
-{
- int tmp;
-
- tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE,
- RWSEM_ACTIVE_WRITE_BIAS);
- smp_wmb();
- return tmp == RWSEM_UNLOCKED_VALUE;
-}
-
-/*
- * unlock after reading
- */
-static inline void __up_read(struct rw_semaphore *sem)
-{
- int tmp;
-
- smp_wmb();
- tmp = atomic_dec_return((atomic_t *)(&sem->count));
- if (tmp < -1 && (tmp & RWSEM_ACTIVE_MASK) == 0)
- rwsem_wake(sem);
-}
-
-/*
- * unlock after writing
- */
-static inline void __up_write(struct rw_semaphore *sem)
-{
- smp_wmb();
- if (atomic_sub_return(RWSEM_ACTIVE_WRITE_BIAS,
- (atomic_t *)(&sem->count)) < 0)
- rwsem_wake(sem);
-}
-
-/*
- * implement atomic add functionality
- */
-static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
-{
- atomic_add(delta, (atomic_t *)(&sem->count));
-}
-
-/*
- * downgrade write lock to read lock
- */
-static inline void __downgrade_write(struct rw_semaphore *sem)
-{
- int tmp;
-
- smp_wmb();
- tmp = atomic_add_return(-RWSEM_WAITING_BIAS, (atomic_t *)(&sem->count));
- if (tmp < 0)
- rwsem_downgrade_wake(sem);
-}
-
-/*
- * implement exchange and add functionality
- */
-static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
-{
- smp_mb();
- return atomic_add_return(delta, (atomic_t *)(&sem->count));
-}
-
-#endif /* __KERNEL__ */
-#endif /* _PPC_RWSEM_XADD_H */
diff --git a/include/asm-ppc/scatterlist.h b/include/asm-ppc/scatterlist.h
deleted file mode 100644
index f21f18f56548..000000000000
--- a/include/asm-ppc/scatterlist.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifdef __KERNEL__
-#ifndef _PPC_SCATTERLIST_H
-#define _PPC_SCATTERLIST_H
-
-#include <asm/dma.h>
-
-struct scatterlist {
- struct page *page;
- unsigned int offset;
- dma_addr_t dma_address;
- unsigned int length;
-};
-
-/*
- * These macros should be used after a pci_map_sg call has been done
- * to get bus addresses of each of the SG entries and their lengths.
- * You should only work with the number of sg entries pci_map_sg
- * returns, or alternatively stop on the first sg_dma_len(sg) which
- * is 0.
- */
-#define sg_dma_address(sg) ((sg)->dma_address)
-#define sg_dma_len(sg) ((sg)->length)
-
-#endif /* !(_PPC_SCATTERLIST_H) */
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/seccomp.h b/include/asm-ppc/seccomp.h
deleted file mode 100644
index 666c4da96d87..000000000000
--- a/include/asm-ppc/seccomp.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef _ASM_SECCOMP_H
-
-#include <linux/unistd.h>
-
-#define __NR_seccomp_read __NR_read
-#define __NR_seccomp_write __NR_write
-#define __NR_seccomp_exit __NR_exit
-#define __NR_seccomp_sigreturn __NR_rt_sigreturn
-
-#endif /* _ASM_SECCOMP_H */
diff --git a/include/asm-ppc/sections.h b/include/asm-ppc/sections.h
deleted file mode 100644
index ba8f43ac9bf3..000000000000
--- a/include/asm-ppc/sections.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifdef __KERNEL__
-#ifndef _PPC_SECTIONS_H
-#define _PPC_SECTIONS_H
-
-#include <asm-generic/sections.h>
-
-#define __pmac __attribute__ ((__section__ (".pmac.text")))
-#define __pmacdata __attribute__ ((__section__ (".pmac.data")))
-#define __pmacfunc(__argpmac) \
- __argpmac __pmac; \
- __argpmac
-
-#define __prep __attribute__ ((__section__ (".prep.text")))
-#define __prepdata __attribute__ ((__section__ (".prep.data")))
-#define __prepfunc(__argprep) \
- __argprep __prep; \
- __argprep
-
-#define __chrp __attribute__ ((__section__ (".chrp.text")))
-#define __chrpdata __attribute__ ((__section__ (".chrp.data")))
-#define __chrpfunc(__argchrp) \
- __argchrp __chrp; \
- __argchrp
-
-/* this is actually just common chrp/pmac code, not OF code -- Cort */
-#define __openfirmware __attribute__ ((__section__ (".openfirmware.text")))
-#define __openfirmwaredata __attribute__ ((__section__ (".openfirmware.data")))
-#define __openfirmwarefunc(__argopenfirmware) \
- __argopenfirmware __openfirmware; \
- __argopenfirmware
-
-#endif /* _PPC_SECTIONS_H */
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/semaphore.h b/include/asm-ppc/semaphore.h
deleted file mode 100644
index 89e6e73be08c..000000000000
--- a/include/asm-ppc/semaphore.h
+++ /dev/null
@@ -1,111 +0,0 @@
-#ifndef _PPC_SEMAPHORE_H
-#define _PPC_SEMAPHORE_H
-
-/*
- * Swiped from asm-sparc/semaphore.h and modified
- * -- Cort (cort@cs.nmt.edu)
- *
- * Stole some rw spinlock-based semaphore stuff from asm-alpha/semaphore.h
- * -- Ani Joshi (ajoshi@unixbox.com)
- *
- * Remove spinlock-based RW semaphores; RW semaphore definitions are
- * now in rwsem.h and we use the generic lib/rwsem.c implementation.
- * Rework semaphores to use atomic_dec_if_positive.
- * -- Paul Mackerras (paulus@samba.org)
- */
-
-#ifdef __KERNEL__
-
-#include <asm/atomic.h>
-#include <asm/system.h>
-#include <linux/wait.h>
-#include <linux/rwsem.h>
-
-struct semaphore {
- /*
- * Note that any negative value of count is equivalent to 0,
- * but additionally indicates that some process(es) might be
- * sleeping on `wait'.
- */
- atomic_t count;
- wait_queue_head_t wait;
-};
-
-#define __SEMAPHORE_INITIALIZER(name, n) \
-{ \
- .count = ATOMIC_INIT(n), \
- .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
-}
-
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name, 1)
-
-#define __DECLARE_SEMAPHORE_GENERIC(name, count) \
- struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
-
-#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1)
-#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name, 0)
-
-static inline void sema_init (struct semaphore *sem, int val)
-{
- atomic_set(&sem->count, val);
- init_waitqueue_head(&sem->wait);
-}
-
-static inline void init_MUTEX (struct semaphore *sem)
-{
- sema_init(sem, 1);
-}
-
-static inline void init_MUTEX_LOCKED (struct semaphore *sem)
-{
- sema_init(sem, 0);
-}
-
-extern void __down(struct semaphore * sem);
-extern int __down_interruptible(struct semaphore * sem);
-extern void __up(struct semaphore * sem);
-
-extern inline void down(struct semaphore * sem)
-{
- might_sleep();
-
- /*
- * Try to get the semaphore, take the slow path if we fail.
- */
- if (atomic_dec_return(&sem->count) < 0)
- __down(sem);
- smp_wmb();
-}
-
-extern inline int down_interruptible(struct semaphore * sem)
-{
- int ret = 0;
-
- might_sleep();
-
- if (atomic_dec_return(&sem->count) < 0)
- ret = __down_interruptible(sem);
- smp_wmb();
- return ret;
-}
-
-extern inline int down_trylock(struct semaphore * sem)
-{
- int ret;
-
- ret = atomic_dec_if_positive(&sem->count) < 0;
- smp_wmb();
- return ret;
-}
-
-extern inline void up(struct semaphore * sem)
-{
- smp_wmb();
- if (atomic_inc_return(&sem->count) <= 0)
- __up(sem);
-}
-
-#endif /* __KERNEL__ */
-
-#endif /* !(_PPC_SEMAPHORE_H) */
diff --git a/include/asm-ppc/smp.h b/include/asm-ppc/smp.h
index 829481c0a9dc..30e9268a888c 100644
--- a/include/asm-ppc/smp.h
+++ b/include/asm-ppc/smp.h
@@ -35,6 +35,7 @@ extern cpumask_t cpu_possible_map;
extern unsigned long smp_proc_in_lock[];
extern volatile unsigned long cpu_callin_map[];
extern int smp_tb_synchronized;
+extern struct smp_ops_t *smp_ops;
extern void smp_send_tlb_invalidate(int);
extern void smp_send_xmon_break(int cpu);
@@ -45,32 +46,31 @@ extern int __cpu_disable(void);
extern void __cpu_die(unsigned int cpu);
extern void cpu_die(void) __attribute__((noreturn));
-#define NO_PROC_ID 0xFF /* No processor magic marker */
-#define PROC_CHANGE_PENALTY 20
-
#define raw_smp_processor_id() (current_thread_info()->cpu)
extern int __cpu_up(unsigned int cpu);
extern int smp_hw_index[];
-#define hard_smp_processor_id() (smp_hw_index[smp_processor_id()])
-
-struct klock_info_struct {
- unsigned long kernel_flag;
- unsigned char akp;
-};
-
-extern struct klock_info_struct klock_info;
-#define KLOCK_HELD 0xffffffff
-#define KLOCK_CLEAR 0x0
-
+#define hard_smp_processor_id() (smp_hw_index[smp_processor_id()])
+#define get_hard_smp_processor_id(cpu) (smp_hw_index[(cpu)])
+#define set_hard_smp_processor_id(cpu, phys)\
+ (smp_hw_index[(cpu)] = (phys))
+
#endif /* __ASSEMBLY__ */
#else /* !(CONFIG_SMP) */
static inline void cpu_die(void) { }
+#define get_hard_smp_processor_id(cpu) 0
+#define set_hard_smp_processor_id(cpu, phys)
+#define hard_smp_processor_id() 0
#endif /* !(CONFIG_SMP) */
+#ifndef __ASSEMBLY__
+extern int boot_cpuid;
+extern int boot_cpuid_phys;
+#endif
+
#endif /* !(_PPC_SMP_H) */
#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/spinlock.h b/include/asm-ppc/spinlock.h
index 20edcf2a6e0c..5c64b75f0295 100644
--- a/include/asm-ppc/spinlock.h
+++ b/include/asm-ppc/spinlock.h
@@ -9,7 +9,7 @@
* (the type definitions are in asm/raw_spinlock_types.h)
*/
-#define __raw_spin_is_locked(x) ((x)->lock != 0)
+#define __raw_spin_is_locked(x) ((x)->slock != 0)
#define __raw_spin_unlock_wait(lock) \
do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0)
#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
@@ -31,17 +31,17 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock)
bne- 2b\n\
isync"
: "=&r"(tmp)
- : "r"(&lock->lock), "r"(1)
+ : "r"(&lock->slock), "r"(1)
: "cr0", "memory");
}
static inline void __raw_spin_unlock(raw_spinlock_t *lock)
{
__asm__ __volatile__("eieio # __raw_spin_unlock": : :"memory");
- lock->lock = 0;
+ lock->slock = 0;
}
-#define __raw_spin_trylock(l) (!test_and_set_bit(0,&(l)->lock))
+#define __raw_spin_trylock(l) (!test_and_set_bit(0,(volatile unsigned long *)(&(l)->slock)))
/*
* Read-write spinlocks, allowing multiple readers
diff --git a/include/asm-ppc/spinlock_types.h b/include/asm-ppc/spinlock_types.h
deleted file mode 100644
index 7919ccc75b8a..000000000000
--- a/include/asm-ppc/spinlock_types.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef __ASM_SPINLOCK_TYPES_H
-#define __ASM_SPINLOCK_TYPES_H
-
-#ifndef __LINUX_SPINLOCK_TYPES_H
-# error "please don't include this file directly"
-#endif
-
-typedef struct {
- volatile unsigned long lock;
-} raw_spinlock_t;
-
-#define __RAW_SPIN_LOCK_UNLOCKED { 0 }
-
-typedef struct {
- volatile signed int lock;
-} raw_rwlock_t;
-
-#define __RAW_RW_LOCK_UNLOCKED { 0 }
-
-#endif
diff --git a/include/asm-ppc/statfs.h b/include/asm-ppc/statfs.h
deleted file mode 100644
index 807c69954a1b..000000000000
--- a/include/asm-ppc/statfs.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef _PPC_STATFS_H
-#define _PPC_STATFS_H
-
-#include <asm-generic/statfs.h>
-#endif
-
-
-
diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h
index d754ab570fe0..bd99cb53a19f 100644
--- a/include/asm-ppc/system.h
+++ b/include/asm-ppc/system.h
@@ -70,25 +70,47 @@ extern void _set_L3CR(unsigned long);
#endif
extern void via_cuda_init(void);
extern void pmac_nvram_init(void);
+extern void chrp_nvram_init(void);
extern void read_rtc_time(void);
extern void pmac_find_display(void);
extern void giveup_fpu(struct task_struct *);
extern void enable_kernel_fp(void);
+extern void flush_fp_to_thread(struct task_struct *);
extern void enable_kernel_altivec(void);
extern void giveup_altivec(struct task_struct *);
extern void load_up_altivec(struct task_struct *);
+extern int emulate_altivec(struct pt_regs *);
extern void giveup_spe(struct task_struct *);
extern void load_up_spe(struct task_struct *);
extern int fix_alignment(struct pt_regs *);
-extern void cvt_fd(float *from, double *to, unsigned long *fpscr);
-extern void cvt_df(double *from, float *to, unsigned long *fpscr);
+extern void cvt_fd(float *from, double *to, struct thread_struct *thread);
+extern void cvt_df(double *from, float *to, struct thread_struct *thread);
+
+#ifdef CONFIG_ALTIVEC
+extern void flush_altivec_to_thread(struct task_struct *);
+#else
+static inline void flush_altivec_to_thread(struct task_struct *t)
+{
+}
+#endif
+
+#ifdef CONFIG_SPE
+extern void flush_spe_to_thread(struct task_struct *);
+#else
+static inline void flush_spe_to_thread(struct task_struct *t)
+{
+}
+#endif
+
extern int call_rtas(const char *, int, int, unsigned long *, ...);
extern void cacheable_memzero(void *p, unsigned int nb);
extern void *cacheable_memcpy(void *, const void *, unsigned int);
extern int do_page_fault(struct pt_regs *, unsigned long, unsigned long);
extern void bad_page_fault(struct pt_regs *, unsigned long, int);
-extern void die(const char *, struct pt_regs *, long);
+extern int die(const char *, struct pt_regs *, long);
extern void _exception(int, struct pt_regs *, int, unsigned long);
+void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
+
#ifdef CONFIG_BOOKE_WDT
extern u32 booke_wdt_enabled;
extern u32 booke_wdt_period;
diff --git a/include/asm-ppc/thread_info.h b/include/asm-ppc/thread_info.h
deleted file mode 100644
index 27903db42efc..000000000000
--- a/include/asm-ppc/thread_info.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/* thread_info.h: PPC low-level thread information
- * adapted from the i386 version by Paul Mackerras
- *
- * Copyright (C) 2002 David Howells (dhowells@redhat.com)
- * - Incorporating suggestions made by Linus Torvalds and Dave Miller
- */
-
-#ifndef _ASM_THREAD_INFO_H
-#define _ASM_THREAD_INFO_H
-
-#ifdef __KERNEL__
-#ifndef __ASSEMBLY__
-/*
- * low level task data.
- * If you change this, change the TI_* offsets below to match.
- */
-struct thread_info {
- struct task_struct *task; /* main task structure */
- struct exec_domain *exec_domain; /* execution domain */
- unsigned long flags; /* low level flags */
- unsigned long local_flags; /* non-racy flags */
- int cpu; /* cpu we're on */
- int preempt_count; /* 0 => preemptable,
- <0 => BUG */
- struct restart_block restart_block;
-};
-
-#define INIT_THREAD_INFO(tsk) \
-{ \
- .task = &tsk, \
- .exec_domain = &default_exec_domain, \
- .flags = 0, \
- .local_flags = 0, \
- .cpu = 0, \
- .preempt_count = 1, \
- .restart_block = { \
- .fn = do_no_restart_syscall, \
- }, \
-}
-
-#define init_thread_info (init_thread_union.thread_info)
-#define init_stack (init_thread_union.stack)
-
-/*
- * macros/functions for gaining access to the thread information structure
- */
-
-/* how to get the thread information struct from C */
-static inline struct thread_info *current_thread_info(void)
-{
- struct thread_info *ti;
- __asm__("rlwinm %0,1,0,0,18" : "=r"(ti));
- return ti;
-}
-
-/* thread information allocation */
-#define alloc_thread_info(tsk) ((struct thread_info *) \
- __get_free_pages(GFP_KERNEL, 1))
-#define free_thread_info(ti) free_pages((unsigned long) (ti), 1)
-#define get_thread_info(ti) get_task_struct((ti)->task)
-#define put_thread_info(ti) put_task_struct((ti)->task)
-#endif /* __ASSEMBLY__ */
-
-/*
- * Size of kernel stack for each process.
- */
-#define THREAD_SIZE 8192 /* 2 pages */
-
-#define PREEMPT_ACTIVE 0x10000000
-
-/*
- * thread information flag bit numbers
- */
-#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
-#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */
-#define TIF_SIGPENDING 2 /* signal pending */
-#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
-#define TIF_POLLING_NRFLAG 4 /* true if poll_idle() is polling
- TIF_NEED_RESCHED */
-#define TIF_MEMDIE 5
-#define TIF_SYSCALL_AUDIT 6 /* syscall auditing active */
-#define TIF_SECCOMP 7 /* secure computing */
-
-/* as above, but as bit values */
-#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
-#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
-#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
-#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
-#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
-#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
-#define _TIF_SECCOMP (1<<TIF_SECCOMP)
-
-#define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP)
-
-/*
- * Non racy (local) flags bit numbers
- */
-#define TIFL_FORCE_NOERROR 0 /* don't return error from current
- syscall even if result < 0 */
-
-/* as above, but as bit values */
-#define _TIFL_FORCE_NOERROR (1<<TIFL_FORCE_NOERROR)
-
-
-#endif /* __KERNEL__ */
-
-#endif /* _ASM_THREAD_INFO_H */
diff --git a/include/asm-ppc/types.h b/include/asm-ppc/types.h
deleted file mode 100644
index 77dc24d7d2ad..000000000000
--- a/include/asm-ppc/types.h
+++ /dev/null
@@ -1,69 +0,0 @@
-#ifndef _PPC_TYPES_H
-#define _PPC_TYPES_H
-
-#ifndef __ASSEMBLY__
-
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
-
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-typedef __signed__ long long __s64;
-typedef unsigned long long __u64;
-#endif
-
-typedef struct {
- __u32 u[4];
-} __vector128;
-
-/*
- * XXX allowed outside of __KERNEL__ for now, until glibc gets
- * a proper set of asm headers of its own. -- paulus
- */
-typedef unsigned short umode_t;
-
-#endif /* __ASSEMBLY__ */
-
-#ifdef __KERNEL__
-/*
- * These aren't exported outside the kernel to avoid name space clashes
- */
-#define BITS_PER_LONG 32
-
-#ifndef __ASSEMBLY__
-
-#include <linux/config.h>
-
-typedef signed char s8;
-typedef unsigned char u8;
-
-typedef signed short s16;
-typedef unsigned short u16;
-
-typedef signed int s32;
-typedef unsigned int u32;
-
-typedef signed long long s64;
-typedef unsigned long long u64;
-
-typedef __vector128 vector128;
-
-/* DMA addresses are 32-bits wide */
-typedef u32 dma_addr_t;
-typedef u64 dma64_addr_t;
-
-#ifdef CONFIG_LBD
-typedef u64 sector_t;
-#define HAVE_SECTOR_T
-#endif
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* __KERNEL__ */
-
-#endif
diff --git a/include/asm-ppc/vga.h b/include/asm-ppc/vga.h
deleted file mode 100644
index c5864734e3e1..000000000000
--- a/include/asm-ppc/vga.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Access to VGA videoram
- *
- * (c) 1998 Martin Mares <mj@ucw.cz>
- */
-
-#ifdef __KERNEL__
-#ifndef _LINUX_ASM_VGA_H_
-#define _LINUX_ASM_VGA_H_
-
-#include <asm/io.h>
-
-#include <linux/config.h>
-
-#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_MDA_CONSOLE)
-
-#define VT_BUF_HAVE_RW
-/*
- * These are only needed for supporting VGA or MDA text mode, which use little
- * endian byte ordering.
- * In other cases, we can optimize by using native byte ordering and
- * <linux/vt_buffer.h> has already done the right job for us.
- */
-
-extern inline void scr_writew(u16 val, volatile u16 *addr)
-{
- st_le16(addr, val);
-}
-
-extern inline u16 scr_readw(volatile const u16 *addr)
-{
- return ld_le16(addr);
-}
-
-#define VT_BUF_HAVE_MEMCPYW
-#define scr_memcpyw memcpy
-
-#endif /* !CONFIG_VGA_CONSOLE && !CONFIG_MDA_CONSOLE */
-
-extern unsigned long vgacon_remap_base;
-#define VGA_MAP_MEM(x) (x + vgacon_remap_base)
-#define vga_readb(x) (*(x))
-#define vga_writeb(x,y) (*(y) = (x))
-
-#endif
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/xmon.h b/include/asm-ppc/xmon.h
deleted file mode 100644
index 042b83e6680d..000000000000
--- a/include/asm-ppc/xmon.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef __PPC_XMON_H
-#define __PPC_XMON_H
-#ifdef __KERNEL__
-
-struct pt_regs;
-
-extern void xmon(struct pt_regs *excp);
-extern void xmon_printf(const char *fmt, ...);
-extern void xmon_map_scc(void);
-extern int xmon_bpt(struct pt_regs *regs);
-extern int xmon_sstep(struct pt_regs *regs);
-extern int xmon_iabr_match(struct pt_regs *regs);
-extern int xmon_dabr_match(struct pt_regs *regs);
-extern void (*xmon_fault_handler)(struct pt_regs *regs);
-
-#endif
-#endif
diff --git a/include/asm-ppc64/abs_addr.h b/include/asm-ppc64/abs_addr.h
index 84c24d4cdb71..dc3fc3fefef2 100644
--- a/include/asm-ppc64/abs_addr.h
+++ b/include/asm-ppc64/abs_addr.h
@@ -63,4 +63,11 @@ static inline unsigned long phys_to_abs(unsigned long pa)
#define virt_to_abs(va) phys_to_abs(__pa(va))
#define abs_to_virt(aa) __va(aa)
+/*
+ * Converts Virtual Address to Real Address for
+ * Legacy iSeries Hypervisor calls
+ */
+#define iseries_hv_addr(virtaddr) \
+ (0x8000000000000000 | virt_to_abs(virtaddr))
+
#endif /* _ABS_ADDR_H */
diff --git a/include/asm-ppc64/atomic.h b/include/asm-ppc64/atomic.h
deleted file mode 100644
index 0e5f25e83bc0..000000000000
--- a/include/asm-ppc64/atomic.h
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * PowerPC64 atomic operations
- *
- * Copyright (C) 2001 Paul Mackerras <paulus@au.ibm.com>, IBM
- * Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
- *
- * This program is free software; you can redistribute 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_PPC64_ATOMIC_H_
-#define _ASM_PPC64_ATOMIC_H_
-
-#include <asm/memory.h>
-
-typedef struct { volatile int counter; } atomic_t;
-
-#define ATOMIC_INIT(i) { (i) }
-
-#define atomic_read(v) ((v)->counter)
-#define atomic_set(v,i) (((v)->counter) = (i))
-
-static __inline__ void atomic_add(int a, atomic_t *v)
-{
- int t;
-
- __asm__ __volatile__(
-"1: lwarx %0,0,%3 # atomic_add\n\
- add %0,%2,%0\n\
- stwcx. %0,0,%3\n\
- bne- 1b"
- : "=&r" (t), "=m" (v->counter)
- : "r" (a), "r" (&v->counter), "m" (v->counter)
- : "cc");
-}
-
-static __inline__ int atomic_add_return(int a, atomic_t *v)
-{
- int t;
-
- __asm__ __volatile__(
- EIEIO_ON_SMP
-"1: lwarx %0,0,%2 # atomic_add_return\n\
- add %0,%1,%0\n\
- stwcx. %0,0,%2\n\
- bne- 1b"
- ISYNC_ON_SMP
- : "=&r" (t)
- : "r" (a), "r" (&v->counter)
- : "cc", "memory");
-
- return t;
-}
-
-#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
-
-static __inline__ void atomic_sub(int a, atomic_t *v)
-{
- int t;
-
- __asm__ __volatile__(
-"1: lwarx %0,0,%3 # atomic_sub\n\
- subf %0,%2,%0\n\
- stwcx. %0,0,%3\n\
- bne- 1b"
- : "=&r" (t), "=m" (v->counter)
- : "r" (a), "r" (&v->counter), "m" (v->counter)
- : "cc");
-}
-
-static __inline__ int atomic_sub_return(int a, atomic_t *v)
-{
- int t;
-
- __asm__ __volatile__(
- EIEIO_ON_SMP
-"1: lwarx %0,0,%2 # atomic_sub_return\n\
- subf %0,%1,%0\n\
- stwcx. %0,0,%2\n\
- bne- 1b"
- ISYNC_ON_SMP
- : "=&r" (t)
- : "r" (a), "r" (&v->counter)
- : "cc", "memory");
-
- return t;
-}
-
-static __inline__ void atomic_inc(atomic_t *v)
-{
- int t;
-
- __asm__ __volatile__(
-"1: lwarx %0,0,%2 # atomic_inc\n\
- addic %0,%0,1\n\
- stwcx. %0,0,%2\n\
- bne- 1b"
- : "=&r" (t), "=m" (v->counter)
- : "r" (&v->counter), "m" (v->counter)
- : "cc");
-}
-
-static __inline__ int atomic_inc_return(atomic_t *v)
-{
- int t;
-
- __asm__ __volatile__(
- EIEIO_ON_SMP
-"1: lwarx %0,0,%1 # atomic_inc_return\n\
- addic %0,%0,1\n\
- stwcx. %0,0,%1\n\
- bne- 1b"
- ISYNC_ON_SMP
- : "=&r" (t)
- : "r" (&v->counter)
- : "cc", "memory");
-
- return t;
-}
-
-/*
- * atomic_inc_and_test - increment and test
- * @v: pointer of type atomic_t
- *
- * Atomically increments @v by 1
- * and returns true if the result is zero, or false for all
- * other cases.
- */
-#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
-
-static __inline__ void atomic_dec(atomic_t *v)
-{
- int t;
-
- __asm__ __volatile__(
-"1: lwarx %0,0,%2 # atomic_dec\n\
- addic %0,%0,-1\n\
- stwcx. %0,0,%2\n\
- bne- 1b"
- : "=&r" (t), "=m" (v->counter)
- : "r" (&v->counter), "m" (v->counter)
- : "cc");
-}
-
-static __inline__ int atomic_dec_return(atomic_t *v)
-{
- int t;
-
- __asm__ __volatile__(
- EIEIO_ON_SMP
-"1: lwarx %0,0,%1 # atomic_dec_return\n\
- addic %0,%0,-1\n\
- stwcx. %0,0,%1\n\
- bne- 1b"
- ISYNC_ON_SMP
- : "=&r" (t)
- : "r" (&v->counter)
- : "cc", "memory");
-
- return t;
-}
-
-#define atomic_sub_and_test(a, v) (atomic_sub_return((a), (v)) == 0)
-#define atomic_dec_and_test(v) (atomic_dec_return((v)) == 0)
-
-/*
- * Atomically test *v and decrement if it is greater than 0.
- * The function returns the old value of *v minus 1.
- */
-static __inline__ int atomic_dec_if_positive(atomic_t *v)
-{
- int t;
-
- __asm__ __volatile__(
- EIEIO_ON_SMP
-"1: lwarx %0,0,%1 # atomic_dec_if_positive\n\
- addic. %0,%0,-1\n\
- blt- 2f\n\
- stwcx. %0,0,%1\n\
- bne- 1b"
- ISYNC_ON_SMP
- "\n\
-2:" : "=&r" (t)
- : "r" (&v->counter)
- : "cc", "memory");
-
- return t;
-}
-
-#define smp_mb__before_atomic_dec() smp_mb()
-#define smp_mb__after_atomic_dec() smp_mb()
-#define smp_mb__before_atomic_inc() smp_mb()
-#define smp_mb__after_atomic_inc() smp_mb()
-
-#endif /* _ASM_PPC64_ATOMIC_H_ */
diff --git a/include/asm-ppc64/bitops.h b/include/asm-ppc64/bitops.h
index a0f831224f96..dbfa42ef4a99 100644
--- a/include/asm-ppc64/bitops.h
+++ b/include/asm-ppc64/bitops.h
@@ -42,7 +42,7 @@
#ifdef __KERNEL__
-#include <asm/memory.h>
+#include <asm/synch.h>
/*
* clear_bit doesn't imply a memory barrier
diff --git a/include/asm-ppc64/bootinfo.h b/include/asm-ppc64/bootinfo.h
deleted file mode 100644
index f55e7cb48f46..000000000000
--- a/include/asm-ppc64/bootinfo.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Non-machine dependent bootinfo structure. Basic idea
- * borrowed from the m68k.
- *
- * Copyright (C) 1999 Cort Dougan <cort@ppc.kernel.org>
- * Copyright (c) 2001 PPC64 Team, IBM Corp
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-
-#ifndef _PPC64_BOOTINFO_H
-#define _PPC64_BOOTINFO_H
-
-#include <asm/types.h>
-
-/* We use a u32 for the type of the fields since they're written by
- * the bootloader which is a 32-bit process and read by the kernel
- * which is a 64-bit process. This way they can both agree on the
- * size of the type.
- */
-typedef u32 bi_rec_field;
-
-struct bi_record {
- bi_rec_field tag; /* tag ID */
- bi_rec_field size; /* size of record (in bytes) */
- bi_rec_field data[0]; /* data */
-};
-
-#define BI_FIRST 0x1010 /* first record - marker */
-#define BI_LAST 0x1011 /* last record - marker */
-#define BI_CMD_LINE 0x1012
-#define BI_BOOTLOADER_ID 0x1013
-#define BI_INITRD 0x1014
-#define BI_SYSMAP 0x1015
-#define BI_MACHTYPE 0x1016
-
-static __inline__ struct bi_record * bi_rec_init(unsigned long addr)
-{
- struct bi_record *bi_recs;
- bi_recs = (struct bi_record *)_ALIGN(addr, PAGE_SIZE);
- bi_recs->size = 0;
- return bi_recs;
-}
-
-static __inline__ struct bi_record * bi_rec_alloc(struct bi_record *rec,
- unsigned long args)
-{
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
- rec->size = sizeof(struct bi_record) + args*sizeof(bi_rec_field);
- return rec;
-}
-
-static __inline__ struct bi_record * bi_rec_alloc_bytes(struct bi_record *rec,
- unsigned long bytes)
-{
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
- rec->size = sizeof(struct bi_record) + bytes;
- return rec;
-}
-
-static __inline__ struct bi_record * bi_rec_next(struct bi_record *rec)
-{
- return (struct bi_record *)((unsigned long)rec + rec->size);
-}
-
-#endif /* _PPC64_BOOTINFO_H */
diff --git a/include/asm-ppc64/btext.h b/include/asm-ppc64/btext.h
index 67aef0cc72c0..71cce36bc630 100644
--- a/include/asm-ppc64/btext.h
+++ b/include/asm-ppc64/btext.h
@@ -15,6 +15,7 @@ extern int boot_text_mapped;
extern int btext_initialize(struct device_node *np);
extern void map_boot_text(void);
+extern void init_boot_display(void);
extern void btext_update_display(unsigned long phys, int width, int height,
int depth, int pitch);
diff --git a/include/asm-ppc64/cputable.h b/include/asm-ppc64/cputable.h
deleted file mode 100644
index acc9b4d6c168..000000000000
--- a/include/asm-ppc64/cputable.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * include/asm-ppc64/cputable.h
- *
- * Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org)
- *
- * Modifications for ppc64:
- * Copyright (C) 2003 Dave Engebretsen <engebret@us.ibm.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_PPC_CPUTABLE_H
-#define __ASM_PPC_CPUTABLE_H
-
-#include <linux/config.h>
-#include <asm/page.h> /* for ASM_CONST */
-
-/* Exposed to userland CPU features - Must match ppc32 definitions */
-#define PPC_FEATURE_32 0x80000000
-#define PPC_FEATURE_64 0x40000000
-#define PPC_FEATURE_601_INSTR 0x20000000
-#define PPC_FEATURE_HAS_ALTIVEC 0x10000000
-#define PPC_FEATURE_HAS_FPU 0x08000000
-#define PPC_FEATURE_HAS_MMU 0x04000000
-#define PPC_FEATURE_HAS_4xxMAC 0x02000000
-#define PPC_FEATURE_UNIFIED_CACHE 0x01000000
-
-#ifdef __KERNEL__
-
-#ifndef __ASSEMBLY__
-
-/* This structure can grow, it's real size is used by head.S code
- * via the mkdefs mechanism.
- */
-struct cpu_spec;
-struct op_ppc64_model;
-
-typedef void (*cpu_setup_t)(unsigned long offset, struct cpu_spec* spec);
-
-struct cpu_spec {
- /* CPU is matched via (PVR & pvr_mask) == pvr_value */
- unsigned int pvr_mask;
- unsigned int pvr_value;
-
- char *cpu_name;
- unsigned long cpu_features; /* Kernel features */
- unsigned int cpu_user_features; /* Userland features */
-
- /* cache line sizes */
- unsigned int icache_bsize;
- unsigned int dcache_bsize;
-
- /* number of performance monitor counters */
- unsigned int num_pmcs;
-
- /* this is called to initialize various CPU bits like L1 cache,
- * BHT, SPD, etc... from head.S before branching to identify_machine
- */
- cpu_setup_t cpu_setup;
-
- /* Used by oprofile userspace to select the right counters */
- char *oprofile_cpu_type;
-
- /* Processor specific oprofile operations */
- struct op_ppc64_model *oprofile_model;
-};
-
-extern struct cpu_spec cpu_specs[];
-extern struct cpu_spec *cur_cpu_spec;
-
-static inline unsigned long cpu_has_feature(unsigned long feature)
-{
- return cur_cpu_spec->cpu_features & feature;
-}
-
-#endif /* __ASSEMBLY__ */
-
-/* CPU kernel features */
-
-/* Retain the 32b definitions for the time being - use bottom half of word */
-#define CPU_FTR_SPLIT_ID_CACHE ASM_CONST(0x0000000000000001)
-#define CPU_FTR_L2CR ASM_CONST(0x0000000000000002)
-#define CPU_FTR_SPEC7450 ASM_CONST(0x0000000000000004)
-#define CPU_FTR_ALTIVEC ASM_CONST(0x0000000000000008)
-#define CPU_FTR_TAU ASM_CONST(0x0000000000000010)
-#define CPU_FTR_CAN_DOZE ASM_CONST(0x0000000000000020)
-#define CPU_FTR_USE_TB ASM_CONST(0x0000000000000040)
-#define CPU_FTR_604_PERF_MON ASM_CONST(0x0000000000000080)
-#define CPU_FTR_601 ASM_CONST(0x0000000000000100)
-#define CPU_FTR_HPTE_TABLE ASM_CONST(0x0000000000000200)
-#define CPU_FTR_CAN_NAP ASM_CONST(0x0000000000000400)
-#define CPU_FTR_L3CR ASM_CONST(0x0000000000000800)
-#define CPU_FTR_L3_DISABLE_NAP ASM_CONST(0x0000000000001000)
-#define CPU_FTR_NAP_DISABLE_L2_PR ASM_CONST(0x0000000000002000)
-#define CPU_FTR_DUAL_PLL_750FX ASM_CONST(0x0000000000004000)
-
-/* Add the 64b processor unique features in the top half of the word */
-#define CPU_FTR_SLB ASM_CONST(0x0000000100000000)
-#define CPU_FTR_16M_PAGE ASM_CONST(0x0000000200000000)
-#define CPU_FTR_TLBIEL ASM_CONST(0x0000000400000000)
-#define CPU_FTR_NOEXECUTE ASM_CONST(0x0000000800000000)
-#define CPU_FTR_NODSISRALIGN ASM_CONST(0x0000001000000000)
-#define CPU_FTR_IABR ASM_CONST(0x0000002000000000)
-#define CPU_FTR_MMCRA ASM_CONST(0x0000004000000000)
-/* unused ASM_CONST(0x0000008000000000) */
-#define CPU_FTR_SMT ASM_CONST(0x0000010000000000)
-#define CPU_FTR_COHERENT_ICACHE ASM_CONST(0x0000020000000000)
-#define CPU_FTR_LOCKLESS_TLBIE ASM_CONST(0x0000040000000000)
-#define CPU_FTR_MMCRA_SIHV ASM_CONST(0x0000080000000000)
-#define CPU_FTR_CTRL ASM_CONST(0x0000100000000000)
-
-#ifndef __ASSEMBLY__
-
-#define COMMON_USER_PPC64 (PPC_FEATURE_32 | PPC_FEATURE_64 | \
- PPC_FEATURE_HAS_FPU | PPC_FEATURE_HAS_MMU)
-
-#define CPU_FTR_PPCAS_ARCH_V2_BASE (CPU_FTR_SLB | \
- CPU_FTR_TLBIEL | CPU_FTR_NOEXECUTE | \
- CPU_FTR_NODSISRALIGN | CPU_FTR_CTRL)
-
-/* iSeries doesn't support large pages */
-#ifdef CONFIG_PPC_ISERIES
-#define CPU_FTR_PPCAS_ARCH_V2 (CPU_FTR_PPCAS_ARCH_V2_BASE)
-#else
-#define CPU_FTR_PPCAS_ARCH_V2 (CPU_FTR_PPCAS_ARCH_V2_BASE | CPU_FTR_16M_PAGE)
-#endif /* CONFIG_PPC_ISERIES */
-
-#endif /* __ASSEMBLY */
-
-#ifdef __ASSEMBLY__
-
-#define BEGIN_FTR_SECTION 98:
-
-#define END_FTR_SECTION(msk, val) \
-99: \
- .section __ftr_fixup,"a"; \
- .align 3; \
- .llong msk; \
- .llong val; \
- .llong 98b; \
- .llong 99b; \
- .previous
-
-#else
-
-#define BEGIN_FTR_SECTION "98:\n"
-#define END_FTR_SECTION(msk, val) \
-"99:\n" \
-" .section __ftr_fixup,\"a\";\n" \
-" .align 3;\n" \
-" .llong "#msk";\n" \
-" .llong "#val";\n" \
-" .llong 98b;\n" \
-" .llong 99b;\n" \
-" .previous\n"
-
-#endif /* __ASSEMBLY__ */
-
-#define END_FTR_SECTION_IFSET(msk) END_FTR_SECTION((msk), (msk))
-#define END_FTR_SECTION_IFCLR(msk) END_FTR_SECTION((msk), 0)
-
-#endif /* __ASM_PPC_CPUTABLE_H */
-#endif /* __KERNEL__ */
-
diff --git a/include/asm-ppc64/dart.h b/include/asm-ppc64/dart.h
new file mode 100644
index 000000000000..cdf8a2dec05f
--- /dev/null
+++ b/include/asm-ppc64/dart.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2004 Olof Johansson <olof@austin.ibm.com>, IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _ASM_DART_H
+#define _ASM_DART_H
+
+
+/* physical base of DART registers */
+#define DART_BASE 0xf8033000UL
+
+/* Offset from base to control register */
+#define DARTCNTL 0
+/* Offset from base to exception register */
+#define DARTEXCP 0x10
+/* Offset from base to TLB tag registers */
+#define DARTTAG 0x1000
+
+
+/* Control Register fields */
+
+/* base address of table (pfn) */
+#define DARTCNTL_BASE_MASK 0xfffff
+#define DARTCNTL_BASE_SHIFT 12
+
+#define DARTCNTL_FLUSHTLB 0x400
+#define DARTCNTL_ENABLE 0x200
+
+/* size of table in pages */
+#define DARTCNTL_SIZE_MASK 0x1ff
+#define DARTCNTL_SIZE_SHIFT 0
+
+
+/* DART table fields */
+
+#define DARTMAP_VALID 0x80000000
+#define DARTMAP_RPNMASK 0x00ffffff
+
+
+#define DART_PAGE_SHIFT 12
+#define DART_PAGE_SIZE (1 << DART_PAGE_SHIFT)
+#define DART_PAGE_FACTOR (PAGE_SHIFT - DART_PAGE_SHIFT)
+
+
+#endif
diff --git a/include/asm-ppc64/dbdma.h b/include/asm-ppc64/dbdma.h
deleted file mode 100644
index f2d5d5dc3377..000000000000
--- a/include/asm-ppc64/dbdma.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include <asm-ppc/dbdma.h>
-
diff --git a/include/asm-ppc64/dma.h b/include/asm-ppc64/dma.h
deleted file mode 100644
index dfd1f69059ba..000000000000
--- a/include/asm-ppc64/dma.h
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * linux/include/asm/dma.h: Defines for using and allocating dma channels.
- * Written by Hennus Bergman, 1992.
- * High DMA channel support & info by Hannu Savolainen
- * and John Boyd, Nov. 1992.
- * Changes for ppc sound by Christoph Nadig
- *
- * This program is free software; you can redistribute 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_DMA_H
-#define _ASM_DMA_H
-
-#include <linux/config.h>
-#include <asm/io.h>
-#include <linux/spinlock.h>
-#include <asm/system.h>
-
-#ifndef MAX_DMA_CHANNELS
-#define MAX_DMA_CHANNELS 8
-#endif
-
-/* The maximum address that we can perform a DMA transfer to on this platform */
-/* Doesn't really apply... */
-#define MAX_DMA_ADDRESS (~0UL)
-
-#if !defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI)
-
-#define dma_outb outb
-#define dma_inb inb
-
-/*
- * NOTES about DMA transfers:
- *
- * controller 1: channels 0-3, byte operations, ports 00-1F
- * controller 2: channels 4-7, word operations, ports C0-DF
- *
- * - ALL registers are 8 bits only, regardless of transfer size
- * - channel 4 is not used - cascades 1 into 2.
- * - channels 0-3 are byte - addresses/counts are for physical bytes
- * - channels 5-7 are word - addresses/counts are for physical words
- * - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries
- * - transfer count loaded to registers is 1 less than actual count
- * - controller 2 offsets are all even (2x offsets for controller 1)
- * - page registers for 5-7 don't use data bit 0, represent 128K pages
- * - page registers for 0-3 use bit 0, represent 64K pages
- *
- * On PReP, DMA transfers are limited to the lower 16MB of _physical_ memory.
- * On CHRP, the W83C553F (and VLSI Tollgate?) support full 32 bit addressing.
- * Note that addresses loaded into registers must be _physical_ addresses,
- * not logical addresses (which may differ if paging is active).
- *
- * Address mapping for channels 0-3:
- *
- * A23 ... A16 A15 ... A8 A7 ... A0 (Physical addresses)
- * | ... | | ... | | ... |
- * | ... | | ... | | ... |
- * | ... | | ... | | ... |
- * P7 ... P0 A7 ... A0 A7 ... A0
- * | Page | Addr MSB | Addr LSB | (DMA registers)
- *
- * Address mapping for channels 5-7:
- *
- * A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0 (Physical addresses)
- * | ... | \ \ ... \ \ \ ... \ \
- * | ... | \ \ ... \ \ \ ... \ (not used)
- * | ... | \ \ ... \ \ \ ... \
- * P7 ... P1 (0) A7 A6 ... A0 A7 A6 ... A0
- * | Page | Addr MSB | Addr LSB | (DMA registers)
- *
- * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses
- * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at
- * the hardware level, so odd-byte transfers aren't possible).
- *
- * Transfer count (_not # bytes_) is limited to 64K, represented as actual
- * count - 1 : 64K => 0xFFFF, 1 => 0x0000. Thus, count is always 1 or more,
- * and up to 128K bytes may be transferred on channels 5-7 in one operation.
- *
- */
-
-/* 8237 DMA controllers */
-#define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */
-#define IO_DMA2_BASE 0xC0 /* 16 bit master DMA, ch 4(=slave input)..7 */
-
-/* DMA controller registers */
-#define DMA1_CMD_REG 0x08 /* command register (w) */
-#define DMA1_STAT_REG 0x08 /* status register (r) */
-#define DMA1_REQ_REG 0x09 /* request register (w) */
-#define DMA1_MASK_REG 0x0A /* single-channel mask (w) */
-#define DMA1_MODE_REG 0x0B /* mode register (w) */
-#define DMA1_CLEAR_FF_REG 0x0C /* clear pointer flip-flop (w) */
-#define DMA1_TEMP_REG 0x0D /* Temporary Register (r) */
-#define DMA1_RESET_REG 0x0D /* Master Clear (w) */
-#define DMA1_CLR_MASK_REG 0x0E /* Clear Mask */
-#define DMA1_MASK_ALL_REG 0x0F /* all-channels mask (w) */
-
-#define DMA2_CMD_REG 0xD0 /* command register (w) */
-#define DMA2_STAT_REG 0xD0 /* status register (r) */
-#define DMA2_REQ_REG 0xD2 /* request register (w) */
-#define DMA2_MASK_REG 0xD4 /* single-channel mask (w) */
-#define DMA2_MODE_REG 0xD6 /* mode register (w) */
-#define DMA2_CLEAR_FF_REG 0xD8 /* clear pointer flip-flop (w) */
-#define DMA2_TEMP_REG 0xDA /* Temporary Register (r) */
-#define DMA2_RESET_REG 0xDA /* Master Clear (w) */
-#define DMA2_CLR_MASK_REG 0xDC /* Clear Mask */
-#define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */
-
-#define DMA_ADDR_0 0x00 /* DMA address registers */
-#define DMA_ADDR_1 0x02
-#define DMA_ADDR_2 0x04
-#define DMA_ADDR_3 0x06
-#define DMA_ADDR_4 0xC0
-#define DMA_ADDR_5 0xC4
-#define DMA_ADDR_6 0xC8
-#define DMA_ADDR_7 0xCC
-
-#define DMA_CNT_0 0x01 /* DMA count registers */
-#define DMA_CNT_1 0x03
-#define DMA_CNT_2 0x05
-#define DMA_CNT_3 0x07
-#define DMA_CNT_4 0xC2
-#define DMA_CNT_5 0xC6
-#define DMA_CNT_6 0xCA
-#define DMA_CNT_7 0xCE
-
-#define DMA_LO_PAGE_0 0x87 /* DMA page registers */
-#define DMA_LO_PAGE_1 0x83
-#define DMA_LO_PAGE_2 0x81
-#define DMA_LO_PAGE_3 0x82
-#define DMA_LO_PAGE_5 0x8B
-#define DMA_LO_PAGE_6 0x89
-#define DMA_LO_PAGE_7 0x8A
-
-#define DMA_HI_PAGE_0 0x487 /* DMA page registers */
-#define DMA_HI_PAGE_1 0x483
-#define DMA_HI_PAGE_2 0x481
-#define DMA_HI_PAGE_3 0x482
-#define DMA_HI_PAGE_5 0x48B
-#define DMA_HI_PAGE_6 0x489
-#define DMA_HI_PAGE_7 0x48A
-
-#define DMA1_EXT_REG 0x40B
-#define DMA2_EXT_REG 0x4D6
-
-#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */
-#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */
-#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */
-
-#define DMA_AUTOINIT 0x10
-
-extern spinlock_t dma_spin_lock;
-
-static __inline__ unsigned long claim_dma_lock(void)
-{
- unsigned long flags;
- spin_lock_irqsave(&dma_spin_lock, flags);
- return flags;
-}
-
-static __inline__ void release_dma_lock(unsigned long flags)
-{
- spin_unlock_irqrestore(&dma_spin_lock, flags);
-}
-
-/* enable/disable a specific DMA channel */
-static __inline__ void enable_dma(unsigned int dmanr)
-{
- unsigned char ucDmaCmd=0x00;
-
- if (dmanr != 4)
- {
- dma_outb(0, DMA2_MASK_REG); /* This may not be enabled */
- dma_outb(ucDmaCmd, DMA2_CMD_REG); /* Enable group */
- }
- if (dmanr<=3)
- {
- dma_outb(dmanr, DMA1_MASK_REG);
- dma_outb(ucDmaCmd, DMA1_CMD_REG); /* Enable group */
- } else
- {
- dma_outb(dmanr & 3, DMA2_MASK_REG);
- }
-}
-
-static __inline__ void disable_dma(unsigned int dmanr)
-{
- if (dmanr<=3)
- dma_outb(dmanr | 4, DMA1_MASK_REG);
- else
- dma_outb((dmanr & 3) | 4, DMA2_MASK_REG);
-}
-
-/* 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! ---
- */
-static __inline__ void clear_dma_ff(unsigned int dmanr)
-{
- if (dmanr<=3)
- dma_outb(0, DMA1_CLEAR_FF_REG);
- else
- dma_outb(0, DMA2_CLEAR_FF_REG);
-}
-
-/* set mode (above) for a specific DMA channel */
-static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
-{
- if (dmanr<=3)
- dma_outb(mode | dmanr, DMA1_MODE_REG);
- else
- dma_outb(mode | (dmanr&3), DMA2_MODE_REG);
-}
-
-/* Set only the page register bits of the transfer address.
- * This is used for successive transfers when we know the contents of
- * the lower 16 bits of the DMA current address register, but a 64k boundary
- * may have been crossed.
- */
-static __inline__ void set_dma_page(unsigned int dmanr, int pagenr)
-{
- switch(dmanr) {
- case 0:
- dma_outb(pagenr, DMA_LO_PAGE_0);
- dma_outb(pagenr>>8, DMA_HI_PAGE_0);
- break;
- case 1:
- dma_outb(pagenr, DMA_LO_PAGE_1);
- dma_outb(pagenr>>8, DMA_HI_PAGE_1);
- break;
- case 2:
- dma_outb(pagenr, DMA_LO_PAGE_2);
- dma_outb(pagenr>>8, DMA_HI_PAGE_2);
- break;
- case 3:
- dma_outb(pagenr, DMA_LO_PAGE_3);
- dma_outb(pagenr>>8, DMA_HI_PAGE_3);
- break;
- case 5:
- dma_outb(pagenr & 0xfe, DMA_LO_PAGE_5);
- dma_outb(pagenr>>8, DMA_HI_PAGE_5);
- break;
- case 6:
- dma_outb(pagenr & 0xfe, DMA_LO_PAGE_6);
- dma_outb(pagenr>>8, DMA_HI_PAGE_6);
- break;
- case 7:
- dma_outb(pagenr & 0xfe, DMA_LO_PAGE_7);
- dma_outb(pagenr>>8, DMA_HI_PAGE_7);
- break;
- }
-}
-
-
-/* Set transfer address & page bits for specific DMA channel.
- * Assumes dma flipflop is clear.
- */
-static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int phys)
-{
- if (dmanr <= 3) {
- dma_outb( phys & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
- dma_outb( (phys>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
- } else {
- dma_outb( (phys>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
- dma_outb( (phys>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
- }
- set_dma_page(dmanr, phys>>16);
-}
-
-
-/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for
- * a specific DMA channel.
- * You must ensure the parameters are valid.
- * NOTE: from a manual: "the number of transfers is one more
- * than the initial word count"! This is taken into account.
- * Assumes dma flip-flop is clear.
- * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7.
- */
-static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
-{
- count--;
- if (dmanr <= 3) {
- dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
- dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
- } else {
- dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
- dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
- }
-}
-
-
-/* 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.
- * If called before the channel has been used, it may return 1.
- * Otherwise, it returns the number of _bytes_ left to transfer.
- *
- * Assumes DMA flip-flop is clear.
- */
-static __inline__ int get_dma_residue(unsigned int dmanr)
-{
- unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE
- : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE;
-
- /* using short to get 16-bit wrap around */
- unsigned short count;
-
- count = 1 + dma_inb(io_port);
- count += dma_inb(io_port) << 8;
-
- return (dmanr <= 3)? count : (count<<1);
-}
-
-/* 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 */
-
-#ifdef CONFIG_PCI
-extern int isa_dma_bridge_buggy;
-#else
-#define isa_dma_bridge_buggy (0)
-#endif
-#endif /* !defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI) */
-#endif /* _ASM_DMA_H */
diff --git a/include/asm-ppc64/futex.h b/include/asm-ppc64/futex.h
index cb2640b3a408..266b460de44e 100644
--- a/include/asm-ppc64/futex.h
+++ b/include/asm-ppc64/futex.h
@@ -5,7 +5,7 @@
#include <linux/futex.h>
#include <asm/errno.h>
-#include <asm/memory.h>
+#include <asm/synch.h>
#include <asm/uaccess.h>
#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
diff --git a/include/asm-ppc64/hardirq.h b/include/asm-ppc64/hardirq.h
deleted file mode 100644
index 4ee72bb1fd48..000000000000
--- a/include/asm-ppc64/hardirq.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef __ASM_HARDIRQ_H
-#define __ASM_HARDIRQ_H
-
-/*
- * This program is free software; you can redistribute 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/config.h>
-#include <linux/cache.h>
-#include <linux/preempt.h>
-
-typedef struct {
- unsigned int __softirq_pending;
-} ____cacheline_aligned irq_cpustat_t;
-
-#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
-
-static inline void ack_bad_irq(int irq)
-{
- printk(KERN_CRIT "illegal vector %d received!\n", irq);
- BUG();
-}
-
-#endif /* __ASM_HARDIRQ_H */
diff --git a/include/asm-ppc64/io.h b/include/asm-ppc64/io.h
index 59c958aea4db..bd7c9532d77b 100644
--- a/include/asm-ppc64/io.h
+++ b/include/asm-ppc64/io.h
@@ -15,7 +15,7 @@
#ifdef CONFIG_PPC_ISERIES
#include <asm/iSeries/iSeries_io.h>
#endif
-#include <asm/memory.h>
+#include <asm/synch.h>
#include <asm/delay.h>
#include <asm-generic/iomap.h>
diff --git a/include/asm-ppc64/irq.h b/include/asm-ppc64/irq.h
deleted file mode 100644
index 99782afb4cde..000000000000
--- a/include/asm-ppc64/irq.h
+++ /dev/null
@@ -1,120 +0,0 @@
-#ifdef __KERNEL__
-#ifndef _ASM_IRQ_H
-#define _ASM_IRQ_H
-
-/*
- * This program is free software; you can redistribute 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/config.h>
-#include <linux/threads.h>
-
-/*
- * Maximum number of interrupt sources that we can handle.
- */
-#define NR_IRQS 512
-
-/* this number is used when no interrupt has been assigned */
-#define NO_IRQ (-1)
-
-/*
- * These constants are used for passing information about interrupt
- * signal polarity and level/edge sensing to the low-level PIC chip
- * drivers.
- */
-#define IRQ_SENSE_MASK 0x1
-#define IRQ_SENSE_LEVEL 0x1 /* interrupt on active level */
-#define IRQ_SENSE_EDGE 0x0 /* interrupt triggered by edge */
-
-#define IRQ_POLARITY_MASK 0x2
-#define IRQ_POLARITY_POSITIVE 0x2 /* high level or low->high edge */
-#define IRQ_POLARITY_NEGATIVE 0x0 /* low level or high->low edge */
-
-/*
- * IRQ line status macro IRQ_PER_CPU is used
- */
-#define ARCH_HAS_IRQ_PER_CPU
-
-#define get_irq_desc(irq) (&irq_desc[(irq)])
-
-/* Define a way to iterate across irqs. */
-#define for_each_irq(i) \
- for ((i) = 0; (i) < NR_IRQS; ++(i))
-
-/* Interrupt numbers are virtual in case they are sparsely
- * distributed by the hardware.
- */
-extern unsigned int virt_irq_to_real_map[NR_IRQS];
-
-/* Create a mapping for a real_irq if it doesn't already exist.
- * Return the virtual irq as a convenience.
- */
-int virt_irq_create_mapping(unsigned int real_irq);
-void virt_irq_init(void);
-
-static inline unsigned int virt_irq_to_real(unsigned int virt_irq)
-{
- return virt_irq_to_real_map[virt_irq];
-}
-
-extern unsigned int real_irq_to_virt_slowpath(unsigned int real_irq);
-
-/*
- * Because many systems have two overlapping names spaces for
- * interrupts (ISA and XICS for example), and the ISA interrupts
- * have historically not been easy to renumber, we allow ISA
- * interrupts to take values 0 - 15, and shift up the remaining
- * interrupts by 0x10.
- */
-#define NUM_ISA_INTERRUPTS 0x10
-extern int __irq_offset_value;
-
-static inline int irq_offset_up(int irq)
-{
- return(irq + __irq_offset_value);
-}
-
-static inline int irq_offset_down(int irq)
-{
- return(irq - __irq_offset_value);
-}
-
-static inline int irq_offset_value(void)
-{
- return __irq_offset_value;
-}
-
-static __inline__ int irq_canonicalize(int irq)
-{
- return irq;
-}
-
-extern int distribute_irqs;
-
-struct irqaction;
-struct pt_regs;
-
-#ifdef CONFIG_IRQSTACKS
-/*
- * Per-cpu stacks for handling hard and soft interrupts.
- */
-extern struct thread_info *hardirq_ctx[NR_CPUS];
-extern struct thread_info *softirq_ctx[NR_CPUS];
-
-extern void irq_ctx_init(void);
-extern void call_do_softirq(struct thread_info *tp);
-extern int call_handle_IRQ_event(int irq, struct pt_regs *regs,
- struct irqaction *action, struct thread_info *tp);
-
-#define __ARCH_HAS_DO_SOFTIRQ
-
-#else
-#define irq_ctx_init()
-
-#endif /* CONFIG_IRQSTACKS */
-
-#endif /* _ASM_IRQ_H */
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc64/keylargo.h b/include/asm-ppc64/keylargo.h
deleted file mode 100644
index 4d78e3d0314c..000000000000
--- a/include/asm-ppc64/keylargo.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include <asm-ppc/keylargo.h>
-
diff --git a/include/asm-ppc64/kmap_types.h b/include/asm-ppc64/kmap_types.h
deleted file mode 100644
index fd1574648223..000000000000
--- a/include/asm-ppc64/kmap_types.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifdef __KERNEL__
-#ifndef _ASM_KMAP_TYPES_H
-#define _ASM_KMAP_TYPES_H
-
-enum km_type {
- KM_BOUNCE_READ,
- KM_SKB_SUNRPC_DATA,
- KM_SKB_DATA_SOFTIRQ,
- KM_USER0,
- KM_USER1,
- KM_BIO_SRC_IRQ,
- KM_BIO_DST_IRQ,
- KM_PTE0,
- KM_PTE1,
- KM_IRQ0,
- KM_IRQ1,
- KM_SOFTIRQ0,
- KM_SOFTIRQ1,
- KM_TYPE_NR
-};
-
-#endif
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc64/macio.h b/include/asm-ppc64/macio.h
deleted file mode 100644
index a3028b364f70..000000000000
--- a/include/asm-ppc64/macio.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include <asm-ppc/macio.h>
-
diff --git a/include/asm-ppc64/memory.h b/include/asm-ppc64/memory.h
deleted file mode 100644
index af53ffb55726..000000000000
--- a/include/asm-ppc64/memory.h
+++ /dev/null
@@ -1,61 +0,0 @@
-#ifndef _ASM_PPC64_MEMORY_H_
-#define _ASM_PPC64_MEMORY_H_
-
-/*
- * This program is free software; you can redistribute 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/config.h>
-
-/*
- * Arguably the bitops and *xchg operations don't imply any memory barrier
- * or SMP ordering, but in fact a lot of drivers expect them to imply
- * both, since they do on x86 cpus.
- */
-#ifdef CONFIG_SMP
-#define EIEIO_ON_SMP "eieio\n"
-#define ISYNC_ON_SMP "\n\tisync"
-#define SYNC_ON_SMP "lwsync\n\t"
-#else
-#define EIEIO_ON_SMP
-#define ISYNC_ON_SMP
-#define SYNC_ON_SMP
-#endif
-
-static inline void eieio(void)
-{
- __asm__ __volatile__ ("eieio" : : : "memory");
-}
-
-static inline void isync(void)
-{
- __asm__ __volatile__ ("isync" : : : "memory");
-}
-
-#ifdef CONFIG_SMP
-#define eieio_on_smp() eieio()
-#define isync_on_smp() isync()
-#else
-#define eieio_on_smp() __asm__ __volatile__("": : :"memory")
-#define isync_on_smp() __asm__ __volatile__("": : :"memory")
-#endif
-
-/* Macros for adjusting thread priority (hardware multi-threading) */
-#define HMT_very_low() asm volatile("or 31,31,31 # very low priority")
-#define HMT_low() asm volatile("or 1,1,1 # low priority")
-#define HMT_medium_low() asm volatile("or 6,6,6 # medium low priority")
-#define HMT_medium() asm volatile("or 2,2,2 # medium priority")
-#define HMT_medium_high() asm volatile("or 5,5,5 # medium high priority")
-#define HMT_high() asm volatile("or 3,3,3 # high priority")
-
-#define HMT_VERY_LOW "\tor 31,31,31 # very low priority\n"
-#define HMT_LOW "\tor 1,1,1 # low priority\n"
-#define HMT_MEDIUM_LOW "\tor 6,6,6 # medium low priority\n"
-#define HMT_MEDIUM "\tor 2,2,2 # medium priority\n"
-#define HMT_MEDIUM_HIGH "\tor 5,5,5 # medium high priority\n"
-#define HMT_HIGH "\tor 3,3,3 # high priority\n"
-
-#endif
diff --git a/include/asm-ppc64/mmu.h b/include/asm-ppc64/mmu.h
index 7bc42eb087ad..e0505acb77d9 100644
--- a/include/asm-ppc64/mmu.h
+++ b/include/asm-ppc64/mmu.h
@@ -14,6 +14,7 @@
#define _PPC64_MMU_H_
#include <linux/config.h>
+#include <asm/ppc_asm.h> /* for ASM_CONST */
#include <asm/page.h>
/*
@@ -29,7 +30,7 @@
/* Location of cpu0's segment table */
#define STAB0_PAGE 0x6
-#define STAB0_PHYS_ADDR (STAB0_PAGE<<PAGE_SHIFT)
+#define STAB0_PHYS_ADDR (STAB0_PAGE<<12)
#ifndef __ASSEMBLY__
extern char initial_stab[];
@@ -205,6 +206,10 @@ extern long native_hpte_insert(unsigned long hpte_group, unsigned long va,
unsigned long prpn,
unsigned long vflags, unsigned long rflags);
+extern long iSeries_hpte_bolt_or_insert(unsigned long hpte_group,
+ unsigned long va, unsigned long prpn,
+ unsigned long vflags, unsigned long rflags);
+
extern void stabs_alloc(void);
#endif /* __ASSEMBLY__ */
diff --git a/include/asm-ppc64/mmzone.h b/include/asm-ppc64/mmzone.h
index ed473f4b0152..80a708e7093a 100644
--- a/include/asm-ppc64/mmzone.h
+++ b/include/asm-ppc64/mmzone.h
@@ -67,9 +67,6 @@ static inline int pa_to_nid(unsigned long pa)
#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn)
#define node_end_pfn(nid) (NODE_DATA(nid)->node_end_pfn)
-#define local_mapnr(kvaddr) \
- ( (__pa(kvaddr) >> PAGE_SHIFT) - node_start_pfn(kvaddr_to_nid(kvaddr))
-
#ifdef CONFIG_DISCONTIGMEM
/*
diff --git a/include/asm-ppc64/of_device.h b/include/asm-ppc64/of_device.h
deleted file mode 100644
index 7bc136e22590..000000000000
--- a/include/asm-ppc64/of_device.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include <asm-ppc/of_device.h>
-
diff --git a/include/asm-ppc64/page.h b/include/asm-ppc64/page.h
index a15422bcf30d..d404431f0a9a 100644
--- a/include/asm-ppc64/page.h
+++ b/include/asm-ppc64/page.h
@@ -11,13 +11,7 @@
*/
#include <linux/config.h>
-
-#ifdef __ASSEMBLY__
- #define ASM_CONST(x) x
-#else
- #define __ASM_CONST(x) x##UL
- #define ASM_CONST(x) __ASM_CONST(x)
-#endif
+#include <asm/ppc_asm.h> /* for ASM_CONST */
/* PAGE_SHIFT determines the page size */
#define PAGE_SHIFT 12
diff --git a/include/asm-ppc64/parport.h b/include/asm-ppc64/parport.h
deleted file mode 100644
index 2f8874c581cc..000000000000
--- a/include/asm-ppc64/parport.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * parport.h: platform-specific PC-style parport initialisation
- *
- * Copyright (C) 1999, 2000 Tim Waugh <tim@cyberelk.demon.co.uk>
- *
- * This file should only be included by drivers/parport/parport_pc.c.
- */
-
-#ifndef _ASM_PPC64_PARPORT_H
-#define _ASM_PPC64_PARPORT_H
-
-static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma);
-static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma)
-{
- return parport_pc_find_isa_ports (autoirq, autodma);
-}
-
-#endif /* !(_ASM_PPC_PARPORT_H) */
diff --git a/include/asm-ppc64/pci-bridge.h b/include/asm-ppc64/pci-bridge.h
index d8991389ab39..60cf8c838af0 100644
--- a/include/asm-ppc64/pci-bridge.h
+++ b/include/asm-ppc64/pci-bridge.h
@@ -2,7 +2,9 @@
#ifndef _ASM_PCI_BRIDGE_H
#define _ASM_PCI_BRIDGE_H
+#include <linux/config.h>
#include <linux/pci.h>
+#include <linux/list.h>
/*
* This program is free software; you can redistribute it and/or
@@ -34,7 +36,7 @@ struct pci_controller {
struct pci_ops *ops;
volatile unsigned int __iomem *cfg_addr;
- volatile unsigned char __iomem *cfg_data;
+ volatile void __iomem *cfg_data;
/* Currently, we limit ourselves to 1 IO range and 3 mem
* ranges since the common pci_bus structure can't handle more
@@ -71,6 +73,12 @@ struct pci_dn {
struct iommu_table *iommu_table; /* for phb's or bridges */
struct pci_dev *pcidev; /* back-pointer to the pci device */
struct device_node *node; /* back-pointer to the device_node */
+#ifdef CONFIG_PPC_ISERIES
+ struct list_head Device_List;
+ int Irq; /* Assigned IRQ */
+ int Flags; /* Possible flags(disable/bist)*/
+ u8 LogicalSlot; /* Hv Slot Index for Tces */
+#endif
u32 config_space[16]; /* saved PCI config space */
};
@@ -96,6 +104,16 @@ static inline struct device_node *pci_device_to_OF_node(struct pci_dev *dev)
return fetch_dev_dn(dev);
}
+static inline int pci_device_from_OF_node(struct device_node *np,
+ u8 *bus, u8 *devfn)
+{
+ if (!PCI_DN(np))
+ return -ENODEV;
+ *bus = PCI_DN(np)->busno;
+ *devfn = PCI_DN(np)->devfn;
+ return 0;
+}
+
static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
{
if (bus->self)
@@ -105,7 +123,7 @@ static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
}
extern void pci_process_bridge_OF_ranges(struct pci_controller *hose,
- struct device_node *dev);
+ struct device_node *dev, int primary);
extern int pcibios_remove_root_bus(struct pci_controller *phb);
diff --git a/include/asm-ppc64/pci.h b/include/asm-ppc64/pci.h
index a88bbfc26967..342e2d755550 100644
--- a/include/asm-ppc64/pci.h
+++ b/include/asm-ppc64/pci.h
@@ -168,7 +168,7 @@ extern void pcibios_add_platform_entries(struct pci_dev *dev);
struct file;
extern pgprot_t pci_phys_mem_access_prot(struct file *file,
- unsigned long offset,
+ unsigned long pfn,
unsigned long size,
pgprot_t prot);
diff --git a/include/asm-ppc64/pgtable.h b/include/asm-ppc64/pgtable.h
index c83679c9d2b0..8c3f574046b6 100644
--- a/include/asm-ppc64/pgtable.h
+++ b/include/asm-ppc64/pgtable.h
@@ -471,17 +471,19 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry, int dirty)
#define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | _PAGE_NO_CACHE | _PAGE_GUARDED))
struct file;
-extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long addr,
+extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
unsigned long size, pgprot_t vma_prot);
#define __HAVE_PHYS_MEM_ACCESS_PROT
#define __HAVE_ARCH_PTE_SAME
#define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0)
+#define pte_ERROR(e) \
+ printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
#define pmd_ERROR(e) \
printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
#define pud_ERROR(e) \
- printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pud_val(e))
+ printk("%s:%d: bad pud %08lx.\n", __FILE__, __LINE__, pud_val(e))
#define pgd_ERROR(e) \
printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
diff --git a/include/asm-ppc64/pmac_feature.h b/include/asm-ppc64/pmac_feature.h
deleted file mode 100644
index e07e36c4cbb2..000000000000
--- a/include/asm-ppc64/pmac_feature.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include <asm-ppc/pmac_feature.h>
-
diff --git a/include/asm-ppc64/pmac_low_i2c.h b/include/asm-ppc64/pmac_low_i2c.h
deleted file mode 100644
index 7bcfc72c5c8a..000000000000
--- a/include/asm-ppc64/pmac_low_i2c.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include <asm-ppc/pmac_low_i2c.h>
-
diff --git a/include/asm-ppc64/ppc32.h b/include/asm-ppc64/ppc32.h
index 6b44a8caf395..3945a55d112a 100644
--- a/include/asm-ppc64/ppc32.h
+++ b/include/asm-ppc64/ppc32.h
@@ -70,18 +70,18 @@ typedef struct compat_siginfo {
#define __old_sigaction32 old_sigaction32
struct __old_sigaction32 {
- unsigned sa_handler;
+ compat_uptr_t sa_handler;
compat_old_sigset_t sa_mask;
unsigned int sa_flags;
- unsigned sa_restorer; /* not used by Linux/SPARC yet */
+ compat_uptr_t sa_restorer; /* not used by Linux/SPARC yet */
};
struct sigaction32 {
- unsigned int sa_handler; /* Really a pointer, but need to deal with 32 bits */
+ compat_uptr_t sa_handler; /* Really a pointer, but need to deal with 32 bits */
unsigned int sa_flags;
- unsigned int sa_restorer; /* Another 32 bit pointer */
+ compat_uptr_t sa_restorer; /* Another 32 bit pointer */
compat_sigset_t sa_mask; /* A 32 bit mask */
};
@@ -94,9 +94,9 @@ typedef struct sigaltstack_32 {
struct sigcontext32 {
unsigned int _unused[4];
int signal;
- unsigned int handler;
+ compat_uptr_t handler;
unsigned int oldmask;
- u32 regs; /* 4 byte pointer to the pt_regs32 structure. */
+ compat_uptr_t regs; /* 4 byte pointer to the pt_regs32 structure. */
};
struct mcontext32 {
@@ -111,7 +111,7 @@ struct ucontext32 {
unsigned int uc_link;
stack_32_t uc_stack;
int uc_pad[7];
- u32 uc_regs; /* points to uc_mcontext field */
+ compat_uptr_t uc_regs; /* points to uc_mcontext field */
compat_sigset_t uc_sigmask; /* mask last for extensibility */
/* glibc has 1024-bit signal masks, ours are 64-bit */
int uc_maskext[30];
diff --git a/include/asm-ppc64/ppc_asm.h b/include/asm-ppc64/ppc_asm.h
deleted file mode 100644
index 9031d8a29aca..000000000000
--- a/include/asm-ppc64/ppc_asm.h
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * arch/ppc64/kernel/ppc_asm.h
- *
- * Definitions used by various bits of low-level assembly code on PowerPC.
- *
- * Copyright (C) 1995-1999 Gary Thomas, Paul Mackerras, Cort Dougan.
- *
- * This program is free software; you can redistribute 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 _PPC64_PPC_ASM_H
-#define _PPC64_PPC_ASM_H
-/*
- * Macros for storing registers into and loading registers from
- * exception frames.
- */
-#define SAVE_GPR(n, base) std n,GPR0+8*(n)(base)
-#define SAVE_2GPRS(n, base) SAVE_GPR(n, base); SAVE_GPR(n+1, base)
-#define SAVE_4GPRS(n, base) SAVE_2GPRS(n, base); SAVE_2GPRS(n+2, base)
-#define SAVE_8GPRS(n, base) SAVE_4GPRS(n, base); SAVE_4GPRS(n+4, base)
-#define SAVE_10GPRS(n, base) SAVE_8GPRS(n, base); SAVE_2GPRS(n+8, base)
-#define REST_GPR(n, base) ld n,GPR0+8*(n)(base)
-#define REST_2GPRS(n, base) REST_GPR(n, base); REST_GPR(n+1, base)
-#define REST_4GPRS(n, base) REST_2GPRS(n, base); REST_2GPRS(n+2, base)
-#define REST_8GPRS(n, base) REST_4GPRS(n, base); REST_4GPRS(n+4, base)
-#define REST_10GPRS(n, base) REST_8GPRS(n, base); REST_2GPRS(n+8, base)
-
-#define SAVE_NVGPRS(base) SAVE_8GPRS(14, base); SAVE_10GPRS(22, base)
-#define REST_NVGPRS(base) REST_8GPRS(14, base); REST_10GPRS(22, base)
-
-#define SAVE_FPR(n, base) stfd n,THREAD_FPR0+8*(n)(base)
-#define SAVE_2FPRS(n, base) SAVE_FPR(n, base); SAVE_FPR(n+1, base)
-#define SAVE_4FPRS(n, base) SAVE_2FPRS(n, base); SAVE_2FPRS(n+2, base)
-#define SAVE_8FPRS(n, base) SAVE_4FPRS(n, base); SAVE_4FPRS(n+4, base)
-#define SAVE_16FPRS(n, base) SAVE_8FPRS(n, base); SAVE_8FPRS(n+8, base)
-#define SAVE_32FPRS(n, base) SAVE_16FPRS(n, base); SAVE_16FPRS(n+16, base)
-#define REST_FPR(n, base) lfd n,THREAD_FPR0+8*(n)(base)
-#define REST_2FPRS(n, base) REST_FPR(n, base); REST_FPR(n+1, base)
-#define REST_4FPRS(n, base) REST_2FPRS(n, base); REST_2FPRS(n+2, base)
-#define REST_8FPRS(n, base) REST_4FPRS(n, base); REST_4FPRS(n+4, base)
-#define REST_16FPRS(n, base) REST_8FPRS(n, base); REST_8FPRS(n+8, base)
-#define REST_32FPRS(n, base) REST_16FPRS(n, base); REST_16FPRS(n+16, base)
-
-#define SAVE_VR(n,b,base) li b,THREAD_VR0+(16*(n)); stvx n,b,base
-#define SAVE_2VRS(n,b,base) SAVE_VR(n,b,base); SAVE_VR(n+1,b,base)
-#define SAVE_4VRS(n,b,base) SAVE_2VRS(n,b,base); SAVE_2VRS(n+2,b,base)
-#define SAVE_8VRS(n,b,base) SAVE_4VRS(n,b,base); SAVE_4VRS(n+4,b,base)
-#define SAVE_16VRS(n,b,base) SAVE_8VRS(n,b,base); SAVE_8VRS(n+8,b,base)
-#define SAVE_32VRS(n,b,base) SAVE_16VRS(n,b,base); SAVE_16VRS(n+16,b,base)
-#define REST_VR(n,b,base) li b,THREAD_VR0+(16*(n)); lvx n,b,base
-#define REST_2VRS(n,b,base) REST_VR(n,b,base); REST_VR(n+1,b,base)
-#define REST_4VRS(n,b,base) REST_2VRS(n,b,base); REST_2VRS(n+2,b,base)
-#define REST_8VRS(n,b,base) REST_4VRS(n,b,base); REST_4VRS(n+4,b,base)
-#define REST_16VRS(n,b,base) REST_8VRS(n,b,base); REST_8VRS(n+8,b,base)
-#define REST_32VRS(n,b,base) REST_16VRS(n,b,base); REST_16VRS(n+16,b,base)
-
-/* Macros to adjust thread priority for Iseries hardware multithreading */
-#define HMT_LOW or 1,1,1
-#define HMT_MEDIUM or 2,2,2
-#define HMT_HIGH or 3,3,3
-
-/* Insert the high 32 bits of the MSR into what will be the new
- MSR (via SRR1 and rfid) This preserves the MSR.SF and MSR.ISF
- bits. */
-
-#define FIX_SRR1(ra, rb) \
- mr rb,ra; \
- mfmsr ra; \
- rldimi ra,rb,0,32
-
-#define CLR_TOP32(r) rlwinm (r),(r),0,0,31 /* clear top 32 bits */
-
-/*
- * LOADADDR( rn, name )
- * loads the address of 'name' into 'rn'
- *
- * LOADBASE( rn, name )
- * loads the address (less the low 16 bits) of 'name' into 'rn'
- * suitable for base+disp addressing
- */
-#define LOADADDR(rn,name) \
- lis rn,name##@highest; \
- ori rn,rn,name##@higher; \
- rldicr rn,rn,32,31; \
- oris rn,rn,name##@h; \
- ori rn,rn,name##@l
-
-#define LOADBASE(rn,name) \
- lis rn,name@highest; \
- ori rn,rn,name@higher; \
- rldicr rn,rn,32,31; \
- oris rn,rn,name@ha
-
-
-#define SET_REG_TO_CONST(reg, value) \
- lis reg,(((value)>>48)&0xFFFF); \
- ori reg,reg,(((value)>>32)&0xFFFF); \
- rldicr reg,reg,32,31; \
- oris reg,reg,(((value)>>16)&0xFFFF); \
- ori reg,reg,((value)&0xFFFF);
-
-#define SET_REG_TO_LABEL(reg, label) \
- lis reg,(label)@highest; \
- ori reg,reg,(label)@higher; \
- rldicr reg,reg,32,31; \
- oris reg,reg,(label)@h; \
- ori reg,reg,(label)@l;
-
-
-/* PPPBBB - DRENG If KERNELBASE is always 0xC0...,
- * Then we can easily do this with one asm insn. -Peter
- */
-#define tophys(rd,rs) \
- lis rd,((KERNELBASE>>48)&0xFFFF); \
- rldicr rd,rd,32,31; \
- sub rd,rs,rd
-
-#define tovirt(rd,rs) \
- lis rd,((KERNELBASE>>48)&0xFFFF); \
- rldicr rd,rd,32,31; \
- add rd,rs,rd
-
-/* Condition Register Bit Fields */
-
-#define cr0 0
-#define cr1 1
-#define cr2 2
-#define cr3 3
-#define cr4 4
-#define cr5 5
-#define cr6 6
-#define cr7 7
-
-
-/* General Purpose Registers (GPRs) */
-
-#define r0 0
-#define r1 1
-#define r2 2
-#define r3 3
-#define r4 4
-#define r5 5
-#define r6 6
-#define r7 7
-#define r8 8
-#define r9 9
-#define r10 10
-#define r11 11
-#define r12 12
-#define r13 13
-#define r14 14
-#define r15 15
-#define r16 16
-#define r17 17
-#define r18 18
-#define r19 19
-#define r20 20
-#define r21 21
-#define r22 22
-#define r23 23
-#define r24 24
-#define r25 25
-#define r26 26
-#define r27 27
-#define r28 28
-#define r29 29
-#define r30 30
-#define r31 31
-
-
-/* Floating Point Registers (FPRs) */
-
-#define fr0 0
-#define fr1 1
-#define fr2 2
-#define fr3 3
-#define fr4 4
-#define fr5 5
-#define fr6 6
-#define fr7 7
-#define fr8 8
-#define fr9 9
-#define fr10 10
-#define fr11 11
-#define fr12 12
-#define fr13 13
-#define fr14 14
-#define fr15 15
-#define fr16 16
-#define fr17 17
-#define fr18 18
-#define fr19 19
-#define fr20 20
-#define fr21 21
-#define fr22 22
-#define fr23 23
-#define fr24 24
-#define fr25 25
-#define fr26 26
-#define fr27 27
-#define fr28 28
-#define fr29 29
-#define fr30 30
-#define fr31 31
-
-#define vr0 0
-#define vr1 1
-#define vr2 2
-#define vr3 3
-#define vr4 4
-#define vr5 5
-#define vr6 6
-#define vr7 7
-#define vr8 8
-#define vr9 9
-#define vr10 10
-#define vr11 11
-#define vr12 12
-#define vr13 13
-#define vr14 14
-#define vr15 15
-#define vr16 16
-#define vr17 17
-#define vr18 18
-#define vr19 19
-#define vr20 20
-#define vr21 21
-#define vr22 22
-#define vr23 23
-#define vr24 24
-#define vr25 25
-#define vr26 26
-#define vr27 27
-#define vr28 28
-#define vr29 29
-#define vr30 30
-#define vr31 31
-
-#endif /* _PPC64_PPC_ASM_H */
diff --git a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h
deleted file mode 100644
index 4146189006e3..000000000000
--- a/include/asm-ppc64/processor.h
+++ /dev/null
@@ -1,558 +0,0 @@
-#ifndef __ASM_PPC64_PROCESSOR_H
-#define __ASM_PPC64_PROCESSOR_H
-
-/*
- * Copyright (C) 2001 PPC 64 Team, IBM Corp
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/stringify.h>
-#ifndef __ASSEMBLY__
-#include <linux/config.h>
-#include <asm/atomic.h>
-#include <asm/ppcdebug.h>
-#include <asm/a.out.h>
-#endif
-#include <asm/ptrace.h>
-#include <asm/types.h>
-#include <asm/systemcfg.h>
-#include <asm/cputable.h>
-
-/* Machine State Register (MSR) Fields */
-#define MSR_SF_LG 63 /* Enable 64 bit mode */
-#define MSR_ISF_LG 61 /* Interrupt 64b mode valid on 630 */
-#define MSR_HV_LG 60 /* Hypervisor state */
-#define MSR_VEC_LG 25 /* Enable AltiVec */
-#define MSR_POW_LG 18 /* Enable Power Management */
-#define MSR_WE_LG 18 /* Wait State Enable */
-#define MSR_TGPR_LG 17 /* TLB Update registers in use */
-#define MSR_CE_LG 17 /* Critical Interrupt Enable */
-#define MSR_ILE_LG 16 /* Interrupt Little Endian */
-#define MSR_EE_LG 15 /* External Interrupt Enable */
-#define MSR_PR_LG 14 /* Problem State / Privilege Level */
-#define MSR_FP_LG 13 /* Floating Point enable */
-#define MSR_ME_LG 12 /* Machine Check Enable */
-#define MSR_FE0_LG 11 /* Floating Exception mode 0 */
-#define MSR_SE_LG 10 /* Single Step */
-#define MSR_BE_LG 9 /* Branch Trace */
-#define MSR_DE_LG 9 /* Debug Exception Enable */
-#define MSR_FE1_LG 8 /* Floating Exception mode 1 */
-#define MSR_IP_LG 6 /* Exception prefix 0x000/0xFFF */
-#define MSR_IR_LG 5 /* Instruction Relocate */
-#define MSR_DR_LG 4 /* Data Relocate */
-#define MSR_PE_LG 3 /* Protection Enable */
-#define MSR_PX_LG 2 /* Protection Exclusive Mode */
-#define MSR_PMM_LG 2 /* Performance monitor */
-#define MSR_RI_LG 1 /* Recoverable Exception */
-#define MSR_LE_LG 0 /* Little Endian */
-
-#ifdef __ASSEMBLY__
-#define __MASK(X) (1<<(X))
-#else
-#define __MASK(X) (1UL<<(X))
-#endif
-
-#define MSR_SF __MASK(MSR_SF_LG) /* Enable 64 bit mode */
-#define MSR_ISF __MASK(MSR_ISF_LG) /* Interrupt 64b mode valid on 630 */
-#define MSR_HV __MASK(MSR_HV_LG) /* Hypervisor state */
-#define MSR_VEC __MASK(MSR_VEC_LG) /* Enable AltiVec */
-#define MSR_POW __MASK(MSR_POW_LG) /* Enable Power Management */
-#define MSR_WE __MASK(MSR_WE_LG) /* Wait State Enable */
-#define MSR_TGPR __MASK(MSR_TGPR_LG) /* TLB Update registers in use */
-#define MSR_CE __MASK(MSR_CE_LG) /* Critical Interrupt Enable */
-#define MSR_ILE __MASK(MSR_ILE_LG) /* Interrupt Little Endian */
-#define MSR_EE __MASK(MSR_EE_LG) /* External Interrupt Enable */
-#define MSR_PR __MASK(MSR_PR_LG) /* Problem State / Privilege Level */
-#define MSR_FP __MASK(MSR_FP_LG) /* Floating Point enable */
-#define MSR_ME __MASK(MSR_ME_LG) /* Machine Check Enable */
-#define MSR_FE0 __MASK(MSR_FE0_LG) /* Floating Exception mode 0 */
-#define MSR_SE __MASK(MSR_SE_LG) /* Single Step */
-#define MSR_BE __MASK(MSR_BE_LG) /* Branch Trace */
-#define MSR_DE __MASK(MSR_DE_LG) /* Debug Exception Enable */
-#define MSR_FE1 __MASK(MSR_FE1_LG) /* Floating Exception mode 1 */
-#define MSR_IP __MASK(MSR_IP_LG) /* Exception prefix 0x000/0xFFF */
-#define MSR_IR __MASK(MSR_IR_LG) /* Instruction Relocate */
-#define MSR_DR __MASK(MSR_DR_LG) /* Data Relocate */
-#define MSR_PE __MASK(MSR_PE_LG) /* Protection Enable */
-#define MSR_PX __MASK(MSR_PX_LG) /* Protection Exclusive Mode */
-#define MSR_PMM __MASK(MSR_PMM_LG) /* Performance monitor */
-#define MSR_RI __MASK(MSR_RI_LG) /* Recoverable Exception */
-#define MSR_LE __MASK(MSR_LE_LG) /* Little Endian */
-
-#define MSR_ MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_ISF
-#define MSR_KERNEL MSR_ | MSR_SF | MSR_HV
-
-#define MSR_USER32 MSR_ | MSR_PR | MSR_EE
-#define MSR_USER64 MSR_USER32 | MSR_SF
-
-/* Floating Point Status and Control Register (FPSCR) Fields */
-
-#define FPSCR_FX 0x80000000 /* FPU exception summary */
-#define FPSCR_FEX 0x40000000 /* FPU enabled exception summary */
-#define FPSCR_VX 0x20000000 /* Invalid operation summary */
-#define FPSCR_OX 0x10000000 /* Overflow exception summary */
-#define FPSCR_UX 0x08000000 /* Underflow exception summary */
-#define FPSCR_ZX 0x04000000 /* Zero-divide exception summary */
-#define FPSCR_XX 0x02000000 /* Inexact exception summary */
-#define FPSCR_VXSNAN 0x01000000 /* Invalid op for SNaN */
-#define FPSCR_VXISI 0x00800000 /* Invalid op for Inv - Inv */
-#define FPSCR_VXIDI 0x00400000 /* Invalid op for Inv / Inv */
-#define FPSCR_VXZDZ 0x00200000 /* Invalid op for Zero / Zero */
-#define FPSCR_VXIMZ 0x00100000 /* Invalid op for Inv * Zero */
-#define FPSCR_VXVC 0x00080000 /* Invalid op for Compare */
-#define FPSCR_FR 0x00040000 /* Fraction rounded */
-#define FPSCR_FI 0x00020000 /* Fraction inexact */
-#define FPSCR_FPRF 0x0001f000 /* FPU Result Flags */
-#define FPSCR_FPCC 0x0000f000 /* FPU Condition Codes */
-#define FPSCR_VXSOFT 0x00000400 /* Invalid op for software request */
-#define FPSCR_VXSQRT 0x00000200 /* Invalid op for square root */
-#define FPSCR_VXCVI 0x00000100 /* Invalid op for integer convert */
-#define FPSCR_VE 0x00000080 /* Invalid op exception enable */
-#define FPSCR_OE 0x00000040 /* IEEE overflow exception enable */
-#define FPSCR_UE 0x00000020 /* IEEE underflow exception enable */
-#define FPSCR_ZE 0x00000010 /* IEEE zero divide exception enable */
-#define FPSCR_XE 0x00000008 /* FP inexact exception enable */
-#define FPSCR_NI 0x00000004 /* FPU non IEEE-Mode */
-#define FPSCR_RN 0x00000003 /* FPU rounding control */
-
-/* Special Purpose Registers (SPRNs)*/
-
-#define SPRN_CTR 0x009 /* Count Register */
-#define SPRN_DABR 0x3F5 /* Data Address Breakpoint Register */
-#define DABR_TRANSLATION (1UL << 2)
-#define SPRN_DAR 0x013 /* Data Address Register */
-#define SPRN_DEC 0x016 /* Decrement Register */
-#define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */
-#define DSISR_NOHPTE 0x40000000 /* no translation found */
-#define DSISR_PROTFAULT 0x08000000 /* protection fault */
-#define DSISR_ISSTORE 0x02000000 /* access was a store */
-#define DSISR_DABRMATCH 0x00400000 /* hit data breakpoint */
-#define DSISR_NOSEGMENT 0x00200000 /* STAB/SLB miss */
-#define SPRN_HID0 0x3F0 /* Hardware Implementation Register 0 */
-#define SPRN_MSRDORM 0x3F1 /* Hardware Implementation Register 1 */
-#define SPRN_HID1 0x3F1 /* Hardware Implementation Register 1 */
-#define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */
-#define SPRN_NIADORM 0x3F3 /* Hardware Implementation Register 2 */
-#define SPRN_HID4 0x3F4 /* 970 HID4 */
-#define SPRN_HID5 0x3F6 /* 970 HID5 */
-#define SPRN_HID6 0x3F9 /* BE HID 6 */
-#define HID6_LB (0x0F<<12) /* Concurrent Large Page Modes */
-#define HID6_DLP (1<<20) /* Disable all large page modes (4K only) */
-#define SPRN_TSCR 0x399 /* Thread switch control on BE */
-#define SPRN_TTR 0x39A /* Thread switch timeout on BE */
-#define TSCR_DEC_ENABLE 0x200000 /* Decrementer Interrupt */
-#define TSCR_EE_ENABLE 0x100000 /* External Interrupt */
-#define TSCR_EE_BOOST 0x080000 /* External Interrupt Boost */
-#define SPRN_TSC 0x3FD /* Thread switch control on others */
-#define SPRN_TST 0x3FC /* Thread switch timeout on others */
-#define SPRN_L2CR 0x3F9 /* Level 2 Cache Control Regsiter */
-#define SPRN_LR 0x008 /* Link Register */
-#define SPRN_PIR 0x3FF /* Processor Identification Register */
-#define SPRN_PIT 0x3DB /* Programmable Interval Timer */
-#define SPRN_PURR 0x135 /* Processor Utilization of Resources Register */
-#define SPRN_PVR 0x11F /* Processor Version Register */
-#define SPRN_RPA 0x3D6 /* Required Physical Address Register */
-#define SPRN_SDA 0x3BF /* Sampled Data Address Register */
-#define SPRN_SDR1 0x019 /* MMU Hash Base Register */
-#define SPRN_SIA 0x3BB /* Sampled Instruction Address Register */
-#define SPRN_SPRG0 0x110 /* Special Purpose Register General 0 */
-#define SPRN_SPRG1 0x111 /* Special Purpose Register General 1 */
-#define SPRN_SPRG2 0x112 /* Special Purpose Register General 2 */
-#define SPRN_SPRG3 0x113 /* Special Purpose Register General 3 */
-#define SPRN_SRR0 0x01A /* Save/Restore Register 0 */
-#define SPRN_SRR1 0x01B /* Save/Restore Register 1 */
-#define SPRN_TBRL 0x10C /* Time Base Read Lower Register (user, R/O) */
-#define SPRN_TBRU 0x10D /* Time Base Read Upper Register (user, R/O) */
-#define SPRN_TBWL 0x11C /* Time Base Lower Register (super, W/O) */
-#define SPRN_TBWU 0x11D /* Time Base Write Upper Register (super, W/O) */
-#define SPRN_HIOR 0x137 /* 970 Hypervisor interrupt offset */
-#define SPRN_USIA 0x3AB /* User Sampled Instruction Address Register */
-#define SPRN_XER 0x001 /* Fixed Point Exception Register */
-#define SPRN_VRSAVE 0x100 /* Vector save */
-#define SPRN_CTRLF 0x088
-#define SPRN_CTRLT 0x098
-#define CTRL_RUNLATCH 0x1
-
-/* Performance monitor SPRs */
-#define SPRN_SIAR 780
-#define SPRN_SDAR 781
-#define SPRN_MMCRA 786
-#define MMCRA_SIHV 0x10000000UL /* state of MSR HV when SIAR set */
-#define MMCRA_SIPR 0x08000000UL /* state of MSR PR when SIAR set */
-#define MMCRA_SAMPLE_ENABLE 0x00000001UL /* enable sampling */
-#define SPRN_PMC1 787
-#define SPRN_PMC2 788
-#define SPRN_PMC3 789
-#define SPRN_PMC4 790
-#define SPRN_PMC5 791
-#define SPRN_PMC6 792
-#define SPRN_PMC7 793
-#define SPRN_PMC8 794
-#define SPRN_MMCR0 795
-#define MMCR0_FC 0x80000000UL /* freeze counters. set to 1 on a perfmon exception */
-#define MMCR0_FCS 0x40000000UL /* freeze in supervisor state */
-#define MMCR0_KERNEL_DISABLE MMCR0_FCS
-#define MMCR0_FCP 0x20000000UL /* freeze in problem state */
-#define MMCR0_PROBLEM_DISABLE MMCR0_FCP
-#define MMCR0_FCM1 0x10000000UL /* freeze counters while MSR mark = 1 */
-#define MMCR0_FCM0 0x08000000UL /* freeze counters while MSR mark = 0 */
-#define MMCR0_PMXE 0x04000000UL /* performance monitor exception enable */
-#define MMCR0_FCECE 0x02000000UL /* freeze counters on enabled condition or event */
-/* time base exception enable */
-#define MMCR0_TBEE 0x00400000UL /* time base exception enable */
-#define MMCR0_PMC1CE 0x00008000UL /* PMC1 count enable*/
-#define MMCR0_PMCjCE 0x00004000UL /* PMCj count enable*/
-#define MMCR0_TRIGGER 0x00002000UL /* TRIGGER enable */
-#define MMCR0_PMAO 0x00000080UL /* performance monitor alert has occurred, set to 0 after handling exception */
-#define MMCR0_SHRFC 0x00000040UL /* SHRre freeze conditions between threads */
-#define MMCR0_FCTI 0x00000008UL /* freeze counters in tags inactive mode */
-#define MMCR0_FCTA 0x00000004UL /* freeze counters in tags active mode */
-#define MMCR0_FCWAIT 0x00000002UL /* freeze counter in WAIT state */
-#define MMCR0_FCHV 0x00000001UL /* freeze conditions in hypervisor mode */
-#define SPRN_MMCR1 798
-
-/* Short-hand versions for a number of the above SPRNs */
-
-#define CTR SPRN_CTR /* Counter Register */
-#define DAR SPRN_DAR /* Data Address Register */
-#define DABR SPRN_DABR /* Data Address Breakpoint Register */
-#define DEC SPRN_DEC /* Decrement Register */
-#define DSISR SPRN_DSISR /* Data Storage Interrupt Status Register */
-#define HID0 SPRN_HID0 /* Hardware Implementation Register 0 */
-#define MSRDORM SPRN_MSRDORM /* MSR Dormant Register */
-#define NIADORM SPRN_NIADORM /* NIA Dormant Register */
-#define TSC SPRN_TSC /* Thread switch control */
-#define TST SPRN_TST /* Thread switch timeout */
-#define IABR SPRN_IABR /* Instruction Address Breakpoint Register */
-#define L2CR SPRN_L2CR /* PPC 750 L2 control register */
-#define __LR SPRN_LR
-#define PVR SPRN_PVR /* Processor Version */
-#define PIR SPRN_PIR /* Processor ID */
-#define PURR SPRN_PURR /* Processor Utilization of Resource Register */
-#define SDR1 SPRN_SDR1 /* MMU hash base register */
-#define SPR0 SPRN_SPRG0 /* Supervisor Private Registers */
-#define SPR1 SPRN_SPRG1
-#define SPR2 SPRN_SPRG2
-#define SPR3 SPRN_SPRG3
-#define SPRG0 SPRN_SPRG0
-#define SPRG1 SPRN_SPRG1
-#define SPRG2 SPRN_SPRG2
-#define SPRG3 SPRN_SPRG3
-#define SRR0 SPRN_SRR0 /* Save and Restore Register 0 */
-#define SRR1 SPRN_SRR1 /* Save and Restore Register 1 */
-#define TBRL SPRN_TBRL /* Time Base Read Lower Register */
-#define TBRU SPRN_TBRU /* Time Base Read Upper Register */
-#define TBWL SPRN_TBWL /* Time Base Write Lower Register */
-#define TBWU SPRN_TBWU /* Time Base Write Upper Register */
-#define XER SPRN_XER
-
-/* Processor Version Register (PVR) field extraction */
-
-#define PVR_VER(pvr) (((pvr) >> 16) & 0xFFFF) /* Version field */
-#define PVR_REV(pvr) (((pvr) >> 0) & 0xFFFF) /* Revison field */
-
-/* Processor Version Numbers */
-#define PV_NORTHSTAR 0x0033
-#define PV_PULSAR 0x0034
-#define PV_POWER4 0x0035
-#define PV_ICESTAR 0x0036
-#define PV_SSTAR 0x0037
-#define PV_POWER4p 0x0038
-#define PV_970 0x0039
-#define PV_POWER5 0x003A
-#define PV_POWER5p 0x003B
-#define PV_970FX 0x003C
-#define PV_630 0x0040
-#define PV_630p 0x0041
-#define PV_970MP 0x0044
-#define PV_BE 0x0070
-
-/* Platforms supported by PPC64 */
-#define PLATFORM_PSERIES 0x0100
-#define PLATFORM_PSERIES_LPAR 0x0101
-#define PLATFORM_ISERIES_LPAR 0x0201
-#define PLATFORM_LPAR 0x0001
-#define PLATFORM_POWERMAC 0x0400
-#define PLATFORM_MAPLE 0x0500
-#define PLATFORM_BPA 0x1000
-
-/* Compatibility with drivers coming from PPC32 world */
-#define _machine (systemcfg->platform)
-#define _MACH_Pmac PLATFORM_POWERMAC
-
-/*
- * List of interrupt controllers.
- */
-#define IC_INVALID 0
-#define IC_OPEN_PIC 1
-#define IC_PPC_XIC 2
-#define IC_BPA_IIC 3
-
-#define XGLUE(a,b) a##b
-#define GLUE(a,b) XGLUE(a,b)
-
-#ifdef __ASSEMBLY__
-
-#define _GLOBAL(name) \
- .section ".text"; \
- .align 2 ; \
- .globl name; \
- .globl GLUE(.,name); \
- .section ".opd","aw"; \
-name: \
- .quad GLUE(.,name); \
- .quad .TOC.@tocbase; \
- .quad 0; \
- .previous; \
- .type GLUE(.,name),@function; \
-GLUE(.,name):
-
-#define _KPROBE(name) \
- .section ".kprobes.text","a"; \
- .align 2 ; \
- .globl name; \
- .globl GLUE(.,name); \
- .section ".opd","aw"; \
-name: \
- .quad GLUE(.,name); \
- .quad .TOC.@tocbase; \
- .quad 0; \
- .previous; \
- .type GLUE(.,name),@function; \
-GLUE(.,name):
-
-#define _STATIC(name) \
- .section ".text"; \
- .align 2 ; \
- .section ".opd","aw"; \
-name: \
- .quad GLUE(.,name); \
- .quad .TOC.@tocbase; \
- .quad 0; \
- .previous; \
- .type GLUE(.,name),@function; \
-GLUE(.,name):
-
-#else /* __ASSEMBLY__ */
-
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#define current_text_addr() ({ __label__ _l; _l: &&_l;})
-
-/* Macros for setting and retrieving special purpose registers */
-
-#define mfmsr() ({unsigned long rval; \
- asm volatile("mfmsr %0" : "=r" (rval)); rval;})
-
-#define __mtmsrd(v, l) asm volatile("mtmsrd %0," __stringify(l) \
- : : "r" (v))
-#define mtmsrd(v) __mtmsrd((v), 0)
-
-#define mfspr(rn) ({unsigned long rval; \
- asm volatile("mfspr %0," __stringify(rn) \
- : "=r" (rval)); rval;})
-#define mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : : "r" (v))
-
-#define mftb() ({unsigned long rval; \
- asm volatile("mftb %0" : "=r" (rval)); rval;})
-
-#define mttbl(v) asm volatile("mttbl %0":: "r"(v))
-#define mttbu(v) asm volatile("mttbu %0":: "r"(v))
-
-#define mfasr() ({unsigned long rval; \
- asm volatile("mfasr %0" : "=r" (rval)); rval;})
-
-static inline void set_tb(unsigned int upper, unsigned int lower)
-{
- mttbl(0);
- mttbu(upper);
- mttbl(lower);
-}
-
-#define __get_SP() ({unsigned long sp; \
- asm volatile("mr %0,1": "=r" (sp)); sp;})
-
-#ifdef __KERNEL__
-
-extern int have_of;
-extern u64 ppc64_interrupt_controller;
-
-struct task_struct;
-void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp);
-void release_thread(struct task_struct *);
-
-/* Prepare to copy thread state - unlazy all lazy status */
-extern void prepare_to_copy(struct task_struct *tsk);
-
-/* Create a new kernel thread. */
-extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
-/* Lazy FPU handling on uni-processor */
-extern struct task_struct *last_task_used_math;
-extern struct task_struct *last_task_used_altivec;
-
-/* 64-bit user address space is 44-bits (16TB user VM) */
-#define TASK_SIZE_USER64 (0x0000100000000000UL)
-
-/*
- * 32-bit user address space is 4GB - 1 page
- * (this 1 page is needed so referencing of 0xFFFFFFFF generates EFAULT
- */
-#define TASK_SIZE_USER32 (0x0000000100000000UL - (1*PAGE_SIZE))
-
-#define TASK_SIZE (test_thread_flag(TIF_32BIT) ? \
- TASK_SIZE_USER32 : TASK_SIZE_USER64)
-
-/* This decides where the kernel will search for a free chunk of vm
- * space during mmap's.
- */
-#define TASK_UNMAPPED_BASE_USER32 (PAGE_ALIGN(TASK_SIZE_USER32 / 4))
-#define TASK_UNMAPPED_BASE_USER64 (PAGE_ALIGN(TASK_SIZE_USER64 / 4))
-
-#define TASK_UNMAPPED_BASE ((test_thread_flag(TIF_32BIT)||(ppcdebugset(PPCDBG_BINFMT_32ADDR))) ? \
- TASK_UNMAPPED_BASE_USER32 : TASK_UNMAPPED_BASE_USER64 )
-
-typedef struct {
- unsigned long seg;
-} mm_segment_t;
-
-struct thread_struct {
- unsigned long ksp; /* Kernel stack pointer */
- unsigned long ksp_vsid;
- struct pt_regs *regs; /* Pointer to saved register state */
- mm_segment_t fs; /* for get_fs() validation */
- double fpr[32]; /* Complete floating point set */
- unsigned long fpscr; /* Floating point status (plus pad) */
- unsigned long fpexc_mode; /* Floating-point exception mode */
- unsigned long start_tb; /* Start purr when proc switched in */
- unsigned long accum_tb; /* Total accumilated purr for process */
- unsigned long vdso_base; /* base of the vDSO library */
- unsigned long dabr; /* Data address breakpoint register */
-#ifdef CONFIG_ALTIVEC
- /* Complete AltiVec register set */
- vector128 vr[32] __attribute((aligned(16)));
- /* AltiVec status */
- vector128 vscr __attribute((aligned(16)));
- unsigned long vrsave;
- int used_vr; /* set if process has used altivec */
-#endif /* CONFIG_ALTIVEC */
-};
-
-#define ARCH_MIN_TASKALIGN 16
-
-#define INIT_SP (sizeof(init_stack) + (unsigned long) &init_stack)
-
-#define INIT_THREAD { \
- .ksp = INIT_SP, \
- .regs = (struct pt_regs *)INIT_SP - 1, \
- .fs = KERNEL_DS, \
- .fpr = {0}, \
- .fpscr = 0, \
- .fpexc_mode = MSR_FE0|MSR_FE1, \
-}
-
-/*
- * Return saved PC of a blocked thread. For now, this is the "user" PC
- */
-#define thread_saved_pc(tsk) \
- ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0)
-
-unsigned long get_wchan(struct task_struct *p);
-
-#define KSTK_EIP(tsk) ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0)
-#define KSTK_ESP(tsk) ((tsk)->thread.regs? (tsk)->thread.regs->gpr[1]: 0)
-
-/* Get/set floating-point exception mode */
-#define GET_FPEXC_CTL(tsk, adr) get_fpexc_mode((tsk), (adr))
-#define SET_FPEXC_CTL(tsk, val) set_fpexc_mode((tsk), (val))
-
-extern int get_fpexc_mode(struct task_struct *tsk, unsigned long adr);
-extern int set_fpexc_mode(struct task_struct *tsk, unsigned int val);
-
-static inline unsigned int __unpack_fe01(unsigned long msr_bits)
-{
- return ((msr_bits & MSR_FE0) >> 10) | ((msr_bits & MSR_FE1) >> 8);
-}
-
-static inline unsigned long __pack_fe01(unsigned int fpmode)
-{
- return ((fpmode << 10) & MSR_FE0) | ((fpmode << 8) & MSR_FE1);
-}
-
-#define cpu_relax() do { HMT_low(); HMT_medium(); barrier(); } while (0)
-
-/*
- * Prefetch macros.
- */
-#define ARCH_HAS_PREFETCH
-#define ARCH_HAS_PREFETCHW
-#define ARCH_HAS_SPINLOCK_PREFETCH
-
-static inline void prefetch(const void *x)
-{
- if (unlikely(!x))
- return;
-
- __asm__ __volatile__ ("dcbt 0,%0" : : "r" (x));
-}
-
-static inline void prefetchw(const void *x)
-{
- if (unlikely(!x))
- return;
-
- __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (x));
-}
-
-#define spin_lock_prefetch(x) prefetchw(x)
-
-#define HAVE_ARCH_PICK_MMAP_LAYOUT
-
-static inline void ppc64_runlatch_on(void)
-{
- unsigned long ctrl;
-
- if (cpu_has_feature(CPU_FTR_CTRL)) {
- ctrl = mfspr(SPRN_CTRLF);
- ctrl |= CTRL_RUNLATCH;
- mtspr(SPRN_CTRLT, ctrl);
- }
-}
-
-static inline void ppc64_runlatch_off(void)
-{
- unsigned long ctrl;
-
- if (cpu_has_feature(CPU_FTR_CTRL)) {
- ctrl = mfspr(SPRN_CTRLF);
- ctrl &= ~CTRL_RUNLATCH;
- mtspr(SPRN_CTRLT, ctrl);
- }
-}
-
-#endif /* __KERNEL__ */
-
-#endif /* __ASSEMBLY__ */
-
-#ifdef __KERNEL__
-#define RUNLATCH_ON(REG) \
-BEGIN_FTR_SECTION \
- mfspr (REG),SPRN_CTRLF; \
- ori (REG),(REG),CTRL_RUNLATCH; \
- mtspr SPRN_CTRLT,(REG); \
-END_FTR_SECTION_IFSET(CPU_FTR_CTRL)
-#endif
-
-/*
- * Number of entries in the SLB. If this ever changes we should handle
- * it with a use a cpu feature fixup.
- */
-#define SLB_NUM_ENTRIES 64
-
-#endif /* __ASM_PPC64_PROCESSOR_H */
diff --git a/include/asm-ppc64/prom.h b/include/asm-ppc64/prom.h
index c02ec1d6b909..e8d0d2ab4c0f 100644
--- a/include/asm-ppc64/prom.h
+++ b/include/asm-ppc64/prom.h
@@ -14,6 +14,7 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
+#include <linux/config.h>
#include <linux/proc_fs.h>
#include <asm/atomic.h>
@@ -137,6 +138,9 @@ struct device_node {
struct kref kref;
unsigned long _flags;
void *data;
+#ifdef CONFIG_PPC_ISERIES
+ struct list_head Device_List;
+#endif
};
extern struct device_node *of_chosen;
diff --git a/include/asm-ppc64/smp.h b/include/asm-ppc64/smp.h
index d86f742e9a21..c5e9052e7967 100644
--- a/include/asm-ppc64/smp.h
+++ b/include/asm-ppc64/smp.h
@@ -77,7 +77,6 @@ extern int smt_enabled_at_boot;
extern int smp_mpic_probe(void);
extern void smp_mpic_setup_cpu(int cpu);
-extern void smp_mpic_message_pass(int target, int msg);
extern void smp_generic_kick_cpu(int nr);
extern void smp_generic_give_timebase(void);
diff --git a/include/asm-ppc64/system.h b/include/asm-ppc64/system.h
index 375015c62f20..99b8ca52f101 100644
--- a/include/asm-ppc64/system.h
+++ b/include/asm-ppc64/system.h
@@ -13,7 +13,7 @@
#include <asm/page.h>
#include <asm/processor.h>
#include <asm/hw_irq.h>
-#include <asm/memory.h>
+#include <asm/synch.h>
/*
* Memory barrier.
@@ -48,7 +48,7 @@
#ifdef CONFIG_SMP
#define smp_mb() mb()
#define smp_rmb() rmb()
-#define smp_wmb() __asm__ __volatile__ ("eieio" : : : "memory")
+#define smp_wmb() eieio()
#define smp_read_barrier_depends() read_barrier_depends()
#else
#define smp_mb() __asm__ __volatile__("": : :"memory")
@@ -120,8 +120,8 @@ extern void giveup_altivec(struct task_struct *);
extern void disable_kernel_altivec(void);
extern void enable_kernel_altivec(void);
extern int emulate_altivec(struct pt_regs *);
-extern void cvt_fd(float *from, double *to, unsigned long *fpscr);
-extern void cvt_df(double *from, float *to, unsigned long *fpscr);
+extern void cvt_fd(float *from, double *to, struct thread_struct *thread);
+extern void cvt_df(double *from, float *to, struct thread_struct *thread);
#ifdef CONFIG_ALTIVEC
extern void flush_altivec_to_thread(struct task_struct *);
@@ -131,7 +131,12 @@ static inline void flush_altivec_to_thread(struct task_struct *t)
}
#endif
+static inline void flush_spe_to_thread(struct task_struct *t)
+{
+}
+
extern int mem_init_done; /* set on boot once kmalloc can be called */
+extern unsigned long memory_limit;
/* EBCDIC -> ASCII conversion for [0-9A-Z] on iSeries */
extern unsigned char e2a(unsigned char);
@@ -144,12 +149,7 @@ struct thread_struct;
extern struct task_struct * _switch(struct thread_struct *prev,
struct thread_struct *next);
-static inline int __is_processor(unsigned long pv)
-{
- unsigned long pvr;
- asm("mfspr %0, 0x11F" : "=r" (pvr));
- return(PVR_VER(pvr) == pv);
-}
+extern int powersave_nap; /* set if nap mode can be used in idle loop */
/*
* Atomic exchange
diff --git a/include/asm-ppc64/tce.h b/include/asm-ppc64/tce.h
new file mode 100644
index 000000000000..d40b6b42ab35
--- /dev/null
+++ b/include/asm-ppc64/tce.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
+ * Rewrite, cleanup:
+ * Copyright (C) 2004 Olof Johansson <olof@austin.ibm.com>, IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _ASM_TCE_H
+#define _ASM_TCE_H
+
+/*
+ * Tces come in two formats, one for the virtual bus and a different
+ * format for PCI
+ */
+#define TCE_VB 0
+#define TCE_PCI 1
+
+/* TCE page size is 4096 bytes (1 << 12) */
+
+#define TCE_SHIFT 12
+#define TCE_PAGE_SIZE (1 << TCE_SHIFT)
+#define TCE_PAGE_FACTOR (PAGE_SHIFT - TCE_SHIFT)
+
+
+/* tce_entry
+ * Used by pSeries (SMP) and iSeries/pSeries LPAR, but there it's
+ * abstracted so layout is irrelevant.
+ */
+union tce_entry {
+ unsigned long te_word;
+ struct {
+ unsigned int tb_cacheBits :6; /* Cache hash bits - not used */
+ unsigned int tb_rsvd :6;
+ unsigned long tb_rpn :40; /* Real page number */
+ unsigned int tb_valid :1; /* Tce is valid (vb only) */
+ unsigned int tb_allio :1; /* Tce is valid for all lps (vb only) */
+ unsigned int tb_lpindex :8; /* LpIndex for user of TCE (vb only) */
+ unsigned int tb_pciwr :1; /* Write allowed (pci only) */
+ unsigned int tb_rdwr :1; /* Read allowed (pci), Write allowed (vb) */
+ } te_bits;
+#define te_cacheBits te_bits.tb_cacheBits
+#define te_rpn te_bits.tb_rpn
+#define te_valid te_bits.tb_valid
+#define te_allio te_bits.tb_allio
+#define te_lpindex te_bits.tb_lpindex
+#define te_pciwr te_bits.tb_pciwr
+#define te_rdwr te_bits.tb_rdwr
+};
+
+
+#endif
diff --git a/include/asm-ppc64/time.h b/include/asm-ppc64/time.h
deleted file mode 100644
index c6c762cad8b0..000000000000
--- a/include/asm-ppc64/time.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Common time prototypes and such for all ppc machines.
- *
- * Written by Cort Dougan (cort@cs.nmt.edu) to merge
- * Paul Mackerras' version and mine for PReP and Pmac.
- *
- * This program is free software; you can redistribute 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 __PPC64_TIME_H
-#define __PPC64_TIME_H
-
-#ifdef __KERNEL__
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/mc146818rtc.h>
-
-#include <asm/processor.h>
-#include <asm/paca.h>
-#include <asm/iSeries/HvCall.h>
-
-/* time.c */
-extern unsigned long tb_ticks_per_jiffy;
-extern unsigned long tb_ticks_per_usec;
-extern unsigned long tb_ticks_per_sec;
-extern unsigned long tb_to_xs;
-extern unsigned tb_to_us;
-extern unsigned long tb_last_stamp;
-
-struct rtc_time;
-extern void to_tm(int tim, struct rtc_time * tm);
-extern time_t last_rtc_update;
-
-void generic_calibrate_decr(void);
-void setup_default_decr(void);
-
-/* Some sane defaults: 125 MHz timebase, 1GHz processor */
-extern unsigned long ppc_proc_freq;
-#define DEFAULT_PROC_FREQ (DEFAULT_TB_FREQ * 8)
-extern unsigned long ppc_tb_freq;
-#define DEFAULT_TB_FREQ 125000000UL
-
-/*
- * By putting all of this stuff into a single struct we
- * reduce the number of cache lines touched by do_gettimeofday.
- * Both by collecting all of the data in one cache line and
- * by touching only one TOC entry
- */
-struct gettimeofday_vars {
- unsigned long tb_to_xs;
- unsigned long stamp_xsec;
- unsigned long tb_orig_stamp;
-};
-
-struct gettimeofday_struct {
- unsigned long tb_ticks_per_sec;
- struct gettimeofday_vars vars[2];
- struct gettimeofday_vars * volatile varp;
- unsigned var_idx;
- unsigned tb_to_us;
-};
-
-struct div_result {
- unsigned long result_high;
- unsigned long result_low;
-};
-
-int via_calibrate_decr(void);
-
-static __inline__ unsigned long get_tb(void)
-{
- return mftb();
-}
-
-/* Accessor functions for the decrementer register. */
-static __inline__ unsigned int get_dec(void)
-{
- return (mfspr(SPRN_DEC));
-}
-
-static __inline__ void set_dec(int val)
-{
-#ifdef CONFIG_PPC_ISERIES
- struct paca_struct *lpaca = get_paca();
- int cur_dec;
-
- if (lpaca->lppaca.shared_proc) {
- lpaca->lppaca.virtual_decr = val;
- cur_dec = get_dec();
- if (cur_dec > val)
- HvCall_setVirtualDecr();
- } else
-#endif
- mtspr(SPRN_DEC, val);
-}
-
-static inline unsigned long tb_ticks_since(unsigned long tstamp)
-{
- return get_tb() - tstamp;
-}
-
-#define mulhwu(x,y) \
-({unsigned z; asm ("mulhwu %0,%1,%2" : "=r" (z) : "r" (x), "r" (y)); z;})
-#define mulhdu(x,y) \
-({unsigned long z; asm ("mulhdu %0,%1,%2" : "=r" (z) : "r" (x), "r" (y)); z;})
-
-
-unsigned mulhwu_scale_factor(unsigned, unsigned);
-void div128_by_32( unsigned long dividend_high, unsigned long dividend_low,
- unsigned divisor, struct div_result *dr );
-
-/* Used to store Processor Utilization register (purr) values */
-
-struct cpu_usage {
- u64 current_tb; /* Holds the current purr register values */
-};
-
-DECLARE_PER_CPU(struct cpu_usage, cpu_usage_array);
-
-#endif /* __KERNEL__ */
-#endif /* __PPC64_TIME_H */
diff --git a/include/asm-ppc64/tlbflush.h b/include/asm-ppc64/tlbflush.h
index 74271d7c1d16..626f505c6ee3 100644
--- a/include/asm-ppc64/tlbflush.h
+++ b/include/asm-ppc64/tlbflush.h
@@ -20,10 +20,8 @@
struct mm_struct;
struct ppc64_tlb_batch {
unsigned long index;
- unsigned long context;
struct mm_struct *mm;
pte_t pte[PPC64_TLB_BATCH_NR];
- unsigned long addr[PPC64_TLB_BATCH_NR];
unsigned long vaddr[PPC64_TLB_BATCH_NR];
unsigned int large;
};
@@ -48,8 +46,7 @@ static inline void flush_tlb_pending(void)
#define flush_tlb_kernel_range(start, end) flush_tlb_pending()
#define flush_tlb_pgtables(mm, start, end) do { } while (0)
-extern void flush_hash_page(unsigned long context, unsigned long ea, pte_t pte,
- int local);
-void flush_hash_range(unsigned long context, unsigned long number, int local);
+extern void flush_hash_page(unsigned long va, pte_t pte, int local);
+void flush_hash_range(unsigned long number, int local);
#endif /* _PPC64_TLBFLUSH_H */
diff --git a/include/asm-ppc64/udbg.h b/include/asm-ppc64/udbg.h
index c786604aef02..8192fb8541cc 100644
--- a/include/asm-ppc64/udbg.h
+++ b/include/asm-ppc64/udbg.h
@@ -28,4 +28,7 @@ extern unsigned long udbg_ifdebug(unsigned long flags);
extern void __init ppcdbg_initialize(void);
extern void udbg_init_uart(void __iomem *comport, unsigned int speed);
+
+struct device_node;
+extern void udbg_init_scc(struct device_node *np);
#endif
diff --git a/include/asm-ppc64/uninorth.h b/include/asm-ppc64/uninorth.h
deleted file mode 100644
index 7ad7059f2c80..000000000000
--- a/include/asm-ppc64/uninorth.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include <asm-ppc/uninorth.h>
-
diff --git a/include/asm-ppc64/unistd.h b/include/asm-ppc64/unistd.h
deleted file mode 100644
index 977bc980c1af..000000000000
--- a/include/asm-ppc64/unistd.h
+++ /dev/null
@@ -1,487 +0,0 @@
-#ifndef _ASM_PPC_UNISTD_H_
-#define _ASM_PPC_UNISTD_H_
-
-/*
- * This file contains the system call numbers.
- *
- * This program is free software; you can redistribute 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.
- */
-
-#define __NR_restart_syscall 0
-#define __NR_exit 1
-#define __NR_fork 2
-#define __NR_read 3
-#define __NR_write 4
-#define __NR_open 5
-#define __NR_close 6
-#define __NR_waitpid 7
-#define __NR_creat 8
-#define __NR_link 9
-#define __NR_unlink 10
-#define __NR_execve 11
-#define __NR_chdir 12
-#define __NR_time 13
-#define __NR_mknod 14
-#define __NR_chmod 15
-#define __NR_lchown 16
-#define __NR_break 17
-#define __NR_oldstat 18
-#define __NR_lseek 19
-#define __NR_getpid 20
-#define __NR_mount 21
-#define __NR_umount 22
-#define __NR_setuid 23
-#define __NR_getuid 24
-#define __NR_stime 25
-#define __NR_ptrace 26
-#define __NR_alarm 27
-#define __NR_oldfstat 28
-#define __NR_pause 29
-#define __NR_utime 30
-#define __NR_stty 31
-#define __NR_gtty 32
-#define __NR_access 33
-#define __NR_nice 34
-#define __NR_ftime 35
-#define __NR_sync 36
-#define __NR_kill 37
-#define __NR_rename 38
-#define __NR_mkdir 39
-#define __NR_rmdir 40
-#define __NR_dup 41
-#define __NR_pipe 42
-#define __NR_times 43
-#define __NR_prof 44
-#define __NR_brk 45
-#define __NR_setgid 46
-#define __NR_getgid 47
-#define __NR_signal 48
-#define __NR_geteuid 49
-#define __NR_getegid 50
-#define __NR_acct 51
-#define __NR_umount2 52
-#define __NR_lock 53
-#define __NR_ioctl 54
-#define __NR_fcntl 55
-#define __NR_mpx 56
-#define __NR_setpgid 57
-#define __NR_ulimit 58
-#define __NR_oldolduname 59
-#define __NR_umask 60
-#define __NR_chroot 61
-#define __NR_ustat 62
-#define __NR_dup2 63
-#define __NR_getppid 64
-#define __NR_getpgrp 65
-#define __NR_setsid 66
-#define __NR_sigaction 67
-#define __NR_sgetmask 68
-#define __NR_ssetmask 69
-#define __NR_setreuid 70
-#define __NR_setregid 71
-#define __NR_sigsuspend 72
-#define __NR_sigpending 73
-#define __NR_sethostname 74
-#define __NR_setrlimit 75
-#define __NR_getrlimit 76
-#define __NR_getrusage 77
-#define __NR_gettimeofday 78
-#define __NR_settimeofday 79
-#define __NR_getgroups 80
-#define __NR_setgroups 81
-#define __NR_select 82
-#define __NR_symlink 83
-#define __NR_oldlstat 84
-#define __NR_readlink 85
-#define __NR_uselib 86
-#define __NR_swapon 87
-#define __NR_reboot 88
-#define __NR_readdir 89
-#define __NR_mmap 90
-#define __NR_munmap 91
-#define __NR_truncate 92
-#define __NR_ftruncate 93
-#define __NR_fchmod 94
-#define __NR_fchown 95
-#define __NR_getpriority 96
-#define __NR_setpriority 97
-#define __NR_profil 98
-#define __NR_statfs 99
-#define __NR_fstatfs 100
-#define __NR_ioperm 101
-#define __NR_socketcall 102
-#define __NR_syslog 103
-#define __NR_setitimer 104
-#define __NR_getitimer 105
-#define __NR_stat 106
-#define __NR_lstat 107
-#define __NR_fstat 108
-#define __NR_olduname 109
-#define __NR_iopl 110
-#define __NR_vhangup 111
-#define __NR_idle 112
-#define __NR_vm86 113
-#define __NR_wait4 114
-#define __NR_swapoff 115
-#define __NR_sysinfo 116
-#define __NR_ipc 117
-#define __NR_fsync 118
-#define __NR_sigreturn 119
-#define __NR_clone 120
-#define __NR_setdomainname 121
-#define __NR_uname 122
-#define __NR_modify_ldt 123
-#define __NR_adjtimex 124
-#define __NR_mprotect 125
-#define __NR_sigprocmask 126
-#define __NR_create_module 127
-#define __NR_init_module 128
-#define __NR_delete_module 129
-#define __NR_get_kernel_syms 130
-#define __NR_quotactl 131
-#define __NR_getpgid 132
-#define __NR_fchdir 133
-#define __NR_bdflush 134
-#define __NR_sysfs 135
-#define __NR_personality 136
-#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
-#define __NR_setfsuid 138
-#define __NR_setfsgid 139
-#define __NR__llseek 140
-#define __NR_getdents 141
-#define __NR__newselect 142
-#define __NR_flock 143
-#define __NR_msync 144
-#define __NR_readv 145
-#define __NR_writev 146
-#define __NR_getsid 147
-#define __NR_fdatasync 148
-#define __NR__sysctl 149
-#define __NR_mlock 150
-#define __NR_munlock 151
-#define __NR_mlockall 152
-#define __NR_munlockall 153
-#define __NR_sched_setparam 154
-#define __NR_sched_getparam 155
-#define __NR_sched_setscheduler 156
-#define __NR_sched_getscheduler 157
-#define __NR_sched_yield 158
-#define __NR_sched_get_priority_max 159
-#define __NR_sched_get_priority_min 160
-#define __NR_sched_rr_get_interval 161
-#define __NR_nanosleep 162
-#define __NR_mremap 163
-#define __NR_setresuid 164
-#define __NR_getresuid 165
-#define __NR_query_module 166
-#define __NR_poll 167
-#define __NR_nfsservctl 168
-#define __NR_setresgid 169
-#define __NR_getresgid 170
-#define __NR_prctl 171
-#define __NR_rt_sigreturn 172
-#define __NR_rt_sigaction 173
-#define __NR_rt_sigprocmask 174
-#define __NR_rt_sigpending 175
-#define __NR_rt_sigtimedwait 176
-#define __NR_rt_sigqueueinfo 177
-#define __NR_rt_sigsuspend 178
-#define __NR_pread64 179
-#define __NR_pwrite64 180
-#define __NR_chown 181
-#define __NR_getcwd 182
-#define __NR_capget 183
-#define __NR_capset 184
-#define __NR_sigaltstack 185
-#define __NR_sendfile 186
-#define __NR_getpmsg 187 /* some people actually want streams */
-#define __NR_putpmsg 188 /* some people actually want streams */
-#define __NR_vfork 189
-#define __NR_ugetrlimit 190 /* SuS compliant getrlimit */
-#define __NR_readahead 191
-/* #define __NR_mmap2 192 32bit only */
-/* #define __NR_truncate64 193 32bit only */
-/* #define __NR_ftruncate64 194 32bit only */
-/* #define __NR_stat64 195 32bit only */
-/* #define __NR_lstat64 196 32bit only */
-/* #define __NR_fstat64 197 32bit only */
-#define __NR_pciconfig_read 198
-#define __NR_pciconfig_write 199
-#define __NR_pciconfig_iobase 200
-#define __NR_multiplexer 201
-#define __NR_getdents64 202
-#define __NR_pivot_root 203
-/* #define __NR_fcntl64 204 32bit only */
-#define __NR_madvise 205
-#define __NR_mincore 206
-#define __NR_gettid 207
-#define __NR_tkill 208
-#define __NR_setxattr 209
-#define __NR_lsetxattr 210
-#define __NR_fsetxattr 211
-#define __NR_getxattr 212
-#define __NR_lgetxattr 213
-#define __NR_fgetxattr 214
-#define __NR_listxattr 215
-#define __NR_llistxattr 216
-#define __NR_flistxattr 217
-#define __NR_removexattr 218
-#define __NR_lremovexattr 219
-#define __NR_fremovexattr 220
-#define __NR_futex 221
-#define __NR_sched_setaffinity 222
-#define __NR_sched_getaffinity 223
-/* 224 currently unused */
-#define __NR_tuxcall 225
-/* #define __NR_sendfile64 226 32bit only */
-#define __NR_io_setup 227
-#define __NR_io_destroy 228
-#define __NR_io_getevents 229
-#define __NR_io_submit 230
-#define __NR_io_cancel 231
-#define __NR_set_tid_address 232
-#define __NR_fadvise64 233
-#define __NR_exit_group 234
-#define __NR_lookup_dcookie 235
-#define __NR_epoll_create 236
-#define __NR_epoll_ctl 237
-#define __NR_epoll_wait 238
-#define __NR_remap_file_pages 239
-#define __NR_timer_create 240
-#define __NR_timer_settime 241
-#define __NR_timer_gettime 242
-#define __NR_timer_getoverrun 243
-#define __NR_timer_delete 244
-#define __NR_clock_settime 245
-#define __NR_clock_gettime 246
-#define __NR_clock_getres 247
-#define __NR_clock_nanosleep 248
-#define __NR_swapcontext 249
-#define __NR_tgkill 250
-#define __NR_utimes 251
-#define __NR_statfs64 252
-#define __NR_fstatfs64 253
-/* #define __NR_fadvise64_64 254 32bit only */
-#define __NR_rtas 255
-/* Number 256 is reserved for sys_debug_setcontext */
-/* Number 257 is reserved for vserver */
-/* 258 currently unused */
-#define __NR_mbind 259
-#define __NR_get_mempolicy 260
-#define __NR_set_mempolicy 261
-#define __NR_mq_open 262
-#define __NR_mq_unlink 263
-#define __NR_mq_timedsend 264
-#define __NR_mq_timedreceive 265
-#define __NR_mq_notify 266
-#define __NR_mq_getsetattr 267
-#define __NR_kexec_load 268
-#define __NR_add_key 269
-#define __NR_request_key 270
-#define __NR_keyctl 271
-#define __NR_waitid 272
-#define __NR_ioprio_set 273
-#define __NR_ioprio_get 274
-#define __NR_inotify_init 275
-#define __NR_inotify_add_watch 276
-#define __NR_inotify_rm_watch 277
-
-#define __NR_syscalls 278
-#ifdef __KERNEL__
-#define NR_syscalls __NR_syscalls
-#endif
-
-#ifndef __ASSEMBLY__
-
-/* On powerpc a system call basically clobbers the same registers like a
- * function call, with the exception of LR (which is needed for the
- * "sc; bnslr" sequence) and CR (where only CR0.SO is clobbered to signal
- * an error return status).
- */
-
-#define __syscall_nr(nr, type, name, args...) \
- unsigned long __sc_ret, __sc_err; \
- { \
- register unsigned long __sc_0 __asm__ ("r0"); \
- register unsigned long __sc_3 __asm__ ("r3"); \
- register unsigned long __sc_4 __asm__ ("r4"); \
- register unsigned long __sc_5 __asm__ ("r5"); \
- register unsigned long __sc_6 __asm__ ("r6"); \
- register unsigned long __sc_7 __asm__ ("r7"); \
- register unsigned long __sc_8 __asm__ ("r8"); \
- \
- __sc_loadargs_##nr(name, args); \
- __asm__ __volatile__ \
- ("sc \n\t" \
- "mfcr %0 " \
- : "=&r" (__sc_0), \
- "=&r" (__sc_3), "=&r" (__sc_4), \
- "=&r" (__sc_5), "=&r" (__sc_6), \
- "=&r" (__sc_7), "=&r" (__sc_8) \
- : __sc_asm_input_##nr \
- : "cr0", "ctr", "memory", \
- "r9", "r10","r11", "r12"); \
- __sc_ret = __sc_3; \
- __sc_err = __sc_0; \
- } \
- if (__sc_err & 0x10000000) \
- { \
- errno = __sc_ret; \
- __sc_ret = -1; \
- } \
- return (type) __sc_ret
-
-#define __sc_loadargs_0(name, dummy...) \
- __sc_0 = __NR_##name
-#define __sc_loadargs_1(name, arg1) \
- __sc_loadargs_0(name); \
- __sc_3 = (unsigned long) (arg1)
-#define __sc_loadargs_2(name, arg1, arg2) \
- __sc_loadargs_1(name, arg1); \
- __sc_4 = (unsigned long) (arg2)
-#define __sc_loadargs_3(name, arg1, arg2, arg3) \
- __sc_loadargs_2(name, arg1, arg2); \
- __sc_5 = (unsigned long) (arg3)
-#define __sc_loadargs_4(name, arg1, arg2, arg3, arg4) \
- __sc_loadargs_3(name, arg1, arg2, arg3); \
- __sc_6 = (unsigned long) (arg4)
-#define __sc_loadargs_5(name, arg1, arg2, arg3, arg4, arg5) \
- __sc_loadargs_4(name, arg1, arg2, arg3, arg4); \
- __sc_7 = (unsigned long) (arg5)
-#define __sc_loadargs_6(name, arg1, arg2, arg3, arg4, arg5, arg6) \
- __sc_loadargs_5(name, arg1, arg2, arg3, arg4, arg5); \
- __sc_8 = (unsigned long) (arg6)
-
-#define __sc_asm_input_0 "0" (__sc_0)
-#define __sc_asm_input_1 __sc_asm_input_0, "1" (__sc_3)
-#define __sc_asm_input_2 __sc_asm_input_1, "2" (__sc_4)
-#define __sc_asm_input_3 __sc_asm_input_2, "3" (__sc_5)
-#define __sc_asm_input_4 __sc_asm_input_3, "4" (__sc_6)
-#define __sc_asm_input_5 __sc_asm_input_4, "5" (__sc_7)
-#define __sc_asm_input_6 __sc_asm_input_5, "6" (__sc_8)
-
-#define _syscall0(type,name) \
-type name(void) \
-{ \
- __syscall_nr(0, type, name); \
-}
-
-#define _syscall1(type,name,type1,arg1) \
-type name(type1 arg1) \
-{ \
- __syscall_nr(1, type, name, arg1); \
-}
-
-#define _syscall2(type,name,type1,arg1,type2,arg2) \
-type name(type1 arg1, type2 arg2) \
-{ \
- __syscall_nr(2, type, name, arg1, arg2); \
-}
-
-#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
-type name(type1 arg1, type2 arg2, type3 arg3) \
-{ \
- __syscall_nr(3, type, name, arg1, arg2, arg3); \
-}
-
-#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
-{ \
- __syscall_nr(4, type, name, arg1, arg2, arg3, arg4); \
-}
-
-#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
-{ \
- __syscall_nr(5, type, name, arg1, arg2, arg3, arg4, arg5); \
-}
-#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \
-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \
-{ \
- __syscall_nr(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6); \
-}
-
-#ifdef __KERNEL_SYSCALLS__
-
-/*
- * Forking from kernel space will result in the child getting a new,
- * empty kernel stack area. Thus the child cannot access automatic
- * variables set in the parent unless they are in registers, and the
- * procedure where the fork was done cannot return to its caller in
- * the child.
- */
-
-/*
- * System call prototypes.
- */
-static inline _syscall3(int, execve, __const__ char *, file, char **, argv,
- char **,envp)
-
-#endif /* __KERNEL_SYSCALLS__ */
-
-#ifdef __KERNEL__
-
-#include <linux/types.h>
-#include <linux/compiler.h>
-#include <linux/linkage.h>
-
-#define __ARCH_WANT_IPC_PARSE_VERSION
-#define __ARCH_WANT_OLD_READDIR
-#define __ARCH_WANT_STAT64
-#define __ARCH_WANT_SYS_ALARM
-#define __ARCH_WANT_SYS_GETHOSTNAME
-#define __ARCH_WANT_SYS_PAUSE
-#define __ARCH_WANT_SYS_SGETMASK
-#define __ARCH_WANT_SYS_SIGNAL
-#define __ARCH_WANT_SYS_TIME
-#define __ARCH_WANT_COMPAT_SYS_TIME
-#define __ARCH_WANT_SYS_UTIME
-#define __ARCH_WANT_SYS_WAITPID
-#define __ARCH_WANT_SYS_SOCKETCALL
-#define __ARCH_WANT_SYS_FADVISE64
-#define __ARCH_WANT_SYS_GETPGRP
-#define __ARCH_WANT_SYS_LLSEEK
-#define __ARCH_WANT_SYS_NICE
-#define __ARCH_WANT_SYS_OLD_GETRLIMIT
-#define __ARCH_WANT_SYS_OLDUMOUNT
-#define __ARCH_WANT_SYS_SIGPENDING
-#define __ARCH_WANT_SYS_SIGPROCMASK
-#define __ARCH_WANT_SYS_RT_SIGACTION
-
-unsigned long sys_mmap(unsigned long addr, size_t len, unsigned long prot,
- unsigned long flags, unsigned long fd, off_t offset);
-struct pt_regs;
-int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
- unsigned long a3, unsigned long a4, unsigned long a5,
- struct pt_regs *regs);
-int sys_clone(unsigned long clone_flags, unsigned long p2, unsigned long p3,
- unsigned long p4, unsigned long p5, unsigned long p6,
- struct pt_regs *regs);
-int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3,
- unsigned long p4, unsigned long p5, unsigned long p6,
- struct pt_regs *regs);
-int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,
- unsigned long p4, unsigned long p5, unsigned long p6,
- struct pt_regs *regs);
-int sys_pipe(int __user *fildes);
-int sys_ptrace(long request, long pid, long addr, long data);
-struct sigaction;
-long sys_rt_sigaction(int sig, const struct sigaction __user *act,
- struct sigaction __user *oact, size_t sigsetsize);
-
-/*
- * "Conditional" syscalls
- *
- * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
- * but it doesn't work on all toolchains, so we just do it by hand
- */
-#define cond_syscall(x) asm(".weak\t." #x "\n\t.set\t." #x ",.sys_ni_syscall")
-
-#endif /* __KERNEL__ */
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* _ASM_PPC_UNISTD_H_ */
diff --git a/include/asm-s390/rwsem.h b/include/asm-s390/rwsem.h
index 8c0cebbfc034..0422a085dd56 100644
--- a/include/asm-s390/rwsem.h
+++ b/include/asm-s390/rwsem.h
@@ -351,5 +351,10 @@ static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem)
return new;
}
+static inline int rwsem_is_locked(struct rw_semaphore *sem)
+{
+ return (sem->count != 0);
+}
+
#endif /* __KERNEL__ */
#endif /* _S390_RWSEM_H */
diff --git a/include/asm-s390/semaphore.h b/include/asm-s390/semaphore.h
index 873def6f363a..702cf436698c 100644
--- a/include/asm-s390/semaphore.h
+++ b/include/asm-s390/semaphore.h
@@ -29,9 +29,6 @@ struct semaphore {
#define __SEMAPHORE_INITIALIZER(name,count) \
{ ATOMIC_INIT(count), __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) }
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/asm-s390/setup.h b/include/asm-s390/setup.h
index 0d51c484c2ea..348a88137445 100644
--- a/include/asm-s390/setup.h
+++ b/include/asm-s390/setup.h
@@ -8,11 +8,14 @@
#ifndef _ASM_S390_SETUP_H
#define _ASM_S390_SETUP_H
+#include <asm/types.h>
+
#define PARMAREA 0x10400
#define COMMAND_LINE_SIZE 896
#define RAMDISK_ORIGIN 0x800000
#define RAMDISK_SIZE 0x800000
#define MEMORY_CHUNKS 16 /* max 0x7fff */
+#define IPL_PARMBLOCK_ORIGIN 0x2000
#ifndef __ASSEMBLY__
@@ -64,6 +67,53 @@ extern unsigned int console_irq;
#define SET_CONSOLE_3215 do { console_mode = 2; } while (0)
#define SET_CONSOLE_3270 do { console_mode = 3; } while (0)
+struct ipl_list_header {
+ u32 length;
+ u8 reserved[3];
+ u8 version;
+} __attribute__((packed));
+
+struct ipl_block_fcp {
+ u32 length;
+ u8 pbt;
+ u8 reserved1[322-1];
+ u16 devno;
+ u8 reserved2[4];
+ u64 wwpn;
+ u64 lun;
+ u32 bootprog;
+ u8 reserved3[12];
+ u64 br_lba;
+ u32 scp_data_len;
+ u8 reserved4[260];
+ u8 scp_data[];
+} __attribute__((packed));
+
+struct ipl_parameter_block {
+ union {
+ u32 length;
+ struct ipl_list_header header;
+ } hdr;
+ struct ipl_block_fcp fcp;
+} __attribute__((packed));
+
+#define IPL_MAX_SUPPORTED_VERSION (0)
+
+#define IPL_TYPE_FCP (0)
+
+/*
+ * IPL validity flags and parameters as detected in head.S
+ */
+extern u32 ipl_parameter_flags;
+extern u16 ipl_devno;
+
+#define IPL_DEVNO_VALID (ipl_parameter_flags & 1)
+#define IPL_PARMBLOCK_VALID (ipl_parameter_flags & 2)
+
+#define IPL_PARMBLOCK_START ((struct ipl_parameter_block *) \
+ IPL_PARMBLOCK_ORIGIN)
+#define IPL_PARMBLOCK_SIZE (IPL_PARMBLOCK_START->hdr.length)
+
#else
#ifndef __s390x__
diff --git a/include/asm-s390/unistd.h b/include/asm-s390/unistd.h
index 221e965da924..f97d92691f17 100644
--- a/include/asm-s390/unistd.h
+++ b/include/asm-s390/unistd.h
@@ -590,7 +590,6 @@ asmlinkage long sys_clone(struct pt_regs regs);
asmlinkage long sys_fork(struct pt_regs regs);
asmlinkage long sys_vfork(struct pt_regs regs);
asmlinkage long sys_pipe(unsigned long __user *fildes);
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
diff --git a/include/asm-sh/pgtable.h b/include/asm-sh/pgtable.h
index 0f4bcaae61bd..aef8ae43de13 100644
--- a/include/asm-sh/pgtable.h
+++ b/include/asm-sh/pgtable.h
@@ -224,8 +224,6 @@ static inline pgprot_t pgprot_noncached(pgprot_t _prot)
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{ set_pte(&pte, __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot))); return pte; }
-#define page_pte(page) page_pte_prot(page, __pgprot(0))
-
#define pmd_page_kernel(pmd) \
((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
diff --git a/include/asm-sh/rwsem.h b/include/asm-sh/rwsem.h
index 1be4337f5259..0262d3d1e5e0 100644
--- a/include/asm-sh/rwsem.h
+++ b/include/asm-sh/rwsem.h
@@ -166,5 +166,10 @@ static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
return atomic_add_return(delta, (atomic_t *)(&sem->count));
}
+static inline int rwsem_is_locked(struct rw_semaphore *sem)
+{
+ return (sem->count != 0);
+}
+
#endif /* __KERNEL__ */
#endif /* _ASM_SH_RWSEM_H */
diff --git a/include/asm-sh/semaphore.h b/include/asm-sh/semaphore.h
index b923a77a8a7e..489f7847c5d9 100644
--- a/include/asm-sh/semaphore.h
+++ b/include/asm-sh/semaphore.h
@@ -33,9 +33,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/asm-sh/unistd.h b/include/asm-sh/unistd.h
index ea89e8f223ea..f2c8e14d1fd9 100644
--- a/include/asm-sh/unistd.h
+++ b/include/asm-sh/unistd.h
@@ -503,7 +503,6 @@ asmlinkage int sys_vfork(unsigned long r4, unsigned long r5,
asmlinkage int sys_pipe(unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7,
struct pt_regs regs);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
asmlinkage ssize_t sys_pread_wrapper(unsigned int fd, char *buf,
size_t count, long dummy, loff_t pos);
asmlinkage ssize_t sys_pwrite_wrapper(unsigned int fd, const char *buf,
diff --git a/include/asm-sh64/pgtable.h b/include/asm-sh64/pgtable.h
index 51db4307bfaf..51b05818e4eb 100644
--- a/include/asm-sh64/pgtable.h
+++ b/include/asm-sh64/pgtable.h
@@ -457,9 +457,6 @@ extern inline pte_t pte_mkhuge(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _
extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{ set_pte(&pte, __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot))); return pte; }
-#define page_pte_prot(page, prot) mk_pte(page, prot)
-#define page_pte(page) page_pte_prot(page, __pgprot(0))
-
typedef pte_t *pte_addr_t;
#define pgtable_cache_init() do { } while (0)
diff --git a/include/asm-sh64/semaphore.h b/include/asm-sh64/semaphore.h
index fce22bb9a546..469526459149 100644
--- a/include/asm-sh64/semaphore.h
+++ b/include/asm-sh64/semaphore.h
@@ -40,9 +40,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/asm-sparc/floppy.h b/include/asm-sparc/floppy.h
index caf926116506..7a941b800b6b 100644
--- a/include/asm-sparc/floppy.h
+++ b/include/asm-sparc/floppy.h
@@ -17,10 +17,8 @@
/* We don't need no stinkin' I/O port allocation crap. */
#undef release_region
-#undef check_region
#undef request_region
#define release_region(X, Y) do { } while(0)
-#define check_region(X, Y) (0)
#define request_region(X, Y, Z) (1)
/* References:
diff --git a/include/asm-sparc/pgtable.h b/include/asm-sparc/pgtable.h
index a14e98677500..b33c35411e82 100644
--- a/include/asm-sparc/pgtable.h
+++ b/include/asm-sparc/pgtable.h
@@ -255,8 +255,6 @@ BTFIXUPDEF_CALL_CONST(pte_t, pte_mkyoung, pte_t)
#define pte_mkdirty(pte) BTFIXUP_CALL(pte_mkdirty)(pte)
#define pte_mkyoung(pte) BTFIXUP_CALL(pte_mkyoung)(pte)
-#define page_pte_prot(page, prot) mk_pte(page, prot)
-#define page_pte(page) mk_pte(page, __pgprot(0))
#define pfn_pte(pfn, prot) mk_pte(pfn_to_page(pfn), prot)
BTFIXUPDEF_CALL(unsigned long, pte_pfn, pte_t)
diff --git a/include/asm-sparc/semaphore.h b/include/asm-sparc/semaphore.h
index 60ac5fd9eb48..f74ba31e265b 100644
--- a/include/asm-sparc/semaphore.h
+++ b/include/asm-sparc/semaphore.h
@@ -22,9 +22,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h
index 8c6dfc6c7af6..9a02879b235d 100644
--- a/include/asm-sparc64/pgtable.h
+++ b/include/asm-sparc64/pgtable.h
@@ -231,9 +231,6 @@ extern struct page *mem_map_zero;
#define pte_pfn(x) ((pte_val(x) & _PAGE_PADDR)>>PAGE_SHIFT)
#define pte_page(x) pfn_to_page(pte_pfn(x))
-#define page_pte_prot(page, prot) mk_pte(page, prot)
-#define page_pte(page) page_pte_prot(page, __pgprot(0))
-
static inline pte_t pte_modify(pte_t orig_pte, pgprot_t new_prot)
{
pte_t __pte;
diff --git a/include/asm-sparc64/rwsem.h b/include/asm-sparc64/rwsem.h
index 4568ee4022df..cef5e8270421 100644
--- a/include/asm-sparc64/rwsem.h
+++ b/include/asm-sparc64/rwsem.h
@@ -56,6 +56,11 @@ static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
atomic_add(delta, (atomic_t *)(&sem->count));
}
+static inline int rwsem_is_locked(struct rw_semaphore *sem)
+{
+ return (sem->count != 0);
+}
+
#endif /* __KERNEL__ */
#endif /* _SPARC64_RWSEM_H */
diff --git a/include/asm-sparc64/semaphore.h b/include/asm-sparc64/semaphore.h
index 7419dd88b49e..093dcc6788db 100644
--- a/include/asm-sparc64/semaphore.h
+++ b/include/asm-sparc64/semaphore.h
@@ -22,9 +22,6 @@ struct semaphore {
{ ATOMIC_INIT(count), \
__WAIT_QUEUE_HEAD_INITIALIZER((name).wait) }
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name, 1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name, count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/asm-sparc64/tlb.h b/include/asm-sparc64/tlb.h
index 9baf57db01d2..66138d959df5 100644
--- a/include/asm-sparc64/tlb.h
+++ b/include/asm-sparc64/tlb.h
@@ -25,9 +25,8 @@ struct mmu_gather {
struct mm_struct *mm;
unsigned int pages_nr;
unsigned int need_flush;
- unsigned int tlb_frozen;
+ unsigned int fullmm;
unsigned int tlb_nr;
- unsigned long freed;
unsigned long vaddrs[TLB_BATCH_NR];
struct page *pages[FREE_PTE_NR];
};
@@ -44,14 +43,13 @@ extern void flush_tlb_pending(void);
static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
{
- struct mmu_gather *mp = &__get_cpu_var(mmu_gathers);
+ struct mmu_gather *mp = &get_cpu_var(mmu_gathers);
BUG_ON(mp->tlb_nr);
mp->mm = mm;
mp->pages_nr = num_online_cpus() > 1 ? 0U : ~0U;
- mp->tlb_frozen = full_mm_flush;
- mp->freed = 0;
+ mp->fullmm = full_mm_flush;
return mp;
}
@@ -78,30 +76,19 @@ extern void smp_flush_tlb_mm(struct mm_struct *mm);
static inline void tlb_finish_mmu(struct mmu_gather *mp, unsigned long start, unsigned long end)
{
- unsigned long freed = mp->freed;
- struct mm_struct *mm = mp->mm;
- unsigned long rss = get_mm_counter(mm, rss);
-
- if (rss < freed)
- freed = rss;
- add_mm_counter(mm, rss, -freed);
-
tlb_flush_mmu(mp);
- if (mp->tlb_frozen) {
- if (CTX_VALID(mm->context))
- do_flush_tlb_mm(mm);
- mp->tlb_frozen = 0;
+ if (mp->fullmm) {
+ if (CTX_VALID(mp->mm->context))
+ do_flush_tlb_mm(mp->mm);
+ mp->fullmm = 0;
} else
flush_tlb_pending();
/* keep the page table cache within bounds */
check_pgt_cache();
-}
-static inline unsigned int tlb_is_full_mm(struct mmu_gather *mp)
-{
- return mp->tlb_frozen;
+ put_cpu_var(mmu_gathers);
}
static inline void tlb_remove_page(struct mmu_gather *mp, struct page *page)
diff --git a/include/asm-um/cache.h b/include/asm-um/cache.h
index 4b134fe8504e..a10602a5b2d6 100644
--- a/include/asm-um/cache.h
+++ b/include/asm-um/cache.h
@@ -1,10 +1,21 @@
#ifndef __UM_CACHE_H
#define __UM_CACHE_H
-/* These are x86 numbers */
-#define L1_CACHE_SHIFT 5
-#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
+#include <linux/config.h>
-#define L1_CACHE_SHIFT_MAX 7 /* largest L1 which this arch supports */
+#if defined(CONFIG_UML_X86) && !defined(CONFIG_64BIT)
+# define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT)
+#elif defined(CONFIG_UML_X86) /* 64-bit */
+# define L1_CACHE_SHIFT 6 /* Should be 7 on Intel */
+#else
+/* XXX: this was taken from x86, now it's completely random. Luckily only
+ * affects SMP padding. */
+# define L1_CACHE_SHIFT 5
+#endif
+
+/* XXX: this is valid for x86 and x86_64. */
+#define L1_CACHE_SHIFT_MAX 7 /* largest L1 which this arch supports */
+
+#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
#endif
diff --git a/include/asm-um/linkage.h b/include/asm-um/linkage.h
index 7dfce37adc8b..e3d62dcbd356 100644
--- a/include/asm-um/linkage.h
+++ b/include/asm-um/linkage.h
@@ -3,4 +3,12 @@
#include "asm/arch/linkage.h"
+#include <linux/config.h>
+
+/* <linux/linkage.h> will pick sane defaults */
+#ifdef CONFIG_GPROF
+#undef FASTCALL
+#undef fastcall
+#endif
+
#endif
diff --git a/include/asm-um/pgtable.h b/include/asm-um/pgtable.h
index 616d02b57ea9..ac64eb955868 100644
--- a/include/asm-um/pgtable.h
+++ b/include/asm-um/pgtable.h
@@ -138,7 +138,7 @@ extern unsigned long pg0[1024];
#define pte_clear(mm,addr,xp) pte_set_val(*(xp), (phys_t) 0, __pgprot(_PAGE_NEWPAGE))
-#define pmd_none(x) (!(pmd_val(x) & ~_PAGE_NEWPAGE))
+#define pmd_none(x) (!((unsigned long)pmd_val(x) & ~_PAGE_NEWPAGE))
#define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT)
#define pmd_clear(xp) do { pmd_val(*(xp)) = _PAGE_NEWPAGE; } while (0)
diff --git a/include/asm-v850/semaphore.h b/include/asm-v850/semaphore.h
index c514062bb69e..df6cdecf6c1f 100644
--- a/include/asm-v850/semaphore.h
+++ b/include/asm-v850/semaphore.h
@@ -18,9 +18,6 @@ struct semaphore {
{ ATOMIC_INIT (count), 0, \
__WAIT_QUEUE_HEAD_INITIALIZER ((name).wait) }
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER (name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER (name,count)
diff --git a/include/asm-v850/unistd.h b/include/asm-v850/unistd.h
index 3b552096c0e8..5a86f8e976ec 100644
--- a/include/asm-v850/unistd.h
+++ b/include/asm-v850/unistd.h
@@ -452,7 +452,6 @@ unsigned long sys_mmap2(unsigned long addr, size_t len,
struct pt_regs;
int sys_execve (char *name, char **argv, char **envp, struct pt_regs *regs);
int sys_pipe (int *fildes);
-int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
diff --git a/include/asm-x86_64/mtrr.h b/include/asm-x86_64/mtrr.h
index c5959d6418bb..66ac1c0f27e1 100644
--- a/include/asm-x86_64/mtrr.h
+++ b/include/asm-x86_64/mtrr.h
@@ -25,6 +25,7 @@
#include <linux/config.h>
#include <linux/ioctl.h>
+#include <linux/compat.h>
#define MTRR_IOCTL_BASE 'M'
@@ -105,4 +106,36 @@ static __inline__ int mtrr_del_page (int reg, unsigned long base,
#endif
+#ifdef CONFIG_COMPAT
+
+struct mtrr_sentry32
+{
+ compat_ulong_t base; /* Base address */
+ compat_uint_t size; /* Size of region */
+ compat_uint_t type; /* Type of region */
+};
+
+struct mtrr_gentry32
+{
+ compat_ulong_t regnum; /* Register number */
+ compat_uint_t base; /* Base address */
+ compat_uint_t size; /* Size of region */
+ compat_uint_t type; /* Type of region */
+};
+
+#define MTRR_IOCTL_BASE 'M'
+
+#define MTRRIOC32_ADD_ENTRY _IOW(MTRR_IOCTL_BASE, 0, struct mtrr_sentry32)
+#define MTRRIOC32_SET_ENTRY _IOW(MTRR_IOCTL_BASE, 1, struct mtrr_sentry32)
+#define MTRRIOC32_DEL_ENTRY _IOW(MTRR_IOCTL_BASE, 2, struct mtrr_sentry32)
+#define MTRRIOC32_GET_ENTRY _IOWR(MTRR_IOCTL_BASE, 3, struct mtrr_gentry32)
+#define MTRRIOC32_KILL_ENTRY _IOW(MTRR_IOCTL_BASE, 4, struct mtrr_sentry32)
+#define MTRRIOC32_ADD_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 5, struct mtrr_sentry32)
+#define MTRRIOC32_SET_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 6, struct mtrr_sentry32)
+#define MTRRIOC32_DEL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 7, struct mtrr_sentry32)
+#define MTRRIOC32_GET_PAGE_ENTRY _IOWR(MTRR_IOCTL_BASE, 8, struct mtrr_gentry32)
+#define MTRRIOC32_KILL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 9, struct mtrr_sentry32)
+
+#endif /* CONFIG_COMPAT */
+
#endif /* _LINUX_MTRR_H */
diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h
index dd8711ecaf2f..7a07196a7202 100644
--- a/include/asm-x86_64/pgtable.h
+++ b/include/asm-x86_64/pgtable.h
@@ -318,8 +318,6 @@ static inline int pmd_large(pmd_t pte) {
* and a page entry and page directory to the page they refer to.
*/
-#define page_pte(page) page_pte_prot(page, __pgprot(0))
-
/*
* Level 4 access.
*/
diff --git a/include/asm-x86_64/rwsem.h b/include/asm-x86_64/rwsem.h
index c002175b6e82..46077e9c1910 100644
--- a/include/asm-x86_64/rwsem.h
+++ b/include/asm-x86_64/rwsem.h
@@ -274,5 +274,10 @@ LOCK_PREFIX "xaddl %0,(%2)"
return tmp+delta;
}
+static inline int rwsem_is_locked(struct rw_semaphore *sem)
+{
+ return (sem->count != 0);
+}
+
#endif /* __KERNEL__ */
#endif /* _X8664_RWSEM_H */
diff --git a/include/asm-x86_64/semaphore.h b/include/asm-x86_64/semaphore.h
index f325e39bf3b9..a389aa6fe80f 100644
--- a/include/asm-x86_64/semaphore.h
+++ b/include/asm-x86_64/semaphore.h
@@ -56,9 +56,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h
index 11ba931cf82f..3c494b65d33a 100644
--- a/include/asm-x86_64/unistd.h
+++ b/include/asm-x86_64/unistd.h
@@ -780,8 +780,6 @@ asmlinkage long sys_pipe(int *fildes);
#include <linux/types.h>
#include <asm/ptrace.h>
-asmlinkage long sys_ptrace(long request, long pid,
- unsigned long addr, long data);
asmlinkage long sys_iopl(unsigned int level, struct pt_regs *regs);
asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on);
struct sigaction;
diff --git a/include/asm-xtensa/semaphore.h b/include/asm-xtensa/semaphore.h
index 09e89ab3eb61..2a10e193b929 100644
--- a/include/asm-xtensa/semaphore.h
+++ b/include/asm-xtensa/semaphore.h
@@ -29,9 +29,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name, 1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/keys/user-type.h b/include/keys/user-type.h
new file mode 100644
index 000000000000..26f6ec38577a
--- /dev/null
+++ b/include/keys/user-type.h
@@ -0,0 +1,47 @@
+/* user-type.h: User-defined key type
+ *
+ * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _KEYS_USER_TYPE_H
+#define _KEYS_USER_TYPE_H
+
+#include <linux/key.h>
+#include <linux/rcupdate.h>
+
+/*****************************************************************************/
+/*
+ * the payload for a key of type "user"
+ * - once filled in and attached to a key:
+ * - the payload struct is invariant may not be changed, only replaced
+ * - the payload must be read with RCU procedures or with the key semaphore
+ * held
+ * - the payload may only be replaced with the key semaphore write-locked
+ * - the key's data length is the size of the actual data, not including the
+ * payload wrapper
+ */
+struct user_key_payload {
+ struct rcu_head rcu; /* RCU destructor */
+ unsigned short datalen; /* length of this data */
+ char data[0]; /* actual data */
+};
+
+extern struct key_type key_type_user;
+
+extern int user_instantiate(struct key *key, const void *data, size_t datalen);
+extern int user_duplicate(struct key *key, const struct key *source);
+extern int user_update(struct key *key, const void *data, size_t datalen);
+extern int user_match(const struct key *key, const void *criterion);
+extern void user_destroy(struct key *key);
+extern void user_describe(const struct key *user, struct seq_file *m);
+extern long user_read(const struct key *key,
+ char __user *buffer, size_t buflen);
+
+
+#endif /* _KEYS_USER_TYPE_H */
diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index 86dd5502b05c..7d8ff97b3e92 100644
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h
@@ -40,6 +40,8 @@
* bitmap_weight(src, nbits) Hamming Weight: number set bits
* bitmap_shift_right(dst, src, n, nbits) *dst = *src >> n
* bitmap_shift_left(dst, src, n, nbits) *dst = *src << n
+ * bitmap_remap(dst, src, old, new, nbits) *dst = map(old, new)(src)
+ * bitmap_bitremap(oldbit, old, new, nbits) newbit = map(old, new)(oldbit)
* bitmap_scnprintf(buf, len, src, nbits) Print bitmap src to buf
* bitmap_parse(ubuf, ulen, dst, nbits) Parse bitmap dst from user buf
* bitmap_scnlistprintf(buf, len, src, nbits) Print bitmap src as list to buf
@@ -104,6 +106,10 @@ extern int bitmap_scnlistprintf(char *buf, unsigned int len,
const unsigned long *src, int nbits);
extern int bitmap_parselist(const char *buf, unsigned long *maskp,
int nmaskbits);
+extern void bitmap_remap(unsigned long *dst, const unsigned long *src,
+ const unsigned long *old, const unsigned long *new, int bits);
+extern int bitmap_bitremap(int oldbit,
+ const unsigned long *old, const unsigned long *new, int bits);
extern int bitmap_find_free_region(unsigned long *bitmap, int bits, int order);
extern void bitmap_release_region(unsigned long *bitmap, int pos, int order);
extern int bitmap_allocate_region(unsigned long *bitmap, int pos, int order);
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 88af42f5e04a..1db061bb6b08 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -126,8 +126,8 @@ BUFFER_FNS(Eopnotsupp, eopnotsupp)
/* If we *know* page->private refers to buffer_heads */
#define page_buffers(page) \
({ \
- BUG_ON(!PagePrivate(page)); \
- ((struct buffer_head *)(page)->private); \
+ BUG_ON(!PagePrivate(page)); \
+ ((struct buffer_head *)page_private(page)); \
})
#define page_has_buffers(page) PagePrivate(page)
@@ -190,6 +190,7 @@ extern int buffer_heads_over_limit;
*/
int try_to_release_page(struct page * page, gfp_t gfp_mask);
int block_invalidatepage(struct page *page, unsigned long offset);
+int do_invalidatepage(struct page *page, unsigned long offset);
int block_write_full_page(struct page *page, get_block_t *get_block,
struct writeback_control *wbc);
int block_read_full_page(struct page*, get_block_t*);
@@ -219,7 +220,7 @@ static inline void attach_page_buffers(struct page *page,
{
page_cache_get(page);
SetPagePrivate(page);
- page->private = (unsigned long)head;
+ set_page_private(page, (unsigned long)head);
}
static inline void get_bh(struct buffer_head *bh)
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 86980c68234a..1f7b2c097503 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -32,6 +32,7 @@ struct cpu {
};
extern int register_cpu(struct cpu *, int, struct node *);
+extern struct sys_device *get_cpu_sysdev(int cpu);
#ifdef CONFIG_HOTPLUG_CPU
extern void unregister_cpu(struct cpu *, struct node *);
#endif
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index ff7f80f48df1..d068176b7ad7 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -23,6 +23,7 @@
#include <linux/completion.h>
#include <linux/workqueue.h>
#include <linux/cpumask.h>
+#include <asm/div64.h>
#define CPUFREQ_NAME_LEN 16
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
index 9bdba8169b41..13e9f4a3ab26 100644
--- a/include/linux/cpumask.h
+++ b/include/linux/cpumask.h
@@ -12,6 +12,8 @@
* see bitmap_scnprintf() and bitmap_parse() in lib/bitmap.c.
* For details of cpulist_scnprintf() and cpulist_parse(), see
* bitmap_scnlistprintf() and bitmap_parselist(), also in bitmap.c.
+ * For details of cpu_remap(), see bitmap_bitremap in lib/bitmap.c
+ * For details of cpus_remap(), see bitmap_remap in lib/bitmap.c.
*
* The available cpumask operations are:
*
@@ -50,6 +52,8 @@
* int cpumask_parse(ubuf, ulen, mask) Parse ascii string as cpumask
* int cpulist_scnprintf(buf, len, mask) Format cpumask as list for printing
* int cpulist_parse(buf, map) Parse ascii string as cpulist
+ * int cpu_remap(oldbit, old, new) newbit = map(old, new)(oldbit)
+ * int cpus_remap(dst, src, old, new) *dst = map(old, new)(src)
*
* for_each_cpu_mask(cpu, mask) for-loop cpu over mask
*
@@ -294,6 +298,22 @@ static inline int __cpulist_parse(const char *buf, cpumask_t *dstp, int nbits)
return bitmap_parselist(buf, dstp->bits, nbits);
}
+#define cpu_remap(oldbit, old, new) \
+ __cpu_remap((oldbit), &(old), &(new), NR_CPUS)
+static inline int __cpu_remap(int oldbit,
+ const cpumask_t *oldp, const cpumask_t *newp, int nbits)
+{
+ return bitmap_bitremap(oldbit, oldp->bits, newp->bits, nbits);
+}
+
+#define cpus_remap(dst, src, old, new) \
+ __cpus_remap(&(dst), &(src), &(old), &(new), NR_CPUS)
+static inline void __cpus_remap(cpumask_t *dstp, const cpumask_t *srcp,
+ const cpumask_t *oldp, const cpumask_t *newp, int nbits)
+{
+ bitmap_remap(dstp->bits, srcp->bits, oldp->bits, newp->bits, nbits);
+}
+
#if NR_CPUS > 1
#define for_each_cpu_mask(cpu, mask) \
for ((cpu) = first_cpu(mask); \
diff --git a/include/linux/dmi.h b/include/linux/dmi.h
index a415f1d93e9a..05f4132622fc 100644
--- a/include/linux/dmi.h
+++ b/include/linux/dmi.h
@@ -60,7 +60,7 @@ struct dmi_device {
void *device_data; /* Type specific data */
};
-#if defined(CONFIG_X86) && !defined(CONFIG_X86_64)
+#if defined(CONFIG_X86_32)
extern int dmi_check_system(struct dmi_system_id *list);
extern char * dmi_get_system_info(int field);
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
index 4522c7186bf3..cc84934f9059 100644
--- a/include/linux/etherdevice.h
+++ b/include/linux/etherdevice.h
@@ -104,6 +104,22 @@ static inline void random_ether_addr(u8 *addr)
addr [0] &= 0xfe; /* clear multicast bit */
addr [0] |= 0x02; /* set local assignment bit (IEEE802) */
}
+
+/**
+ * compare_ether_addr - Compare two Ethernet addresses
+ * @addr1: Pointer to a six-byte array containing the Ethernet address
+ * @addr2 Pointer other six-byte array containing the Ethernet address
+ *
+ * Compare two ethernet addresses, returns 0 if equal
+ */
+static inline unsigned compare_ether_addr(const u8 *_a, const u8 *_b)
+{
+ const u16 *a = (const u16 *) _a;
+ const u16 *b = (const u16 *) _b;
+
+ BUILD_BUG_ON(ETH_ALEN != 6);
+ return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) != 0;
+}
#endif /* __KERNEL__ */
#endif /* _LINUX_ETHERDEVICE_H */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index f83d997c5582..6d6226732c93 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -574,7 +574,14 @@ struct file_ra_state {
#define RA_FLAG_INCACHE 0x02 /* file is already in cache */
struct file {
- struct list_head f_list;
+ /*
+ * fu_list becomes invalid after file_free is called and queued via
+ * fu_rcuhead for RCU freeing
+ */
+ union {
+ struct list_head fu_list;
+ struct rcu_head fu_rcuhead;
+ } f_u;
struct dentry *f_dentry;
struct vfsmount *f_vfsmnt;
struct file_operations *f_op;
@@ -598,7 +605,6 @@ struct file {
spinlock_t f_ep_lock;
#endif /* #ifdef CONFIG_EPOLL */
struct address_space *f_mapping;
- struct rcu_head f_rcuhead;
};
extern spinlock_t files_lock;
#define file_list_lock() spin_lock(&files_lock);
diff --git a/include/linux/fs_enet_pd.h b/include/linux/fs_enet_pd.h
new file mode 100644
index 000000000000..bef23bbf8690
--- /dev/null
+++ b/include/linux/fs_enet_pd.h
@@ -0,0 +1,136 @@
+/*
+ * Platform information definitions for the
+ * universal Freescale Ethernet driver.
+ *
+ * Copyright (c) 2003 Intracom S.A.
+ * by Pantelis Antoniou <panto@intracom.gr>
+ *
+ * 2005 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#ifndef FS_ENET_PD_H
+#define FS_ENET_PD_H
+
+#include <linux/version.h>
+#include <asm/types.h>
+
+#define FS_ENET_NAME "fs_enet"
+
+enum fs_id {
+ fsid_fec1,
+ fsid_fec2,
+ fsid_fcc1,
+ fsid_fcc2,
+ fsid_fcc3,
+ fsid_scc1,
+ fsid_scc2,
+ fsid_scc3,
+ fsid_scc4,
+};
+
+#define FS_MAX_INDEX 9
+
+static inline int fs_get_fec_index(enum fs_id id)
+{
+ if (id >= fsid_fec1 && id <= fsid_fec2)
+ return id - fsid_fec1;
+ return -1;
+}
+
+static inline int fs_get_fcc_index(enum fs_id id)
+{
+ if (id >= fsid_fcc1 && id <= fsid_fcc3)
+ return id - fsid_fcc1;
+ return -1;
+}
+
+static inline int fs_get_scc_index(enum fs_id id)
+{
+ if (id >= fsid_scc1 && id <= fsid_scc4)
+ return id - fsid_scc1;
+ return -1;
+}
+
+enum fs_mii_method {
+ fsmii_fixed,
+ fsmii_fec,
+ fsmii_bitbang,
+};
+
+enum fs_ioport {
+ fsiop_porta,
+ fsiop_portb,
+ fsiop_portc,
+ fsiop_portd,
+ fsiop_porte,
+};
+
+struct fs_mii_bus_info {
+ int method; /* mii method */
+ int id; /* the id of the mii_bus */
+ int disable_aneg; /* if the controller needs to negothiate speed & duplex */
+ int lpa; /* the default board-specific vallues will be applied otherwise */
+
+ union {
+ struct {
+ int duplex;
+ int speed;
+ } fixed;
+
+ struct {
+ /* nothing */
+ } fec;
+
+ struct {
+ /* nothing */
+ } scc;
+
+ struct {
+ int mdio_port; /* port & bit for MDIO */
+ int mdio_bit;
+ int mdc_port; /* port & bit for MDC */
+ int mdc_bit;
+ int delay; /* delay in us */
+ } bitbang;
+ } i;
+};
+
+struct fs_platform_info {
+
+ void(*init_ioports)(void);
+ /* device specific information */
+ int fs_no; /* controller index */
+
+ u32 cp_page; /* CPM page */
+ u32 cp_block; /* CPM sblock */
+
+ u32 clk_trx; /* some stuff for pins & mux configuration*/
+ u32 clk_route;
+ u32 clk_mask;
+
+ u32 mem_offset;
+ u32 dpram_offset;
+ u32 fcc_regs_c;
+
+ u32 device_flags;
+
+ int phy_addr; /* the phy address (-1 no phy) */
+ int phy_irq; /* the phy irq (if it exists) */
+
+ const struct fs_mii_bus_info *bus_info;
+
+ int rx_ring, tx_ring; /* number of buffers on rx */
+ __u8 macaddr[6]; /* mac address */
+ int rx_copybreak; /* limit we copy small frames */
+ int use_napi; /* use NAPI */
+ int napi_weight; /* NAPI weight */
+
+ int use_rmii; /* use RMII mode */
+};
+
+#endif
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
index 70f54af87b9f..114d5d59f695 100644
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -47,16 +47,21 @@
struct gianfar_platform_data {
/* device specific information */
u32 device_flags;
- u32 phy_reg_addr;
/* board specific information */
u32 board_flags;
- u32 phy_flags;
- u32 phyid;
- u32 interruptPHY;
+ const char *bus_id;
u8 mac_addr[6];
};
+struct gianfar_mdio_data {
+ /* device specific information */
+ u32 paddr;
+
+ /* board specific information */
+ int irq[32];
+};
+
/* Flags related to gianfar device features */
#define FSL_GIANFAR_DEV_HAS_GIGABIT 0x00000001
#define FSL_GIANFAR_DEV_HAS_COALESCE 0x00000002
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
index acbeb96a3353..f98854c2abd7 100644
--- a/include/linux/fuse.h
+++ b/include/linux/fuse.h
@@ -61,7 +61,6 @@ struct fuse_kstatfs {
#define FATTR_SIZE (1 << 3)
#define FATTR_ATIME (1 << 4)
#define FATTR_MTIME (1 << 5)
-#define FATTR_CTIME (1 << 6)
/**
* Flags returned by the OPEN request
diff --git a/include/linux/gameport.h b/include/linux/gameport.h
index cd623eccdbea..2401dea2b867 100644
--- a/include/linux/gameport.h
+++ b/include/linux/gameport.h
@@ -12,6 +12,7 @@
#include <asm/io.h>
#include <linux/list.h>
#include <linux/device.h>
+#include <linux/timer.h>
struct gameport {
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index d664330d900e..0cea162b08c0 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -16,7 +16,6 @@ static inline int is_vm_hugetlb_page(struct vm_area_struct *vma)
int hugetlb_sysctl_handler(struct ctl_table *, int, struct file *, void __user *, size_t *, loff_t *);
int copy_hugetlb_page_range(struct mm_struct *, struct mm_struct *, struct vm_area_struct *);
int follow_hugetlb_page(struct mm_struct *, struct vm_area_struct *, struct page **, struct vm_area_struct **, unsigned long *, int *, int);
-void zap_hugepage_range(struct vm_area_struct *, unsigned long, unsigned long);
void unmap_hugepage_range(struct vm_area_struct *, unsigned long, unsigned long);
int hugetlb_prefault(struct address_space *, struct vm_area_struct *);
int hugetlb_report_meminfo(char *);
@@ -87,7 +86,6 @@ static inline unsigned long hugetlb_total_pages(void)
#define follow_huge_addr(mm, addr, write) ERR_PTR(-EINVAL)
#define copy_hugetlb_page_range(src, dst, vma) ({ BUG(); 0; })
#define hugetlb_prefault(mapping, vma) ({ BUG(); 0; })
-#define zap_hugepage_range(vma, start, len) BUG()
#define unmap_hugepage_range(vma, start, end) BUG()
#define is_hugepage_mem_enough(size) 0
#define hugetlb_report_meminfo(buf) 0
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index f88577ca3b3a..5e19a7ba69b2 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -31,6 +31,7 @@
#include <linux/i2c-id.h>
#include <linux/mod_devicetable.h>
#include <linux/device.h> /* for struct device */
+#include <linux/sched.h> /* for completion */
#include <asm/semaphore.h>
/* --- For i2c-isa ---------------------------------------------------- */
diff --git a/include/linux/i2o.h b/include/linux/i2o.h
index 92300325dbcd..d79c8a4bc4f8 100644
--- a/include/linux/i2o.h
+++ b/include/linux/i2o.h
@@ -25,10 +25,14 @@
/* How many different OSM's are we allowing */
#define I2O_MAX_DRIVERS 8
-#include <asm/io.h>
-#include <asm/semaphore.h> /* Needed for MUTEX init macros */
#include <linux/pci.h>
#include <linux/dma-mapping.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h> /* work_struct */
+
+#include <asm/io.h>
+#include <asm/semaphore.h> /* Needed for MUTEX init macros */
/* message queue empty */
#define I2O_QUEUE_EMPTY 0xffffffff
diff --git a/include/linux/ide.h b/include/linux/ide.h
index a6dbb51ecd7b..3461abc1e854 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -218,7 +218,7 @@ typedef enum { ide_unknown, ide_generic, ide_pci,
ide_rz1000, ide_trm290,
ide_cmd646, ide_cy82c693, ide_4drives,
ide_pmac, ide_etrax100, ide_acorn,
- ide_forced
+ ide_au1xxx, ide_forced
} hwif_chipset_t;
/*
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 4367ce4db52a..f1925ccc9fe1 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -307,7 +307,7 @@ struct sysinfo {
char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding: libc5 uses this.. */
};
-/* Force a compilation error if condition is false */
+/* Force a compilation error if condition is true */
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
#ifdef CONFIG_SYSCTL
diff --git a/include/linux/key-ui.h b/include/linux/key-ui.h
index 7a2e332067c3..e8b8a7a5c496 100644
--- a/include/linux/key-ui.h
+++ b/include/linux/key-ui.h
@@ -24,7 +24,8 @@ extern spinlock_t key_serial_lock;
#define KEY_WRITE 0x04 /* require permission to update / modify */
#define KEY_SEARCH 0x08 /* require permission to search (keyring) or find (key) */
#define KEY_LINK 0x10 /* require permission to link */
-#define KEY_ALL 0x1f /* all the above permissions */
+#define KEY_SETATTR 0x20 /* require permission to change attributes */
+#define KEY_ALL 0x3f /* all the above permissions */
/*
* the keyring payload contains a list of the keys to which the keyring is
diff --git a/include/linux/key.h b/include/linux/key.h
index f1efa016dbf3..53513a3be53b 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -40,28 +40,32 @@ struct key;
#define KEY_POS_WRITE 0x04000000 /* possessor can update key payload / add link to keyring */
#define KEY_POS_SEARCH 0x08000000 /* possessor can find a key in search / search a keyring */
#define KEY_POS_LINK 0x10000000 /* possessor can create a link to a key/keyring */
-#define KEY_POS_ALL 0x1f000000
+#define KEY_POS_SETATTR 0x20000000 /* possessor can set key attributes */
+#define KEY_POS_ALL 0x3f000000
#define KEY_USR_VIEW 0x00010000 /* user permissions... */
#define KEY_USR_READ 0x00020000
#define KEY_USR_WRITE 0x00040000
#define KEY_USR_SEARCH 0x00080000
#define KEY_USR_LINK 0x00100000
-#define KEY_USR_ALL 0x001f0000
+#define KEY_USR_SETATTR 0x00200000
+#define KEY_USR_ALL 0x003f0000
#define KEY_GRP_VIEW 0x00000100 /* group permissions... */
#define KEY_GRP_READ 0x00000200
#define KEY_GRP_WRITE 0x00000400
#define KEY_GRP_SEARCH 0x00000800
#define KEY_GRP_LINK 0x00001000
-#define KEY_GRP_ALL 0x00001f00
+#define KEY_GRP_SETATTR 0x00002000
+#define KEY_GRP_ALL 0x00003f00
#define KEY_OTH_VIEW 0x00000001 /* third party permissions... */
#define KEY_OTH_READ 0x00000002
#define KEY_OTH_WRITE 0x00000004
#define KEY_OTH_SEARCH 0x00000008
#define KEY_OTH_LINK 0x00000010
-#define KEY_OTH_ALL 0x0000001f
+#define KEY_OTH_SETATTR 0x00000020
+#define KEY_OTH_ALL 0x0000003f
struct seq_file;
struct user_struct;
@@ -119,6 +123,7 @@ struct key {
struct key_type *type; /* type of key */
struct rw_semaphore sem; /* change vs change sem */
struct key_user *user; /* owner of this key */
+ void *security; /* security data for this key */
time_t expiry; /* time at which key expires (or 0) */
uid_t uid;
gid_t gid;
diff --git a/include/linux/kobj_map.h b/include/linux/kobj_map.h
index b6cc10bf8dfc..cbe7d8008042 100644
--- a/include/linux/kobj_map.h
+++ b/include/linux/kobj_map.h
@@ -1,5 +1,7 @@
#ifdef __KERNEL__
+#include <asm/semaphore.h>
+
typedef struct kobject *kobj_probe_t(dev_t, int *, void *);
struct kobj_map;
diff --git a/include/linux/kthread.h b/include/linux/kthread.h
index 3fa786448db3..ebdd41fd1082 100644
--- a/include/linux/kthread.h
+++ b/include/linux/kthread.h
@@ -70,6 +70,18 @@ void kthread_bind(struct task_struct *k, unsigned int cpu);
int kthread_stop(struct task_struct *k);
/**
+ * kthread_stop_sem: stop a thread created by kthread_create().
+ * @k: thread created by kthread_create().
+ * @s: semaphore that @k waits on while idle.
+ *
+ * Does essentially the same thing as kthread_stop() above, but wakes
+ * @k by calling up(@s).
+ *
+ * Returns the result of threadfn(), or -EINTR if wake_up_process()
+ * was never called. */
+int kthread_stop_sem(struct task_struct *k, struct semaphore *s);
+
+/**
* kthread_should_stop: should this kthread return now?
*
* When someone calls kthread_stop on your kthread, it will be woken
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 00a8a5738858..0ba3af7a1236 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -172,6 +172,13 @@ enum hsm_task_states {
HSM_ST_ERR,
};
+enum ata_completion_errors {
+ AC_ERR_OTHER = (1 << 0),
+ AC_ERR_DEV = (1 << 1),
+ AC_ERR_ATA_BUS = (1 << 2),
+ AC_ERR_HOST_BUS = (1 << 3),
+};
+
/* forward declarations */
struct scsi_device;
struct ata_port_operations;
@@ -179,7 +186,7 @@ struct ata_port;
struct ata_queued_cmd;
/* typedefs */
-typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc, u8 drv_stat);
+typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc, unsigned int err_mask);
struct ata_ioports {
unsigned long cmd_addr;
@@ -347,7 +354,6 @@ struct ata_port_operations {
void (*exec_command)(struct ata_port *ap, const struct ata_taskfile *tf);
u8 (*check_status)(struct ata_port *ap);
u8 (*check_altstatus)(struct ata_port *ap);
- u8 (*check_err)(struct ata_port *ap);
void (*dev_select)(struct ata_port *ap, unsigned int device);
void (*phy_reset) (struct ata_port *ap);
@@ -434,7 +440,6 @@ extern void ata_noop_dev_select (struct ata_port *ap, unsigned int device);
extern void ata_std_dev_select (struct ata_port *ap, unsigned int device);
extern u8 ata_check_status(struct ata_port *ap);
extern u8 ata_altstatus(struct ata_port *ap);
-extern u8 ata_chk_err(struct ata_port *ap);
extern void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf);
extern int ata_port_start (struct ata_port *ap);
extern void ata_port_stop (struct ata_port *ap);
@@ -455,7 +460,7 @@ extern void ata_bmdma_start (struct ata_queued_cmd *qc);
extern void ata_bmdma_stop(struct ata_queued_cmd *qc);
extern u8 ata_bmdma_status(struct ata_port *ap);
extern void ata_bmdma_irq_clear(struct ata_port *ap);
-extern void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat);
+extern void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask);
extern void ata_eng_timeout(struct ata_port *ap);
extern void ata_scsi_simulate(u16 *id, struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *));
@@ -718,4 +723,21 @@ static inline int ata_try_flush_cache(const struct ata_device *dev)
ata_id_has_flush_ext(dev->id);
}
+static inline unsigned int ac_err_mask(u8 status)
+{
+ if (status & ATA_BUSY)
+ return AC_ERR_ATA_BUS;
+ if (status & (ATA_ERR | ATA_DF))
+ return AC_ERR_DEV;
+ return 0;
+}
+
+static inline unsigned int __ac_err_mask(u8 status)
+{
+ unsigned int mask = ac_err_mask(status);
+ if (mask == 0)
+ return AC_ERR_OTHER;
+ return mask;
+}
+
#endif /* __LINUX_LIBATA_H__ */
diff --git a/include/linux/memory.h b/include/linux/memory.h
new file mode 100644
index 000000000000..0def328ab5cf
--- /dev/null
+++ b/include/linux/memory.h
@@ -0,0 +1,94 @@
+/*
+ * include/linux/memory.h - generic memory definition
+ *
+ * This is mainly for topological representation. We define the
+ * basic "struct memory_block" here, which can be embedded in per-arch
+ * definitions or NUMA information.
+ *
+ * Basic handling of the devices is done in drivers/base/memory.c
+ * and system devices are handled in drivers/base/sys.c.
+ *
+ * Memory block are exported via sysfs in the class/memory/devices/
+ * directory.
+ *
+ */
+#ifndef _LINUX_MEMORY_H_
+#define _LINUX_MEMORY_H_
+
+#include <linux/sysdev.h>
+#include <linux/node.h>
+#include <linux/compiler.h>
+
+#include <asm/semaphore.h>
+
+struct memory_block {
+ unsigned long phys_index;
+ unsigned long state;
+ /*
+ * This serializes all state change requests. It isn't
+ * held during creation because the control files are
+ * created long after the critical areas during
+ * initialization.
+ */
+ struct semaphore state_sem;
+ int phys_device; /* to which fru does this belong? */
+ void *hw; /* optional pointer to fw/hw data */
+ int (*phys_callback)(struct memory_block *);
+ struct sys_device sysdev;
+};
+
+/* These states are exposed to userspace as text strings in sysfs */
+#define MEM_ONLINE (1<<0) /* exposed to userspace */
+#define MEM_GOING_OFFLINE (1<<1) /* exposed to userspace */
+#define MEM_OFFLINE (1<<2) /* exposed to userspace */
+
+/*
+ * All of these states are currently kernel-internal for notifying
+ * kernel components and architectures.
+ *
+ * For MEM_MAPPING_INVALID, all notifier chains with priority >0
+ * are called before pfn_to_page() becomes invalid. The priority=0
+ * entry is reserved for the function that actually makes
+ * pfn_to_page() stop working. Any notifiers that want to be called
+ * after that should have priority <0.
+ */
+#define MEM_MAPPING_INVALID (1<<3)
+
+#ifndef CONFIG_MEMORY_HOTPLUG
+static inline int memory_dev_init(void)
+{
+ return 0;
+}
+static inline int register_memory_notifier(struct notifier_block *nb)
+{
+ return 0;
+}
+static inline void unregister_memory_notifier(struct notifier_block *nb)
+{
+}
+#else
+extern int register_memory(struct memory_block *, struct mem_section *section, struct node *);
+extern int register_new_memory(struct mem_section *);
+extern int unregister_memory_section(struct mem_section *);
+extern int memory_dev_init(void);
+extern int register_memory_notifier(struct notifier_block *nb);
+extern void unregister_memory_notifier(struct notifier_block *nb);
+
+#define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT)
+
+extern int invalidate_phys_mapping(unsigned long, unsigned long);
+struct notifier_block;
+
+extern int register_memory_notifier(struct notifier_block *nb);
+extern void unregister_memory_notifier(struct notifier_block *nb);
+
+extern struct sysdev_class memory_sysdev_class;
+#endif /* CONFIG_MEMORY_HOTPLUG */
+
+#define hotplug_memory_notifier(fn, pri) { \
+ static struct notifier_block fn##_mem_nb = \
+ { .notifier_call = fn, .priority = pri }; \
+ register_memory_notifier(&fn##_mem_nb); \
+}
+
+#endif /* _LINUX_MEMORY_H_ */
diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
new file mode 100644
index 000000000000..01f03bc06eff
--- /dev/null
+++ b/include/linux/memory_hotplug.h
@@ -0,0 +1,104 @@
+#ifndef __LINUX_MEMORY_HOTPLUG_H
+#define __LINUX_MEMORY_HOTPLUG_H
+
+#include <linux/mmzone.h>
+#include <linux/spinlock.h>
+#include <linux/mmzone.h>
+#include <linux/notifier.h>
+
+#ifdef CONFIG_MEMORY_HOTPLUG
+/*
+ * pgdat resizing functions
+ */
+static inline
+void pgdat_resize_lock(struct pglist_data *pgdat, unsigned long *flags)
+{
+ spin_lock_irqsave(&pgdat->node_size_lock, *flags);
+}
+static inline
+void pgdat_resize_unlock(struct pglist_data *pgdat, unsigned long *flags)
+{
+ spin_unlock_irqrestore(&pgdat->node_size_lock, *flags);
+}
+static inline
+void pgdat_resize_init(struct pglist_data *pgdat)
+{
+ spin_lock_init(&pgdat->node_size_lock);
+}
+/*
+ * Zone resizing functions
+ */
+static inline unsigned zone_span_seqbegin(struct zone *zone)
+{
+ return read_seqbegin(&zone->span_seqlock);
+}
+static inline int zone_span_seqretry(struct zone *zone, unsigned iv)
+{
+ return read_seqretry(&zone->span_seqlock, iv);
+}
+static inline void zone_span_writelock(struct zone *zone)
+{
+ write_seqlock(&zone->span_seqlock);
+}
+static inline void zone_span_writeunlock(struct zone *zone)
+{
+ write_sequnlock(&zone->span_seqlock);
+}
+static inline void zone_seqlock_init(struct zone *zone)
+{
+ seqlock_init(&zone->span_seqlock);
+}
+extern int zone_grow_free_lists(struct zone *zone, unsigned long new_nr_pages);
+extern int zone_grow_waitqueues(struct zone *zone, unsigned long nr_pages);
+extern int add_one_highpage(struct page *page, int pfn, int bad_ppro);
+/* need some defines for these for archs that don't support it */
+extern void online_page(struct page *page);
+/* VM interface that may be used by firmware interface */
+extern int add_memory(u64 start, u64 size);
+extern int remove_memory(u64 start, u64 size);
+extern int online_pages(unsigned long, unsigned long);
+
+/* reasonably generic interface to expand the physical pages in a zone */
+extern int __add_pages(struct zone *zone, unsigned long start_pfn,
+ unsigned long nr_pages);
+#else /* ! CONFIG_MEMORY_HOTPLUG */
+/*
+ * Stub functions for when hotplug is off
+ */
+static inline void pgdat_resize_lock(struct pglist_data *p, unsigned long *f) {}
+static inline void pgdat_resize_unlock(struct pglist_data *p, unsigned long *f) {}
+static inline void pgdat_resize_init(struct pglist_data *pgdat) {}
+
+static inline unsigned zone_span_seqbegin(struct zone *zone)
+{
+ return 0;
+}
+static inline int zone_span_seqretry(struct zone *zone, unsigned iv)
+{
+ return 0;
+}
+static inline void zone_span_writelock(struct zone *zone) {}
+static inline void zone_span_writeunlock(struct zone *zone) {}
+static inline void zone_seqlock_init(struct zone *zone) {}
+
+static inline int mhp_notimplemented(const char *func)
+{
+ printk(KERN_WARNING "%s() called, with CONFIG_MEMORY_HOTPLUG disabled\n", func);
+ dump_stack();
+ return -ENOSYS;
+}
+
+static inline int __add_pages(struct zone *zone, unsigned long start_pfn,
+ unsigned long nr_pages)
+{
+ return mhp_notimplemented(__FUNCTION__);
+}
+#endif /* ! CONFIG_MEMORY_HOTPLUG */
+static inline int __remove_pages(struct zone *zone, unsigned long start_pfn,
+ unsigned long nr_pages)
+{
+ printk(KERN_WARNING "%s() called, not yet supported\n", __FUNCTION__);
+ dump_stack();
+ return -ENOSYS;
+}
+#endif /* __LINUX_MEMORY_HOTPLUG_H */
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h
index 58385ee1c0ac..8b67cf837ca9 100644
--- a/include/linux/mempolicy.h
+++ b/include/linux/mempolicy.h
@@ -27,10 +27,10 @@
#include <linux/config.h>
#include <linux/mmzone.h>
-#include <linux/bitmap.h>
#include <linux/slab.h>
#include <linux/rbtree.h>
#include <linux/spinlock.h>
+#include <linux/nodemask.h>
struct vm_area_struct;
@@ -47,8 +47,7 @@ struct vm_area_struct;
* Locking policy for interlave:
* In process context there is no locking because only the process accesses
* its own state. All vma manipulation is somewhat protected by a down_read on
- * mmap_sem. For allocating in the interleave policy the page_table_lock
- * must be also aquired to protect il_next.
+ * mmap_sem.
*
* Freeing policy:
* When policy is MPOL_BIND v.zonelist is kmalloc'ed and must be kfree'd.
@@ -63,7 +62,7 @@ struct mempolicy {
union {
struct zonelist *zonelist; /* bind */
short preferred_node; /* preferred */
- DECLARE_BITMAP(nodes, MAX_NUMNODES); /* interleave */
+ nodemask_t nodes; /* interleave */
/* undefined for default */
} v;
};
@@ -155,6 +154,7 @@ struct mempolicy *get_vma_policy(struct task_struct *task,
extern void numa_default_policy(void);
extern void numa_policy_init(void);
+extern void numa_policy_rebind(const nodemask_t *old, const nodemask_t *new);
extern struct mempolicy default_policy;
#else
@@ -227,6 +227,11 @@ static inline void numa_default_policy(void)
{
}
+static inline void numa_policy_rebind(const nodemask_t *old,
+ const nodemask_t *new)
+{
+}
+
#endif /* CONFIG_NUMA */
#endif /* __KERNEL__ */
diff --git a/include/linux/mm.h b/include/linux/mm.h
index e1649578fb0c..5c1fb0a2e806 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -157,7 +157,7 @@ extern unsigned int kobjsize(const void *objp);
#define VM_DONTCOPY 0x00020000 /* Do not copy this vma on fork */
#define VM_DONTEXPAND 0x00040000 /* Cannot expand with mremap() */
-#define VM_RESERVED 0x00080000 /* Don't unmap it from swap_out */
+#define VM_RESERVED 0x00080000 /* Pages managed in a special way */
#define VM_ACCOUNT 0x00100000 /* Is a VM accounted object */
#define VM_HUGETLB 0x00400000 /* Huge TLB Page VM */
#define VM_NONLINEAR 0x00800000 /* Is non-linear (remap_file_pages) */
@@ -226,13 +226,18 @@ struct page {
* to show when page is mapped
* & limit reverse map searches.
*/
- unsigned long private; /* Mapping-private opaque data:
+ union {
+ unsigned long private; /* Mapping-private opaque data:
* usually used for buffer_heads
* if PagePrivate set; used for
* swp_entry_t if PageSwapCache
* When page is free, this indicates
* order in the buddy system.
*/
+#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
+ spinlock_t ptl;
+#endif
+ } u;
struct address_space *mapping; /* If low bit clear, points to
* inode address_space, or NULL.
* If page mapped as anonymous
@@ -260,6 +265,9 @@ struct page {
#endif /* WANT_PAGE_VIRTUAL */
};
+#define page_private(page) ((page)->u.private)
+#define set_page_private(page, v) ((page)->u.private = (v))
+
/*
* FIXME: take this include out, include page-flags.h in
* files which need it (119 of them)
@@ -311,17 +319,17 @@ extern void FASTCALL(__page_cache_release(struct page *));
#ifdef CONFIG_HUGETLB_PAGE
-static inline int page_count(struct page *p)
+static inline int page_count(struct page *page)
{
- if (PageCompound(p))
- p = (struct page *)p->private;
- return atomic_read(&(p)->_count) + 1;
+ if (PageCompound(page))
+ page = (struct page *)page_private(page);
+ return atomic_read(&page->_count) + 1;
}
static inline void get_page(struct page *page)
{
if (unlikely(PageCompound(page)))
- page = (struct page *)page->private;
+ page = (struct page *)page_private(page);
atomic_inc(&page->_count);
}
@@ -338,7 +346,7 @@ static inline void get_page(struct page *page)
static inline void put_page(struct page *page)
{
- if (!PageReserved(page) && put_page_testzero(page))
+ if (put_page_testzero(page))
__page_cache_release(page);
}
@@ -587,7 +595,7 @@ static inline int PageAnon(struct page *page)
static inline pgoff_t page_index(struct page *page)
{
if (unlikely(PageSwapCache(page)))
- return page->private;
+ return page_private(page);
return page->index;
}
@@ -682,7 +690,7 @@ struct zap_details {
unsigned long zap_page_range(struct vm_area_struct *vma, unsigned long address,
unsigned long size, struct zap_details *);
-unsigned long unmap_vmas(struct mmu_gather **tlb, struct mm_struct *mm,
+unsigned long unmap_vmas(struct mmu_gather **tlb,
struct vm_area_struct *start_vma, unsigned long start_addr,
unsigned long end_addr, unsigned long *nr_accounted,
struct zap_details *);
@@ -704,10 +712,6 @@ static inline void unmap_shared_mapping_range(struct address_space *mapping,
}
extern int vmtruncate(struct inode * inode, loff_t offset);
-extern pud_t *FASTCALL(__pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address));
-extern pmd_t *FASTCALL(__pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address));
-extern pte_t *FASTCALL(pte_alloc_kernel(struct mm_struct *mm, pmd_t *pmd, unsigned long address));
-extern pte_t *FASTCALL(pte_alloc_map(struct mm_struct *mm, pmd_t *pmd, unsigned long address));
extern int install_page(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, struct page *page, pgprot_t prot);
extern int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, unsigned long pgoff, pgprot_t prot);
extern int __handle_mm_fault(struct mm_struct *mm,struct vm_area_struct *vma, unsigned long address, int write_access);
@@ -723,6 +727,7 @@ void install_arg_page(struct vm_area_struct *, struct page *, unsigned long);
int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start,
int len, int write, int force, struct page **pages, struct vm_area_struct **vmas);
+void print_bad_pte(struct vm_area_struct *, pte_t, unsigned long);
int __set_page_dirty_buffers(struct page *page);
int __set_page_dirty_nobuffers(struct page *page);
@@ -759,38 +764,83 @@ struct shrinker;
extern struct shrinker *set_shrinker(int, shrinker_t);
extern void remove_shrinker(struct shrinker *shrinker);
-/*
- * On a two-level or three-level page table, this ends up being trivial. Thus
- * the inlining and the symmetry break with pte_alloc_map() that does all
- * of this out-of-line.
- */
+int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address);
+int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address);
+int __pte_alloc(struct mm_struct *mm, pmd_t *pmd, unsigned long address);
+int __pte_alloc_kernel(pmd_t *pmd, unsigned long address);
+
/*
* The following ifdef needed to get the 4level-fixup.h header to work.
* Remove it when 4level-fixup.h has been removed.
*/
-#ifdef CONFIG_MMU
-#ifndef __ARCH_HAS_4LEVEL_HACK
+#if defined(CONFIG_MMU) && !defined(__ARCH_HAS_4LEVEL_HACK)
static inline pud_t *pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
{
- if (pgd_none(*pgd))
- return __pud_alloc(mm, pgd, address);
- return pud_offset(pgd, address);
+ return (unlikely(pgd_none(*pgd)) && __pud_alloc(mm, pgd, address))?
+ NULL: pud_offset(pgd, address);
}
static inline pmd_t *pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
{
- if (pud_none(*pud))
- return __pmd_alloc(mm, pud, address);
- return pmd_offset(pud, address);
+ return (unlikely(pud_none(*pud)) && __pmd_alloc(mm, pud, address))?
+ NULL: pmd_offset(pud, address);
}
-#endif
-#endif /* CONFIG_MMU */
+#endif /* CONFIG_MMU && !__ARCH_HAS_4LEVEL_HACK */
+
+#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
+/*
+ * We tuck a spinlock to guard each pagetable page into its struct page,
+ * at page->private, with BUILD_BUG_ON to make sure that this will not
+ * overflow into the next struct page (as it might with DEBUG_SPINLOCK).
+ * When freeing, reset page->mapping so free_pages_check won't complain.
+ */
+#define __pte_lockptr(page) &((page)->u.ptl)
+#define pte_lock_init(_page) do { \
+ spin_lock_init(__pte_lockptr(_page)); \
+} while (0)
+#define pte_lock_deinit(page) ((page)->mapping = NULL)
+#define pte_lockptr(mm, pmd) ({(void)(mm); __pte_lockptr(pmd_page(*(pmd)));})
+#else
+/*
+ * We use mm->page_table_lock to guard all pagetable pages of the mm.
+ */
+#define pte_lock_init(page) do {} while (0)
+#define pte_lock_deinit(page) do {} while (0)
+#define pte_lockptr(mm, pmd) ({(void)(pmd); &(mm)->page_table_lock;})
+#endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
+
+#define pte_offset_map_lock(mm, pmd, address, ptlp) \
+({ \
+ spinlock_t *__ptl = pte_lockptr(mm, pmd); \
+ pte_t *__pte = pte_offset_map(pmd, address); \
+ *(ptlp) = __ptl; \
+ spin_lock(__ptl); \
+ __pte; \
+})
+
+#define pte_unmap_unlock(pte, ptl) do { \
+ spin_unlock(ptl); \
+ pte_unmap(pte); \
+} while (0)
+
+#define pte_alloc_map(mm, pmd, address) \
+ ((unlikely(!pmd_present(*(pmd))) && __pte_alloc(mm, pmd, address))? \
+ NULL: pte_offset_map(pmd, address))
+
+#define pte_alloc_map_lock(mm, pmd, address, ptlp) \
+ ((unlikely(!pmd_present(*(pmd))) && __pte_alloc(mm, pmd, address))? \
+ NULL: pte_offset_map_lock(mm, pmd, address, ptlp))
+
+#define pte_alloc_kernel(pmd, address) \
+ ((unlikely(!pmd_present(*(pmd))) && __pte_alloc_kernel(pmd, address))? \
+ NULL: pte_offset_kernel(pmd, address))
extern void free_area_init(unsigned long * zones_size);
extern void free_area_init_node(int nid, pg_data_t *pgdat,
unsigned long * zones_size, unsigned long zone_start_pfn,
unsigned long *zholes_size);
extern void memmap_init_zone(unsigned long, int, unsigned long, unsigned long);
+extern void setup_per_zone_pages_min(void);
extern void mem_init(void);
extern void show_mem(void);
extern void si_meminfo(struct sysinfo * val);
@@ -834,6 +884,7 @@ extern int split_vma(struct mm_struct *,
extern int insert_vm_struct(struct mm_struct *, struct vm_area_struct *);
extern void __vma_link_rb(struct mm_struct *, struct vm_area_struct *,
struct rb_node **, struct rb_node *);
+extern void unlink_file_vma(struct vm_area_struct *);
extern struct vm_area_struct *copy_vma(struct vm_area_struct **,
unsigned long addr, unsigned long len, pgoff_t pgoff);
extern void exit_mmap(struct mm_struct *);
@@ -894,7 +945,8 @@ void handle_ra_miss(struct address_space *mapping,
unsigned long max_sane_readahead(unsigned long nr);
/* Do stack extension */
-extern int expand_stack(struct vm_area_struct * vma, unsigned long address);
+extern int expand_stack(struct vm_area_struct *vma, unsigned long address);
+extern int expand_upwards(struct vm_area_struct *vma, unsigned long address);
/* Look up the first VMA which satisfies addr < vm_end, NULL if none. */
extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr);
@@ -917,40 +969,28 @@ static inline unsigned long vma_pages(struct vm_area_struct *vma)
return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
}
-extern struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr);
+struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr);
+struct page *vmalloc_to_page(void *addr);
+unsigned long vmalloc_to_pfn(void *addr);
+int remap_pfn_range(struct vm_area_struct *, unsigned long addr,
+ unsigned long pfn, unsigned long size, pgprot_t);
-extern struct page * vmalloc_to_page(void *addr);
-extern unsigned long vmalloc_to_pfn(void *addr);
-extern struct page * follow_page(struct mm_struct *mm, unsigned long address,
- int write);
-extern int check_user_page_readable(struct mm_struct *mm, unsigned long address);
-int remap_pfn_range(struct vm_area_struct *, unsigned long,
- unsigned long, unsigned long, pgprot_t);
+struct page *follow_page(struct mm_struct *, unsigned long address,
+ unsigned int foll_flags);
+#define FOLL_WRITE 0x01 /* check pte is writable */
+#define FOLL_TOUCH 0x02 /* mark page accessed */
+#define FOLL_GET 0x04 /* do get_page on page */
+#define FOLL_ANON 0x08 /* give ZERO_PAGE if no pgtable */
#ifdef CONFIG_PROC_FS
-void __vm_stat_account(struct mm_struct *, unsigned long, struct file *, long);
+void vm_stat_account(struct mm_struct *, unsigned long, struct file *, long);
#else
-static inline void __vm_stat_account(struct mm_struct *mm,
+static inline void vm_stat_account(struct mm_struct *mm,
unsigned long flags, struct file *file, long pages)
{
}
#endif /* CONFIG_PROC_FS */
-static inline void vm_stat_account(struct vm_area_struct *vma)
-{
- __vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file,
- vma_pages(vma));
-}
-
-static inline void vm_stat_unaccount(struct vm_area_struct *vma)
-{
- __vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file,
- -vma_pages(vma));
-}
-
-/* update per process rss and vm hiwater data */
-extern void update_mem_hiwater(struct task_struct *tsk);
-
#ifndef CONFIG_DEBUG_PAGEALLOC
static inline void
kernel_map_pages(struct page *page, int numpages, int enable)
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 7519eb4191e7..f5fa3082fd6a 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -12,6 +12,7 @@
#include <linux/threads.h>
#include <linux/numa.h>
#include <linux/init.h>
+#include <linux/seqlock.h>
#include <asm/atomic.h>
/* Free memory management - zoned buddy allocator. */
@@ -137,6 +138,10 @@ struct zone {
* free areas of different sizes
*/
spinlock_t lock;
+#ifdef CONFIG_MEMORY_HOTPLUG
+ /* see spanned/present_pages for more description */
+ seqlock_t span_seqlock;
+#endif
struct free_area free_area[MAX_ORDER];
@@ -220,6 +225,16 @@ struct zone {
/* zone_start_pfn == zone_start_paddr >> PAGE_SHIFT */
unsigned long zone_start_pfn;
+ /*
+ * zone_start_pfn, spanned_pages and present_pages are all
+ * protected by span_seqlock. It is a seqlock because it has
+ * to be read outside of zone->lock, and it is done in the main
+ * allocator path. But, it is written quite infrequently.
+ *
+ * The lock is declared along with zone->lock because it is
+ * frequently read in proximity to zone->lock. It's good to
+ * give them a chance of being in the same cacheline.
+ */
unsigned long spanned_pages; /* total size, including holes */
unsigned long present_pages; /* amount of memory (excluding holes) */
@@ -273,6 +288,16 @@ typedef struct pglist_data {
struct page *node_mem_map;
#endif
struct bootmem_data *bdata;
+#ifdef CONFIG_MEMORY_HOTPLUG
+ /*
+ * Must be held any time you expect node_start_pfn, node_present_pages
+ * or node_spanned_pages stay constant. Holding this will also
+ * guarantee that any pfn_valid() stays that way.
+ *
+ * Nests above zone->lock and zone->size_seqlock.
+ */
+ spinlock_t node_size_lock;
+#endif
unsigned long node_start_pfn;
unsigned long node_present_pages; /* total number of physical pages */
unsigned long node_spanned_pages; /* total size of physical page
@@ -293,6 +318,8 @@ typedef struct pglist_data {
#endif
#define nid_page_nr(nid, pagenr) pgdat_page_nr(NODE_DATA(nid),(pagenr))
+#include <linux/memory_hotplug.h>
+
extern struct pglist_data *pgdat_list;
void __get_zone_counts(unsigned long *active, unsigned long *inactive,
@@ -509,6 +536,7 @@ static inline struct mem_section *__nr_to_section(unsigned long nr)
return NULL;
return &mem_section[SECTION_NR_TO_ROOT(nr)][nr & SECTION_ROOT_MASK];
}
+extern int __section_nr(struct mem_section* ms);
/*
* We use the lower bits of the mem_map pointer to store
diff --git a/include/linux/module.h b/include/linux/module.h
index f05372b7fe77..84d75f3a8aca 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -554,7 +554,9 @@ static inline void MODULE_PARM_(void) { }
#ifdef MODULE
/* DEPRECATED: Do not use. */
#define MODULE_PARM(var,type) \
-struct obsolete_modparm __parm_##var __attribute__((section("__obsparm"))) = \
+extern struct obsolete_modparm __parm_##var \
+__attribute__((section("__obsparm"))); \
+struct obsolete_modparm __parm_##var = \
{ __stringify(var), type, &MODULE_PARM_ }; \
__MODULE_PARM_TYPE(var, type);
#else
diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h
index 9a3d27257984..941da5c016a0 100644
--- a/include/linux/msdos_fs.h
+++ b/include/linux/msdos_fs.h
@@ -282,6 +282,17 @@ static inline u8 fat_attr(struct inode *inode)
MSDOS_I(inode)->i_attrs;
}
+static inline unsigned char fat_checksum(const __u8 *name)
+{
+ unsigned char s = name[0];
+ s = (s<<7) + (s>>1) + name[1]; s = (s<<7) + (s>>1) + name[2];
+ s = (s<<7) + (s>>1) + name[3]; s = (s<<7) + (s>>1) + name[4];
+ s = (s<<7) + (s>>1) + name[5]; s = (s<<7) + (s>>1) + name[6];
+ s = (s<<7) + (s>>1) + name[7]; s = (s<<7) + (s>>1) + name[8];
+ s = (s<<7) + (s>>1) + name[9]; s = (s<<7) + (s>>1) + name[10];
+ return s;
+}
+
static inline sector_t fat_clus_to_blknr(struct msdos_sb_info *sbi, int clus)
{
return ((sector_t)clus - FAT_START_ENT) * sbi->sec_per_clus
diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h
index 142963f01d29..fc28841f3409 100644
--- a/include/linux/mtd/map.h
+++ b/include/linux/mtd/map.h
@@ -8,7 +8,10 @@
#include <linux/config.h>
#include <linux/types.h>
#include <linux/list.h>
+#include <linux/string.h>
+
#include <linux/mtd/compatmac.h>
+
#include <asm/unaligned.h>
#include <asm/system.h>
#include <asm/io.h>
diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h
index e96fe9062500..4726ef7ba8e8 100644
--- a/include/linux/nodemask.h
+++ b/include/linux/nodemask.h
@@ -12,6 +12,8 @@
* see bitmap_scnprintf() and bitmap_parse() in lib/bitmap.c.
* For details of nodelist_scnprintf() and nodelist_parse(), see
* bitmap_scnlistprintf() and bitmap_parselist(), also in bitmap.c.
+ * For details of node_remap(), see bitmap_bitremap in lib/bitmap.c.
+ * For details of nodes_remap(), see bitmap_remap in lib/bitmap.c.
*
* The available nodemask operations are:
*
@@ -52,6 +54,8 @@
* int nodemask_parse(ubuf, ulen, mask) Parse ascii string as nodemask
* int nodelist_scnprintf(buf, len, mask) Format nodemask as list for printing
* int nodelist_parse(buf, map) Parse ascii string as nodelist
+ * int node_remap(oldbit, old, new) newbit = map(old, new)(oldbit)
+ * int nodes_remap(dst, src, old, new) *dst = map(old, new)(dst)
*
* for_each_node_mask(node, mask) for-loop node over mask
*
@@ -307,6 +311,22 @@ static inline int __nodelist_parse(const char *buf, nodemask_t *dstp, int nbits)
return bitmap_parselist(buf, dstp->bits, nbits);
}
+#define node_remap(oldbit, old, new) \
+ __node_remap((oldbit), &(old), &(new), MAX_NUMNODES)
+static inline int __node_remap(int oldbit,
+ const nodemask_t *oldp, const nodemask_t *newp, int nbits)
+{
+ return bitmap_bitremap(oldbit, oldp->bits, newp->bits, nbits);
+}
+
+#define nodes_remap(dst, src, old, new) \
+ __nodes_remap(&(dst), &(src), &(old), &(new), MAX_NUMNODES)
+static inline void __nodes_remap(nodemask_t *dstp, const nodemask_t *srcp,
+ const nodemask_t *oldp, const nodemask_t *newp, int nbits)
+{
+ bitmap_remap(dstp->bits, srcp->bits, oldp->bits, newp->bits, nbits);
+}
+
#if MAX_NUMNODES > 1
#define for_each_node_mask(node, mask) \
for ((node) = first_node(mask); \
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 467a096c3b81..56192005fa4d 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1788,11 +1788,13 @@
#define PCI_DEVICE_ID_TIGON3_5721 0x1659
#define PCI_DEVICE_ID_TIGON3_5705M 0x165d
#define PCI_DEVICE_ID_TIGON3_5705M_2 0x165e
+#define PCI_DEVICE_ID_TIGON3_5714 0x1668
#define PCI_DEVICE_ID_TIGON3_5780 0x166a
#define PCI_DEVICE_ID_TIGON3_5780S 0x166b
#define PCI_DEVICE_ID_TIGON3_5705F 0x166e
#define PCI_DEVICE_ID_TIGON3_5750 0x1676
#define PCI_DEVICE_ID_TIGON3_5751 0x1677
+#define PCI_DEVICE_ID_TIGON3_5715 0x1678
#define PCI_DEVICE_ID_TIGON3_5750M 0x167c
#define PCI_DEVICE_ID_TIGON3_5751M 0x167d
#define PCI_DEVICE_ID_TIGON3_5751F 0x167e
diff --git a/include/linux/pm.h b/include/linux/pm.h
index c61d5de837ef..1514098d156d 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -170,6 +170,7 @@ typedef int __bitwise suspend_disk_method_t;
struct pm_ops {
suspend_disk_method_t pm_disk_mode;
+ int (*valid)(suspend_state_t state);
int (*prepare)(suspend_state_t state);
int (*enter)(suspend_state_t state);
int (*finish)(suspend_state_t state);
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 70191a5a148f..cce25591eec2 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -275,6 +275,7 @@ static inline int rcu_pending(int cpu)
extern void rcu_init(void);
extern void rcu_check_callbacks(int cpu, int user);
extern void rcu_restart_cpu(int cpu);
+extern long rcu_batches_completed(void);
/* Exported interfaces */
extern void FASTCALL(call_rcu(struct rcu_head *head,
diff --git a/include/linux/rmap.h b/include/linux/rmap.h
index e80fb7ee6efd..35b30e6c8cf8 100644
--- a/include/linux/rmap.h
+++ b/include/linux/rmap.h
@@ -95,8 +95,8 @@ int try_to_unmap(struct page *);
/*
* Called from mm/filemap_xip.c to unmap empty zero page
*/
-pte_t *page_check_address(struct page *, struct mm_struct *, unsigned long);
-
+pte_t *page_check_address(struct page *, struct mm_struct *,
+ unsigned long, spinlock_t **);
/*
* Used by swapoff to help locate where page is expected in vma.
diff --git a/include/linux/rwsem-spinlock.h b/include/linux/rwsem-spinlock.h
index b52a2af25f1f..f30f805080ae 100644
--- a/include/linux/rwsem-spinlock.h
+++ b/include/linux/rwsem-spinlock.h
@@ -61,5 +61,10 @@ extern void FASTCALL(__up_read(struct rw_semaphore *sem));
extern void FASTCALL(__up_write(struct rw_semaphore *sem));
extern void FASTCALL(__downgrade_write(struct rw_semaphore *sem));
+static inline int rwsem_is_locked(struct rw_semaphore *sem)
+{
+ return (sem->activity != 0);
+}
+
#endif /* __KERNEL__ */
#endif /* _LINUX_RWSEM_SPINLOCK_H */
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index 7f717e95ae37..66ff545552f7 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -1,14 +1,23 @@
#ifndef _LINUX_SCATTERLIST_H
#define _LINUX_SCATTERLIST_H
-static inline void sg_init_one(struct scatterlist *sg,
- u8 *buf, unsigned int buflen)
-{
- memset(sg, 0, sizeof(*sg));
+#include <asm/scatterlist.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+static inline void sg_set_buf(struct scatterlist *sg, void *buf,
+ unsigned int buflen)
+{
sg->page = virt_to_page(buf);
sg->offset = offset_in_page(buf);
sg->length = buflen;
}
+static inline void sg_init_one(struct scatterlist *sg, void *buf,
+ unsigned int buflen)
+{
+ memset(sg, 0, sizeof(*sg));
+ sg_set_buf(sg, buf, buflen);
+}
+
#endif /* _LINUX_SCATTERLIST_H */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 27519df0f987..03b68a7b4b82 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -249,6 +249,36 @@ arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
extern void arch_unmap_area(struct mm_struct *, unsigned long);
extern void arch_unmap_area_topdown(struct mm_struct *, unsigned long);
+#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
+/*
+ * The mm counters are not protected by its page_table_lock,
+ * so must be incremented atomically.
+ */
+#ifdef ATOMIC64_INIT
+#define set_mm_counter(mm, member, value) atomic64_set(&(mm)->_##member, value)
+#define get_mm_counter(mm, member) ((unsigned long)atomic64_read(&(mm)->_##member))
+#define add_mm_counter(mm, member, value) atomic64_add(value, &(mm)->_##member)
+#define inc_mm_counter(mm, member) atomic64_inc(&(mm)->_##member)
+#define dec_mm_counter(mm, member) atomic64_dec(&(mm)->_##member)
+typedef atomic64_t mm_counter_t;
+#else /* !ATOMIC64_INIT */
+/*
+ * The counters wrap back to 0 at 2^32 * PAGE_SIZE,
+ * that is, at 16TB if using 4kB page size.
+ */
+#define set_mm_counter(mm, member, value) atomic_set(&(mm)->_##member, value)
+#define get_mm_counter(mm, member) ((unsigned long)atomic_read(&(mm)->_##member))
+#define add_mm_counter(mm, member, value) atomic_add(value, &(mm)->_##member)
+#define inc_mm_counter(mm, member) atomic_inc(&(mm)->_##member)
+#define dec_mm_counter(mm, member) atomic_dec(&(mm)->_##member)
+typedef atomic_t mm_counter_t;
+#endif /* !ATOMIC64_INIT */
+
+#else /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
+/*
+ * The mm counters are protected by its page_table_lock,
+ * so can be incremented directly.
+ */
#define set_mm_counter(mm, member, value) (mm)->_##member = (value)
#define get_mm_counter(mm, member) ((mm)->_##member)
#define add_mm_counter(mm, member, value) (mm)->_##member += (value)
@@ -256,6 +286,20 @@ extern void arch_unmap_area_topdown(struct mm_struct *, unsigned long);
#define dec_mm_counter(mm, member) (mm)->_##member--
typedef unsigned long mm_counter_t;
+#endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
+
+#define get_mm_rss(mm) \
+ (get_mm_counter(mm, file_rss) + get_mm_counter(mm, anon_rss))
+#define update_hiwater_rss(mm) do { \
+ unsigned long _rss = get_mm_rss(mm); \
+ if ((mm)->hiwater_rss < _rss) \
+ (mm)->hiwater_rss = _rss; \
+} while (0)
+#define update_hiwater_vm(mm) do { \
+ if ((mm)->hiwater_vm < (mm)->total_vm) \
+ (mm)->hiwater_vm = (mm)->total_vm; \
+} while (0)
+
struct mm_struct {
struct vm_area_struct * mmap; /* list of VMAs */
struct rb_root mm_rb;
@@ -279,15 +323,20 @@ struct mm_struct {
* by mmlist_lock
*/
+ /* Special counters, in some configurations protected by the
+ * page_table_lock, in other configurations by being atomic.
+ */
+ mm_counter_t _file_rss;
+ mm_counter_t _anon_rss;
+
+ unsigned long hiwater_rss; /* High-watermark of RSS usage */
+ unsigned long hiwater_vm; /* High-water virtual memory usage */
+
+ unsigned long total_vm, locked_vm, shared_vm, exec_vm;
+ unsigned long stack_vm, reserved_vm, def_flags, nr_ptes;
unsigned long start_code, end_code, start_data, end_data;
unsigned long start_brk, brk, start_stack;
unsigned long arg_start, arg_end, env_start, env_end;
- unsigned long total_vm, locked_vm, shared_vm;
- unsigned long exec_vm, stack_vm, reserved_vm, def_flags, nr_ptes;
-
- /* Special counters protected by the page_table_lock */
- mm_counter_t _rss;
- mm_counter_t _anon_rss;
unsigned long saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */
@@ -308,11 +357,7 @@ struct mm_struct {
/* aio bits */
rwlock_t ioctx_list_lock;
struct kioctx *ioctx_list;
-
struct kioctx default_kioctx;
-
- unsigned long hiwater_rss; /* High-water RSS usage */
- unsigned long hiwater_vm; /* High-water virtual memory usage */
};
struct sighand_struct {
@@ -895,7 +940,7 @@ extern int set_cpus_allowed(task_t *p, cpumask_t new_mask);
#else
static inline int set_cpus_allowed(task_t *p, cpumask_t new_mask)
{
- if (!cpus_intersects(new_mask, cpu_online_map))
+ if (!cpu_isset(0, new_mask))
return -EINVAL;
return 0;
}
@@ -1039,6 +1084,11 @@ extern int do_sigaltstack(const stack_t __user *, stack_t __user *, unsigned lon
#define SEND_SIG_PRIV ((struct siginfo *) 1)
#define SEND_SIG_FORCED ((struct siginfo *) 2)
+static inline int is_si_special(const struct siginfo *info)
+{
+ return info <= SEND_SIG_FORCED;
+}
+
/* True if we are on the alternate signal stack. */
static inline int on_sig_stack(unsigned long sp)
@@ -1166,7 +1216,7 @@ extern void unhash_process(struct task_struct *p);
/*
* Protects ->fs, ->files, ->mm, ->ptrace, ->group_info, ->comm, keyring
* subscriptions and synchronises with wait4(). Also used in procfs. Also
- * pins the final release of task.io_context.
+ * pins the final release of task.io_context. Also protects ->cpuset.
*
* Nests both inside and outside of read_lock(&tasklist_lock).
* It must not be nested with write_lock_irq(&tasklist_lock),
diff --git a/include/linux/security.h b/include/linux/security.h
index dac956ed98f0..f7e0ae018712 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -30,6 +30,7 @@
#include <linux/shm.h>
#include <linux/msg.h>
#include <linux/sched.h>
+#include <linux/key.h>
struct ctl_table;
@@ -385,6 +386,9 @@ struct swap_info_struct;
* NULL to request the size of the buffer required. @size indicates
* the size of @buffer in bytes. Note that @name is the remainder
* of the attribute name after the security. prefix has been removed.
+ * @err is the return value from the preceding fs getxattr call,
+ * and can be used by the security module to determine whether it
+ * should try and canonicalize the attribute value.
* Return number of bytes used/required on success.
* @inode_setsecurity:
* Set the security label associated with @name for @inode from the
@@ -785,6 +789,27 @@ struct swap_info_struct;
* @sk_free_security:
* Deallocate security structure.
*
+ * Security hooks affecting all Key Management operations
+ *
+ * @key_alloc:
+ * Permit allocation of a key and assign security data. Note that key does
+ * not have a serial number assigned at this point.
+ * @key points to the key.
+ * Return 0 if permission is granted, -ve error otherwise.
+ * @key_free:
+ * Notification of destruction; free security data.
+ * @key points to the key.
+ * No return value.
+ * @key_permission:
+ * See whether a specific operational right is granted to a process on a
+ * key.
+ * @key_ref refers to the key (key pointer + possession attribute bit).
+ * @context points to the process to provide the context against which to
+ * evaluate the security data on the key.
+ * @perm describes the combination of permissions required of this key.
+ * Return 1 if permission granted, 0 if permission denied and -ve it the
+ * normal permissions model should be effected.
+ *
* Security hooks affecting all System V IPC operations.
*
* @ipc_permission:
@@ -1091,7 +1116,7 @@ struct security_operations {
int (*inode_getxattr) (struct dentry *dentry, char *name);
int (*inode_listxattr) (struct dentry *dentry);
int (*inode_removexattr) (struct dentry *dentry, char *name);
- int (*inode_getsecurity)(struct inode *inode, const char *name, void *buffer, size_t size);
+ int (*inode_getsecurity)(struct inode *inode, const char *name, void *buffer, size_t size, int err);
int (*inode_setsecurity)(struct inode *inode, const char *name, const void *value, size_t size, int flags);
int (*inode_listsecurity)(struct inode *inode, char *buffer, size_t buffer_size);
@@ -1213,6 +1238,17 @@ struct security_operations {
int (*sk_alloc_security) (struct sock *sk, int family, gfp_t priority);
void (*sk_free_security) (struct sock *sk);
#endif /* CONFIG_SECURITY_NETWORK */
+
+ /* key management security hooks */
+#ifdef CONFIG_KEYS
+ int (*key_alloc)(struct key *key);
+ void (*key_free)(struct key *key);
+ int (*key_permission)(key_ref_t key_ref,
+ struct task_struct *context,
+ key_perm_t perm);
+
+#endif /* CONFIG_KEYS */
+
};
/* global variables */
@@ -1580,11 +1616,11 @@ static inline int security_inode_removexattr (struct dentry *dentry, char *name)
return security_ops->inode_removexattr (dentry, name);
}
-static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size)
+static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
{
if (unlikely (IS_PRIVATE (inode)))
return 0;
- return security_ops->inode_getsecurity(inode, name, buffer, size);
+ return security_ops->inode_getsecurity(inode, name, buffer, size, err);
}
static inline int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags)
@@ -2222,7 +2258,7 @@ static inline int security_inode_removexattr (struct dentry *dentry, char *name)
return cap_inode_removexattr(dentry, name);
}
-static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size)
+static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
{
return -EOPNOTSUPP;
}
@@ -2761,5 +2797,45 @@ static inline void security_sk_free(struct sock *sk)
}
#endif /* CONFIG_SECURITY_NETWORK */
+#ifdef CONFIG_KEYS
+#ifdef CONFIG_SECURITY
+static inline int security_key_alloc(struct key *key)
+{
+ return security_ops->key_alloc(key);
+}
+
+static inline void security_key_free(struct key *key)
+{
+ security_ops->key_free(key);
+}
+
+static inline int security_key_permission(key_ref_t key_ref,
+ struct task_struct *context,
+ key_perm_t perm)
+{
+ return security_ops->key_permission(key_ref, context, perm);
+}
+
+#else
+
+static inline int security_key_alloc(struct key *key)
+{
+ return 0;
+}
+
+static inline void security_key_free(struct key *key)
+{
+}
+
+static inline int security_key_permission(key_ref_t key_ref,
+ struct task_struct *context,
+ key_perm_t perm)
+{
+ return 0;
+}
+
+#endif
+#endif /* CONFIG_KEYS */
+
#endif /* ! __LINUX_SECURITY_H */
diff --git a/include/linux/serial.h b/include/linux/serial.h
index 12cd9cf65e8f..33fc8cb8ddfb 100644
--- a/include/linux/serial.h
+++ b/include/linux/serial.h
@@ -11,6 +11,7 @@
#define _LINUX_SERIAL_H
#ifdef __KERNEL__
+#include <linux/types.h>
#include <asm/page.h>
/*
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 27db8da43aa4..2b0401b93f2b 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -39,7 +39,8 @@
#define PORT_RSA 13
#define PORT_NS16550A 14
#define PORT_XSCALE 15
-#define PORT_MAX_8250 15 /* max port ID */
+#define PORT_IP3106 16
+#define PORT_MAX_8250 16 /* max port ID */
/*
* ARM specific type numbers. These are not currently guaranteed
diff --git a/include/linux/serial_ip3106.h b/include/linux/serial_ip3106.h
new file mode 100644
index 000000000000..f500ac602c5c
--- /dev/null
+++ b/include/linux/serial_ip3106.h
@@ -0,0 +1,81 @@
+/*
+ * Embedded Alley Solutions, source@embeddedalley.com.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LINUX_SERIAL_IP3106_H
+#define _LINUX_SERIAL_IP3106_H
+
+#include <linux/serial_core.h>
+#include <linux/device.h>
+
+#define IP3106_NR_PORTS 2
+
+struct ip3106_port {
+ struct uart_port port;
+ struct timer_list timer;
+ unsigned int old_status;
+};
+
+/* register offsets */
+#define IP3106_LCR 0
+#define IP3106_MCR 0x004
+#define IP3106_BAUD 0x008
+#define IP3106_CFG 0x00c
+#define IP3106_FIFO 0x028
+#define IP3106_ISTAT 0xfe0
+#define IP3106_IEN 0xfe4
+#define IP3106_ICLR 0xfe8
+#define IP3106_ISET 0xfec
+#define IP3106_PD 0xff4
+#define IP3106_MID 0xffc
+
+#define IP3106_UART_LCR_TXBREAK (1<<30)
+#define IP3106_UART_LCR_PAREVN 0x10000000
+#define IP3106_UART_LCR_PAREN 0x08000000
+#define IP3106_UART_LCR_2STOPB 0x04000000
+#define IP3106_UART_LCR_8BIT 0x01000000
+#define IP3106_UART_LCR_TX_RST 0x00040000
+#define IP3106_UART_LCR_RX_RST 0x00020000
+#define IP3106_UART_LCR_RX_NEXT 0x00010000
+
+#define IP3106_UART_MCR_SCR 0xFF000000
+#define IP3106_UART_MCR_DCD 0x00800000
+#define IP3106_UART_MCR_CTS 0x00100000
+#define IP3106_UART_MCR_LOOP 0x00000010
+#define IP3106_UART_MCR_RTS 0x00000002
+#define IP3106_UART_MCR_DTR 0x00000001
+
+#define IP3106_UART_INT_TX 0x00000080
+#define IP3106_UART_INT_EMPTY 0x00000040
+#define IP3106_UART_INT_RCVTO 0x00000020
+#define IP3106_UART_INT_RX 0x00000010
+#define IP3106_UART_INT_RXOVRN 0x00000008
+#define IP3106_UART_INT_FRERR 0x00000004
+#define IP3106_UART_INT_BREAK 0x00000002
+#define IP3106_UART_INT_PARITY 0x00000001
+#define IP3106_UART_INT_ALLRX 0x0000003F
+#define IP3106_UART_INT_ALLTX 0x000000C0
+
+#define IP3106_UART_FIFO_TXFIFO 0x001F0000
+#define IP3106_UART_FIFO_TXFIFO_STA (0x1f<<16)
+#define IP3106_UART_FIFO_RXBRK 0x00008000
+#define IP3106_UART_FIFO_RXFE 0x00004000
+#define IP3106_UART_FIFO_RXPAR 0x00002000
+#define IP3106_UART_FIFO_RXFIFO 0x00001F00
+#define IP3106_UART_FIFO_RBRTHR 0x000000FF
+
+#endif
diff --git a/include/linux/signal.h b/include/linux/signal.h
index 7be18b5e2fb4..5dd5f02c5c5f 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -25,7 +25,6 @@
struct sigqueue {
struct list_head list;
- spinlock_t *lock;
int flags;
siginfo_t info;
struct user_struct *user;
diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
index cdc99a27840d..0e9682c9def5 100644
--- a/include/linux/spinlock.h
+++ b/include/linux/spinlock.h
@@ -171,23 +171,42 @@ extern int __lockfunc generic__raw_read_trylock(raw_rwlock_t *lock);
#define write_lock_irq(lock) _write_lock_irq(lock)
#define write_lock_bh(lock) _write_lock_bh(lock)
-#define spin_unlock(lock) _spin_unlock(lock)
-#define write_unlock(lock) _write_unlock(lock)
-#define read_unlock(lock) _read_unlock(lock)
+/*
+ * We inline the unlock functions in the nondebug case:
+ */
+#if defined(CONFIG_DEBUG_SPINLOCK) || defined(CONFIG_PREEMPT) || !defined(CONFIG_SMP)
+# define spin_unlock(lock) _spin_unlock(lock)
+# define read_unlock(lock) _read_unlock(lock)
+# define write_unlock(lock) _write_unlock(lock)
+#else
+# define spin_unlock(lock) __raw_spin_unlock(&(lock)->raw_lock)
+# define read_unlock(lock) __raw_read_unlock(&(lock)->raw_lock)
+# define write_unlock(lock) __raw_write_unlock(&(lock)->raw_lock)
+#endif
+
+#if defined(CONFIG_DEBUG_SPINLOCK) || defined(CONFIG_PREEMPT) || !defined(CONFIG_SMP)
+# define spin_unlock_irq(lock) _spin_unlock_irq(lock)
+# define read_unlock_irq(lock) _read_unlock_irq(lock)
+# define write_unlock_irq(lock) _write_unlock_irq(lock)
+#else
+# define spin_unlock_irq(lock) \
+ do { __raw_spin_unlock(&(lock)->raw_lock); local_irq_enable(); } while (0)
+# define read_unlock_irq(lock) \
+ do { __raw_read_unlock(&(lock)->raw_lock); local_irq_enable(); } while (0)
+# define write_unlock_irq(lock) \
+ do { __raw_write_unlock(&(lock)->raw_lock); local_irq_enable(); } while (0)
+#endif
#define spin_unlock_irqrestore(lock, flags) \
_spin_unlock_irqrestore(lock, flags)
-#define spin_unlock_irq(lock) _spin_unlock_irq(lock)
#define spin_unlock_bh(lock) _spin_unlock_bh(lock)
#define read_unlock_irqrestore(lock, flags) \
_read_unlock_irqrestore(lock, flags)
-#define read_unlock_irq(lock) _read_unlock_irq(lock)
#define read_unlock_bh(lock) _read_unlock_bh(lock)
#define write_unlock_irqrestore(lock, flags) \
_write_unlock_irqrestore(lock, flags)
-#define write_unlock_irq(lock) _write_unlock_irq(lock)
#define write_unlock_bh(lock) _write_unlock_bh(lock)
#define spin_trylock_bh(lock) __cond_lock(_spin_trylock_bh(lock))
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index ba448c760168..a61c04f804b2 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -71,7 +71,12 @@ void restore_processor_state(void);
struct saved_context;
void __save_processor_state(struct saved_context *ctxt);
void __restore_processor_state(struct saved_context *ctxt);
-extern unsigned long get_usable_page(gfp_t gfp_mask);
-extern void free_eaten_memory(void);
+unsigned long get_safe_page(gfp_t gfp_mask);
+
+/*
+ * XXX: We try to keep some more pages free so that I/O operations succeed
+ * without paging. Might this be more?
+ */
+#define PAGES_FOR_IO 512
#endif /* _LINUX_SWSUSP_H */
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index a6f03e473737..c7007b1db91d 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -491,6 +491,7 @@ asmlinkage long sys_nfsservctl(int cmd,
asmlinkage long sys_syslog(int type, char __user *buf, int len);
asmlinkage long sys_uselib(const char __user *library);
asmlinkage long sys_ni_syscall(void);
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data);
asmlinkage long sys_add_key(const char __user *_type,
const char __user *_description,
diff --git a/include/linux/textsearch.h b/include/linux/textsearch.h
index fc5bb4e91a58..7dac8f04d28e 100644
--- a/include/linux/textsearch.h
+++ b/include/linux/textsearch.h
@@ -8,6 +8,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/err.h>
+#include <linux/slab.h>
struct ts_config;
diff --git a/include/linux/timer.h b/include/linux/timer.h
index 3340f3bd135d..72f3a7781106 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -12,16 +12,12 @@ struct timer_list {
struct list_head entry;
unsigned long expires;
- unsigned long magic;
-
void (*function)(unsigned long);
unsigned long data;
struct timer_base_s *base;
};
-#define TIMER_MAGIC 0x4b87ad6e
-
extern struct timer_base_s __init_timer_base;
#define TIMER_INITIALIZER(_function, _expires, _data) { \
@@ -29,7 +25,6 @@ extern struct timer_base_s __init_timer_base;
.expires = (_expires), \
.data = (_data), \
.base = &__init_timer_base, \
- .magic = TIMER_MAGIC, \
}
#define DEFINE_TIMER(_name, _function, _expires, _data) \
@@ -38,6 +33,15 @@ extern struct timer_base_s __init_timer_base;
void fastcall init_timer(struct timer_list * timer);
+static inline void setup_timer(struct timer_list * timer,
+ void (*function)(unsigned long),
+ unsigned long data)
+{
+ timer->function = function;
+ timer->data = data;
+ init_timer(timer);
+}
+
/***
* timer_pending - is a timer pending?
* @timer: the timer in question
@@ -74,8 +78,9 @@ extern unsigned long next_timer_interrupt(void);
* Timers with an ->expired field in the past will be executed in the next
* timer tick.
*/
-static inline void add_timer(struct timer_list * timer)
+static inline void add_timer(struct timer_list *timer)
{
+ BUG_ON(timer_pending(timer));
__mod_timer(timer, timer->expires);
}
diff --git a/include/linux/timex.h b/include/linux/timex.h
index 7e050a2cc35b..04a4a8cb4ed3 100644
--- a/include/linux/timex.h
+++ b/include/linux/timex.h
@@ -282,6 +282,13 @@ static inline int ntp_synced(void)
return !(time_status & STA_UNSYNC);
}
+/* Required to safely shift negative values */
+#define shift_right(x, s) ({ \
+ __typeof__(x) __x = (x); \
+ __typeof__(s) __s = (s); \
+ __x < 0 ? -(-__x >> __s) : __x >> __s; \
+})
+
#ifdef CONFIG_TIME_INTERPOLATION
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 3701a0673d2c..1d5577b2b752 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -32,10 +32,14 @@ struct vm_struct {
* Highlevel APIs for driver use
*/
extern void *vmalloc(unsigned long size);
+extern void *vmalloc_node(unsigned long size, int node);
extern void *vmalloc_exec(unsigned long size);
extern void *vmalloc_32(unsigned long size);
extern void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot);
-extern void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot);
+extern void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask,
+ pgprot_t prot);
+extern void *__vmalloc_node(unsigned long size, gfp_t gfp_mask,
+ pgprot_t prot, int node);
extern void vfree(void *addr);
extern void *vmap(struct page **pages, unsigned int count,
@@ -48,6 +52,8 @@ extern void vunmap(void *addr);
extern struct vm_struct *get_vm_area(unsigned long size, unsigned long flags);
extern struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
unsigned long start, unsigned long end);
+extern struct vm_struct *get_vm_area_node(unsigned long size,
+ unsigned long flags, int node);
extern struct vm_struct *remove_vm_area(void *addr);
extern struct vm_struct *__remove_vm_area(void *addr);
extern int map_vm_area(struct vm_struct *area, pgprot_t prot,
diff --git a/include/linux/zutil.h b/include/linux/zutil.h
index fdfd5ed41ec4..ee0c59cf2136 100644
--- a/include/linux/zutil.h
+++ b/include/linux/zutil.h
@@ -15,7 +15,6 @@
#include <linux/zlib.h>
#include <linux/string.h>
-#include <linux/errno.h>
#include <linux/kernel.h>
typedef unsigned char uch;
diff --git a/include/net/ax25.h b/include/net/ax25.h
index 30bb4a893237..2250a18b0cbb 100644
--- a/include/net/ax25.h
+++ b/include/net/ax25.h
@@ -237,8 +237,7 @@ typedef struct ax25_cb {
static __inline__ void ax25_cb_put(ax25_cb *ax25)
{
if (atomic_dec_and_test(&ax25->refcount)) {
- if (ax25->digipeat)
- kfree(ax25->digipeat);
+ kfree(ax25->digipeat);
kfree(ax25);
}
}
diff --git a/include/net/netrom.h b/include/net/netrom.h
index a6bf6e0f606a..a5ee53bce62f 100644
--- a/include/net/netrom.h
+++ b/include/net/netrom.h
@@ -136,8 +136,7 @@ static __inline__ void nr_node_put(struct nr_node *nr_node)
static __inline__ void nr_neigh_put(struct nr_neigh *nr_neigh)
{
if (atomic_dec_and_test(&nr_neigh->refcount)) {
- if (nr_neigh->digipeat != NULL)
- kfree(nr_neigh->digipeat);
+ kfree(nr_neigh->digipeat);
kfree(nr_neigh);
}
}
diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h
index c8592c7e8eaa..e788bbc5657d 100644
--- a/include/pcmcia/ss.h
+++ b/include/pcmcia/ss.h
@@ -17,6 +17,7 @@
#include <linux/config.h>
#include <linux/device.h>
+#include <linux/sched.h> /* task_struct, completion */
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
index b361172b576c..6cb1e2788d8b 100644
--- a/include/scsi/scsi.h
+++ b/include/scsi/scsi.h
@@ -116,6 +116,9 @@ extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE];
/* values for service action in */
#define SAI_READ_CAPACITY_16 0x10
+/* Values for T10/04-262r7 */
+#define ATA_16 0x85 /* 16-byte pass-thru */
+#define ATA_12 0xa1 /* 12-byte pass-thru */
/*
* SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index e6b61fab66dd..7529f4388bb4 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -4,6 +4,7 @@
#include <linux/dma-mapping.h>
#include <linux/list.h>
#include <linux/types.h>
+#include <linux/timer.h>
struct request;
struct scatterlist;
diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
index b0d445437372..c04405bead2d 100644
--- a/include/scsi/scsi_transport_fc.h
+++ b/include/scsi/scsi_transport_fc.h
@@ -28,6 +28,7 @@
#define SCSI_TRANSPORT_FC_H
#include <linux/config.h>
+#include <linux/sched.h>
struct scsi_transport_template;
diff --git a/init/Kconfig b/init/Kconfig
index d5a1a1228fab..3dcbd5bfd498 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -60,8 +60,8 @@ config INIT_ENV_ARG_LIMIT
default 32 if !USERMODE
default 128 if USERMODE
help
- This is the value of the two limits on the number of argument and of
- env.var passed to init from the kernel command line.
+ Maximum of each of the number of arguments and environment
+ variables passed to init from the kernel command line.
endmenu
diff --git a/init/main.c b/init/main.c
index f142d4035341..4075d97e94b1 100644
--- a/init/main.c
+++ b/init/main.c
@@ -64,10 +64,6 @@
#endif
#endif
-#ifdef CONFIG_X86_LOCAL_APIC
-#include <asm/smp.h>
-#endif
-
/*
* Versions of gcc older than that listed below may actually compile
* and link okay, but the end product can have subtle run time bugs.
@@ -314,14 +310,7 @@ extern void setup_arch(char **);
#ifndef CONFIG_SMP
-#ifdef CONFIG_X86_LOCAL_APIC
-static void __init smp_init(void)
-{
- APIC_init_uniprocessor();
-}
-#else
#define smp_init() do { } while (0)
-#endif
static inline void setup_per_cpu_areas(void) { }
static inline void smp_prepare_cpus(unsigned int maxcpus) { }
diff --git a/ipc/shm.c b/ipc/shm.c
index dca90489e3b0..b58c651d31ae 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -233,10 +233,11 @@ static int newseg (key_t key, int shmflg, size_t size)
shp->id = shm_buildid(id,shp->shm_perm.seq);
shp->shm_file = file;
file->f_dentry->d_inode->i_ino = shp->id;
- if (shmflg & SHM_HUGETLB)
- set_file_hugepages(file);
- else
+
+ /* Hugetlb ops would have already been assigned. */
+ if (!(shmflg & SHM_HUGETLB))
file->f_op = &shm_file_operations;
+
shm_tot += numpages;
shm_unlock(shp);
return shp->id;
diff --git a/kernel/Makefile b/kernel/Makefile
index ff4dc02ce170..4f5a1453093a 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -22,7 +22,6 @@ obj-$(CONFIG_KEXEC) += kexec.o
obj-$(CONFIG_COMPAT) += compat.o
obj-$(CONFIG_CPUSETS) += cpuset.o
obj-$(CONFIG_IKCONFIG) += configs.o
-obj-$(CONFIG_IKCONFIG_PROC) += configs.o
obj-$(CONFIG_STOP_MACHINE) += stop_machine.o
obj-$(CONFIG_AUDIT) += audit.o
obj-$(CONFIG_AUDITSYSCALL) += auditsc.o
@@ -32,6 +31,7 @@ obj-$(CONFIG_DETECT_SOFTLOCKUP) += softlockup.o
obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_SECCOMP) += seccomp.o
+obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o
ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y)
# According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
diff --git a/kernel/acct.c b/kernel/acct.c
index b756f527497e..2e3f4a47e7d0 100644
--- a/kernel/acct.c
+++ b/kernel/acct.c
@@ -553,7 +553,7 @@ void acct_update_integrals(struct task_struct *tsk)
if (delta == 0)
return;
tsk->acct_stimexpd = tsk->stime;
- tsk->acct_rss_mem1 += delta * get_mm_counter(tsk->mm, rss);
+ tsk->acct_rss_mem1 += delta * get_mm_rss(tsk->mm);
tsk->acct_vm_mem1 += delta * tsk->mm->total_vm;
}
}
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 53d8263ae12e..3619e939182e 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -17,6 +17,7 @@
/* This protects CPUs going up and down... */
DECLARE_MUTEX(cpucontrol);
+EXPORT_SYMBOL_GPL(cpucontrol);
static struct notifier_block *cpu_chain;
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 28176d083f7b..5a737ed9dac7 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -32,6 +32,7 @@
#include <linux/kernel.h>
#include <linux/kmod.h>
#include <linux/list.h>
+#include <linux/mempolicy.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/mount.h>
@@ -60,6 +61,9 @@ struct cpuset {
cpumask_t cpus_allowed; /* CPUs allowed to tasks in cpuset */
nodemask_t mems_allowed; /* Memory Nodes allowed to tasks */
+ /*
+ * Count is atomic so can incr (fork) or decr (exit) without a lock.
+ */
atomic_t count; /* count tasks using this cpuset */
/*
@@ -142,80 +146,91 @@ static struct vfsmount *cpuset_mount;
static struct super_block *cpuset_sb = NULL;
/*
- * cpuset_sem should be held by anyone who is depending on the children
- * or sibling lists of any cpuset, or performing non-atomic operations
- * on the flags or *_allowed values of a cpuset, such as raising the
- * CS_REMOVED flag bit iff it is not already raised, or reading and
- * conditionally modifying the *_allowed values. One kernel global
- * cpuset semaphore should be sufficient - these things don't change
- * that much.
- *
- * The code that modifies cpusets holds cpuset_sem across the entire
- * operation, from cpuset_common_file_write() down, single threading
- * all cpuset modifications (except for counter manipulations from
- * fork and exit) across the system. This presumes that cpuset
- * modifications are rare - better kept simple and safe, even if slow.
- *
- * The code that reads cpusets, such as in cpuset_common_file_read()
- * and below, only holds cpuset_sem across small pieces of code, such
- * as when reading out possibly multi-word cpumasks and nodemasks, as
- * the risks are less, and the desire for performance a little greater.
- * The proc_cpuset_show() routine needs to hold cpuset_sem to insure
- * that no cs->dentry is NULL, as it walks up the cpuset tree to root.
- *
- * The hooks from fork and exit, cpuset_fork() and cpuset_exit(), don't
- * (usually) grab cpuset_sem. These are the two most performance
- * critical pieces of code here. The exception occurs on exit(),
- * when a task in a notify_on_release cpuset exits. Then cpuset_sem
+ * We have two global cpuset semaphores below. They can nest.
+ * It is ok to first take manage_sem, then nest callback_sem. We also
+ * require taking task_lock() when dereferencing a tasks cpuset pointer.
+ * See "The task_lock() exception", at the end of this comment.
+ *
+ * A task must hold both semaphores to modify cpusets. If a task
+ * holds manage_sem, then it blocks others wanting that semaphore,
+ * ensuring that it is the only task able to also acquire callback_sem
+ * and be able to modify cpusets. It can perform various checks on
+ * the cpuset structure first, knowing nothing will change. It can
+ * also allocate memory while just holding manage_sem. While it is
+ * performing these checks, various callback routines can briefly
+ * acquire callback_sem to query cpusets. Once it is ready to make
+ * the changes, it takes callback_sem, blocking everyone else.
+ *
+ * Calls to the kernel memory allocator can not be made while holding
+ * callback_sem, as that would risk double tripping on callback_sem
+ * from one of the callbacks into the cpuset code from within
+ * __alloc_pages().
+ *
+ * If a task is only holding callback_sem, then it has read-only
+ * access to cpusets.
+ *
+ * The task_struct fields mems_allowed and mems_generation may only
+ * be accessed in the context of that task, so require no locks.
+ *
+ * Any task can increment and decrement the count field without lock.
+ * So in general, code holding manage_sem or callback_sem can't rely
+ * on the count field not changing. However, if the count goes to
+ * zero, then only attach_task(), which holds both semaphores, can
+ * increment it again. Because a count of zero means that no tasks
+ * are currently attached, therefore there is no way a task attached
+ * to that cpuset can fork (the other way to increment the count).
+ * So code holding manage_sem or callback_sem can safely assume that
+ * if the count is zero, it will stay zero. Similarly, if a task
+ * holds manage_sem or callback_sem on a cpuset with zero count, it
+ * knows that the cpuset won't be removed, as cpuset_rmdir() needs
+ * both of those semaphores.
+ *
+ * A possible optimization to improve parallelism would be to make
+ * callback_sem a R/W semaphore (rwsem), allowing the callback routines
+ * to proceed in parallel, with read access, until the holder of
+ * manage_sem needed to take this rwsem for exclusive write access
+ * and modify some cpusets.
+ *
+ * The cpuset_common_file_write handler for operations that modify
+ * the cpuset hierarchy holds manage_sem across the entire operation,
+ * single threading all such cpuset modifications across the system.
+ *
+ * The cpuset_common_file_read() handlers only hold callback_sem across
+ * small pieces of code, such as when reading out possibly multi-word
+ * cpumasks and nodemasks.
+ *
+ * The fork and exit callbacks cpuset_fork() and cpuset_exit(), don't
+ * (usually) take either semaphore. These are the two most performance
+ * critical pieces of code here. The exception occurs on cpuset_exit(),
+ * when a task in a notify_on_release cpuset exits. Then manage_sem
* is taken, and if the cpuset count is zero, a usermode call made
* to /sbin/cpuset_release_agent with the name of the cpuset (path
* relative to the root of cpuset file system) as the argument.
*
- * A cpuset can only be deleted if both its 'count' of using tasks is
- * zero, and its list of 'children' cpusets is empty. Since all tasks
- * in the system use _some_ cpuset, and since there is always at least
- * one task in the system (init, pid == 1), therefore, top_cpuset
- * always has either children cpusets and/or using tasks. So no need
- * for any special hack to ensure that top_cpuset cannot be deleted.
+ * A cpuset can only be deleted if both its 'count' of using tasks
+ * is zero, and its list of 'children' cpusets is empty. Since all
+ * tasks in the system use _some_ cpuset, and since there is always at
+ * least one task in the system (init, pid == 1), therefore, top_cpuset
+ * always has either children cpusets and/or using tasks. So we don't
+ * need a special hack to ensure that top_cpuset cannot be deleted.
+ *
+ * The above "Tale of Two Semaphores" would be complete, but for:
+ *
+ * The task_lock() exception
+ *
+ * The need for this exception arises from the action of attach_task(),
+ * which overwrites one tasks cpuset pointer with another. It does
+ * so using both semaphores, however there are several performance
+ * critical places that need to reference task->cpuset without the
+ * expense of grabbing a system global semaphore. Therefore except as
+ * noted below, when dereferencing or, as in attach_task(), modifying
+ * a tasks cpuset pointer we use task_lock(), which acts on a spinlock
+ * (task->alloc_lock) already in the task_struct routinely used for
+ * such matters.
*/
-static DECLARE_MUTEX(cpuset_sem);
-static struct task_struct *cpuset_sem_owner;
-static int cpuset_sem_depth;
-
-/*
- * The global cpuset semaphore cpuset_sem can be needed by the
- * memory allocator to update a tasks mems_allowed (see the calls
- * to cpuset_update_current_mems_allowed()) or to walk up the
- * cpuset hierarchy to find a mem_exclusive cpuset see the calls
- * to cpuset_excl_nodes_overlap()).
- *
- * But if the memory allocation is being done by cpuset.c code, it
- * usually already holds cpuset_sem. Double tripping on a kernel
- * semaphore deadlocks the current task, and any other task that
- * subsequently tries to obtain the lock.
- *
- * Run all up's and down's on cpuset_sem through the following
- * wrappers, which will detect this nested locking, and avoid
- * deadlocking.
- */
-
-static inline void cpuset_down(struct semaphore *psem)
-{
- if (cpuset_sem_owner != current) {
- down(psem);
- cpuset_sem_owner = current;
- }
- cpuset_sem_depth++;
-}
-
-static inline void cpuset_up(struct semaphore *psem)
-{
- if (--cpuset_sem_depth == 0) {
- cpuset_sem_owner = NULL;
- up(psem);
- }
-}
+static DECLARE_MUTEX(manage_sem);
+static DECLARE_MUTEX(callback_sem);
/*
* A couple of forward declarations required, due to cyclic reference loop:
@@ -390,7 +405,7 @@ static inline struct cftype *__d_cft(struct dentry *dentry)
}
/*
- * Call with cpuset_sem held. Writes path of cpuset into buf.
+ * Call with manage_sem held. Writes path of cpuset into buf.
* Returns 0 on success, -errno on error.
*/
@@ -442,10 +457,11 @@ static int cpuset_path(const struct cpuset *cs, char *buf, int buflen)
* status of the /sbin/cpuset_release_agent task, so no sense holding
* our caller up for that.
*
- * The simple act of forking that task might require more memory,
- * which might need cpuset_sem. So this routine must be called while
- * cpuset_sem is not held, to avoid a possible deadlock. See also
- * comments for check_for_release(), below.
+ * When we had only one cpuset semaphore, we had to call this
+ * without holding it, to avoid deadlock when call_usermodehelper()
+ * allocated memory. With two locks, we could now call this while
+ * holding manage_sem, but we still don't, so as to minimize
+ * the time manage_sem is held.
*/
static void cpuset_release_agent(const char *pathbuf)
@@ -477,15 +493,15 @@ static void cpuset_release_agent(const char *pathbuf)
* cs is notify_on_release() and now both the user count is zero and
* the list of children is empty, prepare cpuset path in a kmalloc'd
* buffer, to be returned via ppathbuf, so that the caller can invoke
- * cpuset_release_agent() with it later on, once cpuset_sem is dropped.
- * Call here with cpuset_sem held.
+ * cpuset_release_agent() with it later on, once manage_sem is dropped.
+ * Call here with manage_sem held.
*
* This check_for_release() routine is responsible for kmalloc'ing
* pathbuf. The above cpuset_release_agent() is responsible for
* kfree'ing pathbuf. The caller of these routines is responsible
* for providing a pathbuf pointer, initialized to NULL, then
- * calling check_for_release() with cpuset_sem held and the address
- * of the pathbuf pointer, then dropping cpuset_sem, then calling
+ * calling check_for_release() with manage_sem held and the address
+ * of the pathbuf pointer, then dropping manage_sem, then calling
* cpuset_release_agent() with pathbuf, as set by check_for_release().
*/
@@ -516,7 +532,7 @@ static void check_for_release(struct cpuset *cs, char **ppathbuf)
* One way or another, we guarantee to return some non-empty subset
* of cpu_online_map.
*
- * Call with cpuset_sem held.
+ * Call with callback_sem held.
*/
static void guarantee_online_cpus(const struct cpuset *cs, cpumask_t *pmask)
@@ -540,7 +556,7 @@ static void guarantee_online_cpus(const struct cpuset *cs, cpumask_t *pmask)
* One way or another, we guarantee to return some non-empty subset
* of node_online_map.
*
- * Call with cpuset_sem held.
+ * Call with callback_sem held.
*/
static void guarantee_online_mems(const struct cpuset *cs, nodemask_t *pmask)
@@ -555,22 +571,47 @@ static void guarantee_online_mems(const struct cpuset *cs, nodemask_t *pmask)
}
/*
- * Refresh current tasks mems_allowed and mems_generation from
- * current tasks cpuset. Call with cpuset_sem held.
+ * Refresh current tasks mems_allowed and mems_generation from current
+ * tasks cpuset.
*
- * This routine is needed to update the per-task mems_allowed
- * data, within the tasks context, when it is trying to allocate
- * memory (in various mm/mempolicy.c routines) and notices
- * that some other task has been modifying its cpuset.
+ * Call without callback_sem or task_lock() held. May be called with
+ * or without manage_sem held. Will acquire task_lock() and might
+ * acquire callback_sem during call.
+ *
+ * The task_lock() is required to dereference current->cpuset safely.
+ * Without it, we could pick up the pointer value of current->cpuset
+ * in one instruction, and then attach_task could give us a different
+ * cpuset, and then the cpuset we had could be removed and freed,
+ * and then on our next instruction, we could dereference a no longer
+ * valid cpuset pointer to get its mems_generation field.
+ *
+ * This routine is needed to update the per-task mems_allowed data,
+ * within the tasks context, when it is trying to allocate memory
+ * (in various mm/mempolicy.c routines) and notices that some other
+ * task has been modifying its cpuset.
*/
static void refresh_mems(void)
{
- struct cpuset *cs = current->cpuset;
+ int my_cpusets_mem_gen;
+
+ task_lock(current);
+ my_cpusets_mem_gen = current->cpuset->mems_generation;
+ task_unlock(current);
- if (current->cpuset_mems_generation != cs->mems_generation) {
+ if (current->cpuset_mems_generation != my_cpusets_mem_gen) {
+ struct cpuset *cs;
+ nodemask_t oldmem = current->mems_allowed;
+
+ down(&callback_sem);
+ task_lock(current);
+ cs = current->cpuset;
guarantee_online_mems(cs, &current->mems_allowed);
current->cpuset_mems_generation = cs->mems_generation;
+ task_unlock(current);
+ up(&callback_sem);
+ if (!nodes_equal(oldmem, current->mems_allowed))
+ numa_policy_rebind(&oldmem, &current->mems_allowed);
}
}
@@ -579,7 +620,7 @@ static void refresh_mems(void)
*
* One cpuset is a subset of another if all its allowed CPUs and
* Memory Nodes are a subset of the other, and its exclusive flags
- * are only set if the other's are set.
+ * are only set if the other's are set. Call holding manage_sem.
*/
static int is_cpuset_subset(const struct cpuset *p, const struct cpuset *q)
@@ -597,7 +638,7 @@ static int is_cpuset_subset(const struct cpuset *p, const struct cpuset *q)
* If we replaced the flag and mask values of the current cpuset
* (cur) with those values in the trial cpuset (trial), would
* our various subset and exclusive rules still be valid? Presumes
- * cpuset_sem held.
+ * manage_sem held.
*
* 'cur' is the address of an actual, in-use cpuset. Operations
* such as list traversal that depend on the actual address of the
@@ -651,7 +692,7 @@ static int validate_change(const struct cpuset *cur, const struct cpuset *trial)
* exclusive child cpusets
* Build these two partitions by calling partition_sched_domains
*
- * Call with cpuset_sem held. May nest a call to the
+ * Call with manage_sem held. May nest a call to the
* lock_cpu_hotplug()/unlock_cpu_hotplug() pair.
*/
@@ -696,6 +737,10 @@ static void update_cpu_domains(struct cpuset *cur)
unlock_cpu_hotplug();
}
+/*
+ * Call with manage_sem held. May take callback_sem during call.
+ */
+
static int update_cpumask(struct cpuset *cs, char *buf)
{
struct cpuset trialcs;
@@ -712,12 +757,18 @@ static int update_cpumask(struct cpuset *cs, char *buf)
if (retval < 0)
return retval;
cpus_unchanged = cpus_equal(cs->cpus_allowed, trialcs.cpus_allowed);
+ down(&callback_sem);
cs->cpus_allowed = trialcs.cpus_allowed;
+ up(&callback_sem);
if (is_cpu_exclusive(cs) && !cpus_unchanged)
update_cpu_domains(cs);
return 0;
}
+/*
+ * Call with manage_sem held. May take callback_sem during call.
+ */
+
static int update_nodemask(struct cpuset *cs, char *buf)
{
struct cpuset trialcs;
@@ -732,9 +783,11 @@ static int update_nodemask(struct cpuset *cs, char *buf)
return -ENOSPC;
retval = validate_change(cs, &trialcs);
if (retval == 0) {
+ down(&callback_sem);
cs->mems_allowed = trialcs.mems_allowed;
atomic_inc(&cpuset_mems_generation);
cs->mems_generation = atomic_read(&cpuset_mems_generation);
+ up(&callback_sem);
}
return retval;
}
@@ -745,6 +798,8 @@ static int update_nodemask(struct cpuset *cs, char *buf)
* CS_NOTIFY_ON_RELEASE)
* cs: the cpuset to update
* buf: the buffer where we read the 0 or 1
+ *
+ * Call with manage_sem held.
*/
static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, char *buf)
@@ -766,16 +821,27 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, char *buf)
return err;
cpu_exclusive_changed =
(is_cpu_exclusive(cs) != is_cpu_exclusive(&trialcs));
+ down(&callback_sem);
if (turning_on)
set_bit(bit, &cs->flags);
else
clear_bit(bit, &cs->flags);
+ up(&callback_sem);
if (cpu_exclusive_changed)
update_cpu_domains(cs);
return 0;
}
+/*
+ * Attack task specified by pid in 'pidbuf' to cpuset 'cs', possibly
+ * writing the path of the old cpuset in 'ppathbuf' if it needs to be
+ * notified on release.
+ *
+ * Call holding manage_sem. May take callback_sem and task_lock of
+ * the task 'pid' during call.
+ */
+
static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
{
pid_t pid;
@@ -792,7 +858,7 @@ static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
read_lock(&tasklist_lock);
tsk = find_task_by_pid(pid);
- if (!tsk) {
+ if (!tsk || tsk->flags & PF_EXITING) {
read_unlock(&tasklist_lock);
return -ESRCH;
}
@@ -810,10 +876,13 @@ static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
get_task_struct(tsk);
}
+ down(&callback_sem);
+
task_lock(tsk);
oldcs = tsk->cpuset;
if (!oldcs) {
task_unlock(tsk);
+ up(&callback_sem);
put_task_struct(tsk);
return -ESRCH;
}
@@ -824,6 +893,7 @@ static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
guarantee_online_cpus(cs, &cpus);
set_cpus_allowed(tsk, cpus);
+ up(&callback_sem);
put_task_struct(tsk);
if (atomic_dec_and_test(&oldcs->count))
check_for_release(oldcs, ppathbuf);
@@ -867,7 +937,7 @@ static ssize_t cpuset_common_file_write(struct file *file, const char __user *us
}
buffer[nbytes] = 0; /* nul-terminate */
- cpuset_down(&cpuset_sem);
+ down(&manage_sem);
if (is_removed(cs)) {
retval = -ENODEV;
@@ -901,7 +971,7 @@ static ssize_t cpuset_common_file_write(struct file *file, const char __user *us
if (retval == 0)
retval = nbytes;
out2:
- cpuset_up(&cpuset_sem);
+ up(&manage_sem);
cpuset_release_agent(pathbuf);
out1:
kfree(buffer);
@@ -941,9 +1011,9 @@ static int cpuset_sprintf_cpulist(char *page, struct cpuset *cs)
{
cpumask_t mask;
- cpuset_down(&cpuset_sem);
+ down(&callback_sem);
mask = cs->cpus_allowed;
- cpuset_up(&cpuset_sem);
+ up(&callback_sem);
return cpulist_scnprintf(page, PAGE_SIZE, mask);
}
@@ -952,9 +1022,9 @@ static int cpuset_sprintf_memlist(char *page, struct cpuset *cs)
{
nodemask_t mask;
- cpuset_down(&cpuset_sem);
+ down(&callback_sem);
mask = cs->mems_allowed;
- cpuset_up(&cpuset_sem);
+ up(&callback_sem);
return nodelist_scnprintf(page, PAGE_SIZE, mask);
}
@@ -995,7 +1065,6 @@ static ssize_t cpuset_common_file_read(struct file *file, char __user *buf,
goto out;
}
*s++ = '\n';
- *s = '\0';
retval = simple_read_from_buffer(buf, nbytes, ppos, page, s - page);
out:
@@ -1048,6 +1117,21 @@ static int cpuset_file_release(struct inode *inode, struct file *file)
return 0;
}
+/*
+ * cpuset_rename - Only allow simple rename of directories in place.
+ */
+static int cpuset_rename(struct inode *old_dir, struct dentry *old_dentry,
+ struct inode *new_dir, struct dentry *new_dentry)
+{
+ if (!S_ISDIR(old_dentry->d_inode->i_mode))
+ return -ENOTDIR;
+ if (new_dentry->d_inode)
+ return -EEXIST;
+ if (old_dir != new_dir)
+ return -EIO;
+ return simple_rename(old_dir, old_dentry, new_dir, new_dentry);
+}
+
static struct file_operations cpuset_file_operations = {
.read = cpuset_file_read,
.write = cpuset_file_write,
@@ -1060,6 +1144,7 @@ static struct inode_operations cpuset_dir_inode_operations = {
.lookup = simple_lookup,
.mkdir = cpuset_mkdir,
.rmdir = cpuset_rmdir,
+ .rename = cpuset_rename,
};
static int cpuset_create_file(struct dentry *dentry, int mode)
@@ -1163,7 +1248,9 @@ struct ctr_struct {
/*
* Load into 'pidarray' up to 'npids' of the tasks using cpuset 'cs'.
- * Return actual number of pids loaded.
+ * Return actual number of pids loaded. No need to task_lock(p)
+ * when reading out p->cpuset, as we don't really care if it changes
+ * on the next cycle, and we are not going to try to dereference it.
*/
static inline int pid_array_load(pid_t *pidarray, int npids, struct cpuset *cs)
{
@@ -1205,6 +1292,12 @@ static int pid_array_to_buf(char *buf, int sz, pid_t *a, int npids)
return cnt;
}
+/*
+ * Handle an open on 'tasks' file. Prepare a buffer listing the
+ * process id's of tasks currently attached to the cpuset being opened.
+ *
+ * Does not require any specific cpuset semaphores, and does not take any.
+ */
static int cpuset_tasks_open(struct inode *unused, struct file *file)
{
struct cpuset *cs = __d_cs(file->f_dentry->d_parent);
@@ -1352,7 +1445,8 @@ static long cpuset_create(struct cpuset *parent, const char *name, int mode)
if (!cs)
return -ENOMEM;
- cpuset_down(&cpuset_sem);
+ down(&manage_sem);
+ refresh_mems();
cs->flags = 0;
if (notify_on_release(parent))
set_bit(CS_NOTIFY_ON_RELEASE, &cs->flags);
@@ -1366,25 +1460,27 @@ static long cpuset_create(struct cpuset *parent, const char *name, int mode)
cs->parent = parent;
+ down(&callback_sem);
list_add(&cs->sibling, &cs->parent->children);
+ up(&callback_sem);
err = cpuset_create_dir(cs, name, mode);
if (err < 0)
goto err;
/*
- * Release cpuset_sem before cpuset_populate_dir() because it
+ * Release manage_sem before cpuset_populate_dir() because it
* will down() this new directory's i_sem and if we race with
* another mkdir, we might deadlock.
*/
- cpuset_up(&cpuset_sem);
+ up(&manage_sem);
err = cpuset_populate_dir(cs->dentry);
/* If err < 0, we have a half-filled directory - oh well ;) */
return 0;
err:
list_del(&cs->sibling);
- cpuset_up(&cpuset_sem);
+ up(&manage_sem);
kfree(cs);
return err;
}
@@ -1406,29 +1502,32 @@ static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry)
/* the vfs holds both inode->i_sem already */
- cpuset_down(&cpuset_sem);
+ down(&manage_sem);
+ refresh_mems();
if (atomic_read(&cs->count) > 0) {
- cpuset_up(&cpuset_sem);
+ up(&manage_sem);
return -EBUSY;
}
if (!list_empty(&cs->children)) {
- cpuset_up(&cpuset_sem);
+ up(&manage_sem);
return -EBUSY;
}
parent = cs->parent;
+ down(&callback_sem);
set_bit(CS_REMOVED, &cs->flags);
if (is_cpu_exclusive(cs))
update_cpu_domains(cs);
list_del(&cs->sibling); /* delete my sibling from parent->children */
- if (list_empty(&parent->children))
- check_for_release(parent, &pathbuf);
spin_lock(&cs->dentry->d_lock);
d = dget(cs->dentry);
cs->dentry = NULL;
spin_unlock(&d->d_lock);
cpuset_d_remove_dir(d);
dput(d);
- cpuset_up(&cpuset_sem);
+ up(&callback_sem);
+ if (list_empty(&parent->children))
+ check_for_release(parent, &pathbuf);
+ up(&manage_sem);
cpuset_release_agent(pathbuf);
return 0;
}
@@ -1488,16 +1587,26 @@ void __init cpuset_init_smp(void)
* cpuset_fork - attach newly forked task to its parents cpuset.
* @tsk: pointer to task_struct of forking parent process.
*
- * Description: By default, on fork, a task inherits its
- * parent's cpuset. The pointer to the shared cpuset is
- * automatically copied in fork.c by dup_task_struct().
- * This cpuset_fork() routine need only increment the usage
- * counter in that cpuset.
+ * Description: A task inherits its parent's cpuset at fork().
+ *
+ * A pointer to the shared cpuset was automatically copied in fork.c
+ * by dup_task_struct(). However, we ignore that copy, since it was
+ * not made under the protection of task_lock(), so might no longer be
+ * a valid cpuset pointer. attach_task() might have already changed
+ * current->cpuset, allowing the previously referenced cpuset to
+ * be removed and freed. Instead, we task_lock(current) and copy
+ * its present value of current->cpuset for our freshly forked child.
+ *
+ * At the point that cpuset_fork() is called, 'current' is the parent
+ * task, and the passed argument 'child' points to the child task.
**/
-void cpuset_fork(struct task_struct *tsk)
+void cpuset_fork(struct task_struct *child)
{
- atomic_inc(&tsk->cpuset->count);
+ task_lock(current);
+ child->cpuset = current->cpuset;
+ atomic_inc(&child->cpuset->count);
+ task_unlock(current);
}
/**
@@ -1506,35 +1615,42 @@ void cpuset_fork(struct task_struct *tsk)
*
* Description: Detach cpuset from @tsk and release it.
*
- * Note that cpusets marked notify_on_release force every task
- * in them to take the global cpuset_sem semaphore when exiting.
- * This could impact scaling on very large systems. Be reluctant
- * to use notify_on_release cpusets where very high task exit
- * scaling is required on large systems.
- *
- * Don't even think about derefencing 'cs' after the cpuset use
- * count goes to zero, except inside a critical section guarded
- * by the cpuset_sem semaphore. If you don't hold cpuset_sem,
- * then a zero cpuset use count is a license to any other task to
- * nuke the cpuset immediately.
+ * Note that cpusets marked notify_on_release force every task in
+ * them to take the global manage_sem semaphore when exiting.
+ * This could impact scaling on very large systems. Be reluctant to
+ * use notify_on_release cpusets where very high task exit scaling
+ * is required on large systems.
+ *
+ * Don't even think about derefencing 'cs' after the cpuset use count
+ * goes to zero, except inside a critical section guarded by manage_sem
+ * or callback_sem. Otherwise a zero cpuset use count is a license to
+ * any other task to nuke the cpuset immediately, via cpuset_rmdir().
+ *
+ * This routine has to take manage_sem, not callback_sem, because
+ * it is holding that semaphore while calling check_for_release(),
+ * which calls kmalloc(), so can't be called holding callback__sem().
+ *
+ * We don't need to task_lock() this reference to tsk->cpuset,
+ * because tsk is already marked PF_EXITING, so attach_task() won't
+ * mess with it.
**/
void cpuset_exit(struct task_struct *tsk)
{
struct cpuset *cs;
- task_lock(tsk);
+ BUG_ON(!(tsk->flags & PF_EXITING));
+
cs = tsk->cpuset;
tsk->cpuset = NULL;
- task_unlock(tsk);
if (notify_on_release(cs)) {
char *pathbuf = NULL;
- cpuset_down(&cpuset_sem);
+ down(&manage_sem);
if (atomic_dec_and_test(&cs->count))
check_for_release(cs, &pathbuf);
- cpuset_up(&cpuset_sem);
+ up(&manage_sem);
cpuset_release_agent(pathbuf);
} else {
atomic_dec(&cs->count);
@@ -1555,11 +1671,11 @@ cpumask_t cpuset_cpus_allowed(const struct task_struct *tsk)
{
cpumask_t mask;
- cpuset_down(&cpuset_sem);
+ down(&callback_sem);
task_lock((struct task_struct *)tsk);
guarantee_online_cpus(tsk->cpuset, &mask);
task_unlock((struct task_struct *)tsk);
- cpuset_up(&cpuset_sem);
+ up(&callback_sem);
return mask;
}
@@ -1575,19 +1691,28 @@ void cpuset_init_current_mems_allowed(void)
* If the current tasks cpusets mems_allowed changed behind our backs,
* update current->mems_allowed and mems_generation to the new value.
* Do not call this routine if in_interrupt().
+ *
+ * Call without callback_sem or task_lock() held. May be called
+ * with or without manage_sem held. Unless exiting, it will acquire
+ * task_lock(). Also might acquire callback_sem during call to
+ * refresh_mems().
*/
void cpuset_update_current_mems_allowed(void)
{
- struct cpuset *cs = current->cpuset;
+ struct cpuset *cs;
+ int need_to_refresh = 0;
+ task_lock(current);
+ cs = current->cpuset;
if (!cs)
- return; /* task is exiting */
- if (current->cpuset_mems_generation != cs->mems_generation) {
- cpuset_down(&cpuset_sem);
+ goto done;
+ if (current->cpuset_mems_generation != cs->mems_generation)
+ need_to_refresh = 1;
+done:
+ task_unlock(current);
+ if (need_to_refresh)
refresh_mems();
- cpuset_up(&cpuset_sem);
- }
}
/**
@@ -1621,7 +1746,7 @@ int cpuset_zonelist_valid_mems_allowed(struct zonelist *zl)
/*
* nearest_exclusive_ancestor() - Returns the nearest mem_exclusive
- * ancestor to the specified cpuset. Call while holding cpuset_sem.
+ * ancestor to the specified cpuset. Call holding callback_sem.
* If no ancestor is mem_exclusive (an unusual configuration), then
* returns the root cpuset.
*/
@@ -1648,12 +1773,12 @@ static const struct cpuset *nearest_exclusive_ancestor(const struct cpuset *cs)
* GFP_KERNEL allocations are not so marked, so can escape to the
* nearest mem_exclusive ancestor cpuset.
*
- * Scanning up parent cpusets requires cpuset_sem. The __alloc_pages()
+ * Scanning up parent cpusets requires callback_sem. The __alloc_pages()
* routine only calls here with __GFP_HARDWALL bit _not_ set if
* it's a GFP_KERNEL allocation, and all nodes in the current tasks
* mems_allowed came up empty on the first pass over the zonelist.
* So only GFP_KERNEL allocations, if all nodes in the cpuset are
- * short of memory, might require taking the cpuset_sem semaphore.
+ * short of memory, might require taking the callback_sem semaphore.
*
* The first loop over the zonelist in mm/page_alloc.c:__alloc_pages()
* calls here with __GFP_HARDWALL always set in gfp_mask, enforcing
@@ -1685,14 +1810,16 @@ int cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask)
return 0;
/* Not hardwall and node outside mems_allowed: scan up cpusets */
- cpuset_down(&cpuset_sem);
- cs = current->cpuset;
- if (!cs)
- goto done; /* current task exiting */
- cs = nearest_exclusive_ancestor(cs);
+ down(&callback_sem);
+
+ if (current->flags & PF_EXITING) /* Let dying task have memory */
+ return 1;
+ task_lock(current);
+ cs = nearest_exclusive_ancestor(current->cpuset);
+ task_unlock(current);
+
allowed = node_isset(node, cs->mems_allowed);
-done:
- cpuset_up(&cpuset_sem);
+ up(&callback_sem);
return allowed;
}
@@ -1705,7 +1832,7 @@ done:
* determine if task @p's memory usage might impact the memory
* available to the current task.
*
- * Acquires cpuset_sem - not suitable for calling from a fast path.
+ * Acquires callback_sem - not suitable for calling from a fast path.
**/
int cpuset_excl_nodes_overlap(const struct task_struct *p)
@@ -1713,18 +1840,27 @@ int cpuset_excl_nodes_overlap(const struct task_struct *p)
const struct cpuset *cs1, *cs2; /* my and p's cpuset ancestors */
int overlap = 0; /* do cpusets overlap? */
- cpuset_down(&cpuset_sem);
- cs1 = current->cpuset;
- if (!cs1)
- goto done; /* current task exiting */
- cs2 = p->cpuset;
- if (!cs2)
- goto done; /* task p is exiting */
- cs1 = nearest_exclusive_ancestor(cs1);
- cs2 = nearest_exclusive_ancestor(cs2);
+ down(&callback_sem);
+
+ task_lock(current);
+ if (current->flags & PF_EXITING) {
+ task_unlock(current);
+ goto done;
+ }
+ cs1 = nearest_exclusive_ancestor(current->cpuset);
+ task_unlock(current);
+
+ task_lock((struct task_struct *)p);
+ if (p->flags & PF_EXITING) {
+ task_unlock((struct task_struct *)p);
+ goto done;
+ }
+ cs2 = nearest_exclusive_ancestor(p->cpuset);
+ task_unlock((struct task_struct *)p);
+
overlap = nodes_intersects(cs1->mems_allowed, cs2->mems_allowed);
done:
- cpuset_up(&cpuset_sem);
+ up(&callback_sem);
return overlap;
}
@@ -1733,6 +1869,10 @@ done:
* proc_cpuset_show()
* - Print tasks cpuset path into seq_file.
* - Used for /proc/<pid>/cpuset.
+ * - No need to task_lock(tsk) on this tsk->cpuset reference, as it
+ * doesn't really matter if tsk->cpuset changes after we read it,
+ * and we take manage_sem, keeping attach_task() from changing it
+ * anyway.
*/
static int proc_cpuset_show(struct seq_file *m, void *v)
@@ -1747,10 +1887,8 @@ static int proc_cpuset_show(struct seq_file *m, void *v)
return -ENOMEM;
tsk = m->private;
- cpuset_down(&cpuset_sem);
- task_lock(tsk);
+ down(&manage_sem);
cs = tsk->cpuset;
- task_unlock(tsk);
if (!cs) {
retval = -EINVAL;
goto out;
@@ -1762,7 +1900,7 @@ static int proc_cpuset_show(struct seq_file *m, void *v)
seq_puts(m, buf);
seq_putc(m, '\n');
out:
- cpuset_up(&cpuset_sem);
+ up(&manage_sem);
kfree(buf);
return retval;
}
diff --git a/kernel/exit.c b/kernel/exit.c
index 3b25b182d2be..537394b25e8d 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -547,7 +547,7 @@ static inline void reparent_thread(task_t *p, task_t *father, int traced)
if (p->pdeath_signal)
/* We already hold the tasklist_lock here. */
- group_send_sig_info(p->pdeath_signal, (void *) 0, p);
+ group_send_sig_info(p->pdeath_signal, SEND_SIG_NOINFO, p);
/* Move the child from its dying parent to the new one. */
if (unlikely(traced)) {
@@ -591,8 +591,8 @@ static inline void reparent_thread(task_t *p, task_t *father, int traced)
int pgrp = process_group(p);
if (will_become_orphaned_pgrp(pgrp, NULL) && has_stopped_jobs(pgrp)) {
- __kill_pg_info(SIGHUP, (void *)1, pgrp);
- __kill_pg_info(SIGCONT, (void *)1, pgrp);
+ __kill_pg_info(SIGHUP, SEND_SIG_PRIV, pgrp);
+ __kill_pg_info(SIGCONT, SEND_SIG_PRIV, pgrp);
}
}
}
@@ -727,8 +727,8 @@ static void exit_notify(struct task_struct *tsk)
(t->signal->session == tsk->signal->session) &&
will_become_orphaned_pgrp(process_group(tsk), tsk) &&
has_stopped_jobs(process_group(tsk))) {
- __kill_pg_info(SIGHUP, (void *)1, process_group(tsk));
- __kill_pg_info(SIGCONT, (void *)1, process_group(tsk));
+ __kill_pg_info(SIGHUP, SEND_SIG_PRIV, process_group(tsk));
+ __kill_pg_info(SIGCONT, SEND_SIG_PRIV, process_group(tsk));
}
/* Let father know we died
@@ -783,10 +783,6 @@ static void exit_notify(struct task_struct *tsk)
/* If the process is dead, release it - nobody will wait for it */
if (state == EXIT_DEAD)
release_task(tsk);
-
- /* PF_DEAD causes final put_task_struct after we schedule. */
- preempt_disable();
- tsk->flags |= PF_DEAD;
}
fastcall NORET_TYPE void do_exit(long code)
@@ -839,7 +835,10 @@ fastcall NORET_TYPE void do_exit(long code)
preempt_count());
acct_update_integrals(tsk);
- update_mem_hiwater(tsk);
+ if (tsk->mm) {
+ update_hiwater_rss(tsk->mm);
+ update_hiwater_vm(tsk->mm);
+ }
group_dead = atomic_dec_and_test(&tsk->signal->live);
if (group_dead) {
del_timer_sync(&tsk->signal->real_timer);
@@ -870,7 +869,11 @@ fastcall NORET_TYPE void do_exit(long code)
tsk->mempolicy = NULL;
#endif
- BUG_ON(!(current->flags & PF_DEAD));
+ /* PF_DEAD causes final put_task_struct after we schedule. */
+ preempt_disable();
+ BUG_ON(tsk->flags & PF_DEAD);
+ tsk->flags |= PF_DEAD;
+
schedule();
BUG();
/* Avoid "noreturn function does return". */
@@ -1380,6 +1383,15 @@ repeat:
switch (p->state) {
case TASK_TRACED:
+ /*
+ * When we hit the race with PTRACE_ATTACH,
+ * we will not report this child. But the
+ * race means it has not yet been moved to
+ * our ptrace_children list, so we need to
+ * set the flag here to avoid a spurious ECHILD
+ * when the race happens with the only child.
+ */
+ flag = 1;
if (!my_ptrace_child(p))
continue;
/*FALLTHROUGH*/
diff --git a/kernel/fork.c b/kernel/fork.c
index 280bd44ac441..8a069612eac3 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -182,37 +182,37 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
}
#ifdef CONFIG_MMU
-static inline int dup_mmap(struct mm_struct * mm, struct mm_struct * oldmm)
+static inline int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
{
- struct vm_area_struct * mpnt, *tmp, **pprev;
+ struct vm_area_struct *mpnt, *tmp, **pprev;
struct rb_node **rb_link, *rb_parent;
int retval;
unsigned long charge;
struct mempolicy *pol;
down_write(&oldmm->mmap_sem);
- flush_cache_mm(current->mm);
+ flush_cache_mm(oldmm);
+ down_write(&mm->mmap_sem);
+
mm->locked_vm = 0;
mm->mmap = NULL;
mm->mmap_cache = NULL;
mm->free_area_cache = oldmm->mmap_base;
mm->cached_hole_size = ~0UL;
mm->map_count = 0;
- set_mm_counter(mm, rss, 0);
- set_mm_counter(mm, anon_rss, 0);
cpus_clear(mm->cpu_vm_mask);
mm->mm_rb = RB_ROOT;
rb_link = &mm->mm_rb.rb_node;
rb_parent = NULL;
pprev = &mm->mmap;
- for (mpnt = current->mm->mmap ; mpnt ; mpnt = mpnt->vm_next) {
+ for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) {
struct file *file;
if (mpnt->vm_flags & VM_DONTCOPY) {
long pages = vma_pages(mpnt);
mm->total_vm -= pages;
- __vm_stat_account(mm, mpnt->vm_flags, mpnt->vm_file,
+ vm_stat_account(mm, mpnt->vm_flags, mpnt->vm_file,
-pages);
continue;
}
@@ -253,12 +253,8 @@ static inline int dup_mmap(struct mm_struct * mm, struct mm_struct * oldmm)
}
/*
- * Link in the new vma and copy the page table entries:
- * link in first so that swapoff can see swap entries.
- * Note that, exceptionally, here the vma is inserted
- * without holding mm->mmap_sem.
+ * Link in the new vma and copy the page table entries.
*/
- spin_lock(&mm->page_table_lock);
*pprev = tmp;
pprev = &tmp->vm_next;
@@ -267,8 +263,7 @@ static inline int dup_mmap(struct mm_struct * mm, struct mm_struct * oldmm)
rb_parent = &tmp->vm_rb;
mm->map_count++;
- retval = copy_page_range(mm, current->mm, tmp);
- spin_unlock(&mm->page_table_lock);
+ retval = copy_page_range(mm, oldmm, tmp);
if (tmp->vm_ops && tmp->vm_ops->open)
tmp->vm_ops->open(tmp);
@@ -277,9 +272,9 @@ static inline int dup_mmap(struct mm_struct * mm, struct mm_struct * oldmm)
goto out;
}
retval = 0;
-
out:
- flush_tlb_mm(current->mm);
+ up_write(&mm->mmap_sem);
+ flush_tlb_mm(oldmm);
up_write(&oldmm->mmap_sem);
return retval;
fail_nomem_policy:
@@ -323,6 +318,8 @@ static struct mm_struct * mm_init(struct mm_struct * mm)
INIT_LIST_HEAD(&mm->mmlist);
mm->core_waiters = 0;
mm->nr_ptes = 0;
+ set_mm_counter(mm, file_rss, 0);
+ set_mm_counter(mm, anon_rss, 0);
spin_lock_init(&mm->page_table_lock);
rwlock_init(&mm->ioctx_list_lock);
mm->ioctx_list = NULL;
@@ -499,7 +496,7 @@ static int copy_mm(unsigned long clone_flags, struct task_struct * tsk)
if (retval)
goto free_pt;
- mm->hiwater_rss = get_mm_counter(mm,rss);
+ mm->hiwater_rss = get_mm_rss(mm);
mm->hiwater_vm = mm->total_vm;
good_mm:
diff --git a/kernel/futex.c b/kernel/futex.c
index ca05fe6a70b2..3b4d5ad44cc6 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -205,15 +205,13 @@ static int get_futex_key(unsigned long uaddr, union futex_key *key)
/*
* Do a quick atomic lookup first - this is the fastpath.
*/
- spin_lock(&current->mm->page_table_lock);
- page = follow_page(mm, uaddr, 0);
+ page = follow_page(mm, uaddr, FOLL_TOUCH|FOLL_GET);
if (likely(page != NULL)) {
key->shared.pgoff =
page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
- spin_unlock(&current->mm->page_table_lock);
+ put_page(page);
return 0;
}
- spin_unlock(&current->mm->page_table_lock);
/*
* Do it the general way.
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index 3ff7b925c387..51df337b37db 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -117,14 +117,16 @@ fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs)
/*
* No locking required for CPU-local interrupts:
*/
- desc->handler->ack(irq);
+ if (desc->handler->ack)
+ desc->handler->ack(irq);
action_ret = handle_IRQ_event(irq, regs, desc->action);
desc->handler->end(irq);
return 1;
}
spin_lock(&desc->lock);
- desc->handler->ack(irq);
+ if (desc->handler->ack)
+ desc->handler->ack(irq);
/*
* REPLAY is when Linux resends an IRQ that was dropped earlier
* WAITING is used by probe to mark irqs that are being tested
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index 13bcec151b57..39277dd6bf90 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -18,6 +18,7 @@
#include <linux/fs.h>
#include <linux/err.h>
#include <linux/proc_fs.h>
+#include <linux/sched.h> /* for cond_resched */
#include <linux/mm.h>
#include <asm/sections.h>
diff --git a/kernel/kexec.c b/kernel/kexec.c
index 36c5d9cd4cc1..2c95848fbce8 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -334,7 +334,7 @@ static struct page *kimage_alloc_pages(gfp_t gfp_mask, unsigned int order)
if (pages) {
unsigned int count, i;
pages->mapping = NULL;
- pages->private = order;
+ set_page_private(pages, order);
count = 1 << order;
for (i = 0; i < count; i++)
SetPageReserved(pages + i);
@@ -347,7 +347,7 @@ static void kimage_free_pages(struct page *page)
{
unsigned int order, count, i;
- order = page->private;
+ order = page_private(page);
count = 1 << order;
for (i = 0; i < count; i++)
ClearPageReserved(page + i);
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 44166e3bb8af..51a892063aaa 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -131,14 +131,14 @@ struct subprocess_info {
static int ____call_usermodehelper(void *data)
{
struct subprocess_info *sub_info = data;
- struct key *old_session;
+ struct key *new_session, *old_session;
int retval;
/* Unblock all signals and set the session keyring. */
- key_get(sub_info->ring);
+ new_session = key_get(sub_info->ring);
flush_signals(current);
spin_lock_irq(&current->sighand->siglock);
- old_session = __install_session_keyring(current, sub_info->ring);
+ old_session = __install_session_keyring(current, new_session);
flush_signal_handlers(current, 1);
sigemptyset(&current->blocked);
recalc_sigpending();
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index f3ea492ab44d..ce4915dd683a 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -35,6 +35,7 @@
#include <linux/spinlock.h>
#include <linux/hash.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/moduleloader.h>
#include <asm-generic/sections.h>
diff --git a/kernel/kthread.c b/kernel/kthread.c
index f50f174e92da..e75950a1092c 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -165,6 +165,12 @@ EXPORT_SYMBOL(kthread_bind);
int kthread_stop(struct task_struct *k)
{
+ return kthread_stop_sem(k, NULL);
+}
+EXPORT_SYMBOL(kthread_stop);
+
+int kthread_stop_sem(struct task_struct *k, struct semaphore *s)
+{
int ret;
down(&kthread_stop_lock);
@@ -178,7 +184,10 @@ int kthread_stop(struct task_struct *k)
/* Now set kthread_should_stop() to true, and wake it up. */
kthread_stop_info.k = k;
- wake_up_process(k);
+ if (s)
+ up(s);
+ else
+ wake_up_process(k);
put_task_struct(k);
/* Once it dies, reset stop ptr, gather result and we're done. */
@@ -189,7 +198,7 @@ int kthread_stop(struct task_struct *k)
return ret;
}
-EXPORT_SYMBOL(kthread_stop);
+EXPORT_SYMBOL(kthread_stop_sem);
static __init int helper_init(void)
{
diff --git a/kernel/params.c b/kernel/params.c
index 1a8614bac5d5..47ba69547945 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -23,6 +23,7 @@
#include <linux/module.h>
#include <linux/device.h>
#include <linux/err.h>
+#include <linux/slab.h>
#if 0
#define DEBUGP printk
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index bf374fceb39c..91a894264941 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -1225,7 +1225,7 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)
/*
* The task was cleaned up already, no future firings.
*/
- return;
+ goto out;
/*
* Fetch the current sample and update the timer's expiry time.
@@ -1235,7 +1235,7 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)
bump_cpu_timer(timer, now);
if (unlikely(p->exit_state)) {
clear_dead_task(timer, now);
- return;
+ goto out;
}
read_lock(&tasklist_lock); /* arm_timer needs it. */
} else {
@@ -1248,8 +1248,7 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)
put_task_struct(p);
timer->it.cpu.task = p = NULL;
timer->it.cpu.expires.sched = 0;
- read_unlock(&tasklist_lock);
- return;
+ goto out_unlock;
} else if (unlikely(p->exit_state) && thread_group_empty(p)) {
/*
* We've noticed that the thread is dead, but
@@ -1257,8 +1256,7 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)
* drop our task ref.
*/
clear_dead_task(timer, now);
- read_unlock(&tasklist_lock);
- return;
+ goto out_unlock;
}
cpu_clock_sample_group(timer->it_clock, p, &now);
bump_cpu_timer(timer, now);
@@ -1270,7 +1268,13 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)
*/
arm_timer(timer, now);
+out_unlock:
read_unlock(&tasklist_lock);
+
+out:
+ timer->it_overrun_last = timer->it_overrun;
+ timer->it_overrun = -1;
+ ++timer->it_requeue_pending;
}
/*
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index dda3cda73c77..ea55c7a1cd75 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -1295,13 +1295,6 @@ sys_clock_getres(clockid_t which_clock, struct timespec __user *tp)
return error;
}
-static void nanosleep_wake_up(unsigned long __data)
-{
- struct task_struct *p = (struct task_struct *) __data;
-
- wake_up_process(p);
-}
-
/*
* The standard says that an absolute nanosleep call MUST wake up at
* the requested time in spite of clock settings. Here is what we do:
@@ -1442,7 +1435,6 @@ static int common_nsleep(clockid_t which_clock,
int flags, struct timespec *tsave)
{
struct timespec t, dum;
- struct timer_list new_timer;
DECLARE_WAITQUEUE(abs_wqueue, current);
u64 rq_time = (u64)0;
s64 left;
@@ -1451,10 +1443,6 @@ static int common_nsleep(clockid_t which_clock,
&current_thread_info()->restart_block;
abs_wqueue.flags = 0;
- init_timer(&new_timer);
- new_timer.expires = 0;
- new_timer.data = (unsigned long) current;
- new_timer.function = nanosleep_wake_up;
abs = flags & TIMER_ABSTIME;
if (restart_block->fn == clock_nanosleep_restart) {
@@ -1490,13 +1478,8 @@ static int common_nsleep(clockid_t which_clock,
if (left < (s64)0)
break;
- new_timer.expires = jiffies + left;
- __set_current_state(TASK_INTERRUPTIBLE);
- add_timer(&new_timer);
-
- schedule();
+ schedule_timeout_interruptible(left);
- del_timer_sync(&new_timer);
left = rq_time - get_jiffies_64();
} while (left > (s64)0 && !test_thread_flag(TIF_SIGPENDING));
diff --git a/kernel/power/Makefile b/kernel/power/Makefile
index 2f438d0eaa13..c71eb4579c07 100644
--- a/kernel/power/Makefile
+++ b/kernel/power/Makefile
@@ -4,7 +4,7 @@ EXTRA_CFLAGS += -DDEBUG
endif
obj-y := main.o process.o console.o pm.o
-obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o disk.o
+obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o disk.o snapshot.o
obj-$(CONFIG_SUSPEND_SMP) += smp.o
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index 761956e813f5..027322a564f4 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -30,7 +30,6 @@ extern int swsusp_check(void);
extern int swsusp_read(void);
extern void swsusp_close(void);
extern int swsusp_resume(void);
-extern int swsusp_free(void);
static int noresume = 0;
@@ -93,10 +92,7 @@ static void free_some_memory(void)
printk("Freeing memory... ");
while ((tmp = shrink_all_memory(10000))) {
pages += tmp;
- printk("\b%c", p[i]);
- i++;
- if (i > 3)
- i = 0;
+ printk("\b%c", p[i++ % 4]);
}
printk("\bdone (%li pages freed)\n", pages);
}
@@ -178,13 +174,12 @@ int pm_suspend_disk(void)
goto Done;
if (in_suspend) {
+ device_resume();
pr_debug("PM: writing image.\n");
error = swsusp_write();
if (!error)
power_down(pm_disk_mode);
else {
- /* swsusp_write can not fail in device_resume,
- no need to do second device_resume */
swsusp_free();
unprepare_processes();
return error;
@@ -252,14 +247,17 @@ static int software_resume(void)
pr_debug("PM: Reading swsusp image.\n");
- if ((error = swsusp_read()))
- goto Cleanup;
+ if ((error = swsusp_read())) {
+ swsusp_free();
+ goto Thaw;
+ }
pr_debug("PM: Preparing devices for restore.\n");
if ((error = device_suspend(PMSG_FREEZE))) {
printk("Some devices failed to suspend\n");
- goto Free;
+ swsusp_free();
+ goto Thaw;
}
mb();
@@ -268,9 +266,7 @@ static int software_resume(void)
swsusp_resume();
pr_debug("PM: Restore failed, recovering.n");
device_resume();
- Free:
- swsusp_free();
- Cleanup:
+ Thaw:
unprepare_processes();
Done:
/* For success case, the suspend path will release the lock */
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 22bdc93cc038..18d7d693fbba 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -167,6 +167,8 @@ static int enter_state(suspend_state_t state)
{
int error;
+ if (pm_ops->valid && !pm_ops->valid(state))
+ return -ENODEV;
if (down_trylock(&pm_sem))
return -EBUSY;
@@ -236,7 +238,8 @@ static ssize_t state_show(struct subsystem * subsys, char * buf)
char * s = buf;
for (i = 0; i < PM_SUSPEND_MAX; i++) {
- if (pm_states[i])
+ if (pm_states[i] && pm_ops && (!pm_ops->valid
+ ||(pm_ops->valid && pm_ops->valid(i))))
s += sprintf(s,"%s ",pm_states[i]);
}
s += sprintf(s,"\n");
diff --git a/kernel/power/power.h b/kernel/power/power.h
index 6748de23e83c..d4fd96a135ab 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -53,3 +53,20 @@ extern void thaw_processes(void);
extern int pm_prepare_console(void);
extern void pm_restore_console(void);
+
+
+/* References to section boundaries */
+extern const void __nosave_begin, __nosave_end;
+
+extern unsigned int nr_copy_pages;
+extern suspend_pagedir_t *pagedir_nosave;
+extern suspend_pagedir_t *pagedir_save;
+
+extern asmlinkage int swsusp_arch_suspend(void);
+extern asmlinkage int swsusp_arch_resume(void);
+
+extern int restore_highmem(void);
+extern struct pbe * alloc_pagedir(unsigned nr_pages);
+extern void create_pbe_list(struct pbe *pblist, unsigned nr_pages);
+extern void swsusp_free(void);
+extern int enough_swap(unsigned nr_pages);
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
new file mode 100644
index 000000000000..42a628704398
--- /dev/null
+++ b/kernel/power/snapshot.c
@@ -0,0 +1,435 @@
+/*
+ * linux/kernel/power/snapshot.c
+ *
+ * This file provide system snapshot/restore functionality.
+ *
+ * Copyright (C) 1998-2005 Pavel Machek <pavel@suse.cz>
+ *
+ * This file is released under the GPLv2, and is based on swsusp.c.
+ *
+ */
+
+
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/suspend.h>
+#include <linux/smp_lock.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+#include <linux/spinlock.h>
+#include <linux/kernel.h>
+#include <linux/pm.h>
+#include <linux/device.h>
+#include <linux/bootmem.h>
+#include <linux/syscalls.h>
+#include <linux/console.h>
+#include <linux/highmem.h>
+
+#include <asm/uaccess.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+#include <asm/io.h>
+
+#include "power.h"
+
+#ifdef CONFIG_HIGHMEM
+struct highmem_page {
+ char *data;
+ struct page *page;
+ struct highmem_page *next;
+};
+
+static struct highmem_page *highmem_copy;
+
+static int save_highmem_zone(struct zone *zone)
+{
+ unsigned long zone_pfn;
+ mark_free_pages(zone);
+ for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn) {
+ struct page *page;
+ struct highmem_page *save;
+ void *kaddr;
+ unsigned long pfn = zone_pfn + zone->zone_start_pfn;
+
+ if (!(pfn%1000))
+ printk(".");
+ if (!pfn_valid(pfn))
+ continue;
+ page = pfn_to_page(pfn);
+ /*
+ * This condition results from rvmalloc() sans vmalloc_32()
+ * and architectural memory reservations. This should be
+ * corrected eventually when the cases giving rise to this
+ * are better understood.
+ */
+ if (PageReserved(page)) {
+ printk("highmem reserved page?!\n");
+ continue;
+ }
+ BUG_ON(PageNosave(page));
+ if (PageNosaveFree(page))
+ continue;
+ save = kmalloc(sizeof(struct highmem_page), GFP_ATOMIC);
+ if (!save)
+ return -ENOMEM;
+ save->next = highmem_copy;
+ save->page = page;
+ save->data = (void *) get_zeroed_page(GFP_ATOMIC);
+ if (!save->data) {
+ kfree(save);
+ return -ENOMEM;
+ }
+ kaddr = kmap_atomic(page, KM_USER0);
+ memcpy(save->data, kaddr, PAGE_SIZE);
+ kunmap_atomic(kaddr, KM_USER0);
+ highmem_copy = save;
+ }
+ return 0;
+}
+
+
+static int save_highmem(void)
+{
+ struct zone *zone;
+ int res = 0;
+
+ pr_debug("swsusp: Saving Highmem\n");
+ for_each_zone (zone) {
+ if (is_highmem(zone))
+ res = save_highmem_zone(zone);
+ if (res)
+ return res;
+ }
+ return 0;
+}
+
+int restore_highmem(void)
+{
+ printk("swsusp: Restoring Highmem\n");
+ while (highmem_copy) {
+ struct highmem_page *save = highmem_copy;
+ void *kaddr;
+ highmem_copy = save->next;
+
+ kaddr = kmap_atomic(save->page, KM_USER0);
+ memcpy(kaddr, save->data, PAGE_SIZE);
+ kunmap_atomic(kaddr, KM_USER0);
+ free_page((long) save->data);
+ kfree(save);
+ }
+ return 0;
+}
+#else
+static int save_highmem(void) { return 0; }
+int restore_highmem(void) { return 0; }
+#endif /* CONFIG_HIGHMEM */
+
+
+static int pfn_is_nosave(unsigned long pfn)
+{
+ unsigned long nosave_begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT;
+ unsigned long nosave_end_pfn = PAGE_ALIGN(__pa(&__nosave_end)) >> PAGE_SHIFT;
+ return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn);
+}
+
+/**
+ * saveable - Determine whether a page should be cloned or not.
+ * @pfn: The page
+ *
+ * We save a page if it's Reserved, and not in the range of pages
+ * statically defined as 'unsaveable', or if it isn't reserved, and
+ * isn't part of a free chunk of pages.
+ */
+
+static int saveable(struct zone *zone, unsigned long *zone_pfn)
+{
+ unsigned long pfn = *zone_pfn + zone->zone_start_pfn;
+ struct page *page;
+
+ if (!pfn_valid(pfn))
+ return 0;
+
+ page = pfn_to_page(pfn);
+ BUG_ON(PageReserved(page) && PageNosave(page));
+ if (PageNosave(page))
+ return 0;
+ if (PageReserved(page) && pfn_is_nosave(pfn)) {
+ pr_debug("[nosave pfn 0x%lx]", pfn);
+ return 0;
+ }
+ if (PageNosaveFree(page))
+ return 0;
+
+ return 1;
+}
+
+static unsigned count_data_pages(void)
+{
+ struct zone *zone;
+ unsigned long zone_pfn;
+ unsigned n;
+
+ n = 0;
+ for_each_zone (zone) {
+ if (is_highmem(zone))
+ continue;
+ mark_free_pages(zone);
+ for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn)
+ n += saveable(zone, &zone_pfn);
+ }
+ return n;
+}
+
+static void copy_data_pages(struct pbe *pblist)
+{
+ struct zone *zone;
+ unsigned long zone_pfn;
+ struct pbe *pbe, *p;
+
+ pbe = pblist;
+ for_each_zone (zone) {
+ if (is_highmem(zone))
+ continue;
+ mark_free_pages(zone);
+ /* This is necessary for swsusp_free() */
+ for_each_pb_page (p, pblist)
+ SetPageNosaveFree(virt_to_page(p));
+ for_each_pbe (p, pblist)
+ SetPageNosaveFree(virt_to_page(p->address));
+ for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn) {
+ if (saveable(zone, &zone_pfn)) {
+ struct page *page;
+ page = pfn_to_page(zone_pfn + zone->zone_start_pfn);
+ BUG_ON(!pbe);
+ pbe->orig_address = (unsigned long)page_address(page);
+ /* copy_page is not usable for copying task structs. */
+ memcpy((void *)pbe->address, (void *)pbe->orig_address, PAGE_SIZE);
+ pbe = pbe->next;
+ }
+ }
+ }
+ BUG_ON(pbe);
+}
+
+
+/**
+ * free_pagedir - free pages allocated with alloc_pagedir()
+ */
+
+static void free_pagedir(struct pbe *pblist)
+{
+ struct pbe *pbe;
+
+ while (pblist) {
+ pbe = (pblist + PB_PAGE_SKIP)->next;
+ ClearPageNosave(virt_to_page(pblist));
+ ClearPageNosaveFree(virt_to_page(pblist));
+ free_page((unsigned long)pblist);
+ pblist = pbe;
+ }
+}
+
+/**
+ * fill_pb_page - Create a list of PBEs on a given memory page
+ */
+
+static inline void fill_pb_page(struct pbe *pbpage)
+{
+ struct pbe *p;
+
+ p = pbpage;
+ pbpage += PB_PAGE_SKIP;
+ do
+ p->next = p + 1;
+ while (++p < pbpage);
+}
+
+/**
+ * create_pbe_list - Create a list of PBEs on top of a given chain
+ * of memory pages allocated with alloc_pagedir()
+ */
+
+void create_pbe_list(struct pbe *pblist, unsigned nr_pages)
+{
+ struct pbe *pbpage, *p;
+ unsigned num = PBES_PER_PAGE;
+
+ for_each_pb_page (pbpage, pblist) {
+ if (num >= nr_pages)
+ break;
+
+ fill_pb_page(pbpage);
+ num += PBES_PER_PAGE;
+ }
+ if (pbpage) {
+ for (num -= PBES_PER_PAGE - 1, p = pbpage; num < nr_pages; p++, num++)
+ p->next = p + 1;
+ p->next = NULL;
+ }
+ pr_debug("create_pbe_list(): initialized %d PBEs\n", num);
+}
+
+static void *alloc_image_page(void)
+{
+ void *res = (void *)get_zeroed_page(GFP_ATOMIC | __GFP_COLD);
+ if (res) {
+ SetPageNosave(virt_to_page(res));
+ SetPageNosaveFree(virt_to_page(res));
+ }
+ return res;
+}
+
+/**
+ * alloc_pagedir - Allocate the page directory.
+ *
+ * First, determine exactly how many pages we need and
+ * allocate them.
+ *
+ * We arrange the pages in a chain: each page is an array of PBES_PER_PAGE
+ * struct pbe elements (pbes) and the last element in the page points
+ * to the next page.
+ *
+ * On each page we set up a list of struct_pbe elements.
+ */
+
+struct pbe *alloc_pagedir(unsigned nr_pages)
+{
+ unsigned num;
+ struct pbe *pblist, *pbe;
+
+ if (!nr_pages)
+ return NULL;
+
+ pr_debug("alloc_pagedir(): nr_pages = %d\n", nr_pages);
+ pblist = alloc_image_page();
+ /* FIXME: rewrite this ugly loop */
+ for (pbe = pblist, num = PBES_PER_PAGE; pbe && num < nr_pages;
+ pbe = pbe->next, num += PBES_PER_PAGE) {
+ pbe += PB_PAGE_SKIP;
+ pbe->next = alloc_image_page();
+ }
+ if (!pbe) { /* get_zeroed_page() failed */
+ free_pagedir(pblist);
+ pblist = NULL;
+ }
+ return pblist;
+}
+
+/**
+ * Free pages we allocated for suspend. Suspend pages are alocated
+ * before atomic copy, so we need to free them after resume.
+ */
+
+void swsusp_free(void)
+{
+ struct zone *zone;
+ unsigned long zone_pfn;
+
+ for_each_zone(zone) {
+ for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn)
+ if (pfn_valid(zone_pfn + zone->zone_start_pfn)) {
+ struct page * page;
+ page = pfn_to_page(zone_pfn + zone->zone_start_pfn);
+ if (PageNosave(page) && PageNosaveFree(page)) {
+ ClearPageNosave(page);
+ ClearPageNosaveFree(page);
+ free_page((long) page_address(page));
+ }
+ }
+ }
+}
+
+
+/**
+ * enough_free_mem - Make sure we enough free memory to snapshot.
+ *
+ * Returns TRUE or FALSE after checking the number of available
+ * free pages.
+ */
+
+static int enough_free_mem(unsigned nr_pages)
+{
+ pr_debug("swsusp: available memory: %u pages\n", nr_free_pages());
+ return nr_free_pages() > (nr_pages + PAGES_FOR_IO +
+ (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE);
+}
+
+
+static struct pbe *swsusp_alloc(unsigned nr_pages)
+{
+ struct pbe *pblist, *p;
+
+ if (!(pblist = alloc_pagedir(nr_pages))) {
+ printk(KERN_ERR "suspend: Allocating pagedir failed.\n");
+ return NULL;
+ }
+ create_pbe_list(pblist, nr_pages);
+
+ for_each_pbe (p, pblist) {
+ p->address = (unsigned long)alloc_image_page();
+ if (!p->address) {
+ printk(KERN_ERR "suspend: Allocating image pages failed.\n");
+ swsusp_free();
+ return NULL;
+ }
+ }
+
+ return pblist;
+}
+
+asmlinkage int swsusp_save(void)
+{
+ unsigned nr_pages;
+
+ pr_debug("swsusp: critical section: \n");
+ if (save_highmem()) {
+ printk(KERN_CRIT "swsusp: Not enough free pages for highmem\n");
+ restore_highmem();
+ return -ENOMEM;
+ }
+
+ drain_local_pages();
+ nr_pages = count_data_pages();
+ printk("swsusp: Need to copy %u pages\n", nr_pages);
+
+ pr_debug("swsusp: pages needed: %u + %lu + %u, free: %u\n",
+ nr_pages,
+ (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE,
+ PAGES_FOR_IO, nr_free_pages());
+
+ /* This is needed because of the fixed size of swsusp_info */
+ if (MAX_PBES < (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE)
+ return -ENOSPC;
+
+ if (!enough_free_mem(nr_pages)) {
+ printk(KERN_ERR "swsusp: Not enough free memory\n");
+ return -ENOMEM;
+ }
+
+ if (!enough_swap(nr_pages)) {
+ printk(KERN_ERR "swsusp: Not enough free swap\n");
+ return -ENOSPC;
+ }
+
+ pagedir_nosave = swsusp_alloc(nr_pages);
+ if (!pagedir_nosave)
+ return -ENOMEM;
+
+ /* During allocating of suspend pagedir, new cold pages may appear.
+ * Kill them.
+ */
+ drain_local_pages();
+ copy_data_pages(pagedir_nosave);
+
+ /*
+ * End of critical section. From now on, we can write to memory,
+ * but we should not touch disk. This specially means we must _not_
+ * touch swap space! Except we must write out our image of course.
+ */
+
+ nr_copy_pages = nr_pages;
+
+ printk("swsusp: critical section/: done (%d pages copied)\n", nr_pages);
+ return 0;
+}
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c
index 10bc5ec496d7..12db1d2ad61f 100644
--- a/kernel/power/swsusp.c
+++ b/kernel/power/swsusp.c
@@ -1,11 +1,10 @@
/*
* linux/kernel/power/swsusp.c
*
- * This file is to realize architecture-independent
- * machine suspend feature using pretty near only high-level routines
+ * This file provides code to write suspend image to swap and read it back.
*
* Copyright (C) 1998-2001 Gabor Kuti <seasons@fornax.hu>
- * Copyright (C) 1998,2001-2004 Pavel Machek <pavel@suse.cz>
+ * Copyright (C) 1998,2001-2005 Pavel Machek <pavel@suse.cz>
*
* This file is released under the GPLv2.
*
@@ -47,11 +46,7 @@
#include <linux/utsname.h>
#include <linux/version.h>
#include <linux/delay.h>
-#include <linux/reboot.h>
#include <linux/bitops.h>
-#include <linux/vt_kern.h>
-#include <linux/kbd_kern.h>
-#include <linux/keyboard.h>
#include <linux/spinlock.h>
#include <linux/genhd.h>
#include <linux/kernel.h>
@@ -63,10 +58,8 @@
#include <linux/swapops.h>
#include <linux/bootmem.h>
#include <linux/syscalls.h>
-#include <linux/console.h>
#include <linux/highmem.h>
#include <linux/bio.h>
-#include <linux/mount.h>
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
@@ -84,16 +77,10 @@
#define MAXKEY 32
#define MAXIV 32
-/* References to section boundaries */
-extern const void __nosave_begin, __nosave_end;
-
-/* Variables to be preserved over suspend */
-static int nr_copy_pages_check;
-
extern char resume_file[];
/* Local variables that should not be affected by save */
-static unsigned int nr_copy_pages __nosavedata = 0;
+unsigned int nr_copy_pages __nosavedata = 0;
/* Suspend pagedir is allocated before final copy, therefore it
must be freed after resume
@@ -109,7 +96,7 @@ static unsigned int nr_copy_pages __nosavedata = 0;
MMU hardware.
*/
suspend_pagedir_t *pagedir_nosave __nosavedata = NULL;
-static suspend_pagedir_t *pagedir_save;
+suspend_pagedir_t *pagedir_save;
#define SWSUSP_SIG "S1SUSPEND"
@@ -124,12 +111,6 @@ static struct swsusp_header {
static struct swsusp_info swsusp_info;
/*
- * XXX: We try to keep some more pages free so that I/O operations succeed
- * without paging. Might this be more?
- */
-#define PAGES_FOR_IO 512
-
-/*
* Saving part...
*/
@@ -552,346 +533,6 @@ static int write_suspend_image(void)
goto Done;
}
-
-#ifdef CONFIG_HIGHMEM
-struct highmem_page {
- char *data;
- struct page *page;
- struct highmem_page *next;
-};
-
-static struct highmem_page *highmem_copy;
-
-static int save_highmem_zone(struct zone *zone)
-{
- unsigned long zone_pfn;
- mark_free_pages(zone);
- for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn) {
- struct page *page;
- struct highmem_page *save;
- void *kaddr;
- unsigned long pfn = zone_pfn + zone->zone_start_pfn;
-
- if (!(pfn%1000))
- printk(".");
- if (!pfn_valid(pfn))
- continue;
- page = pfn_to_page(pfn);
- /*
- * This condition results from rvmalloc() sans vmalloc_32()
- * and architectural memory reservations. This should be
- * corrected eventually when the cases giving rise to this
- * are better understood.
- */
- if (PageReserved(page)) {
- printk("highmem reserved page?!\n");
- continue;
- }
- BUG_ON(PageNosave(page));
- if (PageNosaveFree(page))
- continue;
- save = kmalloc(sizeof(struct highmem_page), GFP_ATOMIC);
- if (!save)
- return -ENOMEM;
- save->next = highmem_copy;
- save->page = page;
- save->data = (void *) get_zeroed_page(GFP_ATOMIC);
- if (!save->data) {
- kfree(save);
- return -ENOMEM;
- }
- kaddr = kmap_atomic(page, KM_USER0);
- memcpy(save->data, kaddr, PAGE_SIZE);
- kunmap_atomic(kaddr, KM_USER0);
- highmem_copy = save;
- }
- return 0;
-}
-#endif /* CONFIG_HIGHMEM */
-
-
-static int save_highmem(void)
-{
-#ifdef CONFIG_HIGHMEM
- struct zone *zone;
- int res = 0;
-
- pr_debug("swsusp: Saving Highmem\n");
- for_each_zone (zone) {
- if (is_highmem(zone))
- res = save_highmem_zone(zone);
- if (res)
- return res;
- }
-#endif
- return 0;
-}
-
-static int restore_highmem(void)
-{
-#ifdef CONFIG_HIGHMEM
- printk("swsusp: Restoring Highmem\n");
- while (highmem_copy) {
- struct highmem_page *save = highmem_copy;
- void *kaddr;
- highmem_copy = save->next;
-
- kaddr = kmap_atomic(save->page, KM_USER0);
- memcpy(kaddr, save->data, PAGE_SIZE);
- kunmap_atomic(kaddr, KM_USER0);
- free_page((long) save->data);
- kfree(save);
- }
-#endif
- return 0;
-}
-
-
-static int pfn_is_nosave(unsigned long pfn)
-{
- unsigned long nosave_begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT;
- unsigned long nosave_end_pfn = PAGE_ALIGN(__pa(&__nosave_end)) >> PAGE_SHIFT;
- return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn);
-}
-
-/**
- * saveable - Determine whether a page should be cloned or not.
- * @pfn: The page
- *
- * We save a page if it's Reserved, and not in the range of pages
- * statically defined as 'unsaveable', or if it isn't reserved, and
- * isn't part of a free chunk of pages.
- */
-
-static int saveable(struct zone * zone, unsigned long * zone_pfn)
-{
- unsigned long pfn = *zone_pfn + zone->zone_start_pfn;
- struct page * page;
-
- if (!pfn_valid(pfn))
- return 0;
-
- page = pfn_to_page(pfn);
- BUG_ON(PageReserved(page) && PageNosave(page));
- if (PageNosave(page))
- return 0;
- if (PageReserved(page) && pfn_is_nosave(pfn)) {
- pr_debug("[nosave pfn 0x%lx]", pfn);
- return 0;
- }
- if (PageNosaveFree(page))
- return 0;
-
- return 1;
-}
-
-static void count_data_pages(void)
-{
- struct zone *zone;
- unsigned long zone_pfn;
-
- nr_copy_pages = 0;
-
- for_each_zone (zone) {
- if (is_highmem(zone))
- continue;
- mark_free_pages(zone);
- for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn)
- nr_copy_pages += saveable(zone, &zone_pfn);
- }
-}
-
-
-static void copy_data_pages(void)
-{
- struct zone *zone;
- unsigned long zone_pfn;
- struct pbe * pbe = pagedir_nosave;
-
- pr_debug("copy_data_pages(): pages to copy: %d\n", nr_copy_pages);
- for_each_zone (zone) {
- if (is_highmem(zone))
- continue;
- mark_free_pages(zone);
- for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn) {
- if (saveable(zone, &zone_pfn)) {
- struct page * page;
- page = pfn_to_page(zone_pfn + zone->zone_start_pfn);
- BUG_ON(!pbe);
- pbe->orig_address = (long) page_address(page);
- /* copy_page is not usable for copying task structs. */
- memcpy((void *)pbe->address, (void *)pbe->orig_address, PAGE_SIZE);
- pbe = pbe->next;
- }
- }
- }
- BUG_ON(pbe);
-}
-
-
-/**
- * calc_nr - Determine the number of pages needed for a pbe list.
- */
-
-static int calc_nr(int nr_copy)
-{
- return nr_copy + (nr_copy+PBES_PER_PAGE-2)/(PBES_PER_PAGE-1);
-}
-
-/**
- * free_pagedir - free pages allocated with alloc_pagedir()
- */
-
-static inline void free_pagedir(struct pbe *pblist)
-{
- struct pbe *pbe;
-
- while (pblist) {
- pbe = (pblist + PB_PAGE_SKIP)->next;
- free_page((unsigned long)pblist);
- pblist = pbe;
- }
-}
-
-/**
- * fill_pb_page - Create a list of PBEs on a given memory page
- */
-
-static inline void fill_pb_page(struct pbe *pbpage)
-{
- struct pbe *p;
-
- p = pbpage;
- pbpage += PB_PAGE_SKIP;
- do
- p->next = p + 1;
- while (++p < pbpage);
-}
-
-/**
- * create_pbe_list - Create a list of PBEs on top of a given chain
- * of memory pages allocated with alloc_pagedir()
- */
-
-static void create_pbe_list(struct pbe *pblist, unsigned nr_pages)
-{
- struct pbe *pbpage, *p;
- unsigned num = PBES_PER_PAGE;
-
- for_each_pb_page (pbpage, pblist) {
- if (num >= nr_pages)
- break;
-
- fill_pb_page(pbpage);
- num += PBES_PER_PAGE;
- }
- if (pbpage) {
- for (num -= PBES_PER_PAGE - 1, p = pbpage; num < nr_pages; p++, num++)
- p->next = p + 1;
- p->next = NULL;
- }
- pr_debug("create_pbe_list(): initialized %d PBEs\n", num);
-}
-
-/**
- * alloc_pagedir - Allocate the page directory.
- *
- * First, determine exactly how many pages we need and
- * allocate them.
- *
- * We arrange the pages in a chain: each page is an array of PBES_PER_PAGE
- * struct pbe elements (pbes) and the last element in the page points
- * to the next page.
- *
- * On each page we set up a list of struct_pbe elements.
- */
-
-static struct pbe * alloc_pagedir(unsigned nr_pages)
-{
- unsigned num;
- struct pbe *pblist, *pbe;
-
- if (!nr_pages)
- return NULL;
-
- pr_debug("alloc_pagedir(): nr_pages = %d\n", nr_pages);
- pblist = (struct pbe *)get_zeroed_page(GFP_ATOMIC | __GFP_COLD);
- for (pbe = pblist, num = PBES_PER_PAGE; pbe && num < nr_pages;
- pbe = pbe->next, num += PBES_PER_PAGE) {
- pbe += PB_PAGE_SKIP;
- pbe->next = (struct pbe *)get_zeroed_page(GFP_ATOMIC | __GFP_COLD);
- }
- if (!pbe) { /* get_zeroed_page() failed */
- free_pagedir(pblist);
- pblist = NULL;
- }
- return pblist;
-}
-
-/**
- * free_image_pages - Free pages allocated for snapshot
- */
-
-static void free_image_pages(void)
-{
- struct pbe * p;
-
- for_each_pbe (p, pagedir_save) {
- if (p->address) {
- ClearPageNosave(virt_to_page(p->address));
- free_page(p->address);
- p->address = 0;
- }
- }
-}
-
-/**
- * alloc_image_pages - Allocate pages for the snapshot.
- */
-
-static int alloc_image_pages(void)
-{
- struct pbe * p;
-
- for_each_pbe (p, pagedir_save) {
- p->address = get_zeroed_page(GFP_ATOMIC | __GFP_COLD);
- if (!p->address)
- return -ENOMEM;
- SetPageNosave(virt_to_page(p->address));
- }
- return 0;
-}
-
-/* Free pages we allocated for suspend. Suspend pages are alocated
- * before atomic copy, so we need to free them after resume.
- */
-void swsusp_free(void)
-{
- BUG_ON(PageNosave(virt_to_page(pagedir_save)));
- BUG_ON(PageNosaveFree(virt_to_page(pagedir_save)));
- free_image_pages();
- free_pagedir(pagedir_save);
-}
-
-
-/**
- * enough_free_mem - Make sure we enough free memory to snapshot.
- *
- * Returns TRUE or FALSE after checking the number of available
- * free pages.
- */
-
-static int enough_free_mem(void)
-{
- if (nr_free_pages() < (nr_copy_pages + PAGES_FOR_IO)) {
- pr_debug("swsusp: Not enough free pages: Have %d\n",
- nr_free_pages());
- return 0;
- }
- return 1;
-}
-
-
/**
* enough_swap - Make sure we have enough swap to save the image.
*
@@ -902,87 +543,14 @@ static int enough_free_mem(void)
* We should only consider resume_device.
*/
-static int enough_swap(void)
+int enough_swap(unsigned nr_pages)
{
struct sysinfo i;
si_swapinfo(&i);
- if (i.freeswap < (nr_copy_pages + PAGES_FOR_IO)) {
- pr_debug("swsusp: Not enough swap. Need %ld\n",i.freeswap);
- return 0;
- }
- return 1;
-}
-
-static int swsusp_alloc(void)
-{
- int error;
-
- pagedir_nosave = NULL;
- nr_copy_pages = calc_nr(nr_copy_pages);
- nr_copy_pages_check = nr_copy_pages;
-
- pr_debug("suspend: (pages needed: %d + %d free: %d)\n",
- nr_copy_pages, PAGES_FOR_IO, nr_free_pages());
-
- if (!enough_free_mem())
- return -ENOMEM;
-
- if (!enough_swap())
- return -ENOSPC;
-
- if (MAX_PBES < nr_copy_pages / PBES_PER_PAGE +
- !!(nr_copy_pages % PBES_PER_PAGE))
- return -ENOSPC;
-
- if (!(pagedir_save = alloc_pagedir(nr_copy_pages))) {
- printk(KERN_ERR "suspend: Allocating pagedir failed.\n");
- return -ENOMEM;
- }
- create_pbe_list(pagedir_save, nr_copy_pages);
- pagedir_nosave = pagedir_save;
- if ((error = alloc_image_pages())) {
- printk(KERN_ERR "suspend: Allocating image pages failed.\n");
- swsusp_free();
- return error;
- }
-
- return 0;
-}
-
-static int suspend_prepare_image(void)
-{
- int error;
-
- pr_debug("swsusp: critical section: \n");
- if (save_highmem()) {
- printk(KERN_CRIT "Suspend machine: Not enough free pages for highmem\n");
- restore_highmem();
- return -ENOMEM;
- }
-
- drain_local_pages();
- count_data_pages();
- printk("swsusp: Need to copy %u pages\n", nr_copy_pages);
-
- error = swsusp_alloc();
- if (error)
- return error;
-
- /* During allocating of suspend pagedir, new cold pages may appear.
- * Kill them.
- */
- drain_local_pages();
- copy_data_pages();
-
- /*
- * End of critical section. From now on, we can write to memory,
- * but we should not touch disk. This specially means we must _not_
- * touch swap space! Except we must write out our image of course.
- */
-
- printk("swsusp: critical section/: done (%d pages copied)\n", nr_copy_pages );
- return 0;
+ pr_debug("swsusp: available swap: %lu pages\n", i.freeswap);
+ return i.freeswap > (nr_pages + PAGES_FOR_IO +
+ (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE);
}
@@ -994,7 +562,7 @@ static int suspend_prepare_image(void)
int swsusp_write(void)
{
int error;
- device_resume();
+
lock_swapdevices();
error = write_suspend_image();
/* This will unlock ignored swap devices since writing is finished */
@@ -1004,14 +572,6 @@ int swsusp_write(void)
}
-extern asmlinkage int swsusp_arch_suspend(void);
-extern asmlinkage int swsusp_arch_resume(void);
-
-
-asmlinkage int swsusp_save(void)
-{
- return suspend_prepare_image();
-}
int swsusp_suspend(void)
{
@@ -1043,7 +603,6 @@ int swsusp_suspend(void)
printk(KERN_ERR "Error %d suspending\n", error);
/* Restore control flow magically appears here */
restore_processor_state();
- BUG_ON (nr_copy_pages_check != nr_copy_pages);
restore_highmem();
device_power_up();
local_irq_enable();
@@ -1063,6 +622,11 @@ int swsusp_resume(void)
* execution continues at place where swsusp_arch_suspend was called
*/
BUG_ON(!error);
+ /* The only reason why swsusp_arch_resume() can fail is memory being
+ * very tight, so we have to free it as soon as we can to avoid
+ * subsequent failures
+ */
+ swsusp_free();
restore_processor_state();
restore_highmem();
touch_softlockup_watchdog();
@@ -1078,54 +642,28 @@ int swsusp_resume(void)
*
* We don't know which pages are usable until we allocate them.
*
- * Allocated but unusable (ie eaten) memory pages are linked together
- * to create a list, so that we can free them easily
- *
- * We could have used a type other than (void *)
- * for this purpose, but ...
+ * Allocated but unusable (ie eaten) memory pages are marked so that
+ * swsusp_free() can release them
*/
-static void **eaten_memory = NULL;
-
-static inline void eat_page(void *page)
-{
- void **c;
-
- c = eaten_memory;
- eaten_memory = page;
- *eaten_memory = c;
-}
-unsigned long get_usable_page(gfp_t gfp_mask)
+unsigned long get_safe_page(gfp_t gfp_mask)
{
unsigned long m;
- m = get_zeroed_page(gfp_mask);
- while (!PageNosaveFree(virt_to_page(m))) {
- eat_page((void *)m);
+ do {
m = get_zeroed_page(gfp_mask);
- if (!m)
- break;
+ if (m && PageNosaveFree(virt_to_page(m)))
+ /* This is for swsusp_free() */
+ SetPageNosave(virt_to_page(m));
+ } while (m && PageNosaveFree(virt_to_page(m)));
+ if (m) {
+ /* This is for swsusp_free() */
+ SetPageNosave(virt_to_page(m));
+ SetPageNosaveFree(virt_to_page(m));
}
return m;
}
-void free_eaten_memory(void)
-{
- unsigned long m;
- void **c;
- int i = 0;
-
- c = eaten_memory;
- while (c) {
- m = (unsigned long)c;
- c = *c;
- free_page(m);
- i++;
- }
- eaten_memory = NULL;
- pr_debug("swsusp: %d unused pages freed\n", i);
-}
-
/**
* check_pagedir - We ensure here that pages that the PBEs point to
* won't collide with pages where we're going to restore from the loaded
@@ -1143,7 +681,7 @@ static int check_pagedir(struct pbe *pblist)
p->address = 0UL;
for_each_pbe (p, pblist) {
- p->address = get_usable_page(GFP_ATOMIC);
+ p->address = get_safe_page(GFP_ATOMIC);
if (!p->address)
return -ENOMEM;
}
@@ -1162,7 +700,7 @@ static struct pbe * swsusp_pagedir_relocate(struct pbe *pblist)
unsigned long zone_pfn;
struct pbe *pbpage, *tail, *p;
void *m;
- int rel = 0, error = 0;
+ int rel = 0;
if (!pblist) /* a sanity check */
return NULL;
@@ -1170,41 +708,37 @@ static struct pbe * swsusp_pagedir_relocate(struct pbe *pblist)
pr_debug("swsusp: Relocating pagedir (%lu pages to check)\n",
swsusp_info.pagedir_pages);
- /* Set page flags */
+ /* Clear page flags */
for_each_zone (zone) {
for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn)
- SetPageNosaveFree(pfn_to_page(zone_pfn +
+ if (pfn_valid(zone_pfn + zone->zone_start_pfn))
+ ClearPageNosaveFree(pfn_to_page(zone_pfn +
zone->zone_start_pfn));
}
- /* Clear orig addresses */
+ /* Mark orig addresses */
for_each_pbe (p, pblist)
- ClearPageNosaveFree(virt_to_page(p->orig_address));
+ SetPageNosaveFree(virt_to_page(p->orig_address));
tail = pblist + PB_PAGE_SKIP;
/* Relocate colliding pages */
for_each_pb_page (pbpage, pblist) {
- if (!PageNosaveFree(virt_to_page((unsigned long)pbpage))) {
- m = (void *)get_usable_page(GFP_ATOMIC | __GFP_COLD);
- if (!m) {
- error = -ENOMEM;
- break;
- }
+ if (PageNosaveFree(virt_to_page((unsigned long)pbpage))) {
+ m = (void *)get_safe_page(GFP_ATOMIC | __GFP_COLD);
+ if (!m)
+ return NULL;
memcpy(m, (void *)pbpage, PAGE_SIZE);
if (pbpage == pblist)
pblist = (struct pbe *)m;
else
tail->next = (struct pbe *)m;
-
- eat_page((void *)pbpage);
pbpage = (struct pbe *)m;
/* We have to link the PBEs again */
-
for (p = pbpage; p < pbpage + PB_PAGE_SKIP; p++)
if (p->next) /* needed to save the end */
p->next = p + 1;
@@ -1214,15 +748,13 @@ static struct pbe * swsusp_pagedir_relocate(struct pbe *pblist)
tail = pbpage + PB_PAGE_SKIP;
}
- if (error) {
- printk("\nswsusp: Out of memory\n\n");
- free_pagedir(pblist);
- free_eaten_memory();
- pblist = NULL;
- /* Is this even worth handling? It should never ever happen, and we
- have just lost user's state, anyway... */
- } else
- printk("swsusp: Relocated %d pages\n", rel);
+ /* This is for swsusp_free() */
+ for_each_pb_page (pbpage, pblist) {
+ SetPageNosave(virt_to_page(pbpage));
+ SetPageNosaveFree(virt_to_page(pbpage));
+ }
+
+ printk("swsusp: Relocated %d pages\n", rel);
return pblist;
}
@@ -1440,9 +972,7 @@ static int read_pagedir(struct pbe *pblist)
break;
}
- if (error)
- free_pagedir(pblist);
- else
+ if (!error)
BUG_ON(i != swsusp_info.pagedir_pages);
return error;
@@ -1485,15 +1015,6 @@ static int read_suspend_image(void)
if (!error)
error = data_read(pagedir_nosave);
- if (error) { /* We fail cleanly */
- free_eaten_memory();
- for_each_pbe (p, pagedir_nosave)
- if (p->address) {
- free_page(p->address);
- p->address = 0UL;
- }
- free_pagedir(pagedir_nosave);
- }
return error;
}
diff --git a/kernel/printk.c b/kernel/printk.c
index 4b8f0f9230a4..3cb9708209bc 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -10,7 +10,7 @@
* elsewhere, in preparation for a serial line console (someday).
* Ted Ts'o, 2/11/93.
* Modified for sysctl support, 1/8/97, Chris Horn.
- * Fixed SMP synchronization, 08/08/99, Manfred Spraul
+ * Fixed SMP synchronization, 08/08/99, Manfred Spraul
* manfreds@colorfullife.com
* Rewrote bits to get rid of console_lock
* 01Mar01 Andrew Morton <andrewm@uow.edu.au>
@@ -148,7 +148,7 @@ static int __init console_setup(char *str)
if (!strcmp(str, "ttyb"))
strcpy(name, "ttyS1");
#endif
- for(s = name; *s; s++)
+ for (s = name; *s; s++)
if ((*s >= '0' && *s <= '9') || *s == ',')
break;
idx = simple_strtoul(s, NULL, 10);
@@ -169,11 +169,11 @@ static int __init log_buf_len_setup(char *str)
size = roundup_pow_of_two(size);
if (size > log_buf_len) {
unsigned long start, dest_idx, offset;
- char * new_log_buf;
+ char *new_log_buf;
new_log_buf = alloc_bootmem(size);
if (!new_log_buf) {
- printk("log_buf_len: allocation failed\n");
+ printk(KERN_WARNING "log_buf_len: allocation failed\n");
goto out;
}
@@ -193,10 +193,9 @@ static int __init log_buf_len_setup(char *str)
log_end -= offset;
spin_unlock_irqrestore(&logbuf_lock, flags);
- printk("log_buf_len: %d\n", log_buf_len);
+ printk(KERN_NOTICE "log_buf_len: %d\n", log_buf_len);
}
out:
-
return 1;
}
@@ -217,7 +216,7 @@ __setup("log_buf_len=", log_buf_len_setup);
* 9 -- Return number of unread characters in the log buffer
* 10 -- Return size of the log buffer
*/
-int do_syslog(int type, char __user * buf, int len)
+int do_syslog(int type, char __user *buf, int len)
{
unsigned long i, j, limit, count;
int do_clear = 0;
@@ -244,7 +243,8 @@ int do_syslog(int type, char __user * buf, int len)
error = -EFAULT;
goto out;
}
- error = wait_event_interruptible(log_wait, (log_start - log_end));
+ error = wait_event_interruptible(log_wait,
+ (log_start - log_end));
if (error)
goto out;
i = 0;
@@ -264,7 +264,7 @@ int do_syslog(int type, char __user * buf, int len)
error = i;
break;
case 4: /* Read/clear last kernel messages */
- do_clear = 1;
+ do_clear = 1;
/* FALL THRU */
case 3: /* Read last kernel messages */
error = -EINVAL;
@@ -288,11 +288,11 @@ int do_syslog(int type, char __user * buf, int len)
limit = log_end;
/*
* __put_user() could sleep, and while we sleep
- * printk() could overwrite the messages
+ * printk() could overwrite the messages
* we try to copy to user space. Therefore
* the messages are copied in reverse. <manfreds>
*/
- for(i = 0; i < count && !error; i++) {
+ for (i = 0; i < count && !error; i++) {
j = limit-1-i;
if (j + log_buf_len < log_end)
break;
@@ -306,10 +306,10 @@ int do_syslog(int type, char __user * buf, int len)
if (error)
break;
error = i;
- if(i != count) {
+ if (i != count) {
int offset = count-error;
/* buffer overflow during copy, correct user buffer. */
- for(i=0;i<error;i++) {
+ for (i = 0; i < error; i++) {
if (__get_user(c,&buf[i+offset]) ||
__put_user(c,&buf[i])) {
error = -EFAULT;
@@ -351,7 +351,7 @@ out:
return error;
}
-asmlinkage long sys_syslog(int type, char __user * buf, int len)
+asmlinkage long sys_syslog(int type, char __user *buf, int len)
{
return do_syslog(type, buf, len);
}
@@ -404,21 +404,19 @@ static void call_console_drivers(unsigned long start, unsigned long end)
cur_index = start;
start_print = start;
while (cur_index != end) {
- if ( msg_level < 0 &&
- ((end - cur_index) > 2) &&
- LOG_BUF(cur_index + 0) == '<' &&
- LOG_BUF(cur_index + 1) >= '0' &&
- LOG_BUF(cur_index + 1) <= '7' &&
- LOG_BUF(cur_index + 2) == '>')
- {
+ if (msg_level < 0 && ((end - cur_index) > 2) &&
+ LOG_BUF(cur_index + 0) == '<' &&
+ LOG_BUF(cur_index + 1) >= '0' &&
+ LOG_BUF(cur_index + 1) <= '7' &&
+ LOG_BUF(cur_index + 2) == '>') {
msg_level = LOG_BUF(cur_index + 1) - '0';
cur_index += 3;
start_print = cur_index;
}
while (cur_index != end) {
char c = LOG_BUF(cur_index);
- cur_index++;
+ cur_index++;
if (c == '\n') {
if (msg_level < 0) {
/*
@@ -461,7 +459,7 @@ static void zap_locks(void)
static unsigned long oops_timestamp;
if (time_after_eq(jiffies, oops_timestamp) &&
- !time_after(jiffies, oops_timestamp + 30*HZ))
+ !time_after(jiffies, oops_timestamp + 30 * HZ))
return;
oops_timestamp = jiffies;
@@ -495,7 +493,7 @@ __attribute__((weak)) unsigned long long printk_clock(void)
/*
* This is printk. It can be called from any context. We want it to work.
- *
+ *
* We try to grab the console_sem. If we succeed, it's easy - we log the output and
* call the console drivers. If we fail to get the semaphore we place the output
* into the log buffer and return. The current holder of the console_sem will
@@ -639,13 +637,19 @@ EXPORT_SYMBOL(vprintk);
#else
-asmlinkage long sys_syslog(int type, char __user * buf, int len)
+asmlinkage long sys_syslog(int type, char __user *buf, int len)
{
return 0;
}
-int do_syslog(int type, char __user * buf, int len) { return 0; }
-static void call_console_drivers(unsigned long start, unsigned long end) {}
+int do_syslog(int type, char __user *buf, int len)
+{
+ return 0;
+}
+
+static void call_console_drivers(unsigned long start, unsigned long end)
+{
+}
#endif
@@ -851,9 +855,9 @@ EXPORT_SYMBOL(console_start);
* print any messages that were printed by the kernel before the
* console driver was initialized.
*/
-void register_console(struct console * console)
+void register_console(struct console *console)
{
- int i;
+ int i;
unsigned long flags;
if (preferred_console < 0)
@@ -878,7 +882,8 @@ void register_console(struct console * console)
* See if this console matches one we selected on
* the command line.
*/
- for(i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++) {
+ for (i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0];
+ i++) {
if (strcmp(console_cmdline[i].name, console->name) != 0)
continue;
if (console->index >= 0 &&
@@ -933,9 +938,9 @@ void register_console(struct console * console)
}
EXPORT_SYMBOL(register_console);
-int unregister_console(struct console * console)
+int unregister_console(struct console *console)
{
- struct console *a,*b;
+ struct console *a, *b;
int res = 1;
acquire_console_sem();
@@ -949,10 +954,10 @@ int unregister_console(struct console * console)
b->next = a->next;
res = 0;
break;
- }
+ }
}
}
-
+
/* If last console is removed, we re-enable picking the first
* one that gets registered. Without that, pmac early boot console
* would prevent fbcon from taking over.
@@ -994,7 +999,7 @@ void tty_write_message(struct tty_struct *tty, char *msg)
int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst)
{
static DEFINE_SPINLOCK(ratelimit_lock);
- static unsigned long toks = 10*5*HZ;
+ static unsigned long toks = 10 * 5 * HZ;
static unsigned long last_msg;
static int missed;
unsigned long flags;
@@ -1007,6 +1012,7 @@ int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst)
toks = ratelimit_burst * ratelimit_jiffies;
if (toks >= ratelimit_jiffies) {
int lost = missed;
+
missed = 0;
toks -= ratelimit_jiffies;
spin_unlock_irqrestore(&ratelimit_lock, flags);
@@ -1021,7 +1027,7 @@ int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst)
EXPORT_SYMBOL(__printk_ratelimit);
/* minimum time in jiffies between messages */
-int printk_ratelimit_jiffies = 5*HZ;
+int printk_ratelimit_jiffies = 5 * HZ;
/* number of messages we send before ratelimiting */
int printk_ratelimit_burst = 10;
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 019e04ec065a..863eee8bff47 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -56,6 +56,10 @@ void ptrace_untrace(task_t *child)
signal_wake_up(child, 1);
}
}
+ if (child->signal->flags & SIGNAL_GROUP_EXIT) {
+ sigaddset(&child->pending.signal, SIGKILL);
+ signal_wake_up(child, 1);
+ }
spin_unlock(&child->sighand->siglock);
}
@@ -77,8 +81,7 @@ void __ptrace_unlink(task_t *child)
SET_LINKS(child);
}
- if (child->state == TASK_TRACED)
- ptrace_untrace(child);
+ ptrace_untrace(child);
}
/*
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
index 2559d4b8f23f..c4d159a21e04 100644
--- a/kernel/rcupdate.c
+++ b/kernel/rcupdate.c
@@ -154,6 +154,15 @@ void fastcall call_rcu_bh(struct rcu_head *head,
}
/*
+ * Return the number of RCU batches processed thus far. Useful
+ * for debug and statistics.
+ */
+long rcu_batches_completed(void)
+{
+ return rcu_ctrlblk.completed;
+}
+
+/*
* Invoke the completed RCU callbacks. They are expected to be in
* a per-cpu list.
*/
@@ -501,6 +510,7 @@ void synchronize_kernel(void)
}
module_param(maxbatch, int, 0);
+EXPORT_SYMBOL_GPL(rcu_batches_completed);
EXPORT_SYMBOL(call_rcu); /* WARNING: GPL-only in April 2006. */
EXPORT_SYMBOL(call_rcu_bh); /* WARNING: GPL-only in April 2006. */
EXPORT_SYMBOL_GPL(synchronize_rcu);
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
new file mode 100644
index 000000000000..9b58f1eff3ca
--- /dev/null
+++ b/kernel/rcutorture.c
@@ -0,0 +1,492 @@
+/*
+ * Read-Copy Update /proc-based torture test facility
+ *
+ * This program is free software; you can redistribute 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.
+ *
+ * Copyright (C) IBM Corporation, 2005
+ *
+ * Authors: Paul E. McKenney <paulmck@us.ibm.com>
+ *
+ * See also: Documentation/RCU/torture.txt
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kthread.h>
+#include <linux/err.h>
+#include <linux/spinlock.h>
+#include <linux/smp.h>
+#include <linux/rcupdate.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <asm/atomic.h>
+#include <linux/bitops.h>
+#include <linux/module.h>
+#include <linux/completion.h>
+#include <linux/moduleparam.h>
+#include <linux/percpu.h>
+#include <linux/notifier.h>
+#include <linux/rcuref.h>
+#include <linux/cpu.h>
+#include <linux/random.h>
+#include <linux/delay.h>
+#include <linux/byteorder/swabb.h>
+#include <linux/stat.h>
+
+MODULE_LICENSE("GPL");
+
+static int nreaders = -1; /* # reader threads, defaults to 4*ncpus */
+static int stat_interval = 0; /* Interval between stats, in seconds. */
+ /* Defaults to "only at end of test". */
+static int verbose = 0; /* Print more debug info. */
+
+MODULE_PARM(nreaders, "i");
+MODULE_PARM_DESC(nreaders, "Number of RCU reader threads");
+MODULE_PARM(stat_interval, "i");
+MODULE_PARM_DESC(stat_interval, "Number of seconds between stats printk()s");
+MODULE_PARM(verbose, "i");
+MODULE_PARM_DESC(verbose, "Enable verbose debugging printk()s");
+#define TORTURE_FLAG "rcutorture: "
+#define PRINTK_STRING(s) \
+ do { printk(KERN_ALERT TORTURE_FLAG s "\n"); } while (0)
+#define VERBOSE_PRINTK_STRING(s) \
+ do { if (verbose) printk(KERN_ALERT TORTURE_FLAG s "\n"); } while (0)
+#define VERBOSE_PRINTK_ERRSTRING(s) \
+ do { if (verbose) printk(KERN_ALERT TORTURE_FLAG "!!! " s "\n"); } while (0)
+
+static char printk_buf[4096];
+
+static int nrealreaders;
+static struct task_struct *writer_task;
+static struct task_struct **reader_tasks;
+static struct task_struct *stats_task;
+
+#define RCU_TORTURE_PIPE_LEN 10
+
+struct rcu_torture {
+ struct rcu_head rtort_rcu;
+ int rtort_pipe_count;
+ struct list_head rtort_free;
+};
+
+static int fullstop = 0; /* stop generating callbacks at test end. */
+static LIST_HEAD(rcu_torture_freelist);
+static struct rcu_torture *rcu_torture_current = NULL;
+static long rcu_torture_current_version = 0;
+static struct rcu_torture rcu_tortures[10 * RCU_TORTURE_PIPE_LEN];
+static DEFINE_SPINLOCK(rcu_torture_lock);
+static DEFINE_PER_CPU(long [RCU_TORTURE_PIPE_LEN + 1], rcu_torture_count) =
+ { 0 };
+static DEFINE_PER_CPU(long [RCU_TORTURE_PIPE_LEN + 1], rcu_torture_batch) =
+ { 0 };
+static atomic_t rcu_torture_wcount[RCU_TORTURE_PIPE_LEN + 1];
+atomic_t n_rcu_torture_alloc;
+atomic_t n_rcu_torture_alloc_fail;
+atomic_t n_rcu_torture_free;
+
+/*
+ * Allocate an element from the rcu_tortures pool.
+ */
+struct rcu_torture *
+rcu_torture_alloc(void)
+{
+ struct list_head *p;
+
+ spin_lock(&rcu_torture_lock);
+ if (list_empty(&rcu_torture_freelist)) {
+ atomic_inc(&n_rcu_torture_alloc_fail);
+ spin_unlock(&rcu_torture_lock);
+ return NULL;
+ }
+ atomic_inc(&n_rcu_torture_alloc);
+ p = rcu_torture_freelist.next;
+ list_del_init(p);
+ spin_unlock(&rcu_torture_lock);
+ return container_of(p, struct rcu_torture, rtort_free);
+}
+
+/*
+ * Free an element to the rcu_tortures pool.
+ */
+static void
+rcu_torture_free(struct rcu_torture *p)
+{
+ atomic_inc(&n_rcu_torture_free);
+ spin_lock(&rcu_torture_lock);
+ list_add_tail(&p->rtort_free, &rcu_torture_freelist);
+ spin_unlock(&rcu_torture_lock);
+}
+
+static void
+rcu_torture_cb(struct rcu_head *p)
+{
+ int i;
+ struct rcu_torture *rp = container_of(p, struct rcu_torture, rtort_rcu);
+
+ if (fullstop) {
+ /* Test is ending, just drop callbacks on the floor. */
+ /* The next initialization will pick up the pieces. */
+ return;
+ }
+ i = rp->rtort_pipe_count;
+ if (i > RCU_TORTURE_PIPE_LEN)
+ i = RCU_TORTURE_PIPE_LEN;
+ atomic_inc(&rcu_torture_wcount[i]);
+ if (++rp->rtort_pipe_count >= RCU_TORTURE_PIPE_LEN)
+ rcu_torture_free(rp);
+ else
+ call_rcu(p, rcu_torture_cb);
+}
+
+struct rcu_random_state {
+ unsigned long rrs_state;
+ unsigned long rrs_count;
+};
+
+#define RCU_RANDOM_MULT 39916801 /* prime */
+#define RCU_RANDOM_ADD 479001701 /* prime */
+#define RCU_RANDOM_REFRESH 10000
+
+#define DEFINE_RCU_RANDOM(name) struct rcu_random_state name = { 0, 0 }
+
+/*
+ * Crude but fast random-number generator. Uses a linear congruential
+ * generator, with occasional help from get_random_bytes().
+ */
+static long
+rcu_random(struct rcu_random_state *rrsp)
+{
+ long refresh;
+
+ if (--rrsp->rrs_count < 0) {
+ get_random_bytes(&refresh, sizeof(refresh));
+ rrsp->rrs_state += refresh;
+ rrsp->rrs_count = RCU_RANDOM_REFRESH;
+ }
+ rrsp->rrs_state = rrsp->rrs_state * RCU_RANDOM_MULT + RCU_RANDOM_ADD;
+ return swahw32(rrsp->rrs_state);
+}
+
+/*
+ * RCU torture writer kthread. Repeatedly substitutes a new structure
+ * for that pointed to by rcu_torture_current, freeing the old structure
+ * after a series of grace periods (the "pipeline").
+ */
+static int
+rcu_torture_writer(void *arg)
+{
+ int i;
+ long oldbatch = rcu_batches_completed();
+ struct rcu_torture *rp;
+ struct rcu_torture *old_rp;
+ static DEFINE_RCU_RANDOM(rand);
+
+ VERBOSE_PRINTK_STRING("rcu_torture_writer task started");
+ do {
+ schedule_timeout_uninterruptible(1);
+ if (rcu_batches_completed() == oldbatch)
+ continue;
+ if ((rp = rcu_torture_alloc()) == NULL)
+ continue;
+ rp->rtort_pipe_count = 0;
+ udelay(rcu_random(&rand) & 0x3ff);
+ old_rp = rcu_torture_current;
+ rcu_assign_pointer(rcu_torture_current, rp);
+ smp_wmb();
+ if (old_rp != NULL) {
+ i = old_rp->rtort_pipe_count;
+ if (i > RCU_TORTURE_PIPE_LEN)
+ i = RCU_TORTURE_PIPE_LEN;
+ atomic_inc(&rcu_torture_wcount[i]);
+ old_rp->rtort_pipe_count++;
+ call_rcu(&old_rp->rtort_rcu, rcu_torture_cb);
+ }
+ rcu_torture_current_version++;
+ oldbatch = rcu_batches_completed();
+ } while (!kthread_should_stop() && !fullstop);
+ VERBOSE_PRINTK_STRING("rcu_torture_writer task stopping");
+ while (!kthread_should_stop())
+ schedule_timeout_uninterruptible(1);
+ return 0;
+}
+
+/*
+ * RCU torture reader kthread. Repeatedly dereferences rcu_torture_current,
+ * incrementing the corresponding element of the pipeline array. The
+ * counter in the element should never be greater than 1, otherwise, the
+ * RCU implementation is broken.
+ */
+static int
+rcu_torture_reader(void *arg)
+{
+ int completed;
+ DEFINE_RCU_RANDOM(rand);
+ struct rcu_torture *p;
+ int pipe_count;
+
+ VERBOSE_PRINTK_STRING("rcu_torture_reader task started");
+ do {
+ rcu_read_lock();
+ completed = rcu_batches_completed();
+ p = rcu_dereference(rcu_torture_current);
+ if (p == NULL) {
+ /* Wait for rcu_torture_writer to get underway */
+ rcu_read_unlock();
+ schedule_timeout_interruptible(HZ);
+ continue;
+ }
+ udelay(rcu_random(&rand) & 0x7f);
+ preempt_disable();
+ pipe_count = p->rtort_pipe_count;
+ if (pipe_count > RCU_TORTURE_PIPE_LEN) {
+ /* Should not happen, but... */
+ pipe_count = RCU_TORTURE_PIPE_LEN;
+ }
+ ++__get_cpu_var(rcu_torture_count)[pipe_count];
+ completed = rcu_batches_completed() - completed;
+ if (completed > RCU_TORTURE_PIPE_LEN) {
+ /* Should not happen, but... */
+ completed = RCU_TORTURE_PIPE_LEN;
+ }
+ ++__get_cpu_var(rcu_torture_batch)[completed];
+ preempt_enable();
+ rcu_read_unlock();
+ schedule();
+ } while (!kthread_should_stop() && !fullstop);
+ VERBOSE_PRINTK_STRING("rcu_torture_reader task stopping");
+ while (!kthread_should_stop())
+ schedule_timeout_uninterruptible(1);
+ return 0;
+}
+
+/*
+ * Create an RCU-torture statistics message in the specified buffer.
+ */
+static int
+rcu_torture_printk(char *page)
+{
+ int cnt = 0;
+ int cpu;
+ int i;
+ long pipesummary[RCU_TORTURE_PIPE_LEN + 1] = { 0 };
+ long batchsummary[RCU_TORTURE_PIPE_LEN + 1] = { 0 };
+
+ for_each_cpu(cpu) {
+ for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++) {
+ pipesummary[i] += per_cpu(rcu_torture_count, cpu)[i];
+ batchsummary[i] += per_cpu(rcu_torture_batch, cpu)[i];
+ }
+ }
+ for (i = RCU_TORTURE_PIPE_LEN - 1; i >= 0; i--) {
+ if (pipesummary[i] != 0)
+ break;
+ }
+ cnt += sprintf(&page[cnt], "rcutorture: ");
+ cnt += sprintf(&page[cnt],
+ "rtc: %p ver: %ld tfle: %d rta: %d rtaf: %d rtf: %d",
+ rcu_torture_current,
+ rcu_torture_current_version,
+ list_empty(&rcu_torture_freelist),
+ atomic_read(&n_rcu_torture_alloc),
+ atomic_read(&n_rcu_torture_alloc_fail),
+ atomic_read(&n_rcu_torture_free));
+ cnt += sprintf(&page[cnt], "\nrcutorture: ");
+ if (i > 1)
+ cnt += sprintf(&page[cnt], "!!! ");
+ cnt += sprintf(&page[cnt], "Reader Pipe: ");
+ for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++)
+ cnt += sprintf(&page[cnt], " %ld", pipesummary[i]);
+ cnt += sprintf(&page[cnt], "\nrcutorture: ");
+ cnt += sprintf(&page[cnt], "Reader Batch: ");
+ for (i = 0; i < RCU_TORTURE_PIPE_LEN; i++)
+ cnt += sprintf(&page[cnt], " %ld", batchsummary[i]);
+ cnt += sprintf(&page[cnt], "\nrcutorture: ");
+ cnt += sprintf(&page[cnt], "Free-Block Circulation: ");
+ for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++) {
+ cnt += sprintf(&page[cnt], " %d",
+ atomic_read(&rcu_torture_wcount[i]));
+ }
+ cnt += sprintf(&page[cnt], "\n");
+ return cnt;
+}
+
+/*
+ * Print torture statistics. Caller must ensure that there is only
+ * one call to this function at a given time!!! This is normally
+ * accomplished by relying on the module system to only have one copy
+ * of the module loaded, and then by giving the rcu_torture_stats
+ * kthread full control (or the init/cleanup functions when rcu_torture_stats
+ * thread is not running).
+ */
+static void
+rcu_torture_stats_print(void)
+{
+ int cnt;
+
+ cnt = rcu_torture_printk(printk_buf);
+ printk(KERN_ALERT "%s", printk_buf);
+}
+
+/*
+ * Periodically prints torture statistics, if periodic statistics printing
+ * was specified via the stat_interval module parameter.
+ *
+ * No need to worry about fullstop here, since this one doesn't reference
+ * volatile state or register callbacks.
+ */
+static int
+rcu_torture_stats(void *arg)
+{
+ VERBOSE_PRINTK_STRING("rcu_torture_stats task started");
+ do {
+ schedule_timeout_interruptible(stat_interval * HZ);
+ rcu_torture_stats_print();
+ } while (!kthread_should_stop());
+ VERBOSE_PRINTK_STRING("rcu_torture_stats task stopping");
+ return 0;
+}
+
+static void
+rcu_torture_cleanup(void)
+{
+ int i;
+
+ fullstop = 1;
+ if (writer_task != NULL) {
+ VERBOSE_PRINTK_STRING("Stopping rcu_torture_writer task");
+ kthread_stop(writer_task);
+ }
+ writer_task = NULL;
+
+ if (reader_tasks != NULL) {
+ for (i = 0; i < nrealreaders; i++) {
+ if (reader_tasks[i] != NULL) {
+ VERBOSE_PRINTK_STRING(
+ "Stopping rcu_torture_reader task");
+ kthread_stop(reader_tasks[i]);
+ }
+ reader_tasks[i] = NULL;
+ }
+ kfree(reader_tasks);
+ reader_tasks = NULL;
+ }
+ rcu_torture_current = NULL;
+
+ if (stats_task != NULL) {
+ VERBOSE_PRINTK_STRING("Stopping rcu_torture_stats task");
+ kthread_stop(stats_task);
+ }
+ stats_task = NULL;
+
+ /* Wait for all RCU callbacks to fire. */
+
+ for (i = 0; i < RCU_TORTURE_PIPE_LEN; i++)
+ synchronize_rcu();
+ rcu_torture_stats_print(); /* -After- the stats thread is stopped! */
+ PRINTK_STRING("--- End of test");
+}
+
+static int
+rcu_torture_init(void)
+{
+ int i;
+ int cpu;
+ int firsterr = 0;
+
+ /* Process args and tell the world that the torturer is on the job. */
+
+ if (nreaders >= 0)
+ nrealreaders = nreaders;
+ else
+ nrealreaders = 2 * num_online_cpus();
+ printk(KERN_ALERT TORTURE_FLAG
+ "--- Start of test: nreaders=%d stat_interval=%d verbose=%d\n",
+ nrealreaders, stat_interval, verbose);
+ fullstop = 0;
+
+ /* Set up the freelist. */
+
+ INIT_LIST_HEAD(&rcu_torture_freelist);
+ for (i = 0; i < sizeof(rcu_tortures) / sizeof(rcu_tortures[0]); i++) {
+ list_add_tail(&rcu_tortures[i].rtort_free,
+ &rcu_torture_freelist);
+ }
+
+ /* Initialize the statistics so that each run gets its own numbers. */
+
+ rcu_torture_current = NULL;
+ rcu_torture_current_version = 0;
+ atomic_set(&n_rcu_torture_alloc, 0);
+ atomic_set(&n_rcu_torture_alloc_fail, 0);
+ atomic_set(&n_rcu_torture_free, 0);
+ for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++)
+ atomic_set(&rcu_torture_wcount[i], 0);
+ for_each_cpu(cpu) {
+ for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++) {
+ per_cpu(rcu_torture_count, cpu)[i] = 0;
+ per_cpu(rcu_torture_batch, cpu)[i] = 0;
+ }
+ }
+
+ /* Start up the kthreads. */
+
+ VERBOSE_PRINTK_STRING("Creating rcu_torture_writer task");
+ writer_task = kthread_run(rcu_torture_writer, NULL,
+ "rcu_torture_writer");
+ if (IS_ERR(writer_task)) {
+ firsterr = PTR_ERR(writer_task);
+ VERBOSE_PRINTK_ERRSTRING("Failed to create writer");
+ writer_task = NULL;
+ goto unwind;
+ }
+ reader_tasks = kmalloc(nrealreaders * sizeof(reader_tasks[0]),
+ GFP_KERNEL);
+ if (reader_tasks == NULL) {
+ VERBOSE_PRINTK_ERRSTRING("out of memory");
+ firsterr = -ENOMEM;
+ goto unwind;
+ }
+ for (i = 0; i < nrealreaders; i++) {
+ VERBOSE_PRINTK_STRING("Creating rcu_torture_reader task");
+ reader_tasks[i] = kthread_run(rcu_torture_reader, NULL,
+ "rcu_torture_reader");
+ if (IS_ERR(reader_tasks[i])) {
+ firsterr = PTR_ERR(reader_tasks[i]);
+ VERBOSE_PRINTK_ERRSTRING("Failed to create reader");
+ reader_tasks[i] = NULL;
+ goto unwind;
+ }
+ }
+ if (stat_interval > 0) {
+ VERBOSE_PRINTK_STRING("Creating rcu_torture_stats task");
+ stats_task = kthread_run(rcu_torture_stats, NULL,
+ "rcu_torture_stats");
+ if (IS_ERR(stats_task)) {
+ firsterr = PTR_ERR(stats_task);
+ VERBOSE_PRINTK_ERRSTRING("Failed to create stats");
+ stats_task = NULL;
+ goto unwind;
+ }
+ }
+ return 0;
+
+unwind:
+ rcu_torture_cleanup();
+ return firsterr;
+}
+
+module_init(rcu_torture_init);
+module_exit(rcu_torture_cleanup);
diff --git a/kernel/sched.c b/kernel/sched.c
index 1e5cafdf4e27..340dd238c16d 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -2511,8 +2511,6 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
cpustat->idle = cputime64_add(cpustat->idle, tmp);
/* Account for system time used */
acct_update_integrals(p);
- /* Update rss highwater mark */
- update_mem_hiwater(p);
}
/*
@@ -3879,7 +3877,6 @@ EXPORT_SYMBOL(cpu_present_map);
#ifndef CONFIG_SMP
cpumask_t cpu_online_map = CPU_MASK_ALL;
-EXPORT_SYMBOL_GPL(cpu_online_map);
cpumask_t cpu_possible_map = CPU_MASK_ALL;
#endif
diff --git a/kernel/signal.c b/kernel/signal.c
index f2b96b08fb44..1bf3c39d6109 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -277,7 +277,6 @@ static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags,
} else {
INIT_LIST_HEAD(&q->list);
q->flags = 0;
- q->lock = NULL;
q->user = get_uid(t->user);
}
return(q);
@@ -406,6 +405,8 @@ void __exit_signal(struct task_struct *tsk)
void exit_signal(struct task_struct *tsk)
{
+ atomic_dec(&tsk->signal->live);
+
write_lock_irq(&tasklist_lock);
__exit_signal(tsk);
write_unlock_irq(&tasklist_lock);
@@ -650,8 +651,7 @@ static int check_kill_permission(int sig, struct siginfo *info,
if (!valid_signal(sig))
return error;
error = -EPERM;
- if ((!info || ((unsigned long)info != 1 &&
- (unsigned long)info != 2 && SI_FROMUSER(info)))
+ if ((info == SEND_SIG_NOINFO || (!is_si_special(info) && SI_FROMUSER(info)))
&& ((sig != SIGCONT) ||
(current->signal->session != t->signal->session))
&& (current->euid ^ t->suid) && (current->euid ^ t->uid)
@@ -788,7 +788,7 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
* fast-pathed signals for kernel-internal things like SIGSTOP
* or SIGKILL.
*/
- if ((unsigned long)info == 2)
+ if (info == SEND_SIG_FORCED)
goto out_set;
/* Real-time signals must be queued if sent by sigqueue, or
@@ -800,19 +800,19 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
pass on the info struct. */
q = __sigqueue_alloc(t, GFP_ATOMIC, (sig < SIGRTMIN &&
- ((unsigned long) info < 2 ||
+ (is_si_special(info) ||
info->si_code >= 0)));
if (q) {
list_add_tail(&q->list, &signals->list);
switch ((unsigned long) info) {
- case 0:
+ case (unsigned long) SEND_SIG_NOINFO:
q->info.si_signo = sig;
q->info.si_errno = 0;
q->info.si_code = SI_USER;
q->info.si_pid = current->pid;
q->info.si_uid = current->uid;
break;
- case 1:
+ case (unsigned long) SEND_SIG_PRIV:
q->info.si_signo = sig;
q->info.si_errno = 0;
q->info.si_code = SI_KERNEL;
@@ -823,20 +823,13 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
copy_siginfo(&q->info, info);
break;
}
- } else {
- if (sig >= SIGRTMIN && info && (unsigned long)info != 1
- && info->si_code != SI_USER)
+ } else if (!is_si_special(info)) {
+ if (sig >= SIGRTMIN && info->si_code != SI_USER)
/*
* Queue overflow, abort. We may abort if the signal was rt
* and sent by user using something other than kill().
*/
return -EAGAIN;
- if (((unsigned long)info > 1) && (info->si_code == SI_TIMER))
- /*
- * Set up a return to indicate that we dropped
- * the signal.
- */
- ret = info->si_sys_private;
}
out_set:
@@ -857,12 +850,6 @@ specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
BUG();
assert_spin_locked(&t->sighand->siglock);
- if (((unsigned long)info > 2) && (info->si_code == SI_TIMER))
- /*
- * Set up a return to indicate that we dropped the signal.
- */
- ret = info->si_sys_private;
-
/* Short-circuit ignored signals. */
if (sig_ignored(t, sig))
goto out;
@@ -892,11 +879,13 @@ force_sig_info(int sig, struct siginfo *info, struct task_struct *t)
int ret;
spin_lock_irqsave(&t->sighand->siglock, flags);
- if (sigismember(&t->blocked, sig) || t->sighand->action[sig-1].sa.sa_handler == SIG_IGN) {
+ if (t->sighand->action[sig-1].sa.sa_handler == SIG_IGN) {
t->sighand->action[sig-1].sa.sa_handler = SIG_DFL;
+ }
+ if (sigismember(&t->blocked, sig)) {
sigdelset(&t->blocked, sig);
- recalc_sigpending_tsk(t);
}
+ recalc_sigpending_tsk(t);
ret = specific_send_sig_info(sig, info, t);
spin_unlock_irqrestore(&t->sighand->siglock, flags);
@@ -906,15 +895,7 @@ force_sig_info(int sig, struct siginfo *info, struct task_struct *t)
void
force_sig_specific(int sig, struct task_struct *t)
{
- unsigned long int flags;
-
- spin_lock_irqsave(&t->sighand->siglock, flags);
- if (t->sighand->action[sig-1].sa.sa_handler == SIG_IGN)
- t->sighand->action[sig-1].sa.sa_handler = SIG_DFL;
- sigdelset(&t->blocked, sig);
- recalc_sigpending_tsk(t);
- specific_send_sig_info(sig, (void *)2, t);
- spin_unlock_irqrestore(&t->sighand->siglock, flags);
+ force_sig_info(sig, SEND_SIG_FORCED, t);
}
/*
@@ -1049,12 +1030,6 @@ __group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
assert_spin_locked(&p->sighand->siglock);
handle_stop_signal(sig, p);
- if (((unsigned long)info > 2) && (info->si_code == SI_TIMER))
- /*
- * Set up a return to indicate that we dropped the signal.
- */
- ret = info->si_sys_private;
-
/* Short-circuit ignored signals. */
if (sig_ignored(p, sig))
return ret;
@@ -1107,8 +1082,8 @@ void zap_other_threads(struct task_struct *p)
if (t != p->group_leader)
t->exit_signal = -1;
+ /* SIGKILL will be handled before any pending SIGSTOP */
sigaddset(&t->pending.signal, SIGKILL);
- rm_from_queue(SIG_KERNEL_STOP_MASK, &t->pending);
signal_wake_up(t, 1);
}
}
@@ -1284,10 +1259,13 @@ send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
return ret;
}
+#define __si_special(priv) \
+ ((priv) ? SEND_SIG_PRIV : SEND_SIG_NOINFO)
+
int
send_sig(int sig, struct task_struct *p, int priv)
{
- return send_sig_info(sig, (void*)(long)(priv != 0), p);
+ return send_sig_info(sig, __si_special(priv), p);
}
/*
@@ -1307,7 +1285,7 @@ send_group_sig_info(int sig, struct siginfo *info, struct task_struct *p)
void
force_sig(int sig, struct task_struct *p)
{
- force_sig_info(sig, (void*)1L, p);
+ force_sig_info(sig, SEND_SIG_PRIV, p);
}
/*
@@ -1332,13 +1310,13 @@ force_sigsegv(int sig, struct task_struct *p)
int
kill_pg(pid_t pgrp, int sig, int priv)
{
- return kill_pg_info(sig, (void *)(long)(priv != 0), pgrp);
+ return kill_pg_info(sig, __si_special(priv), pgrp);
}
int
kill_proc(pid_t pid, int sig, int priv)
{
- return kill_proc_info(sig, (void *)(long)(priv != 0), pid);
+ return kill_proc_info(sig, __si_special(priv), pid);
}
/*
@@ -1369,11 +1347,12 @@ void sigqueue_free(struct sigqueue *q)
* pending queue.
*/
if (unlikely(!list_empty(&q->list))) {
- read_lock(&tasklist_lock);
- spin_lock_irqsave(q->lock, flags);
+ spinlock_t *lock = &current->sighand->siglock;
+ read_lock(&tasklist_lock);
+ spin_lock_irqsave(lock, flags);
if (!list_empty(&q->list))
list_del_init(&q->list);
- spin_unlock_irqrestore(q->lock, flags);
+ spin_unlock_irqrestore(lock, flags);
read_unlock(&tasklist_lock);
}
q->flags &= ~SIGQUEUE_PREALLOC;
@@ -1412,7 +1391,6 @@ send_sigqueue(int sig, struct sigqueue *q, struct task_struct *p)
goto out;
}
- q->lock = &p->sighand->siglock;
list_add_tail(&q->list, &p->pending.list);
sigaddset(&p->pending.signal, sig);
if (!sigismember(&p->blocked, sig))
@@ -1460,7 +1438,6 @@ send_group_sigqueue(int sig, struct sigqueue *q, struct task_struct *p)
* We always use the shared queue for process-wide signals,
* to avoid several races.
*/
- q->lock = &p->sighand->siglock;
list_add_tail(&q->list, &p->signal->shared_pending.list);
sigaddset(&p->signal->shared_pending.signal, sig);
@@ -1879,9 +1856,9 @@ relock:
/* Let the debugger run. */
ptrace_stop(signr, signr, info);
- /* We're back. Did the debugger cancel the sig? */
+ /* We're back. Did the debugger cancel the sig or group_exit? */
signr = current->exit_code;
- if (signr == 0)
+ if (signr == 0 || current->signal->flags & SIGNAL_GROUP_EXIT)
continue;
current->exit_code = 0;
@@ -2283,26 +2260,13 @@ sys_kill(int pid, int sig)
return kill_something_info(sig, &info, pid);
}
-/**
- * sys_tgkill - send signal to one specific thread
- * @tgid: the thread group ID of the thread
- * @pid: the PID of the thread
- * @sig: signal to be sent
- *
- * This syscall also checks the tgid and returns -ESRCH even if the PID
- * exists but it's not belonging to the target process anymore. This
- * method solves the problem of threads exiting and PIDs getting reused.
- */
-asmlinkage long sys_tgkill(int tgid, int pid, int sig)
+static int do_tkill(int tgid, int pid, int sig)
{
- struct siginfo info;
int error;
+ struct siginfo info;
struct task_struct *p;
- /* This is only valid for single tasks */
- if (pid <= 0 || tgid <= 0)
- return -EINVAL;
-
+ error = -ESRCH;
info.si_signo = sig;
info.si_errno = 0;
info.si_code = SI_TKILL;
@@ -2311,8 +2275,7 @@ asmlinkage long sys_tgkill(int tgid, int pid, int sig)
read_lock(&tasklist_lock);
p = find_task_by_pid(pid);
- error = -ESRCH;
- if (p && (p->tgid == tgid)) {
+ if (p && (tgid <= 0 || p->tgid == tgid)) {
error = check_kill_permission(sig, &info, p);
/*
* The null signal is a permissions and process existence
@@ -2326,47 +2289,40 @@ asmlinkage long sys_tgkill(int tgid, int pid, int sig)
}
}
read_unlock(&tasklist_lock);
+
return error;
}
+/**
+ * sys_tgkill - send signal to one specific thread
+ * @tgid: the thread group ID of the thread
+ * @pid: the PID of the thread
+ * @sig: signal to be sent
+ *
+ * This syscall also checks the tgid and returns -ESRCH even if the PID
+ * exists but it's not belonging to the target process anymore. This
+ * method solves the problem of threads exiting and PIDs getting reused.
+ */
+asmlinkage long sys_tgkill(int tgid, int pid, int sig)
+{
+ /* This is only valid for single tasks */
+ if (pid <= 0 || tgid <= 0)
+ return -EINVAL;
+
+ return do_tkill(tgid, pid, sig);
+}
+
/*
* Send a signal to only one task, even if it's a CLONE_THREAD task.
*/
asmlinkage long
sys_tkill(int pid, int sig)
{
- struct siginfo info;
- int error;
- struct task_struct *p;
-
/* This is only valid for single tasks */
if (pid <= 0)
return -EINVAL;
- info.si_signo = sig;
- info.si_errno = 0;
- info.si_code = SI_TKILL;
- info.si_pid = current->tgid;
- info.si_uid = current->uid;
-
- read_lock(&tasklist_lock);
- p = find_task_by_pid(pid);
- error = -ESRCH;
- if (p) {
- error = check_kill_permission(sig, &info, p);
- /*
- * The null signal is a permissions and process existence
- * probe. No signal is actually delivered.
- */
- if (!error && sig && p->sighand) {
- spin_lock_irq(&p->sighand->siglock);
- handle_stop_signal(sig, p);
- error = specific_send_sig_info(sig, &info, p);
- spin_unlock_irq(&p->sighand->siglock);
- }
- }
- read_unlock(&tasklist_lock);
- return error;
+ return do_tkill(0, pid, sig);
}
asmlinkage long
diff --git a/kernel/time.c b/kernel/time.c
index 40c2410ac99a..245d595a13cb 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -338,30 +338,20 @@ int do_adjtimex(struct timex *txc)
if (mtemp >= MINSEC) {
ltemp = (time_offset / mtemp) << (SHIFT_USEC -
SHIFT_UPDATE);
- if (ltemp < 0)
- time_freq -= -ltemp >> SHIFT_KH;
- else
- time_freq += ltemp >> SHIFT_KH;
+ time_freq += shift_right(ltemp, SHIFT_KH);
} else /* calibration interval too short (p. 12) */
result = TIME_ERROR;
} else { /* PLL mode */
if (mtemp < MAXSEC) {
ltemp *= mtemp;
- if (ltemp < 0)
- time_freq -= -ltemp >> (time_constant +
- time_constant +
- SHIFT_KF - SHIFT_USEC);
- else
- time_freq += ltemp >> (time_constant +
+ time_freq += shift_right(ltemp,(time_constant +
time_constant +
- SHIFT_KF - SHIFT_USEC);
+ SHIFT_KF - SHIFT_USEC));
} else /* calibration interval too long (p. 12) */
result = TIME_ERROR;
}
- if (time_freq > time_tolerance)
- time_freq = time_tolerance;
- else if (time_freq < -time_tolerance)
- time_freq = -time_tolerance;
+ time_freq = min(time_freq, time_tolerance);
+ time_freq = max(time_freq, -time_tolerance);
} /* STA_PLL || STA_PPSTIME */
} /* txc->modes & ADJ_OFFSET */
if (txc->modes & ADJ_TICK) {
@@ -384,10 +374,7 @@ leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0
if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT)
txc->offset = save_adjust;
else {
- if (time_offset < 0)
- txc->offset = -(-time_offset >> SHIFT_UPDATE);
- else
- txc->offset = time_offset >> SHIFT_UPDATE;
+ txc->offset = shift_right(time_offset, SHIFT_UPDATE);
}
txc->freq = time_freq + pps_freq;
txc->maxerror = time_maxerror;
@@ -532,6 +519,7 @@ int do_settimeofday (struct timespec *tv)
clock_was_set();
return 0;
}
+EXPORT_SYMBOL(do_settimeofday);
void do_gettimeofday (struct timeval *tv)
{
diff --git a/kernel/timer.c b/kernel/timer.c
index 3ba10fa35b60..fd74268d8663 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -46,6 +46,10 @@ static void time_interpolator_update(long delta_nsec);
#define time_interpolator_update(x)
#endif
+u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;
+
+EXPORT_SYMBOL(jiffies_64);
+
/*
* per-CPU timer vector definitions:
*/
@@ -91,30 +95,6 @@ static inline void set_running_timer(tvec_base_t *base,
#endif
}
-static void check_timer_failed(struct timer_list *timer)
-{
- static int whine_count;
- if (whine_count < 16) {
- whine_count++;
- printk("Uninitialised timer!\n");
- printk("This is just a warning. Your computer is OK\n");
- printk("function=0x%p, data=0x%lx\n",
- timer->function, timer->data);
- dump_stack();
- }
- /*
- * Now fix it up
- */
- timer->magic = TIMER_MAGIC;
-}
-
-static inline void check_timer(struct timer_list *timer)
-{
- if (timer->magic != TIMER_MAGIC)
- check_timer_failed(timer);
-}
-
-
static void internal_add_timer(tvec_base_t *base, struct timer_list *timer)
{
unsigned long expires = timer->expires;
@@ -177,7 +157,6 @@ void fastcall init_timer(struct timer_list *timer)
{
timer->entry.next = NULL;
timer->base = &per_cpu(tvec_bases, raw_smp_processor_id()).t_base;
- timer->magic = TIMER_MAGIC;
}
EXPORT_SYMBOL(init_timer);
@@ -230,7 +209,6 @@ int __mod_timer(struct timer_list *timer, unsigned long expires)
int ret = 0;
BUG_ON(!timer->function);
- check_timer(timer);
base = lock_timer_base(timer, &flags);
@@ -283,9 +261,6 @@ void add_timer_on(struct timer_list *timer, int cpu)
unsigned long flags;
BUG_ON(timer_pending(timer) || !timer->function);
-
- check_timer(timer);
-
spin_lock_irqsave(&base->t_base.lock, flags);
timer->base = &base->t_base;
internal_add_timer(base, timer);
@@ -316,8 +291,6 @@ int mod_timer(struct timer_list *timer, unsigned long expires)
{
BUG_ON(!timer->function);
- check_timer(timer);
-
/*
* This is a common optimization triggered by the
* networking code - if the timer is re-modified
@@ -348,8 +321,6 @@ int del_timer(struct timer_list *timer)
unsigned long flags;
int ret = 0;
- check_timer(timer);
-
if (timer_pending(timer)) {
base = lock_timer_base(timer, &flags);
if (timer_pending(timer)) {
@@ -412,8 +383,6 @@ out:
*/
int del_timer_sync(struct timer_list *timer)
{
- check_timer(timer);
-
for (;;) {
int ret = try_to_del_timer_sync(timer);
if (ret >= 0)
@@ -632,134 +601,118 @@ long time_next_adjust;
*/
static void second_overflow(void)
{
- long ltemp;
-
- /* Bump the maxerror field */
- time_maxerror += time_tolerance >> SHIFT_USEC;
- if ( time_maxerror > NTP_PHASE_LIMIT ) {
- time_maxerror = NTP_PHASE_LIMIT;
- time_status |= STA_UNSYNC;
- }
-
- /*
- * Leap second processing. If in leap-insert state at
- * the end of the day, the system clock is set back one
- * second; if in leap-delete state, the system clock is
- * set ahead one second. The microtime() routine or
- * external clock driver will insure that reported time
- * is always monotonic. The ugly divides should be
- * replaced.
- */
- switch (time_state) {
-
- case TIME_OK:
- if (time_status & STA_INS)
- time_state = TIME_INS;
- else if (time_status & STA_DEL)
- time_state = TIME_DEL;
- break;
-
- case TIME_INS:
- if (xtime.tv_sec % 86400 == 0) {
- xtime.tv_sec--;
- wall_to_monotonic.tv_sec++;
- /* The timer interpolator will make time change gradually instead
- * of an immediate jump by one second.
- */
- time_interpolator_update(-NSEC_PER_SEC);
- time_state = TIME_OOP;
- clock_was_set();
- printk(KERN_NOTICE "Clock: inserting leap second 23:59:60 UTC\n");
+ long ltemp;
+
+ /* Bump the maxerror field */
+ time_maxerror += time_tolerance >> SHIFT_USEC;
+ if (time_maxerror > NTP_PHASE_LIMIT) {
+ time_maxerror = NTP_PHASE_LIMIT;
+ time_status |= STA_UNSYNC;
}
- break;
-
- case TIME_DEL:
- if ((xtime.tv_sec + 1) % 86400 == 0) {
- xtime.tv_sec++;
- wall_to_monotonic.tv_sec--;
- /* Use of time interpolator for a gradual change of time */
- time_interpolator_update(NSEC_PER_SEC);
- time_state = TIME_WAIT;
- clock_was_set();
- printk(KERN_NOTICE "Clock: deleting leap second 23:59:59 UTC\n");
+
+ /*
+ * Leap second processing. If in leap-insert state at the end of the
+ * day, the system clock is set back one second; if in leap-delete
+ * state, the system clock is set ahead one second. The microtime()
+ * routine or external clock driver will insure that reported time is
+ * always monotonic. The ugly divides should be replaced.
+ */
+ switch (time_state) {
+ case TIME_OK:
+ if (time_status & STA_INS)
+ time_state = TIME_INS;
+ else if (time_status & STA_DEL)
+ time_state = TIME_DEL;
+ break;
+ case TIME_INS:
+ if (xtime.tv_sec % 86400 == 0) {
+ xtime.tv_sec--;
+ wall_to_monotonic.tv_sec++;
+ /*
+ * The timer interpolator will make time change
+ * gradually instead of an immediate jump by one second
+ */
+ time_interpolator_update(-NSEC_PER_SEC);
+ time_state = TIME_OOP;
+ clock_was_set();
+ printk(KERN_NOTICE "Clock: inserting leap second "
+ "23:59:60 UTC\n");
+ }
+ break;
+ case TIME_DEL:
+ if ((xtime.tv_sec + 1) % 86400 == 0) {
+ xtime.tv_sec++;
+ wall_to_monotonic.tv_sec--;
+ /*
+ * Use of time interpolator for a gradual change of
+ * time
+ */
+ time_interpolator_update(NSEC_PER_SEC);
+ time_state = TIME_WAIT;
+ clock_was_set();
+ printk(KERN_NOTICE "Clock: deleting leap second "
+ "23:59:59 UTC\n");
+ }
+ break;
+ case TIME_OOP:
+ time_state = TIME_WAIT;
+ break;
+ case TIME_WAIT:
+ if (!(time_status & (STA_INS | STA_DEL)))
+ time_state = TIME_OK;
}
- break;
-
- case TIME_OOP:
- time_state = TIME_WAIT;
- break;
-
- case TIME_WAIT:
- if (!(time_status & (STA_INS | STA_DEL)))
- time_state = TIME_OK;
- }
-
- /*
- * Compute the phase adjustment for the next second. In
- * PLL mode, the offset is reduced by a fixed factor
- * times the time constant. In FLL mode the offset is
- * used directly. In either mode, the maximum phase
- * adjustment for each second is clamped so as to spread
- * the adjustment over not more than the number of
- * seconds between updates.
- */
- if (time_offset < 0) {
- ltemp = -time_offset;
- if (!(time_status & STA_FLL))
- ltemp >>= SHIFT_KG + time_constant;
- if (ltemp > (MAXPHASE / MINSEC) << SHIFT_UPDATE)
- ltemp = (MAXPHASE / MINSEC) << SHIFT_UPDATE;
- time_offset += ltemp;
- time_adj = -ltemp << (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE);
- } else {
+
+ /*
+ * Compute the phase adjustment for the next second. In PLL mode, the
+ * offset is reduced by a fixed factor times the time constant. In FLL
+ * mode the offset is used directly. In either mode, the maximum phase
+ * adjustment for each second is clamped so as to spread the adjustment
+ * over not more than the number of seconds between updates.
+ */
ltemp = time_offset;
if (!(time_status & STA_FLL))
- ltemp >>= SHIFT_KG + time_constant;
- if (ltemp > (MAXPHASE / MINSEC) << SHIFT_UPDATE)
- ltemp = (MAXPHASE / MINSEC) << SHIFT_UPDATE;
+ ltemp = shift_right(ltemp, SHIFT_KG + time_constant);
+ ltemp = min(ltemp, (MAXPHASE / MINSEC) << SHIFT_UPDATE);
+ ltemp = max(ltemp, -(MAXPHASE / MINSEC) << SHIFT_UPDATE);
time_offset -= ltemp;
time_adj = ltemp << (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE);
- }
-
- /*
- * Compute the frequency estimate and additional phase
- * adjustment due to frequency error for the next
- * second. When the PPS signal is engaged, gnaw on the
- * watchdog counter and update the frequency computed by
- * the pll and the PPS signal.
- */
- pps_valid++;
- if (pps_valid == PPS_VALID) { /* PPS signal lost */
- pps_jitter = MAXTIME;
- pps_stabil = MAXFREQ;
- time_status &= ~(STA_PPSSIGNAL | STA_PPSJITTER |
- STA_PPSWANDER | STA_PPSERROR);
- }
- ltemp = time_freq + pps_freq;
- if (ltemp < 0)
- time_adj -= -ltemp >>
- (SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE);
- else
- time_adj += ltemp >>
- (SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE);
+
+ /*
+ * Compute the frequency estimate and additional phase adjustment due
+ * to frequency error for the next second. When the PPS signal is
+ * engaged, gnaw on the watchdog counter and update the frequency
+ * computed by the pll and the PPS signal.
+ */
+ pps_valid++;
+ if (pps_valid == PPS_VALID) { /* PPS signal lost */
+ pps_jitter = MAXTIME;
+ pps_stabil = MAXFREQ;
+ time_status &= ~(STA_PPSSIGNAL | STA_PPSJITTER |
+ STA_PPSWANDER | STA_PPSERROR);
+ }
+ ltemp = time_freq + pps_freq;
+ time_adj += shift_right(ltemp,(SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE));
#if HZ == 100
- /* Compensate for (HZ==100) != (1 << SHIFT_HZ).
- * Add 25% and 3.125% to get 128.125; => only 0.125% error (p. 14)
- */
- if (time_adj < 0)
- time_adj -= (-time_adj >> 2) + (-time_adj >> 5);
- else
- time_adj += (time_adj >> 2) + (time_adj >> 5);
+ /*
+ * Compensate for (HZ==100) != (1 << SHIFT_HZ). Add 25% and 3.125% to
+ * get 128.125; => only 0.125% error (p. 14)
+ */
+ time_adj += shift_right(time_adj, 2) + shift_right(time_adj, 5);
+#endif
+#if HZ == 250
+ /*
+ * Compensate for (HZ==250) != (1 << SHIFT_HZ). Add 1.5625% and
+ * 0.78125% to get 255.85938; => only 0.05% error (p. 14)
+ */
+ time_adj += shift_right(time_adj, 6) + shift_right(time_adj, 7);
#endif
#if HZ == 1000
- /* Compensate for (HZ==1000) != (1 << SHIFT_HZ).
- * Add 1.5625% and 0.78125% to get 1023.4375; => only 0.05% error (p. 14)
- */
- if (time_adj < 0)
- time_adj -= (-time_adj >> 6) + (-time_adj >> 7);
- else
- time_adj += (time_adj >> 6) + (time_adj >> 7);
+ /*
+ * Compensate for (HZ==1000) != (1 << SHIFT_HZ). Add 1.5625% and
+ * 0.78125% to get 1023.4375; => only 0.05% error (p. 14)
+ */
+ time_adj += shift_right(time_adj, 6) + shift_right(time_adj, 7);
#endif
}
@@ -768,23 +721,20 @@ static void update_wall_time_one_tick(void)
{
long time_adjust_step, delta_nsec;
- if ( (time_adjust_step = time_adjust) != 0 ) {
- /* We are doing an adjtime thing.
- *
- * Prepare time_adjust_step to be within bounds.
- * Note that a positive time_adjust means we want the clock
- * to run faster.
- *
- * Limit the amount of the step to be in the range
- * -tickadj .. +tickadj
- */
- if (time_adjust > tickadj)
- time_adjust_step = tickadj;
- else if (time_adjust < -tickadj)
- time_adjust_step = -tickadj;
-
- /* Reduce by this step the amount of time left */
- time_adjust -= time_adjust_step;
+ if ((time_adjust_step = time_adjust) != 0 ) {
+ /*
+ * We are doing an adjtime thing. Prepare time_adjust_step to
+ * be within bounds. Note that a positive time_adjust means we
+ * want the clock to run faster.
+ *
+ * Limit the amount of the step to be in the range
+ * -tickadj .. +tickadj
+ */
+ time_adjust_step = min(time_adjust_step, (long)tickadj);
+ time_adjust_step = max(time_adjust_step, (long)-tickadj);
+
+ /* Reduce by this step the amount of time left */
+ time_adjust -= time_adjust_step;
}
delta_nsec = tick_nsec + time_adjust_step * 1000;
/*
@@ -792,13 +742,8 @@ static void update_wall_time_one_tick(void)
* advance the tick more.
*/
time_phase += time_adj;
- if (time_phase <= -FINENSEC) {
- long ltemp = -time_phase >> (SHIFT_SCALE - 10);
- time_phase += ltemp << (SHIFT_SCALE - 10);
- delta_nsec -= ltemp;
- }
- else if (time_phase >= FINENSEC) {
- long ltemp = time_phase >> (SHIFT_SCALE - 10);
+ if ((time_phase >= FINENSEC) || (time_phase <= -FINENSEC)) {
+ long ltemp = shift_right(time_phase, (SHIFT_SCALE - 10));
time_phase -= ltemp << (SHIFT_SCALE - 10);
delta_nsec += ltemp;
}
@@ -1128,8 +1073,8 @@ fastcall signed long __sched schedule_timeout(signed long timeout)
if (timeout < 0)
{
printk(KERN_ERR "schedule_timeout: wrong timeout "
- "value %lx from %p\n", timeout,
- __builtin_return_address(0));
+ "value %lx from %p\n", timeout,
+ __builtin_return_address(0));
current->state = TASK_RUNNING;
goto out;
}
@@ -1137,12 +1082,8 @@ fastcall signed long __sched schedule_timeout(signed long timeout)
expire = timeout + jiffies;
- init_timer(&timer);
- timer.expires = expire;
- timer.data = (unsigned long) current;
- timer.function = process_timeout;
-
- add_timer(&timer);
+ setup_timer(&timer, process_timeout, (unsigned long)current);
+ __mod_timer(&timer, expire);
schedule();
del_singleshot_timer_sync(&timer);
@@ -1159,15 +1100,15 @@ EXPORT_SYMBOL(schedule_timeout);
*/
signed long __sched schedule_timeout_interruptible(signed long timeout)
{
- __set_current_state(TASK_INTERRUPTIBLE);
- return schedule_timeout(timeout);
+ __set_current_state(TASK_INTERRUPTIBLE);
+ return schedule_timeout(timeout);
}
EXPORT_SYMBOL(schedule_timeout_interruptible);
signed long __sched schedule_timeout_uninterruptible(signed long timeout)
{
- __set_current_state(TASK_UNINTERRUPTIBLE);
- return schedule_timeout(timeout);
+ __set_current_state(TASK_UNINTERRUPTIBLE);
+ return schedule_timeout(timeout);
}
EXPORT_SYMBOL(schedule_timeout_uninterruptible);
@@ -1507,16 +1448,18 @@ static void time_interpolator_update(long delta_nsec)
if (!time_interpolator)
return;
- /* The interpolator compensates for late ticks by accumulating
- * the late time in time_interpolator->offset. A tick earlier than
- * expected will lead to a reset of the offset and a corresponding
- * jump of the clock forward. Again this only works if the
- * interpolator clock is running slightly slower than the regular clock
- * and the tuning logic insures that.
- */
+ /*
+ * The interpolator compensates for late ticks by accumulating the late
+ * time in time_interpolator->offset. A tick earlier than expected will
+ * lead to a reset of the offset and a corresponding jump of the clock
+ * forward. Again this only works if the interpolator clock is running
+ * slightly slower than the regular clock and the tuning logic insures
+ * that.
+ */
counter = time_interpolator_get_counter(1);
- offset = time_interpolator->offset + GET_TI_NSECS(counter, time_interpolator);
+ offset = time_interpolator->offset +
+ GET_TI_NSECS(counter, time_interpolator);
if (delta_nsec < 0 || (unsigned long) delta_nsec < offset)
time_interpolator->offset = offset - delta_nsec;
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 91bacb13a7e2..7cee222231bc 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -12,6 +12,8 @@
* Andrew Morton <andrewm@uow.edu.au>
* Kai Petzke <wpp@marie.physik.tu-berlin.de>
* Theodore Ts'o <tytso@mit.edu>
+ *
+ * Made to use alloc_percpu by Christoph Lameter <clameter@sgi.com>.
*/
#include <linux/module.h>
@@ -57,7 +59,7 @@ struct cpu_workqueue_struct {
* per-CPU workqueues:
*/
struct workqueue_struct {
- struct cpu_workqueue_struct cpu_wq[NR_CPUS];
+ struct cpu_workqueue_struct *cpu_wq;
const char *name;
struct list_head list; /* Empty if single thread */
};
@@ -102,7 +104,7 @@ int fastcall queue_work(struct workqueue_struct *wq, struct work_struct *work)
if (unlikely(is_single_threaded(wq)))
cpu = 0;
BUG_ON(!list_empty(&work->entry));
- __queue_work(wq->cpu_wq + cpu, work);
+ __queue_work(per_cpu_ptr(wq->cpu_wq, cpu), work);
ret = 1;
}
put_cpu();
@@ -118,7 +120,7 @@ static void delayed_work_timer_fn(unsigned long __data)
if (unlikely(is_single_threaded(wq)))
cpu = 0;
- __queue_work(wq->cpu_wq + cpu, work);
+ __queue_work(per_cpu_ptr(wq->cpu_wq, cpu), work);
}
int fastcall queue_delayed_work(struct workqueue_struct *wq,
@@ -265,13 +267,13 @@ void fastcall flush_workqueue(struct workqueue_struct *wq)
if (is_single_threaded(wq)) {
/* Always use cpu 0's area. */
- flush_cpu_workqueue(wq->cpu_wq + 0);
+ flush_cpu_workqueue(per_cpu_ptr(wq->cpu_wq, 0));
} else {
int cpu;
lock_cpu_hotplug();
for_each_online_cpu(cpu)
- flush_cpu_workqueue(wq->cpu_wq + cpu);
+ flush_cpu_workqueue(per_cpu_ptr(wq->cpu_wq, cpu));
unlock_cpu_hotplug();
}
}
@@ -279,7 +281,7 @@ void fastcall flush_workqueue(struct workqueue_struct *wq)
static struct task_struct *create_workqueue_thread(struct workqueue_struct *wq,
int cpu)
{
- struct cpu_workqueue_struct *cwq = wq->cpu_wq + cpu;
+ struct cpu_workqueue_struct *cwq = per_cpu_ptr(wq->cpu_wq, cpu);
struct task_struct *p;
spin_lock_init(&cwq->lock);
@@ -312,6 +314,7 @@ struct workqueue_struct *__create_workqueue(const char *name,
if (!wq)
return NULL;
+ wq->cpu_wq = alloc_percpu(struct cpu_workqueue_struct);
wq->name = name;
/* We don't need the distraction of CPUs appearing and vanishing. */
lock_cpu_hotplug();
@@ -353,7 +356,7 @@ static void cleanup_workqueue_thread(struct workqueue_struct *wq, int cpu)
unsigned long flags;
struct task_struct *p;
- cwq = wq->cpu_wq + cpu;
+ cwq = per_cpu_ptr(wq->cpu_wq, cpu);
spin_lock_irqsave(&cwq->lock, flags);
p = cwq->thread;
cwq->thread = NULL;
@@ -380,6 +383,7 @@ void destroy_workqueue(struct workqueue_struct *wq)
spin_unlock(&workqueue_lock);
}
unlock_cpu_hotplug();
+ free_percpu(wq->cpu_wq);
kfree(wq);
}
@@ -458,7 +462,7 @@ int current_is_keventd(void)
BUG_ON(!keventd_wq);
- cwq = keventd_wq->cpu_wq + cpu;
+ cwq = per_cpu_ptr(keventd_wq->cpu_wq, cpu);
if (current == cwq->thread)
ret = 1;
@@ -470,7 +474,7 @@ int current_is_keventd(void)
/* Take the work from this (downed) CPU. */
static void take_over_work(struct workqueue_struct *wq, unsigned int cpu)
{
- struct cpu_workqueue_struct *cwq = wq->cpu_wq + cpu;
+ struct cpu_workqueue_struct *cwq = per_cpu_ptr(wq->cpu_wq, cpu);
LIST_HEAD(list);
struct work_struct *work;
@@ -481,7 +485,7 @@ static void take_over_work(struct workqueue_struct *wq, unsigned int cpu)
printk("Taking work for %s\n", wq->name);
work = list_entry(list.next,struct work_struct,entry);
list_del(&work->entry);
- __queue_work(wq->cpu_wq + smp_processor_id(), work);
+ __queue_work(per_cpu_ptr(wq->cpu_wq, smp_processor_id()), work);
}
spin_unlock_irq(&cwq->lock);
}
@@ -508,15 +512,18 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb,
case CPU_ONLINE:
/* Kick off worker threads. */
list_for_each_entry(wq, &workqueues, list) {
- kthread_bind(wq->cpu_wq[hotcpu].thread, hotcpu);
- wake_up_process(wq->cpu_wq[hotcpu].thread);
+ struct cpu_workqueue_struct *cwq;
+
+ cwq = per_cpu_ptr(wq->cpu_wq, hotcpu);
+ kthread_bind(cwq->thread, hotcpu);
+ wake_up_process(cwq->thread);
}
break;
case CPU_UP_CANCELED:
list_for_each_entry(wq, &workqueues, list) {
/* Unbind so it can run. */
- kthread_bind(wq->cpu_wq[hotcpu].thread,
+ kthread_bind(per_cpu_ptr(wq->cpu_wq, hotcpu)->thread,
smp_processor_id());
cleanup_workqueue_thread(wq, hotcpu);
}
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 016e89a44ac8..156822e3cc79 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -128,7 +128,7 @@ config DEBUG_HIGHMEM
config DEBUG_BUGVERBOSE
bool "Verbose BUG() reporting (adds 70K)" if DEBUG_KERNEL && EMBEDDED
depends on BUG
- depends on ARM || ARM26 || M32R || M68K || SPARC32 || SPARC64 || (X86 && !X86_64) || FRV
+ depends on ARM || ARM26 || M32R || M68K || SPARC32 || SPARC64 || X86_32 || FRV
default !EMBEDDED
help
Say Y here to make BUG() panics output the file name and line number
@@ -168,13 +168,34 @@ config DEBUG_FS
If unsure, say N.
+config DEBUG_VM
+ bool "Debug VM"
+ depends on DEBUG_KERNEL
+ help
+ Enable this to debug the virtual-memory system.
+
+ If unsure, say N.
+
config FRAME_POINTER
bool "Compile the kernel with frame pointers"
depends on DEBUG_KERNEL && (X86 || CRIS || M68K || M68KNOMMU || FRV || UML)
default y if DEBUG_INFO && UML
help
If you say Y here the resulting kernel image will be slightly larger
- and slower, but it might give very useful debugging information
- on some architectures or you use external debuggers.
+ and slower, but it might give very useful debugging information on
+ some architectures or if you use external debuggers.
If you don't debug the kernel, you can say N.
+config RCU_TORTURE_TEST
+ tristate "torture tests for RCU"
+ depends on DEBUG_KERNEL
+ default n
+ help
+ This option provides a kernel module that runs torture tests
+ on the RCU infrastructure. The kernel module may be built
+ after the fact on the running kernel to be tested, if desired.
+
+ Say Y here if you want RCU torture tests to start automatically
+ at boot time (you probably don't).
+ Say M if you want the RCU torture tests to build as a module.
+ Say N if you are unsure.
diff --git a/lib/bitmap.c b/lib/bitmap.c
index fb9371fdd44a..23d3b1147fe9 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -511,6 +511,172 @@ int bitmap_parselist(const char *bp, unsigned long *maskp, int nmaskbits)
}
EXPORT_SYMBOL(bitmap_parselist);
+/*
+ * bitmap_pos_to_ord(buf, pos, bits)
+ * @buf: pointer to a bitmap
+ * @pos: a bit position in @buf (0 <= @pos < @bits)
+ * @bits: number of valid bit positions in @buf
+ *
+ * Map the bit at position @pos in @buf (of length @bits) to the
+ * ordinal of which set bit it is. If it is not set or if @pos
+ * is not a valid bit position, map to zero (0).
+ *
+ * If for example, just bits 4 through 7 are set in @buf, then @pos
+ * values 4 through 7 will get mapped to 0 through 3, respectively,
+ * and other @pos values will get mapped to 0. When @pos value 7
+ * gets mapped to (returns) @ord value 3 in this example, that means
+ * that bit 7 is the 3rd (starting with 0th) set bit in @buf.
+ *
+ * The bit positions 0 through @bits are valid positions in @buf.
+ */
+static int bitmap_pos_to_ord(const unsigned long *buf, int pos, int bits)
+{
+ int ord = 0;
+
+ if (pos >= 0 && pos < bits) {
+ int i;
+
+ for (i = find_first_bit(buf, bits);
+ i < pos;
+ i = find_next_bit(buf, bits, i + 1))
+ ord++;
+ if (i > pos)
+ ord = 0;
+ }
+ return ord;
+}
+
+/**
+ * bitmap_ord_to_pos(buf, ord, bits)
+ * @buf: pointer to bitmap
+ * @ord: ordinal bit position (n-th set bit, n >= 0)
+ * @bits: number of valid bit positions in @buf
+ *
+ * Map the ordinal offset of bit @ord in @buf to its position in @buf.
+ * If @ord is not the ordinal offset of a set bit in @buf, map to zero (0).
+ *
+ * If for example, just bits 4 through 7 are set in @buf, then @ord
+ * values 0 through 3 will get mapped to 4 through 7, respectively,
+ * and all other @ord valuds will get mapped to 0. When @ord value 3
+ * gets mapped to (returns) @pos value 7 in this example, that means
+ * that the 3rd set bit (starting with 0th) is at position 7 in @buf.
+ *
+ * The bit positions 0 through @bits are valid positions in @buf.
+ */
+static int bitmap_ord_to_pos(const unsigned long *buf, int ord, int bits)
+{
+ int pos = 0;
+
+ if (ord >= 0 && ord < bits) {
+ int i;
+
+ for (i = find_first_bit(buf, bits);
+ i < bits && ord > 0;
+ i = find_next_bit(buf, bits, i + 1))
+ ord--;
+ if (i < bits && ord == 0)
+ pos = i;
+ }
+
+ return pos;
+}
+
+/**
+ * bitmap_remap - Apply map defined by a pair of bitmaps to another bitmap
+ * @src: subset to be remapped
+ * @dst: remapped result
+ * @old: defines domain of map
+ * @new: defines range of map
+ * @bits: number of bits in each of these bitmaps
+ *
+ * Let @old and @new define a mapping of bit positions, such that
+ * whatever position is held by the n-th set bit in @old is mapped
+ * to the n-th set bit in @new. In the more general case, allowing
+ * for the possibility that the weight 'w' of @new is less than the
+ * weight of @old, map the position of the n-th set bit in @old to
+ * the position of the m-th set bit in @new, where m == n % w.
+ *
+ * If either of the @old and @new bitmaps are empty, or if@src and @dst
+ * point to the same location, then this routine does nothing.
+ *
+ * The positions of unset bits in @old are mapped to the position of
+ * the first set bit in @new.
+ *
+ * Apply the above specified mapping to @src, placing the result in
+ * @dst, clearing any bits previously set in @dst.
+ *
+ * The resulting value of @dst will have either the same weight as
+ * @src, or less weight in the general case that the mapping wasn't
+ * injective due to the weight of @new being less than that of @old.
+ * The resulting value of @dst will never have greater weight than
+ * that of @src, except perhaps in the case that one of the above
+ * conditions was not met and this routine just returned.
+ *
+ * For example, lets say that @old has bits 4 through 7 set, and
+ * @new has bits 12 through 15 set. This defines the mapping of bit
+ * position 4 to 12, 5 to 13, 6 to 14 and 7 to 15, and of all other
+ * bit positions to 12 (the first set bit in @new. So if say @src
+ * comes into this routine with bits 1, 5 and 7 set, then @dst should
+ * leave with bits 12, 13 and 15 set.
+ */
+void bitmap_remap(unsigned long *dst, const unsigned long *src,
+ const unsigned long *old, const unsigned long *new,
+ int bits)
+{
+ int s;
+
+ if (bitmap_weight(old, bits) == 0)
+ return;
+ if (bitmap_weight(new, bits) == 0)
+ return;
+ if (dst == src) /* following doesn't handle inplace remaps */
+ return;
+
+ bitmap_zero(dst, bits);
+ for (s = find_first_bit(src, bits);
+ s < bits;
+ s = find_next_bit(src, bits, s + 1)) {
+ int x = bitmap_pos_to_ord(old, s, bits);
+ int y = bitmap_ord_to_pos(new, x, bits);
+ set_bit(y, dst);
+ }
+}
+EXPORT_SYMBOL(bitmap_remap);
+
+/**
+ * bitmap_bitremap - Apply map defined by a pair of bitmaps to a single bit
+ * @oldbit - bit position to be mapped
+ * @old: defines domain of map
+ * @new: defines range of map
+ * @bits: number of bits in each of these bitmaps
+ *
+ * Let @old and @new define a mapping of bit positions, such that
+ * whatever position is held by the n-th set bit in @old is mapped
+ * to the n-th set bit in @new. In the more general case, allowing
+ * for the possibility that the weight 'w' of @new is less than the
+ * weight of @old, map the position of the n-th set bit in @old to
+ * the position of the m-th set bit in @new, where m == n % w.
+ *
+ * The positions of unset bits in @old are mapped to the position of
+ * the first set bit in @new.
+ *
+ * Apply the above specified mapping to bit position @oldbit, returning
+ * the new bit position.
+ *
+ * For example, lets say that @old has bits 4 through 7 set, and
+ * @new has bits 12 through 15 set. This defines the mapping of bit
+ * position 4 to 12, 5 to 13, 6 to 14 and 7 to 15, and of all other
+ * bit positions to 12 (the first set bit in @new. So if say @oldbit
+ * is 5, then this routine returns 13.
+ */
+int bitmap_bitremap(int oldbit, const unsigned long *old,
+ const unsigned long *new, int bits)
+{
+ int x = bitmap_pos_to_ord(old, oldbit, bits);
+ return bitmap_ord_to_pos(new, x, bits);
+}
+EXPORT_SYMBOL(bitmap_bitremap);
+
/**
* bitmap_find_free_region - find a contiguous aligned mem region
* @bitmap: an array of unsigned longs corresponding to the bitmap
diff --git a/lib/extable.c b/lib/extable.c
index 3f677a8f0c3c..18df57c029df 100644
--- a/lib/extable.c
+++ b/lib/extable.c
@@ -16,9 +16,6 @@
#include <linux/sort.h>
#include <asm/uaccess.h>
-extern struct exception_table_entry __start___ex_table[];
-extern struct exception_table_entry __stop___ex_table[];
-
#ifndef ARCH_HAS_SORT_EXTABLE
/*
* The exception table needs to be sorted so that the binary
diff --git a/lib/idr.c b/lib/idr.c
index 6414b2fb482d..d226259c3c28 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -6,20 +6,20 @@
* Modified by George Anzinger to reuse immediately and to use
* find bit instructions. Also removed _irq on spinlocks.
*
- * Small id to pointer translation service.
+ * Small id to pointer translation service.
*
- * It uses a radix tree like structure as a sparse array indexed
+ * It uses a radix tree like structure as a sparse array indexed
* by the id to obtain the pointer. The bitmap makes allocating
- * a new id quick.
+ * a new id quick.
*
* You call it to allocate an id (an int) an associate with that id a
* pointer or what ever, we treat it as a (void *). You can pass this
* id to a user for him to pass back at a later time. You then pass
* that id to this code and it returns your pointer.
- * You can release ids at any time. When all ids are released, most of
+ * You can release ids at any time. When all ids are released, most of
* the memory is returned (we keep IDR_FREE_MAX) in a local pool so we
- * don't need to go to the memory "store" during an id allocate, just
+ * don't need to go to the memory "store" during an id allocate, just
* so you don't need to be too concerned about locking and conflicts
* with the slab allocator.
*/
@@ -77,7 +77,7 @@ int idr_pre_get(struct idr *idp, gfp_t gfp_mask)
while (idp->id_free_cnt < IDR_FREE_MAX) {
struct idr_layer *new;
new = kmem_cache_alloc(idr_layer_cache, gfp_mask);
- if(new == NULL)
+ if (new == NULL)
return (0);
free_layer(idp, new);
}
@@ -107,7 +107,7 @@ static int sub_alloc(struct idr *idp, void *ptr, int *starting_id)
if (m == IDR_SIZE) {
/* no space available go back to previous layer. */
l++;
- id = (id | ((1 << (IDR_BITS*l))-1)) + 1;
+ id = (id | ((1 << (IDR_BITS * l)) - 1)) + 1;
if (!(p = pa[l])) {
*starting_id = id;
return -2;
@@ -161,7 +161,7 @@ static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id)
{
struct idr_layer *p, *new;
int layers, v, id;
-
+
id = starting_id;
build_up:
p = idp->top;
@@ -225,6 +225,7 @@ build_up:
int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id)
{
int rv;
+
rv = idr_get_new_above_int(idp, ptr, starting_id);
/*
* This is a cheap hack until the IDR code can be fixed to
@@ -259,6 +260,7 @@ EXPORT_SYMBOL(idr_get_new_above);
int idr_get_new(struct idr *idp, void *ptr, int *id)
{
int rv;
+
rv = idr_get_new_above_int(idp, ptr, 0);
/*
* This is a cheap hack until the IDR code can be fixed to
@@ -306,11 +308,10 @@ static void sub_remove(struct idr *idp, int shift, int id)
free_layer(idp, **paa);
**paa-- = NULL;
}
- if ( ! *paa )
+ if (!*paa)
idp->layers = 0;
- } else {
+ } else
idr_remove_warning(id);
- }
}
/**
@@ -326,9 +327,8 @@ void idr_remove(struct idr *idp, int id)
id &= MAX_ID_MASK;
sub_remove(idp, (idp->layers - 1) * IDR_BITS, id);
- if ( idp->top && idp->top->count == 1 &&
- (idp->layers > 1) &&
- idp->top->ary[0]){ // We can drop a layer
+ if (idp->top && idp->top->count == 1 && (idp->layers > 1) &&
+ idp->top->ary[0]) { // We can drop a layer
p = idp->top->ary[0];
idp->top->bitmap = idp->top->count = 0;
@@ -337,7 +337,6 @@ void idr_remove(struct idr *idp, int id)
--idp->layers;
}
while (idp->id_free_cnt >= IDR_FREE_MAX) {
-
p = alloc_layer(idp);
kmem_cache_free(idr_layer_cache, p);
return;
@@ -391,8 +390,8 @@ void *idr_find(struct idr *idp, int id)
}
EXPORT_SYMBOL(idr_find);
-static void idr_cache_ctor(void * idr_layer,
- kmem_cache_t *idr_layer_cache, unsigned long flags)
+static void idr_cache_ctor(void * idr_layer, kmem_cache_t *idr_layer_cache,
+ unsigned long flags)
{
memset(idr_layer, 0, sizeof(struct idr_layer));
}
@@ -400,7 +399,7 @@ static void idr_cache_ctor(void * idr_layer,
static int init_id_cache(void)
{
if (!idr_layer_cache)
- idr_layer_cache = kmem_cache_create("idr_layer_cache",
+ idr_layer_cache = kmem_cache_create("idr_layer_cache",
sizeof(struct idr_layer), 0, 0, idr_cache_ctor, NULL);
return 0;
}
diff --git a/lib/kobject.c b/lib/kobject.c
index 253d3004ace9..a181abed89f6 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -14,6 +14,7 @@
#include <linux/string.h>
#include <linux/module.h>
#include <linux/stat.h>
+#include <linux/slab.h>
/**
* populate_dir - populate directory with attributes.
diff --git a/lib/smp_processor_id.c b/lib/smp_processor_id.c
index 42c08ef828c5..eddc9b3d3876 100644
--- a/lib/smp_processor_id.c
+++ b/lib/smp_processor_id.c
@@ -5,6 +5,7 @@
*/
#include <linux/module.h>
#include <linux/kallsyms.h>
+#include <linux/sched.h>
unsigned int debug_smp_processor_id(void)
{
diff --git a/lib/sort.c b/lib/sort.c
index ddc4d35df289..5f3b51ffa1dc 100644
--- a/lib/sort.c
+++ b/lib/sort.c
@@ -7,6 +7,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sort.h>
+#include <linux/slab.h>
static void u32_swap(void *a, void *b, int size)
{
diff --git a/lib/string.c b/lib/string.c
index d886ef157c12..037a48acedbb 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -36,11 +36,13 @@ int strnicmp(const char *s1, const char *s2, size_t len)
/* Yes, Virginia, it had better be unsigned */
unsigned char c1, c2;
- c1 = 0; c2 = 0;
+ c1 = c2 = 0;
if (len) {
do {
- c1 = *s1; c2 = *s2;
- s1++; s2++;
+ c1 = *s1;
+ c2 = *s2;
+ s1++;
+ s2++;
if (!c1)
break;
if (!c2)
@@ -55,7 +57,6 @@ int strnicmp(const char *s1, const char *s2, size_t len)
}
return (int)c1 - (int)c2;
}
-
EXPORT_SYMBOL(strnicmp);
#endif
@@ -66,7 +67,7 @@ EXPORT_SYMBOL(strnicmp);
* @src: Where to copy the string from
*/
#undef strcpy
-char * strcpy(char * dest,const char *src)
+char *strcpy(char *dest, const char *src)
{
char *tmp = dest;
@@ -91,12 +92,13 @@ EXPORT_SYMBOL(strcpy);
* count, the remainder of @dest will be padded with %NUL.
*
*/
-char * strncpy(char * dest,const char *src,size_t count)
+char *strncpy(char *dest, const char *src, size_t count)
{
char *tmp = dest;
while (count) {
- if ((*tmp = *src) != 0) src++;
+ if ((*tmp = *src) != 0)
+ src++;
tmp++;
count--;
}
@@ -122,7 +124,7 @@ size_t strlcpy(char *dest, const char *src, size_t size)
size_t ret = strlen(src);
if (size) {
- size_t len = (ret >= size) ? size-1 : ret;
+ size_t len = (ret >= size) ? size - 1 : ret;
memcpy(dest, src, len);
dest[len] = '\0';
}
@@ -138,7 +140,7 @@ EXPORT_SYMBOL(strlcpy);
* @src: The string to append to it
*/
#undef strcat
-char * strcat(char * dest, const char * src)
+char *strcat(char *dest, const char *src)
{
char *tmp = dest;
@@ -146,7 +148,6 @@ char * strcat(char * dest, const char * src)
dest++;
while ((*dest++ = *src++) != '\0')
;
-
return tmp;
}
EXPORT_SYMBOL(strcat);
@@ -162,7 +163,7 @@ EXPORT_SYMBOL(strcat);
* Note that in contrast to strncpy, strncat ensures the result is
* terminated.
*/
-char * strncat(char *dest, const char *src, size_t count)
+char *strncat(char *dest, const char *src, size_t count)
{
char *tmp = dest;
@@ -176,7 +177,6 @@ char * strncat(char *dest, const char *src, size_t count)
}
}
}
-
return tmp;
}
EXPORT_SYMBOL(strncat);
@@ -216,15 +216,14 @@ EXPORT_SYMBOL(strlcat);
* @ct: Another string
*/
#undef strcmp
-int strcmp(const char * cs,const char * ct)
+int strcmp(const char *cs, const char *ct)
{
- register signed char __res;
+ signed char __res;
while (1) {
if ((__res = *cs - *ct++) != 0 || !*cs++)
break;
}
-
return __res;
}
EXPORT_SYMBOL(strcmp);
@@ -237,16 +236,15 @@ EXPORT_SYMBOL(strcmp);
* @ct: Another string
* @count: The maximum number of bytes to compare
*/
-int strncmp(const char * cs,const char * ct,size_t count)
+int strncmp(const char *cs, const char *ct, size_t count)
{
- register signed char __res = 0;
+ signed char __res = 0;
while (count) {
if ((__res = *cs - *ct++) != 0 || !*cs++)
break;
count--;
}
-
return __res;
}
EXPORT_SYMBOL(strncmp);
@@ -258,12 +256,12 @@ EXPORT_SYMBOL(strncmp);
* @s: The string to be searched
* @c: The character to search for
*/
-char * strchr(const char * s, int c)
+char *strchr(const char *s, int c)
{
- for(; *s != (char) c; ++s)
+ for (; *s != (char)c; ++s)
if (*s == '\0')
return NULL;
- return (char *) s;
+ return (char *)s;
}
EXPORT_SYMBOL(strchr);
#endif
@@ -274,7 +272,7 @@ EXPORT_SYMBOL(strchr);
* @s: The string to be searched
* @c: The character to search for
*/
-char * strrchr(const char * s, int c)
+char *strrchr(const char *s, int c)
{
const char *p = s + strlen(s);
do {
@@ -296,8 +294,8 @@ EXPORT_SYMBOL(strrchr);
char *strnchr(const char *s, size_t count, int c)
{
for (; count-- && *s != '\0'; ++s)
- if (*s == (char) c)
- return (char *) s;
+ if (*s == (char)c)
+ return (char *)s;
return NULL;
}
EXPORT_SYMBOL(strnchr);
@@ -308,7 +306,7 @@ EXPORT_SYMBOL(strnchr);
* strlen - Find the length of a string
* @s: The string to be sized
*/
-size_t strlen(const char * s)
+size_t strlen(const char *s)
{
const char *sc;
@@ -325,7 +323,7 @@ EXPORT_SYMBOL(strlen);
* @s: The string to be sized
* @count: The maximum number of bytes to search
*/
-size_t strnlen(const char * s, size_t count)
+size_t strnlen(const char *s, size_t count)
{
const char *sc;
@@ -358,7 +356,6 @@ size_t strspn(const char *s, const char *accept)
return count;
++count;
}
-
return count;
}
@@ -384,9 +381,8 @@ size_t strcspn(const char *s, const char *reject)
}
++count;
}
-
return count;
-}
+}
EXPORT_SYMBOL(strcspn);
#ifndef __HAVE_ARCH_STRPBRK
@@ -395,14 +391,14 @@ EXPORT_SYMBOL(strcspn);
* @cs: The string to be searched
* @ct: The characters to search for
*/
-char * strpbrk(const char * cs,const char * ct)
+char *strpbrk(const char *cs, const char *ct)
{
- const char *sc1,*sc2;
+ const char *sc1, *sc2;
- for( sc1 = cs; *sc1 != '\0'; ++sc1) {
- for( sc2 = ct; *sc2 != '\0'; ++sc2) {
+ for (sc1 = cs; *sc1 != '\0'; ++sc1) {
+ for (sc2 = ct; *sc2 != '\0'; ++sc2) {
if (*sc1 == *sc2)
- return (char *) sc1;
+ return (char *)sc1;
}
}
return NULL;
@@ -422,9 +418,10 @@ EXPORT_SYMBOL(strpbrk);
* of that name. In fact, it was stolen from glibc2 and de-fancy-fied.
* Same semantics, slimmer shape. ;)
*/
-char * strsep(char **s, const char *ct)
+char *strsep(char **s, const char *ct)
{
- char *sbegin = *s, *end;
+ char *sbegin = *s;
+ char *end;
if (sbegin == NULL)
return NULL;
@@ -433,10 +430,8 @@ char * strsep(char **s, const char *ct)
if (end)
*end++ = '\0';
*s = end;
-
return sbegin;
}
-
EXPORT_SYMBOL(strsep);
#endif
@@ -449,13 +444,12 @@ EXPORT_SYMBOL(strsep);
*
* Do not use memset() to access IO space, use memset_io() instead.
*/
-void * memset(void * s,int c,size_t count)
+void *memset(void *s, int c, size_t count)
{
- char *xs = (char *) s;
+ char *xs = s;
while (count--)
*xs++ = c;
-
return s;
}
EXPORT_SYMBOL(memset);
@@ -471,13 +465,13 @@ EXPORT_SYMBOL(memset);
* You should not use this function to access IO space, use memcpy_toio()
* or memcpy_fromio() instead.
*/
-void * memcpy(void * dest,const void *src,size_t count)
+void *memcpy(void *dest, const void *src, size_t count)
{
- char *tmp = (char *) dest, *s = (char *) src;
+ char *tmp = dest;
+ char *s = src;
while (count--)
*tmp++ = *s++;
-
return dest;
}
EXPORT_SYMBOL(memcpy);
@@ -492,23 +486,24 @@ EXPORT_SYMBOL(memcpy);
*
* Unlike memcpy(), memmove() copes with overlapping areas.
*/
-void * memmove(void * dest,const void *src,size_t count)
+void *memmove(void *dest, const void *src, size_t count)
{
- char *tmp, *s;
+ char *tmp;
+ const char *s;
if (dest <= src) {
- tmp = (char *) dest;
- s = (char *) src;
+ tmp = dest;
+ s = src;
while (count--)
*tmp++ = *s++;
- }
- else {
- tmp = (char *) dest + count;
- s = (char *) src + count;
+ } else {
+ tmp = dest;
+ tmp += count;
+ s = src;
+ s += count;
while (count--)
*--tmp = *--s;
- }
-
+ }
return dest;
}
EXPORT_SYMBOL(memmove);
@@ -522,12 +517,12 @@ EXPORT_SYMBOL(memmove);
* @count: The size of the area.
*/
#undef memcmp
-int memcmp(const void * cs,const void * ct,size_t count)
+int memcmp(const void *cs, const void *ct, size_t count)
{
const unsigned char *su1, *su2;
int res = 0;
- for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
+ for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
if ((res = *su1 - *su2) != 0)
break;
return res;
@@ -545,17 +540,17 @@ EXPORT_SYMBOL(memcmp);
* returns the address of the first occurrence of @c, or 1 byte past
* the area if @c is not found
*/
-void * memscan(void * addr, int c, size_t size)
+void *memscan(void *addr, int c, size_t size)
{
- unsigned char * p = (unsigned char *) addr;
+ unsigned char *p = addr;
while (size) {
if (*p == c)
- return (void *) p;
+ return (void *)p;
p++;
size--;
}
- return (void *) p;
+ return (void *)p;
}
EXPORT_SYMBOL(memscan);
#endif
@@ -566,18 +561,18 @@ EXPORT_SYMBOL(memscan);
* @s1: The string to be searched
* @s2: The string to search for
*/
-char * strstr(const char * s1,const char * s2)
+char *strstr(const char *s1, const char *s2)
{
int l1, l2;
l2 = strlen(s2);
if (!l2)
- return (char *) s1;
+ return (char *)s1;
l1 = strlen(s1);
while (l1 >= l2) {
l1--;
- if (!memcmp(s1,s2,l2))
- return (char *) s1;
+ if (!memcmp(s1, s2, l2))
+ return (char *)s1;
s1++;
}
return NULL;
@@ -600,7 +595,7 @@ void *memchr(const void *s, int c, size_t n)
const unsigned char *p = s;
while (n-- != 0) {
if ((unsigned char)c == *p++) {
- return (void *)(p-1);
+ return (void *)(p - 1);
}
}
return NULL;
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index e4e9031dd9c3..b07db5ca3f66 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -23,6 +23,7 @@
#include <linux/ctype.h>
#include <linux/kernel.h>
+#include <asm/page.h> /* for PAGE_SIZE */
#include <asm/div64.h>
/**
diff --git a/lib/zlib_inflate/inflate.c b/lib/zlib_inflate/inflate.c
index 3d94cb90c1d3..31b9e9054bf7 100644
--- a/lib/zlib_inflate/inflate.c
+++ b/lib/zlib_inflate/inflate.c
@@ -3,7 +3,6 @@
* For conditions of distribution and use, see copyright notice in zlib.h
*/
-#include <linux/module.h>
#include <linux/zutil.h>
#include "infblock.h"
#include "infutil.h"
diff --git a/mm/Kconfig b/mm/Kconfig
index 391ffc54d136..1a4473fcb2ca 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -111,3 +111,24 @@ config SPARSEMEM_STATIC
config SPARSEMEM_EXTREME
def_bool y
depends on SPARSEMEM && !SPARSEMEM_STATIC
+
+# eventually, we can have this option just 'select SPARSEMEM'
+config MEMORY_HOTPLUG
+ bool "Allow for memory hot-add"
+ depends on SPARSEMEM && HOTPLUG && !SOFTWARE_SUSPEND
+
+comment "Memory hotplug is currently incompatible with Software Suspend"
+ depends on SPARSEMEM && HOTPLUG && SOFTWARE_SUSPEND
+
+# Heavily threaded applications may benefit from splitting the mm-wide
+# page_table_lock, so that faults on different parts of the user address
+# space can be handled with less contention: split it at this NR_CPUS.
+# Default to 4 for wider testing, though 8 might be more appropriate.
+# ARM's adjust_pte (unused if VIPT) depends on mm-wide page_table_lock.
+# PA-RISC's debug spinlock_t is too large for the 32-bit struct page.
+#
+config SPLIT_PTLOCK_CPUS
+ int
+ default "4096" if ARM && !CPU_CACHE_VIPT
+ default "4096" if PARISC && DEBUG_SPINLOCK && !64BIT
+ default "4"
diff --git a/mm/Makefile b/mm/Makefile
index 4cd69e3ce421..2fa6d2ca9f28 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -18,5 +18,5 @@ obj-$(CONFIG_NUMA) += mempolicy.o
obj-$(CONFIG_SPARSEMEM) += sparse.o
obj-$(CONFIG_SHMEM) += shmem.o
obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o
-
+obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o
obj-$(CONFIG_FS_XIP) += filemap_xip.o
diff --git a/mm/bootmem.c b/mm/bootmem.c
index a58699b6579e..e8c567177dcf 100644
--- a/mm/bootmem.c
+++ b/mm/bootmem.c
@@ -305,6 +305,7 @@ static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat)
if (j + 16 < BITS_PER_LONG)
prefetchw(page + j + 16);
__ClearPageReserved(page + j);
+ set_page_count(page + j, 0);
}
__free_pages(page, order);
i += BITS_PER_LONG;
diff --git a/mm/filemap.c b/mm/filemap.c
index 1c31b2fd2ca5..5d6e4c2000dc 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -66,7 +66,7 @@ generic_file_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
*
* ->mmap_sem
* ->i_mmap_lock
- * ->page_table_lock (various places, mainly in mmap.c)
+ * ->page_table_lock or pte_lock (various, mainly in memory.c)
* ->mapping->tree_lock (arch-dependent flush_dcache_mmap_lock)
*
* ->mmap_sem
@@ -86,9 +86,9 @@ generic_file_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
* ->anon_vma.lock (vma_adjust)
*
* ->anon_vma.lock
- * ->page_table_lock (anon_vma_prepare and various)
+ * ->page_table_lock or pte_lock (anon_vma_prepare and various)
*
- * ->page_table_lock
+ * ->page_table_lock or pte_lock
* ->swap_lock (try_to_unmap_one)
* ->private_lock (try_to_unmap_one)
* ->tree_lock (try_to_unmap_one)
@@ -152,7 +152,7 @@ static int sync_page(void *word)
* in the ->sync_page() methods make essential use of the
* page_mapping(), merely passing the page down to the backing
* device's unplug functions when it's non-NULL, which in turn
- * ignore it for all cases but swap, where only page->private is
+ * ignore it for all cases but swap, where only page_private(page) is
* of interest. When page_mapping() does go NULL, the entire
* call stack gracefully ignores the page and returns.
* -- wli
@@ -1030,8 +1030,8 @@ __generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
desc.error = 0;
do_generic_file_read(filp,ppos,&desc,file_read_actor);
retval += desc.written;
- if (!retval) {
- retval = desc.error;
+ if (desc.error) {
+ retval = retval ?: desc.error;
break;
}
}
@@ -1520,7 +1520,7 @@ repeat:
page_cache_release(page);
return err;
}
- } else {
+ } else if (vma->vm_flags & VM_NONLINEAR) {
/* No page was found just because we can't read it in now (being
* here implies nonblock != 0), but the page may exist, so set
* the PTE to fault it in later. */
@@ -1537,6 +1537,7 @@ repeat:
return 0;
}
+EXPORT_SYMBOL(filemap_populate);
struct vm_operations_struct generic_file_vm_ops = {
.nopage = filemap_nopage,
@@ -1555,7 +1556,6 @@ int generic_file_mmap(struct file * file, struct vm_area_struct * vma)
vma->vm_ops = &generic_file_vm_ops;
return 0;
}
-EXPORT_SYMBOL(filemap_populate);
/*
* This is for filesystems which do not implement ->writepage.
diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c
index 8c199f537732..9cf687e4a29a 100644
--- a/mm/filemap_xip.c
+++ b/mm/filemap_xip.c
@@ -174,6 +174,8 @@ __xip_unmap (struct address_space * mapping,
unsigned long address;
pte_t *pte;
pte_t pteval;
+ spinlock_t *ptl;
+ struct page *page;
spin_lock(&mapping->i_mmap_lock);
vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
@@ -181,19 +183,17 @@ __xip_unmap (struct address_space * mapping,
address = vma->vm_start +
((pgoff - vma->vm_pgoff) << PAGE_SHIFT);
BUG_ON(address < vma->vm_start || address >= vma->vm_end);
- /*
- * We need the page_table_lock to protect us from page faults,
- * munmap, fork, etc...
- */
- pte = page_check_address(ZERO_PAGE(address), mm,
- address);
- if (!IS_ERR(pte)) {
+ page = ZERO_PAGE(address);
+ pte = page_check_address(page, mm, address, &ptl);
+ if (pte) {
/* Nuke the page table entry. */
flush_cache_page(vma, address, pte_pfn(*pte));
pteval = ptep_clear_flush(vma, address, pte);
+ page_remove_rmap(page);
+ dec_mm_counter(mm, file_rss);
BUG_ON(pte_dirty(pteval));
- pte_unmap(pte);
- spin_unlock(&mm->page_table_lock);
+ pte_unmap_unlock(pte, ptl);
+ page_cache_release(page);
}
}
spin_unlock(&mapping->i_mmap_lock);
@@ -228,7 +228,7 @@ xip_file_nopage(struct vm_area_struct * area,
page = mapping->a_ops->get_xip_page(mapping, pgoff*(PAGE_SIZE/512), 0);
if (!IS_ERR(page)) {
- return page;
+ goto out;
}
if (PTR_ERR(page) != -ENODATA)
return NULL;
@@ -249,6 +249,8 @@ xip_file_nopage(struct vm_area_struct * area,
page = ZERO_PAGE(address);
}
+out:
+ page_cache_get(page);
return page;
}
diff --git a/mm/fremap.c b/mm/fremap.c
index ab23a0673c35..d862be3bc3e3 100644
--- a/mm/fremap.c
+++ b/mm/fremap.c
@@ -20,33 +20,32 @@
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
-static inline void zap_pte(struct mm_struct *mm, struct vm_area_struct *vma,
+static int zap_pte(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep)
{
pte_t pte = *ptep;
+ struct page *page = NULL;
- if (pte_none(pte))
- return;
if (pte_present(pte)) {
unsigned long pfn = pte_pfn(pte);
-
flush_cache_page(vma, addr, pfn);
pte = ptep_clear_flush(vma, addr, ptep);
- if (pfn_valid(pfn)) {
- struct page *page = pfn_to_page(pfn);
- if (!PageReserved(page)) {
- if (pte_dirty(pte))
- set_page_dirty(page);
- page_remove_rmap(page);
- page_cache_release(page);
- dec_mm_counter(mm, rss);
- }
+ if (unlikely(!pfn_valid(pfn))) {
+ print_bad_pte(vma, pte, addr);
+ goto out;
}
+ page = pfn_to_page(pfn);
+ if (pte_dirty(pte))
+ set_page_dirty(page);
+ page_remove_rmap(page);
+ page_cache_release(page);
} else {
if (!pte_file(pte))
free_swap_and_cache(pte_to_swp_entry(pte));
pte_clear(mm, addr, ptep);
}
+out:
+ return !!page;
}
/*
@@ -64,21 +63,20 @@ int install_page(struct mm_struct *mm, struct vm_area_struct *vma,
pud_t *pud;
pgd_t *pgd;
pte_t pte_val;
+ spinlock_t *ptl;
+
+ BUG_ON(vma->vm_flags & VM_RESERVED);
pgd = pgd_offset(mm, addr);
- spin_lock(&mm->page_table_lock);
-
pud = pud_alloc(mm, pgd, addr);
if (!pud)
- goto err_unlock;
-
+ goto out;
pmd = pmd_alloc(mm, pud, addr);
if (!pmd)
- goto err_unlock;
-
- pte = pte_alloc_map(mm, pmd, addr);
+ goto out;
+ pte = pte_alloc_map_lock(mm, pmd, addr, &ptl);
if (!pte)
- goto err_unlock;
+ goto out;
/*
* This page may have been truncated. Tell the
@@ -88,29 +86,27 @@ int install_page(struct mm_struct *mm, struct vm_area_struct *vma,
inode = vma->vm_file->f_mapping->host;
size = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
if (!page->mapping || page->index >= size)
- goto err_unlock;
+ goto unlock;
err = -ENOMEM;
if (page_mapcount(page) > INT_MAX/2)
- goto err_unlock;
+ goto unlock;
- zap_pte(mm, vma, addr, pte);
+ if (pte_none(*pte) || !zap_pte(mm, vma, addr, pte))
+ inc_mm_counter(mm, file_rss);
- inc_mm_counter(mm,rss);
flush_icache_page(vma, page);
set_pte_at(mm, addr, pte, mk_pte(page, prot));
page_add_file_rmap(page);
pte_val = *pte;
- pte_unmap(pte);
update_mmu_cache(vma, addr, pte_val);
-
err = 0;
-err_unlock:
- spin_unlock(&mm->page_table_lock);
+unlock:
+ pte_unmap_unlock(pte, ptl);
+out:
return err;
}
EXPORT_SYMBOL(install_page);
-
/*
* Install a file pte to a given virtual memory address, release any
* previously existing mapping.
@@ -124,37 +120,35 @@ int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma,
pud_t *pud;
pgd_t *pgd;
pte_t pte_val;
+ spinlock_t *ptl;
+
+ BUG_ON(vma->vm_flags & VM_RESERVED);
pgd = pgd_offset(mm, addr);
- spin_lock(&mm->page_table_lock);
-
pud = pud_alloc(mm, pgd, addr);
if (!pud)
- goto err_unlock;
-
+ goto out;
pmd = pmd_alloc(mm, pud, addr);
if (!pmd)
- goto err_unlock;
-
- pte = pte_alloc_map(mm, pmd, addr);
+ goto out;
+ pte = pte_alloc_map_lock(mm, pmd, addr, &ptl);
if (!pte)
- goto err_unlock;
+ goto out;
- zap_pte(mm, vma, addr, pte);
+ if (!pte_none(*pte) && zap_pte(mm, vma, addr, pte)) {
+ update_hiwater_rss(mm);
+ dec_mm_counter(mm, file_rss);
+ }
set_pte_at(mm, addr, pte, pgoff_to_pte(pgoff));
pte_val = *pte;
- pte_unmap(pte);
update_mmu_cache(vma, addr, pte_val);
- spin_unlock(&mm->page_table_lock);
- return 0;
-
-err_unlock:
- spin_unlock(&mm->page_table_lock);
+ pte_unmap_unlock(pte, ptl);
+ err = 0;
+out:
return err;
}
-
/***
* sys_remap_file_pages - remap arbitrary pages of a shared backing store
* file within an existing vma.
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 61d380678030..c9b43360fd33 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -277,19 +277,23 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
unsigned long addr;
for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) {
+ src_pte = huge_pte_offset(src, addr);
+ if (!src_pte)
+ continue;
dst_pte = huge_pte_alloc(dst, addr);
if (!dst_pte)
goto nomem;
+ spin_lock(&dst->page_table_lock);
spin_lock(&src->page_table_lock);
- src_pte = huge_pte_offset(src, addr);
- if (src_pte && !pte_none(*src_pte)) {
+ if (!pte_none(*src_pte)) {
entry = *src_pte;
ptepage = pte_page(entry);
get_page(ptepage);
- add_mm_counter(dst, rss, HPAGE_SIZE / PAGE_SIZE);
+ add_mm_counter(dst, file_rss, HPAGE_SIZE / PAGE_SIZE);
set_huge_pte_at(dst, addr, dst_pte, entry);
}
spin_unlock(&src->page_table_lock);
+ spin_unlock(&dst->page_table_lock);
}
return 0;
@@ -310,12 +314,14 @@ void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start,
BUG_ON(start & ~HPAGE_MASK);
BUG_ON(end & ~HPAGE_MASK);
+ spin_lock(&mm->page_table_lock);
+
+ /* Update high watermark before we lower rss */
+ update_hiwater_rss(mm);
+
for (address = start; address < end; address += HPAGE_SIZE) {
ptep = huge_pte_offset(mm, address);
- if (! ptep)
- /* This can happen on truncate, or if an
- * mmap() is aborted due to an error before
- * the prefault */
+ if (!ptep)
continue;
pte = huge_ptep_get_and_clear(mm, address, ptep);
@@ -324,96 +330,99 @@ void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start,
page = pte_page(pte);
put_page(page);
- add_mm_counter(mm, rss, - (HPAGE_SIZE / PAGE_SIZE));
+ add_mm_counter(mm, file_rss, (int) -(HPAGE_SIZE / PAGE_SIZE));
}
- flush_tlb_range(vma, start, end);
-}
-
-void zap_hugepage_range(struct vm_area_struct *vma,
- unsigned long start, unsigned long length)
-{
- struct mm_struct *mm = vma->vm_mm;
- spin_lock(&mm->page_table_lock);
- unmap_hugepage_range(vma, start, start + length);
spin_unlock(&mm->page_table_lock);
+ flush_tlb_range(vma, start, end);
}
-int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma)
+static struct page *find_lock_huge_page(struct address_space *mapping,
+ unsigned long idx)
{
- struct mm_struct *mm = current->mm;
- unsigned long addr;
- int ret = 0;
-
- WARN_ON(!is_vm_hugetlb_page(vma));
- BUG_ON(vma->vm_start & ~HPAGE_MASK);
- BUG_ON(vma->vm_end & ~HPAGE_MASK);
-
- hugetlb_prefault_arch_hook(mm);
-
- spin_lock(&mm->page_table_lock);
- for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) {
- unsigned long idx;
- pte_t *pte = huge_pte_alloc(mm, addr);
- struct page *page;
-
- if (!pte) {
- ret = -ENOMEM;
- goto out;
- }
+ struct page *page;
+ int err;
+ struct inode *inode = mapping->host;
+ unsigned long size;
+
+retry:
+ page = find_lock_page(mapping, idx);
+ if (page)
+ goto out;
+
+ /* Check to make sure the mapping hasn't been truncated */
+ size = i_size_read(inode) >> HPAGE_SHIFT;
+ if (idx >= size)
+ goto out;
+
+ if (hugetlb_get_quota(mapping))
+ goto out;
+ page = alloc_huge_page();
+ if (!page) {
+ hugetlb_put_quota(mapping);
+ goto out;
+ }
- idx = ((addr - vma->vm_start) >> HPAGE_SHIFT)
- + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
- page = find_get_page(mapping, idx);
- if (!page) {
- /* charge the fs quota first */
- if (hugetlb_get_quota(mapping)) {
- ret = -ENOMEM;
- goto out;
- }
- page = alloc_huge_page();
- if (!page) {
- hugetlb_put_quota(mapping);
- ret = -ENOMEM;
- goto out;
- }
- ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC);
- if (! ret) {
- unlock_page(page);
- } else {
- hugetlb_put_quota(mapping);
- free_huge_page(page);
- goto out;
- }
- }
- add_mm_counter(mm, rss, HPAGE_SIZE / PAGE_SIZE);
- set_huge_pte_at(mm, addr, pte, make_huge_pte(vma, page));
+ err = add_to_page_cache(page, mapping, idx, GFP_KERNEL);
+ if (err) {
+ put_page(page);
+ hugetlb_put_quota(mapping);
+ if (err == -EEXIST)
+ goto retry;
+ page = NULL;
}
out:
- spin_unlock(&mm->page_table_lock);
- return ret;
+ return page;
}
-/*
- * On ia64 at least, it is possible to receive a hugetlb fault from a
- * stale zero entry left in the TLB from earlier hardware prefetching.
- * Low-level arch code should already have flushed the stale entry as
- * part of its fault handling, but we do need to accept this minor fault
- * and return successfully. Whereas the "normal" case is that this is
- * an access to a hugetlb page which has been truncated off since mmap.
- */
int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long address, int write_access)
{
int ret = VM_FAULT_SIGBUS;
+ unsigned long idx;
+ unsigned long size;
pte_t *pte;
+ struct page *page;
+ struct address_space *mapping;
+
+ pte = huge_pte_alloc(mm, address);
+ if (!pte)
+ goto out;
+
+ mapping = vma->vm_file->f_mapping;
+ idx = ((address - vma->vm_start) >> HPAGE_SHIFT)
+ + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
+
+ /*
+ * Use page lock to guard against racing truncation
+ * before we get page_table_lock.
+ */
+ page = find_lock_huge_page(mapping, idx);
+ if (!page)
+ goto out;
spin_lock(&mm->page_table_lock);
- pte = huge_pte_offset(mm, address);
- if (pte && !pte_none(*pte))
- ret = VM_FAULT_MINOR;
+ size = i_size_read(mapping->host) >> HPAGE_SHIFT;
+ if (idx >= size)
+ goto backout;
+
+ ret = VM_FAULT_MINOR;
+ if (!pte_none(*pte))
+ goto backout;
+
+ add_mm_counter(mm, file_rss, HPAGE_SIZE / PAGE_SIZE);
+ set_huge_pte_at(mm, address, pte, make_huge_pte(vma, page));
spin_unlock(&mm->page_table_lock);
+ unlock_page(page);
+out:
return ret;
+
+backout:
+ spin_unlock(&mm->page_table_lock);
+ hugetlb_put_quota(mapping);
+ unlock_page(page);
+ put_page(page);
+ goto out;
}
int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
@@ -423,34 +432,36 @@ int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long vpfn, vaddr = *position;
int remainder = *length;
- BUG_ON(!is_vm_hugetlb_page(vma));
-
vpfn = vaddr/PAGE_SIZE;
spin_lock(&mm->page_table_lock);
while (vaddr < vma->vm_end && remainder) {
+ pte_t *pte;
+ struct page *page;
- if (pages) {
- pte_t *pte;
- struct page *page;
-
- /* Some archs (sparc64, sh*) have multiple
- * pte_ts to each hugepage. We have to make
- * sure we get the first, for the page
- * indexing below to work. */
- pte = huge_pte_offset(mm, vaddr & HPAGE_MASK);
-
- /* the hugetlb file might have been truncated */
- if (!pte || pte_none(*pte)) {
- remainder = 0;
- if (!i)
- i = -EFAULT;
- break;
- }
+ /*
+ * Some archs (sparc64, sh*) have multiple pte_ts to
+ * each hugepage. We have to make * sure we get the
+ * first, for the page indexing below to work.
+ */
+ pte = huge_pte_offset(mm, vaddr & HPAGE_MASK);
- page = &pte_page(*pte)[vpfn % (HPAGE_SIZE/PAGE_SIZE)];
+ if (!pte || pte_none(*pte)) {
+ int ret;
- WARN_ON(!PageCompound(page));
+ spin_unlock(&mm->page_table_lock);
+ ret = hugetlb_fault(mm, vma, vaddr, 0);
+ spin_lock(&mm->page_table_lock);
+ if (ret == VM_FAULT_MINOR)
+ continue;
+
+ remainder = 0;
+ if (!i)
+ i = -EFAULT;
+ break;
+ }
+ if (pages) {
+ page = &pte_page(*pte)[vpfn % (HPAGE_SIZE/PAGE_SIZE)];
get_page(page);
pages[i] = page;
}
diff --git a/mm/madvise.c b/mm/madvise.c
index 20e075d1c64c..17aaf3e16449 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -126,7 +126,7 @@ static long madvise_dontneed(struct vm_area_struct * vma,
unsigned long start, unsigned long end)
{
*prev = vma;
- if ((vma->vm_flags & VM_LOCKED) || is_vm_hugetlb_page(vma))
+ if (vma->vm_flags & (VM_LOCKED|VM_HUGETLB|VM_RESERVED))
return -EINVAL;
if (unlikely(vma->vm_flags & VM_NONLINEAR)) {
diff --git a/mm/memory.c b/mm/memory.c
index 1db40e935e55..0f60baf6f69b 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -114,6 +114,7 @@ static void free_pte_range(struct mmu_gather *tlb, pmd_t *pmd)
{
struct page *page = pmd_page(*pmd);
pmd_clear(pmd);
+ pte_lock_deinit(page);
pte_free_tlb(tlb, page);
dec_page_state(nr_page_table_pages);
tlb->mm->nr_ptes--;
@@ -249,7 +250,7 @@ void free_pgd_range(struct mmu_gather **tlb,
free_pud_range(*tlb, pgd, addr, next, floor, ceiling);
} while (pgd++, addr = next, addr != end);
- if (!tlb_is_full_mm(*tlb))
+ if (!(*tlb)->fullmm)
flush_tlb_pgtables((*tlb)->mm, start, end);
}
@@ -260,6 +261,12 @@ void free_pgtables(struct mmu_gather **tlb, struct vm_area_struct *vma,
struct vm_area_struct *next = vma->vm_next;
unsigned long addr = vma->vm_start;
+ /*
+ * Hide vma from rmap and vmtruncate before freeing pgtables
+ */
+ anon_vma_unlink(vma);
+ unlink_file_vma(vma);
+
if (is_hugepage_only_range(vma->vm_mm, addr, HPAGE_SIZE)) {
hugetlb_free_pgd_range(tlb, addr, vma->vm_end,
floor, next? next->vm_start: ceiling);
@@ -272,6 +279,8 @@ void free_pgtables(struct mmu_gather **tlb, struct vm_area_struct *vma,
HPAGE_SIZE)) {
vma = next;
next = vma->vm_next;
+ anon_vma_unlink(vma);
+ unlink_file_vma(vma);
}
free_pgd_range(tlb, addr, vma->vm_end,
floor, next? next->vm_start: ceiling);
@@ -280,72 +289,78 @@ void free_pgtables(struct mmu_gather **tlb, struct vm_area_struct *vma,
}
}
-pte_t fastcall *pte_alloc_map(struct mm_struct *mm, pmd_t *pmd,
- unsigned long address)
+int __pte_alloc(struct mm_struct *mm, pmd_t *pmd, unsigned long address)
{
- if (!pmd_present(*pmd)) {
- struct page *new;
-
- spin_unlock(&mm->page_table_lock);
- new = pte_alloc_one(mm, address);
- spin_lock(&mm->page_table_lock);
- if (!new)
- return NULL;
- /*
- * Because we dropped the lock, we should re-check the
- * entry, as somebody else could have populated it..
- */
- if (pmd_present(*pmd)) {
- pte_free(new);
- goto out;
- }
+ struct page *new = pte_alloc_one(mm, address);
+ if (!new)
+ return -ENOMEM;
+
+ pte_lock_init(new);
+ spin_lock(&mm->page_table_lock);
+ if (pmd_present(*pmd)) { /* Another has populated it */
+ pte_lock_deinit(new);
+ pte_free(new);
+ } else {
mm->nr_ptes++;
inc_page_state(nr_page_table_pages);
pmd_populate(mm, pmd, new);
}
-out:
- return pte_offset_map(pmd, address);
+ spin_unlock(&mm->page_table_lock);
+ return 0;
}
-pte_t fastcall * pte_alloc_kernel(struct mm_struct *mm, pmd_t *pmd, unsigned long address)
+int __pte_alloc_kernel(pmd_t *pmd, unsigned long address)
{
- if (!pmd_present(*pmd)) {
- pte_t *new;
+ pte_t *new = pte_alloc_one_kernel(&init_mm, address);
+ if (!new)
+ return -ENOMEM;
- spin_unlock(&mm->page_table_lock);
- new = pte_alloc_one_kernel(mm, address);
- spin_lock(&mm->page_table_lock);
- if (!new)
- return NULL;
+ spin_lock(&init_mm.page_table_lock);
+ if (pmd_present(*pmd)) /* Another has populated it */
+ pte_free_kernel(new);
+ else
+ pmd_populate_kernel(&init_mm, pmd, new);
+ spin_unlock(&init_mm.page_table_lock);
+ return 0;
+}
- /*
- * Because we dropped the lock, we should re-check the
- * entry, as somebody else could have populated it..
- */
- if (pmd_present(*pmd)) {
- pte_free_kernel(new);
- goto out;
- }
- pmd_populate_kernel(mm, pmd, new);
- }
-out:
- return pte_offset_kernel(pmd, address);
+static inline void add_mm_rss(struct mm_struct *mm, int file_rss, int anon_rss)
+{
+ if (file_rss)
+ add_mm_counter(mm, file_rss, file_rss);
+ if (anon_rss)
+ add_mm_counter(mm, anon_rss, anon_rss);
+}
+
+/*
+ * This function is called to print an error when a pte in a
+ * !VM_RESERVED region is found pointing to an invalid pfn (which
+ * is an error.
+ *
+ * The calling function must still handle the error.
+ */
+void print_bad_pte(struct vm_area_struct *vma, pte_t pte, unsigned long vaddr)
+{
+ printk(KERN_ERR "Bad pte = %08llx, process = %s, "
+ "vm_flags = %lx, vaddr = %lx\n",
+ (long long)pte_val(pte),
+ (vma->vm_mm == current->mm ? current->comm : "???"),
+ vma->vm_flags, vaddr);
+ dump_stack();
}
/*
* copy one vm_area from one task to the other. Assumes the page tables
* already present in the new task to be cleared in the whole range
* covered by this vma.
- *
- * dst->page_table_lock is held on entry and exit,
- * but may be dropped within p[mg]d_alloc() and pte_alloc_map().
*/
static inline void
copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
- pte_t *dst_pte, pte_t *src_pte, unsigned long vm_flags,
- unsigned long addr)
+ pte_t *dst_pte, pte_t *src_pte, struct vm_area_struct *vma,
+ unsigned long addr, int *rss)
{
+ unsigned long vm_flags = vma->vm_flags;
pte_t pte = *src_pte;
struct page *page;
unsigned long pfn;
@@ -357,29 +372,32 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
/* make sure dst_mm is on swapoff's mmlist. */
if (unlikely(list_empty(&dst_mm->mmlist))) {
spin_lock(&mmlist_lock);
- list_add(&dst_mm->mmlist, &src_mm->mmlist);
+ if (list_empty(&dst_mm->mmlist))
+ list_add(&dst_mm->mmlist,
+ &src_mm->mmlist);
spin_unlock(&mmlist_lock);
}
}
- set_pte_at(dst_mm, addr, dst_pte, pte);
- return;
+ goto out_set_pte;
}
- pfn = pte_pfn(pte);
- /* the pte points outside of valid memory, the
- * mapping is assumed to be good, meaningful
- * and not mapped via rmap - duplicate the
- * mapping as is.
+ /* If the region is VM_RESERVED, the mapping is not
+ * mapped via rmap - duplicate the pte as is.
*/
- page = NULL;
- if (pfn_valid(pfn))
- page = pfn_to_page(pfn);
+ if (vm_flags & VM_RESERVED)
+ goto out_set_pte;
- if (!page || PageReserved(page)) {
- set_pte_at(dst_mm, addr, dst_pte, pte);
- return;
+ pfn = pte_pfn(pte);
+ /* If the pte points outside of valid memory but
+ * the region is not VM_RESERVED, we have a problem.
+ */
+ if (unlikely(!pfn_valid(pfn))) {
+ print_bad_pte(vma, pte, addr);
+ goto out_set_pte; /* try to do something sane */
}
+ page = pfn_to_page(pfn);
+
/*
* If it's a COW mapping, write protect it both
* in the parent and the child
@@ -397,11 +415,11 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
pte = pte_mkclean(pte);
pte = pte_mkold(pte);
get_page(page);
- inc_mm_counter(dst_mm, rss);
- if (PageAnon(page))
- inc_mm_counter(dst_mm, anon_rss);
- set_pte_at(dst_mm, addr, dst_pte, pte);
page_dup_rmap(page);
+ rss[!!PageAnon(page)]++;
+
+out_set_pte:
+ set_pte_at(dst_mm, addr, dst_pte, pte);
}
static int copy_pte_range(struct mm_struct *dst_mm, struct mm_struct *src_mm,
@@ -409,38 +427,44 @@ static int copy_pte_range(struct mm_struct *dst_mm, struct mm_struct *src_mm,
unsigned long addr, unsigned long end)
{
pte_t *src_pte, *dst_pte;
- unsigned long vm_flags = vma->vm_flags;
- int progress;
+ spinlock_t *src_ptl, *dst_ptl;
+ int progress = 0;
+ int rss[2];
again:
- dst_pte = pte_alloc_map(dst_mm, dst_pmd, addr);
+ rss[1] = rss[0] = 0;
+ dst_pte = pte_alloc_map_lock(dst_mm, dst_pmd, addr, &dst_ptl);
if (!dst_pte)
return -ENOMEM;
src_pte = pte_offset_map_nested(src_pmd, addr);
+ src_ptl = pte_lockptr(src_mm, src_pmd);
+ spin_lock(src_ptl);
- progress = 0;
- spin_lock(&src_mm->page_table_lock);
do {
/*
* We are holding two locks at this point - either of them
* could generate latencies in another task on another CPU.
*/
- if (progress >= 32 && (need_resched() ||
- need_lockbreak(&src_mm->page_table_lock) ||
- need_lockbreak(&dst_mm->page_table_lock)))
- break;
+ if (progress >= 32) {
+ progress = 0;
+ if (need_resched() ||
+ need_lockbreak(src_ptl) ||
+ need_lockbreak(dst_ptl))
+ break;
+ }
if (pte_none(*src_pte)) {
progress++;
continue;
}
- copy_one_pte(dst_mm, src_mm, dst_pte, src_pte, vm_flags, addr);
+ copy_one_pte(dst_mm, src_mm, dst_pte, src_pte, vma, addr, rss);
progress += 8;
} while (dst_pte++, src_pte++, addr += PAGE_SIZE, addr != end);
- spin_unlock(&src_mm->page_table_lock);
+ spin_unlock(src_ptl);
pte_unmap_nested(src_pte - 1);
- pte_unmap(dst_pte - 1);
- cond_resched_lock(&dst_mm->page_table_lock);
+ add_mm_rss(dst_mm, rss[0], rss[1]);
+ pte_unmap_unlock(dst_pte - 1, dst_ptl);
+ cond_resched();
if (addr != end)
goto again;
return 0;
@@ -525,24 +549,30 @@ int copy_page_range(struct mm_struct *dst_mm, struct mm_struct *src_mm,
return 0;
}
-static void zap_pte_range(struct mmu_gather *tlb, pmd_t *pmd,
+static void zap_pte_range(struct mmu_gather *tlb,
+ struct vm_area_struct *vma, pmd_t *pmd,
unsigned long addr, unsigned long end,
struct zap_details *details)
{
+ struct mm_struct *mm = tlb->mm;
pte_t *pte;
+ spinlock_t *ptl;
+ int file_rss = 0;
+ int anon_rss = 0;
- pte = pte_offset_map(pmd, addr);
+ pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
do {
pte_t ptent = *pte;
if (pte_none(ptent))
continue;
if (pte_present(ptent)) {
struct page *page = NULL;
- unsigned long pfn = pte_pfn(ptent);
- if (pfn_valid(pfn)) {
- page = pfn_to_page(pfn);
- if (PageReserved(page))
- page = NULL;
+ if (!(vma->vm_flags & VM_RESERVED)) {
+ unsigned long pfn = pte_pfn(ptent);
+ if (unlikely(!pfn_valid(pfn)))
+ print_bad_pte(vma, ptent, addr);
+ else
+ page = pfn_to_page(pfn);
}
if (unlikely(details) && page) {
/*
@@ -562,7 +592,7 @@ static void zap_pte_range(struct mmu_gather *tlb, pmd_t *pmd,
page->index > details->last_index))
continue;
}
- ptent = ptep_get_and_clear_full(tlb->mm, addr, pte,
+ ptent = ptep_get_and_clear_full(mm, addr, pte,
tlb->fullmm);
tlb_remove_tlb_entry(tlb, pte, addr);
if (unlikely(!page))
@@ -570,15 +600,17 @@ static void zap_pte_range(struct mmu_gather *tlb, pmd_t *pmd,
if (unlikely(details) && details->nonlinear_vma
&& linear_page_index(details->nonlinear_vma,
addr) != page->index)
- set_pte_at(tlb->mm, addr, pte,
+ set_pte_at(mm, addr, pte,
pgoff_to_pte(page->index));
- if (pte_dirty(ptent))
- set_page_dirty(page);
if (PageAnon(page))
- dec_mm_counter(tlb->mm, anon_rss);
- else if (pte_young(ptent))
- mark_page_accessed(page);
- tlb->freed++;
+ anon_rss--;
+ else {
+ if (pte_dirty(ptent))
+ set_page_dirty(page);
+ if (pte_young(ptent))
+ mark_page_accessed(page);
+ file_rss--;
+ }
page_remove_rmap(page);
tlb_remove_page(tlb, page);
continue;
@@ -591,12 +623,15 @@ static void zap_pte_range(struct mmu_gather *tlb, pmd_t *pmd,
continue;
if (!pte_file(ptent))
free_swap_and_cache(pte_to_swp_entry(ptent));
- pte_clear_full(tlb->mm, addr, pte, tlb->fullmm);
+ pte_clear_full(mm, addr, pte, tlb->fullmm);
} while (pte++, addr += PAGE_SIZE, addr != end);
- pte_unmap(pte - 1);
+
+ add_mm_rss(mm, file_rss, anon_rss);
+ pte_unmap_unlock(pte - 1, ptl);
}
-static inline void zap_pmd_range(struct mmu_gather *tlb, pud_t *pud,
+static inline void zap_pmd_range(struct mmu_gather *tlb,
+ struct vm_area_struct *vma, pud_t *pud,
unsigned long addr, unsigned long end,
struct zap_details *details)
{
@@ -608,11 +643,12 @@ static inline void zap_pmd_range(struct mmu_gather *tlb, pud_t *pud,
next = pmd_addr_end(addr, end);
if (pmd_none_or_clear_bad(pmd))
continue;
- zap_pte_range(tlb, pmd, addr, next, details);
+ zap_pte_range(tlb, vma, pmd, addr, next, details);
} while (pmd++, addr = next, addr != end);
}
-static inline void zap_pud_range(struct mmu_gather *tlb, pgd_t *pgd,
+static inline void zap_pud_range(struct mmu_gather *tlb,
+ struct vm_area_struct *vma, pgd_t *pgd,
unsigned long addr, unsigned long end,
struct zap_details *details)
{
@@ -624,7 +660,7 @@ static inline void zap_pud_range(struct mmu_gather *tlb, pgd_t *pgd,
next = pud_addr_end(addr, end);
if (pud_none_or_clear_bad(pud))
continue;
- zap_pmd_range(tlb, pud, addr, next, details);
+ zap_pmd_range(tlb, vma, pud, addr, next, details);
} while (pud++, addr = next, addr != end);
}
@@ -645,7 +681,7 @@ static void unmap_page_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
next = pgd_addr_end(addr, end);
if (pgd_none_or_clear_bad(pgd))
continue;
- zap_pud_range(tlb, pgd, addr, next, details);
+ zap_pud_range(tlb, vma, pgd, addr, next, details);
} while (pgd++, addr = next, addr != end);
tlb_end_vma(tlb, vma);
}
@@ -660,7 +696,6 @@ static void unmap_page_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
/**
* unmap_vmas - unmap a range of memory covered by a list of vma's
* @tlbp: address of the caller's struct mmu_gather
- * @mm: the controlling mm_struct
* @vma: the starting vma
* @start_addr: virtual address at which to start unmapping
* @end_addr: virtual address at which to end unmapping
@@ -669,10 +704,10 @@ static void unmap_page_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
*
* Returns the end address of the unmapping (restart addr if interrupted).
*
- * Unmap all pages in the vma list. Called under page_table_lock.
+ * Unmap all pages in the vma list.
*
- * We aim to not hold page_table_lock for too long (for scheduling latency
- * reasons). So zap pages in ZAP_BLOCK_SIZE bytecounts. This means we need to
+ * We aim to not hold locks for too long (for scheduling latency reasons).
+ * So zap pages in ZAP_BLOCK_SIZE bytecounts. This means we need to
* return the ending mmu_gather to the caller.
*
* Only addresses between `start' and `end' will be unmapped.
@@ -684,7 +719,7 @@ static void unmap_page_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
* ensure that any thus-far unmapped pages are flushed before unmap_vmas()
* drops the lock and schedules.
*/
-unsigned long unmap_vmas(struct mmu_gather **tlbp, struct mm_struct *mm,
+unsigned long unmap_vmas(struct mmu_gather **tlbp,
struct vm_area_struct *vma, unsigned long start_addr,
unsigned long end_addr, unsigned long *nr_accounted,
struct zap_details *details)
@@ -694,7 +729,7 @@ unsigned long unmap_vmas(struct mmu_gather **tlbp, struct mm_struct *mm,
int tlb_start_valid = 0;
unsigned long start = start_addr;
spinlock_t *i_mmap_lock = details? details->i_mmap_lock: NULL;
- int fullmm = tlb_is_full_mm(*tlbp);
+ int fullmm = (*tlbp)->fullmm;
for ( ; vma && vma->vm_start < end_addr; vma = vma->vm_next) {
unsigned long end;
@@ -734,19 +769,15 @@ unsigned long unmap_vmas(struct mmu_gather **tlbp, struct mm_struct *mm,
tlb_finish_mmu(*tlbp, tlb_start, start);
if (need_resched() ||
- need_lockbreak(&mm->page_table_lock) ||
(i_mmap_lock && need_lockbreak(i_mmap_lock))) {
if (i_mmap_lock) {
- /* must reset count of rss freed */
- *tlbp = tlb_gather_mmu(mm, fullmm);
+ *tlbp = NULL;
goto out;
}
- spin_unlock(&mm->page_table_lock);
cond_resched();
- spin_lock(&mm->page_table_lock);
}
- *tlbp = tlb_gather_mmu(mm, fullmm);
+ *tlbp = tlb_gather_mmu(vma->vm_mm, fullmm);
tlb_start_valid = 0;
zap_bytes = ZAP_BLOCK_SIZE;
}
@@ -770,123 +801,93 @@ unsigned long zap_page_range(struct vm_area_struct *vma, unsigned long address,
unsigned long end = address + size;
unsigned long nr_accounted = 0;
- if (is_vm_hugetlb_page(vma)) {
- zap_hugepage_range(vma, address, size);
- return end;
- }
-
lru_add_drain();
- spin_lock(&mm->page_table_lock);
tlb = tlb_gather_mmu(mm, 0);
- end = unmap_vmas(&tlb, mm, vma, address, end, &nr_accounted, details);
- tlb_finish_mmu(tlb, address, end);
- spin_unlock(&mm->page_table_lock);
+ update_hiwater_rss(mm);
+ end = unmap_vmas(&tlb, vma, address, end, &nr_accounted, details);
+ if (tlb)
+ tlb_finish_mmu(tlb, address, end);
return end;
}
/*
* Do a quick page-table lookup for a single page.
- * mm->page_table_lock must be held.
*/
-static struct page *__follow_page(struct mm_struct *mm, unsigned long address,
- int read, int write, int accessed)
+struct page *follow_page(struct mm_struct *mm, unsigned long address,
+ unsigned int flags)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t *ptep, pte;
+ spinlock_t *ptl;
unsigned long pfn;
struct page *page;
- page = follow_huge_addr(mm, address, write);
- if (! IS_ERR(page))
- return page;
+ page = follow_huge_addr(mm, address, flags & FOLL_WRITE);
+ if (!IS_ERR(page)) {
+ BUG_ON(flags & FOLL_GET);
+ goto out;
+ }
+ page = NULL;
pgd = pgd_offset(mm, address);
if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
- goto out;
+ goto no_page_table;
pud = pud_offset(pgd, address);
if (pud_none(*pud) || unlikely(pud_bad(*pud)))
- goto out;
+ goto no_page_table;
pmd = pmd_offset(pud, address);
if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
+ goto no_page_table;
+
+ if (pmd_huge(*pmd)) {
+ BUG_ON(flags & FOLL_GET);
+ page = follow_huge_pmd(mm, address, pmd, flags & FOLL_WRITE);
goto out;
- if (pmd_huge(*pmd))
- return follow_huge_pmd(mm, address, pmd, write);
+ }
- ptep = pte_offset_map(pmd, address);
+ ptep = pte_offset_map_lock(mm, pmd, address, &ptl);
if (!ptep)
goto out;
pte = *ptep;
- pte_unmap(ptep);
- if (pte_present(pte)) {
- if (write && !pte_write(pte))
- goto out;
- if (read && !pte_read(pte))
- goto out;
- pfn = pte_pfn(pte);
- if (pfn_valid(pfn)) {
- page = pfn_to_page(pfn);
- if (accessed) {
- if (write && !pte_dirty(pte) &&!PageDirty(page))
- set_page_dirty(page);
- mark_page_accessed(page);
- }
- return page;
- }
+ if (!pte_present(pte))
+ goto unlock;
+ if ((flags & FOLL_WRITE) && !pte_write(pte))
+ goto unlock;
+ pfn = pte_pfn(pte);
+ if (!pfn_valid(pfn))
+ goto unlock;
+
+ page = pfn_to_page(pfn);
+ if (flags & FOLL_GET)
+ get_page(page);
+ if (flags & FOLL_TOUCH) {
+ if ((flags & FOLL_WRITE) &&
+ !pte_dirty(pte) && !PageDirty(page))
+ set_page_dirty(page);
+ mark_page_accessed(page);
}
-
+unlock:
+ pte_unmap_unlock(ptep, ptl);
out:
- return NULL;
-}
-
-inline struct page *
-follow_page(struct mm_struct *mm, unsigned long address, int write)
-{
- return __follow_page(mm, address, 0, write, 1);
-}
-
-/*
- * check_user_page_readable() can be called frm niterrupt context by oprofile,
- * so we need to avoid taking any non-irq-safe locks
- */
-int check_user_page_readable(struct mm_struct *mm, unsigned long address)
-{
- return __follow_page(mm, address, 1, 0, 0) != NULL;
-}
-EXPORT_SYMBOL(check_user_page_readable);
-
-static inline int
-untouched_anonymous_page(struct mm_struct* mm, struct vm_area_struct *vma,
- unsigned long address)
-{
- pgd_t *pgd;
- pud_t *pud;
- pmd_t *pmd;
-
- /* Check if the vma is for an anonymous mapping. */
- if (vma->vm_ops && vma->vm_ops->nopage)
- return 0;
-
- /* Check if page directory entry exists. */
- pgd = pgd_offset(mm, address);
- if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
- return 1;
-
- pud = pud_offset(pgd, address);
- if (pud_none(*pud) || unlikely(pud_bad(*pud)))
- return 1;
-
- /* Check if page middle directory entry exists. */
- pmd = pmd_offset(pud, address);
- if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
- return 1;
+ return page;
- /* There is a pte slot for 'address' in 'mm'. */
- return 0;
+no_page_table:
+ /*
+ * When core dumping an enormous anonymous area that nobody
+ * has touched so far, we don't want to allocate page tables.
+ */
+ if (flags & FOLL_ANON) {
+ page = ZERO_PAGE(address);
+ if (flags & FOLL_GET)
+ get_page(page);
+ BUG_ON(flags & FOLL_WRITE);
+ }
+ return page;
}
int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
@@ -894,18 +895,19 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
struct page **pages, struct vm_area_struct **vmas)
{
int i;
- unsigned int flags;
+ unsigned int vm_flags;
/*
* Require read or write permissions.
* If 'force' is set, we only require the "MAY" flags.
*/
- flags = write ? (VM_WRITE | VM_MAYWRITE) : (VM_READ | VM_MAYREAD);
- flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
+ vm_flags = write ? (VM_WRITE | VM_MAYWRITE) : (VM_READ | VM_MAYREAD);
+ vm_flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
i = 0;
do {
- struct vm_area_struct * vma;
+ struct vm_area_struct *vma;
+ unsigned int foll_flags;
vma = find_extend_vma(mm, start);
if (!vma && in_gate_area(tsk, start)) {
@@ -945,8 +947,8 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
continue;
}
- if (!vma || (vma->vm_flags & VM_IO)
- || !(flags & vma->vm_flags))
+ if (!vma || (vma->vm_flags & (VM_IO | VM_RESERVED))
+ || !(vm_flags & vma->vm_flags))
return i ? : -EFAULT;
if (is_vm_hugetlb_page(vma)) {
@@ -954,29 +956,25 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
&start, &len, i);
continue;
}
- spin_lock(&mm->page_table_lock);
+
+ foll_flags = FOLL_TOUCH;
+ if (pages)
+ foll_flags |= FOLL_GET;
+ if (!write && !(vma->vm_flags & VM_LOCKED) &&
+ (!vma->vm_ops || !vma->vm_ops->nopage))
+ foll_flags |= FOLL_ANON;
+
do {
- int write_access = write;
struct page *page;
- cond_resched_lock(&mm->page_table_lock);
- while (!(page = follow_page(mm, start, write_access))) {
- int ret;
-
- /*
- * Shortcut for anonymous pages. We don't want
- * to force the creation of pages tables for
- * insanely big anonymously mapped areas that
- * nobody touched so far. This is important
- * for doing a core dump for these mappings.
- */
- if (!write && untouched_anonymous_page(mm,vma,start)) {
- page = ZERO_PAGE(start);
- break;
- }
- spin_unlock(&mm->page_table_lock);
- ret = __handle_mm_fault(mm, vma, start, write_access);
+ if (write)
+ foll_flags |= FOLL_WRITE;
+ cond_resched();
+ while (!(page = follow_page(mm, start, foll_flags))) {
+ int ret;
+ ret = __handle_mm_fault(mm, vma, start,
+ foll_flags & FOLL_WRITE);
/*
* The VM_FAULT_WRITE bit tells us that do_wp_page has
* broken COW when necessary, even if maybe_mkwrite
@@ -984,7 +982,7 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
* subsequent page lookups as if they were reads.
*/
if (ret & VM_FAULT_WRITE)
- write_access = 0;
+ foll_flags &= ~FOLL_WRITE;
switch (ret & ~VM_FAULT_WRITE) {
case VM_FAULT_MINOR:
@@ -1000,13 +998,10 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
default:
BUG();
}
- spin_lock(&mm->page_table_lock);
}
if (pages) {
pages[i] = page;
flush_dcache_page(page);
- if (!PageReserved(page))
- page_cache_get(page);
}
if (vmas)
vmas[i] = vma;
@@ -1014,7 +1009,6 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
start += PAGE_SIZE;
len--;
} while (len && start < vma->vm_end);
- spin_unlock(&mm->page_table_lock);
} while (len);
return i;
}
@@ -1024,16 +1018,21 @@ static int zeromap_pte_range(struct mm_struct *mm, pmd_t *pmd,
unsigned long addr, unsigned long end, pgprot_t prot)
{
pte_t *pte;
+ spinlock_t *ptl;
- pte = pte_alloc_map(mm, pmd, addr);
+ pte = pte_alloc_map_lock(mm, pmd, addr, &ptl);
if (!pte)
return -ENOMEM;
do {
- pte_t zero_pte = pte_wrprotect(mk_pte(ZERO_PAGE(addr), prot));
+ struct page *page = ZERO_PAGE(addr);
+ pte_t zero_pte = pte_wrprotect(mk_pte(page, prot));
+ page_cache_get(page);
+ page_add_file_rmap(page);
+ inc_mm_counter(mm, file_rss);
BUG_ON(!pte_none(*pte));
set_pte_at(mm, addr, pte, zero_pte);
} while (pte++, addr += PAGE_SIZE, addr != end);
- pte_unmap(pte - 1);
+ pte_unmap_unlock(pte - 1, ptl);
return 0;
}
@@ -1083,14 +1082,12 @@ int zeromap_page_range(struct vm_area_struct *vma,
BUG_ON(addr >= end);
pgd = pgd_offset(mm, addr);
flush_cache_range(vma, addr, end);
- spin_lock(&mm->page_table_lock);
do {
next = pgd_addr_end(addr, end);
err = zeromap_pud_range(mm, pgd, addr, next, prot);
if (err)
break;
} while (pgd++, addr = next, addr != end);
- spin_unlock(&mm->page_table_lock);
return err;
}
@@ -1104,17 +1101,17 @@ static int remap_pte_range(struct mm_struct *mm, pmd_t *pmd,
unsigned long pfn, pgprot_t prot)
{
pte_t *pte;
+ spinlock_t *ptl;
- pte = pte_alloc_map(mm, pmd, addr);
+ pte = pte_alloc_map_lock(mm, pmd, addr, &ptl);
if (!pte)
return -ENOMEM;
do {
BUG_ON(!pte_none(*pte));
- if (!pfn_valid(pfn) || PageReserved(pfn_to_page(pfn)))
- set_pte_at(mm, addr, pte, pfn_pte(pfn, prot));
+ set_pte_at(mm, addr, pte, pfn_pte(pfn, prot));
pfn++;
} while (pte++, addr += PAGE_SIZE, addr != end);
- pte_unmap(pte - 1);
+ pte_unmap_unlock(pte - 1, ptl);
return 0;
}
@@ -1173,8 +1170,8 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
* rest of the world about it:
* VM_IO tells people not to look at these pages
* (accesses can have side effects).
- * VM_RESERVED tells swapout not to try to touch
- * this region.
+ * VM_RESERVED tells the core MM not to "manage" these pages
+ * (e.g. refcount, mapcount, try to swap them out).
*/
vma->vm_flags |= VM_IO | VM_RESERVED;
@@ -1182,7 +1179,6 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
pfn -= addr >> PAGE_SHIFT;
pgd = pgd_offset(mm, addr);
flush_cache_range(vma, addr, end);
- spin_lock(&mm->page_table_lock);
do {
next = pgd_addr_end(addr, end);
err = remap_pud_range(mm, pgd, addr, next,
@@ -1190,12 +1186,36 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
if (err)
break;
} while (pgd++, addr = next, addr != end);
- spin_unlock(&mm->page_table_lock);
return err;
}
EXPORT_SYMBOL(remap_pfn_range);
/*
+ * handle_pte_fault chooses page fault handler according to an entry
+ * which was read non-atomically. Before making any commitment, on
+ * those architectures or configurations (e.g. i386 with PAE) which
+ * might give a mix of unmatched parts, do_swap_page and do_file_page
+ * must check under lock before unmapping the pte and proceeding
+ * (but do_wp_page is only called after already making such a check;
+ * and do_anonymous_page and do_no_page can safely check later on).
+ */
+static inline int pte_unmap_same(struct mm_struct *mm, pmd_t *pmd,
+ pte_t *page_table, pte_t orig_pte)
+{
+ int same = 1;
+#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
+ if (sizeof(pte_t) > sizeof(unsigned long)) {
+ spinlock_t *ptl = pte_lockptr(mm, pmd);
+ spin_lock(ptl);
+ same = pte_same(*page_table, orig_pte);
+ spin_unlock(ptl);
+ }
+#endif
+ pte_unmap(page_table);
+ return same;
+}
+
+/*
* Do pte_mkwrite, but only if the vma says VM_WRITE. We do this when
* servicing faults for write access. In the normal case, do always want
* pte_mkwrite. But get_user_pages can cause write faults for mappings
@@ -1209,28 +1229,10 @@ static inline pte_t maybe_mkwrite(pte_t pte, struct vm_area_struct *vma)
}
/*
- * We hold the mm semaphore for reading and vma->vm_mm->page_table_lock
- */
-static inline void break_cow(struct vm_area_struct * vma, struct page * new_page, unsigned long address,
- pte_t *page_table)
-{
- pte_t entry;
-
- entry = maybe_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot)),
- vma);
- ptep_establish(vma, address, page_table, entry);
- update_mmu_cache(vma, address, entry);
- lazy_mmu_prot_update(entry);
-}
-
-/*
* This routine handles present pages, when users try to write
* to a shared page. It is done by copying the page to a new address
* and decrementing the shared-page counter for the old page.
*
- * Goto-purists beware: the only reason for goto's here is that it results
- * in better assembly code.. The "default" path will see no jumps at all.
- *
* Note that this routine assumes that the protection checks have been
* done by the caller (the low-level page fault routine in most cases).
* Thus we can safely just mark it writable once we've done any necessary
@@ -1240,28 +1242,28 @@ static inline void break_cow(struct vm_area_struct * vma, struct page * new_page
* change only once the write actually happens. This avoids a few races,
* and potentially makes it more efficient.
*
- * We hold the mm semaphore and the page_table_lock on entry and exit
- * with the page_table_lock released.
+ * We enter with non-exclusive mmap_sem (to exclude vma changes,
+ * but allow concurrent faults), with pte both mapped and locked.
+ * We return with mmap_sem still held, but pte unmapped and unlocked.
*/
-static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma,
- unsigned long address, pte_t *page_table, pmd_t *pmd, pte_t pte)
+static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
+ unsigned long address, pte_t *page_table, pmd_t *pmd,
+ spinlock_t *ptl, pte_t orig_pte)
{
struct page *old_page, *new_page;
- unsigned long pfn = pte_pfn(pte);
+ unsigned long pfn = pte_pfn(orig_pte);
pte_t entry;
- int ret;
+ int ret = VM_FAULT_MINOR;
+
+ BUG_ON(vma->vm_flags & VM_RESERVED);
if (unlikely(!pfn_valid(pfn))) {
/*
- * This should really halt the system so it can be debugged or
- * at least the kernel stops what it's doing before it corrupts
- * data, but for the moment just pretend this is OOM.
+ * Page table corrupted: show pte and kill process.
*/
- pte_unmap(page_table);
- printk(KERN_ERR "do_wp_page: bogus page at address %08lx\n",
- address);
- spin_unlock(&mm->page_table_lock);
- return VM_FAULT_OOM;
+ print_bad_pte(vma, orig_pte, address);
+ ret = VM_FAULT_OOM;
+ goto unlock;
}
old_page = pfn_to_page(pfn);
@@ -1270,52 +1272,51 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma,
unlock_page(old_page);
if (reuse) {
flush_cache_page(vma, address, pfn);
- entry = maybe_mkwrite(pte_mkyoung(pte_mkdirty(pte)),
- vma);
+ entry = pte_mkyoung(orig_pte);
+ entry = maybe_mkwrite(pte_mkdirty(entry), vma);
ptep_set_access_flags(vma, address, page_table, entry, 1);
update_mmu_cache(vma, address, entry);
lazy_mmu_prot_update(entry);
- pte_unmap(page_table);
- spin_unlock(&mm->page_table_lock);
- return VM_FAULT_MINOR|VM_FAULT_WRITE;
+ ret |= VM_FAULT_WRITE;
+ goto unlock;
}
}
- pte_unmap(page_table);
/*
* Ok, we need to copy. Oh, well..
*/
- if (!PageReserved(old_page))
- page_cache_get(old_page);
- spin_unlock(&mm->page_table_lock);
+ page_cache_get(old_page);
+ pte_unmap_unlock(page_table, ptl);
if (unlikely(anon_vma_prepare(vma)))
- goto no_new_page;
+ goto oom;
if (old_page == ZERO_PAGE(address)) {
new_page = alloc_zeroed_user_highpage(vma, address);
if (!new_page)
- goto no_new_page;
+ goto oom;
} else {
new_page = alloc_page_vma(GFP_HIGHUSER, vma, address);
if (!new_page)
- goto no_new_page;
+ goto oom;
copy_user_highpage(new_page, old_page, address);
}
+
/*
* Re-check the pte - we dropped the lock
*/
- ret = VM_FAULT_MINOR;
- spin_lock(&mm->page_table_lock);
- page_table = pte_offset_map(pmd, address);
- if (likely(pte_same(*page_table, pte))) {
- if (PageAnon(old_page))
- dec_mm_counter(mm, anon_rss);
- if (PageReserved(old_page))
- inc_mm_counter(mm, rss);
- else
- page_remove_rmap(old_page);
+ page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
+ if (likely(pte_same(*page_table, orig_pte))) {
+ page_remove_rmap(old_page);
+ if (!PageAnon(old_page)) {
+ inc_mm_counter(mm, anon_rss);
+ dec_mm_counter(mm, file_rss);
+ }
flush_cache_page(vma, address, pfn);
- break_cow(vma, new_page, address, page_table);
+ entry = mk_pte(new_page, vma->vm_page_prot);
+ entry = maybe_mkwrite(pte_mkdirty(entry), vma);
+ ptep_establish(vma, address, page_table, entry);
+ update_mmu_cache(vma, address, entry);
+ lazy_mmu_prot_update(entry);
lru_cache_add_active(new_page);
page_add_anon_rmap(new_page, vma, address);
@@ -1323,13 +1324,12 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma,
new_page = old_page;
ret |= VM_FAULT_WRITE;
}
- pte_unmap(page_table);
page_cache_release(new_page);
page_cache_release(old_page);
- spin_unlock(&mm->page_table_lock);
+unlock:
+ pte_unmap_unlock(page_table, ptl);
return ret;
-
-no_new_page:
+oom:
page_cache_release(old_page);
return VM_FAULT_OOM;
}
@@ -1399,13 +1399,6 @@ again:
restart_addr = zap_page_range(vma, start_addr,
end_addr - start_addr, details);
-
- /*
- * We cannot rely on the break test in unmap_vmas:
- * on the one hand, we don't want to restart our loop
- * just because that broke out for the page_table_lock;
- * on the other hand, it does no test when vma is small.
- */
need_break = need_resched() ||
need_lockbreak(details->i_mmap_lock);
@@ -1654,38 +1647,37 @@ void swapin_readahead(swp_entry_t entry, unsigned long addr,struct vm_area_struc
}
/*
- * We hold the mm semaphore and the page_table_lock on entry and
- * should release the pagetable lock on exit..
+ * We enter with non-exclusive mmap_sem (to exclude vma changes,
+ * but allow concurrent faults), and pte mapped but not yet locked.
+ * We return with mmap_sem still held, but pte unmapped and unlocked.
*/
-static int do_swap_page(struct mm_struct * mm,
- struct vm_area_struct * vma, unsigned long address,
- pte_t *page_table, pmd_t *pmd, pte_t orig_pte, int write_access)
+static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
+ unsigned long address, pte_t *page_table, pmd_t *pmd,
+ int write_access, pte_t orig_pte)
{
+ spinlock_t *ptl;
struct page *page;
- swp_entry_t entry = pte_to_swp_entry(orig_pte);
+ swp_entry_t entry;
pte_t pte;
int ret = VM_FAULT_MINOR;
- pte_unmap(page_table);
- spin_unlock(&mm->page_table_lock);
+ if (!pte_unmap_same(mm, pmd, page_table, orig_pte))
+ goto out;
+
+ entry = pte_to_swp_entry(orig_pte);
page = lookup_swap_cache(entry);
if (!page) {
swapin_readahead(entry, address, vma);
page = read_swap_cache_async(entry, vma, address);
if (!page) {
/*
- * Back out if somebody else faulted in this pte while
- * we released the page table lock.
+ * Back out if somebody else faulted in this pte
+ * while we released the pte lock.
*/
- spin_lock(&mm->page_table_lock);
- page_table = pte_offset_map(pmd, address);
+ page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
if (likely(pte_same(*page_table, orig_pte)))
ret = VM_FAULT_OOM;
- else
- ret = VM_FAULT_MINOR;
- pte_unmap(page_table);
- spin_unlock(&mm->page_table_lock);
- goto out;
+ goto unlock;
}
/* Had to read the page from swap area: Major fault */
@@ -1698,15 +1690,11 @@ static int do_swap_page(struct mm_struct * mm,
lock_page(page);
/*
- * Back out if somebody else faulted in this pte while we
- * released the page table lock.
+ * Back out if somebody else already faulted in this pte.
*/
- spin_lock(&mm->page_table_lock);
- page_table = pte_offset_map(pmd, address);
- if (unlikely(!pte_same(*page_table, orig_pte))) {
- ret = VM_FAULT_MINOR;
+ page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
+ if (unlikely(!pte_same(*page_table, orig_pte)))
goto out_nomap;
- }
if (unlikely(!PageUptodate(page))) {
ret = VM_FAULT_SIGBUS;
@@ -1715,7 +1703,7 @@ static int do_swap_page(struct mm_struct * mm,
/* The page isn't present yet, go ahead with the fault. */
- inc_mm_counter(mm, rss);
+ inc_mm_counter(mm, anon_rss);
pte = mk_pte(page, vma->vm_page_prot);
if (write_access && can_share_swap_page(page)) {
pte = maybe_mkwrite(pte_mkdirty(pte), vma);
@@ -1733,7 +1721,7 @@ static int do_swap_page(struct mm_struct * mm,
if (write_access) {
if (do_wp_page(mm, vma, address,
- page_table, pmd, pte) == VM_FAULT_OOM)
+ page_table, pmd, ptl, pte) == VM_FAULT_OOM)
ret = VM_FAULT_OOM;
goto out;
}
@@ -1741,74 +1729,76 @@ static int do_swap_page(struct mm_struct * mm,
/* No need to invalidate - it was non-present before */
update_mmu_cache(vma, address, pte);
lazy_mmu_prot_update(pte);
- pte_unmap(page_table);
- spin_unlock(&mm->page_table_lock);
+unlock:
+ pte_unmap_unlock(page_table, ptl);
out:
return ret;
out_nomap:
- pte_unmap(page_table);
- spin_unlock(&mm->page_table_lock);
+ pte_unmap_unlock(page_table, ptl);
unlock_page(page);
page_cache_release(page);
- goto out;
+ return ret;
}
/*
- * We are called with the MM semaphore and page_table_lock
- * spinlock held to protect against concurrent faults in
- * multithreaded programs.
+ * We enter with non-exclusive mmap_sem (to exclude vma changes,
+ * but allow concurrent faults), and pte mapped but not yet locked.
+ * We return with mmap_sem still held, but pte unmapped and unlocked.
*/
-static int
-do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
- pte_t *page_table, pmd_t *pmd, int write_access,
- unsigned long addr)
+static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
+ unsigned long address, pte_t *page_table, pmd_t *pmd,
+ int write_access)
{
+ struct page *page;
+ spinlock_t *ptl;
pte_t entry;
- struct page * page = ZERO_PAGE(addr);
-
- /* Read-only mapping of ZERO_PAGE. */
- entry = pte_wrprotect(mk_pte(ZERO_PAGE(addr), vma->vm_page_prot));
- /* ..except if it's a write access */
if (write_access) {
/* Allocate our own private page. */
pte_unmap(page_table);
- spin_unlock(&mm->page_table_lock);
if (unlikely(anon_vma_prepare(vma)))
- goto no_mem;
- page = alloc_zeroed_user_highpage(vma, addr);
+ goto oom;
+ page = alloc_zeroed_user_highpage(vma, address);
if (!page)
- goto no_mem;
+ goto oom;
- spin_lock(&mm->page_table_lock);
- page_table = pte_offset_map(pmd, addr);
+ entry = mk_pte(page, vma->vm_page_prot);
+ entry = maybe_mkwrite(pte_mkdirty(entry), vma);
- if (!pte_none(*page_table)) {
- pte_unmap(page_table);
- page_cache_release(page);
- spin_unlock(&mm->page_table_lock);
- goto out;
- }
- inc_mm_counter(mm, rss);
- entry = maybe_mkwrite(pte_mkdirty(mk_pte(page,
- vma->vm_page_prot)),
- vma);
+ page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
+ if (!pte_none(*page_table))
+ goto release;
+ inc_mm_counter(mm, anon_rss);
lru_cache_add_active(page);
SetPageReferenced(page);
- page_add_anon_rmap(page, vma, addr);
+ page_add_anon_rmap(page, vma, address);
+ } else {
+ /* Map the ZERO_PAGE - vm_page_prot is readonly */
+ page = ZERO_PAGE(address);
+ page_cache_get(page);
+ entry = mk_pte(page, vma->vm_page_prot);
+
+ ptl = pte_lockptr(mm, pmd);
+ spin_lock(ptl);
+ if (!pte_none(*page_table))
+ goto release;
+ inc_mm_counter(mm, file_rss);
+ page_add_file_rmap(page);
}
- set_pte_at(mm, addr, page_table, entry);
- pte_unmap(page_table);
+ set_pte_at(mm, address, page_table, entry);
/* No need to invalidate - it was non-present before */
- update_mmu_cache(vma, addr, entry);
+ update_mmu_cache(vma, address, entry);
lazy_mmu_prot_update(entry);
- spin_unlock(&mm->page_table_lock);
-out:
+unlock:
+ pte_unmap_unlock(page_table, ptl);
return VM_FAULT_MINOR;
-no_mem:
+release:
+ page_cache_release(page);
+ goto unlock;
+oom:
return VM_FAULT_OOM;
}
@@ -1821,25 +1811,23 @@ no_mem:
* As this is called only for pages that do not currently exist, we
* do not need to flush old virtual caches or the TLB.
*
- * This is called with the MM semaphore held and the page table
- * spinlock held. Exit with the spinlock released.
+ * We enter with non-exclusive mmap_sem (to exclude vma changes,
+ * but allow concurrent faults), and pte mapped but not yet locked.
+ * We return with mmap_sem still held, but pte unmapped and unlocked.
*/
-static int
-do_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
- unsigned long address, int write_access, pte_t *page_table, pmd_t *pmd)
+static int do_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
+ unsigned long address, pte_t *page_table, pmd_t *pmd,
+ int write_access)
{
- struct page * new_page;
+ spinlock_t *ptl;
+ struct page *new_page;
struct address_space *mapping = NULL;
pte_t entry;
unsigned int sequence = 0;
int ret = VM_FAULT_MINOR;
int anon = 0;
- if (!vma->vm_ops || !vma->vm_ops->nopage)
- return do_anonymous_page(mm, vma, page_table,
- pmd, write_access, address);
pte_unmap(page_table);
- spin_unlock(&mm->page_table_lock);
if (vma->vm_file) {
mapping = vma->vm_file->f_mapping;
@@ -1847,7 +1835,6 @@ do_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
smp_rmb(); /* serializes i_size against truncate_count */
}
retry:
- cond_resched();
new_page = vma->vm_ops->nopage(vma, address & PAGE_MASK, &ret);
/*
* No smp_rmb is needed here as long as there's a full
@@ -1880,19 +1867,20 @@ retry:
anon = 1;
}
- spin_lock(&mm->page_table_lock);
+ page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
/*
* For a file-backed vma, someone could have truncated or otherwise
* invalidated this page. If unmap_mapping_range got called,
* retry getting the page.
*/
if (mapping && unlikely(sequence != mapping->truncate_count)) {
- sequence = mapping->truncate_count;
- spin_unlock(&mm->page_table_lock);
+ pte_unmap_unlock(page_table, ptl);
page_cache_release(new_page);
+ cond_resched();
+ sequence = mapping->truncate_count;
+ smp_rmb();
goto retry;
}
- page_table = pte_offset_map(pmd, address);
/*
* This silly early PAGE_DIRTY setting removes a race
@@ -1906,68 +1894,67 @@ retry:
*/
/* Only go through if we didn't race with anybody else... */
if (pte_none(*page_table)) {
- if (!PageReserved(new_page))
- inc_mm_counter(mm, rss);
-
flush_icache_page(vma, new_page);
entry = mk_pte(new_page, vma->vm_page_prot);
if (write_access)
entry = maybe_mkwrite(pte_mkdirty(entry), vma);
set_pte_at(mm, address, page_table, entry);
if (anon) {
+ inc_mm_counter(mm, anon_rss);
lru_cache_add_active(new_page);
page_add_anon_rmap(new_page, vma, address);
- } else
+ } else if (!(vma->vm_flags & VM_RESERVED)) {
+ inc_mm_counter(mm, file_rss);
page_add_file_rmap(new_page);
- pte_unmap(page_table);
+ }
} else {
/* One of our sibling threads was faster, back out. */
- pte_unmap(page_table);
page_cache_release(new_page);
- spin_unlock(&mm->page_table_lock);
- goto out;
+ goto unlock;
}
/* no need to invalidate: a not-present page shouldn't be cached */
update_mmu_cache(vma, address, entry);
lazy_mmu_prot_update(entry);
- spin_unlock(&mm->page_table_lock);
-out:
+unlock:
+ pte_unmap_unlock(page_table, ptl);
return ret;
oom:
page_cache_release(new_page);
- ret = VM_FAULT_OOM;
- goto out;
+ return VM_FAULT_OOM;
}
/*
* Fault of a previously existing named mapping. Repopulate the pte
* from the encoded file_pte if possible. This enables swappable
* nonlinear vmas.
+ *
+ * We enter with non-exclusive mmap_sem (to exclude vma changes,
+ * but allow concurrent faults), and pte mapped but not yet locked.
+ * We return with mmap_sem still held, but pte unmapped and unlocked.
*/
-static int do_file_page(struct mm_struct * mm, struct vm_area_struct * vma,
- unsigned long address, int write_access, pte_t *pte, pmd_t *pmd)
+static int do_file_page(struct mm_struct *mm, struct vm_area_struct *vma,
+ unsigned long address, pte_t *page_table, pmd_t *pmd,
+ int write_access, pte_t orig_pte)
{
- unsigned long pgoff;
+ pgoff_t pgoff;
int err;
- BUG_ON(!vma->vm_ops || !vma->vm_ops->nopage);
- /*
- * Fall back to the linear mapping if the fs does not support
- * ->populate:
- */
- if (!vma->vm_ops->populate ||
- (write_access && !(vma->vm_flags & VM_SHARED))) {
- pte_clear(mm, address, pte);
- return do_no_page(mm, vma, address, write_access, pte, pmd);
- }
-
- pgoff = pte_to_pgoff(*pte);
+ if (!pte_unmap_same(mm, pmd, page_table, orig_pte))
+ return VM_FAULT_MINOR;
- pte_unmap(pte);
- spin_unlock(&mm->page_table_lock);
+ if (unlikely(!(vma->vm_flags & VM_NONLINEAR))) {
+ /*
+ * Page table corrupted: show pte and kill process.
+ */
+ print_bad_pte(vma, orig_pte, address);
+ return VM_FAULT_OOM;
+ }
+ /* We can then assume vm->vm_ops && vma->vm_ops->populate */
- err = vma->vm_ops->populate(vma, address & PAGE_MASK, PAGE_SIZE, vma->vm_page_prot, pgoff, 0);
+ pgoff = pte_to_pgoff(orig_pte);
+ err = vma->vm_ops->populate(vma, address & PAGE_MASK, PAGE_SIZE,
+ vma->vm_page_prot, pgoff, 0);
if (err == -ENOMEM)
return VM_FAULT_OOM;
if (err)
@@ -1984,56 +1971,68 @@ static int do_file_page(struct mm_struct * mm, struct vm_area_struct * vma,
* with external mmu caches can use to update those (ie the Sparc or
* PowerPC hashed page tables that act as extended TLBs).
*
- * Note the "page_table_lock". It is to protect against kswapd removing
- * pages from under us. Note that kswapd only ever _removes_ pages, never
- * adds them. As such, once we have noticed that the page is not present,
- * we can drop the lock early.
- *
- * The adding of pages is protected by the MM semaphore (which we hold),
- * so we don't need to worry about a page being suddenly been added into
- * our VM.
- *
- * We enter with the pagetable spinlock held, we are supposed to
- * release it when done.
+ * We enter with non-exclusive mmap_sem (to exclude vma changes,
+ * but allow concurrent faults), and pte mapped but not yet locked.
+ * We return with mmap_sem still held, but pte unmapped and unlocked.
*/
static inline int handle_pte_fault(struct mm_struct *mm,
- struct vm_area_struct * vma, unsigned long address,
- int write_access, pte_t *pte, pmd_t *pmd)
+ struct vm_area_struct *vma, unsigned long address,
+ pte_t *pte, pmd_t *pmd, int write_access)
{
pte_t entry;
+ pte_t old_entry;
+ spinlock_t *ptl;
- entry = *pte;
+ old_entry = entry = *pte;
if (!pte_present(entry)) {
- /*
- * If it truly wasn't present, we know that kswapd
- * and the PTE updates will not touch it later. So
- * drop the lock.
- */
- if (pte_none(entry))
- return do_no_page(mm, vma, address, write_access, pte, pmd);
+ if (pte_none(entry)) {
+ if (!vma->vm_ops || !vma->vm_ops->nopage)
+ return do_anonymous_page(mm, vma, address,
+ pte, pmd, write_access);
+ return do_no_page(mm, vma, address,
+ pte, pmd, write_access);
+ }
if (pte_file(entry))
- return do_file_page(mm, vma, address, write_access, pte, pmd);
- return do_swap_page(mm, vma, address, pte, pmd, entry, write_access);
+ return do_file_page(mm, vma, address,
+ pte, pmd, write_access, entry);
+ return do_swap_page(mm, vma, address,
+ pte, pmd, write_access, entry);
}
+ ptl = pte_lockptr(mm, pmd);
+ spin_lock(ptl);
+ if (unlikely(!pte_same(*pte, entry)))
+ goto unlock;
if (write_access) {
if (!pte_write(entry))
- return do_wp_page(mm, vma, address, pte, pmd, entry);
+ return do_wp_page(mm, vma, address,
+ pte, pmd, ptl, entry);
entry = pte_mkdirty(entry);
}
entry = pte_mkyoung(entry);
- ptep_set_access_flags(vma, address, pte, entry, write_access);
- update_mmu_cache(vma, address, entry);
- lazy_mmu_prot_update(entry);
- pte_unmap(pte);
- spin_unlock(&mm->page_table_lock);
+ if (!pte_same(old_entry, entry)) {
+ ptep_set_access_flags(vma, address, pte, entry, write_access);
+ update_mmu_cache(vma, address, entry);
+ lazy_mmu_prot_update(entry);
+ } else {
+ /*
+ * This is needed only for protection faults but the arch code
+ * is not yet telling us if this is a protection fault or not.
+ * This still avoids useless tlb flushes for .text page faults
+ * with threads.
+ */
+ if (write_access)
+ flush_tlb_page(vma, address);
+ }
+unlock:
+ pte_unmap_unlock(pte, ptl);
return VM_FAULT_MINOR;
}
/*
* By the time we get here, we already hold the mm semaphore
*/
-int __handle_mm_fault(struct mm_struct *mm, struct vm_area_struct * vma,
+int __handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long address, int write_access)
{
pgd_t *pgd;
@@ -2048,100 +2047,66 @@ int __handle_mm_fault(struct mm_struct *mm, struct vm_area_struct * vma,
if (unlikely(is_vm_hugetlb_page(vma)))
return hugetlb_fault(mm, vma, address, write_access);
- /*
- * We need the page table lock to synchronize with kswapd
- * and the SMP-safe atomic PTE updates.
- */
pgd = pgd_offset(mm, address);
- spin_lock(&mm->page_table_lock);
-
pud = pud_alloc(mm, pgd, address);
if (!pud)
- goto oom;
-
+ return VM_FAULT_OOM;
pmd = pmd_alloc(mm, pud, address);
if (!pmd)
- goto oom;
-
+ return VM_FAULT_OOM;
pte = pte_alloc_map(mm, pmd, address);
if (!pte)
- goto oom;
-
- return handle_pte_fault(mm, vma, address, write_access, pte, pmd);
+ return VM_FAULT_OOM;
- oom:
- spin_unlock(&mm->page_table_lock);
- return VM_FAULT_OOM;
+ return handle_pte_fault(mm, vma, address, pte, pmd, write_access);
}
#ifndef __PAGETABLE_PUD_FOLDED
/*
* Allocate page upper directory.
- *
- * We've already handled the fast-path in-line, and we own the
- * page table lock.
+ * We've already handled the fast-path in-line.
*/
-pud_t fastcall *__pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
+int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
{
- pud_t *new;
-
- spin_unlock(&mm->page_table_lock);
- new = pud_alloc_one(mm, address);
- spin_lock(&mm->page_table_lock);
+ pud_t *new = pud_alloc_one(mm, address);
if (!new)
- return NULL;
+ return -ENOMEM;
- /*
- * Because we dropped the lock, we should re-check the
- * entry, as somebody else could have populated it..
- */
- if (pgd_present(*pgd)) {
+ spin_lock(&mm->page_table_lock);
+ if (pgd_present(*pgd)) /* Another has populated it */
pud_free(new);
- goto out;
- }
- pgd_populate(mm, pgd, new);
- out:
- return pud_offset(pgd, address);
+ else
+ pgd_populate(mm, pgd, new);
+ spin_unlock(&mm->page_table_lock);
+ return 0;
}
#endif /* __PAGETABLE_PUD_FOLDED */
#ifndef __PAGETABLE_PMD_FOLDED
/*
* Allocate page middle directory.
- *
- * We've already handled the fast-path in-line, and we own the
- * page table lock.
+ * We've already handled the fast-path in-line.
*/
-pmd_t fastcall *__pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
+int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
{
- pmd_t *new;
-
- spin_unlock(&mm->page_table_lock);
- new = pmd_alloc_one(mm, address);
- spin_lock(&mm->page_table_lock);
+ pmd_t *new = pmd_alloc_one(mm, address);
if (!new)
- return NULL;
+ return -ENOMEM;
- /*
- * Because we dropped the lock, we should re-check the
- * entry, as somebody else could have populated it..
- */
+ spin_lock(&mm->page_table_lock);
#ifndef __ARCH_HAS_4LEVEL_HACK
- if (pud_present(*pud)) {
+ if (pud_present(*pud)) /* Another has populated it */
pmd_free(new);
- goto out;
- }
- pud_populate(mm, pud, new);
+ else
+ pud_populate(mm, pud, new);
#else
- if (pgd_present(*pud)) {
+ if (pgd_present(*pud)) /* Another has populated it */
pmd_free(new);
- goto out;
- }
- pgd_populate(mm, pud, new);
+ else
+ pgd_populate(mm, pud, new);
#endif /* __ARCH_HAS_4LEVEL_HACK */
-
- out:
- return pmd_offset(pud, address);
+ spin_unlock(&mm->page_table_lock);
+ return 0;
}
#endif /* __PAGETABLE_PMD_FOLDED */
@@ -2206,22 +2171,6 @@ unsigned long vmalloc_to_pfn(void * vmalloc_addr)
EXPORT_SYMBOL(vmalloc_to_pfn);
-/*
- * update_mem_hiwater
- * - update per process rss and vm high water data
- */
-void update_mem_hiwater(struct task_struct *tsk)
-{
- if (tsk->mm) {
- unsigned long rss = get_mm_counter(tsk->mm, rss);
-
- if (tsk->mm->hiwater_rss < rss)
- tsk->mm->hiwater_rss = rss;
- if (tsk->mm->hiwater_vm < tsk->mm->total_vm)
- tsk->mm->hiwater_vm = tsk->mm->total_vm;
- }
-}
-
#if !defined(__HAVE_ARCH_GATE_AREA)
#if defined(AT_SYSINFO_EHDR)
@@ -2233,7 +2182,7 @@ static int __init gate_vma_init(void)
gate_vma.vm_start = FIXADDR_USER_START;
gate_vma.vm_end = FIXADDR_USER_END;
gate_vma.vm_page_prot = PAGE_READONLY;
- gate_vma.vm_flags = 0;
+ gate_vma.vm_flags = VM_RESERVED;
return 0;
}
__initcall(gate_vma_init);
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
new file mode 100644
index 000000000000..431a64f021c0
--- /dev/null
+++ b/mm/memory_hotplug.c
@@ -0,0 +1,138 @@
+/*
+ * linux/mm/memory_hotplug.c
+ *
+ * Copyright (C)
+ */
+
+#include <linux/config.h>
+#include <linux/stddef.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/interrupt.h>
+#include <linux/pagemap.h>
+#include <linux/bootmem.h>
+#include <linux/compiler.h>
+#include <linux/module.h>
+#include <linux/pagevec.h>
+#include <linux/slab.h>
+#include <linux/sysctl.h>
+#include <linux/cpu.h>
+#include <linux/memory.h>
+#include <linux/memory_hotplug.h>
+#include <linux/highmem.h>
+#include <linux/vmalloc.h>
+
+#include <asm/tlbflush.h>
+
+extern void zonetable_add(struct zone *zone, int nid, int zid, unsigned long pfn,
+ unsigned long size);
+static void __add_zone(struct zone *zone, unsigned long phys_start_pfn)
+{
+ struct pglist_data *pgdat = zone->zone_pgdat;
+ int nr_pages = PAGES_PER_SECTION;
+ int nid = pgdat->node_id;
+ int zone_type;
+
+ zone_type = zone - pgdat->node_zones;
+ memmap_init_zone(nr_pages, nid, zone_type, phys_start_pfn);
+ zonetable_add(zone, nid, zone_type, phys_start_pfn, nr_pages);
+}
+
+extern int sparse_add_one_section(struct zone *zone, unsigned long start_pfn,
+ int nr_pages);
+static int __add_section(struct zone *zone, unsigned long phys_start_pfn)
+{
+ struct pglist_data *pgdat = zone->zone_pgdat;
+ int nr_pages = PAGES_PER_SECTION;
+ int ret;
+
+ ret = sparse_add_one_section(zone, phys_start_pfn, nr_pages);
+
+ if (ret < 0)
+ return ret;
+
+ __add_zone(zone, phys_start_pfn);
+ return register_new_memory(__pfn_to_section(phys_start_pfn));
+}
+
+/*
+ * Reasonably generic function for adding memory. It is
+ * expected that archs that support memory hotplug will
+ * call this function after deciding the zone to which to
+ * add the new pages.
+ */
+int __add_pages(struct zone *zone, unsigned long phys_start_pfn,
+ unsigned long nr_pages)
+{
+ unsigned long i;
+ int err = 0;
+
+ for (i = 0; i < nr_pages; i += PAGES_PER_SECTION) {
+ err = __add_section(zone, phys_start_pfn + i);
+
+ if (err)
+ break;
+ }
+
+ return err;
+}
+
+static void grow_zone_span(struct zone *zone,
+ unsigned long start_pfn, unsigned long end_pfn)
+{
+ unsigned long old_zone_end_pfn;
+
+ zone_span_writelock(zone);
+
+ old_zone_end_pfn = zone->zone_start_pfn + zone->spanned_pages;
+ if (start_pfn < zone->zone_start_pfn)
+ zone->zone_start_pfn = start_pfn;
+
+ if (end_pfn > old_zone_end_pfn)
+ zone->spanned_pages = end_pfn - zone->zone_start_pfn;
+
+ zone_span_writeunlock(zone);
+}
+
+static void grow_pgdat_span(struct pglist_data *pgdat,
+ unsigned long start_pfn, unsigned long end_pfn)
+{
+ unsigned long old_pgdat_end_pfn =
+ pgdat->node_start_pfn + pgdat->node_spanned_pages;
+
+ if (start_pfn < pgdat->node_start_pfn)
+ pgdat->node_start_pfn = start_pfn;
+
+ if (end_pfn > old_pgdat_end_pfn)
+ pgdat->node_spanned_pages = end_pfn - pgdat->node_spanned_pages;
+}
+
+int online_pages(unsigned long pfn, unsigned long nr_pages)
+{
+ unsigned long i;
+ unsigned long flags;
+ unsigned long onlined_pages = 0;
+ struct zone *zone;
+
+ /*
+ * This doesn't need a lock to do pfn_to_page().
+ * The section can't be removed here because of the
+ * memory_block->state_sem.
+ */
+ zone = page_zone(pfn_to_page(pfn));
+ pgdat_resize_lock(zone->zone_pgdat, &flags);
+ grow_zone_span(zone, pfn, pfn + nr_pages);
+ grow_pgdat_span(zone->zone_pgdat, pfn, pfn + nr_pages);
+ pgdat_resize_unlock(zone->zone_pgdat, &flags);
+
+ for (i = 0; i < nr_pages; i++) {
+ struct page *page = pfn_to_page(pfn + i);
+ online_page(page);
+ onlined_pages++;
+ }
+ zone->present_pages += onlined_pages;
+
+ setup_per_zone_pages_min();
+
+ return 0;
+}
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 1d5c64df1653..5abc57c2b8bd 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -2,6 +2,7 @@
* Simple NUMA memory policy for the Linux kernel.
*
* Copyright 2003,2004 Andi Kleen, SuSE Labs.
+ * (C) Copyright 2005 Christoph Lameter, Silicon Graphics, Inc.
* Subject to the GNU Public License, version 2.
*
* NUMA policy allows the user to give hints in which node(s) memory should
@@ -17,13 +18,19 @@
* offset into the backing object or offset into the mapping
* for anonymous memory. For process policy an process counter
* is used.
+ *
* bind Only allocate memory on a specific set of nodes,
* no fallback.
+ * FIXME: memory is allocated starting with the first node
+ * to the last. It would be better if bind would truly restrict
+ * the allocation to memory nodes instead
+ *
* preferred Try a specific node first before normal fallback.
* As a special case node -1 here means do the allocation
* on the local CPU. This is normally identical to default,
* but useful to set in a VMA when you have a non default
* process policy.
+ *
* default Allocate on the local node first, or when on a VMA
* use the process policy. This is what Linux always did
* in a NUMA aware kernel and still does by, ahem, default.
@@ -93,23 +100,10 @@ struct mempolicy default_policy = {
.policy = MPOL_DEFAULT,
};
-/* Check if all specified nodes are online */
-static int nodes_online(unsigned long *nodes)
-{
- DECLARE_BITMAP(online2, MAX_NUMNODES);
-
- bitmap_copy(online2, nodes_addr(node_online_map), MAX_NUMNODES);
- if (bitmap_empty(online2, MAX_NUMNODES))
- set_bit(0, online2);
- if (!bitmap_subset(nodes, online2, MAX_NUMNODES))
- return -EINVAL;
- return 0;
-}
-
/* Do sanity checking on a policy */
-static int mpol_check_policy(int mode, unsigned long *nodes)
+static int mpol_check_policy(int mode, nodemask_t *nodes)
{
- int empty = bitmap_empty(nodes, MAX_NUMNODES);
+ int empty = nodes_empty(*nodes);
switch (mode) {
case MPOL_DEFAULT:
@@ -124,71 +118,20 @@ static int mpol_check_policy(int mode, unsigned long *nodes)
return -EINVAL;
break;
}
- return nodes_online(nodes);
-}
-
-/* Copy a node mask from user space. */
-static int get_nodes(unsigned long *nodes, unsigned long __user *nmask,
- unsigned long maxnode, int mode)
-{
- unsigned long k;
- unsigned long nlongs;
- unsigned long endmask;
-
- --maxnode;
- bitmap_zero(nodes, MAX_NUMNODES);
- if (maxnode == 0 || !nmask)
- return 0;
-
- nlongs = BITS_TO_LONGS(maxnode);
- if ((maxnode % BITS_PER_LONG) == 0)
- endmask = ~0UL;
- else
- endmask = (1UL << (maxnode % BITS_PER_LONG)) - 1;
-
- /* When the user specified more nodes than supported just check
- if the non supported part is all zero. */
- if (nlongs > BITS_TO_LONGS(MAX_NUMNODES)) {
- if (nlongs > PAGE_SIZE/sizeof(long))
- return -EINVAL;
- for (k = BITS_TO_LONGS(MAX_NUMNODES); k < nlongs; k++) {
- unsigned long t;
- if (get_user(t, nmask + k))
- return -EFAULT;
- if (k == nlongs - 1) {
- if (t & endmask)
- return -EINVAL;
- } else if (t)
- return -EINVAL;
- }
- nlongs = BITS_TO_LONGS(MAX_NUMNODES);
- endmask = ~0UL;
- }
-
- if (copy_from_user(nodes, nmask, nlongs*sizeof(unsigned long)))
- return -EFAULT;
- nodes[nlongs-1] &= endmask;
- /* Update current mems_allowed */
- cpuset_update_current_mems_allowed();
- /* Ignore nodes not set in current->mems_allowed */
- cpuset_restrict_to_mems_allowed(nodes);
- return mpol_check_policy(mode, nodes);
+ return nodes_subset(*nodes, node_online_map) ? 0 : -EINVAL;
}
-
/* Generate a custom zonelist for the BIND policy. */
-static struct zonelist *bind_zonelist(unsigned long *nodes)
+static struct zonelist *bind_zonelist(nodemask_t *nodes)
{
struct zonelist *zl;
int num, max, nd;
- max = 1 + MAX_NR_ZONES * bitmap_weight(nodes, MAX_NUMNODES);
+ max = 1 + MAX_NR_ZONES * nodes_weight(*nodes);
zl = kmalloc(sizeof(void *) * max, GFP_KERNEL);
if (!zl)
return NULL;
num = 0;
- for (nd = find_first_bit(nodes, MAX_NUMNODES);
- nd < MAX_NUMNODES;
- nd = find_next_bit(nodes, MAX_NUMNODES, 1+nd)) {
+ for_each_node_mask(nd, *nodes) {
int k;
for (k = MAX_NR_ZONES-1; k >= 0; k--) {
struct zone *z = &NODE_DATA(nd)->node_zones[k];
@@ -199,17 +142,16 @@ static struct zonelist *bind_zonelist(unsigned long *nodes)
policy_zone = k;
}
}
- BUG_ON(num >= max);
zl->zones[num] = NULL;
return zl;
}
/* Create a new policy */
-static struct mempolicy *mpol_new(int mode, unsigned long *nodes)
+static struct mempolicy *mpol_new(int mode, nodemask_t *nodes)
{
struct mempolicy *policy;
- PDprintk("setting mode %d nodes[0] %lx\n", mode, nodes[0]);
+ PDprintk("setting mode %d nodes[0] %lx\n", mode, nodes_addr(*nodes)[0]);
if (mode == MPOL_DEFAULT)
return NULL;
policy = kmem_cache_alloc(policy_cache, GFP_KERNEL);
@@ -218,10 +160,10 @@ static struct mempolicy *mpol_new(int mode, unsigned long *nodes)
atomic_set(&policy->refcnt, 1);
switch (mode) {
case MPOL_INTERLEAVE:
- bitmap_copy(policy->v.nodes, nodes, MAX_NUMNODES);
+ policy->v.nodes = *nodes;
break;
case MPOL_PREFERRED:
- policy->v.preferred_node = find_first_bit(nodes, MAX_NUMNODES);
+ policy->v.preferred_node = first_node(*nodes);
if (policy->v.preferred_node >= MAX_NUMNODES)
policy->v.preferred_node = -1;
break;
@@ -238,14 +180,14 @@ static struct mempolicy *mpol_new(int mode, unsigned long *nodes)
}
/* Ensure all existing pages follow the policy. */
-static int check_pte_range(struct mm_struct *mm, pmd_t *pmd,
- unsigned long addr, unsigned long end, unsigned long *nodes)
+static int check_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
+ unsigned long addr, unsigned long end, nodemask_t *nodes)
{
pte_t *orig_pte;
pte_t *pte;
+ spinlock_t *ptl;
- spin_lock(&mm->page_table_lock);
- orig_pte = pte = pte_offset_map(pmd, addr);
+ orig_pte = pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
do {
unsigned long pfn;
unsigned int nid;
@@ -253,19 +195,20 @@ static int check_pte_range(struct mm_struct *mm, pmd_t *pmd,
if (!pte_present(*pte))
continue;
pfn = pte_pfn(*pte);
- if (!pfn_valid(pfn))
+ if (!pfn_valid(pfn)) {
+ print_bad_pte(vma, *pte, addr);
continue;
+ }
nid = pfn_to_nid(pfn);
- if (!test_bit(nid, nodes))
+ if (!node_isset(nid, *nodes))
break;
} while (pte++, addr += PAGE_SIZE, addr != end);
- pte_unmap(orig_pte);
- spin_unlock(&mm->page_table_lock);
+ pte_unmap_unlock(orig_pte, ptl);
return addr != end;
}
-static inline int check_pmd_range(struct mm_struct *mm, pud_t *pud,
- unsigned long addr, unsigned long end, unsigned long *nodes)
+static inline int check_pmd_range(struct vm_area_struct *vma, pud_t *pud,
+ unsigned long addr, unsigned long end, nodemask_t *nodes)
{
pmd_t *pmd;
unsigned long next;
@@ -275,14 +218,14 @@ static inline int check_pmd_range(struct mm_struct *mm, pud_t *pud,
next = pmd_addr_end(addr, end);
if (pmd_none_or_clear_bad(pmd))
continue;
- if (check_pte_range(mm, pmd, addr, next, nodes))
+ if (check_pte_range(vma, pmd, addr, next, nodes))
return -EIO;
} while (pmd++, addr = next, addr != end);
return 0;
}
-static inline int check_pud_range(struct mm_struct *mm, pgd_t *pgd,
- unsigned long addr, unsigned long end, unsigned long *nodes)
+static inline int check_pud_range(struct vm_area_struct *vma, pgd_t *pgd,
+ unsigned long addr, unsigned long end, nodemask_t *nodes)
{
pud_t *pud;
unsigned long next;
@@ -292,24 +235,24 @@ static inline int check_pud_range(struct mm_struct *mm, pgd_t *pgd,
next = pud_addr_end(addr, end);
if (pud_none_or_clear_bad(pud))
continue;
- if (check_pmd_range(mm, pud, addr, next, nodes))
+ if (check_pmd_range(vma, pud, addr, next, nodes))
return -EIO;
} while (pud++, addr = next, addr != end);
return 0;
}
-static inline int check_pgd_range(struct mm_struct *mm,
- unsigned long addr, unsigned long end, unsigned long *nodes)
+static inline int check_pgd_range(struct vm_area_struct *vma,
+ unsigned long addr, unsigned long end, nodemask_t *nodes)
{
pgd_t *pgd;
unsigned long next;
- pgd = pgd_offset(mm, addr);
+ pgd = pgd_offset(vma->vm_mm, addr);
do {
next = pgd_addr_end(addr, end);
if (pgd_none_or_clear_bad(pgd))
continue;
- if (check_pud_range(mm, pgd, addr, next, nodes))
+ if (check_pud_range(vma, pgd, addr, next, nodes))
return -EIO;
} while (pgd++, addr = next, addr != end);
return 0;
@@ -318,7 +261,7 @@ static inline int check_pgd_range(struct mm_struct *mm,
/* Step 1: check the range */
static struct vm_area_struct *
check_range(struct mm_struct *mm, unsigned long start, unsigned long end,
- unsigned long *nodes, unsigned long flags)
+ nodemask_t *nodes, unsigned long flags)
{
int err;
struct vm_area_struct *first, *vma, *prev;
@@ -326,6 +269,8 @@ check_range(struct mm_struct *mm, unsigned long start, unsigned long end,
first = find_vma(mm, start);
if (!first)
return ERR_PTR(-EFAULT);
+ if (first->vm_flags & VM_RESERVED)
+ return ERR_PTR(-EACCES);
prev = NULL;
for (vma = first; vma && vma->vm_start < end; vma = vma->vm_next) {
if (!vma->vm_next && vma->vm_end < end)
@@ -338,8 +283,7 @@ check_range(struct mm_struct *mm, unsigned long start, unsigned long end,
endvma = end;
if (vma->vm_start > start)
start = vma->vm_start;
- err = check_pgd_range(vma->vm_mm,
- start, endvma, nodes);
+ err = check_pgd_range(vma, start, endvma, nodes);
if (err) {
first = ERR_PTR(err);
break;
@@ -393,17 +337,25 @@ static int mbind_range(struct vm_area_struct *vma, unsigned long start,
return err;
}
-/* Change policy for a memory range */
-asmlinkage long sys_mbind(unsigned long start, unsigned long len,
- unsigned long mode,
- unsigned long __user *nmask, unsigned long maxnode,
- unsigned flags)
+static int contextualize_policy(int mode, nodemask_t *nodes)
+{
+ if (!nodes)
+ return 0;
+
+ /* Update current mems_allowed */
+ cpuset_update_current_mems_allowed();
+ /* Ignore nodes not set in current->mems_allowed */
+ cpuset_restrict_to_mems_allowed(nodes->bits);
+ return mpol_check_policy(mode, nodes);
+}
+
+long do_mbind(unsigned long start, unsigned long len,
+ unsigned long mode, nodemask_t *nmask, unsigned long flags)
{
struct vm_area_struct *vma;
struct mm_struct *mm = current->mm;
struct mempolicy *new;
unsigned long end;
- DECLARE_BITMAP(nodes, MAX_NUMNODES);
int err;
if ((flags & ~(unsigned long)(MPOL_MF_STRICT)) || mode > MPOL_MAX)
@@ -418,20 +370,17 @@ asmlinkage long sys_mbind(unsigned long start, unsigned long len,
return -EINVAL;
if (end == start)
return 0;
-
- err = get_nodes(nodes, nmask, maxnode, mode);
- if (err)
- return err;
-
- new = mpol_new(mode, nodes);
+ if (mpol_check_policy(mode, nmask))
+ return -EINVAL;
+ new = mpol_new(mode, nmask);
if (IS_ERR(new))
return PTR_ERR(new);
PDprintk("mbind %lx-%lx mode:%ld nodes:%lx\n",start,start+len,
- mode,nodes[0]);
+ mode,nodes_addr(nodes)[0]);
down_write(&mm->mmap_sem);
- vma = check_range(mm, start, end, nodes, flags);
+ vma = check_range(mm, start, end, nmask, flags);
err = PTR_ERR(vma);
if (!IS_ERR(vma))
err = mbind_range(vma, start, end, new);
@@ -441,50 +390,45 @@ asmlinkage long sys_mbind(unsigned long start, unsigned long len,
}
/* Set the process memory policy */
-asmlinkage long sys_set_mempolicy(int mode, unsigned long __user *nmask,
- unsigned long maxnode)
+long do_set_mempolicy(int mode, nodemask_t *nodes)
{
- int err;
struct mempolicy *new;
- DECLARE_BITMAP(nodes, MAX_NUMNODES);
- if (mode < 0 || mode > MPOL_MAX)
+ if (contextualize_policy(mode, nodes))
return -EINVAL;
- err = get_nodes(nodes, nmask, maxnode, mode);
- if (err)
- return err;
new = mpol_new(mode, nodes);
if (IS_ERR(new))
return PTR_ERR(new);
mpol_free(current->mempolicy);
current->mempolicy = new;
if (new && new->policy == MPOL_INTERLEAVE)
- current->il_next = find_first_bit(new->v.nodes, MAX_NUMNODES);
+ current->il_next = first_node(new->v.nodes);
return 0;
}
/* Fill a zone bitmap for a policy */
-static void get_zonemask(struct mempolicy *p, unsigned long *nodes)
+static void get_zonemask(struct mempolicy *p, nodemask_t *nodes)
{
int i;
- bitmap_zero(nodes, MAX_NUMNODES);
+ nodes_clear(*nodes);
switch (p->policy) {
case MPOL_BIND:
for (i = 0; p->v.zonelist->zones[i]; i++)
- __set_bit(p->v.zonelist->zones[i]->zone_pgdat->node_id, nodes);
+ node_set(p->v.zonelist->zones[i]->zone_pgdat->node_id,
+ *nodes);
break;
case MPOL_DEFAULT:
break;
case MPOL_INTERLEAVE:
- bitmap_copy(nodes, p->v.nodes, MAX_NUMNODES);
+ *nodes = p->v.nodes;
break;
case MPOL_PREFERRED:
/* or use current node instead of online map? */
if (p->v.preferred_node < 0)
- bitmap_copy(nodes, nodes_addr(node_online_map), MAX_NUMNODES);
+ *nodes = node_online_map;
else
- __set_bit(p->v.preferred_node, nodes);
+ node_set(p->v.preferred_node, *nodes);
break;
default:
BUG();
@@ -504,37 +448,18 @@ static int lookup_node(struct mm_struct *mm, unsigned long addr)
return err;
}
-/* Copy a kernel node mask to user space */
-static int copy_nodes_to_user(unsigned long __user *mask, unsigned long maxnode,
- void *nodes, unsigned nbytes)
-{
- unsigned long copy = ALIGN(maxnode-1, 64) / 8;
-
- if (copy > nbytes) {
- if (copy > PAGE_SIZE)
- return -EINVAL;
- if (clear_user((char __user *)mask + nbytes, copy - nbytes))
- return -EFAULT;
- copy = nbytes;
- }
- return copy_to_user(mask, nodes, copy) ? -EFAULT : 0;
-}
-
/* Retrieve NUMA policy */
-asmlinkage long sys_get_mempolicy(int __user *policy,
- unsigned long __user *nmask,
- unsigned long maxnode,
- unsigned long addr, unsigned long flags)
+long do_get_mempolicy(int *policy, nodemask_t *nmask,
+ unsigned long addr, unsigned long flags)
{
- int err, pval;
+ int err;
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma = NULL;
struct mempolicy *pol = current->mempolicy;
+ cpuset_update_current_mems_allowed();
if (flags & ~(unsigned long)(MPOL_F_NODE|MPOL_F_ADDR))
return -EINVAL;
- if (nmask != NULL && maxnode < MAX_NUMNODES)
- return -EINVAL;
if (flags & MPOL_F_ADDR) {
down_read(&mm->mmap_sem);
vma = find_vma_intersection(mm, addr, addr+1);
@@ -557,31 +482,25 @@ asmlinkage long sys_get_mempolicy(int __user *policy,
err = lookup_node(mm, addr);
if (err < 0)
goto out;
- pval = err;
+ *policy = err;
} else if (pol == current->mempolicy &&
pol->policy == MPOL_INTERLEAVE) {
- pval = current->il_next;
+ *policy = current->il_next;
} else {
err = -EINVAL;
goto out;
}
} else
- pval = pol->policy;
+ *policy = pol->policy;
if (vma) {
up_read(&current->mm->mmap_sem);
vma = NULL;
}
- if (policy && put_user(pval, policy))
- return -EFAULT;
-
err = 0;
- if (nmask) {
- DECLARE_BITMAP(nodes, MAX_NUMNODES);
- get_zonemask(pol, nodes);
- err = copy_nodes_to_user(nmask, maxnode, nodes, sizeof(nodes));
- }
+ if (nmask)
+ get_zonemask(pol, nmask);
out:
if (vma)
@@ -589,6 +508,126 @@ asmlinkage long sys_get_mempolicy(int __user *policy,
return err;
}
+/*
+ * User space interface with variable sized bitmaps for nodelists.
+ */
+
+/* Copy a node mask from user space. */
+static int get_nodes(nodemask_t *nodes, unsigned long __user *nmask,
+ unsigned long maxnode)
+{
+ unsigned long k;
+ unsigned long nlongs;
+ unsigned long endmask;
+
+ --maxnode;
+ nodes_clear(*nodes);
+ if (maxnode == 0 || !nmask)
+ return 0;
+
+ nlongs = BITS_TO_LONGS(maxnode);
+ if ((maxnode % BITS_PER_LONG) == 0)
+ endmask = ~0UL;
+ else
+ endmask = (1UL << (maxnode % BITS_PER_LONG)) - 1;
+
+ /* When the user specified more nodes than supported just check
+ if the non supported part is all zero. */
+ if (nlongs > BITS_TO_LONGS(MAX_NUMNODES)) {
+ if (nlongs > PAGE_SIZE/sizeof(long))
+ return -EINVAL;
+ for (k = BITS_TO_LONGS(MAX_NUMNODES); k < nlongs; k++) {
+ unsigned long t;
+ if (get_user(t, nmask + k))
+ return -EFAULT;
+ if (k == nlongs - 1) {
+ if (t & endmask)
+ return -EINVAL;
+ } else if (t)
+ return -EINVAL;
+ }
+ nlongs = BITS_TO_LONGS(MAX_NUMNODES);
+ endmask = ~0UL;
+ }
+
+ if (copy_from_user(nodes_addr(*nodes), nmask, nlongs*sizeof(unsigned long)))
+ return -EFAULT;
+ nodes_addr(*nodes)[nlongs-1] &= endmask;
+ return 0;
+}
+
+/* Copy a kernel node mask to user space */
+static int copy_nodes_to_user(unsigned long __user *mask, unsigned long maxnode,
+ nodemask_t *nodes)
+{
+ unsigned long copy = ALIGN(maxnode-1, 64) / 8;
+ const int nbytes = BITS_TO_LONGS(MAX_NUMNODES) * sizeof(long);
+
+ if (copy > nbytes) {
+ if (copy > PAGE_SIZE)
+ return -EINVAL;
+ if (clear_user((char __user *)mask + nbytes, copy - nbytes))
+ return -EFAULT;
+ copy = nbytes;
+ }
+ return copy_to_user(mask, nodes_addr(*nodes), copy) ? -EFAULT : 0;
+}
+
+asmlinkage long sys_mbind(unsigned long start, unsigned long len,
+ unsigned long mode,
+ unsigned long __user *nmask, unsigned long maxnode,
+ unsigned flags)
+{
+ nodemask_t nodes;
+ int err;
+
+ err = get_nodes(&nodes, nmask, maxnode);
+ if (err)
+ return err;
+ return do_mbind(start, len, mode, &nodes, flags);
+}
+
+/* Set the process memory policy */
+asmlinkage long sys_set_mempolicy(int mode, unsigned long __user *nmask,
+ unsigned long maxnode)
+{
+ int err;
+ nodemask_t nodes;
+
+ if (mode < 0 || mode > MPOL_MAX)
+ return -EINVAL;
+ err = get_nodes(&nodes, nmask, maxnode);
+ if (err)
+ return err;
+ return do_set_mempolicy(mode, &nodes);
+}
+
+/* Retrieve NUMA policy */
+asmlinkage long sys_get_mempolicy(int __user *policy,
+ unsigned long __user *nmask,
+ unsigned long maxnode,
+ unsigned long addr, unsigned long flags)
+{
+ int err, pval;
+ nodemask_t nodes;
+
+ if (nmask != NULL && maxnode < MAX_NUMNODES)
+ return -EINVAL;
+
+ err = do_get_mempolicy(&pval, &nodes, addr, flags);
+
+ if (err)
+ return err;
+
+ if (policy && put_user(pval, policy))
+ return -EFAULT;
+
+ if (nmask)
+ err = copy_nodes_to_user(nmask, maxnode, &nodes);
+
+ return err;
+}
+
#ifdef CONFIG_COMPAT
asmlinkage long compat_sys_get_mempolicy(int __user *policy,
@@ -649,15 +688,15 @@ asmlinkage long compat_sys_mbind(compat_ulong_t start, compat_ulong_t len,
long err = 0;
unsigned long __user *nm = NULL;
unsigned long nr_bits, alloc_size;
- DECLARE_BITMAP(bm, MAX_NUMNODES);
+ nodemask_t bm;
nr_bits = min_t(unsigned long, maxnode-1, MAX_NUMNODES);
alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8;
if (nmask) {
- err = compat_get_bitmap(bm, nmask, nr_bits);
+ err = compat_get_bitmap(nodes_addr(bm), nmask, nr_bits);
nm = compat_alloc_user_space(alloc_size);
- err |= copy_to_user(nm, bm, alloc_size);
+ err |= copy_to_user(nm, nodes_addr(bm), alloc_size);
}
if (err)
@@ -676,7 +715,7 @@ get_vma_policy(struct task_struct *task, struct vm_area_struct *vma, unsigned lo
if (vma) {
if (vma->vm_ops && vma->vm_ops->get_policy)
- pol = vma->vm_ops->get_policy(vma, addr);
+ pol = vma->vm_ops->get_policy(vma, addr);
else if (vma->vm_policy &&
vma->vm_policy->policy != MPOL_DEFAULT)
pol = vma->vm_policy;
@@ -722,10 +761,9 @@ static unsigned interleave_nodes(struct mempolicy *policy)
struct task_struct *me = current;
nid = me->il_next;
- BUG_ON(nid >= MAX_NUMNODES);
- next = find_next_bit(policy->v.nodes, MAX_NUMNODES, 1+nid);
+ next = next_node(nid, policy->v.nodes);
if (next >= MAX_NUMNODES)
- next = find_first_bit(policy->v.nodes, MAX_NUMNODES);
+ next = first_node(policy->v.nodes);
me->il_next = next;
return nid;
}
@@ -734,29 +772,27 @@ static unsigned interleave_nodes(struct mempolicy *policy)
static unsigned offset_il_node(struct mempolicy *pol,
struct vm_area_struct *vma, unsigned long off)
{
- unsigned nnodes = bitmap_weight(pol->v.nodes, MAX_NUMNODES);
+ unsigned nnodes = nodes_weight(pol->v.nodes);
unsigned target = (unsigned)off % nnodes;
int c;
int nid = -1;
c = 0;
do {
- nid = find_next_bit(pol->v.nodes, MAX_NUMNODES, nid+1);
+ nid = next_node(nid, pol->v.nodes);
c++;
} while (c <= target);
- BUG_ON(nid >= MAX_NUMNODES);
- BUG_ON(!test_bit(nid, pol->v.nodes));
return nid;
}
/* Allocate a page in interleaved policy.
Own path because it needs to do special accounting. */
-static struct page *alloc_page_interleave(gfp_t gfp, unsigned order, unsigned nid)
+static struct page *alloc_page_interleave(gfp_t gfp, unsigned order,
+ unsigned nid)
{
struct zonelist *zl;
struct page *page;
- BUG_ON(!node_online(nid));
zl = NODE_DATA(nid)->node_zonelists + gfp_zone(gfp);
page = __alloc_pages(gfp, order, zl);
if (page && page_zone(page) == zl->zones[0]) {
@@ -799,8 +835,6 @@ alloc_page_vma(gfp_t gfp, struct vm_area_struct *vma, unsigned long addr)
unsigned nid;
if (vma) {
unsigned long off;
- BUG_ON(addr >= vma->vm_end);
- BUG_ON(addr < vma->vm_start);
off = vma->vm_pgoff;
off += (addr - vma->vm_start) >> PAGE_SHIFT;
nid = offset_il_node(pol, vma, off);
@@ -878,7 +912,7 @@ int __mpol_equal(struct mempolicy *a, struct mempolicy *b)
case MPOL_DEFAULT:
return 1;
case MPOL_INTERLEAVE:
- return bitmap_equal(a->v.nodes, b->v.nodes, MAX_NUMNODES);
+ return nodes_equal(a->v.nodes, b->v.nodes);
case MPOL_PREFERRED:
return a->v.preferred_node == b->v.preferred_node;
case MPOL_BIND: {
@@ -1117,7 +1151,7 @@ int mpol_set_shared_policy(struct shared_policy *info,
PDprintk("set_shared_policy %lx sz %lu %d %lx\n",
vma->vm_pgoff,
sz, npol? npol->policy : -1,
- npol ? npol->v.nodes[0] : -1);
+ npol ? nodes_addr(npol->v.nodes)[0] : -1);
if (npol) {
new = sp_alloc(vma->vm_pgoff, vma->vm_pgoff + sz, npol);
@@ -1164,14 +1198,75 @@ void __init numa_policy_init(void)
/* Set interleaving policy for system init. This way not all
the data structures allocated at system boot end up in node zero. */
- if (sys_set_mempolicy(MPOL_INTERLEAVE, nodes_addr(node_online_map),
- MAX_NUMNODES) < 0)
+ if (do_set_mempolicy(MPOL_INTERLEAVE, &node_online_map))
printk("numa_policy_init: interleaving failed\n");
}
-/* Reset policy of current process to default.
- * Assumes fs == KERNEL_DS */
+/* Reset policy of current process to default */
void numa_default_policy(void)
{
- sys_set_mempolicy(MPOL_DEFAULT, NULL, 0);
+ do_set_mempolicy(MPOL_DEFAULT, NULL);
+}
+
+/* Migrate a policy to a different set of nodes */
+static void rebind_policy(struct mempolicy *pol, const nodemask_t *old,
+ const nodemask_t *new)
+{
+ nodemask_t tmp;
+
+ if (!pol)
+ return;
+
+ switch (pol->policy) {
+ case MPOL_DEFAULT:
+ break;
+ case MPOL_INTERLEAVE:
+ nodes_remap(tmp, pol->v.nodes, *old, *new);
+ pol->v.nodes = tmp;
+ current->il_next = node_remap(current->il_next, *old, *new);
+ break;
+ case MPOL_PREFERRED:
+ pol->v.preferred_node = node_remap(pol->v.preferred_node,
+ *old, *new);
+ break;
+ case MPOL_BIND: {
+ nodemask_t nodes;
+ struct zone **z;
+ struct zonelist *zonelist;
+
+ nodes_clear(nodes);
+ for (z = pol->v.zonelist->zones; *z; z++)
+ node_set((*z)->zone_pgdat->node_id, nodes);
+ nodes_remap(tmp, nodes, *old, *new);
+ nodes = tmp;
+
+ zonelist = bind_zonelist(&nodes);
+
+ /* If no mem, then zonelist is NULL and we keep old zonelist.
+ * If that old zonelist has no remaining mems_allowed nodes,
+ * then zonelist_policy() will "FALL THROUGH" to MPOL_DEFAULT.
+ */
+
+ if (zonelist) {
+ /* Good - got mem - substitute new zonelist */
+ kfree(pol->v.zonelist);
+ pol->v.zonelist = zonelist;
+ }
+ break;
+ }
+ default:
+ BUG();
+ break;
+ }
+}
+
+/*
+ * Someone moved this task to different nodes. Fixup mempolicies.
+ *
+ * TODO - fixup current->mm->vma and shmfs/tmpfs/hugetlbfs policies as well,
+ * once we have a cpuset mechanism to mark which cpuset subtree is migrating.
+ */
+void numa_policy_rebind(const nodemask_t *old, const nodemask_t *new)
+{
+ rebind_policy(current->mempolicy, old, new);
}
diff --git a/mm/mmap.c b/mm/mmap.c
index fa11d91242e8..320dda1778c3 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -181,26 +181,36 @@ static void __remove_shared_vm_struct(struct vm_area_struct *vma,
}
/*
- * Remove one vm structure and free it.
+ * Unlink a file-based vm structure from its prio_tree, to hide
+ * vma from rmap and vmtruncate before freeing its page tables.
*/
-static void remove_vm_struct(struct vm_area_struct *vma)
+void unlink_file_vma(struct vm_area_struct *vma)
{
struct file *file = vma->vm_file;
- might_sleep();
if (file) {
struct address_space *mapping = file->f_mapping;
spin_lock(&mapping->i_mmap_lock);
__remove_shared_vm_struct(vma, file, mapping);
spin_unlock(&mapping->i_mmap_lock);
}
+}
+
+/*
+ * Close a vm structure and free it, returning the next.
+ */
+static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
+{
+ struct vm_area_struct *next = vma->vm_next;
+
+ might_sleep();
if (vma->vm_ops && vma->vm_ops->close)
vma->vm_ops->close(vma);
- if (file)
- fput(file);
- anon_vma_unlink(vma);
+ if (vma->vm_file)
+ fput(vma->vm_file);
mpol_free(vma_policy(vma));
kmem_cache_free(vm_area_cachep, vma);
+ return next;
}
asmlinkage unsigned long sys_brk(unsigned long brk)
@@ -832,7 +842,7 @@ none:
}
#ifdef CONFIG_PROC_FS
-void __vm_stat_account(struct mm_struct *mm, unsigned long flags,
+void vm_stat_account(struct mm_struct *mm, unsigned long flags,
struct file *file, long pages)
{
const unsigned long stack_flags
@@ -1070,6 +1080,17 @@ munmap_back:
error = file->f_op->mmap(file, vma);
if (error)
goto unmap_and_free_vma;
+ if ((vma->vm_flags & (VM_SHARED | VM_WRITE | VM_RESERVED))
+ == (VM_WRITE | VM_RESERVED)) {
+ printk(KERN_WARNING "program %s is using MAP_PRIVATE, "
+ "PROT_WRITE mmap of VM_RESERVED memory, which "
+ "is deprecated. Please report this to "
+ "linux-kernel@vger.kernel.org\n",current->comm);
+ if (vma->vm_ops && vma->vm_ops->close)
+ vma->vm_ops->close(vma);
+ error = -EACCES;
+ goto unmap_and_free_vma;
+ }
} else if (vm_flags & VM_SHARED) {
error = shmem_zero_setup(vma);
if (error)
@@ -1110,7 +1131,7 @@ munmap_back:
}
out:
mm->total_vm += len >> PAGE_SHIFT;
- __vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
+ vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
if (vm_flags & VM_LOCKED) {
mm->locked_vm += len >> PAGE_SHIFT;
make_pages_present(addr, addr + len);
@@ -1475,15 +1496,19 @@ static int acct_stack_growth(struct vm_area_struct * vma, unsigned long size, un
mm->total_vm += grow;
if (vma->vm_flags & VM_LOCKED)
mm->locked_vm += grow;
- __vm_stat_account(mm, vma->vm_flags, vma->vm_file, grow);
+ vm_stat_account(mm, vma->vm_flags, vma->vm_file, grow);
return 0;
}
-#ifdef CONFIG_STACK_GROWSUP
+#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64)
/*
- * vma is the first one with address > vma->vm_end. Have to extend vma.
+ * PA-RISC uses this for its stack; IA64 for its Register Backing Store.
+ * vma is the last one with address > vma->vm_end. Have to extend vma.
*/
-int expand_stack(struct vm_area_struct * vma, unsigned long address)
+#ifdef CONFIG_STACK_GROWSUP
+static inline
+#endif
+int expand_upwards(struct vm_area_struct *vma, unsigned long address)
{
int error;
@@ -1521,6 +1546,13 @@ int expand_stack(struct vm_area_struct * vma, unsigned long address)
anon_vma_unlock(vma);
return error;
}
+#endif /* CONFIG_STACK_GROWSUP || CONFIG_IA64 */
+
+#ifdef CONFIG_STACK_GROWSUP
+int expand_stack(struct vm_area_struct *vma, unsigned long address)
+{
+ return expand_upwards(vma, address);
+}
struct vm_area_struct *
find_extend_vma(struct mm_struct *mm, unsigned long addr)
@@ -1603,36 +1635,24 @@ find_extend_vma(struct mm_struct * mm, unsigned long addr)
}
#endif
-/* Normal function to fix up a mapping
- * This function is the default for when an area has no specific
- * function. This may be used as part of a more specific routine.
- *
- * By the time this function is called, the area struct has been
- * removed from the process mapping list.
- */
-static void unmap_vma(struct mm_struct *mm, struct vm_area_struct *area)
-{
- size_t len = area->vm_end - area->vm_start;
-
- area->vm_mm->total_vm -= len >> PAGE_SHIFT;
- if (area->vm_flags & VM_LOCKED)
- area->vm_mm->locked_vm -= len >> PAGE_SHIFT;
- vm_stat_unaccount(area);
- remove_vm_struct(area);
-}
-
/*
- * Update the VMA and inode share lists.
- *
- * Ok - we have the memory areas we should free on the 'free' list,
+ * Ok - we have the memory areas we should free on the vma list,
* so release them, and do the vma updates.
+ *
+ * Called with the mm semaphore held.
*/
-static void unmap_vma_list(struct mm_struct *mm, struct vm_area_struct *vma)
+static void remove_vma_list(struct mm_struct *mm, struct vm_area_struct *vma)
{
+ /* Update high watermark before we lower total_vm */
+ update_hiwater_vm(mm);
do {
- struct vm_area_struct *next = vma->vm_next;
- unmap_vma(mm, vma);
- vma = next;
+ long nrpages = vma_pages(vma);
+
+ mm->total_vm -= nrpages;
+ if (vma->vm_flags & VM_LOCKED)
+ mm->locked_vm -= nrpages;
+ vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages);
+ vma = remove_vma(vma);
} while (vma);
validate_mm(mm);
}
@@ -1651,14 +1671,13 @@ static void unmap_region(struct mm_struct *mm,
unsigned long nr_accounted = 0;
lru_add_drain();
- spin_lock(&mm->page_table_lock);
tlb = tlb_gather_mmu(mm, 0);
- unmap_vmas(&tlb, mm, vma, start, end, &nr_accounted, NULL);
+ update_hiwater_rss(mm);
+ unmap_vmas(&tlb, vma, start, end, &nr_accounted, NULL);
vm_unacct_memory(nr_accounted);
free_pgtables(&tlb, vma, prev? prev->vm_end: FIRST_USER_ADDRESS,
next? next->vm_start: 0);
tlb_finish_mmu(tlb, start, end);
- spin_unlock(&mm->page_table_lock);
}
/*
@@ -1799,7 +1818,7 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
unmap_region(mm, vma, prev, start, end);
/* Fix up all other VM information */
- unmap_vma_list(mm, vma);
+ remove_vma_list(mm, vma);
return 0;
}
@@ -1821,7 +1840,7 @@ asmlinkage long sys_munmap(unsigned long addr, size_t len)
static inline void verify_mm_writelocked(struct mm_struct *mm)
{
-#ifdef CONFIG_DEBUG_KERNEL
+#ifdef CONFIG_DEBUG_VM
if (unlikely(down_read_trylock(&mm->mmap_sem))) {
WARN_ON(1);
up_read(&mm->mmap_sem);
@@ -1933,34 +1952,21 @@ void exit_mmap(struct mm_struct *mm)
unsigned long end;
lru_add_drain();
-
- spin_lock(&mm->page_table_lock);
-
flush_cache_mm(mm);
tlb = tlb_gather_mmu(mm, 1);
+ /* Don't update_hiwater_rss(mm) here, do_exit already did */
/* Use -1 here to ensure all VMAs in the mm are unmapped */
- end = unmap_vmas(&tlb, mm, vma, 0, -1, &nr_accounted, NULL);
+ end = unmap_vmas(&tlb, vma, 0, -1, &nr_accounted, NULL);
vm_unacct_memory(nr_accounted);
free_pgtables(&tlb, vma, FIRST_USER_ADDRESS, 0);
tlb_finish_mmu(tlb, 0, end);
- mm->mmap = mm->mmap_cache = NULL;
- mm->mm_rb = RB_ROOT;
- set_mm_counter(mm, rss, 0);
- mm->total_vm = 0;
- mm->locked_vm = 0;
-
- spin_unlock(&mm->page_table_lock);
-
/*
- * Walk the list again, actually closing and freeing it
- * without holding any MM locks.
+ * Walk the list again, actually closing and freeing it,
+ * with preemption enabled, without holding any MM locks.
*/
- while (vma) {
- struct vm_area_struct *next = vma->vm_next;
- remove_vm_struct(vma);
- vma = next;
- }
+ while (vma)
+ vma = remove_vma(vma);
BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
}
diff --git a/mm/mprotect.c b/mm/mprotect.c
index 57577f63b305..17a2b52b753b 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -29,8 +29,9 @@ static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
unsigned long addr, unsigned long end, pgprot_t newprot)
{
pte_t *pte;
+ spinlock_t *ptl;
- pte = pte_offset_map(pmd, addr);
+ pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
do {
if (pte_present(*pte)) {
pte_t ptent;
@@ -44,7 +45,7 @@ static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
lazy_mmu_prot_update(ptent);
}
} while (pte++, addr += PAGE_SIZE, addr != end);
- pte_unmap(pte - 1);
+ pte_unmap_unlock(pte - 1, ptl);
}
static inline void change_pmd_range(struct mm_struct *mm, pud_t *pud,
@@ -88,7 +89,6 @@ static void change_protection(struct vm_area_struct *vma,
BUG_ON(addr >= end);
pgd = pgd_offset(mm, addr);
flush_cache_range(vma, addr, end);
- spin_lock(&mm->page_table_lock);
do {
next = pgd_addr_end(addr, end);
if (pgd_none_or_clear_bad(pgd))
@@ -96,7 +96,6 @@ static void change_protection(struct vm_area_struct *vma,
change_pud_range(mm, pgd, addr, next, newprot);
} while (pgd++, addr = next, addr != end);
flush_tlb_range(vma, start, end);
- spin_unlock(&mm->page_table_lock);
}
static int
@@ -125,6 +124,14 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
* a MAP_NORESERVE private mapping to writable will now reserve.
*/
if (newflags & VM_WRITE) {
+ if (oldflags & VM_RESERVED) {
+ BUG_ON(oldflags & VM_WRITE);
+ printk(KERN_WARNING "program %s is using MAP_PRIVATE, "
+ "PROT_WRITE mprotect of VM_RESERVED memory, "
+ "which is deprecated. Please report this to "
+ "linux-kernel@vger.kernel.org\n",current->comm);
+ return -EACCES;
+ }
if (!(oldflags & (VM_ACCOUNT|VM_WRITE|VM_SHARED|VM_HUGETLB))) {
charged = nrpages;
if (security_vm_enough_memory(charged))
@@ -168,8 +175,8 @@ success:
vma->vm_flags = newflags;
vma->vm_page_prot = newprot;
change_protection(vma, start, end, newprot);
- __vm_stat_account(mm, oldflags, vma->vm_file, -nrpages);
- __vm_stat_account(mm, newflags, vma->vm_file, nrpages);
+ vm_stat_account(mm, oldflags, vma->vm_file, -nrpages);
+ vm_stat_account(mm, newflags, vma->vm_file, nrpages);
return 0;
fail:
diff --git a/mm/mremap.c b/mm/mremap.c
index f343fc73a8bd..b535438c363c 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -22,35 +22,7 @@
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
-static pte_t *get_one_pte_map_nested(struct mm_struct *mm, unsigned long addr)
-{
- pgd_t *pgd;
- pud_t *pud;
- pmd_t *pmd;
- pte_t *pte = NULL;
-
- pgd = pgd_offset(mm, addr);
- if (pgd_none_or_clear_bad(pgd))
- goto end;
-
- pud = pud_offset(pgd, addr);
- if (pud_none_or_clear_bad(pud))
- goto end;
-
- pmd = pmd_offset(pud, addr);
- if (pmd_none_or_clear_bad(pmd))
- goto end;
-
- pte = pte_offset_map_nested(pmd, addr);
- if (pte_none(*pte)) {
- pte_unmap_nested(pte);
- pte = NULL;
- }
-end:
- return pte;
-}
-
-static pte_t *get_one_pte_map(struct mm_struct *mm, unsigned long addr)
+static pmd_t *get_old_pmd(struct mm_struct *mm, unsigned long addr)
{
pgd_t *pgd;
pud_t *pud;
@@ -68,35 +40,39 @@ static pte_t *get_one_pte_map(struct mm_struct *mm, unsigned long addr)
if (pmd_none_or_clear_bad(pmd))
return NULL;
- return pte_offset_map(pmd, addr);
+ return pmd;
}
-static inline pte_t *alloc_one_pte_map(struct mm_struct *mm, unsigned long addr)
+static pmd_t *alloc_new_pmd(struct mm_struct *mm, unsigned long addr)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
- pte_t *pte = NULL;
pgd = pgd_offset(mm, addr);
-
pud = pud_alloc(mm, pgd, addr);
if (!pud)
return NULL;
+
pmd = pmd_alloc(mm, pud, addr);
- if (pmd)
- pte = pte_alloc_map(mm, pmd, addr);
- return pte;
+ if (!pmd)
+ return NULL;
+
+ if (!pmd_present(*pmd) && __pte_alloc(mm, pmd, addr))
+ return NULL;
+
+ return pmd;
}
-static int
-move_one_page(struct vm_area_struct *vma, unsigned long old_addr,
- struct vm_area_struct *new_vma, unsigned long new_addr)
+static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
+ unsigned long old_addr, unsigned long old_end,
+ struct vm_area_struct *new_vma, pmd_t *new_pmd,
+ unsigned long new_addr)
{
struct address_space *mapping = NULL;
struct mm_struct *mm = vma->vm_mm;
- int error = 0;
- pte_t *src, *dst;
+ pte_t *old_pte, *new_pte, pte;
+ spinlock_t *old_ptl, *new_ptl;
if (vma->vm_file) {
/*
@@ -111,74 +87,69 @@ move_one_page(struct vm_area_struct *vma, unsigned long old_addr,
new_vma->vm_truncate_count != vma->vm_truncate_count)
new_vma->vm_truncate_count = 0;
}
- spin_lock(&mm->page_table_lock);
- src = get_one_pte_map_nested(mm, old_addr);
- if (src) {
- /*
- * Look to see whether alloc_one_pte_map needs to perform a
- * memory allocation. If it does then we need to drop the
- * atomic kmap
- */
- dst = get_one_pte_map(mm, new_addr);
- if (unlikely(!dst)) {
- pte_unmap_nested(src);
- if (mapping)
- spin_unlock(&mapping->i_mmap_lock);
- dst = alloc_one_pte_map(mm, new_addr);
- if (mapping && !spin_trylock(&mapping->i_mmap_lock)) {
- spin_unlock(&mm->page_table_lock);
- spin_lock(&mapping->i_mmap_lock);
- spin_lock(&mm->page_table_lock);
- }
- src = get_one_pte_map_nested(mm, old_addr);
- }
- /*
- * Since alloc_one_pte_map can drop and re-acquire
- * page_table_lock, we should re-check the src entry...
- */
- if (src) {
- if (dst) {
- pte_t pte;
- pte = ptep_clear_flush(vma, old_addr, src);
-
- /* ZERO_PAGE can be dependant on virtual addr */
- pte = move_pte(pte, new_vma->vm_page_prot,
- old_addr, new_addr);
- set_pte_at(mm, new_addr, dst, pte);
- } else
- error = -ENOMEM;
- pte_unmap_nested(src);
- }
- if (dst)
- pte_unmap(dst);
+ /*
+ * We don't have to worry about the ordering of src and dst
+ * pte locks because exclusive mmap_sem prevents deadlock.
+ */
+ old_pte = pte_offset_map_lock(mm, old_pmd, old_addr, &old_ptl);
+ new_pte = pte_offset_map_nested(new_pmd, new_addr);
+ new_ptl = pte_lockptr(mm, new_pmd);
+ if (new_ptl != old_ptl)
+ spin_lock(new_ptl);
+
+ for (; old_addr < old_end; old_pte++, old_addr += PAGE_SIZE,
+ new_pte++, new_addr += PAGE_SIZE) {
+ if (pte_none(*old_pte))
+ continue;
+ pte = ptep_clear_flush(vma, old_addr, old_pte);
+ /* ZERO_PAGE can be dependant on virtual addr */
+ pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
+ set_pte_at(mm, new_addr, new_pte, pte);
}
- spin_unlock(&mm->page_table_lock);
+
+ if (new_ptl != old_ptl)
+ spin_unlock(new_ptl);
+ pte_unmap_nested(new_pte - 1);
+ pte_unmap_unlock(old_pte - 1, old_ptl);
if (mapping)
spin_unlock(&mapping->i_mmap_lock);
- return error;
}
+#define LATENCY_LIMIT (64 * PAGE_SIZE)
+
static unsigned long move_page_tables(struct vm_area_struct *vma,
unsigned long old_addr, struct vm_area_struct *new_vma,
unsigned long new_addr, unsigned long len)
{
- unsigned long offset;
+ unsigned long extent, next, old_end;
+ pmd_t *old_pmd, *new_pmd;
- flush_cache_range(vma, old_addr, old_addr + len);
+ old_end = old_addr + len;
+ flush_cache_range(vma, old_addr, old_end);
- /*
- * This is not the clever way to do this, but we're taking the
- * easy way out on the assumption that most remappings will be
- * only a few pages.. This also makes error recovery easier.
- */
- for (offset = 0; offset < len; offset += PAGE_SIZE) {
- if (move_one_page(vma, old_addr + offset,
- new_vma, new_addr + offset) < 0)
- break;
+ for (; old_addr < old_end; old_addr += extent, new_addr += extent) {
cond_resched();
+ next = (old_addr + PMD_SIZE) & PMD_MASK;
+ if (next - 1 > old_end)
+ next = old_end;
+ extent = next - old_addr;
+ old_pmd = get_old_pmd(vma->vm_mm, old_addr);
+ if (!old_pmd)
+ continue;
+ new_pmd = alloc_new_pmd(vma->vm_mm, new_addr);
+ if (!new_pmd)
+ break;
+ next = (new_addr + PMD_SIZE) & PMD_MASK;
+ if (extent > next - new_addr)
+ extent = next - new_addr;
+ if (extent > LATENCY_LIMIT)
+ extent = LATENCY_LIMIT;
+ move_ptes(vma, old_pmd, old_addr, old_addr + extent,
+ new_vma, new_pmd, new_addr);
}
- return offset;
+
+ return len + old_addr - old_end; /* how much done */
}
static unsigned long move_vma(struct vm_area_struct *vma,
@@ -191,6 +162,7 @@ static unsigned long move_vma(struct vm_area_struct *vma,
unsigned long new_pgoff;
unsigned long moved_len;
unsigned long excess = 0;
+ unsigned long hiwater_vm;
int split = 0;
/*
@@ -229,17 +201,24 @@ static unsigned long move_vma(struct vm_area_struct *vma,
}
/*
- * if we failed to move page tables we still do total_vm increment
- * since do_munmap() will decrement it by old_len == new_len
+ * If we failed to move page tables we still do total_vm increment
+ * since do_munmap() will decrement it by old_len == new_len.
+ *
+ * Since total_vm is about to be raised artificially high for a
+ * moment, we need to restore high watermark afterwards: if stats
+ * are taken meanwhile, total_vm and hiwater_vm appear too high.
+ * If this were a serious issue, we'd add a flag to do_munmap().
*/
+ hiwater_vm = mm->hiwater_vm;
mm->total_vm += new_len >> PAGE_SHIFT;
- __vm_stat_account(mm, vma->vm_flags, vma->vm_file, new_len>>PAGE_SHIFT);
+ vm_stat_account(mm, vma->vm_flags, vma->vm_file, new_len>>PAGE_SHIFT);
if (do_munmap(mm, old_addr, old_len) < 0) {
/* OOM: unable to split vma, just get accounts right */
vm_unacct_memory(excess >> PAGE_SHIFT);
excess = 0;
}
+ mm->hiwater_vm = hiwater_vm;
/* Restore VM_ACCOUNT if one or two pieces of vma left */
if (excess) {
@@ -269,6 +248,7 @@ unsigned long do_mremap(unsigned long addr,
unsigned long old_len, unsigned long new_len,
unsigned long flags, unsigned long new_addr)
{
+ struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
unsigned long ret = -EINVAL;
unsigned long charged = 0;
@@ -309,7 +289,7 @@ unsigned long do_mremap(unsigned long addr,
if ((addr <= new_addr) && (addr+old_len) > new_addr)
goto out;
- ret = do_munmap(current->mm, new_addr, new_len);
+ ret = do_munmap(mm, new_addr, new_len);
if (ret)
goto out;
}
@@ -320,7 +300,7 @@ unsigned long do_mremap(unsigned long addr,
* do_munmap does all the needed commit accounting
*/
if (old_len >= new_len) {
- ret = do_munmap(current->mm, addr+new_len, old_len - new_len);
+ ret = do_munmap(mm, addr+new_len, old_len - new_len);
if (ret && old_len != new_len)
goto out;
ret = addr;
@@ -333,7 +313,7 @@ unsigned long do_mremap(unsigned long addr,
* Ok, we need to grow.. or relocate.
*/
ret = -EFAULT;
- vma = find_vma(current->mm, addr);
+ vma = find_vma(mm, addr);
if (!vma || vma->vm_start > addr)
goto out;
if (is_vm_hugetlb_page(vma)) {
@@ -349,14 +329,14 @@ unsigned long do_mremap(unsigned long addr,
}
if (vma->vm_flags & VM_LOCKED) {
unsigned long locked, lock_limit;
- locked = current->mm->locked_vm << PAGE_SHIFT;
+ locked = mm->locked_vm << PAGE_SHIFT;
lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
locked += new_len - old_len;
ret = -EAGAIN;
if (locked > lock_limit && !capable(CAP_IPC_LOCK))
goto out;
}
- if (!may_expand_vm(current->mm, (new_len - old_len) >> PAGE_SHIFT)) {
+ if (!may_expand_vm(mm, (new_len - old_len) >> PAGE_SHIFT)) {
ret = -ENOMEM;
goto out;
}
@@ -383,11 +363,10 @@ unsigned long do_mremap(unsigned long addr,
vma_adjust(vma, vma->vm_start,
addr + new_len, vma->vm_pgoff, NULL);
- current->mm->total_vm += pages;
- __vm_stat_account(vma->vm_mm, vma->vm_flags,
- vma->vm_file, pages);
+ mm->total_vm += pages;
+ vm_stat_account(mm, vma->vm_flags, vma->vm_file, pages);
if (vma->vm_flags & VM_LOCKED) {
- current->mm->locked_vm += pages;
+ mm->locked_vm += pages;
make_pages_present(addr + old_len,
addr + new_len);
}
diff --git a/mm/msync.c b/mm/msync.c
index d0f5a1bce7cb..0e040e9c39d8 100644
--- a/mm/msync.c
+++ b/mm/msync.c
@@ -17,40 +17,48 @@
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
-/*
- * Called with mm->page_table_lock held to protect against other
- * threads/the swapper from ripping pte's out from under us.
- */
-
-static void sync_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
+static void msync_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
unsigned long addr, unsigned long end)
{
pte_t *pte;
+ spinlock_t *ptl;
+ int progress = 0;
- pte = pte_offset_map(pmd, addr);
+again:
+ pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
do {
unsigned long pfn;
struct page *page;
+ if (progress >= 64) {
+ progress = 0;
+ if (need_resched() || need_lockbreak(ptl))
+ break;
+ }
+ progress++;
if (!pte_present(*pte))
continue;
if (!pte_maybe_dirty(*pte))
continue;
pfn = pte_pfn(*pte);
- if (!pfn_valid(pfn))
+ if (unlikely(!pfn_valid(pfn))) {
+ print_bad_pte(vma, *pte, addr);
continue;
+ }
page = pfn_to_page(pfn);
- if (PageReserved(page))
- continue;
if (ptep_clear_flush_dirty(vma, addr, pte) ||
page_test_and_clear_dirty(page))
set_page_dirty(page);
+ progress += 3;
} while (pte++, addr += PAGE_SIZE, addr != end);
- pte_unmap(pte - 1);
+ pte_unmap_unlock(pte - 1, ptl);
+ cond_resched();
+ if (addr != end)
+ goto again;
}
-static inline void sync_pmd_range(struct vm_area_struct *vma, pud_t *pud,
+static inline void msync_pmd_range(struct vm_area_struct *vma, pud_t *pud,
unsigned long addr, unsigned long end)
{
pmd_t *pmd;
@@ -61,11 +69,11 @@ static inline void sync_pmd_range(struct vm_area_struct *vma, pud_t *pud,
next = pmd_addr_end(addr, end);
if (pmd_none_or_clear_bad(pmd))
continue;
- sync_pte_range(vma, pmd, addr, next);
+ msync_pte_range(vma, pmd, addr, next);
} while (pmd++, addr = next, addr != end);
}
-static inline void sync_pud_range(struct vm_area_struct *vma, pgd_t *pgd,
+static inline void msync_pud_range(struct vm_area_struct *vma, pgd_t *pgd,
unsigned long addr, unsigned long end)
{
pud_t *pud;
@@ -76,58 +84,34 @@ static inline void sync_pud_range(struct vm_area_struct *vma, pgd_t *pgd,
next = pud_addr_end(addr, end);
if (pud_none_or_clear_bad(pud))
continue;
- sync_pmd_range(vma, pud, addr, next);
+ msync_pmd_range(vma, pud, addr, next);
} while (pud++, addr = next, addr != end);
}
-static void sync_page_range(struct vm_area_struct *vma,
+static void msync_page_range(struct vm_area_struct *vma,
unsigned long addr, unsigned long end)
{
- struct mm_struct *mm = vma->vm_mm;
pgd_t *pgd;
unsigned long next;
/* For hugepages we can't go walking the page table normally,
* but that's ok, hugetlbfs is memory based, so we don't need
- * to do anything more on an msync() */
- if (is_vm_hugetlb_page(vma))
+ * to do anything more on an msync().
+ * Can't do anything with VM_RESERVED regions either.
+ */
+ if (vma->vm_flags & (VM_HUGETLB|VM_RESERVED))
return;
BUG_ON(addr >= end);
- pgd = pgd_offset(mm, addr);
+ pgd = pgd_offset(vma->vm_mm, addr);
flush_cache_range(vma, addr, end);
- spin_lock(&mm->page_table_lock);
do {
next = pgd_addr_end(addr, end);
if (pgd_none_or_clear_bad(pgd))
continue;
- sync_pud_range(vma, pgd, addr, next);
+ msync_pud_range(vma, pgd, addr, next);
} while (pgd++, addr = next, addr != end);
- spin_unlock(&mm->page_table_lock);
-}
-
-#ifdef CONFIG_PREEMPT
-static inline void filemap_sync(struct vm_area_struct *vma,
- unsigned long addr, unsigned long end)
-{
- const size_t chunk = 64 * 1024; /* bytes */
- unsigned long next;
-
- do {
- next = addr + chunk;
- if (next > end || next < addr)
- next = end;
- sync_page_range(vma, addr, next);
- cond_resched();
- } while (addr = next, addr != end);
-}
-#else
-static inline void filemap_sync(struct vm_area_struct *vma,
- unsigned long addr, unsigned long end)
-{
- sync_page_range(vma, addr, end);
}
-#endif
/*
* MS_SYNC syncs the entire file - including mappings.
@@ -150,7 +134,7 @@ static int msync_interval(struct vm_area_struct *vma,
return -EBUSY;
if (file && (vma->vm_flags & VM_SHARED)) {
- filemap_sync(vma, addr, end);
+ msync_page_range(vma, addr, end);
if (flags & MS_SYNC) {
struct address_space *mapping = file->f_mapping;
diff --git a/mm/nommu.c b/mm/nommu.c
index 0ef241ae3763..d1e076a487cb 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -931,6 +931,8 @@ int do_munmap(struct mm_struct *mm, unsigned long addr, size_t len)
realalloc -= kobjsize(vml);
askedalloc -= sizeof(*vml);
kfree(vml);
+
+ update_hiwater_vm(mm);
mm->total_vm -= len >> PAGE_SHIFT;
#ifdef DEBUG
@@ -1047,7 +1049,8 @@ struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
EXPORT_SYMBOL(find_vma);
-struct page * follow_page(struct mm_struct *mm, unsigned long addr, int write)
+struct page *follow_page(struct mm_struct *mm, unsigned long address,
+ unsigned int foll_flags)
{
return NULL;
}
@@ -1078,19 +1081,6 @@ void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
{
}
-void update_mem_hiwater(struct task_struct *tsk)
-{
- unsigned long rss;
-
- if (likely(tsk->mm)) {
- rss = get_mm_counter(tsk->mm, rss);
- if (tsk->mm->hiwater_rss < rss)
- tsk->mm->hiwater_rss = rss;
- if (tsk->mm->hiwater_vm < tsk->mm->total_vm)
- tsk->mm->hiwater_vm = tsk->mm->total_vm;
- }
-}
-
void unmap_mapping_range(struct address_space *mapping,
loff_t const holebegin, loff_t const holelen,
int even_cows)
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 94c864eac9c4..2dbdd98426fd 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -33,6 +33,7 @@
#include <linux/sysctl.h>
#include <linux/cpu.h>
#include <linux/cpuset.h>
+#include <linux/memory_hotplug.h>
#include <linux/nodemask.h>
#include <linux/vmalloc.h>
@@ -78,21 +79,44 @@ int min_free_kbytes = 1024;
unsigned long __initdata nr_kernel_pages;
unsigned long __initdata nr_all_pages;
+static int page_outside_zone_boundaries(struct zone *zone, struct page *page)
+{
+ int ret = 0;
+ unsigned seq;
+ unsigned long pfn = page_to_pfn(page);
+
+ do {
+ seq = zone_span_seqbegin(zone);
+ if (pfn >= zone->zone_start_pfn + zone->spanned_pages)
+ ret = 1;
+ else if (pfn < zone->zone_start_pfn)
+ ret = 1;
+ } while (zone_span_seqretry(zone, seq));
+
+ return ret;
+}
+
+static int page_is_consistent(struct zone *zone, struct page *page)
+{
+#ifdef CONFIG_HOLES_IN_ZONE
+ if (!pfn_valid(page_to_pfn(page)))
+ return 0;
+#endif
+ if (zone != page_zone(page))
+ return 0;
+
+ return 1;
+}
/*
* Temporary debugging check for pages not lying within a given zone.
*/
static int bad_range(struct zone *zone, struct page *page)
{
- if (page_to_pfn(page) >= zone->zone_start_pfn + zone->spanned_pages)
+ if (page_outside_zone_boundaries(zone, page))
return 1;
- if (page_to_pfn(page) < zone->zone_start_pfn)
- return 1;
-#ifdef CONFIG_HOLES_IN_ZONE
- if (!pfn_valid(page_to_pfn(page)))
- return 1;
-#endif
- if (zone != page_zone(page))
+ if (!page_is_consistent(zone, page))
return 1;
+
return 0;
}
@@ -114,7 +138,8 @@ static void bad_page(const char *function, struct page *page)
1 << PG_reclaim |
1 << PG_slab |
1 << PG_swapcache |
- 1 << PG_writeback);
+ 1 << PG_writeback |
+ 1 << PG_reserved );
set_page_count(page, 0);
reset_page_mapcount(page);
page->mapping = NULL;
@@ -153,7 +178,7 @@ static void prep_compound_page(struct page *page, unsigned long order)
struct page *p = page + i;
SetPageCompound(p);
- p->private = (unsigned long)page;
+ set_page_private(p, (unsigned long)page);
}
}
@@ -173,7 +198,7 @@ static void destroy_compound_page(struct page *page, unsigned long order)
if (!PageCompound(p))
bad_page(__FUNCTION__, page);
- if (p->private != (unsigned long)page)
+ if (page_private(p) != (unsigned long)page)
bad_page(__FUNCTION__, page);
ClearPageCompound(p);
}
@@ -186,18 +211,18 @@ static void destroy_compound_page(struct page *page, unsigned long order)
* So, we don't need atomic page->flags operations here.
*/
static inline unsigned long page_order(struct page *page) {
- return page->private;
+ return page_private(page);
}
static inline void set_page_order(struct page *page, int order) {
- page->private = order;
+ set_page_private(page, order);
__SetPagePrivate(page);
}
static inline void rmv_page_order(struct page *page)
{
__ClearPagePrivate(page);
- page->private = 0;
+ set_page_private(page, 0);
}
/*
@@ -237,14 +262,13 @@ __find_combined_index(unsigned long page_idx, unsigned int order)
* (a) the buddy is free &&
* (b) the buddy is on the buddy system &&
* (c) a page and its buddy have the same order.
- * for recording page's order, we use page->private and PG_private.
+ * for recording page's order, we use page_private(page) and PG_private.
*
*/
static inline int page_is_buddy(struct page *page, int order)
{
if (PagePrivate(page) &&
(page_order(page) == order) &&
- !PageReserved(page) &&
page_count(page) == 0)
return 1;
return 0;
@@ -264,7 +288,7 @@ static inline int page_is_buddy(struct page *page, int order)
* parts of the VM system.
* At each level, we keep a list of pages, which are heads of continuous
* free pages of length of (1 << order) and marked with PG_Private.Page's
- * order is recorded in page->private field.
+ * order is recorded in page_private(page) field.
* So when we are allocating or freeing one, we can derive the state of the
* other. That is, if we allocate a small block, and both were
* free, the remainder of the region must be split into blocks.
@@ -327,7 +351,8 @@ static inline void free_pages_check(const char *function, struct page *page)
1 << PG_reclaim |
1 << PG_slab |
1 << PG_swapcache |
- 1 << PG_writeback )))
+ 1 << PG_writeback |
+ 1 << PG_reserved )))
bad_page(function, page);
if (PageDirty(page))
__ClearPageDirty(page);
@@ -455,13 +480,14 @@ static void prep_new_page(struct page *page, int order)
1 << PG_reclaim |
1 << PG_slab |
1 << PG_swapcache |
- 1 << PG_writeback )))
+ 1 << PG_writeback |
+ 1 << PG_reserved )))
bad_page(__FUNCTION__, page);
page->flags &= ~(1 << PG_uptodate | 1 << PG_error |
1 << PG_referenced | 1 << PG_arch_1 |
1 << PG_checked | 1 << PG_mappedtodisk);
- page->private = 0;
+ set_page_private(page, 0);
set_page_refs(page, order);
kernel_map_pages(page, 1 << order, 1);
}
@@ -1016,7 +1042,7 @@ void __pagevec_free(struct pagevec *pvec)
fastcall void __free_pages(struct page *page, unsigned int order)
{
- if (!PageReserved(page) && put_page_testzero(page)) {
+ if (put_page_testzero(page)) {
if (order == 0)
free_hot_page(page);
else
@@ -1305,12 +1331,9 @@ void show_free_areas(void)
} else
printk("\n");
- for (cpu = 0; cpu < NR_CPUS; ++cpu) {
+ for_each_cpu(cpu) {
struct per_cpu_pageset *pageset;
- if (!cpu_possible(cpu))
- continue;
-
pageset = zone_pcp(zone, cpu);
for (temperature = 0; temperature < 2; temperature++)
@@ -1660,7 +1683,7 @@ static void __init calculate_zone_totalpages(struct pglist_data *pgdat,
* up by free_all_bootmem() once the early boot process is
* done. Non-atomic initialization, single-pass.
*/
-void __init memmap_init_zone(unsigned long size, int nid, unsigned long zone,
+void __devinit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
unsigned long start_pfn)
{
struct page *page;
@@ -1674,7 +1697,7 @@ void __init memmap_init_zone(unsigned long size, int nid, unsigned long zone,
continue;
page = pfn_to_page(pfn);
set_page_links(page, zone, nid, pfn);
- set_page_count(page, 0);
+ set_page_count(page, 1);
reset_page_mapcount(page);
SetPageReserved(page);
INIT_LIST_HEAD(&page->lru);
@@ -1721,29 +1744,29 @@ static int __devinit zone_batchsize(struct zone *zone)
/*
* The per-cpu-pages pools are set to around 1000th of the
- * size of the zone. But no more than 1/4 of a meg - there's
- * no point in going beyond the size of L2 cache.
+ * size of the zone. But no more than 1/2 of a meg.
*
* OK, so we don't know how big the cache is. So guess.
*/
batch = zone->present_pages / 1024;
- if (batch * PAGE_SIZE > 256 * 1024)
- batch = (256 * 1024) / PAGE_SIZE;
+ if (batch * PAGE_SIZE > 512 * 1024)
+ batch = (512 * 1024) / PAGE_SIZE;
batch /= 4; /* We effectively *= 4 below */
if (batch < 1)
batch = 1;
/*
- * Clamp the batch to a 2^n - 1 value. Having a power
- * of 2 value was found to be more likely to have
- * suboptimal cache aliasing properties in some cases.
+ * We will be trying to allcoate bigger chunks of contiguous
+ * memory of the order of fls(batch). This should result in
+ * better cache coloring.
*
- * For example if 2 tasks are alternately allocating
- * batches of pages, one task can end up with a lot
- * of pages of one half of the possible page colors
- * and the other with pages of the other colors.
+ * A sanity check also to ensure that batch is still in limits.
*/
- batch = (1 << fls(batch + batch/2)) - 1;
+ batch = (1 << fls(batch + batch/2));
+
+ if (fls(batch) >= (PAGE_SHIFT + MAX_ORDER - 2))
+ batch = PAGE_SHIFT + ((MAX_ORDER - 1 - PAGE_SHIFT)/2);
+
return batch;
}
@@ -1755,7 +1778,7 @@ inline void setup_pageset(struct per_cpu_pageset *p, unsigned long batch)
pcp = &p->pcp[0]; /* hot */
pcp->count = 0;
- pcp->low = 2 * batch;
+ pcp->low = 0;
pcp->high = 6 * batch;
pcp->batch = max(1UL, 1 * batch);
INIT_LIST_HEAD(&pcp->list);
@@ -1764,7 +1787,7 @@ inline void setup_pageset(struct per_cpu_pageset *p, unsigned long batch)
pcp->count = 0;
pcp->low = 0;
pcp->high = 2 * batch;
- pcp->batch = max(1UL, 1 * batch);
+ pcp->batch = max(1UL, batch/2);
INIT_LIST_HEAD(&pcp->list);
}
@@ -1873,6 +1896,60 @@ void __init setup_per_cpu_pageset()
#endif
+static __devinit
+void zone_wait_table_init(struct zone *zone, unsigned long zone_size_pages)
+{
+ int i;
+ struct pglist_data *pgdat = zone->zone_pgdat;
+
+ /*
+ * The per-page waitqueue mechanism uses hashed waitqueues
+ * per zone.
+ */
+ zone->wait_table_size = wait_table_size(zone_size_pages);
+ zone->wait_table_bits = wait_table_bits(zone->wait_table_size);
+ zone->wait_table = (wait_queue_head_t *)
+ alloc_bootmem_node(pgdat, zone->wait_table_size
+ * sizeof(wait_queue_head_t));
+
+ for(i = 0; i < zone->wait_table_size; ++i)
+ init_waitqueue_head(zone->wait_table + i);
+}
+
+static __devinit void zone_pcp_init(struct zone *zone)
+{
+ int cpu;
+ unsigned long batch = zone_batchsize(zone);
+
+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
+#ifdef CONFIG_NUMA
+ /* Early boot. Slab allocator not functional yet */
+ zone->pageset[cpu] = &boot_pageset[cpu];
+ setup_pageset(&boot_pageset[cpu],0);
+#else
+ setup_pageset(zone_pcp(zone,cpu), batch);
+#endif
+ }
+ printk(KERN_DEBUG " %s zone: %lu pages, LIFO batch:%lu\n",
+ zone->name, zone->present_pages, batch);
+}
+
+static __devinit void init_currently_empty_zone(struct zone *zone,
+ unsigned long zone_start_pfn, unsigned long size)
+{
+ struct pglist_data *pgdat = zone->zone_pgdat;
+
+ zone_wait_table_init(zone, size);
+ pgdat->nr_zones = zone_idx(zone) + 1;
+
+ zone->zone_mem_map = pfn_to_page(zone_start_pfn);
+ zone->zone_start_pfn = zone_start_pfn;
+
+ memmap_init(size, pgdat->node_id, zone_idx(zone), zone_start_pfn);
+
+ zone_init_free_lists(pgdat, zone, zone->spanned_pages);
+}
+
/*
* Set up the zone data structures:
* - mark all pages reserved
@@ -1882,10 +1959,11 @@ void __init setup_per_cpu_pageset()
static void __init free_area_init_core(struct pglist_data *pgdat,
unsigned long *zones_size, unsigned long *zholes_size)
{
- unsigned long i, j;
- int cpu, nid = pgdat->node_id;
+ unsigned long j;
+ int nid = pgdat->node_id;
unsigned long zone_start_pfn = pgdat->node_start_pfn;
+ pgdat_resize_init(pgdat);
pgdat->nr_zones = 0;
init_waitqueue_head(&pgdat->kswapd_wait);
pgdat->kswapd_max_order = 0;
@@ -1893,7 +1971,6 @@ static void __init free_area_init_core(struct pglist_data *pgdat,
for (j = 0; j < MAX_NR_ZONES; j++) {
struct zone *zone = pgdat->node_zones + j;
unsigned long size, realsize;
- unsigned long batch;
realsize = size = zones_size[j];
if (zholes_size)
@@ -1908,24 +1985,13 @@ static void __init free_area_init_core(struct pglist_data *pgdat,
zone->name = zone_names[j];
spin_lock_init(&zone->lock);
spin_lock_init(&zone->lru_lock);
+ zone_seqlock_init(zone);
zone->zone_pgdat = pgdat;
zone->free_pages = 0;
zone->temp_priority = zone->prev_priority = DEF_PRIORITY;
- batch = zone_batchsize(zone);
-
- for (cpu = 0; cpu < NR_CPUS; cpu++) {
-#ifdef CONFIG_NUMA
- /* Early boot. Slab allocator not functional yet */
- zone->pageset[cpu] = &boot_pageset[cpu];
- setup_pageset(&boot_pageset[cpu],0);
-#else
- setup_pageset(zone_pcp(zone,cpu), batch);
-#endif
- }
- printk(KERN_DEBUG " %s zone: %lu pages, LIFO batch:%lu\n",
- zone_names[j], realsize, batch);
+ zone_pcp_init(zone);
INIT_LIST_HEAD(&zone->active_list);
INIT_LIST_HEAD(&zone->inactive_list);
zone->nr_scan_active = 0;
@@ -1936,32 +2002,9 @@ static void __init free_area_init_core(struct pglist_data *pgdat,
if (!size)
continue;
- /*
- * The per-page waitqueue mechanism uses hashed waitqueues
- * per zone.
- */
- zone->wait_table_size = wait_table_size(size);
- zone->wait_table_bits =
- wait_table_bits(zone->wait_table_size);
- zone->wait_table = (wait_queue_head_t *)
- alloc_bootmem_node(pgdat, zone->wait_table_size
- * sizeof(wait_queue_head_t));
-
- for(i = 0; i < zone->wait_table_size; ++i)
- init_waitqueue_head(zone->wait_table + i);
-
- pgdat->nr_zones = j+1;
-
- zone->zone_mem_map = pfn_to_page(zone_start_pfn);
- zone->zone_start_pfn = zone_start_pfn;
-
- memmap_init(size, nid, j, zone_start_pfn);
-
zonetable_add(zone, nid, j, zone_start_pfn, size);
-
+ init_currently_empty_zone(zone, zone_start_pfn, size);
zone_start_pfn += size;
-
- zone_init_free_lists(pgdat, zone, zone->spanned_pages);
}
}
@@ -2361,7 +2404,7 @@ static void setup_per_zone_lowmem_reserve(void)
* that the pages_{min,low,high} values for each zone are set correctly
* with respect to min_free_kbytes.
*/
-static void setup_per_zone_pages_min(void)
+void setup_per_zone_pages_min(void)
{
unsigned long pages_min = min_free_kbytes >> (PAGE_SHIFT - 10);
unsigned long lowmem_pages = 0;
diff --git a/mm/page_io.c b/mm/page_io.c
index 330e00d6db00..bb2b0d53889c 100644
--- a/mm/page_io.c
+++ b/mm/page_io.c
@@ -91,7 +91,8 @@ int swap_writepage(struct page *page, struct writeback_control *wbc)
unlock_page(page);
goto out;
}
- bio = get_swap_bio(GFP_NOIO, page->private, page, end_swap_bio_write);
+ bio = get_swap_bio(GFP_NOIO, page_private(page), page,
+ end_swap_bio_write);
if (bio == NULL) {
set_page_dirty(page);
unlock_page(page);
@@ -115,7 +116,8 @@ int swap_readpage(struct file *file, struct page *page)
BUG_ON(!PageLocked(page));
ClearPageUptodate(page);
- bio = get_swap_bio(GFP_KERNEL, page->private, page, end_swap_bio_read);
+ bio = get_swap_bio(GFP_KERNEL, page_private(page), page,
+ end_swap_bio_read);
if (bio == NULL) {
unlock_page(page);
ret = -ENOMEM;
diff --git a/mm/pdflush.c b/mm/pdflush.c
index d6781951267e..52822c98c489 100644
--- a/mm/pdflush.c
+++ b/mm/pdflush.c
@@ -20,6 +20,7 @@
#include <linux/fs.h> // Needed by writeback.h
#include <linux/writeback.h> // Prototypes pdflush_operation()
#include <linux/kthread.h>
+#include <linux/cpuset.h>
/*
@@ -170,12 +171,24 @@ static int __pdflush(struct pdflush_work *my_work)
static int pdflush(void *dummy)
{
struct pdflush_work my_work;
+ cpumask_t cpus_allowed;
/*
* pdflush can spend a lot of time doing encryption via dm-crypt. We
* don't want to do that at keventd's priority.
*/
set_user_nice(current, 0);
+
+ /*
+ * Some configs put our parent kthread in a limited cpuset,
+ * which kthread() overrides, forcing cpus_allowed == CPU_MASK_ALL.
+ * Our needs are more modest - cut back to our cpusets cpus_allowed.
+ * This is needed as pdflush's are dynamically created and destroyed.
+ * The boottime pdflush's are easily placed w/o these 2 lines.
+ */
+ cpus_allowed = cpuset_cpus_allowed(current);
+ set_cpus_allowed(current, cpus_allowed);
+
return __pdflush(&my_work);
}
diff --git a/mm/rmap.c b/mm/rmap.c
index 450f5241b5a5..914d04b98bee 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -32,7 +32,7 @@
* page->flags PG_locked (lock_page)
* mapping->i_mmap_lock
* anon_vma->lock
- * mm->page_table_lock
+ * mm->page_table_lock or pte_lock
* zone->lru_lock (in mark_page_accessed)
* swap_lock (in swap_duplicate, swap_info_get)
* mmlist_lock (in mmput, drain_mmlist and others)
@@ -244,37 +244,44 @@ unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma)
/*
* Check that @page is mapped at @address into @mm.
*
- * On success returns with mapped pte and locked mm->page_table_lock.
+ * On success returns with pte mapped and locked.
*/
pte_t *page_check_address(struct page *page, struct mm_struct *mm,
- unsigned long address)
+ unsigned long address, spinlock_t **ptlp)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
+ spinlock_t *ptl;
- /*
- * We need the page_table_lock to protect us from page faults,
- * munmap, fork, etc...
- */
- spin_lock(&mm->page_table_lock);
pgd = pgd_offset(mm, address);
- if (likely(pgd_present(*pgd))) {
- pud = pud_offset(pgd, address);
- if (likely(pud_present(*pud))) {
- pmd = pmd_offset(pud, address);
- if (likely(pmd_present(*pmd))) {
- pte = pte_offset_map(pmd, address);
- if (likely(pte_present(*pte) &&
- page_to_pfn(page) == pte_pfn(*pte)))
- return pte;
- pte_unmap(pte);
- }
- }
+ if (!pgd_present(*pgd))
+ return NULL;
+
+ pud = pud_offset(pgd, address);
+ if (!pud_present(*pud))
+ return NULL;
+
+ pmd = pmd_offset(pud, address);
+ if (!pmd_present(*pmd))
+ return NULL;
+
+ pte = pte_offset_map(pmd, address);
+ /* Make a quick check before getting the lock */
+ if (!pte_present(*pte)) {
+ pte_unmap(pte);
+ return NULL;
+ }
+
+ ptl = pte_lockptr(mm, pmd);
+ spin_lock(ptl);
+ if (pte_present(*pte) && page_to_pfn(page) == pte_pfn(*pte)) {
+ *ptlp = ptl;
+ return pte;
}
- spin_unlock(&mm->page_table_lock);
- return ERR_PTR(-ENOENT);
+ pte_unmap_unlock(pte, ptl);
+ return NULL;
}
/*
@@ -287,24 +294,28 @@ static int page_referenced_one(struct page *page,
struct mm_struct *mm = vma->vm_mm;
unsigned long address;
pte_t *pte;
+ spinlock_t *ptl;
int referenced = 0;
address = vma_address(page, vma);
if (address == -EFAULT)
goto out;
- pte = page_check_address(page, mm, address);
- if (!IS_ERR(pte)) {
- if (ptep_clear_flush_young(vma, address, pte))
- referenced++;
+ pte = page_check_address(page, mm, address, &ptl);
+ if (!pte)
+ goto out;
- if (mm != current->mm && !ignore_token && has_swap_token(mm))
- referenced++;
+ if (ptep_clear_flush_young(vma, address, pte))
+ referenced++;
- (*mapcount)--;
- pte_unmap(pte);
- spin_unlock(&mm->page_table_lock);
- }
+ /* Pretend the page is referenced if the task has the
+ swap token and is in the middle of a page fault. */
+ if (mm != current->mm && !ignore_token && has_swap_token(mm) &&
+ rwsem_is_locked(&mm->mmap_sem))
+ referenced++;
+
+ (*mapcount)--;
+ pte_unmap_unlock(pte, ptl);
out:
return referenced;
}
@@ -434,15 +445,11 @@ int page_referenced(struct page *page, int is_locked, int ignore_token)
* @vma: the vm area in which the mapping is added
* @address: the user virtual address mapped
*
- * The caller needs to hold the mm->page_table_lock.
+ * The caller needs to hold the pte lock.
*/
void page_add_anon_rmap(struct page *page,
struct vm_area_struct *vma, unsigned long address)
{
- BUG_ON(PageReserved(page));
-
- inc_mm_counter(vma->vm_mm, anon_rss);
-
if (atomic_inc_and_test(&page->_mapcount)) {
struct anon_vma *anon_vma = vma->anon_vma;
@@ -461,13 +468,12 @@ void page_add_anon_rmap(struct page *page,
* page_add_file_rmap - add pte mapping to a file page
* @page: the page to add the mapping to
*
- * The caller needs to hold the mm->page_table_lock.
+ * The caller needs to hold the pte lock.
*/
void page_add_file_rmap(struct page *page)
{
BUG_ON(PageAnon(page));
- if (!pfn_valid(page_to_pfn(page)) || PageReserved(page))
- return;
+ BUG_ON(!pfn_valid(page_to_pfn(page)));
if (atomic_inc_and_test(&page->_mapcount))
inc_page_state(nr_mapped);
@@ -477,12 +483,10 @@ void page_add_file_rmap(struct page *page)
* page_remove_rmap - take down pte mapping from a page
* @page: page to remove mapping from
*
- * Caller needs to hold the mm->page_table_lock.
+ * The caller needs to hold the pte lock.
*/
void page_remove_rmap(struct page *page)
{
- BUG_ON(PageReserved(page));
-
if (atomic_add_negative(-1, &page->_mapcount)) {
BUG_ON(page_mapcount(page) < 0);
/*
@@ -510,14 +514,15 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma)
unsigned long address;
pte_t *pte;
pte_t pteval;
+ spinlock_t *ptl;
int ret = SWAP_AGAIN;
address = vma_address(page, vma);
if (address == -EFAULT)
goto out;
- pte = page_check_address(page, mm, address);
- if (IS_ERR(pte))
+ pte = page_check_address(page, mm, address, &ptl);
+ if (!pte)
goto out;
/*
@@ -541,8 +546,11 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma)
if (pte_dirty(pteval))
set_page_dirty(page);
+ /* Update high watermark before we lower rss */
+ update_hiwater_rss(mm);
+
if (PageAnon(page)) {
- swp_entry_t entry = { .val = page->private };
+ swp_entry_t entry = { .val = page_private(page) };
/*
* Store the swap location in the pte.
* See handle_pte_fault() ...
@@ -551,21 +559,21 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma)
swap_duplicate(entry);
if (list_empty(&mm->mmlist)) {
spin_lock(&mmlist_lock);
- list_add(&mm->mmlist, &init_mm.mmlist);
+ if (list_empty(&mm->mmlist))
+ list_add(&mm->mmlist, &init_mm.mmlist);
spin_unlock(&mmlist_lock);
}
set_pte_at(mm, address, pte, swp_entry_to_pte(entry));
BUG_ON(pte_file(*pte));
dec_mm_counter(mm, anon_rss);
- }
+ } else
+ dec_mm_counter(mm, file_rss);
- dec_mm_counter(mm, rss);
page_remove_rmap(page);
page_cache_release(page);
out_unmap:
- pte_unmap(pte);
- spin_unlock(&mm->page_table_lock);
+ pte_unmap_unlock(pte, ptl);
out:
return ret;
}
@@ -599,19 +607,14 @@ static void try_to_unmap_cluster(unsigned long cursor,
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
- pte_t *pte, *original_pte;
+ pte_t *pte;
pte_t pteval;
+ spinlock_t *ptl;
struct page *page;
unsigned long address;
unsigned long end;
unsigned long pfn;
- /*
- * We need the page_table_lock to protect us from page faults,
- * munmap, fork, etc...
- */
- spin_lock(&mm->page_table_lock);
-
address = (vma->vm_start + cursor) & CLUSTER_MASK;
end = address + CLUSTER_SIZE;
if (address < vma->vm_start)
@@ -621,30 +624,33 @@ static void try_to_unmap_cluster(unsigned long cursor,
pgd = pgd_offset(mm, address);
if (!pgd_present(*pgd))
- goto out_unlock;
+ return;
pud = pud_offset(pgd, address);
if (!pud_present(*pud))
- goto out_unlock;
+ return;
pmd = pmd_offset(pud, address);
if (!pmd_present(*pmd))
- goto out_unlock;
+ return;
+
+ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
- for (original_pte = pte = pte_offset_map(pmd, address);
- address < end; pte++, address += PAGE_SIZE) {
+ /* Update high watermark before we lower rss */
+ update_hiwater_rss(mm);
+ for (; address < end; pte++, address += PAGE_SIZE) {
if (!pte_present(*pte))
continue;
pfn = pte_pfn(*pte);
- if (!pfn_valid(pfn))
+ if (unlikely(!pfn_valid(pfn))) {
+ print_bad_pte(vma, *pte, address);
continue;
+ }
page = pfn_to_page(pfn);
BUG_ON(PageAnon(page));
- if (PageReserved(page))
- continue;
if (ptep_clear_flush_young(vma, address, pte))
continue;
@@ -663,13 +669,10 @@ static void try_to_unmap_cluster(unsigned long cursor,
page_remove_rmap(page);
page_cache_release(page);
- dec_mm_counter(mm, rss);
+ dec_mm_counter(mm, file_rss);
(*mapcount)--;
}
-
- pte_unmap(original_pte);
-out_unlock:
- spin_unlock(&mm->page_table_lock);
+ pte_unmap_unlock(pte - 1, ptl);
}
static int try_to_unmap_anon(struct page *page)
@@ -806,7 +809,6 @@ int try_to_unmap(struct page *page)
{
int ret;
- BUG_ON(PageReserved(page));
BUG_ON(!PageLocked(page));
if (PageAnon(page))
diff --git a/mm/shmem.c b/mm/shmem.c
index 55e04a0734c1..dc25565a61e9 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -71,9 +71,6 @@
/* Pretend that each entry is of this size in directory's i_size */
#define BOGO_DIRENT_SIZE 20
-/* Keep swapped page count in private field of indirect struct page */
-#define nr_swapped private
-
/* Flag allocation requirements to shmem_getpage and shmem_swp_alloc */
enum sgp_type {
SGP_QUICK, /* don't try more than file page cache lookup */
@@ -324,8 +321,10 @@ static void shmem_swp_set(struct shmem_inode_info *info, swp_entry_t *entry, uns
entry->val = value;
info->swapped += incdec;
- if ((unsigned long)(entry - info->i_direct) >= SHMEM_NR_DIRECT)
- kmap_atomic_to_page(entry)->nr_swapped += incdec;
+ if ((unsigned long)(entry - info->i_direct) >= SHMEM_NR_DIRECT) {
+ struct page *page = kmap_atomic_to_page(entry);
+ set_page_private(page, page_private(page) + incdec);
+ }
}
/*
@@ -368,9 +367,8 @@ static swp_entry_t *shmem_swp_alloc(struct shmem_inode_info *info, unsigned long
spin_unlock(&info->lock);
page = shmem_dir_alloc(mapping_gfp_mask(inode->i_mapping) | __GFP_ZERO);
- if (page) {
- page->nr_swapped = 0;
- }
+ if (page)
+ set_page_private(page, 0);
spin_lock(&info->lock);
if (!page) {
@@ -561,7 +559,7 @@ static void shmem_truncate(struct inode *inode)
diroff = 0;
}
subdir = dir[diroff];
- if (subdir && subdir->nr_swapped) {
+ if (subdir && page_private(subdir)) {
size = limit - idx;
if (size > ENTRIES_PER_PAGE)
size = ENTRIES_PER_PAGE;
@@ -572,10 +570,10 @@ static void shmem_truncate(struct inode *inode)
nr_swaps_freed += freed;
if (offset)
spin_lock(&info->lock);
- subdir->nr_swapped -= freed;
+ set_page_private(subdir, page_private(subdir) - freed);
if (offset)
spin_unlock(&info->lock);
- BUG_ON(subdir->nr_swapped > offset);
+ BUG_ON(page_private(subdir) > offset);
}
if (offset)
offset = 0;
@@ -743,7 +741,7 @@ static int shmem_unuse_inode(struct shmem_inode_info *info, swp_entry_t entry, s
dir = shmem_dir_map(subdir);
}
subdir = *dir;
- if (subdir && subdir->nr_swapped) {
+ if (subdir && page_private(subdir)) {
ptr = shmem_swp_map(subdir);
size = limit - idx;
if (size > ENTRIES_PER_PAGE)
@@ -1201,7 +1199,7 @@ static int shmem_populate(struct vm_area_struct *vma,
page_cache_release(page);
return err;
}
- } else {
+ } else if (vma->vm_flags & VM_NONLINEAR) {
/* No page was found just because we can't read it in
* now (being here implies nonblock != 0), but the page
* may exist, so set the PTE to fault it in later. */
@@ -1506,8 +1504,10 @@ static void do_shmem_file_read(struct file *filp, loff_t *ppos, read_descriptor_
*/
if (!offset)
mark_page_accessed(page);
- } else
+ } else {
page = ZERO_PAGE(0);
+ page_cache_get(page);
+ }
/*
* Ok, we have the page, and it's up-to-date, so
diff --git a/mm/slab.c b/mm/slab.c
index d30423f167a2..22bfb0b2ac8b 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -2419,6 +2419,7 @@ retry:
next = slab_bufctl(slabp)[slabp->free];
#if DEBUG
slab_bufctl(slabp)[slabp->free] = BUFCTL_FREE;
+ WARN_ON(numa_node_id() != slabp->nodeid);
#endif
slabp->free = next;
}
@@ -2633,8 +2634,10 @@ static void free_block(kmem_cache_t *cachep, void **objpp, int nr_objects, int n
check_spinlock_acquired_node(cachep, node);
check_slabp(cachep, slabp);
-
#if DEBUG
+ /* Verify that the slab belongs to the intended node */
+ WARN_ON(slabp->nodeid != node);
+
if (slab_bufctl(slabp)[objnr] != BUFCTL_FREE) {
printk(KERN_ERR "slab: double free detected in cache "
"'%s', objp %p\n", cachep->name, objp);
diff --git a/mm/sparse.c b/mm/sparse.c
index 347249a4917a..72079b538e2d 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -5,8 +5,10 @@
#include <linux/mm.h>
#include <linux/mmzone.h>
#include <linux/bootmem.h>
+#include <linux/highmem.h>
#include <linux/module.h>
#include <linux/spinlock.h>
+#include <linux/vmalloc.h>
#include <asm/dma.h>
/*
@@ -72,6 +74,31 @@ static inline int sparse_index_init(unsigned long section_nr, int nid)
}
#endif
+/*
+ * Although written for the SPARSEMEM_EXTREME case, this happens
+ * to also work for the flat array case becase
+ * NR_SECTION_ROOTS==NR_MEM_SECTIONS.
+ */
+int __section_nr(struct mem_section* ms)
+{
+ unsigned long root_nr;
+ struct mem_section* root;
+
+ for (root_nr = 0;
+ root_nr < NR_MEM_SECTIONS;
+ root_nr += SECTIONS_PER_ROOT) {
+ root = __nr_to_section(root_nr);
+
+ if (!root)
+ continue;
+
+ if ((ms >= root) && (ms < (root + SECTIONS_PER_ROOT)))
+ break;
+ }
+
+ return (root_nr * SECTIONS_PER_ROOT) + (ms - root);
+}
+
/* Record a memory area against a node. */
void memory_present(int nid, unsigned long start, unsigned long end)
{
@@ -162,6 +189,45 @@ static struct page *sparse_early_mem_map_alloc(unsigned long pnum)
return NULL;
}
+static struct page *__kmalloc_section_memmap(unsigned long nr_pages)
+{
+ struct page *page, *ret;
+ unsigned long memmap_size = sizeof(struct page) * nr_pages;
+
+ page = alloc_pages(GFP_KERNEL, get_order(memmap_size));
+ if (page)
+ goto got_map_page;
+
+ ret = vmalloc(memmap_size);
+ if (ret)
+ goto got_map_ptr;
+
+ return NULL;
+got_map_page:
+ ret = (struct page *)pfn_to_kaddr(page_to_pfn(page));
+got_map_ptr:
+ memset(ret, 0, memmap_size);
+
+ return ret;
+}
+
+static int vaddr_in_vmalloc_area(void *addr)
+{
+ if (addr >= (void *)VMALLOC_START &&
+ addr < (void *)VMALLOC_END)
+ return 1;
+ return 0;
+}
+
+static void __kfree_section_memmap(struct page *memmap, unsigned long nr_pages)
+{
+ if (vaddr_in_vmalloc_area(memmap))
+ vfree(memmap);
+ else
+ free_pages((unsigned long)memmap,
+ get_order(sizeof(struct page) * nr_pages));
+}
+
/*
* Allocate the accumulated non-linear sections, allocate a mem_map
* for each and record the physical to section mapping.
@@ -187,14 +253,37 @@ void sparse_init(void)
* set. If this is <=0, then that means that the passed-in
* map was not consumed and must be freed.
*/
-int sparse_add_one_section(unsigned long start_pfn, int nr_pages, struct page *map)
+int sparse_add_one_section(struct zone *zone, unsigned long start_pfn,
+ int nr_pages)
{
- struct mem_section *ms = __pfn_to_section(start_pfn);
+ unsigned long section_nr = pfn_to_section_nr(start_pfn);
+ struct pglist_data *pgdat = zone->zone_pgdat;
+ struct mem_section *ms;
+ struct page *memmap;
+ unsigned long flags;
+ int ret;
- if (ms->section_mem_map & SECTION_MARKED_PRESENT)
- return -EEXIST;
+ /*
+ * no locking for this, because it does its own
+ * plus, it does a kmalloc
+ */
+ sparse_index_init(section_nr, pgdat->node_id);
+ memmap = __kmalloc_section_memmap(nr_pages);
+
+ pgdat_resize_lock(pgdat, &flags);
+ ms = __pfn_to_section(start_pfn);
+ if (ms->section_mem_map & SECTION_MARKED_PRESENT) {
+ ret = -EEXIST;
+ goto out;
+ }
ms->section_mem_map |= SECTION_MARKED_PRESENT;
- return sparse_init_one_section(ms, pfn_to_section_nr(start_pfn), map);
+ ret = sparse_init_one_section(ms, section_nr, memmap);
+
+ if (ret <= 0)
+ __kfree_section_memmap(memmap, nr_pages);
+out:
+ pgdat_resize_unlock(pgdat, &flags);
+ return ret;
}
diff --git a/mm/swap.c b/mm/swap.c
index 7771d2803f62..96387e20184a 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -39,7 +39,7 @@ int page_cluster;
void put_page(struct page *page)
{
if (unlikely(PageCompound(page))) {
- page = (struct page *)page->private;
+ page = (struct page *)page_private(page);
if (put_page_testzero(page)) {
void (*dtor)(struct page *page);
@@ -48,7 +48,7 @@ void put_page(struct page *page)
}
return;
}
- if (!PageReserved(page) && put_page_testzero(page))
+ if (put_page_testzero(page))
__page_cache_release(page);
}
EXPORT_SYMBOL(put_page);
@@ -215,7 +215,7 @@ void release_pages(struct page **pages, int nr, int cold)
struct page *page = pages[i];
struct zone *pagezone;
- if (PageReserved(page) || !put_page_testzero(page))
+ if (!put_page_testzero(page))
continue;
pagezone = page_zone(page);
@@ -270,7 +270,6 @@ void __pagevec_release_nonlru(struct pagevec *pvec)
struct pagevec pages_to_free;
pagevec_init(&pages_to_free, pvec->cold);
- pages_to_free.cold = pvec->cold;
for (i = 0; i < pagevec_count(pvec); i++) {
struct page *page = pvec->pages[i];
diff --git a/mm/swap_state.c b/mm/swap_state.c
index 132164f7d0a7..dfd9a46755b8 100644
--- a/mm/swap_state.c
+++ b/mm/swap_state.c
@@ -83,7 +83,7 @@ static int __add_to_swap_cache(struct page *page, swp_entry_t entry,
page_cache_get(page);
SetPageLocked(page);
SetPageSwapCache(page);
- page->private = entry.val;
+ set_page_private(page, entry.val);
total_swapcache_pages++;
pagecache_acct(1);
}
@@ -126,8 +126,8 @@ void __delete_from_swap_cache(struct page *page)
BUG_ON(PageWriteback(page));
BUG_ON(PagePrivate(page));
- radix_tree_delete(&swapper_space.page_tree, page->private);
- page->private = 0;
+ radix_tree_delete(&swapper_space.page_tree, page_private(page));
+ set_page_private(page, 0);
ClearPageSwapCache(page);
total_swapcache_pages--;
pagecache_acct(-1);
@@ -197,7 +197,7 @@ void delete_from_swap_cache(struct page *page)
{
swp_entry_t entry;
- entry.val = page->private;
+ entry.val = page_private(page);
write_lock_irq(&swapper_space.tree_lock);
__delete_from_swap_cache(page);
@@ -259,8 +259,7 @@ static inline void free_swap_cache(struct page *page)
/*
* Perform a free_page(), also freeing any swap cache associated with
- * this page if it is the last user of the page. Can not do a lock_page,
- * as we are holding the page_table_lock spinlock.
+ * this page if it is the last user of the page.
*/
void free_page_and_swap_cache(struct page *page)
{
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 1dcaeda039f4..8970c0b74194 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -61,7 +61,7 @@ void swap_unplug_io_fn(struct backing_dev_info *unused_bdi, struct page *page)
swp_entry_t entry;
down_read(&swap_unplug_sem);
- entry.val = page->private;
+ entry.val = page_private(page);
if (PageSwapCache(page)) {
struct block_device *bdev = swap_info[swp_type(entry)].bdev;
struct backing_dev_info *bdi;
@@ -69,8 +69,8 @@ void swap_unplug_io_fn(struct backing_dev_info *unused_bdi, struct page *page)
/*
* If the page is removed from swapcache from under us (with a
* racy try_to_unuse/swapoff) we need an additional reference
- * count to avoid reading garbage from page->private above. If
- * the WARN_ON triggers during a swapoff it maybe the race
+ * count to avoid reading garbage from page_private(page) above.
+ * If the WARN_ON triggers during a swapoff it maybe the race
* condition and it's harmless. However if it triggers without
* swapoff it signals a problem.
*/
@@ -294,7 +294,7 @@ static inline int page_swapcount(struct page *page)
struct swap_info_struct *p;
swp_entry_t entry;
- entry.val = page->private;
+ entry.val = page_private(page);
p = swap_info_get(entry);
if (p) {
/* Subtract the 1 for the swap cache itself */
@@ -339,7 +339,7 @@ int remove_exclusive_swap_page(struct page *page)
if (page_count(page) != 2) /* 2: us + cache */
return 0;
- entry.val = page->private;
+ entry.val = page_private(page);
p = swap_info_get(entry);
if (!p)
return 0;
@@ -398,17 +398,14 @@ void free_swap_and_cache(swp_entry_t entry)
}
/*
- * Always set the resulting pte to be nowrite (the same as COW pages
- * after one process has exited). We don't know just how many PTEs will
- * share this swap entry, so be cautious and let do_wp_page work out
- * what to do if a write is requested later.
- *
- * vma->vm_mm->page_table_lock is held.
+ * No need to decide whether this PTE shares the swap entry with others,
+ * just let do_wp_page work it out if a write is requested later - to
+ * force COW, vm_page_prot omits write permission from any private vma.
*/
static void unuse_pte(struct vm_area_struct *vma, pte_t *pte,
unsigned long addr, swp_entry_t entry, struct page *page)
{
- inc_mm_counter(vma->vm_mm, rss);
+ inc_mm_counter(vma->vm_mm, anon_rss);
get_page(page);
set_pte_at(vma->vm_mm, addr, pte,
pte_mkold(mk_pte(page, vma->vm_page_prot)));
@@ -425,23 +422,25 @@ static int unuse_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
unsigned long addr, unsigned long end,
swp_entry_t entry, struct page *page)
{
- pte_t *pte;
pte_t swp_pte = swp_entry_to_pte(entry);
+ pte_t *pte;
+ spinlock_t *ptl;
+ int found = 0;
- pte = pte_offset_map(pmd, addr);
+ pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
do {
/*
* swapoff spends a _lot_ of time in this loop!
* Test inline before going to call unuse_pte.
*/
if (unlikely(pte_same(*pte, swp_pte))) {
- unuse_pte(vma, pte, addr, entry, page);
- pte_unmap(pte);
- return 1;
+ unuse_pte(vma, pte++, addr, entry, page);
+ found = 1;
+ break;
}
} while (pte++, addr += PAGE_SIZE, addr != end);
- pte_unmap(pte - 1);
- return 0;
+ pte_unmap_unlock(pte - 1, ptl);
+ return found;
}
static inline int unuse_pmd_range(struct vm_area_struct *vma, pud_t *pud,
@@ -523,12 +522,10 @@ static int unuse_mm(struct mm_struct *mm,
down_read(&mm->mmap_sem);
lock_page(page);
}
- spin_lock(&mm->page_table_lock);
for (vma = mm->mmap; vma; vma = vma->vm_next) {
if (vma->anon_vma && unuse_vma(vma, entry, page))
break;
}
- spin_unlock(&mm->page_table_lock);
up_read(&mm->mmap_sem);
/*
* Currently unuse_mm cannot fail, but leave error handling
@@ -1045,7 +1042,7 @@ int page_queue_congested(struct page *page)
BUG_ON(!PageLocked(page)); /* It pins the swap_info_struct */
if (PageSwapCache(page)) {
- swp_entry_t entry = { .val = page->private };
+ swp_entry_t entry = { .val = page_private(page) };
struct swap_info_struct *sis;
sis = get_swap_info_struct(swp_type(entry));
diff --git a/mm/thrash.c b/mm/thrash.c
index 11461f7ad830..eff3c18c33a1 100644
--- a/mm/thrash.c
+++ b/mm/thrash.c
@@ -19,7 +19,7 @@ static unsigned long swap_token_check;
struct mm_struct * swap_token_mm = &init_mm;
#define SWAP_TOKEN_CHECK_INTERVAL (HZ * 2)
-#define SWAP_TOKEN_TIMEOUT 0
+#define SWAP_TOKEN_TIMEOUT (300 * HZ)
/*
* Currently disabled; Needs further code to work at HZ * 300.
*/
diff --git a/mm/tiny-shmem.c b/mm/tiny-shmem.c
index c13a2161bca2..b58abcf44ed6 100644
--- a/mm/tiny-shmem.c
+++ b/mm/tiny-shmem.c
@@ -31,11 +31,14 @@ static struct vfsmount *shm_mnt;
static int __init init_tmpfs(void)
{
- register_filesystem(&tmpfs_fs_type);
+ BUG_ON(register_filesystem(&tmpfs_fs_type) != 0);
+
#ifdef CONFIG_TMPFS
devfs_mk_dir("shm");
#endif
shm_mnt = kern_mount(&tmpfs_fs_type);
+ BUG_ON(IS_ERR(shm_mnt));
+
return 0;
}
module_init(init_tmpfs)
diff --git a/mm/truncate.c b/mm/truncate.c
index 60c8764bfac2..29c18f68dc35 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -13,18 +13,9 @@
#include <linux/pagemap.h>
#include <linux/pagevec.h>
#include <linux/buffer_head.h> /* grr. try_to_release_page,
- block_invalidatepage */
+ do_invalidatepage */
-static int do_invalidatepage(struct page *page, unsigned long offset)
-{
- int (*invalidatepage)(struct page *, unsigned long);
- invalidatepage = page->mapping->a_ops->invalidatepage;
- if (invalidatepage == NULL)
- invalidatepage = block_invalidatepage;
- return (*invalidatepage)(page, offset);
-}
-
static inline void truncate_partial_page(struct page *page, unsigned partial)
{
memclear_highpage_flush(page, partial, PAGE_CACHE_SIZE-partial);
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 1150229b6366..54a90e83cb31 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -5,6 +5,7 @@
* Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
* SMP-safe vmalloc/vfree/ioremap, Tigran Aivazian <tigran@veritas.com>, May 2000
* Major rework to support vmap/vunmap, Christoph Hellwig, SGI, August 2002
+ * Numa awareness, Christoph Lameter, SGI, June 2005
*/
#include <linux/mm.h>
@@ -88,7 +89,7 @@ static int vmap_pte_range(pmd_t *pmd, unsigned long addr,
{
pte_t *pte;
- pte = pte_alloc_kernel(&init_mm, pmd, addr);
+ pte = pte_alloc_kernel(pmd, addr);
if (!pte)
return -ENOMEM;
do {
@@ -146,20 +147,18 @@ int map_vm_area(struct vm_struct *area, pgprot_t prot, struct page ***pages)
BUG_ON(addr >= end);
pgd = pgd_offset_k(addr);
- spin_lock(&init_mm.page_table_lock);
do {
next = pgd_addr_end(addr, end);
err = vmap_pud_range(pgd, addr, next, prot, pages);
if (err)
break;
} while (pgd++, addr = next, addr != end);
- spin_unlock(&init_mm.page_table_lock);
flush_cache_vmap((unsigned long) area->addr, end);
return err;
}
-struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
- unsigned long start, unsigned long end)
+struct vm_struct *__get_vm_area_node(unsigned long size, unsigned long flags,
+ unsigned long start, unsigned long end, int node)
{
struct vm_struct **p, *tmp, *area;
unsigned long align = 1;
@@ -178,7 +177,7 @@ struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
addr = ALIGN(start, align);
size = PAGE_ALIGN(size);
- area = kmalloc(sizeof(*area), GFP_KERNEL);
+ area = kmalloc_node(sizeof(*area), GFP_KERNEL, node);
if (unlikely(!area))
return NULL;
@@ -231,6 +230,12 @@ out:
return NULL;
}
+struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
+ unsigned long start, unsigned long end)
+{
+ return __get_vm_area_node(size, flags, start, end, -1);
+}
+
/**
* get_vm_area - reserve a contingous kernel virtual area
*
@@ -246,6 +251,11 @@ struct vm_struct *get_vm_area(unsigned long size, unsigned long flags)
return __get_vm_area(size, flags, VMALLOC_START, VMALLOC_END);
}
+struct vm_struct *get_vm_area_node(unsigned long size, unsigned long flags, int node)
+{
+ return __get_vm_area_node(size, flags, VMALLOC_START, VMALLOC_END, node);
+}
+
/* Caller must hold vmlist_lock */
struct vm_struct *__remove_vm_area(void *addr)
{
@@ -342,7 +352,6 @@ void vfree(void *addr)
BUG_ON(in_interrupt());
__vunmap(addr, 1);
}
-
EXPORT_SYMBOL(vfree);
/**
@@ -360,7 +369,6 @@ void vunmap(void *addr)
BUG_ON(in_interrupt());
__vunmap(addr, 0);
}
-
EXPORT_SYMBOL(vunmap);
/**
@@ -392,10 +400,10 @@ void *vmap(struct page **pages, unsigned int count,
return area->addr;
}
-
EXPORT_SYMBOL(vmap);
-void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot)
+void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
+ pgprot_t prot, int node)
{
struct page **pages;
unsigned int nr_pages, array_size, i;
@@ -406,9 +414,9 @@ void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot)
area->nr_pages = nr_pages;
/* Please note that the recursion is strictly bounded. */
if (array_size > PAGE_SIZE)
- pages = __vmalloc(array_size, gfp_mask, PAGE_KERNEL);
+ pages = __vmalloc_node(array_size, gfp_mask, PAGE_KERNEL, node);
else
- pages = kmalloc(array_size, (gfp_mask & ~__GFP_HIGHMEM));
+ pages = kmalloc_node(array_size, (gfp_mask & ~__GFP_HIGHMEM), node);
area->pages = pages;
if (!area->pages) {
remove_vm_area(area->addr);
@@ -418,7 +426,10 @@ void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot)
memset(area->pages, 0, array_size);
for (i = 0; i < area->nr_pages; i++) {
- area->pages[i] = alloc_page(gfp_mask);
+ if (node < 0)
+ area->pages[i] = alloc_page(gfp_mask);
+ else
+ area->pages[i] = alloc_pages_node(node, gfp_mask, 0);
if (unlikely(!area->pages[i])) {
/* Successfully allocated i pages, free them in __vunmap() */
area->nr_pages = i;
@@ -435,18 +446,25 @@ fail:
return NULL;
}
+void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot)
+{
+ return __vmalloc_area_node(area, gfp_mask, prot, -1);
+}
+
/**
- * __vmalloc - allocate virtually contiguous memory
+ * __vmalloc_node - allocate virtually contiguous memory
*
* @size: allocation size
* @gfp_mask: flags for the page level allocator
* @prot: protection mask for the allocated pages
+ * @node node to use for allocation or -1
*
* Allocate enough pages to cover @size from the page level
* allocator with @gfp_mask flags. Map them into contiguous
* kernel virtual space, using a pagetable protection of @prot.
*/
-void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
+void *__vmalloc_node(unsigned long size, gfp_t gfp_mask, pgprot_t prot,
+ int node)
{
struct vm_struct *area;
@@ -454,13 +472,18 @@ void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
if (!size || (size >> PAGE_SHIFT) > num_physpages)
return NULL;
- area = get_vm_area(size, VM_ALLOC);
+ area = get_vm_area_node(size, VM_ALLOC, node);
if (!area)
return NULL;
- return __vmalloc_area(area, gfp_mask, prot);
+ return __vmalloc_area_node(area, gfp_mask, prot, node);
}
+EXPORT_SYMBOL(__vmalloc_node);
+void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
+{
+ return __vmalloc_node(size, gfp_mask, prot, -1);
+}
EXPORT_SYMBOL(__vmalloc);
/**
@@ -478,9 +501,26 @@ void *vmalloc(unsigned long size)
{
return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL);
}
-
EXPORT_SYMBOL(vmalloc);
+/**
+ * vmalloc_node - allocate memory on a specific node
+ *
+ * @size: allocation size
+ * @node; numa node
+ *
+ * Allocate enough pages to cover @size from the page level
+ * allocator and map them into contiguous kernel virtual space.
+ *
+ * For tight cotrol over page level allocator and protection flags
+ * use __vmalloc() instead.
+ */
+void *vmalloc_node(unsigned long size, int node)
+{
+ return __vmalloc_node(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL, node);
+}
+EXPORT_SYMBOL(vmalloc_node);
+
#ifndef PAGE_KERNEL_EXEC
# define PAGE_KERNEL_EXEC PAGE_KERNEL
#endif
@@ -515,7 +555,6 @@ void *vmalloc_32(unsigned long size)
{
return __vmalloc(size, GFP_KERNEL, PAGE_KERNEL);
}
-
EXPORT_SYMBOL(vmalloc_32);
long vread(char *buf, char *addr, unsigned long count)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 843c87d1e61f..135bf8ca96ee 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -417,7 +417,9 @@ static int shrink_list(struct list_head *page_list, struct scan_control *sc)
* Anonymous process memory has backing store?
* Try to allocate it some swap space here.
*/
- if (PageAnon(page) && !PageSwapCache(page) && sc->may_swap) {
+ if (PageAnon(page) && !PageSwapCache(page)) {
+ if (!sc->may_swap)
+ goto keep_locked;
if (!add_to_swap(page))
goto activate_locked;
}
@@ -519,7 +521,7 @@ static int shrink_list(struct list_head *page_list, struct scan_control *sc)
#ifdef CONFIG_SWAP
if (PageSwapCache(page)) {
- swp_entry_t swap = { .val = page->private };
+ swp_entry_t swap = { .val = page_private(page) };
__delete_from_swap_cache(page);
write_unlock_irq(&mapping->tree_lock);
swap_free(swap);
diff --git a/net/bluetooth/hidp/Kconfig b/net/bluetooth/hidp/Kconfig
index 4e958f7d9418..edfea772fb67 100644
--- a/net/bluetooth/hidp/Kconfig
+++ b/net/bluetooth/hidp/Kconfig
@@ -1,6 +1,6 @@
config BT_HIDP
tristate "HIDP protocol support"
- depends on BT && BT_L2CAP
+ depends on BT && BT_L2CAP && (BROKEN || !S390)
select INPUT
help
HIDP (Human Interface Device Protocol) is a transport layer
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index 68a5ca866442..e24577367274 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -146,19 +146,6 @@ int eth_rebuild_header(struct sk_buff *skb)
return 0;
}
-static inline unsigned int compare_eth_addr(const unsigned char *__a, const unsigned char *__b)
-{
- const unsigned short *dest = (unsigned short *) __a;
- const unsigned short *devaddr = (unsigned short *) __b;
- unsigned int res;
-
- BUILD_BUG_ON(ETH_ALEN != 6);
- res = ((dest[0] ^ devaddr[0]) |
- (dest[1] ^ devaddr[1]) |
- (dest[2] ^ devaddr[2])) != 0;
-
- return res;
-}
/*
* Determine the packet's protocol ID. The rule here is that we
@@ -176,7 +163,7 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
eth = eth_hdr(skb);
if (*eth->h_dest&1) {
- if (!compare_eth_addr(eth->h_dest, dev->broadcast))
+ if (!compare_ether_addr(eth->h_dest, dev->broadcast))
skb->pkt_type = PACKET_BROADCAST;
else
skb->pkt_type = PACKET_MULTICAST;
@@ -191,7 +178,7 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
*/
else if(1 /*dev->flags&IFF_PROMISC*/) {
- if (unlikely(compare_eth_addr(eth->h_dest, dev->dev_addr)))
+ if (unlikely(compare_ether_addr(eth->h_dest, dev->dev_addr)))
skb->pkt_type = PACKET_OTHERHOST;
}
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index e61bc7177eb1..990633c09dfe 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -591,7 +591,7 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event,
break;
case NETDEV_DOWN:
fib_del_ifaddr(ifa);
- if (ifa->ifa_dev && ifa->ifa_dev->ifa_list == NULL) {
+ if (ifa->ifa_dev->ifa_list == NULL) {
/* Last address was deleted from this interface.
Disable IP.
*/
diff --git a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c
index f5909a4c3fc7..e19c2a52d00c 100644
--- a/net/ipv4/netfilter/ipt_addrtype.c
+++ b/net/ipv4/netfilter/ipt_addrtype.c
@@ -48,7 +48,7 @@ static int checkentry(const char *tablename, const struct ipt_ip *ip,
unsigned int hook_mask)
{
if (matchsize != IPT_ALIGN(sizeof(struct ipt_addrtype_info))) {
- printk(KERN_ERR "ipt_addrtype: invalid size (%u != %Zu)\n.",
+ printk(KERN_ERR "ipt_addrtype: invalid size (%u != %Zu)\n",
matchsize, IPT_ALIGN(sizeof(struct ipt_addrtype_info)));
return 0;
}
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index a970b4727ce8..41edc14851e8 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -75,7 +75,7 @@
#ifdef CONFIG_IPV6_PRIVACY
#include <linux/random.h>
#include <linux/crypto.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
#endif
#include <asm/uaccess.h>
@@ -1217,12 +1217,8 @@ static int __ipv6_regen_rndid(struct inet6_dev *idev)
struct net_device *dev;
struct scatterlist sg[2];
- sg[0].page = virt_to_page(idev->entropy);
- sg[0].offset = offset_in_page(idev->entropy);
- sg[0].length = 8;
- sg[1].page = virt_to_page(idev->work_eui64);
- sg[1].offset = offset_in_page(idev->work_eui64);
- sg[1].length = 8;
+ sg_set_buf(&sg[0], idev->entropy, 8);
+ sg_set_buf(&sg[1], idev->work_eui64, 8);
dev = idev->dev;
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
index 3f3d5437f02d..97c981fa6b8e 100644
--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
@@ -37,7 +37,7 @@
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/slab.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
#include <linux/crypto.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
@@ -75,9 +75,7 @@ krb5_encrypt(
memcpy(local_iv, iv, crypto_tfm_alg_ivsize(tfm));
memcpy(out, in, length);
- sg[0].page = virt_to_page(out);
- sg[0].offset = offset_in_page(out);
- sg[0].length = length;
+ sg_set_buf(sg, out, length);
ret = crypto_cipher_encrypt_iv(tfm, sg, sg, length, local_iv);
@@ -117,9 +115,7 @@ krb5_decrypt(
memcpy(local_iv,iv, crypto_tfm_alg_ivsize(tfm));
memcpy(out, in, length);
- sg[0].page = virt_to_page(out);
- sg[0].offset = offset_in_page(out);
- sg[0].length = length;
+ sg_set_buf(sg, out, length);
ret = crypto_cipher_decrypt_iv(tfm, sg, sg, length, local_iv);
@@ -132,13 +128,6 @@ out:
EXPORT_SYMBOL(krb5_decrypt);
-static void
-buf_to_sg(struct scatterlist *sg, char *ptr, int len) {
- sg->page = virt_to_page(ptr);
- sg->offset = offset_in_page(ptr);
- sg->length = len;
-}
-
static int
process_xdr_buf(struct xdr_buf *buf, int offset, int len,
int (*actor)(struct scatterlist *, void *), void *data)
@@ -152,7 +141,7 @@ process_xdr_buf(struct xdr_buf *buf, int offset, int len,
thislen = buf->head[0].iov_len - offset;
if (thislen > len)
thislen = len;
- buf_to_sg(sg, buf->head[0].iov_base + offset, thislen);
+ sg_set_buf(sg, buf->head[0].iov_base + offset, thislen);
ret = actor(sg, data);
if (ret)
goto out;
@@ -195,7 +184,7 @@ process_xdr_buf(struct xdr_buf *buf, int offset, int len,
thislen = buf->tail[0].iov_len - offset;
if (thislen > len)
thislen = len;
- buf_to_sg(sg, buf->tail[0].iov_base + offset, thislen);
+ sg_set_buf(sg, buf->tail[0].iov_base + offset, thislen);
ret = actor(sg, data);
len -= thislen;
}
@@ -241,7 +230,7 @@ make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body,
goto out;
crypto_digest_init(tfm);
- buf_to_sg(sg, header, hdrlen);
+ sg_set_buf(sg, header, hdrlen);
crypto_digest_update(tfm, sg, 1);
process_xdr_buf(body, body_offset, body->len - body_offset,
checksummer, tfm);
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 2fcb244a9e18..0dd96919de3e 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -116,6 +116,15 @@ endif
clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \
.tmp_gtkcheck zconf.tab.c zconf.tab.h lex.zconf.c
+# Needed for systems without gettext
+KBUILD_HAVE_NLS := $(shell \
+ if echo "\#include <libint.h>" | $(HOSTCC) $(HOSTCFLAGS) -E - > /dev/null 2>&1 ; \
+ then echo yes ; \
+ else echo no ; fi)
+ifeq ($(KBUILD_HAVE_NLS),no)
+HOSTCFLAGS += -DKBUILD_NO_NLS
+endif
+
# generated files seem to need this to find local include files
HOSTCFLAGS_lex.zconf.o := -I$(src)
HOSTCFLAGS_zconf.tab.o := -I$(src)
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index c3d25786a64d..5fba1feff2a8 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -8,7 +8,13 @@
#include "expr.h"
-#include <libintl.h>
+#ifndef KBUILD_NO_NLS
+# include <libintl.h>
+#else
+# define gettext(Msgid) ((const char *) (Msgid))
+# define textdomain(Domainname) ((const char *) (Domainname))
+# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname))
+#endif
#ifdef __cplusplus
extern "C" {
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index 457bec29511d..d1ad40531ee5 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -219,6 +219,7 @@ save_config_help[] = N_(
search_help[] = N_(
"\n"
"Search for CONFIG_ symbols and display their relations.\n"
+ "Regular expressions are allowed.\n"
"Example: search for \"^FOO\"\n"
"Result:\n"
"-----------------------------------------------------------------\n"
@@ -531,7 +532,7 @@ again:
cprint("--title");
cprint(_("Search Configuration Parameter"));
cprint("--inputbox");
- cprint(_("Enter Keyword"));
+ cprint(_("Enter CONFIG_ (sub)string to search for (omit CONFIG_)"));
cprint("10");
cprint("75");
cprint("");
diff --git a/security/dummy.c b/security/dummy.c
index 3d34f3de7e82..3ca5f2b828a0 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -377,7 +377,7 @@ static int dummy_inode_removexattr (struct dentry *dentry, char *name)
return 0;
}
-static int dummy_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size)
+static int dummy_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
{
return -EOPNOTSUPP;
}
@@ -803,6 +803,23 @@ static int dummy_setprocattr(struct task_struct *p, char *name, void *value, siz
return -EINVAL;
}
+#ifdef CONFIG_KEYS
+static inline int dummy_key_alloc(struct key *key)
+{
+ return 0;
+}
+
+static inline void dummy_key_free(struct key *key)
+{
+}
+
+static inline int dummy_key_permission(key_ref_t key_ref,
+ struct task_struct *context,
+ key_perm_t perm)
+{
+ return 0;
+}
+#endif /* CONFIG_KEYS */
struct security_operations dummy_security_ops;
@@ -954,5 +971,11 @@ void security_fixup_ops (struct security_operations *ops)
set_to_dummy_if_null(ops, sk_alloc_security);
set_to_dummy_if_null(ops, sk_free_security);
#endif /* CONFIG_SECURITY_NETWORK */
+#ifdef CONFIG_KEYS
+ set_to_dummy_if_null(ops, key_alloc);
+ set_to_dummy_if_null(ops, key_free);
+ set_to_dummy_if_null(ops, key_permission);
+#endif /* CONFIG_KEYS */
+
}
diff --git a/security/keys/key.c b/security/keys/key.c
index 2182be9e9309..ccde17aff616 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -1,6 +1,6 @@
/* key.c: basic authentication token and access key management
*
- * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
@@ -13,6 +13,7 @@
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/slab.h>
+#include <linux/security.h>
#include <linux/workqueue.h>
#include <linux/err.h>
#include "internal.h"
@@ -253,6 +254,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
struct key_user *user = NULL;
struct key *key;
size_t desclen, quotalen;
+ int ret;
key = ERR_PTR(-EINVAL);
if (!desc || !*desc)
@@ -305,6 +307,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
key->flags = 0;
key->expiry = 0;
key->payload.data = NULL;
+ key->security = NULL;
if (!not_in_quota)
key->flags |= 1 << KEY_FLAG_IN_QUOTA;
@@ -315,16 +318,34 @@ struct key *key_alloc(struct key_type *type, const char *desc,
key->magic = KEY_DEBUG_MAGIC;
#endif
+ /* let the security module know about the key */
+ ret = security_key_alloc(key);
+ if (ret < 0)
+ goto security_error;
+
/* publish the key by giving it a serial number */
atomic_inc(&user->nkeys);
key_alloc_serial(key);
- error:
+error:
return key;
- no_memory_3:
+security_error:
+ kfree(key->description);
+ kmem_cache_free(key_jar, key);
+ if (!not_in_quota) {
+ spin_lock(&user->lock);
+ user->qnkeys--;
+ user->qnbytes -= quotalen;
+ spin_unlock(&user->lock);
+ }
+ key_user_put(user);
+ key = ERR_PTR(ret);
+ goto error;
+
+no_memory_3:
kmem_cache_free(key_jar, key);
- no_memory_2:
+no_memory_2:
if (!not_in_quota) {
spin_lock(&user->lock);
user->qnkeys--;
@@ -332,11 +353,11 @@ struct key *key_alloc(struct key_type *type, const char *desc,
spin_unlock(&user->lock);
}
key_user_put(user);
- no_memory_1:
+no_memory_1:
key = ERR_PTR(-ENOMEM);
goto error;
- no_quota:
+no_quota:
spin_unlock(&user->lock);
key_user_put(user);
key = ERR_PTR(-EDQUOT);
@@ -556,6 +577,8 @@ static void key_cleanup(void *data)
key_check(key);
+ security_key_free(key);
+
/* deal with the user's key tracking and quota */
if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
spin_lock(&key->user->lock);
@@ -700,8 +723,8 @@ static inline key_ref_t __key_update(key_ref_t key_ref,
int ret;
/* need write permission on the key to update it */
- ret = -EACCES;
- if (!key_permission(key_ref, KEY_WRITE))
+ ret = key_permission(key_ref, KEY_WRITE);
+ if (ret < 0)
goto error;
ret = -EEXIST;
@@ -711,7 +734,6 @@ static inline key_ref_t __key_update(key_ref_t key_ref,
down_write(&key->sem);
ret = key->type->update(key, payload, plen);
-
if (ret == 0)
/* updating a negative key instantiates it */
clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
@@ -768,9 +790,11 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
/* if we're going to allocate a new key, we're going to have
* to modify the keyring */
- key_ref = ERR_PTR(-EACCES);
- if (!key_permission(keyring_ref, KEY_WRITE))
+ ret = key_permission(keyring_ref, KEY_WRITE);
+ if (ret < 0) {
+ key_ref = ERR_PTR(ret);
goto error_3;
+ }
/* search for an existing key of the same type and description in the
* destination keyring
@@ -780,8 +804,8 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
goto found_matching_key;
/* decide on the permissions we want */
- perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK;
- perm |= KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_LINK;
+ perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR;
+ perm |= KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_LINK | KEY_USR_SETATTR;
if (ktype->read)
perm |= KEY_POS_READ | KEY_USR_READ;
@@ -840,16 +864,16 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen)
key_check(key);
/* the key must be writable */
- ret = -EACCES;
- if (!key_permission(key_ref, KEY_WRITE))
+ ret = key_permission(key_ref, KEY_WRITE);
+ if (ret < 0)
goto error;
/* attempt to update it if supported */
ret = -EOPNOTSUPP;
if (key->type->update) {
down_write(&key->sem);
- ret = key->type->update(key, payload, plen);
+ ret = key->type->update(key, payload, plen);
if (ret == 0)
/* updating a negative key instantiates it */
clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 4c670ee6acf9..b7a468fabdf9 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -624,8 +624,8 @@ long keyctl_keyring_search(key_serial_t ringid,
/* link the resulting key to the destination keyring if we can */
if (dest_ref) {
- ret = -EACCES;
- if (!key_permission(key_ref, KEY_LINK))
+ ret = key_permission(key_ref, KEY_LINK);
+ if (ret < 0)
goto error6;
ret = key_link(key_ref_to_ptr(dest_ref), key_ref_to_ptr(key_ref));
@@ -676,8 +676,11 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
key = key_ref_to_ptr(key_ref);
/* see if we can read it directly */
- if (key_permission(key_ref, KEY_READ))
+ ret = key_permission(key_ref, KEY_READ);
+ if (ret == 0)
goto can_read_key;
+ if (ret != -EACCES)
+ goto error;
/* we can't; see if it's searchable from this process's keyrings
* - we automatically take account of the fact that it may be
@@ -726,7 +729,7 @@ long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid)
if (uid == (uid_t) -1 && gid == (gid_t) -1)
goto error;
- key_ref = lookup_user_key(NULL, id, 1, 1, 0);
+ key_ref = lookup_user_key(NULL, id, 1, 1, KEY_SETATTR);
if (IS_ERR(key_ref)) {
ret = PTR_ERR(key_ref);
goto error;
@@ -786,7 +789,7 @@ long keyctl_setperm_key(key_serial_t id, key_perm_t perm)
if (perm & ~(KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL))
goto error;
- key_ref = lookup_user_key(NULL, id, 1, 1, 0);
+ key_ref = lookup_user_key(NULL, id, 1, 1, KEY_SETATTR);
if (IS_ERR(key_ref)) {
ret = PTR_ERR(key_ref);
goto error;
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 0639396dd441..e1cc4dd79012 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -13,6 +13,7 @@
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/slab.h>
+#include <linux/security.h>
#include <linux/seq_file.h>
#include <linux/err.h>
#include <asm/uaccess.h>
@@ -309,7 +310,9 @@ struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
int ret;
keyring = key_alloc(&key_type_keyring, description,
- uid, gid, KEY_POS_ALL | KEY_USR_ALL, not_in_quota);
+ uid, gid,
+ (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
+ not_in_quota);
if (!IS_ERR(keyring)) {
ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL);
@@ -359,9 +362,11 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
key_check(keyring);
/* top keyring must have search permission to begin the search */
- key_ref = ERR_PTR(-EACCES);
- if (!key_task_permission(keyring_ref, context, KEY_SEARCH))
+ err = key_task_permission(keyring_ref, context, KEY_SEARCH);
+ if (err < 0) {
+ key_ref = ERR_PTR(err);
goto error;
+ }
key_ref = ERR_PTR(-ENOTDIR);
if (keyring->type != &key_type_keyring)
@@ -402,8 +407,8 @@ descend:
continue;
/* key must have search permissions */
- if (!key_task_permission(make_key_ref(key, possessed),
- context, KEY_SEARCH))
+ if (key_task_permission(make_key_ref(key, possessed),
+ context, KEY_SEARCH) < 0)
continue;
/* we set a different error code if we find a negative key */
@@ -430,7 +435,7 @@ ascend:
continue;
if (!key_task_permission(make_key_ref(key, possessed),
- context, KEY_SEARCH))
+ context, KEY_SEARCH) < 0)
continue;
/* stack the current position */
@@ -521,7 +526,7 @@ key_ref_t __keyring_search_one(key_ref_t keyring_ref,
(!key->type->match ||
key->type->match(key, description)) &&
key_permission(make_key_ref(key, possessed),
- perm) &&
+ perm) < 0 &&
!test_bit(KEY_FLAG_REVOKED, &key->flags)
)
goto found;
@@ -617,7 +622,7 @@ struct key *find_keyring_by_name(const char *name, key_serial_t bound)
continue;
if (!key_permission(make_key_ref(keyring, 0),
- KEY_SEARCH))
+ KEY_SEARCH) < 0)
continue;
/* found a potential candidate, but we still need to
diff --git a/security/keys/permission.c b/security/keys/permission.c
index 03db073ba45c..e7f579c0eaf5 100644
--- a/security/keys/permission.c
+++ b/security/keys/permission.c
@@ -10,6 +10,7 @@
*/
#include <linux/module.h>
+#include <linux/security.h>
#include "internal.h"
/*****************************************************************************/
@@ -63,7 +64,11 @@ use_these_perms:
kperm = kperm & perm & KEY_ALL;
- return kperm == perm;
+ if (kperm != perm)
+ return -EACCES;
+
+ /* let LSM be the final arbiter */
+ return security_key_permission(key_ref, context, perm);
} /* end key_task_permission() */
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index d42d2158ce13..566b1cc0118a 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -39,7 +39,7 @@ struct key root_user_keyring = {
.type = &key_type_keyring,
.user = &root_key_user,
.sem = __RWSEM_INITIALIZER(root_user_keyring.sem),
- .perm = KEY_POS_ALL | KEY_USR_ALL,
+ .perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
.flags = 1 << KEY_FLAG_INSTANTIATED,
.description = "_uid.0",
#ifdef KEY_DEBUGGING
@@ -54,7 +54,7 @@ struct key root_session_keyring = {
.type = &key_type_keyring,
.user = &root_key_user,
.sem = __RWSEM_INITIALIZER(root_session_keyring.sem),
- .perm = KEY_POS_ALL | KEY_USR_ALL,
+ .perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
.flags = 1 << KEY_FLAG_INSTANTIATED,
.description = "_uid_ses.0",
#ifdef KEY_DEBUGGING
@@ -666,9 +666,8 @@ key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id,
goto invalid_key;
/* check the permissions */
- ret = -EACCES;
-
- if (!key_task_permission(key_ref, context, perm))
+ ret = key_task_permission(key_ref, context, perm);
+ if (ret < 0)
goto invalid_key;
error:
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index e446acba73d3..cbda3b2780a1 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -15,18 +15,10 @@
#include <linux/slab.h>
#include <linux/seq_file.h>
#include <linux/err.h>
+#include <keys/user-type.h>
#include <asm/uaccess.h>
#include "internal.h"
-static int user_instantiate(struct key *key, const void *data, size_t datalen);
-static int user_duplicate(struct key *key, const struct key *source);
-static int user_update(struct key *key, const void *data, size_t datalen);
-static int user_match(const struct key *key, const void *criterion);
-static void user_destroy(struct key *key);
-static void user_describe(const struct key *user, struct seq_file *m);
-static long user_read(const struct key *key,
- char __user *buffer, size_t buflen);
-
/*
* user defined keys take an arbitrary string as the description and an
* arbitrary blob of data as the payload
@@ -42,19 +34,13 @@ struct key_type key_type_user = {
.read = user_read,
};
-struct user_key_payload {
- struct rcu_head rcu; /* RCU destructor */
- unsigned short datalen; /* length of this data */
- char data[0]; /* actual data */
-};
-
EXPORT_SYMBOL_GPL(key_type_user);
/*****************************************************************************/
/*
* instantiate a user defined key
*/
-static int user_instantiate(struct key *key, const void *data, size_t datalen)
+int user_instantiate(struct key *key, const void *data, size_t datalen)
{
struct user_key_payload *upayload;
int ret;
@@ -78,18 +64,20 @@ static int user_instantiate(struct key *key, const void *data, size_t datalen)
rcu_assign_pointer(key->payload.data, upayload);
ret = 0;
- error:
+error:
return ret;
} /* end user_instantiate() */
+EXPORT_SYMBOL_GPL(user_instantiate);
+
/*****************************************************************************/
/*
* duplicate a user defined key
* - both keys' semaphores are locked against further modification
* - the new key cannot yet be accessed
*/
-static int user_duplicate(struct key *key, const struct key *source)
+int user_duplicate(struct key *key, const struct key *source)
{
struct user_key_payload *upayload, *spayload;
int ret;
@@ -112,6 +100,8 @@ static int user_duplicate(struct key *key, const struct key *source)
} /* end user_duplicate() */
+EXPORT_SYMBOL_GPL(user_duplicate);
+
/*****************************************************************************/
/*
* dispose of the old data from an updated user defined key
@@ -131,7 +121,7 @@ static void user_update_rcu_disposal(struct rcu_head *rcu)
* update a user defined key
* - the key's semaphore is write-locked
*/
-static int user_update(struct key *key, const void *data, size_t datalen)
+int user_update(struct key *key, const void *data, size_t datalen)
{
struct user_key_payload *upayload, *zap;
int ret;
@@ -163,26 +153,30 @@ static int user_update(struct key *key, const void *data, size_t datalen)
call_rcu(&zap->rcu, user_update_rcu_disposal);
- error:
+error:
return ret;
} /* end user_update() */
+EXPORT_SYMBOL_GPL(user_update);
+
/*****************************************************************************/
/*
* match users on their name
*/
-static int user_match(const struct key *key, const void *description)
+int user_match(const struct key *key, const void *description)
{
return strcmp(key->description, description) == 0;
} /* end user_match() */
+EXPORT_SYMBOL_GPL(user_match);
+
/*****************************************************************************/
/*
* dispose of the data dangling from the corpse of a user
*/
-static void user_destroy(struct key *key)
+void user_destroy(struct key *key)
{
struct user_key_payload *upayload = key->payload.data;
@@ -190,11 +184,13 @@ static void user_destroy(struct key *key)
} /* end user_destroy() */
+EXPORT_SYMBOL_GPL(user_destroy);
+
/*****************************************************************************/
/*
* describe the user key
*/
-static void user_describe(const struct key *key, struct seq_file *m)
+void user_describe(const struct key *key, struct seq_file *m)
{
seq_puts(m, key->description);
@@ -202,13 +198,14 @@ static void user_describe(const struct key *key, struct seq_file *m)
} /* end user_describe() */
+EXPORT_SYMBOL_GPL(user_describe);
+
/*****************************************************************************/
/*
* read the key data
* - the key's semaphore is read-locked
*/
-static long user_read(const struct key *key,
- char __user *buffer, size_t buflen)
+long user_read(const struct key *key, char __user *buffer, size_t buflen)
{
struct user_key_payload *upayload;
long ret;
@@ -228,3 +225,5 @@ static long user_read(const struct key *key,
return ret;
} /* end user_read() */
+
+EXPORT_SYMBOL_GPL(user_read);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 447a1e0f48cb..45c41490d521 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -122,11 +122,10 @@ static int task_alloc_security(struct task_struct *task)
{
struct task_security_struct *tsec;
- tsec = kmalloc(sizeof(struct task_security_struct), GFP_KERNEL);
+ tsec = kzalloc(sizeof(struct task_security_struct), GFP_KERNEL);
if (!tsec)
return -ENOMEM;
- memset(tsec, 0, sizeof(struct task_security_struct));
tsec->magic = SELINUX_MAGIC;
tsec->task = task;
tsec->osid = tsec->sid = tsec->ptrace_sid = SECINITSID_UNLABELED;
@@ -151,11 +150,10 @@ static int inode_alloc_security(struct inode *inode)
struct task_security_struct *tsec = current->security;
struct inode_security_struct *isec;
- isec = kmalloc(sizeof(struct inode_security_struct), GFP_KERNEL);
+ isec = kzalloc(sizeof(struct inode_security_struct), GFP_KERNEL);
if (!isec)
return -ENOMEM;
- memset(isec, 0, sizeof(struct inode_security_struct));
init_MUTEX(&isec->sem);
INIT_LIST_HEAD(&isec->list);
isec->magic = SELINUX_MAGIC;
@@ -193,11 +191,10 @@ static int file_alloc_security(struct file *file)
struct task_security_struct *tsec = current->security;
struct file_security_struct *fsec;
- fsec = kmalloc(sizeof(struct file_security_struct), GFP_ATOMIC);
+ fsec = kzalloc(sizeof(struct file_security_struct), GFP_ATOMIC);
if (!fsec)
return -ENOMEM;
- memset(fsec, 0, sizeof(struct file_security_struct));
fsec->magic = SELINUX_MAGIC;
fsec->file = file;
if (tsec && tsec->magic == SELINUX_MAGIC) {
@@ -227,11 +224,10 @@ static int superblock_alloc_security(struct super_block *sb)
{
struct superblock_security_struct *sbsec;
- sbsec = kmalloc(sizeof(struct superblock_security_struct), GFP_KERNEL);
+ sbsec = kzalloc(sizeof(struct superblock_security_struct), GFP_KERNEL);
if (!sbsec)
return -ENOMEM;
- memset(sbsec, 0, sizeof(struct superblock_security_struct));
init_MUTEX(&sbsec->sem);
INIT_LIST_HEAD(&sbsec->list);
INIT_LIST_HEAD(&sbsec->isec_head);
@@ -269,11 +265,10 @@ static int sk_alloc_security(struct sock *sk, int family, gfp_t priority)
if (family != PF_UNIX)
return 0;
- ssec = kmalloc(sizeof(*ssec), priority);
+ ssec = kzalloc(sizeof(*ssec), priority);
if (!ssec)
return -ENOMEM;
- memset(ssec, 0, sizeof(*ssec));
ssec->magic = SELINUX_MAGIC;
ssec->sk = sk;
ssec->peer_sid = SECINITSID_UNLABELED;
@@ -1483,11 +1478,10 @@ static int selinux_bprm_alloc_security(struct linux_binprm *bprm)
{
struct bprm_security_struct *bsec;
- bsec = kmalloc(sizeof(struct bprm_security_struct), GFP_KERNEL);
+ bsec = kzalloc(sizeof(struct bprm_security_struct), GFP_KERNEL);
if (!bsec)
return -ENOMEM;
- memset(bsec, 0, sizeof *bsec);
bsec->magic = SELINUX_MAGIC;
bsec->bprm = bprm;
bsec->sid = SECINITSID_UNLABELED;
@@ -1615,7 +1609,7 @@ static inline void flush_unauthorized_files(struct files_struct * files)
if (tty) {
file_list_lock();
- file = list_entry(tty->tty_files.next, typeof(*file), f_list);
+ file = list_entry(tty->tty_files.next, typeof(*file), f_u.fu_list);
if (file) {
/* Revalidate access to controlling tty.
Use inode_has_perm on the tty inode directly rather
@@ -2211,12 +2205,6 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, char *name,
static int selinux_inode_getxattr (struct dentry *dentry, char *name)
{
- struct inode *inode = dentry->d_inode;
- struct superblock_security_struct *sbsec = inode->i_sb->s_security;
-
- if (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)
- return -EOPNOTSUPP;
-
return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
}
@@ -2247,33 +2235,54 @@ static int selinux_inode_removexattr (struct dentry *dentry, char *name)
return -EACCES;
}
-static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size)
+/*
+ * Copy the in-core inode security context value to the user. If the
+ * getxattr() prior to this succeeded, check to see if we need to
+ * canonicalize the value to be finally returned to the user.
+ *
+ * Permission check is handled by selinux_inode_getxattr hook.
+ */
+static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
{
struct inode_security_struct *isec = inode->i_security;
char *context;
unsigned len;
int rc;
- /* Permission check handled by selinux_inode_getxattr hook.*/
-
- if (strcmp(name, XATTR_SELINUX_SUFFIX))
- return -EOPNOTSUPP;
+ if (strcmp(name, XATTR_SELINUX_SUFFIX)) {
+ rc = -EOPNOTSUPP;
+ goto out;
+ }
rc = security_sid_to_context(isec->sid, &context, &len);
if (rc)
- return rc;
+ goto out;
+ /* Probe for required buffer size */
if (!buffer || !size) {
- kfree(context);
- return len;
+ rc = len;
+ goto out_free;
}
+
if (size < len) {
- kfree(context);
- return -ERANGE;
+ rc = -ERANGE;
+ goto out_free;
+ }
+
+ if (err > 0) {
+ if ((len == err) && !(memcmp(context, buffer, len))) {
+ /* Don't need to canonicalize value */
+ rc = err;
+ goto out_free;
+ }
+ memset(buffer, 0, size);
}
memcpy(buffer, context, len);
+ rc = len;
+out_free:
kfree(context);
- return len;
+out:
+ return rc;
}
static int selinux_inode_setsecurity(struct inode *inode, const char *name,
@@ -2704,8 +2713,7 @@ static int selinux_task_kill(struct task_struct *p, struct siginfo *info, int si
if (rc)
return rc;
- if (info && ((unsigned long)info == 1 ||
- (unsigned long)info == 2 || SI_FROMKERNEL(info)))
+ if (info != SEND_SIG_NOINFO && (is_si_special(info) || SI_FROMKERNEL(info)))
return 0;
if (!sig)
@@ -3599,11 +3607,10 @@ static int ipc_alloc_security(struct task_struct *task,
struct task_security_struct *tsec = task->security;
struct ipc_security_struct *isec;
- isec = kmalloc(sizeof(struct ipc_security_struct), GFP_KERNEL);
+ isec = kzalloc(sizeof(struct ipc_security_struct), GFP_KERNEL);
if (!isec)
return -ENOMEM;
- memset(isec, 0, sizeof(struct ipc_security_struct));
isec->magic = SELINUX_MAGIC;
isec->sclass = sclass;
isec->ipc_perm = perm;
@@ -3631,11 +3638,10 @@ static int msg_msg_alloc_security(struct msg_msg *msg)
{
struct msg_security_struct *msec;
- msec = kmalloc(sizeof(struct msg_security_struct), GFP_KERNEL);
+ msec = kzalloc(sizeof(struct msg_security_struct), GFP_KERNEL);
if (!msec)
return -ENOMEM;
- memset(msec, 0, sizeof(struct msg_security_struct));
msec->magic = SELINUX_MAGIC;
msec->msg = msg;
msec->sid = SECINITSID_UNLABELED;
diff --git a/security/selinux/netif.c b/security/selinux/netif.c
index 718d7be9f4dd..b10c34e8a743 100644
--- a/security/selinux/netif.c
+++ b/security/selinux/netif.c
@@ -114,13 +114,12 @@ static struct sel_netif *sel_netif_lookup(struct net_device *dev)
if (likely(netif != NULL))
goto out;
- new = kmalloc(sizeof(*new), GFP_ATOMIC);
+ new = kzalloc(sizeof(*new), GFP_ATOMIC);
if (!new) {
netif = ERR_PTR(-ENOMEM);
goto out;
}
- memset(new, 0, sizeof(*new));
nsec = &new->nsec;
ret = security_netif_sid(dev->name, &nsec->if_sid, &nsec->msg_sid);
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index a45cc971e735..fdc382389720 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -105,7 +105,7 @@ static ssize_t sel_write_enforce(struct file * file, const char __user * buf,
ssize_t length;
int new_value;
- if (count < 0 || count >= PAGE_SIZE)
+ if (count >= PAGE_SIZE)
return -ENOMEM;
if (*ppos != 0) {
/* No partial writes. */
@@ -155,7 +155,7 @@ static ssize_t sel_write_disable(struct file * file, const char __user * buf,
int new_value;
extern int selinux_disable(void);
- if (count < 0 || count >= PAGE_SIZE)
+ if (count >= PAGE_SIZE)
return -ENOMEM;
if (*ppos != 0) {
/* No partial writes. */
@@ -242,7 +242,7 @@ static ssize_t sel_write_load(struct file * file, const char __user * buf,
goto out;
}
- if ((count < 0) || (count > 64 * 1024 * 1024)
+ if ((count > 64 * 1024 * 1024)
|| (data = vmalloc(count)) == NULL) {
length = -ENOMEM;
goto out;
@@ -284,7 +284,7 @@ static ssize_t sel_write_context(struct file * file, const char __user * buf,
if (length)
return length;
- if (count < 0 || count >= PAGE_SIZE)
+ if (count >= PAGE_SIZE)
return -ENOMEM;
if (*ppos != 0) {
/* No partial writes. */
@@ -332,7 +332,7 @@ static ssize_t sel_write_checkreqprot(struct file * file, const char __user * bu
if (length)
return length;
- if (count < 0 || count >= PAGE_SIZE)
+ if (count >= PAGE_SIZE)
return -ENOMEM;
if (*ppos != 0) {
/* No partial writes. */
@@ -424,15 +424,13 @@ static ssize_t sel_write_access(struct file * file, char *buf, size_t size)
return length;
length = -ENOMEM;
- scon = kmalloc(size+1, GFP_KERNEL);
+ scon = kzalloc(size+1, GFP_KERNEL);
if (!scon)
return length;
- memset(scon, 0, size+1);
- tcon = kmalloc(size+1, GFP_KERNEL);
+ tcon = kzalloc(size+1, GFP_KERNEL);
if (!tcon)
goto out;
- memset(tcon, 0, size+1);
length = -EINVAL;
if (sscanf(buf, "%s %s %hu %x", scon, tcon, &tclass, &req) != 4)
@@ -475,15 +473,13 @@ static ssize_t sel_write_create(struct file * file, char *buf, size_t size)
return length;
length = -ENOMEM;
- scon = kmalloc(size+1, GFP_KERNEL);
+ scon = kzalloc(size+1, GFP_KERNEL);
if (!scon)
return length;
- memset(scon, 0, size+1);
- tcon = kmalloc(size+1, GFP_KERNEL);
+ tcon = kzalloc(size+1, GFP_KERNEL);
if (!tcon)
goto out;
- memset(tcon, 0, size+1);
length = -EINVAL;
if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
@@ -536,15 +532,13 @@ static ssize_t sel_write_relabel(struct file * file, char *buf, size_t size)
return length;
length = -ENOMEM;
- scon = kmalloc(size+1, GFP_KERNEL);
+ scon = kzalloc(size+1, GFP_KERNEL);
if (!scon)
return length;
- memset(scon, 0, size+1);
- tcon = kmalloc(size+1, GFP_KERNEL);
+ tcon = kzalloc(size+1, GFP_KERNEL);
if (!tcon)
goto out;
- memset(tcon, 0, size+1);
length = -EINVAL;
if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
@@ -595,15 +589,13 @@ static ssize_t sel_write_user(struct file * file, char *buf, size_t size)
return length;
length = -ENOMEM;
- con = kmalloc(size+1, GFP_KERNEL);
+ con = kzalloc(size+1, GFP_KERNEL);
if (!con)
return length;
- memset(con, 0, size+1);
- user = kmalloc(size+1, GFP_KERNEL);
+ user = kzalloc(size+1, GFP_KERNEL);
if (!user)
goto out;
- memset(user, 0, size+1);
length = -EINVAL;
if (sscanf(buf, "%s %s", con, user) != 2)
@@ -658,15 +650,13 @@ static ssize_t sel_write_member(struct file * file, char *buf, size_t size)
return length;
length = -ENOMEM;
- scon = kmalloc(size+1, GFP_KERNEL);
+ scon = kzalloc(size+1, GFP_KERNEL);
if (!scon)
return length;
- memset(scon, 0, size+1);
- tcon = kmalloc(size+1, GFP_KERNEL);
+ tcon = kzalloc(size+1, GFP_KERNEL);
if (!tcon)
goto out;
- memset(tcon, 0, size+1);
length = -EINVAL;
if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
@@ -739,7 +729,7 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
if (!filep->f_op)
goto out;
- if (count < 0 || count > PAGE_SIZE) {
+ if (count > PAGE_SIZE) {
ret = -EINVAL;
goto out;
}
@@ -800,7 +790,7 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
if (!filep->f_op)
goto out;
- if (count < 0 || count >= PAGE_SIZE) {
+ if (count >= PAGE_SIZE) {
length = -ENOMEM;
goto out;
}
@@ -858,7 +848,7 @@ static ssize_t sel_commit_bools_write(struct file *filep,
if (!filep->f_op)
goto out;
- if (count < 0 || count >= PAGE_SIZE) {
+ if (count >= PAGE_SIZE) {
length = -ENOMEM;
goto out;
}
@@ -924,7 +914,7 @@ static void sel_remove_bools(struct dentry *de)
file_list_lock();
list_for_each(p, &sb->s_files) {
- struct file * filp = list_entry(p, struct file, f_list);
+ struct file * filp = list_entry(p, struct file, f_u.fu_list);
struct dentry * dentry = filp->f_dentry;
if (dentry->d_parent != de) {
@@ -1032,7 +1022,7 @@ static ssize_t sel_write_avc_cache_threshold(struct file * file,
ssize_t ret;
int new_value;
- if (count < 0 || count >= PAGE_SIZE) {
+ if (count >= PAGE_SIZE) {
ret = -ENOMEM;
goto out;
}
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
index daf288007460..d2737edba541 100644
--- a/security/selinux/ss/conditional.c
+++ b/security/selinux/ss/conditional.c
@@ -220,10 +220,9 @@ int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp)
u32 len;
int rc;
- booldatum = kmalloc(sizeof(struct cond_bool_datum), GFP_KERNEL);
+ booldatum = kzalloc(sizeof(struct cond_bool_datum), GFP_KERNEL);
if (!booldatum)
return -1;
- memset(booldatum, 0, sizeof(struct cond_bool_datum));
rc = next_entry(buf, fp, sizeof buf);
if (rc < 0)
@@ -321,10 +320,9 @@ static int cond_insertf(struct avtab *a, struct avtab_key *k, struct avtab_datum
goto err;
}
- list = kmalloc(sizeof(struct cond_av_list), GFP_KERNEL);
+ list = kzalloc(sizeof(struct cond_av_list), GFP_KERNEL);
if (!list)
goto err;
- memset(list, 0, sizeof(*list));
list->node = node_ptr;
if (!data->head)
@@ -414,11 +412,10 @@ static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp)
if (rc < 0)
goto err;
- expr = kmalloc(sizeof(struct cond_expr), GFP_KERNEL);
+ expr = kzalloc(sizeof(struct cond_expr), GFP_KERNEL);
if (!expr) {
goto err;
}
- memset(expr, 0, sizeof(struct cond_expr));
expr->expr_type = le32_to_cpu(buf[0]);
expr->bool = le32_to_cpu(buf[1]);
@@ -460,10 +457,9 @@ int cond_read_list(struct policydb *p, void *fp)
len = le32_to_cpu(buf[0]);
for (i = 0; i < len; i++) {
- node = kmalloc(sizeof(struct cond_node), GFP_KERNEL);
+ node = kzalloc(sizeof(struct cond_node), GFP_KERNEL);
if (!node)
goto err;
- memset(node, 0, sizeof(struct cond_node));
if (cond_read_node(p, node, fp) != 0)
goto err;
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
index d515154128cc..47024a6e1844 100644
--- a/security/selinux/ss/ebitmap.c
+++ b/security/selinux/ss/ebitmap.c
@@ -39,12 +39,11 @@ int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src)
n = src->node;
prev = NULL;
while (n) {
- new = kmalloc(sizeof(*new), GFP_ATOMIC);
+ new = kzalloc(sizeof(*new), GFP_ATOMIC);
if (!new) {
ebitmap_destroy(dst);
return -ENOMEM;
}
- memset(new, 0, sizeof(*new));
new->startbit = n->startbit;
new->map = n->map;
new->next = NULL;
@@ -150,10 +149,9 @@ int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value)
if (!value)
return 0;
- new = kmalloc(sizeof(*new), GFP_ATOMIC);
+ new = kzalloc(sizeof(*new), GFP_ATOMIC);
if (!new)
return -ENOMEM;
- memset(new, 0, sizeof(*new));
new->startbit = bit & ~(MAPSIZE - 1);
new->map = (MAPBIT << (bit - new->startbit));
@@ -232,13 +230,12 @@ int ebitmap_read(struct ebitmap *e, void *fp)
printk(KERN_ERR "security: ebitmap: truncated map\n");
goto bad;
}
- n = kmalloc(sizeof(*n), GFP_KERNEL);
+ n = kzalloc(sizeof(*n), GFP_KERNEL);
if (!n) {
printk(KERN_ERR "security: ebitmap: out of memory\n");
rc = -ENOMEM;
goto bad;
}
- memset(n, 0, sizeof(*n));
n->startbit = le32_to_cpu(buf[0]);
diff --git a/security/selinux/ss/hashtab.c b/security/selinux/ss/hashtab.c
index 26661fcc00ce..24e5ec957630 100644
--- a/security/selinux/ss/hashtab.c
+++ b/security/selinux/ss/hashtab.c
@@ -15,11 +15,10 @@ struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, void *key),
struct hashtab *p;
u32 i;
- p = kmalloc(sizeof(*p), GFP_KERNEL);
+ p = kzalloc(sizeof(*p), GFP_KERNEL);
if (p == NULL)
return p;
- memset(p, 0, sizeof(*p));
p->size = size;
p->nel = 0;
p->hash_value = hash_value;
@@ -55,10 +54,9 @@ int hashtab_insert(struct hashtab *h, void *key, void *datum)
if (cur && (h->keycmp(h, key, cur->key) == 0))
return -EEXIST;
- newnode = kmalloc(sizeof(*newnode), GFP_KERNEL);
+ newnode = kzalloc(sizeof(*newnode), GFP_KERNEL);
if (newnode == NULL)
return -ENOMEM;
- memset(newnode, 0, sizeof(*newnode));
newnode->key = key;
newnode->datum = datum;
if (prev) {
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 8e6262d12aa9..2f5f539875f2 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -121,12 +121,11 @@ static int roles_init(struct policydb *p)
int rc;
struct role_datum *role;
- role = kmalloc(sizeof(*role), GFP_KERNEL);
+ role = kzalloc(sizeof(*role), GFP_KERNEL);
if (!role) {
rc = -ENOMEM;
goto out;
}
- memset(role, 0, sizeof(*role));
role->value = ++p->p_roles.nprim;
if (role->value != OBJECT_R_VAL) {
rc = -EINVAL;
@@ -851,12 +850,11 @@ static int perm_read(struct policydb *p, struct hashtab *h, void *fp)
__le32 buf[2];
u32 len;
- perdatum = kmalloc(sizeof(*perdatum), GFP_KERNEL);
+ perdatum = kzalloc(sizeof(*perdatum), GFP_KERNEL);
if (!perdatum) {
rc = -ENOMEM;
goto out;
}
- memset(perdatum, 0, sizeof(*perdatum));
rc = next_entry(buf, fp, sizeof buf);
if (rc < 0)
@@ -893,12 +891,11 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
u32 len, nel;
int i, rc;
- comdatum = kmalloc(sizeof(*comdatum), GFP_KERNEL);
+ comdatum = kzalloc(sizeof(*comdatum), GFP_KERNEL);
if (!comdatum) {
rc = -ENOMEM;
goto out;
}
- memset(comdatum, 0, sizeof(*comdatum));
rc = next_entry(buf, fp, sizeof buf);
if (rc < 0)
@@ -950,10 +947,9 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons,
lc = NULL;
for (i = 0; i < ncons; i++) {
- c = kmalloc(sizeof(*c), GFP_KERNEL);
+ c = kzalloc(sizeof(*c), GFP_KERNEL);
if (!c)
return -ENOMEM;
- memset(c, 0, sizeof(*c));
if (lc) {
lc->next = c;
@@ -969,10 +965,9 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons,
le = NULL;
depth = -1;
for (j = 0; j < nexpr; j++) {
- e = kmalloc(sizeof(*e), GFP_KERNEL);
+ e = kzalloc(sizeof(*e), GFP_KERNEL);
if (!e)
return -ENOMEM;
- memset(e, 0, sizeof(*e));
if (le) {
le->next = e;
@@ -1033,12 +1028,11 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
u32 len, len2, ncons, nel;
int i, rc;
- cladatum = kmalloc(sizeof(*cladatum), GFP_KERNEL);
+ cladatum = kzalloc(sizeof(*cladatum), GFP_KERNEL);
if (!cladatum) {
rc = -ENOMEM;
goto out;
}
- memset(cladatum, 0, sizeof(*cladatum));
rc = next_entry(buf, fp, sizeof(u32)*6);
if (rc < 0)
@@ -1127,12 +1121,11 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
__le32 buf[2];
u32 len;
- role = kmalloc(sizeof(*role), GFP_KERNEL);
+ role = kzalloc(sizeof(*role), GFP_KERNEL);
if (!role) {
rc = -ENOMEM;
goto out;
}
- memset(role, 0, sizeof(*role));
rc = next_entry(buf, fp, sizeof buf);
if (rc < 0)
@@ -1188,12 +1181,11 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp)
__le32 buf[3];
u32 len;
- typdatum = kmalloc(sizeof(*typdatum),GFP_KERNEL);
+ typdatum = kzalloc(sizeof(*typdatum),GFP_KERNEL);
if (!typdatum) {
rc = -ENOMEM;
return rc;
}
- memset(typdatum, 0, sizeof(*typdatum));
rc = next_entry(buf, fp, sizeof buf);
if (rc < 0)
@@ -1261,12 +1253,11 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
__le32 buf[2];
u32 len;
- usrdatum = kmalloc(sizeof(*usrdatum), GFP_KERNEL);
+ usrdatum = kzalloc(sizeof(*usrdatum), GFP_KERNEL);
if (!usrdatum) {
rc = -ENOMEM;
goto out;
}
- memset(usrdatum, 0, sizeof(*usrdatum));
rc = next_entry(buf, fp, sizeof buf);
if (rc < 0)
@@ -1316,12 +1307,11 @@ static int sens_read(struct policydb *p, struct hashtab *h, void *fp)
__le32 buf[2];
u32 len;
- levdatum = kmalloc(sizeof(*levdatum), GFP_ATOMIC);
+ levdatum = kzalloc(sizeof(*levdatum), GFP_ATOMIC);
if (!levdatum) {
rc = -ENOMEM;
goto out;
}
- memset(levdatum, 0, sizeof(*levdatum));
rc = next_entry(buf, fp, sizeof buf);
if (rc < 0)
@@ -1368,12 +1358,11 @@ static int cat_read(struct policydb *p, struct hashtab *h, void *fp)
__le32 buf[3];
u32 len;
- catdatum = kmalloc(sizeof(*catdatum), GFP_ATOMIC);
+ catdatum = kzalloc(sizeof(*catdatum), GFP_ATOMIC);
if (!catdatum) {
rc = -ENOMEM;
goto out;
}
- memset(catdatum, 0, sizeof(*catdatum));
rc = next_entry(buf, fp, sizeof buf);
if (rc < 0)
@@ -1567,12 +1556,11 @@ int policydb_read(struct policydb *p, void *fp)
nel = le32_to_cpu(buf[0]);
ltr = NULL;
for (i = 0; i < nel; i++) {
- tr = kmalloc(sizeof(*tr), GFP_KERNEL);
+ tr = kzalloc(sizeof(*tr), GFP_KERNEL);
if (!tr) {
rc = -ENOMEM;
goto bad;
}
- memset(tr, 0, sizeof(*tr));
if (ltr) {
ltr->next = tr;
} else {
@@ -1593,12 +1581,11 @@ int policydb_read(struct policydb *p, void *fp)
nel = le32_to_cpu(buf[0]);
lra = NULL;
for (i = 0; i < nel; i++) {
- ra = kmalloc(sizeof(*ra), GFP_KERNEL);
+ ra = kzalloc(sizeof(*ra), GFP_KERNEL);
if (!ra) {
rc = -ENOMEM;
goto bad;
}
- memset(ra, 0, sizeof(*ra));
if (lra) {
lra->next = ra;
} else {
@@ -1627,12 +1614,11 @@ int policydb_read(struct policydb *p, void *fp)
nel = le32_to_cpu(buf[0]);
l = NULL;
for (j = 0; j < nel; j++) {
- c = kmalloc(sizeof(*c), GFP_KERNEL);
+ c = kzalloc(sizeof(*c), GFP_KERNEL);
if (!c) {
rc = -ENOMEM;
goto bad;
}
- memset(c, 0, sizeof(*c));
if (l) {
l->next = c;
} else {
@@ -1743,12 +1729,11 @@ int policydb_read(struct policydb *p, void *fp)
if (rc < 0)
goto bad;
len = le32_to_cpu(buf[0]);
- newgenfs = kmalloc(sizeof(*newgenfs), GFP_KERNEL);
+ newgenfs = kzalloc(sizeof(*newgenfs), GFP_KERNEL);
if (!newgenfs) {
rc = -ENOMEM;
goto bad;
}
- memset(newgenfs, 0, sizeof(*newgenfs));
newgenfs->fstype = kmalloc(len + 1,GFP_KERNEL);
if (!newgenfs->fstype) {
@@ -1790,12 +1775,11 @@ int policydb_read(struct policydb *p, void *fp)
goto bad;
len = le32_to_cpu(buf[0]);
- newc = kmalloc(sizeof(*newc), GFP_KERNEL);
+ newc = kzalloc(sizeof(*newc), GFP_KERNEL);
if (!newc) {
rc = -ENOMEM;
goto bad;
}
- memset(newc, 0, sizeof(*newc));
newc->u.name = kmalloc(len + 1,GFP_KERNEL);
if (!newc->u.name) {
@@ -1843,12 +1827,11 @@ int policydb_read(struct policydb *p, void *fp)
nel = le32_to_cpu(buf[0]);
lrt = NULL;
for (i = 0; i < nel; i++) {
- rt = kmalloc(sizeof(*rt), GFP_KERNEL);
+ rt = kzalloc(sizeof(*rt), GFP_KERNEL);
if (!rt) {
rc = -ENOMEM;
goto bad;
}
- memset(rt, 0, sizeof(*rt));
if (lrt)
lrt->next = rt;
else
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index aecdded55e74..44eb4d74908d 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1531,12 +1531,11 @@ int security_get_user_sids(u32 fromsid,
}
usercon.user = user->value;
- mysids = kmalloc(maxnel*sizeof(*mysids), GFP_ATOMIC);
+ mysids = kcalloc(maxnel, sizeof(*mysids), GFP_ATOMIC);
if (!mysids) {
rc = -ENOMEM;
goto out_unlock;
}
- memset(mysids, 0, maxnel*sizeof(*mysids));
ebitmap_for_each_bit(&user->roles, rnode, i) {
if (!ebitmap_node_get_bit(rnode, i))
@@ -1566,13 +1565,12 @@ int security_get_user_sids(u32 fromsid,
mysids[mynel++] = sid;
} else {
maxnel += SIDS_NEL;
- mysids2 = kmalloc(maxnel*sizeof(*mysids2), GFP_ATOMIC);
+ mysids2 = kcalloc(maxnel, sizeof(*mysids2), GFP_ATOMIC);
if (!mysids2) {
rc = -ENOMEM;
kfree(mysids);
goto out_unlock;
}
- memset(mysids2, 0, maxnel*sizeof(*mysids2));
memcpy(mysids2, mysids, mynel * sizeof(*mysids2));
kfree(mysids);
mysids = mysids2;
@@ -1714,12 +1712,11 @@ int security_get_bools(int *len, char ***names, int **values)
goto out;
}
- *names = (char**)kmalloc(sizeof(char*) * *len, GFP_ATOMIC);
+ *names = (char**)kcalloc(*len, sizeof(char*), GFP_ATOMIC);
if (!*names)
goto err;
- memset(*names, 0, sizeof(char*) * *len);
- *values = (int*)kmalloc(sizeof(int) * *len, GFP_ATOMIC);
+ *values = (int*)kcalloc(*len, sizeof(int), GFP_ATOMIC);
if (!*values)
goto err;
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 67abebabf83e..e97b2d162cc7 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -2949,8 +2949,7 @@ static struct page * snd_pcm_mmap_status_nopage(struct vm_area_struct *area, uns
return NOPAGE_OOM;
runtime = substream->runtime;
page = virt_to_page(runtime->status);
- if (!PageReserved(page))
- get_page(page);
+ get_page(page);
if (type)
*type = VM_FAULT_MINOR;
return page;
@@ -2992,8 +2991,7 @@ static struct page * snd_pcm_mmap_control_nopage(struct vm_area_struct *area, un
return NOPAGE_OOM;
runtime = substream->runtime;
page = virt_to_page(runtime->control);
- if (!PageReserved(page))
- get_page(page);
+ get_page(page);
if (type)
*type = VM_FAULT_MINOR;
return page;
@@ -3066,8 +3064,7 @@ static struct page *snd_pcm_mmap_data_nopage(struct vm_area_struct *area, unsign
vaddr = runtime->dma_area + offset;
page = virt_to_page(vaddr);
}
- if (!PageReserved(page))
- get_page(page);
+ get_page(page);
if (type)
*type = VM_FAULT_MINOR;
return page;
diff --git a/sound/oss/ac97_codec.c b/sound/oss/ac97_codec.c
index 3ecef4689f1b..fd25aca25120 100644
--- a/sound/oss/ac97_codec.c
+++ b/sound/oss/ac97_codec.c
@@ -55,6 +55,7 @@
#include <linux/pci.h>
#include <linux/ac97_codec.h>
#include <asm/uaccess.h>
+#include <asm/semaphore.h>
#define CODEC_ID_BUFSZ 14
diff --git a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c
index a78e48d412d2..6b46a8a4b1cc 100644
--- a/sound/oss/au1550_ac97.c
+++ b/sound/oss/au1550_ac97.c
@@ -35,7 +35,6 @@
#undef DEBUG
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/ioport.h>
diff --git a/sound/oss/awe_wave.c b/sound/oss/awe_wave.c
index d2b9beda8ace..b3ea719d33db 100644
--- a/sound/oss/awe_wave.c
+++ b/sound/oss/awe_wave.c
@@ -6062,7 +6062,7 @@ static int awe_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id
io1 = pnp_port_start(dev,0);
io2 = pnp_port_start(dev,1);
io3 = pnp_port_start(dev,2);
- printk(KERN_INFO "AWE32: A PnP Wave Table was detected at IO's %#x,%#x,%#x\n.",
+ printk(KERN_INFO "AWE32: A PnP Wave Table was detected at IO's %#x,%#x,%#x.\n",
io1, io2, io3);
setup_ports(io1, io2, io3);
diff --git a/sound/oss/cs4232.c b/sound/oss/cs4232.c
index 6ec308f5d935..7c59e2d4003a 100644
--- a/sound/oss/cs4232.c
+++ b/sound/oss/cs4232.c
@@ -195,10 +195,12 @@ static int __init probe_cs4232(struct address_info *hw_config, int isapnp_config
CS_OUT2(0x15, 0x00); /* Select logical device 0 (WSS/SB/FM) */
CS_OUT3(0x47, (base >> 8) & 0xff, base & 0xff); /* WSS base */
- if (check_region(0x388, 4)) /* Not free */
+ if (!request_region(0x388, 4, "FM")) /* Not free */
CS_OUT3(0x48, 0x00, 0x00) /* FM base off */
- else
+ else {
+ release_region(0x388, 4);
CS_OUT3(0x48, 0x03, 0x88); /* FM base 0x388 */
+ }
CS_OUT3(0x42, 0x00, 0x00); /* SB base off */
CS_OUT2(0x22, irq); /* SB+WSS IRQ */
diff --git a/sound/oss/wavfront.c b/sound/oss/wavfront.c
index b92ba8921638..b1a4eeb9dc08 100644
--- a/sound/oss/wavfront.c
+++ b/sound/oss/wavfront.c
@@ -2434,7 +2434,7 @@ static int __init detect_wavefront (int irq, int io_base)
consumes 16.
*/
- if (check_region (io_base, 16)) {
+ if (!request_region (io_base, 16, "wavfront")) {
printk (KERN_ERR LOGNAME "IO address range 0x%x - 0x%x "
"already in use - ignored\n", dev.base,
dev.base+15);
@@ -2466,10 +2466,13 @@ static int __init detect_wavefront (int irq, int io_base)
} else {
printk (KERN_WARNING LOGNAME "not raw, but no "
"hardware version!\n");
+ release_region (io_base, 16);
return 0;
}
if (!wf_raw) {
+ /* will re-acquire region in install_wavefront() */
+ release_region (io_base, 16);
return 1;
} else {
printk (KERN_INFO LOGNAME
@@ -2489,6 +2492,7 @@ static int __init detect_wavefront (int irq, int io_base)
if (wavefront_hw_reset ()) {
printk (KERN_WARNING LOGNAME "hardware reset failed\n");
+ release_region (io_base, 16);
return 0;
}
@@ -2496,6 +2500,8 @@ static int __init detect_wavefront (int irq, int io_base)
dev.has_fx = (detect_wffx () == 0);
+ /* will re-acquire region in install_wavefront() */
+ release_region (io_base, 16);
return 1;
}
@@ -2804,17 +2810,27 @@ static int __init wavefront_init (int atboot)
}
static int __init install_wavefront (void)
-
{
+ if (!request_region (dev.base+2, 6, "wavefront synth"))
+ return -1;
+
+ if (dev.has_fx) {
+ if (!request_region (dev.base+8, 8, "wavefront fx")) {
+ release_region (dev.base+2, 6);
+ return -1;
+ }
+ }
+
if ((dev.synth_dev = register_sound_synth (&wavefront_fops, -1)) < 0) {
printk (KERN_ERR LOGNAME "cannot register raw synth\n");
- return -1;
+ goto err_out;
}
#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
if ((dev.oss_dev = sound_alloc_synthdev()) == -1) {
printk (KERN_ERR LOGNAME "Too many sequencers\n");
- return -1;
+ /* FIXME: leak: should unregister sound synth */
+ goto err_out;
} else {
synth_devs[dev.oss_dev] = &wavefront_operations;
}
@@ -2827,20 +2843,20 @@ static int __init install_wavefront (void)
sound_unload_synthdev (dev.oss_dev);
#endif /* OSS_SUPPORT_SEQ */
- return -1;
+ goto err_out;
}
- request_region (dev.base+2, 6, "wavefront synth");
-
- if (dev.has_fx) {
- request_region (dev.base+8, 8, "wavefront fx");
- }
-
if (wavefront_config_midi ()) {
printk (KERN_WARNING LOGNAME "could not initialize MIDI.\n");
}
return dev.oss_dev;
+
+err_out:
+ release_region (dev.base+2, 6);
+ if (dev.has_fx)
+ release_region (dev.base+8, 8);
+ return -1;
}
static void __exit uninstall_wavefront (void)